* Add smooth arc drawing function

Update ESP8266 architecture reference
Add pushMaskedImage() to render 16bpp images with a 1bpp mask (used for transparent PNG images plus with sprites)

New functions added using drawArc:
drawSmoothArc
drawSmoothCircle
drawSmoothRoundRect
New sqrt_fraction() added to improve smooth graphics performance on processors without a FPU (e.g. RP2040)

Faster alphaBlend() function added which retains 6bpp for green

Rename swap_coord() to transpose()

* Update TFT_eSPI.cpp

* Add arc examples
This commit is contained in:
Bodmer 2023-01-13 01:31:57 +00:00 committed by GitHub
parent ea82a7c15a
commit d37f202b94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 140152 additions and 125 deletions

View File

@ -1257,8 +1257,8 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const u
// Intentionally not constrained to viewport area, does not manage 1bpp rotations // Intentionally not constrained to viewport area, does not manage 1bpp rotations
void TFT_eSprite::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1) void TFT_eSprite::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
{ {
if (x0 > x1) swap_coord(x0, x1); if (x0 > x1) transpose(x0, x1);
if (y0 > y1) swap_coord(y0, y1); if (y0 > y1) transpose(y0, y1);
int32_t w = width(); int32_t w = width();
int32_t h = height(); int32_t h = height();
@ -1700,13 +1700,13 @@ void TFT_eSprite::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint3
bool steep = abs(y1 - y0) > abs(x1 - x0); bool steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) { if (steep) {
swap_coord(x0, y0); transpose(x0, y0);
swap_coord(x1, y1); transpose(x1, y1);
} }
if (x0 > x1) { if (x0 > x1) {
swap_coord(x0, x1); transpose(x0, x1);
swap_coord(y0, y1); transpose(y0, y1);
} }
int32_t dx = x1 - x0, dy = abs(y1 - y0);; int32_t dx = x1 - x0, dy = abs(y1 - y0);;

View File

@ -19,7 +19,7 @@
#define DMA_BUSY_CHECK // DMA not available, leave blank #define DMA_BUSY_CHECK // DMA not available, leave blank
// Initialise processor specific SPI functions, used by init() // Initialise processor specific SPI functions, used by init()
#if (!defined (SUPPORT_TRANSACTIONS) && defined (ESP8266)) #if (!defined (SUPPORT_TRANSACTIONS) && defined (ARDUINO_ARCH_ESP8266))
#define INIT_TFT_DATA_BUS \ #define INIT_TFT_DATA_BUS \
spi.setBitOrder(MSBFIRST); \ spi.setBitOrder(MSBFIRST); \
spi.setDataMode(TFT_SPI_MODE); \ spi.setDataMode(TFT_SPI_MODE); \

View File

@ -577,7 +577,7 @@ void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
#ifdef RP2040_DMA // DMA functions for 16 bit SPI and 8 bit parallel displays #ifdef RP2040_DMA // DMA functions for 16 bit SPI and 8/16 bit parallel displays
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
/* /*
These are created in header file: These are created in header file:

View File

@ -65,9 +65,20 @@
#define DMA_BUSY_CHECK #define DMA_BUSY_CHECK
#endif #endif
// Handle high performance MHS RPi display type
#if defined (MHS_DISPLAY_TYPE) && !defined (RPI_DISPLAY_TYPE)
#define RPI_DISPLAY_TYPE
#endif
#if !defined (RP2040_PIO_INTERFACE) // SPI #if !defined (RP2040_PIO_INTERFACE) // SPI
// Initialise processor specific SPI functions, used by init()
#define INIT_TFT_DATA_BUS // Not used #if defined (MHS_DISPLAY_TYPE) // High speed RPi TFT type always needs 16 bit transfers
// This swaps to 16 bit mode, used for commands so wait avoids clash with DC timing
#define INIT_TFT_DATA_BUS hw_write_masked(&spi_get_hw(SPI_X)->cr0, (16 - 1) << SPI_SSPCR0_DSS_LSB, SPI_SSPCR0_DSS_BITS)
#else
// Initialise processor specific SPI functions, used by init()
#define INIT_TFT_DATA_BUS // Not used
#endif
// Wait for tx to end, flush rx FIFO, clear rx overrun // Wait for tx to end, flush rx FIFO, clear rx overrun
#define SPI_BUSY_CHECK while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \ #define SPI_BUSY_CHECK while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
@ -141,7 +152,7 @@
#if !defined (RP2040_PIO_INTERFACE)// SPI #if !defined (RP2040_PIO_INTERFACE)// SPI
//#define DC_C sio_hw->gpio_clr = (1ul << TFT_DC) //#define DC_C sio_hw->gpio_clr = (1ul << TFT_DC)
//#define DC_D sio_hw->gpio_set = (1ul << TFT_DC) //#define DC_D sio_hw->gpio_set = (1ul << TFT_DC)
#if defined (RPI_DISPLAY_TYPE) #if defined (RPI_DISPLAY_TYPE) && !defined (MHS_DISPLAY_TYPE)
#define DC_C digitalWrite(TFT_DC, LOW); #define DC_C digitalWrite(TFT_DC, LOW);
#define DC_D digitalWrite(TFT_DC, HIGH); #define DC_D digitalWrite(TFT_DC, HIGH);
#else #else
@ -167,7 +178,7 @@
#define CS_H // No macro allocated so it generates no code #define CS_H // No macro allocated so it generates no code
#else #else
#if !defined (RP2040_PIO_INTERFACE) // SPI #if !defined (RP2040_PIO_INTERFACE) // SPI
#if defined (RPI_DISPLAY_TYPE) #if defined (RPI_DISPLAY_TYPE) && !defined (MHS_DISPLAY_TYPE)
#define CS_L digitalWrite(TFT_CS, LOW); #define CS_L digitalWrite(TFT_CS, LOW);
#define CS_H digitalWrite(TFT_CS, HIGH); #define CS_H digitalWrite(TFT_CS, HIGH);
#else #else
@ -287,7 +298,28 @@
// Macros to write commands/pixel colour data to other displays // Macros to write commands/pixel colour data to other displays
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
#else #else
#if defined (RPI_DISPLAY_TYPE) // RPi TFT type always needs 16 bit transfers #if defined (MHS_DISPLAY_TYPE) // High speed RPi TFT type always needs 16 bit transfers
// This swaps to 16 bit mode, used for commands so wait avoids clash with DC timing
#define tft_Write_8(C) while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
hw_write_masked(&spi_get_hw(SPI_X)->cr0, (16 - 1) << SPI_SSPCR0_DSS_LSB, SPI_SSPCR0_DSS_BITS); \
spi_get_hw(SPI_X)->dr = (uint32_t)((C) | ((C)<<8)); \
while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
// Note: the following macros do not wait for the end of transmission
#define tft_Write_16(C) while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)
#define tft_Write_16N(C) while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)
#define tft_Write_16S(C) while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)<<8 | (C)>>8
#define tft_Write_32(C) spi_get_hw(SPI_X)->dr = (uint32_t)((C)>>16); spi_get_hw(SPI_X)->dr = (uint32_t)(C)
#define tft_Write_32C(C,D) spi_get_hw(SPI_X)->dr = (uint32_t)(C); spi_get_hw(SPI_X)->dr = (uint32_t)(D)
#define tft_Write_32D(C) spi_get_hw(SPI_X)->dr = (uint32_t)(C); spi_get_hw(SPI_X)->dr = (uint32_t)(C)
#elif defined (RPI_DISPLAY_TYPE) // RPi TFT type always needs 16 bit transfers
#define tft_Write_8(C) spi.transfer(C); spi.transfer(C) #define tft_Write_8(C) spi.transfer(C); spi.transfer(C)
#define tft_Write_16(C) spi.transfer((uint8_t)((C)>>8));spi.transfer((uint8_t)((C)>>0)) #define tft_Write_16(C) spi.transfer((uint8_t)((C)>>8));spi.transfer((uint8_t)((C)>>0))
#define tft_Write_16N(C) spi.transfer((uint8_t)((C)>>8));spi.transfer((uint8_t)((C)>>0)) #define tft_Write_16N(C) spi.transfer((uint8_t)((C)>>8));spi.transfer((uint8_t)((C)>>0))

View File

@ -149,7 +149,6 @@ inline void TFT_eSPI::begin_tft_read(void){
SET_BUS_READ_MODE; SET_BUS_READ_MODE;
} }
/*************************************************************************************** /***************************************************************************************
** Function name: end_tft_read (was called spi_end_read) ** Function name: end_tft_read (was called spi_end_read)
** Description: End transaction for reads and deselect TFT ** Description: End transaction for reads and deselect TFT
@ -233,7 +232,6 @@ void TFT_eSPI::setViewport(int32_t x, int32_t y, int32_t w, int32_t h, bool vpDa
//Serial.print(" _vpX=");Serial.print( _vpX);Serial.print(", _vpY=");Serial.print( _vpY); //Serial.print(" _vpX=");Serial.print( _vpX);Serial.print(", _vpY=");Serial.print( _vpY);
//Serial.print(", _vpW=");Serial.print(_vpW);Serial.print(", _vpH=");Serial.println(_vpH); //Serial.print(", _vpW=");Serial.print(_vpW);Serial.print(", _vpH=");Serial.println(_vpH);
} }
/*************************************************************************************** /***************************************************************************************
@ -866,6 +864,48 @@ void TFT_eSPI::setRotation(uint8_t m)
} }
/***************************************************************************************
** Function name: getRotation
** Description: Return the rotation value (as used by setRotation())
***************************************************************************************/
uint8_t TFT_eSPI::getRotation(void)
{
return rotation;
}
/***************************************************************************************
** Function name: setOrigin
** Description: Set graphics origin to position x,y wrt to top left corner
***************************************************************************************/
//Note: setRotation, setViewport and resetViewport will revert origin to top left
void TFT_eSPI::setOrigin(int32_t x, int32_t y)
{
_xDatum = x;
_yDatum = y;
}
/***************************************************************************************
** Function name: getOriginX
** Description: Set graphics origin to position x
***************************************************************************************/
int32_t TFT_eSPI::getOriginX(void)
{
return _xDatum;
}
/***************************************************************************************
** Function name: getOriginY
** Description: Set graphics origin to position y
***************************************************************************************/
int32_t TFT_eSPI::getOriginY(void)
{
return _yDatum;
}
/*************************************************************************************** /***************************************************************************************
** Function name: commandList, used for FLASH based lists only (e.g. ST7735) ** Function name: commandList, used for FLASH based lists only (e.g. ST7735)
** Description: Get initialisation commands from FLASH and send to TFT ** Description: Get initialisation commands from FLASH and send to TFT
@ -1998,6 +2038,91 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
end_tft_write(); end_tft_write();
} }
/***************************************************************************************
** Function name: pushMaskedImage
** Description: Render a 16 bit colour image with a 1bpp mask
***************************************************************************************/
// Can be used with a 16bpp sprite and a 1bpp sprite for the mask
void TFT_eSPI::pushMaskedImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *img, uint8_t *mask)
{
if (_vpOoB || w < 1 || h < 1) return;
// To simplify mask handling the window clipping is done by the pushImage function
// Each mask image line assumed to be padded to and integer number of bytes & padding bits are 0
begin_tft_write();
inTransaction = true;
uint8_t *mptr = mask;
uint8_t *eptr = mask + ((w + 7) >> 3);
uint16_t *iptr = img;
uint32_t setCount = 0;
// For each line in the image
while (h--) {
uint32_t xp = 0;
uint32_t clearCount = 0;
uint8_t mbyte= *mptr++;
uint32_t bits = 8;
// Scan through each byte of the bitmap and determine run lengths
do {
setCount = 0;
//Get run length for clear bits to determine x offset
while ((mbyte & 0x80) == 0x00) {
// Check if remaining bits in byte are clear (reduce shifts)
if (mbyte == 0) {
clearCount += bits; // bits not always 8 here
if (mptr >= eptr) break; // end of line
mbyte = *mptr++;
bits = 8;
continue;
}
mbyte = mbyte << 1; // 0's shifted in
clearCount ++;
if (--bits) continue;;
if (mptr >= eptr) break;
mbyte = *mptr++;
bits = 8;
}
//Get run length for set bits to determine render width
while ((mbyte & 0x80) == 0x80) {
// Check if all bits are set (reduces shifts)
if (mbyte == 0xFF) {
setCount += bits;
if (mptr >= eptr) break;
mbyte = *mptr++;
//bits = 8; // NR, bits always 8 here unless 1's shifted in
continue;
}
mbyte = mbyte << 1; //or mbyte += mbyte + 1 to shift in 1's
setCount ++;
if (--bits) continue;
if (mptr >= eptr) break;
mbyte = *mptr++;
bits = 8;
}
// A mask boundary or mask end has been found, so render the pixel line
if (setCount) {
xp += clearCount;
clearCount = 0;
pushImage(x + xp, y, setCount, 1, iptr + xp); // pushImage handles clipping
//pushImageDMA(x + xp, y, setCount, 1, iptr + xp);
xp += setCount;
}
} while (setCount || mptr < eptr);
y++;
iptr += w;
eptr += ((w + 7) >> 3);
}
inTransaction = lockTransaction;
end_tft_write();
}
/*************************************************************************************** /***************************************************************************************
** Function name: setSwapBytes ** Function name: setSwapBytes
@ -2510,13 +2635,13 @@ void TFT_eSPI::fillTriangle ( int32_t x0, int32_t y0, int32_t x1, int32_t y1, in
// Sort coordinates by Y order (y2 >= y1 >= y0) // Sort coordinates by Y order (y2 >= y1 >= y0)
if (y0 > y1) { if (y0 > y1) {
swap_coord(y0, y1); swap_coord(x0, x1); transpose(y0, y1); transpose(x0, x1);
} }
if (y1 > y2) { if (y1 > y2) {
swap_coord(y2, y1); swap_coord(x2, x1); transpose(y2, y1); transpose(x2, x1);
} }
if (y0 > y1) { if (y0 > y1) {
swap_coord(y0, y1); swap_coord(x0, x1); transpose(y0, y1); transpose(x0, x1);
} }
if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing
@ -2557,7 +2682,7 @@ void TFT_eSPI::fillTriangle ( int32_t x0, int32_t y0, int32_t x1, int32_t y1, in
sa += dx01; sa += dx01;
sb += dx02; sb += dx02;
if (a > b) swap_coord(a, b); if (a > b) transpose(a, b);
drawFastHLine(a, y, b - a + 1, color); drawFastHLine(a, y, b - a + 1, color);
} }
@ -2571,7 +2696,7 @@ void TFT_eSPI::fillTriangle ( int32_t x0, int32_t y0, int32_t x1, int32_t y1, in
sa += dx12; sa += dx12;
sb += dx02; sb += dx02;
if (a > b) swap_coord(a, b); if (a > b) transpose(a, b);
drawFastHLine(a, y, b - a + 1, color); drawFastHLine(a, y, b - a + 1, color);
} }
@ -2837,15 +2962,6 @@ uint16_t TFT_eSPI::getTextPadding(void)
return padX; return padX;
} }
/***************************************************************************************
** Function name: getRotation
** Description: Return the rotation value (as used by setRotation())
***************************************************************************************/
uint8_t TFT_eSPI::getRotation(void)
{
return rotation;
}
/*************************************************************************************** /***************************************************************************************
** Function name: getTextDatum ** Function name: getTextDatum
** Description: Return the text datum value (as used by setTextDatum()) ** Description: Return the text datum value (as used by setTextDatum())
@ -3194,7 +3310,7 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
addr_col = 0xFFFF; addr_col = 0xFFFF;
#if defined (ILI9225_DRIVER) #if defined (ILI9225_DRIVER)
if (rotation & 0x01) { swap_coord(x0, y0); swap_coord(x1, y1); } if (rotation & 0x01) { transpose(x0, y0); transpose(x1, y1); }
SPI_BUSY_CHECK; SPI_BUSY_CHECK;
DC_C; tft_Write_8(TFT_CASET1); DC_C; tft_Write_8(TFT_CASET1);
DC_D; tft_Write_16(x0); DC_D; tft_Write_16(x0);
@ -3222,8 +3338,8 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
#endif #endif
#elif defined (SSD1351_DRIVER) #elif defined (SSD1351_DRIVER)
if (rotation & 1) { if (rotation & 1) {
swap_coord(x0, y0); transpose(x0, y0);
swap_coord(x1, y1); transpose(x1, y1);
} }
SPI_BUSY_CHECK; SPI_BUSY_CHECK;
DC_C; tft_Write_8(TFT_CASET); DC_C; tft_Write_8(TFT_CASET);
@ -3234,7 +3350,7 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
DC_D; DC_D;
#else #else
#if defined (SSD1963_DRIVER) #if defined (SSD1963_DRIVER)
if ((rotation & 0x1) == 0) { swap_coord(x0, y0); swap_coord(x1, y1); } if ((rotation & 0x1) == 0) { transpose(x0, y0); transpose(x1, y1); }
#endif #endif
#ifdef CGRAM_OFFSET #ifdef CGRAM_OFFSET
@ -3326,7 +3442,7 @@ void TFT_eSPI::readAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h)
addr_row = 0xFFFF; addr_row = 0xFFFF;
#if defined (SSD1963_DRIVER) #if defined (SSD1963_DRIVER)
if ((rotation & 0x1) == 0) { swap_coord(xs, ys); swap_coord(xe, ye); } if ((rotation & 0x1) == 0) { transpose(xs, ys); transpose(xe, ye); }
#endif #endif
#ifdef CGRAM_OFFSET #ifdef CGRAM_OFFSET
@ -3420,7 +3536,7 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
begin_tft_write(); begin_tft_write();
#if defined (ILI9225_DRIVER) #if defined (ILI9225_DRIVER)
if (rotation & 0x01) { swap_coord(x, y); } if (rotation & 0x01) { transpose(x, y); }
SPI_BUSY_CHECK; SPI_BUSY_CHECK;
// Set window to full screen to optimise sequential pixel rendering // Set window to full screen to optimise sequential pixel rendering
@ -3455,7 +3571,7 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
#elif (defined (ARDUINO_ARCH_RP2040) || defined (ARDUINO_ARCH_MBED)) && !defined (SSD1351_DRIVER) #elif (defined (ARDUINO_ARCH_RP2040) || defined (ARDUINO_ARCH_MBED)) && !defined (SSD1351_DRIVER)
#if defined (SSD1963_DRIVER) #if defined (SSD1963_DRIVER)
if ((rotation & 0x1) == 0) { swap_coord(x, y); } if ((rotation & 0x1) == 0) { transpose(x, y); }
#endif #endif
#if !defined(RP2040_PIO_INTERFACE) #if !defined(RP2040_PIO_INTERFACE)
@ -3535,13 +3651,13 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
#else #else
#if defined (SSD1963_DRIVER) #if defined (SSD1963_DRIVER)
if ((rotation & 0x1) == 0) { swap_coord(x, y); } if ((rotation & 0x1) == 0) { transpose(x, y); }
#endif #endif
SPI_BUSY_CHECK; SPI_BUSY_CHECK;
#if defined (SSD1351_DRIVER) #if defined (SSD1351_DRIVER)
if (rotation & 0x1) { swap_coord(x, y); } if (rotation & 0x1) { transpose(x, y); }
// No need to send x if it has not changed (speeds things up) // No need to send x if it has not changed (speeds things up)
if (addr_col != x) { if (addr_col != x) {
DC_C; tft_Write_8(TFT_CASET); DC_C; tft_Write_8(TFT_CASET);
@ -3693,13 +3809,13 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t
bool steep = abs(y1 - y0) > abs(x1 - x0); bool steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) { if (steep) {
swap_coord(x0, y0); transpose(x0, y0);
swap_coord(x1, y1); transpose(x1, y1);
} }
if (x0 > x1) { if (x0 > x1) {
swap_coord(x0, x1); transpose(x0, x1);
swap_coord(y0, y1); transpose(y0, y1);
} }
int32_t dx = x1 - x0, dy = abs(y1 - y0);; int32_t dx = x1 - x0, dy = abs(y1 - y0);;
@ -3750,6 +3866,7 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t
constexpr float PixelAlphaGain = 255.0; constexpr float PixelAlphaGain = 255.0;
constexpr float LoAlphaTheshold = 1.0/32.0; constexpr float LoAlphaTheshold = 1.0/32.0;
constexpr float HiAlphaTheshold = 1.0 - LoAlphaTheshold; constexpr float HiAlphaTheshold = 1.0 - LoAlphaTheshold;
constexpr float deg2rad = 3.14159265359/180.0;
/*************************************************************************************** /***************************************************************************************
** Function name: drawPixel (alpha blended) ** Function name: drawPixel (alpha blended)
@ -3763,6 +3880,290 @@ uint16_t TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha
return color; return color;
} }
/***************************************************************************************
** Function name: drawSmoothArc
** Description: Draw a smooth arc clockwise from 6 o'clock
***************************************************************************************/
void TFT_eSPI::drawSmoothArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool roundEnds)
// Centre at x,y
// r = arc outer radius, ir = arc inner radius. Inclusive so arc thickness = r - ir + 1
// Angles in range 0-360
// Arc foreground colour anti-aliased with background colour at edges
// anti-aliased roundEnd is optional, default is anti-aliased straight end
// Note: rounded ends extend the arc angle so can overlap, user sketch to manage this.
{
inTransaction = true;
if (endAngle != startAngle)
{
float sx = -sinf(startAngle * deg2rad);
float sy = +cosf(startAngle * deg2rad);
float ex = -sinf( endAngle * deg2rad);
float ey = +cosf( endAngle * deg2rad);
if (roundEnds)
{ // Round ends
sx = sx * (r + ir)/2.0 + x;
sy = sy * (r + ir)/2.0 + y;
drawSpot(sx, sy, (r - ir)/2.0, fg_color, bg_color);
ex = ex * (r + ir)/2.0 + x;
ey = ey * (r + ir)/2.0 + y;
drawSpot(ex, ey, (r - ir)/2.0, fg_color, bg_color);
}
else
{ // Square ends
float asx = sx * ir + x;
float asy = sy * ir + y;
float aex = sx * r + x;
float aey = sy * r + y;
drawWedgeLine(asx, asy, aex, aey, 0.3, 0.3, fg_color, bg_color);
asx = ex * ir + x;
asy = ey * ir + y;
aex = ex * r + x;
aey = ey * r + y;
drawWedgeLine(asx, asy, aex, aey, 0.3, 0.3, fg_color, bg_color);
}
if (endAngle > startAngle)
{
// Draw arc in single sweep
drawArc(x, y, r, ir, startAngle, endAngle, fg_color, bg_color);
}
else
{
// Arc sweeps through 6 o'clock so draw in two parts
drawArc(x, y, r, ir, startAngle, 360, fg_color, bg_color);
drawArc(x, y, r, ir, 0, endAngle, fg_color, bg_color);
}
}
else // Draw full 360
{
drawArc(x, y, r, ir, 0, 360, fg_color, bg_color);
}
inTransaction = lockTransaction;
end_tft_write();
}
/***************************************************************************************
** Function name: sqrt_fraction
** Description: Smooth graphics support function for alpha derivation
***************************************************************************************/
// Compute the fixed point square root of an integer and
// return the 8 MS bits of fractional part.
// Quicker than sqrt() for processors that do not have and FPU (e.g. RP2040)
inline uint8_t TFT_eSPI::sqrt_fraction(uint32_t num) {
if (num > (0x40000000)) return 0;
uint32_t bsh = 0x00004000;
uint32_t fpr = 0;
uint32_t osh = 0;
// Auto adjust from U8:8 up to U15:16
while (num>bsh) {bsh <<= 2; osh++;}
do {
uint32_t bod = bsh + fpr;
if(num >= bod)
{
num -= bod;
fpr = bsh + bod;
}
num <<= 1;
} while(bsh >>= 1);
return fpr>>osh;
}
/***************************************************************************************
** Function name: drawArc
** Description: Draw an arc clockwise from 6 o'clock position
***************************************************************************************/
// Centre at x,y
// r = arc outer radius, ir = arc inner radius. Inclusive, so arc thickness = r-ir+1
// Angles MUST be in range 0-360, end angle MUST be greater than start angle
// Arc foreground fg_color anti-aliased with background colour along sides
// smooth is optional, default is true, smooth=false means no antialiasing
// Note: Arc ends are not anti-aliased (use drawSmoothArc instead for that)
void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
int32_t startAngle, int32_t endAngle,
uint32_t fg_color, uint32_t bg_color,
bool smooth)
{
if (_vpOoB) return;
if (r < ir) transpose(r, ir); // Required that r > ir
if (r <= 0 || ir < 0) return; // Invalid r, ir can be zero (circle sector)
if (endAngle < startAngle) transpose(startAngle, endAngle);
if (startAngle < 0) startAngle = 0;
if (endAngle > 360) endAngle = 360;
inTransaction = true;
int32_t xs = 0; // x start position for quadrant scan
uint8_t alpha = 0; // alpha value for blending pixels
int32_t r2 = r * r; // Outer arc radius^2
if (smooth) r++; // Outer AA zone radius
int32_t r1 = r * r; // Outer AA radius^2
int16_t w = r - ir; // Width of arc (r - ir + 1)
int32_t r3 = ir * ir; // Inner arc radius^2
if (smooth) ir--; // Inner AA zone radius
int32_t r4 = ir * ir; // Inner AA radius^2
// Float variants of adjusted inner and outer arc radii
//float irf = ir;
//float rf = r;
// 1 | 2
// ---¦--- Arc quadrant index
// 0 | 3
// Fixed point U16.16 slope table for arc start/end in each quadrant
uint32_t startSlope[4] = {0, 0, 0xFFFFFFFF, 0};
uint32_t endSlope[4] = {0, 0xFFFFFFFF, 0, 0};
// Ensure maximum U16.16 slope of arc ends is ~ 0x8000 0000
constexpr float minDivisor = 1.0f/0x8000;
// Fill in start slope table and empty quadrants
float fabscos = fabsf(cosf(startAngle * deg2rad));
float fabssin = fabsf(sinf(startAngle * deg2rad));
// U16.16 slope of arc start
uint32_t slope = (fabscos/(fabssin + minDivisor)) * (float)(1<<16);
// Update slope table, add slope for arc start
if (startAngle < 90) {
startSlope[0] = slope;
}
else if (startAngle < 180) {
startSlope[1] = slope;
}
else if (startAngle < 270) {
startSlope[1] = 0xFFFFFFFF;
startSlope[2] = slope;
}
else {
startSlope[1] = 0xFFFFFFFF;
startSlope[2] = 0;
startSlope[3] = slope;
}
// Fill in end slope table and empty quadrants
fabscos = fabsf(cosf(endAngle * deg2rad));
fabssin = fabsf(sinf(endAngle * deg2rad));
// U16.16 slope of arc end
slope = (uint32_t)((fabscos/(fabssin + minDivisor)) * (float)(1<<16));
// Work out which quadrants will need to be drawn and add slope for arc end
if (endAngle < 90) {
endSlope[0] = slope;
endSlope[1] = 0;
endSlope[2] = 0xFFFFFFFF;
}
else if (endAngle < 180) {
endSlope[1] = slope;
endSlope[2] = 0xFFFFFFFF;
}
else if (endAngle < 270) {
endSlope[2] = slope;
}
else {
endSlope[3] = slope;
}
// Scan quadrant
for (int32_t cy = r - 1; cy > 0; cy--)
{
uint32_t len[4] = { 0, 0, 0, 0}; // Pixel run length
int32_t xst[4] = {-1, -1, -1, -1}; // Pixel run x start
uint32_t dy2 = (r - cy) * (r - cy);
// Find and track arc zone start point
while ((r - xs) * (r - xs) + dy2 >= r1) xs++;
for (int32_t cx = xs; cx < r; cx++)
{
// Calculate radius^2
uint32_t hyp = (r - cx) * (r - cx) + dy2;
// If in outer zone calculate alpha
if (hyp > r2) {
//alpha = (uint8_t)((rf - sqrtf(hyp)) * 255);
alpha = ~sqrt_fraction(hyp); // Outer AA zone
}
// If within arc fill zone, get line start and lengths for each quadrant
else if (hyp >= r3) {
// Calculate U16.16 slope
slope = ((r - cy) << 16)/(r - cx);
if (slope <= startSlope[0] && slope >= endSlope[0]) { // slope hi -> lo
xst[0] = cx; // Bottom left line end
len[0]++;
}
if (slope >= startSlope[1] && slope <= endSlope[1]) { // slope lo -> hi
xst[1] = cx; // Top left line end
len[1]++;
}
if (slope <= startSlope[2] && slope >= endSlope[2]) { // slope hi -> lo
xst[2] = cx; // Bottom right line start
len[2]++;
}
if (slope >= startSlope[3] && slope <= endSlope[3]) { // slope lo -> hi
xst[3] = cx; // Top right line start
len[3]++;
}
continue; // Next x
}
else {
if (hyp <= r4) break; // Skip inner pixels
//alpha = (uint8_t)((sqrtf(hyp) - irf) * 255.0);
alpha = sqrt_fraction(hyp); // Inner AA zone
}
if (alpha < 16) continue; // Skip low alpha pixels
// If background is read it must be done in each quadrant
uint16_t pcol = alphaBlend(alpha, fg_color, bg_color);
// Check if an AA pixels need to be drawn
slope = ((r - cy)<<16)/(r - cx);
if (slope <= startSlope[0] && slope >= endSlope[0]) // BL
drawPixel(x + cx - r, y - cy + r, pcol);
if (slope >= startSlope[1] && slope <= endSlope[1]) // TL
drawPixel(x + cx - r, y + cy - r, pcol);
if (slope <= startSlope[2] && slope >= endSlope[2]) // TR
drawPixel(x - cx + r, y + cy - r, pcol);
if (slope >= startSlope[3] && slope <= endSlope[3]) // BR
drawPixel(x - cx + r, y - cy + r, pcol);
}
// Add line in inner zone
if (len[0]) drawFastHLine(x + xst[0] - len[0] + 1 - r, y - cy + r, len[0], fg_color); // BL
if (len[1]) drawFastHLine(x + xst[1] - len[1] + 1 - r, y + cy - r, len[1], fg_color); // TL
if (len[2]) drawFastHLine(x - xst[2] + r, y + cy - r, len[2], fg_color); // TR
if (len[3]) drawFastHLine(x - xst[3] + r, y - cy + r, len[3], fg_color); // BR
}
// Fill in centre lines
if (startAngle == 0 || endAngle == 360) drawFastVLine(x, y + r - w, w, fg_color); // Bottom
if (startAngle <= 90 && endAngle >= 90) drawFastHLine(x - r + 1, y, w, fg_color); // Left
if (startAngle <= 180 && endAngle >= 180) drawFastVLine(x, y - r + 1, w, fg_color); // Top
if (startAngle <= 270 && endAngle >= 270) drawFastHLine(x + r - w, y, w, fg_color); // Right
inTransaction = lockTransaction;
end_tft_write();
}
/***************************************************************************************
** Function name: drawSmoothCircle
** Description: Draw a smooth circle
***************************************************************************************/
// To have effective anti-aliasing the circle will be 3 pixels thick
void TFT_eSPI::drawSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t fg_color, uint32_t bg_color)
{
drawSmoothRoundRect(x-r, y-r, r, r-1, 0, 0, fg_color, bg_color);
}
/*************************************************************************************** /***************************************************************************************
** Function name: fillSmoothCircle ** Function name: fillSmoothCircle
** Description: Draw a filled anti-aliased circle ** Description: Draw a filled anti-aliased circle
@ -3789,12 +4190,19 @@ void TFT_eSPI::fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color,
int32_t hyp2 = (r - cx) * (r - cx) + dy2; int32_t hyp2 = (r - cx) * (r - cx) + dy2;
if (hyp2 <= r1) break; if (hyp2 <= r1) break;
if (hyp2 >= r2) continue; if (hyp2 >= r2) continue;
//*
uint8_t alpha = ~sqrt_fraction(hyp2);
if (alpha > 246) break;
xs = cx;
if (alpha < 9) continue;
//*/
/*
float alphaf = (float)r - sqrtf(hyp2); float alphaf = (float)r - sqrtf(hyp2);
if (alphaf > HiAlphaTheshold) break; if (alphaf > HiAlphaTheshold) break;
xs = cx; xs = cx;
if (alphaf < LoAlphaTheshold) continue; if (alphaf < LoAlphaTheshold) continue;
uint8_t alpha = alphaf * 255; uint8_t alpha = alphaf * 255;
//*/
if (bg_color == 0x00FFFFFF) { if (bg_color == 0x00FFFFFF) {
drawPixel(x + cx - r, y + cy - r, color, alpha, bg_color); drawPixel(x + cx - r, y + cy - r, color, alpha, bg_color);
drawPixel(x - cx + r, y + cy - r, color, alpha, bg_color); drawPixel(x - cx + r, y + cy - r, color, alpha, bg_color);
@ -3816,6 +4224,119 @@ void TFT_eSPI::fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color,
} }
/***************************************************************************************
** Function name: drawSmoothRoundRect
** Description: Draw a rounded rectangle
***************************************************************************************/
// x,y is top left corner of bounding box for a complete rounded rectangle
// r = arc outer corner radius, ir = arc inner radius. Arc thickness = r-ir+1
// w and h are width and height of the bounding rectangle
// If w and h are < radius (e.g. 0,0) a circle will be drawn with centre at x+r,y+r
// Arc foreground fg_color anti-aliased with background colour at edges
// A subset of corners can be drawn by specifying a quadrants mask. A bit set in the
// mask means draw that quadrant (all are drawn if parameter missing):
// 0x1 | 0x2
// ---¦--- Arc quadrant mask select bits (as in drawCircleHelper fn)
// 0x8 | 0x4
void TFT_eSPI::drawSmoothRoundRect(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t w, int32_t h, uint32_t fg_color, uint32_t bg_color, uint8_t quadrants)
{
if (_vpOoB) return;
if (r < ir) transpose(r, ir); // Required that r > ir
if (r <= 0 || ir < 0) return; // Invalid
w -= 2*r;
h -= 2*r;
if (w < 0) w = 0;
if (h < 0) h = 0;
inTransaction = true;
x += r;
y += r;
/*
float alphaGain = 1.0;
if (w != 0 || h != 0) {
if (r - ir < 2) alphaGain = 1.5; // Boost brightness for thin lines
if (r - ir < 1) alphaGain = 1.7;
}
*/
uint16_t t = r - ir + 1;
int32_t xs = 0;
int32_t cx = 0;
int32_t r2 = r * r; // Outer arc radius^2
r++;
int32_t r1 = r * r; // Outer AA zone radius^2
int32_t r3 = ir * ir; // Inner arc radius^2
ir--;
int32_t r4 = ir * ir; // Inner AA zone radius^2
//float irf = ir;
//float rf = r;
uint8_t alpha = 0;
// Scan top left quadrant x y r ir fg_color bg_color
for (int32_t cy = r - 1; cy > 0; cy--)
{
int32_t len = 0; // Pixel run length
int32_t lxst = 0; // Left side run x start
int32_t rxst = 0; // Right side run x start
int32_t dy2 = (r - cy) * (r - cy);
// Find and track arc zone start point
while ((r - xs) * (r - xs) + dy2 >= r1) xs++;
for (cx = xs; cx < r; cx++)
{
// Calculate radius^2
int32_t hyp = (r - cx) * (r - cx) + dy2;
// If in outer zone calculate alpha
if (hyp > r2) {
alpha = ~sqrt_fraction(hyp);
//alpha = (uint8_t)((rf - sqrtf(hyp)) * 255); // Outer AA zone
}
// If within arc fill zone, get line lengths for each quadrant
else if (hyp >= r3) {
rxst = cx; // Right side start
len++; // Line segment length
continue; // Next x
}
else {
if (hyp <= r4) break; // Skip inner pixels
//alpha = (uint8_t)((sqrtf(hyp) - irf) * 255); // Inner AA zone
alpha = sqrt_fraction(hyp);
}
if (alpha < 16) continue; // Skip low alpha pixels
// If background is read it must be done in each quadrant - TODO
uint16_t pcol = alphaBlend(alpha, fg_color, bg_color);
if (quadrants & 0x8) drawPixel(x + cx - r, y - cy + r + h, pcol); // BL
if (quadrants & 0x1) drawPixel(x + cx - r, y + cy - r, pcol); // TL
if (quadrants & 0x2) drawPixel(x - cx + r + w, y + cy - r, pcol); // TR
if (quadrants & 0x4) drawPixel(x - cx + r + w, y - cy + r + h, pcol); // BR
}
// Fill arc inner zone in each quadrant
lxst = rxst - len + 1; // Calculate line segment start for left side
if (quadrants & 0x8) drawFastHLine(x + lxst - r, y - cy + r + h, len, fg_color); // BL
if (quadrants & 0x1) drawFastHLine(x + lxst - r, y + cy - r, len, fg_color); // TL
if (quadrants & 0x2) drawFastHLine(x - rxst + r + w, y + cy - r, len, fg_color); // TR
if (quadrants & 0x4) drawFastHLine(x - rxst + r + w, y - cy + r + h, len, fg_color); // BR
}
// Draw sides
if ((quadrants & 0xC) == 0xC) fillRect(x, y + r - t + h, w + 1, t, fg_color); // Bottom
if ((quadrants & 0x9) == 0x9) fillRect(x - r + 1, y, t, h + 1, fg_color); // Left
if ((quadrants & 0x3) == 0x3) fillRect(x, y - r + 1, w + 1, t, fg_color); // Top
if ((quadrants & 0x6) == 0x6) fillRect(x + r - t + w, y, t, h + 1, fg_color); // Right
inTransaction = lockTransaction;
end_tft_write();
}
/*************************************************************************************** /***************************************************************************************
** Function name: fillSmoothRoundRect ** Function name: fillSmoothRoundRect
** Description: Draw a filled anti-aliased rounded corner rectangle ** Description: Draw a filled anti-aliased rounded corner rectangle
@ -3823,20 +4344,23 @@ void TFT_eSPI::fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color,
void TFT_eSPI::fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t r, uint32_t color, uint32_t bg_color) void TFT_eSPI::fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t r, uint32_t color, uint32_t bg_color)
{ {
inTransaction = true; inTransaction = true;
int32_t xs = 0; int32_t xs = 0;
int32_t cx = 0; int32_t cx = 0;
// Limit radius to half width or height // Limit radius to half width or height
if (r < 0) r = 0; if (r < 0) r = 0;
if (r > w/2) r = w/2; if (r > w/2) r = w/2;
if (r > h/2) r = h/2; if (r > h/2) r = h/2;
y += r; y += r;
h -= 2*r; h -= 2*r;
fillRect(x, y, w, h, color); fillRect(x, y, w, h, color);
h--; h--;
x += r; x += r;
w -= 2*r+1; w -= 2*r+1;
int32_t r1 = r * r; int32_t r1 = r * r;
r++; r++;
int32_t r2 = r * r; int32_t r2 = r * r;
@ -3849,12 +4373,18 @@ void TFT_eSPI::fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, i
int32_t hyp2 = (r - cx) * (r - cx) + dy2; int32_t hyp2 = (r - cx) * (r - cx) + dy2;
if (hyp2 <= r1) break; if (hyp2 <= r1) break;
if (hyp2 >= r2) continue; if (hyp2 >= r2) continue;
uint8_t alpha = ~sqrt_fraction(hyp2);
if (alpha > 246) break;
xs = cx;
if (alpha < 9) continue;
/*
float alphaf = (float)r - sqrtf(hyp2); float alphaf = (float)r - sqrtf(hyp2);
if (alphaf > HiAlphaTheshold) break; if (alphaf > HiAlphaTheshold) break;
xs = cx; xs = cx;
if (alphaf < LoAlphaTheshold) continue; if (alphaf < LoAlphaTheshold) continue;
uint8_t alpha = alphaf * 255; uint8_t alpha = alphaf * 255;
*/
drawPixel(x + cx - r, y + cy - r, color, alpha, bg_color); drawPixel(x + cx - r, y + cy - r, color, alpha, bg_color);
drawPixel(x - cx + r + w, y + cy - r, color, alpha, bg_color); drawPixel(x - cx + r + w, y + cy - r, color, alpha, bg_color);
drawPixel(x - cx + r + w, y - cy + r + h, color, alpha, bg_color); drawPixel(x - cx + r + w, y - cy + r + h, color, alpha, bg_color);
@ -3871,6 +4401,7 @@ void TFT_eSPI::fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, i
** Function name: drawSpot - maths intensive, so for small filled circles ** Function name: drawSpot - maths intensive, so for small filled circles
** Description: Draw an anti-aliased filled circle at ax,ay with radius r ** Description: Draw an anti-aliased filled circle at ax,ay with radius r
***************************************************************************************/ ***************************************************************************************/
// Coordinates are floating point to achieve sub-pixel positioning
void TFT_eSPI::drawSpot(float ax, float ay, float r, uint32_t fg_color, uint32_t bg_color) void TFT_eSPI::drawSpot(float ax, float ay, float r, uint32_t fg_color, uint32_t bg_color)
{ {
// Filled circle can be created by the wide line function with zero line length // Filled circle can be created by the wide line function with zero line length
@ -3893,7 +4424,7 @@ void TFT_eSPI::drawWideLine(float ax, float ay, float bx, float by, float wd, ui
void TFT_eSPI::drawWedgeLine(float ax, float ay, float bx, float by, float ar, float br, uint32_t fg_color, uint32_t bg_color) void TFT_eSPI::drawWedgeLine(float ax, float ay, float bx, float by, float ar, float br, uint32_t fg_color, uint32_t bg_color)
{ {
if ( (ar < 0.0) || (br < 0.0) )return; if ( (ar < 0.0) || (br < 0.0) )return;
if ( (abs(ax - bx) < 0.01f) && (abs(ay - by) < 0.01f) ) bx += 0.01f; // Avoid divide by zero if ( (fabsf(ax - bx) < 0.01f) && (fabsf(ay - by) < 0.01f) ) bx += 0.01f; // Avoid divide by zero
// Find line bounding box // Find line bounding box
int32_t x0 = (int32_t)floorf(fminf(ax-ar, bx-br)); int32_t x0 = (int32_t)floorf(fminf(ax-ar, bx-br));
@ -3963,7 +4494,7 @@ void TFT_eSPI::drawWedgeLine(float ax, float ay, float bx, float by, float ar, f
pushColor(fg_color); pushColor(fg_color);
continue; continue;
} }
//Blend color with background and plot //Blend colour with background and plot
if (bg_color == 0x00FFFFFF) { if (bg_color == 0x00FFFFFF) {
bg = readPixel(xp, yp); swin = true; bg = readPixel(xp, yp); swin = true;
} }
@ -3976,7 +4507,7 @@ void TFT_eSPI::drawWedgeLine(float ax, float ay, float bx, float by, float ar, f
end_nin_write(); end_nin_write();
} }
// Calculate distance of px,py to closest part of line
/*************************************************************************************** /***************************************************************************************
** Function name: lineDistance - private helper function for drawWedgeLine ** Function name: lineDistance - private helper function for drawWedgeLine
** Description: returns distance of px,py to closest part of a to b wedge ** Description: returns distance of px,py to closest part of a to b wedge
@ -4375,26 +4906,13 @@ uint16_t TFT_eSPI::decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining)
** Function name: alphaBlend ** Function name: alphaBlend
** Description: Blend 16bit foreground and background ** Description: Blend 16bit foreground and background
*************************************************************************************x*/ *************************************************************************************x*/
uint16_t TFT_eSPI::alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc) inline uint16_t TFT_eSPI::alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc)
{ {
// For speed use fixed point maths and rounding to permit a power of 2 division uint32_t rxb = bgc & 0xF81F;
uint16_t fgR = ((fgc >> 10) & 0x3E) + 1; rxb += ((fgc & 0xF81F) - rxb) * (alpha >> 2) >> 6;
uint16_t fgG = ((fgc >> 4) & 0x7E) + 1; uint32_t xgx = bgc & 0x07E0;
uint16_t fgB = ((fgc << 1) & 0x3E) + 1; xgx += ((fgc & 0x07E0) - xgx) * alpha >> 8;
return (rxb & 0xF81F) | (xgx & 0x07E0);
uint16_t bgR = ((bgc >> 10) & 0x3E) + 1;
uint16_t bgG = ((bgc >> 4) & 0x7E) + 1;
uint16_t bgB = ((bgc << 1) & 0x3E) + 1;
// Shift right 1 to drop rounding bit and shift right 8 to divide by 256
uint16_t r = (((fgR * alpha) + (bgR * (255 - alpha))) >> 9);
uint16_t g = (((fgG * alpha) + (bgG * (255 - alpha))) >> 9);
uint16_t b = (((fgB * alpha) + (bgB * (255 - alpha))) >> 9);
// Combine RGB565 colours into 16 bits
//return ((r&0x18) << 11) | ((g&0x30) << 5) | ((b&0x18) << 0); // 2 bit greyscale
//return ((r&0x1E) << 11) | ((g&0x3C) << 5) | ((b&0x1E) << 0); // 4 bit greyscale
return (r << 11) | (g << 5) | (b << 0);
} }
/*************************************************************************************** /***************************************************************************************
@ -4427,22 +4945,13 @@ uint32_t TFT_eSPI::alphaBlend24(uint8_t alpha, uint32_t fgc, uint32_t bgc, uint8
if (alphaDither >255) alpha = 255; if (alphaDither >255) alpha = 255;
} }
// For speed use fixed point maths and rounding to permit a power of 2 division uint32_t rxx = bgc & 0xFF0000;
uint16_t fgR = ((fgc >> 15) & 0x1FE) + 1; rxx += ((fgc & 0xFF0000) - rxx) * alpha >> 8;
uint16_t fgG = ((fgc >> 7) & 0x1FE) + 1; uint32_t xgx = bgc & 0x00FF00;
uint16_t fgB = ((fgc << 1) & 0x1FE) + 1; xgx += ((fgc & 0xFF0000) - xgx) * alpha >> 8;
uint32_t xxb = bgc & 0x0000FF;
uint16_t bgR = ((bgc >> 15) & 0x1FE) + 1; xxb += ((fgc & 0xFF0000) - xxb) * alpha >> 8;
uint16_t bgG = ((bgc >> 7) & 0x1FE) + 1; return (rxx & 0xFF0000) | (xgx & 0x00FF00) | (xxb & 0x0000FF);
uint16_t bgB = ((bgc << 1) & 0x1FE) + 1;
// Shift right 1 to drop rounding bit and shift right 8 to divide by 256
uint16_t r = (((fgR * alpha) + (bgR * (255 - alpha))) >> 9);
uint16_t g = (((fgG * alpha) + (bgG * (255 - alpha))) >> 9);
uint16_t b = (((fgB * alpha) + (bgB * (255 - alpha))) >> 9);
// Combine RGB colours into 24 bits
return (r << 16) | (g << 8) | (b << 0);
} }
/*************************************************************************************** /***************************************************************************************

View File

@ -16,7 +16,7 @@
#ifndef _TFT_eSPIH_ #ifndef _TFT_eSPIH_
#define _TFT_eSPIH_ #define _TFT_eSPIH_
#define TFT_ESPI_VERSION "2.4.79" #define TFT_ESPI_VERSION "2.5.81b"
// Bit level feature flags // Bit level feature flags
// Bit 0 set: viewport capability // Bit 0 set: viewport capability
@ -402,9 +402,6 @@ int16_t tch_spi_freq;// Touch controller read/write SPI frequency
/*************************************************************************************** /***************************************************************************************
** Section 8: Class member and support functions ** Section 8: Class member and support functions
***************************************************************************************/ ***************************************************************************************/
// Swap any type
template <typename T> static inline void
swap_coord(T& a, T& b) { T t = a; a = b; b = t; }
// Callback prototype for smooth font pixel colour read // Callback prototype for smooth font pixel colour read
typedef uint16_t (*getColorCallback)(uint16_t x, uint16_t y); typedef uint16_t (*getColorCallback)(uint16_t x, uint16_t y);
@ -449,6 +446,12 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
void setRotation(uint8_t r); // Set the display image orientation to 0, 1, 2 or 3 void setRotation(uint8_t r); // Set the display image orientation to 0, 1, 2 or 3
uint8_t getRotation(void); // Read the current rotation uint8_t getRotation(void); // Read the current rotation
// Change the origin position from the default top left
// Note: setRotation, setViewport and resetViewport will revert origin to top left corner of screen/sprite
void setOrigin(int32_t x, int32_t y);
int32_t getOriginX(void);
int32_t getOriginY(void);
void invertDisplay(bool i); // Tell TFT to invert all displayed colours void invertDisplay(bool i); // Tell TFT to invert all displayed colours
@ -491,6 +494,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
void end_SDA_Read(void); // Restore MOSI to output void end_SDA_Read(void); // Restore MOSI to output
#endif #endif
// Graphics drawing // Graphics drawing
void fillScreen(uint32_t color), void fillScreen(uint32_t color),
drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color), drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color),
@ -500,28 +504,6 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
void fillRectVGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2); void fillRectVGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2);
void fillRectHGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2); void fillRectHGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2);
// Draw a pixel blended with the pixel colour on the TFT or sprite, return blended colour
// If bg_color is not included the background pixel colour will be read from TFT or sprite
uint16_t drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha, uint32_t bg_color = 0x00FFFFFF);
// Draw a small anti-aliased filled circle at ax,ay with radius r (uses drawWideLine)
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawSpot(float ax, float ay, float r, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased filled circle at x, y with radius r
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color, uint32_t bg_color = 0x00FFFFFF);
void fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased wide line from ax,ay to bx,by width wd with radiused ends (radius is wd/2)
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawWideLine(float ax, float ay, float bx, float by, float wd, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased wide line from ax,ay to bx,by with different width at each end aw, bw and with radiused ends
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawWedgeLine(float ax, float ay, float bx, float by, float aw, float bw, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
void drawCircle(int32_t x, int32_t y, int32_t r, uint32_t color), void drawCircle(int32_t x, int32_t y, int32_t r, uint32_t color),
drawCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, uint32_t color), drawCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, uint32_t color),
fillCircle(int32_t x, int32_t y, int32_t r, uint32_t color), fillCircle(int32_t x, int32_t y, int32_t r, uint32_t color),
@ -534,6 +516,53 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
drawTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color), drawTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color),
fillTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color); fillTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color);
// Smooth (anti-aliased) graphics drawing
// Draw a pixel blended with the background pixel colour (bg_color) specified, return blended colour
// If the bg_color is not specified, the background pixel colour will be read from TFT or sprite
uint16_t drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased (smooth) arc between start and end angles. Arc ends are anti-aliased.
// By default the arc is drawn with square ends unless the "roundEnds" parameter is included and set true
// Angle = 0 is at 6 o'clock position, 90 at 9 o'clock etc. The angles must be in range 0-360 or they will be clipped to these limits
// The start angle may be larger than the end angle. Arcs are always drawn clockwise from the start angle.
void drawSmoothArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool roundEnds = false);
// As per "drawSmoothArc" except endAngle should be greater than startAngle (angles will be swapped otherwise)
// The sides of the arc are anti-aliased by default. If smoothArc is false sides will NOT be anti-aliased
// The ends of the arc are NOT anti-aliased, this facilitates dynamic arc length changes with arc segments and ensures clean segment joints
void drawArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool smoothArc = true);
// Draw an anti-aliased filled circle at x, y with radius r
// Note: The thickness of line is 3 pixels to reduce the visible "braiding" effect of anti-aliasing narrow lines
// this means the inner anti-alias zone is always at r-1 and the outer zone at r+1
void drawSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t fg_color, uint32_t bg_color);
// Draw an anti-aliased filled circle at x, y with radius r
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color, uint32_t bg_color = 0x00FFFFFF);
// Draw a rounded rectangle that has a line thickness of r-ir+1 and bounding box defined by x,y and w,h
// The outer corner radius is r, inner corner radius is ir
// The inside and outside of the border are anti-aliased
void drawSmoothRoundRect(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t w, int32_t h, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF, uint8_t quadrants = 0xF);
// Draw a filled rounded rectangle , corner radius r and bounding box defined by x,y and w,h
void fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color, uint32_t bg_color = 0x00FFFFFF);
// Draw a small anti-aliased filled circle at ax,ay with radius r (uses drawWideLine)
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawSpot(float ax, float ay, float r, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased wide line from ax,ay to bx,by width wd with radiused ends (radius is wd/2)
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawWideLine(float ax, float ay, float bx, float by, float wd, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased wide line from ax,ay to bx,by with different width at each end aw, bw and with radiused ends
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawWedgeLine(float ax, float ay, float bx, float by, float aw, float bw, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
// Image rendering // Image rendering
// Swap the byte order for pushImage() and pushPixels() - corrects endianness // Swap the byte order for pushImage() and pushPixels() - corrects endianness
void setSwapBytes(bool swap); void setSwapBytes(bool swap);
@ -572,11 +601,16 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, uint8_t transparent, bool bpp8 = true, uint16_t *cmap = nullptr); void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, uint8_t transparent, bool bpp8 = true, uint16_t *cmap = nullptr);
// FLASH version // FLASH version
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint8_t *data, bool bpp8, uint16_t *cmap = nullptr); void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint8_t *data, bool bpp8, uint16_t *cmap = nullptr);
// Render a 16 bit colour image with a 1bpp mask
void pushMaskedImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *img, uint8_t *mask);
// This next function has been used successfully to dump the TFT screen to a PC for documentation purposes // This next function has been used successfully to dump the TFT screen to a PC for documentation purposes
// It reads a screen area and returns the 3 RGB 8 bit colour values of each pixel in the buffer // It reads a screen area and returns the 3 RGB 8 bit colour values of each pixel in the buffer
// Set w and h to 1 to read 1 pixel's colour. The data buffer must be at least w * h * 3 bytes // Set w and h to 1 to read 1 pixel's colour. The data buffer must be at least w * h * 3 bytes
void readRectRGB(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data); void readRectRGB(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data);
// Text rendering - value returned is the pixel width of the rendered text // Text rendering - value returned is the pixel width of the rendered text
int16_t drawNumber(long intNumber, int32_t x, int32_t y, uint8_t font), // Draw integer using specified font number int16_t drawNumber(long intNumber, int32_t x, int32_t y, uint8_t font), // Draw integer using specified font number
drawNumber(long intNumber, int32_t x, int32_t y), // Draw integer using current font drawNumber(long intNumber, int32_t x, int32_t y), // Draw integer using current font
@ -598,6 +632,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
drawCentreString(const String& string, int32_t x, int32_t y, uint8_t font),// Deprecated, use setTextDatum() and drawString() drawCentreString(const String& string, int32_t x, int32_t y, uint8_t font),// Deprecated, use setTextDatum() and drawString()
drawRightString(const String& string, int32_t x, int32_t y, uint8_t font); // Deprecated, use setTextDatum() and drawString() drawRightString(const String& string, int32_t x, int32_t y, uint8_t font); // Deprecated, use setTextDatum() and drawString()
// Text rendering and font handling support funtions // Text rendering and font handling support funtions
void setCursor(int16_t x, int16_t y), // Set cursor for tft.print() void setCursor(int16_t x, int16_t y), // Set cursor for tft.print()
setCursor(int16_t x, int16_t y, uint8_t font); // Set cursor and font number for tft.print() setCursor(int16_t x, int16_t y, uint8_t font); // Set cursor and font number for tft.print()
@ -638,13 +673,14 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Support function to UTF8 decode and draw characters piped through print stream // Support function to UTF8 decode and draw characters piped through print stream
size_t write(uint8_t); size_t write(uint8_t);
// size_t write(const uint8_t *buf, size_t len); // size_t write(const uint8_t *buf, size_t len);
// Used by Smooth font class to fetch a pixel colour for the anti-aliasing // Used by Smooth font class to fetch a pixel colour for the anti-aliasing
void setCallback(getColorCallback getCol); void setCallback(getColorCallback getCol);
uint16_t fontsLoaded(void); // Each bit in returned value represents a font type that is loaded - used for debug/error handling only uint16_t fontsLoaded(void); // Each bit in returned value represents a font type that is loaded - used for debug/error handling only
// Low level read/write // Low level read/write
void spiwrite(uint8_t); // legacy support only void spiwrite(uint8_t); // legacy support only
#ifndef RM68120_DRIVER #ifndef RM68120_DRIVER
@ -678,15 +714,15 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Alpha blend 2 colours, see generic "alphaBlend_Test" example // Alpha blend 2 colours, see generic "alphaBlend_Test" example
// alpha = 0 = 100% background colour // alpha = 0 = 100% background colour
// alpha = 255 = 100% foreground colour // alpha = 255 = 100% foreground colour
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc); inline uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc);
// 16 bit colour alphaBlend with alpha dither (dither reduces colour banding) // 16 bit colour alphaBlend with alpha dither (dither reduces colour banding)
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc, uint8_t dither); uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc, uint8_t dither);
// 24 bit colour alphaBlend with optional alpha dither // 24 bit colour alphaBlend with optional alpha dither
uint32_t alphaBlend24(uint8_t alpha, uint32_t fgc, uint32_t bgc, uint8_t dither = 0); uint32_t alphaBlend24(uint8_t alpha, uint32_t fgc, uint32_t bgc, uint8_t dither = 0);
// Direct Memory Access (DMA) support functions
// DMA support functions - these are currently just for SPI writes when using the ESP32 or STM32 processors // These can be used for SPI writes when using the ESP32 (original) or STM32 processors.
// DMA works also on RP2040 and PIO SPI, 8 bit parallel and 16 bit parallel // DMA also works on a RP2040 processor with PIO based SPI and parallel (8 and 16 bit) interfaces
// Bear in mind DMA will only be of benefit in particular circumstances and can be tricky // Bear in mind DMA will only be of benefit in particular circumstances and can be tricky
// to manage by noobs. The functions have however been designed to be noob friendly and // to manage by noobs. The functions have however been designed to be noob friendly and
// avoid a few DMA behaviour "gotchas". // avoid a few DMA behaviour "gotchas".
@ -718,8 +754,13 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Push an image to the TFT using DMA, buffer is optional and grabs (double buffers) a copy of the image // Push an image to the TFT using DMA, buffer is optional and grabs (double buffers) a copy of the image
// Use the buffer if the image data will get over-written or destroyed while DMA is in progress // Use the buffer if the image data will get over-written or destroyed while DMA is in progress
// If swapping colour bytes is defined, and the double buffer option is NOT used, then the bytes //
// in the original data image will be swapped by the function before DMA is initiated. // Note 1: If swapping colour bytes is defined, and the double buffer option is NOT used, then the bytes
// in the original image buffer content will be byte swapped by the function before DMA is initiated.
//
// Note 2: If part of the image will be off screen or outside of a set viewport, then the the original
// image buffer content will be altered to a correctly clipped image before DMA is initiated.
//
// The function will wait for the last DMA to complete if it is called while a previous DMA is still // The function will wait for the last DMA to complete if it is called while a previous DMA is still
// in progress, this simplifies the sketch and helps avoid "gotchas". // in progress, this simplifies the sketch and helps avoid "gotchas".
void pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t* data, uint16_t* buffer = nullptr); void pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t* data, uint16_t* buffer = nullptr);
@ -812,6 +853,9 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Single GPIO input/output direction control // Single GPIO input/output direction control
void gpioMode(uint8_t gpio, uint8_t mode); void gpioMode(uint8_t gpio, uint8_t mode);
// Smooth graphics helper
uint8_t sqrt_fraction(uint32_t num);
// Helper function: calculate distance of a point from a finite length line between two points // Helper function: calculate distance of a point from a finite length line between two points
float wedgeLineDistance(float pax, float pay, float bax, float bay, float dr); float wedgeLineDistance(float pax, float pay, float bax, float bay, float dr);
@ -917,6 +961,10 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
}; // End of class TFT_eSPI }; // End of class TFT_eSPI
// Swap any type
template <typename T> static inline void
transpose(T& a, T& b) { T t = a; a = b; b = t; }
/*************************************************************************************** /***************************************************************************************
** Section 10: Additional extension classes ** Section 10: Additional extension classes
***************************************************************************************/ ***************************************************************************************/

