diff --git a/firmware/manifest.json b/firmware/manifest.json index f2e5171..295bb8b 100644 --- a/firmware/manifest.json +++ b/firmware/manifest.json @@ -1,12 +1,12 @@ { "name": "BLLED Firmware", - "version": "Stable 19.3.24", + "version": "Stable 26.3.24", "new_install_prompt_erase": true, "builds": [ { "chipFamily": "ESP32", "parts": [ - { "path": "esp32dev/BLLC_19.3.24.bin", "offset": 0 } + { "path": "esp32dev/BLLC_26.3.24.bin", "offset": 0 } ] } ] diff --git a/firmware/manifestexpirimental.json b/firmware/manifestexpirimental.json index d5035da..e6793c8 100644 --- a/firmware/manifestexpirimental.json +++ b/firmware/manifestexpirimental.json @@ -1,12 +1,12 @@ { "name": "BLLEDCONTROLLER", - "version": "Experimental 25 2 24", + "version": "Experimental 26.3.24", "new_install_prompt_erase": true, "builds": [ { "chipFamily": "ESP32", "parts": [ - { "path": "esp32dev/BLLC_Experimental_25.2.24.bin", "offset": 0 } + { "path": "esp32dev/BLLC_Experimental_26.3.24.bin", "offset": 0 } ] } ] diff --git a/src/filesystem.h b/src/filesystem.h index a10d912..0bce617 100644 --- a/src/filesystem.h +++ b/src/filesystem.h @@ -28,43 +28,94 @@ void saveFileSystem(){ Serial.println(F("Saving config")); JsonDocument json; + json["ssid"] = globalVariables.SSID; + json["appw"] = globalVariables.APPW; json["printerIp"] = printerConfig.printerIP; json["accessCode"] = printerConfig.accessCode; json["serialNumber"] = printerConfig.serialNumber; - json["ssid"] = globalVariables.SSID; - json["appw"] = globalVariables.APPW; //json["webpagePassword"] = printerConfig.webpagePassword; json["bssi"] = printerConfig.BSSID; json["brightness"] = printerConfig.brightness; - // BLLED Settings + // LED Behaviour (Choose One) + json["maintMode"] = printerConfig.maintMode; + json["discoMode"] = printerConfig.discoMode; json["replicatestate"] = printerConfig.replicatestate; - json["errordetection"] = printerConfig.errordetection; + // Running Color + json["runningRGB"] = printerConfig.runningColor.RGBhex; + json["runningWW"] = printerConfig.runningColor.ww; + json["runningCW"] = printerConfig.runningColor.cw; + // Test LED Colors + json["showtestcolor"] = printerConfig.testcolorEnabled; + json["testRGB"] = printerConfig.testColor.RGBhex; + json["testWW"] = printerConfig.testColor.ww; + json["testCW"] = printerConfig.testColor.cw; + json["debugwifi"] = printerConfig.debugwifi; + // Options json["finishindication"] = printerConfig.finishindication; - json["lidarLightsOff"] = printerConfig.lidarLightsOff; + json["finishColor"] = printerConfig.finishColor.RGBhex; + json["finishWW"] = printerConfig.finishColor.ww; + json["finishCW"] = printerConfig.finishColor.cw; + json["finishExit"] = printerConfig.finishExit; + json["finish_check"] = printerConfig.finish_check; + json["finishTimerMins"] = printerConfig.finishTimeOut; json["inactivityEnabled"] = printerConfig.inactivityEnabled; json["inactivityTimeOut"] = printerConfig.inactivityTimeOut; - json["discoMode"] = printerConfig.discoMode; - json["maintMode"] = printerConfig.maintMode; // Debugging json["debuging"] = printerConfig.debuging; json["debugingchange"] = printerConfig.debugingchange; json["mqttdebug"] = printerConfig.mqttdebug; - // Test - Fixed LED Colors - json["testRGB"] = printerConfig.testRGB; - json["testwarmwhite"] = printerConfig.testwarmwhite; - json["testcoldwhite"] = printerConfig.testcoldwhite; + // Printer Dependant + json["p1Printer"] = printerVariables.isP1Printer; + json["doorSwitch"] = printerVariables.useDoorSwtich; + // Customise LED Colors (during Lidar) + json["stage14RGB"] = printerConfig.stage14Color.RGBhex; + json["stage14WW"] = printerConfig.stage14Color.ww; + json["stage14CW"] = printerConfig.stage14Color.cw; + json["stage1RGB"] = printerConfig.stage1Color.RGBhex; + json["stage1WW"] = printerConfig.stage1Color.ww; + json["stage1CW"] = printerConfig.stage1Color.cw; + json["stage8RGB"] = printerConfig.stage8Color.RGBhex; + json["stage8WW"] = printerConfig.stage8Color.ww; + json["stage8CW"] = printerConfig.stage8Color.cw; + json["stage9RGB"] = printerConfig.stage9Color.RGBhex; + json["stage9WW"] = printerConfig.stage9Color.ww; + json["stage9CW"] = printerConfig.stage9Color.cw; + json["stage10RGB"] = printerConfig.stage10Color.RGBhex; + json["stage10WW"] = printerConfig.stage10Color.ww; + json["stage10CW"] = printerConfig.stage10Color.cw; // Customise LED Colors - json["wifiRGB"] = printerConfig.wifiRGB; - json["finishRGB"] = printerConfig.finishRGB; - json["pauseRGB"] = printerConfig.pauseRGB; - json["firstlayerRGB"] = printerConfig.firstlayerRGB; - json["nozzleclogRGB"] = printerConfig.nozzleclogRGB; - json["hmsSeriousRGB"] = printerConfig.hmsSeriousRGB; - json["hmsFatalRGB"] = printerConfig.hmsFatalRGB; - json["filamentRunoutRGB"] = printerConfig.filamentRunoutRGB; - json["frontCoverRGB"] = printerConfig.frontCoverRGB; - json["nozzleTempRGB"] = printerConfig.nozzleTempRGB; - json["bedTempRGB"] = printerConfig.bedTempRGB; + json["errordetection"] = printerConfig.errordetection; + json["wifiRGB"] = printerConfig.wifiRGB.RGBhex; + json["wifiWW"] = printerConfig.wifiRGB.ww; + json["wifiCW"] = printerConfig.wifiRGB.cw; + json["pauseRGB"] = printerConfig.pauseRGB.RGBhex; + json["pauseWW"] = printerConfig.pauseRGB.ww; + json["pauseCW"] = printerConfig.pauseRGB.cw; + json["firstlayerRGB"] = printerConfig.firstlayerRGB.RGBhex; + json["firstlayerWW"] = printerConfig.firstlayerRGB.ww; + json["firstlayerCW"] = printerConfig.firstlayerRGB.cw; + json["nozzleclogRGB"] = printerConfig.nozzleclogRGB.RGBhex; + json["nozzleclogWW"] = printerConfig.nozzleclogRGB.ww; + json["nozzleclogCW"] = printerConfig.nozzleclogRGB.cw; + json["hmsSeriousRGB"] = printerConfig.hmsSeriousRGB.RGBhex; + json["hmsSeriousWW"] = printerConfig.hmsSeriousRGB.ww; + json["hmsSeriousCW"] = printerConfig.hmsSeriousRGB.cw; + json["hmsFatalRGB"] = printerConfig.hmsFatalRGB.RGBhex; + json["hmsFatalWW"] = printerConfig.hmsFatalRGB.ww; + json["hmsFatalCW"] = printerConfig.hmsFatalRGB.cw; + json["filamentRunoutRGB"] = printerConfig.filamentRunoutRGB.RGBhex; + json["filamentRunoutWW"] = printerConfig.filamentRunoutRGB.ww; + json["filamentRunoutCW"] = printerConfig.filamentRunoutRGB.cw; + json["frontCoverRGB"] = printerConfig.frontCoverRGB.RGBhex; + json["frontCoverWW"] = printerConfig.frontCoverRGB.ww; + json["frontCoverCW"] = printerConfig.frontCoverRGB.cw; + json["nozzleTempRGB"] = printerConfig.nozzleTempRGB.RGBhex; + json["nozzleTempWW"] = printerConfig.nozzleTempRGB.ww; + json["nozzleTempCW"] = printerConfig.nozzleTempRGB.cw; + json["bedTempRGB"] = printerConfig.bedTempRGB.RGBhex; + json["bedTempWW"] = printerConfig.bedTempRGB.ww; + json["bedTempCW"] = printerConfig.bedTempRGB.cw; + File configFile = LittleFS.open(configPath, "w"); if (!configFile) { Serial.println(F("Failed to save config")); @@ -115,36 +166,49 @@ void loadFileSystem(){ //strcpy(printerConfig.webpagePassword, json["webpagePassword"]); strcpy(printerConfig.BSSID, json["bssi"]); printerConfig.brightness = json["brightness"]; - //BLLED Settings + // LED Behaviour (Choose One) + printerConfig.maintMode = json["maintMode"]; + printerConfig.discoMode = json["discoMode"]; printerConfig.replicatestate = json["replicatestate"]; - printerConfig.errordetection = json["errordetection"]; + // Running Color + printerConfig.runningColor = hex2rgb(json["runningRGB"],json["runningWW"],json["runningCW"]); + // Test LED Colors + printerConfig.testcolorEnabled = json["showtestcolor"]; + printerConfig.testColor = hex2rgb(json["testRGB"],json["testWW"],json["testCW"]); + printerConfig.debugwifi = json["debugwifi"]; + // Options printerConfig.finishindication = json["finishindication"]; - printerConfig.lidarLightsOff = json["lidarLightsOff"]; + printerConfig.finishColor = hex2rgb(json["finishColor"],json["finishWW"],json["finishCW"]); + printerConfig.finishExit = json["finishExit"]; + printerConfig.finishTimeOut = json["finishTimerMins"]; + printerConfig.finish_check = json["finish_check"]; printerConfig.inactivityEnabled = json["inactivityEnabled"]; printerConfig.inactivityTimeOut = json["inactivityTimeOut"]; - printerConfig.discoMode = json["discoMode"]; - printerConfig.maintMode = json["maintMode"]; - //Debugging + // Debugging printerConfig.debuging = json["debuging"]; printerConfig.debugingchange = json["debugingchange"]; printerConfig.mqttdebug = json["mqttdebug"]; - //Test - Fixed LED Colors - strcpy(printerConfig.testRGB, json["testRGB"]); - printerConfig.testwarmwhite = json["testwarmwhite"]; - printerConfig.testcoldwhite = json["testcoldwhite"]; + // Printer Dependant + printerVariables.isP1Printer = json["p1Printer"]; + printerVariables.useDoorSwtich = json["doorSwitch"]; + printerConfig.stage14Color = hex2rgb(json["stage14RGB"],json["stage14WW"],json["stage14CW"]); + printerConfig.stage1Color = hex2rgb(json["stage1RGB"],json["stage1WW"],json["stage1CW"]); + printerConfig.stage8Color = hex2rgb(json["stage8RGB"],json["stage8WW"],json["stage8CW"]); + printerConfig.stage9Color = hex2rgb(json["stage9RGB"],json["stage9WW"],json["stage9CW"]); + printerConfig.stage10Color = hex2rgb(json["stage10RGB"],json["stage10WW"],json["stage10CW"]); // Customise LED Colors - strcpy(printerConfig.wifiRGB, json["wifiRGB"]); - strcpy(printerConfig.finishRGB, json["finishRGB"]); - strcpy(printerConfig.pauseRGB, json["pauseRGB"]); - strcpy(printerConfig.firstlayerRGB, json["firstlayerRGB"]); - strcpy(printerConfig.nozzleclogRGB, json["nozzleclogRGB"]); - strcpy(printerConfig.hmsSeriousRGB, json["hmsSeriousRGB"]); - strcpy(printerConfig.hmsFatalRGB, json["hmsFatalRGB"]); - strcpy(printerConfig.filamentRunoutRGB, json["filamentRunoutRGB"]); - strcpy(printerConfig.frontCoverRGB, json["frontCoverRGB"]); - strcpy(printerConfig.nozzleTempRGB, json["nozzleTempRGB"]); - strcpy(printerConfig.bedTempRGB, json["bedTempRGB"]); - + printerConfig.errordetection = json["errordetection"]; + printerConfig.wifiRGB = hex2rgb(json["wifiRGB"],json["wifiWW"],json["wifiCW"]); + + printerConfig.pauseRGB = hex2rgb(json["pauseRGB"],json["pauseWW"],json["pauseCW"]); + printerConfig.firstlayerRGB = hex2rgb(json["firstlayerRGB"],json["firstlayerWW"],json["firstlayerCW"]); + printerConfig.nozzleclogRGB = hex2rgb(json["nozzleclogRGB"],json["nozzleclogWW"],json["nozzleclogCW"]); + printerConfig.hmsSeriousRGB = hex2rgb(json["hmsSeriousRGB"],json["hmsSeriousWW"],json["hmsSeriousCW"]); + printerConfig.hmsFatalRGB = hex2rgb(json["hmsFatalRGB"],json["hmsFatalWW"],json["hmsFatalCW"]); + printerConfig.filamentRunoutRGB = hex2rgb(json["filamentRunoutRGB"],json["filamentRunoutWW"],json["filamentRunoutCW"]); + printerConfig.frontCoverRGB = hex2rgb(json["frontCoverRGB"],json["frontCoverWW"],json["frontCoverCW"]); + printerConfig.nozzleTempRGB = hex2rgb(json["nozzleTempRGB"],json["nozzleTempWW"],json["nozzleTempCW"]); + printerConfig.bedTempRGB = hex2rgb(json["bedTempRGB"],json["bedTempWW"],json["bedTempCW"]); Serial.println(F("Loaded config")); } else { Serial.println(F("Failed loading config")); diff --git a/src/leds.h b/src/leds.h index 00c5e47..f95da7b 100644 --- a/src/leds.h +++ b/src/leds.h @@ -16,16 +16,13 @@ int currentBlue = 0; int currentWarm = 0; int currentCold = 0; -struct COLOR { - short r; - short g; - short b; -}; +unsigned long tempms = 0; +unsigned long oldms = 0; -COLOR hex2rgb(String hex) { +COLOR hex2rgb(String hex, short ww_value = 0, short cw_value = 0) { COLOR color; long hexcolor; - + strcpy(color.RGBhex, hex.c_str()); if(hex.charAt(0) == '#') { hex.remove(0,1); } @@ -36,6 +33,9 @@ COLOR hex2rgb(String hex) { color.r = (hexcolor & 0xFF0000) >> 16; color.g = (hexcolor & 0x00FF00) >> 8; color.b = (hexcolor & 0x0000FF); + color.ww = ww_value; + color.cw = cw_value; + return color; } @@ -104,19 +104,24 @@ void tweenToColor(int targetRed, int targetGreen, int targetBlue, int targetWarm } //Helper functions to allow changes colors by using a string or integer hex code +void tweenToColor(COLOR targetcolor) { + tweenToColor(targetcolor.r, targetcolor.g, targetcolor.b, targetcolor.ww, targetcolor.cw); +} //Example: tweenToColor("#33FD67") -void tweenToColor(String strTargetColor) { +void tweenToColor(String strTargetColor, short ww_value = 0, short cw_value = 0) { COLOR targetcolor; - targetcolor = hex2rgb(strTargetColor); - tweenToColor(targetcolor.r, targetcolor.g, targetcolor.b, 0, 0); + targetcolor = hex2rgb(strTargetColor, ww_value, cw_value); + tweenToColor(targetcolor.r, targetcolor.g, targetcolor.b, targetcolor.ww, targetcolor.cw); } //Example: tweenToColor(0xFFACA5) -void tweenToColor(int hexValue) { +void tweenToColor(int hexValue, short ww_value = 0, short cw_value = 0) { COLOR targetcolor; targetcolor.r = ((hexValue >> 16) & 0xFF) / 255.0; targetcolor.g = ((hexValue >> 8) & 0xFF) / 255.0; targetcolor.b = ((hexValue) & 0xFF) / 255.0; - tweenToColor(targetcolor.r, targetcolor.g, targetcolor.b, 0, 0); + targetcolor.ww = ww_value; + targetcolor.cw = cw_value; + tweenToColor(targetcolor.r, targetcolor.g, targetcolor.b, targetcolor.ww, targetcolor.cw); } float hue = 0.0; @@ -124,8 +129,16 @@ float hue = 0.0; void RGBCycle() { if (printerConfig.discoMode == false) { //Skip changing colors if RGB Mode not enabled + printerConfig.discoMode_update = true; return; } + if(printerConfig.discoMode_update){ + printerConfig.discoMode_update = false; + if (printerConfig.debugingchange){ + Serial.println(F("RGB Mode, turning LEDs... w-i-l-d!")); + }; + } + if (printerVariables.online == false) { analogWrite(redPin, 0); analogWrite(greenPin, 0); @@ -145,14 +158,7 @@ void RGBCycle() { currentWarm = 0; currentCold = 0; - //Adjust to set brightness level - float brightness = (float)printerConfig.brightness/100.0; - - int brightenedRed = round(currentRed * brightness); - int brightenedGreen = round(currentGreen * brightness); - int brightenedBlue = round(currentBlue * brightness); - int brightenedWarm = round(currentWarm * brightness); - int brightenedCold = round(currentCold * brightness); + //Need to add code so it adjusts to set brightness level analogWrite(redPin, currentRed); analogWrite(greenPin, currentGreen); @@ -161,28 +167,45 @@ void RGBCycle() { analogWrite(coldPin, currentCold); } - - -void idleStatus(){ +void printLogs(String Desc, COLOR thisColor){ if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("Stage ")); - Serial.print(printerVariables.stage); - Serial.print(F(", IDLE Turning LEDs to WHITE. Brightness: ")); + Serial.print(Desc); + Serial.print(F(" - Turning LEDs to: ")); + if((thisColor.r + thisColor.g + thisColor.b + thisColor.ww + thisColor.cw) == 0){ + Serial.println(F(" OFF")); + return; + } + Serial.print(F(" r:")); + Serial.print(thisColor.r); + Serial.print(F(" g:")); + Serial.print(thisColor.g); + Serial.print(F(" b:")); + Serial.print(thisColor.b); + Serial.print(F(" ww:")); + Serial.print(thisColor.ww); + Serial.print(F(" cw:")); + Serial.print(thisColor.cw); + Serial.print(F(" Brightness: ")); Serial.println(printerConfig.brightness); }; } - - - +void printLogs(String Desc, short r, short g, short b, short ww, short cw){ + COLOR tempColor; + tempColor.r = r; + tempColor.g = g; + tempColor.b = b; + tempColor.ww = ww; + tempColor.cw = cw; + printLogs(Desc, tempColor); +} void updateleds(){ //Maintenance Mode - White lights on regardless of printer power, WiFi or MQTT connection //priortised over Wifi Strength Display or Custom TEST color - if (printerConfig.maintMode && printerConfig.updateMaintenance){ + if (printerConfig.maintMode && printerConfig.maintMode_update){ tweenToColor(0,0,0,255,255); //WHITE - printerConfig.updateMaintenance = false; - if (printerConfig.debugingchange){ - Serial.println(F("Maintenance Mode, turning LEDs to WHITE")); - }; + printerConfig.maintMode_update = false; + printLogs("Maintenance Mode", 0,0,0,255,255); + Serial.println(F("(Expect MQTT connection to drop and need reconnecting after exiting maintenance mode)")); return; } @@ -206,29 +229,15 @@ void updateleds(){ } //TEST Color Enabled - LED ON regardless of printer state - if (printerVariables.testcolorEnabled && !printerConfig.maintMode && !printerConfig.debugwifi){ - COLOR customColor = hex2rgb(printerConfig.testRGB); - - tweenToColor(customColor.r,customColor.g,customColor.b,printerConfig.testwarmwhite,printerConfig.testcoldwhite); //Variable Test Color - if (printerConfig.debugingchange){ - Serial.print(F("LED Test ON, Changing LEDs to selected color: ")); - Serial.print(customColor.r); - Serial.print(F(" ")); - Serial.print(customColor.g); - Serial.print(F(" ")); - Serial.print(customColor.b); - Serial.print(F(" ")); - Serial.print(printerConfig.testwarmwhite); - Serial.print(F(" ")); - Serial.print(printerConfig.testcoldwhite); - Serial.print(F(" Brightness: ")); - Serial.println(printerConfig.brightness); - }; - printerConfig.updateTestLEDS = false; + if (printerConfig.testcolorEnabled && printerConfig.testcolor_update){ + tweenToColor(printerConfig.testColor); //Variable Test Color + printLogs("LED Test ON", printerConfig.testColor); + Serial.println(F("(Expect MQTT connection to drop and need reconnecting after exiting test color mode)")); + printerConfig.testcolor_update = false; return; - } + } - if(printerVariables.testcolorEnabled || printerConfig.maintMode || printerConfig.debugwifi){ + if(printerConfig.testcolorEnabled || printerConfig.maintMode || printerConfig.debugwifi){ //Skip trying to set a color as it's in one of the override states return; } @@ -241,12 +250,25 @@ void updateleds(){ Serial.println(printerVariables.gcodeState); Serial.println(printerVariables.printerledstate); Serial.println(printerVariables.hmsstate); - Serial.println(printerVariables.parsedHMS); + Serial.println(printerVariables.parsedHMSlevel); } + //Initial Boot + if (printerVariables.initalisedLEDs == false) { + printerVariables.initalisedLEDs = true; //Run once per boot + printerConfig.inactivityStartms = millis(); //restart idle timer + printerConfig.isIdleOFFActive = false; + printerVariables.waitingForDoor = false; + printerConfig.finish_check = false; + printerVariables.lastdoorClosems = millis(); + Serial.println(F("Initial Boot")); + return; + } + + //TOGGLE LIGHTS via DOOR //If door is closed twice in 6 seconds, it will flip the state of the lights - if (printerVariables.doorSwitchenabled == true){ + if (printerVariables.doorSwitchTriggered == true){ if (printerConfig.debugingchange){ Serial.print(F("Door closed twice within 6 seconds - Toggling LEDs to ")); } @@ -256,109 +278,164 @@ void updateleds(){ if (printerConfig.debuging || printerConfig.debugingchange) { Serial.println(F("ON")); } + printerConfig.isIdleOFFActive = false; } else { tweenToColor(0,0,0,0,0); //OFF //Shortcut to idle state - note: light will go back on immediately if there is an MQTT change of any sort - printerVariables.inactivityLightsOff = true; - printerVariables.inactivityStartms = millis()-printerConfig.inactivityTimeOut; + printerConfig.isIdleOFFActive = true; + printerConfig.inactivityStartms = (millis()-printerConfig.inactivityTimeOut); if (printerConfig.debuging || printerConfig.debugingchange) { Serial.println(F("OFF")); } } - printerVariables.doorSwitchenabled = false; + printerVariables.doorSwitchTriggered = false; } + + //RED -- RED -- RED -- RED + // allow errordetection to turn ledstrip red + if (printerConfig.errordetection == true){ - //OFF -- OFF -- OFF -- OFF + //Fillament runout + if (printerVariables.stage == 6 || printerVariables.overridestage == 6){ + tweenToColor(printerConfig.filamentRunoutRGB); //Customisable - Default is RED + printLogs("Stage 6, FILAMENT RUNOUT", printerConfig.filamentRunoutRGB); + return; + }; + + //Front Cover Removed + if (printerVariables.stage == 17 || printerVariables.overridestage == 17){ + tweenToColor(printerConfig.frontCoverRGB); //Customisable - Default is RED + printLogs("Stage 17, FRONT COVER REMOVED", printerConfig.frontCoverRGB); + return; + }; + + //Nozzle Temp fail + if (printerVariables.stage == 20 || printerVariables.overridestage == 20){ + tweenToColor(printerConfig.nozzleTempRGB); //Customisable - Default is RED + printLogs("Stage 20, NOZZLE TEMP FAIL", printerConfig.nozzleTempRGB); + return; + }; - if (printerConfig.discoMode == true){ - //Skip all the following code that sets specific colors if RGB Mode is on - done in RGBCycle() + //Bed Temp Fail + if (printerVariables.stage == 21 || printerVariables.overridestage == 21){ + tweenToColor(printerConfig.bedTempRGB); //Customisable - Default is RED + printLogs("Stage 21, BED TEMP FAIL", printerConfig.bedTempRGB); + return; + }; + //SERIOUS HMS state + if (printerVariables.parsedHMSlevel == "Serious"){ + tweenToColor(printerConfig.hmsSeriousRGB); //Customisable - Default is RED + Serial.print(F("HMS SERIOUS Severity ")); + Serial.print(F("Error Code: ")); + Serial.printf("%016llX\n", printerVariables.parsedHMScode); + printLogs("PROBLEM", printerConfig.hmsSeriousRGB); + return; + }; + + //FATAL HMS state + if (printerVariables.parsedHMSlevel == "Fatal"){ + tweenToColor(printerConfig.hmsFatalRGB); //Customisable - Default is RED + Serial.print(F("HMS FATAL Severity ")); + Serial.print(F("Error Code: ")); + Serial.printf("%016llX\n", printerVariables.parsedHMScode); + printLogs("PROBLEM", printerConfig.hmsFatalRGB); + return; + }; + }; + + //BLUE -- BLUE -- BLUE -- BLUE + + // Pause (by user or via Gcode) + if ((printerVariables.stage == 16 || printerVariables.stage == 30) || printerVariables.gcodeState == "PAUSE"){ + tweenToColor(printerConfig.pauseRGB); //Customisable - Default is BLUE + printLogs("Stage 16, gcodeState pause, PAUSED", printerConfig.pauseRGB); + return; + } + + //First Layer Error PAUSED + if (printerVariables.stage == 34){ + tweenToColor(printerConfig.firstlayerRGB); //Customisable - Default is BLUE + printLogs("Stage 34, FIRST LAYER ERROR, PAUSED", printerConfig.firstlayerRGB); return; } + //Nozzle Clog PAUSED + if (printerVariables.stage == 35){ + tweenToColor(printerConfig.nozzleclogRGB); //Customisable - Default is BLUE + printLogs("Stage 35, NOZZLE CLOG, PAUSED", printerConfig.nozzleclogRGB); + return; + } + + //OFF -- OFF -- OFF -- OFF + //printer offline and MQTT disconnect more than 5 seconds. if (printerVariables.online == false && (millis() - printerVariables.disconnectMQTTms) >= 5000){ tweenToColor(0,0,0,0,0); //OFF - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.println(F("Printer offline, Turning LEDs OFF")); - }; + printLogs("Printer offline", 0,0,0,0,0); return; } - // replicate printer behaviour - if (printerVariables.printerledstate == false && printerConfig.replicatestate == true){ + // replicate printer behaviour OFF + if (printerConfig.replicatestate && printerConfig.replicate_update && printerVariables.printerledstate == false){ tweenToColor(0,0,0,0,0); //OFF - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.println(F("LED Replication, Turning LEDs OFF")); - }; + printLogs("LED Replication OFF", 0,0,0,0,0); + printerConfig.replicate_update = false; return; } //Cleaning nozzle - if (printerVariables.stage == 14 && printerConfig.lidarLightsOff){ - tweenToColor(0,0,0,0,0); //OFF - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.println(F("Stage 14, CLEANING NOZZLE, Turning LEDs OFF")); - }; + if (printerVariables.stage == 14){ + tweenToColor(printerConfig.stage14Color); //Customisable - Default is OFF + printLogs("Stage 14, CLEANING NOZZLE", printerConfig.stage14Color); return; } //Auto Bed Leveling - if (printerVariables.stage == 1 && printerConfig.lidarLightsOff){ - tweenToColor(0,0,0,0,0); //OFF - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.println(F("Stage 1, BED LEVELING, Turning LEDs OFF")); - }; + if (printerVariables.stage == 1){ + tweenToColor(printerConfig.stage1Color); //Customisable - Default is OFF + printLogs("Stage 1, BED LEVELING", printerConfig.stage1Color); return; } //Calibrating Extrusion - if (printerVariables.stage == 8 && printerConfig.lidarLightsOff){ - tweenToColor(0,0,0,0,0); //OFF - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.println(F("Stage 8, CALIBRATING EXTRUSION, Turning LEDs OFF")); - }; + if (printerVariables.stage == 8){ + tweenToColor(printerConfig.stage8Color); //Customisable - Default is OFF + printLogs("Stage 8, CALIBRATING EXTRUSION", printerConfig.stage8Color); return; } //Scaning surface - if (printerVariables.stage == 9 && printerConfig.lidarLightsOff){ - tweenToColor(0,0,0,0,0); //OFF - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.println(F("Stage 9, SCANNING BED SURFACE, Turning LEDs OFF")); - }; + if (printerVariables.stage == 9){ + tweenToColor(printerConfig.stage9Color); //Customisable - Default is OFF + printLogs("Stage 9, SCANNING BED SURFACE", printerConfig.stage9Color); return; } //Inspecting First Layer - if ((printerVariables.stage == 10 && printerConfig.lidarLightsOff) - || (printerVariables.inspectingFirstLayer && printerConfig.lidarLightsOff)){ - tweenToColor(0,0,0,0,0); //OFF - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.println(F("Stage 10 / HMS 0C00, FIRST LAYER INSPECTION, Turning LEDs OFF")); - }; + if (printerVariables.stage == 10 || printerVariables.overridestage == 10){ + tweenToColor(printerConfig.stage10Color); //Customisable - Default is OFF + printLogs("Stage 10 / HMS 0C00, FIRST LAYER INSPECTION", printerConfig.stage10Color); return; } //Calibrating MicroLidar - if (printerVariables.stage == 12 && printerConfig.lidarLightsOff){ - tweenToColor(0,0,0,0,0); //OFF - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.println(F("Stage 12, CALIBRATING MICRO LIDAR, Turning LEDs OFF")); - }; + if (printerVariables.stage == 12){ + tweenToColor(printerConfig.stage10Color); + printLogs("Stage 12, CALIBRATING MICRO LIDAR", printerConfig.stage10Color); return; } // Idle Timeout (Has to be enabled) if ((printerVariables.stage == -1 || printerVariables.stage == 255) - && !printerVariables.waitingForDoor - && (millis() - printerVariables.inactivityStartms) > printerConfig.inactivityTimeOut - && printerVariables.inactivityLightsOff == false + && !((printerConfig.finishExit && printerVariables.waitingForDoor) || (printerConfig.finishExit == false && ((millis() - printerConfig.finishStartms) < printerConfig.finishTimeOut))) + && (millis() - printerConfig.inactivityStartms) > printerConfig.inactivityTimeOut + && printerConfig.isIdleOFFActive == false && printerConfig.inactivityEnabled){ tweenToColor(0,0,0,0,0); //OFF - printerVariables.inactivityLightsOff = true; + printerConfig.isIdleOFFActive = true; if (printerConfig.debuging || printerConfig.debugingchange){ Serial.print(F("Idle Timeout [")); Serial.print((int)(printerConfig.inactivityTimeOut / 60000)); @@ -366,166 +443,56 @@ void updateleds(){ }; return; } - - //RED -- RED -- RED -- RED - - // allow errordetection to turn ledstrip red - if (printerConfig.errordetection == true){ - - //SERIOUS HMS state - if (printerVariables.parsedHMS == "Serious"){ - tweenToColor(printerConfig.hmsSeriousRGB); //Customisable - Default is RED - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("HMS Severity, SERIOUS PROBLEM, Turning LEDs to ")); - Serial.println(printerConfig.hmsSeriousRGB); - }; - return; - }; - - //FATAL HMS state - if (printerVariables.parsedHMS == "Fatal"){ - tweenToColor(printerConfig.hmsFatalRGB); //Customisable - Default is RED - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("HMS Severity, FATAL PROBLEM, Turning LEDs to ")); - Serial.println(printerConfig.hmsFatalRGB); - }; - return; - }; - - //Fillament runout - if (printerVariables.stage == 6){ - tweenToColor(printerConfig.filamentRunoutRGB); //Customisable - Default is RED - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("Stage 17, FILAMENT RUNOUT, Turning LEDs to ")); - Serial.println(printerConfig.filamentRunoutRGB); - }; - return; - }; - - //Front Cover Removed - if (printerVariables.stage == 17){ - tweenToColor(printerConfig.frontCoverRGB); //Customisable - Default is RED - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("Stage 17, FRONT COVER REMOVED, Turning LEDs to ")); - Serial.println(printerConfig.frontCoverRGB); - }; - return; - }; - - //Nozzle Temp fail - if (printerVariables.stage == 20){ - tweenToColor(printerConfig.nozzleTempRGB); //Customisable - Default is RED - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("Stage 20, NOZZLE TEMP FAIL, Turning LEDs to ")); - Serial.println(printerConfig.nozzleTempRGB); - }; - return; - }; - - //Bed Temp Fail - if (printerVariables.stage == 21){ - tweenToColor(printerConfig.bedTempRGB); //Customisable - Default is RED - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("Stage 21, BED TEMP FAIL, Turning LEDs to ")); - Serial.println(printerConfig.bedTempRGB); - }; - return; - }; - }; - - //BLUE -- BLUE -- BLUE -- BLUE - - // Pause (by user or via Gcode) - if ((printerVariables.stage == 6 || printerVariables.stage == 30) || printerVariables.gcodeState == "PAUSE"){ - tweenToColor(printerConfig.pauseRGB); //Customisable - Default is BLUE - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("Stage ")); - Serial.print(printerVariables.stage); - Serial.print(F(", gcodeState PAUSE, Turning LEDs to ")); - Serial.println(printerConfig.pauseRGB); - }; - return; - } - - //First Layer Error PAUSED - if (printerVariables.stage == 34){ - tweenToColor(printerConfig.firstlayerRGB); //Customisable - Default is BLUE - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("Stage 34, FIRST LAYER ERROR, PAUSED Turning LEDs to ")); - Serial.println(printerConfig.firstlayerRGB); - }; - return; - } - - //Nozzle Clog PAUSED - if (printerVariables.stage == 35){ - tweenToColor(printerConfig.nozzleclogRGB); //Customisable - Default is BLUE - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("Stage 35, NOZZLE CLOG, PAUSED Turning LEDs to ")); - Serial.println(printerConfig.nozzleclogRGB); - }; - return; - } //ON -- ON -- ON -- ON - //Initial Boot - if (printerVariables.initalisedLEDs == false) { - tweenToColor(0,0,0,255,255); //WHITE - printerVariables.initalisedLEDs = true; - printerVariables.inactivityStartms = millis(); - printerVariables.waitingForDoor = false; - printerVariables.lastdoorClosems = millis(); - Serial.println(F("Initial BLLED bootup - Turning LEDs to WHITE, Start IDLE timer")); - return; - } - //Preheating Bed if (printerVariables.stage == 2){ - tweenToColor(0,0,0,255,255); //WHITE - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.println(F("Stage 2, PREHEATING BED, Turning LEDs to WHITE")); - }; + tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE + printLogs("Stage 2, PREHEATING BED", printerConfig.runningColor); return; } //Printing or Resume after Pausing if (printerVariables.stage == 0 && printerVariables.gcodeState == "RUNNING"){ - tweenToColor(0,0,0,255,255); //WHITE - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("Stage 0, PRINTING - gcodeState RUNNING, Turning LEDs to WHITE. Brightness: ")); - Serial.println(printerConfig.brightness); - }; + tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE + printLogs("Stage 0, PRINTING - gcodeState RUNNING", printerConfig.runningColor); return; } //for IDLE - P1 uses 255, X1 uses -1 - //This covers both IDLE & FINISH if ((printerVariables.stage == -1 || printerVariables.stage == 255) - && printerVariables.waitingForDoor == false - && (millis() - printerVariables.inactivityStartms < printerConfig.inactivityTimeOut)){ - tweenToColor(0,0,0,255,255); //WHITE - idleStatus(); + && !((printerConfig.finishExit && printerVariables.waitingForDoor) || (printerConfig.finishExit == false && ((millis() - printerConfig.finishStartms) < printerConfig.finishTimeOut))) + && (millis() - printerConfig.inactivityStartms < printerConfig.inactivityTimeOut)){ + tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE + printLogs("Stage -1/255, IDLE", printerConfig.runningColor); return; } //User Cancelled Print if (printerVariables.gcodeState == "FAILED"){ - tweenToColor(0,0,0,255,255); //WHITE - idleStatus(); + tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE + printLogs("Stage -1/255, FAILED", printerConfig.runningColor); return; } //Print file just sent if (printerVariables.gcodeState == "PREPARE"){ - tweenToColor(0,0,0,255,255); //WHITE - idleStatus(); + tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE + printLogs("Stage -1/255, PREPARE", printerConfig.runningColor); + return; + } + + //Homing ToolHead + if (printerVariables.stage == 13){ + //No color change assigned + Serial.println(F("STAGE 13, HOMING TOOL HEAD")); return; } //Offline if (printerVariables.gcodeState == "OFFLINE" || printerVariables.stage == -2){ - tweenToColor(0,0,0,255,255); //WHITE - idleStatus(); + tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE + printLogs("Stage -1/255, OFFLINE", printerConfig.runningColor); return; } @@ -533,12 +500,18 @@ void updateleds(){ //Sets to green when print finishes AND user wants Finish Indication enabled if (printerVariables.finished == true && printerConfig.finishindication == true){ - tweenToColor(printerConfig.finishRGB); //Customisable - Default is GREEN + tweenToColor(printerConfig.finishColor); //Customisable - Default is GREEN + printLogs("Finished print", printerConfig.finishColor); printerVariables.finished = false; - if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("Finished print, Turning LEDs to ")); - Serial.println(printerConfig.finishRGB); - }; + return; + } + + // replicate printer behaviour ON + if (printerConfig.replicatestate && printerConfig.replicate_update && printerVariables.printerledstate + && !((printerConfig.finishExit && printerVariables.waitingForDoor) || (printerConfig.finishExit == false && ((millis() - printerConfig.finishStartms) < printerConfig.finishTimeOut)))){ + tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE + printLogs("LED Replication ON", printerConfig.runningColor); + printerConfig.replicate_update = false; return; } } @@ -555,28 +528,49 @@ void setupLeds() { void ledsloop(){ RGBCycle(); + if((millis() - tempms) > 30000 && printerConfig.discoMode) { + Serial.print(F("[")); + Serial.print(millis()); + Serial.print(F("]")); + Serial.print(F("RGB Cycle Mode - next update in 30 seconds")); + tempms = millis(); + } // Turn off GREEN if... finished and Door OPENED or CLOSED in last 5 secs AND user wants Finish Indication enabled // Can't use Boolean finished as printer defaults back to IDLE via MQTT - if((printerVariables.waitingForDoor && printerConfig.finishindication == true + if((printerVariables.waitingForDoor && printerConfig.finishindication && printerConfig.finishExit && ((millis() - printerVariables.lastdoorClosems) < 6000 || (millis() - printerVariables.lastdoorOpenms) < 6000))){ if (printerConfig.debuging || printerConfig.debugingchange){ Serial.println(F("Updating from finishloop after Door interaction - Starting IDLE timer")); - }; + } printerVariables.waitingForDoor = false; - printerVariables.inactivityStartms = millis(); + printerConfig.inactivityStartms = millis(); + printerConfig.isIdleOFFActive = false; + updateleds(); + } + + if((printerConfig.finish_check && printerConfig.finishindication && printerConfig.finishExit == false + && ((millis() - printerConfig.finishStartms) > printerConfig.finishTimeOut))){ + if (printerConfig.debuging || printerConfig.debugingchange){ + Serial.println(F("Updating from finishloop after Finish timer expired - Starting IDLE timer")); + } + printerConfig.finish_check = false; + printerConfig.inactivityStartms = millis(); + printerConfig.isIdleOFFActive = false; updateleds(); } //Need an trigger action to run updateleds() so lights turn off //There is no change in the printer STATE, just monitoring the timer and triggering when over a threshhold - if(printerConfig.inactivityEnabled && (millis() - printerVariables.inactivityStartms) > printerConfig.inactivityTimeOut - && printerVariables.finished == false && printerVariables.inactivityLightsOff == false) + if(printerConfig.inactivityEnabled + && (millis() - printerConfig.inactivityStartms) > printerConfig.inactivityTimeOut + && printerVariables.finished == false && printerConfig.isIdleOFFActive == false) { //Opening or Closing the Door will turn LEDs back on and restart the timer. updateleds(); } + delay(10); } -#endif +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 202e6ed..a1d4983 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,35 +7,55 @@ #include "serialmanager.h" #include "wifi-manager.h" + void defaultcolors(){ Serial.println(F("Setting default customisable colors")); - strcpy(printerConfig.testRGB, "#3F3CFB"); //Violet - strcpy(printerConfig.wifiRGB, "#FFA500"); //Orange - strcpy(printerConfig.finishRGB, "#00FF00"); //Green - strcpy(printerConfig.pauseRGB, "#0000FF"); //Blue - strcpy(printerConfig.firstlayerRGB, "#0000FF"); //Blue - strcpy(printerConfig.nozzleclogRGB, "#0000FF"); //Blue - strcpy(printerConfig.hmsSeriousRGB, "#FF0000"); //Red - strcpy(printerConfig.hmsFatalRGB, "#FF0000"); //Red - strcpy(printerConfig.filamentRunoutRGB, "#FF0000"); //Red - strcpy(printerConfig.frontCoverRGB, "#FF0000"); //Red - strcpy(printerConfig.nozzleTempRGB, "#FF0000"); //Red - strcpy(printerConfig.bedTempRGB, "#FF0000"); //Red + printerConfig.runningColor = hex2rgb("#000000",255,255);//WHITE Running + printerConfig.testColor = hex2rgb("#3F3CFB"); //Violet Test + printerConfig.finishColor = hex2rgb("#00FF00"); //Green Finish + + printerConfig.stage14Color = hex2rgb("#000000"); //OFF Cleaning Nozzle + printerConfig.stage1Color = hex2rgb("#0000AA"); //OFF Bed Leveling + printerConfig.stage8Color = hex2rgb("#000000"); //OFF Calibrating Extrusion + printerConfig.stage9Color = hex2rgb("#000000"); //OFF Scanning Bed Surface + printerConfig.stage10Color = hex2rgb("#000000"); //OFF First Layer Inspection + + printerConfig.wifiRGB = hex2rgb("#FFA500"); //Orange Wifi Scan + + printerConfig.pauseRGB = hex2rgb("#0000FF"); //Blue Pause + printerConfig.firstlayerRGB = hex2rgb("#0000FF"); //Blue + printerConfig.nozzleclogRGB = hex2rgb("#0000FF"); //Blue + printerConfig.hmsSeriousRGB = hex2rgb("#FF0000"); //Red + printerConfig.hmsFatalRGB = hex2rgb("#FF0000"); //Red + printerConfig.filamentRunoutRGB = hex2rgb("#FF0000"); //Red + printerConfig.frontCoverRGB = hex2rgb("#FF0000"); //Red + printerConfig.nozzleTempRGB = hex2rgb("#FF0000"); //Red + printerConfig.bedTempRGB = hex2rgb("#FF0000"); //Red + + } +unsigned long lastUpdatems = 0; void setup(){ Serial.begin(115200); delay(100); Serial.println(F("Initializing")); Serial.println(ESP.getFreeHeap()); + Serial.println(""); + Serial.print(F("** Using firmware version: ")); + Serial.print(globalVariables.FWVersion); + Serial.println(F(" **")); + Serial.println(""); defaultcolors(); setupLeds(); tweenToColor(255,255,255,255,255); //ALL LEDS ON + Serial.println(F("")); delay(1000); tweenToColor(255,0,0,0,0); //RED setupFileSystem(); loadFileSystem(); + Serial.println(F("")); delay(500); tweenToColor(printerConfig.wifiRGB); //Customisable - Default is ORANGE @@ -61,10 +81,13 @@ void setup(){ setupMqtt(); Serial.println(); - Serial.println(F("BLLED Controller started")); + Serial.print(F("** BLLED Controller started ")); + Serial.print(F("using firmware version: ")); + Serial.print(globalVariables.FWVersion); + Serial.println(F(" **")); Serial.println(); - tweenToColor(0,0,0,0,0,3000); //Fade to Black before starting globalVariables.started = true; + } void loop(){ @@ -72,13 +95,26 @@ void loop(){ if(printerConfig.maintMode){ //Doesn't require monitoring of Wifi or MQTT if LEDs only need to be ON webserverloop(); - if(printerConfig.updateMaintenance) updateleds(); - printerVariables.inactivityStartms = millis(); // Don't turn light off (due to inactivity) if in Maintenance Mode + if(printerConfig.maintMode_update) updateleds(); + if((millis() - lastUpdatems) > 30000) { + Serial.print(F("[")); + Serial.print(millis()); + Serial.print(F("]")); + Serial.println(F(" Maintenance Mode (no MQTT updates) - next update in 30 seconds")); + lastUpdatems = millis(); + } } - else if (printerVariables.testcolorEnabled){ + else if (printerConfig.testcolorEnabled){ //Doesn't require monitoring of Wifi or MQTT if LEDs set to a custom color webserverloop(); - if(printerConfig.updateTestLEDS) ledsloop(); + if(printerConfig.testcolor_update) updateleds(); + if((millis() - lastUpdatems) > 30000) { + Serial.print(F("[")); + Serial.print(millis()); + Serial.print(F("]")); + Serial.println(F(" Test Color (no MQTT updates) - next update in 30 seconds")); + lastUpdatems = millis(); + } } else if (globalVariables.started){ mqttloop(); @@ -86,7 +122,9 @@ void loop(){ ledsloop(); if (WiFi.status() != WL_CONNECTED){ - Serial.println(F("Reconnecting to WiFi...")); + if (WiFi.status() == WL_DISCONNECTED) Serial.print(F("Wifi connection Disconnected. ")); + + Serial.println(F("Attempting to reconnect to WiFi...")); WiFi.disconnect(); delay(10); WiFi.reconnect(); @@ -100,4 +138,4 @@ void loop(){ printerConfig.rescanWiFiNetwork = false; updateleds(); } -} +} \ No newline at end of file diff --git a/src/mqttmanager.h b/src/mqttmanager.h index ad2f4bf..7b5b610 100644 --- a/src/mqttmanager.h +++ b/src/mqttmanager.h @@ -22,6 +22,7 @@ String clientId = "BLLED-"; AutoGrowBufferStream stream; unsigned long mqttattempt = (millis()-3000); +unsigned long lastMQTTupdate = millis(); //With a Default BLLED //Expected information when viewing MQTT status messages @@ -72,7 +73,6 @@ void connectMqtt(){ void ParseCallback(char *topic, byte *payload, unsigned int length){ JsonDocument messageobject; - JsonDocument filter; //Rather than showing the entire message to Serial - grabbing only the pertinent bits for BLLED. //Device Status @@ -82,36 +82,16 @@ void ParseCallback(char *topic, byte *payload, unsigned int length){ filter["print"]["print_gcode_action"] = true; filter["print"]["print_real_action"] = true; filter["print"]["hms"] = true; - filter["print"]["lights_report"] = true; filter["print"]["home_flag"] = true; + filter["print"]["lights_report"] = true; filter["print"]["stg_cur"] = true; filter["print"]["print_error"] = true; filter["print"]["wifi_signal"] = true; - - //Adding extra filters that looking interesting - //Could be useful for additional functionality that might be developed at a later date - //Color blend, the closer to 100% - I dunno - - //Print Job Status - //filter["print"]["subtask_name"] = true; //Print Name - //filter["print"]["layer_num"] = true; - //filter["print"]["total_layer_num"] = true; - //filter["print"]["mc_percent"] = true; - //filter["print"]["mc_print_error_code"] = true; - //filter["print"]["mc_print_stage"] = true; - //filter["print"]["mc_print_sub_stage"] = true; - //filter["print"]["mc_remaining_time"] = true; - - //Temperatures - //filter["print"]["bed_target_temper"] = true; - //filter["print"]["bed_temper"] = true; - //filter["print"]["nozzle_target_temper"] = true; - //filter["print"]["nozzle_temper"] = true; - //filter["print"]["chamber_temper"] = true; + filter["system"]["command"] = true; + filter["system"]["led_mode"] = true; auto deserializeError = deserializeJson(messageobject, payload, length, DeserializationOption::Filter(filter)); if (!deserializeError){ - if (printerConfig.debuging){ Serial.print(F("Mqtt message received, ")); Serial.print(F("FreeHeap: ")); @@ -121,30 +101,62 @@ void ParseCallback(char *topic, byte *payload, unsigned int length){ bool Changed = false; if (messageobject["print"].containsKey("command")){ - if (messageobject["print"]["command"].as() == "gcode_line"){ - //gcode_line used a lot during print initialisations - Skip these + if (messageobject["print"]["command"] == "gcode_line" //gcode_line used a lot during print initialisations - Skip these + || messageobject["print"]["command"] == "project_prepare" //1 message per print + || messageobject["print"]["command"] == "project_file" //1 message per print + || messageobject["print"]["command"] == "clean_print_error" //During error (no info) + || messageobject["print"]["command"] == "resume" //After error or pause + || messageobject["print"]["command"] == "prepare"){ //1 message per print return; } } if(messageobject.size() == 0) { - //Null or Filtered essage that is not 'print' - Ignore + //Null or Filtered message that are not 'Print' or 'System' payload - Ignore these return; } //Output Filtered MQTT message if (printerConfig.mqttdebug){ - Serial.print(F("(Filtered) MQTT payload, ")); - Serial.print(messageobject.size()); - Serial.print(F(", ")); + Serial.print(F("(Filtered) MQTT payload, [")); + Serial.print(millis()); + Serial.print(F("], ")); serializeJson(messageobject, Serial); Serial.println(); } + //Check for Door Status + if (messageobject["print"].containsKey("home_flag")){ + //https://github.com/greghesp/ha-bambulab/blob/main/custom_components/bambu_lab/pybambu/const.py#L324 + + bool doorState = false; + long homeFlag = 0; + homeFlag = messageobject["print"]["home_flag"]; + doorState = homeFlag >> 23; //shift left 23 to the Door bit + doorState = doorState & 1; // remove any bits above Door bit + + if (printerVariables.doorOpen != doorState){ + printerVariables.doorOpen = doorState; + + if (printerConfig.debugingchange)Serial.print(F("MQTT Door ")); + if (printerVariables.doorOpen){ + printerVariables.lastdoorOpenms = millis(); + if (printerConfig.debugingchange) Serial.println(F("Opened")); + } + else{ + if ((millis() - printerVariables.lastdoorClosems) < 6000){ + printerVariables.doorSwitchTriggered = true; + } + printerVariables.lastdoorClosems = millis(); + if (printerConfig.debugingchange) Serial.println(F("Closed")); + } + Changed = true; + } + } + //Check BBLP Stage if (messageobject["print"].containsKey("stg_cur")){ if (printerVariables.stage != messageobject["print"]["stg_cur"].as() ){ - printerVariables.inactivityStartms = millis(); //restart idle timer printerVariables.stage = messageobject["print"]["stg_cur"]; if (printerConfig.debugingchange || printerConfig.debuging){ @@ -153,28 +165,24 @@ void ParseCallback(char *topic, byte *payload, unsigned int length){ } Changed = true; } - }else{ - if (printerConfig.debuging){ - Serial.println(F("MQTT stg_cur not in message")); - } } //Check BBLP GCode State - if (messageobject["print"].containsKey("gcode_state")){ + if (messageobject["print"].containsKey("gcode_state") && ((millis() - lastMQTTupdate) > 2000)){ String mqttgcodeState = messageobject["print"]["gcode_state"].as(); if(mqttgcodeState =="RUNNING" || mqttgcodeState =="PAUSE"){ //Never turn off light (due to idle timer) while in this state - printerVariables.inactivityStartms = millis(); + printerConfig.inactivityStartms = millis(); } // Onchange of gcodeState... if(printerVariables.gcodeState != mqttgcodeState){ - printerVariables.inactivityStartms = millis(); //restart idle timer - if(mqttgcodeState =="FINISH"){ printerVariables.finished = true; - if(printerConfig.finishindication == true) printerVariables.waitingForDoor = true; + printerVariables.waitingForDoor = true; + printerConfig.finishStartms = millis(); + printerConfig.finish_check = true; } printerVariables.gcodeState = mqttgcodeState; @@ -186,93 +194,119 @@ void ParseCallback(char *topic, byte *payload, unsigned int length){ } } + //Pause Command - quicker, but Only for user generated pause - error & code pauses don't trigger this. + if (messageobject["print"].containsKey("command")){ + if (messageobject["print"]["command"] == "pause"){ + lastMQTTupdate = millis(); + Serial.println(F("MQTT update - manual PAUSE")); + printerVariables.gcodeState = "PAUSE"; + Changed = true; + } + } - if (messageobject["print"].containsKey("lights_report")) { + //Added a delay so the slower MQTT status message doesn't reverse the "system" commands + if (messageobject["print"].containsKey("lights_report") && ((millis() - lastMQTTupdate) > 2000)) { JsonArray lightsReport = messageobject["print"]["lights_report"]; - for (JsonObject light : lightsReport) { if (light["node"] == "chamber_light") { + if(printerVariables.printerledstate != (light["mode"] == "on")){ - printerVariables.printerledstate = light["mode"] == "on"; + printerVariables.printerledstate = (light["mode"] == "on"); + printerConfig.replicate_update = true; if (printerConfig.debugingchange || printerConfig.debuging){ Serial.print(F("MQTT chamber_light now: ")); Serial.println(printerVariables.printerledstate); } + if(printerVariables.waitingForDoor && printerConfig.finish_check){ + printerVariables.finished = true; + } Changed = true; } } } - }else{ - if (printerConfig.debuging){ - Serial.println(F("MQTT lights_report not in message")); + } + //System Commands are sent quicker than the push_status + //Message only sent onChange + if (messageobject["system"].containsKey("command")) { + if (messageobject["system"]["command"] == "ledctrl"){ + //Ignore Printer sending attempts to turn light on when already on. + if(printerVariables.printerledstate != (messageobject["system"]["led_mode"] == "on")){ + printerVariables.printerledstate = (messageobject["system"]["led_mode"] == "on"); + printerConfig.replicate_update = true; + lastMQTTupdate = millis(); + if (printerConfig.debugingchange || printerConfig.debuging){ + Serial.print(F("MQTT led_mode now: ")); + Serial.println(printerVariables.printerledstate); + } + if(printerVariables.waitingForDoor && printerConfig.finish_check){ + printerVariables.finished = true; + } + + Changed = true; + } } } + //Bambu Health Management System (HMS) if (messageobject["print"].containsKey("hms")){ - String oldHMS = ""; - oldHMS = printerVariables.parsedHMS; + String oldHMSlevel = ""; + oldHMSlevel = printerVariables.parsedHMSlevel; printerVariables.hmsstate = false; - printerVariables.parsedHMS = ""; + printerVariables.parsedHMSlevel = ""; for (const auto& hms : messageobject["print"]["hms"].as()) { if (ParseHMSSeverity(hms["code"]) != ""){ printerVariables.hmsstate = true; - printerVariables.parsedHMS = ParseHMSSeverity(hms["code"]); - int attrib = hms["attr"]; - printerVariables.parsedHMSattrib = (attrib>>16); + printerVariables.parsedHMSlevel = ParseHMSSeverity(hms["code"]); + printerVariables.parsedHMScode = ((uint64_t)hms["attr"] << 32) + (uint64_t)hms["code"]; } } - if(oldHMS != printerVariables.parsedHMS){ - printerVariables.inspectingFirstLayer = false; - if(printerVariables.parsedHMS == "Common" && printerVariables.parsedHMSattrib == 3072) - { - printerVariables.inspectingFirstLayer = true; - } - + if(oldHMSlevel != printerVariables.parsedHMSlevel){ + if(printerVariables.parsedHMScode == 0x0C0003000003000B) printerVariables.overridestage = 10; + if(printerVariables.parsedHMScode == 0x0300120000020001) printerVariables.overridestage = 17; + if(printerVariables.parsedHMScode == 0x0700200000030001) printerVariables.overridestage = 6; + if(printerVariables.parsedHMScode == 0x0300020000010001) printerVariables.overridestage = 20; + if(printerVariables.parsedHMScode == 0x0300010000010007) printerVariables.overridestage = 21; + if (printerConfig.debuging || printerConfig.debugingchange){ - Serial.print(F("MQTT update - parsedHMS now: ")); - if (printerVariables.parsedHMS.length() == 0) Serial.print(F("NULL")); - Serial.println(printerVariables.parsedHMS); - } - Changed = true; - } - } - - if (messageobject["print"].containsKey("home_flag")){ - //https://github.com/greghesp/ha-bambulab/blob/main/custom_components/bambu_lab/pybambu/const.py#L324 - - bool doorState = false; - long homeFlag = 0; - homeFlag = messageobject["print"]["home_flag"]; - doorState = homeFlag >> 23; //shift left 23 to the Door bit - doorState = doorState & 1; // remove any bits above Door bit - - if (printerVariables.doorOpen != doorState){ - printerVariables.inactivityStartms = millis(); //restart idle timer - - printerVariables.doorOpen = doorState; - printerVariables.inactivityLightsOff = false; - if (printerConfig.debugingchange)Serial.print(F("MQTT Door ")); - if (printerVariables.doorOpen){ - printerVariables.lastdoorOpenms = millis(); - if (printerConfig.debugingchange) Serial.println(F("Opened")); - } - else{ - if ((millis() - printerVariables.lastdoorClosems) < 6000){ - printerVariables.doorSwitchenabled = true; + Serial.print(F("MQTT update - parsedHMSlevel now: ")); + if (printerVariables.parsedHMSlevel.length() > 0) { + Serial.print(printerVariables.parsedHMSlevel); + Serial.print(F(" Error Code: ")); + //Serial.println(F("https://wiki.bambulab.com/en/x1/troubleshooting/how-to-enter-the-specific-code-page")); + int chunk1 = (printerVariables.parsedHMScode >> 48); + int chunk2 = (printerVariables.parsedHMScode >> 32) & 0xFFFF; + int chunk3 = (printerVariables.parsedHMScode >> 16) & 0xFFFF; + int chunk4 = printerVariables.parsedHMScode & 0xFFFF; + char strHMScode[20]; + sprintf(strHMScode, "%04X_%04X_%04X_%04X", chunk1, chunk2, chunk3, chunk4); + Serial.print(strHMScode); + if(printerVariables.overridestage != printerVariables.stage){ + Serial.println(F(" **")); + }else{ + Serial.println(F("")); + } + } else { + Serial.println(F("NULL")); + printerVariables.overridestage = 999; } - printerVariables.lastdoorClosems = millis(); - if (printerConfig.debugingchange) Serial.println(F("Closed")); } Changed = true; } } if (Changed == true){ + printerConfig.inactivityStartms = millis(); //restart idle timer + printerConfig.isIdleOFFActive = false; if (printerConfig.debuging){ Serial.println(F("Change from mqtt")); } + printerConfig.maintMode_update = true; + printerConfig.discoMode_update = true; + printerConfig.replicate_update = true; + printerConfig.testcolor_update = true; + updateleds(); } }else{ @@ -289,7 +323,7 @@ void mqttCallback(char *topic, byte *payload, unsigned int length){ void setupMqtt(){ clientId += String(random(0xffff), HEX); - Serial.print(F("Setting up MQTT with ip: ")); + Serial.print(F("Setting up MQTT with Bambu Lab Printer IP address: ")); Serial.println(printerConfig.printerIP); device_topic = String("device/") + printerConfig.serialNumber; @@ -331,4 +365,4 @@ void mqttloop(){ delay(10); } -#endif +#endif \ No newline at end of file diff --git a/src/types.h b/src/types.h index 408e16a..df06948 100644 --- a/src/types.h +++ b/src/types.h @@ -6,34 +6,41 @@ extern "C" { #endif + typedef struct COLORStruct { + short r; + short g; + short b; + short ww; + short cw; + char RGBhex[8]; + } COLOR; + + typedef struct PrinterVaraiblesStruct{ - String parsedHMS = ""; - int parsedHMSattrib = 0; + String parsedHMSlevel = ""; + uint64_t parsedHMScode = 0; //8 bytes per code stored String gcodeState = "FINISH"; //Initialised to Finish so the logic doesn't //assume a Print has just finished and needs //to wait for a door interaction to continue int stage = 0; - bool testcolorEnabled = false; + int overridestage = 999; bool printerledstate = true; bool hmsstate = false; bool online = false; bool finished = false; bool initalisedLEDs = false; - bool inspectingFirstLayer = false; //Time since unsigned long disconnectMQTTms = 0; - //InactivityLightsOff Timer and status - bool inactivityLightsOff = false; // Are the lights out due to inactivity Timeout? - unsigned long inactivityStartms = 0; // Time the inactivity countdown is measured from - + + //PrinterType + bool isP1Printer = false; //Is this a P1 Printer without lidar or door switch //Door Monitoring + bool useDoorSwtich = true; //DoorSwitch to be used for Actions? bool doorOpen = false; // Current State of Door - bool doorSwitchenabled = false; // Has door been closed twice within 6 seconds? + bool doorSwitchTriggered = false; // Has door been closed twice within 6 seconds? bool waitingForDoor = false; // Are we waiting for the door to be actuated? unsigned long lastdoorClosems = 0; // Last time door was opened unsigned long lastdoorOpenms = 0; // Last time door was closed - - } PrinterVariables; PrinterVariables printerVariables; @@ -41,7 +48,7 @@ extern "C" typedef struct GlobalVariablesStruct{ char SSID[32]; char APPW[63]; - String FWVersion = "Stable 19.3.24"; + String FWVersion = "Experimental 26.3.24"; String Host = "BLLED"; bool started = false; } GlobalVariables; @@ -57,38 +64,52 @@ extern "C" char BSSID[18]; //Nominated AP to connect to (Useful if multiple accesspoints with same name) int brightness = 100; //Brightness of LEDS bool rescanWiFiNetwork = false; //Scans available WiFi networks for strongest signal - // BLLED Settings + // LED Behaviour (Choose One) + bool maintMode = false; //White lights on, even if printer is unpowered + bool maintMode_update = true; + bool discoMode = false; //Cycles through RGB colors slowly for 'pretty' timelapse movie + bool discoMode_update = true; bool replicatestate = true; //LED will be on if the BBPL Light is on - bool errordetection = true; //Utilises Error Colors when BBLP give an error - bool finishindication = true; //Utilises Finish Color when print ends successfully - bool lidarLightsOff = true; //For X1C owners - option to turn off if you have a P1P with no Lidar. + bool replicate_update = true; //LED will be on if the BBPL Light is on + COLOR runningColor; //Running Color (Default if no issues) + bool testcolorEnabled = false; + bool testcolor_update= true; //When updateleds() is run, should the TEST LEDS be set? + COLOR testColor; //Test Color + bool debugwifi = false; //Changes LED to a color range that represents WiFi signal Strength + // Options + bool finishindication = true; //Enable / Disable + COLOR finishColor; //Set Finish Color + bool finishExit = true; //True = use Door / False = use Timer + bool finish_check = false; //When updateleds() is run, should the TEST LEDS be set? + unsigned long finishStartms = 0; // Time the finish countdown is measured from + int finishTimeOut = 600000; //300000 = 5 mins + //Inactivity Timout bool inactivityEnabled = true; - int inactivityTimeOut = 1800000;// 1800000 = 30 mins - bool discoMode = false; //Cycles through RGB colors slowly for 'pretty' timelapse movie - bool maintMode = false; //White lights on, even if printer is unpowered - bool updateMaintenance = false; //When updateleds() is run, should the Maintenance LEDS be set? + bool isIdleOFFActive = false; // Are the lights out due to inactivity Timeout? + unsigned long inactivityStartms = 0; // Time the inactivity countdown is measured from + int inactivityTimeOut = 3600000; // 1800000 = 30mins / 600000 = 10mins / 60000 = 1mins // Debugging bool debuging = false; //Debugging for all interactions through functions bool debugingchange = true; //Default debugging level - to shows onChange bool mqttdebug = false; //Writes each packet from BBLP to the serial log - bool debugwifi = false; //Changes LED to a color range that represents WiFi signal Strength - // Test - Fixed LED Colors - char testRGB[8]; //Test Color (RGB only) - int testwarmwhite = 100; //Testing just the Warm White LED line - int testcoldwhite = 100; //Testing just the Cold White LED line - bool updateTestLEDS = false; //When updateleds() is run, should the TEST LEDS be set? + //Custom Colors for events using lidar + COLOR stage14Color; + COLOR stage1Color; + COLOR stage8Color; + COLOR stage9Color; + COLOR stage10Color; // Customise LED Colors - char wifiRGB[8]; //These need to be 8 char: '#' + 123456 + end char '/0' - char finishRGB[8]; - char pauseRGB[8]; - char firstlayerRGB[8]; - char nozzleclogRGB[8]; - char hmsSeriousRGB[8]; - char hmsFatalRGB[8]; - char filamentRunoutRGB[8]; - char frontCoverRGB[8]; - char nozzleTempRGB[8]; - char bedTempRGB[8]; + bool errordetection = true; //Utilises Error Colors when BBLP give an error + COLOR wifiRGB; + COLOR pauseRGB; + COLOR firstlayerRGB; + COLOR nozzleclogRGB; + COLOR hmsSeriousRGB; + COLOR hmsFatalRGB; + COLOR filamentRunoutRGB; + COLOR frontCoverRGB; + COLOR nozzleTempRGB; + COLOR bedTempRGB; //char webpagePassword[8]; } PrinterConfig; @@ -99,4 +120,4 @@ extern "C" } /*extern "C"*/ #endif -#endif +#endif \ No newline at end of file diff --git a/src/web-server.h b/src/web-server.h index f249646..51c7b62 100644 --- a/src/web-server.h +++ b/src/web-server.h @@ -38,56 +38,72 @@ void submitSetup(){ } strcpy(printerConfig.printerIP,webServer.arg("ip").c_str()); strcpy(printerConfig.accessCode,webServer.arg("code").c_str()); - strcpy(printerConfig.serialNumber,webServer.arg("id").c_str()); + //Force Uppercase + char temperserial[20]; + strcpy(temperserial,webServer.arg("id").c_str()); + for (int x=0; x 10 && wifimode == 0){ + WiFi.disconnect(); + WiFi.begin(globalVariables.SSID, globalVariables.APPW); + connectionAttempts = 1; + wifimode = 1; + Serial.println(F("Attempting to connect without specific BSSI")); + } + if(connectionAttempts > 10 && wifimode == 1){ + WiFi.disconnect(); + WiFi.begin(globalVariables.SSID); + connectionAttempts = 1; + wifimode = 2; + if(strlen(printerConfig.BSSID) == 0) wifimode = 0; + + Serial.println(F("Attempting to connect to open network (no password)")); + } + if(connectionAttempts > 10 && wifimode == 2){ + WiFi.disconnect(); + WiFi.begin(globalVariables.SSID, globalVariables.APPW, 0, bssid); + connectionAttempts = 1; + wifimode = 0; + Serial.println(F("Attempting to connect to wifi using BSSI")); + } + + Serial.print(F("Connecting to WIFI.. Status check #")); + Serial.print(connectionAttempts); + Serial.print(F(" / 10 SSID: ")); + Serial.print(globalVariables.SSID); + if(strlen(printerConfig.BSSID) > 0){ + Serial.print(F(" BSSID: ")); + Serial.print(printerConfig.BSSID); + } + Serial.println(); if(status != WiFi.status()){ status = WiFi.status(); switch (status) { + case WL_CONNECTED: + Serial.print(F("Wifi Status: ")); + Serial.println(wl_status_to_string(status)); + break; case WL_IDLE_STATUS: - Serial.print(F("Connecting to WIFI.. Attempt #")); - Serial.println(connectionAttempts); - Serial.print(F(" SSID: ")); - Serial.print(globalVariables.SSID); - Serial.print(F(" APPW: ")); - Serial.print(globalVariables.APPW); - if(strlen(printerConfig.BSSID) > 0){ - Serial.print(F(" BSSID: ")); - Serial.print(globalVariables.SSID); - } - Serial.println(); + Serial.print(F("Wifi Status: ")); + Serial.println(wl_status_to_string(status)); break; case WL_NO_SSID_AVAIL: - Serial.print(F("Bad WiFi credentials")); + Serial.print(F("Wifi Status: ")); + Serial.println(wl_status_to_string(status)); + Serial.println(F("Bad WiFi credentials")); return false; case WL_CONNECT_FAILED: - Serial.print(F("Connect Failed.")); + Serial.print(F("Wifi Status: ")); + Serial.println(wl_status_to_string(status)); break; case WL_DISCONNECTED: + Serial.print(F("Wifi Status: ")); + Serial.println(wl_status_to_string(status)); Serial.print(F("Disconnected. (Check low RSSI)")); + return false; default: + Serial.print(F("Uncaught Status - Wifi Status: ")); + Serial.println(wl_status_to_string(status)); break; } } - delay(1000); // Giving time to connect + delay(2000); // Giving time to connect connectionAttempts++; } @@ -95,6 +145,9 @@ bool connectToWifi(){ #ifdef ESP32 WiFi.setTxPower(WIFI_POWER_19_5dBm); // https://github.com/G6EJD/ESP32-8266-Adjust-WiFi-RF-Power-Output/blob/main/README.md #endif + Serial.print(F("IP_ADDRESS:")); // !!! Line required in this format for WifiSetup.html page to show IP Address correct. + Serial.print(WiFi.localIP()); // !!! Line required in this format for WifiSetup.html page to show IP Address correct. + Serial.println(F("\n ")); // !!! Line required in this format for WifiSetup.html page to show IP Address correct. Serial.print(F("Connected To Wifi Access Point: ")); Serial.println(globalVariables.SSID); @@ -102,9 +155,12 @@ bool connectToWifi(){ Serial.println(WiFi.BSSIDstr()); Serial.print(F("RSSI (Signal Strength): ")); Serial.println(WiFi.RSSI()); - Serial.print(F("IP_ADDRESS:")); // Line required in this format for WifiSetup.html page to show IP Address correct. - Serial.println(WiFi.localIP()); // Line required in this format for WifiSetup.html page to show IP Address correct. - + Serial.print(F("BLLED Controller IP Address: ")); + Serial.println(WiFi.localIP()); + Serial.println(); + Serial.print(F("Use web browser to access 'http://")); // Instruction for user to go to Config page + Serial.print(WiFi.localIP()); // Instruction for user to go to Config page + Serial.println(F("/' to view the setup page")); // Instruction for user to go to Config page Serial.println(); return true; }; diff --git a/src/www/setupPage.h b/src/www/setupPage.h index be29e0f..fc07a09 100644 --- a/src/www/setupPage.h +++ b/src/www/setupPage.h @@ -1,278 +1,390 @@ //https://mischianti.org/online-converter-file-to-cpp-gzip-byte-array-3/ -//File: setuppage.html.gz, Size: 4353 -#define setuppage_html_gz_len 4353 +//File: setuppage.html.gz, Size: 6158 +#define setuppage_html_gz_len 6158 const uint8_t setuppage_html_gz[] PROGMEM = { -0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xED, 0x5D, 0x7B, 0x73, 0xDB, 0x38, -0x92, 0xFF, 0xFF, 0xAA, 0xEE, 0x3B, 0x60, 0x34, 0x35, 0xA1, 0x5C, 0x8E, 0x1E, 0xB6, 0xE3, 0x24, -0xEB, 0x58, 0xAA, 0xF2, 0x4B, 0x19, 0x67, 0x9D, 0x89, 0xD7, 0x52, 0x66, 0xE6, 0x66, 0x6B, 0xEB, -0x0A, 0x22, 0x21, 0x09, 0x31, 0x49, 0x70, 0x00, 0xD2, 0xB2, 0x73, 0x9B, 0xEF, 0x7E, 0x0D, 0x80, -0xEF, 0x97, 0x28, 0xD9, 0xD9, 0x8D, 0x2E, 0x27, 0x27, 0x31, 0x09, 0x36, 0xFB, 0xF1, 0xEB, 0x46, -0xE3, 0xC1, 0xA6, 0x72, 0xFC, 0xC3, 0xF9, 0x87, 0xB3, 0xC9, 0x7F, 0x5D, 0x5F, 0xA0, 0x85, 0xEF, -0xD8, 0xC3, 0xFF, 0xFC, 0x8F, 0xE3, 0xF0, 0xB7, 0x3C, 0x22, 0xD8, 0x82, 0x23, 0x04, 0x9F, 0x63, -0x9B, 0xBA, 0xB7, 0x88, 0x13, 0x7B, 0x60, 0x08, 0xFF, 0xC1, 0x26, 0x62, 0x41, 0x88, 0x6F, 0xA0, -0x05, 0x27, 0xB3, 0x81, 0xB1, 0xF0, 0x7D, 0x4F, 0x1C, 0xF5, 0x7A, 0xA6, 0xE5, 0x7E, 0x12, 0x5D, -0xD3, 0x66, 0x81, 0x35, 0xB3, 0x31, 0x27, 0x5D, 0x93, 0x39, 0x3D, 0xFC, 0x09, 0xDF, 0xF7, 0x6C, -0x3A, 0x15, 0xBD, 0x19, 0x73, 0xFD, 0x0E, 0x5E, 0x12, 0xC1, 0x1C, 0xD2, 0x3B, 0xEC, 0xEE, 0x1D, -0x76, 0x0F, 0x7A, 0xA6, 0x10, 0x3D, 0x6C, 0xDB, 0x5D, 0x87, 0xBA, 0x5D, 0x38, 0x36, 0x10, 0x75, -0x7D, 0x32, 0xE7, 0xD4, 0x7F, 0x00, 0x41, 0x0B, 0x7C, 0xB8, 0xB7, 0xDF, 0xA1, 0xF7, 0xF6, 0x87, -0x3F, 0xDE, 0xDD, 0xDB, 0xAF, 0xF1, 0xA7, 0xBD, 0xB3, 0xCF, 0x7D, 0xE7, 0xAF, 0x9F, 0x1E, 0x46, -0x93, 0x77, 0x7F, 0xBB, 0xEF, 0x89, 0xDD, 0x8F, 0x2F, 0x97, 0xAC, 0xCF, 0x5E, 0x5E, 0xEF, 0x9E, -0xFD, 0x71, 0x7D, 0xF3, 0xEE, 0xF7, 0xDD, 0xF9, 0x67, 0x72, 0xF0, 0x6E, 0xF1, 0x7A, 0xC4, 0x59, -0xCF, 0x99, 0x3C, 0x5C, 0xF1, 0x43, 0xDE, 0xFB, 0xF5, 0x7E, 0x37, 0xF8, 0xF5, 0xD5, 0xBB, 0xD7, -0x37, 0x77, 0x37, 0xB3, 0x3F, 0xBC, 0xC3, 0xDD, 0xDF, 0xFF, 0x32, 0xA3, 0x77, 0x6F, 0x5F, 0x9D, -0x0C, 0x06, 0x06, 0x32, 0x39, 0x13, 0x82, 0x71, 0x3A, 0xA7, 0xEE, 0xC0, 0xC0, 0x2E, 0x73, 0x1F, -0x1C, 0x16, 0x80, 0x0E, 0x60, 0x14, 0xE1, 0x9C, 0x70, 0x8F, 0xD9, 0xD4, 0x04, 0x45, 0x5C, 0xD6, -0x89, 0x9A, 0x0C, 0xD4, 0x8B, 0x10, 0x51, 0x38, 0x84, 0x27, 0xF2, 0x33, 0x65, 0xD6, 0x03, 0xFA, -0x9F, 0xE4, 0x5C, 0xB5, 0x61, 0xF3, 0x76, 0xCE, 0x59, 0xE0, 0x5A, 0x1D, 0x93, 0xD9, 0x8C, 0x1F, -0xA1, 0x1F, 0x67, 0x7B, 0xF2, 0xE7, 0x4D, 0x96, 0x4E, 0x41, 0x33, 0xC3, 0x0E, 0xB5, 0x1F, 0x8E, -0xD0, 0x09, 0xA7, 0xD8, 0x7E, 0x8E, 0x04, 0x76, 0x45, 0x47, 0x10, 0x4E, 0x67, 0x29, 0xE2, 0x2F, -0xC9, 0x21, 0xA0, 0xEB, 0xFA, 0x98, 0xBA, 0x84, 0xE7, 0xA5, 0x5A, 0x54, 0x78, 0x36, 0x06, 0x4E, -0x33, 0x9B, 0xDC, 0xE7, 0x25, 0x41, 0x53, 0xC7, 0xA2, 0x9C, 0x98, 0x3E, 0x65, 0xEE, 0x11, 0x02, -0xB5, 0x02, 0xC7, 0xCD, 0x11, 0x7D, 0x0A, 0x84, 0x4F, 0x67, 0x0F, 0x1D, 0x29, 0x81, 0xB8, 0x3E, -0x50, 0xC1, 0xBF, 0x84, 0xE7, 0xA8, 0xB0, 0x4D, 0xE7, 0x6E, 0x87, 0xFA, 0xC4, 0x11, 0x15, 0x14, -0x0B, 0x42, 0xE7, 0x0B, 0x79, 0x3B, 0xB6, 0xCD, 0xF6, 0x5E, 0xBF, 0xFF, 0x13, 0xEA, 0x20, 0xF8, -0xE5, 0xDD, 0xEF, 0x54, 0x98, 0x64, 0xB3, 0x39, 0xEB, 0x6C, 0x64, 0x57, 0xBD, 0x32, 0x79, 0x19, -0x79, 0xCE, 0x4B, 0x6A, 0xF9, 0x8B, 0x23, 0xAD, 0x5B, 0x85, 0x0D, 0x65, 0xD7, 0x1C, 0xCC, 0x21, -0x76, 0x3A, 0x5C, 0x53, 0xEC, 0x67, 0x09, 0x0A, 0x76, 0xF9, 0xE4, 0xDE, 0xCF, 0x0B, 0x56, 0x8E, -0x17, 0xF4, 0x33, 0x39, 0x42, 0x07, 0x2F, 0x0B, 0xFC, 0xD5, 0xD5, 0x65, 0xA8, 0xC0, 0x94, 0xD9, -0x56, 0x05, 0xFB, 0x19, 0xE3, 0x4E, 0x35, 0x6C, 0xC5, 0x20, 0x5C, 0x2E, 0x00, 0xA8, 0x9C, 0x2C, -0x0F, 0x5B, 0x16, 0x75, 0xE7, 0x05, 0x33, 0x14, 0x07, 0xC6, 0x2D, 0xC2, 0x3B, 0x1C, 0x5B, 0x34, -0x10, 0x12, 0x8A, 0x12, 0x8A, 0xFB, 0x0E, 0xF4, 0x57, 0x8B, 0x2D, 0x8F, 0x50, 0x1F, 0x7E, 0x24, -0x09, 0xE2, 0xF3, 0x29, 0x6E, 0xF7, 0x9F, 0xA3, 0xF0, 0x4F, 0xF7, 0x60, 0xE7, 0x4D, 0x29, 0xEC, -0xAF, 0xFB, 0x3F, 0x95, 0x03, 0xEB, 0x33, 0xAF, 0x0E, 0x56, 0x1B, 0x4F, 0x89, 0x5D, 0x19, 0x24, -0x53, 0x9B, 0x99, 0xB7, 0xE5, 0x02, 0x65, 0x28, 0x96, 0x4B, 0x9C, 0x32, 0xDF, 0x67, 0xCE, 0x11, -0x3A, 0x5C, 0xCB, 0x17, 0xF1, 0x75, 0xED, 0xC9, 0xBD, 0xA2, 0x27, 0xA3, 0xDE, 0x7F, 0x70, 0x70, -0x50, 0x6E, 0x0B, 0x75, 0xBD, 0xC0, 0xFF, 0xBB, 0xFF, 0xE0, 0x91, 0x81, 0x21, 0x03, 0xC5, 0xF8, -0x47, 0x75, 0x8C, 0xE6, 0x75, 0x8F, 0x5D, 0x57, 0xEA, 0x98, 0x8C, 0xEB, 0x8A, 0x76, 0x69, 0x02, -0xB8, 0x17, 0x1C, 0x26, 0x20, 0xE1, 0x59, 0xE8, 0x47, 0xD3, 0x34, 0xEB, 0xD1, 0x29, 0x09, 0x91, -0x6A, 0xF3, 0x2B, 0x8C, 0x14, 0xC1, 0xD4, 0xA1, 0x25, 0x66, 0x96, 0xA4, 0xCC, 0x17, 0x67, 0x27, -0xA3, 0xC3, 0x7E, 0x39, 0xA2, 0xB5, 0xA1, 0xFC, 0x18, 0x3C, 0x60, 0x38, 0xC8, 0xF3, 0x35, 0x03, -0x2E, 0xA4, 0x4C, 0x8F, 0xD1, 0x92, 0x64, 0x57, 0x13, 0xB3, 0xF5, 0x00, 0xC5, 0x57, 0x57, 0xF7, -0xF4, 0x69, 0x00, 0x0E, 0x70, 0xFF, 0x1F, 0xB2, 0x35, 0x20, 0xEB, 0xFA, 0x6C, 0x3E, 0xB7, 0xC9, -0xD7, 0x18, 0x55, 0x52, 0x26, 0x44, 0x3D, 0x63, 0xAF, 0x7A, 0x0C, 0x08, 0xF5, 0x28, 0x4D, 0x5A, -0xD9, 0x81, 0x64, 0x35, 0x13, 0xB1, 0xA4, 0xBE, 0xB9, 0xC8, 0x73, 0xF1, 0x98, 0xA0, 0x7A, 0x54, -0x87, 0x89, 0x1A, 0xF6, 0xE9, 0x5D, 0xDE, 0x1B, 0xB1, 0xA9, 0xD4, 0x85, 0xF9, 0x1C, 0xE9, 0xD4, -0xA4, 0xC8, 0x97, 0xD5, 0x23, 0xE1, 0xC1, 0x8B, 0x86, 0xEA, 0xA9, 0xEE, 0x9E, 0x57, 0x92, 0x79, -0xD8, 0x84, 0xE9, 0x1D, 0x0C, 0x13, 0xE5, 0x82, 0xF3, 0xCD, 0x91, 0xD4, 0x7E, 0x85, 0x48, 0x01, -0x29, 0xAB, 0xE8, 0xD4, 0x04, 0x0A, 0x3C, 0x85, 0xAC, 0x16, 0x14, 0x02, 0xBE, 0x3E, 0x30, 0x55, -0x44, 0xE6, 0x35, 0xB1, 0xC9, 0xCC, 0x2F, 0xB6, 0xF2, 0xA2, 0x7A, 0xF2, 0x13, 0x05, 0x44, 0xA1, -0xBD, 0xD8, 0x57, 0x8B, 0xE9, 0x16, 0xC2, 0x7A, 0x7A, 0x4B, 0xFD, 0x8E, 0xCF, 0x61, 0x0E, 0x18, -0xDA, 0xD1, 0x7D, 0x21, 0xF2, 0x4A, 0xD6, 0x5E, 0xCD, 0xF5, 0xDA, 0x1A, 0xA7, 0x69, 0x04, 0x8F, -0xA6, 0x04, 0xA6, 0x11, 0x64, 0x7D, 0x20, 0xA3, 0x39, 0xA2, 0x61, 0x54, 0x78, 0x6E, 0xBF, 0xD8, -0x77, 0x43, 0x5F, 0x97, 0x5C, 0xD1, 0x20, 0xBF, 0x28, 0xC9, 0x31, 0x1A, 0xCF, 0x92, 0x2B, 0x8D, -0xA6, 0x37, 0x5F, 0x01, 0xD2, 0xC3, 0xCC, 0x40, 0x9C, 0x1F, 0xE6, 0x8E, 0xCC, 0x05, 0x31, 0x6F, -0x89, 0x85, 0x76, 0xAB, 0x62, 0xB4, 0x24, 0x14, 0xF6, 0xF7, 0xFE, 0xF2, 0x72, 0x54, 0x37, 0x43, -0x38, 0x9A, 0x31, 0x33, 0x10, 0x35, 0x3C, 0xF3, 0xF3, 0x30, 0x18, 0xD5, 0x1B, 0x70, 0x2D, 0xE8, -0x5A, 0x11, 0x0D, 0x19, 0x14, 0xE5, 0xAC, 0xF3, 0x48, 0x43, 0x06, 0xD9, 0x86, 0xFC, 0xDE, 0x96, -0xEE, 0xCC, 0x4F, 0xF1, 0x3A, 0x8E, 0x58, 0x83, 0xBA, 0x19, 0x65, 0xC5, 0x8C, 0x02, 0x6E, 0x98, -0x93, 0x75, 0xE6, 0x4D, 0xF5, 0xB3, 0x9A, 0x50, 0xCA, 0x71, 0x2F, 0xBD, 0xD0, 0x3B, 0x16, 0x26, -0xA7, 0x9E, 0x9F, 0x5A, 0xF6, 0xCD, 0x02, 0x57, 0x2D, 0xA5, 0x50, 0xE0, 0x59, 0xA0, 0xED, 0xA5, -0x65, 0x93, 0xF6, 0x4E, 0x5E, 0x87, 0x3B, 0xCC, 0xD1, 0x3D, 0x1A, 0x20, 0x0B, 0xBC, 0xE7, 0x40, -0x6F, 0xE9, 0xCE, 0x89, 0x7F, 0x61, 0x13, 0x79, 0x78, 0xFA, 0x70, 0x69, 0xB5, 0x5B, 0xD4, 0xC5, -0xC0, 0xE5, 0x0E, 0x12, 0xE3, 0x7B, 0xEA, 0x8A, 0x56, 0x1E, 0x17, 0x3A, 0x43, 0xED, 0xAA, 0x7B, -0x8D, 0xE4, 0xDE, 0x0B, 0x17, 0x4F, 0x6D, 0x62, 0x19, 0x3B, 0xDD, 0xD0, 0xA1, 0x05, 0x45, 0xE4, -0xE7, 0xBE, 0xAB, 0x2C, 0xEA, 0x86, 0xA3, 0x01, 0xA8, 0x65, 0xA8, 0x81, 0x20, 0xDF, 0x7F, 0xBF, -0x20, 0x62, 0x8B, 0x42, 0x08, 0x54, 0x70, 0x90, 0x63, 0x7F, 0x91, 0x41, 0xEA, 0x53, 0xEA, 0xBE, -0x18, 0x3C, 0xB1, 0x60, 0xCB, 0x09, 0x11, 0xFE, 0x07, 0x4F, 0x9E, 0x8A, 0x0D, 0x10, 0xBC, 0xBA, -0x38, 0x97, 0x0C, 0xC6, 0xC4, 0xF7, 0x61, 0x22, 0xB3, 0x26, 0x84, 0x9C, 0x78, 0xB0, 0xD4, 0x07, -0xF7, 0x5D, 0x11, 0x6B, 0xEC, 0xC3, 0xEF, 0xF5, 0x21, 0x2C, 0x03, 0x40, 0x7E, 0x2A, 0x65, 0x5A, -0x64, 0x1A, 0xCC, 0x97, 0x74, 0x46, 0x13, 0x59, 0xC0, 0x67, 0x86, 0x01, 0xF3, 0xC7, 0x38, 0xA2, -0xDC, 0x95, 0xAB, 0xD1, 0x3F, 0xB1, 0xEE, 0xB0, 0x6B, 0x12, 0x6B, 0x03, 0xE8, 0xA3, 0x5B, 0xCF, -0xE9, 0xDD, 0x7A, 0xB0, 0xE3, 0xF0, 0xC6, 0xC8, 0x69, 0xDF, 0x64, 0xE0, 0xD6, 0x7E, 0xEA, 0x71, -0xD5, 0x29, 0xE1, 0x8C, 0xB9, 0x33, 0x3A, 0xAF, 0xC0, 0x75, 0xC1, 0x41, 0x09, 0x97, 0x2C, 0xD1, -0xEF, 0xEF, 0xAF, 0x7E, 0xF6, 0x7D, 0xEF, 0x86, 0xFC, 0x19, 0x40, 0x18, 0xB7, 0xF3, 0x38, 0x02, -0x61, 0x97, 0xB9, 0x9C, 0x60, 0xEB, 0x41, 0xC8, 0x00, 0x35, 0x17, 0x32, 0xDB, 0xC9, 0x80, 0x09, -0x85, 0x15, 0xF9, 0xCB, 0x8F, 0x84, 0x5F, 0xDE, 0xAA, 0x6E, 0x54, 0x91, 0x8D, 0x06, 0x83, 0x01, -0x7A, 0x81, 0x9E, 0x3D, 0x53, 0x2C, 0x25, 0x2F, 0x18, 0x4F, 0x64, 0xDB, 0x7E, 0xBF, 0x5F, 0xCA, -0x22, 0x52, 0xD5, 0x54, 0x66, 0x9C, 0x63, 0x1F, 0x83, 0xD4, 0x77, 0xE3, 0x0F, 0xBF, 0x74, 0x3D, -0xCC, 0x05, 0x09, 0xD9, 0x0B, 0x0F, 0xBA, 0x2D, 0x99, 0xC0, 0xCA, 0x35, 0xAF, 0x79, 0xF4, 0xA9, -0xCE, 0x5F, 0x1E, 0xF8, 0xFD, 0x0E, 0xDB, 0x81, 0x34, 0x27, 0x91, 0xD2, 0xA5, 0x1E, 0xFA, 0xE7, -0x3F, 0x8B, 0xD3, 0x8A, 0x95, 0xFC, 0x4C, 0x66, 0x91, 0x72, 0x8E, 0xF2, 0xCA, 0x66, 0x3C, 0xA9, -0x55, 0xA1, 0xA3, 0xB5, 0x19, 0xBF, 0x9A, 0x84, 0x93, 0x15, 0x10, 0x13, 0x42, 0x5E, 0x97, 0xA2, -0xCA, 0xF2, 0xC3, 0x4A, 0x69, 0x84, 0x73, 0xC6, 0xCF, 0x89, 0xAF, 0x37, 0xFD, 0xAA, 0x44, 0x29, -0x2A, 0x2B, 0xA2, 0xDA, 0x58, 0xD8, 0x8C, 0xBA, 0x54, 0x2C, 0x2E, 0x5D, 0x4B, 0xAA, 0x5D, 0x23, -0x4E, 0xD3, 0xD1, 0x98, 0x6E, 0x63, 0x81, 0x2A, 0x91, 0x42, 0xFA, 0xA8, 0x12, 0x14, 0x5D, 0x7F, -0xB4, 0x00, 0xDD, 0xE7, 0x56, 0x89, 0x09, 0x7B, 0xE6, 0xA6, 0xC2, 0x9C, 0x3F, 0x7D, 0x5F, 0xB1, -0xAA, 0x92, 0x13, 0x13, 0x6C, 0x2C, 0x02, 0x66, 0x78, 0x98, 0x5F, 0xC9, 0xC9, 0xB9, 0xF8, 0x30, -0x9B, 0x55, 0xC9, 0xC9, 0x52, 0x6D, 0x2C, 0xAC, 0x66, 0x76, 0x92, 0xEB, 0x4A, 0x79, 0xC2, 0x27, -0x10, 0x29, 0x27, 0x53, 0x15, 0x1D, 0x37, 0x43, 0xA3, 0x3A, 0xF1, 0x41, 0x7F, 0xED, 0x6E, 0xEC, -0x60, 0x58, 0x3D, 0xBE, 0xD7, 0xF9, 0xA6, 0xDC, 0x59, 0x11, 0xC1, 0xE6, 0xC1, 0x47, 0x85, 0xC9, -0xEA, 0x44, 0xC4, 0x04, 0x1B, 0x8B, 0xF0, 0x61, 0xC0, 0xB9, 0x79, 0x7B, 0x5A, 0x0E, 0x54, 0x78, -0x71, 0xC3, 0x54, 0xBC, 0xFC, 0x6F, 0xBD, 0x9E, 0xA8, 0xE6, 0x0D, 0x4B, 0x1F, 0x4B, 0x2D, 0xD8, -0xA4, 0x04, 0x98, 0xA4, 0xAF, 0x2B, 0x62, 0xB9, 0x5A, 0xC4, 0x12, 0x73, 0xE7, 0x31, 0x22, 0xCA, -0x67, 0x6A, 0xF9, 0xAE, 0x2F, 0x09, 0x36, 0x76, 0x01, 0xF6, 0xDE, 0x9F, 0x9C, 0x95, 0x5B, 0xA0, -0x2E, 0x6D, 0x06, 0xFF, 0x54, 0x6D, 0x4E, 0xB8, 0x44, 0x88, 0x3A, 0x88, 0x12, 0xAA, 0xCD, 0xF0, -0x69, 0xE5, 0xC5, 0x9C, 0xEB, 0xD9, 0x55, 0x6B, 0xA7, 0x2B, 0x77, 0xB2, 0xCF, 0xF4, 0x06, 0x01, -0xC8, 0x6C, 0x9D, 0xC6, 0x84, 0x47, 0xA8, 0xB5, 0x8B, 0xDA, 0x75, 0x4A, 0xEC, 0xC0, 0x62, 0xB4, -0xF5, 0x53, 0x6B, 0x5D, 0x5D, 0x66, 0x14, 0x7C, 0x8D, 0x39, 0xB9, 0x23, 0x5C, 0xC0, 0xA0, 0x52, -0xD4, 0x61, 0x14, 0x12, 0xA0, 0x5F, 0x35, 0xC5, 0x51, 0x6B, 0xB7, 0x9D, 0x19, 0x95, 0x32, 0xF7, -0x23, 0xA9, 0x4D, 0xEB, 0xA3, 0x7B, 0xEB, 0xB2, 0xA5, 0x8B, 0x62, 0xA6, 0x6B, 0x07, 0x29, 0xC4, -0x46, 0x65, 0x0F, 0x0B, 0x2F, 0x6E, 0xE6, 0x62, 0x3D, 0x8A, 0x56, 0xF2, 0x8E, 0x2F, 0x6F, 0xC6, -0xDD, 0xC3, 0x81, 0x20, 0x95, 0xCC, 0xA3, 0xAB, 0x9B, 0x6A, 0xCE, 0x85, 0x0F, 0x61, 0x42, 0x78, -0x8D, 0xF6, 0x29, 0x92, 0xCD, 0xA4, 0xB8, 0xEC, 0xF3, 0x67, 0x9B, 0x98, 0x36, 0x9B, 0x57, 0x4A, -0xC9, 0x90, 0x6C, 0x26, 0x65, 0xE1, 0x88, 0x31, 0xE1, 0x94, 0x05, 0xA2, 0x52, 0x4A, 0x86, 0x64, -0x63, 0x29, 0x23, 0x60, 0x65, 0xD7, 0xC9, 0x88, 0x08, 0x36, 0xF5, 0x89, 0x8D, 0xE5, 0xD9, 0x4D, -0xE0, 0xB2, 0xA0, 0x7A, 0x4C, 0x28, 0x90, 0x6D, 0x28, 0x8D, 0x43, 0xB7, 0x3C, 0x63, 0x77, 0x75, -0x11, 0x90, 0x26, 0x79, 0x4C, 0x04, 0x4C, 0x88, 0xE3, 0xAD, 0x88, 0x80, 0x90, 0x64, 0xC3, 0x54, -0x4B, 0xAC, 0x5A, 0x11, 0xC9, 0xF5, 0x5A, 0xFE, 0x85, 0x7D, 0x90, 0x0A, 0xBA, 0xF4, 0x66, 0x53, -0x09, 0xC9, 0x97, 0x6C, 0xD3, 0x97, 0xB2, 0xC5, 0xA4, 0x47, 0xDC, 0xB6, 0xF1, 0xF6, 0x62, 0x62, -0x3C, 0x47, 0x46, 0x0F, 0xCC, 0xD1, 0xCB, 0x54, 0x38, 0xF3, 0x79, 0x40, 0xCA, 0x96, 0x9F, 0x82, -0xB8, 0x56, 0xBB, 0x62, 0x1F, 0x6E, 0x09, 0xF3, 0x78, 0xB6, 0x84, 0x15, 0xAA, 0xCD, 0xB0, 0x55, -0xBB, 0x2A, 0x6D, 0x3C, 0x8A, 0x40, 0xEA, 0xC6, 0x96, 0x75, 0x71, 0x07, 0x04, 0x57, 0x54, 0x40, -0xFA, 0x26, 0x5C, 0xEE, 0x93, 0x79, 0x81, 0xDF, 0x7A, 0x9E, 0xF0, 0x27, 0xA5, 0x6B, 0xD6, 0x27, -0x1F, 0xAA, 0x48, 0xD7, 0xC7, 0x1C, 0x98, 0x85, 0xAE, 0x2D, 0x1B, 0x9A, 0xBE, 0xE4, 0x31, 0xCB, -0xAE, 0xFE, 0x73, 0x17, 0x57, 0x39, 0xBA, 0xC2, 0xC1, 0xD2, 0x93, 0xF2, 0x27, 0x3A, 0x2F, 0xDB, -0xCC, 0x51, 0x0F, 0x56, 0x47, 0x8C, 0x3B, 0x45, 0xF0, 0x89, 0x44, 0xB3, 0xEB, 0x71, 0xF5, 0xFB, -0x9C, 0xCC, 0x70, 0x60, 0xEB, 0xAD, 0x86, 0xC7, 0xEE, 0x4C, 0xA8, 0x60, 0xBA, 0xFE, 0x30, 0xD6, -0xD1, 0xA4, 0x55, 0x18, 0x13, 0x3F, 0xF0, 0x6A, 0xE3, 0xC9, 0x0F, 0x79, 0xFE, 0x4C, 0x30, 0xF8, -0xA2, 0x6D, 0x84, 0xF8, 0x77, 0x26, 0x0F, 0x1E, 0x91, 0x8C, 0xB0, 0xA7, 0x17, 0xBF, 0x60, 0x56, -0xEF, 0xBE, 0xB3, 0x5C, 0x2E, 0x3B, 0xAA, 0xD2, 0x21, 0xE0, 0x36, 0x71, 0xE5, 0x5A, 0x1E, 0xD6, -0x12, 0x05, 0xDD, 0x9F, 0x72, 0xA3, 0xA4, 0x64, 0x9F, 0x24, 0xB5, 0x4D, 0x52, 0xDE, 0x33, 0xB1, -0x4D, 0xB8, 0xDF, 0x36, 0xA2, 0x2D, 0x2D, 0x24, 0xF0, 0x1D, 0x4C, 0x17, 0x45, 0x60, 0x9A, 0x10, -0x4B, 0xB3, 0xC0, 0xB6, 0x1F, 0x7E, 0x30, 0x1A, 0x76, 0xD9, 0xA2, 0x53, 0xA4, 0xF9, 0xE1, 0x0E, -0x8C, 0xF4, 0xCC, 0x28, 0x3C, 0x4D, 0x76, 0xD8, 0x00, 0x4E, 0xFE, 0x30, 0x26, 0x30, 0x9C, 0xF9, -0x0C, 0x00, 0x95, 0xF4, 0xC6, 0x4E, 0x5E, 0x9C, 0xE4, 0xE4, 0x61, 0x0E, 0x29, 0xDC, 0x87, 0x09, -0x0D, 0xF0, 0xFA, 0xFB, 0x3F, 0x72, 0x14, 0x91, 0x1C, 0x59, 0x59, 0x72, 0x81, 0xCD, 0x45, 0x3B, -0x06, 0x4F, 0xC5, 0xFF, 0x73, 0x74, 0x4B, 0x1E, 0x4A, 0x61, 0x4C, 0xD8, 0x76, 0xBD, 0x40, 0x2C, -0xDA, 0xDA, 0x4F, 0x1F, 0x6F, 0x2E, 0xCF, 0x98, 0xE3, 0x31, 0x17, 0x54, 0x6C, 0xAB, 0x5B, 0x77, -0x91, 0x31, 0x30, 0xE0, 0xDF, 0x92, 0xEB, 0x4A, 0x42, 0x41, 0xE7, 0x42, 0xEF, 0x92, 0x46, 0xA8, -0x92, 0xAB, 0x41, 0x5A, 0xE8, 0x27, 0x46, 0x21, 0x10, 0x9F, 0x55, 0xC4, 0x85, 0xCA, 0x60, 0xF2, -0xA6, 0xE2, 0x65, 0x0E, 0xC1, 0xCA, 0xDD, 0xC2, 0xE4, 0x3D, 0x79, 0x08, 0x10, 0xED, 0xFB, 0x1F, -0xF7, 0xC2, 0xB2, 0x38, 0x38, 0x94, 0xAC, 0xA2, 0x07, 0x03, 0x16, 0xBD, 0x43, 0xA6, 0x8D, 0x85, -0x18, 0x18, 0xF1, 0xA3, 0x66, 0x23, 0xF5, 0x9C, 0x20, 0x4D, 0x90, 0x2D, 0x73, 0x4A, 0x53, 0x29, -0x4A, 0xEA, 0xCC, 0xD3, 0x94, 0x06, 0x12, 0xDC, 0x4C, 0xAA, 0xEC, 0x38, 0x5E, 0x76, 0xE7, 0xD4, -0x5F, 0x04, 0x53, 0x98, 0x7D, 0xF1, 0xF0, 0xF1, 0x9B, 0x2A, 0xB5, 0x3B, 0x0F, 0x7C, 0x73, 0x71, -0x0E, 0x7D, 0xDB, 0x66, 0x5E, 0xEF, 0xF4, 0xEA, 0xEA, 0xE2, 0x5C, 0x76, 0x28, 0xCE, 0x6C, 0x08, -0xC9, 0x9E, 0x5C, 0x89, 0xF6, 0x80, 0x51, 0x0F, 0xBA, 0x51, 0xEF, 0x12, 0x6E, 0xEB, 0x88, 0x3F, -0x03, 0x59, 0xA4, 0xE7, 0xB9, 0x73, 0x03, 0xA2, 0xD6, 0x1F, 0x18, 0x57, 0x52, 0x58, 0x5E, 0x19, -0xE1, 0x61, 0x37, 0xA3, 0xB7, 0xAA, 0x4E, 0x19, 0xE6, 0xD8, 0x03, 0x40, 0x40, 0x97, 0x36, 0xB7, -0x07, 0xF6, 0x56, 0x98, 0x9F, 0x2D, 0x57, 0x2A, 0x48, 0x5C, 0xEC, 0x01, 0x77, 0x04, 0xEC, 0x51, -0xC2, 0x1F, 0xC5, 0xFD, 0xE9, 0x1A, 0xCF, 0x09, 0xF8, 0x60, 0xAF, 0x70, 0xD7, 0x3E, 0xA2, 0xD6, -0xA0, 0x30, 0xFF, 0x1F, 0xC6, 0xF3, 0xFD, 0xB0, 0xE5, 0x08, 0x5D, 0xDC, 0x7B, 0x94, 0x53, 0xD9, -0x5D, 0xB0, 0x8D, 0x64, 0x15, 0x62, 0x77, 0xFF, 0x05, 0x70, 0x3C, 0xC8, 0x73, 0xF4, 0x86, 0x93, -0x05, 0x15, 0x10, 0x5D, 0x90, 0x3E, 0xB0, 0x6D, 0xB3, 0xA5, 0x40, 0x0F, 0x2C, 0x40, 0x3E, 0x43, -0x61, 0x4E, 0xF1, 0x17, 0x04, 0xBD, 0xFF, 0xDB, 0x64, 0x82, 0xA6, 0x9C, 0xDD, 0x82, 0x8E, 0xD4, -0x9D, 0x31, 0x84, 0x5D, 0x0B, 0xFE, 0x3E, 0x20, 0x59, 0x50, 0x21, 0x7B, 0x0C, 0xC8, 0x10, 0xA1, -0xEE, 0xDD, 0xE3, 0x9E, 0x97, 0x17, 0x22, 0xB1, 0x40, 0x10, 0xBC, 0x0B, 0x66, 0x0D, 0x74, 0x02, -0x45, 0x58, 0xF5, 0xB4, 0x41, 0x36, 0x8D, 0x22, 0x18, 0x24, 0xD4, 0xE9, 0xC0, 0x08, 0x43, 0x35, -0x9D, 0xE7, 0xDF, 0xE4, 0x41, 0x54, 0xBC, 0x75, 0xA9, 0x01, 0x48, 0x18, 0xC8, 0x3D, 0xD6, 0xE1, -0xE5, 0xF5, 0xD1, 0x71, 0x4F, 0xB5, 0x95, 0x11, 0xEB, 0x87, 0xF5, 0xA9, 0x02, 0x24, 0x09, 0xA7, -0xBC, 0x0F, 0xB9, 0xD0, 0xB9, 0xF4, 0x91, 0x4F, 0x7D, 0x1B, 0x0E, 0x2F, 0xE4, 0x13, 0x73, 0x65, -0xFD, 0xE5, 0xB5, 0xB4, 0x93, 0xCB, 0x55, 0x1B, 0x9B, 0x49, 0x74, 0x78, 0x1A, 0x10, 0x03, 0xA9, -0xBE, 0x3C, 0x30, 0x8C, 0xE1, 0xF1, 0x94, 0xAF, 0xD0, 0x50, 0xED, 0xDA, 0x0E, 0x4F, 0x54, 0x9A, -0x04, 0xC7, 0x5B, 0x64, 0x7D, 0x65, 0x15, 0x8B, 0x50, 0x5D, 0x7D, 0x5C, 0x50, 0x18, 0x6B, 0xFE, -0x6A, 0x23, 0x18, 0xC4, 0x3E, 0x4E, 0x65, 0x6A, 0x19, 0x43, 0x39, 0xA7, 0x07, 0x17, 0x5F, 0x9E, -0x6F, 0x80, 0xAD, 0x15, 0x63, 0x6B, 0x95, 0xA8, 0x2A, 0x22, 0xCE, 0x89, 0xA2, 0x16, 0xB9, 0xA3, -0x26, 0x59, 0x4B, 0x47, 0xBD, 0xB1, 0x30, 0xFC, 0x4D, 0x6E, 0x4E, 0x84, 0xE0, 0x5E, 0xCB, 0x92, -0x07, 0x24, 0x37, 0x15, 0x4E, 0xB4, 0xEF, 0xEA, 0x54, 0xF7, 0xE5, 0x56, 0x9C, 0x7E, 0x86, 0x3A, -0x30, 0xE4, 0x33, 0xD4, 0xB2, 0x48, 0x53, 0x94, 0x93, 0x9B, 0x8A, 0x2B, 0x9A, 0x8F, 0x15, 0x31, -0xD9, 0x97, 0x85, 0x94, 0x55, 0x5C, 0x56, 0x40, 0xA6, 0xAD, 0x09, 0x51, 0x0B, 0x4F, 0x0A, 0xC0, -0x49, 0xCB, 0xF2, 0x51, 0x29, 0x3C, 0x62, 0x02, 0x04, 0x66, 0x06, 0x83, 0x04, 0x48, 0xE4, 0xE0, -0x7B, 0x98, 0x53, 0xCC, 0x95, 0x91, 0xAF, 0x20, 0xE1, 0xD2, 0xCF, 0x44, 0x1D, 0xD5, 0x99, 0xD4, -0xF3, 0xAD, 0x66, 0x16, 0xBF, 0x54, 0x06, 0x3F, 0x73, 0xA7, 0xC2, 0x7B, 0xD3, 0xFC, 0xAE, 0x83, -0x46, 0x38, 0xA5, 0xD2, 0x6A, 0xBE, 0xD0, 0x69, 0xD5, 0xBD, 0xEA, 0x7E, 0x1D, 0x2A, 0x59, 0x0E, -0xBA, 0x7C, 0xA7, 0xC9, 0xED, 0x8A, 0x45, 0xDA, 0x55, 0x6A, 0x7B, 0x6C, 0xCA, 0xEE, 0xB5, 0xBB, -0xC0, 0x05, 0x26, 0x76, 0x7F, 0xA3, 0x23, 0xFA, 0x0B, 0xF1, 0x97, 0x8C, 0xDF, 0x46, 0xAE, 0x2B, -0x5E, 0x68, 0x2A, 0x2C, 0x3D, 0x1C, 0x85, 0x9B, 0x5A, 0xC3, 0xC2, 0xE0, 0x53, 0x79, 0x77, 0x65, -0x9C, 0xE7, 0x3F, 0xDA, 0x59, 0xE9, 0x7F, 0x33, 0x92, 0xD3, 0xB5, 0x5C, 0xC6, 0xF0, 0x9A, 0x70, -0x95, 0xC6, 0xE5, 0x94, 0x4C, 0x75, 0x34, 0x57, 0x1B, 0x85, 0xA4, 0x91, 0xC7, 0xA7, 0x37, 0xC3, -0xF6, 0x0D, 0x81, 0x31, 0x40, 0xC8, 0xA1, 0x43, 0xC0, 0x80, 0x06, 0x63, 0x87, 0xF0, 0xD1, 0xE9, -0x78, 0x7C, 0x79, 0xBE, 0xD3, 0x48, 0xF7, 0xFC, 0x60, 0x5A, 0xBC, 0x5E, 0x19, 0x54, 0xC7, 0xBD, -0xD2, 0x7E, 0x09, 0x77, 0xC8, 0x8E, 0xBD, 0x2A, 0x59, 0x85, 0x45, 0x9A, 0x51, 0x3F, 0x19, 0xC3, -0x5C, 0x16, 0xE9, 0x05, 0x4D, 0xC0, 0xF5, 0xC3, 0x9D, 0xA1, 0xB4, 0xAF, 0x84, 0x4B, 0x79, 0x6B, -0x2A, 0x31, 0x15, 0xF6, 0x26, 0xD5, 0xF0, 0x5D, 0xB5, 0x3E, 0x1B, 0xA6, 0xD7, 0x63, 0x32, 0x0D, -0x35, 0xCB, 0xB6, 0x2D, 0x55, 0x13, 0xD2, 0x2A, 0x65, 0xDD, 0xD2, 0xB1, 0x58, 0xD2, 0xEE, 0x50, -0x77, 0xD0, 0xEA, 0xB7, 0x64, 0x52, 0x18, 0xB4, 0x40, 0x58, 0x2B, 0xB4, 0x5F, 0x1D, 0xAF, 0x4A, -0x92, 0x92, 0xE8, 0xA7, 0x32, 0x2A, 0x45, 0x59, 0x9F, 0x24, 0x27, 0xE7, 0x52, 0x12, 0x9D, 0x83, -0x78, 0x9F, 0x79, 0xAD, 0x88, 0xE3, 0x61, 0x35, 0xC3, 0xF8, 0xD6, 0x70, 0xFA, 0xF3, 0x56, 0x2E, -0x93, 0xB1, 0x1D, 0x57, 0x41, 0x0C, 0xC3, 0x86, 0x78, 0xFE, 0x04, 0x13, 0x9D, 0xFD, 0x55, 0xBC, -0xC0, 0x77, 0xE5, 0xFE, 0xCB, 0x50, 0x7D, 0xE3, 0x99, 0x27, 0xFF, 0x7C, 0x35, 0xCE, 0x3C, 0x85, -0x0B, 0xCC, 0xD5, 0xF3, 0xB9, 0x64, 0x66, 0x95, 0x5F, 0x9B, 0x6F, 0x75, 0x76, 0xBA, 0x89, 0x2C, -0x56, 0x53, 0x6A, 0x65, 0x73, 0xA8, 0x52, 0xFA, 0x56, 0x55, 0x17, 0x01, 0xD3, 0xE7, 0xA4, 0xE4, -0x56, 0x38, 0x58, 0xCE, 0xBC, 0xDF, 0xB4, 0x20, 0x18, 0x86, 0xED, 0x89, 0x04, 0x86, 0xCD, 0x66, -0x6A, 0x32, 0xE2, 0xC8, 0xD2, 0xB0, 0x68, 0x56, 0x0B, 0x29, 0xEC, 0xB4, 0x99, 0x91, 0xAB, 0xD2, -0x98, 0xA2, 0xF9, 0xA6, 0xC3, 0x2A, 0xF7, 0x20, 0x3D, 0x8C, 0xA9, 0x5C, 0xEB, 0x36, 0x07, 0xCB, -0x85, 0x34, 0x05, 0xC5, 0xB6, 0x7C, 0x27, 0x6E, 0x2D, 0x94, 0x2C, 0x84, 0x8E, 0x2D, 0xB4, 0x6F, -0xB3, 0x6B, 0x47, 0xCA, 0x18, 0x94, 0x58, 0xF3, 0x9D, 0x38, 0x37, 0x57, 0xED, 0x10, 0xBA, 0x36, -0xD7, 0xBA, 0xCD, 0x8E, 0x55, 0x56, 0xA0, 0x0F, 0x61, 0x6E, 0xBE, 0x92, 0x86, 0x7D, 0x27, 0xAE, -0x2D, 0xD6, 0x96, 0x44, 0x0B, 0xEA, 0xE2, 0x85, 0xC2, 0x28, 0x9F, 0xDE, 0x61, 0xDF, 0x6A, 0xFF, -0x5F, 0xC6, 0xC6, 0xA2, 0x09, 0x75, 0x08, 0x03, 0xB0, 0xDA, 0xEF, 0xA9, 0x1B, 0xF8, 0x44, 0x34, -0x5B, 0x5E, 0xA4, 0x50, 0x0E, 0xA7, 0x01, 0xBA, 0x66, 0xFA, 0x85, 0x2C, 0x88, 0x8E, 0xDE, 0x19, -0x51, 0x95, 0x96, 0xAD, 0xE2, 0x26, 0x46, 0xB6, 0xD6, 0xA6, 0x80, 0xBF, 0x6E, 0x0D, 0xD7, 0xE8, -0xBF, 0x04, 0xCE, 0x14, 0x16, 0xE9, 0xB0, 0x28, 0xA7, 0x00, 0xBB, 0x9C, 0x67, 0x4B, 0x25, 0x51, -0x58, 0x6B, 0xAE, 0xB6, 0x14, 0xE5, 0x24, 0x45, 0x20, 0xB9, 0x5F, 0x27, 0x9D, 0x44, 0x2C, 0x35, -0xE7, 0x88, 0x17, 0x20, 0x7B, 0x99, 0x95, 0xFA, 0x61, 0xB4, 0x50, 0x3F, 0x5C, 0xB9, 0x4C, 0xDE, -0xFA, 0x50, 0x4F, 0x2A, 0x8D, 0x42, 0x88, 0x93, 0x86, 0x6D, 0x8E, 0xDD, 0xF7, 0xD2, 0x0A, 0xE2, -0xCA, 0x2A, 0x60, 0x24, 0x8D, 0xF9, 0x4E, 0x12, 0x57, 0x52, 0xD4, 0x15, 0x7A, 0x33, 0x69, 0xD8, -0x66, 0x6F, 0xCA, 0xA7, 0xDB, 0xDF, 0x93, 0x17, 0xA3, 0xC2, 0xD3, 0xC8, 0x89, 0xD1, 0xF9, 0x36, -0xFB, 0xF0, 0x5C, 0x1A, 0x21, 0xAD, 0xF8, 0xCE, 0x9C, 0x18, 0x16, 0xF7, 0xE6, 0x5C, 0x19, 0xB6, -0xFE, 0x9F, 0x70, 0x28, 0x3A, 0x53, 0xC6, 0x88, 0xEF, 0xC4, 0xB1, 0x49, 0x21, 0x75, 0x34, 0x62, -0xC6, 0x0D, 0xDB, 0xEC, 0x4E, 0xF5, 0xB0, 0xEA, 0x8A, 0x7D, 0x4F, 0x5D, 0xB4, 0xF0, 0x9A, 0x50, -0xF4, 0x00, 0xA8, 0xD0, 0x5E, 0xBA, 0x95, 0x97, 0xBC, 0xD9, 0xB4, 0xD5, 0x8E, 0x8F, 0xCC, 0x78, -0xA2, 0x27, 0x06, 0x93, 0xF3, 0xAF, 0xB4, 0x13, 0x2D, 0x43, 0x49, 0xB9, 0x2D, 0xF7, 0x46, 0x9E, -0x11, 0x2E, 0x2E, 0x8C, 0x68, 0x45, 0xA1, 0xDE, 0xBC, 0x6A, 0x82, 0xE7, 0x62, 0x7F, 0x18, 0x3E, -0x07, 0xD0, 0x8F, 0x57, 0xC2, 0x67, 0x46, 0x68, 0xEC, 0x73, 0xB5, 0x12, 0x40, 0x77, 0x14, 0xAB, -0x75, 0x43, 0x83, 0xCD, 0x6D, 0xC5, 0x50, 0xEF, 0xD7, 0x87, 0x6B, 0x9D, 0xF0, 0xAD, 0x5E, 0x21, -0xDF, 0x4B, 0x77, 0xE7, 0x47, 0xFD, 0x56, 0x93, 0x8D, 0xFC, 0x22, 0x60, 0xAB, 0xF6, 0xCB, 0xB3, -0xD4, 0x09, 0xBC, 0x0E, 0xB5, 0x60, 0x2D, 0xD4, 0x54, 0x4E, 0xCC, 0xE1, 0x91, 0x1D, 0xB6, 0xC0, -0xEF, 0xF1, 0x1D, 0xB8, 0xC0, 0x72, 0xC5, 0x98, 0xAB, 0x0A, 0xEA, 0xD3, 0xC3, 0xAD, 0x6A, 0xD8, -0x54, 0xD8, 0xA3, 0x7A, 0x6C, 0x81, 0x5B, 0xE3, 0x1E, 0x9C, 0xFF, 0xAC, 0x3F, 0x32, 0xAB, 0x90, -0xDE, 0x48, 0xD3, 0x26, 0x89, 0x3D, 0x4B, 0x5F, 0xDB, 0xE7, 0x0B, 0xE4, 0xB9, 0x1C, 0xB0, 0xAE, -0x76, 0xF5, 0x9D, 0x6C, 0x13, 0xAF, 0x4C, 0x6E, 0x22, 0x76, 0xFA, 0x7D, 0x79, 0xFD, 0x9E, 0x7F, -0xC9, 0x6B, 0xF4, 0x07, 0x7D, 0xF9, 0xF3, 0x46, 0xEE, 0x52, 0x74, 0x94, 0x05, 0xF1, 0x97, 0x77, -0x6C, 0x22, 0x57, 0xCB, 0x3E, 0x8F, 0xD2, 0xC2, 0xAB, 0xBE, 0x77, 0xAF, 0x9E, 0x89, 0xDC, 0x8C, -0xC7, 0x97, 0xFA, 0xD9, 0x07, 0xE0, 0x0A, 0x04, 0xC3, 0xD0, 0xFB, 0x28, 0x6E, 0x00, 0xA2, 0x31, -0x48, 0x97, 0x8F, 0xDF, 0xC2, 0x54, 0x15, 0xD3, 0x6F, 0x12, 0x94, 0x6B, 0xE5, 0x98, 0x44, 0xF3, -0x18, 0xB5, 0x12, 0xA4, 0xFA, 0xFD, 0xD9, 0xAC, 0xDF, 0x97, 0xCF, 0x78, 0xC0, 0xC0, 0x90, 0xAC, -0x14, 0xB6, 0xCE, 0x41, 0x5F, 0x3E, 0xBE, 0xEE, 0x1C, 0xF6, 0x23, 0xEB, 0x92, 0x7A, 0x0E, 0x59, -0xA6, 0x50, 0xB0, 0xFD, 0xE2, 0xDE, 0x24, 0xB6, 0x0D, 0xB7, 0xEB, 0x16, 0xA9, 0x7C, 0x45, 0xC5, -0xE4, 0xE6, 0xDA, 0x63, 0x3C, 0x9B, 0x61, 0xDC, 0x44, 0xFB, 0xC3, 0x3D, 0xA5, 0xFD, 0xCB, 0x7E, -0xB5, 0xB3, 0xDE, 0x32, 0x66, 0x7D, 0x45, 0x5D, 0x67, 0xB3, 0xA6, 0x48, 0xBF, 0xD4, 0xBA, 0xBE, -0xAA, 0xD1, 0x75, 0x84, 0x29, 0xFF, 0xAA, 0xBA, 0xBE, 0x7E, 0xDD, 0x4C, 0xD7, 0x57, 0x5A, 0xD7, -0xD7, 0x35, 0xBA, 0x5E, 0x33, 0xF6, 0x75, 0x75, 0xED, 0xF7, 0x1B, 0xE9, 0xFA, 0xCC, 0xF6, 0xDF, -0xD4, 0x6B, 0xFA, 0xD1, 0xE5, 0xC4, 0xA6, 0x32, 0x6D, 0x25, 0xFA, 0xAE, 0x9B, 0x92, 0xAB, 0xCA, -0x2A, 0xAA, 0xEF, 0x68, 0x9C, 0x0C, 0x1A, 0xEA, 0x93, 0xE8, 0xD0, 0x6C, 0x6A, 0x25, 0xE7, 0x68, -0xEA, 0xD1, 0xB0, 0x42, 0xB4, 0xE9, 0x1C, 0xEA, 0xB7, 0x05, 0xB5, 0x89, 0x2A, 0x55, 0xBC, 0x23, -0xCF, 0x91, 0x2E, 0xA1, 0x73, 0xC4, 0x5C, 0x3C, 0x47, 0x1E, 0x57, 0xDF, 0xA8, 0x83, 0x54, 0xF5, -0xB5, 0x40, 0xCF, 0x50, 0xEA, 0xD5, 0x2E, 0x0A, 0x7F, 0xE6, 0x2E, 0xE3, 0x30, 0x8B, 0x6D, 0x54, -0x64, 0xA0, 0x74, 0x6C, 0x5C, 0x5D, 0x51, 0xB8, 0x73, 0xED, 0x49, 0x59, 0x28, 0x64, 0xFF, 0x10, -0x64, 0xA4, 0x8A, 0x55, 0x5A, 0xE1, 0x4B, 0x90, 0xAD, 0x21, 0x4C, 0x66, 0x91, 0x02, 0xEC, 0x4C, -0x82, 0x15, 0xCD, 0x13, 0xD6, 0x1F, 0x59, 0x87, 0x99, 0x2A, 0x15, 0x85, 0xBC, 0xAA, 0x52, 0x89, -0xDF, 0xC5, 0x0C, 0x27, 0x46, 0xF1, 0x69, 0xB8, 0x01, 0xFE, 0xE3, 0xC1, 0xE8, 0xE0, 0x6C, 0x74, -0x6A, 0xAC, 0x23, 0x72, 0x8D, 0x38, 0x5E, 0x1B, 0xB1, 0x0C, 0x4A, 0xF1, 0xAB, 0x98, 0xAD, 0xE1, -0x6F, 0x98, 0x3B, 0x32, 0x46, 0x64, 0xAD, 0xC1, 0xD3, 0x60, 0x94, 0xAA, 0xE4, 0x49, 0xE4, 0x84, -0x25, 0x3C, 0xA9, 0x86, 0x4C, 0xED, 0xCE, 0xFE, 0xE1, 0x61, 0xB6, 0x76, 0xE7, 0x5B, 0x44, 0xCD, -0x4C, 0x50, 0x83, 0xA0, 0xB2, 0xBE, 0x1A, 0x6A, 0x66, 0x1E, 0x35, 0xF3, 0xDF, 0x87, 0x5A, 0xF3, -0x3C, 0x79, 0xFC, 0xF3, 0xCA, 0x42, 0xA4, 0xA6, 0xFB, 0x1B, 0xB2, 0x7B, 0xA5, 0xBE, 0xAA, 0xE4, -0x51, 0xEB, 0xD1, 0x88, 0xCF, 0x3A, 0x75, 0x55, 0xEA, 0xDE, 0xD3, 0xE1, 0x59, 0x20, 0x7C, 0xE6, -0x50, 0x41, 0x52, 0x49, 0x57, 0x3D, 0xB9, 0xD5, 0x09, 0x53, 0xCD, 0x10, 0x1B, 0x25, 0xC6, 0x76, -0x52, 0x13, 0x17, 0x15, 0xE3, 0x00, 0x0F, 0x6A, 0xDB, 0x48, 0xBD, 0x37, 0x43, 0xAC, 0x9D, 0x6F, -0x3A, 0xC9, 0xEE, 0x49, 0x19, 0x55, 0x69, 0x30, 0x7A, 0x61, 0x36, 0x4C, 0x83, 0xF1, 0x69, 0x94, -0x06, 0x47, 0xA3, 0x93, 0xC3, 0x7E, 0x7F, 0xAD, 0x34, 0x18, 0x89, 0xCF, 0xA6, 0x2C, 0xCD, 0x18, -0x12, 0x16, 0x1D, 0x51, 0xA4, 0x4A, 0xED, 0x51, 0x0F, 0x8D, 0x4D, 0xEC, 0xBA, 0x6A, 0x7F, 0x6D, -0xED, 0x5E, 0xF8, 0x35, 0xD3, 0x46, 0x23, 0xE4, 0x92, 0x17, 0x82, 0x33, 0x45, 0x2C, 0x19, 0xF4, -0xFA, 0xFD, 0xD1, 0xE8, 0x29, 0xD0, 0x8B, 0x59, 0xB7, 0xC2, 0xEA, 0x12, 0xB9, 0x3B, 0xB5, 0x7D, -0x90, 0xC5, 0x6F, 0x39, 0x87, 0x88, 0x25, 0xE7, 0x09, 0x60, 0x12, 0xB2, 0x4D, 0x00, 0xCB, 0xE0, -0x15, 0x31, 0x6E, 0x0D, 0xAF, 0xE5, 0x11, 0x6A, 0xBF, 0x55, 0x2F, 0x22, 0x40, 0xDF, 0xFF, 0x28, -0x08, 0xDF, 0xD9, 0x46, 0xEC, 0xB2, 0x6F, 0x71, 0xC7, 0x21, 0x97, 0x69, 0x7C, 0x3C, 0x8A, 0xF9, -0xB0, 0x4B, 0xB1, 0x57, 0x6F, 0xF8, 0xC8, 0x19, 0xAC, 0x3C, 0x47, 0xBA, 0x7E, 0xAD, 0xAD, 0xE1, -0x95, 0x49, 0x35, 0xF8, 0x57, 0x01, 0xFB, 0xF4, 0xD0, 0x66, 0x5F, 0x5D, 0x0F, 0xA1, 0xCD, 0x35, -0x3E, 0x71, 0x80, 0x66, 0xB8, 0xB7, 0x86, 0xBF, 0xA8, 0x53, 0x74, 0x06, 0xE7, 0xFF, 0x16, 0x4C, -0xD7, 0x30, 0xA3, 0x11, 0xA2, 0xD9, 0xD7, 0xF4, 0x43, 0x44, 0x73, 0x8D, 0xC9, 0x08, 0x23, 0x31, -0x7D, 0x7C, 0xB0, 0x66, 0xD8, 0xB7, 0x86, 0x3F, 0xBF, 0x1F, 0xC3, 0x30, 0x73, 0x47, 0xE4, 0x57, -0xDC, 0x3F, 0x47, 0xE3, 0x8B, 0x9B, 0xCB, 0x0F, 0x1F, 0xC7, 0xDB, 0x19, 0x9F, 0xE9, 0xAF, 0x23, -0x48, 0xB0, 0x4C, 0x9A, 0x1E, 0x8F, 0x64, 0x1E, 0xC8, 0x88, 0x77, 0x1E, 0xC6, 0xD1, 0xC9, 0xE4, -0xE4, 0x6A, 0x1B, 0x03, 0xB2, 0xF8, 0x7D, 0x0B, 0x71, 0x06, 0x2D, 0x5C, 0x78, 0xEA, 0xC0, 0x2C, -0x88, 0x90, 0x99, 0x54, 0x37, 0x21, 0xDD, 0xB6, 0x9D, 0x61, 0x99, 0xFD, 0x56, 0x89, 0x08, 0xCF, -0x6C, 0xE3, 0x13, 0x87, 0x66, 0x86, 0x3B, 0xC0, 0x28, 0x4F, 0x91, 0x3A, 0x47, 0x37, 0xC4, 0x81, -0xDF, 0x5B, 0x39, 0x2D, 0xCA, 0x7E, 0x71, 0x46, 0x66, 0xFC, 0x89, 0x1B, 0x9F, 0x3A, 0x28, 0x33, -0xEC, 0xE3, 0x01, 0x48, 0x9E, 0xA3, 0x11, 0xA6, 0xF6, 0x76, 0x46, 0x64, 0xEA, 0xBB, 0x41, 0x42, -0x14, 0xD3, 0x2D, 0x4F, 0x1C, 0x8B, 0x09, 0xEB, 0xD6, 0xF0, 0x14, 0x16, 0xA8, 0xFF, 0x02, 0xEC, -0x9A, 0xAD, 0xE6, 0x1F, 0xF1, 0x48, 0x7A, 0xE5, 0x4B, 0x6C, 0xD9, 0x6B, 0xC7, 0x3D, 0xF9, 0x3A, -0x5E, 0xEE, 0x86, 0xE3, 0x1F, 0x3A, 0x9D, 0xE3, 0xF0, 0xFB, 0xF3, 0xF5, 0x33, 0x49, 0x7D, 0xA2, -0x8A, 0x06, 0x6C, 0x6A, 0xDE, 0xCA, 0x55, 0xA6, 0xFA, 0x12, 0x13, 0x9B, 0xE9, 0xFA, 0xF8, 0xAE, -0xFA, 0xDF, 0x6D, 0x5A, 0x3D, 0x5D, 0x28, 0xDC, 0x7A, 0x63, 0x0C, 0x3F, 0xAA, 0x23, 0x94, 0x7E, -0xED, 0x5D, 0x33, 0x19, 0x76, 0x3A, 0x29, 0x71, 0x69, 0x4B, 0xA3, 0x63, 0xA0, 0xD4, 0x5F, 0x16, -0xA0, 0xBE, 0x41, 0x40, 0xFF, 0x17, 0x3B, 0xFF, 0x0B, 0x55, 0x20, 0xB8, 0x15, 0x7C, 0x67, 0x00, -0x00 +0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xED, 0x5D, 0xE9, 0x73, 0xDB, 0x46, +0x96, 0xFF, 0xBE, 0x55, 0xFB, 0x3F, 0x74, 0x98, 0x4A, 0x40, 0x95, 0xCD, 0x43, 0x97, 0x4D, 0xC9, +0x22, 0xA7, 0x24, 0x4A, 0x4C, 0xE4, 0x95, 0x63, 0x8D, 0x28, 0x47, 0xD9, 0x4C, 0xCD, 0x87, 0x26, +0xD0, 0x24, 0xDB, 0x06, 0x01, 0x04, 0x87, 0x28, 0x7A, 0xC7, 0xFF, 0xFB, 0xF6, 0x85, 0x1B, 0x0D, +0xE2, 0x20, 0x15, 0x6A, 0x32, 0x74, 0x62, 0x93, 0xC0, 0xEB, 0x77, 0xF5, 0xAF, 0x5F, 0x1F, 0x68, +0xBC, 0x3E, 0xFB, 0xEE, 0xF2, 0xE3, 0xF0, 0xFE, 0x7F, 0x6F, 0xAF, 0xC0, 0xDC, 0x5D, 0xE8, 0x83, +0xFF, 0xFE, 0xAF, 0x33, 0xF1, 0x2F, 0xFD, 0x86, 0xA0, 0x46, 0xBE, 0x01, 0xF2, 0x39, 0xD3, 0xB1, +0xF1, 0x05, 0xD8, 0x48, 0xEF, 0x2B, 0x8E, 0xBB, 0xD2, 0x91, 0x33, 0x47, 0xC8, 0x55, 0xC0, 0xDC, +0x46, 0xD3, 0xBE, 0x32, 0x77, 0x5D, 0xCB, 0x39, 0xED, 0x74, 0x54, 0xCD, 0xF8, 0xEC, 0xB4, 0x55, +0xDD, 0xF4, 0xB4, 0xA9, 0x0E, 0x6D, 0xD4, 0x56, 0xCD, 0x45, 0x07, 0x7E, 0x86, 0x4F, 0x1D, 0x1D, +0x4F, 0x9C, 0xCE, 0xD4, 0x34, 0xDC, 0x16, 0x5C, 0x22, 0xC7, 0x5C, 0xA0, 0xCE, 0x71, 0x7B, 0xFF, +0xB8, 0x7D, 0xD8, 0x51, 0x1D, 0xA7, 0x03, 0x75, 0xBD, 0xBD, 0xC0, 0x46, 0x9B, 0x7C, 0x57, 0x00, +0x36, 0x5C, 0x34, 0xB3, 0xB1, 0xBB, 0x22, 0x82, 0xE6, 0xF0, 0x78, 0xFF, 0xA0, 0x85, 0x9F, 0xF4, +0x8F, 0xBF, 0xBF, 0x7F, 0xD2, 0x7B, 0xF0, 0xF3, 0xFE, 0xF0, 0x6B, 0x77, 0xF1, 0x3F, 0x9F, 0x57, +0xA3, 0xFB, 0xF7, 0x7F, 0x7F, 0xEA, 0x38, 0xAF, 0x3E, 0xBD, 0x59, 0x9A, 0x5D, 0xF3, 0xCD, 0xED, +0xAB, 0xE1, 0xEF, 0xB7, 0x77, 0xEF, 0x7F, 0x7B, 0x35, 0xFB, 0x8A, 0x0E, 0xDF, 0xCF, 0x7B, 0x23, +0xDB, 0xEC, 0x2C, 0xEE, 0x57, 0x37, 0xF6, 0xB1, 0xDD, 0xF9, 0xF5, 0xE9, 0x95, 0xF7, 0xEB, 0xDB, +0xF7, 0xBD, 0xBB, 0xC7, 0xBB, 0xE9, 0xEF, 0xD6, 0xF1, 0xAB, 0xDF, 0x4E, 0xA6, 0xF8, 0xF1, 0xA7, +0xB7, 0xE7, 0xFD, 0xBE, 0x02, 0x54, 0xDB, 0x74, 0x1C, 0xD3, 0xC6, 0x33, 0x6C, 0xF4, 0x15, 0x68, +0x98, 0xC6, 0x6A, 0x61, 0x7A, 0x44, 0x07, 0x62, 0x14, 0xB2, 0x6D, 0x64, 0x5B, 0xA6, 0x8E, 0x55, +0xA2, 0x88, 0x61, 0xB6, 0xFC, 0x4B, 0x0A, 0xE8, 0xF8, 0x1E, 0x61, 0x7E, 0x10, 0x3F, 0xE8, 0x67, +0x62, 0x6A, 0x2B, 0xF0, 0x7F, 0xE1, 0x6F, 0x76, 0x0D, 0xAA, 0x5F, 0x66, 0xB6, 0xE9, 0x19, 0x5A, +0x4B, 0x35, 0x75, 0xD3, 0x3E, 0x05, 0xDF, 0x4F, 0xF7, 0xE9, 0x9F, 0x77, 0x71, 0x3A, 0xE6, 0x9A, +0x29, 0x5C, 0x60, 0x7D, 0x75, 0x0A, 0xCE, 0x6D, 0x0C, 0xF5, 0xD7, 0xC0, 0x81, 0x86, 0xD3, 0x72, +0x90, 0x8D, 0xA7, 0x11, 0xE2, 0x6F, 0xE1, 0x57, 0xE2, 0x5D, 0xC3, 0x85, 0xD8, 0x40, 0x76, 0x52, +0xAA, 0x86, 0x1D, 0x4B, 0x87, 0x84, 0xD3, 0x54, 0x47, 0x4F, 0x49, 0x49, 0xE4, 0x52, 0x4B, 0xC3, +0x36, 0x52, 0x5D, 0x6C, 0x1A, 0xA7, 0x80, 0xA8, 0xE5, 0x2D, 0x8C, 0x04, 0xD1, 0x67, 0xCF, 0x71, +0xF1, 0x74, 0xD5, 0xA2, 0x12, 0x90, 0xE1, 0x12, 0x2A, 0xF2, 0x37, 0xB2, 0x13, 0x54, 0x50, 0xC7, +0x33, 0xA3, 0x85, 0x5D, 0xB4, 0x70, 0x24, 0x14, 0x73, 0x84, 0x67, 0x73, 0x5A, 0x1C, 0xEA, 0x6A, +0x73, 0xBF, 0xDB, 0xFD, 0x01, 0xB4, 0x00, 0xF9, 0xC7, 0x7A, 0xDA, 0x93, 0x98, 0xA4, 0x9B, 0x33, +0xB3, 0x55, 0xC9, 0xAE, 0x7C, 0x65, 0x92, 0x32, 0x92, 0x9C, 0x97, 0x58, 0x73, 0xE7, 0xA7, 0x5C, +0x37, 0x89, 0x0D, 0x59, 0xF7, 0x16, 0xD0, 0x26, 0xD8, 0x69, 0xD9, 0x9C, 0xE2, 0x20, 0x4E, 0x90, +0xB2, 0xCB, 0x45, 0x4F, 0x6E, 0x52, 0x30, 0xAB, 0x78, 0x07, 0x7F, 0x45, 0xA7, 0xE0, 0xF0, 0x4D, +0x8A, 0x3F, 0xBB, 0xBB, 0x14, 0x0A, 0x4C, 0x4C, 0x5D, 0x93, 0xB0, 0x9F, 0x9A, 0xF6, 0x42, 0xEE, +0xB6, 0x34, 0x08, 0x97, 0x73, 0xE2, 0xA8, 0x84, 0x2C, 0x0B, 0x6A, 0x1A, 0x36, 0x66, 0x29, 0x33, +0x18, 0x07, 0xD3, 0xD6, 0x90, 0xDD, 0xB2, 0xA1, 0x86, 0x3D, 0x87, 0xBA, 0x22, 0x83, 0xE2, 0xA9, +0x45, 0xDA, 0xAB, 0x66, 0x2E, 0x4F, 0x41, 0x97, 0xFC, 0xA1, 0x24, 0xC0, 0x9E, 0x4D, 0x60, 0xB3, +0xFB, 0x1A, 0x88, 0xFF, 0xDA, 0x87, 0x7B, 0xEF, 0x32, 0xDD, 0xDE, 0xEB, 0xFE, 0x90, 0xED, 0x58, +0xD7, 0xB4, 0xF2, 0xDC, 0xAA, 0xC3, 0x09, 0xD2, 0xA5, 0x20, 0x99, 0xE8, 0xA6, 0xFA, 0x25, 0x5B, +0x20, 0x85, 0x62, 0xB6, 0xC4, 0x89, 0xE9, 0xBA, 0xE6, 0xE2, 0x14, 0x1C, 0x97, 0xAA, 0x8B, 0xE0, +0x3E, 0xAF, 0xC9, 0xFD, 0x74, 0x4D, 0xFA, 0xAD, 0xFF, 0xF0, 0xF0, 0x30, 0xDB, 0x16, 0x6C, 0x58, +0x9E, 0xFB, 0x0F, 0x77, 0x65, 0xA1, 0xBE, 0x42, 0x81, 0xA2, 0xFC, 0x53, 0x8E, 0xD1, 0xA4, 0xEE, +0x41, 0xD5, 0x65, 0x56, 0x4C, 0xAC, 0xEA, 0xD2, 0x76, 0x71, 0x02, 0x52, 0x96, 0x54, 0x98, 0x43, +0x02, 0x9E, 0x06, 0xBE, 0x57, 0x55, 0x35, 0xDF, 0x3B, 0x19, 0x10, 0x91, 0x9B, 0x2F, 0x31, 0xD2, +0xF1, 0x26, 0x0B, 0x9C, 0x61, 0x66, 0x46, 0xC8, 0x3C, 0x1A, 0x9E, 0x8F, 0x8E, 0xBB, 0xD9, 0x1E, +0xCD, 0x85, 0x72, 0x1D, 0x7F, 0x90, 0xEE, 0x20, 0xC9, 0x57, 0xF5, 0x6C, 0x87, 0xCA, 0xB4, 0x4C, +0x9C, 0x11, 0xEC, 0x72, 0x30, 0x9B, 0xEF, 0xA0, 0xE0, 0xEE, 0xFA, 0x96, 0x3E, 0xF1, 0x48, 0x05, +0x18, 0xFF, 0x71, 0x59, 0x09, 0x97, 0xB5, 0x5D, 0x73, 0x36, 0xD3, 0xD1, 0x36, 0x7A, 0x95, 0x88, +0x09, 0x7E, 0xCB, 0xD8, 0x97, 0xF7, 0x01, 0x42, 0x8F, 0xCC, 0xA0, 0x15, 0xEF, 0x48, 0xD6, 0x33, +0x71, 0x96, 0xD8, 0x55, 0xE7, 0x49, 0x2E, 0x96, 0xE9, 0x60, 0xDE, 0xAB, 0x93, 0x81, 0x1A, 0x74, +0xF1, 0x63, 0xB2, 0x36, 0x02, 0x53, 0xB1, 0x41, 0xC6, 0x73, 0xA8, 0x95, 0x13, 0x22, 0xDF, 0xC8, +0x7B, 0xC2, 0xC3, 0xA3, 0x82, 0xEA, 0xB1, 0xE6, 0x9E, 0x54, 0xD2, 0xB4, 0xA0, 0x4A, 0x86, 0x77, +0xA4, 0x9B, 0xC8, 0x16, 0x9C, 0xBC, 0xEC, 0x4B, 0xED, 0x4A, 0x44, 0x3A, 0x24, 0x64, 0xA5, 0x2B, +0x35, 0x74, 0x05, 0x9C, 0x90, 0xA8, 0xE6, 0xA5, 0x00, 0x9F, 0x0F, 0x4C, 0x86, 0xC8, 0xA4, 0x26, +0x3A, 0x9A, 0xBA, 0xE9, 0xAB, 0x76, 0x5A, 0x3D, 0xFA, 0xF1, 0x01, 0x91, 0xBA, 0x9E, 0x6E, 0xAB, +0xE9, 0x70, 0x4B, 0x60, 0x3D, 0xF9, 0x82, 0xDD, 0x96, 0x6B, 0x93, 0x31, 0xA0, 0xB0, 0xA3, 0x7D, +0xE4, 0x24, 0x95, 0xCC, 0xBD, 0x9B, 0x68, 0xB5, 0x39, 0x95, 0xC6, 0x3D, 0x78, 0x3A, 0x41, 0x64, +0x18, 0x81, 0xCA, 0x3B, 0xD2, 0x1F, 0x23, 0x2A, 0x8A, 0xA4, 0xE6, 0x0E, 0xD2, 0x6D, 0x57, 0xD4, +0x75, 0xC6, 0x1D, 0xEE, 0xE4, 0xA3, 0x8C, 0x18, 0xC3, 0xFD, 0x99, 0x71, 0xA7, 0xD0, 0xF0, 0x66, +0x0B, 0x2E, 0x3D, 0x8E, 0x75, 0xC4, 0xC9, 0x6E, 0xEE, 0x54, 0x9D, 0x23, 0xF5, 0x0B, 0xD2, 0xC0, +0x2B, 0x19, 0x46, 0x33, 0xA0, 0x70, 0xB0, 0x7F, 0xF2, 0x66, 0x94, 0x37, 0x42, 0x38, 0x9D, 0x9A, +0xAA, 0xE7, 0xE4, 0xF0, 0x4C, 0x8E, 0xC3, 0x48, 0xAF, 0x5E, 0x80, 0x6B, 0x4A, 0x57, 0x09, 0x1A, +0x62, 0x5E, 0xA4, 0xA3, 0xCE, 0x53, 0xEE, 0x32, 0x12, 0x6D, 0xD0, 0x6F, 0x4D, 0x5A, 0x9D, 0xC9, +0x21, 0x5E, 0x6B, 0xE1, 0x94, 0xA0, 0x2E, 0x46, 0x29, 0x19, 0x51, 0x90, 0x02, 0x33, 0x54, 0x66, +0xDC, 0x94, 0x3F, 0xAA, 0x11, 0x52, 0xCE, 0x3A, 0xD1, 0x89, 0xDE, 0x99, 0xA3, 0xDA, 0xD8, 0x72, +0x23, 0xD3, 0xBE, 0xA9, 0x67, 0xB0, 0xA9, 0x14, 0xF0, 0x2C, 0x8D, 0x68, 0x7B, 0xAD, 0xE9, 0xA8, +0xB9, 0x97, 0xD4, 0xE1, 0x11, 0xDA, 0xE0, 0x09, 0xF4, 0x81, 0x46, 0x6A, 0x6F, 0x41, 0x5A, 0x4B, +0x7B, 0x86, 0xDC, 0x2B, 0x1D, 0xD1, 0xAF, 0x17, 0xAB, 0x6B, 0xAD, 0xD9, 0xC0, 0x06, 0x24, 0x5C, +0x1E, 0x49, 0x60, 0xFC, 0x80, 0x0D, 0xA7, 0x91, 0xF4, 0x0B, 0x9E, 0x82, 0xA6, 0xAC, 0xAC, 0x12, +0x96, 0xBD, 0x32, 0xE0, 0x44, 0x47, 0x9A, 0xB2, 0xD7, 0x16, 0x15, 0x9A, 0x52, 0x84, 0x7E, 0x9E, +0xDA, 0xCC, 0xA2, 0xB6, 0xE8, 0x0D, 0x88, 0x5A, 0x0A, 0xEB, 0x08, 0x92, 0xED, 0xF7, 0x1B, 0x40, +0xBA, 0x93, 0x82, 0x80, 0x84, 0x03, 0xED, 0xFB, 0xD3, 0x0C, 0x22, 0x9F, 0x98, 0x63, 0x33, 0xDC, +0xE7, 0x20, 0x77, 0x84, 0x0D, 0xEC, 0xCC, 0x87, 0xB4, 0x2D, 0xA4, 0x5D, 0x98, 0xEB, 0x82, 0x29, +0x2B, 0x79, 0x6D, 0x68, 0x58, 0x85, 0x94, 0xDB, 0x1A, 0x0F, 0x48, 0xAB, 0x81, 0xF3, 0x61, 0xAD, +0x51, 0x9D, 0x9B, 0x58, 0x45, 0x8D, 0xBD, 0x82, 0xCE, 0x2A, 0xC0, 0x16, 0x19, 0xDA, 0x16, 0x99, +0xBA, 0xD8, 0xD5, 0xCB, 0x71, 0x2E, 0x5A, 0xDB, 0xF5, 0xBC, 0x95, 0x05, 0x8C, 0xBA, 0xCE, 0xAA, +0xCB, 0x53, 0xEA, 0xAB, 0x4C, 0x14, 0x67, 0x06, 0x9E, 0x34, 0x6E, 0xAF, 0x9E, 0xB0, 0xDB, 0xC4, +0xDA, 0x5E, 0x46, 0xD3, 0x5F, 0xAC, 0x86, 0x14, 0x8D, 0x24, 0x38, 0x67, 0xC7, 0x00, 0xE7, 0x62, +0x35, 0xD4, 0xA1, 0xE3, 0xFC, 0x02, 0x17, 0xC8, 0x57, 0xF6, 0xA3, 0x45, 0xD9, 0x67, 0x44, 0x02, +0x22, 0x23, 0x00, 0x77, 0x46, 0x6D, 0x9D, 0xDB, 0x36, 0x5C, 0xB5, 0x2D, 0xDB, 0x74, 0x4D, 0x1A, +0x16, 0xE9, 0xDA, 0xC0, 0x15, 0x54, 0xE7, 0x6D, 0x15, 0xEA, 0x7A, 0x33, 0x54, 0xE4, 0xB5, 0x6F, +0x40, 0x13, 0xE9, 0x59, 0x6C, 0xE8, 0x07, 0xE9, 0xBE, 0x20, 0xA2, 0xF6, 0x14, 0x12, 0x78, 0x64, +0xF8, 0xFC, 0x5B, 0x52, 0x43, 0xA6, 0xA5, 0x16, 0x29, 0xE9, 0xDA, 0x5E, 0xB2, 0x20, 0x07, 0xDB, +0x33, 0x6A, 0x9F, 0xA1, 0x43, 0x31, 0xE5, 0xB3, 0xCC, 0x8E, 0x05, 0xB0, 0x5C, 0x4C, 0x0C, 0x19, +0xDC, 0x2A, 0x05, 0xB3, 0x2B, 0x43, 0xBB, 0x34, 0x4D, 0xBB, 0x5E, 0x24, 0xD3, 0x08, 0x07, 0x53, +0x00, 0x69, 0x73, 0x31, 0xC7, 0xC5, 0x0B, 0x94, 0xC3, 0xD6, 0x6F, 0x44, 0x1B, 0x8A, 0x2F, 0x6B, +0xA4, 0x55, 0x35, 0x22, 0xDF, 0x35, 0xC5, 0x03, 0x41, 0xA7, 0x73, 0x73, 0x75, 0x09, 0x2E, 0xD0, +0x1C, 0x3E, 0x62, 0xD3, 0x73, 0x32, 0xD1, 0xA0, 0x23, 0xD5, 0xFD, 0x68, 0xE8, 0xAB, 0x8F, 0x06, +0xDA, 0x48, 0x84, 0x20, 0x12, 0x85, 0x40, 0xBB, 0xB1, 0x17, 0x67, 0xB6, 0xA1, 0x06, 0xB4, 0xB6, +0xE9, 0xA7, 0x5A, 0x4E, 0x5E, 0x93, 0xCF, 0x6C, 0x23, 0x73, 0x93, 0x8C, 0xD3, 0x35, 0xC4, 0xE3, +0x9C, 0x53, 0xB2, 0x8D, 0xD0, 0xD2, 0x2E, 0x72, 0x5C, 0xD6, 0xF9, 0x54, 0x6D, 0x23, 0x01, 0x83, +0x92, 0xDD, 0x72, 0x05, 0x28, 0x17, 0x10, 0xB5, 0x06, 0x72, 0x6B, 0x5D, 0xA2, 0xA1, 0x89, 0x37, +0x5B, 0xE2, 0x29, 0xAE, 0xEA, 0x0E, 0xA1, 0xCB, 0x03, 0x61, 0x31, 0x76, 0x6D, 0x64, 0xCC, 0xDC, +0xF9, 0x36, 0x5D, 0x52, 0x50, 0x5C, 0x5D, 0xB7, 0xD8, 0xC8, 0xD2, 0xE9, 0xA8, 0x10, 0xDD, 0x20, +0x6D, 0xEC, 0x92, 0x7F, 0xAB, 0xBA, 0xC7, 0xF6, 0x0C, 0x03, 0x1B, 0xB3, 0x67, 0x02, 0x4C, 0x31, +0x69, 0x05, 0x9C, 0x23, 0x09, 0x5A, 0x57, 0xB6, 0x6D, 0xDA, 0x7C, 0x45, 0x30, 0x33, 0x66, 0x91, +0xF6, 0x45, 0x26, 0x9A, 0x64, 0x5E, 0xC4, 0x86, 0xE3, 0x65, 0x9B, 0x27, 0xA2, 0xDC, 0x2F, 0x91, +0xCB, 0x9F, 0x32, 0x55, 0xF5, 0xF8, 0x30, 0xA2, 0xC0, 0x25, 0x7E, 0xDC, 0xA6, 0xBB, 0x0B, 0x88, +0x5A, 0x3B, 0xC3, 0xC9, 0xFD, 0xE4, 0x07, 0xC3, 0x39, 0x74, 0x6E, 0xF7, 0x9B, 0xC9, 0x40, 0x9C, +0xEB, 0x62, 0x6B, 0xFF, 0xD6, 0x66, 0x4B, 0x57, 0x95, 0x9B, 0x3B, 0xE9, 0x00, 0xC7, 0x6C, 0xA1, +0xAE, 0xB1, 0x57, 0x60, 0x9C, 0x27, 0xE5, 0x73, 0xAE, 0xEB, 0xE6, 0xF2, 0x32, 0xCA, 0xAC, 0xE0, +0x88, 0x20, 0x97, 0xAB, 0xE3, 0xC2, 0x19, 0xDA, 0x3F, 0x7A, 0x78, 0x20, 0xFC, 0x1E, 0xA1, 0xEE, +0x21, 0xC2, 0xE7, 0xE0, 0xF8, 0xB8, 0x8C, 0x62, 0x9C, 0x45, 0x6D, 0x0E, 0xBD, 0xDA, 0x1C, 0x4E, +0xEA, 0x5B, 0xD1, 0xCD, 0x60, 0x51, 0xDE, 0x9B, 0xC3, 0xDA, 0x7A, 0xD4, 0xE6, 0xD0, 0xAB, 0xCD, +0xE1, 0xA4, 0xBE, 0x15, 0xDD, 0x02, 0x2C, 0x36, 0xB9, 0xDE, 0x50, 0x90, 0x5F, 0xB1, 0x21, 0xFF, +0x3A, 0x1B, 0x65, 0xCC, 0x72, 0xDA, 0x76, 0x71, 0x96, 0xF7, 0x74, 0x30, 0x1E, 0xE3, 0x29, 0x99, +0x59, 0xAD, 0xAD, 0x89, 0xAA, 0xA3, 0xF0, 0x12, 0xCC, 0xAB, 0xCE, 0x1C, 0xE8, 0xE7, 0x5B, 0xFA, +0xF2, 0xB7, 0xDA, 0xBD, 0x8C, 0x24, 0xE4, 0x4A, 0x5C, 0x58, 0x27, 0xE2, 0x06, 0xB6, 0x95, 0x0F, +0x12, 0x77, 0x3F, 0x5D, 0x44, 0x1A, 0x87, 0xF2, 0x7D, 0x97, 0x7D, 0x4A, 0xCD, 0xB0, 0x38, 0xA7, +0x4D, 0x31, 0xEA, 0x6D, 0x8A, 0xD1, 0xC9, 0xC6, 0x4C, 0xEB, 0xCA, 0x39, 0xD5, 0xEC, 0xE3, 0x92, +0xCF, 0x8B, 0x0A, 0x30, 0xA8, 0x59, 0xBE, 0x57, 0xB3, 0xFC, 0x49, 0x5D, 0xFD, 0xBB, 0x29, 0x06, +0x35, 0x7B, 0xB6, 0x0A, 0x3A, 0xD4, 0x2C, 0xDF, 0xAB, 0x59, 0xFE, 0xA4, 0xAE, 0xFE, 0xDD, 0x14, +0x83, 0xED, 0xF7, 0x68, 0x15, 0x3A, 0xA0, 0x9C, 0xCE, 0xA2, 0x4A, 0xDF, 0x93, 0xD7, 0x9F, 0x6D, +0x67, 0x65, 0xAC, 0x00, 0xE7, 0x82, 0xAB, 0x63, 0x49, 0xAE, 0xA9, 0xDE, 0x65, 0xCD, 0x94, 0x81, +0x3F, 0x6E, 0x1A, 0x9A, 0xC6, 0x14, 0xCF, 0x24, 0x0F, 0x9C, 0xE6, 0x36, 0x11, 0x68, 0xA0, 0x25, +0xF8, 0xED, 0xC3, 0xCD, 0xCF, 0xAE, 0x6B, 0xDD, 0xA1, 0x3F, 0x3C, 0xE4, 0xB8, 0xCD, 0xE4, 0xD2, +0x0D, 0x21, 0x6C, 0x9B, 0x86, 0x8D, 0xA0, 0xB6, 0x72, 0xE8, 0x0C, 0x59, 0x9D, 0xD3, 0x27, 0x69, +0xD4, 0xBF, 0xFE, 0x22, 0x51, 0x26, 0x06, 0x28, 0x9E, 0x68, 0x51, 0x56, 0x90, 0x4D, 0xAD, 0x41, +0xBF, 0xDF, 0x07, 0x47, 0xE0, 0xC7, 0x1F, 0x19, 0x4B, 0xCA, 0xCB, 0x73, 0xD8, 0xB5, 0x83, 0x6E, +0x57, 0x0A, 0x23, 0xAA, 0xAA, 0xCA, 0xCC, 0xB8, 0x84, 0x2E, 0x24, 0x52, 0xDF, 0x8F, 0x3F, 0xFE, +0xD2, 0xB6, 0xA0, 0xED, 0x20, 0xC1, 0xDE, 0xB1, 0x4C, 0xC3, 0x41, 0xF7, 0xE8, 0xC9, 0xCD, 0x5A, +0xAE, 0x5D, 0x53, 0x25, 0xF6, 0x62, 0x09, 0x6D, 0xF4, 0x88, 0x6C, 0x87, 0x57, 0x08, 0xDD, 0x5C, +0x35, 0xE4, 0xCF, 0xAC, 0x89, 0xAC, 0xC6, 0x48, 0x10, 0x80, 0x5F, 0x39, 0xC5, 0x29, 0x68, 0xBC, +0x6A, 0x86, 0xEA, 0xB4, 0x13, 0x0C, 0xC0, 0xBF, 0xFE, 0x05, 0x1A, 0x9F, 0x8C, 0x2F, 0x86, 0xB9, +0x34, 0x40, 0xC0, 0x54, 0xA2, 0x15, 0x9E, 0x46, 0x39, 0x2D, 0x23, 0x0B, 0x1D, 0xE0, 0x3B, 0x22, +0xBA, 0x21, 0x5B, 0xB9, 0xCE, 0xB5, 0x68, 0x19, 0x5F, 0x2F, 0x49, 0x98, 0x43, 0xBE, 0x1A, 0x7C, +0xD2, 0x0D, 0x7C, 0xA2, 0xA4, 0x45, 0x31, 0x3D, 0xA8, 0x39, 0x8D, 0xBD, 0x57, 0x0D, 0xED, 0x62, +0xD1, 0x28, 0x3E, 0x12, 0xCA, 0x53, 0x50, 0xC1, 0x96, 0x12, 0x46, 0xA2, 0x88, 0x5C, 0x6C, 0x51, +0x69, 0xA9, 0x5D, 0x02, 0x6B, 0xF9, 0xA9, 0xA6, 0x86, 0xB2, 0x39, 0xD2, 0x3B, 0xD5, 0x78, 0x62, +0x4D, 0xA2, 0xA3, 0x56, 0x8D, 0x1F, 0xB4, 0x3E, 0x9C, 0x0F, 0xB3, 0x59, 0xB2, 0x5B, 0xD5, 0xB8, +0x4E, 0xD8, 0xDE, 0x12, 0x03, 0x39, 0x0E, 0x7F, 0x28, 0x9F, 0x2D, 0x20, 0xA4, 0xA2, 0x52, 0xF6, +0xBB, 0x59, 0xBD, 0x47, 0x2E, 0xA2, 0x92, 0x62, 0x2E, 0x79, 0xB0, 0x4A, 0x83, 0xEB, 0x22, 0x20, +0xA4, 0x98, 0x02, 0xCD, 0x3C, 0x25, 0xF6, 0xC0, 0x2B, 0xD0, 0xF8, 0x41, 0x86, 0x29, 0xA9, 0xC9, +0x0B, 0x88, 0x0D, 0xF7, 0x03, 0xAF, 0xF1, 0x30, 0xCE, 0x47, 0x04, 0x05, 0x04, 0x54, 0x4E, 0x95, +0xF8, 0xAF, 0x90, 0x58, 0xAC, 0x9A, 0x79, 0x22, 0x02, 0x82, 0xCA, 0x22, 0x72, 0xD6, 0x1C, 0xE3, +0xA2, 0x02, 0x42, 0x1D, 0x69, 0xD5, 0xA5, 0xF1, 0xA5, 0x42, 0x32, 0x24, 0xCD, 0x06, 0x48, 0x78, +0xBF, 0x1A, 0x0C, 0x45, 0xF9, 0x87, 0x87, 0x5C, 0xF6, 0x0F, 0x0F, 0x94, 0x7B, 0xF6, 0x5C, 0xBA, +0x08, 0xFB, 0x61, 0x3E, 0xFB, 0x61, 0x55, 0xF6, 0x92, 0x27, 0x05, 0x71, 0x21, 0x31, 0xA2, 0xCA, +0x15, 0x41, 0x39, 0x48, 0x6B, 0x41, 0xDC, 0xAC, 0x56, 0x05, 0xB4, 0xB0, 0xCC, 0xFF, 0xFC, 0x1E, +0xE5, 0x5B, 0xB6, 0xE5, 0x33, 0xB6, 0x32, 0xBF, 0xF3, 0x7B, 0x95, 0xD8, 0x66, 0x3C, 0x89, 0x48, +0xB4, 0x30, 0x9F, 0xA0, 0xB2, 0xAB, 0xE5, 0xC3, 0xD5, 0xB8, 0x24, 0x4E, 0x87, 0x03, 0xBA, 0x9A, +0x02, 0x87, 0x02, 0x44, 0x19, 0xFE, 0x8A, 0x10, 0x54, 0xAB, 0x63, 0xCE, 0x40, 0x56, 0xCB, 0xFE, +0xDD, 0x4A, 0x15, 0x22, 0x74, 0xCB, 0x65, 0x9D, 0x5F, 0xD7, 0xF1, 0xA1, 0xCC, 0x34, 0xD8, 0xF0, +0x50, 0x65, 0x08, 0x53, 0x6D, 0x7E, 0x40, 0x3F, 0xF1, 0xBD, 0x16, 0x45, 0xF9, 0xCB, 0x86, 0x67, +0xF2, 0x05, 0x9C, 0xE2, 0x16, 0x94, 0x5E, 0x0F, 0x2B, 0x6B, 0x82, 0x10, 0x20, 0xB5, 0xA1, 0x12, +0x12, 0x18, 0x53, 0xBA, 0xD1, 0x2C, 0x0F, 0x10, 0x01, 0x11, 0xEF, 0xD1, 0x4B, 0x0F, 0xB1, 0xE4, +0xBB, 0xD2, 0x12, 0x63, 0xAE, 0x24, 0x61, 0xE5, 0x36, 0x1A, 0xDF, 0x44, 0x27, 0x19, 0xE1, 0xC5, +0x68, 0xA8, 0xA8, 0xC3, 0x6A, 0xF1, 0x8D, 0xF4, 0x49, 0xB9, 0xE1, 0x8D, 0xDC, 0xAF, 0x3E, 0x44, +0x11, 0x0C, 0xF8, 0x44, 0x6C, 0x9D, 0x18, 0x31, 0x5D, 0xAB, 0x2A, 0x6C, 0xF1, 0x87, 0xEB, 0x32, +0x56, 0xD2, 0x21, 0x97, 0x4F, 0x50, 0x59, 0x44, 0xC6, 0xB3, 0xAA, 0xB8, 0x88, 0x80, 0xA0, 0xBA, +0xCB, 0x82, 0xE5, 0x50, 0xA9, 0xBB, 0x02, 0x8A, 0xCA, 0x42, 0xC2, 0x15, 0xD2, 0x6C, 0x70, 0x85, +0xF7, 0xAB, 0x75, 0x01, 0xC1, 0x82, 0x60, 0x2E, 0xFB, 0x8A, 0x9D, 0x40, 0xB0, 0x52, 0x96, 0xCB, +0xBC, 0x62, 0x97, 0x1F, 0xAC, 0xF8, 0xE6, 0x31, 0xAF, 0xE9, 0x97, 0x7C, 0xB7, 0xD4, 0xF2, 0x4A, +0xBE, 0x53, 0xEA, 0xF8, 0xA4, 0x97, 0xEF, 0x93, 0x5E, 0x3D, 0x9F, 0xF4, 0x72, 0x7D, 0xD2, 0xAB, +0xE3, 0x93, 0x5E, 0xAE, 0x4F, 0x7A, 0x75, 0x7C, 0x72, 0x92, 0xEF, 0x93, 0x93, 0x7A, 0x3E, 0x39, +0xC9, 0xF5, 0xC9, 0x49, 0x1D, 0x9F, 0x9C, 0xE4, 0xFA, 0xE4, 0xA4, 0x56, 0xDB, 0xE9, 0xAE, 0x69, +0x3C, 0xDD, 0x9A, 0xAD, 0xA7, 0x9B, 0xDF, 0x7C, 0xBA, 0xB5, 0xDA, 0x4F, 0x37, 0xBF, 0x01, 0x75, +0x2B, 0x7A, 0x46, 0xB6, 0x8D, 0x24, 0x2E, 0x83, 0x51, 0x69, 0x3E, 0x55, 0xE5, 0xE0, 0x4E, 0xE7, +0x23, 0xD2, 0x3A, 0x10, 0x37, 0xAB, 0x55, 0x00, 0x2D, 0x2C, 0xF3, 0x3E, 0xBF, 0x57, 0xC9, 0x3B, +0xB4, 0xA8, 0xCC, 0xEF, 0xFC, 0x5E, 0x25, 0xB6, 0x16, 0xF4, 0x1C, 0x24, 0x75, 0x84, 0x7F, 0xB7, +0x9A, 0x27, 0x58, 0x69, 0x99, 0x2B, 0xC4, 0xCD, 0xEA, 0x4A, 0xCB, 0x9C, 0x21, 0x6E, 0x56, 0x9C, +0x3A, 0xD9, 0x8E, 0xAB, 0xC3, 0x15, 0xB2, 0xA5, 0x2E, 0x89, 0x91, 0x54, 0x9D, 0xFB, 0xF9, 0x2C, +0xE4, 0xF3, 0xBF, 0x90, 0xA2, 0xA6, 0x21, 0xF2, 0x79, 0x60, 0x48, 0x51, 0x49, 0x84, 0x61, 0x7E, +0xFD, 0xAA, 0x23, 0x55, 0x37, 0xE5, 0x6B, 0x51, 0x31, 0x92, 0x6A, 0xBE, 0x0A, 0x59, 0xC8, 0x7C, +0x15, 0xA5, 0xA8, 0x69, 0x88, 0xCC, 0x57, 0x51, 0x8A, 0x4A, 0x22, 0xE6, 0x0B, 0x67, 0x8C, 0x6C, +0xBA, 0x63, 0x58, 0xEA, 0xAB, 0x18, 0x49, 0x35, 0x5F, 0x85, 0x2C, 0x64, 0xBE, 0x8A, 0x52, 0xD4, +0x34, 0x44, 0xE6, 0xAB, 0x28, 0x45, 0x55, 0x11, 0x23, 0xC2, 0x48, 0xCF, 0xF3, 0x94, 0x4F, 0x50, +0xD9, 0x4F, 0x8C, 0x41, 0x8E, 0x97, 0xC4, 0xFD, 0x5A, 0x06, 0xE4, 0x78, 0x48, 0xDC, 0xAF, 0xD8, +0xB4, 0x75, 0x48, 0x7F, 0xDD, 0x79, 0x86, 0xE9, 0xC9, 0x57, 0x20, 0x53, 0x64, 0x55, 0x63, 0x55, +0x94, 0x8D, 0x3C, 0x5E, 0xC5, 0xA9, 0x36, 0x60, 0x98, 0x3C, 0x6E, 0xC5, 0xA9, 0xAA, 0x89, 0xB2, +0x4D, 0xC3, 0x1D, 0x9A, 0x8F, 0x79, 0x71, 0x3E, 0x4A, 0x52, 0xD1, 0x77, 0x01, 0x0B, 0xA9, 0xDF, +0x22, 0x14, 0x35, 0x0D, 0x91, 0xFA, 0x2B, 0x42, 0x51, 0x23, 0x3C, 0xDE, 0xA3, 0x85, 0xB5, 0x26, +0xCE, 0x0B, 0x92, 0x3A, 0x71, 0x9E, 0xB2, 0xC8, 0x8F, 0xF3, 0x9C, 0xA2, 0xA6, 0x21, 0xF9, 0x71, +0x9E, 0x53, 0x54, 0x12, 0x31, 0x41, 0x5A, 0xAE, 0xA3, 0xC2, 0xFB, 0x15, 0x9F, 0x11, 0xF2, 0xF2, +0x32, 0x17, 0x05, 0xB7, 0xEB, 0x28, 0x2F, 0x73, 0x4E, 0x70, 0xDB, 0x67, 0x9E, 0xCD, 0x3E, 0xFA, +0x62, 0xAC, 0x44, 0x83, 0xD4, 0xCB, 0x20, 0x39, 0x74, 0xF1, 0x6D, 0xE9, 0x32, 0xC2, 0xC4, 0xDB, +0xA4, 0x6B, 0xC9, 0xC4, 0x8B, 0x5A, 0x05, 0x36, 0x66, 0x64, 0x6D, 0x9E, 0xB0, 0x90, 0xD1, 0x54, +0x7E, 0xBA, 0xBA, 0x57, 0x5E, 0x03, 0xA5, 0x43, 0xBC, 0xC8, 0xB7, 0x65, 0x90, 0x5F, 0x74, 0x35, +0x38, 0x6B, 0xBB, 0x85, 0x83, 0x0C, 0xAD, 0x29, 0x79, 0xA7, 0x79, 0x89, 0x0D, 0xCD, 0x5C, 0xB6, +0x4D, 0x43, 0x37, 0xA1, 0x96, 0xBB, 0x0B, 0xA3, 0xF0, 0x23, 0xDD, 0xC6, 0x5E, 0x1B, 0x6A, 0xDA, +0xD5, 0x23, 0x21, 0xB8, 0xC1, 0x8E, 0x8B, 0x0C, 0x64, 0xD3, 0x77, 0x8E, 0x2D, 0xCF, 0x6D, 0xBC, +0x0E, 0xF9, 0xA3, 0x72, 0x1B, 0xC8, 0xAB, 0x3E, 0x37, 0x46, 0x6D, 0x17, 0xDA, 0x84, 0x99, 0x80, +0x54, 0xD6, 0x73, 0xE2, 0xD4, 0xDB, 0x45, 0xF1, 0xDD, 0x2E, 0x99, 0x37, 0x33, 0x01, 0xB6, 0x0E, +0x58, 0x6B, 0x01, 0xB5, 0x06, 0x48, 0x79, 0x00, 0xFA, 0xC6, 0x5A, 0x44, 0xF8, 0x3B, 0x63, 0x13, +0x0F, 0x4F, 0x82, 0x33, 0x32, 0xED, 0x45, 0xBA, 0x72, 0x11, 0xAD, 0xAD, 0xB6, 0x65, 0xB3, 0x7F, +0x2F, 0xD1, 0x14, 0x7A, 0x3A, 0xDF, 0xBA, 0x53, 0x77, 0xA7, 0x0F, 0x03, 0xEB, 0xED, 0xC7, 0x31, +0x47, 0x2B, 0x57, 0x61, 0x8C, 0x5C, 0xCF, 0xCA, 0xC5, 0xAB, 0x2B, 0x78, 0xFE, 0x8C, 0x20, 0xA9, +0xEB, 0xA6, 0x22, 0xEA, 0xB7, 0x75, 0xBF, 0xB2, 0x10, 0x65, 0x04, 0x2D, 0xFE, 0x28, 0x9B, 0x98, +0xD5, 0x79, 0x6A, 0x2D, 0x97, 0xCB, 0x16, 0xCB, 0x4A, 0xE5, 0xD9, 0x3A, 0x32, 0xE8, 0x46, 0x0D, +0x4D, 0x49, 0xEB, 0xBE, 0xC9, 0x8D, 0x47, 0x19, 0xFB, 0x8E, 0x22, 0xDB, 0x8E, 0xB2, 0x9B, 0x3F, +0xD4, 0x91, 0xED, 0x36, 0x15, 0x62, 0xBC, 0x8B, 0x8D, 0x99, 0x03, 0x1C, 0xF8, 0x88, 0x34, 0x52, +0x29, 0xAA, 0x4A, 0xB0, 0x3A, 0xF5, 0x74, 0x7D, 0xF5, 0x9D, 0x52, 0x30, 0x24, 0xA4, 0x2B, 0x85, +0x9A, 0x2F, 0x76, 0x34, 0xD1, 0x9A, 0x19, 0x89, 0x9F, 0xE1, 0x33, 0x1F, 0xE2, 0x4E, 0x7B, 0x35, +0x46, 0xF4, 0xE5, 0x40, 0x82, 0x2C, 0x85, 0xD2, 0xA7, 0x1F, 0xF4, 0x50, 0x4E, 0x16, 0xB4, 0xC9, +0x00, 0xC7, 0x45, 0x36, 0x31, 0x0A, 0xFC, 0xE3, 0x9F, 0x09, 0x0A, 0x5F, 0x8E, 0xFF, 0xAA, 0x5F, +0x33, 0x70, 0x1E, 0x6B, 0x5F, 0xAF, 0xC1, 0x17, 0xB4, 0xCA, 0x74, 0x63, 0xC8, 0xB6, 0x6D, 0x79, +0xCE, 0xBC, 0xC9, 0xEB, 0xE9, 0xD3, 0xDD, 0xF5, 0xD0, 0x5C, 0x58, 0xA6, 0x41, 0x54, 0x6C, 0xB2, +0xA2, 0xAF, 0x80, 0xD2, 0x57, 0xC8, 0xDF, 0x19, 0xF7, 0x99, 0x84, 0x94, 0xCE, 0xA9, 0xD6, 0x4B, +0x8D, 0x60, 0xE9, 0xF1, 0xFA, 0x51, 0xA1, 0x9F, 0x4D, 0x4C, 0x80, 0xF8, 0xA3, 0x04, 0x17, 0x2C, +0x42, 0xD2, 0x42, 0xE9, 0xDB, 0x36, 0x01, 0xAB, 0x6D, 0xA4, 0x56, 0x79, 0xC2, 0x84, 0x0D, 0x7E, +0x8E, 0x86, 0xB3, 0x8E, 0x48, 0x61, 0x48, 0xBE, 0x52, 0x56, 0x7E, 0x12, 0x07, 0x0D, 0x3F, 0x02, +0x95, 0xBE, 0x4E, 0xD9, 0x57, 0x82, 0xB4, 0x40, 0x4A, 0x24, 0xA7, 0x43, 0x94, 0x20, 0x9E, 0x92, +0x2E, 0x4A, 0xC5, 0x28, 0xF1, 0x62, 0x16, 0xA5, 0x54, 0x80, 0x63, 0xAB, 0x61, 0x46, 0x44, 0x1B, +0x2E, 0xDB, 0x33, 0xEC, 0xCE, 0xBD, 0x89, 0xE7, 0x20, 0x5B, 0xA4, 0x4A, 0x61, 0x69, 0x11, 0x2F, +0x3D, 0x57, 0x9D, 0x5F, 0x92, 0xB6, 0xAD, 0x9B, 0x56, 0xE7, 0xE2, 0xE6, 0xE6, 0xEA, 0x92, 0x36, +0x28, 0xDB, 0xD4, 0x09, 0x24, 0x3B, 0x74, 0x93, 0x4B, 0x87, 0x30, 0xEA, 0x90, 0x66, 0xD4, 0xB9, +0x26, 0xC5, 0x5A, 0xCE, 0x1F, 0x1E, 0x4D, 0xA8, 0x68, 0x19, 0x33, 0x85, 0xA0, 0xD6, 0xED, 0x2B, +0x37, 0x54, 0x58, 0x52, 0x19, 0xC7, 0x82, 0x46, 0x4C, 0x6F, 0x96, 0x49, 0x6C, 0x90, 0x60, 0x4F, +0x1C, 0x44, 0xE8, 0xA2, 0xE6, 0x76, 0x88, 0xBD, 0x12, 0xF3, 0xE3, 0xA9, 0xE5, 0x52, 0x12, 0xE7, +0xFB, 0x84, 0x3B, 0xA0, 0x6F, 0xC0, 0x86, 0xFC, 0x41, 0xD0, 0x9E, 0x6E, 0xE1, 0x0C, 0x91, 0x3A, +0xD8, 0x4F, 0x95, 0x3A, 0x00, 0x58, 0xEB, 0xA7, 0x36, 0xE7, 0x0D, 0x82, 0xCD, 0x78, 0x8F, 0xFE, +0x66, 0xBC, 0xAB, 0x27, 0x0B, 0xDB, 0x98, 0x36, 0x17, 0xA8, 0x83, 0x83, 0xC3, 0xF6, 0x61, 0xFB, +0xE0, 0x88, 0x70, 0x3C, 0x4C, 0x72, 0xB4, 0x06, 0xF7, 0x73, 0xEC, 0x10, 0x74, 0x91, 0xF0, 0x01, +0xE9, 0xF6, 0x78, 0x07, 0xAC, 0x4C, 0x0F, 0xB8, 0x26, 0x10, 0x31, 0xC5, 0x9D, 0x23, 0xF0, 0xE1, +0xEF, 0xF7, 0xF7, 0x60, 0x62, 0x9B, 0x5F, 0x88, 0x8E, 0xD8, 0x98, 0x9A, 0x00, 0x1A, 0x1A, 0xF9, +0x7F, 0x05, 0x68, 0xF2, 0x2B, 0xDA, 0x62, 0x88, 0x0C, 0x47, 0xE8, 0xDE, 0x3E, 0xEB, 0x58, 0x49, +0x21, 0xD4, 0x17, 0x80, 0x80, 0x77, 0x6E, 0x6A, 0x7D, 0x1E, 0x40, 0x01, 0x64, 0x2D, 0xAD, 0x1F, +0x0F, 0xA3, 0x80, 0xF4, 0x34, 0xEC, 0x67, 0x5F, 0x11, 0x50, 0x8D, 0xC6, 0xF9, 0x77, 0x49, 0x27, +0x32, 0xDE, 0x3C, 0x2D, 0x14, 0x91, 0xD0, 0xA7, 0x1B, 0xE8, 0x06, 0xD7, 0xB7, 0xA7, 0x67, 0x1D, +0x76, 0x2D, 0x8B, 0x98, 0x27, 0x56, 0x8A, 0x24, 0x8B, 0xA3, 0xEE, 0xA4, 0xE5, 0x80, 0x41, 0x1A, +0x17, 0xFF, 0xC6, 0x72, 0x1C, 0xF4, 0x95, 0x2B, 0xF6, 0x54, 0x8D, 0x5A, 0x7F, 0x7D, 0x4B, 0xED, +0xB4, 0xE9, 0x16, 0x2D, 0x73, 0x4A, 0xBD, 0x63, 0x47, 0x1D, 0xA2, 0x00, 0xD6, 0x96, 0xFB, 0x8A, +0x32, 0x38, 0x9B, 0xD8, 0x6B, 0x34, 0x64, 0x5B, 0xF2, 0x06, 0xE7, 0x2C, 0x4C, 0x92, 0x8A, 0xD7, +0x50, 0x79, 0x65, 0x19, 0x0B, 0xA1, 0x2E, 0xFF, 0x9E, 0x52, 0x18, 0x72, 0xFE, 0x6C, 0x97, 0x1F, +0x11, 0x5B, 0x4F, 0x65, 0xAC, 0x29, 0x03, 0xBA, 0x0A, 0x41, 0xAA, 0xF8, 0xFA, 0xB2, 0x82, 0x6F, +0xB5, 0xC0, 0xB7, 0x5A, 0x86, 0xAA, 0x8E, 0xCF, 0x39, 0x54, 0x54, 0x43, 0x8F, 0x64, 0x40, 0x50, +0x4A, 0x47, 0xBE, 0x8B, 0x70, 0x40, 0xDF, 0x88, 0x05, 0xC2, 0xB9, 0xB7, 0x34, 0x3D, 0x15, 0xA0, +0x3B, 0x08, 0xCF, 0x79, 0xDD, 0xE5, 0xA9, 0xEE, 0xD2, 0xC7, 0xE7, 0x3C, 0xDF, 0x4D, 0x5F, 0xA1, +0xF9, 0x6E, 0xB2, 0x90, 0xC6, 0x28, 0xEF, 0xEF, 0x24, 0x77, 0x38, 0x1F, 0x4D, 0x30, 0x69, 0x1C, +0x74, 0x7F, 0x68, 0xE4, 0x50, 0xE6, 0x38, 0x8C, 0xDB, 0x22, 0x7C, 0x26, 0x7E, 0xA4, 0xDC, 0x46, +0xED, 0x4A, 0x62, 0xD2, 0xB1, 0x90, 0x4A, 0x1C, 0xA0, 0xC6, 0x3C, 0x10, 0xBA, 0x11, 0x2C, 0xE0, +0x93, 0xCE, 0xF6, 0xAE, 0x12, 0x13, 0xDF, 0x92, 0x70, 0x8B, 0xBF, 0x22, 0xF1, 0x8D, 0xEE, 0xB4, +0xEE, 0x37, 0xFC, 0xD4, 0x52, 0x34, 0x5D, 0x67, 0x9E, 0xEE, 0x67, 0x1D, 0x57, 0x2B, 0xE4, 0x04, +0x85, 0xE6, 0x05, 0x22, 0xD5, 0x67, 0xB1, 0x98, 0x15, 0xDB, 0x7E, 0x3B, 0xA0, 0x41, 0x62, 0x3D, +0xA3, 0x75, 0x1E, 0x8C, 0x84, 0xDB, 0x64, 0xB2, 0x3A, 0x59, 0x0D, 0xC6, 0xCA, 0x73, 0x08, 0xC5, +0x39, 0xF0, 0x14, 0x6C, 0x45, 0x8A, 0x33, 0x16, 0xD1, 0x4A, 0x54, 0x45, 0x8E, 0x00, 0x5E, 0x91, +0xA4, 0x72, 0x54, 0x68, 0x3C, 0xE0, 0x11, 0xFE, 0x05, 0xB9, 0x4B, 0xD3, 0xFE, 0xE2, 0x57, 0x6A, +0xFA, 0x46, 0x51, 0x61, 0xD1, 0x6E, 0x4A, 0xEC, 0x6C, 0x1D, 0xA4, 0x3A, 0x25, 0x69, 0x69, 0x29, +0xFE, 0x93, 0x9F, 0x1F, 0x8D, 0x89, 0x63, 0xBD, 0x8B, 0xFE, 0x1D, 0x93, 0x1C, 0xCD, 0xC7, 0xA7, +0x0C, 0x6E, 0x91, 0xCD, 0xC2, 0x3B, 0x1D, 0xAA, 0xB1, 0x06, 0x68, 0x70, 0xA3, 0x00, 0x35, 0xF2, +0xEC, 0xE2, 0x6E, 0xD0, 0xBC, 0x43, 0xA4, 0x6F, 0x70, 0x68, 0x97, 0xE2, 0x90, 0x8E, 0x8E, 0xF4, +0x29, 0x8E, 0x0B, 0x2E, 0xC6, 0xE3, 0xEB, 0xCB, 0xBD, 0x42, 0xBA, 0x27, 0x3B, 0xD9, 0xF4, 0x7D, +0x29, 0x50, 0xCE, 0x3A, 0x99, 0xED, 0x95, 0x94, 0xA0, 0x0D, 0x7E, 0x5D, 0x10, 0x13, 0x89, 0x36, +0xFD, 0x16, 0x34, 0x26, 0x63, 0x5C, 0xC0, 0x27, 0x52, 0x9E, 0xCD, 0xF7, 0xCE, 0x0D, 0xA8, 0x7D, +0x19, 0x5C, 0xB2, 0xAF, 0x46, 0x02, 0x56, 0x6A, 0x83, 0x32, 0x6B, 0x22, 0xB2, 0x79, 0xE1, 0x20, +0x3A, 0x0F, 0xA4, 0xE1, 0xA9, 0x58, 0x14, 0x6E, 0xB0, 0xBC, 0x5E, 0x8D, 0x4C, 0xD6, 0x0D, 0x8E, +0xC5, 0x8C, 0xEB, 0x0B, 0x6C, 0xF4, 0x1B, 0xDD, 0x06, 0x0D, 0x17, 0xFD, 0x06, 0x11, 0xD6, 0x10, +0xF6, 0xB3, 0xEF, 0xEB, 0x82, 0x27, 0x25, 0x92, 0x06, 0xBE, 0x35, 0xC1, 0xF3, 0xBB, 0x56, 0x8B, +0xB8, 0x97, 0x26, 0x55, 0x06, 0x1F, 0x0D, 0xD4, 0x6A, 0xE5, 0xD1, 0xDE, 0x5F, 0x52, 0xAD, 0xF0, +0x8C, 0xA8, 0xEA, 0x9A, 0x56, 0xC3, 0x97, 0x7E, 0x74, 0xC2, 0x84, 0xCB, 0xD6, 0x53, 0x82, 0xE2, +0xF3, 0x43, 0x3F, 0xE8, 0xD1, 0xB8, 0xDB, 0x62, 0x9C, 0x82, 0x34, 0x95, 0x22, 0xDB, 0x27, 0xCF, +0x85, 0x97, 0xCE, 0x35, 0x67, 0xCF, 0x26, 0xCD, 0xB7, 0x6F, 0x5E, 0x83, 0xFD, 0xB7, 0xC7, 0xAF, +0x41, 0xAF, 0xBB, 0xF7, 0xAE, 0x31, 0x88, 0xE6, 0x31, 0xB1, 0x41, 0x93, 0xCC, 0x68, 0x4D, 0x07, +0x51, 0x23, 0xF6, 0x32, 0x46, 0x5C, 0x29, 0x65, 0x76, 0x3A, 0x88, 0x85, 0xDB, 0xCA, 0x45, 0xF0, +0x8A, 0x5C, 0xE0, 0x22, 0x63, 0x39, 0x55, 0xC8, 0x00, 0x8E, 0x0F, 0x1B, 0x49, 0xEB, 0x41, 0xD1, +0xE4, 0x2D, 0x2E, 0x19, 0x64, 0xEE, 0xBD, 0x4B, 0x2F, 0x2A, 0xBC, 0xE8, 0xD0, 0xF7, 0x81, 0xFA, +0x02, 0x19, 0xD0, 0x50, 0x49, 0x8F, 0x4C, 0x07, 0x5B, 0xCD, 0x73, 0x7D, 0x09, 0x57, 0x0E, 0xA9, +0xFA, 0xCD, 0x84, 0x36, 0x46, 0xB3, 0xD3, 0xF8, 0x08, 0xDF, 0x09, 0x10, 0xF8, 0x88, 0x5C, 0xD8, +0x0C, 0x3E, 0x24, 0x2B, 0x10, 0x29, 0x1D, 0x77, 0x11, 0x20, 0x74, 0x71, 0x9A, 0x6F, 0x6C, 0x1E, +0xAE, 0x54, 0xFD, 0x2F, 0x0B, 0x92, 0xF4, 0x5B, 0x1D, 0xC1, 0x48, 0x28, 0x75, 0xE3, 0x2F, 0x1F, +0x54, 0xEE, 0x7C, 0x9F, 0xB0, 0xC5, 0x01, 0xE6, 0x95, 0xE2, 0x2A, 0x51, 0x18, 0xD0, 0xEE, 0x3E, +0x23, 0x09, 0x4E, 0x85, 0x6A, 0x6C, 0xB0, 0xF2, 0x0D, 0x5E, 0x87, 0xE1, 0xBB, 0x32, 0x7E, 0xE5, +0x45, 0xAE, 0x88, 0x21, 0x92, 0xFF, 0x36, 0x77, 0x41, 0x59, 0xDC, 0x17, 0x0F, 0x0F, 0xC2, 0x27, +0x5C, 0x72, 0xBA, 0x63, 0xF6, 0xFB, 0x65, 0x91, 0x16, 0x97, 0x65, 0x1B, 0xF5, 0x93, 0x93, 0x1E, +0x1D, 0x92, 0xC9, 0x8A, 0xD0, 0xD6, 0xF0, 0x16, 0x13, 0x3A, 0x82, 0x71, 0x5C, 0x64, 0xF5, 0xF7, +0xD9, 0x00, 0xE6, 0xE0, 0xF8, 0x98, 0x0D, 0x68, 0xBA, 0x51, 0x1B, 0x1E, 0x1E, 0x12, 0x26, 0xD0, +0x0B, 0xC2, 0x02, 0x52, 0xA0, 0x9C, 0xF6, 0xC3, 0xE7, 0xD6, 0x7E, 0x98, 0xD4, 0x7E, 0x58, 0x5A, +0xFB, 0x42, 0x11, 0x45, 0xD0, 0xBC, 0xE4, 0xB8, 0x13, 0x7F, 0x83, 0x49, 0x78, 0x2D, 0x71, 0xF1, +0xDF, 0x31, 0xDE, 0x94, 0xC1, 0x6F, 0xC1, 0xA8, 0x74, 0x4F, 0x27, 0x6D, 0x7C, 0xB5, 0x92, 0x3E, +0xED, 0x01, 0xA5, 0x7B, 0x31, 0x66, 0x81, 0x1F, 0x9E, 0x92, 0x49, 0xDD, 0x6A, 0xC6, 0x26, 0xFF, +0xF5, 0x31, 0x51, 0xC3, 0xC1, 0x4F, 0x3F, 0x2A, 0x1D, 0x8E, 0x0E, 0x87, 0xA3, 0x8B, 0x5D, 0x8D, +0x4A, 0xE2, 0x15, 0xB5, 0x88, 0xF2, 0x91, 0x78, 0xB4, 0x5F, 0x36, 0x9A, 0x3E, 0x5F, 0x3C, 0x12, +0xEF, 0xC0, 0x45, 0xF4, 0x1E, 0x96, 0xD6, 0x7B, 0x83, 0x91, 0x88, 0x4F, 0x43, 0x85, 0xBD, 0x22, +0xE1, 0xB8, 0x43, 0x53, 0xE6, 0x1B, 0xB3, 0xD3, 0x6E, 0xA3, 0xC8, 0xFC, 0x34, 0xC6, 0x2E, 0x77, +0xAE, 0x1A, 0xA7, 0x0C, 0xE7, 0xA2, 0x0B, 0xAC, 0x69, 0x7A, 0x61, 0x38, 0xB3, 0xD2, 0x35, 0x03, +0x68, 0x8C, 0x57, 0xFD, 0x60, 0x1A, 0x63, 0x97, 0x33, 0xEA, 0x0F, 0xDE, 0x53, 0xF4, 0x47, 0xFD, +0xE1, 0x85, 0xE7, 0x0C, 0xA8, 0x31, 0x75, 0x6B, 0x05, 0xD7, 0x18, 0xA7, 0xC2, 0x81, 0x36, 0xFA, +0x29, 0x15, 0x4E, 0xC7, 0xC4, 0x64, 0xBE, 0x5A, 0x16, 0x24, 0x14, 0x78, 0xC4, 0x90, 0x06, 0x58, +0xA7, 0xB4, 0xCA, 0x45, 0xDA, 0x50, 0x48, 0x7B, 0x7F, 0x59, 0x01, 0xD7, 0x6C, 0x8D, 0x45, 0x4C, +0xF7, 0x92, 0xA9, 0x27, 0xFD, 0xF5, 0x63, 0xFF, 0xDE, 0x29, 0xCB, 0xD3, 0x51, 0x46, 0xFF, 0xFC, +0x96, 0x5B, 0xB6, 0xF2, 0xEE, 0xEF, 0x7C, 0x56, 0xD1, 0x75, 0x9C, 0x8C, 0x23, 0x03, 0x0E, 0xBB, +0xF4, 0xCF, 0xBB, 0x8C, 0x15, 0xA0, 0xB2, 0x32, 0x7D, 0x77, 0x89, 0x18, 0xF3, 0x96, 0x2D, 0xA0, +0x9F, 0x5D, 0x0C, 0xEE, 0xC6, 0xE3, 0xEB, 0xB3, 0xCE, 0xC5, 0x80, 0x79, 0x9D, 0x10, 0x0C, 0x04, +0x48, 0x40, 0x70, 0x81, 0x10, 0x8D, 0x89, 0x64, 0xA8, 0x07, 0x38, 0x08, 0xE8, 0xCB, 0x62, 0xB6, +0x70, 0xC0, 0x0A, 0x35, 0x0E, 0x3C, 0x95, 0xE1, 0x9D, 0x6E, 0x77, 0x3A, 0xED, 0x76, 0x89, 0x2B, +0xA8, 0x61, 0xF2, 0xC5, 0xB2, 0xC6, 0xA0, 0x75, 0xD8, 0xA5, 0x4B, 0xBB, 0xAD, 0xE3, 0xAE, 0x6F, +0x55, 0x7C, 0xF9, 0x3F, 0x65, 0xF3, 0xD5, 0x93, 0x8A, 0x74, 0x9D, 0x14, 0xE7, 0x57, 0xA8, 0xE2, +0x05, 0x47, 0x2C, 0xC5, 0x34, 0x87, 0x70, 0x3A, 0x85, 0xB0, 0x88, 0xE6, 0xC7, 0xFB, 0x4C, 0xF3, +0x37, 0x5D, 0x79, 0x05, 0xFD, 0x64, 0x9A, 0xDA, 0x96, 0xF4, 0x9C, 0x4E, 0x8B, 0x7A, 0xF8, 0x0D, +0xD7, 0xF3, 0x6D, 0x8E, 0x9E, 0x23, 0x88, 0xED, 0xAD, 0xE9, 0xD9, 0xEB, 0x15, 0xD3, 0xF3, 0x2D, +0xD7, 0xB3, 0x97, 0xA3, 0xE7, 0xAD, 0x69, 0x6E, 0x4F, 0x4F, 0x3A, 0xF7, 0x2C, 0xA0, 0xE7, 0x8F, +0xBA, 0xFB, 0x2E, 0x5F, 0xCB, 0x4F, 0x86, 0x8D, 0x74, 0x4C, 0xC3, 0x52, 0xA8, 0x6B, 0x99, 0x80, +0x2C, 0x7B, 0xBC, 0x90, 0x4D, 0x5D, 0xA8, 0xB1, 0x17, 0xD0, 0x21, 0x94, 0xFB, 0xDC, 0x0B, 0xE0, +0xA2, 0xE7, 0x2E, 0xB2, 0xDA, 0x9D, 0x1B, 0xEC, 0xDF, 0x05, 0xC7, 0x69, 0xED, 0x93, 0x51, 0x69, +0xC1, 0x71, 0x5A, 0xAC, 0x97, 0x2A, 0xD1, 0xB9, 0x05, 0x4F, 0x6A, 0xD7, 0x3C, 0xEF, 0x4C, 0x95, +0x7D, 0x91, 0x43, 0xB6, 0x54, 0xDE, 0x07, 0x31, 0x72, 0x4B, 0x5F, 0x8F, 0x0E, 0xD6, 0xE2, 0x5B, +0xF8, 0x0A, 0x2F, 0xC6, 0xC6, 0x74, 0x7A, 0x49, 0xE3, 0x32, 0x6E, 0x2E, 0x08, 0xDD, 0xB1, 0x43, +0xA3, 0xB1, 0xB2, 0x10, 0xE5, 0x1B, 0x85, 0x92, 0x07, 0x8D, 0x94, 0xF5, 0xB9, 0x64, 0xCA, 0x1D, +0xCD, 0xEA, 0x11, 0x43, 0x92, 0xB8, 0x14, 0x2E, 0x08, 0x8E, 0x46, 0xC5, 0xA7, 0xB0, 0xFE, 0xE7, +0xB9, 0xA7, 0xE0, 0x41, 0x06, 0x91, 0x98, 0x29, 0x91, 0x69, 0x78, 0x45, 0x0B, 0x9E, 0x6F, 0x32, +0x1E, 0x24, 0x2A, 0x89, 0x57, 0x46, 0x45, 0x0B, 0xB6, 0x00, 0xE2, 0x82, 0x7D, 0x68, 0xB9, 0x88, +0x5F, 0x6E, 0xBE, 0x5D, 0xAB, 0x0D, 0x25, 0x8E, 0xC0, 0xA9, 0x3B, 0xE9, 0xA1, 0x1F, 0x9A, 0xC8, +0x04, 0x88, 0x88, 0x03, 0xA7, 0x04, 0x07, 0xA7, 0xBB, 0x10, 0x66, 0xEA, 0x2E, 0x66, 0x64, 0xB8, +0x6C, 0x23, 0xDE, 0x4A, 0x30, 0x8F, 0xA4, 0xA1, 0xAC, 0xD2, 0x51, 0x6E, 0xB6, 0xDF, 0x65, 0x2C, +0xD7, 0xF5, 0xBD, 0x7E, 0x5A, 0x9D, 0x58, 0x0B, 0x0D, 0x2E, 0xFA, 0xBB, 0x46, 0x23, 0x47, 0x18, +0x65, 0x76, 0xC5, 0x2C, 0xFB, 0x8D, 0x58, 0x37, 0x49, 0x6D, 0xA1, 0xAF, 0xD4, 0x41, 0x33, 0xE5, +0x37, 0xD6, 0x49, 0x33, 0x6E, 0x95, 0x3A, 0x6A, 0xFA, 0x49, 0x77, 0xD6, 0xD4, 0x3B, 0xE0, 0xA3, +0x85, 0x8C, 0xCE, 0x50, 0x37, 0x1D, 0x54, 0x76, 0xC4, 0x50, 0xBC, 0x95, 0x04, 0x65, 0xE2, 0x38, +0x8B, 0x26, 0x25, 0xDD, 0x29, 0xA0, 0xF9, 0x6F, 0xF4, 0xE7, 0x02, 0x8E, 0x27, 0x41, 0x4A, 0x22, +0x4E, 0x5C, 0xFD, 0x0F, 0xE4, 0xE8, 0x27, 0x0D, 0x39, 0xE6, 0x9E, 0xCA, 0x83, 0xEF, 0xAD, 0x77, +0xF2, 0x61, 0x0E, 0xAA, 0x58, 0xBD, 0x46, 0x2E, 0x07, 0x6B, 0xF0, 0x55, 0x20, 0x46, 0xC4, 0x79, +0x2E, 0x72, 0xB6, 0xDB, 0xD0, 0xFE, 0x9C, 0x01, 0x46, 0xB1, 0x89, 0xF9, 0x6E, 0x3F, 0xD3, 0x4C, +0x67, 0x07, 0xF3, 0xB7, 0x57, 0xA7, 0x6F, 0x84, 0x6D, 0x39, 0xFA, 0xA2, 0xD7, 0xAE, 0x3D, 0xAD, +0x2C, 0x35, 0x41, 0xBB, 0x0E, 0xAC, 0x04, 0x14, 0xF0, 0x26, 0xF1, 0x52, 0xF3, 0x03, 0x47, 0x6C, +0x89, 0xE7, 0x90, 0xB1, 0x96, 0xCA, 0x5B, 0xE2, 0x11, 0x6D, 0x95, 0xFE, 0xF8, 0x84, 0x65, 0xB1, +0x6E, 0xA4, 0xF7, 0xB2, 0xC7, 0xD3, 0xA4, 0xA5, 0x1C, 0xCF, 0xAF, 0x8A, 0xCD, 0xDA, 0xBF, 0xB0, +0xD6, 0x4C, 0x77, 0x67, 0x63, 0xE2, 0x76, 0xBF, 0x59, 0x01, 0x71, 0x3C, 0x2C, 0x7B, 0xB3, 0x84, +0xAD, 0xF7, 0x03, 0xFA, 0xDA, 0x06, 0x7D, 0xD7, 0x81, 0xC4, 0x72, 0x73, 0x3A, 0x05, 0x61, 0xF3, +0x8D, 0x6D, 0xD9, 0x3E, 0xF6, 0x77, 0x6C, 0xAF, 0x7D, 0xC2, 0xFF, 0xF2, 0xF7, 0x0B, 0x05, 0x69, +0xE2, 0xA2, 0x4F, 0x97, 0xE8, 0xEF, 0x97, 0x8C, 0xDC, 0x4B, 0x6A, 0x04, 0xB5, 0xE2, 0x2F, 0xB2, +0xE9, 0x2B, 0x91, 0x8A, 0x2F, 0x51, 0x95, 0xE2, 0xEA, 0xBF, 0x45, 0x85, 0x82, 0x8F, 0xC6, 0x90, +0xBF, 0x2B, 0xC5, 0xDE, 0x13, 0x2E, 0xF6, 0x04, 0xEF, 0xE5, 0x57, 0x70, 0x98, 0xFE, 0xD0, 0xDF, +0x1A, 0x1C, 0x5C, 0x78, 0xC9, 0xD5, 0xCA, 0xDE, 0x93, 0xBA, 0x31, 0x37, 0xD7, 0x54, 0xD7, 0x8C, +0x5F, 0x72, 0x0A, 0xD2, 0x1D, 0xF1, 0x63, 0x0B, 0xAA, 0xA4, 0x1B, 0xE1, 0x1B, 0xE3, 0x4B, 0x6D, +0x8A, 0xF7, 0x1F, 0x23, 0xAE, 0x11, 0x20, 0xB6, 0xDC, 0xDF, 0x2F, 0xCD, 0x3A, 0x5B, 0xEE, 0x65, +0xC5, 0x58, 0xD1, 0x0D, 0x3F, 0x6D, 0xF0, 0x33, 0x5E, 0x5E, 0x22, 0x32, 0x2D, 0xD4, 0x20, 0x7D, +0x90, 0xF8, 0xC2, 0x77, 0xD9, 0x87, 0x69, 0x3E, 0x45, 0x53, 0x8A, 0x5C, 0x08, 0x07, 0x71, 0xE2, +0xAC, 0xBB, 0x17, 0xDD, 0xBA, 0xFC, 0x63, 0x16, 0x48, 0xD4, 0x74, 0x4D, 0x00, 0xC1, 0xED, 0x3E, +0x10, 0x96, 0xFE, 0x0D, 0x34, 0x7F, 0x31, 0x01, 0x9B, 0xEE, 0xF3, 0x64, 0xA3, 0xAF, 0x01, 0xF9, +0x7D, 0x83, 0x35, 0x68, 0xEF, 0x6D, 0x39, 0x94, 0xB2, 0xE9, 0x7E, 0xF2, 0x6C, 0xA8, 0x3F, 0x1D, +0x14, 0x91, 0xC4, 0xAC, 0x7E, 0xE7, 0x19, 0x5E, 0x79, 0xC9, 0x18, 0x88, 0xD4, 0x31, 0xF0, 0x1C, +0x32, 0xEC, 0xA5, 0xAF, 0x7E, 0xF2, 0xF7, 0x81, 0x1D, 0xD0, 0x24, 0x88, 0x20, 0x40, 0x07, 0x86, +0x09, 0xB8, 0x27, 0x0B, 0x55, 0x7E, 0xF1, 0x97, 0x90, 0x62, 0x65, 0x4B, 0x6D, 0xF2, 0x0A, 0x98, +0xFF, 0xD0, 0x28, 0xB3, 0x43, 0x83, 0x6D, 0xF3, 0x98, 0x1F, 0xD5, 0x8B, 0x80, 0xFB, 0x47, 0x24, +0xFA, 0xF9, 0x7F, 0xD1, 0x18, 0x38, 0xA6, 0xE9, 0x21, 0x1D, 0xA2, 0x93, 0x3B, 0xE7, 0x6D, 0x04, +0x60, 0x83, 0x3A, 0x13, 0x34, 0x31, 0x99, 0x70, 0x18, 0x8E, 0x0B, 0x75, 0x32, 0x05, 0xA4, 0xEF, +0x1F, 0x1D, 0x95, 0x54, 0xB6, 0x8A, 0x9D, 0x9B, 0x9B, 0x7B, 0x4B, 0x1E, 0x37, 0x45, 0xF2, 0x07, +0xFB, 0xDB, 0x78, 0x23, 0x57, 0xCA, 0xED, 0x3E, 0x7F, 0xEE, 0x87, 0x4B, 0x61, 0x6E, 0xE2, 0xB8, +0xEA, 0x65, 0x1E, 0x2F, 0x3D, 0xF7, 0xE3, 0xA4, 0x30, 0xE5, 0x71, 0x5C, 0xE7, 0x32, 0x0F, 0x94, +0xCA, 0xF5, 0x0B, 0x3A, 0x82, 0x74, 0x33, 0x3B, 0x89, 0xF9, 0x34, 0x6F, 0x94, 0x08, 0x51, 0xFC, +0x45, 0xCA, 0x3A, 0x90, 0x49, 0x21, 0x26, 0x05, 0x98, 0xF3, 0xF3, 0xDD, 0x04, 0x4C, 0x12, 0x2F, +0xBB, 0x0F, 0x97, 0x24, 0x5A, 0xB6, 0x06, 0x96, 0x0B, 0xD2, 0x67, 0xDC, 0xD0, 0x0C, 0x20, 0xE1, +0x10, 0xBD, 0x36, 0x52, 0x7A, 0x49, 0xA4, 0xF4, 0x5E, 0x4A, 0x68, 0xE9, 0x25, 0x90, 0xD2, 0xDB, +0x79, 0xA4, 0xF4, 0x12, 0x48, 0xE9, 0x6D, 0x2F, 0xAC, 0x10, 0xF5, 0x27, 0xF4, 0x65, 0x6D, 0x12, +0x59, 0xAE, 0x9E, 0x5C, 0xDB, 0x73, 0xC2, 0x3D, 0x1D, 0xB5, 0x21, 0x73, 0x92, 0x84, 0xCC, 0xC9, +0x4B, 0x81, 0xCC, 0x49, 0x02, 0x32, 0x27, 0x3B, 0x0F, 0x99, 0x93, 0x04, 0x64, 0x4E, 0xB6, 0x06, +0x99, 0xB1, 0x0A, 0xD9, 0x6B, 0x55, 0x80, 0x46, 0x99, 0xB1, 0x67, 0x4F, 0xC9, 0xFC, 0x7B, 0x63, +0xDD, 0x51, 0x37, 0xD5, 0x1F, 0x75, 0x5F, 0x0A, 0x66, 0x58, 0x1E, 0xF4, 0xB8, 0xEA, 0x3B, 0x8F, +0x1A, 0x96, 0x5E, 0x3D, 0xAE, 0xF3, 0xD6, 0x70, 0x33, 0xA2, 0x49, 0xA0, 0xC1, 0x0D, 0xCD, 0x02, +0x0D, 0xAE, 0x0D, 0x9A, 0x8C, 0xC5, 0x4D, 0xC7, 0x9A, 0xE7, 0x5D, 0x28, 0x19, 0xB2, 0xFC, 0x7C, +0xD8, 0x41, 0xE2, 0xAD, 0xAD, 0x17, 0xBF, 0x4E, 0x92, 0x48, 0x6B, 0x2F, 0x6A, 0x36, 0x79, 0x35, +0x5C, 0x31, 0xF1, 0x93, 0x48, 0xA5, 0x72, 0x15, 0xBE, 0xE8, 0xF9, 0xF3, 0x15, 0xB5, 0x17, 0x04, +0x06, 0x6F, 0x76, 0xB9, 0x99, 0xBA, 0x79, 0x18, 0xF1, 0xD5, 0x25, 0x7E, 0x54, 0xD6, 0x06, 0x3D, +0x56, 0x5A, 0x12, 0xF8, 0xFC, 0xD3, 0x01, 0x44, 0x65, 0x05, 0x3F, 0xFD, 0x90, 0x37, 0x1A, 0x9D, +0x1F, 0x17, 0xDB, 0x21, 0xF8, 0xDC, 0x61, 0x4F, 0x9C, 0x3E, 0x10, 0x51, 0xBC, 0xEC, 0x8E, 0xC0, +0xE7, 0x0E, 0x7A, 0xE2, 0x60, 0x83, 0x88, 0xC6, 0x65, 0x77, 0x00, 0x96, 0x02, 0x22, 0x4D, 0x61, +0x04, 0x58, 0xE6, 0x36, 0xD0, 0x01, 0x7E, 0xBF, 0x59, 0x2A, 0xE2, 0xE5, 0x01, 0x27, 0x38, 0x4E, +0xC1, 0x5F, 0x13, 0x0D, 0x7E, 0x47, 0x7B, 0xCB, 0xD1, 0x68, 0x17, 0xA1, 0xE3, 0x1F, 0xD7, 0x10, +0x55, 0x7D, 0xD7, 0xC1, 0xE3, 0x9F, 0x04, 0x11, 0xD5, 0x79, 0xAB, 0xF0, 0xB9, 0x85, 0x6C, 0xC1, +0xEA, 0x27, 0x96, 0xA7, 0x8E, 0x44, 0xB4, 0x4F, 0x0E, 0xB2, 0xF7, 0x4A, 0x0C, 0xB5, 0xF2, 0xC0, +0x13, 0x3F, 0x7D, 0x22, 0xD8, 0x28, 0x13, 0xBB, 0xB8, 0xFB, 0x30, 0x8A, 0x9D, 0x6E, 0x91, 0x32, +0x62, 0xD7, 0x01, 0x15, 0x3B, 0x38, 0x23, 0xA5, 0xFD, 0x56, 0xA1, 0x15, 0x1D, 0x8C, 0xF1, 0xEE, +0xB2, 0xC9, 0xD1, 0x46, 0x97, 0x9A, 0xBD, 0x0D, 0xE2, 0x2C, 0x7E, 0x72, 0x87, 0x30, 0x32, 0x71, +0x71, 0xF7, 0x71, 0x16, 0x3B, 0x19, 0x24, 0x65, 0xC4, 0xAE, 0xE3, 0x2C, 0x76, 0xE8, 0x48, 0x4A, +0xFB, 0xAD, 0xE2, 0x8C, 0xAF, 0x56, 0x82, 0x21, 0x91, 0xB3, 0x2D, 0x84, 0xC5, 0xCF, 0x3B, 0x11, +0xE6, 0x25, 0x2E, 0x86, 0x63, 0xA9, 0xA2, 0xE9, 0x57, 0x9E, 0x1B, 0x61, 0xB1, 0xF3, 0x54, 0x52, +0x46, 0xEC, 0x3A, 0xC2, 0x62, 0x47, 0xB5, 0xA4, 0xB4, 0xDF, 0x2A, 0xC2, 0x7E, 0xFE, 0x30, 0x26, +0x43, 0xAC, 0x47, 0x22, 0xC9, 0x5D, 0xBD, 0x06, 0xE3, 0xAB, 0xBB, 0xEB, 0x8F, 0x9F, 0xC6, 0x9B, +0x83, 0x56, 0x70, 0x3C, 0x4C, 0x68, 0x55, 0x78, 0xE9, 0x45, 0xC0, 0xCA, 0x3F, 0x7E, 0x26, 0x61, +0xC0, 0x0B, 0x80, 0x94, 0x7F, 0xB2, 0x4D, 0x42, 0xF3, 0x67, 0x84, 0xD3, 0xE8, 0xFC, 0xFE, 0xFC, +0x66, 0x63, 0x23, 0xAE, 0xE4, 0x59, 0x3A, 0x41, 0x97, 0x9F, 0xBA, 0xB1, 0xFB, 0xC0, 0x4A, 0x9D, +0xD5, 0x93, 0x69, 0xCC, 0xAE, 0x83, 0x2C, 0x75, 0x0C, 0x50, 0xA6, 0x15, 0x5B, 0x1E, 0x89, 0x71, +0x51, 0x80, 0xCB, 0xDA, 0x14, 0xD8, 0x62, 0x87, 0x0E, 0xF9, 0x56, 0xC5, 0x2F, 0xBE, 0x00, 0x90, +0x45, 0x0F, 0x35, 0x4A, 0x19, 0xB1, 0xF3, 0xE0, 0x8A, 0x9E, 0x97, 0x94, 0xD2, 0x7E, 0xBB, 0xA0, +0xA2, 0x62, 0x00, 0x93, 0x03, 0xEE, 0xD0, 0x82, 0xFC, 0xAB, 0x6D, 0x74, 0x3C, 0xEF, 0x1F, 0x3C, +0x14, 0x1B, 0x4C, 0x06, 0x17, 0x77, 0x1F, 0x58, 0xB1, 0x13, 0xA0, 0x52, 0x46, 0xEC, 0x3A, 0xB0, +0x62, 0x87, 0x4B, 0xA5, 0xB4, 0x7F, 0x8E, 0xF1, 0x3C, 0x95, 0x03, 0x46, 0x10, 0xEB, 0x1B, 0x42, +0x55, 0xE4, 0x2C, 0x2B, 0x61, 0x4F, 0xF4, 0xCA, 0xEE, 0xE3, 0x29, 0x3C, 0x2B, 0x2B, 0xAE, 0xFE, +0xAE, 0x23, 0x29, 0x3C, 0x86, 0x2B, 0xAE, 0xF7, 0x56, 0x31, 0x44, 0x9F, 0x1B, 0x66, 0x03, 0x28, +0x17, 0x3A, 0xD5, 0x77, 0x11, 0xFF, 0x09, 0x59, 0xCE, 0xCF, 0x3A, 0x34, 0xE7, 0x7B, 0xF2, 0xE2, +0x77, 0xAD, 0xD6, 0xD9, 0xC4, 0x73, 0x5D, 0xD3, 0x10, 0xBC, 0xF9, 0x0F, 0xF6, 0x44, 0x46, 0xC7, +0xEA, 0x17, 0xBA, 0x24, 0xCD, 0x4E, 0xE8, 0xD2, 0x4D, 0x9E, 0x5D, 0xA1, 0x3D, 0xB7, 0xD1, 0xB4, +0xDF, 0xE8, 0xF0, 0xD7, 0x93, 0x1A, 0xEF, 0x94, 0xC1, 0x27, 0xF6, 0x0D, 0x44, 0xCF, 0x5C, 0xE1, +0x4C, 0x06, 0xB1, 0xDD, 0xC9, 0x51, 0x6F, 0xF9, 0xDF, 0x09, 0x25, 0x3F, 0xA9, 0x86, 0x1D, 0x5F, +0xE3, 0x2E, 0xF4, 0xC1, 0xFF, 0x03, 0x40, 0x4A, 0xFD, 0x4D, 0xA3, 0xB7, 0x00, 0x00 }; \ No newline at end of file diff --git a/src/www/setuppage.html b/src/www/setuppage.html index 8e43723..7923fac 100644 --- a/src/www/setuppage.html +++ b/src/www/setuppage.html @@ -142,63 +142,229 @@ x.style.display = 'none'; } } - function showTestOptions() { - var x = document.getElementById("LEDTestSettings"); + + function setFinishColor() { + if (document.getElementById('finishIndication').checked) { + document.getElementById("finishcolorchoice").style.display = 'block'; + document.getElementById("finishendchoice").style.display = 'block'; + document.getElementById("finishendchoicetitle").style.display = 'block'; + + } else { + document.getElementById("finishcolorchoice").style.display = 'none'; + document.getElementById("finishendchoice").style.display = 'none'; + document.getElementById("finishendchoicetitle").style.display = 'none'; + } + } + function setFinishExit(id){ + var myCheckbox = document.getElementsByClassName("finishOption"); + if(id.checked){ + Array.prototype.forEach.call(myCheckbox,function(el){ + el.checked = false; + }); + id.checked = true; + } else{ + Array.prototype.forEach.call(myCheckbox,function(el){ + el.checked = true; + }); + id.checked = false; + } + + } + function setFinishChoice() { + if (document.getElementById('finishEndDoor').checked) { + document.getElementById("finishdooroption").style.display = 'block'; + document.getElementById("finishtimeroption").style.display = 'none'; + + } else { + document.getElementById("finishtimeroption").style.display = 'block'; + document.getElementById("finishdooroption").style.display = 'none'; + } + } + //LED Behavious + function selectOnlyOne(id){ + var myCheckbox = document.getElementsByClassName("LEDBehavior") + Array.prototype.forEach.call(myCheckbox,function(el){ + el.checked = false; + }); + id.checked = true; + } + function showhideOptions() { + if (document.getElementById('showtestcolor').checked) { + document.getElementById("testcolorchoice").style.display = 'block'; + } else { + document.getElementById("testcolorchoice").style.display = 'none'; + } + if (document.getElementById('debugwifi').checked) { + document.getElementById("displayWifiStrength").style.display = 'block'; + } else { + document.getElementById("displayWifiStrength").style.display = 'none'; + } if (document.getElementById('replicateLedState').checked) { - x.style.display = 'none'; - document.getElementById('debugwifi').checked = false; + document.getElementById("runningcolorchoice").style.display = 'block'; } else { - x.style.display = 'block'; + document.getElementById("runningcolorchoice").style.display = 'none'; } + } - function showAdvanced() { - var x = document.getElementById("AdvancedDiv"); - if (document.getElementById('advancedSettings').checked) { - x.style.display = 'block'; + //Error colors + function showcustomColors() { + if (document.getElementById('errorDetection').checked) { + document.getElementById("CustomColorsDiv").style.display = 'block'; } else { - x.style.display = 'none'; + document.getElementById("CustomColorsDiv").style.display = 'none'; } } + function hasP1(){ + if (document.getElementById('p1Printer').checked) { + document.getElementById("doorSwitch").checked = false; + document.getElementById("AllowDoorSwitch").style.display = 'none'; + + document.getElementById("stage14WW").value = 255; + document.getElementById("stage1WW").value = 255; + document.getElementById("stage8WW").value = 255; + document.getElementById("stage9WW").value = 255; + document.getElementById("stage10WW").value = 255; + + document.getElementById("stage14CW").value = 255; + document.getElementById("stage1CW").value = 255; + document.getElementById("stage8CW").value = 255; + document.getElementById("stage9CW").value = 255; + document.getElementById("stage10CW").value = 255; + if (document.getElementById('finishIndication').checked) { + if (document.getElementById('finishEndDoor').checked) { + document.getElementById('finishEndDoor').checked = false; + document.getElementById('finishEndTimer').checked = true; + document.getElementById("finishdooroption").style.display = 'none'; + document.getElementById("finishtimeroption").style.display = 'block'; + } + } + } else { + document.getElementById("doorSwitch").checked = true; + document.getElementById("AllowDoorSwitch").style.display = 'block'; + + document.getElementById("stage14RGB").value = '#000000'; + document.getElementById("stage1RGB").value = '#000000'; + document.getElementById("stage8RGB").value = '#000000'; + document.getElementById("stage9RGB").value = '#000000'; + document.getElementById("stage10RGB").value = '#000000'; + + document.getElementById("stage14WW").value = 0; + document.getElementById("stage1WW").value = 0; + document.getElementById("stage8WW").value = 0; + document.getElementById("stage9WW").value = 0; + document.getElementById("stage10WW").value = 0; + + document.getElementById("stage14CW").value = 0; + document.getElementById("stage1CW").value = 0; + document.getElementById("stage8CW").value = 0; + document.getElementById("stage9CW").value = 0; + document.getElementById("stage10CW").value = 0; + + if (document.getElementById('finishIndication').checked) { + document.getElementById('finishEndDoor').checked = true; + document.getElementById('finishEndTimer').checked = false; + document.getElementById("finishdooroption").style.display = 'block'; + document.getElementById("finishtimeroption").style.display = 'none'; + } + } + } function updateConfig() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { var configData = JSON.parse(xhr.responseText); + document.getElementById("firmwareversion").textContent = "Firmware Version: "+(configData.firmwareversion || "Unknown version"); + if(configData.wifiStrength != ""){ + document.getElementById("wifiStrength").textContent = "Connection Strength: "+(configData.wifiStrength || "")+"dBm"; + } document.getElementById('ip').value = configData.ip || ''; document.getElementById('code').value = configData.code || ''; document.getElementById('id').value = configData.id || ''; + document.getElementById('apMAC').value = configData.apMAC || ''; + document.getElementById('brightnessslider').value = configData.brightness || 100; + document.getElementById("brightnesssliderDisplay").textContent = "Brightness: "+ (configData.brightness || 100) + "%"; + document.getElementById('maintMode').checked = configData.maintMode || false; + document.getElementById('discoMode').checked = configData.discoMode || false; document.getElementById('replicateLedState').checked = configData.replicateled || false; - document.getElementById('errorDetection').checked = configData.errordetection || false; + document.getElementById('runningRGB').value = configData.runningRGB || ''; + document.getElementById('runningWW').value = configData.runningWW || 255; + document.getElementById('runningCW').value = configData.runningCW || 255; + document.getElementById('showtestcolor').checked = configData.showtestcolor || false; + document.getElementById('testRGB').value = configData.testRGB || ''; + document.getElementById('testWW').value = configData.testWW || 0; + document.getElementById('testCW').value = configData.testCW || 0; + document.getElementById('debugwifi').checked = configData.debugwifi || false; document.getElementById('finishIndication').checked = configData.finishindication || false; + document.getElementById('finishColor').value = configData.finishColor || ''; + document.getElementById('finishWW').value = configData.finishWW || 0; + document.getElementById('finishCW').value = configData.finishCW || 0; + if(configData.finishExit){ + document.getElementById('finishEndDoor').checked = true; + setFinishExit(document.getElementById('finishEndDoor')); + } else { + document.getElementById('finishEndTimer').checked = true; + setFinishExit(document.getElementById('finishEndTimer')); + } + document.getElementById('finishTimerMins').value = configData.finishTimerMins || 10; + document.getElementById('inactivityEnabled').checked = configData.inactivityEnabled || false; + document.getElementById('inactivityMins').value = configData.inactivityMins || 30; document.getElementById('debuging').checked = configData.debuging || false; document.getElementById('debugingchange').checked = configData.debugingchange || false; document.getElementById('mqttdebug').checked = configData.mqttdebug || false; - document.getElementById('lidarLightsOff').checked = configData.lidarLightsOff || false; - document.getElementById('inactivityEnabled').checked = configData.inactivityEnabled || false; - document.getElementById('inactivityMins').value = configData.inactivityMins || '30'; - document.getElementById('maintMode').checked = configData.maintMode || false; - document.getElementById('discoMode').checked = configData.discoMode || false; - document.getElementById('testRGB').value = configData.testRGB || ''; - document.getElementById('cw_slider').value = configData.testcoldwhite || 100; - document.getElementById('ww_slider').value = configData.testwarmwhite || 100; - document.getElementById('debugwifi').checked = configData.debugwifi || false; - document.getElementById('apMAC').value = configData.apMAC || ''; - document.getElementById('brightnessslider').value = configData.brightness || 100; - document.getElementById("brightnesssliderDisplay").textContent = "Brightness: "+ (configData.brightness || 100) + "%"; - document.getElementById("firmwareversion").textContent = "Firmware Version:"+(configData.firmwareversion || "Unknown version"); + document.getElementById('p1Printer').checked = configData.p1Printer || false; + document.getElementById('doorSwitch').checked = configData.doorSwitch || false; + document.getElementById('stage14RGB').value = configData.stage14RGB || ''; + document.getElementById('stage14WW').value = configData.stage14WW || 0; + document.getElementById('stage14CW').value = configData.stage14CW || 0; + document.getElementById('stage1RGB').value = configData.stage1RGB || ''; + document.getElementById('stage1WW').value = configData.stage1WW || 0; + document.getElementById('stage1CW').value = configData.stage1CW || 0; + document.getElementById('stage8RGB').value = configData.stage8RGB || ''; + document.getElementById('stage8WW').value = configData.stage8WW || 0; + document.getElementById('stage8CW').value = configData.stage8CW || 0; + document.getElementById('stage9RGB').value = configData.stage9RGB || ''; + document.getElementById('stage9WW').value = configData.stage9WW || 0; + document.getElementById('stage9CW').value = configData.stage9CW || 0; + document.getElementById('stage10RGB').value = configData.stage10RGB || ''; + document.getElementById('stage10WW').value = configData.stage10WW || 0; + document.getElementById('stage10CW').value = configData.stage10CW || 0; + document.getElementById('errorDetection').checked = configData.errordetection || false; document.getElementById('wifiRGB').value = configData.wifiRGB || ''; - document.getElementById('finishRGB').value = configData.finishRGB || ''; + document.getElementById('wifiWW').value = configData.wifiWW || 0; + document.getElementById('wifiCW').value = configData.wifiCW || 0; document.getElementById('pauseRGB').value = configData.pauseRGB || ''; + document.getElementById('pauseWW').value = configData.pauseWW || 0; + document.getElementById('pauseCW').value = configData.pauseCW || 0; document.getElementById('firstlayerRGB').value = configData.firstlayerRGB || ''; + document.getElementById('firstlayerWW').value = configData.firstlayerWW || 0; + document.getElementById('firstlayerCW').value = configData.firstlayerCW || 0; document.getElementById('nozzleclogRGB').value = configData.nozzleclogRGB || ''; + document.getElementById('nozzleclogWW').value = configData.nozzleclogWW || 0; + document.getElementById('nozzleclogCW').value = configData.nozzleclogCW || 0; document.getElementById('hmsSeriousRGB').value = configData.hmsSeriousRGB || ''; + document.getElementById('hmsSeriousWW').value = configData.hmsSeriousWW || 0; + document.getElementById('hmsSeriousCW').value = configData.hmsSeriousCW || 0; document.getElementById('hmsFatalRGB').value = configData.hmsFatalRGB || ''; + document.getElementById('hmsFatalWW').value = configData.hmsFatalWW || 0; + document.getElementById('hmsFatalCW').value = configData.hmsFatalCW || 0; document.getElementById('filamentRunoutRGB').value = configData.filamentRunoutRGB || ''; + document.getElementById('filamentRunoutWW').value = configData.filamentRunoutWW || 0; + document.getElementById('filamentRunoutCW').value = configData.filamentRunoutCW || 0; document.getElementById('frontCoverRGB').value = configData.frontCoverRGB || ''; + document.getElementById('frontCoverWW').value = configData.frontCoverWW || 0; + document.getElementById('frontCoverCW').value = configData.frontCoverCW || 0; document.getElementById('nozzleTempRGB').value = configData.nozzleTempRGB || ''; + document.getElementById('nozzleTempWW').value = configData.nozzleTempWW || 0; + document.getElementById('nozzleTempCW').value = configData.nozzleTempCW || 0; document.getElementById('bedTempRGB').value = configData.bedTempRGB || ''; - showTestOptions(); + document.getElementById('bedTempWW').value = configData.bedTempWW || 0; + document.getElementById('bedTempCW').value = configData.bedTempCW || 0; + updateIdle(); + showhideOptions(); + showcustomColors(); + setFinishColor(); + setFinishChoice(); } }; xhr.open('GET', '/getConfig', true); @@ -209,8 +375,11 @@ document.getElementById("brightnesssliderDisplay").textContent = "Brightness: "+ e.target.value + "%"; }); updateConfig(); - showTestOptions(); updateIdle(); + showhideOptions(); + showcustomColors(); + setFinishColor(); + setFinishChoice(); }; @@ -251,7 +420,7 @@

BL LED Controller Settings Page

-

Firmware version: Expirimental 15.3.24

+

Firmware version: Expirimental 26.3.24

This page allows you to change the MQTT broker info and any additional settings.

@@ -263,11 +432,11 @@

Firmware version: Expirimental 15.3.24

- - - +
- + +   +

- + \ No newline at end of file diff --git a/src/www/wifiSetup.html b/src/www/wifiSetup.html index 7824d16..c80bd15 100644 --- a/src/www/wifiSetup.html +++ b/src/www/wifiSetup.html @@ -4,12 +4,8 @@