diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/Makefile b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/Makefile new file mode 100644 index 00000000..c7939bbb --- /dev/null +++ b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/Makefile @@ -0,0 +1,31 @@ +CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion +CFLAGS += -Wformat-truncation -fno-common -Wconversion -Wno-sign-conversion +CFLAGS += -g3 -Os -ffunction-sections -fdata-sections +CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_f7/Include +CFLAGS += -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 $(CFLAGS_EXTRA) +LDFLAGS ?= -Tlink.ld -nostdlib -nostartfiles --specs nosys.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map + +SOURCES += cmsis_f7/Source/Templates/gcc/startup_stm32f746xx.s + +SOURCES += main.c hal.c mongoose.c packed_fs.c net.c +CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\" -DHTTPS_URL=\"https://0.0.0.0/\" + +all build example: firmware.bin + +firmware.bin: firmware.elf + arm-none-eabi-objcopy -O binary $< $@ + arm-none-eabi-size --format=berkeley $< + +firmware.elf: cmsis_core cmsis_f7 $(SOURCES) hal.h link.ld Makefile + arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@ + +flash: firmware.bin + st-flash --reset write $< 0x8000000 + +cmsis_core: + git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@ +cmsis_f7: + git clone --depth 1 -b v1.2.8 https://github.com/STMicroelectronics/cmsis_device_f7 $@ + +clean: + rm -rf firmware.* cmsis_core cmsis_f7 diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/cube/README.md b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/cube/README.md new file mode 100644 index 00000000..e69de29b diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/hal.c b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/hal.c new file mode 100644 index 00000000..d0240e6a --- /dev/null +++ b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/hal.c @@ -0,0 +1,146 @@ +// Copyright (c) 2024 Cesanta Software Limited +// All rights reserved + +#include "hal.h" + +static volatile uint64_t s_ticks; // Milliseconds since boot +void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms + s_ticks++; +} + +void mg_random(void *buf, size_t len) { // Use on-board RNG + for (size_t n = 0; n < len; n += sizeof(uint32_t)) { + uint32_t r = rng_read(); + memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r)); + } +} + +uint64_t mg_millis(void) { // Let Mongoose use our uptime function + return s_ticks; // Return number of milliseconds since boot +} + +void hal_init(void) { + clock_init(); // Set system clock to SYS_FREQUENCY + SystemCoreClock = SYS_FREQUENCY; // Update SystemCoreClock global var + SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms + rng_init(); // Initialise random number generator + + uart_init(UART_DEBUG, 115200); // Initialise UART + gpio_output(LED1); // Initialise LED1 + gpio_output(LED2); // Initialise LED2 + gpio_output(LED3); // Initialise LED3 + ethernet_init(); // Initialise Ethernet pins +} + +#if defined(__ARMCC_VERSION) +// Keil specific - implement IO printf redirection +int fputc(int c, FILE *stream) { + if (stream == stdout || stream == stderr) uart_write_byte(UART_DEBUG, c); + return c; +} +#elif defined(__GNUC__) +// ARM GCC specific. ARM GCC is shipped with Newlib C library. +// Implement newlib syscalls: +// _sbrk() for malloc +// _write() for printf redirection +// the rest are just stubs +#include // For _fstat() + +uint32_t SystemCoreClock; +void SystemInit(void) { // Called automatically by startup code +} + +int _fstat(int fd, struct stat *st) { + (void) fd, (void) st; + return -1; +} + +extern unsigned char _end[]; // End of data section, start of heap. See link.ld +static unsigned char *s_current_heap_end = _end; + +size_t hal_ram_used(void) { + return (size_t) (s_current_heap_end - _end); +} + +size_t hal_ram_free(void) { + unsigned char endofstack; + return (size_t) (&endofstack - s_current_heap_end); +} + +void *_sbrk(int incr) { + unsigned char *prev_heap; + unsigned char *heap_end = (unsigned char *) ((size_t) &heap_end - 256); + prev_heap = s_current_heap_end; + // Check how much space we got from the heap end to the stack end + if (s_current_heap_end + incr > heap_end) return (void *) -1; + s_current_heap_end += incr; + return prev_heap; +} + +int _open(const char *path) { + (void) path; + return -1; +} + +int _close(int fd) { + (void) fd; + return -1; +} + +int _isatty(int fd) { + (void) fd; + return 1; +} + +int _lseek(int fd, int ptr, int dir) { + (void) fd, (void) ptr, (void) dir; + return 0; +} + +void _exit(int status) { + (void) status; + for (;;) asm volatile("BKPT #0"); +} + +void _kill(int pid, int sig) { + (void) pid, (void) sig; +} + +int _getpid(void) { + return -1; +} + +int _write(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + if (fd == 1) uart_write_buf(UART_DEBUG, ptr, (size_t) len); + return -1; +} + +int _read(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + return -1; +} + +int _link(const char *a, const char *b) { + (void) a, (void) b; + return -1; +} + +int _unlink(const char *a) { + (void) a; + return -1; +} + +int _stat(const char *path, struct stat *st) { + (void) path, (void) st; + return -1; +} + +int mkdir(const char *path, mode_t mode) { + (void) path, (void) mode; + return -1; +} + +void _init(void) { +} +#endif // __GNUC__ diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/hal.h b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/hal.h new file mode 100644 index 00000000..d5919a2d --- /dev/null +++ b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/hal.h @@ -0,0 +1,182 @@ +// Copyright (c) 2022-2024 Cesanta Software Limited +// https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf +// https://www.st.com/resource/en/datasheet/stm32f746zg.pdf + +#pragma once + +#define LED1 PIN('B', 0) // On-board LED pin (green) +#define LED2 PIN('B', 7) // On-board LED pin (blue) +#define LED3 PIN('B', 14) // On-board LED pin (red) +#define UART_DEBUG USART3 // Wired to the on-board st-link debugger + +#include + +#include +#include +#include +#include + +#define BIT(x) (1UL << (x)) +#define CLRSET(reg, clear, set) ((reg) = ((reg) & ~(clear)) | (set)) +#define PIN(bank, num) ((((bank) - 'A') << 8) | (num)) +#define PINNO(pin) (pin & 255) +#define PINBANK(pin) (pin >> 8) + +void hal_init(void); +size_t hal_ram_free(void); +size_t hal_ram_used(void); + +/* System clock +5.3.3: APB1 clock <= 54MHz; APB2 clock <= 108MHz +3.3.2, Table 5: configure flash latency (WS) in accordance to clock freq +38.4: The AHB clock frequency must be at least 25 MHz when the Ethernet +controller is used */ +enum { APB1_PRE = 5 /* AHB clock / 4 */, APB2_PRE = 4 /* AHB clock / 2 */ }; +enum { PLL_HSI = 16, PLL_M = 8, PLL_N = 216, PLL_P = 2 }; // Run at 216 Mhz +#define FLASH_LATENCY 7 +#define SYS_FREQUENCY ((PLL_HSI * PLL_N / PLL_M / PLL_P) * 1000000) +#define APB2_FREQUENCY (SYS_FREQUENCY / (BIT(APB2_PRE - 3))) +#define APB1_FREQUENCY (SYS_FREQUENCY / (BIT(APB1_PRE - 3))) + +enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF, GPIO_MODE_ANALOG }; +enum { GPIO_OTYPE_PUSH_PULL, GPIO_OTYPE_OPEN_DRAIN }; +enum { GPIO_SPEED_LOW, GPIO_SPEED_MEDIUM, GPIO_SPEED_HIGH, GPIO_SPEED_INSANE }; +enum { GPIO_PULL_NONE, GPIO_PULL_UP, GPIO_PULL_DOWN }; +#define GPIO(N) ((GPIO_TypeDef *) (0x40020000 + 0x400 * (N))) + +static GPIO_TypeDef *gpio_bank(uint16_t pin) { + return GPIO(PINBANK(pin)); +} +static inline void gpio_toggle(uint16_t pin) { + GPIO_TypeDef *gpio = gpio_bank(pin); + uint32_t mask = BIT(PINNO(pin)); + gpio->BSRR = mask << (gpio->ODR & mask ? 16 : 0); +} +static inline int gpio_read(uint16_t pin) { + return gpio_bank(pin)->IDR & BIT(PINNO(pin)) ? 1 : 0; +} +static inline void gpio_write(uint16_t pin, bool val) { + GPIO_TypeDef *gpio = gpio_bank(pin); + gpio->BSRR = BIT(PINNO(pin)) << (val ? 0 : 16); +} +static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t type, + uint8_t speed, uint8_t pull, uint8_t af) { + GPIO_TypeDef *gpio = gpio_bank(pin); + uint8_t n = (uint8_t) (PINNO(pin)); + RCC->AHB1ENR |= BIT(PINBANK(pin)); // Enable GPIO clock + CLRSET(gpio->OTYPER, 1UL << n, ((uint32_t) type) << n); + CLRSET(gpio->OSPEEDR, 3UL << (n * 2), ((uint32_t) speed) << (n * 2)); + CLRSET(gpio->PUPDR, 3UL << (n * 2), ((uint32_t) pull) << (n * 2)); + CLRSET(gpio->AFR[n >> 3], 15UL << ((n & 7) * 4), + ((uint32_t) af) << ((n & 7) * 4)); + CLRSET(gpio->MODER, 3UL << (n * 2), ((uint32_t) mode) << (n * 2)); +} +static inline void gpio_input(uint16_t pin) { + gpio_init(pin, GPIO_MODE_INPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, + GPIO_PULL_NONE, 0); +} +static inline void gpio_output(uint16_t pin) { + gpio_init(pin, GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, + GPIO_PULL_NONE, 0); +} + +static inline void irq_exti_attach(uint16_t pin) { + uint8_t bank = (uint8_t) (PINBANK(pin)), n = (uint8_t) (PINNO(pin)); + SYSCFG->EXTICR[n / 4] &= ~(15UL << ((n % 4) * 4)); + SYSCFG->EXTICR[n / 4] |= (uint32_t) (bank << ((n % 4) * 4)); + EXTI->IMR |= BIT(n); + EXTI->RTSR |= BIT(n); + EXTI->FTSR |= BIT(n); + int irqvec = n < 5 ? 6 + n : n < 10 ? 23 : 40; // IRQ vector index, 10.1.2 + NVIC_SetPriority(irqvec, 3); + NVIC_EnableIRQ(irqvec); +} + +static inline void uart_init(USART_TypeDef *uart, unsigned long baud) { + uint8_t af = 7; // Alternate function + uint16_t rx = 0, tx = 0; // pins + uint32_t freq = 0; // Bus frequency. UART1 is on APB2, rest on APB1 + + if (uart == USART1) freq = APB2_FREQUENCY, RCC->APB2ENR |= BIT(4); + if (uart == USART2) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(17); + if (uart == USART3) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(18); + + if (uart == USART1) tx = PIN('A', 9), rx = PIN('A', 10); + if (uart == USART2) tx = PIN('A', 2), rx = PIN('A', 3); + if (uart == USART3) tx = PIN('D', 8), rx = PIN('D', 9); + + gpio_init(tx, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, 0, af); + gpio_init(rx, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, 0, af); + uart->CR1 = 0; // Disable this UART + uart->BRR = freq / baud; // Set baud rate + uart->CR1 |= BIT(0) | BIT(2) | BIT(3); // Set UE, RE, TE +} +static inline void uart_write_byte(USART_TypeDef *uart, uint8_t byte) { + uart->TDR = byte; + while ((uart->ISR & BIT(7)) == 0) (void) 0; +} +static inline void uart_write_buf(USART_TypeDef *uart, char *buf, size_t len) { + while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++); +} +static inline int uart_read_ready(USART_TypeDef *uart) { + return uart->ISR & BIT(5); // If RXNE bit is set, data is ready +} +static inline uint8_t uart_read_byte(USART_TypeDef *uart) { + return (uint8_t) (uart->RDR & 255); +} + +static inline void rng_init(void) { + RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN; + RNG->CR |= RNG_CR_RNGEN; +} +static inline uint32_t rng_read(void) { + while ((RNG->SR & RNG_SR_DRDY) == 0) (void) 0; + return RNG->DR; +} + +static inline void ethernet_init(void) { + // Initialise Ethernet. Enable MAC GPIO pins, see + // https://www.farnell.com/datasheets/2014265.pdf section 6.10 + uint16_t pins[] = {PIN('A', 1), PIN('A', 2), PIN('A', 7), + PIN('B', 13), PIN('C', 1), PIN('C', 4), + PIN('C', 5), PIN('G', 11), PIN('G', 13)}; + for (size_t i = 0; i < sizeof(pins) / sizeof(pins[0]); i++) { + gpio_init(pins[i], GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_INSANE, + GPIO_PULL_NONE, 11); // 11 is the Ethernet function + } + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // Enable SYSCFG + NVIC_EnableIRQ(ETH_IRQn); // Setup Ethernet IRQ handler + SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; // Use RMII. Goes first! + RCC->AHB1ENR |= + RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN; +} + +static inline void clock_init(void) { + SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); // Enable FPU + __DSB(); + __ISB(); + FLASH->ACR |= FLASH_LATENCY | BIT(8) | BIT(9); // Flash latency, prefetch + RCC->PLLCFGR &= ~((BIT(17) - 1)); // Clear PLL multipliers + RCC->PLLCFGR |= (((PLL_P - 2) / 2) & 3) << 16; // Set PLL_P + RCC->PLLCFGR |= PLL_M | (PLL_N << 6); // Set PLL_M and PLL_N + RCC->CR |= BIT(24); // Enable PLL + while ((RCC->CR & BIT(25)) == 0) (void) 0; // Wait until done + RCC->CFGR = (APB1_PRE << 10) | (APB2_PRE << 13); // Set prescalers + RCC->CFGR |= 2; // Set clock source to PLL + while ((RCC->CFGR & 12) == 0) (void) 0; // Wait until done +} + +// Helper macro for MAC generation +#define UUID ((uint8_t *) UID_BASE) // Unique 96-bit chip ID. TRM 41.1 +#define GENERATE_MAC_ADDRESS() \ + { \ + 2, UUID[0] ^ UUID[1], UUID[2] ^ UUID[3], UUID[4] ^ UUID[5], \ + UUID[6] ^ UUID[7] ^ UUID[8], UUID[9] ^ UUID[10] ^ UUID[11] \ + } + +#define MG_TCPIP_DRIVER_INIT(mgr) \ + struct mg_tcpip_driver_stm32f_data driver_data = {.mdc_cr = 4}; \ + struct mg_tcpip_if mif = {.mac = GENERATE_MAC_ADDRESS(), \ + .driver = &mg_tcpip_driver_stm32f, \ + .driver_data = &driver_data}; \ + mg_tcpip_init(&mgr, &mif); diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/keil/README.md b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/keil/README.md new file mode 100644 index 00000000..e69de29b diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/link.ld b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/link.ld new file mode 100644 index 00000000..1aeee783 --- /dev/null +++ b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/link.ld @@ -0,0 +1,25 @@ +ENTRY(Reset_Handler); +MEMORY { + flash(rx) : ORIGIN = 0x08000000, LENGTH = 1024k + sram(rwx) : ORIGIN = 0x20000000, LENGTH = 320k +} +_estack = ORIGIN(sram) + LENGTH(sram); /* stack points to end of SRAM */ + +SECTIONS { + .vectors : { KEEP(*(.isr_vector)) } > flash + .text : { *(.text* .text.*) } > flash + .rodata : { *(.rodata*) } > flash + + .data : { + _sdata = .; + *(.first_data) + *(.data SORT(.data.*)) + _edata = .; + } > sram AT > flash + _sidata = LOADADDR(.data); + + .bss : { _sbss = .; *(.bss SORT(.bss.*) COMMON) _ebss = .; } > sram + + . = ALIGN(8); + _end = .; +} diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/main.c b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/main.c new file mode 120000 index 00000000..c2536055 --- /dev/null +++ b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/main.c @@ -0,0 +1 @@ +../../../windows-macos-linux/web-ui-dashboard/main.c \ No newline at end of file diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/mongoose.c b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/mongoose.c new file mode 120000 index 00000000..7a2752cb --- /dev/null +++ b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/mongoose.c @@ -0,0 +1 @@ +../../../../mongoose.c \ No newline at end of file diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/mongoose.h b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/mongoose.h new file mode 120000 index 00000000..daff1633 --- /dev/null +++ b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/mongoose.h @@ -0,0 +1 @@ +../../../../mongoose.h \ No newline at end of file diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/mongoose_custom.h b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/mongoose_custom.h new file mode 100644 index 00000000..937c96e5 --- /dev/null +++ b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/mongoose_custom.h @@ -0,0 +1,11 @@ +#pragma once + +// See https://mongoose.ws/documentation/#build-options +#define MG_ARCH MG_ARCH_NEWLIB +#define MG_TLS MG_TLS_BUILTIN + +#define MG_ENABLE_TCPIP 1 +#define MG_ENABLE_CUSTOM_MILLIS 1 +#define MG_ENABLE_CUSTOM_RANDOM 1 +#define MG_ENABLE_PACKED_FS 1 +#define MG_ENABLE_DRIVER_STM32F 1 diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/net.c b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/net.c new file mode 120000 index 00000000..4e03148e --- /dev/null +++ b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/net.c @@ -0,0 +1 @@ +../../../windows-macos-linux/web-ui-dashboard/net.c \ No newline at end of file diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/net.h b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/net.h new file mode 120000 index 00000000..e685462d --- /dev/null +++ b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/net.h @@ -0,0 +1 @@ +../../../windows-macos-linux/web-ui-dashboard/net.h \ No newline at end of file diff --git a/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/packed_fs.c b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/packed_fs.c new file mode 120000 index 00000000..d58fed46 --- /dev/null +++ b/reference-projects/stm32/nucleo-f746zg/web-ui-dashboard/packed_fs.c @@ -0,0 +1 @@ +../../../windows-macos-linux/web-ui-dashboard/packed_fs.c \ No newline at end of file diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/Makefile b/reference-projects/windows-macos-linux/web-ui-dashboard/Makefile new file mode 100644 index 00000000..440270b9 --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/Makefile @@ -0,0 +1,51 @@ +# Environment setup: https://mongoose.ws/documentation/tutorials/tools/ + +PROG ?= ./example # Program we are building +PACK ?= ./pack # Packing executable +DELETE = rm -rf # Command to remove files +NPX ?= npx # For generating optimised tailwind CSS +OUT ?= -o $(PROG) # Compiler argument for output file + +SOURCES = main.c mongoose.c net.c packed_fs.c +CFLAGS += -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion -Wconversion -Wno-sign-conversion +CFLAGS += -fno-common -ffunction-sections -fdata-sections +CFLAGS += -g3 -Os -I. + +# Mongoose build options. See https://mongoose.ws/documentation/#build-options +CFLAGS_MONGOOSE += -DMG_ENABLE_PACKED_FS=1 + +ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe + PROG = example.exe # Use .exe suffix for the binary + PACK = pack.exe # Packing executable + CC = gcc # Use MinGW gcc compiler + CFLAGS += -lws2_32 # Link against Winsock library + DELETE = cmd /C del /Q /F /S # Command prompt command to delete files +endif + +# Default target. Build and run program +all: $(PROG) + $(RUN) $(PROG) $(ARGS) + +# Build program from sources +$(PROG): $(SOURCES) + $(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT) + +# Build using Microsoft Visual C compiler +vc: $(SOURCES) Makefile + cl $(SOURCES) /DMG_ENABLE_PACKED_FS=1 /MD /W3 /nologo /Fedemo.exe + +# Bundle JS libraries (preact, preact-router, ...) into a single file +web_root/bundle.js: + curl -s https://npm.reversehttp.com/preact,preact/hooks,htm/preact,preact-router -o $@ + +# Create optimised CSS. Prerequisite: npm -g i tailwindcss tailwindcss-font-inter +web_root/main.css: web_root/index.html $(wildcard web_root/*.js) + $(NPX) tailwindcss -o $@ --minify + +# Generate packed filesystem for serving Web UI +packed_fs.c: $(wildcard web_root/*) $(wildcard certs/*) Makefile + node pack.js $(addsuffix ::gzip, $(wildcard web_root/*)) certs/* > $@ + +# Cleanup. Delete built program and all build artifacts +clean: + $(DELETE) $(PROG) $(PACK) *.o *.obj *.exe *.dSYM mbedtls diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/certs/server_cert.pem b/reference-projects/windows-macos-linux/web-ui-dashboard/certs/server_cert.pem new file mode 100644 index 00000000..ecfd036c --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/certs/server_cert.pem @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE----- +MIIBCTCBsAIJAK9wbIDkHnAoMAoGCCqGSM49BAMCMA0xCzAJBgNVBAYTAklFMB4X +DTIzMDEyOTIxMjEzOFoXDTMzMDEyNjIxMjEzOFowDTELMAkGA1UEBhMCSUUwWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARzSQS5OHd17lUeNI+6kp9WYu0cxuEIi/JT +jphbCmdJD1cUvhmzM9/phvJT9ka10Z9toZhgnBq0o0xfTQ4jC1vwMAoGCCqGSM49 +BAMCA0gAMEUCIQCe0T2E0GOiVe9KwvIEPeX1J1J0T7TNacgR0Ya33HV9VgIgNvdn +aEWiBp1xshs4iz6WbpxrS1IHucrqkZuJLfNZGZI= +-----END CERTIFICATE----- diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/certs/server_key.pem b/reference-projects/windows-macos-linux/web-ui-dashboard/certs/server_key.pem new file mode 100644 index 00000000..33c61111 --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/certs/server_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEICBz3HOkQLPBDtdknqC7k1PNsWj6HfhyNB5MenfjmqiooAoGCCqGSM49 +AwEHoUQDQgAEc0kEuTh3de5VHjSPupKfVmLtHMbhCIvyU46YWwpnSQ9XFL4ZszPf +6YbyU/ZGtdGfbaGYYJwatKNMX00OIwtb8A== +-----END EC PRIVATE KEY----- diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/hal.h b/reference-projects/windows-macos-linux/web-ui-dashboard/hal.h new file mode 100644 index 00000000..689f23b2 --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/hal.h @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Cesanta Software Limited +// All rights reserved + +#pragma once + +#define LED1 0 +#define LED2 1 +#define UART_DEBUG NULL + +// No-op HAL API implementation for a device with GPIO and UART +#define hal_init() +#define hal_ram_free() 0 +#define hal_ram_used() 0 +#define gpio_output(pin) +#define gpio_toggle(pin) +#define gpio_read(pin) 0 +#define gpio_write(pin, val) +#define uart_init(uart, baud) +#define uart_read_ready(uart) 0 +#define uart_write_byte(uart, ch) +#define uart_write_buf(uart, buf, len) diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/main.c b/reference-projects/windows-macos-linux/web-ui-dashboard/main.c new file mode 100644 index 00000000..6e0047ba --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/main.c @@ -0,0 +1,32 @@ +// Copyright (c) 2024 Cesanta Software Limited +// All rights reserved + +#include "hal.h" +#include "mongoose.h" +#include "net.h" + +#define BLINK_PERIOD_MS 1000 // LED blinking period in millis + +static void timer_fn(void *arg) { + gpio_toggle(LED1); // Blink LED + (void) arg; // Unused +} + +// In RTOS environment, you can run this function in a separate task +static void run_mongoose(void) { + struct mg_mgr mgr; // Mongoose event manager + mg_mgr_init(&mgr); // Initialise event manager + mg_log_set(MG_LL_DEBUG); // Set log level to debug + mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, NULL); + + net_init(&mgr); // Initialise application defined in net.c + for (;;) { // Infinite event loop + mg_mgr_poll(&mgr, 0); // Process network events + } +} + +int main(void) { + hal_init(); // Cross-platform hardware init + run_mongoose(); // Initialise and run network application + return 0; +} diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/mongoose.c b/reference-projects/windows-macos-linux/web-ui-dashboard/mongoose.c new file mode 120000 index 00000000..5e522bbc --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/mongoose.c @@ -0,0 +1 @@ +../../../mongoose.c \ No newline at end of file diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/mongoose.h b/reference-projects/windows-macos-linux/web-ui-dashboard/mongoose.h new file mode 120000 index 00000000..ee4ac823 --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/mongoose.h @@ -0,0 +1 @@ +../../../mongoose.h \ No newline at end of file diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/net.c b/reference-projects/windows-macos-linux/web-ui-dashboard/net.c new file mode 100644 index 00000000..622d93e1 --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/net.c @@ -0,0 +1,324 @@ +// Copyright (c) 2023 Cesanta Software Limited +// All rights reserved + +#include "hal.h" +#include "net.h" + +// Authenticated user. +// A user can be authenticated by: +// - a name:pass pair, passed in a header Authorization: Basic ..... +// - an access_token, passed in a header Cookie: access_token=.... +// When a user is shown a login screen, she enters a user:pass. If successful, +// a server responds with a http-only access_token cookie set. +struct user { + const char *name, *pass, *access_token; +}; + +// Settings +struct settings { + bool log_enabled; + int log_level; + long brightness; + char *device_name; +}; + +static struct settings s_settings = {true, 1, 57, NULL}; + +static const char *s_json_header = + "Content-Type: application/json\r\n" + "Cache-Control: no-cache\r\n"; +static uint64_t s_boot_timestamp = 0; // Updated by SNTP + +// This is for newlib and TLS (mbedTLS) +uint64_t mg_now(void) { + return mg_millis() + s_boot_timestamp; +} + +int ui_event_next(int no, struct ui_event *e) { + if (no < 0 || no >= MAX_EVENTS_NO) return 0; + + srand((unsigned) no); + e->type = (uint8_t) rand() % 4; + e->prio = (uint8_t) rand() % 3; + e->timestamp = + (unsigned long) ((int64_t) mg_now() - 86400 * 1000 /* one day back */ + + no * 300 * 1000 /* 5 mins between alerts */ + + 1000 * (rand() % 300) /* randomize event time */) / + 1000UL; + + mg_snprintf(e->text, MAX_EVENT_TEXT_SIZE, "event#%d", no); + return no + 1; +} + +// SNTP connection event handler. When we get a response from an SNTP server, +// adjust s_boot_timestamp. We'll get a valid time from that point on +static void sfn(struct mg_connection *c, int ev, void *ev_data) { + uint64_t *expiration_time = (uint64_t *) c->data; + if (ev == MG_EV_OPEN) { + *expiration_time = mg_millis() + 3000; // Store expiration time in 3s + } else if (ev == MG_EV_SNTP_TIME) { + uint64_t t = *(uint64_t *) ev_data; + s_boot_timestamp = t - mg_millis(); + c->is_closing = 1; + } else if (ev == MG_EV_POLL) { + if (mg_millis() > *expiration_time) c->is_closing = 1; + } +} + +static void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time + mg_sntp_connect(param, "udp://time.google.com:123", sfn, NULL); +} + +// Parse HTTP requests, return authenticated user or NULL +static struct user *authenticate(struct mg_http_message *hm) { + // In production, make passwords strong and tokens randomly generated + // In this example, user list is kept in RAM. In production, it can + // be backed by file, database, or some other method. + static struct user users[] = { + {"admin", "admin", "admin_token"}, + {"user1", "user1", "user1_token"}, + {"user2", "user2", "user2_token"}, + {NULL, NULL, NULL}, + }; + char user[64], pass[64]; + struct user *u, *result = NULL; + mg_http_creds(hm, user, sizeof(user), pass, sizeof(pass)); + MG_VERBOSE(("user [%s] pass [%s]", user, pass)); + + if (user[0] != '\0' && pass[0] != '\0') { + // Both user and password is set, search by user/password + for (u = users; result == NULL && u->name != NULL; u++) + if (strcmp(user, u->name) == 0 && strcmp(pass, u->pass) == 0) result = u; + } else if (user[0] == '\0') { + // Only password is set, search by token + for (u = users; result == NULL && u->name != NULL; u++) + if (strcmp(pass, u->access_token) == 0) result = u; + } + return result; +} + +static void handle_login(struct mg_connection *c, struct user *u) { + char cookie[256]; + mg_snprintf(cookie, sizeof(cookie), + "Set-Cookie: access_token=%s; Path=/; " + "%sHttpOnly; SameSite=Lax; Max-Age=%d\r\n", + u->access_token, c->is_tls ? "Secure; " : "", 3600 * 24); + mg_http_reply(c, 200, cookie, "{%m:%m}", MG_ESC("user"), MG_ESC(u->name)); +} + +static void handle_logout(struct mg_connection *c) { + char cookie[256]; + mg_snprintf(cookie, sizeof(cookie), + "Set-Cookie: access_token=; Path=/; " + "Expires=Thu, 01 Jan 1970 00:00:00 UTC; " + "%sHttpOnly; Max-Age=0; \r\n", + c->is_tls ? "Secure; " : ""); + mg_http_reply(c, 200, cookie, "true\n"); +} + +static void handle_debug(struct mg_connection *c, struct mg_http_message *hm) { + int level = (int) mg_json_get_long(hm->body, "$.level", MG_LL_DEBUG); + mg_log_set(level); + mg_http_reply(c, 200, "", "Debug level set to %d\n", level); +} + +static size_t print_int_arr(void (*out)(char, void *), void *ptr, va_list *ap) { + size_t i, len = 0, num = va_arg(*ap, size_t); // Number of items in the array + int *arr = va_arg(*ap, int *); // Array ptr + for (i = 0; i < num; i++) { + len += mg_xprintf(out, ptr, "%s%d", i == 0 ? "" : ",", arr[i]); + } + return len; +} + +static void handle_stats_get(struct mg_connection *c) { + int points[] = {21, 22, 22, 19, 18, 20, 23, 23, 22, 22, 22, 23, 22}; + mg_http_reply(c, 200, s_json_header, "{%m:%d,%m:%d,%m:[%M]}\n", + MG_ESC("temperature"), 21, // + MG_ESC("humidity"), 67, // + MG_ESC("points"), print_int_arr, + sizeof(points) / sizeof(points[0]), points); +} + +static size_t print_events(void (*out)(char, void *), void *ptr, va_list *ap) { + size_t len = 0; + struct ui_event ev; + int pageno = va_arg(*ap, int); + int no = (pageno - 1) * EVENTS_PER_PAGE; + int end = no + EVENTS_PER_PAGE; + + while ((no = ui_event_next(no, &ev)) != 0 && no <= end) { + len += mg_xprintf(out, ptr, "%s{%m:%lu,%m:%d,%m:%d,%m:%m}\n", // + len == 0 ? "" : ",", // + MG_ESC("time"), ev.timestamp, // + MG_ESC("type"), ev.type, // + MG_ESC("prio"), ev.prio, // + MG_ESC("text"), MG_ESC(ev.text)); + } + + return len; +} + +static void handle_events_get(struct mg_connection *c, + struct mg_http_message *hm) { + int pageno = (int) mg_json_get_long(hm->body, "$.page", 1); + mg_http_reply(c, 200, s_json_header, "{%m:[%M], %m:%d}\n", MG_ESC("arr"), + print_events, pageno, MG_ESC("totalCount"), MAX_EVENTS_NO); +} + +static void handle_settings_set(struct mg_connection *c, struct mg_str body) { + struct settings settings; + char *s = mg_json_get_str(body, "$.device_name"); + bool ok = true; + memset(&settings, 0, sizeof(settings)); + mg_json_get_bool(body, "$.log_enabled", &settings.log_enabled); + settings.log_level = (int) mg_json_get_long(body, "$.log_level", 0); + settings.brightness = mg_json_get_long(body, "$.brightness", 0); + if (s && strlen(s) < MAX_DEVICE_NAME) { + free(settings.device_name); + settings.device_name = s; + } else { + free(s); + } + s_settings = settings; // Save to the device flash + mg_http_reply(c, 200, s_json_header, + "{%m:%s,%m:%m}", // + MG_ESC("status"), ok ? "true" : "false", // + MG_ESC("message"), MG_ESC(ok ? "Success" : "Failed")); +} + +static void handle_settings_get(struct mg_connection *c) { + mg_http_reply(c, 200, s_json_header, "{%m:%s,%m:%hhu,%m:%hhu,%m:%m}\n", // + MG_ESC("log_enabled"), + s_settings.log_enabled ? "true" : "false", // + MG_ESC("log_level"), s_settings.log_level, // + MG_ESC("brightness"), s_settings.brightness, // + MG_ESC("device_name"), MG_ESC(s_settings.device_name)); +} + +static void handle_firmware_upload(struct mg_connection *c, + struct mg_http_message *hm) { + char name[64], offset[20], total[20]; + struct mg_str data = hm->body; + long ofs = -1, tot = -1; + name[0] = offset[0] = '\0'; + mg_http_get_var(&hm->query, "name", name, sizeof(name)); + mg_http_get_var(&hm->query, "offset", offset, sizeof(offset)); + mg_http_get_var(&hm->query, "total", total, sizeof(total)); + MG_INFO(("File %s, offset %s, len %lu", name, offset, data.len)); + if ((ofs = mg_json_get_long(mg_str(offset), "$", -1)) < 0 || + (tot = mg_json_get_long(mg_str(total), "$", -1)) < 0) { + mg_http_reply(c, 500, "", "offset and total not set\n"); + } else if (ofs == 0 && mg_ota_begin((size_t) tot) == false) { + mg_http_reply(c, 500, "", "mg_ota_begin(%ld) failed\n", tot); + } else if (data.len > 0 && mg_ota_write(data.ptr, data.len) == false) { + mg_http_reply(c, 500, "", "mg_ota_write(%lu) @%ld failed\n", data.len, ofs); + mg_ota_end(); + } else if (data.len == 0 && mg_ota_end() == false) { + mg_http_reply(c, 500, "", "mg_ota_end() failed\n", tot); + } else { + mg_http_reply(c, 200, s_json_header, "true\n"); + if (data.len == 0) { + // Successful mg_ota_end() called, schedule device reboot + mg_timer_add(c->mgr, 500, 0, (void (*)(void *)) mg_device_reset, NULL); + } + } +} + +static void handle_firmware_commit(struct mg_connection *c) { + mg_http_reply(c, 200, s_json_header, "%s\n", + mg_ota_commit() ? "true" : "false"); +} + +static void handle_firmware_rollback(struct mg_connection *c) { + mg_http_reply(c, 200, s_json_header, "%s\n", + mg_ota_rollback() ? "true" : "false"); +} + +static size_t print_status(void (*out)(char, void *), void *ptr, va_list *ap) { + int fw = va_arg(*ap, int); + return mg_xprintf(out, ptr, "{%m:%d,%m:%c%lx%c,%m:%u,%m:%u}\n", + MG_ESC("status"), mg_ota_status(fw), MG_ESC("crc32"), '"', + mg_ota_crc32(fw), '"', MG_ESC("size"), mg_ota_size(fw), + MG_ESC("timestamp"), mg_ota_timestamp(fw)); +} + +static void handle_firmware_status(struct mg_connection *c) { + mg_http_reply(c, 200, s_json_header, "[%M,%M]\n", print_status, + MG_FIRMWARE_CURRENT, print_status, MG_FIRMWARE_PREVIOUS); +} + +static void handle_device_reset(struct mg_connection *c) { + mg_http_reply(c, 200, s_json_header, "true\n"); + mg_timer_add(c->mgr, 500, 0, (void (*)(void *)) mg_device_reset, NULL); +} + +static void handle_device_eraselast(struct mg_connection *c) { + size_t ss = mg_flash_sector_size(), size = mg_flash_size(); + char *base = (char *) mg_flash_start(), *last = base + size - ss; + if (mg_flash_bank() == 2) last -= size / 2; + mg_flash_erase(last); + mg_http_reply(c, 200, s_json_header, "true\n"); +} + +// HTTP request handler function +static void ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_ACCEPT) { + if (c->fn_data != NULL) { // TLS listener! + struct mg_tls_opts opts = {0}; + opts.cert = mg_unpacked("/certs/server_cert.pem"); + opts.key = mg_unpacked("/certs/server_key.pem"); + mg_tls_init(c, &opts); + } + } else if (ev == MG_EV_HTTP_MSG) { + struct mg_http_message *hm = (struct mg_http_message *) ev_data; + struct user *u = authenticate(hm); + + if (mg_http_match_uri(hm, "/api/#") && u == NULL) { + mg_http_reply(c, 403, "", "Not Authorised\n"); + } else if (mg_http_match_uri(hm, "/api/login")) { + handle_login(c, u); + } else if (mg_http_match_uri(hm, "/api/logout")) { + handle_logout(c); + } else if (mg_http_match_uri(hm, "/api/debug")) { + handle_debug(c, hm); + } else if (mg_http_match_uri(hm, "/api/stats/get")) { + handle_stats_get(c); + } else if (mg_http_match_uri(hm, "/api/events/get")) { + handle_events_get(c, hm); + } else if (mg_http_match_uri(hm, "/api/settings/get")) { + handle_settings_get(c); + } else if (mg_http_match_uri(hm, "/api/settings/set")) { + handle_settings_set(c, hm->body); + } else if (mg_http_match_uri(hm, "/api/firmware/upload")) { + handle_firmware_upload(c, hm); + } else if (mg_http_match_uri(hm, "/api/firmware/commit")) { + handle_firmware_commit(c); + } else if (mg_http_match_uri(hm, "/api/firmware/rollback")) { + handle_firmware_rollback(c); + } else if (mg_http_match_uri(hm, "/api/firmware/status")) { + handle_firmware_status(c); + } else if (mg_http_match_uri(hm, "/api/device/reset")) { + handle_device_reset(c); + } else if (mg_http_match_uri(hm, "/api/device/eraselast")) { + handle_device_eraselast(c); + } else { + struct mg_http_serve_opts opts; + memset(&opts, 0, sizeof(opts)); + opts.fs = HAL_FS; + opts.root_dir = HAL_WEB_ROOT_DIR; + mg_http_serve_dir(c, ev_data, &opts); + } + MG_DEBUG(("%lu %.*s %.*s -> %.*s", c->id, (int) hm->method.len, + hm->method.ptr, (int) hm->uri.len, hm->uri.ptr, (int) 3, + &c->send.buf[9])); + } +} + +void net_init(struct mg_mgr *mgr) { + s_settings.device_name = strdup("My Device"); + mg_http_listen(mgr, HTTP_URL, ev_handler, NULL); + mg_http_listen(mgr, HTTPS_URL, ev_handler, (void *) 1); + mg_timer_add(mgr, 3600 * 1000, MG_TIMER_RUN_NOW | MG_TIMER_REPEAT, + timer_sntp_fn, mgr); +} diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/net.h b/reference-projects/windows-macos-linux/web-ui-dashboard/net.h new file mode 100644 index 00000000..7c30854a --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/net.h @@ -0,0 +1,50 @@ +// Copyright (c) 2023-2024 Cesanta Software Limited +// All rights reserved +#pragma once + +#include "mongoose.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if MG_ENABLE_FATFS +#define HAL_FS (&mg_fs_fat) +#define HAL_ROOT_DIR "/" +#elif MG_ENABLE_PACKED_FS +#define HAL_FS (&mg_fs_packed) +#define HAL_ROOT_DIR "/" +#else +#define HAL_FS (&mg_fs_posix) +#define HAL_ROOT_DIR "./" +#endif + +#define HAL_WEB_ROOT_DIR HAL_ROOT_DIR "web_root" + +#if defined(HTTP_URL) && defined(HTTPS_URL) +// Allow to override via the build flags +#elif MG_ENABLE_TCPIP +#define HTTP_URL "http://0.0.0.0:80" // Embedded build: +#define HTTPS_URL "https://0.0.0.0:443" // Use standard privileged ports +#else +#define HTTP_URL "http://0.0.0.0:8000" // Workstation build: +#define HTTPS_URL "https://0.0.0.0:8443" // Use non-privileged ports +#endif + +#define MAX_DEVICE_NAME 40 +#define MAX_EVENTS_NO 400 +#define MAX_EVENT_TEXT_SIZE 10 +#define EVENTS_PER_PAGE 20 + +// Event log entry +struct ui_event { + uint8_t type, prio; + unsigned long timestamp; + char text[10]; +}; + +void net_init(struct mg_mgr *mgr); + +#ifdef __cplusplus +} +#endif diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/pack.js b/reference-projects/windows-macos-linux/web-ui-dashboard/pack.js new file mode 100644 index 00000000..4facd3d4 --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/pack.js @@ -0,0 +1,81 @@ +// Copyright (c) 2024 Cesanta Software Limited +// +// Utility that generates packed filesystem C file compatible with the +// Mongoose Network Library, https://github.com/cesanta/mongoose +// +// Usage: +// node pack.js FILE[:DESTINATION[:gzip]] ... + +const fs = require('fs'); +const zlib = require('zlib'); +const argv = process.argv.slice(2); + +// Convert each command-line arguments into [ DATA_ARRAY, STRUCT_INITIALIZER ] +const entries = argv.map(function(filename, i) { + const parts = filename.split(':'); + const stat = fs.statSync(parts[0]); + const data = fs.readFileSync(parts[0], null); + let bytes = Array.from(data); + let destination = (parts[1] || parts[0]).replace(/^\.+[\/\\]*/, ''); + if (parts[2] == 'gzip') { + bytes = Array.from(zlib.gzipSync(data)); + destination += '.gz'; + } + + // concat(0) appends trailing 0, in order to make any file an asciz string + return [ + `static const unsigned char v${i}[] = {${bytes.concat(0).join(',')}};`, + ` {"/${destination}", v${i}, sizeof(v${i}) - 1, ${parseInt(stat.mtimeMs / 1000)}}`, + ]; +}); + +process.stdout.write(`// DO NOT EDIT. This file is generated using this command: +// ${process.argv.join(' ')} + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +const char *mg_unlist(size_t no); +const char *mg_unpack(const char *, size_t *, time_t *); + +#if defined(__cplusplus) +} +#endif + +${entries.map(x => x[0]).join('\n\n')} + +static const struct packed_file { + const char *name; + const unsigned char *data; + size_t size; + time_t mtime; +} packed_files[] = { +${entries.map(x => x[1]).join(',\n')}, + {NULL, NULL, 0, 0} +}; + +static int scmp(const char *a, const char *b) { + while (*a && (*a == *b)) a++, b++; + return *(const unsigned char *) a - *(const unsigned char *) b; +} + +const char *mg_unlist(size_t no) { + return packed_files[no].name; +} + +const char *mg_unpack(const char *name, size_t *size, time_t *mtime) { + const struct packed_file *p; + for (p = packed_files; p->name != NULL; p++) { + if (scmp(p->name, name) != 0) continue; + if (size != NULL) *size = p->size; + if (mtime != NULL) *mtime = p->mtime; + return (const char *) p->data; + } + return NULL; +}; +`); diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/packed_fs.c b/reference-projects/windows-macos-linux/web-ui-dashboard/packed_fs.c new file mode 100644 index 00000000..be7ba7ff --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/packed_fs.c @@ -0,0 +1,70 @@ +// DO NOT EDIT. This file is generated using this command: +// /opt/homebrew/Cellar/node/21.6.0/bin/node /Users/cpq/src/mongoose/reference-projects/windows-macos-linux/web-ui-dashboard/pack.js web_root/bundle.js::gzip web_root/components.js::gzip web_root/history.min.js::gzip web_root/index.html::gzip web_root/main.css::gzip web_root/main.js::gzip certs/server_cert.pem certs/server_key.pem + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +const char *mg_unlist(size_t no); +const char *mg_unpack(const char *, size_t *, time_t *); + +#if defined(__cplusplus) +} +#endif + +static const unsigned char v0[] = {31,139,8,0,0,0,0,0,0,19,173,60,139,114,219,56,146,191,18,105,83,90,98,132,200,118,102,178,119,71,25,81,37,30,79,156,153,60,188,118,30,187,171,209,170,40,10,178,56,166,64,153,132,228,120,76,221,183,95,119,227,65,82,166,231,246,182,174,42,17,65,60,27,141,126,163,233,109,148,63,81,92,115,201,167,60,231,25,79,248,134,167,60,22,247,59,30,137,241,132,23,226,32,138,19,93,202,111,193,40,44,202,171,82,149,235,242,41,43,243,245,178,188,202,147,121,153,221,22,229,74,197,165,210,183,101,162,228,56,94,78,202,223,179,172,252,103,150,207,203,68,203,60,58,72,134,139,141,138,117,146,169,39,139,0,22,99,247,139,44,15,182,176,178,124,146,168,39,154,169,177,156,8,13,63,195,92,234,77,174,158,168,157,31,177,14,20,187,199,190,90,168,193,58,202,165,210,31,178,185,28,234,94,79,15,114,185,202,182,242,100,153,164,115,232,86,13,90,6,180,35,51,208,110,11,182,52,196,117,19,92,83,178,238,181,188,235,10,145,140,114,33,199,201,36,236,230,114,65,239,153,121,223,192,15,149,134,201,34,136,242,171,205,10,86,46,6,169,84,87,122,249,242,121,175,23,108,6,49,46,12,16,137,7,237,223,143,212,32,142,210,180,26,201,159,179,112,202,120,215,193,8,107,233,187,181,204,22,79,96,39,106,147,166,29,161,7,115,185,136,54,169,62,207,179,117,193,60,176,123,245,219,44,153,63,57,20,66,32,136,8,7,66,218,236,3,53,204,225,114,14,184,216,208,217,226,42,53,36,1,202,220,161,27,68,1,138,16,164,80,241,53,78,18,78,57,224,40,204,57,96,38,204,248,116,122,29,226,12,80,112,207,89,120,8,191,210,189,206,67,3,26,20,99,87,183,52,133,56,83,133,206,55,177,206,242,170,211,150,218,16,231,253,190,12,147,157,63,125,83,91,161,101,171,224,196,241,188,169,16,108,24,223,84,219,216,6,236,222,12,188,143,55,57,210,7,77,187,171,122,172,144,132,220,220,254,208,170,246,59,67,148,122,153,20,3,218,185,128,119,124,1,168,181,252,166,133,174,250,94,153,190,64,19,6,74,205,252,196,211,233,8,90,225,193,241,7,254,93,15,18,53,151,223,62,66,95,214,63,98,4,214,208,147,254,80,31,43,234,100,72,102,168,251,125,102,167,237,136,64,10,106,28,235,9,115,120,144,80,33,221,114,244,98,17,214,66,83,106,128,5,132,199,44,91,109,96,230,249,137,203,97,181,158,162,245,252,90,248,18,27,62,197,162,129,38,30,204,162,2,138,120,160,90,28,254,155,27,184,127,48,161,217,203,44,151,209,245,206,110,15,161,172,157,224,53,2,29,116,112,204,28,40,158,158,162,115,8,51,231,131,245,166,88,66,115,175,215,57,129,234,188,223,47,203,172,35,136,33,102,25,76,32,47,36,156,66,158,168,43,232,19,4,89,107,75,89,38,44,56,169,49,199,73,96,176,228,100,35,138,16,32,99,58,190,124,80,100,185,6,50,28,42,1,229,101,178,208,1,27,50,7,157,134,74,131,18,62,21,150,216,51,87,72,69,144,16,114,24,244,222,226,143,228,65,76,40,56,71,248,166,40,116,1,200,69,0,18,56,97,212,75,36,248,219,63,226,159,130,24,192,200,56,246,86,220,204,8,91,141,7,217,173,146,249,229,151,55,167,169,68,97,195,13,190,113,216,114,52,78,39,150,25,185,33,217,20,200,34,97,97,202,169,157,241,139,96,10,43,209,155,236,136,180,215,155,65,51,227,110,19,47,53,98,217,238,152,13,9,201,226,176,194,212,183,224,161,254,40,12,242,22,124,205,151,124,203,239,248,140,95,243,19,49,237,245,136,47,202,50,226,223,196,137,35,28,196,41,110,233,26,247,190,0,194,90,28,107,223,214,32,170,45,33,234,122,188,152,8,179,23,168,209,240,6,231,215,157,101,89,42,163,26,15,108,161,242,33,103,108,71,56,50,236,130,56,130,131,111,246,86,155,213,76,230,205,186,89,114,149,40,93,31,63,39,104,96,91,244,48,101,22,190,202,243,232,110,144,20,244,12,182,12,186,173,248,189,19,54,225,118,87,235,78,130,56,220,194,86,102,47,15,161,227,150,184,149,111,141,244,129,39,200,93,248,5,185,59,162,95,115,126,91,162,152,112,203,72,252,224,155,144,84,57,35,172,204,128,64,12,82,68,176,20,39,6,43,203,94,143,102,19,98,137,15,124,195,165,4,190,99,129,97,63,75,155,67,153,22,242,9,30,198,26,206,96,125,252,109,184,6,228,227,90,52,223,26,25,249,143,39,187,199,94,110,54,195,207,75,58,168,221,39,32,146,45,95,138,101,89,198,13,58,225,119,98,107,152,96,45,104,175,176,200,18,159,29,177,6,118,0,82,9,144,44,24,167,202,94,239,218,240,59,189,57,220,115,91,185,38,108,196,101,9,200,3,2,54,52,115,55,178,146,122,6,211,205,196,93,171,10,54,27,193,13,33,21,226,126,224,57,218,146,152,73,197,105,176,5,88,65,146,166,226,179,217,7,63,1,154,78,91,167,146,118,42,162,104,24,205,96,24,110,9,101,30,50,87,90,51,98,64,206,66,199,84,92,5,75,6,178,199,178,129,20,51,224,130,111,195,197,179,103,32,84,104,19,120,74,208,243,15,150,171,250,225,12,189,158,43,9,162,141,185,135,231,85,48,101,3,5,74,237,50,153,165,40,249,248,215,0,251,114,34,24,134,26,225,154,44,15,195,135,215,117,62,124,31,32,231,241,235,113,191,239,31,53,145,121,106,4,65,101,221,129,68,48,74,0,196,223,225,48,239,245,178,99,39,84,134,25,204,7,194,46,31,103,19,18,123,72,205,48,92,180,108,113,106,116,217,41,136,41,156,62,252,28,160,176,65,113,51,37,202,209,204,219,58,53,69,125,102,20,181,107,16,186,44,65,186,24,82,80,109,226,2,42,131,38,19,43,6,86,92,145,173,100,16,184,105,81,15,153,153,119,112,176,218,41,31,198,107,43,127,174,11,68,35,8,137,218,17,183,94,102,107,60,13,150,152,39,167,223,6,27,122,3,67,150,101,222,17,89,89,154,215,188,70,62,76,133,190,27,116,200,26,148,5,26,70,13,162,245,26,84,156,177,143,115,16,241,196,140,180,0,29,210,70,100,160,144,14,135,80,216,52,136,2,200,244,120,234,142,42,237,139,35,148,193,27,88,157,17,87,63,81,67,5,182,77,33,115,253,90,194,68,50,192,157,194,244,153,211,223,126,159,201,40,9,243,250,220,21,158,94,213,44,17,62,29,250,173,24,219,5,142,104,95,68,155,134,186,193,101,44,24,36,49,162,89,45,234,6,201,179,163,161,126,137,102,202,179,103,8,126,211,34,1,218,123,21,72,198,220,108,211,186,241,89,193,120,94,157,165,129,53,35,109,149,89,31,194,137,119,128,17,79,192,250,20,116,24,100,184,151,229,7,152,192,88,222,92,2,173,131,79,82,77,0,182,99,175,87,17,124,199,59,4,208,17,38,123,124,242,238,54,74,55,210,189,196,75,25,95,203,185,125,197,85,160,100,230,48,171,99,217,173,94,109,237,210,177,107,247,89,151,6,28,78,144,220,37,121,16,112,178,119,129,182,236,34,71,221,110,8,140,167,0,117,162,86,229,244,165,7,28,14,173,24,104,89,232,64,179,145,12,101,191,187,254,214,173,86,252,240,16,153,68,193,112,208,119,41,109,71,51,243,218,60,119,32,244,1,117,25,196,69,241,9,13,114,105,104,184,173,243,148,236,195,102,247,169,232,118,25,108,158,104,4,49,63,101,232,78,208,33,150,229,165,235,15,192,65,63,36,41,89,117,149,12,102,148,184,115,33,166,240,104,246,199,6,182,115,28,219,205,28,38,225,92,149,41,31,77,24,152,156,192,9,64,157,232,176,174,211,40,150,193,193,73,180,6,114,147,79,15,112,73,16,31,208,166,179,119,217,173,204,79,192,36,14,24,172,172,70,123,117,131,34,77,96,236,115,20,60,174,8,190,70,10,130,11,126,193,191,165,183,177,238,3,5,72,46,71,83,16,26,131,104,62,63,221,130,84,120,151,20,90,130,149,8,167,154,141,126,12,111,129,97,67,101,29,232,199,58,120,81,212,157,71,234,74,230,217,166,72,239,46,165,126,171,160,223,217,167,247,239,186,40,201,200,68,200,89,99,123,223,128,213,175,131,179,50,92,50,216,225,178,203,170,166,226,67,180,162,125,23,221,218,2,183,201,92,47,105,58,64,221,82,38,87,75,237,223,208,51,183,229,20,128,116,101,56,162,149,43,235,104,246,22,125,45,247,62,7,139,56,205,162,185,125,167,147,84,76,231,119,247,251,68,108,29,143,39,106,23,71,58,70,97,126,191,107,211,179,136,100,39,144,59,71,112,180,64,65,192,57,56,255,248,7,228,28,131,202,87,26,232,113,182,209,18,88,32,36,118,170,213,0,183,213,189,154,219,154,95,74,254,102,58,54,34,174,223,57,154,4,122,32,241,88,70,246,73,158,92,141,125,127,124,124,240,225,255,58,24,205,177,189,136,143,225,200,136,23,100,179,207,193,202,185,50,86,59,63,229,103,252,51,127,197,207,249,165,48,230,70,67,147,201,65,205,185,103,53,41,58,52,54,9,42,105,48,67,193,201,161,18,40,28,99,228,24,229,141,101,99,35,130,250,0,87,133,241,32,34,165,56,3,33,29,1,35,14,233,208,72,76,60,60,149,75,162,61,180,127,141,229,124,45,96,244,165,243,219,63,161,182,0,231,101,28,161,89,8,38,142,136,70,215,163,107,211,119,64,50,52,196,166,208,88,18,241,232,74,4,5,65,103,96,141,209,251,18,5,252,156,134,65,23,70,233,12,215,237,2,45,93,246,122,151,3,95,3,103,143,142,228,200,12,45,132,146,183,32,94,103,252,132,133,65,189,238,142,234,120,81,199,152,184,132,119,51,94,124,1,83,22,77,220,98,51,11,10,236,103,162,17,51,40,21,58,210,72,131,182,68,204,94,5,40,78,56,66,9,222,40,95,19,188,232,28,83,213,146,98,120,131,105,49,35,35,218,80,48,54,20,112,34,244,20,118,70,103,47,95,14,174,164,254,17,188,226,173,156,95,98,195,79,121,182,162,160,146,31,225,134,248,10,114,86,169,8,162,108,97,42,249,227,19,5,51,215,25,204,122,97,119,201,231,110,90,106,4,79,143,175,153,129,247,143,64,50,64,35,38,86,235,76,1,169,127,77,210,244,61,120,247,192,245,109,181,129,219,103,173,241,199,100,238,71,0,202,140,81,215,210,206,188,214,249,223,225,154,1,103,44,31,1,239,66,198,18,198,216,158,127,208,104,200,165,83,24,147,222,205,85,44,179,77,58,63,113,131,62,175,231,116,22,36,148,30,105,117,24,135,233,192,66,32,244,10,34,241,173,177,214,169,170,99,171,232,88,247,40,207,208,12,183,180,117,196,168,36,161,196,247,153,249,154,202,215,166,60,128,201,79,35,144,170,13,3,90,217,16,142,144,104,69,243,83,176,209,78,143,137,72,157,201,121,10,222,65,227,44,160,109,124,58,97,67,71,202,134,184,109,247,94,111,99,251,49,47,204,91,17,239,80,213,90,93,195,81,43,137,84,131,61,92,213,174,216,125,91,231,128,4,41,110,114,151,44,130,38,187,86,8,158,78,207,193,245,57,35,169,151,243,207,226,144,255,11,178,198,156,91,251,233,240,179,94,239,12,68,39,143,132,19,45,238,68,121,197,99,22,24,198,95,1,254,95,53,241,255,170,13,255,175,106,248,55,38,207,60,187,255,55,215,108,0,190,187,5,75,87,146,216,0,71,181,223,255,124,252,252,5,46,85,223,155,59,17,224,56,114,103,78,204,76,64,73,57,136,31,18,64,57,78,187,215,30,160,140,89,59,231,137,154,47,85,180,6,38,177,158,139,57,40,16,172,219,199,91,241,24,97,154,115,97,128,136,64,49,185,192,199,202,176,165,16,17,70,68,70,145,213,45,62,236,19,113,12,143,53,221,202,115,54,58,15,199,231,147,7,26,24,192,175,226,161,117,205,248,8,177,243,43,43,129,79,9,73,212,183,226,76,115,68,62,150,222,224,250,81,176,207,170,150,133,89,104,94,222,5,150,163,107,32,198,108,72,186,121,158,44,22,114,110,213,115,101,53,153,5,8,222,32,54,24,239,136,132,217,200,131,20,169,221,81,167,19,243,100,156,248,216,120,202,38,22,114,100,0,105,44,147,186,153,116,129,85,236,30,91,99,188,4,128,71,32,185,66,99,119,207,57,199,94,104,45,16,6,151,118,61,244,250,91,188,120,123,63,67,34,168,218,132,7,129,100,227,14,219,60,28,239,130,189,48,103,101,50,45,64,143,77,189,30,115,214,200,214,154,75,124,5,28,70,190,202,22,29,21,129,18,54,195,240,181,139,211,146,183,49,92,29,39,142,255,86,38,234,9,232,78,198,43,116,87,187,117,67,18,133,66,36,0,145,56,209,22,136,46,205,96,47,104,86,227,228,225,247,2,201,17,111,74,200,0,130,77,137,136,227,60,198,251,55,113,185,218,5,70,165,208,196,214,217,111,243,44,166,107,171,65,12,189,181,68,47,10,195,10,193,28,236,49,145,141,246,154,109,216,249,195,101,208,93,106,189,14,15,14,110,111,111,7,183,223,15,178,252,234,224,249,225,225,225,1,238,28,163,164,237,3,131,45,159,3,123,244,122,115,23,163,0,43,17,40,184,14,216,18,126,231,101,153,34,5,0,83,70,230,53,176,47,243,74,55,39,116,115,100,78,87,27,78,68,208,209,158,194,192,168,61,166,178,4,235,238,17,175,134,47,196,252,209,182,78,234,17,230,78,110,137,183,165,120,198,171,99,61,136,220,41,21,245,195,92,142,235,45,112,22,3,5,199,133,215,118,205,90,50,74,135,193,2,28,105,228,156,5,50,120,175,183,64,66,214,43,107,186,97,169,44,171,58,152,36,113,224,49,66,137,127,21,139,106,112,89,162,167,137,56,61,7,66,158,131,145,159,97,8,115,193,92,232,221,59,99,43,71,193,94,142,129,20,211,123,82,108,197,70,171,16,64,118,44,97,28,50,112,220,212,199,217,111,50,38,47,109,75,124,146,140,18,240,136,67,146,53,189,222,85,48,229,64,249,105,147,248,87,162,162,253,42,236,137,68,219,235,173,3,98,130,33,250,185,54,242,1,12,0,154,194,187,32,48,124,110,80,135,72,91,81,120,141,94,97,207,176,145,171,92,22,133,101,188,206,10,234,178,181,117,35,176,6,187,47,253,232,15,176,81,187,8,95,113,91,207,209,226,241,113,150,182,197,109,27,51,211,105,247,110,231,115,35,105,70,251,130,115,178,221,195,184,229,123,43,0,73,146,181,221,236,141,80,206,129,107,105,47,59,133,124,40,189,26,226,243,171,155,208,222,133,163,36,210,131,141,90,25,147,215,23,97,2,30,96,192,214,4,225,131,220,173,128,215,63,182,136,97,69,92,163,44,223,7,185,141,106,249,72,123,144,219,107,67,19,16,216,179,177,204,34,228,130,183,55,5,109,98,24,48,100,116,98,110,204,36,186,61,33,143,202,224,31,201,217,6,153,137,142,48,208,188,23,101,198,16,115,175,247,53,200,41,10,198,167,245,91,161,206,94,104,113,56,117,166,130,221,230,218,92,127,50,90,84,84,55,151,46,88,91,161,249,139,11,167,213,125,242,154,159,103,118,227,187,255,20,212,227,96,200,39,67,220,180,209,111,216,134,146,16,182,211,66,1,57,51,87,88,57,30,12,221,166,25,53,190,65,85,247,9,216,75,138,160,3,252,152,67,3,35,222,94,6,43,115,88,99,9,78,96,130,119,48,113,117,125,56,125,112,125,72,163,71,227,124,18,38,102,169,233,96,145,228,133,177,172,92,102,195,180,46,91,205,13,213,198,142,204,97,28,93,39,54,6,98,136,248,34,216,52,208,240,214,68,233,127,34,228,189,173,53,124,108,203,224,32,51,79,27,217,196,254,189,100,14,123,58,255,127,9,29,115,96,38,82,242,27,14,8,215,116,117,151,97,193,93,80,213,54,245,212,236,150,174,255,197,61,102,73,104,209,133,199,73,183,159,246,251,148,88,193,193,112,45,96,129,60,172,140,149,218,61,70,149,190,16,104,182,227,224,37,110,147,121,163,179,157,158,251,128,54,17,226,158,89,12,146,84,210,69,243,20,3,9,24,17,195,94,188,173,171,168,249,56,46,86,190,51,61,91,93,77,81,7,165,74,169,48,130,148,228,7,149,208,32,109,51,202,200,118,61,228,120,225,143,198,151,93,104,51,107,76,43,221,189,203,208,37,6,181,9,148,97,123,117,125,67,0,195,154,2,169,178,150,170,193,65,216,147,96,164,243,198,60,4,100,127,159,54,226,211,84,228,192,161,159,124,217,129,59,185,122,248,9,164,51,16,147,137,214,114,141,103,46,27,7,107,104,220,93,152,17,157,15,53,121,130,67,50,0,115,42,199,152,221,128,171,144,248,196,250,76,228,141,176,155,139,14,100,109,33,137,211,60,207,114,146,232,96,69,82,109,240,120,63,186,205,74,72,222,206,157,100,207,27,190,237,9,74,105,163,32,246,107,81,247,148,37,198,166,252,12,137,51,41,115,114,84,114,43,228,129,164,149,208,59,189,204,179,91,112,215,119,32,180,14,249,180,113,202,181,80,34,93,148,250,188,39,85,223,250,142,223,213,156,99,183,65,209,228,30,147,112,35,173,3,71,52,69,33,48,87,66,157,77,132,134,99,71,174,54,116,5,43,120,124,143,214,139,95,138,106,8,101,124,81,232,82,209,62,106,72,176,195,172,211,226,182,99,39,71,27,94,187,55,240,192,137,178,193,67,190,14,176,10,89,160,190,63,160,148,88,62,198,104,118,50,83,36,54,170,150,89,58,150,121,100,98,27,129,92,241,28,229,66,210,166,119,128,218,87,73,33,71,246,89,27,172,151,82,13,102,192,65,129,107,3,139,43,75,183,18,220,239,16,142,228,83,178,146,217,70,163,4,111,23,106,0,57,134,124,159,105,87,218,113,155,103,66,247,147,120,124,191,241,27,254,154,255,194,223,64,221,239,8,227,207,248,243,87,19,43,230,127,179,209,147,191,123,255,148,255,195,176,14,87,64,103,206,198,169,18,17,181,170,188,202,165,209,186,203,224,134,43,254,166,44,225,240,222,216,85,167,226,6,90,206,64,94,210,19,25,56,132,101,49,175,109,60,217,249,123,103,245,146,220,103,239,162,211,11,33,28,6,124,9,127,6,134,192,170,177,154,84,202,64,214,137,252,141,56,226,83,21,92,43,94,15,211,79,149,51,42,12,44,0,244,111,160,39,158,211,29,213,116,0,130,143,119,166,198,45,54,55,232,99,57,162,139,135,107,101,227,243,128,101,190,175,27,52,193,250,97,68,191,206,50,135,39,199,24,128,198,91,63,112,242,58,116,193,65,179,126,128,105,13,248,71,147,137,137,148,87,130,228,30,165,180,173,21,55,188,115,51,216,48,171,180,69,83,208,145,85,104,192,69,84,90,177,208,49,120,206,133,111,64,212,45,146,84,203,188,169,27,106,196,18,239,76,166,66,142,183,27,249,93,91,63,202,21,251,176,243,23,188,29,186,32,55,78,33,170,58,3,18,173,157,128,171,57,244,66,170,53,98,105,111,153,63,84,153,168,132,177,161,183,10,63,144,129,248,193,101,121,57,67,153,110,2,193,35,5,95,31,99,9,188,19,116,18,67,29,177,13,0,226,61,61,116,105,7,143,237,134,128,79,97,113,148,1,45,182,170,92,96,215,155,182,136,230,176,181,182,237,88,156,204,112,132,150,13,125,194,90,110,187,241,76,76,119,0,124,242,0,202,29,127,4,46,16,246,206,98,64,228,24,59,181,162,238,220,178,96,131,182,191,103,195,142,54,194,121,166,136,252,206,184,172,101,136,76,7,137,144,252,198,18,138,149,106,211,122,152,38,107,155,246,135,127,121,218,182,41,55,77,86,125,193,99,213,136,253,238,167,159,162,197,48,174,167,198,164,30,217,111,196,95,120,214,54,186,213,213,11,192,204,11,88,141,133,43,54,8,140,109,9,150,55,244,242,206,32,222,111,180,116,246,237,148,221,192,108,10,238,142,249,11,126,25,210,53,30,232,102,212,255,21,224,113,93,129,58,100,254,135,151,123,128,75,73,184,212,204,132,20,191,128,2,100,28,172,41,161,93,0,147,158,95,76,96,177,154,56,106,170,128,55,226,63,219,145,10,182,1,195,108,27,63,176,168,201,177,27,103,106,141,73,42,160,4,179,32,254,23,171,172,180,24,19,139,92,22,152,36,39,139,96,69,5,169,233,174,237,6,111,224,235,118,42,250,215,117,104,23,94,91,108,10,249,163,156,109,174,190,24,35,118,175,34,64,249,187,119,215,186,174,1,108,161,59,58,4,28,9,80,0,85,226,146,33,195,155,135,38,21,169,158,7,181,117,38,158,26,45,102,93,71,124,231,18,68,53,89,208,224,241,161,100,175,155,188,216,100,206,31,4,119,45,101,94,185,140,87,15,229,17,9,89,146,164,149,141,170,73,35,110,237,229,46,94,174,19,99,173,156,5,106,141,87,107,196,90,186,193,14,20,153,130,167,24,31,242,195,9,51,178,179,123,222,237,35,132,253,238,51,44,28,77,250,253,93,77,208,215,146,213,17,60,7,131,26,42,241,123,149,120,107,165,243,57,134,253,80,179,80,12,216,75,8,39,208,239,148,241,226,155,181,87,245,90,188,216,48,230,105,198,238,235,181,54,52,157,81,87,140,11,147,213,209,176,192,110,76,112,226,175,189,222,95,17,243,52,34,111,244,248,91,175,247,55,52,192,126,179,182,133,22,193,141,141,152,224,82,248,69,67,240,26,20,194,205,136,16,69,235,222,212,1,120,228,54,13,101,171,187,81,51,90,138,192,252,34,126,182,74,73,1,59,58,142,7,131,204,204,222,192,139,126,128,19,7,1,112,198,107,113,131,219,49,102,85,99,71,127,239,245,254,238,188,48,155,209,61,148,230,170,225,204,50,153,193,182,179,139,130,35,32,144,223,141,132,69,241,251,11,69,47,115,121,179,145,133,126,165,146,85,132,83,255,148,71,43,188,146,9,126,121,172,145,149,229,74,177,96,142,190,138,91,229,49,236,36,22,55,103,136,7,139,26,128,226,231,58,202,190,96,189,67,146,195,30,34,11,55,111,132,38,97,36,222,227,187,105,139,15,235,168,239,33,229,45,133,173,127,212,186,33,94,43,203,43,101,221,95,67,140,178,125,33,101,76,215,64,185,163,66,11,99,90,81,171,244,212,10,245,255,232,245,254,97,34,131,220,91,195,141,179,84,224,43,40,229,79,147,79,237,121,218,156,237,51,171,43,31,199,52,238,251,142,0,175,174,132,132,162,197,105,160,195,174,52,130,10,225,51,55,208,96,229,224,146,91,213,26,236,106,59,254,202,140,95,85,194,149,203,186,103,31,167,50,202,173,223,1,202,156,111,97,123,113,164,98,153,54,167,66,87,171,242,80,136,115,167,162,86,33,65,88,31,2,78,148,73,236,111,131,6,211,8,107,31,147,212,245,19,119,92,209,150,81,100,143,46,246,136,65,77,127,211,248,216,164,62,215,208,116,198,223,96,175,223,172,161,76,59,10,243,190,12,203,145,60,54,69,140,73,237,17,81,35,94,137,38,235,88,78,26,87,94,215,141,137,219,190,93,26,81,110,145,222,33,144,39,106,207,182,244,241,187,33,230,196,97,66,177,21,224,153,56,26,102,85,146,63,134,105,77,158,44,230,45,246,251,19,240,20,49,105,17,4,33,140,43,69,50,58,10,159,99,174,29,53,78,96,189,113,191,159,77,134,120,211,149,140,208,202,22,155,240,7,251,114,52,17,230,6,98,16,21,69,2,40,196,42,12,74,240,13,11,95,80,39,170,18,174,158,141,205,116,56,201,95,252,36,174,178,47,54,253,110,55,132,65,24,103,142,214,235,244,46,216,240,19,220,225,6,118,56,238,118,201,136,154,16,153,147,96,203,25,223,96,50,165,129,253,57,200,219,113,246,236,57,108,159,18,49,69,14,34,216,246,220,248,11,128,233,142,127,83,148,35,244,62,90,87,228,125,90,35,128,111,10,99,54,198,121,247,102,3,42,85,55,12,102,64,191,204,152,230,26,224,129,38,128,211,188,210,88,101,174,135,176,19,230,90,215,185,215,171,119,60,53,112,70,115,1,27,203,240,39,17,104,65,108,26,189,49,213,132,18,45,97,190,92,228,85,114,223,63,127,45,190,251,85,193,79,233,10,79,15,174,40,197,145,141,18,179,105,144,175,60,103,116,75,105,167,200,193,120,180,141,223,83,35,64,240,156,133,207,77,143,238,96,48,192,171,154,28,228,147,155,227,7,232,118,232,123,64,75,199,55,189,224,135,28,12,59,88,97,250,82,188,192,47,126,242,178,236,0,251,226,209,227,7,78,110,169,41,116,204,209,177,153,138,191,80,128,166,106,128,201,93,3,35,76,236,40,12,145,30,171,42,39,26,40,54,69,133,102,64,216,0,75,110,130,148,49,79,226,49,12,136,143,213,56,157,184,49,49,140,129,195,130,154,49,152,170,52,112,212,61,166,44,209,81,128,19,0,166,19,112,165,197,247,44,204,251,66,19,69,67,151,103,207,236,246,187,47,109,103,119,64,208,79,232,126,142,62,124,54,210,152,255,59,194,35,51,163,255,220,253,51,246,46,203,238,159,205,176,12,42,253,20,184,30,76,3,88,194,239,10,132,159,248,5,136,172,220,78,222,61,160,106,148,252,199,47,96,30,26,107,224,239,31,77,152,153,196,157,99,34,240,150,15,39,77,184,123,49,248,124,14,216,156,98,3,156,88,247,73,215,2,245,171,246,37,229,75,121,3,186,231,6,15,126,141,110,199,163,2,32,253,129,219,85,28,15,17,10,119,38,27,159,241,42,78,143,70,140,11,227,31,141,116,136,124,73,242,234,76,137,83,27,183,90,26,181,247,89,209,87,162,62,67,93,253,159,63,87,61,111,134,108,0,147,7,193,40,252,117,20,140,255,249,167,201,119,192,5,193,159,6,223,177,209,211,3,96,46,53,88,145,166,164,204,124,88,23,236,216,172,215,203,48,101,216,173,184,17,248,74,81,106,29,116,123,93,102,9,113,211,32,68,67,111,27,164,53,219,83,96,30,243,120,46,227,108,46,63,95,188,245,142,121,16,35,198,38,162,173,197,230,20,31,177,193,111,89,162,104,14,182,83,226,22,118,228,25,60,119,233,202,80,171,233,70,217,19,124,36,222,71,122,9,91,250,22,56,54,225,78,194,227,221,251,225,176,56,142,134,133,201,108,208,227,2,115,164,67,147,35,93,76,6,241,50,202,95,233,224,208,6,143,22,166,214,203,149,224,159,97,57,238,127,55,154,244,159,50,35,80,248,90,208,44,22,135,7,182,245,0,68,220,103,197,80,244,2,116,124,41,254,123,237,67,251,221,62,12,155,55,106,190,131,154,45,208,116,65,221,201,221,193,75,98,252,94,166,214,107,212,101,199,135,101,185,4,224,166,24,44,242,41,20,9,126,61,213,130,203,45,227,160,111,231,236,158,58,40,139,217,130,1,176,235,224,97,127,135,241,131,174,77,96,219,249,148,114,220,34,105,230,98,210,88,220,80,94,208,193,120,184,116,223,254,98,102,114,199,72,185,164,150,232,191,31,109,205,35,117,13,202,23,31,160,88,205,251,75,251,254,12,43,104,227,207,180,121,214,242,247,247,39,162,118,240,244,205,20,173,193,123,235,85,91,0,71,135,33,145,147,169,92,3,189,24,148,252,168,28,10,186,12,57,152,219,46,181,92,233,230,172,53,194,248,245,160,95,194,127,71,23,142,3,0,151,181,100,233,218,104,34,58,85,17,220,232,168,223,253,174,63,234,86,55,64,174,77,249,15,73,24,80,213,15,225,11,146,26,159,80,70,240,11,133,134,246,59,250,125,175,140,239,247,21,90,54,121,26,190,5,3,116,199,191,40,241,52,248,10,246,116,117,231,91,185,216,133,10,190,40,114,175,21,28,224,87,175,228,49,38,0,12,63,204,91,99,33,239,148,191,30,104,109,180,151,89,239,148,223,139,198,219,44,23,142,50,29,199,138,127,172,199,161,223,122,168,220,231,196,221,126,0,96,189,7,149,248,94,81,110,17,246,27,213,202,161,109,195,171,66,19,88,122,87,235,245,176,54,0,193,191,1,136,22,137,146,243,234,210,221,79,237,231,253,4,116,128,84,161,200,1,132,211,236,227,183,22,96,201,99,28,164,91,63,209,143,77,90,244,119,67,154,236,116,202,215,176,95,134,116,106,23,52,106,0,231,67,61,60,9,113,252,242,25,106,155,113,242,42,218,113,225,117,190,198,196,20,56,177,11,252,132,96,0,206,196,69,134,89,253,138,85,161,108,91,56,218,209,7,201,123,119,80,77,16,187,120,146,32,125,12,42,97,198,17,253,162,53,221,134,43,48,226,116,150,223,245,122,182,48,214,253,46,69,224,187,147,182,186,160,246,177,41,114,20,215,163,174,221,48,208,191,93,250,169,106,252,209,132,167,123,59,199,228,94,144,218,242,184,66,129,4,233,125,129,234,111,144,227,222,63,101,180,79,68,248,97,219,55,120,191,249,224,57,162,254,170,150,194,86,5,210,235,181,129,249,214,131,145,219,212,108,208,160,207,165,54,95,231,208,229,172,21,251,192,254,7,244,97,119,71,98,102,179,171,157,142,10,153,46,158,30,36,213,23,94,31,233,202,188,2,238,166,41,81,0,131,235,183,171,149,156,39,128,64,204,190,142,174,136,38,17,242,199,218,2,202,65,132,198,150,254,251,221,214,57,125,137,241,163,17,132,80,5,84,226,97,121,237,16,213,65,233,163,243,244,23,121,135,78,220,74,234,200,22,163,84,219,18,197,189,108,25,144,163,51,197,42,116,26,60,13,231,25,125,28,21,145,126,173,242,3,17,113,109,8,55,151,0,131,101,84,212,154,48,177,238,153,130,29,108,101,151,161,247,216,108,118,45,22,191,120,48,191,33,138,29,190,9,191,59,155,219,139,225,192,218,135,139,59,146,164,191,40,212,103,30,9,111,108,84,195,147,122,128,130,213,189,178,218,253,171,17,179,196,182,101,73,210,118,7,166,218,27,85,93,73,154,207,45,248,125,235,189,68,248,80,81,117,14,233,198,6,103,79,48,121,21,167,118,151,194,70,89,209,90,106,144,169,147,37,102,6,54,27,93,237,142,59,177,240,32,35,67,139,179,160,54,194,165,19,120,182,169,190,12,165,36,12,186,134,219,113,203,102,141,217,12,30,252,5,28,161,98,231,82,33,76,218,81,37,155,26,89,32,107,56,69,124,214,110,145,3,252,116,149,63,252,78,34,172,41,24,51,22,120,188,214,209,125,19,81,239,103,163,199,208,123,248,11,122,134,120,190,135,32,224,202,242,193,71,104,221,53,32,129,68,21,175,235,57,16,65,120,156,20,201,122,56,38,6,237,118,221,229,175,209,194,191,112,170,16,221,97,18,162,6,187,27,129,122,138,134,212,3,29,254,6,195,235,48,64,197,80,121,49,134,58,79,238,171,30,89,87,61,140,194,129,14,21,71,123,56,179,185,37,117,108,180,69,75,8,66,123,39,143,238,202,133,215,217,23,53,157,77,91,2,181,205,91,110,239,254,133,115,121,188,35,64,125,181,151,87,132,28,102,227,145,31,64,249,210,159,121,184,84,149,85,111,52,64,67,1,216,155,53,84,3,224,222,156,99,24,105,90,179,232,220,139,185,161,181,210,96,12,158,208,100,7,244,76,105,6,123,48,216,128,35,125,45,238,56,137,227,223,233,0,210,6,207,200,144,52,134,132,12,103,156,5,85,54,14,195,175,20,241,219,100,114,9,63,6,24,120,225,32,11,224,31,49,70,198,73,35,200,34,148,224,31,29,77,40,51,227,30,255,172,141,187,222,148,139,176,138,141,115,252,203,33,1,221,114,162,73,192,238,97,158,175,202,195,32,236,156,40,203,147,108,83,132,174,39,119,87,127,83,142,40,8,167,163,58,70,76,114,156,7,4,179,99,12,225,229,38,237,42,25,68,49,202,82,112,246,199,211,73,56,158,120,236,167,226,93,21,114,64,243,227,29,186,223,120,233,222,22,81,196,132,192,32,241,254,240,18,76,76,159,162,196,239,205,247,110,201,142,178,67,141,184,248,93,181,217,236,75,212,27,136,196,123,56,12,100,185,240,181,218,113,188,22,228,63,63,50,160,150,105,133,98,107,40,191,173,129,144,238,239,158,68,197,19,47,124,249,10,95,127,202,163,43,74,50,252,93,225,235,187,68,93,195,180,88,36,145,197,223,84,229,156,127,196,114,156,194,112,151,154,248,148,106,40,121,220,38,168,241,101,85,229,122,109,171,170,11,185,224,231,52,167,252,38,99,254,150,138,149,137,250,25,14,111,201,207,168,22,179,164,249,91,42,221,205,115,188,88,159,226,75,82,124,137,210,100,238,230,214,88,103,50,136,11,254,19,190,24,162,6,171,154,94,104,23,103,88,212,25,37,210,81,190,52,143,168,117,83,200,147,40,77,103,81,124,205,11,95,99,55,178,112,21,213,133,34,207,93,221,233,98,33,99,205,215,254,29,147,181,94,131,208,153,71,249,29,95,186,234,183,115,158,250,242,106,45,115,210,210,103,145,154,167,192,83,174,229,93,116,7,96,218,41,99,87,251,94,174,50,62,117,111,23,114,190,137,97,91,155,170,98,193,127,242,47,230,128,164,123,39,101,180,27,254,15,228,255,0,84,79,76,0,0,0}; + +static const unsigned char v1[] = {31,139,8,0,0,0,0,0,0,19,237,93,235,115,219,70,146,255,238,191,98,162,242,45,169,181,0,225,77,64,182,148,114,156,77,57,85,246,94,42,78,244,37,151,59,67,36,40,34,198,131,7,64,148,100,133,255,251,245,175,103,0,12,64,74,206,195,187,117,167,219,84,12,14,230,61,253,238,158,38,53,185,170,19,81,55,85,58,111,38,207,159,164,249,186,172,26,113,39,86,71,162,74,138,69,82,29,9,234,240,174,137,155,132,75,127,91,46,147,121,195,197,239,147,229,145,88,53,121,118,36,190,47,175,154,164,18,91,177,172,202,92,136,137,121,124,113,85,44,178,196,252,165,166,73,159,28,31,139,215,73,182,166,30,203,171,98,222,164,101,33,154,85,220,208,10,205,85,85,212,34,22,107,26,151,210,70,84,117,93,102,155,132,234,151,152,117,145,100,241,237,147,121,89,212,141,248,26,101,113,42,166,121,125,36,54,113,118,40,78,207,68,145,92,139,239,228,4,83,53,22,213,117,210,252,144,230,9,109,173,173,61,18,237,176,67,218,85,114,195,103,149,19,127,139,15,154,248,238,137,16,171,36,174,154,19,236,105,93,99,34,156,241,253,139,122,115,41,230,89,92,215,167,79,239,184,201,228,183,173,184,201,179,162,62,61,88,53,205,250,228,248,248,250,250,218,188,118,205,178,186,60,118,44,203,58,166,97,7,98,153,102,217,233,65,81,22,201,129,216,164,201,245,87,229,205,233,129,37,44,225,120,244,255,193,217,139,117,220,172,128,133,242,67,98,100,105,145,204,227,245,233,65,85,18,16,15,244,234,95,202,180,24,215,95,167,139,102,117,122,224,28,136,197,233,193,91,207,116,237,80,4,120,198,158,233,11,252,163,133,44,11,117,129,247,198,118,132,99,161,148,205,204,32,116,12,126,14,122,26,220,209,232,186,83,15,55,200,12,27,83,202,231,158,238,194,250,72,167,56,198,49,232,131,206,124,246,254,136,32,185,40,175,139,151,85,85,226,192,255,76,128,142,96,99,155,126,91,117,122,48,191,170,136,178,155,87,101,86,86,7,103,226,15,129,30,144,142,68,104,58,254,235,153,233,199,14,21,4,63,24,34,221,235,38,26,53,117,111,171,125,45,60,112,99,140,155,140,174,237,181,237,211,178,182,147,185,194,205,169,41,115,13,55,55,232,229,28,173,7,226,152,142,211,3,255,106,253,47,208,127,78,208,231,150,225,102,6,64,14,208,3,236,57,189,156,219,59,128,159,151,151,143,14,226,166,31,121,194,53,35,111,110,90,145,97,250,158,99,250,129,65,239,194,54,109,27,133,21,213,68,238,220,244,1,58,219,36,176,186,81,200,173,212,152,153,142,237,210,139,19,218,52,65,224,154,238,12,146,202,37,233,19,152,129,231,155,225,204,180,168,202,242,76,219,163,98,232,154,142,99,218,206,204,116,29,170,138,2,115,6,44,204,48,241,204,167,6,47,163,201,236,153,97,122,126,16,211,34,132,48,249,36,184,208,138,238,204,244,34,116,137,2,96,211,155,237,244,49,76,39,160,87,207,181,33,219,44,203,53,67,103,54,167,218,136,150,246,104,94,55,52,3,219,69,129,14,16,57,49,109,193,143,132,124,98,2,75,208,134,124,26,97,89,180,203,89,104,218,52,130,246,230,17,148,176,180,101,209,169,156,112,110,122,116,2,215,55,125,215,51,35,223,107,151,197,170,14,1,232,158,221,209,17,130,136,206,192,187,107,15,74,139,185,190,111,208,74,180,175,25,21,172,153,131,205,207,2,64,132,118,72,0,226,135,58,32,32,24,98,16,29,193,14,105,140,31,210,210,17,13,12,60,207,12,131,40,51,58,188,224,32,132,101,15,189,2,194,24,182,192,168,179,87,6,48,235,81,7,160,22,235,57,6,112,107,180,152,151,179,24,18,187,52,77,128,246,25,193,208,181,169,68,24,230,245,12,194,49,182,232,8,126,180,91,52,128,101,236,209,193,193,34,234,75,103,2,170,229,193,12,198,181,132,193,94,92,75,72,25,64,55,67,116,102,236,135,40,193,221,144,232,6,106,176,27,90,150,250,99,49,143,234,9,194,132,110,19,231,151,216,142,92,236,20,79,198,182,193,216,6,178,113,184,16,72,8,37,18,228,16,73,69,60,111,184,151,216,120,245,236,161,45,130,108,13,198,57,142,27,48,198,9,225,1,240,77,43,1,30,142,232,161,194,216,39,142,1,203,80,141,69,44,36,193,25,18,194,81,32,38,242,73,197,3,227,10,1,132,113,154,217,147,168,250,40,229,214,31,21,9,54,109,221,137,73,10,130,221,109,35,160,15,249,98,217,1,204,129,145,80,36,107,172,73,139,203,250,245,99,19,141,182,69,150,80,176,138,8,67,170,76,136,5,90,125,9,24,2,73,78,255,244,74,11,149,111,129,83,17,64,139,81,187,237,240,12,185,129,231,160,183,181,111,10,139,167,32,221,207,189,121,142,200,8,86,46,79,225,254,174,41,228,130,188,250,125,56,59,127,108,56,35,17,76,188,113,206,224,178,4,142,62,128,150,5,243,202,112,7,192,226,58,129,17,231,196,154,126,78,162,205,253,83,19,24,129,17,181,19,184,191,125,130,136,39,176,204,93,100,205,227,226,177,225,137,232,154,97,243,58,120,57,52,204,36,239,108,104,209,183,0,166,236,100,135,195,94,54,121,58,142,234,6,200,157,239,116,32,87,137,251,172,12,116,49,72,177,143,87,178,121,37,59,220,24,188,214,111,150,121,66,250,63,73,253,161,41,215,143,13,45,228,131,204,96,47,67,227,205,226,22,2,80,240,145,128,205,225,188,1,226,28,123,5,3,35,112,108,126,188,108,251,1,136,176,223,103,231,60,75,78,154,209,33,43,122,104,122,219,189,41,255,218,167,199,24,43,194,246,207,81,159,19,10,173,17,113,216,176,195,132,187,103,156,229,138,110,208,57,97,242,119,46,233,240,146,99,198,139,179,228,159,27,46,248,167,104,53,178,15,97,110,195,22,39,56,145,117,236,17,175,200,15,0,146,236,92,223,227,112,192,203,208,140,130,153,144,79,197,84,16,82,27,178,142,206,163,151,129,8,120,64,32,162,13,164,220,184,55,1,157,204,68,178,180,44,199,153,219,230,140,76,157,0,158,134,15,51,217,10,125,129,149,32,4,93,59,247,205,153,237,145,18,35,219,135,140,49,161,62,120,22,213,212,117,233,120,84,85,144,182,37,147,73,16,93,242,126,35,33,159,24,235,195,10,36,217,10,235,15,108,28,143,59,16,73,7,33,2,30,99,204,95,36,89,246,47,196,255,63,68,124,149,44,171,164,94,61,58,220,3,25,46,33,209,245,194,149,7,63,104,3,247,214,126,235,152,17,33,196,142,224,70,108,12,110,65,16,68,246,201,185,194,69,56,138,124,14,91,224,233,198,144,240,28,166,145,34,153,8,200,114,97,153,190,37,191,197,181,105,141,48,240,135,157,236,190,147,54,19,45,196,243,219,27,60,119,52,236,69,92,213,222,99,195,3,219,28,80,53,43,105,41,178,137,67,100,248,27,94,119,68,20,193,199,125,148,240,65,36,134,143,44,95,201,129,210,192,209,1,111,12,143,172,188,44,175,30,159,182,118,24,4,126,214,71,39,169,64,162,112,101,144,224,123,235,216,48,91,35,17,73,201,8,235,71,200,55,22,218,123,156,245,120,147,60,58,24,181,126,2,187,95,184,217,176,161,70,160,25,4,106,164,47,6,23,224,126,63,194,185,199,127,184,207,107,56,31,215,7,188,131,21,188,13,90,105,101,68,99,200,39,121,156,62,58,155,194,177,91,134,221,192,115,189,215,236,38,55,108,111,35,63,206,49,62,39,29,228,239,26,252,145,146,128,59,227,181,27,1,53,116,99,58,158,59,94,4,65,53,178,52,34,59,200,192,48,52,87,176,111,39,46,25,9,111,92,211,117,96,35,216,251,38,49,120,18,222,234,14,102,111,214,113,177,120,108,168,101,66,199,131,212,179,207,170,218,95,161,100,240,253,224,27,146,50,178,11,179,9,76,7,120,226,59,157,108,146,81,204,99,204,29,220,139,155,250,73,223,144,215,24,229,16,235,36,193,152,84,250,78,253,172,232,181,123,31,83,175,170,180,248,240,216,32,79,160,61,167,35,227,243,181,250,124,211,97,3,46,58,163,132,11,175,219,66,102,48,4,241,64,44,35,2,22,184,112,222,22,50,180,25,109,7,219,111,123,216,26,130,179,110,146,49,164,203,223,1,229,207,5,66,17,87,105,108,172,210,197,34,33,0,53,213,85,242,39,67,27,208,165,111,152,200,4,31,156,157,154,223,175,67,151,143,80,144,115,172,24,143,76,165,0,40,130,48,212,235,239,135,210,213,58,43,227,199,39,21,217,162,216,56,187,1,40,102,29,199,94,33,254,60,106,2,236,194,62,60,140,30,70,4,59,69,154,116,45,136,81,177,65,227,110,180,177,188,46,254,5,205,125,208,148,198,159,237,176,213,23,176,182,176,56,70,105,59,185,130,235,185,187,235,91,150,217,163,243,20,164,97,74,224,202,96,137,25,44,230,24,42,244,182,130,39,254,134,121,92,90,108,168,167,174,175,49,104,135,115,87,101,254,232,124,4,166,30,219,201,66,220,212,27,120,250,115,211,227,108,128,8,23,181,190,211,22,253,200,38,18,106,193,244,22,68,20,41,251,214,118,252,185,37,16,242,54,125,203,19,250,45,47,63,95,203,32,153,103,134,51,234,104,180,29,13,173,139,44,175,176,157,57,218,57,163,130,106,198,19,158,19,237,123,188,160,222,203,232,187,201,137,206,89,131,133,138,89,194,161,226,150,180,158,61,66,11,137,104,215,70,56,47,8,7,41,107,160,121,15,121,109,142,231,117,154,107,208,65,79,129,203,128,98,216,245,244,68,164,208,69,246,132,227,232,213,247,166,207,237,157,221,210,150,223,65,67,189,74,147,236,209,9,240,251,140,170,220,112,201,221,178,220,224,37,50,77,252,72,168,15,233,65,251,81,40,2,174,138,212,83,222,224,208,72,47,34,14,35,110,64,248,214,12,233,32,196,118,14,236,12,234,23,56,184,228,177,103,72,184,112,201,85,139,8,23,24,101,112,155,195,25,44,46,50,50,224,209,249,51,42,209,66,124,103,110,175,12,176,248,220,0,221,144,171,71,3,225,213,57,94,104,128,103,168,218,9,253,221,75,62,132,216,160,122,31,27,214,92,25,84,68,144,132,202,145,204,112,112,89,35,200,92,5,106,6,129,111,108,71,197,156,144,14,195,222,7,95,236,145,172,121,3,45,60,219,39,111,98,164,38,62,70,168,145,206,100,152,176,141,145,33,16,96,4,12,18,7,241,115,50,149,187,170,253,48,185,122,116,183,197,234,228,27,67,193,132,15,47,90,160,192,125,232,42,198,54,198,117,92,61,70,2,137,54,174,202,245,113,73,50,33,25,18,169,125,97,128,155,47,31,153,110,92,7,21,30,121,161,44,131,15,103,54,223,147,97,183,102,200,9,119,97,219,201,224,78,111,108,100,104,70,60,34,148,51,34,109,129,26,45,215,81,165,144,164,42,25,46,102,16,205,96,10,219,78,240,145,49,228,35,242,130,251,252,13,61,194,215,182,188,250,9,119,204,190,180,88,150,143,14,37,118,23,87,202,76,203,35,149,96,57,49,114,57,103,173,193,128,148,213,208,119,50,195,156,89,200,217,12,221,64,235,96,181,29,220,110,184,253,105,87,152,240,207,210,18,80,15,91,168,159,67,211,236,0,61,185,33,120,230,49,190,57,241,67,149,198,197,101,246,232,76,239,255,227,108,209,172,174,242,139,31,31,157,236,14,204,192,117,217,57,156,155,161,21,176,135,225,35,251,216,243,144,88,109,185,28,246,14,227,8,116,47,228,83,222,156,135,1,236,43,111,110,206,28,234,238,134,192,8,108,231,136,239,247,3,31,120,154,217,176,140,189,8,119,236,120,130,149,76,215,1,78,130,153,115,238,234,60,200,169,182,179,113,82,78,123,247,57,183,90,247,204,145,9,223,72,144,118,64,68,142,29,162,146,250,249,161,105,115,152,223,9,201,26,101,23,138,74,43,228,7,4,115,100,53,203,227,69,158,79,84,224,225,116,62,54,77,155,164,99,249,166,231,80,77,16,18,151,227,131,7,251,49,27,172,210,108,109,47,9,2,162,180,153,233,59,72,133,118,195,208,244,144,130,27,133,51,90,50,194,193,44,31,165,215,72,58,0,49,122,33,81,46,117,32,159,193,180,102,72,170,246,0,48,7,95,53,48,109,206,213,181,60,248,15,150,45,228,147,189,140,174,219,107,223,140,44,239,173,188,203,138,216,101,124,203,85,50,252,49,151,185,244,22,44,98,90,17,17,147,25,237,193,33,11,119,102,202,37,65,251,100,4,59,204,4,100,2,71,22,51,73,24,177,169,60,67,14,188,207,95,253,137,56,219,220,13,194,24,156,209,166,112,211,73,105,167,190,53,155,163,187,239,211,106,145,228,173,128,196,164,77,22,162,27,133,175,136,247,194,25,155,233,22,236,74,59,152,177,7,32,164,35,176,162,67,250,46,185,218,51,204,74,246,61,217,246,62,161,140,192,130,164,12,63,20,242,169,142,238,90,176,27,130,64,161,61,162,179,147,161,239,144,185,239,18,101,121,204,232,187,66,244,34,158,127,32,131,226,209,121,87,80,52,4,106,219,70,212,33,4,29,69,224,89,32,27,244,70,232,143,102,51,220,107,217,86,72,216,176,2,103,39,243,28,64,141,72,123,105,125,94,142,251,208,50,236,74,111,136,141,28,247,99,171,52,63,207,202,111,200,64,36,146,32,38,177,247,164,197,171,153,212,202,59,95,183,89,165,143,78,238,114,172,198,229,252,86,132,13,248,235,78,46,167,45,114,170,42,87,218,142,94,149,147,121,45,211,96,245,126,60,15,172,239,115,178,72,100,228,152,163,159,54,42,114,118,216,236,112,80,103,64,72,17,67,238,220,211,90,195,155,216,251,191,41,21,236,136,105,11,219,189,231,250,183,255,98,214,199,156,183,227,172,162,77,180,50,162,141,17,237,162,58,206,147,42,126,108,200,14,240,93,20,130,143,205,112,115,109,193,15,153,161,102,135,1,66,69,46,43,19,104,36,40,65,98,40,27,162,216,118,61,12,122,229,152,81,196,74,39,148,96,13,33,142,101,145,80,63,243,206,237,240,222,111,195,217,187,129,115,149,187,192,67,89,168,91,193,140,191,234,130,32,12,20,82,104,57,6,114,227,162,216,155,33,143,75,168,15,37,158,105,91,6,246,37,134,135,129,72,96,117,230,147,23,76,71,102,101,98,7,49,116,17,164,55,158,106,134,153,11,11,205,114,35,225,145,18,35,107,78,125,112,179,207,210,222,18,251,199,9,30,199,11,216,156,60,24,252,217,239,185,200,171,3,144,124,31,197,35,131,30,150,188,30,52,164,119,18,138,156,122,204,193,244,206,170,95,177,197,200,57,251,59,4,205,46,127,253,216,8,90,102,127,191,113,199,119,45,234,38,135,175,107,114,139,111,184,16,33,154,169,78,10,210,111,101,21,190,212,50,6,215,162,156,63,54,88,113,86,10,91,111,27,24,143,142,31,179,245,34,109,24,73,215,92,148,79,150,234,59,170,25,128,36,144,217,152,131,218,31,156,225,53,84,66,46,185,157,108,71,90,112,110,200,203,3,163,187,98,208,175,34,54,28,191,123,240,66,99,197,220,241,137,43,8,54,23,148,59,76,59,138,148,116,239,144,187,29,127,35,191,73,215,12,220,246,91,249,151,85,146,20,39,98,114,113,105,112,209,176,45,75,52,201,77,163,94,35,122,173,210,162,109,117,45,107,2,146,185,77,178,172,188,150,227,100,185,31,168,222,187,145,234,189,29,90,37,11,57,142,10,253,32,188,116,35,240,34,187,107,251,239,126,228,224,171,171,166,41,139,233,93,147,54,89,114,36,202,98,158,165,243,15,71,98,145,214,241,69,150,44,142,136,112,235,35,145,210,129,241,115,11,75,122,231,19,31,137,85,185,73,42,126,233,123,243,235,246,144,129,33,65,244,83,189,78,105,100,157,52,239,168,240,51,1,170,253,173,134,233,50,206,234,228,240,121,215,117,126,65,173,237,198,166,201,70,78,211,182,86,9,160,172,246,39,190,108,75,211,67,113,34,138,171,44,123,206,125,211,165,192,47,41,136,191,252,69,52,183,235,164,148,175,230,60,110,230,171,67,113,122,122,42,38,237,10,147,118,126,209,238,110,138,204,140,195,231,170,178,27,55,157,242,79,56,200,237,154,205,42,41,84,77,59,76,182,168,129,91,122,110,81,196,86,190,144,192,58,84,64,163,3,0,87,23,217,85,98,4,132,31,6,225,73,91,227,83,77,11,200,174,210,35,204,61,103,68,227,119,40,164,60,121,242,226,130,177,198,71,60,61,144,47,7,74,194,28,164,5,152,216,88,102,201,141,248,229,170,110,210,229,173,49,39,49,144,84,34,109,146,188,110,95,46,227,181,225,8,102,243,100,33,214,55,184,106,16,235,91,112,167,164,162,58,23,203,178,160,207,36,79,47,202,108,33,107,175,87,52,139,168,87,241,130,200,144,186,60,189,147,103,219,162,148,213,219,3,153,123,78,146,142,158,219,22,77,244,58,191,216,118,199,163,215,182,40,126,253,85,128,70,182,226,140,70,62,149,132,8,32,190,120,122,135,122,66,53,255,240,133,169,18,218,9,221,32,198,109,123,220,107,195,19,93,207,73,92,164,57,209,150,129,247,9,117,157,76,182,96,225,39,47,142,143,207,222,239,101,128,191,151,4,161,116,206,129,171,233,93,73,164,143,99,130,236,203,58,25,144,50,215,92,52,133,164,225,239,147,229,20,116,167,17,48,255,178,8,161,184,169,226,162,206,176,141,91,130,112,185,142,231,105,115,107,88,162,206,79,244,166,81,5,33,96,210,207,213,148,227,153,172,110,38,240,249,104,168,165,13,253,169,169,152,225,126,168,134,236,70,187,227,205,118,63,145,50,237,152,173,101,5,30,53,109,202,195,231,162,123,87,191,79,146,108,64,242,29,12,136,193,218,178,169,244,140,41,89,243,222,150,233,225,17,25,240,150,197,155,216,30,137,159,126,214,96,7,58,161,65,180,97,185,208,157,218,139,220,181,190,17,238,119,36,92,76,36,57,109,200,27,139,116,35,243,173,178,116,67,220,65,68,146,84,13,21,59,6,249,72,0,20,107,82,114,196,5,70,178,161,253,213,6,244,171,136,47,234,50,187,34,234,78,11,90,143,0,206,60,36,153,38,41,152,71,60,112,72,0,232,203,234,186,137,137,152,232,117,109,4,7,32,96,94,94,45,196,195,175,141,37,81,9,79,101,16,167,12,121,176,38,140,2,183,94,63,35,45,196,19,13,167,26,109,55,190,34,250,80,51,231,241,141,193,156,8,97,178,132,114,144,137,102,45,107,27,217,165,32,105,50,224,91,170,98,221,96,203,143,139,44,38,196,113,177,165,49,146,1,32,175,101,89,229,34,137,235,196,32,208,139,197,85,197,124,2,125,34,219,83,230,33,226,218,106,171,118,61,218,183,225,117,245,123,128,163,1,81,235,182,219,209,144,249,145,134,53,232,197,50,162,252,208,73,8,42,158,168,34,50,219,58,17,177,34,140,93,211,63,213,121,162,105,100,136,87,136,137,78,109,162,66,138,12,109,149,227,227,251,54,151,227,71,54,174,21,169,16,56,215,68,54,100,130,141,118,185,110,187,15,228,106,158,44,210,171,188,181,15,226,91,168,236,131,51,130,37,85,108,95,28,175,239,155,68,161,55,111,104,189,118,194,126,18,31,147,188,44,110,65,208,215,41,25,124,49,39,78,144,95,90,136,162,188,102,27,82,52,171,180,134,101,153,152,163,117,30,62,170,39,57,226,65,140,236,85,77,82,33,180,98,65,215,10,138,239,183,251,180,87,75,192,249,162,39,224,254,160,94,167,64,7,135,39,216,206,175,234,19,34,87,158,136,13,231,225,22,105,147,196,119,69,187,98,93,25,101,145,221,30,156,189,194,70,200,216,163,182,221,1,157,5,79,212,228,19,198,253,177,53,142,255,91,107,253,147,201,159,163,233,133,178,205,165,167,237,132,72,92,213,111,119,164,131,11,183,49,120,19,242,15,154,200,171,108,164,22,204,180,142,182,213,247,179,225,1,82,33,187,183,159,33,251,201,33,22,247,51,134,253,212,194,70,59,33,175,221,109,240,227,136,77,246,208,207,46,65,233,175,218,75,87,84,5,254,96,165,253,124,175,214,126,83,94,146,225,117,151,225,227,27,178,47,241,157,153,111,217,70,85,134,44,153,230,63,128,143,6,182,40,105,62,169,26,127,164,194,64,57,78,38,154,46,250,105,77,136,230,126,223,81,225,254,126,244,184,186,200,211,230,33,179,149,36,245,106,181,168,160,204,191,138,235,116,46,38,226,153,184,104,202,120,138,205,80,121,114,130,26,172,168,12,72,57,110,149,196,139,68,58,22,47,105,138,178,74,63,178,232,61,105,103,220,202,222,74,247,45,19,24,170,147,120,157,30,51,76,38,71,226,78,77,177,85,54,171,130,213,161,185,76,139,56,203,110,167,149,178,97,113,72,28,76,234,229,253,10,181,163,253,78,153,13,21,217,200,208,36,118,149,150,137,99,89,59,106,241,162,172,104,95,157,229,217,177,54,121,57,129,88,27,254,30,245,151,67,33,173,97,77,125,114,105,152,181,55,154,214,33,21,209,18,135,166,16,108,167,245,120,231,183,113,193,198,184,122,183,53,170,126,177,178,59,45,4,137,221,91,193,55,25,75,106,208,26,12,216,9,211,227,100,59,38,227,157,83,184,253,190,178,248,34,201,58,152,100,37,105,224,86,154,231,23,36,218,23,113,245,225,164,55,185,15,206,64,180,69,156,147,136,226,161,221,68,105,177,38,221,44,5,46,250,31,128,68,202,121,153,175,179,164,233,195,0,6,8,14,162,248,191,175,82,210,116,29,23,234,7,44,72,221,199,89,143,146,14,71,18,101,242,67,138,90,152,0,202,2,233,166,106,149,224,45,148,32,187,20,67,237,38,214,100,104,36,43,130,226,64,106,147,36,239,167,216,145,222,108,234,42,192,80,49,35,170,134,161,18,244,190,18,29,176,46,43,234,220,24,49,188,99,237,112,186,63,197,107,217,186,147,53,212,154,221,160,178,96,144,146,118,146,182,168,18,24,196,219,38,89,42,151,73,99,110,98,242,205,14,183,130,63,169,31,64,187,21,226,31,136,124,48,233,53,129,255,33,228,175,85,159,251,8,160,111,255,7,16,193,31,199,253,103,194,249,103,195,53,203,195,29,92,119,35,90,156,175,57,130,71,246,203,42,46,46,19,54,101,164,58,216,62,76,7,141,49,211,133,147,12,192,108,165,222,58,61,120,151,94,22,226,91,50,153,224,228,210,164,210,156,149,95,9,29,218,77,237,98,228,116,15,93,141,161,64,60,248,212,110,90,111,159,229,181,215,134,144,110,106,41,224,164,22,253,141,90,153,13,158,100,49,189,147,225,34,229,72,203,240,64,171,136,57,14,242,235,175,50,18,34,23,237,226,86,242,53,218,27,242,208,77,54,221,72,220,137,105,216,50,140,209,154,225,79,121,51,240,74,101,44,86,190,107,225,3,95,172,12,142,226,190,231,168,195,158,117,36,127,234,54,187,102,153,50,165,35,108,210,194,109,224,89,177,39,217,199,72,52,243,254,97,72,194,218,232,130,114,18,142,10,23,92,104,77,29,21,126,28,1,249,94,245,221,91,239,240,68,59,6,87,140,221,199,116,218,227,221,100,82,16,117,152,2,31,203,26,77,8,132,123,116,124,231,139,178,167,186,207,19,109,157,105,71,236,209,247,251,49,75,144,238,57,103,199,167,34,203,186,152,199,3,23,65,186,3,29,218,14,206,186,248,146,232,252,158,251,216,194,222,99,106,236,108,98,229,14,118,65,240,234,118,49,10,157,85,228,97,131,32,154,244,114,213,19,4,219,14,253,126,195,22,188,125,149,195,254,104,111,51,43,250,25,155,205,35,194,221,221,122,199,203,188,164,244,70,6,19,19,99,40,246,221,50,4,79,123,238,111,101,145,34,188,173,162,54,89,243,74,69,255,254,176,41,143,37,206,33,83,167,119,44,90,217,240,94,22,122,8,90,83,29,71,172,235,142,68,188,88,148,197,247,0,166,42,191,73,150,40,54,8,126,229,8,57,231,241,13,77,213,36,107,42,94,101,35,79,224,226,146,151,249,234,114,104,221,183,212,57,25,5,202,100,188,247,142,99,186,88,95,32,144,92,92,229,23,73,53,57,20,243,85,50,255,64,123,159,62,227,133,159,241,202,207,164,222,120,174,69,186,176,25,41,250,236,137,220,20,191,217,90,8,92,205,164,123,20,253,97,54,90,152,238,171,203,241,110,101,196,153,122,67,214,109,196,11,64,225,80,235,218,222,16,40,214,197,43,136,75,31,27,223,200,177,103,88,239,183,142,221,246,219,71,244,19,135,52,115,142,155,31,255,167,249,236,63,204,169,249,236,240,88,243,154,22,233,101,218,192,177,201,197,151,34,255,201,254,217,204,146,226,178,65,96,215,26,196,3,89,175,246,1,65,222,38,25,52,180,63,212,13,212,115,127,134,93,236,180,65,254,123,176,212,197,251,49,237,179,233,58,174,234,228,155,172,36,241,75,224,62,102,44,145,3,85,126,147,222,144,98,147,123,215,34,253,66,18,235,116,211,131,98,255,46,120,155,188,130,44,253,245,254,153,31,22,223,74,201,15,152,123,100,161,233,193,249,139,203,173,82,131,29,151,244,186,240,62,157,170,155,129,157,64,99,29,215,18,128,24,40,239,193,102,198,246,225,200,20,244,135,22,70,183,43,86,137,239,25,168,186,81,75,50,6,176,108,229,228,100,239,29,66,111,136,243,167,66,12,17,34,213,224,99,11,94,160,114,142,107,6,194,59,138,241,205,86,58,46,3,11,78,22,183,194,52,77,218,27,9,19,57,151,130,17,131,115,8,29,165,124,90,12,252,22,99,120,246,123,141,225,207,101,244,234,171,194,128,237,223,148,248,86,232,96,177,250,25,168,36,251,44,84,210,199,181,235,121,85,102,25,238,170,111,97,42,19,54,229,181,247,137,240,173,127,123,222,81,19,111,191,35,167,135,140,172,36,35,225,190,87,247,148,107,244,168,123,37,52,80,31,77,249,109,129,168,207,13,4,211,13,24,157,197,6,85,78,73,108,126,57,120,59,17,55,15,72,53,41,61,120,190,29,151,99,143,48,168,121,199,251,73,182,51,104,153,2,91,130,28,120,116,82,60,244,84,105,107,16,15,246,211,94,75,224,15,208,224,193,94,150,148,244,164,224,72,10,97,61,221,244,9,17,178,186,231,218,159,172,159,183,66,30,142,103,65,5,192,42,217,249,12,21,246,207,18,165,135,159,192,233,117,74,170,103,15,78,7,8,108,175,145,135,104,248,66,169,236,174,219,197,37,245,248,66,86,227,226,64,187,187,229,91,131,150,231,28,75,191,127,107,170,225,40,253,158,206,151,183,13,59,55,119,191,225,122,119,24,51,167,210,118,40,150,116,214,148,55,30,182,61,12,213,11,133,59,117,153,212,153,229,76,48,138,33,157,182,192,123,36,66,38,118,213,174,122,12,101,183,118,55,65,116,116,121,63,68,204,136,43,162,61,36,36,171,216,29,82,41,9,36,138,136,147,233,108,53,99,75,133,200,89,65,51,250,21,240,152,134,164,248,217,141,161,247,135,39,33,189,247,58,111,224,189,169,168,189,118,171,53,60,253,240,130,76,109,115,184,117,237,194,235,190,227,227,15,12,200,251,131,23,199,18,111,247,203,30,254,221,218,41,167,3,73,210,132,109,35,53,223,105,111,20,183,22,133,76,27,234,236,10,9,56,178,43,218,1,26,221,223,55,132,217,75,31,210,139,191,135,204,142,62,101,73,186,43,151,85,186,16,120,128,22,106,34,24,153,72,144,147,224,159,72,140,13,130,91,187,174,200,238,157,21,52,98,14,218,211,125,236,118,221,62,200,218,123,45,131,182,46,58,241,144,3,137,49,171,41,31,253,72,166,103,29,126,210,9,255,46,190,76,11,149,24,64,50,191,137,179,111,49,227,145,156,248,187,164,162,14,36,94,84,120,77,190,112,252,232,50,193,157,132,98,149,145,230,160,89,208,1,6,240,219,184,89,153,243,36,205,166,253,228,100,114,234,179,107,194,136,44,22,212,124,175,244,135,211,183,100,73,93,255,64,90,224,221,109,78,206,38,181,29,188,56,232,91,47,171,132,36,77,53,236,112,166,117,96,194,127,135,155,104,180,8,173,5,59,1,218,137,122,170,132,228,85,186,73,196,189,177,23,210,39,174,22,8,225,91,78,112,207,71,98,18,89,52,54,105,157,146,114,104,197,195,254,90,38,131,125,245,229,114,169,174,229,247,54,119,146,249,249,110,156,73,107,235,14,7,96,2,228,248,83,45,119,164,178,129,189,180,126,57,231,83,110,217,225,155,178,241,39,85,86,252,164,13,24,190,82,98,184,75,2,146,8,159,98,138,46,78,216,73,39,5,67,164,199,116,179,127,41,222,247,105,51,125,148,247,61,116,195,72,70,15,153,100,55,180,164,210,201,148,21,213,37,20,41,35,106,178,149,145,206,214,55,71,212,242,82,217,199,47,142,227,179,247,84,58,100,152,12,184,255,211,225,152,54,198,120,145,52,215,73,82,12,194,58,76,5,206,222,116,128,58,63,225,185,212,39,29,165,203,123,104,51,34,242,147,241,220,50,73,2,225,34,94,66,190,22,229,117,21,175,149,205,176,123,203,187,39,60,212,7,24,119,194,66,131,27,203,122,85,94,19,80,71,1,149,225,245,143,156,103,38,239,235,167,154,0,16,134,176,15,201,185,211,121,88,60,19,246,86,233,5,106,223,157,183,221,198,211,59,150,8,100,215,14,166,252,235,72,222,244,194,226,176,155,182,92,18,110,123,70,222,14,78,244,155,79,210,207,220,77,92,37,53,249,169,245,224,10,87,203,24,0,114,7,112,47,226,14,217,105,93,98,242,129,196,48,90,100,174,245,235,125,101,0,176,222,56,61,232,197,238,56,183,32,30,188,62,196,139,18,144,241,205,24,55,71,132,158,195,237,104,26,181,223,189,34,142,233,121,87,125,117,238,218,239,229,72,132,254,180,45,125,113,42,108,216,136,67,174,87,153,107,59,2,116,71,20,238,100,18,60,189,27,42,131,17,33,16,203,63,25,214,60,189,107,229,224,150,101,32,193,210,222,118,114,240,116,184,91,228,79,218,219,241,173,255,176,207,217,80,81,61,19,14,157,111,215,145,212,4,227,167,64,168,209,169,11,58,37,223,92,81,231,123,9,167,209,110,94,86,52,210,68,226,216,244,78,134,150,78,68,199,88,189,2,62,26,110,244,175,180,81,98,212,195,237,145,152,254,23,105,2,38,168,142,140,156,129,154,39,74,210,199,30,210,192,244,144,125,156,53,131,233,140,65,73,160,176,225,69,115,249,133,174,250,181,203,136,29,232,179,128,126,8,1,178,3,60,161,241,193,245,158,131,245,12,142,237,233,72,177,15,255,217,88,209,182,115,198,52,127,47,4,250,158,15,194,65,239,118,220,45,250,231,4,198,72,242,62,131,192,232,215,249,223,38,57,52,144,126,86,17,178,99,49,238,145,34,250,43,201,124,61,169,71,83,9,218,139,44,222,99,105,255,200,63,177,246,77,154,37,42,31,93,115,139,218,220,29,238,34,179,119,184,56,136,220,203,76,92,33,142,143,213,92,237,159,235,235,39,168,169,227,149,76,235,121,199,197,157,196,30,108,147,38,120,37,161,172,126,247,77,200,113,125,76,224,129,4,224,214,179,26,182,62,225,89,223,33,131,52,22,25,34,60,156,122,39,230,171,171,226,131,184,184,149,133,110,146,154,58,2,18,95,199,77,172,223,3,92,85,217,17,15,252,123,156,39,178,132,46,71,114,248,187,244,99,210,198,186,149,45,167,255,205,193,110,150,238,207,12,86,201,47,100,57,105,225,113,153,194,156,22,105,189,66,162,253,135,62,232,142,255,58,176,247,103,214,199,201,236,124,233,148,149,133,130,220,151,163,138,41,178,171,119,79,160,226,255,195,68,126,252,247,199,146,249,37,4,62,149,187,207,153,160,10,24,252,29,2,9,143,233,161,118,180,173,72,104,216,96,226,123,135,105,163,84,105,251,124,0,89,160,245,21,99,92,195,169,100,66,125,239,155,184,82,132,113,218,3,168,190,186,136,161,212,84,255,35,33,63,73,62,105,184,135,135,60,121,62,152,168,92,243,69,203,93,158,52,171,18,95,20,249,238,223,223,253,48,57,18,23,229,226,246,68,142,221,14,71,32,24,242,99,5,23,145,200,13,217,105,95,202,165,78,145,164,214,174,170,193,99,242,23,22,66,220,60,194,167,24,117,68,234,18,247,75,138,121,185,72,126,252,254,219,87,101,190,38,195,189,104,166,45,81,28,142,246,255,225,185,78,128,146,109,167,19,73,136,176,209,219,101,49,22,187,165,163,221,146,135,32,244,221,138,137,105,78,6,123,153,14,193,215,209,31,117,133,33,189,231,44,218,190,100,166,157,130,19,7,138,235,67,109,110,73,99,58,187,13,41,179,163,106,100,43,35,85,94,219,1,41,70,235,176,39,148,123,182,249,124,48,27,248,84,200,233,134,13,74,8,160,9,122,103,58,24,183,125,96,203,232,189,111,207,95,148,31,14,117,44,252,173,170,202,234,132,161,197,67,142,148,240,32,46,39,81,74,18,239,155,56,205,118,102,217,61,175,220,40,143,120,91,86,74,44,214,248,2,4,32,49,116,205,186,213,85,228,29,200,21,95,19,13,65,158,169,63,5,37,22,201,38,157,39,100,143,76,70,176,26,237,239,101,150,181,139,209,74,205,0,60,207,199,76,220,99,197,106,175,255,218,43,191,125,209,253,61,249,160,12,195,62,198,15,10,171,127,178,126,238,0,208,221,111,34,124,12,217,13,37,240,61,231,112,226,155,19,203,193,173,103,59,90,37,129,154,164,177,23,47,107,182,124,191,186,90,46,105,200,242,176,109,43,249,23,55,245,77,13,190,249,164,196,186,174,118,84,232,80,106,28,179,96,105,141,29,253,72,166,69,200,139,76,177,36,60,67,218,153,99,121,97,47,54,71,183,24,136,29,77,180,182,117,197,33,218,175,147,101,76,163,123,170,84,223,41,209,191,52,114,17,215,73,251,205,17,5,242,61,16,87,113,252,61,0,7,44,151,197,115,237,140,76,53,75,232,239,27,237,218,251,139,101,161,130,162,227,239,171,72,131,226,239,101,107,10,164,5,52,26,153,71,156,30,188,42,175,165,34,95,164,113,86,94,234,170,119,89,244,59,189,247,58,119,112,151,214,38,229,12,191,32,42,243,106,164,89,49,200,254,63,80,151,3,88,191,77,175,231,110,219,253,151,67,241,124,158,172,155,46,150,43,95,149,39,183,147,132,54,140,174,14,51,209,218,31,112,29,231,240,243,125,132,220,7,103,248,119,41,34,234,56,122,150,200,224,11,34,77,123,239,55,140,209,192,66,198,229,45,184,125,39,248,43,171,199,241,219,255,1,166,194,210,173,39,122,0,0,0}; + +static const unsigned char v2[] = {31,139,8,0,0,0,0,0,0,19,237,91,109,111,219,186,146,254,43,182,47,214,144,96,86,181,123,206,61,187,43,151,215,72,211,52,9,144,32,65,147,246,124,8,140,3,197,166,109,181,50,233,82,146,147,192,214,127,223,25,190,72,148,45,167,233,222,158,189,7,187,251,37,150,248,50,28,14,135,51,207,67,49,237,89,206,39,89,44,184,151,17,238,111,58,226,254,11,155,100,29,74,179,167,21,19,179,22,123,92,9,153,165,221,238,94,205,82,76,243,132,141,244,79,96,218,81,238,249,97,199,202,172,26,79,217,44,230,172,219,213,191,65,180,156,142,244,163,119,55,134,113,195,67,227,142,204,111,112,22,167,153,144,79,74,126,230,190,21,94,182,136,83,82,78,195,223,72,150,229,146,183,170,137,249,27,251,220,226,158,240,55,241,204,99,119,98,236,155,134,248,108,245,31,174,35,217,146,20,139,232,198,148,133,155,130,196,211,80,144,68,68,83,54,13,219,131,98,104,186,102,216,117,18,37,137,39,173,4,34,73,245,204,125,120,209,221,104,187,95,85,20,56,12,163,155,82,16,15,150,20,22,32,152,80,6,127,87,180,211,33,220,235,195,228,238,220,245,33,12,86,40,79,89,43,205,100,12,214,26,150,243,18,56,75,171,84,183,155,5,127,252,193,210,75,189,66,89,184,1,91,71,121,146,133,89,81,112,167,10,117,130,49,37,139,50,118,29,101,11,10,67,71,50,181,207,137,152,68,40,61,61,146,236,228,91,30,37,212,54,190,48,53,101,193,37,91,194,122,148,203,98,74,207,162,116,177,91,246,78,138,135,148,73,91,188,22,241,180,213,183,102,247,222,248,195,43,229,9,129,118,143,107,41,86,76,102,79,30,39,157,250,208,29,178,97,60,95,50,25,221,39,44,132,137,204,89,22,238,123,129,220,209,184,40,124,114,112,132,189,9,191,120,144,189,158,48,142,154,84,12,147,26,60,51,169,210,222,47,28,42,174,86,232,217,169,84,139,250,98,193,85,23,171,124,4,202,255,187,79,38,84,120,145,79,114,120,251,15,159,164,240,150,251,100,6,111,255,233,147,4,222,102,254,240,192,234,78,2,227,121,164,201,37,210,189,218,186,27,37,182,190,32,59,81,202,221,3,59,14,13,239,209,116,122,193,162,105,204,231,55,9,12,71,221,72,160,103,219,121,13,145,134,102,193,100,17,201,163,12,54,26,108,18,40,235,193,72,60,64,193,171,31,23,16,164,249,61,116,133,213,14,43,49,215,18,86,230,145,214,213,55,22,239,43,9,49,159,178,199,171,153,199,29,17,176,245,24,159,103,11,87,210,173,140,226,228,229,26,101,70,196,171,129,146,155,196,19,230,245,201,43,171,92,181,205,93,73,184,230,156,102,219,45,8,35,12,131,144,192,63,18,54,175,85,179,243,183,142,63,148,109,74,95,13,186,93,79,64,141,209,89,250,132,87,111,16,235,124,187,1,156,206,35,236,108,252,205,202,96,85,175,120,71,70,236,99,193,148,77,196,148,125,250,120,14,54,34,155,21,40,205,163,37,11,57,73,89,36,39,139,16,164,194,204,217,168,211,9,25,89,128,117,66,80,18,74,4,150,136,162,168,135,184,134,249,6,86,38,204,25,108,165,164,194,204,179,0,133,193,236,25,47,21,80,166,41,231,0,9,13,6,135,137,192,131,39,123,212,104,226,120,5,67,237,122,204,39,2,154,254,13,155,10,211,84,171,232,52,21,168,118,79,64,198,40,234,254,254,231,68,253,23,4,247,90,108,54,145,38,74,211,120,14,102,168,101,87,33,61,109,202,193,144,191,141,228,28,162,13,135,156,173,61,112,200,123,61,109,106,70,203,186,59,62,30,218,110,162,21,131,41,125,51,192,74,138,76,32,8,64,235,95,61,112,27,212,116,154,101,68,248,96,64,204,187,42,73,251,133,157,62,228,104,12,181,125,159,68,16,146,98,140,90,240,58,192,176,37,188,9,134,45,21,136,247,38,89,183,52,136,223,104,175,53,147,55,155,11,77,207,231,21,60,201,70,94,76,193,67,211,106,39,249,96,10,18,195,102,5,233,20,32,13,52,144,30,64,7,40,213,178,96,189,227,210,213,96,18,213,11,108,50,213,85,121,222,72,187,148,125,173,60,68,117,209,133,232,105,61,251,226,135,85,113,7,196,160,215,142,180,179,233,151,29,17,88,132,254,215,211,143,216,93,23,117,140,162,208,145,119,187,142,210,106,78,122,120,51,59,84,247,43,123,2,180,34,106,51,25,193,246,104,187,243,220,25,187,156,49,216,46,178,225,221,119,42,136,40,31,125,212,172,236,224,148,147,184,104,116,224,198,40,91,237,110,152,10,119,236,111,119,186,42,214,143,88,168,76,129,69,248,128,5,56,77,124,135,95,152,66,159,228,149,218,153,182,135,10,209,240,235,127,111,227,42,111,167,78,238,45,134,89,137,156,197,159,190,235,75,148,245,11,152,144,122,2,99,182,163,12,214,102,148,231,73,66,156,109,225,88,146,114,183,121,70,149,155,120,186,11,206,157,57,189,112,43,65,14,64,172,141,213,109,154,217,141,213,192,14,178,81,134,61,32,55,13,247,118,90,60,106,232,32,70,176,197,65,124,40,189,118,31,255,98,54,105,15,252,130,37,96,49,85,88,64,4,7,110,33,27,2,62,196,63,230,174,2,71,35,70,171,85,242,228,105,167,39,101,156,242,75,132,14,254,151,167,11,143,213,76,6,178,6,48,142,8,102,113,146,49,233,237,167,229,86,134,233,161,64,243,196,238,152,54,248,101,116,55,94,130,241,143,164,140,158,48,156,48,218,31,178,183,217,144,65,8,229,119,108,236,4,80,54,30,194,176,66,158,68,147,69,227,184,245,25,113,191,40,231,178,73,89,6,97,117,185,202,32,137,78,4,159,197,114,9,240,130,167,49,202,184,21,144,70,161,47,227,211,11,0,98,140,51,25,74,194,69,22,207,158,108,65,26,198,136,17,185,221,10,52,254,65,136,54,137,248,167,148,189,191,186,164,109,175,147,115,141,95,167,213,2,63,0,100,16,15,219,109,91,63,4,83,49,81,243,222,47,49,241,252,36,97,248,6,120,1,225,223,201,26,158,173,178,116,119,91,85,22,218,105,57,218,47,82,158,220,70,216,20,68,89,6,182,86,181,94,7,188,177,135,194,48,18,73,64,173,107,246,194,49,27,26,143,26,75,157,145,167,236,192,200,0,229,143,245,250,237,39,179,114,76,238,25,147,153,165,6,39,81,157,211,124,165,34,143,133,219,123,161,192,116,227,209,58,158,71,208,36,128,53,149,71,115,208,194,56,146,87,193,215,206,17,159,74,116,181,55,65,199,167,26,218,53,212,254,26,244,77,245,118,235,84,95,138,251,56,97,173,155,104,22,201,184,169,193,241,2,252,149,117,252,246,94,205,239,74,201,180,117,189,16,220,54,192,92,99,148,95,232,201,1,250,194,237,123,131,97,186,3,112,163,94,91,51,199,181,88,169,102,87,28,185,202,241,34,226,243,90,180,48,86,61,108,156,74,183,91,25,79,161,192,76,200,29,228,84,252,30,103,11,145,103,31,25,30,15,124,74,33,230,157,213,128,253,15,13,244,33,6,158,33,30,157,129,226,244,228,49,131,61,205,68,142,51,82,249,73,57,80,3,117,104,149,169,62,179,169,254,217,209,142,101,124,117,99,199,250,177,148,103,64,22,145,36,38,17,153,168,252,208,54,129,57,31,194,75,169,10,247,115,202,217,67,235,68,74,8,149,157,203,152,199,179,152,77,91,236,113,194,86,58,15,78,38,185,148,108,58,108,225,128,217,130,181,184,224,175,150,182,225,148,173,91,140,175,99,41,56,70,134,22,196,74,213,104,6,233,168,197,80,106,107,201,210,52,154,179,86,196,167,45,216,248,42,252,69,73,107,193,146,21,180,106,61,68,146,195,186,164,224,209,67,76,44,74,203,148,222,57,19,24,3,15,238,15,93,77,49,28,172,146,8,232,214,235,127,75,95,207,27,14,166,210,187,89,175,55,46,0,67,229,129,70,127,231,28,36,199,17,40,249,57,22,137,62,222,40,50,112,249,135,86,30,204,36,180,73,111,5,172,34,29,144,188,248,151,96,6,175,33,9,223,60,45,239,69,2,59,43,85,15,187,21,65,12,25,17,93,104,212,148,157,76,226,47,194,166,74,144,121,120,184,12,227,24,76,48,159,128,108,112,148,178,188,109,159,43,14,49,178,186,133,229,128,228,47,79,100,124,197,100,126,65,34,227,41,38,195,188,223,252,218,41,204,27,75,103,212,41,204,175,246,20,134,76,225,237,239,62,1,40,191,50,91,30,32,61,237,32,146,157,168,56,214,33,43,55,194,100,242,105,39,202,152,128,168,195,192,118,187,41,10,0,217,0,48,202,197,129,146,130,52,228,138,93,99,253,163,111,25,4,44,75,101,173,254,120,228,190,132,128,128,167,21,24,24,233,30,33,160,236,73,133,178,33,7,14,245,170,212,149,36,138,69,76,119,243,152,239,1,219,6,88,225,86,53,197,116,108,23,67,196,131,213,155,176,143,108,38,25,144,253,136,150,74,199,221,110,12,246,205,48,201,130,122,210,77,180,196,30,92,130,255,205,70,211,221,60,28,206,200,156,42,230,112,161,33,221,178,106,62,31,253,22,206,201,3,84,223,71,41,83,156,73,241,200,253,67,30,223,83,21,59,167,89,200,58,108,79,96,72,64,218,174,155,207,112,54,8,200,21,109,33,234,152,70,49,149,216,218,208,178,39,152,177,67,190,38,37,237,4,63,211,180,16,76,16,245,38,189,220,226,224,7,240,218,25,173,84,214,39,92,190,55,35,15,224,164,138,241,238,242,98,240,204,141,26,62,20,4,212,9,17,14,147,251,134,84,119,9,205,3,72,90,83,177,244,252,32,19,55,138,11,120,191,252,230,219,51,161,55,100,9,125,175,112,252,164,242,16,159,60,214,211,154,119,138,180,251,212,248,34,181,231,105,228,42,216,193,177,222,105,101,137,211,32,82,18,96,128,139,154,56,229,74,7,19,42,242,254,237,246,200,187,182,116,16,209,213,141,59,59,172,91,121,62,150,159,32,97,56,170,73,135,164,119,226,171,242,71,207,201,51,156,118,174,175,174,59,195,171,160,1,161,171,96,255,84,197,126,136,251,108,244,232,109,244,4,0,213,219,73,65,68,247,195,63,96,24,197,64,254,104,240,20,199,0,140,94,86,199,145,232,56,160,14,45,79,233,250,190,73,230,85,163,76,55,18,180,60,14,52,141,128,100,190,18,67,9,69,39,200,182,142,129,105,194,228,191,82,109,7,114,73,239,190,98,215,49,185,109,130,35,15,61,229,65,213,161,29,154,184,32,103,46,140,48,231,52,18,172,244,233,230,172,67,212,105,76,190,115,184,227,99,67,114,239,41,87,176,101,7,44,10,116,210,181,168,94,24,99,37,65,111,245,137,146,58,244,80,91,67,173,52,2,22,230,35,197,13,74,116,233,109,208,197,39,68,59,124,14,88,12,9,181,128,104,238,239,108,189,96,1,91,135,10,23,90,84,166,173,20,86,54,134,93,120,89,158,226,166,202,222,163,126,152,246,32,52,206,52,49,141,117,187,75,58,35,149,35,200,202,17,226,194,176,227,102,45,10,220,147,95,154,45,252,241,228,250,226,232,248,228,95,111,100,131,172,126,212,206,22,144,9,255,69,182,30,166,246,104,250,242,46,29,83,99,216,31,51,106,53,164,50,236,113,205,205,129,183,9,229,209,159,26,98,224,177,7,252,165,32,31,27,171,176,230,156,246,201,183,154,188,243,30,205,200,0,156,226,124,228,169,88,181,75,98,125,195,134,200,130,92,168,163,232,231,91,173,201,13,100,22,76,86,231,208,84,181,109,224,167,205,66,159,107,168,228,22,228,29,198,186,15,255,4,132,232,118,221,55,194,233,85,80,158,104,128,61,108,166,122,183,221,122,223,16,36,193,128,125,191,1,136,191,3,157,149,50,223,208,230,62,193,175,201,5,121,223,16,36,175,130,250,129,136,51,138,26,193,145,173,100,25,81,167,116,163,167,18,150,25,200,248,144,138,237,149,31,125,37,230,235,24,236,197,240,150,224,134,14,207,136,113,162,240,11,153,139,240,24,254,188,139,38,95,195,79,240,240,65,72,32,39,211,240,35,185,7,25,95,195,15,36,81,154,133,239,203,243,170,211,194,57,158,121,250,159,226,9,127,121,112,253,19,176,181,11,167,215,116,131,175,247,240,22,110,244,119,34,76,88,13,172,166,211,110,248,228,216,126,221,233,85,80,106,7,230,193,86,209,159,190,94,46,177,246,13,18,66,162,72,81,86,77,179,134,177,220,97,246,240,102,65,154,100,236,52,122,94,66,81,103,29,181,195,165,90,26,34,220,249,32,170,191,52,154,35,44,157,241,58,192,227,204,20,17,23,242,30,198,195,167,70,8,177,43,29,207,86,96,245,231,13,155,187,73,147,186,22,135,162,123,99,79,155,165,249,63,104,127,196,195,190,223,195,111,45,184,154,203,191,12,109,170,145,163,67,103,81,136,171,27,217,15,242,171,146,207,176,6,250,195,20,177,66,155,223,194,22,45,73,21,126,75,2,70,142,62,209,9,53,183,250,89,28,8,8,214,93,52,6,90,181,12,42,63,5,102,180,12,42,207,172,83,14,109,127,13,72,173,155,205,212,231,140,125,110,147,145,25,4,137,253,207,125,47,97,34,159,145,137,124,126,1,19,249,92,1,241,207,46,19,129,252,116,163,191,202,156,236,235,15,218,195,166,121,192,124,132,72,10,191,220,249,176,49,28,160,195,232,189,34,196,149,120,108,217,190,48,223,178,246,190,162,249,158,128,244,96,238,70,97,211,27,88,182,61,60,94,181,48,186,29,121,234,243,215,30,181,185,240,47,254,27,212,70,252,20,106,243,217,165,54,103,1,120,78,118,110,182,245,222,132,184,223,76,118,190,211,45,243,159,167,63,23,72,127,62,90,250,131,171,117,9,171,245,213,31,126,133,165,186,236,118,231,222,165,238,114,171,150,233,140,222,237,13,113,235,143,107,192,188,12,255,16,85,30,188,89,19,87,218,65,156,248,45,64,187,130,33,75,242,16,142,55,31,139,204,207,231,239,226,121,169,14,115,155,241,60,223,247,26,137,142,136,58,115,60,122,1,107,224,125,8,244,177,216,223,128,31,145,39,132,232,250,226,209,119,236,238,168,134,217,251,172,140,186,145,229,70,17,114,163,137,230,70,28,45,59,113,32,60,171,188,72,90,8,255,232,105,172,254,169,217,114,37,9,250,139,25,15,156,12,77,55,7,211,85,182,139,95,98,183,97,100,121,206,25,196,78,8,28,135,13,84,212,25,137,203,97,206,27,136,202,71,205,97,190,53,86,13,20,5,232,187,12,0,228,189,179,28,230,221,232,123,20,230,68,115,147,119,47,96,28,216,24,17,61,68,160,211,63,159,112,188,7,194,241,1,145,227,251,3,132,227,61,168,172,148,249,224,18,142,223,127,140,112,124,216,33,28,31,28,194,241,249,165,132,227,214,37,28,95,52,225,56,46,9,7,82,12,224,22,134,112,156,59,132,227,155,33,28,167,150,112,252,94,18,142,207,46,225,88,254,255,135,137,255,19,31,38,6,190,190,104,245,70,147,167,95,157,235,161,7,190,128,171,51,222,101,204,61,253,16,61,170,40,171,190,103,39,63,17,31,43,42,209,116,114,207,20,197,128,24,28,37,39,28,188,145,165,117,52,123,215,121,221,25,27,4,107,218,169,44,4,243,115,80,108,31,240,107,82,59,226,159,86,213,201,232,183,48,1,166,168,162,175,3,13,215,59,208,240,8,161,225,145,133,134,71,128,92,149,62,118,231,46,246,32,226,81,5,104,142,42,136,184,106,8,179,47,57,73,159,106,242,228,229,164,79,68,117,93,20,56,146,128,117,89,53,92,42,105,186,6,135,156,227,96,46,68,112,29,62,223,68,217,112,187,197,150,224,96,75,26,57,249,10,240,188,227,69,204,158,19,186,40,166,73,50,195,113,201,145,147,128,23,7,18,176,32,252,96,2,62,210,89,20,63,162,244,6,224,14,213,250,24,172,1,144,219,122,37,27,197,65,186,82,197,224,57,214,150,12,111,40,197,26,130,64,246,94,151,217,85,56,217,149,168,81,192,225,140,116,117,166,136,249,246,186,121,238,117,28,242,115,167,15,241,205,43,167,121,103,12,48,166,242,128,234,5,46,89,237,75,78,102,195,208,204,51,189,123,25,120,215,174,107,163,151,9,77,2,96,26,213,136,108,252,114,85,71,207,155,19,184,193,218,83,234,93,53,108,143,123,13,80,30,27,171,6,123,31,128,106,14,209,203,202,83,9,96,248,221,46,127,187,59,189,157,207,63,255,20,216,176,99,45,106,136,163,112,185,96,149,159,22,251,168,1,41,153,197,4,243,231,49,193,252,238,105,108,204,247,84,122,227,220,5,10,75,13,20,30,74,160,112,141,64,225,222,2,133,43,7,40,60,146,73,196,79,69,120,97,0,195,141,5,12,39,37,96,56,114,1,67,242,236,5,50,227,84,223,191,134,143,183,254,234,114,108,14,132,109,12,117,12,182,178,164,246,114,252,80,188,149,67,214,163,3,34,224,143,159,225,13,59,76,124,67,72,146,2,54,81,209,120,125,112,119,37,223,210,193,118,91,6,255,106,241,6,99,60,176,114,223,113,104,117,241,20,66,69,230,225,77,242,237,246,14,108,142,247,40,249,110,105,132,109,25,222,2,156,96,61,67,22,147,211,104,187,157,40,170,175,235,70,49,149,161,52,138,232,27,182,168,56,136,140,113,35,193,202,34,247,36,109,27,147,252,210,110,67,253,21,196,92,115,70,14,102,155,168,105,206,104,124,87,6,178,193,120,152,210,78,128,182,158,109,183,157,160,124,82,191,154,62,165,128,107,75,192,145,0,190,159,82,219,127,56,133,141,50,156,190,122,165,69,47,64,244,116,60,212,242,22,234,38,231,212,15,141,212,197,200,211,5,36,1,80,19,38,72,171,205,59,244,47,240,232,34,247,113,152,33,188,15,19,63,14,114,158,46,226,25,24,46,192,123,58,237,220,168,21,195,230,217,110,99,181,161,152,135,191,96,86,167,117,71,179,165,53,104,249,69,0,28,113,239,245,227,191,187,169,123,204,107,155,45,245,157,178,117,143,98,51,178,118,239,224,200,31,186,250,104,216,228,255,26,208,90,109,183,22,222,225,213,255,93,135,199,181,194,184,90,91,57,23,158,17,81,10,168,86,63,148,149,3,172,84,215,93,131,56,213,215,94,185,61,90,106,123,237,122,141,128,21,180,188,6,201,175,117,88,220,60,108,205,228,83,5,89,106,119,46,81,47,216,218,126,97,79,103,154,110,156,242,145,83,26,170,221,22,55,54,20,59,13,133,58,122,195,127,137,137,107,179,170,254,165,145,74,237,248,17,229,193,58,74,114,6,204,92,125,115,168,222,176,3,210,113,176,208,164,93,217,7,116,199,91,114,74,237,220,126,92,1,188,148,162,122,105,173,64,148,222,155,91,68,73,105,90,70,134,124,215,66,53,251,128,117,172,137,10,59,7,55,58,139,66,89,239,191,0,255,82,202,232,45,58,0,0,0}; + +static const unsigned char v3[] = {31,139,8,0,0,0,0,0,0,19,93,83,77,111,219,48,12,189,247,87,112,186,248,176,90,254,254,72,97,5,232,186,30,118,24,182,195,54,108,71,213,86,98,181,178,148,73,74,220,252,251,209,118,146,165,5,12,147,122,239,145,162,68,170,249,240,249,219,195,143,63,223,31,161,247,131,90,223,52,147,1,197,245,150,17,161,9,180,138,59,199,72,31,110,246,74,193,211,54,28,123,233,5,89,223,0,52,189,224,221,228,160,235,165,87,98,221,68,139,93,176,65,120,14,109,207,173,19,158,145,189,223,132,53,129,232,154,236,189,223,133,226,239,94,30,24,249,29,254,188,15,31,204,176,227,94,62,41,129,59,27,237,133,198,200,47,143,76,116,91,241,46,86,243,65,48,114,144,98,220,25,235,175,228,163,236,124,207,58,113,144,173,8,231,197,45,72,45,189,228,42,116,45,87,130,37,52,254,159,76,73,253,2,86,40,70,36,166,32,224,143,59,204,43,7,190,21,145,59,108,63,190,14,138,64,111,197,134,145,142,123,126,247,134,185,109,208,1,116,180,99,193,116,154,187,40,26,199,145,142,25,53,118,27,165,113,28,79,210,0,54,82,41,22,104,163,69,0,83,205,159,204,43,11,98,136,33,205,241,11,192,121,107,94,78,229,178,32,161,197,25,98,65,187,183,22,15,246,96,148,177,193,26,26,188,160,254,172,199,226,69,203,119,44,176,102,175,187,224,26,126,54,82,95,240,142,5,95,147,156,214,69,5,73,69,227,58,229,105,70,235,188,134,147,193,74,226,130,230,69,30,38,52,75,238,107,186,42,43,88,254,72,37,73,13,43,90,21,135,144,86,191,86,247,37,148,115,64,9,171,3,162,252,189,58,76,49,71,10,37,141,211,180,77,104,149,101,180,204,33,163,69,9,120,243,117,1,211,78,5,76,59,13,5,173,146,28,98,158,230,52,69,236,100,230,44,39,234,34,201,32,67,34,185,16,1,182,16,154,233,122,215,239,186,185,116,107,224,82,211,214,57,178,116,215,249,163,18,174,23,194,159,212,77,116,158,223,230,201,116,199,243,164,15,82,135,61,14,138,21,56,254,56,209,19,55,139,16,146,59,15,206,182,248,28,164,243,198,30,41,138,233,179,155,100,11,123,45,92,6,105,48,221,126,154,230,57,108,46,233,173,30,171,152,223,221,63,169,238,250,235,136,3,0,0,0}; + +static const unsigned char v4[] = {31,139,8,0,0,0,0,0,0,19,237,60,107,143,227,200,113,127,133,222,195,1,51,23,146,203,151,164,25,10,9,28,4,8,98,192,231,15,78,62,196,216,217,15,124,180,36,122,248,10,73,141,70,195,200,191,221,85,253,98,179,73,189,238,246,156,179,145,93,104,165,174,170,174,174,174,234,46,86,87,23,247,243,15,191,49,186,40,203,15,89,153,38,109,107,188,249,182,111,123,198,255,26,63,254,238,191,140,223,103,9,41,91,2,173,93,215,213,109,248,249,179,66,106,39,85,241,195,231,31,204,48,218,116,164,49,195,152,108,170,134,244,113,245,110,181,217,71,86,110,195,184,106,82,210,88,0,89,179,159,161,99,180,85,158,165,198,119,100,65,86,36,62,105,125,45,171,59,88,73,85,118,164,236,194,79,159,78,187,174,200,251,60,43,137,181,35,217,118,215,133,174,189,88,91,7,18,191,102,157,213,145,247,14,71,34,86,148,254,121,223,2,210,113,190,95,91,69,245,97,117,81,76,49,97,176,182,42,181,165,252,220,192,48,214,38,42,178,252,24,254,14,70,108,140,183,168,49,255,181,201,162,220,252,15,146,191,145,46,75,34,179,141,202,214,106,73,147,109,120,7,18,117,251,134,0,168,235,96,138,109,248,41,121,115,221,79,230,167,182,117,220,79,140,6,248,100,81,151,85,165,66,85,213,237,199,39,195,247,78,113,149,30,251,34,106,182,89,25,58,107,117,110,89,185,131,113,186,211,174,233,57,196,89,39,85,94,53,2,195,149,104,117,85,109,29,178,180,219,133,110,253,126,138,226,184,9,15,64,64,30,190,116,89,151,147,175,143,253,72,69,41,73,170,134,202,19,238,75,232,143,99,26,105,213,117,36,93,95,35,56,237,92,115,231,153,59,223,220,5,230,110,97,238,150,61,157,34,213,161,16,139,66,14,227,73,68,253,88,116,125,32,65,23,155,109,215,84,229,182,87,153,196,85,14,98,156,146,42,37,230,107,156,154,117,67,192,16,69,221,171,54,219,103,96,234,178,106,235,40,33,230,127,254,251,143,240,219,250,35,217,238,115,176,226,143,164,204,43,19,64,81,82,153,255,86,149,176,232,162,214,252,125,22,19,54,188,129,212,128,216,55,25,216,253,15,228,96,74,86,235,97,126,46,41,78,109,17,229,185,50,231,39,231,251,83,187,7,169,247,181,2,93,45,190,31,153,210,89,215,85,155,209,137,54,36,135,33,223,200,250,141,52,184,162,114,43,202,179,45,42,0,240,81,142,204,96,203,116,93,85,132,150,237,45,112,72,96,13,38,134,38,182,96,197,230,164,167,234,131,109,135,251,194,17,235,96,118,113,0,48,143,234,150,132,226,199,41,222,3,247,210,204,202,122,223,153,85,221,109,155,106,95,155,45,201,73,210,153,200,56,106,72,52,82,237,200,176,76,21,184,181,102,236,60,183,128,181,69,43,215,122,29,165,41,122,5,71,72,196,68,96,115,235,26,216,104,224,3,138,176,172,74,114,250,210,29,107,242,207,140,238,171,201,90,13,129,237,36,26,160,182,34,131,22,35,145,11,62,170,107,18,1,171,132,132,12,179,142,163,228,21,103,92,166,82,95,84,241,42,34,43,162,45,97,3,135,212,127,108,170,100,223,54,32,108,95,237,59,156,98,24,237,187,138,35,97,225,101,229,27,88,49,101,190,110,23,165,213,129,245,174,155,106,11,98,182,253,25,99,135,161,16,52,43,75,48,86,91,103,165,197,181,49,224,96,204,49,78,248,3,42,4,159,63,76,51,217,125,157,155,56,234,115,147,145,60,93,115,225,173,106,179,1,213,133,150,7,238,98,24,134,177,80,54,229,28,51,166,20,217,103,147,229,196,218,215,121,21,165,214,85,213,227,122,145,27,189,221,23,176,18,142,125,154,181,117,30,29,195,60,107,65,11,29,172,240,56,175,146,215,255,217,87,29,49,211,212,76,115,115,147,109,193,197,154,19,215,99,238,26,179,70,103,32,253,231,137,206,19,230,54,133,152,57,217,146,50,237,135,85,87,144,114,111,86,185,185,199,71,10,12,222,118,199,156,77,112,110,141,202,141,1,246,196,29,32,44,122,162,251,40,100,75,1,102,146,144,29,245,86,114,39,77,81,125,5,142,37,235,142,161,203,183,198,119,207,73,228,71,27,193,106,158,203,45,12,190,52,85,62,108,19,110,144,100,223,180,64,83,87,25,62,213,78,33,104,28,125,72,42,16,41,217,68,251,28,92,244,62,205,42,51,137,96,45,183,38,41,98,146,154,217,166,137,10,98,102,197,214,172,226,63,163,127,104,223,182,230,91,150,146,74,26,142,154,75,247,102,69,150,166,57,57,97,71,70,93,68,239,226,25,133,174,99,180,128,119,64,76,202,175,146,35,93,99,16,71,132,184,37,211,166,170,245,144,130,134,5,220,191,161,147,6,11,89,239,96,173,57,248,81,192,169,71,1,223,75,6,210,1,36,169,154,170,131,182,104,181,175,228,48,144,211,150,164,108,97,182,200,203,85,155,71,209,172,163,18,112,198,208,56,202,70,86,194,46,251,168,192,193,27,162,43,152,45,183,218,50,170,97,17,54,89,210,149,224,51,66,112,30,239,25,56,181,35,163,218,54,81,154,17,116,202,77,85,88,242,121,98,104,216,183,44,58,143,236,170,9,14,180,149,149,81,46,101,129,7,227,142,164,214,7,105,42,1,43,247,5,108,217,196,98,251,80,135,114,69,79,136,155,40,81,199,65,239,9,94,14,253,142,10,97,174,136,47,13,167,126,159,162,248,10,223,108,54,10,142,3,253,248,201,219,44,159,156,105,47,238,133,29,195,49,190,115,224,143,66,49,143,186,4,101,195,145,84,199,198,249,190,17,179,137,27,92,209,212,112,28,130,113,107,19,181,157,98,133,35,93,37,2,176,219,19,177,222,56,4,158,35,176,143,164,45,48,180,84,176,45,169,179,72,52,112,95,8,161,133,8,124,187,140,229,146,192,137,128,18,165,75,42,17,19,145,37,102,42,187,68,141,39,33,193,194,103,233,112,125,150,3,130,77,247,100,183,141,85,149,249,177,151,75,55,138,33,128,131,135,226,90,70,189,194,161,224,79,233,179,133,27,183,16,90,129,80,155,28,148,197,188,205,58,201,179,26,130,177,164,123,112,76,250,247,113,125,216,193,243,135,174,103,124,12,28,154,168,22,65,20,95,158,39,155,59,81,139,188,193,118,106,45,244,84,253,24,198,188,151,78,136,142,78,39,164,206,207,222,100,239,224,138,229,212,104,243,100,139,25,78,231,124,178,69,4,217,79,98,74,80,21,56,225,87,69,83,172,125,178,233,198,179,156,158,109,64,152,8,11,49,1,194,99,77,0,229,100,131,36,248,133,77,186,92,152,224,205,224,172,109,60,108,56,52,30,5,154,12,3,105,144,146,125,211,56,158,65,78,246,135,229,58,253,7,141,81,193,71,58,8,120,249,18,60,189,124,149,192,224,137,1,151,142,2,92,2,37,236,54,180,66,105,121,253,182,201,104,156,182,47,96,46,0,50,188,207,236,235,100,23,86,32,158,242,110,3,97,131,93,188,51,105,25,208,162,243,64,0,95,6,150,58,139,226,8,147,224,112,58,23,65,52,168,3,72,92,149,4,130,113,24,70,163,99,64,74,236,141,136,231,104,37,169,63,34,93,205,209,174,36,113,160,18,187,83,82,87,16,46,70,132,179,226,186,82,222,120,152,156,62,149,124,144,143,234,80,202,146,15,178,80,4,31,185,25,166,206,84,44,38,218,12,244,12,193,59,116,115,138,165,240,25,197,80,248,220,212,40,98,53,70,240,30,52,36,25,7,40,184,5,104,236,59,198,169,64,216,139,57,121,151,40,108,200,94,35,140,2,131,253,64,207,99,2,69,91,39,27,151,173,132,97,227,100,51,183,51,142,113,236,29,110,18,238,186,60,174,54,128,121,2,230,115,200,162,151,249,14,79,80,45,7,152,0,109,246,112,54,21,80,8,179,64,69,160,154,29,6,24,4,198,166,13,137,125,219,157,236,3,236,2,233,219,14,150,235,242,150,39,52,121,0,19,114,39,203,219,11,209,22,146,28,64,18,1,18,144,149,39,64,79,28,242,44,136,188,128,67,168,176,67,72,200,100,229,96,250,83,69,97,244,104,181,133,18,70,114,62,104,4,88,78,248,21,186,134,107,32,53,133,181,59,120,216,191,194,252,148,22,206,146,253,26,65,93,1,157,82,195,129,240,192,96,248,11,41,241,91,208,81,24,58,211,168,205,90,240,100,62,4,48,224,203,40,142,194,66,132,160,179,101,33,41,169,35,124,210,245,250,209,92,28,7,109,45,118,117,206,69,186,34,78,154,198,186,181,72,173,201,184,236,45,106,30,102,217,60,26,231,80,199,199,147,173,198,203,204,40,147,40,218,98,198,153,80,154,182,10,129,135,133,60,203,75,248,131,28,90,33,125,52,103,160,199,199,71,131,5,26,67,31,214,6,4,70,228,255,61,192,89,184,206,225,127,210,224,200,136,198,50,106,7,22,195,11,204,159,116,12,244,57,105,147,153,158,37,208,194,42,205,98,74,35,55,203,136,78,213,211,241,31,73,79,199,169,158,142,186,158,240,129,57,165,177,21,53,161,38,76,173,199,223,183,138,126,251,74,142,244,68,221,26,152,205,129,40,74,153,16,151,204,133,104,184,124,60,65,8,88,102,69,68,227,81,160,100,13,26,209,65,211,112,91,3,31,65,81,99,100,229,6,189,7,60,75,216,105,222,226,65,166,126,234,183,89,114,141,69,172,34,69,179,111,169,87,66,4,203,123,176,124,150,14,213,1,236,249,134,238,171,5,215,75,127,119,164,168,169,142,89,172,214,66,72,90,147,168,123,112,77,112,229,224,180,33,200,118,55,13,174,146,161,171,119,185,171,55,233,74,253,42,80,49,7,155,102,24,189,163,74,88,71,142,199,176,189,151,191,66,252,7,162,113,204,157,136,139,4,139,166,129,84,72,8,16,120,212,131,36,45,28,192,163,166,235,105,22,131,166,163,218,144,61,18,16,44,104,144,193,132,66,225,145,16,106,2,149,132,129,78,54,94,76,100,155,163,32,145,77,46,136,78,22,147,238,128,143,110,157,142,30,82,4,22,148,26,213,104,137,104,8,166,40,228,197,94,48,160,191,26,160,30,3,13,128,128,2,92,217,126,199,157,137,11,129,233,213,146,228,107,29,32,232,253,41,253,106,210,97,165,246,8,38,61,92,141,126,144,231,8,1,6,62,116,41,148,143,203,78,105,192,168,126,255,23,88,147,221,131,72,34,61,254,101,220,100,62,70,80,55,112,244,106,90,50,132,251,44,46,133,13,154,60,224,41,241,135,97,211,142,123,60,62,174,213,200,119,232,240,224,26,150,113,190,23,172,90,1,11,190,149,160,168,153,187,4,165,29,110,21,244,120,143,160,199,169,160,24,136,95,30,245,168,140,170,157,79,206,206,79,233,115,178,211,12,115,138,214,241,22,57,5,173,34,232,228,214,140,141,58,49,166,222,21,197,149,55,152,244,244,172,117,191,208,83,10,141,25,21,203,115,156,59,100,31,146,189,163,123,158,102,27,63,120,222,179,225,249,46,124,22,159,245,209,121,55,106,89,146,111,70,142,13,1,35,191,198,41,26,210,37,59,149,134,131,78,182,72,159,176,35,182,76,166,176,211,180,68,242,67,142,150,107,81,8,88,170,115,32,96,109,133,224,56,30,0,98,2,158,118,104,246,101,130,177,179,158,199,153,38,109,128,24,111,144,72,158,103,53,196,224,230,208,151,194,37,3,65,0,135,17,228,193,22,26,99,209,207,113,165,119,67,36,21,209,59,230,84,247,173,116,184,28,203,66,229,49,201,51,252,193,224,71,144,228,91,157,199,152,69,49,25,67,248,111,65,241,174,15,33,79,190,20,218,143,210,86,174,114,4,241,198,40,79,65,197,253,220,226,86,59,203,65,105,166,104,138,151,227,178,212,209,148,64,44,254,209,177,230,222,229,61,238,134,203,91,229,238,223,193,221,1,238,174,15,159,231,27,184,55,160,246,123,68,95,4,134,231,120,248,185,129,57,139,79,239,210,204,18,180,2,236,3,231,102,246,119,169,198,103,170,241,110,81,60,141,97,225,104,11,129,73,63,98,69,83,229,64,182,197,140,52,177,150,82,128,173,58,184,126,33,139,2,248,43,227,249,89,179,251,118,52,244,86,95,77,87,121,206,175,166,41,87,136,168,240,100,123,59,91,199,240,22,30,178,190,192,22,151,207,61,76,113,249,160,141,189,229,5,166,204,174,247,176,13,96,250,193,2,62,207,87,217,222,165,217,185,213,56,207,118,113,135,176,79,160,88,170,220,11,92,223,178,42,39,221,93,74,128,197,229,249,176,184,23,193,5,190,244,9,112,187,185,64,167,236,115,129,229,17,158,56,240,72,187,119,25,4,207,134,251,124,137,47,111,89,171,197,132,175,3,15,6,188,99,200,115,43,57,70,37,104,223,233,177,5,91,115,25,47,211,128,227,152,105,2,137,124,14,34,63,126,194,235,132,166,122,37,172,43,238,94,214,134,206,79,207,110,236,73,252,224,95,4,65,18,167,11,226,74,2,151,35,196,51,1,78,100,240,40,18,23,53,252,241,135,39,17,1,114,57,100,49,64,196,131,182,198,124,31,135,242,4,53,75,117,11,24,79,66,15,228,158,70,62,71,61,16,227,161,105,76,191,156,229,191,28,6,240,181,14,171,57,250,149,36,15,198,228,238,148,216,21,164,154,40,238,236,84,7,213,96,226,69,224,216,181,134,104,13,247,26,72,164,206,145,166,218,221,49,95,113,37,224,14,140,221,113,135,121,122,133,124,50,132,191,154,237,34,66,155,250,168,216,105,184,66,209,201,37,177,63,38,158,103,62,240,94,142,200,221,89,230,226,112,89,231,152,192,30,43,158,229,177,235,70,25,87,179,107,167,235,158,193,206,168,154,34,103,38,204,131,87,28,148,133,171,172,158,2,219,39,155,5,230,172,182,66,47,41,226,21,23,172,251,203,151,37,203,68,203,130,173,37,205,190,209,10,201,66,1,219,79,76,113,227,154,74,79,145,228,93,173,118,19,235,111,76,190,82,201,91,149,251,12,115,150,181,71,18,172,234,27,149,249,173,48,88,160,128,28,219,35,156,47,113,5,129,136,183,24,33,23,18,89,86,77,17,229,35,100,32,145,45,41,178,201,160,75,68,239,235,154,52,73,212,18,189,248,76,34,240,122,52,162,166,90,234,5,168,34,99,153,188,82,75,82,209,225,145,212,41,57,120,203,118,104,41,31,211,209,56,24,98,135,18,173,160,231,76,12,164,210,210,148,43,182,105,28,20,92,101,231,46,150,134,187,244,13,119,117,19,195,197,117,134,206,202,112,221,192,112,189,167,91,24,94,159,240,106,97,60,45,96,206,183,112,91,93,229,6,143,227,37,48,116,111,225,246,116,221,24,174,1,177,211,226,38,213,61,95,87,29,68,32,129,225,95,159,41,198,162,215,77,187,194,96,209,187,201,16,200,240,186,37,144,25,44,149,85,112,19,191,235,243,133,16,249,201,55,130,107,218,195,32,249,250,108,49,46,116,225,112,2,159,27,248,221,96,12,15,172,1,27,237,154,53,180,83,212,133,201,206,28,158,46,112,188,97,235,226,140,113,235,62,93,51,136,136,177,175,239,93,7,244,7,14,225,234,26,100,28,111,216,110,46,221,110,183,77,249,6,163,64,48,13,43,198,187,194,78,137,210,207,219,99,46,56,159,229,198,3,244,27,164,3,243,82,123,156,103,40,43,231,123,173,212,221,162,245,195,18,125,178,69,248,238,200,178,78,103,0,226,97,65,74,128,247,212,88,240,197,83,176,162,98,205,173,223,13,31,62,188,54,205,113,220,200,100,80,15,62,152,166,30,16,103,202,218,6,22,67,226,85,161,121,212,249,205,83,9,249,76,254,205,50,93,178,36,122,184,116,155,20,234,153,178,178,78,185,185,83,170,245,102,241,12,37,71,197,209,52,197,56,32,170,187,64,161,125,85,9,192,45,128,246,18,17,193,45,218,25,243,57,171,162,17,211,203,42,194,48,108,106,69,79,181,162,147,94,48,150,119,193,88,235,191,133,206,27,165,64,97,166,240,114,204,144,150,157,61,26,14,253,59,43,18,61,24,62,206,227,248,172,116,249,46,141,65,115,242,23,6,210,71,18,198,97,179,50,217,183,123,227,226,157,87,223,68,105,138,62,79,98,128,95,179,250,112,153,253,211,165,225,46,42,145,242,235,53,254,33,253,151,83,196,57,132,204,170,6,164,163,213,88,82,151,75,5,251,172,73,51,184,91,218,30,103,128,111,96,58,155,2,62,195,26,35,157,123,120,187,62,68,101,254,51,196,219,222,21,222,24,166,220,37,245,2,195,179,5,126,174,112,230,15,180,251,152,99,228,18,24,43,247,10,111,241,132,90,204,176,118,108,135,165,157,240,142,155,125,41,117,72,249,190,81,107,143,100,93,178,2,20,21,201,10,72,214,34,43,176,161,10,89,1,178,250,99,5,32,42,140,85,16,214,22,43,109,165,154,26,115,106,106,33,53,207,169,141,106,171,241,159,135,167,250,93,167,53,135,38,159,188,40,181,208,224,138,54,212,254,170,90,166,117,219,115,216,25,69,77,171,183,231,144,179,170,211,106,184,231,48,98,25,204,160,102,244,60,46,230,126,92,255,191,26,80,13,188,192,137,150,104,247,195,79,171,6,18,24,239,24,210,237,104,234,41,97,83,189,92,49,245,176,146,65,49,127,107,178,100,171,201,101,52,135,167,152,57,20,86,49,3,152,103,214,231,250,255,86,170,95,181,52,183,232,172,203,10,244,135,155,125,201,75,148,246,113,150,88,49,249,200,72,243,96,7,38,132,24,158,233,62,170,93,210,61,127,21,214,118,23,173,186,66,44,124,227,116,78,3,0,255,197,198,164,154,106,127,185,197,249,109,5,23,77,122,105,53,75,230,169,84,254,57,42,31,168,72,212,18,216,248,248,214,101,127,191,144,188,255,61,157,157,161,175,242,142,223,75,56,74,238,205,188,69,248,13,210,125,151,198,251,198,67,237,176,238,226,37,20,119,193,11,24,130,130,110,189,10,91,64,36,229,59,134,23,156,189,16,29,70,224,9,204,251,6,192,123,54,118,221,120,246,30,151,143,48,74,226,170,131,252,156,84,174,202,91,36,96,111,226,125,83,26,150,190,192,252,18,126,192,6,9,233,111,249,194,141,231,72,172,120,61,24,107,60,57,149,120,221,25,143,155,252,127,106,160,175,191,105,111,18,211,58,18,141,11,63,42,56,99,78,162,199,48,42,59,114,113,170,95,243,121,232,238,147,208,141,231,240,159,114,124,164,218,178,222,178,54,139,115,34,117,30,142,192,82,229,236,197,102,106,190,115,61,45,239,76,95,165,78,232,76,207,177,157,39,12,52,123,79,251,203,141,52,223,159,87,146,120,139,165,79,98,44,163,99,47,47,191,132,188,222,185,172,240,142,12,78,57,36,157,188,217,172,224,212,158,194,7,161,155,147,93,110,244,18,207,75,122,244,2,71,113,206,73,140,198,161,59,217,253,9,227,120,1,28,195,130,224,146,191,27,6,26,59,141,241,80,63,203,111,252,22,47,219,34,227,161,110,200,134,52,45,147,207,106,147,29,41,72,152,70,205,235,99,111,227,215,75,168,214,96,201,219,148,235,133,70,211,107,149,105,149,17,31,96,171,231,142,175,43,113,154,68,214,52,72,57,15,218,243,110,184,24,153,169,33,210,157,173,194,246,91,229,167,165,37,134,55,163,150,129,3,7,208,222,110,139,151,112,230,197,53,1,214,95,142,66,248,45,111,180,76,232,204,9,232,239,253,117,140,153,9,77,117,193,239,119,199,164,231,94,112,89,255,3,40,228,150,215,32,6,186,243,175,66,12,52,23,94,135,64,162,59,223,117,192,46,51,213,67,12,44,203,60,228,197,60,53,220,125,117,15,216,229,226,109,255,204,110,92,45,159,232,110,44,192,29,255,244,87,92,102,24,187,142,23,80,206,249,246,37,156,125,177,21,17,59,43,232,71,21,22,8,60,88,245,123,175,84,225,34,236,103,188,126,51,238,238,95,238,238,95,233,30,92,238,30,204,119,167,239,142,44,167,239,142,76,94,79,17,214,167,74,251,37,74,69,79,127,5,147,193,249,242,40,77,0,0,0}; + +static const unsigned char v5[] = {31,139,8,0,0,0,0,0,0,19,189,91,233,114,219,72,146,254,239,167,168,230,184,155,164,155,0,9,82,151,105,81,29,62,219,158,112,219,14,75,118,108,143,66,225,6,137,34,137,22,174,0,64,145,28,13,223,105,159,97,159,108,191,204,194,81,32,33,74,125,236,206,168,105,28,85,89,89,89,121,124,153,85,232,118,133,248,240,241,226,245,80,60,255,244,78,76,108,207,75,132,191,72,82,145,164,118,156,138,165,155,206,69,211,142,220,110,83,184,129,8,99,71,198,34,13,69,34,227,27,41,210,185,20,118,20,9,59,21,118,176,22,95,62,191,123,244,168,185,72,36,58,199,238,36,109,62,123,228,250,81,8,50,183,98,222,17,177,12,208,187,35,208,224,60,181,83,201,87,175,167,83,57,73,249,242,179,156,118,196,60,245,189,142,248,28,46,82,12,180,17,211,56,244,133,104,154,221,241,34,112,60,105,254,158,232,68,223,77,194,32,233,136,247,225,204,13,58,226,92,166,169,27,204,58,226,197,34,77,67,122,128,81,58,34,117,163,151,161,23,198,104,200,255,74,167,35,62,132,169,59,117,39,118,234,82,187,79,54,250,103,215,95,34,47,180,157,55,174,39,21,149,156,7,176,48,9,49,110,32,131,52,81,108,60,162,209,83,26,61,20,35,17,197,97,148,136,209,25,207,224,183,211,228,102,38,38,158,157,36,163,199,183,252,202,228,187,141,88,249,94,144,140,26,243,52,141,134,221,238,114,185,52,151,3,51,140,103,221,126,175,215,235,162,91,67,220,184,114,249,34,92,141,26,61,209,19,86,223,60,57,230,223,195,198,217,169,35,167,201,217,105,146,174,61,121,102,122,158,49,241,18,195,186,157,186,158,55,12,192,219,51,8,62,188,150,195,127,128,86,118,109,248,46,68,233,185,248,103,104,21,15,151,174,147,206,135,61,243,48,90,61,219,156,118,21,193,211,174,34,63,19,174,51,106,188,183,215,50,254,214,111,8,199,78,109,35,176,125,153,61,19,253,70,181,141,101,212,181,178,208,42,178,161,62,74,12,141,156,91,52,29,53,126,193,132,142,250,29,203,60,233,127,61,49,159,90,207,45,243,240,164,195,63,61,252,223,234,88,248,235,153,7,39,111,15,108,203,60,56,232,240,15,191,50,44,195,28,28,63,55,143,158,226,47,107,13,233,160,73,207,51,76,188,180,250,182,121,2,202,86,214,222,180,14,13,80,250,122,104,30,30,227,205,49,254,178,110,230,201,145,129,255,222,30,152,199,131,175,199,102,255,4,175,143,240,199,175,123,29,190,57,124,251,212,60,32,138,135,248,43,94,128,226,201,225,215,129,121,112,248,188,210,5,60,91,131,206,160,99,30,31,225,175,120,200,12,218,102,255,41,254,212,67,98,19,255,209,188,158,170,31,245,152,39,247,182,111,14,158,126,37,225,144,92,142,59,252,163,88,62,232,152,253,195,183,150,181,243,162,20,232,191,26,221,189,146,39,177,42,225,126,181,118,5,143,213,96,90,111,107,135,199,224,88,26,76,252,233,193,46,7,232,128,137,130,125,208,176,171,19,179,168,239,224,216,195,172,77,203,214,164,131,199,150,101,90,7,154,20,233,209,129,121,112,156,175,72,33,120,203,80,55,160,111,13,242,229,44,133,111,168,101,57,122,75,203,162,47,52,189,161,102,95,177,146,186,106,96,33,173,67,136,1,92,177,210,148,26,69,111,6,166,101,117,170,186,215,83,179,96,1,119,103,217,127,48,217,179,223,224,13,166,139,96,66,62,68,188,149,54,252,92,235,214,131,99,88,40,215,6,175,151,200,244,124,30,46,207,93,71,142,109,186,47,111,54,109,113,251,72,192,63,166,139,56,80,254,227,209,169,227,222,228,235,55,158,25,203,57,172,24,110,213,157,92,175,225,127,35,163,39,254,109,92,30,156,92,137,213,210,152,46,60,79,140,217,55,27,99,17,173,141,190,120,124,171,209,23,63,252,32,154,145,103,28,247,155,27,145,198,118,144,184,196,168,1,103,47,156,69,204,158,207,24,244,122,234,221,52,140,253,198,25,248,209,89,136,86,32,154,141,132,1,122,194,167,159,169,39,87,2,140,249,137,49,129,95,148,49,247,67,207,177,242,157,233,58,130,59,80,55,13,17,6,19,15,252,195,33,202,27,114,148,85,137,180,248,217,119,55,237,77,62,102,42,87,169,145,120,136,20,198,65,175,151,145,6,241,199,183,236,247,77,116,74,6,69,235,185,113,212,16,221,108,252,110,126,161,77,129,153,165,31,195,18,51,59,50,86,198,1,88,240,166,6,92,162,76,39,115,225,205,134,234,249,81,57,150,214,63,150,96,197,69,212,211,8,193,197,229,67,213,12,166,75,166,24,178,102,20,116,77,34,59,168,206,219,23,219,243,135,62,205,164,67,97,216,78,134,88,97,210,171,141,54,126,149,131,185,235,56,50,160,225,198,94,56,185,166,139,185,26,126,105,68,43,126,62,51,102,177,13,109,1,113,97,199,174,109,168,62,224,32,94,200,202,212,88,234,42,32,66,131,220,212,35,47,207,234,221,16,46,22,99,148,175,137,210,249,141,182,214,249,147,82,76,221,234,42,241,63,244,3,35,218,232,118,148,43,198,237,34,246,148,189,100,134,162,226,238,7,251,230,189,27,92,35,244,182,110,153,165,14,179,2,8,17,19,144,64,39,52,207,227,113,166,206,217,192,54,183,25,53,254,241,248,150,46,54,141,92,104,234,94,140,70,212,93,252,36,154,144,145,90,129,195,158,90,143,177,183,144,198,17,108,101,22,135,139,168,41,134,162,201,207,89,146,199,120,62,15,111,100,60,172,182,85,207,114,121,31,230,157,55,74,149,148,58,12,4,158,1,32,57,134,239,136,8,214,150,171,129,7,119,2,88,99,28,137,105,24,224,137,244,221,113,232,57,186,61,208,188,11,67,88,162,37,25,67,33,240,199,74,60,155,92,232,133,212,33,240,253,94,231,198,13,61,153,26,22,77,33,49,104,18,158,189,214,46,141,48,146,193,144,189,6,11,105,101,244,10,133,161,255,25,250,43,246,29,15,242,62,21,26,83,119,5,165,87,46,207,147,211,20,255,140,67,40,162,175,92,224,81,239,10,126,233,184,47,10,39,153,57,194,184,66,37,123,152,235,187,160,9,76,189,112,105,172,13,123,65,120,118,18,135,158,7,109,51,214,149,126,202,143,178,3,173,76,19,107,23,187,179,121,170,122,231,12,237,184,205,210,85,76,66,79,248,176,63,90,236,117,97,251,59,109,231,16,54,84,61,134,98,99,126,181,14,132,181,128,52,64,105,200,202,211,29,197,97,213,81,146,141,106,30,146,150,0,122,33,126,13,23,177,120,129,249,56,15,115,151,249,12,116,210,153,249,21,238,224,149,157,204,199,161,29,59,91,30,97,30,250,114,147,217,91,183,65,118,133,87,100,156,154,71,216,165,150,97,249,100,139,216,36,156,21,180,146,162,201,3,105,190,113,99,127,105,199,18,24,31,96,85,110,145,118,194,101,64,208,191,160,191,200,90,61,144,250,235,27,202,12,182,136,218,158,140,211,130,162,204,154,236,82,188,207,21,42,226,173,219,138,3,188,84,244,24,90,168,6,87,112,134,121,118,213,186,188,106,63,43,219,70,246,76,114,75,36,59,178,210,206,66,179,162,29,24,141,101,50,39,167,74,206,147,153,155,82,116,108,113,18,168,70,236,206,100,218,236,48,39,234,127,190,76,231,161,3,87,248,233,227,249,5,222,140,67,103,61,20,255,60,255,248,193,164,76,48,152,185,211,117,235,150,88,24,10,250,221,180,59,89,223,77,219,68,18,25,180,98,242,212,49,242,170,48,104,181,219,5,97,237,101,49,201,86,220,86,28,23,217,99,43,227,186,163,166,121,181,253,154,167,146,177,155,73,160,197,204,69,64,16,178,133,240,104,123,231,105,24,227,185,137,169,189,131,213,181,154,68,169,217,110,179,12,153,83,80,223,75,185,66,38,169,144,233,240,172,205,52,60,103,105,180,20,213,77,149,95,181,0,23,243,221,92,18,72,62,153,132,4,165,200,6,115,3,221,2,131,86,175,132,128,217,133,114,9,228,90,75,231,56,131,207,182,39,110,138,96,117,72,72,14,248,93,68,228,86,216,137,144,131,45,2,79,37,220,232,78,230,41,81,180,39,215,14,216,164,32,23,151,119,200,68,25,6,230,73,175,138,60,167,221,116,174,162,77,54,73,167,102,146,78,17,192,136,83,0,162,137,52,130,112,25,219,209,29,19,35,63,206,96,151,249,143,98,132,208,26,232,244,148,60,98,193,14,158,19,55,142,206,205,167,216,13,25,69,68,184,216,104,43,170,94,83,31,188,190,108,206,225,240,177,148,77,95,58,238,194,167,43,4,144,230,213,37,117,187,122,166,245,152,112,185,129,250,20,181,7,147,203,14,229,237,90,122,232,172,63,153,197,82,6,21,98,122,100,134,195,201,138,23,155,140,60,60,136,186,216,48,135,184,229,201,137,44,172,111,52,157,98,187,225,25,74,29,18,157,166,49,59,157,199,183,23,78,65,228,178,25,133,75,25,211,236,230,112,230,228,47,233,58,117,101,60,200,47,14,48,105,104,51,192,253,85,230,193,170,52,114,142,73,176,27,65,51,34,204,111,178,120,193,94,109,31,208,115,125,9,200,213,10,228,82,188,34,199,148,61,122,34,128,63,122,109,56,138,240,61,153,152,204,141,136,176,151,245,244,184,103,244,44,252,53,239,34,155,73,37,247,171,143,238,4,60,20,158,113,11,212,105,172,243,139,93,192,192,1,63,131,106,133,93,237,6,254,138,237,236,102,3,37,102,36,124,24,17,252,251,125,1,139,158,174,141,177,76,151,80,5,177,99,6,117,152,225,143,12,83,155,213,248,177,113,208,56,123,253,245,245,135,11,241,254,227,207,167,221,18,37,107,151,88,203,162,70,6,5,92,196,49,232,147,31,165,234,22,57,244,220,175,190,161,216,151,93,99,17,194,212,246,200,15,38,35,100,48,138,181,79,50,230,142,253,158,40,99,94,149,39,55,240,220,64,26,42,111,241,221,192,200,18,79,219,115,103,129,225,35,73,241,16,151,185,102,133,9,216,43,99,46,9,139,13,197,73,255,102,254,172,88,170,161,160,181,122,150,139,45,181,199,158,44,166,93,82,205,125,138,68,52,176,75,252,72,146,39,216,173,137,13,193,200,118,180,148,72,217,79,113,11,197,155,23,112,224,2,214,209,16,221,187,27,144,113,236,109,112,1,229,223,219,224,149,4,106,117,35,90,147,74,59,248,183,130,49,242,188,26,211,167,41,133,230,178,233,227,219,150,10,233,166,29,199,48,62,237,102,72,225,206,244,237,168,37,217,101,180,216,139,32,234,195,135,180,55,37,249,146,32,110,72,196,123,129,204,75,56,149,180,117,75,197,194,10,150,9,224,158,232,161,233,201,96,134,120,215,125,34,48,90,236,202,68,60,233,118,196,18,175,73,97,212,211,181,224,242,37,191,241,200,207,90,135,120,195,177,139,237,5,47,74,239,78,241,148,18,24,180,128,33,68,115,161,148,133,59,175,41,132,18,129,67,122,253,171,176,87,110,34,212,51,122,61,102,218,220,85,33,252,26,242,107,232,31,49,119,168,61,34,95,235,146,208,90,115,97,128,74,91,116,243,161,158,136,150,43,126,20,150,6,205,198,28,241,43,205,159,224,190,75,92,63,19,221,174,120,97,199,25,211,101,159,245,78,31,252,206,91,145,70,23,240,126,38,201,235,115,37,31,216,207,253,55,33,192,84,70,28,3,158,199,112,11,38,213,182,91,183,74,232,67,110,2,84,210,250,134,84,154,27,185,196,48,117,17,255,249,15,152,6,231,76,140,71,1,103,52,16,50,68,202,250,91,78,210,222,155,78,250,235,191,219,189,122,188,142,139,40,146,241,196,78,228,67,188,236,1,3,6,38,119,33,125,116,180,193,45,164,2,170,169,232,31,204,235,253,81,94,249,201,61,73,89,219,167,36,89,133,114,99,133,180,62,47,144,193,165,86,139,248,143,111,131,39,203,31,61,196,106,68,199,77,225,81,30,223,242,34,181,122,185,42,42,131,115,245,178,69,102,104,228,17,197,202,26,245,196,218,130,139,93,167,45,183,189,17,171,62,85,88,146,31,65,125,35,214,253,242,133,94,230,31,245,204,65,9,26,249,121,129,12,27,121,75,7,233,155,77,42,49,106,88,29,171,234,79,24,1,173,104,232,124,0,163,95,173,210,93,30,69,171,43,65,219,16,122,193,10,141,201,59,211,79,87,205,239,73,203,253,209,106,235,69,171,223,10,95,162,9,35,80,114,88,213,200,33,6,236,6,47,60,235,21,207,26,215,227,117,139,156,199,229,234,234,9,140,166,75,3,66,6,106,242,86,63,51,30,106,55,175,107,23,175,70,253,66,177,104,10,147,181,29,112,38,93,39,5,125,100,242,43,15,17,195,234,73,127,51,236,245,106,166,125,95,226,247,10,30,217,3,244,143,63,132,64,68,12,241,58,98,50,119,61,7,17,248,190,186,49,27,68,148,21,29,250,59,70,84,3,150,203,242,193,222,98,230,110,45,214,13,166,101,161,33,171,170,210,254,225,216,78,220,196,184,28,244,72,48,179,24,118,162,149,55,50,243,4,216,97,251,4,20,233,107,34,191,19,231,52,206,10,169,208,70,158,220,46,40,114,88,227,213,130,211,106,54,219,102,18,121,110,218,106,154,77,165,86,55,133,90,137,211,72,115,79,125,65,107,117,195,218,153,175,15,64,118,46,236,125,203,244,139,237,6,219,217,57,4,144,37,231,148,103,87,115,243,0,110,66,119,213,213,172,91,207,184,153,10,39,220,181,153,114,53,65,230,129,84,126,92,159,30,171,146,128,59,21,173,239,152,112,59,87,158,102,115,175,243,174,83,31,82,172,196,31,82,169,210,95,41,191,61,139,93,135,127,168,88,148,224,5,21,187,139,91,165,135,7,185,130,61,190,37,118,75,184,83,250,227,134,66,239,13,32,73,98,18,16,190,120,181,17,255,243,223,47,27,148,54,93,112,147,89,24,58,124,251,78,47,187,132,92,150,201,50,43,202,140,170,89,86,89,118,217,226,225,237,2,224,18,185,241,54,3,243,236,249,70,124,175,141,141,220,40,216,29,155,158,222,53,186,10,21,229,240,117,123,60,16,21,97,207,0,210,83,72,84,175,11,195,71,59,176,33,111,214,192,83,226,152,11,76,186,57,86,28,70,150,6,53,88,47,24,95,9,0,28,184,80,137,104,230,168,141,109,218,195,255,37,12,32,72,132,80,202,227,101,224,108,111,164,212,196,196,251,87,223,170,174,126,191,88,253,92,244,140,5,55,204,214,40,151,116,20,186,0,160,44,161,29,17,49,130,152,175,140,254,193,118,177,247,175,136,168,112,240,74,84,23,115,72,104,66,156,145,168,236,64,156,127,253,89,184,62,87,207,102,50,32,53,132,228,104,111,107,78,136,99,93,8,177,160,195,98,86,150,68,16,102,157,157,146,208,76,185,56,106,81,43,231,58,255,146,151,46,105,33,23,73,185,223,1,175,187,19,14,148,75,161,193,36,151,45,190,124,120,254,245,249,187,247,207,95,188,127,77,9,252,155,119,159,207,47,190,189,248,248,145,10,117,205,15,31,47,190,189,252,248,203,47,239,46,46,94,191,162,7,229,205,213,101,139,232,155,9,143,73,190,180,215,22,223,139,131,171,210,111,221,32,35,163,82,142,222,238,76,244,238,219,86,80,75,71,197,167,18,16,86,23,242,255,2,240,85,54,66,234,52,58,111,45,182,241,94,85,7,173,198,153,90,6,218,131,99,49,111,106,11,232,170,233,203,207,47,7,125,106,169,100,245,147,146,213,36,158,12,250,101,61,208,58,226,98,70,208,181,155,251,104,157,3,158,239,144,34,204,254,144,206,111,112,51,135,66,218,169,78,162,40,182,48,45,170,183,96,70,126,148,23,93,106,107,46,213,145,246,71,200,93,21,86,197,247,237,96,169,52,153,170,166,184,168,150,177,111,145,145,220,110,174,30,22,46,167,217,40,93,165,141,15,9,154,52,226,253,49,83,141,28,6,147,208,247,93,74,240,212,30,118,221,208,170,73,83,85,177,239,44,111,103,47,212,48,149,33,98,57,14,195,218,33,28,121,227,78,100,23,61,228,67,233,211,11,90,228,79,112,83,110,34,139,89,83,117,33,92,164,45,53,198,109,46,211,86,251,153,136,233,7,66,31,112,217,173,202,26,111,146,77,174,247,206,63,111,84,225,48,159,86,133,28,188,105,34,247,76,148,223,83,110,86,172,99,141,184,22,124,98,11,84,114,85,107,133,215,72,33,108,95,170,156,183,157,85,115,25,245,132,215,5,228,153,218,94,34,43,149,214,191,36,167,172,232,186,47,3,206,17,208,61,145,114,208,200,234,152,85,175,95,160,148,151,170,252,38,114,129,171,240,212,96,119,128,64,74,255,92,246,174,54,251,182,244,184,170,94,102,5,89,96,220,218,224,127,169,84,61,165,136,152,143,165,159,226,200,141,161,12,161,149,189,175,20,168,105,252,37,66,128,119,19,170,11,57,37,111,121,172,24,141,4,31,224,224,93,107,222,156,188,3,120,220,41,139,79,49,52,37,92,36,123,133,97,21,194,216,153,227,231,92,161,129,95,246,76,52,87,233,124,170,149,137,210,11,116,113,118,103,106,233,51,237,213,205,180,38,14,21,1,114,85,41,72,87,3,164,168,236,44,223,85,25,254,171,1,83,80,254,9,67,36,91,75,33,131,106,150,85,23,60,7,85,198,148,142,113,226,167,43,218,246,33,75,13,132,169,101,81,13,216,32,139,133,53,199,110,64,185,53,47,141,50,122,94,27,117,153,147,160,189,213,70,197,29,169,247,13,97,79,38,50,2,194,35,58,29,115,49,189,43,215,84,204,234,231,122,118,181,70,121,104,229,165,182,52,133,95,109,170,26,146,57,141,122,85,175,27,224,53,59,70,174,74,37,136,70,97,92,29,132,253,226,102,123,255,122,82,161,47,212,97,158,59,33,38,98,243,159,113,78,187,121,224,54,22,47,1,120,97,116,85,196,93,187,13,161,43,157,40,192,130,200,204,199,14,128,185,17,1,98,182,235,216,231,141,8,2,232,73,74,123,98,116,38,138,80,182,38,176,130,84,56,133,54,2,250,20,21,235,218,69,191,103,252,9,18,129,177,20,37,118,238,136,47,31,10,168,44,194,88,20,55,166,120,55,21,65,88,250,196,42,195,246,141,237,122,228,36,128,222,57,197,208,224,185,249,16,30,133,40,72,115,174,242,243,151,119,130,20,28,164,75,91,33,51,97,161,37,200,230,18,26,105,50,95,4,215,148,141,168,11,118,119,90,206,194,154,76,219,212,73,2,156,151,239,240,100,141,195,233,20,145,176,163,182,115,202,65,24,121,210,32,182,26,143,66,238,176,32,89,99,131,63,41,66,163,255,250,129,41,141,126,253,129,207,11,255,107,123,218,186,170,254,157,202,86,179,190,234,144,135,240,37,82,190,192,77,124,72,98,234,6,50,17,3,78,210,114,72,145,64,90,118,202,58,150,218,49,82,184,45,201,169,35,243,174,31,121,210,135,220,134,194,159,125,195,20,191,141,229,204,5,34,235,228,247,203,24,188,3,180,146,212,178,71,88,160,86,251,15,46,252,231,215,231,23,176,113,102,17,124,59,200,112,19,194,174,130,8,174,86,43,140,64,175,232,92,147,77,7,22,243,217,226,1,219,130,169,169,80,102,53,61,35,219,121,201,244,35,118,103,51,162,90,176,72,251,145,147,185,128,92,73,159,203,64,89,144,202,68,185,96,5,162,113,157,173,160,252,7,39,121,106,23,231,151,233,152,95,245,68,29,5,193,152,106,226,141,178,131,200,206,217,208,209,250,100,216,237,250,89,85,195,92,38,221,165,132,215,183,227,164,219,56,251,103,72,31,50,44,98,100,238,82,138,236,197,105,215,62,131,120,10,90,148,165,59,50,133,173,98,26,114,21,121,182,218,252,132,149,141,1,7,69,20,194,80,104,63,113,90,213,36,242,72,84,34,152,185,50,41,77,1,171,93,232,134,242,4,142,244,195,189,106,95,123,32,50,59,241,180,83,105,204,158,171,98,99,118,179,175,222,120,73,203,243,89,38,11,47,85,125,138,219,63,91,165,204,6,85,133,202,7,39,38,26,187,247,101,96,5,23,254,53,122,77,105,191,240,154,247,191,110,182,9,241,174,193,199,241,239,160,97,146,59,155,81,101,182,35,86,200,34,47,175,175,134,226,102,67,73,141,208,50,8,54,146,154,44,164,152,85,162,157,119,42,206,58,65,5,210,187,206,58,229,61,219,52,204,158,51,78,91,178,40,150,129,164,81,155,37,22,213,219,98,128,74,1,87,205,200,11,103,31,35,165,173,35,113,121,217,235,136,230,43,133,76,155,87,16,167,133,251,215,113,28,198,124,215,199,29,165,192,124,51,160,166,114,188,152,53,175,174,238,207,101,182,129,130,194,15,190,179,5,23,182,235,44,123,234,62,101,97,239,255,23,223,230,202,179,7,224,102,7,141,14,245,51,145,37,206,221,42,25,241,193,209,98,53,233,248,104,126,38,70,255,242,104,35,66,194,115,101,195,44,91,216,170,73,86,90,248,50,73,248,108,197,196,131,107,195,59,101,139,85,237,97,195,229,163,64,155,71,37,198,204,38,89,130,204,128,79,68,188,15,233,12,229,141,13,215,170,206,110,176,36,104,79,23,142,159,211,25,62,221,49,37,168,153,25,95,171,169,189,109,98,36,117,208,63,89,186,176,157,42,176,221,30,20,163,137,247,20,161,239,24,210,163,119,119,12,200,239,180,225,164,7,27,7,176,119,156,48,120,47,167,192,246,61,36,207,122,22,246,93,253,116,66,101,29,234,116,122,102,42,155,125,92,191,224,195,190,192,5,117,146,26,23,47,107,248,46,95,150,140,7,72,140,101,156,49,254,153,247,38,27,223,239,23,91,166,167,31,108,58,19,178,195,129,2,33,223,8,77,213,176,160,189,45,121,184,35,249,241,199,80,109,63,205,243,56,196,189,137,52,40,251,131,57,25,180,51,112,166,37,43,149,252,131,116,116,83,201,82,212,147,252,64,47,249,216,242,84,111,247,236,207,160,61,173,204,207,134,45,61,207,141,18,128,224,202,241,129,186,194,255,125,101,255,231,16,106,236,202,116,77,249,66,150,237,34,214,35,174,71,177,52,20,40,164,83,232,66,146,159,33,28,232,40,114,12,247,52,8,146,134,179,25,140,106,156,125,130,72,135,34,233,100,177,80,202,74,37,251,104,65,165,27,233,57,234,227,74,62,182,66,8,33,206,78,120,20,168,129,180,35,49,115,23,149,47,54,51,85,108,225,16,160,183,33,133,96,166,247,220,138,200,197,126,67,39,3,113,202,173,39,37,77,10,95,34,84,49,83,35,244,146,214,146,224,92,182,223,193,129,50,251,182,71,125,42,186,29,38,181,206,91,155,28,59,176,70,197,170,231,81,164,151,238,182,144,13,101,13,252,73,39,72,191,87,215,21,132,66,31,170,232,184,70,125,41,34,211,47,177,87,105,215,236,54,43,205,242,47,178,190,224,162,218,176,210,46,169,124,176,85,249,92,169,142,13,61,0,19,72,172,1,74,234,77,115,171,4,77,108,208,208,237,74,12,119,9,228,112,147,239,98,51,188,22,63,105,82,104,113,245,178,77,145,37,239,207,78,95,12,11,132,145,45,69,205,72,177,73,2,40,142,89,155,80,110,172,211,186,104,84,29,163,254,204,115,117,78,110,144,79,137,111,218,37,104,35,180,146,173,162,142,85,248,248,16,137,83,140,1,173,175,249,124,52,105,153,27,184,169,139,36,147,186,228,88,135,153,221,62,13,203,223,252,110,148,152,248,208,161,87,60,8,179,253,88,254,248,129,231,88,117,162,197,151,10,234,195,225,44,131,40,182,117,47,66,69,149,63,220,27,194,12,125,55,232,242,175,250,148,207,234,242,175,186,233,243,13,151,146,126,227,195,90,156,252,243,242,169,111,181,212,135,75,217,114,38,19,218,126,126,180,23,88,185,129,49,55,84,67,81,124,125,100,101,231,50,40,50,100,223,12,234,95,17,208,16,163,202,39,127,229,97,88,245,53,226,38,211,73,237,131,44,98,124,148,125,69,166,127,141,184,77,168,170,247,42,236,156,239,142,164,205,225,239,248,248,144,121,87,159,129,83,84,121,57,167,179,65,250,167,131,48,241,150,188,49,49,127,196,180,185,75,133,32,58,10,244,86,93,153,16,32,4,247,22,75,157,61,105,161,153,22,96,233,196,198,134,178,125,27,128,137,54,233,97,194,155,186,16,140,160,78,223,210,18,220,40,131,87,217,170,186,173,149,183,205,191,29,209,91,170,175,23,242,22,249,183,32,251,55,128,151,110,128,232,97,134,65,182,197,161,108,79,125,72,223,154,183,224,60,97,106,78,56,89,80,24,50,41,21,129,213,253,47,209,215,238,195,211,63,0,0,0}; + +static const unsigned char v6[] = {45,45,45,45,45,66,69,71,73,78,32,67,69,82,84,73,70,73,67,65,84,69,45,45,45,45,45,10,77,73,73,66,67,84,67,66,115,65,73,74,65,75,57,119,98,73,68,107,72,110,65,111,77,65,111,71,67,67,113,71,83,77,52,57,66,65,77,67,77,65,48,120,67,122,65,74,66,103,78,86,66,65,89,84,65,107,108,70,77,66,52,88,10,68,84,73,122,77,68,69,121,79,84,73,120,77,106,69,122,79,70,111,88,68,84,77,122,77,68,69,121,78,106,73,120,77,106,69,122,79,70,111,119,68,84,69,76,77,65,107,71,65,49,85,69,66,104,77,67,83,85,85,119,87,84,65,84,10,66,103,99,113,104,107,106,79,80,81,73,66,66,103,103,113,104,107,106,79,80,81,77,66,66,119,78,67,65,65,82,122,83,81,83,53,79,72,100,49,55,108,85,101,78,73,43,54,107,112,57,87,89,117,48,99,120,117,69,73,105,47,74,84,10,106,112,104,98,67,109,100,74,68,49,99,85,118,104,109,122,77,57,47,112,104,118,74,84,57,107,97,49,48,90,57,116,111,90,104,103,110,66,113,48,111,48,120,102,84,81,52,106,67,49,118,119,77,65,111,71,67,67,113,71,83,77,52,57,10,66,65,77,67,65,48,103,65,77,69,85,67,73,81,67,101,48,84,50,69,48,71,79,105,86,101,57,75,119,118,73,69,80,101,88,49,74,49,74,48,84,55,84,78,97,99,103,82,48,89,97,51,51,72,86,57,86,103,73,103,78,118,100,110,10,97,69,87,105,66,112,49,120,115,104,115,52,105,122,54,87,98,112,120,114,83,49,73,72,117,99,114,113,107,90,117,74,76,102,78,90,71,90,73,61,10,45,45,45,45,45,69,78,68,32,67,69,82,84,73,70,73,67,65,84,69,45,45,45,45,45,10,0}; + +static const unsigned char v7[] = {45,45,45,45,45,66,69,71,73,78,32,69,67,32,80,82,73,86,65,84,69,32,75,69,89,45,45,45,45,45,10,77,72,99,67,65,81,69,69,73,67,66,122,51,72,79,107,81,76,80,66,68,116,100,107,110,113,67,55,107,49,80,78,115,87,106,54,72,102,104,121,78,66,53,77,101,110,102,106,109,113,105,111,111,65,111,71,67,67,113,71,83,77,52,57,10,65,119,69,72,111,85,81,68,81,103,65,69,99,48,107,69,117,84,104,51,100,101,53,86,72,106,83,80,117,112,75,102,86,109,76,116,72,77,98,104,67,73,118,121,85,52,54,89,87,119,112,110,83,81,57,88,70,76,52,90,115,122,80,102,10,54,89,98,121,85,47,90,71,116,100,71,102,98,97,71,89,89,74,119,97,116,75,78,77,88,48,48,79,73,119,116,98,56,65,61,61,10,45,45,45,45,45,69,78,68,32,69,67,32,80,82,73,86,65,84,69,32,75,69,89,45,45,45,45,45,10,0}; + +static const struct packed_file { + const char *name; + const unsigned char *data; + size_t size; + time_t mtime; +} packed_files[] = { + {"/web_root/bundle.js.gz", v0, sizeof(v0) - 1, 1709984472}, + {"/web_root/components.js.gz", v1, sizeof(v1) - 1, 1709984472}, + {"/web_root/history.min.js.gz", v2, sizeof(v2) - 1, 1709984472}, + {"/web_root/index.html.gz", v3, sizeof(v3) - 1, 1709996122}, + {"/web_root/main.css.gz", v4, sizeof(v4) - 1, 1709996124}, + {"/web_root/main.js.gz", v5, sizeof(v5) - 1, 1709984472}, + {"/certs/server_cert.pem", v6, sizeof(v6) - 1, 1709980241}, + {"/certs/server_key.pem", v7, sizeof(v7) - 1, 1709980241}, + {NULL, NULL, 0, 0} +}; + +static int scmp(const char *a, const char *b) { + while (*a && (*a == *b)) a++, b++; + return *(const unsigned char *) a - *(const unsigned char *) b; +} + +const char *mg_unlist(size_t no) { + return packed_files[no].name; +} + +const char *mg_unpack(const char *name, size_t *size, time_t *mtime) { + const struct packed_file *p; + for (p = packed_files; p->name != NULL; p++) { + if (scmp(p->name, name) != 0) continue; + if (size != NULL) *size = p->size; + if (mtime != NULL) *mtime = p->mtime; + return (const char *) p->data; + } + return NULL; +}; diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/tailwind.config.js b/reference-projects/windows-macos-linux/web-ui-dashboard/tailwind.config.js new file mode 100644 index 00000000..9309f0be --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/tailwind.config.js @@ -0,0 +1,17 @@ +module.exports = { + content: ['./web_root/*.{html,js}'], + xplugins: [ 'tailwindcss', 'xautoprefixer' ], + corePlugins: {outline: false}, + theme: { + extend: {}, + fontFamily: { + sans: + [ + "Inter var, Arial, Helvetica, sans-serif", { + fontFeatureSettings: '"cv11", "ss01"', + fontVariationSettings: '"opsz" 32', + } + ] + } + } +} diff --git a/reference-projects/windows-macos-linux/web-ui-dashboard/web_root/bundle.js b/reference-projects/windows-macos-linux/web-ui-dashboard/web_root/bundle.js new file mode 100644 index 00000000..58426ace --- /dev/null +++ b/reference-projects/windows-macos-linux/web-ui-dashboard/web_root/bundle.js @@ -0,0 +1 @@ +var n,t,e,_,r,o,i,u,l,c={},a=[],s=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function f(n,t){for(var e in t)n[e]=t[e];return n}function p(n){var t=n.parentNode;t&&t.removeChild(n)}function h(t,e,_){var r,o,i,u={};for(i in e)"key"==i?r=e[i]:"ref"==i?o=e[i]:u[i]=e[i];if(arguments.length>2&&(u.children=arguments.length>3?n.call(arguments,2):_),"function"==typeof t&&null!=t.defaultProps)for(i in t.defaultProps)void 0===u[i]&&(u[i]=t.defaultProps[i]);return d(t,u,r,o,null)}function d(n,_,r,o,i){var u={type:n,props:_,key:r,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==i?++e:i};return null==i&&null!=t.vnode&&t.vnode(u),u}function v(){return{current:null}}function m(n){return n.children}function y(n,t){this.props=n,this.context=t}function g(n,t){if(null==t)return n.__?g(n.__,n.__.__k.indexOf(n)+1):null;for(var e;tt&&r.sort(u));C.__r=0}function x(n,t,e,_,r,o,i,u,l,s){var f,p,h,v,y,b,k,C=_&&_.__k||a,x=C.length;for(e.__k=[],f=0;f0?d(v.type,v.props,v.key,v.ref?v.ref:null,v.__v):v)){if(v.__=e,v.__b=e.__b+1,null===(h=C[f])||h&&v.key==h.key&&v.type===h.type)C[f]=void 0;else for(p=0;p=0;t--)if((e=n.__k[t])&&(_=A(e)))return _;return null}function P(n,t,e,_,r){var o;for(o in e)"children"===o||"key"===o||o in t||N(n,o,null,e[o],_);for(o in t)r&&"function"!=typeof t[o]||"children"===o||"key"===o||"value"===o||"checked"===o||e[o]===t[o]||N(n,o,t[o],e[o],_)}function S(n,t,e){"-"===t[0]?n.setProperty(t,null==e?"":e):n[t]=null==e?"":"number"!=typeof e||s.test(t)?e:e+"px"}function N(n,t,e,_,r){var o;n:if("style"===t)if("string"==typeof e)n.style.cssText=e;else{if("string"==typeof _&&(n.style.cssText=_=""),_)for(t in _)e&&t in e||S(n.style,t,"");if(e)for(t in e)_&&e[t]===_[t]||S(n.style,t,e[t])}else if("o"===t[0]&&"n"===t[1])o=t!==(t=t.replace(/Capture$/,"")),t=t.toLowerCase()in n?t.toLowerCase().slice(2):t.slice(2),n.l||(n.l={}),n.l[t+o]=e,e?_||n.addEventListener(t,o?D:w,o):n.removeEventListener(t,o?D:w,o);else if("dangerouslySetInnerHTML"!==t){if(r)t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==t&&"height"!==t&&"href"!==t&&"list"!==t&&"form"!==t&&"tabIndex"!==t&&"download"!==t&&t in n)try{n[t]=null==e?"":e;break n}catch(n){}"function"==typeof e||(null==e||!1===e&&"-"!==t[4]?n.removeAttribute(t):n.setAttribute(t,e))}}function w(n){return this.l[n.type+!1](t.event?t.event(n):n)}function D(n){return this.l[n.type+!0](t.event?t.event(n):n)}function T(n,e,_,r,o,i,u,l,c){var a,s,p,h,d,v,g,b,k,C,E,H,U,A,P,S=e.type;if(void 0!==e.constructor)return null;null!=_.__h&&(c=_.__h,l=e.__e=_.__e,e.__h=null,i=[l]),(a=t.__b)&&a(e);try{n:if("function"==typeof S){if(b=e.props,k=(a=S.contextType)&&r[a.__c],C=a?k?k.props.value:a.__:r,_.__c?g=(s=e.__c=_.__c).__=s.__E:("prototype"in S&&S.prototype.render?e.__c=s=new S(b,C):(e.__c=s=new y(b,C),s.constructor=S,s.render=V),k&&k.sub(s),s.props=b,s.state||(s.state={}),s.context=C,s.__n=r,p=s.__d=!0,s.__h=[],s._sb=[]),null==s.__s&&(s.__s=s.state),null!=S.getDerivedStateFromProps&&(s.__s==s.state&&(s.__s=f({},s.__s)),f(s.__s,S.getDerivedStateFromProps(b,s.__s))),h=s.props,d=s.state,s.__v=e,p)null==S.getDerivedStateFromProps&&null!=s.componentWillMount&&s.componentWillMount(),null!=s.componentDidMount&&s.__h.push(s.componentDidMount);else{if(null==S.getDerivedStateFromProps&&b!==h&&null!=s.componentWillReceiveProps&&s.componentWillReceiveProps(b,C),!s.__e&&null!=s.shouldComponentUpdate&&!1===s.shouldComponentUpdate(b,s.__s,C)||e.__v===_.__v){for(e.__v!==_.__v&&(s.props=b,s.state=s.__s,s.__d=!1),s.__e=!1,e.__e=_.__e,e.__k=_.__k,e.__k.forEach((function(n){n&&(n.__=e)})),E=0;E2&&(u.children=arguments.length>3?n.call(arguments,2):_),d(t.type,u,r||t.key,o||t.ref,null)}function $(n,t){var e={__c:t="__cC"+l++,__:n,Consumer:function(n,t){return n.children(t)},Provider:function(n){var e,_;return this.getChildContext||(e=[],(_={})[t]=this,this.getChildContext=function(){return _},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&e.some((function(n){n.__e=!0,k(n)}))},this.sub=function(n){e.push(n);var t=n.componentWillUnmount;n.componentWillUnmount=function(){e.splice(e.indexOf(n),1),t&&t.call(n)}}),n.children}};return e.Provider.__=e.Consumer.contextType=e}n=a.slice,t={__e:function(n,t,e,_){for(var r,o,i;t=t.__;)if((r=t.__c)&&!r.__)try{if((o=r.constructor)&&null!=o.getDerivedStateFromError&&(r.setState(o.getDerivedStateFromError(n)),i=r.__d),null!=r.componentDidCatch&&(r.componentDidCatch(n,_||{}),i=r.__d),i)return r.__E=r}catch(t){n=t}throw n}},e=0,_=function(n){return null!=n&&void 0===n.constructor},y.prototype.setState=function(n,t){var e;e=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=f({},this.state),"function"==typeof n&&(n=n(f({},e),this.props)),n&&f(e,n),null!=n&&this.__v&&(t&&this._sb.push(t),k(this))},y.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),k(this))},y.prototype.render=m,r=[],i="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,u=function(n,t){return n.__v.__b-t.__v.__b},C.__r=0,l=0;var j,q,B,K,G=0,z=[],J=[],Q=t.__b,X=t.__r,Y=t.diffed,Z=t.__c,nn=t.unmount;function tn(n,e){t.__h&&t.__h(q,n,G||e),G=0;var _=q.__H||(q.__H={__:[],__h:[]});return n>=_.__.length&&_.__.push({__V:J}),_.__[n]}function en(n){return G=1,_n(kn,n)}function _n(n,t,e){var _=tn(j++,2);if(_.t=n,!_.__c&&(_.__=[e?e(t):kn(void 0,t),function(n){var t=_.__N?_.__N[0]:_.__[0],e=_.t(t,n);t!==e&&(_.__N=[e,_.__[1]],_.__c.setState({}))}],_.__c=q,!q.u)){var r=function(n,t,e){if(!_.__c.__H)return!0;var r=_.__c.__H.__.filter((function(n){return n.__c}));if(r.every((function(n){return!n.__N})))return!o||o.call(this,n,t,e);var i=!1;return r.forEach((function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}})),!(!i&&_.__c.props===n)&&(!o||o.call(this,n,t,e))};q.u=!0;var o=q.shouldComponentUpdate,i=q.componentWillUpdate;q.componentWillUpdate=function(n,t,e){if(this.__e){var _=o;o=void 0,r(n,t,e),o=_}i&&i.call(this,n,t,e)},q.shouldComponentUpdate=r}return _.__N||_.__}function rn(n,e){var _=tn(j++,3);!t.__s&&bn(_.__H,e)&&(_.__=n,_.i=e,q.__H.__h.push(_))}function on(n,e){var _=tn(j++,4);!t.__s&&bn(_.__H,e)&&(_.__=n,_.i=e,q.__h.push(_))}function un(n){return G=5,cn((function(){return{current:n}}),[])}function ln(n,t,e){G=6,on((function(){return"function"==typeof n?(n(t()),function(){return n(null)}):n?(n.current=t(),function(){return n.current=null}):void 0}),null==e?e:e.concat(n))}function cn(n,t){var e=tn(j++,7);return bn(e.__H,t)?(e.__V=n(),e.i=t,e.__h=n,e.__V):e.__}function an(n,t){return G=8,cn((function(){return n}),t)}function sn(n){var t=q.context[n.__c],e=tn(j++,9);return e.c=n,t?(null==e.__&&(e.__=!0,t.sub(q)),t.props.value):n.__}function fn(n,e){t.useDebugValue&&t.useDebugValue(e?e(n):n)}function pn(n){var t=tn(j++,10),e=en();return t.__=n,q.componentDidCatch||(q.componentDidCatch=function(n,_){t.__&&t.__(n,_),e[1](n)}),[e[0],function(){e[1](void 0)}]}function hn(){var n=tn(j++,11);if(!n.__){for(var t=q.__v;null!==t&&!t.__m&&null!==t.__;)t=t.__;var e=t.__m||(t.__m=[0,0]);n.__="P"+e[0]+"-"+e[1]++}return n.__}function dn(){for(var n;n=z.shift();)if(n.__P&&n.__H)try{n.__H.__h.forEach(yn),n.__H.__h.forEach(gn),n.__H.__h=[]}catch(o){n.__H.__h=[],t.__e(o,n.__v)}}t.__b=function(n){q=null,Q&&Q(n)},t.__r=function(n){X&&X(n),j=0;var t=(q=n.__c).__H;t&&(B===q?(t.__h=[],q.__h=[],t.__.forEach((function(n){n.__N&&(n.__=n.__N),n.__V=J,n.__N=n.i=void 0}))):(t.__h.forEach(yn),t.__h.forEach(gn),t.__h=[])),B=q},t.diffed=function(n){Y&&Y(n);var e=n.__c;e&&e.__H&&(e.__H.__h.length&&(1!==z.push(e)&&K===t.requestAnimationFrame||((K=t.requestAnimationFrame)||mn)(dn)),e.__H.__.forEach((function(n){n.i&&(n.__H=n.i),n.__V!==J&&(n.__=n.__V),n.i=void 0,n.__V=J}))),B=q=null},t.__c=function(n,_){_.some((function(n){try{n.__h.forEach(yn),n.__h=n.__h.filter((function(n){return!n.__||gn(n)}))}catch(e){_.some((function(n){n.__h&&(n.__h=[])})),_=[],t.__e(e,n.__v)}})),Z&&Z(n,_)},t.unmount=function(n){nn&&nn(n);var e,_=n.__c;_&&_.__H&&(_.__H.__.forEach((function(n){try{yn(n)}catch(n){e=n}})),_.__H=void 0,e&&t.__e(e,_.__v))};var vn="function"==typeof requestAnimationFrame;function mn(n){var t,e=function(){clearTimeout(_),vn&&cancelAnimationFrame(t),setTimeout(n)},_=setTimeout(e,100);vn&&(t=requestAnimationFrame(e))}function yn(n){var t=q,e=n.__c;"function"==typeof e&&(n.__c=void 0,e()),q=t}function gn(n){var t=q;n.__c=n.__(),q=t}function bn(n,t){return!n||n.length!==t.length||t.some((function(t,e){return t!==n[e]}))}function kn(n,t){return"function"==typeof t?t(n):t}var Cn=function(n,t,e,_){var r;t[0]=0;for(var o=1;o=5&&((r||!n&&5===_)&&(i.push(_,0,r,e),_=6),n&&(i.push(_,n,0,e),_=6)),r=""},l=0;l"===t?(_=1,r=""):r=t+r[0]:o?t===o?o="":r+=t:'"'===t||"'"===t?o=t:">"===t?(u(),_=1):_&&("="===t?(_=5,e=r,r=""):"/"===t&&(_<5||">"===n[l][c+1])?(u(),3===_&&(i=i[0]),_=i,(i=i[0]).push(2,0,_),_=0):" "===t||"\t"===t||"\n"===t||"\r"===t?(u(),_=2):r+=t),3===_&&"!--"===r&&(_=4,i=i[0])}return u(),i}(n)),t),arguments,[])).length>1?t:t[0]}var Hn=En.bind(h);var Un={};function An(n,t){for(var e in t)n[e]=t[e];return n}function Pn(n,t,e){var _,r=/(?:\?([^#]*))?(#.*)?$/,o=n.match(r),i={};if(o&&o[1])for(var u=o[1].split("&"),l=0;lt.rank?-1:n.index-t.index}function Nn(n,t){return n.index=t,n.rank=function(n){return n.props.default?0:wn(n.props.path).map(Dn).join("")}(n),n.props}function wn(n){return n.replace(/(^\/+|\/+$)/g,"").split("/")}function Dn(n){return":"==n.charAt(0)?1+"*+?".indexOf(n.charAt(n.length-1))||4:5}var Tn={},Rn=[],Ln=[],Mn=null,Wn={url:In()},Vn=$(Wn);function Fn(){var n=sn(Vn);if(n===Wn){var t=en()[1];rn((function(){return Ln.push(t),function(){return Ln.splice(Ln.indexOf(t),1)}}),[])}return[n,On]}function In(){var n;return""+((n=Mn&&Mn.location?Mn.location:Mn&&Mn.getCurrentLocation?Mn.getCurrentLocation():"undefined"!=typeof location?location:Tn).pathname||"")+(n.search||"")}function On(n,t){return void 0===t&&(t=!1),"string"!=typeof n&&n.url&&(t=n.replace,n=n.url),function(n){for(var t=Rn.length;t--;)if(Rn[t].canRoute(n))return!0;return!1}(n)&&function(n,t){void 0===t&&(t="push"),Mn&&Mn[t]?Mn[t](n):"undefined"!=typeof history&&history[t+"State"]&&history[t+"State"](null,null,n)}(n,t?"replace":"push"),$n(n)}function $n(n){for(var t=!1,e=0;e new Promise(resolve => setTimeout(resolve, ms, val)); + +export const Icons = { + heart: props => html``, + downArrowBox: props => html` `, + upArrowBox: props => html` `, + cog: props => html` `, + settingsH: props => html` `, + settingsV: props => html` `, + scan: props => html` `, + desktop: props => html` `, + alert: props => html` `, + bell: props => html` `, + refresh: props => html` `, + bars4: props => html` `, + bars3: props => html` `, + logout: props => html` `, + save: props => html` `, + email: props => html` `, + expand: props => html` `, + shrink: props => html` `, + ok: props => html``, + fail: props => html` `, + upload: props => html` `, + download: props => html` `, + bolt: props => html` `, + home: props => html` `, + link: props => html` `, + shield: props => html` `, + barsdown: props => html` `, + arrowdown: props => html` `, + arrowup: props => html` `, + warn: props => html` `, + info: props => html` `, + exclamationTriangle: props => html` `, + thumbUp: props => html` `, + backward: props => html` `, + chip: props => html` `, + camera: props => html` `, + arrows: props => html` `, + doc: props => html` `, +}; + +export const tipColors = { + green: 'bg-green-100 text-green-900 ring-green-300', + yellow: 'bg-yellow-100 text-yellow-900 ring-yellow-300', + red: 'bg-red-100 text-red-900 ring-red-300', +}; + +export function Button({title, onclick, disabled, cls, icon, ref, colors, hovercolor, disabledcolor}) { + const [spin, setSpin] = useState(false); + const cb = function(ev) { + const res = onclick ? onclick() : null; + if (res && typeof (res.catch) === 'function') { + setSpin(true); + res.catch(() => false).then(() => setSpin(false)); + } + }; + if (!colors) colors = 'bg-blue-600 hover:bg-blue-500 disabled:bg-blue-400'; + return html` +