View File

@ -11,7 +11,7 @@
#include <Timezone.h> #include <Timezone.h>
// Choose library to load // Choose library to load
#ifdef ESP8266 #ifdef ARDUINO_ARCH_ESP8266
// ESP8266 // ESP8266
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#elif (defined(ARDUINO_ARCH_MBED) || defined(ARDUINO_ARCH_RP2040)) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) #elif (defined(ARDUINO_ARCH_MBED) || defined(ARDUINO_ARCH_RP2040)) && !defined(ARDUINO_RASPBERRY_PI_PICO_W)

View File

@ -0,0 +1,208 @@
// This is a test sketch being developed for a new arc based meter widget
// The meter grahic is fully anti-aliased to avoid jaggy pixelated edges
// For this demo randomly sized meters are drawn, cycled and redrawn a random size.
// The meter is ramped up and down 0-100 and 100-0, then pauses before a new
// random sized meter is drawn
// If the radius is > 25 then the value is drawn in the middle
// The outer ring of the meter uses the drawSmoothCircle function (which draws
// a narrow full circle smooth arc)
// Uncomment to draw meter digits and label text
//#define DRAW_DIGITS
// If DRAW_DIGITS is defined the OpenFontRender library must be loaded since
// the sketch uses a scaleable TrueType font for the text and numerals.
// https://github.com/Bodmer/OpenFontRender
#define LOOP_DELAY 0 // This controls how frequently the meter is updated
// for test purposes this is set to 0
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
#ifdef DRAW_DIGITS
#include "NotoSans_Bold.h"
#include "OpenFontRender.h"
#define TTF_FONT NotoSans_Bold
#endif
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library with default width and height
TFT_eSprite spr = TFT_eSprite(&tft); // Declare Sprite object "spr" with pointer to "tft" object
#ifdef DRAW_DIGITS
OpenFontRender ofr;
#endif
#define DARKER_GREY 0x18E3
uint32_t runTime = 0; // time for next update
int reading = 0; // Value to be displayed
int d = 0; // Variable used for the sinewave test waveform
bool range_error = 0;
int8_t ramp = 1;
bool initMeter = true;
void setup(void) {
Serial.begin(115200);
tft.begin();
tft.setRotation(1);
tft.fillScreen(TFT_NAVY);
//tft.setViewport(0, 0, 240, 320);
}
void loop() {
static uint16_t maxRadius = 0;
int8_t ramp = 1;
static uint8_t radius = 0;
static int16_t xpos = tft.width() / 2;
static int16_t ypos = tft.height() / 2;
bool newMeter = false;
if (maxRadius == 0) {
maxRadius = tft.width();
if (tft.height() < maxRadius) maxRadius = tft.height();
maxRadius = (0.6 * maxRadius) / 2;
radius = maxRadius;
}
// Choose a random meter radius for test purposes and draw for one range cycle
// Clear old meter first
tft.fillCircle(xpos, ypos, radius + 1, TFT_NAVY);
radius = random(20, maxRadius); // Random radius
initMeter = true;
#ifdef DRAW_DIGITS
// Loading a font takes a few milliseconds, so for test purposes it is done outside the test loop
if (ofr.loadFont(TTF_FONT, sizeof(TTF_FONT))) {
Serial.println("Render initialize error");
return;
}
#endif
initMeter = true;
reading = 0;
ramp = 1;
while (!newMeter) {
if (millis() - runTime >= LOOP_DELAY) {
runTime = millis();
reading += ramp;
ringMeter(xpos, ypos, radius, reading, "Watts"); // Draw analogue meter
if (reading > 99) ramp = -1;
if (reading <= 0) ramp = 1;
if (reading > 99) delay(1000);
if (reading <= 0) {
delay(1000);
newMeter = true;
}
}
}
#ifdef DRAW_DIGITS
ofr.unloadFont(); // Recover space used by font metrics etc
#endif
}
// #########################################################################
// Draw the meter on the screen, returns x coord of righthand side
// #########################################################################
// x,y is centre of meter, r the radius, val a number in range 0-100
// units is the meter scale label
void ringMeter(int x, int y, int r, int val, const char *units)
{
static uint16_t last_angle = 30;
if (initMeter) {
initMeter = false;
last_angle = 30;
tft.fillCircle(x, y, r, DARKER_GREY);
tft.drawSmoothCircle(x, y, r, TFT_SILVER, DARKER_GREY);
uint16_t tmp = r - 3;
tft.drawArc(x, y, tmp, tmp - tmp / 5, last_angle, 330, TFT_BLACK, DARKER_GREY);
}
r -= 3;
// Range here is 0-100 so value is scaled to an angle 30-330
int val_angle = map(val, 0, 100, 30, 330);
if (last_angle != val_angle) {
// Could load the required font here
//if (ofr.loadFont(TTF_FONT, sizeof(TTF_FONT))) {
// Serial.println("Render initialize error");
// return;
//}
#ifdef DRAW_DIGITS
ofr.setDrawer(spr); // Link renderer to sprite (font will be rendered in sprite spr)
// Add value in centre if radius is a reasonable size
if ( r >= 25 ) {
// This code gets the font dimensions in pixels to determine the required the sprite size
ofr.setFontSize((6 * r) / 4);
ofr.setFontColor(TFT_WHITE, DARKER_GREY);
// The OpenFontRender library only has simple print functions...
// Digit jiggle for chaging values often happens with proportional fonts because
// digit glyph width varies ( 1 narrower that 4 for example). This code prints up to
// 3 digits with even spacing.
// A few experiemntal fudge factors are used here to position the
// digits in the sprite...
// Create a sprite to draw the digits into
uint8_t w = ofr.getTextWidth("444");
uint8_t h = ofr.getTextHeight("4") + 4;
spr.createSprite(w, h + 2);
spr.fillSprite(DARKER_GREY); // (TFT_BLUE); // (DARKER_GREY);
char str_buf[8]; // Buffed for string
itoa (val, str_buf, 10); // Convert value to string (null terminated)
uint8_t ptr = 0; // Pointer to a digit character
uint8_t dx = 4; // x offfset for cursor position
if (val < 100) dx = ofr.getTextWidth("4") / 2; // Adjust cursor x for 2 digits
if (val < 10) dx = ofr.getTextWidth("4"); // Adjust cursor x for 1 digit
while ((uint8_t)str_buf[ptr] != 0) ptr++; // Count the characters
while (ptr) {
ofr.setCursor(w - dx - w / 20, -h / 2.5); // Offset cursor position in sprtie
ofr.rprintf(str_buf + ptr - 1); // Draw a character
str_buf[ptr - 1] = 0; // Replace character with a null
dx += 1 + w / 3; // Adjust cursor for next character
ptr--; // Decrement character pointer
}
spr.pushSprite(x - w / 2, y - h / 2); // Push sprite containing the val number
spr.deleteSprite(); // Recover used memory
// Make the TFT the print destination, print the units label direct to the TFT
ofr.setDrawer(tft);
ofr.setFontColor(TFT_GOLD, DARKER_GREY);
ofr.setFontSize(r / 2.0);
ofr.setCursor(x, y + (r * 0.4));
ofr.cprintf("Watts");
}
#endif
//ofr.unloadFont(); // Recover space used by font metrics etc
// Allocate a value to the arc thickness dependant of radius
uint8_t thickness = r / 5;
if ( r < 25 ) thickness = r / 3;
// Update the arc, only the zone between last_angle and new val_angle is updated
if (val_angle > last_angle) {
tft.drawArc(x, y, r, r - thickness, last_angle, val_angle, TFT_SKYBLUE, TFT_BLACK); // TFT_SKYBLUE random(0x10000)
}
else {
tft.drawArc(x, y, r, r - thickness, val_angle, last_angle, TFT_BLACK, DARKER_GREY);
}
last_angle = val_angle; // Store meter arc position for next redraw
}
}

