Compare commits

...

56 Commits

Author SHA1 Message Date
Aircoookie
830223f6e2 Merge pull request #83 from Aircoookie/development
Fixed incorrect #defines for 0.8.2
2018-12-06 00:43:32 +01:00
cschwinne
eb53c52499 Fixed incorrect #defines for 0.8.2 2018-12-06 00:40:59 +01:00
Aircoookie
96c9e2b4d6 Merge pull request #82 from Aircoookie/development
Updated readme
2018-12-06 00:31:39 +01:00
cschwinne
c34b948bad Updated readme 2018-12-06 00:30:38 +01:00
Aircoookie
9ac609f846 Release of v0.8.2 (merge)
Release of v0.8.2 (PR)
2018-12-06 00:30:05 +01:00
cschwinne
6aa47bfd1b Release of v0.8.2
Improved settings page scaling on mobile devices
Added 2 new effects to web UIs
2018-12-06 00:27:36 +01:00
cschwinne
ff46e6ea86 Added Auto Brightness Limiter and power calculation 2018-12-04 00:58:06 +01:00
cschwinne
5489c74986 Added Smooth meteor and Railway effects 2018-12-02 02:49:05 +01:00
cschwinne
f6f8151150 Added meteor FX to web UI 2018-11-29 21:46:05 +01:00
cschwinne
a20d577f6c WS2812b Color Order changeable in settings
Meteor effect can now use palettes
2018-11-28 12:24:32 +01:00
cschwinne
c4c2494dd1 Improved binary size 2018-11-25 00:00:02 +01:00
cschwinne
c9c294a1d5 Merge branch 'development' of https://github.com/Aircoookie/WLED.git into development 2018-11-24 11:52:44 +01:00
cschwinne
6359a8a8a2 Improved effect updating internals 2018-11-24 11:52:23 +01:00
Aircoookie
f9b44381bd Merge pull request #77 from viknet365/master
add meteor effect
2018-11-23 00:21:07 +01:00
Aircoookie
eb1ccb600b Delete htmls00.h
0.8.2 will use the new gzip system with different files. HTML changes will be manually added
2018-11-23 00:20:26 +01:00
cschwinne
b2db61aa03 Merge branch 'development' of https://github.com/Aircoookie/WLED.git into development 2018-11-23 00:16:25 +01:00
cschwinne
ee55a574de Moved About section to Github wiki
Updated readme
2018-11-23 00:11:47 +01:00
cschwinne
0998fd32cd Moved About section to Github wiki 2018-11-23 00:03:44 +01:00
cschwinne
686f2c4aa6 IR codes will now also be printed without debug enabled 2018-11-22 22:43:44 +01:00
cschwinne
cd234673ea Fixed nightlight issues
Added custom infrared method
2018-11-22 00:09:30 +01:00
cschwinne
54d7a81f16 Incomplete commit for Nightlight Fixes
Interim state (Reason: Local Working Copy Data Corruption)
Affected files: (local changes will be re-implemented in next commit)
settings_sync.html (already recovered)
html_settings.h (already recovered)
wled03_set.ino
wled08_led.ino
wled09_button.ino
wled19_ir.ino
2018-11-21 23:28:20 +01:00
viknet365
9d8d2c0aa1 add meteor effect
This reverts commit f1371d6737.
2018-11-20 21:31:07 +01:00
viknet365
17ce6b9507 Revert "Add files via upload"
This reverts commit f1371d6737.
2018-11-20 21:09:06 +01:00
viknet365
296065a976 Revert "add meteor effect"
This reverts commit 0b0f600f97.
2018-11-20 20:59:13 +01:00
viknet365
0b0f600f97 add meteor effect 2018-11-20 20:42:47 +01:00
viknet365
f1371d6737 Add files via upload
add meteor effect
2018-11-20 20:35:04 +01:00
viknet365
03a33790e1 Update WS2812FX.cpp 2018-11-20 20:32:21 +01:00
cschwinne
c0816c80ae Infrared support added 2018-11-18 00:31:45 +01:00
cschwinne
071ebe6ef2 Gzipped UIs, improving speed and flash usage 2018-11-16 19:59:00 +01:00
Aircoookie
2126e42743 Merge pull request #74 from wiesendaniel/feature/pio-port
Added Plattform IO Support
2018-11-16 19:50:19 +01:00
Daniel Wiesendorf
8a2b34adb4 moved ws2812fx sources back 2018-11-16 15:02:09 +01:00
Daniel Wiesendorf
93eb4d21bf Added PIO recommendation when opening in vscode 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
868cedeed2 pio support for esp01 512k 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
5c794f428a added verbose flag to travisci.yml for debugging 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
612d6f85bd Pio support of esp32 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
e5cef6b877 fixed DEBUG constant for travis build 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
f2a63c04a8 fixed travisci build again... 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
5a5064e070 fixed travisci build 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
478fa3132c Minor fixes for PIO support 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
a84859c211 Changed platformio.ini. A few boards are building now 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
67013bd58f Changed platformio.ini. A few boards are building now 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
b51be31d8a added initial PlatformIO config. still needs work 2018-11-14 22:07:04 +01:00
Aircoookie
a3bef49124 Refactored code to improve readability (merge dev PR)
Refactored code to improve readability
Fixed non-2-char indentations
2018-11-09 17:02:58 +01:00
cschwinne
a5cf553f17 Refactored code to improve readability
Fixed non-2-char indentations
2018-11-09 17:00:36 +01:00
Aircoookie
640188f4e2 Merge pull request #68 from Aircoookie/development
Release of v0.8.0
2018-11-07 20:23:01 +01:00
cschwinne
48265bbe02 Release of WLED 0.8.1
Added Lake effect
2018-11-07 20:22:05 +01:00
cschwinne
6aaf544079 Auto-select pixel driving method based on LEDPIN 2018-11-05 02:24:13 +01:00
cschwinne
9904c10984 Added Colortwinkle effect 74 2018-11-04 20:14:23 +01:00
cschwinne
81c810eba4 Increased max. UDP leds from 341 to 490
MQTT now publishes state on connect
2018-11-01 16:16:38 +01:00
cschwinne
5e6b1e8175 Added defines for more granular feature disable control 2018-11-01 15:36:13 +01:00
cschwinne
48c165b0b4 Added support for E1.31 with more than 170 LEDs 2018-11-01 01:05:35 +01:00
cschwinne
042605701e Added DNRGB UDP protocol 2018-10-27 11:39:00 +02:00
cschwinne
32cf1495d3 Fixed tricolor chase modes
Added a new palette
2018-10-25 20:55:29 +02:00
cschwinne
9577e49231 Added Palette support for most effects
Fixed Analog Clock bugs
Added Tiamat palette
2018-10-24 02:06:07 +02:00
cschwinne
de19839145 Fixed overlay not unlocking on disable 2018-10-18 18:31:25 +02:00
cschwinne
f970780d6c Fixed Clock overlay not working in reverse mode
Removed need for Macros to start with capital letter
2018-10-18 18:06:46 +02:00
46 changed files with 4810 additions and 1799 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.pio
.pioenvs
.piolibdeps
.vscode
!.vscode/extensions.json

35
.travis.yml Normal file
View File

@@ -0,0 +1,35 @@
# Continuous Integration (CI) is the practice, in software
# engineering, of merging all developer working copies with a shared mainline
# several times a day < https://docs.platformio.org/page/ci/index.html >
#
# Documentation:
#
# * Travis CI Embedded Builds with PlatformIO
# < https://docs.travis-ci.com/user/integration/platformio/ >
#
# * PlatformIO integration with Travis CI
# < https://docs.platformio.org/page/ci/travis.html >
#
# * User Guide for `platformio ci` command
# < https://docs.platformio.org/page/userguide/cmd_ci.html >
#
#
# Please choose one of the following templates (proposed below) and uncomment
# it (remove "# " before each line) or use own configuration according to the
# Travis CI documentation (see above).
#
language: python
python:
- "2.7"
sudo: false
cache:
directories:
- "~/.platformio"
env:
- PLATFORMIO_CI_SRC=wled00
install:
- pip install -U platformio
- platformio update
script:
- platformio ci --project-conf=./platformio.ini -v

7
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

39
include/README Normal file
View File

@@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README Normal file
View File

@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

121
platformio.ini Normal file
View File

@@ -0,0 +1,121 @@
; PlatformIO Project Configuration File
; Please visit documentation: https://docs.platformio.org/page/projectconf.html
[platformio]
src_dir = ./wled00
data_dir = ./wled00/data
lib_extra_dirs = ./wled00/src
; env_default = nodemcuv2
env_default = esp01
; env_default = esp01_1m
; env_default = d1_mini
; env_default = esp32dev
[common]
framework = arduino
monitor_speed = 115200
board_build.flash_mode = dout
upload_speed = 921600
build_flags =
; -D VERSION=0.8.2-dev
; -D DEBUG
# TODO replace libs in /lib with managed libs in here if possible.
# If they are not changed it's just a metter of setting the correfct version and change the import statement
lib_deps_external =
#Blynk@0.5.4
#E131@1.0.0
#webserver
FastLED@3.2.1
NeoPixelBus@2.3.4
#PubSubClient@2.7
#Time@1.5
#Timezone@1.2.1
#WS2812FX@1.1.2
[common:esp8266]
platform = espressif8266@1.8.0
build_flags =
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
[common:esp8266_512k]
platform = espressif8266@1.7.0
build_flags =
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH
; -D WLED_DISABLE_MOBILE_UI
-D WLED_DISABLE_OTA
-D WLED_DISABLE_ALEXA
; -D WLED_DISABLE_BLYNK
; -D WLED_DISABLE_CRONIXIE
-D WLED_DISABLE_HUESYNC
[common:esp32]
platform = espressif32@1.5.0
build_flags =
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
-D ARDUINO_ARCH_ESP32
-D WORKAROUND_ESP32_BITBANG
# see: http://docs.platformio.org/en/latest/platforms/espressif8266.html
[env:nodemcuv2]
board = nodemcuv2
platform = ${common:esp8266.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266.build_flags}
lib_deps =
${common.lib_deps_external}
[env:d1_mini]
board = d1_mini
platform = ${common:esp8266.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266.build_flags}
lib_deps =
${common.lib_deps_external}
[env:esp01_1m]
board = esp01_1m
platform = ${common:esp8266.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266.build_flags}
lib_deps =
${common.lib_deps_external}
[env:esp01]
board = esp01
platform = ${common:esp8266_512k.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266_512k.build_flags}
lib_deps =
${common.lib_deps_external}
# see: http://docs.platformio.org/en/latest/platforms/espressif32.html
[env:esp32dev]
board = esp32dev
platform = ${common:esp32.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp32.build_flags}
lib_deps =
${common.lib_deps_external}

View File

@@ -1,11 +1,11 @@
![WLED logo](https://raw.githubusercontent.com/Aircoookie/WLED/development/wled_logo.png)
![WLED logo](https://raw.githubusercontent.com/Aircoookie/WLED/master/wled_logo.png)
## Welcome to my project WLED! (v0.8.0)
## Welcome to my project WLED! (v0.8.2)
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B) LEDs!
### Features:
- WS2812FX library integrated for over 70 special effects
- WS2812FX library integrated for 75 special effects
- FastLED noise effects and palettes
- Customizable Mobile and desktop UI with color and effect controls
- Settings page - configuration over network
@@ -16,6 +16,7 @@ A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control
- Nightlight function (gradually dims down)
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
- Configurable analog clock + support for the Cronixie kit by Diamex
- Configurable Auto Brightness limit for safer operation
### Supported light control interfaces:
- HTTP request API
@@ -28,6 +29,7 @@ A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control
- Sync to Philips hue lights
- Adalight (PC ambilight via serial)
- Sync color of multiple WLED devices (UDP notifier)
- Infrared remotes (24-key RGB, receiver required)
- Simple timers/schedules (time from NTP, timezones/DST supported)
### Quick start guide and documentation:
@@ -37,13 +39,13 @@ See the [wiki](https://github.com/Aircoookie/WLED/wiki)!
### Other
Licensed under the MIT license
Credits in About page!
Credits [here](https://github.com/Aircoookie/WLED/wiki/Contributors-&-About)!
Uses Linearicons by Perxis!
Join the Discord [server](https://discord.gg/KuqP7NE) to discuss everything about WLED!
You can also send me mails to [dev.aircoookie@gmail.com](mailto:dev.aircoookie@gmail.com).
If you insist that you just love WLED too much, you can [send me a gift](https://paypal.me/aircoookie)!
If WLED really brightens up your every day, you can [send me a small gift](https://paypal.me/aircoookie)!

11
test/README Normal file
View File

@@ -0,0 +1,11 @@
This directory is intended for PIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html

View File

@@ -2,35 +2,42 @@
#ifndef NpbWrapper_h
#define NpbWrapper_h
//#define WORKAROUND_ESP32_BITBANG
#define WORKAROUND_ESP32_BITBANG
//see https://github.com/Aircoookie/WLED/issues/2 for flicker free ESP32 support
#define LEDPIN 2 //strip pin. Only effective for ESP32, ESP8266 must use gpio2
//PIN CONFIGURATION
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 is recommended for ESP8266
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
#define IR_PIN 4 //infrared pin.
#define AUXPIN 15 //unused auxiliary output pin
//uncomment this if red and green are swapped
//#define SWAPRG
//automatically uses the right driver method for each platform
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
#define PIXELMETHOD NeoEsp32BitBangWs2813Method
#else
#define PIXELMETHOD NeoEsp32RmtWS2813_V3Method
#endif
#ifdef WORKAROUND_ESP32_BITBANG
#define PIXELMETHOD NeoEsp32BitBangWs2813Method
#pragma message "Software BitBang is used because of your NeoPixelBus version. Look in NpbWrapper.h for instructions on how to mitigate flickering."
#else
#define PIXELMETHOD NeoEsp32RmtWS2813_V3Method
#endif
#else //esp8266
//you may change to DMA method on pin GPIO3 here
#define PIXELMETHOD NeoEsp8266Uart800KbpsMethod
//#define PIXELMETHOD NeoEsp8266Dma800KbpsMethod
//autoselect the right method depending on strip pin
#if LEDPIN == 2
#define PIXELMETHOD NeoEsp8266Uart800KbpsMethod
#elif LEDPIN == 3
#define PIXELMETHOD NeoEsp8266Dma800KbpsMethod
#else
#define PIXELMETHOD NeoEsp8266BitBang800KbpsMethod
#pragma message "Software BitBang will be used because of your selected LED pin. This may cause flicker. Use GPIO 2 or 3 for best results."
#endif
#endif
//handle swapping Red and Green automatically
#ifdef SWAPRG
#define PIXELFEATURE3 NeoRgbFeature
#define PIXELFEATURE4 NeoRgbwFeature
#else
//you can now change the color order in the web settings
#define PIXELFEATURE3 NeoGrbFeature
#define PIXELFEATURE4 NeoGrbwFeature
#endif
#include <NeoPixelBrightnessBus.h>
@@ -46,10 +53,10 @@ class NeoPixelWrapper
{
public:
NeoPixelWrapper() :
// initialize each member to null
_pGrb(NULL),
_pGrbw(NULL),
_type(NeoPixelType_None)
// initialize each member to null
_pGrb(NULL),
_pGrbw(NULL),
_type(NeoPixelType_None)
{
}
@@ -64,8 +71,8 @@ public:
cleanup();
_type = type;
switch (_type) {
switch (_type)
{
case NeoPixelType_Grb:
_pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, LEDPIN);
_pGrb->Begin();
@@ -81,23 +88,25 @@ public:
void Show()
{
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
delay(1);
portDISABLE_INTERRUPTS(); //this is a workaround to prevent flickering (see https://github.com/adafruit/Adafruit_NeoPixel/issues/139)
#endif
#ifdef WORKAROUND_ESP32_BITBANG
delay(1);
portDISABLE_INTERRUPTS(); //this is a workaround to prevent flickering (see https://github.com/adafruit/Adafruit_NeoPixel/issues/139)
#endif
#endif
switch (_type) {
switch (_type)
{
case NeoPixelType_Grb: _pGrb->Show(); break;
case NeoPixelType_Grbw: _pGrbw->Show(); break;
}
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
portENABLE_INTERRUPTS();
#endif
#ifdef WORKAROUND_ESP32_BITBANG
portENABLE_INTERRUPTS();
#endif
#endif
}
bool CanShow() const
{
switch (_type) {
@@ -106,65 +115,65 @@ public:
}
}
void SetPixelColor(uint16_t indexPixel, RgbColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, color); break;
case NeoPixelType_Grbw:_pGrbw->SetPixelColor(indexPixel, color); break;
}
void SetPixelColor(uint16_t indexPixel, RgbColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, color); break;
case NeoPixelType_Grbw:_pGrbw->SetPixelColor(indexPixel, color); break;
}
}
void SetPixelColor(uint16_t indexPixel, RgbwColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); break;
case NeoPixelType_Grbw: _pGrbw->SetPixelColor(indexPixel, color); break;
}
void SetPixelColor(uint16_t indexPixel, RgbwColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); break;
case NeoPixelType_Grbw: _pGrbw->SetPixelColor(indexPixel, color); break;
}
}
void SetBrightness(byte b)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetBrightness(b); break;
case NeoPixelType_Grbw:_pGrbw->SetBrightness(b); break;
}
void SetBrightness(byte b)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetBrightness(b); break;
case NeoPixelType_Grbw:_pGrbw->SetBrightness(b); break;
}
}
RgbColor GetPixelColor(uint16_t indexPixel) const
{
switch (_type) {
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
case NeoPixelType_Grbw: /*doesn't support it so we don't return it*/ break;
}
return 0;
RgbColor GetPixelColor(uint16_t indexPixel) const
{
switch (_type) {
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
case NeoPixelType_Grbw: /*doesn't support it so we don't return it*/ break;
}
return 0;
}
// NOTE: Due to feature differences, some support RGBW but the method name
// here needs to be unique, thus GetPixeColorRgbw
RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const
{
switch (_type) {
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
case NeoPixelType_Grbw: return _pGrbw->GetPixelColor(indexPixel); break;
}
return 0;
// NOTE: Due to feature differences, some support RGBW but the method name
// here needs to be unique, thus GetPixeColorRgbw
RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const
{
switch (_type) {
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
case NeoPixelType_Grbw: return _pGrbw->GetPixelColor(indexPixel); break;
}
return 0;
}
void ClearTo(RgbColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->ClearTo(color); break;
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
}
void ClearTo(RgbColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->ClearTo(color); break;
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
}
}
void ClearTo(RgbwColor color)
{
switch (_type) {
case NeoPixelType_Grb: break;
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
}
void ClearTo(RgbwColor color)
{
switch (_type) {
case NeoPixelType_Grb: break;
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
}
}
private:
NeoPixelType _type;

File diff suppressed because it is too large Load Diff

View File

@@ -41,9 +41,12 @@
#include "NpbWrapper.h"
#define DEFAULT_BRIGHTNESS (uint8_t)50
#define FASTLED_INTERNAL //remove annoying pragma messages
#include "FastLED.h"
#define DEFAULT_BRIGHTNESS (uint8_t)127
#define DEFAULT_MODE (uint8_t)0
#define DEFAULT_SPEED (uint16_t)1000
#define DEFAULT_SPEED (uint8_t)128
#define DEFAULT_COLOR (uint32_t)0xFF0000
#define min(a,b) ((a)<(b)?(a):(b))
@@ -82,7 +85,7 @@
#define REVERSE (uint8_t)0x80
#define IS_REVERSE ((SEGMENT.options & REVERSE) == REVERSE)
#define MODE_COUNT 74
#define MODE_COUNT 79
#define FX_MODE_STATIC 0
#define FX_MODE_BLINK 1
@@ -159,6 +162,12 @@
#define FX_MODE_NOISE16_2 71
#define FX_MODE_NOISE16_3 72
#define FX_MODE_NOISE16_4 73
#define FX_MODE_COLORTWINKLE 74
#define FX_MODE_LAKE 75
#define FX_MODE_METEOR 76
#define FX_MODE_METEOR_SMOOTH 77
#define FX_MODE_RAILWAY 78
class WS2812FX {
typedef uint16_t (WS2812FX::*mode_ptr)(void);
@@ -261,6 +270,12 @@ class WS2812FX {
_mode[FX_MODE_NOISE16_2] = &WS2812FX::mode_noise16_2;
_mode[FX_MODE_NOISE16_3] = &WS2812FX::mode_noise16_3;
_mode[FX_MODE_NOISE16_4] = &WS2812FX::mode_noise16_4;
_mode[FX_MODE_COLORTWINKLE] = &WS2812FX::mode_colortwinkle;
_mode[FX_MODE_LAKE] = &WS2812FX::mode_lake;
_mode[FX_MODE_METEOR] = &WS2812FX::mode_meteor;
_mode[FX_MODE_METEOR_SMOOTH] = &WS2812FX::mode_meteor_smooth;
_mode[FX_MODE_RAILWAY] = &WS2812FX::mode_railway;
_brightness = DEFAULT_BRIGHTNESS;
_running = false;
@@ -271,8 +286,11 @@ class WS2812FX {
_segments[0].speed = DEFAULT_SPEED;
_reverseMode = false;
_skipFirstMode = false;
colorOrder = 0;
paletteFade = 0;
paletteBlend = 0;
ablMilliampsMax = 750;
currentMilliamps = 0;
_locked = NULL;
_cronixieDigits = new byte[6];
bus = new NeoPixelWrapper();
@@ -316,9 +334,13 @@ class WS2812FX {
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
show(void);
bool
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p);
uint8_t
paletteFade,
paletteBlend,
colorOrder,
getBrightness(void),
getMode(void),
getSpeed(void),
@@ -327,14 +349,11 @@ class WS2812FX {
uint32_t
color_wheel(uint8_t),
color_from_palette(uint16_t, bool, bool, uint8_t, uint8_t pbri = 255),
color_blend(uint32_t,uint32_t,uint8_t),
getPixelColor(uint16_t),
getColor(void);
double
getPowerEstimate(uint16_t leds, uint32_t c, byte b),
getSafePowerMultiplier(double safeMilliAmps, uint16_t leds, uint32_t c, byte b);
WS2812FX::Segment
getSegment(void);
@@ -346,12 +365,15 @@ class WS2812FX {
// mode helper functions
uint16_t
blink(uint32_t, uint32_t, bool strobe),
color_wipe(uint32_t, uint32_t, bool),
theater_chase(uint32_t, uint32_t),
ablMilliampsMax,
currentMilliamps,
blink(uint32_t, uint32_t, bool strobe, bool),
color_wipe(uint32_t, uint32_t, bool , bool),
scan(bool),
theater_chase(uint32_t, uint32_t, bool),
twinkle(uint32_t),
twinkle_fade(uint32_t),
chase(uint32_t, uint32_t, uint32_t),
chase(uint32_t, uint32_t, uint32_t, uint8_t),
running(uint32_t, uint32_t),
fireworks(uint32_t),
tricolor_chase(uint32_t, uint32_t, uint32_t);
@@ -432,19 +454,24 @@ class WS2812FX {
mode_noise16_2(void),
mode_noise16_3(void),
mode_noise16_4(void),
mode_colortwinkle(void),
mode_lake(void),
mode_meteor(void),
mode_meteor_smooth(void),
mode_railway(void),
mode_lightning(void);
private:
NeoPixelWrapper *bus;
CRGB fastled_from_col(uint32_t);
uint16_t _length;
uint16_t _rand16seed;
uint8_t _brightness;
void handle_palette(void);
double
_cronixieSecMultiplier;
bool modeUsesLock(uint8_t);
boolean
_running,
@@ -466,9 +493,9 @@ class WS2812FX {
uint8_t _segment_index = 0;
uint8_t _segment_index_palette_last = 99;
uint8_t _num_segments = 1;
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 20 bytes per element
// start, stop, speed, intensity, mode, options, color[]
{ 0, 7, DEFAULT_SPEED, 128, FX_MODE_STATIC, NO_OPTIONS, {DEFAULT_COLOR}}
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 21 bytes per element
// start, stop, speed, intensity, palette, mode, options, color[]
{ 0, 7, DEFAULT_SPEED, 128, 0, FX_MODE_STATIC, NO_OPTIONS, {DEFAULT_COLOR}}
};
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 17 bytes per element
};

View File

@@ -2,7 +2,7 @@
<html>
<head><meta charset="utf-8"><meta name="theme-color" content="#fff">
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico'/>
<title>WLED 0.8.0</title>
<title>WLED 0.8.2</title>
<script>
var d=document;
var w=window.getComputedStyle(d.querySelector("html"));
@@ -26,14 +26,17 @@
{
return d.getElementById(s);
}
function Startup()
function UCol()
{
var w=window.getComputedStyle(d.querySelector("html"));
aC = w.getPropertyValue("--aCol");
bC = w.getPropertyValue("--bCol");
dC = w.getPropertyValue("--dCol");
d.querySelector("meta[name=theme-color]").setAttribute("content",bC);
}
function Startup()
{
var w=window.getComputedStyle(d.querySelector("html"));
UCol();
CV(0);
setInterval('GIO()', 5000);
GIO();
@@ -63,10 +66,18 @@
d.Cf.IX.value = this.responseXML.getElementsByTagName('ix')[0].childNodes[0].nodeValue;
nla = (this.responseXML.getElementsByTagName('nl')[0].innerHTML)!=0?true:false;
if(firstload){
d.Cf.NC.checked = (this.responseXML.getElementsByTagName('nf')[0].innerHTML)!=0?true:false;
d.Cf.SN.value = this.responseXML.getElementsByTagName('nd')[0].childNodes[0].nodeValue;
d.Cf.ST.value = this.responseXML.getElementsByTagName('nt')[0].childNodes[0].nodeValue;
CV(parseInt(this.responseXML.getElementsByTagName('md')[0].childNodes[0].nodeValue));
d.Cf.NC.checked = (this.responseXML.getElementsByTagName('nf')[0].innerHTML)!=0?true:false;
d.Cf.SN.value = this.responseXML.getElementsByTagName('nd')[0].childNodes[0].nodeValue;
d.Cf.ST.value = this.responseXML.getElementsByTagName('nt')[0].childNodes[0].nodeValue;
d.documentElement.style.setProperty("--aCol",this.responseXML.getElementsByTagName('ca')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--bCol",this.responseXML.getElementsByTagName('cb')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--cCol",this.responseXML.getElementsByTagName('cc')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--dCol",this.responseXML.getElementsByTagName('cd')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--sCol",this.responseXML.getElementsByTagName('cs')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--tCol",this.responseXML.getElementsByTagName('ct')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--cFn",this.responseXML.getElementsByTagName('cf')[0].childNodes[0].nodeValue);
UCol();
CV(parseInt(this.responseXML.getElementsByTagName('md')[0].childNodes[0].nodeValue));
}firstload=false;
nState = 0;
nState = (this.responseXML.getElementsByTagName('nr')[0].innerHTML)!=0?1:0;
@@ -77,6 +88,7 @@
}
}
}
if (firstload) resp+="&IT"
request.open("GET", "win" +resp +nocache, true);
request.send(null);
resp="";
@@ -172,7 +184,7 @@
case 3: gId("path1").style.fill = aC; gId("path2").style.fill = aC;
}
tgb.style.fill=(Cf.SA.value>0)?aC:dC;
fpX.style.display=(Cf.TX.selectedIndex>64)?"block":"none";
fpX.style.display=(Cf.TX.selectedIndex>0)?"block":"none";
fof.style.fill=(Cf.TX.selectedIndex>64)?aC:dC;
fmr.style.fill=(Cf.TX.selectedIndex<1)?aC:dC;
}
@@ -192,10 +204,10 @@
function SwFX(s)
{
var n=Cf.TX.selectedIndex+s;
if (n==-1||n==74) return;
if (n==-1||n==79) return;
Cf.TX.selectedIndex =n;
if (n < 0) Cf.TX.selectedIndex = 0;
if (n > 73) Cf.TX.selectedIndex = 65;
if (n > 78) Cf.TX.selectedIndex = 65;
GX();
}
function TgHSB()
@@ -302,7 +314,6 @@
rr=diffc(r);
gg=diffc(g);
bb=diffc(b);
if(r===v) {
h=bb-gg;
}else if (g===v){
@@ -660,6 +671,11 @@
<option value="71">Noise 16 2 (71)</option>
<option value="72">Noise 16 3 (72)</option>
<option value="73">Noise 16 4 (73)</option>
<option value="74">Colortwinkle (74)</option>
<option value="75">Lake (75)</option>
<option value="76">Meteor (76)</option>
<option value="77">Smooth Meteor (77)</option>
<option value="78">Railway (78)</option>
</select><br><br>
Set secondary color to
<button type="button" onclick="CS(0)">White</button>
@@ -716,6 +732,8 @@
<option value="42">Yelmag</option>
<option value="43">Yelblu</option>
<option value="44">Orange & Teal</option>
<option value="43">Tiamat</option>
<option value="44">April Night</option>
</select>
</div>
<div id="slX" class="sl">
@@ -730,14 +748,14 @@
<svg id="psn" onclick="SwitchPS(1)"><use xlink:href="#lnr-arrow-right-circle"></use></svg>
<svg id="pss" onclick="PSIO(true)"><use xlink:href="#lnr-arrow-down-circle"></use></svg>
<br><input id="psI" name = "FF" type="number" value="1" min="1" max="25" step="1"><br><br>
Click checkmark to apply <input type="checkbox" checked="true" name="BC"> brightness, <input type="checkbox" checked="true" name="CC"> color and <input type="checkbox" checked="true" name="FC"> effects.<br><br>
Click checkmark to apply <input type="checkbox" checked name="CC"> color, <input type="checkbox" checked name="FC"> effects and <input type="checkbox" name="BC"> brightness.<br><br>
Cycle through presets <input id="cy1" name="P1" type="number" value="1" min="1" max="25" step="1"> to <input id="cy2" name="P2" type="number" value="5" min="1" max="25" step="1">, keep each for <input id="cyT" name="PT" type="number" value="1250" min="50" max="65501" step="1">ms: <input type="checkbox" name="CY" onclick="uCY()"><br><br>
<button type="button" onclick="R()">Apply boot config</button><br>
</div>
<div id="tlN" class="tools">
Timed Light<br><br>
<svg id="ntb" onclick="TgNl()"><use xlink:href="#lnr-power-switch"></use></svg><br><br>
Gradually dim down <input type="checkbox" checked="true" name="NC"><br>
Gradually dim down <input type="checkbox" checked name="NC"><br>
1st slider sets duration (1-255min), 2nd sets target brightness.
<div id="slN" class="sl">
<input type="range" title="Duration" class="sds" name="SN" value="60" min="1" max="255" step="1"></div>

View File

@@ -7,7 +7,7 @@
<meta name="theme-color" content="#333333">
<meta content="yes" name="apple-mobile-web-app-capable">
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAGACGAAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAE1JREFUOI1j/P//PwOxgNGeAUMxE9G6cQCKDWAhpADZ2f8PMjBS3QW08QK20KaZC2gfC9hCnqouoNgARgY7zMxAyNlUdQHlXiAlO2MDAD63EVqNHAe0AAAAAElFTkSuQmCC"/>
<title>WLED 0.8.0</title>
<title>WLED 0.8.2</title>
<style>
*{transition-duration: 0.5s;}
body {
@@ -432,7 +432,12 @@
<li onclick="X(70)">Noise 16 1</li>
<li onclick="X(71)">Noise 16 2</li>
<li onclick="X(72)">Noise 16 3</li>
<li onclick="X(73)">Noise 16 4</li>&nbsp;
<li onclick="X(73)">Noise 16 4</li>
<li onclick="X(74)">Colortwinkle</li>
<li onclick="X(75)">Lake</li>
<li onclick="X(76)">Meteor</li>
<li onclick="X(77)">Smooth Meteor</li>
<li onclick="X(78)">Railway</li>&nbsp;
<li><a href="#">Go to top</a></li>&nbsp;
<p style="margin-left:-37px">FastLED Palette (Effects 56-73)</p>
<li onclick="P(0)">Default</li>
@@ -480,6 +485,8 @@
<li onclick="P(42)">Yelmag</li>
<li onclick="P(43)">Yelblu</li>
<li onclick="P(44)">Orange & Teal</li>
<li onclick="P(45)">Tiamat</li>
<li onclick="P(46)">April Night</li>
&nbsp;
<li><a href="#">Go to top</a></li></div>
<iframe id="stf" onload="feedback();" style="display:none;"></iframe>

View File

@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html><head>
<meta content='width=device-width' name='viewport'>
<title>WLED Message</title>
<script>
function B() {

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta content='width=device-width' name='viewport'>
<title>WLED Setup</title>
<style>
:root {
@@ -14,9 +15,7 @@
font-family: Verdana, Helvetica, sans-serif;
text-align: center;
background: linear-gradient(var(--bCol),black);
height: 100%;
margin: 0;
background-repeat: no-repeat;
background-attachment: fixed;
color: var(--dCol);
}

711
wled00/html_classic.h Normal file
View File

@@ -0,0 +1,711 @@
/*
* Binary arrays for the classic desktop UI index page.
* gzip is used for smaller size and improved speeds.
*
* Workflow for creating them from HTML source:
* 1. Minify HTML (https://htmlcompressor.com/compressor/) (optional)
* 2. Compress with gzip (https://online-converting.com/archives/convert-to-gzip/)
* 3. Convert gzip binary to c array (https://sourceforge.net/projects/bin2header/)
* alternative: https://littlevgl.com/image-to-c-array (raw)
* 4. update length value
*/
const uint16_t PAGE_index0_L = 11122;
const char PAGE_index0[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x08, 0x8d, 0x45, 0x08, 0x5c, 0x00, 0x03, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65,
0x73, 0x73, 0x65, 0x64, 0x20, 0x28, 0x31, 0x30, 0x29, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x00, 0xcc,
0x5a, 0x09, 0x6f, 0xdb, 0xc6, 0xb6, 0xfe, 0x2b, 0xac, 0x82, 0xb6, 0x52, 0x2d, 0xd2, 0xe4, 0x70,
0x97, 0x4c, 0x17, 0x89, 0xdb, 0x2c, 0x40, 0xe2, 0x1a, 0xb1, 0x6f, 0x9b, 0xa2, 0x28, 0x02, 0x8a,
0xa4, 0x2c, 0xc6, 0x14, 0xa9, 0x4b, 0x52, 0x5e, 0xea, 0xfa, 0xbf, 0xbf, 0xef, 0xcc, 0x0c, 0x25,
0x52, 0xde, 0xa4, 0xdc, 0xbe, 0xfb, 0x5e, 0x80, 0x50, 0x9a, 0x39, 0x33, 0x73, 0x96, 0xef, 0x6c,
0x43, 0xf9, 0xe0, 0x9b, 0x9f, 0x7e, 0x39, 0x3a, 0xfb, 0xfd, 0xe4, 0x67, 0x65, 0x56, 0xcf, 0xb3,
0xc3, 0x03, 0xf9, 0x4c, 0xc2, 0xf8, 0xf0, 0x60, 0x9e, 0xd4, 0xa1, 0x12, 0xcd, 0xc2, 0xb2, 0x4a,
0xea, 0x60, 0x59, 0x4f, 0x55, 0x4f, 0xce, 0xe5, 0xe1, 0x3c, 0x09, 0xea, 0x59, 0x32, 0x4f, 0xd4,
0xa8, 0xc8, 0x8a, 0x52, 0x89, 0x8a, 0xbc, 0x4e, 0xf2, 0x3a, 0x78, 0x31, 0x9d, 0x4e, 0x0f, 0x0f,
0xb2, 0x34, 0xbf, 0x50, 0xca, 0x24, 0x0b, 0xbe, 0xaf, 0x66, 0x45, 0x59, 0x47, 0xcb, 0x5a, 0x49,
0xb1, 0xe2, 0x7b, 0xa5, 0xbe, 0x59, 0x24, 0x41, 0x3a, 0x0f, 0xcf, 0x93, 0xfd, 0x6b, 0x95, 0xa6,
0x94, 0x59, 0x99, 0x4c, 0x83, 0xef, 0xf7, 0xa7, 0xe1, 0x25, 0x0d, 0x35, 0x3c, 0xbe, 0xdf, 0x3f,
0x3c, 0xa8, 0xd3, 0x3a, 0x4b, 0x0e, 0x7f, 0x7b, 0xff, 0xf3, 0x4f, 0x8a, 0xae, 0x79, 0x1a, 0x3b,
0xd8, 0x17, 0x33, 0xca, 0x41, 0x15, 0x95, 0xe9, 0xa2, 0x3e, 0xbc, 0x0c, 0x4b, 0x25, 0x0e, 0xe2,
0x22, 0x5a, 0xce, 0xc1, 0x76, 0x4c, 0xc3, 0xab, 0xe0, 0x2a, 0xcd, 0xe3, 0xe2, 0x4a, 0x3b, 0x4f,
0xea, 0xa3, 0x62, 0xbe, 0x58, 0xd6, 0x49, 0x7c, 0x5a, 0xdf, 0x64, 0x49, 0x3f, 0xd6, 0xfe, 0xbd,
0x4c, 0xca, 0x9b, 0xd3, 0x24, 0x4b, 0xa2, 0xba, 0x28, 0xfb, 0x3d, 0xd2, 0xb1, 0x37, 0x18, 0x8c,
0xcb, 0xa4, 0x5a, 0x04, 0xbd, 0x1e, 0xdf, 0x9e, 0x67, 0x61, 0x30, 0x0d, 0xb3, 0x2a, 0x11, 0xa3,
0xb2, 0x33, 0xaa, 0xda, 0xa3, 0xaa, 0x2e, 0x5a, 0xa3, 0xe5, 0xd5, 0x65, 0x9b, 0x36, 0x99, 0x06,
0x75, 0xb9, 0x14, 0x83, 0x69, 0x5a, 0x56, 0x75, 0x56, 0x84, 0xf1, 0x7a, 0x2a, 0x0b, 0xab, 0xba,
0xba, 0x0e, 0x74, 0x71, 0xec, 0x69, 0x1d, 0xd6, 0x89, 0x1c, 0x44, 0x97, 0xf2, 0x4b, 0x36, 0xc7,
0x97, 0xf0, 0x88, 0xe4, 0x9a, 0xf0, 0x67, 0xcc, 0x9f, 0xd3, 0x65, 0x1e, 0xd5, 0x29, 0x2c, 0x76,
0xfe, 0x2e, 0xee, 0x87, 0x83, 0xdb, 0x32, 0xa9, 0x97, 0x65, 0xae, 0xc4, 0xa4, 0xee, 0xcf, 0x59,
0x42, 0x66, 0x78, 0x75, 0xc3, 0x49, 0x77, 0xab, 0xa5, 0xff, 0x3a, 0x2a, 0xb2, 0xfe, 0xe0, 0x16,
0x87, 0x71, 0xab, 0x9c, 0x94, 0xc5, 0x22, 0x29, 0xeb, 0x9b, 0x5f, 0xc3, 0x6c, 0x99, 0xf4, 0x7b,
0xaa, 0x1a, 0x82, 0xde, 0x1b, 0x10, 0x9b, 0x87, 0xe9, 0x13, 0x41, 0x8f, 0x1f, 0xa3, 0xc7, 0x92,
0xbe, 0x69, 0x5f, 0xf2, 0x91, 0x3f, 0x36, 0x7d, 0xe4, 0xcf, 0xde, 0x40, 0x83, 0x1f, 0xbd, 0xac,
0xeb, 0x32, 0x9d, 0x00, 0x9c, 0x7e, 0x4f, 0x3a, 0x4d, 0x6f, 0x38, 0x39, 0x6a, 0x09, 0x0d, 0xa3,
0x94, 0xf5, 0x72, 0x01, 0xb9, 0xc9, 0x1a, 0xe1, 0xee, 0xa8, 0x0a, 0xad, 0xc7, 0x47, 0xbf, 0xf6,
0xf5, 0xc1, 0x18, 0x1c, 0xdf, 0x81, 0x4b, 0x79, 0x19, 0x66, 0xfd, 0xde, 0x9b, 0x77, 0xbf, 0xf4,
0x07, 0xbd, 0xa1, 0xad, 0xeb, 0xa0, 0xf0, 0xc1, 0x9a, 0x2d, 0x1f, 0xde, 0xe6, 0x45, 0x14, 0x46,
0xb3, 0x24, 0xe8, 0x7d, 0xb7, 0xfa, 0xb6, 0xf7, 0x21, 0xac, 0x67, 0x5a, 0x19, 0x42, 0x8a, 0x79,
0x7f, 0xf0, 0x83, 0xa1, 0xf3, 0x7f, 0x63, 0x21, 0x5c, 0x9e, 0x5c, 0x29, 0x9f, 0x3e, 0xbc, 0x7f,
0x5b, 0xd7, 0x8b, 0x8f, 0x09, 0xe4, 0xa9, 0x6a, 0x70, 0x0e, 0xb5, 0x22, 0x2f, 0x11, 0x40, 0x37,
0x15, 0xe1, 0x8b, 0xf8, 0xc9, 0xcf, 0x93, 0xa0, 0x61, 0x04, 0x26, 0xe9, 0xb4, 0x5f, 0xcf, 0xd2,
0x4a, 0xe3, 0x6b, 0x84, 0x0f, 0x04, 0xd6, 0x7a, 0x9a, 0x76, 0x2d, 0xab, 0x20, 0x60, 0x90, 0xb2,
0xb5, 0xb6, 0x5a, 0x14, 0x79, 0x95, 0x80, 0xd9, 0x37, 0x41, 0xbe, 0xcc, 0xb2, 0xc1, 0x6d, 0xac,
0x1d, 0x4d, 0xb5, 0xd3, 0x97, 0xda, 0x25, 0xc1, 0x11, 0x6c, 0xae, 0x6a, 0xf9, 0x45, 0xf5, 0xea,
0xe6, 0x2c, 0x3c, 0x3f, 0x06, 0x1e, 0xfd, 0x5e, 0x18, 0xf5, 0x06, 0x7f, 0xe8, 0x7f, 0x6a, 0xd1,
0x2c, 0xcd, 0xe2, 0xe3, 0x22, 0x4e, 0x2a, 0x1a, 0xe5, 0xf8, 0xc2, 0x51, 0x1d, 0x8b, 0x43, 0x3f,
0xee, 0x76, 0x68, 0x94, 0x6d, 0x73, 0xe8, 0x9b, 0xaf, 0x38, 0xd4, 0x78, 0xee, 0xd0, 0x57, 0x5f,
0x71, 0x28, 0x7b, 0xfc, 0xd0, 0x07, 0xcc, 0xfd, 0xc8, 0x49, 0x57, 0x97, 0x4f, 0xea, 0x7c, 0x18,
0xe8, 0x0d, 0x42, 0xbf, 0xed, 0x26, 0xe2, 0x33, 0x07, 0x8f, 0x29, 0xe1, 0x50, 0x3e, 0xb9, 0x4b,
0x90, 0x74, 0x6e, 0x57, 0xe9, 0xe7, 0x0e, 0xac, 0xce, 0x3e, 0x21, 0xc2, 0x28, 0x1c, 0x92, 0xf8,
0x5d, 0x1e, 0x27, 0xd7, 0xdb, 0xb2, 0x9c, 0x5e, 0x3f, 0xcd, 0x12, 0x47, 0xbf, 0x3e, 0xf9, 0xca,
0xa3, 0x17, 0xdb, 0xb8, 0xc6, 0xa7, 0xdd, 0x4c, 0x54, 0x3d, 0x23, 0x2f, 0x3f, 0xf4, 0xdd, 0x8e,
0x87, 0xa6, 0xcf, 0x1c, 0x4a, 0x05, 0x62, 0x5b, 0xe7, 0xc8, 0x65, 0x40, 0xa4, 0x79, 0x9e, 0x94,
0x6f, 0xcf, 0x3e, 0xbc, 0x1f, 0x7c, 0x13, 0xe8, 0x3f, 0x12, 0x6a, 0x23, 0x51, 0x2b, 0xe0, 0x67,
0xab, 0xea, 0x20, 0xfd, 0xe4, 0xf8, 0x08, 0xac, 0x93, 0xe8, 0x22, 0x89, 0xb7, 0x67, 0x33, 0x7d,
0x86, 0x8d, 0xb0, 0xee, 0xf1, 0x6e, 0x86, 0xc8, 0xe3, 0x6d, 0x20, 0x3b, 0xdb, 0xf1, 0xd0, 0xfa,
0xb9, 0x43, 0x9b, 0x62, 0x2e, 0x37, 0x23, 0x0d, 0x22, 0xcb, 0x53, 0xc5, 0x68, 0xca, 0xce, 0xaa,
0x62, 0x0d, 0xb7, 0x0d, 0xf6, 0xf0, 0x49, 0x9e, 0x83, 0x6d, 0x99, 0x4e, 0x76, 0x62, 0x3a, 0xf9,
0x67, 0x98, 0x46, 0x3b, 0x31, 0x7d, 0x3a, 0xab, 0x6f, 0xcd, 0x34, 0xde, 0x89, 0xe9, 0xd3, 0x7e,
0xb2, 0x35, 0xd3, 0x6a, 0x27, 0xa6, 0xd5, 0x3f, 0xc3, 0xb4, 0xde, 0x89, 0xe9, 0xd3, 0xce, 0xbb,
0x3d, 0xa6, 0xaf, 0xf3, 0xed, 0x79, 0x4e, 0x9f, 0xe1, 0xb9, 0x6e, 0x73, 0x16, 0xd4, 0xa0, 0xa3,
0xcb, 0xd9, 0x36, 0x6d, 0xcc, 0x9f, 0x01, 0x0e, 0x5d, 0xd1, 0xaa, 0x73, 0x15, 0x79, 0x64, 0xd5,
0xa9, 0xca, 0x2f, 0x5b, 0x27, 0xa8, 0xf2, 0xa1, 0x04, 0x65, 0x8c, 0x9a, 0x83, 0xf6, 0xb6, 0x3f,
0xa9, 0x7a, 0xe8, 0x24, 0x86, 0x93, 0xe2, 0xee, 0x8e, 0x23, 0xb4, 0xd8, 0x95, 0xd8, 0x03, 0xc5,
0xa2, 0x8d, 0x5d, 0xdb, 0xa6, 0xab, 0x78, 0x93, 0xdd, 0xf8, 0x5f, 0xbf, 0xa2, 0x5b, 0xc4, 0xbf,
0x8d, 0xd4, 0x4d, 0x47, 0xed, 0xa1, 0x5d, 0x7c, 0x77, 0xd6, 0xbb, 0x43, 0xdf, 0xb7, 0x48, 0x72,
0xb4, 0x99, 0x3f, 0x9f, 0xf5, 0x86, 0x3d, 0xf4, 0xad, 0xbd, 0x3d, 0x4e, 0x96, 0xad, 0xe4, 0x90,
0x12, 0x33, 0x75, 0x87, 0x55, 0x92, 0xc7, 0x7d, 0xde, 0xc3, 0x35, 0x37, 0x90, 0x56, 0x1b, 0x7a,
0xd4, 0x5f, 0x1f, 0xfa, 0x12, 0xdd, 0x67, 0xab, 0xc7, 0x1b, 0x37, 0xf3, 0x1f, 0xe5, 0xfc, 0xc7,
0x8d, 0xf9, 0x37, 0x72, 0xfe, 0xcd, 0xc6, 0xfc, 0x2b, 0x39, 0x2f, 0x9b, 0x25, 0x52, 0x01, 0x7d,
0xc3, 0x9a, 0xcf, 0x6f, 0x92, 0x2e, 0x3b, 0x95, 0x3b, 0xd2, 0xf5, 0x5e, 0x7f, 0xfc, 0xa9, 0x25,
0xd8, 0xeb, 0x4f, 0x62, 0xc7, 0x66, 0xc3, 0xb1, 0xe2, 0x78, 0x2a, 0x17, 0x34, 0x95, 0x7d, 0x45,
0x78, 0x27, 0x09, 0x4d, 0x75, 0x1e, 0x3f, 0xc8, 0x2b, 0xa9, 0x3f, 0xbe, 0x79, 0xd5, 0xdc, 0x00,
0x86, 0xd9, 0x30, 0x1f, 0x7e, 0x19, 0xce, 0x87, 0xc9, 0x30, 0x1a, 0x2e, 0x79, 0xe3, 0x7d, 0x11,
0x88, 0x22, 0xf4, 0x56, 0x1c, 0x32, 0xbc, 0x96, 0xe3, 0x53, 0x39, 0x2e, 0x02, 0x66, 0xdb, 0xe3,
0x2f, 0x01, 0x6f, 0xdd, 0xa7, 0x59, 0x81, 0xeb, 0xc1, 0xc5, 0x0f, 0xce, 0x60, 0x3c, 0x0f, 0xf0,
0xa1, 0x7e, 0x19, 0x27, 0x41, 0xf1, 0x43, 0xdf, 0x50, 0xaf, 0x07, 0xe3, 0x48, 0x7c, 0x9b, 0xff,
0x80, 0xef, 0x4b, 0xf1, 0x9d, 0x86, 0x03, 0x1a, 0x57, 0x57, 0x69, 0x1d, 0xcd, 0xfa, 0x5f, 0xbe,
0x75, 0x06, 0xb7, 0x51, 0x58, 0x25, 0x8a, 0x3e, 0x0a, 0x83, 0x62, 0x98, 0x05, 0xcb, 0x61, 0x1e,
0x24, 0xe3, 0x09, 0xfa, 0xf7, 0x8b, 0x31, 0x27, 0x18, 0x20, 0x44, 0x20, 0x14, 0x9b, 0x04, 0x06,
0x42, 0x22, 0x09, 0xcb, 0x36, 0xc1, 0x94, 0x84, 0x08, 0x84, 0xa2, 0x4d, 0xb0, 0x40, 0x58, 0x82,
0x90, 0x6c, 0x12, 0x6c, 0xc9, 0x9c, 0x08, 0xd1, 0x5d, 0xb7, 0x4f, 0x0f, 0x37, 0x5a, 0xec, 0x6c,
0xa3, 0x3b, 0xce, 0xc7, 0xe4, 0x57, 0x2d, 0x03, 0x9f, 0xb4, 0xc1, 0x3c, 0x11, 0x90, 0x6c, 0xb6,
0x78, 0x9b, 0xa8, 0x20, 0xd3, 0x84, 0xfc, 0x42, 0x82, 0x0b, 0xf0, 0xe0, 0xf6, 0x28, 0x2b, 0xaa,
0xe4, 0x34, 0xa9, 0xeb, 0x34, 0x3f, 0xaf, 0xb0, 0x8c, 0xae, 0xa5, 0xbd, 0x2a, 0x7b, 0x49, 0xb7,
0x3c, 0x9e, 0xfb, 0xe2, 0xb4, 0x5a, 0x64, 0xe1, 0x4d, 0xd0, 0xcb, 0x8b, 0x3c, 0xe9, 0x8d, 0x05,
0xbd, 0x3c, 0x9f, 0x3c, 0xbd, 0x60, 0x56, 0x3d, 0x4d, 0xcf, 0x7e, 0x7b, 0x92, 0x5e, 0x67, 0x9f,
0x9e, 0xa1, 0x9f, 0x3c, 0x43, 0x3f, 0x7e, 0x8c, 0x0e, 0xc5, 0xc3, 0x03, 0xc6, 0x0d, 0xc0, 0x83,
0xe7, 0x71, 0x79, 0x26, 0x59, 0x11, 0x5d, 0xf4, 0x9e, 0xb0, 0x88, 0x5c, 0x20, 0xfd, 0x2b, 0x5c,
0x79, 0xd7, 0x13, 0x36, 0x12, 0x5b, 0xc6, 0xfc, 0xe5, 0x40, 0xc7, 0xf1, 0x1e, 0x37, 0xdb, 0x7a,
0x8b, 0xd1, 0x75, 0xc9, 0xc7, 0x2d, 0x21, 0xb7, 0x74, 0xfc, 0xf4, 0x71, 0xbb, 0xde, 0x5f, 0x6d,
0x8d, 0x1e, 0xb7, 0xa2, 0x54, 0x3a, 0xba, 0x84, 0xb7, 0xce, 0xe3, 0x89, 0x24, 0x4f, 0xd3, 0x2c,
0x0b, 0xfa, 0xd9, 0xfc, 0x50, 0x1f, 0xfc, 0x18, 0x1e, 0x8d, 0xe2, 0xa3, 0xb5, 0xbf, 0xc1, 0x0e,
0x6c, 0x96, 0x5c, 0xf7, 0x29, 0xec, 0x43, 0x91, 0x0b, 0x26, 0x41, 0xf8, 0x77, 0x3f, 0x3a, 0x38,
0xf0, 0x06, 0x7f, 0xf7, 0x93, 0x83, 0x03, 0xc3, 0xa1, 0x0c, 0x4a, 0xef, 0x41, 0x7a, 0x2f, 0x7a,
0x7b, 0x7d, 0xc3, 0x71, 0x5d, 0x97, 0x19, 0xce, 0xde, 0x64, 0xa0, 0xd5, 0xc5, 0x69, 0x5d, 0xc2,
0x35, 0x31, 0x09, 0x49, 0xb2, 0x34, 0x4a, 0xfa, 0x46, 0xcb, 0x97, 0x33, 0x90, 0xca, 0x30, 0x6e,
0xce, 0x96, 0x87, 0x60, 0x36, 0x09, 0x4b, 0x95, 0x28, 0x29, 0x0a, 0x42, 0xbf, 0xb7, 0x37, 0x39,
0xda, 0x43, 0x2a, 0xdf, 0xeb, 0x8a, 0xb2, 0xd7, 0x1b, 0xb4, 0x32, 0x36, 0x25, 0x30, 0x74, 0xf0,
0x93, 0x22, 0xbe, 0x91, 0x3a, 0x4d, 0xc2, 0xe8, 0xe2, 0xbc, 0x2c, 0x96, 0x79, 0x1c, 0x34, 0x7c,
0x5a, 0xc1, 0x3a, 0x6c, 0x05, 0xea, 0xb0, 0x15, 0xa4, 0xfc, 0x5d, 0xc5, 0xdb, 0xd3, 0xed, 0x96,
0x4e, 0xaf, 0xbb, 0x06, 0xe4, 0xe1, 0xbe, 0x99, 0x8d, 0x57, 0x36, 0xc5, 0xdd, 0xa5, 0xbb, 0x1c,
0x77, 0x99, 0x15, 0xa9, 0x7e, 0x94, 0x24, 0xfd, 0x53, 0x94, 0xea, 0xae, 0x93, 0x2e, 0x90, 0x58,
0x8d, 0x15, 0xc6, 0x7c, 0x27, 0x36, 0xac, 0x48, 0xec, 0x1e, 0xe9, 0xbe, 0xcf, 0x3e, 0x70, 0x44,
0xb8, 0xed, 0x11, 0xec, 0x6b, 0xa4, 0x08, 0x8f, 0x1e, 0x70, 0xec, 0xdd, 0xa4, 0x08, 0x8f, 0xee,
0xea, 0xf3, 0xae, 0xbd, 0x5a, 0xf5, 0x79, 0x6d, 0xef, 0xe9, 0xe2, 0xd3, 0x86, 0xfb, 0xf7, 0x1f,
0xc1, 0x47, 0x86, 0xc5, 0x48, 0x26, 0x99, 0x69, 0x31, 0xdd, 0x3c, 0xfd, 0xde, 0x2e, 0xc7, 0x5a,
0xb1, 0x99, 0x97, 0xcf, 0xad, 0x3e, 0x30, 0xee, 0xc5, 0xd5, 0xd9, 0xf9, 0x99, 0x78, 0x09, 0xd5,
0x15, 0x7d, 0x55, 0x0f, 0xce, 0x02, 0xbd, 0x37, 0x6e, 0xbf, 0x5a, 0xd2, 0xc5, 0xab, 0x86, 0x35,
0x9d, 0xf5, 0x1e, 0x6c, 0x11, 0x4e, 0xaf, 0x5e, 0x7f, 0xea, 0xaf, 0x22, 0xf5, 0x01, 0x61, 0xf6,
0x42, 0xca, 0xa2, 0x93, 0x20, 0x50, 0x8d, 0xbf, 0xff, 0xc6, 0x87, 0xeb, 0x37, 0xa1, 0xf7, 0xe0,
0xdb, 0x8b, 0x09, 0x5f, 0x7d, 0x00, 0xd1, 0x1e, 0xa2, 0xea, 0x77, 0x44, 0x3d, 0x74, 0xbd, 0x87,
0xc9, 0x8e, 0x7d, 0x47, 0x2d, 0x4b, 0x5b, 0xed, 0xb7, 0xa7, 0xaf, 0x84, 0xe2, 0xd1, 0x25, 0x25,
0x72, 0x7c, 0x0c, 0x7e, 0xe4, 0x6f, 0x09, 0x47, 0x78, 0x22, 0x3b, 0x70, 0x2d, 0xf1, 0x35, 0x9b,
0xa3, 0xd3, 0x6b, 0x69, 0x45, 0x51, 0x70, 0x72, 0x4a, 0x9a, 0xf1, 0x30, 0x7b, 0xfd, 0x5a, 0xda,
0x65, 0xd5, 0x77, 0x77, 0xa6, 0x07, 0x42, 0xcb, 0xce, 0x1c, 0x50, 0xd8, 0xd8, 0x6b, 0xdc, 0x6d,
0xae, 0x39, 0x64, 0xf6, 0xe6, 0x22, 0x66, 0xb7, 0xe4, 0x38, 0x79, 0x59, 0xaf, 0x8a, 0xb6, 0xd8,
0xf9, 0x6a, 0xf5, 0xc6, 0x00, 0x7e, 0xf4, 0xdd, 0xc9, 0xcb, 0xc0, 0x80, 0x1f, 0xd1, 0x27, 0xf0,
0x6b, 0xaf, 0x3b, 0xea, 0xae, 0x3b, 0x92, 0xeb, 0x8e, 0x36, 0xd7, 0xbd, 0xee, 0xae, 0xfb, 0x24,
0xd7, 0x7d, 0xc2, 0xba, 0x96, 0x18, 0xa7, 0x00, 0x1d, 0xa6, 0xe0, 0xe2, 0xf0, 0xa2, 0xb8, 0xf6,
0x9c, 0x93, 0xd3, 0xa0, 0x39, 0xb1, 0xa3, 0x48, 0xd7, 0x7f, 0x4e, 0xde, 0x3f, 0xb2, 0x6a, 0xc3,
0x9d, 0x7e, 0x41, 0x33, 0xbd, 0x6e, 0x30, 0x6e, 0xe9, 0xb5, 0x3b, 0x7f, 0x8f, 0x5e, 0x75, 0x33,
0x16, 0xc2, 0x35, 0x8a, 0x5f, 0x3d, 0x5c, 0xb3, 0xab, 0x7a, 0xba, 0x49, 0x48, 0x73, 0xca, 0xf2,
0xbc, 0x9c, 0x57, 0x93, 0x29, 0x1d, 0x8b, 0x25, 0x65, 0x14, 0xf4, 0xf6, 0x2b, 0xc9, 0x0b, 0x85,
0x79, 0x32, 0x95, 0x2f, 0xd5, 0xd6, 0xcd, 0x4f, 0xb7, 0xdd, 0xb9, 0x5d, 0xff, 0x08, 0xb0, 0x21,
0x4e, 0xfc, 0xa0, 0x38, 0x0d, 0xd7, 0x07, 0x04, 0xe2, 0x92, 0xb6, 0xdd, 0xf4, 0xb4, 0xff, 0x78,
0x97, 0xc5, 0x0d, 0xd9, 0x35, 0xcc, 0x5d, 0x7b, 0xef, 0x31, 0xbd, 0xef, 0xa7, 0x37, 0x55, 0xdf,
0xe0, 0x41, 0x3a, 0x52, 0x3a, 0x5f, 0x59, 0xfe, 0x18, 0x96, 0xdf, 0xeb, 0xbc, 0x13, 0x5a, 0xf5,
0xe5, 0xc7, 0x67, 0x2b, 0xd2, 0x59, 0x87, 0xd4, 0xdf, 0x78, 0x39, 0x45, 0xae, 0x71, 0xfc, 0x5a,
0xb8, 0x06, 0x3e, 0xe1, 0x1a, 0x1d, 0x70, 0xc1, 0x42, 0x7f, 0x38, 0x3b, 0x40, 0x38, 0x92, 0x4d,
0xdc, 0xfb, 0xf6, 0xb8, 0x6c, 0xfc, 0xfb, 0xa1, 0xd9, 0xcc, 0x22, 0xa4, 0x1f, 0x2e, 0x39, 0xab,
0x5b, 0xc5, 0x71, 0xa0, 0x7f, 0xf7, 0xf1, 0x98, 0xfc, 0xb6, 0x53, 0x4f, 0x36, 0xe9, 0x46, 0xaf,
0x5b, 0x2c, 0x5a, 0x74, 0xe3, 0xfe, 0x7e, 0xf3, 0x1e, 0xdd, 0x78, 0x58, 0x03, 0x51, 0x9f, 0x45,
0x7e, 0x4b, 0x86, 0x17, 0xb8, 0x93, 0x84, 0x41, 0x58, 0x9e, 0xf3, 0x7b, 0x3f, 0x5d, 0xa1, 0xf7,
0x71, 0xe9, 0x18, 0xa6, 0xad, 0x29, 0x43, 0x4c, 0x65, 0xad, 0x29, 0x26, 0xa6, 0xa6, 0x43, 0xba,
0x11, 0xf0, 0xeb, 0xc9, 0x3c, 0xbc, 0xee, 0x87, 0xc3, 0x74, 0x98, 0x0d, 0x86, 0xf3, 0x20, 0x57,
0xc5, 0x5c, 0x9a, 0x37, 0x73, 0xd1, 0xfa, 0x97, 0x83, 0x49, 0x93, 0x2d, 0xfb, 0xb9, 0x3a, 0x19,
0xec, 0x3b, 0xfb, 0xf3, 0x3d, 0x63, 0x9f, 0xf1, 0x1b, 0xe9, 0x3c, 0xa0, 0xf7, 0xcd, 0xd3, 0xa0,
0x68, 0x92, 0x75, 0x11, 0xcc, 0xf7, 0x73, 0xdc, 0x73, 0x22, 0xc4, 0xe7, 0xf8, 0x02, 0x1f, 0xe9,
0x00, 0xf7, 0xa1, 0xa8, 0x9f, 0x89, 0x98, 0x0d, 0x82, 0x20, 0xa7, 0xf5, 0x5f, 0xd4, 0x0b, 0xb1,
0x1e, 0x93, 0x69, 0x33, 0xd9, 0x37, 0xf6, 0xcd, 0xc1, 0x5e, 0xa2, 0x7e, 0x59, 0x91, 0xb2, 0x15,
0x89, 0x11, 0xe9, 0x42, 0x4d, 0x70, 0x13, 0xa6, 0x8b, 0x30, 0x25, 0xe7, 0xe9, 0x1e, 0xb2, 0x59,
0xb3, 0x72, 0x7a, 0x88, 0x54, 0x37, 0x55, 0x31, 0xc3, 0x17, 0x14, 0x87, 0xab, 0xd7, 0xe0, 0xf2,
0xae, 0x16, 0x4c, 0xef, 0x3a, 0x77, 0xb5, 0xa0, 0x68, 0x05, 0x19, 0x4f, 0xb2, 0xf7, 0xda, 0xe2,
0x15, 0x3c, 0xbf, 0x3d, 0x86, 0xfb, 0xab, 0xc7, 0x00, 0xff, 0xb8, 0xe1, 0x0b, 0x2d, 0xac, 0x4f,
0x36, 0x3a, 0xd7, 0x15, 0xe1, 0xa8, 0xd7, 0xbd, 0x76, 0xb5, 0x0e, 0x83, 0x6b, 0x6f, 0xf8, 0xc4,
0xf2, 0xe8, 0xf7, 0x7e, 0x93, 0x0c, 0x3b, 0x39, 0xf7, 0xf7, 0x76, 0xc0, 0x1c, 0xfd, 0x2e, 0x02,
0x06, 0x9f, 0xab, 0x9c, 0x8b, 0x44, 0x68, 0x88, 0x8b, 0xd7, 0x89, 0xb1, 0x11, 0x8c, 0x27, 0x4c,
0x12, 0xd8, 0x26, 0xe1, 0x4c, 0x12, 0x9a, 0x18, 0xdd, 0x90, 0xe6, 0x63, 0xeb, 0x5a, 0x77, 0x42,
0x91, 0x28, 0x17, 0x8c, 0x0f, 0xf6, 0xe5, 0x0f, 0xa7, 0xca, 0x01, 0x4f, 0x3f, 0x87, 0xa3, 0xb2,
0x28, 0xea, 0x5b, 0xf1, 0x42, 0x75, 0xf4, 0x22, 0xf6, 0x27, 0xa6, 0xa1, 0x8f, 0xc5, 0xab, 0xce,
0xd1, 0x0b, 0x7d, 0x62, 0x46, 0x76, 0x3c, 0x16, 0x2f, 0x21, 0x47, 0x2f, 0x8c, 0x98, 0xb9, 0xa6,
0x31, 0x16, 0xaf, 0x07, 0x47, 0x2f, 0x4c, 0xe6, 0x45, 0x11, 0x0d, 0x2b, 0xb1, 0x58, 0xa7, 0x8d,
0x75, 0x97, 0x14, 0xbd, 0xce, 0x47, 0xbf, 0x26, 0x65, 0x1c, 0xe6, 0xe1, 0x9d, 0x16, 0xd5, 0x65,
0xf6, 0x79, 0x52, 0x5c, 0xdf, 0xce, 0x11, 0x07, 0x69, 0x3e, 0x0a, 0x97, 0x75, 0x31, 0xbe, 0x4a,
0xe3, 0x7a, 0x36, 0xf2, 0xf4, 0xcb, 0xab, 0xf1, 0xba, 0x5f, 0x16, 0xbf, 0x14, 0x8e, 0x10, 0x60,
0x7d, 0xc1, 0x7c, 0x30, 0x5e, 0x14, 0x55, 0x4a, 0xba, 0x8d, 0xc2, 0x49, 0x55, 0x64, 0xcb, 0x3a,
0x19, 0xd7, 0xc5, 0x62, 0x64, 0xdb, 0xdf, 0x8e, 0xb3, 0x64, 0x5a, 0x8f, 0x6c, 0xfd, 0xdb, 0x71,
0x5d, 0x86, 0x79, 0x35, 0x2d, 0xca, 0xf9, 0x88, 0x7f, 0xcb, 0x90, 0x3a, 0xfa, 0x2a, 0x08, 0x43,
0x7a, 0xa0, 0x57, 0x4e, 0xb3, 0x3a, 0x29, 0x47, 0x71, 0x59, 0x2c, 0xd4, 0x6a, 0x16, 0xc6, 0xc5,
0x15, 0xa8, 0x8b, 0x6b, 0x85, 0x3f, 0xe8, 0xbf, 0x60, 0x47, 0xda, 0x0c, 0x06, 0x77, 0x5a, 0x15,
0x57, 0xb7, 0x42, 0x38, 0x43, 0xc7, 0xe1, 0xb3, 0x24, 0x3d, 0x9f, 0xd5, 0x23, 0x83, 0x5d, 0xce,
0xc6, 0x42, 0x7e, 0x95, 0x04, 0xc0, 0x10, 0x4b, 0x33, 0xa9, 0x92, 0xca, 0x65, 0xe1, 0x7a, 0xc9,
0x89, 0x92, 0xef, 0x6a, 0xcf, 0xc8, 0x5d, 0x52, 0x71, 0xd7, 0xbd, 0xbc, 0xba, 0x7b, 0x81, 0xdb,
0xe1, 0x6d, 0x8b, 0xac, 0x83, 0xbc, 0x36, 0xc6, 0x68, 0xf3, 0x3a, 0x52, 0x17, 0x0a, 0x3f, 0x76,
0x38, 0xc9, 0xb0, 0x68, 0x78, 0x93, 0x64, 0x59, 0x71, 0x35, 0xa0, 0x53, 0x3e, 0xde, 0x6e, 0xbf,
0xad, 0x84, 0x4b, 0xd2, 0x9e, 0x37, 0x3b, 0xec, 0x39, 0x2f, 0x93, 0x24, 0xe7, 0xbb, 0x5e, 0xed,
0xb0, 0x6b, 0x42, 0xdd, 0x10, 0x6d, 0xfa, 0x6d, 0x87, 0x4d, 0x57, 0xb3, 0xb4, 0x16, 0xbb, 0xde,
0x6e, 0xb5, 0x0b, 0xea, 0x0c, 0x8b, 0x92, 0x7e, 0x62, 0x95, 0x06, 0x11, 0xc2, 0x0e, 0xa3, 0x9b,
0x30, 0xe7, 0x12, 0x0c, 0x2f, 0xd3, 0x22, 0x4b, 0xea, 0x95, 0xde, 0xa7, 0x5b, 0x1d, 0x8b, 0x43,
0x6e, 0x5a, 0x6a, 0x1f, 0xef, 0xa0, 0x01, 0x32, 0xf4, 0xbf, 0x97, 0x45, 0x5a, 0x09, 0x2d, 0xce,
0x76, 0xd8, 0xd9, 0x20, 0x8a, 0xdb, 0x6b, 0x91, 0x55, 0xff, 0xb1, 0x6f, 0x7d, 0xfa, 0x2a, 0xb3,
0xbf, 0xdb, 0xd5, 0x97, 0xe8, 0xe6, 0x7b, 0x3b, 0x2d, 0xf2, 0x5a, 0x9d, 0x86, 0xf3, 0x34, 0xbb,
0x69, 0xc2, 0xf7, 0x75, 0x3e, 0x18, 0xbe, 0x4d, 0xb2, 0xcb, 0xa4, 0x4e, 0xa3, 0x70, 0x58, 0x21,
0x32, 0xd5, 0x2a, 0x29, 0xd3, 0xe9, 0xb8, 0x4e, 0xae, 0x6b, 0x35, 0xcc, 0xd2, 0xf3, 0x7c, 0x14,
0x25, 0xf4, 0xe3, 0xfc, 0x53, 0x4e, 0x2f, 0x0e, 0xa3, 0xbc, 0x34, 0x10, 0x4c, 0x07, 0xab, 0x90,
0xa4, 0xf0, 0x94, 0x29, 0x45, 0x6f, 0x27, 0x91, 0x32, 0x59, 0x24, 0x61, 0x3d, 0xca, 0x0b, 0xf9,
0xad, 0x4d, 0x0b, 0xeb, 0x3a, 0x8c, 0x66, 0x54, 0x8b, 0x47, 0xd3, 0xf4, 0x3a, 0x89, 0xc7, 0xed,
0x8c, 0x43, 0x49, 0x6c, 0x70, 0x47, 0x7f, 0x47, 0x70, 0xdb, 0xe2, 0x81, 0x3a, 0x56, 0x86, 0xf3,
0xe4, 0x56, 0x76, 0x6c, 0x23, 0x6a, 0xd8, 0xc6, 0x93, 0xa2, 0x8c, 0x91, 0x54, 0xf4, 0xdd, 0xb2,
0xcb, 0xf8, 0x91, 0x0c, 0x28, 0xb9, 0x39, 0x94, 0x00, 0xfe, 0xe3, 0x84, 0x77, 0x57, 0x5d, 0x9e,
0xdf, 0x52, 0x2f, 0x2a, 0xb5, 0x8a, 0x79, 0x1e, 0x95, 0x29, 0x8d, 0xad, 0xb9, 0x19, 0xfa, 0x25,
0xfa, 0x8c, 0x1d, 0xd3, 0x63, 0x9a, 0x2f, 0x96, 0xf5, 0xed, 0x6e, 0x4a, 0x3f, 0xe2, 0x1b, 0x6b,
0x8f, 0xb8, 0x9b, 0x2c, 0xeb, 0xba, 0xc8, 0xdb, 0x8e, 0xd7, 0x82, 0xbd, 0x03, 0x91, 0x50, 0x46,
0x5a, 0x5f, 0xb3, 0xa3, 0x99, 0x02, 0x23, 0xa5, 0xb1, 0xd2, 0x5e, 0x2f, 0x83, 0x62, 0x52, 0xe0,
0xd0, 0xf9, 0xc8, 0x80, 0x4d, 0xff, 0x69, 0x79, 0xc5, 0x55, 0x73, 0x1b, 0x79, 0xeb, 0x2d, 0xe4,
0xfd, 0xa7, 0xa5, 0xe3, 0x18, 0xfd, 0xc1, 0xff, 0xd6, 0x2a, 0x5f, 0xce, 0x27, 0x49, 0xf9, 0xe7,
0x3f, 0x25, 0xa9, 0x70, 0x22, 0x33, 0x99, 0xb7, 0x79, 0xf0, 0xe4, 0xfb, 0xe7, 0xad, 0x7a, 0x95,
0x4c, 0x2e, 0x52, 0x04, 0xf6, 0x02, 0x31, 0x87, 0xb9, 0x28, 0x11, 0x91, 0x22, 0x5d, 0x5e, 0xb5,
0xa0, 0x88, 0x7e, 0x7f, 0xdf, 0x68, 0x5a, 0x44, 0xcb, 0xea, 0xb6, 0x58, 0xd6, 0x14, 0xf9, 0xa3,
0x87, 0x56, 0x8c, 0x9a, 0xa3, 0x2b, 0xc8, 0x93, 0x94, 0x6a, 0xb9, 0xcc, 0xf3, 0x70, 0x92, 0x25,
0x2a, 0xbc, 0x3f, 0xba, 0x78, 0xac, 0x58, 0x47, 0xcb, 0xb2, 0x82, 0x72, 0x8b, 0x22, 0xdd, 0x4c,
0x31, 0x2d, 0x8d, 0xb6, 0xe0, 0x56, 0xcf, 0x60, 0xc3, 0x1d, 0x3d, 0x7e, 0x1d, 0x61, 0x4d, 0x4e,
0x36, 0x36, 0x6a, 0xbb, 0x58, 0x1e, 0x0a, 0x14, 0xba, 0x92, 0x3e, 0x6d, 0x48, 0x9e, 0xeb, 0xe1,
0xd3, 0x0f, 0x4a, 0x3e, 0x2f, 0xfe, 0x52, 0xf9, 0xe0, 0x7f, 0xcb, 0x34, 0x2d, 0x06, 0xff, 0x6d,
0xb3, 0x6c, 0xa3, 0x7e, 0xf5, 0xb5, 0x7a, 0xf3, 0x3c, 0xba, 0x08, 0x4b, 0xfa, 0x63, 0x42, 0x11,
0x02, 0xb2, 0x15, 0x6d, 0x13, 0xee, 0xcd, 0x3c, 0x26, 0x04, 0x25, 0x5f, 0x15, 0x95, 0x3c, 0x29,
0xdb, 0x81, 0xf7, 0xe2, 0x59, 0xe3, 0xca, 0x9d, 0x4b, 0x00, 0xbf, 0xf3, 0x4e, 0x81, 0xc7, 0xce,
0x56, 0x6d, 0x41, 0x72, 0x87, 0x4b, 0x02, 0xbf, 0x1b, 0xc8, 0x3b, 0x82, 0x92, 0xc6, 0xc1, 0xac,
0xc8, 0x60, 0x8b, 0x2f, 0xc8, 0x2c, 0x7c, 0x86, 0x73, 0xa5, 0xf2, 0xbd, 0x1f, 0x55, 0xd5, 0x61,
0xb3, 0xfe, 0x60, 0x5f, 0xfc, 0xb9, 0x28, 0x35, 0x02, 0x4a, 0x91, 0xf3, 0xdf, 0x8d, 0x57, 0x7f,
0xc5, 0xa7, 0x44, 0xf4, 0x83, 0x6c, 0xf0, 0xf9, 0x33, 0x6a, 0x67, 0x9a, 0x7f, 0xa6, 0xcd, 0x9f,
0x3f, 0xfe, 0xfc, 0xf2, 0xa7, 0xdf, 0x3f, 0x7f, 0x26, 0x46, 0x8b, 0x30, 0x97, 0x2b, 0xe8, 0xd7,
0xda, 0xc3, 0xf7, 0xd8, 0x9b, 0xe6, 0xe7, 0x9a, 0xa6, 0xe1, 0x70, 0xd0, 0x68, 0xc9, 0xe5, 0xb9,
0xc2, 0xf9, 0x04, 0xf7, 0x2b, 0xa3, 0x50, 0x57, 0x6f, 0xb4, 0xd0, 0xc7, 0xc5, 0x65, 0x52, 0x4e,
0x61, 0xf9, 0xd1, 0x2c, 0x8d, 0xe3, 0x24, 0x57, 0x30, 0xac, 0xb0, 0x23, 0x30, 0x34, 0x43, 0xb9,
0x9e, 0x67, 0x79, 0x15, 0xcc, 0xea, 0x7a, 0x31, 0xda, 0xdf, 0xbf, 0xba, 0xba, 0xd2, 0xae, 0x4c,
0xad, 0x28, 0xcf, 0xf7, 0x19, 0x6e, 0x30, 0xfb, 0xe0, 0x02, 0x5e, 0x71, 0x32, 0xad, 0x0e, 0x95,
0xfd, 0xfd, 0xf7, 0xbc, 0x09, 0xa1, 0xbf, 0x48, 0xad, 0xb4, 0xa8, 0x98, 0xef, 0x4f, 0xd1, 0x08,
0x42, 0x92, 0x9b, 0xf9, 0xa4, 0xc8, 0xc8, 0x2c, 0x59, 0x5e, 0xaa, 0x0b, 0xc2, 0x57, 0x15, 0x97,
0x55, 0xe5, 0x32, 0x4d, 0xae, 0x5e, 0x15, 0xd7, 0x41, 0x4f, 0x57, 0x74, 0xc5, 0xd0, 0x99, 0xc5,
0x1f, 0xbd, 0xc3, 0x03, 0x7a, 0x89, 0xac, 0xc4, 0x41, 0xef, 0x83, 0xe5, 0x39, 0x9a, 0xa5, 0x38,
0x86, 0xa5, 0x59, 0x91, 0x8a, 0xa7, 0x61, 0x7a, 0x8a, 0xae, 0x32, 0x5b, 0x73, 0x54, 0xc3, 0xd0,
0x2c, 0xc7, 0x10, 0xdf, 0xe9, 0x71, 0xa9, 0x5a, 0x8e, 0xae, 0x79, 0x91, 0xde, 0xac, 0xe3, 0x0b,
0x18, 0xa7, 0x29, 0xab, 0x55, 0x15, 0x1f, 0x0a, 0x92, 0xb2, 0x22, 0x5d, 0xca, 0xad, 0x0a, 0xdf,
0xea, 0xab, 0x2d, 0xfa, 0x7a, 0xff, 0x5f, 0x10, 0x6c, 0x9f, 0x24, 0xbb, 0x27, 0x9f, 0xef, 0x32,
0xec, 0x56, 0x21, 0xbc, 0x66, 0xbb, 0x90, 0xcf, 0xf0, 0x7d, 0xd5, 0xf4, 0x35, 0xdf, 0xb2, 0x54,
0xe6, 0x1a, 0x9a, 0x6d, 0xe2, 0x40, 0xa6, 0x59, 0xae, 0x8a, 0x75, 0x36, 0xf3, 0x9a, 0x0f, 0x39,
0x69, 0x38, 0x9e, 0xe6, 0x3b, 0xcd, 0x48, 0x6c, 0xc0, 0x21, 0x9e, 0xa5, 0x99, 0xbe, 0xad, 0x30,
0x47, 0xf3, 0x6c, 0x48, 0xe4, 0xc0, 0x04, 0xae, 0xa7, 0xb8, 0xae, 0xe6, 0xb8, 0x38, 0xd6, 0xc4,
0x2a, 0xdf, 0x52, 0x2c, 0x5f, 0x33, 0x6c, 0x15, 0x34, 0xdf, 0xb0, 0xa1, 0x15, 0x0e, 0x72, 0x49,
0x7a, 0x13, 0x5b, 0x61, 0x4c, 0xdf, 0xd1, 0x1c, 0x66, 0xa9, 0x86, 0xe9, 0x68, 0xb6, 0x6e, 0x28,
0x98, 0xb6, 0x6d, 0xd5, 0xd2, 0x74, 0xd3, 0x52, 0x98, 0xab, 0x79, 0xba, 0xad, 0x98, 0x9a, 0xe3,
0x99, 0x0a, 0x0e, 0xf3, 0xc8, 0x60, 0xae, 0xc6, 0x4c, 0xab, 0x52, 0xc5, 0xa4, 0x58, 0xa1, 0x8a,
0x49, 0xb9, 0x04, 0x3a, 0x92, 0x5e, 0xb6, 0xad, 0x58, 0x86, 0xe6, 0xd8, 0x24, 0x87, 0xab, 0xb9,
0x3a, 0xc3, 0x56, 0x58, 0x60, 0x3d, 0x34, 0x0d, 0x5f, 0xd3, 0x19, 0x23, 0x54, 0x3d, 0x30, 0xd5,
0x61, 0x71, 0x48, 0xca, 0x20, 0x93, 0x69, 0x62, 0x61, 0xfb, 0x59, 0xf1, 0xa7, 0xda, 0xa1, 0xab,
0xfc, 0xc9, 0x91, 0x74, 0x34, 0xc3, 0x73, 0x55, 0x1f, 0xc7, 0xda, 0x30, 0x8d, 0xab, 0x99, 0xae,
0xe4, 0x62, 0xa8, 0x82, 0x09, 0xa9, 0x07, 0xb5, 0x98, 0xd0, 0x4b, 0x65, 0x86, 0xc6, 0x1c, 0xd8,
0xd4, 0xd3, 0x98, 0xe7, 0x49, 0xe1, 0x55, 0xa9, 0x1f, 0xad, 0x60, 0x72, 0xb9, 0x42, 0x2b, 0x7c,
0xb9, 0x5c, 0x68, 0xe7, 0x8a, 0xe5, 0x36, 0xb7, 0xb1, 0x05, 0xcc, 0x4d, 0xcd, 0xe0, 0x92, 0xbb,
0x9a, 0x05, 0xc3, 0xc3, 0xe0, 0x1e, 0x13, 0x36, 0x35, 0xf1, 0x09, 0x9b, 0x5a, 0xbe, 0xaf, 0xd8,
0xf0, 0x1b, 0xc3, 0x51, 0x1c, 0x57, 0x33, 0x0c, 0xb1, 0xd3, 0xb5, 0xf9, 0x16, 0x06, 0x33, 0xc8,
0xa1, 0x00, 0xcb, 0x13, 0x3e, 0x0e, 0x0f, 0x11, 0xbe, 0x41, 0x67, 0x41, 0x01, 0x9d, 0x49, 0xe4,
0x15, 0xe9, 0x2a, 0xc2, 0x39, 0x14, 0xfe, 0xe1, 0x48, 0xe7, 0x50, 0xba, 0xce, 0x21, 0x46, 0x2d,
0x7f, 0xdc, 0x17, 0x41, 0x76, 0xb8, 0x19, 0x6d, 0x59, 0x5a, 0xd5, 0x5b, 0x44, 0x99, 0xef, 0x7b,
0xf0, 0x62, 0x0f, 0xf6, 0x64, 0x33, 0xd5, 0x75, 0xbc, 0xe7, 0x42, 0xad, 0x7a, 0x30, 0xb4, 0x66,
0xb4, 0x53, 0x04, 0x10, 0x18, 0xad, 0xe3, 0xcc, 0x58, 0xc7, 0x59, 0xa5, 0xb6, 0x66, 0x9e, 0x8e,
0x2c, 0x21, 0x93, 0xed, 0x98, 0xff, 0xef, 0x64, 0x32, 0x75, 0xf7, 0x29, 0x99, 0xd8, 0xd7, 0xca,
0xc4, 0xbe, 0x4a, 0x26, 0xd7, 0xa1, 0x48, 0xb2, 0x3d, 0x4a, 0x90, 0x16, 0xd3, 0x4c, 0x8b, 0x12,
0x10, 0x4d, 0xaa, 0x26, 0x32, 0x06, 0xf9, 0x13, 0x7d, 0xa7, 0x47, 0xd5, 0x9a, 0x50, 0x56, 0xb3,
0x8a, 0x38, 0x80, 0x93, 0x94, 0x35, 0xa9, 0x35, 0xb1, 0x5e, 0xf6, 0x97, 0xe0, 0xc6, 0x6c, 0x47,
0x68, 0x0e, 0x8f, 0x17, 0x9a, 0x73, 0x05, 0x3c, 0x7b, 0x2d, 0x69, 0x25, 0x26, 0xd6, 0x1a, 0xad,
0x1f, 0x6a, 0x8b, 0xa4, 0xb6, 0x26, 0xd6, 0x66, 0x53, 0x9f, 0xd4, 0x55, 0x16, 0x83, 0x07, 0x74,
0x35, 0xd6, 0xba, 0x62, 0x5e, 0x2e, 0x78, 0x50, 0xe9, 0xea, 0x41, 0xa5, 0x91, 0xff, 0xf9, 0x26,
0xff, 0x49, 0xed, 0x6d, 0x83, 0xfd, 0x1f, 0x6a, 0xef, 0xb9, 0xfa, 0xf3, 0xda, 0x3f, 0x8b, 0xb4,
0xb1, 0x25, 0xd2, 0x2b, 0x1f, 0xff, 0x2f, 0xe9, 0xfa, 0x58, 0x1e, 0x9b, 0x17, 0x45, 0xbe, 0x45,
0x1e, 0xb3, 0x99, 0x05, 0xa1, 0x69, 0x96, 0xa4, 0xd6, 0x35, 0xc3, 0xf5, 0x49, 0x6c, 0x24, 0x4d,
0xdf, 0xf1, 0x54, 0xdb, 0x42, 0x06, 0x07, 0xb6, 0x18, 0xea, 0x3e, 0x6a, 0x8b, 0x6d, 0xa2, 0x8a,
0x54, 0xf2, 0x13, 0x45, 0x45, 0x47, 0x11, 0x6d, 0x46, 0x72, 0x11, 0x95, 0x20, 0xc3, 0xd6, 0x18,
0x92, 0x35, 0xca, 0x03, 0xc3, 0xf1, 0xba, 0x41, 0xbc, 0x1d, 0xcd, 0xf7, 0x91, 0xc6, 0x61, 0x19,
0x1b, 0x85, 0xc2, 0x34, 0x79, 0x39, 0xb7, 0x50, 0x75, 0x1d, 0xd4, 0x00, 0x93, 0x57, 0x68, 0x0f,
0xcd, 0x93, 0x4d, 0x35, 0xd9, 0xd7, 0x4c, 0x66, 0xf3, 0x1c, 0x6f, 0x32, 0x53, 0x41, 0x41, 0xd3,
0x6d, 0x9d, 0x2a, 0x92, 0x85, 0xbe, 0x01, 0xb5, 0xc4, 0xb1, 0x54, 0xdb, 0xd6, 0x2c, 0xd2, 0x06,
0xb5, 0xc4, 0x02, 0x1b, 0xb0, 0x66, 0xb0, 0x9a, 0x8f, 0xc2, 0x82, 0x02, 0xa5, 0xf9, 0xa8, 0xdc,
0x4c, 0xe7, 0x2b, 0x74, 0xcd, 0x34, 0x1d, 0xea, 0x08, 0x7c, 0xb4, 0x19, 0xa8, 0x5f, 0x8c, 0x55,
0xa8, 0x84, 0x54, 0xb9, 0x51, 0x24, 0x50, 0xaa, 0x4c, 0x4d, 0x77, 0x50, 0xda, 0x3d, 0x48, 0x89,
0x08, 0x85, 0x58, 0x3a, 0x26, 0xd1, 0x1c, 0x98, 0x68, 0x69, 0x2c, 0x0f, 0xb5, 0xd3, 0x57, 0x0c,
0x58, 0x1c, 0x15, 0x7a, 0x35, 0xf4, 0x4d, 0x01, 0x2e, 0x8a, 0x14, 0x8a, 0x92, 0x8b, 0x09, 0xa8,
0x0b, 0x31, 0x4d, 0x7c, 0x74, 0x9e, 0xa8, 0x70, 0x96, 0x61, 0x91, 0xe5, 0x71, 0xbe, 0xeb, 0x02,
0x4b, 0x1b, 0x27, 0x18, 0xcd, 0x09, 0xe2, 0x40, 0x0f, 0x52, 0x1b, 0xba, 0x8b, 0x5a, 0x0c, 0x13,
0x90, 0xd4, 0x86, 0x89, 0x6e, 0xc2, 0x72, 0x7c, 0x29, 0x94, 0x90, 0x90, 0x5c, 0xc6, 0xa0, 0x9e,
0x01, 0x64, 0x8b, 0xeb, 0x61, 0x49, 0xa5, 0x22, 0x3a, 0xd5, 0x43, 0xde, 0x23, 0x14, 0x5c, 0x93,
0x0a, 0xa5, 0x67, 0xc1, 0x88, 0x3a, 0x74, 0xf0, 0xa4, 0x65, 0x1c, 0x69, 0x28, 0x9b, 0x8c, 0x68,
0x38, 0x8e, 0x62, 0xc1, 0x87, 0xd0, 0x03, 0xc1, 0x04, 0x36, 0xe2, 0x03, 0xea, 0x01, 0x9a, 0xc6,
0xdc, 0x8d, 0xf9, 0x7d, 0x1d, 0x75, 0x13, 0xb6, 0x80, 0x8e, 0xbe, 0x47, 0xfd, 0x99, 0x66, 0x52,
0x69, 0xdf, 0x00, 0x52, 0x8e, 0xff, 0xfa, 0x00, 0x33, 0xa3, 0x83, 0x72, 0x69, 0xbd, 0xe7, 0x53,
0xb2, 0x43, 0x35, 0x76, 0x2d, 0x83, 0xb0, 0xf5, 0x3d, 0xe4, 0x73, 0x70, 0x31, 0x40, 0x66, 0xf0,
0x31, 0x1d, 0xcd, 0x59, 0x33, 0xb6, 0x18, 0x9d, 0x4b, 0x46, 0x62, 0x0e, 0x64, 0x03, 0xc2, 0x8c,
0x2a, 0xb5, 0x0d, 0x19, 0xc9, 0x2b, 0x3a, 0x4f, 0xc3, 0xf3, 0x79, 0x63, 0xa5, 0x23, 0x79, 0xc3,
0x92, 0x86, 0x25, 0xdb, 0x00, 0xbb, 0x39, 0xa5, 0x39, 0x55, 0xb5, 0x31, 0x4d, 0xc2, 0xfa, 0xd4,
0x44, 0xa0, 0xc9, 0x24, 0xbb, 0xa3, 0x3d, 0xf3, 0x39, 0xd1, 0x40, 0xe3, 0x6a, 0x83, 0x65, 0x33,
0xc4, 0xa7, 0x4f, 0x8d, 0x17, 0x22, 0x8b, 0xc1, 0xd6, 0xd8, 0xad, 0x53, 0xa3, 0x88, 0x28, 0x87,
0xe8, 0x26, 0x50, 0x43, 0xe6, 0xa0, 0x92, 0xe4, 0xa3, 0xe3, 0x71, 0x7c, 0xfe, 0xe1, 0xca, 0x49,
0x6a, 0x9e, 0xc8, 0xc1, 0x9d, 0xd5, 0x58, 0x6c, 0xa2, 0x64, 0x0a, 0x11, 0x0d, 0xd3, 0x00, 0xba,
0x20, 0xea, 0x80, 0x12, 0xdd, 0x4c, 0x57, 0x80, 0x2d, 0x82, 0x38, 0x2a, 0xce, 0xb7, 0x88, 0x61,
0x13, 0x50, 0x91, 0x5b, 0xe9, 0x60, 0xe3, 0xda, 0x76, 0x84, 0x08, 0x30, 0x74, 0x0a, 0x63, 0x0b,
0x61, 0xe8, 0xa9, 0x3a, 0xfa, 0x35, 0xa6, 0x3a, 0xe4, 0x6b, 0x2a, 0xb5, 0x5e, 0x2a, 0xd0, 0xf7,
0x5d, 0x9e, 0x59, 0x3c, 0xdd, 0x24, 0x9c, 0x0d, 0xca, 0xdf, 0xc0, 0xc5, 0xa2, 0x56, 0x0f, 0x0e,
0x83, 0xa0, 0x46, 0xe4, 0x33, 0x83, 0x96, 0xf8, 0x0c, 0x49, 0x11, 0x51, 0x81, 0x86, 0xdc, 0x21,
0xdf, 0x64, 0x8c, 0x08, 0x3e, 0x75, 0xc7, 0x94, 0x07, 0x4d, 0x8b, 0xdc, 0x11, 0xce, 0x0c, 0x3b,
0xf8, 0x0c, 0x7e, 0x47, 0xe0, 0xf9, 0xbc, 0x7d, 0x84, 0x9f, 0xc9, 0x11, 0x1c, 0xdd, 0xf7, 0xc9,
0xc2, 0xb6, 0xc3, 0x8d, 0x44, 0x02, 0x90, 0x61, 0xd1, 0xda, 0x59, 0xdd, 0x27, 0xfc, 0x9b, 0x51,
0xde, 0xc4, 0xc9, 0x3a, 0xf9, 0x29, 0x50, 0x5d, 0x6d, 0x97, 0x87, 0xe1, 0xc3, 0x30, 0x4d, 0x85,
0xfa, 0x74, 0xea, 0xee, 0x28, 0x52, 0x15, 0x50, 0x98, 0x14, 0x87, 0x49, 0xd9, 0x90, 0x78, 0x0c,
0x44, 0x15, 0xf9, 0x14, 0xa3, 0xdc, 0x6f, 0xe9, 0x9e, 0xea, 0x91, 0xd7, 0xd8, 0x42, 0x37, 0x43,
0xaa, 0x4a, 0xd1, 0x66, 0x9a, 0x26, 0x1d, 0xeb, 0x7b, 0x3e, 0xa2, 0xcd, 0x87, 0xb3, 0x3a, 0x54,
0xd2, 0x14, 0x83, 0x78, 0x70, 0xcb, 0xe0, 0x83, 0xb7, 0xef, 0xb8, 0xa4, 0x10, 0xde, 0x26, 0x77,
0x73, 0x17, 0xe7, 0x23, 0xe8, 0xe8, 0x6a, 0x20, 0x47, 0xe8, 0xb9, 0x41, 0xab, 0x54, 0x1e, 0xb9,
0x60, 0x67, 0xaa, 0x9c, 0xe0, 0x71, 0x82, 0xa5, 0x47, 0xc4, 0xc4, 0xe5, 0xb1, 0xce, 0x5c, 0x0a,
0x29, 0xe4, 0x58, 0x46, 0x3a, 0x3b, 0xa6, 0xa7, 0x1a, 0x42, 0x21, 0xce, 0xcc, 0x55, 0x24, 0x36,
0x02, 0x29, 0x45, 0x62, 0x23, 0x90, 0x52, 0x3a, 0xe2, 0x23, 0xc0, 0x04, 0x38, 0x1c, 0x29, 0x45,
0xa0, 0xc3, 0x91, 0x52, 0x04, 0x3a, 0xc2, 0x1c, 0x0a, 0x87, 0xc7, 0xe4, 0x50, 0xf1, 0xd6, 0x1d,
0x49, 0x4f, 0xd8, 0x53, 0xe1, 0xd6, 0x6d, 0x06, 0x02, 0x20, 0xd9, 0x76, 0x37, 0x40, 0x29, 0x2d,
0x88, 0xe8, 0xaa, 0x46, 0x20, 0x39, 0xaa, 0xc0, 0x86, 0x03, 0x45, 0x41, 0xb4, 0x06, 0x5a, 0x15,
0x66, 0xe3, 0x38, 0x21, 0x40, 0x00, 0x0d, 0xe3, 0x38, 0x59, 0x14, 0x0c, 0x2d, 0xb7, 0xe1, 0xd8,
0x08, 0xa0, 0x1c, 0x9e, 0x85, 0x28, 0xa2, 0x05, 0x52, 0x4a, 0xc7, 0x0d, 0x0d, 0x92, 0xce, 0xa7,
0x88, 0x04, 0x52, 0x3c, 0xef, 0x11, 0x3a, 0x84, 0x94, 0xd2, 0x98, 0xcb, 0x11, 0x1f, 0x16, 0x99,
0x99, 0x0e, 0x76, 0x75, 0x9e, 0x10, 0x57, 0x48, 0x21, 0xcb, 0x72, 0x08, 0xe4, 0xa8, 0x02, 0x34,
0x02, 0x24, 0x3e, 0x0f, 0xf3, 0x0b, 0x04, 0x23, 0xb0, 0xf3, 0x38, 0x4a, 0x06, 0xe5, 0x5a, 0xc7,
0xb2, 0x05, 0x4a, 0xb6, 0x60, 0xe4, 0x0b, 0x94, 0x7c, 0x45, 0xe2, 0xc2, 0x51, 0x62, 0x0a, 0xe1,
0x62, 0x4b, 0x90, 0xa4, 0xe4, 0xa6, 0xd2, 0x48, 0x6e, 0xf0, 0xe4, 0xc2, 0x41, 0x22, 0x31, 0x51,
0x0a, 0x38, 0x48, 0xba, 0x27, 0x8c, 0xa1, 0x48, 0xa7, 0x25, 0x60, 0x98, 0x40, 0xc9, 0xe1, 0xd6,
0x44, 0x46, 0xe7, 0x38, 0xb9, 0xcd, 0xa8, 0x09, 0xa2, 0x06, 0xa3, 0x36, 0x36, 0xdd, 0x27, 0xc7,
0x87, 0xb2, 0xa4, 0xc0, 0x86, 0x03, 0x25, 0xb7, 0x4b, 0xa0, 0x14, 0x0e, 0x8e, 0x27, 0x90, 0x52,
0x04, 0x38, 0x1c, 0x29, 0x29, 0x8f, 0x25, 0x85, 0xe3, 0xd8, 0x38, 0x12, 0x29, 0xc5, 0x12, 0x59,
0x55, 0x20, 0x25, 0x14, 0x6c, 0x80, 0x52, 0x04, 0x34, 0x22, 0x88, 0x80, 0x93, 0x0f, 0xcb, 0x0a,
0x9c, 0xa4, 0x63, 0x4b, 0xa4, 0x54, 0x89, 0x8d, 0x40, 0x4a, 0x86, 0x87, 0x44, 0x4a, 0xed, 0x20,
0x55, 0x49, 0x7c, 0x70, 0xad, 0x6e, 0xcd, 0xe3, 0x3e, 0x2d, 0x62, 0x48, 0x21, 0xa4, 0x14, 0x11,
0x42, 0x8a, 0x08, 0x21, 0xa5, 0xcd, 0xc9, 0x97, 0xe9, 0x4d, 0x42, 0x25, 0xd3, 0x9b, 0x80, 0x4a,
0xed, 0x88, 0xce, 0xb3, 0x9b, 0x2d, 0x80, 0xb2, 0x55, 0x89, 0x8d, 0x40, 0x4a, 0x6d, 0x19, 0x83,
0xa9, 0x12, 0x1c, 0x8e, 0x94, 0xda, 0xc1, 0x46, 0x6d, 0x19, 0x17, 0xa3, 0x26, 0x88, 0x64, 0xc4,
0xb4, 0xb3, 0x9d, 0x84, 0x48, 0x57, 0x64, 0xa6, 0x13, 0xd8, 0xc8, 0x6c, 0xd7, 0x05, 0x5a, 0xba,
0x34, 0x01, 0xe5, 0x88, 0x04, 0xd7, 0x00, 0xc5, 0xc5, 0x69, 0xc2, 0x5b, 0x62, 0x23, 0x90, 0x52,
0x25, 0x36, 0x02, 0xa9, 0x55, 0x8a, 0x90, 0xc9, 0x9c, 0xf1, 0x73, 0x09, 0x29, 0x47, 0xa6, 0x38,
0x81, 0x94, 0xda, 0x76, 0x6e, 0x57, 0x64, 0x38, 0x4f, 0x22, 0x25, 0x32, 0x9c, 0xdd, 0x4e, 0x64,
0x4d, 0xb4, 0x78, 0x95, 0x4a, 0xef, 0x3c, 0x44, 0xae, 0xeb, 0x84, 0x17, 0x1a, 0x29, 0xdc, 0xd9,
0xa9, 0xad, 0x94, 0x2f, 0x53, 0xb8, 0xc0, 0x50, 0x99, 0x7a, 0x35, 0x48, 0x4a, 0x75, 0x82, 0x0f,
0xfe, 0xfa, 0x80, 0xab, 0x81, 0x6c, 0xd0, 0x6d, 0x7a, 0x43, 0x61, 0xf3, 0xd4, 0x83, 0x9a, 0x89,
0x08, 0x32, 0x99, 0x78, 0x27, 0x85, 0x5e, 0xca, 0x37, 0xd0, 0xbc, 0xa1, 0x38, 0x93, 0xb3, 0xd2,
0xcb, 0x04, 0x17, 0x28, 0x30, 0x72, 0x1c, 0xdc, 0xf8, 0x75, 0xfe, 0xea, 0xc2, 0x73, 0xf9, 0xab,
0x04, 0xe6, 0x8b, 0xda, 0x63, 0x39, 0xaa, 0x8d, 0xfe, 0x84, 0xa7, 0x42, 0xdd, 0xa5, 0xe5, 0x16,
0x8a, 0x34, 0xb5, 0x77, 0xae, 0x2d, 0x07, 0xa8, 0xf2, 0x86, 0xc7, 0xc4, 0x5b, 0x23, 0xc7, 0x47,
0xa3, 0x43, 0x0d, 0xa1, 0xc5, 0xbb, 0x59, 0xea, 0x97, 0x4c, 0xaa, 0xdb, 0xe2, 0xbb, 0x4b, 0x0d,
0x9a, 0x88, 0x27, 0x7a, 0xbb, 0xc1, 0x38, 0x33, 0xbe, 0xdd, 0x50, 0xe8, 0x2c, 0x8f, 0xfb, 0xbd,
0xcb, 0x53, 0x99, 0x0b, 0x0b, 0x33, 0xec, 0x32, 0xe9, 0x7c, 0xc7, 0x61, 0x8a, 0x94, 0x46, 0xca,
0x66, 0x51, 0x77, 0x44, 0xc6, 0x67, 0xe4, 0x49, 0xa4, 0x11, 0x5a, 0x34, 0xe8, 0x82, 0x0c, 0x2e,
0x47, 0x42, 0x5d, 0xdc, 0x47, 0x44, 0x84, 0x0a, 0x63, 0x18, 0x52, 0xfb, 0x86, 0x1a, 0x09, 0xfd,
0x55, 0x69, 0x0c, 0xa1, 0xbf, 0xca, 0xad, 0xe1, 0xa8, 0x5d, 0x8e, 0xc2, 0x00, 0x0a, 0x59, 0x83,
0x09, 0x03, 0x58, 0x42, 0xe8, 0xc6, 0x00, 0x62, 0x20, 0x8d, 0x20, 0x7a, 0x7c, 0x47, 0x6d, 0x1b,
0x43, 0x9a, 0x41, 0x24, 0x7e, 0x18, 0x82, 0xeb, 0xaf, 0x4a, 0x63, 0xb4, 0x8e, 0x6a, 0xf4, 0x57,
0xa5, 0x35, 0x84, 0x01, 0x54, 0x61, 0x8d, 0x2e, 0x36, 0xc2, 0x00, 0x8a, 0xb0, 0x86, 0xd0, 0x5f,
0xe9, 0xea, 0x2f, 0x87, 0x55, 0x63, 0x00, 0xb5, 0xb1, 0x87, 0xf0, 0x06, 0x69, 0xad, 0x48, 0x5a,
0x80, 0x3a, 0x62, 0x82, 0x94, 0xbb, 0x83, 0xc2, 0xcd, 0x61, 0x49, 0x96, 0x12, 0x00, 0x61, 0x00,
0x85, 0x5b, 0xc3, 0xe6, 0x52, 0xf3, 0x4b, 0x88, 0xee, 0x32, 0x39, 0x90, 0x78, 0xea, 0x8a, 0xb0,
0x84, 0xb4, 0x40, 0xd7, 0x11, 0xc4, 0x77, 0x57, 0x76, 0x57, 0xc2, 0x02, 0x2a, 0xe3, 0xcc, 0xa4,
0x05, 0x84, 0x39, 0xb8, 0x01, 0xfe, 0xa7, 0xb4, 0x2b, 0xec, 0x8d, 0xdb, 0x56, 0xb6, 0x7f, 0x85,
0xb8, 0x0f, 0xb8, 0x70, 0xf1, 0x2a, 0x47, 0x24, 0x45, 0x4a, 0x2a, 0x52, 0x01, 0xb1, 0xfb, 0xd2,
0xe6, 0xa2, 0x49, 0x0c, 0xdb, 0xef, 0x36, 0xf7, 0xd3, 0x83, 0x2c, 0xcb, 0xce, 0x22, 0xf2, 0xae,
0xb1, 0x5a, 0x27, 0x75, 0x7e, 0xfd, 0x9b, 0x33, 0x43, 0xed, 0x4a, 0xf2, 0xd2, 0xd9, 0xa6, 0x1f,
0xbc, 0x6b, 0xad, 0xa8, 0x21, 0x39, 0xc3, 0x19, 0xce, 0x9c, 0x19, 0x49, 0x56, 0x31, 0x3b, 0x32,
0x61, 0x80, 0x0a, 0xdc, 0x08, 0xa3, 0x09, 0x63, 0x63, 0x06, 0x28, 0xe6, 0x46, 0x58, 0xe0, 0xb9,
0x9a, 0xb0, 0x43, 0x0d, 0xcb, 0x21, 0x19, 0xb4, 0x41, 0x94, 0x23, 0x99, 0x9c, 0xce, 0x1b, 0x9e,
0x7f, 0xd0, 0x0d, 0x15, 0xd4, 0x21, 0x70, 0x63, 0xda, 0xa3, 0x30, 0x40, 0x94, 0x43, 0x18, 0x90,
0x25, 0x63, 0x06, 0x84, 0x83, 0x61, 0x39, 0xc8, 0x9c, 0xd5, 0x98, 0x19, 0xe1, 0x53, 0x4c, 0x58,
0x5a, 0x26, 0xa2, 0x0e, 0x81, 0x19, 0xa2, 0x0e, 0x81, 0x97, 0x32, 0xff, 0xa0, 0x1c, 0x81, 0x01,
0xa2, 0x1c, 0x6a, 0x2a, 0x1b, 0x61, 0x80, 0x28, 0x87, 0x9a, 0xa8, 0xc3, 0x30, 0xff, 0x70, 0xb8,
0x2f, 0xc6, 0x87, 0x05, 0xf1, 0x9e, 0x02, 0x9a, 0xe6, 0xdb, 0x8b, 0xb8, 0x8f, 0x2b, 0x79, 0x64,
0x9e, 0xd1, 0x75, 0x20, 0xa6, 0x2b, 0x83, 0x38, 0x9a, 0x6f, 0x5b, 0xfc, 0x3e, 0xb6, 0x5b, 0x37,
0xdf, 0xf4, 0xb8, 0xfa, 0xa8, 0xbb, 0x7c, 0x40, 0x00, 0xf1, 0xb1, 0xad, 0xd7, 0x87, 0xc0, 0x99,
0x13, 0x50, 0x1e, 0x5b, 0x2b, 0xc3, 0xe9, 0xc7, 0x8e, 0xb6, 0x14, 0xcd, 0x6b, 0x04, 0x7b, 0x13,
0x60, 0x61, 0x44, 0xd0, 0xd4, 0xa0, 0x20, 0x6f, 0xda, 0x1c, 0x63, 0x03, 0x04, 0xa2, 0x5c, 0xd0,
0x8e, 0x20, 0xb8, 0xb9, 0x21, 0x71, 0x69, 0x03, 0xa7, 0x56, 0x53, 0xbc, 0xc1, 0xdc, 0xf3, 0x19,
0xb9, 0xc1, 0xb4, 0xb9, 0x62, 0xb3, 0x44, 0x60, 0x8b, 0x6f, 0xda, 0xa5, 0x3c, 0x02, 0x0a, 0xc3,
0x80, 0xbf, 0x2e, 0xb6, 0x56, 0xc4, 0x52, 0x58, 0x5a, 0xd0, 0x6e, 0x40, 0xd7, 0xe4, 0x0e, 0x71,
0x3c, 0x07, 0x4b, 0xb4, 0x2f, 0x0c, 0x87, 0xc6, 0xd2, 0xa8, 0x0a, 0x66, 0x75, 0x26, 0x7b, 0x80,
0xa6, 0x98, 0xd9, 0x21, 0xc2, 0xa4, 0xbe, 0xe0, 0x74, 0xd0, 0x67, 0xf8, 0x1f, 0xcb, 0x90, 0xd4,
0x10, 0x53, 0xb6, 0x0c, 0x16, 0x42, 0x31, 0xb0, 0xd5, 0x3b, 0xc4, 0xa0, 0x1a, 0x0a, 0x52, 0x92,
0xd3, 0x45, 0xbb, 0xaa, 0x71, 0x9a, 0x7d, 0x89, 0x9c, 0xf5, 0x34, 0x23, 0x43, 0x91, 0xc1, 0x41,
0xb1, 0x08, 0xe1, 0x1d, 0xf9, 0x9a, 0xb4, 0xad, 0xf9, 0x74, 0xd8, 0x09, 0x80, 0xc0, 0x38, 0x72,
0x09, 0x29, 0x92, 0x0d, 0x26, 0xdd, 0x23, 0x04, 0xc8, 0x91, 0x29, 0x08, 0x0d, 0x33, 0x2f, 0xb8,
0x09, 0x29, 0x45, 0x96, 0x2b, 0x0a, 0x9d, 0x0b, 0xf2, 0xf7, 0x43, 0x77, 0xd2, 0x7b, 0xba, 0x3d,
0x0c, 0xd3, 0x48, 0x65, 0xe8, 0xc3, 0x74, 0xd4, 0x68, 0x3a, 0x74, 0x8e, 0xf4, 0x05, 0xb1, 0x27,
0x7a, 0x86, 0x11, 0x70, 0x05, 0xbb, 0xce, 0xc2, 0x13, 0x15, 0x78, 0x82, 0xd0, 0x1f, 0xf9, 0x0e,
0x4f, 0x5a, 0xed, 0xc8, 0xef, 0x87, 0x6f, 0x01, 0xd7, 0x99, 0x24, 0x9b, 0xf9, 0x81, 0xd9, 0x6a,
0x60, 0xb6, 0x86, 0x25, 0x80, 0xcb, 0x96, 0x92, 0x96, 0x72, 0x5a, 0x22, 0x65, 0xd7, 0x01, 0xe8,
0x79, 0x0e, 0xb3, 0x26, 0x92, 0x54, 0x83, 0x24, 0x2d, 0xfc, 0x1d, 0xb2, 0xfd, 0x88, 0x15, 0x25,
0x8a, 0xe0, 0xa5, 0x20, 0xeb, 0x42, 0x0e, 0xbe, 0xbe, 0x0d, 0x53, 0x80, 0x7e, 0x34, 0xbc, 0x34,
0xca, 0x02, 0xea, 0x68, 0xe0, 0xa0, 0xc1, 0x7f, 0xf3, 0x3a, 0x0b, 0x07, 0xf2, 0x09, 0xfb, 0xe2,
0xb0, 0x70, 0x78, 0xda, 0x96, 0x9c, 0x04, 0x03, 0x47, 0x82, 0xf6, 0x2b, 0x83, 0x34, 0x03, 0xfd,
0x6e, 0x69, 0xb8, 0x96, 0xa6, 0x0c, 0xc7, 0x8d, 0xa2, 0xe9, 0x42, 0x73, 0xe8, 0x4e, 0xd6, 0x05,
0x60, 0x10, 0x19, 0xc4, 0x63, 0xef, 0x88, 0x4b, 0xe4, 0x61, 0xb0, 0x3f, 0x4e, 0x7c, 0x81, 0x97,
0x47, 0xb6, 0xd2, 0x41, 0x61, 0xca, 0x63, 0x5b, 0x80, 0xb4, 0x05, 0x24, 0x02, 0xa4, 0x0e, 0xcc,
0x0b, 0x8d, 0x93, 0xa1, 0x31, 0x85, 0xcd, 0x70, 0xd1, 0x11, 0xd7, 0x1b, 0xc0, 0xc7, 0xd2, 0x31,
0xcd, 0x1f, 0x51, 0x40, 0xb6, 0x3d, 0x1e, 0x06, 0x92, 0x0e, 0xf3, 0x4a, 0x78, 0x3e, 0x5e, 0xe6,
0x33, 0xf9, 0x2c, 0x72, 0x64, 0x60, 0x78, 0xc3, 0x24, 0xfb, 0xe6, 0x3c, 0x12, 0x21, 0x39, 0x00,
0xad, 0xd2, 0x0a, 0x8b, 0x2d, 0xb1, 0xbe, 0x04, 0x4b, 0x01, 0xf5, 0x91, 0x93, 0x04, 0xe0, 0x91,
0x46, 0x85, 0xb4, 0x0a, 0x11, 0x70, 0x00, 0x32, 0x32, 0x81, 0x6d, 0xf8, 0x88, 0x02, 0xca, 0x14,
0x81, 0x06, 0x3c, 0x55, 0xa7, 0xc3, 0xb9, 0x44, 0xce, 0x35, 0xc8, 0xc7, 0x64, 0xce, 0x23, 0xa1,
0x65, 0x69, 0xd3, 0x05, 0x1e, 0xa3, 0xd1, 0x57, 0xe8, 0x23, 0xf4, 0x39, 0x1c, 0x1f, 0x60, 0x32,
0xfa, 0x4d, 0xbd, 0x3e, 0xc0, 0x62, 0xe4, 0x44, 0x18, 0x19, 0x9a, 0x9d, 0xcd, 0x48, 0x1d, 0xdb,
0x0c, 0x84, 0x7b, 0x9a, 0x13, 0x4b, 0xb4, 0x36, 0x8c, 0x23, 0xef, 0x12, 0xe1, 0x48, 0x47, 0x3a,
0x59, 0xb2, 0xf7, 0x8a, 0x04, 0x55, 0xa9, 0xcd, 0x70, 0xac, 0xc2, 0x31, 0x5c, 0x1a, 0xd0, 0xcb,
0x78, 0xb7, 0x27, 0x16, 0x6b, 0xcd, 0xe9, 0x27, 0x24, 0x2c, 0x72, 0xa0, 0x27, 0x44, 0xd4, 0x6b,
0x60, 0x11, 0x25, 0xed, 0x52, 0xb4, 0x68, 0x72, 0xf6, 0xbe, 0x53, 0xf4, 0xe6, 0x8e, 0x41, 0x97,
0xf8, 0x08, 0x7c, 0xc2, 0xd1, 0x35, 0x65, 0x47, 0x5a, 0xc9, 0xb9, 0xad, 0x12, 0x03, 0x03, 0x1b,
0xa8, 0x0d, 0x05, 0x7d, 0xf2, 0xed, 0x1a, 0x8a, 0x7c, 0x72, 0x22, 0x23, 0x9f, 0x25, 0x6f, 0x38,
0x1a, 0x07, 0xc0, 0x49, 0x4c, 0xce, 0x2a, 0x5e, 0xea, 0xac, 0xd7, 0xb0, 0x3d, 0x46, 0x10, 0x36,
0xc3, 0xe0, 0x1c, 0x67, 0xbc, 0x32, 0x5b, 0x74, 0xa0, 0x8c, 0xe9, 0xa0, 0x23, 0x07, 0xb5, 0x35,
0x38, 0x69, 0x32, 0x86, 0x0e, 0x9b, 0x8c, 0x9d, 0xec, 0x82, 0x31, 0x3d, 0x48, 0x96, 0x11, 0x61,
0xd8, 0x1a, 0x62, 0x16, 0xa6, 0xc2, 0x47, 0xbd, 0x86, 0x85, 0x35, 0xe4, 0x9a, 0x40, 0x6d, 0xe5,
0x94, 0x92, 0x53, 0x9d, 0xd0, 0x53, 0x81, 0x9e, 0x0a, 0xbd, 0x29, 0xe9, 0xad, 0x29, 0x25, 0x88,
0x23, 0x27, 0x9b, 0xd7, 0x88, 0xc9, 0x10, 0xd9, 0x5b, 0xf8, 0x66, 0x18, 0xa2, 0x38, 0xd7, 0x45,
0x2f, 0x30, 0x17, 0x58, 0x69, 0xad, 0xcc, 0x4b, 0xc9, 0xbc, 0xba, 0x81, 0x1f, 0x2a, 0xf0, 0x43,
0x09, 0xbb, 0x54, 0x60, 0x57, 0x03, 0x56, 0x03, 0xb9, 0x02, 0x50, 0xc7, 0xfa, 0x0d, 0x55, 0x82,
0x67, 0xc7, 0x3c, 0x56, 0xc2, 0x63, 0x92, 0x79, 0xa6, 0x11, 0x87, 0x6b, 0x46, 0x19, 0x3c, 0x05,
0x28, 0x64, 0x4a, 0x2c, 0x43, 0x24, 0xa4, 0x76, 0xfc, 0xbf, 0xec, 0x92, 0xc0, 0xc4, 0x11, 0x82,
0x20, 0x79, 0x53, 0xc0, 0xef, 0xa7, 0xa1, 0xb3, 0xea, 0x61, 0x81, 0x30, 0x05, 0x5a, 0x20, 0x30,
0x38, 0x19, 0x90, 0x4b, 0x83, 0x35, 0xe4, 0x81, 0x04, 0x38, 0x07, 0x49, 0x38, 0xc4, 0x39, 0x64,
0x4e, 0x8e, 0xad, 0x04, 0x5f, 0xd4, 0x04, 0xa6, 0x02, 0x02, 0xc3, 0xce, 0x99, 0x23, 0xa2, 0x23,
0x6e, 0x51, 0x20, 0xd5, 0x69, 0xd8, 0x5f, 0x4e, 0x01, 0xca, 0xb7, 0x81, 0xa1, 0xb4, 0x1a, 0x38,
0x33, 0x2d, 0x14, 0x2c, 0xb1, 0xb4, 0x48, 0x41, 0x29, 0x63, 0x30, 0x16, 0xfe, 0x26, 0x11, 0xc9,
0xd9, 0x83, 0xf6, 0xf0, 0xae, 0x11, 0x32, 0x76, 0x0c, 0x18, 0xd2, 0x7a, 0x27, 0xd5, 0x4a, 0xb1,
0xac, 0x87, 0x63, 0x15, 0x8e, 0x11, 0xde, 0x78, 0xee, 0xd9, 0xa2, 0xaf, 0x14, 0xcc, 0xe2, 0xb8,
0xba, 0x10, 0x3a, 0x6a, 0xa0, 0x13, 0xba, 0x57, 0xd2, 0xbd, 0x92, 0x51, 0x65, 0xe1, 0xdb, 0x37,
0x2e, 0x38, 0xa6, 0xc0, 0x6b, 0x69, 0x25, 0x90, 0x53, 0xc9, 0xc2, 0x77, 0x3c, 0x25, 0x15, 0xa6,
0x14, 0xf8, 0xa0, 0x02, 0x1f, 0x94, 0xb0, 0x09, 0x18, 0x01, 0xb3, 0xa9, 0xa1, 0xae, 0x0c, 0x62,
0xf7, 0xb4, 0x00, 0x11, 0x04, 0xd5, 0xcc, 0xce, 0xc0, 0x5b, 0x39, 0x38, 0x04, 0x69, 0x5c, 0xaf,
0xfa, 0xfe, 0x90, 0x7c, 0x41, 0x26, 0xee, 0xa9, 0xb3, 0x64, 0xe9, 0x3a, 0x53, 0xd0, 0xba, 0x29,
0x81, 0xe6, 0xe2, 0x1b, 0xeb, 0x12, 0x58, 0x31, 0x7f, 0x2a, 0xf9, 0x1f, 0xae, 0x5d, 0x8a, 0x3d,
0xc0, 0x7a, 0x66, 0x65, 0xc9, 0xe8, 0xb1, 0x7c, 0xca, 0xb9, 0x70, 0xc0, 0xe7, 0x69, 0xb3, 0xee,
0x02, 0x31, 0xe0, 0xdf, 0x13, 0xe2, 0xc3, 0xef, 0x4d, 0xb2, 0xeb, 0x65, 0x1f, 0x0d, 0x58, 0x21,
0x3e, 0x54, 0xa3, 0x76, 0x6a, 0x18, 0x87, 0x92, 0x36, 0xdd, 0xb4, 0x93, 0x62, 0xde, 0x69, 0x33,
0x22, 0x91, 0xef, 0x25, 0x41, 0x2c, 0xa0, 0x25, 0x8e, 0x89, 0x6a, 0xd2, 0x43, 0xc8, 0x2c, 0x2b,
0x39, 0xab, 0x80, 0x85, 0xc2, 0x07, 0xbd, 0xb6, 0xb2, 0x8a, 0x38, 0xeb, 0x2d, 0x67, 0x12, 0x9c,
0x29, 0xbb, 0x69, 0xaf, 0x85, 0x9a, 0xf7, 0x2e, 0x84, 0x77, 0xe4, 0xc9, 0x05, 0x19, 0xd1, 0xd7,
0x51, 0xfa, 0x5a, 0xe8, 0x37, 0xe3, 0x99, 0xef, 0x93, 0x83, 0xed, 0x66, 0x5c, 0x2d, 0x0e, 0x58,
0x22, 0xf5, 0x7a, 0xbd, 0xfa, 0xc2, 0x45, 0xc2, 0x49, 0xb3, 0x58, 0x37, 0x5d, 0x7b, 0xc0, 0x72,
0x09, 0xd8, 0x39, 0xa7, 0x3c, 0x48, 0x65, 0x9a, 0x11, 0x86, 0x8e, 0x0c, 0xc7, 0x14, 0x3c, 0x57,
0x01, 0x3c, 0x1f, 0x8e, 0xfb, 0x00, 0xc8, 0x2b, 0x06, 0xe4, 0x5d, 0x38, 0x8d, 0xf2, 0x02, 0x69,
0x3e, 0x7c, 0x0b, 0x99, 0xdd, 0xf1, 0x00, 0xdc, 0x87, 0xcb, 0x84, 0x4a, 0xf9, 0xa4, 0x97, 0xe9,
0x65, 0x26, 0x99, 0x92, 0x37, 0xc9, 0x70, 0xdd, 0x24, 0x1d, 0x50, 0x6c, 0xd3, 0x01, 0xdb, 0x66,
0x93, 0x49, 0x98, 0x6d, 0x06, 0x20, 0x5c, 0x36, 0xcc, 0x61, 0xd6, 0xcb, 0xd7, 0x89, 0xcb, 0x1d,
0x32, 0x49, 0xa9, 0x24, 0x8e, 0x92, 0x71, 0x46, 0x29, 0xe1, 0xcf, 0x3e, 0xfc, 0x96, 0x8c, 0x7e,
0x93, 0x4f, 0x72, 0x00, 0xc2, 0xc5, 0x72, 0xac, 0xc6, 0x0d, 0x85, 0x44, 0x1f, 0xcb, 0x50, 0xed,
0x0b, 0xa7, 0x34, 0x0d, 0x8b, 0xd1, 0x53, 0xcd, 0x10, 0x60, 0x67, 0xc8, 0x3f, 0x24, 0x5e, 0xe1,
0x93, 0x97, 0x95, 0x0b, 0xea, 0x3d, 0x52, 0xbc, 0x62, 0xd0, 0x88, 0x54, 0xed, 0x54, 0x3f, 0x2c,
0xbc, 0xb9, 0xd6, 0x90, 0x71, 0x45, 0x9e, 0x07, 0x8e, 0xa9, 0x47, 0xbe, 0xd0, 0x7f, 0x74, 0x86,
0x33, 0x48, 0xcd, 0x50, 0x17, 0xf0, 0x6c, 0xc9, 0xc1, 0xbc, 0xc0, 0xe8, 0x63, 0x12, 0x2e, 0xef,
0x02, 0x39, 0x15, 0xc8, 0x37, 0xbb, 0x91, 0xb8, 0xfd, 0x23, 0x49, 0x32, 0x1e, 0x25, 0x7f, 0x26,
0xac, 0x64, 0x39, 0xeb, 0x95, 0x87, 0x11, 0x87, 0x32, 0xf2, 0x41, 0x9f, 0x8c, 0xb5, 0x2c, 0x9c,
0x4a, 0x72, 0x66, 0x4d, 0x32, 0xe6, 0x0d, 0xed, 0x03, 0xc1, 0x0a, 0xd1, 0x3f, 0xdc, 0x95, 0x11,
0x6d, 0xd3, 0x7f, 0x41, 0xb9, 0xb8, 0xe4, 0xfd, 0x70, 0xed, 0x2a, 0xe0, 0xb3, 0x23, 0x1e, 0x08,
0xda, 0x95, 0x4c, 0xd4, 0x2b, 0x96, 0x9b, 0xda, 0xaa, 0x57, 0x32, 0xd5, 0xaf, 0x99, 0x02, 0x64,
0xc9, 0x4c, 0xbf, 0x66, 0x0a, 0xe4, 0xd5, 0x54, 0xbf, 0x66, 0xea, 0x57, 0xcc, 0xd4, 0xd2, 0xcc,
0xd4, 0xd7, 0xa8, 0xa9, 0x7e, 0xcd, 0x94, 0xdf, 0xa8, 0x99, 0x7e, 0xcd, 0x14, 0xa8, 0x48, 0xa6,
0xfa, 0x95, 0x3c, 0xab, 0x5f, 0x33, 0x1d, 0xd9, 0xa3, 0x4c, 0xfd, 0x53, 0xb5, 0x09, 0xfa, 0x35,
0xd5, 0xcd, 0x3d, 0xd9, 0xde, 0x7e, 0x8f, 0xbe, 0xc6, 0xf5, 0x2b, 0x2f, 0x3c, 0xaf, 0xae, 0x41,
0xbf, 0xa6, 0x8b, 0x68, 0xa4, 0x61, 0xe3, 0xad, 0xad, 0xd8, 0x6e, 0x8f, 0xa3, 0xcd, 0x35, 0x4f,
0xf6, 0x6b, 0xd8, 0x5c, 0xc1, 0x06, 0x15, 0x99, 0x95, 0xde, 0xa8, 0x51, 0x39, 0xd0, 0xae, 0x2c,
0x61, 0x5c, 0x52, 0x23, 0x1a, 0x36, 0x28, 0x58, 0x32, 0xd7, 0xb0, 0xd1, 0x50, 0xdc, 0xfe, 0xa1,
0xa8, 0x91, 0x8a, 0xa9, 0xb1, 0x8a, 0xa9, 0x89, 0x8a, 0xcd, 0xf7, 0xb1, 0x9d, 0x86, 0x8d, 0x79,
0x33, 0xe8, 0x97, 0xfa, 0x2e, 0xfd, 0x5a, 0xaf, 0x9a, 0x4f, 0xed, 0x21, 0x48, 0x88, 0x47, 0x1c,
0xa8, 0xa4, 0xb8, 0x31, 0xc9, 0x69, 0x8d, 0x71, 0x41, 0x04, 0x92, 0x01, 0x2e, 0xe7, 0x2c, 0xa3,
0xe6, 0x0c, 0x51, 0xd1, 0xef, 0x0e, 0x55, 0xf8, 0x09, 0xdf, 0x4a, 0x7e, 0x56, 0xc3, 0xcf, 0xbb,
0xc3, 0xa1, 0xc5, 0xd7, 0xd0, 0x05, 0x97, 0x04, 0x4d, 0x8a, 0x52, 0x9e, 0x14, 0xde, 0xf4, 0xf3,
0x72, 0x9b, 0x67, 0x6a, 0x50, 0x9e, 0xd4, 0x2e, 0xf1, 0xc7, 0xbe, 0x15, 0x08, 0xa9, 0x22, 0x19,
0xc5, 0x35, 0x1f, 0x9e, 0xcb, 0xed, 0x52, 0x0e, 0x3f, 0xb9, 0x76, 0x02, 0x31, 0x16, 0xfb, 0x12,
0x5e, 0x7c, 0x09, 0x04, 0x9d, 0x14, 0x48, 0xc9, 0x27, 0x45, 0x01, 0xce, 0x49, 0xe4, 0x69, 0x28,
0x06, 0x2b, 0x1d, 0x3b, 0x60, 0xe4, 0x79, 0xe6, 0x05, 0x47, 0x52, 0x06, 0x29, 0x84, 0xac, 0xe0,
0x25, 0x02, 0x42, 0xd6, 0x48, 0xc9, 0x9f, 0x41, 0x51, 0x22, 0x2c, 0xcc, 0x70, 0x9c, 0x1f, 0x17,
0x80, 0x98, 0x90, 0xf9, 0x29, 0x51, 0x53, 0x81, 0x72, 0x13, 0x80, 0x1c, 0xce, 0x7b, 0x65, 0x9d,
0x94, 0x88, 0xe4, 0x0c, 0x43, 0x0d, 0x5f, 0xe4, 0x58, 0x6b, 0x72, 0x7c, 0x32, 0x2e, 0xd3, 0xb4,
0xb4, 0x62, 0x68, 0xa5, 0x96, 0x52, 0x05, 0x2a, 0xa9, 0x94, 0x9c, 0xa3, 0xee, 0x04, 0x78, 0x87,
0x46, 0xfa, 0x8e, 0xec, 0x42, 0x41, 0xc1, 0xa1, 0x35, 0x52, 0x8b, 0x83, 0x4a, 0x94, 0x82, 0x57,
0x59, 0x81, 0x72, 0x40, 0x4e, 0x63, 0x90, 0xeb, 0xad, 0xf1, 0x3f, 0x12, 0x05, 0x34, 0x01, 0x94,
0x33, 0xe0, 0xff, 0xaf, 0x6f, 0x4d, 0x86, 0x22, 0x11, 0x04, 0xee, 0xd4, 0x9f, 0x43, 0x90, 0xed,
0xf0, 0x1d, 0xb2, 0xfa, 0xa5, 0xa4, 0x59, 0xb3, 0x84, 0x54, 0xd9, 0x14, 0x06, 0xe5, 0x22, 0xc6,
0x72, 0xea, 0x16, 0x49, 0x8f, 0x8c, 0xc2, 0x0b, 0x46, 0xbc, 0x0c, 0x62, 0xbf, 0x54, 0x22, 0x08,
0x92, 0xb8, 0xe3, 0xac, 0x07, 0x62, 0xbd, 0x1c, 0x38, 0xa3, 0x75, 0x9c, 0x15, 0x45, 0xe4, 0x07,
0x80, 0x02, 0x01, 0x0d, 0x3c, 0x7c, 0x30, 0xc3, 0x23, 0x7c, 0xa0, 0x58, 0xc7, 0xb2, 0x37, 0xeb,
0x32, 0xb0, 0x34, 0xb1, 0x39, 0x03, 0xd8, 0x79, 0xca, 0xd8, 0x9b, 0xf7, 0x1c, 0x39, 0x12, 0x3b,
0x72, 0x24, 0x0f, 0x33, 0x29, 0x04, 0x15, 0x34, 0x8d, 0x86, 0x9e, 0x43, 0x92, 0x96, 0x4d, 0xfa,
0xb1, 0x2f, 0x8c, 0x20, 0x21, 0xd4, 0x01, 0x49, 0x05, 0xa6, 0x12, 0x31, 0x83, 0x1f, 0xbe, 0x90,
0x54, 0x02, 0xfe, 0x93, 0x42, 0x3d, 0x91, 0xf5, 0x41, 0x76, 0x88, 0x0f, 0xe2, 0xf5, 0x7c, 0x48,
0x65, 0xa3, 0xde, 0x34, 0x13, 0x63, 0x42, 0x73, 0x75, 0x1e, 0x4c, 0x71, 0x80, 0x08, 0xe9, 0xb0,
0xa4, 0x90, 0x95, 0x86, 0x88, 0x48, 0xbd, 0x30, 0xac, 0xb4, 0xd6, 0x4b, 0x96, 0x9b, 0x66, 0xc3,
0x00, 0x7c, 0xc1, 0x30, 0xb4, 0xd1, 0xb8, 0xb4, 0x10, 0x61, 0x15, 0x1c, 0x5f, 0x72, 0xc4, 0x6c,
0xc4, 0x35, 0x4d, 0xb9, 0xec, 0xd4, 0x20, 0x04, 0x46, 0x28, 0xcf, 0x89, 0x10, 0x14, 0xe6, 0x16,
0x14, 0x1d, 0x02, 0x5a, 0xa3, 0x73, 0xa8, 0x0a, 0x4d, 0x50, 0x17, 0x82, 0xa2, 0xd1, 0x94, 0x6b,
0x83, 0x91, 0x18, 0x43, 0x54, 0x4d, 0x32, 0x42, 0x51, 0x00, 0x42, 0x30, 0x29, 0x09, 0xe6, 0x72,
0x2f, 0x04, 0xce, 0x3e, 0xec, 0x67, 0x40, 0x82, 0xb8, 0xe2, 0x25, 0xe5, 0xe0, 0x0d, 0x08, 0x99,
0xe7, 0xb5, 0x0c, 0xfc, 0x8c, 0x4c, 0x1c, 0x80, 0x30, 0x85, 0x21, 0x97, 0x58, 0x58, 0xa9, 0x45,
0x5d, 0x0c, 0x83, 0x4c, 0xc8, 0xde, 0x40, 0x8b, 0x38, 0x6d, 0x88, 0x64, 0x3c, 0x82, 0x2d, 0x0c,
0xb4, 0xd0, 0x08, 0x0b, 0x01, 0x18, 0x03, 0xaf, 0xe7, 0x0a, 0x06, 0x4e, 0xf2, 0xf2, 0x2c, 0xcb,
0xe3, 0xdc, 0xc1, 0xab, 0x07, 0x24, 0x84, 0x64, 0x62, 0x69, 0xc2, 0x01, 0x4d, 0x49, 0x70, 0x4a,
0x1b, 0x10, 0x75, 0x29, 0xb6, 0x4d, 0x3d, 0xf4, 0x0e, 0xe1, 0x77, 0x8a, 0x10, 0x1f, 0x85, 0x1c,
0x19, 0x83, 0xea, 0x5a, 0x00, 0xa2, 0x92, 0x99, 0x9c, 0x21, 0x12, 0xcf, 0x91, 0x9a, 0x64, 0xfb,
0xc1, 0xd8, 0x49, 0x86, 0x24, 0x4f, 0x2e, 0xa9, 0x49, 0xc3, 0x15, 0x50, 0xda, 0x89, 0x46, 0x92,
0x22, 0x32, 0x26, 0xe6, 0x39, 0x1c, 0xcf, 0x78, 0xbd, 0x2b, 0x9a, 0x38, 0xa0, 0x79, 0x5a, 0xa4,
0x9c, 0xd2, 0xa2, 0xa1, 0xd1, 0x5a, 0x07, 0x77, 0x50, 0x62, 0x6b, 0x38, 0x85, 0x18, 0xbe, 0x50,
0x17, 0x46, 0x01, 0x2d, 0x30, 0x42, 0x3b, 0x34, 0x31, 0x72, 0x05, 0x97, 0x49, 0x67, 0x5c, 0x3c,
0x85, 0x04, 0x29, 0x76, 0x0d, 0xa4, 0xbf, 0xb9, 0xac, 0x57, 0xba, 0x35, 0x61, 0x14, 0x9a, 0x53,
0x22, 0x52, 0x52, 0x91, 0x93, 0x09, 0xa1, 0xd1, 0xfb, 0xc2, 0x63, 0x2e, 0x9c, 0x05, 0xc8, 0x91,
0x05, 0xc0, 0xc4, 0x2c, 0xd2, 0xe2, 0x05, 0x29, 0x08, 0x7f, 0x62, 0x71, 0xa0, 0x38, 0x0b, 0x38,
0x09, 0x0a, 0xe2, 0x68, 0xc8, 0x21, 0x85, 0x93, 0x62, 0x87, 0x71, 0xc8, 0x98, 0x16, 0x9c, 0x30,
0xcd, 0x73, 0xce, 0x3c, 0x5a, 0x2e, 0xa7, 0xca, 0xd1, 0xad, 0x1c, 0x09, 0x84, 0x99, 0x2a, 0x51,
0x10, 0x52, 0xa4, 0x9c, 0x77, 0xa5, 0x8c, 0xab, 0x14, 0xf2, 0x94, 0x51, 0x4c, 0x64, 0xd3, 0x68,
0x88, 0xa5, 0x2a, 0x18, 0xec, 0xc9, 0x00, 0x49, 0x6f, 0x45, 0x3e, 0x2c, 0x81, 0xcc, 0x33, 0x42,
0x6d, 0x73, 0xf6, 0x77, 0x48, 0x4f, 0x3d, 0xac, 0xa5, 0x93, 0x6c, 0x47, 0x58, 0x4c, 0xb2, 0xb8,
0x38, 0xff, 0x47, 0x0b, 0x3d, 0x73, 0x40, 0xc9, 0x01, 0xb3, 0xa0, 0xf2, 0xa3, 0x4c, 0xb1, 0x34,
0x87, 0x15, 0x2a, 0x0b, 0xd6, 0x4a, 0xc4, 0x0e, 0x34, 0x0a, 0x55, 0xae, 0x24, 0x5f, 0xe4, 0xce,
0x29, 0x36, 0x03, 0xc4, 0x22, 0x6b, 0xde, 0x48, 0x5e, 0xd4, 0x67, 0x6c, 0x1e, 0x5c, 0xce, 0xd2,
0x02, 0x8e, 0x8b, 0xc5, 0x01, 0x3c, 0x00, 0x60, 0x8a, 0xa8, 0x92, 0xdd, 0xaa, 0x16, 0x29, 0x0a,
0xc6, 0x0a, 0x43, 0xe4, 0x61, 0xab, 0x3c, 0xd7, 0xbb, 0x1b, 0x50, 0x26, 0xf9, 0x84, 0xc3, 0xa0,
0xb3, 0x9f, 0xa5, 0xd8, 0x56, 0x4a, 0x0c, 0xdf, 0x6a, 0x57, 0x72, 0x30, 0x4b, 0xb6, 0x1e, 0x96,
0xb5, 0xa1, 0xc8, 0x1f, 0x75, 0x62, 0xb0, 0x40, 0x62, 0xb2, 0x8a, 0x8c, 0x41, 0x54, 0xf6, 0x01,
0xd3, 0x5c, 0x50, 0x09, 0x98, 0x44, 0xcb, 0x89, 0x46, 0x43, 0x93, 0x77, 0x92, 0xcb, 0x01, 0xa6,
0x0e, 0xfc, 0x43, 0x6b, 0x06, 0xf7, 0x9c, 0x67, 0x5b, 0xae, 0x89, 0x29, 0x8e, 0x96, 0x8d, 0x2b,
0xb9, 0xee, 0xcc, 0x0a, 0x72, 0x03, 0xf6, 0x79, 0x06, 0xb2, 0x0a, 0x9a, 0x3f, 0x6a, 0xc5, 0x2d,
0x43, 0xed, 0x3e, 0x47, 0xb6, 0xd8, 0xa0, 0xf8, 0x4a, 0x15, 0xc4, 0x02, 0xda, 0x6e, 0x1a, 0x9a,
0x44, 0x4e, 0x2e, 0x1f, 0x84, 0xe4, 0xc0, 0x24, 0x76, 0x44, 0x34, 0xef, 0x8b, 0xb8, 0x42, 0x0b,
0x01, 0xd4, 0x0e, 0xd0, 0x78, 0x70, 0x4b, 0x00, 0x97, 0xc6, 0x43, 0x33, 0x38, 0x05, 0x6e, 0x45,
0x15, 0x30, 0x0c, 0xec, 0xd4, 0xc4, 0xe4, 0x92, 0x2b, 0x8a, 0x00, 0x29, 0x17, 0x5c, 0x08, 0x84,
0x4a, 0x46, 0x0b, 0x26, 0xa3, 0x58, 0xb8, 0xe4, 0xd9, 0x01, 0xd0, 0xc7, 0x6c, 0xad, 0x76, 0x5f,
0xdf, 0xe6, 0x39, 0x17, 0x57, 0x29, 0x87, 0x19, 0x02, 0x18, 0x02, 0xfc, 0x4a, 0x46, 0x91, 0xfc,
0xf1, 0x12, 0x3a, 0x00, 0x4c, 0x91, 0xd7, 0x84, 0xe3, 0xed, 0x0f, 0x98, 0x32, 0x14, 0x6d, 0x38,
0x4e, 0x99, 0xbf, 0xc8, 0x1a, 0x91, 0x7c, 0x35, 0xf4, 0xdb, 0xc2, 0x5e, 0xa1, 0xb0, 0x80, 0x0b,
0x01, 0x19, 0xc2, 0xce, 0xe1, 0x3a, 0x58, 0x96, 0x29, 0xe9, 0x32, 0xac, 0x39, 0x4d, 0xc6, 0xeb,
0x02, 0x88, 0x2f, 0xd2, 0xcc, 0x8e, 0xb3, 0x34, 0xc4, 0x18, 0x74, 0xc0, 0x9f, 0xa8, 0x54, 0x42,
0x6b, 0xd2, 0x0a, 0xd9, 0x55, 0xd0, 0x80, 0x5b, 0xf3, 0x4e, 0x50, 0x02, 0xdd, 0x47, 0xb1, 0xbf,
0x1b, 0x7a, 0xa1, 0x3e, 0x73, 0x22, 0xb5, 0x3b, 0x42, 0xed, 0x56, 0x2a, 0xb0, 0x27, 0xa2, 0xf4,
0xb0, 0xc0, 0x3c, 0xe7, 0x8b, 0x65, 0xf0, 0xf9, 0x68, 0x32, 0x86, 0xf3, 0xe9, 0x1a, 0xbb, 0x19,
0xf4, 0x93, 0xac, 0x81, 0x43, 0x41, 0x15, 0x90, 0x7c, 0xd4, 0x17, 0xd1, 0x8e, 0x51, 0xc0, 0x51,
0x4f, 0x0d, 0xeb, 0xb7, 0x63, 0x5c, 0x93, 0x37, 0x56, 0xf2, 0x51, 0x32, 0x6c, 0xd2, 0xb4, 0xbb,
0x0b, 0x0c, 0x27, 0x6d, 0xb6, 0xd7, 0x1c, 0x82, 0x56, 0x3f, 0x2e, 0x9b, 0x6f, 0x78, 0x75, 0xd4,
0x92, 0x1f, 0xbe, 0x24, 0xe1, 0x2d, 0x85, 0x12, 0x6c, 0x92, 0x33, 0x30, 0xb3, 0x0c, 0x2e, 0xf7,
0x37, 0x10, 0x29, 0x92, 0x7e, 0x61, 0x79, 0x35, 0xd3, 0x17, 0xca, 0xeb, 0x90, 0xbc, 0x4a, 0x81,
0x9c, 0xf2, 0x46, 0x54, 0xe2, 0x36, 0x83, 0x14, 0x45, 0x5d, 0x9c, 0x1b, 0xa0, 0x05, 0x4b, 0xab,
0x88, 0x74, 0x87, 0x73, 0xf0, 0xb4, 0x15, 0xc9, 0x17, 0xf9, 0x4d, 0x45, 0x2a, 0x39, 0x13, 0x4e,
0x35, 0x31, 0xf2, 0x02, 0x42, 0x72, 0x04, 0xbd, 0x35, 0xbc, 0x9d, 0xc2, 0x0c, 0x13, 0x4f, 0x60,
0x56, 0x90, 0x31, 0xf7, 0x70, 0x11, 0x81, 0x3d, 0x16, 0x5c, 0xc1, 0xe9, 0x25, 0x13, 0x15, 0xc2,
0xd1, 0x63, 0xb9, 0xeb, 0x04, 0x95, 0x6b, 0x30, 0x72, 0x9e, 0x6b, 0x49, 0x5c, 0x99, 0x4b, 0x83,
0x42, 0x49, 0xeb, 0xa1, 0x05, 0x5a, 0xcb, 0xf9, 0x24, 0xb4, 0x06, 0x71, 0x0c, 0x21, 0x07, 0x2c,
0xcc, 0x77, 0x9e, 0xb0, 0x67, 0x80, 0x21, 0x78, 0xdc, 0xe4, 0xc2, 0xc9, 0x98, 0xed, 0xb1, 0x2e,
0x25, 0xa2, 0x43, 0x01, 0xa6, 0x91, 0xb2, 0x32, 0x6c, 0x8e, 0xec, 0xb3, 0x49, 0x4d, 0xaa, 0x85,
0x2d, 0xd7, 0x25, 0xb3, 0xcc, 0xd1, 0x54, 0xe5, 0xeb, 0x00, 0x26, 0x4f, 0x40, 0xc3, 0x7d, 0xc1,
0x84, 0xeb, 0xc6, 0x59, 0xd3, 0xbf, 0x09, 0x90, 0x75, 0xa3, 0x2c, 0x6a, 0x0c, 0x2c, 0x73, 0x5b,
0xb0, 0x6c, 0xee, 0x07, 0x85, 0x05, 0x65, 0x24, 0x06, 0xf7, 0x5c, 0xbc, 0x4c, 0x96, 0x94, 0xd3,
0xa5, 0x5c, 0xe3, 0x07, 0xef, 0x18, 0x9c, 0xb7, 0xb0, 0x26, 0x41, 0x4c, 0x88, 0x4c, 0x45, 0x32,
0xcc, 0x79, 0x38, 0x1b, 0x16, 0x01, 0x01, 0xb3, 0x1e, 0x6b, 0x83, 0x59, 0xaf, 0x84, 0xd5, 0x28,
0xd4, 0x95, 0x3c, 0xd8, 0x70, 0x2c, 0xac, 0x67, 0x00, 0xcf, 0x49, 0x07, 0x81, 0xf5, 0x49, 0x60,
0x7d, 0xc2, 0xac, 0x37, 0xba, 0x13, 0x96, 0xab, 0xc0, 0x79, 0xf2, 0x1f, 0x47, 0x00, 0x65, 0x39,
0x06, 0x28, 0xcb, 0x38, 0x40, 0xd9, 0x8c, 0x71, 0xcf, 0xb1, 0xd4, 0x46, 0x00, 0xe2, 0x98, 0x85,
0xdf, 0x86, 0x64, 0xbb, 0x71, 0x36, 0xfc, 0x00, 0x74, 0xb5, 0x0f, 0xc7, 0xe5, 0xe0, 0x3d, 0x0a,
0x15, 0x56, 0xc1, 0xa0, 0x8f, 0x0d, 0xf4, 0x50, 0x89, 0x1e, 0xf2, 0x3e, 0x57, 0xa2, 0x94, 0x80,
0xf5, 0xd0, 0xa8, 0xa0, 0x88, 0x4a, 0x14, 0x91, 0xef, 0x2b, 0xe2, 0x4a, 0xf3, 0x5c, 0xb6, 0x5a,
0xd6, 0xc4, 0x4c, 0x89, 0xee, 0x29, 0xd1, 0x44, 0x33, 0x1c, 0x0e, 0xaa, 0xa8, 0x44, 0x15, 0x13,
0xd1, 0x44, 0x15, 0x34, 0x31, 0x09, 0x9a, 0xc8, 0xba, 0x55, 0x88, 0xb8, 0x35, 0x74, 0x0b, 0xf7,
0x46, 0x89, 0xb8, 0x45, 0xc2, 0x2c, 0xef, 0x43, 0x62, 0x53, 0x7e, 0x7e, 0xcb, 0x5d, 0xbd, 0xfe,
0x74, 0x38, 0xf2, 0x23, 0xe0, 0x46, 0x28, 0xdb, 0x3f, 0xac, 0x80, 0x39, 0xeb, 0x67, 0x45, 0xcb,
0xd9, 0x0c, 0x18, 0xf2, 0x28, 0xdd, 0x67, 0x5a, 0x76, 0x40, 0x84, 0xa6, 0xe0, 0xe5, 0xb6, 0x61,
0x2f, 0x04, 0xec, 0x1c, 0x11, 0x1a, 0x8e, 0x9b, 0xed, 0x90, 0xd4, 0xf3, 0x10, 0x6e, 0x7f, 0x10,
0x84, 0x9b, 0xa9, 0x29, 0xc8, 0xb3, 0x3d, 0x3d, 0x00, 0x5e, 0x4a, 0x6a, 0xb2, 0x67, 0x44, 0xe6,
0x78, 0xd6, 0xd7, 0x1d, 0xd7, 0xb0, 0x04, 0xbf, 0x1f, 0x36, 0x8d, 0xa2, 0xb4, 0x51, 0x90, 0x76,
0x5f, 0x24, 0x05, 0xdf, 0x23, 0xcf, 0x78, 0x28, 0x9e, 0xe3, 0x9c, 0xf4, 0x09, 0xd4, 0xb8, 0x4b,
0x18, 0x8c, 0x8b, 0x58, 0xa6, 0xd6, 0x74, 0xaf, 0x76, 0xee, 0x49, 0x7d, 0x24, 0x33, 0x4d, 0x42,
0x61, 0x0d, 0x1b, 0xcc, 0xf0, 0x6d, 0x43, 0x39, 0x83, 0x7c, 0x17, 0xcd, 0x53, 0xdd, 0x1c, 0x53,
0x98, 0x62, 0xbd, 0xc5, 0x5e, 0x84, 0xd5, 0x75, 0x6c, 0x9b, 0xb2, 0xe1, 0x56, 0xab, 0x90, 0x2f,
0x49, 0x46, 0xf9, 0x92, 0x64, 0x9c, 0x2f, 0x39, 0x18, 0x25, 0xbd, 0x5e, 0x7d, 0x59, 0xfe, 0x55,
0x90, 0xd4, 0x53, 0xc8, 0x89, 0x1b, 0x01, 0x8b, 0x59, 0x0a, 0x62, 0x56, 0xc7, 0x3f, 0x5b, 0x3b,
0x45, 0x9f, 0x4c, 0x35, 0x61, 0xae, 0x32, 0x31, 0x55, 0xda, 0xa9, 0x5a, 0x00, 0x47, 0x27, 0x10,
0x6b, 0x31, 0x83, 0x58, 0xcd, 0x0c, 0x62, 0x35, 0x53, 0x88, 0x35, 0x9b, 0x41, 0xac, 0x66, 0x06,
0xb1, 0xfa, 0x27, 0xbf, 0x4f, 0x21, 0xd6, 0x7c, 0x0a, 0xb1, 0x6e, 0x53, 0x15, 0x48, 0xce, 0xd2,
0x6a, 0xe6, 0x54, 0x1e, 0xe9, 0xfe, 0xe4, 0x76, 0x96, 0xa7, 0x40, 0x68, 0x1f, 0xc3, 0x3f, 0x9b,
0xe1, 0x4e, 0x98, 0x28, 0x0e, 0xda, 0x47, 0xd5, 0x63, 0x6f, 0x41, 0x57, 0x9a, 0xf1, 0x86, 0x54,
0x58, 0x2e, 0x12, 0x7b, 0x92, 0x81, 0x90, 0x75, 0xed, 0xf6, 0x27, 0xb6, 0x46, 0x5a, 0x11, 0x41,
0x50, 0x9f, 0x00, 0x99, 0x9f, 0xb7, 0x00, 0xe9, 0x70, 0x1f, 0xf4, 0x93, 0x3b, 0x25, 0xe5, 0xd6,
0xc4, 0x11, 0x6c, 0x3a, 0xba, 0x41, 0xf1, 0xf3, 0x04, 0x20, 0xd5, 0x5c, 0xb2, 0xc4, 0xf4, 0x0f,
0x41, 0x73, 0xc7, 0x39, 0x88, 0x80, 0x8c, 0x32, 0x4c, 0x9a, 0x8c, 0x61, 0xd2, 0x3e, 0x6c, 0xd0,
0x36, 0xe8, 0x0a, 0xef, 0x37, 0x7c, 0x46, 0x78, 0xa3, 0x76, 0xbc, 0x81, 0x7b, 0xa1, 0x02, 0x3a,
0xaa, 0x59, 0x0f, 0x35, 0xee, 0xa2, 0xdd, 0xab, 0x5a, 0x2f, 0xe4, 0x26, 0xf4, 0x97, 0x7c, 0x4b,
0xfa, 0xcb, 0xeb, 0xc5, 0x67, 0x68, 0xd9, 0xe6, 0xea, 0x24, 0xdc, 0x26, 0x8f, 0x47, 0x03, 0xe1,
0x61, 0x5a, 0xe1, 0xce, 0x78, 0x9c, 0xbb, 0xbd, 0x52, 0xab, 0x65, 0xd3, 0x2d, 0x9a, 0x4f, 0x3f,
0xf3, 0xb3, 0x3d, 0xab, 0x97, 0x0f, 0x7d, 0xab, 0xfe, 0xc4, 0x5b, 0x98, 0x7e, 0xe2, 0xf7, 0x2b,
0xfd, 0xd7, 0xfc, 0x7e, 0x75, 0xea, 0x8f, 0x9a, 0x54, 0x2f, 0xc3, 0x6d, 0xef, 0x81, 0xd0, 0xdd,
0xf5, 0x98, 0x10, 0x3f, 0x2d, 0x73, 0x3f, 0x29, 0xdc, 0x8c, 0xbb, 0x9f, 0xc4, 0x7d, 0xbf, 0x23,
0x71, 0xfa, 0xef, 0x23, 0x13, 0x21, 0xc0, 0xf5, 0x6f, 0xfb, 0x29, 0xdc, 0xfc, 0x39, 0xa1, 0x60,
0x23, 0x14, 0x50, 0x0e, 0xb3, 0x9f, 0xc0, 0xb2, 0x9b, 0x10, 0xc8, 0x22, 0x04, 0x70, 0x23, 0x5e,
0x84, 0x40, 0x3f, 0x66, 0xc3, 0xbb, 0x18, 0x13, 0x10, 0xe2, 0xec, 0x27, 0xd0, 0x6f, 0xc6, 0x04,
0x2e, 0x62, 0x04, 0x9a, 0xd5, 0xed, 0xe4, 0x7a, 0x92, 0xfc, 0xe2, 0xf3, 0x56, 0xe2, 0xcd, 0xf5,
0x20, 0xf1, 0xe1, 0xf1, 0x69, 0xd5, 0x4b, 0x3c, 0xf2, 0x87, 0x79, 0x44, 0xdf, 0xff, 0xd7, 0xc8,
0x5b, 0xb8, 0x4e, 0x6f, 0xa8, 0xe3, 0xab, 0xf5, 0xf6, 0xba, 0xbe, 0x7b, 0x15, 0xae, 0xeb, 0xb1,
0x9a, 0xf8, 0x69, 0x11, 0x6a, 0xf7, 0xb4, 0x08, 0xc5, 0x2f, 0xd2, 0xfa, 0xf9, 0x84, 0x53, 0x5a,
0xcb, 0xb6, 0xef, 0x87, 0xc6, 0xd7, 0xbd, 0xd0, 0xbb, 0x78, 0xa5, 0xc2, 0x53, 0x5f, 0xd5, 0xdd,
0x62, 0x89, 0xcf, 0xfa, 0x4f, 0x3c, 0x4d, 0x5d, 0xf5, 0x9b, 0xf6, 0xfe, 0x67, 0x8d, 0x89, 0xc9,
0x0b, 0x8d, 0xf0, 0x44, 0xf1, 0xd9, 0x98, 0xf1, 0xe8, 0xea, 0xd1, 0x40, 0xce, 0x0f, 0x18, 0xc8,
0x3f, 0xce, 0xdb, 0x6b, 0xc5, 0xaf, 0x1d, 0xf8, 0xc7, 0x93, 0x91, 0x9c, 0xff, 0x8d, 0x91, 0x74,
0xbf, 0x1e, 0xd2, 0xf9, 0xaf, 0x78, 0xc0, 0x57, 0xac, 0xfb, 0x5f, 0xff, 0x4e, 0xf7, 0x27, 0x87,
0x74, 0x7f, 0x42, 0xe4, 0x63, 0xbd, 0x9f, 0x7c, 0x47, 0xef, 0xd3, 0x31, 0x7c, 0xec, 0x47, 0xe3,
0xf9, 0xed, 0x80, 0xf1, 0xfc, 0x46, 0xa3, 0x99, 0x0f, 0xe3, 0xb7, 0x3d, 0xc3, 0xd0, 0x32, 0x88,
0xf4, 0x38, 0x35, 0x6e, 0x34, 0x90, 0xf0, 0xd0, 0xfe, 0x27, 0xac, 0xb8, 0x38, 0xa0, 0xeb, 0x8b,
0x7a, 0xf3, 0xb0, 0xae, 0xf9, 0x19, 0x86, 0xf3, 0x11, 0x5c, 0x7c, 0xf7, 0x08, 0x66, 0xe3, 0xf8,
0xe3, 0x10, 0x91, 0xfc, 0x81, 0xe7, 0xa0, 0xc5, 0x64, 0xf2, 0xc7, 0xf7, 0xaf, 0x88, 0x4d, 0xf7,
0x61, 0x64, 0xc0, 0xc9, 0xbe, 0xff, 0xcf, 0xcd, 0x4d, 0xdb, 0x6c, 0xd4, 0x59, 0xbd, 0x6c, 0x3b,
0xd6, 0x5f, 0xfa, 0xdb, 0x19, 0xc1, 0xbb, 0xf5, 0xd6, 0x82, 0xf0, 0x53, 0x95, 0x93, 0xb2, 0x8c,
0x59, 0x11, 0x54, 0x08, 0x45, 0x4c, 0xe9, 0x6a, 0x4e, 0x45, 0x47, 0x88, 0x3c, 0xa9, 0x21, 0x89,
0x10, 0xbc, 0xbb, 0x99, 0x12, 0x7c, 0x9e, 0xde, 0x38, 0x6d, 0x1e, 0x1b, 0xe1, 0x8c, 0x60, 0x74,
0x9a, 0x92, 0x28, 0x9c, 0xda, 0xcb, 0x1d, 0xd7, 0xf8, 0x71, 0x5c, 0x22, 0xa4, 0xcb, 0x0f, 0x23,
0x39, 0x7c, 0x80, 0x1c, 0x56, 0xf7, 0xbc, 0xae, 0x06, 0xd1, 0x0d, 0x8f, 0x89, 0xae, 0x2e, 0xf8,
0xf1, 0x56, 0x47, 0xe9, 0x0f, 0x2f, 0x5f, 0x48, 0x93, 0x59, 0x53, 0x5d, 0x9d, 0xf0, 0x8b, 0x0c,
0x69, 0x96, 0x91, 0x16, 0xa6, 0x3a, 0x59, 0xb7, 0xf0, 0x8f, 0x68, 0xa3, 0x8b, 0x34, 0xb1, 0xd5,
0x1f, 0x8b, 0xfb, 0x56, 0xd1, 0x3e, 0x16, 0x69, 0x90, 0x49, 0x83, 0x73, 0x7e, 0xbf, 0x9c, 0xa2,
0xed, 0x2a, 0xd2, 0xce, 0x55, 0xa7, 0xfc, 0xa6, 0xc5, 0x73, 0x75, 0xe4, 0x62, 0x6d, 0x7c, 0x75,
0xf1, 0xa5, 0x6d, 0xef, 0xd5, 0x91, 0x8f, 0xb5, 0xc8, 0xab, 0x5f, 0x1e, 0x89, 0x4d, 0x8b, 0x46,
0x1d, 0xe5, 0xb1, 0x36, 0x85, 0xf4, 0xd4, 0xad, 0x56, 0x44, 0xa9, 0x88, 0xb5, 0x2a, 0xab, 0xf3,
0x7a, 0xb1, 0xbc, 0x5a, 0x7d, 0x51, 0x47, 0x65, 0x94, 0x83, 0x69, 0x75, 0xd1, 0xd4, 0x4b, 0xe2,
0x60, 0x9c, 0xc9, 0x5a, 0x9a, 0xfc, 0x69, 0xa8, 0x55, 0x94, 0xd1, 0xda, 0x54, 0xaf, 0xeb, 0x6b,
0x62, 0xa3, 0x8e, 0x32, 0x5a, 0xdb, 0xea, 0xf4, 0x23, 0x1e, 0xd8, 0x7a, 0xa4, 0xa3, 0xbc, 0xd6,
0x59, 0x68, 0x73, 0xda, 0x51, 0xb3, 0x28, 0xab, 0xb5, 0xab, 0xce, 0x1f, 0x96, 0xcb, 0xc5, 0xf2,
0x96, 0x5a, 0x45, 0x99, 0xad, 0x7d, 0x75, 0xf9, 0x85, 0xd6, 0x47, 0x87, 0x2e, 0xa3, 0x0c, 0xd7,
0xf9, 0xb6, 0x15, 0x49, 0x4e, 0x47, 0x99, 0xae, 0x8b, 0x6d, 0xbb, 0x30, 0xd3, 0x28, 0xe7, 0x75,
0xb9, 0x23, 0xf9, 0x9a, 0x1a, 0x46, 0xd9, 0x6f, 0x88, 0xfd, 0xf7, 0xf5, 0x9a, 0x47, 0x68, 0xa2,
0x12, 0x30, 0x7a, 0xdb, 0xea, 0xcd, 0xf2, 0x33, 0xb5, 0x8c, 0x2f, 0x77, 0x33, 0x6e, 0xf9, 0xdf,
0xd4, 0x34, 0x2a, 0x0d, 0x63, 0xab, 0x8b, 0xcd, 0x7a, 0x75, 0x85, 0x9e, 0xa3, 0xe2, 0x30, 0xd9,
0xd0, 0x08, 0xf2, 0x30, 0x51, 0x79, 0x18, 0x37, 0xb4, 0x43, 0x9f, 0x51, 0x81, 0x18, 0x1f, 0x14,
0x96, 0xa9, 0x45, 0x25, 0x62, 0xf2, 0xea, 0xd5, 0xf2, 0x7a, 0xbd, 0x82, 0xee, 0x9b, 0xa8, 0x3c,
0x4c, 0x31, 0x2c, 0x27, 0x13, 0x15, 0x84, 0x29, 0x43, 0x1b, 0x92, 0xac, 0x89, 0x4a, 0xc1, 0xa6,
0x43, 0xab, 0x41, 0x5f, 0x6c, 0x54, 0x16, 0x56, 0x87, 0xb6, 0xaf, 0x69, 0xab, 0x20, 0xb3, 0x62,
0xa3, 0xb2, 0xb0, 0x66, 0xa0, 0x4a, 0x4b, 0xc0, 0xc6, 0xcd, 0x8f, 0xdd, 0xad, 0x78, 0x96, 0xae,
0x8d, 0x4a, 0xc3, 0x66, 0xa2, 0xf7, 0x37, 0x0f, 0xc4, 0x3e, 0x1b, 0x15, 0x86, 0x75, 0xd5, 0xe5,
0xba, 0xbe, 0xb9, 0x21, 0x13, 0xf2, 0x3b, 0xec, 0x3b, 0xb5, 0x8d, 0x4a, 0xc4, 0x0e, 0x06, 0xe9,
0xfc, 0xc8, 0x46, 0xe5, 0x61, 0xf3, 0xad, 0xb6, 0x91, 0x0d, 0xb0, 0x51, 0x89, 0xd8, 0xa2, 0x22,
0x5f, 0xf1, 0x05, 0xfb, 0x4c, 0x47, 0x36, 0x2a, 0x14, 0x5b, 0x6e, 0xc9, 0x91, 0x58, 0x6c, 0x54,
0x2c, 0x99, 0xd8, 0xa6, 0x65, 0xbb, 0x26, 0xa3, 0x1b, 0x15, 0x48, 0xa6, 0x2b, 0x9e, 0xe5, 0xc7,
0x15, 0x36, 0xa5, 0xa3, 0x2c, 0x2a, 0x8f, 0x8c, 0x2c, 0xd4, 0x62, 0xdd, 0x7e, 0x59, 0xad, 0x3f,
0xf5, 0xd4, 0x2e, 0x2a, 0x90, 0xcc, 0x8e, 0xda, 0xd1, 0x00, 0xb3, 0xf8, 0xc6, 0x00, 0x63, 0xb5,
0xa6, 0x48, 0xeb, 0xae, 0x06, 0xc5, 0xa8, 0x40, 0x32, 0xc7, 0x14, 0x69, 0xc9, 0xd0, 0x2e, 0xca,
0xb3, 0x89, 0xca, 0x23, 0xf3, 0xd5, 0xaf, 0xe1, 0xb9, 0xaa, 0xd4, 0x2c, 0x2a, 0x91, 0x2c, 0x1f,
0x9e, 0xc3, 0x46, 0xad, 0xa2, 0xf2, 0xc8, 0x0a, 0xd9, 0xb9, 0xde, 0xbc, 0xa7, 0x56, 0x51, 0x71,
0x64, 0x65, 0x68, 0xf5, 0x86, 0x5a, 0x45, 0x85, 0xe1, 0x52, 0x69, 0xf5, 0x9e, 0x68, 0xb9, 0xa8,
0x30, 0x9c, 0x0e, 0xad, 0x88, 0x96, 0x8b, 0x4a, 0xc2, 0x91, 0x66, 0x90, 0xcb, 0xf1, 0x40, 0x4c,
0x73, 0x51, 0x31, 0x38, 0x5b, 0xfd, 0x56, 0xe3, 0x61, 0xbb, 0xf0, 0xff, 0x8f, 0x5c, 0x54, 0x08,
0x2e, 0xa3, 0xd5, 0xbe, 0x90, 0x77, 0x1c, 0x07, 0x7b, 0xe0, 0xe2, 0x5b, 0xb4, 0xdb, 0x35, 0x96,
0x5d, 0xdf, 0x45, 0x45, 0xe1, 0xfc, 0xae, 0xad, 0x18, 0x7c, 0x17, 0x95, 0x87, 0xcb, 0x65, 0x11,
0xb2, 0x40, 0x5c, 0x54, 0x20, 0xae, 0xa8, 0xde, 0x9c, 0xfe, 0x2f, 0xb5, 0x88, 0x0a, 0xc3, 0x95,
0xd5, 0xdb, 0x87, 0x6e, 0xb3, 0x50, 0xa7, 0xab, 0xbb, 0x96, 0x96, 0x80, 0x8b, 0x0a, 0xc4, 0xef,
0xb4, 0x03, 0x3b, 0xb3, 0x8f, 0xca, 0xc4, 0xeb, 0x2a, 0xb8, 0x2e, 0x81, 0x3d, 0x3e, 0x2a, 0x18,
0x6f, 0xaa, 0xf7, 0x7d, 0xb3, 0xe8, 0xf0, 0xb8, 0x5a, 0x6a, 0x17, 0x95, 0x8d, 0xb7, 0xd5, 0xd9,
0x7a, 0x41, 0x2c, 0x31, 0xa9, 0x76, 0xd4, 0x30, 0x2a, 0x1c, 0x9f, 0x55, 0xff, 0x7a, 0xb8, 0xbd,
0xc5, 0xf6, 0xe6, 0xa3, 0x42, 0xf1, 0xae, 0x3a, 0xab, 0xbb, 0x76, 0xc3, 0x7d, 0xc6, 0x3d, 0x27,
0x2f, 0x4a, 0x44, 0x5d, 0x62, 0xba, 0x51, 0x51, 0xf8, 0x5c, 0x8c, 0xe4, 0x97, 0xfa, 0x73, 0x4b,
0x0b, 0xcc, 0x47, 0x85, 0xe1, 0x8b, 0xea, 0xe4, 0xec, 0x2d, 0xb5, 0x88, 0x0a, 0xc3, 0x97, 0xd4,
0x65, 0xd7, 0xa9, 0x77, 0x78, 0x54, 0xb4, 0x2a, 0xa8, 0x69, 0x54, 0x1a, 0x79, 0x5a, 0x49, 0x2b,
0x60, 0x8a, 0xe4, 0xb9, 0x45, 0xa5, 0x91, 0xeb, 0x5d, 0x43, 0x9a, 0x47, 0x1e, 0x95, 0x45, 0x6e,
0x76, 0x0d, 0x2d, 0x35, 0x8c, 0x0a, 0x23, 0xb7, 0xbb, 0x86, 0x19, 0x35, 0x8c, 0x0a, 0x23, 0x0f,
0xdb, 0xc7, 0x66, 0xf0, 0x89, 0xf2, 0xa8, 0x48, 0x72, 0x57, 0xfd, 0x5e, 0x7f, 0x42, 0x93, 0xa8,
0x3c, 0x72, 0x5f, 0xbd, 0x6d, 0x37, 0x2d, 0x29, 0xc7, 0x51, 0x1e, 0x77, 0x66, 0xf3, 0xea, 0xe2,
0x6e, 0xb5, 0x22, 0xff, 0x7b, 0xdb, 0x36, 0x2a, 0x8f, 0xbc, 0x80, 0xbf, 0xda, 0x7d, 0xa9, 0x1f,
0xa9, 0xd5, 0x48, 0x26, 0xc0, 0xd9, 0x38, 0x20, 0xd8, 0x85, 0x13, 0x17, 0xa4, 0x1a, 0x7d, 0xdb,
0xac, 0x96, 0xd7, 0xf5, 0xfa, 0x51, 0x89, 0x8a, 0x6e, 0x56, 0xea, 0xa5, 0x3c, 0xa4, 0x58, 0x62,
0xc6, 0xf0, 0xff, 0x16, 0x67, 0xba, 0xa0, 0x30, 0xa2, 0xe2, 0xd8, 0xf1, 0xe5, 0x0b, 0x39, 0x57,
0x7d, 0xeb, 0x02, 0x8a, 0x9d, 0x4e, 0xf0, 0x3c, 0xeb, 0x83, 0x2f, 0x30, 0x3f, 0x04, 0x55, 0x3b,
0xf8, 0x0a, 0xfb, 0x03, 0x34, 0xe9, 0x8e, 0xa6, 0x71, 0xf0, 0x25, 0xd9, 0x0f, 0xb4, 0x65, 0xd7,
0xf7, 0xea, 0xec, 0xc5, 0xc5, 0xee, 0x1a, 0x62, 0xc0, 0x37, 0x2e, 0x73, 0x74, 0x19, 0xb1, 0x2d,
0xf4, 0x06, 0x76, 0xcd, 0x86, 0x3a, 0xc4, 0xc1, 0x37, 0xf7, 0x1f, 0x04, 0xaf, 0x7a, 0x5d, 0xf7,
0x1b, 0xbc, 0xdf, 0x3d, 0x28, 0xe7, 0xfe, 0x60, 0xee, 0xf5, 0xd9, 0x28, 0x98, 0x3b, 0x7b, 0x2e,
0x98, 0xfb, 0xa5, 0xbd, 0xa9, 0xc9, 0xb4, 0x45, 0x43, 0xb9, 0xc1, 0x48, 0x3d, 0x52, 0x2c, 0x1a,
0x8d, 0xe6, 0x86, 0xe1, 0x4b, 0xa4, 0xf5, 0x7e, 0xd9, 0x3d, 0x46, 0xa3, 0xba, 0x13, 0x32, 0x76,
0xd7, 0x0a, 0xef, 0xc3, 0x19, 0x18, 0xbc, 0x7f, 0xfb, 0x63, 0xb6, 0x30, 0xbd, 0xfe, 0x39, 0x82,
0x6e, 0x47, 0x70, 0x77, 0x41, 0x34, 0xca, 0x3b, 0xab, 0xd7, 0x9b, 0x18, 0x25, 0x32, 0x50, 0xdd,
0xea, 0xe1, 0x3a, 0x1a, 0xdb, 0xfd, 0x5e, 0x7f, 0xae, 0xa3, 0x21, 0xdd, 0xfb, 0xa6, 0xad, 0x97,
0xf1, 0x60, 0xee, 0xf5, 0x6a, 0xdd, 0xf6, 0x51, 0x1e, 0xeb, 0x21, 0x22, 0x8c, 0x07, 0x71, 0x83,
0x0b, 0x8c, 0x77, 0xb3, 0xdd, 0xc7, 0xe4, 0x40, 0x91, 0xdc, 0xc5, 0xc3, 0xb2, 0x6f, 0xa3, 0x1d,
0x65, 0xd5, 0xf9, 0xe2, 0x73, 0xbb, 0xbc, 0x6e, 0xbb, 0x2e, 0x1e, 0xc1, 0x51, 0x64, 0xde, 0x7e,
0x8d, 0x76, 0xe1, 0xe1, 0x4b, 0xaa, 0x7f, 0x2a, 0x78, 0x93, 0xf1, 0xc8, 0xed, 0x3f, 0xfc, 0x3c,
0xfe, 0xd5, 0x43, 0x74, 0x24, 0x05, 0x85, 0x12, 0x75, 0xb7, 0xba, 0x25, 0xef, 0x30, 0x1e, 0xac,
0x5d, 0xdc, 0xc3, 0x99, 0x8f, 0xc7, 0x68, 0x67, 0xa4, 0x09, 0x6d, 0x6c, 0x26, 0x88, 0xce, 0x98,
0x19, 0x26, 0x1e, 0x94, 0x9d, 0xb4, 0x6d, 0x13, 0xa5, 0x6f, 0xab, 0x7f, 0x2f, 0x96, 0x9b, 0xfa,
0x36, 0xba, 0xea, 0x33, 0xd2, 0x9d, 0x7b, 0x3c, 0xac, 0x77, 0x1d, 0x6d, 0x02, 0x7b, 0xbd, 0xbc,
0xee, 0x9b, 0x3a, 0x2a, 0x33, 0xc4, 0x5e, 0x6d, 0x1d, 0x1f, 0x05, 0x59, 0xea, 0x8f, 0xed, 0xfa,
0x2a, 0x2a, 0x53, 0x0a, 0xb7, 0x7e, 0x8b, 0xab, 0x2f, 0x05, 0x5a, 0x38, 0xeb, 0xb3, 0x78, 0x88,
0xf5, 0xcb, 0xfa, 0xf1, 0x4b, 0x94, 0x3a, 0x85, 0x55, 0xff, 0x7a, 0x88, 0x71, 0x98, 0x22, 0xa9,
0x5f, 0xd7, 0xcf, 0xb2, 0x88, 0x82, 0xa8, 0xf3, 0xf6, 0xcb, 0xc7, 0x45, 0x3c, 0x70, 0xba, 0x6c,
0xd7, 0x9b, 0x45, 0xdc, 0x0a, 0x58, 0x71, 0xd1, 0xe3, 0x51, 0xd2, 0x9b, 0xa6, 0xbd, 0x79, 0xa6,
0x01, 0xe9, 0xf4, 0x63, 0xbd, 0x8c, 0x9e, 0x2e, 0xc4, 0x3d, 0x54, 0x67, 0xb4, 0xf3, 0xc6, 0xa3,
0xa2, 0x57, 0x0f, 0x9b, 0x87, 0xbb, 0x98, 0x72, 0x53, 0x34, 0xf4, 0x96, 0x18, 0x40, 0x5c, 0x88,
0x07, 0x42, 0xd4, 0x60, 0xdd, 0xc6, 0x0c, 0x0b, 0xc5, 0x3f, 0xa4, 0x2d, 0x77, 0xf5, 0x6d, 0x3c,
0xee, 0xa1, 0xf3, 0x57, 0xdd, 0x43, 0x3c, 0xda, 0x79, 0x2f, 0x40, 0xec, 0x3f, 0xd5, 0x65, 0x5b,
0xc7, 0x84, 0x45, 0x64, 0x2e, 0x17, 0xf5, 0x5d, 0x1d, 0x93, 0x34, 0x91, 0x79, 0x75, 0xbf, 0x5e,
0x90, 0x57, 0x05, 0x8e, 0xec, 0xdb, 0xe5, 0x67, 0xa0, 0xf0, 0x87, 0x43, 0x40, 0xe1, 0x80, 0xd5,
0x5e, 0xdc, 0xb7, 0xed, 0xf5, 0x53, 0x54, 0xf8, 0xc3, 0xa1, 0xa8, 0xf0, 0x87, 0x3d, 0xe0, 0xf8,
0x9b, 0xbf, 0xd0, 0xff, 0x9b, 0xe5, 0xa6, 0x5d, 0xf6, 0x8b, 0xcd, 0xe3, 0x93, 0x31, 0xbc, 0xf9,
0x9e, 0x31, 0xcc, 0xf0, 0xe9, 0xb3, 0x29, 0x3e, 0xfd, 0xba, 0xfe, 0xbc, 0x5a, 0x03, 0x0b, 0x3f,
0x23, 0x9b, 0xdf, 0x6e, 0xfa, 0x27, 0x18, 0xf5, 0x7d, 0xdf, 0x6d, 0x3d, 0x00, 0x7e, 0x29, 0x1c,
0xbf, 0x0e, 0x2d, 0x86, 0x52, 0xcf, 0x6a, 0x69, 0x62, 0xd9, 0xc3, 0xfb, 0x11, 0x1c, 0x1c, 0x5e,
0xbb, 0xf7, 0x77, 0x41, 0xeb, 0xfb, 0x7e, 0xf9, 0x94, 0xe8, 0xdf, 0x05, 0xae, 0xef, 0xfb, 0x7e,
0x3a, 0x79, 0x7e, 0xb7, 0xf3, 0x73, 0x34, 0x47, 0xd5, 0x11, 0x33, 0x92, 0x60, 0xac, 0x48, 0x9e,
0x09, 0xbf, 0x09, 0xae, 0xcf, 0x6b, 0x35, 0x7a, 0x83, 0xc3, 0xb0, 0x9b, 0xb0, 0x78, 0x75, 0x10,
0x6f, 0x90, 0xee, 0xce, 0x73, 0x3d, 0xc5, 0x78, 0xd4, 0x96, 0xd7, 0x70, 0xc3, 0xea, 0xfb, 0xfb,
0xee, 0x71, 0xb2, 0xb2, 0xf8, 0xf4, 0xd5, 0xea, 0x4f, 0x15, 0xde, 0x4f, 0x15, 0xd2, 0x88, 0xa7,
0x95, 0xb8, 0xba, 0x3f, 0x1e, 0xd0, 0xf8, 0x35, 0x35, 0x6e, 0x79, 0x4d, 0xf6, 0x8a, 0x36, 0x86,
0xfd, 0x57, 0x70, 0xcb, 0x13, 0x6a, 0x79, 0xb5, 0xcd, 0x35, 0x1e, 0xef, 0x46, 0x0a, 0x3f, 0x4c,
0x6d, 0x3e, 0xae, 0x57, 0x0f, 0xb7, 0x1f, 0xd5, 0xbd, 0x2c, 0x31, 0xb5, 0x63, 0x43, 0xf3, 0xa8,
0x85, 0xc0, 0x99, 0x3e, 0x98, 0x0d, 0xec, 0xa4, 0x8f, 0x28, 0x98, 0x40, 0xc1, 0xec, 0xa1, 0xe0,
0xf6, 0x52, 0xf8, 0x51, 0x7d, 0x02, 0x5a, 0x85, 0x8d, 0x4c, 0x21, 0x79, 0x32, 0xa6, 0x76, 0x19,
0xa8, 0x5d, 0xee, 0x1b, 0x8f, 0x71, 0xa2, 0x78, 0x4e, 0x34, 0xcf, 0x3b, 0xd4, 0x02, 0x04, 0xa2,
0x77, 0xfd, 0x4f, 0xcf, 0x30, 0xe8, 0xf4, 0x3f, 0xdb, 0x75, 0xc4, 0xaf, 0x12, 0x1b, 0x65, 0x35,
0x9e, 0xf1, 0xb8, 0xcf, 0xa9, 0xe1, 0x2b, 0x96, 0xec, 0x15, 0xc5, 0x3f, 0x24, 0xb8, 0xe5, 0xcd,
0xe2, 0x76, 0xe7, 0x6b, 0x83, 0xc4, 0x4c, 0xbb, 0xdf, 0x4d, 0xb5, 0xfb, 0x72, 0x71, 0x47, 0xc2,
0xe4, 0x6d, 0xe3, 0x89, 0x62, 0x2f, 0x27, 0xe9, 0x6b, 0xbc, 0x51, 0xf0, 0x2f, 0x16, 0x14, 0x6c,
0x29, 0x02, 0x6c, 0x7a, 0xa8, 0x3b, 0x1a, 0xe6, 0xf5, 0xe2, 0x4e, 0x41, 0x03, 0x0e, 0x58, 0x5c,
0xef, 0x4e, 0xe5, 0x62, 0xdd, 0x53, 0x18, 0xc6, 0xaf, 0xe0, 0x50, 0xbc, 0x38, 0xae, 0x87, 0x04,
0xe1, 0x11, 0x2a, 0x40, 0x1c, 0xb1, 0xfb, 0x87, 0x1f, 0x95, 0xa1, 0xd5, 0xc7, 0x67, 0x37, 0xf5,
0xfa, 0x96, 0x1c, 0xe7, 0xf1, 0x5a, 0xdb, 0xda, 0xd8, 0x77, 0x07, 0xd8, 0xd8, 0x5f, 0x62, 0xe9,
0xc7, 0x77, 0x5b, 0x44, 0x64, 0xb2, 0x64, 0x76, 0xca, 0x37, 0x33, 0xe8, 0x97, 0x87, 0x18, 0xf4,
0x4b, 0x19, 0xed, 0x2e, 0x0b, 0xff, 0x74, 0x57, 0xb9, 0x7c, 0xd6, 0xa2, 0x4f, 0x6c, 0xb8, 0x98,
0x90, 0x17, 0xa8, 0x0a, 0xd8, 0xfe, 0x22, 0xef, 0x2c, 0x92, 0x6a, 0x84, 0x1b, 0x85, 0x17, 0x5c,
0xd6, 0x57, 0xe4, 0xc8, 0xfe, 0x74, 0xd5, 0xd5, 0xcb, 0x4f, 0xd4, 0x4a, 0xce, 0xd3, 0x3f, 0x78,
0x69, 0x03, 0xde, 0xe0, 0xb0, 0xb9, 0xeb, 0xaa, 0xff, 0x07, 0x89, 0xc6, 0x88, 0x77, 0x0c, 0x8c,
};

1286
wled00/html_mobile.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,7 @@ const char PAGE_usermod[] PROGMEM = R"=====(
//server message
const char PAGE_msg0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head>
<html><head><meta content='width=device-width' name='viewport'>
<title>WLED Message</title>
<script>function B(){window.history.back()};function RS(){window.location = "/settings";}function RP(){top.location.href="/";}</script>
)=====";
@@ -24,15 +24,15 @@ button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-seri
//new user welcome page
#ifndef WLED_FLASH_512K_MODE
#ifndef WLED_DISABLE_MOBILE_UI
const char PAGE_welcome0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head>
<html><head><meta content='width=device-width' name='viewport'>
<title>WLED Welcome!</title>
)=====";
const char PAGE_welcome1[] PROGMEM = R"=====(
body{font-family:var(--cFn),sans-serif;text-align:center;background:linear-gradient(var(--bCol),black);height:100%;margin:0;background-repeat:no-repeat;background-attachment: fixed;color: var(--tCol);}svg {fill: var(--dCol);}
body{font-family:var(--cFn),sans-serif;text-align:center;background:linear-gradient(var(--bCol),black);margin:0;background-attachment: fixed;color: var(--tCol);}svg {fill: var(--dCol);}
</style></head>
<body>
<svg style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg">

View File

@@ -4,7 +4,7 @@
//common CSS of settings pages
const char PAGE_settingsCss[] PROGMEM = R"=====(
body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%;margin:0;background-attachment:fixed}hr{border-color:var(--dCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.5ch solid var(--bCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}input[type=number]{width:3em}select{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:0.5ch solid var(--bCol);filter:drop-shadow( -5px -5px 5px var(--sCol) );}</style>
body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%;margin:0;background-attachment:fixed}hr{border-color:var(--dCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.5ch solid var(--bCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}input[type=number]{width:4em}select{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:0.5ch solid var(--bCol);filter:drop-shadow( -5px -5px 5px var(--sCol) );}</style>
)=====";
@@ -34,7 +34,7 @@ body{text-align:center;background:var(--cCol);height:100%;margin:0;background-at
//wifi settings
const char PAGE_settings_wifi0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head>
<html><head><meta name="viewport" content="width=500">
<title>WiFi Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#wifi-settings");}function B(){window.history.back();}function GetV(){var d = document;
)=====";
@@ -83,44 +83,63 @@ AP IP: <span class="sip"> Not active </span><hr>
//LED settings
const char PAGE_settings_leds0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head>
<title>LED Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings");}function B(){window.history.back();}function GetV(){var d = document;
<html><head><meta name="viewport" content="width=500">
<title>LED Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings");}function B(){window.history.back();}function S(){GetV();UI();}function UI(){
var myC=document.querySelectorAll('.wc'),l=myC.length;
for (i = 0; i < l; i++){myC[i].style.display=(document.getElementById('rgbw').checked)?'inline':'none';}
var val=Math.ceil((100+document.Sf.LC.value*55)/500)/2;
val=(val>5)?Math.ceil(val):val;var s="";
if (val<1.1){s="ESP 5V pin with 1A USB supply";}else{s="External 5V ";s+=val;s+="A supply connected to LEDs";}
document.getElementById('psu').innerHTML=s;document.getElementById('ps2').innerHTML=val+"A = "+val*1000;
}function GetV(){var d = document;
)=====";
const char PAGE_settings_leds1[] PROGMEM = R"=====(
</head>
<body onload="GetV()">
<body onload="S()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>LED setup</h2>
LED count: <input name="LC" type="number" min="1" max="1200" required><br>
LEDs are 4-channel type (RGBW): <input type="checkbox" name="EW"><br>
<br>
Apply preset <input name="BP" type="number" min="0" max="25" required> at boot (0 uses defaults)<br>
Turn on after power up/reset: <input type="checkbox" name="BO"><br>
<br>
LED count: <input name="LC" type="number" min="1" max="1200" oninput=UI() required><br>
<i>Recommended power supply for brightest white:</i><br>
<b><span id="psu">?</span></b><br><br>
Maximum Current: <input name="MA" type="number" min="250" max="65000" required> mA<br>
<i>Automatically limits brightness to stay close to the limit.<br>
Keep at &lt;1A if powering LEDs directly from the ESP 5V pin!<br>
If you are using an external 5V supply, enter its rating.<br>
"65000" completely diasbles the power calculation.<br>
(Current estimated usage: <span class="pow">unknown</span>)</i><br><br>
LEDs are 4-channel type (RGBW): <input type="checkbox" name="EW" onchange=UI() id="rgbw"><br>
Color order:
<select name="CO">
<option value="0">GRB</option>
<option value="1">RGB</option>
<option value="2">BRG</option>
<option value="3">RBG</option></select>
<h3>Defaults</h3>
Turn LEDs on after power up/reset: <input type="checkbox" name="BO"><br><br>
Default RGB color:
<input name="CR" type="number" min="0" max="255" required>
<input name="CG" type="number" min="0" max="255" required>
<input name="CB" type="number" min="0" max="255" required><br>
Default white value (only RGBW): <input name="CW" type="number" min="0" max="255" required><br>
Auto-calculate white from RGB instead: <input type="checkbox" name="AW"><br>
<span class="wc">Default white value: <input name="CW" type="number" min="0" max="255" required><br>
Auto-calculate white from RGB instead: <input type="checkbox" name="AW"><br></span>
Default brightness: <input name="CA" type="number" min="0" max="255" required> (0-255)<br>
Default effect ID: <input name="FX" type="number" min="0" max="57" required><br>
Default effect speed: <input name="SX" type="number" min="0" max="255" required><br>
Default effect intensity: <input name="IX" type="number" min="0" max="255" required><br>
Default effect palette: <input name="FP" type="number" min="0" max="255" required><br>
Default secondary RGB(W):<br>
Default secondary RGB<span class="wc">W</span>:<br>
<input name="SR" type="number" min="0" max="255" required>
<input name="SG" type="number" min="0" max="255" required>
<input name="SB" type="number" min="0" max="255" required>
<input name="SW" type="number" min="0" max="255" required><br>
Ignore and use current color, brightness and effects: <input type="checkbox" name="IS"><br>
Save current preset cycle configuration as boot default: <input type="checkbox" name="PC"><br>
<br>
<span class="wc"><input name="SW" type="number" min="0" max="255" required></span><br>
Ignore and use current color, brightness and effects: <input type="checkbox" name="IS"><br><br>
Apply preset <input name="BP" type="number" min="0" max="25" required> at boot (0 uses defaults)<br>
Save current preset cycle configuration as boot default: <input type="checkbox" name="PC"><br><br>
Use Gamma correction for color: <input type="checkbox" name="GC"> (strongly recommended)<br>
Use Gamma correction for brightness: <input type="checkbox" name="GB"> (not recommended)<br>
Use Gamma correction for brightness: <input type="checkbox" name="GB"> (not recommended)<br><br>
Brightness factor: <input name="BF" type="number" min="0" max="255" required> %
<h3>Transitions</h3>
Crossfade: <input type="checkbox" name="TF"><br>
@@ -152,7 +171,7 @@ Skip first LED: <input type="checkbox" name="SL"><hr>
//User Interface settings
const char PAGE_settings_ui0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head>
<html><head><meta name="viewport" content="width=500">
<title>UI Settings</title><script>
function gId(s){return document.getElementById(s);}function S(){GetV();Ct();}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");}function B(){window.history.back();}function Ct(){if (gId("co").selected){gId("cth").style.display="block";}else{gId("cth").style.display="none";}}function GetV(){var d = document;
)=====";
@@ -188,7 +207,7 @@ Color Theme:
<option value="10">Terminal</option>
<option value="11">C64</option>
<option value="12">Easter</option>
<option value="13">Placeholder</option>
<option value="13">Christmas</option>
<option value="14">The End</option>
<option value="15" id="co">Custom</option>
</select><br>
@@ -212,7 +231,7 @@ Make sure the font you use is installed on your system!<br>
//sync settings
const char PAGE_settings_sync0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head><title>Sync Settings</title>
<html><head><meta name="viewport" content="width=500"><title>Sync Settings</title>
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}function GetV(){var d = document;
)=====";
@@ -224,7 +243,9 @@ const char PAGE_settings_sync1[] PROGMEM = R"=====(
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>Sync setup</h2>
<h3>Button setup</h3>
On/Off button enabled: <input type="checkbox" name="BT">
On/Off button enabled: <input type="checkbox" name="BT"><br>
Infrared receiver enabled: <input type="checkbox" name="IR"><br>
<a href="https://github.com/Aircoookie/WLED/wiki/Infrared-Control" target="_blank">IR info</a>
<h3>WLED Broadcast</h3>
UDP Port: <input name="UP" maxlength="5" size="4"><br>
Receive <input type="checkbox" name="RB">Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox" name="RX">Effects<br>
@@ -237,7 +258,7 @@ Send notifications twice: <input type="checkbox" name="S2"><br>
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
<i>E1.31 (sACN)</i><br>
Use E1.31 multicast: <input type="checkbox" name="EM"><br>
E1.31 universe: <input name="EU" type="number" min="1" max="63999" required><br>
E1.31 start universe: <input name="EU" type="number" min="1" max="63999" required><br>
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx</a>!<br><br>
Timeout: <input name="ET" type="number" min="1" max="65000" required> ms<br>
Force max brightness: <input type="checkbox" name="FB"><br>
@@ -248,6 +269,10 @@ Enable UI access during realtime: <input type="checkbox" name="RU"> (can cause i
Emulate Alexa device: <input type="checkbox" name="AL"><br>
Alexa invocation name: <input name="AI" maxlength="32">
<h3>Blynk</h3>
<b>Blynk, MQTT and Hue sync all connect to external hosts!<br>
This impacts the responsiveness of the ESP8266.</b><br>
For best results, only use one of these services at a time.<br>
(alternatively, connect a second ESP to them and use the UDP sync)<br><br>
Device Auth token: <input name="BK" maxlength="33"><br>
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
<h3>MQTT</h3>
@@ -277,7 +302,7 @@ Hue status: <span class="hms"> Internal ESP Error! </span><hr>
//time and macro settings
const char PAGE_settings_time0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head><title>Time Settings</title>
<html><head><meta name="viewport" content="width=500"><title>Time Settings</title>
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings");}function B(){window.open("/settings","_self");}function S(){GetV();Cs();}function gId(s){return document.getElementById(s);}function Cs(){gId("cac").style.display="none";gId("coc").style.display="block";gId("ccc").style.display="none";if (gId("ca").selected){gId("cac").style.display="block";}if (gId("cc").selected){gId("coc").style.display="none";gId("ccc").style.display="block";}if (gId("cn").selected){gId("coc").style.display="none";}}function GetV(){var d = document;
)=====";
@@ -329,7 +354,8 @@ Cronixie Display: <input name="CX" maxlength="6"><br>
Cronixie Backlight: <input type="checkbox" name="CB"><br>
</div>
Countdown Mode: <input type="checkbox" name="CE"><br>
Countdown Goal: Year: 20 <input name="CY" type="number" min="0" max="99" required> Month: <input name="CI" type="number" min="1" max="12" required> Day: <input name="CD" type="number" min="1" max="31" required><br>
Countdown Goal:<br>
Year: 20 <input name="CY" type="number" min="0" max="99" required> Month: <input name="CI" type="number" min="1" max="12" required> Day: <input name="CD" type="number" min="1" max="31" required><br>
Hour: <input name="CH" type="number" min="0" max="23" required> Minute: <input name="CM" type="number" min="0" max="59" required> Second: <input name="CS" type="number" min="0" max="59" required><br>
<h3>Advanced Macros</h3>
Define API macros here:<br>
@@ -382,7 +408,7 @@ Time-Controlled Macros (Hours/Minutes &gt; Macro):<br>
//security settings and about
const char PAGE_settings_sec0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head>
<html><head><meta name="viewport" content="width=500">
<title>Misc Settings</title>
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#security-settings");}function B(){window.open("/settings","_self");}function U(){window.open("/update","_self");}function GetV(){var d = document;
)=====";
@@ -411,24 +437,11 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
<button type="button" onclick="U()">Manual OTA Update</button><br>
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
<h3>About</h3>
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.8.0<br><br>
<b>Contributors:</b><br>
StormPie <i>(Mobile HTML UI)</i><br><br>
Thank you so much!<br><br>
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.8.2<br><br>
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-&-About" target="_blank">Contributors, dependencies and special thanks</a><br>
A huge thank you to everyone who helped me create WLED!<br><br>
(c) 2016-2018 Christian Schwinne <br>
<i>Licensed under the MIT license</i><br><br>
<b>Uses libraries:</b><br>
<i>ESP8266/ESP32 Arduino Core</i><br>
<i><a href="https://github.com/svenihoney/NeoPixelBus" target="_blank">NeoPixelBus</a> by Makuna (svenihoney fork)</i><br>
<i><a href="https://github.com/FastLED/FastLED/" target="_blank">FastLED</a> library</i><br>
<i>(ESP32) <a href="https://github.com/bbx10/WebServer_tng" target="_blank">WebServer_tng</a> by bbx10</i><br>
<i><a href="https://github.com/kitesurfer1404/WS2812FX" target="_blank">WS2812FX</a> by kitesurfer1404 (modified)</i><br>
<i><a href="https://github.com/JChristensen/Timezone" target="_blank">Timezone</a> library by JChristensen</i><br>
<i><a href="https://github.com/blynkkk/blynk-library" target="_blank">Blynk</a> library (compacted)</i><br>
<i><a href="https://github.com/forkineye/E131" target="_blank">E1.31</a> library by forkineye (modified)</i><br>
<i><a href="https://github.com/knolleary/pubsubclient" target="_blank">PubSubClient</a> by knolleary (modified)</i><br>
<i><a href="https://github.com/Aircoookie/Espalexa" target="_blank">Espalexa</a> by Aircoookie (modified)</i><br><br>
<i>UI icons by <a href="https://linearicons.com" target="_blank">Linearicons</a> created by <a href="https://perxis.com" target="_blank">Perxis</a>! (CC-BY-SA 4.0)</i> <br><br>
Server message: <span class="msg"> Response error! </span><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
</form>

File diff suppressed because one or more lines are too long

95
wled00/ir_codes.h Normal file
View File

@@ -0,0 +1,95 @@
//Infrared codes
//Add your custom codes here
#define IRCUSTOM_ONOFF 0xA55AEA15 //Pioneer RC-975R "+FAV" button (example)
#define IRCUSTOM_MACRO1 0xFFFFFFFF //placeholder, will never be checked for
//Infrared codes for 24-key remote from http://woodsgood.ca/projects/2015/02/13/rgb-led-strip-controllers-ir-codes/
#define IR24_BRIGHTER 0xF700FF
#define IR24_DARKER 0xF7807F
#define IR24_OFF 0xF740BF
#define IR24_ON 0xF7C03F
#define IR24_RED 0xF720DF
#define IR24_REDDISH 0xF710EF
#define IR24_ORANGE 0xF730CF
#define IR24_YELLOWISH 0xF708F7
#define IR24_YELLOW 0xF728D7
#define IR24_GREEN 0xF7A05F
#define IR24_GREENISH 0xF7906F
#define IR24_TURQUOISE 0xF7B04F
#define IR24_CYAN 0xF78877
#define IR24_AQUA 0xF7A857
#define IR24_BLUE 0xF7609F
#define IR24_DEEPBLUE 0xF750AF
#define IR24_PURPLE 0xF7708F
#define IR24_MAGENTA 0xF748B7
#define IR24_PINK 0xF76897
#define IR24_WHITE 0xF7E01F
#define IR24_FLASH 0xF7D02F
#define IR24_STROBE 0xF7F00F
#define IR24_FADE 0xF7C837
#define IR24_SMOOTH 0xF7E817
/* 44-key defs, to be done later
#define IR44_BPlus 0xFF3AC5 //
#define IR44_BMinus 0xFFBA45 //
#define IR44_ON 0xFF827D //
#define IR44_OFF 0xFF02FD //
#define IR44_R 0xFF1AE5 //
#define IR44_G 0xFF9A65 //
#define IR44_B 0xFFA25D //
#define IR44_W 0xFF22DD //
#define IR44_B1 0xFF2AD5 //
#define IR44_B2 0xFFAA55 //
#define IR44_B3 0xFF926D //
#define IR44_B4 0xFF12ED //
#define IR44_B5 0xFF0AF5 //
#define IR44_B6 0xFF8A75 //
#define IR44_B7 0xFFB24D //
#define IR44_B8 0xFF32CD //
#define IR44_B9 0xFF38C7 //
#define IR44_B10 0xFFB847 //
#define IR44_B11 0xFF7887 //
#define IR44_B12 0xFFF807 //
#define IR44_B13 0xFF18E7 //
#define IR44_B14 0xFF9867 //
#define IR44_B15 0xFF58A7 //
#define IR44_B16 0xFFD827 //
#define IR44_UPR 0xFF28D7 //
#define IR44_UPG 0xFFA857 //
#define IR44_UPB 0xFF6897 //
#define IR44_QUICK 0xFFE817 //
#define IR44_DOWNR 0xFF08F7 //
#define IR44_DOWNG 0xFF8877 //
#define IR44_DOWNB 0xFF48B7 //
#define IR44_SLOW 0xFFC837 //
#define IR44_DIY1 0xFF30CF //
#define IR44_DIY2 0xFFB04F //
#define IR44_DIY3 0xFF708F //
#define IR44_AUTO 0xFFF00F //
#define IR44_DIY4 0xFF10EF //
#define IR44_DIY5 0xFF906F //
#define IR44_DIY6 0xFF50AF //
#define IR44_FLASH 0xFFD02F //
#define IR44_JUMP3 0xFF20DF //
#define IR44_JUMP7 0xFFA05F //
#define IR44_FADE3 0xFF609F //
#define IR44_FADE7 0xFFE01F //
*/
#define COLOR_RED 0xFF0000
#define COLOR_REDDISH 0xFF7800
#define COLOR_ORANGE 0xFFA000
#define COLOR_YELLOWISH 0xFFC800
#define COLOR_YELLOW 0xFFFF00
#define COLOR_GREEN 0x00FF00
#define COLOR_GREENISH 0x00FF78
#define COLOR_TURQUOISE 0x00FFA0
#define COLOR_CYAN 0x00FFDC
#define COLOR_AQUA 0x00C8FF
#define COLOR_BLUE 0x00A0FF
#define COLOR_DEEPBLUE 0x0000FF
#define COLOR_PURPLE 0xAA00FF
#define COLOR_MAGENTA 0xFF00DC
#define COLOR_PINK 0xFF00A0
#define COLOR_WHITE 0xFFFFDC

View File

@@ -500,6 +500,42 @@ DEFINE_GRADIENT_PALETTE( Orange_Teal_gp ) {
200, 255, 72, 0,
255, 255, 72, 0};
//Custom palette by Aircoookie
DEFINE_GRADIENT_PALETTE( Tiamat_gp ) {
0, 1, 2, 14, //gc
33, 2, 5, 35, //gc from 47, 61,126
100, 13,135, 92, //gc from 88,242,247
120, 43,255,193, //gc from 135,255,253
140, 247, 7,249, //gc from 252, 69,253
160, 193, 17,208, //gc from 231, 96,237
180, 39,255,154, //gc from 130, 77,213
200, 4,213,236, //gc from 57,122,248
220, 39,252,135, //gc from 177,254,255
240, 193,213,253, //gc from 203,239,253
255, 255,249,255};
//Custom palette by Aircoookie
DEFINE_GRADIENT_PALETTE( April_Night_gp ) {
0, 1, 5, 45, //deep blue
10, 1, 5, 45,
25, 5,169,175, //light blue
40, 1, 5, 45,
61, 1, 5, 45,
76, 45,175, 31, //green
91, 1, 5, 45,
112, 1, 5, 45,
127, 249,150, 5, //yellow
143, 1, 5, 45,
162, 1, 5, 45,
178, 255,92, 0, //pastel orange
193, 1, 5, 45,
214, 1, 5, 45,
229, 223, 45, 72, //pink
244, 1, 5, 45,
255, 1, 5, 45};
// Single array of defined cpt-city color palettes.
// This will let us programmatically choose one based on
@@ -543,8 +579,10 @@ const TProgmemRGBGradientPalettePtr gGradientPalettes[] = {
BlacK_Magenta_Red_gp, //41-28 Magred
BlacK_Red_Magenta_Yellow_gp, //42-29 Yelmag
Blue_Cyan_Yellow_gp, //43-30 Yelblu
Orange_Teal_gp //44-31 Orange & Teal
};
Orange_Teal_gp, //44-31 Orange & Teal
Tiamat_gp, //45-32 Tiamat
April_Night_gp //46-33 April Night
};
// Count of how many cpt-city gradients are defined:
@@ -552,4 +590,3 @@ const uint8_t gGradientPaletteCount =
sizeof( gGradientPalettes) / sizeof( TProgmemRGBGradientPalettePtr );
#endif

View File

@@ -3,50 +3,79 @@
*/
/*
* @title WLED project sketch
* @version 0.8.0
* @version 0.8.2
* @author Christian Schwinne
*/
//ESP8266-01 got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.3.0 and the setting 512K(64K SPIFFS).
//Uncomment the following line to disable some features (currently Mobile UI, welcome page and single digit + cronixie overlays) to compile for ESP8266-01
//#define WLED_FLASH_512K_MODE
//CURRENTLY NOT WORKING
//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.3.0 and the setting 512K(64K SPIFFS).
//ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS).
//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB):
//You are required to disable over-the-air updates:
//#define WLED_DISABLE_OTA
//You need to choose 1-2 of these features to disable:
//#define WLED_DISABLE_ALEXA
//#define WLED_DISABLE_BLYNK
//#define WLED_DISABLE_CRONIXIE
//#define WLED_DISABLE_HUESYNC
//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01
//#define WLED_DISABLE_MOBILE_UI
//to toggle usb serial debug (un)comment following line(s)
//#define WLED_DEBUG
//library inclusions
#include <Arduino.h>
#ifdef ARDUINO_ARCH_ESP32
#include <WiFi.h>
#include <ESPmDNS.h>
#include "src/dependencies/webserver/WebServer.h"
#include <HTTPClient.h>
#include <WiFi.h>
#include <ESPmDNS.h>
#include "src/dependencies/webserver/WebServer.h"
#include <HTTPClient.h>
/*#ifndef WLED_DISABLE_INFRARED
#include <IRremote.h>
#endif*/ //there are issues with ESP32 infrared, so it is disabled for now
#else
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
#ifndef WLED_DISABLE_INFRARED
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
#endif
#endif
#include <EEPROM.h>
#include <ArduinoOTA.h>
#include <WiFiUDP.h>
#include <DNSServer.h>
#include "src/dependencies/webserver/ESP8266HTTPUpdateServer.h"
#ifndef WLED_DISABLE_OTA
#include <ArduinoOTA.h>
#include "src/dependencies/webserver/ESP8266HTTPUpdateServer.h"
#endif
#include "src/dependencies/time/Time.h"
#include "src/dependencies/time/TimeLib.h"
#include "src/dependencies/timezone/Timezone.h"
#include "src/dependencies/blynk/BlynkSimpleEsp.h"
#ifndef WLED_DISABLE_BLYNK
#include "src/dependencies/blynk/BlynkSimpleEsp.h"
#endif
#include "src/dependencies/e131/E131.h"
#include "src/dependencies/pubsubclient/PubSubClient.h"
#include "htmls00.h"
#include "htmls01.h"
#include "htmls02.h"
#include "html_classic.h"
#include "html_mobile.h"
#include "html_settings.h"
#include "html_other.h"
#include "WS2812FX.h"
#include "ir_codes.h"
//version code in format yymmddb (b = daily build)
#define VERSION 1810151
char versionString[] = "0.8.0";
#define VERSION 1812052
char versionString[] = "0.8.2";
//AP and OTA default passwords (for maximum change them!)
@@ -54,18 +83,13 @@ char apPass[65] = "wled1234";
char otaPass[33] = "wledota";
//to toggle usb serial debug (un)comment following line(s)
//#define DEBUG
//spiffs FS only useful for debug (only ESP8266)
//#define USEFS
//Hardware CONFIG (only changeble HERE, not at runtime)
//LED strip pin changeable in NpbWrapper.h. Only change for ESP32
byte buttonPin = 0; //needs pull-up
byte auxPin = 15; //debug feature, use e.g. for external relay with API call AX=
//LED strip pin, button pin and IR pin changeable in NpbWrapper.h!
byte auxDefaultState = 0; //0: input 1: high 2: low
byte auxTriggeredState = 0; //0: input 1: high 2: low
char ntpServerName[] = "0.wled.pool.ntp.org"; //NTP server to use
@@ -87,9 +111,10 @@ IPAddress staticDNS(8, 8, 8, 8); //only for NTP, google DNS server
//LED CONFIG
uint16_t ledCount = 10; //lowered to prevent accidental overcurrent
uint16_t ledCount = 30; //overcurrent prevented by ABL
bool useRGBW = false; //SK6812 strips can contain an extra White channel
bool autoRGBtoRGBW = false; //if RGBW enabled, calculate White channel from RGB
#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit
bool turnOnAtBoot = true; //turn on LEDs at power-up
byte bootPreset = 0; //save preset to load after power-up
@@ -130,7 +155,8 @@ bool useHSBDefault = useHSB;
//Sync CONFIG
bool buttonEnabled = true;
bool buttonEnabled = true;
bool irEnabled = false; //Infrared receiver
uint16_t udpPort = 21324; //WLED notifier default port
uint16_t udpRgbPort = 19446; //Hyperion port
@@ -139,7 +165,7 @@ bool receiveNotificationBrightness = true; //apply brightness from incoming n
bool receiveNotificationColor = true; //apply color
bool receiveNotificationEffects = true; //apply effects setup
bool notifyDirect = true; //send notification if change via UI or HTTP API
bool notifyButton = true;
bool notifyButton = true; //send if updated by button or infrared remote
bool notifyAlexa = false; //send notification if updated via Alexa
bool notifyMacro = false; //send notification for macro
bool notifyHue = true; //send notification if Hue light changes
@@ -240,6 +266,7 @@ float tperLast = 0; //crossfade transition progress, 0
bool nightlightActive = false;
bool nightlightActiveOld = false;
uint32_t nightlightDelayMs = 10;
uint8_t nightlightDelayMinsDefault = nightlightDelayMins;
unsigned long nightlightStartTime;
byte briNlT = 0; //current nightlight brightness
@@ -273,7 +300,6 @@ bool udpConnected = false, udpRgbConnected = false;
//ui style
char cssCol[6][9]={"","","","","",""};
String cssColorString="";
bool showWelcomePage = false;
//hue
@@ -321,7 +347,7 @@ bool presetCyclingEnabled = false;
byte presetCycleMin = 1, presetCycleMax = 5;
uint16_t presetCycleTime = 1250;
unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin;
bool presetApplyBri = true, presetApplyCol = true, presetApplyFx = true;
bool presetApplyBri = false, presetApplyCol = true, presetApplyFx = true;
bool saveCurrPresetCycConf = false;
//realtime
@@ -343,6 +369,7 @@ bool auxActive = false, auxActiveBefore = false;
//alexa udp
WiFiUDP alexaUDP;
bool alexaUdpConnected = false;
IPAddress ipMulti(239, 255, 255, 250);
unsigned int portMulti = 1900;
String escapedMac;
@@ -361,21 +388,23 @@ unsigned int ntpLocalPort = 2390;
#define NTP_PACKET_SIZE 48
//string temp buffer
#define OMAX 1750
#define OMAX 2000
char obuf[OMAX];
uint16_t olen = 0;
//server library objects
#ifdef ARDUINO_ARCH_ESP32
WebServer server(80);
WebServer server(80);
#else
ESP8266WebServer server(80);
ESP8266WebServer server(80);
#endif
HTTPClient* hueClient = NULL;
WiFiClient* mqttTCPClient = NULL;
PubSubClient* mqtt = NULL;
ESP8266HTTPUpdateServer httpUpdater;
#ifndef WLED_DISABLE_OTA
ESP8266HTTPUpdateServer httpUpdater;
#endif
//udp interface objects
WiFiUDP notifierUdp, rgbUdp;
@@ -386,7 +415,7 @@ E131* e131;
WS2812FX strip = WS2812FX();
//debug macros
#ifdef DEBUG
#ifdef WLED_DEBUG
#define DEBUG_PRINT(x) Serial.print (x)
#define DEBUG_PRINTLN(x) Serial.println (x)
#define DEBUG_PRINTF(x) Serial.printf (x)
@@ -401,8 +430,8 @@ WS2812FX strip = WS2812FX();
//filesystem
#ifdef USEFS
#include <FS.h>;
File fsUploadFile;
#include <FS.h>;
File fsUploadFile;
#endif
//gamma 2.4 lookup table used for color correction
@@ -462,64 +491,64 @@ bool oappendi(int i)
//boot starts here
void setup() {
wledInit();
wledInit();
}
//main program loop
void loop() {
server.handleClient();
handleSerial();
handleNotifications();
handleTransitions();
userLoop();
yield();
handleButton();
handleNetworkTime();
if (!onlyAP)
{
handleAlexa();
handleMQTT();
}
handleOverlays();
server.handleClient();
handleSerial();
handleNotifications();
handleTransitions();
userLoop();
yield();
handleButton();
handleIR();
handleNetworkTime();
if (!onlyAP)
{
handleAlexa();
handleMQTT();
}
handleOverlays();
yield();
if (!realtimeActive) //block stuff if WARLS/Adalight is enabled
{
if (dnsActive) dnsServer.processNextRequest();
if (aOtaEnabled) ArduinoOTA.handle();
handleNightlight();
if (!onlyAP) {
handleHue();
handleBlynk();
}
if (briT) strip.service(); //do not update strip if off, prevents flicker on ESP32
}
//DEBUG serial logging
#ifdef DEBUG
if (millis() - debugTime > 5000)
{
DEBUG_PRINTLN("---MODULE DEBUG INFO---");
DEBUG_PRINT("Runtime: "); DEBUG_PRINTLN(millis());
DEBUG_PRINT("Unix time: "); DEBUG_PRINTLN(now());
DEBUG_PRINT("Free heap: "); DEBUG_PRINTLN(ESP.getFreeHeap());
DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(WiFi.status());
if (WiFi.status() != lastWifiState)
{
wifiStateChangedTime = millis();
}
lastWifiState = WiFi.status();
DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime);
DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime);
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP());
debugTime = millis();
}
yield();
if (!realtimeActive) //block stuff if WARLS/Adalight is enabled
{
if (dnsActive) dnsServer.processNextRequest();
#ifndef WLED_DISABLE_OTA
if (aOtaEnabled) ArduinoOTA.handle();
#endif
handleNightlight();
if (!onlyAP) {
handleHue();
handleBlynk();
}
if (briT) strip.service(); //do not update strip if off, prevents flicker on ESP32
}
//DEBUG serial logging
#ifdef WLED_DEBUG
if (millis() - debugTime > 5000)
{
DEBUG_PRINTLN("---MODULE DEBUG INFO---");
DEBUG_PRINT("Runtime: "); DEBUG_PRINTLN(millis());
DEBUG_PRINT("Unix time: "); DEBUG_PRINTLN(now());
DEBUG_PRINT("Free heap: "); DEBUG_PRINTLN(ESP.getFreeHeap());
DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(WiFi.status());
if (WiFi.status() != lastWifiState)
{
wifiStateChangedTime = millis();
}
lastWifiState = WiFi.status();
DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime);
DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime);
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP());
debugTime = millis();
}
#endif
}

View File

@@ -6,7 +6,7 @@
#define EEPSIZE 3072
//eeprom Version code, enables default settings instead of 0 init on update
#define EEPVER 9
#define EEPVER 10
//0 -> old version, default
//1 -> 0.4p 1711272 and up
//2 -> 0.4p 1711302 and up
@@ -17,6 +17,8 @@
//7 -> 0.7.1 and up
//8 -> 0.8.0-a and up
//9 -> 0.8.0
//10-> 0.8.2
/*
* Erase all configuration data
@@ -30,6 +32,7 @@ void clearEEPROM()
EEPROM.commit();
}
void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len)
{
for (int i = 0; i < len; ++i)
@@ -39,6 +42,7 @@ void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len)
}
}
void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len)
{
for (int i = 0; i < len; ++i)
@@ -49,6 +53,7 @@ void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len)
str[len] = 0; //make sure every string is properly terminated. str must be at least len +1 big.
}
/*
* Write configuration to flash
*/
@@ -66,12 +71,12 @@ void saveSettingsToEEPROM()
writeStringToEEPROM(128, apSSID, 32);
writeStringToEEPROM(160, apPass, 64);
EEPROM.write(224, nightlightDelayMins);
EEPROM.write(224, nightlightDelayMinsDefault);
EEPROM.write(225, nightlightFade);
EEPROM.write(226, notifyDirectDefault);
EEPROM.write(227, apChannel);
EEPROM.write(228, apHide);
EEPROM.write(229, (ledCount >> 0) & 0xFF);
EEPROM.write(229, ledCount & 0xFF);
EEPROM.write(230, notifyButton);
EEPROM.write(231, notifyTwice);
EEPROM.write(232, buttonEnabled);
@@ -92,7 +97,7 @@ void saveSettingsToEEPROM()
EEPROM.write(250, receiveNotificationBrightness);
EEPROM.write(251, fadeTransition);
EEPROM.write(252, reverseMode);
EEPROM.write(253, (transitionDelayDefault >> 0) & 0xFF);
EEPROM.write(253, transitionDelayDefault & 0xFF);
EEPROM.write(254, (transitionDelayDefault >> 8) & 0xFF);
EEPROM.write(255, briMultiplier);
@@ -101,7 +106,7 @@ void saveSettingsToEEPROM()
EEPROM.write(288, nightlightTargetBri);
EEPROM.write(289, otaLock);
EEPROM.write(290, (udpPort >> 0) & 0xFF);
EEPROM.write(290, udpPort & 0xFF);
EEPROM.write(291, (udpPort >> 8) & 0xFF);
writeStringToEEPROM(292, serverDescription, 32);
@@ -138,14 +143,19 @@ void saveSettingsToEEPROM()
EEPROM.write(380, colSecS[2]);
EEPROM.write(381, whiteSecS);
EEPROM.write(382, strip.paletteBlend);
EEPROM.write(383, strip.colorOrder);
EEPROM.write(385, irEnabled);
EEPROM.write(387, strip.ablMilliampsMax & 0xFF);
EEPROM.write(388, (strip.ablMilliampsMax >> 8) & 0xFF);
EEPROM.write(389, bootPreset);
EEPROM.write(390, aOtaEnabled);
EEPROM.write(391, receiveNotificationColor);
EEPROM.write(392, receiveNotificationEffects);
EEPROM.write(393, wifiLock);
EEPROM.write(394, (abs(utcOffsetSecs) >> 0) & 0xFF);
EEPROM.write(394, abs(utcOffsetSecs) & 0xFF);
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
EEPROM.write(396, (utcOffsetSecs<0)); //is negative
EEPROM.write(397, initLedsLast);
@@ -170,7 +180,7 @@ void saveSettingsToEEPROM()
EEPROM.write(i, hueIP[i-2050]);
}
writeStringToEEPROM(2054, hueApiKey, 46);
EEPROM.write(2100, (huePollIntervalMs >> 0) & 0xFF);
EEPROM.write(2100, huePollIntervalMs & 0xFF);
EEPROM.write(2101, (huePollIntervalMs >> 8) & 0xFF);
EEPROM.write(2102, notifyHue);
EEPROM.write(2103, hueApplyOnOff);
@@ -205,10 +215,10 @@ void saveSettingsToEEPROM()
EEPROM.write(2180, macroCountdown);
EEPROM.write(2181, macroNl);
EEPROM.write(2190, (e131Universe >> 0) & 0xFF);
EEPROM.write(2190, e131Universe & 0xFF);
EEPROM.write(2191, (e131Universe >> 8) & 0xFF);
EEPROM.write(2192, e131Multicast);
EEPROM.write(2193, (realtimeTimeoutMs >> 0) & 0xFF);
EEPROM.write(2193, realtimeTimeoutMs & 0xFF);
EEPROM.write(2194, (realtimeTimeoutMs >> 8) & 0xFF);
EEPROM.write(2195, arlsForceMaxBri);
EEPROM.write(2196, arlsDisableGammaCorrection);
@@ -222,7 +232,7 @@ void saveSettingsToEEPROM()
if (saveCurrPresetCycConf)
{
EEPROM.write(2205, presetCyclingEnabled);
EEPROM.write(2206, (presetCycleTime >> 0) & 0xFF);
EEPROM.write(2206, presetCycleTime & 0xFF);
EEPROM.write(2207, (presetCycleTime >> 8) & 0xFF);
EEPROM.write(2208, presetCycleMin);
EEPROM.write(2209, presetCycleMax);
@@ -246,9 +256,10 @@ void saveSettingsToEEPROM()
writeStringToEEPROM(2333, mqttDeviceTopic, 32);
writeStringToEEPROM(2366, mqttGroupTopic, 32);
EEPROM.commit();
commit();
}
/*
* Read all configuration from flash
*/
@@ -256,7 +267,9 @@ void loadSettingsFromEEPROM(bool first)
{
if (EEPROM.read(233) != 233) //first boot/reset to default
{
DEBUG_PRINT("Settings invalid, restoring defaults...");
saveSettingsToEEPROM();
DEBUG_PRINTLN("done");
return;
}
int lastEEPROMversion = EEPROM.read(377); //last EEPROM version before update
@@ -268,7 +281,8 @@ void loadSettingsFromEEPROM(bool first)
readStringFromEEPROM(128, apSSID, 32);
readStringFromEEPROM(160, apPass, 64);
nightlightDelayMins = EEPROM.read(224);
nightlightDelayMinsDefault = EEPROM.read(224);
nightlightDelayMins = nightlightDelayMinsDefault;
nightlightFade = EEPROM.read(225);
notifyDirectDefault = EEPROM.read(226);
notifyDirect = notifyDirectDefault;
@@ -277,7 +291,7 @@ void loadSettingsFromEEPROM(bool first)
if (apChannel > 13 || apChannel < 1) apChannel = 1;
apHide = EEPROM.read(228);
if (apHide > 1) apHide = 1;
ledCount = ((EEPROM.read(229) << 0) & 0xFF) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 10;
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 30;
notifyButton = EEPROM.read(230);
notifyTwice = EEPROM.read(231);
@@ -307,7 +321,7 @@ void loadSettingsFromEEPROM(bool first)
receiveNotificationBrightness = EEPROM.read(250);
fadeTransition = EEPROM.read(251);
reverseMode = EEPROM.read(252);
transitionDelayDefault = ((EEPROM.read(253) << 0) & 0xFF) + ((EEPROM.read(254) << 8) & 0xFF00);
transitionDelayDefault = EEPROM.read(253) + ((EEPROM.read(254) << 8) & 0xFF00);
transitionDelay = transitionDelayDefault;
briMultiplier = EEPROM.read(255);
@@ -315,7 +329,7 @@ void loadSettingsFromEEPROM(bool first)
nightlightTargetBri = EEPROM.read(288);
otaLock = EEPROM.read(289);
udpPort = ((EEPROM.read(290) << 0) & 0xFF) + ((EEPROM.read(291) << 8) & 0xFF00);
udpPort = EEPROM.read(290) + ((EEPROM.read(291) << 8) & 0xFF00);
readStringFromEEPROM(292, serverDescription, 32);
@@ -377,7 +391,7 @@ void loadSettingsFromEEPROM(bool first)
readStringFromEEPROM(2054, hueApiKey, 46);
huePollIntervalMs = ((EEPROM.read(2100) << 0) & 0xFF) + ((EEPROM.read(2101) << 8) & 0xFF00);
huePollIntervalMs = EEPROM.read(2100) + ((EEPROM.read(2101) << 8) & 0xFF00);
notifyHue = EEPROM.read(2102);
hueApplyOnOff = EEPROM.read(2103);
hueApplyBri = EEPROM.read(2104);
@@ -413,9 +427,9 @@ void loadSettingsFromEEPROM(bool first)
if (lastEEPROMversion > 6)
{
e131Universe = ((EEPROM.read(2190) << 0) & 0xFF) + ((EEPROM.read(2191) << 8) & 0xFF00);
e131Universe = EEPROM.read(2190) + ((EEPROM.read(2191) << 8) & 0xFF00);
e131Multicast = EEPROM.read(2192);
realtimeTimeoutMs = ((EEPROM.read(2193) << 0) & 0xFF) + ((EEPROM.read(2194) << 8) & 0xFF00);
realtimeTimeoutMs = EEPROM.read(2193) + ((EEPROM.read(2194) << 8) & 0xFF00);
arlsForceMaxBri = EEPROM.read(2195);
arlsDisableGammaCorrection = EEPROM.read(2196);
}
@@ -430,8 +444,8 @@ void loadSettingsFromEEPROM(bool first)
timerHours[i] = EEPROM.read(2260 + i);
timerMinutes[i] = EEPROM.read(2270 + i);
timerWeekday[i] = EEPROM.read(2280 + i);
timerMacro[i] = EEPROM.read(2290 + i);
if (timerWeekday[i] == 0) timerWeekday[i] = 255;
timerMacro[i] = EEPROM.read(2290 + i);
}
}
@@ -441,12 +455,24 @@ void loadSettingsFromEEPROM(bool first)
readStringFromEEPROM(2333, mqttDeviceTopic, 32);
readStringFromEEPROM(2366, mqttGroupTopic, 32);
}
if (lastEEPROMversion > 9)
{
strip.colorOrder = EEPROM.read(383);
irEnabled = EEPROM.read(385);
strip.ablMilliampsMax = EEPROM.read(387) + ((EEPROM.read(388) << 8) & 0xFF00);
} else if (lastEEPROMversion > 1) //ABL is off by default when updating from version older than 0.8.2
{
strip.ablMilliampsMax = 65000;
} else {
strip.ablMilliampsMax = ABL_MILLIAMPS_DEFAULT;
}
receiveDirect = !EEPROM.read(2200);
enableRealtimeUI = EEPROM.read(2201);
uiConfiguration = EEPROM.read(2202);
#ifdef WLED_FLASH_512K_MODE
#ifdef WLED_DISABLE_MOBILE_UI
uiConfiguration = 1;
//force default UI since mobile is unavailable
#endif
@@ -457,7 +483,7 @@ void loadSettingsFromEEPROM(bool first)
if (EEPROM.read(2210) || EEPROM.read(2211) || EEPROM.read(2212))
{
presetCyclingEnabled = EEPROM.read(2205);
presetCycleTime = ((EEPROM.read(2206) << 0) & 0xFF) + ((EEPROM.read(2207) << 8) & 0xFF00);
presetCycleTime = EEPROM.read(2206) + ((EEPROM.read(2207) << 8) & 0xFF00);
presetCycleMin = EEPROM.read(2208);
presetCycleMax = EEPROM.read(2209);
presetApplyBri = EEPROM.read(2210);
@@ -467,7 +493,7 @@ void loadSettingsFromEEPROM(bool first)
bootPreset = EEPROM.read(389);
wifiLock = EEPROM.read(393);
utcOffsetSecs = ((EEPROM.read(394) << 0) & 0xFF) + ((EEPROM.read(395) << 8) & 0xFF00);
utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00);
if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative
initLedsLast = EEPROM.read(397);
enableSecTransition = !EEPROM.read(399);
@@ -491,23 +517,24 @@ void loadSettingsFromEEPROM(bool first)
useHSB = useHSBDefault;
strip.setMode(effectCurrent);
strip.setSpeed(effectSpeed);
strip.setIntensity(effectIntensity);
strip.setPalette(effectPalette);
overlayCurrent = overlayDefault;
}
//PRESET PROTOCOL 20 bytes
//0: preset purpose byte 0:invalid 1:valid preset 1.0
//1:a 2:r 3:g 4:b 5:w 6:er 7:eg 8:eb 9:ew 10:fx 11:sx | custom chase 12:numP 13:numS 14:(0:fs 1:both 2:fe) 15:step 16:ix 17: fp 18-19:Zeros
void applyPreset(byte index, bool loadBri, bool loadCol, bool loadFX)
bool applyPreset(byte index, bool loadBri = true, bool loadCol = true, bool loadFX = true)
{
if (index == 255 || index == 0) loadSettingsFromEEPROM(false);//load boot defaults
if (index > 25 || index < 1) return;
if (index == 255 || index == 0)
{
loadSettingsFromEEPROM(false);//load boot defaults
return true;
}
if (index > 25 || index < 1) return false;
uint16_t i = 380 + index*20;
if (EEPROM.read(i) == 0) return;
if (EEPROM.read(i) == 0) return false;
if (loadBri) bri = EEPROM.read(i+1);
if (loadCol)
{
@@ -522,16 +549,12 @@ void applyPreset(byte index, bool loadBri, bool loadCol, bool loadFX)
}
if (loadFX)
{
byte lastfx = effectCurrent;
effectCurrent = EEPROM.read(i+10);
effectSpeed = EEPROM.read(i+11);
effectIntensity = EEPROM.read(i+16);
effectPalette = EEPROM.read(i+17);
if (lastfx != effectCurrent) strip.setMode(effectCurrent);
strip.setSpeed(effectSpeed);
strip.setIntensity(effectIntensity);
strip.setPalette(effectPalette);
}
return true;
}
void savePreset(byte index)
@@ -554,9 +577,10 @@ void savePreset(byte index)
EEPROM.write(i+16, effectIntensity);
EEPROM.write(i+17, effectPalette);
EEPROM.commit();
commit();
}
String loadMacro(byte index)
{
index-=1;
@@ -567,10 +591,10 @@ String loadMacro(byte index)
if (EEPROM.read(i) == 0) break;
m += char(EEPROM.read(i));
}
if (m.charAt(0) < 65 || m.charAt(0) > 90) return ""; //do simple check if macro is valid (capital first letter)
return m;
}
void applyMacro(byte index)
{
index-=1;
@@ -589,6 +613,7 @@ void applyMacro(byte index)
handleSet(mc);
}
void saveMacro(byte index, String mc, bool sing=true) //only commit on single save, not in settings
{
index-=1;
@@ -598,6 +623,23 @@ void saveMacro(byte index, String mc, bool sing=true) //only commit on single sa
{
EEPROM.write(i, mc.charAt(i-s));
}
if (sing) EEPROM.commit();
if (sing) commit();
}
void commit()
{
DEBUG_PRINT("s");
//this is to support IR on ESP32, needs work
/*#ifdef ARDUINO_ARCH_ESP32
portMUX_TYPE mMux = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&mMux);
#endif*/
EEPROM.commit();
/*#ifdef ARDUINO_ARCH_ESP32
portEXIT_CRITICAL(&mMux);
#endif*/
DEBUG_PRINT(".");
}

View File

@@ -2,60 +2,78 @@
* Sending XML status files to client
*/
void XML_response(bool isHTTP)
//build XML response to HTTP /win API request
void XML_response(bool isHTTP, bool includeTheme)
{
olen = 0;
oappend("<?xml version = \"1.0\" ?><vs><ac>");
if (nightlightActive && nightlightFade)
{
oappendi(briT);
} else
{
oappendi(bri);
}
oappend("</ac>");
for (int i = 0; i < 3; i++)
{
oappend("<cl>");
oappendi(col[i]);
oappend("</cl>");
}
oappend("<ns>");
oappendi(notifyDirect);
oappend("</ns><nr>");
oappendi(receiveNotifications);
oappend("</nr><nl>");
oappendi(nightlightActive);
oappend("</nl><nf>");
oappendi(nightlightFade);
oappend("</nf><nd>");
oappendi(nightlightDelayMins);
oappend("</nd><nt>");
oappendi(nightlightTargetBri);
oappend("</nt><fx>");
oappendi(effectCurrent);
oappend("</fx><sx>");
oappendi(effectSpeed);
oappend("</sx><ix>");
oappendi(effectIntensity);
oappend("</ix><fp>");
oappendi(effectPalette);
oappend("</fp><wv>");
if (useRGBW && !autoRGBtoRGBW) {
oappendi(white);
} else {
oappend("-1");
}
oappend("</wv><md>");
oappendi(useHSB);
oappend("</md><ds>");
oappend(serverDescription);
oappend("</ds></vs>");
if (isHTTP) server.send(200, "text/xml", obuf);
olen = 0;
oappend("<?xml version = \"1.0\" ?><vs><ac>");
oappendi((nightlightActive && nightlightFade) ? briT : bri);
oappend("</ac>");
for (int i = 0; i < 3; i++)
{
oappend("<cl>");
oappendi(col[i]);
oappend("</cl>");
}
oappend("<ns>");
oappendi(notifyDirect);
oappend("</ns><nr>");
oappendi(receiveNotifications);
oappend("</nr><nl>");
oappendi(nightlightActive);
oappend("</nl><nf>");
oappendi(nightlightFade);
oappend("</nf><nd>");
oappendi(nightlightDelayMins);
oappend("</nd><nt>");
oappendi(nightlightTargetBri);
oappend("</nt><fx>");
oappendi(effectCurrent);
oappend("</fx><sx>");
oappendi(effectSpeed);
oappend("</sx><ix>");
oappendi(effectIntensity);
oappend("</ix><fp>");
oappendi(effectPalette);
oappend("</fp><wv>");
if (useRGBW && !autoRGBtoRGBW) {
oappendi(white);
} else {
oappend("-1");
}
oappend("</wv><md>");
oappendi(useHSB);
oappend("</md><ds>");
oappend(serverDescription);
oappend("</ds>");
if (includeTheme)
{
char cs[6][9];
getThemeColors(cs);
oappend("<th><ca>#");
oappend(cs[0]);
oappend("</ca><cb>#");
oappend(cs[1]);
oappend("</cb><cc>#");
oappend(cs[2]);
oappend("</cc><cd>#");
oappend(cs[3]);
oappend("</cd><cs>#");
oappend(cs[4]);
oappend("</cs><ct>#");
oappend(cs[5]);
oappend("</ct><cf>");
oappend(cssFont);
oappend("</cf></th>");
}
oappend("</vs>");
if (isHTTP) server.send(200, "text/xml", obuf);
}
void sappend(char stype, char* key, int val) //append a setting to string buffer
//append a numeric setting to string buffer
void sappend(char stype, char* key, int val)
{
char ds[] = "d.Sf.";
@@ -85,28 +103,30 @@ void sappend(char stype, char* key, int val) //append a setting to string buffer
}
}
void sappends(char stype, char* key, char* val) //append a string setting
//append a string setting to buffer
void sappends(char stype, char* key, char* val)
{
switch(stype)
{
case 's': //string (we can interpret val as char*)
oappend("d.Sf.");
oappend(key);
oappend(".value=\"");
oappend(val);
oappend("\";");
break;
oappend("d.Sf.");
oappend(key);
oappend(".value=\"");
oappend(val);
oappend("\";");
break;
case 'm': //message
oappend("d.getElementsByClassName");
oappend(key);
oappend(".innerHTML=\"");
oappend(val);
oappend("\";");
break;
oappend("d.getElementsByClassName");
oappend(key);
oappend(".innerHTML=\"");
oappend(val);
oappend("\";");
break;
}
}
void getSettingsJS(byte subPage) //get values for settings form in javascript
//get values for settings form in javascript
void getSettingsJS(byte subPage)
{
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec
DEBUG_PRINT("settings resp");
@@ -171,11 +191,20 @@ void getSettingsJS(byte subPage) //get values for settings form in javascript
if (subPage == 2) {
sappend('v',"LC",ledCount);
sappend('v',"MA",strip.ablMilliampsMax);
if (strip.currentMilliamps)
{
sappends('m',"(\"pow\")[0]","");
olen -= 2; //delete ";
oappendi(strip.currentMilliamps);
oappend("mA\";");
}
sappend('v',"CR",colS[0]);
sappend('v',"CG",colS[1]);
sappend('v',"CB",colS[2]);
sappend('v',"CA",briS);
sappend('c',"EW",useRGBW);
sappend('i',"CO",strip.colorOrder);
sappend('c',"AW",autoRGBtoRGBW);
sappend('v',"CW",whiteS);
sappend('v',"SR",colSecS[0]);
@@ -196,7 +225,7 @@ void getSettingsJS(byte subPage) //get values for settings form in javascript
sappend('c',"T2",enableSecTransition);
sappend('v',"BF",briMultiplier);
sappend('v',"TB",nightlightTargetBri);
sappend('v',"TL",nightlightDelayMins);
sappend('v',"TL",nightlightDelayMinsDefault);
sappend('c',"TW",nightlightFade);
sappend('i',"PB",strip.paletteBlend);
sappend('c',"RV",reverseMode);
@@ -222,6 +251,7 @@ void getSettingsJS(byte subPage) //get values for settings form in javascript
if (subPage == 4)
{
sappend('c',"BT",buttonEnabled);
sappend('c',"IR",irEnabled);
sappend('v',"UP",udpPort);
sappend('c',"RB",receiveNotificationBrightness);
sappend('c',"RC",receiveNotificationColor);
@@ -321,3 +351,29 @@ void getSettingsJS(byte subPage) //get values for settings form in javascript
}
oappend("}</script>");
}
//get colors from current theme as c strings
void getThemeColors(char o[][9])
{
switch (currentTheme)
{
// accent color (aCol) background (bCol) panel (cCol) controls (dCol) shadows (sCol) text (tCol)
default: strcpy(o[0], "D9B310"); strcpy(o[1], "0B3C5D"); strcpy(o[2], "1D2731"); strcpy(o[3], "328CC1"); strcpy(o[4], "000"); strcpy(o[5], "328CC1"); break; //night
case 1: strcpy(o[0], "eee"); strcpy(o[1], "ddd"); strcpy(o[2], "b9b9b9"); strcpy(o[3], "049"); strcpy(o[4], "777"); strcpy(o[5], "049"); break; //modern
case 2: strcpy(o[0], "abc"); strcpy(o[1], "fff"); strcpy(o[2], "ddd"); strcpy(o[3], "000"); strcpy(o[4], "0004"); strcpy(o[5], "000"); break; //bright
case 3: strcpy(o[0], "c09f80"); strcpy(o[1], "d7cec7"); strcpy(o[2], "76323f"); strcpy(o[3], "888"); strcpy(o[4], "3334"); strcpy(o[5], "888"); break; //wine
case 4: strcpy(o[0], "3cc47c"); strcpy(o[1], "828081"); strcpy(o[2], "d9a803"); strcpy(o[3], "1e392a"); strcpy(o[4], "000a"); strcpy(o[5], "1e392a"); break; //electric
case 5: strcpy(o[0], "57bc90"); strcpy(o[1], "a5a5af"); strcpy(o[2], "015249"); strcpy(o[3], "88c9d4"); strcpy(o[4], "0004"); strcpy(o[5], "88c9d4"); break; //mint
case 6: strcpy(o[0], "f7c331"); strcpy(o[1], "dcc7aa"); strcpy(o[2], "6b7a8f"); strcpy(o[3], "f7882f"); strcpy(o[4], "0007"); strcpy(o[5], "f7882f"); break; //amber
case 7: strcpy(o[0], "fc3"); strcpy(o[1], "124"); strcpy(o[2], "334"); strcpy(o[3], "f1d"); strcpy(o[4], "f00"); strcpy(o[5], "f1d"); break; //club
case 8: strcpy(o[0], "0ac"); strcpy(o[1], "124"); strcpy(o[2], "224"); strcpy(o[3], "003eff"); strcpy(o[4], "003eff"); strcpy(o[5], "003eff"); break; //air
case 9: strcpy(o[0], "f70"); strcpy(o[1], "421"); strcpy(o[2], "221"); strcpy(o[3], "a50"); strcpy(o[4], "f70"); strcpy(o[5], "f70"); break; //nixie
case 10: strcpy(o[0], "2d2"); strcpy(o[1], "010"); strcpy(o[2], "121"); strcpy(o[3], "060"); strcpy(o[4], "040"); strcpy(o[5], "3f3"); break; //terminal
case 11: strcpy(o[0], "867ADE"); strcpy(o[1], "4033A3"); strcpy(o[2], "483AAA"); strcpy(o[3], "483AAA"); strcpy(o[4], ""); strcpy(o[5], "867ADE"); break; //c64
case 12: strcpy(o[0], "fbe8a6"); strcpy(o[1], "d2fdff"); strcpy(o[2], "b4dfe5"); strcpy(o[3], "f4976c"); strcpy(o[4], ""); strcpy(o[5], "303c6c"); break; //easter
case 13: strcpy(o[0], "d4af37"); strcpy(o[1], "173305"); strcpy(o[2], "308505"); strcpy(o[3], "f21313"); strcpy(o[4], "f002"); strcpy(o[5], "d4af37"); break; //christmas
case 14: strcpy(o[0], "fc7"); strcpy(o[1], "49274a"); strcpy(o[2], "94618e"); strcpy(o[3], "f4decb"); strcpy(o[4], "0008"); strcpy(o[5], "f4decb"); break; //end
case 15: for (int i=0;i<6;i++) strcpy(o[i], cssCol[i]); //custom
}
}

View File

@@ -59,9 +59,13 @@ void handleSettingsSet(byte subPage)
#ifdef ARDUINO_ARCH_ESP32
if (ledCount > 600) ledCount = 600;
#endif
strip.ablMilliampsMax = server.arg("MA").toInt();
useRGBW = server.hasArg("EW");
strip.colorOrder = server.arg("CO").toInt();
autoRGBtoRGBW = server.hasArg("AW");
if (server.hasArg("IS")) //ignore settings and save current brightness, colors and fx as default
//ignore settings and save current brightness, colors and fx as default
if (server.hasArg("IS"))
{
colS[0] = col[0];
colS[1] = col[1];
@@ -107,7 +111,7 @@ void handleSettingsSet(byte subPage)
nightlightTargetBri = server.arg("TB").toInt();
t = server.arg("TL").toInt();
if (t > 0) nightlightDelayMins = t;
if (t > 0) nightlightDelayMinsDefault = t;
nightlightFade = server.hasArg("TW");
t = server.arg("PB").toInt();
@@ -136,13 +140,13 @@ void handleSettingsSet(byte subPage)
strcpy(cssCol[i],server.arg(k).c_str());
}
strcpy(cssFont,server.arg("CF").c_str());
buildCssColorString();
}
//SYNC
if (subPage == 4)
{
buttonEnabled = server.hasArg("BT");
irEnabled = server.hasArg("IR");
int t = server.arg("UP").toInt();
if (t > 0) udpPort = t;
receiveNotificationBrightness = server.hasArg("RB");
@@ -170,7 +174,9 @@ void handleSettingsSet(byte subPage)
strcpy(alexaInvocationName, server.arg("AI").c_str());
notifyAlexa = server.hasArg("SA");
if (server.hasArg("BK") && !server.arg("BK").equals("Hidden")) {strcpy(blynkApiKey,server.arg("BK").c_str()); initBlynk(blynkApiKey);}
if (server.hasArg("BK") && !server.arg("BK").equals("Hidden")) {
strcpy(blynkApiKey,server.arg("BK").c_str()); initBlynk(blynkApiKey);
}
strcpy(mqttServer, server.arg("MS").c_str());
strcpy(mqttDeviceTopic, server.arg("MD").c_str());
@@ -209,10 +215,13 @@ void handleSettingsSet(byte subPage)
useAMPM = !server.hasArg("CF");
currentTimezone = server.arg("TZ").toInt();
utcOffsetSecs = server.arg("UO").toInt();
if (ntpEnabled && WiFi.status() == WL_CONNECTED && !ntpConnected) ntpConnected = ntpUdp.begin(ntpLocalPort); //start if not already connected
//start ntp if not already connected
if (ntpEnabled && WiFi.status() == WL_CONNECTED && !ntpConnected) ntpConnected = ntpUdp.begin(ntpLocalPort);
if (server.hasArg("OL")){
overlayDefault = server.arg("OL").toInt();
if (overlayCurrent != overlayDefault) strip.unlockAll();
overlayCurrent = overlayDefault;
}
@@ -273,7 +282,7 @@ void handleSettingsSet(byte subPage)
if (server.hasArg("RS")) //complete factory reset
{
clearEEPROM();
serveMessage(200, "All Settings erased.", "Connect to WLED-AP to setup again...",255);
serveMessage(200, "All Settings erased.", "Connect to WLED-AP to setup again",255);
reset();
}
@@ -302,453 +311,425 @@ void handleSettingsSet(byte subPage)
if (subPage == 2) strip.init(useRGBW,ledCount,skipFirstLed);
}
//helper to get int value at a position in string
int getNumVal(String* req, uint16_t pos)
{
return req->substring(pos + 3).toInt();
}
//HTTP API request parser
bool handleSet(String req)
{
bool effectUpdated = false;
if (!(req.indexOf("win") >= 0)) return false;
if (!(req.indexOf("win") >= 0)) return false;
int pos = 0;
DEBUG_PRINT("API req: ");
DEBUG_PRINTLN(req);
int pos = 0;
DEBUG_PRINT("API req: ");
DEBUG_PRINTLN(req);
//save macro, requires &MS=<slot>(<macro>) format
pos = req.indexOf("&MS=");
if (pos > 0) {
int i = req.substring(pos + 4).toInt();
pos = req.indexOf('(') +1;
if (pos > 0) {
int en = req.indexOf(')');
String mc = req.substring(pos);
if (en > 0) mc = req.substring(pos, en);
saveMacro(i, mc);
}
pos = req.indexOf("IN");
if (pos < 1) XML_response(true, false);
return true;
//if you save a macro in one request, other commands in that request are ignored due to unwanted behavior otherwise
}
//save macro, requires &MS=<slot>(<macro>) format
pos = req.indexOf("&MS=");
if (pos > 0) {
int i = req.substring(pos + 4).toInt();
pos = req.indexOf('(') +1;
if (pos > 0) {
int en = req.indexOf(')');
String mc = req.substring(pos);
if (en > 0) mc = req.substring(pos, en);
saveMacro(i, mc);
}
pos = req.indexOf("IN");
if (pos < 1) XML_response(true);
return true;
//if you save a macro in one request, other commands in that request are ignored due to unwanted behavior otherwise
}
//set brigthness
pos = req.indexOf("&A=");
if (pos > 0) {
bri = req.substring(pos + 3).toInt();
}
//set brigthness
pos = req.indexOf("&A=");
if (pos > 0) {
bri = getNumVal(&req, pos);
}
//set hue
pos = req.indexOf("HU=");
if (pos > 0) {
uint16_t temphue = req.substring(pos + 3).toInt();
byte tempsat = 255;
pos = req.indexOf("SA=");
if (pos > 0) {
tempsat = req.substring(pos + 3).toInt();
}
colorHStoRGB(temphue,tempsat,(req.indexOf("H2")>0)? colSec:col);
}
//set hue
pos = req.indexOf("HU=");
if (pos > 0) {
uint16_t temphue = getNumVal(&req, pos);
byte tempsat = 255;
pos = req.indexOf("SA=");
if (pos > 0) {
tempsat = getNumVal(&req, pos);
}
colorHStoRGB(temphue,tempsat,(req.indexOf("H2")>0)? colSec:col);
}
//set red value
pos = req.indexOf("&R=");
if (pos > 0) {
col[0] = req.substring(pos + 3).toInt();
}
//set green value
pos = req.indexOf("&G=");
if (pos > 0) {
col[1] = req.substring(pos + 3).toInt();
}
//set blue value
pos = req.indexOf("&B=");
if (pos > 0) {
col[2] = req.substring(pos + 3).toInt();
}
//set white value
pos = req.indexOf("&W=");
if (pos > 0) {
white = req.substring(pos + 3).toInt();
}
//set red value
pos = req.indexOf("&R=");
if (pos > 0) {
col[0] = getNumVal(&req, pos);
}
//set green value
pos = req.indexOf("&G=");
if (pos > 0) {
col[1] = getNumVal(&req, pos);
}
//set blue value
pos = req.indexOf("&B=");
if (pos > 0) {
col[2] = getNumVal(&req, pos);
}
//set white value
pos = req.indexOf("&W=");
if (pos > 0) {
white = getNumVal(&req, pos);
}
//set 2nd red value
pos = req.indexOf("R2=");
if (pos > 0) {
colSec[0] = req.substring(pos + 3).toInt();
}
//set 2nd green value
pos = req.indexOf("G2=");
if (pos > 0) {
colSec[1] = req.substring(pos + 3).toInt();
}
//set 2nd blue value
pos = req.indexOf("B2=");
if (pos > 0) {
colSec[2] = req.substring(pos + 3).toInt();
}
//set 2nd white value
pos = req.indexOf("W2=");
if (pos > 0) {
whiteSec = req.substring(pos + 3).toInt();
}
//set 2nd red value
pos = req.indexOf("R2=");
if (pos > 0) {
colSec[0] = getNumVal(&req, pos);
}
//set 2nd green value
pos = req.indexOf("G2=");
if (pos > 0) {
colSec[1] = getNumVal(&req, pos);
}
//set 2nd blue value
pos = req.indexOf("B2=");
if (pos > 0) {
colSec[2] = getNumVal(&req, pos);
}
//set 2nd white value
pos = req.indexOf("W2=");
if (pos > 0) {
whiteSec = getNumVal(&req, pos);
}
//set color from HEX or 32bit DEC
pos = req.indexOf("CL=");
if (pos > 0) {
colorFromDecOrHexString(col, &white, (char*)req.substring(pos + 3).c_str());
}
pos = req.indexOf("C2=");
if (pos > 0) {
colorFromDecOrHexString(colSec, &whiteSec, (char*)req.substring(pos + 3).c_str());
}
//set color from HEX or 32bit DEC
pos = req.indexOf("CL=");
if (pos > 0) {
colorFromDecOrHexString(col, &white, (char*)req.substring(pos + 3).c_str());
}
pos = req.indexOf("C2=");
if (pos > 0) {
colorFromDecOrHexString(colSec, &whiteSec, (char*)req.substring(pos + 3).c_str());
}
//set 2nd to white
pos = req.indexOf("SW");
if (pos > 0) {
if(useRGBW) {
whiteSec = 255;
colSec[0] = 0;
colSec[1] = 0;
colSec[2] = 0;
} else {
colSec[0] = 255;
colSec[1] = 255;
colSec[2] = 255;
}
}
//set 2nd to black
pos = req.indexOf("SB");
if (pos > 0) {
whiteSec = 0;
//set 2nd to white
pos = req.indexOf("SW");
if (pos > 0) {
if(useRGBW) {
whiteSec = 255;
colSec[0] = 0;
colSec[1] = 0;
colSec[2] = 0;
}
} else {
colSec[0] = 255;
colSec[1] = 255;
colSec[2] = 255;
}
}
//set to random hue SR=0->1st SR=1->2nd
pos = req.indexOf("SR");
if (pos > 0) {
_setRandomColor(req.substring(pos + 3).toInt());
}
//set 2nd to 1st
pos = req.indexOf("SP");
if (pos > 0) {
colSec[0] = col[0];
colSec[1] = col[1];
colSec[2] = col[2];
whiteSec = white;
}
//swap 2nd & 1st
pos = req.indexOf("SC");
if (pos > 0) {
byte _temp[4];
for (int i = 0; i<3; i++)
{
_temp[i] = col[i];
col[i] = colSec[i];
colSec[i] = _temp[i];
}
_temp[3] = white;
white = whiteSec;
whiteSec = _temp[3];
}
//set 2nd to black
pos = req.indexOf("SB");
if (pos > 0) {
whiteSec = 0;
colSec[0] = 0;
colSec[1] = 0;
colSec[2] = 0;
}
//set current effect index
pos = req.indexOf("FX=");
if (pos > 0) {
if (effectCurrent != req.substring(pos + 3).toInt())
{
effectCurrent = req.substring(pos + 3).toInt();
strip.setMode(effectCurrent);
effectUpdated = true;
}
}
//set effect speed
pos = req.indexOf("SX=");
if (pos > 0) {
if (effectSpeed != req.substring(pos + 3).toInt())
{
effectSpeed = req.substring(pos + 3).toInt();
strip.setSpeed(effectSpeed);
effectUpdated = true;
}
}
//set effect intensity
pos = req.indexOf("IX=");
if (pos > 0) {
if (effectIntensity != req.substring(pos + 3).toInt())
{
effectIntensity = req.substring(pos + 3).toInt();
strip.setIntensity(effectIntensity);
effectUpdated = true;
}
}
//set effect palette (only for FastLED effects)
pos = req.indexOf("FP=");
if (pos > 0) {
if (effectPalette != req.substring(pos + 3).toInt())
{
effectPalette = req.substring(pos + 3).toInt();
strip.setPalette(effectPalette);
effectUpdated = true;
}
}
//set to random hue SR=0->1st SR=1->2nd
pos = req.indexOf("SR");
if (pos > 0) {
_setRandomColor(getNumVal(&req, pos));
}
//set 2nd to 1st
pos = req.indexOf("SP");
if (pos > 0) {
colSec[0] = col[0];
colSec[1] = col[1];
colSec[2] = col[2];
whiteSec = white;
}
//swap 2nd & 1st
pos = req.indexOf("SC");
if (pos > 0) {
byte _temp[4];
for (int i = 0; i<3; i++)
{
_temp[i] = col[i];
col[i] = colSec[i];
colSec[i] = _temp[i];
}
_temp[3] = white;
white = whiteSec;
whiteSec = _temp[3];
}
//set current effect index
pos = req.indexOf("FX=");
if (pos > 0) {
effectCurrent = getNumVal(&req, pos);
}
//set effect speed
pos = req.indexOf("SX=");
if (pos > 0) {
effectSpeed = getNumVal(&req, pos);
}
//set effect intensity
pos = req.indexOf("IX=");
if (pos > 0) {
effectIntensity = req.substring(pos + 3).toInt();
}
//set effect palette (only for FastLED effects)
pos = req.indexOf("FP=");
if (pos > 0) {
effectPalette = req.substring(pos + 3).toInt();
}
//set hue polling light: 0 -off
pos = req.indexOf("HP=");
if (pos > 0) {
int id = req.substring(pos + 3).toInt();
if (id > 0)
{
if (id < 100) huePollLightId = id;
setupHue();
} else {
huePollingEnabled = false;
}
}
//set hue polling light: 0 -off
pos = req.indexOf("HP=");
if (pos > 0) {
int id = getNumVal(&req, pos);
if (id > 0)
{
if (id < 100) huePollLightId = id;
setupHue();
} else {
huePollingEnabled = false;
}
}
//set default control mode (0 - RGB, 1 - HSB)
pos = req.indexOf("MD=");
if (pos > 0) {
useHSB = req.substring(pos + 3).toInt();
}
//set advanced overlay
pos = req.indexOf("OL=");
if (pos > 0) {
overlayCurrent = req.substring(pos + 3).toInt();
strip.unlockAll();
}
//(un)lock pixel (ranges)
pos = req.indexOf("&L=");
if (pos > 0){
int index = req.substring(pos + 3).toInt();
pos = req.indexOf("L2=");
if (pos > 0){
int index2 = req.substring(pos + 3).toInt();
if (req.indexOf("UL") > 0)
{
strip.unlockRange(index, index2);
} else
{
strip.lockRange(index, index2);
}
//set default control mode (0 - RGB, 1 - HSB)
pos = req.indexOf("MD=");
if (pos > 0) {
useHSB = getNumVal(&req, pos);
}
//set advanced overlay
pos = req.indexOf("OL=");
if (pos > 0) {
overlayCurrent = getNumVal(&req, pos);
strip.unlockAll();
}
//(un)lock pixel (ranges)
pos = req.indexOf("&L=");
if (pos > 0){
int index = getNumVal(&req, pos);
pos = req.indexOf("L2=");
if (pos > 0){
int index2 = getNumVal(&req, pos);
if (req.indexOf("UL") > 0)
{
strip.unlockRange(index, index2);
} else
{
if (req.indexOf("UL") > 0)
{
strip.unlock(index);
} else
{
strip.lock(index);
}
strip.lockRange(index, index2);
}
}
} else
{
if (req.indexOf("UL") > 0)
{
strip.unlock(index);
} else
{
strip.lock(index);
}
}
}
//apply macro
pos = req.indexOf("&M=");
if (pos > 0) {
applyMacro(req.substring(pos + 3).toInt());
}
//toggle send UDP direct notifications
if (req.indexOf("SN=") > 0)
{
notifyDirect = true;
if (req.indexOf("SN=0") > 0)
{
notifyDirect = false;
}
}
//apply macro
pos = req.indexOf("&M=");
if (pos > 0) {
applyMacro(getNumVal(&req, pos));
}
//toggle send UDP direct notifications
if (req.indexOf("SN=") > 0)
{
notifyDirect = true;
if (req.indexOf("SN=0") > 0)
{
notifyDirect = false;
}
}
//toggle receive UDP direct notifications
if (req.indexOf("RN=") > 0)
{
receiveNotifications = true;
if (req.indexOf("RN=0") > 0)
{
receiveNotifications = false;
}
}
//toggle receive UDP direct notifications
if (req.indexOf("RN=") > 0)
{
receiveNotifications = true;
if (req.indexOf("RN=0") > 0)
{
receiveNotifications = false;
}
}
//toggle nightlight mode
bool aNlDef = false;
if (req.indexOf("&ND") > 0) aNlDef = true;
pos = req.indexOf("NL=");
if (pos > 0)
{
if (req.indexOf("NL=0") > 0)
{
nightlightActive = false;
bri = briT;
} else {
nightlightActive = true;
if (!aNlDef) nightlightDelayMins = req.substring(pos + 3).toInt();
nightlightStartTime = millis();
}
} else if (aNlDef)
{
//toggle nightlight mode
bool aNlDef = false;
if (req.indexOf("&ND") > 0) aNlDef = true;
pos = req.indexOf("NL=");
if (pos > 0)
{
if (req.indexOf("NL=0") > 0)
{
nightlightActive = false;
bri = briT;
} else {
nightlightActive = true;
if (!aNlDef) nightlightDelayMins = getNumVal(&req, pos);
nightlightStartTime = millis();
}
}
} else if (aNlDef)
{
nightlightActive = true;
nightlightStartTime = millis();
}
//set nightlight target brightness
pos = req.indexOf("NT=");
if (pos > 0) {
nightlightTargetBri = req.substring(pos + 3).toInt();
nightlightActiveOld = false; //re-init
}
//set nightlight target brightness
pos = req.indexOf("NT=");
if (pos > 0) {
nightlightTargetBri = getNumVal(&req, pos);
nightlightActiveOld = false; //re-init
}
//toggle nightlight fade
if (req.indexOf("NF=") > 0)
{
if (req.indexOf("NF=0") > 0)
{
nightlightFade = false;
} else {
nightlightFade = true;
}
nightlightActiveOld = false; //re-init
}
//toggle nightlight fade
if (req.indexOf("NF=") > 0)
{
if (req.indexOf("NF=0") > 0)
{
nightlightFade = false;
} else {
nightlightFade = true;
}
nightlightActiveOld = false; //re-init
}
//toggle general purpose output
pos = req.indexOf("AX=");
if (pos > 0) {
auxTime = req.substring(pos + 3).toInt();
auxActive = true;
if (auxTime == 0) auxActive = false;
}
pos = req.indexOf("TT=");
if (pos > 0) {
transitionDelay = req.substring(pos + 3).toInt();
}
//toggle general purpose output
pos = req.indexOf("AX=");
if (pos > 0) {
auxTime = getNumVal(&req, pos);
auxActive = true;
if (auxTime == 0) auxActive = false;
}
pos = req.indexOf("TT=");
if (pos > 0) {
transitionDelay = getNumVal(&req, pos);
}
//main toggle on/off
pos = req.indexOf("&T=");
if (pos > 0) {
nightlightActive = false; //always disable nightlight when toggling
switch (req.substring(pos + 3).toInt())
{
case 0: if (bri != 0){briLast = bri; bri = 0;} break; //off
case 1: bri = briLast; break; //on
default: if (bri == 0) //toggle
{
bri = briLast;
} else
{
briLast = bri;
bri = 0;
}
}
}
//main toggle on/off
pos = req.indexOf("&T=");
if (pos > 0) {
nightlightActive = false; //always disable nightlight when toggling
switch (getNumVal(&req, pos))
{
case 0: if (bri != 0){briLast = bri; bri = 0;} break; //off
case 1: bri = briLast; break; //on
default: toggleOnOff(); //toggle
}
}
//deactivate nightlight if target brightness is reached
if (bri == nightlightTargetBri) nightlightActive = false;
//set time (unix timestamp)
pos = req.indexOf("ST=");
if (pos > 0) {
setTime(req.substring(pos+3).toInt());
}
//deactivate nightlight if target brightness is reached
if (bri == nightlightTargetBri) nightlightActive = false;
//set time (unix timestamp)
pos = req.indexOf("ST=");
if (pos > 0) {
setTime(getNumVal(&req, pos));
}
//set countdown goal (unix timestamp)
pos = req.indexOf("CT=");
if (pos > 0) {
countdownTime = req.substring(pos+3).toInt();
if (countdownTime - now() > 0) countdownOverTriggered = false;
}
//set countdown goal (unix timestamp)
pos = req.indexOf("CT=");
if (pos > 0) {
countdownTime = getNumVal(&req, pos);
if (countdownTime - now() > 0) countdownOverTriggered = false;
}
//set presets
pos = req.indexOf("P1="); //sets first preset for cycle
if (pos > 0) presetCycleMin = req.substring(pos + 3).toInt();
pos = req.indexOf("P2="); //sets last preset for cycle
if (pos > 0) presetCycleMax = req.substring(pos + 3).toInt();
//set presets
pos = req.indexOf("P1="); //sets first preset for cycle
if (pos > 0) presetCycleMin = getNumVal(&req, pos);
pos = req.indexOf("P2="); //sets last preset for cycle
if (pos > 0) presetCycleMax = getNumVal(&req, pos);
if (req.indexOf("CY=") > 0) //preset cycle
{
presetCyclingEnabled = true;
if (req.indexOf("CY=0") > 0)
{
presetCyclingEnabled = false;
}
presetCycCurr = presetCycleMin;
}
pos = req.indexOf("PT="); //sets cycle time in ms
if (pos > 0) {
int v = req.substring(pos + 3).toInt();
if (v > 49) presetCycleTime = v;
}
if (req.indexOf("PA=") > 0) //apply brightness from preset
{
presetApplyBri = true;
if (req.indexOf("PA=0") > 0) presetApplyBri = false;
}
if (req.indexOf("PC=") > 0) //apply color from preset
{
presetApplyCol = true;
if (req.indexOf("PC=0") > 0) presetApplyCol = false;
}
if (req.indexOf("PX=") > 0) //apply effects from preset
{
presetApplyFx = true;
if (req.indexOf("PX=0") > 0) presetApplyFx = false;
}
pos = req.indexOf("PS="); //saves current in preset
if (pos > 0) {
savePreset(req.substring(pos + 3).toInt());
}
pos = req.indexOf("PL="); //applies entire preset
if (pos > 0) {
applyPreset(req.substring(pos + 3).toInt(), presetApplyBri, presetApplyCol, presetApplyFx);
if (presetApplyFx) effectUpdated = true;
}
//cronixie
pos = req.indexOf("NX="); //sets digits to code
if (pos > 0) {
strcpy(cronixieDisplay,req.substring(pos + 3, pos + 9).c_str());
setCronixie();
}
pos = req.indexOf("NM="); //mode, 1 countdown
if (pos > 0) {
countdownMode = true;
if (req.indexOf("NM=0") > 0)
{
countdownMode = false;
}
}
if (req.indexOf("NB=") > 0) //sets backlight
{
cronixieBacklight = true;
if (req.indexOf("NB=0") > 0)
{
cronixieBacklight = false;
}
if (overlayCurrent == 3) strip.setCronixieBacklight(cronixieBacklight);
overlayRefreshedTime = 0;
}
pos = req.indexOf("U0="); //user var 0
if (pos > 0) {
userVar0 = req.substring(pos + 3).toInt();
}
pos = req.indexOf("U1="); //user var 1
if (pos > 0) {
userVar1 = req.substring(pos + 3).toInt();
}
//you can add more if you need
if (req.indexOf("CY=") > 0) //preset cycle
{
presetCyclingEnabled = true;
if (req.indexOf("CY=0") > 0)
{
presetCyclingEnabled = false;
}
presetCycCurr = presetCycleMin;
}
pos = req.indexOf("PT="); //sets cycle time in ms
if (pos > 0) {
int v = getNumVal(&req, pos);
if (v > 49) presetCycleTime = v;
}
if (req.indexOf("PA=") > 0) //apply brightness from preset
{
presetApplyBri = true;
if (req.indexOf("PA=0") > 0) presetApplyBri = false;
}
if (req.indexOf("PC=") > 0) //apply color from preset
{
presetApplyCol = true;
if (req.indexOf("PC=0") > 0) presetApplyCol = false;
}
if (req.indexOf("PX=") > 0) //apply effects from preset
{
presetApplyFx = true;
if (req.indexOf("PX=0") > 0) presetApplyFx = false;
}
pos = req.indexOf("PS="); //saves current in preset
if (pos > 0) {
savePreset(getNumVal(&req, pos));
}
pos = req.indexOf("PL="); //applies entire preset
if (pos > 0) {
applyPreset(getNumVal(&req, pos), presetApplyBri, presetApplyCol, presetApplyFx);
}
//cronixie
pos = req.indexOf("NX="); //sets digits to code
if (pos > 0) {
strcpy(cronixieDisplay,req.substring(pos + 3, pos + 9).c_str());
setCronixie();
}
pos = req.indexOf("NM="); //mode, 1 countdown
if (pos > 0) {
countdownMode = true;
if (req.indexOf("NM=0") > 0)
{
countdownMode = false;
}
}
if (req.indexOf("NB=") > 0) //sets backlight
{
cronixieBacklight = true;
if (req.indexOf("NB=0") > 0)
{
cronixieBacklight = false;
}
if (overlayCurrent == 3) strip.setCronixieBacklight(cronixieBacklight);
overlayRefreshedTime = 0;
}
pos = req.indexOf("U0="); //user var 0
if (pos > 0) {
userVar0 = getNumVal(&req, pos);
}
pos = req.indexOf("U1="); //user var 1
if (pos > 0) {
userVar1 = getNumVal(&req, pos);
}
//you can add more if you need
//internal call, does not send XML response
pos = req.indexOf("IN");
if (pos < 1) XML_response(true);
//do not send UDP notifications this time
pos = req.indexOf("NN");
if (pos > 0)
{
colorUpdated(5);
return true;
}
if (effectUpdated)
{
colorUpdated(6);
} else
{
colorUpdated(1);
}
return true;
//internal call, does not send XML response
pos = req.indexOf("IN");
if (pos < 1) XML_response(true, (req.indexOf("IT") > 0)); //include theme if firstload
pos = req.indexOf("NN"); //do not send UDP notifications this time
colorUpdated((pos > 0) ? 5:1);
return true;
}

View File

@@ -3,36 +3,37 @@
*/
void handleSerial()
{
if (Serial.available() > 0) //support for Adalight protocol to high-speed control LEDs over serial (gamma correction done by PC)
if (Serial.available() > 0) //support for Adalight protocol to high-speed control LEDs over serial
{
if (Serial.find("Ada"))
if (!Serial.find("Ada")) return;
if (!realtimeActive && bri == 0) strip.setBrightness(briLast);
arlsLock(realtimeTimeoutMs);
delay(1);
byte hi = Serial.read();
byte ledc = Serial.read();
byte chk = Serial.read();
if(chk != (hi ^ ledc ^ 0x55)) return;
if (ledCount < ledc) ledc = ledCount;
byte sc[3]; int t =-1; int to = 0;
for (int i=0; i < ledc; i++)
{
if (!realtimeActive && bri == 0) strip.setBrightness(briLast);
arlsLock(realtimeTimeoutMs);
delay(1);
byte hi = Serial.read();
byte ledc = Serial.read();
byte chk = Serial.read();
if(chk != (hi ^ ledc ^ 0x55)) return;
if (ledCount < ledc) ledc = ledCount;
byte sc[3]; int t =-1; int to = 0;
for (int i=0; i < ledc; i++)
for (byte j=0; j<3; j++)
{
for (byte j=0; j<3; j++)
while (Serial.peek()<0) //no data yet available
{
while (Serial.peek()<0) //no data yet available
{
delay(1);
to++;
if (to>5) {strip.show(); return;} //unexpected end of transmission
}
to = 0;
sc[j] = Serial.read();
delay(1);
to++;
if (to>5) {strip.show(); return;} //unexpected end of transmission
}
setRealtimePixel(i,sc[0],sc[1],sc[2],0);
to = 0;
sc[j] = Serial.read();
}
strip.show();
setRealtimePixel(i,sc[0],sc[1],sc[2],0);
}
strip.show();
}
}

View File

@@ -5,10 +5,11 @@
void wledInit()
{
EEPROM.begin(EEPSIZE);
ledCount = ((EEPROM.read(229) << 0) & 0xFF) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 10;
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00);
if (ledCount > 1200 || ledCount == 0) ledCount = 30;
//RMT eats up too much RAM
#ifdef ARDUINO_ARCH_ESP32
if (ledCount > 600) ledCount = 600;
if (ledCount > 600) ledCount = 600;
#endif
if (!EEPROM.read(397)) strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //quick init
@@ -16,7 +17,7 @@ void wledInit()
Serial.setTimeout(50);
#ifdef USEFS
SPIFFS.begin();
SPIFFS.begin();
#endif
DEBUG_PRINTLN("Load EEPROM");
@@ -24,7 +25,6 @@ void wledInit()
if (!initLedsLast) initStrip();
DEBUG_PRINT("CSSID: ");
DEBUG_PRINT(clientSSID);
buildCssColorString();
userBeginPreConnection();
if (strcmp(clientSSID,"Your_Network") == 0) showWelcomePage = true;
@@ -86,6 +86,7 @@ void wledInit()
//init ArduinoOTA
if (!onlyAP) {
#ifndef WLED_DISABLE_OTA
if (aOtaEnabled)
{
ArduinoOTA.onStart([]() {
@@ -97,6 +98,7 @@ void wledInit()
if (strlen(cmDNS) > 0) ArduinoOTA.setHostname(cmDNS);
ArduinoOTA.begin();
}
#endif
if (!initLedsLast) strip.service();
// Set up mDNS responder:
@@ -119,10 +121,12 @@ void wledInit()
if (initLedsLast) initStrip();
userBegin();
if (macroBoot>0) applyMacro(macroBoot);
Serial.println("Ada");
}
void initStrip()
{
// Initialize NeoPixel Strip and button
@@ -131,15 +135,16 @@ void initStrip()
strip.setColor(0);
strip.setBrightness(255);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(4,OUTPUT); //this is only needed in special cases
digitalWrite(4,LOW);
pinMode(BTNPIN, INPUT_PULLUP);
if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true);
colorUpdated(0);
if(digitalRead(buttonPin) == LOW) buttonEnabled = false; //disable button if it is "pressed" unintentionally
//disable button if it is "pressed" unintentionally
if(digitalRead(BTNPIN) == LOW) buttonEnabled = false;
}
void initAP(){
bool set = apSSID[0];
if (!set) strcpy(apSSID,"WLED-AP");
@@ -147,6 +152,7 @@ void initAP(){
if (!set) apSSID[0] = 0;
}
void initCon()
{
WiFi.disconnect(); //close old connections
@@ -170,13 +176,14 @@ void initCon()
WiFi.softAPdisconnect(true);
}
int fail_count = 0;
if (strlen(clientSSID) <1 || strcmp(clientSSID,"Your_Network") == 0) fail_count = apWaitTimeSecs*2; //instantly go to ap mode
if (strlen(clientSSID) <1 || strcmp(clientSSID,"Your_Network") == 0)
fail_count = apWaitTimeSecs*2; //instantly go to ap mode
#ifndef ARDUINO_ARCH_ESP32
WiFi.hostname(serverDescription);
WiFi.hostname(serverDescription);
#endif
WiFi.begin(clientSSID, clientPass);
WiFi.begin(clientSSID, clientPass);
#ifdef ARDUINO_ARCH_ESP32
WiFi.setHostname(serverDescription);
WiFi.setHostname(serverDescription);
#endif
unsigned long lastTry = 0;
bool con = false;
@@ -208,9 +215,9 @@ void initCon()
}
//fill string buffer with build info
void getBuildInfo()
{
//fill string buffer with build info
olen = 0;
oappend("hard-coded build info:\r\n\n");
#ifdef ARDUINO_ARCH_ESP32
@@ -224,25 +231,46 @@ void getBuildInfo()
oappendi(VERSION);
oappend("\r\neepver: ");
oappendi(EEPVER);
oappend("\r\nesp-core: ");
#ifdef ARDUINO_ARCH_ESP32
oappend((char*)ESP.getSdkVersion());
#else
oappend((char*)ESP.getCoreVersion().c_str());
#endif
oappend("\r\nopt: ");
#ifndef WLED_DISABLE_ALEXA
oappend("alexa ");
#endif
#ifndef WLED_DISABLE_BLYNK
oappend("blynk ");
#endif
#ifndef WLED_DISABLE_CRONIXIE
oappend("cronixie ");
#endif
#ifndef WLED_DISABLE_HUESYNC
oappend("huesync ");
#endif
#ifndef WLED_DISABLE_MOBILE_UI
oappend("mobile-ui ");
#endif
#ifndef WLED_DISABLE_OTA
oappend("ota");
#endif
#ifdef USEFS
oappend("\r\nspiffs: true\r\n");
#else
oappend("\r\nspiffs: false\r\n");
#endif
#ifdef DEBUG
#ifdef WLED_DEBUG
oappend("debug: true\r\n");
#else
oappend("debug: false\r\n");
#endif
oappend("button-pin: gpio");
oappendi(buttonPin);
oappend("\r\n");
#ifdef ARDUINO_ARCH_ESP32
oappend("strip-pin: gpio");
oappendi(BTNPIN);
oappend("\r\nstrip-pin: gpio");
oappendi(LEDPIN);
#else
oappend("strip-pin: gpio2");
#endif
oappend("\r\nbrand: wled");
oappend("\r\nbuild-type: src\r\n");
}
@@ -255,6 +283,3 @@ bool checkClientIsMobile(String useragent)
if (useragent.indexOf("iPod") >= 0) return true;
return false;
}

View File

@@ -3,6 +3,8 @@
*/
#define WLEDPACKETSIZE 24
#define UDP_IN_MAXSIZE 1472
void notify(byte callMode, bool followUp=false)
{
@@ -52,6 +54,7 @@ void notify(byte callMode, bool followUp=false)
notificationTwoRequired = (followUp)? false:notifyTwice;
}
void arlsLock(uint32_t timeoutMs)
{
if (!realtimeActive){
@@ -59,13 +62,14 @@ void arlsLock(uint32_t timeoutMs)
{
strip.setPixelColor(i,0,0,0,0);
}
strip.setMode(0);
strip.unlockAll();
}
realtimeActive = true;
realtimeTimeout = millis() + timeoutMs;
if (arlsForceMaxBri) strip.setBrightness(255);
}
void initE131(){
if (WiFi.status() == WL_CONNECTED && e131Enabled)
{
@@ -76,6 +80,29 @@ void initE131(){
}
}
void handleE131(){
//E1.31 protocol support
if(e131Enabled) {
uint16_t len = e131->parsePacket();
if (!len || e131->universe < e131Universe || e131->universe > e131Universe +4) return;
len /= 3; //one LED is 3 DMX channels
uint16_t multipacketOffset = (e131->universe - e131Universe)*170; //if more than 170 LEDs (510 channels), client will send in next higher universe
if (ledCount <= multipacketOffset) return;
arlsLock(realtimeTimeoutMs);
if (len + multipacketOffset > ledCount) len = ledCount - multipacketOffset;
for (uint16_t i = 0; i < len; i++) {
int j = i * 3;
setRealtimePixel(i + multipacketOffset, e131->data[j], e131->data[j+1], e131->data[j+2], 0);
}
strip.show();
}
}
void handleNotifications()
{
//send second notification if enabled
@@ -83,73 +110,65 @@ void handleNotifications()
notify(notificationSentCallMode,true);
}
//E1.31 protocol support
if(e131Enabled) {
uint16_t len = e131->parsePacket();
if (len && e131->universe == e131Universe) {
arlsLock(realtimeTimeoutMs);
if (len > ledCount) len = ledCount;
for (uint16_t i = 0; i < len; i++) {
int j = i * 3;
setRealtimePixel(i, e131->data[j], e131->data[j+1], e131->data[j+2], 0);
}
strip.show();
}
}
handleE131();
//unlock strip when realtime UDP times out
if (realtimeActive && millis() > realtimeTimeout)
{
strip.unlockAll();
//strip.unlockAll();
strip.setBrightness(bri);
realtimeActive = false;
strip.setMode(effectCurrent);
//strip.setMode(effectCurrent);
realtimeIP[0] = 0;
}
//receive UDP notifications
if(udpConnected && (receiveNotifications || receiveDirect)){
uint16_t packetSize = notifierUdp.parsePacket();
//hyperion / raw RGB
if (!packetSize && udpRgbConnected) {
packetSize = rgbUdp.parsePacket();
if (!receiveDirect) return;
if (packetSize > 1026 || packetSize < 3) return;
realtimeIP = rgbUdp.remoteIP();
DEBUG_PRINTLN(rgbUdp.remoteIP());
byte udpIn[packetSize];
rgbUdp.read(udpIn, packetSize);
arlsLock(realtimeTimeoutMs);
uint16_t id = 0;
for (uint16_t i = 0; i < packetSize -2; i += 3)
{
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
id++; if (id >= ledCount) break;
}
strip.show();
return;
}
if (!udpConnected || !(receiveNotifications || receiveDirect)) return;
if (packetSize > 1026) return;
if(packetSize && notifierUdp.remoteIP() != WiFi.localIP()) //don't process broadcasts we send ourselves
uint16_t packetSize = notifierUdp.parsePacket();
//hyperion / raw RGB
if (!packetSize && udpRgbConnected) {
packetSize = rgbUdp.parsePacket();
if (!receiveDirect) return;
if (packetSize > UDP_IN_MAXSIZE || packetSize < 3) return;
realtimeIP = rgbUdp.remoteIP();
DEBUG_PRINTLN(rgbUdp.remoteIP());
olen = 0;
rgbUdp.read(obuf, packetSize);
arlsLock(realtimeTimeoutMs);
uint16_t id = 0;
for (uint16_t i = 0; i < packetSize -2; i += 3)
{
byte udpIn[packetSize];
notifierUdp.read(udpIn, packetSize);
if (udpIn[0] == 0 && !realtimeActive && receiveNotifications) //wled notifier, block if realtime packets active
setRealtimePixel(id, obuf[i], obuf[i+1], obuf[i+2], 0);
id++; if (id >= ledCount) break;
}
strip.show();
return;
}
//notifier and UDP realtime
if (packetSize > UDP_IN_MAXSIZE) return;
if(packetSize && notifierUdp.remoteIP() != WiFi.localIP()) //don't process broadcasts we send ourselves
{
olen = 0;
notifierUdp.read(obuf, packetSize);
char* udpIn = obuf;
//wled notifier, block if realtime packets active
if (udpIn[0] == 0 && !realtimeActive && receiveNotifications)
{
//apply colors from notification
if (receiveNotificationColor)
{
if (receiveNotificationColor)
{
col[0] = udpIn[3];
col[1] = udpIn[4];
col[2] = udpIn[5];
}
if (udpIn[11] > 0 && receiveNotificationColor) //check if sending modules white val is inteded
if (udpIn[11] > 0) //check if sending modules white val is inteded
{
white = udpIn[10];
if (udpIn[11] > 1 )
if (udpIn[11] > 1)
{
colSec[0] = udpIn[12];
colSec[1] = udpIn[13];
@@ -157,79 +176,81 @@ void handleNotifications()
whiteSec = udpIn[15];
}
}
if (udpIn[8] != effectCurrent && receiveNotificationEffects)
{
effectCurrent = udpIn[8];
strip.setMode(effectCurrent);
}
if (udpIn[9] != effectSpeed && receiveNotificationEffects)
{
effectSpeed = udpIn[9];
strip.setSpeed(effectSpeed);
}
if (udpIn[11] > 2 && udpIn[16] != effectIntensity && receiveNotificationEffects)
{
effectIntensity = udpIn[16];
strip.setIntensity(effectIntensity);
}
if (udpIn[11] > 3)
{
transitionDelayTemp = ((udpIn[17] << 0) & 0xFF) + ((udpIn[18] << 8) & 0xFF00);
}
if (udpIn[11] > 4 && udpIn[19] != effectPalette && receiveNotificationEffects)
{
effectPalette = udpIn[19];
strip.setPalette(effectPalette);
}
nightlightActive = udpIn[6];
if (!nightlightActive)
{
if (receiveNotificationBrightness) bri = udpIn[2];
colorUpdated(3);
}
} else if (udpIn[0] > 0 && udpIn[0] < 4 && receiveDirect) //1 warls //2 drgb //3 drgbw
{
realtimeIP = notifierUdp.remoteIP();
DEBUG_PRINTLN(notifierUdp.remoteIP());
if (packetSize > 1) {
if (udpIn[1] == 0)
{
realtimeActive = false;
} else {
arlsLock(udpIn[1]*1000);
}
if (udpIn[0] == 1) //warls
{
for (uint16_t i = 2; i < packetSize -3; i += 4)
{
setRealtimePixel(udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3], 0);
}
} else if (udpIn[0] == 2) //drgb
{
uint16_t id = 0;
for (uint16_t i = 2; i < packetSize -2; i += 3)
{
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
}
id++; if (id >= ledCount) break;
}
} else if (udpIn[0] == 3) //drgbw
{
uint16_t id = 0;
for (uint16_t i = 2; i < packetSize -3; i += 4)
{
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
id++; if (id >= ledCount) break;
}
}
strip.show();
//apply effects from notification
if (receiveNotificationEffects)
{
effectCurrent = udpIn[8];
effectSpeed = udpIn[9];
if (udpIn[11] > 2) effectIntensity = udpIn[16];
if (udpIn[11] > 4) effectPalette = udpIn[19];
}
if (udpIn[11] > 3)
{
transitionDelayTemp = ((udpIn[17] << 0) & 0xFF) + ((udpIn[18] << 8) & 0xFF00);
}
nightlightActive = udpIn[6];
if (nightlightActive) nightlightDelayMins = udpIn[7];
if (receiveNotificationBrightness) bri = udpIn[2];
colorUpdated(3);
} else if (udpIn[0] > 0 && udpIn[0] < 4 && receiveDirect) //1 warls //2 drgb //3 drgbw
{
realtimeIP = notifierUdp.remoteIP();
DEBUG_PRINTLN(notifierUdp.remoteIP());
if (packetSize > 1) {
if (udpIn[1] == 0)
{
realtimeActive = false;
return;
} else {
arlsLock(udpIn[1]*1000);
}
if (udpIn[0] == 1) //warls
{
for (uint16_t i = 2; i < packetSize -3; i += 4)
{
setRealtimePixel(udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3], 0);
}
} else if (udpIn[0] == 2) //drgb
{
uint16_t id = 0;
for (uint16_t i = 2; i < packetSize -2; i += 3)
{
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
id++; if (id >= ledCount) break;
}
} else if (udpIn[0] == 3) //drgbw
{
uint16_t id = 0;
for (uint16_t i = 2; i < packetSize -3; i += 4)
{
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
id++; if (id >= ledCount) break;
}
} else if (udpIn[0] == 4) //dnrgb
{
uint16_t id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00);
for (uint16_t i = 4; i < packetSize -2; i += 3)
{
if (id >= ledCount) break;
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
id++;
}
}
strip.show();
}
}
}
}
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w)
{
uint16_t pix = i + arlsOffset;
@@ -243,5 +264,3 @@ void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w)
}
}
}

View File

@@ -2,6 +2,19 @@
* LED methods
*/
void toggleOnOff()
{
if (bri == 0)
{
bri = briLast;
} else
{
briLast = bri;
bri = 0;
}
}
void setAllLeds() {
if (!realtimeActive || !arlsForceMaxBri)
{
@@ -38,6 +51,7 @@ void setAllLeds() {
}
}
void setLedsStandard()
{
for (byte i = 0; i<3; i++)
@@ -56,6 +70,7 @@ void setLedsStandard()
setAllLeds();
}
bool colorChanged()
{
for (int i = 0; i < 3; i++)
@@ -68,12 +83,19 @@ bool colorChanged()
return false;
}
void colorUpdated(int callMode)
{
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (NN)6: fx changed 7: hue 8: preset cycle 9: blynk
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
// 6: fx changed 7: hue 8: preset cycle 9: blynk
bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette);
if (!colorChanged())
{
if (callMode == 6) notify(6);
if (nightlightActive && !nightlightActiveOld && callMode != 3 && callMode != 5)
{
notify(4); return;
}
else if (fxChanged) notify(6);
return; //no change
}
if (callMode != 5 && nightlightActive && nightlightFade)
@@ -133,6 +155,7 @@ void colorUpdated(int callMode)
updateInterfaces(callMode);
}
void updateInterfaces(uint8_t callMode)
{
if (callMode != 9 && callMode != 5) updateBlynk();
@@ -140,6 +163,7 @@ void updateInterfaces(uint8_t callMode)
lastInterfaceUpdate = millis();
}
void handleTransitions()
{
//handle still pending interface update
@@ -180,6 +204,7 @@ void handleTransitions()
}
}
void handleNightlight()
{
if (nightlightActive)
@@ -187,7 +212,6 @@ void handleNightlight()
if (!nightlightActiveOld) //init
{
nightlightStartTime = millis();
notify(4);
nightlightDelayMs = (int)(nightlightDelayMins*60000);
nightlightActiveOld = true;
briNlT = bri;
@@ -195,7 +219,7 @@ void handleNightlight()
float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs);
if (nightlightFade)
{
bri = briNlT+((nightlightTargetBri - briNlT)*nper);
bri = briNlT + ((nightlightTargetBri - briNlT)*nper);
colorUpdated(5);
}
if (nper >= 1)

View File

@@ -6,15 +6,15 @@ void handleButton()
{
if (buttonEnabled)
{
if (digitalRead(buttonPin) == LOW && !buttonPressedBefore)
if (digitalRead(BTNPIN) == LOW && !buttonPressedBefore)
{
buttonPressedTime = millis();
buttonPressedBefore = true;
}
else if (digitalRead(buttonPin) == HIGH && buttonPressedBefore)
else if (digitalRead(BTNPIN) == HIGH && buttonPressedBefore)
{
delay(15); //debounce
if (digitalRead(buttonPin) == HIGH)
if (digitalRead(BTNPIN) == HIGH)
{
if (millis() - buttonPressedTime > 7000) {initAP();}
else if (millis() - buttonPressedTime > 700)
@@ -25,14 +25,7 @@ void handleButton()
else {
if (macroButton == 0)
{
if (bri == 0)
{
bri = briLast;
} else
{
briLast = bri;
bri = 0;
}
toggleOnOff();
colorUpdated(2);
} else {
applyMacro(macroButton);
@@ -51,9 +44,9 @@ void handleButton()
auxActiveBefore = true;
switch (auxTriggeredState)
{
case 0: pinMode(auxPin, INPUT); break;
case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break;
case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break;
case 0: pinMode(AUXPIN, INPUT); break;
case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break;
case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break;
}
auxStartTime = millis();
}
@@ -63,9 +56,9 @@ void handleButton()
auxActiveBefore = false;
switch (auxDefaultState)
{
case 0: pinMode(auxPin, INPUT); break;
case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break;
case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break;
case 0: pinMode(AUXPIN, INPUT); break;
case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break;
case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break;
}
}
}

View File

@@ -171,9 +171,9 @@ void _overlayAnalogClock()
int pix;
for (int i = 0; i <= 12; i++)
{
pix = overlayMin + analogClock12pixel + (overlaySize/12)*i;
if (pix > overlayMax) pix = pix - overlayMax;
strip.setIndividual(pix,0x00FFAA);
pix = analogClock12pixel + round((overlaySize / 12.0) *i);
if (pix > overlayMax) pix -= overlaySize;
strip.setIndividual(pix, 0x00FFAA);
}
}
if (!analogClockSecondsTrail) strip.setIndividual(secondPixel, 0xFF0000);
@@ -184,7 +184,7 @@ void _overlayAnalogClock()
void _overlayNixieClock()
{
#ifdef WLED_FLASH_512K_MODE
#ifdef WLED_DISABLE_CRONIXIE
if (countdownMode) checkCountdown();
#else

View File

@@ -5,40 +5,41 @@
* https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch
* https://github.com/probonopd/ESP8266HueEmulator
*/
void prepareIds() {
escapedMac = WiFi.macAddress();
escapedMac.replace(":", "");
escapedMac.toLowerCase();
}
#ifndef WLED_DISABLE_ALEXA
void alexaInit()
{
if (alexaEnabled && WiFi.status() == WL_CONNECTED)
{
udpConnected = connectUDP();
alexaUdpConnected = connectUDP();
if (udpConnected) alexaInitPages();
if (alexaUdpConnected) alexaInitPages();
}
}
void handleAlexa()
{
if (alexaEnabled && WiFi.status() == WL_CONNECTED)
{
if(udpConnected){
// if theres data available, read a packet
int packetSize = alexaUDP.parsePacket();
if(packetSize>0) {
IPAddress remote = alexaUDP.remoteIP();
int len = alexaUDP.read(obuf, 254);
if (len > 0) {
obuf[len] = 0;
}
if(strstr(obuf,"M-SEARCH") > 0) {
if(strstr(obuf,"upnp:rootdevice") > 0 || strstr(obuf,"device:basic:1") > 0) {
DEBUG_PRINTLN("Responding search req...");
respondToSearch();
}
}
}
}
}
if (!alexaEnabled || WiFi.status() != WL_CONNECTED || !alexaUdpConnected) return;
// if there's data available, read a packet
int packetSize = alexaUDP.parsePacket();
if(packetSize < 1) return;
IPAddress remote = alexaUDP.remoteIP();
int len = alexaUDP.read(obuf, 254);
if (len > 0) obuf[len] = 0;
if(strstr(obuf,"M-SEARCH") > 0) {
if(strstr(obuf,"upnp:rootdevice") > 0 || strstr(obuf,"device:basic:1") > 0) {
DEBUG_PRINTLN("Responding search req...");
respondToSearch();
}
}
}
void alexaOn()
@@ -87,133 +88,126 @@ void alexaDim(byte briL)
handleSet(ct);
}
void prepareIds() {
escapedMac = WiFi.macAddress();
escapedMac.replace(":", "");
escapedMac.toLowerCase();
}
void respondToSearch() {
DEBUG_PRINTLN("");
DEBUG_PRINT("Send resp to ");
DEBUG_PRINTLN(alexaUDP.remoteIP());
DEBUG_PRINT("Port : ");
DEBUG_PRINTLN(alexaUDP.remotePort());
DEBUG_PRINTLN("");
DEBUG_PRINT("Send resp to ");
DEBUG_PRINTLN(alexaUDP.remoteIP());
DEBUG_PRINT("Port : ");
DEBUG_PRINTLN(alexaUDP.remotePort());
IPAddress localIP = WiFi.localIP();
char s[16];
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
IPAddress localIP = WiFi.localIP();
char s[16];
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
olen = 0;
oappend(
"HTTP/1.1 200 OK\r\n"
"EXT:\r\n"
"CACHE-CONTROL: max-age=100\r\n" // SSDP_INTERVAL
"LOCATION: http://");
oappend(s);
oappend(":80/description.xml\r\n"
"SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/1.17.0\r\n" // _modelName, _modelNumber
"hue-bridgeid: ");
oappend((char*)escapedMac.c_str());
oappend("\r\n"
"ST: urn:schemas-upnp-org:device:basic:1\r\n" // _deviceType
"USN: uuid:2f402f80-da50-11e1-9b23-");
oappend((char*)escapedMac.c_str());
oappend("::upnp:rootdevice\r\n" // _uuid::_deviceType
"\r\n");
olen = 0;
oappend(
"HTTP/1.1 200 OK\r\n"
"EXT:\r\n"
"CACHE-CONTROL: max-age=100\r\n" // SSDP_INTERVAL
"LOCATION: http://");
oappend(s);
oappend(":80/description.xml\r\n"
"SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/1.17.0\r\n" // _modelName, _modelNumber
"hue-bridgeid: ");
oappend((char*)escapedMac.c_str());
oappend("\r\n"
"ST: urn:schemas-upnp-org:device:basic:1\r\n" // _deviceType
"USN: uuid:2f402f80-da50-11e1-9b23-");
oappend((char*)escapedMac.c_str());
oappend("::upnp:rootdevice\r\n" // _uuid::_deviceType
"\r\n");
alexaUDP.beginPacket(alexaUDP.remoteIP(), alexaUDP.remotePort());
#ifdef ARDUINO_ARCH_ESP32
alexaUDP.write((byte*)obuf, olen);
#else
alexaUDP.write(obuf);
#endif
alexaUDP.endPacket();
alexaUDP.beginPacket(alexaUDP.remoteIP(), alexaUDP.remotePort());
#ifdef ARDUINO_ARCH_ESP32
alexaUDP.write((byte*)obuf, olen);
#else
alexaUDP.write(obuf);
#endif
alexaUDP.endPacket();
DEBUG_PRINTLN("Response sent!");
DEBUG_PRINTLN("Response sent!");
}
void alexaInitPages() {
server.on("/description.xml", HTTP_GET, [](){
DEBUG_PRINTLN(" # Responding to description.xml ... #\n");
IPAddress localIP = WiFi.localIP();
char s[16];
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
olen = 0;
oappend("<?xml version=\"1.0\" ?>"
server.on("/description.xml", HTTP_GET, [](){
DEBUG_PRINTLN(" # Responding to description.xml ... #\n");
IPAddress localIP = WiFi.localIP();
char s[16];
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
olen = 0;
oappend("<?xml version=\"1.0\" ?>"
"<root xmlns=\"urn:schemas-upnp-org:device-1-0\">"
"<specVersion><major>1</major><minor>0</minor></specVersion>"
"<URLBase>http://");
oappend(s);
oappend(":80/</URLBase>"
oappend(s);
oappend(":80/</URLBase>"
"<device>"
"<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>"
"<friendlyName>Philips hue (");
oappend(s);
oappend(")</friendlyName>"
"<manufacturer>Royal Philips Electronics</manufacturer>"
"<manufacturerURL>http://www.philips.com</manufacturerURL>"
"<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>"
"<modelName>Philips hue bridge 2012</modelName>"
"<modelNumber>929000226503</modelNumber>"
"<modelURL>http://www.meethue.com</modelURL>"
"<serialNumber>");
oappend((char*)escapedMac.c_str());
oappend("</serialNumber>"
"<UDN>uuid:2f402f80-da50-11e1-9b23-");
oappend((char*)escapedMac.c_str());
oappend("</UDN>"
"<presentationURL>index.html</presentationURL>"
"<iconList>"
" <icon>"
" <mimetype>image/png</mimetype>"
" <height>48</height>"
" <width>48</width>"
" <depth>24</depth>"
" <url>hue_logo_0.png</url>"
" </icon>"
" <icon>"
" <mimetype>image/png</mimetype>"
" <height>120</height>"
" <width>120</width>"
" <depth>24</depth>"
" <url>hue_logo_3.png</url>"
" </icon>"
"</iconList>"
"<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>"
"<friendlyName>Philips hue (");
oappend(s);
oappend(")</friendlyName>"
"<manufacturer>Royal Philips Electronics</manufacturer>"
"<manufacturerURL>http://www.philips.com</manufacturerURL>"
"<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>"
"<modelName>Philips hue bridge 2012</modelName>"
"<modelNumber>929000226503</modelNumber>"
"<modelURL>http://www.meethue.com</modelURL>"
"<serialNumber>");
oappend((char*)escapedMac.c_str());
oappend("</serialNumber>"
"<UDN>uuid:2f402f80-da50-11e1-9b23-");
oappend((char*)escapedMac.c_str());
oappend("</UDN>"
"<presentationURL>index.html</presentationURL>"
"<iconList>"
" <icon>"
" <mimetype>image/png</mimetype>"
" <height>48</height>"
" <width>48</width>"
" <depth>24</depth>"
" <url>hue_logo_0.png</url>"
" </icon>"
" <icon>"
" <mimetype>image/png</mimetype>"
" <height>120</height>"
" <width>120</width>"
" <depth>24</depth>"
" <url>hue_logo_3.png</url>"
" </icon>"
"</iconList>"
"</device>"
"</root>");
server.send(200, "text/xml", obuf);
DEBUG_PRINTLN("Sending setup_xml");
});
server.send(200, "text/xml", obuf);
DEBUG_PRINTLN("Sending setup_xml");
});
// openHAB support
server.on("/on.html", HTTP_GET, [](){
DEBUG_PRINTLN("on req");
server.send(200, "text/plain", "turned on");
alexaOn();
});
server.on("/off.html", HTTP_GET, [](){
DEBUG_PRINTLN("off req");
server.send(200, "text/plain", "turned off");
alexaOff();
});
server.on("/status.html", HTTP_GET, [](){
DEBUG_PRINTLN("Got status request");
char statrespone[] = "0";
if (bri > 0) {
statrespone[0] = '1';
}
server.send(200, "text/plain", statrespone);
});
// openHAB support
server.on("/on.html", HTTP_GET, [](){
DEBUG_PRINTLN("on req");
server.send(200, "text/plain", "turned on");
alexaOn();
});
server.on("/off.html", HTTP_GET, [](){
DEBUG_PRINTLN("off req");
server.send(200, "text/plain", "turned off");
alexaOff();
});
server.on("/status.html", HTTP_GET, [](){
DEBUG_PRINTLN("Got status request");
char statrespone[] = "0";
if (bri > 0) {
statrespone[0] = '1';
}
server.send(200, "text/plain", statrespone);
});
}
String boolString(bool st)
@@ -288,3 +282,10 @@ bool connectUDP(){
return state;
}
#else
void alexaInit(){}
void handleAlexa(){}
void alexaInitPages(){}
bool handleAlexaApiCall(String req, String body){return false;}
#endif

View File

@@ -19,7 +19,7 @@ byte getSameCodeLength(char code, int index, char const cronixieDisplay[])
void setCronixie()
{
#ifndef WLED_FLASH_512K_MODE
#ifndef WLED_DISABLE_CRONIXIE
/*
* digit purpose index
* 0-9 | 0-9 (incl. random)
@@ -145,73 +145,72 @@ void setCronixie()
void _overlayCronixie()
{
if (countdownMode) checkCountdown();
#ifndef WLED_FLASH_512K_MODE
byte h = hour(local);
byte h0 = h;
byte m = minute(local);
byte s = second(local);
byte d = day(local);
byte mi = month(local);
int y = year(local);
//this has to be changed in time for 22nd century
y -= 2000; if (y<0) y += 30; //makes countdown work
if (countdownMode) checkCountdown();
#ifndef WLED_DISABLE_CRONIXIE
byte h = hour(local);
byte h0 = h;
byte m = minute(local);
byte s = second(local);
byte d = day(local);
byte mi = month(local);
int y = year(local);
//this has to be changed in time for 22nd century
y -= 2000; if (y<0) y += 30; //makes countdown work
if (useAMPM && !countdownMode)
{
if (h>12) h-=12;
else if (h==0) h+=12;
}
byte _digitOut[]{10,10,10,10,10,10};
for (int i = 0; i < 6; i++)
{
if (dP[i] < 12) _digitOut[i] = dP[i];
else {
if (dP[i] < 65)
if (useAMPM && !countdownMode)
{
if (h>12) h-=12;
else if (h==0) h+=12;
}
byte _digitOut[]{10,10,10,10,10,10};
for (int i = 0; i < 6; i++)
{
if (dP[i] < 12) _digitOut[i] = dP[i];
else {
if (dP[i] < 65)
{
switch(dP[i])
{
switch(dP[i])
{
case 21: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; i++; break; //HH
case 25: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; i++; break; //MM
case 31: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; i++; break; //SS
case 21: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; i++; break; //HH
case 25: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; i++; break; //MM
case 31: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; i++; break; //SS
case 20: _digitOut[i] = h- (h/10)*10; break; //H
case 24: _digitOut[i] = m/10; break; //M
case 30: _digitOut[i] = s/10; break; //S
case 43: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //D
case 44: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; i++; break; //DD
case 40: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; i++; break; //II
case 37: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //YY
case 39: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //YYYY
case 16: _digitOut[i+2] = ((h0/3)&1)?1:0; i++; //BBB (BBBB NI)
case 15: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:0; i++; //BB
case 14: _digitOut[i] = (h0>11)?1:0; break; //B
}
} else
case 20: _digitOut[i] = h- (h/10)*10; break; //H
case 24: _digitOut[i] = m/10; break; //M
case 30: _digitOut[i] = s/10; break; //S
case 43: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //D
case 44: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; i++; break; //DD
case 40: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; i++; break; //II
case 37: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //YY
case 39: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //YYYY
case 16: _digitOut[i+2] = ((h0/3)&1)?1:0; i++; //BBB (BBBB NI)
case 15: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:0; i++; //BB
case 14: _digitOut[i] = (h0>11)?1:0; break; //B
}
} else
{
switch(dP[i])
{
switch(dP[i])
{
case 71: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //hh
case 75: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //mm
case 81: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ss
case 66: _digitOut[i+2] = ((h0/3)&1)?1:10; i++; //bbb (bbbb NI)
case 65: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:10; i++; //bb
case 64: _digitOut[i] = (h0>11)?1:10; break; //b
case 71: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //hh
case 75: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //mm
case 81: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ss
case 66: _digitOut[i+2] = ((h0/3)&1)?1:10; i++; //bbb (bbbb NI)
case 65: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:10; i++; //bb
case 64: _digitOut[i] = (h0>11)?1:10; break; //b
case 93: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //d
case 94: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //dd
case 90: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ii
case 87: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //yy
case 89: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //yyyy
}
case 93: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //d
case 94: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //dd
case 90: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ii
case 87: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //yy
case 89: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //yyyy
}
}
}
strip.setCronixieDigits(_digitOut);
//strip.trigger(); //this has a drawback, no effects slower than RefreshMs. advantage: Quick update, not dependant on effect time
#endif
}
strip.setCronixieDigits(_digitOut);
//strip.trigger(); //this has a drawback, no effects slower than RefreshMs. advantage: Quick update, not dependant on effect time
#endif
}

View File

@@ -1,34 +1,13 @@
/*
* Color conversion methods
*/
void colorCTtoRGB(uint16_t mired, byte* rgb) //white spectrum to rgb
void colorFromUint32(uint32_t in)
{
//this is only an approximation using WS2812B with gamma correction enabled
if (mired > 475)
{
rgb[0]=255;rgb[1]=199;rgb[2]=92;//500
} else if (mired > 425)
{
rgb[0]=255;rgb[1]=213;rgb[2]=118;//450
} else if (mired > 375)
{
rgb[0]=255;rgb[1]=216;rgb[2]=118;//400
} else if (mired > 325)
{
rgb[0]=255;rgb[1]=234;rgb[2]=140;//350
} else if (mired > 275)
{
rgb[0]=255;rgb[1]=243;rgb[2]=160;//300
} else if (mired > 225)
{
rgb[0]=250;rgb[1]=255;rgb[2]=188;//250
} else if (mired > 175)
{
rgb[0]=247;rgb[1]=255;rgb[2]=215;//200
} else
{
rgb[0]=237;rgb[1]=255;rgb[2]=239;//150
}
white = in >> 24 & 0xFF;
col[0] = in >> 16 & 0xFF;
col[1] = in >> 8 & 0xFF;
col[2] = in & 0xFF;
}
void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb
@@ -50,6 +29,29 @@ void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb
}
}
#ifndef WLED_DISABLE_HUESYNC
void colorCTtoRGB(uint16_t mired, byte* rgb) //white spectrum to rgb
{
//this is only an approximation using WS2812B with gamma correction enabled
if (mired > 475) {
rgb[0]=255;rgb[1]=199;rgb[2]=92;//500
} else if (mired > 425) {
rgb[0]=255;rgb[1]=213;rgb[2]=118;//450
} else if (mired > 375) {
rgb[0]=255;rgb[1]=216;rgb[2]=118;//400
} else if (mired > 325) {
rgb[0]=255;rgb[1]=234;rgb[2]=140;//350
} else if (mired > 275) {
rgb[0]=255;rgb[1]=243;rgb[2]=160;//300
} else if (mired > 225) {
rgb[0]=250;rgb[1]=255;rgb[2]=188;//250
} else if (mired > 175) {
rgb[0]=247;rgb[1]=255;rgb[2]=215;//200
} else {
rgb[0]=237;rgb[1]=255;rgb[2]=239;//150
}
}
void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
{
float z = 1.0f - x - y;
@@ -59,20 +61,20 @@ void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www
float g = (int)255*(-X * 0.707196f + 1.655397f + Z * 0.036152f);
float b = (int)255*(X * 0.051713f - 0.121364f + Z * 1.011530f);
if (r > b && r > g && r > 1.0f) {
// red is too big
g = g / r;
b = b / r;
r = 1.0f;
// red is too big
g = g / r;
b = b / r;
r = 1.0f;
} else if (g > b && g > r && g > 1.0f) {
// green is too big
r = r / g;
b = b / g;
g = 1.0f;
// green is too big
r = r / g;
b = b / g;
g = 1.0f;
} else if (b > r && b > g && b > 1.0f) {
// blue is too big
r = r / b;
g = g / b;
b = 1.0f;
// blue is too big
r = r / b;
g = g / b;
b = 1.0f;
}
// Apply gamma correction
r = r <= 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * pow(r, (1.0f / 2.4f)) - 0.055f;
@@ -80,32 +82,42 @@ void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www
b = b <= 0.0031308f ? 12.92f * b : (1.0f + 0.055f) * pow(b, (1.0f / 2.4f)) - 0.055f;
if (r > b && r > g) {
// red is biggest
if (r > 1.0f) {
g = g / r;
b = b / r;
r = 1.0f;
}
// red is biggest
if (r > 1.0f) {
g = g / r;
b = b / r;
r = 1.0f;
}
} else if (g > b && g > r) {
// green is biggest
if (g > 1.0f) {
r = r / g;
b = b / g;
g = 1.0f;
}
// green is biggest
if (g > 1.0f) {
r = r / g;
b = b / g;
g = 1.0f;
}
} else if (b > r && b > g) {
// blue is biggest
if (b > 1.0f) {
r = r / b;
g = g / b;
b = 1.0f;
}
// blue is biggest
if (b > 1.0f) {
r = r / b;
g = g / b;
b = 1.0f;
}
}
rgb[0] = 255.0*r;
rgb[1] = 255.0*g;
rgb[2] = 255.0*b;
}
void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
{
float X = rgb[0] * 0.664511f + rgb[1] * 0.154324f + rgb[2] * 0.162028f;
float Y = rgb[0] * 0.283881f + rgb[1] * 0.668433f + rgb[2] * 0.047685f;
float Z = rgb[0] * 0.000088f + rgb[1] * 0.072310f + rgb[2] * 0.986039f;
xy[0] = X / (X + Y + Z);
xy[1] = Y / (X + Y + Z);
}
#endif
void colorFromDecOrHexString(byte* rgb, byte* wht, char* in)
{
if (in[0] == 0) return;
@@ -126,15 +138,6 @@ void colorFromDecOrHexString(byte* rgb, byte* wht, char* in)
rgb[2] = c & 0xFF;
}
void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
{
float X = rgb[0] * 0.664511f + rgb[1] * 0.154324f + rgb[2] * 0.162028f;
float Y = rgb[0] * 0.283881f + rgb[1] * 0.668433f + rgb[2] * 0.047685f;
float Z = rgb[0] * 0.000088f + rgb[1] * 0.072310f + rgb[2] * 0.986039f;
xy[0] = X / (X + Y + Z);
xy[1] = Y / (X + Y + Z);
}
float minf (float v, float w)
{
if (w > v) return v;
@@ -155,4 +158,3 @@ void colorRGBtoRGBW(byte* rgb, byte* wht) //rgb to rgbw (http://codewelt.com/rgb
float sat = 255.0f * ((high - low) / high);
*wht = (byte)((255.0f - sat) / 255.0f * (rgb[0] + rgb[1] + rgb[2]) / 3);
}

View File

@@ -1,7 +1,7 @@
/*
* Sync to Philips hue lights
*/
#ifndef WLED_DISABLE_HUESYNC
void handleHue()
{
if (huePollingEnabled && WiFi.status() == WL_CONNECTED && hueClient != NULL)
@@ -206,4 +206,7 @@ String getJsonValue(String* req, String key)
}
return "";
}
#else
void handleHue(){}
bool setupHue(){return false;}
#endif

View File

@@ -7,19 +7,24 @@ byte blSat = 255;
void initBlynk(const char* auth)
{
#ifndef WLED_DISABLE_BLYNK
if (WiFi.status() != WL_CONNECTED) return;
blynkEnabled = (auth[0] != 0);
if (blynkEnabled) Blynk.config(auth);
#endif
}
void handleBlynk()
{
#ifndef WLED_DISABLE_BLYNK
if (WiFi.status() == WL_CONNECTED && blynkEnabled)
Blynk.run();
#endif
}
void updateBlynk()
{
#ifndef WLED_DISABLE_BLYNK
if (onlyAP) return;
Blynk.virtualWrite(V0, bri);
//we need a RGB -> HSB convert here
@@ -29,26 +34,28 @@ void updateBlynk()
Blynk.virtualWrite(V6, effectIntensity);
Blynk.virtualWrite(V7, nightlightActive);
Blynk.virtualWrite(V8, notifyDirect);
#endif
}
#ifndef WLED_DISABLE_BLYNK
BLYNK_WRITE(V0)
{
bri = param.asInt();//bri
colorUpdated(9);
bri = param.asInt();//bri
colorUpdated(9);
}
BLYNK_WRITE(V1)
{
blHue = param.asInt();//hue
colorHStoRGB(blHue*10,blSat,(false)? colSec:col);
colorUpdated(9);
blHue = param.asInt();//hue
colorHStoRGB(blHue*10,blSat,(false)? colSec:col);
colorUpdated(9);
}
BLYNK_WRITE(V2)
{
blSat = param.asInt();//sat
colorHStoRGB(blHue*10,blSat,(false)? colSec:col);
colorUpdated(9);
blSat = param.asInt();//sat
colorHStoRGB(blHue*10,blSat,(false)? colSec:col);
colorUpdated(9);
}
BLYNK_WRITE(V3)
@@ -58,23 +65,20 @@ BLYNK_WRITE(V3)
BLYNK_WRITE(V4)
{
effectCurrent = param.asInt()-1;//fx
strip.setMode(effectCurrent);
colorUpdated(6);
effectCurrent = param.asInt()-1;//fx
colorUpdated(9);
}
BLYNK_WRITE(V5)
{
effectSpeed = param.asInt();//sx
strip.setSpeed(effectSpeed);
colorUpdated(6);
effectSpeed = param.asInt();//sx
colorUpdated(9);
}
BLYNK_WRITE(V6)
{
effectIntensity = param.asInt();//ix
strip.setIntensity(effectIntensity);
colorUpdated(6);
effectIntensity = param.asInt();//ix
colorUpdated(9);
}
BLYNK_WRITE(V7)
@@ -86,4 +90,4 @@ BLYNK_WRITE(V8)
{
notifyDirect = (param.asInt()>0); //send notifications
}
#endif

View File

@@ -5,7 +5,7 @@
void parseMQTTBriPayload(char* payload)
{
if (strcmp(payload, "ON") == 0) {bri = briLast; colorUpdated(1);}
else if (strcmp(payload, "T" ) == 0) {handleSet("win&T=2");}
else if (strcmp(payload, "T" ) == 0) {toggleOnOff(); colorUpdated(1);}
else {
uint8_t in = strtoul(payload, NULL, 10);
if (in == 0 && bri > 0) briLast = bri;
@@ -14,6 +14,7 @@ void parseMQTTBriPayload(char* payload)
}
}
void callbackMQTT(char* topic, byte* payload, unsigned int length) {
DEBUG_PRINT("MQTT callb rec: ");
@@ -37,6 +38,7 @@ void callbackMQTT(char* topic, byte* payload, unsigned int length) {
}
}
void publishMQTT()
{
if (mqtt == NULL) return;
@@ -58,12 +60,13 @@ void publishMQTT()
//if you want to use this, increase the MQTT buffer in PubSubClient.h to 350+
//it will publish the API response to MQTT
/*XML_response(false);
/*XML_response(false, false);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/v");
mqtt->publish(subuf, obuf);*/
}
bool reconnectMQTT()
{
if (mqtt->connect(escapedMac.c_str()))
@@ -93,10 +96,13 @@ bool reconnectMQTT()
strcat(subuf, "/api");
mqtt->subscribe(subuf);
}
publishMQTT();
}
return mqtt->connected();
}
bool initMQTT()
{
if (WiFi.status() != WL_CONNECTED) return false;
@@ -114,6 +120,7 @@ bool initMQTT()
return true;
}
void handleMQTT()
{
if (WiFi.status() != WL_CONNECTED || !mqttInit) return;

View File

@@ -101,9 +101,16 @@ void initServer()
});
server.on("/power", HTTP_GET, [](){
String val = (String)(int)strip.getPowerEstimate(ledCount,strip.getColor(),strip.getBrightness());
val += "mA currently";
serveMessage(200,val,"This is just an estimate (does not take into account several factors like effects and wire resistance). It is NOT an accurate measurement!",254);
String val = "";
if (strip.currentMilliamps == 0)
{
val = "Power calculation disabled";
} else
{
val += (String)strip.currentMilliamps;
val += "mA currently";
}
serveMessage(200, val, "This is just an estimate (does not account for factors like wire resistance). It is NOT a measurement!", 254);
});
server.on("/u", HTTP_GET, [](){
@@ -113,7 +120,7 @@ void initServer()
});
server.on("/teapot", HTTP_GET, [](){
serveMessage(418, "418. I'm a teapot.","(Tangible Embedded Advanced Project Of Twinkling)",254);
serveMessage(418, "418. I'm a teapot.", "(Tangible Embedded Advanced Project Of Twinkling)", 254);
});
server.on("/build", HTTP_GET, [](){
@@ -132,7 +139,13 @@ void initServer()
server.on("/list", HTTP_GET, handleFileList);
#endif
//init ota page
#ifndef WLED_DISABLE_OTA
httpUpdater.setup(&server);
#else
server.on("/update", HTTP_GET, [](){
serveMessage(500, "Not implemented", "OTA updates are unsupported in this build.", 254);
});
#endif
} else
{
server.on("/edit", HTTP_GET, [](){
@@ -179,43 +192,6 @@ void initServer()
#endif
}
void buildCssColorString()
{
String cs[]={"","","","","",""};
switch (currentTheme)
{
default: cs[0]="D9B310"; cs[1]="0B3C5D"; cs[2]="1D2731"; cs[3]="328CC1"; cs[4]="000"; cs[5]="328CC1"; break; //night
case 1: cs[0]="eee"; cs[1]="ddd"; cs[2]="b9b9b9"; cs[3]="049"; cs[4]="777"; cs[5]="049"; break; //modern
case 2: cs[0]="abc"; cs[1]="fff"; cs[2]="ddd"; cs[3]="000"; cs[4]="0004"; cs[5]="000"; break; //bright
case 3: cs[0]="c09f80"; cs[1]="d7cec7"; cs[2]="76323f"; cs[3]="888"; cs[4]="3334"; cs[5]="888"; break; //wine
case 4: cs[0]="3cc47c"; cs[1]="828081"; cs[2]="d9a803"; cs[3]="1e392a"; cs[4]="000a"; cs[5]="1e392a"; break; //electric
case 5: cs[0]="57bc90"; cs[1]="a5a5af"; cs[2]="015249"; cs[3]="88c9d4"; cs[4]="0004"; cs[5]="88c9d4"; break; //mint
case 6: cs[0]="f7c331"; cs[1]="dcc7aa"; cs[2]="6b7a8f"; cs[3]="f7882f"; cs[4]="0007"; cs[5]="f7882f"; break; //amber
case 7: cs[0]="fc3"; cs[1]="124"; cs[2]="334"; cs[3]="f1d"; cs[4]="f00"; cs[5]="f1d"; break;//club
case 8: cs[0]="0ac"; cs[1]="124"; cs[2]="224"; cs[3]="003eff"; cs[4]="003eff"; cs[5]="003eff"; break;//air
case 9: cs[0]="f70"; cs[1]="421"; cs[2]="221"; cs[3]="a50"; cs[4]="f70"; cs[5]="f70"; break;//nixie
case 10: cs[0]="2d2"; cs[1]="010"; cs[2]="121"; cs[3]="060"; cs[4]="040"; cs[5]="3f3"; break; //terminal
case 11: cs[0]="867ADE"; cs[1]="4033A3"; cs[2]="483AAA"; cs[3]="483AAA"; cs[4]=""; cs[5]="867ADE"; break; //c64
case 12: cs[0]="fbe8a6"; cs[1]="d2fdff"; cs[2]="b4dfe5"; cs[3]="f4976c"; cs[4]=""; cs[5]="303c6c"; break; //c64
case 14: cs[0]="fc7"; cs[1]="49274a"; cs[2]="94618e"; cs[3]="f4decb"; cs[4]="0008"; cs[5]="f4decb"; break; //end
case 15: for (int i=0;i<6;i++)cs[i]=cssCol[i];//custom
}
cssColorString="<style>:root{--aCol:#";
cssColorString+=cs[0];
cssColorString+=";--bCol:#";
cssColorString+=cs[1];
cssColorString+=";--cCol:#";
cssColorString+=cs[2];
cssColorString+=";--dCol:#";
cssColorString+=cs[3];
cssColorString+=";--sCol:#";
cssColorString+=cs[4];
cssColorString+=";--tCol:#";
cssColorString+=cs[5];
cssColorString+=";--cFn:";
cssColorString+=cssFont;
cssColorString+=";}";
}
void serveIndexOrWelcome()
{
@@ -247,36 +223,52 @@ void serveRealtimeError(bool settings)
server.send(200, "text/plain", mesg);
}
void getCSSColors()
{
char cs[6][9];
getThemeColors(cs);
oappend("<style>:root{--aCol:#"); oappend(cs[0]);
oappend(";--bCol:#"); oappend(cs[1]);
oappend(";--cCol:#"); oappend(cs[2]);
oappend(";--dCol:#"); oappend(cs[3]);
oappend(";--sCol:#"); oappend(cs[4]);
oappend(";--tCol:#"); oappend(cs[5]);
oappend(";--cFn:"); oappend(cssFont);
oappend(";}");
}
void serveIndex()
{
bool serveMobile = false;
if (uiConfiguration == 0) serveMobile = checkClientIsMobile(server.header("User-Agent"));
else if (uiConfiguration == 2) serveMobile = true;
if (!realtimeActive || enableRealtimeUI) //do not serve while receiving realtime
if (realtimeActive && !enableRealtimeUI) //do not serve while receiving realtime
{
if (serveMobile)
{
server.setContentLength(strlen_P(PAGE_indexM));
server.send(200, "text/html", "");
server.sendContent_P(PAGE_indexM);
} else
{
server.setContentLength(strlen_P(PAGE_index0) + cssColorString.length() + strlen_P(PAGE_index1) + strlen_P(PAGE_index2) + strlen_P(PAGE_index3));
server.send(200, "text/html", "");
server.sendContent_P(PAGE_index0);
server.sendContent(cssColorString);
server.sendContent_P(PAGE_index1);
server.sendContent_P(PAGE_index2);
server.sendContent_P(PAGE_index3);
}
} else {
serveRealtimeError(false);
return;
}
//error message is not gzipped
#ifdef WLED_DISABLE_MOBILE_UI
if (!serveMobile) server.sendHeader("Content-Encoding","gzip");
#else
server.sendHeader("Content-Encoding","gzip");
#endif
server.send_P(200, "text/html",
(serveMobile) ? PAGE_indexM : PAGE_index0,
(serveMobile) ? PAGE_indexM_L : PAGE_index0_L);
}
void serveMessage(int code, String headl, String subl="", int optionType)
{
olen = 0;
getCSSColors();
String messageBody = "<h2>";
messageBody += headl;
messageBody += "</h2>";
@@ -298,69 +290,72 @@ void serveMessage(int code, String headl, String subl="", int optionType)
messageBody += "<script>setTimeout(RP," + String((optionType-120)*1000) + ")</script>";
}
messageBody += "</body></html>";
server.setContentLength(strlen_P(PAGE_msg0) + cssColorString.length() + strlen_P(PAGE_msg1) + messageBody.length());
server.setContentLength(strlen_P(PAGE_msg0) + olen + strlen_P(PAGE_msg1) + messageBody.length());
server.send(code, "text/html", "");
server.sendContent_P(PAGE_msg0);
server.sendContent(cssColorString);
server.sendContent(obuf);
server.sendContent_P(PAGE_msg1);
server.sendContent(messageBody);
}
void serveSettings(byte subPage)
{
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 255: welcomepage
if (!realtimeActive || enableRealtimeUI) //do not serve while receiving realtime
{
#ifdef WLED_FLASH_512K_MODE //disable welcome page if not enough storage
if (subPage == 255) {serveIndex(); return;}
#endif
int pl0, pl1;
switch (subPage)
{
case 1: pl0 = strlen_P(PAGE_settings_wifi0); pl1 = strlen_P(PAGE_settings_wifi1); break;
case 2: pl0 = strlen_P(PAGE_settings_leds0); pl1 = strlen_P(PAGE_settings_leds1); break;
case 3: pl0 = strlen_P(PAGE_settings_ui0); pl1 = strlen_P(PAGE_settings_ui1); break;
case 4: pl0 = strlen_P(PAGE_settings_sync0); pl1 = strlen_P(PAGE_settings_sync1); break;
case 5: pl0 = strlen_P(PAGE_settings_time0); pl1 = strlen_P(PAGE_settings_time1); break;
case 6: pl0 = strlen_P(PAGE_settings_sec0); pl1 = strlen_P(PAGE_settings_sec1); break;
case 255: pl0 = strlen_P(PAGE_welcome0); pl1 = strlen_P(PAGE_welcome1); break;
default: pl0 = strlen_P(PAGE_settings0); pl1 = strlen_P(PAGE_settings1);
}
getSettingsJS(subPage);
int sCssLength = (subPage >0 && subPage <7)?strlen_P(PAGE_settingsCss):0;
server.setContentLength(pl0 + cssColorString.length() + olen + sCssLength + pl1);
server.send(200, "text/html", "");
switch (subPage)
{
case 1: server.sendContent_P(PAGE_settings_wifi0); break;
case 2: server.sendContent_P(PAGE_settings_leds0); break;
case 3: server.sendContent_P(PAGE_settings_ui0); break;
case 4: server.sendContent_P(PAGE_settings_sync0); break;
case 5: server.sendContent_P(PAGE_settings_time0); break;
case 6: server.sendContent_P(PAGE_settings_sec0); break;
case 255: server.sendContent_P(PAGE_welcome0); break;
default: server.sendContent_P(PAGE_settings0);
}
server.sendContent(obuf);
server.sendContent(cssColorString);
if (subPage >0 && subPage <7) server.sendContent_P(PAGE_settingsCss);
switch (subPage)
{
case 1: server.sendContent_P(PAGE_settings_wifi1); break;
case 2: server.sendContent_P(PAGE_settings_leds1); break;
case 3: server.sendContent_P(PAGE_settings_ui1); break;
case 4: server.sendContent_P(PAGE_settings_sync1); break;
case 5: server.sendContent_P(PAGE_settings_time1); break;
case 6: server.sendContent_P(PAGE_settings_sec1); break;
case 255: server.sendContent_P(PAGE_welcome1); break;
default: server.sendContent_P(PAGE_settings1);
}
} else {
serveRealtimeError(true);
}
}
if (realtimeActive && !enableRealtimeUI) //do not serve while receiving realtime
{
serveRealtimeError(true);
return;
}
#ifdef WLED_DISABLE_MOBILE_UI //disable welcome page if not enough storage
if (subPage == 255) {serveIndex(); return;}
#endif
int pl0, pl1;
switch (subPage) //0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 255: welcomepage
{
case 1: pl0 = strlen_P(PAGE_settings_wifi0); pl1 = strlen_P(PAGE_settings_wifi1); break;
case 2: pl0 = strlen_P(PAGE_settings_leds0); pl1 = strlen_P(PAGE_settings_leds1); break;
case 3: pl0 = strlen_P(PAGE_settings_ui0); pl1 = strlen_P(PAGE_settings_ui1); break;
case 4: pl0 = strlen_P(PAGE_settings_sync0); pl1 = strlen_P(PAGE_settings_sync1); break;
case 5: pl0 = strlen_P(PAGE_settings_time0); pl1 = strlen_P(PAGE_settings_time1); break;
case 6: pl0 = strlen_P(PAGE_settings_sec0); pl1 = strlen_P(PAGE_settings_sec1); break;
case 255: pl0 = strlen_P(PAGE_welcome0); pl1 = strlen_P(PAGE_welcome1); break;
default: pl0 = strlen_P(PAGE_settings0); pl1 = strlen_P(PAGE_settings1);
}
uint16_t sCssLength = (subPage >0 && subPage <7)?strlen_P(PAGE_settingsCss):0;
getSettingsJS(subPage);
getCSSColors();
server.setContentLength(pl0 + olen + sCssLength + pl1);
server.send(200, "text/html", "");
switch (subPage)
{
case 1: server.sendContent_P(PAGE_settings_wifi0); break;
case 2: server.sendContent_P(PAGE_settings_leds0); break;
case 3: server.sendContent_P(PAGE_settings_ui0 ); break;
case 4: server.sendContent_P(PAGE_settings_sync0); break;
case 5: server.sendContent_P(PAGE_settings_time0); break;
case 6: server.sendContent_P(PAGE_settings_sec0 ); break;
case 255: server.sendContent_P(PAGE_welcome0 ); break;
default: server.sendContent_P(PAGE_settings0 );
}
server.sendContent(obuf);
if (subPage >0 && subPage <7) server.sendContent_P(PAGE_settingsCss);
switch (subPage)
{
case 1: server.sendContent_P(PAGE_settings_wifi1); break;
case 2: server.sendContent_P(PAGE_settings_leds1); break;
case 3: server.sendContent_P(PAGE_settings_ui1 ); break;
case 4: server.sendContent_P(PAGE_settings_sync1); break;
case 5: server.sendContent_P(PAGE_settings_time1); break;
case 6: server.sendContent_P(PAGE_settings_sec1 ); break;
case 255: server.sendContent_P(PAGE_welcome1 ); break;
default: server.sendContent_P(PAGE_settings1 );
}
}

155
wled00/wled19_ir.ino Normal file
View File

@@ -0,0 +1,155 @@
/*
* Infrared sensor support for generic 24 key RGB remote
*/
#if defined(WLED_DISABLE_INFRARED) || defined(ARDUINO_ARCH_ESP32)
void handleIR(){}
#else
IRrecv* irrecv;
//change pin in NpbWrapper.h
decode_results results;
unsigned long irCheckedTime = 0;
uint32_t lastValidCode = 0;
uint16_t irTimesRepeated = 0;
//Add what your custom IR codes should trigger here. Guide: https://github.com/Aircoookie/WLED/wiki/Infrared-Control
//IR codes themselves can be defined directly after "case" or in "ir_codes.h"
bool decodeIRCustom(uint32_t code)
{
switch (code)
{
//just examples, feel free to modify or remove
case IRCUSTOM_ONOFF : toggleOnOff(); break;
case IRCUSTOM_MACRO1 : applyMacro(1); break;
default: return false;
}
if (code != IRCUSTOM_MACRO1) colorUpdated(2); //don't update color again if we apply macro, it already does it
return true;
}
//relatively change brightness, minumum A=5
void relativeChange(byte* property, int8_t amount, byte lowerBoundary =0)
{
int16_t new_val = (int16_t) *property + amount;
if (new_val > 0xFF) new_val = 0xFF;
else if (new_val < lowerBoundary) new_val = lowerBoundary;
*property = new_val;
}
void decodeIR(uint32_t code)
{
if (code == 0xFFFFFFFF) //repeated code, continue brightness up/down
{
irTimesRepeated++;
if (lastValidCode == IR24_BRIGHTER)
{
relativeChange(&bri, 10); colorUpdated(2);
}
else if (lastValidCode == IR24_DARKER)
{
relativeChange(&bri, -10, 5); colorUpdated(2);
}
else if (lastValidCode == IR24_ON && irTimesRepeated > 7)
{
nightlightActive = true;
nightlightStartTime = millis();
colorUpdated(2);
}
return;
}
lastValidCode = 0; irTimesRepeated = 0;
if (decodeIRCustom(code)) return;
if (code > 0xFFFFFF) return; //invalid code
else if (code > 0xFF0000) decodeIR44(code); //is in 44-key remote range
else if (code > 0xF70000 && code < 0xF80000) decodeIR24(code); //is in 24-key remote range
//code <= 0xF70000 also invalid
}
void decodeIR24(uint32_t code)
{
switch (code) {
case IR24_BRIGHTER : relativeChange(&bri, 10); break;
case IR24_DARKER : relativeChange(&bri, -10, 5); break;
case IR24_OFF : briLast = bri; bri = 0; break;
case IR24_ON : bri = briLast; break;
case IR24_RED : colorFromUint32(COLOR_RED); break;
case IR24_REDDISH : colorFromUint32(COLOR_REDDISH); break;
case IR24_ORANGE : colorFromUint32(COLOR_ORANGE); break;
case IR24_YELLOWISH : colorFromUint32(COLOR_YELLOWISH); break;
case IR24_YELLOW : colorFromUint32(COLOR_YELLOW); break;
case IR24_GREEN : colorFromUint32(COLOR_GREEN); break;
case IR24_GREENISH : colorFromUint32(COLOR_GREENISH); break;
case IR24_TURQUOISE : colorFromUint32(COLOR_TURQUOISE); break;
case IR24_CYAN : colorFromUint32(COLOR_CYAN); break;
case IR24_AQUA : colorFromUint32(COLOR_AQUA); break;
case IR24_BLUE : colorFromUint32(COLOR_BLUE); break;
case IR24_DEEPBLUE : colorFromUint32(COLOR_DEEPBLUE); break;
case IR24_PURPLE : colorFromUint32(COLOR_PURPLE); break;
case IR24_MAGENTA : colorFromUint32(COLOR_MAGENTA); break;
case IR24_PINK : colorFromUint32(COLOR_PINK); break;
case IR24_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break;
case IR24_FLASH : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break;
case IR24_STROBE : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break;
case IR24_FADE : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break;
case IR24_SMOOTH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break;
default: return;
}
lastValidCode = code;
colorUpdated(2); //for notifier, IR is considered a button input
}
void decodeIR44(uint32_t code)
{
//not implemented for now
}
void initIR()
{
if (irEnabled)
{
irrecv = new IRrecv(IR_PIN);
irrecv->enableIRIn();
}
}
void handleIR()
{
if (irEnabled && millis() - irCheckedTime > 120)
{
irCheckedTime = millis();
if (irEnabled)
{
if (irrecv == NULL)
{
initIR(); return;
}
if (irrecv->decode(&results))
{
Serial.print("IR recv\r\n0x");
Serial.println((uint32_t)results.value, HEX);
Serial.println();
decodeIR(results.value);
irrecv->resume();
}
} else if (irrecv != NULL)
{
irrecv->disableIRIn();
delete irrecv; irrecv = NULL;
}
}
}
#endif