From ab1bea97f4d61999cbb444e958b320cef9465f7a Mon Sep 17 00:00:00 2001 From: seder Date: Sat, 31 Oct 2020 01:01:26 +0100 Subject: [PATCH 01/21] Add speaker on/off feature --- Tonuino.ino | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/Tonuino.ino b/Tonuino.ino index c3ce9c9b..5401e132 100644 --- a/Tonuino.ino +++ b/Tonuino.ino @@ -20,6 +20,12 @@ // uncomment the below line to enable five button support //#define FIVEBUTTONS +// ------------------------------------------------------------------------------------------------ +#define SpkOnOff // Aus und Einschalten des Lautsprechers über MOSFET's + // zur Unterdrückung des Einschaltgeräusches und + // Möglichkeit der Abschaltung beim Anschluss eines Kopfhörers + // Hardwareerweiterung erforderlich: (Abschaltung des Lautsprechers über MOS-FET's) + static const uint32_t cardCookie = 322417479; // DFPlayer Mini @@ -638,6 +644,10 @@ byte blockAddr = 4; byte trailerBlock = 7; MFRC522::StatusCode status; +#define NFCgain_max // Maximale Empfindlichkeit +//#define NFCgain_avg // Mittlere Empfindlichkeit +//#define NFCgain_min // Minimale Empfindlichkeit + #define buttonPause A0 #define buttonUp A1 #define buttonDown A2 @@ -650,6 +660,11 @@ MFRC522::StatusCode status; #define buttonFivePin A4 #endif +#ifdef SpkOnOff + #define SpkOnPin 6 // Lautsprecher Ein + bool SpkisOn = false; // Marker Lautsprecher Ein/Aus +#endif + #define LONG_PRESS 1000 Button pauseButton(buttonPause); @@ -740,6 +755,11 @@ void setup() { Serial.println(F("created by Thorsten Voß and licensed under GNU/GPL.")); Serial.println(F("Information and contribution at https://tonuino.de.\n")); +#ifdef SpkOnOff + pinMode(SpkOnPin, OUTPUT); // Ausgang Lautsprecher-Einschaltsignal + spkOff(); // Voreinstellung - Speaker Off +#endif + // Busy Pin pinMode(busyPin, INPUT); @@ -762,6 +782,20 @@ void setup() { // NFC Leser initialisieren SPI.begin(); // Init SPI bus mfrc522.PCD_Init(); // Init MFRC522 + +#ifdef NFCgain_min + mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_min); + Serial.println(F("=== mfrc522-> RxGain_min === ")); +#endif +#ifdef NFCgain_avg + mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_avg); + Serial.println(F("=== mfrc522-> RxGain_avg === ")); +#endif +#ifdef NFCgain_max + mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); + Serial.println(F("=== mfrc522-> RxGain_max === ")); +#endif + mfrc522 .PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader for (byte i = 0; i < 6; i++) { @@ -778,6 +812,9 @@ void setup() { pinMode(shutdownPin, OUTPUT); digitalWrite(shutdownPin, LOW); +#ifdef SpkOnOff + spkOn(); +#endif // RESET --- ALLE DREI KNÖPFE BEIM STARTEN GEDRÜCKT HALTEN -> alle EINSTELLUNGEN werden gelöscht if (digitalRead(buttonPause) == LOW && digitalRead(buttonUp) == LOW && @@ -1784,7 +1821,30 @@ void writeCard(nfcTagObject nfcTag) { delay(2000); } +// ************************** Speaker On-Off ***************************************** + +// **************************Speaker On ******************* +#ifdef SpkOnOff +void spkOn() + { + digitalWrite(SpkOnPin, HIGH); // Lautsprecher über Mosfets Einschalten + Serial.println(F("Lautsprecher wird eingeschaltet!")); + SpkisOn = true; + } + +// **************************Speaker Off ******************* +void spkOff() { + digitalWrite(SpkOnPin, LOW); // Lautsprecher über Mosfets Ausschalten + Serial.println(F("Lautsprecher wird ausgeschaltet!")); + SpkisOn = false; +} + +//void SpkrOnOff() { +// SpkOn(); // Lautsprecher über Mosfets Einschalten +//} +#endif +// ************************** END Speaker On-Off ************************************** /** Helper routine to dump a byte array as hex values to Serial. From 87975b88b212b748ba6fe284f8898c4e9b94d05a Mon Sep 17 00:00:00 2001 From: seder Date: Tue, 29 Dec 2020 21:03:34 +0100 Subject: [PATCH 02/21] Convert to PIO --- .gitignore | 7 + include/README | 39 + lib/README | 46 + platformio.ini | 19 + LICENSE => src/LICENSE | 0 README.md => src/README.md | 0 .../TonUINO_Schaltplan.pdf | Bin Tonuino.ino => src/Tonuino.cpp | 2104 +++++++++-------- src/Tonuino.ino.eightanaloginputs.hex | 1556 ++++++++++++ ....ino.with_bootloader.eightanaloginputs.hex | 1678 +++++++++++++ .../audio_messages_de.txt | 0 .../create-soundfiles.sh | 0 {sd-card => src/sd-card}/advert/0001.mp3 | Bin {sd-card => src/sd-card}/advert/0002.mp3 | Bin {sd-card => src/sd-card}/advert/0003.mp3 | Bin {sd-card => src/sd-card}/advert/0004.mp3 | Bin {sd-card => src/sd-card}/advert/0005.mp3 | Bin {sd-card => src/sd-card}/advert/0006.mp3 | Bin {sd-card => src/sd-card}/advert/0007.mp3 | Bin {sd-card => src/sd-card}/advert/0008.mp3 | Bin {sd-card => src/sd-card}/advert/0009.mp3 | Bin {sd-card => src/sd-card}/advert/0010.mp3 | Bin {sd-card => src/sd-card}/advert/0011.mp3 | Bin {sd-card => src/sd-card}/advert/0012.mp3 | Bin {sd-card => src/sd-card}/advert/0013.mp3 | Bin {sd-card => src/sd-card}/advert/0014.mp3 | Bin {sd-card => src/sd-card}/advert/0015.mp3 | Bin {sd-card => src/sd-card}/advert/0016.mp3 | Bin {sd-card => src/sd-card}/advert/0017.mp3 | Bin {sd-card => src/sd-card}/advert/0018.mp3 | Bin {sd-card => src/sd-card}/advert/0019.mp3 | Bin {sd-card => src/sd-card}/advert/0020.mp3 | Bin {sd-card => src/sd-card}/advert/0021.mp3 | Bin {sd-card => src/sd-card}/advert/0022.mp3 | Bin {sd-card => src/sd-card}/advert/0023.mp3 | Bin {sd-card => src/sd-card}/advert/0024.mp3 | Bin {sd-card => src/sd-card}/advert/0025.mp3 | Bin {sd-card => src/sd-card}/advert/0026.mp3 | Bin {sd-card => src/sd-card}/advert/0027.mp3 | Bin {sd-card => src/sd-card}/advert/0028.mp3 | Bin {sd-card => src/sd-card}/advert/0029.mp3 | Bin {sd-card => src/sd-card}/advert/0030.mp3 | Bin {sd-card => src/sd-card}/advert/0031.mp3 | Bin {sd-card => src/sd-card}/advert/0032.mp3 | Bin {sd-card => src/sd-card}/advert/0033.mp3 | Bin {sd-card => src/sd-card}/advert/0034.mp3 | Bin {sd-card => src/sd-card}/advert/0035.mp3 | Bin {sd-card => src/sd-card}/advert/0036.mp3 | Bin {sd-card => src/sd-card}/advert/0037.mp3 | Bin {sd-card => src/sd-card}/advert/0038.mp3 | Bin {sd-card => src/sd-card}/advert/0039.mp3 | Bin {sd-card => src/sd-card}/advert/0040.mp3 | Bin {sd-card => src/sd-card}/advert/0041.mp3 | Bin {sd-card => src/sd-card}/advert/0042.mp3 | Bin {sd-card => src/sd-card}/advert/0043.mp3 | Bin {sd-card => src/sd-card}/advert/0044.mp3 | Bin {sd-card => src/sd-card}/advert/0045.mp3 | Bin {sd-card => src/sd-card}/advert/0046.mp3 | Bin {sd-card => src/sd-card}/advert/0047.mp3 | Bin {sd-card => src/sd-card}/advert/0048.mp3 | Bin {sd-card => src/sd-card}/advert/0049.mp3 | Bin {sd-card => src/sd-card}/advert/0050.mp3 | Bin {sd-card => src/sd-card}/advert/0051.mp3 | Bin {sd-card => src/sd-card}/advert/0052.mp3 | Bin {sd-card => src/sd-card}/advert/0053.mp3 | Bin {sd-card => src/sd-card}/advert/0054.mp3 | Bin {sd-card => src/sd-card}/advert/0055.mp3 | Bin {sd-card => src/sd-card}/advert/0056.mp3 | Bin {sd-card => src/sd-card}/advert/0057.mp3 | Bin {sd-card => src/sd-card}/advert/0058.mp3 | Bin {sd-card => src/sd-card}/advert/0059.mp3 | Bin {sd-card => src/sd-card}/advert/0060.mp3 | Bin {sd-card => src/sd-card}/advert/0061.mp3 | Bin {sd-card => src/sd-card}/advert/0062.mp3 | Bin {sd-card => src/sd-card}/advert/0063.mp3 | Bin {sd-card => src/sd-card}/advert/0064.mp3 | Bin {sd-card => src/sd-card}/advert/0065.mp3 | Bin {sd-card => src/sd-card}/advert/0066.mp3 | Bin {sd-card => src/sd-card}/advert/0067.mp3 | Bin {sd-card => src/sd-card}/advert/0068.mp3 | Bin {sd-card => src/sd-card}/advert/0069.mp3 | Bin {sd-card => src/sd-card}/advert/0070.mp3 | Bin {sd-card => src/sd-card}/advert/0071.mp3 | Bin {sd-card => src/sd-card}/advert/0072.mp3 | Bin {sd-card => src/sd-card}/advert/0073.mp3 | Bin {sd-card => src/sd-card}/advert/0074.mp3 | Bin {sd-card => src/sd-card}/advert/0075.mp3 | Bin {sd-card => src/sd-card}/advert/0076.mp3 | Bin {sd-card => src/sd-card}/advert/0077.mp3 | Bin {sd-card => src/sd-card}/advert/0078.mp3 | Bin {sd-card => src/sd-card}/advert/0079.mp3 | Bin {sd-card => src/sd-card}/advert/0080.mp3 | Bin {sd-card => src/sd-card}/advert/0081.mp3 | Bin {sd-card => src/sd-card}/advert/0082.mp3 | Bin {sd-card => src/sd-card}/advert/0083.mp3 | Bin {sd-card => src/sd-card}/advert/0084.mp3 | Bin {sd-card => src/sd-card}/advert/0085.mp3 | Bin {sd-card => src/sd-card}/advert/0086.mp3 | Bin {sd-card => src/sd-card}/advert/0087.mp3 | Bin {sd-card => src/sd-card}/advert/0088.mp3 | Bin {sd-card => src/sd-card}/advert/0089.mp3 | Bin {sd-card => src/sd-card}/advert/0090.mp3 | Bin {sd-card => src/sd-card}/advert/0091.mp3 | Bin {sd-card => src/sd-card}/advert/0092.mp3 | Bin {sd-card => src/sd-card}/advert/0093.mp3 | Bin {sd-card => src/sd-card}/advert/0094.mp3 | Bin {sd-card => src/sd-card}/advert/0095.mp3 | Bin {sd-card => src/sd-card}/advert/0096.mp3 | Bin {sd-card => src/sd-card}/advert/0097.mp3 | Bin {sd-card => src/sd-card}/advert/0098.mp3 | Bin {sd-card => src/sd-card}/advert/0099.mp3 | Bin {sd-card => src/sd-card}/advert/0100.mp3 | Bin {sd-card => src/sd-card}/advert/0101.mp3 | Bin {sd-card => src/sd-card}/advert/0102.mp3 | Bin {sd-card => src/sd-card}/advert/0103.mp3 | Bin {sd-card => src/sd-card}/advert/0104.mp3 | Bin {sd-card => src/sd-card}/advert/0105.mp3 | Bin {sd-card => src/sd-card}/advert/0106.mp3 | Bin {sd-card => src/sd-card}/advert/0107.mp3 | Bin {sd-card => src/sd-card}/advert/0108.mp3 | Bin {sd-card => src/sd-card}/advert/0109.mp3 | Bin {sd-card => src/sd-card}/advert/0110.mp3 | Bin {sd-card => src/sd-card}/advert/0111.mp3 | Bin {sd-card => src/sd-card}/advert/0112.mp3 | Bin {sd-card => src/sd-card}/advert/0113.mp3 | Bin {sd-card => src/sd-card}/advert/0114.mp3 | Bin {sd-card => src/sd-card}/advert/0115.mp3 | Bin {sd-card => src/sd-card}/advert/0116.mp3 | Bin {sd-card => src/sd-card}/advert/0117.mp3 | Bin {sd-card => src/sd-card}/advert/0118.mp3 | Bin {sd-card => src/sd-card}/advert/0119.mp3 | Bin {sd-card => src/sd-card}/advert/0120.mp3 | Bin {sd-card => src/sd-card}/advert/0121.mp3 | Bin {sd-card => src/sd-card}/advert/0122.mp3 | Bin {sd-card => src/sd-card}/advert/0123.mp3 | Bin {sd-card => src/sd-card}/advert/0124.mp3 | Bin {sd-card => src/sd-card}/advert/0125.mp3 | Bin {sd-card => src/sd-card}/advert/0126.mp3 | Bin {sd-card => src/sd-card}/advert/0127.mp3 | Bin {sd-card => src/sd-card}/advert/0128.mp3 | Bin {sd-card => src/sd-card}/advert/0129.mp3 | Bin {sd-card => src/sd-card}/advert/0130.mp3 | Bin {sd-card => src/sd-card}/advert/0131.mp3 | Bin {sd-card => src/sd-card}/advert/0132.mp3 | Bin {sd-card => src/sd-card}/advert/0133.mp3 | Bin {sd-card => src/sd-card}/advert/0134.mp3 | Bin {sd-card => src/sd-card}/advert/0135.mp3 | Bin {sd-card => src/sd-card}/advert/0136.mp3 | Bin {sd-card => src/sd-card}/advert/0137.mp3 | Bin {sd-card => src/sd-card}/advert/0138.mp3 | Bin {sd-card => src/sd-card}/advert/0139.mp3 | Bin {sd-card => src/sd-card}/advert/0140.mp3 | Bin {sd-card => src/sd-card}/advert/0141.mp3 | Bin {sd-card => src/sd-card}/advert/0142.mp3 | Bin {sd-card => src/sd-card}/advert/0143.mp3 | Bin {sd-card => src/sd-card}/advert/0144.mp3 | Bin {sd-card => src/sd-card}/advert/0145.mp3 | Bin {sd-card => src/sd-card}/advert/0146.mp3 | Bin {sd-card => src/sd-card}/advert/0147.mp3 | Bin {sd-card => src/sd-card}/advert/0148.mp3 | Bin {sd-card => src/sd-card}/advert/0149.mp3 | Bin {sd-card => src/sd-card}/advert/0150.mp3 | Bin {sd-card => src/sd-card}/advert/0151.mp3 | Bin {sd-card => src/sd-card}/advert/0152.mp3 | Bin {sd-card => src/sd-card}/advert/0153.mp3 | Bin {sd-card => src/sd-card}/advert/0154.mp3 | Bin {sd-card => src/sd-card}/advert/0155.mp3 | Bin {sd-card => src/sd-card}/advert/0156.mp3 | Bin {sd-card => src/sd-card}/advert/0157.mp3 | Bin {sd-card => src/sd-card}/advert/0158.mp3 | Bin {sd-card => src/sd-card}/advert/0159.mp3 | Bin {sd-card => src/sd-card}/advert/0160.mp3 | Bin {sd-card => src/sd-card}/advert/0161.mp3 | Bin {sd-card => src/sd-card}/advert/0162.mp3 | Bin {sd-card => src/sd-card}/advert/0163.mp3 | Bin {sd-card => src/sd-card}/advert/0164.mp3 | Bin {sd-card => src/sd-card}/advert/0165.mp3 | Bin {sd-card => src/sd-card}/advert/0166.mp3 | Bin {sd-card => src/sd-card}/advert/0167.mp3 | Bin {sd-card => src/sd-card}/advert/0168.mp3 | Bin {sd-card => src/sd-card}/advert/0169.mp3 | Bin {sd-card => src/sd-card}/advert/0170.mp3 | Bin {sd-card => src/sd-card}/advert/0171.mp3 | Bin {sd-card => src/sd-card}/advert/0172.mp3 | Bin {sd-card => src/sd-card}/advert/0173.mp3 | Bin {sd-card => src/sd-card}/advert/0174.mp3 | Bin {sd-card => src/sd-card}/advert/0175.mp3 | Bin {sd-card => src/sd-card}/advert/0176.mp3 | Bin {sd-card => src/sd-card}/advert/0177.mp3 | Bin {sd-card => src/sd-card}/advert/0178.mp3 | Bin {sd-card => src/sd-card}/advert/0179.mp3 | Bin {sd-card => src/sd-card}/advert/0180.mp3 | Bin {sd-card => src/sd-card}/advert/0181.mp3 | Bin {sd-card => src/sd-card}/advert/0182.mp3 | Bin {sd-card => src/sd-card}/advert/0183.mp3 | Bin {sd-card => src/sd-card}/advert/0184.mp3 | Bin {sd-card => src/sd-card}/advert/0185.mp3 | Bin {sd-card => src/sd-card}/advert/0186.mp3 | Bin {sd-card => src/sd-card}/advert/0187.mp3 | Bin {sd-card => src/sd-card}/advert/0188.mp3 | Bin {sd-card => src/sd-card}/advert/0189.mp3 | Bin {sd-card => src/sd-card}/advert/0190.mp3 | Bin {sd-card => src/sd-card}/advert/0191.mp3 | Bin {sd-card => src/sd-card}/advert/0192.mp3 | Bin {sd-card => src/sd-card}/advert/0193.mp3 | Bin {sd-card => src/sd-card}/advert/0194.mp3 | Bin {sd-card => src/sd-card}/advert/0195.mp3 | Bin {sd-card => src/sd-card}/advert/0196.mp3 | Bin {sd-card => src/sd-card}/advert/0197.mp3 | Bin {sd-card => src/sd-card}/advert/0198.mp3 | Bin {sd-card => src/sd-card}/advert/0199.mp3 | Bin {sd-card => src/sd-card}/advert/0200.mp3 | Bin {sd-card => src/sd-card}/advert/0201.mp3 | Bin {sd-card => src/sd-card}/advert/0202.mp3 | Bin {sd-card => src/sd-card}/advert/0203.mp3 | Bin {sd-card => src/sd-card}/advert/0204.mp3 | Bin {sd-card => src/sd-card}/advert/0205.mp3 | Bin {sd-card => src/sd-card}/advert/0206.mp3 | Bin {sd-card => src/sd-card}/advert/0207.mp3 | Bin {sd-card => src/sd-card}/advert/0208.mp3 | Bin {sd-card => src/sd-card}/advert/0209.mp3 | Bin {sd-card => src/sd-card}/advert/0210.mp3 | Bin {sd-card => src/sd-card}/advert/0211.mp3 | Bin {sd-card => src/sd-card}/advert/0212.mp3 | Bin {sd-card => src/sd-card}/advert/0213.mp3 | Bin {sd-card => src/sd-card}/advert/0214.mp3 | Bin {sd-card => src/sd-card}/advert/0215.mp3 | Bin {sd-card => src/sd-card}/advert/0216.mp3 | Bin {sd-card => src/sd-card}/advert/0217.mp3 | Bin {sd-card => src/sd-card}/advert/0218.mp3 | Bin {sd-card => src/sd-card}/advert/0219.mp3 | Bin {sd-card => src/sd-card}/advert/0220.mp3 | Bin {sd-card => src/sd-card}/advert/0221.mp3 | Bin {sd-card => src/sd-card}/advert/0222.mp3 | Bin {sd-card => src/sd-card}/advert/0223.mp3 | Bin {sd-card => src/sd-card}/advert/0224.mp3 | Bin {sd-card => src/sd-card}/advert/0225.mp3 | Bin {sd-card => src/sd-card}/advert/0226.mp3 | Bin {sd-card => src/sd-card}/advert/0227.mp3 | Bin {sd-card => src/sd-card}/advert/0228.mp3 | Bin {sd-card => src/sd-card}/advert/0229.mp3 | Bin {sd-card => src/sd-card}/advert/0230.mp3 | Bin {sd-card => src/sd-card}/advert/0231.mp3 | Bin {sd-card => src/sd-card}/advert/0232.mp3 | Bin {sd-card => src/sd-card}/advert/0233.mp3 | Bin {sd-card => src/sd-card}/advert/0234.mp3 | Bin {sd-card => src/sd-card}/advert/0235.mp3 | Bin {sd-card => src/sd-card}/advert/0236.mp3 | Bin {sd-card => src/sd-card}/advert/0237.mp3 | Bin {sd-card => src/sd-card}/advert/0238.mp3 | Bin {sd-card => src/sd-card}/advert/0239.mp3 | Bin {sd-card => src/sd-card}/advert/0240.mp3 | Bin {sd-card => src/sd-card}/advert/0241.mp3 | Bin {sd-card => src/sd-card}/advert/0242.mp3 | Bin {sd-card => src/sd-card}/advert/0243.mp3 | Bin {sd-card => src/sd-card}/advert/0244.mp3 | Bin {sd-card => src/sd-card}/advert/0245.mp3 | Bin {sd-card => src/sd-card}/advert/0246.mp3 | Bin {sd-card => src/sd-card}/advert/0247.mp3 | Bin {sd-card => src/sd-card}/advert/0248.mp3 | Bin {sd-card => src/sd-card}/advert/0249.mp3 | Bin {sd-card => src/sd-card}/advert/0250.mp3 | Bin {sd-card => src/sd-card}/advert/0251.mp3 | Bin {sd-card => src/sd-card}/advert/0252.mp3 | Bin {sd-card => src/sd-card}/advert/0253.mp3 | Bin {sd-card => src/sd-card}/advert/0254.mp3 | Bin {sd-card => src/sd-card}/advert/0255.mp3 | Bin {sd-card => src/sd-card}/advert/0260.mp3 | Bin {sd-card => src/sd-card}/advert/0261.mp3 | Bin .../sd-card}/advert/0300_freeze_into.mp3 | Bin .../sd-card}/advert/0301_freeze_freeze.mp3 | Bin .../sd-card}/advert/0302_sleep.mp3 | Bin .../sd-card}/advert/0303_locked.mp3 | Bin .../sd-card}/advert/0304_buttonslocked.mp3 | Bin .../sd-card}/advert/0305_kindergarden.mp3 | Bin {sd-card => src/sd-card}/mp3/0001.mp3 | Bin {sd-card => src/sd-card}/mp3/0002.mp3 | Bin {sd-card => src/sd-card}/mp3/0003.mp3 | Bin {sd-card => src/sd-card}/mp3/0004.mp3 | Bin {sd-card => src/sd-card}/mp3/0005.mp3 | Bin {sd-card => src/sd-card}/mp3/0006.mp3 | Bin {sd-card => src/sd-card}/mp3/0007.mp3 | Bin {sd-card => src/sd-card}/mp3/0008.mp3 | Bin {sd-card => src/sd-card}/mp3/0009.mp3 | Bin {sd-card => src/sd-card}/mp3/0010.mp3 | Bin {sd-card => src/sd-card}/mp3/0011.mp3 | Bin {sd-card => src/sd-card}/mp3/0012.mp3 | Bin {sd-card => src/sd-card}/mp3/0013.mp3 | Bin {sd-card => src/sd-card}/mp3/0014.mp3 | Bin {sd-card => src/sd-card}/mp3/0015.mp3 | Bin {sd-card => src/sd-card}/mp3/0016.mp3 | Bin {sd-card => src/sd-card}/mp3/0017.mp3 | Bin {sd-card => src/sd-card}/mp3/0018.mp3 | Bin {sd-card => src/sd-card}/mp3/0019.mp3 | Bin {sd-card => src/sd-card}/mp3/0020.mp3 | Bin {sd-card => src/sd-card}/mp3/0021.mp3 | Bin {sd-card => src/sd-card}/mp3/0022.mp3 | Bin {sd-card => src/sd-card}/mp3/0023.mp3 | Bin {sd-card => src/sd-card}/mp3/0024.mp3 | Bin {sd-card => src/sd-card}/mp3/0025.mp3 | Bin {sd-card => src/sd-card}/mp3/0026.mp3 | Bin {sd-card => src/sd-card}/mp3/0027.mp3 | Bin {sd-card => src/sd-card}/mp3/0028.mp3 | Bin {sd-card => src/sd-card}/mp3/0029.mp3 | Bin {sd-card => src/sd-card}/mp3/0030.mp3 | Bin {sd-card => src/sd-card}/mp3/0031.mp3 | Bin {sd-card => src/sd-card}/mp3/0032.mp3 | Bin {sd-card => src/sd-card}/mp3/0033.mp3 | Bin {sd-card => src/sd-card}/mp3/0034.mp3 | Bin {sd-card => src/sd-card}/mp3/0035.mp3 | Bin {sd-card => src/sd-card}/mp3/0036.mp3 | Bin {sd-card => src/sd-card}/mp3/0037.mp3 | Bin {sd-card => src/sd-card}/mp3/0038.mp3 | Bin {sd-card => src/sd-card}/mp3/0039.mp3 | Bin {sd-card => src/sd-card}/mp3/0040.mp3 | Bin {sd-card => src/sd-card}/mp3/0041.mp3 | Bin {sd-card => src/sd-card}/mp3/0042.mp3 | Bin {sd-card => src/sd-card}/mp3/0043.mp3 | Bin {sd-card => src/sd-card}/mp3/0044.mp3 | Bin {sd-card => src/sd-card}/mp3/0045.mp3 | Bin {sd-card => src/sd-card}/mp3/0046.mp3 | Bin {sd-card => src/sd-card}/mp3/0047.mp3 | Bin {sd-card => src/sd-card}/mp3/0048.mp3 | Bin {sd-card => src/sd-card}/mp3/0049.mp3 | Bin {sd-card => src/sd-card}/mp3/0050.mp3 | Bin {sd-card => src/sd-card}/mp3/0051.mp3 | Bin {sd-card => src/sd-card}/mp3/0052.mp3 | Bin {sd-card => src/sd-card}/mp3/0053.mp3 | Bin {sd-card => src/sd-card}/mp3/0054.mp3 | Bin {sd-card => src/sd-card}/mp3/0055.mp3 | Bin {sd-card => src/sd-card}/mp3/0056.mp3 | Bin {sd-card => src/sd-card}/mp3/0057.mp3 | Bin {sd-card => src/sd-card}/mp3/0058.mp3 | Bin {sd-card => src/sd-card}/mp3/0059.mp3 | Bin {sd-card => src/sd-card}/mp3/0060.mp3 | Bin {sd-card => src/sd-card}/mp3/0061.mp3 | Bin {sd-card => src/sd-card}/mp3/0062.mp3 | Bin {sd-card => src/sd-card}/mp3/0063.mp3 | Bin {sd-card => src/sd-card}/mp3/0064.mp3 | Bin {sd-card => src/sd-card}/mp3/0065.mp3 | Bin {sd-card => src/sd-card}/mp3/0066.mp3 | Bin {sd-card => src/sd-card}/mp3/0067.mp3 | Bin {sd-card => src/sd-card}/mp3/0068.mp3 | Bin {sd-card => src/sd-card}/mp3/0069.mp3 | Bin {sd-card => src/sd-card}/mp3/0070.mp3 | Bin {sd-card => src/sd-card}/mp3/0071.mp3 | Bin {sd-card => src/sd-card}/mp3/0072.mp3 | Bin {sd-card => src/sd-card}/mp3/0073.mp3 | Bin {sd-card => src/sd-card}/mp3/0074.mp3 | Bin {sd-card => src/sd-card}/mp3/0075.mp3 | Bin {sd-card => src/sd-card}/mp3/0076.mp3 | Bin {sd-card => src/sd-card}/mp3/0077.mp3 | Bin {sd-card => src/sd-card}/mp3/0078.mp3 | Bin {sd-card => src/sd-card}/mp3/0079.mp3 | Bin {sd-card => src/sd-card}/mp3/0080.mp3 | Bin {sd-card => src/sd-card}/mp3/0081.mp3 | Bin {sd-card => src/sd-card}/mp3/0082.mp3 | Bin {sd-card => src/sd-card}/mp3/0083.mp3 | Bin {sd-card => src/sd-card}/mp3/0084.mp3 | Bin {sd-card => src/sd-card}/mp3/0085.mp3 | Bin {sd-card => src/sd-card}/mp3/0086.mp3 | Bin {sd-card => src/sd-card}/mp3/0087.mp3 | Bin {sd-card => src/sd-card}/mp3/0088.mp3 | Bin {sd-card => src/sd-card}/mp3/0089.mp3 | Bin {sd-card => src/sd-card}/mp3/0090.mp3 | Bin {sd-card => src/sd-card}/mp3/0091.mp3 | Bin {sd-card => src/sd-card}/mp3/0092.mp3 | Bin {sd-card => src/sd-card}/mp3/0093.mp3 | Bin {sd-card => src/sd-card}/mp3/0094.mp3 | Bin {sd-card => src/sd-card}/mp3/0095.mp3 | Bin {sd-card => src/sd-card}/mp3/0096.mp3 | Bin {sd-card => src/sd-card}/mp3/0097.mp3 | Bin {sd-card => src/sd-card}/mp3/0098.mp3 | Bin {sd-card => src/sd-card}/mp3/0099.mp3 | Bin {sd-card => src/sd-card}/mp3/0100.mp3 | Bin {sd-card => src/sd-card}/mp3/0101.mp3 | Bin {sd-card => src/sd-card}/mp3/0102.mp3 | Bin {sd-card => src/sd-card}/mp3/0103.mp3 | Bin {sd-card => src/sd-card}/mp3/0104.mp3 | Bin {sd-card => src/sd-card}/mp3/0105.mp3 | Bin {sd-card => src/sd-card}/mp3/0106.mp3 | Bin {sd-card => src/sd-card}/mp3/0107.mp3 | Bin {sd-card => src/sd-card}/mp3/0108.mp3 | Bin {sd-card => src/sd-card}/mp3/0109.mp3 | Bin {sd-card => src/sd-card}/mp3/0110.mp3 | Bin {sd-card => src/sd-card}/mp3/0111.mp3 | Bin {sd-card => src/sd-card}/mp3/0112.mp3 | Bin {sd-card => src/sd-card}/mp3/0113.mp3 | Bin {sd-card => src/sd-card}/mp3/0114.mp3 | Bin {sd-card => src/sd-card}/mp3/0115.mp3 | Bin {sd-card => src/sd-card}/mp3/0116.mp3 | Bin {sd-card => src/sd-card}/mp3/0117.mp3 | Bin {sd-card => src/sd-card}/mp3/0118.mp3 | Bin {sd-card => src/sd-card}/mp3/0119.mp3 | Bin {sd-card => src/sd-card}/mp3/0120.mp3 | Bin {sd-card => src/sd-card}/mp3/0121.mp3 | Bin {sd-card => src/sd-card}/mp3/0122.mp3 | Bin {sd-card => src/sd-card}/mp3/0123.mp3 | Bin {sd-card => src/sd-card}/mp3/0124.mp3 | Bin {sd-card => src/sd-card}/mp3/0125.mp3 | Bin {sd-card => src/sd-card}/mp3/0126.mp3 | Bin {sd-card => src/sd-card}/mp3/0127.mp3 | Bin {sd-card => src/sd-card}/mp3/0128.mp3 | Bin {sd-card => src/sd-card}/mp3/0129.mp3 | Bin {sd-card => src/sd-card}/mp3/0130.mp3 | Bin {sd-card => src/sd-card}/mp3/0131.mp3 | Bin {sd-card => src/sd-card}/mp3/0132.mp3 | Bin {sd-card => src/sd-card}/mp3/0133.mp3 | Bin {sd-card => src/sd-card}/mp3/0134.mp3 | Bin {sd-card => src/sd-card}/mp3/0135.mp3 | Bin {sd-card => src/sd-card}/mp3/0136.mp3 | Bin {sd-card => src/sd-card}/mp3/0137.mp3 | Bin {sd-card => src/sd-card}/mp3/0138.mp3 | Bin {sd-card => src/sd-card}/mp3/0139.mp3 | Bin {sd-card => src/sd-card}/mp3/0140.mp3 | Bin {sd-card => src/sd-card}/mp3/0141.mp3 | Bin {sd-card => src/sd-card}/mp3/0142.mp3 | Bin {sd-card => src/sd-card}/mp3/0143.mp3 | Bin {sd-card => src/sd-card}/mp3/0144.mp3 | Bin {sd-card => src/sd-card}/mp3/0145.mp3 | Bin {sd-card => src/sd-card}/mp3/0146.mp3 | Bin {sd-card => src/sd-card}/mp3/0147.mp3 | Bin {sd-card => src/sd-card}/mp3/0148.mp3 | Bin {sd-card => src/sd-card}/mp3/0149.mp3 | Bin {sd-card => src/sd-card}/mp3/0150.mp3 | Bin {sd-card => src/sd-card}/mp3/0151.mp3 | Bin {sd-card => src/sd-card}/mp3/0152.mp3 | Bin {sd-card => src/sd-card}/mp3/0153.mp3 | Bin {sd-card => src/sd-card}/mp3/0154.mp3 | Bin {sd-card => src/sd-card}/mp3/0155.mp3 | Bin {sd-card => src/sd-card}/mp3/0156.mp3 | Bin {sd-card => src/sd-card}/mp3/0157.mp3 | Bin {sd-card => src/sd-card}/mp3/0158.mp3 | Bin {sd-card => src/sd-card}/mp3/0159.mp3 | Bin {sd-card => src/sd-card}/mp3/0160.mp3 | Bin {sd-card => src/sd-card}/mp3/0161.mp3 | Bin {sd-card => src/sd-card}/mp3/0162.mp3 | Bin {sd-card => src/sd-card}/mp3/0163.mp3 | Bin {sd-card => src/sd-card}/mp3/0164.mp3 | Bin {sd-card => src/sd-card}/mp3/0165.mp3 | Bin {sd-card => src/sd-card}/mp3/0166.mp3 | Bin {sd-card => src/sd-card}/mp3/0167.mp3 | Bin {sd-card => src/sd-card}/mp3/0168.mp3 | Bin {sd-card => src/sd-card}/mp3/0169.mp3 | Bin {sd-card => src/sd-card}/mp3/0170.mp3 | Bin {sd-card => src/sd-card}/mp3/0171.mp3 | Bin {sd-card => src/sd-card}/mp3/0172.mp3 | Bin {sd-card => src/sd-card}/mp3/0173.mp3 | Bin {sd-card => src/sd-card}/mp3/0174.mp3 | Bin {sd-card => src/sd-card}/mp3/0175.mp3 | Bin {sd-card => src/sd-card}/mp3/0176.mp3 | Bin {sd-card => src/sd-card}/mp3/0177.mp3 | Bin {sd-card => src/sd-card}/mp3/0178.mp3 | Bin {sd-card => src/sd-card}/mp3/0179.mp3 | Bin {sd-card => src/sd-card}/mp3/0180.mp3 | Bin {sd-card => src/sd-card}/mp3/0181.mp3 | Bin {sd-card => src/sd-card}/mp3/0182.mp3 | Bin {sd-card => src/sd-card}/mp3/0183.mp3 | Bin {sd-card => src/sd-card}/mp3/0184.mp3 | Bin {sd-card => src/sd-card}/mp3/0185.mp3 | Bin {sd-card => src/sd-card}/mp3/0186.mp3 | Bin {sd-card => src/sd-card}/mp3/0187.mp3 | Bin {sd-card => src/sd-card}/mp3/0188.mp3 | Bin {sd-card => src/sd-card}/mp3/0189.mp3 | Bin {sd-card => src/sd-card}/mp3/0190.mp3 | Bin {sd-card => src/sd-card}/mp3/0191.mp3 | Bin {sd-card => src/sd-card}/mp3/0192.mp3 | Bin {sd-card => src/sd-card}/mp3/0193.mp3 | Bin {sd-card => src/sd-card}/mp3/0194.mp3 | Bin {sd-card => src/sd-card}/mp3/0195.mp3 | Bin {sd-card => src/sd-card}/mp3/0196.mp3 | Bin {sd-card => src/sd-card}/mp3/0197.mp3 | Bin {sd-card => src/sd-card}/mp3/0198.mp3 | Bin {sd-card => src/sd-card}/mp3/0199.mp3 | Bin {sd-card => src/sd-card}/mp3/0200.mp3 | Bin {sd-card => src/sd-card}/mp3/0201.mp3 | Bin {sd-card => src/sd-card}/mp3/0202.mp3 | Bin {sd-card => src/sd-card}/mp3/0203.mp3 | Bin {sd-card => src/sd-card}/mp3/0204.mp3 | Bin {sd-card => src/sd-card}/mp3/0205.mp3 | Bin {sd-card => src/sd-card}/mp3/0206.mp3 | Bin {sd-card => src/sd-card}/mp3/0207.mp3 | Bin {sd-card => src/sd-card}/mp3/0208.mp3 | Bin {sd-card => src/sd-card}/mp3/0209.mp3 | Bin {sd-card => src/sd-card}/mp3/0210.mp3 | Bin {sd-card => src/sd-card}/mp3/0211.mp3 | Bin {sd-card => src/sd-card}/mp3/0212.mp3 | Bin {sd-card => src/sd-card}/mp3/0213.mp3 | Bin {sd-card => src/sd-card}/mp3/0214.mp3 | Bin {sd-card => src/sd-card}/mp3/0215.mp3 | Bin {sd-card => src/sd-card}/mp3/0216.mp3 | Bin {sd-card => src/sd-card}/mp3/0217.mp3 | Bin {sd-card => src/sd-card}/mp3/0218.mp3 | Bin {sd-card => src/sd-card}/mp3/0219.mp3 | Bin {sd-card => src/sd-card}/mp3/0220.mp3 | Bin {sd-card => src/sd-card}/mp3/0221.mp3 | Bin {sd-card => src/sd-card}/mp3/0222.mp3 | Bin {sd-card => src/sd-card}/mp3/0223.mp3 | Bin {sd-card => src/sd-card}/mp3/0224.mp3 | Bin {sd-card => src/sd-card}/mp3/0225.mp3 | Bin {sd-card => src/sd-card}/mp3/0226.mp3 | Bin {sd-card => src/sd-card}/mp3/0227.mp3 | Bin {sd-card => src/sd-card}/mp3/0228.mp3 | Bin {sd-card => src/sd-card}/mp3/0229.mp3 | Bin {sd-card => src/sd-card}/mp3/0230.mp3 | Bin {sd-card => src/sd-card}/mp3/0231.mp3 | Bin {sd-card => src/sd-card}/mp3/0232.mp3 | Bin {sd-card => src/sd-card}/mp3/0233.mp3 | Bin {sd-card => src/sd-card}/mp3/0234.mp3 | Bin {sd-card => src/sd-card}/mp3/0235.mp3 | Bin {sd-card => src/sd-card}/mp3/0236.mp3 | Bin {sd-card => src/sd-card}/mp3/0237.mp3 | Bin {sd-card => src/sd-card}/mp3/0238.mp3 | Bin {sd-card => src/sd-card}/mp3/0239.mp3 | Bin {sd-card => src/sd-card}/mp3/0240.mp3 | Bin {sd-card => src/sd-card}/mp3/0241.mp3 | Bin {sd-card => src/sd-card}/mp3/0242.mp3 | Bin {sd-card => src/sd-card}/mp3/0243.mp3 | Bin {sd-card => src/sd-card}/mp3/0244.mp3 | Bin {sd-card => src/sd-card}/mp3/0245.mp3 | Bin {sd-card => src/sd-card}/mp3/0246.mp3 | Bin {sd-card => src/sd-card}/mp3/0247.mp3 | Bin {sd-card => src/sd-card}/mp3/0248.mp3 | Bin {sd-card => src/sd-card}/mp3/0249.mp3 | Bin {sd-card => src/sd-card}/mp3/0250.mp3 | Bin {sd-card => src/sd-card}/mp3/0251.mp3 | Bin {sd-card => src/sd-card}/mp3/0252.mp3 | Bin {sd-card => src/sd-card}/mp3/0253.mp3 | Bin {sd-card => src/sd-card}/mp3/0254.mp3 | Bin {sd-card => src/sd-card}/mp3/0255.mp3 | Bin {sd-card => src/sd-card}/mp3/0300_new_tag.mp3 | Bin .../sd-card}/mp3/0301_select_folder.mp3 | Bin {sd-card => src/sd-card}/mp3/0310.mp3 | Bin .../sd-card}/mp3/0311_mode_random_episode.mp3 | Bin .../sd-card}/mp3/0312_mode_album.mp3 | Bin .../sd-card}/mp3/0313_mode_party.mp3 | Bin .../sd-card}/mp3/0314_mode_single_track.mp3 | Bin .../sd-card}/mp3/0315_mode_audio_book.mp3 | Bin {sd-card => src/sd-card}/mp3/0316_admin.mp3 | Bin .../sd-card}/mp3/0317_special_random.mp3 | Bin .../sd-card}/mp3/0318_special_album.mp3 | Bin .../sd-card}/mp3/0319_special_party.mp3 | Bin .../sd-card}/mp3/0320_select_file.mp3 | Bin .../sd-card}/mp3/0321_select_first_file.mp3 | Bin .../sd-card}/mp3/0322_select_last_file.mp3 | Bin {sd-card => src/sd-card}/mp3/0330.mp3 | Bin {sd-card => src/sd-card}/mp3/0331.mp3 | Bin {sd-card => src/sd-card}/mp3/0332.mp3 | Bin {sd-card => src/sd-card}/mp3/0400_ok.mp3 | Bin {sd-card => src/sd-card}/mp3/0401_error.mp3 | Bin .../sd-card}/mp3/0800_waiting_for_card.mp3 | Bin .../sd-card}/mp3/0802_reset_aborted.mp3 | Bin {sd-card => src/sd-card}/mp3/0900_admin.mp3 | Bin .../sd-card}/mp3/0901_card_reset.mp3 | Bin .../sd-card}/mp3/0902_max_volume.mp3 | Bin .../sd-card}/mp3/0903_min_volume.mp3 | Bin .../sd-card}/mp3/0904_init_volume.mp3 | Bin {sd-card => src/sd-card}/mp3/0905_eq.mp3 | Bin .../sd-card}/mp3/0906_modifiers.mp3 | Bin .../sd-card}/mp3/0907_shortcut.mp3 | Bin .../sd-card}/mp3/0908_standbytimer.mp3 | Bin .../sd-card}/mp3/0909_batch_cards.mp3 | Bin .../sd-card}/mp3/0910_switch_volume.mp3 | Bin {sd-card => src/sd-card}/mp3/0911_reset.mp3 | Bin .../sd-card}/mp3/0912_admin_lock.mp3 | Bin .../sd-card}/mp3/0920_eq_intro.mp3 | Bin {sd-card => src/sd-card}/mp3/0921_normal.mp3 | Bin {sd-card => src/sd-card}/mp3/0922_pop.mp3 | Bin {sd-card => src/sd-card}/mp3/0923_rock.mp3 | Bin {sd-card => src/sd-card}/mp3/0924_jazz.mp3 | Bin {sd-card => src/sd-card}/mp3/0925_classic.mp3 | Bin {sd-card => src/sd-card}/mp3/0926_bass.mp3 | Bin .../sd-card}/mp3/0930_max_volume_intro.mp3 | Bin .../sd-card}/mp3/0931_min_volume_into.mp3 | Bin .../sd-card}/mp3/0932_init_volume_into.mp3 | Bin .../sd-card}/mp3/0933_switch_volume_intro.mp3 | Bin {sd-card => src/sd-card}/mp3/0934_no.mp3 | Bin {sd-card => src/sd-card}/mp3/0935_yes.mp3 | Bin .../sd-card}/mp3/0936_batch_cards_intro.mp3 | Bin .../sd-card}/mp3/0940_shortcut_into.mp3 | Bin {sd-card => src/sd-card}/mp3/0941_pause.mp3 | Bin {sd-card => src/sd-card}/mp3/0942_up.mp3 | Bin {sd-card => src/sd-card}/mp3/0943_down.mp3 | Bin {sd-card => src/sd-card}/mp3/0944_startup.mp3 | Bin .../sd-card}/mp3/0960_timer_intro.mp3 | Bin {sd-card => src/sd-card}/mp3/0961_timer_5.mp3 | Bin .../sd-card}/mp3/0962_timer_15.mp3 | Bin .../sd-card}/mp3/0963_timer_30.mp3 | Bin .../sd-card}/mp3/0964_timer_60.mp3 | Bin .../sd-card}/mp3/0965_timer_disabled.mp3 | Bin .../sd-card}/mp3/0970_modifier_Intro.mp3 | Bin .../sd-card}/mp3/0971_modifier_SleepTimer.mp3 | Bin .../mp3/0972_modifier_FreezeDance.mp3 | Bin .../sd-card}/mp3/0973_modifier_Locked.mp3 | Bin .../sd-card}/mp3/0974_modifier_Toddler.mp3 | Bin .../mp3/0975_modifier_KinderGarden.mp3 | Bin .../sd-card}/mp3/0976_modifier_repeat1.mp3 | Bin .../sd-card}/mp3/0980_admin_lock_intro.mp3 | Bin .../sd-card}/mp3/0981_admin_lock_disabled.mp3 | Bin .../sd-card}/mp3/0982_admin_lock_card.mp3 | Bin .../sd-card}/mp3/0983_admin_lock_pin.mp3 | Bin .../sd-card}/mp3/0984_admin_lock_calc.mp3 | Bin .../sd-card}/mp3/0991_admin_pin.mp3 | Bin .../sd-card}/mp3/0992_admin_calc.mp3 | Bin .../sd-card}/mp3/0993_admin_calc.mp3 | Bin .../sd-card}/mp3/0994_admin_calc.mp3 | Bin .../sd-card}/mp3/0999_reset_ok.mp3 | Bin soundfiles.txt => src/soundfiles.txt | 0 {tools => src/tools}/add_lead_in_messages.py | 0 {tools => src/tools}/create_audio_messages.py | 0 {tools => src/tools}/text_to_speech.py | 0 test/README | 11 + 612 files changed, 4413 insertions(+), 1047 deletions(-) create mode 100644 include/README create mode 100644 lib/README create mode 100644 platformio.ini rename LICENSE => src/LICENSE (100%) rename README.md => src/README.md (100%) rename TonUINO_Schaltplan.pdf => src/TonUINO_Schaltplan.pdf (100%) rename Tonuino.ino => src/Tonuino.cpp (98%) create mode 100644 src/Tonuino.ino.eightanaloginputs.hex create mode 100644 src/Tonuino.ino.with_bootloader.eightanaloginputs.hex rename audio_messages_de.txt => src/audio_messages_de.txt (100%) rename create-soundfiles.sh => src/create-soundfiles.sh (100%) rename {sd-card => src/sd-card}/advert/0001.mp3 (100%) rename {sd-card => src/sd-card}/advert/0002.mp3 (100%) rename {sd-card => src/sd-card}/advert/0003.mp3 (100%) rename {sd-card => src/sd-card}/advert/0004.mp3 (100%) rename {sd-card => src/sd-card}/advert/0005.mp3 (100%) rename {sd-card => src/sd-card}/advert/0006.mp3 (100%) rename {sd-card => src/sd-card}/advert/0007.mp3 (100%) rename {sd-card => src/sd-card}/advert/0008.mp3 (100%) rename {sd-card => src/sd-card}/advert/0009.mp3 (100%) rename {sd-card => src/sd-card}/advert/0010.mp3 (100%) rename {sd-card => src/sd-card}/advert/0011.mp3 (100%) rename {sd-card => src/sd-card}/advert/0012.mp3 (100%) rename {sd-card => src/sd-card}/advert/0013.mp3 (100%) rename {sd-card => src/sd-card}/advert/0014.mp3 (100%) rename {sd-card => src/sd-card}/advert/0015.mp3 (100%) rename {sd-card => src/sd-card}/advert/0016.mp3 (100%) rename {sd-card => src/sd-card}/advert/0017.mp3 (100%) rename {sd-card => src/sd-card}/advert/0018.mp3 (100%) rename {sd-card => src/sd-card}/advert/0019.mp3 (100%) rename {sd-card => src/sd-card}/advert/0020.mp3 (100%) rename {sd-card => src/sd-card}/advert/0021.mp3 (100%) rename {sd-card => src/sd-card}/advert/0022.mp3 (100%) rename {sd-card => src/sd-card}/advert/0023.mp3 (100%) rename {sd-card => src/sd-card}/advert/0024.mp3 (100%) rename {sd-card => src/sd-card}/advert/0025.mp3 (100%) rename {sd-card => src/sd-card}/advert/0026.mp3 (100%) rename {sd-card => src/sd-card}/advert/0027.mp3 (100%) rename {sd-card => src/sd-card}/advert/0028.mp3 (100%) rename {sd-card => src/sd-card}/advert/0029.mp3 (100%) rename {sd-card => src/sd-card}/advert/0030.mp3 (100%) rename {sd-card => src/sd-card}/advert/0031.mp3 (100%) rename {sd-card => src/sd-card}/advert/0032.mp3 (100%) rename {sd-card => src/sd-card}/advert/0033.mp3 (100%) rename {sd-card => src/sd-card}/advert/0034.mp3 (100%) rename {sd-card => src/sd-card}/advert/0035.mp3 (100%) rename {sd-card => src/sd-card}/advert/0036.mp3 (100%) rename {sd-card => src/sd-card}/advert/0037.mp3 (100%) rename {sd-card => src/sd-card}/advert/0038.mp3 (100%) rename {sd-card => src/sd-card}/advert/0039.mp3 (100%) rename {sd-card => src/sd-card}/advert/0040.mp3 (100%) rename {sd-card => src/sd-card}/advert/0041.mp3 (100%) rename {sd-card => src/sd-card}/advert/0042.mp3 (100%) rename {sd-card => src/sd-card}/advert/0043.mp3 (100%) rename {sd-card => src/sd-card}/advert/0044.mp3 (100%) rename {sd-card => src/sd-card}/advert/0045.mp3 (100%) rename {sd-card => src/sd-card}/advert/0046.mp3 (100%) rename {sd-card => src/sd-card}/advert/0047.mp3 (100%) rename {sd-card => src/sd-card}/advert/0048.mp3 (100%) rename {sd-card => src/sd-card}/advert/0049.mp3 (100%) rename {sd-card => src/sd-card}/advert/0050.mp3 (100%) rename {sd-card => src/sd-card}/advert/0051.mp3 (100%) rename {sd-card => src/sd-card}/advert/0052.mp3 (100%) rename {sd-card => src/sd-card}/advert/0053.mp3 (100%) rename {sd-card => src/sd-card}/advert/0054.mp3 (100%) rename {sd-card => src/sd-card}/advert/0055.mp3 (100%) rename {sd-card => src/sd-card}/advert/0056.mp3 (100%) rename {sd-card => src/sd-card}/advert/0057.mp3 (100%) rename {sd-card => src/sd-card}/advert/0058.mp3 (100%) rename {sd-card => src/sd-card}/advert/0059.mp3 (100%) rename {sd-card => src/sd-card}/advert/0060.mp3 (100%) rename {sd-card => src/sd-card}/advert/0061.mp3 (100%) rename {sd-card => src/sd-card}/advert/0062.mp3 (100%) rename {sd-card => src/sd-card}/advert/0063.mp3 (100%) rename {sd-card => src/sd-card}/advert/0064.mp3 (100%) rename {sd-card => src/sd-card}/advert/0065.mp3 (100%) rename {sd-card => src/sd-card}/advert/0066.mp3 (100%) rename {sd-card => src/sd-card}/advert/0067.mp3 (100%) rename {sd-card => src/sd-card}/advert/0068.mp3 (100%) rename {sd-card => src/sd-card}/advert/0069.mp3 (100%) rename {sd-card => src/sd-card}/advert/0070.mp3 (100%) rename {sd-card => src/sd-card}/advert/0071.mp3 (100%) rename {sd-card => src/sd-card}/advert/0072.mp3 (100%) rename {sd-card => src/sd-card}/advert/0073.mp3 (100%) rename {sd-card => src/sd-card}/advert/0074.mp3 (100%) rename {sd-card => src/sd-card}/advert/0075.mp3 (100%) rename {sd-card => src/sd-card}/advert/0076.mp3 (100%) rename {sd-card => src/sd-card}/advert/0077.mp3 (100%) rename {sd-card => src/sd-card}/advert/0078.mp3 (100%) rename {sd-card => src/sd-card}/advert/0079.mp3 (100%) rename {sd-card => src/sd-card}/advert/0080.mp3 (100%) rename {sd-card => src/sd-card}/advert/0081.mp3 (100%) rename {sd-card => src/sd-card}/advert/0082.mp3 (100%) rename {sd-card => src/sd-card}/advert/0083.mp3 (100%) rename {sd-card => src/sd-card}/advert/0084.mp3 (100%) rename {sd-card => src/sd-card}/advert/0085.mp3 (100%) rename {sd-card => src/sd-card}/advert/0086.mp3 (100%) rename {sd-card => src/sd-card}/advert/0087.mp3 (100%) rename {sd-card => src/sd-card}/advert/0088.mp3 (100%) rename {sd-card => src/sd-card}/advert/0089.mp3 (100%) rename {sd-card => src/sd-card}/advert/0090.mp3 (100%) rename {sd-card => src/sd-card}/advert/0091.mp3 (100%) rename {sd-card => src/sd-card}/advert/0092.mp3 (100%) rename {sd-card => src/sd-card}/advert/0093.mp3 (100%) rename {sd-card => src/sd-card}/advert/0094.mp3 (100%) rename {sd-card => src/sd-card}/advert/0095.mp3 (100%) rename {sd-card => src/sd-card}/advert/0096.mp3 (100%) rename {sd-card => src/sd-card}/advert/0097.mp3 (100%) rename {sd-card => src/sd-card}/advert/0098.mp3 (100%) rename {sd-card => src/sd-card}/advert/0099.mp3 (100%) rename {sd-card => src/sd-card}/advert/0100.mp3 (100%) rename {sd-card => src/sd-card}/advert/0101.mp3 (100%) rename {sd-card => src/sd-card}/advert/0102.mp3 (100%) rename {sd-card => src/sd-card}/advert/0103.mp3 (100%) rename {sd-card => src/sd-card}/advert/0104.mp3 (100%) rename {sd-card => src/sd-card}/advert/0105.mp3 (100%) rename {sd-card => src/sd-card}/advert/0106.mp3 (100%) rename {sd-card => src/sd-card}/advert/0107.mp3 (100%) rename {sd-card => src/sd-card}/advert/0108.mp3 (100%) rename {sd-card => src/sd-card}/advert/0109.mp3 (100%) rename {sd-card => src/sd-card}/advert/0110.mp3 (100%) rename {sd-card => src/sd-card}/advert/0111.mp3 (100%) rename {sd-card => src/sd-card}/advert/0112.mp3 (100%) rename {sd-card => src/sd-card}/advert/0113.mp3 (100%) rename {sd-card => src/sd-card}/advert/0114.mp3 (100%) rename {sd-card => src/sd-card}/advert/0115.mp3 (100%) rename {sd-card => src/sd-card}/advert/0116.mp3 (100%) rename {sd-card => src/sd-card}/advert/0117.mp3 (100%) rename {sd-card => src/sd-card}/advert/0118.mp3 (100%) rename {sd-card => src/sd-card}/advert/0119.mp3 (100%) rename {sd-card => src/sd-card}/advert/0120.mp3 (100%) rename {sd-card => src/sd-card}/advert/0121.mp3 (100%) rename {sd-card => src/sd-card}/advert/0122.mp3 (100%) rename {sd-card => src/sd-card}/advert/0123.mp3 (100%) rename {sd-card => src/sd-card}/advert/0124.mp3 (100%) rename {sd-card => src/sd-card}/advert/0125.mp3 (100%) rename {sd-card => src/sd-card}/advert/0126.mp3 (100%) rename {sd-card => src/sd-card}/advert/0127.mp3 (100%) rename {sd-card => src/sd-card}/advert/0128.mp3 (100%) rename {sd-card => src/sd-card}/advert/0129.mp3 (100%) rename {sd-card => src/sd-card}/advert/0130.mp3 (100%) rename {sd-card => src/sd-card}/advert/0131.mp3 (100%) rename {sd-card => src/sd-card}/advert/0132.mp3 (100%) rename {sd-card => src/sd-card}/advert/0133.mp3 (100%) rename {sd-card => src/sd-card}/advert/0134.mp3 (100%) rename {sd-card => src/sd-card}/advert/0135.mp3 (100%) rename {sd-card => src/sd-card}/advert/0136.mp3 (100%) rename {sd-card => src/sd-card}/advert/0137.mp3 (100%) rename {sd-card => src/sd-card}/advert/0138.mp3 (100%) rename {sd-card => src/sd-card}/advert/0139.mp3 (100%) rename {sd-card => src/sd-card}/advert/0140.mp3 (100%) rename {sd-card => src/sd-card}/advert/0141.mp3 (100%) rename {sd-card => src/sd-card}/advert/0142.mp3 (100%) rename {sd-card => src/sd-card}/advert/0143.mp3 (100%) rename {sd-card => src/sd-card}/advert/0144.mp3 (100%) rename {sd-card => src/sd-card}/advert/0145.mp3 (100%) rename {sd-card => src/sd-card}/advert/0146.mp3 (100%) rename {sd-card => src/sd-card}/advert/0147.mp3 (100%) rename {sd-card => src/sd-card}/advert/0148.mp3 (100%) rename {sd-card => src/sd-card}/advert/0149.mp3 (100%) rename {sd-card => src/sd-card}/advert/0150.mp3 (100%) rename {sd-card => src/sd-card}/advert/0151.mp3 (100%) rename {sd-card => src/sd-card}/advert/0152.mp3 (100%) rename {sd-card => src/sd-card}/advert/0153.mp3 (100%) rename {sd-card => src/sd-card}/advert/0154.mp3 (100%) rename {sd-card => src/sd-card}/advert/0155.mp3 (100%) rename {sd-card => src/sd-card}/advert/0156.mp3 (100%) rename {sd-card => src/sd-card}/advert/0157.mp3 (100%) rename {sd-card => src/sd-card}/advert/0158.mp3 (100%) rename {sd-card => src/sd-card}/advert/0159.mp3 (100%) rename {sd-card => src/sd-card}/advert/0160.mp3 (100%) rename {sd-card => src/sd-card}/advert/0161.mp3 (100%) rename {sd-card => src/sd-card}/advert/0162.mp3 (100%) rename {sd-card => src/sd-card}/advert/0163.mp3 (100%) rename {sd-card => src/sd-card}/advert/0164.mp3 (100%) rename {sd-card => src/sd-card}/advert/0165.mp3 (100%) rename {sd-card => src/sd-card}/advert/0166.mp3 (100%) rename {sd-card => src/sd-card}/advert/0167.mp3 (100%) rename {sd-card => src/sd-card}/advert/0168.mp3 (100%) rename {sd-card => src/sd-card}/advert/0169.mp3 (100%) rename {sd-card => src/sd-card}/advert/0170.mp3 (100%) rename {sd-card => src/sd-card}/advert/0171.mp3 (100%) rename {sd-card => src/sd-card}/advert/0172.mp3 (100%) rename {sd-card => src/sd-card}/advert/0173.mp3 (100%) rename {sd-card => src/sd-card}/advert/0174.mp3 (100%) rename {sd-card => src/sd-card}/advert/0175.mp3 (100%) rename {sd-card => src/sd-card}/advert/0176.mp3 (100%) rename {sd-card => src/sd-card}/advert/0177.mp3 (100%) rename {sd-card => src/sd-card}/advert/0178.mp3 (100%) rename {sd-card => src/sd-card}/advert/0179.mp3 (100%) rename {sd-card => src/sd-card}/advert/0180.mp3 (100%) rename {sd-card => src/sd-card}/advert/0181.mp3 (100%) rename {sd-card => src/sd-card}/advert/0182.mp3 (100%) rename {sd-card => src/sd-card}/advert/0183.mp3 (100%) rename {sd-card => src/sd-card}/advert/0184.mp3 (100%) rename {sd-card => src/sd-card}/advert/0185.mp3 (100%) rename {sd-card => src/sd-card}/advert/0186.mp3 (100%) rename {sd-card => src/sd-card}/advert/0187.mp3 (100%) rename {sd-card => src/sd-card}/advert/0188.mp3 (100%) rename {sd-card => src/sd-card}/advert/0189.mp3 (100%) rename {sd-card => src/sd-card}/advert/0190.mp3 (100%) rename {sd-card => src/sd-card}/advert/0191.mp3 (100%) rename {sd-card => src/sd-card}/advert/0192.mp3 (100%) rename {sd-card => src/sd-card}/advert/0193.mp3 (100%) rename {sd-card => src/sd-card}/advert/0194.mp3 (100%) rename {sd-card => src/sd-card}/advert/0195.mp3 (100%) rename {sd-card => src/sd-card}/advert/0196.mp3 (100%) rename {sd-card => src/sd-card}/advert/0197.mp3 (100%) rename {sd-card => src/sd-card}/advert/0198.mp3 (100%) rename {sd-card => src/sd-card}/advert/0199.mp3 (100%) rename {sd-card => src/sd-card}/advert/0200.mp3 (100%) rename {sd-card => src/sd-card}/advert/0201.mp3 (100%) rename {sd-card => src/sd-card}/advert/0202.mp3 (100%) rename {sd-card => src/sd-card}/advert/0203.mp3 (100%) rename {sd-card => src/sd-card}/advert/0204.mp3 (100%) rename {sd-card => src/sd-card}/advert/0205.mp3 (100%) rename {sd-card => src/sd-card}/advert/0206.mp3 (100%) rename {sd-card => src/sd-card}/advert/0207.mp3 (100%) rename {sd-card => src/sd-card}/advert/0208.mp3 (100%) rename {sd-card => src/sd-card}/advert/0209.mp3 (100%) rename {sd-card => src/sd-card}/advert/0210.mp3 (100%) rename {sd-card => src/sd-card}/advert/0211.mp3 (100%) rename {sd-card => src/sd-card}/advert/0212.mp3 (100%) rename {sd-card => src/sd-card}/advert/0213.mp3 (100%) rename {sd-card => src/sd-card}/advert/0214.mp3 (100%) rename {sd-card => src/sd-card}/advert/0215.mp3 (100%) rename {sd-card => src/sd-card}/advert/0216.mp3 (100%) rename {sd-card => src/sd-card}/advert/0217.mp3 (100%) rename {sd-card => src/sd-card}/advert/0218.mp3 (100%) rename {sd-card => src/sd-card}/advert/0219.mp3 (100%) rename {sd-card => src/sd-card}/advert/0220.mp3 (100%) rename {sd-card => src/sd-card}/advert/0221.mp3 (100%) rename {sd-card => src/sd-card}/advert/0222.mp3 (100%) rename {sd-card => src/sd-card}/advert/0223.mp3 (100%) rename {sd-card => src/sd-card}/advert/0224.mp3 (100%) rename {sd-card => src/sd-card}/advert/0225.mp3 (100%) rename {sd-card => src/sd-card}/advert/0226.mp3 (100%) rename {sd-card => src/sd-card}/advert/0227.mp3 (100%) rename {sd-card => src/sd-card}/advert/0228.mp3 (100%) rename {sd-card => src/sd-card}/advert/0229.mp3 (100%) rename {sd-card => src/sd-card}/advert/0230.mp3 (100%) rename {sd-card => src/sd-card}/advert/0231.mp3 (100%) rename {sd-card => src/sd-card}/advert/0232.mp3 (100%) rename {sd-card => src/sd-card}/advert/0233.mp3 (100%) rename {sd-card => src/sd-card}/advert/0234.mp3 (100%) rename {sd-card => src/sd-card}/advert/0235.mp3 (100%) rename {sd-card => src/sd-card}/advert/0236.mp3 (100%) rename {sd-card => src/sd-card}/advert/0237.mp3 (100%) rename {sd-card => src/sd-card}/advert/0238.mp3 (100%) rename {sd-card => src/sd-card}/advert/0239.mp3 (100%) rename {sd-card => src/sd-card}/advert/0240.mp3 (100%) rename {sd-card => src/sd-card}/advert/0241.mp3 (100%) rename {sd-card => src/sd-card}/advert/0242.mp3 (100%) rename {sd-card => src/sd-card}/advert/0243.mp3 (100%) rename {sd-card => src/sd-card}/advert/0244.mp3 (100%) rename {sd-card => src/sd-card}/advert/0245.mp3 (100%) rename {sd-card => src/sd-card}/advert/0246.mp3 (100%) rename {sd-card => src/sd-card}/advert/0247.mp3 (100%) rename {sd-card => src/sd-card}/advert/0248.mp3 (100%) rename {sd-card => src/sd-card}/advert/0249.mp3 (100%) rename {sd-card => src/sd-card}/advert/0250.mp3 (100%) rename {sd-card => src/sd-card}/advert/0251.mp3 (100%) rename {sd-card => src/sd-card}/advert/0252.mp3 (100%) rename {sd-card => src/sd-card}/advert/0253.mp3 (100%) rename {sd-card => src/sd-card}/advert/0254.mp3 (100%) rename {sd-card => src/sd-card}/advert/0255.mp3 (100%) rename {sd-card => src/sd-card}/advert/0260.mp3 (100%) rename {sd-card => src/sd-card}/advert/0261.mp3 (100%) rename {sd-card => src/sd-card}/advert/0300_freeze_into.mp3 (100%) rename {sd-card => src/sd-card}/advert/0301_freeze_freeze.mp3 (100%) rename {sd-card => src/sd-card}/advert/0302_sleep.mp3 (100%) rename {sd-card => src/sd-card}/advert/0303_locked.mp3 (100%) rename {sd-card => src/sd-card}/advert/0304_buttonslocked.mp3 (100%) rename {sd-card => src/sd-card}/advert/0305_kindergarden.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0001.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0002.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0003.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0004.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0005.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0006.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0007.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0008.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0009.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0010.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0011.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0012.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0013.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0014.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0015.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0016.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0017.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0018.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0019.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0020.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0021.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0022.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0023.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0024.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0025.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0026.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0027.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0028.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0029.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0030.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0031.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0032.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0033.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0034.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0035.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0036.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0037.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0038.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0039.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0040.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0041.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0042.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0043.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0044.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0045.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0046.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0047.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0048.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0049.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0050.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0051.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0052.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0053.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0054.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0055.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0056.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0057.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0058.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0059.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0060.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0061.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0062.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0063.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0064.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0065.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0066.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0067.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0068.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0069.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0070.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0071.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0072.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0073.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0074.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0075.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0076.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0077.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0078.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0079.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0080.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0081.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0082.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0083.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0084.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0085.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0086.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0087.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0088.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0089.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0090.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0091.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0092.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0093.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0094.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0095.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0096.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0097.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0098.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0099.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0100.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0101.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0102.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0103.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0104.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0105.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0106.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0107.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0108.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0109.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0110.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0111.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0112.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0113.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0114.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0115.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0116.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0117.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0118.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0119.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0120.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0121.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0122.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0123.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0124.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0125.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0126.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0127.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0128.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0129.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0130.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0131.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0132.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0133.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0134.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0135.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0136.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0137.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0138.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0139.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0140.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0141.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0142.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0143.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0144.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0145.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0146.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0147.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0148.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0149.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0150.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0151.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0152.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0153.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0154.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0155.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0156.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0157.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0158.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0159.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0160.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0161.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0162.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0163.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0164.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0165.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0166.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0167.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0168.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0169.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0170.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0171.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0172.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0173.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0174.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0175.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0176.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0177.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0178.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0179.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0180.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0181.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0182.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0183.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0184.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0185.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0186.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0187.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0188.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0189.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0190.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0191.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0192.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0193.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0194.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0195.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0196.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0197.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0198.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0199.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0200.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0201.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0202.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0203.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0204.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0205.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0206.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0207.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0208.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0209.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0210.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0211.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0212.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0213.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0214.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0215.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0216.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0217.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0218.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0219.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0220.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0221.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0222.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0223.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0224.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0225.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0226.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0227.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0228.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0229.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0230.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0231.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0232.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0233.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0234.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0235.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0236.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0237.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0238.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0239.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0240.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0241.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0242.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0243.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0244.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0245.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0246.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0247.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0248.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0249.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0250.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0251.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0252.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0253.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0254.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0255.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0300_new_tag.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0301_select_folder.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0310.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0311_mode_random_episode.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0312_mode_album.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0313_mode_party.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0314_mode_single_track.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0315_mode_audio_book.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0316_admin.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0317_special_random.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0318_special_album.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0319_special_party.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0320_select_file.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0321_select_first_file.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0322_select_last_file.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0330.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0331.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0332.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0400_ok.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0401_error.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0800_waiting_for_card.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0802_reset_aborted.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0900_admin.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0901_card_reset.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0902_max_volume.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0903_min_volume.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0904_init_volume.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0905_eq.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0906_modifiers.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0907_shortcut.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0908_standbytimer.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0909_batch_cards.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0910_switch_volume.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0911_reset.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0912_admin_lock.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0920_eq_intro.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0921_normal.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0922_pop.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0923_rock.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0924_jazz.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0925_classic.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0926_bass.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0930_max_volume_intro.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0931_min_volume_into.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0932_init_volume_into.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0933_switch_volume_intro.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0934_no.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0935_yes.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0936_batch_cards_intro.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0940_shortcut_into.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0941_pause.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0942_up.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0943_down.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0944_startup.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0960_timer_intro.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0961_timer_5.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0962_timer_15.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0963_timer_30.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0964_timer_60.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0965_timer_disabled.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0970_modifier_Intro.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0971_modifier_SleepTimer.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0972_modifier_FreezeDance.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0973_modifier_Locked.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0974_modifier_Toddler.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0975_modifier_KinderGarden.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0976_modifier_repeat1.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0980_admin_lock_intro.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0981_admin_lock_disabled.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0982_admin_lock_card.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0983_admin_lock_pin.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0984_admin_lock_calc.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0991_admin_pin.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0992_admin_calc.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0993_admin_calc.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0994_admin_calc.mp3 (100%) rename {sd-card => src/sd-card}/mp3/0999_reset_ok.mp3 (100%) rename soundfiles.txt => src/soundfiles.txt (100%) rename {tools => src/tools}/add_lead_in_messages.py (100%) mode change 100755 => 100644 rename {tools => src/tools}/create_audio_messages.py (100%) mode change 100755 => 100644 rename {tools => src/tools}/text_to_speech.py (100%) mode change 100755 => 100644 create mode 100644 test/README diff --git a/.gitignore b/.gitignore index 0aab59b2..bddee316 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,10 @@ Temporary Items # TonUINO /tools/*.pyc + +# PIO/VSCode +.pio/ +.vscode/ + +*/sd-card/01 +*/sd-card/02 \ No newline at end of file diff --git a/include/README b/include/README new file mode 100644 index 00000000..194dcd43 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 00000000..6debab1e --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 00000000..3fa3f402 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,19 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nanoatmega328] +platform = atmelavr +board = nanoatmega328 +framework = arduino +lib_deps = + miguelbalboa/MFRC522@^1.4.7 + makuna/DFPlayer Mini Mp3 by Makuna@^1.0.7 + jchristensen/JC_Button@^2.1.2 +monitor_speed = 115200 diff --git a/LICENSE b/src/LICENSE similarity index 100% rename from LICENSE rename to src/LICENSE diff --git a/README.md b/src/README.md similarity index 100% rename from README.md rename to src/README.md diff --git a/TonUINO_Schaltplan.pdf b/src/TonUINO_Schaltplan.pdf similarity index 100% rename from TonUINO_Schaltplan.pdf rename to src/TonUINO_Schaltplan.pdf diff --git a/Tonuino.ino b/src/Tonuino.cpp similarity index 98% rename from Tonuino.ino rename to src/Tonuino.cpp index 5401e132..adada345 100644 --- a/Tonuino.ino +++ b/src/Tonuino.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -28,6 +29,55 @@ static const uint32_t cardCookie = 322417479; +// MFRC522 +#define RST_PIN 9 // Configurable, see typical pin layout above +#define SS_PIN 10 // Configurable, see typical pin layout above +MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 +MFRC522::MIFARE_Key key; +bool successRead; +byte sector = 1; +byte blockAddr = 4; +byte trailerBlock = 7; +MFRC522::StatusCode status; + +//#define NFCgain_max // Maximale Empfindlichkeit +#define NFCgain_avg // Mittlere Empfindlichkeit +//#define NFCgain_min // Minimale Empfindlichkeit + +#define buttonPause A0 +#define buttonUp A1 +#define buttonDown A2 +#define busyPin 4 +#define shutdownPin 7 +#define openAnalogPin A7 + +#ifdef FIVEBUTTONS +#define buttonFourPin A3 +#define buttonFivePin A4 +#endif + +#ifdef SpkOnOff + #define SpkOnPin 5 // Lautsprecher Ein + bool SpkisOn = false; // Marker Lautsprecher Ein/Aus +#endif + +#define LONG_PRESS 1000 + +Button pauseButton(buttonPause); +Button upButton(buttonUp); +Button downButton(buttonDown); +#ifdef FIVEBUTTONS +Button buttonFour(buttonFourPin); +Button buttonFive(buttonFivePin); +#endif +bool ignorePauseButton = false; +bool ignoreUpButton = false; +bool ignoreDownButton = false; +#ifdef FIVEBUTTONS +bool ignoreButtonFour = false; +bool ignoreButtonFive = false; +#endif + // DFPlayer Mini SoftwareSerial mySoftwareSerial(2, 3); // RX, TX uint16_t numTracksInFolder; @@ -229,6 +279,138 @@ void loadSettingsFromFlash() { Serial.println(mySettings.adminMenuPin[3]); } +/// Funktionen für den Standby Timer (z.B. über Pololu-Switch oder Mosfet) + +void setstandbyTimer() { + Serial.println(F("=== setstandbyTimer()")); + if (mySettings.standbyTimer != 0) + sleepAtMillis = millis() + (mySettings.standbyTimer * 60 * 1000); + else + sleepAtMillis = 0; + Serial.println(sleepAtMillis); +} + +void disablestandbyTimer() { + Serial.println(F("=== disablestandby()")); + sleepAtMillis = 0; +} + +void checkStandbyAtMillis() { + if (sleepAtMillis != 0 && millis() > sleepAtMillis) { + Serial.println(F("=== power off!")); + // enter sleep state + digitalWrite(shutdownPin, HIGH); + delay(500); + + // http://discourse.voss.earth/t/intenso-s10000-powerbank-automatische-abschaltung-software-only/805 + // powerdown to 27mA (powerbank switches off after 30-60s) + mfrc522.PCD_AntennaOff(); + mfrc522.PCD_SoftPowerDown(); + mp3.sleep(); + + set_sleep_mode(SLEEP_MODE_PWR_DOWN); + cli(); // Disable interrupts + sleep_mode(); + } +} + +void playFolder() { + Serial.println(F("== playFolder()")) ; + disablestandbyTimer(); + knownCard = true; + _lastTrackFinished = 0; + numTracksInFolder = mp3.getFolderTrackCount(myFolder->folder); + firstTrack = 1; + Serial.print(numTracksInFolder); + Serial.print(F(" Dateien in Ordner ")); + Serial.println(myFolder->folder); + + // Hörspielmodus: eine zufällige Datei aus dem Ordner + if (myFolder->mode == 1) { + Serial.println(F("Hörspielmodus -> zufälligen Track wiedergeben")); + currentTrack = random(1, numTracksInFolder + 1); + Serial.println(currentTrack); + mp3.playFolderTrack(myFolder->folder, currentTrack); + } + // Album Modus: kompletten Ordner spielen + if (myFolder->mode == 2) { + Serial.println(F("Album Modus -> kompletten Ordner wiedergeben")); + currentTrack = 1; + mp3.playFolderTrack(myFolder->folder, currentTrack); + } + // Party Modus: Ordner in zufälliger Reihenfolge + if (myFolder->mode == 3) { + Serial.println( + F("Party Modus -> Ordner in zufälliger Reihenfolge wiedergeben")); + shuffleQueue(); + currentTrack = 1; + mp3.playFolderTrack(myFolder->folder, queue[currentTrack - 1]); + } + // Einzel Modus: eine Datei aus dem Ordner abspielen + if (myFolder->mode == 4) { + Serial.println( + F("Einzel Modus -> eine Datei aus dem Odrdner abspielen")); + currentTrack = myFolder->special; + mp3.playFolderTrack(myFolder->folder, currentTrack); + } + // Hörbuch Modus: kompletten Ordner spielen und Fortschritt merken + if (myFolder->mode == 5) { + Serial.println(F("Hörbuch Modus -> kompletten Ordner spielen und " + "Fortschritt merken")); + currentTrack = EEPROM.read(myFolder->folder); + if (currentTrack == 0 || currentTrack > numTracksInFolder) { + currentTrack = 1; + } + mp3.playFolderTrack(myFolder->folder, currentTrack); + } + // Spezialmodus Von-Bin: Hörspiel: eine zufällige Datei aus dem Ordner + if (myFolder->mode == 7) { + Serial.println(F("Spezialmodus Von-Bin: Hörspiel -> zufälligen Track wiedergeben")); + Serial.print(myFolder->special); + Serial.print(F(" bis ")); + Serial.println(myFolder->special2); + numTracksInFolder = myFolder->special2; + currentTrack = random(myFolder->special, numTracksInFolder + 1); + Serial.println(currentTrack); + mp3.playFolderTrack(myFolder->folder, currentTrack); + } + + // Spezialmodus Von-Bis: Album: alle Dateien zwischen Start und Ende spielen + if (myFolder->mode == 8) { + Serial.println(F("Spezialmodus Von-Bis: Album: alle Dateien zwischen Start- und Enddatei spielen")); + Serial.print(myFolder->special); + Serial.print(F(" bis ")); + Serial.println(myFolder->special2); + numTracksInFolder = myFolder->special2; + currentTrack = myFolder->special; + mp3.playFolderTrack(myFolder->folder, currentTrack); + } + + // Spezialmodus Von-Bis: Party Ordner in zufälliger Reihenfolge + if (myFolder->mode == 9) { + Serial.println( + F("Spezialmodus Von-Bis: Party -> Ordner in zufälliger Reihenfolge wiedergeben")); + firstTrack = myFolder->special; + numTracksInFolder = myFolder->special2; + shuffleQueue(); + currentTrack = 1; + mp3.playFolderTrack(myFolder->folder, queue[currentTrack - 1]); + } +} + +void playShortCut(uint8_t shortCut) { + Serial.println(F("=== playShortCut()")); + Serial.println(shortCut); + if (mySettings.shortCuts[shortCut].folder != 0) { + myFolder = &mySettings.shortCuts[shortCut]; + playFolder(); + disablestandbyTimer(); + delay(1000); + } + else + Serial.println(F("Shortcut not configured!")); +} + class Modifier { public: virtual void loop() {} @@ -633,231 +815,49 @@ static void previousTrack() { delay(1000); } -// MFRC522 -#define RST_PIN 9 // Configurable, see typical pin layout above -#define SS_PIN 10 // Configurable, see typical pin layout above -MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 -MFRC522::MIFARE_Key key; -bool successRead; -byte sector = 1; -byte blockAddr = 4; -byte trailerBlock = 7; -MFRC522::StatusCode status; - -#define NFCgain_max // Maximale Empfindlichkeit -//#define NFCgain_avg // Mittlere Empfindlichkeit -//#define NFCgain_min // Minimale Empfindlichkeit +bool isPlaying() { + return !digitalRead(busyPin); +} -#define buttonPause A0 -#define buttonUp A1 -#define buttonDown A2 -#define busyPin 4 -#define shutdownPin 7 -#define openAnalogPin A7 +void waitForTrackToFinish() { + unsigned long currentTime = millis(); +#define TIMEOUT 1000 + do { + mp3.loop(); + } while (!isPlaying() && millis() < currentTime + TIMEOUT); + delay(1000); + do { + mp3.loop(); + } while (isPlaying()); +} +void readButtons() { + pauseButton.read(); + upButton.read(); + downButton.read(); #ifdef FIVEBUTTONS -#define buttonFourPin A3 -#define buttonFivePin A4 -#endif - -#ifdef SpkOnOff - #define SpkOnPin 6 // Lautsprecher Ein - bool SpkisOn = false; // Marker Lautsprecher Ein/Aus + buttonFour.read(); + buttonFive.read(); #endif +} -#define LONG_PRESS 1000 +void volumeUpButton() { + if (activeModifier != NULL) + if (activeModifier->handleVolumeUp() == true) + return; -Button pauseButton(buttonPause); -Button upButton(buttonUp); -Button downButton(buttonDown); -#ifdef FIVEBUTTONS -Button buttonFour(buttonFourPin); -Button buttonFive(buttonFivePin); -#endif -bool ignorePauseButton = false; -bool ignoreUpButton = false; -bool ignoreDownButton = false; -#ifdef FIVEBUTTONS -bool ignoreButtonFour = false; -bool ignoreButtonFive = false; -#endif + Serial.println(F("=== volumeUp()")); + if (volume < mySettings.maxVolume) { + mp3.increaseVolume(); + volume++; + } + Serial.println(volume); +} -/// Funktionen für den Standby Timer (z.B. über Pololu-Switch oder Mosfet) - -void setstandbyTimer() { - Serial.println(F("=== setstandbyTimer()")); - if (mySettings.standbyTimer != 0) - sleepAtMillis = millis() + (mySettings.standbyTimer * 60 * 1000); - else - sleepAtMillis = 0; - Serial.println(sleepAtMillis); -} - -void disablestandbyTimer() { - Serial.println(F("=== disablestandby()")); - sleepAtMillis = 0; -} - -void checkStandbyAtMillis() { - if (sleepAtMillis != 0 && millis() > sleepAtMillis) { - Serial.println(F("=== power off!")); - // enter sleep state - digitalWrite(shutdownPin, HIGH); - delay(500); - - // http://discourse.voss.earth/t/intenso-s10000-powerbank-automatische-abschaltung-software-only/805 - // powerdown to 27mA (powerbank switches off after 30-60s) - mfrc522.PCD_AntennaOff(); - mfrc522.PCD_SoftPowerDown(); - mp3.sleep(); - - set_sleep_mode(SLEEP_MODE_PWR_DOWN); - cli(); // Disable interrupts - sleep_mode(); - } -} - -bool isPlaying() { - return !digitalRead(busyPin); -} - -void waitForTrackToFinish() { - long currentTime = millis(); -#define TIMEOUT 1000 - do { - mp3.loop(); - } while (!isPlaying() && millis() < currentTime + TIMEOUT); - delay(1000); - do { - mp3.loop(); - } while (isPlaying()); -} - -void setup() { - - Serial.begin(115200); // Es gibt ein paar Debug Ausgaben über die serielle Schnittstelle - - // Wert für randomSeed() erzeugen durch das mehrfache Sammeln von rauschenden LSBs eines offenen Analogeingangs - uint32_t ADC_LSB; - uint32_t ADCSeed; - for (uint8_t i = 0; i < 128; i++) { - ADC_LSB = analogRead(openAnalogPin) & 0x1; - ADCSeed ^= ADC_LSB << (i % 32); - } - randomSeed(ADCSeed); // Zufallsgenerator initialisieren - - // Dieser Hinweis darf nicht entfernt werden - Serial.println(F("\n _____ _____ _____ _____ _____")); - Serial.println(F("|_ _|___ ___| | | | | | |")); - Serial.println(F(" | | | . | | | |- -| | | | | |")); - Serial.println(F(" |_| |___|_|_|_____|_____|_|___|_____|\n")); - Serial.println(F("TonUINO Version 2.1")); - Serial.println(F("created by Thorsten Voß and licensed under GNU/GPL.")); - Serial.println(F("Information and contribution at https://tonuino.de.\n")); - -#ifdef SpkOnOff - pinMode(SpkOnPin, OUTPUT); // Ausgang Lautsprecher-Einschaltsignal - spkOff(); // Voreinstellung - Speaker Off -#endif - - // Busy Pin - pinMode(busyPin, INPUT); - - // load Settings from EEPROM - loadSettingsFromFlash(); - - // activate standby timer - setstandbyTimer(); - - // DFPlayer Mini initialisieren - mp3.begin(); - // Zwei Sekunden warten bis der DFPlayer Mini initialisiert ist - delay(2000); - volume = mySettings.initVolume; - mp3.setVolume(volume); - mp3.setEq(mySettings.eq - 1); - // Fix für das Problem mit dem Timeout (ist jetzt in Upstream daher nicht mehr nötig!) - //mySoftwareSerial.setTimeout(10000); - - // NFC Leser initialisieren - SPI.begin(); // Init SPI bus - mfrc522.PCD_Init(); // Init MFRC522 - -#ifdef NFCgain_min - mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_min); - Serial.println(F("=== mfrc522-> RxGain_min === ")); -#endif -#ifdef NFCgain_avg - mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_avg); - Serial.println(F("=== mfrc522-> RxGain_avg === ")); -#endif -#ifdef NFCgain_max - mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); - Serial.println(F("=== mfrc522-> RxGain_max === ")); -#endif - - mfrc522 - .PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader - for (byte i = 0; i < 6; i++) { - key.keyByte[i] = 0xFF; - } - - pinMode(buttonPause, INPUT_PULLUP); - pinMode(buttonUp, INPUT_PULLUP); - pinMode(buttonDown, INPUT_PULLUP); -#ifdef FIVEBUTTONS - pinMode(buttonFourPin, INPUT_PULLUP); - pinMode(buttonFivePin, INPUT_PULLUP); -#endif - pinMode(shutdownPin, OUTPUT); - digitalWrite(shutdownPin, LOW); - -#ifdef SpkOnOff - spkOn(); -#endif - - // RESET --- ALLE DREI KNÖPFE BEIM STARTEN GEDRÜCKT HALTEN -> alle EINSTELLUNGEN werden gelöscht - if (digitalRead(buttonPause) == LOW && digitalRead(buttonUp) == LOW && - digitalRead(buttonDown) == LOW) { - Serial.println(F("Reset -> EEPROM wird gelöscht")); - for (int i = 0; i < EEPROM.length(); i++) { - EEPROM.update(i, 0); - } - loadSettingsFromFlash(); - } - - - // Start Shortcut "at Startup" - e.g. Welcome Sound - playShortCut(3); -} - -void readButtons() { - pauseButton.read(); - upButton.read(); - downButton.read(); -#ifdef FIVEBUTTONS - buttonFour.read(); - buttonFive.read(); -#endif -} - -void volumeUpButton() { - if (activeModifier != NULL) - if (activeModifier->handleVolumeUp() == true) - return; - - Serial.println(F("=== volumeUp()")); - if (volume < mySettings.maxVolume) { - mp3.increaseVolume(); - volume++; - } - Serial.println(volume); -} - -void volumeDownButton() { - if (activeModifier != NULL) - if (activeModifier->handleVolumeDown() == true) - return; +void volumeDownButton() { + if (activeModifier != NULL) + if (activeModifier->handleVolumeDown() == true) + return; Serial.println(F("=== volumeDown()")); if (volume > mySettings.minVolume) { @@ -885,602 +885,335 @@ void previousButton() { delay(1000); } -void playFolder() { - Serial.println(F("== playFolder()")) ; - disablestandbyTimer(); - knownCard = true; - _lastTrackFinished = 0; - numTracksInFolder = mp3.getFolderTrackCount(myFolder->folder); - firstTrack = 1; - Serial.print(numTracksInFolder); - Serial.print(F(" Dateien in Ordner ")); - Serial.println(myFolder->folder); - - // Hörspielmodus: eine zufällige Datei aus dem Ordner - if (myFolder->mode == 1) { - Serial.println(F("Hörspielmodus -> zufälligen Track wiedergeben")); - currentTrack = random(1, numTracksInFolder + 1); - Serial.println(currentTrack); - mp3.playFolderTrack(myFolder->folder, currentTrack); - } - // Album Modus: kompletten Ordner spielen - if (myFolder->mode == 2) { - Serial.println(F("Album Modus -> kompletten Ordner wiedergeben")); - currentTrack = 1; - mp3.playFolderTrack(myFolder->folder, currentTrack); - } - // Party Modus: Ordner in zufälliger Reihenfolge - if (myFolder->mode == 3) { - Serial.println( - F("Party Modus -> Ordner in zufälliger Reihenfolge wiedergeben")); - shuffleQueue(); - currentTrack = 1; - mp3.playFolderTrack(myFolder->folder, queue[currentTrack - 1]); - } - // Einzel Modus: eine Datei aus dem Ordner abspielen - if (myFolder->mode == 4) { - Serial.println( - F("Einzel Modus -> eine Datei aus dem Odrdner abspielen")); - currentTrack = myFolder->special; - mp3.playFolderTrack(myFolder->folder, currentTrack); - } - // Hörbuch Modus: kompletten Ordner spielen und Fortschritt merken - if (myFolder->mode == 5) { - Serial.println(F("Hörbuch Modus -> kompletten Ordner spielen und " - "Fortschritt merken")); - currentTrack = EEPROM.read(myFolder->folder); - if (currentTrack == 0 || currentTrack > numTracksInFolder) { - currentTrack = 1; +uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, + bool preview, int previewFromFolder, int defaultValue, bool exitWithLongPress) { + uint8_t returnValue = defaultValue; + if (startMessage != 0) + mp3.playMp3FolderTrack(startMessage); + Serial.print(F("=== voiceMenu() (")); + Serial.print(numberOfOptions); + Serial.println(F(" Options)")); + do { + if (Serial.available() > 0) { + int optionSerial = Serial.parseInt(); + if (optionSerial != 0 && optionSerial <= numberOfOptions) + return optionSerial; } - mp3.playFolderTrack(myFolder->folder, currentTrack); - } - // Spezialmodus Von-Bin: Hörspiel: eine zufällige Datei aus dem Ordner - if (myFolder->mode == 7) { - Serial.println(F("Spezialmodus Von-Bin: Hörspiel -> zufälligen Track wiedergeben")); - Serial.print(myFolder->special); - Serial.print(F(" bis ")); - Serial.println(myFolder->special2); - numTracksInFolder = myFolder->special2; - currentTrack = random(myFolder->special, numTracksInFolder + 1); - Serial.println(currentTrack); - mp3.playFolderTrack(myFolder->folder, currentTrack); - } - - // Spezialmodus Von-Bis: Album: alle Dateien zwischen Start und Ende spielen - if (myFolder->mode == 8) { - Serial.println(F("Spezialmodus Von-Bis: Album: alle Dateien zwischen Start- und Enddatei spielen")); - Serial.print(myFolder->special); - Serial.print(F(" bis ")); - Serial.println(myFolder->special2); - numTracksInFolder = myFolder->special2; - currentTrack = myFolder->special; - mp3.playFolderTrack(myFolder->folder, currentTrack); - } - - // Spezialmodus Von-Bis: Party Ordner in zufälliger Reihenfolge - if (myFolder->mode == 9) { - Serial.println( - F("Spezialmodus Von-Bis: Party -> Ordner in zufälliger Reihenfolge wiedergeben")); - firstTrack = myFolder->special; - numTracksInFolder = myFolder->special2; - shuffleQueue(); - currentTrack = 1; - mp3.playFolderTrack(myFolder->folder, queue[currentTrack - 1]); - } -} - -void playShortCut(uint8_t shortCut) { - Serial.println(F("=== playShortCut()")); - Serial.println(shortCut); - if (mySettings.shortCuts[shortCut].folder != 0) { - myFolder = &mySettings.shortCuts[shortCut]; - playFolder(); - disablestandbyTimer(); - delay(1000); - } - else - Serial.println(F("Shortcut not configured!")); -} - -void loop() { - do { - checkStandbyAtMillis(); - mp3.loop(); - - // Modifier : WIP! - if (activeModifier != NULL) { - activeModifier->loop(); - } - - // Buttons werden nun über JS_Button gehandelt, dadurch kann jede Taste - // doppelt belegt werden readButtons(); - - // admin menu - if ((pauseButton.pressedFor(LONG_PRESS) || upButton.pressedFor(LONG_PRESS) || downButton.pressedFor(LONG_PRESS)) && pauseButton.isPressed() && upButton.isPressed() && downButton.isPressed()) { - mp3.pause(); - do { - readButtons(); - } while (pauseButton.isPressed() || upButton.isPressed() || downButton.isPressed()); - readButtons(); - adminMenu(); - break; + mp3.loop(); + if (pauseButton.pressedFor(LONG_PRESS)) { + mp3.playMp3FolderTrack(802); + ignorePauseButton = true; + checkStandbyAtMillis(); + return defaultValue; } - if (pauseButton.wasReleased()) { - if (activeModifier != NULL) - if (activeModifier->handlePause() == true) - return; - if (ignorePauseButton == false) - if (isPlaying()) { - mp3.pause(); - setstandbyTimer(); - } - else if (knownCard) { - mp3.start(); - disablestandbyTimer(); - } - ignorePauseButton = false; - } else if (pauseButton.pressedFor(LONG_PRESS) && - ignorePauseButton == false) { - if (activeModifier != NULL) - if (activeModifier->handlePause() == true) - return; - if (isPlaying()) { - uint8_t advertTrack; - if (myFolder->mode == 3 || myFolder->mode == 9) { - advertTrack = (queue[currentTrack - 1]); - } - else { - advertTrack = currentTrack; - } - // Spezialmodus Von-Bis für Album und Party gibt die Dateinummer relativ zur Startposition wieder - if (myFolder->mode == 8 || myFolder->mode == 9) { - advertTrack = advertTrack - myFolder->special + 1; - } - mp3.playAdvertisement(advertTrack); - } - else { - playShortCut(0); + if (returnValue != 0) { + Serial.print(F("=== ")); + Serial.print(returnValue); + Serial.println(F(" ===")); + return returnValue; } - ignorePauseButton = true; + delay(1000); } if (upButton.pressedFor(LONG_PRESS)) { -#ifndef FIVEBUTTONS - if (isPlaying()) { - if (!mySettings.invertVolumeButtons) { - volumeUpButton(); - } - else { - nextButton(); - } - } - else { - playShortCut(1); - } + returnValue = min(returnValue + 10, numberOfOptions); + Serial.println(returnValue); + //mp3.pause(); + mp3.playMp3FolderTrack(messageOffset + returnValue); + waitForTrackToFinish(); + /*if (preview) { + if (previewFromFolder == 0) + mp3.playFolderTrack(returnValue, 1); + else + mp3.playFolderTrack(previewFromFolder, returnValue); + }*/ ignoreUpButton = true; -#endif } else if (upButton.wasReleased()) { - if (!ignoreUpButton) - if (!mySettings.invertVolumeButtons) { - nextButton(); - } - else { - volumeUpButton(); + if (!ignoreUpButton) { + returnValue = min(returnValue + 1, numberOfOptions); + Serial.println(returnValue); + //mp3.pause(); + mp3.playMp3FolderTrack(messageOffset + returnValue); + if (preview) { + waitForTrackToFinish(); + if (previewFromFolder == 0) { + mp3.playFolderTrack(returnValue, 1); + } else { + mp3.playFolderTrack(previewFromFolder, returnValue); + } + delay(1000); } - ignoreUpButton = false; + } else { + ignoreUpButton = false; + } } if (downButton.pressedFor(LONG_PRESS)) { -#ifndef FIVEBUTTONS - if (isPlaying()) { - if (!mySettings.invertVolumeButtons) { - volumeDownButton(); - } - else { - previousButton(); - } - } - else { - playShortCut(2); - } + returnValue = max(returnValue - 10, 1); + Serial.println(returnValue); + //mp3.pause(); + mp3.playMp3FolderTrack(messageOffset + returnValue); + waitForTrackToFinish(); + /*if (preview) { + if (previewFromFolder == 0) + mp3.playFolderTrack(returnValue, 1); + else + mp3.playFolderTrack(previewFromFolder, returnValue); + }*/ ignoreDownButton = true; -#endif } else if (downButton.wasReleased()) { if (!ignoreDownButton) { - if (!mySettings.invertVolumeButtons) { - previousButton(); - } - else { - volumeDownButton(); - } - } - ignoreDownButton = false; - } -#ifdef FIVEBUTTONS - if (buttonFour.wasReleased()) { - if (isPlaying()) { - if (!mySettings.invertVolumeButtons) { - volumeUpButton(); - } - else { - nextButton(); - } - } - else { - playShortCut(1); - } - } - if (buttonFive.wasReleased()) { - if (isPlaying()) { - if (!mySettings.invertVolumeButtons) { - volumeDownButton(); - } - else { - previousButton(); + returnValue = max(returnValue - 1, 1); + Serial.println(returnValue); + //mp3.pause(); + mp3.playMp3FolderTrack(messageOffset + returnValue); + if (preview) { + waitForTrackToFinish(); + if (previewFromFolder == 0) { + mp3.playFolderTrack(returnValue, 1); + } + else { + mp3.playFolderTrack(previewFromFolder, returnValue); + } + delay(1000); } - } - else { - playShortCut(2); + } else { + ignoreDownButton = false; } } -#endif - // Ende der Buttons - } while (!mfrc522.PICC_IsNewCardPresent()); + } while (true); +} - // RFID Karte wurde aufgelegt +bool setupFolder(folderSettings * theFolder) { + // Ordner abfragen + theFolder->folder = voiceMenu(99, 301, 0, true, 0, 0, true); + if (theFolder->folder == 0) return false; - if (!mfrc522.PICC_ReadCardSerial()) - return; + // Wiedergabemodus abfragen + theFolder->mode = voiceMenu(9, 310, 310, false, 0, 0, true); + if (theFolder->mode == 0) return false; - if (readCard(&myCard) == true) { - if (myCard.cookie == cardCookie && myCard.nfcFolderSettings.folder != 0 && myCard.nfcFolderSettings.mode != 0) { - playFolder(); - } + // // Hörbuchmodus -> Fortschritt im EEPROM auf 1 setzen + // EEPROM.update(theFolder->folder, 1); - // Neue Karte konfigurieren - else if (myCard.cookie != cardCookie) { - knownCard = false; - mp3.playMp3FolderTrack(300); - waitForTrackToFinish(); - setupCard(); - } + // Einzelmodus -> Datei abfragen + if (theFolder->mode == 4) + theFolder->special = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 320, 0, + true, theFolder->folder); + // Admin Funktionen + if (theFolder->mode == 6) { + //theFolder->special = voiceMenu(3, 320, 320); + theFolder->folder = 0; + theFolder->mode = 255; } - mfrc522.PICC_HaltA(); - mfrc522.PCD_StopCrypto1(); + // Spezialmodus Von-Bis + if (theFolder->mode == 7 || theFolder->mode == 8 || theFolder->mode == 9) { + theFolder->special = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 321, 0, + true, theFolder->folder); + theFolder->special2 = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 322, 0, + true, theFolder->folder, theFolder->special); + } + return true; } -void adminMenu(bool fromCard = false) { - disablestandbyTimer(); + +void setupCard() { mp3.pause(); - Serial.println(F("=== adminMenu()")); - knownCard = false; - if (fromCard == false) { - // Admin menu has been locked - it still can be trigged via admin card - if (mySettings.adminMenuLocked == 1) { - return; - } - // Pin check - else if (mySettings.adminMenuLocked == 2) { - uint8_t pin[4]; - mp3.playMp3FolderTrack(991); - if (askCode(pin) == true) { - if (checkTwo(pin, mySettings.adminMenuPin) == false) { - return; - } - } else { - return; - } - } - // Match check - else if (mySettings.adminMenuLocked == 3) { - uint8_t a = random(10, 20); - uint8_t b = random(1, 10); - uint8_t c; - mp3.playMp3FolderTrack(992); - waitForTrackToFinish(); - mp3.playMp3FolderTrack(a); - - if (random(1, 3) == 2) { - // a + b - c = a + b; - waitForTrackToFinish(); - mp3.playMp3FolderTrack(993); - } else { - // a - b - b = random(1, a); - c = a - b; - waitForTrackToFinish(); - mp3.playMp3FolderTrack(994); - } - waitForTrackToFinish(); - mp3.playMp3FolderTrack(b); - Serial.println(c); - uint8_t temp = voiceMenu(255, 0, 0, false); - if (temp != c) { - return; - } - } - } - int subMenu = voiceMenu(12, 900, 900, false, false, 0, true); - if (subMenu == 0) - return; - if (subMenu == 1) { - resetCard(); - mfrc522.PICC_HaltA(); - mfrc522.PCD_StopCrypto1(); - } - else if (subMenu == 2) { - // Maximum Volume - mySettings.maxVolume = voiceMenu(30 - mySettings.minVolume, 930, mySettings.minVolume, false, false, mySettings.maxVolume - mySettings.minVolume) + mySettings.minVolume; - } - else if (subMenu == 3) { - // Minimum Volume - mySettings.minVolume = voiceMenu(mySettings.maxVolume - 1, 931, 0, false, false, mySettings.minVolume); - } - else if (subMenu == 4) { - // Initial Volume - mySettings.initVolume = voiceMenu(mySettings.maxVolume - mySettings.minVolume + 1, 932, mySettings.minVolume - 1, false, false, mySettings.initVolume - mySettings.minVolume + 1) + mySettings.minVolume - 1; - } - else if (subMenu == 5) { - // EQ - mySettings.eq = voiceMenu(6, 920, 920, false, false, mySettings.eq); - mp3.setEq(mySettings.eq - 1); + Serial.println(F("=== setupCard()")); + nfcTagObject newCard; + if (setupFolder(&newCard.nfcFolderSettings) == true) + { + // Karte ist konfiguriert -> speichern + mp3.pause(); + do { + } while (isPlaying()); + writeCard(newCard); } - else if (subMenu == 6) { - // create modifier card - nfcTagObject tempCard; - tempCard.cookie = cardCookie; - tempCard.version = 1; - tempCard.nfcFolderSettings.folder = 0; - tempCard.nfcFolderSettings.special = 0; - tempCard.nfcFolderSettings.special2 = 0; - tempCard.nfcFolderSettings.mode = voiceMenu(6, 970, 970, false, false, 0, true); + delay(1000); +} - if (tempCard.nfcFolderSettings.mode != 0) { - if (tempCard.nfcFolderSettings.mode == 1) { - switch (voiceMenu(4, 960, 960)) { - case 1: tempCard.nfcFolderSettings.special = 5; break; - case 2: tempCard.nfcFolderSettings.special = 15; break; - case 3: tempCard.nfcFolderSettings.special = 30; break; - case 4: tempCard.nfcFolderSettings.special = 60; break; - } - } - mp3.playMp3FolderTrack(800); - do { - readButtons(); - if (upButton.wasReleased() || downButton.wasReleased()) { - Serial.println(F("Abgebrochen!")); - mp3.playMp3FolderTrack(802); - return; - } - } while (!mfrc522.PICC_IsNewCardPresent()); +bool readCard(nfcTagObject * nfcTag) { + nfcTagObject tempCard; + // Show some details of the PICC (that is: the tag/card) + Serial.print(F("Card UID:")); + dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size); + Serial.println(); + Serial.print(F("PICC type: ")); + MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); + Serial.println(mfrc522.PICC_GetTypeName(piccType)); - // RFID Karte wurde aufgelegt - if (mfrc522.PICC_ReadCardSerial()) { - Serial.println(F("schreibe Karte...")); - writeCard(tempCard); - delay(100); - mfrc522.PICC_HaltA(); - mfrc522.PCD_StopCrypto1(); - waitForTrackToFinish(); - } - } + byte buffer[18]; + byte size = sizeof(buffer); + + // Authenticate using key A + if ((piccType == MFRC522::PICC_TYPE_MIFARE_MINI ) || + (piccType == MFRC522::PICC_TYPE_MIFARE_1K ) || + (piccType == MFRC522::PICC_TYPE_MIFARE_4K ) ) + { + Serial.println(F("Authenticating Classic using key A...")); + status = mfrc522.PCD_Authenticate( + MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid)); } - else if (subMenu == 7) { - uint8_t shortcut = voiceMenu(4, 940, 940); - setupFolder(&mySettings.shortCuts[shortcut - 1]); - mp3.playMp3FolderTrack(400); + else if (piccType == MFRC522::PICC_TYPE_MIFARE_UL ) + { + byte pACK[] = {0, 0}; //16 bit PassWord ACK returned by the tempCard + + // Authenticate using key A + Serial.println(F("Authenticating MIFARE UL...")); + status = mfrc522.PCD_NTAG216_AUTH(key.keyByte, pACK); } - else if (subMenu == 8) { - switch (voiceMenu(5, 960, 960)) { - case 1: mySettings.standbyTimer = 5; break; - case 2: mySettings.standbyTimer = 15; break; - case 3: mySettings.standbyTimer = 30; break; - case 4: mySettings.standbyTimer = 60; break; - case 5: mySettings.standbyTimer = 0; break; - } + + if (status != MFRC522::STATUS_OK) { + Serial.print(F("PCD_Authenticate() failed: ")); + Serial.println(mfrc522.GetStatusCodeName(status)); + return false; } - else if (subMenu == 9) { - // Create Cards for Folder - // Ordner abfragen - nfcTagObject tempCard; - tempCard.cookie = cardCookie; - tempCard.version = 1; - tempCard.nfcFolderSettings.mode = 4; - tempCard.nfcFolderSettings.folder = voiceMenu(99, 301, 0, true); - uint8_t special = voiceMenu(mp3.getFolderTrackCount(tempCard.nfcFolderSettings.folder), 321, 0, - true, tempCard.nfcFolderSettings.folder); - uint8_t special2 = voiceMenu(mp3.getFolderTrackCount(tempCard.nfcFolderSettings.folder), 322, 0, - true, tempCard.nfcFolderSettings.folder, special); - mp3.playMp3FolderTrack(936); - waitForTrackToFinish(); - for (uint8_t x = special; x <= special2; x++) { - mp3.playMp3FolderTrack(x); - tempCard.nfcFolderSettings.special = x; - Serial.print(x); - Serial.println(F(" Karte auflegen")); - do { - readButtons(); - if (upButton.wasReleased() || downButton.wasReleased()) { - Serial.println(F("Abgebrochen!")); - mp3.playMp3FolderTrack(802); - return; - } - } while (!mfrc522.PICC_IsNewCardPresent()); + // Show the whole sector as it currently is + // Serial.println(F("Current data in sector:")); + // mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector); + // Serial.println(); - // RFID Karte wurde aufgelegt - if (mfrc522.PICC_ReadCardSerial()) { - Serial.println(F("schreibe Karte...")); - writeCard(tempCard); - delay(100); - mfrc522.PICC_HaltA(); - mfrc522.PCD_StopCrypto1(); - waitForTrackToFinish(); - } - } - } - else if (subMenu == 10) { - // Invert Functions for Up/Down Buttons - int temp = voiceMenu(2, 933, 933, false); - if (temp == 2) { - mySettings.invertVolumeButtons = true; - } - else { - mySettings.invertVolumeButtons = false; - } - } - else if (subMenu == 11) { - Serial.println(F("Reset -> EEPROM wird gelöscht")); - for (int i = 0; i < EEPROM.length(); i++) { - EEPROM.update(i, 0); - } - resetSettings(); - mp3.playMp3FolderTrack(999); - } - // lock admin menu - else if (subMenu == 12) { - int temp = voiceMenu(4, 980, 980, false); - if (temp == 1) { - mySettings.adminMenuLocked = 0; - } - else if (temp == 2) { - mySettings.adminMenuLocked = 1; - } - else if (temp == 3) { - int8_t pin[4]; - mp3.playMp3FolderTrack(991); - if (askCode(pin)) { - memcpy(mySettings.adminMenuPin, pin, 4); - mySettings.adminMenuLocked = 2; - } - } - else if (temp == 4) { - mySettings.adminMenuLocked = 3; + // Read data from the block + if ((piccType == MFRC522::PICC_TYPE_MIFARE_MINI ) || + (piccType == MFRC522::PICC_TYPE_MIFARE_1K ) || + (piccType == MFRC522::PICC_TYPE_MIFARE_4K ) ) + { + Serial.print(F("Reading data from block ")); + Serial.print(blockAddr); + Serial.println(F(" ...")); + status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(blockAddr, buffer, &size); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("MIFARE_Read() failed: ")); + Serial.println(mfrc522.GetStatusCodeName(status)); + return false; } - } - writeSettingsToFlash(); - setstandbyTimer(); -} + else if (piccType == MFRC522::PICC_TYPE_MIFARE_UL ) + { + byte buffer2[18]; + byte size2 = sizeof(buffer2); -bool askCode(uint8_t *code) { - uint8_t x = 0; - while (x < 4) { - readButtons(); - if (pauseButton.pressedFor(LONG_PRESS)) - break; - if (pauseButton.wasReleased()) - code[x++] = 1; - if (upButton.wasReleased()) - code[x++] = 2; - if (downButton.wasReleased()) - code[x++] = 3; - } - return true; -} + status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(8, buffer2, &size2); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("MIFARE_Read_1() failed: ")); + Serial.println(mfrc522.GetStatusCodeName(status)); + return false; + } + memcpy(buffer, buffer2, 4); -uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, - bool preview = false, int previewFromFolder = 0, int defaultValue = 0, bool exitWithLongPress = false) { - uint8_t returnValue = defaultValue; - if (startMessage != 0) - mp3.playMp3FolderTrack(startMessage); - Serial.print(F("=== voiceMenu() (")); - Serial.print(numberOfOptions); - Serial.println(F(" Options)")); - do { - if (Serial.available() > 0) { - int optionSerial = Serial.parseInt(); - if (optionSerial != 0 && optionSerial <= numberOfOptions) - return optionSerial; + status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(9, buffer2, &size2); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("MIFARE_Read_2() failed: ")); + Serial.println(mfrc522.GetStatusCodeName(status)); + return false; } - readButtons(); - mp3.loop(); - if (pauseButton.pressedFor(LONG_PRESS)) { - mp3.playMp3FolderTrack(802); - ignorePauseButton = true; - checkStandbyAtMillis(); - return defaultValue; + memcpy(buffer + 4, buffer2, 4); + + status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(10, buffer2, &size2); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("MIFARE_Read_3() failed: ")); + Serial.println(mfrc522.GetStatusCodeName(status)); + return false; } - if (pauseButton.wasReleased()) { - if (returnValue != 0) { - Serial.print(F("=== ")); - Serial.print(returnValue); - Serial.println(F(" ===")); - return returnValue; - } - delay(1000); + memcpy(buffer + 8, buffer2, 4); + + status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(11, buffer2, &size2); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("MIFARE_Read_4() failed: ")); + Serial.println(mfrc522.GetStatusCodeName(status)); + return false; } + memcpy(buffer + 12, buffer2, 4); + } - if (upButton.pressedFor(LONG_PRESS)) { - returnValue = min(returnValue + 10, numberOfOptions); - Serial.println(returnValue); - //mp3.pause(); - mp3.playMp3FolderTrack(messageOffset + returnValue); - waitForTrackToFinish(); - /*if (preview) { - if (previewFromFolder == 0) - mp3.playFolderTrack(returnValue, 1); - else - mp3.playFolderTrack(previewFromFolder, returnValue); - }*/ - ignoreUpButton = true; - } else if (upButton.wasReleased()) { - if (!ignoreUpButton) { - returnValue = min(returnValue + 1, numberOfOptions); - Serial.println(returnValue); - //mp3.pause(); - mp3.playMp3FolderTrack(messageOffset + returnValue); - if (preview) { - waitForTrackToFinish(); - if (previewFromFolder == 0) { - mp3.playFolderTrack(returnValue, 1); - } else { - mp3.playFolderTrack(previewFromFolder, returnValue); - } - delay(1000); - } - } else { - ignoreUpButton = false; + Serial.print(F("Data on Card ")); + Serial.println(F(":")); + dump_byte_array(buffer, 16); + Serial.println(); + Serial.println(); + + uint32_t tempCookie; + tempCookie = (uint32_t)buffer[0] << 24; + tempCookie += (uint32_t)buffer[1] << 16; + tempCookie += (uint32_t)buffer[2] << 8; + tempCookie += (uint32_t)buffer[3]; + + tempCard.cookie = tempCookie; + tempCard.version = buffer[4]; + tempCard.nfcFolderSettings.folder = buffer[5]; + tempCard.nfcFolderSettings.mode = buffer[6]; + tempCard.nfcFolderSettings.special = buffer[7]; + tempCard.nfcFolderSettings.special2 = buffer[8]; + + if (tempCard.cookie == cardCookie) { + + if (activeModifier != NULL && tempCard.nfcFolderSettings.folder != 0) { + if (activeModifier->handleRFID(&tempCard) == true) { + return false; } } - if (downButton.pressedFor(LONG_PRESS)) { - returnValue = max(returnValue - 10, 1); - Serial.println(returnValue); - //mp3.pause(); - mp3.playMp3FolderTrack(messageOffset + returnValue); - waitForTrackToFinish(); - /*if (preview) { - if (previewFromFolder == 0) - mp3.playFolderTrack(returnValue, 1); - else - mp3.playFolderTrack(previewFromFolder, returnValue); - }*/ - ignoreDownButton = true; - } else if (downButton.wasReleased()) { - if (!ignoreDownButton) { - returnValue = max(returnValue - 1, 1); - Serial.println(returnValue); - //mp3.pause(); - mp3.playMp3FolderTrack(messageOffset + returnValue); - if (preview) { - waitForTrackToFinish(); - if (previewFromFolder == 0) { - mp3.playFolderTrack(returnValue, 1); + if (tempCard.nfcFolderSettings.folder == 0) { + if (activeModifier != NULL) { + if (activeModifier->getActive() == tempCard.nfcFolderSettings.mode) { + activeModifier = NULL; + Serial.println(F("modifier removed")); + if (isPlaying()) { + mp3.playAdvertisement(261); } else { - mp3.playFolderTrack(previewFromFolder, returnValue); + mp3.start(); + delay(100); + mp3.playAdvertisement(261); + delay(100); + mp3.pause(); } - delay(1000); + delay(2000); + return false; } - } else { - ignoreDownButton = false; } + if (tempCard.nfcFolderSettings.mode != 0 && tempCard.nfcFolderSettings.mode != 255) { + if (isPlaying()) { + mp3.playAdvertisement(260); + } + else { + mp3.start(); + delay(100); + mp3.playAdvertisement(260); + delay(100); + mp3.pause(); + } + } + switch (tempCard.nfcFolderSettings.mode ) { + case 0: + case 255: + mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); adminMenu(true); break; + case 1: activeModifier = new SleepTimer(tempCard.nfcFolderSettings.special); break; + case 2: activeModifier = new FreezeDance(); break; + case 3: activeModifier = new Locked(); break; + case 4: activeModifier = new ToddlerMode(); break; + case 5: activeModifier = new KindergardenMode(); break; + case 6: activeModifier = new RepeatSingleModifier(); break; + + } + delay(2000); + return false; } - } while (true); + else { + memcpy(nfcTag, &tempCard, sizeof(nfcTagObject)); + Serial.println( nfcTag->nfcFolderSettings.folder); + myFolder = &nfcTag->nfcFolderSettings; + Serial.println( myFolder->folder); + } + return true; + } + else { + memcpy(nfcTag, &tempCard, sizeof(nfcTagObject)); + return true; + } } void resetCard() { @@ -1504,364 +1237,641 @@ void resetCard() { setupCard(); } -bool setupFolder(folderSettings * theFolder) { - // Ordner abfragen - theFolder->folder = voiceMenu(99, 301, 0, true, 0, 0, true); - if (theFolder->folder == 0) return false; - - // Wiedergabemodus abfragen - theFolder->mode = voiceMenu(9, 310, 310, false, 0, 0, true); - if (theFolder->mode == 0) return false; - - // // Hörbuchmodus -> Fortschritt im EEPROM auf 1 setzen - // EEPROM.update(theFolder->folder, 1); - - // Einzelmodus -> Datei abfragen - if (theFolder->mode == 4) - theFolder->special = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 320, 0, - true, theFolder->folder); - // Admin Funktionen - if (theFolder->mode == 6) { - //theFolder->special = voiceMenu(3, 320, 320); - theFolder->folder = 0; - theFolder->mode = 255; - } - // Spezialmodus Von-Bis - if (theFolder->mode == 7 || theFolder->mode == 8 || theFolder->mode == 9) { - theFolder->special = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 321, 0, - true, theFolder->folder); - theFolder->special2 = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 322, 0, - true, theFolder->folder, theFolder->special); - } - return true; -} - -void setupCard() { - mp3.pause(); - Serial.println(F("=== setupCard()")); - nfcTagObject newCard; - if (setupFolder(&newCard.nfcFolderSettings) == true) - { - // Karte ist konfiguriert -> speichern - mp3.pause(); - do { - } while (isPlaying()); - writeCard(newCard); - } - delay(1000); -} -bool readCard(nfcTagObject * nfcTag) { - nfcTagObject tempCard; - // Show some details of the PICC (that is: the tag/card) - Serial.print(F("Card UID:")); - dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size); - Serial.println(); - Serial.print(F("PICC type: ")); - MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); - Serial.println(mfrc522.PICC_GetTypeName(piccType)); +void writeCard(nfcTagObject nfcTag) { + MFRC522::PICC_Type mifareType; + byte buffer[16] = {0x13, 0x37, 0xb3, 0x47, // 0x1337 0xb347 magic cookie to + // identify our nfc tags + 0x02, // version 1 + nfcTag.nfcFolderSettings.folder, // the folder picked by the user + nfcTag.nfcFolderSettings.mode, // the playback mode picked by the user + nfcTag.nfcFolderSettings.special, // track or function for admin cards + nfcTag.nfcFolderSettings.special2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; - byte buffer[18]; - byte size = sizeof(buffer); + //byte size = sizeof(buffer); - // Authenticate using key A - if ((piccType == MFRC522::PICC_TYPE_MIFARE_MINI ) || - (piccType == MFRC522::PICC_TYPE_MIFARE_1K ) || - (piccType == MFRC522::PICC_TYPE_MIFARE_4K ) ) + mifareType = mfrc522.PICC_GetType(mfrc522.uid.sak); + + // Authenticate using key B + //authentificate with the card and set card specific parameters + if ((mifareType == MFRC522::PICC_TYPE_MIFARE_MINI ) || + (mifareType == MFRC522::PICC_TYPE_MIFARE_1K ) || + (mifareType == MFRC522::PICC_TYPE_MIFARE_4K ) ) { - Serial.println(F("Authenticating Classic using key A...")); + Serial.println(F("Authenticating again using key A...")); status = mfrc522.PCD_Authenticate( MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid)); } - else if (piccType == MFRC522::PICC_TYPE_MIFARE_UL ) + else if (mifareType == MFRC522::PICC_TYPE_MIFARE_UL ) { - byte pACK[] = {0, 0}; //16 bit PassWord ACK returned by the tempCard + byte pACK[] = {0, 0}; //16 bit PassWord ACK returned by the NFCtag // Authenticate using key A - Serial.println(F("Authenticating MIFARE UL...")); + Serial.println(F("Authenticating UL...")); status = mfrc522.PCD_NTAG216_AUTH(key.keyByte, pACK); } if (status != MFRC522::STATUS_OK) { Serial.print(F("PCD_Authenticate() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); - return false; + mp3.playMp3FolderTrack(401); + return; } - // Show the whole sector as it currently is - // Serial.println(F("Current data in sector:")); - // mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector); - // Serial.println(); + // Write data to the block + Serial.print(F("Writing data into block ")); + Serial.print(blockAddr); + Serial.println(F(" ...")); + dump_byte_array(buffer, 16); + Serial.println(); - // Read data from the block - if ((piccType == MFRC522::PICC_TYPE_MIFARE_MINI ) || - (piccType == MFRC522::PICC_TYPE_MIFARE_1K ) || - (piccType == MFRC522::PICC_TYPE_MIFARE_4K ) ) + if ((mifareType == MFRC522::PICC_TYPE_MIFARE_MINI ) || + (mifareType == MFRC522::PICC_TYPE_MIFARE_1K ) || + (mifareType == MFRC522::PICC_TYPE_MIFARE_4K ) ) { - Serial.print(F("Reading data from block ")); - Serial.print(blockAddr); - Serial.println(F(" ...")); - status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(blockAddr, buffer, &size); - if (status != MFRC522::STATUS_OK) { - Serial.print(F("MIFARE_Read() failed: ")); - Serial.println(mfrc522.GetStatusCodeName(status)); - return false; - } + status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(blockAddr, buffer, 16); } - else if (piccType == MFRC522::PICC_TYPE_MIFARE_UL ) + else if (mifareType == MFRC522::PICC_TYPE_MIFARE_UL ) { - byte buffer2[18]; + byte buffer2[16]; byte size2 = sizeof(buffer2); - status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(8, buffer2, &size2); - if (status != MFRC522::STATUS_OK) { - Serial.print(F("MIFARE_Read_1() failed: ")); - Serial.println(mfrc522.GetStatusCodeName(status)); - return false; - } - memcpy(buffer, buffer2, 4); + memset(buffer2, 0, size2); + memcpy(buffer2, buffer, 4); + status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(8, buffer2, 16); - status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(9, buffer2, &size2); - if (status != MFRC522::STATUS_OK) { - Serial.print(F("MIFARE_Read_2() failed: ")); - Serial.println(mfrc522.GetStatusCodeName(status)); - return false; - } - memcpy(buffer + 4, buffer2, 4); + memset(buffer2, 0, size2); + memcpy(buffer2, buffer + 4, 4); + status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(9, buffer2, 16); - status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(10, buffer2, &size2); - if (status != MFRC522::STATUS_OK) { - Serial.print(F("MIFARE_Read_3() failed: ")); - Serial.println(mfrc522.GetStatusCodeName(status)); - return false; - } - memcpy(buffer + 8, buffer2, 4); + memset(buffer2, 0, size2); + memcpy(buffer2, buffer + 8, 4); + status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(10, buffer2, 16); - status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(11, buffer2, &size2); - if (status != MFRC522::STATUS_OK) { - Serial.print(F("MIFARE_Read_4() failed: ")); - Serial.println(mfrc522.GetStatusCodeName(status)); - return false; - } - memcpy(buffer + 12, buffer2, 4); + memset(buffer2, 0, size2); + memcpy(buffer2, buffer + 12, 4); + status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(11, buffer2, 16); } - Serial.print(F("Data on Card ")); - Serial.println(F(":")); - dump_byte_array(buffer, 16); - Serial.println(); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("MIFARE_Write() failed: ")); + Serial.println(mfrc522.GetStatusCodeName(status)); + mp3.playMp3FolderTrack(401); + } + else + mp3.playMp3FolderTrack(400); Serial.println(); + delay(2000); +} - uint32_t tempCookie; - tempCookie = (uint32_t)buffer[0] << 24; - tempCookie += (uint32_t)buffer[1] << 16; - tempCookie += (uint32_t)buffer[2] << 8; - tempCookie += (uint32_t)buffer[3]; +// ************************** Speaker On-Off ***************************************** - tempCard.cookie = tempCookie; - tempCard.version = buffer[4]; - tempCard.nfcFolderSettings.folder = buffer[5]; - tempCard.nfcFolderSettings.mode = buffer[6]; - tempCard.nfcFolderSettings.special = buffer[7]; - tempCard.nfcFolderSettings.special2 = buffer[8]; +// **************************Speaker On ******************* +#ifdef SpkOnOff +void spkOn() + { + digitalWrite(SpkOnPin, HIGH); // Lautsprecher über Mosfets Einschalten + Serial.println(F("Lautsprecher wird eingeschaltet!")); + SpkisOn = true; + } - if (tempCard.cookie == cardCookie) { +// **************************Speaker Off ******************* +void spkOff() { + digitalWrite(SpkOnPin, LOW); // Lautsprecher über Mosfets Ausschalten + Serial.println(F("Lautsprecher wird ausgeschaltet!")); + SpkisOn = false; +} - if (activeModifier != NULL && tempCard.nfcFolderSettings.folder != 0) { - if (activeModifier->handleRFID(&tempCard) == true) { - return false; +//void SpkrOnOff() { +// SpkOn(); // Lautsprecher über Mosfets Einschalten +//} +#endif + +// ************************** END Speaker On-Off ************************************** + +/** + Helper routine to dump a byte array as hex values to Serial. +*/ +void dump_byte_array(byte * buffer, byte bufferSize) { + for (byte i = 0; i < bufferSize; i++) { + Serial.print(buffer[i] < 0x10 ? " 0" : " "); + Serial.print(buffer[i], HEX); + } +} + +///////////////////////////////////////// Check Bytes /////////////////////////////////// +bool checkTwo ( uint8_t a[], uint8_t b[] ) { + for ( uint8_t k = 0; k < 4; k++ ) { // Loop 4 times + if ( a[k] != b[k] ) { // IF a != b then false, because: one fails, all fail + return false; + } + } + return true; +} + + +bool askCode(uint8_t *code) { + uint8_t x = 0; + while (x < 4) { + readButtons(); + if (pauseButton.pressedFor(LONG_PRESS)) + break; + if (pauseButton.wasReleased()) + code[x++] = 1; + if (upButton.wasReleased()) + code[x++] = 2; + if (downButton.wasReleased()) + code[x++] = 3; + } + return true; +} + +void adminMenu(bool fromCard) { + disablestandbyTimer(); + mp3.pause(); + Serial.println(F("=== adminMenu()")); + knownCard = false; + if (fromCard == false) { + // Admin menu has been locked - it still can be trigged via admin card + if (mySettings.adminMenuLocked == 1) { + return; + } + // Pin check + else if (mySettings.adminMenuLocked == 2) { + uint8_t pin[4]; + mp3.playMp3FolderTrack(991); + if (askCode(pin) == true) { + if (checkTwo(pin, mySettings.adminMenuPin) == false) { + return; + } + } else { + return; + } + } + // Match check + else if (mySettings.adminMenuLocked == 3) { + uint8_t a = random(10, 20); + uint8_t b = random(1, 10); + uint8_t c; + mp3.playMp3FolderTrack(992); + waitForTrackToFinish(); + mp3.playMp3FolderTrack(a); + + if (random(1, 3) == 2) { + // a + b + c = a + b; + waitForTrackToFinish(); + mp3.playMp3FolderTrack(993); + } else { + // a - b + b = random(1, a); + c = a - b; + waitForTrackToFinish(); + mp3.playMp3FolderTrack(994); + } + waitForTrackToFinish(); + mp3.playMp3FolderTrack(b); + Serial.println(c); + uint8_t temp = voiceMenu(255, 0, 0, false); + if (temp != c) { + return; } } + } + int subMenu = voiceMenu(12, 900, 900, false, false, 0, true); + if (subMenu == 0) + return; + if (subMenu == 1) { + resetCard(); + mfrc522.PICC_HaltA(); + mfrc522.PCD_StopCrypto1(); + } + else if (subMenu == 2) { + // Maximum Volume + mySettings.maxVolume = voiceMenu(30 - mySettings.minVolume, 930, mySettings.minVolume, false, false, mySettings.maxVolume - mySettings.minVolume) + mySettings.minVolume; + } + else if (subMenu == 3) { + // Minimum Volume + mySettings.minVolume = voiceMenu(mySettings.maxVolume - 1, 931, 0, false, false, mySettings.minVolume); + } + else if (subMenu == 4) { + // Initial Volume + mySettings.initVolume = voiceMenu(mySettings.maxVolume - mySettings.minVolume + 1, 932, mySettings.minVolume - 1, false, false, mySettings.initVolume - mySettings.minVolume + 1) + mySettings.minVolume - 1; + } + else if (subMenu == 5) { + // EQ + mySettings.eq = voiceMenu(6, 920, 920, false, false, mySettings.eq); + mp3.setEq(static_cast(mySettings.eq - 1)); + } + else if (subMenu == 6) { + // create modifier card + nfcTagObject tempCard; + tempCard.cookie = cardCookie; + tempCard.version = 1; + tempCard.nfcFolderSettings.folder = 0; + tempCard.nfcFolderSettings.special = 0; + tempCard.nfcFolderSettings.special2 = 0; + tempCard.nfcFolderSettings.mode = voiceMenu(6, 970, 970, false, false, 0, true); - if (tempCard.nfcFolderSettings.folder == 0) { - if (activeModifier != NULL) { - if (activeModifier->getActive() == tempCard.nfcFolderSettings.mode) { - activeModifier = NULL; - Serial.println(F("modifier removed")); - if (isPlaying()) { - mp3.playAdvertisement(261); - } - else { - mp3.start(); - delay(100); - mp3.playAdvertisement(261); - delay(100); - mp3.pause(); - } - delay(2000); - return false; + if (tempCard.nfcFolderSettings.mode != 0) { + if (tempCard.nfcFolderSettings.mode == 1) { + switch (voiceMenu(4, 960, 960)) { + case 1: tempCard.nfcFolderSettings.special = 5; break; + case 2: tempCard.nfcFolderSettings.special = 15; break; + case 3: tempCard.nfcFolderSettings.special = 30; break; + case 4: tempCard.nfcFolderSettings.special = 60; break; } } - if (tempCard.nfcFolderSettings.mode != 0 && tempCard.nfcFolderSettings.mode != 255) { - if (isPlaying()) { - mp3.playAdvertisement(260); - } - else { - mp3.start(); - delay(100); - mp3.playAdvertisement(260); - delay(100); - mp3.pause(); + mp3.playMp3FolderTrack(800); + do { + readButtons(); + if (upButton.wasReleased() || downButton.wasReleased()) { + Serial.println(F("Abgebrochen!")); + mp3.playMp3FolderTrack(802); + return; } + } while (!mfrc522.PICC_IsNewCardPresent()); + + // RFID Karte wurde aufgelegt + if (mfrc522.PICC_ReadCardSerial()) { + Serial.println(F("schreibe Karte...")); + writeCard(tempCard); + delay(100); + mfrc522.PICC_HaltA(); + mfrc522.PCD_StopCrypto1(); + waitForTrackToFinish(); } - switch (tempCard.nfcFolderSettings.mode ) { - case 0: - case 255: - mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); adminMenu(true); break; - case 1: activeModifier = new SleepTimer(tempCard.nfcFolderSettings.special); break; - case 2: activeModifier = new FreezeDance(); break; - case 3: activeModifier = new Locked(); break; - case 4: activeModifier = new ToddlerMode(); break; - case 5: activeModifier = new KindergardenMode(); break; - case 6: activeModifier = new RepeatSingleModifier(); break; + } + } + else if (subMenu == 7) { + uint8_t shortcut = voiceMenu(4, 940, 940); + setupFolder(&mySettings.shortCuts[shortcut - 1]); + mp3.playMp3FolderTrack(400); + } + else if (subMenu == 8) { + switch (voiceMenu(5, 960, 960)) { + case 1: mySettings.standbyTimer = 5; break; + case 2: mySettings.standbyTimer = 15; break; + case 3: mySettings.standbyTimer = 30; break; + case 4: mySettings.standbyTimer = 60; break; + case 5: mySettings.standbyTimer = 0; break; + } + } + else if (subMenu == 9) { + // Create Cards for Folder + // Ordner abfragen + nfcTagObject tempCard; + tempCard.cookie = cardCookie; + tempCard.version = 1; + tempCard.nfcFolderSettings.mode = 4; + tempCard.nfcFolderSettings.folder = voiceMenu(99, 301, 0, true); + uint8_t special = voiceMenu(mp3.getFolderTrackCount(tempCard.nfcFolderSettings.folder), 321, 0, + true, tempCard.nfcFolderSettings.folder); + uint8_t special2 = voiceMenu(mp3.getFolderTrackCount(tempCard.nfcFolderSettings.folder), 322, 0, + true, tempCard.nfcFolderSettings.folder, special); + + mp3.playMp3FolderTrack(936); + waitForTrackToFinish(); + for (uint8_t x = special; x <= special2; x++) { + mp3.playMp3FolderTrack(x); + tempCard.nfcFolderSettings.special = x; + Serial.print(x); + Serial.println(F(" Karte auflegen")); + do { + readButtons(); + if (upButton.wasReleased() || downButton.wasReleased()) { + Serial.println(F("Abgebrochen!")); + mp3.playMp3FolderTrack(802); + return; + } + } while (!mfrc522.PICC_IsNewCardPresent()); + // RFID Karte wurde aufgelegt + if (mfrc522.PICC_ReadCardSerial()) { + Serial.println(F("schreibe Karte...")); + writeCard(tempCard); + delay(100); + mfrc522.PICC_HaltA(); + mfrc522.PCD_StopCrypto1(); + waitForTrackToFinish(); } - delay(2000); - return false; + } + } + else if (subMenu == 10) { + // Invert Functions for Up/Down Buttons + int temp = voiceMenu(2, 933, 933, false); + if (temp == 2) { + mySettings.invertVolumeButtons = true; } else { - memcpy(nfcTag, &tempCard, sizeof(nfcTagObject)); - Serial.println( nfcTag->nfcFolderSettings.folder); - myFolder = &nfcTag->nfcFolderSettings; - Serial.println( myFolder->folder); + mySettings.invertVolumeButtons = false; } - return true; } - else { - memcpy(nfcTag, &tempCard, sizeof(nfcTagObject)); - return true; + else if (subMenu == 11) { + Serial.println(F("Reset -> EEPROM wird gelöscht")); + for (unsigned int i = 0; i < EEPROM.length(); i++) { + EEPROM.update(i, 0); + } + resetSettings(); + mp3.playMp3FolderTrack(999); + } + // lock admin menu + else if (subMenu == 12) { + int temp = voiceMenu(4, 980, 980, false); + if (temp == 1) { + mySettings.adminMenuLocked = 0; + } + else if (temp == 2) { + mySettings.adminMenuLocked = 1; + } + else if (temp == 3) { + uint8_t pin[4]; + mp3.playMp3FolderTrack(991); + if (askCode(pin)) { + memcpy(mySettings.adminMenuPin, pin, 4); + mySettings.adminMenuLocked = 2; + } + } + else if (temp == 4) { + mySettings.adminMenuLocked = 3; + } + } + writeSettingsToFlash(); + setstandbyTimer(); } +void setup() { -void writeCard(nfcTagObject nfcTag) { - MFRC522::PICC_Type mifareType; - byte buffer[16] = {0x13, 0x37, 0xb3, 0x47, // 0x1337 0xb347 magic cookie to - // identify our nfc tags - 0x02, // version 1 - nfcTag.nfcFolderSettings.folder, // the folder picked by the user - nfcTag.nfcFolderSettings.mode, // the playback mode picked by the user - nfcTag.nfcFolderSettings.special, // track or function for admin cards - nfcTag.nfcFolderSettings.special2, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; + Serial.begin(115200); // Es gibt ein paar Debug Ausgaben über die serielle Schnittstelle - byte size = sizeof(buffer); + // Wert für randomSeed() erzeugen durch das mehrfache Sammeln von rauschenden LSBs eines offenen Analogeingangs + uint32_t ADC_LSB; + uint32_t ADCSeed; + for (uint8_t i = 0; i < 128; i++) { + ADC_LSB = analogRead(openAnalogPin) & 0x1; + ADCSeed ^= ADC_LSB << (i % 32); + } + randomSeed(ADCSeed); // Zufallsgenerator initialisieren - mifareType = mfrc522.PICC_GetType(mfrc522.uid.sak); + // Dieser Hinweis darf nicht entfernt werden + Serial.println(F("\n _____ _____ _____ _____ _____")); + Serial.println(F("|_ _|___ ___| | | | | | |")); + Serial.println(F(" | | | . | | | |- -| | | | | |")); + Serial.println(F(" |_| |___|_|_|_____|_____|_|___|_____|\n")); + Serial.println(F("TonUINO Version 2.1")); + Serial.println(F("created by Thorsten Voß and licensed under GNU/GPL.")); + Serial.println(F("Information and contribution at https://tonuino.de.\n")); - // Authenticate using key B - //authentificate with the card and set card specific parameters - if ((mifareType == MFRC522::PICC_TYPE_MIFARE_MINI ) || - (mifareType == MFRC522::PICC_TYPE_MIFARE_1K ) || - (mifareType == MFRC522::PICC_TYPE_MIFARE_4K ) ) - { - Serial.println(F("Authenticating again using key A...")); - status = mfrc522.PCD_Authenticate( - MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid)); - } - else if (mifareType == MFRC522::PICC_TYPE_MIFARE_UL ) - { - byte pACK[] = {0, 0}; //16 bit PassWord ACK returned by the NFCtag +#ifdef SpkOnOff + pinMode(SpkOnPin, OUTPUT); // Ausgang Lautsprecher-Einschaltsignal + spkOff(); // Voreinstellung - Speaker Off +#endif - // Authenticate using key A - Serial.println(F("Authenticating UL...")); - status = mfrc522.PCD_NTAG216_AUTH(key.keyByte, pACK); - } + // Busy Pin + pinMode(busyPin, INPUT); - if (status != MFRC522::STATUS_OK) { - Serial.print(F("PCD_Authenticate() failed: ")); - Serial.println(mfrc522.GetStatusCodeName(status)); - mp3.playMp3FolderTrack(401); - return; + // load Settings from EEPROM + loadSettingsFromFlash(); + + // activate standby timer + setstandbyTimer(); + + // DFPlayer Mini initialisieren + mp3.begin(); + // Zwei Sekunden warten bis der DFPlayer Mini initialisiert ist + delay(2000); + volume = mySettings.initVolume; + mp3.setVolume(volume); + mp3.setEq(static_cast(mySettings.eq - 1)); + // Fix für das Problem mit dem Timeout (ist jetzt in Upstream daher nicht mehr nötig!) + //mySoftwareSerial.setTimeout(10000); + + // NFC Leser initialisieren + SPI.begin(); // Init SPI bus + mfrc522.PCD_Init(); // Init MFRC522 + +#ifdef NFCgain_min + mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_min); + Serial.println(F("=== mfrc522-> RxGain_min === ")); +#endif +#ifdef NFCgain_avg + mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_avg); + Serial.println(F("=== mfrc522-> RxGain_avg === ")); +#endif +#ifdef NFCgain_max + mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); + Serial.println(F("=== mfrc522-> RxGain_max === ")); +#endif + + mfrc522 + .PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader + for (byte i = 0; i < 6; i++) { + key.keyByte[i] = 0xFF; } - // Write data to the block - Serial.print(F("Writing data into block ")); - Serial.print(blockAddr); - Serial.println(F(" ...")); - dump_byte_array(buffer, 16); - Serial.println(); + pinMode(buttonPause, INPUT_PULLUP); + pinMode(buttonUp, INPUT_PULLUP); + pinMode(buttonDown, INPUT_PULLUP); +#ifdef FIVEBUTTONS + pinMode(buttonFourPin, INPUT_PULLUP); + pinMode(buttonFivePin, INPUT_PULLUP); +#endif + pinMode(shutdownPin, OUTPUT); + digitalWrite(shutdownPin, LOW); - if ((mifareType == MFRC522::PICC_TYPE_MIFARE_MINI ) || - (mifareType == MFRC522::PICC_TYPE_MIFARE_1K ) || - (mifareType == MFRC522::PICC_TYPE_MIFARE_4K ) ) - { - status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(blockAddr, buffer, 16); +#ifdef SpkOnOff + spkOn(); +#endif + + // RESET --- ALLE DREI KNÖPFE BEIM STARTEN GEDRÜCKT HALTEN -> alle EINSTELLUNGEN werden gelöscht + if (digitalRead(buttonPause) == LOW && digitalRead(buttonUp) == LOW && + digitalRead(buttonDown) == LOW) { + Serial.println(F("Reset -> EEPROM wird gelöscht")); + for (unsigned int i = 0; i < EEPROM.length(); i++) { + EEPROM.update(i, 0); + } + loadSettingsFromFlash(); } - else if (mifareType == MFRC522::PICC_TYPE_MIFARE_UL ) - { - byte buffer2[16]; - byte size2 = sizeof(buffer2); - memset(buffer2, 0, size2); - memcpy(buffer2, buffer, 4); - status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(8, buffer2, 16); - memset(buffer2, 0, size2); - memcpy(buffer2, buffer + 4, 4); - status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(9, buffer2, 16); + // Start Shortcut "at Startup" - e.g. Welcome Sound + playShortCut(3); +} - memset(buffer2, 0, size2); - memcpy(buffer2, buffer + 8, 4); - status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(10, buffer2, 16); +void loop() { + do { + checkStandbyAtMillis(); + mp3.loop(); - memset(buffer2, 0, size2); - memcpy(buffer2, buffer + 12, 4); - status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(11, buffer2, 16); - } + // Modifier : WIP! + if (activeModifier != NULL) { + activeModifier->loop(); + } - if (status != MFRC522::STATUS_OK) { - Serial.print(F("MIFARE_Write() failed: ")); - Serial.println(mfrc522.GetStatusCodeName(status)); - mp3.playMp3FolderTrack(401); - } - else - mp3.playMp3FolderTrack(400); - Serial.println(); - delay(2000); -} + // Buttons werden nun über JS_Button gehandelt, dadurch kann jede Taste + // doppelt belegt werden + readButtons(); -// ************************** Speaker On-Off ***************************************** + // admin menu + if ((pauseButton.pressedFor(LONG_PRESS) || upButton.pressedFor(LONG_PRESS) || downButton.pressedFor(LONG_PRESS)) && pauseButton.isPressed() && upButton.isPressed() && downButton.isPressed()) { + mp3.pause(); + do { + readButtons(); + } while (pauseButton.isPressed() || upButton.isPressed() || downButton.isPressed()); + readButtons(); + adminMenu(); + break; + } -// **************************Speaker On ******************* -#ifdef SpkOnOff -void spkOn() - { - digitalWrite(SpkOnPin, HIGH); // Lautsprecher über Mosfets Einschalten - Serial.println(F("Lautsprecher wird eingeschaltet!")); - SpkisOn = true; - } + if (pauseButton.wasReleased()) { + if (activeModifier != NULL) { + if (activeModifier->handlePause() == true) { + return; + } + } + if (ignorePauseButton == false) { + if (isPlaying()) { + mp3.pause(); + setstandbyTimer(); + } + else if (knownCard) { + mp3.start(); + disablestandbyTimer(); + } + } + ignorePauseButton = false; + } else if (pauseButton.pressedFor(LONG_PRESS) && + ignorePauseButton == false) { + if (activeModifier != NULL) { + if (activeModifier->handlePause() == true) { + return; + } + } + if (isPlaying()) { + uint8_t advertTrack; + if (myFolder->mode == 3 || myFolder->mode == 9) { + advertTrack = (queue[currentTrack - 1]); + } + else { + advertTrack = currentTrack; + } + // Spezialmodus Von-Bis für Album und Party gibt die Dateinummer relativ zur Startposition wieder + if (myFolder->mode == 8 || myFolder->mode == 9) { + advertTrack = advertTrack - myFolder->special + 1; + } + mp3.playAdvertisement(advertTrack); + } + else { + playShortCut(0); + } + ignorePauseButton = true; + } -// **************************Speaker Off ******************* -void spkOff() { - digitalWrite(SpkOnPin, LOW); // Lautsprecher über Mosfets Ausschalten - Serial.println(F("Lautsprecher wird ausgeschaltet!")); - SpkisOn = false; -} + if (upButton.pressedFor(LONG_PRESS)) { +#ifndef FIVEBUTTONS + if (isPlaying()) { + if (!mySettings.invertVolumeButtons) { + volumeUpButton(); + } + else { + nextButton(); + } + } + else { + playShortCut(1); + } + ignoreUpButton = true; +#endif + } else if (upButton.wasReleased()) { + if (!ignoreUpButton) { + if (!mySettings.invertVolumeButtons) { + nextButton(); + } + else { + volumeUpButton(); + } + } + ignoreUpButton = false; -//void SpkrOnOff() { -// SpkOn(); // Lautsprecher über Mosfets Einschalten -//} + } + + if (downButton.pressedFor(LONG_PRESS)) { +#ifndef FIVEBUTTONS + if (isPlaying()) { + if (!mySettings.invertVolumeButtons) { + volumeDownButton(); + } + else { + previousButton(); + } + } + else { + playShortCut(2); + } + ignoreDownButton = true; +#endif + } else if (downButton.wasReleased()) { + if (!ignoreDownButton) { + if (!mySettings.invertVolumeButtons) { + previousButton(); + } + else { + volumeDownButton(); + } + } + ignoreDownButton = false; + } +#ifdef FIVEBUTTONS + if (buttonFour.wasReleased()) { + if (isPlaying()) { + if (!mySettings.invertVolumeButtons) { + volumeUpButton(); + } + else { + nextButton(); + } + } + else { + playShortCut(1); + } + } + if (buttonFive.wasReleased()) { + if (isPlaying()) { + if (!mySettings.invertVolumeButtons) { + volumeDownButton(); + } + else { + previousButton(); + } + } + else { + playShortCut(2); + } + } #endif + // Ende der Buttons + } while (!mfrc522.PICC_IsNewCardPresent()); -// ************************** END Speaker On-Off ************************************** + // RFID Karte wurde aufgelegt -/** - Helper routine to dump a byte array as hex values to Serial. -*/ -void dump_byte_array(byte * buffer, byte bufferSize) { - for (byte i = 0; i < bufferSize; i++) { - Serial.print(buffer[i] < 0x10 ? " 0" : " "); - Serial.print(buffer[i], HEX); - } -} + if (!mfrc522.PICC_ReadCardSerial()) + return; -///////////////////////////////////////// Check Bytes /////////////////////////////////// -bool checkTwo ( uint8_t a[], uint8_t b[] ) { - for ( uint8_t k = 0; k < 4; k++ ) { // Loop 4 times - if ( a[k] != b[k] ) { // IF a != b then false, because: one fails, all fail - return false; + if (readCard(&myCard) == true) { + if (myCard.cookie == cardCookie && myCard.nfcFolderSettings.folder != 0 && myCard.nfcFolderSettings.mode != 0) { + playFolder(); + } + + // Neue Karte konfigurieren + else if (myCard.cookie != cardCookie) { + knownCard = false; + mp3.playMp3FolderTrack(300); + waitForTrackToFinish(); + setupCard(); } } - return true; + mfrc522.PICC_HaltA(); + mfrc522.PCD_StopCrypto1(); } diff --git a/src/Tonuino.ino.eightanaloginputs.hex b/src/Tonuino.ino.eightanaloginputs.hex new file mode 100644 index 00000000..646bca0b --- /dev/null +++ b/src/Tonuino.ino.eightanaloginputs.hex @@ -0,0 +1,1556 @@ +:100000000C94C7080C94EF080C94EF080C94CD24C2 +:100010000C94CD240C94CD240C94EF080C94EF0890 +:100020000C94EF080C94EF080C94EF080C94EF0874 +:100030000C94EF080C94EF080C94EF080C94EF0864 +:100040000C9483240C94EF080C9451240C942B24CE +:100050000C94EF080C94EF080C94EF080C94EF0844 +:100060000C94EF080C94EF083D3D3D2077726974C5 +:100070006553657474696E6773546F466C61736819 +:100080002829003D3D3D2072657365745365747485 +:10009000696E677328290031202D3E2032003D3DD6 +:1000A0003D20726573657453657474696E67732857 +:1000B000290041646D696E204D656E752050696E32 +:1000C0003A200041646D696E204D656E75206C6F3D +:1000D000636B65643A2000496E76657274656420CE +:1000E000566F6C756D6520427574746F6E733A202F +:1000F00000536C6565702054696D65723A20004C40 +:100100006F636B65643A200045513A2000496E697F +:100110007469616C20566F6C756D653A20004D698D +:100120006E696D616C20566F6C756D653A20004D7F +:100130006178696D616C20566F6C756D653A200051 +:1001400056657273696F6E3A20003D3D3D206C6FBD +:10015000616453657474696E677346726F6D466C43 +:100160006173682829003D3D3D20536C65657054DE +:10017000696D65723A3A6C6F6F702829202D3E20A8 +:10018000534C45455021003D3D20536C65657054EE +:10019000696D65723A3A676574416374697665287A +:1001A00029003D3D3D20467265657A6544616E6378 +:1001B000653A3A7365744E65787453746F70417420 +:1001C0004D696C6C69732829003D3D204672656558 +:1001D0007A6544616E63653A3A6C6F6F70282920C6 +:1001E0002D3E20465245455A4521003D3D20467250 +:1001F00065657A6544616E63653A3A676574416323 +:10020000746976652829003D3D204C6F636B6564F9 +:100210003A3A68616E646C6550617573652829208F +:100220002D3E204C4F434B454421003D3D204C6F1B +:10023000636B65643A3A68616E646C654E657874A8 +:10024000427574746F6E2829202D3E204C4F434B0D +:10025000454421003D3D204C6F636B65643A3A682C +:10026000616E646C6550726576696F757342757402 +:10027000746F6E2829202D3E204C4F434B4544215E +:10028000003D3D204C6F636B65643A3A68616E6473 +:100290006C65566F6C756D6555702829202D3E2054 +:1002A0004C4F434B454421003D3D204C6F636B65F3 +:1002B000643A3A68616E646C65566F6C756D65443E +:1002C0006F776E2829202D3E204C4F434B4544210B +:1002D000003D3D204C6F636B65643A3A68616E6423 +:1002E0006C65524649442829202D3E204C4F434BF3 +:1002F000454421003D3D20546F64646C65724D6F30 +:1003000064653A3A68616E646C655061757365281E +:1003100029202D3E204C4F434B454421003D3D209C +:10032000546F64646C65724D6F64653A3A68616ECF +:10033000646C654E657874427574746F6E282920FC +:100340002D3E204C4F434B454421003D3D20546FF2 +:1003500064646C65724D6F64653A3A68616E646C92 +:100360006550726576696F7573427574746F6E2827 +:1003700029202D3E204C4F434B454421003D3D203C +:10038000546F64646C65724D6F64653A3A68616E6F +:10039000646C65566F6C756D6555702829202D3E0F +:1003A000204C4F434B454421003D3D20546F646435 +:1003B0006C65724D6F64653A3A68616E646C65563F +:1003C0006F6C756D65446F776E2829202D3E204C2B +:1003D0004F434B454421003D3D20546F64646C65A0 +:1003E000724D6F64653A3A67657441637469766506 +:1003F0002829003D3D204B696E6465726761726417 +:10040000656E4D6F64653A3A68616E646C654E6501 +:1004100078742829202D3E204E455854003D3D201B +:100420004B696E64657267617264656E4D6F646579 +:100430003A3A68616E646C654E657874427574749E +:100440006F6E2829202D3E204C4F434B4544210000 +:100450003D3D204B696E64657267617264656E4DE7 +:100460006F64653A3A68616E646C6550726576696E +:100470006F7573427574746F6E2829202D3E204C61 +:100480004F434B454421003D3D204B696E646572EE +:1004900067617264656E4D6F64653A3A68616E6457 +:1004A0006C65524649442829202D3E20717565759A +:1004B000656421003D3D204B696E64657267617221 +:1004C00064656E4D6F64653A3A676574416374693B +:1004D00076652829003D3D20526570656174536939 +:1004E0006E676C654D6F6469666965723A3A6861FA +:1004F0006E646C654E6578742829202D3E20524527 +:10050000504541542043555252454E542054524177 +:10051000434B003D3D2052657065617453696E67C1 +:100520006C654D6F6469666965723A3A67657441D6 +:10053000637469766528290048C3B672627563687A +:10054000204D6F6475732069737420616B746976D4 +:10055000202D3E206EC3A4636873746572205472AC +:1005600061636B20756E6420466F7274736368728A +:100570006974742073706569636865726E0045699B +:100580006E7A656C204D6F64757320616B7469764B +:10059000202D3E205374726F6D2073706172656EF2 +:1005A00000456E646520646572205175657565202F +:1005B0002D3E20626567696E6E6520766F6E2076CF +:1005C0006F726E65005061727479202D3E207765E0 +:1005D0006974657220696E20646572205175657555 +:1005E000652000416C62756D6D6F64757320697371 +:1005F0007420616B746976202D3E206EC3A46368FD +:100600007374657220547261636B3A200048C3B6FC +:1006100072737069656C6D6F647573206973742093 +:10062000616B746976202D3E206B65696E656E2066 +:100630006E6575656E20547261636B2073706965B9 +:100640006C656E003D3D3D206E657874547261634B +:100650006B2829003D3D3D207365747374616E64A1 +:10066000627954696D65722829003D3D3D206469B9 +:100670007361626C657374616E6462792829003DF0 +:100680003D3D20706F776572206F666621003D3DAD +:100690003D20766F6C756D6555702829003D3D3D98 +:1006A00020766F6C756D65446F776E28290048C39E +:1006B000B67262756368204D6F64757320697374D8 +:1006C00020616B746976202D3E20766F72686572AA +:1006D0006967657220547261636B20756E64204691 +:1006E0006F72747363687269747420737065696380 +:1006F0006865726E0045696E7A656C204D6F647531 +:100700007320616B746976202D3E20547261636B97 +:1007100020766F6E20766F726E6520737069656CDF +:10072000656E00416E66616E67206465722051756A +:10073000657565202D3E20737072696E6765206156 +:100740006E7320456E646520005061727479204D8F +:100750006F6475732069737420616B746976202DE2 +:100760003E207A7572C3BC636B20696E206465722B +:10077000205165756575652000416C62756D6D6F02 +:100780006475732069737420616B746976202D3EE3 +:1007900020766F7268657269676572205472616352 +:1007A0006B003D3D3D2070726576696F75735472C4 +:1007B00061636B2829005370657A69616C6D6F64A1 +:1007C000757320566F6E2D4269733A2050617274B2 +:1007D00079202D3E204F72646E657220696E207AFA +:1007E0007566C3A46C6C696765722052656968653B +:1007F0006E666F6C676520776965646572676562B0 +:10080000656E002062697320005370657A69616CBF +:100810006D6F64757320566F6E2D4269733A204177 +:100820006C62756D3A20616C6C6520446174656919 +:10083000656E207A7769736368656E2053746172A0 +:10084000742D20756E6420456E6464617465692042 +:10085000737069656C656E00206269732000537067 +:10086000657A69616C6D6F64757320566F6E2D4289 +:10087000696E3A2048C3B672737069656C202D3E6C +:10088000207A7566C3A46C6C6967656E20547261CA +:10089000636B20776965646572676562656E0048A1 +:1008A000C3B67262756368204D6F647573202D3E08 +:1008B000206B6F6D706C657474656E204F72646E22 +:1008C000657220737069656C656E20756E64204674 +:1008D0006F727473636872697474206D65726B658E +:1008E0006E0045696E7A656C204D6F647573202DBE +:1008F0003E2065696E652044617465692061757389 +:100900002064656D204F6472646E6572206162734D +:100910007069656C656E005061727479204D6F640A +:100920007573202D3E204F72646E657220696E20B3 +:100930007A7566C3A46C6C696765722052656968D4 +:10094000656E666F6C67652077696564657267655B +:1009500062656E00416C62756D204D6F6475732029 +:100960002D3E206B6F6D706C657474656E204F72D8 +:10097000646E657220776965646572676562656E2D +:100980000048C3B672737069656C6D6F64757320CF +:100990002D3E207A7566C3A46C6C6967656E205421 +:1009A0007261636B20776965646572676562656E05 +:1009B00000204461746569656E20696E204F726421 +:1009C0006E657220003D3D20706C6179466F6C64ED +:1009D000657228290053686F7274637574206E6F96 +:1009E0007420636F6E6669677572656421003D3DB2 +:1009F0003D20706C617953686F7274437574282957 +:100A0000004B617274652077697264206E65752091 +:100A10006B6F6E66696775726965727421004162F9 +:100A2000676562726F6368656E21005265736574F5 +:100A3000202D3E20454550524F4D2077697264204D +:100A400067656CC3B67363687400736368726569C5 +:100A50006265204B617274652E2E2E0041626765BF +:100A600062726F6368656E2100204B61727465204D +:100A70006175666C6567656E00736368726569624F +:100A800065204B617274652E2E2E0041626765628F +:100A9000726F6368656E21003D3D3D2061646D6944 +:100AA0006E4D656E752829003D3D3D20736574755A +:100AB00070436172642829004D49464152455F5791 +:100AC000726974652829206661696C65643A200042 +:100AD000202E2E2E0057726974696E67206461742F +:100AE0006120696E746F20626C6F636B20005043ED +:100AF000445F41757468656E746963617465282923 +:100B0000206661696C65643A200041757468656EA1 +:100B10007469636174696E6720554C2E2E2E0041F6 +:100B2000757468656E7469636174696E6720616766 +:100B300061696E207573696E67206B657920412E3F +:100B40002E2E00556E6B6E6F776E206572726F720F +:100B50000041204D494641524520504943432072AF +:100B60006573706F6E6465642077697468204E41A8 +:100B70004B2E00546865204352435F4120646F65EB +:100B800073206E6F74206D617463682E00496E76F9 +:100B9000616C696420617267756D656E742E0049C1 +:100BA0006E7465726E616C206572726F7220696E10 +:100BB0002074686520636F64652E2053686F756CC0 +:100BC00064206E6F742068617070656E2E00412025 +:100BD000627566666572206973206E6F7420626943 +:100BE0006720656E6F7567682E0054696D656F7557 +:100BF0007420696E20636F6D6D756E6963617469D1 +:100C00006F6E2E00436F6C6C6973696F6E20646544 +:100C10007465637465642E004572726F7220696E2C +:100C200020636F6D6D756E69636174696F6E2E0000 +:100C3000537563636573732E0000000008000201A2 +:100C4000000003040700000000000000004C617574 +:100C5000747370726563686572207769726420616D +:100C600075736765736368616C7465742100000057 +:100C70000000240027002A005741524E494E473AAF +:100C800020436F6D6D756E69636174696F6E206668 +:100C900061696C7572652C20697320746865204DDC +:100CA0004652433532322070726F7065726C792013 +:100CB000636F6E6E65637465643F00203D20287528 +:100CC0006E6B6E6F776E2900203D20636F756E74BA +:100CD000657266656974206368697000203D2076DE +:100CE000322E3000203D2076312E3000203D2076FF +:100CF000302E3000203D2028636C6F6E6529004641 +:100D000069726D776172652056657273696F6E3AAC +:100D1000203078004C617574737072656368657219 +:100D200020776972642065696E6765736368616CBA +:100D300074657421005265736574202D3E2045450D +:100D400050524F4D20776972642067656CC3B6734B +:100D5000636874003D3D3D206D6672633532322D0F +:100D60003E2052784761696E5F6D6178203D3D3D60 +:100D70002000496E666F726D6174696F6E20616EDE +:100D80006420636F6E747269627574696F6E20613E +:100D9000742068747470733A2F2F746F6E75696E57 +:100DA0006F2E64652E0A006372656174656420624B +:100DB000792054686F727374656E20566FC39F20DC +:100DC000616E64206C6963656E73656420756E6422 +:100DD000657220474E552F47504C2E00546F6E556C +:100DE000494E4F2056657273696F6E20322E310066 +:100DF00020207C5F7C207C5F5F5F7C5F7C5F7C5F12 +:100E00005F5F5F5F7C5F5F5F5F5F7C5F7C5F5F5F9B +:100E10007C5F5F5F5F5F7C0A0020207C207C207C01 +:100E2000202E207C2020207C20207C20207C2D2037 +:100E300020202D7C207C207C207C20207C20207C7D +:100E4000007C5F2020205F7C5F5F5F205F5F5F7CB6 +:100E500020207C20207C20202020207C2020207C22 +:100E6000207C20202020207C000A205F5F5F5F5FC5 +:100E70002020202020202020205F5F5F5F5F205FF8 +:100E80005F5F5F5F205F5F5F5F5F205F5F5F5F5FF0 +:100E9000003D3D3D2052657065617453696E676C1D +:100EA000654D6F6469666965722829003D3D3D2086 +:100EB0004B696E64657267617264656E4D6F6465DF +:100EC0002829003D3D3D20546F64646C65724D6F70 +:100ED00064652829003D3D3D204C6F636B656428A7 +:100EE00029003D3D3D20467265657A6544616E632B +:100EF000652829003D3D3D20536C65657054696D42 +:100F00006572282900556E6B6E6F776E207479704C +:100F1000650053414B20696E646963617465732099 +:100F2000554944206973206E6F7420636F6D706C37 +:100F30006574652E004D494641524520544E50334C +:100F4000585858004D49464152452044455346693A +:100F50007265004D494641524520506C7573004DF5 +:100F6000494641524520556C7472616C69676874DA +:100F7000206F7220556C7472616C696768742043CD +:100F8000004D494641524520344B42004D494641AF +:100F9000524520314B42004D4946415245204D6952 +:100FA0006E692C20333230206279746573005049A9 +:100FB000434320636F6D706C69616E742077697450 +:100FC000682049534F2F494543203138303932206A +:100FD000284E464329005049434320636F6D706C8F +:100FE00069616E7420776974682049534F2F4945B1 +:100FF000432031343434332D34006D6F64696669B5 +:1010000065722072656D6F766564003A00446174A4 +:1010100061206F6E204361726420004D4946415249 +:10102000455F526561645F342829206661696C659B +:10103000643A20004D49464152455F526561645F04 +:10104000332829206661696C65643A20004D494661 +:101050004152455F526561645F32282920666169AB +:101060006C65643A20004D49464152455F526561C6 +:10107000645F312829206661696C65643A20004DFF +:1010800049464152455F526561642829206661697D +:101090006C65643A2000202E2E2E00526561646932 +:1010A0006E6720646174612066726F6D20626C6F80 +:1010B000636B20005043445F41757468656E7469CA +:1010C000636174652829206661696C65643A200053 +:1010D00041757468656E7469636174696E67204DEB +:1010E000494641524520554C2E2E2E0041757468BC +:1010F000656E7469636174696E6720436C617373B4 +:101100006963207573696E67206B657920412E2EA7 +:101110002E005049434320747970653A20004361A2 +:101120007264205549443A00203D3D3D003D3D3D1F +:101130002000204F7074696F6E7329003D3D3D2083 +:10114000766F6963654D656E75282920280000005B +:1011500000002300260029000000000025002800D0 +:101160002B00040404040404040402020202020228 +:10117000030303030303010204081020408001025B +:101180000408102001020408102045254A2D1124CE +:101190001FBECFEFD8E0DEBFCDBF12E0A0E0B1E0D0 +:1011A000E8EDFFE502C005900D92A834B107D9F72C +:1011B00024E0A8E4B2E001C01D92AD3EB207E1F721 +:1011C00018E0C6ECD8E004C02197FE010E94AB2EC7 +:1011D000C53CD107C9F70E943C260C94DF2F0C9424 +:1011E0000000FC018781882399F04285538564853E +:1011F000758586859785A089B189481B590B6A0B2F +:101200007B0B81E0483E53406105710508F480E0A6 +:1012100008958CBD9DBD0895AF92BF92CF92DF928D +:10122000EF92FF920F931F93CF93DF936C017B019B +:101230008B01040F151FEB015E01AE18BF08C0172C +:10124000D10759F06991D601ED91FC910190F0819F +:10125000E02DC6010995892B79F7C501DF91CF9162 +:101260001F910F91FF90EF90DF90CF90BF90AF90C4 +:101270000895FC01538D448D252F30E0842F90E09C +:10128000821B930B541710F0CF9608950197089581 +:10129000FC01918D828D981761F0A28DAE0FBF2F4A +:1012A000B11D5D968C91928D9F5F9F73928F90E0A0 +:1012B00008958FEF9FEF0895FC01918D828D98170F +:1012C00031F0828DE80FF11D858D90E008958FEF4C +:1012D0009FEF0895FC01918D228D892F90E0805C15 +:1012E0009F4F821B91098F73992708958EED93E08C +:1012F0000E946A0921E0892B09F420E0822F0895D9 +:1013000080E090E0892B29F00E94760981110C94ED +:1013100000000895FC01A48DA80FB92FB11DA35A98 +:10132000BF4F2C91848D90E001968F739927848F05 +:10133000A689B7892C93A089B1898C918370806428 +:101340008C93938D848D981306C00288F389E02DC9 +:1013500080818F7D80830895EF92FF920F931F937A +:10136000CF93DF93EC0181E0888F9B8D8C8D981358 +:101370001AC0E889F989808185FF15C09FB7F89464 +:10138000EE89FF896083E889F989808183708064B0 +:1013900080839FBF81E090E0DF91CF911F910F91FB +:1013A000FF90EF900895F62E0B8D10E00F5F1F4F0A +:1013B0000F731127E02E8C8D8E110CC00FB607FC19 +:1013C000FACFE889F989808185FFF5CFCE010E94A7 +:1013D0008A09F1CFEB8DEC0FFD2FF11DE35AFF4F82 +:1013E000F0829FB7F8940B8FEA89FB898081806235 +:1013F000CFCF0F931F93CF93DF938C01D0E0C0E04A +:10140000F801EC0FFD1F6491662341F08EED93E02F +:101410000E94AC09892B11F02196F2CFCE01DF9109 +:10142000CF911F910F910895CF93DF93EC01888D99 +:101430008823B9F0AA89BB89E889F9898C9185FD4F +:1014400003C0808186FD0DC00FB607FCF7CF8C91DD +:1014500085FFF2CF808185FFEDCFCE010E948A0902 +:10146000E9CFDF91CF910895833081F028F4813066 +:1014700099F08230A9F008958730A9F08830C9F03A +:101480008430B1F4809180008F7D03C08091800012 +:101490008F7780938000089584B58F7784BD0895F9 +:1014A00084B58F7DFBCF8091B0008F778093B000A3 +:1014B00008958091B0008F7DF9CFCF93DF93282FCF +:1014C00030E0F901E75CF34F8491F901EA58FE4EF0 +:1014D000D491F901EE59FE4EC491CC23A1F08111B3 +:1014E0000E94340AEC2FF0E0EE0FFF1FE25BFE4E8D +:1014F000A591B491EC91ED2381E090E009F480E0B6 +:10150000DF91CF91089580E090E0FACF1F93CF93C1 +:10151000DF93282F30E0F901E75CF34F8491F90164 +:10152000EA58FE4ED491F901EE59FE4EC491CC23F7 +:10153000A9F0162F81110E94340AEC2FF0E0EE0F73 +:10154000FF1FE85AFE4EA591B4918FB7F894EC9125 +:10155000111108C0D095DE23DC938FBFDF91CF91AE +:101560001F910895DE2BF8CFCF93DF9390E0FC011D +:10157000EA58FE4E24918E599E4EFC018491882398 +:10158000C9F090E0880F991FFC01E259F34FA59133 +:10159000B491FC01E85AFE4EC591D49161110DC081 +:1015A0009FB7F8948C91209582238C93888128236F +:1015B00028839FBFDF91CF910895623051F49FB788 +:1015C000F8943C91822F809583238C93E8812E2B75 +:1015D000EFCF8FB7F894EC912E2B2C938FBFEACFDF +:1015E0003FB7F8948091970290919802A091990248 +:1015F000B0919A0226B5A89B05C02F3F19F001961D +:10160000A11DB11D3FBFBA2FA92F982F8827BC015C +:10161000CD01620F711D811D911D42E0660F771F84 +:10162000881F991F4A95D1F708958F929F92AF9284 +:10163000BF92CF92DF92EF92FF924B015C010E942A +:10164000F00A6B017C010E94F00A6C197D098E0979 +:101650009F09683E734081059105A8F321E0821A35 +:101660009108A108B10888EEC80E83E0D81EE11CDD +:10167000F11C81149104A104B10429F7FF90EF90AB +:10168000DF90CF90BF90AF909F908F9008952FB72D +:10169000F8946091930270919402809195029091D8 +:1016A00096022FBF08950F931F930E94470B6093DC +:1016B000E6037093E7038093E8039093E9038EEDCC +:1016C00093E00E945C0997FF1DC00E94470B0091A8 +:1016D000E6031091E7032091E8033091E903601BD2 +:1016E000710B820B930B0091E2031091E3032091A5 +:1016F000E4033091E5036017710782079307F8F25E +:101700008FEF9FEF1F910F9108958F929F92AF924D +:10171000BF92CF92DF92EF92FF920F931F93CF93DE +:10172000DF93EC016A017B0110E000E00E94470BAF +:10173000688779878A879B87E881F9810284F385A6 +:10174000E02DCE01099597FF21C00E94470B8884A8 +:101750009984AA84BB84681979098A099B098C80B9 +:101760009D80AE80BF80681579058A059B0520F3B2 +:10177000C801DF91CF911F910F91FF90EF90DF9003 +:10178000CF90BF90AF909F908F900895F701819375 +:101790007F010F5F1F4FC016D10641F6E9CF2091A0 +:1017A0009D0230919E022817390771F490919B0297 +:1017B00080919C02981741F0E0919B02F0E0EE5A74 +:1017C000FD4F808190E008958FEF9FEF0895089579 +:1017D000EF92FF920F931F93CF93DF93DC015C9600 +:1017E000ED90FC905D97E114F10479F481E090E0D4 +:1017F00013969C938E93129790E080E0DF91CF91A7 +:101800001F910F91FF90EF9008955196ED91FC91EB +:10181000529750968C915097982F90950FB75E964F +:101820002C915E97122F127021FD6095F894208103 +:10183000112319F1282B2083E7012197F1F728E0E4 +:10184000462F50E0308160FF1AC0382B3083E7010B +:101850002197F1F7BA0175956795215089F7112302 +:1018600081F08081892380830FBF5C968D919C914C +:101870000197F1F781E090E0C1CF2923DCCF392334 +:10188000E5CF9081892BEFCF20919D0230919E0270 +:101890002817390771F480919C0220919B0290E0F7 +:1018A000805C9F4F821B910960E470E00E94832E50 +:1018B000089590E080E0089520919D0230919E026D +:1018C00028173907B9F490919B0280919C029817D0 +:1018D00089F0E0919B02F0E0EE5AFD4F808120916B +:1018E0009B0230E02F5F3F4F2F73332720939B02E3 +:1018F00090E008958FEF9FEF089590E080E00895C5 +:10190000BC016E5F7F4FDC01ED91FC910190F08195 +:10191000E02D40E0099591E0811190E0892F089534 +:101920008430F1F050F4813091F030F1823091F058 +:10193000833099F083E49BE008958630B9F098F005 +:101940008730B9F08F3FB1F781E59BE0089588E1DA +:101950009CE0089584E09CE008958AEE9BE0089561 +:101960008EEC9BE008958FE99BE008958DE89BE065 +:10197000089583E79BE0089580E39CE0089508952F +:101980008EBD00000DB407FEFDCF8EB50895DF9229 +:10199000EF92FF920F931F93CF93DF937C01062F5B +:1019A000D42E152F83E590E00E94090960E0F7012D +:1019B00086850E94860A82E10E94C00CCD2DD12F1F +:1019C0000C0F1D2F111DC017D10721F089910E9406 +:1019D000C00CF9CF61E0F7018685DF91CF911F91AF +:1019E0000F91FF90EF90DF900C94860A1F93CF9396 +:1019F000DF93EC01162F83E590E00E94090960E077 +:101A00008E850E94860A812F80680E94C00C80E02B +:101A10000E94C00C182F61E08E850E94860A812FDB +:101A2000DF91CF911F9108950F931F93CF93DF9371 +:101A3000EC01062F142F83E590E00E94090960E075 +:101A40008E850E94860A802F0E94C00C812F0E94E2 +:101A5000C00C61E08E85DF91CF911F910F910C94A6 +:101A6000860ACF92DF92EF92FF920F931F93CF934C +:101A7000DF93EC016B01142F790140E062E00E94DA +:101A8000140D44E06AE0CE010E94140D40E864E1C8 +:101A9000CE010E94140DA601612FCE010E94C70C39 +:101AA00043E062E0CE010E94140D08E813E16AE011 +:101AB000CE010E94F60C82FF1BC040E062E0CE0126 +:101AC0000E94140D64E4CE010E94F60CF70180839D +:101AD00062E4CE010E94F60CF701818380E0DF9181 +:101AE000CF911F910F91FF90EF90DF90CF900895CD +:101AF00001501109E1F683E0F2CF3F924F925F92DD +:101B00006F927F928F929F92AF92BF92CF92DF920D +:101B1000EF92FF920F931F93CF93DF9300D0CDB737 +:101B2000DEB73C01162F942E290180E0A114B104E8 +:101B300011F0F5018081382C329490EF3922380E63 +:101B400040E062E0C3010E94140D4FE768E0C3016A +:101B50000E94140D40E864E1C3010E94140DA2012B +:101B6000602FC3010E94C70C432D6AE1C3010E948C +:101B7000140D412F62E0C3010E94140D1C3051F47A +:101B80006AE1C3010E94F60C482F40686AE1C30174 +:101B90000E94140D00ED17E068E0C3010E94F60CEE +:101BA000982F992109F0B3C080FD03C0015011099D +:101BB00099F783E092C0E114F10409F46BC0C114F9 +:101BC000D10409F467C064E1C3010E94F60C982EA9 +:101BD000F6018081891508F494C090829920C9F19A +:101BE00083E590E00E94090960E0F30186850E9488 +:101BF000860A9A9482E90E94C00C882099F00FEF1F +:101C000010E001C0000F8A94EAF782E90E94C00C3C +:101C1000902F9095F701208192238023982B908319 +:101C2000882483948701080D111D891440F482E9EA +:101C30000E94C00CF80181938F018394F6CF80E05D +:101C40000E94C00CF801808361E0F30186850E9448 +:101C5000860A68E1C3010E94F60C8770A114B104E2 +:101C600011F0F501808353FC4EC0E114F10409F436 +:101C70004CC0C114D10409F448C09E89992309F4C9 +:101C800044C0F6014081413039F4843009F049C044 +:101C90008FEF23C080E0E7CF423008F442C08111CB +:101CA00040C042509E012F5F3F4FB701C3010E94C9 +:101CB000310D811112C0F6019081E90EF11CF7017E +:101CC00032972081998129132CC0F1E0EF1AF10895 +:101CD000F70120819A81291324C00F900F90DF9182 +:101CE000CF911F910F91FF90EF90DF90CF90BF9019 +:101CF000AF909F908F907F906F905F904F903F90AC +:101D0000089584E0EACF82E0E8CF80E0E6CF6CE09F +:101D1000C3010E94F60C582E837109F44CCF81E068 +:101D2000DCCF87E0DACF6F927F928F92AF92BF9233 +:101D3000CF92DF92EF92FF920F93CF93DF93CDB7C5 +:101D4000DEB764970FB6F894DEBF0FBECDBF3C017F +:101D50008BE189838091D8038A838091D9038B8317 +:101D60008091DA038C838091DB038D839E012A5F4F +:101D70003F4F45E0BE016F5F7F4F81EB94E00E94D3 +:101D8000310D81111BC01C8A85E08B8B1F92812C29 +:101D9000CE0144965C01FE0173966F0143977C016E +:101DA00007E09C0140E36CE081EB94E00E947D0D34 +:101DB0009981F30190839A8191830F9064960FB675 +:101DC000F894DEBF0FBECDBFDF91CF910F91FF9092 +:101DD000EF90DF90CF90BF90AF908F907F906F90FB +:101DE00008958F92AF92BF92CF92DF92EF92FF92BF +:101DF0000F93CF93DF93CDB7DEB72C970FB6F89440 +:101E0000DEBF0FBECDBF90E699838A83E8EDF3E095 +:101E1000DE01139681918D9383E0EE3DF807D1F7B3 +:101E2000E091B304E150FF0BEF54FB4FDE01199634 +:101E3000CE010D9621912D93A817B907D9F71F92BE +:101E4000812CB12CA12CD12CC12CF12CE12C0CE03B +:101E50009E012F5F3F4F40E16EE081EB94E00E94D6 +:101E60007D0D0F902C960FB6F894DEBF0FBECDBF40 +:101E7000DF91CF910F91FF90EF90DF90CF90BF90C7 +:101E8000AF908F9008956F927F928F92AF92BF9292 +:101E9000CF92DF92EF92FF920F931F93CF93DF9336 +:101EA00000D000D0CDB7DEB73C0180E589831A822F +:101EB0009E012D5F3F4F42E0BE016F5F7F4FC30128 +:101EC0000E94310D182F811118C01F92812CB12C46 +:101ED000A12CD12CC12CF12CE12C04E09E012F5F10 +:101EE0003F4F40E36CE0C3010E947D0D0F908330B3 +:101EF00021F0182F811101C011E0812F0F900F9058 +:101F00000F900F90DF91CF911F910F91FF90EF9065 +:101F1000DF90CF90BF90AF908F907F906F9008959B +:101F20008F92AF92BF92CF92DF92EF92FF920F9378 +:101F3000CF93DF93FA019081923148F16A01EB016E +:101F400090E3988389839B012E5F3F4F42E081EBB2 +:101F500094E00E94310D81110FC081E08F93812C9C +:101F6000B12CA12C7E0104E09E0140E36CE081EBEA +:101F700094E00E947D0D0F90DF91CF910F91FF9023 +:101F8000EF90DF90CF90BF90AF908F90089584E056 +:101F9000F3CF0F931F93CF93DF938C01D62FC42FD2 +:101FA0000E94F60CC0954C2F48236D2FC801DF917D +:101FB000CF911F910F910C94140D48E060E181EBDB +:101FC00094E00C94C90F6F927F928F92AF92BF9260 +:101FD000CF92DF92EF92FF920F93CF93DF9300D0D7 +:101FE00000D01F92CDB7DEB73C0182E08D8340E088 +:101FF00064E2C3010E94140D40E066E2C3010E9446 +:10200000140D46E268E4C3010E94140D86E28B833E +:102010008D818230C8F140E86CE1C3010E94C90F94 +:1020200087E08C831F92812CCE0104965C0101967F +:102030006C0104977C0101E09E012D5F3F4F40E35E +:102040006CE0C3010E947D0D982F0F90811119C083 +:102050008D818230C9F48C81811116C081E00F908E +:102060000F900F900F900F90DF91CF910F91FF90F5 +:10207000EF90DF90CF90BF90AF908F907F906F9058 +:10208000089581E0923059F380E0E9CF2F923F929A +:102090004F925F926F927F928F929F92AF92BF9278 +:1020A000CF92DF92EF92FF920F931F93CF93DF9324 +:1020B000CDB7DEB72E970FB6F894DEBF0FBECDBFFB +:1020C00006E0413508F046C14E873B012C0140E84F +:1020D0006CE10E94C90F83E989832E85222329F0B0 +:1020E00081E0F3019081953008F480E09924939485 +:1020F0001C869C85990F990F990F1E85191B17FD3A +:1021000010E032E0882319F098E89B8333E021E067 +:10211000912F977009F420E0912F959595959595BD +:10212000290FD1F094E0811193E0291708F4922F40 +:102130002C85E22FF0E03196E60DF71D232F41911B +:10214000A1E0B0E0AC0FBD1FA20FB11D4C932F5FFB +:10215000422F431B491798F38111185F10320CF47A +:1021600084C080E78A838B819C8189279D81892710 +:102170009E8189278F839E01285F3F4F47E0BE01E4 +:102180006F5F7F4FC2010E94310D082F8111E2C0A5 +:102190001A8693E09B871D87FE0137961F0109E091 +:1021A0008A84482D4295407F480D6AE1C2010E9411 +:1021B000140D1F92CE010A965C01FE013B966F0141 +:1021C00071019E012F5F3F4F40E36CE0C2010E940E +:1021D0007D0D082F0F90823009F065C06CE1C201BF +:1021E0000E94F60C85FDB6C08F7109F480E2282F9D +:1021F00030E0412F110F550B421753070CF09EC0D2 +:10220000182FE22FE595E595E595EF5F922F9770F2 +:1022100081E009F480E0E80F81E090E08C0F9D1FE1 +:102220008E0F911DFC01215031092770332781E069 +:1022300090E002C0880F991F2A95E2F79C018081E7 +:10224000822B80838BCF85E98983FE85FF2331F044 +:1022500081E0F3019081983008F04BCF80E049CFC6 +:1022600087E98983F6E0FC87F9CF912F97709A87E9 +:10227000812F8595859585958E5F282F2295207FC6 +:10228000290F2A8301E0911101C000E0080F2224E8 +:102290002394312C2C0E3D1E280E311CF9E0F81B26 +:1022A000FB871D877DCF811155C010E29D8590323F +:1022B0000CF457CF8B81883809F042C083E093E05B +:1022C0002C85E22FF0E03196E60DF71D980FA1E086 +:1022D000B0E0AC0FBD1FA80FB11D2C9121938F5FF3 +:1022E0008913F5CF8B858C87833009F04DC08A85A3 +:1022F00081114AC09E012D5F3F4F41E0B101C201F3 +:102300000E94310D082F811125C09B81F10181812F +:1023100098133CC09C818281981338C0808182FFD1 +:1023200012C09394F2E09F1609F48DCF23E0921629 +:1023300009F496CF81E0981609F4CDCE05E00AC0E5 +:1023400082E094E0BDCFF3018387892D880F980E3A +:1023500093949082802F2E960FB6F894DEBF0FBE16 +:10236000CDBFDF91CF911F910F91FF90EF90DF9044 +:10237000CF90BF90AF909F908F907F906F905F9025 +:102380004F903F902F90089501E0E4CF07E0E2CF17 +:10239000FC012781211102C08185089580E0089504 +:1023A000CF92DF92EF92FF920F931F93CF93DF9321 +:1023B000EC010E94470B6B017C0188810E945D0A41 +:1023C0009C018E8191E0811104C0232B21F490E0C7 +:1023D00002C0232BE1F74E855F85688979899701D3 +:1023E0008601041B150B260B370B49815A816B8123 +:1023F0007C81041715072607370778F41986CA86E3 +:10240000DB86EC86FD868F81DF91CF911F910F9146 +:10241000FF90EF90DF90CF9008958F8188879F8302 +:10242000292F28272987981751F3CE86DF86E88A37 +:10243000F98AE5CF8FE994E00E94D0118DE894E00D +:102440000E94D0118BE794E00C94D011EF92FF9290 +:102450000F931F93CF93DF938C01C0E0FF24F3947D +:1024600082E0E82ED3E0C43050F50E941A128FE9C2 +:1024700094E00E94F108811122C08FE994E00E944B +:10248000C811882329F0F801EC0FF11DF082CF5F0D +:102490008DE894E00E94C811882329F0F801EC0F20 +:1024A000F11DE082CF5F8BE794E00E94C811882382 +:1024B000D1F2F801EC0FF11DD083CF5FD4CF81E0D2 +:1024C000DF91CF911F910F91FF90EF90089584E0DD +:1024D0000E945D0A21E0892B09F020E0822F0895F7 +:1024E00083E0089580E0089580E008950895FC0158 +:1024F00001900020E9F73197AF01481B590BBC014F +:102500008EED93E00C940C0989E092E00C94771224 +:10251000CF93DF930E94F909EC010E9484128C0F83 +:102520009D1FDF91CF9108958AE696E00E94881260 +:10253000109248021092490210924A0210924B02E5 +:10254000089583E195E00E94881286E0089584EB67 +:1025500094E00E94881285E008950F931F93CF9313 +:10256000DF93EC018B0187E894E00E94881289E0F8 +:10257000F801DE01129601900D928A95E1F781E053 +:102580008B870E946712811107C0E881F98104805E +:10259000F581E02DCE01099581E0DF91CF911F916A +:1025A0000F91089580E594E00E94881281E00895DB +:1025B0008DE194E00E94881281E0089587ED93E018 +:1025C0000E94881284E0089589EA93E00E948812AC +:1025D00081E008958DE793E00E94881281E00895DC +:1025E0008BE493E00E94881281E008958DE193E0EE +:1025F0000E94881281E0089584EF92E00E94881280 +:1026000081E0089581ED92E00E94881281E00895B2 +:1026100088EA92E00E94881281E0089581E892E0C1 +:102620000E94881281E0089584E592E00E94881259 +:1026300081E008958BE292E00E94881281E0089583 +:1026400087E092E00E94881281E008958BEE91E08D +:102650000E94881282E0089587E891E00E94881223 +:1026600081E008958F929F92AF92BF920F931F9334 +:10267000CF93DF93CDB7DEB7A1970FB6F894DEBF47 +:102680000FBECDBF19A2423008F44AE08E010F5DA3 +:102690001F4F842E912CB12CA12CA50194010E94D6 +:1026A000522EE62FB901CA01EA30F4F4E05DD801F8 +:1026B000EE938D01232B242B252B79F790E080E0DE +:1026C000109719F0CD010E947712A1960FB6F894D9 +:1026D000DEBF0FBECDBFDF91CF911F910F91BF9095 +:1026E000AF909F908F900895E95CE1CF462F682FBF +:1026F00070E090E080E00C943213CF93DF936AE0B7 +:1027000070E00E947613EC010E9484128C0F9D1FD2 +:10271000DF91CF910895CF93DF93BC0190E080E0EB +:102720004AE00E943213EC010E9484128C0F9D1F1C +:10273000DF91CF910895CF92DF92EF92FF92CF93E6 +:10274000DF9397FF1BC06B017C016DE28EED93E080 +:102750000E94AC09EC0166277727CB016C197D0933 +:102760008E099F094AE00E9432138C0F9D1FDF9152 +:10277000CF91FF90EF90DF90CF9008954AE0DF91E6 +:10278000CF91FF90EF90DF90CF900C943213CF92C7 +:10279000DF92EF92FF9284E596E00E94881280918A +:1027A000B5029091B602A091B702B091B802892B00 +:1027B0008A2B8B2B69F10E94470B6B017C012091C6 +:1027C000B5023091B6024091B7025091B802A0E62E +:1027D000BAEE0E943F2EC60ED71EE81EF91EC0920A +:1027E0004802D0924902E0924A02F0924B02609174 +:1027F00048027091490280914A0290914B024AE04E +:102800000E943213FF90EF90DF90CF900C948412CF +:10281000109248021092490210924A0210924B0202 +:10282000E6CFEF92FF920F931F93CF93DF93EC01CC +:102830008C01060F111DC017D10799F07E01888108 +:10284000803160F08CE192E00E947712219660E185 +:1028500070E0F70180810E947613EDCF8CE092E06A +:10286000F3CFDF91CF911F910F91FF90EF900895DB +:102870000F931F93CF93C82F8B0181FF04C08FE06C +:1028800092E00E947712C0FF04C089E192E00E94AA +:102890007712C3FF04C08EE192E00E947712C80154 +:1028A0000E947712CF911F910F910C948412CF93B5 +:1028B000DF93EC010E94841285E292E00E9477127D +:1028C000CE01DF91CF910C948B138F92AF92BF9278 +:1028D000CF92DF92EF92FF920F93CF93DF93CDB71A +:1028E000DEB764970FB6F894DEBF0FBECDBF062FDC +:1028F000E62EF12CA701BC01CE0101960E94D62F35 +:1029000021E030E02C0F3D1F2E0D3F1D402FBE015A +:102910006F5F7F4F81EB94E00E94310D811123C0E6 +:1029200082E18C8B1B8A0E5F1F92812CCE01439615 +:102930005C0101966C0143977C019C0140E36CE0D3 +:1029400081EB94E00E947D0D0F9081110CC08C8969 +:102950008130D1F48B898430B9F481E099819A3047 +:1029600009F480E0819564960FB6F894DEBF0FBE3F +:10297000CDBFDF91CF910F91FF90EF90DF90CF907F +:10298000BF90AF908F90089581E0EDCF0F931F938C +:10299000CF93DF9300D0CDB7DEB78B0190EA998358 +:1029A0008A8362E0CE0101960E946514811104C001 +:1029B00060E1C8010E9465140F900F90DF91CF91E4 +:1029C0001F910F9108951F93CF93DF93EC01162F62 +:1029D0000E940A2E181739F0612FCE01DF91CF9196 +:1029E0001F910C94122EDF91CF911F910895CF93D8 +:1029F000DF93EC010E948B138091D3039091D40359 +:102A0000009751F480915002909151028C179D07CC +:102A100069F4DF91CF910895DC01ED91FC91048080 +:102A2000F581E02D0995882369F3F3CFD093510206 +:102A3000C09350028091D203882359F384E496E036 +:102A40000E948812E091D003F091D10381818130FE +:102A500011F0873031F48DE096E00E9488120E94D8 +:102A6000C713E091D003F091D1038181823011F03E +:102A7000883011F56091CE037091CF0380914E02A2 +:102A800090914F026817790709F498C06F5F7F4FE4 +:102A90007093CF036093CE0380810E945F1783EE13 +:102AA00095E00E94F9096091CE037091CF0390E008 +:102AB00080E04AE00E943213E091D003F091D1030C +:102AC0008181833011F0893099F5C091CE03D09186 +:102AD000CF0380914E0290914F02019620914C02BB +:102AE00030914D02821B930B8C179D0709F469C02E +:102AF00085EC95E00E94F9092196D093CF03C0930D +:102B0000CE03E091CE03F091CF03E253FD4F8081DD +:102B10000E947D13E091CE03F091CF03E253FD4F6D +:102B2000A091D003B091D10360818C910E945F1776 +:102B3000E091D003F091D1038181843031F48EE7AC +:102B400095E00E9488120E94C713E091D003F09193 +:102B5000D1038181853051F5C091CE03D091CF034F +:102B600080914E0290914F02C817D907A9F1219682 +:102B7000D093CF03C093CE0388E395E00E94F90978 +:102B8000CE010E948B13E091D003F091D1036091AC +:102B9000CE0380810E945F17E091D003F091D103B2 +:102BA00080816091CE0390E00E94E31464EF71E0B5 +:102BB00080E090E0DF91CF910C94150B0E94C71339 +:102BC0007BCF81EA95E00E94881281E090E09093AB +:102BD000CF038093CE0395CF808161E090E00E9487 +:102BE000E3140E94C713E2CFBF92CF92DF92EF921D +:102BF000FF920F931F93CF93DF93CDB7DEB72A9742 +:102C00000FB6F894DEBF0FBECDBFD82E8AE0B82E27 +:102C10008E010F5F1F4FEE24E394FF24FA94CC241F +:102C2000C394D801EB2D1D92EA95E9F741E050E0FD +:102C3000B8018091C1049091C2040E94850B81303B +:102C400009F068C089818E3789F749E050E0BE01FC +:102C50006E5F7F4F8091C1049091C2040E94850BEA +:102C60008F5F8A3008F468C08A818F3F09F067C09F +:102C70008B81863009F063C08A858F3E09F05FC082 +:102C80009C81288539853227232732276D81492F5A +:102C900050E04A5F5F4F640F752F711D4E81640FC6 +:102CA000711D4F81460F572F511DB701641B750BC6 +:102CB0002617370709F046C02E813F813227232788 +:102CC0003227DD2009F441C0D91256C0C9012A9625 +:102CD0000FB6F894DEBF0FBECDBFDF91CF911F912D +:102CE0000F91FF90EF90DF90CF90BF900895C901B2 +:102CF0000E94F714D11095CF3CC0C092C90460E384 +:102D000072E0C9010E943814F5CFC092C90467E38C +:102D100072E0F7CF81E890E00E9457148091C104DF +:102D20009091C204DC01ED91FC910084F185E02DCD +:102D30000995892BF9F61DC082E890E0EDCF83E874 +:102D400090E0EACF84E890E0E7CF9F3358F49C33DB +:102D500070F69A33D1F29B3361F4C092C9046EE3EA +:102D600072E0CFCF9F3349F2903419F4C9010E9429 +:102D7000571430E020E0AACF9F3348F49C3308F08A +:102D8000B6CF9A3311F29B3309F04BCFE6CF9F3386 +:102D900009F4B3CF903409F044CFE8CF8091C10457 +:102DA0009091C204DC01ED91FC910084F185E02D4D +:102DB00009950A9724F080E00E94F415EFCF08955A +:102DC0000F931F93CF93DF93CDB7DEB72A970FB63C +:102DD000F894DEBF0FBECDBF96E0FE013596DF0151 +:102DE000292F1D922A95E9F74EE749834FEF4A8331 +:102DF0009B839FEE9A878C83272F30E07E836F839F +:102E000090E08B5F9E4F4D81840F911D280F391FDD +:102E1000620F732F711D71956195710978876987AC +:102E20000E94470B0091C3041091C4042091C50473 +:102E30003091C604AB01BC01401B510B620B730BFC +:102E40008091C7049091C804B0E0A0E048175907EA +:102E50006A077B0748F40E94CE1661E070E080E0CC +:102E600090E00E94150BDCCF82E390E09093C804C1 +:102E70008093C7048091C1049091C204DC01ED915C +:102E8000FC910280F381E02D4AE050E0BE016F5FCB +:102E90007F4F09950E94470B6093C3047093C4044D +:102EA0008093C5049093C6042A960FB6F894DEBFAB +:102EB0000FBECDBFDF91CF911F910F910895782F55 +:102EC0008FE00C94E016CF93DF938091D303909121 +:102ED000D403009749F582EA97E00E948812E091B6 +:102EE000D003F091D1038181823051F589E797E0D9 +:102EF0000E9488128091CE039091CF0320914C02C2 +:102F000030914D028217930729F001979093CF03D8 +:102F10008093CE03E091D003F091D1036091CE0372 +:102F200080810E945F170EC0DC01ED91FC9102844C +:102F3000F385E02D0995882371F2DF91CF910895F3 +:102F40008830A1F2E091D003F091D10381818330E8 +:102F500011F0893041F5C091CE03D091CF03C1303B +:102F6000D10509F46CC089E497E00E94F909219722 +:102F7000D093CF03C093CE03E091CE03F091CF0363 +:102F8000E253FD4F80810E947D13E091CE03F091CA +:102F9000CF03E253FD4FA091D003B091D1036081E4 +:102FA0008C910E945F17E091D003F091D103818151 +:102FB000843069F485EF96E00E948812E091D00396 +:102FC000F091D1036091CE0380810E945F17E09160 +:102FD000D003F091D1038181853019F58EEA96E016 +:102FE0000E9488128091CE039091CF038130910589 +:102FF00029F001979093CF038093CE03E091D00303 +:10300000F091D1036091CE0380810E945F17E0911F +:10301000D003F091D10380816091CE0390E00E94B3 +:10302000E31468EE73E080E090E00E94150B68EE18 +:1030300073E080E090E0DF91CF910C94150B83E278 +:1030400097E00E94F90980914E0290914F0290936F +:10305000CF038093CE0390CF85ED94E00E94881239 +:1030600062E370E080E090E00E94150B0E9467121E +:10307000811118C0E091D003F091D103918160914A +:10308000CE037091CF038081933011F0993021F4F9 +:1030900062537D4FFB0160810E945F1710925102C5 +:1030A0001092500281E00895BC0183E10C94E01677 +:1030B00070E060E08EE00C94E01670E060E08DE07F +:1030C0000C94E016BC0182E10C94E0168091D303CD +:1030D0009091D4030097C1F48DE996E00E94881284 +:1030E0009091B1028091A002981750F470E060E0D6 +:1030F00085E00E94E0168091A00281508093A0029A +:103100008091A0020C947D13DC01ED91FC9106846A +:10311000F785E02D09958823F9F208958091D3036E +:103120009091D4030097C1F48EE896E00E94881233 +:103130009091B0028091A002891750F470E060E095 +:1031400084E00E94E0168091A0028F5F8093A0022D +:103150008091A0020C947D13DC01ED91FC9104841C +:10316000F585E02D09958823F9F20895CF92DF9235 +:10317000EF92FF92C0904802D0904902E0904A023C +:10318000F0904B02C114D104E104F104C1F10E949A +:10319000470BC616D706E806F90688F58FE796E0CE +:1031A0000E94881261E087E00E94860A64EF71E065 +:1031B00080E090E00E94150B43E068E281EB94E030 +:1031C0000E94C90F62E081EB94E00E94F60C482F48 +:1031D000406162E081EB94E00E94140D70E060E0D9 +:1031E0008AE00E94E01683B7817F846083BFF894F1 +:1031F00083B7816083BF889583B78E7F83BFFF903D +:10320000EF90DF90CF900895CF92DF92EF92FF92F0 +:103210000E94470B6B017C0128EEC20E23E0D21EF8 +:10322000E11CF11C0E94CE160E946712811107C09A +:103230000E94470B6C157D058E059F0598F368EE7F +:1032400073E080E090E00E94150B0E94CE160E9471 +:1032500067128111FACFFF90EF90DF90CF90089521 +:103260004F925F926F927F929F92AF92BF92CF9256 +:10327000DF92EF92FF920F931F93CF93DF936C0136 +:10328000CB015A01D22F009711F00E9462188CE3F3 +:1032900091E10E94F909B6010D2C000C880B990BE5 +:1032A0000E949B1382E391E10E948812CE2D992403 +:1032B00093948EED93E00E946A09181619060CF09B +:1032C00069C00E94530BFC0197FD60C08D329105CF +:1032D00021F0C0970A9708F051C0412C512C3201BF +:1032E000F12CE130F105D9F0ED32F10509F44BC0D4 +:1032F000CF01C0970A9798F4AAE0B0E0A301920129 +:103300000E943F2E2F01FF0F66087708460E571EBA +:10331000681E791E80E3481A5108610871088EED15 +:1033200093E00E9448090E94530BFC01C0970A9742 +:10333000C0F2E130F105A9F2FF2041F070946094F1 +:1033400050944094411C511C611C711CC201892B7A +:1033500009F1C414D504F4F0C42D8C2FDF91CF9162 +:103360001F910F91FF90EF90DF90CF90BF90AF90A3 +:103370009F907F906F905F904F9008958EED93E0B7 +:103380000E9448099ECFFF24F394C9CF412C512CB1 +:103390003201DCCF0E941A120E94CE168FE994E00F +:1033A0000E94F108882359F082E293E00E9462189B +:1033B00081E08093D7030E94B618CE2DCECF8FE93F +:1033C00094E00E94C8118823B1F0CC2371F08DE203 +:1033D00091E10E94F9096AE070E08C2F0E94761357 +:1033E00088E291E10E948812B8CF68EE73E080E035 +:1033F00090E00E94150B8DE894E00E94F10888236C +:1034000071F16C2E712C8AE0680E711CC614D70401 +:103410000CF43601C62D862D0E947D13C501860D44 +:10342000911D0E9462180E9404199092D6038BE7A6 +:1034300094E00E94F108882309F444C0CB3008F4DA +:10344000CBE0CA508C2F0E947D13C5018C0F911DBB +:103450000E9462180E9404199092D5032ACF8DE829 +:1034600094E00E94C811882311F38091D603811142 +:1034700026C06C2E712C8FEF681A780AC614D704F8 +:103480000CF43601C62D862D0E947D13C501860DD4 +:10349000911D0E946218DD2351F20E94041961E01F +:1034A000862D0115110511F0662D802F0E945F17E2 +:1034B00068EE73E080E090E00E94150BB8CF1092A8 +:1034C000D603B5CF8BE794E00E94C811882309F496 +:1034D000F0CE8091D503811121C0C23008F4C2E042 +:1034E000C1508C2F0E947D13C5018C0F911D0E942D +:1034F0006218DD2309F4DDCE0E94041961E08C2FEF +:103500000115110511F06C2F802F0E945F1768EED6 +:1035100073E080E090E00E94150BCBCE1092D503B3 +:10352000C8CECF93DF93EC018091C1049091C20487 +:10353000DC01ED91FC910084F185E02D09951816D0 +:10354000190624F480E00E94F415EECFBE018EE44B +:103550000E94E0168EE4DF91CF910C94F415EF9267 +:10356000FF920F931F93CF93DF93EC01F12CE12C8B +:1035700010E000E021E050E040E06DE271E083E621 +:1035800090E00E9430198883811108C080E0DF91AB +:10359000CF911F910F91FF90EF900895F12CE12CA6 +:1035A00010E000E020E046E351E066E371E089E0EE +:1035B00090E00E9430198983882341F3843069F4B4 +:1035C000088110E0C8010E94911A21E050E040E01B +:1035D00060E471E00E9430198A838981863019F491 +:1035E00018828FEF8983898187508330F0F40881B6 +:1035F00010E0C8010E94911AF12CE12C21E050E06A +:1036000040E061E471E00E943019E82E8A8308816D +:1036100010E0C8010E94911AF12C21E050E040E036 +:1036200062E471E00E9430198B8381E0B0CFFF9299 +:103630000F931F93CF93DF9388E690E00E94881248 +:103640000BEA12E0C4E6D0E0F801F1908F01CE0160 +:103650000E940A2EF81621F06F2DCE010E94122E24 +:103660002196C838D10581F7DF91CF911F910F9135 +:10367000FF90089583E890E00E948812EBEAF2E060 +:1036800087E493EBA7E3B3E180839183A283B383C1 +:1036900082E0848389E1858385E086838FE0878368 +:1036A00081E08087118612861386148615868687A8 +:1036B0001786138A178A138E178E80A381A382A37D +:1036C00083A30C94171B0F931F93CF93DF938AE46C +:1036D00091E00E9488120BEA12E0C4E6D0E0CE012D +:1036E0000E940A2EF80181938F012196C838D105D6 +:1036F000B1F78091AB029091AC02A091AD02B09174 +:10370000AE028734934BA743B34111F00E943A1B9A +:10371000C091AF02C130B9F48EE990E00E948812E6 +:1037200087E990E00E94881282E08093AF021092B5 +:10373000CA02C093CB02C093CC02C093CD02C09307 +:10374000CE020E94171B80E491E00E94F90980914B +:10375000AF020E947D138FE291E00E94F9098091EF +:10376000B0020E947D138EE191E00E94F9098091E0 +:10377000B1020E947D138DE091E00E94F9098091D1 +:10378000B2020E947D1388E091E00E94F9098091C5 +:10379000B3020E947D138FEF90E00E94F9096091BF +:1037A000B40270E090E080E00E949B130E948412BB +:1037B00081EF90E00E94F9096091B5027091B60224 +:1037C0008091B7029091B8020E949B130E948412CC +:1037D00087ED90E00E94F9096091B90270E090E0F5 +:1037E00080E00E949B130E94841283EC90E00E9470 +:1037F000F9098091CA020E947D1382EB90E00E9439 +:10380000F9096AE070E08091CB020E9476136AE0C9 +:1038100070E08091CC020E9476136AE070E08091A3 +:10382000CD020E9476138091CE02DF91CF911F913D +:103830000F910C947D13DF92EF92FF920F931F93E1 +:10384000CF93DF93CDB7DEB7A9970FB6F894DEBF5D +:103850000FBECDBF09A31AA32BA33CA34DA35EA308 +:103860006FA378A789A77E0189E1E80EF11C88E0A3 +:10387000F70111928A95E9F783E1898B87E38A8BB7 +:1038800083EB8B8B87E48C8B82E08D8B8EA18E8B70 +:103890008FA18F8B88A5888F89A5898FE091BE0421 +:1038A000EF7710E0E13420F4F0E0E656FE4F1081AF +:1038B0000DEF010F033040F58FE19BE00E9488126D +:1038C00087E00E94F10E8093A102D090A102DD203A +:1038D00041F18EEE9AE00E94F9098D2D0E94900C24 +:1038E0000E94881281E991E00E946218A9960FB6A1 +:1038F000F894DEBF0FBECDBFDF91CF911F910F9126 +:10390000FF90EF90DF9008951630F9F619821A8231 +:103910008AE09BE00E948812CE0101960E94930EDD +:10392000D2CF85ED9AE00E94F9096AE070E084E068 +:103930000E94761380ED9AE00E94881260E1CE0129 +:1039400041960E9411140E948412BE016F5E7F4F47 +:1039500084E0033008F454C0163009F055C08E01DD +:103960000B5F1F4F8CE0D82EF8018D2D11928A9598 +:10397000E9F784E0FE017196DE01119601900D9247 +:103980008A95E1F7BE016F5F7F4F88E00E94C61401 +:10399000F8018D2D11928A95E9F784E0FE01759664 +:1039A000DE01119601900D928A95E1F7BE016F5FDD +:1039B0007F4F89E00E94C614F8018D2D11928A95DF +:1039C000E9F784E0F701DE01119601900D928A95E6 +:1039D000E1F7BE016F5F7F4F8AE00E94C614F801D5 +:1039E0001192DA94E9F784E0FE017D96DE011196EA +:1039F00001900D928A95E1F7BE016F5F7F4F8BE0DA +:103A00000E94C6148093A1021091A10280E991E066 +:103A1000112359F088EB9AE00E94F909812F0E9446 +:103A2000900C0E94881281E991E00E9462180E9425 +:103A3000841260ED77E080E090E00E94150B56CF95 +:103A40000F931F93CF93DF93CDB7DEB729970FB6B0 +:103A5000F894DEBF0FBECDBF0E94581888EA9AE0E6 +:103A60000E948812CE0106960E94AF1A882389F020 +:103A70000E9458180E9467128111FCCF09811A8197 +:103A80002B813C814D815E816F81788589850E9483 +:103A90001B1C68EE73E080E090E00E94150B2996F5 +:103AA0000FB6F894DEBF0FBECDBFDF91CF911F914F +:103AB0000F9108954F925F926F927F928F929F9293 +:103AC000AF92BF92CF92DF92EF92FF920F931F932C +:103AD000CF93DF93CDB7DEB729970FB6F894DEBF4B +:103AE0000FBECDBF182F0E9494120E94581888E96B +:103AF0009AE00E9488121092D203111199C080910D +:103B0000CA02813009F18230B1F58FED93E00E9455 +:103B10006218CE0101960E9426128823A9F0909186 +:103B2000CB028981981310C09091CC028A8198139E +:103B30000BC09B818091CD02981306C09C8180911F +:103B4000CE02981709F474C029960FB6F894DEBF18 +:103B50000FBECDBFDF91CF911F910F91FF90EF90DE +:103B6000DF90CF90BF90AF909F908F907F906F909D +:103B70005F904F900895833009F05AC00E94B22D93 +:103B80002AE030E040E050E00E94202E4B015C0132 +:103B90007C016B012AE0C20ED11CE11CF11C1C2D22 +:103BA0000E94B22D2B013C0180EE93E00E9462182E +:103BB0000E940419C6010E9462180E94B22D22E0E0 +:103BC00030E040E050E00E94202E61307105810518 +:103BD000910509F071C0C301B20129E030E040E075 +:103BE00050E00E94202EDC01CB010196A11DB11DE9 +:103BF000B82EC80E0E94041981EE93E00E9462184C +:103C00000E9404198B2D90E00E9462188C2D0E9456 +:103C10007D13F12CE12C10E000E020E050E040E0CA +:103C200070E060E08FEF90E00E943019C8128CCFF6 +:103C3000F12CE12C10E000E020E044E853E064E8DF +:103C400073E08CE090E00E94301990E0009709F456 +:103C50007BCF8130910509F062C080E293E00E9441 +:103C600062188FE994E00E94D0118DE894E00E94E0 +:103C7000D0118BE794E00E94D0118DE894E00E946F +:103C8000C811811106C08BE794E00E94C8118823F7 +:103C900091F18EE19AE00E94F90982E293E00E949C +:103CA000621881EB94E00E94430F0E94DD0F0E9496 +:103CB000171B0E94C71348CF31E0C316D104E1049B +:103CC000F10489F00E94B22DA5019401275F3F4FB6 +:103CD0004F4F5F4F0E94202E6B017C012FEFC21AC5 +:103CE000D20AE20AF20ABC2C1C19C12E0E94041945 +:103CF00082EE93E083CF81EB94E00E94E30F882370 +:103D000009F4AFCF81EB94E00E94800C882349F244 +:103D100081E09AE00E94F9090E94201DC2CF823002 +:103D20009105D1F4E091B102F0E0E090B002F12C05 +:103D3000EE1AFF0A10E000E020E0AF0162EA73E053 +:103D40008EE190E08E1B9F0B0E9430199091B10282 +:103D5000890F8093B002ABCF8330910599F4E09046 +:103D6000B102F12C8091B00210E000E020E050E0C0 +:103D700040E063EA73E08150990B0E943019809310 +:103D8000B10295CF8430910511F52091B10230E058 +:103D9000E090B202F12CE21AF30A8FEFE81AF80A67 +:103DA000A901415051098091B00290E0821B930B10 +:103DB00010E000E020E064EA73E001960E94301910 +:103DC0009091B1029150890F8093B20270CF8530EB +:103DD0009105C1F4E090B302F12C10E000E020E086 +:103DE00048E953E068E973E086E090E00E9430190A +:103DF0008093B302282F2150330BB90187E00E9432 +:103E0000E01655CF8630910509F083C087E493EB27 +:103E1000A7E3B3E189839A83AB83BC8381E08D837D +:103E20001E8218861986F12CE12C10E000E020E0BB +:103E30004AEC53E06AEC73E086E090E00E943019AF +:103E4000D82E882309F433CF31E083130EC020E04D +:103E500040EC53E060EC73E084E090E00E943019A5 +:103E6000823039F1E8F4813009F180E293E00E9478 +:103E700062180E941A128DE894E00E94C811811104 +:103E800006C08BE794E00E94C8118823B1F08BE84C +:103E90009AE00E94881282E293E00E94621854CE57 +:103EA000833049F0843009F78CE301C085E08887CE +:103EB000DCCF8FE0FCCF8EE1FACF81EB94E00E9463 +:103EC000E30F8823B1F281EB94E00E94800C8823F9 +:103ED00009F4EDCE89E79AE00E948812DF82098119 +:103EE0001A812B813C814D815E816D2D788589857C +:103EF0000E941B1C64E670E080E090E00E94150BBD +:103F000081EB94E00E94430F0E94DD0F0E94041990 +:103F1000CECE87309105E1F4F12CE12C10E000E0E9 +:103F200020E04CEA53E06CEA73E084E090E00E9409 +:103F300030198150990B880F991F880F991F86544B +:103F40009D4F0E94AF1A80E991E00E946218AFCEA7 +:103F50008830910509F03FC0F12CE12C10E000E021 +:103F600020E040EC53E060EC73E085E090E00E94DC +:103F70003019833031F150F48130B1F0823009F0E2 +:103F800096CE8FE090E0A0E0B0E012C08430F1F077 +:103F9000853009F08CCE1092B5021092B6021092C4 +:103FA000B7021092B80283CE85E090E0A0E0B0E0C6 +:103FB0008093B5029093B602A093B702B093B80273 +:103FC00076CE8EE190E0A0E0B0E0F2CF8CE390E01E +:103FD000A0E0B0E0EDCF8930910509F089C087E419 +:103FE00093EBA7E3B3E189839A83AB83BC8381E03E +:103FF0008D8384E08F83F12CE12C10E000E021E040 +:1040000050E040E06DE271E083E690E00E943019FC +:10401000C82EA82EB12CC5010E94911A850121E05D +:1040200050E040E061E471E00E943019D82EC501F3 +:104030000E94911AED2CF12C21E050E040E062E466 +:1040400071E00E943019F82E88EA93E00E9462180D +:104050000E940419FD1408F42ACE8D2D90E00E94D0 +:104060006218D8866AE070E08D2D0E94761389E68A +:104070009AE00E9488120E941A128DE894E00E9431 +:10408000C811811132C08BE794E00E94C8118111E0 +:104090002CC081EB94E00E94E30F882361F381EB55 +:1040A00094E00E94800C8823F1F08AE49AE00E9458 +:1040B0008812CE8209811A812B813C814D815C2D31 +:1040C0006F81788589850E941B1C64E670E080E022 +:1040D00090E00E94150B81EB94E00E94430F0E9438 +:1040E000DD0F0E940419D394B5CF8CE59AE0D1CEB0 +:1040F0008A309105B1F4F12CE12C10E000E020E0D1 +:1041000045EA53E065EA73E082E090E00E943019EE +:10411000823021F481E08093B902C9CD1092B902B6 +:10412000C6CD8B309105B1F48BE29AE00E948812E3 +:10413000F12CE12C60E0C7010E94E3148FEFE81A34 +:10414000F80AE11424E0F206A9F70E943A1B87EE70 +:1041500093E0FBCE0C9709F0AACDF12CE12C10E0F6 +:1041600000E020E044ED53E064ED73E084E090E093 +:104170000E94301990E08130910519F41092CA0222 +:1041800096CD8230910521F481E08093CA028FCDD3 +:1041900083309105C9F48FED93E00E946218CE013F +:1041A00001960E942612882309F481CD89819A8183 +:1041B000AB81BC818093CB029093CC02A093CD02C3 +:1041C000B093CE0282E0E1CF049709F070CD83E096 +:1041D000DCCF8091D3039091D403009789F40E949F +:1041E000B22D20E030E041E050E00E94202ECB01D3 +:1041F0000E94F71468EE73E080E090E00C94150BD9 +:10420000DC01ED91FC910084F185E02D0995882376 +:1042100031F308958F929F92AF92BF92CF92DF9227 +:10422000EF92FF92CF93DF93EC01CF80D12C8FEFF1 +:10423000C81AD80A0D2C000CEE08FF088E80912CAD +:10424000B12CA12C8C149D04AE04BF048CF4C818AE +:10425000D908EA08FB0841F00E94B22DA701960197 +:104260000E94202E6B017C018C0C9D1CAE1CBF1C7F +:1042700082EA91E00E948812C4010E948B130E947E +:10428000470B48EE53E0489D9001499D300D589DE5 +:10429000300D1124620F731F811D911D6A837B8372 +:1042A0008C839D83DF91CF91FF90EF90DF90CF9033 +:1042B000BF90AF909F908F9008950F931F93CF93CF +:1042C000DF93FC014281538164817581452B462B2C +:1042D000472B29F1EC010E94470B0A811B812C819D +:1042E0003D810617170728073907C8F489EC91E0C4 +:1042F0000E9488120E946712882351F08DE291E09B +:104300000E94541864EF71E080E090E00E94150B69 +:10431000CE01DF91CF911F910F910C940A21DF9173 +:10432000CF911F910F910895EF92FF920F931F93DA +:10433000CF93DF9380914E0290914F0260914C0297 +:1043400070914D02FC013196E61BF70BA62F20E081 +:10435000422F50E04E175F0740F441535D4F3A2F14 +:10436000320FEA0138832F5FF3CF8F5F861BE82F70 +:10437000F0E0E153FD4F8F3F19F011928F5FFBCFBB +:10438000F12C20914E0230914F022F5F3F4F8091D0 +:104390004C0290914D028901081B190BCF2DD0E0E2 +:1043A000C017D10798F40E94B22DC153DD4FE880A9 +:1043B000980150E040E00E94202EE62FF0E0E1530B +:1043C000FD4F80818883E082F394DBCFDF91CF9132 +:1043D0001F910F91FF90EF9008958F929F92AF924F +:1043E000BF92CF92DF92EF92FF9285EC99E00E940C +:1043F00088120E94941281E08093D203109251029D +:1044000010925002E091D003F091D103808190E0AE +:104410000E94911A90934F0280934E0221E030E067 +:1044200030934D0220934C02BC0190E080E04AE0C2 +:104430000E94321381EB99E00E94F909E091D003C8 +:10444000F091D10380810E947D13E091D003F0911F +:10445000D1038181813079F581E899E00E94881249 +:10446000E0904E02F0904F028FEFE81AF80A82E0D7 +:10447000E816F10408F45AC10E94B22D970150E0E9 +:1044800040E021503109410951090E94202EDC01F0 +:10449000CB010196A11DB11D9093CF038093CE0354 +:1044A0000E948B13E091D003F091D1036091CE0371 +:1044B00080810E945F17E091D003F091D103818148 +:1044C000823091F484E599E00E94881281E090E0C6 +:1044D0009093CF038093CE03E091D003F091D1036A +:1044E00061E080810E945F17E091D003F091D103D9 +:1044F00081818330A9F487E199E00E9488120E94AB +:10450000942181E090E09093CF038093CE03E091DB +:10451000D003F091D1036091CF0280810E945F1798 +:10452000E091D003F091D1038181843091F482EE47 +:1045300098E00E948812E091D003F091D10362814B +:10454000862F90E09093CF038093CE0380810E94CA +:104550005F17E091D003F091D1038181853031F56F +:104560008FE998E00E948812E091D003F091D10386 +:10457000F0808F2D90E00E940A2E90E09093CF0360 +:104580008093CE03009739F020914E0230914F0274 +:104590002817390730F481E090E09093CF0380939F +:1045A000CE036091CE038F2D0E945F17E091D00360 +:1045B000F091D1038181873009F051C08EE598E0F8 +:1045C0000E948812E091D003F091D1036AE070E07C +:1045D00082810E94761388E598E00E94F909E091B3 +:1045E000D003F091D10383810E947D13E091D00329 +:1045F000F091D103C380D12CD0924F02C0924E02D1 +:104600008FEFC81AD80AF12CE12C8280912CB12CA2 +:10461000A12C8C149D04AE04BF048CF4C818D908D6 +:10462000EA08FB0841F00E94B22DA70196010E9402 +:10463000202E6B017C018C0C9D1CAE1CBF1C90922B +:10464000CF038092CE03C4010E948B13E091D0036C +:10465000F091D1036091CE0380810E945F17E091B9 +:10466000D003F091D1038181883061F589E098E031 +:104670000E948812E091D003F091D1036AE070E0CB +:1046800082810E94761383E098E00E94F909E0910C +:10469000D003F091D10383810E947D13E091D00378 +:1046A000F091D103838190E090934F0280934E026A +:1046B0006281862F90E09093CF038093CE03808118 +:1046C0000E945F17E091D003F091D103818189307E +:1046D00091F586EB97E00E948812E091D003F0916B +:1046E000D103828190E090934D0280934C028381AC +:1046F00090E090934F0280934E020E94942181E0BB +:1047000090E09093CF038093CE03E091D003F0919B +:10471000D1036091CF028081FF90EF90DF90CF9026 +:10472000BF90AF909F908F900C945F1781E090E0C6 +:10473000A0E0B0E0B1CEFF90EF90DF90CF90BF90BF +:10474000AF909F908F900895CF93C82F8EEE99E0F1 +:104750000E9488128C2F0E947D1324E0C29FC0010A +:104760001124FC01E555FD4F2785222389F086544D +:104770009D4F9093D1038093D0030E94ED210E941E +:10478000941268EE73E080E090E0CF910C94150BEA +:1047900085ED99E0CF910C9488121F93CF93DF930E +:1047A000EC0183EF93E00E9488121B851123E9F04E +:1047B0001B8689E0FE013296A2EAB2E001900D92DA +:1047C0008A95E1F787EA92E09093D1038093D00332 +:1047D0008091A7020E947D13E091D003F091D10354 +:1047E00081810E947D130E94ED21812FDF91CF9165 +:1047F0001F9108950F931F93CF93DF93FC01428184 +:10480000538164817581452B462B472BF9F0EC01D0 +:104810000E94470B0A811B812C813D8106171707D7 +:104820002807390798F486E691E00E9488120E94D2 +:1048300058180E94C7131092D4031092D303CE01CC +:10484000DF91CF911F910F910C944D2FDF91CF915C +:104850001F910F9108951F920F920FB60F9211247E +:104860002F933F934F935F936F937F938F939F9378 +:10487000AF93BF93EF93FF938EED93E00E948A096D +:10488000FF91EF91BF91AF919F918F917F916F9128 +:104890005F914F913F912F910F900FBE0F901F90FE +:1048A00018951F920F920FB60F9211242F938F938A +:1048B0009F93EF93FF93E091EE03F091EF038081DC +:1048C000E091F403F091F50382FD1BC0908180918B +:1048D000F7038F5F8F732091F803821741F0E09107 +:1048E000F703F0E0E252FC4F958F8093F703FF91BE +:1048F000EF919F918F912F910F900FBE0F901F906E +:1049000018958081F4CF1F920F920FB60F92112449 +:104910002F933F938F939F93AF93BF938091930275 +:1049200090919402A0919502B091960230919202DA +:1049300023E0230F2D3758F50196A11DB11D2093BB +:1049400092028093930290939402A0939502B09365 +:1049500096028091970290919802A0919902B0914D +:104960009A020196A11DB11D80939702909398021F +:10497000A0939902B0939A02BF91AF919F918F91AA +:104980003F912F910F900FBE0F901F90189526E822 +:10499000230F0296A11DB11DD2CF1F920F920FB609 +:1049A0000F9211242F933F934F935F936F937F93B5 +:1049B0008F939F93AF93BF93EF93FF93E0919D02EB +:1049C000F0919E02309749F0A685B7858585968D32 +:1049D00091FF14C09C918923A1F4FF91EF91BF91A5 +:1049E000AF919F918F917F916F915F914F913F9187 +:1049F0002F910F900FBE0F901F9018959C918923B7 +:104A000061F7A389B4899C918589809589238C93CA +:104A1000868997890197F1F7608D718DA685B78595 +:104A2000558538E020E0CB010197F1F7822F90E027 +:104A300095958795282F4C91452309F02068315092 +:104A400091F7868D81FD209580919C0290E00196E2 +:104A50008F73992730919B02381799F0A0919C028F +:104A6000B0E0AE5ABD4F2C9380939C02828D938D03 +:104A70000197F1F7A389B4898C919589892B8C933F +:104A8000ACCF868D8160868FF1CF1092E1031092BA +:104A9000E00388EE93E0A0E0B0E08093E20390931F +:104AA000E303A093E403B093E5032FED31E03093EB +:104AB000DF032093DE0325EC30E03093EB032093FB +:104AC000EA0324EC30E03093ED032093EC0320EC78 +:104AD00030E03093EF032093EE0321EC30E030938D +:104AE000F1032093F00322EC30E03093F3032093A2 +:104AF000F20326EC30E03093F5032093F403109298 +:104B0000F7031092F8031092F9031092FA0310922F +:104B1000CD041092CC048093CE049093CF04A09344 +:104B2000D004B093D1048BEF91E09093CB048093A9 +:104B3000CA041092E1041092E0041092E30410926F +:104B4000E2041092E5041092E4041092E70410923B +:104B5000E6046091E8046E7F6D7F6093E8046695DB +:104B6000617081E0682783E00E94860A61E083E04B +:104B70000E94B40AE9E7F1E1E491E093DA04E5E6A2 +:104B8000F1E1E491F0E0EE0FFF1FE85AFE4E85914F +:104B900094919093DC048093DB0460E082E00E94B7 +:104BA000B40A8091E80481FD04C061E082E00E94C3 +:104BB000860A82E08093D604E8E7F1E1E491E0938D +:104BC000D704E4E6F1E1E491F0E0EE0FFF1FE25BD1 +:104BD000FE4E859194919093D9048093D8048AECE9 +:104BE00094E09093C2048093C10482E390E0909398 +:104BF000C8048093C7041092C90481EF91E0909398 +:104C0000B2048093B1048AE08093BF0489E080936A +:104C1000C0048EE080939F0449E150E060E070E0C2 +:104C20004093A0045093A1046093A2047093A30442 +:104C300081E08093A4048093A5049FE090938D0469 +:104C400040938E0450938F0460939004709391046A +:104C5000809392048093930490E190937B0440931B +:104C60007C0450937D0460937E0470937F04809352 +:104C70008004809381040895CF93DF93CDB7DEB78E +:104C8000A6970FB6F894DEBF0FBECDBF789484B55B +:104C9000826084BD84B5816084BD85B5826085BD38 +:104CA00085B5816085BD80916E00816080936E00C6 +:104CB00010928100809181008260809381008091B8 +:104CC0008100816080938100809180008160809369 +:104CD00080008091B10084608093B1008091B00029 +:104CE00081608093B00080917A00846080937A0024 +:104CF00080917A00826080937A0080917A0081604E +:104D000080937A0080917A00806880937A00109274 +:104D1000C100E091EE03F091EF0382E08083E09127 +:104D2000EA03F091EB031082E091EC03F091ED03C4 +:104D300080E180831092F603E091F203F091F30397 +:104D400086E08083E091F003F091F103808180613F +:104D50008083E091F003F091F1038081886080838B +:104D6000E091F003F091F103808180688083E0910D +:104D7000F003F091F10380818F7D808320E0E7E4F0 +:104D8000E0937C0080917A00806480937A00809127 +:104D90007A0086FDFCCF8091780090917900482FB1 +:104DA000417050E04A01550FAA08BB08322F3F71ED +:104DB00004C0880C991CAA1CBB1C3A95D2F7C501EB +:104DC000B4016C257D258E259F252F5F203809F0A5 +:104DD000C5C18C149D04AE04BF0411F00E94012EC5 +:104DE00089E69EE00E94881281E49EE00E9488127B +:104DF00089E19EE00E94881280EF9DE00E94881267 +:104E00008CED9DE00E94881287EA9DE00E94881246 +:104E100082E79DE00E94881261E086E00E94B40A69 +:104E200060E086E00E94860A8DE49CE00E94881281 +:104E300060E084E00E94B40A0E94631B0E94C713D2 +:104E4000E091C104F091C204138E128E118E108E67 +:104E5000178A168A8DE991E0958F848F8485863133 +:104E600008F03DC02DEB30E0378B268B2BE931E08D +:104E7000318F208F2CE231E0338F228F90916800A8 +:104E8000883008F46EC121E08E3008F420E081E023 +:104E900001C0880F2A95EAF7892B809368009485D2 +:104EA0002DE630E0983050F02BE630E09E3030F0C8 +:104EB0002CE630E0963110F030E020E0348B238B8C +:104EC000292F30E0983008F04EC181E001C0880FF2 +:104ED0009A95EAF7858B848D958D0197F1F7828DF0 +:104EE000938D892B41F140919D0250919E02E417D0 +:104EF000F50709F14115510569F0DA0153962D9135 +:104F00003C91D9019C91DA0155968C918095892329 +:104F1000D9018C93868D8E7F868F10929C02109281 +:104F20009B02F0939E02E0939D02A389B4898C9129 +:104F30009589892B8C93E091C104F091C20480E1A2 +:104F400097E2A0E0B0E084839583A683B7830E94B4 +:104F5000470B6093C3047093C4048093C50490937B +:104F6000C60460ED77E080E090E00E94150B609150 +:104F7000B2026093A00270E086E00E94E0166091A9 +:104F8000B3026150770B87E00E94E0161FB7F894D8 +:104F900080919F02811127C0ECE6F1E18491E0E865 +:104FA000F1E19491E82FF0E0EE0FFF1FE259F34F8B +:104FB000A591B491EC91E92321F461E08AE00E948B +:104FC000860A61E08AE00E94B40A8CB580618CBDDB +:104FD0008CB580648CBD61E08DE00E94B40A61E014 +:104FE0008BE00E94B40A80919F028F5F80939F02A2 +:104FF0001FBF61E08091BF040E94B40A61E080910C +:10500000BF040E94860A8091C0048F3F09F4B8C093 +:1050100060E00E94B40A8091C0040E945D0A892B5E +:1050200009F0AEC061E08091C0040E94B40A60E063 +:105030008091C0040E94860A83E090E00197F1F716 +:1050400061E08091C0040E94860A62E370E080E023 +:1050500090E00E94150B40E064E281EB94E00E9436 +:10506000140D40E066E281EB94E00E94140D46E2EC +:1050700068E481EB94E00E94140D40E864E581EB64 +:1050800094E00E94140D49EA66E581EB94E00E94E9 +:10509000140D43E068E581EB94E00E94140D48EEA6 +:1050A0006AE581EB94E00E94140D40E46AE281EB32 +:1050B00094E00E94140D4DE362E281EB94E00E94C3 +:1050C000140D68E281EB94E00E94F60C982F937027 +:1050D000933039F0482F436068E281EB94E00E94FE +:1050E000140D6CE481EB94E00E94F60C807780371D +:1050F00091F040E76CE481EB94E00E94C90F6CE40E +:1051000081EB94E00E94F60C482F40676CE481EB41 +:1051100094E00E94140D84E59DE00E9488126EE6E2 +:1051200081EB94E00E94F60C182F8FEF9CE00E9418 +:10513000F90960E170E0812F0E9476138CEE9CE00B +:105140001039E9F1A0F588EC9CE01231C1F184EF4F +:105150009CE01838A1F18BEB9CE031C06B017C0125 +:105160000FCE84E099CE9E3040F42850310981E082 +:1051700001C0880F2A95EAF7ADCE2E503109F7CF3E +:105180004FE062E081EB94E00E94140D13E062E3D3 +:1051900070E080E090E00E94150B62E081EB94E00B +:1051A0000E94F60C84FF57CF115089F754CF84EE3C +:1051B0009CE0113921F08CED9CE0123961F60E94DF +:1051C000881211501E3F20F088E79CE00E94881250 +:1051D0008FEF8093D8038093D9038093DA03809371 +:1051E000DB038093DC038093DD0362E08EE00E94AA +:1051F000B40A62E08FE00E94B40A62E080E10E949B +:10520000B40A61E087E00E94B40A60E087E00E948F +:10521000860A61E086E00E94860A84E19DE00E94A1 +:1052200088128EE00E945D0A892B01F58FE00E94B2 +:105230005D0A892BD9F480E10E945D0A8C01892BDB +:10524000A9F485E39DE00E948812C8010E940A2EFD +:10525000882321F060E0C8010E94122E0F5F1F4FCB +:105260000115B4E01B0789F70E94631B83E00E94CD +:10527000A423F7EA2F2EF2E03F2EA6E56A2EA1E046 +:105280007A2EBEE0AB2EB1E0BB2E16E8812E11E0E7 +:10529000912E11E00E94B6180E94CE168091D30381 +:1052A0009091D403009739F0DC01ED91FC910190CD +:1052B000F081E02D09950E941A128FE994E00E9476 +:1052C000F108082F81110DC08DE894E00E94F108CB +:1052D000811107C08BE794E00E94F108882309F44C +:1052E0005BC08091A604882309F456C08091940481 +:1052F000882309F451C080918204882309F44CC0AA +:105300000E9458180E941A128091A6048111FACFA7 +:10531000809194048111F6CF809182048111F2CFA3 +:105320000E941A1280E00E945A1D81EB94E00E94B4 +:10533000800C882309F49BC08EE191E10E94F90959 +:105340006091B30484EB94E00E9411140E948412D3 +:1053500082E191E10E94F909E091BE04EF77E13426 +:1053600008F046C1F0E0E656FE4F108181E89FE06C +:10537000153009F401C108F024C18EEA9FE0123013 +:1053800009F4FAC008F0EFC086ED9FE0113009F48F +:10539000F3C085E09FE0F0C08FE994E00E94C8115F +:1053A000811115C0002349F18091D703811125C0D7 +:1053B0008091D3039091D403009709F06FC00E94AD +:1053C0006712811176C080E00E94A4238DC0809175 +:1053D000D3039091D403009709F03FC08091D70385 +:1053E000811109C00E946712882309F44DC00E94F0 +:1053F00058180E94C7131092D7038DE894E00E94BA +:10540000F108882309F47AC00E946712882309F4FE +:1054100071C08091B90281116AC00E948E181093E8 +:10542000D6038BE794E00E94F108882309F484C036 +:105430000E946712882309F47BC08091B902811110 +:1054400074C00E9466181093D50381EB94E00E940B +:10545000E30F882309F41ECF68CFDC01ED91FC91A6 +:105460000280F381E02D0995882309F4B7CF80E00D +:1054700090E0892B09F40DCF0E947609882309F466 +:10548000F8CE0E940000F5CE8091D203882309F463 +:10549000B2CF0E945D180E949412ADCFDC01ED9155 +:1054A000FC910280F381E02D0995882309F487CFD0 +:1054B000DECFE091D003F091D10321818091CE0322 +:1054C0009091CF03233011F0293021F482539D4F66 +:1054D000DC018C912850223020F49281B12FB91B2D +:1054E0008B0F90E00E9454181093D70386CF0E9430 +:1054F000E92095CF81E00E94A42391CF8DE894E02C +:105500000E94C811882309F48CCF8091D6038111A1 +:1055100006C08091B902811105C00E94E920109255 +:10552000D6037FCF0E948E18FACF0E9463178BCFCD +:1055300082E00E94A42387CF8BE794E00E94C811E9 +:10554000882309F482CF8091D503811106C0809110 +:10555000B902811105C00E9463171092D50375CF5F +:105560000E946618FACF87E99FE0133029F08CE893 +:105570009FE0143009F00DCF0E94881282E18EA3C3 +:105580000DEF010F0330B0F58CEE90E10E94881210 +:1055900087E00E94F10E8093A1025090A102552055 +:1055A000B1F184EB90E10E94F909852D0E94900CE5 +:1055B0000E94881281EB94E00E94430F0E94DD0F4D +:1055C00056CF84E49FE01830B9F248F48FE59FE0AD +:1055D000163091F283E59FE0173071F2DACE85E361 +:1055E0009FE0193049F282E19FE01F3F29F2D1CEBE +:1055F00010E0CFCE163089F619821A8280ED90E144 +:105600000E948812CE0101960E94930EC4CF0330EF +:1056100008F0A0C08BE990E10E94F9096AE070E00F +:1056200084E00E94761386E990E10E948812AE0120 +:105630004A5D5F4FBE016D5E7F4F84E00E94900F18 +:10564000182F8093A1028FE790E11111E3C08DE044 +:1056500090E10E94F9098BE090E10E94881260E1DC +:10566000CE0143960E9411140E9484120E9484125B +:105670008B8990E0B0E0A0E0782F6627552744277B +:105680009C89892F90E0B0E0A0E0DC019927882771 +:10569000840F951FA61FB71F2E89820F911DA11D74 +:1056A000B11D4D8950E070E060E0762F652F542FDA +:1056B0004427840F951FA61FB71F89839A83AB8346 +:1056C000BC832F892D83288D2E83398D3F833A8D7E +:1056D00038873B8D39878734934BA743B34109F013 +:1056E000C4C18091D3039091D403009709F0A0C066 +:1056F0008E81882309F4ADC099E0FE013196A2EABB +:10570000B2E001900D929A95E1F70E947D133092DC +:10571000D1032092D0038091A7020E947D13809133 +:10572000A2029091A302A091A402B091A502873495 +:10573000934BA743B34109F0A2C18091A7028823EC +:1057400009F438CF8091A802882309F433CF0E944E +:10575000ED2130CF163009F07ACF82E18DA3AE0172 +:105760004B5D5F4FBE016F5F7F4F88E00E94900FDF +:10577000182F8093A10286E690E111114BC084E0BE +:10578000FE013196DE01539601900D928A95E1F764 +:10579000AE014B5D5F4FBE016F5F7F4F89E00E949E +:1057A000900F182F8093A1028DE490E1111132C067 +:1057B00084E0FE013196DE01579601900D928A95A4 +:1057C000E1F7AE014B5D5F4FBE016F5F7F4F8AE037 +:1057D0000E94900F182F8093A10284E390E1111191 +:1057E00019C084E0FE013196DE015B9601900D92B6 +:1057F0008A95E1F7AE014B5D5F4FBE016F5F7F4F52 +:105800008BE00E94900F182F8093A102882331F023 +:105810008BE190E10E94F909812FC8CE84E0FE015E +:105820003196DE015F9601900D928A95E1F70FCFD8 +:10583000222309F45DCFDC01ED91FC910088F18910 +:10584000E02DBE016F5F7F4F0995882309F450CF8B +:10585000B1CE8091D3039091D4030097B1F1DC01D4 +:10586000ED91FC910288F389E02D09959F818913C0 +:105870002CC01092D4031092D3038AEF9FE00E94B1 +:1058800088120E946712882359F085E091E00E94F7 +:10589000541860ED77E080E090E00E94150B8ACE0E +:1058A0000E945D1864E670E080E090E00E94150BB5 +:1058B00085E091E00E94541864E670E080E090E09A +:1058C0000E94150B0E945818E4CF8F8181508E3FA3 +:1058D00040F40E9467128823B9F084E091E00E94AE +:1058E00054188F81833009F48BC018F5813069F129 +:1058F00008F057C081EB94E00E94430F0E94DD0F37 +:1059000081E00E945A1DC5CF0E945D1864E670E0D8 +:1059100080E090E00E94150B84E091E00E94541812 +:1059200064E670E080E090E00E94150B0E94581839 +:10593000D8CF853009F47EC008F46FC0863009F4F2 +:1059400089C08F3F09F0A5CFD5CF86E090E00E94B7 +:10595000B12E8C015884FC019182808212821382C4 +:105960001482158284EF9EE00E948812852D0E9489 +:105970007D130E94470B6B017C01252D30E0A0E6D2 +:10598000BAEE0E94742E6C0D7D1D8E1D9F1DF801B8 +:1059900062837383848395831093D4030093D3032A +:1059A00078CF88E090E00E94B12E8C018EE691E0E5 +:1059B000D8018D939C93F801128213821482158270 +:1059C00085E086838EE1878382EE9EE00E948812C6 +:1059D0000E946712882381F068EE73E080E090E017 +:1059E0000E94150B8CE291E00E94541864EF71E064 +:1059F00080E090E00E94150BC8010E940A21CCCFE4 +:105A000082E090E00E94B12E8C01DC016D927C92CC +:105A100085ED9EE00E948812BFCF82E090E00E9458 +:105A2000B12E8C012EE331E0FC013183208383EC25 +:105A30009EE0F0CF8CE090E00E94B12E8C01E6E277 +:105A4000F1E0DC011196FC93EE931B961C928CEA1C +:105A50009EE0E0CF82E090E00E94B12E8C01DC015C +:105A6000AD92BC9281E99EE0D5CF89E0FE013196EE +:105A7000A2EAB2E001900D928A95E1F750CE109221 +:105A8000D2038CE291E00E9462180E9404190E94E5 +:105A9000201D90CD8BEF91E09093CB048093CA04AE +:105AA00080919D0290919E028A5C944071F4E091F5 +:105AB000DD04F091DE0490818091DF0480958923DC +:105AC000808310929E0210929D0208958F929F9261 +:105AD000AF92BF92CF92DF92EF92FF92CF93DF937C +:105AE000EC01688179818A819B816115710581054D +:105AF000910521F464E279ED8BE597E02DE133EF38 +:105B000041E050E00E94202E49015A019B01AC0166 +:105B1000A7EAB1E40E943F2E6B017C01ACEEB4EF2A +:105B2000A50194010E944D2EC60ED71EE81EF91E37 +:105B3000F7FE06C081E0C81AD108E10880E8F80A3B +:105B4000C882D982EA82FB82C701B6019F77DF91C2 +:105B5000CF91FF90EF90DF90CF90BF90AF909F904C +:105B60008F9008958F929F92AF92BF92CF92DF92C3 +:105B7000EF92FF926091000170910101809102010A +:105B800090910301611571058105910521F464E28D +:105B900079ED8BE597E02DE133EF41E050E00E9495 +:105BA000202E49015A019B01AC01A7EAB1E40E94F1 +:105BB0003F2E6B017C01ACEEB4EFA50194010E9475 +:105BC0004D2EC60ED71EE81EF91EF7FE06C081E058 +:105BD000C81AD108E10880E8F80AC0920001D09202 +:105BE0000101E0920201F0920301C701B6019F7723 +:105BF000FF90EF90DF90CF90BF90AF909F908F90ED +:105C000008956093000170930101809302019093C5 +:105C100003010895F999FECF92BD81BDF89A9927A5 +:105C200080B50895262FF999FECF1FBA92BD81BD88 +:105C300020BD0FB6F894FA9AF99A0FBE019608950E +:105C4000052E97FB1EF400940E94372E57FD07D0B7 +:105C50000E94522E07FC03D04EF40C94372E509520 +:105C60004095309521953F4F4F4F5F4F0895909548 +:105C70008095709561957F4F8F4F9F4F08950E943B +:105C8000742EA59F900DB49F900DA49F800D911D23 +:105C900011240895B7FF0C943F2E0E943F2E821BC3 +:105CA000930B0895A1E21A2EAA1BBB1BFD010DC088 +:105CB000AA1FBB1FEE1FFF1FA217B307E407F507BC +:105CC00020F0A21BB30BE40BF50B661F771F881F98 +:105CD000991F1A9469F760957095809590959B012E +:105CE000AC01BD01CF010895A29FB001B39FC001D7 +:105CF000A39F700D811D1124911DB29F700D811DF8 +:105D00001124911D089597FB072E16F4009407D0D7 +:105D100077FD09D00E94972E07FC05D03EF49095A0 +:105D200081959F4F0895709561957F4F0895AA1BA7 +:105D3000BB1B51E107C0AA1FBB1FA617B70710F076 +:105D4000A61BB70B881F991F5A95A9F780959095A8 +:105D5000BC01CD010895EE0FFF1F0590F491E02DD9 +:105D600009940F931F93CF93DF938230910510F422 +:105D700082E090E0E091EB04F091EC0430E020E070 +:105D8000B0E0A0E0309799F42115310509F44AC03C +:105D9000281B390B24303105D8F58A819B81611588 +:105DA000710589F1FB0193838283FE0111C040815B +:105DB00051810281138148175907E0F048175907AC +:105DC00099F4109761F012960C93129713961C9306 +:105DD0003296CF01DF91CF911F910F9108950093DB +:105DE000EB041093EC04F4CF2115310551F0421768 +:105DF000530738F0A901DB019A01BD01DF01F80169 +:105E0000C1CFEF01F9CF9093EC048093EB04CDCF99 +:105E1000FE01E20FF31F81939193225031093983E0 +:105E20002883D7CF2091E9043091EA04232B41F451 +:105E300020910601309107013093EA042093E90490 +:105E400020910401309105012115310541F42DB750 +:105E50003EB74091080150910901241B350BE09198 +:105E6000E904F091EA04E217F307A0F42E1B3F0BBC +:105E70002817390778F0AC014E5F5F4F24173507BC +:105E800048F04E0F5F1F5093EA044093E90481935A +:105E900091939FCFF0E0E0E09CCFCF93DF9300970A +:105EA000E9F0FC01329713821282A091EB04B091C9 +:105EB000EC04ED0130E020E01097A1F42081318165 +:105EC000820F931F2091E9043091EA0428173907C3 +:105ED00009F061C0F093EA04E093E904DF91CF9107 +:105EE0000895EA01CE17DF07E8F54A815B819E013C +:105EF00041155105B1F7E901FB83EA8349915991B5 +:105F0000C40FD51FEC17FD0761F4808191810296C3 +:105F1000840F951FE90199838883828193819B83F4 +:105F20008A83F0E0E0E012968D919C9113970097A0 +:105F3000B9F52D913C911197CD010296820F931FD7 +:105F40002091E9043091EA042817390739F630978F +:105F500051F51092EC041092EB04B093EA04A09374 +:105F6000E904BCCFD383C28340815181840F951F44 +:105F7000C817D90761F44E5F5F4F88819981480F38 +:105F8000591F518340838A819B819383828321158A +:105F9000310509F0B0CFF093EC04E093EB049ECF11 +:105FA000FD01DC01C0CF13821282D7CFFB01DC01DF +:105FB00002C001900D9241505040D8F7089518E06A +:105FC000C6ECD8E004C0FE010E94AB2E2196C73C6F +:085FD000D107C9F7F894FFCFD7 +:105FD800010000000000ED048000000000007612BF +:105FE80074122C18741274127412741274127212BD +:105FF800A1120000000076127412CD237412D81278 +:10600800D21274127412AD12A71200000000761298 +:10601800FC1274127412F612F012EA12E4127212DE +:10602800DE120000000076122013741274121A1384 +:1060380014130E13081302137012000000005D21E0 +:10604800741274127412741274127412741272121A +:10605800261300000000FA237412741274127412CA +:1060680074127412741272122C1306090000FF00C5 +:106078000000040300000000000007070000000003 +:106088000000050000000000000001000000000002 +:1060980000000000000000000000000000000000F8 +:1060A800000000000000000000000200000000AC3A +:1060B800090C093909140A6A0948095C0900000031 +:1060C800004610E30F800C00000000E80B0C097D6F +:1060D8000CE70B440C5C0CCF0B0D0A00203000536E +:1060E80044204B6172746520005553422000466C71 +:1060F8006173682000436F6D204572726F722000D3 +:106108006F6E6C696E650062657265697400656EB4 +:08611800746665726E740000EC +:00000001FF diff --git a/src/Tonuino.ino.with_bootloader.eightanaloginputs.hex b/src/Tonuino.ino.with_bootloader.eightanaloginputs.hex new file mode 100644 index 00000000..ddc36769 --- /dev/null +++ b/src/Tonuino.ino.with_bootloader.eightanaloginputs.hex @@ -0,0 +1,1678 @@ +:020000040000FA +:100000000C94C7080C94EF080C94EF080C94CD24C2 +:100010000C94CD240C94CD240C94EF080C94EF0890 +:100020000C94EF080C94EF080C94EF080C94EF0874 +:100030000C94EF080C94EF080C94EF080C94EF0864 +:100040000C9483240C94EF080C9451240C942B24CE +:100050000C94EF080C94EF080C94EF080C94EF0844 +:100060000C94EF080C94EF083D3D3D2077726974C5 +:100070006553657474696E6773546F466C61736819 +:100080002829003D3D3D2072657365745365747485 +:10009000696E677328290031202D3E2032003D3DD6 +:1000A0003D20726573657453657474696E67732857 +:1000B000290041646D696E204D656E752050696E32 +:1000C0003A200041646D696E204D656E75206C6F3D +:1000D000636B65643A2000496E76657274656420CE +:1000E000566F6C756D6520427574746F6E733A202F +:1000F00000536C6565702054696D65723A20004C40 +:100100006F636B65643A200045513A2000496E697F +:100110007469616C20566F6C756D653A20004D698D +:100120006E696D616C20566F6C756D653A20004D7F +:100130006178696D616C20566F6C756D653A200051 +:1001400056657273696F6E3A20003D3D3D206C6FBD +:10015000616453657474696E677346726F6D466C43 +:100160006173682829003D3D3D20536C65657054DE +:10017000696D65723A3A6C6F6F702829202D3E20A8 +:10018000534C45455021003D3D20536C65657054EE +:10019000696D65723A3A676574416374697665287A +:1001A00029003D3D3D20467265657A6544616E6378 +:1001B000653A3A7365744E65787453746F70417420 +:1001C0004D696C6C69732829003D3D204672656558 +:1001D0007A6544616E63653A3A6C6F6F70282920C6 +:1001E0002D3E20465245455A4521003D3D20467250 +:1001F00065657A6544616E63653A3A676574416323 +:10020000746976652829003D3D204C6F636B6564F9 +:100210003A3A68616E646C6550617573652829208F +:100220002D3E204C4F434B454421003D3D204C6F1B +:10023000636B65643A3A68616E646C654E657874A8 +:10024000427574746F6E2829202D3E204C4F434B0D +:10025000454421003D3D204C6F636B65643A3A682C +:10026000616E646C6550726576696F757342757402 +:10027000746F6E2829202D3E204C4F434B4544215E +:10028000003D3D204C6F636B65643A3A68616E6473 +:100290006C65566F6C756D6555702829202D3E2054 +:1002A0004C4F434B454421003D3D204C6F636B65F3 +:1002B000643A3A68616E646C65566F6C756D65443E +:1002C0006F776E2829202D3E204C4F434B4544210B +:1002D000003D3D204C6F636B65643A3A68616E6423 +:1002E0006C65524649442829202D3E204C4F434BF3 +:1002F000454421003D3D20546F64646C65724D6F30 +:1003000064653A3A68616E646C655061757365281E +:1003100029202D3E204C4F434B454421003D3D209C +:10032000546F64646C65724D6F64653A3A68616ECF +:10033000646C654E657874427574746F6E282920FC +:100340002D3E204C4F434B454421003D3D20546FF2 +:1003500064646C65724D6F64653A3A68616E646C92 +:100360006550726576696F7573427574746F6E2827 +:1003700029202D3E204C4F434B454421003D3D203C +:10038000546F64646C65724D6F64653A3A68616E6F +:10039000646C65566F6C756D6555702829202D3E0F +:1003A000204C4F434B454421003D3D20546F646435 +:1003B0006C65724D6F64653A3A68616E646C65563F +:1003C0006F6C756D65446F776E2829202D3E204C2B +:1003D0004F434B454421003D3D20546F64646C65A0 +:1003E000724D6F64653A3A67657441637469766506 +:1003F0002829003D3D204B696E6465726761726417 +:10040000656E4D6F64653A3A68616E646C654E6501 +:1004100078742829202D3E204E455854003D3D201B +:100420004B696E64657267617264656E4D6F646579 +:100430003A3A68616E646C654E657874427574749E +:100440006F6E2829202D3E204C4F434B4544210000 +:100450003D3D204B696E64657267617264656E4DE7 +:100460006F64653A3A68616E646C6550726576696E +:100470006F7573427574746F6E2829202D3E204C61 +:100480004F434B454421003D3D204B696E646572EE +:1004900067617264656E4D6F64653A3A68616E6457 +:1004A0006C65524649442829202D3E20717565759A +:1004B000656421003D3D204B696E64657267617221 +:1004C00064656E4D6F64653A3A676574416374693B +:1004D00076652829003D3D20526570656174536939 +:1004E0006E676C654D6F6469666965723A3A6861FA +:1004F0006E646C654E6578742829202D3E20524527 +:10050000504541542043555252454E542054524177 +:10051000434B003D3D2052657065617453696E67C1 +:100520006C654D6F6469666965723A3A67657441D6 +:10053000637469766528290048C3B672627563687A +:10054000204D6F6475732069737420616B746976D4 +:10055000202D3E206EC3A4636873746572205472AC +:1005600061636B20756E6420466F7274736368728A +:100570006974742073706569636865726E0045699B +:100580006E7A656C204D6F64757320616B7469764B +:10059000202D3E205374726F6D2073706172656EF2 +:1005A00000456E646520646572205175657565202F +:1005B0002D3E20626567696E6E6520766F6E2076CF +:1005C0006F726E65005061727479202D3E207765E0 +:1005D0006974657220696E20646572205175657555 +:1005E000652000416C62756D6D6F64757320697371 +:1005F0007420616B746976202D3E206EC3A46368FD +:100600007374657220547261636B3A200048C3B6FC +:1006100072737069656C6D6F647573206973742093 +:10062000616B746976202D3E206B65696E656E2066 +:100630006E6575656E20547261636B2073706965B9 +:100640006C656E003D3D3D206E657874547261634B +:100650006B2829003D3D3D207365747374616E64A1 +:10066000627954696D65722829003D3D3D206469B9 +:100670007361626C657374616E6462792829003DF0 +:100680003D3D20706F776572206F666621003D3DAD +:100690003D20766F6C756D6555702829003D3D3D98 +:1006A00020766F6C756D65446F776E28290048C39E +:1006B000B67262756368204D6F64757320697374D8 +:1006C00020616B746976202D3E20766F72686572AA +:1006D0006967657220547261636B20756E64204691 +:1006E0006F72747363687269747420737065696380 +:1006F0006865726E0045696E7A656C204D6F647531 +:100700007320616B746976202D3E20547261636B97 +:1007100020766F6E20766F726E6520737069656CDF +:10072000656E00416E66616E67206465722051756A +:10073000657565202D3E20737072696E6765206156 +:100740006E7320456E646520005061727479204D8F +:100750006F6475732069737420616B746976202DE2 +:100760003E207A7572C3BC636B20696E206465722B +:10077000205165756575652000416C62756D6D6F02 +:100780006475732069737420616B746976202D3EE3 +:1007900020766F7268657269676572205472616352 +:1007A0006B003D3D3D2070726576696F75735472C4 +:1007B00061636B2829005370657A69616C6D6F64A1 +:1007C000757320566F6E2D4269733A2050617274B2 +:1007D00079202D3E204F72646E657220696E207AFA +:1007E0007566C3A46C6C696765722052656968653B +:1007F0006E666F6C676520776965646572676562B0 +:10080000656E002062697320005370657A69616CBF +:100810006D6F64757320566F6E2D4269733A204177 +:100820006C62756D3A20616C6C6520446174656919 +:10083000656E207A7769736368656E2053746172A0 +:10084000742D20756E6420456E6464617465692042 +:10085000737069656C656E00206269732000537067 +:10086000657A69616C6D6F64757320566F6E2D4289 +:10087000696E3A2048C3B672737069656C202D3E6C +:10088000207A7566C3A46C6C6967656E20547261CA +:10089000636B20776965646572676562656E0048A1 +:1008A000C3B67262756368204D6F647573202D3E08 +:1008B000206B6F6D706C657474656E204F72646E22 +:1008C000657220737069656C656E20756E64204674 +:1008D0006F727473636872697474206D65726B658E +:1008E0006E0045696E7A656C204D6F647573202DBE +:1008F0003E2065696E652044617465692061757389 +:100900002064656D204F6472646E6572206162734D +:100910007069656C656E005061727479204D6F640A +:100920007573202D3E204F72646E657220696E20B3 +:100930007A7566C3A46C6C696765722052656968D4 +:10094000656E666F6C67652077696564657267655B +:1009500062656E00416C62756D204D6F6475732029 +:100960002D3E206B6F6D706C657474656E204F72D8 +:10097000646E657220776965646572676562656E2D +:100980000048C3B672737069656C6D6F64757320CF +:100990002D3E207A7566C3A46C6C6967656E205421 +:1009A0007261636B20776965646572676562656E05 +:1009B00000204461746569656E20696E204F726421 +:1009C0006E657220003D3D20706C6179466F6C64ED +:1009D000657228290053686F7274637574206E6F96 +:1009E0007420636F6E6669677572656421003D3DB2 +:1009F0003D20706C617953686F7274437574282957 +:100A0000004B617274652077697264206E65752091 +:100A10006B6F6E66696775726965727421004162F9 +:100A2000676562726F6368656E21005265736574F5 +:100A3000202D3E20454550524F4D2077697264204D +:100A400067656CC3B67363687400736368726569C5 +:100A50006265204B617274652E2E2E0041626765BF +:100A600062726F6368656E2100204B61727465204D +:100A70006175666C6567656E00736368726569624F +:100A800065204B617274652E2E2E0041626765628F +:100A9000726F6368656E21003D3D3D2061646D6944 +:100AA0006E4D656E752829003D3D3D20736574755A +:100AB00070436172642829004D49464152455F5791 +:100AC000726974652829206661696C65643A200042 +:100AD000202E2E2E0057726974696E67206461742F +:100AE0006120696E746F20626C6F636B20005043ED +:100AF000445F41757468656E746963617465282923 +:100B0000206661696C65643A200041757468656EA1 +:100B10007469636174696E6720554C2E2E2E0041F6 +:100B2000757468656E7469636174696E6720616766 +:100B300061696E207573696E67206B657920412E3F +:100B40002E2E00556E6B6E6F776E206572726F720F +:100B50000041204D494641524520504943432072AF +:100B60006573706F6E6465642077697468204E41A8 +:100B70004B2E00546865204352435F4120646F65EB +:100B800073206E6F74206D617463682E00496E76F9 +:100B9000616C696420617267756D656E742E0049C1 +:100BA0006E7465726E616C206572726F7220696E10 +:100BB0002074686520636F64652E2053686F756CC0 +:100BC00064206E6F742068617070656E2E00412025 +:100BD000627566666572206973206E6F7420626943 +:100BE0006720656E6F7567682E0054696D656F7557 +:100BF0007420696E20636F6D6D756E6963617469D1 +:100C00006F6E2E00436F6C6C6973696F6E20646544 +:100C10007465637465642E004572726F7220696E2C +:100C200020636F6D6D756E69636174696F6E2E0000 +:100C3000537563636573732E0000000008000201A2 +:100C4000000003040700000000000000004C617574 +:100C5000747370726563686572207769726420616D +:100C600075736765736368616C7465742100000057 +:100C70000000240027002A005741524E494E473AAF +:100C800020436F6D6D756E69636174696F6E206668 +:100C900061696C7572652C20697320746865204DDC +:100CA0004652433532322070726F7065726C792013 +:100CB000636F6E6E65637465643F00203D20287528 +:100CC0006E6B6E6F776E2900203D20636F756E74BA +:100CD000657266656974206368697000203D2076DE +:100CE000322E3000203D2076312E3000203D2076FF +:100CF000302E3000203D2028636C6F6E6529004641 +:100D000069726D776172652056657273696F6E3AAC +:100D1000203078004C617574737072656368657219 +:100D200020776972642065696E6765736368616CBA +:100D300074657421005265736574202D3E2045450D +:100D400050524F4D20776972642067656CC3B6734B +:100D5000636874003D3D3D206D6672633532322D0F +:100D60003E2052784761696E5F6D6178203D3D3D60 +:100D70002000496E666F726D6174696F6E20616EDE +:100D80006420636F6E747269627574696F6E20613E +:100D9000742068747470733A2F2F746F6E75696E57 +:100DA0006F2E64652E0A006372656174656420624B +:100DB000792054686F727374656E20566FC39F20DC +:100DC000616E64206C6963656E73656420756E6422 +:100DD000657220474E552F47504C2E00546F6E556C +:100DE000494E4F2056657273696F6E20322E310066 +:100DF00020207C5F7C207C5F5F5F7C5F7C5F7C5F12 +:100E00005F5F5F5F7C5F5F5F5F5F7C5F7C5F5F5F9B +:100E10007C5F5F5F5F5F7C0A0020207C207C207C01 +:100E2000202E207C2020207C20207C20207C2D2037 +:100E300020202D7C207C207C207C20207C20207C7D +:100E4000007C5F2020205F7C5F5F5F205F5F5F7CB6 +:100E500020207C20207C20202020207C2020207C22 +:100E6000207C20202020207C000A205F5F5F5F5FC5 +:100E70002020202020202020205F5F5F5F5F205FF8 +:100E80005F5F5F5F205F5F5F5F5F205F5F5F5F5FF0 +:100E9000003D3D3D2052657065617453696E676C1D +:100EA000654D6F6469666965722829003D3D3D2086 +:100EB0004B696E64657267617264656E4D6F6465DF +:100EC0002829003D3D3D20546F64646C65724D6F70 +:100ED00064652829003D3D3D204C6F636B656428A7 +:100EE00029003D3D3D20467265657A6544616E632B +:100EF000652829003D3D3D20536C65657054696D42 +:100F00006572282900556E6B6E6F776E207479704C +:100F1000650053414B20696E646963617465732099 +:100F2000554944206973206E6F7420636F6D706C37 +:100F30006574652E004D494641524520544E50334C +:100F4000585858004D49464152452044455346693A +:100F50007265004D494641524520506C7573004DF5 +:100F6000494641524520556C7472616C69676874DA +:100F7000206F7220556C7472616C696768742043CD +:100F8000004D494641524520344B42004D494641AF +:100F9000524520314B42004D4946415245204D6952 +:100FA0006E692C20333230206279746573005049A9 +:100FB000434320636F6D706C69616E742077697450 +:100FC000682049534F2F494543203138303932206A +:100FD000284E464329005049434320636F6D706C8F +:100FE00069616E7420776974682049534F2F4945B1 +:100FF000432031343434332D34006D6F64696669B5 +:1010000065722072656D6F766564003A00446174A4 +:1010100061206F6E204361726420004D4946415249 +:10102000455F526561645F342829206661696C659B +:10103000643A20004D49464152455F526561645F04 +:10104000332829206661696C65643A20004D494661 +:101050004152455F526561645F32282920666169AB +:101060006C65643A20004D49464152455F526561C6 +:10107000645F312829206661696C65643A20004DFF +:1010800049464152455F526561642829206661697D +:101090006C65643A2000202E2E2E00526561646932 +:1010A0006E6720646174612066726F6D20626C6F80 +:1010B000636B20005043445F41757468656E7469CA +:1010C000636174652829206661696C65643A200053 +:1010D00041757468656E7469636174696E67204DEB +:1010E000494641524520554C2E2E2E0041757468BC +:1010F000656E7469636174696E6720436C617373B4 +:101100006963207573696E67206B657920412E2EA7 +:101110002E005049434320747970653A20004361A2 +:101120007264205549443A00203D3D3D003D3D3D1F +:101130002000204F7074696F6E7329003D3D3D2083 +:10114000766F6963654D656E75282920280000005B +:1011500000002300260029000000000025002800D0 +:101160002B00040404040404040402020202020228 +:10117000030303030303010204081020408001025B +:101180000408102001020408102045254A2D1124CE +:101190001FBECFEFD8E0DEBFCDBF12E0A0E0B1E0D0 +:1011A000E8EDFFE502C005900D92A834B107D9F72C +:1011B00024E0A8E4B2E001C01D92AD3EB207E1F721 +:1011C00018E0C6ECD8E004C02197FE010E94AB2EC7 +:1011D000C53CD107C9F70E943C260C94DF2F0C9424 +:1011E0000000FC018781882399F04285538564853E +:1011F000758586859785A089B189481B590B6A0B2F +:101200007B0B81E0483E53406105710508F480E0A6 +:1012100008958CBD9DBD0895AF92BF92CF92DF928D +:10122000EF92FF920F931F93CF93DF936C017B019B +:101230008B01040F151FEB015E01AE18BF08C0172C +:10124000D10759F06991D601ED91FC910190F0819F +:10125000E02DC6010995892B79F7C501DF91CF9162 +:101260001F910F91FF90EF90DF90CF90BF90AF90C4 +:101270000895FC01538D448D252F30E0842F90E09C +:10128000821B930B541710F0CF9608950197089581 +:10129000FC01918D828D981761F0A28DAE0FBF2F4A +:1012A000B11D5D968C91928D9F5F9F73928F90E0A0 +:1012B00008958FEF9FEF0895FC01918D828D98170F +:1012C00031F0828DE80FF11D858D90E008958FEF4C +:1012D0009FEF0895FC01918D228D892F90E0805C15 +:1012E0009F4F821B91098F73992708958EED93E08C +:1012F0000E946A0921E0892B09F420E0822F0895D9 +:1013000080E090E0892B29F00E94760981110C94ED +:1013100000000895FC01A48DA80FB92FB11DA35A98 +:10132000BF4F2C91848D90E001968F739927848F05 +:10133000A689B7892C93A089B1898C918370806428 +:101340008C93938D848D981306C00288F389E02DC9 +:1013500080818F7D80830895EF92FF920F931F937A +:10136000CF93DF93EC0181E0888F9B8D8C8D981358 +:101370001AC0E889F989808185FF15C09FB7F89464 +:10138000EE89FF896083E889F989808183708064B0 +:1013900080839FBF81E090E0DF91CF911F910F91FB +:1013A000FF90EF900895F62E0B8D10E00F5F1F4F0A +:1013B0000F731127E02E8C8D8E110CC00FB607FC19 +:1013C000FACFE889F989808185FFF5CFCE010E94A7 +:1013D0008A09F1CFEB8DEC0FFD2FF11DE35AFF4F82 +:1013E000F0829FB7F8940B8FEA89FB898081806235 +:1013F000CFCF0F931F93CF93DF938C01D0E0C0E04A +:10140000F801EC0FFD1F6491662341F08EED93E02F +:101410000E94AC09892B11F02196F2CFCE01DF9109 +:10142000CF911F910F910895CF93DF93EC01888D99 +:101430008823B9F0AA89BB89E889F9898C9185FD4F +:1014400003C0808186FD0DC00FB607FCF7CF8C91DD +:1014500085FFF2CF808185FFEDCFCE010E948A0902 +:10146000E9CFDF91CF910895833081F028F4813066 +:1014700099F08230A9F008958730A9F08830C9F03A +:101480008430B1F4809180008F7D03C08091800012 +:101490008F7780938000089584B58F7784BD0895F9 +:1014A00084B58F7DFBCF8091B0008F778093B000A3 +:1014B00008958091B0008F7DF9CFCF93DF93282FCF +:1014C00030E0F901E75CF34F8491F901EA58FE4EF0 +:1014D000D491F901EE59FE4EC491CC23A1F08111B3 +:1014E0000E94340AEC2FF0E0EE0FFF1FE25BFE4E8D +:1014F000A591B491EC91ED2381E090E009F480E0B6 +:10150000DF91CF91089580E090E0FACF1F93CF93C1 +:10151000DF93282F30E0F901E75CF34F8491F90164 +:10152000EA58FE4ED491F901EE59FE4EC491CC23F7 +:10153000A9F0162F81110E94340AEC2FF0E0EE0F73 +:10154000FF1FE85AFE4EA591B4918FB7F894EC9125 +:10155000111108C0D095DE23DC938FBFDF91CF91AE +:101560001F910895DE2BF8CFCF93DF9390E0FC011D +:10157000EA58FE4E24918E599E4EFC018491882398 +:10158000C9F090E0880F991FFC01E259F34FA59133 +:10159000B491FC01E85AFE4EC591D49161110DC081 +:1015A0009FB7F8948C91209582238C93888128236F +:1015B00028839FBFDF91CF910895623051F49FB788 +:1015C000F8943C91822F809583238C93E8812E2B75 +:1015D000EFCF8FB7F894EC912E2B2C938FBFEACFDF +:1015E0003FB7F8948091970290919802A091990248 +:1015F000B0919A0226B5A89B05C02F3F19F001961D +:10160000A11DB11D3FBFBA2FA92F982F8827BC015C +:10161000CD01620F711D811D911D42E0660F771F84 +:10162000881F991F4A95D1F708958F929F92AF9284 +:10163000BF92CF92DF92EF92FF924B015C010E942A +:10164000F00A6B017C010E94F00A6C197D098E0979 +:101650009F09683E734081059105A8F321E0821A35 +:101660009108A108B10888EEC80E83E0D81EE11CDD +:10167000F11C81149104A104B10429F7FF90EF90AB +:10168000DF90CF90BF90AF909F908F9008952FB72D +:10169000F8946091930270919402809195029091D8 +:1016A00096022FBF08950F931F930E94470B6093DC +:1016B000E6037093E7038093E8039093E9038EEDCC +:1016C00093E00E945C0997FF1DC00E94470B0091A8 +:1016D000E6031091E7032091E8033091E903601BD2 +:1016E000710B820B930B0091E2031091E3032091A5 +:1016F000E4033091E5036017710782079307F8F25E +:101700008FEF9FEF1F910F9108958F929F92AF924D +:10171000BF92CF92DF92EF92FF920F931F93CF93DE +:10172000DF93EC016A017B0110E000E00E94470BAF +:10173000688779878A879B87E881F9810284F385A6 +:10174000E02DCE01099597FF21C00E94470B8884A8 +:101750009984AA84BB84681979098A099B098C80B9 +:101760009D80AE80BF80681579058A059B0520F3B2 +:10177000C801DF91CF911F910F91FF90EF90DF9003 +:10178000CF90BF90AF909F908F900895F701819375 +:101790007F010F5F1F4FC016D10641F6E9CF2091A0 +:1017A0009D0230919E022817390771F490919B0297 +:1017B00080919C02981741F0E0919B02F0E0EE5A74 +:1017C000FD4F808190E008958FEF9FEF0895089579 +:1017D000EF92FF920F931F93CF93DF93DC015C9600 +:1017E000ED90FC905D97E114F10479F481E090E0D4 +:1017F00013969C938E93129790E080E0DF91CF91A7 +:101800001F910F91FF90EF9008955196ED91FC91EB +:10181000529750968C915097982F90950FB75E964F +:101820002C915E97122F127021FD6095F894208103 +:10183000112319F1282B2083E7012197F1F728E0E4 +:10184000462F50E0308160FF1AC0382B3083E7010B +:101850002197F1F7BA0175956795215089F7112302 +:1018600081F08081892380830FBF5C968D919C914C +:101870000197F1F781E090E0C1CF2923DCCF392334 +:10188000E5CF9081892BEFCF20919D0230919E0270 +:101890002817390771F480919C0220919B0290E0F7 +:1018A000805C9F4F821B910960E470E00E94832E50 +:1018B000089590E080E0089520919D0230919E026D +:1018C00028173907B9F490919B0280919C029817D0 +:1018D00089F0E0919B02F0E0EE5AFD4F808120916B +:1018E0009B0230E02F5F3F4F2F73332720939B02E3 +:1018F00090E008958FEF9FEF089590E080E00895C5 +:10190000BC016E5F7F4FDC01ED91FC910190F08195 +:10191000E02D40E0099591E0811190E0892F089534 +:101920008430F1F050F4813091F030F1823091F058 +:10193000833099F083E49BE008958630B9F098F005 +:101940008730B9F08F3FB1F781E59BE0089588E1DA +:101950009CE0089584E09CE008958AEE9BE0089561 +:101960008EEC9BE008958FE99BE008958DE89BE065 +:10197000089583E79BE0089580E39CE0089508952F +:101980008EBD00000DB407FEFDCF8EB50895DF9229 +:10199000EF92FF920F931F93CF93DF937C01062F5B +:1019A000D42E152F83E590E00E94090960E0F7012D +:1019B00086850E94860A82E10E94C00CCD2DD12F1F +:1019C0000C0F1D2F111DC017D10721F089910E9406 +:1019D000C00CF9CF61E0F7018685DF91CF911F91AF +:1019E0000F91FF90EF90DF900C94860A1F93CF9396 +:1019F000DF93EC01162F83E590E00E94090960E077 +:101A00008E850E94860A812F80680E94C00C80E02B +:101A10000E94C00C182F61E08E850E94860A812FDB +:101A2000DF91CF911F9108950F931F93CF93DF9371 +:101A3000EC01062F142F83E590E00E94090960E075 +:101A40008E850E94860A802F0E94C00C812F0E94E2 +:101A5000C00C61E08E85DF91CF911F910F910C94A6 +:101A6000860ACF92DF92EF92FF920F931F93CF934C +:101A7000DF93EC016B01142F790140E062E00E94DA +:101A8000140D44E06AE0CE010E94140D40E864E1C8 +:101A9000CE010E94140DA601612FCE010E94C70C39 +:101AA00043E062E0CE010E94140D08E813E16AE011 +:101AB000CE010E94F60C82FF1BC040E062E0CE0126 +:101AC0000E94140D64E4CE010E94F60CF70180839D +:101AD00062E4CE010E94F60CF701818380E0DF9181 +:101AE000CF911F910F91FF90EF90DF90CF900895CD +:101AF00001501109E1F683E0F2CF3F924F925F92DD +:101B00006F927F928F929F92AF92BF92CF92DF920D +:101B1000EF92FF920F931F93CF93DF9300D0CDB737 +:101B2000DEB73C01162F942E290180E0A114B104E8 +:101B300011F0F5018081382C329490EF3922380E63 +:101B400040E062E0C3010E94140D4FE768E0C3016A +:101B50000E94140D40E864E1C3010E94140DA2012B +:101B6000602FC3010E94C70C432D6AE1C3010E948C +:101B7000140D412F62E0C3010E94140D1C3051F47A +:101B80006AE1C3010E94F60C482F40686AE1C30174 +:101B90000E94140D00ED17E068E0C3010E94F60CEE +:101BA000982F992109F0B3C080FD03C0015011099D +:101BB00099F783E092C0E114F10409F46BC0C114F9 +:101BC000D10409F467C064E1C3010E94F60C982EA9 +:101BD000F6018081891508F494C090829920C9F19A +:101BE00083E590E00E94090960E0F30186850E9488 +:101BF000860A9A9482E90E94C00C882099F00FEF1F +:101C000010E001C0000F8A94EAF782E90E94C00C3C +:101C1000902F9095F701208192238023982B908319 +:101C2000882483948701080D111D891440F482E9EA +:101C30000E94C00CF80181938F018394F6CF80E05D +:101C40000E94C00CF801808361E0F30186850E9448 +:101C5000860A68E1C3010E94F60C8770A114B104E2 +:101C600011F0F501808353FC4EC0E114F10409F436 +:101C70004CC0C114D10409F448C09E89992309F4C9 +:101C800044C0F6014081413039F4843009F049C044 +:101C90008FEF23C080E0E7CF423008F442C08111CB +:101CA00040C042509E012F5F3F4FB701C3010E94C9 +:101CB000310D811112C0F6019081E90EF11CF7017E +:101CC00032972081998129132CC0F1E0EF1AF10895 +:101CD000F70120819A81291324C00F900F90DF9182 +:101CE000CF911F910F91FF90EF90DF90CF90BF9019 +:101CF000AF909F908F907F906F905F904F903F90AC +:101D0000089584E0EACF82E0E8CF80E0E6CF6CE09F +:101D1000C3010E94F60C582E837109F44CCF81E068 +:101D2000DCCF87E0DACF6F927F928F92AF92BF9233 +:101D3000CF92DF92EF92FF920F93CF93DF93CDB7C5 +:101D4000DEB764970FB6F894DEBF0FBECDBF3C017F +:101D50008BE189838091D8038A838091D9038B8317 +:101D60008091DA038C838091DB038D839E012A5F4F +:101D70003F4F45E0BE016F5F7F4F81EB94E00E94D3 +:101D8000310D81111BC01C8A85E08B8B1F92812C29 +:101D9000CE0144965C01FE0173966F0143977C016E +:101DA00007E09C0140E36CE081EB94E00E947D0D34 +:101DB0009981F30190839A8191830F9064960FB675 +:101DC000F894DEBF0FBECDBFDF91CF910F91FF9092 +:101DD000EF90DF90CF90BF90AF908F907F906F90FB +:101DE00008958F92AF92BF92CF92DF92EF92FF92BF +:101DF0000F93CF93DF93CDB7DEB72C970FB6F89440 +:101E0000DEBF0FBECDBF90E699838A83E8EDF3E095 +:101E1000DE01139681918D9383E0EE3DF807D1F7B3 +:101E2000E091B304E150FF0BEF54FB4FDE01199634 +:101E3000CE010D9621912D93A817B907D9F71F92BE +:101E4000812CB12CA12CD12CC12CF12CE12C0CE03B +:101E50009E012F5F3F4F40E16EE081EB94E00E94D6 +:101E60007D0D0F902C960FB6F894DEBF0FBECDBF40 +:101E7000DF91CF910F91FF90EF90DF90CF90BF90C7 +:101E8000AF908F9008956F927F928F92AF92BF9292 +:101E9000CF92DF92EF92FF920F931F93CF93DF9336 +:101EA00000D000D0CDB7DEB73C0180E589831A822F +:101EB0009E012D5F3F4F42E0BE016F5F7F4FC30128 +:101EC0000E94310D182F811118C01F92812CB12C46 +:101ED000A12CD12CC12CF12CE12C04E09E012F5F10 +:101EE0003F4F40E36CE0C3010E947D0D0F908330B3 +:101EF00021F0182F811101C011E0812F0F900F9058 +:101F00000F900F90DF91CF911F910F91FF90EF9065 +:101F1000DF90CF90BF90AF908F907F906F9008959B +:101F20008F92AF92BF92CF92DF92EF92FF920F9378 +:101F3000CF93DF93FA019081923148F16A01EB016E +:101F400090E3988389839B012E5F3F4F42E081EBB2 +:101F500094E00E94310D81110FC081E08F93812C9C +:101F6000B12CA12C7E0104E09E0140E36CE081EBEA +:101F700094E00E947D0D0F90DF91CF910F91FF9023 +:101F8000EF90DF90CF90BF90AF908F90089584E056 +:101F9000F3CF0F931F93CF93DF938C01D62FC42FD2 +:101FA0000E94F60CC0954C2F48236D2FC801DF917D +:101FB000CF911F910F910C94140D48E060E181EBDB +:101FC00094E00C94C90F6F927F928F92AF92BF9260 +:101FD000CF92DF92EF92FF920F93CF93DF9300D0D7 +:101FE00000D01F92CDB7DEB73C0182E08D8340E088 +:101FF00064E2C3010E94140D40E066E2C3010E9446 +:10200000140D46E268E4C3010E94140D86E28B833E +:102010008D818230C8F140E86CE1C3010E94C90F94 +:1020200087E08C831F92812CCE0104965C0101967F +:102030006C0104977C0101E09E012D5F3F4F40E35E +:102040006CE0C3010E947D0D982F0F90811119C083 +:102050008D818230C9F48C81811116C081E00F908E +:102060000F900F900F900F90DF91CF910F91FF90F5 +:10207000EF90DF90CF90BF90AF908F907F906F9058 +:10208000089581E0923059F380E0E9CF2F923F929A +:102090004F925F926F927F928F929F92AF92BF9278 +:1020A000CF92DF92EF92FF920F931F93CF93DF9324 +:1020B000CDB7DEB72E970FB6F894DEBF0FBECDBFFB +:1020C00006E0413508F046C14E873B012C0140E84F +:1020D0006CE10E94C90F83E989832E85222329F0B0 +:1020E00081E0F3019081953008F480E09924939485 +:1020F0001C869C85990F990F990F1E85191B17FD3A +:1021000010E032E0882319F098E89B8333E021E067 +:10211000912F977009F420E0912F959595959595BD +:10212000290FD1F094E0811193E0291708F4922F40 +:102130002C85E22FF0E03196E60DF71D232F41911B +:10214000A1E0B0E0AC0FBD1FA20FB11D4C932F5FFB +:10215000422F431B491798F38111185F10320CF47A +:1021600084C080E78A838B819C8189279D81892710 +:102170009E8189278F839E01285F3F4F47E0BE01E4 +:102180006F5F7F4FC2010E94310D082F8111E2C0A5 +:102190001A8693E09B871D87FE0137961F0109E091 +:1021A0008A84482D4295407F480D6AE1C2010E9411 +:1021B000140D1F92CE010A965C01FE013B966F0141 +:1021C00071019E012F5F3F4F40E36CE0C2010E940E +:1021D0007D0D082F0F90823009F065C06CE1C201BF +:1021E0000E94F60C85FDB6C08F7109F480E2282F9D +:1021F00030E0412F110F550B421753070CF09EC0D2 +:10220000182FE22FE595E595E595EF5F922F9770F2 +:1022100081E009F480E0E80F81E090E08C0F9D1FE1 +:102220008E0F911DFC01215031092770332781E069 +:1022300090E002C0880F991F2A95E2F79C018081E7 +:10224000822B80838BCF85E98983FE85FF2331F044 +:1022500081E0F3019081983008F04BCF80E049CFC6 +:1022600087E98983F6E0FC87F9CF912F97709A87E9 +:10227000812F8595859585958E5F282F2295207FC6 +:10228000290F2A8301E0911101C000E0080F2224E8 +:102290002394312C2C0E3D1E280E311CF9E0F81B26 +:1022A000FB871D877DCF811155C010E29D8590323F +:1022B0000CF457CF8B81883809F042C083E093E05B +:1022C0002C85E22FF0E03196E60DF71D980FA1E086 +:1022D000B0E0AC0FBD1FA80FB11D2C9121938F5FF3 +:1022E0008913F5CF8B858C87833009F04DC08A85A3 +:1022F00081114AC09E012D5F3F4F41E0B101C201F3 +:102300000E94310D082F811125C09B81F10181812F +:1023100098133CC09C818281981338C0808182FFD1 +:1023200012C09394F2E09F1609F48DCF23E0921629 +:1023300009F496CF81E0981609F4CDCE05E00AC0E5 +:1023400082E094E0BDCFF3018387892D880F980E3A +:1023500093949082802F2E960FB6F894DEBF0FBE16 +:10236000CDBFDF91CF911F910F91FF90EF90DF9044 +:10237000CF90BF90AF909F908F907F906F905F9025 +:102380004F903F902F90089501E0E4CF07E0E2CF17 +:10239000FC012781211102C08185089580E0089504 +:1023A000CF92DF92EF92FF920F931F93CF93DF9321 +:1023B000EC010E94470B6B017C0188810E945D0A41 +:1023C0009C018E8191E0811104C0232B21F490E0C7 +:1023D00002C0232BE1F74E855F85688979899701D3 +:1023E0008601041B150B260B370B49815A816B8123 +:1023F0007C81041715072607370778F41986CA86E3 +:10240000DB86EC86FD868F81DF91CF911F910F9146 +:10241000FF90EF90DF90CF9008958F8188879F8302 +:10242000292F28272987981751F3CE86DF86E88A37 +:10243000F98AE5CF8FE994E00E94D0118DE894E00D +:102440000E94D0118BE794E00C94D011EF92FF9290 +:102450000F931F93CF93DF938C01C0E0FF24F3947D +:1024600082E0E82ED3E0C43050F50E941A128FE9C2 +:1024700094E00E94F108811122C08FE994E00E944B +:10248000C811882329F0F801EC0FF11DF082CF5F0D +:102490008DE894E00E94C811882329F0F801EC0F20 +:1024A000F11DE082CF5F8BE794E00E94C811882382 +:1024B000D1F2F801EC0FF11DD083CF5FD4CF81E0D2 +:1024C000DF91CF911F910F91FF90EF90089584E0DD +:1024D0000E945D0A21E0892B09F020E0822F0895F7 +:1024E00083E0089580E0089580E008950895FC0158 +:1024F00001900020E9F73197AF01481B590BBC014F +:102500008EED93E00C940C0989E092E00C94771224 +:10251000CF93DF930E94F909EC010E9484128C0F83 +:102520009D1FDF91CF9108958AE696E00E94881260 +:10253000109248021092490210924A0210924B02E5 +:10254000089583E195E00E94881286E0089584EB67 +:1025500094E00E94881285E008950F931F93CF9313 +:10256000DF93EC018B0187E894E00E94881289E0F8 +:10257000F801DE01129601900D928A95E1F781E053 +:102580008B870E946712811107C0E881F98104805E +:10259000F581E02DCE01099581E0DF91CF911F916A +:1025A0000F91089580E594E00E94881281E00895DB +:1025B0008DE194E00E94881281E0089587ED93E018 +:1025C0000E94881284E0089589EA93E00E948812AC +:1025D00081E008958DE793E00E94881281E00895DC +:1025E0008BE493E00E94881281E008958DE193E0EE +:1025F0000E94881281E0089584EF92E00E94881280 +:1026000081E0089581ED92E00E94881281E00895B2 +:1026100088EA92E00E94881281E0089581E892E0C1 +:102620000E94881281E0089584E592E00E94881259 +:1026300081E008958BE292E00E94881281E0089583 +:1026400087E092E00E94881281E008958BEE91E08D +:102650000E94881282E0089587E891E00E94881223 +:1026600081E008958F929F92AF92BF920F931F9334 +:10267000CF93DF93CDB7DEB7A1970FB6F894DEBF47 +:102680000FBECDBF19A2423008F44AE08E010F5DA3 +:102690001F4F842E912CB12CA12CA50194010E94D6 +:1026A000522EE62FB901CA01EA30F4F4E05DD801F8 +:1026B000EE938D01232B242B252B79F790E080E0DE +:1026C000109719F0CD010E947712A1960FB6F894D9 +:1026D000DEBF0FBECDBFDF91CF911F910F91BF9095 +:1026E000AF909F908F900895E95CE1CF462F682FBF +:1026F00070E090E080E00C943213CF93DF936AE0B7 +:1027000070E00E947613EC010E9484128C0F9D1FD2 +:10271000DF91CF910895CF93DF93BC0190E080E0EB +:102720004AE00E943213EC010E9484128C0F9D1F1C +:10273000DF91CF910895CF92DF92EF92FF92CF93E6 +:10274000DF9397FF1BC06B017C016DE28EED93E080 +:102750000E94AC09EC0166277727CB016C197D0933 +:102760008E099F094AE00E9432138C0F9D1FDF9152 +:10277000CF91FF90EF90DF90CF9008954AE0DF91E6 +:10278000CF91FF90EF90DF90CF900C943213CF92C7 +:10279000DF92EF92FF9284E596E00E94881280918A +:1027A000B5029091B602A091B702B091B802892B00 +:1027B0008A2B8B2B69F10E94470B6B017C012091C6 +:1027C000B5023091B6024091B7025091B802A0E62E +:1027D000BAEE0E943F2EC60ED71EE81EF91EC0920A +:1027E0004802D0924902E0924A02F0924B02609174 +:1027F00048027091490280914A0290914B024AE04E +:102800000E943213FF90EF90DF90CF900C948412CF +:10281000109248021092490210924A0210924B0202 +:10282000E6CFEF92FF920F931F93CF93DF93EC01CC +:102830008C01060F111DC017D10799F07E01888108 +:10284000803160F08CE192E00E947712219660E185 +:1028500070E0F70180810E947613EDCF8CE092E06A +:10286000F3CFDF91CF911F910F91FF90EF900895DB +:102870000F931F93CF93C82F8B0181FF04C08FE06C +:1028800092E00E947712C0FF04C089E192E00E94AA +:102890007712C3FF04C08EE192E00E947712C80154 +:1028A0000E947712CF911F910F910C948412CF93B5 +:1028B000DF93EC010E94841285E292E00E9477127D +:1028C000CE01DF91CF910C948B138F92AF92BF9278 +:1028D000CF92DF92EF92FF920F93CF93DF93CDB71A +:1028E000DEB764970FB6F894DEBF0FBECDBF062FDC +:1028F000E62EF12CA701BC01CE0101960E94D62F35 +:1029000021E030E02C0F3D1F2E0D3F1D402FBE015A +:102910006F5F7F4F81EB94E00E94310D811123C0E6 +:1029200082E18C8B1B8A0E5F1F92812CCE01439615 +:102930005C0101966C0143977C019C0140E36CE0D3 +:1029400081EB94E00E947D0D0F9081110CC08C8969 +:102950008130D1F48B898430B9F481E099819A3047 +:1029600009F480E0819564960FB6F894DEBF0FBE3F +:10297000CDBFDF91CF910F91FF90EF90DF90CF907F +:10298000BF90AF908F90089581E0EDCF0F931F938C +:10299000CF93DF9300D0CDB7DEB78B0190EA998358 +:1029A0008A8362E0CE0101960E946514811104C001 +:1029B00060E1C8010E9465140F900F90DF91CF91E4 +:1029C0001F910F9108951F93CF93DF93EC01162F62 +:1029D0000E940A2E181739F0612FCE01DF91CF9196 +:1029E0001F910C94122EDF91CF911F910895CF93D8 +:1029F000DF93EC010E948B138091D3039091D40359 +:102A0000009751F480915002909151028C179D07CC +:102A100069F4DF91CF910895DC01ED91FC91048080 +:102A2000F581E02D0995882369F3F3CFD093510206 +:102A3000C09350028091D203882359F384E496E036 +:102A40000E948812E091D003F091D10381818130FE +:102A500011F0873031F48DE096E00E9488120E94D8 +:102A6000C713E091D003F091D1038181823011F03E +:102A7000883011F56091CE037091CF0380914E02A2 +:102A800090914F026817790709F498C06F5F7F4FE4 +:102A90007093CF036093CE0380810E945F1783EE13 +:102AA00095E00E94F9096091CE037091CF0390E008 +:102AB00080E04AE00E943213E091D003F091D1030C +:102AC0008181833011F0893099F5C091CE03D09186 +:102AD000CF0380914E0290914F02019620914C02BB +:102AE00030914D02821B930B8C179D0709F469C02E +:102AF00085EC95E00E94F9092196D093CF03C0930D +:102B0000CE03E091CE03F091CF03E253FD4F8081DD +:102B10000E947D13E091CE03F091CF03E253FD4F6D +:102B2000A091D003B091D10360818C910E945F1776 +:102B3000E091D003F091D1038181843031F48EE7AC +:102B400095E00E9488120E94C713E091D003F09193 +:102B5000D1038181853051F5C091CE03D091CF034F +:102B600080914E0290914F02C817D907A9F1219682 +:102B7000D093CF03C093CE0388E395E00E94F90978 +:102B8000CE010E948B13E091D003F091D1036091AC +:102B9000CE0380810E945F17E091D003F091D103B2 +:102BA00080816091CE0390E00E94E31464EF71E0B5 +:102BB00080E090E0DF91CF910C94150B0E94C71339 +:102BC0007BCF81EA95E00E94881281E090E09093AB +:102BD000CF038093CE0395CF808161E090E00E9487 +:102BE000E3140E94C713E2CFBF92CF92DF92EF921D +:102BF000FF920F931F93CF93DF93CDB7DEB72A9742 +:102C00000FB6F894DEBF0FBECDBFD82E8AE0B82E27 +:102C10008E010F5F1F4FEE24E394FF24FA94CC241F +:102C2000C394D801EB2D1D92EA95E9F741E050E0FD +:102C3000B8018091C1049091C2040E94850B81303B +:102C400009F068C089818E3789F749E050E0BE01FC +:102C50006E5F7F4F8091C1049091C2040E94850BEA +:102C60008F5F8A3008F468C08A818F3F09F067C09F +:102C70008B81863009F063C08A858F3E09F05FC082 +:102C80009C81288539853227232732276D81492F5A +:102C900050E04A5F5F4F640F752F711D4E81640FC6 +:102CA000711D4F81460F572F511DB701641B750BC6 +:102CB0002617370709F046C02E813F813227232788 +:102CC0003227DD2009F441C0D91256C0C9012A9625 +:102CD0000FB6F894DEBF0FBECDBFDF91CF911F912D +:102CE0000F91FF90EF90DF90CF90BF900895C901B2 +:102CF0000E94F714D11095CF3CC0C092C90460E384 +:102D000072E0C9010E943814F5CFC092C90467E38C +:102D100072E0F7CF81E890E00E9457148091C104DF +:102D20009091C204DC01ED91FC910084F185E02DCD +:102D30000995892BF9F61DC082E890E0EDCF83E874 +:102D400090E0EACF84E890E0E7CF9F3358F49C33DB +:102D500070F69A33D1F29B3361F4C092C9046EE3EA +:102D600072E0CFCF9F3349F2903419F4C9010E9429 +:102D7000571430E020E0AACF9F3348F49C3308F08A +:102D8000B6CF9A3311F29B3309F04BCFE6CF9F3386 +:102D900009F4B3CF903409F044CFE8CF8091C10457 +:102DA0009091C204DC01ED91FC910084F185E02D4D +:102DB00009950A9724F080E00E94F415EFCF08955A +:102DC0000F931F93CF93DF93CDB7DEB72A970FB63C +:102DD000F894DEBF0FBECDBF96E0FE013596DF0151 +:102DE000292F1D922A95E9F74EE749834FEF4A8331 +:102DF0009B839FEE9A878C83272F30E07E836F839F +:102E000090E08B5F9E4F4D81840F911D280F391FDD +:102E1000620F732F711D71956195710978876987AC +:102E20000E94470B0091C3041091C4042091C50473 +:102E30003091C604AB01BC01401B510B620B730BFC +:102E40008091C7049091C804B0E0A0E048175907EA +:102E50006A077B0748F40E94CE1661E070E080E0CC +:102E600090E00E94150BDCCF82E390E09093C804C1 +:102E70008093C7048091C1049091C204DC01ED915C +:102E8000FC910280F381E02D4AE050E0BE016F5FCB +:102E90007F4F09950E94470B6093C3047093C4044D +:102EA0008093C5049093C6042A960FB6F894DEBFAB +:102EB0000FBECDBFDF91CF911F910F910895782F55 +:102EC0008FE00C94E016CF93DF938091D303909121 +:102ED000D403009749F582EA97E00E948812E091B6 +:102EE000D003F091D1038181823051F589E797E0D9 +:102EF0000E9488128091CE039091CF0320914C02C2 +:102F000030914D028217930729F001979093CF03D8 +:102F10008093CE03E091D003F091D1036091CE0372 +:102F200080810E945F170EC0DC01ED91FC9102844C +:102F3000F385E02D0995882371F2DF91CF910895F3 +:102F40008830A1F2E091D003F091D10381818330E8 +:102F500011F0893041F5C091CE03D091CF03C1303B +:102F6000D10509F46CC089E497E00E94F909219722 +:102F7000D093CF03C093CE03E091CE03F091CF0363 +:102F8000E253FD4F80810E947D13E091CE03F091CA +:102F9000CF03E253FD4FA091D003B091D1036081E4 +:102FA0008C910E945F17E091D003F091D103818151 +:102FB000843069F485EF96E00E948812E091D00396 +:102FC000F091D1036091CE0380810E945F17E09160 +:102FD000D003F091D1038181853019F58EEA96E016 +:102FE0000E9488128091CE039091CF038130910589 +:102FF00029F001979093CF038093CE03E091D00303 +:10300000F091D1036091CE0380810E945F17E0911F +:10301000D003F091D10380816091CE0390E00E94B3 +:10302000E31468EE73E080E090E00E94150B68EE18 +:1030300073E080E090E0DF91CF910C94150B83E278 +:1030400097E00E94F90980914E0290914F0290936F +:10305000CF038093CE0390CF85ED94E00E94881239 +:1030600062E370E080E090E00E94150B0E9467121E +:10307000811118C0E091D003F091D103918160914A +:10308000CE037091CF038081933011F0993021F4F9 +:1030900062537D4FFB0160810E945F1710925102C5 +:1030A0001092500281E00895BC0183E10C94E01677 +:1030B00070E060E08EE00C94E01670E060E08DE07F +:1030C0000C94E016BC0182E10C94E0168091D303CD +:1030D0009091D4030097C1F48DE996E00E94881284 +:1030E0009091B1028091A002981750F470E060E0D6 +:1030F00085E00E94E0168091A00281508093A0029A +:103100008091A0020C947D13DC01ED91FC9106846A +:10311000F785E02D09958823F9F208958091D3036E +:103120009091D4030097C1F48EE896E00E94881233 +:103130009091B0028091A002891750F470E060E095 +:1031400084E00E94E0168091A0028F5F8093A0022D +:103150008091A0020C947D13DC01ED91FC9104841C +:10316000F585E02D09958823F9F20895CF92DF9235 +:10317000EF92FF92C0904802D0904902E0904A023C +:10318000F0904B02C114D104E104F104C1F10E949A +:10319000470BC616D706E806F90688F58FE796E0CE +:1031A0000E94881261E087E00E94860A64EF71E065 +:1031B00080E090E00E94150B43E068E281EB94E030 +:1031C0000E94C90F62E081EB94E00E94F60C482F48 +:1031D000406162E081EB94E00E94140D70E060E0D9 +:1031E0008AE00E94E01683B7817F846083BFF894F1 +:1031F00083B7816083BF889583B78E7F83BFFF903D +:10320000EF90DF90CF900895CF92DF92EF92FF92F0 +:103210000E94470B6B017C0128EEC20E23E0D21EF8 +:10322000E11CF11C0E94CE160E946712811107C09A +:103230000E94470B6C157D058E059F0598F368EE7F +:1032400073E080E090E00E94150B0E94CE160E9471 +:1032500067128111FACFFF90EF90DF90CF90089521 +:103260004F925F926F927F929F92AF92BF92CF9256 +:10327000DF92EF92FF920F931F93CF93DF936C0136 +:10328000CB015A01D22F009711F00E9462188CE3F3 +:1032900091E10E94F909B6010D2C000C880B990BE5 +:1032A0000E949B1382E391E10E948812CE2D992403 +:1032B00093948EED93E00E946A09181619060CF09B +:1032C00069C00E94530BFC0197FD60C08D329105CF +:1032D00021F0C0970A9708F051C0412C512C3201BF +:1032E000F12CE130F105D9F0ED32F10509F44BC0D4 +:1032F000CF01C0970A9798F4AAE0B0E0A301920129 +:103300000E943F2E2F01FF0F66087708460E571EBA +:10331000681E791E80E3481A5108610871088EED15 +:1033200093E00E9448090E94530BFC01C0970A9742 +:10333000C0F2E130F105A9F2FF2041F070946094F1 +:1033400050944094411C511C611C711CC201892B7A +:1033500009F1C414D504F4F0C42D8C2FDF91CF9162 +:103360001F910F91FF90EF90DF90CF90BF90AF90A3 +:103370009F907F906F905F904F9008958EED93E0B7 +:103380000E9448099ECFFF24F394C9CF412C512CB1 +:103390003201DCCF0E941A120E94CE168FE994E00F +:1033A0000E94F108882359F082E293E00E9462189B +:1033B00081E08093D7030E94B618CE2DCECF8FE93F +:1033C00094E00E94C8118823B1F0CC2371F08DE203 +:1033D00091E10E94F9096AE070E08C2F0E94761357 +:1033E00088E291E10E948812B8CF68EE73E080E035 +:1033F00090E00E94150B8DE894E00E94F10888236C +:1034000071F16C2E712C8AE0680E711CC614D70401 +:103410000CF43601C62D862D0E947D13C501860D44 +:10342000911D0E9462180E9404199092D6038BE7A6 +:1034300094E00E94F108882309F444C0CB3008F4DA +:10344000CBE0CA508C2F0E947D13C5018C0F911DBB +:103450000E9462180E9404199092D5032ACF8DE829 +:1034600094E00E94C811882311F38091D603811142 +:1034700026C06C2E712C8FEF681A780AC614D704F8 +:103480000CF43601C62D862D0E947D13C501860DD4 +:10349000911D0E946218DD2351F20E94041961E01F +:1034A000862D0115110511F0662D802F0E945F17E2 +:1034B00068EE73E080E090E00E94150BB8CF1092A8 +:1034C000D603B5CF8BE794E00E94C811882309F496 +:1034D000F0CE8091D503811121C0C23008F4C2E042 +:1034E000C1508C2F0E947D13C5018C0F911D0E942D +:1034F0006218DD2309F4DDCE0E94041961E08C2FEF +:103500000115110511F06C2F802F0E945F1768EED6 +:1035100073E080E090E00E94150BCBCE1092D503B3 +:10352000C8CECF93DF93EC018091C1049091C20487 +:10353000DC01ED91FC910084F185E02D09951816D0 +:10354000190624F480E00E94F415EECFBE018EE44B +:103550000E94E0168EE4DF91CF910C94F415EF9267 +:10356000FF920F931F93CF93DF93EC01F12CE12C8B +:1035700010E000E021E050E040E06DE271E083E621 +:1035800090E00E9430198883811108C080E0DF91AB +:10359000CF911F910F91FF90EF900895F12CE12CA6 +:1035A00010E000E020E046E351E066E371E089E0EE +:1035B00090E00E9430198983882341F3843069F4B4 +:1035C000088110E0C8010E94911A21E050E040E01B +:1035D00060E471E00E9430198A838981863019F491 +:1035E00018828FEF8983898187508330F0F40881B6 +:1035F00010E0C8010E94911AF12CE12C21E050E06A +:1036000040E061E471E00E943019E82E8A8308816D +:1036100010E0C8010E94911AF12C21E050E040E036 +:1036200062E471E00E9430198B8381E0B0CFFF9299 +:103630000F931F93CF93DF9388E690E00E94881248 +:103640000BEA12E0C4E6D0E0F801F1908F01CE0160 +:103650000E940A2EF81621F06F2DCE010E94122E24 +:103660002196C838D10581F7DF91CF911F910F9135 +:10367000FF90089583E890E00E948812EBEAF2E060 +:1036800087E493EBA7E3B3E180839183A283B383C1 +:1036900082E0848389E1858385E086838FE0878368 +:1036A00081E08087118612861386148615868687A8 +:1036B0001786138A178A138E178E80A381A382A37D +:1036C00083A30C94171B0F931F93CF93DF938AE46C +:1036D00091E00E9488120BEA12E0C4E6D0E0CE012D +:1036E0000E940A2EF80181938F012196C838D105D6 +:1036F000B1F78091AB029091AC02A091AD02B09174 +:10370000AE028734934BA743B34111F00E943A1B9A +:10371000C091AF02C130B9F48EE990E00E948812E6 +:1037200087E990E00E94881282E08093AF021092B5 +:10373000CA02C093CB02C093CC02C093CD02C09307 +:10374000CE020E94171B80E491E00E94F90980914B +:10375000AF020E947D138FE291E00E94F9098091EF +:10376000B0020E947D138EE191E00E94F9098091E0 +:10377000B1020E947D138DE091E00E94F9098091D1 +:10378000B2020E947D1388E091E00E94F9098091C5 +:10379000B3020E947D138FEF90E00E94F9096091BF +:1037A000B40270E090E080E00E949B130E948412BB +:1037B00081EF90E00E94F9096091B5027091B60224 +:1037C0008091B7029091B8020E949B130E948412CC +:1037D00087ED90E00E94F9096091B90270E090E0F5 +:1037E00080E00E949B130E94841283EC90E00E9470 +:1037F000F9098091CA020E947D1382EB90E00E9439 +:10380000F9096AE070E08091CB020E9476136AE0C9 +:1038100070E08091CC020E9476136AE070E08091A3 +:10382000CD020E9476138091CE02DF91CF911F913D +:103830000F910C947D13DF92EF92FF920F931F93E1 +:10384000CF93DF93CDB7DEB7A9970FB6F894DEBF5D +:103850000FBECDBF09A31AA32BA33CA34DA35EA308 +:103860006FA378A789A77E0189E1E80EF11C88E0A3 +:10387000F70111928A95E9F783E1898B87E38A8BB7 +:1038800083EB8B8B87E48C8B82E08D8B8EA18E8B70 +:103890008FA18F8B88A5888F89A5898FE091BE0421 +:1038A000EF7710E0E13420F4F0E0E656FE4F1081AF +:1038B0000DEF010F033040F58FE19BE00E9488126D +:1038C00087E00E94F10E8093A102D090A102DD203A +:1038D00041F18EEE9AE00E94F9098D2D0E94900C24 +:1038E0000E94881281E991E00E946218A9960FB6A1 +:1038F000F894DEBF0FBECDBFDF91CF911F910F9126 +:10390000FF90EF90DF9008951630F9F619821A8231 +:103910008AE09BE00E948812CE0101960E94930EDD +:10392000D2CF85ED9AE00E94F9096AE070E084E068 +:103930000E94761380ED9AE00E94881260E1CE0129 +:1039400041960E9411140E948412BE016F5E7F4F47 +:1039500084E0033008F454C0163009F055C08E01DD +:103960000B5F1F4F8CE0D82EF8018D2D11928A9598 +:10397000E9F784E0FE017196DE01119601900D9247 +:103980008A95E1F7BE016F5F7F4F88E00E94C61401 +:10399000F8018D2D11928A95E9F784E0FE01759664 +:1039A000DE01119601900D928A95E1F7BE016F5FDD +:1039B0007F4F89E00E94C614F8018D2D11928A95DF +:1039C000E9F784E0F701DE01119601900D928A95E6 +:1039D000E1F7BE016F5F7F4F8AE00E94C614F801D5 +:1039E0001192DA94E9F784E0FE017D96DE011196EA +:1039F00001900D928A95E1F7BE016F5F7F4F8BE0DA +:103A00000E94C6148093A1021091A10280E991E066 +:103A1000112359F088EB9AE00E94F909812F0E9446 +:103A2000900C0E94881281E991E00E9462180E9425 +:103A3000841260ED77E080E090E00E94150B56CF95 +:103A40000F931F93CF93DF93CDB7DEB729970FB6B0 +:103A5000F894DEBF0FBECDBF0E94581888EA9AE0E6 +:103A60000E948812CE0106960E94AF1A882389F020 +:103A70000E9458180E9467128111FCCF09811A8197 +:103A80002B813C814D815E816F81788589850E9483 +:103A90001B1C68EE73E080E090E00E94150B2996F5 +:103AA0000FB6F894DEBF0FBECDBFDF91CF911F914F +:103AB0000F9108954F925F926F927F928F929F9293 +:103AC000AF92BF92CF92DF92EF92FF920F931F932C +:103AD000CF93DF93CDB7DEB729970FB6F894DEBF4B +:103AE0000FBECDBF182F0E9494120E94581888E96B +:103AF0009AE00E9488121092D203111199C080910D +:103B0000CA02813009F18230B1F58FED93E00E9455 +:103B10006218CE0101960E9426128823A9F0909186 +:103B2000CB028981981310C09091CC028A8198139E +:103B30000BC09B818091CD02981306C09C8180911F +:103B4000CE02981709F474C029960FB6F894DEBF18 +:103B50000FBECDBFDF91CF911F910F91FF90EF90DE +:103B6000DF90CF90BF90AF909F908F907F906F909D +:103B70005F904F900895833009F05AC00E94B22D93 +:103B80002AE030E040E050E00E94202E4B015C0132 +:103B90007C016B012AE0C20ED11CE11CF11C1C2D22 +:103BA0000E94B22D2B013C0180EE93E00E9462182E +:103BB0000E940419C6010E9462180E94B22D22E0E0 +:103BC00030E040E050E00E94202E61307105810518 +:103BD000910509F071C0C301B20129E030E040E075 +:103BE00050E00E94202EDC01CB010196A11DB11DE9 +:103BF000B82EC80E0E94041981EE93E00E9462184C +:103C00000E9404198B2D90E00E9462188C2D0E9456 +:103C10007D13F12CE12C10E000E020E050E040E0CA +:103C200070E060E08FEF90E00E943019C8128CCFF6 +:103C3000F12CE12C10E000E020E044E853E064E8DF +:103C400073E08CE090E00E94301990E0009709F456 +:103C50007BCF8130910509F062C080E293E00E9441 +:103C600062188FE994E00E94D0118DE894E00E94E0 +:103C7000D0118BE794E00E94D0118DE894E00E946F +:103C8000C811811106C08BE794E00E94C8118823F7 +:103C900091F18EE19AE00E94F90982E293E00E949C +:103CA000621881EB94E00E94430F0E94DD0F0E9496 +:103CB000171B0E94C71348CF31E0C316D104E1049B +:103CC000F10489F00E94B22DA5019401275F3F4FB6 +:103CD0004F4F5F4F0E94202E6B017C012FEFC21AC5 +:103CE000D20AE20AF20ABC2C1C19C12E0E94041945 +:103CF00082EE93E083CF81EB94E00E94E30F882370 +:103D000009F4AFCF81EB94E00E94800C882349F244 +:103D100081E09AE00E94F9090E94201DC2CF823002 +:103D20009105D1F4E091B102F0E0E090B002F12C05 +:103D3000EE1AFF0A10E000E020E0AF0162EA73E053 +:103D40008EE190E08E1B9F0B0E9430199091B10282 +:103D5000890F8093B002ABCF8330910599F4E09046 +:103D6000B102F12C8091B00210E000E020E050E0C0 +:103D700040E063EA73E08150990B0E943019809310 +:103D8000B10295CF8430910511F52091B10230E058 +:103D9000E090B202F12CE21AF30A8FEFE81AF80A67 +:103DA000A901415051098091B00290E0821B930B10 +:103DB00010E000E020E064EA73E001960E94301910 +:103DC0009091B1029150890F8093B20270CF8530EB +:103DD0009105C1F4E090B302F12C10E000E020E086 +:103DE00048E953E068E973E086E090E00E9430190A +:103DF0008093B302282F2150330BB90187E00E9432 +:103E0000E01655CF8630910509F083C087E493EB27 +:103E1000A7E3B3E189839A83AB83BC8381E08D837D +:103E20001E8218861986F12CE12C10E000E020E0BB +:103E30004AEC53E06AEC73E086E090E00E943019AF +:103E4000D82E882309F433CF31E083130EC020E04D +:103E500040EC53E060EC73E084E090E00E943019A5 +:103E6000823039F1E8F4813009F180E293E00E9478 +:103E700062180E941A128DE894E00E94C811811104 +:103E800006C08BE794E00E94C8118823B1F08BE84C +:103E90009AE00E94881282E293E00E94621854CE57 +:103EA000833049F0843009F78CE301C085E08887CE +:103EB000DCCF8FE0FCCF8EE1FACF81EB94E00E9463 +:103EC000E30F8823B1F281EB94E00E94800C8823F9 +:103ED00009F4EDCE89E79AE00E948812DF82098119 +:103EE0001A812B813C814D815E816D2D788589857C +:103EF0000E941B1C64E670E080E090E00E94150BBD +:103F000081EB94E00E94430F0E94DD0F0E94041990 +:103F1000CECE87309105E1F4F12CE12C10E000E0E9 +:103F200020E04CEA53E06CEA73E084E090E00E9409 +:103F300030198150990B880F991F880F991F86544B +:103F40009D4F0E94AF1A80E991E00E946218AFCEA7 +:103F50008830910509F03FC0F12CE12C10E000E021 +:103F600020E040EC53E060EC73E085E090E00E94DC +:103F70003019833031F150F48130B1F0823009F0E2 +:103F800096CE8FE090E0A0E0B0E012C08430F1F077 +:103F9000853009F08CCE1092B5021092B6021092C4 +:103FA000B7021092B80283CE85E090E0A0E0B0E0C6 +:103FB0008093B5029093B602A093B702B093B80273 +:103FC00076CE8EE190E0A0E0B0E0F2CF8CE390E01E +:103FD000A0E0B0E0EDCF8930910509F089C087E419 +:103FE00093EBA7E3B3E189839A83AB83BC8381E03E +:103FF0008D8384E08F83F12CE12C10E000E021E040 +:1040000050E040E06DE271E083E690E00E943019FC +:10401000C82EA82EB12CC5010E94911A850121E05D +:1040200050E040E061E471E00E943019D82EC501F3 +:104030000E94911AED2CF12C21E050E040E062E466 +:1040400071E00E943019F82E88EA93E00E9462180D +:104050000E940419FD1408F42ACE8D2D90E00E94D0 +:104060006218D8866AE070E08D2D0E94761389E68A +:104070009AE00E9488120E941A128DE894E00E9431 +:10408000C811811132C08BE794E00E94C8118111E0 +:104090002CC081EB94E00E94E30F882361F381EB55 +:1040A00094E00E94800C8823F1F08AE49AE00E9458 +:1040B0008812CE8209811A812B813C814D815C2D31 +:1040C0006F81788589850E941B1C64E670E080E022 +:1040D00090E00E94150B81EB94E00E94430F0E9438 +:1040E000DD0F0E940419D394B5CF8CE59AE0D1CEB0 +:1040F0008A309105B1F4F12CE12C10E000E020E0D1 +:1041000045EA53E065EA73E082E090E00E943019EE +:10411000823021F481E08093B902C9CD1092B902B6 +:10412000C6CD8B309105B1F48BE29AE00E948812E3 +:10413000F12CE12C60E0C7010E94E3148FEFE81A34 +:10414000F80AE11424E0F206A9F70E943A1B87EE70 +:1041500093E0FBCE0C9709F0AACDF12CE12C10E0F6 +:1041600000E020E044ED53E064ED73E084E090E093 +:104170000E94301990E08130910519F41092CA0222 +:1041800096CD8230910521F481E08093CA028FCDD3 +:1041900083309105C9F48FED93E00E946218CE013F +:1041A00001960E942612882309F481CD89819A8183 +:1041B000AB81BC818093CB029093CC02A093CD02C3 +:1041C000B093CE0282E0E1CF049709F070CD83E096 +:1041D000DCCF8091D3039091D403009789F40E949F +:1041E000B22D20E030E041E050E00E94202ECB01D3 +:1041F0000E94F71468EE73E080E090E00C94150BD9 +:10420000DC01ED91FC910084F185E02D0995882376 +:1042100031F308958F929F92AF92BF92CF92DF9227 +:10422000EF92FF92CF93DF93EC01CF80D12C8FEFF1 +:10423000C81AD80A0D2C000CEE08FF088E80912CAD +:10424000B12CA12C8C149D04AE04BF048CF4C818AE +:10425000D908EA08FB0841F00E94B22DA701960197 +:104260000E94202E6B017C018C0C9D1CAE1CBF1C7F +:1042700082EA91E00E948812C4010E948B130E947E +:10428000470B48EE53E0489D9001499D300D589DE5 +:10429000300D1124620F731F811D911D6A837B8372 +:1042A0008C839D83DF91CF91FF90EF90DF90CF9033 +:1042B000BF90AF909F908F9008950F931F93CF93CF +:1042C000DF93FC014281538164817581452B462B2C +:1042D000472B29F1EC010E94470B0A811B812C819D +:1042E0003D810617170728073907C8F489EC91E0C4 +:1042F0000E9488120E946712882351F08DE291E09B +:104300000E94541864EF71E080E090E00E94150B69 +:10431000CE01DF91CF911F910F910C940A21DF9173 +:10432000CF911F910F910895EF92FF920F931F93DA +:10433000CF93DF9380914E0290914F0260914C0297 +:1043400070914D02FC013196E61BF70BA62F20E081 +:10435000422F50E04E175F0740F441535D4F3A2F14 +:10436000320FEA0138832F5FF3CF8F5F861BE82F70 +:10437000F0E0E153FD4F8F3F19F011928F5FFBCFBB +:10438000F12C20914E0230914F022F5F3F4F8091D0 +:104390004C0290914D028901081B190BCF2DD0E0E2 +:1043A000C017D10798F40E94B22DC153DD4FE880A9 +:1043B000980150E040E00E94202EE62FF0E0E1530B +:1043C000FD4F80818883E082F394DBCFDF91CF9132 +:1043D0001F910F91FF90EF9008958F929F92AF924F +:1043E000BF92CF92DF92EF92FF9285EC99E00E940C +:1043F00088120E94941281E08093D203109251029D +:1044000010925002E091D003F091D103808190E0AE +:104410000E94911A90934F0280934E0221E030E067 +:1044200030934D0220934C02BC0190E080E04AE0C2 +:104430000E94321381EB99E00E94F909E091D003C8 +:10444000F091D10380810E947D13E091D003F0911F +:10445000D1038181813079F581E899E00E94881249 +:10446000E0904E02F0904F028FEFE81AF80A82E0D7 +:10447000E816F10408F45AC10E94B22D970150E0E9 +:1044800040E021503109410951090E94202EDC01F0 +:10449000CB010196A11DB11D9093CF038093CE0354 +:1044A0000E948B13E091D003F091D1036091CE0371 +:1044B00080810E945F17E091D003F091D103818148 +:1044C000823091F484E599E00E94881281E090E0C6 +:1044D0009093CF038093CE03E091D003F091D1036A +:1044E00061E080810E945F17E091D003F091D103D9 +:1044F00081818330A9F487E199E00E9488120E94AB +:10450000942181E090E09093CF038093CE03E091DB +:10451000D003F091D1036091CF0280810E945F1798 +:10452000E091D003F091D1038181843091F482EE47 +:1045300098E00E948812E091D003F091D10362814B +:10454000862F90E09093CF038093CE0380810E94CA +:104550005F17E091D003F091D1038181853031F56F +:104560008FE998E00E948812E091D003F091D10386 +:10457000F0808F2D90E00E940A2E90E09093CF0360 +:104580008093CE03009739F020914E0230914F0274 +:104590002817390730F481E090E09093CF0380939F +:1045A000CE036091CE038F2D0E945F17E091D00360 +:1045B000F091D1038181873009F051C08EE598E0F8 +:1045C0000E948812E091D003F091D1036AE070E07C +:1045D00082810E94761388E598E00E94F909E091B3 +:1045E000D003F091D10383810E947D13E091D00329 +:1045F000F091D103C380D12CD0924F02C0924E02D1 +:104600008FEFC81AD80AF12CE12C8280912CB12CA2 +:10461000A12C8C149D04AE04BF048CF4C818D908D6 +:10462000EA08FB0841F00E94B22DA70196010E9402 +:10463000202E6B017C018C0C9D1CAE1CBF1C90922B +:10464000CF038092CE03C4010E948B13E091D0036C +:10465000F091D1036091CE0380810E945F17E091B9 +:10466000D003F091D1038181883061F589E098E031 +:104670000E948812E091D003F091D1036AE070E0CB +:1046800082810E94761383E098E00E94F909E0910C +:10469000D003F091D10383810E947D13E091D00378 +:1046A000F091D103838190E090934F0280934E026A +:1046B0006281862F90E09093CF038093CE03808118 +:1046C0000E945F17E091D003F091D103818189307E +:1046D00091F586EB97E00E948812E091D003F0916B +:1046E000D103828190E090934D0280934C028381AC +:1046F00090E090934F0280934E020E94942181E0BB +:1047000090E09093CF038093CE03E091D003F0919B +:10471000D1036091CF028081FF90EF90DF90CF9026 +:10472000BF90AF909F908F900C945F1781E090E0C6 +:10473000A0E0B0E0B1CEFF90EF90DF90CF90BF90BF +:10474000AF909F908F900895CF93C82F8EEE99E0F1 +:104750000E9488128C2F0E947D1324E0C29FC0010A +:104760001124FC01E555FD4F2785222389F086544D +:104770009D4F9093D1038093D0030E94ED210E941E +:10478000941268EE73E080E090E0CF910C94150BEA +:1047900085ED99E0CF910C9488121F93CF93DF930E +:1047A000EC0183EF93E00E9488121B851123E9F04E +:1047B0001B8689E0FE013296A2EAB2E001900D92DA +:1047C0008A95E1F787EA92E09093D1038093D00332 +:1047D0008091A7020E947D13E091D003F091D10354 +:1047E00081810E947D130E94ED21812FDF91CF9165 +:1047F0001F9108950F931F93CF93DF93FC01428184 +:10480000538164817581452B462B472BF9F0EC01D0 +:104810000E94470B0A811B812C813D8106171707D7 +:104820002807390798F486E691E00E9488120E94D2 +:1048300058180E94C7131092D4031092D303CE01CC +:10484000DF91CF911F910F910C944D2FDF91CF915C +:104850001F910F9108951F920F920FB60F9211247E +:104860002F933F934F935F936F937F938F939F9378 +:10487000AF93BF93EF93FF938EED93E00E948A096D +:10488000FF91EF91BF91AF919F918F917F916F9128 +:104890005F914F913F912F910F900FBE0F901F90FE +:1048A00018951F920F920FB60F9211242F938F938A +:1048B0009F93EF93FF93E091EE03F091EF038081DC +:1048C000E091F403F091F50382FD1BC0908180918B +:1048D000F7038F5F8F732091F803821741F0E09107 +:1048E000F703F0E0E252FC4F958F8093F703FF91BE +:1048F000EF919F918F912F910F900FBE0F901F906E +:1049000018958081F4CF1F920F920FB60F92112449 +:104910002F933F938F939F93AF93BF938091930275 +:1049200090919402A0919502B091960230919202DA +:1049300023E0230F2D3758F50196A11DB11D2093BB +:1049400092028093930290939402A0939502B09365 +:1049500096028091970290919802A0919902B0914D +:104960009A020196A11DB11D80939702909398021F +:10497000A0939902B0939A02BF91AF919F918F91AA +:104980003F912F910F900FBE0F901F90189526E822 +:10499000230F0296A11DB11DD2CF1F920F920FB609 +:1049A0000F9211242F933F934F935F936F937F93B5 +:1049B0008F939F93AF93BF93EF93FF93E0919D02EB +:1049C000F0919E02309749F0A685B7858585968D32 +:1049D00091FF14C09C918923A1F4FF91EF91BF91A5 +:1049E000AF919F918F917F916F915F914F913F9187 +:1049F0002F910F900FBE0F901F9018959C918923B7 +:104A000061F7A389B4899C918589809589238C93CA +:104A1000868997890197F1F7608D718DA685B78595 +:104A2000558538E020E0CB010197F1F7822F90E027 +:104A300095958795282F4C91452309F02068315092 +:104A400091F7868D81FD209580919C0290E00196E2 +:104A50008F73992730919B02381799F0A0919C028F +:104A6000B0E0AE5ABD4F2C9380939C02828D938D03 +:104A70000197F1F7A389B4898C919589892B8C933F +:104A8000ACCF868D8160868FF1CF1092E1031092BA +:104A9000E00388EE93E0A0E0B0E08093E20390931F +:104AA000E303A093E403B093E5032FED31E03093EB +:104AB000DF032093DE0325EC30E03093EB032093FB +:104AC000EA0324EC30E03093ED032093EC0320EC78 +:104AD00030E03093EF032093EE0321EC30E030938D +:104AE000F1032093F00322EC30E03093F3032093A2 +:104AF000F20326EC30E03093F5032093F403109298 +:104B0000F7031092F8031092F9031092FA0310922F +:104B1000CD041092CC048093CE049093CF04A09344 +:104B2000D004B093D1048BEF91E09093CB048093A9 +:104B3000CA041092E1041092E0041092E30410926F +:104B4000E2041092E5041092E4041092E70410923B +:104B5000E6046091E8046E7F6D7F6093E8046695DB +:104B6000617081E0682783E00E94860A61E083E04B +:104B70000E94B40AE9E7F1E1E491E093DA04E5E6A2 +:104B8000F1E1E491F0E0EE0FFF1FE85AFE4E85914F +:104B900094919093DC048093DB0460E082E00E94B7 +:104BA000B40A8091E80481FD04C061E082E00E94C3 +:104BB000860A82E08093D604E8E7F1E1E491E0938D +:104BC000D704E4E6F1E1E491F0E0EE0FFF1FE25BD1 +:104BD000FE4E859194919093D9048093D8048AECE9 +:104BE00094E09093C2048093C10482E390E0909398 +:104BF000C8048093C7041092C90481EF91E0909398 +:104C0000B2048093B1048AE08093BF0489E080936A +:104C1000C0048EE080939F0449E150E060E070E0C2 +:104C20004093A0045093A1046093A2047093A30442 +:104C300081E08093A4048093A5049FE090938D0469 +:104C400040938E0450938F0460939004709391046A +:104C5000809392048093930490E190937B0440931B +:104C60007C0450937D0460937E0470937F04809352 +:104C70008004809381040895CF93DF93CDB7DEB78E +:104C8000A6970FB6F894DEBF0FBECDBF789484B55B +:104C9000826084BD84B5816084BD85B5826085BD38 +:104CA00085B5816085BD80916E00816080936E00C6 +:104CB00010928100809181008260809381008091B8 +:104CC0008100816080938100809180008160809369 +:104CD00080008091B10084608093B1008091B00029 +:104CE00081608093B00080917A00846080937A0024 +:104CF00080917A00826080937A0080917A0081604E +:104D000080937A0080917A00806880937A00109274 +:104D1000C100E091EE03F091EF0382E08083E09127 +:104D2000EA03F091EB031082E091EC03F091ED03C4 +:104D300080E180831092F603E091F203F091F30397 +:104D400086E08083E091F003F091F103808180613F +:104D50008083E091F003F091F1038081886080838B +:104D6000E091F003F091F103808180688083E0910D +:104D7000F003F091F10380818F7D808320E0E7E4F0 +:104D8000E0937C0080917A00806480937A00809127 +:104D90007A0086FDFCCF8091780090917900482FB1 +:104DA000417050E04A01550FAA08BB08322F3F71ED +:104DB00004C0880C991CAA1CBB1C3A95D2F7C501EB +:104DC000B4016C257D258E259F252F5F203809F0A5 +:104DD000C5C18C149D04AE04BF0411F00E94012EC5 +:104DE00089E69EE00E94881281E49EE00E9488127B +:104DF00089E19EE00E94881280EF9DE00E94881267 +:104E00008CED9DE00E94881287EA9DE00E94881246 +:104E100082E79DE00E94881261E086E00E94B40A69 +:104E200060E086E00E94860A8DE49CE00E94881281 +:104E300060E084E00E94B40A0E94631B0E94C713D2 +:104E4000E091C104F091C204138E128E118E108E67 +:104E5000178A168A8DE991E0958F848F8485863133 +:104E600008F03DC02DEB30E0378B268B2BE931E08D +:104E7000318F208F2CE231E0338F228F90916800A8 +:104E8000883008F46EC121E08E3008F420E081E023 +:104E900001C0880F2A95EAF7892B809368009485D2 +:104EA0002DE630E0983050F02BE630E09E3030F0C8 +:104EB0002CE630E0963110F030E020E0348B238B8C +:104EC000292F30E0983008F04EC181E001C0880FF2 +:104ED0009A95EAF7858B848D958D0197F1F7828DF0 +:104EE000938D892B41F140919D0250919E02E417D0 +:104EF000F50709F14115510569F0DA0153962D9135 +:104F00003C91D9019C91DA0155968C918095892329 +:104F1000D9018C93868D8E7F868F10929C02109281 +:104F20009B02F0939E02E0939D02A389B4898C9129 +:104F30009589892B8C93E091C104F091C20480E1A2 +:104F400097E2A0E0B0E084839583A683B7830E94B4 +:104F5000470B6093C3047093C4048093C50490937B +:104F6000C60460ED77E080E090E00E94150B609150 +:104F7000B2026093A00270E086E00E94E0166091A9 +:104F8000B3026150770B87E00E94E0161FB7F894D8 +:104F900080919F02811127C0ECE6F1E18491E0E865 +:104FA000F1E19491E82FF0E0EE0FFF1FE259F34F8B +:104FB000A591B491EC91E92321F461E08AE00E948B +:104FC000860A61E08AE00E94B40A8CB580618CBDDB +:104FD0008CB580648CBD61E08DE00E94B40A61E014 +:104FE0008BE00E94B40A80919F028F5F80939F02A2 +:104FF0001FBF61E08091BF040E94B40A61E080910C +:10500000BF040E94860A8091C0048F3F09F4B8C093 +:1050100060E00E94B40A8091C0040E945D0A892B5E +:1050200009F0AEC061E08091C0040E94B40A60E063 +:105030008091C0040E94860A83E090E00197F1F716 +:1050400061E08091C0040E94860A62E370E080E023 +:1050500090E00E94150B40E064E281EB94E00E9436 +:10506000140D40E066E281EB94E00E94140D46E2EC +:1050700068E481EB94E00E94140D40E864E581EB64 +:1050800094E00E94140D49EA66E581EB94E00E94E9 +:10509000140D43E068E581EB94E00E94140D48EEA6 +:1050A0006AE581EB94E00E94140D40E46AE281EB32 +:1050B00094E00E94140D4DE362E281EB94E00E94C3 +:1050C000140D68E281EB94E00E94F60C982F937027 +:1050D000933039F0482F436068E281EB94E00E94FE +:1050E000140D6CE481EB94E00E94F60C807780371D +:1050F00091F040E76CE481EB94E00E94C90F6CE40E +:1051000081EB94E00E94F60C482F40676CE481EB41 +:1051100094E00E94140D84E59DE00E9488126EE6E2 +:1051200081EB94E00E94F60C182F8FEF9CE00E9418 +:10513000F90960E170E0812F0E9476138CEE9CE00B +:105140001039E9F1A0F588EC9CE01231C1F184EF4F +:105150009CE01838A1F18BEB9CE031C06B017C0125 +:105160000FCE84E099CE9E3040F42850310981E082 +:1051700001C0880F2A95EAF7ADCE2E503109F7CF3E +:105180004FE062E081EB94E00E94140D13E062E3D3 +:1051900070E080E090E00E94150B62E081EB94E00B +:1051A0000E94F60C84FF57CF115089F754CF84EE3C +:1051B0009CE0113921F08CED9CE0123961F60E94DF +:1051C000881211501E3F20F088E79CE00E94881250 +:1051D0008FEF8093D8038093D9038093DA03809371 +:1051E000DB038093DC038093DD0362E08EE00E94AA +:1051F000B40A62E08FE00E94B40A62E080E10E949B +:10520000B40A61E087E00E94B40A60E087E00E948F +:10521000860A61E086E00E94860A84E19DE00E94A1 +:1052200088128EE00E945D0A892B01F58FE00E94B2 +:105230005D0A892BD9F480E10E945D0A8C01892BDB +:10524000A9F485E39DE00E948812C8010E940A2EFD +:10525000882321F060E0C8010E94122E0F5F1F4FCB +:105260000115B4E01B0789F70E94631B83E00E94CD +:10527000A423F7EA2F2EF2E03F2EA6E56A2EA1E046 +:105280007A2EBEE0AB2EB1E0BB2E16E8812E11E0E7 +:10529000912E11E00E94B6180E94CE168091D30381 +:1052A0009091D403009739F0DC01ED91FC910190CD +:1052B000F081E02D09950E941A128FE994E00E9476 +:1052C000F108082F81110DC08DE894E00E94F108CB +:1052D000811107C08BE794E00E94F108882309F44C +:1052E0005BC08091A604882309F456C08091940481 +:1052F000882309F451C080918204882309F44CC0AA +:105300000E9458180E941A128091A6048111FACFA7 +:10531000809194048111F6CF809182048111F2CFA3 +:105320000E941A1280E00E945A1D81EB94E00E94B4 +:10533000800C882309F49BC08EE191E10E94F90959 +:105340006091B30484EB94E00E9411140E948412D3 +:1053500082E191E10E94F909E091BE04EF77E13426 +:1053600008F046C1F0E0E656FE4F108181E89FE06C +:10537000153009F401C108F024C18EEA9FE0123013 +:1053800009F4FAC008F0EFC086ED9FE0113009F48F +:10539000F3C085E09FE0F0C08FE994E00E94C8115F +:1053A000811115C0002349F18091D703811125C0D7 +:1053B0008091D3039091D403009709F06FC00E94AD +:1053C0006712811176C080E00E94A4238DC0809175 +:1053D000D3039091D403009709F03FC08091D70385 +:1053E000811109C00E946712882309F44DC00E94F0 +:1053F00058180E94C7131092D7038DE894E00E94BA +:10540000F108882309F47AC00E946712882309F4FE +:1054100071C08091B90281116AC00E948E181093E8 +:10542000D6038BE794E00E94F108882309F484C036 +:105430000E946712882309F47BC08091B902811110 +:1054400074C00E9466181093D50381EB94E00E940B +:10545000E30F882309F41ECF68CFDC01ED91FC91A6 +:105460000280F381E02D0995882309F4B7CF80E00D +:1054700090E0892B09F40DCF0E947609882309F466 +:10548000F8CE0E940000F5CE8091D203882309F463 +:10549000B2CF0E945D180E949412ADCFDC01ED9155 +:1054A000FC910280F381E02D0995882309F487CFD0 +:1054B000DECFE091D003F091D10321818091CE0322 +:1054C0009091CF03233011F0293021F482539D4F66 +:1054D000DC018C912850223020F49281B12FB91B2D +:1054E0008B0F90E00E9454181093D70386CF0E9430 +:1054F000E92095CF81E00E94A42391CF8DE894E02C +:105500000E94C811882309F48CCF8091D6038111A1 +:1055100006C08091B902811105C00E94E920109255 +:10552000D6037FCF0E948E18FACF0E9463178BCFCD +:1055300082E00E94A42387CF8BE794E00E94C811E9 +:10554000882309F482CF8091D503811106C0809110 +:10555000B902811105C00E9463171092D50375CF5F +:105560000E946618FACF87E99FE0133029F08CE893 +:105570009FE0143009F00DCF0E94881282E18EA3C3 +:105580000DEF010F0330B0F58CEE90E10E94881210 +:1055900087E00E94F10E8093A1025090A102552055 +:1055A000B1F184EB90E10E94F909852D0E94900CE5 +:1055B0000E94881281EB94E00E94430F0E94DD0F4D +:1055C00056CF84E49FE01830B9F248F48FE59FE0AD +:1055D000163091F283E59FE0173071F2DACE85E361 +:1055E0009FE0193049F282E19FE01F3F29F2D1CEBE +:1055F00010E0CFCE163089F619821A8280ED90E144 +:105600000E948812CE0101960E94930EC4CF0330EF +:1056100008F0A0C08BE990E10E94F9096AE070E00F +:1056200084E00E94761386E990E10E948812AE0120 +:105630004A5D5F4FBE016D5E7F4F84E00E94900F18 +:10564000182F8093A1028FE790E11111E3C08DE044 +:1056500090E10E94F9098BE090E10E94881260E1DC +:10566000CE0143960E9411140E9484120E9484125B +:105670008B8990E0B0E0A0E0782F6627552744277B +:105680009C89892F90E0B0E0A0E0DC019927882771 +:10569000840F951FA61FB71F2E89820F911DA11D74 +:1056A000B11D4D8950E070E060E0762F652F542FDA +:1056B0004427840F951FA61FB71F89839A83AB8346 +:1056C000BC832F892D83288D2E83398D3F833A8D7E +:1056D00038873B8D39878734934BA743B34109F013 +:1056E000C4C18091D3039091D403009709F0A0C066 +:1056F0008E81882309F4ADC099E0FE013196A2EABB +:10570000B2E001900D929A95E1F70E947D133092DC +:10571000D1032092D0038091A7020E947D13809133 +:10572000A2029091A302A091A402B091A502873495 +:10573000934BA743B34109F0A2C18091A7028823EC +:1057400009F438CF8091A802882309F433CF0E944E +:10575000ED2130CF163009F07ACF82E18DA3AE0172 +:105760004B5D5F4FBE016F5F7F4F88E00E94900FDF +:10577000182F8093A10286E690E111114BC084E0BE +:10578000FE013196DE01539601900D928A95E1F764 +:10579000AE014B5D5F4FBE016F5F7F4F89E00E949E +:1057A000900F182F8093A1028DE490E1111132C067 +:1057B00084E0FE013196DE01579601900D928A95A4 +:1057C000E1F7AE014B5D5F4FBE016F5F7F4F8AE037 +:1057D0000E94900F182F8093A10284E390E1111191 +:1057E00019C084E0FE013196DE015B9601900D92B6 +:1057F0008A95E1F7AE014B5D5F4FBE016F5F7F4F52 +:105800008BE00E94900F182F8093A102882331F023 +:105810008BE190E10E94F909812FC8CE84E0FE015E +:105820003196DE015F9601900D928A95E1F70FCFD8 +:10583000222309F45DCFDC01ED91FC910088F18910 +:10584000E02DBE016F5F7F4F0995882309F450CF8B +:10585000B1CE8091D3039091D4030097B1F1DC01D4 +:10586000ED91FC910288F389E02D09959F818913C0 +:105870002CC01092D4031092D3038AEF9FE00E94B1 +:1058800088120E946712882359F085E091E00E94F7 +:10589000541860ED77E080E090E00E94150B8ACE0E +:1058A0000E945D1864E670E080E090E00E94150BB5 +:1058B00085E091E00E94541864E670E080E090E09A +:1058C0000E94150B0E945818E4CF8F8181508E3FA3 +:1058D00040F40E9467128823B9F084E091E00E94AE +:1058E00054188F81833009F48BC018F5813069F129 +:1058F00008F057C081EB94E00E94430F0E94DD0F37 +:1059000081E00E945A1DC5CF0E945D1864E670E0D8 +:1059100080E090E00E94150B84E091E00E94541812 +:1059200064E670E080E090E00E94150B0E94581839 +:10593000D8CF853009F47EC008F46FC0863009F4F2 +:1059400089C08F3F09F0A5CFD5CF86E090E00E94B7 +:10595000B12E8C015884FC019182808212821382C4 +:105960001482158284EF9EE00E948812852D0E9489 +:105970007D130E94470B6B017C01252D30E0A0E6D2 +:10598000BAEE0E94742E6C0D7D1D8E1D9F1DF801B8 +:1059900062837383848395831093D4030093D3032A +:1059A00078CF88E090E00E94B12E8C018EE691E0E5 +:1059B000D8018D939C93F801128213821482158270 +:1059C00085E086838EE1878382EE9EE00E948812C6 +:1059D0000E946712882381F068EE73E080E090E017 +:1059E0000E94150B8CE291E00E94541864EF71E064 +:1059F00080E090E00E94150BC8010E940A21CCCFE4 +:105A000082E090E00E94B12E8C01DC016D927C92CC +:105A100085ED9EE00E948812BFCF82E090E00E9458 +:105A2000B12E8C012EE331E0FC013183208383EC25 +:105A30009EE0F0CF8CE090E00E94B12E8C01E6E277 +:105A4000F1E0DC011196FC93EE931B961C928CEA1C +:105A50009EE0E0CF82E090E00E94B12E8C01DC015C +:105A6000AD92BC9281E99EE0D5CF89E0FE013196EE +:105A7000A2EAB2E001900D928A95E1F750CE109221 +:105A8000D2038CE291E00E9462180E9404190E94E5 +:105A9000201D90CD8BEF91E09093CB048093CA04AE +:105AA00080919D0290919E028A5C944071F4E091F5 +:105AB000DD04F091DE0490818091DF0480958923DC +:105AC000808310929E0210929D0208958F929F9261 +:105AD000AF92BF92CF92DF92EF92FF92CF93DF937C +:105AE000EC01688179818A819B816115710581054D +:105AF000910521F464E279ED8BE597E02DE133EF38 +:105B000041E050E00E94202E49015A019B01AC0166 +:105B1000A7EAB1E40E943F2E6B017C01ACEEB4EF2A +:105B2000A50194010E944D2EC60ED71EE81EF91E37 +:105B3000F7FE06C081E0C81AD108E10880E8F80A3B +:105B4000C882D982EA82FB82C701B6019F77DF91C2 +:105B5000CF91FF90EF90DF90CF90BF90AF909F904C +:105B60008F9008958F929F92AF92BF92CF92DF92C3 +:105B7000EF92FF926091000170910101809102010A +:105B800090910301611571058105910521F464E28D +:105B900079ED8BE597E02DE133EF41E050E00E9495 +:105BA000202E49015A019B01AC01A7EAB1E40E94F1 +:105BB0003F2E6B017C01ACEEB4EFA50194010E9475 +:105BC0004D2EC60ED71EE81EF91EF7FE06C081E058 +:105BD000C81AD108E10880E8F80AC0920001D09202 +:105BE0000101E0920201F0920301C701B6019F7723 +:105BF000FF90EF90DF90CF90BF90AF909F908F90ED +:105C000008956093000170930101809302019093C5 +:105C100003010895F999FECF92BD81BDF89A9927A5 +:105C200080B50895262FF999FECF1FBA92BD81BD88 +:105C300020BD0FB6F894FA9AF99A0FBE019608950E +:105C4000052E97FB1EF400940E94372E57FD07D0B7 +:105C50000E94522E07FC03D04EF40C94372E509520 +:105C60004095309521953F4F4F4F5F4F0895909548 +:105C70008095709561957F4F8F4F9F4F08950E943B +:105C8000742EA59F900DB49F900DA49F800D911D23 +:105C900011240895B7FF0C943F2E0E943F2E821BC3 +:105CA000930B0895A1E21A2EAA1BBB1BFD010DC088 +:105CB000AA1FBB1FEE1FFF1FA217B307E407F507BC +:105CC00020F0A21BB30BE40BF50B661F771F881F98 +:105CD000991F1A9469F760957095809590959B012E +:105CE000AC01BD01CF010895A29FB001B39FC001D7 +:105CF000A39F700D811D1124911DB29F700D811DF8 +:105D00001124911D089597FB072E16F4009407D0D7 +:105D100077FD09D00E94972E07FC05D03EF49095A0 +:105D200081959F4F0895709561957F4F0895AA1BA7 +:105D3000BB1B51E107C0AA1FBB1FA617B70710F076 +:105D4000A61BB70B881F991F5A95A9F780959095A8 +:105D5000BC01CD010895EE0FFF1F0590F491E02DD9 +:105D600009940F931F93CF93DF938230910510F422 +:105D700082E090E0E091EB04F091EC0430E020E070 +:105D8000B0E0A0E0309799F42115310509F44AC03C +:105D9000281B390B24303105D8F58A819B81611588 +:105DA000710589F1FB0193838283FE0111C040815B +:105DB00051810281138148175907E0F048175907AC +:105DC00099F4109761F012960C93129713961C9306 +:105DD0003296CF01DF91CF911F910F9108950093DB +:105DE000EB041093EC04F4CF2115310551F0421768 +:105DF000530738F0A901DB019A01BD01DF01F80169 +:105E0000C1CFEF01F9CF9093EC048093EB04CDCF99 +:105E1000FE01E20FF31F81939193225031093983E0 +:105E20002883D7CF2091E9043091EA04232B41F451 +:105E300020910601309107013093EA042093E90490 +:105E400020910401309105012115310541F42DB750 +:105E50003EB74091080150910901241B350BE09198 +:105E6000E904F091EA04E217F307A0F42E1B3F0BBC +:105E70002817390778F0AC014E5F5F4F24173507BC +:105E800048F04E0F5F1F5093EA044093E90481935A +:105E900091939FCFF0E0E0E09CCFCF93DF9300970A +:105EA000E9F0FC01329713821282A091EB04B091C9 +:105EB000EC04ED0130E020E01097A1F42081318165 +:105EC000820F931F2091E9043091EA0428173907C3 +:105ED00009F061C0F093EA04E093E904DF91CF9107 +:105EE0000895EA01CE17DF07E8F54A815B819E013C +:105EF00041155105B1F7E901FB83EA8349915991B5 +:105F0000C40FD51FEC17FD0761F4808191810296C3 +:105F1000840F951FE90199838883828193819B83F4 +:105F20008A83F0E0E0E012968D919C9113970097A0 +:105F3000B9F52D913C911197CD010296820F931FD7 +:105F40002091E9043091EA042817390739F630978F +:105F500051F51092EC041092EB04B093EA04A09374 +:105F6000E904BCCFD383C28340815181840F951F44 +:105F7000C817D90761F44E5F5F4F88819981480F38 +:105F8000591F518340838A819B819383828321158A +:105F9000310509F0B0CFF093EC04E093EB049ECF11 +:105FA000FD01DC01C0CF13821282D7CFFB01DC01DF +:105FB00002C001900D9241505040D8F7089518E06A +:105FC000C6ECD8E004C0FE010E94AB2E2196C73C6F +:105FD000D107C9F7F894FFCF010000000000ED04DD +:105FE000800000000000761274122C1874127412D3 +:105FF0007412741274127212A11200000000761250 +:106000007412CD237412D812D21274127412AD12FB +:10601000A712000000007612FC1274127412F6121D +:10602000F012EA12E4127212DE1200000000761280 +:106030002013741274121A1314130E13081302137C +:106040007012000000005D21741274127412741238 +:106050007412741274127212261300000000FA23D4 +:106060007412741274127412741274127412721202 +:106070002C1306090000FF000000040300000000CC +:1060800000000707000000000000050000000000FD +:1060900000000100000000000000000000000000FF +:1060A00000000000000000000000000000000000F0 +:1060B00000000200000000AC090C093909140A6A4A +:1060C0000948095C09000000004610E30F800C003D +:1060D000000000E80B0C097D0CE70B440C5C0CCFB6 +:1060E0000B0D0A002030005344204B617274652070 +:1060F000005553422000466C6173682000436F6D69 +:10610000204572726F7220006F6E6C696E6500625E +:10611000657265697400656E746665726E74000000 +:107800000C94343C0C94513C0C94513C0C94513CE1 +:107810000C94513C0C94513C0C94513C0C94513CB4 +:107820000C94513C0C94513C0C94513C0C94513CA4 +:107830000C94513C0C94513C0C94513C0C94513C94 +:107840000C94513C0C94513C0C94513C0C94513C84 +:107850000C94513C0C94513C0C94513C0C94513C74 +:107860000C94513C0C94513C11241FBECFEFD8E036 +:10787000DEBFCDBF11E0A0E0B1E0ECE9FFE702C060 +:1078800005900D92A230B107D9F712E0A2E0B1E065 +:1078900001C01D92AD30B107E1F70E942D3D0C945F +:1078A000CC3F0C94003C982F959595959595959582 +:1078B000905D8F708A307CF0282F295A8091C0000B +:1078C00085FFFCCF9093C6008091C00085FFFCCF60 +:1078D0002093C6000895282F205DF0CF982F809127 +:1078E000C00085FFFCCF9093C6000895EF92FF92F1 +:1078F0000F931F93EE24FF2487018091C00087FD22 +:1079000017C00894E11CF11C011D111D81E4E8164B +:1079100082E4F8068FE0080780E0180770F3E09132 +:107920000401F091050109958091C00087FFE9CF1E +:107930008091C6001F910F91FF90EF9008950E94D3 +:10794000763C982F8091C00085FFFCCF9093C600B5 +:1079500091362CF490330CF09053892F089597555D +:10796000892F08951F930E949F3C182F0E949F3CCF +:107970001295107F810F1F9108951F93182F882350 +:1079800021F00E94763C1150E1F71F9108951F935A +:10799000182F0E94763C803249F0809103018F5F5E +:1079A000809303018530C1F01F9108958091C0003C +:1079B00085FFFCCF84E18093C6008091C00085FFE5 +:1079C000FCCF1093C6008091C00085FFFCCF80E102 +:1079D0008093C6001F910895E0910401F091050184 +:1079E00009951F9108950E94763C803241F0809164 +:1079F00003018F5F80930301853081F008958091AA +:107A0000C00085FFFCCF84E18093C6008091C00058 +:107A100085FFFCCF80E18093C6000895E0910401CA +:107A2000F09105010995089540E951E08823A1F0FE +:107A30002D9A28EE33E0FA013197F1F721503040CA +:107A4000D1F72D9828EE33E0FA013197F1F7215064 +:107A50003040D1F7815061F708953F924F925F9285 +:107A60006F927F928F929F92AF92BF92CF92DF924E +:107A7000EF92FF920F931F93CF93DF93000080E16B +:107A80008093C4001092C50088E18093C10086E015 +:107A90008093C2005098589A259A81E00E94143D24 +:107AA00024E1F22E9EE1E92E85E9D82E0FE0C02ECA +:107AB00010E1B12EAA24A394B1E49B2EA6E58A2E50 +:107AC000F2E57F2EE0E26E2E79E4572E63E5462E36 +:107AD00050E5352E0E94763C8033B1F18133B9F107 +:107AE000803409F46FC0813409F476C0823409F41B +:107AF00085C0853409F488C0803531F1823521F1A3 +:107B0000813511F1853509F485C0863509F48DC0BC +:107B1000843609F496C0843709F403C1853709F423 +:107B200072C1863709F466C0809103018F5F80932C +:107B30000301853079F6E0910401F0910501099582 +:107B40000E94763C803351F60E94F33CC3CF0E94E2 +:107B5000763C803249F78091C00085FFFCCFF092DF +:107B6000C6008091C00085FFFCCF9092C600809136 +:107B7000C00085FFFCCF8092C6008091C00085FFC9 +:107B8000FCCF7092C6008091C00085FFFCCF609250 +:107B9000C6008091C00085FFFCCF5092C600809146 +:107BA000C00085FFFCCF4092C6008091C00085FFD9 +:107BB000FCCF3092C6008091C00085FFFCCFB09210 +:107BC000C60088CF0E94763C863808F4BDCF0E945C +:107BD000763C0E94F33C7ECF0E94763C803809F4CC +:107BE0009CC0813809F40BC1823809F43CC1883942 +:107BF00009F48FC080E00E94C73C6CCF84E10E94F2 +:107C0000BD3C0E94F33C66CF85E00E94BD3C0E94D3 +:107C1000F33C60CF0E94763C809306010E94763C44 +:107C2000809307010E94F33C55CF0E94763C80333D +:107C300009F41DC183E00E94BD3C80E00E94C73C66 +:107C400049CF0E94763C809309020E94763C809343 +:107C5000080280910C028E7F80930C020E94763C79 +:107C6000853409F415C18091080290910902892B8D +:107C700089F000E010E00E94763CF801E85FFE4FDA +:107C800080830F5F1F4F80910802909109020817AF +:107C9000190788F30E94763C803209F045CF809125 +:107CA0000C0280FF01C16091060170910701660F0F +:107CB000771F7093070160930601A0910802B091AD +:107CC00009021097C9F0E8E0F1E09B01AD014E0F09 +:107CD0005F1FF999FECF32BD21BD819180BDFA9A17 +:107CE000F99A2F5F3F4FE417F50799F76A0F7B1F4B +:107CF00070930701609306018091C00085FFFCCF5F +:107D0000F092C6008091C00085FFFCCFB092C60003 +:107D1000E1CE83E00E94C73CDDCE82E00E94C73CFA +:107D2000D9CE0E94763C809309020E94763C8093D3 +:107D300008028091060190910701880F991F909386 +:107D40000701809306010E94763C853409F4A6C0A1 +:107D500080910C028E7F80930C020E94763C8032D0 +:107D600009F0B8CE8091C00085FFFCCFF092C6002C +:107D7000609108027091090261157105B9F140E046 +:107D800050E080910C02A82FA170B82FB27011C0E2 +:107D9000BB2309F45CC0E0910601F0910701319624 +:107DA000F0930701E09306014F5F5F4F46175707B7 +:107DB000E8F4AA2369F3F999FECF209106013091E6 +:107DC000070132BD21BDF89A90B58091C00085FFB2 +:107DD000FCCF9093C6002F5F3F4F30930701209355 +:107DE00006014F5F5F4F4617570718F38091C00099 +:107DF00085FDE5CE8091C00085FFF8CFE0CE81E023 +:107E00000E94C73C67CE0E94763C803209F08CCE3F +:107E10008091C00085FFFCCFF092C6008091C00029 +:107E200085FFFCCFE092C6008091C00085FFFCCFAB +:107E3000D092C6008091C00085FFFCCFC092C600E2 +:107E40008091C00085FFFCCFB092C60043CEE09188 +:107E50000601F091070194918091C00085FFFCCF4D +:107E60009093C6009CCF80E10E94C73C33CE0E9415 +:107E7000763C0E94763C182F0E94763C112309F430 +:107E800083C0113009F484C08FE00E94C73C22CE29 +:107E900080910C02816080930C02E5CE80910C02EF +:107EA000816080930C0259CF809107018823880F4D +:107EB000880B8A2180930B02809106019091070123 +:107EC000880F991F90930701809306018091080203 +:107ED00080FF09C080910802909109020196909359 +:107EE000090280930802F894F999FECF1127E091D6 +:107EF0000601F0910701C8E0D1E08091080290915D +:107F00000902103091F40091570001700130D9F34B +:107F100003E000935700E89500915700017001308D +:107F2000D9F301E100935700E89509901990009169 +:107F3000570001700130D9F301E000935700E89534 +:107F40001395103498F011270091570001700130FB +:107F5000D9F305E000935700E895009157000170B0 +:107F60000130D9F301E100935700E895329602976A +:107F700009F0C7CF103011F00296E5CF112480919F +:107F8000C00085FFB9CEBCCE8EE10E94C73CA2CD19 +:0E7F900085E90E94C73C9ECDF894FFCF80008B +:00000001FF diff --git a/audio_messages_de.txt b/src/audio_messages_de.txt similarity index 100% rename from audio_messages_de.txt rename to src/audio_messages_de.txt diff --git a/create-soundfiles.sh b/src/create-soundfiles.sh similarity index 100% rename from create-soundfiles.sh rename to src/create-soundfiles.sh diff --git a/sd-card/advert/0001.mp3 b/src/sd-card/advert/0001.mp3 similarity index 100% rename from sd-card/advert/0001.mp3 rename to src/sd-card/advert/0001.mp3 diff --git a/sd-card/advert/0002.mp3 b/src/sd-card/advert/0002.mp3 similarity index 100% rename from sd-card/advert/0002.mp3 rename to src/sd-card/advert/0002.mp3 diff --git a/sd-card/advert/0003.mp3 b/src/sd-card/advert/0003.mp3 similarity index 100% rename from sd-card/advert/0003.mp3 rename to src/sd-card/advert/0003.mp3 diff --git a/sd-card/advert/0004.mp3 b/src/sd-card/advert/0004.mp3 similarity index 100% rename from sd-card/advert/0004.mp3 rename to src/sd-card/advert/0004.mp3 diff --git a/sd-card/advert/0005.mp3 b/src/sd-card/advert/0005.mp3 similarity index 100% rename from sd-card/advert/0005.mp3 rename to src/sd-card/advert/0005.mp3 diff --git a/sd-card/advert/0006.mp3 b/src/sd-card/advert/0006.mp3 similarity index 100% rename from sd-card/advert/0006.mp3 rename to src/sd-card/advert/0006.mp3 diff --git a/sd-card/advert/0007.mp3 b/src/sd-card/advert/0007.mp3 similarity index 100% rename from sd-card/advert/0007.mp3 rename to src/sd-card/advert/0007.mp3 diff --git a/sd-card/advert/0008.mp3 b/src/sd-card/advert/0008.mp3 similarity index 100% rename from sd-card/advert/0008.mp3 rename to src/sd-card/advert/0008.mp3 diff --git a/sd-card/advert/0009.mp3 b/src/sd-card/advert/0009.mp3 similarity index 100% rename from sd-card/advert/0009.mp3 rename to src/sd-card/advert/0009.mp3 diff --git a/sd-card/advert/0010.mp3 b/src/sd-card/advert/0010.mp3 similarity index 100% rename from sd-card/advert/0010.mp3 rename to src/sd-card/advert/0010.mp3 diff --git a/sd-card/advert/0011.mp3 b/src/sd-card/advert/0011.mp3 similarity index 100% rename from sd-card/advert/0011.mp3 rename to src/sd-card/advert/0011.mp3 diff --git a/sd-card/advert/0012.mp3 b/src/sd-card/advert/0012.mp3 similarity index 100% rename from sd-card/advert/0012.mp3 rename to src/sd-card/advert/0012.mp3 diff --git a/sd-card/advert/0013.mp3 b/src/sd-card/advert/0013.mp3 similarity index 100% rename from sd-card/advert/0013.mp3 rename to src/sd-card/advert/0013.mp3 diff --git a/sd-card/advert/0014.mp3 b/src/sd-card/advert/0014.mp3 similarity index 100% rename from sd-card/advert/0014.mp3 rename to src/sd-card/advert/0014.mp3 diff --git a/sd-card/advert/0015.mp3 b/src/sd-card/advert/0015.mp3 similarity index 100% rename from sd-card/advert/0015.mp3 rename to src/sd-card/advert/0015.mp3 diff --git a/sd-card/advert/0016.mp3 b/src/sd-card/advert/0016.mp3 similarity index 100% rename from sd-card/advert/0016.mp3 rename to src/sd-card/advert/0016.mp3 diff --git a/sd-card/advert/0017.mp3 b/src/sd-card/advert/0017.mp3 similarity index 100% rename from sd-card/advert/0017.mp3 rename to src/sd-card/advert/0017.mp3 diff --git a/sd-card/advert/0018.mp3 b/src/sd-card/advert/0018.mp3 similarity index 100% rename from sd-card/advert/0018.mp3 rename to src/sd-card/advert/0018.mp3 diff --git a/sd-card/advert/0019.mp3 b/src/sd-card/advert/0019.mp3 similarity index 100% rename from sd-card/advert/0019.mp3 rename to src/sd-card/advert/0019.mp3 diff --git a/sd-card/advert/0020.mp3 b/src/sd-card/advert/0020.mp3 similarity index 100% rename from sd-card/advert/0020.mp3 rename to src/sd-card/advert/0020.mp3 diff --git a/sd-card/advert/0021.mp3 b/src/sd-card/advert/0021.mp3 similarity index 100% rename from sd-card/advert/0021.mp3 rename to src/sd-card/advert/0021.mp3 diff --git a/sd-card/advert/0022.mp3 b/src/sd-card/advert/0022.mp3 similarity index 100% rename from sd-card/advert/0022.mp3 rename to src/sd-card/advert/0022.mp3 diff --git a/sd-card/advert/0023.mp3 b/src/sd-card/advert/0023.mp3 similarity index 100% rename from sd-card/advert/0023.mp3 rename to src/sd-card/advert/0023.mp3 diff --git a/sd-card/advert/0024.mp3 b/src/sd-card/advert/0024.mp3 similarity index 100% rename from sd-card/advert/0024.mp3 rename to src/sd-card/advert/0024.mp3 diff --git a/sd-card/advert/0025.mp3 b/src/sd-card/advert/0025.mp3 similarity index 100% rename from sd-card/advert/0025.mp3 rename to src/sd-card/advert/0025.mp3 diff --git a/sd-card/advert/0026.mp3 b/src/sd-card/advert/0026.mp3 similarity index 100% rename from sd-card/advert/0026.mp3 rename to src/sd-card/advert/0026.mp3 diff --git a/sd-card/advert/0027.mp3 b/src/sd-card/advert/0027.mp3 similarity index 100% rename from sd-card/advert/0027.mp3 rename to src/sd-card/advert/0027.mp3 diff --git a/sd-card/advert/0028.mp3 b/src/sd-card/advert/0028.mp3 similarity index 100% rename from sd-card/advert/0028.mp3 rename to src/sd-card/advert/0028.mp3 diff --git a/sd-card/advert/0029.mp3 b/src/sd-card/advert/0029.mp3 similarity index 100% rename from sd-card/advert/0029.mp3 rename to src/sd-card/advert/0029.mp3 diff --git a/sd-card/advert/0030.mp3 b/src/sd-card/advert/0030.mp3 similarity index 100% rename from sd-card/advert/0030.mp3 rename to src/sd-card/advert/0030.mp3 diff --git a/sd-card/advert/0031.mp3 b/src/sd-card/advert/0031.mp3 similarity index 100% rename from sd-card/advert/0031.mp3 rename to src/sd-card/advert/0031.mp3 diff --git a/sd-card/advert/0032.mp3 b/src/sd-card/advert/0032.mp3 similarity index 100% rename from sd-card/advert/0032.mp3 rename to src/sd-card/advert/0032.mp3 diff --git a/sd-card/advert/0033.mp3 b/src/sd-card/advert/0033.mp3 similarity index 100% rename from sd-card/advert/0033.mp3 rename to src/sd-card/advert/0033.mp3 diff --git a/sd-card/advert/0034.mp3 b/src/sd-card/advert/0034.mp3 similarity index 100% rename from sd-card/advert/0034.mp3 rename to src/sd-card/advert/0034.mp3 diff --git a/sd-card/advert/0035.mp3 b/src/sd-card/advert/0035.mp3 similarity index 100% rename from sd-card/advert/0035.mp3 rename to src/sd-card/advert/0035.mp3 diff --git a/sd-card/advert/0036.mp3 b/src/sd-card/advert/0036.mp3 similarity index 100% rename from sd-card/advert/0036.mp3 rename to src/sd-card/advert/0036.mp3 diff --git a/sd-card/advert/0037.mp3 b/src/sd-card/advert/0037.mp3 similarity index 100% rename from sd-card/advert/0037.mp3 rename to src/sd-card/advert/0037.mp3 diff --git a/sd-card/advert/0038.mp3 b/src/sd-card/advert/0038.mp3 similarity index 100% rename from sd-card/advert/0038.mp3 rename to src/sd-card/advert/0038.mp3 diff --git a/sd-card/advert/0039.mp3 b/src/sd-card/advert/0039.mp3 similarity index 100% rename from sd-card/advert/0039.mp3 rename to src/sd-card/advert/0039.mp3 diff --git a/sd-card/advert/0040.mp3 b/src/sd-card/advert/0040.mp3 similarity index 100% rename from sd-card/advert/0040.mp3 rename to src/sd-card/advert/0040.mp3 diff --git a/sd-card/advert/0041.mp3 b/src/sd-card/advert/0041.mp3 similarity index 100% rename from sd-card/advert/0041.mp3 rename to src/sd-card/advert/0041.mp3 diff --git a/sd-card/advert/0042.mp3 b/src/sd-card/advert/0042.mp3 similarity index 100% rename from sd-card/advert/0042.mp3 rename to src/sd-card/advert/0042.mp3 diff --git a/sd-card/advert/0043.mp3 b/src/sd-card/advert/0043.mp3 similarity index 100% rename from sd-card/advert/0043.mp3 rename to src/sd-card/advert/0043.mp3 diff --git a/sd-card/advert/0044.mp3 b/src/sd-card/advert/0044.mp3 similarity index 100% rename from sd-card/advert/0044.mp3 rename to src/sd-card/advert/0044.mp3 diff --git a/sd-card/advert/0045.mp3 b/src/sd-card/advert/0045.mp3 similarity index 100% rename from sd-card/advert/0045.mp3 rename to src/sd-card/advert/0045.mp3 diff --git a/sd-card/advert/0046.mp3 b/src/sd-card/advert/0046.mp3 similarity index 100% rename from sd-card/advert/0046.mp3 rename to src/sd-card/advert/0046.mp3 diff --git a/sd-card/advert/0047.mp3 b/src/sd-card/advert/0047.mp3 similarity index 100% rename from sd-card/advert/0047.mp3 rename to src/sd-card/advert/0047.mp3 diff --git a/sd-card/advert/0048.mp3 b/src/sd-card/advert/0048.mp3 similarity index 100% rename from sd-card/advert/0048.mp3 rename to src/sd-card/advert/0048.mp3 diff --git a/sd-card/advert/0049.mp3 b/src/sd-card/advert/0049.mp3 similarity index 100% rename from sd-card/advert/0049.mp3 rename to src/sd-card/advert/0049.mp3 diff --git a/sd-card/advert/0050.mp3 b/src/sd-card/advert/0050.mp3 similarity index 100% rename from sd-card/advert/0050.mp3 rename to src/sd-card/advert/0050.mp3 diff --git a/sd-card/advert/0051.mp3 b/src/sd-card/advert/0051.mp3 similarity index 100% rename from sd-card/advert/0051.mp3 rename to src/sd-card/advert/0051.mp3 diff --git a/sd-card/advert/0052.mp3 b/src/sd-card/advert/0052.mp3 similarity index 100% rename from sd-card/advert/0052.mp3 rename to src/sd-card/advert/0052.mp3 diff --git a/sd-card/advert/0053.mp3 b/src/sd-card/advert/0053.mp3 similarity index 100% rename from sd-card/advert/0053.mp3 rename to src/sd-card/advert/0053.mp3 diff --git a/sd-card/advert/0054.mp3 b/src/sd-card/advert/0054.mp3 similarity index 100% rename from sd-card/advert/0054.mp3 rename to src/sd-card/advert/0054.mp3 diff --git a/sd-card/advert/0055.mp3 b/src/sd-card/advert/0055.mp3 similarity index 100% rename from sd-card/advert/0055.mp3 rename to src/sd-card/advert/0055.mp3 diff --git a/sd-card/advert/0056.mp3 b/src/sd-card/advert/0056.mp3 similarity index 100% rename from sd-card/advert/0056.mp3 rename to src/sd-card/advert/0056.mp3 diff --git a/sd-card/advert/0057.mp3 b/src/sd-card/advert/0057.mp3 similarity index 100% rename from sd-card/advert/0057.mp3 rename to src/sd-card/advert/0057.mp3 diff --git a/sd-card/advert/0058.mp3 b/src/sd-card/advert/0058.mp3 similarity index 100% rename from sd-card/advert/0058.mp3 rename to src/sd-card/advert/0058.mp3 diff --git a/sd-card/advert/0059.mp3 b/src/sd-card/advert/0059.mp3 similarity index 100% rename from sd-card/advert/0059.mp3 rename to src/sd-card/advert/0059.mp3 diff --git a/sd-card/advert/0060.mp3 b/src/sd-card/advert/0060.mp3 similarity index 100% rename from sd-card/advert/0060.mp3 rename to src/sd-card/advert/0060.mp3 diff --git a/sd-card/advert/0061.mp3 b/src/sd-card/advert/0061.mp3 similarity index 100% rename from sd-card/advert/0061.mp3 rename to src/sd-card/advert/0061.mp3 diff --git a/sd-card/advert/0062.mp3 b/src/sd-card/advert/0062.mp3 similarity index 100% rename from sd-card/advert/0062.mp3 rename to src/sd-card/advert/0062.mp3 diff --git a/sd-card/advert/0063.mp3 b/src/sd-card/advert/0063.mp3 similarity index 100% rename from sd-card/advert/0063.mp3 rename to src/sd-card/advert/0063.mp3 diff --git a/sd-card/advert/0064.mp3 b/src/sd-card/advert/0064.mp3 similarity index 100% rename from sd-card/advert/0064.mp3 rename to src/sd-card/advert/0064.mp3 diff --git a/sd-card/advert/0065.mp3 b/src/sd-card/advert/0065.mp3 similarity index 100% rename from sd-card/advert/0065.mp3 rename to src/sd-card/advert/0065.mp3 diff --git a/sd-card/advert/0066.mp3 b/src/sd-card/advert/0066.mp3 similarity index 100% rename from sd-card/advert/0066.mp3 rename to src/sd-card/advert/0066.mp3 diff --git a/sd-card/advert/0067.mp3 b/src/sd-card/advert/0067.mp3 similarity index 100% rename from sd-card/advert/0067.mp3 rename to src/sd-card/advert/0067.mp3 diff --git a/sd-card/advert/0068.mp3 b/src/sd-card/advert/0068.mp3 similarity index 100% rename from sd-card/advert/0068.mp3 rename to src/sd-card/advert/0068.mp3 diff --git a/sd-card/advert/0069.mp3 b/src/sd-card/advert/0069.mp3 similarity index 100% rename from sd-card/advert/0069.mp3 rename to src/sd-card/advert/0069.mp3 diff --git a/sd-card/advert/0070.mp3 b/src/sd-card/advert/0070.mp3 similarity index 100% rename from sd-card/advert/0070.mp3 rename to src/sd-card/advert/0070.mp3 diff --git a/sd-card/advert/0071.mp3 b/src/sd-card/advert/0071.mp3 similarity index 100% rename from sd-card/advert/0071.mp3 rename to src/sd-card/advert/0071.mp3 diff --git a/sd-card/advert/0072.mp3 b/src/sd-card/advert/0072.mp3 similarity index 100% rename from sd-card/advert/0072.mp3 rename to src/sd-card/advert/0072.mp3 diff --git a/sd-card/advert/0073.mp3 b/src/sd-card/advert/0073.mp3 similarity index 100% rename from sd-card/advert/0073.mp3 rename to src/sd-card/advert/0073.mp3 diff --git a/sd-card/advert/0074.mp3 b/src/sd-card/advert/0074.mp3 similarity index 100% rename from sd-card/advert/0074.mp3 rename to src/sd-card/advert/0074.mp3 diff --git a/sd-card/advert/0075.mp3 b/src/sd-card/advert/0075.mp3 similarity index 100% rename from sd-card/advert/0075.mp3 rename to src/sd-card/advert/0075.mp3 diff --git a/sd-card/advert/0076.mp3 b/src/sd-card/advert/0076.mp3 similarity index 100% rename from sd-card/advert/0076.mp3 rename to src/sd-card/advert/0076.mp3 diff --git a/sd-card/advert/0077.mp3 b/src/sd-card/advert/0077.mp3 similarity index 100% rename from sd-card/advert/0077.mp3 rename to src/sd-card/advert/0077.mp3 diff --git a/sd-card/advert/0078.mp3 b/src/sd-card/advert/0078.mp3 similarity index 100% rename from sd-card/advert/0078.mp3 rename to src/sd-card/advert/0078.mp3 diff --git a/sd-card/advert/0079.mp3 b/src/sd-card/advert/0079.mp3 similarity index 100% rename from sd-card/advert/0079.mp3 rename to src/sd-card/advert/0079.mp3 diff --git a/sd-card/advert/0080.mp3 b/src/sd-card/advert/0080.mp3 similarity index 100% rename from sd-card/advert/0080.mp3 rename to src/sd-card/advert/0080.mp3 diff --git a/sd-card/advert/0081.mp3 b/src/sd-card/advert/0081.mp3 similarity index 100% rename from sd-card/advert/0081.mp3 rename to src/sd-card/advert/0081.mp3 diff --git a/sd-card/advert/0082.mp3 b/src/sd-card/advert/0082.mp3 similarity index 100% rename from sd-card/advert/0082.mp3 rename to src/sd-card/advert/0082.mp3 diff --git a/sd-card/advert/0083.mp3 b/src/sd-card/advert/0083.mp3 similarity index 100% rename from sd-card/advert/0083.mp3 rename to src/sd-card/advert/0083.mp3 diff --git a/sd-card/advert/0084.mp3 b/src/sd-card/advert/0084.mp3 similarity index 100% rename from sd-card/advert/0084.mp3 rename to src/sd-card/advert/0084.mp3 diff --git a/sd-card/advert/0085.mp3 b/src/sd-card/advert/0085.mp3 similarity index 100% rename from sd-card/advert/0085.mp3 rename to src/sd-card/advert/0085.mp3 diff --git a/sd-card/advert/0086.mp3 b/src/sd-card/advert/0086.mp3 similarity index 100% rename from sd-card/advert/0086.mp3 rename to src/sd-card/advert/0086.mp3 diff --git a/sd-card/advert/0087.mp3 b/src/sd-card/advert/0087.mp3 similarity index 100% rename from sd-card/advert/0087.mp3 rename to src/sd-card/advert/0087.mp3 diff --git a/sd-card/advert/0088.mp3 b/src/sd-card/advert/0088.mp3 similarity index 100% rename from sd-card/advert/0088.mp3 rename to src/sd-card/advert/0088.mp3 diff --git a/sd-card/advert/0089.mp3 b/src/sd-card/advert/0089.mp3 similarity index 100% rename from sd-card/advert/0089.mp3 rename to src/sd-card/advert/0089.mp3 diff --git a/sd-card/advert/0090.mp3 b/src/sd-card/advert/0090.mp3 similarity index 100% rename from sd-card/advert/0090.mp3 rename to src/sd-card/advert/0090.mp3 diff --git a/sd-card/advert/0091.mp3 b/src/sd-card/advert/0091.mp3 similarity index 100% rename from sd-card/advert/0091.mp3 rename to src/sd-card/advert/0091.mp3 diff --git a/sd-card/advert/0092.mp3 b/src/sd-card/advert/0092.mp3 similarity index 100% rename from sd-card/advert/0092.mp3 rename to src/sd-card/advert/0092.mp3 diff --git a/sd-card/advert/0093.mp3 b/src/sd-card/advert/0093.mp3 similarity index 100% rename from sd-card/advert/0093.mp3 rename to src/sd-card/advert/0093.mp3 diff --git a/sd-card/advert/0094.mp3 b/src/sd-card/advert/0094.mp3 similarity index 100% rename from sd-card/advert/0094.mp3 rename to src/sd-card/advert/0094.mp3 diff --git a/sd-card/advert/0095.mp3 b/src/sd-card/advert/0095.mp3 similarity index 100% rename from sd-card/advert/0095.mp3 rename to src/sd-card/advert/0095.mp3 diff --git a/sd-card/advert/0096.mp3 b/src/sd-card/advert/0096.mp3 similarity index 100% rename from sd-card/advert/0096.mp3 rename to src/sd-card/advert/0096.mp3 diff --git a/sd-card/advert/0097.mp3 b/src/sd-card/advert/0097.mp3 similarity index 100% rename from sd-card/advert/0097.mp3 rename to src/sd-card/advert/0097.mp3 diff --git a/sd-card/advert/0098.mp3 b/src/sd-card/advert/0098.mp3 similarity index 100% rename from sd-card/advert/0098.mp3 rename to src/sd-card/advert/0098.mp3 diff --git a/sd-card/advert/0099.mp3 b/src/sd-card/advert/0099.mp3 similarity index 100% rename from sd-card/advert/0099.mp3 rename to src/sd-card/advert/0099.mp3 diff --git a/sd-card/advert/0100.mp3 b/src/sd-card/advert/0100.mp3 similarity index 100% rename from sd-card/advert/0100.mp3 rename to src/sd-card/advert/0100.mp3 diff --git a/sd-card/advert/0101.mp3 b/src/sd-card/advert/0101.mp3 similarity index 100% rename from sd-card/advert/0101.mp3 rename to src/sd-card/advert/0101.mp3 diff --git a/sd-card/advert/0102.mp3 b/src/sd-card/advert/0102.mp3 similarity index 100% rename from sd-card/advert/0102.mp3 rename to src/sd-card/advert/0102.mp3 diff --git a/sd-card/advert/0103.mp3 b/src/sd-card/advert/0103.mp3 similarity index 100% rename from sd-card/advert/0103.mp3 rename to src/sd-card/advert/0103.mp3 diff --git a/sd-card/advert/0104.mp3 b/src/sd-card/advert/0104.mp3 similarity index 100% rename from sd-card/advert/0104.mp3 rename to src/sd-card/advert/0104.mp3 diff --git a/sd-card/advert/0105.mp3 b/src/sd-card/advert/0105.mp3 similarity index 100% rename from sd-card/advert/0105.mp3 rename to src/sd-card/advert/0105.mp3 diff --git a/sd-card/advert/0106.mp3 b/src/sd-card/advert/0106.mp3 similarity index 100% rename from sd-card/advert/0106.mp3 rename to src/sd-card/advert/0106.mp3 diff --git a/sd-card/advert/0107.mp3 b/src/sd-card/advert/0107.mp3 similarity index 100% rename from sd-card/advert/0107.mp3 rename to src/sd-card/advert/0107.mp3 diff --git a/sd-card/advert/0108.mp3 b/src/sd-card/advert/0108.mp3 similarity index 100% rename from sd-card/advert/0108.mp3 rename to src/sd-card/advert/0108.mp3 diff --git a/sd-card/advert/0109.mp3 b/src/sd-card/advert/0109.mp3 similarity index 100% rename from sd-card/advert/0109.mp3 rename to src/sd-card/advert/0109.mp3 diff --git a/sd-card/advert/0110.mp3 b/src/sd-card/advert/0110.mp3 similarity index 100% rename from sd-card/advert/0110.mp3 rename to src/sd-card/advert/0110.mp3 diff --git a/sd-card/advert/0111.mp3 b/src/sd-card/advert/0111.mp3 similarity index 100% rename from sd-card/advert/0111.mp3 rename to src/sd-card/advert/0111.mp3 diff --git a/sd-card/advert/0112.mp3 b/src/sd-card/advert/0112.mp3 similarity index 100% rename from sd-card/advert/0112.mp3 rename to src/sd-card/advert/0112.mp3 diff --git a/sd-card/advert/0113.mp3 b/src/sd-card/advert/0113.mp3 similarity index 100% rename from sd-card/advert/0113.mp3 rename to src/sd-card/advert/0113.mp3 diff --git a/sd-card/advert/0114.mp3 b/src/sd-card/advert/0114.mp3 similarity index 100% rename from sd-card/advert/0114.mp3 rename to src/sd-card/advert/0114.mp3 diff --git a/sd-card/advert/0115.mp3 b/src/sd-card/advert/0115.mp3 similarity index 100% rename from sd-card/advert/0115.mp3 rename to src/sd-card/advert/0115.mp3 diff --git a/sd-card/advert/0116.mp3 b/src/sd-card/advert/0116.mp3 similarity index 100% rename from sd-card/advert/0116.mp3 rename to src/sd-card/advert/0116.mp3 diff --git a/sd-card/advert/0117.mp3 b/src/sd-card/advert/0117.mp3 similarity index 100% rename from sd-card/advert/0117.mp3 rename to src/sd-card/advert/0117.mp3 diff --git a/sd-card/advert/0118.mp3 b/src/sd-card/advert/0118.mp3 similarity index 100% rename from sd-card/advert/0118.mp3 rename to src/sd-card/advert/0118.mp3 diff --git a/sd-card/advert/0119.mp3 b/src/sd-card/advert/0119.mp3 similarity index 100% rename from sd-card/advert/0119.mp3 rename to src/sd-card/advert/0119.mp3 diff --git a/sd-card/advert/0120.mp3 b/src/sd-card/advert/0120.mp3 similarity index 100% rename from sd-card/advert/0120.mp3 rename to src/sd-card/advert/0120.mp3 diff --git a/sd-card/advert/0121.mp3 b/src/sd-card/advert/0121.mp3 similarity index 100% rename from sd-card/advert/0121.mp3 rename to src/sd-card/advert/0121.mp3 diff --git a/sd-card/advert/0122.mp3 b/src/sd-card/advert/0122.mp3 similarity index 100% rename from sd-card/advert/0122.mp3 rename to src/sd-card/advert/0122.mp3 diff --git a/sd-card/advert/0123.mp3 b/src/sd-card/advert/0123.mp3 similarity index 100% rename from sd-card/advert/0123.mp3 rename to src/sd-card/advert/0123.mp3 diff --git a/sd-card/advert/0124.mp3 b/src/sd-card/advert/0124.mp3 similarity index 100% rename from sd-card/advert/0124.mp3 rename to src/sd-card/advert/0124.mp3 diff --git a/sd-card/advert/0125.mp3 b/src/sd-card/advert/0125.mp3 similarity index 100% rename from sd-card/advert/0125.mp3 rename to src/sd-card/advert/0125.mp3 diff --git a/sd-card/advert/0126.mp3 b/src/sd-card/advert/0126.mp3 similarity index 100% rename from sd-card/advert/0126.mp3 rename to src/sd-card/advert/0126.mp3 diff --git a/sd-card/advert/0127.mp3 b/src/sd-card/advert/0127.mp3 similarity index 100% rename from sd-card/advert/0127.mp3 rename to src/sd-card/advert/0127.mp3 diff --git a/sd-card/advert/0128.mp3 b/src/sd-card/advert/0128.mp3 similarity index 100% rename from sd-card/advert/0128.mp3 rename to src/sd-card/advert/0128.mp3 diff --git a/sd-card/advert/0129.mp3 b/src/sd-card/advert/0129.mp3 similarity index 100% rename from sd-card/advert/0129.mp3 rename to src/sd-card/advert/0129.mp3 diff --git a/sd-card/advert/0130.mp3 b/src/sd-card/advert/0130.mp3 similarity index 100% rename from sd-card/advert/0130.mp3 rename to src/sd-card/advert/0130.mp3 diff --git a/sd-card/advert/0131.mp3 b/src/sd-card/advert/0131.mp3 similarity index 100% rename from sd-card/advert/0131.mp3 rename to src/sd-card/advert/0131.mp3 diff --git a/sd-card/advert/0132.mp3 b/src/sd-card/advert/0132.mp3 similarity index 100% rename from sd-card/advert/0132.mp3 rename to src/sd-card/advert/0132.mp3 diff --git a/sd-card/advert/0133.mp3 b/src/sd-card/advert/0133.mp3 similarity index 100% rename from sd-card/advert/0133.mp3 rename to src/sd-card/advert/0133.mp3 diff --git a/sd-card/advert/0134.mp3 b/src/sd-card/advert/0134.mp3 similarity index 100% rename from sd-card/advert/0134.mp3 rename to src/sd-card/advert/0134.mp3 diff --git a/sd-card/advert/0135.mp3 b/src/sd-card/advert/0135.mp3 similarity index 100% rename from sd-card/advert/0135.mp3 rename to src/sd-card/advert/0135.mp3 diff --git a/sd-card/advert/0136.mp3 b/src/sd-card/advert/0136.mp3 similarity index 100% rename from sd-card/advert/0136.mp3 rename to src/sd-card/advert/0136.mp3 diff --git a/sd-card/advert/0137.mp3 b/src/sd-card/advert/0137.mp3 similarity index 100% rename from sd-card/advert/0137.mp3 rename to src/sd-card/advert/0137.mp3 diff --git a/sd-card/advert/0138.mp3 b/src/sd-card/advert/0138.mp3 similarity index 100% rename from sd-card/advert/0138.mp3 rename to src/sd-card/advert/0138.mp3 diff --git a/sd-card/advert/0139.mp3 b/src/sd-card/advert/0139.mp3 similarity index 100% rename from sd-card/advert/0139.mp3 rename to src/sd-card/advert/0139.mp3 diff --git a/sd-card/advert/0140.mp3 b/src/sd-card/advert/0140.mp3 similarity index 100% rename from sd-card/advert/0140.mp3 rename to src/sd-card/advert/0140.mp3 diff --git a/sd-card/advert/0141.mp3 b/src/sd-card/advert/0141.mp3 similarity index 100% rename from sd-card/advert/0141.mp3 rename to src/sd-card/advert/0141.mp3 diff --git a/sd-card/advert/0142.mp3 b/src/sd-card/advert/0142.mp3 similarity index 100% rename from sd-card/advert/0142.mp3 rename to src/sd-card/advert/0142.mp3 diff --git a/sd-card/advert/0143.mp3 b/src/sd-card/advert/0143.mp3 similarity index 100% rename from sd-card/advert/0143.mp3 rename to src/sd-card/advert/0143.mp3 diff --git a/sd-card/advert/0144.mp3 b/src/sd-card/advert/0144.mp3 similarity index 100% rename from sd-card/advert/0144.mp3 rename to src/sd-card/advert/0144.mp3 diff --git a/sd-card/advert/0145.mp3 b/src/sd-card/advert/0145.mp3 similarity index 100% rename from sd-card/advert/0145.mp3 rename to src/sd-card/advert/0145.mp3 diff --git a/sd-card/advert/0146.mp3 b/src/sd-card/advert/0146.mp3 similarity index 100% rename from sd-card/advert/0146.mp3 rename to src/sd-card/advert/0146.mp3 diff --git a/sd-card/advert/0147.mp3 b/src/sd-card/advert/0147.mp3 similarity index 100% rename from sd-card/advert/0147.mp3 rename to src/sd-card/advert/0147.mp3 diff --git a/sd-card/advert/0148.mp3 b/src/sd-card/advert/0148.mp3 similarity index 100% rename from sd-card/advert/0148.mp3 rename to src/sd-card/advert/0148.mp3 diff --git a/sd-card/advert/0149.mp3 b/src/sd-card/advert/0149.mp3 similarity index 100% rename from sd-card/advert/0149.mp3 rename to src/sd-card/advert/0149.mp3 diff --git a/sd-card/advert/0150.mp3 b/src/sd-card/advert/0150.mp3 similarity index 100% rename from sd-card/advert/0150.mp3 rename to src/sd-card/advert/0150.mp3 diff --git a/sd-card/advert/0151.mp3 b/src/sd-card/advert/0151.mp3 similarity index 100% rename from sd-card/advert/0151.mp3 rename to src/sd-card/advert/0151.mp3 diff --git a/sd-card/advert/0152.mp3 b/src/sd-card/advert/0152.mp3 similarity index 100% rename from sd-card/advert/0152.mp3 rename to src/sd-card/advert/0152.mp3 diff --git a/sd-card/advert/0153.mp3 b/src/sd-card/advert/0153.mp3 similarity index 100% rename from sd-card/advert/0153.mp3 rename to src/sd-card/advert/0153.mp3 diff --git a/sd-card/advert/0154.mp3 b/src/sd-card/advert/0154.mp3 similarity index 100% rename from sd-card/advert/0154.mp3 rename to src/sd-card/advert/0154.mp3 diff --git a/sd-card/advert/0155.mp3 b/src/sd-card/advert/0155.mp3 similarity index 100% rename from sd-card/advert/0155.mp3 rename to src/sd-card/advert/0155.mp3 diff --git a/sd-card/advert/0156.mp3 b/src/sd-card/advert/0156.mp3 similarity index 100% rename from sd-card/advert/0156.mp3 rename to src/sd-card/advert/0156.mp3 diff --git a/sd-card/advert/0157.mp3 b/src/sd-card/advert/0157.mp3 similarity index 100% rename from sd-card/advert/0157.mp3 rename to src/sd-card/advert/0157.mp3 diff --git a/sd-card/advert/0158.mp3 b/src/sd-card/advert/0158.mp3 similarity index 100% rename from sd-card/advert/0158.mp3 rename to src/sd-card/advert/0158.mp3 diff --git a/sd-card/advert/0159.mp3 b/src/sd-card/advert/0159.mp3 similarity index 100% rename from sd-card/advert/0159.mp3 rename to src/sd-card/advert/0159.mp3 diff --git a/sd-card/advert/0160.mp3 b/src/sd-card/advert/0160.mp3 similarity index 100% rename from sd-card/advert/0160.mp3 rename to src/sd-card/advert/0160.mp3 diff --git a/sd-card/advert/0161.mp3 b/src/sd-card/advert/0161.mp3 similarity index 100% rename from sd-card/advert/0161.mp3 rename to src/sd-card/advert/0161.mp3 diff --git a/sd-card/advert/0162.mp3 b/src/sd-card/advert/0162.mp3 similarity index 100% rename from sd-card/advert/0162.mp3 rename to src/sd-card/advert/0162.mp3 diff --git a/sd-card/advert/0163.mp3 b/src/sd-card/advert/0163.mp3 similarity index 100% rename from sd-card/advert/0163.mp3 rename to src/sd-card/advert/0163.mp3 diff --git a/sd-card/advert/0164.mp3 b/src/sd-card/advert/0164.mp3 similarity index 100% rename from sd-card/advert/0164.mp3 rename to src/sd-card/advert/0164.mp3 diff --git a/sd-card/advert/0165.mp3 b/src/sd-card/advert/0165.mp3 similarity index 100% rename from sd-card/advert/0165.mp3 rename to src/sd-card/advert/0165.mp3 diff --git a/sd-card/advert/0166.mp3 b/src/sd-card/advert/0166.mp3 similarity index 100% rename from sd-card/advert/0166.mp3 rename to src/sd-card/advert/0166.mp3 diff --git a/sd-card/advert/0167.mp3 b/src/sd-card/advert/0167.mp3 similarity index 100% rename from sd-card/advert/0167.mp3 rename to src/sd-card/advert/0167.mp3 diff --git a/sd-card/advert/0168.mp3 b/src/sd-card/advert/0168.mp3 similarity index 100% rename from sd-card/advert/0168.mp3 rename to src/sd-card/advert/0168.mp3 diff --git a/sd-card/advert/0169.mp3 b/src/sd-card/advert/0169.mp3 similarity index 100% rename from sd-card/advert/0169.mp3 rename to src/sd-card/advert/0169.mp3 diff --git a/sd-card/advert/0170.mp3 b/src/sd-card/advert/0170.mp3 similarity index 100% rename from sd-card/advert/0170.mp3 rename to src/sd-card/advert/0170.mp3 diff --git a/sd-card/advert/0171.mp3 b/src/sd-card/advert/0171.mp3 similarity index 100% rename from sd-card/advert/0171.mp3 rename to src/sd-card/advert/0171.mp3 diff --git a/sd-card/advert/0172.mp3 b/src/sd-card/advert/0172.mp3 similarity index 100% rename from sd-card/advert/0172.mp3 rename to src/sd-card/advert/0172.mp3 diff --git a/sd-card/advert/0173.mp3 b/src/sd-card/advert/0173.mp3 similarity index 100% rename from sd-card/advert/0173.mp3 rename to src/sd-card/advert/0173.mp3 diff --git a/sd-card/advert/0174.mp3 b/src/sd-card/advert/0174.mp3 similarity index 100% rename from sd-card/advert/0174.mp3 rename to src/sd-card/advert/0174.mp3 diff --git a/sd-card/advert/0175.mp3 b/src/sd-card/advert/0175.mp3 similarity index 100% rename from sd-card/advert/0175.mp3 rename to src/sd-card/advert/0175.mp3 diff --git a/sd-card/advert/0176.mp3 b/src/sd-card/advert/0176.mp3 similarity index 100% rename from sd-card/advert/0176.mp3 rename to src/sd-card/advert/0176.mp3 diff --git a/sd-card/advert/0177.mp3 b/src/sd-card/advert/0177.mp3 similarity index 100% rename from sd-card/advert/0177.mp3 rename to src/sd-card/advert/0177.mp3 diff --git a/sd-card/advert/0178.mp3 b/src/sd-card/advert/0178.mp3 similarity index 100% rename from sd-card/advert/0178.mp3 rename to src/sd-card/advert/0178.mp3 diff --git a/sd-card/advert/0179.mp3 b/src/sd-card/advert/0179.mp3 similarity index 100% rename from sd-card/advert/0179.mp3 rename to src/sd-card/advert/0179.mp3 diff --git a/sd-card/advert/0180.mp3 b/src/sd-card/advert/0180.mp3 similarity index 100% rename from sd-card/advert/0180.mp3 rename to src/sd-card/advert/0180.mp3 diff --git a/sd-card/advert/0181.mp3 b/src/sd-card/advert/0181.mp3 similarity index 100% rename from sd-card/advert/0181.mp3 rename to src/sd-card/advert/0181.mp3 diff --git a/sd-card/advert/0182.mp3 b/src/sd-card/advert/0182.mp3 similarity index 100% rename from sd-card/advert/0182.mp3 rename to src/sd-card/advert/0182.mp3 diff --git a/sd-card/advert/0183.mp3 b/src/sd-card/advert/0183.mp3 similarity index 100% rename from sd-card/advert/0183.mp3 rename to src/sd-card/advert/0183.mp3 diff --git a/sd-card/advert/0184.mp3 b/src/sd-card/advert/0184.mp3 similarity index 100% rename from sd-card/advert/0184.mp3 rename to src/sd-card/advert/0184.mp3 diff --git a/sd-card/advert/0185.mp3 b/src/sd-card/advert/0185.mp3 similarity index 100% rename from sd-card/advert/0185.mp3 rename to src/sd-card/advert/0185.mp3 diff --git a/sd-card/advert/0186.mp3 b/src/sd-card/advert/0186.mp3 similarity index 100% rename from sd-card/advert/0186.mp3 rename to src/sd-card/advert/0186.mp3 diff --git a/sd-card/advert/0187.mp3 b/src/sd-card/advert/0187.mp3 similarity index 100% rename from sd-card/advert/0187.mp3 rename to src/sd-card/advert/0187.mp3 diff --git a/sd-card/advert/0188.mp3 b/src/sd-card/advert/0188.mp3 similarity index 100% rename from sd-card/advert/0188.mp3 rename to src/sd-card/advert/0188.mp3 diff --git a/sd-card/advert/0189.mp3 b/src/sd-card/advert/0189.mp3 similarity index 100% rename from sd-card/advert/0189.mp3 rename to src/sd-card/advert/0189.mp3 diff --git a/sd-card/advert/0190.mp3 b/src/sd-card/advert/0190.mp3 similarity index 100% rename from sd-card/advert/0190.mp3 rename to src/sd-card/advert/0190.mp3 diff --git a/sd-card/advert/0191.mp3 b/src/sd-card/advert/0191.mp3 similarity index 100% rename from sd-card/advert/0191.mp3 rename to src/sd-card/advert/0191.mp3 diff --git a/sd-card/advert/0192.mp3 b/src/sd-card/advert/0192.mp3 similarity index 100% rename from sd-card/advert/0192.mp3 rename to src/sd-card/advert/0192.mp3 diff --git a/sd-card/advert/0193.mp3 b/src/sd-card/advert/0193.mp3 similarity index 100% rename from sd-card/advert/0193.mp3 rename to src/sd-card/advert/0193.mp3 diff --git a/sd-card/advert/0194.mp3 b/src/sd-card/advert/0194.mp3 similarity index 100% rename from sd-card/advert/0194.mp3 rename to src/sd-card/advert/0194.mp3 diff --git a/sd-card/advert/0195.mp3 b/src/sd-card/advert/0195.mp3 similarity index 100% rename from sd-card/advert/0195.mp3 rename to src/sd-card/advert/0195.mp3 diff --git a/sd-card/advert/0196.mp3 b/src/sd-card/advert/0196.mp3 similarity index 100% rename from sd-card/advert/0196.mp3 rename to src/sd-card/advert/0196.mp3 diff --git a/sd-card/advert/0197.mp3 b/src/sd-card/advert/0197.mp3 similarity index 100% rename from sd-card/advert/0197.mp3 rename to src/sd-card/advert/0197.mp3 diff --git a/sd-card/advert/0198.mp3 b/src/sd-card/advert/0198.mp3 similarity index 100% rename from sd-card/advert/0198.mp3 rename to src/sd-card/advert/0198.mp3 diff --git a/sd-card/advert/0199.mp3 b/src/sd-card/advert/0199.mp3 similarity index 100% rename from sd-card/advert/0199.mp3 rename to src/sd-card/advert/0199.mp3 diff --git a/sd-card/advert/0200.mp3 b/src/sd-card/advert/0200.mp3 similarity index 100% rename from sd-card/advert/0200.mp3 rename to src/sd-card/advert/0200.mp3 diff --git a/sd-card/advert/0201.mp3 b/src/sd-card/advert/0201.mp3 similarity index 100% rename from sd-card/advert/0201.mp3 rename to src/sd-card/advert/0201.mp3 diff --git a/sd-card/advert/0202.mp3 b/src/sd-card/advert/0202.mp3 similarity index 100% rename from sd-card/advert/0202.mp3 rename to src/sd-card/advert/0202.mp3 diff --git a/sd-card/advert/0203.mp3 b/src/sd-card/advert/0203.mp3 similarity index 100% rename from sd-card/advert/0203.mp3 rename to src/sd-card/advert/0203.mp3 diff --git a/sd-card/advert/0204.mp3 b/src/sd-card/advert/0204.mp3 similarity index 100% rename from sd-card/advert/0204.mp3 rename to src/sd-card/advert/0204.mp3 diff --git a/sd-card/advert/0205.mp3 b/src/sd-card/advert/0205.mp3 similarity index 100% rename from sd-card/advert/0205.mp3 rename to src/sd-card/advert/0205.mp3 diff --git a/sd-card/advert/0206.mp3 b/src/sd-card/advert/0206.mp3 similarity index 100% rename from sd-card/advert/0206.mp3 rename to src/sd-card/advert/0206.mp3 diff --git a/sd-card/advert/0207.mp3 b/src/sd-card/advert/0207.mp3 similarity index 100% rename from sd-card/advert/0207.mp3 rename to src/sd-card/advert/0207.mp3 diff --git a/sd-card/advert/0208.mp3 b/src/sd-card/advert/0208.mp3 similarity index 100% rename from sd-card/advert/0208.mp3 rename to src/sd-card/advert/0208.mp3 diff --git a/sd-card/advert/0209.mp3 b/src/sd-card/advert/0209.mp3 similarity index 100% rename from sd-card/advert/0209.mp3 rename to src/sd-card/advert/0209.mp3 diff --git a/sd-card/advert/0210.mp3 b/src/sd-card/advert/0210.mp3 similarity index 100% rename from sd-card/advert/0210.mp3 rename to src/sd-card/advert/0210.mp3 diff --git a/sd-card/advert/0211.mp3 b/src/sd-card/advert/0211.mp3 similarity index 100% rename from sd-card/advert/0211.mp3 rename to src/sd-card/advert/0211.mp3 diff --git a/sd-card/advert/0212.mp3 b/src/sd-card/advert/0212.mp3 similarity index 100% rename from sd-card/advert/0212.mp3 rename to src/sd-card/advert/0212.mp3 diff --git a/sd-card/advert/0213.mp3 b/src/sd-card/advert/0213.mp3 similarity index 100% rename from sd-card/advert/0213.mp3 rename to src/sd-card/advert/0213.mp3 diff --git a/sd-card/advert/0214.mp3 b/src/sd-card/advert/0214.mp3 similarity index 100% rename from sd-card/advert/0214.mp3 rename to src/sd-card/advert/0214.mp3 diff --git a/sd-card/advert/0215.mp3 b/src/sd-card/advert/0215.mp3 similarity index 100% rename from sd-card/advert/0215.mp3 rename to src/sd-card/advert/0215.mp3 diff --git a/sd-card/advert/0216.mp3 b/src/sd-card/advert/0216.mp3 similarity index 100% rename from sd-card/advert/0216.mp3 rename to src/sd-card/advert/0216.mp3 diff --git a/sd-card/advert/0217.mp3 b/src/sd-card/advert/0217.mp3 similarity index 100% rename from sd-card/advert/0217.mp3 rename to src/sd-card/advert/0217.mp3 diff --git a/sd-card/advert/0218.mp3 b/src/sd-card/advert/0218.mp3 similarity index 100% rename from sd-card/advert/0218.mp3 rename to src/sd-card/advert/0218.mp3 diff --git a/sd-card/advert/0219.mp3 b/src/sd-card/advert/0219.mp3 similarity index 100% rename from sd-card/advert/0219.mp3 rename to src/sd-card/advert/0219.mp3 diff --git a/sd-card/advert/0220.mp3 b/src/sd-card/advert/0220.mp3 similarity index 100% rename from sd-card/advert/0220.mp3 rename to src/sd-card/advert/0220.mp3 diff --git a/sd-card/advert/0221.mp3 b/src/sd-card/advert/0221.mp3 similarity index 100% rename from sd-card/advert/0221.mp3 rename to src/sd-card/advert/0221.mp3 diff --git a/sd-card/advert/0222.mp3 b/src/sd-card/advert/0222.mp3 similarity index 100% rename from sd-card/advert/0222.mp3 rename to src/sd-card/advert/0222.mp3 diff --git a/sd-card/advert/0223.mp3 b/src/sd-card/advert/0223.mp3 similarity index 100% rename from sd-card/advert/0223.mp3 rename to src/sd-card/advert/0223.mp3 diff --git a/sd-card/advert/0224.mp3 b/src/sd-card/advert/0224.mp3 similarity index 100% rename from sd-card/advert/0224.mp3 rename to src/sd-card/advert/0224.mp3 diff --git a/sd-card/advert/0225.mp3 b/src/sd-card/advert/0225.mp3 similarity index 100% rename from sd-card/advert/0225.mp3 rename to src/sd-card/advert/0225.mp3 diff --git a/sd-card/advert/0226.mp3 b/src/sd-card/advert/0226.mp3 similarity index 100% rename from sd-card/advert/0226.mp3 rename to src/sd-card/advert/0226.mp3 diff --git a/sd-card/advert/0227.mp3 b/src/sd-card/advert/0227.mp3 similarity index 100% rename from sd-card/advert/0227.mp3 rename to src/sd-card/advert/0227.mp3 diff --git a/sd-card/advert/0228.mp3 b/src/sd-card/advert/0228.mp3 similarity index 100% rename from sd-card/advert/0228.mp3 rename to src/sd-card/advert/0228.mp3 diff --git a/sd-card/advert/0229.mp3 b/src/sd-card/advert/0229.mp3 similarity index 100% rename from sd-card/advert/0229.mp3 rename to src/sd-card/advert/0229.mp3 diff --git a/sd-card/advert/0230.mp3 b/src/sd-card/advert/0230.mp3 similarity index 100% rename from sd-card/advert/0230.mp3 rename to src/sd-card/advert/0230.mp3 diff --git a/sd-card/advert/0231.mp3 b/src/sd-card/advert/0231.mp3 similarity index 100% rename from sd-card/advert/0231.mp3 rename to src/sd-card/advert/0231.mp3 diff --git a/sd-card/advert/0232.mp3 b/src/sd-card/advert/0232.mp3 similarity index 100% rename from sd-card/advert/0232.mp3 rename to src/sd-card/advert/0232.mp3 diff --git a/sd-card/advert/0233.mp3 b/src/sd-card/advert/0233.mp3 similarity index 100% rename from sd-card/advert/0233.mp3 rename to src/sd-card/advert/0233.mp3 diff --git a/sd-card/advert/0234.mp3 b/src/sd-card/advert/0234.mp3 similarity index 100% rename from sd-card/advert/0234.mp3 rename to src/sd-card/advert/0234.mp3 diff --git a/sd-card/advert/0235.mp3 b/src/sd-card/advert/0235.mp3 similarity index 100% rename from sd-card/advert/0235.mp3 rename to src/sd-card/advert/0235.mp3 diff --git a/sd-card/advert/0236.mp3 b/src/sd-card/advert/0236.mp3 similarity index 100% rename from sd-card/advert/0236.mp3 rename to src/sd-card/advert/0236.mp3 diff --git a/sd-card/advert/0237.mp3 b/src/sd-card/advert/0237.mp3 similarity index 100% rename from sd-card/advert/0237.mp3 rename to src/sd-card/advert/0237.mp3 diff --git a/sd-card/advert/0238.mp3 b/src/sd-card/advert/0238.mp3 similarity index 100% rename from sd-card/advert/0238.mp3 rename to src/sd-card/advert/0238.mp3 diff --git a/sd-card/advert/0239.mp3 b/src/sd-card/advert/0239.mp3 similarity index 100% rename from sd-card/advert/0239.mp3 rename to src/sd-card/advert/0239.mp3 diff --git a/sd-card/advert/0240.mp3 b/src/sd-card/advert/0240.mp3 similarity index 100% rename from sd-card/advert/0240.mp3 rename to src/sd-card/advert/0240.mp3 diff --git a/sd-card/advert/0241.mp3 b/src/sd-card/advert/0241.mp3 similarity index 100% rename from sd-card/advert/0241.mp3 rename to src/sd-card/advert/0241.mp3 diff --git a/sd-card/advert/0242.mp3 b/src/sd-card/advert/0242.mp3 similarity index 100% rename from sd-card/advert/0242.mp3 rename to src/sd-card/advert/0242.mp3 diff --git a/sd-card/advert/0243.mp3 b/src/sd-card/advert/0243.mp3 similarity index 100% rename from sd-card/advert/0243.mp3 rename to src/sd-card/advert/0243.mp3 diff --git a/sd-card/advert/0244.mp3 b/src/sd-card/advert/0244.mp3 similarity index 100% rename from sd-card/advert/0244.mp3 rename to src/sd-card/advert/0244.mp3 diff --git a/sd-card/advert/0245.mp3 b/src/sd-card/advert/0245.mp3 similarity index 100% rename from sd-card/advert/0245.mp3 rename to src/sd-card/advert/0245.mp3 diff --git a/sd-card/advert/0246.mp3 b/src/sd-card/advert/0246.mp3 similarity index 100% rename from sd-card/advert/0246.mp3 rename to src/sd-card/advert/0246.mp3 diff --git a/sd-card/advert/0247.mp3 b/src/sd-card/advert/0247.mp3 similarity index 100% rename from sd-card/advert/0247.mp3 rename to src/sd-card/advert/0247.mp3 diff --git a/sd-card/advert/0248.mp3 b/src/sd-card/advert/0248.mp3 similarity index 100% rename from sd-card/advert/0248.mp3 rename to src/sd-card/advert/0248.mp3 diff --git a/sd-card/advert/0249.mp3 b/src/sd-card/advert/0249.mp3 similarity index 100% rename from sd-card/advert/0249.mp3 rename to src/sd-card/advert/0249.mp3 diff --git a/sd-card/advert/0250.mp3 b/src/sd-card/advert/0250.mp3 similarity index 100% rename from sd-card/advert/0250.mp3 rename to src/sd-card/advert/0250.mp3 diff --git a/sd-card/advert/0251.mp3 b/src/sd-card/advert/0251.mp3 similarity index 100% rename from sd-card/advert/0251.mp3 rename to src/sd-card/advert/0251.mp3 diff --git a/sd-card/advert/0252.mp3 b/src/sd-card/advert/0252.mp3 similarity index 100% rename from sd-card/advert/0252.mp3 rename to src/sd-card/advert/0252.mp3 diff --git a/sd-card/advert/0253.mp3 b/src/sd-card/advert/0253.mp3 similarity index 100% rename from sd-card/advert/0253.mp3 rename to src/sd-card/advert/0253.mp3 diff --git a/sd-card/advert/0254.mp3 b/src/sd-card/advert/0254.mp3 similarity index 100% rename from sd-card/advert/0254.mp3 rename to src/sd-card/advert/0254.mp3 diff --git a/sd-card/advert/0255.mp3 b/src/sd-card/advert/0255.mp3 similarity index 100% rename from sd-card/advert/0255.mp3 rename to src/sd-card/advert/0255.mp3 diff --git a/sd-card/advert/0260.mp3 b/src/sd-card/advert/0260.mp3 similarity index 100% rename from sd-card/advert/0260.mp3 rename to src/sd-card/advert/0260.mp3 diff --git a/sd-card/advert/0261.mp3 b/src/sd-card/advert/0261.mp3 similarity index 100% rename from sd-card/advert/0261.mp3 rename to src/sd-card/advert/0261.mp3 diff --git a/sd-card/advert/0300_freeze_into.mp3 b/src/sd-card/advert/0300_freeze_into.mp3 similarity index 100% rename from sd-card/advert/0300_freeze_into.mp3 rename to src/sd-card/advert/0300_freeze_into.mp3 diff --git a/sd-card/advert/0301_freeze_freeze.mp3 b/src/sd-card/advert/0301_freeze_freeze.mp3 similarity index 100% rename from sd-card/advert/0301_freeze_freeze.mp3 rename to src/sd-card/advert/0301_freeze_freeze.mp3 diff --git a/sd-card/advert/0302_sleep.mp3 b/src/sd-card/advert/0302_sleep.mp3 similarity index 100% rename from sd-card/advert/0302_sleep.mp3 rename to src/sd-card/advert/0302_sleep.mp3 diff --git a/sd-card/advert/0303_locked.mp3 b/src/sd-card/advert/0303_locked.mp3 similarity index 100% rename from sd-card/advert/0303_locked.mp3 rename to src/sd-card/advert/0303_locked.mp3 diff --git a/sd-card/advert/0304_buttonslocked.mp3 b/src/sd-card/advert/0304_buttonslocked.mp3 similarity index 100% rename from sd-card/advert/0304_buttonslocked.mp3 rename to src/sd-card/advert/0304_buttonslocked.mp3 diff --git a/sd-card/advert/0305_kindergarden.mp3 b/src/sd-card/advert/0305_kindergarden.mp3 similarity index 100% rename from sd-card/advert/0305_kindergarden.mp3 rename to src/sd-card/advert/0305_kindergarden.mp3 diff --git a/sd-card/mp3/0001.mp3 b/src/sd-card/mp3/0001.mp3 similarity index 100% rename from sd-card/mp3/0001.mp3 rename to src/sd-card/mp3/0001.mp3 diff --git a/sd-card/mp3/0002.mp3 b/src/sd-card/mp3/0002.mp3 similarity index 100% rename from sd-card/mp3/0002.mp3 rename to src/sd-card/mp3/0002.mp3 diff --git a/sd-card/mp3/0003.mp3 b/src/sd-card/mp3/0003.mp3 similarity index 100% rename from sd-card/mp3/0003.mp3 rename to src/sd-card/mp3/0003.mp3 diff --git a/sd-card/mp3/0004.mp3 b/src/sd-card/mp3/0004.mp3 similarity index 100% rename from sd-card/mp3/0004.mp3 rename to src/sd-card/mp3/0004.mp3 diff --git a/sd-card/mp3/0005.mp3 b/src/sd-card/mp3/0005.mp3 similarity index 100% rename from sd-card/mp3/0005.mp3 rename to src/sd-card/mp3/0005.mp3 diff --git a/sd-card/mp3/0006.mp3 b/src/sd-card/mp3/0006.mp3 similarity index 100% rename from sd-card/mp3/0006.mp3 rename to src/sd-card/mp3/0006.mp3 diff --git a/sd-card/mp3/0007.mp3 b/src/sd-card/mp3/0007.mp3 similarity index 100% rename from sd-card/mp3/0007.mp3 rename to src/sd-card/mp3/0007.mp3 diff --git a/sd-card/mp3/0008.mp3 b/src/sd-card/mp3/0008.mp3 similarity index 100% rename from sd-card/mp3/0008.mp3 rename to src/sd-card/mp3/0008.mp3 diff --git a/sd-card/mp3/0009.mp3 b/src/sd-card/mp3/0009.mp3 similarity index 100% rename from sd-card/mp3/0009.mp3 rename to src/sd-card/mp3/0009.mp3 diff --git a/sd-card/mp3/0010.mp3 b/src/sd-card/mp3/0010.mp3 similarity index 100% rename from sd-card/mp3/0010.mp3 rename to src/sd-card/mp3/0010.mp3 diff --git a/sd-card/mp3/0011.mp3 b/src/sd-card/mp3/0011.mp3 similarity index 100% rename from sd-card/mp3/0011.mp3 rename to src/sd-card/mp3/0011.mp3 diff --git a/sd-card/mp3/0012.mp3 b/src/sd-card/mp3/0012.mp3 similarity index 100% rename from sd-card/mp3/0012.mp3 rename to src/sd-card/mp3/0012.mp3 diff --git a/sd-card/mp3/0013.mp3 b/src/sd-card/mp3/0013.mp3 similarity index 100% rename from sd-card/mp3/0013.mp3 rename to src/sd-card/mp3/0013.mp3 diff --git a/sd-card/mp3/0014.mp3 b/src/sd-card/mp3/0014.mp3 similarity index 100% rename from sd-card/mp3/0014.mp3 rename to src/sd-card/mp3/0014.mp3 diff --git a/sd-card/mp3/0015.mp3 b/src/sd-card/mp3/0015.mp3 similarity index 100% rename from sd-card/mp3/0015.mp3 rename to src/sd-card/mp3/0015.mp3 diff --git a/sd-card/mp3/0016.mp3 b/src/sd-card/mp3/0016.mp3 similarity index 100% rename from sd-card/mp3/0016.mp3 rename to src/sd-card/mp3/0016.mp3 diff --git a/sd-card/mp3/0017.mp3 b/src/sd-card/mp3/0017.mp3 similarity index 100% rename from sd-card/mp3/0017.mp3 rename to src/sd-card/mp3/0017.mp3 diff --git a/sd-card/mp3/0018.mp3 b/src/sd-card/mp3/0018.mp3 similarity index 100% rename from sd-card/mp3/0018.mp3 rename to src/sd-card/mp3/0018.mp3 diff --git a/sd-card/mp3/0019.mp3 b/src/sd-card/mp3/0019.mp3 similarity index 100% rename from sd-card/mp3/0019.mp3 rename to src/sd-card/mp3/0019.mp3 diff --git a/sd-card/mp3/0020.mp3 b/src/sd-card/mp3/0020.mp3 similarity index 100% rename from sd-card/mp3/0020.mp3 rename to src/sd-card/mp3/0020.mp3 diff --git a/sd-card/mp3/0021.mp3 b/src/sd-card/mp3/0021.mp3 similarity index 100% rename from sd-card/mp3/0021.mp3 rename to src/sd-card/mp3/0021.mp3 diff --git a/sd-card/mp3/0022.mp3 b/src/sd-card/mp3/0022.mp3 similarity index 100% rename from sd-card/mp3/0022.mp3 rename to src/sd-card/mp3/0022.mp3 diff --git a/sd-card/mp3/0023.mp3 b/src/sd-card/mp3/0023.mp3 similarity index 100% rename from sd-card/mp3/0023.mp3 rename to src/sd-card/mp3/0023.mp3 diff --git a/sd-card/mp3/0024.mp3 b/src/sd-card/mp3/0024.mp3 similarity index 100% rename from sd-card/mp3/0024.mp3 rename to src/sd-card/mp3/0024.mp3 diff --git a/sd-card/mp3/0025.mp3 b/src/sd-card/mp3/0025.mp3 similarity index 100% rename from sd-card/mp3/0025.mp3 rename to src/sd-card/mp3/0025.mp3 diff --git a/sd-card/mp3/0026.mp3 b/src/sd-card/mp3/0026.mp3 similarity index 100% rename from sd-card/mp3/0026.mp3 rename to src/sd-card/mp3/0026.mp3 diff --git a/sd-card/mp3/0027.mp3 b/src/sd-card/mp3/0027.mp3 similarity index 100% rename from sd-card/mp3/0027.mp3 rename to src/sd-card/mp3/0027.mp3 diff --git a/sd-card/mp3/0028.mp3 b/src/sd-card/mp3/0028.mp3 similarity index 100% rename from sd-card/mp3/0028.mp3 rename to src/sd-card/mp3/0028.mp3 diff --git a/sd-card/mp3/0029.mp3 b/src/sd-card/mp3/0029.mp3 similarity index 100% rename from sd-card/mp3/0029.mp3 rename to src/sd-card/mp3/0029.mp3 diff --git a/sd-card/mp3/0030.mp3 b/src/sd-card/mp3/0030.mp3 similarity index 100% rename from sd-card/mp3/0030.mp3 rename to src/sd-card/mp3/0030.mp3 diff --git a/sd-card/mp3/0031.mp3 b/src/sd-card/mp3/0031.mp3 similarity index 100% rename from sd-card/mp3/0031.mp3 rename to src/sd-card/mp3/0031.mp3 diff --git a/sd-card/mp3/0032.mp3 b/src/sd-card/mp3/0032.mp3 similarity index 100% rename from sd-card/mp3/0032.mp3 rename to src/sd-card/mp3/0032.mp3 diff --git a/sd-card/mp3/0033.mp3 b/src/sd-card/mp3/0033.mp3 similarity index 100% rename from sd-card/mp3/0033.mp3 rename to src/sd-card/mp3/0033.mp3 diff --git a/sd-card/mp3/0034.mp3 b/src/sd-card/mp3/0034.mp3 similarity index 100% rename from sd-card/mp3/0034.mp3 rename to src/sd-card/mp3/0034.mp3 diff --git a/sd-card/mp3/0035.mp3 b/src/sd-card/mp3/0035.mp3 similarity index 100% rename from sd-card/mp3/0035.mp3 rename to src/sd-card/mp3/0035.mp3 diff --git a/sd-card/mp3/0036.mp3 b/src/sd-card/mp3/0036.mp3 similarity index 100% rename from sd-card/mp3/0036.mp3 rename to src/sd-card/mp3/0036.mp3 diff --git a/sd-card/mp3/0037.mp3 b/src/sd-card/mp3/0037.mp3 similarity index 100% rename from sd-card/mp3/0037.mp3 rename to src/sd-card/mp3/0037.mp3 diff --git a/sd-card/mp3/0038.mp3 b/src/sd-card/mp3/0038.mp3 similarity index 100% rename from sd-card/mp3/0038.mp3 rename to src/sd-card/mp3/0038.mp3 diff --git a/sd-card/mp3/0039.mp3 b/src/sd-card/mp3/0039.mp3 similarity index 100% rename from sd-card/mp3/0039.mp3 rename to src/sd-card/mp3/0039.mp3 diff --git a/sd-card/mp3/0040.mp3 b/src/sd-card/mp3/0040.mp3 similarity index 100% rename from sd-card/mp3/0040.mp3 rename to src/sd-card/mp3/0040.mp3 diff --git a/sd-card/mp3/0041.mp3 b/src/sd-card/mp3/0041.mp3 similarity index 100% rename from sd-card/mp3/0041.mp3 rename to src/sd-card/mp3/0041.mp3 diff --git a/sd-card/mp3/0042.mp3 b/src/sd-card/mp3/0042.mp3 similarity index 100% rename from sd-card/mp3/0042.mp3 rename to src/sd-card/mp3/0042.mp3 diff --git a/sd-card/mp3/0043.mp3 b/src/sd-card/mp3/0043.mp3 similarity index 100% rename from sd-card/mp3/0043.mp3 rename to src/sd-card/mp3/0043.mp3 diff --git a/sd-card/mp3/0044.mp3 b/src/sd-card/mp3/0044.mp3 similarity index 100% rename from sd-card/mp3/0044.mp3 rename to src/sd-card/mp3/0044.mp3 diff --git a/sd-card/mp3/0045.mp3 b/src/sd-card/mp3/0045.mp3 similarity index 100% rename from sd-card/mp3/0045.mp3 rename to src/sd-card/mp3/0045.mp3 diff --git a/sd-card/mp3/0046.mp3 b/src/sd-card/mp3/0046.mp3 similarity index 100% rename from sd-card/mp3/0046.mp3 rename to src/sd-card/mp3/0046.mp3 diff --git a/sd-card/mp3/0047.mp3 b/src/sd-card/mp3/0047.mp3 similarity index 100% rename from sd-card/mp3/0047.mp3 rename to src/sd-card/mp3/0047.mp3 diff --git a/sd-card/mp3/0048.mp3 b/src/sd-card/mp3/0048.mp3 similarity index 100% rename from sd-card/mp3/0048.mp3 rename to src/sd-card/mp3/0048.mp3 diff --git a/sd-card/mp3/0049.mp3 b/src/sd-card/mp3/0049.mp3 similarity index 100% rename from sd-card/mp3/0049.mp3 rename to src/sd-card/mp3/0049.mp3 diff --git a/sd-card/mp3/0050.mp3 b/src/sd-card/mp3/0050.mp3 similarity index 100% rename from sd-card/mp3/0050.mp3 rename to src/sd-card/mp3/0050.mp3 diff --git a/sd-card/mp3/0051.mp3 b/src/sd-card/mp3/0051.mp3 similarity index 100% rename from sd-card/mp3/0051.mp3 rename to src/sd-card/mp3/0051.mp3 diff --git a/sd-card/mp3/0052.mp3 b/src/sd-card/mp3/0052.mp3 similarity index 100% rename from sd-card/mp3/0052.mp3 rename to src/sd-card/mp3/0052.mp3 diff --git a/sd-card/mp3/0053.mp3 b/src/sd-card/mp3/0053.mp3 similarity index 100% rename from sd-card/mp3/0053.mp3 rename to src/sd-card/mp3/0053.mp3 diff --git a/sd-card/mp3/0054.mp3 b/src/sd-card/mp3/0054.mp3 similarity index 100% rename from sd-card/mp3/0054.mp3 rename to src/sd-card/mp3/0054.mp3 diff --git a/sd-card/mp3/0055.mp3 b/src/sd-card/mp3/0055.mp3 similarity index 100% rename from sd-card/mp3/0055.mp3 rename to src/sd-card/mp3/0055.mp3 diff --git a/sd-card/mp3/0056.mp3 b/src/sd-card/mp3/0056.mp3 similarity index 100% rename from sd-card/mp3/0056.mp3 rename to src/sd-card/mp3/0056.mp3 diff --git a/sd-card/mp3/0057.mp3 b/src/sd-card/mp3/0057.mp3 similarity index 100% rename from sd-card/mp3/0057.mp3 rename to src/sd-card/mp3/0057.mp3 diff --git a/sd-card/mp3/0058.mp3 b/src/sd-card/mp3/0058.mp3 similarity index 100% rename from sd-card/mp3/0058.mp3 rename to src/sd-card/mp3/0058.mp3 diff --git a/sd-card/mp3/0059.mp3 b/src/sd-card/mp3/0059.mp3 similarity index 100% rename from sd-card/mp3/0059.mp3 rename to src/sd-card/mp3/0059.mp3 diff --git a/sd-card/mp3/0060.mp3 b/src/sd-card/mp3/0060.mp3 similarity index 100% rename from sd-card/mp3/0060.mp3 rename to src/sd-card/mp3/0060.mp3 diff --git a/sd-card/mp3/0061.mp3 b/src/sd-card/mp3/0061.mp3 similarity index 100% rename from sd-card/mp3/0061.mp3 rename to src/sd-card/mp3/0061.mp3 diff --git a/sd-card/mp3/0062.mp3 b/src/sd-card/mp3/0062.mp3 similarity index 100% rename from sd-card/mp3/0062.mp3 rename to src/sd-card/mp3/0062.mp3 diff --git a/sd-card/mp3/0063.mp3 b/src/sd-card/mp3/0063.mp3 similarity index 100% rename from sd-card/mp3/0063.mp3 rename to src/sd-card/mp3/0063.mp3 diff --git a/sd-card/mp3/0064.mp3 b/src/sd-card/mp3/0064.mp3 similarity index 100% rename from sd-card/mp3/0064.mp3 rename to src/sd-card/mp3/0064.mp3 diff --git a/sd-card/mp3/0065.mp3 b/src/sd-card/mp3/0065.mp3 similarity index 100% rename from sd-card/mp3/0065.mp3 rename to src/sd-card/mp3/0065.mp3 diff --git a/sd-card/mp3/0066.mp3 b/src/sd-card/mp3/0066.mp3 similarity index 100% rename from sd-card/mp3/0066.mp3 rename to src/sd-card/mp3/0066.mp3 diff --git a/sd-card/mp3/0067.mp3 b/src/sd-card/mp3/0067.mp3 similarity index 100% rename from sd-card/mp3/0067.mp3 rename to src/sd-card/mp3/0067.mp3 diff --git a/sd-card/mp3/0068.mp3 b/src/sd-card/mp3/0068.mp3 similarity index 100% rename from sd-card/mp3/0068.mp3 rename to src/sd-card/mp3/0068.mp3 diff --git a/sd-card/mp3/0069.mp3 b/src/sd-card/mp3/0069.mp3 similarity index 100% rename from sd-card/mp3/0069.mp3 rename to src/sd-card/mp3/0069.mp3 diff --git a/sd-card/mp3/0070.mp3 b/src/sd-card/mp3/0070.mp3 similarity index 100% rename from sd-card/mp3/0070.mp3 rename to src/sd-card/mp3/0070.mp3 diff --git a/sd-card/mp3/0071.mp3 b/src/sd-card/mp3/0071.mp3 similarity index 100% rename from sd-card/mp3/0071.mp3 rename to src/sd-card/mp3/0071.mp3 diff --git a/sd-card/mp3/0072.mp3 b/src/sd-card/mp3/0072.mp3 similarity index 100% rename from sd-card/mp3/0072.mp3 rename to src/sd-card/mp3/0072.mp3 diff --git a/sd-card/mp3/0073.mp3 b/src/sd-card/mp3/0073.mp3 similarity index 100% rename from sd-card/mp3/0073.mp3 rename to src/sd-card/mp3/0073.mp3 diff --git a/sd-card/mp3/0074.mp3 b/src/sd-card/mp3/0074.mp3 similarity index 100% rename from sd-card/mp3/0074.mp3 rename to src/sd-card/mp3/0074.mp3 diff --git a/sd-card/mp3/0075.mp3 b/src/sd-card/mp3/0075.mp3 similarity index 100% rename from sd-card/mp3/0075.mp3 rename to src/sd-card/mp3/0075.mp3 diff --git a/sd-card/mp3/0076.mp3 b/src/sd-card/mp3/0076.mp3 similarity index 100% rename from sd-card/mp3/0076.mp3 rename to src/sd-card/mp3/0076.mp3 diff --git a/sd-card/mp3/0077.mp3 b/src/sd-card/mp3/0077.mp3 similarity index 100% rename from sd-card/mp3/0077.mp3 rename to src/sd-card/mp3/0077.mp3 diff --git a/sd-card/mp3/0078.mp3 b/src/sd-card/mp3/0078.mp3 similarity index 100% rename from sd-card/mp3/0078.mp3 rename to src/sd-card/mp3/0078.mp3 diff --git a/sd-card/mp3/0079.mp3 b/src/sd-card/mp3/0079.mp3 similarity index 100% rename from sd-card/mp3/0079.mp3 rename to src/sd-card/mp3/0079.mp3 diff --git a/sd-card/mp3/0080.mp3 b/src/sd-card/mp3/0080.mp3 similarity index 100% rename from sd-card/mp3/0080.mp3 rename to src/sd-card/mp3/0080.mp3 diff --git a/sd-card/mp3/0081.mp3 b/src/sd-card/mp3/0081.mp3 similarity index 100% rename from sd-card/mp3/0081.mp3 rename to src/sd-card/mp3/0081.mp3 diff --git a/sd-card/mp3/0082.mp3 b/src/sd-card/mp3/0082.mp3 similarity index 100% rename from sd-card/mp3/0082.mp3 rename to src/sd-card/mp3/0082.mp3 diff --git a/sd-card/mp3/0083.mp3 b/src/sd-card/mp3/0083.mp3 similarity index 100% rename from sd-card/mp3/0083.mp3 rename to src/sd-card/mp3/0083.mp3 diff --git a/sd-card/mp3/0084.mp3 b/src/sd-card/mp3/0084.mp3 similarity index 100% rename from sd-card/mp3/0084.mp3 rename to src/sd-card/mp3/0084.mp3 diff --git a/sd-card/mp3/0085.mp3 b/src/sd-card/mp3/0085.mp3 similarity index 100% rename from sd-card/mp3/0085.mp3 rename to src/sd-card/mp3/0085.mp3 diff --git a/sd-card/mp3/0086.mp3 b/src/sd-card/mp3/0086.mp3 similarity index 100% rename from sd-card/mp3/0086.mp3 rename to src/sd-card/mp3/0086.mp3 diff --git a/sd-card/mp3/0087.mp3 b/src/sd-card/mp3/0087.mp3 similarity index 100% rename from sd-card/mp3/0087.mp3 rename to src/sd-card/mp3/0087.mp3 diff --git a/sd-card/mp3/0088.mp3 b/src/sd-card/mp3/0088.mp3 similarity index 100% rename from sd-card/mp3/0088.mp3 rename to src/sd-card/mp3/0088.mp3 diff --git a/sd-card/mp3/0089.mp3 b/src/sd-card/mp3/0089.mp3 similarity index 100% rename from sd-card/mp3/0089.mp3 rename to src/sd-card/mp3/0089.mp3 diff --git a/sd-card/mp3/0090.mp3 b/src/sd-card/mp3/0090.mp3 similarity index 100% rename from sd-card/mp3/0090.mp3 rename to src/sd-card/mp3/0090.mp3 diff --git a/sd-card/mp3/0091.mp3 b/src/sd-card/mp3/0091.mp3 similarity index 100% rename from sd-card/mp3/0091.mp3 rename to src/sd-card/mp3/0091.mp3 diff --git a/sd-card/mp3/0092.mp3 b/src/sd-card/mp3/0092.mp3 similarity index 100% rename from sd-card/mp3/0092.mp3 rename to src/sd-card/mp3/0092.mp3 diff --git a/sd-card/mp3/0093.mp3 b/src/sd-card/mp3/0093.mp3 similarity index 100% rename from sd-card/mp3/0093.mp3 rename to src/sd-card/mp3/0093.mp3 diff --git a/sd-card/mp3/0094.mp3 b/src/sd-card/mp3/0094.mp3 similarity index 100% rename from sd-card/mp3/0094.mp3 rename to src/sd-card/mp3/0094.mp3 diff --git a/sd-card/mp3/0095.mp3 b/src/sd-card/mp3/0095.mp3 similarity index 100% rename from sd-card/mp3/0095.mp3 rename to src/sd-card/mp3/0095.mp3 diff --git a/sd-card/mp3/0096.mp3 b/src/sd-card/mp3/0096.mp3 similarity index 100% rename from sd-card/mp3/0096.mp3 rename to src/sd-card/mp3/0096.mp3 diff --git a/sd-card/mp3/0097.mp3 b/src/sd-card/mp3/0097.mp3 similarity index 100% rename from sd-card/mp3/0097.mp3 rename to src/sd-card/mp3/0097.mp3 diff --git a/sd-card/mp3/0098.mp3 b/src/sd-card/mp3/0098.mp3 similarity index 100% rename from sd-card/mp3/0098.mp3 rename to src/sd-card/mp3/0098.mp3 diff --git a/sd-card/mp3/0099.mp3 b/src/sd-card/mp3/0099.mp3 similarity index 100% rename from sd-card/mp3/0099.mp3 rename to src/sd-card/mp3/0099.mp3 diff --git a/sd-card/mp3/0100.mp3 b/src/sd-card/mp3/0100.mp3 similarity index 100% rename from sd-card/mp3/0100.mp3 rename to src/sd-card/mp3/0100.mp3 diff --git a/sd-card/mp3/0101.mp3 b/src/sd-card/mp3/0101.mp3 similarity index 100% rename from sd-card/mp3/0101.mp3 rename to src/sd-card/mp3/0101.mp3 diff --git a/sd-card/mp3/0102.mp3 b/src/sd-card/mp3/0102.mp3 similarity index 100% rename from sd-card/mp3/0102.mp3 rename to src/sd-card/mp3/0102.mp3 diff --git a/sd-card/mp3/0103.mp3 b/src/sd-card/mp3/0103.mp3 similarity index 100% rename from sd-card/mp3/0103.mp3 rename to src/sd-card/mp3/0103.mp3 diff --git a/sd-card/mp3/0104.mp3 b/src/sd-card/mp3/0104.mp3 similarity index 100% rename from sd-card/mp3/0104.mp3 rename to src/sd-card/mp3/0104.mp3 diff --git a/sd-card/mp3/0105.mp3 b/src/sd-card/mp3/0105.mp3 similarity index 100% rename from sd-card/mp3/0105.mp3 rename to src/sd-card/mp3/0105.mp3 diff --git a/sd-card/mp3/0106.mp3 b/src/sd-card/mp3/0106.mp3 similarity index 100% rename from sd-card/mp3/0106.mp3 rename to src/sd-card/mp3/0106.mp3 diff --git a/sd-card/mp3/0107.mp3 b/src/sd-card/mp3/0107.mp3 similarity index 100% rename from sd-card/mp3/0107.mp3 rename to src/sd-card/mp3/0107.mp3 diff --git a/sd-card/mp3/0108.mp3 b/src/sd-card/mp3/0108.mp3 similarity index 100% rename from sd-card/mp3/0108.mp3 rename to src/sd-card/mp3/0108.mp3 diff --git a/sd-card/mp3/0109.mp3 b/src/sd-card/mp3/0109.mp3 similarity index 100% rename from sd-card/mp3/0109.mp3 rename to src/sd-card/mp3/0109.mp3 diff --git a/sd-card/mp3/0110.mp3 b/src/sd-card/mp3/0110.mp3 similarity index 100% rename from sd-card/mp3/0110.mp3 rename to src/sd-card/mp3/0110.mp3 diff --git a/sd-card/mp3/0111.mp3 b/src/sd-card/mp3/0111.mp3 similarity index 100% rename from sd-card/mp3/0111.mp3 rename to src/sd-card/mp3/0111.mp3 diff --git a/sd-card/mp3/0112.mp3 b/src/sd-card/mp3/0112.mp3 similarity index 100% rename from sd-card/mp3/0112.mp3 rename to src/sd-card/mp3/0112.mp3 diff --git a/sd-card/mp3/0113.mp3 b/src/sd-card/mp3/0113.mp3 similarity index 100% rename from sd-card/mp3/0113.mp3 rename to src/sd-card/mp3/0113.mp3 diff --git a/sd-card/mp3/0114.mp3 b/src/sd-card/mp3/0114.mp3 similarity index 100% rename from sd-card/mp3/0114.mp3 rename to src/sd-card/mp3/0114.mp3 diff --git a/sd-card/mp3/0115.mp3 b/src/sd-card/mp3/0115.mp3 similarity index 100% rename from sd-card/mp3/0115.mp3 rename to src/sd-card/mp3/0115.mp3 diff --git a/sd-card/mp3/0116.mp3 b/src/sd-card/mp3/0116.mp3 similarity index 100% rename from sd-card/mp3/0116.mp3 rename to src/sd-card/mp3/0116.mp3 diff --git a/sd-card/mp3/0117.mp3 b/src/sd-card/mp3/0117.mp3 similarity index 100% rename from sd-card/mp3/0117.mp3 rename to src/sd-card/mp3/0117.mp3 diff --git a/sd-card/mp3/0118.mp3 b/src/sd-card/mp3/0118.mp3 similarity index 100% rename from sd-card/mp3/0118.mp3 rename to src/sd-card/mp3/0118.mp3 diff --git a/sd-card/mp3/0119.mp3 b/src/sd-card/mp3/0119.mp3 similarity index 100% rename from sd-card/mp3/0119.mp3 rename to src/sd-card/mp3/0119.mp3 diff --git a/sd-card/mp3/0120.mp3 b/src/sd-card/mp3/0120.mp3 similarity index 100% rename from sd-card/mp3/0120.mp3 rename to src/sd-card/mp3/0120.mp3 diff --git a/sd-card/mp3/0121.mp3 b/src/sd-card/mp3/0121.mp3 similarity index 100% rename from sd-card/mp3/0121.mp3 rename to src/sd-card/mp3/0121.mp3 diff --git a/sd-card/mp3/0122.mp3 b/src/sd-card/mp3/0122.mp3 similarity index 100% rename from sd-card/mp3/0122.mp3 rename to src/sd-card/mp3/0122.mp3 diff --git a/sd-card/mp3/0123.mp3 b/src/sd-card/mp3/0123.mp3 similarity index 100% rename from sd-card/mp3/0123.mp3 rename to src/sd-card/mp3/0123.mp3 diff --git a/sd-card/mp3/0124.mp3 b/src/sd-card/mp3/0124.mp3 similarity index 100% rename from sd-card/mp3/0124.mp3 rename to src/sd-card/mp3/0124.mp3 diff --git a/sd-card/mp3/0125.mp3 b/src/sd-card/mp3/0125.mp3 similarity index 100% rename from sd-card/mp3/0125.mp3 rename to src/sd-card/mp3/0125.mp3 diff --git a/sd-card/mp3/0126.mp3 b/src/sd-card/mp3/0126.mp3 similarity index 100% rename from sd-card/mp3/0126.mp3 rename to src/sd-card/mp3/0126.mp3 diff --git a/sd-card/mp3/0127.mp3 b/src/sd-card/mp3/0127.mp3 similarity index 100% rename from sd-card/mp3/0127.mp3 rename to src/sd-card/mp3/0127.mp3 diff --git a/sd-card/mp3/0128.mp3 b/src/sd-card/mp3/0128.mp3 similarity index 100% rename from sd-card/mp3/0128.mp3 rename to src/sd-card/mp3/0128.mp3 diff --git a/sd-card/mp3/0129.mp3 b/src/sd-card/mp3/0129.mp3 similarity index 100% rename from sd-card/mp3/0129.mp3 rename to src/sd-card/mp3/0129.mp3 diff --git a/sd-card/mp3/0130.mp3 b/src/sd-card/mp3/0130.mp3 similarity index 100% rename from sd-card/mp3/0130.mp3 rename to src/sd-card/mp3/0130.mp3 diff --git a/sd-card/mp3/0131.mp3 b/src/sd-card/mp3/0131.mp3 similarity index 100% rename from sd-card/mp3/0131.mp3 rename to src/sd-card/mp3/0131.mp3 diff --git a/sd-card/mp3/0132.mp3 b/src/sd-card/mp3/0132.mp3 similarity index 100% rename from sd-card/mp3/0132.mp3 rename to src/sd-card/mp3/0132.mp3 diff --git a/sd-card/mp3/0133.mp3 b/src/sd-card/mp3/0133.mp3 similarity index 100% rename from sd-card/mp3/0133.mp3 rename to src/sd-card/mp3/0133.mp3 diff --git a/sd-card/mp3/0134.mp3 b/src/sd-card/mp3/0134.mp3 similarity index 100% rename from sd-card/mp3/0134.mp3 rename to src/sd-card/mp3/0134.mp3 diff --git a/sd-card/mp3/0135.mp3 b/src/sd-card/mp3/0135.mp3 similarity index 100% rename from sd-card/mp3/0135.mp3 rename to src/sd-card/mp3/0135.mp3 diff --git a/sd-card/mp3/0136.mp3 b/src/sd-card/mp3/0136.mp3 similarity index 100% rename from sd-card/mp3/0136.mp3 rename to src/sd-card/mp3/0136.mp3 diff --git a/sd-card/mp3/0137.mp3 b/src/sd-card/mp3/0137.mp3 similarity index 100% rename from sd-card/mp3/0137.mp3 rename to src/sd-card/mp3/0137.mp3 diff --git a/sd-card/mp3/0138.mp3 b/src/sd-card/mp3/0138.mp3 similarity index 100% rename from sd-card/mp3/0138.mp3 rename to src/sd-card/mp3/0138.mp3 diff --git a/sd-card/mp3/0139.mp3 b/src/sd-card/mp3/0139.mp3 similarity index 100% rename from sd-card/mp3/0139.mp3 rename to src/sd-card/mp3/0139.mp3 diff --git a/sd-card/mp3/0140.mp3 b/src/sd-card/mp3/0140.mp3 similarity index 100% rename from sd-card/mp3/0140.mp3 rename to src/sd-card/mp3/0140.mp3 diff --git a/sd-card/mp3/0141.mp3 b/src/sd-card/mp3/0141.mp3 similarity index 100% rename from sd-card/mp3/0141.mp3 rename to src/sd-card/mp3/0141.mp3 diff --git a/sd-card/mp3/0142.mp3 b/src/sd-card/mp3/0142.mp3 similarity index 100% rename from sd-card/mp3/0142.mp3 rename to src/sd-card/mp3/0142.mp3 diff --git a/sd-card/mp3/0143.mp3 b/src/sd-card/mp3/0143.mp3 similarity index 100% rename from sd-card/mp3/0143.mp3 rename to src/sd-card/mp3/0143.mp3 diff --git a/sd-card/mp3/0144.mp3 b/src/sd-card/mp3/0144.mp3 similarity index 100% rename from sd-card/mp3/0144.mp3 rename to src/sd-card/mp3/0144.mp3 diff --git a/sd-card/mp3/0145.mp3 b/src/sd-card/mp3/0145.mp3 similarity index 100% rename from sd-card/mp3/0145.mp3 rename to src/sd-card/mp3/0145.mp3 diff --git a/sd-card/mp3/0146.mp3 b/src/sd-card/mp3/0146.mp3 similarity index 100% rename from sd-card/mp3/0146.mp3 rename to src/sd-card/mp3/0146.mp3 diff --git a/sd-card/mp3/0147.mp3 b/src/sd-card/mp3/0147.mp3 similarity index 100% rename from sd-card/mp3/0147.mp3 rename to src/sd-card/mp3/0147.mp3 diff --git a/sd-card/mp3/0148.mp3 b/src/sd-card/mp3/0148.mp3 similarity index 100% rename from sd-card/mp3/0148.mp3 rename to src/sd-card/mp3/0148.mp3 diff --git a/sd-card/mp3/0149.mp3 b/src/sd-card/mp3/0149.mp3 similarity index 100% rename from sd-card/mp3/0149.mp3 rename to src/sd-card/mp3/0149.mp3 diff --git a/sd-card/mp3/0150.mp3 b/src/sd-card/mp3/0150.mp3 similarity index 100% rename from sd-card/mp3/0150.mp3 rename to src/sd-card/mp3/0150.mp3 diff --git a/sd-card/mp3/0151.mp3 b/src/sd-card/mp3/0151.mp3 similarity index 100% rename from sd-card/mp3/0151.mp3 rename to src/sd-card/mp3/0151.mp3 diff --git a/sd-card/mp3/0152.mp3 b/src/sd-card/mp3/0152.mp3 similarity index 100% rename from sd-card/mp3/0152.mp3 rename to src/sd-card/mp3/0152.mp3 diff --git a/sd-card/mp3/0153.mp3 b/src/sd-card/mp3/0153.mp3 similarity index 100% rename from sd-card/mp3/0153.mp3 rename to src/sd-card/mp3/0153.mp3 diff --git a/sd-card/mp3/0154.mp3 b/src/sd-card/mp3/0154.mp3 similarity index 100% rename from sd-card/mp3/0154.mp3 rename to src/sd-card/mp3/0154.mp3 diff --git a/sd-card/mp3/0155.mp3 b/src/sd-card/mp3/0155.mp3 similarity index 100% rename from sd-card/mp3/0155.mp3 rename to src/sd-card/mp3/0155.mp3 diff --git a/sd-card/mp3/0156.mp3 b/src/sd-card/mp3/0156.mp3 similarity index 100% rename from sd-card/mp3/0156.mp3 rename to src/sd-card/mp3/0156.mp3 diff --git a/sd-card/mp3/0157.mp3 b/src/sd-card/mp3/0157.mp3 similarity index 100% rename from sd-card/mp3/0157.mp3 rename to src/sd-card/mp3/0157.mp3 diff --git a/sd-card/mp3/0158.mp3 b/src/sd-card/mp3/0158.mp3 similarity index 100% rename from sd-card/mp3/0158.mp3 rename to src/sd-card/mp3/0158.mp3 diff --git a/sd-card/mp3/0159.mp3 b/src/sd-card/mp3/0159.mp3 similarity index 100% rename from sd-card/mp3/0159.mp3 rename to src/sd-card/mp3/0159.mp3 diff --git a/sd-card/mp3/0160.mp3 b/src/sd-card/mp3/0160.mp3 similarity index 100% rename from sd-card/mp3/0160.mp3 rename to src/sd-card/mp3/0160.mp3 diff --git a/sd-card/mp3/0161.mp3 b/src/sd-card/mp3/0161.mp3 similarity index 100% rename from sd-card/mp3/0161.mp3 rename to src/sd-card/mp3/0161.mp3 diff --git a/sd-card/mp3/0162.mp3 b/src/sd-card/mp3/0162.mp3 similarity index 100% rename from sd-card/mp3/0162.mp3 rename to src/sd-card/mp3/0162.mp3 diff --git a/sd-card/mp3/0163.mp3 b/src/sd-card/mp3/0163.mp3 similarity index 100% rename from sd-card/mp3/0163.mp3 rename to src/sd-card/mp3/0163.mp3 diff --git a/sd-card/mp3/0164.mp3 b/src/sd-card/mp3/0164.mp3 similarity index 100% rename from sd-card/mp3/0164.mp3 rename to src/sd-card/mp3/0164.mp3 diff --git a/sd-card/mp3/0165.mp3 b/src/sd-card/mp3/0165.mp3 similarity index 100% rename from sd-card/mp3/0165.mp3 rename to src/sd-card/mp3/0165.mp3 diff --git a/sd-card/mp3/0166.mp3 b/src/sd-card/mp3/0166.mp3 similarity index 100% rename from sd-card/mp3/0166.mp3 rename to src/sd-card/mp3/0166.mp3 diff --git a/sd-card/mp3/0167.mp3 b/src/sd-card/mp3/0167.mp3 similarity index 100% rename from sd-card/mp3/0167.mp3 rename to src/sd-card/mp3/0167.mp3 diff --git a/sd-card/mp3/0168.mp3 b/src/sd-card/mp3/0168.mp3 similarity index 100% rename from sd-card/mp3/0168.mp3 rename to src/sd-card/mp3/0168.mp3 diff --git a/sd-card/mp3/0169.mp3 b/src/sd-card/mp3/0169.mp3 similarity index 100% rename from sd-card/mp3/0169.mp3 rename to src/sd-card/mp3/0169.mp3 diff --git a/sd-card/mp3/0170.mp3 b/src/sd-card/mp3/0170.mp3 similarity index 100% rename from sd-card/mp3/0170.mp3 rename to src/sd-card/mp3/0170.mp3 diff --git a/sd-card/mp3/0171.mp3 b/src/sd-card/mp3/0171.mp3 similarity index 100% rename from sd-card/mp3/0171.mp3 rename to src/sd-card/mp3/0171.mp3 diff --git a/sd-card/mp3/0172.mp3 b/src/sd-card/mp3/0172.mp3 similarity index 100% rename from sd-card/mp3/0172.mp3 rename to src/sd-card/mp3/0172.mp3 diff --git a/sd-card/mp3/0173.mp3 b/src/sd-card/mp3/0173.mp3 similarity index 100% rename from sd-card/mp3/0173.mp3 rename to src/sd-card/mp3/0173.mp3 diff --git a/sd-card/mp3/0174.mp3 b/src/sd-card/mp3/0174.mp3 similarity index 100% rename from sd-card/mp3/0174.mp3 rename to src/sd-card/mp3/0174.mp3 diff --git a/sd-card/mp3/0175.mp3 b/src/sd-card/mp3/0175.mp3 similarity index 100% rename from sd-card/mp3/0175.mp3 rename to src/sd-card/mp3/0175.mp3 diff --git a/sd-card/mp3/0176.mp3 b/src/sd-card/mp3/0176.mp3 similarity index 100% rename from sd-card/mp3/0176.mp3 rename to src/sd-card/mp3/0176.mp3 diff --git a/sd-card/mp3/0177.mp3 b/src/sd-card/mp3/0177.mp3 similarity index 100% rename from sd-card/mp3/0177.mp3 rename to src/sd-card/mp3/0177.mp3 diff --git a/sd-card/mp3/0178.mp3 b/src/sd-card/mp3/0178.mp3 similarity index 100% rename from sd-card/mp3/0178.mp3 rename to src/sd-card/mp3/0178.mp3 diff --git a/sd-card/mp3/0179.mp3 b/src/sd-card/mp3/0179.mp3 similarity index 100% rename from sd-card/mp3/0179.mp3 rename to src/sd-card/mp3/0179.mp3 diff --git a/sd-card/mp3/0180.mp3 b/src/sd-card/mp3/0180.mp3 similarity index 100% rename from sd-card/mp3/0180.mp3 rename to src/sd-card/mp3/0180.mp3 diff --git a/sd-card/mp3/0181.mp3 b/src/sd-card/mp3/0181.mp3 similarity index 100% rename from sd-card/mp3/0181.mp3 rename to src/sd-card/mp3/0181.mp3 diff --git a/sd-card/mp3/0182.mp3 b/src/sd-card/mp3/0182.mp3 similarity index 100% rename from sd-card/mp3/0182.mp3 rename to src/sd-card/mp3/0182.mp3 diff --git a/sd-card/mp3/0183.mp3 b/src/sd-card/mp3/0183.mp3 similarity index 100% rename from sd-card/mp3/0183.mp3 rename to src/sd-card/mp3/0183.mp3 diff --git a/sd-card/mp3/0184.mp3 b/src/sd-card/mp3/0184.mp3 similarity index 100% rename from sd-card/mp3/0184.mp3 rename to src/sd-card/mp3/0184.mp3 diff --git a/sd-card/mp3/0185.mp3 b/src/sd-card/mp3/0185.mp3 similarity index 100% rename from sd-card/mp3/0185.mp3 rename to src/sd-card/mp3/0185.mp3 diff --git a/sd-card/mp3/0186.mp3 b/src/sd-card/mp3/0186.mp3 similarity index 100% rename from sd-card/mp3/0186.mp3 rename to src/sd-card/mp3/0186.mp3 diff --git a/sd-card/mp3/0187.mp3 b/src/sd-card/mp3/0187.mp3 similarity index 100% rename from sd-card/mp3/0187.mp3 rename to src/sd-card/mp3/0187.mp3 diff --git a/sd-card/mp3/0188.mp3 b/src/sd-card/mp3/0188.mp3 similarity index 100% rename from sd-card/mp3/0188.mp3 rename to src/sd-card/mp3/0188.mp3 diff --git a/sd-card/mp3/0189.mp3 b/src/sd-card/mp3/0189.mp3 similarity index 100% rename from sd-card/mp3/0189.mp3 rename to src/sd-card/mp3/0189.mp3 diff --git a/sd-card/mp3/0190.mp3 b/src/sd-card/mp3/0190.mp3 similarity index 100% rename from sd-card/mp3/0190.mp3 rename to src/sd-card/mp3/0190.mp3 diff --git a/sd-card/mp3/0191.mp3 b/src/sd-card/mp3/0191.mp3 similarity index 100% rename from sd-card/mp3/0191.mp3 rename to src/sd-card/mp3/0191.mp3 diff --git a/sd-card/mp3/0192.mp3 b/src/sd-card/mp3/0192.mp3 similarity index 100% rename from sd-card/mp3/0192.mp3 rename to src/sd-card/mp3/0192.mp3 diff --git a/sd-card/mp3/0193.mp3 b/src/sd-card/mp3/0193.mp3 similarity index 100% rename from sd-card/mp3/0193.mp3 rename to src/sd-card/mp3/0193.mp3 diff --git a/sd-card/mp3/0194.mp3 b/src/sd-card/mp3/0194.mp3 similarity index 100% rename from sd-card/mp3/0194.mp3 rename to src/sd-card/mp3/0194.mp3 diff --git a/sd-card/mp3/0195.mp3 b/src/sd-card/mp3/0195.mp3 similarity index 100% rename from sd-card/mp3/0195.mp3 rename to src/sd-card/mp3/0195.mp3 diff --git a/sd-card/mp3/0196.mp3 b/src/sd-card/mp3/0196.mp3 similarity index 100% rename from sd-card/mp3/0196.mp3 rename to src/sd-card/mp3/0196.mp3 diff --git a/sd-card/mp3/0197.mp3 b/src/sd-card/mp3/0197.mp3 similarity index 100% rename from sd-card/mp3/0197.mp3 rename to src/sd-card/mp3/0197.mp3 diff --git a/sd-card/mp3/0198.mp3 b/src/sd-card/mp3/0198.mp3 similarity index 100% rename from sd-card/mp3/0198.mp3 rename to src/sd-card/mp3/0198.mp3 diff --git a/sd-card/mp3/0199.mp3 b/src/sd-card/mp3/0199.mp3 similarity index 100% rename from sd-card/mp3/0199.mp3 rename to src/sd-card/mp3/0199.mp3 diff --git a/sd-card/mp3/0200.mp3 b/src/sd-card/mp3/0200.mp3 similarity index 100% rename from sd-card/mp3/0200.mp3 rename to src/sd-card/mp3/0200.mp3 diff --git a/sd-card/mp3/0201.mp3 b/src/sd-card/mp3/0201.mp3 similarity index 100% rename from sd-card/mp3/0201.mp3 rename to src/sd-card/mp3/0201.mp3 diff --git a/sd-card/mp3/0202.mp3 b/src/sd-card/mp3/0202.mp3 similarity index 100% rename from sd-card/mp3/0202.mp3 rename to src/sd-card/mp3/0202.mp3 diff --git a/sd-card/mp3/0203.mp3 b/src/sd-card/mp3/0203.mp3 similarity index 100% rename from sd-card/mp3/0203.mp3 rename to src/sd-card/mp3/0203.mp3 diff --git a/sd-card/mp3/0204.mp3 b/src/sd-card/mp3/0204.mp3 similarity index 100% rename from sd-card/mp3/0204.mp3 rename to src/sd-card/mp3/0204.mp3 diff --git a/sd-card/mp3/0205.mp3 b/src/sd-card/mp3/0205.mp3 similarity index 100% rename from sd-card/mp3/0205.mp3 rename to src/sd-card/mp3/0205.mp3 diff --git a/sd-card/mp3/0206.mp3 b/src/sd-card/mp3/0206.mp3 similarity index 100% rename from sd-card/mp3/0206.mp3 rename to src/sd-card/mp3/0206.mp3 diff --git a/sd-card/mp3/0207.mp3 b/src/sd-card/mp3/0207.mp3 similarity index 100% rename from sd-card/mp3/0207.mp3 rename to src/sd-card/mp3/0207.mp3 diff --git a/sd-card/mp3/0208.mp3 b/src/sd-card/mp3/0208.mp3 similarity index 100% rename from sd-card/mp3/0208.mp3 rename to src/sd-card/mp3/0208.mp3 diff --git a/sd-card/mp3/0209.mp3 b/src/sd-card/mp3/0209.mp3 similarity index 100% rename from sd-card/mp3/0209.mp3 rename to src/sd-card/mp3/0209.mp3 diff --git a/sd-card/mp3/0210.mp3 b/src/sd-card/mp3/0210.mp3 similarity index 100% rename from sd-card/mp3/0210.mp3 rename to src/sd-card/mp3/0210.mp3 diff --git a/sd-card/mp3/0211.mp3 b/src/sd-card/mp3/0211.mp3 similarity index 100% rename from sd-card/mp3/0211.mp3 rename to src/sd-card/mp3/0211.mp3 diff --git a/sd-card/mp3/0212.mp3 b/src/sd-card/mp3/0212.mp3 similarity index 100% rename from sd-card/mp3/0212.mp3 rename to src/sd-card/mp3/0212.mp3 diff --git a/sd-card/mp3/0213.mp3 b/src/sd-card/mp3/0213.mp3 similarity index 100% rename from sd-card/mp3/0213.mp3 rename to src/sd-card/mp3/0213.mp3 diff --git a/sd-card/mp3/0214.mp3 b/src/sd-card/mp3/0214.mp3 similarity index 100% rename from sd-card/mp3/0214.mp3 rename to src/sd-card/mp3/0214.mp3 diff --git a/sd-card/mp3/0215.mp3 b/src/sd-card/mp3/0215.mp3 similarity index 100% rename from sd-card/mp3/0215.mp3 rename to src/sd-card/mp3/0215.mp3 diff --git a/sd-card/mp3/0216.mp3 b/src/sd-card/mp3/0216.mp3 similarity index 100% rename from sd-card/mp3/0216.mp3 rename to src/sd-card/mp3/0216.mp3 diff --git a/sd-card/mp3/0217.mp3 b/src/sd-card/mp3/0217.mp3 similarity index 100% rename from sd-card/mp3/0217.mp3 rename to src/sd-card/mp3/0217.mp3 diff --git a/sd-card/mp3/0218.mp3 b/src/sd-card/mp3/0218.mp3 similarity index 100% rename from sd-card/mp3/0218.mp3 rename to src/sd-card/mp3/0218.mp3 diff --git a/sd-card/mp3/0219.mp3 b/src/sd-card/mp3/0219.mp3 similarity index 100% rename from sd-card/mp3/0219.mp3 rename to src/sd-card/mp3/0219.mp3 diff --git a/sd-card/mp3/0220.mp3 b/src/sd-card/mp3/0220.mp3 similarity index 100% rename from sd-card/mp3/0220.mp3 rename to src/sd-card/mp3/0220.mp3 diff --git a/sd-card/mp3/0221.mp3 b/src/sd-card/mp3/0221.mp3 similarity index 100% rename from sd-card/mp3/0221.mp3 rename to src/sd-card/mp3/0221.mp3 diff --git a/sd-card/mp3/0222.mp3 b/src/sd-card/mp3/0222.mp3 similarity index 100% rename from sd-card/mp3/0222.mp3 rename to src/sd-card/mp3/0222.mp3 diff --git a/sd-card/mp3/0223.mp3 b/src/sd-card/mp3/0223.mp3 similarity index 100% rename from sd-card/mp3/0223.mp3 rename to src/sd-card/mp3/0223.mp3 diff --git a/sd-card/mp3/0224.mp3 b/src/sd-card/mp3/0224.mp3 similarity index 100% rename from sd-card/mp3/0224.mp3 rename to src/sd-card/mp3/0224.mp3 diff --git a/sd-card/mp3/0225.mp3 b/src/sd-card/mp3/0225.mp3 similarity index 100% rename from sd-card/mp3/0225.mp3 rename to src/sd-card/mp3/0225.mp3 diff --git a/sd-card/mp3/0226.mp3 b/src/sd-card/mp3/0226.mp3 similarity index 100% rename from sd-card/mp3/0226.mp3 rename to src/sd-card/mp3/0226.mp3 diff --git a/sd-card/mp3/0227.mp3 b/src/sd-card/mp3/0227.mp3 similarity index 100% rename from sd-card/mp3/0227.mp3 rename to src/sd-card/mp3/0227.mp3 diff --git a/sd-card/mp3/0228.mp3 b/src/sd-card/mp3/0228.mp3 similarity index 100% rename from sd-card/mp3/0228.mp3 rename to src/sd-card/mp3/0228.mp3 diff --git a/sd-card/mp3/0229.mp3 b/src/sd-card/mp3/0229.mp3 similarity index 100% rename from sd-card/mp3/0229.mp3 rename to src/sd-card/mp3/0229.mp3 diff --git a/sd-card/mp3/0230.mp3 b/src/sd-card/mp3/0230.mp3 similarity index 100% rename from sd-card/mp3/0230.mp3 rename to src/sd-card/mp3/0230.mp3 diff --git a/sd-card/mp3/0231.mp3 b/src/sd-card/mp3/0231.mp3 similarity index 100% rename from sd-card/mp3/0231.mp3 rename to src/sd-card/mp3/0231.mp3 diff --git a/sd-card/mp3/0232.mp3 b/src/sd-card/mp3/0232.mp3 similarity index 100% rename from sd-card/mp3/0232.mp3 rename to src/sd-card/mp3/0232.mp3 diff --git a/sd-card/mp3/0233.mp3 b/src/sd-card/mp3/0233.mp3 similarity index 100% rename from sd-card/mp3/0233.mp3 rename to src/sd-card/mp3/0233.mp3 diff --git a/sd-card/mp3/0234.mp3 b/src/sd-card/mp3/0234.mp3 similarity index 100% rename from sd-card/mp3/0234.mp3 rename to src/sd-card/mp3/0234.mp3 diff --git a/sd-card/mp3/0235.mp3 b/src/sd-card/mp3/0235.mp3 similarity index 100% rename from sd-card/mp3/0235.mp3 rename to src/sd-card/mp3/0235.mp3 diff --git a/sd-card/mp3/0236.mp3 b/src/sd-card/mp3/0236.mp3 similarity index 100% rename from sd-card/mp3/0236.mp3 rename to src/sd-card/mp3/0236.mp3 diff --git a/sd-card/mp3/0237.mp3 b/src/sd-card/mp3/0237.mp3 similarity index 100% rename from sd-card/mp3/0237.mp3 rename to src/sd-card/mp3/0237.mp3 diff --git a/sd-card/mp3/0238.mp3 b/src/sd-card/mp3/0238.mp3 similarity index 100% rename from sd-card/mp3/0238.mp3 rename to src/sd-card/mp3/0238.mp3 diff --git a/sd-card/mp3/0239.mp3 b/src/sd-card/mp3/0239.mp3 similarity index 100% rename from sd-card/mp3/0239.mp3 rename to src/sd-card/mp3/0239.mp3 diff --git a/sd-card/mp3/0240.mp3 b/src/sd-card/mp3/0240.mp3 similarity index 100% rename from sd-card/mp3/0240.mp3 rename to src/sd-card/mp3/0240.mp3 diff --git a/sd-card/mp3/0241.mp3 b/src/sd-card/mp3/0241.mp3 similarity index 100% rename from sd-card/mp3/0241.mp3 rename to src/sd-card/mp3/0241.mp3 diff --git a/sd-card/mp3/0242.mp3 b/src/sd-card/mp3/0242.mp3 similarity index 100% rename from sd-card/mp3/0242.mp3 rename to src/sd-card/mp3/0242.mp3 diff --git a/sd-card/mp3/0243.mp3 b/src/sd-card/mp3/0243.mp3 similarity index 100% rename from sd-card/mp3/0243.mp3 rename to src/sd-card/mp3/0243.mp3 diff --git a/sd-card/mp3/0244.mp3 b/src/sd-card/mp3/0244.mp3 similarity index 100% rename from sd-card/mp3/0244.mp3 rename to src/sd-card/mp3/0244.mp3 diff --git a/sd-card/mp3/0245.mp3 b/src/sd-card/mp3/0245.mp3 similarity index 100% rename from sd-card/mp3/0245.mp3 rename to src/sd-card/mp3/0245.mp3 diff --git a/sd-card/mp3/0246.mp3 b/src/sd-card/mp3/0246.mp3 similarity index 100% rename from sd-card/mp3/0246.mp3 rename to src/sd-card/mp3/0246.mp3 diff --git a/sd-card/mp3/0247.mp3 b/src/sd-card/mp3/0247.mp3 similarity index 100% rename from sd-card/mp3/0247.mp3 rename to src/sd-card/mp3/0247.mp3 diff --git a/sd-card/mp3/0248.mp3 b/src/sd-card/mp3/0248.mp3 similarity index 100% rename from sd-card/mp3/0248.mp3 rename to src/sd-card/mp3/0248.mp3 diff --git a/sd-card/mp3/0249.mp3 b/src/sd-card/mp3/0249.mp3 similarity index 100% rename from sd-card/mp3/0249.mp3 rename to src/sd-card/mp3/0249.mp3 diff --git a/sd-card/mp3/0250.mp3 b/src/sd-card/mp3/0250.mp3 similarity index 100% rename from sd-card/mp3/0250.mp3 rename to src/sd-card/mp3/0250.mp3 diff --git a/sd-card/mp3/0251.mp3 b/src/sd-card/mp3/0251.mp3 similarity index 100% rename from sd-card/mp3/0251.mp3 rename to src/sd-card/mp3/0251.mp3 diff --git a/sd-card/mp3/0252.mp3 b/src/sd-card/mp3/0252.mp3 similarity index 100% rename from sd-card/mp3/0252.mp3 rename to src/sd-card/mp3/0252.mp3 diff --git a/sd-card/mp3/0253.mp3 b/src/sd-card/mp3/0253.mp3 similarity index 100% rename from sd-card/mp3/0253.mp3 rename to src/sd-card/mp3/0253.mp3 diff --git a/sd-card/mp3/0254.mp3 b/src/sd-card/mp3/0254.mp3 similarity index 100% rename from sd-card/mp3/0254.mp3 rename to src/sd-card/mp3/0254.mp3 diff --git a/sd-card/mp3/0255.mp3 b/src/sd-card/mp3/0255.mp3 similarity index 100% rename from sd-card/mp3/0255.mp3 rename to src/sd-card/mp3/0255.mp3 diff --git a/sd-card/mp3/0300_new_tag.mp3 b/src/sd-card/mp3/0300_new_tag.mp3 similarity index 100% rename from sd-card/mp3/0300_new_tag.mp3 rename to src/sd-card/mp3/0300_new_tag.mp3 diff --git a/sd-card/mp3/0301_select_folder.mp3 b/src/sd-card/mp3/0301_select_folder.mp3 similarity index 100% rename from sd-card/mp3/0301_select_folder.mp3 rename to src/sd-card/mp3/0301_select_folder.mp3 diff --git a/sd-card/mp3/0310.mp3 b/src/sd-card/mp3/0310.mp3 similarity index 100% rename from sd-card/mp3/0310.mp3 rename to src/sd-card/mp3/0310.mp3 diff --git a/sd-card/mp3/0311_mode_random_episode.mp3 b/src/sd-card/mp3/0311_mode_random_episode.mp3 similarity index 100% rename from sd-card/mp3/0311_mode_random_episode.mp3 rename to src/sd-card/mp3/0311_mode_random_episode.mp3 diff --git a/sd-card/mp3/0312_mode_album.mp3 b/src/sd-card/mp3/0312_mode_album.mp3 similarity index 100% rename from sd-card/mp3/0312_mode_album.mp3 rename to src/sd-card/mp3/0312_mode_album.mp3 diff --git a/sd-card/mp3/0313_mode_party.mp3 b/src/sd-card/mp3/0313_mode_party.mp3 similarity index 100% rename from sd-card/mp3/0313_mode_party.mp3 rename to src/sd-card/mp3/0313_mode_party.mp3 diff --git a/sd-card/mp3/0314_mode_single_track.mp3 b/src/sd-card/mp3/0314_mode_single_track.mp3 similarity index 100% rename from sd-card/mp3/0314_mode_single_track.mp3 rename to src/sd-card/mp3/0314_mode_single_track.mp3 diff --git a/sd-card/mp3/0315_mode_audio_book.mp3 b/src/sd-card/mp3/0315_mode_audio_book.mp3 similarity index 100% rename from sd-card/mp3/0315_mode_audio_book.mp3 rename to src/sd-card/mp3/0315_mode_audio_book.mp3 diff --git a/sd-card/mp3/0316_admin.mp3 b/src/sd-card/mp3/0316_admin.mp3 similarity index 100% rename from sd-card/mp3/0316_admin.mp3 rename to src/sd-card/mp3/0316_admin.mp3 diff --git a/sd-card/mp3/0317_special_random.mp3 b/src/sd-card/mp3/0317_special_random.mp3 similarity index 100% rename from sd-card/mp3/0317_special_random.mp3 rename to src/sd-card/mp3/0317_special_random.mp3 diff --git a/sd-card/mp3/0318_special_album.mp3 b/src/sd-card/mp3/0318_special_album.mp3 similarity index 100% rename from sd-card/mp3/0318_special_album.mp3 rename to src/sd-card/mp3/0318_special_album.mp3 diff --git a/sd-card/mp3/0319_special_party.mp3 b/src/sd-card/mp3/0319_special_party.mp3 similarity index 100% rename from sd-card/mp3/0319_special_party.mp3 rename to src/sd-card/mp3/0319_special_party.mp3 diff --git a/sd-card/mp3/0320_select_file.mp3 b/src/sd-card/mp3/0320_select_file.mp3 similarity index 100% rename from sd-card/mp3/0320_select_file.mp3 rename to src/sd-card/mp3/0320_select_file.mp3 diff --git a/sd-card/mp3/0321_select_first_file.mp3 b/src/sd-card/mp3/0321_select_first_file.mp3 similarity index 100% rename from sd-card/mp3/0321_select_first_file.mp3 rename to src/sd-card/mp3/0321_select_first_file.mp3 diff --git a/sd-card/mp3/0322_select_last_file.mp3 b/src/sd-card/mp3/0322_select_last_file.mp3 similarity index 100% rename from sd-card/mp3/0322_select_last_file.mp3 rename to src/sd-card/mp3/0322_select_last_file.mp3 diff --git a/sd-card/mp3/0330.mp3 b/src/sd-card/mp3/0330.mp3 similarity index 100% rename from sd-card/mp3/0330.mp3 rename to src/sd-card/mp3/0330.mp3 diff --git a/sd-card/mp3/0331.mp3 b/src/sd-card/mp3/0331.mp3 similarity index 100% rename from sd-card/mp3/0331.mp3 rename to src/sd-card/mp3/0331.mp3 diff --git a/sd-card/mp3/0332.mp3 b/src/sd-card/mp3/0332.mp3 similarity index 100% rename from sd-card/mp3/0332.mp3 rename to src/sd-card/mp3/0332.mp3 diff --git a/sd-card/mp3/0400_ok.mp3 b/src/sd-card/mp3/0400_ok.mp3 similarity index 100% rename from sd-card/mp3/0400_ok.mp3 rename to src/sd-card/mp3/0400_ok.mp3 diff --git a/sd-card/mp3/0401_error.mp3 b/src/sd-card/mp3/0401_error.mp3 similarity index 100% rename from sd-card/mp3/0401_error.mp3 rename to src/sd-card/mp3/0401_error.mp3 diff --git a/sd-card/mp3/0800_waiting_for_card.mp3 b/src/sd-card/mp3/0800_waiting_for_card.mp3 similarity index 100% rename from sd-card/mp3/0800_waiting_for_card.mp3 rename to src/sd-card/mp3/0800_waiting_for_card.mp3 diff --git a/sd-card/mp3/0802_reset_aborted.mp3 b/src/sd-card/mp3/0802_reset_aborted.mp3 similarity index 100% rename from sd-card/mp3/0802_reset_aborted.mp3 rename to src/sd-card/mp3/0802_reset_aborted.mp3 diff --git a/sd-card/mp3/0900_admin.mp3 b/src/sd-card/mp3/0900_admin.mp3 similarity index 100% rename from sd-card/mp3/0900_admin.mp3 rename to src/sd-card/mp3/0900_admin.mp3 diff --git a/sd-card/mp3/0901_card_reset.mp3 b/src/sd-card/mp3/0901_card_reset.mp3 similarity index 100% rename from sd-card/mp3/0901_card_reset.mp3 rename to src/sd-card/mp3/0901_card_reset.mp3 diff --git a/sd-card/mp3/0902_max_volume.mp3 b/src/sd-card/mp3/0902_max_volume.mp3 similarity index 100% rename from sd-card/mp3/0902_max_volume.mp3 rename to src/sd-card/mp3/0902_max_volume.mp3 diff --git a/sd-card/mp3/0903_min_volume.mp3 b/src/sd-card/mp3/0903_min_volume.mp3 similarity index 100% rename from sd-card/mp3/0903_min_volume.mp3 rename to src/sd-card/mp3/0903_min_volume.mp3 diff --git a/sd-card/mp3/0904_init_volume.mp3 b/src/sd-card/mp3/0904_init_volume.mp3 similarity index 100% rename from sd-card/mp3/0904_init_volume.mp3 rename to src/sd-card/mp3/0904_init_volume.mp3 diff --git a/sd-card/mp3/0905_eq.mp3 b/src/sd-card/mp3/0905_eq.mp3 similarity index 100% rename from sd-card/mp3/0905_eq.mp3 rename to src/sd-card/mp3/0905_eq.mp3 diff --git a/sd-card/mp3/0906_modifiers.mp3 b/src/sd-card/mp3/0906_modifiers.mp3 similarity index 100% rename from sd-card/mp3/0906_modifiers.mp3 rename to src/sd-card/mp3/0906_modifiers.mp3 diff --git a/sd-card/mp3/0907_shortcut.mp3 b/src/sd-card/mp3/0907_shortcut.mp3 similarity index 100% rename from sd-card/mp3/0907_shortcut.mp3 rename to src/sd-card/mp3/0907_shortcut.mp3 diff --git a/sd-card/mp3/0908_standbytimer.mp3 b/src/sd-card/mp3/0908_standbytimer.mp3 similarity index 100% rename from sd-card/mp3/0908_standbytimer.mp3 rename to src/sd-card/mp3/0908_standbytimer.mp3 diff --git a/sd-card/mp3/0909_batch_cards.mp3 b/src/sd-card/mp3/0909_batch_cards.mp3 similarity index 100% rename from sd-card/mp3/0909_batch_cards.mp3 rename to src/sd-card/mp3/0909_batch_cards.mp3 diff --git a/sd-card/mp3/0910_switch_volume.mp3 b/src/sd-card/mp3/0910_switch_volume.mp3 similarity index 100% rename from sd-card/mp3/0910_switch_volume.mp3 rename to src/sd-card/mp3/0910_switch_volume.mp3 diff --git a/sd-card/mp3/0911_reset.mp3 b/src/sd-card/mp3/0911_reset.mp3 similarity index 100% rename from sd-card/mp3/0911_reset.mp3 rename to src/sd-card/mp3/0911_reset.mp3 diff --git a/sd-card/mp3/0912_admin_lock.mp3 b/src/sd-card/mp3/0912_admin_lock.mp3 similarity index 100% rename from sd-card/mp3/0912_admin_lock.mp3 rename to src/sd-card/mp3/0912_admin_lock.mp3 diff --git a/sd-card/mp3/0920_eq_intro.mp3 b/src/sd-card/mp3/0920_eq_intro.mp3 similarity index 100% rename from sd-card/mp3/0920_eq_intro.mp3 rename to src/sd-card/mp3/0920_eq_intro.mp3 diff --git a/sd-card/mp3/0921_normal.mp3 b/src/sd-card/mp3/0921_normal.mp3 similarity index 100% rename from sd-card/mp3/0921_normal.mp3 rename to src/sd-card/mp3/0921_normal.mp3 diff --git a/sd-card/mp3/0922_pop.mp3 b/src/sd-card/mp3/0922_pop.mp3 similarity index 100% rename from sd-card/mp3/0922_pop.mp3 rename to src/sd-card/mp3/0922_pop.mp3 diff --git a/sd-card/mp3/0923_rock.mp3 b/src/sd-card/mp3/0923_rock.mp3 similarity index 100% rename from sd-card/mp3/0923_rock.mp3 rename to src/sd-card/mp3/0923_rock.mp3 diff --git a/sd-card/mp3/0924_jazz.mp3 b/src/sd-card/mp3/0924_jazz.mp3 similarity index 100% rename from sd-card/mp3/0924_jazz.mp3 rename to src/sd-card/mp3/0924_jazz.mp3 diff --git a/sd-card/mp3/0925_classic.mp3 b/src/sd-card/mp3/0925_classic.mp3 similarity index 100% rename from sd-card/mp3/0925_classic.mp3 rename to src/sd-card/mp3/0925_classic.mp3 diff --git a/sd-card/mp3/0926_bass.mp3 b/src/sd-card/mp3/0926_bass.mp3 similarity index 100% rename from sd-card/mp3/0926_bass.mp3 rename to src/sd-card/mp3/0926_bass.mp3 diff --git a/sd-card/mp3/0930_max_volume_intro.mp3 b/src/sd-card/mp3/0930_max_volume_intro.mp3 similarity index 100% rename from sd-card/mp3/0930_max_volume_intro.mp3 rename to src/sd-card/mp3/0930_max_volume_intro.mp3 diff --git a/sd-card/mp3/0931_min_volume_into.mp3 b/src/sd-card/mp3/0931_min_volume_into.mp3 similarity index 100% rename from sd-card/mp3/0931_min_volume_into.mp3 rename to src/sd-card/mp3/0931_min_volume_into.mp3 diff --git a/sd-card/mp3/0932_init_volume_into.mp3 b/src/sd-card/mp3/0932_init_volume_into.mp3 similarity index 100% rename from sd-card/mp3/0932_init_volume_into.mp3 rename to src/sd-card/mp3/0932_init_volume_into.mp3 diff --git a/sd-card/mp3/0933_switch_volume_intro.mp3 b/src/sd-card/mp3/0933_switch_volume_intro.mp3 similarity index 100% rename from sd-card/mp3/0933_switch_volume_intro.mp3 rename to src/sd-card/mp3/0933_switch_volume_intro.mp3 diff --git a/sd-card/mp3/0934_no.mp3 b/src/sd-card/mp3/0934_no.mp3 similarity index 100% rename from sd-card/mp3/0934_no.mp3 rename to src/sd-card/mp3/0934_no.mp3 diff --git a/sd-card/mp3/0935_yes.mp3 b/src/sd-card/mp3/0935_yes.mp3 similarity index 100% rename from sd-card/mp3/0935_yes.mp3 rename to src/sd-card/mp3/0935_yes.mp3 diff --git a/sd-card/mp3/0936_batch_cards_intro.mp3 b/src/sd-card/mp3/0936_batch_cards_intro.mp3 similarity index 100% rename from sd-card/mp3/0936_batch_cards_intro.mp3 rename to src/sd-card/mp3/0936_batch_cards_intro.mp3 diff --git a/sd-card/mp3/0940_shortcut_into.mp3 b/src/sd-card/mp3/0940_shortcut_into.mp3 similarity index 100% rename from sd-card/mp3/0940_shortcut_into.mp3 rename to src/sd-card/mp3/0940_shortcut_into.mp3 diff --git a/sd-card/mp3/0941_pause.mp3 b/src/sd-card/mp3/0941_pause.mp3 similarity index 100% rename from sd-card/mp3/0941_pause.mp3 rename to src/sd-card/mp3/0941_pause.mp3 diff --git a/sd-card/mp3/0942_up.mp3 b/src/sd-card/mp3/0942_up.mp3 similarity index 100% rename from sd-card/mp3/0942_up.mp3 rename to src/sd-card/mp3/0942_up.mp3 diff --git a/sd-card/mp3/0943_down.mp3 b/src/sd-card/mp3/0943_down.mp3 similarity index 100% rename from sd-card/mp3/0943_down.mp3 rename to src/sd-card/mp3/0943_down.mp3 diff --git a/sd-card/mp3/0944_startup.mp3 b/src/sd-card/mp3/0944_startup.mp3 similarity index 100% rename from sd-card/mp3/0944_startup.mp3 rename to src/sd-card/mp3/0944_startup.mp3 diff --git a/sd-card/mp3/0960_timer_intro.mp3 b/src/sd-card/mp3/0960_timer_intro.mp3 similarity index 100% rename from sd-card/mp3/0960_timer_intro.mp3 rename to src/sd-card/mp3/0960_timer_intro.mp3 diff --git a/sd-card/mp3/0961_timer_5.mp3 b/src/sd-card/mp3/0961_timer_5.mp3 similarity index 100% rename from sd-card/mp3/0961_timer_5.mp3 rename to src/sd-card/mp3/0961_timer_5.mp3 diff --git a/sd-card/mp3/0962_timer_15.mp3 b/src/sd-card/mp3/0962_timer_15.mp3 similarity index 100% rename from sd-card/mp3/0962_timer_15.mp3 rename to src/sd-card/mp3/0962_timer_15.mp3 diff --git a/sd-card/mp3/0963_timer_30.mp3 b/src/sd-card/mp3/0963_timer_30.mp3 similarity index 100% rename from sd-card/mp3/0963_timer_30.mp3 rename to src/sd-card/mp3/0963_timer_30.mp3 diff --git a/sd-card/mp3/0964_timer_60.mp3 b/src/sd-card/mp3/0964_timer_60.mp3 similarity index 100% rename from sd-card/mp3/0964_timer_60.mp3 rename to src/sd-card/mp3/0964_timer_60.mp3 diff --git a/sd-card/mp3/0965_timer_disabled.mp3 b/src/sd-card/mp3/0965_timer_disabled.mp3 similarity index 100% rename from sd-card/mp3/0965_timer_disabled.mp3 rename to src/sd-card/mp3/0965_timer_disabled.mp3 diff --git a/sd-card/mp3/0970_modifier_Intro.mp3 b/src/sd-card/mp3/0970_modifier_Intro.mp3 similarity index 100% rename from sd-card/mp3/0970_modifier_Intro.mp3 rename to src/sd-card/mp3/0970_modifier_Intro.mp3 diff --git a/sd-card/mp3/0971_modifier_SleepTimer.mp3 b/src/sd-card/mp3/0971_modifier_SleepTimer.mp3 similarity index 100% rename from sd-card/mp3/0971_modifier_SleepTimer.mp3 rename to src/sd-card/mp3/0971_modifier_SleepTimer.mp3 diff --git a/sd-card/mp3/0972_modifier_FreezeDance.mp3 b/src/sd-card/mp3/0972_modifier_FreezeDance.mp3 similarity index 100% rename from sd-card/mp3/0972_modifier_FreezeDance.mp3 rename to src/sd-card/mp3/0972_modifier_FreezeDance.mp3 diff --git a/sd-card/mp3/0973_modifier_Locked.mp3 b/src/sd-card/mp3/0973_modifier_Locked.mp3 similarity index 100% rename from sd-card/mp3/0973_modifier_Locked.mp3 rename to src/sd-card/mp3/0973_modifier_Locked.mp3 diff --git a/sd-card/mp3/0974_modifier_Toddler.mp3 b/src/sd-card/mp3/0974_modifier_Toddler.mp3 similarity index 100% rename from sd-card/mp3/0974_modifier_Toddler.mp3 rename to src/sd-card/mp3/0974_modifier_Toddler.mp3 diff --git a/sd-card/mp3/0975_modifier_KinderGarden.mp3 b/src/sd-card/mp3/0975_modifier_KinderGarden.mp3 similarity index 100% rename from sd-card/mp3/0975_modifier_KinderGarden.mp3 rename to src/sd-card/mp3/0975_modifier_KinderGarden.mp3 diff --git a/sd-card/mp3/0976_modifier_repeat1.mp3 b/src/sd-card/mp3/0976_modifier_repeat1.mp3 similarity index 100% rename from sd-card/mp3/0976_modifier_repeat1.mp3 rename to src/sd-card/mp3/0976_modifier_repeat1.mp3 diff --git a/sd-card/mp3/0980_admin_lock_intro.mp3 b/src/sd-card/mp3/0980_admin_lock_intro.mp3 similarity index 100% rename from sd-card/mp3/0980_admin_lock_intro.mp3 rename to src/sd-card/mp3/0980_admin_lock_intro.mp3 diff --git a/sd-card/mp3/0981_admin_lock_disabled.mp3 b/src/sd-card/mp3/0981_admin_lock_disabled.mp3 similarity index 100% rename from sd-card/mp3/0981_admin_lock_disabled.mp3 rename to src/sd-card/mp3/0981_admin_lock_disabled.mp3 diff --git a/sd-card/mp3/0982_admin_lock_card.mp3 b/src/sd-card/mp3/0982_admin_lock_card.mp3 similarity index 100% rename from sd-card/mp3/0982_admin_lock_card.mp3 rename to src/sd-card/mp3/0982_admin_lock_card.mp3 diff --git a/sd-card/mp3/0983_admin_lock_pin.mp3 b/src/sd-card/mp3/0983_admin_lock_pin.mp3 similarity index 100% rename from sd-card/mp3/0983_admin_lock_pin.mp3 rename to src/sd-card/mp3/0983_admin_lock_pin.mp3 diff --git a/sd-card/mp3/0984_admin_lock_calc.mp3 b/src/sd-card/mp3/0984_admin_lock_calc.mp3 similarity index 100% rename from sd-card/mp3/0984_admin_lock_calc.mp3 rename to src/sd-card/mp3/0984_admin_lock_calc.mp3 diff --git a/sd-card/mp3/0991_admin_pin.mp3 b/src/sd-card/mp3/0991_admin_pin.mp3 similarity index 100% rename from sd-card/mp3/0991_admin_pin.mp3 rename to src/sd-card/mp3/0991_admin_pin.mp3 diff --git a/sd-card/mp3/0992_admin_calc.mp3 b/src/sd-card/mp3/0992_admin_calc.mp3 similarity index 100% rename from sd-card/mp3/0992_admin_calc.mp3 rename to src/sd-card/mp3/0992_admin_calc.mp3 diff --git a/sd-card/mp3/0993_admin_calc.mp3 b/src/sd-card/mp3/0993_admin_calc.mp3 similarity index 100% rename from sd-card/mp3/0993_admin_calc.mp3 rename to src/sd-card/mp3/0993_admin_calc.mp3 diff --git a/sd-card/mp3/0994_admin_calc.mp3 b/src/sd-card/mp3/0994_admin_calc.mp3 similarity index 100% rename from sd-card/mp3/0994_admin_calc.mp3 rename to src/sd-card/mp3/0994_admin_calc.mp3 diff --git a/sd-card/mp3/0999_reset_ok.mp3 b/src/sd-card/mp3/0999_reset_ok.mp3 similarity index 100% rename from sd-card/mp3/0999_reset_ok.mp3 rename to src/sd-card/mp3/0999_reset_ok.mp3 diff --git a/soundfiles.txt b/src/soundfiles.txt similarity index 100% rename from soundfiles.txt rename to src/soundfiles.txt diff --git a/tools/add_lead_in_messages.py b/src/tools/add_lead_in_messages.py old mode 100755 new mode 100644 similarity index 100% rename from tools/add_lead_in_messages.py rename to src/tools/add_lead_in_messages.py diff --git a/tools/create_audio_messages.py b/src/tools/create_audio_messages.py old mode 100755 new mode 100644 similarity index 100% rename from tools/create_audio_messages.py rename to src/tools/create_audio_messages.py diff --git a/tools/text_to_speech.py b/src/tools/text_to_speech.py old mode 100755 new mode 100644 similarity index 100% rename from tools/text_to_speech.py rename to src/tools/text_to_speech.py diff --git a/test/README b/test/README new file mode 100644 index 00000000..b94d0890 --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html From 011c561b1e93a82eabc34b57f87304d148eba20a Mon Sep 17 00:00:00 2001 From: seder Date: Wed, 6 Jan 2021 21:17:11 +0100 Subject: [PATCH 03/21] Switch HIGH/LOW when turning speaker on/off This switches the HIGH state TO low and vice versa when turning the speakers on or off, because changing the circuit form a MOSFET switch to a modified DFPlayer which has the Amp's SDH (shutdown) on the former IO1 pin of the DFPlayer. --- src/Tonuino.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index adada345..d121c346 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -1331,14 +1331,14 @@ void writeCard(nfcTagObject nfcTag) { #ifdef SpkOnOff void spkOn() { - digitalWrite(SpkOnPin, HIGH); // Lautsprecher über Mosfets Einschalten + digitalWrite(SpkOnPin, LOW); // Lautsprecher über Mosfets Einschalten Serial.println(F("Lautsprecher wird eingeschaltet!")); SpkisOn = true; } // **************************Speaker Off ******************* void spkOff() { - digitalWrite(SpkOnPin, LOW); // Lautsprecher über Mosfets Ausschalten + digitalWrite(SpkOnPin, HIGH); // Lautsprecher über Mosfets Ausschalten Serial.println(F("Lautsprecher wird ausgeschaltet!")); SpkisOn = false; } From e3abcc8320e4679855a75f278b41e75dce4aa189 Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 02:45:15 +0100 Subject: [PATCH 04/21] Beep when card is read --- src/Tonuino.cpp | 18 ++++++++++++++++++ .../advert/0400_card_detected_beep.mp3 | Bin 0 -> 10286 bytes 2 files changed, 18 insertions(+) create mode 100644 src/sd-card/advert/0400_card_detected_beep.mp3 diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index d121c346..666c0279 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -27,6 +27,13 @@ // Möglichkeit der Abschaltung beim Anschluss eines Kopfhörers // Hardwareerweiterung erforderlich: (Abschaltung des Lautsprechers über MOS-FET's) +#define BeepOnNewCard + +#ifdef BeepOnNewCard +#define BEEP_DELAY 1000 +#define BEEP_SOUND 400 +#endif + static const uint32_t cardCookie = 322417479; // MFRC522 @@ -1156,6 +1163,17 @@ bool readCard(nfcTagObject * nfcTag) { } } +#ifdef BeepOnNewCard + if (!isPlaying()) { + // Note(sprietl): Turn speaker on/off to minimize the impact of sound of last mp3 + spkOff(); + mp3.start(); + delay(100); + spkOn(); + } + mp3.playAdvertisement(BEEP_SOUND); + delay(BEEP_DELAY); +#endif if (tempCard.nfcFolderSettings.folder == 0) { if (activeModifier != NULL) { if (activeModifier->getActive() == tempCard.nfcFolderSettings.mode) { diff --git a/src/sd-card/advert/0400_card_detected_beep.mp3 b/src/sd-card/advert/0400_card_detected_beep.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..68125b61d5988c45afebb5d3a45ac6d29fae7aaa GIT binary patch literal 10286 zcmeHMc~leE9=?;XBw-OWMK(zYiin783J5{~*#v|bg1C|*i(y|YA~XpoO9P0Cs0bKp zKtMo6QNUWFD5xx=0s=yfxT1(uP^lrzo7i$*m-G7GJE!%Jp4@Y0?qu$r``zE~`|fvV zPGDhf0QfJ(mk|++beV%3o&YSi1lT!vH8q0nQe$HaYX>JMSNC-kiuZ<%8@KrR2L=X* zghxfi#3$_DoyI2S-)fDXr>YFHo{=rP5SL)QS1oltEtZi1hCDqIR%P30%-aZN8|U-GMDbL7}xisR3XKi{FP=H|i!bsd*^1t&C?fP@2=SvT9{rl9cW|bkItQ zQ(9IDJCmnDa+dlMaW*fMg}29x8fE>C%w?}XK=J@ikx zErEY7y|g_g#L$^VShT&@{x{Qgm33rfhCu1H_S^^23F1rU%dNw8)njt|>YhC*?sSL= zJR0Xf1dsrzmtb>;)}J7q)%O0Du#=wX(o=3o>u(<~y`1$17J3EDW#2up;0|*;7o$ML z5d;9jk+U5};~4@C7Q-C?sjnlKdQJ?f;&JXKxORoK4xVhLG!TrdqDoHLWvs3E*3wt> zO6yThLUMTVlZAYQIuwXPXnQvzGU!mLY$1Xq^K66pykU|;Q|CYvZJx=lDGyDa;nI=tcF zGTZJo;((xLmN=lvku8n^>l>87a^-82=gz3OOl`zQrtFPW3$+P8;QW%;=zq}HyWzWv zkRPhEE3sRb+8C9Zc?z&v3JQ^aJp-YKoX(#c^2;~4IvVcWPgf@k6anl9XH;h160-n7 zccVymcWZ_uV7clu$gD9(GO45CSOK1;CuSir*a%1ofYKN~H^5^|HVMUbo%_1pq}Mq_ zn$yEs-CbBca9Q*;ry`WPBHw$Gz2l?+9KtwU$u?83+^vK*~r?9FGiifJ&kYHSH5{WLz;4 zkDO|@?dYyd!6Md0IPN_$y=ylpMc@3n~LKZ%v@20 z#6tuOWc^9CHJ*x7(n1Kjwt}3PRkFy%$-sOy=XyVWIdH~s1k`*ft$FA6x=q2jjMw+NybHc+SJ%7Q89=GG3(DVWs%P6`TXaSf2Wq0r(p@Zz&K96s4jfZCQEuQMN zUU?{Mn6o6uLdB_`|86At*z@+mK)4Sg6NE7Q@t&2<9Yo>dpm*cQRaLbwcl3uO>T%Wv z#5}j5N;i4+KAwDg1a;6r_u-(JR6P5f5ve28hNdUS#||M$z)f=O#8#ooS~`U!;o(P% z8+cu=J#>{@Ot)!C+x6Iq{=M=u9l96Y8hS$B;-?~ibl(Js;YB{NbXcvPZrUDU-VqX= zpdTsndxb=+fv6IKA5>Db3yAG3AlFd+=mNW&YR_s4t-HLN+JN0`A z7R}hyafTY>1H|#5*mu_;q#`0!B&&b2ioQ(RX!vu1I#?`Tbik7j7UYwn{P$F5m{p`; z<#givP2KZ*_TT=n`Q+7BlZ$#Yu?=Iw1bURO^?AJPY25j~`>k3Yge1S=R+o%j$+!Bo zxky+51G4}czVq-@24F+z=3)DnNF6FH`h)5X%P1cf6@gNQYRcY&moqrEx%(81IjC9YT42*O0 zl43Ba)K`TEeJ0!vTP?+cmo0o^W^{B7Yq`W)i@cQ!ZMv*~~X~^2%jcu3w zY3g;9E`SEIC>9``oOvS(+PWRtu9JY;(s*g#TdaAUGNpHkXBb*HdD+P?V`hr|hs-*p z<#%KI9;`~DKyECSls!aZP0^jYbeHQG(d$t%i-8P%6>wY8mF=`(e!GuSSe>vgflqwVMgGIRN>5*M=V7>rIq0FmL+^al>|A>~hb|BO$_J0NFttCRLe5H#F z7bjk+m~M`T*#7~rdR(=&h z>Av+hO-_|(=7`>PRVp=&#-1-X`=_UcT_|(My$B+ld>d@vh%w1`+{U00?DD$DZ0XvxrrE z&&4PbaeiFHU#!ztG!(Nix$F_96pCy`^SucJ%uG|ZiC2}EyKN$HjS>jH)^s?slBI%pV6_1i^w6Kf@aK_fy3>u zoa)`f!iwmKC;{m6?qP~jt$JTE`O@#R?u6>1?&<2<(yo&s)!;@SzeDm1J6z&+@D-&t zKSr}0Fsu)oip&bU6*}+Uir94a{nup`Cum`}V>aIwDiN-cX~4@_#>=72Ss)%-Bg};~ zptpH_v}ehS1WNeY>9cAS((L=Kp-JT*3oKL$P~3+Y05cs~Fvxy8j%XFhJ`Wj<2!I(2 zq3(}Q{qD}6BK+J}jAJCmVITt|I10$%e;3aB&x8~AnQ-zy6HfhS!WsBXIMbgA2bSRc z))4+jKak|@w`r@CVI0^?7SSk z?VKHbyJP{NA%C5rkOL{)PiN$$_{)V|OdKON4p1ZGBLeIh{$YWJ+atqqzchL?;=%%f jePCb|@l%KYFevMn?f^mjcjwugzpj4^^Xrzs;u`)JE&+{H literal 0 HcmV?d00001 From 3298686a408c71623a3515d708c2b1e5b64be28c Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 02:48:26 +0100 Subject: [PATCH 05/21] Revamp speaker on/off --- src/Tonuino.cpp | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 666c0279..6ce39568 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -65,7 +65,9 @@ MFRC522::StatusCode status; #ifdef SpkOnOff #define SpkOnPin 5 // Lautsprecher Ein - bool SpkisOn = false; // Marker Lautsprecher Ein/Aus +bool isSpkOn = false; // Marker Lautsprecher Ein/Aus +void spkOn(); +void spkOff(); #endif #define LONG_PRESS 1000 @@ -311,6 +313,7 @@ void checkStandbyAtMillis() { // http://discourse.voss.earth/t/intenso-s10000-powerbank-automatische-abschaltung-software-only/805 // powerdown to 27mA (powerbank switches off after 30-60s) + spkOff(); mfrc522.PCD_AntennaOff(); mfrc522.PCD_SoftPowerDown(); mp3.sleep(); @@ -1344,28 +1347,27 @@ void writeCard(nfcTagObject nfcTag) { } // ************************** Speaker On-Off ***************************************** - -// **************************Speaker On ******************* #ifdef SpkOnOff -void spkOn() - { - digitalWrite(SpkOnPin, LOW); // Lautsprecher über Mosfets Einschalten +// **************************Speaker On ******************* +void spkOn() { + if (!isSpkOn) { Serial.println(F("Lautsprecher wird eingeschaltet!")); - SpkisOn = true; + digitalWrite(SpkOnPin, LOW); + isSpkOn = true; + // Wait a tiny bit for the Amp to start up + // delay(100); } +} // **************************Speaker Off ******************* void spkOff() { - digitalWrite(SpkOnPin, HIGH); // Lautsprecher über Mosfets Ausschalten + if (isSpkOn) { Serial.println(F("Lautsprecher wird ausgeschaltet!")); - SpkisOn = false; + digitalWrite(SpkOnPin, HIGH); + isSpkOn = false; +} } - -//void SpkrOnOff() { -// SpkOn(); // Lautsprecher über Mosfets Einschalten -//} #endif - // ************************** END Speaker On-Off ************************************** /** @@ -1622,6 +1624,10 @@ void adminMenu(bool fromCard) { void setup() { +#ifdef SpkOnOff + pinMode(SpkOnPin, OUTPUT); // Ausgang Lautsprecher-Einschaltsignal + spkOff(); // Voreinstellung - Speaker Off +#endif Serial.begin(115200); // Es gibt ein paar Debug Ausgaben über die serielle Schnittstelle // Wert für randomSeed() erzeugen durch das mehrfache Sammeln von rauschenden LSBs eines offenen Analogeingangs @@ -1713,6 +1719,9 @@ void setup() { loadSettingsFromFlash(); } +#ifdef SpkOnOff + spkOn(); +#endif // Start Shortcut "at Startup" - e.g. Welcome Sound playShortCut(3); From 11718ca6e4463392d5f9843ca96343f4b275df85 Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 02:51:28 +0100 Subject: [PATCH 06/21] Improve the feedback modifier --- src/Tonuino.cpp | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 6ce39568..5fa4928e 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -679,33 +679,32 @@ class RepeatSingleModifier: public Modifier { // This simple FeedbackModifier will tell the volume before changing it and // give some feedback once a RFID card is detected. class FeedbackModifier: public Modifier { + private: + bool advertVolume(uint8_t volume) { + if (isPlaying()) { + mp3.playAdvertisement(volume); + delay(500); + } + + return false; + } public: virtual bool handleVolumeDown() { + Serial.println(F("== FeedbackModifier::handleVolumeDown()")); if (volume > mySettings.minVolume) { - mp3.playAdvertisement(volume - 1); + return advertVolume(volume - 1); } - else { - mp3.playAdvertisement(volume); + return advertVolume(volume); } - delay(500); - Serial.println(F("== FeedbackModifier::handleVolumeDown()!")); - return false; - } + virtual bool handleVolumeUp() { + Serial.println(F("== FeedbackModifier::handleVolumeUp()")); if (volume < mySettings.maxVolume) { - mp3.playAdvertisement(volume + 1); + return advertVolume(volume + 1); } - else { - mp3.playAdvertisement(volume); + return advertVolume(volume); } - delay(500); - Serial.println(F("== FeedbackModifier::handleVolumeUp()!")); - return false; - } - virtual bool handleRFID(nfcTagObject *newCard) { - Serial.println(F("== FeedbackModifier::handleRFID()")); - return false; - } + }; // Leider kann das Modul selbst keine Queue abspielen, daher müssen wir selbst die Queue verwalten From d76abfe16404e208f64636678a6c4aef20d9a34e Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 02:52:22 +0100 Subject: [PATCH 07/21] Improve admin menu --- src/Tonuino.cpp | 74 ++++++++++++++----------------- src/sd-card/mp3/0399_ok_only.mp3 | Bin 0 -> 5787 bytes 2 files changed, 34 insertions(+), 40 deletions(-) create mode 100644 src/sd-card/mp3/0399_ok_only.mp3 diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 5fa4928e..0439dd05 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -1407,17 +1407,16 @@ bool askCode(uint8_t *code) { } void adminMenu(bool fromCard) { + Serial.println(F("=== adminMenu()")); disablestandbyTimer(); mp3.pause(); - Serial.println(F("=== adminMenu()")); knownCard = false; if (fromCard == false) { // Admin menu has been locked - it still can be trigged via admin card if (mySettings.adminMenuLocked == 1) { return; - } + } else if (mySettings.adminMenuLocked == 2) { // Pin check - else if (mySettings.adminMenuLocked == 2) { uint8_t pin[4]; mp3.playMp3FolderTrack(991); if (askCode(pin) == true) { @@ -1427,9 +1426,8 @@ void adminMenu(bool fromCard) { } else { return; } - } + } else if (mySettings.adminMenuLocked == 3) { // Match check - else if (mySettings.adminMenuLocked == 3) { uint8_t a = random(10, 20); uint8_t b = random(1, 10); uint8_t c; @@ -1458,32 +1456,35 @@ void adminMenu(bool fromCard) { } } } + int subMenu = voiceMenu(12, 900, 900, false, false, 0, true); - if (subMenu == 0) + + if (subMenu == 0) { return; + } + if (subMenu == 1) { resetCard(); mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); - } - else if (subMenu == 2) { + } else if (subMenu == 2) { // Maximum Volume mySettings.maxVolume = voiceMenu(30 - mySettings.minVolume, 930, mySettings.minVolume, false, false, mySettings.maxVolume - mySettings.minVolume) + mySettings.minVolume; - } - else if (subMenu == 3) { + mp3.playMp3FolderTrack(399); + } else if (subMenu == 3) { // Minimum Volume mySettings.minVolume = voiceMenu(mySettings.maxVolume - 1, 931, 0, false, false, mySettings.minVolume); - } - else if (subMenu == 4) { + mp3.playMp3FolderTrack(399); + } else if (subMenu == 4) { // Initial Volume mySettings.initVolume = voiceMenu(mySettings.maxVolume - mySettings.minVolume + 1, 932, mySettings.minVolume - 1, false, false, mySettings.initVolume - mySettings.minVolume + 1) + mySettings.minVolume - 1; - } - else if (subMenu == 5) { + mp3.playMp3FolderTrack(399); + } else if (subMenu == 5) { // EQ mySettings.eq = voiceMenu(6, 920, 920, false, false, mySettings.eq); mp3.setEq(static_cast(mySettings.eq - 1)); - } - else if (subMenu == 6) { + mp3.playMp3FolderTrack(399); + } else if (subMenu == 6) { // create modifier card nfcTagObject tempCard; tempCard.cookie = cardCookie; @@ -1514,21 +1515,18 @@ void adminMenu(bool fromCard) { // RFID Karte wurde aufgelegt if (mfrc522.PICC_ReadCardSerial()) { - Serial.println(F("schreibe Karte...")); + Serial.println(F("Schreibe Karte...")); writeCard(tempCard); delay(100); mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); - waitForTrackToFinish(); } } - } - else if (subMenu == 7) { + } else if (subMenu == 7) { uint8_t shortcut = voiceMenu(4, 940, 940); setupFolder(&mySettings.shortCuts[shortcut - 1]); mp3.playMp3FolderTrack(400); - } - else if (subMenu == 8) { + } else if (subMenu == 8) { switch (voiceMenu(5, 960, 960)) { case 1: mySettings.standbyTimer = 5; break; case 2: mySettings.standbyTimer = 15; break; @@ -1536,8 +1534,8 @@ void adminMenu(bool fromCard) { case 4: mySettings.standbyTimer = 60; break; case 5: mySettings.standbyTimer = 0; break; } - } - else if (subMenu == 9) { + mp3.playMp3FolderTrack(399); + } else if (subMenu == 9) { // Create Cards for Folder // Ordner abfragen nfcTagObject tempCard; @@ -1568,57 +1566,53 @@ void adminMenu(bool fromCard) { // RFID Karte wurde aufgelegt if (mfrc522.PICC_ReadCardSerial()) { - Serial.println(F("schreibe Karte...")); + Serial.println(F("Schreibe Karte...")); writeCard(tempCard); delay(100); mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); - waitForTrackToFinish(); } } - } - else if (subMenu == 10) { + } else if (subMenu == 10) { // Invert Functions for Up/Down Buttons - int temp = voiceMenu(2, 933, 933, false); + int temp = voiceMenu(2, 933, 933); if (temp == 2) { mySettings.invertVolumeButtons = true; } else { mySettings.invertVolumeButtons = false; } - } - else if (subMenu == 11) { + mp3.playMp3FolderTrack(399); + } else if (subMenu == 11) { Serial.println(F("Reset -> EEPROM wird gelöscht")); for (unsigned int i = 0; i < EEPROM.length(); i++) { EEPROM.update(i, 0); } resetSettings(); mp3.playMp3FolderTrack(999); - } + } else if (subMenu == 12) { // lock admin menu - else if (subMenu == 12) { int temp = voiceMenu(4, 980, 980, false); if (temp == 1) { mySettings.adminMenuLocked = 0; - } - else if (temp == 2) { + } else if (temp == 2) { mySettings.adminMenuLocked = 1; - } - else if (temp == 3) { + } else if (temp == 3) { uint8_t pin[4]; mp3.playMp3FolderTrack(991); if (askCode(pin)) { memcpy(mySettings.adminMenuPin, pin, 4); mySettings.adminMenuLocked = 2; } - } - else if (temp == 4) { + } else if (temp == 4) { mySettings.adminMenuLocked = 3; } - + mp3.playMp3FolderTrack(399); } writeSettingsToFlash(); setstandbyTimer(); + + waitForTrackToFinish(); } void setup() { diff --git a/src/sd-card/mp3/0399_ok_only.mp3 b/src/sd-card/mp3/0399_ok_only.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..cbfa6368888d60ee6ac44ffdbdfb0b0ea4fb699d GIT binary patch literal 5787 zcmd6rcT^KkyT>;Pga{#o9*~kyLZ}9$iyA@=MY<#aG?!D*!b?=||bIzQZ+1Y3IJI_8l&+bwT55s_c4%<`g)mSxx zRYHP;E?`3f?VX&QSUq7@u?z8uIPZDx3}E3I<)fjcqNS>$N+g17v_970zj5*p_GPtr zSVar~gxmlm63N3tL_|c1g{Gz^i3Np1v1Q@RA}lN{okebLZW)Wp%E|^7O)NS)J9}9$ z7>sci@87?lW3kL)b#--%#m>&o9t#izS=X|*(6=-?ysw5W_}@YRKoB7V`;7x2U-ost z+KPJrbKrle!L{5zfSm?ahq6u-X3hWK@Z9PHw@3q6ATCjQ|L9()gD|#pzJECWIhq&| zt@JAapTF4!f{wQg1zw$#HbP5i^0t#Nq+?0Mt0$F_1!j`jsSp_ymZ>J1{XOq}@TF2< z9wJ?i0H9202>t^R>we;3bS10?-b)KllNkoH^1?o(6qf?UF<@u1t{{k5Uu zp+tRxFlDvMk3Z%3#$^sQ@aNP`4Y|>nU5lozygAC%YY}KQEe+k%DmuD0^57b=Zx%&> z8%mM@Adg!9x+J~1Hawi4pB()-AboYkel)E{d(`j^gArEDnd6f`)Fh$y4?O5Y`)?u% zAw9&N;K~MA;E>}o2xt}{wI3o&8m>aNarwD`nl+njsjkQs7^NX7t--UbhDzw5I!RQ~ z5ww)RLVA=LGdzQdLk>toj3J2hVhgq#_0gh%M=@0qwNrQ`J_ghwu4QZI~FG%CaKgc6!EzzvYTFuG|74=6j3 zH6M+E(}HahunHNvck-M^4Y!}mggL$?k51dAdI={H;Dx~L({*H__0pEyzhwFy2rM_N zJ5;X%*31g8zawt$gSa25o%^u{hPMvUbRTW*Hx*t9nU;RAIpNYG>KQBwk8^K%HHR*7 z`Y0KesrIrxdu%n6(gp4X+&>QPp!th{YM@sdW+W|=JX(SEG*v6nT5D|({Pn2tx|y-c zoqiAU2jGA#c?BcYi3;Q0QTnAV{qbPrp(o_w_c5yx+0dNB)j1@(Jkl)F!m}4rmWd69 ztD&8U50Yu+?B&>s>xQ!EBvn$#+~br|k-XltmIMWr0)=C-3lk#O)r`hUbrmh%1)uhz zBGcy#x${*iY$%a+i<}Gj7sa(q47;a(Dt9RNmJbV*Vs0c4c9>$kbf}2wJYn*Loj)MG=ugueMy0Wzbv2l4#2h}aRz18W$m>)UbhxTKxtXPUj(5q5V@mBZjM~41b1b30(2km=P zV~YyfRa6q7VpanHoFPvxd&MBP^B1c-9$KHmyOu5W z9NF<2j~zEJ)F@gEoyz^P(%)wtld|&9x3IfApTeXqmtL@Bf-g04=PdObWi>C*8=L2r3)1YxJPj{;QpYS;6TV))ucimpC53x;kQ6$8*1~@2Y zd<-NiF7XN^!+bm|zx9u{m+B`d-ZSU1^rwp|$PhMtM`s!WS{Ucmn*y4Z1XUGx#5F&H zYoUEV@B(}dZo^grD}j40pGK9!(|LFtMJKl>d)FR7GeOc zP{01m5>?rGUt8UQq56krFX@vzZ!QXYLQSIRSMDhBjg z?=}rtgi{XxRg2^CQt_OE)1W285)U=OHIKeM{PJFkyAuf#(Hk0@6%S>+un%@#x9K_c zV9n4wO-^kHAI>qR1j9g*zIcuF%dQwBPN`Q1Al%A)WM}an3fy@6?iR1@Lrl)9(hc(R z(E`=0FPsrvZl^YKuOwpGJfAlV#0=+$3Z*lPWR7{7il+$UqI_NL$F5<^B8NpRmDleLrv6+lAb@!qu4m&~r2MJ99vfTCU1e#Z^Jr`JvWuq7+*-G?YYCgLuI!?1^EJ zHH7tLqWytHSm-5UIotBqM${{C4ZI0XZ$+tZwx&3pb57mtAO^t_k)dToBS-;T1)12) zUVy;X6Ej#-jq(xIAut$GpQr>G=Xh|Is0&L3zVH(ZxW~DEd3|K4O&+7GVCZ$v*CmSyAF>WfaiPoNvbi@P8%Ojqkmr+vm=ojIq_q@)GK4kZgRv40C#1#;GwSI-n@ox)2a2_Q$*qP66Dt$Z zFqkpBHRo$acl%%t1DjRvc7AT43GOk*tavA7e7I;%JXXs(@$gYChh{Ywtg744Ng|sP z)X#!EM3-O#>^P2=k+Fau2}PBoTUdDZ;Zad=sIsmqJ*JKg=&S(j_(jx+02-^!_B<&$ z0l=k5@aeH}^0NW^k?`{}L&yX2ZVKRlb3xI`7?MXW`G6?Z4c8}zs^i)_>a(pt3X6z*3{%lMYO(Y=u z^gYtpPt-P`P+}57rwH3=m3`0pE6~rX=46muX@y)EG*KX#Bbj6&BPJk%DABfvzo(ps ztC;E8geBW!2zowHW1$mp6IE;t1A(y}=i#N`-*hmc(2}#4?`r&hfl~SB!Y-PYknkEO zDBA0ie#go40*SM=M)ojJY+!j^hcp13F#yFei-B)6HO+BRX84WHjCs$DJLEaPe)S;}MB7z|I*M09P(ZF|o6%7c|^-hs;#my8YU z?{Jr3{`i2_Rfaw$9<>qYo_ssW*8*+RHh4;HBsd&PzgqI%mN9ePii|mJ{fX=a$6Z=H zSs9yST`Q9L)aOB*S#h0Rjya5MmSphr@dHzg@m|afLx<9)>oT_oM%F!(t%tcBr~hvKu-IdqOSZP<746fQ+ao2Od#e=mbZ?>&ta3PI z@9+3CrV58CZ;o8HZLN8q?@} z*ovLALFj%4_@!`aV_;)CIeW)KHXA*`B|vaN@vb~GaG-+y9`(<$T?|S{P&F7S8Rnt)C)9PWLlNk*nPi51&5M{{;$g<-da^*GCga9X9 zdi112^WX5s9D*LaEWFAl^GJf#ZrpjTzHz<)QrjYL5;4%JgHk$FH7Vl6)=)p^O96UE z){QSGe(F4b(Rj5Bt5S1A?lp{jFrL zu3jFry{rW;K6!Ypr|`R_hGc9$&T09_*dbPi-3{EnxZ3HmFn^k(%s@2wwJ!*k`h0cZE0Nte(2ln)izC8Pg&?z;O&Iwv54-g_4&Gi95K`g3heu95TtP%Ovq;rLWJ^&PJDtfDYA8myQJN9~3r7VD&a7vERCqL8`$ zN@CbtBU2Dwc>uD+CvnqCWKbLYazy=Nmb*iUkKP)*74hSUCpe-&J*YqU83aG__}V*Y z((jo@MVO0e``HMBTmNhy2Lim=H+_fg6H~5AI~vtcNB1nhbeWz zP?x|ihp8SQbVU0I`isUnfHNU{i!|8qwqa1t!;cVf_^f6bPldTwfK|XwEq%gt<)-x! zabD8z$^zgi{u0)-tTiiPFk)6!3WI*o9=!|32cP>mY8-} zeqoJ=O;yenL4^Z&S))J~`Ptl$wjcbLnrD^YJu6GFE-K8nKUkvqcG`ga=9ahOWXuNv z8M%P!_ObbQof=28|Jt|Eel_-vS{h$epIk7hKFha&S;%;s3CH|X8o#f4U0#oGP~usp z`cQ;|ibsNV3t1`i(i*`|jq$yBEQdO7mjaPy2Db3>RFSzL;9ncQf&JFfG+-_KPbLK!le z%bhbumlcdpt+2KfwcX#9|Hwt4dSZLnkLp=TA8h7ar29lyMC0{61pK0n(o%N@d4-iZ z+Am$;0KqE}LZ~FOgaP@Y+>vu>9byf!-?x_fI^uRwwQ2{5<2p9<9R^(&u`SquH|dk* ztPy^vP+cHavS{roL=~8e8mF_Vn<}4Ue3bm!Pier#~zCgEDpx_3(7ZuD7c7 z2(>wGUBl*M?%={pD}24}*Fao=qxLK55%6zHI4u!dZOq2habMyBmx7V_Jzt z*{Z=q&2P?CIZR(A#B@hUiivY(3HfxLk>$8&GakteE-9Yg_vjBf8C3CJkJ*lnqC!x< zLP!hv_l$TAGjyFSLcxGkmB_2XD)MChYGrc{M~)`_6EJCTw%KF zR%Vw=$Hwb>C#$dJ1{whqCFYTzhc4$;n)8bzoB0GFwyrINbG8{(CFUR%JMJ#e7qlZK zC@OwZZP(#4$tK`Jm3gu3ov4_G&&+fn)heG5GZ|1)ypyBX8nk6(Ru9&=FCb2;%!! zAS6l38E3ciJM}7);$)Xlfh`y;m*Pwo8UVr3IkhkwMPv5lyrTRSkLA9$pV+Vg zV>i>6vJU^h0N1d6JE*b|k_2E<@qd)IZ?nirfUAqL{-6GzZP0y80D$eVO#Y|Me*pAb BT_ykk literal 0 HcmV?d00001 From 9e1e30f121023fcd5b2de81e8342087a5d11516d Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 02:52:56 +0100 Subject: [PATCH 08/21] Speed up launch --- src/Tonuino.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 0439dd05..759b6c5c 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -1621,6 +1621,11 @@ void setup() { pinMode(SpkOnPin, OUTPUT); // Ausgang Lautsprecher-Einschaltsignal spkOff(); // Voreinstellung - Speaker Off #endif + // Busy Pin + pinMode(busyPin, INPUT); + + // DFPlayer Mini initialisieren + mp3.begin(); Serial.begin(115200); // Es gibt ein paar Debug Ausgaben über die serielle Schnittstelle // Wert für randomSeed() erzeugen durch das mehrfache Sammeln von rauschenden LSBs eines offenen Analogeingangs @@ -1655,10 +1660,8 @@ void setup() { // activate standby timer setstandbyTimer(); - // DFPlayer Mini initialisieren - mp3.begin(); // Zwei Sekunden warten bis der DFPlayer Mini initialisiert ist - delay(2000); + // delay(2000); volume = mySettings.initVolume; mp3.setVolume(volume); mp3.setEq(static_cast(mySettings.eq - 1)); From 7505cf6e439ded4d9a67857230e4c057b185b86c Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 02:56:45 +0100 Subject: [PATCH 09/21] fixup: revamp spk on/off --- src/Tonuino.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 759b6c5c..64e9e408 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -1646,10 +1646,6 @@ void setup() { Serial.println(F("created by Thorsten Voß and licensed under GNU/GPL.")); Serial.println(F("Information and contribution at https://tonuino.de.\n")); -#ifdef SpkOnOff - pinMode(SpkOnPin, OUTPUT); // Ausgang Lautsprecher-Einschaltsignal - spkOff(); // Voreinstellung - Speaker Off -#endif // Busy Pin pinMode(busyPin, INPUT); @@ -1701,10 +1697,6 @@ void setup() { pinMode(shutdownPin, OUTPUT); digitalWrite(shutdownPin, LOW); -#ifdef SpkOnOff - spkOn(); -#endif - // RESET --- ALLE DREI KNÖPFE BEIM STARTEN GEDRÜCKT HALTEN -> alle EINSTELLUNGEN werden gelöscht if (digitalRead(buttonPause) == LOW && digitalRead(buttonUp) == LOW && digitalRead(buttonDown) == LOW) { From 0cc0494097a05718c180a37c29f1a2f279df8a0c Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 02:57:22 +0100 Subject: [PATCH 10/21] fixup: speed up launch --- src/Tonuino.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 64e9e408..cdb5ff7e 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -1621,11 +1621,13 @@ void setup() { pinMode(SpkOnPin, OUTPUT); // Ausgang Lautsprecher-Einschaltsignal spkOff(); // Voreinstellung - Speaker Off #endif + // Busy Pin pinMode(busyPin, INPUT); // DFPlayer Mini initialisieren mp3.begin(); + Serial.begin(115200); // Es gibt ein paar Debug Ausgaben über die serielle Schnittstelle // Wert für randomSeed() erzeugen durch das mehrfache Sammeln von rauschenden LSBs eines offenen Analogeingangs @@ -1646,10 +1648,6 @@ void setup() { Serial.println(F("created by Thorsten Voß and licensed under GNU/GPL.")); Serial.println(F("Information and contribution at https://tonuino.de.\n")); - - // Busy Pin - pinMode(busyPin, INPUT); - // load Settings from EEPROM loadSettingsFromFlash(); From fecf135eb9fb30ca056f81be45fbbf3356575397 Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 02:58:22 +0100 Subject: [PATCH 11/21] fixup: improve admin menu --- src/Tonuino.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index cdb5ff7e..bd498d68 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -139,6 +139,7 @@ static void nextTrack(uint16_t track); uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, bool preview = false, int previewFromFolder = 0, int defaultValue = 0, bool exitWithLongPress = false); bool isPlaying(); +void waitForTrackToFinish(); bool checkTwo ( uint8_t a[], uint8_t b[] ); void writeCard(nfcTagObject nfcTag); void dump_byte_array(byte * buffer, byte bufferSize); From 04e8b97f39aa54cc91223a75100f3a898769ffbb Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 13:02:47 +0100 Subject: [PATCH 12/21] fixup: improve feedback modifier --- src/Tonuino.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index bd498d68..78244249 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -679,7 +679,7 @@ class RepeatSingleModifier: public Modifier { // by returning false (not handled) at the end // This simple FeedbackModifier will tell the volume before changing it and // give some feedback once a RFID card is detected. -class FeedbackModifier: public Modifier { +class FeedbackModifier : public Modifier { private: bool advertVolume(uint8_t volume) { if (isPlaying()) { @@ -689,23 +689,17 @@ class FeedbackModifier: public Modifier { return false; } + public: virtual bool handleVolumeDown() { Serial.println(F("== FeedbackModifier::handleVolumeDown()")); - if (volume > mySettings.minVolume) { - return advertVolume(volume - 1); - } - return advertVolume(volume); + return advertVolume(volume > mySettings.minVolume ? volume - 1 : volume); } virtual bool handleVolumeUp() { Serial.println(F("== FeedbackModifier::handleVolumeUp()")); - if (volume < mySettings.maxVolume) { - return advertVolume(volume + 1); + return advertVolume(volume < mySettings.maxVolume ? volume + 1 : volume); } - return advertVolume(volume); - } - }; // Leider kann das Modul selbst keine Queue abspielen, daher müssen wir selbst die Queue verwalten From bc6968cfccab9393466b39c8fe400cbd6e21b8f2 Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 13:03:06 +0100 Subject: [PATCH 13/21] WIP: Format with clang Chromium rules --- src/Tonuino.cpp | 1055 +++++++++++++++++++++++++---------------------- 1 file changed, 566 insertions(+), 489 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 78244249..f6910ba7 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -21,11 +21,12 @@ // uncomment the below line to enable five button support //#define FIVEBUTTONS -// ------------------------------------------------------------------------------------------------ -#define SpkOnOff // Aus und Einschalten des Lautsprechers über MOSFET's - // zur Unterdrückung des Einschaltgeräusches und - // Möglichkeit der Abschaltung beim Anschluss eines Kopfhörers - // Hardwareerweiterung erforderlich: (Abschaltung des Lautsprechers über MOS-FET's) +// ------------------------------------------------------------------------------------------------ +#define SpkOnOff // Aus und Einschalten des Lautsprechers über MOSFET's + // zur Unterdrückung des Einschaltgeräusches und + // Möglichkeit der Abschaltung beim Anschluss eines Kopfhörers + // Hardwareerweiterung erforderlich: (Abschaltung des + // Lautsprechers über MOS-FET's) #define BeepOnNewCard @@ -37,9 +38,9 @@ static const uint32_t cardCookie = 322417479; // MFRC522 -#define RST_PIN 9 // Configurable, see typical pin layout above -#define SS_PIN 10 // Configurable, see typical pin layout above -MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 +#define RST_PIN 9 // Configurable, see typical pin layout above +#define SS_PIN 10 // Configurable, see typical pin layout above +MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 MFRC522::MIFARE_Key key; bool successRead; byte sector = 1; @@ -47,9 +48,13 @@ byte blockAddr = 4; byte trailerBlock = 7; MFRC522::StatusCode status; -//#define NFCgain_max // Maximale Empfindlichkeit -#define NFCgain_avg // Mittlere Empfindlichkeit -//#define NFCgain_min // Minimale Empfindlichkeit +/* + * Note(sprietl): It is possible to change the antenna gain to the following: + * - NFCgain_min + * - NFCgain_avg + * - NFCgain_max + */ +#define NFCgain_avg #define buttonPause A0 #define buttonUp A1 @@ -64,8 +69,8 @@ MFRC522::StatusCode status; #endif #ifdef SpkOnOff - #define SpkOnPin 5 // Lautsprecher Ein -bool isSpkOn = false; // Marker Lautsprecher Ein/Aus +#define SpkOnPin 5 // Lautsprecher Ein +bool isSpkOn = false; // Marker Lautsprecher Ein/Aus void spkOn(); void spkOff(); #endif @@ -88,7 +93,7 @@ bool ignoreButtonFive = false; #endif // DFPlayer Mini -SoftwareSerial mySoftwareSerial(2, 3); // RX, TX +SoftwareSerial mySoftwareSerial(2, 3); // RX, TX uint16_t numTracksInFolder; uint16_t currentTrack; uint16_t firstTrack; @@ -131,53 +136,67 @@ struct adminSettings { adminSettings mySettings; nfcTagObject myCard; -folderSettings *myFolder; +folderSettings* myFolder; unsigned long sleepAtMillis = 0; static uint16_t _lastTrackFinished; static void nextTrack(uint16_t track); -uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, - bool preview = false, int previewFromFolder = 0, int defaultValue = 0, bool exitWithLongPress = false); +uint8_t voiceMenu(int numberOfOptions, + int startMessage, + int messageOffset, + bool preview = false, + int previewFromFolder = 0, + int defaultValue = 0, + bool exitWithLongPress = false); bool isPlaying(); void waitForTrackToFinish(); -bool checkTwo ( uint8_t a[], uint8_t b[] ); +bool checkTwo(uint8_t a[], uint8_t b[]); void writeCard(nfcTagObject nfcTag); -void dump_byte_array(byte * buffer, byte bufferSize); +void dump_byte_array(byte* buffer, byte bufferSize); void adminMenu(bool fromCard = false); bool knownCard = false; // implement a notification class, // its member methods will get called -// class Mp3Notify { - public: - static void OnError(uint16_t errorCode) { - // see DfMp3_Error for code meaning - Serial.println(); - Serial.print("Com Error "); - Serial.println(errorCode); - } - static void PrintlnSourceAction(DfMp3_PlaySources source, const char* action) { - if (source & DfMp3_PlaySources_Sd) Serial.print("SD Karte "); - if (source & DfMp3_PlaySources_Usb) Serial.print("USB "); - if (source & DfMp3_PlaySources_Flash) Serial.print("Flash "); - Serial.println(action); - } - static void OnPlayFinished(DfMp3_PlaySources source, uint16_t track) { - // Serial.print("Track beendet"); - // Serial.println(track); - // delay(100); - nextTrack(track); - } - static void OnPlaySourceOnline(DfMp3_PlaySources source) { - PrintlnSourceAction(source, "online"); + public: + static void OnError(uint16_t errorCode) { + // see DfMp3_Error for code meaning + Serial.println(); + Serial.print("Com Error "); + Serial.println(errorCode); + } + static void PrintlnSourceAction(DfMp3_PlaySources source, + const char* action) { + if (source & DfMp3_PlaySources_Sd) { + Serial.print("SD Karte "); } - static void OnPlaySourceInserted(DfMp3_PlaySources source) { - PrintlnSourceAction(source, "bereit"); + + if (source & DfMp3_PlaySources_Usb) { + Serial.print("USB "); } - static void OnPlaySourceRemoved(DfMp3_PlaySources source) { - PrintlnSourceAction(source, "entfernt"); + + if (source & DfMp3_PlaySources_Flash) { + Serial.print("Flash "); } + + Serial.println(action); + } + static void OnPlayFinished(DfMp3_PlaySources source, uint16_t track) { + // Serial.print("Track beendet"); + // Serial.println(track); + // delay(100); + nextTrack(track); + } + static void OnPlaySourceOnline(DfMp3_PlaySources source) { + PrintlnSourceAction(source, "online"); + } + static void OnPlaySourceInserted(DfMp3_PlaySources source) { + PrintlnSourceAction(source, "bereit"); + } + static void OnPlaySourceRemoved(DfMp3_PlaySources source) { + PrintlnSourceAction(source, "entfernt"); + } }; static DFMiniMp3 mp3(mySoftwareSerial); @@ -190,9 +209,8 @@ void shuffleQueue() { for (uint8_t x = numTracksInFolder - firstTrack + 1; x < 255; x++) queue[x] = 0; // Queue mischen - for (uint8_t i = 0; i < numTracksInFolder - firstTrack + 1; i++) - { - uint8_t j = random (0, numTracksInFolder - firstTrack + 1); + for (uint8_t i = 0; i < numTracksInFolder - firstTrack + 1; i++) { + uint8_t j = random(0, numTracksInFolder - firstTrack + 1); uint8_t t = queue[i]; queue[i] = queue[j]; queue[j] = t; @@ -251,8 +269,10 @@ void loadSettingsFromFlash() { Serial.println(F("=== loadSettingsFromFlash()")); int address = sizeof(myFolder->folder) * 100; EEPROM.get(address, mySettings); - if (mySettings.cookie != cardCookie) + if (mySettings.cookie != cardCookie) { resetSettings(); + } + migrateSettings(mySettings.version); Serial.print(F("Version: ")); @@ -326,7 +346,7 @@ void checkStandbyAtMillis() { } void playFolder() { - Serial.println(F("== playFolder()")) ; + Serial.println(F("== playFolder()")); disablestandbyTimer(); knownCard = true; _lastTrackFinished = 0; @@ -352,22 +372,22 @@ void playFolder() { // Party Modus: Ordner in zufälliger Reihenfolge if (myFolder->mode == 3) { Serial.println( - F("Party Modus -> Ordner in zufälliger Reihenfolge wiedergeben")); + F("Party Modus -> Ordner in zufälliger Reihenfolge wiedergeben")); shuffleQueue(); currentTrack = 1; mp3.playFolderTrack(myFolder->folder, queue[currentTrack - 1]); } // Einzel Modus: eine Datei aus dem Ordner abspielen if (myFolder->mode == 4) { - Serial.println( - F("Einzel Modus -> eine Datei aus dem Odrdner abspielen")); + Serial.println(F("Einzel Modus -> eine Datei aus dem Odrdner abspielen")); currentTrack = myFolder->special; mp3.playFolderTrack(myFolder->folder, currentTrack); } // Hörbuch Modus: kompletten Ordner spielen und Fortschritt merken if (myFolder->mode == 5) { - Serial.println(F("Hörbuch Modus -> kompletten Ordner spielen und " - "Fortschritt merken")); + Serial.println( + F("Hörbuch Modus -> kompletten Ordner spielen und " + "Fortschritt merken")); currentTrack = EEPROM.read(myFolder->folder); if (currentTrack == 0 || currentTrack > numTracksInFolder) { currentTrack = 1; @@ -376,7 +396,8 @@ void playFolder() { } // Spezialmodus Von-Bin: Hörspiel: eine zufällige Datei aus dem Ordner if (myFolder->mode == 7) { - Serial.println(F("Spezialmodus Von-Bin: Hörspiel -> zufälligen Track wiedergeben")); + Serial.println( + F("Spezialmodus Von-Bin: Hörspiel -> zufälligen Track wiedergeben")); Serial.print(myFolder->special); Serial.print(F(" bis ")); Serial.println(myFolder->special2); @@ -388,7 +409,9 @@ void playFolder() { // Spezialmodus Von-Bis: Album: alle Dateien zwischen Start und Ende spielen if (myFolder->mode == 8) { - Serial.println(F("Spezialmodus Von-Bis: Album: alle Dateien zwischen Start- und Enddatei spielen")); + Serial.println( + F("Spezialmodus Von-Bis: Album: alle Dateien zwischen " + "Start- und Enddatei spielen")); Serial.print(myFolder->special); Serial.print(F(" bis ")); Serial.println(myFolder->special2); @@ -400,7 +423,8 @@ void playFolder() { // Spezialmodus Von-Bis: Party Ordner in zufälliger Reihenfolge if (myFolder->mode == 9) { Serial.println( - F("Spezialmodus Von-Bis: Party -> Ordner in zufälliger Reihenfolge wiedergeben")); + F("Spezialmodus Von-Bis: Party -> Ordner in zufälliger " + "Reihenfolge wiedergeben")); firstTrack = myFolder->special; numTracksInFolder = myFolder->special2; shuffleQueue(); @@ -417,262 +441,262 @@ void playShortCut(uint8_t shortCut) { playFolder(); disablestandbyTimer(); delay(1000); - } - else + } else Serial.println(F("Shortcut not configured!")); } class Modifier { - public: - virtual void loop() {} - virtual bool handlePause() { - return false; - } - virtual bool handleNext() { - return false; - } - virtual bool handlePrevious() { - return false; - } - virtual bool handleNextButton() { - return false; - } - virtual bool handlePreviousButton() { - return false; - } - virtual bool handleVolumeUp() { - return false; - } - virtual bool handleVolumeDown() { - return false; - } - virtual bool handleRFID(nfcTagObject *newCard) { - return false; - } - virtual uint8_t getActive() { - return 0; - } - Modifier() { - - } + public: + virtual void loop() {} + virtual bool handlePause() { return false; } + virtual bool handleNext() { return false; } + virtual bool handlePrevious() { return false; } + virtual bool handleNextButton() { return false; } + virtual bool handlePreviousButton() { return false; } + virtual bool handleVolumeUp() { return false; } + virtual bool handleVolumeDown() { return false; } + virtual bool handleRFID(nfcTagObject* newCard) { return false; } + virtual uint8_t getActive() { return 0; } + Modifier() {} }; -Modifier *activeModifier = NULL; +Modifier* activeModifier = NULL; -class SleepTimer: public Modifier { - private: - unsigned long sleepAtMillis = 0; +class SleepTimer : public Modifier { + private: + unsigned long sleepAtMillis = 0; - public: - void loop() { - if (this->sleepAtMillis != 0 && millis() > this->sleepAtMillis) { - Serial.println(F("=== SleepTimer::loop() -> SLEEP!")); - mp3.pause(); - setstandbyTimer(); - activeModifier = NULL; - delete this; - } + public: + void loop() { + if (this->sleepAtMillis != 0 && millis() > this->sleepAtMillis) { + Serial.println(F("=== SleepTimer::loop() -> SLEEP!")); + mp3.pause(); + setstandbyTimer(); + activeModifier = NULL; + delete this; } + } - SleepTimer(uint8_t minutes) { - Serial.println(F("=== SleepTimer()")); - Serial.println(minutes); - this->sleepAtMillis = millis() + minutes * 60000; - // if (isPlaying()) - // mp3.playAdvertisement(302); - // delay(500); - } - uint8_t getActive() { - Serial.println(F("== SleepTimer::getActive()")); - return 1; - } + SleepTimer(uint8_t minutes) { + Serial.println(F("=== SleepTimer()")); + Serial.println(minutes); + this->sleepAtMillis = millis() + minutes * 60000; + // if (isPlaying()) + // mp3.playAdvertisement(302); + // delay(500); + } + uint8_t getActive() { + Serial.println(F("== SleepTimer::getActive()")); + return 1; + } }; -class FreezeDance: public Modifier { - private: - unsigned long nextStopAtMillis = 0; - const uint8_t minSecondsBetweenStops = 5; - const uint8_t maxSecondsBetweenStops = 30; - - void setNextStopAtMillis() { - uint16_t seconds = random(this->minSecondsBetweenStops, this->maxSecondsBetweenStops + 1); - Serial.println(F("=== FreezeDance::setNextStopAtMillis()")); - Serial.println(seconds); - this->nextStopAtMillis = millis() + seconds * 1000; - } +class FreezeDance : public Modifier { + private: + unsigned long nextStopAtMillis = 0; + const uint8_t minSecondsBetweenStops = 5; + const uint8_t maxSecondsBetweenStops = 30; + + void setNextStopAtMillis() { + uint16_t seconds = + random(this->minSecondsBetweenStops, this->maxSecondsBetweenStops + 1); + Serial.println(F("=== FreezeDance::setNextStopAtMillis()")); + Serial.println(seconds); + this->nextStopAtMillis = millis() + seconds * 1000; + } - public: - void loop() { - if (this->nextStopAtMillis != 0 && millis() > this->nextStopAtMillis) { - Serial.println(F("== FreezeDance::loop() -> FREEZE!")); - if (isPlaying()) { - mp3.playAdvertisement(301); - delay(500); - } - setNextStopAtMillis(); - } - } - FreezeDance(void) { - Serial.println(F("=== FreezeDance()")); + public: + void loop() { + if (this->nextStopAtMillis != 0 && millis() > this->nextStopAtMillis) { + Serial.println(F("== FreezeDance::loop() -> FREEZE!")); if (isPlaying()) { - delay(1000); - mp3.playAdvertisement(300); + mp3.playAdvertisement(301); delay(500); } setNextStopAtMillis(); } - uint8_t getActive() { - Serial.println(F("== FreezeDance::getActive()")); - return 2; + } + FreezeDance(void) { + Serial.println(F("=== FreezeDance()")); + if (isPlaying()) { + delay(1000); + mp3.playAdvertisement(300); + delay(500); } + setNextStopAtMillis(); + } + uint8_t getActive() { + Serial.println(F("== FreezeDance::getActive()")); + return 2; + } }; -class Locked: public Modifier { - public: - virtual bool handlePause() { - Serial.println(F("== Locked::handlePause() -> LOCKED!")); - return true; - } - virtual bool handleNextButton() { - Serial.println(F("== Locked::handleNextButton() -> LOCKED!")); - return true; - } - virtual bool handlePreviousButton() { - Serial.println(F("== Locked::handlePreviousButton() -> LOCKED!")); - return true; - } - virtual bool handleVolumeUp() { - Serial.println(F("== Locked::handleVolumeUp() -> LOCKED!")); - return true; - } - virtual bool handleVolumeDown() { - Serial.println(F("== Locked::handleVolumeDown() -> LOCKED!")); - return true; - } - virtual bool handleRFID(nfcTagObject *newCard) { - Serial.println(F("== Locked::handleRFID() -> LOCKED!")); - return true; - } - Locked(void) { - Serial.println(F("=== Locked()")); - // if (isPlaying()) - // mp3.playAdvertisement(303); - } - uint8_t getActive() { - return 3; - } +class Locked : public Modifier { + public: + virtual bool handlePause() { + Serial.println(F("== Locked::handlePause() -> LOCKED!")); + return true; + } + + virtual bool handleNextButton() { + Serial.println(F("== Locked::handleNextButton() -> LOCKED!")); + return true; + } + + virtual bool handlePreviousButton() { + Serial.println(F("== Locked::handlePreviousButton() -> LOCKED!")); + return true; + } + + virtual bool handleVolumeUp() { + Serial.println(F("== Locked::handleVolumeUp() -> LOCKED!")); + return true; + } + + virtual bool handleVolumeDown() { + Serial.println(F("== Locked::handleVolumeDown() -> LOCKED!")); + return true; + } + + virtual bool handleRFID(nfcTagObject* newCard) { + Serial.println(F("== Locked::handleRFID() -> LOCKED!")); + return true; + } + + Locked(void) { + Serial.println(F("=== Locked()")); + // if (isPlaying()) + // mp3.playAdvertisement(303); + } + + uint8_t getActive() { return 3; } }; -class ToddlerMode: public Modifier { - public: - virtual bool handlePause() { - Serial.println(F("== ToddlerMode::handlePause() -> LOCKED!")); - return true; - } - virtual bool handleNextButton() { - Serial.println(F("== ToddlerMode::handleNextButton() -> LOCKED!")); - return true; - } - virtual bool handlePreviousButton() { - Serial.println(F("== ToddlerMode::handlePreviousButton() -> LOCKED!")); - return true; - } - virtual bool handleVolumeUp() { - Serial.println(F("== ToddlerMode::handleVolumeUp() -> LOCKED!")); - return true; - } - virtual bool handleVolumeDown() { - Serial.println(F("== ToddlerMode::handleVolumeDown() -> LOCKED!")); - return true; - } - ToddlerMode(void) { - Serial.println(F("=== ToddlerMode()")); - // if (isPlaying()) - // mp3.playAdvertisement(304); - } - uint8_t getActive() { - Serial.println(F("== ToddlerMode::getActive()")); - return 4; - } +class ToddlerMode : public Modifier { + public: + virtual bool handlePause() { + Serial.println(F("== ToddlerMode::handlePause() -> LOCKED!")); + return true; + } + + virtual bool handleNextButton() { + Serial.println(F("== ToddlerMode::handleNextButton() -> LOCKED!")); + return true; + } + + virtual bool handlePreviousButton() { + Serial.println(F("== ToddlerMode::handlePreviousButton() -> LOCKED!")); + return true; + } + + virtual bool handleVolumeUp() { + Serial.println(F("== ToddlerMode::handleVolumeUp() -> LOCKED!")); + return true; + } + + virtual bool handleVolumeDown() { + Serial.println(F("== ToddlerMode::handleVolumeDown() -> LOCKED!")); + return true; + } + + ToddlerMode(void) { + Serial.println(F("=== ToddlerMode()")); + // if (isPlaying()) + // mp3.playAdvertisement(304); + } + + uint8_t getActive() { + Serial.println(F("== ToddlerMode::getActive()")); + return 4; + } }; -class KindergardenMode: public Modifier { - private: - nfcTagObject nextCard; - bool cardQueued = false; - - public: - virtual bool handleNext() { - Serial.println(F("== KindergardenMode::handleNext() -> NEXT")); - //if (this->nextCard.cookie == cardCookie && this->nextCard.nfcFolderSettings.folder != 0 && this->nextCard.nfcFolderSettings.mode != 0) { - //myFolder = &this->nextCard.nfcFolderSettings; - if (this->cardQueued == true) { - this->cardQueued = false; - - myCard = nextCard; - myFolder = &myCard.nfcFolderSettings; - Serial.println(myFolder->folder); - Serial.println(myFolder->mode); - playFolder(); - return true; - } - return false; - } - // virtual bool handlePause() { - // Serial.println(F("== KindergardenMode::handlePause() -> LOCKED!")); - // return true; - // } - virtual bool handleNextButton() { - Serial.println(F("== KindergardenMode::handleNextButton() -> LOCKED!")); - return true; - } - virtual bool handlePreviousButton() { - Serial.println(F("== KindergardenMode::handlePreviousButton() -> LOCKED!")); - return true; - } - virtual bool handleRFID(nfcTagObject * newCard) { // lot of work to do! - Serial.println(F("== KindergardenMode::handleRFID() -> queued!")); - this->nextCard = *newCard; - this->cardQueued = true; - if (!isPlaying()) { - handleNext(); - } +class KindergardenMode : public Modifier { + private: + nfcTagObject nextCard; + bool cardQueued = false; + + public: + virtual bool handleNext() { + Serial.println(F("== KindergardenMode::handleNext() -> NEXT")); + // if (this->nextCard.cookie == cardCookie && + // this->nextCard.nfcFolderSettings.folder != 0 && + // this->nextCard.nfcFolderSettings.mode != 0) { myFolder = + // &this->nextCard.nfcFolderSettings; + if (this->cardQueued == true) { + this->cardQueued = false; + + myCard = nextCard; + myFolder = &myCard.nfcFolderSettings; + Serial.println(myFolder->folder); + Serial.println(myFolder->mode); + playFolder(); return true; } - KindergardenMode() { - Serial.println(F("=== KindergardenMode()")); - // if (isPlaying()) - // mp3.playAdvertisement(305); - // delay(500); - } - uint8_t getActive() { - Serial.println(F("== KindergardenMode::getActive()")); - return 5; + return false; + } + + // virtual bool handlePause() { + // Serial.println(F("== KindergardenMode::handlePause() -> LOCKED!")); + // return true; + // } + + virtual bool handleNextButton() { + Serial.println(F("== KindergardenMode::handleNextButton() -> LOCKED!")); + return true; + } + + virtual bool handlePreviousButton() { + Serial.println(F("== KindergardenMode::handlePreviousButton() -> LOCKED!")); + return true; + } + + virtual bool handleRFID(nfcTagObject* newCard) { // lot of work to do! + Serial.println(F("== KindergardenMode::handleRFID() -> queued!")); + this->nextCard = *newCard; + this->cardQueued = true; + if (!isPlaying()) { + handleNext(); } + return true; + } + + KindergardenMode() { + Serial.println(F("=== KindergardenMode()")); + // if (isPlaying()) + // mp3.playAdvertisement(305); + // delay(500); + } + + uint8_t getActive() { + Serial.println(F("== KindergardenMode::getActive()")); + return 5; + } }; -class RepeatSingleModifier: public Modifier { - public: - virtual bool handleNext() { - Serial.println(F("== RepeatSingleModifier::handleNext() -> REPEAT CURRENT TRACK")); - delay(50); - if (isPlaying()) return true; - if (myFolder->mode == 3 || myFolder->mode == 9){ - mp3.playFolderTrack(myFolder->folder, queue[currentTrack - 1]); - } - else{ - mp3.playFolderTrack(myFolder->folder, currentTrack); - } - _lastTrackFinished = 0; +class RepeatSingleModifier : public Modifier { + public: + virtual bool handleNext() { + Serial.println( + F("== RepeatSingleModifier::handleNext() -> REPEAT CURRENT TRACK")); + delay(50); + if (isPlaying()) return true; + if (myFolder->mode == 3 || myFolder->mode == 9) { + mp3.playFolderTrack(myFolder->folder, queue[currentTrack - 1]); + } else { + mp3.playFolderTrack(myFolder->folder, currentTrack); } - RepeatSingleModifier() { - Serial.println(F("=== RepeatSingleModifier()")); - } - uint8_t getActive() { - Serial.println(F("== RepeatSingleModifier::getActive()")); - return 6; - } + _lastTrackFinished = 0; + return true; + } + + RepeatSingleModifier() { Serial.println(F("=== RepeatSingleModifier()")); } + + uint8_t getActive() { + Serial.println(F("== RepeatSingleModifier::getActive()")); + return 6; + } }; // An modifier can also do somethings in addition to the modified action @@ -680,38 +704,41 @@ class RepeatSingleModifier: public Modifier { // This simple FeedbackModifier will tell the volume before changing it and // give some feedback once a RFID card is detected. class FeedbackModifier : public Modifier { - private: - bool advertVolume(uint8_t volume) { - if (isPlaying()) { - mp3.playAdvertisement(volume); - delay(500); - } - - return false; + private: + bool advertVolume(uint8_t volume) { + if (isPlaying()) { + mp3.playAdvertisement(volume); + delay(500); } - public: - virtual bool handleVolumeDown() { - Serial.println(F("== FeedbackModifier::handleVolumeDown()")); + return false; + } + + public: + virtual bool handleVolumeDown() { + Serial.println(F("== FeedbackModifier::handleVolumeDown()")); return advertVolume(volume > mySettings.minVolume ? volume - 1 : volume); - } - - virtual bool handleVolumeUp() { - Serial.println(F("== FeedbackModifier::handleVolumeUp()")); + } + + virtual bool handleVolumeUp() { + Serial.println(F("== FeedbackModifier::handleVolumeUp()")); return advertVolume(volume < mySettings.maxVolume ? volume + 1 : volume); - } + } }; -// Leider kann das Modul selbst keine Queue abspielen, daher müssen wir selbst die Queue verwalten +// Leider kann das Modul selbst keine Queue abspielen, daher müssen wir selbst +// die Queue verwalten static void nextTrack(uint16_t track) { Serial.println(track); if (activeModifier != NULL) - if (activeModifier->handleNext() == true) + if (activeModifier->handleNext() == true) { return; + } if (track == _lastTrackFinished) { return; } + _lastTrackFinished = track; if (knownCard == false) @@ -724,7 +751,8 @@ static void nextTrack(uint16_t track) { if (myFolder->mode == 1 || myFolder->mode == 7) { Serial.println(F("Hörspielmodus ist aktiv -> keinen neuen Track spielen")); setstandbyTimer(); - // mp3.sleep(); // Je nach Modul kommt es nicht mehr zurück aus dem Sleep! + // mp3.sleep(); // Je nach Modul kommt es nicht mehr zurück aus dem + // Sleep! } if (myFolder->mode == 2 || myFolder->mode == 8) { if (currentTrack != numTracksInFolder) { @@ -732,11 +760,13 @@ static void nextTrack(uint16_t track) { mp3.playFolderTrack(myFolder->folder, currentTrack); Serial.print(F("Albummodus ist aktiv -> nächster Track: ")); Serial.print(currentTrack); - } else - // mp3.sleep(); // Je nach Modul kommt es nicht mehr zurück aus dem Sleep! + } else { + // mp3.sleep(); // Je nach Modul kommt es nicht mehr zurück aus dem + // Sleep! setstandbyTimer(); - { } + } } + if (myFolder->mode == 3 || myFolder->mode == 9) { if (currentTrack != numTracksInFolder - firstTrack + 1) { Serial.print(F("Party -> weiter in der Queue ")); @@ -744,7 +774,8 @@ static void nextTrack(uint16_t track) { } else { Serial.println(F("Ende der Queue -> beginne von vorne")); currentTrack = 1; - //// Wenn am Ende der Queue neu gemischt werden soll bitte die Zeilen wieder aktivieren + // Wenn am Ende der Queue neu gemischt werden soll bitte die Zeilen + // wieder aktivieren // Serial.println(F("Ende der Queue -> mische neu")); // shuffleQueue(); } @@ -754,20 +785,23 @@ static void nextTrack(uint16_t track) { if (myFolder->mode == 4) { Serial.println(F("Einzel Modus aktiv -> Strom sparen")); - // mp3.sleep(); // Je nach Modul kommt es nicht mehr zurück aus dem Sleep! + // mp3.sleep(); // Je nach Modul kommt es nicht mehr zurück aus dem + // Sleep! setstandbyTimer(); } if (myFolder->mode == 5) { if (currentTrack != numTracksInFolder) { currentTrack = currentTrack + 1; - Serial.print(F("Hörbuch Modus ist aktiv -> nächster Track und " - "Fortschritt speichern")); + Serial.print( + F("Hörbuch Modus ist aktiv -> nächster Track und " + "Fortschritt speichern")); Serial.println(currentTrack); mp3.playFolderTrack(myFolder->folder, currentTrack); // Fortschritt im EEPROM abspeichern EEPROM.update(myFolder->folder, currentTrack); } else { - // mp3.sleep(); // Je nach Modul kommt es nicht mehr zurück aus dem Sleep! + // mp3.sleep(); // Je nach Modul kommt es nicht mehr zurück aus dem + // Sleep! // Fortschritt zurück setzen EEPROM.update(myFolder->folder, 1); setstandbyTimer(); @@ -789,26 +823,28 @@ static void previousTrack() { } mp3.playFolderTrack(myFolder->folder, currentTrack); } + if (myFolder->mode == 3 || myFolder->mode == 9) { if (currentTrack != 1) { Serial.print(F("Party Modus ist aktiv -> zurück in der Qeueue ")); currentTrack--; - } - else - { + } else { Serial.print(F("Anfang der Queue -> springe ans Ende ")); currentTrack = numTracksInFolder; } Serial.println(queue[currentTrack - 1]); mp3.playFolderTrack(myFolder->folder, queue[currentTrack - 1]); } + if (myFolder->mode == 4) { Serial.println(F("Einzel Modus aktiv -> Track von vorne spielen")); mp3.playFolderTrack(myFolder->folder, currentTrack); } + if (myFolder->mode == 5) { - Serial.println(F("Hörbuch Modus ist aktiv -> vorheriger Track und " - "Fortschritt speichern")); + Serial.println( + F("Hörbuch Modus ist aktiv -> vorheriger Track und " + "Fortschritt speichern")); if (currentTrack != 1) { currentTrack = currentTrack - 1; } @@ -889,8 +925,13 @@ void previousButton() { delay(1000); } -uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, - bool preview, int previewFromFolder, int defaultValue, bool exitWithLongPress) { +uint8_t voiceMenu(int numberOfOptions, + int startMessage, + int messageOffset, + bool preview, + int previewFromFolder, + int defaultValue, + bool exitWithLongPress) { uint8_t returnValue = defaultValue; if (startMessage != 0) mp3.playMp3FolderTrack(startMessage); @@ -924,7 +965,7 @@ uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, if (upButton.pressedFor(LONG_PRESS)) { returnValue = min(returnValue + 10, numberOfOptions); Serial.println(returnValue); - //mp3.pause(); + // mp3.pause(); mp3.playMp3FolderTrack(messageOffset + returnValue); waitForTrackToFinish(); /*if (preview) { @@ -938,7 +979,7 @@ uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, if (!ignoreUpButton) { returnValue = min(returnValue + 1, numberOfOptions); Serial.println(returnValue); - //mp3.pause(); + // mp3.pause(); mp3.playMp3FolderTrack(messageOffset + returnValue); if (preview) { waitForTrackToFinish(); @@ -957,7 +998,7 @@ uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, if (downButton.pressedFor(LONG_PRESS)) { returnValue = max(returnValue - 10, 1); Serial.println(returnValue); - //mp3.pause(); + // mp3.pause(); mp3.playMp3FolderTrack(messageOffset + returnValue); waitForTrackToFinish(); /*if (preview) { @@ -971,14 +1012,13 @@ uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, if (!ignoreDownButton) { returnValue = max(returnValue - 1, 1); Serial.println(returnValue); - //mp3.pause(); + // mp3.pause(); mp3.playMp3FolderTrack(messageOffset + returnValue); if (preview) { waitForTrackToFinish(); if (previewFromFolder == 0) { mp3.playFolderTrack(returnValue, 1); - } - else { + } else { mp3.playFolderTrack(previewFromFolder, returnValue); } delay(1000); @@ -990,45 +1030,49 @@ uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, } while (true); } -bool setupFolder(folderSettings * theFolder) { +bool setupFolder(folderSettings* theFolder) { // Ordner abfragen theFolder->folder = voiceMenu(99, 301, 0, true, 0, 0, true); - if (theFolder->folder == 0) return false; + if (theFolder->folder == 0) { + return false; + } // Wiedergabemodus abfragen theFolder->mode = voiceMenu(9, 310, 310, false, 0, 0, true); - if (theFolder->mode == 0) return false; + if (theFolder->mode == 0) { + return false; + } // // Hörbuchmodus -> Fortschritt im EEPROM auf 1 setzen // EEPROM.update(theFolder->folder, 1); // Einzelmodus -> Datei abfragen - if (theFolder->mode == 4) - theFolder->special = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 320, 0, - true, theFolder->folder); + if (theFolder->mode == 4) { + theFolder->special = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), + 320, 0, true, theFolder->folder); + } // Admin Funktionen if (theFolder->mode == 6) { - //theFolder->special = voiceMenu(3, 320, 320); + // theFolder->special = voiceMenu(3, 320, 320); theFolder->folder = 0; theFolder->mode = 255; } // Spezialmodus Von-Bis if (theFolder->mode == 7 || theFolder->mode == 8 || theFolder->mode == 9) { - theFolder->special = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 321, 0, - true, theFolder->folder); - theFolder->special2 = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 322, 0, - true, theFolder->folder, theFolder->special); + theFolder->special = voiceMenu(mp3.getFolderTrackCount(theFolder->folder), + 321, 0, true, theFolder->folder); + theFolder->special2 = + voiceMenu(mp3.getFolderTrackCount(theFolder->folder), 322, 0, true, + theFolder->folder, theFolder->special); } return true; } - void setupCard() { mp3.pause(); Serial.println(F("=== setupCard()")); nfcTagObject newCard; - if (setupFolder(&newCard.nfcFolderSettings) == true) - { + if (setupFolder(&newCard.nfcFolderSettings) == true) { // Karte ist konfiguriert -> speichern mp3.pause(); do { @@ -1038,7 +1082,7 @@ void setupCard() { delay(1000); } -bool readCard(nfcTagObject * nfcTag) { +bool readCard(nfcTagObject* nfcTag) { nfcTagObject tempCard; // Show some details of the PICC (that is: the tag/card) Serial.print(F("Card UID:")); @@ -1052,17 +1096,14 @@ bool readCard(nfcTagObject * nfcTag) { byte size = sizeof(buffer); // Authenticate using key A - if ((piccType == MFRC522::PICC_TYPE_MIFARE_MINI ) || - (piccType == MFRC522::PICC_TYPE_MIFARE_1K ) || - (piccType == MFRC522::PICC_TYPE_MIFARE_4K ) ) - { + if ((piccType == MFRC522::PICC_TYPE_MIFARE_MINI) || + (piccType == MFRC522::PICC_TYPE_MIFARE_1K) || + (piccType == MFRC522::PICC_TYPE_MIFARE_4K)) { Serial.println(F("Authenticating Classic using key A...")); - status = mfrc522.PCD_Authenticate( - MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid)); - } - else if (piccType == MFRC522::PICC_TYPE_MIFARE_UL ) - { - byte pACK[] = {0, 0}; //16 bit PassWord ACK returned by the tempCard + status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, + trailerBlock, &key, &(mfrc522.uid)); + } else if (piccType == MFRC522::PICC_TYPE_MIFARE_UL) { + byte pACK[] = {0, 0}; // 16 bit PassWord ACK returned by the tempCard // Authenticate using key A Serial.println(F("Authenticating MIFARE UL...")); @@ -1081,10 +1122,9 @@ bool readCard(nfcTagObject * nfcTag) { // Serial.println(); // Read data from the block - if ((piccType == MFRC522::PICC_TYPE_MIFARE_MINI ) || - (piccType == MFRC522::PICC_TYPE_MIFARE_1K ) || - (piccType == MFRC522::PICC_TYPE_MIFARE_4K ) ) - { + if ((piccType == MFRC522::PICC_TYPE_MIFARE_MINI) || + (piccType == MFRC522::PICC_TYPE_MIFARE_1K) || + (piccType == MFRC522::PICC_TYPE_MIFARE_4K)) { Serial.print(F("Reading data from block ")); Serial.print(blockAddr); Serial.println(F(" ...")); @@ -1094,9 +1134,7 @@ bool readCard(nfcTagObject * nfcTag) { Serial.println(mfrc522.GetStatusCodeName(status)); return false; } - } - else if (piccType == MFRC522::PICC_TYPE_MIFARE_UL ) - { + } else if (piccType == MFRC522::PICC_TYPE_MIFARE_UL) { byte buffer2[18]; byte size2 = sizeof(buffer2); @@ -1153,7 +1191,6 @@ bool readCard(nfcTagObject * nfcTag) { tempCard.nfcFolderSettings.special2 = buffer[8]; if (tempCard.cookie == cardCookie) { - if (activeModifier != NULL && tempCard.nfcFolderSettings.folder != 0) { if (activeModifier->handleRFID(&tempCard) == true) { return false; @@ -1162,7 +1199,8 @@ bool readCard(nfcTagObject * nfcTag) { #ifdef BeepOnNewCard if (!isPlaying()) { - // Note(sprietl): Turn speaker on/off to minimize the impact of sound of last mp3 + // Note(sprietl): Turn speaker on/off to minimize the impact of sound of + // last mp3 spkOff(); mp3.start(); delay(100); @@ -1170,7 +1208,8 @@ bool readCard(nfcTagObject * nfcTag) { } mp3.playAdvertisement(BEEP_SOUND); delay(BEEP_DELAY); -#endif +#endif + if (tempCard.nfcFolderSettings.folder == 0) { if (activeModifier != NULL) { if (activeModifier->getActive() == tempCard.nfcFolderSettings.mode) { @@ -1178,8 +1217,7 @@ bool readCard(nfcTagObject * nfcTag) { Serial.println(F("modifier removed")); if (isPlaying()) { mp3.playAdvertisement(261); - } - else { + } else { mp3.start(); delay(100); mp3.playAdvertisement(261); @@ -1190,11 +1228,12 @@ bool readCard(nfcTagObject * nfcTag) { return false; } } - if (tempCard.nfcFolderSettings.mode != 0 && tempCard.nfcFolderSettings.mode != 255) { + + if (tempCard.nfcFolderSettings.mode != 0 && + tempCard.nfcFolderSettings.mode != 255) { if (isPlaying()) { mp3.playAdvertisement(260); - } - else { + } else { mp3.start(); delay(100); mp3.playAdvertisement(260); @@ -1202,30 +1241,44 @@ bool readCard(nfcTagObject * nfcTag) { mp3.pause(); } } - switch (tempCard.nfcFolderSettings.mode ) { + + switch (tempCard.nfcFolderSettings.mode) { case 0: case 255: - mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); adminMenu(true); break; - case 1: activeModifier = new SleepTimer(tempCard.nfcFolderSettings.special); break; - case 2: activeModifier = new FreezeDance(); break; - case 3: activeModifier = new Locked(); break; - case 4: activeModifier = new ToddlerMode(); break; - case 5: activeModifier = new KindergardenMode(); break; - case 6: activeModifier = new RepeatSingleModifier(); break; - + mfrc522.PICC_HaltA(); + mfrc522.PCD_StopCrypto1(); + adminMenu(true); + break; + case 1: + activeModifier = new SleepTimer(tempCard.nfcFolderSettings.special); + break; + case 2: + activeModifier = new FreezeDance(); + break; + case 3: + activeModifier = new Locked(); + break; + case 4: + activeModifier = new ToddlerMode(); + break; + case 5: + activeModifier = new KindergardenMode(); + break; + case 6: + activeModifier = new RepeatSingleModifier(); + break; } + delay(2000); return false; - } - else { + } else { memcpy(nfcTag, &tempCard, sizeof(nfcTagObject)); - Serial.println( nfcTag->nfcFolderSettings.folder); + Serial.println(nfcTag->nfcFolderSettings.folder); myFolder = &nfcTag->nfcFolderSettings; - Serial.println( myFolder->folder); + Serial.println(myFolder->folder); } return true; - } - else { + } else { memcpy(nfcTag, &tempCard, sizeof(nfcTagObject)); return true; } @@ -1243,6 +1296,7 @@ void resetCard() { mp3.playMp3FolderTrack(802); return; } + } while (!mfrc522.PICC_IsNewCardPresent()); if (!mfrc522.PICC_ReadCardSerial()) @@ -1254,33 +1308,30 @@ void resetCard() { void writeCard(nfcTagObject nfcTag) { MFRC522::PICC_Type mifareType; - byte buffer[16] = {0x13, 0x37, 0xb3, 0x47, // 0x1337 0xb347 magic cookie to - // identify our nfc tags - 0x02, // version 1 - nfcTag.nfcFolderSettings.folder, // the folder picked by the user - nfcTag.nfcFolderSettings.mode, // the playback mode picked by the user - nfcTag.nfcFolderSettings.special, // track or function for admin cards - nfcTag.nfcFolderSettings.special2, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - //byte size = sizeof(buffer); + byte buffer[16] = { + 0x13, 0x37, 0xb3, 0x47, // 0x1337 0xb347 magic cookie to + // identify our nfc tags + 0x02, // version 1 + nfcTag.nfcFolderSettings.folder, // the folder picked by the user + nfcTag.nfcFolderSettings.mode, // the playback mode picked by the user + nfcTag.nfcFolderSettings.special, // track or function for admin cards + nfcTag.nfcFolderSettings.special2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00}; + + // byte size = sizeof(buffer); mifareType = mfrc522.PICC_GetType(mfrc522.uid.sak); // Authenticate using key B - //authentificate with the card and set card specific parameters - if ((mifareType == MFRC522::PICC_TYPE_MIFARE_MINI ) || - (mifareType == MFRC522::PICC_TYPE_MIFARE_1K ) || - (mifareType == MFRC522::PICC_TYPE_MIFARE_4K ) ) - { + // authentificate with the card and set card specific parameters + if ((mifareType == MFRC522::PICC_TYPE_MIFARE_MINI) || + (mifareType == MFRC522::PICC_TYPE_MIFARE_1K) || + (mifareType == MFRC522::PICC_TYPE_MIFARE_4K)) { Serial.println(F("Authenticating again using key A...")); - status = mfrc522.PCD_Authenticate( - MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid)); - } - else if (mifareType == MFRC522::PICC_TYPE_MIFARE_UL ) - { - byte pACK[] = {0, 0}; //16 bit PassWord ACK returned by the NFCtag + status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, + trailerBlock, &key, &(mfrc522.uid)); + } else if (mifareType == MFRC522::PICC_TYPE_MIFARE_UL) { + byte pACK[] = {0, 0}; // 16 bit PassWord ACK returned by the NFCtag // Authenticate using key A Serial.println(F("Authenticating UL...")); @@ -1301,14 +1352,11 @@ void writeCard(nfcTagObject nfcTag) { dump_byte_array(buffer, 16); Serial.println(); - if ((mifareType == MFRC522::PICC_TYPE_MIFARE_MINI ) || - (mifareType == MFRC522::PICC_TYPE_MIFARE_1K ) || - (mifareType == MFRC522::PICC_TYPE_MIFARE_4K ) ) - { + if ((mifareType == MFRC522::PICC_TYPE_MIFARE_MINI) || + (mifareType == MFRC522::PICC_TYPE_MIFARE_1K) || + (mifareType == MFRC522::PICC_TYPE_MIFARE_4K)) { status = (MFRC522::StatusCode)mfrc522.MIFARE_Write(blockAddr, buffer, 16); - } - else if (mifareType == MFRC522::PICC_TYPE_MIFARE_UL ) - { + } else if (mifareType == MFRC522::PICC_TYPE_MIFARE_UL) { byte buffer2[16]; byte size2 = sizeof(buffer2); @@ -1333,59 +1381,61 @@ void writeCard(nfcTagObject nfcTag) { Serial.print(F("MIFARE_Write() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); mp3.playMp3FolderTrack(401); - } - else + } else { mp3.playMp3FolderTrack(400); + } Serial.println(); delay(2000); } -// ************************** Speaker On-Off ***************************************** +// ************************** Speaker On-Off +// ***************************************** #ifdef SpkOnOff // **************************Speaker On ******************* void spkOn() { if (!isSpkOn) { - Serial.println(F("Lautsprecher wird eingeschaltet!")); + Serial.println(F("Lautsprecher wird eingeschaltet!")); digitalWrite(SpkOnPin, LOW); isSpkOn = true; // Wait a tiny bit for the Amp to start up // delay(100); - } + } } // **************************Speaker Off ******************* void spkOff() { if (isSpkOn) { - Serial.println(F("Lautsprecher wird ausgeschaltet!")); + Serial.println(F("Lautsprecher wird ausgeschaltet!")); digitalWrite(SpkOnPin, HIGH); isSpkOn = false; -} + } } #endif -// ************************** END Speaker On-Off ************************************** +// ************************** END Speaker On-Off +// ************************************** /** Helper routine to dump a byte array as hex values to Serial. */ -void dump_byte_array(byte * buffer, byte bufferSize) { +void dump_byte_array(byte* buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); } } -///////////////////////////////////////// Check Bytes /////////////////////////////////// -bool checkTwo ( uint8_t a[], uint8_t b[] ) { - for ( uint8_t k = 0; k < 4; k++ ) { // Loop 4 times - if ( a[k] != b[k] ) { // IF a != b then false, because: one fails, all fail +///////////////////////////////////////// Check Bytes +////////////////////////////////////// +bool checkTwo(uint8_t a[], uint8_t b[]) { + for (uint8_t k = 0; k < 4; k++) { // Loop 4 times + if (a[k] != b[k]) { // IF a != b then false, because: one fails, all fail return false; } } return true; } - -bool askCode(uint8_t *code) { +bool askCode(uint8_t* code) { uint8_t x = 0; while (x < 4) { readButtons(); @@ -1411,7 +1461,7 @@ void adminMenu(bool fromCard) { if (mySettings.adminMenuLocked == 1) { return; } else if (mySettings.adminMenuLocked == 2) { - // Pin check + // Pin check uint8_t pin[4]; mp3.playMp3FolderTrack(991); if (askCode(pin) == true) { @@ -1422,7 +1472,7 @@ void adminMenu(bool fromCard) { return; } } else if (mySettings.adminMenuLocked == 3) { - // Match check + // Match check uint8_t a = random(10, 20); uint8_t b = random(1, 10); uint8_t c; @@ -1453,7 +1503,7 @@ void adminMenu(bool fromCard) { } int subMenu = voiceMenu(12, 900, 900, false, false, 0, true); - + if (subMenu == 0) { return; } @@ -1464,15 +1514,23 @@ void adminMenu(bool fromCard) { mfrc522.PCD_StopCrypto1(); } else if (subMenu == 2) { // Maximum Volume - mySettings.maxVolume = voiceMenu(30 - mySettings.minVolume, 930, mySettings.minVolume, false, false, mySettings.maxVolume - mySettings.minVolume) + mySettings.minVolume; + mySettings.maxVolume = + voiceMenu(30 - mySettings.minVolume, 930, mySettings.minVolume, false, + false, mySettings.maxVolume - mySettings.minVolume) + + mySettings.minVolume; mp3.playMp3FolderTrack(399); } else if (subMenu == 3) { // Minimum Volume - mySettings.minVolume = voiceMenu(mySettings.maxVolume - 1, 931, 0, false, false, mySettings.minVolume); + mySettings.minVolume = voiceMenu(mySettings.maxVolume - 1, 931, 0, false, + false, mySettings.minVolume); mp3.playMp3FolderTrack(399); } else if (subMenu == 4) { // Initial Volume - mySettings.initVolume = voiceMenu(mySettings.maxVolume - mySettings.minVolume + 1, 932, mySettings.minVolume - 1, false, false, mySettings.initVolume - mySettings.minVolume + 1) + mySettings.minVolume - 1; + mySettings.initVolume = + voiceMenu(mySettings.maxVolume - mySettings.minVolume + 1, 932, + mySettings.minVolume - 1, false, false, + mySettings.initVolume - mySettings.minVolume + 1) + + mySettings.minVolume - 1; mp3.playMp3FolderTrack(399); } else if (subMenu == 5) { // EQ @@ -1487,15 +1545,24 @@ void adminMenu(bool fromCard) { tempCard.nfcFolderSettings.folder = 0; tempCard.nfcFolderSettings.special = 0; tempCard.nfcFolderSettings.special2 = 0; - tempCard.nfcFolderSettings.mode = voiceMenu(6, 970, 970, false, false, 0, true); + tempCard.nfcFolderSettings.mode = + voiceMenu(6, 970, 970, false, false, 0, true); if (tempCard.nfcFolderSettings.mode != 0) { if (tempCard.nfcFolderSettings.mode == 1) { switch (voiceMenu(4, 960, 960)) { - case 1: tempCard.nfcFolderSettings.special = 5; break; - case 2: tempCard.nfcFolderSettings.special = 15; break; - case 3: tempCard.nfcFolderSettings.special = 30; break; - case 4: tempCard.nfcFolderSettings.special = 60; break; + case 1: + tempCard.nfcFolderSettings.special = 5; + break; + case 2: + tempCard.nfcFolderSettings.special = 15; + break; + case 3: + tempCard.nfcFolderSettings.special = 30; + break; + case 4: + tempCard.nfcFolderSettings.special = 60; + break; } } mp3.playMp3FolderTrack(800); @@ -1523,11 +1590,21 @@ void adminMenu(bool fromCard) { mp3.playMp3FolderTrack(400); } else if (subMenu == 8) { switch (voiceMenu(5, 960, 960)) { - case 1: mySettings.standbyTimer = 5; break; - case 2: mySettings.standbyTimer = 15; break; - case 3: mySettings.standbyTimer = 30; break; - case 4: mySettings.standbyTimer = 60; break; - case 5: mySettings.standbyTimer = 0; break; + case 1: + mySettings.standbyTimer = 5; + break; + case 2: + mySettings.standbyTimer = 15; + break; + case 3: + mySettings.standbyTimer = 30; + break; + case 4: + mySettings.standbyTimer = 60; + break; + case 5: + mySettings.standbyTimer = 0; + break; } mp3.playMp3FolderTrack(399); } else if (subMenu == 9) { @@ -1538,10 +1615,12 @@ void adminMenu(bool fromCard) { tempCard.version = 1; tempCard.nfcFolderSettings.mode = 4; tempCard.nfcFolderSettings.folder = voiceMenu(99, 301, 0, true); - uint8_t special = voiceMenu(mp3.getFolderTrackCount(tempCard.nfcFolderSettings.folder), 321, 0, - true, tempCard.nfcFolderSettings.folder); - uint8_t special2 = voiceMenu(mp3.getFolderTrackCount(tempCard.nfcFolderSettings.folder), 322, 0, - true, tempCard.nfcFolderSettings.folder, special); + uint8_t special = + voiceMenu(mp3.getFolderTrackCount(tempCard.nfcFolderSettings.folder), + 321, 0, true, tempCard.nfcFolderSettings.folder); + uint8_t special2 = + voiceMenu(mp3.getFolderTrackCount(tempCard.nfcFolderSettings.folder), + 322, 0, true, tempCard.nfcFolderSettings.folder, special); mp3.playMp3FolderTrack(936); waitForTrackToFinish(); @@ -1573,8 +1652,7 @@ void adminMenu(bool fromCard) { int temp = voiceMenu(2, 933, 933); if (temp == 2) { mySettings.invertVolumeButtons = true; - } - else { + } else { mySettings.invertVolumeButtons = false; } mp3.playMp3FolderTrack(399); @@ -1586,7 +1664,7 @@ void adminMenu(bool fromCard) { resetSettings(); mp3.playMp3FolderTrack(999); } else if (subMenu == 12) { - // lock admin menu + // lock admin menu int temp = voiceMenu(4, 980, 980, false); if (temp == 1) { mySettings.adminMenuLocked = 0; @@ -1611,7 +1689,6 @@ void adminMenu(bool fromCard) { } void setup() { - #ifdef SpkOnOff pinMode(SpkOnPin, OUTPUT); // Ausgang Lautsprecher-Einschaltsignal spkOff(); // Voreinstellung - Speaker Off @@ -1620,19 +1697,23 @@ void setup() { // Busy Pin pinMode(busyPin, INPUT); - // DFPlayer Mini initialisieren + // DFPlayer Mini initialisieren mp3.begin(); - Serial.begin(115200); // Es gibt ein paar Debug Ausgaben über die serielle Schnittstelle + // Es gibt ein paar Debug Ausgaben über die serielle Schnittstelle + Serial.begin(115200); - // Wert für randomSeed() erzeugen durch das mehrfache Sammeln von rauschenden LSBs eines offenen Analogeingangs + // Wert für randomSeed() erzeugen durch das mehrfache Sammeln von rauschenden + // LSBs eines offenen Analogeingangs uint32_t ADC_LSB; uint32_t ADCSeed; for (uint8_t i = 0; i < 128; i++) { ADC_LSB = analogRead(openAnalogPin) & 0x1; ADCSeed ^= ADC_LSB << (i % 32); } - randomSeed(ADCSeed); // Zufallsgenerator initialisieren + + // Zufallsgenerator initialisieren + randomSeed(ADCSeed); // Dieser Hinweis darf nicht entfernt werden Serial.println(F("\n _____ _____ _____ _____ _____")); @@ -1654,12 +1735,14 @@ void setup() { volume = mySettings.initVolume; mp3.setVolume(volume); mp3.setEq(static_cast(mySettings.eq - 1)); - // Fix für das Problem mit dem Timeout (ist jetzt in Upstream daher nicht mehr nötig!) - //mySoftwareSerial.setTimeout(10000); + + // Fix für das Problem mit dem Timeout (ist jetzt in Upstream daher nicht mehr + // nötig!) + // mySoftwareSerial.setTimeout(10000); // NFC Leser initialisieren - SPI.begin(); // Init SPI bus - mfrc522.PCD_Init(); // Init MFRC522 + SPI.begin(); // Init SPI bus + mfrc522.PCD_Init(); // Init MFRC522 #ifdef NFCgain_min mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_min); @@ -1673,9 +1756,9 @@ void setup() { mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); Serial.println(F("=== mfrc522-> RxGain_max === ")); #endif - - mfrc522 - .PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader + + // Show details of PCD - MFRC522 Card Reader + mfrc522.PCD_DumpVersionToSerial(); for (byte i = 0; i < 6; i++) { key.keyByte[i] = 0xFF; } @@ -1690,7 +1773,8 @@ void setup() { pinMode(shutdownPin, OUTPUT); digitalWrite(shutdownPin, LOW); - // RESET --- ALLE DREI KNÖPFE BEIM STARTEN GEDRÜCKT HALTEN -> alle EINSTELLUNGEN werden gelöscht + // RESET --- ALLE DREI KNÖPFE BEIM STARTEN GEDRÜCKT HALTEN -> alle + // EINSTELLUNGEN werden gelöscht if (digitalRead(buttonPause) == LOW && digitalRead(buttonUp) == LOW && digitalRead(buttonDown) == LOW) { Serial.println(F("Reset -> EEPROM wird gelöscht")); @@ -1702,7 +1786,7 @@ void setup() { #ifdef SpkOnOff spkOn(); -#endif +#endif // Start Shortcut "at Startup" - e.g. Welcome Sound playShortCut(3); @@ -1723,11 +1807,16 @@ void loop() { readButtons(); // admin menu - if ((pauseButton.pressedFor(LONG_PRESS) || upButton.pressedFor(LONG_PRESS) || downButton.pressedFor(LONG_PRESS)) && pauseButton.isPressed() && upButton.isPressed() && downButton.isPressed()) { + if ((pauseButton.pressedFor(LONG_PRESS) || + upButton.pressedFor(LONG_PRESS) || + downButton.pressedFor(LONG_PRESS)) && + pauseButton.isPressed() && upButton.isPressed() && + downButton.isPressed()) { mp3.pause(); do { readButtons(); - } while (pauseButton.isPressed() || upButton.isPressed() || downButton.isPressed()); + } while (pauseButton.isPressed() || upButton.isPressed() || + downButton.isPressed()); readButtons(); adminMenu(); break; @@ -1743,8 +1832,7 @@ void loop() { if (isPlaying()) { mp3.pause(); setstandbyTimer(); - } - else if (knownCard) { + } else if (knownCard) { mp3.start(); disablestandbyTimer(); } @@ -1761,17 +1849,16 @@ void loop() { uint8_t advertTrack; if (myFolder->mode == 3 || myFolder->mode == 9) { advertTrack = (queue[currentTrack - 1]); - } - else { + } else { advertTrack = currentTrack; } - // Spezialmodus Von-Bis für Album und Party gibt die Dateinummer relativ zur Startposition wieder + // Spezialmodus Von-Bis für Album und Party gibt die Dateinummer relativ + // zur Startposition wieder if (myFolder->mode == 8 || myFolder->mode == 9) { advertTrack = advertTrack - myFolder->special + 1; } mp3.playAdvertisement(advertTrack); - } - else { + } else { playShortCut(0); } ignorePauseButton = true; @@ -1782,12 +1869,10 @@ void loop() { if (isPlaying()) { if (!mySettings.invertVolumeButtons) { volumeUpButton(); - } - else { + } else { nextButton(); } - } - else { + } else { playShortCut(1); } ignoreUpButton = true; @@ -1796,13 +1881,11 @@ void loop() { if (!ignoreUpButton) { if (!mySettings.invertVolumeButtons) { nextButton(); - } - else { + } else { volumeUpButton(); } } ignoreUpButton = false; - } if (downButton.pressedFor(LONG_PRESS)) { @@ -1810,12 +1893,10 @@ void loop() { if (isPlaying()) { if (!mySettings.invertVolumeButtons) { volumeDownButton(); - } - else { + } else { previousButton(); } - } - else { + } else { playShortCut(2); } ignoreDownButton = true; @@ -1824,8 +1905,7 @@ void loop() { if (!ignoreDownButton) { if (!mySettings.invertVolumeButtons) { previousButton(); - } - else { + } else { volumeDownButton(); } } @@ -1836,12 +1916,10 @@ void loop() { if (isPlaying()) { if (!mySettings.invertVolumeButtons) { volumeUpButton(); - } - else { + } else { nextButton(); } - } - else { + } else { playShortCut(1); } } @@ -1849,12 +1927,10 @@ void loop() { if (isPlaying()) { if (!mySettings.invertVolumeButtons) { volumeDownButton(); - } - else { + } else { previousButton(); } - } - else { + } else { playShortCut(2); } } @@ -1868,7 +1944,8 @@ void loop() { return; if (readCard(&myCard) == true) { - if (myCard.cookie == cardCookie && myCard.nfcFolderSettings.folder != 0 && myCard.nfcFolderSettings.mode != 0) { + if (myCard.cookie == cardCookie && myCard.nfcFolderSettings.folder != 0 && + myCard.nfcFolderSettings.mode != 0) { playFolder(); } From bdd22d364f24d36606c832b20479c14ea934d754 Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 13:14:46 +0100 Subject: [PATCH 14/21] fixup: format with clang chromium style --- src/Tonuino.cpp | 55 +++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index f6910ba7..875c5233 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -680,8 +680,11 @@ class RepeatSingleModifier : public Modifier { Serial.println( F("== RepeatSingleModifier::handleNext() -> REPEAT CURRENT TRACK")); delay(50); - if (isPlaying()) + + if (isPlaying()) { return true; + } + if (myFolder->mode == 3 || myFolder->mode == 9) { mp3.playFolderTrack(myFolder->folder, queue[currentTrack - 1]); } else { @@ -882,9 +885,9 @@ void readButtons() { } void volumeUpButton() { - if (activeModifier != NULL) - if (activeModifier->handleVolumeUp() == true) - return; + if (activeModifier != NULL && activeModifier->handleVolumeUp() == true) { + return; + } Serial.println(F("=== volumeUp()")); if (volume < mySettings.maxVolume) { @@ -895,9 +898,9 @@ void volumeUpButton() { } void volumeDownButton() { - if (activeModifier != NULL) - if (activeModifier->handleVolumeDown() == true) - return; + if (activeModifier != NULL && activeModifier->handleVolumeDown() == true) { + return; + } Serial.println(F("=== volumeDown()")); if (volume > mySettings.minVolume) { @@ -908,18 +911,19 @@ void volumeDownButton() { } void nextButton() { - if (activeModifier != NULL) - if (activeModifier->handleNextButton() == true) - return; + if (activeModifier != NULL && activeModifier->handleNextButton() == true) { + return; + } nextTrack(random(65536)); delay(1000); } void previousButton() { - if (activeModifier != NULL) - if (activeModifier->handlePreviousButton() == true) - return; + if (activeModifier != NULL && + activeModifier->handlePreviousButton() == true) { + return; + } previousTrack(); delay(1000); @@ -933,8 +937,10 @@ uint8_t voiceMenu(int numberOfOptions, int defaultValue, bool exitWithLongPress) { uint8_t returnValue = defaultValue; - if (startMessage != 0) + if (startMessage != 0) { mp3.playMp3FolderTrack(startMessage); + } + Serial.print(F("=== voiceMenu() (")); Serial.print(numberOfOptions); Serial.println(F(" Options)")); @@ -1299,8 +1305,9 @@ void resetCard() { } while (!mfrc522.PICC_IsNewCardPresent()); - if (!mfrc522.PICC_ReadCardSerial()) + if (!mfrc522.PICC_ReadCardSerial()) { return; + } Serial.print(F("Karte wird neu konfiguriert!")); setupCard(); @@ -1439,14 +1446,21 @@ bool askCode(uint8_t* code) { uint8_t x = 0; while (x < 4) { readButtons(); - if (pauseButton.pressedFor(LONG_PRESS)) + if (pauseButton.pressedFor(LONG_PRESS)) { break; - if (pauseButton.wasReleased()) + } + + if (pauseButton.wasReleased()) { code[x++] = 1; - if (upButton.wasReleased()) + } + + if (upButton.wasReleased()) { code[x++] = 2; - if (downButton.wasReleased()) + } + + if (downButton.wasReleased()) { code[x++] = 3; + } } return true; } @@ -1940,8 +1954,9 @@ void loop() { // RFID Karte wurde aufgelegt - if (!mfrc522.PICC_ReadCardSerial()) + if (!mfrc522.PICC_ReadCardSerial()) { return; + } if (readCard(&myCard) == true) { if (myCard.cookie == cardCookie && myCard.nfcFolderSettings.folder != 0 && From 1c7468616bc9bb7ea4ff084057757ea6469b6485 Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 13:14:57 +0100 Subject: [PATCH 15/21] fixup: chromium clang style --- .clang-format | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..4f0e6550 --- /dev/null +++ b/.clang-format @@ -0,0 +1,2 @@ +BasedOnStyle: Chromium +IndentWidth: 2 From e5b22f4b024777829c5fde7500aac060d42a19ee Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 13:20:41 +0100 Subject: [PATCH 16/21] Remodel redundant true and false in conditionals --- src/Tonuino.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 875c5233..2265841d 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -623,7 +623,7 @@ class KindergardenMode : public Modifier { // this->nextCard.nfcFolderSettings.folder != 0 && // this->nextCard.nfcFolderSettings.mode != 0) { myFolder = // &this->nextCard.nfcFolderSettings; - if (this->cardQueued == true) { + if (this->cardQueued) { this->cardQueued = false; myCard = nextCard; @@ -734,7 +734,7 @@ class FeedbackModifier : public Modifier { static void nextTrack(uint16_t track) { Serial.println(track); if (activeModifier != NULL) - if (activeModifier->handleNext() == true) { + if (activeModifier->handleNext()) { return; } @@ -744,7 +744,7 @@ static void nextTrack(uint16_t track) { _lastTrackFinished = track; - if (knownCard == false) + if (!knownCard) // Wenn eine neue Karte angelernt wird soll das Ende eines Tracks nicht // verarbeitet werden return; @@ -885,7 +885,7 @@ void readButtons() { } void volumeUpButton() { - if (activeModifier != NULL && activeModifier->handleVolumeUp() == true) { + if (activeModifier != NULL && activeModifier->handleVolumeUp()) { return; } @@ -898,7 +898,7 @@ void volumeUpButton() { } void volumeDownButton() { - if (activeModifier != NULL && activeModifier->handleVolumeDown() == true) { + if (activeModifier != NULL && activeModifier->handleVolumeDown()) { return; } @@ -911,7 +911,7 @@ void volumeDownButton() { } void nextButton() { - if (activeModifier != NULL && activeModifier->handleNextButton() == true) { + if (activeModifier != NULL && activeModifier->handleNextButton()) { return; } @@ -921,7 +921,7 @@ void nextButton() { void previousButton() { if (activeModifier != NULL && - activeModifier->handlePreviousButton() == true) { + activeModifier->handlePreviousButton()) { return; } @@ -1078,7 +1078,7 @@ void setupCard() { mp3.pause(); Serial.println(F("=== setupCard()")); nfcTagObject newCard; - if (setupFolder(&newCard.nfcFolderSettings) == true) { + if (setupFolder(&newCard.nfcFolderSettings)) { // Karte ist konfiguriert -> speichern mp3.pause(); do { @@ -1198,7 +1198,7 @@ bool readCard(nfcTagObject* nfcTag) { if (tempCard.cookie == cardCookie) { if (activeModifier != NULL && tempCard.nfcFolderSettings.folder != 0) { - if (activeModifier->handleRFID(&tempCard) == true) { + if (activeModifier->handleRFID(&tempCard)) { return false; } } @@ -1470,7 +1470,7 @@ void adminMenu(bool fromCard) { disablestandbyTimer(); mp3.pause(); knownCard = false; - if (fromCard == false) { + if (!fromCard) { // Admin menu has been locked - it still can be trigged via admin card if (mySettings.adminMenuLocked == 1) { return; @@ -1478,8 +1478,8 @@ void adminMenu(bool fromCard) { // Pin check uint8_t pin[4]; mp3.playMp3FolderTrack(991); - if (askCode(pin) == true) { - if (checkTwo(pin, mySettings.adminMenuPin) == false) { + if (askCode(pin)) { + if (!checkTwo(pin, mySettings.adminMenuPin)) { return; } } else { @@ -1838,11 +1838,11 @@ void loop() { if (pauseButton.wasReleased()) { if (activeModifier != NULL) { - if (activeModifier->handlePause() == true) { + if (activeModifier->handlePause()) { return; } } - if (ignorePauseButton == false) { + if (!ignorePauseButton) { if (isPlaying()) { mp3.pause(); setstandbyTimer(); @@ -1853,9 +1853,9 @@ void loop() { } ignorePauseButton = false; } else if (pauseButton.pressedFor(LONG_PRESS) && - ignorePauseButton == false) { + !ignorePauseButton) { if (activeModifier != NULL) { - if (activeModifier->handlePause() == true) { + if (activeModifier->handlePause()) { return; } } @@ -1958,7 +1958,7 @@ void loop() { return; } - if (readCard(&myCard) == true) { + if (readCard(&myCard)) { if (myCard.cookie == cardCookie && myCard.nfcFolderSettings.folder != 0 && myCard.nfcFolderSettings.mode != 0) { playFolder(); From a7bd05f77cdf4cc1fb7aa1eb87911f3383fc3783 Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 23:29:12 +0100 Subject: [PATCH 17/21] Use a status LED --- src/Tonuino.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 2265841d..c5d3116a 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -30,6 +30,8 @@ #define BeepOnNewCard +#define UseStatusLED + #ifdef BeepOnNewCard #define BEEP_DELAY 1000 #define BEEP_SOUND 400 @@ -156,6 +158,86 @@ void dump_byte_array(byte* buffer, byte bufferSize); void adminMenu(bool fromCard = false); bool knownCard = false; +#ifdef UseStatusLED +#define STATUS_LED_BLUE A3 +#define STATUS_LED_GREEN A4 +#define STATUS_LED_RED A5 + +#define ANALOG_LOW 0 +#define ANALOG_HIGH 1024 + +class StatusLED { + private: + uint8_t redPin; + uint8_t greenPin; + uint8_t bluePin; + + byte currentRed = 0; + byte currentGreen = 0; + byte currentBlue = 0; + + bool isSleeping = false; + + int mapColor(byte color) { + return map(color, LOW, HIGH, ANALOG_LOW, ANALOG_HIGH); + } + + void showColor(byte red, byte green, byte blue) { + if (this->currentRed != red) { + analogWrite(this->redPin, mapColor(red)); + this->currentRed = red; + } + if (this->currentGreen != green) { + analogWrite(this->greenPin, mapColor(green)); + this->currentGreen = green; + } + if (currentBlue != blue) { + analogWrite(this->bluePin, mapColor(blue)); + this->currentBlue = blue; + } + } + + public: + StatusLED(uint8_t redPin, uint8_t greenPin, uint8_t bluePin) { + this->redPin = STATUS_LED_RED; + this->greenPin = STATUS_LED_GREEN; + this->bluePin = STATUS_LED_BLUE; + this->isSleeping = false; + } + + void setup() { + pinMode(this->redPin, OUTPUT); + pinMode(this->bluePin, OUTPUT); + pinMode(this->greenPin, OUTPUT); + this->isSleeping = false; + this->showColor(HIGH, 0, 0); + } + + void sleep() { + this->isSleeping = true; + this->showColor(0, 0, 0); + } + + void newCard() { this->showColor(0, HIGH, HIGH); } + + void adminMenu() { this->showColor(HIGH, HIGH, 0); } + + void setupCard() { this->showColor(HIGH, 0, HIGH); } + + void loop() { + if (!this->isSleeping && !ignorePauseButton) { + if (isPlaying()) { + this->showColor(0, HIGH, 0); + } else { + this->showColor(0, 0, HIGH); + } + } + } +}; + +StatusLED* statusLed = NULL; +#endif + // implement a notification class, // its member methods will get called class Mp3Notify { @@ -338,6 +420,9 @@ void checkStandbyAtMillis() { mfrc522.PCD_AntennaOff(); mfrc522.PCD_SoftPowerDown(); mp3.sleep(); +#ifdef UseStatusLED + statusLed->sleep(); +#endif set_sleep_mode(SLEEP_MODE_PWR_DOWN); cli(); // Disable interrupts @@ -1203,6 +1288,10 @@ bool readCard(nfcTagObject* nfcTag) { } } +#ifdef UseStatusLED + statusLed->newCard(); +#endif + #ifdef BeepOnNewCard if (!isPlaying()) { // Note(sprietl): Turn speaker on/off to minimize the impact of sound of @@ -1467,6 +1556,9 @@ bool askCode(uint8_t* code) { void adminMenu(bool fromCard) { Serial.println(F("=== adminMenu()")); +#ifdef UseStatusLED + statusLed->adminMenu(); +#endif disablestandbyTimer(); mp3.pause(); knownCard = false; @@ -1708,6 +1800,11 @@ void setup() { spkOff(); // Voreinstellung - Speaker Off #endif +#ifdef UseStatusLED + statusLed = new StatusLED(STATUS_LED_RED, STATUS_LED_GREEN, STATUS_LED_BLUE); + statusLed->setup(); +#endif + // Busy Pin pinMode(busyPin, INPUT); @@ -1811,6 +1908,10 @@ void loop() { checkStandbyAtMillis(); mp3.loop(); +#ifdef UseStatusLED + statusLed->loop(); +#endif + // Modifier : WIP! if (activeModifier != NULL) { activeModifier->loop(); @@ -1966,6 +2067,9 @@ void loop() { // Neue Karte konfigurieren else if (myCard.cookie != cardCookie) { +#ifdef UseStatusLED + statusLed->setupCard(); +#endif knownCard = false; mp3.playMp3FolderTrack(300); waitForTrackToFinish(); From 62cb517f01fe0103d41f0bab6e96ea76469e3656 Mon Sep 17 00:00:00 2001 From: seder Date: Sun, 14 Feb 2021 23:30:01 +0100 Subject: [PATCH 18/21] fixup: speaker on/off stuff --- src/Tonuino.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index c5d3116a..136536ec 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -416,13 +416,15 @@ void checkStandbyAtMillis() { // http://discourse.voss.earth/t/intenso-s10000-powerbank-automatische-abschaltung-software-only/805 // powerdown to 27mA (powerbank switches off after 30-60s) - spkOff(); mfrc522.PCD_AntennaOff(); mfrc522.PCD_SoftPowerDown(); mp3.sleep(); #ifdef UseStatusLED statusLed->sleep(); #endif +#ifdef SpkOnOff + spkOff(); +#endif set_sleep_mode(SLEEP_MODE_PWR_DOWN); cli(); // Disable interrupts @@ -1294,12 +1296,16 @@ bool readCard(nfcTagObject* nfcTag) { #ifdef BeepOnNewCard if (!isPlaying()) { - // Note(sprietl): Turn speaker on/off to minimize the impact of sound of - // last mp3 +#ifdef SpkOnOff + // Note(sprietl): + // Turn speaker on/off to minimize the impact of sound of last mp3 spkOff(); +#endif mp3.start(); delay(100); +#ifdef SpkOnOff spkOn(); +#endif } mp3.playAdvertisement(BEEP_SOUND); delay(BEEP_DELAY); From f9f304f7497fc84599ef87f2b909ed8e5fccc504 Mon Sep 17 00:00:00 2001 From: seder Date: Mon, 15 Feb 2021 00:45:14 +0100 Subject: [PATCH 19/21] fixup: logic changes --- src/Tonuino.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 136536ec..8f94cc1b 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -1007,8 +1007,7 @@ void nextButton() { } void previousButton() { - if (activeModifier != NULL && - activeModifier->handlePreviousButton()) { + if (activeModifier != NULL && activeModifier->handlePreviousButton()) { return; } @@ -1959,8 +1958,7 @@ void loop() { } } ignorePauseButton = false; - } else if (pauseButton.pressedFor(LONG_PRESS) && - !ignorePauseButton) { + } else if (pauseButton.pressedFor(LONG_PRESS) && !ignorePauseButton) { if (activeModifier != NULL) { if (activeModifier->handlePause()) { return; @@ -2075,7 +2073,7 @@ void loop() { else if (myCard.cookie != cardCookie) { #ifdef UseStatusLED statusLed->setupCard(); -#endif +#endif knownCard = false; mp3.playMp3FolderTrack(300); waitForTrackToFinish(); From 1c086275af3941c320da7f1a7837b2011d1bfea9 Mon Sep 17 00:00:00 2001 From: seder Date: Tue, 16 Feb 2021 01:41:40 +0100 Subject: [PATCH 20/21] fixup: improve status led --- src/Tonuino.cpp | 77 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 19 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 8f94cc1b..85a6cc6a 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -163,11 +163,15 @@ bool knownCard = false; #define STATUS_LED_GREEN A4 #define STATUS_LED_RED A5 -#define ANALOG_LOW 0 -#define ANALOG_HIGH 1024 - class StatusLED { private: + enum BlockMode { + NONE, + UNTIL_PLAYING, + UNTIL_PAUSE, + AFTER_N_CHANGES + }; + uint8_t redPin; uint8_t greenPin; uint8_t bluePin; @@ -176,23 +180,24 @@ class StatusLED { byte currentGreen = 0; byte currentBlue = 0; + byte changes = 0; + bool isSleeping = false; + bool previouslyPlaying = false; - int mapColor(byte color) { - return map(color, LOW, HIGH, ANALOG_LOW, ANALOG_HIGH); - } + BlockMode blockMode = UNTIL_PAUSE; void showColor(byte red, byte green, byte blue) { if (this->currentRed != red) { - analogWrite(this->redPin, mapColor(red)); + digitalWrite(this->redPin, red); this->currentRed = red; } if (this->currentGreen != green) { - analogWrite(this->greenPin, mapColor(green)); + digitalWrite(this->greenPin, green); this->currentGreen = green; } if (currentBlue != blue) { - analogWrite(this->bluePin, mapColor(blue)); + digitalWrite(this->bluePin, blue); this->currentBlue = blue; } } @@ -210,28 +215,59 @@ class StatusLED { pinMode(this->bluePin, OUTPUT); pinMode(this->greenPin, OUTPUT); this->isSleeping = false; - this->showColor(HIGH, 0, 0); + this->showColor(HIGH, LOW, LOW); } void sleep() { this->isSleeping = true; - this->showColor(0, 0, 0); + this->showColor(LOW, LOW, LOW); } - void newCard() { this->showColor(0, HIGH, HIGH); } + void newCard() { + this->showColor(LOW, HIGH, HIGH); + this->blockMode = UNTIL_PLAYING; + } - void adminMenu() { this->showColor(HIGH, HIGH, 0); } + void adminMenu() { + this->showColor(HIGH, HIGH, LOW); + this->blockMode = UNTIL_PAUSE; + } + + void setupCard() { + this->showColor(HIGH, LOW, HIGH); + this->blockMode = UNTIL_PAUSE; + } - void setupCard() { this->showColor(HIGH, 0, HIGH); } + void advertTrack() { + this->showColor(HIGH, LOW, LOW); + this->blockMode = AFTER_N_CHANGES; + this->changes = 3; + } void loop() { - if (!this->isSleeping && !ignorePauseButton) { - if (isPlaying()) { - this->showColor(0, HIGH, 0); - } else { - this->showColor(0, 0, HIGH); + bool currentlyPlaying = isPlaying(); + if (!this->isSleeping) { + if (this->blockMode == NONE) { + if (currentlyPlaying) { + this->showColor(LOW, HIGH, LOW); + } else { + this->showColor(LOW, LOW, HIGH); + } + } else if (this->blockMode == AFTER_N_CHANGES) { + if (currentlyPlaying != previouslyPlaying) { + if (this->changes == 0) { + this->blockMode = NONE; + } else { + this->changes--; + } + } + } else if (currentlyPlaying && this->blockMode == UNTIL_PLAYING) { + this->blockMode = NONE; + } else if (!currentlyPlaying && this->blockMode == UNTIL_PAUSE) { + this->blockMode = NONE; } } + this->previouslyPlaying = currentlyPlaying; } }; @@ -1976,6 +2012,9 @@ void loop() { if (myFolder->mode == 8 || myFolder->mode == 9) { advertTrack = advertTrack - myFolder->special + 1; } +#ifdef UseStatusLED + statusLed->advertTrack(); +#endif mp3.playAdvertisement(advertTrack); } else { playShortCut(0); From 7a1ef123684ed670eeee9dae69f44b205cac8b4c Mon Sep 17 00:00:00 2001 From: seder Date: Tue, 16 Feb 2021 01:45:25 +0100 Subject: [PATCH 21/21] fixup: beep more --- src/Tonuino.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Tonuino.cpp b/src/Tonuino.cpp index 85a6cc6a..560349f6 100644 --- a/src/Tonuino.cpp +++ b/src/Tonuino.cpp @@ -1318,13 +1318,6 @@ bool readCard(nfcTagObject* nfcTag) { tempCard.nfcFolderSettings.special = buffer[7]; tempCard.nfcFolderSettings.special2 = buffer[8]; - if (tempCard.cookie == cardCookie) { - if (activeModifier != NULL && tempCard.nfcFolderSettings.folder != 0) { - if (activeModifier->handleRFID(&tempCard)) { - return false; - } - } - #ifdef UseStatusLED statusLed->newCard(); #endif @@ -1346,6 +1339,13 @@ bool readCard(nfcTagObject* nfcTag) { delay(BEEP_DELAY); #endif + if (tempCard.cookie == cardCookie) { + if (activeModifier != NULL && tempCard.nfcFolderSettings.folder != 0) { + if (activeModifier->handleRFID(&tempCard)) { + return false; + } + } + if (tempCard.nfcFolderSettings.folder == 0) { if (activeModifier != NULL) { if (activeModifier->getActive() == tempCard.nfcFolderSettings.mode) {