View File

@ -0,0 +1,732 @@
// This font is a subset of the full font to reduce array size, ONLY these characters are present:
// !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
// array size is 11592
const unsigned char NotoSans_Bold[] PROGMEM = {
0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x80, 0x00, 0x03, 0x00, 0x30, 0x63, 0x6d, 0x61, 0x70,
0xe1, 0x4c, 0xf1, 0x46, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x0b, 0x6e, 0x67, 0x6c, 0x79, 0x66,
0xab, 0x85, 0x48, 0xd5, 0x00, 0x00, 0x0c, 0x2c, 0x00, 0x00, 0x1b, 0xa0, 0x68, 0x65, 0x61, 0x64,
0x26, 0x95, 0xb4, 0xa1, 0x00, 0x00, 0x27, 0xcc, 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61,
0x03, 0x7f, 0x04, 0x08, 0x00, 0x00, 0x28, 0x04, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, 0x74, 0x78,
0xd0, 0xa7, 0x10, 0x76, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x01, 0x7c, 0x6c, 0x6f, 0x63, 0x61,
0x00, 0x05, 0x33, 0xed, 0x00, 0x00, 0x29, 0xa4, 0x00, 0x00, 0x01, 0x80, 0x6d, 0x61, 0x78, 0x70,
0x07, 0x5d, 0x11, 0x1f, 0x00, 0x00, 0x2b, 0x24, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65,
0x1a, 0x56, 0x03, 0x30, 0x00, 0x00, 0x2b, 0x44, 0x00, 0x00, 0x01, 0x7a, 0x4f, 0x53, 0x2f, 0x32,
0x0f, 0x8e, 0x89, 0xf7, 0x00, 0x00, 0x2c, 0xc0, 0x00, 0x00, 0x00, 0x60, 0x70, 0x6f, 0x73, 0x74,
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x20, 0x00, 0x00, 0x00, 0x20, 0x70, 0x72, 0x65, 0x70,
0x68, 0x06, 0x8c, 0x85, 0x00, 0x00, 0x2d, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe2,
0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x07, 0xa8, 0x00, 0x04, 0x03, 0xc6, 0x00, 0x00, 0x00, 0xbe,
0x00, 0x80, 0x00, 0x06, 0x00, 0x3e, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25,
0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d,
0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35,
0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d,
0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45,
0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d,
0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55,
0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d,
0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65,
0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d,
0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75,
0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d,
0x00, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25,
0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d,
0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35,
0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d,
0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45,
0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d,
0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55,
0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d,
0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65,
0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d,
0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75,
0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d,
0x00, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08,
0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10,
0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18,
0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20,
0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28,
0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30,
0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38,
0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40,
0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48,
0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50,
0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58,
0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x04,
0x03, 0xc6, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x80, 0x00, 0x06, 0x00, 0x3e, 0x00, 0x21, 0x00, 0x22,
0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a,
0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32,
0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a,
0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42,
0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a,
0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52,
0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a,
0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62,
0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a,
0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72,
0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a,
0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0x21, 0x00, 0x22,
0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a,
0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32,
0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a,
0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42,
0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a,
0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52,
0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a,
0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62,
0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a,
0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72,
0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a,
0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05,
0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d,
0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15,
0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d,
0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25,
0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d,
0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35,
0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d,
0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45,
0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d,
0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55,
0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d,
0x00, 0x5e, 0x00, 0x00, 0x00, 0x04, 0x03, 0xc6, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x80, 0x00, 0x06,
0x00, 0x3e, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27,
0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f,
0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37,
0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f,
0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47,
0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f,
0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57,
0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f,
0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67,
0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x6f,
0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77,
0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0xff, 0xff,
0x00, 0x00, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27,
0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f,
0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37,
0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f,
0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47,
0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f,
0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57,
0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f,
0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67,
0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x6f,
0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77,
0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe,
0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0x01, 0x00, 0x02,
0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a,
0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12,
0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a,
0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22,
0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a,
0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32,
0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a,
0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42,
0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a,
0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52,
0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a,
0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x00, 0x00, 0x02, 0x58, 0x08, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x58, 0x00, 0x00, 0xfd, 0xad, 0x02, 0x4e,
0x00, 0x00, 0xfd, 0xb2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x05, 0x00, 0x00,
0x07, 0xf6, 0x00, 0x00, 0x00, 0x02, 0x00, 0x39, 0xff, 0xf3, 0x00, 0xe4, 0x02, 0xca, 0x00, 0x03,
0x00, 0x0f, 0x00, 0x00, 0x37, 0x23, 0x03, 0x33, 0x03, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14,
0x06, 0x23, 0x22, 0x26, 0xcb, 0x77, 0x19, 0xa9, 0xab, 0x32, 0x24, 0x23, 0x32, 0x32, 0x23, 0x24,
0x32, 0xed, 0x01, 0xdd, 0xfd, 0x7c, 0x2e, 0x25, 0x25, 0x2e, 0x2c, 0x27, 0x27, 0x00, 0x02, 0x00,
0x41, 0x01, 0xc8, 0x01, 0x97, 0x02, 0xca, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x13, 0x03, 0x23,
0x03, 0x21, 0x03, 0x23, 0x03, 0xc9, 0x14, 0x60, 0x14, 0x01, 0x56, 0x14, 0x60, 0x14, 0x02, 0xca,
0xfe, 0xfe, 0x01, 0x02, 0xfe, 0xfe, 0x01, 0x02, 0x00, 0x02, 0x00, 0x16, 0x00, 0x00, 0x02, 0x70,
0x02, 0xc9, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x07, 0x33, 0x15, 0x23, 0x07, 0x23, 0x37,
0x23, 0x07, 0x23, 0x37, 0x23, 0x35, 0x33, 0x37, 0x23, 0x35, 0x33, 0x37, 0x33, 0x07, 0x33, 0x37,
0x33, 0x07, 0x33, 0x15, 0x05, 0x33, 0x37, 0x23, 0x01, 0xe8, 0x17, 0x7e, 0x91, 0x26, 0x6b, 0x26,
0x5f, 0x25, 0x69, 0x24, 0x74, 0x87, 0x17, 0x7b, 0x8d, 0x26, 0x6b, 0x26, 0x61, 0x26, 0x69, 0x26,
0x75, 0xfe, 0x97, 0x60, 0x17, 0x60, 0x01, 0x9c, 0x71, 0x65, 0xc6, 0xc6, 0xc6, 0xc6, 0x65, 0x71,
0x66, 0xc7, 0xc7, 0xc7, 0xc7, 0x66, 0x71, 0x71, 0x00, 0x03, 0x00, 0x2b, 0xff, 0xc6, 0x02, 0x15,
0x02, 0xf7, 0x00, 0x22, 0x00, 0x28, 0x00, 0x2e, 0x00, 0x00, 0x37, 0x26, 0x26, 0x27, 0x35, 0x16,
0x16, 0x17, 0x35, 0x2e, 0x02, 0x35, 0x34, 0x36, 0x37, 0x35, 0x33, 0x15, 0x16, 0x17, 0x07, 0x26,
0x26, 0x27, 0x15, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, 0x15, 0x23, 0x11, 0x06, 0x15, 0x14, 0x16,
0x17, 0x13, 0x36, 0x35, 0x34, 0x26, 0x27, 0xfd, 0x41, 0x66, 0x2a, 0x29, 0x74, 0x34, 0x4d, 0x5d,
0x28, 0x75, 0x5d, 0x43, 0x6f, 0x5b, 0x2e, 0x28, 0x51, 0x23, 0x36, 0x62, 0x3d, 0x6a, 0x6b, 0x43,
0x3f, 0x1e, 0x21, 0x43, 0x42, 0x21, 0x21, 0x28, 0x02, 0x15, 0x13, 0x81, 0x14, 0x21, 0x03, 0x97,
0x1e, 0x39, 0x46, 0x31, 0x4b, 0x59, 0x08, 0x4b, 0x49, 0x04, 0x29, 0x72, 0x11, 0x12, 0x03, 0x90,
0x14, 0x2f, 0x48, 0x3b, 0x49, 0x62, 0x0a, 0x64, 0x02, 0x6d, 0x09, 0x2a, 0x15, 0x1c, 0x0f, 0xfe,
0xde, 0x0c, 0x2e, 0x14, 0x1d, 0x0f, 0x00, 0x05, 0x00, 0x1f, 0xff, 0xf7, 0x03, 0x66, 0x02, 0xd4,
0x00, 0x0b, 0x00, 0x0f, 0x00, 0x17, 0x00, 0x23, 0x00, 0x2b, 0x00, 0x00, 0x13, 0x32, 0x16, 0x15,
0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x05, 0x01, 0x23, 0x01, 0x05, 0x22, 0x15, 0x14,
0x33, 0x32, 0x35, 0x34, 0x05, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36,
0x17, 0x22, 0x15, 0x14, 0x33, 0x32, 0x35, 0x34, 0xc7, 0x54, 0x57, 0x52, 0x59, 0x52, 0x56, 0x50,
0x02, 0x53, 0xfe, 0x74, 0x75, 0x01, 0x8c, 0xfe, 0x7b, 0x2e, 0x2e, 0x2f, 0x01, 0xc4, 0x54, 0x57,
0x52, 0x59, 0x52, 0x56, 0x50, 0x59, 0x2e, 0x2e, 0x2f, 0x02, 0xd4, 0x75, 0x6a, 0x6a, 0x77, 0x77,
0x6a, 0x6a, 0x75, 0x0a, 0xfd, 0x36, 0x02, 0xca, 0x5c, 0x7a, 0x7b, 0x7b, 0x7a, 0xb7, 0x75, 0x6a,
0x6a, 0x77, 0x77, 0x6a, 0x6a, 0x75, 0x66, 0x7a, 0x7b, 0x7b, 0x7a, 0x00, 0x03, 0x00, 0x28, 0xff,
0xf6, 0x02, 0xee, 0x02, 0xd4, 0x00, 0x21, 0x00, 0x2d, 0x00, 0x37, 0x00, 0x00, 0x01, 0x32, 0x16,
0x16, 0x15, 0x14, 0x06, 0x07, 0x17, 0x36, 0x36, 0x37, 0x33, 0x06, 0x06, 0x07, 0x17, 0x23, 0x27,
0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, 0x26, 0x26, 0x35, 0x34, 0x36, 0x36, 0x17,
0x22, 0x06, 0x15, 0x14, 0x16, 0x17, 0x36, 0x36, 0x35, 0x34, 0x26, 0x03, 0x06, 0x06, 0x15, 0x14,
0x16, 0x33, 0x32, 0x36, 0x37, 0x01, 0x36, 0x3a, 0x5a, 0x34, 0x52, 0x3d, 0x8b, 0x14, 0x1e, 0x0a,
0x9b, 0x0f, 0x3a, 0x2d, 0x93, 0xb8, 0x38, 0x2b, 0x6a, 0x3e, 0x7a, 0x89, 0x46, 0x3d, 0x27, 0x1f,
0x35, 0x5f, 0x3c, 0x19, 0x2d, 0x19, 0x15, 0x2a, 0x2d, 0x28, 0x4a, 0x1c, 0x21, 0x40, 0x30, 0x20,
0x38, 0x17, 0x02, 0xd4, 0x24, 0x45, 0x32, 0x45, 0x5e, 0x23, 0x87, 0x22, 0x4b, 0x26, 0x38, 0x80,
0x38, 0x8f, 0x37, 0x1e, 0x23, 0x70, 0x5b, 0x4c, 0x5b, 0x23, 0x2d, 0x4c, 0x2b, 0x33, 0x4a, 0x28,
0x73, 0x19, 0x23, 0x19, 0x2e, 0x18, 0x17, 0x2e, 0x1e, 0x1e, 0x1a, 0xfe, 0xd1, 0x15, 0x2f, 0x1f,
0x2b, 0x31, 0x10, 0x0e, 0x00, 0x01, 0x00, 0x41, 0x01, 0xc8, 0x00, 0xc9, 0x02, 0xca, 0x00, 0x03,
0x00, 0x00, 0x13, 0x03, 0x23, 0x03, 0xc9, 0x14, 0x60, 0x14, 0x02, 0xca, 0xfe, 0xfe, 0x01, 0x02,
0x00, 0x01, 0x00, 0x28, 0xff, 0x62, 0x01, 0x35, 0x02, 0xca, 0x00, 0x0d, 0x00, 0x00, 0x13, 0x34,
0x36, 0x37, 0x33, 0x06, 0x06, 0x15, 0x14, 0x16, 0x17, 0x23, 0x26, 0x26, 0x28, 0x47, 0x4c, 0x7a,
0x44, 0x47, 0x47, 0x43, 0x79, 0x4c, 0x47, 0x01, 0x12, 0x7a, 0xe3, 0x5b, 0x5e, 0xe2, 0x77, 0x74,
0xe1, 0x5c, 0x58, 0xdf, 0x00, 0x01, 0x00, 0x1e, 0xff, 0x62, 0x01, 0x2b, 0x02, 0xca, 0x00, 0x0d,
0x00, 0x00, 0x01, 0x14, 0x06, 0x07, 0x23, 0x36, 0x36, 0x35, 0x34, 0x26, 0x27, 0x33, 0x16, 0x16,
0x01, 0x2b, 0x47, 0x4c, 0x79, 0x44, 0x46, 0x47, 0x44, 0x7a, 0x4c, 0x47, 0x01, 0x12, 0x79, 0xdf,
0x58, 0x5c, 0xe1, 0x74, 0x77, 0xe2, 0x5e, 0x5b, 0xe3, 0x00, 0x01, 0x00, 0x1f, 0x01, 0x24, 0x02,
0x02, 0x02, 0xf8, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x07, 0x37, 0x17, 0x07, 0x17, 0x07, 0x27, 0x07,
0x27, 0x37, 0x27, 0x37, 0x17, 0x27, 0x01, 0x50, 0x14, 0xb6, 0x10, 0xa6, 0x6d, 0x6f, 0x4c, 0x43,
0x73, 0x6c, 0xa5, 0x13, 0xb2, 0x14, 0x02, 0xf8, 0xb4, 0x33, 0x7b, 0x0c, 0x91, 0x3b, 0x99, 0x98,
0x3a, 0x91, 0x0d, 0x7a, 0x33, 0xb4, 0x00, 0x01, 0x00, 0x2b, 0x00, 0x6f, 0x02, 0x10, 0x02, 0x54,
0x00, 0x0b, 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x23, 0x35, 0x33, 0x35, 0x33,
0x01, 0x53, 0xbd, 0xbd, 0x6b, 0xbd, 0xbd, 0x6b, 0x01, 0x96, 0x6b, 0xbc, 0xbc, 0x6b, 0xbe, 0x00,
0x01, 0x00, 0x1f, 0xff, 0x7f, 0x00, 0xe0, 0x00, 0x74, 0x00, 0x08, 0x00, 0x00, 0x37, 0x06, 0x06,
0x07, 0x23, 0x36, 0x36, 0x37, 0x33, 0xe0, 0x0d, 0x30, 0x19, 0x6b, 0x0e, 0x1c, 0x07, 0x89, 0x69,
0x35, 0x7e, 0x37, 0x3b, 0x86, 0x34, 0x00, 0x01, 0x00, 0x1e, 0x00, 0xcf, 0x01, 0x24, 0x01, 0x49,
0x00, 0x03, 0x00, 0x00, 0x37, 0x35, 0x21, 0x15, 0x1e, 0x01, 0x06, 0xcf, 0x7a, 0x7a, 0x00, 0x01,
0x00, 0x39, 0xff, 0xf3, 0x00, 0xe4, 0x00, 0x99, 0x00, 0x0b, 0x00, 0x00, 0x37, 0x34, 0x36, 0x33,
0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x39, 0x32, 0x24, 0x23, 0x32, 0x32, 0x23, 0x24,
0x32, 0x46, 0x2e, 0x25, 0x25, 0x2e, 0x2c, 0x27, 0x27, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x01,
0x98, 0x02, 0xca, 0x00, 0x03, 0x00, 0x00, 0x01, 0x01, 0x23, 0x01, 0x01, 0x98, 0xfe, 0xf6, 0x87,
0x01, 0x0a, 0x02, 0xca, 0xfd, 0x36, 0x02, 0xca, 0x00, 0x02, 0x00, 0x24, 0xff, 0xf6, 0x02, 0x17,
0x02, 0xd5, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x00, 0x01, 0x14, 0x06, 0x06, 0x23, 0x22, 0x26, 0x35,
0x34, 0x36, 0x36, 0x33, 0x32, 0x16, 0x05, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23,
0x22, 0x06, 0x02, 0x17, 0x31, 0x6d, 0x5c, 0x81, 0x78, 0x30, 0x6e, 0x5b, 0x80, 0x7a, 0xfe, 0xa3,
0x2a, 0x39, 0x38, 0x2c, 0x2c, 0x38, 0x39, 0x2a, 0x01, 0x65, 0x73, 0xa4, 0x58, 0xc3, 0xac, 0x74,
0xa4, 0x58, 0xc2, 0xae, 0x7a, 0x7b, 0x7a, 0x7b, 0x7a, 0x7c, 0x7c, 0x00, 0x01, 0x00, 0x3b, 0x00,
0x00, 0x01, 0x9d, 0x02, 0xca, 0x00, 0x0c, 0x00, 0x00, 0x21, 0x23, 0x11, 0x34, 0x36, 0x37, 0x06,
0x06, 0x07, 0x07, 0x27, 0x37, 0x33, 0x01, 0x9d, 0x97, 0x03, 0x01, 0x05, 0x21, 0x0e, 0x52, 0x49,
0xe6, 0x7c, 0x01, 0x9d, 0x1a, 0x54, 0x20, 0x06, 0x1f, 0x0c, 0x42, 0x5b, 0xb7, 0x00, 0x01, 0x00,
0x26, 0x00, 0x00, 0x02, 0x1b, 0x02, 0xd4, 0x00, 0x1d, 0x00, 0x00, 0x21, 0x21, 0x35, 0x37, 0x3e,
0x02, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x16, 0x15,
0x14, 0x06, 0x06, 0x07, 0x07, 0x15, 0x21, 0x02, 0x1b, 0xfe, 0x0d, 0xb3, 0x36, 0x42, 0x1e, 0x2f,
0x28, 0x29, 0x4e, 0x2b, 0x52, 0x1f, 0x45, 0x5b, 0x40, 0x46, 0x65, 0x37, 0x2f, 0x59, 0x3f, 0x5c,
0x01, 0x37, 0x69, 0xb5, 0x38, 0x4b, 0x3d, 0x23, 0x2b, 0x2a, 0x26, 0x23, 0x61, 0x1b, 0x2e, 0x1d,
0x33, 0x57, 0x37, 0x3b, 0x62, 0x60, 0x3a, 0x56, 0x07, 0x00, 0x01, 0x00, 0x26, 0xff, 0xf6, 0x02,
0x14, 0x02, 0xd4, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x14, 0x06, 0x07, 0x15, 0x16, 0x16, 0x15, 0x14,
0x06, 0x06, 0x23, 0x22, 0x27, 0x35, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x26, 0x23,
0x23, 0x35, 0x33, 0x32, 0x36, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36,
0x33, 0x32, 0x16, 0x01, 0xff, 0x59, 0x41, 0x56, 0x59, 0x3d, 0x7f, 0x64, 0x74, 0x5a, 0x2e, 0x65,
0x2b, 0x51, 0x41, 0x1e, 0x4b, 0x43, 0x36, 0x37, 0x42, 0x45, 0x19, 0x2f, 0x37, 0x33, 0x4b, 0x1a,
0x46, 0x2a, 0x71, 0x4e, 0x6e, 0x81, 0x02, 0x2a, 0x4a, 0x58, 0x10, 0x03, 0x0a, 0x54, 0x47, 0x3e,
0x63, 0x39, 0x27, 0x80, 0x17, 0x18, 0x38, 0x33, 0x1e, 0x29, 0x15, 0x74, 0x19, 0x2b, 0x1c, 0x26,
0x2b, 0x23, 0x11, 0x68, 0x1e, 0x28, 0x59, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x02, 0x2b, 0x02,
0xca, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x00, 0x25, 0x23, 0x15, 0x23, 0x35, 0x21, 0x35, 0x01, 0x33,
0x11, 0x33, 0x27, 0x34, 0x36, 0x36, 0x37, 0x23, 0x06, 0x06, 0x07, 0x07, 0x33, 0x02, 0x2b, 0x56,
0x93, 0xfe, 0xcf, 0x01, 0x39, 0x8b, 0x56, 0xe9, 0x02, 0x03, 0x01, 0x04, 0x09, 0x14, 0x0e, 0x83,
0xac, 0x94, 0x94, 0x94, 0x69, 0x01, 0xcd, 0xfe, 0x3f, 0x79, 0x17, 0x42, 0x39, 0x09, 0x14, 0x26,
0x14, 0xc6, 0x00, 0x01, 0x00, 0x31, 0xff, 0xf6, 0x02, 0x0e, 0x02, 0xca, 0x00, 0x1e, 0x00, 0x00,
0x01, 0x32, 0x16, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x16, 0x16, 0x33, 0x32,
0x36, 0x35, 0x34, 0x23, 0x22, 0x06, 0x07, 0x27, 0x13, 0x21, 0x15, 0x23, 0x07, 0x36, 0x36, 0x01,
0x2c, 0x41, 0x66, 0x3b, 0x90, 0x8d, 0x38, 0x63, 0x25, 0x25, 0x68, 0x2e, 0x43, 0x47, 0x8f, 0x1c,
0x3c, 0x14, 0x3c, 0x1b, 0x01, 0x83, 0xff, 0x0d, 0x11, 0x27, 0x01, 0xc8, 0x32, 0x60, 0x47, 0x74,
0x85, 0x14, 0x13, 0x82, 0x13, 0x1b, 0x37, 0x3a, 0x6c, 0x0b, 0x05, 0x20, 0x01, 0x6c, 0x80, 0x8c,
0x03, 0x07, 0x00, 0x02, 0x00, 0x23, 0xff, 0xf6, 0x02, 0x1b, 0x02, 0xd2, 0x00, 0x1e, 0x00, 0x2c,
0x00, 0x00, 0x13, 0x34, 0x3e, 0x03, 0x33, 0x32, 0x16, 0x17, 0x15, 0x26, 0x26, 0x23, 0x22, 0x06,
0x06, 0x07, 0x33, 0x36, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x26, 0x05,
0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x06, 0x15, 0x14, 0x16, 0x16, 0x23, 0x12, 0x2d,
0x51, 0x7d, 0x59, 0x15, 0x38, 0x13, 0x13, 0x2d, 0x16, 0x59, 0x61, 0x28, 0x03, 0x06, 0x14, 0x4b,
0x3c, 0x5e, 0x6e, 0x83, 0x70, 0x49, 0x76, 0x46, 0x01, 0x02, 0x2c, 0x38, 0x30, 0x31, 0x21, 0x32,
0x1c, 0x18, 0x31, 0x01, 0x2f, 0x3e, 0x78, 0x6b, 0x53, 0x2f, 0x03, 0x04, 0x79, 0x05, 0x05, 0x38,
0x65, 0x42, 0x23, 0x30, 0x76, 0x6c, 0x74, 0x84, 0x43, 0x8b, 0x55, 0x3d, 0x40, 0x34, 0x3c, 0x1d,
0x2e, 0x18, 0x21, 0x3f, 0x2a, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x02, 0x1b, 0x02, 0xca, 0x00,
0x06, 0x00, 0x00, 0x33, 0x01, 0x21, 0x35, 0x21, 0x15, 0x01, 0x6f, 0x01, 0x0c, 0xfe, 0xa0, 0x02,
0x00, 0xfe, 0xf2, 0x02, 0x4b, 0x7f, 0x5f, 0xfd, 0x95, 0x00, 0x03, 0x00, 0x23, 0xff, 0xf6, 0x02,
0x18, 0x02, 0xd3, 0x00, 0x1b, 0x00, 0x27, 0x00, 0x35, 0x00, 0x00, 0x01, 0x32, 0x16, 0x16, 0x15,
0x14, 0x06, 0x07, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37,
0x26, 0x26, 0x35, 0x34, 0x36, 0x36, 0x17, 0x22, 0x06, 0x15, 0x14, 0x16, 0x17, 0x36, 0x36, 0x35,
0x34, 0x26, 0x03, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x26, 0x27, 0x27, 0x06, 0x06,
0x01, 0x1e, 0x3e, 0x67, 0x3f, 0x49, 0x37, 0x26, 0x45, 0x2b, 0x3f, 0x71, 0x4a, 0x78, 0x83, 0x50,
0x39, 0x30, 0x43, 0x40, 0x69, 0x3b, 0x25, 0x31, 0x34, 0x23, 0x22, 0x34, 0x31, 0x94, 0x37, 0x36,
0x38, 0x38, 0x20, 0x2f, 0x19, 0x0d, 0x2e, 0x3a, 0x02, 0xd3, 0x26, 0x4c, 0x3a, 0x40, 0x53, 0x1b,
0x14, 0x35, 0x47, 0x30, 0x3b, 0x58, 0x30, 0x66, 0x59, 0x4a, 0x5a, 0x1c, 0x1e, 0x55, 0x40, 0x39,
0x4c, 0x26, 0x6e, 0x26, 0x23, 0x25, 0x2e, 0x11, 0x10, 0x2d, 0x27, 0x23, 0x26, 0xfe, 0x59, 0x27,
0x32, 0x30, 0x28, 0x1b, 0x29, 0x21, 0x0e, 0x07, 0x16, 0x3a, 0x00, 0x02, 0x00, 0x20, 0xff, 0xf6,
0x02, 0x18, 0x02, 0xd2, 0x00, 0x1e, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x14, 0x0e, 0x03, 0x23, 0x22,
0x26, 0x27, 0x35, 0x16, 0x16, 0x33, 0x32, 0x36, 0x36, 0x37, 0x23, 0x06, 0x06, 0x23, 0x22, 0x26,
0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x16, 0x25, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36,
0x36, 0x35, 0x34, 0x26, 0x26, 0x02, 0x18, 0x12, 0x2d, 0x51, 0x7d, 0x59, 0x15, 0x38, 0x13, 0x14,
0x2c, 0x16, 0x59, 0x61, 0x28, 0x03, 0x06, 0x15, 0x45, 0x44, 0x5b, 0x6e, 0x83, 0x70, 0x49, 0x76,
0x46, 0xfe, 0xfe, 0x2c, 0x38, 0x30, 0x31, 0x22, 0x31, 0x1c, 0x18, 0x30, 0x01, 0x99, 0x3d, 0x79,
0x6b, 0x53, 0x2f, 0x03, 0x04, 0x79, 0x04, 0x06, 0x39, 0x64, 0x42, 0x23, 0x30, 0x76, 0x6c, 0x74,
0x84, 0x43, 0x8b, 0x55, 0x3c, 0x41, 0x34, 0x3c, 0x1e, 0x2d, 0x18, 0x21, 0x40, 0x29, 0x00, 0x02,
0x00, 0x39, 0xff, 0xf3, 0x00, 0xe4, 0x02, 0x2c, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x00, 0x13, 0x34,
0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x11, 0x34, 0x36, 0x33, 0x32, 0x16,
0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x39, 0x32, 0x24, 0x23, 0x32, 0x32, 0x23, 0x24, 0x32, 0x32,
0x24, 0x23, 0x32, 0x32, 0x23, 0x24, 0x32, 0x01, 0xd9, 0x2e, 0x25, 0x25, 0x2e, 0x2c, 0x27, 0x27,
0xfe, 0x99, 0x2e, 0x25, 0x25, 0x2e, 0x2c, 0x27, 0x27, 0x00, 0x02, 0x00, 0x1f, 0xff, 0x7f, 0x00,
0xe4, 0x02, 0x2c, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x00, 0x13, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15,
0x14, 0x06, 0x23, 0x22, 0x26, 0x13, 0x06, 0x06, 0x07, 0x23, 0x36, 0x36, 0x37, 0x33, 0x39, 0x32,
0x24, 0x23, 0x32, 0x32, 0x23, 0x24, 0x32, 0xa7, 0x0d, 0x30, 0x19, 0x6b, 0x0e, 0x1c, 0x07, 0x89,
0x01, 0xd9, 0x2e, 0x25, 0x25, 0x2e, 0x2c, 0x27, 0x27, 0xfe, 0xbc, 0x35, 0x7e, 0x37, 0x3b, 0x86,
0x34, 0x00, 0x01, 0x00, 0x2b, 0x00, 0x63, 0x02, 0x10, 0x02, 0x71, 0x00, 0x06, 0x00, 0x00, 0x25,
0x25, 0x35, 0x25, 0x15, 0x05, 0x05, 0x02, 0x10, 0xfe, 0x1b, 0x01, 0xe5, 0xfe, 0xb2, 0x01, 0x4e,
0x63, 0xd6, 0x46, 0xf2, 0x75, 0x9b, 0x89, 0x00, 0x02, 0x00, 0x2b, 0x00, 0xcc, 0x02, 0x10, 0x01,
0xf4, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x13, 0x35, 0x21, 0x15, 0x05, 0x35, 0x21, 0x15, 0x2b,
0x01, 0xe5, 0xfe, 0x1b, 0x01, 0xe5, 0x01, 0x8a, 0x6a, 0x6a, 0xbe, 0x6b, 0x6b, 0x00, 0x01, 0x00,
0x2b, 0x00, 0x63, 0x02, 0x10, 0x02, 0x71, 0x00, 0x06, 0x00, 0x00, 0x37, 0x25, 0x25, 0x35, 0x05,
0x15, 0x05, 0x2b, 0x01, 0x4e, 0xfe, 0xb2, 0x01, 0xe5, 0xfe, 0x1b, 0xd8, 0x89, 0x9b, 0x75, 0xf2,
0x46, 0xd6, 0x00, 0x02, 0x00, 0x03, 0xff, 0xf3, 0x01, 0xc5, 0x02, 0xd4, 0x00, 0x1d, 0x00, 0x29,
0x00, 0x00, 0x13, 0x34, 0x36, 0x37, 0x36, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27,
0x36, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x06, 0x07, 0x0e, 0x02, 0x15, 0x15, 0x23, 0x07,
0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x87, 0x2a, 0x33, 0x2d, 0x27,
0x2f, 0x2a, 0x2a, 0x52, 0x2b, 0x35, 0x31, 0x72, 0x44, 0x68, 0x73, 0x1a, 0x34, 0x27, 0x1d, 0x20,
0x0b, 0x81, 0x10, 0x32, 0x24, 0x23, 0x32, 0x32, 0x23, 0x24, 0x32, 0x01, 0x11, 0x32, 0x44, 0x25,
0x20, 0x2f, 0x20, 0x20, 0x21, 0x1a, 0x16, 0x6b, 0x1b, 0x22, 0x64, 0x4d, 0x29, 0x3c, 0x33, 0x1d,
0x15, 0x1e, 0x1c, 0x15, 0x1d, 0xa7, 0x2e, 0x25, 0x25, 0x2e, 0x2c, 0x27, 0x27, 0x00, 0x02, 0x00,
0x32, 0xff, 0xac, 0x03, 0x4f, 0x02, 0xca, 0x00, 0x3f, 0x00, 0x4d, 0x00, 0x00, 0x01, 0x14, 0x0e,
0x02, 0x23, 0x22, 0x26, 0x27, 0x23, 0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x36, 0x33,
0x32, 0x16, 0x17, 0x07, 0x06, 0x14, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x36, 0x35, 0x34, 0x26,
0x26, 0x23, 0x22, 0x06, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x06, 0x06, 0x23,
0x22, 0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x16, 0x05, 0x14, 0x16, 0x33, 0x32,
0x36, 0x37, 0x37, 0x26, 0x26, 0x23, 0x22, 0x06, 0x06, 0x03, 0x4f, 0x16, 0x2d, 0x44, 0x2e, 0x25,
0x38, 0x0b, 0x08, 0x14, 0x43, 0x2f, 0x59, 0x61, 0x3a, 0x6a, 0x48, 0x2f, 0x65, 0x1c, 0x0a, 0x01,
0x17, 0x0e, 0x17, 0x1e, 0x0f, 0x44, 0x75, 0x4b, 0x69, 0x8f, 0x4a, 0x91, 0x88, 0x3a, 0x7e, 0x34,
0x30, 0x76, 0x42, 0x7c, 0xb0, 0x5d, 0x3c, 0x71, 0x9e, 0x62, 0x6b, 0xa6, 0x5f, 0xfe, 0x0c, 0x2e,
0x26, 0x32, 0x29, 0x04, 0x06, 0x0b, 0x1c, 0x11, 0x2f, 0x39, 0x19, 0x01, 0x66, 0x2e, 0x5a, 0x4a,
0x2b, 0x23, 0x1c, 0x19, 0x26, 0x6b, 0x57, 0x43, 0x67, 0x3b, 0x11, 0x0a, 0xcd, 0x0a, 0x15, 0x03,
0x29, 0x1b, 0x2d, 0x4b, 0x2d, 0x54, 0x75, 0x3e, 0x57, 0x96, 0x61, 0x87, 0x90, 0x1a, 0x13, 0x5e,
0x14, 0x18, 0x58, 0xa5, 0x74, 0x5b, 0x9c, 0x75, 0x41, 0x56, 0xa0, 0xab, 0x37, 0x30, 0x49, 0x3b,
0x6c, 0x02, 0x03, 0x29, 0x41, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0xb2, 0x02, 0xcd, 0x00,
0x07, 0x00, 0x12, 0x00, 0x00, 0x21, 0x27, 0x21, 0x07, 0x23, 0x13, 0x33, 0x13, 0x01, 0x2e, 0x02,
0x27, 0x0e, 0x02, 0x07, 0x07, 0x33, 0x02, 0x0f, 0x34, 0xfe, 0xfc, 0x34, 0xa3, 0xfc, 0xb9, 0xfd,
0xfe, 0xd1, 0x05, 0x10, 0x10, 0x05, 0x05, 0x11, 0x0f, 0x04, 0x33, 0xba, 0xaa, 0xaa, 0x02, 0xcd,
0xfd, 0x33, 0x01, 0xcf, 0x11, 0x34, 0x36, 0x14, 0x14, 0x3b, 0x35, 0x0b, 0xa6, 0x00, 0x03, 0x00,
0x5a, 0x00, 0x00, 0x02, 0x6b, 0x02, 0xca, 0x00, 0x10, 0x00, 0x19, 0x00, 0x22, 0x00, 0x00, 0x01,
0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x15, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x23, 0x21, 0x11, 0x13,
0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x23, 0x1d, 0x02, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23,
0x01, 0x38, 0x8f, 0x92, 0x39, 0x35, 0x24, 0x3a, 0x22, 0x8c, 0x7a, 0xfe, 0xf5, 0xef, 0x42, 0x33,
0x3c, 0x41, 0x50, 0x63, 0x44, 0x36, 0x37, 0x48, 0x02, 0xca, 0x50, 0x65, 0x3d, 0x54, 0x09, 0x05,
0x07, 0x24, 0x44, 0x38, 0x61, 0x6e, 0x02, 0xca, 0xfe, 0xe5, 0x2a, 0x28, 0x29, 0x24, 0x9f, 0x78,
0xba, 0x35, 0x2c, 0x28, 0x31, 0x00, 0x01, 0x00, 0x3a, 0xff, 0xf6, 0x02, 0x5a, 0x02, 0xd4, 0x00,
0x1b, 0x00, 0x00, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x06, 0x06,
0x23, 0x22, 0x26, 0x26, 0x35, 0x34, 0x36, 0x36, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x01,
0x89, 0x57, 0x5c, 0x55, 0x5e, 0x2c, 0x57, 0x33, 0x2f, 0x5c, 0x39, 0x6e, 0x8f, 0x44, 0x4e, 0x95,
0x6c, 0x35, 0x6b, 0x31, 0x31, 0x28, 0x51, 0x02, 0x56, 0x82, 0x71, 0x72, 0x7d, 0x14, 0x12, 0x7f,
0x13, 0x12, 0x5b, 0xa5, 0x6e, 0x6c, 0xa6, 0x5e, 0x1b, 0x17, 0x7b, 0x13, 0x1c, 0x00, 0x02, 0x00,
0x5a, 0x00, 0x00, 0x02, 0xaa, 0x02, 0xca, 0x00, 0x09, 0x00, 0x11, 0x00, 0x00, 0x01, 0x14, 0x06,
0x23, 0x23, 0x11, 0x33, 0x32, 0x16, 0x16, 0x07, 0x34, 0x26, 0x23, 0x23, 0x11, 0x33, 0x32, 0x02,
0xaa, 0xcd, 0xb9, 0xca, 0xe0, 0x70, 0xa5, 0x5b, 0x9d, 0x68, 0x63, 0x51, 0x41, 0xdb, 0x01, 0x6c,
0xb5, 0xb7, 0x02, 0xca, 0x50, 0x9b, 0x77, 0x77, 0x6f, 0xfe, 0x2f, 0x00, 0x01, 0x00, 0x5a, 0x00,
0x00, 0x01, 0xf5, 0x02, 0xca, 0x00, 0x0b, 0x00, 0x00, 0x21, 0x21, 0x11, 0x21, 0x15, 0x21, 0x15,
0x33, 0x15, 0x23, 0x15, 0x21, 0x01, 0xf5, 0xfe, 0x65, 0x01, 0x9b, 0xfe, 0xfc, 0xf2, 0xf2, 0x01,
0x04, 0x02, 0xca, 0x7c, 0x9d, 0x7c, 0xb8, 0x00, 0x01, 0x00, 0x5a, 0x00, 0x00, 0x01, 0xf3, 0x02,
0xca, 0x00, 0x09, 0x00, 0x00, 0x33, 0x23, 0x11, 0x21, 0x15, 0x21, 0x15, 0x33, 0x15, 0x23, 0xef,
0x95, 0x01, 0x99, 0xfe, 0xfc, 0xf2, 0xf2, 0x02, 0xca, 0x7c, 0xb8, 0x7c, 0x00, 0x01, 0x00, 0x3a,
0xff, 0xf6, 0x02, 0x84, 0x02, 0xd4, 0x00, 0x20, 0x00, 0x00, 0x01, 0x21, 0x11, 0x06, 0x06, 0x23,
0x22, 0x26, 0x35, 0x34, 0x36, 0x36, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x06,
0x06, 0x15, 0x14, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x35, 0x23, 0x01, 0x69, 0x01, 0x1b, 0x38,
0x79, 0x4d, 0xa0, 0xac, 0x57, 0xa6, 0x78, 0x39, 0x6e, 0x2d, 0x32, 0x21, 0x54, 0x2e, 0x42, 0x61,
0x35, 0x26, 0x52, 0x42, 0x20, 0x2d, 0x13, 0x87, 0x01, 0x91, 0xfe, 0x8e, 0x13, 0x16, 0xbc, 0xb4,
0x70, 0xa4, 0x5a, 0x18, 0x14, 0x79, 0x11, 0x16, 0x3c, 0x6d, 0x4a, 0x46, 0x6c, 0x3d, 0x06, 0x04,
0x95, 0x00, 0x01, 0x00, 0x5a, 0x00, 0x00, 0x02, 0xa3, 0x02, 0xca, 0x00, 0x0b, 0x00, 0x00, 0x21,
0x23, 0x11, 0x21, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x02, 0xa3, 0x97, 0xfe, 0xe5,
0x97, 0x97, 0x01, 0x1b, 0x97, 0x01, 0x34, 0xfe, 0xcc, 0x02, 0xca, 0xfe, 0xe8, 0x01, 0x18, 0x00,
0x01, 0x00, 0x20, 0x00, 0x00, 0x01, 0x65, 0x02, 0xca, 0x00, 0x0b, 0x00, 0x00, 0x21, 0x21, 0x35,
0x37, 0x11, 0x27, 0x35, 0x21, 0x15, 0x07, 0x11, 0x17, 0x01, 0x65, 0xfe, 0xbb, 0x57, 0x57, 0x01,
0x45, 0x57, 0x57, 0x56, 0x28, 0x01, 0xce, 0x28, 0x56, 0x56, 0x28, 0xfe, 0x32, 0x28, 0x00, 0x01,
0xff, 0xb6, 0xff, 0x2e, 0x00, 0xf1, 0x02, 0xca, 0x00, 0x11, 0x00, 0x00, 0x17, 0x22, 0x26, 0x27,
0x35, 0x16, 0x16, 0x33, 0x32, 0x36, 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x06, 0x06, 0x0f, 0x1d,
0x2c, 0x10, 0x10, 0x23, 0x14, 0x1a, 0x2b, 0x18, 0x97, 0x39, 0x66, 0xd2, 0x07, 0x04, 0x7e, 0x04,
0x06, 0x14, 0x38, 0x34, 0x02, 0x9d, 0xfd, 0x64, 0x5c, 0x71, 0x33, 0x00, 0x01, 0x00, 0x5a, 0x00,
0x00, 0x02, 0x98, 0x02, 0xca, 0x00, 0x0e, 0x00, 0x00, 0x21, 0x23, 0x03, 0x07, 0x15, 0x23, 0x11,
0x33, 0x11, 0x36, 0x36, 0x37, 0x37, 0x33, 0x03, 0x02, 0x98, 0xac, 0xbb, 0x40, 0x97, 0x97, 0x0f,
0x1e, 0x0f, 0xc1, 0xa8, 0xf9, 0x01, 0x2d, 0x2e, 0xff, 0x02, 0xca, 0xfe, 0xb9, 0x15, 0x2a, 0x15,
0xf3, 0xfe, 0xc4, 0x00, 0x01, 0x00, 0x5a, 0x00, 0x00, 0x02, 0x13, 0x02, 0xca, 0x00, 0x05, 0x00,
0x00, 0x33, 0x11, 0x33, 0x11, 0x21, 0x15, 0x5a, 0x97, 0x01, 0x22, 0x02, 0xca, 0xfd, 0xb3, 0x7d,
0x00, 0x01, 0x00, 0x5a, 0x00, 0x00, 0x03, 0x55, 0x02, 0xca, 0x00, 0x17, 0x00, 0x00, 0x21, 0x03,
0x23, 0x1e, 0x02, 0x15, 0x11, 0x23, 0x11, 0x33, 0x13, 0x33, 0x13, 0x33, 0x11, 0x23, 0x11, 0x34,
0x36, 0x36, 0x37, 0x23, 0x03, 0x01, 0x88, 0xac, 0x04, 0x01, 0x04, 0x04, 0x87, 0xce, 0xa9, 0x03,
0xb3, 0xce, 0x8d, 0x03, 0x03, 0x01, 0x04, 0xb8, 0x02, 0x30, 0x14, 0x50, 0x5b, 0x25, 0xfe, 0xb4,
0x02, 0xca, 0xfd, 0xde, 0x02, 0x22, 0xfd, 0x36, 0x01, 0x52, 0x22, 0x58, 0x4f, 0x14, 0xfd, 0xd1,
0x00, 0x01, 0x00, 0x5a, 0x00, 0x00, 0x02, 0xd3, 0x02, 0xca, 0x00, 0x11, 0x00, 0x00, 0x21, 0x23,
0x01, 0x23, 0x16, 0x16, 0x17, 0x11, 0x23, 0x11, 0x33, 0x01, 0x33, 0x26, 0x26, 0x27, 0x11, 0x33,
0x02, 0xd3, 0xc0, 0xfe, 0xc9, 0x04, 0x02, 0x05, 0x02, 0x87, 0xbf, 0x01, 0x36, 0x03, 0x01, 0x04,
0x02, 0x88, 0x02, 0x1c, 0x33, 0x66, 0x33, 0xfe, 0xb0, 0x02, 0xca, 0xfd, 0xe9, 0x32, 0x62, 0x31,
0x01, 0x52, 0x00, 0x02, 0x00, 0x3a, 0xff, 0xf6, 0x02, 0xe2, 0x02, 0xd5, 0x00, 0x0f, 0x00, 0x1b,
0x00, 0x00, 0x01, 0x14, 0x06, 0x06, 0x23, 0x22, 0x26, 0x26, 0x35, 0x34, 0x36, 0x36, 0x33, 0x32,
0x16, 0x16, 0x05, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x02, 0xe2,
0x49, 0x96, 0x75, 0x74, 0x97, 0x49, 0x49, 0x97, 0x75, 0x74, 0x96, 0x49, 0xfd, 0xf7, 0x56, 0x5f,
0x61, 0x54, 0x54, 0x60, 0x60, 0x56, 0x01, 0x66, 0x6f, 0xa5, 0x5c, 0x5c, 0xa6, 0x6f, 0x6f, 0xa4,
0x5b, 0x5b, 0xa5, 0x6f, 0x70, 0x81, 0x81, 0x70, 0x71, 0x80, 0x80, 0x00, 0x02, 0x00, 0x5a, 0x00,
0x00, 0x02, 0x47, 0x02, 0xca, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x00, 0x01, 0x32, 0x16, 0x15, 0x14,
0x06, 0x06, 0x23, 0x23, 0x15, 0x23, 0x11, 0x17, 0x23, 0x15, 0x33, 0x32, 0x36, 0x35, 0x34, 0x01,
0x3e, 0x8a, 0x7f, 0x34, 0x79, 0x68, 0x41, 0x97, 0xdc, 0x45, 0x32, 0x40, 0x4b, 0x02, 0xca, 0x77,
0x68, 0x3e, 0x6d, 0x42, 0xfe, 0x02, 0xca, 0x7c, 0xd4, 0x33, 0x39, 0x68, 0x00, 0x02, 0x00, 0x3a,
0xff, 0x56, 0x02, 0xe2, 0x02, 0xd5, 0x00, 0x12, 0x00, 0x1e, 0x00, 0x00, 0x01, 0x14, 0x06, 0x07,
0x17, 0x23, 0x27, 0x23, 0x22, 0x26, 0x26, 0x35, 0x34, 0x36, 0x36, 0x33, 0x32, 0x16, 0x16, 0x05,
0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x02, 0xe2, 0x56, 0x5a, 0xac,
0xc2, 0x83, 0x0b, 0x74, 0x97, 0x49, 0x49, 0x97, 0x75, 0x74, 0x96, 0x49, 0xfd, 0xf7, 0x56, 0x5f,
0x61, 0x54, 0x54, 0x60, 0x60, 0x56, 0x01, 0x66, 0x78, 0xaf, 0x29, 0xc0, 0xa0, 0x5c, 0xa6, 0x6f,
0x6f, 0xa4, 0x5b, 0x5b, 0xa5, 0x6f, 0x70, 0x81, 0x81, 0x70, 0x71, 0x80, 0x80, 0x00, 0x02, 0x00,
0x5a, 0x00, 0x00, 0x02, 0x94, 0x02, 0xca, 0x00, 0x0e, 0x00, 0x17, 0x00, 0x00, 0x01, 0x32, 0x16,
0x15, 0x14, 0x06, 0x06, 0x07, 0x13, 0x23, 0x03, 0x23, 0x11, 0x23, 0x11, 0x17, 0x23, 0x15, 0x33,
0x32, 0x36, 0x35, 0x34, 0x26, 0x01, 0x2a, 0x92, 0x8b, 0x25, 0x3d, 0x23, 0xd2, 0xa8, 0xaa, 0x51,
0x97, 0xc5, 0x2e, 0x31, 0x4b, 0x41, 0x45, 0x02, 0xca, 0x6a, 0x6c, 0x31, 0x49, 0x33, 0x10, 0xfe,
0xc9, 0x01, 0x12, 0xfe, 0xee, 0x02, 0xca, 0x7c, 0xc1, 0x32, 0x31, 0x33, 0x2b, 0x00, 0x01, 0x00,
0x2e, 0xff, 0xf6, 0x01, 0xff, 0x02, 0xd4, 0x00, 0x28, 0x00, 0x00, 0x25, 0x14, 0x06, 0x23, 0x22,
0x27, 0x35, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x26, 0x27, 0x2e, 0x03, 0x35, 0x34,
0x36, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x17, 0x1e,
0x02, 0x01, 0xff, 0x89, 0x7e, 0x71, 0x59, 0x33, 0x6d, 0x36, 0x38, 0x2f, 0x25, 0x3e, 0x28, 0x19,
0x3a, 0x35, 0x22, 0x82, 0x70, 0x38, 0x65, 0x37, 0x31, 0x31, 0x4e, 0x29, 0x2b, 0x2e, 0x44, 0x43,
0x37, 0x4d, 0x2a, 0xc6, 0x5f, 0x71, 0x2b, 0x8d, 0x16, 0x25, 0x2b, 0x21, 0x1b, 0x26, 0x21, 0x13,
0x0c, 0x21, 0x31, 0x46, 0x31, 0x60, 0x6b, 0x1a, 0x18, 0x76, 0x14, 0x16, 0x28, 0x20, 0x26, 0x2c,
0x20, 0x1a, 0x38, 0x4c, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x02, 0x2f, 0x02, 0xca, 0x00, 0x07,
0x00, 0x00, 0x21, 0x23, 0x11, 0x23, 0x35, 0x21, 0x15, 0x23, 0x01, 0x6d, 0x97, 0xc2, 0x02, 0x1b,
0xc2, 0x02, 0x4c, 0x7e, 0x7e, 0x00, 0x01, 0x00, 0x55, 0xff, 0xf6, 0x02, 0x9f, 0x02, 0xca, 0x00,
0x12, 0x00, 0x00, 0x25, 0x14, 0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16,
0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x02, 0x9f, 0x41, 0x83, 0x64, 0x8e, 0x94, 0x97, 0x48, 0x47,
0x4a, 0x43, 0x97, 0xfc, 0x4a, 0x77, 0x45, 0x91, 0x77, 0x01, 0xcc, 0xfe, 0x4b, 0x58, 0x48, 0x4e,
0x53, 0x01, 0xb4, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x8a, 0x02, 0xca, 0x00, 0x0e, 0x00,
0x00, 0x01, 0x03, 0x23, 0x03, 0x33, 0x13, 0x1e, 0x02, 0x17, 0x3e, 0x02, 0x37, 0x13, 0x02, 0x8a,
0xf3, 0xa5, 0xf2, 0x99, 0x86, 0x04, 0x0f, 0x10, 0x03, 0x03, 0x0f, 0x10, 0x03, 0x87, 0x02, 0xca,
0xfd, 0x36, 0x02, 0xca, 0xfe, 0x57, 0x0b, 0x3b, 0x41, 0x16, 0x16, 0x41, 0x3b, 0x0b, 0x01, 0xa9,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc7, 0x02, 0xca, 0x00, 0x26, 0x00, 0x00, 0x01, 0x03,
0x23, 0x03, 0x2e, 0x03, 0x27, 0x0e, 0x03, 0x07, 0x03, 0x23, 0x03, 0x33, 0x13, 0x1e, 0x02, 0x17,
0x3e, 0x02, 0x37, 0x13, 0x33, 0x13, 0x1e, 0x02, 0x17, 0x3e, 0x02, 0x37, 0x13, 0x03, 0xc7, 0xb6,
0xac, 0x61, 0x03, 0x09, 0x0b, 0x08, 0x02, 0x01, 0x09, 0x0a, 0x0a, 0x03, 0x60, 0xac, 0xb6, 0x95,
0x5b, 0x06, 0x0e, 0x0c, 0x03, 0x03, 0x0c, 0x0d, 0x05, 0x68, 0x8f, 0x68, 0x05, 0x0d, 0x0c, 0x03,
0x03, 0x0c, 0x0f, 0x05, 0x5b, 0x02, 0xca, 0xfd, 0x36, 0x01, 0x77, 0x0b, 0x2c, 0x34, 0x2f, 0x0d,
0x0d, 0x2f, 0x33, 0x2d, 0x0c, 0xfe, 0x8a, 0x02, 0xca, 0xfe, 0x7a, 0x17, 0x46, 0x46, 0x18, 0x19,
0x45, 0x41, 0x12, 0x01, 0x90, 0xfe, 0x70, 0x11, 0x42, 0x46, 0x18, 0x19, 0x45, 0x46, 0x17, 0x01,
0x86, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9b, 0x02, 0xca, 0x00, 0x0b, 0x00, 0x00, 0x21,
0x23, 0x03, 0x03, 0x23, 0x13, 0x03, 0x33, 0x13, 0x13, 0x33, 0x03, 0x02, 0x9b, 0xad, 0xa6, 0xa6,
0xa2, 0xed, 0xde, 0xa7, 0x9a, 0x97, 0xa3, 0xe0, 0x01, 0x0e, 0xfe, 0xf2, 0x01, 0x70, 0x01, 0x5a,
0xfe, 0xff, 0x01, 0x01, 0xfe, 0x9e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x70, 0x02, 0xca,
0x00, 0x08, 0x00, 0x00, 0x01, 0x13, 0x33, 0x03, 0x11, 0x23, 0x11, 0x03, 0x33, 0x01, 0x38, 0x95,
0xa3, 0xed, 0x96, 0xed, 0xa4, 0x01, 0xa4, 0x01, 0x26, 0xfe, 0x4c, 0xfe, 0xea, 0x01, 0x11, 0x01,
0xb9, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x02, 0x2b, 0x02, 0xca, 0x00, 0x09, 0x00, 0x00, 0x21,
0x21, 0x35, 0x01, 0x21, 0x35, 0x21, 0x15, 0x01, 0x21, 0x02, 0x2b, 0xfd, 0xed, 0x01, 0x56, 0xfe,
0xb3, 0x02, 0x01, 0xfe, 0xaa, 0x01, 0x5f, 0x62, 0x01, 0xeb, 0x7d, 0x62, 0xfe, 0x15, 0x00, 0x01,
0x00, 0x46, 0xff, 0x62, 0x01, 0x32, 0x02, 0xca, 0x00, 0x07, 0x00, 0x00, 0x05, 0x23, 0x11, 0x33,
0x15, 0x23, 0x11, 0x33, 0x01, 0x32, 0xec, 0xec, 0x6d, 0x6d, 0x9e, 0x03, 0x68, 0x67, 0xfd, 0x66,
0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x01, 0x97, 0x02, 0xca, 0x00, 0x03, 0x00, 0x00, 0x13, 0x01,
0x23, 0x01, 0x8d, 0x01, 0x0a, 0x87, 0xfe, 0xf6, 0x02, 0xca, 0xfd, 0x36, 0x02, 0xca, 0x00, 0x01,
0x00, 0x19, 0xff, 0x62, 0x01, 0x05, 0x02, 0xca, 0x00, 0x07, 0x00, 0x00, 0x17, 0x33, 0x11, 0x23,
0x35, 0x33, 0x11, 0x23, 0x19, 0x6d, 0x6d, 0xec, 0xec, 0x37, 0x02, 0x9a, 0x67, 0xfc, 0x98, 0x00,
0x01, 0x00, 0x17, 0x00, 0xfe, 0x02, 0x25, 0x02, 0xce, 0x00, 0x06, 0x00, 0x00, 0x37, 0x13, 0x33,
0x13, 0x23, 0x03, 0x03, 0x17, 0xd6, 0x46, 0xf2, 0x75, 0x9d, 0x89, 0xfe, 0x01, 0xd0, 0xfe, 0x30,
0x01, 0x3a, 0xfe, 0xc6, 0x00, 0x01, 0xff, 0xfe, 0xff, 0x62, 0x01, 0x9d, 0xff, 0xa6, 0x00, 0x03,
0x00, 0x00, 0x05, 0x21, 0x35, 0x21, 0x01, 0x9d, 0xfe, 0x61, 0x01, 0x9f, 0x9e, 0x44, 0x00, 0x01,
0x00, 0x28, 0x02, 0x5e, 0x01, 0x42, 0x02, 0xfe, 0x00, 0x0c, 0x00, 0x00, 0x13, 0x1e, 0x02, 0x17,
0x15, 0x23, 0x2e, 0x03, 0x27, 0x35, 0xcf, 0x0f, 0x29, 0x2b, 0x10, 0x63, 0x13, 0x33, 0x35, 0x2e,
0x0e, 0x02, 0xfe, 0x16, 0x37, 0x33, 0x13, 0x0d, 0x0d, 0x27, 0x2c, 0x28, 0x0e, 0x0a, 0x00, 0x02,
0x00, 0x2a, 0xff, 0xf6, 0x02, 0x11, 0x02, 0x2d, 0x00, 0x1b, 0x00, 0x26, 0x00, 0x00, 0x01, 0x32,
0x16, 0x15, 0x11, 0x23, 0x27, 0x23, 0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, 0x37,
0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x13, 0x06, 0x06, 0x15, 0x14, 0x16,
0x33, 0x32, 0x36, 0x35, 0x35, 0x01, 0x2e, 0x6e, 0x75, 0x68, 0x1d, 0x04, 0x23, 0x4e, 0x44, 0x49,
0x60, 0x7a, 0x7a, 0x5f, 0x2d, 0x28, 0x28, 0x4c, 0x26, 0x31, 0x2c, 0x6b, 0x4f, 0x48, 0x38, 0x28,
0x20, 0x30, 0x42, 0x02, 0x2d, 0x5f, 0x62, 0xfe, 0x94, 0x4a, 0x2c, 0x28, 0x55, 0x58, 0x57, 0x53,
0x04, 0x03, 0x18, 0x2b, 0x28, 0x17, 0x11, 0x65, 0x17, 0x1a, 0xfe, 0xce, 0x02, 0x30, 0x27, 0x22,
0x1d, 0x39, 0x34, 0x2d, 0x00, 0x02, 0x00, 0x4e, 0xff, 0xf6, 0x02, 0x4c, 0x02, 0xf8, 0x00, 0x15,
0x00, 0x22, 0x00, 0x00, 0x13, 0x14, 0x06, 0x07, 0x33, 0x36, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14,
0x06, 0x23, 0x22, 0x26, 0x27, 0x23, 0x07, 0x23, 0x11, 0x33, 0x13, 0x22, 0x06, 0x07, 0x15, 0x14,
0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0xe3, 0x04, 0x02, 0x06, 0x16, 0x4a, 0x3b, 0x5c, 0x72,
0x74, 0x5e, 0x3c, 0x45, 0x16, 0x0a, 0x19, 0x72, 0x95, 0x6b, 0x3a, 0x2f, 0x02, 0x2f, 0x3e, 0x2e,
0x36, 0x37, 0x02, 0x47, 0x1f, 0x3c, 0x11, 0x22, 0x2f, 0x8f, 0x8b, 0x8c, 0x90, 0x2b, 0x1b, 0x3c,
0x02, 0xf8, 0xfe, 0xbd, 0x48, 0x4a, 0x10, 0x4f, 0x55, 0x55, 0x50, 0x50, 0x51, 0x00, 0x01, 0x00,
0x2d, 0xff, 0xf6, 0x01, 0xe3, 0x02, 0x2c, 0x00, 0x19, 0x00, 0x00, 0x05, 0x22, 0x26, 0x35, 0x34,
0x36, 0x36, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x15, 0x14, 0x16, 0x33, 0x32,
0x36, 0x37, 0x15, 0x06, 0x06, 0x01, 0x2c, 0x7a, 0x85, 0x44, 0x79, 0x4f, 0x38, 0x53, 0x1f, 0x2c,
0x23, 0x3d, 0x1e, 0x74, 0x3d, 0x37, 0x2f, 0x48, 0x22, 0x22, 0x4b, 0x0a, 0x87, 0x91, 0x64, 0x7e,
0x3c, 0x16, 0x0f, 0x73, 0x0e, 0x12, 0xa5, 0x52, 0x4e, 0x19, 0x16, 0x7f, 0x16, 0x13, 0x00, 0x02,
0x00, 0x2d, 0xff, 0xf6, 0x02, 0x2b, 0x02, 0xf8, 0x00, 0x15, 0x00, 0x22, 0x00, 0x00, 0x17, 0x22,
0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17, 0x33, 0x26, 0x26, 0x35, 0x35, 0x33, 0x11, 0x23,
0x27, 0x23, 0x06, 0x06, 0x27, 0x32, 0x36, 0x37, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14,
0x16, 0xfb, 0x5b, 0x73, 0x74, 0x5e, 0x3b, 0x4c, 0x16, 0x05, 0x03, 0x08, 0x95, 0x72, 0x1d, 0x06,
0x16, 0x4a, 0x07, 0x3e, 0x32, 0x01, 0x31, 0x42, 0x31, 0x38, 0x38, 0x0a, 0x8f, 0x8b, 0x8c, 0x90,
0x2e, 0x22, 0x10, 0x3d, 0x20, 0xaf, 0xfd, 0x08, 0x47, 0x22, 0x2f, 0x77, 0x49, 0x49, 0x10, 0x50,
0x54, 0x55, 0x50, 0x50, 0x51, 0x00, 0x02, 0x00, 0x2d, 0xff, 0xf6, 0x02, 0x24, 0x02, 0x2c, 0x00,
0x16, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x32, 0x16, 0x15, 0x15, 0x21, 0x16, 0x16, 0x33, 0x32, 0x36,
0x37, 0x15, 0x06, 0x06, 0x23, 0x22, 0x26, 0x26, 0x35, 0x34, 0x36, 0x36, 0x17, 0x22, 0x06, 0x07,
0x33, 0x26, 0x26, 0x01, 0x2f, 0x71, 0x84, 0xfe, 0xa0, 0x02, 0x47, 0x3f, 0x35, 0x56, 0x2e, 0x28,
0x59, 0x3f, 0x52, 0x7e, 0x48, 0x41, 0x74, 0x4e, 0x2b, 0x39, 0x05, 0xd1, 0x01, 0x32, 0x02, 0x2c,
0x81, 0x77, 0x48, 0x3f, 0x48, 0x15, 0x16, 0x73, 0x14, 0x13, 0x3d, 0x7c, 0x5e, 0x60, 0x7f, 0x40,
0x6a, 0x38, 0x3b, 0x32, 0x41, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x01, 0xb0, 0x02, 0xfd, 0x00,
0x18, 0x00, 0x00, 0x01, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, 0x37, 0x35, 0x34, 0x36, 0x36, 0x33,
0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x06, 0x15, 0x15, 0x33, 0x01, 0x7c, 0x81, 0x95,
0x52, 0x52, 0x2f, 0x57, 0x3b, 0x2c, 0x47, 0x16, 0x26, 0x11, 0x28, 0x1a, 0x1f, 0x1d, 0x81, 0x01,
0xb2, 0xfe, 0x4e, 0x01, 0xb2, 0x48, 0x28, 0x28, 0x46, 0x4d, 0x20, 0x0e, 0x09, 0x6d, 0x05, 0x09,
0x26, 0x1d, 0x22, 0x00, 0x02, 0x00, 0x2d, 0xff, 0x10, 0x02, 0x2b, 0x02, 0x2c, 0x00, 0x1e, 0x00,
0x29, 0x00, 0x00, 0x13, 0x32, 0x17, 0x33, 0x37, 0x33, 0x11, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27,
0x35, 0x16, 0x33, 0x32, 0x35, 0x35, 0x34, 0x36, 0x37, 0x23, 0x06, 0x06, 0x23, 0x22, 0x26, 0x35,
0x34, 0x36, 0x17, 0x22, 0x15, 0x14, 0x33, 0x32, 0x36, 0x35, 0x35, 0x34, 0x26, 0xff, 0x65, 0x39,
0x04, 0x0c, 0x7e, 0x8a, 0x87, 0x3a, 0x63, 0x2f, 0x65, 0x70, 0x73, 0x03, 0x01, 0x04, 0x1c, 0x4e,
0x31, 0x61, 0x6d, 0x70, 0x91, 0x69, 0x6b, 0x39, 0x37, 0x36, 0x02, 0x2c, 0x50, 0x46, 0xfd, 0xdd,
0x75, 0x7a, 0x0e, 0x12, 0x77, 0x2a, 0x7c, 0x0b, 0x11, 0x24, 0x0e, 0x2b, 0x26, 0x95, 0x85, 0x86,
0x96, 0x79, 0xa5, 0xa3, 0x41, 0x51, 0x12, 0x58, 0x4c, 0x00, 0x01, 0x00, 0x4e, 0x00, 0x00, 0x02,
0x46, 0x02, 0xf8, 0x00, 0x16, 0x00, 0x00, 0x13, 0x14, 0x06, 0x07, 0x33, 0x36, 0x36, 0x33, 0x32,
0x16, 0x15, 0x11, 0x23, 0x11, 0x34, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0xe3, 0x05,
0x02, 0x08, 0x1a, 0x52, 0x32, 0x59, 0x6b, 0x95, 0x58, 0x43, 0x33, 0x95, 0x95, 0x02, 0x5d, 0x28,
0x4a, 0x0f, 0x2a, 0x26, 0x5f, 0x69, 0xfe, 0x9c, 0x01, 0x3f, 0x76, 0x5d, 0x57, 0xfe, 0xff, 0x02,
0xf8, 0x00, 0x02, 0x00, 0x48, 0x00, 0x00, 0x00, 0xea, 0x02, 0xf8, 0x00, 0x0b, 0x00, 0x0f, 0x00,
0x00, 0x13, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x17, 0x11, 0x23,
0x11, 0x99, 0x21, 0x30, 0x30, 0x21, 0x22, 0x2f, 0x2f, 0x6c, 0x95, 0x02, 0xf8, 0x1f, 0x2a, 0x29,
0x20, 0x20, 0x29, 0x2a, 0x1f, 0xd6, 0xfd, 0xde, 0x02, 0x22, 0x00, 0x02, 0xff, 0xc0, 0xff, 0x10,
0x00, 0xea, 0x02, 0xf8, 0x00, 0x0b, 0x00, 0x1c, 0x00, 0x00, 0x13, 0x34, 0x36, 0x33, 0x32, 0x16,
0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x03, 0x22, 0x26, 0x27, 0x35, 0x16, 0x16, 0x33, 0x32, 0x36,
0x35, 0x11, 0x33, 0x11, 0x14, 0x06, 0x06, 0x48, 0x2f, 0x22, 0x21, 0x30, 0x30, 0x21, 0x22, 0x2f,
0x26, 0x19, 0x37, 0x12, 0x12, 0x20, 0x14, 0x1e, 0x2a, 0x95, 0x26, 0x55, 0x02, 0xaf, 0x2a, 0x1f,
0x1f, 0x2a, 0x29, 0x20, 0x20, 0xfc, 0x8a, 0x07, 0x05, 0x75, 0x04, 0x05, 0x22, 0x31, 0x02, 0x47,
0xfd, 0xa3, 0x32, 0x52, 0x31, 0x00, 0x01, 0x00, 0x4e, 0x00, 0x00, 0x02, 0x6c, 0x02, 0xf8, 0x00,
0x12, 0x00, 0x00, 0x13, 0x14, 0x06, 0x07, 0x33, 0x36, 0x36, 0x37, 0x37, 0x33, 0x07, 0x13, 0x23,
0x27, 0x07, 0x15, 0x23, 0x11, 0x33, 0xe3, 0x05, 0x03, 0x02, 0x0f, 0x20, 0x12, 0x99, 0xa8, 0xd9,
0xe6, 0xac, 0x9d, 0x40, 0x95, 0x95, 0x01, 0xa4, 0x1f, 0x3d, 0x1f, 0x15, 0x2b, 0x13, 0xa6, 0xed,
0xfe, 0xcb, 0xdd, 0x33, 0xaa, 0x02, 0xf8, 0x00, 0x01, 0x00, 0x4e, 0x00, 0x00, 0x00, 0xe3, 0x02,
0xf8, 0x00, 0x03, 0x00, 0x00, 0x33, 0x23, 0x11, 0x33, 0xe3, 0x95, 0x95, 0x02, 0xf8, 0x00, 0x01,
0x00, 0x4e, 0x00, 0x00, 0x03, 0x8b, 0x02, 0x2c, 0x00, 0x22, 0x00, 0x00, 0x01, 0x32, 0x16, 0x15,
0x11, 0x23, 0x11, 0x34, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x34, 0x23, 0x22, 0x06, 0x15,
0x11, 0x23, 0x11, 0x33, 0x17, 0x33, 0x36, 0x36, 0x33, 0x32, 0x16, 0x17, 0x33, 0x36, 0x36, 0x02,
0xcf, 0x5d, 0x5f, 0x95, 0x52, 0x3b, 0x32, 0x95, 0x52, 0x3e, 0x2f, 0x95, 0x72, 0x14, 0x08, 0x19,
0x57, 0x2f, 0x3c, 0x54, 0x16, 0x0d, 0x19, 0x59, 0x02, 0x2c, 0x5f, 0x69, 0xfe, 0x9c, 0x01, 0x3f,
0x76, 0x54, 0x4f, 0xfe, 0xee, 0x01, 0x3f, 0x76, 0x5d, 0x57, 0xfe, 0xff, 0x02, 0x22, 0x46, 0x2a,
0x26, 0x27, 0x29, 0x2a, 0x26, 0x00, 0x01, 0x00, 0x4e, 0x00, 0x00, 0x02, 0x46, 0x02, 0x2c, 0x00,
0x14, 0x00, 0x00, 0x01, 0x32, 0x16, 0x15, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15,
0x11, 0x23, 0x11, 0x33, 0x17, 0x33, 0x36, 0x36, 0x01, 0x84, 0x58, 0x6a, 0x95, 0x2a, 0x2e, 0x44,
0x32, 0x95, 0x72, 0x14, 0x08, 0x1a, 0x5b, 0x02, 0x2c, 0x5f, 0x69, 0xfe, 0x9c, 0x01, 0x3f, 0x3b,
0x3b, 0x5d, 0x57, 0xfe, 0xff, 0x02, 0x22, 0x46, 0x2a, 0x26, 0x00, 0x02, 0x00, 0x2d, 0xff, 0xf6,
0x02, 0x3e, 0x02, 0x2c, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x00, 0x01, 0x14, 0x06, 0x23, 0x22, 0x26,
0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x16, 0x05, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34,
0x26, 0x23, 0x22, 0x06, 0x02, 0x3e, 0x8f, 0x7b, 0x4c, 0x77, 0x44, 0x8e, 0x7c, 0x4d, 0x76, 0x44,
0xfe, 0x87, 0x35, 0x3c, 0x3b, 0x35, 0x35, 0x3c, 0x3b, 0x35, 0x01, 0x12, 0x88, 0x94, 0x42, 0x7f,
0x5b, 0x88, 0x92, 0x42, 0x7d, 0x5b, 0x51, 0x53, 0x53, 0x51, 0x51, 0x51, 0x51, 0x00, 0x02, 0x00,
0x4e, 0xff, 0x10, 0x02, 0x4c, 0x02, 0x2c, 0x00, 0x14, 0x00, 0x20, 0x00, 0x00, 0x01, 0x32, 0x16,
0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x23, 0x16, 0x15, 0x15, 0x23, 0x11, 0x33, 0x17, 0x33,
0x36, 0x36, 0x17, 0x22, 0x06, 0x07, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x01, 0x7e,
0x5c, 0x72, 0x76, 0x5c, 0x3b, 0x46, 0x16, 0x08, 0x08, 0x95, 0x79, 0x15, 0x07, 0x16, 0x4a, 0x0b,
0x3a, 0x2f, 0x02, 0x2f, 0x3e, 0x33, 0x31, 0x02, 0x2c, 0x8f, 0x8b, 0x8b, 0x91, 0x2b, 0x1b, 0x2a,
0x26, 0xdc, 0x03, 0x12, 0x47, 0x21, 0x30, 0x77, 0x48, 0x4a, 0x10, 0x4f, 0x55, 0x55, 0x50, 0xa1,
0x00, 0x02, 0x00, 0x2d, 0xff, 0x10, 0x02, 0x2b, 0x02, 0x2c, 0x00, 0x14, 0x00, 0x20, 0x00, 0x00,
0x05, 0x34, 0x37, 0x23, 0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17,
0x33, 0x37, 0x33, 0x11, 0x23, 0x03, 0x32, 0x36, 0x37, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15,
0x14, 0x01, 0x96, 0x06, 0x06, 0x15, 0x4a, 0x3c, 0x5c, 0x72, 0x74, 0x5d, 0x3c, 0x4b, 0x17, 0x04,
0x0d, 0x7e, 0x95, 0x66, 0x3e, 0x31, 0x01, 0x31, 0x41, 0x35, 0x34, 0x0b, 0x2a, 0x28, 0x22, 0x2f,
0x8f, 0x8b, 0x8c, 0x90, 0x2e, 0x22, 0x46, 0xfc, 0xee, 0x01, 0x5b, 0x49, 0x49, 0x12, 0x50, 0x54,
0x55, 0x50, 0xa3, 0x00, 0x01, 0x00, 0x4e, 0x00, 0x00, 0x01, 0xb1, 0x02, 0x2c, 0x00, 0x13, 0x00,
0x00, 0x01, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x06, 0x06, 0x15, 0x11, 0x23, 0x11,
0x33, 0x17, 0x33, 0x36, 0x36, 0x01, 0x7f, 0x0b, 0x1e, 0x09, 0x0b, 0x07, 0x1b, 0x0a, 0x26, 0x46,
0x2b, 0x95, 0x71, 0x16, 0x07, 0x18, 0x54, 0x02, 0x2c, 0x02, 0x02, 0x8c, 0x02, 0x03, 0x1b, 0x3c,
0x34, 0xfe, 0xea, 0x02, 0x22, 0x5c, 0x2a, 0x3c, 0x00, 0x01, 0x00, 0x2d, 0xff, 0xf6, 0x01, 0xcb,
0x02, 0x2c, 0x00, 0x28, 0x00, 0x00, 0x25, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x16, 0x16,
0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x26, 0x27, 0x2e, 0x02, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16,
0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x15, 0x14, 0x16, 0x16, 0x17, 0x1e, 0x02, 0x01, 0xcb, 0x75,
0x74, 0x39, 0x52, 0x29, 0x2c, 0x66, 0x27, 0x2c, 0x25, 0x0f, 0x32, 0x35, 0x33, 0x42, 0x20, 0x76,
0x62, 0x33, 0x5c, 0x31, 0x2d, 0x28, 0x48, 0x25, 0x42, 0x11, 0x31, 0x30, 0x2f, 0x44, 0x25, 0xa2,
0x53, 0x59, 0x0f, 0x11, 0x7b, 0x14, 0x1a, 0x1a, 0x15, 0x0e, 0x16, 0x1c, 0x16, 0x16, 0x2b, 0x3d,
0x2e, 0x4c, 0x4c, 0x14, 0x17, 0x6b, 0x11, 0x17, 0x24, 0x0d, 0x15, 0x18, 0x14, 0x13, 0x29, 0x3d,
0x00, 0x01, 0x00, 0x17, 0xff, 0xf6, 0x01, 0x92, 0x02, 0x96, 0x00, 0x18, 0x00, 0x00, 0x25, 0x32,
0x36, 0x37, 0x15, 0x06, 0x06, 0x23, 0x22, 0x26, 0x26, 0x35, 0x11, 0x23, 0x35, 0x37, 0x37, 0x33,
0x15, 0x33, 0x15, 0x23, 0x11, 0x14, 0x16, 0x01, 0x34, 0x19, 0x2e, 0x17, 0x18, 0x47, 0x2a, 0x31,
0x4d, 0x2d, 0x47, 0x52, 0x2b, 0x5f, 0x99, 0x99, 0x24, 0x6d, 0x0a, 0x07, 0x6f, 0x0a, 0x0f, 0x20,
0x4f, 0x46, 0x01, 0x07, 0x3f, 0x32, 0x73, 0x74, 0x70, 0xfe, 0xf9, 0x1f, 0x1f, 0x00, 0x01, 0x00,
0x4b, 0xff, 0xf6, 0x02, 0x43, 0x02, 0x22, 0x00, 0x14, 0x00, 0x00, 0x01, 0x11, 0x23, 0x27, 0x23,
0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11,
0x02, 0x43, 0x72, 0x14, 0x08, 0x1a, 0x5b, 0x33, 0x58, 0x6a, 0x95, 0x2a, 0x2e, 0x44, 0x32, 0x02,
0x22, 0xfd, 0xde, 0x46, 0x2a, 0x26, 0x5f, 0x69, 0x01, 0x64, 0xfe, 0xc1, 0x3a, 0x3c, 0x5d, 0x57,
0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x02, 0x22, 0x00, 0x0c, 0x00, 0x00,
0x33, 0x03, 0x33, 0x13, 0x16, 0x16, 0x17, 0x33, 0x36, 0x37, 0x13, 0x33, 0x03, 0xd0, 0xd0, 0x9c,
0x69, 0x09, 0x0b, 0x01, 0x04, 0x03, 0x13, 0x69, 0x9c, 0xd0, 0x02, 0x22, 0xfe, 0xc9, 0x1c, 0x3c,
0x18, 0x36, 0x3a, 0x01, 0x37, 0xfd, 0xde, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x03, 0x4e, 0x02,
0x22, 0x00, 0x2a, 0x00, 0x00, 0x25, 0x2e, 0x03, 0x27, 0x23, 0x0e, 0x03, 0x07, 0x07, 0x23, 0x03,
0x33, 0x17, 0x1e, 0x02, 0x17, 0x33, 0x3e, 0x03, 0x37, 0x13, 0x33, 0x13, 0x1e, 0x02, 0x15, 0x33,
0x3e, 0x02, 0x37, 0x37, 0x33, 0x03, 0x23, 0x01, 0xe5, 0x04, 0x0f, 0x12, 0x10, 0x03, 0x04, 0x03,
0x0f, 0x12, 0x10, 0x04, 0x2c, 0xa0, 0x9b, 0x94, 0x3f, 0x07, 0x0b, 0x0a, 0x02, 0x04, 0x01, 0x06,
0x09, 0x07, 0x02, 0x43, 0xa4, 0x40, 0x04, 0x0b, 0x09, 0x04, 0x02, 0x0a, 0x0d, 0x07, 0x41, 0x92,
0x9d, 0xa2, 0xbf, 0x11, 0x43, 0x4d, 0x41, 0x0f, 0x0f, 0x41, 0x4d, 0x44, 0x12, 0xbd, 0x02, 0x22,
0xf2, 0x19, 0x46, 0x41, 0x13, 0x0e, 0x2f, 0x32, 0x29, 0x07, 0x01, 0x06, 0xfe, 0xfa, 0x0e, 0x3e,
0x40, 0x13, 0x11, 0x41, 0x48, 0x19, 0xf2, 0xfd, 0xde, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x02,
0x3d, 0x02, 0x22, 0x00, 0x0b, 0x00, 0x00, 0x13, 0x03, 0x33, 0x17, 0x37, 0x33, 0x03, 0x13, 0x23,
0x27, 0x07, 0x23, 0xbe, 0xb0, 0xa9, 0x6a, 0x6b, 0xa9, 0xb2, 0xba, 0xa9, 0x73, 0x73, 0xa9, 0x01,
0x17, 0x01, 0x0b, 0xae, 0xae, 0xfe, 0xf5, 0xfe, 0xe9, 0xbb, 0xbb, 0x00, 0x01, 0x00, 0x00, 0xff,
0x10, 0x02, 0x39, 0x02, 0x22, 0x00, 0x1a, 0x00, 0x00, 0x11, 0x33, 0x13, 0x16, 0x16, 0x17, 0x33,
0x36, 0x36, 0x37, 0x13, 0x33, 0x03, 0x06, 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x16, 0x16, 0x33,
0x32, 0x36, 0x37, 0x37, 0xa3, 0x67, 0x08, 0x08, 0x02, 0x03, 0x03, 0x0b, 0x07, 0x65, 0xa0, 0xe7,
0x1f, 0x77, 0x4e, 0x19, 0x25, 0x0e, 0x0b, 0x1f, 0x11, 0x2f, 0x37, 0x0d, 0x09, 0x02, 0x22, 0xfe,
0xcd, 0x16, 0x2f, 0x1a, 0x1a, 0x2f, 0x16, 0x01, 0x33, 0xfd, 0x98, 0x55, 0x55, 0x05, 0x03, 0x76,
0x02, 0x04, 0x39, 0x28, 0x1b, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x01, 0xca, 0x02, 0x22, 0x00,
0x09, 0x00, 0x00, 0x21, 0x21, 0x35, 0x13, 0x23, 0x35, 0x21, 0x15, 0x03, 0x33, 0x01, 0xca, 0xfe,
0x51, 0xfd, 0xee, 0x01, 0x97, 0xf6, 0xff, 0x58, 0x01, 0x58, 0x72, 0x61, 0xfe, 0xb1, 0x00, 0x01,
0x00, 0x0f, 0xff, 0x62, 0x01, 0x62, 0x02, 0xca, 0x00, 0x1f, 0x00, 0x00, 0x05, 0x22, 0x26, 0x26,
0x35, 0x35, 0x34, 0x26, 0x23, 0x35, 0x32, 0x36, 0x35, 0x35, 0x34, 0x36, 0x36, 0x33, 0x15, 0x06,
0x06, 0x15, 0x15, 0x14, 0x07, 0x15, 0x16, 0x15, 0x15, 0x14, 0x16, 0x17, 0x01, 0x62, 0x55, 0x5d,
0x24, 0x40, 0x3d, 0x3d, 0x40, 0x24, 0x5d, 0x55, 0x27, 0x2e, 0x72, 0x72, 0x2e, 0x27, 0x9e, 0x1c,
0x3c, 0x30, 0x9a, 0x2f, 0x28, 0x75, 0x28, 0x2f, 0x9b, 0x30, 0x3c, 0x1c, 0x6e, 0x01, 0x1a, 0x2a,
0x92, 0x5b, 0x11, 0x06, 0x11, 0x5b, 0x92, 0x2a, 0x1a, 0x01, 0x00, 0x01, 0x00, 0xde, 0xff, 0x1d,
0x01, 0x49, 0x02, 0xf5, 0x00, 0x03, 0x00, 0x00, 0x13, 0x33, 0x11, 0x23, 0xde, 0x6b, 0x6b, 0x02,
0xf5, 0xfc, 0x28, 0x00, 0x01, 0x00, 0x28, 0xff, 0x62, 0x01, 0x7b, 0x02, 0xca, 0x00, 0x1f, 0x00,
0x00, 0x17, 0x36, 0x36, 0x35, 0x35, 0x34, 0x37, 0x35, 0x26, 0x35, 0x35, 0x34, 0x26, 0x27, 0x35,
0x32, 0x16, 0x16, 0x15, 0x15, 0x14, 0x16, 0x33, 0x15, 0x22, 0x06, 0x15, 0x15, 0x14, 0x06, 0x06,
0x23, 0x28, 0x27, 0x2e, 0x72, 0x72, 0x2e, 0x27, 0x56, 0x5c, 0x24, 0x40, 0x3d, 0x3d, 0x40, 0x24,
0x5c, 0x56, 0x30, 0x01, 0x1a, 0x2a, 0x92, 0x5b, 0x11, 0x06, 0x11, 0x5b, 0x92, 0x2a, 0x1a, 0x01,
0x6e, 0x1c, 0x3c, 0x30, 0x9b, 0x2f, 0x28, 0x75, 0x28, 0x2f, 0x9a, 0x30, 0x3c, 0x1c, 0x00, 0x01,
0x00, 0x2b, 0x01, 0x0d, 0x02, 0x10, 0x01, 0xb4, 0x00, 0x17, 0x00, 0x00, 0x01, 0x26, 0x26, 0x23,
0x22, 0x06, 0x07, 0x35, 0x36, 0x33, 0x32, 0x16, 0x17, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15,
0x06, 0x23, 0x22, 0x26, 0x01, 0x0c, 0x25, 0x33, 0x17, 0x1c, 0x3d, 0x19, 0x32, 0x4b, 0x1d, 0x3b,
0x2f, 0x25, 0x34, 0x16, 0x1d, 0x3c, 0x19, 0x32, 0x4b, 0x1d, 0x3b, 0x01, 0x2d, 0x10, 0x0b, 0x22,
0x19, 0x71, 0x35, 0x0b, 0x14, 0x10, 0x0b, 0x22, 0x19, 0x71, 0x35, 0x0c, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf3, 0x66, 0xcb, 0x35, 0x5f, 0x0f, 0x3c, 0xf5, 0x00, 0x03, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0xdf, 0x93, 0x35, 0xf6, 0x00, 0x00, 0x00, 0x00, 0xdf, 0x93, 0x35, 0xf6,
0xfd, 0x68, 0xfe, 0x76, 0x0a, 0xf0, 0x05, 0x43, 0x00, 0x01, 0x00, 0x06, 0x00, 0x02, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd6,
0xff, 0xb6, 0xff, 0xd3, 0x03, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x02, 0x58, 0x00, 0x00, 0x01, 0x1e, 0x00, 0x39,
0x01, 0xd8, 0x00, 0x41, 0x02, 0x86, 0x00, 0x16, 0x02, 0x3c, 0x00, 0x2b, 0x03, 0x85, 0x00, 0x1f,
0x02, 0xee, 0x00, 0x28, 0x01, 0x0a, 0x00, 0x41, 0x01, 0x53, 0x00, 0x28, 0x01, 0x53, 0x00, 0x1e,
0x02, 0x21, 0x00, 0x1f, 0x02, 0x3c, 0x00, 0x2b, 0x01, 0x1d, 0x00, 0x1f, 0x01, 0x42, 0x00, 0x1e,
0x01, 0x1d, 0x00, 0x39, 0x01, 0x9d, 0x00, 0x07, 0x02, 0x3c, 0x00, 0x24, 0x02, 0x3c, 0x00, 0x3b,
0x02, 0x3c, 0x00, 0x26, 0x02, 0x3c, 0x00, 0x26, 0x02, 0x3c, 0x00, 0x11, 0x02, 0x3c, 0x00, 0x31,
0x02, 0x3c, 0x00, 0x23, 0x02, 0x3c, 0x00, 0x1b, 0x02, 0x3c, 0x00, 0x23, 0x02, 0x3c, 0x00, 0x20,
0x01, 0x1d, 0x00, 0x39, 0x01, 0x1d, 0x00, 0x1f, 0x02, 0x3c, 0x00, 0x2b, 0x02, 0x3c, 0x00, 0x2b,
0x02, 0x3c, 0x00, 0x2b, 0x01, 0xdd, 0x00, 0x03, 0x03, 0x81, 0x00, 0x32, 0x02, 0xb2, 0x00, 0x00,
0x02, 0xa0, 0x00, 0x5a, 0x02, 0x7d, 0x00, 0x3a, 0x02, 0xe4, 0x00, 0x5a, 0x02, 0x30, 0x00, 0x5a,
0x02, 0x25, 0x00, 0x5a, 0x02, 0xd4, 0x00, 0x3a, 0x02, 0xfd, 0x00, 0x5a, 0x01, 0x85, 0x00, 0x20,
0x01, 0x4b, 0xff, 0xb6, 0x02, 0x98, 0x00, 0x5a, 0x02, 0x35, 0x00, 0x5a, 0x03, 0xaf, 0x00, 0x5a,
0x03, 0x2d, 0x00, 0x5a, 0x03, 0x1c, 0x00, 0x3a, 0x02, 0x74, 0x00, 0x5a, 0x03, 0x1c, 0x00, 0x3a,
0x02, 0x94, 0x00, 0x5a, 0x02, 0x27, 0x00, 0x2e, 0x02, 0x43, 0x00, 0x14, 0x02, 0xf4, 0x00, 0x55,
0x02, 0x8a, 0x00, 0x00, 0x03, 0xc7, 0x00, 0x00, 0x02, 0x9b, 0x00, 0x00, 0x02, 0x70, 0x00, 0x00,
0x02, 0x43, 0x00, 0x18, 0x01, 0x4b, 0x00, 0x46, 0x01, 0x9d, 0x00, 0x06, 0x01, 0x4b, 0x00, 0x19,
0x02, 0x3c, 0x00, 0x17, 0x01, 0x9b, 0xff, 0xfe, 0x01, 0x6a, 0x00, 0x28, 0x02, 0x5c, 0x00, 0x2a,
0x02, 0x79, 0x00, 0x4e, 0x02, 0x02, 0x00, 0x2d, 0x02, 0x79, 0x00, 0x2d, 0x02, 0x4f, 0x00, 0x2d,
0x01, 0x83, 0x00, 0x14, 0x02, 0x79, 0x00, 0x2d, 0x02, 0x91, 0x00, 0x4e, 0x01, 0x31, 0x00, 0x48,
0x01, 0x31, 0xff, 0xc0, 0x02, 0x6c, 0x00, 0x4e, 0x01, 0x31, 0x00, 0x4e, 0x03, 0xd6, 0x00, 0x4e,
0x02, 0x91, 0x00, 0x4e, 0x02, 0x6b, 0x00, 0x2d, 0x02, 0x79, 0x00, 0x4e, 0x02, 0x79, 0x00, 0x2d,
0x01, 0xc6, 0x00, 0x4e, 0x01, 0xf1, 0x00, 0x2d, 0x01, 0xb2, 0x00, 0x17, 0x02, 0x91, 0x00, 0x4b,
0x02, 0x39, 0x00, 0x00, 0x03, 0x58, 0x00, 0x0a, 0x02, 0x42, 0x00, 0x05, 0x02, 0x39, 0x00, 0x00,
0x01, 0xe8, 0x00, 0x1b, 0x01, 0x8a, 0x00, 0x0f, 0x02, 0x27, 0x00, 0xde, 0x01, 0x8a, 0x00, 0x28,
0x02, 0x3c, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x71,
0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x01, 0x8a, 0x00, 0x00, 0x02, 0x0f,
0x00, 0x00, 0x02, 0xb8, 0x00, 0x00, 0x02, 0xd4, 0x00, 0x00, 0x03, 0x08, 0x00, 0x00, 0x03, 0x3d,
0x00, 0x00, 0x03, 0x7a, 0x00, 0x00, 0x03, 0xa3, 0x00, 0x00, 0x03, 0xca, 0x00, 0x00, 0x03, 0xe2,
0x00, 0x00, 0x04, 0x0d, 0x00, 0x00, 0x04, 0x2c, 0x00, 0x00, 0x04, 0x7f, 0x00, 0x00, 0x04, 0xb1,
0x00, 0x00, 0x05, 0x0d, 0x00, 0x00, 0x05, 0x8b, 0x00, 0x00, 0x05, 0xd6, 0x00, 0x00, 0x06, 0x36,
0x00, 0x00, 0x06, 0xb9, 0x00, 0x00, 0x06, 0xdd, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x08, 0x02,
0x00, 0x00, 0x08, 0x4d, 0x00, 0x00, 0x08, 0x95, 0x00, 0x00, 0x08, 0xbb, 0x00, 0x00, 0x08, 0xe1,
0x00, 0x00, 0x09, 0x06, 0x00, 0x00, 0x09, 0x81, 0x00, 0x00, 0x0a, 0x59, 0x00, 0x00, 0x0a, 0xa1,
0x00, 0x00, 0x0b, 0x09, 0x00, 0x00, 0x0b, 0x61, 0x00, 0x00, 0x0b, 0x9f, 0x00, 0x00, 0x0b, 0xcb,
0x00, 0x00, 0x0b, 0xf0, 0x00, 0x00, 0x0c, 0x55, 0x00, 0x00, 0x0c, 0x83, 0x00, 0x00, 0x0c, 0xb2,
0x00, 0x00, 0x0c, 0xef, 0x00, 0x00, 0x0d, 0x27, 0x00, 0x00, 0x0d, 0x44, 0x00, 0x00, 0x0d, 0x94,
0x00, 0x00, 0x0d, 0xd6, 0x00, 0x00, 0x0e, 0x2f, 0x00, 0x00, 0x0e, 0x70, 0x00, 0x00, 0x0e, 0xd1,
0x00, 0x00, 0x0f, 0x21, 0x00, 0x00, 0x0f, 0x98, 0x00, 0x00, 0x0f, 0xb9, 0x00, 0x00, 0x0f, 0xf7,
0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x10, 0xb5, 0x00, 0x00, 0x10, 0xea, 0x00, 0x00, 0x11, 0x15,
0x00, 0x00, 0x11, 0x42, 0x00, 0x00, 0x11, 0x64, 0x00, 0x00, 0x11, 0x82, 0x00, 0x00, 0x11, 0xa3,
0x00, 0x00, 0x11, 0xc8, 0x00, 0x00, 0x11, 0xe2, 0x00, 0x00, 0x12, 0x12, 0x00, 0x00, 0x12, 0x88,
0x00, 0x00, 0x12, 0xf1, 0x00, 0x00, 0x13, 0x42, 0x00, 0x00, 0x13, 0xa9, 0x00, 0x00, 0x14, 0x09,
0x00, 0x00, 0x14, 0x57, 0x00, 0x00, 0x14, 0xcd, 0x00, 0x00, 0x15, 0x15, 0x00, 0x00, 0x15, 0x4e,
0x00, 0x00, 0x15, 0xa9, 0x00, 0x00, 0x15, 0xeb, 0x00, 0x00, 0x16, 0x02, 0x00, 0x00, 0x16, 0x69,
0x00, 0x00, 0x16, 0xae, 0x00, 0x00, 0x17, 0x01, 0x00, 0x00, 0x17, 0x64, 0x00, 0x00, 0x17, 0xc7,
0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x18, 0x84, 0x00, 0x00, 0x18, 0xd1, 0x00, 0x00, 0x19, 0x16,
0x00, 0x00, 0x19, 0x4b, 0x00, 0x00, 0x19, 0xcd, 0x00, 0x00, 0x19, 0xff, 0x00, 0x00, 0x1a, 0x59,
0x00, 0x00, 0x1a, 0x82, 0x00, 0x00, 0x1a, 0xde, 0x00, 0x00, 0x1a, 0xf7, 0x00, 0x00, 0x1b, 0x52,
0x00, 0x00, 0x1b, 0xa0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x10, 0x00, 0x04, 0x00, 0x00, 0xff,
0x00, 0xff, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x96, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04,
0x00, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x11, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x2f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x05, 0x00, 0x03, 0x00, 0x3c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0d,
0x00, 0x3f, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x1a, 0x00, 0x4c, 0x00, 0x03,
0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x08, 0x00, 0x66, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
0x00, 0x03, 0x00, 0x3c, 0x00, 0x6e, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x04, 0x00, 0x1a,
0x00, 0xaa, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x05, 0x00, 0x06, 0x00, 0xc4, 0x00, 0x03,
0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x1a, 0x00, 0xca, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61,
0x74, 0x65, 0x64, 0x46, 0x6f, 0x6e, 0x74, 0x42, 0x6f, 0x6c, 0x64, 0x47, 0x65, 0x6e, 0x65, 0x72,
0x61, 0x74, 0x65, 0x64, 0x46, 0x6f, 0x6e, 0x74, 0x20, 0x42, 0x6f, 0x6c, 0x64, 0x3a, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
0x65, 0x64, 0x46, 0x6f, 0x6e, 0x74, 0x31, 0x2e, 0x30, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
0x65, 0x64, 0x46, 0x6f, 0x6e, 0x74, 0x00, 0x47, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72,
0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74,
0x00, 0x42, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x64, 0x00, 0x47, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65,
0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e,
0x00, 0x74, 0x00, 0x20, 0x00, 0x42, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x64, 0x00, 0x3a, 0x00, 0x56,
0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x31,
0x00, 0x2e, 0x00, 0x30, 0x00, 0x47, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61,
0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x31,
0x00, 0x2e, 0x00, 0x30, 0x00, 0x47, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61,
0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x00,
0x00, 0x03, 0x02, 0x68, 0x02, 0xbc, 0x00, 0x05, 0x00, 0x08, 0x02, 0x8a, 0x02, 0x58, 0x00, 0x00,
0x00, 0x4b, 0x02, 0x8a, 0x02, 0x58, 0x00, 0x00, 0x01, 0x5e, 0x00, 0x32, 0x01, 0x48, 0x00, 0x00,
0x02, 0x0b, 0x08, 0x02, 0x04, 0x05, 0x04, 0x02, 0x02, 0x04, 0xe0, 0x00, 0x82, 0xff, 0x40, 0x00,
0x20, 0x5f, 0x08, 0x00, 0x00, 0x29, 0x00, 0x10, 0x00, 0x00, 0x47, 0x4f, 0x4f, 0x47, 0x00, 0xa0,
0x00, 0x00, 0xff, 0xfd, 0x04, 0x2d, 0xfe, 0xdb, 0x00, 0x00, 0x05, 0x43, 0x01, 0x8b, 0x00, 0x00,
0x01, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x22, 0x02, 0xca, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04,
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb8, 0x01, 0xff, 0x85, 0xb0, 0x04, 0x8d, 0x00
};

View File

@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Example OpenOCD configuration file for ESP32-WROVER-KIT board.
#
# For example, OpenOCD can be started for ESP32 debugging on
#
# openocd -f board/esp32-wrover-kit-3.3v.cfg
#
# Source the JTAG interface configuration file
source [find interface/ftdi/esp32_devkitj_v1.cfg]
set ESP32_FLASH_VOLTAGE 3.3
# Source the ESP32 configuration file
source [find target/esp32.cfg]

View File

@ -0,0 +1,19 @@
{
"name":"Arduino on ESP32",
"toolchainPrefix":"xtensa-esp32-elf",
"svdFile":"esp32.svd",
"request":"attach",
"postAttachCommands":[
"set remote hardware-watchpoint-limit 2",
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
],
"overrideRestartCommands":[
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
]
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,84 @@
// Example for drawArc function. This is intended for arc based meters.
// (See arcMeter example)
// Draws arcs without smooth ends, suitable for dynamically changing arc
// angles to avoid residual anti-alias pixels at the arc segment joints.
// The sides of the arc can optionally be smooth or not. Smooth arcs have
// a much better appearance, especially at small sizes.
// Start angle for drawArc must be smaller than end angle
#include <TFT_eSPI.h> // Include the graphics library
TFT_eSPI tft = TFT_eSPI(); // Create object "tft"
// -------------------------------------------------------------------------
// Setup
// -------------------------------------------------------------------------
void setup(void) {
Serial.begin(115200);
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
}
// -------------------------------------------------------------------------
// Main loop
// -------------------------------------------------------------------------
void loop()
{
static uint32_t count = 0;
uint16_t fg_color = random(0x10000);
uint16_t bg_color = TFT_BLACK; // This is the background colour used for smoothing (anti-aliasing)
uint16_t x = random(tft.width()); // Position of centre of arc
uint16_t y = random(tft.height());
uint8_t radius = random(20, tft.width() / 4); // Outer arc radius
uint8_t thickness = random(1, radius / 4); // Thickness
uint8_t inner_radius = radius - thickness; // Calculate inner radius (can be 0 for circle segment)
// 0 degrees is at 6 o'clock position
// Arcs are drawn clockwise from start_angle to end_angle
// Start angle for drawArc must be smaller than end angle (function will swap them otherwise)
uint16_t start_angle = random(361); // Start angle must be in range 0 to 360
uint16_t end_angle = random(361); // End angle must be in range 0 to 360
bool smooth = random(2); // true = smooth sides, false = no smooth sides
tft.drawArc(x, y, radius, inner_radius, start_angle, end_angle, fg_color, bg_color, smooth);
//tft.drawArc(x, y, radius, inner_radius, start_angle, end_angle, fg_color, bg_color); // always smooth sides if parameter is missing
// The following function allows arcs to be drawn through the 6 o'clock position by drawing in 2 segments if
// the start angle is greater than the end angle
//drawAnyArc(x, y, radius, inner_radius, start_angle, end_angle, fg_color, bg_color, smooth); // smooth sides if parameter is missing
count++;
if (count < 30) delay(500); // After 15s draw as fast as possible!
}
// The following function allows arcs to be drawn through the 0 degree position by drawing in 2 segments
// Function prototype with default smooth setting
void drawAnyArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle,
uint32_t fg_color, uint32_t bg_color, bool smooth = true);
void drawAnyArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle,
uint32_t fg_color, uint32_t bg_color, bool smooth)
{
if (endAngle > startAngle)
{
// Draw arc in single sweep
tft.drawArc(x, y, r, ir, startAngle, endAngle, fg_color, bg_color);
}
else
{
// Arc sweeps through 6 o'clock so draw in two parts
tft.drawArc(x, y, r, ir, startAngle, 360, fg_color, bg_color);
tft.drawArc(x, y, r, ir, 0, endAngle, fg_color, bg_color);
}
}

View File

@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Example OpenOCD configuration file for ESP32-WROVER-KIT board.
#
# For example, OpenOCD can be started for ESP32 debugging on
#
# openocd -f board/esp32-wrover-kit-3.3v.cfg
#
# Source the JTAG interface configuration file
source [find interface/ftdi/esp32_devkitj_v1.cfg]
set ESP32_FLASH_VOLTAGE 3.3
# Source the ESP32 configuration file
source [find target/esp32.cfg]

View File

@ -0,0 +1,19 @@
{
"name":"Arduino on ESP32",
"toolchainPrefix":"xtensa-esp32-elf",
"svdFile":"esp32.svd",
"request":"attach",
"postAttachCommands":[
"set remote hardware-watchpoint-limit 2",
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
],
"overrideRestartCommands":[
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
]
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
// Example for drawSmoothArc function.
// Draws smooth arcs with rounded or square smooth ends
#include <TFT_eSPI.h> // Include the graphics library
TFT_eSPI tft = TFT_eSPI(); // Create object "tft"
// -------------------------------------------------------------------------
// Setup
// -------------------------------------------------------------------------
void setup(void) {
Serial.begin(115200);
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
}
// -------------------------------------------------------------------------
// Main loop
// -------------------------------------------------------------------------
void loop()
{
static uint32_t count = 0;
uint16_t fg_color = random(0x10000);
uint16_t bg_color = TFT_BLACK; // This is the background colour used for smoothing (anti-aliasing)
uint16_t x = random(tft.width()); // Position of centre of arc
uint16_t y = random(tft.height());
uint8_t radius = random(20, tft.width()/4); // Outer arc radius
uint8_t thickness = random(1, radius / 4); // Thickness
uint8_t inner_radius = radius - thickness; // Calculate inner radius (can be 0 for circle segment)
// 0 degrees is at 6 o'clock position
// Arcs are drawn clockwise from start_angle to end_angle
uint16_t start_angle = random(361); // Start angle must be in range 0 to 360
uint16_t end_angle = random(361); // End angle must be in range 0 to 360
bool arc_end = random(2); // true = round ends, false = square ends (arc_end parameter can be omitted, ends will then be square)
tft.drawSmoothArc(x, y, radius, inner_radius, start_angle, end_angle, fg_color, bg_color, arc_end);
count++;
if (count < 30) delay(500); // After 15s draw as fast as possible!
}

View File

@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Example OpenOCD configuration file for ESP32-WROVER-KIT board.
#
# For example, OpenOCD can be started for ESP32 debugging on
#
# openocd -f board/esp32-wrover-kit-3.3v.cfg
#
# Source the JTAG interface configuration file
source [find interface/ftdi/esp32_devkitj_v1.cfg]
set ESP32_FLASH_VOLTAGE 3.3
# Source the ESP32 configuration file
source [find target/esp32.cfg]

View File

@ -0,0 +1,19 @@
{
"name":"Arduino on ESP32",
"toolchainPrefix":"xtensa-esp32-elf",
"svdFile":"esp32.svd",
"request":"attach",
"postAttachCommands":[
"set remote hardware-watchpoint-limit 2",
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
],
"overrideRestartCommands":[
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
]
}

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@
TFT_eSPI tft = TFT_eSPI(); // Invoke library TFT_eSPI tft = TFT_eSPI(); // Invoke library
#ifdef ESP8266 #ifdef ARDUINO_ARCH_ESP8266
ADC_MODE(ADC_VCC); // Read the supply voltage ADC_MODE(ADC_VCC); // Read the supply voltage
#endif #endif
@ -45,15 +45,15 @@ Serial.print("\n[code]\n");
Serial.print ("TFT_eSPI ver = "); Serial.println(user.version); Serial.print ("TFT_eSPI ver = "); Serial.println(user.version);
printProcessorName(); printProcessorName();
#if defined (ESP32) || defined (ESP8266) #if defined (ESP32) || defined (ARDUINO_ARCH_ESP8266)
if (user.esp < 0x32F000 || user.esp > 0x32FFFF) { Serial.print("Frequency = "); Serial.print(ESP.getCpuFreqMHz());Serial.println("MHz"); } if (user.esp < 0x32F000 || user.esp > 0x32FFFF) { Serial.print("Frequency = "); Serial.print(ESP.getCpuFreqMHz());Serial.println("MHz"); }
#endif #endif
#ifdef ESP8266 #ifdef ARDUINO_ARCH_ESP8266
Serial.print("Voltage = "); Serial.print(ESP.getVcc() / 918.0); Serial.println("V"); // 918 empirically determined Serial.print("Voltage = "); Serial.print(ESP.getVcc() / 918.0); Serial.println("V"); // 918 empirically determined
#endif #endif
Serial.print("Transactions = "); Serial.println((user.trans == 1) ? "Yes" : "No"); Serial.print("Transactions = "); Serial.println((user.trans == 1) ? "Yes" : "No");
Serial.print("Interface = "); Serial.println((user.serial == 1) ? "SPI" : "Parallel"); Serial.print("Interface = "); Serial.println((user.serial == 1) ? "SPI" : "Parallel");
#ifdef ESP8266 #ifdef ARDUINO_ARCH_ESP8266
if (user.serial == 1){ Serial.print("SPI overlap = "); Serial.println((user.overlap == 1) ? "Yes\n" : "No\n"); } if (user.serial == 1){ Serial.print("SPI overlap = "); Serial.println((user.overlap == 1) ? "Yes\n" : "No\n"); }
#endif #endif
if (user.tft_driver != 0xE9D) // For ePaper displays the size is defined in the sketch if (user.tft_driver != 0xE9D) // For ePaper displays the size is defined in the sketch
@ -78,7 +78,7 @@ if (user.pin_tft_mosi != -1) { Serial.print("MOSI = "); Serial.print("GPIO ")
if (user.pin_tft_miso != -1) { Serial.print("MISO = "); Serial.print("GPIO "); Serial.println(getPinName(user.pin_tft_miso)); } if (user.pin_tft_miso != -1) { Serial.print("MISO = "); Serial.print("GPIO "); Serial.println(getPinName(user.pin_tft_miso)); }
if (user.pin_tft_clk != -1) { Serial.print("SCK = "); Serial.print("GPIO "); Serial.println(getPinName(user.pin_tft_clk)); } if (user.pin_tft_clk != -1) { Serial.print("SCK = "); Serial.print("GPIO "); Serial.println(getPinName(user.pin_tft_clk)); }
#ifdef ESP8266 #ifdef ARDUINO_ARCH_ESP8266
if (user.overlap == true) if (user.overlap == true)
{ {
Serial.println("Overlap selected, following pins MUST be used:"); Serial.println("Overlap selected, following pins MUST be used:");
@ -92,7 +92,7 @@ if (user.overlap == true)
} }
#endif #endif
String pinNameRef = "GPIO "; String pinNameRef = "GPIO ";
#ifdef ESP8266 #ifdef ARDUINO_ARCH_ESP8266
pinNameRef = "PIN_D"; pinNameRef = "PIN_D";
#endif #endif

View File

@ -18,6 +18,9 @@ pushColor KEYWORD2
setRotation KEYWORD2 setRotation KEYWORD2
getRotation KEYWORD2 getRotation KEYWORD2
setOrigin KEYWORD2
getOriginX KEYWORD2
getOriginY KEYWORD2
invertDisplay KEYWORD2 invertDisplay KEYWORD2
setAddrWindow KEYWORD2 setAddrWindow KEYWORD2
@ -44,6 +47,8 @@ end_SDA_Read KEYWORD2
fillScreen KEYWORD2 fillScreen KEYWORD2
drawRect KEYWORD2 drawRect KEYWORD2
fillRectHGradient KEYWORD2
fillRectVGradient KEYWORD2
drawRoundRect KEYWORD2 drawRoundRect KEYWORD2
fillRoundRect KEYWORD2 fillRoundRect KEYWORD2
@ -69,6 +74,7 @@ getPivotY KEYWORD2
readRect KEYWORD2 readRect KEYWORD2
pushRect KEYWORD2 pushRect KEYWORD2
pushImage KEYWORD2 pushImage KEYWORD2
pushMaskedImage KEYWORD2
readRectRGB KEYWORD2 readRectRGB KEYWORD2
drawNumber KEYWORD2 drawNumber KEYWORD2
@ -140,10 +146,12 @@ calibrateTouch KEYWORD2
setTouch KEYWORD2 setTouch KEYWORD2
# Smooth (anti-aliased) graphics functions # Smooth (anti-aliased) graphics functions
fillRectHGradient KEYWORD2 drawSmoothCircle KEYWORD2
fillRectVGradient KEYWORD2
fillSmoothCircle KEYWORD2 fillSmoothCircle KEYWORD2
drawSmoothRoundRect KEYWORD2
fillSmoothRoundRect KEYWORD2 fillSmoothRoundRect KEYWORD2
drawSmoothArc KEYWORD2
drawArc KEYWORD2
drawSpot KEYWORD2 drawSpot KEYWORD2
drawWideLine KEYWORD2 drawWideLine KEYWORD2
drawWedgeLine KEYWORD2 drawWedgeLine KEYWORD2