diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..aa2ccfb0 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,21 @@ +{ + "name": "ESP-IDF Development", + "image": "espressif/idf:v4.4.6", + "workspaceFolder": "/project", + "workspaceMount": "source=${localWorkspaceFolder},target=/project,type=bind", + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.shell.linux": "/bin/bash" + }, + "extensions": [ + "ms-vscode.cpptools", + "usernamehw.errorlens", + "espressif.esp-idf-extension" // ESP-IDF extension + ] + } + }, + "runArgs": [ + "--privileged" // If needed for accessing certain hardware resources + ] +} diff --git a/CMakeLists.txt b/CMakeLists.txt index fbb11090..644b7260 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ add_definitions(-DSTATE_MACHINE_LOGGER=1) add_definitions(-DHIERARCHICAL_STATES=1) # Uncomment line below to get memory usage trace details -#add_definitions(-DENABLE_MEMTRACE=1) +# add_definitions(-DENABLE_MEMTRACE=1) #uncomment line below to get network ethernet debug logs #add_definitions(-DNETWORK_ETHERNET_LOG_LEVEL=ESP_LOG_DEBUG) #uncomment line below to get network status debug logs @@ -53,6 +53,7 @@ endfunction() set(EXTRA_COMPONENT_DIRS components/platform_console/app_recovery components/platform_console/app_squeezelite ) project(recovery) +spiffs_create_partition_image(spiffs spiffs FLASH_IN_PROJECT DEPENDS generate_spiffs_bin ) # we need own "esp_app_desc" to take precedence add_custom_command( @@ -64,7 +65,7 @@ add_custom_command( # when building recovery, add app_recovery to the link get_target_property(BCA recovery.elf LINK_LIBRARIES) -list(REMOVE_ITEM BCA "idf::app_squeezelite" "idf::app_recovery" "-Wl,--Map=${BUILD_DIR}/recovery.map") +list(REMOVE_ITEM BCA "idf::app_squeezelite" "idf::app_recovery" "-Wl,--Map=${BUILD_DIR}/recovery.map" "-Wl,--cref -Wl,--Map=${BUILD_DIR}/recovery.map") set_target_properties(recovery.elf PROPERTIES LINK_LIBRARIES "${BCA};idf::app_recovery;-Wl,--Map=${BUILD_DIR}/recovery.map") # create files with size for recovery @@ -74,10 +75,12 @@ set_target_properties(recovery.elf PROPERTIES LINK_LIBRARIES "${BCA};idf::app_re add_executable(squeezelite.elf "CMakeLists.txt") add_dependencies(squeezelite.elf recovery.elf) set_target_properties(squeezelite.elf PROPERTIES LINK_LIBRARIES "${BCA};idf::app_squeezelite;-Wl,--Map=${BUILD_DIR}/squeezelite.map") +get_target_property(BCASQUEEZELITE squeezelite.elf LINK_LIBRARIES) add_custom_command( TARGET squeezelite.elf POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "Generating ${BUILD_DIR}/squeezelite.bin" + COMMAND ${CMAKE_COMMAND} -E echo "BCA value for squeezelite is: ${BCASQUEEZELITE}" COMMAND ${ESPTOOLPY} elf2image ${ESPTOOLPY_FLASH_OPTIONS} ${ESPTOOLPY_ELF2IMAGE_OPTIONS} -o "squeezelite.bin" "squeezelite.elf" VERBATIM ) @@ -128,77 +131,83 @@ if(CMAKE_HOST_UNIX) add_dependencies(__idf_spotify set_cspot_permissions) endif() +# Set the main project library target here before including protocol_buffers.cmake +# add_library(main_project_lib ...) + +# Include the protocol_buffers.cmake file +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/protobuf ${CMAKE_CURRENT_BINARY_DIR}/protobuf) + + # ======================= DEBUG FLAGS ============================ #target_compile_definitions(__idf_esp_eth PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO) -#target_compile_definitions(__idf_services PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_services PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -#target_compile_definitions(__idf_driver PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -#target_compile_definitions(__idf_wifi-manager PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -#target_compile_definitions(__idf_esp_wifi PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -#target_compile_definitions(__idf_platform_console PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_driver PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_wifi-manager PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_wifi PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_platform_console PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -#target_compile_definitions(__idf_app_recovery PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO) -# target_compile_definitions(__idf_esp_eth PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO) -# target_compile_definitions(__idf_esp_event PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO) -# target_compile_definitions(__idf_esp_netif PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_app_recovery PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO) +target_compile_definitions(__idf_esp_eth PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO) +target_compile_definitions(__idf_esp_event PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO) +target_compile_definitions(__idf_esp_netif PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) + +target_compile_definitions(__idf_freertos PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_bt PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_ERROR) +target_compile_definitions(__idf_mdns PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_tcpip_adapter PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_tcp_transport PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_freertos PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -#target_compile_definitions(__idf_bt PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_ERROR) -# target_compile_definitions(__idf_mdns PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_tcpip_adapter PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_tcp_transport PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_app_squeezelite PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_app_trace PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_app_update PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_asio PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_audio PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_bootloader_support PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -#target_compile_definitions(__idf_app_squeezelite PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_app_trace PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_app_update PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_asio PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_audio PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_bootloader_support PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) - -# target_compile_definitions(__idf_cbor PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_cmock PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_coap PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_console PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_cxx PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_display PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_driver PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_driver_bt PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_efuse PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp-dsp PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp-tls PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp32 PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_espcoredump PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_adc_cal PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_common PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_gdbstub PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_hid PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_https_ota PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_http_client PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_http_server PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_hw_support PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_ipc PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_local_ctrl PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_pm PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_ringbuf PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_rom PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_serial_slave_link PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_system PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_timer PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_esp_websocket_client PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_expat PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_fatfs PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_freemodbus PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_hal PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_heap PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_jsmn PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_json PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_cbor PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_cmock PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_coap PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_console PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_cxx PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_display PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_driver PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_driver_bt PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_efuse PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp-dsp PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp-tls PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp32 PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_espcoredump PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_adc_cal PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_common PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_gdbstub PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_hid PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_https_ota PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_http_client PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_http_server PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_hw_support PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_ipc PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_local_ctrl PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_pm PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_ringbuf PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_rom PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_serial_slave_link PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_system PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_esp_timer PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_expat PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_fatfs PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_freemodbus PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_hal PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_heap PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_jsmn PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_json PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) # target_compile_definitions(__idf_libsodium PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) # target_compile_definitions(__idf_log PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) # target_compile_definitions(__idf_lwip PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_main PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_mbedtls PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_main PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_mbedtls PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) # target_compile_definitions(mbedcrypto PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) # target_compile_definitions(mbedtls PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) # target_compile_definitions(mbedx509 PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) @@ -208,24 +217,24 @@ endif() # target_compile_definitions(__idf_nvs_flash PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) # target_compile_definitions(__idf_openssl PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) # target_compile_definitions(__idf_perfmon PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_platform_config PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_protobuf-c PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_protocomm PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_pthread PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_raop PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_sdmmc PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_platform_config PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_protobuf-c PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_protocomm PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_pthread PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_raop PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_sdmmc PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_soc PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_spiffs PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_spi_flash PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_squeezelite PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_squeezelite-ota PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_telnet PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_tools PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_ulp PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_unity PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_soc PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_spiffs PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_spi_flash PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_squeezelite PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_squeezelite-ota PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_telnet PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_tools PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_ulp PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_unity PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) # target_compile_definitions(__idf_vfs PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_wear_levelling PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) -# target_compile_definitions(__idf_wifi_provisioning PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_wear_levelling PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) +target_compile_definitions(__idf_wifi_provisioning PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) # target_compile_definitions(__idf_wpa_supplicant PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) # target_compile_definitions(__idf_xtensa PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG) \ No newline at end of file diff --git a/ToggleGitTracking.ps1 b/ToggleGitTracking.ps1 index 05b86141..73c5c9b7 100644 --- a/ToggleGitTracking.ps1 +++ b/ToggleGitTracking.ps1 @@ -1,27 +1,42 @@ param ( [Parameter(Position=0, Mandatory=$false)] - [ValidateSet("t", "u")] + [ValidateSet("t", "u", "d")] [string]$option ) -# Define the directory to apply changes to -$targetDir = "components\wifi-manager\webapp\dist" - # Get the current directory $currentDir = Get-Location -# Get list of files from the file system -$fsFiles = Get-ChildItem -Recurse $targetDir -File | ForEach-Object { +# Define target directories +$targetDir = "components\wifi-manager\webapp" +$distDir = "$targetDir\dist" + +# Get list of files from the 'dist' directory +$fsFiles = Get-ChildItem -Recurse $distDir -File | ForEach-Object { $_.FullName.Substring($currentDir.Path.Length + 1).Replace("\", "/") } +# Define additional files to include +$additionalFiles = @("webpack.c", "webpack.h", "webapp.cmake") + +# Check if additional files exist in $targetDir and format them +$additionalFilesFormatted = @() +Get-ChildItem $targetDir -File | ForEach-Object { + if ($additionalFiles -contains $_.Name) { + $formatted = $_.FullName.Substring($currentDir.Path.Length + 1).Replace("\", "/") + $additionalFilesFormatted += $formatted + Write-Host "Found $formatted" + } +} + # Get list of files from the Git index -$indexFiles = git ls-files -s $targetDir | ForEach-Object { +$indexFiles = git ls-files -s $distDir | ForEach-Object { ($_ -split "\s+")[3] } # Combine and remove duplicates -$allFiles = $fsFiles + $indexFiles | Sort-Object -Unique +$allFiles = $fsFiles + $additionalFilesFormatted + $indexFiles | Sort-Object -Unique +# ... (previous code remains unchanged) # Apply the git command based on the option $allFiles | ForEach-Object { @@ -29,20 +44,48 @@ $allFiles | ForEach-Object { $isInIndex = $indexFiles -contains $relativePath if ($null -eq $option) { - $status = if ($isInIndex) { 'tracked' } else { 'not tracked' } - Write-Host "$relativePath is $status" + $gitStatus = & git status --porcelain -- $relativePath + if ($gitStatus) { + $status = ($gitStatus -split "\s")[0] + Write-Host "$relativePath has Git status: $status" + } else { + Write-Host "$relativePath is not tracked" + } } elseif ($isInIndex) { + if ($option -eq "d") { + $resetResult = & git reset -- $relativePath 2>&1 + if ($resetResult -match 'error:') { + Write-Host "Error resetting ${relativePath}: $resetResult" + + continue + } + $checkoutResult = & git checkout -- $relativePath 2>&1 + if ($checkoutResult -match 'error:') { + Write-Host "Error checking out ${relativePath}: $checkoutResult" + + continue + } + Write-Host "Discarded changes in $relativePath" + } + # ... (rest of the code remains unchanged) + } + # else { + # # if ($option -eq "d") { + # # Remove-Item -Path $relativePath -Force + # # Write-Host "Removed untracked file $relativePath" + # # } else { + # # Write-Host "File $relativePath is not tracked." + # # } + + # } + else { if ($option -eq "t") { + git add $relativePath git update-index --no-skip-worktree $relativePath Write-Host "Started tracking changes in $relativePath" + } else { + Write-Host "File $relativePath is not tracked." } - elseif ($option -eq "u") { - git update-index --skip-worktree $relativePath - Write-Host "Stopped tracking changes in $relativePath" - } - } - else { - Write-Host "File $relativePath is not tracked." } } diff --git a/components/display/CMakeLists.txt b/components/display/CMakeLists.txt index 7c25a75f..31e1c10e 100644 --- a/components/display/CMakeLists.txt +++ b/components/display/CMakeLists.txt @@ -1,9 +1,9 @@ # the JPEG library is in ROM but seems to fail randomly (PSRAM issue?) set(TJPGD tjpgd) -idf_component_register(SRC_DIRS . core core/ifaces fonts - INCLUDE_DIRS . fonts core - REQUIRES platform_config tools esp_common +idf_component_register(SRC_DIRS . core core/ifaces + INCLUDE_DIRS . core + REQUIRES platform_config tools esp_common spiffs PRIV_REQUIRES services freertos driver ${TJPGD} EMBED_FILES note.jpg ) diff --git a/components/display/ILI9341.c b/components/display/ILI9341.c index f643d31f..af0ce1d4 100644 --- a/components/display/ILI9341.c +++ b/components/display/ILI9341.c @@ -319,21 +319,21 @@ static const struct GDS_Device ILI9341_X = { .Mode = GDS_RGB565, .Depth = 16, }; -struct GDS_Device* ILI9341_Detect(char *Driver, struct GDS_Device* Device) { +struct GDS_Device* ILI9341_Detect(sys_Display * Driver, struct GDS_Device* Device) { uint8_t Model; int Depth=16; // 16bit colordepth - if (strcasestr(Driver, "ILI9341")) Model = ILI9341; - else if (strcasestr(Driver, "ILI9341_24")) Model = ILI9341_24; //for future use... + if(Driver->common.driver == sys_DisplayDriverEnum_ILI9341) Model = ILI9341; + else if(Driver->common.driver == sys_DisplayDriverEnum_ILI9341_24) Model = ILI9341_24; else return NULL; - + if (!Device) Device = calloc(1, sizeof(struct GDS_Device)); *Device = ILI9341_X; - sscanf(Driver, "%*[^:]:%u", &Depth); // NVS-Parameter driver=ILI9341[:16|18] + Depth = Driver->common.bitDepth != 0?Driver->common.bitDepth:Depth; struct PrivateSpace* Private = (struct PrivateSpace*) Device->Private; Private->Model = Model; - ESP_LOGI(TAG, "ILI9341_Detect 391 Driver= %s Depth=%d", Driver, Depth); + ESP_LOGI(TAG, "ILI9341_Detect 391 Driver= %s Depth=%d", Model==ILI9341?"ILI9341":"ILI9341_24", Depth); if (Depth == 18) { Device->Mode = GDS_RGB888; diff --git a/components/display/SH1106.c b/components/display/SH1106.c index 136b53d3..78a44f03 100644 --- a/components/display/SH1106.c +++ b/components/display/SH1106.c @@ -152,8 +152,9 @@ static const struct GDS_Device SH1106 = { #endif }; -struct GDS_Device* SH1106_Detect(char *Driver, struct GDS_Device* Device) { - if (!strcasestr(Driver, "SH1106")) return NULL; +struct GDS_Device* SH1106_Detect(sys_Display * Driver, struct GDS_Device* Device) { + // if (!strcasestr(Driver, "SH1106")) return NULL; + if(Driver->common.driver != sys_DisplayDriverEnum_SH1106) return NULL; if (!Device) Device = calloc(1, sizeof(struct GDS_Device)); *Device = SH1106; diff --git a/components/display/SSD1306.c b/components/display/SSD1306.c index 036f787d..44d07cdc 100644 --- a/components/display/SSD1306.c +++ b/components/display/SSD1306.c @@ -162,8 +162,8 @@ static const struct GDS_Device SSD1306 = { #endif }; -struct GDS_Device* SSD1306_Detect(char *Driver, struct GDS_Device* Device) { - if (!strcasestr(Driver, "SSD1306")) return NULL; +struct GDS_Device* SSD1306_Detect(sys_Display * Driver, struct GDS_Device* Device) { + if(Driver->common.driver != sys_DisplayDriverEnum_SSD1306) return NULL; if (!Device) Device = calloc(1, sizeof(struct GDS_Device)); *Device = SSD1306; diff --git a/components/display/SSD1322.c b/components/display/SSD1322.c index 73929d68..0f368a60 100644 --- a/components/display/SSD1322.c +++ b/components/display/SSD1322.c @@ -191,8 +191,8 @@ static const struct GDS_Device SSD1322 = { .Mode = GDS_GRAYSCALE, .Depth = 4, }; -struct GDS_Device* SSD1322_Detect(char *Driver, struct GDS_Device* Device) { - if (!strcasestr(Driver, "SSD1322")) return NULL; +struct GDS_Device* SSD1322_Detect(sys_Display * Driver, struct GDS_Device* Device) { + if(Driver->common.driver != sys_DisplayDriverEnum_SSD1322) return NULL; if (!Device) Device = calloc(1, sizeof(struct GDS_Device)); diff --git a/components/display/SSD132x.c b/components/display/SSD132x.c index 28df964c..5020b629 100644 --- a/components/display/SSD132x.c +++ b/components/display/SSD132x.c @@ -319,13 +319,13 @@ static const struct GDS_Device SSD132x = { .Mode = GDS_GRAYSCALE, .Depth = 4, }; -struct GDS_Device* SSD132x_Detect(char *Driver, struct GDS_Device* Device) { +struct GDS_Device* SSD132x_Detect(sys_Display * Driver, struct GDS_Device* Device) { uint8_t Model; int Depth; - if (strcasestr(Driver, "SSD1326")) Model = SSD1326; - else if (strcasestr(Driver, "SSD1327")) Model = SSD1327; - else return NULL; + if(Driver->common.driver == sys_DisplayDriverEnum_SSD1326) Model = SSD1326; + else if(Driver->common.driver == sys_DisplayDriverEnum_SSD1327) Model = SSD1327; + return NULL; if (!Device) Device = calloc(1, sizeof(struct GDS_Device)); @@ -333,7 +333,7 @@ struct GDS_Device* SSD132x_Detect(char *Driver, struct GDS_Device* Device) { struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private; Private->Model = Model; - sscanf(Driver, "%*[^:]:%u", &Depth); + Depth = Driver->common.bitDepth != 0?Driver->common.bitDepth:1; if (Model == SSD1326 && Depth == 1) { Device->Update = Update1; diff --git a/components/display/SSD1351.c b/components/display/SSD1351.c index c8e4b6ec..d1c7b3a8 100644 --- a/components/display/SSD1351.c +++ b/components/display/SSD1351.c @@ -268,15 +268,15 @@ static const struct GDS_Device SSD1351 = { .Mode = GDS_RGB565, .Depth = 16, }; -struct GDS_Device* SSD1351_Detect(char *Driver, struct GDS_Device* Device) { +struct GDS_Device* SSD1351_Detect(sys_Display * Driver, struct GDS_Device* Device) { int Depth; - if (!strcasestr(Driver, "SSD1351")) return NULL; + if(Driver->common.driver != sys_DisplayDriverEnum_SSD1351) return NULL; if (!Device) Device = calloc(1, sizeof(struct GDS_Device)); *Device = SSD1351; - sscanf(Driver, "%*[^:]:%u", &Depth); + Depth = Driver->common.bitDepth != 0?Driver->common.bitDepth:18; if (Depth == 18) { Device->Mode = GDS_RGB666; diff --git a/components/display/SSD1675.c b/components/display/SSD1675.c index deaa4145..d298f228 100644 --- a/components/display/SSD1675.c +++ b/components/display/SSD1675.c @@ -234,8 +234,8 @@ static const struct GDS_Device SSD1675 = { .Alloc = GDS_ALLOC_NONE, }; -struct GDS_Device* SSD1675_Detect(char *Driver, struct GDS_Device* Device) { - if (!strcasestr(Driver, "SSD1675")) return NULL; +struct GDS_Device* SSD1675_Detect(sys_Display * Driver, struct GDS_Device* Device) { + if(Driver->common.driver != sys_DisplayDriverEnum_SSD1675) return NULL; if (!Device) Device = calloc(1, sizeof(struct GDS_Device)); *Device = SSD1675; @@ -243,7 +243,9 @@ struct GDS_Device* SSD1675_Detect(char *Driver, struct GDS_Device* Device) { char *p; struct PrivateSpace* Private = (struct PrivateSpace*) Device->Private; Private->ReadyPin = -1; - if ((p = strcasestr(Driver, "ready")) && (p = strchr(p, '='))) Private->ReadyPin = atoi(p + 1); + if(Driver->common.has_ready && Driver->common.ready.pin >=0){ + Private->ReadyPin = Driver->common.ready.pin; + } ESP_LOGI(TAG, "SSD1675 driver with ready GPIO %d", Private->ReadyPin); diff --git a/components/display/ST77xx.c b/components/display/ST77xx.c index 25df43f4..f874067c 100644 --- a/components/display/ST77xx.c +++ b/components/display/ST77xx.c @@ -273,24 +273,25 @@ static const struct GDS_Device ST77xx = { .Mode = GDS_RGB565, .Depth = 16, }; -struct GDS_Device* ST77xx_Detect(char *Driver, struct GDS_Device* Device) { +struct GDS_Device* ST77xx_Detect(sys_Display * Driver, struct GDS_Device* Device) { uint8_t Model; int Depth; - - if (strcasestr(Driver, "ST7735")) Model = ST7735; - else if (strcasestr(Driver, "ST7789")) Model = ST7789; + if(Driver->common.driver == sys_DisplayDriverEnum_ST7735) Model = ST7735; + else if(Driver->common.driver == sys_DisplayDriverEnum_ST7789) Model = ST7789; else return NULL; if (!Device) Device = calloc(1, sizeof(struct GDS_Device)); *Device = ST77xx; - sscanf(Driver, "%*[^:]:%u", &Depth); + Depth = Driver->common.bitDepth != 0?Driver->common.bitDepth:18; struct PrivateSpace* Private = (struct PrivateSpace*) Device->Private; Private->Model = Model; - sscanf(Driver, "%*[^:]%*[^x]%*[^=]=%hu", &Private->Offset.Height); - sscanf(Driver, "%*[^:]%*[^y]%*[^=]=%hu", &Private->Offset.Width); + if(Driver->common.has_offsets){ + Private->Offset.Height = Driver->common.offsets.height; + Private->Offset.Width = Driver->common.offsets.width; + } if (Depth == 18) { Device->Mode = GDS_RGB666; diff --git a/components/display/core/gds.c b/components/display/core/gds.c index e2479f49..44581774 100644 --- a/components/display/core/gds.c +++ b/components/display/core/gds.c @@ -15,7 +15,7 @@ #include "driver/gpio.h" #include "driver/ledc.h" #include "esp_log.h" - +#include "Configurator.h" #include "gds.h" #include "gds_private.h" @@ -24,14 +24,14 @@ #else #define LEDC_SPEED_MODE LEDC_HIGH_SPEED_MODE #endif - +extern bool gds_init_fonts(); static struct GDS_Device Display; static struct GDS_BacklightPWM PWMConfig; static char TAG[] = "gds"; -struct GDS_Device* GDS_AutoDetect( char *Driver, GDS_DetectFunc* DetectFunc[], struct GDS_BacklightPWM* PWM ) { - if (!Driver) return NULL; +struct GDS_Device* GDS_AutoDetect( sys_Display * Driver, GDS_DetectFunc* DetectFunc[], struct GDS_BacklightPWM* PWM ) { + if (!Driver->has_common || Driver->common.driver == sys_DisplayDriverEnum_UNSPECIFIED_DRIVER) return NULL; if (PWM) PWMConfig = *PWM; for (int i = 0; DetectFunc[i]; i++) { @@ -203,7 +203,11 @@ bool GDS_Init( struct GDS_Device* Device ) { } bool Res = Device->Init( Device ); + if(Res){ + Res = gds_init_fonts(); + } if (!Res && Device->Framebuffer) free(Device->Framebuffer); + return Res; } diff --git a/components/display/core/gds.h b/components/display/core/gds.h index f0abb5ab..0b96c7a4 100644 --- a/components/display/core/gds.h +++ b/components/display/core/gds.h @@ -3,6 +3,7 @@ #include #include +#include "Configurator.h" /* NOTE for drivers: The build-in DrawPixel(Fast), DrawCBR and ClearWindow have optimized for 1 bit @@ -33,9 +34,9 @@ struct GDS_Layout { bool ColorSwap; }; -typedef struct GDS_Device* GDS_DetectFunc(char *Driver, struct GDS_Device *Device); +typedef struct GDS_Device* GDS_DetectFunc(sys_Display * Driver, struct GDS_Device *Device); -struct GDS_Device* GDS_AutoDetect( char *Driver, GDS_DetectFunc* DetectFunc[], struct GDS_BacklightPWM *PWM ); +struct GDS_Device* GDS_AutoDetect( sys_Display * Driver, GDS_DetectFunc* DetectFunc[], struct GDS_BacklightPWM *PWM ); void GDS_SetContrast( struct GDS_Device* Device, uint8_t Contrast ); void GDS_DisplayOn( struct GDS_Device* Device ); diff --git a/components/display/core/gds_font.c b/components/display/core/gds_font.c index 65c1a08e..0cb9ca49 100644 --- a/components/display/core/gds_font.c +++ b/components/display/core/gds_font.c @@ -14,7 +14,67 @@ #include "gds_font.h" #include "gds_draw.h" #include "gds_err.h" +#include "esp_spiffs.h" +#include "esp_log.h" +#include "esp_heap_caps.h" +#include "tools.h" +static const char * TAG = "gds_font"; +struct GDS_FontDef * Font_droid_sans_fallback_11x13 = NULL; +struct GDS_FontDef * Font_line_1 = NULL; +struct GDS_FontDef * Font_line_2 = NULL; +// struct GDS_FontDef * Font_droid_sans_fallback_15x17 = NULL; +// struct GDS_FontDef * Font_droid_sans_fallback_24x28 = NULL; +// struct GDS_FontDef * Font_droid_sans_mono_7x13 = NULL; +// struct GDS_FontDef * Font_droid_sans_mono_13x24 = NULL; +// struct GDS_FontDef * Font_droid_sans_mono_16x31 = NULL; +// struct GDS_FontDef * Font_liberation_mono_9x15 = NULL; +// struct GDS_FontDef * Font_liberation_mono_13x21 = NULL; +// struct GDS_FontDef * Font_liberation_mono_17x30 = NULL; +// struct GDS_FontDef * Font_Tarable7Seg_16x32 = NULL; +// struct GDS_FontDef * Font_Tarable7Seg_32x64 = NULL; + + +static bool LoadFont(struct GDS_FontDef ** fontPtr, const char * fileName){ + if(!fontPtr){ + ESP_LOGE(TAG, "Invalid pointer for LoadFont"); + return false; + } + + // Allocate DMA-capable memory for the font + struct GDS_FontDef* loadedFont = load_file_dma(NULL,"fonts",fileName); + + // Check if allocation succeeded + if (loadedFont == NULL) { + ESP_LOGE(TAG, "Failed to load font"); + return false; + } + // Update the pointer + *fontPtr = loadedFont; + + ESP_LOGI(TAG, "Successfully loaded font: %s", fileName); + return true; +} +bool gds_init_fonts() { + bool success = true; + + // Load the Font_droid_sans_fallback_11x13 + if (!LoadFont(&Font_droid_sans_fallback_11x13, "droid_sans_fb_11x13.bin")) { + success = false; + } + + // Load the Font_line_1 + if (!LoadFont(&Font_line_1, "line_1.bin")) { + success = false; + } + + // Load the Font_line_2 + if (!LoadFont(&Font_line_2, "line_2.bin")) { + success = false; + } + + return success; +} static int RoundUpFontHeight( const struct GDS_FontDef* Font ) { int Height = Font->Height; @@ -26,7 +86,7 @@ static int RoundUpFontHeight( const struct GDS_FontDef* Font ) { } static const uint8_t* GetCharPtr( const struct GDS_FontDef* Font, char Character ) { - return &Font->FontData[ ( Character - Font->StartChar ) * ( ( Font->Width * ( RoundUpFontHeight( Font ) / 8 ) ) + 1 ) ]; + return &Font->FontData[( Character - Font->StartChar ) * ( ( Font->Width * ( RoundUpFontHeight( Font ) / 8 ) ) + 1 )]; } void GDS_FontDrawChar( struct GDS_Device* Device, char Character, int x, int y, int Color ) { @@ -130,9 +190,7 @@ int GDS_FontGetCharWidth( struct GDS_Device* Display, char Character ) { if ( Character >= Display->Font->StartChar && Character <= Display->Font->EndChar ) { CharPtr = GetCharPtr( Display->Font, Character ); - Width = ( Display->Font->Monospace == true ) ? Display->Font->Width : *CharPtr; - if ( Display->FontForceMonospace == true ) { Width = Display->Font->Width; } @@ -168,7 +226,6 @@ int GDS_FontMeasureString( struct GDS_Device* Display, const char* Text ) { Width+= GDS_FontGetCharWidth( Display, *Text ); } } - return Width; } diff --git a/components/display/core/gds_font.h b/components/display/core/gds_font.h index 566f8546..712f5039 100644 --- a/components/display/core/gds_font.h +++ b/components/display/core/gds_font.h @@ -22,17 +22,21 @@ struct GDS_Device; * 'c': And so on... */ +#pragma pack(push, 1) // Disable padding struct GDS_FontDef { - const uint8_t* FontData; + const void* dummy; // 4 bytes (assuming 32-bit pointers) - int Width; - int Height; + int Width; // 4 bytes + int Height; // 4 bytes + int StartChar; // 4 bytes + int EndChar; // 4 bytes + bool Monospace; // 1 byte - int StartChar; - int EndChar; - - bool Monospace; + uint8_t padding[3]; // 3 bytes padding to align to 24 bytes + const uint8_t FontData[]; // 4 bytes (assuming 32-bit pointers) }; +#pragma pack(pop) // Re-enable padding + typedef enum { TextAnchor_East = 0, @@ -45,7 +49,7 @@ typedef enum { TextAnchor_SouthWest, TextAnchor_Center } TextAnchor; - +bool gds_init_fonts(); const struct GDS_FontDef* GDS_SetFont( struct GDS_Device* Display, const struct GDS_FontDef* Font ); void GDS_FontForceProportional( struct GDS_Device* Display, bool Force ); @@ -67,23 +71,23 @@ void GDS_FontDrawString( struct GDS_Device* Display, int x, int y, const char* T void GDS_FontDrawAnchoredString( struct GDS_Device* Display, TextAnchor Anchor, const char* Text, int Color ); void GDS_FontGetAnchoredStringCoords( struct GDS_Device* Display, int* OutX, int* OutY, TextAnchor Anchor, const char* Text ); -extern const struct GDS_FontDef Font_droid_sans_fallback_11x13; -extern const struct GDS_FontDef Font_droid_sans_fallback_15x17; -extern const struct GDS_FontDef Font_droid_sans_fallback_24x28; +struct GDS_FontDef * Font_droid_sans_fallback_11x13; +// const struct GDS_FontDef * Font_droid_sans_fallback_15x17; +// const struct GDS_FontDef * Font_droid_sans_fallback_24x28; -extern const struct GDS_FontDef Font_droid_sans_mono_7x13; -extern const struct GDS_FontDef Font_droid_sans_mono_13x24; -extern const struct GDS_FontDef Font_droid_sans_mono_16x31; +// const struct GDS_FontDef * Font_droid_sans_mono_7x13; +// const struct GDS_FontDef * Font_droid_sans_mono_13x24; +// const struct GDS_FontDef * Font_droid_sans_mono_16x31; -extern const struct GDS_FontDef Font_liberation_mono_9x15; -extern const struct GDS_FontDef Font_liberation_mono_13x21; -extern const struct GDS_FontDef Font_liberation_mono_17x30; +// const struct GDS_FontDef * Font_liberation_mono_9x15; +// const struct GDS_FontDef * Font_liberation_mono_13x21; +// const struct GDS_FontDef * Font_liberation_mono_17x30; -extern const struct GDS_FontDef Font_Tarable7Seg_16x32; -extern const struct GDS_FontDef Font_Tarable7Seg_32x64; +// const struct GDS_FontDef * Font_Tarable7Seg_16x32; +// const struct GDS_FontDef * Font_Tarable7Seg_32x64; -extern const struct GDS_FontDef Font_line_1; -extern const struct GDS_FontDef Font_line_2; +struct GDS_FontDef * Font_line_1; +struct GDS_FontDef * Font_line_2; #ifdef __cplusplus } diff --git a/components/display/core/gds_text.c b/components/display/core/gds_text.c index b2ef8903..aa09d162 100644 --- a/components/display/core/gds_text.c +++ b/components/display/core/gds_text.c @@ -29,14 +29,14 @@ static const struct GDS_FontDef *GuessFont( struct GDS_Device *Device, int FontT case GDS_FONT_DEFAULT: return Device->Font; case GDS_FONT_LINE_1: - return &Font_line_1; + return Font_line_1; case GDS_FONT_LINE_2: - return &Font_line_2; + return Font_line_2; case GDS_FONT_MEDIUM: //return &Font_droid_sans_fallback_15x17; case GDS_FONT_SMALL: default: - return &Font_droid_sans_fallback_11x13; + return Font_droid_sans_fallback_11x13; #ifdef USE_LARGE_FONTS case GDS_FONT_LARGE: return &Font_droid_sans_fallback_24x28; @@ -48,7 +48,7 @@ static const struct GDS_FontDef *GuessFont( struct GDS_Device *Device, int FontT case GDS_FONT_SEGMENT: ESP_LOGW(TAG, "large fonts disabled"); //return &Font_droid_sans_fallback_15x17; - return &Font_droid_sans_fallback_11x13; + return Font_droid_sans_fallback_11x13; #endif } } diff --git a/components/display/display.c b/components/display/display.c index e5d0747d..8d5c1e10 100644 --- a/components/display/display.c +++ b/components/display/display.c @@ -12,8 +12,8 @@ #include #include "esp_log.h" #include "globdefs.h" -#include "platform_config.h" #include "tools.h" +#include "accessors.h" #include "display.h" #include "services.h" #include "gds.h" @@ -22,7 +22,7 @@ #include "gds_text.h" #include "gds_font.h" #include "gds_image.h" - +#include "Configurator.h" static const char *TAG = "display"; #define min(a,b) (((a) < (b)) ? (a) : (b)) @@ -44,7 +44,7 @@ static EXT_RAM_ATTR struct { char header[HEADER_SIZE + 1]; char string[SCROLLABLE_SIZE + 1]; int offset, boundary; - char *metadata_config; + sys_Metadata *metadata_config; bool timer, refresh; uint32_t elapsed; struct { @@ -62,18 +62,6 @@ static EXT_RAM_ATTR struct { TickType_t tick; } displayer; -static const char *known_drivers[] = {"SH1106", - "SSD1306", - "SSD1322", - "SSD1326", - "SSD1327", - "SSD1675", - "SSD1351", - "ST7735", - "ST7789", - "ILI9341", - NULL - }; static void displayer_task(void *args); static void display_sleep(void); @@ -87,46 +75,61 @@ GDS_DetectFunc *drivers[] = { SH1106_Detect, SSD1306_Detect, SSD132x_Detect, SSD */ void display_init(char *welcome) { bool init = false; - char *config = config_alloc_get_str("display_config", CONFIG_DISPLAY_CONFIG, "N/A"); - - int width = -1, height = -1, backlight_pin = -1; - char *drivername = strstr(config, "driver"); + int width = -1, height = -1, backlight_pin = -1, RST_pin = -1; + sys_Display * sys_display; + sys_DispCommon * common; - PARSE_PARAM(config, "width", '=', width); - PARSE_PARAM(config, "height", '=', height); - PARSE_PARAM(config, "back", '=', backlight_pin); - - // query drivers to see if we have a match - ESP_LOGI(TAG, "Trying to configure display with %s", config); - if (backlight_pin >= 0) { + if(!SYS_DISPLAY(sys_display) || !SYS_DISPLAY_COMMON(common)){ + return; + } + // // so far so good + if( common->width == 0 || common->height == 0){ + ESP_LOGE(TAG,"Misconfigured display missing data"); + return; + } + + ESP_LOGI(TAG, "Trying to configure display type %s, driver: %s", + sys_DeviceTypeEnum_name(sys_display->type), + sys_DisplayDriverEnum_name(common->driver)); + if (common->has_back && common->back.pin >= 0) { struct GDS_BacklightPWM PWMConfig = { .Channel = pwm_system.base_channel++, .Timer = pwm_system.timer, .Max = pwm_system.max, .Init = false }; - display = GDS_AutoDetect(drivername, drivers, &PWMConfig); + display = GDS_AutoDetect(sys_display, drivers, &PWMConfig); } else { - display = GDS_AutoDetect(drivername, drivers, NULL); + display = GDS_AutoDetect(sys_display, drivers, NULL); } - // so far so good - if (display && width > 0 && height > 0) { - int RST_pin = -1; - PARSE_PARAM(config, "reset", '=', RST_pin); - + if (display) { + if(common->has_reset){ + RST_pin = common->reset.pin; + } + if(common->has_back){ + backlight_pin = common->back.pin; + } + width = common->width; + height = common->height; + // Detect driver interface - if (strcasestr(config, "I2C") && i2c_system_port != -1) { + if (sys_display->which_dispType == sys_Display_i2c_tag && i2c_system_port != -1){ int address = 0x3C; - - PARSE_PARAM(config, "address", '=', address); - + + address = sys_display->dispType.i2c.address; init = true; GDS_I2CInit( i2c_system_port, -1, -1, i2c_system_speed ) ; GDS_I2CAttachDevice( display, width, height, address, RST_pin, backlight_pin ); ESP_LOGI(TAG, "Display is I2C on port %u", address); - } else if (strcasestr(config, "SPI") && spi_system_host != -1) { + } else if (sys_display->which_dispType == sys_Display_spi_tag && spi_system_host != -1) { int CS_pin = -1, speed = 0, mode = 0; - - PARSE_PARAM(config, "cs", '=', CS_pin); - PARSE_PARAM(config, "speed", '=', speed); - PARSE_PARAM(config, "mode", '=', mode); + if(sys_display->dispType.spi.has_cs){ + CS_pin = sys_display->dispType.spi.cs.pin; + } + speed = sys_display->dispType.spi.speed; + + //todo: what is mode? + + // PARSE_PARAM(config, "mode", '=', mode); + + // todo: need to handle display offsets init = true; GDS_SPIInit( spi_system_host, spi_system_dc_gpio ); @@ -137,24 +140,22 @@ void display_init(char *welcome) { display = NULL; ESP_LOGI(TAG, "Unsupported display interface or serial link not configured"); } - } else { - display = NULL; - ESP_LOGW(TAG, "No display driver"); - } + } + if (init) { static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4))); static EXT_RAM_ATTR StackType_t xStack[DISPLAYER_STACK_SIZE] __attribute__ ((aligned (4))); struct GDS_Layout Layout = { - .HFlip = strcasestr(config, "HFlip"), - .VFlip = strcasestr(config, "VFlip"), - .Rotate = strcasestr(config, "rotate"), - .Invert = strcasestr(config, "invert"), - .ColorSwap = strcasestr(config, "cswap"), + .HFlip = platform->dev.display.common.HFlip, + .VFlip = platform->dev.display.common.VFlip, + .Rotate = platform->dev.display.common.rotate, + .Invert = platform->dev.display.common.invert, + .ColorSwap = platform->dev.display.common.colow_swap }; GDS_SetLayout(display, &Layout); - GDS_SetFont(display, &Font_line_2); + GDS_SetFont(display, Font_line_2); GDS_TextPos(display, GDS_FONT_DEFAULT, GDS_TEXT_CENTERED, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, welcome); // start the task that will handle scrolling & counting @@ -168,21 +169,25 @@ void display_init(char *welcome) { GDS_TextSetFontAuto(display, 1, GDS_FONT_LINE_1, -3); GDS_TextSetFontAuto(display, 2, GDS_FONT_LINE_2, -3); - displayer.metadata_config = config_alloc_get(NVS_TYPE_STR, "metadata_config"); + if(platform->has_services && platform->services.has_metadata){ + displayer.metadata_config = &platform->services.metadata; + + // leave room for artwork is display is horizontal-style + if (displayer.metadata_config->has_artwork && displayer.metadata_config->artwork.enabled) { + // todo : check for resize flag + displayer.artwork.enable = true; + displayer.artwork.fit = true; + if (height <= 64 && width > height * 2) + displayer.artwork.offset = width - height - ARTWORK_BORDER; + } + } - // leave room for artwork is display is horizontal-style - if (strcasestr(displayer.metadata_config, "artwork")) { - displayer.artwork.enable = true; - displayer.artwork.fit = true; - if (height <= 64 && width > height * 2) displayer.artwork.offset = width - height - ARTWORK_BORDER; - PARSE_PARAM(displayer.metadata_config, "artwork", ':', displayer.artwork.fit); - } // and finally register ourselves to power off upon deep sleep services_sleep_setsuspend(display_sleep); } - free(config); + } /**************************************************************************************** @@ -328,13 +333,13 @@ void displayer_metadata(char *artist, char *album, char *title) { xSemaphoreTake(displayer.mutex, portMAX_DELAY); // format metadata parameters and write them directly - if ((p = strcasestr(displayer.metadata_config, "format")) != NULL) { + if (strlen(displayer.metadata_config->format)>0) { char token[16], *q; int space = len; bool skip = false; displayer.string[0] = '\0'; - p = strchr(displayer.metadata_config, '='); + p = strchr(displayer.metadata_config->format, '='); while (p++) { // find token and copy what's after when reaching last one @@ -369,11 +374,9 @@ void displayer_metadata(char *artist, char *album, char *title) { } else { strncpy(string, title ? title : "", SCROLLABLE_SIZE); } - - // get optional scroll speed & pause - PARSE_PARAM(displayer.metadata_config, "speed", '=', displayer.speed); - PARSE_PARAM(displayer.metadata_config, "pause", '=', displayer.pause); - + if(displayer.metadata_config->speed <=0) displayer.metadata_config->speed= displayer.speed; + if(displayer.metadata_config->pause <=0) displayer.metadata_config->pause= displayer.pause; + displayer.metadata_config->speed = displayer.speed; displayer.offset = 0; utf8_decode(displayer.string); ESP_LOGI(TAG, "playing %s", displayer.string); @@ -494,46 +497,3 @@ void displayer_control(enum displayer_cmd_e cmd, ...) { xSemaphoreGive(displayer.mutex); va_end(args); } - -/**************************************************************************************** - * - */ -bool display_is_valid_driver(const char * driver){ - return display_conf_get_driver_name(driver)!=NULL; -} - -/**************************************************************************************** - * - */ -const char *display_conf_get_driver_name(const char * driver){ - for(uint8_t i=0;known_drivers[i]!=NULL && strlen(known_drivers[i])>0;i++ ){ - if(strcasestr(driver,known_drivers[i])){ - return known_drivers[i]; - } - } - return NULL; -} - -/**************************************************************************************** - * - */ -char * display_get_supported_drivers(void){ - int total_size = 1; - char * supported_drivers=NULL; - const char * separator = "|"; - int separator_len = strlen(separator); - - for(uint8_t i=0;known_drivers[i]!=NULL && strlen(known_drivers[i])>0;i++ ){ - total_size += strlen(known_drivers[i])+separator_len; - } - total_size+=2; - supported_drivers = malloc(total_size); - memset(supported_drivers,0x00,total_size); - strcat(supported_drivers,"<"); - for(uint8_t i=0;known_drivers[i]!=NULL && strlen(known_drivers[i])>0;i++ ){ - supported_drivers = strcat(supported_drivers,known_drivers[i]); - supported_drivers = strcat(supported_drivers,separator); - } - strcat(supported_drivers,">"); - return supported_drivers; -} diff --git a/components/display/display.h b/components/display/display.h index 278bc077..c2cbf890 100644 --- a/components/display/display.h +++ b/components/display/display.h @@ -32,8 +32,6 @@ enum displayer_time_e { DISPLAYER_ELAPSED, DISPLAYER_REMAINING }; enum display_bus_cmd_e { DISPLAY_BUS_TAKE, DISPLAY_BUS_GIVE }; bool (*display_bus)(void *from, enum display_bus_cmd_e cmd); -const char *display_conf_get_driver_name(const char * driver); -bool display_is_valid_driver(const char * driver); void displayer_scroll(char *string, int speed, int pause); void displayer_control(enum displayer_cmd_e cmd, ...); @@ -41,4 +39,3 @@ void displayer_metadata(char *artist, char *album, char *title); void displayer_artwork(uint8_t *data); void displayer_timer(enum displayer_time_e mode, int elapsed, int duration); bool displayer_can_artwork(void); -char * display_get_supported_drivers(void); diff --git a/components/display/fonts/LICENSE-apache b/components/display/fonts/LICENSE-apache deleted file mode 100644 index f4f87bd4..00000000 --- a/components/display/fonts/LICENSE-apache +++ /dev/null @@ -1,203 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - \ No newline at end of file diff --git a/components/display/fonts/LICENSE-liberation-mono b/components/display/fonts/LICENSE-liberation-mono deleted file mode 100644 index aba73e8a..00000000 --- a/components/display/fonts/LICENSE-liberation-mono +++ /dev/null @@ -1,102 +0,0 @@ -Digitized data copyright (c) 2010 Google Corporation - with Reserved Font Arimo, Tinos and Cousine. -Copyright (c) 2012 Red Hat, Inc. - with Reserved Font Name Liberation. - -This Font Software is licensed under the SIL Open Font License, -Version 1.1. - -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 - -PREAMBLE The goals of the Open Font License (OFL) are to stimulate -worldwide development of collaborative font projects, to support the font -creation efforts of academic and linguistic communities, and to provide -a free and open framework in which fonts may be shared and improved in -partnership with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. -The fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply to -any document created using the fonts or their derivatives. - - - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. -This may include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components -as distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting ? in part or in whole ? -any of the components of the Original Version, by changing formats or -by porting the Font Software to a new environment. - -"Author" refers to any designer, engineer, programmer, technical writer -or other person who contributed to the Font Software. - - -PERMISSION & CONDITIONS - -Permission is hereby granted, free of charge, to any person obtaining a -copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components,in - Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, - redistributed and/or sold with any software, provided that each copy - contains the above copyright notice and this license. These can be - included either as stand-alone text files, human-readable headers or - in the appropriate machine-readable metadata fields within text or - binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font - Name(s) unless explicit written permission is granted by the - corresponding Copyright Holder. This restriction only applies to the - primary font name as presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font - Software shall not be used to promote, endorse or advertise any - Modified Version, except to acknowledge the contribution(s) of the - Copyright Holder(s) and the Author(s) or with their explicit written - permission. - -5) The Font Software, modified or unmodified, in part or in whole, must - be distributed entirely under this license, and must not be distributed - under any other license. The requirement for fonts to remain under - this license does not apply to any document created using the Font - Software. - - - -TERMINATION -This license becomes null and void if any of the above conditions are not met. - - - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER -DEALINGS IN THE FONT SOFTWARE. - diff --git a/components/display/fonts/font_droid_sans_fallback_11x13.c b/components/display/fonts/font_droid_sans_fallback_11x13.c deleted file mode 100644 index e398c434..00000000 --- a/components/display/fonts/font_droid_sans_fallback_11x13.c +++ /dev/null @@ -1,247 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Droid_Sans_Fallback11x13 -//GLCD FontSize : 11 x 13 - -static const uint8_t Droid_Sans_Fallback11x13[ ] = { - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x02, 0x00, 0x00, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x05, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x07, 0x00, 0x00, 0x10, 0x01, 0xFC, 0x07, 0x10, 0x01, 0x10, 0x01, 0xFC, 0x07, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # - 0x06, 0x00, 0x00, 0x30, 0x02, 0x48, 0x04, 0xFC, 0x0F, 0x88, 0x04, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ - 0x08, 0x00, 0x00, 0x08, 0x02, 0x14, 0x01, 0x94, 0x00, 0x48, 0x02, 0x20, 0x05, 0x10, 0x05, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char % - 0x06, 0x00, 0x00, 0x98, 0x03, 0x64, 0x04, 0x98, 0x04, 0x00, 0x03, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & - 0x02, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x03, 0x00, 0x00, 0xF8, 0x0F, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x03, 0x00, 0x00, 0x04, 0x10, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x04, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x06, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0xE0, 0x03, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + - 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x03, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x05, 0x00, 0x00, 0x00, 0x06, 0x80, 0x01, 0x60, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / - 0x06, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 - 0x04, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 - 0x06, 0x00, 0x00, 0x08, 0x06, 0x04, 0x05, 0x84, 0x04, 0x44, 0x04, 0x38, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 - 0x06, 0x00, 0x00, 0x08, 0x02, 0x04, 0x04, 0x44, 0x04, 0x44, 0x04, 0xB8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 - 0x06, 0x00, 0x00, 0x80, 0x01, 0x60, 0x01, 0x18, 0x01, 0xFC, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 - 0x06, 0x00, 0x00, 0x7C, 0x02, 0x24, 0x04, 0x24, 0x04, 0x24, 0x04, 0xC4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 - 0x06, 0x00, 0x00, 0xF8, 0x03, 0x44, 0x04, 0x44, 0x04, 0x44, 0x04, 0x88, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 - 0x06, 0x00, 0x00, 0x04, 0x00, 0x04, 0x07, 0xC4, 0x00, 0x34, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 - 0x06, 0x00, 0x00, 0xB8, 0x03, 0x44, 0x04, 0x44, 0x04, 0x44, 0x04, 0xB8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 - 0x06, 0x00, 0x00, 0x38, 0x02, 0x44, 0x04, 0x44, 0x04, 0x44, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 - 0x02, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x03, 0x00, 0x00, 0x00, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < - 0x06, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = - 0x05, 0x00, 0x00, 0x10, 0x04, 0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > - 0x06, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x84, 0x05, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x0B, 0x00, 0x00, 0xE0, 0x01, 0x18, 0x06, 0x08, 0x04, 0xC4, 0x08, 0x24, 0x09, 0x24, 0x09, 0xE4, 0x08, 0x08, 0x09, 0x18, 0x01, 0xE0, 0x01, // Code for char @ - 0x07, 0x00, 0x06, 0xC0, 0x01, 0x30, 0x01, 0x0C, 0x01, 0x30, 0x01, 0xC0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A - 0x06, 0x00, 0x00, 0xFC, 0x07, 0x44, 0x04, 0x44, 0x04, 0x44, 0x04, 0xB8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C - 0x07, 0x00, 0x00, 0xFC, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x02, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D - 0x06, 0x00, 0x00, 0xFC, 0x07, 0x44, 0x04, 0x44, 0x04, 0x44, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E - 0x06, 0x00, 0x00, 0xFC, 0x07, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x04, 0x04, 0x44, 0x04, 0x44, 0x02, 0xC8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G - 0x07, 0x00, 0x00, 0xFC, 0x07, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H - 0x02, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I - 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x07, 0x00, 0x00, 0xFC, 0x07, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x04, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K - 0x06, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L - 0x08, 0x00, 0x00, 0xFC, 0x07, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x30, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char M - 0x07, 0x00, 0x00, 0xFC, 0x07, 0x18, 0x00, 0x60, 0x00, 0x80, 0x00, 0x00, 0x03, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O - 0x07, 0x00, 0x00, 0xFC, 0x07, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0xF8, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Q - 0x07, 0x00, 0x00, 0xFC, 0x07, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0xB8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R - 0x06, 0x00, 0x00, 0x38, 0x02, 0x44, 0x04, 0x44, 0x04, 0x44, 0x04, 0x88, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S - 0x06, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0xFC, 0x07, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T - 0x07, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U - 0x07, 0x0C, 0x00, 0x70, 0x00, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x70, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V - 0x0B, 0x0C, 0x00, 0x70, 0x00, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x70, 0x00, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x70, 0x00, 0x0C, 0x00, // Code for char W - 0x07, 0x0C, 0x06, 0x10, 0x01, 0xA0, 0x00, 0x40, 0x00, 0xA0, 0x00, 0x10, 0x01, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X - 0x07, 0x0C, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC0, 0x07, 0x20, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y - 0x07, 0x04, 0x06, 0x04, 0x05, 0x84, 0x04, 0x44, 0x04, 0x24, 0x04, 0x14, 0x04, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z - 0x03, 0x00, 0x00, 0xFC, 0x1F, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x05, 0x00, 0x00, 0x1C, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash - 0x03, 0x00, 0x00, 0x04, 0x10, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x06, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ - 0x06, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ - 0x03, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x06, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a - 0x06, 0x00, 0x00, 0xFC, 0x07, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d - 0x06, 0x00, 0x00, 0xC0, 0x03, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xC0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e - 0x03, 0x00, 0x00, 0xF8, 0x07, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f - 0x06, 0x00, 0x00, 0xC0, 0x13, 0x20, 0x14, 0x20, 0x14, 0x20, 0x14, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g - 0x06, 0x00, 0x00, 0xFC, 0x07, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h - 0x02, 0x00, 0x00, 0xE4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i - 0x02, 0x00, 0x00, 0xE4, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x06, 0x00, 0x00, 0xFC, 0x07, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k - 0x02, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l - 0x08, 0x00, 0x00, 0xE0, 0x07, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x07, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m - 0x06, 0x00, 0x00, 0xE0, 0x07, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o - 0x06, 0x00, 0x00, 0xE0, 0x1F, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q - 0x03, 0x00, 0x00, 0xE0, 0x07, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r - 0x05, 0x00, 0x00, 0x40, 0x02, 0xA0, 0x04, 0x20, 0x05, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s - 0x03, 0x00, 0x00, 0xF8, 0x03, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x06, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u - 0x06, 0x00, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v - 0x08, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x06, 0x80, 0x01, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w - 0x05, 0x00, 0x00, 0x60, 0x06, 0x80, 0x01, 0x80, 0x01, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x - 0x05, 0x00, 0x10, 0xE0, 0x11, 0x00, 0x0E, 0x00, 0x02, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y - 0x05, 0x00, 0x00, 0x20, 0x06, 0x20, 0x05, 0xA0, 0x04, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z - 0x04, 0x00, 0x00, 0x40, 0x00, 0xBC, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { - 0x02, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x04, 0x00, 0x00, 0x02, 0x08, 0xBC, 0x07, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x07, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ - 0x03, 0xF8, 0x07, 0x08, 0x04, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char †- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   - 0x02, 0x00, 0x00, 0xD0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x0C, 0x20, 0x04, 0x30, 0x04, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¢ - 0x05, 0x00, 0x00, 0x58, 0x07, 0xE4, 0x04, 0x44, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char £ - 0x06, 0x00, 0x00, 0x74, 0x01, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x74, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¤ - 0x06, 0x00, 0x00, 0x5C, 0x01, 0x60, 0x01, 0xC0, 0x07, 0x60, 0x01, 0x5C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¥ - 0x02, 0x00, 0x00, 0x7C, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ - 0x06, 0x00, 0x00, 0x68, 0x04, 0x94, 0x08, 0x24, 0x09, 0x44, 0x0A, 0x88, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char § - 0x03, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ - 0x09, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, 0x24, 0x01, 0x54, 0x01, 0x54, 0x01, 0x04, 0x01, 0x88, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char © - 0x04, 0x00, 0x00, 0xB4, 0x00, 0xAC, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª - 0x06, 0x00, 0x00, 0x00, 0x01, 0x80, 0x02, 0x40, 0x05, 0x80, 0x02, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char « - 0x06, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¬ - 0x03, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ - 0x08, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, 0x74, 0x01, 0x34, 0x01, 0x54, 0x01, 0x88, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ® - 0x06, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¯ - 0x04, 0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° - 0x06, 0x00, 0x00, 0x40, 0x04, 0x40, 0x04, 0xF0, 0x05, 0x40, 0x04, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ± - 0x03, 0x64, 0x00, 0x54, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² - 0x03, 0x44, 0x00, 0x54, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ - 0x03, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ - 0x06, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x04, 0x00, 0x04, 0xE0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char µ - 0x06, 0x00, 0x00, 0x38, 0x00, 0x7C, 0x00, 0xFC, 0x0F, 0x04, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¶ - 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · - 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ - 0x03, 0x00, 0x00, 0x08, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ - 0x04, 0x00, 0x00, 0xBC, 0x00, 0xA4, 0x00, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º - 0x06, 0x00, 0x00, 0x40, 0x04, 0x80, 0x02, 0x40, 0x05, 0x80, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char » - 0x08, 0x00, 0x00, 0x08, 0x02, 0x7C, 0x01, 0x80, 0x00, 0x40, 0x00, 0x20, 0x03, 0x90, 0x02, 0xC8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¼ - 0x08, 0x00, 0x00, 0x08, 0x02, 0x7C, 0x01, 0x80, 0x00, 0x40, 0x00, 0x60, 0x06, 0x50, 0x05, 0x88, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ½ - 0x08, 0x00, 0x00, 0x44, 0x02, 0x54, 0x01, 0xA8, 0x00, 0x40, 0x00, 0x20, 0x03, 0x90, 0x02, 0xC8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¾ - 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x11, 0xD0, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¿ - 0x07, 0x00, 0x06, 0xC0, 0x01, 0x31, 0x01, 0x0E, 0x01, 0x30, 0x01, 0xC0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char À - 0x07, 0x00, 0x06, 0xC0, 0x01, 0x30, 0x01, 0x0E, 0x01, 0x31, 0x01, 0xC0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x07, 0x00, 0x06, 0xC0, 0x01, 0x34, 0x01, 0x0A, 0x01, 0x34, 0x01, 0xC0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x07, 0x00, 0x06, 0xC2, 0x01, 0x31, 0x01, 0x0F, 0x01, 0x32, 0x01, 0xC1, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x07, 0x00, 0x06, 0xC2, 0x01, 0x30, 0x01, 0x0C, 0x01, 0x30, 0x01, 0xC2, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ä - 0x07, 0x00, 0x06, 0xC0, 0x01, 0x32, 0x01, 0x0D, 0x01, 0x32, 0x01, 0xC0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Å - 0x09, 0x00, 0x06, 0xC0, 0x01, 0xB0, 0x00, 0x8C, 0x00, 0xFC, 0x07, 0x44, 0x04, 0x44, 0x04, 0x44, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, // Code for char Æ - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x04, 0x14, 0x04, 0x1C, 0x04, 0x04, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ç - 0x06, 0x00, 0x00, 0xFC, 0x07, 0x45, 0x04, 0x46, 0x04, 0x44, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char È - 0x06, 0x00, 0x00, 0xFC, 0x07, 0x44, 0x04, 0x46, 0x04, 0x45, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char É - 0x06, 0x00, 0x00, 0xFC, 0x07, 0x46, 0x04, 0x45, 0x04, 0x46, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ê - 0x06, 0x00, 0x00, 0xFE, 0x07, 0x44, 0x04, 0x44, 0x04, 0x44, 0x04, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ë - 0x02, 0x02, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ì - 0x03, 0x00, 0x00, 0xFC, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x03, 0x04, 0x00, 0xFA, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Î - 0x03, 0x02, 0x00, 0xFC, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x07, 0x40, 0x00, 0xFC, 0x07, 0x44, 0x04, 0x44, 0x04, 0x04, 0x04, 0x08, 0x02, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x07, 0x00, 0x00, 0xFE, 0x07, 0x19, 0x00, 0x61, 0x00, 0x82, 0x00, 0x02, 0x03, 0xFD, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ñ - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x04, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ò - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x06, 0x04, 0x05, 0x04, 0x04, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ó - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x06, 0x04, 0x05, 0x04, 0x05, 0x04, 0x06, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ô - 0x07, 0x00, 0x00, 0xFA, 0x03, 0x05, 0x04, 0x05, 0x04, 0x06, 0x04, 0x06, 0x04, 0xF9, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Õ - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ö - 0x06, 0x00, 0x00, 0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char × - 0x07, 0x00, 0x00, 0xF8, 0x07, 0x04, 0x07, 0xC4, 0x04, 0x34, 0x04, 0x0C, 0x04, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ø - 0x07, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x00, 0x04, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ù - 0x07, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x04, 0x02, 0x04, 0x01, 0x04, 0x00, 0x04, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ú - 0x07, 0x00, 0x00, 0xFC, 0x03, 0x02, 0x04, 0x01, 0x04, 0x01, 0x04, 0x02, 0x04, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Û - 0x07, 0x00, 0x00, 0xFC, 0x03, 0x02, 0x04, 0x00, 0x04, 0x00, 0x04, 0x02, 0x04, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ü - 0x07, 0x0C, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC2, 0x07, 0x21, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x07, 0x00, 0x00, 0xFC, 0x07, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Þ - 0x06, 0x00, 0x00, 0xF8, 0x07, 0x04, 0x00, 0x44, 0x04, 0x78, 0x04, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ß - 0x06, 0x00, 0x00, 0x00, 0x03, 0xA4, 0x04, 0xA8, 0x04, 0xA0, 0x04, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x06, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x04, 0xA8, 0x04, 0xA4, 0x04, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char á - 0x06, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x04, 0xA4, 0x04, 0xA8, 0x04, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char â - 0x06, 0x00, 0x00, 0x08, 0x03, 0xA4, 0x04, 0xAC, 0x04, 0xA8, 0x04, 0xC4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ã - 0x06, 0x00, 0x00, 0x00, 0x03, 0xA4, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xC4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ä - 0x06, 0x00, 0x00, 0x00, 0x03, 0xA4, 0x04, 0xAA, 0x04, 0xA4, 0x04, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char å - 0x0A, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xC0, 0x03, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xC0, 0x02, 0x00, 0x00, // Code for char æ - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x14, 0x20, 0x1C, 0x20, 0x04, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ç - 0x06, 0x00, 0x00, 0xC0, 0x03, 0xA4, 0x04, 0xA8, 0x04, 0xA0, 0x04, 0xC0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char è - 0x06, 0x00, 0x00, 0xC0, 0x03, 0xA0, 0x04, 0xA8, 0x04, 0xA4, 0x04, 0xC0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char é - 0x06, 0x00, 0x00, 0xC0, 0x03, 0xA8, 0x04, 0xA4, 0x04, 0xA8, 0x04, 0xC0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ê - 0x06, 0x00, 0x00, 0xC4, 0x03, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xC4, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ë - 0x02, 0x04, 0x00, 0xE8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ì - 0x04, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char í - 0x04, 0x00, 0x00, 0x08, 0x00, 0xE4, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char î - 0x04, 0x00, 0x00, 0x04, 0x00, 0xE0, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ï - 0x06, 0x00, 0x00, 0x80, 0x03, 0x54, 0x04, 0x48, 0x04, 0x74, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ð - 0x06, 0x00, 0x00, 0xE8, 0x07, 0x44, 0x00, 0x2C, 0x00, 0x28, 0x00, 0xC4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ñ - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x24, 0x04, 0x28, 0x04, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ò - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x28, 0x04, 0x24, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ó - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x28, 0x04, 0x24, 0x04, 0x28, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ô - 0x06, 0x00, 0x00, 0xC8, 0x03, 0x24, 0x04, 0x2C, 0x04, 0x28, 0x04, 0xC4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char õ - 0x06, 0x00, 0x00, 0xC4, 0x03, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xC4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ö - 0x06, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0xA0, 0x02, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ÷ - 0x06, 0x00, 0x00, 0xC0, 0x07, 0x20, 0x06, 0xA0, 0x05, 0x60, 0x04, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ø - 0x06, 0x00, 0x00, 0xE0, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x02, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ù - 0x06, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x04, 0x08, 0x04, 0x04, 0x02, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ú - 0x06, 0x00, 0x00, 0xE0, 0x03, 0x08, 0x04, 0x04, 0x04, 0x08, 0x02, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char û - 0x06, 0x00, 0x00, 0xE4, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0xE4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ü - 0x05, 0x00, 0x10, 0xE0, 0x11, 0x08, 0x0E, 0x04, 0x02, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ý - 0x06, 0x00, 0x00, 0xFC, 0x1F, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char þ - 0x05, 0x00, 0x10, 0xE4, 0x11, 0x00, 0x0E, 0x00, 0x02, 0xE4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ -}; - -const struct GDS_FontDef Font_droid_sans_fallback_11x13 = { - Droid_Sans_Fallback11x13, - 11, - 13, - ' ', - '\xFF', - false -}; diff --git a/components/display/fonts/font_droid_sans_fallback_15x17.c b/components/display/fonts/font_droid_sans_fallback_15x17.c deleted file mode 100644 index 5ccbee9f..00000000 --- a/components/display/fonts/font_droid_sans_fallback_15x17.c +++ /dev/null @@ -1,247 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Droid_Sans_Fallback15x17 -//GLCD FontSize : 15 x 17 - -static const uint8_t Droid_Sans_Fallback15x17[ ] = { - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x02, 0x00, 0x00, 0x00, 0xF8, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x05, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x08, 0x00, 0x04, 0x00, 0x40, 0x3C, 0x00, 0xC0, 0x07, 0x00, 0x78, 0x04, 0x00, 0x40, 0x3C, 0x00, 0xC0, 0x07, 0x00, 0x78, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # - 0x07, 0x00, 0x00, 0x00, 0xF0, 0x18, 0x00, 0x08, 0x21, 0x00, 0x08, 0x7F, 0x00, 0xFC, 0x21, 0x00, 0x08, 0x21, 0x00, 0x30, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x08, 0x01, 0x00, 0x08, 0x21, 0x00, 0x08, 0x19, 0x00, 0xF0, 0x06, 0x00, 0x00, 0x01, 0x00, 0xC0, 0x1E, 0x00, 0x30, 0x21, 0x00, 0x08, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char % - 0x09, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x70, 0x21, 0x00, 0x88, 0x20, 0x00, 0x88, 0x21, 0x00, 0x88, 0x22, 0x00, 0x70, 0x14, 0x00, 0x00, 0x18, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & - 0x02, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x05, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x60, 0x60, 0x00, 0x10, 0x80, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x04, 0x08, 0x00, 0x01, 0x10, 0x80, 0x00, 0x60, 0x60, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x05, 0x10, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x38, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x04, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x02, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x04, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0xE0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / - 0x07, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 - 0x07, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x08, 0x28, 0x00, 0x08, 0x24, 0x00, 0x08, 0x22, 0x00, 0x08, 0x21, 0x00, 0xF0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 - 0x07, 0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x08, 0x20, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0xF0, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 - 0x07, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x80, 0x05, 0x00, 0x40, 0x04, 0x00, 0x30, 0x04, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 - 0x07, 0x00, 0x00, 0x00, 0xF8, 0x19, 0x00, 0x88, 0x20, 0x00, 0x88, 0x20, 0x00, 0x88, 0x20, 0x00, 0x88, 0x20, 0x00, 0x08, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 - 0x07, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x08, 0x21, 0x00, 0x88, 0x20, 0x00, 0x88, 0x20, 0x00, 0x88, 0x20, 0x00, 0x30, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 - 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x20, 0x00, 0x08, 0x1C, 0x00, 0x08, 0x03, 0x00, 0xC8, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 - 0x07, 0x00, 0x00, 0x00, 0xF0, 0x1E, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0xF0, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 - 0x07, 0x00, 0x00, 0x00, 0xF0, 0x19, 0x00, 0x08, 0x22, 0x00, 0x08, 0x22, 0x00, 0x08, 0x22, 0x00, 0x08, 0x21, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 - 0x02, 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < - 0x08, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = - 0x08, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > - 0x07, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x27, 0x00, 0x88, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0xC0, 0x60, 0x00, 0x20, 0x80, 0x00, 0x10, 0x9E, 0x00, 0x90, 0x21, 0x01, 0x48, 0x20, 0x01, 0x48, 0x20, 0x01, 0x48, 0x10, 0x01, 0x48, 0x3C, 0x01, 0xD0, 0x23, 0x01, 0x10, 0xA0, 0x00, 0x60, 0x10, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, // Code for char @ - 0x09, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x80, 0x03, 0x00, 0x60, 0x02, 0x00, 0x18, 0x02, 0x00, 0x60, 0x02, 0x00, 0x80, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A - 0x09, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x90, 0x12, 0x00, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x30, 0x18, 0x00, 0x10, 0x10, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x10, 0x10, 0x00, 0x30, 0x18, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x10, 0x10, 0x00, 0x30, 0x18, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D - 0x09, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E - 0x09, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x30, 0x18, 0x00, 0x10, 0x10, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x10, 0x11, 0x00, 0x20, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H - 0x02, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I - 0x07, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x80, 0x01, 0x00, 0x40, 0x02, 0x00, 0x20, 0x04, 0x00, 0x10, 0x08, 0x00, 0x08, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K - 0x08, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L - 0x0C, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x20, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char M - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x30, 0x18, 0x00, 0x10, 0x10, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x10, 0x10, 0x00, 0x30, 0x18, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x10, 0x01, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x30, 0x18, 0x00, 0x10, 0x10, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x24, 0x00, 0x08, 0x28, 0x00, 0x10, 0x10, 0x00, 0x30, 0x38, 0x00, 0xC0, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Q - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x90, 0x03, 0x00, 0x60, 0x1C, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R - 0x09, 0x00, 0x00, 0x00, 0x60, 0x08, 0x00, 0x90, 0x10, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x10, 0x12, 0x00, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S - 0x09, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U - 0x09, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x80, 0x03, 0x00, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V - 0x0F, 0x38, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x38, 0x00, 0x00, 0x06, 0x00, 0x80, 0x01, 0x00, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x38, 0x00, 0x00, 0x06, 0x00, 0xC0, 0x01, 0x00, 0x38, 0x00, 0x00, // Code for char W - 0x0A, 0x08, 0x20, 0x00, 0x10, 0x10, 0x00, 0x20, 0x08, 0x00, 0x40, 0x04, 0x00, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x40, 0x04, 0x00, 0x20, 0x08, 0x00, 0x10, 0x10, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X - 0x09, 0x18, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y - 0x08, 0x00, 0x00, 0x00, 0x08, 0x30, 0x00, 0x08, 0x28, 0x00, 0x08, 0x26, 0x00, 0x08, 0x21, 0x00, 0xC8, 0x20, 0x00, 0x28, 0x20, 0x00, 0x18, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z - 0x04, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x04, 0x18, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash - 0x03, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ - 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ - 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x08, 0x00, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a - 0x07, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x80, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b - 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x80, 0x10, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c - 0x07, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x80, 0x10, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d - 0x07, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x12, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x80, 0x12, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e - 0x04, 0x40, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x48, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f - 0x07, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x40, 0x20, 0x01, 0x40, 0x20, 0x01, 0x40, 0x20, 0x01, 0x80, 0x10, 0x01, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g - 0x07, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h - 0x02, 0x00, 0x00, 0x00, 0xC8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i - 0x02, 0x00, 0x00, 0x01, 0xC8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x08, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x00, 0x80, 0x08, 0x00, 0x40, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k - 0x02, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l - 0x0C, 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m - 0x07, 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n - 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x80, 0x10, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o - 0x07, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x80, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p - 0x07, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x80, 0x10, 0x00, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q - 0x05, 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r - 0x07, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x40, 0x24, 0x00, 0x40, 0x24, 0x00, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s - 0x03, 0x40, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x07, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u - 0x07, 0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v - 0x0B, 0xC0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x08, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w - 0x07, 0x40, 0x20, 0x00, 0x80, 0x10, 0x00, 0x00, 0x09, 0x00, 0x00, 0x06, 0x00, 0x00, 0x09, 0x00, 0x80, 0x10, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x - 0x07, 0xC0, 0x00, 0x01, 0x00, 0x03, 0x01, 0x00, 0x8C, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y - 0x07, 0x00, 0x00, 0x00, 0x40, 0x30, 0x00, 0x40, 0x28, 0x00, 0x40, 0x24, 0x00, 0x40, 0x22, 0x00, 0x40, 0x21, 0x00, 0xC0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z - 0x05, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0xF0, 0xFD, 0x00, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x05, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0xF0, 0xFD, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x08, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ - 0x04, 0xF8, 0x3F, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char †- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   - 0x02, 0x00, 0x00, 0x00, 0x40, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0xD0, 0x00, 0x40, 0x3C, 0x00, 0xC0, 0x23, 0x00, 0xB0, 0x10, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¢ - 0x07, 0x00, 0x21, 0x00, 0xF0, 0x31, 0x00, 0x08, 0x2F, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x20, 0x00, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char £ - 0x07, 0x00, 0x00, 0x00, 0x40, 0x0B, 0x00, 0x80, 0x04, 0x00, 0x40, 0x08, 0x00, 0x40, 0x08, 0x00, 0x80, 0x04, 0x00, 0x40, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¤ - 0x07, 0x18, 0x05, 0x00, 0x60, 0x05, 0x00, 0x80, 0x05, 0x00, 0x00, 0x3F, 0x00, 0x80, 0x05, 0x00, 0x60, 0x05, 0x00, 0x18, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¥ - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ - 0x07, 0x00, 0x00, 0x00, 0x70, 0xC7, 0x00, 0x88, 0x08, 0x01, 0x88, 0x08, 0x01, 0x08, 0x11, 0x01, 0x08, 0x11, 0x01, 0x30, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char § - 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ - 0x0B, 0xC0, 0x07, 0x00, 0x20, 0x08, 0x00, 0x10, 0x10, 0x00, 0xC8, 0x27, 0x00, 0x28, 0x28, 0x00, 0x28, 0x28, 0x00, 0x28, 0x28, 0x00, 0x48, 0x24, 0x00, 0x10, 0x10, 0x00, 0x20, 0x08, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char © - 0x05, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0xA8, 0x02, 0x00, 0xA8, 0x02, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª - 0x07, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x09, 0x00, 0x80, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x09, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char « - 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¬ - 0x04, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ - 0x0B, 0xC0, 0x07, 0x00, 0x20, 0x08, 0x00, 0x10, 0x10, 0x00, 0xE8, 0x2F, 0x00, 0x28, 0x21, 0x00, 0x28, 0x21, 0x00, 0x28, 0x23, 0x00, 0xC8, 0x2C, 0x00, 0x10, 0x10, 0x00, 0x20, 0x08, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ® - 0x08, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¯ - 0x05, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x48, 0x00, 0x00, 0x48, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° - 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0xE0, 0x2F, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ± - 0x04, 0x10, 0x01, 0x00, 0x88, 0x01, 0x00, 0x48, 0x01, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² - 0x04, 0x90, 0x00, 0x00, 0x08, 0x01, 0x00, 0x28, 0x01, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ - 0x08, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char µ - 0x08, 0xF0, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xF8, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¶ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ - 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ - 0x05, 0x00, 0x00, 0x00, 0x70, 0x02, 0x00, 0x88, 0x02, 0x00, 0x88, 0x02, 0x00, 0x70, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º - 0x07, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x09, 0x00, 0x00, 0x06, 0x00, 0x80, 0x10, 0x00, 0x00, 0x09, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char » - 0x0B, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xF8, 0x21, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0x00, 0xC0, 0x18, 0x00, 0x20, 0x14, 0x00, 0x10, 0x12, 0x00, 0x08, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¼ - 0x0C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xF8, 0x21, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x22, 0x00, 0x10, 0x31, 0x00, 0x08, 0x29, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ½ - 0x0B, 0x90, 0x00, 0x00, 0x08, 0x01, 0x00, 0x28, 0x21, 0x00, 0xD0, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0x00, 0xC0, 0x18, 0x00, 0x20, 0x14, 0x00, 0x10, 0x12, 0x00, 0x08, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¾ - 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x10, 0x01, 0x40, 0x0E, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¿ - 0x09, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x80, 0x03, 0x00, 0x61, 0x02, 0x00, 0x1A, 0x02, 0x00, 0x60, 0x02, 0x00, 0x80, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char À - 0x09, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x80, 0x03, 0x00, 0x60, 0x02, 0x00, 0x1A, 0x02, 0x00, 0x61, 0x02, 0x00, 0x80, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x09, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x80, 0x03, 0x00, 0x62, 0x02, 0x00, 0x19, 0x02, 0x00, 0x62, 0x02, 0x00, 0x80, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x09, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x03, 0x00, 0x61, 0x02, 0x00, 0x1B, 0x02, 0x00, 0x62, 0x02, 0x00, 0x81, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x09, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x03, 0x00, 0x60, 0x02, 0x00, 0x18, 0x02, 0x00, 0x60, 0x02, 0x00, 0x82, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ä - 0x09, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x80, 0x03, 0x00, 0x62, 0x02, 0x00, 0x1D, 0x02, 0x00, 0x62, 0x02, 0x00, 0x80, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Å - 0x0E, 0x00, 0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x00, 0xC0, 0x04, 0x00, 0x30, 0x04, 0x00, 0x08, 0x04, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, // Code for char Æ - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x30, 0x18, 0x00, 0x10, 0x10, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x01, 0x08, 0x60, 0x01, 0x08, 0xA0, 0x00, 0x10, 0x10, 0x00, 0x30, 0x18, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ç - 0x09, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x09, 0x21, 0x00, 0x0A, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char È - 0x09, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x0A, 0x21, 0x00, 0x09, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char É - 0x09, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x0A, 0x21, 0x00, 0x09, 0x21, 0x00, 0x0A, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ê - 0x09, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x21, 0x00, 0x0A, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x0A, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ë - 0x02, 0x01, 0x00, 0x00, 0xFA, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ì - 0x03, 0x00, 0x00, 0x00, 0xFA, 0x3F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x03, 0x02, 0x00, 0x00, 0xF9, 0x3F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Î - 0x03, 0x02, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0A, 0x00, 0x01, 0x00, 0xF8, 0x3F, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x10, 0x10, 0x00, 0x30, 0x18, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x10, 0x00, 0x00, 0x22, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x03, 0x01, 0x00, 0x02, 0x06, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ñ - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x30, 0x18, 0x00, 0x10, 0x10, 0x00, 0x08, 0x20, 0x00, 0x09, 0x20, 0x00, 0x0A, 0x20, 0x00, 0x08, 0x20, 0x00, 0x10, 0x10, 0x00, 0x30, 0x18, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ò - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x30, 0x18, 0x00, 0x10, 0x10, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x0A, 0x20, 0x00, 0x09, 0x20, 0x00, 0x10, 0x10, 0x00, 0x30, 0x18, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ó - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x30, 0x18, 0x00, 0x10, 0x10, 0x00, 0x0A, 0x20, 0x00, 0x09, 0x20, 0x00, 0x09, 0x20, 0x00, 0x0A, 0x20, 0x00, 0x10, 0x10, 0x00, 0x30, 0x18, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ô - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x30, 0x18, 0x00, 0x10, 0x10, 0x00, 0x0A, 0x20, 0x00, 0x09, 0x20, 0x00, 0x0B, 0x20, 0x00, 0x0A, 0x20, 0x00, 0x11, 0x10, 0x00, 0x30, 0x18, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Õ - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x30, 0x18, 0x00, 0x10, 0x10, 0x00, 0x0A, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x0A, 0x20, 0x00, 0x10, 0x10, 0x00, 0x30, 0x18, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ö - 0x08, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x40, 0x04, 0x00, 0x80, 0x02, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x40, 0x04, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char × - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x27, 0x00, 0x30, 0x18, 0x00, 0x10, 0x18, 0x00, 0x08, 0x24, 0x00, 0x08, 0x22, 0x00, 0x88, 0x21, 0x00, 0x48, 0x20, 0x00, 0x30, 0x10, 0x00, 0x30, 0x18, 0x00, 0xC8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ø - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x01, 0x20, 0x00, 0x02, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ù - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x02, 0x20, 0x00, 0x01, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ú - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x02, 0x20, 0x00, 0x01, 0x20, 0x00, 0x02, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Û - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x10, 0x00, 0x02, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x02, 0x20, 0x00, 0x00, 0x10, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ü - 0x09, 0x18, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, 0x00, 0x02, 0x3F, 0x00, 0x81, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x09, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x40, 0x04, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Þ - 0x08, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x08, 0x00, 0x00, 0x08, 0x10, 0x00, 0x88, 0x21, 0x00, 0x70, 0x22, 0x00, 0x00, 0x24, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ß - 0x08, 0x00, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x40, 0x22, 0x00, 0x48, 0x22, 0x00, 0x50, 0x22, 0x00, 0x40, 0x22, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x08, 0x00, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x40, 0x22, 0x00, 0x50, 0x22, 0x00, 0x48, 0x22, 0x00, 0x40, 0x22, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char á - 0x08, 0x00, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x40, 0x22, 0x00, 0x50, 0x22, 0x00, 0x48, 0x22, 0x00, 0x50, 0x22, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char â - 0x08, 0x00, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x50, 0x22, 0x00, 0x48, 0x22, 0x00, 0x58, 0x22, 0x00, 0x50, 0x22, 0x00, 0x88, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ã - 0x08, 0x00, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x50, 0x22, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x50, 0x22, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ä - 0x08, 0x00, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x40, 0x22, 0x00, 0x48, 0x22, 0x00, 0x54, 0x22, 0x00, 0x48, 0x22, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char å - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x80, 0x1F, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x80, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char æ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x10, 0x00, 0x40, 0x20, 0x01, 0x40, 0x60, 0x01, 0x40, 0xA0, 0x00, 0x80, 0x10, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ç - 0x07, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x12, 0x00, 0x48, 0x22, 0x00, 0x50, 0x22, 0x00, 0x80, 0x12, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char è - 0x07, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x12, 0x00, 0x50, 0x22, 0x00, 0x48, 0x22, 0x00, 0x80, 0x12, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char é - 0x07, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x12, 0x00, 0x50, 0x22, 0x00, 0x48, 0x22, 0x00, 0x90, 0x12, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ê - 0x07, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x90, 0x12, 0x00, 0x40, 0x22, 0x00, 0x40, 0x22, 0x00, 0x90, 0x12, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ë - 0x02, 0x08, 0x00, 0x00, 0xD0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ì - 0x03, 0x00, 0x00, 0x00, 0xD0, 0x3F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char í - 0x03, 0x10, 0x00, 0x00, 0xC8, 0x3F, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char î - 0x03, 0x10, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ï - 0x07, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0xA8, 0x20, 0x00, 0x90, 0x20, 0x00, 0xB0, 0x20, 0x00, 0xC8, 0x20, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ð - 0x07, 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x90, 0x00, 0x00, 0x48, 0x00, 0x00, 0x58, 0x00, 0x00, 0x50, 0x00, 0x00, 0x88, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ñ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x10, 0x00, 0x48, 0x20, 0x00, 0x50, 0x20, 0x00, 0x40, 0x20, 0x00, 0x80, 0x10, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ò - 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x10, 0x00, 0x40, 0x20, 0x00, 0x50, 0x20, 0x00, 0x48, 0x20, 0x00, 0x80, 0x10, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ó - 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x10, 0x00, 0x50, 0x20, 0x00, 0x48, 0x20, 0x00, 0x50, 0x20, 0x00, 0x80, 0x10, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ô - 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x90, 0x10, 0x00, 0x48, 0x20, 0x00, 0x58, 0x20, 0x00, 0x50, 0x20, 0x00, 0x88, 0x10, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char õ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x90, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x90, 0x10, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ö - 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x40, 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ÷ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x80, 0x10, 0x00, 0x40, 0x28, 0x00, 0x40, 0x26, 0x00, 0x40, 0x21, 0x00, 0x80, 0x10, 0x00, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ø - 0x07, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x08, 0x20, 0x00, 0x10, 0x20, 0x00, 0x00, 0x10, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ù - 0x07, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x10, 0x20, 0x00, 0x08, 0x20, 0x00, 0x00, 0x10, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ú - 0x07, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x10, 0x20, 0x00, 0x08, 0x20, 0x00, 0x10, 0x10, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char û - 0x07, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x10, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x10, 0x10, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ü - 0x07, 0xC0, 0x00, 0x01, 0x00, 0x03, 0x01, 0x00, 0x8C, 0x00, 0x10, 0x70, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ý - 0x07, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x80, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char þ - 0x07, 0xC0, 0x00, 0x01, 0x00, 0x03, 0x01, 0x10, 0x8C, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ -}; - -const struct GDS_FontDef Font_droid_sans_fallback_15x17 = { - Droid_Sans_Fallback15x17, - 15, - 17, - ' ', - '\xFF', - false -}; diff --git a/components/display/fonts/font_droid_sans_fallback_24x28.c b/components/display/fonts/font_droid_sans_fallback_24x28.c deleted file mode 100644 index a405e73d..00000000 --- a/components/display/fonts/font_droid_sans_fallback_24x28.c +++ /dev/null @@ -1,247 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Droid_Sans_Fallback24x28 -//GLCD FontSize : 24 x 28 - -static const uint8_t Droid_Sans_Fallback24x28[ ] = { - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x73, 0x00, 0xE0, 0xFF, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0C, 0x63, 0x00, 0x00, 0x0C, 0x7F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x80, 0xFF, 0x03, 0x00, 0xE0, 0x0F, 0x63, 0x00, 0x60, 0x0C, 0x7F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x80, 0xFF, 0x03, 0x00, 0xE0, 0x0F, 0x03, 0x00, 0x60, 0x0C, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x00, 0x80, 0x1F, 0x3C, 0x00, 0xC0, 0x38, 0x30, 0x00, 0xE0, 0x30, 0x60, 0x00, 0x60, 0x30, 0x60, 0x00, 0x60, 0xF0, 0xFF, 0x01, 0xF8, 0x7F, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0xE0, 0x30, 0x00, 0xC0, 0xC0, 0x30, 0x00, 0xC0, 0xC1, 0x1F, 0x00, 0x80, 0x81, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ - 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x40, 0x00, 0xE0, 0x70, 0x70, 0x00, 0xC0, 0x3F, 0x3E, 0x00, 0x80, 0x9F, 0x0F, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x9F, 0x1F, 0x00, 0xC0, 0xC7, 0x3F, 0x00, 0xE0, 0xE0, 0x70, 0x00, 0x20, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char % - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x80, 0xC7, 0x38, 0x00, 0xC0, 0x6F, 0x70, 0x00, 0xE0, 0x7C, 0x60, 0x00, 0x60, 0x38, 0x60, 0x00, 0x60, 0xF0, 0x60, 0x00, 0x60, 0xD8, 0x61, 0x00, 0xE0, 0x8C, 0x73, 0x00, 0xC0, 0x0F, 0x37, 0x00, 0x80, 0x07, 0x3E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xC0, 0x77, 0x00, 0x00, 0xC0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & - 0x03, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x0F, 0xE0, 0x01, 0xC0, 0x01, 0x00, 0x07, 0x60, 0x00, 0x00, 0x0C, 0x20, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x06, 0x20, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x0C, 0xC0, 0x01, 0x00, 0x07, 0x00, 0x0F, 0xE0, 0x01, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x02, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0xC0, 0x03, 0x3C, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x3C, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x60, 0x00, 0x80, 0x03, 0x78, 0x00, 0xC0, 0x01, 0x7C, 0x00, 0xE0, 0x00, 0x6C, 0x00, 0x60, 0x00, 0x66, 0x00, 0x60, 0x00, 0x63, 0x00, 0x60, 0x80, 0x63, 0x00, 0x60, 0xC0, 0x61, 0x00, 0xE0, 0xE0, 0x60, 0x00, 0xC0, 0x70, 0x60, 0x00, 0xC0, 0x3F, 0x60, 0x00, 0x00, 0x0F, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x80, 0x03, 0x1C, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x70, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x30, 0x60, 0x00, 0x60, 0x30, 0x60, 0x00, 0x60, 0x30, 0x60, 0x00, 0xC0, 0x78, 0x70, 0x00, 0xC0, 0x6F, 0x38, 0x00, 0x80, 0xC7, 0x1F, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 - 0x0C, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xE0, 0x06, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x0E, 0x06, 0x00, 0x00, 0x07, 0x06, 0x00, 0xC0, 0x01, 0x06, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x3E, 0x1C, 0x00, 0xE0, 0x3F, 0x38, 0x00, 0xE0, 0x33, 0x70, 0x00, 0x60, 0x18, 0x60, 0x00, 0x60, 0x18, 0x60, 0x00, 0x60, 0x18, 0x60, 0x00, 0x60, 0x18, 0x60, 0x00, 0x60, 0x38, 0x30, 0x00, 0x60, 0x70, 0x38, 0x00, 0x60, 0xE0, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0xFF, 0x1F, 0x00, 0xC0, 0x33, 0x3C, 0x00, 0xC0, 0x30, 0x30, 0x00, 0xE0, 0x18, 0x60, 0x00, 0x60, 0x18, 0x60, 0x00, 0x60, 0x18, 0x60, 0x00, 0x60, 0x18, 0x60, 0x00, 0x60, 0x38, 0x70, 0x00, 0xC0, 0x70, 0x38, 0x00, 0xC0, 0xE1, 0x1F, 0x00, 0x80, 0xC1, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x40, 0x00, 0x60, 0x00, 0x78, 0x00, 0x60, 0x00, 0x3E, 0x00, 0x60, 0x80, 0x0F, 0x00, 0x60, 0xF0, 0x01, 0x00, 0x60, 0x7C, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x8F, 0x3F, 0x00, 0xC0, 0xDF, 0x31, 0x00, 0xC0, 0xF8, 0x70, 0x00, 0x60, 0x70, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x70, 0x60, 0x00, 0xC0, 0xF8, 0x70, 0x00, 0xC0, 0xDF, 0x31, 0x00, 0x80, 0x8F, 0x3F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x18, 0x00, 0x80, 0x7F, 0x38, 0x00, 0xC0, 0xE1, 0x30, 0x00, 0xE0, 0xC0, 0x61, 0x00, 0x60, 0x80, 0x61, 0x00, 0x60, 0x80, 0x61, 0x00, 0x60, 0x80, 0x61, 0x00, 0x60, 0x80, 0x71, 0x00, 0xC0, 0xC0, 0x30, 0x00, 0xC0, 0x43, 0x3C, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x70, 0x02, 0x00, 0x1C, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x98, 0x01, 0x00, 0x00, 0x9C, 0x03, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0x9C, 0x03, 0x00, 0x00, 0x98, 0x01, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x80, 0x73, 0x00, 0x60, 0xC0, 0x73, 0x00, 0x60, 0x60, 0x00, 0x00, 0xE0, 0x30, 0x00, 0x00, 0xC0, 0x38, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x3E, 0xE0, 0x01, 0x00, 0x07, 0x80, 0x03, 0x80, 0x83, 0x1F, 0x03, 0x80, 0xE1, 0x3F, 0x07, 0xC0, 0x70, 0x70, 0x06, 0xC0, 0x38, 0x60, 0x0E, 0x60, 0x1C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x30, 0x0C, 0x60, 0x0C, 0x18, 0x0C, 0x60, 0x1C, 0x3E, 0x0C, 0x60, 0xF8, 0x7F, 0x0C, 0xE0, 0xFC, 0x61, 0x0C, 0xC0, 0x1C, 0x60, 0x06, 0xC0, 0x01, 0x70, 0x04, 0x80, 0x03, 0x38, 0x00, 0x00, 0x0F, 0x1C, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char @ - 0x11, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x03, 0x00, 0xC0, 0x07, 0x03, 0x00, 0xE0, 0x01, 0x03, 0x00, 0x60, 0x00, 0x03, 0x00, 0xE0, 0x03, 0x03, 0x00, 0x80, 0x0F, 0x03, 0x00, 0x00, 0x3E, 0x03, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0xC0, 0xF0, 0x70, 0x00, 0xC0, 0xDF, 0x30, 0x00, 0x00, 0x8F, 0x1F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x80, 0x07, 0x1E, 0x00, 0xC0, 0x01, 0x38, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x70, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x80, 0x01, 0x38, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x70, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x38, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F - 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x80, 0x01, 0x18, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0xC0, 0x60, 0x00, 0x60, 0xC0, 0x60, 0x00, 0xC0, 0xC0, 0x70, 0x00, 0xC0, 0xC0, 0x30, 0x00, 0x80, 0xC1, 0x38, 0x00, 0x00, 0xC7, 0x7F, 0x00, 0x00, 0xC6, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xEE, 0x00, 0x00, 0x00, 0xC7, 0x03, 0x00, 0x80, 0x03, 0x07, 0x00, 0xC0, 0x01, 0x0E, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0x60, 0x00, 0x70, 0x00, 0x20, 0x00, 0x60, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L - 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char M - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N - 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x80, 0x01, 0x18, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x70, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x38, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x60, 0xC0, 0x00, 0x00, 0xE0, 0x60, 0x00, 0x00, 0xC0, 0x71, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P - 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x80, 0x01, 0x18, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x64, 0x00, 0x60, 0x00, 0x6E, 0x00, 0xE0, 0x00, 0x3C, 0x00, 0xC0, 0x00, 0x38, 0x00, 0xC0, 0x01, 0x3C, 0x00, 0x80, 0x07, 0x7E, 0x00, 0x00, 0xFE, 0xE7, 0x00, 0x00, 0xF8, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Q - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0xE0, 0x00, 0x00, 0x60, 0xA0, 0x01, 0x00, 0xC0, 0xB0, 0x07, 0x00, 0xC0, 0x1F, 0x3F, 0x00, 0x00, 0x0F, 0x78, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0F, 0x1E, 0x00, 0x80, 0x1F, 0x38, 0x00, 0xC0, 0x18, 0x30, 0x00, 0xE0, 0x30, 0x70, 0x00, 0x60, 0x30, 0x60, 0x00, 0x60, 0x30, 0x60, 0x00, 0x60, 0x70, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0xC0, 0xE0, 0x30, 0x00, 0xC0, 0xC1, 0x38, 0x00, 0x80, 0x83, 0x1F, 0x00, 0x00, 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S - 0x0E, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x07, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U - 0x11, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V - 0x18, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, // Code for char W - 0x11, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x60, 0x00, 0x60, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0x80, 0x03, 0x0E, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x8E, 0x01, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x8E, 0x01, 0x00, 0x00, 0x07, 0x07, 0x00, 0x80, 0x03, 0x0E, 0x00, 0xE0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x70, 0x00, 0x20, 0x00, 0x60, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X - 0x10, 0x20, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x60, 0x00, 0x78, 0x00, 0x60, 0x00, 0x7C, 0x00, 0x60, 0x00, 0x67, 0x00, 0x60, 0x80, 0x63, 0x00, 0x60, 0xC0, 0x61, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x38, 0x60, 0x00, 0x60, 0x1C, 0x60, 0x00, 0x60, 0x0E, 0x60, 0x00, 0xE0, 0x03, 0x60, 0x00, 0xE0, 0x01, 0x60, 0x00, 0xE0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x0F, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x07, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash - 0x05, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0xE0, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ - 0x0E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ - 0x06, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x00, 0x00, 0x38, 0x3F, 0x00, 0x00, 0x1C, 0x73, 0x00, 0x00, 0x8C, 0x63, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x31, 0x00, 0x00, 0x9C, 0x31, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x18, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x70, 0x00, 0x00, 0x18, 0x30, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xB8, 0x39, 0x00, 0x00, 0x9C, 0x31, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x9C, 0x61, 0x00, 0x00, 0xB8, 0x31, 0x00, 0x00, 0xF0, 0x39, 0x00, 0x00, 0xE0, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e - 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x0C, 0x00, 0x00, 0x60, 0x0C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x03, 0x00, 0xF0, 0x1F, 0x07, 0x00, 0x38, 0x38, 0x0E, 0x00, 0x1C, 0x70, 0x0C, 0x00, 0x0C, 0x60, 0x0C, 0x00, 0x0C, 0x60, 0x0C, 0x00, 0x0C, 0x60, 0x0C, 0x00, 0x0C, 0x30, 0x0C, 0x00, 0x18, 0x30, 0x06, 0x00, 0xFC, 0xFF, 0x07, 0x00, 0xFC, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xFC, 0x7F, 0x00, 0x60, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i - 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x60, 0xFC, 0xFF, 0x0F, 0x60, 0xFC, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x30, 0x07, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x04, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l - 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x0F, 0x00, 0xFC, 0xFF, 0x0F, 0x00, 0x18, 0x30, 0x00, 0x00, 0x1C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x30, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0xFC, 0xFF, 0x0F, 0x00, 0xFC, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x00, 0x00, 0xF8, 0x38, 0x00, 0x00, 0xDC, 0x71, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x63, 0x00, 0x00, 0x0C, 0x63, 0x00, 0x00, 0x1C, 0x33, 0x00, 0x00, 0x38, 0x3F, 0x00, 0x00, 0x30, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s - 0x06, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0x80, 0xFF, 0x7F, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v - 0x12, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w - 0x0C, 0x00, 0x04, 0x40, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x70, 0x1C, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0x70, 0x1C, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x0C, 0x00, 0xF0, 0x03, 0x0C, 0x00, 0x80, 0x0F, 0x0E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x70, 0x00, 0x00, 0x0C, 0x78, 0x00, 0x00, 0x0C, 0x7C, 0x00, 0x00, 0x0C, 0x6E, 0x00, 0x00, 0x0C, 0x67, 0x00, 0x00, 0x8C, 0x63, 0x00, 0x00, 0xCC, 0x61, 0x00, 0x00, 0xEC, 0x60, 0x00, 0x00, 0x7C, 0x60, 0x00, 0x00, 0x3C, 0x60, 0x00, 0x00, 0x1C, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z - 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x80, 0xFF, 0xFC, 0x03, 0xC0, 0x7F, 0xF8, 0x07, 0xE0, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x08, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0xE0, 0x00, 0x00, 0x0C, 0xC0, 0x7F, 0xF8, 0x07, 0x80, 0xFF, 0xFC, 0x03, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x0E, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ - 0x07, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x7F, 0x00, 0x30, 0x00, 0x40, 0x00, 0x30, 0x00, 0x40, 0x00, 0x30, 0x00, 0x40, 0x00, 0xF0, 0xFF, 0x7F, 0x00, 0xF0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char †- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0xFF, 0x0F, 0x00, 0x9C, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x38, 0x38, 0x03, 0x00, 0x1C, 0xF0, 0x00, 0x00, 0x0C, 0x6E, 0x00, 0x00, 0xEC, 0x61, 0x00, 0x00, 0x1E, 0x60, 0x00, 0x80, 0x1D, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¢ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x70, 0x00, 0x00, 0x7F, 0x38, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0xC0, 0xE0, 0x33, 0x00, 0x60, 0x60, 0x30, 0x00, 0x60, 0x60, 0x30, 0x00, 0x60, 0x60, 0x30, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x03, 0x60, 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char £ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0xF7, 0x0E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF7, 0x0E, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¤ - 0x0E, 0x20, 0x00, 0x00, 0x00, 0xE0, 0x60, 0x06, 0x00, 0xC0, 0x61, 0x06, 0x00, 0x80, 0x67, 0x06, 0x00, 0x00, 0x7E, 0x06, 0x00, 0x00, 0x78, 0x06, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x78, 0x06, 0x00, 0x00, 0x7E, 0x06, 0x00, 0x80, 0x67, 0x06, 0x00, 0xC0, 0x61, 0x06, 0x00, 0xE0, 0x60, 0x06, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¥ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x3F, 0xF8, 0x0F, 0xE0, 0x3F, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x80, 0xF3, 0x03, 0x03, 0xC0, 0x1F, 0x07, 0x07, 0xE0, 0x1C, 0x0E, 0x06, 0x60, 0x18, 0x0C, 0x0C, 0x60, 0x38, 0x1C, 0x0C, 0x60, 0x30, 0x18, 0x0C, 0x60, 0x70, 0x38, 0x0C, 0xC0, 0x60, 0x70, 0x0E, 0xC0, 0xC1, 0xF8, 0x07, 0x80, 0xC1, 0xCF, 0x03, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char § - 0x08, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ - 0x12, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x80, 0x03, 0x1C, 0x00, 0xC0, 0xF9, 0x38, 0x00, 0xC0, 0xFC, 0x33, 0x00, 0x60, 0x0E, 0x66, 0x00, 0x60, 0x02, 0x64, 0x00, 0x60, 0x02, 0x64, 0x00, 0x60, 0x02, 0x64, 0x00, 0x60, 0x06, 0x66, 0x00, 0x60, 0x0C, 0x63, 0x00, 0xC0, 0x08, 0x31, 0x00, 0xC0, 0x01, 0x38, 0x00, 0x80, 0x03, 0x1C, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char © - 0x09, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1C, 0x01, 0x00, 0x60, 0x3E, 0x01, 0x00, 0x20, 0x23, 0x01, 0x00, 0x20, 0x21, 0x01, 0x00, 0x20, 0x21, 0x01, 0x00, 0x20, 0x11, 0x01, 0x00, 0xE0, 0x3F, 0x01, 0x00, 0xC0, 0x3F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x08, 0x21, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char « - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¬ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ - 0x12, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x80, 0x03, 0x1C, 0x00, 0xC0, 0x01, 0x38, 0x00, 0xC0, 0xFE, 0x37, 0x00, 0x60, 0xFE, 0x67, 0x00, 0x60, 0x42, 0x60, 0x00, 0x60, 0x42, 0x60, 0x00, 0x60, 0xC2, 0x60, 0x00, 0x60, 0xE6, 0x63, 0x00, 0x60, 0x3E, 0x67, 0x00, 0xC0, 0x3C, 0x34, 0x00, 0xC0, 0x01, 0x38, 0x00, 0x80, 0x03, 0x1C, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ® - 0x0D, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¯ - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0xFF, 0x6F, 0x00, 0x00, 0xFF, 0x6F, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ± - 0x08, 0x80, 0x20, 0x00, 0x00, 0xC0, 0x38, 0x00, 0x00, 0x60, 0x38, 0x00, 0x00, 0x20, 0x3C, 0x00, 0x00, 0x20, 0x2E, 0x00, 0x00, 0x20, 0x26, 0x00, 0x00, 0xE0, 0x23, 0x00, 0x00, 0xC0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² - 0x07, 0x40, 0x18, 0x00, 0x00, 0x60, 0x38, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x20, 0x22, 0x00, 0x00, 0x20, 0x22, 0x00, 0x00, 0xE0, 0x3D, 0x00, 0x00, 0xC0, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x0F, 0x00, 0xFC, 0xFF, 0x0F, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char µ - 0x0D, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x0F, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x0F, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¶ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ - 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x3F, 0x00, 0x00, 0xE0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ - 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0F, 0x01, 0x00, 0xC0, 0x1F, 0x01, 0x00, 0x60, 0x30, 0x01, 0x00, 0x20, 0x20, 0x01, 0x00, 0x20, 0x20, 0x01, 0x00, 0x60, 0x30, 0x01, 0x00, 0xC0, 0x1F, 0x01, 0x00, 0x80, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x08, 0x21, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char » - 0x13, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x3F, 0x40, 0x00, 0xE0, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00, 0x00, 0x08, 0x1C, 0x00, 0x00, 0x04, 0x12, 0x00, 0x00, 0x83, 0x11, 0x00, 0x80, 0xC0, 0x7F, 0x00, 0x40, 0xC0, 0x7F, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¼ - 0x14, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0xE0, 0x3F, 0x20, 0x00, 0xE0, 0x3F, 0x10, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x41, 0x00, 0x00, 0x84, 0x71, 0x00, 0x00, 0xC3, 0x70, 0x00, 0x80, 0x40, 0x78, 0x00, 0x40, 0x40, 0x5C, 0x00, 0x20, 0x40, 0x4C, 0x00, 0x00, 0xC0, 0x47, 0x00, 0x00, 0x80, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ½ - 0x13, 0x40, 0x18, 0x00, 0x00, 0x60, 0x38, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x20, 0x22, 0x00, 0x00, 0x20, 0x22, 0x40, 0x00, 0xE0, 0x3D, 0x20, 0x00, 0xC0, 0x1D, 0x10, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00, 0x00, 0x08, 0x1C, 0x00, 0x00, 0x04, 0x12, 0x00, 0x00, 0x83, 0x11, 0x00, 0x80, 0xC0, 0x7F, 0x00, 0x40, 0xC0, 0x7F, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¾ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x38, 0x06, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x9C, 0x07, 0x0C, 0x00, 0x9C, 0x03, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¿ - 0x11, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0x3E, 0x03, 0x00, 0xC6, 0x07, 0x03, 0x00, 0xEE, 0x01, 0x03, 0x00, 0x6E, 0x00, 0x03, 0x00, 0xE8, 0x03, 0x03, 0x00, 0x80, 0x0F, 0x03, 0x00, 0x00, 0x3E, 0x03, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char À - 0x11, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x03, 0x00, 0xC0, 0x07, 0x03, 0x00, 0xE8, 0x01, 0x03, 0x00, 0x6E, 0x00, 0x03, 0x00, 0xEE, 0x03, 0x03, 0x00, 0x86, 0x0F, 0x03, 0x00, 0x02, 0x3E, 0x03, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x11, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x08, 0xF8, 0x03, 0x00, 0x0C, 0x3E, 0x03, 0x00, 0xCE, 0x07, 0x03, 0x00, 0xE6, 0x01, 0x03, 0x00, 0x66, 0x00, 0x03, 0x00, 0xEE, 0x03, 0x03, 0x00, 0x8C, 0x0F, 0x03, 0x00, 0x08, 0x3E, 0x03, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x11, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x0C, 0x3E, 0x03, 0x00, 0xCE, 0x07, 0x03, 0x00, 0xE6, 0x01, 0x03, 0x00, 0x66, 0x00, 0x03, 0x00, 0xEC, 0x03, 0x03, 0x00, 0x8C, 0x0F, 0x03, 0x00, 0x0E, 0x3E, 0x03, 0x00, 0x06, 0xF0, 0x03, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x11, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x0E, 0x3E, 0x03, 0x00, 0xCE, 0x07, 0x03, 0x00, 0xE0, 0x01, 0x03, 0x00, 0x60, 0x00, 0x03, 0x00, 0xE0, 0x03, 0x03, 0x00, 0x8E, 0x0F, 0x03, 0x00, 0x0E, 0x3E, 0x03, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ä - 0x11, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x03, 0x00, 0xCE, 0x07, 0x03, 0x00, 0xF1, 0x01, 0x03, 0x00, 0x71, 0x00, 0x03, 0x00, 0xF1, 0x03, 0x03, 0x00, 0x8E, 0x0F, 0x03, 0x00, 0x00, 0x3E, 0x03, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Å - 0x18, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x38, 0x03, 0x00, 0x00, 0x0E, 0x03, 0x00, 0x80, 0x03, 0x03, 0x00, 0xC0, 0x01, 0x03, 0x00, 0x60, 0x00, 0x03, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, // Code for char Æ - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x80, 0x07, 0x1E, 0x00, 0xC0, 0x01, 0x38, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x60, 0x00, 0x60, 0x08, 0x60, 0x00, 0xE0, 0x09, 0x60, 0x00, 0xE0, 0x09, 0x60, 0x00, 0x60, 0x0F, 0x60, 0x00, 0x60, 0x06, 0xE0, 0x00, 0x70, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x80, 0x01, 0x38, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ç - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x62, 0x60, 0x60, 0x00, 0x66, 0x60, 0x60, 0x00, 0x6E, 0x60, 0x60, 0x00, 0x6E, 0x60, 0x60, 0x00, 0x68, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char È - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x68, 0x60, 0x60, 0x00, 0x6E, 0x60, 0x60, 0x00, 0x6E, 0x60, 0x60, 0x00, 0x66, 0x60, 0x60, 0x00, 0x62, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char É - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x60, 0x60, 0x00, 0x68, 0x60, 0x60, 0x00, 0x6C, 0x60, 0x60, 0x00, 0x6E, 0x60, 0x60, 0x00, 0x66, 0x60, 0x60, 0x00, 0x66, 0x60, 0x60, 0x00, 0x6E, 0x60, 0x60, 0x00, 0x6C, 0x60, 0x60, 0x00, 0x68, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ê - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x6E, 0x60, 0x60, 0x00, 0x6E, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x6E, 0x60, 0x60, 0x00, 0x6E, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ë - 0x05, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xEE, 0xFF, 0x7F, 0x00, 0xEE, 0xFF, 0x7F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ì - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0x7F, 0x00, 0xEE, 0xFF, 0x7F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x07, 0x0C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xE6, 0xFF, 0x7F, 0x00, 0xE6, 0xFF, 0x7F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Î - 0x06, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x11, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x70, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x38, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x0C, 0x0E, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0x00, 0x06, 0x70, 0x00, 0x00, 0x06, 0xE0, 0x00, 0x00, 0x0C, 0x80, 0x03, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x06, 0x00, 0x38, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ñ - 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x80, 0x01, 0x18, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x62, 0x00, 0x60, 0x00, 0x66, 0x00, 0x60, 0x00, 0x6E, 0x00, 0x60, 0x00, 0x6E, 0x00, 0x60, 0x00, 0x68, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x70, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x38, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ò - 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x80, 0x01, 0x18, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x60, 0x00, 0x60, 0x00, 0x68, 0x00, 0x60, 0x00, 0x6E, 0x00, 0x60, 0x00, 0x6E, 0x00, 0x60, 0x00, 0x66, 0x00, 0x60, 0x00, 0xE2, 0x00, 0x70, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x38, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ó - 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x80, 0x01, 0x18, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xE8, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x60, 0x00, 0x6E, 0x00, 0x60, 0x00, 0x66, 0x00, 0x60, 0x00, 0x66, 0x00, 0x60, 0x00, 0x6E, 0x00, 0x60, 0x00, 0xEC, 0x00, 0x70, 0x00, 0xC8, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x38, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ô - 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x80, 0x01, 0x18, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xEC, 0x00, 0x70, 0x00, 0x6E, 0x00, 0x60, 0x00, 0x66, 0x00, 0x60, 0x00, 0x66, 0x00, 0x60, 0x00, 0x6C, 0x00, 0x60, 0x00, 0x6C, 0x00, 0x60, 0x00, 0xEE, 0x00, 0x70, 0x00, 0xC6, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x38, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Õ - 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x80, 0x01, 0x18, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xEE, 0x00, 0x70, 0x00, 0x6E, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x6E, 0x00, 0x60, 0x00, 0xEE, 0x00, 0x70, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x38, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ö - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x1C, 0x07, 0x00, 0x00, 0xB8, 0x03, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xB8, 0x03, 0x00, 0x00, 0x1C, 0x07, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char × - 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x41, 0x00, 0x00, 0xFE, 0x67, 0x00, 0x80, 0x07, 0x3E, 0x00, 0x80, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x36, 0x00, 0xE0, 0x00, 0x73, 0x00, 0x60, 0x80, 0x61, 0x00, 0x60, 0xC0, 0x60, 0x00, 0x60, 0x60, 0x60, 0x00, 0x60, 0x30, 0x60, 0x00, 0x60, 0x18, 0x60, 0x00, 0xE0, 0x0C, 0x70, 0x00, 0xC0, 0x06, 0x30, 0x00, 0x80, 0x03, 0x38, 0x00, 0xC0, 0x07, 0x1E, 0x00, 0x60, 0xFE, 0x07, 0x00, 0x20, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ø - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x07, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x60, 0x00, 0x06, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x60, 0x00, 0x08, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ù - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x07, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x08, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x60, 0x00, 0x06, 0x00, 0x60, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ú - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x07, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x08, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x60, 0x00, 0x06, 0x00, 0x60, 0x00, 0x06, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x60, 0x00, 0x0C, 0x00, 0x60, 0x00, 0x08, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Û - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x07, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x0E, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ü - 0x10, 0x20, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x08, 0xE0, 0x7F, 0x00, 0x0E, 0xE0, 0x7F, 0x00, 0x0E, 0x70, 0x00, 0x00, 0x06, 0x1C, 0x00, 0x00, 0x02, 0x0E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x07, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Þ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x18, 0x00, 0x60, 0x70, 0x38, 0x00, 0xE0, 0xFC, 0x70, 0x00, 0xC0, 0xCF, 0x61, 0x00, 0x80, 0x83, 0x61, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ß - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x00, 0x00, 0x38, 0x3F, 0x00, 0x00, 0x1C, 0x73, 0x00, 0x20, 0x8C, 0x63, 0x00, 0x60, 0x8C, 0x61, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0x80, 0x8C, 0x31, 0x00, 0x00, 0x9C, 0x31, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x00, 0x00, 0x38, 0x3F, 0x00, 0x00, 0x1C, 0x73, 0x00, 0x00, 0x8C, 0x63, 0x00, 0x80, 0x8C, 0x61, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0x60, 0x8C, 0x31, 0x00, 0x20, 0x9C, 0x31, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char á - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x00, 0x00, 0x38, 0x3F, 0x00, 0x80, 0x1C, 0x73, 0x00, 0xC0, 0x8C, 0x63, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0x60, 0x8C, 0x61, 0x00, 0x60, 0x8C, 0x61, 0x00, 0xE0, 0x8C, 0x31, 0x00, 0xC0, 0x9C, 0x31, 0x00, 0x80, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char â - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x00, 0x00, 0x38, 0x3F, 0x00, 0xC0, 0x1C, 0x73, 0x00, 0xE0, 0x8C, 0x63, 0x00, 0x60, 0x8C, 0x61, 0x00, 0x60, 0x8C, 0x61, 0x00, 0xC0, 0x8C, 0x61, 0x00, 0xC0, 0x8C, 0x31, 0x00, 0xE0, 0x9C, 0x31, 0x00, 0x60, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ã - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x00, 0x00, 0x38, 0x3F, 0x00, 0x00, 0x1C, 0x73, 0x00, 0xE0, 0x8C, 0x63, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x31, 0x00, 0xE0, 0x9C, 0x31, 0x00, 0xE0, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ä - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x00, 0x00, 0x38, 0x3F, 0x00, 0x00, 0x1C, 0x73, 0x00, 0x00, 0x8C, 0x63, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0x10, 0x8D, 0x61, 0x00, 0x10, 0x8D, 0x61, 0x00, 0x10, 0x8D, 0x31, 0x00, 0xE0, 0x9C, 0x31, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char å - 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x00, 0x00, 0x38, 0x3F, 0x00, 0x00, 0x18, 0x73, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x71, 0x00, 0x00, 0x9C, 0x31, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0xB8, 0x39, 0x00, 0x00, 0x8C, 0x71, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x9C, 0x61, 0x00, 0x00, 0xB8, 0x31, 0x00, 0x00, 0xF0, 0x39, 0x00, 0x00, 0xE0, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char æ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x0C, 0x60, 0x08, 0x00, 0x0C, 0xE0, 0x09, 0x00, 0x0C, 0xE0, 0x09, 0x00, 0x0C, 0x60, 0x0F, 0x00, 0x18, 0x70, 0x06, 0x00, 0x38, 0x38, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ç - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xB8, 0x39, 0x00, 0x20, 0x9C, 0x31, 0x00, 0x60, 0x8C, 0x61, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0x80, 0x8C, 0x61, 0x00, 0x00, 0x9C, 0x61, 0x00, 0x00, 0xB8, 0x31, 0x00, 0x00, 0xF0, 0x39, 0x00, 0x00, 0xE0, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char è - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xB8, 0x39, 0x00, 0x00, 0x9C, 0x31, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x80, 0x8C, 0x61, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0x60, 0x9C, 0x61, 0x00, 0x20, 0xB8, 0x31, 0x00, 0x00, 0xF0, 0x39, 0x00, 0x00, 0xE0, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char é - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x80, 0xB8, 0x39, 0x00, 0xC0, 0x9C, 0x31, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0x60, 0x8C, 0x61, 0x00, 0x60, 0x8C, 0x61, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0xC0, 0x9C, 0x61, 0x00, 0x80, 0xB8, 0x31, 0x00, 0x00, 0xF0, 0x39, 0x00, 0x00, 0xE0, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ê - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xB8, 0x39, 0x00, 0xE0, 0x9C, 0x31, 0x00, 0xE0, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0x8C, 0x61, 0x00, 0xE0, 0x9C, 0x61, 0x00, 0xE0, 0xB8, 0x31, 0x00, 0x00, 0xF0, 0x39, 0x00, 0x00, 0xE0, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ë - 0x04, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xFC, 0x7F, 0x00, 0x80, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ì - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFC, 0x7F, 0x00, 0xE0, 0xFC, 0x7F, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char í - 0x07, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0xFC, 0x7F, 0x00, 0x60, 0xFC, 0x7F, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char î - 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ï - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x38, 0x38, 0x00, 0x20, 0x1D, 0x70, 0x00, 0xA0, 0x0D, 0x60, 0x00, 0xE0, 0x0C, 0x60, 0x00, 0xC0, 0x0C, 0x60, 0x00, 0xC0, 0x0D, 0x60, 0x00, 0x60, 0x1F, 0x70, 0x00, 0x20, 0x3E, 0x38, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ð - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0xC0, 0xFC, 0x7F, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0x60, 0x0C, 0x00, 0x00, 0xC0, 0x0C, 0x00, 0x00, 0xC0, 0x0C, 0x00, 0x00, 0xE0, 0x1C, 0x00, 0x00, 0x60, 0xF8, 0x7F, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ñ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x38, 0x38, 0x00, 0x20, 0x1C, 0x70, 0x00, 0x60, 0x0C, 0x60, 0x00, 0xE0, 0x0C, 0x60, 0x00, 0xE0, 0x0C, 0x60, 0x00, 0x80, 0x0C, 0x60, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ò - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x80, 0x0C, 0x60, 0x00, 0xE0, 0x0C, 0x60, 0x00, 0xE0, 0x0C, 0x60, 0x00, 0x60, 0x1C, 0x70, 0x00, 0x20, 0x38, 0x38, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ó - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x80, 0x38, 0x38, 0x00, 0xC0, 0x1C, 0x70, 0x00, 0xE0, 0x0C, 0x60, 0x00, 0x60, 0x0C, 0x60, 0x00, 0x60, 0x0C, 0x60, 0x00, 0xE0, 0x0C, 0x60, 0x00, 0xC0, 0x1C, 0x70, 0x00, 0x80, 0x38, 0x38, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ô - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0xC0, 0x38, 0x38, 0x00, 0xE0, 0x1C, 0x70, 0x00, 0x60, 0x0C, 0x60, 0x00, 0x60, 0x0C, 0x60, 0x00, 0xC0, 0x0C, 0x60, 0x00, 0xC0, 0x0C, 0x60, 0x00, 0xE0, 0x1C, 0x70, 0x00, 0x60, 0x38, 0x38, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char õ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x38, 0x38, 0x00, 0xE0, 0x1C, 0x70, 0x00, 0xE0, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0xE0, 0x1C, 0x70, 0x00, 0xE0, 0x38, 0x38, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ö - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x67, 0x0E, 0x00, 0x00, 0x67, 0x0E, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ÷ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x4F, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1C, 0x7C, 0x00, 0x00, 0x0C, 0x66, 0x00, 0x00, 0x0C, 0x63, 0x00, 0x00, 0x8C, 0x61, 0x00, 0x00, 0xCC, 0x60, 0x00, 0x00, 0x7C, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0xC4, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ø - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x20, 0x00, 0x70, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x60, 0x00, 0x80, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ù - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x80, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x20, 0xFC, 0x7F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ú - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x80, 0xFC, 0x3F, 0x00, 0xC0, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x80, 0xFC, 0x7F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char û - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0xE0, 0xFC, 0x3F, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0xE0, 0xFC, 0x7F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ü - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x0C, 0x00, 0xF0, 0x03, 0x0C, 0x00, 0x80, 0x0F, 0x0E, 0x80, 0x00, 0xFE, 0x07, 0xE0, 0x00, 0xF0, 0x01, 0xE0, 0x00, 0x7E, 0x00, 0x60, 0x80, 0x0F, 0x00, 0x20, 0xF0, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ý - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x0F, 0x00, 0x18, 0x30, 0x00, 0x00, 0x18, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char þ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x0C, 0xE0, 0xF0, 0x03, 0x0C, 0xE0, 0x80, 0x0F, 0x0E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x7E, 0x00, 0xE0, 0x80, 0x0F, 0x00, 0xE0, 0xF0, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ -}; - -const struct GDS_FontDef Font_droid_sans_fallback_24x28 = { - Droid_Sans_Fallback24x28, - 24, - 28, - ' ', - '\xFF', - false -}; diff --git a/components/display/fonts/font_droid_sans_mono_13x24.c b/components/display/fonts/font_droid_sans_mono_13x24.c deleted file mode 100644 index 58b45ff6..00000000 --- a/components/display/fonts/font_droid_sans_mono_13x24.c +++ /dev/null @@ -1,247 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Droid_Sans_Mono13x24 -//GLCD FontSize : 13 x 24 - -static const uint8_t Droid_Sans_Mono13x24[ ] = { - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x07, 0xF0, 0x7F, 0x07, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x0C, 0x00, 0x60, 0x00, 0x00, 0x63, 0x06, 0x00, 0xF3, 0x07, 0x00, 0x7F, 0x00, 0xF0, 0x63, 0x00, 0x30, 0x63, 0x00, 0x00, 0x63, 0x06, 0x00, 0xF3, 0x07, 0x00, 0x7F, 0x00, 0xF0, 0x63, 0x00, 0x30, 0x63, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, // Code for char # - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x01, 0xC0, 0x07, 0x03, 0x60, 0x0C, 0x03, 0x60, 0x0C, 0x03, 0xF8, 0xFF, 0x0F, 0x60, 0x18, 0x03, 0x60, 0x18, 0x03, 0x60, 0xF0, 0x01, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ - 0x0C, 0xE0, 0x03, 0x00, 0xF0, 0x07, 0x04, 0x10, 0x04, 0x07, 0x10, 0x84, 0x01, 0xF0, 0xE7, 0x00, 0xE0, 0x3B, 0x00, 0x00, 0xEE, 0x03, 0x80, 0xF3, 0x07, 0xC0, 0x10, 0x04, 0x70, 0x10, 0x04, 0x10, 0xF0, 0x07, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, // Code for char % - 0x0D, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0xE0, 0xF1, 0x03, 0xF0, 0x1F, 0x06, 0x30, 0x0E, 0x06, 0x30, 0x1C, 0x06, 0x30, 0x3E, 0x06, 0xF0, 0x63, 0x06, 0xE0, 0xC1, 0x03, 0x00, 0xC0, 0x01, 0x00, 0xF0, 0x07, 0x00, 0x30, 0x06, 0x00, 0x00, 0x04, // Code for char & - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFF, 0x03, 0xC0, 0x03, 0x0F, 0xE0, 0x00, 0x1C, 0x30, 0x00, 0x30, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x30, 0x00, 0x30, 0xE0, 0x00, 0x1C, 0xC0, 0x03, 0x0F, 0x00, 0xFF, 0x03, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x04, 0x00, 0xC0, 0x0E, 0x00, 0x80, 0x07, 0x00, 0xF8, 0x01, 0x00, 0x88, 0x03, 0x00, 0xC0, 0x0E, 0x00, 0xC0, 0x04, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x80, 0xFF, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x00, 0xC0, 0x03, 0x00, 0xF0, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x70, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0xFF, 0x01, 0x60, 0x00, 0x03, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x60, 0x00, 0x03, 0xC0, 0xFF, 0x01, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x20, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x06, 0x60, 0x00, 0x07, 0x30, 0x80, 0x07, 0x30, 0xC0, 0x06, 0x30, 0x60, 0x06, 0x30, 0x30, 0x06, 0x30, 0x1C, 0x06, 0xE0, 0x0F, 0x06, 0xC0, 0x03, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, // Code for char 2 - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x02, 0x20, 0x00, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x1A, 0x07, 0xE0, 0xFB, 0x03, 0xC0, 0xF1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xDC, 0x00, 0x00, 0xCE, 0x00, 0x00, 0xC3, 0x00, 0xC0, 0xC1, 0x00, 0x60, 0xC0, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, // Code for char 4 - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x02, 0xF0, 0x0F, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x1C, 0x03, 0x30, 0xF8, 0x03, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0xC0, 0xFF, 0x01, 0xE0, 0x19, 0x03, 0x60, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x04, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x07, 0x30, 0xF8, 0x03, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 - 0x0B, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x04, 0x30, 0x00, 0x07, 0x30, 0xE0, 0x03, 0x30, 0xF8, 0x00, 0x30, 0x1E, 0x00, 0xB0, 0x07, 0x00, 0xF0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0xC0, 0xF1, 0x03, 0xE0, 0x13, 0x06, 0x30, 0x1E, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x1E, 0x06, 0xE0, 0x1F, 0x06, 0xC0, 0xF1, 0x03, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0xE0, 0x0F, 0x06, 0x70, 0x18, 0x04, 0x30, 0x18, 0x04, 0x30, 0x10, 0x06, 0x30, 0x18, 0x06, 0x30, 0x18, 0x03, 0x60, 0xCC, 0x03, 0xC0, 0xFF, 0x01, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x07, 0x80, 0x03, 0x07, 0x80, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x3C, 0x80, 0x03, 0x3E, 0x80, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x24, 0x00, 0x00, 0x66, 0x00, 0x00, 0x42, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x81, 0x00, 0x80, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x01, 0x00, 0x81, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x42, 0x00, 0x00, 0x66, 0x00, 0x00, 0x24, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x60, 0x07, 0x30, 0x70, 0x07, 0x30, 0x18, 0x07, 0x30, 0x0C, 0x00, 0xE0, 0x07, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x0D, 0x00, 0xFE, 0x00, 0x80, 0xC7, 0x03, 0xC0, 0x00, 0x06, 0x60, 0x3C, 0x0C, 0x30, 0xEE, 0x18, 0x10, 0x83, 0x18, 0x10, 0x81, 0x10, 0x10, 0xC1, 0x10, 0x30, 0x71, 0x10, 0x20, 0x7F, 0x18, 0x60, 0x80, 0x08, 0xC0, 0xE3, 0x00, 0x00, 0x3F, 0x00, // Code for char @ - 0x0D, 0x00, 0x00, 0x04, 0x00, 0x80, 0x07, 0x00, 0xF0, 0x03, 0x00, 0x7E, 0x00, 0x80, 0x6F, 0x00, 0xF0, 0x61, 0x00, 0x30, 0x60, 0x00, 0xF0, 0x61, 0x00, 0x80, 0x6F, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x00, 0x04, // Code for char A - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x1E, 0x03, 0xE0, 0xFB, 0x03, 0xC0, 0xF1, 0x01, 0x00, 0x00, 0x00, // Code for char B - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0xFF, 0x01, 0xE0, 0xC1, 0x03, 0x60, 0x00, 0x03, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, // Code for char C - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x60, 0x00, 0x03, 0xE0, 0xC1, 0x01, 0xC0, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, // Code for char D - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x00, 0x00, 0x00, // Code for char E - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x30, 0x0C, 0x00, 0x30, 0x0C, 0x00, 0x30, 0x0C, 0x00, 0x30, 0x0C, 0x00, 0x30, 0x0C, 0x00, 0x30, 0x0C, 0x00, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0xFF, 0x01, 0xE0, 0x81, 0x03, 0x60, 0x00, 0x03, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0xFC, 0x07, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, // Code for char G - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x00, 0x00, 0x00, // Code for char H - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x00, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1B, 0x00, 0x80, 0x71, 0x00, 0xC0, 0xC0, 0x00, 0x60, 0x80, 0x03, 0x30, 0x00, 0x07, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, // Code for char K - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, // Code for char L - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0xE0, 0x01, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x07, 0x00, 0xF0, 0x03, 0x00, 0x1E, 0x00, 0xE0, 0x01, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x00, 0x00, 0x00, // Code for char M - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0xE0, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x80, 0x03, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x00, 0x00, 0x00, // Code for char N - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0xFF, 0x01, 0xE0, 0x80, 0x03, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0xE0, 0x80, 0x03, 0xC0, 0xFF, 0x01, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, // Code for char O - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x30, 0x10, 0x00, 0x60, 0x18, 0x00, 0xE0, 0x0F, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char P - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0xFF, 0x01, 0xE0, 0x80, 0x03, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x1E, 0xE0, 0x80, 0x3B, 0xC0, 0xFF, 0x71, 0x00, 0x7F, 0x20, 0x00, 0x00, 0x00, // Code for char Q - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x30, 0x18, 0x00, 0x30, 0x18, 0x00, 0x30, 0x18, 0x00, 0x30, 0x38, 0x00, 0x30, 0x78, 0x00, 0x60, 0xEC, 0x01, 0xE0, 0x87, 0x03, 0xC0, 0x03, 0x07, 0x00, 0x00, 0x04, // Code for char R - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x06, 0xE0, 0x07, 0x06, 0x30, 0x0E, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x18, 0x06, 0x30, 0x18, 0x06, 0x30, 0xF0, 0x03, 0x20, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S - 0x0B, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0xF0, 0xFF, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, // Code for char U - 0x0D, 0x10, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x06, 0x00, 0xC0, 0x07, 0x00, 0xF8, 0x00, 0x00, 0x1F, 0x00, 0xE0, 0x07, 0x00, 0xF0, 0x00, 0x00, 0x10, 0x00, 0x00, // Code for char V - 0x0D, 0x70, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x06, 0x00, 0xE0, 0x03, 0x00, 0x3C, 0x00, 0x00, 0x02, 0x00, 0x00, 0x3C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x06, 0x00, 0xFC, 0x07, 0xF0, 0x3F, 0x00, 0x70, 0x00, 0x00, // Code for char W - 0x0C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x70, 0x00, 0x07, 0xE0, 0x80, 0x03, 0x80, 0xE3, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xE3, 0x01, 0xE0, 0x80, 0x03, 0x30, 0x00, 0x07, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, // Code for char X - 0x0C, 0x10, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x80, 0x03, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xF8, 0x07, 0x00, 0xFC, 0x07, 0x00, 0x0E, 0x00, 0x80, 0x03, 0x00, 0xE0, 0x00, 0x00, 0x70, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y - 0x0C, 0x00, 0x00, 0x00, 0x30, 0x00, 0x06, 0x30, 0x00, 0x07, 0x30, 0xC0, 0x07, 0x30, 0x60, 0x06, 0x30, 0x30, 0x06, 0x30, 0x1C, 0x06, 0x30, 0x06, 0x06, 0xB0, 0x03, 0x06, 0xF0, 0x01, 0x06, 0x70, 0x00, 0x06, 0x30, 0x00, 0x06, 0x00, 0x00, 0x00, // Code for char Z - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x3F, 0xF0, 0xFF, 0x3F, 0x30, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x80, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x30, 0xF0, 0xFF, 0x3F, 0xF0, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x07, 0x00, 0x80, 0x03, 0x00, 0xE0, 0x00, 0x00, 0x30, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, // Code for char ^ - 0x0D, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, // Code for char _ - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xE1, 0x03, 0x80, 0x21, 0x06, 0x80, 0x31, 0x06, 0x80, 0x31, 0x04, 0x80, 0x11, 0x06, 0x80, 0x11, 0x06, 0x80, 0x11, 0x03, 0x00, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x07, 0xF8, 0xFF, 0x03, 0x00, 0x03, 0x03, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x03, 0x03, 0x00, 0xFF, 0x03, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char b - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x03, 0x03, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x03, 0x03, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x00, 0x03, 0x03, 0xF8, 0xFF, 0x07, 0xF8, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x33, 0x03, 0x80, 0x31, 0x06, 0x80, 0x31, 0x06, 0x80, 0x31, 0x06, 0x80, 0x31, 0x06, 0x80, 0x31, 0x06, 0x00, 0x33, 0x06, 0x00, 0x3F, 0x06, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, // Code for char e - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF8, 0xFF, 0x07, 0x98, 0x00, 0x00, 0x98, 0x00, 0x00, 0x98, 0x00, 0x00, 0x98, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x1E, 0x7C, 0x00, 0xBF, 0xC7, 0x80, 0xE1, 0xC7, 0x80, 0x40, 0x86, 0x80, 0x40, 0x86, 0x80, 0x40, 0xC6, 0x80, 0x61, 0xC6, 0x80, 0x3F, 0x46, 0x80, 0x1E, 0x7E, 0x80, 0x00, 0x3C, 0x00, 0x00, 0x00, // Code for char g - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x07, 0xF8, 0xFF, 0x07, 0x00, 0x03, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x04, 0x80, 0x00, 0x04, 0x80, 0x00, 0x04, 0x98, 0xFF, 0x07, 0x98, 0xFF, 0x07, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x00, 0xC0, 0x80, 0x00, 0xC0, 0x80, 0x00, 0xC0, 0x80, 0x00, 0xC0, 0x80, 0x00, 0xC0, 0x98, 0xFF, 0x7F, 0x98, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x07, 0xF8, 0xFF, 0x07, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE6, 0x00, 0x00, 0x83, 0x01, 0x80, 0x01, 0x07, 0x80, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, // Code for char k - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x04, 0x08, 0x00, 0x04, 0x08, 0x00, 0x04, 0xF8, 0xFF, 0x07, 0xF8, 0xFF, 0x07, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l - 0x0B, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x80, 0xFF, 0x07, 0x00, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0xFF, 0x07, 0x00, 0xFE, 0x07, 0x00, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0xFF, 0x07, 0x00, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x80, 0xFF, 0x07, 0x00, 0x03, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x03, 0x03, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x00, 0x03, 0x03, 0x00, 0xFE, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char o - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x00, 0x03, 0x03, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x03, 0x03, 0x00, 0xFF, 0x03, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char p - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x03, 0x03, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x00, 0x03, 0x03, 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x80, 0xFF, 0x07, 0x00, 0x03, 0x00, 0x00, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x06, 0x00, 0x0F, 0x06, 0x80, 0x19, 0x06, 0x80, 0x11, 0x06, 0x80, 0x31, 0x06, 0x80, 0x31, 0x06, 0x80, 0x61, 0x06, 0x80, 0xE1, 0x03, 0x00, 0xC1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0xF0, 0xFF, 0x07, 0x80, 0x00, 0x06, 0x80, 0x00, 0x06, 0x80, 0x00, 0x06, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x80, 0xFF, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x80, 0xFF, 0x07, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x04, 0x00, 0xC0, 0x07, 0x00, 0xF0, 0x01, 0x00, 0x3E, 0x00, 0x80, 0x07, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v - 0x0D, 0x80, 0x01, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x06, 0x00, 0xF0, 0x03, 0x00, 0x3F, 0x00, 0x80, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x06, 0x00, 0xF8, 0x03, 0x80, 0x3F, 0x00, 0x80, 0x01, 0x00, // Code for char w - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x01, 0x06, 0x80, 0x03, 0x03, 0x00, 0xCE, 0x01, 0x00, 0x7C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xCE, 0x01, 0x80, 0x83, 0x03, 0x80, 0x01, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, // Code for char x - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0xC0, 0x80, 0x07, 0xC0, 0x00, 0x1E, 0xC0, 0x00, 0xF8, 0xC0, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x1E, 0x00, 0xC0, 0x07, 0x00, 0xF8, 0x00, 0x00, 0x3E, 0x00, 0x80, 0x07, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x06, 0x80, 0x00, 0x07, 0x80, 0xC0, 0x05, 0x80, 0xE0, 0x04, 0x80, 0x30, 0x04, 0x80, 0x18, 0x04, 0x80, 0x0E, 0x04, 0x80, 0x03, 0x04, 0x80, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0xE0, 0xEF, 0x1F, 0xE0, 0xCF, 0x1F, 0x30, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x30, 0xE0, 0xCF, 0x1F, 0xE0, 0xEF, 0x1F, 0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ - 0x04, 0xC0, 0xFF, 0x03, 0x40, 0x00, 0x02, 0x40, 0x00, 0x02, 0xC0, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char †- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x7F, 0x80, 0xF3, 0x7F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x80, 0x7F, 0x00, 0x80, 0xC1, 0x00, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0xF0, 0x80, 0x07, 0xF0, 0x80, 0x07, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¢ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x08, 0x06, 0xC0, 0xFF, 0x07, 0xE0, 0xFF, 0x06, 0x30, 0x08, 0x06, 0x30, 0x08, 0x06, 0x30, 0x08, 0x06, 0x30, 0x08, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, // Code for char £ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xC3, 0x00, 0x00, 0xC3, 0x00, 0x00, 0xC3, 0x00, 0x00, 0xC3, 0x00, 0x00, 0xFF, 0x00, 0x80, 0xFF, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¤ - 0x0B, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xF0, 0x90, 0x00, 0xE0, 0x93, 0x00, 0x00, 0x9F, 0x00, 0x00, 0xF8, 0x07, 0x00, 0xF8, 0x07, 0x00, 0x9F, 0x00, 0xE0, 0x93, 0x00, 0x70, 0x90, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¥ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x06, 0xF8, 0x1F, 0x06, 0x98, 0x31, 0x04, 0x88, 0x21, 0x04, 0x18, 0x63, 0x06, 0x18, 0xFF, 0x03, 0x10, 0xDE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char § - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ - 0x0D, 0x00, 0x7F, 0x00, 0xC0, 0xC1, 0x01, 0x60, 0x00, 0x03, 0x20, 0x3E, 0x02, 0x10, 0x7F, 0x04, 0x90, 0xC1, 0x04, 0x90, 0x80, 0x04, 0x90, 0x80, 0x04, 0x90, 0xC1, 0x04, 0x20, 0x00, 0x02, 0x60, 0x00, 0x03, 0xC0, 0xC1, 0x01, 0x00, 0x7F, 0x00, // Code for char © - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x90, 0x07, 0x00, 0x90, 0x04, 0x00, 0x90, 0x04, 0x00, 0xF0, 0x03, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char « - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¬ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ - 0x0D, 0x00, 0x7F, 0x00, 0xC0, 0xC1, 0x01, 0x60, 0x00, 0x03, 0x20, 0x00, 0x02, 0x90, 0xFF, 0x04, 0x90, 0xFF, 0x04, 0x90, 0x08, 0x04, 0x90, 0x1C, 0x04, 0x90, 0x77, 0x04, 0x20, 0xC7, 0x02, 0x60, 0x80, 0x03, 0xC0, 0xC1, 0x01, 0x00, 0x7F, 0x00, // Code for char ® - 0x0D, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, // Code for char ¯ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xE0, 0x03, 0x00, 0x30, 0x06, 0x00, 0x10, 0x04, 0x00, 0x30, 0x06, 0x00, 0xE0, 0x03, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x80, 0xFF, 0x06, 0x80, 0xFF, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ± - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x0E, 0x00, 0x10, 0x0B, 0x00, 0xF0, 0x09, 0x00, 0xE0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x90, 0x08, 0x00, 0x90, 0x08, 0x00, 0x70, 0x0F, 0x00, 0x60, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x38, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x80, 0xFF, 0x07, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char µ - 0x0B, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0xF0, 0x1F, 0x00, 0xF8, 0x3F, 0x00, 0xF8, 0x3F, 0x00, 0xF8, 0x3F, 0x00, 0xF8, 0xFF, 0x3F, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0xF8, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¶ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x98, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0xF0, 0x03, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, 0xE0, 0x03, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x00, 0x8C, 0x01, 0x00, 0xF8, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x00, 0x8C, 0x01, 0x00, 0xF8, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char » - 0x0C, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0xF0, 0x0F, 0x04, 0xF0, 0x0F, 0x07, 0x00, 0xC0, 0x01, 0x00, 0x70, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x87, 0x01, 0xC0, 0xC1, 0x01, 0x70, 0x30, 0x01, 0x10, 0xF8, 0x07, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, // Code for char ¼ - 0x0C, 0x20, 0x00, 0x00, 0x30, 0x00, 0x04, 0xF0, 0x0F, 0x07, 0xF0, 0xCF, 0x01, 0x00, 0x70, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x07, 0x00, 0xC0, 0x01, 0x06, 0x70, 0x08, 0x07, 0x10, 0x88, 0x05, 0x00, 0xF8, 0x04, 0x00, 0x70, 0x04, 0x00, 0x00, 0x00, // Code for char ½ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x90, 0x08, 0x00, 0x90, 0x08, 0x06, 0x70, 0x8F, 0x03, 0x60, 0xE7, 0x00, 0x00, 0x38, 0x00, 0x00, 0x8E, 0x01, 0x80, 0xC3, 0x01, 0xE0, 0x30, 0x01, 0x30, 0xF8, 0x07, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, // Code for char ¾ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x3F, 0x00, 0x80, 0x61, 0x00, 0x80, 0x61, 0x80, 0xC3, 0x60, 0x80, 0x73, 0x60, 0x80, 0x13, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¿ - 0x0D, 0x00, 0x00, 0x04, 0x00, 0x80, 0x07, 0x00, 0xF0, 0x03, 0x00, 0x7E, 0x00, 0x81, 0x6F, 0x00, 0xF3, 0x61, 0x00, 0x37, 0x60, 0x00, 0xF4, 0x61, 0x00, 0x80, 0x6F, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x00, 0x04, // Code for char À - 0x0D, 0x00, 0x00, 0x04, 0x00, 0x80, 0x07, 0x00, 0xF0, 0x03, 0x00, 0x7E, 0x00, 0x80, 0x6F, 0x00, 0xF0, 0x61, 0x00, 0x34, 0x60, 0x00, 0xF7, 0x61, 0x00, 0x83, 0x6F, 0x00, 0x01, 0x7E, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x00, 0x04, // Code for char à - 0x0D, 0x00, 0x00, 0x04, 0x00, 0x80, 0x07, 0x00, 0xF0, 0x03, 0x04, 0x7E, 0x00, 0x86, 0x6F, 0x00, 0xF3, 0x61, 0x00, 0x31, 0x60, 0x00, 0xF3, 0x61, 0x00, 0x86, 0x6F, 0x00, 0x04, 0x7E, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x00, 0x04, // Code for char  - 0x0D, 0x00, 0x00, 0x04, 0x00, 0x80, 0x07, 0x00, 0xF0, 0x03, 0x06, 0x7E, 0x00, 0x83, 0x6F, 0x00, 0xF3, 0x61, 0x00, 0x33, 0x60, 0x00, 0xF6, 0x61, 0x00, 0x86, 0x6F, 0x00, 0x06, 0x7E, 0x00, 0x03, 0xF0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x00, 0x04, // Code for char à - 0x0D, 0x00, 0x00, 0x04, 0x00, 0x80, 0x07, 0x00, 0xF0, 0x03, 0x00, 0x7E, 0x00, 0x83, 0x6F, 0x00, 0xF3, 0x61, 0x00, 0x30, 0x60, 0x00, 0xF0, 0x61, 0x00, 0x83, 0x6F, 0x00, 0x03, 0x7E, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x00, 0x04, // Code for char Ä - 0x0D, 0x00, 0x00, 0x04, 0x00, 0x80, 0x07, 0x00, 0xF0, 0x03, 0x00, 0x7E, 0x00, 0x8E, 0x6F, 0x00, 0xF1, 0x61, 0x00, 0x31, 0x60, 0x00, 0xF1, 0x61, 0x00, 0x8E, 0x6F, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x00, 0x04, // Code for char Å - 0x0C, 0x00, 0x00, 0x07, 0x00, 0xF8, 0x07, 0xC0, 0x7F, 0x00, 0xF0, 0x33, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x00, 0x00, 0x00, // Code for char Æ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0xFF, 0x01, 0xE0, 0xC1, 0x03, 0x60, 0x00, 0x03, 0x30, 0x00, 0x86, 0x30, 0x00, 0x9E, 0x30, 0x00, 0xFE, 0x30, 0x00, 0x66, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, // Code for char Ç - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x31, 0x0C, 0x06, 0x33, 0x0C, 0x06, 0x37, 0x0C, 0x06, 0x34, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x00, 0x00, 0x00, // Code for char È - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x34, 0x0C, 0x06, 0x37, 0x0C, 0x06, 0x33, 0x0C, 0x06, 0x31, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x00, 0x00, 0x00, // Code for char É - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x34, 0x0C, 0x06, 0x36, 0x0C, 0x06, 0x33, 0x0C, 0x06, 0x31, 0x0C, 0x06, 0x33, 0x0C, 0x06, 0x36, 0x0C, 0x06, 0x34, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x00, 0x00, 0x00, // Code for char Ê - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x33, 0x0C, 0x06, 0x33, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x33, 0x0C, 0x06, 0x33, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x00, 0x00, 0x00, // Code for char Ë - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x31, 0x00, 0x06, 0x33, 0x00, 0x06, 0xF7, 0xFF, 0x07, 0xF4, 0xFF, 0x07, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ì - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0xF4, 0xFF, 0x07, 0xF7, 0xFF, 0x07, 0x33, 0x00, 0x06, 0x31, 0x00, 0x06, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x34, 0x00, 0x06, 0x36, 0x00, 0x06, 0xF3, 0xFF, 0x07, 0xF1, 0xFF, 0x07, 0x33, 0x00, 0x06, 0x36, 0x00, 0x06, 0x14, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Î - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x33, 0x00, 0x06, 0x33, 0x00, 0x06, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x33, 0x00, 0x06, 0x33, 0x00, 0x06, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0C, 0x00, 0x0C, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x0C, 0x06, 0x30, 0x00, 0x06, 0x60, 0x00, 0x03, 0xE0, 0xC1, 0x01, 0xC0, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0xE6, 0x00, 0x00, 0x83, 0x03, 0x00, 0x03, 0x07, 0x00, 0x03, 0x1C, 0x00, 0x06, 0x70, 0x00, 0x06, 0xE0, 0x00, 0x06, 0x80, 0x03, 0xF3, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x00, 0x00, 0x00, // Code for char Ñ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0xFF, 0x01, 0xE0, 0x80, 0x03, 0x31, 0x00, 0x06, 0x33, 0x00, 0x06, 0x37, 0x00, 0x06, 0x34, 0x00, 0x06, 0x30, 0x00, 0x06, 0xE0, 0x80, 0x03, 0xC0, 0xFF, 0x01, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, // Code for char Ò - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0xFF, 0x01, 0xE0, 0x80, 0x03, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x34, 0x00, 0x06, 0x37, 0x00, 0x06, 0x33, 0x00, 0x06, 0xE1, 0x80, 0x03, 0xC0, 0xFF, 0x01, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, // Code for char Ó - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0xFF, 0x01, 0xE4, 0x80, 0x03, 0x36, 0x00, 0x06, 0x33, 0x00, 0x06, 0x31, 0x00, 0x06, 0x33, 0x00, 0x06, 0x36, 0x00, 0x06, 0xE4, 0x80, 0x03, 0xC0, 0xFF, 0x01, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, // Code for char Ô - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0xFF, 0x01, 0xE6, 0x80, 0x03, 0x33, 0x00, 0x06, 0x33, 0x00, 0x06, 0x33, 0x00, 0x06, 0x36, 0x00, 0x06, 0x36, 0x00, 0x06, 0xE6, 0x80, 0x03, 0xC3, 0xFF, 0x01, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, // Code for char Õ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0xFF, 0x01, 0xE0, 0x80, 0x03, 0x33, 0x00, 0x06, 0x33, 0x00, 0x06, 0x30, 0x00, 0x06, 0x30, 0x00, 0x06, 0x33, 0x00, 0x06, 0xE3, 0x80, 0x03, 0xC0, 0xFF, 0x01, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, // Code for char Ö - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x80, 0xC1, 0x00, 0x00, 0x23, 0x00, 0x00, 0x14, 0x00, 0x00, 0x08, 0x00, 0x00, 0x14, 0x00, 0x00, 0x22, 0x00, 0x80, 0x41, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char × - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x04, 0xC0, 0xFF, 0x07, 0xE0, 0x80, 0x03, 0x30, 0xC0, 0x06, 0x30, 0x30, 0x06, 0x30, 0x1C, 0x06, 0x30, 0x06, 0x06, 0xB0, 0x03, 0x06, 0xE0, 0x80, 0x03, 0xF0, 0xFF, 0x01, 0x10, 0x7F, 0x00, 0x00, 0x00, 0x00, // Code for char Ø - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0xF0, 0xFF, 0x03, 0x00, 0x00, 0x03, 0x01, 0x00, 0x06, 0x03, 0x00, 0x06, 0x07, 0x00, 0x06, 0x04, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, // Code for char Ù - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0xF0, 0xFF, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x04, 0x00, 0x06, 0x07, 0x00, 0x06, 0x03, 0x00, 0x06, 0x01, 0x00, 0x03, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, // Code for char Ú - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0xF0, 0xFF, 0x03, 0x04, 0x00, 0x03, 0x06, 0x00, 0x06, 0x03, 0x00, 0x06, 0x01, 0x00, 0x06, 0x03, 0x00, 0x06, 0x06, 0x00, 0x06, 0x04, 0x00, 0x03, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, // Code for char Û - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0xF0, 0xFF, 0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x06, 0x03, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x03, 0x00, 0x06, 0x03, 0x00, 0x03, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, // Code for char Ü - 0x0C, 0x10, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x80, 0x03, 0x00, 0x00, 0x0E, 0x00, 0x04, 0xF8, 0x07, 0x07, 0xFC, 0x07, 0x03, 0x0E, 0x00, 0x81, 0x03, 0x00, 0xE0, 0x00, 0x00, 0x70, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x80, 0xC1, 0x00, 0x80, 0xC1, 0x00, 0x80, 0xC1, 0x00, 0x80, 0xC1, 0x00, 0x80, 0xC1, 0x00, 0x80, 0x63, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, // Code for char Þ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x07, 0xF0, 0xFF, 0x07, 0x18, 0x00, 0x00, 0x18, 0x00, 0x06, 0x18, 0x0E, 0x06, 0x18, 0x1F, 0x06, 0x98, 0x19, 0x06, 0xF0, 0x31, 0x06, 0xF0, 0xE0, 0x03, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, // Code for char ß - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xE1, 0x03, 0x80, 0x21, 0x06, 0x88, 0x31, 0x06, 0x98, 0x31, 0x04, 0xB8, 0x11, 0x06, 0xA0, 0x11, 0x06, 0x80, 0x11, 0x03, 0x00, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xE1, 0x03, 0x80, 0x21, 0x06, 0x80, 0x31, 0x06, 0xA0, 0x31, 0x04, 0xB8, 0x11, 0x06, 0x98, 0x11, 0x06, 0x88, 0x11, 0x03, 0x00, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char á - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xE1, 0x03, 0xA0, 0x21, 0x06, 0xB0, 0x31, 0x06, 0x98, 0x31, 0x04, 0x88, 0x11, 0x06, 0x98, 0x11, 0x06, 0xB0, 0x11, 0x03, 0x20, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char â - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xE1, 0x03, 0xB0, 0x21, 0x06, 0x98, 0x31, 0x06, 0x98, 0x31, 0x04, 0x98, 0x11, 0x06, 0xB0, 0x11, 0x06, 0xB0, 0x11, 0x03, 0x30, 0xFF, 0x03, 0x18, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ã - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xE1, 0x03, 0x80, 0x21, 0x06, 0x98, 0x31, 0x06, 0x98, 0x31, 0x04, 0x80, 0x11, 0x06, 0x80, 0x11, 0x06, 0x98, 0x11, 0x03, 0x18, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ä - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xE1, 0x03, 0x80, 0x21, 0x06, 0x9C, 0x31, 0x06, 0xA2, 0x31, 0x04, 0xA2, 0x11, 0x06, 0xA2, 0x11, 0x06, 0x9C, 0x11, 0x03, 0x00, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char å - 0x0D, 0x00, 0xC0, 0x03, 0x00, 0xE1, 0x07, 0x80, 0x31, 0x06, 0x80, 0x11, 0x06, 0x80, 0x11, 0x02, 0x00, 0xFF, 0x01, 0x00, 0xFF, 0x03, 0x80, 0x33, 0x03, 0x80, 0x31, 0x06, 0x80, 0x31, 0x06, 0x80, 0x31, 0x06, 0x00, 0x3F, 0x06, 0x00, 0x3E, 0x02, // Code for char æ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x03, 0x03, 0x80, 0x01, 0x86, 0x80, 0x01, 0x9E, 0x80, 0x01, 0xFE, 0x80, 0x01, 0x66, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ç - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x33, 0x03, 0x88, 0x31, 0x06, 0x98, 0x31, 0x06, 0xB8, 0x31, 0x06, 0xA0, 0x31, 0x06, 0x80, 0x31, 0x06, 0x00, 0x33, 0x06, 0x00, 0x3F, 0x06, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, // Code for char è - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x33, 0x03, 0x80, 0x31, 0x06, 0x80, 0x31, 0x06, 0xA0, 0x31, 0x06, 0xB8, 0x31, 0x06, 0x98, 0x31, 0x06, 0x08, 0x33, 0x06, 0x00, 0x3F, 0x06, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, // Code for char é - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x01, 0x20, 0x33, 0x03, 0xB0, 0x31, 0x06, 0x98, 0x31, 0x06, 0x88, 0x31, 0x06, 0x98, 0x31, 0x06, 0xB0, 0x31, 0x06, 0x20, 0x33, 0x06, 0x00, 0x3F, 0x06, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, // Code for char ê - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x33, 0x03, 0x98, 0x31, 0x06, 0x98, 0x31, 0x06, 0x80, 0x31, 0x06, 0x80, 0x31, 0x06, 0x98, 0x31, 0x06, 0x18, 0x33, 0x06, 0x00, 0x3F, 0x06, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, // Code for char ë - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x04, 0x88, 0x00, 0x04, 0x98, 0x00, 0x04, 0xB8, 0xFF, 0x07, 0xA0, 0xFF, 0x07, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ì - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x04, 0x80, 0x00, 0x04, 0x80, 0x00, 0x04, 0xA0, 0xFF, 0x07, 0xB8, 0xFF, 0x07, 0x18, 0x00, 0x04, 0x08, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char í - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x04, 0xA0, 0x00, 0x04, 0xB0, 0x00, 0x04, 0x98, 0xFF, 0x07, 0x88, 0xFF, 0x07, 0x18, 0x00, 0x04, 0x30, 0x00, 0x04, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char î - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x04, 0x98, 0x00, 0x04, 0x98, 0x00, 0x04, 0x80, 0xFF, 0x07, 0x80, 0xFF, 0x07, 0x18, 0x00, 0x04, 0x18, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ï - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x0C, 0x03, 0xD8, 0x06, 0x06, 0x50, 0x06, 0x06, 0x70, 0x06, 0x06, 0x70, 0x06, 0x06, 0xF0, 0x06, 0x06, 0xD8, 0x0D, 0x03, 0x10, 0xFF, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char ð - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0xB0, 0xFF, 0x07, 0x18, 0x03, 0x00, 0x98, 0x01, 0x00, 0x98, 0x01, 0x00, 0xB0, 0x01, 0x00, 0xB0, 0x01, 0x00, 0x30, 0xFF, 0x07, 0x18, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ñ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x03, 0x03, 0x88, 0x01, 0x06, 0x98, 0x01, 0x06, 0xB8, 0x01, 0x06, 0xA0, 0x01, 0x06, 0x80, 0x01, 0x06, 0x00, 0x03, 0x03, 0x00, 0xFE, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char ò - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x03, 0x03, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0xA0, 0x01, 0x06, 0xB8, 0x01, 0x06, 0x98, 0x01, 0x06, 0x08, 0x03, 0x03, 0x00, 0xFE, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char ó - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x01, 0x20, 0x03, 0x03, 0xB0, 0x01, 0x06, 0x98, 0x01, 0x06, 0x88, 0x01, 0x06, 0x98, 0x01, 0x06, 0xB0, 0x01, 0x06, 0x20, 0x03, 0x03, 0x00, 0xFE, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char ô - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x01, 0x30, 0x03, 0x03, 0x98, 0x01, 0x06, 0x98, 0x01, 0x06, 0x98, 0x01, 0x06, 0xB0, 0x01, 0x06, 0xB0, 0x01, 0x06, 0x30, 0x03, 0x03, 0x18, 0xFE, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char õ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x03, 0x03, 0x98, 0x01, 0x06, 0x98, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x98, 0x01, 0x06, 0x18, 0x03, 0x03, 0x00, 0xFE, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char ö - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x80, 0x99, 0x01, 0x80, 0x99, 0x01, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ÷ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x03, 0x07, 0x80, 0x81, 0x07, 0x80, 0xE1, 0x06, 0x80, 0x31, 0x06, 0x80, 0x1D, 0x06, 0x80, 0x0F, 0x06, 0x80, 0x03, 0x03, 0x80, 0xFF, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char ø - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x80, 0xFF, 0x03, 0x08, 0x00, 0x06, 0x18, 0x00, 0x06, 0x38, 0x00, 0x06, 0x20, 0x00, 0x06, 0x00, 0x00, 0x03, 0x80, 0xFF, 0x07, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ù - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x80, 0xFF, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x20, 0x00, 0x06, 0x38, 0x00, 0x06, 0x18, 0x00, 0x03, 0x88, 0xFF, 0x07, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ú - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x01, 0xA0, 0xFF, 0x03, 0x30, 0x00, 0x06, 0x18, 0x00, 0x06, 0x08, 0x00, 0x06, 0x18, 0x00, 0x06, 0x30, 0x00, 0x03, 0xA0, 0xFF, 0x07, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char û - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x80, 0xFF, 0x03, 0x18, 0x00, 0x06, 0x18, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x18, 0x00, 0x03, 0x98, 0xFF, 0x07, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ü - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0xC0, 0x80, 0x07, 0xC0, 0x00, 0x1E, 0xC0, 0x00, 0xF8, 0xC0, 0x00, 0xC0, 0x7F, 0x20, 0x00, 0x1E, 0x38, 0xC0, 0x07, 0x18, 0xF8, 0x00, 0x08, 0x3E, 0x00, 0x80, 0x07, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ý - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x00, 0x03, 0x03, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x03, 0x03, 0x00, 0xFF, 0x03, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char þ - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0xC0, 0x80, 0x07, 0xC0, 0x00, 0x1E, 0xC0, 0x18, 0xF8, 0xC0, 0x18, 0xC0, 0x7F, 0x00, 0x00, 0x1E, 0x00, 0xC0, 0x07, 0x18, 0xF8, 0x00, 0x18, 0x3E, 0x00, 0x80, 0x07, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ -}; - -const struct GDS_FontDef Font_droid_sans_mono_13x24 = { - Droid_Sans_Mono13x24, - 13, - 24, - ' ', - '\xFF', - true -}; diff --git a/components/display/fonts/font_droid_sans_mono_16x31.c b/components/display/fonts/font_droid_sans_mono_16x31.c deleted file mode 100644 index f58ec5e8..00000000 --- a/components/display/fonts/font_droid_sans_mono_16x31.c +++ /dev/null @@ -1,247 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Droid_Sans_Mono16x31 -//GLCD FontSize : 16 x 31 - -static const uint8_t Droid_Sans_Mono16x31[ ] = { - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0xC0, 0x01, 0xC0, 0xFF, 0xE7, 0x01, 0xC0, 0xFF, 0xE7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x0C, 0x00, 0x00, 0x30, 0xCC, 0x01, 0x00, 0x30, 0xFF, 0x01, 0x00, 0xFE, 0x1F, 0x00, 0xC0, 0x7F, 0x0C, 0x00, 0xC0, 0x31, 0x0C, 0x00, 0x00, 0x30, 0x0C, 0x00, 0x00, 0x30, 0xCC, 0x01, 0x00, 0x30, 0xFF, 0x01, 0x00, 0xFC, 0x3F, 0x00, 0xC0, 0xFF, 0x0C, 0x00, 0xC0, 0x31, 0x0C, 0x00, 0x00, 0x30, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, // Code for char # - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x60, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x73, 0xC0, 0x00, 0x80, 0xE1, 0xC0, 0x00, 0x80, 0xC1, 0xC0, 0x00, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, 0x80, 0x81, 0xC1, 0x00, 0x80, 0x81, 0x73, 0x00, 0x80, 0x03, 0x7F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ - 0x10, 0x00, 0x1F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xC0, 0x60, 0x00, 0x01, 0xC0, 0x60, 0xC0, 0x01, 0xC0, 0x60, 0xF0, 0x00, 0xC0, 0x60, 0x3C, 0x00, 0x80, 0x3F, 0x0F, 0x00, 0x00, 0xDF, 0x03, 0x00, 0x00, 0xE0, 0x7D, 0x00, 0x00, 0x78, 0xFE, 0x00, 0x00, 0x1E, 0x83, 0x01, 0x80, 0x07, 0x83, 0x01, 0xC0, 0x01, 0x83, 0x01, 0x40, 0x00, 0x83, 0x01, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x7C, 0x00, // Code for char % - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x80, 0xBF, 0xC1, 0x01, 0xC0, 0xF9, 0x81, 0x01, 0xC0, 0xE0, 0x81, 0x01, 0xC0, 0xE0, 0x83, 0x01, 0xC0, 0xF0, 0xC7, 0x01, 0xC0, 0x39, 0xCE, 0x00, 0x80, 0x1F, 0xFC, 0x00, 0x00, 0x0F, 0x78, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xDF, 0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x00, 0x01, // Code for char & - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0xFE, 0xFD, 0x03, 0x00, 0x0F, 0x80, 0x07, 0x80, 0x03, 0x00, 0x0E, 0xC0, 0x01, 0x00, 0x1C, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x10, 0xC0, 0x01, 0x00, 0x1C, 0x80, 0x03, 0x00, 0x0E, 0x00, 0x0F, 0x80, 0x07, 0x00, 0xFE, 0xFD, 0x03, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0xE3, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x70, 0x3E, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF0, 0x1E, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00, 0xE2, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x80, 0x3F, 0xFE, 0x00, 0x80, 0x01, 0xC0, 0x00, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x3F, 0xFE, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x01, 0x80, 0x03, 0xE0, 0x01, 0x80, 0x01, 0xF0, 0x01, 0xC0, 0x01, 0xB8, 0x01, 0xC0, 0x00, 0x9C, 0x01, 0xC0, 0x00, 0x8E, 0x01, 0xC0, 0x00, 0x87, 0x01, 0xC0, 0xC1, 0x83, 0x01, 0x80, 0xF3, 0x81, 0x01, 0x80, 0x7F, 0x80, 0x01, 0x00, 0x3E, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xE1, 0x80, 0x01, 0x80, 0xBB, 0xC1, 0x00, 0x80, 0x3F, 0xF7, 0x00, 0x00, 0x1F, 0x7F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xC0, 0x19, 0x00, 0x00, 0xF0, 0x18, 0x00, 0x00, 0x38, 0x18, 0x00, 0x00, 0x1E, 0x18, 0x00, 0x00, 0x07, 0x18, 0x00, 0xC0, 0x01, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xC0, 0x00, 0xC0, 0x7F, 0xC0, 0x01, 0xC0, 0x67, 0x80, 0x01, 0xC0, 0x60, 0x80, 0x01, 0xC0, 0x60, 0x80, 0x01, 0xC0, 0x60, 0x80, 0x01, 0xC0, 0x60, 0x80, 0x01, 0xC0, 0xE0, 0x80, 0x01, 0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 0xF3, 0x00, 0xC0, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0xFF, 0xFB, 0x00, 0x80, 0xC7, 0xC0, 0x00, 0x80, 0x61, 0x80, 0x01, 0xC0, 0x61, 0x80, 0x01, 0xC0, 0x60, 0x80, 0x01, 0xC0, 0x60, 0x80, 0x01, 0xC0, 0xE0, 0xC0, 0x01, 0xC0, 0xC0, 0xF1, 0x00, 0xC0, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x01, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x00, 0xF8, 0x01, 0xC0, 0x00, 0x7E, 0x00, 0xC0, 0x80, 0x1F, 0x00, 0xC0, 0xE0, 0x03, 0x00, 0xC0, 0xF8, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x1F, 0xFE, 0x00, 0x80, 0x3F, 0xE7, 0x00, 0xC0, 0xF3, 0xC1, 0x01, 0xC0, 0xE0, 0x81, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xE0, 0x81, 0x01, 0xC0, 0xF3, 0xC1, 0x01, 0x80, 0x3F, 0xE7, 0x00, 0x00, 0x1F, 0x7E, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0xFF, 0x81, 0x01, 0x80, 0xC7, 0x81, 0x01, 0xC0, 0x81, 0x83, 0x01, 0xC0, 0x00, 0x83, 0x01, 0xC0, 0x00, 0x83, 0x01, 0xC0, 0x00, 0xC3, 0x01, 0xC0, 0x00, 0xC3, 0x00, 0x80, 0x81, 0xF1, 0x00, 0x80, 0xEF, 0x7F, 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xE0, 0x01, 0x00, 0x78, 0xE0, 0x01, 0x00, 0x78, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x78, 0xC0, 0x1F, 0x00, 0x78, 0xC0, 0x07, 0x00, 0x78, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x60, 0x03, 0x00, 0x00, 0x60, 0x03, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x60, 0x03, 0x00, 0x00, 0x60, 0x03, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x00, 0xE7, 0x01, 0xC0, 0x80, 0xC7, 0x01, 0xC0, 0xC0, 0x01, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0x61, 0x00, 0x00, 0x80, 0x7B, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x10, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x0E, 0xE0, 0x01, 0x00, 0x03, 0x80, 0x01, 0x80, 0xC1, 0x0F, 0x03, 0x80, 0xF0, 0x1F, 0x06, 0xC0, 0x70, 0x38, 0x06, 0xC0, 0x18, 0x30, 0x06, 0xC0, 0x18, 0x30, 0x06, 0xC0, 0x18, 0x18, 0x06, 0xC0, 0xF8, 0x0F, 0x06, 0x80, 0xF9, 0x1F, 0x06, 0x80, 0x03, 0x30, 0x02, 0x00, 0x07, 0x30, 0x03, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0xF0, 0x07, 0x00, // Code for char @ - 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xFE, 0x06, 0x00, 0x80, 0x1F, 0x06, 0x00, 0xC0, 0x03, 0x06, 0x00, 0xC0, 0x03, 0x06, 0x00, 0x80, 0x1F, 0x06, 0x00, 0x00, 0xFE, 0x06, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x01, // Code for char A - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xE1, 0x80, 0x01, 0x80, 0xFF, 0xC1, 0x01, 0x80, 0x3F, 0xFF, 0x00, 0x00, 0x1F, 0x7F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x80, 0x07, 0xF0, 0x00, 0x80, 0x03, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x01, 0x80, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x80, 0x03, 0xE0, 0x00, 0x80, 0x07, 0x70, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x80, 0x07, 0xE0, 0x00, 0x80, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x80, 0x81, 0x01, 0xC0, 0x80, 0x81, 0x01, 0xC0, 0x81, 0xC1, 0x01, 0x80, 0x81, 0xFF, 0x01, 0x80, 0x80, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xB8, 0x07, 0x00, 0x00, 0x1E, 0x1E, 0x00, 0x00, 0x07, 0x3C, 0x00, 0x80, 0x03, 0xF8, 0x00, 0xC0, 0x01, 0xE0, 0x01, 0xC0, 0x00, 0xC0, 0x01, 0x40, 0x00, 0x00, 0x01, // Code for char K - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0x07, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x80, 0x7F, 0x00, 0x00, 0xFC, 0x07, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char M - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xE0, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x80, 0x03, 0xE0, 0x00, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0x80, 0x03, 0xE0, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x03, 0x00, 0xC0, 0x01, 0x03, 0x00, 0xC0, 0x81, 0x01, 0x00, 0x80, 0xFF, 0x01, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x80, 0x03, 0xE0, 0x00, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x03, 0xC0, 0x01, 0xC0, 0x07, 0x80, 0x03, 0xE0, 0x0E, 0x00, 0xFF, 0x7F, 0x1C, 0x00, 0xFE, 0x3F, 0x38, 0x00, 0xF8, 0x0F, 0x10, 0x00, 0x00, 0x00, 0x00, // Code for char Q - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x07, 0x00, 0xC0, 0x80, 0x0F, 0x00, 0xC0, 0xC1, 0x3E, 0x00, 0x80, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xE0, 0x01, 0x00, 0x3E, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char R - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xC0, 0x00, 0x80, 0x3F, 0xC0, 0x01, 0x80, 0x7B, 0x80, 0x01, 0xC0, 0xE1, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x81, 0x01, 0xC0, 0x80, 0x81, 0x01, 0xC0, 0x80, 0xC3, 0x01, 0xC0, 0x01, 0xE7, 0x00, 0x80, 0x01, 0x7F, 0x00, 0x80, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xF8, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U - 0x10, 0x40, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char V - 0x10, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xFF, 0x01, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xFC, 0x01, 0x00, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0x00, 0xC0, 0x03, 0x00, 0x00, // Code for char W - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x03, 0xE0, 0x01, 0x00, 0x0F, 0x78, 0x00, 0x00, 0x3E, 0x1E, 0x00, 0x00, 0x78, 0x0F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x78, 0x0F, 0x00, 0x00, 0x1E, 0x3E, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0xC0, 0x03, 0xE0, 0x01, 0xC0, 0x00, 0xC0, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char X - 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x00, 0x80, 0xFF, 0x01, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char Y - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x00, 0xE0, 0x01, 0xC0, 0x00, 0xF0, 0x01, 0xC0, 0x00, 0xBC, 0x01, 0xC0, 0x00, 0x9E, 0x01, 0xC0, 0x00, 0x87, 0x01, 0xC0, 0xC0, 0x83, 0x01, 0xC0, 0xE0, 0x81, 0x01, 0xC0, 0x70, 0x80, 0x01, 0xC0, 0x3C, 0x80, 0x01, 0xC0, 0x1E, 0x80, 0x01, 0xC0, 0x07, 0x80, 0x01, 0xC0, 0x03, 0x80, 0x01, 0xC0, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char Z - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x1F, 0xC0, 0xFF, 0xFF, 0x1F, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0xFF, 0xFF, 0x1F, 0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ - 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, // Code for char _ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x10, 0xFC, 0x00, 0x00, 0x30, 0xFC, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x18, 0xC6, 0x00, 0x00, 0x78, 0x66, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0x00, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0xFF, 0x01, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x38, 0xC0, 0x01, 0x00, 0xF0, 0xF9, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xFB, 0x00, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x38, 0xC0, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x38, 0x80, 0x01, 0x00, 0x10, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xF9, 0x00, 0x00, 0x38, 0xC0, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x30, 0xC0, 0x00, 0x00, 0xE0, 0x70, 0x00, 0xF0, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x30, 0xC6, 0x00, 0x00, 0x18, 0x86, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x38, 0x86, 0x01, 0x00, 0xF0, 0x86, 0x01, 0x00, 0xE0, 0xC7, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xE0, 0xFF, 0xFF, 0x01, 0xF0, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0x03, 0x3E, 0x00, 0xF0, 0xE7, 0x33, 0x00, 0x30, 0xFE, 0x61, 0x00, 0x18, 0x9C, 0x61, 0x00, 0x18, 0x8C, 0x61, 0x00, 0x18, 0x8C, 0x61, 0x00, 0x18, 0x8C, 0x61, 0x00, 0x18, 0x8C, 0x61, 0x00, 0x38, 0x86, 0x61, 0x00, 0xF8, 0x87, 0x71, 0x00, 0xF8, 0x83, 0x33, 0x00, 0x18, 0x00, 0x3F, 0x00, 0x18, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, // Code for char g - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0xFF, 0x01, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0x00, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x70, 0xF8, 0xFF, 0x01, 0x70, 0xF8, 0xFF, 0x01, 0x20, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x18, 0x00, 0x60, 0x00, 0x18, 0x00, 0x60, 0x00, 0x18, 0x00, 0x60, 0x00, 0x18, 0x00, 0x60, 0x00, 0x18, 0x00, 0x60, 0x70, 0x18, 0x00, 0x38, 0x70, 0xF8, 0xFF, 0x3F, 0x70, 0xF8, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xC0, 0x3C, 0x00, 0x00, 0x60, 0x78, 0x00, 0x00, 0x30, 0xE0, 0x00, 0x00, 0x18, 0xC0, 0x01, 0x00, 0x08, 0x80, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char k - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x30, 0x00, 0x80, 0x01, 0x30, 0x00, 0x80, 0x01, 0x30, 0x00, 0x80, 0x01, 0x30, 0x00, 0x80, 0x01, 0xF0, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xF0, 0xFF, 0x01, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char m - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0x00, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xF9, 0x00, 0x00, 0x38, 0xC0, 0x00, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x30, 0xC0, 0x00, 0x00, 0xF0, 0xF9, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x7F, 0x00, 0xF8, 0xFF, 0x7F, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x38, 0xC0, 0x01, 0x00, 0xF0, 0xF9, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xF9, 0x00, 0x00, 0x38, 0xC0, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x30, 0xC0, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0xF8, 0xFF, 0x7F, 0x00, 0xF8, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00, 0x00, 0xF0, 0x81, 0x01, 0x00, 0xB8, 0x83, 0x01, 0x00, 0x18, 0x83, 0x01, 0x00, 0x18, 0x87, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x18, 0x8E, 0x01, 0x00, 0x18, 0xCC, 0x01, 0x00, 0x38, 0xFC, 0x00, 0x00, 0x10, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x18, 0xE0, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x7F, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v - 0x10, 0x00, 0x38, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x38, 0x00, 0x00, // Code for char w - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x38, 0xC0, 0x01, 0x00, 0x70, 0xE0, 0x00, 0x00, 0xE0, 0x78, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xE0, 0x78, 0x00, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x38, 0xC0, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char x - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x00, 0x78, 0x00, 0x60, 0x00, 0xF8, 0x01, 0x60, 0x00, 0xE0, 0x07, 0x60, 0x00, 0x00, 0x3F, 0x70, 0x00, 0x00, 0xFC, 0x3C, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0xC0, 0x01, 0x00, 0x18, 0xE0, 0x01, 0x00, 0x18, 0xB8, 0x01, 0x00, 0x18, 0x9C, 0x01, 0x00, 0x18, 0x8E, 0x01, 0x00, 0x18, 0x87, 0x01, 0x00, 0x98, 0x83, 0x01, 0x00, 0xD8, 0x81, 0x01, 0x00, 0xF8, 0x80, 0x01, 0x00, 0x78, 0x80, 0x01, 0x00, 0x38, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0x80, 0xFF, 0xFC, 0x0F, 0xC0, 0x01, 0x00, 0x0C, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x00, 0x00, 0x18, 0xC0, 0x01, 0x00, 0x0C, 0x80, 0xFF, 0xFC, 0x0F, 0x00, 0xFF, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ - 0x07, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x03, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0xC0, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char †- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3F, 0x00, 0x78, 0xFE, 0x3F, 0x00, 0x78, 0xFC, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x3E, 0x1F, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 0x03, 0x30, 0x00, 0xC0, 0x03, 0xF0, 0x01, 0xC0, 0x03, 0xF0, 0x01, 0x00, 0x03, 0x30, 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x03, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¢ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x01, 0x00, 0x80, 0xC1, 0x01, 0x00, 0xFF, 0xFF, 0x01, 0x80, 0xFF, 0xBF, 0x01, 0x80, 0x83, 0x81, 0x01, 0xC0, 0x80, 0x81, 0x01, 0xC0, 0x80, 0x81, 0x01, 0xC0, 0x80, 0x81, 0x01, 0xC0, 0x80, 0x81, 0x01, 0xC0, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char £ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0xEE, 0x1D, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xEE, 0x1D, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¤ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xC0, 0x07, 0x33, 0x00, 0x00, 0x1F, 0x33, 0x00, 0x00, 0x7C, 0x33, 0x00, 0x00, 0xF0, 0x33, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x00, 0x80, 0xFF, 0x01, 0x00, 0xE0, 0x33, 0x00, 0x00, 0x7C, 0x33, 0x00, 0x00, 0x1F, 0x33, 0x00, 0xC0, 0x07, 0x33, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¥ - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0xE0, 0x7F, 0xF0, 0x3F, 0xE0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF1, 0xC0, 0x00, 0xE0, 0xFB, 0x81, 0x01, 0x70, 0x8F, 0x83, 0x01, 0x30, 0x0E, 0x83, 0x01, 0x30, 0x0E, 0x87, 0x01, 0x30, 0x0C, 0x86, 0x01, 0x30, 0x1C, 0x8E, 0x01, 0x30, 0x18, 0xDF, 0x00, 0x70, 0xF8, 0xFF, 0x00, 0x20, 0xE0, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char § - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ - 0x10, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x3E, 0x3E, 0x00, 0x00, 0x07, 0x70, 0x00, 0x80, 0xE1, 0xC3, 0x00, 0x80, 0xF8, 0x8F, 0x00, 0xC0, 0x18, 0x8C, 0x01, 0xC0, 0x0C, 0x98, 0x01, 0x40, 0x0C, 0x18, 0x01, 0x40, 0x0C, 0x18, 0x01, 0xC0, 0x0C, 0x98, 0x01, 0xC0, 0x0C, 0x98, 0x01, 0x80, 0x00, 0x80, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x00, 0x07, 0x70, 0x00, 0x00, 0x3E, 0x3E, 0x00, 0x00, 0xF0, 0x07, 0x00, // Code for char © - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0xC0, 0x3C, 0x00, 0x00, 0xC0, 0x36, 0x00, 0x00, 0xC0, 0x32, 0x00, 0x00, 0xC0, 0x32, 0x00, 0x00, 0xC0, 0x12, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xC0, 0x1D, 0x00, 0x00, 0xE0, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x20, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x1D, 0x00, 0x00, 0xE0, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char « - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¬ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ - 0x10, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x3E, 0x3E, 0x00, 0x00, 0x07, 0x70, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x00, 0x80, 0x00, 0xC0, 0xFC, 0x9F, 0x01, 0xC0, 0xFC, 0x9F, 0x01, 0x40, 0x8C, 0x01, 0x01, 0x40, 0x8C, 0x03, 0x01, 0xC0, 0x8C, 0x87, 0x01, 0xC0, 0xF8, 0x9E, 0x01, 0x80, 0x78, 0x98, 0x00, 0x80, 0x01, 0xD0, 0x00, 0x00, 0x07, 0x70, 0x00, 0x00, 0x3E, 0x3E, 0x00, 0x00, 0xF0, 0x07, 0x00, // Code for char ® - 0x10, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, // Code for char ¯ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xC0, 0x30, 0x00, 0x00, 0xC0, 0x30, 0x00, 0x00, 0xC0, 0x30, 0x00, 0x00, 0xC0, 0x30, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xFE, 0x9F, 0x01, 0x00, 0xFE, 0x9F, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0xC0, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ± - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x00, 0x00, 0xC0, 0xE0, 0x00, 0x00, 0xC0, 0xF0, 0x00, 0x00, 0xC0, 0xD8, 0x00, 0x00, 0xC0, 0xDC, 0x00, 0x00, 0xC0, 0xCF, 0x00, 0x00, 0x80, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC4, 0x00, 0x00, 0xC0, 0xC4, 0x00, 0x00, 0xC0, 0xCC, 0x00, 0x00, 0xC0, 0x7B, 0x00, 0x00, 0x80, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x7F, 0x00, 0xF8, 0xFF, 0x7F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char µ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0x00, 0xF0, 0xFF, 0x01, 0x00, 0xF0, 0xFF, 0x01, 0x00, 0xF0, 0xFF, 0x01, 0x00, 0xF0, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0x0F, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¶ - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xC0, 0x30, 0x00, 0x00, 0xC0, 0x30, 0x00, 0x00, 0xC0, 0x30, 0x00, 0x00, 0xC0, 0x30, 0x00, 0x00, 0xC0, 0x30, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0xE0, 0x38, 0x00, 0x00, 0xC0, 0x1D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x20, 0x22, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0xE0, 0x38, 0x00, 0x00, 0xC0, 0x1D, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char » - 0x10, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0x01, 0xC0, 0xFF, 0xC0, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xE0, 0x61, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, 0x1E, 0x6C, 0x00, 0x80, 0x07, 0x66, 0x00, 0xC0, 0x01, 0x63, 0x00, 0x40, 0x80, 0xFF, 0x01, 0x00, 0x80, 0xFF, 0x01, 0x00, 0x00, 0x60, 0x00, // Code for char ¼ - 0x10, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x01, 0xC0, 0xFF, 0xC0, 0x01, 0xC0, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x80, 0x07, 0x81, 0x01, 0xC0, 0x81, 0xC1, 0x01, 0x40, 0x80, 0xE1, 0x01, 0x00, 0x80, 0xB1, 0x01, 0x00, 0x80, 0xB9, 0x01, 0x00, 0x80, 0x9F, 0x01, // Code for char ½ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC4, 0x00, 0x01, 0xC0, 0xC4, 0xC0, 0x01, 0xC0, 0xCC, 0xF0, 0x00, 0xC0, 0x7B, 0x3C, 0x00, 0x80, 0x7B, 0x0F, 0x00, 0x00, 0xC0, 0x63, 0x00, 0x00, 0xE0, 0x79, 0x00, 0x00, 0x78, 0x6C, 0x00, 0x00, 0x1E, 0x66, 0x00, 0x80, 0x07, 0x63, 0x00, 0xC0, 0x81, 0xFF, 0x01, 0x40, 0x80, 0xFF, 0x01, 0x00, 0x00, 0x60, 0x00, // Code for char ¾ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xE0, 0x1D, 0x00, 0x00, 0x70, 0x38, 0x00, 0x00, 0x30, 0x30, 0x00, 0x38, 0x1E, 0x30, 0x00, 0x78, 0x0E, 0x30, 0x00, 0x38, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¿ - 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x01, 0xFE, 0x06, 0x00, 0x83, 0x1F, 0x06, 0x00, 0xC7, 0x03, 0x06, 0x00, 0xCE, 0x03, 0x06, 0x00, 0x88, 0x1F, 0x06, 0x00, 0x00, 0xFE, 0x06, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x01, // Code for char À - 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xFE, 0x06, 0x00, 0x80, 0x1F, 0x06, 0x00, 0xC8, 0x03, 0x06, 0x00, 0xCE, 0x03, 0x06, 0x00, 0x87, 0x1F, 0x06, 0x00, 0x03, 0xFE, 0x06, 0x00, 0x01, 0xF0, 0x07, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x01, // Code for char à - 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x3F, 0x00, 0x08, 0xF0, 0x07, 0x00, 0x0C, 0xFE, 0x06, 0x00, 0x86, 0x1F, 0x06, 0x00, 0xC7, 0x03, 0x06, 0x00, 0xC3, 0x03, 0x06, 0x00, 0x87, 0x1F, 0x06, 0x00, 0x06, 0xFE, 0x06, 0x00, 0x0C, 0xF0, 0x07, 0x00, 0x08, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x01, // Code for char  - 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x3F, 0x00, 0x0C, 0xF0, 0x07, 0x00, 0x07, 0xFE, 0x06, 0x00, 0x83, 0x1F, 0x06, 0x00, 0xC3, 0x03, 0x06, 0x00, 0xC6, 0x03, 0x06, 0x00, 0x8C, 0x1F, 0x06, 0x00, 0x0C, 0xFE, 0x06, 0x00, 0x0E, 0xF0, 0x07, 0x00, 0x03, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x01, // Code for char à - 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x0E, 0xFE, 0x06, 0x00, 0x8E, 0x1F, 0x06, 0x00, 0xC4, 0x03, 0x06, 0x00, 0xC0, 0x03, 0x06, 0x00, 0x84, 0x1F, 0x06, 0x00, 0x0E, 0xFE, 0x06, 0x00, 0x0E, 0xF0, 0x07, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x01, // Code for char Ä - 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x3C, 0xFE, 0x06, 0x00, 0xEE, 0x1F, 0x06, 0x00, 0xC2, 0x03, 0x06, 0x00, 0xC2, 0x03, 0x06, 0x00, 0xFE, 0x1F, 0x06, 0x00, 0x3C, 0xFE, 0x06, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x01, // Code for char Å - 0x0F, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xFC, 0x01, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0xFF, 0x07, 0x00, 0xC0, 0x1F, 0x06, 0x00, 0xC0, 0x00, 0x06, 0x00, 0xC0, 0x00, 0x06, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char Æ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x80, 0x07, 0xF0, 0x00, 0x80, 0x03, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x41, 0xC0, 0x00, 0x80, 0x45, 0xC0, 0x00, 0x80, 0x6F, 0xC0, 0x00, 0x80, 0x79, 0xC0, 0x00, 0x80, 0x39, 0xC0, 0x01, 0x80, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ç - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC1, 0xC0, 0x80, 0x01, 0xC3, 0xC0, 0x80, 0x01, 0xC7, 0xC0, 0x80, 0x01, 0xCE, 0xC0, 0x80, 0x01, 0xC8, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char È - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC8, 0xC0, 0x80, 0x01, 0xCE, 0xC0, 0x80, 0x01, 0xC7, 0xC0, 0x80, 0x01, 0xC3, 0xC0, 0x80, 0x01, 0xC1, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char É - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC8, 0xFF, 0xFF, 0x01, 0xCC, 0xC0, 0x80, 0x01, 0xC6, 0xC0, 0x80, 0x01, 0xC7, 0xC0, 0x80, 0x01, 0xC3, 0xC0, 0x80, 0x01, 0xC7, 0xC0, 0x80, 0x01, 0xC6, 0xC0, 0x80, 0x01, 0xCC, 0xC0, 0x80, 0x01, 0xC8, 0xC0, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ê - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xCE, 0xC0, 0x80, 0x01, 0xCE, 0xC0, 0x80, 0x01, 0xC4, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC4, 0xC0, 0x80, 0x01, 0xCE, 0xC0, 0x80, 0x01, 0xCE, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ë - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC1, 0x00, 0x80, 0x01, 0xC3, 0x00, 0x80, 0x01, 0xC7, 0xFF, 0xFF, 0x01, 0xCE, 0xFF, 0xFF, 0x01, 0xC8, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ì - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC8, 0xFF, 0xFF, 0x01, 0xCE, 0x00, 0x80, 0x01, 0xC7, 0x00, 0x80, 0x01, 0xC3, 0x00, 0x80, 0x01, 0xC1, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x80, 0x01, 0xC8, 0x00, 0x80, 0x01, 0xCC, 0x00, 0x80, 0x01, 0xC6, 0x00, 0x80, 0x01, 0xC7, 0xFF, 0xFF, 0x01, 0xC3, 0xFF, 0xFF, 0x01, 0xC7, 0x00, 0x80, 0x01, 0xC6, 0x00, 0x80, 0x01, 0xCC, 0x00, 0x80, 0x01, 0xC8, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Î - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xCE, 0x00, 0x80, 0x01, 0xCE, 0x00, 0x80, 0x01, 0xC4, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC4, 0x00, 0x80, 0x01, 0xCE, 0x00, 0x80, 0x01, 0xCE, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x01, 0xC0, 0xC0, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x80, 0x03, 0xE0, 0x00, 0x80, 0x07, 0x70, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0xCC, 0x03, 0x00, 0x00, 0x07, 0x0F, 0x00, 0x00, 0x03, 0x7C, 0x00, 0x00, 0x03, 0xF0, 0x01, 0x00, 0x06, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x1F, 0x00, 0x0C, 0x00, 0x78, 0x00, 0x0E, 0x00, 0xE0, 0x01, 0xC3, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ñ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x80, 0x03, 0xE0, 0x00, 0xC1, 0x01, 0xC0, 0x01, 0xC3, 0x00, 0x80, 0x01, 0xC7, 0x00, 0x80, 0x01, 0xCE, 0x00, 0x80, 0x01, 0xC8, 0x00, 0x80, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0x80, 0x03, 0xE0, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ò - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x80, 0x03, 0xE0, 0x00, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC8, 0x00, 0x80, 0x01, 0xCE, 0x00, 0x80, 0x01, 0xC7, 0x00, 0x80, 0x01, 0xC3, 0x01, 0xC0, 0x01, 0x81, 0x03, 0xE0, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ó - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x88, 0x03, 0xE0, 0x00, 0xCC, 0x01, 0xC0, 0x01, 0xC6, 0x00, 0x80, 0x01, 0xC7, 0x00, 0x80, 0x01, 0xC3, 0x00, 0x80, 0x01, 0xC7, 0x00, 0x80, 0x01, 0xC6, 0x01, 0xC0, 0x01, 0x8C, 0x03, 0xE0, 0x00, 0x08, 0xFF, 0x7F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ô - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x8C, 0x03, 0xE0, 0x00, 0xC7, 0x01, 0xC0, 0x01, 0xC3, 0x00, 0x80, 0x01, 0xC3, 0x00, 0x80, 0x01, 0xC6, 0x00, 0x80, 0x01, 0xCC, 0x00, 0x80, 0x01, 0xCC, 0x01, 0xC0, 0x01, 0x8E, 0x03, 0xE0, 0x00, 0x03, 0xFF, 0x7F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Õ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x80, 0x03, 0xE0, 0x00, 0xCE, 0x01, 0xC0, 0x01, 0xCE, 0x00, 0x80, 0x01, 0xC4, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC4, 0x00, 0x80, 0x01, 0xCE, 0x01, 0xC0, 0x01, 0x8E, 0x03, 0xE0, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ö - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x38, 0x0E, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x38, 0x0E, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char × - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x01, 0x80, 0x03, 0xF8, 0x00, 0xC0, 0x01, 0xDC, 0x01, 0xC0, 0x00, 0x8F, 0x01, 0xC0, 0x80, 0x83, 0x01, 0xC0, 0xE0, 0x81, 0x01, 0xC0, 0x78, 0x80, 0x01, 0xC0, 0x3D, 0xC0, 0x01, 0x80, 0x0F, 0xE0, 0x00, 0x80, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x40, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ø - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x01, 0x00, 0xC0, 0x01, 0x03, 0x00, 0x80, 0x01, 0x07, 0x00, 0x80, 0x01, 0x0E, 0x00, 0x80, 0x01, 0x08, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xF8, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ù - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x01, 0x08, 0x00, 0x80, 0x01, 0x0E, 0x00, 0x80, 0x01, 0x07, 0x00, 0x80, 0x01, 0x03, 0x00, 0xC0, 0x01, 0x01, 0x00, 0xF8, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ú - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0x08, 0x00, 0xF8, 0x00, 0x0C, 0x00, 0xC0, 0x01, 0x06, 0x00, 0x80, 0x01, 0x07, 0x00, 0x80, 0x01, 0x03, 0x00, 0x80, 0x01, 0x07, 0x00, 0x80, 0x01, 0x06, 0x00, 0xC0, 0x01, 0x0C, 0x00, 0xF8, 0x00, 0xC8, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Û - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x0E, 0x00, 0xC0, 0x01, 0x0E, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80, 0x01, 0x0E, 0x00, 0xC0, 0x01, 0x0E, 0x00, 0xF8, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ü - 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x08, 0xC0, 0xFF, 0x01, 0x0E, 0x80, 0xFF, 0x01, 0x07, 0xE0, 0x03, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x01, 0x3C, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char à - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0x06, 0x18, 0x00, 0x00, 0x06, 0x18, 0x00, 0x00, 0x06, 0x18, 0x00, 0x00, 0x06, 0x18, 0x00, 0x00, 0x06, 0x18, 0x00, 0x00, 0x0E, 0x1C, 0x00, 0x00, 0x0E, 0x0C, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Þ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x01, 0xE0, 0xFF, 0xFF, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x80, 0x01, 0x30, 0xF8, 0x80, 0x01, 0x30, 0xFC, 0x81, 0x01, 0x70, 0x8E, 0x83, 0x01, 0xE0, 0x87, 0x83, 0x01, 0xC0, 0x03, 0xEF, 0x01, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ß - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x10, 0xFC, 0x00, 0x00, 0x30, 0xFC, 0x01, 0x20, 0x18, 0x86, 0x01, 0x60, 0x18, 0x86, 0x01, 0xE0, 0x18, 0x86, 0x01, 0xC0, 0x19, 0x86, 0x01, 0x00, 0x19, 0xC6, 0x00, 0x00, 0x78, 0x66, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0x00, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x10, 0xFC, 0x00, 0x00, 0x30, 0xFC, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x19, 0x86, 0x01, 0xC0, 0x19, 0x86, 0x01, 0xE0, 0x18, 0xC6, 0x00, 0x60, 0x78, 0x66, 0x00, 0x20, 0xF0, 0xFF, 0x01, 0x00, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char á - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x10, 0xFC, 0x00, 0x00, 0x31, 0xFC, 0x01, 0x80, 0x19, 0x86, 0x01, 0xC0, 0x18, 0x86, 0x01, 0xE0, 0x18, 0x86, 0x01, 0x60, 0x18, 0x86, 0x01, 0xE0, 0x18, 0xC6, 0x00, 0xC0, 0x78, 0x66, 0x00, 0x80, 0xF1, 0xFF, 0x01, 0x00, 0xE1, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char â - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x10, 0xFC, 0x00, 0x80, 0x31, 0xFC, 0x01, 0xE0, 0x18, 0x86, 0x01, 0x60, 0x18, 0x86, 0x01, 0x60, 0x18, 0x86, 0x01, 0xC0, 0x18, 0x86, 0x01, 0x80, 0x19, 0xC6, 0x00, 0x80, 0x79, 0x66, 0x00, 0xC0, 0xF1, 0xFF, 0x01, 0x60, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ã - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x10, 0xFC, 0x00, 0x00, 0x30, 0xFC, 0x01, 0xE0, 0x18, 0x86, 0x01, 0xE0, 0x18, 0x86, 0x01, 0x40, 0x18, 0x86, 0x01, 0x00, 0x18, 0x86, 0x01, 0x40, 0x18, 0xC6, 0x00, 0xE0, 0x78, 0x66, 0x00, 0xE0, 0xF0, 0xFF, 0x01, 0x00, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ä - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x10, 0xFC, 0x00, 0x00, 0x30, 0xFC, 0x01, 0xF0, 0x18, 0x86, 0x01, 0xB8, 0x19, 0x86, 0x01, 0x08, 0x19, 0x86, 0x01, 0x08, 0x19, 0x86, 0x01, 0xF8, 0x19, 0xC6, 0x00, 0xF0, 0x78, 0x66, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0x00, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char å - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x30, 0xFC, 0x01, 0x00, 0x18, 0xCE, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x38, 0xC6, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xF6, 0x00, 0x00, 0x18, 0xC6, 0x01, 0x00, 0x18, 0x86, 0x01, 0x00, 0x78, 0x86, 0x01, 0x00, 0xF0, 0x87, 0x01, 0x00, 0xC0, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char æ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xFB, 0x00, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x38, 0xC0, 0x41, 0x00, 0x18, 0x80, 0x45, 0x00, 0x18, 0x80, 0x6F, 0x00, 0x18, 0x80, 0x79, 0x00, 0x18, 0x80, 0x39, 0x00, 0x18, 0x80, 0x01, 0x00, 0x38, 0x80, 0x01, 0x00, 0x10, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ç - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x20, 0x30, 0xC6, 0x00, 0x60, 0x18, 0x86, 0x01, 0xE0, 0x18, 0x86, 0x01, 0xC0, 0x19, 0x86, 0x01, 0x00, 0x19, 0x86, 0x01, 0x00, 0x38, 0x86, 0x01, 0x00, 0xF0, 0x86, 0x01, 0x00, 0xE0, 0xC7, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char è - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x30, 0xC6, 0x00, 0x00, 0x18, 0x86, 0x01, 0x00, 0x19, 0x86, 0x01, 0xC0, 0x19, 0x86, 0x01, 0xE0, 0x18, 0x86, 0x01, 0x60, 0x38, 0x86, 0x01, 0x20, 0xF0, 0x86, 0x01, 0x00, 0xE0, 0xC7, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char é - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF1, 0xFF, 0x00, 0x80, 0x31, 0xC6, 0x00, 0xC0, 0x18, 0x86, 0x01, 0xE0, 0x18, 0x86, 0x01, 0x60, 0x18, 0x86, 0x01, 0xE0, 0x18, 0x86, 0x01, 0xC0, 0x38, 0x86, 0x01, 0x80, 0xF1, 0x86, 0x01, 0x00, 0xE1, 0xC7, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ê - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0xE0, 0x30, 0xC6, 0x00, 0xE0, 0x18, 0x86, 0x01, 0x40, 0x18, 0x86, 0x01, 0x00, 0x18, 0x86, 0x01, 0x40, 0x18, 0x86, 0x01, 0xE0, 0x38, 0x86, 0x01, 0xE0, 0xF0, 0x86, 0x01, 0x00, 0xE0, 0xC7, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ë - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x20, 0x18, 0x80, 0x01, 0x60, 0x18, 0x80, 0x01, 0xE0, 0xF8, 0xFF, 0x01, 0xC0, 0xF9, 0xFF, 0x01, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ì - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0xF9, 0xFF, 0x01, 0xC0, 0xF9, 0xFF, 0x01, 0xE0, 0x00, 0x80, 0x01, 0x60, 0x00, 0x80, 0x01, 0x20, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char í - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x19, 0x80, 0x01, 0x80, 0x19, 0x80, 0x01, 0xC0, 0x18, 0x80, 0x01, 0xE0, 0xF8, 0xFF, 0x01, 0x60, 0xF8, 0xFF, 0x01, 0xE0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char î - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0xE0, 0x18, 0x80, 0x01, 0xE0, 0x18, 0x80, 0x01, 0x40, 0xF8, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x40, 0x00, 0x80, 0x01, 0xE0, 0x00, 0x80, 0x01, 0xE0, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ï - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0xE1, 0xFB, 0x00, 0x30, 0x73, 0xC0, 0x01, 0xF0, 0x31, 0x80, 0x01, 0xE0, 0x31, 0x80, 0x01, 0xC0, 0x30, 0x80, 0x01, 0xC0, 0x31, 0x80, 0x01, 0xE0, 0x67, 0xC0, 0x00, 0x30, 0xFF, 0xF9, 0x00, 0x20, 0xFC, 0x7F, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ð - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x80, 0xE1, 0x01, 0x00, 0xE0, 0x30, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0xC0, 0x18, 0x00, 0x00, 0x80, 0x19, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00, 0xC0, 0x79, 0x00, 0x00, 0x60, 0xF0, 0xFF, 0x01, 0x00, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ñ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xF9, 0x00, 0x20, 0x38, 0xC0, 0x00, 0x60, 0x18, 0x80, 0x01, 0xE0, 0x18, 0x80, 0x01, 0xC0, 0x19, 0x80, 0x01, 0x00, 0x19, 0x80, 0x01, 0x00, 0x30, 0xC0, 0x00, 0x00, 0xF0, 0xF9, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ò - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xF9, 0x00, 0x00, 0x38, 0xC0, 0x00, 0x00, 0x18, 0x80, 0x01, 0x00, 0x19, 0x80, 0x01, 0xC0, 0x19, 0x80, 0x01, 0xE0, 0x18, 0x80, 0x01, 0x60, 0x30, 0xC0, 0x00, 0x20, 0xF0, 0xF9, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ó - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF1, 0xF9, 0x00, 0x80, 0x39, 0xC0, 0x00, 0xC0, 0x18, 0x80, 0x01, 0xE0, 0x18, 0x80, 0x01, 0x60, 0x18, 0x80, 0x01, 0xE0, 0x18, 0x80, 0x01, 0xC0, 0x30, 0xC0, 0x00, 0x80, 0xF1, 0xF9, 0x00, 0x00, 0xE1, 0x7F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ô - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x80, 0xF1, 0xF9, 0x00, 0xE0, 0x38, 0xC0, 0x00, 0x60, 0x18, 0x80, 0x01, 0x60, 0x18, 0x80, 0x01, 0xC0, 0x18, 0x80, 0x01, 0x80, 0x19, 0x80, 0x01, 0x80, 0x31, 0xC0, 0x00, 0xC0, 0xF1, 0xF9, 0x00, 0x60, 0xE0, 0x7F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char õ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xF0, 0xF9, 0x00, 0xE0, 0x38, 0xC0, 0x00, 0xE0, 0x18, 0x80, 0x01, 0x40, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x40, 0x18, 0x80, 0x01, 0xE0, 0x30, 0xC0, 0x00, 0xE0, 0xF0, 0xF9, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ö - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xCE, 0x1C, 0x00, 0x00, 0xCE, 0x1C, 0x00, 0x00, 0xCE, 0x1C, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ÷ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0xFF, 0x01, 0x00, 0xF0, 0xF9, 0x01, 0x00, 0x38, 0xE0, 0x01, 0x00, 0x18, 0xB8, 0x01, 0x00, 0x18, 0x9E, 0x01, 0x00, 0x98, 0x87, 0x01, 0x00, 0xD8, 0x81, 0x01, 0x00, 0xF0, 0xC0, 0x01, 0x00, 0xF8, 0xF9, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ø - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x20, 0x00, 0xC0, 0x01, 0x60, 0x00, 0x80, 0x01, 0xE0, 0x00, 0x80, 0x01, 0xC0, 0x01, 0x80, 0x01, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ù - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x80, 0x01, 0xC0, 0x01, 0x80, 0x01, 0xE0, 0x00, 0x80, 0x01, 0x60, 0x00, 0xC0, 0x00, 0x20, 0x00, 0x70, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ú - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x01, 0xE0, 0x01, 0x80, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xE0, 0x00, 0x80, 0x01, 0x60, 0x00, 0x80, 0x01, 0xE0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0xC0, 0x00, 0x80, 0x01, 0x70, 0x00, 0x00, 0xF9, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char û - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0x01, 0xE0, 0x00, 0xC0, 0x01, 0xE0, 0x00, 0x80, 0x01, 0x40, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x40, 0x00, 0x80, 0x01, 0xE0, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ü - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x00, 0x78, 0x00, 0x60, 0x00, 0xF8, 0x01, 0x60, 0x00, 0xE0, 0x07, 0x60, 0x00, 0x00, 0x3F, 0x70, 0x00, 0x00, 0xFC, 0x3C, 0x00, 0x01, 0xE0, 0x1F, 0xC0, 0x01, 0xE0, 0x07, 0xE0, 0x00, 0xF8, 0x01, 0x60, 0x00, 0x3F, 0x00, 0x20, 0xC0, 0x0F, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ý - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, 0x7F, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x18, 0x80, 0x01, 0x00, 0x38, 0xC0, 0x01, 0x00, 0xF0, 0xF9, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char þ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x00, 0x78, 0x00, 0x60, 0x00, 0xF8, 0x01, 0x60, 0x00, 0xE0, 0x07, 0x60, 0xE0, 0x00, 0x3F, 0x70, 0xE0, 0x00, 0xFC, 0x3C, 0x40, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xE0, 0x07, 0x40, 0x00, 0xF8, 0x01, 0xE0, 0x00, 0x3F, 0x00, 0xE0, 0xC0, 0x0F, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ -}; - -const struct GDS_FontDef Font_droid_sans_mono_16x31 = { - Droid_Sans_Mono16x31, - 16, - 31, - ' ', - '\xFF', - true -}; diff --git a/components/display/fonts/font_droid_sans_mono_7x13.c b/components/display/fonts/font_droid_sans_mono_7x13.c deleted file mode 100644 index 413defd3..00000000 --- a/components/display/fonts/font_droid_sans_mono_7x13.c +++ /dev/null @@ -1,247 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Droid_Sans_Mono7x13 -//GLCD FontSize : 7 x 13 - -static const uint8_t Droid_Sans_Mono7x13[ ] = { - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x05, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x06, 0x90, 0x00, 0xD0, 0x03, 0xBC, 0x00, 0xD0, 0x03, 0xBC, 0x00, 0x90, 0x00, 0x00, 0x00, // Code for char # - 0x06, 0x00, 0x00, 0x18, 0x02, 0x24, 0x02, 0xFE, 0x07, 0x44, 0x02, 0xC4, 0x01, 0x00, 0x00, // Code for char $ - 0x07, 0x18, 0x00, 0x24, 0x02, 0x98, 0x01, 0x60, 0x00, 0x98, 0x01, 0x44, 0x02, 0x80, 0x01, // Code for char % - 0x07, 0x00, 0x00, 0xDC, 0x01, 0x24, 0x02, 0x64, 0x02, 0x9C, 0x03, 0xC0, 0x03, 0x00, 0x02, // Code for char & - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x05, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x06, 0x00, 0x00, 0x10, 0x00, 0x70, 0x00, 0x1C, 0x00, 0x70, 0x00, 0x10, 0x00, 0x00, 0x00, // Code for char * - 0x06, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF0, 0x01, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char + - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x05, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x06, 0x00, 0x00, 0x00, 0x02, 0x80, 0x01, 0x60, 0x00, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, // Code for char / - 0x06, 0x00, 0x00, 0xF8, 0x01, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0xF8, 0x01, 0x00, 0x00, // Code for char 0 - 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 - 0x06, 0x00, 0x00, 0x00, 0x02, 0x04, 0x03, 0x84, 0x02, 0x44, 0x02, 0x38, 0x02, 0x00, 0x00, // Code for char 2 - 0x06, 0x00, 0x00, 0x00, 0x02, 0x24, 0x02, 0x24, 0x02, 0x24, 0x02, 0xD8, 0x01, 0x00, 0x00, // Code for char 3 - 0x06, 0x00, 0x00, 0xC0, 0x00, 0xB0, 0x00, 0x88, 0x00, 0xFC, 0x03, 0x80, 0x00, 0x00, 0x00, // Code for char 4 - 0x06, 0x00, 0x00, 0x3C, 0x02, 0x24, 0x02, 0x24, 0x02, 0x24, 0x02, 0xC4, 0x01, 0x00, 0x00, // Code for char 5 - 0x06, 0x00, 0x00, 0xF0, 0x01, 0x28, 0x02, 0x24, 0x02, 0x24, 0x02, 0xC4, 0x01, 0x00, 0x00, // Code for char 6 - 0x06, 0x00, 0x00, 0x04, 0x00, 0x04, 0x02, 0xC4, 0x01, 0x34, 0x00, 0x0C, 0x00, 0x00, 0x00, // Code for char 7 - 0x06, 0x00, 0x00, 0xD8, 0x01, 0x24, 0x02, 0x24, 0x02, 0x64, 0x02, 0x98, 0x01, 0x00, 0x00, // Code for char 8 - 0x06, 0x00, 0x00, 0x38, 0x02, 0x44, 0x02, 0x44, 0x02, 0x44, 0x01, 0xF8, 0x00, 0x00, 0x00, // Code for char 9 - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x06, 0x00, 0x00, 0x40, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x10, 0x01, 0x00, 0x00, // Code for char < - 0x06, 0x00, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x00, 0x00, // Code for char = - 0x06, 0x00, 0x00, 0x10, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char > - 0x05, 0x00, 0x00, 0x04, 0x00, 0x44, 0x03, 0x24, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x07, 0xF0, 0x01, 0x08, 0x02, 0xE4, 0x05, 0x14, 0x05, 0xF4, 0x04, 0x08, 0x05, 0xF0, 0x00, // Code for char @ - 0x07, 0x00, 0x02, 0xC0, 0x01, 0xB8, 0x00, 0x84, 0x00, 0xB8, 0x00, 0xC0, 0x01, 0x00, 0x02, // Code for char A - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x24, 0x02, 0x24, 0x02, 0x24, 0x02, 0xD8, 0x01, 0x00, 0x00, // Code for char B - 0x06, 0x00, 0x00, 0xF0, 0x00, 0x0C, 0x03, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x00, 0x00, // Code for char C - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x04, 0x02, 0x04, 0x02, 0x0C, 0x01, 0xF0, 0x00, 0x00, 0x00, // Code for char D - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x24, 0x02, 0x24, 0x02, 0x24, 0x02, 0x24, 0x02, 0x00, 0x00, // Code for char E - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x24, 0x00, 0x24, 0x00, 0x24, 0x00, 0x24, 0x00, 0x00, 0x00, // Code for char F - 0x06, 0x00, 0x00, 0xF0, 0x00, 0x0C, 0x03, 0x04, 0x02, 0x24, 0x02, 0xE4, 0x03, 0x00, 0x00, // Code for char G - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xFC, 0x03, 0x00, 0x00, // Code for char H - 0x06, 0x00, 0x00, 0x04, 0x02, 0x04, 0x02, 0xFC, 0x03, 0x04, 0x02, 0x04, 0x02, 0x00, 0x00, // Code for char I - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x20, 0x00, 0x50, 0x00, 0x88, 0x01, 0x04, 0x02, 0x00, 0x00, // Code for char K - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, // Code for char L - 0x06, 0x00, 0x00, 0xFC, 0x03, 0xF0, 0x00, 0x00, 0x03, 0xF0, 0x00, 0xFC, 0x03, 0x00, 0x00, // Code for char M - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0xFC, 0x03, 0x00, 0x00, // Code for char N - 0x06, 0x00, 0x00, 0xF8, 0x01, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0xF8, 0x01, 0x00, 0x00, // Code for char O - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, // Code for char P - 0x06, 0x00, 0x00, 0xF8, 0x01, 0x04, 0x02, 0x04, 0x02, 0x04, 0x06, 0xF8, 0x09, 0x00, 0x00, // Code for char Q - 0x07, 0x00, 0x00, 0xFC, 0x03, 0x44, 0x00, 0x44, 0x00, 0xC4, 0x00, 0x38, 0x01, 0x00, 0x02, // Code for char R - 0x06, 0x00, 0x00, 0x18, 0x02, 0x24, 0x02, 0x24, 0x02, 0x44, 0x02, 0xC4, 0x01, 0x00, 0x00, // Code for char S - 0x06, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0xFC, 0x03, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, // Code for char T - 0x06, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xFC, 0x01, 0x00, 0x00, // Code for char U - 0x07, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x30, 0x00, 0x0C, 0x00, // Code for char V - 0x07, 0x7C, 0x00, 0x80, 0x03, 0xC0, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x80, 0x03, 0x7C, 0x00, // Code for char W - 0x07, 0x04, 0x02, 0x08, 0x01, 0x90, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x04, 0x02, // Code for char X - 0x07, 0x04, 0x00, 0x18, 0x00, 0x20, 0x00, 0xC0, 0x03, 0x20, 0x00, 0x18, 0x00, 0x04, 0x00, // Code for char Y - 0x06, 0x00, 0x00, 0x04, 0x03, 0x84, 0x02, 0x64, 0x02, 0x14, 0x02, 0x0C, 0x02, 0x00, 0x00, // Code for char Z - 0x05, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0x04, 0x08, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x06, 0x00, 0x00, 0x04, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x00, // Code for char BackSlash - 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x04, 0x08, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x06, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x04, 0x00, 0x38, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char ^ - 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, // Code for char _ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x06, 0x00, 0x00, 0x90, 0x01, 0x50, 0x02, 0x50, 0x02, 0x50, 0x02, 0xE0, 0x03, 0x00, 0x00, // Code for char a - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0xE0, 0x01, 0x00, 0x00, // Code for char b - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x00, 0x00, // Code for char c - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0xFC, 0x03, 0x00, 0x00, // Code for char d - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x50, 0x02, 0x50, 0x02, 0x50, 0x02, 0x60, 0x02, 0x00, 0x00, // Code for char e - 0x06, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0xFC, 0x03, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, // Code for char f - 0x07, 0x00, 0x00, 0x60, 0x0F, 0x90, 0x12, 0x90, 0x12, 0x90, 0x12, 0x70, 0x12, 0x10, 0x0C, // Code for char g - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0xE0, 0x03, 0x00, 0x00, // Code for char h - 0x06, 0x00, 0x00, 0x00, 0x02, 0x10, 0x02, 0xF4, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, // Code for char i - 0x05, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF4, 0x0F, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x07, 0x00, 0x00, 0xFC, 0x03, 0x40, 0x00, 0x40, 0x00, 0xA0, 0x00, 0x10, 0x01, 0x00, 0x02, // Code for char k - 0x06, 0x00, 0x00, 0x00, 0x02, 0x04, 0x02, 0xFC, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, // Code for char l - 0x06, 0x00, 0x00, 0xF0, 0x03, 0x10, 0x00, 0xF0, 0x03, 0x10, 0x00, 0xF0, 0x03, 0x00, 0x00, // Code for char m - 0x06, 0x00, 0x00, 0xF0, 0x03, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0xE0, 0x03, 0x00, 0x00, // Code for char n - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0xE0, 0x01, 0x00, 0x00, // Code for char o - 0x06, 0x00, 0x00, 0xF0, 0x1F, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0xE0, 0x01, 0x00, 0x00, // Code for char p - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0xF0, 0x1F, 0x00, 0x00, // Code for char q - 0x06, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, // Code for char r - 0x06, 0x00, 0x00, 0x60, 0x02, 0x50, 0x02, 0x50, 0x02, 0x90, 0x02, 0x90, 0x01, 0x00, 0x00, // Code for char s - 0x06, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0xFC, 0x03, 0x10, 0x02, 0x10, 0x02, 0x00, 0x00, // Code for char t - 0x06, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xF0, 0x03, 0x00, 0x00, // Code for char u - 0x06, 0x00, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x30, 0x00, 0x00, 0x00, // Code for char v - 0x07, 0xF0, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x10, 0x00, 0xE0, 0x01, 0x00, 0x03, 0xF0, 0x00, // Code for char w - 0x06, 0x00, 0x00, 0x10, 0x02, 0x20, 0x01, 0xC0, 0x00, 0x20, 0x01, 0x10, 0x02, 0x00, 0x00, // Code for char x - 0x06, 0x00, 0x00, 0x30, 0x10, 0xC0, 0x10, 0x00, 0x0F, 0xC0, 0x01, 0x30, 0x00, 0x00, 0x00, // Code for char y - 0x06, 0x00, 0x00, 0x10, 0x02, 0x10, 0x03, 0xD0, 0x02, 0x30, 0x02, 0x10, 0x02, 0x00, 0x00, // Code for char z - 0x06, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0xB8, 0x07, 0x04, 0x08, 0x04, 0x08, 0x00, 0x00, // Code for char { - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x06, 0x00, 0x00, 0x04, 0x08, 0x04, 0x08, 0xB8, 0x07, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char } - 0x06, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char ~ - 0x03, 0xF8, 0x07, 0x08, 0x04, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char †- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ - 0x06, 0x00, 0x00, 0xF0, 0x00, 0x08, 0x01, 0x0C, 0x03, 0x08, 0x01, 0x08, 0x01, 0x00, 0x00, // Code for char ¢ - 0x06, 0x00, 0x00, 0x20, 0x02, 0xFC, 0x03, 0x24, 0x02, 0x24, 0x02, 0x04, 0x02, 0x00, 0x00, // Code for char £ - 0x06, 0x00, 0x00, 0xF0, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xF0, 0x01, 0x00, 0x00, // Code for char ¤ - 0x06, 0x00, 0x00, 0x04, 0x00, 0x78, 0x01, 0xC0, 0x03, 0x78, 0x01, 0x04, 0x00, 0x00, 0x00, // Code for char ¥ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ - 0x06, 0x00, 0x00, 0x6C, 0x02, 0x54, 0x02, 0x94, 0x02, 0x94, 0x02, 0x64, 0x01, 0x00, 0x00, // Code for char § - 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ - 0x07, 0xF8, 0x01, 0x04, 0x02, 0x64, 0x02, 0x94, 0x02, 0x94, 0x02, 0x04, 0x02, 0xF8, 0x01, // Code for char © - 0x05, 0x00, 0x00, 0x74, 0x00, 0x54, 0x00, 0x54, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª - 0x06, 0x00, 0x00, 0x40, 0x00, 0xB0, 0x01, 0x00, 0x00, 0x40, 0x00, 0xB0, 0x01, 0x00, 0x00, // Code for char « - 0x06, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xC0, 0x01, 0x00, 0x00, // Code for char ¬ - 0x05, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ - 0x07, 0xF8, 0x01, 0x04, 0x02, 0xF4, 0x02, 0x54, 0x02, 0xB4, 0x02, 0x04, 0x02, 0xF8, 0x01, // Code for char ® - 0x07, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, // Code for char ¯ - 0x05, 0x00, 0x00, 0x18, 0x00, 0x24, 0x00, 0x24, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° - 0x06, 0x00, 0x00, 0x40, 0x02, 0x40, 0x02, 0xF0, 0x03, 0x40, 0x02, 0x40, 0x02, 0x00, 0x00, // Code for char ± - 0x05, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x64, 0x00, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² - 0x05, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x54, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ - 0x06, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xF0, 0x03, 0x00, 0x00, // Code for char µ - 0x06, 0x00, 0x00, 0x38, 0x00, 0x7C, 0x00, 0xFC, 0x07, 0x04, 0x00, 0xFC, 0x07, 0x00, 0x00, // Code for char ¶ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ - 0x05, 0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º - 0x06, 0x00, 0x00, 0xB0, 0x01, 0x40, 0x00, 0x00, 0x00, 0xB0, 0x01, 0x40, 0x00, 0x00, 0x00, // Code for char » - 0x07, 0x04, 0x00, 0x7C, 0x02, 0x80, 0x01, 0x60, 0x00, 0x98, 0x01, 0x44, 0x01, 0xE0, 0x03, // Code for char ¼ - 0x07, 0x04, 0x00, 0x7C, 0x02, 0x80, 0x01, 0x60, 0x00, 0x38, 0x02, 0x24, 0x03, 0xE0, 0x02, // Code for char ½ - 0x07, 0x44, 0x00, 0x54, 0x02, 0xFC, 0x01, 0x60, 0x00, 0x98, 0x01, 0x44, 0x01, 0xE0, 0x03, // Code for char ¾ - 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x09, 0xB0, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, // Code for char ¿ - 0x07, 0x00, 0x02, 0xC0, 0x01, 0xB8, 0x00, 0x85, 0x00, 0xB8, 0x00, 0xC0, 0x01, 0x00, 0x02, // Code for char À - 0x07, 0x00, 0x02, 0xC0, 0x01, 0xB8, 0x00, 0x85, 0x00, 0xB8, 0x00, 0xC0, 0x01, 0x00, 0x02, // Code for char à - 0x07, 0x00, 0x02, 0xC0, 0x01, 0xB9, 0x00, 0x84, 0x00, 0xB9, 0x00, 0xC0, 0x01, 0x00, 0x02, // Code for char  - 0x07, 0x00, 0x02, 0xC0, 0x01, 0xB9, 0x00, 0x84, 0x00, 0xB9, 0x00, 0xC1, 0x01, 0x00, 0x02, // Code for char à - 0x07, 0x00, 0x02, 0xC0, 0x01, 0xB9, 0x00, 0x84, 0x00, 0xB9, 0x00, 0xC0, 0x01, 0x00, 0x02, // Code for char Ä - 0x07, 0x00, 0x02, 0xC0, 0x01, 0xBF, 0x00, 0x85, 0x00, 0xBF, 0x00, 0xC0, 0x01, 0x00, 0x02, // Code for char Å - 0x06, 0x00, 0x03, 0xF0, 0x00, 0x8C, 0x00, 0xFC, 0x03, 0x24, 0x02, 0x24, 0x02, 0x00, 0x00, // Code for char Æ - 0x06, 0x00, 0x00, 0xF0, 0x00, 0x0C, 0x03, 0x04, 0x12, 0x04, 0x0E, 0x04, 0x02, 0x00, 0x00, // Code for char Ç - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x24, 0x02, 0x25, 0x02, 0x24, 0x02, 0x24, 0x02, 0x00, 0x00, // Code for char È - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x24, 0x02, 0x25, 0x02, 0x24, 0x02, 0x24, 0x02, 0x00, 0x00, // Code for char É - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x25, 0x02, 0x24, 0x02, 0x25, 0x02, 0x24, 0x02, 0x00, 0x00, // Code for char Ê - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x25, 0x02, 0x24, 0x02, 0x25, 0x02, 0x24, 0x02, 0x00, 0x00, // Code for char Ë - 0x06, 0x00, 0x00, 0x04, 0x02, 0x04, 0x02, 0xFD, 0x03, 0x04, 0x02, 0x04, 0x02, 0x00, 0x00, // Code for char Ì - 0x06, 0x00, 0x00, 0x04, 0x02, 0x04, 0x02, 0xFD, 0x03, 0x04, 0x02, 0x04, 0x02, 0x00, 0x00, // Code for char à - 0x06, 0x00, 0x00, 0x04, 0x02, 0x05, 0x02, 0xFC, 0x03, 0x05, 0x02, 0x04, 0x02, 0x00, 0x00, // Code for char Î - 0x06, 0x00, 0x00, 0x04, 0x02, 0x05, 0x02, 0xFC, 0x03, 0x05, 0x02, 0x04, 0x02, 0x00, 0x00, // Code for char à - 0x06, 0x20, 0x00, 0xFC, 0x03, 0x24, 0x02, 0x24, 0x02, 0x0C, 0x01, 0xF0, 0x00, 0x00, 0x00, // Code for char à - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x19, 0x00, 0x60, 0x00, 0x81, 0x01, 0xFD, 0x03, 0x00, 0x00, // Code for char Ñ - 0x06, 0x00, 0x00, 0xF8, 0x01, 0x04, 0x02, 0x05, 0x02, 0x04, 0x02, 0xF8, 0x01, 0x00, 0x00, // Code for char Ò - 0x06, 0x00, 0x00, 0xF8, 0x01, 0x04, 0x02, 0x05, 0x02, 0x04, 0x02, 0xF8, 0x01, 0x00, 0x00, // Code for char Ó - 0x06, 0x00, 0x00, 0xF8, 0x01, 0x05, 0x02, 0x04, 0x02, 0x05, 0x02, 0xF8, 0x01, 0x00, 0x00, // Code for char Ô - 0x06, 0x00, 0x00, 0xF8, 0x01, 0x05, 0x02, 0x04, 0x02, 0x05, 0x02, 0xF9, 0x01, 0x00, 0x00, // Code for char Õ - 0x06, 0x00, 0x00, 0xF8, 0x01, 0x05, 0x02, 0x04, 0x02, 0x05, 0x02, 0xF8, 0x01, 0x00, 0x00, // Code for char Ö - 0x06, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x40, 0x00, 0xA0, 0x00, 0x10, 0x01, 0x00, 0x00, // Code for char × - 0x06, 0x00, 0x00, 0xF8, 0x03, 0x84, 0x03, 0x64, 0x02, 0x1C, 0x02, 0xFC, 0x01, 0x00, 0x00, // Code for char Ø - 0x06, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02, 0xFC, 0x01, 0x00, 0x00, // Code for char Ù - 0x06, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02, 0xFC, 0x01, 0x00, 0x00, // Code for char Ú - 0x06, 0x00, 0x00, 0xFC, 0x01, 0x01, 0x02, 0x00, 0x02, 0x01, 0x02, 0xFC, 0x01, 0x00, 0x00, // Code for char Û - 0x06, 0x00, 0x00, 0xFC, 0x01, 0x01, 0x02, 0x00, 0x02, 0x01, 0x02, 0xFC, 0x01, 0x00, 0x00, // Code for char Ü - 0x07, 0x04, 0x00, 0x18, 0x00, 0x20, 0x00, 0xC1, 0x03, 0x20, 0x00, 0x18, 0x00, 0x04, 0x00, // Code for char à - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, 0x00, 0x00, 0x00, // Code for char Þ - 0x06, 0x00, 0x00, 0xFC, 0x03, 0x04, 0x00, 0x64, 0x02, 0x5C, 0x02, 0x80, 0x03, 0x00, 0x00, // Code for char ß - 0x06, 0x00, 0x00, 0x90, 0x01, 0x52, 0x02, 0x54, 0x02, 0x50, 0x02, 0xE0, 0x03, 0x00, 0x00, // Code for char à - 0x06, 0x00, 0x00, 0x90, 0x01, 0x50, 0x02, 0x54, 0x02, 0x52, 0x02, 0xE0, 0x03, 0x00, 0x00, // Code for char á - 0x06, 0x00, 0x00, 0x90, 0x01, 0x54, 0x02, 0x52, 0x02, 0x54, 0x02, 0xE0, 0x03, 0x00, 0x00, // Code for char â - 0x06, 0x00, 0x00, 0x90, 0x01, 0x56, 0x02, 0x52, 0x02, 0x54, 0x02, 0xE6, 0x03, 0x00, 0x00, // Code for char ã - 0x06, 0x00, 0x00, 0x90, 0x01, 0x54, 0x02, 0x50, 0x02, 0x54, 0x02, 0xE0, 0x03, 0x00, 0x00, // Code for char ä - 0x06, 0x00, 0x00, 0x90, 0x01, 0x57, 0x02, 0x55, 0x02, 0x57, 0x02, 0xE0, 0x03, 0x00, 0x00, // Code for char å - 0x07, 0x90, 0x03, 0x50, 0x02, 0x50, 0x02, 0xE0, 0x01, 0x50, 0x02, 0x50, 0x02, 0x60, 0x02, // Code for char æ - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x02, 0x10, 0x12, 0x10, 0x0E, 0x10, 0x02, 0x00, 0x00, // Code for char ç - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x52, 0x02, 0x54, 0x02, 0x50, 0x02, 0x60, 0x02, 0x00, 0x00, // Code for char è - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x50, 0x02, 0x54, 0x02, 0x52, 0x02, 0x60, 0x02, 0x00, 0x00, // Code for char é - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x54, 0x02, 0x52, 0x02, 0x54, 0x02, 0x60, 0x02, 0x00, 0x00, // Code for char ê - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x54, 0x02, 0x50, 0x02, 0x54, 0x02, 0x60, 0x02, 0x00, 0x00, // Code for char ë - 0x06, 0x00, 0x00, 0x00, 0x02, 0x12, 0x02, 0xF4, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, // Code for char ì - 0x06, 0x00, 0x00, 0x00, 0x02, 0x10, 0x02, 0xF4, 0x03, 0x02, 0x02, 0x00, 0x02, 0x00, 0x00, // Code for char í - 0x06, 0x00, 0x00, 0x00, 0x02, 0x14, 0x02, 0xF2, 0x03, 0x04, 0x02, 0x00, 0x02, 0x00, 0x00, // Code for char î - 0x06, 0x00, 0x00, 0x00, 0x02, 0x14, 0x02, 0xF0, 0x03, 0x04, 0x02, 0x00, 0x02, 0x00, 0x00, // Code for char ï - 0x06, 0x00, 0x00, 0xC0, 0x01, 0x2C, 0x02, 0x24, 0x02, 0x3C, 0x02, 0xE0, 0x01, 0x00, 0x00, // Code for char ð - 0x06, 0x00, 0x00, 0xF0, 0x03, 0x16, 0x00, 0x12, 0x00, 0x14, 0x00, 0xE6, 0x03, 0x00, 0x00, // Code for char ñ - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x02, 0x12, 0x02, 0x14, 0x02, 0xE0, 0x01, 0x00, 0x00, // Code for char ò - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x02, 0x14, 0x02, 0x12, 0x02, 0xE0, 0x01, 0x00, 0x00, // Code for char ó - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x14, 0x02, 0x12, 0x02, 0x14, 0x02, 0xE0, 0x01, 0x00, 0x00, // Code for char ô - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x16, 0x02, 0x12, 0x02, 0x14, 0x02, 0xE6, 0x01, 0x00, 0x00, // Code for char õ - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x14, 0x02, 0x10, 0x02, 0x14, 0x02, 0xE0, 0x01, 0x00, 0x00, // Code for char ö - 0x06, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x50, 0x01, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char ÷ - 0x06, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x03, 0xD0, 0x02, 0x30, 0x02, 0xE0, 0x01, 0x00, 0x00, // Code for char ø - 0x06, 0x00, 0x00, 0xF0, 0x01, 0x02, 0x02, 0x04, 0x02, 0x00, 0x02, 0xF0, 0x03, 0x00, 0x00, // Code for char ù - 0x06, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x02, 0x04, 0x02, 0x02, 0x02, 0xF0, 0x03, 0x00, 0x00, // Code for char ú - 0x06, 0x00, 0x00, 0xF0, 0x01, 0x04, 0x02, 0x02, 0x02, 0x04, 0x02, 0xF0, 0x03, 0x00, 0x00, // Code for char û - 0x06, 0x00, 0x00, 0xF0, 0x01, 0x04, 0x02, 0x00, 0x02, 0x04, 0x02, 0xF0, 0x03, 0x00, 0x00, // Code for char ü - 0x06, 0x00, 0x00, 0x30, 0x10, 0xC0, 0x10, 0x04, 0x0F, 0xC2, 0x01, 0x30, 0x00, 0x00, 0x00, // Code for char ý - 0x06, 0x00, 0x00, 0xFC, 0x1F, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0xE0, 0x01, 0x00, 0x00, // Code for char þ - 0x06, 0x00, 0x00, 0x30, 0x10, 0xC4, 0x10, 0x00, 0x0F, 0xC4, 0x01, 0x30, 0x00, 0x00, 0x00 // Code for char ÿ -}; - -const struct GDS_FontDef Font_droid_sans_mono_7x13 = { - Droid_Sans_Mono7x13, - 7, - 13, - ' ', - '\xFF', - true -}; diff --git a/components/display/fonts/font_liberation_mono_13x21.c b/components/display/fonts/font_liberation_mono_13x21.c deleted file mode 100644 index 37492693..00000000 --- a/components/display/fonts/font_liberation_mono_13x21.c +++ /dev/null @@ -1,247 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Liberation_Mono13x21 -//GLCD FontSize : 13 x 21 - -static const uint8_t Liberation_Mono13x21[ ] = { - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x01, 0xF8, 0x9F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x80, 0xD0, 0x01, 0x80, 0x7E, 0x00, 0xE0, 0x13, 0x00, 0x98, 0x10, 0x00, 0x80, 0x10, 0x00, 0x80, 0xD0, 0x01, 0x80, 0x7E, 0x00, 0xE0, 0x13, 0x00, 0x98, 0x10, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, // Code for char # - 0x0C, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0xF0, 0xE1, 0x00, 0x18, 0x81, 0x01, 0x08, 0x03, 0x01, 0x08, 0x02, 0x01, 0xFE, 0xFF, 0x07, 0x08, 0x02, 0x01, 0x08, 0x06, 0x01, 0x18, 0x84, 0x01, 0x70, 0xFC, 0x00, 0x40, 0x78, 0x00, 0x00, 0x00, 0x00, // Code for char $ - 0x0D, 0xF0, 0x01, 0x00, 0xF8, 0x03, 0x01, 0x08, 0x82, 0x01, 0x08, 0x62, 0x00, 0xB8, 0x33, 0x00, 0xF0, 0x0D, 0x00, 0x00, 0x06, 0x00, 0x00, 0xFB, 0x00, 0xC0, 0xDC, 0x01, 0x60, 0x04, 0x01, 0x18, 0x04, 0x01, 0x08, 0xFC, 0x01, 0x00, 0xF8, 0x00, // Code for char % - 0x0D, 0x00, 0x20, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x8C, 0x01, 0xF0, 0x07, 0x01, 0x98, 0x07, 0x01, 0x08, 0x0F, 0x01, 0x08, 0x19, 0x01, 0x88, 0xF1, 0x00, 0xF8, 0xE0, 0x00, 0x70, 0xF8, 0x00, 0x00, 0x9E, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, // Code for char & - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0xE0, 0xFF, 0x03, 0x38, 0x00, 0x0E, 0x0C, 0x00, 0x18, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x0C, 0x00, 0x18, 0x38, 0x00, 0x0E, 0xF0, 0xFF, 0x07, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xA0, 0x01, 0x00, 0xE0, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0xE0, 0x3F, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, // Code for char + - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xC0, 0x0F, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xC0, 0x01, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x01, 0x00, 0xE0, 0x00, 0x00, 0x78, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x07, 0x00, 0xC0, 0x01, 0x00, 0xF0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x7F, 0x00, 0x70, 0xE0, 0x00, 0x18, 0x80, 0x01, 0x08, 0x07, 0x01, 0x08, 0x07, 0x01, 0x08, 0x07, 0x01, 0x18, 0x80, 0x01, 0x70, 0xE0, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, // Code for char 0 - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x20, 0x00, 0x01, 0x30, 0x00, 0x01, 0x10, 0x00, 0x01, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char 1 - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x01, 0x70, 0xE0, 0x01, 0x18, 0x60, 0x01, 0x08, 0x30, 0x01, 0x08, 0x18, 0x01, 0x08, 0x0C, 0x01, 0x18, 0x06, 0x01, 0xF0, 0x03, 0x01, 0xE0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x60, 0xE0, 0x00, 0x70, 0xC0, 0x00, 0x18, 0x80, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x18, 0x05, 0x01, 0xF0, 0xCD, 0x00, 0xF0, 0xFC, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, // Code for char 3 - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x16, 0x00, 0x80, 0x13, 0x00, 0xC0, 0x10, 0x00, 0x60, 0x10, 0x00, 0x38, 0x10, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, // Code for char 4 - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xF8, 0xE7, 0x00, 0xF8, 0xC7, 0x00, 0x08, 0x82, 0x01, 0x08, 0x01, 0x01, 0x08, 0x01, 0x01, 0x08, 0x01, 0x01, 0x08, 0x83, 0x01, 0x08, 0xC6, 0x00, 0x08, 0x7E, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, // Code for char 5 - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0xF0, 0xFD, 0x00, 0x10, 0x82, 0x01, 0x08, 0x01, 0x01, 0x08, 0x01, 0x01, 0x08, 0x01, 0x01, 0x08, 0x83, 0x01, 0x30, 0xC6, 0x00, 0x30, 0xFE, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, // Code for char 6 - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x80, 0x01, 0x08, 0xF8, 0x01, 0x08, 0x3E, 0x00, 0x88, 0x07, 0x00, 0xE8, 0x01, 0x00, 0x78, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xF0, 0xFC, 0x00, 0xF0, 0xCD, 0x00, 0x18, 0x07, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x18, 0x07, 0x01, 0xF0, 0xCD, 0x00, 0xF0, 0xFC, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, // Code for char 8 - 0x0B, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xE0, 0xC7, 0x00, 0x30, 0xC6, 0x00, 0x18, 0x0C, 0x01, 0x08, 0x08, 0x01, 0x08, 0x08, 0x01, 0x08, 0x08, 0x01, 0x18, 0x84, 0x00, 0xF0, 0xF3, 0x00, 0xE0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC1, 0x01, 0xC0, 0xC1, 0x01, 0xC0, 0xC1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xC0, 0xC1, 0x0F, 0xC0, 0xC1, 0x03, 0xC0, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x05, 0x00, 0x80, 0x0D, 0x00, 0x80, 0x0D, 0x00, 0x80, 0x08, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0x40, 0x10, 0x00, 0x60, 0x30, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, // Code for char < - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, // Code for char = - 0x0C, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x60, 0x30, 0x00, 0x40, 0x10, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0x80, 0x08, 0x00, 0x80, 0x0D, 0x00, 0x80, 0x0D, 0x00, 0x00, 0x05, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char > - 0x0B, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x70, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x98, 0x01, 0x08, 0x9C, 0x01, 0x08, 0x06, 0x00, 0x18, 0x03, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x0D, 0x00, 0x18, 0x00, 0xC0, 0xFF, 0x01, 0x70, 0x00, 0x03, 0x18, 0x7E, 0x04, 0x88, 0xC3, 0x08, 0xC4, 0x80, 0x08, 0x44, 0x80, 0x08, 0x44, 0x60, 0x08, 0x84, 0xFF, 0x0C, 0xC8, 0x83, 0x04, 0x18, 0xC0, 0x02, 0xE0, 0x7F, 0x00, 0x00, 0x07, 0x00, // Code for char @ - 0x0D, 0x00, 0x00, 0x01, 0x00, 0xE0, 0x01, 0x00, 0x78, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0B, 0x00, 0x78, 0x08, 0x00, 0x18, 0x08, 0x00, 0x78, 0x08, 0x00, 0xE0, 0x0B, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x01, // Code for char A - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x18, 0x03, 0x01, 0xF0, 0x85, 0x01, 0xF0, 0xFC, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, // Code for char B - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x7F, 0x00, 0x70, 0xE0, 0x00, 0x18, 0x80, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x18, 0x00, 0x01, 0x30, 0x80, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, // Code for char C - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x10, 0x80, 0x00, 0x70, 0xE0, 0x00, 0xE0, 0x7F, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char D - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char E - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x7F, 0x00, 0x70, 0xE0, 0x00, 0x18, 0x80, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x04, 0x01, 0x18, 0x04, 0x01, 0x30, 0x84, 0x01, 0x70, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Code for char G - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x80, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0xF8, 0xFF, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x80, 0x0F, 0x00, 0xC0, 0x1C, 0x00, 0x60, 0x38, 0x00, 0x38, 0xF0, 0x00, 0x18, 0xC0, 0x01, 0x08, 0x80, 0x01, 0x00, 0x00, 0x01, // Code for char K - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char L - 0x0C, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x38, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x80, 0x07, 0x00, 0x00, 0x0C, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x38, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, // Code for char M - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x38, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x3C, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xC0, 0x01, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x7F, 0x00, 0x70, 0xE0, 0x00, 0x18, 0x80, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x18, 0x80, 0x01, 0x70, 0xE0, 0x00, 0xE0, 0x7F, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char O - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x08, 0x0C, 0x00, 0x30, 0x06, 0x00, 0xF0, 0x07, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char P - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x7F, 0x00, 0x70, 0xE0, 0x00, 0x18, 0x80, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x07, 0x08, 0x00, 0x0F, 0x18, 0x80, 0x19, 0x70, 0xE0, 0x10, 0xE0, 0x7F, 0x10, 0x80, 0x1F, 0x10, 0x00, 0x00, 0x00, // Code for char Q - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x0E, 0x00, 0x08, 0x3E, 0x00, 0x18, 0xF1, 0x00, 0xF0, 0xC1, 0x01, 0xE0, 0x80, 0x01, 0x00, 0x00, 0x00, // Code for char R - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xF0, 0xE1, 0x00, 0xB0, 0x83, 0x01, 0x08, 0x03, 0x01, 0x08, 0x02, 0x01, 0x08, 0x06, 0x01, 0x08, 0x06, 0x01, 0x18, 0x06, 0x01, 0x30, 0x8C, 0x01, 0x70, 0xFC, 0x00, 0x40, 0x78, 0x00, 0x00, 0x00, 0x00, // Code for char S - 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T - 0x0B, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x80, 0x01, 0x00, 0xE0, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U - 0x0D, 0x08, 0x00, 0x00, 0x78, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x80, 0x01, 0x00, 0xF0, 0x01, 0x00, 0x3E, 0x00, 0x80, 0x0F, 0x00, 0xF0, 0x01, 0x00, 0x78, 0x00, 0x00, 0x08, 0x00, 0x00, // Code for char V - 0x0D, 0x38, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x80, 0xFF, 0x01, 0x00, 0x80, 0x01, 0x00, 0xF8, 0x01, 0x80, 0x1F, 0x00, 0x80, 0x01, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x80, 0x01, 0x80, 0xFF, 0x01, 0xF8, 0x0F, 0x00, 0x38, 0x00, 0x00, // Code for char W - 0x0C, 0x00, 0x00, 0x00, 0x08, 0x80, 0x01, 0x18, 0xC0, 0x01, 0x70, 0x70, 0x00, 0xE0, 0x38, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x07, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x38, 0x00, 0x70, 0x70, 0x00, 0x18, 0xC0, 0x01, 0x08, 0x80, 0x01, 0x00, 0x00, 0x00, // Code for char X - 0x0C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xFF, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x07, 0x00, 0xC0, 0x01, 0x00, 0xF0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x08, 0xC0, 0x01, 0x08, 0x70, 0x01, 0x08, 0x38, 0x01, 0x08, 0x0C, 0x01, 0x08, 0x07, 0x01, 0x88, 0x03, 0x01, 0xE8, 0x00, 0x01, 0x78, 0x00, 0x01, 0x38, 0x00, 0x01, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char Z - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x1F, 0xFC, 0xFF, 0x1F, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x38, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x78, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0xFC, 0xFF, 0x1F, 0xFC, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x38, 0x00, 0x00, 0x08, 0x00, 0x00, 0x38, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x80, 0x07, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ - 0x0D, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, // Code for char _ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x80, 0xF9, 0x00, 0x80, 0x9D, 0x01, 0x40, 0x04, 0x01, 0x40, 0x04, 0x01, 0x40, 0x04, 0x01, 0x40, 0x84, 0x00, 0xC0, 0x64, 0x00, 0x80, 0xFF, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char a - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x80, 0x80, 0x00, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0xE3, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, // Code for char b - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xE1, 0x00, 0xC0, 0x80, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x80, 0xC1, 0x00, 0x80, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x80, 0xFF, 0x00, 0x80, 0xE3, 0x01, 0xC0, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x80, 0x80, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xEB, 0x00, 0xC0, 0x88, 0x01, 0x40, 0x08, 0x01, 0x40, 0x08, 0x01, 0x40, 0x08, 0x01, 0xC0, 0x88, 0x01, 0x80, 0xCB, 0x00, 0x00, 0xCF, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, // Code for char e - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x4C, 0x00, 0x00, 0x44, 0x00, 0x00, 0x44, 0x00, 0x00, 0x44, 0x00, 0x00, 0x44, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x04, 0x80, 0xE3, 0x0D, 0xC0, 0x00, 0x19, 0x40, 0x00, 0x11, 0x40, 0x00, 0x11, 0x40, 0x00, 0x11, 0x80, 0x80, 0x18, 0xC0, 0xFF, 0x0F, 0xC0, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0xCC, 0xFF, 0x01, 0xCC, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char i - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x40, 0x00, 0x10, 0x40, 0x00, 0x10, 0x40, 0x00, 0x10, 0x40, 0x00, 0x18, 0xCC, 0xFF, 0x0F, 0xCC, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x3B, 0x00, 0x80, 0x61, 0x00, 0xC0, 0xC0, 0x01, 0x40, 0x80, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char k - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x01, 0x04, 0x00, 0x01, 0x04, 0x00, 0x01, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char l - 0x0C, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x80, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0x00, 0x00, // Code for char m - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xE3, 0x00, 0xC0, 0x80, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0xC0, 0x80, 0x01, 0x80, 0xE3, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, // Code for char o - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x1F, 0xC0, 0xFF, 0x1F, 0x80, 0x80, 0x00, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x80, 0x01, 0xC0, 0xE3, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, // Code for char p - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x80, 0xFF, 0x00, 0xC0, 0xE3, 0x01, 0xC0, 0x80, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x80, 0x80, 0x00, 0xC0, 0xFF, 0x1F, 0xC0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x80, 0xC7, 0x00, 0xC0, 0x0C, 0x01, 0x40, 0x0C, 0x01, 0x40, 0x0C, 0x01, 0x40, 0x08, 0x01, 0x40, 0x18, 0x01, 0x80, 0xF9, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0xF8, 0xFF, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x80, 0x00, 0xC0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u - 0x0C, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x80, 0x01, 0x00, 0xE0, 0x01, 0x00, 0x7C, 0x00, 0x00, 0x0F, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v - 0x0D, 0xC0, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x80, 0x01, 0x00, 0xF0, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x1E, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x80, 0x01, 0x00, 0xFE, 0x01, 0xC0, 0x1F, 0x00, 0xC0, 0x00, 0x00, // Code for char w - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0xC1, 0x00, 0x00, 0x73, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x63, 0x00, 0xC0, 0xC1, 0x00, 0xC0, 0x80, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char x - 0x0C, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x03, 0x10, 0x00, 0x0F, 0x10, 0x00, 0x3C, 0x18, 0x00, 0xE0, 0x0D, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x3C, 0x00, 0x00, 0x0F, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x01, 0x40, 0xC0, 0x01, 0x40, 0x70, 0x01, 0x40, 0x38, 0x01, 0x40, 0x0C, 0x01, 0x40, 0x06, 0x01, 0xC0, 0x03, 0x01, 0xC0, 0x01, 0x01, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x1C, 0x00, 0xF0, 0xF7, 0x07, 0xF8, 0xE3, 0x0F, 0x04, 0x00, 0x18, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x0C, 0x00, 0x18, 0xF8, 0xE3, 0x0F, 0xF0, 0xF7, 0x07, 0x00, 0x1C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, // Code for char ~ - 0x05, 0xF0, 0xFF, 0x03, 0x10, 0x00, 0x02, 0x10, 0x00, 0x02, 0x10, 0x00, 0x02, 0xF0, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char †- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x0E, 0xC0, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x80, 0x3F, 0x00, 0xC0, 0x71, 0x00, 0x60, 0xC0, 0x00, 0x20, 0x80, 0x00, 0x38, 0x80, 0x03, 0x20, 0x80, 0x00, 0x20, 0x80, 0x00, 0xC0, 0x40, 0x00, 0xC0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¢ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0xC2, 0x01, 0xF0, 0x7F, 0x01, 0xF0, 0x0F, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x38, 0x00, 0x01, 0x30, 0x80, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, // Code for char £ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2F, 0x00, 0x80, 0x3F, 0x00, 0xC0, 0x30, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0x40, 0x20, 0x00, 0xC0, 0x30, 0x00, 0x80, 0x19, 0x00, 0xC0, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¤ - 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x38, 0x24, 0x00, 0xF0, 0x24, 0x00, 0xC0, 0x25, 0x00, 0x00, 0x27, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x27, 0x00, 0xC0, 0x25, 0x00, 0xF0, 0x24, 0x00, 0x38, 0x24, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¥ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xE3, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0E, 0x03, 0x78, 0x1F, 0x02, 0xCC, 0x19, 0x04, 0xC4, 0x10, 0x04, 0x84, 0x30, 0x04, 0x84, 0x31, 0x04, 0x84, 0x31, 0x04, 0x18, 0x7B, 0x02, 0x18, 0xCF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char § - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ - 0x0D, 0x80, 0x0F, 0x00, 0x60, 0x30, 0x00, 0x18, 0xC0, 0x00, 0x88, 0x8F, 0x00, 0x44, 0x10, 0x01, 0x24, 0x20, 0x01, 0x24, 0x20, 0x01, 0x24, 0x20, 0x01, 0x64, 0x30, 0x01, 0x48, 0x90, 0x00, 0x18, 0xC0, 0x00, 0x60, 0x30, 0x00, 0x80, 0x0F, 0x00, // Code for char © - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xE8, 0x03, 0x00, 0x24, 0x02, 0x00, 0x24, 0x02, 0x00, 0x24, 0x02, 0x00, 0x24, 0x01, 0x00, 0xF8, 0x03, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x36, 0x00, 0x80, 0xE3, 0x00, 0x80, 0xC1, 0x00, 0x00, 0x08, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x77, 0x00, 0x80, 0xE3, 0x00, 0x80, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char « - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, // Code for char ¬ - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ - 0x0D, 0x80, 0x0F, 0x00, 0x60, 0x30, 0x00, 0x18, 0xC0, 0x00, 0xE8, 0xBF, 0x00, 0xE4, 0x3F, 0x01, 0x24, 0x02, 0x01, 0x24, 0x02, 0x01, 0x24, 0x0E, 0x01, 0x64, 0x3B, 0x01, 0xC8, 0xA1, 0x00, 0x18, 0xC0, 0x00, 0x60, 0x30, 0x00, 0x80, 0x0F, 0x00, // Code for char ® - 0x0D, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, // Code for char ¯ - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x04, 0x01, 0x00, 0x04, 0x01, 0x00, 0x04, 0x01, 0x00, 0x04, 0x01, 0xC0, 0x7F, 0x01, 0x00, 0x04, 0x01, 0x00, 0x04, 0x01, 0x00, 0x04, 0x01, 0x00, 0x04, 0x01, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, // Code for char ± - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x30, 0x0E, 0x00, 0x08, 0x0A, 0x00, 0x08, 0x09, 0x00, 0x88, 0x09, 0x00, 0xF8, 0x08, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x18, 0x0C, 0x00, 0x08, 0x08, 0x00, 0x88, 0x08, 0x00, 0x88, 0x08, 0x00, 0x78, 0x0F, 0x00, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x1F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x80, 0x00, 0x00, 0x60, 0x00, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char µ - 0x0B, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF8, 0x03, 0x00, 0xF8, 0x03, 0x00, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0xF8, 0xFF, 0x0F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¶ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x14, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x10, 0x08, 0x00, 0x18, 0x08, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x0C, 0x03, 0x00, 0x04, 0x02, 0x00, 0x04, 0x02, 0x00, 0x04, 0x02, 0x00, 0x0C, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º - 0x0B, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0xC1, 0x00, 0x00, 0x63, 0x00, 0x00, 0x36, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x80, 0x00, 0x80, 0xC1, 0x00, 0x00, 0x63, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char » - 0x0D, 0x10, 0x00, 0x00, 0x10, 0x04, 0x00, 0xF8, 0x07, 0x01, 0x00, 0xC4, 0x01, 0x00, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x66, 0x00, 0x80, 0x71, 0x00, 0x60, 0x48, 0x00, 0x18, 0x46, 0x00, 0x08, 0xFE, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, // Code for char ¼ - 0x0C, 0x10, 0x00, 0x00, 0x10, 0x04, 0x00, 0xF8, 0x07, 0x01, 0x00, 0xC4, 0x01, 0x00, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x06, 0x00, 0x80, 0x85, 0x01, 0x60, 0x46, 0x01, 0x18, 0x62, 0x01, 0x08, 0x32, 0x01, 0x00, 0x1E, 0x01, 0x00, 0x00, 0x00, // Code for char ½ - 0x0D, 0x10, 0x02, 0x00, 0x18, 0x06, 0x00, 0x48, 0x04, 0x01, 0x48, 0xC4, 0x01, 0xB8, 0x67, 0x00, 0x00, 0x19, 0x00, 0x00, 0x66, 0x00, 0x80, 0x71, 0x00, 0x60, 0x48, 0x00, 0x18, 0x46, 0x00, 0x08, 0xFE, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, // Code for char ¾ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0xE0, 0x07, 0x00, 0x60, 0x0C, 0x00, 0x30, 0x08, 0xC0, 0x1C, 0x08, 0xC0, 0x0C, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // Code for char ¿ - 0x0D, 0x00, 0x00, 0x01, 0x00, 0xE0, 0x01, 0x00, 0x78, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0B, 0x00, 0x79, 0x08, 0x00, 0x1B, 0x08, 0x00, 0x78, 0x08, 0x00, 0xE0, 0x0B, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x01, // Code for char À - 0x0D, 0x00, 0x00, 0x01, 0x00, 0xE0, 0x01, 0x00, 0x78, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0B, 0x00, 0x7A, 0x08, 0x00, 0x1B, 0x08, 0x00, 0x79, 0x08, 0x00, 0xE0, 0x0B, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x01, // Code for char à - 0x0D, 0x00, 0x00, 0x01, 0x00, 0xE0, 0x01, 0x00, 0x78, 0x00, 0x02, 0x0F, 0x00, 0xE3, 0x0B, 0x00, 0x79, 0x08, 0x00, 0x18, 0x08, 0x00, 0x79, 0x08, 0x00, 0xE3, 0x0B, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x01, // Code for char  - 0x0D, 0x00, 0x00, 0x01, 0x00, 0xE0, 0x01, 0x00, 0x78, 0x00, 0x03, 0x0F, 0x00, 0xE0, 0x0B, 0x00, 0x78, 0x08, 0x00, 0x19, 0x08, 0x00, 0x7A, 0x08, 0x00, 0xE2, 0x0B, 0x00, 0x01, 0x0F, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x01, // Code for char à - 0x0D, 0x00, 0x00, 0x01, 0x00, 0xE0, 0x01, 0x00, 0x78, 0x00, 0x00, 0x0F, 0x00, 0xE3, 0x0B, 0x00, 0x78, 0x08, 0x00, 0x18, 0x08, 0x00, 0x78, 0x08, 0x00, 0xE3, 0x0B, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x01, // Code for char Ä - 0x0D, 0x00, 0x00, 0x01, 0x00, 0xE0, 0x01, 0x00, 0x78, 0x00, 0x00, 0x0F, 0x00, 0xE6, 0x0B, 0x00, 0x79, 0x08, 0x00, 0x19, 0x08, 0x00, 0x79, 0x08, 0x00, 0xE6, 0x0B, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x01, // Code for char Å - 0x0D, 0x00, 0x00, 0x01, 0x00, 0xE0, 0x01, 0x00, 0x3C, 0x00, 0x80, 0x0F, 0x00, 0xF0, 0x09, 0x00, 0x18, 0x08, 0x00, 0x08, 0x08, 0x00, 0xF8, 0xFF, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x00, 0x00, 0x01, // Code for char Æ - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x7F, 0x00, 0x70, 0xE0, 0x00, 0x18, 0x80, 0x01, 0x08, 0x00, 0x11, 0x08, 0x00, 0x17, 0x08, 0x00, 0x15, 0x18, 0x00, 0x1D, 0x30, 0x80, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, // Code for char Ç - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x09, 0x02, 0x01, 0x0B, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char È - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x02, 0x01, 0x0A, 0x02, 0x01, 0x0B, 0x02, 0x01, 0x09, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char É - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xFA, 0xFF, 0x01, 0x0B, 0x02, 0x01, 0x09, 0x02, 0x01, 0x08, 0x02, 0x01, 0x09, 0x02, 0x01, 0x0B, 0x02, 0x01, 0x0A, 0x02, 0x01, 0x08, 0x02, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char Ê - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x02, 0x01, 0x0B, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x0B, 0x02, 0x01, 0x08, 0x02, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char Ë - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0xF9, 0xFF, 0x01, 0xFB, 0xFF, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ì - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0xFA, 0xFF, 0x01, 0xFB, 0xFF, 0x01, 0x09, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x0A, 0x00, 0x01, 0x0B, 0x00, 0x01, 0xF9, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x09, 0x00, 0x01, 0x0B, 0x00, 0x01, 0x0A, 0x00, 0x01, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Î - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x0B, 0x00, 0x01, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x00, 0x01, 0x0B, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0C, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x02, 0x01, 0x08, 0x00, 0x01, 0x10, 0x80, 0x00, 0x70, 0xE0, 0x00, 0xE0, 0x7F, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x3B, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x01, 0x0F, 0x00, 0x02, 0x3C, 0x00, 0x02, 0xF0, 0x00, 0x01, 0xC0, 0x01, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ñ - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x7F, 0x00, 0x70, 0xE0, 0x00, 0x18, 0x80, 0x01, 0x09, 0x00, 0x01, 0x0B, 0x00, 0x01, 0x08, 0x00, 0x01, 0x18, 0x80, 0x01, 0x70, 0xE0, 0x00, 0xE0, 0x7F, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char Ò - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x7F, 0x00, 0x70, 0xE0, 0x00, 0x18, 0x80, 0x01, 0x0A, 0x00, 0x01, 0x0B, 0x00, 0x01, 0x09, 0x00, 0x01, 0x18, 0x80, 0x01, 0x70, 0xE0, 0x00, 0xE0, 0x7F, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char Ó - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x7F, 0x00, 0x72, 0xE0, 0x00, 0x1B, 0x80, 0x01, 0x09, 0x00, 0x01, 0x08, 0x00, 0x01, 0x09, 0x00, 0x01, 0x1B, 0x80, 0x01, 0x72, 0xE0, 0x00, 0xE0, 0x7F, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char Ô - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x7F, 0x00, 0x73, 0xE0, 0x00, 0x18, 0x80, 0x01, 0x08, 0x00, 0x01, 0x09, 0x00, 0x01, 0x0A, 0x00, 0x01, 0x1A, 0x80, 0x01, 0x71, 0xE0, 0x00, 0xE0, 0x7F, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char Õ - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x7F, 0x00, 0x70, 0xE0, 0x00, 0x1B, 0x80, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x01, 0x1B, 0x80, 0x01, 0x70, 0xE0, 0x00, 0xE0, 0x7F, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char Ö - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0xC0, 0x18, 0x00, 0x80, 0x0D, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x07, 0x00, 0x80, 0x0F, 0x00, 0xC0, 0x1D, 0x00, 0xC0, 0x18, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char × - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x9F, 0x01, 0xE0, 0xFF, 0x00, 0x70, 0xE0, 0x00, 0x18, 0xB0, 0x01, 0x08, 0x0C, 0x01, 0x08, 0x06, 0x01, 0x08, 0x03, 0x01, 0xD8, 0x80, 0x01, 0x70, 0xE0, 0x00, 0xF0, 0x7F, 0x00, 0x98, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char Ø - 0x0B, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x80, 0x01, 0x00, 0xE0, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ù - 0x0B, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x03, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x80, 0x01, 0x00, 0xE0, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ú - 0x0B, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0xF8, 0xFF, 0x00, 0x02, 0xE0, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x03, 0x80, 0x01, 0x02, 0xE0, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Û - 0x0B, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0xE0, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x80, 0x01, 0x00, 0xE0, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ü - 0x0C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xFF, 0x01, 0x03, 0xFE, 0x01, 0x01, 0x07, 0x00, 0xC0, 0x01, 0x00, 0xF0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x20, 0x20, 0x00, 0x20, 0x20, 0x00, 0x20, 0x20, 0x00, 0x20, 0x20, 0x00, 0x60, 0x30, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char Þ - 0x0C, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x01, 0xF8, 0xFF, 0x01, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x01, 0x84, 0x07, 0x01, 0xCC, 0x06, 0x01, 0x78, 0x0C, 0x01, 0x30, 0x98, 0x01, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, // Code for char ß - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x80, 0xF9, 0x00, 0x84, 0x9D, 0x01, 0x44, 0x04, 0x01, 0x4C, 0x04, 0x01, 0x58, 0x04, 0x01, 0x40, 0x84, 0x00, 0xC0, 0x64, 0x00, 0x80, 0xFF, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char à - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x80, 0xF9, 0x00, 0x80, 0x9D, 0x01, 0x40, 0x04, 0x01, 0x50, 0x04, 0x01, 0x58, 0x04, 0x01, 0x4C, 0x84, 0x00, 0xC4, 0x64, 0x00, 0x80, 0xFF, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char á - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x80, 0xF9, 0x00, 0x90, 0x9D, 0x01, 0x58, 0x04, 0x01, 0x4C, 0x04, 0x01, 0x44, 0x04, 0x01, 0x4C, 0x84, 0x00, 0xD8, 0x64, 0x00, 0x90, 0xFF, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char â - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x80, 0xF9, 0x00, 0x98, 0x9D, 0x01, 0x44, 0x04, 0x01, 0x44, 0x04, 0x01, 0x48, 0x04, 0x01, 0x50, 0x84, 0x00, 0xD0, 0x64, 0x00, 0x8C, 0xFF, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char ã - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x80, 0xF9, 0x00, 0x80, 0x9D, 0x01, 0x4C, 0x04, 0x01, 0x40, 0x04, 0x01, 0x40, 0x04, 0x01, 0x40, 0x84, 0x00, 0xCC, 0x64, 0x00, 0x80, 0xFF, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char ä - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x80, 0xF9, 0x00, 0x80, 0x9D, 0x01, 0x4C, 0x04, 0x01, 0x52, 0x04, 0x01, 0x52, 0x04, 0x01, 0x52, 0x84, 0x00, 0xCC, 0x64, 0x00, 0x80, 0xFF, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char å - 0x0D, 0x00, 0x70, 0x00, 0x80, 0xF9, 0x01, 0xC0, 0x0C, 0x01, 0x40, 0x04, 0x01, 0x40, 0x84, 0x01, 0xC0, 0xFF, 0x00, 0x80, 0xFF, 0x00, 0xC0, 0x89, 0x01, 0x40, 0x08, 0x01, 0x40, 0x08, 0x01, 0xC0, 0x88, 0x01, 0x80, 0xCF, 0x00, 0x00, 0x4E, 0x00, // Code for char æ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xE1, 0x00, 0xC0, 0x80, 0x01, 0x40, 0x00, 0x11, 0x40, 0x00, 0x17, 0x40, 0x00, 0x15, 0x40, 0x00, 0x1D, 0x80, 0xC1, 0x00, 0x80, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ç - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xEB, 0x00, 0xC4, 0x88, 0x01, 0x44, 0x08, 0x01, 0x4C, 0x08, 0x01, 0x58, 0x08, 0x01, 0xC0, 0x88, 0x01, 0x80, 0xCB, 0x00, 0x00, 0xCF, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, // Code for char è - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xEB, 0x00, 0xC0, 0x88, 0x01, 0x50, 0x08, 0x01, 0x58, 0x08, 0x01, 0x4C, 0x08, 0x01, 0xC4, 0x88, 0x01, 0x80, 0xCB, 0x00, 0x00, 0xCF, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, // Code for char é - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x90, 0xEB, 0x00, 0xD8, 0x88, 0x01, 0x4C, 0x08, 0x01, 0x44, 0x08, 0x01, 0x4C, 0x08, 0x01, 0xD8, 0x88, 0x01, 0x90, 0xCB, 0x00, 0x00, 0xCF, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, // Code for char ê - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xEB, 0x00, 0xCC, 0x88, 0x01, 0x40, 0x08, 0x01, 0x40, 0x08, 0x01, 0x40, 0x08, 0x01, 0xCC, 0x88, 0x01, 0x80, 0xCB, 0x00, 0x00, 0xCF, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, // Code for char ë - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x01, 0x44, 0x00, 0x01, 0x44, 0x00, 0x01, 0xCC, 0xFF, 0x01, 0xD8, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char ì - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x50, 0x00, 0x01, 0xD8, 0xFF, 0x01, 0xCC, 0xFF, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char í - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0x00, 0x01, 0x58, 0x00, 0x01, 0x4C, 0x00, 0x01, 0xC4, 0xFF, 0x01, 0xCC, 0xFF, 0x01, 0x18, 0x00, 0x01, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char î - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x4C, 0x00, 0x01, 0xC0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // Code for char ï - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xC3, 0x00, 0xB4, 0x81, 0x01, 0x9C, 0x00, 0x01, 0x98, 0x00, 0x01, 0xB8, 0x00, 0x01, 0xF8, 0x81, 0x01, 0xEC, 0xC3, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, // Code for char ð - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0xD8, 0xFF, 0x01, 0x84, 0x00, 0x00, 0x44, 0x00, 0x00, 0x48, 0x00, 0x00, 0x50, 0x00, 0x00, 0x50, 0x00, 0x00, 0xCC, 0xFF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ñ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xE3, 0x00, 0xC4, 0x80, 0x01, 0x44, 0x00, 0x01, 0x4C, 0x00, 0x01, 0x58, 0x00, 0x01, 0xC0, 0x80, 0x01, 0x80, 0xE3, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, // Code for char ò - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xE3, 0x00, 0xC0, 0x80, 0x01, 0x50, 0x00, 0x01, 0x58, 0x00, 0x01, 0x4C, 0x00, 0x01, 0xC4, 0x80, 0x01, 0x80, 0xE3, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, // Code for char ó - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x90, 0xE3, 0x00, 0xD8, 0x80, 0x01, 0x4C, 0x00, 0x01, 0x44, 0x00, 0x01, 0x4C, 0x00, 0x01, 0xD8, 0x80, 0x01, 0x90, 0xE3, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, // Code for char ô - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x98, 0xE3, 0x00, 0xC4, 0x80, 0x01, 0x44, 0x00, 0x01, 0x48, 0x00, 0x01, 0x50, 0x00, 0x01, 0xD0, 0x80, 0x01, 0x8C, 0xE3, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, // Code for char õ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xE3, 0x00, 0xCC, 0x80, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0xCC, 0x80, 0x01, 0x80, 0xE3, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, // Code for char ö - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x60, 0x32, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, // Code for char ÷ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x80, 0xFF, 0x01, 0x80, 0xC1, 0x00, 0xC0, 0xA0, 0x01, 0x40, 0x10, 0x01, 0x40, 0x08, 0x01, 0x40, 0x04, 0x01, 0xC0, 0x83, 0x01, 0x80, 0xC1, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, // Code for char ø - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0xC4, 0xFF, 0x01, 0x04, 0x00, 0x01, 0x0C, 0x00, 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x80, 0x00, 0xC0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ù - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x01, 0x18, 0x00, 0x01, 0x0C, 0x00, 0x01, 0x04, 0x80, 0x00, 0xC0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ú - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0xD0, 0xFF, 0x01, 0x18, 0x00, 0x01, 0x0C, 0x00, 0x01, 0x04, 0x00, 0x01, 0x0C, 0x00, 0x01, 0x18, 0x80, 0x00, 0xD0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char û - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0xC0, 0xFF, 0x01, 0x0C, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x0C, 0x80, 0x00, 0xC0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ü - 0x0C, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x03, 0x10, 0x00, 0x0F, 0x10, 0x00, 0x3C, 0x18, 0x10, 0xE0, 0x0D, 0x18, 0x80, 0x07, 0x0C, 0xE0, 0x01, 0x04, 0x3C, 0x00, 0x00, 0x0F, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ý - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x1F, 0xFC, 0xFF, 0x1F, 0x80, 0x80, 0x00, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x80, 0x01, 0xC0, 0xE3, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, // Code for char þ - 0x0C, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x03, 0x10, 0x00, 0x0F, 0x10, 0x0C, 0x3C, 0x18, 0x00, 0xE0, 0x0D, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x01, 0x0C, 0x3C, 0x00, 0x00, 0x0F, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ -}; - -const struct GDS_FontDef Font_liberation_mono_13x21 = { - Liberation_Mono13x21, - 13, - 21, - ' ', - '\xFF', - true -}; diff --git a/components/display/fonts/font_liberation_mono_17x30.c b/components/display/fonts/font_liberation_mono_17x30.c deleted file mode 100644 index 74d28df3..00000000 --- a/components/display/fonts/font_liberation_mono_17x30.c +++ /dev/null @@ -1,247 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Liberation_Mono17x30 -//GLCD FontSize : 17 x 30 - -static const uint8_t Liberation_Mono17x30[] = { - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xE3, 0x00, 0xE0, 0xFF, 0xE3, 0x00, 0xE0, 0xFF, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x86, 0x00, 0x00, 0x0C, 0xFE, 0x00, 0x00, 0xEC, 0x3F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0xE0, 0x0F, 0x06, 0x00, 0x20, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0xE6, 0x00, 0x00, 0x0C, 0xFF, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0xC0, 0x3F, 0x06, 0x00, 0xE0, 0x0D, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x0F, 0x38, 0x00, 0xC0, 0x1F, 0x70, 0x00, 0xC0, 0x39, 0x60, 0x00, 0xE0, 0x30, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0xF8, 0xFF, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0x03, 0x60, 0xE0, 0xC0, 0x00, 0xE0, 0xC0, 0xC0, 0x00, 0xC0, 0xC1, 0x61, 0x00, 0xC0, 0x83, 0x7F, 0x00, 0x80, 0x83, 0x3F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ - 0x11, 0x80, 0x1F, 0x00, 0x00, 0xC0, 0x3F, 0x80, 0x00, 0xE0, 0x70, 0xC0, 0x00, 0x60, 0x60, 0x70, 0x00, 0x60, 0x60, 0x38, 0x00, 0xE0, 0x70, 0x0E, 0x00, 0xC0, 0x3F, 0x07, 0x00, 0x80, 0xDF, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x70, 0x3F, 0x00, 0x00, 0x9C, 0x7F, 0x00, 0x00, 0xCE, 0xE1, 0x00, 0x80, 0xC3, 0xC0, 0x00, 0xC0, 0xC1, 0xC0, 0x00, 0x60, 0xC0, 0xE1, 0x00, 0x20, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x3F, 0x00, // Code for char % - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0xC0, 0x60, 0x00, 0xC0, 0x7F, 0xC0, 0x00, 0xC0, 0x7F, 0xC0, 0x00, 0xE0, 0xF0, 0xC0, 0x00, 0x60, 0xF0, 0xC3, 0x00, 0x60, 0x18, 0xC7, 0x00, 0x60, 0x18, 0x6E, 0x00, 0xE0, 0x0C, 0x7C, 0x00, 0xC0, 0x07, 0x3C, 0x00, 0x80, 0x83, 0x7F, 0x00, 0x00, 0xC0, 0xE7, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0xC0, 0x3F, 0xF8, 0x07, 0xE0, 0x03, 0x80, 0x0F, 0x78, 0x00, 0x00, 0x3C, 0x38, 0x00, 0x00, 0x38, 0x08, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x20, 0x38, 0x00, 0x00, 0x38, 0xF8, 0x00, 0x00, 0x3E, 0xE0, 0x03, 0x80, 0x0F, 0xC0, 0x3F, 0xF8, 0x07, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x80, 0x18, 0x00, 0x00, 0x80, 0x1D, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x1D, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xC0, 0x07, 0x7C, 0x00, 0xC0, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x60, 0xE0, 0xC0, 0x00, 0x60, 0xE0, 0xC0, 0x00, 0x60, 0xE0, 0xC0, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xC0, 0x00, 0x70, 0x00, 0xC0, 0x0F, 0x7E, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x80, 0x01, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xE0, 0x00, 0x80, 0x03, 0xF0, 0x00, 0xC0, 0x03, 0xF8, 0x00, 0xC0, 0x00, 0xDC, 0x00, 0x60, 0x00, 0xCE, 0x00, 0x60, 0x00, 0xC7, 0x00, 0x60, 0x80, 0xC3, 0x00, 0x60, 0x80, 0xC1, 0x00, 0x60, 0xC0, 0xC1, 0x00, 0xE0, 0xF0, 0xC0, 0x00, 0xC0, 0x7F, 0xC0, 0x00, 0x80, 0x3F, 0xC0, 0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x00, 0x80, 0x03, 0x78, 0x00, 0xC0, 0x03, 0x78, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x70, 0xC0, 0x00, 0xE0, 0xF0, 0xE0, 0x00, 0xC0, 0xDF, 0x7B, 0x00, 0x80, 0x8F, 0x7F, 0x00, 0x00, 0x07, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x06, 0x00, 0x00, 0x38, 0x06, 0x00, 0x00, 0x1C, 0x06, 0x00, 0x00, 0x0E, 0x06, 0x00, 0x80, 0x03, 0x06, 0x00, 0xC0, 0x01, 0x06, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x18, 0x00, 0xE0, 0xFF, 0x38, 0x00, 0xE0, 0xFF, 0x70, 0x00, 0x60, 0x60, 0xE0, 0x00, 0x60, 0x20, 0xC0, 0x00, 0x60, 0x30, 0xC0, 0x00, 0x60, 0x30, 0xC0, 0x00, 0x60, 0x30, 0xC0, 0x00, 0x60, 0x30, 0xC0, 0x00, 0x60, 0x70, 0x60, 0x00, 0x60, 0xE0, 0x79, 0x00, 0x60, 0xC0, 0x3F, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xC0, 0x63, 0x70, 0x00, 0xE0, 0x60, 0xE0, 0x00, 0x60, 0x30, 0xC0, 0x00, 0x60, 0x30, 0xC0, 0x00, 0x60, 0x30, 0xC0, 0x00, 0x60, 0x30, 0xC0, 0x00, 0xE0, 0x70, 0xE0, 0x00, 0xC0, 0xE3, 0x79, 0x00, 0x80, 0xC3, 0x3F, 0x00, 0x00, 0x82, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0xFC, 0x00, 0x60, 0x00, 0xFF, 0x00, 0x60, 0xE0, 0x1F, 0x00, 0x60, 0xF8, 0x01, 0x00, 0x60, 0x7C, 0x00, 0x00, 0x60, 0x0F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1F, 0x00, 0x80, 0x9F, 0x3F, 0x00, 0xC0, 0xFF, 0x7B, 0x00, 0xE0, 0xF0, 0xE0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0xC0, 0xF0, 0xE0, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0x80, 0x9F, 0x3F, 0x00, 0x00, 0x06, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x08, 0x00, 0x80, 0xFF, 0x38, 0x00, 0xC0, 0xFF, 0x79, 0x00, 0xC0, 0x80, 0xE3, 0x00, 0x60, 0x00, 0xC3, 0x00, 0x60, 0x00, 0xC3, 0x00, 0x60, 0x00, 0xC3, 0x00, 0x60, 0x00, 0xC3, 0x00, 0xE0, 0x80, 0xE1, 0x00, 0xC0, 0xC1, 0x71, 0x00, 0xC0, 0x7F, 0x3F, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x0F, 0xF0, 0x07, 0x00, 0x0F, 0xF0, 0x01, 0x00, 0x0F, 0x70, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, 0xB8, 0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x1C, 0x07, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x06, 0x0C, 0x00, 0x00, 0x06, 0x0C, 0x00, 0x00, 0x03, 0x18, 0x00, 0x00, 0x03, 0x18, 0x00, 0x80, 0x03, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x38, 0x00, 0x00, 0x03, 0x18, 0x00, 0x00, 0x03, 0x18, 0x00, 0x00, 0x06, 0x0C, 0x00, 0x00, 0x06, 0x0C, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x1C, 0x07, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0xB8, 0x03, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0xE4, 0x00, 0x60, 0x00, 0xE7, 0x00, 0x60, 0x80, 0xE7, 0x00, 0x60, 0xC0, 0x01, 0x00, 0x60, 0xE0, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x3F, 0xF8, 0x01, 0xC0, 0x03, 0x80, 0x03, 0xE0, 0xE0, 0x1F, 0x07, 0x70, 0xFC, 0x7F, 0x06, 0x30, 0x0E, 0x40, 0x0C, 0x18, 0x03, 0x40, 0x0C, 0x18, 0x01, 0x60, 0x0C, 0x18, 0x01, 0x30, 0x0C, 0x18, 0x86, 0x3F, 0x0C, 0x38, 0xFC, 0x7F, 0x06, 0x30, 0x7F, 0x40, 0x06, 0xE0, 0x01, 0x60, 0x03, 0xC0, 0x07, 0x3C, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char @ - 0x11, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xFE, 0x07, 0x00, 0xC0, 0x1F, 0x06, 0x00, 0xE0, 0x03, 0x06, 0x00, 0x60, 0x00, 0x06, 0x00, 0xE0, 0x03, 0x06, 0x00, 0xC0, 0x1F, 0x06, 0x00, 0x00, 0xFE, 0x06, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x80, 0x00, // Code for char A - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0xE0, 0xF0, 0xE0, 0x00, 0xC0, 0xDF, 0x60, 0x00, 0xC0, 0x9F, 0x7F, 0x00, 0x00, 0x87, 0x3F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0xC0, 0x1F, 0x7F, 0x00, 0xC0, 0x01, 0x70, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xC0, 0x03, 0x70, 0x00, 0x80, 0x07, 0x3C, 0x00, 0x00, 0x03, 0x1C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0xC0, 0x01, 0x70, 0x00, 0x80, 0x07, 0x3C, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0xC0, 0x0F, 0x7F, 0x00, 0xC0, 0x01, 0x70, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0xC0, 0xC0, 0x00, 0x60, 0xC0, 0xC0, 0x00, 0xE0, 0xC0, 0xC0, 0x00, 0xC0, 0xC1, 0x60, 0x00, 0x80, 0xC3, 0x7F, 0x00, 0x00, 0xC3, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xCE, 0x03, 0x00, 0x00, 0x87, 0x0F, 0x00, 0xC0, 0x03, 0x1E, 0x00, 0xE0, 0x01, 0x3C, 0x00, 0xE0, 0x00, 0xF8, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x80, 0x00, // Code for char K - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char M - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFE, 0xFF, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0xF8, 0x00, 0xE0, 0xFF, 0xEF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xC0, 0x07, 0x7C, 0x00, 0xC0, 0x01, 0x70, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xC0, 0x01, 0x70, 0x00, 0xC0, 0x07, 0x7C, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0xE0, 0xC0, 0x01, 0x00, 0xC0, 0xE1, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xC0, 0x07, 0x7C, 0x00, 0xC0, 0x01, 0x70, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x03, 0x60, 0x00, 0xC0, 0x0F, 0xE0, 0x00, 0xE0, 0x0F, 0xC0, 0x01, 0x70, 0x1C, 0xC0, 0x07, 0x7C, 0x18, 0x80, 0xFF, 0x3F, 0x18, 0x00, 0xFE, 0x0F, 0x18, 0x00, 0xE0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, // Code for char Q - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x60, 0xC0, 0x01, 0x00, 0x60, 0xC0, 0x03, 0x00, 0x60, 0xC0, 0x0F, 0x00, 0xE0, 0xE0, 0x1E, 0x00, 0xC0, 0x71, 0x7C, 0x00, 0xC0, 0x7F, 0xF0, 0x00, 0x80, 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0F, 0x3C, 0x00, 0xC0, 0x1F, 0x7C, 0x00, 0xC0, 0x3F, 0x70, 0x00, 0xE0, 0x30, 0xE0, 0x00, 0x60, 0x70, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0xE0, 0xC0, 0x00, 0xE0, 0xC0, 0xE0, 0x00, 0xC0, 0xC3, 0x71, 0x00, 0xC0, 0x83, 0x7F, 0x00, 0x00, 0x83, 0x3F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S - 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U - 0x11, 0x20, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFE, 0x01, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, // Code for char V - 0x11, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, // Code for char W - 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xE0, 0x01, 0xF8, 0x00, 0xC0, 0x03, 0x3C, 0x00, 0x80, 0x0F, 0x1F, 0x00, 0x00, 0x9E, 0x07, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x9E, 0x07, 0x00, 0x80, 0x0F, 0x1F, 0x00, 0xC0, 0x03, 0x3C, 0x00, 0xE0, 0x01, 0xF8, 0x00, 0x60, 0x00, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X - 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xF0, 0x00, 0x60, 0x00, 0xF8, 0x00, 0x60, 0x00, 0xDE, 0x00, 0x60, 0x00, 0xCF, 0x00, 0x60, 0x80, 0xC7, 0x00, 0x60, 0xE0, 0xC1, 0x00, 0x60, 0xF0, 0xC0, 0x00, 0x60, 0x78, 0xC0, 0x00, 0x60, 0x1E, 0xC0, 0x00, 0x60, 0x0F, 0xC0, 0x00, 0xE0, 0x07, 0xC0, 0x00, 0xE0, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x3F, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0xF8, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ - 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, // Code for char _ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3F, 0x00, 0x00, 0x8C, 0x7F, 0x00, 0x00, 0x8E, 0xF7, 0x00, 0x00, 0xC7, 0xC1, 0x00, 0x00, 0xC3, 0xC0, 0x00, 0x00, 0xC3, 0xC0, 0x00, 0x00, 0xC3, 0xC0, 0x00, 0x00, 0xC3, 0x60, 0x00, 0x00, 0xC7, 0x30, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0x00, 0x1C, 0x38, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0x7E, 0x7E, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x0E, 0x70, 0x00, 0x00, 0x0E, 0x70, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x1C, 0x38, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x8E, 0x61, 0x00, 0x00, 0x87, 0xE1, 0x00, 0x00, 0x83, 0xC1, 0x00, 0x00, 0x83, 0xC1, 0x00, 0x00, 0x83, 0xC1, 0x00, 0x00, 0x87, 0xC1, 0x00, 0x00, 0x86, 0xE1, 0x00, 0x00, 0xFE, 0x71, 0x00, 0x00, 0xFC, 0x31, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x00, 0xF0, 0xFF, 0xFF, 0x00, 0x38, 0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x0C, 0x00, 0xFE, 0x7F, 0x1C, 0x00, 0x07, 0xE0, 0x1C, 0x00, 0x03, 0xC0, 0x38, 0x00, 0x03, 0xC0, 0x30, 0x00, 0x03, 0xC0, 0x30, 0x00, 0x03, 0xC0, 0x30, 0x00, 0x06, 0x60, 0x30, 0x00, 0x1C, 0x38, 0x1C, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x38, 0xFF, 0xFF, 0x00, 0x38, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x03, 0x00, 0x30, 0x00, 0x03, 0x00, 0x30, 0x00, 0x03, 0x00, 0x30, 0x00, 0x03, 0x00, 0x30, 0x00, 0x03, 0x00, 0x30, 0x00, 0x03, 0x00, 0x18, 0x38, 0xFF, 0xFF, 0x1F, 0x38, 0xFF, 0xFF, 0x0F, 0x38, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x1C, 0x1E, 0x00, 0x00, 0x0E, 0x3C, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0x7E, 0x7E, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x1C, 0x38, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x1C, 0x38, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x7C, 0x70, 0x00, 0x00, 0xFE, 0x70, 0x00, 0x00, 0xE6, 0xE0, 0x00, 0x00, 0xC3, 0xC0, 0x00, 0x00, 0xC3, 0xC1, 0x00, 0x00, 0xC3, 0xC1, 0x00, 0x00, 0x83, 0xC1, 0x00, 0x00, 0x83, 0xC3, 0x00, 0x00, 0x87, 0xE3, 0x00, 0x00, 0x0E, 0x7F, 0x00, 0x00, 0x0C, 0x3E, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0xF0, 0xFF, 0x7F, 0x00, 0xF0, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v - 0x11, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // Code for char w - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x0F, 0x78, 0x00, 0x00, 0x3C, 0x3C, 0x00, 0x00, 0x78, 0x0E, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x78, 0x1E, 0x00, 0x00, 0x1C, 0x3C, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x30, 0x00, 0x3F, 0x00, 0x30, 0x00, 0xFC, 0x01, 0x30, 0x00, 0xE0, 0x07, 0x38, 0x00, 0x00, 0x3F, 0x1C, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x03, 0xDC, 0x00, 0x00, 0x03, 0xCF, 0x00, 0x00, 0x83, 0xC7, 0x00, 0x00, 0xC3, 0xC1, 0x00, 0x00, 0xF3, 0xC0, 0x00, 0x00, 0x7B, 0xC0, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xE0, 0x07, 0x00, 0xE0, 0x7F, 0xFE, 0x0F, 0xF0, 0x7F, 0xFE, 0x1F, 0x78, 0x00, 0x00, 0x3C, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x30, 0x38, 0x00, 0x00, 0x3C, 0xF0, 0x7F, 0xFE, 0x1F, 0xE0, 0x7F, 0xFE, 0x0F, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ - 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x01, 0x60, 0x00, 0x00, 0x01, 0x60, 0x00, 0x00, 0x01, 0x60, 0x00, 0x00, 0x01, 0x60, 0x00, 0x00, 0x01, 0xE0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char †- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0xFF, 0x0F, 0x00, 0xC7, 0xFF, 0x0F, 0x00, 0xC7, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x03, 0x1C, 0x00, 0x80, 0x03, 0x38, 0x00, 0x80, 0x01, 0x30, 0x00, 0xF0, 0x01, 0xF0, 0x01, 0xF0, 0x01, 0xF0, 0x01, 0x80, 0x01, 0x30, 0x00, 0x80, 0x03, 0x38, 0x00, 0x00, 0x0F, 0x1E, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¢ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xE0, 0x00, 0x00, 0xFC, 0xFF, 0x00, 0x80, 0xFF, 0xFF, 0x00, 0xC0, 0xFF, 0xDF, 0x00, 0xE0, 0xC0, 0xC0, 0x00, 0x60, 0xC0, 0xC0, 0x00, 0x60, 0xC0, 0xC0, 0x00, 0x60, 0xC0, 0xC0, 0x00, 0x60, 0xC0, 0xC0, 0x00, 0xE0, 0xC0, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x00, 0xC0, 0x01, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char £ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0xFB, 0x0D, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x0E, 0x07, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xFB, 0x0D, 0x00, 0x00, 0x62, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¤ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x0C, 0x00, 0xE0, 0xC3, 0x0C, 0x00, 0x80, 0xC7, 0x0C, 0x00, 0x00, 0xDF, 0x0C, 0x00, 0x00, 0xFC, 0x0C, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0xFC, 0x0C, 0x00, 0x00, 0xDF, 0x0C, 0x00, 0x80, 0xC7, 0x0C, 0x00, 0xE0, 0xC3, 0x0C, 0x00, 0xE0, 0xC0, 0x0C, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¥ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xF8, 0x3F, 0xF8, 0x3F, 0xF8, 0x3F, 0xF8, 0x3F, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0xE0, 0xF1, 0xC1, 0x01, 0xF0, 0xFB, 0xC1, 0x01, 0x30, 0x9B, 0x83, 0x03, 0x18, 0x0E, 0x03, 0x03, 0x18, 0x06, 0x06, 0x03, 0x18, 0x06, 0x06, 0x03, 0x18, 0x0C, 0x06, 0x03, 0x18, 0x0C, 0x06, 0x03, 0x38, 0x1C, 0x8F, 0x03, 0x70, 0xB8, 0xFF, 0x01, 0x60, 0xF8, 0xF9, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char § - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ - 0x11, 0x00, 0x70, 0x00, 0x00, 0x00, 0xFF, 0x07, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x60, 0x00, 0x30, 0x00, 0x10, 0xFE, 0x41, 0x00, 0x10, 0xFF, 0x47, 0x00, 0x88, 0x01, 0x8C, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x01, 0x8C, 0x00, 0x10, 0x03, 0x46, 0x00, 0x10, 0x02, 0x42, 0x00, 0x60, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0x70, 0x00, 0x00, // Code for char © - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3C, 0x00, 0x00, 0x60, 0x7E, 0x00, 0x00, 0x70, 0x67, 0x00, 0x00, 0x30, 0x63, 0x00, 0x00, 0x30, 0x63, 0x00, 0x00, 0x30, 0x63, 0x00, 0x00, 0x30, 0x33, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0x70, 0x1C, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x08, 0x21, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0x70, 0x1C, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char « - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¬ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ - 0x11, 0x00, 0x70, 0x00, 0x00, 0x00, 0xFF, 0x07, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x60, 0x00, 0x30, 0x00, 0x10, 0x00, 0x40, 0x00, 0x90, 0xFF, 0x4F, 0x00, 0x88, 0x20, 0x80, 0x00, 0x88, 0x20, 0x80, 0x00, 0x88, 0x20, 0x80, 0x00, 0x88, 0xE0, 0x80, 0x00, 0x88, 0xF1, 0x83, 0x00, 0x10, 0x1F, 0x4F, 0x00, 0x10, 0x0E, 0x4C, 0x00, 0x60, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0x70, 0x00, 0x00, // Code for char ® - 0x11, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // Code for char ¯ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xC0, 0x0C, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0xE0, 0x1C, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x30, 0xC0, 0x00, 0xC0, 0xFF, 0xCF, 0x00, 0xC0, 0xFF, 0xCF, 0x00, 0xC0, 0xFF, 0xCF, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ± - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0xE0, 0x00, 0x00, 0x70, 0xF0, 0x00, 0x00, 0x30, 0xD8, 0x00, 0x00, 0x30, 0xCC, 0x00, 0x00, 0x30, 0xC4, 0x00, 0x00, 0x70, 0xC3, 0x00, 0x00, 0xE0, 0xC1, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x70, 0xC0, 0x00, 0x00, 0x30, 0xC6, 0x00, 0x00, 0x30, 0xC6, 0x00, 0x00, 0x30, 0xC6, 0x00, 0x00, 0xF0, 0xEF, 0x00, 0x00, 0xE0, 0x7D, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char µ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0xE0, 0xFF, 0xFF, 0x1F, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0xE0, 0xFF, 0xFF, 0x1F, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¶ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x20, 0xC0, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xE0, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x30, 0x60, 0x00, 0x00, 0x30, 0x60, 0x00, 0x00, 0x30, 0x60, 0x00, 0x00, 0x30, 0x70, 0x00, 0x00, 0xE0, 0x38, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x78, 0x3C, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x08, 0x21, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x70, 0x1C, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char » - 0x11, 0x80, 0xC1, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0xE0, 0xFF, 0x80, 0x00, 0x00, 0xC0, 0xE0, 0x00, 0x00, 0xC0, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x0E, 0x3C, 0x00, 0x80, 0x03, 0x37, 0x00, 0xE0, 0x80, 0x31, 0x00, 0x20, 0xC0, 0x30, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x30, 0x00, // Code for char ¼ - 0x11, 0x80, 0xC1, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0xE0, 0xFF, 0x80, 0x00, 0x00, 0xC0, 0xE0, 0x00, 0x00, 0xC0, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0xCE, 0xE0, 0x00, 0x80, 0xC3, 0xF0, 0x00, 0xE0, 0x60, 0xD8, 0x00, 0x20, 0x60, 0xC8, 0x00, 0x00, 0x60, 0xCC, 0x00, 0x00, 0xE0, 0xC7, 0x00, 0x00, 0xC0, 0xC1, 0x00, // Code for char ½ - 0x11, 0xC0, 0x60, 0x00, 0x00, 0xC0, 0x60, 0x00, 0x00, 0x60, 0xC0, 0x00, 0x00, 0x60, 0xC6, 0x80, 0x00, 0x60, 0xC6, 0xE0, 0x00, 0xE0, 0xFF, 0x38, 0x00, 0xC0, 0x79, 0x0E, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x0E, 0x3C, 0x00, 0x80, 0x03, 0x37, 0x00, 0xE0, 0x80, 0x31, 0x00, 0x20, 0xC0, 0x30, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x30, 0x00, // Code for char ¾ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x0E, 0x06, 0x00, 0x00, 0x07, 0x0C, 0x00, 0x80, 0x03, 0x0C, 0x00, 0xE7, 0x01, 0x0C, 0x00, 0xE7, 0x00, 0x0C, 0x00, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¿ - 0x11, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x01, 0xFE, 0x07, 0x00, 0xC3, 0x1F, 0x06, 0x00, 0xE7, 0x03, 0x06, 0x00, 0x6E, 0x00, 0x06, 0x00, 0xEC, 0x03, 0x06, 0x00, 0xC0, 0x1F, 0x06, 0x00, 0x00, 0xFE, 0x06, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x80, 0x00, // Code for char À - 0x11, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xFE, 0x07, 0x00, 0xC0, 0x1F, 0x06, 0x00, 0xE8, 0x03, 0x06, 0x00, 0x6E, 0x00, 0x06, 0x00, 0xE7, 0x03, 0x06, 0x00, 0xC3, 0x1F, 0x06, 0x00, 0x01, 0xFE, 0x06, 0x00, 0x01, 0xF0, 0x07, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x80, 0x00, // Code for char à - 0x11, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x08, 0xF0, 0x07, 0x00, 0x0C, 0xFE, 0x07, 0x00, 0xC6, 0x1F, 0x06, 0x00, 0xE7, 0x03, 0x06, 0x00, 0x63, 0x00, 0x06, 0x00, 0xE7, 0x03, 0x06, 0x00, 0xC6, 0x1F, 0x06, 0x00, 0x0C, 0xFE, 0x06, 0x00, 0x08, 0xF0, 0x07, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x80, 0x00, // Code for char  - 0x11, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x0E, 0xF0, 0x07, 0x00, 0x03, 0xFE, 0x07, 0x00, 0xC3, 0x1F, 0x06, 0x00, 0xE3, 0x03, 0x06, 0x00, 0x66, 0x00, 0x06, 0x00, 0xEC, 0x03, 0x06, 0x00, 0xCC, 0x1F, 0x06, 0x00, 0x0E, 0xFE, 0x06, 0x00, 0x07, 0xF0, 0x07, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x80, 0x00, // Code for char à - 0x11, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x07, 0xFE, 0x07, 0x00, 0xC7, 0x1F, 0x06, 0x00, 0xE0, 0x03, 0x06, 0x00, 0x60, 0x00, 0x06, 0x00, 0xE0, 0x03, 0x06, 0x00, 0xC7, 0x1F, 0x06, 0x00, 0x07, 0xFE, 0x06, 0x00, 0x07, 0xF0, 0x07, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x80, 0x00, // Code for char Ä - 0x11, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x18, 0xFE, 0x07, 0x00, 0xFC, 0x1F, 0x06, 0x00, 0xE6, 0x03, 0x06, 0x00, 0x66, 0x00, 0x06, 0x00, 0xE6, 0x03, 0x06, 0x00, 0xFE, 0x1F, 0x06, 0x00, 0x3C, 0xFE, 0x06, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x80, 0x00, // Code for char Å - 0x11, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x7E, 0x03, 0x00, 0xC0, 0x0F, 0x03, 0x00, 0xE0, 0x01, 0x03, 0x00, 0x60, 0x00, 0x03, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, // Code for char Æ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0xC0, 0x1F, 0x7F, 0x00, 0xC0, 0x01, 0x70, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x60, 0x00, 0xC0, 0x34, 0x60, 0x00, 0xC0, 0x37, 0x60, 0x00, 0xC0, 0x36, 0x60, 0x00, 0xC0, 0x1E, 0xE0, 0x00, 0xE0, 0x0C, 0xC0, 0x03, 0x70, 0x00, 0x80, 0x07, 0x3C, 0x00, 0x00, 0x03, 0x1C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ç - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x61, 0x60, 0xC0, 0x00, 0x63, 0x60, 0xC0, 0x00, 0x67, 0x60, 0xC0, 0x00, 0x6E, 0x60, 0xC0, 0x00, 0x6C, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char È - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x68, 0x60, 0xC0, 0x00, 0x6E, 0x60, 0xC0, 0x00, 0x67, 0x60, 0xC0, 0x00, 0x63, 0x60, 0xC0, 0x00, 0x61, 0x60, 0xC0, 0x00, 0x61, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char É - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE8, 0xFF, 0xFF, 0x00, 0x6C, 0x60, 0xC0, 0x00, 0x66, 0x60, 0xC0, 0x00, 0x67, 0x60, 0xC0, 0x00, 0x63, 0x60, 0xC0, 0x00, 0x67, 0x60, 0xC0, 0x00, 0x66, 0x60, 0xC0, 0x00, 0x6C, 0x60, 0xC0, 0x00, 0x68, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ê - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x67, 0x60, 0xC0, 0x00, 0x67, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x67, 0x60, 0xC0, 0x00, 0x67, 0x60, 0xC0, 0x00, 0x67, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ë - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x61, 0x00, 0xC0, 0x00, 0x63, 0x00, 0xC0, 0x00, 0xE7, 0xFF, 0xFF, 0x00, 0xEE, 0xFF, 0xFF, 0x00, 0xEC, 0xFF, 0xFF, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ì - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE8, 0xFF, 0xFF, 0x00, 0xEE, 0xFF, 0xFF, 0x00, 0x67, 0x00, 0xC0, 0x00, 0x63, 0x00, 0xC0, 0x00, 0x61, 0x00, 0xC0, 0x00, 0x61, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x68, 0x00, 0xC0, 0x00, 0x6C, 0x00, 0xC0, 0x00, 0x66, 0x00, 0xC0, 0x00, 0xE7, 0xFF, 0xFF, 0x00, 0xE3, 0xFF, 0xFF, 0x00, 0xE7, 0xFF, 0xFF, 0x00, 0x66, 0x00, 0xC0, 0x00, 0x6C, 0x00, 0xC0, 0x00, 0x68, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Î - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x67, 0x00, 0xC0, 0x00, 0x67, 0x00, 0xC0, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x67, 0x00, 0xC0, 0x00, 0x67, 0x00, 0xC0, 0x00, 0x67, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x10, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0xC0, 0x01, 0x70, 0x00, 0x80, 0x07, 0x3C, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xEE, 0xFE, 0xFF, 0x00, 0xE3, 0x07, 0x00, 0x00, 0x03, 0x1F, 0x00, 0x00, 0x03, 0x7C, 0x00, 0x00, 0x06, 0xF0, 0x01, 0x00, 0x0C, 0xC0, 0x0F, 0x00, 0x0C, 0x00, 0x3F, 0x00, 0x0E, 0x00, 0xF8, 0x00, 0xE7, 0xFF, 0xEF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ñ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xC0, 0x07, 0x7C, 0x00, 0xC1, 0x01, 0x70, 0x00, 0xE3, 0x00, 0xE0, 0x00, 0x67, 0x00, 0xC0, 0x00, 0x6E, 0x00, 0xC0, 0x00, 0x6C, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xC0, 0x01, 0x70, 0x00, 0xC0, 0x07, 0x7C, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ò - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xC0, 0x07, 0x7C, 0x00, 0xC0, 0x01, 0x70, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x68, 0x00, 0xC0, 0x00, 0x6E, 0x00, 0xC0, 0x00, 0xE7, 0x00, 0xE0, 0x00, 0xC3, 0x01, 0x70, 0x00, 0xC1, 0x07, 0x7C, 0x00, 0x81, 0xFF, 0x3F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ó - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xC8, 0x07, 0x7C, 0x00, 0xCC, 0x01, 0x70, 0x00, 0xE6, 0x00, 0xE0, 0x00, 0x67, 0x00, 0xC0, 0x00, 0x63, 0x00, 0xC0, 0x00, 0x67, 0x00, 0xC0, 0x00, 0xE6, 0x00, 0xE0, 0x00, 0xCC, 0x01, 0x70, 0x00, 0xC8, 0x07, 0x7C, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ô - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xCE, 0x07, 0x7C, 0x00, 0xC3, 0x01, 0x70, 0x00, 0xE3, 0x00, 0xE0, 0x00, 0x63, 0x00, 0xC0, 0x00, 0x66, 0x00, 0xC0, 0x00, 0x6C, 0x00, 0xC0, 0x00, 0xEC, 0x00, 0xE0, 0x00, 0xCE, 0x01, 0x70, 0x00, 0xC7, 0x07, 0x7C, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Õ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xC0, 0x07, 0x7C, 0x00, 0xC7, 0x01, 0x70, 0x00, 0xE7, 0x00, 0xE0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x60, 0x00, 0xC0, 0x00, 0xE7, 0x00, 0xE0, 0x00, 0xC7, 0x01, 0x70, 0x00, 0xC7, 0x07, 0x7C, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ö - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x07, 0x1C, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x1C, 0x07, 0x00, 0x00, 0xB8, 0x03, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xB8, 0x03, 0x00, 0x00, 0x1C, 0x07, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x07, 0x1C, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char × - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xC0, 0x00, 0x00, 0xFE, 0xEF, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xC0, 0x07, 0x7C, 0x00, 0xC0, 0x01, 0x7E, 0x00, 0xE0, 0x00, 0xE7, 0x00, 0x60, 0xC0, 0xC1, 0x00, 0x60, 0xE0, 0xC0, 0x00, 0x60, 0x30, 0xC0, 0x00, 0xE0, 0x1C, 0xE0, 0x00, 0xC0, 0x0F, 0x70, 0x00, 0xC0, 0x07, 0x7C, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xE0, 0xFE, 0x0F, 0x00, 0x60, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ø - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x01, 0x00, 0xE0, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x07, 0x00, 0xC0, 0x00, 0x0E, 0x00, 0xC0, 0x00, 0x0C, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ù - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x08, 0x00, 0xC0, 0x00, 0x0E, 0x00, 0xC0, 0x00, 0x07, 0x00, 0xC0, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x01, 0x00, 0xE0, 0x00, 0xE1, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ú - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE8, 0xFF, 0x7F, 0x00, 0x0C, 0x00, 0xE0, 0x00, 0x06, 0x00, 0xC0, 0x00, 0x07, 0x00, 0xC0, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x07, 0x00, 0xC0, 0x00, 0x06, 0x00, 0xC0, 0x00, 0x0C, 0x00, 0xE0, 0x00, 0xE8, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Û - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x7F, 0x00, 0x07, 0x00, 0xE0, 0x00, 0x07, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x07, 0x00, 0xC0, 0x00, 0x07, 0x00, 0xE0, 0x00, 0xE7, 0xFF, 0x7F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ü - 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x08, 0xC0, 0xFF, 0x00, 0x0E, 0xF0, 0xFF, 0x00, 0x07, 0x78, 0x00, 0x00, 0x03, 0x1E, 0x00, 0x00, 0x81, 0x0F, 0x00, 0x00, 0xE1, 0x03, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x00, 0x0E, 0x07, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Þ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x00, 0xF0, 0xFF, 0xFF, 0x00, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x18, 0x00, 0xC0, 0x00, 0x18, 0x78, 0xC0, 0x00, 0x18, 0xFC, 0xC0, 0x00, 0x30, 0xCF, 0xC1, 0x00, 0xF0, 0xC7, 0xC1, 0x00, 0xE0, 0x81, 0xE7, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ß - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3F, 0x00, 0x00, 0x8C, 0x7F, 0x00, 0x00, 0x8E, 0xF7, 0x00, 0x04, 0xC7, 0xC1, 0x00, 0x0C, 0xC3, 0xC0, 0x00, 0x1C, 0xC3, 0xC0, 0x00, 0x38, 0xC3, 0xC0, 0x00, 0x30, 0xC3, 0x60, 0x00, 0x00, 0xC7, 0x30, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3F, 0x00, 0x00, 0x8C, 0x7F, 0x00, 0x00, 0x8E, 0xF7, 0x00, 0x00, 0xC7, 0xC1, 0x00, 0x00, 0xC3, 0xC0, 0x00, 0x20, 0xC3, 0xC0, 0x00, 0x38, 0xC3, 0xC0, 0x00, 0x1C, 0xC3, 0x60, 0x00, 0x0C, 0xC7, 0x30, 0x00, 0x04, 0xFE, 0x3F, 0x00, 0x04, 0xFE, 0xFF, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char á - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3F, 0x00, 0x00, 0x8C, 0x7F, 0x00, 0x20, 0x8E, 0xF7, 0x00, 0x30, 0xC7, 0xC1, 0x00, 0x18, 0xC3, 0xC0, 0x00, 0x1C, 0xC3, 0xC0, 0x00, 0x0C, 0xC3, 0xC0, 0x00, 0x1C, 0xC3, 0x60, 0x00, 0x18, 0xC7, 0x30, 0x00, 0x30, 0xFE, 0x3F, 0x00, 0x20, 0xFE, 0xFF, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char â - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3F, 0x00, 0x00, 0x8C, 0x7F, 0x00, 0x38, 0x8E, 0xF7, 0x00, 0x0C, 0xC7, 0xC1, 0x00, 0x0C, 0xC3, 0xC0, 0x00, 0x0C, 0xC3, 0xC0, 0x00, 0x18, 0xC3, 0xC0, 0x00, 0x30, 0xC3, 0x60, 0x00, 0x30, 0xC7, 0x30, 0x00, 0x38, 0xFE, 0x3F, 0x00, 0x1C, 0xFE, 0xFF, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ã - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3F, 0x00, 0x00, 0x8C, 0x7F, 0x00, 0x00, 0x8E, 0xF7, 0x00, 0x38, 0xC7, 0xC1, 0x00, 0x38, 0xC3, 0xC0, 0x00, 0x00, 0xC3, 0xC0, 0x00, 0x00, 0xC3, 0xC0, 0x00, 0x00, 0xC3, 0x60, 0x00, 0x38, 0xC7, 0x30, 0x00, 0x38, 0xFE, 0x3F, 0x00, 0x38, 0xFE, 0xFF, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ä - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3F, 0x00, 0x00, 0x8C, 0x7F, 0x00, 0x00, 0x8E, 0xF7, 0x00, 0x0C, 0xC7, 0xC1, 0x00, 0x1E, 0xC3, 0xC0, 0x00, 0x33, 0xC3, 0xC0, 0x00, 0x33, 0xC3, 0xC0, 0x00, 0x33, 0xC3, 0x60, 0x00, 0x3F, 0xC7, 0x30, 0x00, 0x1E, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char å - 0x11, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x8C, 0x7F, 0x00, 0x00, 0x8E, 0xFF, 0x00, 0x00, 0xC7, 0xC1, 0x00, 0x00, 0xC3, 0xC0, 0x00, 0x00, 0xC3, 0xC0, 0x00, 0x00, 0xC3, 0x70, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xBE, 0x7D, 0x00, 0x00, 0x87, 0xE1, 0x00, 0x00, 0x83, 0xC1, 0x00, 0x00, 0x83, 0xC1, 0x00, 0x00, 0x87, 0xC1, 0x00, 0x00, 0xFE, 0x71, 0x00, 0x00, 0xFC, 0x31, 0x00, 0x00, 0xE0, 0x01, 0x00, // Code for char æ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0x7E, 0x7E, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x34, 0x00, 0x03, 0xC0, 0x37, 0x00, 0x03, 0xC0, 0x36, 0x00, 0x03, 0xC0, 0x1E, 0x00, 0x07, 0xE0, 0x0C, 0x00, 0x0E, 0x70, 0x00, 0x00, 0x0E, 0x70, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ç - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x04, 0x8E, 0x61, 0x00, 0x0C, 0x87, 0xE1, 0x00, 0x1C, 0x83, 0xC1, 0x00, 0x38, 0x83, 0xC1, 0x00, 0x30, 0x83, 0xC1, 0x00, 0x00, 0x87, 0xC1, 0x00, 0x00, 0x86, 0xE1, 0x00, 0x00, 0xFE, 0x71, 0x00, 0x00, 0xFC, 0x31, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char è - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x8E, 0x61, 0x00, 0x00, 0x87, 0xE1, 0x00, 0x00, 0x83, 0xC1, 0x00, 0x20, 0x83, 0xC1, 0x00, 0x38, 0x83, 0xC1, 0x00, 0x1C, 0x87, 0xC1, 0x00, 0x0C, 0x86, 0xE1, 0x00, 0x04, 0xFE, 0x71, 0x00, 0x04, 0xFC, 0x31, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char é - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x20, 0xFE, 0x7F, 0x00, 0x30, 0x8E, 0x61, 0x00, 0x18, 0x87, 0xE1, 0x00, 0x1C, 0x83, 0xC1, 0x00, 0x0C, 0x83, 0xC1, 0x00, 0x1C, 0x83, 0xC1, 0x00, 0x18, 0x87, 0xC1, 0x00, 0x30, 0x86, 0xE1, 0x00, 0x20, 0xFE, 0x71, 0x00, 0x00, 0xFC, 0x31, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ê - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x38, 0x8E, 0x61, 0x00, 0x38, 0x87, 0xE1, 0x00, 0x00, 0x83, 0xC1, 0x00, 0x00, 0x83, 0xC1, 0x00, 0x00, 0x83, 0xC1, 0x00, 0x38, 0x87, 0xC1, 0x00, 0x38, 0x86, 0xE1, 0x00, 0x38, 0xFE, 0x71, 0x00, 0x00, 0xFC, 0x31, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ë - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x04, 0x03, 0xC0, 0x00, 0x0C, 0x03, 0xC0, 0x00, 0x1C, 0x03, 0xC0, 0x00, 0x38, 0xFF, 0xFF, 0x00, 0x30, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ì - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x20, 0xFF, 0xFF, 0x00, 0x38, 0xFF, 0xFF, 0x00, 0x1C, 0x00, 0xC0, 0x00, 0x0C, 0x00, 0xC0, 0x00, 0x04, 0x00, 0xC0, 0x00, 0x04, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char í - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x20, 0x03, 0xC0, 0x00, 0x30, 0x03, 0xC0, 0x00, 0x18, 0x03, 0xC0, 0x00, 0x1C, 0x03, 0xC0, 0x00, 0x0C, 0xFF, 0xFF, 0x00, 0x1C, 0xFF, 0xFF, 0x00, 0x18, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char î - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x38, 0x03, 0xC0, 0x00, 0x38, 0x03, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ï - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x40, 0xF8, 0x7C, 0x00, 0xC8, 0x1C, 0xE0, 0x00, 0x58, 0x0C, 0xC0, 0x00, 0x78, 0x0C, 0xC0, 0x00, 0x70, 0x0C, 0xC0, 0x00, 0x70, 0x0C, 0xC0, 0x00, 0xF0, 0x0D, 0xC0, 0x00, 0xD0, 0x1F, 0x60, 0x00, 0x18, 0xFF, 0x7C, 0x00, 0x10, 0xFE, 0x3F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ð - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x38, 0xFF, 0xFF, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x38, 0x07, 0x00, 0x00, 0x1C, 0xFE, 0xFF, 0x00, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ñ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0x7E, 0x7E, 0x00, 0x04, 0x06, 0x60, 0x00, 0x0C, 0x03, 0xC0, 0x00, 0x1C, 0x03, 0xC0, 0x00, 0x38, 0x03, 0xC0, 0x00, 0x30, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ò - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0x7E, 0x7E, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x20, 0x03, 0xC0, 0x00, 0x38, 0x03, 0xC0, 0x00, 0x1C, 0x03, 0xE0, 0x00, 0x0C, 0x06, 0x60, 0x00, 0x04, 0xFE, 0x7F, 0x00, 0x04, 0xFC, 0x3F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ó - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x20, 0x7E, 0x7E, 0x00, 0x30, 0x06, 0x60, 0x00, 0x18, 0x03, 0xC0, 0x00, 0x1C, 0x03, 0xC0, 0x00, 0x0C, 0x03, 0xC0, 0x00, 0x1C, 0x03, 0xC0, 0x00, 0x18, 0x03, 0xE0, 0x00, 0x30, 0x06, 0x60, 0x00, 0x20, 0xFE, 0x7F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ô - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x38, 0x7E, 0x7E, 0x00, 0x0C, 0x06, 0x60, 0x00, 0x0C, 0x03, 0xC0, 0x00, 0x0C, 0x03, 0xC0, 0x00, 0x18, 0x03, 0xC0, 0x00, 0x30, 0x03, 0xC0, 0x00, 0x30, 0x03, 0xE0, 0x00, 0x38, 0x06, 0x60, 0x00, 0x1C, 0xFE, 0x7F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char õ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0x7E, 0x7E, 0x00, 0x38, 0x06, 0x60, 0x00, 0x38, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x38, 0x03, 0xE0, 0x00, 0x38, 0x06, 0x60, 0x00, 0x38, 0xFE, 0x7F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ö - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x63, 0x1C, 0x00, 0x80, 0x63, 0x1C, 0x00, 0x80, 0x63, 0x1C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ÷ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xDF, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x1E, 0x78, 0x00, 0x00, 0x06, 0x7C, 0x00, 0x00, 0x03, 0xC6, 0x00, 0x00, 0x03, 0xC3, 0x00, 0x00, 0x83, 0xC1, 0x00, 0x00, 0xC3, 0xC0, 0x00, 0x00, 0x63, 0xC0, 0x00, 0x00, 0x3F, 0x60, 0x00, 0x00, 0x1E, 0x78, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFB, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ø - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x04, 0x00, 0xE0, 0x00, 0x0C, 0x00, 0xC0, 0x00, 0x1C, 0x00, 0xC0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ù - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x1C, 0x00, 0xC0, 0x00, 0x0C, 0x00, 0x60, 0x00, 0x04, 0x00, 0x30, 0x00, 0x04, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ú - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x20, 0xFF, 0x7F, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x18, 0x00, 0xC0, 0x00, 0x1C, 0x00, 0xC0, 0x00, 0x0C, 0x00, 0xC0, 0x00, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x30, 0x00, 0x30, 0x00, 0x20, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char û - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x38, 0x00, 0xE0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x38, 0x00, 0x30, 0x00, 0x38, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ü - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x30, 0x00, 0x3F, 0x00, 0x30, 0x00, 0xFC, 0x01, 0x30, 0x00, 0xE0, 0x07, 0x38, 0x00, 0x00, 0x3F, 0x1C, 0x00, 0x00, 0xFC, 0x0F, 0x20, 0x00, 0xE0, 0x07, 0x38, 0x00, 0xF8, 0x01, 0x1C, 0x00, 0x3F, 0x00, 0x0C, 0xE0, 0x07, 0x00, 0x04, 0xFC, 0x01, 0x00, 0x04, 0x3F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ý - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x3F, 0x00, 0x1C, 0x38, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char þ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x30, 0x00, 0x3F, 0x00, 0x30, 0x00, 0xFC, 0x01, 0x30, 0x38, 0xE0, 0x07, 0x38, 0x38, 0x00, 0x3F, 0x1C, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x38, 0x00, 0x3F, 0x00, 0x38, 0xE0, 0x07, 0x00, 0x38, 0xFC, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ -}; - -const struct GDS_FontDef Font_liberation_mono_17x30 = { - Liberation_Mono17x30, - 17, - 30, - ' ', - '\xFF', - true -}; diff --git a/components/display/fonts/font_liberation_mono_9x15.c b/components/display/fonts/font_liberation_mono_9x15.c deleted file mode 100644 index e8d4be4f..00000000 --- a/components/display/fonts/font_liberation_mono_9x15.c +++ /dev/null @@ -1,247 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Liberation_Mono9x15 -//GLCD FontSize : 9 x 15 - -static const uint8_t Liberation_Mono9x15[ ] = { - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x07, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x09, 0x00, 0x01, 0x20, 0x0D, 0xE0, 0x03, 0x3C, 0x01, 0x20, 0x01, 0x20, 0x0F, 0xF8, 0x01, 0x24, 0x01, 0x20, 0x00, // Code for char # - 0x08, 0x00, 0x00, 0x38, 0x06, 0x6C, 0x0C, 0x44, 0x08, 0xFE, 0x1F, 0x44, 0x08, 0x8C, 0x08, 0x98, 0x07, 0x00, 0x00, // Code for char $ - 0x09, 0x38, 0x00, 0x44, 0x08, 0x44, 0x06, 0x7C, 0x01, 0xC0, 0x00, 0xA0, 0x0F, 0x98, 0x08, 0x84, 0x08, 0x00, 0x07, // Code for char % - 0x09, 0x00, 0x03, 0x80, 0x0F, 0x78, 0x08, 0xC4, 0x08, 0x24, 0x0B, 0x24, 0x04, 0x18, 0x0F, 0x80, 0x08, 0x00, 0x08, // Code for char & - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x1F, 0x0C, 0x30, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x0C, 0x30, 0xF8, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x38, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x08, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char + - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x80, 0x03, 0xE0, 0x00, 0x38, 0x00, 0x0C, 0x00, 0x02, 0x00, 0x00, 0x00, // Code for char / - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x18, 0x06, 0x04, 0x08, 0xC4, 0x08, 0x04, 0x08, 0x18, 0x06, 0xF0, 0x03, 0x00, 0x00, // Code for char 0 - 0x08, 0x00, 0x00, 0x10, 0x08, 0x10, 0x08, 0x08, 0x08, 0xFC, 0x0F, 0xFC, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, // Code for char 1 - 0x08, 0x00, 0x00, 0x10, 0x0C, 0x18, 0x0E, 0x04, 0x0B, 0x84, 0x09, 0x84, 0x08, 0x7C, 0x08, 0x38, 0x08, 0x00, 0x00, // Code for char 2 - 0x08, 0x00, 0x00, 0x10, 0x06, 0x18, 0x0C, 0x44, 0x08, 0x44, 0x08, 0x44, 0x08, 0xBC, 0x0C, 0x98, 0x07, 0x00, 0x00, // Code for char 3 - 0x08, 0x00, 0x00, 0x80, 0x01, 0x40, 0x01, 0x30, 0x01, 0x18, 0x01, 0x04, 0x01, 0xFC, 0x0F, 0x00, 0x01, 0x00, 0x00, // Code for char 4 - 0x08, 0x00, 0x00, 0x78, 0x06, 0x7C, 0x0C, 0x24, 0x08, 0x24, 0x08, 0x24, 0x08, 0x64, 0x04, 0xC0, 0x03, 0x00, 0x00, // Code for char 5 - 0x08, 0x00, 0x00, 0xE0, 0x03, 0xD8, 0x07, 0x24, 0x08, 0x24, 0x08, 0x24, 0x08, 0x6C, 0x0C, 0xC8, 0x07, 0x00, 0x00, // Code for char 6 - 0x08, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x0E, 0xC4, 0x03, 0x64, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x00, 0x00, // Code for char 7 - 0x08, 0x00, 0x00, 0x98, 0x07, 0xBC, 0x0C, 0x44, 0x08, 0x44, 0x08, 0x44, 0x08, 0xBC, 0x0C, 0x98, 0x07, 0x00, 0x00, // Code for char 8 - 0x08, 0x00, 0x00, 0x70, 0x04, 0xDC, 0x0D, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0xD8, 0x06, 0xF0, 0x03, 0x00, 0x00, // Code for char 9 - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x08, 0x00, 0x00, 0x40, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xB0, 0x01, 0x10, 0x01, 0x10, 0x01, 0x08, 0x02, 0x00, 0x00, // Code for char < - 0x08, 0x00, 0x00, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x00, 0x00, // Code for char = - 0x08, 0x00, 0x00, 0x08, 0x02, 0x10, 0x01, 0x10, 0x01, 0xB0, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char > - 0x08, 0x00, 0x00, 0x18, 0x00, 0x0C, 0x00, 0x04, 0x09, 0x84, 0x09, 0xC4, 0x00, 0x6C, 0x00, 0x38, 0x00, 0x00, 0x00, // Code for char ? - 0x09, 0xC0, 0x03, 0x38, 0x1C, 0xC4, 0x13, 0x32, 0x24, 0x12, 0x24, 0x92, 0x23, 0x76, 0x14, 0x0C, 0x16, 0xF0, 0x01, // Code for char @ - 0x09, 0x00, 0x08, 0x00, 0x0F, 0xE0, 0x01, 0x38, 0x01, 0x04, 0x01, 0x3C, 0x01, 0xE0, 0x01, 0x00, 0x0F, 0x00, 0x08, // Code for char A - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x44, 0x08, 0x44, 0x08, 0x44, 0x08, 0xBC, 0x0C, 0x98, 0x07, 0x00, 0x00, // Code for char B - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x18, 0x06, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x0C, 0x0C, 0x18, 0x06, 0x00, 0x00, // Code for char C - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x18, 0x06, 0xF0, 0x03, 0x00, 0x00, // Code for char D - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x44, 0x08, 0x44, 0x08, 0x44, 0x08, 0x44, 0x08, 0x04, 0x08, 0x00, 0x00, // Code for char E - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x00, 0x00, // Code for char F - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x18, 0x06, 0x04, 0x08, 0x04, 0x08, 0x84, 0x08, 0x88, 0x08, 0x90, 0x07, 0x00, 0x00, // Code for char G - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x00, 0x00, // Code for char H - 0x08, 0x00, 0x00, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0xFC, 0x0F, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x00, 0x00, // Code for char I - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0E, 0x00, 0x08, 0x04, 0x08, 0x04, 0x0C, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x09, 0x00, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x40, 0x00, 0xE0, 0x00, 0x90, 0x01, 0x0C, 0x06, 0x04, 0x0C, 0x00, 0x08, // Code for char K - 0x08, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, // Code for char L - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0x1C, 0x00, 0xE0, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x1C, 0x00, 0xFC, 0x0F, 0x00, 0x00, // Code for char M - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x07, 0x00, 0x0C, 0xFC, 0x0F, 0x00, 0x00, // Code for char N - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x18, 0x06, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x18, 0x06, 0xF0, 0x03, 0x00, 0x00, // Code for char O - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0xCC, 0x00, 0x78, 0x00, 0x00, 0x00, // Code for char P - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x18, 0x06, 0x04, 0x08, 0x04, 0x18, 0x04, 0x78, 0x18, 0x46, 0xF0, 0x43, 0x00, 0x00, // Code for char Q - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x44, 0x00, 0x44, 0x00, 0xC4, 0x01, 0x6C, 0x07, 0x38, 0x0C, 0x00, 0x00, // Code for char R - 0x08, 0x00, 0x00, 0x38, 0x06, 0x6C, 0x0C, 0x44, 0x08, 0x44, 0x08, 0xC4, 0x08, 0x8C, 0x0C, 0x98, 0x07, 0x00, 0x00, // Code for char S - 0x08, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0xFC, 0x0F, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, // Code for char T - 0x08, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0E, 0xFC, 0x07, 0x00, 0x00, // Code for char U - 0x09, 0x04, 0x00, 0x3C, 0x00, 0xE0, 0x01, 0x00, 0x07, 0x00, 0x08, 0x00, 0x07, 0xE0, 0x01, 0x3C, 0x00, 0x04, 0x00, // Code for char V - 0x09, 0x1C, 0x00, 0xF8, 0x0F, 0x00, 0x0C, 0xC0, 0x03, 0x20, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0xF8, 0x0F, 0x1C, 0x00, // Code for char W - 0x08, 0x00, 0x00, 0x04, 0x0C, 0x18, 0x06, 0xB0, 0x01, 0xC0, 0x00, 0xB0, 0x01, 0x18, 0x06, 0x04, 0x0C, 0x00, 0x00, // Code for char X - 0x08, 0x00, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, // Code for char Y - 0x08, 0x00, 0x00, 0x04, 0x0C, 0x04, 0x0B, 0x84, 0x09, 0xC4, 0x08, 0x34, 0x08, 0x1C, 0x08, 0x0C, 0x08, 0x00, 0x00, // Code for char Z - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x08, 0x00, 0x00, 0x02, 0x00, 0x0C, 0x00, 0x38, 0x00, 0xE0, 0x00, 0x80, 0x03, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, // Code for char BackSlash - 0x06, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x08, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x18, 0x00, 0x04, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x00, 0x01, 0x00, 0x00, // Code for char ^ - 0x09, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, // Code for char _ - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x09, 0x00, 0x00, 0x20, 0x07, 0xB0, 0x0D, 0x90, 0x08, 0x90, 0x08, 0x90, 0x04, 0xE0, 0x0F, 0x00, 0x08, 0x00, 0x08, // Code for char a - 0x08, 0x00, 0x00, 0xFE, 0x0F, 0xFE, 0x0F, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x70, 0x0E, 0xE0, 0x07, 0x00, 0x00, // Code for char b - 0x08, 0x00, 0x00, 0xC0, 0x03, 0x60, 0x06, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x30, 0x0C, 0x20, 0x04, 0x00, 0x00, // Code for char c - 0x08, 0x00, 0x00, 0xE0, 0x07, 0x70, 0x0E, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0xFE, 0x0F, 0xFE, 0x0F, 0x00, 0x00, // Code for char d - 0x08, 0x00, 0x00, 0xC0, 0x03, 0xA0, 0x06, 0x90, 0x08, 0x90, 0x08, 0x90, 0x08, 0xB0, 0x0C, 0xE0, 0x04, 0x00, 0x00, // Code for char e - 0x08, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0xFC, 0x0F, 0x16, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x00, 0x00, // Code for char f - 0x08, 0x00, 0x00, 0xE0, 0x07, 0x70, 0x6E, 0x10, 0x48, 0x10, 0x48, 0x10, 0x48, 0xF0, 0x7F, 0xF0, 0x1F, 0x00, 0x00, // Code for char g - 0x08, 0x00, 0x00, 0xFE, 0x0F, 0xFE, 0x0F, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0xF0, 0x0F, 0xE0, 0x0F, 0x00, 0x00, // Code for char h - 0x08, 0x00, 0x00, 0x00, 0x08, 0x10, 0x08, 0x10, 0x08, 0xF2, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, // Code for char i - 0x06, 0x00, 0x00, 0x00, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x60, 0xF2, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x08, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x80, 0x01, 0xC0, 0x01, 0x60, 0x03, 0x30, 0x0C, 0x10, 0x08, 0x00, 0x00, // Code for char k - 0x08, 0x00, 0x00, 0x00, 0x08, 0x02, 0x08, 0x02, 0x08, 0xFE, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, // Code for char l - 0x08, 0x00, 0x00, 0xF0, 0x0F, 0x10, 0x00, 0x10, 0x00, 0xF0, 0x0F, 0x10, 0x00, 0x10, 0x00, 0xF0, 0x0F, 0x00, 0x00, // Code for char m - 0x08, 0x00, 0x00, 0xF0, 0x0F, 0xF0, 0x0F, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0xF0, 0x0F, 0xE0, 0x0F, 0x00, 0x00, // Code for char n - 0x08, 0x00, 0x00, 0xC0, 0x03, 0x70, 0x0E, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x70, 0x06, 0xE0, 0x03, 0x00, 0x00, // Code for char o - 0x08, 0x00, 0x00, 0xF0, 0x7F, 0xF0, 0x7F, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x70, 0x0E, 0xE0, 0x07, 0x00, 0x00, // Code for char p - 0x08, 0x00, 0x00, 0xE0, 0x07, 0x70, 0x0E, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0xF0, 0x7F, 0xF0, 0x7F, 0x00, 0x00, // Code for char q - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0xC0, 0x00, 0x30, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, // Code for char r - 0x08, 0x00, 0x00, 0x00, 0x04, 0xF0, 0x0C, 0x90, 0x08, 0x90, 0x08, 0x10, 0x09, 0x30, 0x0F, 0x00, 0x06, 0x00, 0x00, // Code for char s - 0x07, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0xFC, 0x0F, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x08, 0x00, 0x00, 0xF0, 0x03, 0xF0, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0xF0, 0x0F, 0xF0, 0x0F, 0x00, 0x00, // Code for char u - 0x08, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x01, 0x00, 0x0F, 0x00, 0x08, 0x00, 0x07, 0xE0, 0x01, 0x30, 0x00, 0x00, 0x00, // Code for char v - 0x09, 0x30, 0x00, 0xF0, 0x0F, 0x00, 0x0C, 0x80, 0x03, 0x40, 0x00, 0x80, 0x07, 0x00, 0x08, 0xF0, 0x0F, 0x30, 0x00, // Code for char w - 0x08, 0x00, 0x00, 0x10, 0x08, 0x30, 0x04, 0xC0, 0x03, 0x80, 0x01, 0xC0, 0x03, 0x30, 0x0C, 0x10, 0x08, 0x00, 0x00, // Code for char x - 0x08, 0x00, 0x00, 0x30, 0x40, 0xC0, 0x41, 0x00, 0x67, 0x00, 0x18, 0x00, 0x07, 0xC0, 0x01, 0x30, 0x00, 0x00, 0x00, // Code for char y - 0x08, 0x00, 0x00, 0x10, 0x08, 0x10, 0x0E, 0x10, 0x0B, 0x90, 0x09, 0x50, 0x08, 0x30, 0x08, 0x10, 0x08, 0x00, 0x00, // Code for char z - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x02, 0xFE, 0x7E, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x00, 0x00, // Code for char { - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x07, 0x00, 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x7E, 0x7F, 0x40, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x08, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, // Code for char ~ - 0x03, 0xF0, 0x1F, 0x10, 0x10, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char †- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ - 0x08, 0x00, 0x00, 0xE0, 0x01, 0x30, 0x03, 0x08, 0x04, 0x0C, 0x0C, 0x08, 0x04, 0x18, 0x06, 0x10, 0x02, 0x00, 0x00, // Code for char ¢ - 0x09, 0x40, 0x08, 0x40, 0x0C, 0xF8, 0x0F, 0x44, 0x08, 0x44, 0x08, 0x44, 0x08, 0x0C, 0x08, 0x08, 0x0C, 0x00, 0x04, // Code for char £ - 0x08, 0x00, 0x00, 0xD0, 0x05, 0x60, 0x07, 0x10, 0x04, 0x10, 0x04, 0x10, 0x04, 0x60, 0x03, 0xD0, 0x05, 0x00, 0x00, // Code for char ¤ - 0x08, 0x00, 0x00, 0x8C, 0x02, 0xB8, 0x02, 0xE0, 0x02, 0x80, 0x0F, 0xE0, 0x02, 0x98, 0x02, 0x8C, 0x02, 0x00, 0x00, // Code for char ¥ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ - 0x08, 0x00, 0x00, 0x40, 0x08, 0xEE, 0x19, 0x12, 0x11, 0x12, 0x11, 0x12, 0x13, 0xA6, 0x1B, 0xE4, 0x0C, 0x00, 0x00, // Code for char § - 0x07, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ - 0x09, 0xF0, 0x01, 0x0C, 0x06, 0xF6, 0x0D, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x16, 0x0D, 0x0C, 0x06, 0xF0, 0x01, // Code for char © - 0x07, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x94, 0x00, 0x94, 0x00, 0x5C, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª - 0x08, 0x00, 0x00, 0x80, 0x00, 0x60, 0x03, 0x30, 0x06, 0x90, 0x04, 0xC0, 0x01, 0x20, 0x02, 0x10, 0x04, 0x00, 0x00, // Code for char « - 0x08, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xC0, 0x03, 0x00, 0x00, // Code for char ¬ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ - 0x09, 0xF0, 0x01, 0x0C, 0x06, 0xFE, 0x0F, 0x4A, 0x08, 0x4A, 0x08, 0xCA, 0x09, 0x36, 0x0E, 0x0C, 0x06, 0xF0, 0x01, // Code for char ® - 0x09, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, // Code for char ¯ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x24, 0x00, 0x24, 0x00, 0x24, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° - 0x08, 0x00, 0x00, 0x40, 0x08, 0x40, 0x08, 0x40, 0x08, 0xF8, 0x0B, 0x40, 0x08, 0x40, 0x08, 0x40, 0x08, 0x00, 0x00, // Code for char ± - 0x07, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0xC4, 0x00, 0xA4, 0x00, 0x94, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² - 0x07, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x84, 0x00, 0x94, 0x00, 0x94, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ - 0x08, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x06, 0xF0, 0x0F, 0x00, 0x00, // Code for char µ - 0x08, 0x00, 0x00, 0x38, 0x00, 0x7C, 0x00, 0x7C, 0x00, 0xFC, 0x3F, 0x04, 0x00, 0xFC, 0x3F, 0x04, 0x00, 0x00, 0x00, // Code for char ¶ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · - 0x04, 0x00, 0x00, 0x00, 0x50, 0x00, 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x88, 0x00, 0xFC, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º - 0x08, 0x00, 0x00, 0x10, 0x04, 0x20, 0x02, 0xC0, 0x01, 0x90, 0x04, 0x30, 0x06, 0x60, 0x03, 0x80, 0x00, 0x00, 0x00, // Code for char » - 0x09, 0x88, 0x00, 0xFC, 0x0C, 0x80, 0x03, 0xC0, 0x00, 0x30, 0x06, 0x0C, 0x05, 0xC0, 0x04, 0xC0, 0x0F, 0x00, 0x04, // Code for char ¼ - 0x09, 0x88, 0x00, 0xFC, 0x0C, 0x80, 0x03, 0xC0, 0x00, 0x30, 0x00, 0x8C, 0x0C, 0x40, 0x0A, 0x40, 0x0B, 0x80, 0x08, // Code for char ½ - 0x09, 0x48, 0x00, 0x94, 0x00, 0x94, 0x0C, 0x68, 0x03, 0xC0, 0x06, 0x30, 0x05, 0xCC, 0x04, 0xC0, 0x0F, 0x00, 0x04, // Code for char ¾ - 0x08, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x36, 0x00, 0x23, 0x90, 0x21, 0x90, 0x20, 0x00, 0x30, 0x00, 0x18, 0x00, 0x00, // Code for char ¿ - 0x09, 0x00, 0x08, 0x00, 0x0F, 0xE0, 0x01, 0x38, 0x01, 0x04, 0x01, 0x3D, 0x01, 0xE0, 0x01, 0x00, 0x0F, 0x00, 0x08, // Code for char À - 0x09, 0x00, 0x08, 0x00, 0x0F, 0xE0, 0x01, 0x38, 0x01, 0x05, 0x01, 0x3C, 0x01, 0xE0, 0x01, 0x00, 0x0F, 0x00, 0x08, // Code for char à - 0x09, 0x00, 0x08, 0x00, 0x0F, 0xE1, 0x01, 0x39, 0x01, 0x04, 0x01, 0x3D, 0x01, 0xE1, 0x01, 0x00, 0x0F, 0x00, 0x08, // Code for char  - 0x09, 0x00, 0x08, 0x00, 0x0F, 0xE1, 0x01, 0x38, 0x01, 0x05, 0x01, 0x3D, 0x01, 0xE1, 0x01, 0x00, 0x0F, 0x00, 0x08, // Code for char à - 0x09, 0x00, 0x08, 0x00, 0x0F, 0xE1, 0x01, 0x39, 0x01, 0x04, 0x01, 0x3D, 0x01, 0xE1, 0x01, 0x00, 0x0F, 0x00, 0x08, // Code for char Ä - 0x09, 0x00, 0x08, 0x00, 0x0F, 0xE0, 0x01, 0x3F, 0x01, 0x05, 0x01, 0x3F, 0x01, 0xE0, 0x01, 0x00, 0x0F, 0x00, 0x08, // Code for char Å - 0x09, 0x00, 0x08, 0x00, 0x07, 0xE0, 0x01, 0x1C, 0x01, 0x04, 0x01, 0xFC, 0x0F, 0x44, 0x08, 0x44, 0x08, 0x00, 0x08, // Code for char Æ - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x18, 0x06, 0x04, 0x08, 0x04, 0x58, 0x04, 0x58, 0x0C, 0x2C, 0x18, 0x06, 0x00, 0x00, // Code for char Ç - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x44, 0x08, 0x44, 0x08, 0x45, 0x08, 0x44, 0x08, 0x04, 0x08, 0x00, 0x00, // Code for char È - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x44, 0x08, 0x45, 0x08, 0x44, 0x08, 0x44, 0x08, 0x04, 0x08, 0x00, 0x00, // Code for char É - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFD, 0x0F, 0x45, 0x08, 0x44, 0x08, 0x45, 0x08, 0x45, 0x08, 0x04, 0x08, 0x00, 0x00, // Code for char Ê - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFD, 0x0F, 0x45, 0x08, 0x44, 0x08, 0x45, 0x08, 0x45, 0x08, 0x04, 0x08, 0x00, 0x00, // Code for char Ë - 0x08, 0x00, 0x00, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0xFC, 0x0F, 0x05, 0x08, 0x04, 0x08, 0x04, 0x08, 0x00, 0x00, // Code for char Ì - 0x08, 0x00, 0x00, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0xFD, 0x0F, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x00, 0x00, // Code for char à - 0x08, 0x00, 0x00, 0x04, 0x08, 0x05, 0x08, 0x05, 0x08, 0xFC, 0x0F, 0x05, 0x08, 0x05, 0x08, 0x04, 0x08, 0x00, 0x00, // Code for char Î - 0x08, 0x00, 0x00, 0x04, 0x08, 0x05, 0x08, 0x05, 0x08, 0xFC, 0x0F, 0x05, 0x08, 0x05, 0x08, 0x04, 0x08, 0x00, 0x00, // Code for char à - 0x08, 0x40, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x44, 0x08, 0x44, 0x08, 0x04, 0x08, 0x18, 0x06, 0xF0, 0x03, 0x00, 0x00, // Code for char à - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0x0D, 0x00, 0x30, 0x00, 0xC1, 0x00, 0x01, 0x07, 0x01, 0x0C, 0xFC, 0x0F, 0x00, 0x00, // Code for char Ñ - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x18, 0x06, 0x04, 0x08, 0x04, 0x08, 0x05, 0x08, 0x18, 0x06, 0xF0, 0x03, 0x00, 0x00, // Code for char Ò - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x18, 0x06, 0x04, 0x08, 0x05, 0x08, 0x04, 0x08, 0x18, 0x06, 0xF0, 0x03, 0x00, 0x00, // Code for char Ó - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x19, 0x06, 0x05, 0x08, 0x04, 0x08, 0x05, 0x08, 0x19, 0x06, 0xF0, 0x03, 0x00, 0x00, // Code for char Ô - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x19, 0x06, 0x04, 0x08, 0x05, 0x08, 0x05, 0x08, 0x19, 0x06, 0xF0, 0x03, 0x00, 0x00, // Code for char Õ - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x19, 0x06, 0x05, 0x08, 0x04, 0x08, 0x05, 0x08, 0x19, 0x06, 0xF0, 0x03, 0x00, 0x00, // Code for char Ö - 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xA0, 0x00, 0x40, 0x00, 0xA0, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char × - 0x08, 0x00, 0x00, 0xF0, 0x0F, 0x18, 0x06, 0x04, 0x09, 0xC4, 0x08, 0x24, 0x08, 0x18, 0x06, 0xFC, 0x03, 0x00, 0x00, // Code for char Ø - 0x08, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x08, 0x01, 0x08, 0x00, 0x0E, 0xFC, 0x07, 0x00, 0x00, // Code for char Ù - 0x08, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x0E, 0x00, 0x08, 0x01, 0x08, 0x00, 0x08, 0x00, 0x0E, 0xFC, 0x07, 0x00, 0x00, // Code for char Ú - 0x08, 0x00, 0x00, 0xFC, 0x07, 0x01, 0x0E, 0x01, 0x08, 0x00, 0x08, 0x01, 0x08, 0x01, 0x0E, 0xFC, 0x07, 0x00, 0x00, // Code for char Û - 0x08, 0x00, 0x00, 0xFC, 0x07, 0x01, 0x0E, 0x01, 0x08, 0x00, 0x08, 0x01, 0x08, 0x01, 0x0E, 0xFC, 0x07, 0x00, 0x00, // Code for char Ü - 0x08, 0x00, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x01, 0x0F, 0xC0, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, // Code for char à - 0x08, 0x00, 0x00, 0xFC, 0x0F, 0xFC, 0x0F, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x30, 0x03, 0xE0, 0x01, 0x00, 0x00, // Code for char Þ - 0x09, 0x00, 0x00, 0xFC, 0x0F, 0x06, 0x00, 0x02, 0x00, 0x02, 0x08, 0xE2, 0x08, 0x9E, 0x08, 0x00, 0x0F, 0x00, 0x02, // Code for char ß - 0x09, 0x00, 0x00, 0x20, 0x07, 0xB2, 0x0D, 0x92, 0x08, 0x94, 0x08, 0x90, 0x04, 0xE0, 0x0F, 0x00, 0x08, 0x00, 0x08, // Code for char à - 0x09, 0x00, 0x00, 0x20, 0x07, 0xB0, 0x0D, 0x90, 0x08, 0x94, 0x08, 0x92, 0x04, 0xE2, 0x0F, 0x00, 0x08, 0x00, 0x08, // Code for char á - 0x09, 0x00, 0x00, 0x20, 0x07, 0xB4, 0x0D, 0x96, 0x08, 0x92, 0x08, 0x96, 0x04, 0xE4, 0x0F, 0x00, 0x08, 0x00, 0x08, // Code for char â - 0x09, 0x00, 0x00, 0x20, 0x07, 0xB6, 0x0D, 0x92, 0x08, 0x96, 0x08, 0x94, 0x04, 0xE6, 0x0F, 0x00, 0x08, 0x00, 0x08, // Code for char ã - 0x09, 0x00, 0x00, 0x20, 0x07, 0xB6, 0x0D, 0x96, 0x08, 0x90, 0x08, 0x96, 0x04, 0xE6, 0x0F, 0x00, 0x08, 0x00, 0x08, // Code for char ä - 0x09, 0x00, 0x00, 0x20, 0x07, 0xB0, 0x0D, 0x97, 0x08, 0x95, 0x08, 0x97, 0x04, 0xE0, 0x0F, 0x00, 0x08, 0x00, 0x08, // Code for char å - 0x09, 0x00, 0x07, 0xB0, 0x0D, 0x90, 0x08, 0x90, 0x04, 0xE0, 0x07, 0x90, 0x08, 0x90, 0x08, 0xB0, 0x0C, 0xE0, 0x04, // Code for char æ - 0x08, 0x00, 0x00, 0xC0, 0x03, 0x60, 0x06, 0x10, 0x08, 0x10, 0x58, 0x10, 0x58, 0x30, 0x2C, 0x20, 0x04, 0x00, 0x00, // Code for char ç - 0x08, 0x00, 0x00, 0xC0, 0x03, 0xA0, 0x06, 0x92, 0x08, 0x92, 0x08, 0x94, 0x08, 0xB0, 0x0C, 0xE0, 0x04, 0x00, 0x00, // Code for char è - 0x08, 0x00, 0x00, 0xC0, 0x03, 0xA0, 0x06, 0x90, 0x08, 0x94, 0x08, 0x92, 0x08, 0xB2, 0x0C, 0xE0, 0x04, 0x00, 0x00, // Code for char é - 0x08, 0x00, 0x00, 0xC0, 0x03, 0xA4, 0x06, 0x96, 0x08, 0x92, 0x08, 0x96, 0x08, 0xB4, 0x0C, 0xE0, 0x04, 0x00, 0x00, // Code for char ê - 0x08, 0x00, 0x00, 0xC0, 0x03, 0xA6, 0x06, 0x96, 0x08, 0x90, 0x08, 0x96, 0x08, 0xB6, 0x0C, 0xE0, 0x04, 0x00, 0x00, // Code for char ë - 0x08, 0x00, 0x00, 0x00, 0x08, 0x12, 0x08, 0x12, 0x08, 0xF4, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, // Code for char ì - 0x08, 0x00, 0x00, 0x00, 0x08, 0x10, 0x08, 0x10, 0x08, 0xF4, 0x0F, 0x02, 0x08, 0x02, 0x08, 0x00, 0x08, 0x00, 0x00, // Code for char í - 0x08, 0x00, 0x00, 0x04, 0x08, 0x16, 0x08, 0x12, 0x08, 0xF6, 0x0F, 0x04, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, // Code for char î - 0x08, 0x00, 0x00, 0x00, 0x08, 0x16, 0x08, 0x16, 0x08, 0xF0, 0x0F, 0x06, 0x08, 0x06, 0x08, 0x00, 0x08, 0x00, 0x00, // Code for char ï - 0x08, 0x00, 0x00, 0xC0, 0x07, 0x68, 0x0C, 0x26, 0x08, 0x24, 0x08, 0x2C, 0x08, 0x72, 0x0C, 0xE0, 0x07, 0x00, 0x00, // Code for char ð - 0x08, 0x00, 0x00, 0xF0, 0x0F, 0xF6, 0x0F, 0x12, 0x00, 0x16, 0x00, 0x14, 0x00, 0xF6, 0x0F, 0xE0, 0x0F, 0x00, 0x00, // Code for char ñ - 0x08, 0x00, 0x00, 0xC0, 0x03, 0x70, 0x0E, 0x12, 0x08, 0x12, 0x08, 0x14, 0x08, 0x70, 0x06, 0xE0, 0x03, 0x00, 0x00, // Code for char ò - 0x08, 0x00, 0x00, 0xC0, 0x03, 0x70, 0x0E, 0x10, 0x08, 0x14, 0x08, 0x12, 0x08, 0x72, 0x06, 0xE0, 0x03, 0x00, 0x00, // Code for char ó - 0x08, 0x00, 0x00, 0xC0, 0x03, 0x74, 0x0E, 0x16, 0x08, 0x12, 0x08, 0x16, 0x08, 0x74, 0x06, 0xE0, 0x03, 0x00, 0x00, // Code for char ô - 0x08, 0x00, 0x00, 0xC0, 0x03, 0x76, 0x0E, 0x12, 0x08, 0x16, 0x08, 0x14, 0x08, 0x76, 0x06, 0xE0, 0x03, 0x00, 0x00, // Code for char õ - 0x08, 0x00, 0x00, 0xC0, 0x03, 0x76, 0x0E, 0x16, 0x08, 0x10, 0x08, 0x16, 0x08, 0x76, 0x06, 0xE0, 0x03, 0x00, 0x00, // Code for char ö - 0x08, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x48, 0x02, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, // Code for char ÷ - 0x08, 0x00, 0x00, 0xE0, 0x0F, 0x30, 0x0C, 0x10, 0x0A, 0x90, 0x09, 0x50, 0x08, 0x30, 0x0C, 0xF0, 0x07, 0x00, 0x00, // Code for char ø - 0x08, 0x00, 0x00, 0xF0, 0x03, 0xF0, 0x0F, 0x02, 0x08, 0x02, 0x08, 0x04, 0x08, 0xF0, 0x0F, 0xF0, 0x0F, 0x00, 0x00, // Code for char ù - 0x08, 0x00, 0x00, 0xF0, 0x03, 0xF0, 0x0F, 0x00, 0x08, 0x04, 0x08, 0x02, 0x08, 0xF2, 0x0F, 0xF0, 0x0F, 0x00, 0x00, // Code for char ú - 0x08, 0x00, 0x00, 0xF0, 0x03, 0xF4, 0x0F, 0x06, 0x08, 0x02, 0x08, 0x06, 0x08, 0xF4, 0x0F, 0xF0, 0x0F, 0x00, 0x00, // Code for char û - 0x08, 0x00, 0x00, 0xF0, 0x03, 0xF6, 0x0F, 0x06, 0x08, 0x00, 0x08, 0x06, 0x08, 0xF6, 0x0F, 0xF0, 0x0F, 0x00, 0x00, // Code for char ü - 0x08, 0x00, 0x00, 0x30, 0x40, 0xC0, 0x41, 0x00, 0x67, 0x04, 0x18, 0x02, 0x07, 0xC2, 0x01, 0x30, 0x00, 0x00, 0x00, // Code for char ý - 0x08, 0x00, 0x00, 0xFE, 0x7F, 0xFE, 0x7F, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x70, 0x0E, 0xE0, 0x07, 0x00, 0x00, // Code for char þ - 0x08, 0x00, 0x00, 0x30, 0x40, 0xC6, 0x41, 0x06, 0x67, 0x00, 0x18, 0x06, 0x07, 0xC6, 0x01, 0x30, 0x00, 0x00, 0x00 // Code for char ÿ -}; - -const struct GDS_FontDef Font_liberation_mono_9x15 = { - Liberation_Mono9x15, - 9, - 15, - ' ', - '\xFF', - true -}; diff --git a/components/display/fonts/font_line_1.c b/components/display/fonts/font_line_1.c deleted file mode 100644 index 7f967418..00000000 --- a/components/display/fonts/font_line_1.c +++ /dev/null @@ -1,224 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Square721_BT11x14 -//GLCD FontSize : 11 x 14 - -static const uint8_t Square721_BT11x14[] = { - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x02, 0x00, 0x00, 0xF8, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x03, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x08, 0x00, 0x00, 0x00, 0x01, 0x40, 0x07, 0xE0, 0x01, 0x58, 0x07, 0xC0, 0x01, 0x78, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # - 0x07, 0x30, 0x03, 0x48, 0x04, 0x48, 0x04, 0xFC, 0x0F, 0x48, 0x04, 0x48, 0x04, 0x98, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ - 0x09, 0xF8, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF8, 0x07, 0xE0, 0x00, 0xD8, 0x07, 0x40, 0x04, 0x40, 0x04, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char % - 0x08, 0x00, 0x00, 0x80, 0x03, 0x78, 0x04, 0x48, 0x04, 0xC8, 0x04, 0x08, 0x05, 0x98, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & - 0x02, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x03, 0x00, 0x00, 0xF8, 0x07, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x02, 0x08, 0x04, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x06, 0x00, 0x00, 0x10, 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x08, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xF0, 0x07, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + - 0x02, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x04, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x80, 0x03, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 - 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x04, 0x08, 0x04, 0xF8, 0x07, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 - 0x08, 0x00, 0x00, 0x00, 0x00, 0x30, 0x07, 0x08, 0x05, 0x88, 0x04, 0x88, 0x04, 0x88, 0x04, 0x70, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 - 0x08, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x08, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0xB8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 - 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x40, 0x01, 0x30, 0x01, 0x08, 0x01, 0xF8, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 - 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x03, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x88, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0xD8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 - 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x04, 0x08, 0x03, 0x88, 0x00, 0x68, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 - 0x08, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x03, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0xB8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x06, 0x88, 0x04, 0x88, 0x04, 0x88, 0x04, 0x88, 0x04, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x02, 0x00, 0x00, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x07, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x02, 0x40, 0x02, 0x40, 0x04, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < - 0x07, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = - 0x07, 0x00, 0x00, 0x20, 0x04, 0x40, 0x04, 0x40, 0x02, 0x80, 0x02, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > - 0x06, 0x00, 0x00, 0x30, 0x00, 0x08, 0x00, 0x88, 0x05, 0x88, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x0B, 0x00, 0x00, 0xC0, 0x03, 0x30, 0x04, 0xD0, 0x0F, 0x68, 0x0A, 0x28, 0x0A, 0xA8, 0x09, 0x68, 0x0A, 0x08, 0x0A, 0x10, 0x01, 0xE0, 0x00, // Code for char @ - 0x08, 0x00, 0x00, 0x00, 0x06, 0xC0, 0x01, 0x30, 0x01, 0x08, 0x01, 0x70, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0xB8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C - 0x09, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, // Code for char D - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E - 0x07, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F - 0x09, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x88, 0x04, 0x88, 0x04, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, // Code for char G - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H - 0x05, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0xF8, 0x07, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I - 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x40, 0x00, 0xE0, 0x00, 0x10, 0x01, 0x08, 0x06, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K - 0x07, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x38, 0x00, 0xC0, 0x01, 0x00, 0x06, 0x00, 0x07, 0xE0, 0x00, 0x18, 0x00, 0xF8, 0x07, 0x00, 0x00, // Code for char M - 0x09, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x18, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x01, 0x00, 0x06, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char N - 0x09, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, // Code for char O - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P - 0x09, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x05, 0x08, 0x06, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char Q - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x78, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R - 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x03, 0x48, 0x04, 0x48, 0x04, 0x88, 0x04, 0x88, 0x04, 0x98, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S - 0x07, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x07, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T - 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U - 0x08, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x03, 0x00, 0x04, 0x80, 0x03, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V - 0x0B, 0x00, 0x00, 0x18, 0x00, 0xE0, 0x01, 0x00, 0x06, 0xC0, 0x03, 0x38, 0x00, 0x78, 0x00, 0x80, 0x03, 0x00, 0x06, 0xE0, 0x01, 0x18, 0x00, // Code for char W - 0x08, 0x00, 0x00, 0x08, 0x04, 0x18, 0x02, 0xA0, 0x01, 0xC0, 0x00, 0x20, 0x01, 0x18, 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X - 0x08, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x60, 0x00, 0x80, 0x07, 0x60, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y - 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x08, 0x05, 0x88, 0x04, 0x48, 0x04, 0x28, 0x04, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z - 0x03, 0x00, 0x00, 0xF8, 0x07, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x04, 0x18, 0x00, 0xE0, 0x00, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash - 0x02, 0x08, 0x04, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ - 0x06, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ - 0x03, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x06, 0x00, 0x00, 0xA0, 0x07, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a - 0x06, 0x00, 0x00, 0xF8, 0x07, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b - 0x06, 0x00, 0x00, 0xC0, 0x07, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d - 0x06, 0x00, 0x00, 0xE0, 0x03, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e - 0x04, 0x20, 0x00, 0xF8, 0x07, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f - 0x06, 0x00, 0x00, 0xC0, 0x13, 0x20, 0x14, 0x20, 0x14, 0x20, 0x14, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g - 0x06, 0x00, 0x00, 0xF8, 0x07, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h - 0x02, 0x00, 0x00, 0xE8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i - 0x02, 0x00, 0x10, 0xE8, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x05, 0x00, 0x00, 0xF8, 0x07, 0x80, 0x01, 0x60, 0x02, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k - 0x02, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l - 0x08, 0x00, 0x00, 0xE0, 0x07, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x07, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m - 0x06, 0x00, 0x00, 0xE0, 0x07, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o - 0x06, 0x00, 0x00, 0xE0, 0x1F, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q - 0x05, 0x00, 0x00, 0xE0, 0x07, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r - 0x06, 0x00, 0x00, 0xE0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s - 0x05, 0x20, 0x00, 0xF0, 0x07, 0x20, 0x04, 0x20, 0x04, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x06, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u - 0x05, 0x60, 0x00, 0x80, 0x03, 0x00, 0x04, 0x80, 0x03, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v - 0x08, 0xE0, 0x00, 0x00, 0x07, 0x00, 0x07, 0xE0, 0x00, 0xE0, 0x01, 0x00, 0x06, 0x80, 0x07, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w - 0x05, 0x20, 0x04, 0x40, 0x03, 0x80, 0x01, 0x60, 0x02, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x - 0x05, 0x60, 0x00, 0x80, 0x13, 0x00, 0x0E, 0xC0, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y - 0x06, 0x00, 0x00, 0x20, 0x06, 0x20, 0x05, 0xA0, 0x04, 0x60, 0x04, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z - 0x05, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x78, 0x1F, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { - 0x03, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x05, 0x00, 0x00, 0x08, 0x10, 0x78, 0x1F, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x07, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ - 0x03, 0xF8, 0x07, 0x08, 0x04, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char †- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   - 0x02, 0x00, 0x00, 0xE8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ - 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x0E, 0xE0, 0x05, 0x30, 0x04, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¢ - 0x07, 0x00, 0x00, 0x80, 0x04, 0xF8, 0x07, 0x88, 0x04, 0x88, 0x04, 0x08, 0x04, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char £ - 0x06, 0x08, 0x01, 0xF0, 0x00, 0x90, 0x00, 0x90, 0x00, 0xF0, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¤ - 0x07, 0xA8, 0x00, 0xB0, 0x00, 0xE0, 0x00, 0x80, 0x07, 0xE0, 0x00, 0xB0, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¥ - 0x03, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ - 0x05, 0xF8, 0x06, 0xA8, 0x04, 0x48, 0x05, 0x58, 0x05, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char § - 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ - 0x09, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x02, 0xC8, 0x04, 0x28, 0x05, 0x28, 0x05, 0xC8, 0x04, 0x10, 0x02, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char © - 0x05, 0x00, 0x00, 0x78, 0x00, 0x58, 0x00, 0x58, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª - 0x05, 0x00, 0x00, 0x00, 0x01, 0x80, 0x02, 0x00, 0x01, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char « - 0x07, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¬ - 0x04, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ - 0x09, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x02, 0xE8, 0x05, 0xA8, 0x04, 0xA8, 0x05, 0x68, 0x06, 0x10, 0x02, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char ® - 0x04, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¯ - 0x03, 0x38, 0x00, 0x28, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° - 0x08, 0x00, 0x00, 0x40, 0x04, 0x40, 0x04, 0x40, 0x04, 0xF0, 0x05, 0x40, 0x04, 0x40, 0x04, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ± - 0x05, 0x00, 0x00, 0xD8, 0x00, 0xC8, 0x00, 0xA8, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² - 0x05, 0x00, 0x00, 0xD8, 0x00, 0x88, 0x00, 0xA8, 0x00, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ - 0x05, 0xC0, 0x07, 0x20, 0x04, 0x00, 0x04, 0x80, 0x03, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char µ - 0x06, 0x00, 0x00, 0x78, 0x00, 0xF8, 0x07, 0x08, 0x00, 0xF8, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¶ - 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ - 0x04, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ - 0x05, 0x00, 0x00, 0x78, 0x00, 0x48, 0x00, 0x48, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º - 0x05, 0x00, 0x00, 0x80, 0x02, 0x00, 0x01, 0x80, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char » - 0x0A, 0x10, 0x00, 0x08, 0x00, 0xF8, 0x00, 0x00, 0x06, 0x80, 0x01, 0x70, 0x00, 0x88, 0x01, 0x80, 0x01, 0xC0, 0x07, 0x00, 0x01, 0x00, 0x00, // Code for char ¼ - 0x0A, 0x10, 0x00, 0x08, 0x00, 0xF8, 0x00, 0x00, 0x06, 0x80, 0x01, 0x60, 0x00, 0x58, 0x07, 0x48, 0x05, 0x40, 0x05, 0xC0, 0x04, 0x00, 0x00, // Code for char ½ - 0x0B, 0x00, 0x00, 0xC8, 0x00, 0x88, 0x00, 0x98, 0x04, 0xE8, 0x02, 0x80, 0x01, 0x40, 0x00, 0x30, 0x00, 0x88, 0x01, 0x80, 0x01, 0xC0, 0x07, // Code for char ¾ - 0x05, 0x80, 0x07, 0x40, 0x04, 0x28, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¿ - 0x07, 0x00, 0x06, 0xC0, 0x01, 0x32, 0x01, 0x0C, 0x01, 0x70, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char À - 0x07, 0x00, 0x06, 0xC0, 0x01, 0x30, 0x01, 0x0C, 0x01, 0x72, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x07, 0x00, 0x06, 0xC0, 0x01, 0x34, 0x01, 0x0A, 0x01, 0x74, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x07, 0x00, 0x06, 0xC0, 0x01, 0x32, 0x01, 0x0A, 0x01, 0x72, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x07, 0x00, 0x06, 0xC0, 0x01, 0x32, 0x01, 0x08, 0x01, 0x72, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ä - 0x07, 0x00, 0x06, 0xC0, 0x01, 0x37, 0x01, 0x0D, 0x01, 0x77, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Å - 0x0B, 0x00, 0x03, 0xC0, 0x01, 0x20, 0x01, 0x18, 0x01, 0x08, 0x01, 0xF8, 0x07, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, // Code for char Æ - 0x07, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x14, 0x08, 0x1C, 0x08, 0x04, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ç - 0x07, 0x00, 0x00, 0xF8, 0x07, 0x4A, 0x04, 0x4C, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char È - 0x07, 0x00, 0x00, 0xF8, 0x07, 0x48, 0x04, 0x4C, 0x04, 0x4A, 0x04, 0x48, 0x04, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char É - 0x07, 0x00, 0x00, 0xF8, 0x07, 0x4C, 0x04, 0x4A, 0x04, 0x4C, 0x04, 0x48, 0x04, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ê - 0x07, 0x00, 0x00, 0xF8, 0x07, 0x4A, 0x04, 0x48, 0x04, 0x4A, 0x04, 0x48, 0x04, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ë - 0x02, 0x02, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ì - 0x03, 0x00, 0x00, 0xFC, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x03, 0x04, 0x00, 0xFA, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Î - 0x03, 0x02, 0x00, 0xF8, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x08, 0x40, 0x00, 0xF8, 0x07, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x08, 0x00, 0x00, 0xF8, 0x07, 0x18, 0x00, 0x22, 0x00, 0xC2, 0x00, 0x02, 0x01, 0x00, 0x06, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ñ - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x0A, 0x04, 0x0C, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ò - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x0C, 0x04, 0x0A, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ó - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x0C, 0x04, 0x0A, 0x04, 0x0C, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ô - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x0A, 0x04, 0x0A, 0x04, 0x0A, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Õ - 0x08, 0x00, 0x00, 0xF0, 0x03, 0x0A, 0x04, 0x08, 0x04, 0x0A, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ö - 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x40, 0x02, 0x80, 0x01, 0x80, 0x01, 0x40, 0x02, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char × - 0x08, 0x00, 0x00, 0xF0, 0x07, 0x08, 0x06, 0x08, 0x05, 0xC8, 0x04, 0x28, 0x04, 0x18, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ø - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x02, 0x04, 0x04, 0x04, 0x00, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ù - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x04, 0x04, 0x04, 0x02, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ú - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x02, 0x04, 0x04, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Û - 0x07, 0x00, 0x00, 0xF8, 0x03, 0x02, 0x04, 0x00, 0x04, 0x02, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ü - 0x07, 0x08, 0x00, 0x10, 0x00, 0x60, 0x00, 0x84, 0x07, 0x62, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x07, 0x00, 0x00, 0xF8, 0x07, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Þ - 0x06, 0x00, 0x00, 0xF0, 0x07, 0x08, 0x00, 0x48, 0x04, 0x48, 0x04, 0xB0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ß - 0x06, 0x00, 0x00, 0xA8, 0x07, 0xB0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x06, 0x00, 0x00, 0xA0, 0x07, 0xB0, 0x04, 0xA8, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char á - 0x06, 0x00, 0x00, 0xB0, 0x07, 0xA8, 0x04, 0xB0, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char â - 0x06, 0x00, 0x00, 0xA8, 0x07, 0xA8, 0x04, 0xA8, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ã - 0x06, 0x00, 0x00, 0xA8, 0x07, 0xA0, 0x04, 0xA8, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ä - 0x06, 0x00, 0x00, 0xA0, 0x07, 0xAE, 0x04, 0xAA, 0x04, 0xAE, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char å - 0x0A, 0x00, 0x00, 0xA0, 0x07, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xC0, 0x03, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x02, 0x00, 0x00, // Code for char æ - 0x06, 0x00, 0x00, 0xC0, 0x07, 0x20, 0x14, 0x20, 0x1C, 0x20, 0x04, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ç - 0x06, 0x00, 0x00, 0xE8, 0x03, 0xB0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char è - }; - -const struct GDS_FontDef Font_line_1 = { - Square721_BT11x14, - 11, - 14, - ' ', - '\xFF', - false -}; diff --git a/components/display/fonts/font_line_2.c b/components/display/fonts/font_line_2.c deleted file mode 100644 index 8d4ab57d..00000000 --- a/components/display/fonts/font_line_2.c +++ /dev/null @@ -1,247 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Archivo_Narrow18x24 -//GLCD FontSize : 18 x 24 - -static const uint8_t Archivo_Narrow18x24[] = { - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0x0E, 0xF0, 0xFF, 0x0E, 0xF0, 0x1F, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x08, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x0A, 0x00, 0xC0, 0x08, 0x00, 0xC3, 0x0F, 0x00, 0xFF, 0x0F, 0xC0, 0xFF, 0x00, 0xF0, 0xC3, 0x0C, 0x30, 0xC3, 0x0F, 0x00, 0xFF, 0x03, 0xF0, 0xFF, 0x00, 0xF0, 0xC3, 0x00, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x80, 0x8F, 0x03, 0xC0, 0x9F, 0x03, 0xC0, 0x1D, 0x07, 0xF8, 0xFF, 0x1F, 0xC0, 0x39, 0x07, 0xC0, 0xF3, 0x03, 0x80, 0xF3, 0x03, 0x00, 0xE3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ - 0x10, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0xE0, 0x07, 0x00, 0x30, 0x0C, 0x08, 0x30, 0x0C, 0x0E, 0xE0, 0x87, 0x03, 0xC0, 0xC3, 0x01, 0x00, 0x70, 0x00, 0x00, 0x38, 0x00, 0x00, 0x0E, 0x00, 0x80, 0xC3, 0x03, 0xC0, 0xE1, 0x07, 0x70, 0x30, 0x0C, 0x10, 0x30, 0x0C, 0x00, 0xE0, 0x07, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char % - 0x0E, 0x00, 0x00, 0x00, 0x80, 0xE1, 0x01, 0xE0, 0xF7, 0x03, 0xE0, 0xFF, 0x07, 0x70, 0x3E, 0x0F, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0xFD, 0x07, 0xE0, 0xFD, 0x03, 0x80, 0xFD, 0x01, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & - 0x04, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x06, 0x00, 0xFC, 0x01, 0x80, 0xFF, 0x0F, 0xE0, 0xFF, 0x3F, 0xF0, 0x01, 0x7C, 0x38, 0x00, 0xE0, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x06, 0x08, 0x00, 0x80, 0x38, 0x00, 0xE0, 0xF0, 0x01, 0x7C, 0xE0, 0xFF, 0x3F, 0x80, 0xFF, 0x0F, 0x00, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x08, 0x40, 0x02, 0x00, 0x60, 0x06, 0x00, 0xC0, 0x03, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xC0, 0x03, 0x00, 0x60, 0x06, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x06, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x05, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0x1F, 0x80, 0xFF, 0x01, 0xF8, 0x0F, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xC0, 0xFF, 0x03, 0xE0, 0xFF, 0x07, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0xFF, 0x07, 0xC0, 0xFF, 0x03, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 - 0x0A, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x0E, 0xC0, 0x00, 0x0E, 0xE0, 0x00, 0x0E, 0xE0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 - 0x0A, 0x00, 0x00, 0x00, 0x80, 0x03, 0x0E, 0xE0, 0x83, 0x0F, 0xE0, 0xC3, 0x0F, 0x70, 0xE0, 0x0F, 0x70, 0xF0, 0x0E, 0x70, 0x7C, 0x0E, 0xE0, 0x3F, 0x0E, 0xE0, 0x0F, 0x0E, 0xC0, 0x03, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 - 0x0A, 0x00, 0x00, 0x00, 0x80, 0x81, 0x01, 0xE0, 0x81, 0x07, 0xE0, 0x81, 0x07, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0xE0, 0xFF, 0x07, 0xE0, 0xF7, 0x07, 0xC0, 0xC3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 - 0x0A, 0x00, 0xC0, 0x01, 0x00, 0xF0, 0x01, 0x00, 0xFC, 0x01, 0x80, 0xDF, 0x01, 0xF0, 0xC7, 0x01, 0xF0, 0xC1, 0x01, 0x30, 0xFC, 0x0F, 0x80, 0xFF, 0x0F, 0xC0, 0xFF, 0x0F, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 - 0x0A, 0x00, 0x00, 0x00, 0xF0, 0x9F, 0x01, 0xF0, 0x9F, 0x03, 0xF0, 0x9F, 0x07, 0x70, 0x0C, 0x0E, 0x70, 0x0E, 0x0E, 0x70, 0x0E, 0x0F, 0x70, 0xFE, 0x07, 0x70, 0xFC, 0x03, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xC0, 0xFF, 0x03, 0xE0, 0xFF, 0x07, 0x70, 0x18, 0x0E, 0x70, 0x1C, 0x0E, 0xE0, 0x1D, 0x0E, 0xE0, 0xF9, 0x07, 0x80, 0xF9, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 - 0x0A, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x0F, 0x70, 0xE0, 0x0F, 0x70, 0xFC, 0x0F, 0x70, 0x7F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 - 0x0A, 0x00, 0x00, 0x00, 0x80, 0xE3, 0x01, 0xE0, 0xF7, 0x07, 0xE0, 0xFF, 0x07, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0xE0, 0xFF, 0x07, 0xE0, 0xF7, 0x07, 0x80, 0xE3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 - 0x0A, 0x00, 0x00, 0x00, 0x80, 0x8F, 0x01, 0xE0, 0xBF, 0x07, 0xE0, 0xBF, 0x07, 0x70, 0x70, 0x0E, 0x70, 0x70, 0x0E, 0xF0, 0x38, 0x0E, 0xE0, 0xFF, 0x07, 0xC0, 0xFF, 0x03, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 - 0x04, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x04, 0x00, 0x00, 0x00, 0x00, 0x07, 0x4E, 0x00, 0x07, 0x7E, 0x00, 0x07, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x98, 0x01, 0x00, 0x9C, 0x03, 0x00, 0x0C, 0x03, 0x00, 0x0E, 0x07, 0x00, 0x06, 0x06, 0x00, 0x07, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x07, 0x00, 0x0C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x98, 0x01, 0x00, 0xF8, 0x01, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > - 0x0A, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xE0, 0x03, 0x00, 0xE0, 0x03, 0x00, 0x70, 0x00, 0x00, 0x70, 0xE0, 0x0E, 0x70, 0xF8, 0x0E, 0xE0, 0xFF, 0x0E, 0xE0, 0x1F, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x12, 0x00, 0xF8, 0x00, 0x00, 0xFF, 0x07, 0x80, 0x03, 0x1C, 0xC0, 0x00, 0x30, 0x60, 0x00, 0x60, 0x60, 0xC0, 0x63, 0x20, 0xE4, 0x47, 0x30, 0xE6, 0xC7, 0x30, 0x37, 0xC6, 0x30, 0x33, 0xC6, 0x30, 0xFF, 0xC3, 0x30, 0xFE, 0x67, 0x60, 0xFC, 0x07, 0x60, 0x00, 0x06, 0xC0, 0x00, 0x06, 0xC0, 0x01, 0x03, 0x00, 0xFF, 0x01, 0x00, 0x7C, 0x00, // Code for char @ - 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x03, 0x80, 0xFF, 0x01, 0xF0, 0xCF, 0x01, 0xF0, 0xC1, 0x01, 0xF0, 0xC1, 0x01, 0xF0, 0xCF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A - 0x0D, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0xF0, 0x3F, 0x0F, 0xE0, 0xF7, 0x07, 0xC0, 0xF1, 0x07, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x07, 0xE0, 0x81, 0x07, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0x00, 0x07, 0xE0, 0xC3, 0x07, 0xC0, 0xC3, 0x03, 0x00, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C - 0x0D, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D - 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E - 0x0A, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x03, 0xC0, 0xFF, 0x07, 0xE0, 0x00, 0x07, 0x60, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x38, 0x0E, 0x70, 0x38, 0x06, 0xE0, 0x38, 0x07, 0xE0, 0xFB, 0x03, 0xC0, 0xFB, 0x0F, 0x00, 0xFB, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H - 0x04, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I - 0x09, 0x00, 0x80, 0x03, 0x00, 0x80, 0x07, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x0D, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x78, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x7F, 0x00, 0xC0, 0xFB, 0x01, 0xF0, 0xE1, 0x07, 0x70, 0x80, 0x0F, 0x30, 0x00, 0x0E, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K - 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L - 0x0F, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x03, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0xF0, 0x0F, 0x00, 0x80, 0x0F, 0x00, 0xFC, 0x07, 0xC0, 0x3F, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char M - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xE0, 0x07, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xE0, 0x07, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE0, 0x81, 0x07, 0xE0, 0x00, 0x06, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x3C, 0x00, 0xE0, 0x1F, 0x00, 0xE0, 0x1F, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE0, 0x81, 0x07, 0xE0, 0x00, 0x06, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x1E, 0xE0, 0x00, 0x3F, 0xE0, 0x81, 0x3F, 0xC0, 0xFF, 0x33, 0x80, 0xFF, 0x21, 0x00, 0x7E, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Q - 0x0D, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0xF8, 0x00, 0x70, 0xF8, 0x03, 0xE0, 0xFF, 0x0F, 0xE0, 0x8F, 0x0F, 0x80, 0x07, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x83, 0x01, 0xE0, 0x8F, 0x03, 0xE0, 0x8F, 0x07, 0x70, 0x0E, 0x0F, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x38, 0x0E, 0xE0, 0x39, 0x0E, 0xE0, 0xF1, 0x07, 0x80, 0xF1, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S - 0x0B, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x07, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0F, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U - 0x0D, 0x10, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xF0, 0x0F, 0x00, 0x80, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xFE, 0x03, 0xC0, 0x7F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V - 0x12, 0x30, 0x00, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x7F, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0x80, 0x0F, 0x00, 0xFE, 0x0F, 0xF0, 0x7F, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x7F, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFF, 0x0F, 0xF0, 0x7F, 0x00, 0xF0, 0x03, 0x00, 0x30, 0x00, 0x00, // Code for char W - 0x0D, 0x00, 0x00, 0x08, 0x30, 0x00, 0x0E, 0xF0, 0x00, 0x0F, 0xF0, 0xC1, 0x07, 0xE0, 0xF7, 0x03, 0x80, 0xFF, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xFF, 0x00, 0xC0, 0xF7, 0x03, 0xF0, 0xC1, 0x0F, 0xF0, 0x00, 0x0F, 0x30, 0x00, 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X - 0x0D, 0x10, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x07, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0xF8, 0x0F, 0x00, 0xFE, 0x0F, 0x80, 0x1F, 0x00, 0xE0, 0x07, 0x00, 0xF0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y - 0x0B, 0x00, 0x00, 0x0C, 0x70, 0x00, 0x0F, 0x70, 0xC0, 0x0F, 0x70, 0xE0, 0x0F, 0x70, 0xF8, 0x0F, 0x70, 0x7E, 0x0E, 0xF0, 0x1F, 0x0E, 0xF0, 0x07, 0x0E, 0xF0, 0x01, 0x0E, 0x70, 0x00, 0x0E, 0x30, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z - 0x06, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x05, 0x38, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x80, 0xFF, 0x01, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash - 0x05, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x07, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ - 0x0A, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ - 0x05, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x00, 0xCE, 0x0F, 0x00, 0x6F, 0x0E, 0x00, 0x67, 0x06, 0x00, 0x67, 0x06, 0x00, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a - 0x0B, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x00, 0x06, 0x06, 0x00, 0x06, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x0F, 0x0E, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x07, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x07, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x9E, 0x07, 0x00, 0x9E, 0x07, 0x00, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFE, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x06, 0x06, 0xF8, 0xFF, 0x07, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x7E, 0x07, 0x00, 0x7C, 0x07, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e - 0x06, 0x00, 0x07, 0x00, 0xE0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x38, 0x07, 0x00, 0x38, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f - 0x0B, 0x00, 0x00, 0x18, 0x00, 0x9E, 0x3D, 0x00, 0xFF, 0x3F, 0x80, 0xFF, 0x33, 0x80, 0xB1, 0x33, 0x80, 0xB1, 0x33, 0x80, 0xB1, 0x33, 0x80, 0x3F, 0x33, 0x80, 0x3F, 0x3F, 0xC0, 0x1E, 0x1E, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h - 0x04, 0x00, 0x00, 0x00, 0x38, 0xFF, 0x0F, 0x38, 0xFF, 0x0F, 0x38, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i - 0x04, 0x00, 0x00, 0x38, 0x38, 0xFF, 0x3F, 0x38, 0xFF, 0x3F, 0x38, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x0A, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x00, 0x70, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x8F, 0x0F, 0x00, 0x03, 0x0F, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k - 0x04, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l - 0x10, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x07, 0x0F, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0F, 0x00, 0xFE, 0x07, 0x00, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0xFF, 0x3F, 0x00, 0xFE, 0x3F, 0x00, 0x06, 0x07, 0x00, 0x06, 0x07, 0x00, 0x07, 0x07, 0x00, 0x0F, 0x03, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x01, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFE, 0x03, 0x00, 0xFF, 0x07, 0x00, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00, 0x06, 0x07, 0x00, 0xFF, 0x3F, 0x00, 0xFF, 0x3F, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q - 0x07, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x3E, 0x07, 0x00, 0x3F, 0x07, 0x00, 0x77, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x6F, 0x0E, 0x00, 0xEE, 0x07, 0x00, 0xCC, 0x07, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s - 0x06, 0x00, 0x07, 0x00, 0xE0, 0xFF, 0x03, 0xE0, 0xFF, 0x07, 0xE0, 0xFF, 0x0F, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u - 0x0A, 0x00, 0x03, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFC, 0x07, 0x00, 0xC0, 0x0F, 0x00, 0x80, 0x0F, 0x00, 0xF8, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v - 0x0F, 0x00, 0x01, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xFF, 0x01, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xFF, 0x01, 0x00, 0x07, 0x00, 0x00, 0xFF, 0x01, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0xF0, 0x0F, 0x00, 0xFF, 0x03, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w - 0x0A, 0x00, 0x01, 0x08, 0x00, 0x03, 0x0E, 0x00, 0x8F, 0x0F, 0x00, 0xFF, 0x07, 0x00, 0xFC, 0x01, 0x00, 0xF8, 0x01, 0x00, 0xFE, 0x07, 0x00, 0x8F, 0x0F, 0x00, 0x03, 0x0E, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x - 0x0A, 0x00, 0x01, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0xFC, 0xF3, 0x00, 0xE0, 0x7F, 0x00, 0x80, 0x3F, 0x00, 0xF8, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y - 0x09, 0x00, 0x07, 0x0C, 0x00, 0x07, 0x0F, 0x00, 0x87, 0x0F, 0x00, 0xE7, 0x0F, 0x00, 0xFF, 0x0E, 0x00, 0x7F, 0x0E, 0x00, 0x1F, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x03, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z - 0x07, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0xE0, 0xFF, 0x3F, 0xF0, 0xDF, 0x7F, 0xF8, 0x87, 0xFF, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x07, 0x0C, 0x00, 0x60, 0x0C, 0x00, 0x60, 0xFC, 0xC3, 0x7F, 0xF8, 0xFF, 0x3F, 0xF0, 0xFF, 0x1F, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x30, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ - 0x06, 0xE0, 0xFF, 0x07, 0xE0, 0xFF, 0x07, 0x20, 0x00, 0x04, 0x20, 0x00, 0x04, 0xE0, 0xFF, 0x07, 0xE0, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char †- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC3, 0x3F, 0x80, 0xFB, 0x3F, 0x80, 0xC3, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xC0, 0x81, 0x03, 0xF8, 0xFF, 0x1F, 0xC0, 0x80, 0x03, 0xC0, 0xE3, 0x03, 0x80, 0xE3, 0x01, 0x00, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¢ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0E, 0x80, 0xFF, 0x0F, 0xE0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x38, 0x0E, 0x70, 0x38, 0x0E, 0xF0, 0x01, 0x0E, 0xE0, 0x01, 0x0E, 0x80, 0x01, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char £ - 0x0A, 0x80, 0xBD, 0x01, 0x00, 0xFF, 0x00, 0x00, 0xC3, 0x00, 0x80, 0x81, 0x01, 0x80, 0x81, 0x01, 0x80, 0x81, 0x01, 0x80, 0x81, 0x01, 0x00, 0xC3, 0x00, 0x00, 0xFF, 0x00, 0x80, 0xBD, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¤ - 0x0B, 0x10, 0x00, 0x00, 0x70, 0x98, 0x01, 0xF0, 0x99, 0x01, 0xF0, 0x9F, 0x01, 0x80, 0xFF, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0xFF, 0x0F, 0xE0, 0x9F, 0x01, 0xF0, 0x99, 0x01, 0x70, 0x98, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¥ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x8F, 0x3F, 0xF0, 0x8F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ - 0x0A, 0x00, 0x00, 0x00, 0xE0, 0x39, 0x18, 0xE0, 0x7F, 0x38, 0xF0, 0xFF, 0x38, 0x30, 0xC7, 0x31, 0x30, 0xCE, 0x31, 0x30, 0x8E, 0x33, 0x70, 0xFC, 0x3F, 0x70, 0xF8, 0x3F, 0x60, 0x70, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char § - 0x06, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xC0, 0x00, 0x03, 0x20, 0x7E, 0x04, 0x10, 0xFF, 0x08, 0x90, 0x81, 0x09, 0x90, 0x81, 0x09, 0x90, 0x81, 0x09, 0x10, 0xE7, 0x08, 0x20, 0x66, 0x04, 0x40, 0x00, 0x02, 0x80, 0x81, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char © - 0x07, 0x00, 0x07, 0x00, 0xB0, 0x0F, 0x00, 0xB8, 0x0C, 0x00, 0x98, 0x04, 0x00, 0xF8, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xC7, 0x01, 0x00, 0x11, 0x01, 0x00, 0x7C, 0x00, 0x00, 0xFE, 0x01, 0x00, 0xC7, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char « - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¬ - 0x06, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ - 0x0D, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xC0, 0x80, 0x03, 0x60, 0x00, 0x06, 0xA0, 0xFF, 0x05, 0x90, 0xFF, 0x09, 0x90, 0x19, 0x08, 0x90, 0x19, 0x08, 0x90, 0xFF, 0x08, 0x20, 0xE7, 0x05, 0x60, 0x00, 0x07, 0xC0, 0x81, 0x03, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ® - 0x06, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¯ - 0x08, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xE0, 0x03, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0xE0, 0x03, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0xC0, 0xFF, 0x0E, 0xC0, 0xFF, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ± - 0x06, 0x70, 0x18, 0x00, 0x70, 0x1E, 0x00, 0x18, 0x1F, 0x00, 0x98, 0x1B, 0x00, 0xF0, 0x19, 0x00, 0x70, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² - 0x06, 0x30, 0x0C, 0x00, 0x30, 0x0C, 0x00, 0x98, 0x19, 0x00, 0x98, 0x19, 0x00, 0xF0, 0x0F, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ - 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x06, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char µ - 0x0A, 0x80, 0x07, 0x00, 0xC0, 0x1F, 0x00, 0xE0, 0x3F, 0x00, 0xF0, 0x3F, 0x00, 0xF0, 0xFF, 0x3F, 0xF0, 0xFF, 0x3F, 0x30, 0x00, 0x00, 0xF0, 0xFF, 0x3F, 0xF0, 0xFF, 0x3F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¶ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ - 0x05, 0x20, 0x18, 0x00, 0x20, 0x18, 0x00, 0xF0, 0x1F, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ - 0x07, 0xE0, 0x03, 0x00, 0xF0, 0x07, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x0C, 0x00, 0xF0, 0x07, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xC7, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x7C, 0x00, 0x00, 0x11, 0x01, 0x00, 0xC7, 0x01, 0x00, 0xFE, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char » - 0x0F, 0x60, 0x30, 0x00, 0x60, 0x30, 0x00, 0xF0, 0x3F, 0x00, 0xF0, 0x3F, 0x0C, 0x00, 0x30, 0x06, 0x00, 0x80, 0x03, 0x00, 0xE0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x87, 0x03, 0xC0, 0xE1, 0x03, 0x60, 0x78, 0x03, 0x10, 0x88, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¼ - 0x0F, 0x60, 0x30, 0x00, 0x60, 0x30, 0x00, 0xF0, 0x3F, 0x08, 0xF0, 0x3F, 0x0C, 0x00, 0x30, 0x06, 0x00, 0xB0, 0x01, 0x00, 0xE0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x07, 0x00, 0x80, 0x39, 0x0C, 0x60, 0x3C, 0x0F, 0x10, 0x8C, 0x0F, 0x00, 0xFC, 0x0C, 0x00, 0x38, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ½ - 0x0F, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x70, 0x38, 0x00, 0x30, 0x33, 0x08, 0xE0, 0x3F, 0x0E, 0xC0, 0x1C, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x87, 0x03, 0xC0, 0xE1, 0x03, 0x60, 0x78, 0x03, 0x30, 0x88, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¾ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0xC0, 0x1F, 0x00, 0xE0, 0x3F, 0xC0, 0x7D, 0x38, 0xC0, 0x3D, 0x38, 0xC0, 0x1D, 0x38, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¿ - 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x03, 0x80, 0xFF, 0x01, 0xF2, 0xCF, 0x01, 0xF6, 0xC1, 0x01, 0xF6, 0xC1, 0x01, 0xF4, 0xCF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char À - 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x03, 0x80, 0xFF, 0x01, 0xF4, 0xCF, 0x01, 0xF6, 0xC1, 0x01, 0xF6, 0xC1, 0x01, 0xF2, 0xCF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x03, 0x84, 0xFF, 0x01, 0xF6, 0xCF, 0x01, 0xF2, 0xC1, 0x01, 0xF2, 0xC1, 0x01, 0xF6, 0xCF, 0x01, 0x84, 0xFF, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  - 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x04, 0xFC, 0x03, 0x86, 0xFF, 0x01, 0xF2, 0xCF, 0x01, 0xF2, 0xC1, 0x01, 0xF6, 0xC1, 0x01, 0xF6, 0xCF, 0x01, 0x82, 0xFF, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x07, 0x86, 0xFF, 0x01, 0xF6, 0xCF, 0x01, 0xF0, 0xC0, 0x01, 0xF0, 0xC1, 0x01, 0xF6, 0xCF, 0x01, 0x86, 0xFF, 0x01, 0x00, 0xFC, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ä - 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0E, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x07, 0x80, 0xFF, 0x01, 0xE6, 0xCF, 0x01, 0xE9, 0xC1, 0x01, 0xE9, 0xC1, 0x01, 0xE6, 0xDF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0xFC, 0x0F, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Å - 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xF8, 0x03, 0x00, 0xFF, 0x01, 0xC0, 0xCF, 0x01, 0xF0, 0xC3, 0x01, 0xF0, 0xC0, 0x01, 0xF0, 0xCF, 0x01, 0xF0, 0xFF, 0x01, 0x70, 0xFF, 0x0F, 0x70, 0xFC, 0x0F, 0x70, 0x1C, 0x0F, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, // Code for char Æ - 0x0D, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0xE0, 0xFF, 0x00, 0xF0, 0xFF, 0x01, 0x78, 0xC0, 0x01, 0x18, 0x80, 0x23, 0x1C, 0x80, 0x2F, 0x1C, 0x00, 0x3F, 0x1C, 0x80, 0x13, 0x38, 0xC0, 0x03, 0xF8, 0xF0, 0x01, 0xF0, 0xF0, 0x00, 0xC0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ç - 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x72, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x74, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char È - 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x74, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x72, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char É - 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF4, 0xFF, 0x0F, 0x76, 0x1C, 0x0E, 0x72, 0x1C, 0x0E, 0x72, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x74, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ê - 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF6, 0xFF, 0x0F, 0x76, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ë - 0x04, 0x00, 0x00, 0x00, 0xF2, 0xFF, 0x0F, 0xF6, 0xFF, 0x0F, 0xF4, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ì - 0x04, 0x00, 0x00, 0x00, 0xF4, 0xFF, 0x0F, 0xF6, 0xFF, 0x0F, 0xF2, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x06, 0x04, 0x00, 0x00, 0xF6, 0xFF, 0x0F, 0xF2, 0xFF, 0x0F, 0xF6, 0xFF, 0x0F, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Î - 0x06, 0x06, 0x00, 0x00, 0xE6, 0xFF, 0x0F, 0xE0, 0xFF, 0x0F, 0xE0, 0xFF, 0x0F, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0D, 0x00, 0x18, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x18, 0x0E, 0x70, 0x18, 0x0E, 0x70, 0x18, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF4, 0xFF, 0x0F, 0xF6, 0xFF, 0x0F, 0xE2, 0x07, 0x00, 0x82, 0x1F, 0x00, 0x02, 0x7E, 0x00, 0x06, 0xF8, 0x01, 0x04, 0xE0, 0x07, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ñ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE0, 0x81, 0x07, 0xE2, 0x00, 0x06, 0x76, 0x00, 0x0E, 0x76, 0x00, 0x0E, 0x74, 0x00, 0x0E, 0xE0, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ò - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE0, 0x81, 0x07, 0xE0, 0x00, 0x06, 0x74, 0x00, 0x0E, 0x76, 0x00, 0x0E, 0x76, 0x00, 0x0E, 0xE2, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ó - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE4, 0x81, 0x07, 0xE6, 0x00, 0x06, 0x76, 0x00, 0x0E, 0x72, 0x00, 0x0E, 0x76, 0x00, 0x0E, 0xE6, 0x00, 0x07, 0xE4, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ô - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE4, 0x81, 0x07, 0xE2, 0x00, 0x06, 0x72, 0x00, 0x0E, 0x72, 0x00, 0x0E, 0x72, 0x00, 0x0E, 0xE6, 0x00, 0x07, 0xE2, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Õ - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE6, 0x81, 0x07, 0xE6, 0x00, 0x06, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x76, 0x00, 0x0E, 0xE6, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ö - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x0E, 0x07, 0x00, 0x9C, 0x03, 0x00, 0xF8, 0x01, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x9C, 0x03, 0x00, 0x0E, 0x07, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char × - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x10, 0x80, 0xFF, 0x0D, 0xC0, 0xFF, 0x0F, 0xE0, 0x81, 0x07, 0xE0, 0xE0, 0x0E, 0x70, 0x70, 0x0E, 0x70, 0x18, 0x0E, 0x70, 0x0E, 0x0E, 0x70, 0x07, 0x07, 0xE0, 0x81, 0x07, 0xF0, 0xFF, 0x03, 0xB8, 0xFF, 0x01, 0x08, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ø - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x07, 0x02, 0x00, 0x0F, 0x06, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x0F, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ù - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x07, 0x00, 0x00, 0x0F, 0x04, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x02, 0x00, 0x0F, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ú - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0xF0, 0xFF, 0x03, 0xF4, 0xFF, 0x07, 0x04, 0x00, 0x0F, 0x06, 0x00, 0x0E, 0x02, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x04, 0x00, 0x0F, 0xF4, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Û - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x07, 0x06, 0x00, 0x0F, 0x06, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x06, 0x00, 0x0F, 0xF6, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ü - 0x0D, 0x10, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x07, 0x00, 0x80, 0x1F, 0x00, 0x04, 0xFE, 0x0F, 0x06, 0xF8, 0x0F, 0x02, 0xFE, 0x0F, 0x80, 0x1F, 0x00, 0xE0, 0x07, 0x00, 0xF0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x80, 0xC3, 0x01, 0x80, 0xC3, 0x01, 0x80, 0xC3, 0x01, 0x80, 0xC3, 0x01, 0x80, 0xE3, 0x01, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Þ - 0x0B, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x0F, 0xE0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x38, 0x00, 0x00, 0x38, 0x1C, 0x0E, 0x38, 0x1C, 0x0E, 0x38, 0x1E, 0x0E, 0xF0, 0xFF, 0x07, 0xF0, 0xF3, 0x03, 0xC0, 0xE1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ß - 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x08, 0xCE, 0x0F, 0x18, 0x6F, 0x0E, 0x38, 0x67, 0x06, 0x20, 0x67, 0x06, 0x00, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à - 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x00, 0xCE, 0x0F, 0x20, 0x6F, 0x0E, 0x30, 0x67, 0x06, 0x38, 0x67, 0x06, 0x18, 0xFF, 0x03, 0x08, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char á - 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x20, 0xCE, 0x0F, 0x38, 0x6F, 0x0E, 0x18, 0x67, 0x06, 0x38, 0x67, 0x06, 0x30, 0xFF, 0x03, 0x20, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char â - 0x0A, 0x00, 0x80, 0x03, 0x30, 0xCC, 0x07, 0x38, 0xCE, 0x0F, 0x18, 0x6F, 0x0E, 0x10, 0x67, 0x06, 0x30, 0x67, 0x06, 0x30, 0xFF, 0x03, 0x38, 0xFE, 0x07, 0x08, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ã - 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x38, 0xCE, 0x0F, 0x38, 0x6F, 0x0E, 0x00, 0x67, 0x06, 0x00, 0x67, 0x06, 0x38, 0xFF, 0x03, 0x38, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ä - 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x00, 0xCE, 0x0F, 0x30, 0x6F, 0x0E, 0x48, 0x67, 0x06, 0x48, 0x67, 0x06, 0x30, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char å - 0x10, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x03, 0x00, 0xCE, 0x07, 0x00, 0xCE, 0x0F, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x06, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x7E, 0x07, 0x00, 0x7C, 0x07, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char æ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xFE, 0x8F, 0x00, 0x07, 0xBE, 0x00, 0x07, 0xBC, 0x00, 0x07, 0xEC, 0x00, 0x1E, 0x4F, 0x00, 0x1E, 0x07, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ç - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x08, 0xFC, 0x03, 0x08, 0xFE, 0x07, 0x18, 0x67, 0x0E, 0x30, 0x67, 0x0E, 0x20, 0x67, 0x0E, 0x00, 0x7E, 0x07, 0x00, 0x7C, 0x07, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char è - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x00, 0xFE, 0x07, 0x20, 0x67, 0x0E, 0x30, 0x67, 0x0E, 0x38, 0x67, 0x0E, 0x08, 0x7E, 0x07, 0x08, 0x7C, 0x07, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char é - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x30, 0xFE, 0x07, 0x38, 0x67, 0x0E, 0x18, 0x67, 0x0E, 0x38, 0x67, 0x0E, 0x30, 0x7E, 0x07, 0x20, 0x7C, 0x07, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ê - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x38, 0xFC, 0x03, 0x38, 0xFE, 0x07, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x38, 0x67, 0x0E, 0x38, 0x7E, 0x07, 0x00, 0x7C, 0x07, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ë - 0x04, 0x08, 0x00, 0x00, 0x38, 0xFF, 0x0F, 0x30, 0xFF, 0x0F, 0x20, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ì - 0x06, 0x00, 0x00, 0x00, 0x20, 0xFF, 0x0F, 0x30, 0xFF, 0x0F, 0x38, 0xFF, 0x0F, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char í - 0x06, 0x30, 0x00, 0x00, 0x38, 0xFF, 0x0F, 0x18, 0xFF, 0x0F, 0x38, 0xFF, 0x0F, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char î - 0x06, 0x38, 0x00, 0x00, 0x38, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ï - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x28, 0xFE, 0x07, 0x38, 0x07, 0x0F, 0x38, 0x07, 0x0E, 0xF8, 0x07, 0x0E, 0xF0, 0x07, 0x0F, 0xF0, 0xFF, 0x07, 0x30, 0xFF, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ð - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x30, 0xFF, 0x0F, 0x18, 0xFE, 0x0F, 0x18, 0x06, 0x00, 0x10, 0x06, 0x00, 0x30, 0x07, 0x00, 0x30, 0xFF, 0x0F, 0x18, 0xFE, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ñ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x08, 0xFE, 0x07, 0x18, 0x07, 0x0F, 0x38, 0x07, 0x0E, 0x30, 0x07, 0x0E, 0x20, 0x07, 0x0F, 0x00, 0xFE, 0x07, 0x00, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ò - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x00, 0xFE, 0x07, 0x20, 0x07, 0x0F, 0x30, 0x07, 0x0E, 0x38, 0x07, 0x0E, 0x18, 0x07, 0x0F, 0x08, 0xFE, 0x07, 0x00, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ó - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x20, 0xFE, 0x07, 0x30, 0x07, 0x0F, 0x18, 0x07, 0x0E, 0x18, 0x07, 0x0E, 0x30, 0x07, 0x0F, 0x20, 0xFE, 0x07, 0x00, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ô - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x30, 0xFC, 0x03, 0x38, 0xFE, 0x07, 0x18, 0x07, 0x0F, 0x18, 0x07, 0x0E, 0x30, 0x07, 0x0E, 0x30, 0x07, 0x0F, 0x38, 0xFE, 0x07, 0x18, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char õ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x38, 0xFE, 0x07, 0x38, 0x07, 0x0F, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x38, 0x07, 0x0F, 0x38, 0xFE, 0x07, 0x00, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ö - 0x0C, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xEE, 0x07, 0x00, 0xEE, 0x07, 0x00, 0xEE, 0x07, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ÷ - 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x11, 0x00, 0xFC, 0x0F, 0x00, 0xFE, 0x07, 0x00, 0x87, 0x0F, 0x00, 0xE7, 0x0E, 0x00, 0x77, 0x0E, 0x00, 0x1E, 0x0F, 0x00, 0xFE, 0x07, 0x00, 0xFF, 0x03, 0x80, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ø - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x08, 0xFF, 0x07, 0x08, 0xFF, 0x0F, 0x18, 0x00, 0x0E, 0x30, 0x00, 0x06, 0x20, 0x00, 0x06, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ù - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x20, 0x00, 0x0E, 0x30, 0x00, 0x06, 0x18, 0x00, 0x06, 0x08, 0xFF, 0x07, 0x08, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ú - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xFF, 0x07, 0x30, 0xFF, 0x0F, 0x38, 0x00, 0x0E, 0x18, 0x00, 0x06, 0x38, 0x00, 0x06, 0x30, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char û - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xFF, 0x07, 0x38, 0xFF, 0x0F, 0x38, 0x00, 0x0E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x38, 0xFF, 0x07, 0x38, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ü - 0x0A, 0x00, 0x01, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x7F, 0xE0, 0x20, 0xFC, 0xF3, 0x30, 0xE0, 0x7F, 0x38, 0x80, 0x3F, 0x18, 0xF8, 0x07, 0x08, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ý - 0x0B, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x00, 0x06, 0x06, 0x00, 0x06, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x0F, 0x0E, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x07, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char þ - 0x0A, 0x00, 0x01, 0x00, 0x00, 0x1F, 0xE0, 0x38, 0xFF, 0xE0, 0x38, 0xFC, 0xF7, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x3F, 0x38, 0xF0, 0x0F, 0x38, 0xFF, 0x01, 0x00, 0x1F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ - }; - -const struct GDS_FontDef Font_line_2 = { - Archivo_Narrow18x24, - 18, - 24, - ' ', - '\xFF', - false -}; diff --git a/components/display/fonts/font_tarable7seg_16x32.c b/components/display/fonts/font_tarable7seg_16x32.c deleted file mode 100644 index 9cae1d64..00000000 --- a/components/display/fonts/font_tarable7seg_16x32.c +++ /dev/null @@ -1,119 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Tarable7Seg_16x32 -//GLCD FontSize : 16 x 32 - -static const uint8_t Tarable7Seg_16x32[ ] = { - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char % - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE2, 0x0F, 0xF0, 0x47, 0x06, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x60, 0xE2, 0x0F, 0xF0, 0x47, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char 0 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0xF0, 0x07, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char 1 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x0F, 0x02, 0x80, 0xF1, 0x47, 0x06, 0xC0, 0x03, 0x60, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x06, 0xC0, 0x03, 0x60, 0xE2, 0x8F, 0x01, 0x40, 0xF0, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x01, 0x40, 0x06, 0xC0, 0x03, 0x60, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x06, 0xC0, 0x03, 0x60, 0xE2, 0x8F, 0xF1, 0x47, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char 3 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x8F, 0x01, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0xE0, 0x8F, 0xF1, 0x07, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char 4 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE2, 0x8F, 0x01, 0x40, 0x06, 0xC0, 0x03, 0x60, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x06, 0xC0, 0x03, 0x60, 0x02, 0x80, 0xF1, 0x47, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char 5 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE2, 0x8F, 0xF1, 0x47, 0x06, 0xC0, 0x03, 0x60, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x06, 0xC0, 0x03, 0x60, 0x02, 0x80, 0xF1, 0x47, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char 6 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xE2, 0x0F, 0xF0, 0x07, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char 7 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE2, 0x8F, 0xF1, 0x47, 0x06, 0xC0, 0x03, 0x60, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x06, 0xC0, 0x03, 0x60, 0xE2, 0x8F, 0xF1, 0x47, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char 8 - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE2, 0x8F, 0x01, 0x00, 0x06, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x06, 0xC0, 0x03, 0x00, 0xE2, 0x8F, 0xF1, 0x07, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char 9 - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char @ - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE2, 0x8F, 0xF1, 0x07, 0x06, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x06, 0xC0, 0x03, 0x00, 0xE2, 0x8F, 0xF1, 0x07, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char A - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE0, 0x8F, 0xF1, 0x47, 0x00, 0xC0, 0x03, 0x60, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x60, 0x00, 0x80, 0xF1, 0x47, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char B - 0x0D, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE2, 0x0F, 0xF0, 0x47, 0x06, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x80, 0xF1, 0x47, 0x00, 0xC0, 0x03, 0x60, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x60, 0xE0, 0x8F, 0xF1, 0x47, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char D - 0x0D, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE2, 0x8F, 0xF1, 0x47, 0x06, 0xC0, 0x03, 0x60, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x06, 0xC0, 0x03, 0x60, 0x02, 0x80, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E - 0x0D, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE2, 0x8F, 0xF1, 0x07, 0x06, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x06, 0xC0, 0x03, 0x00, 0x02, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE2, 0x8F, 0x01, 0x40, 0x06, 0xC0, 0x03, 0x60, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x06, 0xC0, 0x03, 0x60, 0xE2, 0x8F, 0xF1, 0x47, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char G - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE0, 0x8F, 0xF1, 0x07, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0xE0, 0x8F, 0xF1, 0x07, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char H - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0xF0, 0x07, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char I - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x47, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0xE0, 0x0F, 0xF0, 0x47, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE0, 0x8F, 0xF1, 0x07, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0xE0, 0x8F, 0xF1, 0x07, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char K - 0x0D, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE0, 0x0F, 0xF0, 0x47, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x0F, 0x02, 0x00, 0xF0, 0x07, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char M - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x80, 0xF1, 0x07, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x80, 0xF1, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char N - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE2, 0x0F, 0xF0, 0x47, 0x06, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x60, 0xE2, 0x0F, 0xF0, 0x47, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char O - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE2, 0x8F, 0xF1, 0x07, 0x06, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x06, 0xC0, 0x03, 0x00, 0xE2, 0x8F, 0x01, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE2, 0x8F, 0x01, 0x00, 0x06, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x0E, 0xC0, 0x03, 0x00, 0x06, 0xC0, 0x03, 0x00, 0xE2, 0x8F, 0xF1, 0x07, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char Q - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x80, 0xF1, 0x07, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE2, 0x8F, 0x01, 0x40, 0x06, 0xC0, 0x03, 0x60, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x06, 0xC0, 0x03, 0x60, 0x02, 0x80, 0xF1, 0x47, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char S - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xE2, 0x0F, 0xF0, 0x07, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char T - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE0, 0x0F, 0xF0, 0x47, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0xE0, 0x0F, 0xF0, 0x47, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char U - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x47, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x47, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char V - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60, 0xE0, 0x0F, 0x00, 0x40, 0xF0, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char W - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0xFC, 0x1F, 0xF0, 0x1F, 0xF8, 0x0F, 0xE0, 0x8F, 0xF1, 0x07, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0xE0, 0x8F, 0xF1, 0x07, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char X - 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0xE0, 0x8F, 0x01, 0x40, 0x00, 0xC0, 0x03, 0x60, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x70, 0x00, 0xC0, 0x03, 0x60, 0xE0, 0x8F, 0xF1, 0x47, 0xF0, 0x1F, 0xF8, 0x0F, 0xF8, 0x3F, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, // Code for char Y - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x0F, 0x02, 0x80, 0xF1, 0x47, 0x06, 0xC0, 0x03, 0x60, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x0E, 0xC0, 0x03, 0x70, 0x06, 0xC0, 0x03, 0x60, 0xE2, 0x8F, 0x01, 0x40, 0xF0, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char  -}; - -const struct GDS_FontDef Font_Tarable7Seg_16x32 = { - Tarable7Seg_16x32, - 16, - 32, - ' ', - 'Z', - true -}; diff --git a/components/display/fonts/font_tarable7seg_32x64.c b/components/display/fonts/font_tarable7seg_32x64.c deleted file mode 100644 index 81071e83..00000000 --- a/components/display/fonts/font_tarable7seg_32x64.c +++ /dev/null @@ -1,119 +0,0 @@ -#include - -//WARNING: This Font Require X-GLCD Lib. -// You can not use it with MikroE GLCD Lib. - -//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 -//MikroElektronika 2011 -//http://www.mikroe.com - -//GLCD FontName : Tarable7Seg_32x64 -//GLCD FontSize : 32 x 64 - -static const uint8_t Tarable7Seg_32x64[ ] = { - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char % - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x02, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x47, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0xE2, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x40, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x47, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x47, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char @ - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x47, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B - 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x47, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D - 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E - 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K - 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x02, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char M - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0xE2, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Q - 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x47, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x47, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xE0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x40, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char W - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0xE0, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x47, 0xF0, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x02, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x47, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0xE2, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x40, 0xF0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char  -}; - -const struct GDS_FontDef Font_Tarable7Seg_32x64 = { - Tarable7Seg_32x64, - 32, - 64, - ' ', - 'Z', - true -}; diff --git a/components/driver_bt/bt_app_core.h b/components/driver_bt/bt_app_core.h index e1730ed6..7ccf9651 100644 --- a/components/driver_bt/bt_app_core.h +++ b/components/driver_bt/bt_app_core.h @@ -13,6 +13,7 @@ #include #include #include +#include "Status.pb.h" #define BT_APP_CORE_TAG "BT_APP_CORE" #define BT_APP_SIG_WORK_DISPATCH (0x01) @@ -21,27 +22,9 @@ enum { BT_APP_EVT_STACK_UP = 0, }; -/* A2DP global state */ -enum { - APP_AV_STATE_IDLE, - APP_AV_STATE_DISCOVERING, - APP_AV_STATE_DISCOVERED, - APP_AV_STATE_UNCONNECTED, - APP_AV_STATE_CONNECTING, - APP_AV_STATE_CONNECTED, - APP_AV_STATE_DISCONNECTING, -}; -/* sub states of APP_AV_STATE_CONNECTED */ -enum { - APP_AV_MEDIA_STATE_IDLE, - APP_AV_MEDIA_STATE_STARTING, - APP_AV_MEDIA_STATE_STARTED, - APP_AV_MEDIA_STATE_STOPPING, - APP_AV_MEDIA_STATE_WAIT_DISCONNECT -}; -extern int bt_app_source_get_a2d_state(); -extern int bt_app_source_get_media_state(); +extern sys_AV_STATE bt_app_source_get_a2d_state(); +extern sys_MEDIA_STATE bt_app_source_get_media_state(); /** * @brief handler for the dispatched work */ diff --git a/components/driver_bt/bt_app_sink.c b/components/driver_bt/bt_app_sink.c index 70f42fec..c5e9db08 100644 --- a/components/driver_bt/bt_app_sink.c +++ b/components/driver_bt/bt_app_sink.c @@ -21,14 +21,14 @@ #include "esp_gap_bt_api.h" #include "esp_a2dp_api.h" #include "esp_avrc_api.h" -#include "nvs.h" -#include "platform_config.h" +#include "Configurator.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "tools.h" #include "audio_controls.h" #include "sys/lock.h" #include "display.h" +#include "accessors.h" // AVRCP used transaction label #define APP_RC_CT_TL_GET_CAPS (0) @@ -493,7 +493,7 @@ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param) static void volume_set_by_controller(uint8_t volume) { - // do not modified NVS volume + // do not modified state volume _lock_acquire(&s_volume_lock); s_volume = abs_volume = (volume * 100) / 127; _lock_release(&s_volume_lock); @@ -509,12 +509,10 @@ static void volume_set_by_local_host(int value, bool is_step) if (abs_volume >= 0) abs_volume = s_volume; else sink_volume = s_volume; _lock_release(&s_volume_lock); - - // volume has been set by controller, do not store it in NVS - if (abs_volume < 0) { - char p[4]; - config_set_value(NVS_TYPE_STR, "bt_sink_volume", itoa(s_volume, p, 10)); - } + if(sys_state->bt_sink_volume != s_volume){ + sys_state->bt_sink_volume = s_volume; + configurator_raise_state_changed(); + } if (s_volume_notify) { esp_avrc_rn_param_t rn_param; @@ -569,23 +567,25 @@ void bt_sink_init(bt_cmd_vcb_t cmd_cb, bt_data_cb_t data_cb) bt_app_a2d_cmd_cb = cmd_handler; cmd_handler_chain = cmd_cb; bt_app_a2d_data_cb = data_cb; + sys_BluetoothSink * bt_sink; + if(!SYS_SERVICES_BTSINK(bt_sink)){ + return; + } + char pin_code[ESP_BT_PIN_CODE_LEN+1] = "1234\0"; // create task and run event loop bt_app_task_start_up(bt_av_hdl_stack_evt); - char *item = config_alloc_get_default(NVS_TYPE_STR, "bt_sink_volume", "127", 0); - sink_volume = atol(item); - free(item); - + sink_volume = sys_state->bt_sink_volume; + /* * Set default parameters for Legacy Pairing */ esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED; + strncpy(pin_code,bt_sink->pin,sizeof(pin_code)); + if(SYS_SERVICES_BTSINK(bt_sink) && strlen(bt_sink->pin)>ESP_BT_PIN_CODE_LEN){ - char * pin_code = config_alloc_get_default(NVS_TYPE_STR, "bt_sink_pin", STR(CONFIG_BT_SINK_PIN), 0); - if(strlen(pin_code)>ESP_BT_PIN_CODE_LEN){ - - ESP_LOGW(BT_AV_TAG, "BT Sink pin code [%s] too long. ", pin_code); + ESP_LOGW(BT_AV_TAG, "BT Sink pin code [%s] too long. ", bt_sink->pin); pin_code[ESP_BT_PIN_CODE_LEN] = '\0'; ESP_LOGW(BT_AV_TAG, "BT Sink pin truncated code [%s]. ", pin_code); } @@ -654,9 +654,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) switch (event) { case BT_APP_EVT_STACK_UP: { /* set up device name */ - bt_name = (char * )config_alloc_get_default(NVS_TYPE_STR, "bt_name", CONFIG_BT_NAME, 0); - esp_bt_dev_set_device_name(bt_name); - free(bt_name); + esp_bt_dev_set_device_name(strlen(platform->names.bluetooth)>0?platform->names.bluetooth:platform->names.device); esp_bt_gap_register_callback(bt_app_gap_cb); /* initialize AVRCP controller */ diff --git a/components/driver_bt/bt_app_source - Copy.c.old b/components/driver_bt/bt_app_source - Copy.c.old index 29c54663..95b97d64 100644 --- a/components/driver_bt/bt_app_source - Copy.c.old +++ b/components/driver_bt/bt_app_source - Copy.c.old @@ -16,7 +16,8 @@ #include "esp_wifi.h" #include "freertos/timers.h" #include "argtable3/argtable3.h" -#include "platform_config.h" +// #include "Configurator.h" +#pragma message("fixme: search for TODO below") #include "messaging.h" #include "cJSON.h" #include "tools.h" diff --git a/components/driver_bt/bt_app_source.c b/components/driver_bt/bt_app_source.c index 503e0593..724ca50c 100644 --- a/components/driver_bt/bt_app_source.c +++ b/components/driver_bt/bt_app_source.c @@ -16,10 +16,12 @@ #include "esp_wifi.h" #include "freertos/timers.h" #include "argtable3/argtable3.h" -#include "platform_config.h" #include "messaging.h" #include "cJSON.h" #include "tools.h" +#include "accessors.h" +#include "Configurator.h" +#include "Status.pb.h" static const char * TAG = "bt_app_source"; static const char * BT_RC_CT_TAG="RCCT"; @@ -33,26 +35,8 @@ extern bool is_recovery_running; static void bt_app_av_state_connecting(uint16_t event, void *param); static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param); +sys_OutputBT * out_bt = NULL; -char * APP_AV_STATE_DESC[] = { - "APP_AV_STATE_IDLE", - "APP_AV_STATE_DISCOVERING", - "APP_AV_STATE_DISCOVERED", - "APP_AV_STATE_UNCONNECTED", - "APP_AV_STATE_CONNECTING", - "APP_AV_STATE_CONNECTED", - "APP_AV_STATE_DISCONNECTING" -}; -static char * ESP_AVRC_CT_DESC[]={ - "ESP_AVRC_CT_CONNECTION_STATE_EVT", - "ESP_AVRC_CT_PASSTHROUGH_RSP_EVT", - "ESP_AVRC_CT_METADATA_RSP_EVT", - "ESP_AVRC_CT_PLAY_STATUS_RSP_EVT", - "ESP_AVRC_CT_CHANGE_NOTIFY_EVT", - "ESP_AVRC_CT_REMOTE_FEATURES_EVT", - "ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT", - "ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT" - }; #define BT_APP_HEART_BEAT_EVT (0xff00) // AVRCP used transaction label @@ -92,8 +76,8 @@ static void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *even static esp_bd_addr_t s_peer_bda = {0}; static uint8_t s_peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; -int bt_app_source_a2d_state = APP_AV_STATE_IDLE; -int bt_app_source_media_state = APP_AV_MEDIA_STATE_IDLE; +sys_AV_STATE bt_app_source_a2d_state = sys_AV_STATE_A_IDLE; +sys_MEDIA_STATE bt_app_source_media_state = sys_MEDIA_STATE_M_IDLE; static uint32_t s_pkt_cnt = 0; static TimerHandle_t s_tmr=NULL; static int prev_duration=10000; @@ -191,22 +175,23 @@ static void peers_list_maintain(const char * s_peer_bdname, int32_t rssi){ } } -int bt_app_source_get_a2d_state(){ +sys_AV_STATE bt_app_source_get_a2d_state(){ if(!is_recovery_running){ // if we are in recovery mode, don't log BT status - ESP_LOGD(TAG,"a2dp status: %u = %s", bt_app_source_a2d_state, APP_AV_STATE_DESC[bt_app_source_a2d_state]); + ESP_LOGD(TAG,"a2dp status: %u = %s", bt_app_source_a2d_state, sys_AV_STATE_name(bt_app_source_a2d_state)); } return bt_app_source_a2d_state; } -int bt_app_source_get_media_state(){ - ESP_LOGD(TAG,"media state : %u ", bt_app_source_media_state); + +sys_MEDIA_STATE bt_app_source_get_media_state(){ + ESP_LOGD(TAG,"media state : %s ", sys_MEDIA_STATE_name(bt_app_source_media_state)); return bt_app_source_media_state; } void set_app_source_state(int new_state){ if(bt_app_source_a2d_state!=new_state){ - ESP_LOGD(TAG, "Updating state from %s to %s", APP_AV_STATE_DESC[bt_app_source_a2d_state], APP_AV_STATE_DESC[new_state]); + ESP_LOGD(TAG, "Updating state from %s to %s", sys_AV_STATE_name(bt_app_source_a2d_state), sys_AV_STATE_name(new_state)); bt_app_source_a2d_state=new_state; } } @@ -217,62 +202,20 @@ void set_a2dp_media_state(int new_state){ } } -void hal_bluetooth_init(const char * options) +void hal_bluetooth_init() { - struct { - struct arg_str *sink_name; - struct arg_end *end; - } squeezelite_args; - - ESP_LOGD(TAG,"Initializing Bluetooth HAL"); - - squeezelite_args.sink_name = arg_str0("n", "name", "", "the name of the bluetooth to connect to"); - squeezelite_args.end = arg_end(2); - - ESP_LOGD(TAG,"Copying parameters"); - char * opts = strdup_psram(options); - char **argv = malloc_init_external(sizeof(char**)*15); - - size_t argv_size=15; - - // change parms so ' appear as " for parsing the options - for (char* p = opts; (p = strchr(p, '\'')); ++p) *p = '"'; - ESP_LOGD(TAG,"Splitting arg line: %s", opts); - - argv_size = esp_console_split_argv(opts, argv, argv_size); - ESP_LOGD(TAG,"Parsing parameters"); - int nerrors = arg_parse(argv_size , argv, (void **) &squeezelite_args); - if (nerrors != 0) { - ESP_LOGD(TAG,"Parsing Errors"); - arg_print_errors(stdout, squeezelite_args.end, "BT"); - arg_print_glossary_gnu(stdout, (void **) &squeezelite_args); - free(opts); - free(argv); - return; - } - - if(squeezelite_args.sink_name->count == 0) - { - squeezelite_conf.sink_name = config_alloc_get_default(NVS_TYPE_STR, "a2dp_sink_name", NULL, 0); - if(!squeezelite_conf.sink_name || strlen(squeezelite_conf.sink_name)==0 ){ - ESP_LOGW(TAG,"Unable to retrieve the a2dp sink name from nvs."); - } - } else { - squeezelite_conf.sink_name=strdup_psram(squeezelite_args.sink_name->sval[0]); - // sync with NVS - esp_err_t err=ESP_OK; - if((err= config_set_value(NVS_TYPE_STR, "a2dp_sink_name", squeezelite_args.sink_name->sval[0]))!=ESP_OK){ - ESP_LOGE(TAG,"Error setting Bluetooth audio device name %s. %s",squeezelite_args.sink_name->sval[0], esp_err_to_name(err)); - } - else { - ESP_LOGI(TAG,"Bluetooth audio device name changed to %s",squeezelite_args.sink_name->sval[0]); - } + + if(!ASSIGN_COND_VAL_3LVL(services,squeezelite,output_bt,out_bt) ){ + ESP_LOGD(TAG,"Bluetooth not configured"); + return; } + if(strlen(out_bt->sink_name) == 0){ + ESP_LOGE(TAG,"Sink name not configured!"); + return; + } + ESP_LOGD(TAG,"Initializing bluetooth sink"); + - ESP_LOGD(TAG,"Freeing options"); - free(argv); - free(opts); - // create task and run event loop bt_app_task_start_up(bt_av_hdl_stack_evt); @@ -281,9 +224,17 @@ void hal_bluetooth_init(const char * options) * Use variable pin, input pin code when pairing */ esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE; - esp_bt_pin_code_t pin_code; - esp_bt_gap_set_pin(pin_type, 0, pin_code); - + uint8_t pin_code_len; + uint8_t *pin_code; + if(strlen(out_bt->pin) == 0){ + pin_code = (uint8_t *)"0000"; + pin_code_len = 4; + } + else { + pin_code = (uint8_t *) out_bt->pin; + pin_code_len = strlen(out_bt->pin); + } + esp_bt_gap_set_pin(pin_type, pin_code_len,pin_code); } void hal_bluetooth_stop(void) { @@ -296,8 +247,16 @@ static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) } static void handle_bt_gap_pin_req(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param){ - char * pin_str = config_alloc_get_default(NVS_TYPE_STR, "a2dp_spin", "0000", 0); - int pinlen=pin_str?strlen(pin_str):0; + + uint8_t pinlen; + char *pin_str; + if(strlen(out_bt->pin) == 0){ + pin_str = "0000"; + } + else { + pin_str = out_bt->pin; + } + pinlen = strlen(pin_str); if (pin_str && ((!param->pin_req.min_16_digit && pinlen==4) || (param->pin_req.min_16_digit && pinlen==16))) { ESP_LOGI(TAG,"Input pin code %s: ",pin_str); esp_bt_pin_code_t pin_code; @@ -328,7 +287,6 @@ static void handle_bt_gap_pin_req(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_par esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code); } } - FREE_AND_NULL(pin_str); } static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) @@ -343,8 +301,8 @@ static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) { peers_list_maintain(NULL, PEERS_LIST_MAINTAIN_PURGE); - if (bt_app_source_a2d_state == APP_AV_STATE_DISCOVERED) { - set_app_source_state(APP_AV_STATE_CONNECTING); + if (bt_app_source_a2d_state == sys_AV_STATE_A_DISCOVERED) { + set_app_source_state(sys_AV_STATE_A_CONNECTING); ESP_LOGI(TAG,"Discovery completed. Ready to start connecting to %s. ", s_peer_bdname); esp_a2d_source_connect(s_peer_bda); } else { @@ -445,7 +403,7 @@ static const char * conn_state_str(esp_a2d_connection_state_t state){ static void unexpected_connection_state(int from, esp_a2d_connection_state_t to) { - ESP_LOGW(TAG,"Unexpected connection state change. App State: %s (%u) Connection State %s (%u)", APP_AV_STATE_DESC[from], from,conn_state_str(to), to); + ESP_LOGW(TAG,"Unexpected connection state change. App State: %s (%u) Connection State %s (%u)", sys_AV_STATE_name(from), from,conn_state_str(to), to); } static void handle_connect_state_unconnected(uint16_t event, esp_a2d_cb_param_t *param){ @@ -486,20 +444,20 @@ static void handle_connect_state_connecting(uint16_t event, esp_a2d_cb_param_t * else { ESP_LOGW(TAG,"A2DP connect unsuccessful"); } - set_app_source_state(APP_AV_STATE_UNCONNECTED); + set_app_source_state(sys_AV_STATE_A_UNCONNECTED); break; case ESP_A2D_CONNECTION_STATE_CONNECTING: break; case ESP_A2D_CONNECTION_STATE_CONNECTED: - set_app_source_state(APP_AV_STATE_CONNECTED); - set_a2dp_media_state(APP_AV_MEDIA_STATE_IDLE); + set_app_source_state(sys_AV_STATE_A_CONNECTED); + set_a2dp_media_state(sys_MEDIA_STATE_M_IDLE); ESP_LOGD(TAG,"Setting scan mode to ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE"); esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); ESP_LOGD(TAG,"Done setting scan mode. App state is now CONNECTED and media state IDLE."); break; case ESP_A2D_CONNECTION_STATE_DISCONNECTING: unexpected_connection_state(bt_app_source_a2d_state, param->conn_stat.state); - set_app_source_state(APP_AV_STATE_DISCONNECTING); + set_app_source_state(sys_AV_STATE_A_CONNECTING); break; default: break; @@ -511,7 +469,7 @@ static void handle_connect_state_connected(uint16_t event, esp_a2d_cb_param_t *p { case ESP_A2D_CONNECTION_STATE_DISCONNECTED: ESP_LOGW(TAG,"a2dp disconnected"); - set_app_source_state(APP_AV_STATE_UNCONNECTED); + set_app_source_state(sys_AV_STATE_A_UNCONNECTED); esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); break; case ESP_A2D_CONNECTION_STATE_CONNECTING: @@ -521,7 +479,7 @@ static void handle_connect_state_connected(uint16_t event, esp_a2d_cb_param_t *p unexpected_connection_state(bt_app_source_a2d_state, param->conn_stat.state); break; case ESP_A2D_CONNECTION_STATE_DISCONNECTING: - set_app_source_state(APP_AV_STATE_DISCONNECTING); + set_app_source_state(sys_AV_STATE_A_DISCONNECTING); break; default: @@ -535,7 +493,7 @@ static void handle_connect_state_disconnecting(uint16_t event, esp_a2d_cb_param_ { case ESP_A2D_CONNECTION_STATE_DISCONNECTED: ESP_LOGI(TAG,"a2dp disconnected"); - set_app_source_state(APP_AV_STATE_UNCONNECTED); + set_app_source_state(sys_AV_STATE_A_UNCONNECTED); esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); break; case ESP_A2D_CONNECTION_STATE_CONNECTING: @@ -555,24 +513,24 @@ static void handle_connect_state_disconnecting(uint16_t event, esp_a2d_cb_param_ static void bt_app_av_sm_hdlr(uint16_t event, void *param) { - ESP_LOGV(TAG,"bt_app_av_sm_hdlr.%s a2d state: %s", event==BT_APP_HEART_BEAT_EVT?"Heart Beat.":"",APP_AV_STATE_DESC[bt_app_source_a2d_state]); + ESP_LOGV(TAG,"bt_app_av_sm_hdlr.%s a2d state: %s", event==BT_APP_HEART_BEAT_EVT?"Heart Beat.":"",sys_AV_STATE_name(bt_app_source_a2d_state)); switch (bt_app_source_a2d_state) { - case APP_AV_STATE_DISCOVERING: - ESP_LOGV(TAG,"state %s, evt 0x%x, output state: %s", APP_AV_STATE_DESC[bt_app_source_a2d_state], event, output_state_str()); + case sys_AV_STATE_A_DISCOVERING: + ESP_LOGV(TAG,"state %s, evt 0x%x, output state: %s", sys_AV_STATE_name(bt_app_source_a2d_state), event, output_state_str()); break; - case APP_AV_STATE_DISCOVERED: - ESP_LOGV(TAG,"state %s, evt 0x%x, output state: %s", APP_AV_STATE_DESC[bt_app_source_a2d_state], event, output_state_str()); + case sys_AV_STATE_A_DISCOVERED: + ESP_LOGV(TAG,"state %s, evt 0x%x, output state: %s", sys_AV_STATE_name(bt_app_source_a2d_state), event, output_state_str()); break; - case APP_AV_STATE_UNCONNECTED: + case sys_AV_STATE_A_UNCONNECTED: bt_app_av_state_unconnected(event, param); break; - case APP_AV_STATE_CONNECTING: + case sys_AV_STATE_A_CONNECTING: bt_app_av_state_connecting(event, param); break; - case APP_AV_STATE_CONNECTED: + case sys_AV_STATE_A_CONNECTED: bt_app_av_state_connected(event, param); break; - case APP_AV_STATE_DISCONNECTING: + case sys_AV_STATE_A_DISCONNECTING: bt_app_av_state_disconnecting(event, param); break; default: @@ -633,7 +591,7 @@ static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param) uint8_t nameLen = 0; esp_bt_gap_dev_prop_t *p; memset(bda_str, 0x00, sizeof(bda_str)); - if(bt_app_source_a2d_state != APP_AV_STATE_DISCOVERING) + if(bt_app_source_a2d_state != sys_AV_STATE_A_DISCOVERING) { // Ignore messages that might have been queued already // when we've discovered the target device. @@ -692,7 +650,7 @@ static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param) if (squeezelite_conf.sink_name && strlen(squeezelite_conf.sink_name) >0 && strcmp((char *)s_peer_bdname, squeezelite_conf.sink_name) == 0) { ESP_LOGI(TAG,"Found our target device. address %s, name %s", bda_str, s_peer_bdname); memcpy(s_peer_bda, param->disc_res.bda, ESP_BD_ADDR_LEN); - set_app_source_state(APP_AV_STATE_DISCOVERED); + set_app_source_state(sys_AV_STATE_A_DISCOVERED); esp_bt_gap_cancel_discovery(); } else { ESP_LOGV(TAG,"Not the device we are looking for (%s). Continuing scan", squeezelite_conf.sink_name?squeezelite_conf.sink_name:"N/A"); @@ -706,17 +664,16 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) ESP_LOGI(TAG,"BT Stack going up."); /* set up device name */ - - char * a2dp_dev_name = config_alloc_get_default(NVS_TYPE_STR, "a2dp_dev_name", CONFIG_A2DP_DEV_NAME, 0); - if(a2dp_dev_name == NULL){ - ESP_LOGW(TAG,"Unable to retrieve the a2dp device name from nvs"); - esp_bt_dev_set_device_name(CONFIG_A2DP_DEV_NAME); - } - else { - esp_bt_dev_set_device_name(a2dp_dev_name); - free(a2dp_dev_name); - } - + if(!out_bt){ + ESP_LOGE(TAG,"Output to bluetooth misconfigured."); + return; + } + if(strlen(out_bt->sink_name)==0){ + ESP_LOGE(TAG,"Bluetooth sink name not configured"); + return; + } + esp_bt_dev_set_device_name(out_bt->sink_name); + ESP_LOGI(TAG,"Preparing to connect"); /* register GAP callback function */ @@ -741,7 +698,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) /* start device discovery */ ESP_LOGI(TAG,"Starting device discovery..."); - set_app_source_state(APP_AV_STATE_DISCOVERING); + set_app_source_state(sys_AV_STATE_A_DISCOVERING); esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); /* create and start heart beat timer */ @@ -765,7 +722,7 @@ static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t case ESP_AVRC_CT_REMOTE_FEATURES_EVT: case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: case ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT: { - ESP_LOGD(TAG,"Received %s message", ESP_AVRC_CT_DESC[event]); + ESP_LOGD(TAG,"Received %s message", sys_ESP_AVRC_CT_name(event)); bt_app_work_dispatch(bt_av_hdl_avrc_ct_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); break; } @@ -778,7 +735,7 @@ static void bt_app_av_media_proc(uint16_t event, void *param) { esp_a2d_cb_param_t *a2d = NULL; switch (bt_app_source_media_state) { - case APP_AV_MEDIA_STATE_IDLE: { + case sys_MEDIA_STATE_M_IDLE: { if (event == BT_APP_HEART_BEAT_EVT) { if(!output_stopped()) { @@ -792,34 +749,34 @@ static void bt_app_av_media_proc(uint16_t event, void *param) a2d->media_ctrl_stat.status == ESP_A2D_MEDIA_CTRL_ACK_SUCCESS ) { ESP_LOGI(TAG,"a2dp media ready, starting playback!"); - set_a2dp_media_state(APP_AV_MEDIA_STATE_STARTING); + set_a2dp_media_state(sys_MEDIA_STATE_M_STARTING); esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_START); } } break; } - case APP_AV_MEDIA_STATE_STARTING: { + case sys_MEDIA_STATE_M_STARTING: { if (event == ESP_A2D_MEDIA_CTRL_ACK_EVT) { a2d = (esp_a2d_cb_param_t *)(param); if (a2d->media_ctrl_stat.cmd == ESP_A2D_MEDIA_CTRL_START && a2d->media_ctrl_stat.status == ESP_A2D_MEDIA_CTRL_ACK_SUCCESS) { ESP_LOGI(TAG,"a2dp media started successfully."); output_bt_start(); - set_a2dp_media_state(APP_AV_MEDIA_STATE_STARTED); + set_a2dp_media_state(sys_MEDIA_STATE_M_STARTED); } else { // not started succesfully, transfer to idle state ESP_LOGI(TAG,"a2dp media start failed."); - set_a2dp_media_state(APP_AV_MEDIA_STATE_IDLE); + set_a2dp_media_state(sys_MEDIA_STATE_M_IDLE); } } break; } - case APP_AV_MEDIA_STATE_STARTED: { + case sys_MEDIA_STATE_M_STARTED: { if (event == BT_APP_HEART_BEAT_EVT) { if(output_stopped()) { ESP_LOGI(TAG,"Output state is %s. Stopping a2dp media ...", output_state_str()); - set_a2dp_media_state(APP_AV_MEDIA_STATE_STOPPING); + set_a2dp_media_state(sys_MEDIA_STATE_M_STOPPING); esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_STOP); } else { output_bt_tick(); @@ -827,15 +784,15 @@ static void bt_app_av_media_proc(uint16_t event, void *param) } break; } - case APP_AV_MEDIA_STATE_STOPPING: { - ESP_LOG_DEBUG_EVENT(TAG,QUOTE(APP_AV_MEDIA_STATE_STOPPING)); + case sys_MEDIA_STATE_M_STOPPING: { + ESP_LOG_DEBUG_EVENT(TAG,QUOTE(sys_MEDIA_STATE_M_STOPPING)); if (event == ESP_A2D_MEDIA_CTRL_ACK_EVT) { a2d = (esp_a2d_cb_param_t *)(param); if (a2d->media_ctrl_stat.cmd == ESP_A2D_MEDIA_CTRL_STOP && a2d->media_ctrl_stat.status == ESP_A2D_MEDIA_CTRL_ACK_SUCCESS) { ESP_LOGI(TAG,"a2dp media stopped successfully..."); output_bt_stop(); - set_a2dp_media_state(APP_AV_MEDIA_STATE_IDLE); + set_a2dp_media_state(sys_MEDIA_STATE_M_IDLE); } else { ESP_LOGI(TAG,"a2dp media stopping..."); esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_STOP); @@ -844,9 +801,9 @@ static void bt_app_av_media_proc(uint16_t event, void *param) break; } - case APP_AV_MEDIA_STATE_WAIT_DISCONNECT:{ + case sys_MEDIA_STATE_M_WAIT_DISCONNECT:{ esp_a2d_source_disconnect(s_peer_bda); - set_app_source_state(APP_AV_STATE_DISCONNECTING); + set_app_source_state(sys_AV_STATE_A_DISCONNECTING); ESP_LOGI(TAG,"a2dp disconnecting..."); } } @@ -886,11 +843,11 @@ static void bt_app_av_state_unconnected(uint16_t event, void *param) uint8_t *p = s_peer_bda; ESP_LOGI(TAG, "a2dp connecting to %s, BT peer: %02x:%02x:%02x:%02x:%02x:%02x",s_peer_bdname,p[0], p[1], p[2], p[3], p[4], p[5]); if(esp_a2d_source_connect(s_peer_bda)==ESP_OK) { - set_app_source_state(APP_AV_STATE_CONNECTING); + set_app_source_state(sys_AV_STATE_A_CONNECTING); s_connecting_intv = 0; } else { - set_app_source_state(APP_AV_STATE_UNCONNECTED); + set_app_source_state(sys_AV_STATE_A_UNCONNECTED); // there was an issue connecting... continue to discover ESP_LOGE(TAG,"Attempt at connecting failed, restart at discover..."); esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); @@ -920,7 +877,7 @@ static void bt_app_av_state_connecting(uint16_t event, void *param) break; case BT_APP_HEART_BEAT_EVT: if (++s_connecting_intv >= 2) { - set_app_source_state(APP_AV_STATE_UNCONNECTED); + set_app_source_state(sys_AV_STATE_A_UNCONNECTED); ESP_LOGW(TAG,"A2DP Connect time out! Setting state to Unconnected. "); s_connecting_intv = 0; } diff --git a/components/led_strip/led_vu.c b/components/led_strip/led_vu.c index 1db3449c..6367208c 100644 --- a/components/led_strip/led_vu.c +++ b/components/led_strip/led_vu.c @@ -23,7 +23,8 @@ #include "globdefs.h" #include "monitor.h" #include "led_strip.h" -#include "platform_config.h" +#include "Configurator.h" +#include "accessors.h" #include "led_vu.h" static const char *TAG = "led_vu"; @@ -76,24 +77,23 @@ static void battery_svc(float value, int cells) { */ void led_vu_init() { - char* p; - char* config = config_alloc_get_str("led_vu_config", NULL, "N/A"); + sys_LEDStrip * config = NULL; + if(!SYS_DEV_LEDSTRIP(config)){ + return; + } + if(!!config->has_gpio ){ + return; + } + // char* config = config_alloc_get_str("led_vu_config", NULL, "N/A"); // Initialize led VU strip - char* drivername = strcasestr(config, "WS2812"); - - if ((p = strcasestr(config, "length")) != NULL) { - strip.length = atoi(strchr(p, '=') + 1); - } // else 0 - if ((p = strcasestr(config, "gpio")) != NULL) { - strip.gpio = atoi(strchr(p, '=') + 1); - } else { - strip.gpio = LED_VU_DEFAULT_GPIO; - } + strip.length = config->length; + strip.gpio = config->gpio.pin; + // check for valid configuration - if (!drivername || !strip.gpio) { + if (config->strip_type == sys_LEDStripType_LS_UNKNOWN || !config->has_gpio || config->gpio.pin <0) { ESP_LOGI(TAG, "led_vu configuration invalid"); - goto done; + return; } battery_handler_chain = battery_handler_svc; @@ -117,7 +117,7 @@ void led_vu_init() ESP_LOGI(TAG, "vu meter using length:%d left:%d right:%d status:%d", strip.vu_length, strip.vu_start_l, strip.vu_start_r, strip.vu_status); // create driver configuration - led_strip_config.rgb_led_type = RGB_LED_TYPE_WS2812; + led_strip_config.rgb_led_type = config->strip_type == sys_LEDStripType_LS_WS2812?RGB_LED_TYPE_WS2812:RGB_LED_TYPE_MAX; led_strip_config.access_semaphore = xSemaphoreCreateBinary(); led_strip_config.led_strip_length = strip.length; led_strip_config.led_strip_working = heap_caps_malloc(strip.length * sizeof(struct led_color_t), MALLOC_CAP_8BIT); @@ -132,7 +132,7 @@ void led_vu_init() ESP_LOGI(TAG, "led_vu using gpio:%d length:%d on channel:%d", strip.gpio, strip.length, led_strip_config.rmt_channel); } else { ESP_LOGE(TAG, "led_vu init failed"); - goto done; + return; } // reserver max memory for remote management systems @@ -140,9 +140,6 @@ void led_vu_init() led_vu_clear(led_display); - done: - free(config); - return; } inline bool inRange(double x, double y, double z) { diff --git a/components/metrics/Batch.cpp b/components/metrics/Batch.cpp index 9555a20e..ebe37455 100644 --- a/components/metrics/Batch.cpp +++ b/components/metrics/Batch.cpp @@ -6,15 +6,12 @@ #include "esp_netif.h" #include "esp_ota_ops.h" #include "esp_tls.h" -#include "nvs_flash.h" + #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE #include "esp_crt_bundle.h" #endif #include "esp_system.h" #include "http_handlers.h" -#include "nvs.h" -#include "nvs_flash.h" -#include "nvs_utilities.h" #include "tools.h" #include #include @@ -85,7 +82,7 @@ void Batch::push() { _events.clear(); } FREE_AND_NULL(json_str) - ESP_LOGD(TAG, "Total duration for metrics call: %lu. ", gettime_ms() - start_time); + ESP_LOGD(TAG, "Total duration for metrics call: %u. ", gettime_ms() - start_time); } void Batch::build_guid() { diff --git a/components/metrics/Events.h b/components/metrics/Events.h index ec616623..f424d36b 100644 --- a/components/metrics/Events.h +++ b/components/metrics/Events.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace Metrics { struct StrCompare { @@ -45,7 +46,7 @@ class Event { } private: char* _name = nullptr; - uint32_t _time; + std::time_t _time; cJSON* _json = nullptr; }; diff --git a/components/metrics/Metrics.cpp b/components/metrics/Metrics.cpp index a93f9d60..d1656ee2 100644 --- a/components/metrics/Metrics.cpp +++ b/components/metrics/Metrics.cpp @@ -9,7 +9,6 @@ #include "esp_tls.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "nvs_flash.h" #include "tools.h" #include #include @@ -21,7 +20,8 @@ #include "cJSON.h" #include "freertos/timers.h" #include "network_manager.h" -#include "platform_config.h" +// #include "Configurator.h" +#pragma message("fixme: search for TODO below") static const char* TAG = "metrics"; @@ -36,7 +36,7 @@ static uint32_t metrics_usage_gen_time = 0; #pragma message "Metrics API key needs to be passed from the environment" #define METRICS_API_KEY "ZZZ" #endif -static const char* metrics_api_key = +static const char* metrics_api_key = METRICS_API_KEY; static const char* parms_str = "params"; static const char* properties_str = "properties"; static const char* user_properties_str = "user_properties"; diff --git a/components/platform_config/CMakeLists.txt b/components/platform_config/CMakeLists.txt index 808e01d6..d13b2517 100644 --- a/components/platform_config/CMakeLists.txt +++ b/components/platform_config/CMakeLists.txt @@ -1,7 +1,5 @@ -idf_component_register( SRC_DIRS . +idf_component_register(SRC_DIRS . INCLUDE_DIRS . - PRIV_REQUIRES tools newlib console esp_common freertos tools - REQUIRES nvs_flash json + PRIV_REQUIRES tools newlib console esp_common freertos tools services + REQUIRES spiffs ) - - diff --git a/components/platform_config/Configurator.cpp b/components/platform_config/Configurator.cpp new file mode 100644 index 00000000..382c7442 --- /dev/null +++ b/components/platform_config/Configurator.cpp @@ -0,0 +1,480 @@ +#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE +#include "Configurator.h" +#include "esp_log.h" +#include "esp_system.h" +#include "pb_common.h" // Nanopb header for encoding (serialization) +#include "pb_decode.h" // Nanopb header for decoding (deserialization) +#include "pb_encode.h" // Nanopb header for encoding (serialization) +// #include "sys_options.h" +#include "tools.h" +#include +#include +static const char* TAG = "Configurator"; +static const char* targets_folder = "targets"; +static const char* config_file_name = "settings.bin"; +static const char* state_file_name = "state.bin"; +__attribute__((section(".ext_ram.bss"))) PlatformConfig::Configurator configurator; +sys_Config* platform = NULL; +sys_State* sys_state = NULL; + +bool set_pb_string_from_mac(pb_ostream_t* stream, const pb_field_t* field, void* const* arg) { + if (!stream) { + // This is a size calculation pass, return true to indicate field presence + return true; + } + + // Generate the string based on MAC and prefix + const char* prefix = reinterpret_cast(*arg); + char* value = alloc_get_string_with_mac(prefix && strlen(prefix) > 0 ? prefix : "squeezelite-"); + + // Write the string to the stream + if (!pb_encode_string(stream, (uint8_t*)value, strlen(value))) { + free(value); // Free memory if encoding fails + return false; + } + + free(value); // Free memory after encoding + return true; +} + +namespace PlatformConfig { + +EXT_RAM_ATTR static const int NO_COMMIT_PENDING = BIT0; +EXT_RAM_ATTR static const int LOAD_BIT = BIT1; +EXT_RAM_ATTR static const int NO_STATE_COMMIT_PENDING = BIT2; + +const int Configurator::MaxDelay = 1000; +const int Configurator::LockMaxWait = 20 * Configurator::MaxDelay; + +EXT_RAM_ATTR TimerHandle_t Configurator::_timer; +EXT_RAM_ATTR SemaphoreHandle_t Configurator::_mutex; +EXT_RAM_ATTR SemaphoreHandle_t Configurator::_state_mutex; +EXT_RAM_ATTR EventGroupHandle_t Configurator::_group; + +static void ConfiguratorCallback(TimerHandle_t xTimer) { + static int cnt = 0, scnt = 0; + if (configurator.HasChanges()) { + ESP_LOGI(TAG, "Configuration has some uncommitted entries"); + configurator.CommitChanges(); + } else { + if (++cnt >= 15) { + ESP_LOGV(TAG, "commit timer: commit flag not set"); + cnt = 0; + } + } + if (configurator.HasStateChanges()) { + ESP_LOGI(TAG, "State has some uncommitted changes"); + configurator.CommitState(); + } else { + if (++scnt >= 15) { + ESP_LOGV(TAG, "commit timer: commit flag not set"); + cnt = 0; + } + } + xTimerReset(xTimer, 10); +} +void Configurator::RaiseStateModified() { SetGroupBit(NO_STATE_COMMIT_PENDING, false); } +void Configurator::RaiseModified() { SetGroupBit(NO_COMMIT_PENDING, false); } +void Configurator::ResetModified() { + ESP_LOGV(TAG, "Resetting the global commit flag."); + SetGroupBit(NO_COMMIT_PENDING, false); +} +void Configurator::ResetStateModified() { + ESP_LOGV(TAG, "Resetting the state commit flag."); + SetGroupBit(NO_STATE_COMMIT_PENDING, false); +} +bool Configurator::SetGroupBit(int bit_num, bool flag) { + bool result = true; + int curFlags = xEventGroupGetBits(_group); + if ((curFlags & LOAD_BIT) && bit_num == NO_COMMIT_PENDING) { + ESP_LOGD(TAG, "Loading config, ignoring changes"); + result = false; + } + if (result) { + bool curBit = (xEventGroupGetBits(_group) & bit_num); + if (curBit == flag) { + ESP_LOGV(TAG, "Flag %d already %s", bit_num, flag ? "Set" : "Cleared"); + result = false; + } + } + if (result) { + ESP_LOGV(TAG, "%s Flag %d ", flag ? "Setting" : "Clearing", bit_num); + if (!flag) { + xEventGroupClearBits(_group, bit_num); + } else { + xEventGroupSetBits(_group, bit_num); + } + } + return result; +} +bool Configurator::Lock() { + ESP_LOGV(TAG, "Locking Configurator"); + if (xSemaphoreTake(_mutex, LockMaxWait) == pdTRUE) { + ESP_LOGV(TAG, "Configurator locked!"); + return true; + } else { + ESP_LOGE(TAG, "Semaphore take failed. Unable to lock Configurator"); + return false; + } +} +bool Configurator::LockState() { + ESP_LOGV(TAG, "Locking State"); + if (xSemaphoreTake(_state_mutex, LockMaxWait) == pdTRUE) { + ESP_LOGV(TAG, "State locked!"); + return true; + } else { + ESP_LOGE(TAG, "Semaphore take failed. Unable to lock State"); + return false; + } +} +void* Configurator::AllocGetConfigBuffer(size_t* sz, sys_Config* config) { + size_t datasz; + pb_byte_t* data = NULL; + + if (!pb_get_encoded_size(&datasz, sys_Config_fields, (const void*)platform) || datasz <= 0) { + return data; + } + data = (pb_byte_t*)malloc_init_external(datasz * sizeof(pb_byte_t)); + pb_ostream_t stream = pb_ostream_from_buffer(data, datasz); + pb_encode(&stream, sys_Config_fields, (const void*)platform); + if (sz) { + *sz = datasz * sizeof(pb_byte_t); + } + return data; +} +void* Configurator::AllocGetConfigBuffer(size_t* sz) { + return AllocGetConfigBuffer(sz, &this->_root); +} +bool Configurator::WaitForCommit() { + bool commit_pending = (xEventGroupGetBits(_group) & NO_COMMIT_PENDING) == 0; + while (commit_pending) { + ESP_LOGW(TAG, "Waiting for config commit ..."); + commit_pending = (xEventGroupWaitBits(_group, NO_COMMIT_PENDING | NO_STATE_COMMIT_PENDING, pdFALSE, pdTRUE, + (MaxDelay * 2) / portTICK_PERIOD_MS) & + ( NO_COMMIT_PENDING | NO_STATE_COMMIT_PENDING)) == 0; + if (commit_pending) { + ESP_LOGW(TAG, "Timeout waiting for config commit."); + } else { + ESP_LOGI(TAG, "Config committed!"); + } + } + return !commit_pending; +} +void Configurator::CommitChanges() { + esp_err_t err = ESP_OK; + ESP_LOGI(TAG, "Committing configuration to flash. Locking config object."); + if (!Lock()) { + ESP_LOGE(TAG, "Unable to lock config for commit "); + return; + } + ESP_LOGV(TAG, "Config Locked. Committing"); + Commit(&_root); + ResetModified(); + Unlock(); + ESP_LOGI(TAG, "Done Committing configuration to flash."); +} + +bool Configurator::CommitState() { + esp_err_t err = ESP_OK; + ESP_LOGI(TAG, "Committing configuration to flash. Locking config object."); + if (!LockState()) { + ESP_LOGE(TAG, "Unable to lock config for commit "); + return false; + } + ESP_LOGV(TAG, "Config Locked. Committing"); + CommitState(&_sys_state); + ResetStateModified(); + Unlock(); + ESP_LOGI(TAG, "Done Committing configuration to flash."); + return true; +} +bool Configurator::HasChanges() { return (xEventGroupGetBits(_group) & NO_COMMIT_PENDING); } +bool Configurator::HasStateChanges() { return (xEventGroupGetBits(_group) & NO_STATE_COMMIT_PENDING); } +void Configurator::Unlock() { + ESP_LOGV(TAG, "Unlocking Configurator!"); + xSemaphoreGive(_mutex); +} +void Configurator::UnlockState() { + ESP_LOGV(TAG, "Unlocking State!"); + xSemaphoreGive(_state_mutex); +} + +void Configurator::ResetStructure(sys_Config* config) { + if (!config) { + return; + } + sys_Config blankconfig = sys_Config_init_default; + memcpy(config, &blankconfig, sizeof(blankconfig)); +} +bool Configurator::LoadDecodeBuffer(void* buffer, size_t buffer_size) { + size_t msgsize = 0; + size_t newsize = 0; + sys_Config config = sys_Config_init_default; + bool result = Configurator::LoadDecode(buffer, buffer_size, &config); + if (result) { + Configurator::ApplyTargetSettings(&config); + } + if (result) { + void* currentbuffer = AllocGetConfigBuffer(&msgsize); + void* newbuffer = AllocGetConfigBuffer(&newsize, &config); + if (msgsize != newsize || !memcmp(currentbuffer, newbuffer, msgsize)) { + ESP_LOGI(TAG, "Config change detected."); + // todo: here we are assuming that all strings and repeated elements have fixed size + // and therefore size should always be the same. + result = Configurator::LoadDecode(buffer, buffer_size, &this->_root); + RaiseModified(); + } + free(currentbuffer); + free(newbuffer); + } + return result; +} +bool Configurator::LoadDecodeState() { + bool result = true; + sys_State blank_state = sys_State_init_default; + FILE* file = open_file("rb", state_file_name); + if (file == nullptr) { + ESP_LOGD(TAG,"No state file found. Initializing "); + pb_release(&sys_State_msg,(void *)&_sys_state); + memcpy(&_sys_state, &blank_state, sizeof(sys_State)); + ESP_LOGD(TAG,"Done Initializing state"); + return true; + } + ESP_LOGD(TAG, "Creating binding"); + pb_istream_t filestream = {&in_file_binding,NULL,0}; + ESP_LOGD(TAG, "Starting encode"); + if (!pb_decode(&filestream, &sys_State_msg, (void*)&_sys_state)) { + ESP_LOGE(TAG, "Decoding failed: %s\n", PB_GET_ERROR(&filestream)); + result = false; + } + + fclose(file); + configurator_raise_state_changed(); + ESP_LOGD(TAG, "State loaded"); + return true; +} +bool Configurator::LoadDecode( + void* buffer, size_t buffer_size, sys_Config* conf_root, bool noinit) { + if (!conf_root || !buffer) { + ESP_LOGE(TAG, "Invalid arguments passed to Load"); + } + bool result = true; + // Prepare to read the data into the 'config' structure + pb_istream_t stream = pb_istream_from_buffer((uint8_t*)buffer, buffer_size); + + // Decode the Protocol Buffers message + if (noinit) { + ESP_LOGD(TAG, "Decoding WITHOUT initialization"); + result = pb_decode_noinit(&stream, &sys_Config_msg, conf_root); + } else { + ESP_LOGD(TAG, "Decoding WITH initialization"); + result = pb_decode(&stream, &sys_Config_msg, conf_root); + } + if (!result) { + ESP_LOGE(TAG, "Failed to decode settings: %s", PB_GET_ERROR(&stream)); + return false; + } + ESP_LOGD(TAG, "Settings decoded"); + return true; +} + +bool Configurator::Commit(sys_Config* config) { + if (!config) { + ESP_LOGE(TAG, "Invalid configuration structure!"); + return false; + } + FILE* file = open_file("wb", config_file_name); + bool result = true; + if (file == nullptr) { + return false; + } + ESP_LOGD(TAG, "Creating binding"); + pb_ostream_t filestream = {&out_file_binding, file, SIZE_MAX, 0}; + ESP_LOGD(TAG, "Starting encode"); + if (!pb_encode(&filestream, sys_Config_fields, (void*)config)) { + ESP_LOGE(TAG, "Encoding failed: %s\n", PB_GET_ERROR(&filestream)); + result = false; + } + ESP_LOGD(TAG, "Encoded size: %d", filestream.bytes_written); + if (filestream.bytes_written == 0) { + ESP_LOGE(TAG, "Empty configuration!"); + ESP_LOGD(TAG, "Device name: %s", config->names.device); + } + + fclose(file); + return result; +} + +bool Configurator::CommitState(sys_State* state) { + if (!state) { + ESP_LOGE(TAG, "Invalid state structure!"); + return false; + } + FILE* file = open_file("wb", state_file_name); + bool result = true; + if (file == nullptr) { + return false; + } + ESP_LOGD(TAG, "Creating binding for state commit"); + pb_ostream_t filestream = {&out_file_binding, file, SIZE_MAX, 0}; + ESP_LOGD(TAG, "Starting state encode"); + if (!pb_encode(&filestream, sys_Config_fields, (void*)state)) { + ESP_LOGE(TAG, "Encoding failed: %s\n", PB_GET_ERROR(&filestream)); + result = false; + } + ESP_LOGD(TAG, "Encoded size: %d", filestream.bytes_written); + if (filestream.bytes_written == 0) { + ESP_LOGE(TAG, "Empty state!"); + } + + fclose(file); + return result; +} + + +void Configurator::InitLoadConfig(const char* filename) { + return Configurator::InitLoadConfig(filename, &this->_root); +} +void Configurator::InitLoadConfig(const char* filename, sys_Config* conf_root, bool noinit) { + esp_err_t err = ESP_OK; + size_t data_length = 0; + bool result = false; + ESP_LOGI(TAG, "Loading settings from %s", filename); + void* data = load_file(&data_length, filename); + if (!data) { + ESP_LOGW(TAG, "Config file %s was empty. ", filename); + return; + } else { + result = LoadDecode(data, data_length, conf_root, noinit); + free(data); + } + if (ApplyTargetSettings(conf_root)) { + result = true; + } + if (result) { + _timer = xTimerCreate( + "configTimer", MaxDelay / portTICK_RATE_MS, pdFALSE, NULL, ConfiguratorCallback); + if (xTimerStart(_timer, MaxDelay / portTICK_RATE_MS) != pdPASS) { + ESP_LOGE(TAG, "config commitment timer failed to start."); + } + } + + return; +} +bool Configurator::ApplyTargetSettings() { return ApplyTargetSettings(&this->_root); } +bool Configurator::ApplyTargetSettings(sys_Config* conf_root) { + size_t data_length = 0; + bool result = false; + std::string target_name = conf_root->target; + std::string target_file; + +#ifdef CONFIG_FW_PLATFORM_NAME + if( target_name.empty()){ + target_name = CONFIG_FW_PLATFORM_NAME; + } +#endif + target_file = target_name+ std::string(".bin"); + + std::transform(target_file.begin(), target_file.end(), target_file.begin(), + [](unsigned char c){ return std::tolower(c); }); + if (target_file.empty() || !get_file_info(NULL, targets_folder, target_file.c_str())) { + ESP_LOGD(TAG, "Platform settings file not found: %s", target_file.c_str()); + return result; + } + + ESP_LOGI(TAG, "Applying target %s settings", target_name.c_str()); + void* data = load_file(&data_length, targets_folder, target_file.c_str()); + if (!data) { + ESP_LOGE(TAG, "File read fail"); + return false; + } else { + + result = LoadDecode(data, data_length, conf_root, true); + if (result) { + ESP_LOGI(TAG, "Target %s settings loaded", target_name.c_str()); + } + free(data); + } + + return result; +} + +}; // namespace PlatformConfig + +void configurator_reset_configuration() { + ESP_LOGI(TAG, "Creating default configuration file. "); + sys_Config config = sys_Config_init_default; + ESP_LOGD(TAG, "Device name before target settings: %s", config.names.device); + PlatformConfig::Configurator::ApplyTargetSettings(&config); + ESP_LOGD(TAG, "Device name after target settings: %s", config.names.device); + ESP_LOGD(TAG, "Committing new structure"); + PlatformConfig::Configurator::Commit(&config); +} + +void configurator_load() { + struct stat fileInformation; + ESP_LOGI(TAG, "Loading system settings file"); + ESP_LOGD(TAG, "Checking if file %s exists", config_file_name); + bool found = get_file_info(&fileInformation, config_file_name); + if (!found || fileInformation.st_size == 0) { + ESP_LOGI(TAG, "Configuration file not found or is empty. "); + configurator_reset_configuration(); + } + configurator.InitLoadConfig(config_file_name); + ESP_LOGD(TAG, "Assigning global config pointer"); + platform = configurator.Root(); + configurator.LoadDecodeState(); + sys_state = configurator.RootState(); +} +bool configurator_lock() { return configurator.Lock(); } + +void configurator_unlock() { configurator.Unlock(); } +void configurator_raise_changed() { configurator.RaiseModified(); } +void configurator_raise_state_changed() { configurator.RaiseStateModified(); } + +bool configurator_has_changes() { return configurator.HasChanges(); } + +bool configurator_waitcommit() { return configurator.WaitForCommit(); } + +void* configurator_alloc_get_config(size_t* sz) { return configurator.AllocGetConfigBuffer(sz); } +bool configurator_parse_config(void* buffer, size_t buffer_size) { + // Load and decode buffer. The method also applies any overlay if needed. + return configurator.LoadDecodeBuffer(buffer, buffer_size); +} +pb_type_t configurator_get_field_type(const pb_msgdesc_t* desc, uint32_t tag) { + pb_field_iter_t iter; + if (pb_field_iter_begin(&iter, desc, NULL) && pb_field_iter_find(&iter, tag)) { + /* Found our field. */ + return iter.type; + } + return 0; +} +bool configurator_set_string( + const pb_msgdesc_t* desc, uint32_t field_tag, void* message, const char* value) { + pb_field_iter_t iter; + const char * newval = STR_OR_BLANK(value); + ESP_LOGD(TAG, "Setting value [%s] in message field tag %d",newval , field_tag); + if (pb_field_iter_begin(&iter, desc, message) && pb_field_iter_find(&iter, field_tag)) { + if (iter.pData && !strcmp((char*)iter.pData, newval)) { + ESP_LOGW(TAG, "No change, from and to values are the same: [%s]", STR_OR_BLANK(newval)); + return false; + } + if (PB_ATYPE(iter.type) == PB_ATYPE_POINTER) { + ESP_LOGD(TAG, "Field is a pointer. Freeing previous value if any"); + FREE_AND_NULL(iter.pData); + ESP_LOGD(TAG, "Field is a pointer. Setting new value "); + if(newval && strlen(newval)>0){ + iter.pData = strdup_psram(newval); + } + + } else if (PB_ATYPE(iter.type) == PB_ATYPE_STATIC) { + ESP_LOGD(TAG, "Static string. Setting new value"); + memset(iter.pData,0x00,iter.data_size); + if(newval && strlen(newval)>0){ + strncpy((char*)iter.pData, newval, iter.data_size); + } + } + ESP_LOGD(TAG, "Done setting value "); + } + return true; +} \ No newline at end of file diff --git a/components/platform_config/Configurator.h b/components/platform_config/Configurator.h new file mode 100644 index 00000000..3ed9b34e --- /dev/null +++ b/components/platform_config/Configurator.h @@ -0,0 +1,107 @@ +#pragma once +#include "State.pb.h" +#include "configuration.pb.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/semphr.h" +#include "freertos/timers.h" +#include "status.pb.h" +#include +#include "accessors.h" +#ifdef __cplusplus +#include +#include +#include + +extern "C" { +#endif +#define PLATFORM_GET_PTR(base, sname) \ + { \ + (base && (base)->##has_##(sname) ? &(base)->sname : NULL) +#define PLATFORM_DEVICES PLATFORM_GET_PTR(platform) +void configurator_load(); +bool configurator_waitcommit(); +bool configurator_has_changes(); +bool configurator_lock(); +void configurator_unlock(); +void configurator_raise_changed(); +void configurator_raise_state_changed(); +bool configurator_has_changes(); +bool configurator_waitcommit(); +void* configurator_alloc_get_config(size_t* sz); +bool configurator_parse_config(void* buffer, size_t buffer_size); +void configurator_reset_configuration(); +pb_type_t configurator_get_field_type(const pb_msgdesc_t* desc, uint32_t tag); +bool configurator_set_string( + const pb_msgdesc_t* desc, uint32_t field_tag, void* message, const char* value); +extern sys_Config* platform; +extern sys_State* sys_state; +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus + +namespace PlatformConfig { + +class Configurator { + private: + static const int MaxDelay; + static const int LockMaxWait; + + EXT_RAM_ATTR static TimerHandle_t _timer; + EXT_RAM_ATTR static SemaphoreHandle_t _mutex; + EXT_RAM_ATTR static SemaphoreHandle_t _state_mutex; + EXT_RAM_ATTR static EventGroupHandle_t _group; + bool SetGroupBit(int bit_num, bool flag); + void ResetModified(); + void ResetStateModified(); + sys_Config _root; + sys_State _sys_state; + + public: + sys_Config* Root() { return &_root; } + sys_State* RootState() { return &_sys_state; } + bool WaitForCommit(); + bool Lock(); + bool LockState(); + void Unlock(); + void UnlockState(); + + void* AllocGetConfigBuffer(size_t* sz); + static void* AllocGetConfigBuffer(size_t* sz, sys_Config* config); + static void ResetStructure(sys_Config* config); + bool LoadDecodeState(); + + void CommitChanges(); + bool Commit(); + static bool Commit(sys_Config* config); + + bool CommitState(); + static bool CommitState(sys_State* state); + sys_Config* AllocDefaultStruct(); + + static bool ApplyTargetSettings(sys_Config* conf_root); + bool ApplyTargetSettings(); + bool HasStateChanges(); + + bool LoadDecodeBuffer(void* buffer, size_t buffer_size); + void InitLoadConfig(const char* filename); + void InitLoadConfig(const char* filename, sys_Config* conf_root, bool noinit = false); + static bool LoadDecode( + void* buffer, size_t buffer_size, sys_Config* conf_root, bool noinit = false); + + Configurator() { + _mutex = xSemaphoreCreateMutex(); + _state_mutex = xSemaphoreCreateMutex(); + _group = xEventGroupCreate(); + } + void RaiseStateModified(); + void RaiseModified(); + bool HasChanges(); + ~Configurator() {} +}; +} // namespace PlatformConfig +extern PlatformConfig::Configurator configurator; +#endif diff --git a/components/platform_config/component.mk b/components/platform_config/component.mk deleted file mode 100644 index 7da70bab..00000000 --- a/components/platform_config/component.mk +++ /dev/null @@ -1,11 +0,0 @@ -# -# Component Makefile -# -# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the SDK documents if you need to do this. -# - -COMPONENT_ADD_INCLUDEDIRS := . - diff --git a/components/platform_config/nvs_utilities.c b/components/platform_config/nvs_utilities.c deleted file mode 100644 index e7ebbc31..00000000 --- a/components/platform_config/nvs_utilities.c +++ /dev/null @@ -1,391 +0,0 @@ -#include "nvs_utilities.h" - -#include -#include -#include "esp_system.h" -#include "esp_log.h" -#include "esp_console.h" -#include "esp_vfs_dev.h" -#include "driver/uart.h" -#include "linenoise/linenoise.h" -#include "argtable3/argtable3.h" - -#include "nvs.h" -#include "nvs_flash.h" -#include "nvs_utilities.h" -#include "platform_config.h" -#include "tools.h" - -const char current_namespace[] = "config"; -const char settings_partition[] = "settings"; -static const char * TAG = "nvs_utilities"; - -typedef struct { - nvs_type_t type; - const char *str; -} type_str_pair_t; - -static const type_str_pair_t type_str_pair[] = { - { NVS_TYPE_I8, "i8" }, - { NVS_TYPE_U8, "u8" }, - { NVS_TYPE_U16, "u16" }, - { NVS_TYPE_I16, "i16" }, - { NVS_TYPE_U32, "u32" }, - { NVS_TYPE_I32, "i32" }, - { NVS_TYPE_U64, "u64" }, - { NVS_TYPE_I64, "i64" }, - { NVS_TYPE_STR, "str" }, - { NVS_TYPE_BLOB, "blob" }, - { NVS_TYPE_ANY, "any" }, -}; - -static const size_t TYPE_STR_PAIR_SIZE = sizeof(type_str_pair) / sizeof(type_str_pair[0]); -void print_blob(const char *blob, size_t len) -{ - for (int i = 0; i < len; i++) { - printf("%02x", blob[i]); - } - printf("\n"); -} -nvs_type_t str_to_type(const char *type) -{ - for (int i = 0; i < TYPE_STR_PAIR_SIZE; i++) { - const type_str_pair_t *p = &type_str_pair[i]; - if (strcmp(type, p->str) == 0) { - return p->type; - } - } - - return NVS_TYPE_ANY; -} -const char *type_to_str(nvs_type_t type) -{ - for (int i = 0; i < TYPE_STR_PAIR_SIZE; i++) { - const type_str_pair_t *p = &type_str_pair[i]; - if (p->type == type) { - return p->str; - } - } - - return "Unknown"; -} -void erase_settings_partition(){ - ESP_LOGW(TAG, "Erasing nvs on partition %s",settings_partition); - ESP_ERROR_CHECK(nvs_flash_erase_partition(settings_partition)); - nvs_flash_init_partition(settings_partition); -} -void initialize_nvs() { - ESP_LOGI(TAG, "Initializing flash nvs "); - esp_err_t err = nvs_flash_init(); - if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_LOGW(TAG, "%s. Erasing nvs flash", esp_err_to_name(err)); - ESP_ERROR_CHECK(nvs_flash_erase()); - err = nvs_flash_init(); - } - if(err != ESP_OK){ - ESP_LOGE(TAG, "nvs_flash_init failed. %s.", esp_err_to_name(err)); - } - ESP_ERROR_CHECK(err); - ESP_LOGI(TAG, "Initializing nvs partition %s",settings_partition); - err = nvs_flash_init_partition(settings_partition); - if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_LOGW(TAG, "%s. Erasing nvs on partition %s",esp_err_to_name(err),settings_partition); - ESP_ERROR_CHECK(nvs_flash_erase_partition(settings_partition)); - err = nvs_flash_init_partition(settings_partition); - } - if(err!=ESP_OK){ - ESP_LOGE(TAG, "nvs_flash_init_partition failed. %s",esp_err_to_name(err)); - } - ESP_ERROR_CHECK(err); - ESP_LOGD(TAG, "nvs init completed"); -} - -esp_err_t nvs_load_config() { - nvs_entry_info_t info; - esp_err_t err = ESP_OK; - size_t malloc_int = heap_caps_get_free_size(MALLOC_CAP_INTERNAL); - size_t malloc_spiram = heap_caps_get_free_size(MALLOC_CAP_SPIRAM); - - nvs_iterator_t it = nvs_entry_find(settings_partition, NULL, NVS_TYPE_ANY); - if (it == NULL) { - ESP_LOGW(TAG, "empty nvs partition %s, namespace %s", settings_partition, current_namespace); - } - while (it != NULL) { - nvs_entry_info(it, &info); - - if (strstr(info.namespace_name, current_namespace)) { - if (strlen(info.key) == 0) { - ESP_LOGW(TAG, "empty key name in namespace %s. Removing it.", current_namespace); - nvs_handle_t nvs_handle; - err = nvs_open(settings_partition, NVS_READWRITE, &nvs_handle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs_open failed. %s", esp_err_to_name(err)); - } else { - if ((err = nvs_erase_key(nvs_handle, info.key)) != ESP_OK) { - ESP_LOGE(TAG, "nvs_erase_key failed. %s", esp_err_to_name(err)); - } else { - nvs_commit(nvs_handle); - } - nvs_close(nvs_handle); - if (err == ESP_OK) { - ESP_LOGW(TAG, "nvs_erase_key completed on empty key. Restarting system to apply changes."); - esp_restart(); - } - } - if (err != ESP_OK) { - ESP_LOGW(TAG, "nvs_erase_key failed on empty key. Configuration partition should be erased. %s", esp_err_to_name(err)); - err = ESP_OK; - } - } - else { - void* value = get_nvs_value_alloc(info.type, info.key); - if (value == NULL) { - ESP_LOGE(TAG, "nvs read failed."); - return ESP_FAIL; - } - config_set_value(info.type, info.key, value); - free(value); - } - } - it = nvs_entry_next(it); - } - char* json_string = config_alloc_get_json(false); - if (json_string != NULL) { - ESP_LOGD(TAG, "config json : %s\n", json_string); - free(json_string); - } - - ESP_LOGW(TAG, "Configuration memory usage. Heap internal:%zu (min:%zu) (used:%zu) external:%zu (min:%zu) (used:%zd)", - heap_caps_get_free_size(MALLOC_CAP_INTERNAL), - heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL), - malloc_int - heap_caps_get_free_size(MALLOC_CAP_INTERNAL), - heap_caps_get_free_size(MALLOC_CAP_SPIRAM), - heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM), - malloc_spiram - heap_caps_get_free_size(MALLOC_CAP_SPIRAM)); - return err; -} - -esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data) { - if (type == NVS_TYPE_BLOB) - return ESP_ERR_NVS_TYPE_MISMATCH; - return store_nvs_value_len(type, key, data,0); -} -esp_err_t store_nvs_value_len_for_partition(const char * partition,const char * namespace,nvs_type_t type, const char *key, const void * data,size_t data_len) { - esp_err_t err; - nvs_handle nvs; - if(!key || key[0]=='\0'){ - ESP_LOGE(TAG, "Cannot store value to nvs: key is empty"); - return ESP_ERR_INVALID_ARG; - } - - if (type == NVS_TYPE_ANY) { - return ESP_ERR_NVS_TYPE_MISMATCH; - } - - err = nvs_open_from_partition(partition, namespace, NVS_READWRITE, &nvs); - if (err != ESP_OK) { - return err; - } - - if (type == NVS_TYPE_I8) { - err = nvs_set_i8(nvs, key, *(int8_t *) data); - } else if (type == NVS_TYPE_U8) { - err = nvs_set_u8(nvs, key, *(uint8_t *) data); - } else if (type == NVS_TYPE_I16) { - err = nvs_set_i16(nvs, key, *(int16_t *) data); - } else if (type == NVS_TYPE_U16) { - err = nvs_set_u16(nvs, key, *(uint16_t *) data); - } else if (type == NVS_TYPE_I32) { - err = nvs_set_i32(nvs, key, *(int32_t *) data); - } else if (type == NVS_TYPE_U32) { - err = nvs_set_u32(nvs, key, *(uint32_t *) data); - } else if (type == NVS_TYPE_I64) { - err = nvs_set_i64(nvs, key, *(int64_t *) data); - } else if (type == NVS_TYPE_U64) { - err = nvs_set_u64(nvs, key, *(uint64_t *) data); - } else if (type == NVS_TYPE_STR) { - err = nvs_set_str(nvs, key, data); - } else if (type == NVS_TYPE_BLOB) { - err = nvs_set_blob(nvs, key, (void *) data, data_len); - } - if (err == ESP_OK) { - err = nvs_commit(nvs); - if (err == ESP_OK) { - ESP_LOGI(TAG, "Value stored under key '%s'", key); - } - } - nvs_close(nvs); - return err; -} -esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data, - size_t data_len) { - return store_nvs_value_len_for_partition(settings_partition,current_namespace,type,key,data,data_len); -} -void * get_nvs_value_alloc_for_partition(const char * partition,const char * namespace,nvs_type_t type, const char *key, size_t * size){ - nvs_handle nvs; - esp_err_t err; - void * value=NULL; - if(size){ - *size=0; - } - err = nvs_open_from_partition(partition, namespace, NVS_READONLY, &nvs); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Could not open the nvs storage."); - return NULL; - } - - if (type == NVS_TYPE_I8) { - value=malloc_init_external(sizeof(int8_t)); - err = nvs_get_i8(nvs, key, (int8_t *) value); - } else if (type == NVS_TYPE_U8) { - value=malloc_init_external(sizeof(uint8_t)); - err = nvs_get_u8(nvs, key, (uint8_t *) value); - } else if (type == NVS_TYPE_I16) { - value=malloc_init_external(sizeof(int16_t)); - err = nvs_get_i16(nvs, key, (int16_t *) value); - } else if (type == NVS_TYPE_U16) { - value=malloc_init_external(sizeof(uint16_t)); - err = nvs_get_u16(nvs, key, (uint16_t *) value); - } else if (type == NVS_TYPE_I32) { - value=malloc_init_external(sizeof(int32_t)); - err = nvs_get_i32(nvs, key, (int32_t *) value); - } else if (type == NVS_TYPE_U32) { - value=malloc_init_external(sizeof(uint32_t)); - err = nvs_get_u32(nvs, key, (uint32_t *) value); - } else if (type == NVS_TYPE_I64) { - value=malloc_init_external(sizeof(int64_t)); - err = nvs_get_i64(nvs, key, (int64_t *) value); - } else if (type == NVS_TYPE_U64) { - value=malloc_init_external(sizeof(uint64_t)); - err = nvs_get_u64(nvs, key, (uint64_t *) value); - } else if (type == NVS_TYPE_STR) { - size_t len=0; - err = nvs_get_str(nvs, key, NULL, &len); - if (err == ESP_OK) { - value=malloc_init_external(len+1); - err = nvs_get_str(nvs, key, value, &len); - if(size){ - *size=len; - } - } - } else if (type == NVS_TYPE_BLOB) { - size_t len; - err = nvs_get_blob(nvs, key, NULL, &len); - if (err == ESP_OK) { - value=malloc_init_external(len+1); - if(size){ - *size=len; - } - err = nvs_get_blob(nvs, key, value, &len); - } - } - if(err!=ESP_OK){ - ESP_LOGD(TAG, "Value not found for key %s",key); - if(value!=NULL) - free(value); - value=NULL; - } - nvs_close(nvs); - return value; -} -void * get_nvs_value_alloc(nvs_type_t type, const char *key) { - return get_nvs_value_alloc_for_partition(settings_partition, current_namespace,type,key,NULL); -} -esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint8_t buf_size) { - nvs_handle nvs; - esp_err_t err; - - err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READONLY, &nvs); - if (err != ESP_OK) { - return err; - } - - if (type == NVS_TYPE_I8) { - err = nvs_get_i8(nvs, key, (int8_t *) value); - } else if (type == NVS_TYPE_U8) { - err = nvs_get_u8(nvs, key, (uint8_t *) value); - } else if (type == NVS_TYPE_I16) { - err = nvs_get_i16(nvs, key, (int16_t *) value); - } else if (type == NVS_TYPE_U16) { - err = nvs_get_u16(nvs, key, (uint16_t *) value); - } else if (type == NVS_TYPE_I32) { - err = nvs_get_i32(nvs, key, (int32_t *) value); - } else if (type == NVS_TYPE_U32) { - err = nvs_get_u32(nvs, key, (uint32_t *) value); - } else if (type == NVS_TYPE_I64) { - err = nvs_get_i64(nvs, key, (int64_t *) value); - } else if (type == NVS_TYPE_U64) { - err = nvs_get_u64(nvs, key, (uint64_t *) value); - } else if (type == NVS_TYPE_STR) { - size_t len; - if ((err = nvs_get_str(nvs, key, NULL, &len)) == ESP_OK) { - if (len > buf_size) { - //ESP_LOGE("Error reading value for %s. Buffer size: %d, Value Length: %d", key, buf_size, len); - err = ESP_FAIL; - } else { - err = nvs_get_str(nvs, key, value, &len); - } - } - } else if (type == NVS_TYPE_BLOB) { - size_t len; - if ((err = nvs_get_blob(nvs, key, NULL, &len)) == ESP_OK) { - - if (len > buf_size) { - //ESP_LOGE("Error reading value for %s. Buffer size: %d, Value Length: %d", - // key, buf_size, len); - err = ESP_FAIL; - } else { - err = nvs_get_blob(nvs, key, value, &len); - } - } - } - - nvs_close(nvs); - return err; -} -esp_err_t erase_nvs_for_partition(const char * partition, const char * namespace,const char *key) -{ - nvs_handle nvs; - esp_err_t err = nvs_open_from_partition(partition,namespace, NVS_READWRITE, &nvs); - if (err == ESP_OK) { - err = nvs_erase_key(nvs, key); - if (err == ESP_OK) { - err = nvs_commit(nvs); - if (err == ESP_OK) { - ESP_LOGI(TAG, "Value with key '%s' erased", key); - } - } - nvs_close(nvs); - } - else { - ESP_LOGE(TAG,"Could not erase key %s from partition %s namespace %s : %s", key,partition,namespace, esp_err_to_name(err)); - } - return err; -} -esp_err_t erase_nvs(const char *key) -{ - return erase_nvs_for_partition(NVS_DEFAULT_PART_NAME, current_namespace,key); -} - -esp_err_t erase_nvs_partition(const char * partition, const char * namespace){ - nvs_handle nvs; - const char * step = "Opening"; - ESP_LOGD(TAG,"%s partition %s, namespace %s ",step,partition,namespace); - esp_err_t err = nvs_open_from_partition(partition,namespace, NVS_READWRITE, &nvs); - if (err == ESP_OK) { - step = "Erasing"; - ESP_LOGD(TAG,"%s namespace %s ",step,partition); - err = nvs_erase_all(nvs); - if (err == ESP_OK) { - step = "Committing"; - ESP_LOGD(TAG,"%s",step); - err = nvs_commit(nvs); - } - } - if(err !=ESP_OK){ - ESP_LOGE(TAG,"%s partition %s, name space %s : %s",step,partition,namespace,esp_err_to_name(err)); - } - ESP_LOGD(TAG,"Closing %s ",namespace); - nvs_close(nvs); - return err; -} \ No newline at end of file diff --git a/components/platform_config/nvs_utilities.h b/components/platform_config/nvs_utilities.h deleted file mode 100644 index 6f181f08..00000000 --- a/components/platform_config/nvs_utilities.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include "esp_err.h" -#include "nvs.h" -#ifdef __cplusplus -extern "C" { -#endif -extern const char current_namespace[]; -extern const char settings_partition[]; - -#define NUM_BUFFER_LEN 101 -void initialize_nvs(); -esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data, size_t data_len); -esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data); -esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint8_t buf_size); -void * get_nvs_value_alloc(nvs_type_t type, const char *key); -void * get_nvs_value_alloc_for_partition(const char * partition,const char * name_space,nvs_type_t type, const char *key, size_t * size); -esp_err_t erase_nvs_for_partition(const char * partition, const char * name_space,const char *key); -esp_err_t store_nvs_value_len_for_partition(const char * partition,const char * name_space,nvs_type_t type, const char *key, const void * data,size_t data_len); -esp_err_t erase_nvs(const char *key); -void print_blob(const char *blob, size_t len); -const char *type_to_str(nvs_type_t type); -nvs_type_t str_to_type(const char *type); -esp_err_t erase_nvs_partition(const char * partition, const char * name_space); -void erase_settings_partition(); -#ifdef __cplusplus -} -#endif diff --git a/components/platform_config/platform_config.c b/components/platform_config/platform_config.c deleted file mode 100644 index 1a6287b3..00000000 --- a/components/platform_config/platform_config.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * Squeezelite for esp32 - * - * (c) Sebastien 2019 - * Philippe G. 2019, philippe_44@outlook.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "platform_config.h" -#include "nvs_utilities.h" -#include "platform_esp32.h" -#include -#include -#include "esp_system.h" -#include "esp_log.h" -#include "esp_console.h" -#include "esp_vfs_dev.h" -#include "driver/uart.h" -#include "linenoise/linenoise.h" -#include "argtable3/argtable3.h" - -#include "nvs.h" -#include "nvs_flash.h" -#include "nvs_utilities.h" -#include "cJSON.h" -#include "freertos/timers.h" -#include "freertos/event_groups.h" -#include "tools.h" -#include "trace.h" - -#define CONFIG_COMMIT_DELAY 1000 -#define LOCK_MAX_WAIT 20*CONFIG_COMMIT_DELAY -static const char * TAG = "config"; -EXT_RAM_ATTR static cJSON * nvs_json=NULL; -EXT_RAM_ATTR static TimerHandle_t timer; -EXT_RAM_ATTR static SemaphoreHandle_t config_mutex = NULL; -EXT_RAM_ATTR static EventGroupHandle_t config_group; -/* @brief indicate that the ESP32 is currently connected. */ -EXT_RAM_ATTR static const int CONFIG_NO_COMMIT_PENDING = BIT0; -EXT_RAM_ATTR static const int CONFIG_LOAD_BIT = BIT1; - -bool config_lock(TickType_t xTicksToWait); -void config_unlock(); -extern esp_err_t nvs_load_config(); -void config_raise_change(bool flag); -cJSON_bool config_is_entry_changed(cJSON * entry); -bool config_set_group_bit(int bit_num,bool flag); -cJSON * config_set_value_safe(nvs_type_t nvs_type, const char *key,const void * value); -static void vCallbackFunction( TimerHandle_t xTimer ); -void config_set_entry_changed_flag(cJSON * entry, cJSON_bool flag); -#define IMPLEMENT_SET_DEFAULT(t,nt) void config_set_default_## t (const char *key, t value){\ - void * pval = malloc_init_external(sizeof(value));\ - *((t *) pval) = value;\ - config_set_default(nt, key,pval,0);\ - free(pval); } -#define IMPLEMENT_GET_NUM(t,nt) esp_err_t config_get_## t (const char *key, t * value){\ - void * pval = config_alloc_get(nt, key);\ - if(pval!=NULL){ *value = *(t * )pval; free(pval); return ESP_OK; }\ - return ESP_FAIL;} -static void * malloc_fn(size_t sz){ - - void * ptr = is_recovery_running?malloc(sz):heap_caps_malloc(sz, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); - if(ptr==NULL){ - ESP_LOGE(TAG,"malloc_fn: unable to allocate memory!"); - } - return ptr; -} -void init_cJSON(){ - static cJSON_Hooks hooks; - hooks.malloc_fn=&malloc_fn; - cJSON_InitHooks(&hooks); -} -void config_init(){ - ESP_LOGD(TAG, "Creating mutex for Config"); - MEMTRACE_PRINT_DELTA(); - config_mutex = xSemaphoreCreateMutex(); - MEMTRACE_PRINT_DELTA(); - ESP_LOGD(TAG, "Creating event group"); - MEMTRACE_PRINT_DELTA(); - config_group = xEventGroupCreate(); - MEMTRACE_PRINT_DELTA(); - ESP_LOGD(TAG, "Loading config from nvs"); - - init_cJSON(); - MEMTRACE_PRINT_DELTA(); - if(nvs_json !=NULL){ - cJSON_Delete(nvs_json); - } - nvs_json = cJSON_CreateObject(); - - config_set_group_bit(CONFIG_LOAD_BIT,true); - MEMTRACE_PRINT_DELTA(); - nvs_load_config(); - MEMTRACE_PRINT_DELTA(); - config_set_group_bit(CONFIG_LOAD_BIT,false); - MEMTRACE_PRINT_DELTA(); - config_start_timer(); -} - -void config_start_timer(){ - ESP_LOGD(TAG, "Starting config timer"); - timer = xTimerCreate("configTimer", CONFIG_COMMIT_DELAY / portTICK_RATE_MS, pdFALSE, NULL, vCallbackFunction); - if( xTimerStart( timer , CONFIG_COMMIT_DELAY/ portTICK_RATE_MS ) != pdPASS ) { - ESP_LOGE(TAG, "config commitment timer failed to start."); - } - -} - -nvs_type_t config_get_item_type(cJSON * entry){ - if(entry==NULL){ - ESP_LOGE(TAG,"null pointer received!"); - return 0; - } - cJSON * item_type = cJSON_GetObjectItemCaseSensitive(entry, "type"); - if(item_type ==NULL ) { - ESP_LOGE(TAG, "Item type not found! "); - return 0; - } - ESP_LOGD(TAG,"Found item type %f",item_type->valuedouble); - return item_type->valuedouble; -} - - -cJSON * config_set_value_safe(nvs_type_t nvs_type, const char *key, const void * value){ - cJSON * entry = cJSON_CreateObject(); - - double numvalue = 0; - if(entry == NULL) { - ESP_LOGE(TAG, "Unable to allocate memory for entry %s",key); - return NULL; - } - -cJSON * existing = cJSON_GetObjectItemCaseSensitive(nvs_json, key); - if(existing !=NULL && nvs_type == NVS_TYPE_STR && config_get_item_type(existing) != NVS_TYPE_STR ) { - ESP_LOGW(TAG, "Storing numeric value from string"); - numvalue = atof((char *)value); - cJSON_AddNumberToObject(entry,"value", numvalue ); - nvs_type_t exist_type = config_get_item_type(existing); - ESP_LOGW(TAG, "Stored value %f from string %s as type %d",numvalue, (char *)value,exist_type); - cJSON_AddNumberToObject(entry,"type", exist_type); - } - else { - cJSON_AddNumberToObject(entry,"type", nvs_type ); - switch (nvs_type) { - case NVS_TYPE_I8: - cJSON_AddNumberToObject(entry,"value", *(int8_t*)value ); - break; - case NVS_TYPE_I16: - cJSON_AddNumberToObject(entry,"value", *(int16_t*)value ); - break; - case NVS_TYPE_I32: - cJSON_AddNumberToObject(entry,"value", *(int32_t*)value ); - break; - case NVS_TYPE_U8: - cJSON_AddNumberToObject(entry,"value", *(uint8_t*)value ); - break; - case NVS_TYPE_U16: - cJSON_AddNumberToObject(entry,"value", *(uint16_t*)value ); - break; - case NVS_TYPE_U32: - cJSON_AddNumberToObject(entry,"value", *(uint32_t*)value ); - break; - case NVS_TYPE_STR: - cJSON_AddStringToObject(entry, "value", (char *)value); - break; - case NVS_TYPE_I64: - case NVS_TYPE_U64: - default: - ESP_LOGE(TAG, "nvs type %u not supported", nvs_type); - break; - } - } - if(existing!=NULL ) { - ESP_LOGV(TAG, "Changing existing entry [%s].", key); - char * exist_str = cJSON_PrintUnformatted(existing); - if(exist_str!=NULL){ - ESP_LOGV(TAG,"Existing entry: %s", exist_str); - free(exist_str); - } - else { - ESP_LOGV(TAG,"Failed to print existing entry"); - } - // set commit flag as equal so we can compare - cJSON_AddBoolToObject(entry,"chg",config_is_entry_changed(existing)); - if(!cJSON_Compare(entry,existing,false)){ - char * entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGD(TAG,"New config object: \n%s", entry_str ); - free(entry_str); - } - else { - ESP_LOGD(TAG,"Failed to print entry"); - } - ESP_LOGI(TAG, "Setting changed flag config [%s]", key); - config_set_entry_changed_flag(entry,true); - ESP_LOGI(TAG, "Updating config [%s]", key); - cJSON_ReplaceItemInObject(nvs_json,key, entry); - entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGD(TAG,"New config: %s", entry_str ); - free(entry_str); - } - else { - ESP_LOGD(TAG,"Failed to print entry"); - } - } - else { - ESP_LOGD(TAG, "Config not changed. "); - cJSON_Delete(entry); - entry = existing; - } - } - else { - // This is a new entry. - config_set_entry_changed_flag(entry,true); - cJSON_AddItemToObject(nvs_json, key, entry); - } - - return entry; -} - -nvs_type_t config_get_entry_type(cJSON * entry){ - if(entry==NULL){ - ESP_LOGE(TAG,"null pointer received!"); - return 0; - } - cJSON * entry_type = cJSON_GetObjectItemCaseSensitive(entry, "type"); - if(entry_type ==NULL ) { - ESP_LOGE(TAG, "Entry type not found in nvs cache for existing setting."); - return 0; - } - ESP_LOGV(TAG,"Found type %s",type_to_str(entry_type->valuedouble)); - return entry_type->valuedouble; -} -void config_set_entry_changed_flag(cJSON * entry, cJSON_bool flag){ - ESP_LOGV(TAG, "config_set_entry_changed_flag: begin"); - if(entry==NULL){ - ESP_LOGE(TAG,"null pointer received!"); - return; - } - bool bIsConfigLoading=((xEventGroupGetBits(config_group) & CONFIG_LOAD_BIT)!=0); - bool changedFlag=bIsConfigLoading?false:flag; - ESP_LOGV(TAG, "config_set_entry_changed_flag: retrieving chg flag from entry"); - cJSON * changed = cJSON_GetObjectItemCaseSensitive(entry, "chg"); - if(changed ==NULL ) { - ESP_LOGV(TAG, "config_set_entry_changed_flag: chg flag not found. Adding. "); - cJSON_AddBoolToObject(entry,"chg",changedFlag); - } - else { - ESP_LOGV(TAG, "config_set_entry_changed_flag: Existing change flag found. "); - if(cJSON_IsTrue(changed) && changedFlag){ - ESP_LOGW(TAG, "Commit flag not changed!"); - } - else{ - ESP_LOGV(TAG, "config_set_entry_changed_flag: Updating change flag to %s",changedFlag?"TRUE":"FALSE"); - changed->type = changedFlag?cJSON_True:cJSON_False ; - } - } - - if(changedFlag) { - ESP_LOGV(TAG, "config_set_entry_changed_flag: Calling config_raise_change. "); - config_raise_change(true); - } - ESP_LOGV(TAG, "config_set_entry_changed_flag: done. "); -} -cJSON_bool config_is_entry_changed(cJSON * entry){ - if(entry==NULL){ - ESP_LOGE(TAG,"null pointer received!"); - return true; - } - cJSON * changed = cJSON_GetObjectItemCaseSensitive(entry, "chg"); - if(changed ==NULL ) { - ESP_LOGE(TAG, "Change flag not found! "); - return true; - } - return cJSON_IsTrue(changed); -} - - - - -void * config_safe_alloc_get_entry_value(nvs_type_t nvs_type, cJSON * entry){ - void * value=NULL; - if(entry==NULL){ - ESP_LOGE(TAG,"null pointer received!"); - } - ESP_LOGV(TAG, "getting config value type %s", type_to_str(nvs_type)); - cJSON * entry_value = cJSON_GetObjectItemCaseSensitive(entry, "value"); - if(entry_value==NULL ) { - char * entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGE(TAG, "Missing config value!. Object: \n%s", entry_str); - free(entry_str); - } - else{ - ESP_LOGE(TAG, "Missing config value"); - } - return NULL; - } - - nvs_type_t type = config_get_entry_type(entry); - if(nvs_type != type){ - // requested value type different than the stored type - char * entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGE(TAG, "Requested value type %s, found value type %s instead, Object: \n%s", type_to_str(nvs_type), type_to_str(type),entry_str); - free(entry_str); - } - else{ - ESP_LOGE(TAG, "Requested value type %s, found value type %s instead", type_to_str(nvs_type), type_to_str(type)); - } - - return NULL; - } - if (nvs_type == NVS_TYPE_I8) { - value=malloc_init_external(sizeof(int8_t)); - *(int8_t *)value = (int8_t)entry_value->valuedouble; - } else if (nvs_type == NVS_TYPE_U8) { - value=malloc_init_external(sizeof(uint8_t)); - *(uint8_t *)value = (uint8_t)entry_value->valuedouble; - } else if (nvs_type == NVS_TYPE_I16) { - value=malloc_init_external(sizeof(int16_t)); - *(int16_t *)value = (int16_t)entry_value->valuedouble; - } else if (nvs_type == NVS_TYPE_U16) { - value=malloc_init_external(sizeof(uint16_t)); - *(uint16_t *)value = (uint16_t)entry_value->valuedouble; - } else if (nvs_type == NVS_TYPE_I32) { - value=malloc_init_external(sizeof(int32_t)); - *(int32_t *)value = (int32_t)entry_value->valuedouble; - } else if (nvs_type == NVS_TYPE_U32) { - value=malloc_init_external(sizeof(uint32_t)); - *(uint32_t *)value = (uint32_t)entry_value->valuedouble; - } else if (nvs_type == NVS_TYPE_I64) { - value=malloc_init_external(sizeof(int64_t)); - *(int64_t *)value = (int64_t)entry_value->valuedouble; - } else if (nvs_type == NVS_TYPE_U64) { - value=malloc_init_external(sizeof(uint64_t)); - *(uint64_t *)value = (uint64_t)entry_value->valuedouble; - } else if (nvs_type == NVS_TYPE_STR) { - if(!cJSON_IsString(entry_value)){ - char * entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGE(TAG, "requested value type string, config type is different. key: %s, value: %s, type %d, Object: \n%s", - str_or_null(entry_value->string), - str_or_null(entry_value->valuestring), - entry_value->type, - str_or_null(entry_str)); - free(entry_str); - } - else { - ESP_LOGE(TAG, "requested value type string, config type is different. key: %s, value: %s, type %d", - str_or_null(entry_value->string), - str_or_null(entry_value->valuestring), - entry_value->type); - } - } - else { - size_t len=strlen(cJSON_GetStringValue(entry_value)); - value=(void *)malloc_init_external(len+1); - memcpy(value,cJSON_GetStringValue(entry_value),len); - if(value==NULL){ - char * entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGE(TAG, "strdup failed on value for object \n%s",entry_str); - free(entry_str); - } - else { - ESP_LOGE(TAG, "strdup failed on value"); - } - } - } - } else if (nvs_type == NVS_TYPE_BLOB) { - ESP_LOGE(TAG, "Unsupported type NVS_TYPE_BLOB"); - } - return value; -} - -void config_commit_to_nvs(){ - ESP_LOGI(TAG,"Committing configuration to nvs. Locking config object."); - if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){ - ESP_LOGE(TAG, "config_commit_to_nvs: Unable to lock config for commit "); - return ; - } - if(nvs_json==NULL){ - ESP_LOGE(TAG, ": cJSON nvs cache object not set."); - return; - } - ESP_LOGV(TAG,"config_commit_to_nvs. Config Locked!"); - cJSON * entry=nvs_json->child; - while(entry!= NULL){ - char * entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGV(TAG,"config_commit_to_nvs processing item %s",entry_str); - free(entry_str); - } - - if(config_is_entry_changed(entry)){ - ESP_LOGD(TAG, "Committing entry %s value to nvs.",(entry->string==NULL)?"UNKNOWN":entry->string); - nvs_type_t type = config_get_entry_type(entry); - void * value = config_safe_alloc_get_entry_value(type, entry); - if(value!=NULL){ - size_t len=strlen(entry->string); - char * key=(void *)malloc_init_external(len+1); - memcpy(key,entry->string,len); - esp_err_t err = store_nvs_value(type,key,value); - FREE_AND_NULL(key); - FREE_AND_NULL(value); - - if(err!=ESP_OK){ - char * entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGE(TAG, "Error comitting value to nvs for key %s, Object: \n%s",entry->string,entry_str); - free(entry_str); - } - else { - ESP_LOGE(TAG, "Error comitting value to nvs for key %s",entry->string); - } - } - else { - config_set_entry_changed_flag(entry, false); - } - } - else { - char * entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGE(TAG, "Unable to retrieve value. Error comitting value to nvs for key %s, Object: \n%s",entry->string,entry_str); - free(entry_str); - } - else { - ESP_LOGE(TAG, "Unable to retrieve value. Error comitting value to nvs for key %s",entry->string); - } - } - } - else { - ESP_LOGV(TAG,"config_commit_to_nvs. Item already committed. Ignoring."); - } - taskYIELD(); /* allows the freeRTOS scheduler to take over if needed. */ - entry = entry->next; - } - ESP_LOGV(TAG,"config_commit_to_nvs. Resetting the global commit flag."); - config_raise_change(false); - ESP_LOGV(TAG,"config_commit_to_nvs. Releasing the lock object."); - config_unlock(); - ESP_LOGI(TAG,"Done Committing configuration to nvs."); -} -bool config_has_changes(){ - return (xEventGroupGetBits(config_group) & CONFIG_NO_COMMIT_PENDING)==0; -} - - -bool wait_for_commit(){ - bool commit_pending=(xEventGroupGetBits(config_group) & CONFIG_NO_COMMIT_PENDING)==0; - while (commit_pending){ - ESP_LOGW(TAG,"Waiting for config commit ..."); - commit_pending = (xEventGroupWaitBits(config_group, CONFIG_NO_COMMIT_PENDING,pdFALSE, pdTRUE, (CONFIG_COMMIT_DELAY*2) / portTICK_PERIOD_MS) & CONFIG_NO_COMMIT_PENDING)==0; - if(commit_pending){ - ESP_LOGW(TAG,"Timeout waiting for config commit."); - } - else { - ESP_LOGI(TAG,"Config committed!"); - } - } - return !commit_pending; -} - -bool config_lock(TickType_t xTicksToWait) { - ESP_LOGV(TAG, "Locking config json object"); - if( xSemaphoreTake( config_mutex, xTicksToWait ) == pdTRUE ) { - ESP_LOGV(TAG, "config Json object locked!"); - return true; - } - else { - ESP_LOGE(TAG, "Semaphore take failed. Unable to lock config Json object mutex"); - return false; - } -} - -void config_unlock() { - ESP_LOGV(TAG, "Unlocking json buffer!"); - xSemaphoreGive( config_mutex ); -} - -static void vCallbackFunction( TimerHandle_t xTimer ) { - static int cnt=0; - if(config_has_changes()){ - ESP_LOGI(TAG, "configuration has some uncommitted entries"); - config_commit_to_nvs(); - } - else{ - if(++cnt>=15){ - ESP_LOGV(TAG,"commit timer: commit flag not set"); - cnt=0; - } - } - xTimerReset( xTimer, 10 ); -} -void config_raise_change(bool change_found){ - if(config_set_group_bit(CONFIG_NO_COMMIT_PENDING,!change_found)) - { - ESP_LOGD(TAG,"Config commit set to %s",change_found?"Pending Commit":"Committed"); - } -} -bool config_set_group_bit(int bit_num,bool flag){ - bool result = true; - int curFlags=xEventGroupGetBits(config_group); - if((curFlags & CONFIG_LOAD_BIT) && bit_num == CONFIG_NO_COMMIT_PENDING ){ - ESP_LOGD(TAG,"Loading config, ignoring changes"); - result = false; - } - if(result){ - bool curBit=(xEventGroupGetBits(config_group) & bit_num); - if(curBit == flag){ - ESP_LOGV(TAG,"Flag %d already %s", bit_num, flag?"Set":"Cleared"); - result = false; - } - } - if(result){ - ESP_LOGV(TAG,"%s Flag %d ", flag?"Setting":"Clearing",bit_num); - if(!flag){ - xEventGroupClearBits(config_group, bit_num); - } - else { - xEventGroupSetBits(config_group, bit_num); - } - } - return result; -} - -void config_set_default(nvs_type_t type, const char *key, const void * default_value, size_t blob_size) { - if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){ - ESP_LOGE(TAG, "Unable to lock config"); - return; - } - - ESP_LOGV(TAG, "Checking if key %s exists in nvs cache for type %s.", key,type_to_str(type)); - cJSON * entry = cJSON_GetObjectItemCaseSensitive(nvs_json, key); - - if(entry !=NULL){ - ESP_LOGV(TAG, "Entry found."); - } - else { - // Value was not found - ESP_LOGW(TAG, "Adding default value for [%s].", key); - entry=config_set_value_safe(type, key, default_value); - if(entry == NULL){ - ESP_LOGE(TAG, "Failed to add value to cache!"); - } - char * entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGD(TAG, "Value added to default for object: \n%s",entry_str); - free(entry_str); - } - } - - config_unlock(); - -} - -void config_delete_key(const char *key){ - nvs_handle nvs; - ESP_LOGD(TAG, "Deleting nvs entry for [%s]", key); - if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){ - ESP_LOGE(TAG, "Unable to lock config for delete"); - return ; - } - esp_err_t err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs); - if (err == ESP_OK) { - err = nvs_erase_key(nvs, key); - if (err == ESP_OK) { - ESP_LOGD(TAG, "key [%s] erased from nvs.",key); - err = nvs_commit(nvs); - if (err == ESP_OK) { - ESP_LOGD(TAG, "nvs erase committed."); - } - else { - ESP_LOGE(TAG, "Unable to commit nvs erase operation for key [%s]. %s.",key,esp_err_to_name(err)); - } - } - else { - ESP_LOGE(TAG, "Unable to delete nvs key [%s]. %s. ",key, esp_err_to_name(err)); - } - nvs_close(nvs); - } - else { - ESP_LOGE(TAG, "Error opening nvs: %s. Unable to delete nvs key [%s].",esp_err_to_name(err),key); - } - char * struc_str = cJSON_PrintUnformatted(nvs_json); - if(struc_str!=NULL){ - ESP_LOGV(TAG, "Structure before delete \n%s", struc_str); - free(struc_str); - } - cJSON * entry = cJSON_DetachItemFromObjectCaseSensitive(nvs_json, key); - if(entry !=NULL){ - ESP_LOGI(TAG, "Removing config key [%s]", entry->string); - cJSON_Delete(entry); - struc_str = cJSON_PrintUnformatted(nvs_json); - if(struc_str!=NULL){ - ESP_LOGV(TAG, "Structure after delete \n%s", struc_str); - free(struc_str); - } - } - else { - ESP_LOGW(TAG, "Unable to remove config key [%s]: not found.", key); - } - config_unlock(); -} - -void * config_alloc_get(nvs_type_t nvs_type, const char *key) { - return config_alloc_get_default(nvs_type, key, NULL, 0); -} -cJSON * config_alloc_get_cjson(const char *key){ - char * conf_str = config_alloc_get_default(NVS_TYPE_STR, key, NULL, 0); - if(conf_str==NULL){ - ESP_LOGE(TAG, "Unable to get config value for key [%s]", key); - return NULL; - } - cJSON * conf_json = cJSON_Parse(conf_str); - free(conf_str); - if(conf_json==NULL){ - ESP_LOGE(TAG, "Unable to parse config value for key [%s]", key); - return NULL; - } - return conf_json; -} -esp_err_t config_set_cjson(const char *key, cJSON *value, bool free_cjson){ - char * value_str = cJSON_PrintUnformatted(value); - if(value_str==NULL){ - ESP_LOGE(TAG, "Unable to print cJSON for key [%s]", key); - return ESP_ERR_INVALID_ARG; - } - esp_err_t err = config_set_value(NVS_TYPE_STR,key, value_str); - free(value_str); - if(free_cjson){ - cJSON_Delete(value); - } - return err; -} -esp_err_t config_set_cjson_str_and_free(const char *key, cJSON *value){ - return config_set_cjson(key, value, true); -} -void config_get_uint16t_from_str(const char *key, uint16_t *value, uint16_t default_value){ - char * str_value = config_alloc_get(NVS_TYPE_STR, key); - if(str_value == NULL){ - *value = default_value; - return ; - } - *value = atoi(str_value); - free(str_value); -} - -void * config_alloc_get_str(const char *key, char *lead, char *fallback) { - if (lead && *lead) return strdup_psram(lead); - char *value = config_alloc_get_default(NVS_TYPE_STR, key, NULL, 0); - if ((!value || !*value) && fallback) { - if (value) free(value); - value = strdup_psram(fallback); - } - return value; -} - -void * config_alloc_get_default(nvs_type_t nvs_type, const char *key, void * default_value, size_t blob_size) { - - void * value = NULL; - ESP_LOGV(TAG, "Retrieving key %s from nvs cache for type %s.", key,type_to_str(nvs_type)); - if(nvs_json==NULL){ - ESP_LOGE(TAG,"configuration not loaded!"); - return value; - } - if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){ - ESP_LOGE(TAG, "Unable to lock config"); - return value; - } - ESP_LOGD(TAG,"Getting config entry for key %s",key); - cJSON * entry = cJSON_GetObjectItemCaseSensitive(nvs_json, key); - if(entry !=NULL){ - ESP_LOGV(TAG, "Entry found, getting value."); - value = config_safe_alloc_get_entry_value(nvs_type, entry); - } - else if(default_value!=NULL){ - // Value was not found - ESP_LOGW(TAG, "Adding new config value for key [%s]",key); - entry=config_set_value_safe(nvs_type, key, default_value); - if(entry == NULL){ - ESP_LOGE(TAG, "Failed to add value to cache"); - } - else { - char * entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGV(TAG, "Value added configuration object for key [%s]: \n%s", entry->string,entry_str); - free(entry_str); - } - else { - ESP_LOGV(TAG, "Value added configuration object for key [%s]", entry->string); - } - value = config_safe_alloc_get_entry_value(nvs_type, entry); - } - } - else{ - ESP_LOGW(TAG,"Value not found for key %s",key); - } - config_unlock(); - return value; -} -char * config_alloc_get_json(bool bFormatted){ - char * json_buffer = NULL; - if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){ - ESP_LOGE(TAG, "Unable to lock config after %d ms",LOCK_MAX_WAIT); - return strdup_psram("{\"error\":\"Unable to lock configuration object.\"}"); - } - if(bFormatted){ - json_buffer= cJSON_Print(nvs_json); - } - else { - json_buffer= cJSON_PrintUnformatted(nvs_json); - } - config_unlock(); - return json_buffer; -} -esp_err_t config_set_value(nvs_type_t nvs_type, const char *key, const void * value){ - esp_err_t result = ESP_OK; - if(!key ||!key[0]){ - ESP_LOGW(TAG,"Empty key passed. Ignoring entry!"); - return ESP_ERR_INVALID_ARG; - } - if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){ - ESP_LOGE(TAG, "Unable to lock config after %d ms",LOCK_MAX_WAIT); - result = ESP_FAIL; - } - cJSON * entry = config_set_value_safe(nvs_type, key, value); - if(entry == NULL){ - result = ESP_FAIL; - } - else{ - char * entry_str = cJSON_PrintUnformatted(entry); - if(entry_str!=NULL){ - ESP_LOGV(TAG,"config_set_value result: \n%s",entry_str); - free(entry_str); - } - else { - ESP_LOGV(TAG,"config_set_value completed"); - } - } - config_unlock(); - return result; -} -cJSON* cjson_update_string(cJSON** root, const char* key, const char* value) { - if (*root == NULL) { - *root = cJSON_CreateObject(); - if (*root == NULL) { - ESP_LOGE(TAG, "Error creating cJSON object!"); - } - } - if (!key || !value || strlen(key) == 0) { - ESP_LOGE(TAG, "cjson_update_string. Invalid key or value passed! key: %s, value: %s", STR_OR_ALT(key, ""), STR_OR_ALT(value, "")); - return *root; - } - cJSON* cjsonvalue = cJSON_GetObjectItemCaseSensitive(*root, key); - if (cjsonvalue && strcasecmp(cJSON_GetStringValue(cjsonvalue), value) != 0) { - ESP_LOGD(TAG, "Value %s changed from %s to %s", key, cJSON_GetStringValue(cjsonvalue), value); - cJSON_SetValuestring(cjsonvalue, value); - } else if(!cjsonvalue){ - ESP_LOGD(TAG, "Adding new value %s: %s", key, value); - cJSON_AddItemToObject(*root, key, cJSON_CreateString(value)); - } - return *root; -} -cJSON* cjson_update_number(cJSON** root, const char* key, int value) { - - if (*root == NULL) { - *root = cJSON_CreateObject(); - } - if (key && strlen(key) != 0) { - cJSON* cjsonvalue = cJSON_GetObjectItemCaseSensitive(*root, key); - if (cjsonvalue) { - cJSON_SetNumberValue(cjsonvalue, value); - } else { - cJSON_AddNumberToObject(*root, key, value); - } - } - return *root; -} - -IMPLEMENT_SET_DEFAULT(uint8_t,NVS_TYPE_U8); -IMPLEMENT_SET_DEFAULT(int8_t,NVS_TYPE_I8); -IMPLEMENT_SET_DEFAULT(uint16_t,NVS_TYPE_U16); -IMPLEMENT_SET_DEFAULT(int16_t,NVS_TYPE_I16); -IMPLEMENT_SET_DEFAULT(uint32_t,NVS_TYPE_U32); -IMPLEMENT_SET_DEFAULT(int32_t,NVS_TYPE_I32); - -IMPLEMENT_GET_NUM(uint8_t,NVS_TYPE_U8); -IMPLEMENT_GET_NUM(int8_t,NVS_TYPE_I8); -IMPLEMENT_GET_NUM(uint16_t,NVS_TYPE_U16); -IMPLEMENT_GET_NUM(int16_t,NVS_TYPE_I16); -IMPLEMENT_GET_NUM(uint32_t,NVS_TYPE_U32); -IMPLEMENT_GET_NUM(int32_t,NVS_TYPE_I32); diff --git a/components/platform_config/platform_config.h b/components/platform_config/platform_config.h deleted file mode 100644 index cf0a0c1e..00000000 --- a/components/platform_config/platform_config.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once -#include -#include -#include "nvs.h" -#include "assert.h" -#include "cJSON.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define PARSE_PARAM(S,P,C,V) do { \ - char *__p; \ - if ((__p = strcasestr(S, P)) && (__p = strchr(__p, C))) V = atoi(__p+1); \ - } while (0) - -#define PARSE_PARAM_FLOAT(S,P,C,V) do { \ - char *__p; \ - if ((__p = strcasestr(S, P)) && (__p = strchr(__p, C))) V = atof(__p+1); \ - } while (0) - -#define PARSE_PARAM_STR(S,P,C,V,I) do { \ - char *__p; \ - if ((__p = strstr(S, P)) && (__p = strchr(__p, C))) { \ - while (*++__p == ' '); \ - sscanf(__p,"%" #I "[^,]", V); \ - } \ - } while (0) - -#define DECLARE_SET_DEFAULT(t) void config_set_default_## t (const char *key, t value); -#define DECLARE_GET_NUM(t) esp_err_t config_get_## t (const char *key, t * value); -#ifndef FREE_RESET -#define FREE_RESET(p) if(p!=NULL) { free(p); p=NULL; } -#endif - -DECLARE_SET_DEFAULT(uint8_t); -DECLARE_SET_DEFAULT(uint16_t); -DECLARE_SET_DEFAULT(uint32_t); -DECLARE_SET_DEFAULT(int8_t); -DECLARE_SET_DEFAULT(int16_t); -DECLARE_SET_DEFAULT(int32_t); -DECLARE_GET_NUM(uint8_t); -DECLARE_GET_NUM(uint16_t); -DECLARE_GET_NUM(uint32_t); -DECLARE_GET_NUM(int8_t); -DECLARE_GET_NUM(int16_t); -DECLARE_GET_NUM(int32_t); - -bool config_has_changes(); -void config_commit_to_nvs(); -void config_start_timer(); -void config_init(); -void * config_alloc_get_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size); -void * config_alloc_get_str(const char *key, char *lead, char *fallback); -cJSON * config_alloc_get_cjson(const char *key); -esp_err_t config_set_cjson_str_and_free(const char *key, cJSON *value); -esp_err_t config_set_cjson(const char *key, cJSON *value, bool free_cjson); -void config_get_uint16t_from_str(const char *key, uint16_t *value, uint16_t default_value); -void config_delete_key(const char *key); -void config_set_default(nvs_type_t type, const char *key, const void * default_value, size_t blob_size); -void * config_alloc_get(nvs_type_t nvs_type, const char *key) ; -bool wait_for_commit(); -char * config_alloc_get_json(bool bFormatted); -esp_err_t config_set_value(nvs_type_t nvs_type, const char *key, const void * value); -nvs_type_t config_get_item_type(cJSON * entry); -void * config_safe_alloc_get_entry_value(nvs_type_t nvs_type, cJSON * entry); -cJSON* cjson_update_number(cJSON** root, const char* key, int value); -cJSON* cjson_update_string(cJSON** root, const char* key, const char* value); -#ifdef __cplusplus -} -#endif - diff --git a/components/platform_console/CMakeLists.txt b/components/platform_console/CMakeLists.txt index 4fee8bd2..e3d0d08d 100644 --- a/components/platform_console/CMakeLists.txt +++ b/components/platform_console/CMakeLists.txt @@ -1,6 +1,5 @@ idf_component_register( SRCS cmd_i2ctools.c - cmd_nvs.c cmd_ota.c cmd_system.c cmd_wifi.c diff --git a/components/platform_console/app_recovery/recovery.c b/components/platform_console/app_recovery/recovery.c index 8f06f20f..1cb17e2b 100644 --- a/components/platform_console/app_recovery/recovery.c +++ b/components/platform_console/app_recovery/recovery.c @@ -40,7 +40,10 @@ int main(int argc, char **argv){ return 1; } -void register_squeezelite(){ +// void register_squeezelite(){ +// } + +void start_squeezelite(){ } void register_external(void) { diff --git a/components/platform_console/app_squeezelite/cmd_squeezelite.c b/components/platform_console/app_squeezelite/cmd_squeezelite.c index 409d45f9..b6cc3aac 100644 --- a/components/platform_console/app_squeezelite/cmd_squeezelite.c +++ b/components/platform_console/app_squeezelite/cmd_squeezelite.c @@ -9,14 +9,16 @@ #include "freertos/event_groups.h" #include "pthread.h" #include "platform_esp32.h" -#include "platform_config.h" +#include "Configurator.h" #include "esp_app_format.h" #include "tools.h" #include "messaging.h" - extern esp_err_t process_recovery_ota(const char * bin_url, char * bin_buffer, uint32_t length); +extern int squeezelite_main_start(); + static const char * TAG = "squeezelite_cmd"; #define SQUEEZELITE_THREAD_STACK_SIZE (8*1024) +#define ADDITIONAL_SQUEEZELITE_ARGS 5 const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = { @@ -41,19 +43,9 @@ const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = { }; extern void register_audio_config(void); -extern void register_rotary_config(void); -extern void register_ledvu_config(void); +// extern void register_rotary_config(void); extern void register_nvs(); extern cJSON * get_gpio_list_handler(bool refresh); -void register_optional_cmd(void) { -#if CONFIG_WITH_CONFIG_UI - register_rotary_config(); -#endif - register_audio_config(); - register_ledvu_config(); - register_nvs(); - -} cJSON * get_gpio_list(bool refresh){ #if CONFIG_WITH_CONFIG_UI return get_gpio_list_handler(refresh); @@ -61,11 +53,14 @@ cJSON * get_gpio_list(bool refresh){ return cJSON_CreateArray(); #endif } +void register_optional_cmd(void) { +// #if CONFIG_WITH_CONFIG_UI +// register_rotary_config(); +// #endif + register_audio_config(); + // register_ledvu_config(); - -extern int squeezelite_main(int argc, char **argv); - -static int launchsqueezelite(int argc, char **argv); +} /** Arguments used by 'squeezelite' function */ static struct { @@ -77,7 +72,6 @@ static struct { char ** argv; } thread_parms ; -#define ADDITIONAL_SQUEEZELITE_ARGS 5 static void squeezelite_thread(void *arg){ ESP_LOGV(TAG ,"Number of args received: %u",thread_parms.argc ); ESP_LOGV(TAG ,"Values:"); @@ -85,13 +79,14 @@ static void squeezelite_thread(void *arg){ ESP_LOGV(TAG ," %s",thread_parms.argv[i]); } ESP_LOGI(TAG ,"Calling squeezelite"); - int ret = squeezelite_main(thread_parms.argc, thread_parms.argv); + int ret = squeezelite_main_start(thread_parms.argc, thread_parms.argv); cmd_send_messaging("cfg-audio-tmpl",ret > 1 ? MESSAGING_ERROR : MESSAGING_WARNING,"squeezelite exited with error code %d\n", ret); if (ret <= 1) { int wait = 60; - wait_for_commit(); + // wait_for_commit(); + // TODO: Add support for the commented code cmd_send_messaging("cfg-audio-tmpl",MESSAGING_ERROR,"Rebooting in %d sec\n", wait); vTaskDelay( pdMS_TO_TICKS(wait * 1000)); esp_restart(); @@ -119,26 +114,26 @@ static int launchsqueezelite(int argc, char **argv) { ESP_LOGV(TAG ,"Begin"); isRunning = true; - ESP_LOGV(TAG, "Parameters:"); - for(int i = 0;i", "command line for squeezelite. -h for help, --defaults to launch with default values."); - squeezelite_args.end = arg_end(1); - const esp_console_cmd_t launch_squeezelite = { - .command = "squeezelite", - .help = "Starts squeezelite", - .hint = NULL, - .func = &launchsqueezelite, - .argtable = &squeezelite_args - }; - ESP_ERROR_CHECK( esp_console_cmd_register(&launch_squeezelite) ); +void start_squeezelite(){ + launchsqueezelite(0,NULL); } +// void register_squeezelite() { +// squeezelite_args.parameters = arg_str0(NULL, NULL, "", "command line for squeezelite. -h for help, --defaults to launch with default values."); +// squeezelite_args.end = arg_end(1); +// const esp_console_cmd_t launch_squeezelite = { +// .command = "squeezelite", +// .help = "Starts squeezelite", +// .hint = NULL, +// .func = &launchsqueezelite, +// .argtable = &squeezelite_args +// }; +// ESP_ERROR_CHECK( esp_console_cmd_register(&launch_squeezelite) ); +// } esp_err_t start_ota(const char * bin_url, char * bin_buffer, uint32_t length) { - if(!bin_url){ + if(!bin_url || strlen(bin_url)==0){ ESP_LOGE(TAG,"missing URL parameter. Unable to start OTA"); return ESP_ERR_INVALID_ARG; } ESP_LOGW(TAG, "Called to update the firmware from url: %s",bin_url); - if(config_set_value(NVS_TYPE_STR, "fwurl", bin_url) != ESP_OK){ - ESP_LOGE(TAG,"Failed to save the OTA url into nvs cache"); - return ESP_FAIL; - } + configurator_set_string(&sys_State_msg,sys_State_ota_url_tag,sys_state,bin_url); + configurator_raise_state_changed(); - if(!wait_for_commit()){ + if(!configurator_waitcommit()){ ESP_LOGW(TAG,"Unable to commit configuration. "); } - ESP_LOGW(TAG, "Rebooting to recovery to complete the installation"); return guided_factory(); return ESP_OK; diff --git a/components/platform_console/cmd_config.c b/components/platform_console/cmd_config.c index 6ce18db1..b664c975 100644 --- a/components/platform_console/cmd_config.c +++ b/components/platform_console/cmd_config.c @@ -13,7 +13,7 @@ #include "esp_log.h" #include "string.h" #include "stdio.h" -#include "platform_config.h" +#include "Configurator.h" #include "messaging.h" #include "accessors.h" #include "adac.h" @@ -24,7 +24,9 @@ #include "metrics.h" #endif #include "cmd_system.h" +#include "network_manager.h" const char * desc_squeezelite ="Squeezelite Options"; +const char * desc_wifi ="Wifi Operations"; const char * desc_dac= "DAC Options"; const char * desc_cspotc= "Spotify (cSpot) Options"; const char * desc_preset= "Preset Options"; @@ -122,7 +124,13 @@ static struct { struct arg_lit * clear; struct arg_end * end; } ledvu_args; +static struct{ + struct arg_str *ap_name; + struct arg_str *password; + struct arg_lit *conn; + struct arg_end *end; +} wifi_ap_args; static struct{ struct arg_str *sink_name; struct arg_str *pin_code; @@ -344,28 +352,30 @@ static int do_bt_source_cmd(int argc, char **argv){ } if(bt_source_args.sink_name->count >0){ - err = config_set_value(NVS_TYPE_STR, "a2dp_sink_name", bt_source_args.sink_name->sval[0]); - if(err!=ESP_OK){ - nerrors++; - fprintf(f,"Error setting Bluetooth audio device name %s. %s\n",bt_source_args.sink_name->sval[0], esp_err_to_name(err)); - } - else { - fprintf(f,"Bluetooth audio device name changed to %s\n",bt_source_args.sink_name->sval[0]); - } - char * squeezelite_cmd = config_alloc_get_default(NVS_TYPE_STR, "autoexec1", NULL, 0); - if( squeezelite_cmd && strstr(squeezelite_cmd," -o ") ){ - char * new_cmd = strip_bt_name(squeezelite_cmd); - if(strcmp(new_cmd,squeezelite_cmd)!=0){ - fprintf(f,"Replacing old squeezelite command [%s] with [%s].\n",squeezelite_cmd,new_cmd); - config_set_value(NVS_TYPE_STR, "autoexec1", new_cmd); - if(err!=ESP_OK){ - nerrors++; - fprintf(f,"Error updating squeezelite command line options . %s\n", esp_err_to_name(err)); - } - } - free(squeezelite_cmd); - free(new_cmd); - } + // err = config_set_value(NVS_TYPE_STR, "a2dp_sink_name", bt_source_args.sink_name->sval[0]); + // if(err!=ESP_OK){ + // nerrors++; + // fprintf(f,"Error setting Bluetooth audio device name %s. %s\n",bt_source_args.sink_name->sval[0], esp_err_to_name(err)); + // } + // else { + // fprintf(f,"Bluetooth audio device name changed to %s\n",bt_source_args.sink_name->sval[0]); + // } + + // char * squeezelite_cmd = config_alloc_get_default(NVS_TYPE_STR, "autoexec1", NULL, 0); + // if( squeezelite_cmd && strstr(squeezelite_cmd," -o ") ){ + // char * new_cmd = strip_bt_name(squeezelite_cmd); + // if(strcmp(new_cmd,squeezelite_cmd)!=0){ + // fprintf(f,"Replacing old squeezelite command [%s] with [%s].\n",squeezelite_cmd,new_cmd); + // config_set_value(NVS_TYPE_STR, "autoexec1", new_cmd); + // if(err!=ESP_OK){ + // nerrors++; + // fprintf(f,"Error updating squeezelite command line options . %s\n", esp_err_to_name(err)); + // } + // } + // free(squeezelite_cmd); + // free(new_cmd); + // } + // TODO: Add support for the commented code } if(bt_source_args.pin_code->count >0){ @@ -381,14 +391,15 @@ static int do_bt_source_cmd(int argc, char **argv){ fprintf(f,"Pin code %s invalid. Should be numbers only with length between 4 and 16 characters. \n",bt_source_args.pin_code->sval[0]); } else { - err = config_set_value(NVS_TYPE_STR, "a2dp_spin", bt_source_args.pin_code->sval[0]); - if(err!=ESP_OK){ - nerrors++; - fprintf(f,"Error setting Bluetooth source pin to %s. %s\n",bt_source_args.pin_code->sval[0], esp_err_to_name(err)); - } - else { - fprintf(f,"Bluetooth source pin changed to %s\n",bt_source_args.pin_code->sval[0]); - } + // err = config_set_value(NVS_TYPE_STR, "a2dp_spin", bt_source_args.pin_code->sval[0]); + // if(err!=ESP_OK){ + // nerrors++; + // fprintf(f,"Error setting Bluetooth source pin to %s. %s\n",bt_source_args.pin_code->sval[0], esp_err_to_name(err)); + // } + // else { + // fprintf(f,"Bluetooth source pin changed to %s\n",bt_source_args.pin_code->sval[0]); + // } + // TODO: Add support for the commented code } } // if(bt_source_args.connect_timeout_delay->count >0){ @@ -437,6 +448,18 @@ static int do_bt_source_cmd(int argc, char **argv){ FREE_AND_NULL(buf); return (nerrors==0 && err==ESP_OK)?0:1; +} +static void do_wifi_ops(int argc, char **argv){ + esp_err_t err=ESP_OK; + int nerrors = arg_parse(argc, argv,(void **)&wifi_ap_args); + if(nerrors >0){ + return 1; + } + if(wifi_ap_args.conn->count >0){ + network_async_connect(wifi_ap_args.ap_name->sval[0],wifi_ap_args.password->sval[0]); + } + + } static int do_audio_cmd(int argc, char **argv){ esp_err_t err=ESP_OK; @@ -465,7 +488,8 @@ static int do_audio_cmd(int argc, char **argv){ // it's not necessary to store loudness in NVS as set_loudness does it, but it does not hurt else { itoa(loudness_val,p,10); - err = config_set_value(NVS_TYPE_STR, "loudness", p); + // err = config_set_value(NVS_TYPE_STR, "loudness", p); + // TODO: Add support for the commented code } if(err!=ESP_OK){ nerrors++; @@ -479,16 +503,17 @@ static int do_audio_cmd(int argc, char **argv){ if(audio_args.jack_behavior->count>0){ err = ESP_OK; // suppress any error code that might have happened in a previous step - if(strcasecmp(audio_args.jack_behavior->sval[0],"Headphones")==0){ - err = config_set_value(NVS_TYPE_STR, "jack_mutes_amp", "y"); - } - else if(strcasecmp(audio_args.jack_behavior->sval[0],"Subwoofer")==0){ - err = config_set_value(NVS_TYPE_STR, "jack_mutes_amp", "n"); - } - else { - nerrors++; - fprintf(f,"Unknown Audio Jack Behavior %s.\n",audio_args.jack_behavior->sval[0]); - } + // TODO: Add support for the commented code + // if(strcasecmp(audio_args.jack_behavior->sval[0],"Headphones")==0){ + // err = config_set_value(NVS_TYPE_STR, "jack_mutes_amp", "y"); + // } + // else if(strcasecmp(audio_args.jack_behavior->sval[0],"Subwoofer")==0){ + // err = config_set_value(NVS_TYPE_STR, "jack_mutes_amp", "n"); + // } + // else { + // nerrors++; + // fprintf(f,"Unknown Audio Jack Behavior %s.\n",audio_args.jack_behavior->sval[0]); + // } if(err!=ESP_OK){ nerrors++; @@ -508,115 +533,118 @@ static int do_audio_cmd(int argc, char **argv){ FREE_AND_NULL(buf); return (nerrors==0 && err==ESP_OK)?0:1; } -static int do_spdif_cmd(int argc, char **argv){ - i2s_platform_config_t i2s_dac_pin = { - .i2c_addr = -1, - .sda= -1, - .scl = -1, - .mute_gpio = -1, - .mute_level = -1 - }; - if(is_spdif_config_locked()){ - cmd_send_messaging(argv[0],MESSAGING_ERROR,"SPDIF Configuration is locked on this platform\n"); - return 1; - } - esp_err_t err=ESP_OK; - int nerrors = arg_parse(argc, argv,(void **)&spdif_args); - if (spdif_args.clear->count) { - cmd_send_messaging(argv[0],MESSAGING_WARNING,"SPDIF config cleared\n"); - config_set_value(NVS_TYPE_STR, "spdif_config", ""); - return 0; - } +// static int do_spdif_cmd(int argc, char **argv){ +// i2s_platform_config_t i2s_dac_pin = { +// .i2c_addr = -1, +// .sda= -1, +// .scl = -1, +// .mute_gpio = -1, +// .mute_level = -1 +// }; +// // if(is_spdif_config_locked()){ +// // cmd_send_messaging(argv[0],MESSAGING_ERROR,"SPDIF Configuration is locked on this platform\n"); +// // return 1; +// // } +// // esp_err_t err=ESP_OK; +// // int nerrors = arg_parse(argc, argv,(void **)&spdif_args); +// // if (spdif_args.clear->count) { +// // cmd_send_messaging(argv[0],MESSAGING_WARNING,"SPDIF config cleared\n"); +// // // config_set_value(NVS_TYPE_STR, "spdif_config", ""); +// // // TODO: Add support for the commented code +// // return 0; +// // } - char *buf = NULL; - size_t buf_size = 0; - FILE *f = system_open_memstream(argv[0],&buf, &buf_size); - if (f == NULL) { - return 1; - } - if(nerrors >0){ - arg_print_errors(f,spdif_args.end,desc_dac); - fclose(f); - return 1; - } - nerrors+=is_output_gpio(spdif_args.clock, f, &i2s_dac_pin.pin.bck_io_num, true); - nerrors+=is_output_gpio(spdif_args.wordselect, f, &i2s_dac_pin.pin.ws_io_num, true); - nerrors+=is_output_gpio(spdif_args.data, f, &i2s_dac_pin.pin.data_out_num, true); - if(!nerrors ){ - fprintf(f,"Storing SPDIF parameters.\n"); - nerrors+=(config_spdif_set(&i2s_dac_pin )!=ESP_OK); - } - if(!nerrors ){ - fprintf(f,"Done.\n"); - } - fflush (f); - cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); - fclose(f); - FREE_AND_NULL(buf); - return (nerrors==0 && err==ESP_OK)?0:1; -} +// // char *buf = NULL; +// // size_t buf_size = 0; +// // FILE *f = system_open_memstream(argv[0],&buf, &buf_size); +// // if (f == NULL) { +// // return 1; +// // } +// // if(nerrors >0){ +// // arg_print_errors(f,spdif_args.end,desc_dac); +// // fclose(f); +// // return 1; +// // } +// // nerrors+=is_output_gpio(spdif_args.clock, f, &i2s_dac_pin.pin.bck_io_num, true); +// // nerrors+=is_output_gpio(spdif_args.wordselect, f, &i2s_dac_pin.pin.ws_io_num, true); +// // nerrors+=is_output_gpio(spdif_args.data, f, &i2s_dac_pin.pin.data_out_num, true); +// // if(!nerrors ){ +// // fprintf(f,"Storing SPDIF parameters.\n"); +// // nerrors+=(config_spdif_set(&i2s_dac_pin )!=ESP_OK); +// // } +// // if(!nerrors ){ +// // fprintf(f,"Done.\n"); +// // } +// // fflush (f); +// // cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); +// // fclose(f); +// // FREE_AND_NULL(buf); +// // return (nerrors==0 && err==ESP_OK)?0:1; +// return 0; +// } -static int do_rotary_cmd(int argc, char **argv){ - rotary_struct_t rotary={ .A = -1, .B = -1, .SW = -1, .longpress = 0, .knobonly=0,.volume_lock=false}; - esp_err_t err=ESP_OK; - int nerrors = arg_parse(argc, argv,(void **)&rotary_args); - if (rotary_args.clear->count) { - cmd_send_messaging(argv[0],MESSAGING_WARNING,"rotary config cleared\n"); - config_set_value(NVS_TYPE_STR, "rotary_config", ""); - return 0; - } +// static int do_rotary_cmd(int argc, char **argv){ +// rotary_struct_t rotary={ .A = -1, .B = -1, .SW = -1, .longpress = 0, .knobonly=0,.volume_lock=false}; +// esp_err_t err=ESP_OK; +// int nerrors = arg_parse(argc, argv,(void **)&rotary_args); +// if (rotary_args.clear->count) { +// cmd_send_messaging(argv[0],MESSAGING_WARNING,"rotary config cleared\n"); +// // config_set_value(NVS_TYPE_STR, "rotary_config", ""); +// // TODO: Add support for the commented code +// return 0; +// } - char *buf = NULL; - size_t buf_size = 0; - FILE *f = system_open_memstream(argv[0],&buf, &buf_size); - if (f == NULL) { - return 1; - } - if(nerrors >0){ - arg_print_errors(f,rotary_args.end,desc_rotary); - fclose(f); - return 1; - } - nerrors+=is_gpio(rotary_args.A, f, &rotary.A, true,false); - nerrors+=is_gpio(rotary_args.B, f, &rotary.B, true,false); - nerrors+=is_gpio(rotary_args.SW, f, &rotary.SW,false,false); +// char *buf = NULL; +// size_t buf_size = 0; +// FILE *f = system_open_memstream(argv[0],&buf, &buf_size); +// if (f == NULL) { +// return 1; +// } +// if(nerrors >0){ +// arg_print_errors(f,rotary_args.end,desc_rotary); +// fclose(f); +// return 1; +// } +// nerrors+=is_gpio(rotary_args.A, f, &rotary.A, true,false); +// nerrors+=is_gpio(rotary_args.B, f, &rotary.B, true,false); +// nerrors+=is_gpio(rotary_args.SW, f, &rotary.SW,false,false); - if(rotary_args.knobonly->count>0 && (rotary_args.volume_lock->count>0 || rotary_args.longpress->count>0)){ - fprintf(f,"error: Cannot use volume lock or longpress option when knob only option selected\n"); - nerrors++; - } +// if(rotary_args.knobonly->count>0 && (rotary_args.volume_lock->count>0 || rotary_args.longpress->count>0)){ +// fprintf(f,"error: Cannot use volume lock or longpress option when knob only option selected\n"); +// nerrors++; +// } - if(rotary_args.timer->count>0 && rotary_args.timer->ival[0]<0){ - fprintf(f,"error: knob only timer should be greater than or equal to zero.\n"); - nerrors++; - } - else { - rotary.timer = rotary_args.timer->count>0?rotary_args.timer->ival[0]:0; - } - rotary.knobonly = rotary_args.knobonly->count>0; - rotary.volume_lock= rotary_args.volume_lock->count>0; - rotary.longpress = rotary_args.longpress->count>0; - if(!nerrors ){ - fprintf(f,"Storing rotary parameters.\n"); - nerrors+=(config_rotary_set(&rotary )!=ESP_OK); - } - if(!nerrors ){ - fprintf(f,"Storing raw mode parameter.\n"); - nerrors+=(config_set_value(NVS_TYPE_STR, "lms_ctrls_raw", rotary_args.raw_mode->count>0?"Y":"N")!=ESP_OK); - if(nerrors>0){ - fprintf(f,"error: Unable to store raw mode parameter.\n"); - } - } - if(!nerrors ){ - fprintf(f,"Done.\n"); - } - fflush (f); - cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); - fclose(f); - FREE_AND_NULL(buf); - return (nerrors==0 && err==ESP_OK)?0:1; -} +// if(rotary_args.timer->count>0 && rotary_args.timer->ival[0]<0){ +// fprintf(f,"error: knob only timer should be greater than or equal to zero.\n"); +// nerrors++; +// } +// else { +// rotary.timer = rotary_args.timer->count>0?rotary_args.timer->ival[0]:0; +// } +// rotary.knobonly = rotary_args.knobonly->count>0; +// rotary.volume_lock= rotary_args.volume_lock->count>0; +// rotary.longpress = rotary_args.longpress->count>0; +// if(!nerrors ){ +// fprintf(f,"Storing rotary parameters.\n"); +// nerrors+=(config_rotary_set(&rotary )!=ESP_OK); +// } +// if(!nerrors ){ +// fprintf(f,"Storing raw mode parameter.\n"); +// // nerrors+=(config_set_value(NVS_TYPE_STR, "lms_ctrls_raw", rotary_args.raw_mode->count>0?"Y":"N")!=ESP_OK); +// if(nerrors>0){ +// fprintf(f,"error: Unable to store raw mode parameter.\n"); +// } +// } +// if(!nerrors ){ +// fprintf(f,"Done.\n"); +// } +// fflush (f); +// cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); +// fclose(f); +// FREE_AND_NULL(buf); +// return (nerrors==0 && err==ESP_OK)?0:1; +// } static int is_valid_gpio_number(int gpio, const char * name, FILE *f, bool mandatory, struct arg_int * target, bool output){ bool invalid = (!GPIO_IS_VALID_GPIO(gpio) ||(output && !GPIO_IS_VALID_OUTPUT_GPIO(gpio))) ; if(invalid && mandatory && gpio!=-1){ @@ -644,39 +672,40 @@ static int do_cspot_config(int argc, char **argv){ return 1; } - cJSON * cspot_config = config_alloc_get_cjson("cspot_config"); - if(!cspot_config){ - nerrors++; - fprintf(f,"error: Unable to get default cspot config.\n"); - } - if(cspot_args.deviceName->count>0){ - cjson_update_string(&cspot_config,cspot_args.deviceName->hdr.longopts,cspot_args.deviceName->sval[0]); - } - if(cspot_args.bitrate->count>0){ - cjson_update_number(&cspot_config,cspot_args.bitrate->hdr.longopts,cspot_args.bitrate->ival[0]); - } - if(cspot_args.zeroConf->count>0){ - cjson_update_number(&cspot_config,cspot_args.zeroConf->hdr.longopts,cspot_args.zeroConf->ival[0]); - } + // cJSON * cspot_config = config_alloc_get_cjson("cspot_config"); + // if(!cspot_config){ + // nerrors++; + // fprintf(f,"error: Unable to get default cspot config.\n"); + // } + // if(cspot_args.deviceName->count>0){ + // cjson_update_string(&cspot_config,cspot_args.deviceName->hdr.longopts,cspot_args.deviceName->sval[0]); + // } + // if(cspot_args.bitrate->count>0){ + // cjson_update_number(&cspot_config,cspot_args.bitrate->hdr.longopts,cspot_args.bitrate->ival[0]); + // } + // if(cspot_args.zeroConf->count>0){ + // cjson_update_number(&cspot_config,cspot_args.zeroConf->hdr.longopts,cspot_args.zeroConf->ival[0]); + // } - if(!nerrors ){ - fprintf(f,"Storing cspot parameters.\n"); - nerrors+=(config_set_cjson_str_and_free("cspot_config",cspot_config) !=ESP_OK); - } - if(nerrors==0 ){ - if(cspot_args.deviceName->count>0){ - fprintf(f,"Device name changed to %s\n",cspot_args.deviceName->sval[0]); - } - if(cspot_args.bitrate->count>0){ - fprintf(f,"Bitrate changed to %u\n",cspot_args.bitrate->ival[0]); - } - if(cspot_args.zeroConf->count>0){ - fprintf(f,"ZeroConf changed to %u\n",cspot_args.zeroConf->ival[0]); - } - } - if(!nerrors ){ - fprintf(f,"Done.\n"); - } + // if(!nerrors ){ + // fprintf(f,"Storing cspot parameters.\n"); + // nerrors+=(config_set_cjson_str_and_free("cspot_config",cspot_config) !=ESP_OK); + // } + // if(nerrors==0 ){ + // if(cspot_args.deviceName->count>0){ + // fprintf(f,"Device name changed to %s\n",cspot_args.deviceName->sval[0]); + // } + // if(cspot_args.bitrate->count>0){ + // fprintf(f,"Bitrate changed to %u\n",cspot_args.bitrate->ival[0]); + // } + // if(cspot_args.zeroConf->count>0){ + // fprintf(f,"ZeroConf changed to %u\n",cspot_args.zeroConf->ival[0]); + // } + // } + // if(!nerrors ){ + // fprintf(f,"Done.\n"); + // } + // TODO: Add support for the commented code fflush (f); cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); fclose(f); @@ -685,121 +714,119 @@ static int do_cspot_config(int argc, char **argv){ } #endif -static int do_ledvu_cmd(int argc, char **argv){ - ledvu_struct_t ledvu={ .type = "WS2812", .gpio = -1, .length = 0}; - esp_err_t err=ESP_OK; - int nerrors = arg_parse(argc, argv,(void **)&ledvu_args); - if (ledvu_args.clear->count) { - cmd_send_messaging(argv[0],MESSAGING_WARNING,"ledvu config cleared\n"); - config_set_value(NVS_TYPE_STR, "led_vu_config", ""); - return 0; - } +// static int do_ledvu_cmd(int argc, char **argv){ +// ledvu_struct_t ledvu={ .type = "WS2812", .gpio = -1, .length = 0}; +// esp_err_t err=ESP_OK; +// int nerrors = arg_parse(argc, argv,(void **)&ledvu_args); +// if (ledvu_args.clear->count) { +// cmd_send_messaging(argv[0],MESSAGING_WARNING,"ledvu config cleared\n"); +// // config_set_value(NVS_TYPE_STR, "led_vu_config", ""); +// // TODO: Add support for the commented code +// return 0; +// } - char *buf = NULL; - size_t buf_size = 0; - FILE *f = system_open_memstream(argv[0],&buf, &buf_size); - if (f == NULL) { - return 1; - } - if(nerrors >0){ - arg_print_errors(f,ledvu_args.end,desc_ledvu); - return 1; - } +// char *buf = NULL; +// size_t buf_size = 0; +// FILE *f = system_open_memstream(argv[0],&buf, &buf_size); +// if (f == NULL) { +// return 1; +// } +// if(nerrors >0){ +// arg_print_errors(f,ledvu_args.end,desc_ledvu); +// return 1; +// } - nerrors+=is_output_gpio(ledvu_args.gpio, f, &ledvu.gpio, true); +// nerrors+=is_output_gpio(ledvu_args.gpio, f, &ledvu.gpio, true); - if(ledvu_args.length->count==0 || ledvu_args.length->ival[0]<1 || ledvu_args.length->ival[0]>255){ - fprintf(f,"error: strip length must be greater than 0 and no more than 255\n"); - nerrors++; - } - else { - ledvu.length = ledvu_args.length->count>0?ledvu_args.length->ival[0]:0; - } +// if(ledvu_args.length->count==0 || ledvu_args.length->ival[0]<1 || ledvu_args.length->ival[0]>255){ +// fprintf(f,"error: strip length must be greater than 0 and no more than 255\n"); +// nerrors++; +// } +// else { +// ledvu.length = ledvu_args.length->count>0?ledvu_args.length->ival[0]:0; +// } - if(!nerrors ){ - fprintf(f,"Storing ledvu parameters.\n"); - nerrors+=(config_ledvu_set(&ledvu )!=ESP_OK); - } - if(!nerrors ){ - fprintf(f,"Done.\n"); - } - fflush (f); - cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); - fclose(f); - FREE_AND_NULL(buf); - return (nerrors==0 && err==ESP_OK)?0:1; -} +// if(!nerrors ){ +// fprintf(f,"Storing ledvu parameters.\n"); +// nerrors+=(config_ledvu_set(&ledvu )!=ESP_OK); +// } +// if(!nerrors ){ +// fprintf(f,"Done.\n"); +// } +// fflush (f); +// cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); +// fclose(f); +// FREE_AND_NULL(buf); +// return (nerrors==0 && err==ESP_OK)?0:1; +// } -static int do_i2s_cmd(int argc, char **argv) -{ - i2s_platform_config_t i2s_dac_pin = { - .i2c_addr = -1, - .sda= -1, - .scl = -1, - .mute_gpio = -1, - .mute_level = -1 - }; - if(is_dac_config_locked()){ - cmd_send_messaging(argv[0],MESSAGING_ERROR,"DAC Configuration is locked on this platform\n"); - return 1; - } +// static int do_i2s_cmd(int argc, char **argv) +// { +// i2s_platform_config_t i2s_dac_pin = { +// .i2c_addr = -1, +// .sda= -1, +// .scl = -1, +// .mute_gpio = -1, +// .mute_level = -1 +// }; - ESP_LOGD(TAG,"Processing i2s command %s with %d parameters",argv[0],argc); +// ESP_LOGD(TAG,"Processing i2s command %s with %d parameters",argv[0],argc); - esp_err_t err=ESP_OK; - int nerrors = arg_parse(argc, argv,(void **)&i2s_args); - if (i2s_args.clear->count) { - cmd_send_messaging(argv[0],MESSAGING_WARNING,"DAC config cleared\n"); - config_set_value(NVS_TYPE_STR, "dac_config", ""); - return 0; - } +// esp_err_t err=ESP_OK; +// int nerrors = arg_parse(argc, argv,(void **)&i2s_args); +// // if (i2s_args.clear->count) { +// // cmd_send_messaging(argv[0],MESSAGING_WARNING,"DAC config cleared\n"); +// // // config_set_value(NVS_TYPE_STR, "dac_config", ""); +// // // TODO: Add support for the commented code +// // return 0; +// // } - char *buf = NULL; - size_t buf_size = 0; - FILE *f = system_open_memstream(argv[0],&buf, &buf_size); - if (f == NULL) { - return 1; - } - if(nerrors >0){ - ESP_LOGE(TAG,"do_i2s_cmd: %d errors parsing arguments",nerrors); - arg_print_errors(f,i2s_args.end,desc_dac); - } - else { - strncpy(i2s_dac_pin.model,i2s_args.model_name->sval[0],sizeof(i2s_dac_pin.model)); - i2s_dac_pin.model[sizeof(i2s_dac_pin.model) - 1] = '\0'; - nerrors += is_output_gpio(i2s_args.clock, f, &i2s_dac_pin.pin.bck_io_num, true); - nerrors += is_output_gpio(i2s_args.wordselect, f, &i2s_dac_pin.pin.ws_io_num, true); - nerrors += is_output_gpio(i2s_args.data, f, &i2s_dac_pin.pin.data_out_num, true); - nerrors += is_output_gpio(i2s_args.mute_gpio, f, &i2s_dac_pin.mute_gpio, false); - if (i2s_dac_pin.mute_gpio >= 0) { - i2s_dac_pin.mute_level = i2s_args.mute_level->count > 0 ? 1 : 0; - } - if (i2s_args.dac_sda->count > 0 && i2s_args.dac_sda->ival[0] >= 0) { - // if SDA specified, then SDA and SCL are both mandatory - nerrors += is_output_gpio(i2s_args.dac_sda, f, &i2s_dac_pin.sda, false); - nerrors += is_output_gpio(i2s_args.dac_scl, f, &i2s_dac_pin.scl, false); - } - if (i2s_args.dac_sda->count == 0 && i2s_args.dac_i2c->count > 0) { - fprintf(f, "warning: ignoring i2c address, since dac i2c gpios config is incomplete\n"); - } else if (i2s_args.dac_i2c->count > 0) { - i2s_dac_pin.i2c_addr = i2s_args.dac_i2c->ival[0]; - } +// // char *buf = NULL; +// // size_t buf_size = 0; +// // FILE *f = system_open_memstream(argv[0],&buf, &buf_size); +// // if (f == NULL) { +// // return 1; +// // } +// // if(nerrors >0){ +// // ESP_LOGE(TAG,"do_i2s_cmd: %d errors parsing arguments",nerrors); +// // arg_print_errors(f,i2s_args.end,desc_dac); +// // } +// // else { +// // strncpy(i2s_dac_pin.model,i2s_args.model_name->sval[0],sizeof(i2s_dac_pin.model)); +// // i2s_dac_pin.model[sizeof(i2s_dac_pin.model) - 1] = '\0'; +// // nerrors += is_output_gpio(i2s_args.clock, f, &i2s_dac_pin.pin.bck_io_num, true); +// // nerrors += is_output_gpio(i2s_args.wordselect, f, &i2s_dac_pin.pin.ws_io_num, true); +// // nerrors += is_output_gpio(i2s_args.data, f, &i2s_dac_pin.pin.data_out_num, true); +// // nerrors += is_output_gpio(i2s_args.mute_gpio, f, &i2s_dac_pin.mute_gpio, false); +// // if (i2s_dac_pin.mute_gpio >= 0) { +// // i2s_dac_pin.mute_level = i2s_args.mute_level->count > 0 ? 1 : 0; +// // } +// // if (i2s_args.dac_sda->count > 0 && i2s_args.dac_sda->ival[0] >= 0) { +// // // if SDA specified, then SDA and SCL are both mandatory +// // nerrors += is_output_gpio(i2s_args.dac_sda, f, &i2s_dac_pin.sda, false); +// // nerrors += is_output_gpio(i2s_args.dac_scl, f, &i2s_dac_pin.scl, false); +// // } +// // if (i2s_args.dac_sda->count == 0 && i2s_args.dac_i2c->count > 0) { +// // fprintf(f, "warning: ignoring i2c address, since dac i2c gpios config is incomplete\n"); +// // } else if (i2s_args.dac_i2c->count > 0) { +// // i2s_dac_pin.i2c_addr = i2s_args.dac_i2c->ival[0]; +// // } - if (!nerrors) { - fprintf(f, "Storing i2s parameters.\n"); - nerrors += (config_i2s_set(&i2s_dac_pin, "dac_config") != ESP_OK); - } - } - if(!nerrors ){ - fprintf(f,"Done.\n"); - } - fflush (f); - cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); - fclose(f); - FREE_AND_NULL(buf); +// // if (!nerrors) { +// // fprintf(f, "Storing i2s parameters.\n"); +// // nerrors += (config_i2s_set(&i2s_dac_pin, "dac_config") != ESP_OK); +// // } +// // } +// // if(!nerrors ){ +// // fprintf(f,"Done.\n"); +// // } +// // fflush (f); +// // cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); +// // fclose(f); +// // FREE_AND_NULL(buf); - return (nerrors==0 && err==ESP_OK)?0:1; -} +// return (nerrors==0 && err==ESP_OK)?0:1; +// } cJSON * example_cb(){ cJSON * values = cJSON_CreateObject(); @@ -822,17 +849,18 @@ cJSON * example_cb(){ cJSON * known_model_cb(){ cJSON * values = cJSON_CreateObject(); - if(!values){ - ESP_LOGE(TAG,"known_model_cb: Failed to create JSON object"); - return NULL; - } - char * name = config_alloc_get_default(NVS_TYPE_STR,known_model_args.model_config->hdr.longopts,"",0); - if(!name){ - ESP_LOGE(TAG,"Failed to get board model from nvs key %s ",known_model_args.model_config->hdr.longopts); - } - else { - cJSON_AddStringToObject(values,known_model_args.model_config->hdr.longopts,name); - } + // if(!values){ + // ESP_LOGE(TAG,"known_model_cb: Failed to create JSON object"); + // return NULL; + // } + // char * name = config_alloc_get_default(NVS_TYPE_STR,known_model_args.model_config->hdr.longopts,"",0); + // if(!name){ + // ESP_LOGE(TAG,"Failed to get board model from nvs key %s ",known_model_args.model_config->hdr.longopts); + // } + // else { + // cJSON_AddStringToObject(values,known_model_args.model_config->hdr.longopts,name); + // } + // TODO: Add support for the commented code return values; } #ifdef CONFIG_CSPOT_SINK @@ -842,174 +870,170 @@ cJSON * cspot_cb(){ ESP_LOGE(TAG,"cspot_cb: Failed to create JSON object"); return NULL; } - cJSON * cspot_config = config_alloc_get_cjson("cspot_config"); - if(!cspot_config){ - ESP_LOGE(TAG,"cspot_cb: Failed to get cspot config"); - return NULL; - } - cJSON * cspot_values = cJSON_GetObjectItem(cspot_config,cspot_args.deviceName->hdr.longopts); - if(cspot_values){ - cJSON_AddStringToObject(values,cspot_args.deviceName->hdr.longopts,cJSON_GetStringValue(cspot_values)); - } - cspot_values = cJSON_GetObjectItem(cspot_config,cspot_args.bitrate->hdr.longopts); - if(cspot_values){ - cJSON_AddNumberToObject(values,cspot_args.bitrate->hdr.longopts,cJSON_GetNumberValue(cspot_values)); - } - cspot_values = cJSON_GetObjectItem(cspot_config,cspot_args.zeroConf->hdr.longopts); - if(cspot_values){ - cJSON_AddNumberToObject(values,cspot_args.zeroConf->hdr.longopts,cJSON_GetNumberValue(cspot_values)); - } + // cJSON * cspot_config = config_alloc_get_cjson("cspot_config"); + // if(!cspot_config){ + // ESP_LOGE(TAG,"cspot_cb: Failed to get cspot config"); + // return NULL; + // } + // cJSON * cspot_values = cJSON_GetObjectItem(cspot_config,cspot_args.deviceName->hdr.longopts); + // if(cspot_values){ + // cJSON_AddStringToObject(values,cspot_args.deviceName->hdr.longopts,cJSON_GetStringValue(cspot_values)); + // } + // cspot_values = cJSON_GetObjectItem(cspot_config,cspot_args.bitrate->hdr.longopts); + // if(cspot_values){ + // cJSON_AddNumberToObject(values,cspot_args.bitrate->hdr.longopts,cJSON_GetNumberValue(cspot_values)); + // } + // cspot_values = cJSON_GetObjectItem(cspot_config,cspot_args.zeroConf->hdr.longopts); + // if(cspot_values){ + // cJSON_AddNumberToObject(values,cspot_args.zeroConf->hdr.longopts,cJSON_GetNumberValue(cspot_values)); + // } - cJSON_Delete(cspot_config); + // cJSON_Delete(cspot_config); + // TODO: Add support for the commented code return values; } #endif -cJSON * i2s_cb(){ - cJSON * values = cJSON_CreateObject(); +// cJSON * i2s_cb(){ +// cJSON * values = cJSON_CreateObject(); - const i2s_platform_config_t * i2s_conf= config_dac_get( ); -#if defined(CONFIG_WITH_METRICS) - metrics_add_feature("i2s",i2s_conf->pin.data_out_num>=0); -#endif - if(i2s_conf->pin.bck_io_num>0 ) { - cJSON_AddNumberToObject(values,i2s_args.clock->hdr.longopts,i2s_conf->pin.bck_io_num); - } - if(i2s_conf->pin.ws_io_num>=0 ) { - cJSON_AddNumberToObject(values,i2s_args.wordselect->hdr.longopts,i2s_conf->pin.ws_io_num); - } - if(i2s_conf->pin.data_out_num>=0 ) { - cJSON_AddNumberToObject(values,i2s_args.data->hdr.longopts,i2s_conf->pin.data_out_num); - } - if(i2s_conf->sda>=0 ) { - cJSON_AddNumberToObject(values,i2s_args.dac_sda->hdr.longopts,i2s_conf->sda); - } - if(i2s_conf->scl>=0 ) { - cJSON_AddNumberToObject(values,i2s_args.dac_scl->hdr.longopts,i2s_conf->scl); - } - if(i2s_conf->i2c_addr>=0 ) { - cJSON_AddNumberToObject(values,i2s_args.dac_i2c->hdr.longopts,i2s_conf->i2c_addr); - } - if(i2s_conf->mute_gpio>=0 ) { - cJSON_AddNumberToObject(values,i2s_args.mute_gpio->hdr.longopts,i2s_conf->mute_gpio); - } - if(i2s_conf->mute_level>=0 ) { - cJSON_AddBoolToObject(values,i2s_args.mute_level->hdr.longopts,i2s_conf->mute_level>0); - } - if(strlen(i2s_conf->model)>0){ - cJSON_AddStringToObject(values,i2s_args.model_name->hdr.longopts,i2s_conf->model); - } - else { - cJSON_AddStringToObject(values,i2s_args.model_name->hdr.longopts,"I2S"); - } +// const i2s_platform_config_t * i2s_conf= config_dac_get( ); +// #if defined(CONFIG_WITH_METRICS) +// metrics_add_feature("i2s",i2s_conf->pin.data_out_num>=0); +// #endif +// if(i2s_conf->pin.bck_io_num>0 ) { +// cJSON_AddNumberToObject(values,i2s_args.clock->hdr.longopts,i2s_conf->pin.bck_io_num); +// } +// if(i2s_conf->pin.ws_io_num>=0 ) { +// cJSON_AddNumberToObject(values,i2s_args.wordselect->hdr.longopts,i2s_conf->pin.ws_io_num); +// } +// if(i2s_conf->pin.data_out_num>=0 ) { +// cJSON_AddNumberToObject(values,i2s_args.data->hdr.longopts,i2s_conf->pin.data_out_num); +// } +// if(i2s_conf->sda>=0 ) { +// cJSON_AddNumberToObject(values,i2s_args.dac_sda->hdr.longopts,i2s_conf->sda); +// } +// if(i2s_conf->scl>=0 ) { +// cJSON_AddNumberToObject(values,i2s_args.dac_scl->hdr.longopts,i2s_conf->scl); +// } +// if(i2s_conf->i2c_addr>=0 ) { +// cJSON_AddNumberToObject(values,i2s_args.dac_i2c->hdr.longopts,i2s_conf->i2c_addr); +// } +// if(i2s_conf->mute_gpio>=0 ) { +// cJSON_AddNumberToObject(values,i2s_args.mute_gpio->hdr.longopts,i2s_conf->mute_gpio); +// } +// if(i2s_conf->mute_level>=0 ) { +// cJSON_AddBoolToObject(values,i2s_args.mute_level->hdr.longopts,i2s_conf->mute_level>0); +// } +// if(strlen(i2s_conf->model)>0){ +// cJSON_AddStringToObject(values,i2s_args.model_name->hdr.longopts,i2s_conf->model); +// } +// else { +// cJSON_AddStringToObject(values,i2s_args.model_name->hdr.longopts,"I2S"); +// } - return values; -} -cJSON * spdif_cb(){ - cJSON * values = cJSON_CreateObject(); - const i2s_platform_config_t * spdif_conf= config_spdif_get( ); - if(spdif_conf->pin.data_out_num>=0) { -#if defined(CONFIG_WITH_METRICS) - metrics_add_feature("spdif","enabled"); -#endif - } - if(spdif_conf->pin.bck_io_num>0 ) { - cJSON_AddNumberToObject(values,"clock",spdif_conf->pin.bck_io_num); - } - if(spdif_conf->pin.ws_io_num>=0 ) { - cJSON_AddNumberToObject(values,"wordselect",spdif_conf->pin.ws_io_num); - } - if(spdif_conf->pin.data_out_num>=0 ) { - cJSON_AddNumberToObject(values,"data",spdif_conf->pin.data_out_num); - } +// return values; +// } +// cJSON * spdif_cb(){ +// cJSON * values = cJSON_CreateObject(); +// const i2s_platform_config_t * spdif_conf= config_spdif_get( ); +// if(spdif_conf->pin.data_out_num>=0) { +// #if defined(CONFIG_WITH_METRICS) +// metrics_add_feature("spdif","enabled"); +// #endif +// } +// if(spdif_conf->pin.bck_io_num>0 ) { +// cJSON_AddNumberToObject(values,"clock",spdif_conf->pin.bck_io_num); +// } +// if(spdif_conf->pin.ws_io_num>=0 ) { +// cJSON_AddNumberToObject(values,"wordselect",spdif_conf->pin.ws_io_num); +// } +// if(spdif_conf->pin.data_out_num>=0 ) { +// cJSON_AddNumberToObject(values,"data",spdif_conf->pin.data_out_num); +// } - return values; -} -cJSON * rotary_cb(){ - cJSON * values = cJSON_CreateObject(); - char *p = config_alloc_get_default(NVS_TYPE_STR, "lms_ctrls_raw", "n", 0); - bool raw_mode = p && (*p == '1' || *p == 'Y' || *p == 'y'); - free(p); - const rotary_struct_t *rotary= config_rotary_get(); -#if defined(CONFIG_WITH_METRICS) - metrics_add_feature("rotary",GPIO_IS_VALID_GPIO(rotary->A )); -#endif - if(GPIO_IS_VALID_GPIO(rotary->A ) && rotary->A>=0 && GPIO_IS_VALID_GPIO(rotary->B) && rotary->B>=0){ - cJSON_AddNumberToObject(values,rotary_args.A->hdr.longopts,rotary->A); - cJSON_AddNumberToObject(values,rotary_args.B->hdr.longopts,rotary->B); - if(GPIO_IS_VALID_GPIO(rotary->SW ) && rotary->SW>=0 ){ - cJSON_AddNumberToObject(values,rotary_args.SW->hdr.longopts,rotary->SW); - } - cJSON_AddBoolToObject(values,rotary_args.volume_lock->hdr.longopts,rotary->volume_lock); - cJSON_AddBoolToObject(values,rotary_args.longpress->hdr.longopts,rotary->longpress); - cJSON_AddBoolToObject(values,rotary_args.knobonly->hdr.longopts,rotary->knobonly); - cJSON_AddNumberToObject(values,rotary_args.timer->hdr.longopts,rotary->timer); - cJSON_AddNumberToObject(values,rotary_args.raw_mode->hdr.longopts,raw_mode); - } - return values; -} +// return values; +// } +// cJSON * rotary_cb(){ +// cJSON * values = cJSON_CreateObject(); + // char *p = config_alloc_get_default(NVS_TYPE_STR, "lms_ctrls_raw", "n", 0); + // bool raw_mode = p && (*p == '1' || *p == 'Y' || *p == 'y'); + // free(p); +// const rotary_struct_t *rotary= config_rotary_get(); +// #if defined(CONFIG_WITH_METRICS) +// metrics_add_feature("rotary",GPIO_IS_VALID_GPIO(rotary->A )); +// #endif +// if(GPIO_IS_VALID_GPIO(rotary->A ) && rotary->A>=0 && GPIO_IS_VALID_GPIO(rotary->B) && rotary->B>=0){ +// cJSON_AddNumberToObject(values,rotary_args.A->hdr.longopts,rotary->A); +// cJSON_AddNumberToObject(values,rotary_args.B->hdr.longopts,rotary->B); +// if(GPIO_IS_VALID_GPIO(rotary->SW ) && rotary->SW>=0 ){ +// cJSON_AddNumberToObject(values,rotary_args.SW->hdr.longopts,rotary->SW); +// } +// cJSON_AddBoolToObject(values,rotary_args.volume_lock->hdr.longopts,rotary->volume_lock); +// cJSON_AddBoolToObject(values,rotary_args.longpress->hdr.longopts,rotary->longpress); +// cJSON_AddBoolToObject(values,rotary_args.knobonly->hdr.longopts,rotary->knobonly); +// cJSON_AddNumberToObject(values,rotary_args.timer->hdr.longopts,rotary->timer); +// cJSON_AddNumberToObject(values,rotary_args.raw_mode->hdr.longopts,raw_mode); +// } + // TODO: Add support for the commented code +// return values; +// } -cJSON * ledvu_cb(){ - cJSON * values = cJSON_CreateObject(); - const ledvu_struct_t *ledvu= config_ledvu_get(); - if(GPIO_IS_VALID_GPIO(ledvu->gpio )){ -#if defined(CONFIG_WITH_METRICS) - metrics_add_feature("led_vu","enabled"); -#endif - } - if(GPIO_IS_VALID_GPIO(ledvu->gpio) && ledvu->gpio>=0 && ledvu->length > 0){ - cJSON_AddNumberToObject(values,"gpio",ledvu->gpio); - cJSON_AddNumberToObject(values,"length",ledvu->length); - } - if(strlen(ledvu->type)>0){ - cJSON_AddStringToObject(values,"type",ledvu->type); - } - else { - cJSON_AddStringToObject(values,"type","WS2812"); - } - return values; -} +// cJSON * ledvu_cb(){ +// cJSON * values = cJSON_CreateObject(); +// const ledvu_struct_t *ledvu= config_ledvu_get(); +// if(GPIO_IS_VALID_GPIO(ledvu->gpio )){ +// #if defined(CONFIG_WITH_METRICS) +// metrics_add_feature("led_vu","enabled"); +// #endif +// } +// if(GPIO_IS_VALID_GPIO(ledvu->gpio) && ledvu->gpio>=0 && ledvu->length > 0){ +// cJSON_AddNumberToObject(values,"gpio",ledvu->gpio); +// cJSON_AddNumberToObject(values,"length",ledvu->length); +// } +// if(strlen(ledvu->type)>0){ +// cJSON_AddStringToObject(values,"type",ledvu->type); +// } +// else { +// cJSON_AddStringToObject(values,"type","WS2812"); +// } +// return values; +// } cJSON * audio_cb(){ cJSON * values = cJSON_CreateObject(); - char * p = config_alloc_get_default(NVS_TYPE_STR, "jack_mutes_amp", "n", 0); - cJSON_AddStringToObject(values,"jack_behavior",(strcmp(p,"1") == 0 ||strcasecmp(p,"y") == 0)?"Headphones":"Subwoofer"); -#if defined(CONFIG_WITH_METRICS) - metrics_add_feature("jack_mute",atoi(p)>=0); -#endif - FREE_AND_NULL(p); - p = config_alloc_get_default(NVS_TYPE_STR, "loudness", "0", 0); -#if defined(CONFIG_WITH_METRICS) - metrics_add_feature("loudness",atoi(p)>=0); -#endif - cJSON_AddStringToObject(values,"loudness",p); - FREE_AND_NULL(p); +// char * p = config_alloc_get_default(NVS_TYPE_STR, "jack_mutes_amp", "n", 0); +// cJSON_AddStringToObject(values,"jack_behavior",(strcmp(p,"1") == 0 ||strcasecmp(p,"y") == 0)?"Headphones":"Subwoofer"); +// #if defined(CONFIG_WITH_METRICS) +// metrics_add_feature("jack_mute",atoi(p)>=0); +// #endif +// FREE_AND_NULL(p); +// p = config_alloc_get_default(NVS_TYPE_STR, "loudness", "0", 0); +// #if defined(CONFIG_WITH_METRICS) +// metrics_add_feature("loudness",atoi(p)>=0); +// #endif +// cJSON_AddStringToObject(values,"loudness",p); +// FREE_AND_NULL(p); + // TODO: Add support for the commented code return values; } cJSON * bt_source_cb(){ cJSON * values = cJSON_CreateObject(); - char * p = config_alloc_get_default(NVS_TYPE_STR, "a2dp_sink_name", NULL, 0); - if(p){ - cJSON_AddStringToObject(values,"sink_name",p); -#if defined(CONFIG_WITH_METRICS) - metrics_add_feature("btsource",strlen(p)>0); -#endif - } - FREE_AND_NULL(p); - // p = config_alloc_get_default(NVS_TYPE_STR, "a2dp_ctmt", NULL, 0); - // if(p){ - // cJSON_AddNumberToObject(values,"connect_timeout_delay",((double)atoi(p)/1000.0)); - // } - // FREE_AND_NULL(p); - p = config_alloc_get_default(NVS_TYPE_STR, "a2dp_spin", "0000", 0); - if(p){ - cJSON_AddStringToObject(values,"pin_code",p); - } - FREE_AND_NULL(p); - // p = config_alloc_get_default(NVS_TYPE_STR, "a2dp_ctrld", NULL, 0); - // if(p){ - // cJSON_AddNumberToObject(values,"control_delay",((double)atoi(p)/1000.0)); - // } - // FREE_AND_NULL(p); + // TODO: Add support for the commented code +// char * p = config_alloc_get_default(NVS_TYPE_STR, "a2dp_sink_name", NULL, 0); +// if(p){ +// cJSON_AddStringToObject(values,"sink_name",p); +// #if defined(CONFIG_WITH_METRICS) +// metrics_add_feature("btsource",strlen(p)>0); +// #endif +// } +// FREE_AND_NULL(p); + +// p = config_alloc_get_default(NVS_TYPE_STR, "a2dp_spin", "0000", 0); +// if(p){ +// cJSON_AddStringToObject(values,"pin_code",p); +// } +// FREE_AND_NULL(p); + return values; } @@ -1058,69 +1082,70 @@ static int do_squeezelite_cmd(int argc, char **argv) cJSON * squeezelite_cb(){ cJSON * values = cJSON_CreateObject(); - char * nvs_config= config_alloc_get(NVS_TYPE_STR, "autoexec1"); - char **argv = NULL; - char *buf = NULL; - size_t buf_size = 0; - int nerrors=1; - FILE *f = system_open_memstream(argv[0],&buf, &buf_size); - if (f == NULL) { - return values; - } +// char * nvs_config= config_alloc_get(NVS_TYPE_STR, "autoexec1"); +// char **argv = NULL; +// char *buf = NULL; +// size_t buf_size = 0; +// int nerrors=1; +// FILE *f = system_open_memstream(argv[0],&buf, &buf_size); +// if (f == NULL) { +// return values; +// } - if(nvs_config && strlen(nvs_config)>0){ - ESP_LOGD(TAG,"Parsing command %s",nvs_config); - argv = (char **) calloc(22, sizeof(char *)); - if (argv == NULL) { - FREE_AND_NULL(nvs_config); - fclose(f); - return values; - } - size_t argc = esp_console_split_argv(nvs_config, argv,22); - if (argc != 0) { - nerrors = arg_parse(argc, argv,(void **)&squeezelite_args); - ESP_LOGD(TAG,"Parsing completed"); - } - } - if (nerrors == 0) { - get_str_parm_json(squeezelite_args.buffers, values); - get_str_parm_json(squeezelite_args.codecs, values); - get_lit_parm_json(squeezelite_args.header_format, values); - get_str_parm_json(squeezelite_args.log_level, values); +// if(nvs_config && strlen(nvs_config)>0){ +// ESP_LOGD(TAG,"Parsing command %s",nvs_config); +// argv = (char **) calloc(22, sizeof(char *)); +// if (argv == NULL) { +// FREE_AND_NULL(nvs_config); +// fclose(f); +// return values; +// } +// size_t argc = esp_console_split_argv(nvs_config, argv,22); +// if (argc != 0) { +// nerrors = arg_parse(argc, argv,(void **)&squeezelite_args); +// ESP_LOGD(TAG,"Parsing completed"); +// } +// } +// if (nerrors == 0) { +// get_str_parm_json(squeezelite_args.buffers, values); +// get_str_parm_json(squeezelite_args.codecs, values); +// get_lit_parm_json(squeezelite_args.header_format, values); +// get_str_parm_json(squeezelite_args.log_level, values); - // get_str_parm_json(squeezelite_args.log_level_all, values); - // get_str_parm_json(squeezelite_args.log_level_decode, values); - // get_str_parm_json(squeezelite_args.log_level_output, values); - // get_str_parm_json(squeezelite_args.log_level_slimproto, values); - // get_str_parm_json(squeezelite_args.log_level_stream, values); - get_str_parm_json(squeezelite_args.mac_addr, values); - get_str_parm_json(squeezelite_args.output_device, values); -#if defined(CONFIG_WITH_METRICS) - if(squeezelite_args.output_device->sval[0]!=NULL && strlen(squeezelite_args.output_device->sval[0])>0){ - metrics_add_feature_variant("output",squeezelite_args.output_device->sval[0]); - } -#endif - get_str_parm_json(squeezelite_args.model_name, values); - get_str_parm_json(squeezelite_args.name, values); - get_int_parm_json(squeezelite_args.rate, values); - get_str_parm_json(squeezelite_args.rates, values); - get_str_parm_json(squeezelite_args.server, values); - get_int_parm_json(squeezelite_args.timeout, values); - char * p = cJSON_Print(values); - ESP_LOGD(TAG,"%s",p); - free(p); - } - else { - arg_print_errors(f, squeezelite_args.end, desc_squeezelite); - } - fflush (f); - if(strlen(buf)>0){ - log_send_messaging(nerrors?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); - } - fclose(f); - FREE_AND_NULL(buf); - FREE_AND_NULL(nvs_config); - FREE_AND_NULL(argv); +// // get_str_parm_json(squeezelite_args.log_level_all, values); +// // get_str_parm_json(squeezelite_args.log_level_decode, values); +// // get_str_parm_json(squeezelite_args.log_level_output, values); +// // get_str_parm_json(squeezelite_args.log_level_slimproto, values); +// // get_str_parm_json(squeezelite_args.log_level_stream, values); +// get_str_parm_json(squeezelite_args.mac_addr, values); +// get_str_parm_json(squeezelite_args.output_device, values); +// #if defined(CONFIG_WITH_METRICS) +// if(squeezelite_args.output_device->sval[0]!=NULL && strlen(squeezelite_args.output_device->sval[0])>0){ +// metrics_add_feature_variant("output",squeezelite_args.output_device->sval[0]); +// } +// #endif +// get_str_parm_json(squeezelite_args.model_name, values); +// get_str_parm_json(squeezelite_args.name, values); +// get_int_parm_json(squeezelite_args.rate, values); +// get_str_parm_json(squeezelite_args.rates, values); +// get_str_parm_json(squeezelite_args.server, values); +// get_int_parm_json(squeezelite_args.timeout, values); +// char * p = cJSON_Print(values); +// ESP_LOGD(TAG,"%s",p); +// free(p); +// } +// else { +// arg_print_errors(f, squeezelite_args.end, desc_squeezelite); +// } +// fflush (f); +// if(strlen(buf)>0){ +// log_send_messaging(nerrors?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); +// } +// fclose(f); +// FREE_AND_NULL(buf); +// FREE_AND_NULL(nvs_config); +// FREE_AND_NULL(argv); +// TODO: Add support for the commented code return values; } static char * get_log_level_options(const char * longname){ @@ -1134,35 +1159,35 @@ static char * get_log_level_options(const char * longname){ return options; } -// loop through dac_set and concatenate model name separated with | -static char * get_dac_list(){ - const char * EXTRA_MODEL_NAMES = "ES8388|I2S"; - char * dac_list=NULL; - size_t total_len=0; - for(int i=0;dac_set[i];i++){ - if(dac_set[i]->model && strlen(dac_set[i]->model)>0){ - total_len+=strlen(dac_set[i]->model)+1; - } - else { - break; - } - } - total_len+=strlen(EXTRA_MODEL_NAMES); - dac_list = malloc_init_external(total_len+1); - if(dac_list){ - for(int i=0;dac_set[i];i++){ - if(dac_set[i]->model && strlen(dac_set[i]->model)>0){ - strcat(dac_list,dac_set[i]->model); - strcat(dac_list,"|"); - } - else { - break; - } - } - strcat(dac_list,EXTRA_MODEL_NAMES); - } - return dac_list; -} +// // loop through dac_set and concatenate model name separated with | +// static char * get_dac_list(){ +// const char * EXTRA_MODEL_NAMES = "ES8388|I2S"; +// char * dac_list=NULL; +// size_t total_len=0; +// for(int i=0;dac_set[i];i++){ +// if(dac_set[i]->model && strlen(dac_set[i]->model)>0){ +// total_len+=strlen(dac_set[i]->model)+1; +// } +// else { +// break; +// } +// } +// total_len+=strlen(EXTRA_MODEL_NAMES); +// dac_list = malloc_init_external(total_len+1); +// if(dac_list){ +// for(int i=0;dac_set[i];i++){ +// if(dac_set[i]->model && strlen(dac_set[i]->model)>0){ +// strcat(dac_list,dac_set[i]->model); +// strcat(dac_list,"|"); +// } +// else { +// break; +// } +// } +// strcat(dac_list,EXTRA_MODEL_NAMES); +// } +// return dac_list; +// } void replace_char_in_string(char * str, char find, char replace){ for(int i=0;str[i];i++){ if(str[i]==find){ @@ -1198,7 +1223,8 @@ static esp_err_t save_known_config(cJSON * known_item, const char * name,FILE * } fprintf(f,"Storing %s=%s\n",key,value); - err = config_set_value(NVS_TYPE_STR,key,value); + // err = config_set_value(NVS_TYPE_STR,key,value); + // TODO: Add support for the commented code if(err){ fprintf(f,"Failed to store config value: %s\n",esp_err_to_name(err)); break; @@ -1216,7 +1242,8 @@ static esp_err_t save_known_config(cJSON * known_item, const char * name,FILE * if(err==ESP_OK){ - err = config_set_value(NVS_TYPE_STR,"board_model",name); + // err = config_set_value(NVS_TYPE_STR,"board_model",name); + // TODO: Add support for the commented code if(err!=ESP_OK){ fprintf(f,"Failed to save board model %s\n",name); } @@ -1225,133 +1252,133 @@ static esp_err_t save_known_config(cJSON * known_item, const char * name,FILE * return err; } -static int do_register_known_templates_config(int argc, char **argv){ - esp_err_t err=ESP_OK; - int nerrors = arg_parse(argc, argv,(void **)&known_model_args); - char *buf = NULL; - size_t buf_size = 0; - cJSON * config_name =NULL; - FILE *f = system_open_memstream(argv[0],&buf, &buf_size); - if (f == NULL) { - return 1; - } - if(nerrors >0){ - arg_print_errors(f,known_model_args.end,desc_preset); - } - else { - ESP_LOGD(TAG,"arg: %s",STR_OR_BLANK(known_model_args.model_config->sval[0])); - char * model_config = strdup_psram(known_model_args.model_config->sval[0]); - char * t = model_config; - for(const char * p=known_model_args.model_config->sval[0];*p;p++){ - if(*p=='\\' && *(p+1)=='"'){ - *t++='"'; - p++; - } - else { - *t++=*p; - } - } - *t=0; - cJSON * known_item = cJSON_Parse(model_config); - if(known_item){ - ESP_LOGD(TAG,"Parsing success"); - config_name= cJSON_GetObjectItem(known_item,"name"); - if(!config_name || !cJSON_IsString(config_name) || strlen(config_name->valuestring)==0){ - fprintf(f,"Failed to find name in config\n"); - err=ESP_FAIL; - nerrors++; - } - if(nerrors==0){ - const char * name = cJSON_GetStringValue(config_name); - nerrors+=(err = save_known_config(known_item,name,f)!=ESP_OK); - if(nerrors==0){ - const i2s_platform_config_t * i2s_config= config_dac_get(); - if(i2s_config->scl!=-1 && i2s_config->sda!=-1 && GPIO_IS_VALID_GPIO(i2s_config->scl) && GPIO_IS_VALID_GPIO(i2s_config->sda)){ - fprintf(f,"Scanning i2c bus for devices\n"); - cmd_i2ctools_scan_bus(f,i2s_config->sda, i2s_config->scl); - } - } - } - cJSON_Delete(known_item); - } - else { - ESP_LOGE(TAG,"Parsing error: %s",cJSON_GetErrorPtr()); - fprintf(f,"Failed to parse JSON: %s\n",cJSON_GetErrorPtr()); - err=ESP_FAIL; - } - if(err!=ESP_OK){ - nerrors++; - fprintf(f,"Error registering known config %s.\n",known_model_args.model_config->sval[0]); - } - else { - fprintf(f,"Registered known config %s.\n",known_model_args.model_config->sval[0]); - } - } +// static int do_register_known_templates_config(int argc, char **argv){ +// esp_err_t err=ESP_OK; +// int nerrors = arg_parse(argc, argv,(void **)&known_model_args); +// char *buf = NULL; +// size_t buf_size = 0; +// cJSON * config_name =NULL; +// FILE *f = system_open_memstream(argv[0],&buf, &buf_size); +// if (f == NULL) { +// return 1; +// } +// if(nerrors >0){ +// arg_print_errors(f,known_model_args.end,desc_preset); +// } +// else { +// ESP_LOGD(TAG,"arg: %s",STR_OR_BLANK(known_model_args.model_config->sval[0])); +// char * model_config = strdup_psram(known_model_args.model_config->sval[0]); +// char * t = model_config; +// for(const char * p=known_model_args.model_config->sval[0];*p;p++){ +// if(*p=='\\' && *(p+1)=='"'){ +// *t++='"'; +// p++; +// } +// else { +// *t++=*p; +// } +// } +// *t=0; +// cJSON * known_item = cJSON_Parse(model_config); +// if(known_item){ +// ESP_LOGD(TAG,"Parsing success"); +// config_name= cJSON_GetObjectItem(known_item,"name"); +// if(!config_name || !cJSON_IsString(config_name) || strlen(config_name->valuestring)==0){ +// fprintf(f,"Failed to find name in config\n"); +// err=ESP_FAIL; +// nerrors++; +// } +// if(nerrors==0){ +// const char * name = cJSON_GetStringValue(config_name); +// nerrors+=(err = save_known_config(known_item,name,f)!=ESP_OK); +// if(nerrors==0){ +// const i2s_platform_config_t * i2s_config= config_dac_get(); +// if(i2s_config->scl!=-1 && i2s_config->sda!=-1 && GPIO_IS_VALID_GPIO(i2s_config->scl) && GPIO_IS_VALID_GPIO(i2s_config->sda)){ +// fprintf(f,"Scanning i2c bus for devices\n"); +// cmd_i2ctools_scan_bus(f,i2s_config->sda, i2s_config->scl); +// } +// } +// } +// cJSON_Delete(known_item); +// } +// else { +// ESP_LOGE(TAG,"Parsing error: %s",cJSON_GetErrorPtr()); +// fprintf(f,"Failed to parse JSON: %s\n",cJSON_GetErrorPtr()); +// err=ESP_FAIL; +// } +// if(err!=ESP_OK){ +// nerrors++; +// fprintf(f,"Error registering known config %s.\n",known_model_args.model_config->sval[0]); +// } +// else { +// fprintf(f,"Registered known config %s.\n",known_model_args.model_config->sval[0]); +// } +// } - if(!nerrors ){ - fprintf(f,"Done.\n"); - } - fflush (f); - cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); - fclose(f); - FREE_AND_NULL(buf); - return (nerrors==0 && err==ESP_OK)?0:1; -} -static void register_known_templates_config(){ +// if(!nerrors ){ +// fprintf(f,"Done.\n"); +// } +// fflush (f); +// cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); +// fclose(f); +// FREE_AND_NULL(buf); +// return (nerrors==0 && err==ESP_OK)?0:1; +// } +// static void register_known_templates_config(){ - known_model_args.model_config = arg_str1(NULL,"model_config","SqueezeAMP|T-WATCH2020 by LilyGo","Known Board Name.\nFor known boards, several systems parameters will be updated"); - known_model_args.end = arg_end(1); - const esp_console_cmd_t cmd = { - .command = CFG_TYPE_HW("preset"), - .help = desc_preset, - .hint = NULL, - .func = &do_register_known_templates_config, - .argtable = &known_model_args - }; - cmd_to_json_with_cb(&cmd,&known_model_cb); - ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); -} -#ifdef CONFIG_CSPOT_SINK -static void register_cspot_config(){ - cspot_args.deviceName = arg_str1(NULL,"deviceName","","Device Name"); - cspot_args.bitrate = arg_int1(NULL,"bitrate","96|160|320","Streaming Bitrate (kbps)"); - cspot_args.zeroConf = arg_int1(NULL,"zeroConf","0|1","Force use of ZeroConf"); -// cspot_args.volume = arg_int1(NULL,"volume","","Spotify Volume"); - cspot_args.end = arg_end(1); - const esp_console_cmd_t cmd = { - .command = CFG_TYPE_SYST("cspot"), - .help = desc_cspotc, - .hint = NULL, - .func = &do_cspot_config, - .argtable = &cspot_args - }; - cmd_to_json_with_cb(&cmd,&cspot_cb); - ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); -} -#endif -static void register_i2s_config(void){ - i2s_args.model_name = arg_str0(NULL,"model_name",STR_OR_BLANK(get_dac_list()),"DAC Model Name"); - i2s_args.clear = arg_lit0(NULL, "clear", "Clear configuration"); - i2s_args.clock = arg_int0(NULL,"clock","","Clock GPIO. e.g. 33"); - i2s_args.wordselect = arg_int0(NULL,"wordselect","","Word Select GPIO. e.g. 25"); - i2s_args.data = arg_int0(NULL,"data","","Data GPIO. e.g. 32"); - i2s_args.mute_gpio = arg_int0(NULL,"mute_gpio", "", "Mute GPIO. e.g. 14"); - i2s_args.mute_level = arg_lit0(NULL,"mute_level","Mute GPIO level. Checked=HIGH, Unchecked=LOW"); - i2s_args.dac_sda = arg_int0(NULL,"dac_sda", "", "SDA GPIO. e.g. 27"); - i2s_args.dac_scl = arg_int0(NULL,"dac_scl", "", "SCL GPIO. e.g. 26"); - i2s_args.dac_i2c = arg_int0(NULL,"dac_i2c", "", "I2C device address. e.g. 106"); - i2s_args.end = arg_end(6); +// known_model_args.model_config = arg_str1(NULL,"model_config","SqueezeAMP|T-WATCH2020 by LilyGo","Known Board Name.\nFor known boards, several systems parameters will be updated"); +// known_model_args.end = arg_end(1); +// const esp_console_cmd_t cmd = { +// .command = CFG_TYPE_HW("preset"), +// .help = desc_preset, +// .hint = NULL, +// .func = &do_register_known_templates_config, +// .argtable = &known_model_args +// }; +// cmd_to_json_with_cb(&cmd,&known_model_cb); +// ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +// } +// #ifdef CONFIG_CSPOT_SINK +// static void register_cspot_config(){ +// cspot_args.deviceName = arg_str1(NULL,"deviceName","","Device Name"); +// cspot_args.bitrate = arg_int1(NULL,"bitrate","96|160|320","Streaming Bitrate (kbps)"); +// cspot_args.zeroConf = arg_int1(NULL,"zeroConf","0|1","Force use of ZeroConf"); +// // cspot_args.volume = arg_int1(NULL,"volume","","Spotify Volume"); +// cspot_args.end = arg_end(1); +// const esp_console_cmd_t cmd = { +// .command = CFG_TYPE_SYST("cspot"), +// .help = desc_cspotc, +// .hint = NULL, +// .func = &do_cspot_config, +// .argtable = &cspot_args +// }; +// cmd_to_json_with_cb(&cmd,&cspot_cb); +// ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +// } +// #endif +// static void register_i2s_config(void){ +// i2s_args.model_name = arg_str0(NULL,"model_name",STR_OR_BLANK(get_dac_list()),"DAC Model Name"); +// i2s_args.clear = arg_lit0(NULL, "clear", "Clear configuration"); +// i2s_args.clock = arg_int0(NULL,"clock","","Clock GPIO. e.g. 33"); +// i2s_args.wordselect = arg_int0(NULL,"wordselect","","Word Select GPIO. e.g. 25"); +// i2s_args.data = arg_int0(NULL,"data","","Data GPIO. e.g. 32"); +// i2s_args.mute_gpio = arg_int0(NULL,"mute_gpio", "", "Mute GPIO. e.g. 14"); +// i2s_args.mute_level = arg_lit0(NULL,"mute_level","Mute GPIO level. Checked=HIGH, Unchecked=LOW"); +// i2s_args.dac_sda = arg_int0(NULL,"dac_sda", "", "SDA GPIO. e.g. 27"); +// i2s_args.dac_scl = arg_int0(NULL,"dac_scl", "", "SCL GPIO. e.g. 26"); +// i2s_args.dac_i2c = arg_int0(NULL,"dac_i2c", "", "I2C device address. e.g. 106"); +// i2s_args.end = arg_end(6); - const esp_console_cmd_t cmd = { - .command = CFG_TYPE_HW("dac"), - .help = desc_dac, - .hint = NULL, - .func = &do_i2s_cmd, - .argtable = &i2s_args - }; - cmd_to_json_with_cb(&cmd,&i2s_cb); - ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); -} +// const esp_console_cmd_t cmd = { +// .command = CFG_TYPE_HW("dac"), +// .help = desc_dac, +// .hint = NULL, +// .func = &do_i2s_cmd, +// .argtable = &i2s_args +// }; +// cmd_to_json_with_cb(&cmd,&i2s_cb); +// ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +// } static void register_bt_source_config(void){ @@ -1371,46 +1398,46 @@ static void register_bt_source_config(void){ ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); } -void register_rotary_config(void){ - rotary_args.rem = arg_rem("remark","One rotary encoder is supported, quadrature shift with press. Such encoders usually have 2 pins for encoders (A and B), and common C that must be set to ground and an optional SW pin for press. A, B and SW must be pulled up, so automatic pull-up is provided by ESP32, but you can add your own resistors. A bit of filtering on A and B (~470nF) helps for debouncing which is not made by software.\r\nEncoder is normally hard-coded to respectively knob left, right and push on LMS and to volume down/up/play toggle on BT and AirPlay."); - rotary_args.A = arg_int1(NULL,"A","gpio","A/DT gpio"); - rotary_args.B = arg_int1(NULL,"B","gpio","B/CLK gpio"); - rotary_args.SW = arg_int0(NULL,"SW","gpio","Switch gpio"); - rotary_args.knobonly = arg_lit0(NULL,"knobonly","Single knob full navigation. Left, Right and Press is navigation, with Press always going to lower submenu item. Longpress is 'Play', Double press is 'Back', a quick left-right movement on the encoder is 'Pause'"); - rotary_args.timer = arg_int0(NULL,"timer","ms","The speed of double click (or left-right) when knob only option is enabled. Be aware that the longer you set double click speed, the less responsive the interface will be. "); - rotary_args.volume_lock = arg_lit0(NULL,"volume_lock", "Force Volume down/up/play toggle all the time (even in LMS). "); - rotary_args.longpress = arg_lit0(NULL,"longpress","Enable alternate mode mode on long-press. In that mode, left is previous, right is next and press is toggle. Every long press on SW alternates between modes (the main mode actual behavior depends on 'volume')."); - rotary_args.clear = arg_lit0(NULL, "clear", "Clear configuration"); - rotary_args.raw_mode = arg_lit0(NULL, "raw_mode", "Send button events as raw values to LMS. No remapping is possible when this is enabled"); - rotary_args.end = arg_end(3); - const esp_console_cmd_t cmd = { - .command = CFG_TYPE_HW("rotary"), - .help = desc_rotary, - .hint = NULL, - .func = &do_rotary_cmd, - .argtable = &rotary_args - }; - cmd_to_json_with_cb(&cmd,&rotary_cb); - ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); -} +// void register_rotary_config(void){ +// rotary_args.rem = arg_rem("remark","One rotary encoder is supported, quadrature shift with press. Such encoders usually have 2 pins for encoders (A and B), and common C that must be set to ground and an optional SW pin for press. A, B and SW must be pulled up, so automatic pull-up is provided by ESP32, but you can add your own resistors. A bit of filtering on A and B (~470nF) helps for debouncing which is not made by software.\r\nEncoder is normally hard-coded to respectively knob left, right and push on LMS and to volume down/up/play toggle on BT and AirPlay."); +// rotary_args.A = arg_int1(NULL,"A","gpio","A/DT gpio"); +// rotary_args.B = arg_int1(NULL,"B","gpio","B/CLK gpio"); +// rotary_args.SW = arg_int0(NULL,"SW","gpio","Switch gpio"); +// rotary_args.knobonly = arg_lit0(NULL,"knobonly","Single knob full navigation. Left, Right and Press is navigation, with Press always going to lower submenu item. Longpress is 'Play', Double press is 'Back', a quick left-right movement on the encoder is 'Pause'"); +// rotary_args.timer = arg_int0(NULL,"timer","ms","The speed of double click (or left-right) when knob only option is enabled. Be aware that the longer you set double click speed, the less responsive the interface will be. "); +// rotary_args.volume_lock = arg_lit0(NULL,"volume_lock", "Force Volume down/up/play toggle all the time (even in LMS). "); +// rotary_args.longpress = arg_lit0(NULL,"longpress","Enable alternate mode mode on long-press. In that mode, left is previous, right is next and press is toggle. Every long press on SW alternates between modes (the main mode actual behavior depends on 'volume')."); +// rotary_args.clear = arg_lit0(NULL, "clear", "Clear configuration"); +// rotary_args.raw_mode = arg_lit0(NULL, "raw_mode", "Send button events as raw values to LMS. No remapping is possible when this is enabled"); +// rotary_args.end = arg_end(3); +// const esp_console_cmd_t cmd = { +// .command = CFG_TYPE_HW("rotary"), +// .help = desc_rotary, +// .hint = NULL, +// .func = &do_rotary_cmd, +// .argtable = &rotary_args +// }; +// cmd_to_json_with_cb(&cmd,&rotary_cb); +// ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +// } -void register_ledvu_config(void){ - ledvu_args.type = arg_str1(NULL,"type","|WS2812","Led type (supports one rgb strip to display built in effects and allow remote control through 'dmx' messaging)"); - ledvu_args.length = arg_int1(NULL,"length","<1..255>","Strip length (1-255 supported)"); - ledvu_args.gpio = arg_int1(NULL,"gpio","gpio","Data pin"); - ledvu_args.clear = arg_lit0(NULL, "clear", "Clear configuration"); - ledvu_args.end = arg_end(4); +// void register_ledvu_config(void){ +// ledvu_args.type = arg_str1(NULL,"type","|WS2812","Led type (supports one rgb strip to display built in effects and allow remote control through 'dmx' messaging)"); +// ledvu_args.length = arg_int1(NULL,"length","<1..255>","Strip length (1-255 supported)"); +// ledvu_args.gpio = arg_int1(NULL,"gpio","gpio","Data pin"); +// ledvu_args.clear = arg_lit0(NULL, "clear", "Clear configuration"); +// ledvu_args.end = arg_end(4); - const esp_console_cmd_t cmd = { - .command = CFG_TYPE_HW("ledvu"), - .help = desc_ledvu, - .hint = NULL, - .func = &do_ledvu_cmd, - .argtable = &ledvu_args - }; - cmd_to_json_with_cb(&cmd,&ledvu_cb); - ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); -} +// const esp_console_cmd_t cmd = { +// .command = CFG_TYPE_HW("ledvu"), +// .help = desc_ledvu, +// .hint = NULL, +// .func = &do_ledvu_cmd, +// .argtable = &ledvu_args +// }; +// cmd_to_json_with_cb(&cmd,&ledvu_cb); +// ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +// } void register_audio_config(void){ audio_args.jack_behavior = arg_str0("j", "jack_behavior","Headphones|Subwoofer","On supported DAC, determines the audio jack behavior. Selecting headphones will cause the external amp to be muted on insert, while selecting Subwoofer will keep the amp active all the time."); @@ -1428,23 +1455,23 @@ void register_audio_config(void){ ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); } -static void register_spdif_config(void){ - spdif_args.clear = arg_lit0(NULL, "clear", "Clear configuration"); - spdif_args.clock = arg_int1(NULL,"clock","","Clock GPIO. e.g. 33"); - spdif_args.wordselect = arg_int1(NULL,"wordselect","","Word Select GPIO. e.g. 25"); - spdif_args.data = arg_int1(NULL,"data","","Data GPIO. e.g. 32"); - spdif_args.end = arg_end(6); +// static void register_spdif_config(void){ +// spdif_args.clear = arg_lit0(NULL, "clear", "Clear configuration"); +// spdif_args.clock = arg_int1(NULL,"clock","","Clock GPIO. e.g. 33"); +// spdif_args.wordselect = arg_int1(NULL,"wordselect","","Word Select GPIO. e.g. 25"); +// spdif_args.data = arg_int1(NULL,"data","","Data GPIO. e.g. 32"); +// spdif_args.end = arg_end(6); - const esp_console_cmd_t cmd = { - .command = CFG_TYPE_HW("spdif"), - .help = desc_spdif, - .hint = NULL, - .func = &do_spdif_cmd, - .argtable = &spdif_args - }; - cmd_to_json_with_cb(&cmd,&spdif_cb); - ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); -} +// const esp_console_cmd_t cmd = { +// .command = CFG_TYPE_HW("spdif"), +// .help = desc_spdif, +// .hint = NULL, +// .func = &do_spdif_cmd, +// .argtable = &spdif_args +// }; +// cmd_to_json_with_cb(&cmd,&spdif_cb); +// ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +// } static void register_squeezelite_config(void){ squeezelite_args.server = arg_str0("s","server","[:]","Connect to specified server, otherwise uses autodiscovery to find server"); squeezelite_args.buffers = arg_str0("b","buffers",":","Internal Stream and Output buffer sizes in Kbytes"); @@ -1483,21 +1510,37 @@ static void register_squeezelite_config(void){ .func = &do_squeezelite_cmd, .argtable = &squeezelite_args }; - cmd_to_json_with_cb(&cmd,&squeezelite_cb); - ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); + // cmd_to_json_with_cb(&cmd,&squeezelite_cb); + // ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); } void dummy_register_cmd(){ } -void register_config_cmd(void){ - if(!is_dac_config_locked()){ - register_known_templates_config(); - } +void register_wifi_connect(){ + wifi_ap_args.conn= arg_lit0(NULL,"join","Connect to an access point "); + wifi_ap_args.ap_name= arg_str0("w","wifi","string","Access Point to connect to "); + wifi_ap_args.password= arg_str0("p","pass","string","Password for the access point (if needed) "); + wifi_ap_args.end = arg_end(1); + const esp_console_cmd_t cmd = { + .command = CFG_TYPE_SYST("wifi"), + .help = desc_wifi, + .hint = NULL, + .func = &do_wifi_ops, + .argtable = &wifi_ap_args + }; + cmd_to_json_with_cb(&cmd,&squeezelite_cb); + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); -#ifdef CONFIG_CSPOT_SINK - register_cspot_config(); -#endif - register_bt_source_config(); +} +void register_config_cmd(void){ + // if(!is_dac_config_locked()){ + // register_known_templates_config(); + // } + +// #ifdef CONFIG_CSPOT_SINK +// register_cspot_config(); +// #endif + // register_bt_source_config(); #if CONFIG_WITH_CONFIG_UI if(!is_dac_config_locked()){ register_i2s_config(); @@ -1507,15 +1550,16 @@ void register_config_cmd(void){ metrics_add_feature("i2s",true); #endif } - if(!is_spdif_config_locked()){ - register_spdif_config(); - } - else { -#if defined(CONFIG_WITH_METRICS) - metrics_add_feature("spdif",true); -#endif - } +// if(!is_spdif_config_locked()){ +// register_spdif_config(); +// } +// else { +// #if defined(CONFIG_WITH_METRICS) +// metrics_add_feature("spdif",true); +// #endif +// } #endif register_optional_cmd(); + register_wifi_connect(); } diff --git a/components/platform_console/cmd_decl.h b/components/platform_console/cmd_decl.h index 1f591501..e35f2069 100644 --- a/components/platform_console/cmd_decl.h +++ b/components/platform_console/cmd_decl.h @@ -14,7 +14,6 @@ extern "C" { #include "cmd_system.h" #include "cmd_wifi.h" -#include "cmd_nvs.h" #include "cmd_i2ctools.h" #include "cmd_ota.h" #include "cmd_config.h" diff --git a/components/platform_console/cmd_i2ctools.c b/components/platform_console/cmd_i2ctools.c index 48d706fd..6daa258e 100644 --- a/components/platform_console/cmd_i2ctools.c +++ b/components/platform_console/cmd_i2ctools.c @@ -16,7 +16,8 @@ #include "driver/i2c.h" #include "esp_log.h" #include "messaging.h" -#include "platform_config.h" +// #include "Configurator.h" +#pragma message("fixme: look for TODO below") #include "platform_console.h" #include "stdio.h" #include "string.h" @@ -520,86 +521,87 @@ static int do_spiconfig_cmd(int argc, char** argv) { static int do_i2cconfig_cmd(int argc, char** argv) { esp_err_t err = ESP_OK; - i2c_config_t conf = {.mode = I2C_MODE_MASTER, - .sda_io_num = 19, - .sda_pullup_en = GPIO_PULLUP_ENABLE, - .scl_io_num = 18, - .scl_pullup_en = GPIO_PULLUP_ENABLE, - .master.clk_speed = 100000}; + // i2c_config_t conf = {.mode = I2C_MODE_MASTER, + // .sda_io_num = 19, + // .sda_pullup_en = GPIO_PULLUP_ENABLE, + // .scl_io_num = 18, + // .scl_pullup_en = GPIO_PULLUP_ENABLE, + // .master.clk_speed = 100000}; int nerrors = arg_parse_msg(argc, argv, (struct arg_hdr**)&i2cconfig_args); /* Check "--clear" option */ - if (i2cconfig_args.clear->count) { - cmd_send_messaging(argv[0], MESSAGING_WARNING, "i2c config cleared\n"); - config_set_value(NVS_TYPE_STR, "i2c_config", ""); - return 0; - } + // if (i2cconfig_args.clear->count) { + // cmd_send_messaging(argv[0], MESSAGING_WARNING, "i2c config cleared\n"); + // config_set_value(NVS_TYPE_STR, "i2c_config", ""); + // return 0; + // } + // TODO: Add support for the commented code - char* buf = NULL; - size_t buf_size = 0; - FILE* f = open_memstream(&buf, &buf_size); - if (f == NULL) { - cmd_send_messaging(argv[0], MESSAGING_ERROR, "Unable to open memory stream.\n"); - return 1; - } - if (nerrors > 0) { - arg_print_errors(f, i2cconfig_args.end, desc_i2c); - fclose(f); - return 1; - } - /* Check "--port" option */ - if (i2cconfig_args.port->count) { - if (i2c_get_port(i2cconfig_args.port->ival[0], &i2c_port) != ESP_OK) { - fprintf(f, "Invalid port %u \n", i2cconfig_args.port->ival[0]); - nerrors++; - } - } - /* Check "--freq" option */ - if (i2cconfig_args.freq->count) { - conf.master.clk_speed = i2cconfig_args.freq->ival[0]; - } +// char* buf = NULL; +// size_t buf_size = 0; +// FILE* f = open_memstream(&buf, &buf_size); +// if (f == NULL) { +// cmd_send_messaging(argv[0], MESSAGING_ERROR, "Unable to open memory stream.\n"); +// return 1; +// } +// if (nerrors > 0) { +// arg_print_errors(f, i2cconfig_args.end, desc_i2c); +// fclose(f); +// return 1; +// } +// /* Check "--port" option */ +// if (i2cconfig_args.port->count) { +// if (i2c_get_port(i2cconfig_args.port->ival[0], &i2c_port) != ESP_OK) { +// fprintf(f, "Invalid port %u \n", i2cconfig_args.port->ival[0]); +// nerrors++; +// } +// } +// /* Check "--freq" option */ +// if (i2cconfig_args.freq->count) { +// conf.master.clk_speed = i2cconfig_args.freq->ival[0]; +// } - nerrors += is_output_gpio(i2cconfig_args.sda, f, &conf.sda_io_num, true); - nerrors += is_output_gpio(i2cconfig_args.scl, f, &conf.scl_io_num, true); +// nerrors += is_output_gpio(i2cconfig_args.sda, f, &conf.sda_io_num, true); +// nerrors += is_output_gpio(i2cconfig_args.scl, f, &conf.scl_io_num, true); -#ifdef CONFIG_I2C_LOCKED - if (i2c_port == I2C_NUM_0) { - i2c_port = I2C_NUM_1; - fprintf(f, "can't use i2c port 0 when locked by config. Changing to port 1.\n"); - } -#endif +// #ifdef CONFIG_I2C_LOCKED +// if (i2c_port == I2C_NUM_0) { +// i2c_port = I2C_NUM_1; +// fprintf(f, "can't use i2c port 0 when locked by config. Changing to port 1.\n"); +// } +// #endif - if (!nerrors) { - fprintf(f, "Uninstalling i2c driver from port %u if needed\n", i2c_port); - if (is_i2c_started(i2c_port)) { - if ((err = i2c_driver_delete(i2c_port)) != ESP_OK) { - fprintf(f, "i2c driver delete failed. %s\n", esp_err_to_name(err)); - nerrors++; - } - } - } - if (!nerrors) { - if ((err = i2c_master_driver_initialize(argv[0], &conf)) == ESP_OK) { - if ((err = i2c_master_driver_install(argv[0])) != ESP_OK) { - nerrors++; - } else { - fprintf(f, "i2c driver successfully started.\n"); - } - } else { - nerrors++; - } - } - if (!nerrors) { - fprintf(f, "Storing i2c parameters.\n"); - config_i2c_set(&conf, i2c_port); - } - if (!nerrors) { - fprintf(f, "Done.\n"); - } - fflush(f); - cmd_send_messaging(argv[0], nerrors > 0 ? MESSAGING_ERROR : MESSAGING_INFO, "%s", buf); - fclose(f); - FREE_AND_NULL(buf); +// if (!nerrors) { +// fprintf(f, "Uninstalling i2c driver from port %u if needed\n", i2c_port); +// if (is_i2c_started(i2c_port)) { +// if ((err = i2c_driver_delete(i2c_port)) != ESP_OK) { +// fprintf(f, "i2c driver delete failed. %s\n", esp_err_to_name(err)); +// nerrors++; +// } +// } +// } +// if (!nerrors) { +// if ((err = i2c_master_driver_initialize(argv[0], &conf)) == ESP_OK) { +// if ((err = i2c_master_driver_install(argv[0])) != ESP_OK) { +// nerrors++; +// } else { +// fprintf(f, "i2c driver successfully started.\n"); +// } +// } else { +// nerrors++; +// } +// } +// if (!nerrors) { +// fprintf(f, "Storing i2c parameters.\n"); +// config_i2c_set(&conf, i2c_port); +// } +// if (!nerrors) { +// fprintf(f, "Done.\n"); +// } +// fflush(f); +// cmd_send_messaging(argv[0], nerrors > 0 ? MESSAGING_ERROR : MESSAGING_INFO, "%s", buf); +// fclose(f); +// FREE_AND_NULL(buf); return nerrors; } @@ -971,50 +973,7 @@ static int do_i2cdetect_cmd(int argc, char** argv) { return 0; } -cJSON* i2c_set_display_cb() { - cJSON* values = cJSON_CreateObject(); - const display_config_t* conf = config_display_get(); - if (conf) { - if (conf->width > 0) { - cJSON_AddNumberToObject(values, "width", conf->width); - } - if (conf->height > 0) { - cJSON_AddNumberToObject(values, "height", conf->height); - } - if (conf->address > 0) { - cJSON_AddNumberToObject(values, "address", conf->address); - } - if (conf->RST_pin >= 0) { - cJSON_AddNumberToObject(values, "reset", conf->RST_pin); - } - if (conf->drivername && strlen(conf->drivername) > 0) { - cJSON_AddStringToObject(values, "driver", conf->drivername); - } - if (conf->CS_pin >= 0) { - cJSON_AddNumberToObject(values, "cs", conf->CS_pin); - } - if (conf->speed > 0) { - cJSON_AddNumberToObject(values, "speed", conf->speed); - } - if (conf->back >= 0) { - cJSON_AddNumberToObject(values, "back", conf->back); - } - if (conf->depth > 0) { - cJSON_AddNumberToObject(values, "depth", conf->depth); - } - if (conf->type && strlen(conf->type)) { - cJSON_AddStringToObject(values, "type", conf->type); - } - cJSON_AddBoolToObject(values, "rotate", conf->rotate); - cJSON_AddBoolToObject(values, "hf", conf->hflip); - cJSON_AddBoolToObject(values, "vf", conf->vflip); - cJSON_AddBoolToObject(values, "invert", conf->invert); - if (conf->mode >= 0) { - cJSON_AddNumberToObject(values, "mode", conf->mode); - } - } - return values; -} + #if CONFIG_WITH_CONFIG_UI static void register_i2c_set_display() { @@ -1044,7 +1003,6 @@ static void register_i2c_set_display() { .hint = NULL, .func = &do_i2c_set_display, .argtable = &i2cdisp_args}; - cmd_to_json_with_cb(&i2c_set_display, &i2c_set_display_cb); ESP_ERROR_CHECK(esp_console_cmd_register(&i2c_set_display)); } #endif diff --git a/components/platform_console/cmd_nvs.c b/components/platform_console/cmd_nvs.c deleted file mode 100644 index df8a0813..00000000 --- a/components/platform_console/cmd_nvs.c +++ /dev/null @@ -1,612 +0,0 @@ -/* Console example — NVS commands - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#ifdef __cplusplus -extern "C" { -#endif -#include "nvs_flash.h" -#include -#include -#include -#include -#include -#include "esp_log.h" -#include "esp_console.h" -#include "argtable3/argtable3.h" -#include "freertos/FreeRTOS.h" -#include "freertos/event_groups.h" -#include "esp_err.h" -#include "cmd_nvs.h" -#include "nvs.h" -#include "nvs_utilities.h" -#include "platform_console.h" -#include "messaging.h" -#include "tools.h" -#include "trace.h" - -extern esp_err_t network_wifi_erase_legacy(); -extern esp_err_t network_wifi_erase_known_ap(); - -static const char *ARG_TYPE_STR = "type can be: i8, u8, i16, u16 i32, u32 i64, u64, str, blob"; -static const char * TAG = "cmd_nvs"; - -EXT_RAM_ATTR static struct { - struct arg_str *key; - struct arg_str *type; - struct arg_str *value; - struct arg_end *end; -} set_args; - -EXT_RAM_ATTR static struct { - struct arg_str *key; - struct arg_str *type; - struct arg_end *end; -} get_args; - -EXT_RAM_ATTR static struct { - struct arg_str *key; - struct arg_end *end; -} erase_args; - -EXT_RAM_ATTR static struct { - struct arg_str *namespace; - struct arg_end *end; -} erase_all_args; - -EXT_RAM_ATTR static struct { - struct arg_str *partition; - struct arg_str *namespace; - struct arg_str *type; - struct arg_end *end; -} list_args; - -EXT_RAM_ATTR static struct { - struct arg_lit *legacy; - struct arg_lit *ap_list; - struct arg_end *end; -} wifi_erase_args; - - -static esp_err_t store_blob(nvs_handle nvs, const char *key, const char *str_values) -{ - uint8_t value; - size_t str_len = strlen(str_values); - size_t blob_len = str_len / 2; - - if (str_len % 2) { - log_send_messaging(MESSAGING_ERROR, "Blob data must contain even number of characters"); - return ESP_ERR_NVS_TYPE_MISMATCH; - } - - char *blob = (char *)malloc_init_external(blob_len); - if (blob == NULL) { - return ESP_ERR_NO_MEM; - } - - for (int i = 0, j = 0; i < str_len; i++) { - char ch = str_values[i]; - if (ch >= '0' && ch <= '9') { - value = ch - '0'; - } else if (ch >= 'A' && ch <= 'F') { - value = ch - 'A' + 10; - } else if (ch >= 'a' && ch <= 'f') { - value = ch - 'a' + 10; - } else { - log_send_messaging(MESSAGING_ERROR, "Blob data contain invalid character"); - free(blob); - return ESP_ERR_NVS_TYPE_MISMATCH; - } - - if (i & 1) { - blob[j++] += value; - } else { - blob[j] = value << 4; - } - } - - esp_err_t err = nvs_set_blob(nvs, key, blob, blob_len); - free(blob); - - if (err == ESP_OK) { - err = nvs_commit(nvs); - } - - return err; -} - -static esp_err_t set_value_in_nvs(const char *key, const char *str_type, const char *str_value) -{ - esp_err_t err; - nvs_handle nvs; - bool range_error = false; - - nvs_type_t type = str_to_type(str_type); - - if (type == NVS_TYPE_ANY) { - return ESP_ERR_NVS_TYPE_MISMATCH; - } - - err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs); - if (err != ESP_OK) { - return err; - } - - if (type == NVS_TYPE_I8) { - int32_t value = strtol(str_value, NULL, 0); - if (value < INT8_MIN || value > INT8_MAX || errno == ERANGE) { - range_error = true; - } else { - err = nvs_set_i8(nvs, key, (int8_t)value); - } - } else if (type == NVS_TYPE_U8) { - uint32_t value = strtoul(str_value, NULL, 0); - if (value > UINT8_MAX || errno == ERANGE) { - range_error = true; - } else { - err = nvs_set_u8(nvs, key, (uint8_t)value); - } - } else if (type == NVS_TYPE_I16) { - int32_t value = strtol(str_value, NULL, 0); - if (value < INT16_MIN || value > INT16_MAX || errno == ERANGE) { - range_error = true; - } else { - err = nvs_set_i16(nvs, key, (int16_t)value); - } - } else if (type == NVS_TYPE_U16) { - uint32_t value = strtoul(str_value, NULL, 0); - if (value > UINT16_MAX || errno == ERANGE) { - range_error = true; - } else { - err = nvs_set_u16(nvs, key, (uint16_t)value); - } - } else if (type == NVS_TYPE_I32) { - int32_t value = strtol(str_value, NULL, 0); - if (errno != ERANGE) { - err = nvs_set_i32(nvs, key, value); - } - } else if (type == NVS_TYPE_U32) { - uint32_t value = strtoul(str_value, NULL, 0); - if (errno != ERANGE) { - err = nvs_set_u32(nvs, key, value); - } - } else if (type == NVS_TYPE_I64) { - int64_t value = strtoll(str_value, NULL, 0); - if (errno != ERANGE) { - err = nvs_set_i64(nvs, key, value); - } - } else if (type == NVS_TYPE_U64) { - uint64_t value = strtoull(str_value, NULL, 0); - if (errno != ERANGE) { - err = nvs_set_u64(nvs, key, value); - } - } else if (type == NVS_TYPE_STR) { - err = nvs_set_str(nvs, key, str_value); - } else if (type == NVS_TYPE_BLOB) { - err = store_blob(nvs, key, str_value); - } - - if (range_error || errno == ERANGE) { - nvs_close(nvs); - return ESP_ERR_NVS_VALUE_TOO_LONG; - } - - if (err == ESP_OK) { - log_send_messaging(MESSAGING_INFO, "Set value ok. Committing '%s'", key); - err = nvs_commit(nvs); - if (err == ESP_OK) { - log_send_messaging(MESSAGING_INFO, "Value stored under key '%s'", key); - } - } - - nvs_close(nvs); - return err; -} - -static esp_err_t get_value_from_nvs(const char *key, const char *str_type) -{ - nvs_handle nvs; - esp_err_t err; - - nvs_type_t type = str_to_type(str_type); - - if (type == NVS_TYPE_ANY) { - return ESP_ERR_NVS_TYPE_MISMATCH; - } - - err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs); - if (err != ESP_OK) { - return err; - } - - if (type == NVS_TYPE_I8) { - int8_t value; - err = nvs_get_i8(nvs, key, &value); - if (err == ESP_OK) { - log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %d \n", key, value); - } - } else if (type == NVS_TYPE_U8) { - uint8_t value; - err = nvs_get_u8(nvs, key, &value); - if (err == ESP_OK) { - log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %u \n", key, value); - } - } else if (type == NVS_TYPE_I16) { - int16_t value; - err = nvs_get_i16(nvs, key, &value); - if (err == ESP_OK) { - log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %d \n", key, value); - } - } else if (type == NVS_TYPE_U16) { - uint16_t value; - if ((err = nvs_get_u16(nvs, key, &value)) == ESP_OK) { - log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %u", key, value); - } - } else if (type == NVS_TYPE_I32) { - int32_t value; - if ((err = nvs_get_i32(nvs, key, &value)) == ESP_OK) { - log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %d \n", key, value); - } - } else if (type == NVS_TYPE_U32) { - uint32_t value; - if ((err = nvs_get_u32(nvs, key, &value)) == ESP_OK) { - log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %u \n", key, value); - } - } else if (type == NVS_TYPE_I64) { - int64_t value; - if ((err = nvs_get_i64(nvs, key, &value)) == ESP_OK) { - log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %lld \n", key, value); - } - } else if (type == NVS_TYPE_U64) { - uint64_t value; - if ( (err = nvs_get_u64(nvs, key, &value)) == ESP_OK) { - log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %llu \n", key, value); - } - } else if (type == NVS_TYPE_STR) { - size_t len=0; - if ( (err = nvs_get_str(nvs, key, NULL, &len)) == ESP_OK) { - char *str = (char *)malloc_init_external(len); - if ( (err = nvs_get_str(nvs, key, str, &len)) == ESP_OK) { - log_send_messaging(MESSAGING_INFO,"String associated with key '%s' is %s \n", key, str); - } - free(str); - } - } else if (type == NVS_TYPE_BLOB) { - size_t len; - if ( (err = nvs_get_blob(nvs, key, NULL, &len)) == ESP_OK) { - char *blob = (char *)malloc_init_external(len); - if ( (err = nvs_get_blob(nvs, key, blob, &len)) == ESP_OK) { - log_send_messaging(MESSAGING_INFO,"Blob associated with key '%s' is %d bytes long: \n", key, len); - print_blob(blob, len); - } - free(blob); - } - } - - nvs_close(nvs); - return err; -} - -static esp_err_t erase(const char *key) -{ - nvs_handle nvs; - - esp_err_t err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs); - if (err == ESP_OK) { - err = nvs_erase_key(nvs, key); - if (err == ESP_OK) { - err = nvs_commit(nvs); - if (err == ESP_OK) { - log_send_messaging(MESSAGING_INFO, "Value with key '%s' erased", key); - } - } - nvs_close(nvs); - } - - return err; -} - -static esp_err_t erase_all(const char *name) -{ - nvs_handle nvs; - - esp_err_t err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs); - if (err == ESP_OK) { - err = nvs_erase_all(nvs); - if (err == ESP_OK) { - err = nvs_commit(nvs); - } - } - - log_send_messaging(MESSAGING_INFO, "Namespace '%s' was %s erased", name, (err == ESP_OK) ? "" : "not"); - nvs_close(nvs); - return ESP_OK; -} - -static int set_value(int argc, char **argv) -{ - ESP_LOGD(TAG, "%s %u - Parsing keys ",__func__,__LINE__); - int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&set_args); - if (nerrors != 0) { - return 1; - } - - const char *key = set_args.key->sval[0]; - const char *type = set_args.type->sval[0]; - const char *values = set_args.value->sval[0]; - cmd_send_messaging(argv[0],MESSAGING_INFO, "Setting '%s' (type %s)", key,type); - esp_err_t err = set_value_in_nvs(key, type, values); - - if (err != ESP_OK) { - cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err)); - return 1; - } - - return 0; - -} - -static int get_value(int argc, char **argv) -{ - int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&get_args); - if (nerrors != 0) { - return 1; - } - - const char *key = get_args.key->sval[0]; - const char *type = get_args.type->sval[0]; - - esp_err_t err = get_value_from_nvs(key, type); - - if (err != ESP_OK) { - cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err)); - return 1; - } - - return 0; -} - -static int erase_value(int argc, char **argv) -{ - int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&erase_args); - if (nerrors != 0) { - return 1; - } - - const char *key = erase_args.key->sval[0]; - - esp_err_t err = erase(key); - - if (err != ESP_OK) { - cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err)); - return 1; - } - - return 0; -} - -static int erase_namespace(int argc, char **argv) -{ - int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&erase_all_args); - if (nerrors != 0) { - return 1; - } - - const char *name = erase_all_args.namespace->sval[0]; - - esp_err_t err = erase_all(name); - if (err != ESP_OK) { - cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err)); - return 1; - } - - return 0; -} - -static int erase_network_manager(int argc, char **argv) -{ - nvs_handle nvs; - esp_err_t err = nvs_open("config", NVS_READWRITE, &nvs); - if (err == ESP_OK) { - err = nvs_erase_all(nvs); - if (err == ESP_OK) { - err = nvs_commit(nvs); - } - } - nvs_close(nvs); - if (err != ESP_OK) { - cmd_send_messaging(argv[0],MESSAGING_ERROR, "System configuration was not erased. %s", esp_err_to_name(err)); - return 1; - } - else { - cmd_send_messaging(argv[0],MESSAGING_WARNING, "system configuration was erased. Please reboot."); - } - return 0; -} - -static int wifi_erase_config(int argc, char **argv) -{ - esp_err_t err=ESP_OK; - esp_err_t err_ap_list=ESP_OK; - bool done = false; - int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&wifi_erase_args); - if (nerrors != 0) { - return 1; - } - if(wifi_erase_args.ap_list->count>0){ - err_ap_list = network_wifi_erase_known_ap(); - if (err_ap_list != ESP_OK) { - cmd_send_messaging(argv[0],MESSAGING_ERROR, "Could not erase legacy wifi configuration: %s", esp_err_to_name(err)); - } - else { - cmd_send_messaging(argv[0],MESSAGING_ERROR, "Legacy wifi configuration was erased"); - } - done = true; - } - if(wifi_erase_args.legacy->count>0){ - err = network_wifi_erase_legacy(); - if (err != ESP_OK) { - cmd_send_messaging(argv[0],MESSAGING_ERROR, "Could not erase known ap list : %s", esp_err_to_name(err)); - } - else { - cmd_send_messaging(argv[0],MESSAGING_ERROR, "Known access point list was erased"); - } - done = true; - } - if(!done){ - cmd_send_messaging(argv[0],MESSAGING_WARNING, "Please specify at least one configuration type to erase.", esp_err_to_name(err)); - } - return (err_ap_list==ESP_OK && err==ESP_OK)?0:1; -} - -static int list(const char *part, const char *name, const char *str_type) -{ - nvs_type_t type = str_to_type(str_type); - - nvs_iterator_t it = nvs_entry_find(part, NULL, type); - if (it == NULL) { - log_send_messaging(MESSAGING_ERROR, "No such enty was found"); - return 1; - } - - do { - nvs_entry_info_t info; - nvs_entry_info(it, &info); - it = nvs_entry_next(it); - - log_send_messaging(MESSAGING_INFO, "namespace '%s', key '%s', type '%s' \n", - info.namespace_name, info.key, type_to_str(info.type)); - } while (it != NULL); - - return 0; -} -static int list_entries(int argc, char **argv) -{ - list_args.partition->sval[0] = ""; - list_args.namespace->sval[0] = ""; - list_args.type->sval[0] = ""; - - int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&list_args); - if (nerrors != 0) { - return 1; - } - - const char *part = list_args.partition->sval[0]; - const char *name = list_args.namespace->sval[0]; - const char *type = list_args.type->sval[0]; - - return list(part, name, type); -} -void register_nvs() -{ - set_args.key = arg_str1(NULL, NULL, "", "key of the value to be set"); - set_args.type = arg_str1(NULL, NULL, "", ARG_TYPE_STR); - set_args.value = arg_str1("v", "value", "", "value to be stored"); - set_args.end = arg_end(2); - - get_args.key = arg_str1(NULL, NULL, "", "key of the value to be read"); - get_args.type = arg_str1(NULL, NULL, "", ARG_TYPE_STR); - get_args.end = arg_end(2); - - erase_args.key = arg_str1(NULL, NULL, "", "key of the value to be erased"); - erase_args.end = arg_end(2); - - erase_all_args.namespace = arg_str1(NULL, NULL, "", "namespace to be erased"); - erase_all_args.end = arg_end(2); - - wifi_erase_args.ap_list = arg_lit0("a","ap_list","Erases Known access points list"); - wifi_erase_args.legacy = arg_lit0("l","legacy","Erases legacy access point storage"); - wifi_erase_args.end = arg_end(1); - - list_args.partition = arg_str1(NULL, NULL, "", "partition name"); - list_args.namespace = arg_str0("n", "namespace", "", "namespace name"); - list_args.type = arg_str0("t", "type", "", ARG_TYPE_STR); - list_args.end = arg_end(2); - const esp_console_cmd_t set_cmd = { - .command = "nvs_set", - .help = "Set variable in selected namespace. Blob type must be comma separated list of hex values. \n" - "Examples:\n" - " nvs_set VarName i32 -v 123 \n" - " nvs_set VarName srt -v YourString \n" - " nvs_set VarName blob -v 0123456789abcdef \n", - .hint = NULL, - .func = &set_value, - .argtable = &set_args - }; - - const esp_console_cmd_t get_cmd = { - .command = "nvs_get", - .help = "Get variable from selected namespace. \n" - "Example: nvs_get VarName i32", - .hint = NULL, - .func = &get_value, - .argtable = &get_args - }; - - const esp_console_cmd_t erase_cmd = { - .command = "nvs_erase", - .help = "Erase variable from current namespace", - .hint = NULL, - .func = &erase_value, - .argtable = &erase_args - }; - - const esp_console_cmd_t erase_namespace_cmd = { - .command = "nvs_erase_namespace", - .help = "Erases specified namespace", - .hint = NULL, - .func = &erase_namespace, - .argtable = &erase_all_args - }; - const esp_console_cmd_t erase_config_cmd = { - .command = "wifi_erase_config", - .help = "Erases all stored access points from flash", - .hint = NULL, - .func = &wifi_erase_config, - .argtable = &wifi_erase_args - }; - - const esp_console_cmd_t erase_networkmanager_cmd = { - .command = "nvs_erase_configuration", - .help = "Erases system's configuration", - .hint = NULL, - .func = &erase_network_manager, - .argtable = NULL - }; - - - const esp_console_cmd_t list_entries_cmd = { - .command = "nvs_list", - .help = "List stored key-value pairs stored in NVS." - "Namespace and type can be specified to print only those key-value pairs.\n" - "Following command list variables stored inside 'nvs' partition, under namespace 'storage' with type uint32_t" - "Example: nvs_list nvs -n storage -t u32 \n", - .hint = NULL, - .func = &list_entries, - .argtable = &list_args - }; - - MEMTRACE_PRINT_DELTA_MESSAGE("registering list_entries_cmd"); - ESP_ERROR_CHECK(esp_console_cmd_register(&list_entries_cmd)); - MEMTRACE_PRINT_DELTA_MESSAGE("registering set_cmd"); - ESP_ERROR_CHECK(esp_console_cmd_register(&set_cmd)); - MEMTRACE_PRINT_DELTA_MESSAGE("registering get_cmd"); - ESP_ERROR_CHECK(esp_console_cmd_register(&get_cmd)); - MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_cmd"); - ESP_ERROR_CHECK(esp_console_cmd_register(&erase_cmd)); - MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_namespace_cmd"); - ESP_ERROR_CHECK(esp_console_cmd_register(&erase_namespace_cmd)); - MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_config_cmd"); - ESP_ERROR_CHECK(esp_console_cmd_register(&erase_networkmanager_cmd)); - MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_config_cmd"); - ESP_ERROR_CHECK(esp_console_cmd_register(&erase_config_cmd)); - MEMTRACE_PRINT_DELTA_MESSAGE("Done"); - -} -#ifdef __cplusplus -extern } -#endif diff --git a/components/platform_console/cmd_nvs.h b/components/platform_console/cmd_nvs.h deleted file mode 100644 index 21f7a4d3..00000000 --- a/components/platform_console/cmd_nvs.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Console example — declarations of command registration functions. - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#pragma once -#include "nvs_flash.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// Register NVS functions -void register_nvs(); - -#ifdef __cplusplus -} -#endif - diff --git a/components/platform_console/cmd_system.c b/components/platform_console/cmd_system.c index cee6c52b..0d0b6a70 100644 --- a/components/platform_console/cmd_system.c +++ b/components/platform_console/cmd_system.c @@ -26,7 +26,7 @@ #include "esp_partition.h" #include "esp_ota_ops.h" #include "platform_esp32.h" -#include "platform_config.h" +#include "Configurator.h" #include "esp_sleep.h" #include "messaging.h" #include "platform_console.h" @@ -42,25 +42,24 @@ #pragma message("Runtime stats disabled") #endif EXT_RAM_ATTR static struct { - struct arg_str *name; - struct arg_end *end; -} name_args; -EXT_RAM_ATTR static struct { - #if CONFIG_CSPOT_SINK - struct arg_lit *cspot; - #endif - struct arg_lit *btspeaker; - struct arg_lit *airplay; - struct arg_str *telnet; -#if WITH_TASKS_INFO - struct arg_lit *stats; -#endif - struct arg_end *end; -} set_services_args; + struct arg_str * device; + // AirPlay device name + struct arg_str * airplay; + // Spotify device name + struct arg_str * spotify; + // Bluetooth player name advertized + struct arg_str * bluetooth; + // Player name reported to the Logitech Media Server + struct arg_str * squeezelite; + // Wifi Access Point name + struct arg_str * wifi_ap_name; + struct arg_lit * all; + struct arg_end *end; +} names_args; + static const char * TAG = "cmd_system"; -//static void register_setbtsource(); static void register_free(); static void register_setdevicename(); static void register_heap(); @@ -73,7 +72,7 @@ static void register_light_sleep(); #endif static void register_factory_boot(); static void register_restart_ota(); -static void register_set_services(); +// static void register_set_services(); #if WITH_TASKS_INFO static void register_tasks(); #endif @@ -88,7 +87,7 @@ FILE * system_open_memstream(const char * cmdname,char **buf,size_t *buf_size){ void register_system() { - register_set_services(); + // register_set_services(); register_setdevicename(); register_free(); register_heap(); @@ -108,7 +107,7 @@ void register_system() void simple_restart() { log_send_messaging(MESSAGING_WARNING,"Rebooting."); - if(!wait_for_commit()){ + if(!configurator_waitcommit()){ log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration. "); } vTaskDelay(750/ portTICK_PERIOD_MS); @@ -320,17 +319,19 @@ static int heap_size(int argc, char **argv) return 0; } cJSON * setdevicename_cb(){ - char * default_host_name = config_alloc_get_str("host_name",NULL,"Squeezelite"); + // char * default_host_name = config_alloc_get_str("host_name",NULL,"Squeezelite"); cJSON * values = cJSON_CreateObject(); - cJSON_AddStringToObject(values,"name",default_host_name); - free(default_host_name); + // cJSON_AddStringToObject(values,"name",default_host_name); + // free(default_host_name); + // TODO: Add support for the commented code") return values; } static int setnamevar(char * nvsname, FILE *f, char * value){ esp_err_t err=ESP_OK; - if((err=config_set_value(NVS_TYPE_STR, nvsname, value))!=ESP_OK){ - fprintf(f,"Unable to set %s=%s. %s\n",nvsname,value,esp_err_to_name(err)); - } + // if((err=config_set_value(NVS_TYPE_STR, nvsname, value))!=ESP_OK){ + // fprintf(f,"Unable to set %s=%s. %s\n",nvsname,value,esp_err_to_name(err)); + // } + // TODO: Add support for the commented code") return err==ESP_OK?0:1; } typedef enum { @@ -339,140 +340,147 @@ typedef enum { } scanstate_t; int set_cspot_player_name(FILE * f,const char * name){ int ret=0; - cJSON * cspot_config = config_alloc_get_cjson("cspot_config"); - if(cspot_config==NULL){ - fprintf(f,"Unable to get cspot_config\n"); - return 1; - } - cJSON * player_name = cJSON_GetObjectItemCaseSensitive(cspot_config,"deviceName"); - if(player_name==NULL){ - fprintf(f,"Unable to get deviceName\n"); - ret=1; - } - if(strcmp(player_name->valuestring,name)==0){ - fprintf(f,"CSpot device name not changed.\n"); - ret=0; - } - else{ - cJSON_SetValuestring(player_name,name); - if(setnamevar("cspot_config",f,cJSON_Print(cspot_config))!=0){ - fprintf(f,"Unable to set cspot_config\n"); - ret=1; - } - else{ - fprintf(f,"CSpot device name set to %s\n",name); - } - } - cJSON_Delete(cspot_config); + // cJSON * cspot_config = config_alloc_get_cjson("cspot_config"); + // if(cspot_config==NULL){ + // fprintf(f,"Unable to get cspot_config\n"); + // return 1; + // } + // cJSON * player_name = cJSON_GetObjectItemCaseSensitive(cspot_config,"deviceName"); + // if(player_name==NULL){ + // fprintf(f,"Unable to get deviceName\n"); + // ret=1; + // } + // if(strcmp(player_name->valuestring,name)==0){ + // fprintf(f,"CSpot device name not changed.\n"); + // ret=0; + // } + // else{ + // cJSON_SetValuestring(player_name,name); + // if(setnamevar("cspot_config",f,cJSON_Print(cspot_config))!=0){ + // fprintf(f,"Unable to set cspot_config\n"); + // ret=1; + // } + // else{ + // fprintf(f,"CSpot device name set to %s\n",name); + // } + // } + // cJSON_Delete(cspot_config); + // TODO: Add support for the commented code") return ret; } int set_squeezelite_player_name(FILE * f,const char * name){ - char * nvs_config= config_alloc_get(NVS_TYPE_STR, "autoexec1"); - char **argv = NULL; - esp_err_t err=ESP_OK; - int nerrors=0; - bool bFoundParm=false; - scanstate_t state=SCANNING; - char * newCommandLine = NULL; - char * parm = " -n "; - char * cleaned_name = strdup(name); - for(char * p=cleaned_name;*p!='\0';p++){ - if(*p == ' '){ - *p='_'; // no spaces allowed - } - } - if(nvs_config && strlen(nvs_config)>0){ - // allocate enough memory to hold the new command line - size_t cmdLength = strlen(nvs_config) + strlen(cleaned_name) + strlen(parm) +1 ; - newCommandLine = malloc_init_external(cmdLength); - ESP_LOGD(TAG,"Parsing command %s",nvs_config); - argv = (char **) malloc_init_external(22* sizeof(char *)); - if (argv == NULL) { - FREE_AND_NULL(nvs_config); - return 1; - } - size_t argc = esp_console_split_argv(nvs_config, argv,22); - for(int i=0;i0){ - strcat(newCommandLine," "); - } - switch (state) - { - case SCANNING: - strcat(newCommandLine,argv[i]); - if(strcasecmp(argv[i],"--name")==0 || strcasecmp(argv[i],"-n")==0 ){ - state = PROCESSING_NAME; - } - break; - case PROCESSING_NAME: - bFoundParm=true; - strcat(newCommandLine,cleaned_name); - state = SCANNING; - break; + int nerrors=0; + // TODO: Add support for the commented code") + // char * nvs_config= config_alloc_get(NVS_TYPE_STR, "autoexec1"); + // char **argv = NULL; + // esp_err_t err=ESP_OK; + // bool bFoundParm=false; + // scanstate_t state=SCANNING; + // char * newCommandLine = NULL; + // char * parm = " -n "; + // char * cleaned_name = strdup(name); + // for(char * p=cleaned_name;*p!='\0';p++){ + // if(*p == ' '){ + // *p='_'; // no spaces allowed + // } + // } + // if(nvs_config && strlen(nvs_config)>0){ + // // allocate enough memory to hold the new command line + // size_t cmdLength = strlen(nvs_config) + strlen(cleaned_name) + strlen(parm) +1 ; + // newCommandLine = malloc_init_external(cmdLength); + // ESP_LOGD(TAG,"Parsing command %s",nvs_config); + // argv = (char **) malloc_init_external(22* sizeof(char *)); + // if (argv == NULL) { + // FREE_AND_NULL(nvs_config); + // return 1; + // } + // size_t argc = esp_console_split_argv(nvs_config, argv,22); + // for(int i=0;i0){ + // strcat(newCommandLine," "); + // } + // switch (state) + // { + // case SCANNING: + // strcat(newCommandLine,argv[i]); + // if(strcasecmp(argv[i],"--name")==0 || strcasecmp(argv[i],"-n")==0 ){ + // state = PROCESSING_NAME; + // } + // break; + // case PROCESSING_NAME: + // bFoundParm=true; + // strcat(newCommandLine,cleaned_name); + // state = SCANNING; + // break; - default: - break; - } - } - if(!bFoundParm){ - strcat(newCommandLine,parm); - strcat(newCommandLine,name); - } - fprintf(f,"Squeezelite player name changed to %s\n",newCommandLine); - if((err=config_set_value(NVS_TYPE_STR, "autoexec1",newCommandLine))!=ESP_OK){ - nerrors++; - fprintf(f,"Failed updating squeezelite command. %s", esp_err_to_name(err)); - } + // default: + // break; + // } + // } + // if(!bFoundParm){ + // strcat(newCommandLine,parm); + // strcat(newCommandLine,name); + // } + // fprintf(f,"Squeezelite player name changed to %s\n",newCommandLine); + // if((err=config_set_value(NVS_TYPE_STR, "autoexec1",newCommandLine))!=ESP_OK){ + // nerrors++; + // fprintf(f,"Failed updating squeezelite command. %s", esp_err_to_name(err)); + // } - } + // } - FREE_AND_NULL(nvs_config); - FREE_AND_NULL(argv); - free(cleaned_name); + // FREE_AND_NULL(nvs_config); + // FREE_AND_NULL(argv); + // free(cleaned_name); return nerrors; } static int setdevicename(int argc, char **argv) { - char * name = NULL; - int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&name_args); + bool changed = false; + int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&names_args); if (nerrors != 0) { return 1; } - - /* Check "--name" option */ - if (name_args.name->count) { - name=strdup_psram(name_args.name->sval[0]); - } + if (names_args.device->count >0){ + changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_device_tag, &platform->names,names_args.device->sval[0]); + } else { - cmd_send_messaging(argv[0],MESSAGING_ERROR,"Name must be specified."); + ESP_LOGE(TAG,"Device name must be specified"); return 1; } + if (names_args.airplay->count >0){ + changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_airplay_tag, &platform->names,names_args.airplay->sval[0]); + } + + if (names_args.bluetooth->count >0){ + changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_bluetooth_tag, &platform->names,names_args.bluetooth->sval[0]); + } + if (names_args.spotify->count >0){ + changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_spotify_tag, &platform->names,names_args.spotify->sval[0]); + } + if (names_args.squeezelite->count >0){ + changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_squeezelite_tag, &platform->names,names_args.squeezelite->sval[0]); + } + if (names_args.wifi_ap_name->count >0){ + changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_wifi_ap_name_tag, &platform->names,names_args.wifi_ap_name->sval[0]); + } + if (names_args.all->count >0){ + ESP_LOGI(TAG,"Setting all names to %s", platform->names.device); + changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_airplay_tag, &platform->names,platform->names.device); + changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_bluetooth_tag, &platform->names,platform->names.device); + changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_spotify_tag, &platform->names,platform->names.device); + changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_squeezelite_tag, &platform->names,platform->names.device); + changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_wifi_ap_name_tag, &platform->names,platform->names.device); + } + if(changed){ + ESP_LOGI(TAG,"Found change(s). Saving"); + configurator_raise_changed(); + } + else { + ESP_LOGW(TAG,"No change detected."); + } - char *buf = NULL; - size_t buf_size = 0; - FILE *f = system_open_memstream(argv[0],&buf, &buf_size); - if (f == NULL) { - return 1; - } - nerrors+=setnamevar("a2dp_dev_name", f, name); - nerrors+=setnamevar("airplay_name", f, name); - nerrors+=setnamevar("ap_ssid", f, name); - nerrors+=setnamevar("bt_name", f, name); - nerrors+=setnamevar("host_name", f, name); - nerrors+=set_squeezelite_player_name(f, name); - nerrors+=set_cspot_player_name(f, name); - if(nerrors==0){ - fprintf(f,"Device name changed to %s\n",name); - } - if(!nerrors ){ - fprintf(f,"Done.\n"); - } - FREE_AND_NULL(name); - fflush (f); - cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); - fclose(f); - FREE_AND_NULL(buf); return nerrors; } @@ -506,18 +514,23 @@ static void register_dump_heap() static void register_setdevicename() { - char * default_host_name = config_alloc_get_str("host_name",NULL,"Squeezelite"); - name_args.name = arg_str0("n", "name", default_host_name, "New Name"); - name_args.end = arg_end(8); + char * default_host_name = platform->names.device; + names_args.device = arg_str0("n", "device", default_host_name, "New Name"); + names_args.airplay = arg_str0("a", "airplay", default_host_name, "New Airplay Device Name"); + names_args.bluetooth = arg_str0("b", "bt", default_host_name, "New Bluetooth Device Name"); + names_args.spotify = arg_str0("s", "spotify", default_host_name, "New Spotify Device Name"); + names_args.squeezelite = arg_str0("l", "squeezelite", default_host_name, "New Squeezelite Player Name"); + names_args.wifi_ap_name = arg_str0("w", "wifiap", default_host_name, "New Wifi AP Name"); + names_args.all = arg_lit0(NULL, "all", "Set all names to device name"); + names_args.end = arg_end(2); const esp_console_cmd_t set_name= { .command = CFG_TYPE_SYST("name"), .help="Device Name", .hint = NULL, .func = &setdevicename, - .argtable = &name_args + .argtable = &names_args }; - cmd_to_json_with_cb(&set_name,&setdevicename_cb); ESP_ERROR_CHECK(esp_console_cmd_register(&set_name)); } /** 'tasks' command prints the list of tasks and related information */ @@ -625,123 +638,124 @@ static void register_deep_sleep() #endif static int enable_disable(FILE * f,char * nvs_name, struct arg_lit *arg){ - esp_err_t err = config_set_value(NVS_TYPE_STR, nvs_name, arg->count>0?"Y":"N"); - const char * name = arg->hdr.longopts?arg->hdr.longopts:arg->hdr.glossary; + esp_err_t err = ESP_OK; + // err= config_set_value(NVS_TYPE_STR, nvs_name, arg->count>0?"Y":"N"); + // const char * name = arg->hdr.longopts?arg->hdr.longopts:arg->hdr.glossary; - if(err!=ESP_OK){ - fprintf(f,"Error %s %s. %s\n",arg->count>0?"Enabling":"Disabling", name, esp_err_to_name(err)); - } - else { - fprintf(f,"%s %s\n",arg->count>0?"Enabled":"Disabled",name); - } + // if(err!=ESP_OK){ + // fprintf(f,"Error %s %s. %s\n",arg->count>0?"Enabling":"Disabling", name, esp_err_to_name(err)); + // } + // else { + // fprintf(f,"%s %s\n",arg->count>0?"Enabled":"Disabled",name); + // } return err; } -static int do_set_services(int argc, char **argv) -{ - esp_err_t err = ESP_OK; - int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&set_services_args); - if (nerrors != 0) { - return 1; - } - char *buf = NULL; - size_t buf_size = 0; - FILE *f = system_open_memstream(argv[0],&buf, &buf_size); - if (f == NULL) { - return 1; - } +// static int do_set_services(int argc, char **argv) +// { +// esp_err_t err = ESP_OK; +// int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&set_services_args); +// if (nerrors != 0) { +// return 1; +// } +// char *buf = NULL; +// size_t buf_size = 0; +// FILE *f = system_open_memstream(argv[0],&buf, &buf_size); +// if (f == NULL) { +// return 1; +// } - nerrors += enable_disable(f,"enable_airplay",set_services_args.airplay); - nerrors += enable_disable(f,"enable_bt_sink",set_services_args.btspeaker); - #if CONFIG_CSPOT_SINK - nerrors += enable_disable(f,"enable_cspot",set_services_args.cspot); - #endif +// nerrors += enable_disable(f,"enable_airplay",set_services_args.airplay); +// nerrors += enable_disable(f,"enable_bt_sink",set_services_args.btspeaker); +// #if CONFIG_CSPOT_SINK +// nerrors += enable_disable(f,"enable_cspot",set_services_args.cspot); +// #endif - if(set_services_args.telnet->count>0){ - if(strcasecmp(set_services_args.telnet->sval[0],"Disabled") == 0){ - err = config_set_value(NVS_TYPE_STR, "telnet_enable", "N"); - } - else if(strcasecmp(set_services_args.telnet->sval[0],"Telnet Only") == 0){ - err = config_set_value(NVS_TYPE_STR, "telnet_enable", "Y"); - } - else if(strcasecmp(set_services_args.telnet->sval[0],"Telnet and Serial") == 0){ - err = config_set_value(NVS_TYPE_STR, "telnet_enable", "D"); - } - - if(err!=ESP_OK){ - nerrors++; - fprintf(f,"Error setting telnet to %s. %s\n",set_services_args.telnet->sval[0], esp_err_to_name(err)); - } - else { - fprintf(f,"Telnet service changed to %s\n",set_services_args.telnet->sval[0]); - } - } +// if(set_services_args.telnet->count>0){ +// // if(strcasecmp(set_services_args.telnet->sval[0],"Disabled") == 0){ +// // err = config_set_value(NVS_TYPE_STR, "telnet_enable", "N"); +// // } +// // else if(strcasecmp(set_services_args.telnet->sval[0],"Telnet Only") == 0){ +// // err = config_set_value(NVS_TYPE_STR, "telnet_enable", "Y"); +// // } +// // else if(strcasecmp(set_services_args.telnet->sval[0],"Telnet and Serial") == 0){ +// // err = config_set_value(NVS_TYPE_STR, "telnet_enable", "D"); +// // } +// // TODO: Add support for the commented code") +// if(err!=ESP_OK){ +// nerrors++; +// fprintf(f,"Error setting telnet to %s. %s\n",set_services_args.telnet->sval[0], esp_err_to_name(err)); +// } +// else { +// fprintf(f,"Telnet service changed to %s\n",set_services_args.telnet->sval[0]); +// } +// } -#if WITH_TASKS_INFO - nerrors += enable_disable(f,"stats",set_services_args.stats); -#endif - if(!nerrors ){ - fprintf(f,"Done.\n"); - } - fflush (f); - cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); - fclose(f); - FREE_AND_NULL(buf); - return nerrors; -} +// #if WITH_TASKS_INFO +// nerrors += enable_disable(f,"stats",set_services_args.stats); +// #endif +// if(!nerrors ){ +// fprintf(f,"Done.\n"); +// } +// fflush (f); +// cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf); +// fclose(f); +// FREE_AND_NULL(buf); +// return nerrors; +// } -cJSON * set_services_cb(){ - cJSON * values = cJSON_CreateObject(); - char * p=NULL; - console_set_bool_parameter(values,"enable_bt_sink",set_services_args.btspeaker); - console_set_bool_parameter(values,"enable_airplay",set_services_args.airplay); - #if CONFIG_CSPOT_SINK - console_set_bool_parameter(values,"enable_cspot",set_services_args.cspot); - #endif - #if WITH_TASKS_INFO - console_set_bool_parameter(values,"stats",set_services_args.stats); - #endif - if ((p = config_alloc_get(NVS_TYPE_STR, "telnet_enable")) != NULL) { - if(strcasestr("YX",p)!=NULL){ - cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Telnet Only"); - } - else if(strcasestr("D",p)!=NULL){ - cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Telnet and Serial"); - } - else { - cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Disabled"); - } -#if defined(CONFIG_WITH_METRICS) - metrics_add_feature_variant("telnet",p); -#endif - FREE_AND_NULL(p); - } +// cJSON * set_services_cb(){ +// cJSON * values = cJSON_CreateObject(); +// char * p=NULL; +// console_set_bool_parameter(values,"enable_bt_sink",set_services_args.btspeaker); +// console_set_bool_parameter(values,"enable_airplay",set_services_args.airplay); +// #if CONFIG_CSPOT_SINK +// console_set_bool_parameter(values,"enable_cspot",set_services_args.cspot); +// #endif +// #if WITH_TASKS_INFO +// console_set_bool_parameter(values,"stats",set_services_args.stats); +// #endif +// // if ((p = config_alloc_get(NVS_TYPE_STR, "telnet_enable")) != NULL) { +// // if(strcasestr("YX",p)!=NULL){ +// // cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Telnet Only"); +// // } +// // else if(strcasestr("D",p)!=NULL){ +// // cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Telnet and Serial"); +// // } +// // else { +// // cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Disabled"); +// // } +// // #if defined(CONFIG_WITH_METRICS) +// // metrics_add_feature_variant("telnet",p); +// // #endif +// // FREE_AND_NULL(p); +// // } +// // TODO: Add support for the commented code") +// return values; +// } - return values; -} - -static void register_set_services(){ - set_services_args.airplay = arg_lit0(NULL, "AirPlay", "AirPlay"); - #if CONFIG_CSPOT_SINK - set_services_args.cspot = arg_lit0(NULL, "cspot", "Spotify (cspot)"); - #endif - set_services_args.btspeaker = arg_lit0(NULL, "BT_Speaker", "Bluetooth Speaker"); - set_services_args.telnet= arg_str0("t", "telnet","Disabled|Telnet Only|Telnet and Serial","Telnet server. Use only for troubleshooting"); -#if WITH_TASKS_INFO - set_services_args.stats= arg_lit0(NULL, "stats", "System Statistics. Use only for troubleshooting"); -#endif - set_services_args.end=arg_end(2); - const esp_console_cmd_t cmd = { - .command = CFG_TYPE_SYST("services"), - .help = "Services", - .argtable = &set_services_args, - .hint = NULL, - .func = &do_set_services, - }; - cmd_to_json_with_cb(&cmd,&set_services_cb); - ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); -} +// static void register_set_services(){ +// set_services_args.airplay = arg_lit0(NULL, "AirPlay", "AirPlay"); +// #if CONFIG_CSPOT_SINK +// set_services_args.cspot = arg_lit0(NULL, "cspot", "Spotify (cspot)"); +// #endif +// set_services_args.btspeaker = arg_lit0(NULL, "BT_Speaker", "Bluetooth Speaker"); +// set_services_args.telnet= arg_str0("t", "telnet","Disabled|Telnet Only|Telnet and Serial","Telnet server. Use only for troubleshooting"); +// #if WITH_TASKS_INFO +// set_services_args.stats= arg_lit0(NULL, "stats", "System Statistics. Use only for troubleshooting"); +// #endif +// set_services_args.end=arg_end(2); +// const esp_console_cmd_t cmd = { +// .command = CFG_TYPE_SYST("services"), +// .help = "Services", +// .argtable = &set_services_args, +// .hint = NULL, +// .func = &do_set_services, +// }; +// cmd_to_json_with_cb(&cmd,&set_services_cb); +// ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); +// } #if CONFIG_WITH_CONFIG_UI static struct { diff --git a/components/platform_console/platform_console.c b/components/platform_console/platform_console.c index ce6a237f..cc87f018 100644 --- a/components/platform_console/platform_console.c +++ b/components/platform_console/platform_console.c @@ -24,7 +24,8 @@ #include "platform_esp32.h" #include "cmd_decl.h" #include "trace.h" -#include "platform_config.h" +// #include "Configurator.h" +#pragma message("fixme: search for TODO below") #include "telnet.h" #include "tools.h" #if defined(CONFIG_WITH_METRICS) @@ -38,7 +39,7 @@ static void * console_thread(); void console_start(); static const char * TAG = "console"; extern bool bypass_network_manager; -extern void register_squeezelite(); +extern void launchsqueezelite(); static EXT_RAM_ATTR QueueHandle_t uart_queue; static EXT_RAM_ATTR struct { @@ -92,16 +93,17 @@ void console_set_bool_parameter(cJSON * root,char * nvs_name, struct arg_lit *ar ESP_LOGE(TAG,"Invalid json parameter. Cannot set %s from %s",arg->hdr.longopts?arg->hdr.longopts:arg->hdr.glossary,nvs_name); return; } - if ((p = config_alloc_get(NVS_TYPE_STR, nvs_name)) != NULL) { - enabled = strcmp(p,"1") == 0 || strcasecmp(p,"y") == 0; - cJSON_AddBoolToObject(root,arg->hdr.longopts,enabled); - FREE_AND_NULL(p); - } -#if defined(CONFIG_WITH_METRICS) - if(enabled){ - metrics_add_feature(nvs_name,"enabled"); - } -#endif +// if ((p = config_alloc_get(NVS_TYPE_STR, nvs_name)) != NULL) { +// enabled = strcmp(p,"1") == 0 || strcasecmp(p,"y") == 0; +// cJSON_AddBoolToObject(root,arg->hdr.longopts,enabled); +// FREE_AND_NULL(p); +// } +// #if defined(CONFIG_WITH_METRICS) +// if(enabled){ +// metrics_add_feature(nvs_name,"enabled"); +// } +// #endif +// TODO: Add support for the commented code } struct arg_end *getParmsEnd(struct arg_hdr * * argtable){ @@ -215,48 +217,52 @@ void process_autoexec(){ char autoexec_name[21]={0}; char * autoexec_value=NULL; uint8_t autoexec_flag=0; + // TODO: Add support for the commented code + void * cmd = run_command; - char * str_flag = config_alloc_get(NVS_TYPE_STR, "autoexec"); - if(!bypass_network_manager){ - ESP_LOGW(TAG, "Processing autoexec commands while network manager active. Wifi related commands will be ignored."); - } - if(is_recovery_running){ - ESP_LOGD(TAG, "Processing autoexec commands in recovery mode. Squeezelite commands will be ignored."); - } - if(str_flag !=NULL ){ - autoexec_flag=atoi(str_flag); - ESP_LOGI(TAG,"autoexec is set to %s auto-process", autoexec_flag>0?"perform":"skip"); - if(autoexec_flag == 1) { - do { - snprintf(autoexec_name,sizeof(autoexec_name)-1,"autoexec%u",i++); - ESP_LOGD(TAG,"Getting command name %s", autoexec_name); - autoexec_value= config_alloc_get(NVS_TYPE_STR, autoexec_name); - if(autoexec_value!=NULL ){ - if(!bypass_network_manager && strstr(autoexec_value, "join ")!=NULL ){ - ESP_LOGW(TAG,"Ignoring wifi join command."); - } - else if(is_recovery_running && !strstr(autoexec_value, "squeezelite " ) ){ - ESP_LOGW(TAG,"Ignoring command. "); - } - else { - ESP_LOGI(TAG,"Running command %s = %s", autoexec_name, autoexec_value); - run_command(autoexec_value); - } - ESP_LOGD(TAG,"Freeing memory for command %s name", autoexec_name); - free(autoexec_value); - } - else { - ESP_LOGD(TAG,"No matching command found for name %s", autoexec_name); - break; - } - } while(1); - } - free(str_flag); - } - else - { - ESP_LOGD(TAG,"No matching command found for name autoexec."); - } + // char * str_flag = config_alloc_get(NVS_TYPE_STR, "autoexec"); + // if(!bypass_network_manager){ + // ESP_LOGW(TAG, "Processing autoexec commands while network manager active. Wifi related commands will be ignored."); + // } + // if(is_recovery_running){ + // ESP_LOGD(TAG, "Processing autoexec commands in recovery mode. Squeezelite commands will be ignored."); + // } + // if(str_flag !=NULL ){ + // autoexec_flag=atoi(str_flag); + // ESP_LOGI(TAG,"autoexec is set to %s auto-process", autoexec_flag>0?"perform":"skip"); + // if(autoexec_flag == 1) { + // do { + // snprintf(autoexec_name,sizeof(autoexec_name)-1,"autoexec%u",i++); + // ESP_LOGD(TAG,"Getting command name %s", autoexec_name); + // autoexec_value= config_alloc_get(NVS_TYPE_STR, autoexec_name); + // if(autoexec_value!=NULL ){ + // if(!bypass_network_manager && strstr(autoexec_value, "join ")!=NULL ){ + // ESP_LOGW(TAG,"Ignoring wifi join command."); + // } + // else if(is_recovery_running && !strstr(autoexec_value, "squeezelite " ) ){ + // ESP_LOGW(TAG,"Ignoring command. "); + // } + // else { + // ESP_LOGI(TAG,"Running command %s = %s", autoexec_name, autoexec_value); + // run_command(autoexec_value); + // } + // ESP_LOGD(TAG,"Freeing memory for command %s name", autoexec_name); + // free(autoexec_value); + // } + // else { + // ESP_LOGD(TAG,"No matching command found for name %s", autoexec_name); + // break; + // } + // } while(1); + // } + // free(str_flag); + + // } + // else + // { + // ESP_LOGD(TAG,"No matching command found for name autoexec."); + // } + // TODO: Add support for the commented code } static ssize_t stdin_read(int fd, void* data, size_t size) { @@ -373,11 +379,7 @@ void console_start() { MEMTRACE_PRINT_DELTA_MESSAGE("Registering wifi commands"); register_wifi(); - if(!is_recovery_running){ - MEMTRACE_PRINT_DELTA_MESSAGE("Registering squeezelite commands"); - register_squeezelite(); - } - else { + if(is_recovery_running){ MEMTRACE_PRINT_DELTA_MESSAGE("Registering recovery commands"); register_ota_cmd(); } diff --git a/components/platform_console/platform_console.h b/components/platform_console/platform_console.h index e82669b5..527591f9 100644 --- a/components/platform_console/platform_console.h +++ b/components/platform_console/platform_console.h @@ -22,7 +22,6 @@ typedef cJSON * parm_values_fn_t(void); esp_err_t cmd_to_json(const esp_console_cmd_t *cmd); esp_err_t cmd_to_json_with_cb(const esp_console_cmd_t *cmd, parm_values_fn_t parm_values_fn); int arg_parse_msg(int argc, char **argv, struct arg_hdr ** args); -void console_set_bool_parameter(cJSON * root,char * nvs_name, struct arg_lit *arg); cJSON * get_cmd_list(); #ifdef __cplusplus } diff --git a/components/platform_console/test/test_system.c b/components/platform_console/test/test_system.c index 0cde9412..3ff2ab86 100644 --- a/components/platform_console/test/test_system.c +++ b/components/platform_console/test/test_system.c @@ -11,7 +11,8 @@ #include "unity.h" #include "platform_console.h" #include "platform_esp32.h" -#include "platform_config.h" +// #include "Configurator.h" +#pragma message("fixme: search for TODO below") #include "string.h" struct arg_lit *arglit; struct arg_int *argint; diff --git a/components/raop/raop_sink.c b/components/raop/raop_sink.c index e5fe0fb1..fb8418d9 100644 --- a/components/raop/raop_sink.c +++ b/components/raop/raop_sink.c @@ -3,14 +3,13 @@ #include #include -#include "nvs.h" #include "esp_netif.h" #include "esp_log.h" #include "esp_console.h" #include "esp_pthread.h" #include "esp_system.h" #include "freertos/timers.h" -#include "platform_config.h" +#include "Configurator.h" #include "raop.h" #include "audio_controls.h" #include "display.h" @@ -168,7 +167,8 @@ static void raop_sink_start(nm_state_t state_id, int sub_state) { esp_netif_t* netif; esp_netif_ip_info_t ipInfo = { }; uint8_t mac[6]; - char* sink_name = (char*) config_alloc_get_default(NVS_TYPE_STR, "airplay_name", CONFIG_AIRPLAY_NAME, 0); + char* sink_name = strlen(platform->names.airplay)>0?platform->names.airplay:platform->names.device; + netif = network_get_active_interface(); esp_netif_get_ip_info(netif, &ipInfo); @@ -177,7 +177,6 @@ static void raop_sink_start(nm_state_t state_id, int sub_state) { LOG_INFO( "starting Airplay for ip %s with servicename %s", inet_ntoa(ipInfo.ip.addr), sink_name); raop = raop_create(ipInfo.ip.addr, sink_name, mac, 0, cmd_handler, raop_cbs.data); - free(sink_name); } /**************************************************************************************** diff --git a/components/services/accessors.c b/components/services/accessors.c index fab030d8..d650207e 100644 --- a/components/services/accessors.c +++ b/components/services/accessors.c @@ -5,13 +5,15 @@ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG #include #include "esp_log.h" #include "driver/gpio.h" #include "driver/i2c.h" #include "driver/spi_master.h" -#include "platform_config.h" +// #include "Configurator.h" +#pragma message("fixme: look for TODO below") #include "accessors.h" #include "globdefs.h" #include "display.h" @@ -59,20 +61,22 @@ bool are_statistics_enabled(){ /**************************************************************************************** * */ -static char * config_spdif_get_string(){ - return config_alloc_get_str("spdif_config", CONFIG_SPDIF_CONFIG, "bck=" STR(CONFIG_SPDIF_BCK_IO) - ",ws=" STR(CONFIG_SPDIF_WS_IO) ",do=" STR(CONFIG_SPDIF_DO_IO)); -} +// static char * config_spdif_get_string(){ +// // return config_alloc_get_str("spdif_config", CONFIG_SPDIF_CONFIG, "bck=" STR(CONFIG_SPDIF_BCK_IO) +// // ",ws=" STR(CONFIG_SPDIF_WS_IO) ",do=" STR(CONFIG_SPDIF_DO_IO)); +// config_alloc_get_str("spdif_config", CONFIG_SPDIF_CONFIG, "bck=" STR(CONFIG_SPDIF_BCK_IO) +// ",ws=" STR(CONFIG_SPDIF_WS_IO) ",do=" STR(CONFIG_SPDIF_DO_IO)); +// } /**************************************************************************************** * */ -static char * get_dac_config_string(){ - return config_alloc_get_str("dac_config", CONFIG_DAC_CONFIG, "model=i2s,bck=" STR(CONFIG_I2S_BCK_IO) - ",ws=" STR(CONFIG_I2S_WS_IO) ",do=" STR(CONFIG_I2S_DO_IO) - ",sda=" STR(CONFIG_I2C_SDA) ",scl=" STR(CONFIG_I2C_SCL) - ",mute=" STR(CONFIG_MUTE_GPIO)); -} +// static char * get_dac_config_string(){ +// return config_alloc_get_str("dac_config", CONFIG_DAC_CONFIG, "model=i2s,bck=" STR(CONFIG_I2S_BCK_IO) +// ",ws=" STR(CONFIG_I2S_WS_IO) ",do=" STR(CONFIG_I2S_DO_IO) +// ",sda=" STR(CONFIG_I2C_SDA) ",scl=" STR(CONFIG_I2C_SCL) +// ",mute=" STR(CONFIG_MUTE_GPIO)); +// } /**************************************************************************************** * @@ -89,453 +93,13 @@ bool is_dac_config_locked(){ return false; } -/**************************************************************************************** - * - */ -bool is_spdif_config_locked(){ -#if ( defined CONFIG_SPDIF_CONFIG ) - if(strlen(CONFIG_SPDIF_CONFIG) > 0){ - return true; - } -#endif -#if defined(CONFIG_SPDIF_BCK_IO) && CONFIG_SPDIF_BCK_IO>0 - return true; -#endif - return false; -} -/**************************************************************************************** - * Set pin from config string - */ -static void set_i2s_pin(char *config, i2s_pin_config_t *pin_config) { - pin_config->bck_io_num = pin_config->ws_io_num = pin_config->data_out_num = pin_config->data_in_num = -1; - PARSE_PARAM(config, "bck", '=', pin_config->bck_io_num); - PARSE_PARAM(config, "ws", '=', pin_config->ws_io_num); - PARSE_PARAM(config, "do", '=', pin_config->data_out_num); -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) - pin_config->mck_io_num = strcasestr(config, "mck") ? 0 : -1; - PARSE_PARAM(config, "mck", '=', pin_config->mck_io_num); -#endif -} - -/**************************************************************************************** - * Get i2s config structure from config string - */ -const i2s_platform_config_t * config_i2s_get_from_str(char * dac_config ){ - static EXT_RAM_ATTR i2s_platform_config_t i2s_dac_pin; - memset(&i2s_dac_pin, 0xff, sizeof(i2s_dac_pin)); - set_i2s_pin(dac_config, &i2s_dac_pin.pin); - strcpy(i2s_dac_pin.model, "i2s"); - char * p=NULL; - - PARSE_PARAM(dac_config, "i2c", '=', i2s_dac_pin.i2c_addr); - PARSE_PARAM(dac_config, "sda", '=', i2s_dac_pin.sda); - PARSE_PARAM(dac_config, "scl", '=', i2s_dac_pin.scl); - PARSE_PARAM_STR(dac_config, "model", '=', i2s_dac_pin.model, 31); - if ((p = strcasestr(dac_config, "mute"))) { - char mute[8] = ""; - sscanf(p, "%*[^=]=%7[^,]", mute); - i2s_dac_pin.mute_gpio = atoi(mute); - PARSE_PARAM(p, "mute", ':', i2s_dac_pin.mute_level); - } - return &i2s_dac_pin; -} - -/**************************************************************************************** - * Get eth config structure from config string - */ -const eth_config_t * config_eth_get_from_str(char* config ){ - static EXT_RAM_ATTR eth_config_t eth_config; - eth_config.rst = eth_config.intr = -1; - - PARSE_PARAM_STR(config, "model", '=', eth_config.model, 15); - PARSE_PARAM(config, "rst", '=', eth_config.rst); - // RMII - PARSE_PARAM(config, "mdc", '=', eth_config.mdc); - PARSE_PARAM(config, "mdio", '=', eth_config.mdio); - // SPI - PARSE_PARAM(config, "intr", '=', eth_config.intr); - PARSE_PARAM(config, "cs", '=', eth_config.cs); - PARSE_PARAM(config, "speed", '=', eth_config.speed); - /* not used as SPI must be shared - PARSE_PARAM(config, "mosi", '=', eth_config.mosi); - PARSE_PARAM(config, "miso", '=', eth_config.miso); - PARSE_PARAM(config, "clk", '=', eth_config.clk); - PARSE_PARAM(config, "host", '=', eth_config.host); - */ - - // only system host is available - eth_config.host = spi_system_host; - eth_config.valid = true; - - if(!eth_config.model || strlen(eth_config.model)==0){ - eth_config.valid = false; - return ð_config; - } - - network_ethernet_driver_t* network_driver = network_ethernet_driver_autodetect(eth_config.model); - - if(!network_driver || !network_driver->valid){ - messaging_post_message(MESSAGING_ERROR,MESSAGING_CLASS_SYSTEM,"Ethernet config invalid: model %s %s",eth_config.model,network_driver?"was not compiled in":"was not found"); - eth_config.valid = false; - } - - if(network_driver){ - eth_config.rmii = network_driver->rmii; - eth_config.spi = network_driver->spi; - - if(network_driver->rmii){ - if(!GPIO_IS_VALID_GPIO(eth_config.mdio) || !GPIO_IS_VALID_GPIO(eth_config.mdc)){ - messaging_post_message(MESSAGING_ERROR,MESSAGING_CLASS_SYSTEM,"Ethernet config invalid: %s %s",!GPIO_IS_VALID_GPIO(eth_config.mdc)?"Invalid MDC":"",!GPIO_IS_VALID_GPIO(eth_config.mdio)?"Invalid mdio":""); - eth_config.valid = false; - } - } - else if(network_driver->spi){ - if(!GPIO_IS_VALID_GPIO(eth_config.cs)){ - messaging_post_message(MESSAGING_ERROR,MESSAGING_CLASS_SYSTEM,"Ethernet config invalid: invalid CS pin"); - return false; - } - } - } - return ð_config; -} - -/**************************************************************************************** - * Get spdif config structure - */ -const i2s_platform_config_t * config_spdif_get( ){ - char * spdif_config = config_spdif_get_string(); - static EXT_RAM_ATTR i2s_platform_config_t i2s_dac_config; - memcpy(&i2s_dac_config, config_i2s_get_from_str(spdif_config), sizeof(i2s_dac_config)); - free(spdif_config); - return &i2s_dac_config; -} - -/**************************************************************************************** - * Get dac config structure - */ -const i2s_platform_config_t * config_dac_get(){ - char * spdif_config = get_dac_config_string(); - static EXT_RAM_ATTR i2s_platform_config_t i2s_dac_config; - memcpy(&i2s_dac_config, config_i2s_get_from_str(spdif_config), sizeof(i2s_dac_config)); - free(spdif_config); - return &i2s_dac_config; -} - -/**************************************************************************************** - * Get ethernet config structure - */ -const eth_config_t * config_eth_get( ){ - char * config = config_alloc_get_str("eth_config", CONFIG_ETH_CONFIG, "rst=" STR(CONFIG_ETH_PHY_RST_IO) - -#if defined(ETH_LAN8720) -#else -#if defined(CONFIG_ETH_USE_SPI_ETHERNET) -#if defined(CONFIG_ETH_DM9051) - ",model=dm9051" -#elif defined(CONFIG_ETH_W5500) - ",model=w5500" -#endif - ",host=" STR(CONFIG_ETH_SPI_HOST) ",cs=" STR(CONFIG_ETH_SPI_CS_IO) - ",mosi=" STR(CONFIG_ETH_SPI_MOSI_IO) ",miso=" STR(CONFIG_ETH_SPI_MISO_IO) - ",intr=" STR(CONFIG_ETH_SPI_INTR_IO) - ",clk=" STR(CONFIG_ETH_SPI_CLK_IO) ",speed=" STR(CONFIG_ETH_SPI_SPEED) - -#elif defined(CONFIG_ETH_PHY_INTERFACE_RMII) - ",model=lan8720, tx_en=21, tx0=19, tx1=22, rx0=25, rx1=26, crs_dv=27" -#endif -#endif - ",mdc=" STR(CONFIG_ETH_MDC_IO) ",mdio=" STR(CONFIG_ETH_MDIO_IO)) ; - if(config && strlen(config)>0){ - ESP_LOGD(TAG,"Parsing ethernet configuration %s", config); - } - static EXT_RAM_ATTR eth_config_t eth_config; - memcpy(ð_config, config_eth_get_from_str(config), sizeof(eth_config)); - FREE_AND_NULL(config); - return ð_config; -} -/**************************************************************************************** - * Get ethernet config structure and assign to eth config structure - */ -void config_eth_init( eth_config_t * target ){ - const eth_config_t * source = config_eth_get(); - memcpy(target,source,sizeof(eth_config_t)); -} - -/**************************************************************************************** - * - */ -esp_err_t config_i2c_set(const i2c_config_t * config, int port){ - int buffer_size=255; - esp_err_t err=ESP_OK; - char * config_buffer=malloc_init_external(buffer_size); - if(config_buffer) { - snprintf(config_buffer,buffer_size,"scl=%u,sda=%u,speed=%u,port=%u",config->scl_io_num,config->sda_io_num,config->master.clk_speed,port); - log_send_messaging(MESSAGING_INFO,"Updating I2C configuration to %s",config_buffer); - err = config_set_value(NVS_TYPE_STR, "i2c_config", config_buffer); - if(err!=ESP_OK){ - log_send_messaging(MESSAGING_ERROR,"Error: %s",esp_err_to_name(err)); - } - free(config_buffer); - } - return err; -} - -/**************************************************************************************** - * - */ -esp_err_t config_rotary_set(rotary_struct_t * config){ - int buffer_size=512; - esp_err_t err=ESP_OK; - char * config_buffer=malloc_init_external(buffer_size); - char * config_buffer2=malloc_init_external(buffer_size); - if(config_buffer && config_buffer2) { - snprintf(config_buffer,buffer_size,"A=%i,B=%i",config->A, config->B); - if(config->SW >=0 ){ - snprintf(config_buffer2,buffer_size,"%s,SW=%i",config_buffer,config->SW); - strcpy(config_buffer,config_buffer2); - } - if(config->knobonly){ - strncat(config_buffer,",knobonly",buffer_size); - if(config->timer>0){ - snprintf(config_buffer2,buffer_size,"%s=%i",config_buffer,config->timer); - strcpy(config_buffer,config_buffer2); - } - } - if(config->volume_lock){ - strncat(config_buffer,",volume",buffer_size); - } - if(config->longpress){ - strncat(config_buffer,",longpress",buffer_size); - } - log_send_messaging(MESSAGING_INFO,"Updating rotary configuration to %s",config_buffer); - err = config_set_value(NVS_TYPE_STR, "rotary_config", config_buffer); - if(err!=ESP_OK){ - log_send_messaging(MESSAGING_ERROR,"Error: %s",esp_err_to_name(err)); - } - } - else { - err = ESP_ERR_NO_MEM; - } - FREE_AND_NULL(config_buffer); - FREE_AND_NULL(config_buffer2); - return err; -} - -/**************************************************************************************** - * - */ -esp_err_t config_ledvu_set(ledvu_struct_t * config){ - int buffer_size=512; - esp_err_t err=ESP_OK; - char * config_buffer=malloc_init_external(buffer_size); - if(config_buffer) { - snprintf(config_buffer,buffer_size,"%s,length=%i,gpio=%i",config->type, config->length, config->gpio); - log_send_messaging(MESSAGING_INFO,"Updating ledvu configuration to %s",config_buffer); - err = config_set_value(NVS_TYPE_STR, "led_vu_config", config_buffer); - if(err!=ESP_OK){ - log_send_messaging(MESSAGING_ERROR,"Error: %s",esp_err_to_name(err)); - } - } - else { - err = ESP_ERR_NO_MEM; - } - FREE_AND_NULL(config_buffer); - return err; -} - -/**************************************************************************************** - * - */ -esp_err_t config_display_set(const display_config_t * config){ - int buffer_size=512; - esp_err_t err=ESP_OK; - char * config_buffer=malloc_init_external(buffer_size); - char * config_buffer2=malloc_init_external(buffer_size); - if(config_buffer && config_buffer2) { - snprintf(config_buffer,buffer_size,"%s,width=%i,height=%i",config->type,config->width,config->height); - if(strcasecmp("I2C",config->type)==0){ - if(config->address>0 ){ - snprintf(config_buffer2,buffer_size,"%s,address=%i",config_buffer,config->address); - strcpy(config_buffer,config_buffer2); - } - } - else { - if(config->CS_pin >=0 ){ - snprintf(config_buffer2,buffer_size,"%s,cs=%i",config_buffer,config->CS_pin); - strcpy(config_buffer,config_buffer2); - } - } - if(config->RST_pin >=0 ){ - snprintf(config_buffer2,buffer_size,"%s,reset=%i",config_buffer,config->RST_pin); - strcpy(config_buffer,config_buffer2); - } -// I2C,width=,height=[address=][,reset=][,HFlip][,VFlip][driver=SSD1306|SSD1326[:1|4]|SSD1327|SH1106] -// SPI,width=,height=,cs=[,back=][,reset=][,speed=][,HFlip][,VFlip][driver=SSD1306|SSD1322|SSD1326[:1|4]|SSD1327|SH1106|SSD1675|ST7735|ST7789[,rotate]] - if(config->back >=0 ){ - snprintf(config_buffer2,buffer_size,"%s,back=%i",config_buffer,config->back); - strcpy(config_buffer,config_buffer2); - } - if(config->speed >0 && strcasecmp("SPI",config->type)==0){ - snprintf(config_buffer2,buffer_size,"%s,speed=%i",config_buffer,config->speed); - strcpy(config_buffer,config_buffer2); - } - if(config->mode >=0 && strcasecmp("SPI",config->type)==0){ - snprintf(config_buffer2,buffer_size,"%s,mode=%i",config_buffer,config->mode); - strcpy(config_buffer,config_buffer2); - } - snprintf(config_buffer2,buffer_size,"%s,driver=%s%s%s%s",config_buffer,config->drivername,config->hflip?",HFlip":"",config->vflip?",VFlip":"",config->rotate?",rotate":""); - strcpy(config_buffer,config_buffer2); - log_send_messaging(MESSAGING_INFO,"Updating display configuration to %s",config_buffer); - err = config_set_value(NVS_TYPE_STR, "display_config", config_buffer); - if(err!=ESP_OK){ - log_send_messaging(MESSAGING_ERROR,"Error: %s",esp_err_to_name(err)); - } - } - else { - err = ESP_ERR_NO_MEM; - } - FREE_AND_NULL(config_buffer); - FREE_AND_NULL(config_buffer2); - return err; -} - -/**************************************************************************************** - * - */ -esp_err_t config_i2s_set(const i2s_platform_config_t * config, const char * nvs_name){ - int buffer_size=255; - esp_err_t err=ESP_OK; - char * config_buffer=malloc_init_external(buffer_size); - char * config_buffer2=malloc_init_external(buffer_size); - if(config_buffer && config_buffer2) { - snprintf(config_buffer,buffer_size,"model=%s,bck=%u,ws=%u,do=%u",config->model,config->pin.bck_io_num,config->pin.ws_io_num,config->pin.data_out_num); - if(config->mute_gpio>=0){ - snprintf(config_buffer2,buffer_size,"%s,mute=%u:%u",config_buffer,config->mute_gpio,config->mute_level); - strcpy(config_buffer,config_buffer2); - } - if(config->sda>=0){ - snprintf(config_buffer2,buffer_size,"%s,sda=%u,scl=%u",config_buffer,config->sda,config->scl); - strcpy(config_buffer,config_buffer2); - } - if(config->i2c_addr>0){ - snprintf(config_buffer2,buffer_size,"%s,i2c=%u",config_buffer,config->i2c_addr); - strcpy(config_buffer,config_buffer2); - } - log_send_messaging(MESSAGING_INFO,"Updating dac configuration to %s",config_buffer); - err = config_set_value(NVS_TYPE_STR, nvs_name, config_buffer); - if(err!=ESP_OK){ - log_send_messaging(MESSAGING_ERROR,"Error: %s",esp_err_to_name(err)); - } - } - else { - err = ESP_ERR_NO_MEM; - } - FREE_AND_NULL(config_buffer); - FREE_AND_NULL(config_buffer2); - return err; -} - -/**************************************************************************************** - * - */ -esp_err_t config_spdif_set(const i2s_platform_config_t * config){ - int buffer_size=255; - esp_err_t err=ESP_OK; - char * config_buffer=malloc_init_external(buffer_size); - if(config_buffer ) { - snprintf(config_buffer,buffer_size,"bck=%u,ws=%u,do=%u",config->pin.bck_io_num,config->pin.ws_io_num,config->pin.data_out_num); - log_send_messaging(MESSAGING_INFO,"Updating SPDIF configuration to %s",config_buffer); - err = config_set_value(NVS_TYPE_STR, "spdif_config", config_buffer); - if(err!=ESP_OK){ - log_send_messaging(MESSAGING_ERROR,"Error: %s",esp_err_to_name(err)); - } - } - else { - err = ESP_ERR_NO_MEM; - } - FREE_AND_NULL(config_buffer); - return err; -} - -/**************************************************************************************** - * - */ -esp_err_t config_spi_set(const spi_bus_config_t * config, int host, int dc){ - int buffer_size=255; - esp_err_t err = ESP_OK; - char * config_buffer=malloc_init_external(buffer_size); - if(config_buffer) { - snprintf(config_buffer,buffer_size,"data=%u,clk=%u,dc=%u,host=%u,miso=%d",config->mosi_io_num,config->sclk_io_num,dc,host,config->miso_io_num); - log_send_messaging(MESSAGING_INFO,"Updating SPI configuration to %s",config_buffer); - err = config_set_value(NVS_TYPE_STR, "spi_config", config_buffer); - if(err!=ESP_OK){ - log_send_messaging(MESSAGING_ERROR,"Error: %s",esp_err_to_name(err)); - } - free(config_buffer); - } - return err; -} - -/**************************************************************************************** - * - */ -const display_config_t * config_display_get(){ - static display_config_t dstruct = { - .back = -1, - .CS_pin = -1, - .RST_pin = -1, - .depth = -1, - .address = 0, - .drivername = NULL, - .height = 0, - .width = 0, - .vflip = false, - .hflip = false, - .type = NULL, - .speed = 0, - .rotate = false, - .invert = false, - .colorswap = 0, - .mode = 0, - }; - char *config = config_alloc_get(NVS_TYPE_STR, "display_config"); - if (!config) { - return NULL; - } - - char * p=NULL; - - if ((p = strcasestr(config, "driver")) != NULL){ - sscanf(p, "%*[^:]:%u", &dstruct.depth); - dstruct.drivername = display_conf_get_driver_name(strchr(p, '=') + 1); - } - - PARSE_PARAM(config, "width", '=', dstruct.width); - PARSE_PARAM(config, "height", '=', dstruct.height); - PARSE_PARAM(config, "reset", '=', dstruct.RST_pin); - PARSE_PARAM(config, "address", '=', dstruct.address); - PARSE_PARAM(config, "cs", '=', dstruct.CS_pin); - PARSE_PARAM(config, "speed", '=', dstruct.speed); - PARSE_PARAM(config, "back", '=', dstruct.back); - PARSE_PARAM(config, "mode", '=', dstruct.mode); - - if (strstr(config, "I2C") ) dstruct.type=i2c_name_type; - if (strstr(config, "SPI") ) dstruct.type=spi_name_type; - - dstruct.hflip= strcasestr(config, "HFlip") ? true : false; - dstruct.vflip= strcasestr(config, "VFlip") ? true : false; - dstruct.rotate= strcasestr(config, "rotate") ? true : false; - dstruct.invert= strcasestr(config, "invert") ? true : false; - dstruct.colorswap= strcasestr(config, "cswap") ? 1 : 0; - return &dstruct; -} /**************************************************************************************** * */ const i2c_config_t * config_i2c_get(int * i2c_port) { - char *nvs_item; + sys_I2CBus * bus = NULL; static i2c_config_t i2c = { .mode = I2C_MODE_MASTER, .sda_io_num = -1, @@ -545,152 +109,54 @@ const i2c_config_t * config_i2c_get(int * i2c_port) { .master.clk_speed = 0, }; - i2c.master.clk_speed = i2c_system_speed; - - nvs_item = config_alloc_get(NVS_TYPE_STR, "i2c_config"); - if (nvs_item) { - PARSE_PARAM(nvs_item, "scl", '=', i2c.scl_io_num); - PARSE_PARAM(nvs_item, "sda", '=', i2c.sda_io_num); - PARSE_PARAM(nvs_item, "speed", '=', i2c.master.clk_speed); - PARSE_PARAM(nvs_item, "port", '=', i2c_system_port); - free(nvs_item); - } - if(i2c_port) { -#ifdef CONFIG_I2C_LOCKED - *i2c_port= I2C_NUM_1; -#else - *i2c_port=i2c_system_port; -#endif + if(SYS_I2CBUS(bus)){ + if(bus->has_scl){ + i2c.scl_io_num = bus->scl.pin; + } + else { + ESP_LOGE(TAG,"%s missing for i2c","SCL"); + } + + if(bus->has_sda){ + i2c.sda_io_num= bus->sda.pin; + } + else { + ESP_LOGE(TAG,"%s missing for i2c","SDA"); + } + if(bus->speed>0){ + i2c.master.clk_speed = bus->speed; + } + if(bus->port != sys_I2CPortEnum_UNSPECIFIED_PORT){ + i2c_system_port = bus->port - sys_I2CPortEnum_I2CPort0; + } + // TODO: untangle i2c system port handling + if(i2c_port) { + *i2c_port=i2c_system_port; + } + } + return &i2c; } -/**************************************************************************************** - * Get IO expander config structure from config string - */ -const gpio_exp_config_t* config_gpio_exp_get(int index) { - char *nvs_item, *item, *p; - static gpio_exp_config_t config; - // re-initialize config every time - memset(&config, 0, sizeof(config)); - config.intr = -1; config.count = 16; config.base = GPIO_NUM_MAX; config.phy.port = i2c_system_port; config.phy.host = spi_system_host; - - nvs_item = config_alloc_get(NVS_TYPE_STR, "gpio_exp_config"); - if (!nvs_item || !*nvs_item) return NULL; - - // search index items - for (item = strtok(nvs_item, ";"); index && item; index--) { - if ((item = strtok(NULL, ";")) == NULL) { - free(nvs_item); - return NULL; - } +void config_set_gpio(int * pin, sys_GPIO * gpio,bool has_value, const char * name, bool mandatory){ + if(has_value){ + ESP_LOGD(TAG, "Setting pin %d as %s", gpio->pin, name); + if(pin) *pin= gpio->pin; } - - PARSE_PARAM(item, "addr", '=', config.phy.addr); - PARSE_PARAM(item, "cs", '=', config.phy.cs_pin); - PARSE_PARAM(item, "speed", '=', config.phy.speed); - PARSE_PARAM(item, "intr", '=', config.intr); - PARSE_PARAM(item, "base", '=', config.base); - PARSE_PARAM(item, "count", '=', config.count); - PARSE_PARAM_STR(item, "model", '=', config.model, sizeof(config.model)-1); - - if ((p = strcasestr(item, "port")) != NULL) { - char port[8] = ""; - sscanf(p, "%*[^=]=%7[^,]", port); - if (strcasestr(port, "dac")) config.phy.port = 0; - } - - free(nvs_item); - return &config; -} - -/**************************************************************************************** - * - */ -const gpio_with_level_t * get_gpio_struct_member(const char * nvs_item, const char * name){ - static gpio_with_level_t gpio_member={ - .gpio=-1, - .level=0 - }; - if(!nvs_item) return &gpio_member; - const char * p=nvs_item; - char type[20]={0}; - int match=0; - do { - if ((match=sscanf(p, "%d=%19[^,:]:%d", &gpio_member.gpio, type,&gpio_member.level)) >0 && (GPIO_IS_VALID_GPIO(gpio_member.gpio) || gpio_member.gpio==GPIO_NUM_NC) && strcasestr(type,name)){ - return &gpio_member; - } - p = strchr(p, ','); - } while (p++); - gpio_member.gpio=-1; - gpio_member.level=0; - return &gpio_member; -} - -#define HANDLE_GPIO_STRUCT_MEMBER(name,fixval) memcpy(&gpio_struct.name, get_gpio_struct_member(nvs_item, QUOTE(name)), sizeof(gpio_struct.name)); gpio_struct.name.fixed=fixval -#define ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(array,structvar,name,type) if(((set_GPIO_struct_t *)structvar)->name.gpio>=0){cJSON_AddItemToArray(array,get_gpio_entry(QUOTE(name),type,((set_GPIO_struct_t *)structvar)->name.gpio, ((set_GPIO_struct_t *)structvar)->name.fixed));} -/**************************************************************************************** - * - */ -const set_GPIO_struct_t * get_gpio_struct(){ - static set_GPIO_struct_t gpio_struct; - char * nvs_item=config_alloc_get(NVS_TYPE_STR, "set_GPIO"); -#ifdef CONFIG_LED_GREEN_GPIO_LEVEL - gpio_struct.green.level = CONFIG_LED_GREEN_GPIO_LEVEL; -#endif -#ifdef CONFIG_LED_GREEN_GPIO - gpio_struct.green.gpio = CONFIG_LED_GREEN_GPIO; -#endif -#ifdef CONFIG_LED_RED_GPIO_LEVEL - gpio_struct.green.level = CONFIG_LED_RED_GPIO_LEVEL; -#endif -#ifdef CONFIG_LED_RED_GPIO - gpio_struct.red.gpio = CONFIG_LED_RED_GPIO; -#endif -#if defined(CONFIG_POWER_GPIO) && CONFIG_POWER_GPIO != -1 - gpio_struct.power.gpio = CONFIG_POWER_GPIO; -#endif -#ifdef CONFIG_POWER_GPIO_LEVEL - gpio_struct.power.level = CONFIG_POWER_GPIO_LEVEL; -#endif - if(nvs_item){ - HANDLE_GPIO_STRUCT_MEMBER(amp,false); -#ifndef CONFIG_LED_LOCKED - HANDLE_GPIO_STRUCT_MEMBER(green,false); - HANDLE_GPIO_STRUCT_MEMBER(red,false); -#endif - HANDLE_GPIO_STRUCT_MEMBER(jack,false); - HANDLE_GPIO_STRUCT_MEMBER(spkfault,false); - HANDLE_GPIO_STRUCT_MEMBER(vcc,false); - HANDLE_GPIO_STRUCT_MEMBER(gnd,false); - HANDLE_GPIO_STRUCT_MEMBER(ir,false); - HANDLE_GPIO_STRUCT_MEMBER(power,false); - free(nvs_item); + else if(mandatory) { + ESP_LOGE(TAG,"Pin %s has no value",name); + } + else { + ESP_LOGD(TAG,"Pin %s has no value",name); } - -#ifdef CONFIG_LED_LOCKED - gpio_struct.red.fixed=true; - gpio_struct.green.fixed=true; -#endif -#ifdef CONFIG_JACK_LOCKED - gpio_struct.jack.gpio=CONFIG_JACK_GPIO; - gpio_struct.jack.fixed=true; - gpio_struct.jack.level=CONFIG_JACK_GPIO_LEVEL; -#endif -#ifdef CONFIG_SPKFAULT_LOCKED - gpio_struct.spkfault.gpio=CONFIG_SPKFAULT_GPIO; - gpio_struct.spkfault.fixed=true; - gpio_struct.spkfault.level=CONFIG_SPKFAULT_GPIO_LEVEL; -#endif - return &gpio_struct; } /**************************************************************************************** * */ const spi_bus_config_t * config_spi_get(spi_host_device_t * spi_host) { - char *nvs_item; // don't memset all to 0xff as it's more than just GPIO static spi_bus_config_t spi = { .mosi_io_num = -1, @@ -699,516 +165,21 @@ const spi_bus_config_t * config_spi_get(spi_host_device_t * spi_host) { .quadwp_io_num = -1, .quadhd_io_num = -1 }; - - nvs_item = config_alloc_get_str("spi_config", CONFIG_SPI_CONFIG, NULL); - if (nvs_item) { - PARSE_PARAM(nvs_item, "data", '=', spi.mosi_io_num); - PARSE_PARAM(nvs_item, "mosi", '=', spi.mosi_io_num); - PARSE_PARAM(nvs_item, "miso", '=', spi.miso_io_num); - PARSE_PARAM(nvs_item, "clk", '=', spi.sclk_io_num); - PARSE_PARAM(nvs_item, "dc", '=', spi_system_dc_gpio); + if(platform->has_dev && platform->dev.has_spi){ + ESP_LOGI(TAG,"SPI Configuration found"); + ASSIGN_GPIO(spi.mosi_io_num,platform->dev.spi,mosi,true); + ASSIGN_GPIO(spi.miso_io_num,platform->dev.spi,miso,false); + ASSIGN_GPIO(spi.sclk_io_num,platform->dev.spi,clk,true); + ASSIGN_GPIO(spi_system_dc_gpio,platform->dev.spi,dc,true); // only VSPI (1) can be used as Flash and PSRAM run at 80MHz - // if ((p = strcasestr(nvs_item, "host")) != NULL) spi_system_host = atoi(strchr(p, '=') + 1); - free(nvs_item); + if(platform->dev.spi.host!=sys_HostEnum_UNSPECIFIED_HOST){ + spi_system_host = platform->dev.spi.host; + } } - if(spi_host) *spi_host = spi_system_host; + else { + ESP_LOGI(TAG,"SPI not configured"); + } + + if(spi_host) *spi_host = spi_system_host; return &spi; } - -/**************************************************************************************** - * - */ -void parse_set_GPIO(void (*cb)(int gpio, char *value)) { - char *nvs_item, *p, type[16]; - int gpio; - - if ((nvs_item = config_alloc_get(NVS_TYPE_STR, "set_GPIO")) == NULL) return; - - p = nvs_item; - - do { - if (sscanf(p, "%d=%15[^,]", &gpio, type) > 0) cb(gpio, type); - p = strchr(p, ','); - } while (p++); - - free(nvs_item); -} - -/**************************************************************************************** - * - */ -const rotary_struct_t * config_rotary_get() { - - static rotary_struct_t rotary={ .A = -1, .B = -1, .SW = -1, .longpress = false, .knobonly=false,.timer=0,.volume_lock=false}; - char *config = config_alloc_get_default(NVS_TYPE_STR, "rotary_config", NULL, 0); - if (config && *config) { - char *p; - - // parse config - PARSE_PARAM(config, "A", '=', rotary.A); - PARSE_PARAM(config, "B", '=', rotary.B); - PARSE_PARAM(config, "SW", '=', rotary.SW); - if ((p = strcasestr(config, "knobonly")) != NULL) { - p = strchr(p, '='); - rotary.knobonly = true; - rotary.timer = p ? atoi(p + 1) : 350; - rotary.longpress = false; - } else { - rotary.knobonly = false; - rotary.timer = 0; - if ((p = strcasestr(config, "volume")) != NULL) rotary.volume_lock = true; - if ((p = strcasestr(config, "longpress")) != NULL) rotary.longpress = true; - } - free(config); - } - return &rotary; -} - -/**************************************************************************************** - * - */ -const ledvu_struct_t * config_ledvu_get() { - - static ledvu_struct_t ledvu={ .type = "WS2812", .gpio = -1, .length = 0}; - char *config = config_alloc_get_default(NVS_TYPE_STR, "led_vu_config", NULL, 0); - if (config && *config) { - char *p; - - // ToDo: Add code for future support of alternate led types - if ((p = strcasestr(config, "gpio")) != NULL) ledvu.gpio = atoi(strchr(p, '=') + 1); - if ((p = strcasestr(config, "length")) != NULL) ledvu.length = atoi(strchr(p, '=') + 1); - free(config); - } - return &ledvu; -} - -/**************************************************************************************** - * - */ -cJSON * get_gpio_entry(const char * name, const char * prefix, int gpio, bool fixed){ - cJSON * entry = cJSON_CreateObject(); - cJSON_AddNumberToObject(entry,"gpio",gpio); - cJSON_AddStringToObject(entry,"name",name); - cJSON_AddStringToObject(entry,"group",prefix); - cJSON_AddBoolToObject(entry,"fixed",fixed); - return entry; -} - -/**************************************************************************************** - * - */ -cJSON * add_gpio_for_value(cJSON * list,const char * name,int gpio, const char * prefix, bool fixed){ - cJSON * llist = list?list:cJSON_CreateArray(); - if(GPIO_IS_VALID_GPIO(gpio) && gpio>0){ - cJSON_AddItemToArray(llist,get_gpio_entry(name,prefix,gpio,fixed)); - } - return llist; -} - -/**************************************************************************************** - * - */ -cJSON * add_gpio_for_name(cJSON * list,const char * nvs_entry,const char * name, const char * prefix, bool fixed){ - cJSON * llist = list?list:cJSON_CreateArray(); - int gpioNum=0; - PARSE_PARAM(nvs_entry, name, '=', gpioNum); - if(gpioNum>=0){ - cJSON_AddItemToArray(llist,get_gpio_entry(name,prefix,gpioNum,fixed)); - } - return llist; -} - -/**************************************************************************************** - * - */ -cJSON * get_GPIO_nvs_list(cJSON * list) { - cJSON * ilist = list?list:cJSON_CreateArray(); - const set_GPIO_struct_t * gpios = get_gpio_struct(); - ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,vcc,"other"); - ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,gnd,"other"); - ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,amp,"other"); - ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,ir,"other"); - ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,jack,"other"); - ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,green,"other"); - ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,red,"other"); - ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,power,"other"); - ADD_GPIO_STRUCT_MEMBER_TO_ARRAY(ilist,gpios,spkfault,"other"); - return ilist; -} - -/**************************************************************************************** - * - */ -cJSON * get_DAC_GPIO(cJSON * list){ - cJSON * llist = list; - if(!llist){ - llist = cJSON_CreateArray(); - } - const i2s_platform_config_t * i2s_config= config_dac_get(); - if(i2s_config->pin.bck_io_num>=0){ - cJSON_AddItemToArray(llist,get_gpio_entry("bck","dac",i2s_config->pin.bck_io_num,is_dac_config_locked())); - cJSON_AddItemToArray(llist,get_gpio_entry("ws","dac",i2s_config->pin.ws_io_num,is_dac_config_locked())); - cJSON_AddItemToArray(llist,get_gpio_entry("do","dac",i2s_config->pin.data_out_num,is_dac_config_locked())); - if(i2s_config->sda>=0){ - cJSON_AddItemToArray(llist,get_gpio_entry("sda","dac",i2s_config->sda,is_dac_config_locked())); - cJSON_AddItemToArray(llist,get_gpio_entry("scl","dac",i2s_config->scl,is_dac_config_locked())); - } - if(i2s_config->mute_gpio>=0){ - cJSON_AddItemToArray(llist,get_gpio_entry("mute","dac",i2s_config->mute_gpio,is_dac_config_locked())); - } - } - return llist; -} - -/**************************************************************************************** - * - */ -cJSON * get_Display_GPIO(cJSON * list){ - cJSON * llist = list; - if(!llist){ - llist = cJSON_CreateArray(); - } - const display_config_t * config= config_display_get(); - if(config->back >=0){ - cJSON_AddItemToArray(llist,get_gpio_entry("backlight","display",config->back,false)); - } - if(config->CS_pin >=0){ - cJSON_AddItemToArray(llist,get_gpio_entry("CS","display",config->CS_pin,false)); - } - if(config->RST_pin >=0){ - cJSON_AddItemToArray(llist,get_gpio_entry("reset","display",config->RST_pin,false)); - } - return llist; -} -/**************************************************************************************** - * - */ -cJSON * get_I2C_GPIO(cJSON * list){ - cJSON * llist = list; - if(!llist){ - llist = cJSON_CreateArray(); - } - int port=0; - const i2c_config_t * i2c_config = config_i2c_get(&port); - if(i2c_config->scl_io_num>=0){ - cJSON_AddItemToArray(llist,get_gpio_entry("scl","i2c",i2c_config->scl_io_num,false)); - cJSON_AddItemToArray(llist,get_gpio_entry("sda","i2c",i2c_config->sda_io_num,false)); - } - return llist; -} - -/**************************************************************************************** - * - */ -cJSON * get_SPI_GPIO(cJSON * list){ - cJSON * llist = list; - if(!llist){ - llist = cJSON_CreateArray(); - } - spi_host_device_t spi_host; - const spi_bus_config_t * spi_config = config_spi_get(&spi_host); - - if(spi_config->miso_io_num>=0){ - cJSON_AddItemToArray(llist,get_gpio_entry("data","spi",spi_config->miso_io_num,false)); - cJSON_AddItemToArray(llist,get_gpio_entry("data","clk",spi_config->sclk_io_num,false)); - } - if(spi_system_dc_gpio>0){ - cJSON_AddItemToArray(llist,get_gpio_entry("data","dc",spi_system_dc_gpio,false)); - } - return llist; -} - -/**************************************************************************************** - * - */ -cJSON * get_eth_GPIO(cJSON * list){ - cJSON * llist = list; - if(!llist){ - llist = cJSON_CreateArray(); - } - spi_host_device_t spi_host; - const eth_config_t * eth_config = config_eth_get(&spi_host); - #if defined(CONFIG_ETH_CONFIG) - bool fixed = strlen(CONFIG_ETH_CONFIG)>0; - #else - bool fixed =false; - #endif - if(eth_config->valid ){ - add_gpio_for_value(llist,"mdc",eth_config->mdc,"ethernet",fixed); - add_gpio_for_value(llist,"rst",eth_config->rst,"ethernet",fixed); - add_gpio_for_value(llist,"mdio",eth_config->mdio,"ethernet",fixed); - if(eth_config->rmii){ - add_gpio_for_value(llist,"tx_en", 21,"ethernet",true); - add_gpio_for_value(llist,"tx0", 19 ,"ethernet",true); - add_gpio_for_value(llist,"tx1", 22 ,"ethernet",true); - add_gpio_for_value(llist,"rx0", 25 ,"ethernet",true); - add_gpio_for_value(llist,"rx1", 26 ,"ethernet",true); - add_gpio_for_value(llist,"crs_dv",27 ,"ethernet",true); - } - else if(eth_config->spi) { - /* SPI ethernet */ - add_gpio_for_value(llist,"cs",eth_config->cs,"ethernet",fixed); - add_gpio_for_value(llist,"mosi",eth_config->mosi,"ethernet",fixed); - add_gpio_for_value(llist,"miso",eth_config->miso,"ethernet",fixed); - add_gpio_for_value(llist,"intr",eth_config->intr,"ethernet",fixed); - add_gpio_for_value(llist,"clk",eth_config->clk,"ethernet",fixed); - } - } - return llist; -} - - -/**************************************************************************************** - * - */ -cJSON * get_SPDIF_GPIO(cJSON * list, bool fixed){ - cJSON * llist = list?list:cJSON_CreateArray(); - char * spdif_config = config_spdif_get_string(); - if(spdif_config){ - llist = add_gpio_for_name(llist,spdif_config,"bck", "spdif", fixed); - llist = add_gpio_for_name(llist,spdif_config,"ws", "spdif", fixed); - llist = add_gpio_for_name(llist,spdif_config,"do", "spdif", fixed); - free(spdif_config); - } - return llist; -} - -/**************************************************************************************** - * - */ -cJSON * get_Rotary_GPIO(cJSON * list){ - cJSON * llist = list?list:cJSON_CreateArray(); - - const rotary_struct_t *rotary= config_rotary_get(); - add_gpio_for_value(llist,"A",rotary->A, "rotary", false); - add_gpio_for_value(llist,"B",rotary->B, "rotary", false); - add_gpio_for_value(llist,"SW",rotary->SW, "rotary", false); - return llist; -} - -/**************************************************************************************** - * - */ -cJSON * get_ledvu_GPIO(cJSON * list){ - cJSON * llist = list?list:cJSON_CreateArray(); - - const ledvu_struct_t *ledvu= config_ledvu_get(); - add_gpio_for_value(llist,"gpio",ledvu->gpio, "led_vu", false); - return llist; -} - -/**************************************************************************************** - * - */ -esp_err_t get_gpio_structure(cJSON * gpio_entry, gpio_entry_t ** gpio){ - esp_err_t err = ESP_OK; - *gpio = malloc_init_external(sizeof(gpio_entry_t)); - cJSON * val = cJSON_GetObjectItem(gpio_entry,"gpio"); - if(val){ - (*gpio)->gpio= (int)val->valuedouble; - } else { - ESP_LOGE(TAG,"gpio pin not found"); - err=ESP_FAIL; - } - val = cJSON_GetObjectItem(gpio_entry,"name"); - if(val){ - (*gpio)->name= strdup_psram(cJSON_GetStringValue(val)); - } else { - ESP_LOGE(TAG,"gpio name value not found"); - err=ESP_FAIL; - } - val = cJSON_GetObjectItem(gpio_entry,"group"); - if(val){ - (*gpio)->group= strdup_psram(cJSON_GetStringValue(val)); - } else { - ESP_LOGE(TAG,"gpio group value not found"); - err=ESP_FAIL; - } - val = cJSON_GetObjectItem(gpio_entry,"fixed"); - if(val){ - (*gpio)->fixed= cJSON_IsTrue(val); - } else { - ESP_LOGE(TAG,"gpio fixed indicator not found"); - err=ESP_FAIL; - } - - return err; -} - -/**************************************************************************************** - * - */ -esp_err_t free_gpio_entry( gpio_entry_t ** gpio) { - if(* gpio){ - free((* gpio)->name); - free((* gpio)->group); - free(* gpio); - * gpio=NULL; - return ESP_OK; - } - return ESP_FAIL; -} - -/**************************************************************************************** - * - */ -gpio_entry_t * get_gpio_by_no(int gpionum, bool refresh){ - cJSON * gpio_header=NULL; - gpio_entry_t * gpio=NULL; - get_gpio_list(refresh); - cJSON_ArrayForEach(gpio_header,gpio_list) - { - if(get_gpio_structure(gpio_header, &gpio)==ESP_OK && gpio->gpio==gpionum){ - ESP_LOGD(TAG,"Found GPIO: %s=%d %s", gpio->name,gpio->gpio,gpio->fixed?"(FIXED)":"(VARIABLE)"); - } - } - return gpio; -} - -/**************************************************************************************** - * - */ -gpio_entry_t * get_gpio_by_name(char * name,char * group, bool refresh){ - cJSON * gpio_header=NULL; - gpio_entry_t * gpio=NULL; - get_gpio_list(refresh); - cJSON_ArrayForEach(gpio_header,gpio_list) - { - if(get_gpio_structure(gpio_header, &gpio)==ESP_OK && strcasecmp(gpio->name,name)&& strcasecmp(gpio->group,group)){ - ESP_LOGD(TAG,"Found GPIO: %s=%d %s", gpio->name,gpio->gpio,gpio->fixed?"(FIXED)":"(VARIABLE)"); - } - } - return gpio; -} - -#ifndef PICO_PSRAM_CLK_IO -#define PICO_PSRAM_CLK_IO 6 -#endif -#ifndef PSRAM_SPIQ_SD0_IO -#define PSRAM_SPIQ_SD0_IO 7 -#define PSRAM_SPID_SD1_IO 8 -#define PSRAM_SPIWP_SD3_IO 10 -#define PSRAM_SPIHD_SD2_IO 9 -#define FLASH_HSPI_CLK_IO 14 -#define FLASH_HSPI_CS_IO 15 -#define PSRAM_HSPI_SPIQ_SD0_IO 12 -#define PSRAM_HSPI_SPID_SD1_IO 13 -#define PSRAM_HSPI_SPIWP_SD3_IO 2 -#define PSRAM_HSPI_SPIHD_SD2_IO 4 -#endif - - -cJSON * get_psram_gpio_list(cJSON * list){ - cJSON * llist=list; - -#if CONFIG_IDF_TARGET_ESP32 - const char * psram_dev = "psram"; - const char * flash_dev = "flash"; - const char * clk = "clk"; - const char * cs = "cs"; - const char * spiq_sd0_io="spiq_sd0_io"; - const char * spid_sd1_io = "spid_sd1_io"; - const char * spiwp_sd3_io = "spiwp_sd3_io"; - const char * spihd_sd2_io = "spihd_sd2_io"; - - uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); - uint32_t pkg_ver = chip_ver & 0x7; - if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) { - rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); - if (cfg.tieh != RTC_VDDSDIO_TIEH_1_8V) { - return llist; - } - cJSON_AddItemToArray(list,get_gpio_entry(clk,psram_dev,CONFIG_D2WD_PSRAM_CLK_IO,true)); - cJSON_AddItemToArray(list,get_gpio_entry(cs,psram_dev,CONFIG_D2WD_PSRAM_CS_IO,true)); - } else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4)) { - rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); - if (cfg.tieh != RTC_VDDSDIO_TIEH_3_3V) { - return llist; - } - cJSON_AddItemToArray(list,get_gpio_entry(clk,psram_dev,PICO_PSRAM_CLK_IO,true)); - cJSON_AddItemToArray(list,get_gpio_entry(cs,psram_dev,CONFIG_PICO_PSRAM_CS_IO,true)); - } else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ6) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ5)){ - cJSON_AddItemToArray(list,get_gpio_entry(clk,psram_dev,CONFIG_D0WD_PSRAM_CLK_IO,true)); - cJSON_AddItemToArray(list,get_gpio_entry(cs,psram_dev,CONFIG_D0WD_PSRAM_CS_IO,true)); - } else { - ESP_LOGW(TAG, "Cant' determine GPIOs for PSRAM chip id: %d", pkg_ver); - cJSON_AddItemToArray(list,get_gpio_entry(clk,psram_dev,-1,true)); - cJSON_AddItemToArray(list,get_gpio_entry(cs,psram_dev,-1,true)); - } - - const uint32_t spiconfig = ets_efuse_get_spiconfig(); - if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) { - cJSON_AddItemToArray(list,get_gpio_entry(spiq_sd0_io,psram_dev,PSRAM_SPIQ_SD0_IO,true)); - cJSON_AddItemToArray(list,get_gpio_entry(spid_sd1_io,psram_dev,PSRAM_SPID_SD1_IO,true)); - cJSON_AddItemToArray(list,get_gpio_entry(spiwp_sd3_io,psram_dev,PSRAM_SPIWP_SD3_IO,true)); - cJSON_AddItemToArray(list,get_gpio_entry(spihd_sd2_io,psram_dev,PSRAM_SPIHD_SD2_IO,true)); - } else if (spiconfig == EFUSE_SPICONFIG_HSPI_DEFAULTS) { - cJSON_AddItemToArray(list,get_gpio_entry(spiq_sd0_io,psram_dev,PSRAM_HSPI_SPIQ_SD0_IO,true)); - cJSON_AddItemToArray(list,get_gpio_entry(spid_sd1_io,psram_dev,PSRAM_HSPI_SPID_SD1_IO,true)); - cJSON_AddItemToArray(list,get_gpio_entry(spiwp_sd3_io,psram_dev,PSRAM_HSPI_SPIWP_SD3_IO,true)); - cJSON_AddItemToArray(list,get_gpio_entry(spihd_sd2_io,psram_dev,PSRAM_HSPI_SPIHD_SD2_IO,true)); - } else { - cJSON_AddItemToArray(list,get_gpio_entry(spiq_sd0_io,psram_dev,EFUSE_SPICONFIG_RET_SPIQ(spiconfig),true)); - cJSON_AddItemToArray(list,get_gpio_entry(spid_sd1_io,psram_dev,EFUSE_SPICONFIG_RET_SPID(spiconfig),true)); - cJSON_AddItemToArray(list,get_gpio_entry(spihd_sd2_io,psram_dev,EFUSE_SPICONFIG_RET_SPIHD(spiconfig),true)); - // If flash mode is set to QIO or QOUT, the WP pin is equal the value configured in bootloader. - // If flash mode is set to DIO or DOUT, the WP pin should config it via menuconfig. - #if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_FLASHMODE_QOUT - cJSON_AddItemToArray(list,get_gpio_entry(spiwp_sd3_io,psram_dev,CONFIG_BOOTLOADER_SPI_WP_PIN,true)); - #else - cJSON_AddItemToArray(list,get_gpio_entry(spiwp_sd3_io,psram_dev,CONFIG_SPIRAM_SPIWP_SD3_PIN,true)); - #endif - } - if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) { - cJSON_AddItemToArray(list,get_gpio_entry(clk,flash_dev,SPI_IOMUX_PIN_NUM_CLK,true)); - cJSON_AddItemToArray(list,get_gpio_entry(cs,flash_dev,SPI_IOMUX_PIN_NUM_CS,true)); - } else if (spiconfig == EFUSE_SPICONFIG_HSPI_DEFAULTS) { - cJSON_AddItemToArray(list,get_gpio_entry(clk,flash_dev,FLASH_HSPI_CLK_IO,true)); - cJSON_AddItemToArray(list,get_gpio_entry(cs,flash_dev,FLASH_HSPI_CS_IO,true)); - } else { - cJSON_AddItemToArray(list,get_gpio_entry(clk,flash_dev,EFUSE_SPICONFIG_RET_SPICLK(spiconfig),true)); - cJSON_AddItemToArray(list,get_gpio_entry(cs,flash_dev,EFUSE_SPICONFIG_RET_SPICS0(spiconfig),true)); - } -#else -#pragma message("need to add esp32-s3 specific SPIRAM GPIO config code") -#endif - return llist; -} - -/**************************************************************************************** - * - */ -cJSON * get_gpio_list_handler(bool refresh) { - gpio_num_t gpio_num; - if(gpio_list && !refresh){ - return gpio_list; - } - - if(gpio_list){ - cJSON_Delete(gpio_list); - } - gpio_list= cJSON_CreateArray(); - - char *bat_config = config_alloc_get_default(NVS_TYPE_STR, "bat_config", NULL, 0); - if (bat_config) { - int channel = -1; - PARSE_PARAM(bat_config, "channel", '=', channel); - if(channel != -1){ - if(adc1_pad_get_io_num(channel,&gpio_num )==ESP_OK){ - cJSON_AddItemToArray(gpio_list,get_gpio_entry("bat","other",gpio_num,false)); - } - } - free(bat_config); - } - gpio_list=get_GPIO_nvs_list(gpio_list); - gpio_list=get_SPDIF_GPIO(gpio_list,is_spdif_config_locked()); - gpio_list=get_Rotary_GPIO(gpio_list); - gpio_list=get_Display_GPIO(gpio_list); - gpio_list=get_SPI_GPIO(gpio_list); - gpio_list=get_I2C_GPIO(gpio_list); - gpio_list=get_DAC_GPIO(gpio_list); - gpio_list=get_ledvu_GPIO(gpio_list); - gpio_list=get_psram_gpio_list(gpio_list); - gpio_list=get_eth_GPIO(gpio_list); - return gpio_list; -} diff --git a/components/services/accessors.h b/components/services/accessors.h index 3a706af2..82a52b4f 100644 --- a/components/services/accessors.h +++ b/components/services/accessors.h @@ -13,115 +13,52 @@ #include "driver/i2s.h" #include "driver/spi_master.h" #include "gpio_exp.h" +#define ASSIGN_GPIO(pin, root, name, mandatory) config_set_gpio(&pin, &(root).name, (root).has_##name, #name, mandatory) -extern const char *i2c_name_type; -extern const char *spi_name_type; +#define ASSIGN_COND_VAL_1LVL(name, targetval) \ + ((targetval) = (platform && platform->has_##name ? &(platform->name) : NULL)) +#define ASSIGN_COND_VAL_2LVL(name1, name2, targetval) \ + ((targetval) = (platform && platform->has_##name1 && platform->name1.has_##name2 ? &(platform->name1.name2) : NULL)) +#define ASSIGN_COND_VAL_3LVL(name1, name2, name3, targetval) \ + ((targetval) = (platform && platform->has_##name1 && platform->name1.has_##name2 && platform->name1.name2.has_##name3 ? &(platform->name1.name2.name3) : NULL)) +#define ASSIGN_COND_VAL_4LVL(name1, name2, name3, name4, targetval) \ + ((targetval) = (platform && platform->has_##name1 && platform->name1.has_##name2 && platform->name1.name2.has_##name3 && platform->name1.name2.name3.has_##name4 ? &(platform->name1.name2.name3.name4) : NULL)) +#define ASSIGN_COND_VAL_5LVL(name1, name2, name3, name4, name5, targetval) \ + ((targetval) = (platform && platform->has_##name1 && platform->name1.has_##name2 && platform->name1.name2.has_##name3 && platform->name1.name2.name3.has_##name4 && platform->name1.name2.name3.name4.has_##name5 ? &(platform->name1.name2.name3.name4.name5) : NULL)) -typedef struct { - int width; - int height; - int address; - int RST_pin; - bool hflip; - bool vflip; - const char *drivername; - int CS_pin; - int speed; - int back; - int depth; - const char *type; - bool rotate; - bool invert; - int colorswap; - int mode; -} display_config_t; -typedef struct eth_config_struct { - char model[16]; - bool valid; - bool rmii; - bool spi; - int rst; - int mdc, mdio; - int host; - int cs, mosi, miso, intr, clk; - int speed; -} eth_config_t; -typedef struct { - i2s_pin_config_t pin; - char model[32]; - int mute_gpio; - int mute_level; - int i2c_addr; - int sda; - int scl; -} i2s_platform_config_t; +#define SYS_NET(target) ASSIGN_COND_VAL_1LVL(net,target) +#define SYS_DISPLAY(target) ASSIGN_COND_VAL_2LVL(dev,display,target) +#define SYS_DEV_LEDSTRIP(target) ASSIGN_COND_VAL_2LVL(dev,led_strip,target) +#define SYS_DEV_ROTARY(target) ASSIGN_COND_VAL_2LVL(dev,rotary,target) +#define SYS_DISPLAY_COMMON(target) ASSIGN_COND_VAL_3LVL(dev,display,common,target) +#define SYS_DISPLAY_SPI(target) ASSIGN_COND_VAL_3LVL(dev,display,spi,target) +#define SYS_DISPLAY_I2C(target) ASSIGN_COND_VAL_3LVL(dev,display,i2c,target) +#define SYS_GPIOS(target) ASSIGN_COND_VAL_2LVL(dev,gpios,target) +#define SYS_ETH(target) ASSIGN_COND_VAL_2LVL(dev,eth,target) +#define SYS_ETH_COMMON(target) ASSIGN_COND_VAL_3LVL(dev,eth,common,target) -typedef struct { - int gpio; - int level; - bool fixed; -} gpio_with_level_t; -typedef struct { - gpio_with_level_t vcc; - gpio_with_level_t gnd; - gpio_with_level_t amp; - gpio_with_level_t ir; - gpio_with_level_t jack; - gpio_with_level_t green; - gpio_with_level_t red; - gpio_with_level_t spkfault; - gpio_with_level_t power; -} set_GPIO_struct_t; +#define SYS_I2CBUS(target) ASSIGN_COND_VAL_2LVL(dev,i2c,target) +#define SYS_GPIOS_NAME(name,target) ASSIGN_COND_VAL_2LVL(gpios,name,target) +#define SYS_SERVICES(target) ASSIGN_COND_VAL_1LVL(services,target) +#define SYS_SERVICES_SPOTIFY(target) ASSIGN_COND_VAL_2LVL(services,cspot,target) +#define SYS_SERVICES_METADATA(target) ASSIGN_COND_VAL_2LVL(services,metadata,target) +#define SYS_SERVICES_AIRPLAY(target) ASSIGN_COND_VAL_2LVL(services,airplay,target) +#define SYS_SERVICES_SLEEP(target) ASSIGN_COND_VAL_2LVL(services,sleep,target) +#define SYS_SERVICES_EQUALIZER(target) ASSIGN_COND_VAL_2LVL(services,equalizer,target) -typedef struct { - int A; - int B; - int SW; - bool knobonly; - bool volume_lock; - bool longpress; - int timer; -} rotary_struct_t; +#define SYS_SERVICES_TELNET(target) ASSIGN_COND_VAL_2LVL(services,telnet,target) +#define SYS_SERVICES_BTSINK(target) ASSIGN_COND_VAL_2LVL(services,bt_sink,target) +#define SYS_SERVICES_SQUEEZELITE(target) ASSIGN_COND_VAL_2LVL(services,squeezelite,target) -typedef struct { - char type[16]; - int length; - int gpio; -} ledvu_struct_t; -typedef struct { - bool fixed; - char * name; - char * group; - int gpio; -} gpio_entry_t; +#define SYS_DEV_BATTERY(target) ASSIGN_COND_VAL_2LVL(dev,battery,target) -const display_config_t * config_display_get(); -const eth_config_t * config_eth_get( ); -void config_eth_init( eth_config_t * target ); -esp_err_t config_display_set(const display_config_t * config); -esp_err_t config_i2c_set(const i2c_config_t * config, int port); -esp_err_t config_i2s_set(const i2s_platform_config_t * config, const char * nvs_name); -esp_err_t config_spi_set(const spi_bus_config_t * config, int host, int dc); const i2c_config_t * config_i2c_get(int * i2c_port); const spi_bus_config_t * config_spi_get(spi_host_device_t * spi_host); const gpio_exp_config_t * config_gpio_exp_get(int index); -void parse_set_GPIO(void (*cb)(int gpio, char *value)); -const i2s_platform_config_t * config_dac_get(); -const i2s_platform_config_t * config_spdif_get( ); -const i2s_platform_config_t * config_i2s_get_from_str(char * dac_config ); -esp_err_t config_spdif_set(const i2s_platform_config_t * config); -bool is_spdif_config_locked(); -esp_err_t free_gpio_entry( gpio_entry_t ** gpio); -gpio_entry_t * get_gpio_by_name(char * name,char * group, bool refresh); -gpio_entry_t * get_gpio_by_no(int gpionum, bool refresh); bool is_dac_config_locked(); bool are_statistics_enabled(); -const rotary_struct_t * config_rotary_get(); -esp_err_t config_rotary_set(rotary_struct_t * rotary); -const ledvu_struct_t * config_ledvu_get(); -esp_err_t config_ledvu_set(ledvu_struct_t * ledvu); \ No newline at end of file diff --git a/components/services/audio_controls.c b/components/services/audio_controls.c index 1850236d..98086402 100644 --- a/components/services/audio_controls.c +++ b/components/services/audio_controls.c @@ -17,7 +17,7 @@ #include "esp_log.h" #include "cJSON.h" #include "buttons.h" -#include "platform_config.h" +#include "Configurator.h" #include "accessors.h" #include "services.h" #include "audio_controls.h" @@ -118,50 +118,53 @@ static void ir_handler(uint16_t addr, uint16_t cmd) { } /**************************************************************************************** - * + * */ -static void set_ir_gpio(int gpio, char *value) { - if (strcasestr(value, "ir")) { - if (strcasestr(value, "rc5")) create_infrared(gpio, ir_handler, IR_RC5); - else create_infrared(gpio, ir_handler, IR_NEC); - } -} - -/**************************************************************************************** - * - */ -esp_err_t actrls_init(const char *profile_name) { - esp_err_t err = ESP_OK; - char *config = config_alloc_get_default(NVS_TYPE_STR, "rotary_config", NULL, 0); - - if (config && *config) { - char *p; - int A = -1, B = -1, SW = -1, longpress = 0; - - // parse config - PARSE_PARAM(config, "A", '=', A); - PARSE_PARAM(config, "B", '=', B); - PARSE_PARAM(config, "SW", '=', SW); - if ((p = strcasestr(config, "knobonly"))) { - p = strchr(p, '='); - int double_press = p ? atoi(p + 1) : 350; - rotary.timer = xTimerCreate("knobTimer", double_press / portTICK_RATE_MS, pdFALSE, NULL, rotary_timer); - longpress = 500; - ESP_LOGI(TAG, "single knob navigation %d", double_press); - } else { - if ((p = strcasestr(config, "volume")) != NULL) rotary.volume_lock = true; - if ((p = strcasestr(config, "longpress")) != NULL) longpress = 1000; - } - - // create rotary (no handling of long press) - err = create_rotary(NULL, A, B, SW, longpress, control_rotary_handler) ? ESP_OK : ESP_FAIL; - } - - // set infrared GPIO if any - parse_set_GPIO(set_ir_gpio); +esp_err_t actrls_init(const char* profile_name) { + esp_err_t err = ESP_OK; + sys_Rotary* dev_config = NULL; + if (!SYS_DEV_ROTARY(dev_config) ) { + ESP_LOGD(TAG, "Rotary not configured"); + return ESP_OK; + } - if (!err) return actrls_init_json(profile_name, true); - else return err; + char* p; + int A = -1, B = -1, SW = -1, longpress = 0; + A = dev_config->A.pin; + B = dev_config->B.pin; + SW = dev_config->SW.pin; + + if (dev_config->has_knobonly && dev_config->knobonly.enable) { + p = strchr(p, '='); + + int double_press = + dev_config->knobonly.delay_ms > 0 ? dev_config->knobonly.delay_ms : 350; + rotary.timer = + xTimerCreate("knobTimer", double_press / portTICK_RATE_MS, pdFALSE, NULL, rotary_timer); + longpress = 500; + ESP_LOGI(TAG, "single knob navigation %d", double_press); + } else { + + if (dev_config->volume) rotary.volume_lock = true; + if (dev_config->longpress) longpress = 1000; + } + + // create rotary (no handling of long press) + err = create_rotary(NULL, A, B, SW, longpress, control_rotary_handler) ? ESP_OK : ESP_FAIL; + + if (platform->dev.has_ir && platform->dev.ir.gpio.pin >= 0) { + + if (platform->dev.ir.type == sys_InfraredType_IR_NEC) { + create_infrared(platform->dev.ir.gpio.pin, ir_handler, IR_RC5); + } else { + create_infrared(platform->dev.ir.gpio.pin, ir_handler, IR_NEC); + } + } + if (!err) + return actrls_init_json(profile_name, true); + else + return err; + return err; } /**************************************************************************************** @@ -509,62 +512,64 @@ static void actrls_defaults(actrls_config_t *config) { */ static esp_err_t actrls_init_json(const char *profile_name, bool create) { esp_err_t err = ESP_OK; - actrls_config_t *cur_config = NULL; - actrls_config_t *config_root = NULL; - char *config; - const cJSON *button; + #pragma message("Add support to button profile names") +// actrls_config_t *cur_config = NULL; +// actrls_config_t *config_root = NULL; +// char *config=NULL; +// const cJSON *button; - if (!profile_name) return ESP_OK; - if ((config = config_alloc_get_str(profile_name, NULL, CONFIG_AUDIO_CONTROLS)) == NULL) return ESP_FAIL; - if (!*config) goto exit; +// if (!profile_name) return ESP_OK; +// //if ((config = config_alloc_get_str(profile_name, NULL, CONFIG_AUDIO_CONTROLS)) == NULL) return ESP_FAIL; +// // TODO: Add support for the commented code +// if (!*config) goto exit; - ESP_LOGD(TAG,"Parsing JSON structure %s", config); - cJSON *buttons = cJSON_Parse(config); - if (buttons == NULL) { - ESP_LOGE(TAG,"JSON Parsing failed for %s", config); - err = ESP_FAIL; - } else { - ESP_LOGD(TAG,"Json parsing completed"); - if (cJSON_IsArray(buttons)) { - ESP_LOGD(TAG,"configuration is an array as expected"); - cur_config =config_root= actrls_init_alloc_structure(buttons, profile_name); - if(!cur_config) { - ESP_LOGE(TAG,"Config buffer was empty. "); - cJSON_Delete(buttons); - err = ESP_FAIL; - goto exit; - } - ESP_LOGD(TAG,"Processing button definitions. "); - cJSON_ArrayForEach(button, buttons){ - char * str = cJSON_Print(button); - ESP_LOGD(TAG,"Processing %s. ", str?str:""); - if(str){ - free(str); - } - actrls_defaults(cur_config); - esp_err_t loc_err = actrls_process_button(button, cur_config); - err = (err == ESP_OK) ? loc_err : err; - if (loc_err == ESP_OK) { - if (create) button_create((void*) cur_config, cur_config->gpio,cur_config->type, - cur_config->pull,cur_config->debounce, control_handler, - cur_config->long_press, cur_config->shifter_gpio); - } else { - ESP_LOGE(TAG,"Error parsing button structure. Button will not be registered."); - } +// ESP_LOGD(TAG,"Parsing JSON structure %s", config); +// cJSON *buttons = cJSON_Parse(config); +// if (buttons == NULL) { +// ESP_LOGE(TAG,"JSON Parsing failed for %s", config); +// err = ESP_FAIL; +// } else { +// ESP_LOGD(TAG,"Json parsing completed"); +// if (cJSON_IsArray(buttons)) { +// ESP_LOGD(TAG,"configuration is an array as expected"); +// cur_config =config_root= actrls_init_alloc_structure(buttons, profile_name); +// if(!cur_config) { +// ESP_LOGE(TAG,"Config buffer was empty. "); +// cJSON_Delete(buttons); +// err = ESP_FAIL; +// goto exit; +// } +// ESP_LOGD(TAG,"Processing button definitions. "); +// cJSON_ArrayForEach(button, buttons){ +// char * str = cJSON_Print(button); +// ESP_LOGD(TAG,"Processing %s. ", str?str:""); +// if(str){ +// free(str); +// } +// actrls_defaults(cur_config); +// esp_err_t loc_err = actrls_process_button(button, cur_config); +// err = (err == ESP_OK) ? loc_err : err; +// if (loc_err == ESP_OK) { +// if (create) button_create((void*) cur_config, cur_config->gpio,cur_config->type, +// cur_config->pull,cur_config->debounce, control_handler, +// cur_config->long_press, cur_config->shifter_gpio); +// } else { +// ESP_LOGE(TAG,"Error parsing button structure. Button will not be registered."); +// } - cur_config++; - } - } else { - ESP_LOGE(TAG,"Invalid configuration; array is expected and none received in %s ", config); - } - cJSON_Delete(buttons); - } - // Now update the global json_config object. If we are recursively processing menu structures, - // the last init that completes will assigh the first json config object found, which will match - // the default config from nvs. - json_config = config_root; -exit: - free(config); +// cur_config++; +// } +// } else { +// ESP_LOGE(TAG,"Invalid configuration; array is expected and none received in %s ", config); +// } +// cJSON_Delete(buttons); +// } +// // Now update the global json_config object. If we are recursively processing menu structures, +// // the last init that completes will assigh the first json config object found, which will match +// // the default config from nvs. +// json_config = config_root; +// exit: +// free(config); return err; } diff --git a/components/services/battery.c b/components/services/battery.c index 2827c264..b842c1f4 100644 --- a/components/services/battery.c +++ b/components/services/battery.c @@ -16,7 +16,7 @@ #include "esp_log.h" #include "driver/adc.h" #include "battery.h" -#include "platform_config.h" +#include "Configurator.h" /* There is a bug in esp32 which causes a spurious interrupt on gpio 36/39 when @@ -30,16 +30,13 @@ static const char *TAG = "battery"; static struct { - int channel; float sum, avg, scale; int count; - int cells, attenuation; + sys_Battery * battery_config; TimerHandle_t timer; -} battery = { - .channel = -1, - .cells = 2, -}; - +} battery; +#define BATTERY_CHANNEL(b) (b.battery_config?b.battery_config->channel - sys_BatteryChannelEnum_CH0:-1) +#define ATTENUATION(b) (b.battery_config?b.battery_config->atten - sys_BatteryAttenEnum_ATT_0:-1) void (*battery_handler_svc)(float value, int cells); /**************************************************************************************** @@ -54,7 +51,8 @@ float battery_value_svc(void) { */ uint8_t battery_level_svc(void) { // TODO: this is vastly incorrect - int level = battery.avg ? (battery.avg - (3.0 * battery.cells)) / ((4.2 - 3.0) * battery.cells) * 100 : 0; + if(!battery.battery_config){ return 0; } + int level = battery.avg ? (battery.avg - (3.0 * battery.battery_config->cells)) / ((4.2 - 3.0) * battery.battery_config->cells) * 100 : 0; return level < 100 ? level : 100; } @@ -62,11 +60,13 @@ uint8_t battery_level_svc(void) { * */ static void battery_callback(TimerHandle_t xTimer) { - battery.sum += adc1_get_raw(battery.channel) * battery.scale / 4095.0; + if(!battery.battery_config){ return; } + + battery.sum += adc1_get_raw(BATTERY_CHANNEL(battery)) * battery.battery_config->scale / 4095.0; if (++battery.count == 30) { battery.avg = battery.sum / battery.count; battery.sum = battery.count = 0; - if (battery_handler_svc) (battery_handler_svc)(battery.avg, battery.cells); + if (battery_handler_svc) (battery_handler_svc)(battery.avg, battery.battery_config->cells); ESP_LOGI(TAG, "Voltage %.2fV", battery.avg); } } @@ -75,31 +75,15 @@ static void battery_callback(TimerHandle_t xTimer) { * */ void battery_svc_init(void) { - char *nvs_item = config_alloc_get_default(NVS_TYPE_STR, "bat_config", "", 0); - -#ifdef CONFIG_BAT_LOCKED - char *p = nvs_item; - asprintf(&nvs_item, CONFIG_BAT_CONFIG ",%s", p); - free(p); -#endif - - if (nvs_item) { - PARSE_PARAM(nvs_item, "channel", '=', battery.channel); - PARSE_PARAM_FLOAT(nvs_item, "scale", '=', battery.scale); - PARSE_PARAM(nvs_item, "atten", '=', battery.attenuation); - PARSE_PARAM(nvs_item, "cells", '=', battery.cells); - free(nvs_item); - } - - if (battery.channel != -1) { + if (SYS_DEV_BATTERY(battery.battery_config) && BATTERY_CHANNEL(battery) != -1) { adc1_config_width(ADC_WIDTH_BIT_12); - adc1_config_channel_atten(battery.channel, battery.attenuation); + adc1_config_channel_atten(BATTERY_CHANNEL(battery), ATTENUATION(battery)); - battery.avg = adc1_get_raw(battery.channel) * battery.scale / 4095.0; + battery.avg = adc1_get_raw(BATTERY_CHANNEL(battery)) * battery.scale / 4095.0; battery.timer = xTimerCreate("battery", BATTERY_TIMER / portTICK_RATE_MS, pdTRUE, NULL, battery_callback); xTimerStart(battery.timer, portMAX_DELAY); - ESP_LOGI(TAG, "Battery measure channel: %u, scale %f, atten %d, cells %u, avg %.2fV", battery.channel, battery.scale, battery.attenuation, battery.cells, battery.avg); + ESP_LOGI(TAG, "Battery measure channel: %u, scale %f, atten %d, cells %u, avg %.2fV", BATTERY_CHANNEL(battery), battery.scale, ATTENUATION(battery), battery.battery_config->cells, battery.avg); } else { ESP_LOGI(TAG, "No battery"); } diff --git a/components/services/led.c b/components/services/led.c index 9e7ea874..41242b77 100644 --- a/components/services/led.c +++ b/components/services/led.c @@ -6,28 +6,28 @@ CONDITIONS OF ANY KIND, either express or implied. */ -#include -#include -#include -#include -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/timers.h" -#include "esp_system.h" -#include "esp_log.h" #include "driver/gpio.h" #include "driver/ledc.h" #include "driver/rmt.h" -#include "platform_config.h" +#include "esp_log.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/timers.h" +#include +#include +#include +#include +#include +#include "Configurator.h" +#include "accessors.h" +#include "globdefs.h" #include "gpio_exp.h" #include "led.h" -#include "globdefs.h" -#include "accessors.h" #include "services.h" -#define MAX_LED 8 -#define BLOCKTIME 10 // up to portMAX_DELAY +#define MAX_LED 8 +#define BLOCKTIME 10 // up to portMAX_DELAY #ifdef CONFIG_IDF_TARGET_ESP32S3 #define LEDC_SPEED_MODE LEDC_LOW_SPEED_MODE @@ -35,46 +35,53 @@ #define LEDC_SPEED_MODE LEDC_HIGH_SPEED_MODE #endif -static const char *TAG = "led"; +static const char* TAG = "led"; -#define RMT_CLK (40/2) +#define RMT_CLK (40 / 2) static int8_t led_rmt_channel = -1; static uint32_t scale24(uint32_t bright, uint8_t); static const struct rmt_led_param_s { - led_type_t type; + sys_LedTypesEnum type; uint8_t bits; // number of ticks in nanoseconds converted in RMT_CLK ticks rmt_item32_t bit_0; rmt_item32_t bit_1; uint32_t green, red; uint32_t (*scale)(uint32_t, uint8_t); -} rmt_led_param[] = { - { LED_WS2812, 24, {{{350 / RMT_CLK, 1, 1000 / RMT_CLK, 0}}}, {{{1000 / RMT_CLK, 1, 350 / RMT_CLK, 0}}}, 0xff0000, 0x00ff00, scale24 }, - { .type = -1 } }; +} rmt_led_param[] = { + {sys_LedTypesEnum_LED_TYPE_WS2812, 24, {{{350 / RMT_CLK, 1, 1000 / RMT_CLK, 0}}}, + {{{1000 / RMT_CLK, 1, 350 / RMT_CLK, 0}}}, 0xff0000, 0x00ff00, scale24}, + {.type = -1}}; static EXT_RAM_ATTR struct led_s { - gpio_num_t gpio; - bool on; - uint32_t color; - int ontime, offtime; - int bright; - int channel; - const struct rmt_led_param_s *rmt; - int pushedon, pushedoff; - bool pushed; - TimerHandle_t timer; + gpio_num_t gpio; + bool on; + uint32_t color; + int ontime, offtime; + int bright; + int channel; + const struct rmt_led_param_s* rmt; + int pushedon, pushedoff; + bool pushed; + TimerHandle_t timer; } leds[MAX_LED]; // can't use EXT_RAM_ATTR for initialized structure static struct led_config_s { - int gpio; - int color; - int bright; - led_type_t type; -} green = { .gpio = CONFIG_LED_GREEN_GPIO, .color = 0, .bright = -1, .type = LED_GPIO }, - red = { .gpio = CONFIG_LED_RED_GPIO, .color = 0, .bright = -1, .type = LED_GPIO }; + int gpio; + int color; + int bright; + sys_LedTypesEnum type; +} green = {.gpio = CONFIG_LED_GREEN_GPIO, + .color = 0, + .bright = -1, + .type = sys_LedTypesEnum_LED_TYPE_GPIO}, + red = {.gpio = CONFIG_LED_RED_GPIO, + .color = 0, + .bright = -1, + .type = sys_LedTypesEnum_LED_TYPE_GPIO}; static int led_max = 2; @@ -91,7 +98,7 @@ static uint32_t scale24(uint32_t color, uint8_t scale) { /**************************************************************************************** * */ -static void set_level(struct led_s *led, bool on) { +static void set_level(struct led_s* led, bool on) { if (led->rmt) { uint32_t data = on ? led->rmt->scale(led->color, led->bright) : 0; uint32_t mask = 1 << (led->rmt->bits - 1); @@ -104,86 +111,89 @@ static void set_level(struct led_s *led, bool on) { rmt_write_items(led->channel, buffer, led->rmt->bits, false); } else if (led->bright < 0 || led->gpio >= GPIO_NUM_MAX) { gpio_set_level_x(led->gpio, on ? led->color : !led->color); - } else { - ledc_set_duty(LEDC_SPEED_MODE, led->channel, on ? led->bright : (led->color ? 0 : pwm_system.max)); - ledc_update_duty(LEDC_SPEED_MODE, led->channel); - } + } else { + ledc_set_duty( + LEDC_SPEED_MODE, led->channel, on ? led->bright : (led->color ? 0 : pwm_system.max)); + ledc_update_duty(LEDC_SPEED_MODE, led->channel); + } } /**************************************************************************************** * */ -static void vCallbackFunction( TimerHandle_t xTimer ) { - struct led_s *led = (struct led_s*) pvTimerGetTimerID (xTimer); +static void vCallbackFunction(TimerHandle_t xTimer) { + struct led_s* led = (struct led_s*)pvTimerGetTimerID(xTimer); - if (!led->timer) return; + if (!led->timer) return; - led->on = !led->on; - ESP_EARLY_LOGD(TAG,"led vCallbackFunction setting gpio %d level %d (bright:%d)", led->gpio, led->on, led->bright); - set_level(led, led->on); + led->on = !led->on; + ESP_EARLY_LOGD(TAG, "led vCallbackFunction setting gpio %d level %d (bright:%d)", led->gpio, + led->on, led->bright); + set_level(led, led->on); - // was just on for a while - if (!led->on && led->offtime == -1) return; + // was just on for a while + if (!led->on && led->offtime == -1) return; - // regular blinking - xTimerChangePeriod(xTimer, (led->on ? led->ontime : led->offtime) / portTICK_RATE_MS, BLOCKTIME); + // regular blinking + xTimerChangePeriod( + xTimer, (led->on ? led->ontime : led->offtime) / portTICK_RATE_MS, BLOCKTIME); } /**************************************************************************************** * */ bool led_blink_core(int idx, int ontime, int offtime, bool pushed) { - if (!leds[idx].gpio || leds[idx].gpio < 0 ) return false; + if (!leds[idx].gpio || leds[idx].gpio < 0) return false; - ESP_LOGD(TAG,"led_blink_core %d on:%d off:%d, pushed:%u", idx, ontime, offtime, pushed); - if (leds[idx].timer) { - // normal requests waits if a pop is pending - if (!pushed && leds[idx].pushed) { - leds[idx].pushedon = ontime; - leds[idx].pushedoff = offtime; - return true; - } - xTimerStop(leds[idx].timer, BLOCKTIME); - } + ESP_LOGD(TAG, "led_blink_core %d on:%d off:%d, pushed:%u", idx, ontime, offtime, pushed); + if (leds[idx].timer) { + // normal requests waits if a pop is pending + if (!pushed && leds[idx].pushed) { + leds[idx].pushedon = ontime; + leds[idx].pushedoff = offtime; + return true; + } + xTimerStop(leds[idx].timer, BLOCKTIME); + } - // save current state if not already pushed - if (!leds[idx].pushed) { - leds[idx].pushedon = leds[idx].ontime; - leds[idx].pushedoff = leds[idx].offtime; - leds[idx].pushed = pushed; - } + // save current state if not already pushed + if (!leds[idx].pushed) { + leds[idx].pushedon = leds[idx].ontime; + leds[idx].pushedoff = leds[idx].offtime; + leds[idx].pushed = pushed; + } - // then set new one - leds[idx].ontime = ontime; - leds[idx].offtime = offtime; + // then set new one + leds[idx].ontime = ontime; + leds[idx].offtime = offtime; - if (ontime == 0) { - ESP_LOGD(TAG,"led %d, setting reverse level", idx); - set_level(leds + idx, false); - } else if (offtime == 0) { - ESP_LOGD(TAG,"led %d, setting level", idx); - set_level(leds + idx, true); - } else { - if (!leds[idx].timer) { - ESP_LOGD(TAG,"led %d, Creating timer", idx); - leds[idx].timer = xTimerCreate("ledTimer", ontime / portTICK_RATE_MS, pdFALSE, (void *)&leds[idx], vCallbackFunction); - } + if (ontime == 0) { + ESP_LOGD(TAG, "led %d, setting reverse level", idx); + set_level(leds + idx, false); + } else if (offtime == 0) { + ESP_LOGD(TAG, "led %d, setting level", idx); + set_level(leds + idx, true); + } else { + if (!leds[idx].timer) { + ESP_LOGD(TAG, "led %d, Creating timer", idx); + leds[idx].timer = xTimerCreate("ledTimer", ontime / portTICK_RATE_MS, pdFALSE, + (void*)&leds[idx], vCallbackFunction); + } leds[idx].on = true; - set_level(leds + idx, true); + set_level(leds + idx, true); - ESP_LOGD(TAG,"led %d, Setting gpio %d and starting timer", idx, leds[idx].gpio); - if (xTimerStart(leds[idx].timer, BLOCKTIME) == pdFAIL) return false; - } + ESP_LOGD(TAG, "led %d, Setting gpio %d and starting timer", idx, leds[idx].gpio); + if (xTimerStart(leds[idx].timer, BLOCKTIME) == pdFAIL) return false; + } - - return true; + return true; } /**************************************************************************************** * */ bool led_brightness(int idx, int bright) { - if (bright > 100) bright = 100; + if (bright > 100) bright = 100; if (leds[idx].rmt) { leds[idx].bright = bright; @@ -195,86 +205,89 @@ bool led_brightness(int idx, int bright) { ledc_update_duty(LEDC_SPEED_MODE, leds[idx].channel); } - return true; + return true; } /**************************************************************************************** * */ bool led_unpush(int idx) { - if (!leds[idx].gpio || leds[idx].gpio<0) return false; + if (!leds[idx].gpio || leds[idx].gpio < 0) return false; - led_blink_core(idx, leds[idx].pushedon, leds[idx].pushedoff, true); - leds[idx].pushed = false; + led_blink_core(idx, leds[idx].pushedon, leds[idx].pushedoff, true); + leds[idx].pushed = false; - return true; + return true; } /**************************************************************************************** * */ int led_allocate(void) { - if (led_max < MAX_LED) return led_max++; - return -1; + if (led_max < MAX_LED) return led_max++; + return -1; } /**************************************************************************************** * */ -bool led_config(int idx, gpio_num_t gpio, int color, int bright, led_type_t type) { - if (gpio < 0) { - ESP_LOGW(TAG,"LED GPIO -1 ignored"); - return false; - } +bool led_config(int idx, sys_LED* led_config) { + if (!led_config->has_gpio) { + return false; + } + if (led_config->gpio.pin < 0) { + ESP_LOGW(TAG, "LED GPIO -1 ignored"); + return false; + } + if (idx >= MAX_LED) return false; + if (led_config->brightness > 100) led_config->brightness = 100; - if (idx >= MAX_LED) return false; - - if (bright > 100) bright = 100; - - leds[idx].gpio = gpio; - leds[idx].color = color; + leds[idx].gpio = led_config->gpio.pin; + leds[idx].color = led_config->gpio.level; leds[idx].rmt = NULL; leds[idx].bright = -1; - if (type != LED_GPIO) { + if (led_config->led_type != sys_LedTypesEnum_LED_TYPE_GPIO) { // first make sure we have a known addressable led - for (const struct rmt_led_param_s *p = rmt_led_param; !leds[idx].rmt && p->type >= 0; p++) if (p->type == type) leds[idx].rmt = p; + for (const struct rmt_led_param_s* p = rmt_led_param; !leds[idx].rmt && p->type >= 0; p++) + if (p->type == led_config->led_type) leds[idx].rmt = p; if (!leds[idx].rmt) return false; if (led_rmt_channel < 0) led_rmt_channel = RMT_NEXT_TX_CHANNEL(); leds[idx].channel = led_rmt_channel; - leds[idx].bright = bright > 0 ? bright : 100; + leds[idx].bright = led_config->brightness > 0 ? led_config->brightness : 100; // set counter clock to 40MHz - rmt_config_t config = RMT_DEFAULT_CONFIG_TX(gpio, leds[idx].channel); + rmt_config_t config = RMT_DEFAULT_CONFIG_TX(led_config->gpio.pin, leds[idx].channel); config.clk_div = 2; rmt_config(&config); rmt_driver_install(config.channel, 0, 0); - } else if (bright < 0 || gpio >= GPIO_NUM_MAX) { - gpio_pad_select_gpio_x(gpio); - gpio_set_direction_x(gpio, GPIO_MODE_OUTPUT); + } else if (led_config->brightness < 0 || led_config->gpio.pin >= GPIO_NUM_MAX) { + gpio_pad_select_gpio_x(led_config->gpio.pin); + gpio_set_direction_x(led_config->gpio.pin, GPIO_MODE_OUTPUT); } else { - leds[idx].channel = pwm_system.base_channel++; - leds[idx].bright = pwm_system.max * powf(bright / 100.0, 3); - if (!color) leds[idx].bright = pwm_system.max - leds[idx].bright; + leds[idx].channel = pwm_system.base_channel++; + leds[idx].bright = pwm_system.max * powf(led_config->brightness / 100.0, 3); + if (!led_config->gpio.level) leds[idx].bright = pwm_system.max - leds[idx].bright; - ledc_channel_config_t ledc_channel = { - .channel = leds[idx].channel, - .duty = leds[idx].bright, - .gpio_num = gpio, + ledc_channel_config_t ledc_channel = { + .channel = leds[idx].channel, + .duty = leds[idx].bright, + .gpio_num = led_config->gpio.pin, .speed_mode = LEDC_SPEED_MODE, - .hpoint = 0, - .timer_sel = pwm_system.timer, + .hpoint = 0, + .timer_sel = pwm_system.timer, }; - ledc_channel_config(&ledc_channel); - } + ledc_channel_config(&ledc_channel); + } - set_level(leds + idx, false); - ESP_LOGD(TAG,"Index %d, GPIO %d, color/onstate %d / RMT %d, bright %d%%", idx, gpio, color, type, bright); - - return true; + set_level(leds + idx, false); + ESP_LOGI(TAG, "Configuring LED %s %d (on:%d rmt:%s %d%% )", idx == LED_GREEN ? "GREEN" : "RED", + led_config->gpio.pin, led_config->gpio.level, sys_LedTypesEnum_name(led_config->led_type), + led_config->brightness); + return true; } /**************************************************************************************** @@ -283,31 +296,38 @@ bool led_config(int idx, gpio_num_t gpio, int color, int bright, led_type_t type static void led_suspend(void) { led_off(LED_GREEN); led_off(LED_RED); -} +} /**************************************************************************************** * */ -void set_led_gpio(int gpio, char *value) { - struct led_config_s *config; +void set_led_gpio(int gpio, char* value) { + struct led_config_s* config; - if (strcasestr(value, "green")) config = &green; - else if (strcasestr(value, "red"))config = &red; - else return; + if (strcasestr(value, "green")) + config = &green; + else if (strcasestr(value, "red")) + config = &red; + else + return; config->gpio = gpio; - char *p = value; + char* p = value; while ((p = strchr(p, ':')) != NULL) { p++; - if ((strcasestr(p, "ws2812")) != NULL) config->type = LED_WS2812; - else config->color = atoi(p); + if ((strcasestr(p, "ws2812")) != NULL) + config->type = sys_LedTypesEnum_LED_TYPE_WS2812; + else + config->color = atoi(p); } - if (config->type != LED_GPIO) { - for (const struct rmt_led_param_s *p = rmt_led_param; p->type >= 0; p++) { + if (config->type != sys_LedTypesEnum_LED_TYPE_GPIO) { + for (const struct rmt_led_param_s* p = rmt_led_param; p->type >= 0; p++) { if (p->type == config->type) { - if (config == &green) config->color = p->green; - else config->color = p->red; + if (config == &green) + config->color = p->green; + else + config->color = p->red; break; } } @@ -315,31 +335,18 @@ void set_led_gpio(int gpio, char *value) { } void led_svc_init(void) { -#ifdef CONFIG_LED_GREEN_GPIO_LEVEL - green.color = CONFIG_LED_GREEN_GPIO_LEVEL; -#endif -#ifdef CONFIG_LED_RED_GPIO_LEVEL - red.color = CONFIG_LED_RED_GPIO_LEVEL; -#endif + sys_Gpios* gpios = NULL; + if (!platform->has_gpios) { + return; + } + gpios = &platform->gpios; + if (gpios->has_greenLED) { + led_config(LED_GREEN, &gpios->greenLED); + } + if (gpios->has_redLED) { + led_config(LED_RED, &gpios->redLED); + } -#ifndef CONFIG_LED_LOCKED - parse_set_GPIO(set_led_gpio); -#endif - - char *nvs_item = config_alloc_get(NVS_TYPE_STR, "led_brightness"); - if (nvs_item) { - PARSE_PARAM(nvs_item, "green", '=', green.bright); - PARSE_PARAM(nvs_item, "red", '=', red.bright); - free(nvs_item); - } - - led_config(LED_GREEN, green.gpio, green.color, green.bright, green.type); - led_config(LED_RED, red.gpio, red.color, red.bright, red.type); - // make sure we switch off all leds (useful for gpio expanders) services_sleep_setsuspend(led_suspend); - - ESP_LOGI(TAG,"Configuring LEDs green:%d (on:%d rmt:%d %d%% ), red:%d (on:%d rmt:%d %d%% )", - green.gpio, green.color, green.type, green.bright, - red.gpio, red.color, red.type, red.bright); } diff --git a/components/services/led.h b/components/services/led.h index f01af042..155d7637 100644 --- a/components/services/led.h +++ b/components/services/led.h @@ -12,17 +12,16 @@ #ifndef LED_H #define LED_H #include "driver/gpio.h" +#include "Configurator.h" enum { LED_GREEN = 0, LED_RED }; -typedef enum { LED_GPIO = -1, LED_WS2812 } led_type_t; - #define led_on(idx) led_blink_core(idx, 1, 0, false) #define led_off(idx) led_blink_core(idx, 0, 0, false) #define led_blink(idx, on, off) led_blink_core(idx, on, off, false) #define led_blink_pushed(idx, on, off) led_blink_core(idx, on, off, true) // if type is LED_GPIO then color set the GPIO logic value for "on" -bool led_config(int idx, gpio_num_t gpio, int color, int bright, led_type_t type); +bool led_config(int idx, sys_LED * led_config); bool led_brightness(int idx, int percent); bool led_blink_core(int idx, int ontime, int offtime, bool push); bool led_unpush(int idx); diff --git a/components/services/messaging.c b/components/services/messaging.c index 2f544019..b3d2770b 100644 --- a/components/services/messaging.c +++ b/components/services/messaging.c @@ -11,7 +11,8 @@ #include "esp_app_trace.h" #include "esp_attr.h" #include "config.h" -#include "nvs_utilities.h" +// #include "nvs_utilities.h" + #include "platform_esp32.h" #include "messaging.h" #include "tools.h" diff --git a/components/services/monitor.c b/components/services/monitor.c index f874dc6e..828166b0 100644 --- a/components/services/monitor.c +++ b/components/services/monitor.c @@ -20,7 +20,8 @@ #include "buttons.h" #include "led.h" #include "globdefs.h" -#include "platform_config.h" +// #include "Configurator.h" +// TODO: Add support for the commented code: search for TODO in the code below") #include "accessors.h" #include "messaging.h" #include "cJSON.h" @@ -41,8 +42,7 @@ bool jack_inserted_svc(void); void (*spkfault_handler_svc)(bool inserted); bool spkfault_svc(void); -static monitor_gpio_t jack = { CONFIG_JACK_GPIO, 0 }; -static monitor_gpio_t spkfault = { CONFIG_SPKFAULT_GPIO, 0 }; + static bool monitor_stats; /**************************************************************************************** @@ -163,8 +163,11 @@ static void jack_handler_default(void *id, button_event_e event, button_press_e * */ bool jack_inserted_svc (void) { - if (jack.gpio != -1) return button_is_pressed(jack.gpio, NULL); - else return true; + sys_GPIO * jack=NULL; + if(SYS_GPIOS_NAME(jack,jack)){ + return button_is_pressed(jack->pin, NULL); + } + return false; } /**************************************************************************************** @@ -181,41 +184,13 @@ static void spkfault_handler_default(void *id, button_event_e event, button_pres * */ bool spkfault_svc (void) { - return button_is_pressed(spkfault.gpio, NULL); + sys_GPIO * spkfault=NULL; + if(SYS_GPIOS_NAME(spkfault,spkfault)){ + return button_is_pressed(spkfault->pin, NULL); + } + return false; } -/**************************************************************************************** - * - */ -#ifndef CONFIG_JACK_LOCKED -static void set_jack_gpio(int gpio, char *value) { - if (strcasestr(value, "jack")) { - char *p; - jack.gpio = gpio; - if ((p = strchr(value, ':')) != NULL) jack.active = atoi(p + 1); - } - else { - jack.gpio = -1; - } -} -#endif - -/**************************************************************************************** - * - */ -#ifndef CONFIG_SPKFAULT_LOCKED -static void set_spkfault_gpio(int gpio, char *value) { - if (strcasestr(value, "spkfault")) { - char *p; - spkfault.gpio = gpio; - if ((p = strchr(value, ':')) != NULL) spkfault.active = atoi(p + 1); - } - else { - spkfault.gpio = -1; - } -} -#endif - /**************************************************************************************** * */ @@ -233,40 +208,19 @@ static void pseudo_idle(void *arg) { * */ void monitor_svc_init(void) { - ESP_LOGI(TAG, "Initializing monitoring"); - -#ifdef CONFIG_JACK_GPIO_LEVEL - jack.active = CONFIG_JACK_GPIO_LEVEL; -#endif - -#ifndef CONFIG_JACK_LOCKED - parse_set_GPIO(set_jack_gpio); -#endif - - // re-use button management for jack handler, it's a GPIO after all - if (jack.gpio != -1) { - ESP_LOGI(TAG,"Adding jack (%s) detection GPIO %d", jack.active ? "high" : "low", jack.gpio); - button_create(NULL, jack.gpio, jack.active ? BUTTON_HIGH : BUTTON_LOW, false, 250, jack_handler_default, 0, -1); + ESP_LOGI(TAG, "Initializing monitoring"); + sys_Services * services = NULL; + sys_GPIO * gpio=NULL; + if(SYS_GPIOS_NAME(jack,gpio) && gpio->pin>=0){ + ESP_LOGI(TAG,"Adding jack (%s) detection GPIO %d", gpio->level ? "high" : "low", gpio->pin); + button_create(NULL, gpio->pin, gpio->level ? BUTTON_HIGH : BUTTON_LOW, false, 250, jack_handler_default, 0, -1); } - -#ifdef CONFIG_SPKFAULT_GPIO_LEVEL - spkfault.active = CONFIG_SPKFAULT_GPIO_LEVEL; -#endif - -#ifndef CONFIG_SPKFAULT_LOCKED - parse_set_GPIO(set_spkfault_gpio); -#endif - - // re-use button management for speaker fault handler, it's a GPIO after all - if (spkfault.gpio != -1) { - ESP_LOGI(TAG,"Adding speaker fault (%s) detection GPIO %d", spkfault.active ? "high" : "low", spkfault.gpio); - button_create(NULL, spkfault.gpio, spkfault.active ? BUTTON_HIGH : BUTTON_LOW, false, 0, spkfault_handler_default, 0, -1); + if(SYS_GPIOS_NAME(spkfault,gpio) && gpio->pin>=0){ + ESP_LOGI(TAG,"Adding speaker fault (%s) detection GPIO %d", gpio->level ? "high" : "low", gpio->pin); + button_create(NULL, gpio->pin, gpio->level ? BUTTON_HIGH : BUTTON_LOW, false, 0, spkfault_handler_default, 0, -1); } - // do we want stats - char *p = config_alloc_get_default(NVS_TYPE_STR, "stats", "n", 0); - monitor_stats = p && (*p == '1' || *p == 'Y' || *p == 'y'); - FREE_AND_NULL(p); + monitor_stats = SYS_SERVICES(services) && services->statistics; ESP_LOGI(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu) dma:%zu (min:%zu)", heap_caps_get_free_size(MALLOC_CAP_INTERNAL), @@ -281,18 +235,4 @@ void monitor_svc_init(void) { static EXT_RAM_ATTR StackType_t xStack[PSEUDO_IDLE_STACK_SIZE] __attribute__ ((aligned (4))); xTaskCreateStatic( (TaskFunction_t) pseudo_idle, "pseudo_idle", PSEUDO_IDLE_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN, xStack, xTaskBuffer ); -} - -/**************************************************************************************** - * - */ - monitor_gpio_t * get_spkfault_gpio(){ - return &spkfault ; - } - -/**************************************************************************************** - * - */ - monitor_gpio_t * get_jack_insertion_gpio(){ - return &jack; } \ No newline at end of file diff --git a/components/services/monitor.h b/components/services/monitor.h index fffd7d43..427fce92 100644 --- a/components/services/monitor.h +++ b/components/services/monitor.h @@ -9,11 +9,6 @@ */ #pragma once -typedef struct { - int gpio; - int active; -} monitor_gpio_t; - extern void (*pseudo_idle_svc)(uint32_t now); extern void (*jack_handler_svc)(bool inserted); @@ -25,7 +20,3 @@ extern bool spkfault_svc(void); extern void (*battery_handler_svc)(float value, int cells); extern float battery_value_svc(void); extern uint16_t battery_level_svc(void); - -extern monitor_gpio_t * get_spkfault_gpio(); -extern monitor_gpio_t * get_jack_insertion_gpio(); - diff --git a/components/services/services.c b/components/services/services.c index ae654ad8..871381e1 100644 --- a/components/services/services.c +++ b/components/services/services.c @@ -12,11 +12,10 @@ #include "esp_log.h" #include "esp_sleep.h" #include "driver/rtc_io.h" -#include "driver/gpio.h" #include "driver/ledc.h" #include "driver/i2c.h" #include "driver/rmt.h" -#include "platform_config.h" +#include "Configurator.h" #include "gpio_exp.h" #include "battery.h" #include "led.h" @@ -43,7 +42,7 @@ pwm_system_t pwm_system = { .base_channel = LEDC_CHANNEL_0, .max = (1 << LEDC_TIMER_13_BIT), }; - +static sys_SleepService * sleep_config; static EXT_RAM_ATTR struct { uint64_t wake_gpio, wake_level; uint64_t rtc_gpio, rtc_level; @@ -58,46 +57,23 @@ static EXT_RAM_ATTR struct { static const char *TAG = "services"; -/**************************************************************************************** - * - */ -void set_chip_power_gpio(int gpio, char *value) { - bool parsed = true; - - // we only parse on-chip GPIOs - if (gpio >= GPIO_NUM_MAX) return; - - if (!strcasecmp(value, "vcc") ) { - gpio_pad_select_gpio(gpio); - gpio_set_direction(gpio, GPIO_MODE_OUTPUT); - gpio_set_level(gpio, 1); - } else if (!strcasecmp(value, "gnd")) { - gpio_pad_select_gpio(gpio); - gpio_set_direction(gpio, GPIO_MODE_OUTPUT); - gpio_set_level(gpio, 0); - } else parsed = false; - - if (parsed) ESP_LOGI(TAG, "set GPIO %u to %s", gpio, value); +void set_gpio_level(sys_GPIO*gpio,const char * name, gpio_mode_t mode){ + gpio_pad_select_gpio(gpio->pin); + gpio_set_direction(gpio->pin, mode); + gpio_set_level(gpio->pin, gpio->level); + ESP_LOGI(TAG, "set GPIO %u to %s, level %d", gpio->pin,name, gpio->level); } +void set_chip_power_gpio(sys_Gpios*gpios) { + + if(gpios->has_power){ + gpios->power.level = 1; + set_gpio_level(&gpios->power,"vcc", GPIO_MODE_OUTPUT); + } + if(gpios->has_GND){ + gpios->GND.level = 0; + set_gpio_level(&gpios->GND,"gnd", GPIO_MODE_OUTPUT); + } -/**************************************************************************************** - * - */ -void set_exp_power_gpio(int gpio, char *value) { - bool parsed = true; - - // we only parse on-chip GPIOs - if (gpio < GPIO_NUM_MAX) return; - - if (!strcasecmp(value, "vcc") ) { - gpio_exp_set_direction(gpio, GPIO_MODE_OUTPUT, NULL); - gpio_exp_set_level(gpio, 1, true, NULL); - } else if (!strcasecmp(value, "gnd")) { - gpio_exp_set_direction(gpio, GPIO_MODE_OUTPUT, NULL); - gpio_exp_set_level(gpio, 0, true, NULL); - } else parsed = false; - - if (parsed) ESP_LOGI(TAG, "set expanded GPIO %u to %s", gpio, value); } /**************************************************************************************** @@ -175,76 +151,54 @@ static void sleep_battery(float level, int cells) { * */ void services_sleep_init(void) { - char *config = config_alloc_get(NVS_TYPE_STR, "sleep_config"); - char *p; - + ESP_LOGD(TAG,"Initializing sleep services"); + if(!SYS_SERVICES_SLEEP(sleep_config)){ + ESP_LOGD(TAG,"No sleep service configured") ; + } // get the wake criteria - if ((p = strcasestr(config, "wake"))) { - char list[32] = "", item[8]; - sscanf(p, "%*[^=]=%31[^,]", list); - p = list - 1; - while (p++ && sscanf(p, "%7[^|]", item)) { - int level = 0, gpio = atoi(item); - if (!rtc_gpio_is_valid_gpio(gpio)) { - ESP_LOGE(TAG, "invalid wake GPIO %d (not in RTC domain)", gpio); - } else { - sleep_context.wake_gpio |= 1LL << gpio; - } - if (sscanf(item, "%*[^:]:%d", &level)) sleep_context.wake_level |= level << gpio; - p = strchr(p, '|'); - } - - // when moving to esp-idf more recent than 4.4.x, multiple gpio wake-up with level specific can be done - if (sleep_context.wake_gpio) { - ESP_LOGI(TAG, "Sleep wake-up gpio bitmap 0x%llx (active 0x%llx)", sleep_context.wake_gpio, sleep_context.wake_level); + for(int i=0;iwake_count;i++){ + if (!rtc_gpio_is_valid_gpio(sleep_config->wake[i].pin)) { + ESP_LOGE(TAG, "invalid wake GPIO %d (not in RTC domain)", sleep_config->wake[i].pin); + } else { + sleep_context.wake_gpio |= 1LL << sleep_config->wake[i].pin; + sleep_context.wake_gpio |= 1LL << sleep_config->wake[i].pin; + sleep_context.wake_level |= sleep_config->wake[i].level << sleep_config->wake[i].pin; } } + // when moving to esp-idf more recent than 4.4.x, multiple gpio wake-up with level specific can be done + if (sleep_context.wake_gpio) { + ESP_LOGI(TAG, "Sleep wake-up gpio bitmap 0x%llx (active 0x%llx)", sleep_context.wake_gpio, sleep_context.wake_level); + } // do we want battery safety - PARSE_PARAM_FLOAT(config, "batt", '=', sleep_context.battery_level); + sleep_context.battery_level = sleep_config->batt; if (sleep_context.battery_level != 0.0) { sleep_context.battery_chain = battery_handler_svc; battery_handler_svc = sleep_battery; ESP_LOGI(TAG, "Sleep on battery level of %.2f", sleep_context.battery_level); } - - - // get the rtc-pull criteria - if ((p = strcasestr(config, "rtc"))) { - char list[32] = "", item[8]; - sscanf(p, "%*[^=]=%31[^,]", list); - p = list - 1; - while (p++ && sscanf(p, "%7[^|]", item)) { - int level = 0, gpio = atoi(item); - if (!rtc_gpio_is_valid_gpio(gpio)) { - ESP_LOGE(TAG, "invalid rtc GPIO %d", gpio); - } else { - sleep_context.rtc_gpio |= 1LL << gpio; - } - if (sscanf(item, "%*[^:]:%d", &level)) sleep_context.rtc_level |= level << gpio; - p = strchr(p, '|'); - } - - // when moving to esp-idf more recent than 4.4.x, multiple gpio wake-up with level specific can be done - if (sleep_context.rtc_gpio) { - ESP_LOGI(TAG, "RTC forced gpio bitmap 0x%llx (active 0x%llx)", sleep_context.rtc_gpio, sleep_context.rtc_level); + for(int i = 0;irtc_count;i++){ + if (!rtc_gpio_is_valid_gpio(sleep_config->rtc[i].pin)) { + ESP_LOGE(TAG, "invalid rtc GPIO %d", sleep_config->rtc[i].pin); + } else { + sleep_context.rtc_gpio |= 1LL << sleep_config->rtc[i].pin; + sleep_context.rtc_level |= sleep_config->rtc[i].level << sleep_config->rtc[i].pin; } } + // when moving to esp-idf more recent than 4.4.x, multiple gpio wake-up with level specific can be done + if (sleep_context.rtc_gpio) { + ESP_LOGI(TAG, "RTC forced gpio bitmap 0x%llx (active 0x%llx)", sleep_context.rtc_gpio, sleep_context.rtc_level); + } // get the GPIOs that activate sleep (we could check that we have a valid wake) - if ((p = strcasestr(config, "sleep"))) { - int gpio, level = 0; - char sleep[8] = ""; - sscanf(p, "%*[^=]=%7[^,]", sleep); - gpio = atoi(sleep); - if ((p = strchr(sleep, ':')) != NULL) level = atoi(p + 1); - ESP_LOGI(TAG, "Sleep activation gpio %d (active %d)", gpio, level); - button_create(NULL, gpio, level ? BUTTON_HIGH : BUTTON_LOW, true, 0, sleep_gpio_handler, 0, -1); + if(sleep_config->has_sleep && sleep_config->sleep.pin >=0 ){ + ESP_LOGI(TAG, "Sleep activation gpio %d (active %d)", sleep_config->sleep.pin, sleep_config->sleep.level); + button_create(NULL, sleep_config->sleep.pin, sleep_config->sleep.level ? BUTTON_HIGH : BUTTON_LOW, true, 0, sleep_gpio_handler, 0, -1); } // do we want delay sleep - PARSE_PARAM(config, "delay", '=', sleep_context.delay); - sleep_context.delay *= 60*1000; + + sleep_context.delay = sleep_config->delay*60*1000; // now check why we woke-up esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); @@ -259,8 +213,11 @@ void services_sleep_init(void) { // we might be woken up by infrared in which case we want a short sleep if (infrared_gpio() >= 0 && ((1LL << infrared_gpio()) & wake_gpio)) { sleep_context.spurious = 1; - PARSE_PARAM(config, "spurious", '=', sleep_context.spurious); + if(sleep_config->spurious>0){ + sleep_context.spurious = sleep_config->spurious; + } sleep_context.spurious *= 60*1000; + ESP_LOGI(TAG, "spurious wake-up detection during %d sec", sleep_context.spurious / 1000); } } @@ -353,7 +310,7 @@ void services_sleep_setsleeper(uint32_t (*sleeper)(void)) { void services_init(void) { messaging_service_init(); gpio_install_isr_service(0); - + // todo: untangle i2c stuff #ifdef CONFIG_I2C_LOCKED if (i2c_system_port == 0) { i2c_system_port = 1; @@ -362,7 +319,7 @@ void services_init(void) { #endif // set potential power GPIO on chip first in case expanders are power using these - parse_set_GPIO(set_chip_power_gpio); + set_chip_power_gpio(&platform->gpios); // shared I2C bus const i2c_config_t * i2c_config = config_i2c_get(&i2c_system_port); @@ -394,11 +351,43 @@ void services_init(void) { } // create GPIO expanders - const gpio_exp_config_t* gpio_exp_config; - for (int count = 0; (gpio_exp_config = config_gpio_exp_get(count)); count++) gpio_exp_create(gpio_exp_config); - - // now set potential power GPIO on expander - parse_set_GPIO(set_exp_power_gpio); + gpio_exp_config_t gpio_exp_config; + if(platform->has_dev && platform->dev.gpio_exp_count>0){ + for(int count = 0;countdev.gpio_exp_count;count++){ + sys_GPIOExp * exp = &platform->dev.gpio_exp[count]; + gpio_exp_config.base = exp->base; + gpio_exp_config.count = exp->count; + gpio_exp_config.phy.addr = exp->addr; + if(exp->has_intr){ + gpio_exp_config.intr = exp->intr.pin; + } + else { + ESP_LOGW(TAG,"Expander doesn't have intr pin"); + } + if(exp->which_ExpType == sys_GPIOExp_spi_tag){ + gpio_exp_config.phy.cs_pin= exp->ExpType.spi.cs.pin; + gpio_exp_config.phy.host = exp->ExpType.spi.host == sys_HostEnum_UNSPECIFIED_HOST ?sys_HostEnum_Host0:exp->ExpType.spi.host -1; + gpio_exp_config.phy.speed = exp->ExpType.spi.speed>0?exp->ExpType.spi.speed:0; + } + else { + gpio_exp_config.phy.port = exp->ExpType.i2c.port == sys_PortEnum_UNSPECIFIED_SYSTPORT?sys_PortEnum_SYSTEM:exp->ExpType.i2c.port -1; + } + strncpy(gpio_exp_config.model,sys_GPIOExpModelEnum_name(exp->model),sizeof(gpio_exp_config.model)-1); + gpio_exp_create(&gpio_exp_config); + } + } + if(platform->has_gpios ){ + // if(platform->gpios.has_GND){ + // platform->gpios.GND.level = 0; + // set_gpio_level(&platform->gpios.GND,"GND", GPIO_MODE_OUTPUT); + // } + // if(platform->gpios.has_Vcc){ + // platform->gpios.Vcc.level = 1; + // set_gpio_level(&platform->gpios.Vcc,"VCC", GPIO_MODE_OUTPUT); + // } + set_chip_power_gpio(&platform->gpios); + } + // system-wide PWM timer configuration ledc_timer_config_t pwm_timer = { diff --git a/components/services/services.h b/components/services/services.h index 3d7fedab..048edca8 100644 --- a/components/services/services.h +++ b/components/services/services.h @@ -7,7 +7,9 @@ * https://opensource.org/licenses/MIT * */ - +#include "Configurator.h" +#include "driver/gpio.h" + #pragma once typedef enum { SLEEP_ONTIMER, SLEEP_ONKEY, SLEEP_ONGPIO, SLEEP_ONIR, SLEEP_ONBATTERY } sleep_cause_e; @@ -15,3 +17,4 @@ void services_sleep_activate(sleep_cause_e cause); void services_sleep_setsuspend(void (*hook)(void)); void services_sleep_setsleeper(uint32_t (*sleeper)(void)); void services_sleep_init(void); +void set_gpio_level(sys_GPIO*gpio,const char * name, gpio_mode_t mode); diff --git a/components/spotify/Shim.cpp b/components/spotify/Shim.cpp index aa33d091..625f2a73 100644 --- a/components/spotify/Shim.cpp +++ b/components/spotify/Shim.cpp @@ -29,10 +29,9 @@ #include "esp_http_server.h" #include "cspot_private.h" #include "cspot_sink.h" -#include "platform_config.h" -#include "nvs_utilities.h" +#include "Configurator.h" #include "tools.h" - +#include "accessors.h" static class cspotPlayer *player; static const struct { @@ -70,6 +69,7 @@ private: void enableZeroConf(void); void runTask(); + sys_Spotify * cspot_config = NULL; public: typedef enum {TRACK_INIT, TRACK_NOTIFY, TRACK_STREAM, TRACK_END} TrackStatus; @@ -86,27 +86,18 @@ cspotPlayer::cspotPlayer(const char* name, httpd_handle_t server, int port, cspo serverHandle(server), serverPort(port), cmdHandler(cmdHandler), dataHandler(dataHandler) { - cJSON *item, *config = config_alloc_get_cjson("cspot_config"); - if ((item = cJSON_GetObjectItem(config, "volume")) != NULL) volume = item->valueint; - if ((item = cJSON_GetObjectItem(config, "bitrate")) != NULL) bitrate = item->valueint; - if ((item = cJSON_GetObjectItem(config, "deviceName") ) != NULL) this->name = item->valuestring; - else this->name = name; - - if ((item = cJSON_GetObjectItem(config, "zeroConf")) != NULL) { - zeroConf = item->valueint; - cJSON_Delete(config); - } else { - zeroConf = true; - cJSON_AddNumberToObject(config, "zeroConf", 1); - config_set_cjson_str_and_free("cspot_config", config); + if(!SYS_SERVICES_SPOTIFY(cspot_config)){ + return; } + volume = cspot_config->volume; + bitrate = cspot_config->bitrate; + this->name = strlen(platform->names.spotify)>0?platform->names.spotify:name; + zeroConf = cspot_config->zeroconf; // get optional credentials from own NVS if (!zeroConf) { - char *credentials = (char*) get_nvs_value_alloc_for_partition(NVS_DEFAULT_PART_NAME, spotify_ns.ns, NVS_TYPE_STR, spotify_ns.credentials, NULL); - if (credentials) { - this->credentials = credentials; - free(credentials); + if (sys_state->cspot_credentials && strlen(sys_state->cspot_credentials)>0) { + this->credentials = sys_state->cspot_credentials; } } @@ -369,15 +360,9 @@ void cspotPlayer::runTask() { // we might have been forced to use zeroConf, so store credentials and reset zeroConf usage if (!zeroConf) { useZeroConf = false; - // can't call store_nvs... from a task running on EXTRAM stack - TimerHandle_t timer = xTimerCreate( "credentials", 1, pdFALSE, strdup(ctx->getCredentialsJson().c_str()), - [](TimerHandle_t xTimer) { - auto credentials = (char*) pvTimerGetTimerID(xTimer); - store_nvs_value_len_for_partition(NVS_DEFAULT_PART_NAME, spotify_ns.ns, NVS_TYPE_STR, spotify_ns.credentials, credentials, 0); - free(credentials); - xTimerDelete(xTimer, portMAX_DELAY); - } ); - xTimerStart(timer, portMAX_DELAY); + if(configurator_set_string(&sys_State_msg,sys_State_cspot_credentials_tag,sys_state,credentials.c_str())){ + configurator.RaiseStateModified(); + } } spirc = std::make_unique(ctx); @@ -430,11 +415,8 @@ void cspotPlayer::runTask() { // on disconnect, stay in the core loop unless we are in ZeroConf mode if (state == DISCO) { // update volume then - cJSON *config = config_alloc_get_cjson("cspot_config"); - cJSON_DeleteItemFromObject(config, "volume"); - cJSON_AddNumberToObject(config, "volume", volume); - config_set_cjson_str_and_free("cspot_config", config); - + cspot_config->volume = volume; + configurator_raise_changed(); // in ZeroConf mod, stay connected (in this loop) if (!zeroConf) state = LINKED; } diff --git a/components/spotify/cspot/bell/external/nanopb/pb_decode.c b/components/spotify/cspot/bell/external/nanopb/pb_decode.c index f388932f..d69be7f7 100644 --- a/components/spotify/cspot/bell/external/nanopb/pb_decode.c +++ b/components/spotify/cspot/bell/external/nanopb/pb_decode.c @@ -16,10 +16,162 @@ #include "pb.h" #include "pb_decode.h" #include "pb_common.h" - +#include /************************************** * Declarations internal to this file * **************************************/ +// Function to write debug headers +const char* pb_ltype_description(uint8_t type) { + uint8_t mask = PB_LTYPE(type); + switch (mask) { + case PB_LTYPE_BOOL: return "BOOL"; + case PB_LTYPE_VARINT: return "VARINT"; + case PB_LTYPE_UVARINT: return "UVARINT"; + case PB_LTYPE_SVARINT: return "SVARINT"; + case PB_LTYPE_FIXED32: return "FIXED32"; + case PB_LTYPE_FIXED64: return "FIXED64"; + case PB_LTYPE_BYTES: return "BYTES"; + case PB_LTYPE_STRING: return "STRING"; + case PB_LTYPE_SUBMESSAGE: return "SUBMESSAGE"; + case PB_LTYPE_SUBMSG_W_CB: return "SUBMSG_W_CB"; + case PB_LTYPE_EXTENSION: return "EXTENSION"; + case PB_LTYPE_FIXED_LENGTH_BYTES: return "FXD_LENBYTES"; + + } + return "UNKNOWN"; +} +const char* pb_htype_description(uint8_t type) { + + uint8_t mask = PB_HTYPE(type); + switch (mask) { + case PB_HTYPE_REQUIRED: return "REQUIRED"; + case PB_HTYPE_OPTIONAL: return "OPTIONAL/SINGULAR"; + case PB_HTYPE_REPEATED: return "REPEATED/ARRAY"; + case PB_HTYPE_ONEOF: return "ONEOF/MASK"; + } + return "UNKNOWN"; +} +const char* pb_atype_description(uint8_t type) { + uint8_t mask = PB_ATYPE(type); + switch (mask) { + case PB_ATYPE_STATIC: return "STATIC"; + case PB_ATYPE_POINTER: return "POINTER"; + case PB_ATYPE_CALLBACK: return "CALLBACK"; + } + return "UNKNOWN"; +} +#define HEAD_FORMAT \ + "| %-5s"\ + "| %-30s"\ + "| %-30s"\ + "| %-5s"\ + "| %-5s"\ + "| %-10s"\ + "| %-10s"\ + "| %-10s"\ + "| %-10s"\ + "| %-10s"\ + "| %-10s"\ + "| %-10s"\ + "| %-10s"\ + "| %-10s"\ + "| %-20s"\ + "| %-20s"\ + "| %-20s"\ + "| %-10s|\n" +void dump_pb_separator(char fill){ + char buf[BUFSIZ] = { 0 }; + int widths[] = {5, 30, 30, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 10,0}; + for(int i=0;widths[i]>0;i++){ + memset(buf, 0x00, sizeof(buf)); + printf("+ %s", (char*)memset(buf, fill, widths[i])); + } + printf("+\n"); +} +void write_debug_header() { + dump_pb_separator('-'); + printf(HEAD_FORMAT, "REC", "Message", "Function", "Line", "Field", "Required", "Largest", + "Submessage","Index", "Field Info", "Required", "Tag", "Data", "Array", "Data", "Rep", + "Alloc", "TypNum"); + printf(HEAD_FORMAT, "", "", "", "", "Count", "Count", "Tag","Index", "", "Index", "Index", "", + "Size", "Size", "Type", "Type", "Type", ""); + dump_pb_separator('-'); +} + +// Function to dump field information +void dump_pb_field(const pb_field_iter_t* iter, const char* msg, const char* func, int line) { + const pb_msgdesc_t* desc = iter->descriptor; + if (!desc) { + printf("DESCRIPTOR MISSING!!\n"); + } + + printf("| %-5s" + "| %-30s" + "| %-30s" + "| %-5d" + "| %-5s" + "| %-10s" + "| %-10s" + "| %-10d" + "| %-10d" + "| %-10d" + "| %-10d" + "| %-10d" + "| %-10d" + "| %-10d" + "| %-20s" + "| %-20s" + "| %-20s" + "| %-10zu|\n", + "FLD", msg, func, line, + "","","", + iter->submessage_index,iter->index, iter->field_info_index, iter->required_field_index, + iter->tag, iter->data_size, iter->array_size, + pb_ltype_description(iter->type), pb_htype_description(iter->type), pb_atype_description(iter->type), + iter->type); +} +void dump_pb_head(const pb_msgdesc_t* desc, const char* msg, const char* func, int line) { + if (!desc) { + printf("DESCRIPTOR MISSING!!\n"); + } + printf("| %-5s" + "| %-30s" + "| %-30s" + "| %-5d" + "| %-5d" + "| %-10d" + "| %-10d" + "| %-10s" + "| %-10s" + "| %-10s" + "| %-10s" + "| %-10s" + "| %-10s" + "| %-10s" + "| %-20s" + "| %-20s" + "| %-20s" + "| %-10s|\n", + "HD", msg, func, line, + desc->field_count, desc->required_field_count, desc->largest_tag, + "","", "", "", + "", "", "", + "", "", "", + ""); +} + +// Macros for convenience +#ifdef DUMP_PB_ENABLE +#define DUMP_PB_FIELD(iter,msg) dump_pb_field(iter,msg, __FUNCTION__, __LINE__) +#define DUMP_PB_HEAD(iter,msg) dump_pb_head(iter,msg, __FUNCTION__, __LINE__) +#define DUMP_PB_MARK(msg) printf("MRK\t%-30s\t%-20s\t%-5d\n",msg, __FUNCTION__, __LINE__) +#define WRITE_DEBUG_HEADER write_debug_header() +#else +#define DUMP_PB_FIELD(iter,msg) +#define DUMP_PB_HEAD(iter,msg) +#define DUMP_PB_MARK(msg) +#define WRITE_DEBUG_HEADER() +#endif static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof); @@ -169,7 +321,7 @@ static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *d { pb_byte_t byte; uint32_t result; - + if (!pb_readbyte(stream, &byte)) { if (stream->bytes_left == 0) @@ -390,9 +542,11 @@ bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *s static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) { + DUMP_PB_FIELD(field,"Decoding basic field"); switch (PB_LTYPE(field->type)) { case PB_LTYPE_BOOL: + if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) PB_RETURN_ERROR(stream, "wrong wire type"); @@ -401,6 +555,7 @@ static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t case PB_LTYPE_VARINT: case PB_LTYPE_UVARINT: case PB_LTYPE_SVARINT: + if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) PB_RETURN_ERROR(stream, "wrong wire type"); @@ -443,6 +598,7 @@ static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t case PB_LTYPE_SUBMESSAGE: case PB_LTYPE_SUBMSG_W_CB: + if (wire_type != PB_WT_STRING) PB_RETURN_ERROR(stream, "wrong wire type"); @@ -461,6 +617,7 @@ static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) { + DUMP_PB_FIELD(field,"Decoding static field"); switch (PB_HTYPE(field->type)) { case PB_HTYPE_REQUIRED: @@ -602,6 +759,7 @@ static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t /* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ static void initialize_pointer_field(void *pItem, pb_field_iter_t *field) { + if (PB_LTYPE(field->type) == PB_LTYPE_STRING || PB_LTYPE(field->type) == PB_LTYPE_BYTES) { @@ -618,6 +776,7 @@ static void initialize_pointer_field(void *pItem, pb_field_iter_t *field) static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) { + DUMP_PB_FIELD(field,"Decoding Pointer field"); #ifndef PB_ENABLE_MALLOC PB_UNUSED(wire_type); PB_UNUSED(field); @@ -746,6 +905,8 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_ static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) { + + DUMP_PB_FIELD(field,"Decoding callback field"); if (!field->descriptor->field_callback) return pb_skip_field(stream, wire_type); @@ -789,6 +950,7 @@ static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) { + DUMP_PB_FIELD(field,"decode field"); #ifdef PB_ENABLE_MALLOC /* When decoding an oneof field, check if there is old data that must be * released first. */ @@ -798,7 +960,6 @@ static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_t return false; } #endif - switch (PB_ATYPE(field->type)) { case PB_ATYPE_STATIC: @@ -862,12 +1023,13 @@ static bool pb_field_set_to_default(pb_field_iter_t *field) { pb_type_t type; type = field->type; - if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) { pb_extension_t *ext = *(pb_extension_t* const *)field->pData; + DUMP_PB_FIELD(field,"Extension START"); while (ext != NULL) { + // DUMP_PB_FIELD(ext,"Process extension"); pb_field_iter_t ext_iter; if (pb_field_iter_begin_extension(&ext_iter, ext)) { @@ -877,12 +1039,14 @@ static bool pb_field_set_to_default(pb_field_iter_t *field) } ext = ext->next; } + DUMP_PB_FIELD(field,"Extension END"); } else if (PB_ATYPE(type) == PB_ATYPE_STATIC) { bool init_data = true; if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->pSize != NULL) { + DUMP_PB_FIELD(field,"has_field = false"); /* Set has_field to false. Still initialize the optional field * itself also. */ *(bool*)field->pSize = false; @@ -890,6 +1054,7 @@ static bool pb_field_set_to_default(pb_field_iter_t *field) else if (PB_HTYPE(type) == PB_HTYPE_REPEATED || PB_HTYPE(type) == PB_HTYPE_ONEOF) { + DUMP_PB_FIELD(field,"set count=0/which field=0"); /* REPEATED: Set array count to 0, no need to initialize contents. ONEOF: Set which_field to 0. */ *(pb_size_t*)field->pSize = 0; @@ -903,6 +1068,10 @@ static bool pb_field_set_to_default(pb_field_iter_t *field) field->submsg_desc->field_callback != NULL || field->submsg_desc->submsg_info[0] != NULL)) { + const char * why = field->submsg_desc->default_value?"default value. Iterating": + field->submsg_desc->field_callback?"Callback. Iterating": + field->submsg_desc->submsg_info[0]?"Sub message. Iterating":""; + DUMP_PB_FIELD(field,why); /* Initialize submessage to defaults. * Only needed if it has default values * or callback/submessage fields. */ @@ -912,9 +1081,14 @@ static bool pb_field_set_to_default(pb_field_iter_t *field) if (!pb_message_set_to_defaults(&submsg_iter)) return false; } + why = field->submsg_desc->default_value?"END default value. Iterating": + field->submsg_desc->field_callback?"END Callback. Iterating": + field->submsg_desc->submsg_info[0]?"END Sub message. Iterating":""; + DUMP_PB_FIELD(field,why); } else { + DUMP_PB_FIELD(field,"Zero init"); /* Initialize to zeros */ memset(field->pData, 0, (size_t)field->data_size); } @@ -922,6 +1096,7 @@ static bool pb_field_set_to_default(pb_field_iter_t *field) } else if (PB_ATYPE(type) == PB_ATYPE_POINTER) { + DUMP_PB_FIELD(field,"Init pointer to NULL"); /* Initialize the pointer to NULL. */ *(void**)field->pField = NULL; @@ -929,11 +1104,13 @@ static bool pb_field_set_to_default(pb_field_iter_t *field) if (PB_HTYPE(type) == PB_HTYPE_REPEATED || PB_HTYPE(type) == PB_HTYPE_ONEOF) { + DUMP_PB_FIELD(field,"Set size = 0"); *(pb_size_t*)field->pSize = 0; } } else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) { + DUMP_PB_FIELD(field,"Don't overwrite callback"); /* Don't overwrite callback */ } @@ -949,6 +1126,7 @@ static bool pb_message_set_to_defaults(pb_field_iter_t *iter) if (iter->descriptor->default_value) { + DUMP_PB_FIELD(iter,"Read default stream"); defstream = pb_istream_from_buffer(iter->descriptor->default_value, (size_t)-1); if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof)) return false; @@ -961,7 +1139,9 @@ static bool pb_message_set_to_defaults(pb_field_iter_t *iter) if (tag != 0 && iter->tag == tag) { + /* We have a default value for this field in the defstream */ + DUMP_PB_FIELD(iter,"default stream has default value"); if (!decode_field(&defstream, wire_type, iter)) return false; if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof)) @@ -995,14 +1175,17 @@ static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t pb_fields_seen_t fields_seen = {{0, 0}}; const uint32_t allbits = ~(uint32_t)0; pb_field_iter_t iter; - + DUMP_PB_HEAD(fields,"Decode INNER"); if (pb_field_iter_begin(&iter, fields, dest_struct)) { if ((flags & PB_DECODE_NOINIT) == 0) { + DUMP_PB_FIELD(&iter,"Begin message"); if (!pb_message_set_to_defaults(&iter)) PB_RETURN_ERROR(stream, "failed to set defaults"); + DUMP_PB_FIELD(&iter,"END message"); } + } while (stream->bytes_left) @@ -1033,6 +1216,8 @@ static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t if (!pb_field_iter_find(&iter, tag) || PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION) { + DUMP_PB_MARK("Processing extension"); + /* No match found, check if it matches an extension. */ if (extension_range_start == 0) { @@ -1067,12 +1252,14 @@ static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t return false; continue; } - + DUMP_PB_FIELD(&iter, "Found field TAG"); /* If a repeated fixed count field was found, get size from * 'fixed_count_field' as there is no counter contained in the struct. */ if (PB_HTYPE(iter.type) == PB_HTYPE_REPEATED && iter.pSize == &iter.array_size) { + + if (fixed_count_field != iter.index) { /* If the new fixed count field does not match the previous one, * check that the previous one is NULL or that it finished @@ -1095,6 +1282,7 @@ static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t if (PB_HTYPE(iter.type) == PB_HTYPE_REQUIRED && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) { + DUMP_PB_FIELD("Mark field as seen",&iter); uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31)); fields_seen.bitfield[iter.required_field_index >> 5] |= tmp; } @@ -1113,7 +1301,6 @@ static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t /* Check that all required fields were present. */ { pb_size_t req_field_count = iter.descriptor->required_field_count; - if (req_field_count > 0) { pb_size_t i; @@ -1146,7 +1333,7 @@ static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t bool checkreturn pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags) { bool status; - + DUMP_PB_HEAD(fields,"ext decode"); if ((flags & PB_DECODE_DELIMITED) == 0) { status = pb_decode_inner(stream, fields, dest_struct, flags); @@ -1174,7 +1361,7 @@ bool checkreturn pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, bool checkreturn pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct) { bool status; - + WRITE_DEBUG_HEADER(); status = pb_decode_inner(stream, fields, dest_struct, 0); #ifdef PB_ENABLE_MALLOC @@ -1190,6 +1377,7 @@ bool checkreturn pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, voi * release it before overwriting with a different one. */ static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field) { + DUMP_PB_FIELD(field,"Decode UNION field"); pb_field_iter_t old_field = *field; pb_size_t old_tag = *(pb_size_t*)field->pSize; /* Previous which_ value */ pb_size_t new_tag = field->tag; /* New which_ value */ @@ -1297,7 +1485,7 @@ static void pb_release_single_field(pb_field_iter_t *field) } } - if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) { /* We are going to release the array, so set the size to 0 */ *(pb_size_t*)field->pSize = 0; @@ -1521,6 +1709,7 @@ static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_t *field) { + DUMP_PB_FIELD(field,"String"); uint32_t size; size_t alloc_size; pb_byte_t *dest = (pb_byte_t*)field->pData; @@ -1602,6 +1791,7 @@ static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_i /* Now decode the submessage contents */ if (status && !submsg_consumed) { + unsigned int flags = 0; /* Static required/optional fields are already initialized by top-level @@ -1609,6 +1799,7 @@ static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_i if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && PB_HTYPE(field->type) != PB_HTYPE_REPEATED) { + flags = PB_DECODE_NOINIT; } diff --git a/components/spotify/cspot_sink.c b/components/spotify/cspot_sink.c index 03eddb1d..5876fbfe 100644 --- a/components/spotify/cspot_sink.c +++ b/components/spotify/cspot_sink.c @@ -2,13 +2,11 @@ #include #include #include - -#include "nvs.h" #include "esp_log.h" #include "esp_console.h" #include "esp_pthread.h" #include "esp_system.h" -#include "platform_config.h" +#include "Configurator.h" #include "audio_controls.h" #include "display.h" #include "accessors.h" diff --git a/components/squeezelite-ota/squeezelite-ota.c b/components/squeezelite-ota/squeezelite-ota.c index 4e804eec..a2058cbd 100644 --- a/components/squeezelite-ota/squeezelite-ota.c +++ b/components/squeezelite-ota/squeezelite-ota.c @@ -21,7 +21,7 @@ #include "esp_err.h" #include "squeezelite-ota.h" #include "esp_netif.h" -#include "platform_config.h" +#include "Configurator.h" #include #include #include @@ -400,19 +400,9 @@ esp_err_t _erase_last_boot_app_partition(const esp_partition_t *ota_partition) { uint16_t num_passes=0; uint16_t remain_size=0; - uint32_t single_pass_size=0; + uint32_t single_pass_size=OTA_FLASH_ERASE_BLOCK; esp_err_t err=ESP_OK; - char * ota_erase_size=config_alloc_get(NVS_TYPE_STR, "ota_erase_blk"); - if(ota_erase_size!=NULL) { - single_pass_size = atol(ota_erase_size); - ESP_LOGD(TAG,"OTA Erase block size is %d (from string: %s)",single_pass_size, ota_erase_size ); - free(ota_erase_size); - } - else { - ESP_LOGW(TAG,"OTA Erase block config not found"); - single_pass_size = OTA_FLASH_ERASE_BLOCK; - } if(single_pass_size % SPI_FLASH_SEC_SIZE !=0){ uint32_t temp_single_pass_size = single_pass_size-(single_pass_size % SPI_FLASH_SEC_SIZE); @@ -442,30 +432,32 @@ esp_err_t _erase_last_boot_app_partition(const esp_partition_t *ota_partition) sendMessaging(MESSAGING_INFO,"Erasing flash complete."); loc_displayer_progressbar(100); vTaskDelay(200/ portTICK_PERIOD_MS); + // TODO: Add support for the commented code return ESP_OK; } void ota_task_cleanup(const char * message, ...){ - ota_status->bOTAThreadStarted=false; - loc_displayer_progressbar(0); - if(message!=NULL){ - va_list args; - va_start(args, message); - sendMessaging(MESSAGING_ERROR,message, args); - va_end(args); + // TODO: Add support for the commented code + // ota_status->bOTAThreadStarted=false; + // loc_displayer_progressbar(0); + // if(message!=NULL){ + // va_list args; + // va_start(args, message); + // sendMessaging(MESSAGING_ERROR,message, args); + // va_end(args); - if (led_display) led_vu_color_red(LED_VU_BRIGHT); - } else { - if (led_display) led_vu_color_green(LED_VU_BRIGHT); - } - FREE_RESET(ota_status->ota_write_data); - FREE_RESET(ota_status->bin_data); - if(ota_http_client!=NULL) { - esp_http_client_cleanup(ota_http_client); - ota_http_client=NULL; - } - ota_status->bOTAStarted = false; - task_fatal_error(); + // if (led_display) led_vu_color_red(LED_VU_BRIGHT); + // } else { + // if (led_display) led_vu_color_green(LED_VU_BRIGHT); + // } + // FREE_RESET(ota_status->ota_write_data); + // FREE_RESET(ota_status->bin_data); + // if(ota_http_client!=NULL) { + // esp_http_client_cleanup(ota_http_client); + // ota_http_client=NULL; + // } + // ota_status->bOTAStarted = false; + // task_fatal_error(); } esp_err_t ota_buffer_all(){ esp_err_t err=ESP_OK; @@ -563,7 +555,7 @@ void ota_task(void *pvParameter) { esp_err_t err = ESP_OK; int data_read = 0; - IF_DISPLAY(GDS_TextSetFont(display,2,GDS_GetHeight(display)>32?&Font_droid_sans_fallback_15x17:&Font_droid_sans_fallback_11x13,-2)) + IF_DISPLAY(GDS_TextSetFontAuto(display,2,GDS_GetHeight(display)>32?GDS_FONT_LARGE:GDS_FONT_MEDIUM,-2)) IF_DISPLAY( GDS_ClearExt(display, true)); IF_DISPLAY(GDS_TextLine(display, 1, GDS_TEXT_LEFT, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, "Firmware update")); IF_DISPLAY(GDS_TextLine(display, 2, GDS_TEXT_LEFT, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, "Initializing")); @@ -691,7 +683,10 @@ esp_err_t process_recovery_ota(const char * bin_url, char * bin_buffer, uint32_t ota_status->bOTAThreadStarted=true; if(bin_url){ + ESP_LOGI(TAG,"Processing recovery OTA for url %s",STR_OR_ALT(bin_url,"N/A")); ota_thread_parms.url =strdup_psram(bin_url); + configurator_set_string(&sys_State_msg,sys_State_ota_url_tag,sys_state,NULL); + configurator_raise_state_changed(); ESP_LOGD(TAG, "Starting ota on core %u for : %s", OTA_CORE,ota_thread_parms.url); } else { @@ -699,28 +694,10 @@ esp_err_t process_recovery_ota(const char * bin_url, char * bin_buffer, uint32_t ota_thread_parms.length = length; ESP_LOGD(TAG, "Starting ota on core %u for file upload", OTA_CORE); } - - char * num_buffer=config_alloc_get(NVS_TYPE_STR, "ota_stack"); - if(num_buffer!=NULL) { - stack_size= atol(num_buffer); - FREE_AND_NULL(num_buffer); - } - else { - ESP_LOGW(TAG,"OTA stack size config not found"); - stack_size = OTA_STACK_SIZE; - } - num_buffer=config_alloc_get(NVS_TYPE_STR, "ota_prio"); - if(num_buffer!=NULL) { - task_priority= atol(num_buffer); - FREE_AND_NULL(num_buffer); - } - else { - ESP_LOGW(TAG,"OTA task priority not found"); - task_priority= OTA_TASK_PRIOTITY; - } + stack_size = OTA_STACK_SIZE; + task_priority= OTA_TASK_PRIOTITY; ESP_LOGD(TAG,"OTA task stack size %d, priority %d (%d %s ESP_TASK_MAIN_PRIO)",stack_size , task_priority, abs(task_priority-ESP_TASK_MAIN_PRIO), task_priority-ESP_TASK_MAIN_PRIO>0?"above":"below"); -// ret=xTaskCreatePinnedToCore(&ota_task, "ota_task", stack_size , (void *)&ota_thread_parms, task_priority, NULL, OTA_CORE); ret=xTaskCreate(&ota_task, "ota_task", stack_size , (void *)&ota_thread_parms, task_priority, NULL); if (ret != pdPASS) { ESP_LOGE(TAG, "create thread %s failed", "ota_task"); diff --git a/components/squeezelite/CMakeLists.txt b/components/squeezelite/CMakeLists.txt index 7d1ba61e..66fede4e 100644 --- a/components/squeezelite/CMakeLists.txt +++ b/components/squeezelite/CMakeLists.txt @@ -1,6 +1,6 @@ # for the forgetful, REQUIRES cannot use CONFIG_XXX due to parsing order if(IDF_TARGET STREQUAL "esp32") - set(target_requires "driver_bt") + set(target_requires "driver_bt" "platform_config") endif() idf_component_register( SRC_DIRS . external ac101 tas57xx wm8978 diff --git a/components/squeezelite/ac101/ac101.c b/components/squeezelite/ac101/ac101.c index bc64378f..34458d45 100644 --- a/components/squeezelite/ac101/ac101.c +++ b/components/squeezelite/ac101/ac101.c @@ -32,7 +32,7 @@ #include #include "adac.h" #include "ac101.h" - +#include "Configurator.h" static const char TAG[] = "AC101"; #define SPKOUT_EN ((1 << 9) | (1 << 11) | (1 << 7) | (1 << 5)) @@ -54,7 +54,7 @@ static void headset(bool active); static bool volume(unsigned left, unsigned right); static void power(adac_power_e mode); -const struct adac_s dac_ac101 = { "AC101", init, adac_deinit, power, speaker, headset, volume }; +const struct adac_s dac_ac101 = { sys_DACModelEnum_AC101, init, adac_deinit, power, speaker, headset, volume }; static void ac101_start(ac_module_t mode); static void ac101_stop(void); diff --git a/components/squeezelite/adac.h b/components/squeezelite/adac.h index 1ab7790e..53631e5e 100644 --- a/components/squeezelite/adac.h +++ b/components/squeezelite/adac.h @@ -12,11 +12,11 @@ #include "freertos/FreeRTOS.h" #include "driver/i2s.h" #include "driver/i2c.h" - +#include "Configurator.h" typedef enum { ADAC_ON = 0, ADAC_STANDBY, ADAC_OFF } adac_power_e; struct adac_s { - char *model; + sys_DACModelEnum model; bool (*init)(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool *mck); void (*deinit)(void); void (*power)(adac_power_e mode); diff --git a/components/squeezelite/controls.c b/components/squeezelite/controls.c index 6906198c..bb6b815b 100644 --- a/components/squeezelite/controls.c +++ b/components/squeezelite/controls.c @@ -7,7 +7,8 @@ */ #include "squeezelite.h" -#include "platform_config.h" +// #include "Configurator.h" +#pragma message("fixme: look for TODO below") #include "audio_controls.h" static log_level loglevel = lINFO; @@ -242,15 +243,16 @@ static bool ir_handler(u16_t addr, u16_t cmd) { * Initialize controls - shall be called once from output_init_embedded */ void sb_controls_init(void) { - char *p = config_alloc_get_default(NVS_TYPE_STR, "lms_ctrls_raw", "n", 0); - raw_mode = p && (*p == '1' || *p == 'Y' || *p == 'y'); - free(p); + // TODO: Add support for the commented code + // char *p = config_alloc_get_default(NVS_TYPE_STR, "lms_ctrls_raw", "n", 0); + // raw_mode = p && (*p == '1' || *p == 'Y' || *p == 'y'); + // free(p); - LOG_INFO("initializing audio (buttons/rotary/ir) controls (raw:%u)", raw_mode); + // LOG_INFO("initializing audio (buttons/rotary/ir) controls (raw:%u)", raw_mode); - get_mac(mac); - actrls_set_default(LMS_controls, raw_mode, NULL, ir_handler); + // get_mac(mac); + // actrls_set_default(LMS_controls, raw_mode, NULL, ir_handler); - chained_notify = server_notify; - server_notify = notify; + // chained_notify = server_notify; + // server_notify = notify; } diff --git a/components/squeezelite/cs4265/cs4265.c b/components/squeezelite/cs4265/cs4265.c index 06dd4c50..eae8cea8 100644 --- a/components/squeezelite/cs4265/cs4265.c +++ b/components/squeezelite/cs4265/cs4265.c @@ -20,6 +20,7 @@ #include "adac.h" #include "stdio.h" #include "math.h" +#include "Configurator.h" #define CS4265_PULL_UP (0x4F ) #define CS4265_PULL_DOWN (0x4E ) @@ -36,7 +37,7 @@ static bool volume(unsigned left, unsigned right); static void power(adac_power_e mode); static esp_err_t cs4265_update_bit(uint8_t reg_no,uint8_t mask,uint8_t val ); static esp_err_t set_clock(); -const struct adac_s dac_cs4265 = { "CS4265", init, adac_deinit, power, speaker, headset, volume }; +const struct adac_s dac_cs4265 = { sys_DACModelEnum_CS4265, init, adac_deinit, power, speaker, headset, volume }; struct cs4265_cmd_s { uint8_t reg; diff --git a/components/squeezelite/decode_external.c b/components/squeezelite/decode_external.c index ba7269e7..a0ff1d95 100644 --- a/components/squeezelite/decode_external.c +++ b/components/squeezelite/decode_external.c @@ -14,7 +14,8 @@ #include "freertos/FreeRTOS.h" #include "freertos/timers.h" #endif -#include "platform_config.h" +#include "Configurator.h" +#include "accessors.h" #include "squeezelite.h" @@ -38,6 +39,7 @@ static bool enable_airplay; #define SYNC_WIN_FAST 2 static raop_event_t raop_state; +static sys_Squeezelite * squeezelite; static EXT_RAM_ATTR struct { bool enabled; @@ -446,44 +448,45 @@ static bool cspot_cmd_handler(cspot_event_t cmd, va_list args) * We provide the generic codec register option */ void register_external(void) { - char *p; - + sys_BluetoothSink * bt_sink; + sys_AirPlay * airplay; + sys_Spotify * spotify; #if CONFIG_BT_SINK - if ((p = config_alloc_get(NVS_TYPE_STR, "enable_bt_sink")) != NULL) { - enable_bt_sink = !strcmp(p,"1") || !strcasecmp(p,"y"); - free(p); - if (!strcasestr(output.device, "BT") && enable_bt_sink) { + enable_bt_sink= (SYS_SERVICES_BTSINK(bt_sink) && bt_sink->enabled); + if ( enable_bt_sink) { + #pragma message ("Is the BT sink logic correct?") + if(SYS_SERVICES_SQUEEZELITE(squeezelite) && squeezelite->output_type == sys_OutputTypeEnum_OUTPUT_Bluetooth ){ + LOG_ERROR("BT Sink cannot be enabled with Bluetooth output"); + } + else { bt_sink_init(bt_sink_cmd_handler, bt_sink_data_handler); - } - } + } + } #endif #if CONFIG_AIRPLAY_SINK - if ((p = config_alloc_get(NVS_TYPE_STR, "enable_airplay")) != NULL) { - enable_airplay = !strcmp(p,"1") || !strcasecmp(p,"y"); - free(p); - if (enable_airplay){ - raop_sink_init(raop_sink_cmd_handler, raop_sink_data_handler); - LOG_INFO("Initializing AirPlay sink"); - } + enable_airplay = SYS_SERVICES_AIRPLAY(airplay) && airplay->enabled; + if (enable_airplay){ + raop_sink_init(raop_sink_cmd_handler, raop_sink_data_handler); + LOG_INFO("Initializing AirPlay sink"); } + #endif #if CONFIG_CSPOT_SINK - if ((p = config_alloc_get(NVS_TYPE_STR, "enable_cspot")) != NULL) { - enable_cspot = strcmp(p,"1") == 0 || strcasecmp(p,"y") == 0; - free(p); - if (enable_cspot){ - cspot_sink_init(cspot_cmd_handler, cspot_sink_data_handler); - LOG_INFO("Initializing CSpot sink"); - } + enable_cspot = SYS_SERVICES_SPOTIFY(spotify) && spotify->enabled; + if (enable_cspot){ + cspot_sink_init(cspot_cmd_handler, cspot_sink_data_handler); + LOG_INFO("Initializing CSpot sink"); } #endif + } void deregister_external(void) { #if CONFIG_BT_SINK - if (!strcasestr(output.device, "BT") && enable_bt_sink) { + sys_Squeezelite * squeezelite; + if(SYS_SERVICES_SQUEEZELITE(squeezelite) && squeezelite->output_type != sys_OutputTypeEnum_OUTPUT_Bluetooth && enable_bt_sink ){ bt_sink_deinit(); } #endif diff --git a/components/squeezelite/embedded.c b/components/squeezelite/embedded.c index 2b9bd2c3..b2156c08 100644 --- a/components/squeezelite/embedded.c +++ b/components/squeezelite/embedded.c @@ -17,20 +17,13 @@ #include "esp_wifi.h" #include "esp_log.h" #include "monitor.h" -#include "platform_config.h" +#include "Configurator.h" #include "messaging.h" #include "gpio_exp.h" #include "accessors.h" -#ifndef CONFIG_POWER_GPIO_LEVEL -#define CONFIG_POWER_GPIO_LEVEL 1 -#endif - static const char TAG[] = "embedded"; - -static struct { - int gpio, active; -} power_control = { CONFIG_POWER_GPIO, CONFIG_POWER_GPIO_LEVEL }; +static sys_GPIO * power=NULL; extern void sb_controls_init(void); extern bool sb_displayer_init(void); @@ -40,16 +33,6 @@ u8_t custom_player_id = 12; mutex_type slimp_mutex; static jmp_buf jumpbuf; -#ifndef POWER_LOCKED -static void set_power_gpio(int gpio, char *value) { - if (strcasestr(value, "power")) { - char *p = strchr(value, ':'); - if (p) power_control.active = atoi(p + 1); - power_control.gpio = gpio; - } -} -#endif - void get_mac(u8_t mac[]) { esp_read_mac(mac, ESP_MAC_WIFI_STA); } @@ -88,16 +71,13 @@ int embedded_init(void) { mutex_create(slimp_mutex); sb_controls_init(); custom_player_id = sb_displayer_init() ? 100 : 101; - -#ifndef POWER_LOCKED - parse_set_GPIO(set_power_gpio); -#endif - if (power_control.gpio != -1) { - gpio_pad_select_gpio_x(power_control.gpio); - gpio_set_direction_x(power_control.gpio, GPIO_MODE_OUTPUT); - gpio_set_level_x(power_control.gpio, !power_control.active); - ESP_LOGI(TAG, "setting power GPIO %d (active:%d)", power_control.gpio, power_control.active); + + if(SYS_GPIOS_NAME(power,power) && power->pin >= 0){ + gpio_pad_select_gpio_x(power->pin); + gpio_set_direction_x(power->pin, GPIO_MODE_OUTPUT); + gpio_set_level_x(power->pin, !power->level); + ESP_LOGI(TAG, "setting power GPIO %d (active:%d)", power->pin, power->level); } return setjmp(jumpbuf); @@ -108,9 +88,9 @@ void embedded_exit(int code) { } void powering(bool on) { - if (power_control.gpio != -1) { + if (power->pin != -1) { ESP_LOGI(TAG, "powering player %s", on ? "ON" : "OFF"); - gpio_set_level_x(power_control.gpio, on ? power_control.active : !power_control.active); + gpio_set_level_x(power->pin, on ? power->level : !power->level); } } @@ -131,25 +111,5 @@ u16_t get_battery(void) { } void set_name(char *name) { - char *cmd = config_alloc_get(NVS_TYPE_STR, "autoexec1"); - char *p, *q; - - if (!cmd) return; - - if ((p = strstr(cmd, " -n")) != NULL) { - q = p + 3; - // in case some smart dude has a " -" in player's name - while ((q = strstr(q, " -")) != NULL) { - if (!strchr(q, '"') || !strchr(q+1, '"')) break; - q++; - } - if (q) memmove(p, q, strlen(q) + 1); - else *p = '\0'; - } - - asprintf(&q, "%s -n \"%s\"", cmd, name); - config_set_value(NVS_TYPE_STR, "autoexec1", q); - - free(q); - free(cmd); + strncpy(platform->names.squeezelite,name,sizeof(platform->names.squeezelite)); } diff --git a/components/squeezelite/equalizer.c b/components/squeezelite/equalizer.c index f823fe19..fec2e60c 100644 --- a/components/squeezelite/equalizer.c +++ b/components/squeezelite/equalizer.c @@ -9,7 +9,7 @@ */ #include "math.h" -#include "platform_config.h" +#include "Configurator.h" #include "squeezelite.h" #include "equalizer.h" #include "esp_equalizer.h" @@ -20,12 +20,14 @@ static log_level loglevel = lINFO; static EXT_RAM_ATTR struct { void *handle; - float loudness, volume; uint32_t samplerate; - float gain[EQ_BANDS], loudness_gain[EQ_BANDS]; + float volume; + float loudness_gain[EQ_BANDS]; bool update; + sys_Equalizer *state; } equalizer; + #define POLYNOME_COUNT 6 static const float loudness_envelope_coefficients[EQ_BANDS][POLYNOME_COUNT] = { @@ -67,11 +69,11 @@ static void calculate_loudness(void) { char trace[EQ_BANDS * 5 + 1]; size_t n = 0; for (int i = 0; i < EQ_BANDS; i++) { - for (int j = 0; j < POLYNOME_COUNT && equalizer.loudness != 0; j++) { + for (int j = 0; j < POLYNOME_COUNT && equalizer.state->loudness != 0; j++) { equalizer.loudness_gain[i] += loudness_envelope_coefficients[i][j] * pow(equalizer.volume, j); } - equalizer.loudness_gain[i] *= equalizer.loudness / 2; + equalizer.loudness_gain[i] *= equalizer.state->loudness / 2; n += sprintf(trace + n, "%.2g%c", equalizer.loudness_gain[i], i < EQ_BANDS ? ',' : '\0'); } LOG_INFO("loudness %s", trace); @@ -81,22 +83,20 @@ static void calculate_loudness(void) { * initialize equalizer */ void equalizer_init(void) { - // handle equalizer - char *config = config_alloc_get(NVS_TYPE_STR, "equalizer"); - char *p = strtok(config, ", !"); + sys_Services * services; + sys_Equalizer blank_eq = sys_Equalizer_init_default; - for (int i = 0; p && i < EQ_BANDS; i++) { - equalizer.gain[i] = atoi(p); - p = strtok(NULL, ", :"); - } - - free(config); - - // handle loudness - config = config_alloc_get(NVS_TYPE_STR, "loudness"); - equalizer.loudness = atof(config) / 10.0; - - free(config); + equalizer.state = &sys_state->equalizer; + if(!sys_state->has_equalizer ){ + sys_state->has_equalizer = true; + if(SYS_SERVICES(services) && services->has_equalizer){ + memcpy(equalizer.state,&services->equalizer,sizeof(sys_Equalizer)); + } + else { + memcpy(equalizer.state,&blank_eq,sizeof(sys_Equalizer)); + } + configurator_raise_state_changed(); + } } /**************************************************************************************** @@ -135,7 +135,7 @@ void equalizer_set_volume(unsigned left, unsigned right) { volume = volume / 16.0 * 100.0; // LMS has the bad habit to send multiple volume commands - if (volume != equalizer.volume && equalizer.loudness) { + if (volume != equalizer.volume && equalizer.state->loudness) { equalizer.volume = volume; calculate_loudness(); equalizer.update = true; @@ -152,15 +152,16 @@ void equalizer_set_gain(int8_t *gain) { int n = 0; for (int i = 0; i < EQ_BANDS; i++) { - equalizer.gain[i] = gain[i]; + equalizer.state->gains[i] = gain[i]; n += sprintf(config + n, "%d,", gain[i]); } - config[n-1] = '\0'; - config_set_value(NVS_TYPE_STR, "equalizer", config); // update only if something changed - if (!memcmp(equalizer.gain, gain, EQ_BANDS)) equalizer.update = true; + if (!memcmp(&equalizer.state->gains, gain, EQ_BANDS)) { + equalizer.update = true; + configurator_raise_state_changed(); + } LOG_INFO("equalizer gain %s", config); #else @@ -173,13 +174,11 @@ void equalizer_set_gain(int8_t *gain) { */ void equalizer_set_loudness(uint8_t loudness) { #if BYTES_PER_FRAME == 4 - char p[4]; - itoa(loudness, p, 10); - config_set_value(NVS_TYPE_STR, "loudness", p); - // update loudness gains as a factor of loudness and volume - if (equalizer.loudness != loudness / 10.0) { - equalizer.loudness = loudness / 10.0; + // update loudness gains as a factor of loudness and volume + if (equalizer.state->loudness != loudness / 10.0) { + equalizer.state->loudness = loudness / 10.0; + configurator_raise_state_changed(); calculate_loudness(); equalizer.update = true; } @@ -188,6 +187,7 @@ void equalizer_set_loudness(uint8_t loudness) { #else LOG_INFO("no equalizer with 32 bits samples"); #endif + } /**************************************************************************************** @@ -211,7 +211,7 @@ void equalizer_process(uint8_t *buf, uint32_t bytes) { bool active = false; for (int i = 0; i < EQ_BANDS; i++) { - float gain = equalizer.gain[i] + equalizer.loudness_gain[i]; + float gain = equalizer.state->gains[i] + equalizer.loudness_gain[i]; esp_equalizer_set_band_value(equalizer.handle, gain, i, 0); esp_equalizer_set_band_value(equalizer.handle, gain, i, 1); active |= gain != 0; diff --git a/components/squeezelite/esp32_main.c b/components/squeezelite/esp32_main.c new file mode 100644 index 00000000..fc3fe4b1 --- /dev/null +++ b/components/squeezelite/esp32_main.c @@ -0,0 +1,185 @@ +/* + * Squeezelite - lightweight headless squeezebox emulator + * + * (c) Adrian Smith 2012-2015, triode1@btinternet.com + * Ralph Irving 2015-2017, ralph_irving@hotmail.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additions (c) Paul Hermann, 2015-2017 under the same license terms + * -Control of Raspberry pi GPIO for amplifier power + * -Launch script on power status change from LMS + */ + +#include "squeezelite.h" +#include +#include "Configurator.h" + +extern bool user_rates; +static unsigned int rates[MAX_SUPPORTED_SAMPLERATES] = {0}; +sys_Squeezelite* config; +log_level loglevel = lDEBUG; +static void sighandler(int signum) { + slimproto_stop(); + + // remove ourselves in case above does not work, second SIGINT will cause non gracefull shutdown + signal(signum, SIG_DFL); +} + +unsigned int* get_rates() { + unsigned int ref[] TEST_RATES; + sys_RatesOption* ratescfg = &config->rates; + if (!config->has_rates || ((ratescfg->list_count == 0 || ratescfg->list[0] == 0) && + ratescfg->min == 0 && ratescfg->max == 0)) { + user_rates = false; + return rates; + } + + if (ratescfg->list_count > 0 && ratescfg->list[0] != 0) { + // Sort the rates from the list + for (int i = 0; i < ratescfg->list_count && i < MAX_SUPPORTED_SAMPLERATES; ++i) { + rates[i] = ratescfg->list[i]; + } + // Sort logic here if needed + } else { + // Use min and max to determine rates + unsigned int min = ratescfg->min; + unsigned int max = ratescfg->max; + if (max < min) { + unsigned int tmp = max; + max = min; + min = tmp; + } + for (int i = 0, j = 0; i < MAX_SUPPORTED_SAMPLERATES; ++i) { + if (ref[i] <= max && ref[i] >= min) { + rates[j++] = ref[i]; + } + } + } + + user_rates = true; + return rates; +} +log_level log_level_from_sys_level(sys_DebugLevelEnum level) { + switch (level) { + case sys_DebugLevelEnum_DEFAULT: + return lWARN; + break; + case sys_DebugLevelEnum_INFO: + return lINFO; + break; + case sys_DebugLevelEnum_ERROR: + return lERROR; + break; + case sys_DebugLevelEnum_WARN: + return lWARN; + break; + case sys_DebugLevelEnum_DEBUG: + return lDEBUG; + break; + case sys_DebugLevelEnum_SDEBUG: + return lSDEBUG; + break; + default: + return lWARN; + } +} +void build_codec_string(sys_CodexEnum* list, size_t count, char* buffer, size_t buf_size) { + const char* prefix = STR(sys_CodexEnum) "_c_"; + const char* name = NULL; + for (int i = 0; i < count; i++) { + if (i > 0) { + strncat(buffer, ", ", buf_size); + } + name = sys_CodexEnum_name(list[i]) + strlen(prefix); + LOG_INFO("Found codec: %s ", name); + strncat(buffer, name, buf_size); + } + LOG_INFO("Codec list: %s ", buffer); +} +int squeezelite_main_start() { + u8_t mac[6]; + unsigned output_buf_size = 0; + char include_codecs[101] = {0}; + char exclude_codecs[101] = {0}; + config = platform->has_services && platform->services.has_squeezelite + ? &platform->services.squeezelite + : NULL; + if (!config) { + LOG_ERROR("Squeezelite not configured"); + return -1; + } + + int err = embedded_init(); + if (err) return err; + get_mac(mac); + unsigned int * rates = get_rates(); + + signal(SIGINT, sighandler); + signal(SIGTERM, sighandler); + #if defined(SIGQUIT) + signal(SIGQUIT, sighandler); + #endif + #if defined(SIGHUP) + signal(SIGHUP, sighandler); + #endif + output_buf_size = config->buffers.output; + + // set the output buffer size if not specified on the command line, take account of resampling + if (!output_buf_size) { + output_buf_size = OUTPUTBUF_SIZE; + if (strlen(config->resample) > 0) { + unsigned scale = 8; + if (rates[0]) { + scale = rates[0] / 44100; + if (scale > 8) scale = 8; + if (scale < 1) scale = 1; + } + output_buf_size *= scale; + } + } + build_codec_string(config->excluded_codex, config->excluded_codex_count, exclude_codecs, + sizeof(exclude_codecs)); + build_codec_string( + config->included_codex, config->included_codex, include_codecs, sizeof(include_codecs)); + + unsigned int stream_buf_size = + config->buffers.stream > 0 ? config->buffers.stream : STREAMBUF_SIZE; + stream_init( + log_level_from_sys_level(platform->services.squeezelite.log.stream), stream_buf_size); + output_init_embedded(); + decode_init(log_level_from_sys_level(platform->services.squeezelite.log.decode), include_codecs, + exclude_codecs); + +#if RESAMPLE || RESAMPLE16 + if (strlen(config->resample) > 0) { + process_init(config->resample); + } +#endif + + if (!config->enabled) { + LOG_ERROR("LMS is disabled"); + while (1) + sleep(3600); + } + char* name = strlen(platform->names.squeezelite) > 0 ? platform->names.squeezelite + : platform->names.device; + slimproto(log_level_from_sys_level(platform->services.squeezelite.log.slimproto), + config->server_name_ip, mac, name, NULL, NULL, config->max_rate); + + decode_close(); + stream_close(); + output_close_embedded(); + return (0); +} diff --git a/components/squeezelite/external/dac_external.c b/components/squeezelite/external/dac_external.c index 67c0b3f7..4bce7173 100644 --- a/components/squeezelite/external/dac_external.c +++ b/components/squeezelite/external/dac_external.c @@ -16,7 +16,9 @@ #include "esp_log.h" #include "gpio_exp.h" #include "cJSON.h" -#include "platform_config.h" +#include "string.h" +// #include "Configurator.h" +#pragma message("fixme: look for TODO below") #include "adac.h" static const char TAG[] = "DAC external"; @@ -29,7 +31,7 @@ static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool static bool i2c_json_execute(char *set); -const struct adac_s dac_external = { "i2s", init, adac_deinit, power, speaker, headset, volume }; +const struct adac_s dac_external = { sys_DACModelEnum_I2S, init, adac_deinit, power, speaker, headset, volume }; static cJSON *i2c_json; static int i2c_addr; @@ -58,34 +60,35 @@ static const struct { * init */ static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool *mck) { - char *p; + char *p=NULL; + void * dummy = &codecs; + // i2c_addr = adac_init(config, i2c_port_num); + // if (!i2c_addr) return true; - i2c_addr = adac_init(config, i2c_port_num); - if (!i2c_addr) return true; + // ESP_LOGI(TAG, "DAC on I2C @%d", i2c_addr); - ESP_LOGI(TAG, "DAC on I2C @%d", i2c_addr); - - p = config_alloc_get_str("dac_controlset", CONFIG_DAC_CONTROLSET, NULL); + // p = config_alloc_get_str("dac_controlset", CONFIG_DAC_CONTROLSET, NULL); - if ((!p || !*p) && (p = strcasestr(config, "model")) != NULL) { - char model[32] = ""; - int i; - sscanf(p, "%*[^=]=%31[^,]", model); - for (i = 0; *model && ((p = codecs[i].controlset) != NULL) && strcasecmp(codecs[i].model, model); i++); - if (p) *mck = codecs[i].mclk; - } + // if ((!p || !*p) && (p = strcasestr(config, "model")) != NULL) { + // char model[32] = ""; + // int i; + // sscanf(p, "%*[^=]=%31[^,]", model); + // for (i = 0; *model && ((p = codecs[i].controlset) != NULL) && strcasecmp(codecs[i].model, model); i++); + // if (p) *mck = codecs[i].mclk; + // } - i2c_json = cJSON_Parse(p); + // i2c_json = cJSON_Parse(p); - if (!i2c_json) { - ESP_LOGW(TAG, "no i2c controlset found"); - return true; - } + // if (!i2c_json) { + // ESP_LOGW(TAG, "no i2c controlset found"); + // return true; + // } - if (!i2c_json_execute("init")) { - ESP_LOGE(TAG, "could not intialize DAC"); - return false; - } + // if (!i2c_json_execute("init")) { + // ESP_LOGE(TAG, "could not intialize DAC"); + // return false; + // } + // TODO: Add support for the commented code return true; } diff --git a/components/squeezelite/main.c b/components/squeezelite/main.c index d1ab04f0..72e35886 100644 --- a/components/squeezelite/main.c +++ b/components/squeezelite/main.c @@ -767,7 +767,7 @@ int squeezelite_main(int argc, char **argv) { stream_init(log_stream, stream_buf_size); #if EMBEDDED - output_init_embedded(log_output, output_device, output_buf_size, output_params, rates, rate_delay, idle); + output_init_embedded(); #else if (!strcmp(output_device, "-")) { output_init_stdout(log_output, output_buf_size, output_params, rates, rate_delay); diff --git a/components/squeezelite/output_bt.c b/components/squeezelite/output_bt.c index c062c0ab..186643c8 100644 --- a/components/squeezelite/output_bt.c +++ b/components/squeezelite/output_bt.c @@ -14,10 +14,11 @@ #include "squeezelite.h" #include "equalizer.h" #include "perf_trace.h" -#include "platform_config.h" #include "services.h" #include "led.h" - +#include "Configurator.h" +extern log_level log_level_from_sys_level(sys_DebugLevelEnum level); +static sys_Squeezelite * config = NULL; extern struct outputstate output; extern struct buffer *outputbuf; extern struct buffer *streambuf; @@ -32,7 +33,7 @@ extern u8_t *silencebuf; #define STATS_REPORT_DELAY_MS 15000 -extern void hal_bluetooth_init(const char * options); +extern void hal_bluetooth_init(); extern void hal_bluetooth_stop(void); extern u8_t config_spdif_gpio; @@ -74,11 +75,10 @@ static uint32_t bt_idle_callback(void) { /**************************************************************************************** * Init BT sink */ -void output_init_bt(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) { - loglevel = level; - - // idle counter - bt_idle_since = pdTICKS_TO_MS(xTaskGetTickCount()); +void output_init_bt() { + config = &platform->services.squeezelite; + loglevel = log_level_from_sys_level(config->log.output); + bt_idle_since = pdTICKS_TO_MS(xTaskGetTickCount()); services_sleep_setsleeper(bt_idle_callback); // even BT has a right to use led :-) @@ -86,11 +86,11 @@ void output_init_bt(log_level level, char *device, unsigned output_buf_size, cha running = true; output.write_cb = &_write_frames; - hal_bluetooth_init(device); - char *p = config_alloc_get_default(NVS_TYPE_STR, "stats", "n", 0); - stats = p && (*p == '1' || *p == 'Y' || *p == 'y'); - free(p); + hal_bluetooth_init(); + stats = platform->services.statistics; + equalizer_set_samplerate(output.current_sample_rate); + } /**************************************************************************************** diff --git a/components/squeezelite/output_embedded.c b/components/squeezelite/output_embedded.c index 4bc7d6bd..7cd334e5 100644 --- a/components/squeezelite/output_embedded.c +++ b/components/squeezelite/output_embedded.c @@ -1,4 +1,4 @@ -/* +/* * Squeezelite for esp32 * * (c) Sebastien 2019 @@ -10,27 +10,30 @@ */ #include "squeezelite.h" #include "equalizer.h" +#include "Configurator.h" +extern log_level log_level_from_sys_level(sys_DebugLevelEnum level); +static sys_Squeezelite* config = NULL; + +extern unsigned int* get_rates() ; extern struct outputstate output; -extern struct buffer *outputbuf; +extern struct buffer* outputbuf; -static bool (*slimp_handler_chain)(u8_t *data, int len); +static bool (*slimp_handler_chain)(u8_t* data, int len); #define FRAME_BLOCK MAX_SILENCE_FRAMES -#define LOCK mutex_lock(outputbuf->mutex) +#define LOCK mutex_lock(outputbuf->mutex) #define UNLOCK mutex_unlock(outputbuf->mutex) // output_bt.c -extern void output_init_bt(log_level level, char *device, unsigned output_buf_size, char *params, - unsigned rates[], unsigned rate_delay, unsigned idle); -extern void output_close_bt(void); +extern void output_init_bt(unsigned rates[]); +extern void output_close_bt(void); // output_i2s.c -extern void output_init_i2s(log_level level, char *device, unsigned output_buf_size, char *params, - unsigned rates[], unsigned rate_delay, unsigned idle); -extern bool output_volume_i2s(unsigned left, unsigned right); -extern void output_close_i2s(void); +extern void output_init_i2s(unsigned rates[]); +extern bool output_volume_i2s(unsigned left, unsigned right); +extern void output_close_i2s(void); // controls.c extern void cli_controls_init(void); @@ -42,137 +45,152 @@ static void (*close_cb)(void); #pragma pack(push, 1) struct eqlz_packet { - char opcode[4]; + char opcode[4]; }; struct loud_packet { - char opcode[4]; - u8_t loudness; + char opcode[4]; + u8_t loudness; }; #pragma pack(pop) -static bool handler(u8_t *data, int len){ - bool res = true; - - if (!strncmp((char*) data, "eqlz", 4)) { - s8_t *gain = (s8_t*) (data + sizeof(struct eqlz_packet)); - // update will be done at next opportunity - equalizer_set_gain(gain); - } else if (!strncmp((char*) data, "loud", 4)) { - struct loud_packet *packet = (struct loud_packet*) data; - // update will be done at next opportunity - equalizer_set_loudness(packet->loudness); - } else { - res = false; - } - - // chain protocol handlers (bitwise or is fine) - if (*slimp_handler_chain) res |= (*slimp_handler_chain)(data, len); - - return res; +static bool handler(u8_t* data, int len) { + bool res = true; + + if (!strncmp((char*)data, "eqlz", 4)) { + s8_t* gain = (s8_t*)(data + sizeof(struct eqlz_packet)); + // update will be done at next opportunity + equalizer_set_gain(gain); + } else if (!strncmp((char*)data, "loud", 4)) { + struct loud_packet* packet = (struct loud_packet*)data; + // update will be done at next opportunity + equalizer_set_loudness(packet->loudness); + } else { + res = false; + } + + // chain protocol handlers (bitwise or is fine) + if (*slimp_handler_chain) res |= (*slimp_handler_chain)(data, len); + + return res; } -void output_init_embedded(log_level level, char *device, unsigned output_buf_size, char *params, - unsigned rates[], unsigned rate_delay, unsigned idle) { - loglevel = level; - LOG_INFO("init device: %s", device); - - // chain handlers - slimp_handler_chain = slimp_handler; - slimp_handler = handler; - - // init equalizer before backends - equalizer_init(); - - memset(&output, 0, sizeof(output)); - output_init_common(level, device, output_buf_size, rates, idle); - output.start_frames = FRAME_BLOCK; - output.rate_delay = rate_delay; - -#if CONFIG_BT_SINK - if (strcasestr(device, "BT")) { - LOG_INFO("init Bluetooth"); - close_cb = &output_close_bt; - output_init_bt(level, device, output_buf_size, params, rates, rate_delay, idle); - } else -#endif - { - LOG_INFO("init I2S/SPDIF"); - close_cb = &output_close_i2s; - volume_cb = &output_volume_i2s; - output_init_i2s(level, device, output_buf_size, params, rates, rate_delay, idle); - } - - output_visu_init(level); - - LOG_INFO("init completed."); -} +void output_init_embedded() { + config = &platform->services.squeezelite; + loglevel = log_level_from_sys_level(config->log.output); + LOG_INFO("init device: %s", sys_OutputTypeEnum_name(config->output_type)); + + // chain handlers + slimp_handler_chain = slimp_handler; + slimp_handler = handler; + + // init equalizer before backends + equalizer_init(); + memset(&output, 0, sizeof(output)); + + output_init_common(loglevel, sys_OutputTypeEnum_name(config->output_type), + config->buffers.output, get_rates(), config->amp_gpio_timeout); + output.start_frames = FRAME_BLOCK; + #pragma message("Rate delay logic incomplete") + output.rate_delay = 0; + +#if CONFIG_BT_SINK + if (config->output_type == sys_OutputTypeEnum_OUTPUT_Bluetooth) { + LOG_INFO("init Bluetooth"); + close_cb = &output_close_bt; + output_init_bt(get_rates()); + } else +#endif + { + close_cb = &output_close_i2s; + volume_cb = &output_volume_i2s; + output_init_i2s(get_rates()); + } + + output_visu_init(loglevel); + + LOG_INFO("init completed."); +} void output_close_embedded(void) { - LOG_INFO("close output"); - if (close_cb) (*close_cb)(); - output_close_common(); - output_visu_close(); + LOG_INFO("close output"); + if (close_cb) (*close_cb)(); + output_close_common(); + output_visu_close(); } -void set_volume(unsigned left, unsigned right) { - LOG_DEBUG("setting internal gain left: %u right: %u", left, right); - if (!volume_cb || !(*volume_cb)(left, right)) { - LOCK; - output.gainL = left; - output.gainR = right; - UNLOCK; - } +void set_volume(unsigned left, unsigned right) { + LOG_DEBUG("setting internal gain left: %u right: %u", left, right); + if (!volume_cb || !(*volume_cb)(left, right)) { + LOCK; + output.gainL = left; + output.gainR = right; + UNLOCK; + } equalizer_set_volume(left, right); } -bool test_open(const char *device, unsigned rates[], bool userdef_rates) { - memset(rates, 0, MAX_SUPPORTED_SAMPLERATES * sizeof(unsigned)); - if (!strcasecmp(device, "I2S")) { - unsigned _rates[] = { -#if BYTES_PER_FRAME == 4 - 192000, 176400, -#endif - 96000, 88200, 48000, - 44100, 32000, 24000, 22050, 16000, - 12000, 11025, 8000, 0 }; - memcpy(rates, _rates, sizeof(_rates)); - } else if (!strcasecmp(device, "SPDIF")) { - unsigned _rates[] = { 96000, 88200, 48000, - 44100, 32000, 24000, 22050, 16000, - 12000, 11025, 8000, 0 }; - memcpy(rates, _rates, sizeof(_rates)); - } else { - rates[0] = 44100; - } - return true; +bool test_open(const char* device, unsigned rates[], bool userdef_rates) { + memset(rates, 0, MAX_SUPPORTED_SAMPLERATES * sizeof(unsigned)); + if (config->output_type == sys_OutputTypeEnum_OUTPUT_I2S) { + unsigned _rates[] = { +#if BYTES_PER_FRAME == 4 + 192000, + 176400, +#endif + 96000, + 88200, + 48000, + 44100, + 32000, + 24000, + 22050, + 16000, + 12000, + 11025, + 8000, + 0 + }; + memcpy(rates, _rates, sizeof(_rates)); + } else if (config->output_type == sys_OutputTypeEnum_OUTPUT_SPDIF) { + unsigned _rates[] = { + 96000, 88200, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 0}; + memcpy(rates, _rates, sizeof(_rates)); + } else { + rates[0] = 44100; + } + return true; } -char* output_state_str(void){ - output_state state; - LOCK; - state = output.state; - UNLOCK; - switch (state) { - case OUTPUT_OFF: return STR(OUTPUT_OFF); - case OUTPUT_STOPPED: return STR(OUTPUT_STOPPED); - case OUTPUT_BUFFER: return STR(OUTPUT_BUFFER); - case OUTPUT_RUNNING: return STR(OUTPUT_RUNNING); - case OUTPUT_PAUSE_FRAMES: return STR(OUTPUT_PAUSE_FRAMES); - case OUTPUT_SKIP_FRAMES: return STR(OUTPUT_SKIP_FRAMES); - case OUTPUT_START_AT: return STR(OUTPUT_START_AT); - default: return "OUTPUT_UNKNOWN_STATE"; - } +char* output_state_str(void) { + output_state state; + LOCK; + state = output.state; + UNLOCK; + switch (state) { + case OUTPUT_OFF: + return STR(OUTPUT_OFF); + case OUTPUT_STOPPED: + return STR(OUTPUT_STOPPED); + case OUTPUT_BUFFER: + return STR(OUTPUT_BUFFER); + case OUTPUT_RUNNING: + return STR(OUTPUT_RUNNING); + case OUTPUT_PAUSE_FRAMES: + return STR(OUTPUT_PAUSE_FRAMES); + case OUTPUT_SKIP_FRAMES: + return STR(OUTPUT_SKIP_FRAMES); + case OUTPUT_START_AT: + return STR(OUTPUT_START_AT); + default: + return "OUTPUT_UNKNOWN_STATE"; + } } bool output_stopped(void) { - output_state state; - LOCK; - state = output.state; - UNLOCK; - return state <= OUTPUT_STOPPED; -} - - - - + output_state state; + LOCK; + state = output.state; + UNLOCK; + return state <= OUTPUT_STOPPED; +} diff --git a/components/squeezelite/output_i2s.c b/components/squeezelite/output_i2s.c index d564c4ce..2222c50a 100644 --- a/components/squeezelite/output_i2s.c +++ b/components/squeezelite/output_i2s.c @@ -1,4 +1,4 @@ -/* +/* * Squeezelite for esp32 * * (c) Sebastien 2019 @@ -8,8 +8,8 @@ * https://opensource.org/licenses/MIT * */ - -/* + +/* Synchronisation is a bit of a hack with i2s. The esp32 driver is always full when it starts, so there is a delay of the total length of buffers. In other words, i2s_write blocks at first call, until at least one buffer @@ -18,14 +18,14 @@ has been written (it uses a queue with produce / consume). The first hack is to consume that length at the beginning of tracks when synchronization is active. It's about ~180ms @ 44.1kHz -The second hack is that we never know exactly the number of frames in the +The second hack is that we never know exactly the number of frames in the DMA buffers when we update the output.frames_played_dmp. We assume that after i2s_write, these buffers are always full so by measuring the gap between time after i2s_write and update of frames_played_dmp, we have a -good idea of the error. +good idea of the error. The third hack is when sample rate changes, buffers are reset and we also -do the change too early, but can't do that exaclty at the right time. So +do the change too early, but can't do that exaclty at the right time. So there might be a pop and a de-sync when sampling rate change happens. Not sure that using rate_delay would fix that */ @@ -43,49 +43,52 @@ sure that using rate_delay would fix that #include "led.h" #include "services.h" #include "monitor.h" -#include "platform_config.h" #include "gpio_exp.h" #include "accessors.h" #include "equalizer.h" #include "globdefs.h" +#include "Configurator.h" -#define LOCK mutex_lock(outputbuf->mutex) +extern log_level log_level_from_sys_level(sys_DebugLevelEnum level); +static sys_Squeezelite* config = NULL; + +#define LOCK mutex_lock(outputbuf->mutex) #define UNLOCK mutex_unlock(outputbuf->mutex) #define FRAME_BLOCK MAX_SILENCE_FRAMES -#define SPDIF_BLOCK 256 +#define SPDIF_BLOCK 256 /* we produce FRAME_BLOCK (2048) per loop of the i2s thread so it's better if they fit - * inside a set of DMA buffer nicely, i.e. DMA_BUF_FRAMES * DMA_BUF_COUNT is a multiple - * of FRAME_BLOCK so that each DMA buffer is filled and we fully empty a FRAME_BLOCK at - * each loop. Because one DMA buffer in esp32 is 4092 or below, when using 16 bits + * inside a set of DMA buffer nicely, i.e. DMA_BUF_FRAMES * DMA_BUF_COUNT is a multiple + * of FRAME_BLOCK so that each DMA buffer is filled and we fully empty a FRAME_BLOCK at + * each loop. Because one DMA buffer in esp32 is 4092 or below, when using 16 bits * samples and 2 channels, the best multiple is 512 (512*2*2=2048) and we use 6 of these. * In SPDIF, as we virtually use 32 bits per sample, the next proper multiple would * be 256 but such DMA buffers are too small and this causes stuttering. So we will use - * non-multiples which means that at every loop one DMA buffer will be not fully filled. - * At least, let's make sure it's not a too small amount of samples so 450*4*2=3600 fits + * non-multiples which means that at every loop one DMA buffer will be not fully filled. + * At least, let's make sure it's not a too small amount of samples so 450*4*2=3600 fits * nicely in one DMA buffer and 2048/450 = 4 buffers + ~1/2 buffer which is acceptable. */ -#define DMA_BUF_FRAMES 512 -#define DMA_BUF_COUNT 12 +#define DMA_BUF_FRAMES 512 +#define DMA_BUF_COUNT 12 -#define DMA_BUF_FRAMES_SPDIF 450 -#define DMA_BUF_COUNT_SPDIF 7 +#define DMA_BUF_FRAMES_SPDIF 450 +#define DMA_BUF_COUNT_SPDIF 7 -#define DECLARE_ALL_MIN_MAX \ - DECLARE_MIN_MAX(o); \ - DECLARE_MIN_MAX(s); \ - DECLARE_MIN_MAX(rec); \ - DECLARE_MIN_MAX(i2s_time); \ - DECLARE_MIN_MAX(buffering); +#define DECLARE_ALL_MIN_MAX \ + DECLARE_MIN_MAX(o); \ + DECLARE_MIN_MAX(s); \ + DECLARE_MIN_MAX(rec); \ + DECLARE_MIN_MAX(i2s_time); \ + DECLARE_MIN_MAX(buffering); + +#define RESET_ALL_MIN_MAX \ + RESET_MIN_MAX(o); \ + RESET_MIN_MAX(s); \ + RESET_MIN_MAX(rec); \ + RESET_MIN_MAX(i2s_time); \ + RESET_MIN_MAX(buffering); -#define RESET_ALL_MIN_MAX \ - RESET_MIN_MAX(o); \ - RESET_MIN_MAX(s); \ - RESET_MIN_MAX(rec); \ - RESET_MIN_MAX(i2s_time); \ - RESET_MIN_MAX(buffering); - #define STATS_PERIOD_MS 5000 static void (*pseudo_idle_chain)(uint32_t now); @@ -94,112 +97,100 @@ static void (*pseudo_idle_chain)(uint32_t now); #endif extern struct outputstate output; -extern struct buffer *streambuf; -extern struct buffer *outputbuf; -extern u8_t *silencebuf; +extern struct buffer* streambuf; +extern struct buffer* outputbuf; +extern u8_t* silencebuf; -const struct adac_s *dac_set[] = { &dac_tas57xx, &dac_tas5713, &dac_ac101, &dac_wm8978, NULL }; -const struct adac_s *adac = &dac_external; +const struct adac_s* dac_set[] = {&dac_tas57xx, &dac_tas5713, &dac_ac101, &dac_wm8978, NULL}; +const struct adac_s* adac = &dac_external; static log_level loglevel; static uint32_t i2s_idle_since; static void (*pseudo_idle_chain)(uint32_t); -static bool (*slimp_handler_chain)(u8_t *data, int len); +static bool (*slimp_handler_chain)(u8_t* data, int len); static bool jack_mutes_amp; static bool running, isI2SStarted, ended; static i2s_config_t i2s_config; -static u8_t *obuf; +static u8_t* obuf; static frames_t oframes; static struct { - bool enabled; - u8_t *buf; + bool enabled; + u8_t* buf; } spdif; static size_t dma_buf_frames; static TaskHandle_t output_i2s_task; static struct { - int gpio, active; -} amp_control = { CONFIG_AMP_GPIO, CONFIG_AMP_GPIO_LEVEL }, - mute_control = { CONFIG_MUTE_GPIO, CONFIG_MUTE_GPIO_LEVEL }; + int gpio, active; +} amp_control = {CONFIG_AMP_GPIO, CONFIG_AMP_GPIO_LEVEL}, + mute_control = {CONFIG_MUTE_GPIO, CONFIG_MUTE_GPIO_LEVEL}; DECLARE_ALL_MIN_MAX; -static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, - s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr); -static void output_thread_i2s(void *arg); +static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, + u8_t flags, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T** cross_ptr); +static void output_thread_i2s(void* arg); static void i2s_stats(uint32_t now); -static void spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst); +static void spdif_convert(ISAMPLE_T* src, size_t frames, u32_t* dst); static void (*jack_handler_chain)(bool inserted); -#define I2C_PORT 0 +#define I2C_PORT 0 /**************************************************************************************** * AUDO packet handler */ -static bool handler(u8_t *data, int len){ - bool res = true; - - if (!strncmp((char*) data, "audo", 4)) { - struct audo_packet *pkt = (struct audo_packet*) data; - // 0 = headphone (internal speakers off), 1 = sub out, - // 2 = always on (internal speakers on), 3 = always off +static bool handler(u8_t* data, int len) { + bool res = true; - if (jack_mutes_amp != (pkt->config == 0)) { - jack_mutes_amp = pkt->config == 0; - config_set_value(NVS_TYPE_STR, "jack_mutes_amp", jack_mutes_amp ? "y" : "n"); - - if (jack_mutes_amp && jack_inserted_svc()) { - adac->speaker(false); - if (amp_control.gpio != -1) gpio_set_level_x(amp_control.gpio, !amp_control.active); - } else { - adac->speaker(true); - if (amp_control.gpio != -1) gpio_set_level_x(amp_control.gpio, amp_control.active); - } - } + if (!strncmp((char*)data, "audo", 4)) { + struct audo_packet* pkt = (struct audo_packet*)data; + // 0 = headphone (internal speakers off), 1 = sub out, + // 2 = always on (internal speakers on), 3 = always off - LOG_INFO("got AUDO %02x", pkt->config); - } else { - res = false; - } - - // chain protocol handlers (bitwise or is fine) - if (*slimp_handler_chain) res |= (*slimp_handler_chain)(data, len); - - return res; + if (jack_mutes_amp != (pkt->config == 0)) { + jack_mutes_amp = pkt->config == 0; + platform->dev.dac.jack_mutes_amp = jack_mutes_amp; + configurator_raise_changed(); + + if (jack_mutes_amp && jack_inserted_svc()) { + adac->speaker(false); + if (amp_control.gpio != -1) gpio_set_level_x(amp_control.gpio, !amp_control.active); + } else { + adac->speaker(true); + if (amp_control.gpio != -1) gpio_set_level_x(amp_control.gpio, amp_control.active); + } + } + + LOG_INFO("got AUDO %02x", pkt->config); + } else { + res = false; + } + + // chain protocol handlers (bitwise or is fine) + if (*slimp_handler_chain) res |= (*slimp_handler_chain)(data, len); + + return res; } /**************************************************************************************** * jack insertion handler */ static void jack_handler(bool inserted) { - // jack detection bounces a bit but that seems fine - if (jack_mutes_amp) { - LOG_INFO("switching amplifier %s", inserted ? "OFF" : "ON"); - adac->speaker(!inserted); - if (amp_control.gpio != -1) gpio_set_level_x(amp_control.gpio, inserted ? !amp_control.active : amp_control.active); - } - - // activate headset - adac->headset(inserted); - - // and chain if any - if (jack_handler_chain) (jack_handler_chain)(inserted); -} + // jack detection bounces a bit but that seems fine + if (jack_mutes_amp) { + LOG_INFO("switching amplifier %s", inserted ? "OFF" : "ON"); + adac->speaker(!inserted); + if (amp_control.gpio != -1) + gpio_set_level_x(amp_control.gpio, inserted ? !amp_control.active : amp_control.active); + } -/**************************************************************************************** - * amp GPIO - */ -#ifndef AMP_LOCKED -static void set_amp_gpio(int gpio, char *value) { - char *p; - - if (strcasestr(value, "amp")) { - amp_control.gpio = gpio; - if ((p = strchr(value, ':')) != NULL) amp_control.active = atoi(p + 1); - } -} -#endif + // activate headset + adac->headset(inserted); + + // and chain if any + if (jack_handler_chain) (jack_handler_chain)(inserted); +} /**************************************************************************************** * Get inactivity callback @@ -208,141 +199,127 @@ static uint32_t i2s_idle_callback(void) { return output.state <= OUTPUT_STOPPED ? pdTICKS_TO_MS(xTaskGetTickCount()) - i2s_idle_since : 0; } -/**************************************************************************************** - * Set pin from config string - */ -static void set_i2s_pin(char *config, i2s_pin_config_t *pin_config) { - pin_config->bck_io_num = pin_config->ws_io_num = pin_config->data_out_num = pin_config->data_in_num = -1; - PARSE_PARAM(config, "bck", '=', pin_config->bck_io_num); - PARSE_PARAM(config, "ws", '=', pin_config->ws_io_num); - PARSE_PARAM(config, "do", '=', pin_config->data_out_num); -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) - pin_config->mck_io_num = strcasestr(config, "mck") ? 0 : -1; - PARSE_PARAM(config, "mck", '=', pin_config->mck_io_num); -#endif -} - /**************************************************************************************** * Initialize the DAC output */ -void output_init_i2s(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) { - loglevel = level; - int silent_do = -1; - char *p; - esp_err_t res; +void output_init_i2s() { + int silent_do = -1; + config = &platform->services.squeezelite; + sys_DAC* dac_config = platform->has_dev && platform->dev.has_dac ? &platform->dev.dac : NULL; + sys_SPDIF* spdif_config = + platform->has_dev && platform->dev.has_spdif ? &platform->dev.spdif : NULL; + loglevel = log_level_from_sys_level(config->log.output); + esp_err_t res; + + // chain SLIMP handlers + slimp_handler_chain = slimp_handler; + slimp_handler = handler; + if (dac_config) jack_mutes_amp = dac_config->jack_mutes_amp; + if (platform->has_gpios) { + amp_control.gpio = platform->has_gpios && platform->gpios.has_amp ? platform->gpios.amp.pin:-1; + amp_control.active = platform->has_gpios && platform->gpios.has_amp ? platform->gpios.amp.level:0; + } - // chain SLIMP handlers - slimp_handler_chain = slimp_handler; - slimp_handler = handler; - - p = config_alloc_get_default(NVS_TYPE_STR, "jack_mutes_amp", "n", 0); - jack_mutes_amp = (strcmp(p,"1") == 0 ||strcasecmp(p,"y") == 0); - free(p); - #if BYTES_PER_FRAME == 8 - output.format = S32_LE; + output.format = S32_LE; #else - output.format = S16_LE; + output.format = S16_LE; #endif - output.write_cb = &_i2s_write_frames; - - obuf = malloc(FRAME_BLOCK * BYTES_PER_FRAME); - if (!obuf) { - LOG_ERROR("Cannot allocate i2s buffer"); - return; - } - - running = true; + output.write_cb = &_i2s_write_frames; - // get SPDIF configuration from NVS or compile - char *spdif_config = config_alloc_get_str("spdif_config", CONFIG_SPDIF_CONFIG, "bck=" STR(CONFIG_SPDIF_BCK_IO) - ",ws=" STR(CONFIG_SPDIF_WS_IO) ",do=" STR(CONFIG_SPDIF_DO_IO)); - - char *dac_config = config_alloc_get_str("dac_config", CONFIG_DAC_CONFIG, "model=i2s,bck=" STR(CONFIG_I2S_BCK_IO) - ",ws=" STR(CONFIG_I2S_WS_IO) ",do=" STR(CONFIG_I2S_DO_IO) ",mck=" STR(CONFIG_I2S_MCK_IO) - ",sda=" STR(CONFIG_I2C_SDA) ",scl=" STR(CONFIG_I2C_SCL) - ",mute=" STR(CONFIG_MUTE_GPIO)); + obuf = malloc(FRAME_BLOCK * BYTES_PER_FRAME); + if (!obuf) { + LOG_ERROR("Cannot allocate i2s buffer"); + return; + } + + running = true; + + i2s_pin_config_t i2s_dac_pin = {-1, -1, -1, -1}, i2s_spdif_pin = {-1, -1, -1, -1}; + if (dac_config) { + i2s_dac_pin.bck_io_num = dac_config->has_bck ? dac_config->bck.pin : -1; + i2s_dac_pin.data_out_num = dac_config->has_dout ? dac_config->dout.pin : -1; + i2s_dac_pin.ws_io_num = dac_config->has_ws ? dac_config->ws.pin : -1; + } + if (spdif_config) { + i2s_spdif_pin.bck_io_num = spdif_config->has_clk ? spdif_config->clk.pin : -1; + i2s_spdif_pin.data_out_num = spdif_config->has_data ? spdif_config->data.pin : -1; + i2s_spdif_pin.ws_io_num = spdif_config->has_dc ? spdif_config->dc.pin : -1; + } - i2s_pin_config_t i2s_dac_pin, i2s_spdif_pin; - set_i2s_pin(spdif_config, &i2s_spdif_pin); - set_i2s_pin(dac_config, &i2s_dac_pin); - if (i2s_dac_pin.data_out_num == -1 && i2s_spdif_pin.data_out_num == -1) { LOG_WARN("DAC and SPDIF not configured, NOT launching i2s thread"); return; } - - // common I2S initialization - i2s_config.mode = I2S_MODE_MASTER | I2S_MODE_TX; - i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT; - i2s_config.communication_format = I2S_COMM_FORMAT_STAND_I2S; - // in case of overflow, do not replay old buffer - i2s_config.tx_desc_auto_clear = true; + + // common I2S initialization + i2s_config.mode = I2S_MODE_MASTER | I2S_MODE_TX; + i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT; + i2s_config.communication_format = I2S_COMM_FORMAT_STAND_I2S; + // in case of overflow, do not replay old buffer + i2s_config.tx_desc_auto_clear = true; #ifndef CONFIG_IDF_TARGET_ESP32S3 i2s_config.use_apll = true; -#endif - i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1; //Interrupt level 1 - i2s_config.dma_buf_len = DMA_BUF_FRAMES; - i2s_config.dma_buf_count = DMA_BUF_COUNT; - - if (strcasestr(device, "spdif")) { - spdif.enabled = true; - if ((spdif.buf = heap_caps_malloc(SPDIF_BLOCK * 16, MALLOC_CAP_INTERNAL)) == NULL) { - LOG_ERROR("Cannot allocate SPDIF buffer"); - } - - if (i2s_spdif_pin.bck_io_num == -1 || i2s_spdif_pin.ws_io_num == -1 || i2s_spdif_pin.data_out_num == -1) { - LOG_WARN("Cannot initialize I2S for SPDIF bck:%d ws:%d do:%d", i2s_spdif_pin.bck_io_num, - i2s_spdif_pin.ws_io_num, - i2s_spdif_pin.data_out_num); - } - - i2s_config.sample_rate = output.current_sample_rate * 2; - i2s_config.bits_per_sample = 32; - // Normally counted in frames, but 16 sample are transformed into 32 bits in spdif - i2s_config.dma_buf_len = DMA_BUF_FRAMES_SPDIF; - i2s_config.dma_buf_count = DMA_BUF_COUNT_SPDIF; - /* - In DMA, we have room for (LEN * COUNT) frames of 32 bits samples that - we push at sample_rate * 2. Each of these pseudo-frames is a single true - audio frame. So the real depth in true frames is (LEN * COUNT / 2) - */ - dma_buf_frames = i2s_config.dma_buf_len * i2s_config.dma_buf_count / 2; - - // silence DAC output if sharing the same ws/bck - if (i2s_dac_pin.ws_io_num == i2s_spdif_pin.ws_io_num && i2s_dac_pin.bck_io_num == i2s_spdif_pin.bck_io_num) silent_do = i2s_dac_pin.data_out_num; - - res = i2s_driver_install(CONFIG_I2S_NUM, &i2s_config, 0, NULL); - res |= i2s_set_pin(CONFIG_I2S_NUM, &i2s_spdif_pin); - LOG_INFO("SPDIF using I2S bck:%d, ws:%d, do:%d", i2s_spdif_pin.bck_io_num, i2s_spdif_pin.ws_io_num, i2s_spdif_pin.data_out_num); - } else { - i2s_config.sample_rate = output.current_sample_rate; - i2s_config.bits_per_sample = BYTES_PER_FRAME * 8 / 2; - // Counted in frames (but i2s allocates a buffer <= 4092 bytes) - i2s_config.dma_buf_len = DMA_BUF_FRAMES; - i2s_config.dma_buf_count = DMA_BUF_COUNT; - dma_buf_frames = i2s_config.dma_buf_len * i2s_config.dma_buf_count; - - // silence SPDIF output - silent_do = i2s_spdif_pin.data_out_num; +#endif + i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1; // Interrupt level 1 + i2s_config.dma_buf_len = DMA_BUF_FRAMES; + i2s_config.dma_buf_count = DMA_BUF_COUNT; - char model[32] = "i2s"; - if ((p = strcasestr(dac_config, "model")) != NULL) sscanf(p, "%*[^=]=%31[^,]", model); - if ((p = strcasestr(dac_config, "mute")) != NULL) { - char mute[8] = ""; - sscanf(p, "%*[^=]=%7[^,]", mute); - mute_control.gpio = atoi(mute); - if ((p = strchr(mute, ':')) != NULL) mute_control.active = atoi(p + 1); - } + if (config->output_type == sys_OutputTypeEnum_OUTPUT_SPDIF) { + spdif.enabled = true; + if ((spdif.buf = heap_caps_malloc(SPDIF_BLOCK * 16, MALLOC_CAP_INTERNAL)) == NULL) { + LOG_ERROR("Cannot allocate SPDIF buffer"); + } + if (i2s_spdif_pin.bck_io_num == -1 || i2s_spdif_pin.ws_io_num == -1 || + i2s_spdif_pin.data_out_num == -1) { + LOG_WARN("Cannot initialize I2S for SPDIF bck:%d ws:%d do:%d", i2s_spdif_pin.bck_io_num, + i2s_spdif_pin.ws_io_num, i2s_spdif_pin.data_out_num); + } + + i2s_config.sample_rate = output.current_sample_rate * 2; + i2s_config.bits_per_sample = 32; + // Normally counted in frames, but 16 sample are transformed into 32 bits in spdif + i2s_config.dma_buf_len = DMA_BUF_FRAMES_SPDIF; + i2s_config.dma_buf_count = DMA_BUF_COUNT_SPDIF; + /* + In DMA, we have room for (LEN * COUNT) frames of 32 bits samples that + we push at sample_rate * 2. Each of these pseudo-frames is a single true + audio frame. So the real depth in true frames is (LEN * COUNT / 2) + */ + dma_buf_frames = i2s_config.dma_buf_len * i2s_config.dma_buf_count / 2; + + // silence DAC output if sharing the same ws/bck + if (i2s_dac_pin.ws_io_num == i2s_spdif_pin.ws_io_num && + i2s_dac_pin.bck_io_num == i2s_spdif_pin.bck_io_num) + silent_do = i2s_dac_pin.data_out_num; + + res = i2s_driver_install(CONFIG_I2S_NUM, &i2s_config, 0, NULL); + res |= i2s_set_pin(CONFIG_I2S_NUM, &i2s_spdif_pin); + LOG_INFO("SPDIF using I2S bck:%d, ws:%d, do:%d", i2s_spdif_pin.bck_io_num, + i2s_spdif_pin.ws_io_num, i2s_spdif_pin.data_out_num); + } else { + i2s_config.sample_rate = output.current_sample_rate; + i2s_config.bits_per_sample = BYTES_PER_FRAME * 8 / 2; + // Counted in frames (but i2s allocates a buffer <= 4092 bytes) + i2s_config.dma_buf_len = DMA_BUF_FRAMES; + i2s_config.dma_buf_count = DMA_BUF_COUNT; + dma_buf_frames = i2s_config.dma_buf_len * i2s_config.dma_buf_count; + + // silence SPDIF output + silent_do = i2s_spdif_pin.data_out_num; + mute_control.gpio = dac_config && dac_config->has_mute ? dac_config->mute.pin : -1; + mute_control.active = dac_config && dac_config->has_mute ? dac_config->mute.level : 0; bool mck_required = false; - for (int i = 0; adac == &dac_external && dac_set[i]; i++) if (strcasestr(dac_set[i]->model, model)) adac = dac_set[i]; - res = adac->init(dac_config, I2C_PORT, &i2s_config, &mck_required) ? ESP_OK : ESP_FAIL; - -#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 0) - int mck_io_num = strcasestr(dac_config, "mck") || mck_required ? 0 : -1; - PARSE_PARAM(dac_config, "mck", '=', mck_io_num); + for (int i = 0; adac == &dac_external && dac_set[i]; i++) + if (dac_set[i]->model == dac_config->model) adac = dac_set[i]; + res = adac->init(NULL, I2C_PORT, &i2s_config, &mck_required) ? ESP_OK : ESP_FAIL; + +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 0) + int mck_io_num = (dac_config->mck - sys_MCKEnum_MCK0) < 0 && mck_required + ? 0 + : dac_config->mck - sys_MCKEnum_MCK0; LOG_INFO("configuring MCLK on GPIO %d", mck_io_num); @@ -361,288 +338,296 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch #else if (mck_required && i2s_dac_pin.mck_io_num == -1) i2s_dac_pin.mck_io_num = 0; LOG_INFO("configuring MCLK on GPIO %d", i2s_dac_pin.mck_io_num); -#endif - - res |= i2s_driver_install(CONFIG_I2S_NUM, &i2s_config, 0, NULL); - res |= i2s_set_pin(CONFIG_I2S_NUM, &i2s_dac_pin); - - if (res == ESP_OK && mute_control.gpio >= 0) { - gpio_pad_select_gpio(mute_control.gpio); - gpio_set_direction(mute_control.gpio, GPIO_MODE_OUTPUT); - gpio_set_level(mute_control.gpio, mute_control.active); - } - - LOG_INFO("%s DAC using I2S bck:%d, ws:%d, do:%d, mute:%d:%d (res:%d)", model, i2s_dac_pin.bck_io_num, i2s_dac_pin.ws_io_num, - i2s_dac_pin.data_out_num, mute_control.gpio, mute_control.active, res); - } - - free(dac_config); - free(spdif_config); - - if (res != ESP_OK) { - LOG_WARN("no DAC configured"); - return; - } - - // turn off GPIO than is not used (SPDIF of DAC DO when shared) - if (silent_do >= 0) { - gpio_pad_select_gpio(silent_do); - gpio_set_direction(silent_do, GPIO_MODE_OUTPUT); - gpio_set_level(silent_do, 0); - } - - LOG_INFO("Initializing I2S mode %s with rate: %d, bits per sample: %d, buffer frames: %d, number of buffers: %d ", - spdif.enabled ? "S/PDIF" : "normal", - i2s_config.sample_rate, i2s_config.bits_per_sample, i2s_config.dma_buf_len, i2s_config.dma_buf_count); - - i2s_stop(CONFIG_I2S_NUM); - i2s_zero_dma_buffer(CONFIG_I2S_NUM); - isI2SStarted=false; - - equalizer_set_samplerate(output.current_sample_rate); - - adac->power(ADAC_STANDBY); - - jack_handler_chain = jack_handler_svc; - jack_handler_svc = jack_handler; - -#ifndef AMP_LOCKED - parse_set_GPIO(set_amp_gpio); #endif - if (amp_control.gpio != -1) { - gpio_pad_select_gpio_x(amp_control.gpio); - gpio_set_direction_x(amp_control.gpio, GPIO_MODE_OUTPUT); - gpio_set_level_x(amp_control.gpio, !amp_control.active); - LOG_INFO("setting amplifier GPIO %d (active:%d)", amp_control.gpio, amp_control.active); - } + res |= i2s_driver_install(CONFIG_I2S_NUM, &i2s_config, 0, NULL); + res |= i2s_set_pin(CONFIG_I2S_NUM, &i2s_dac_pin); + + if (res == ESP_OK && mute_control.gpio >= 0) { + gpio_pad_select_gpio(mute_control.gpio); + gpio_set_direction(mute_control.gpio, GPIO_MODE_OUTPUT); + gpio_set_level(mute_control.gpio, mute_control.active); + } + + LOG_INFO("%s DAC using I2S bck:%d, ws:%d, do:%d, mute:%d:%d (res:%d)", + sys_EthModelEnum_name(dac_config->model), i2s_dac_pin.bck_io_num, i2s_dac_pin.ws_io_num, + i2s_dac_pin.data_out_num, mute_control.gpio, mute_control.active, res); + } + + if (res != ESP_OK) { + LOG_WARN("no DAC configured"); + return; + } + + // turn off GPIO than is not used (SPDIF of DAC DO when shared) + if (silent_do >= 0) { + gpio_pad_select_gpio(silent_do); + gpio_set_direction(silent_do, GPIO_MODE_OUTPUT); + gpio_set_level(silent_do, 0); + } + + LOG_INFO("Initializing I2S mode %s with rate: %d, bits per sample: %d, buffer frames: %d, " + "number of buffers: %d ", + spdif.enabled ? "S/PDIF" : "normal", i2s_config.sample_rate, i2s_config.bits_per_sample, + i2s_config.dma_buf_len, i2s_config.dma_buf_count); + + i2s_stop(CONFIG_I2S_NUM); + i2s_zero_dma_buffer(CONFIG_I2S_NUM); + isI2SStarted = false; + + equalizer_set_samplerate(output.current_sample_rate); + + adac->power(ADAC_STANDBY); + + jack_handler_chain = jack_handler_svc; + jack_handler_svc = jack_handler; + if (amp_control.gpio != -1) { + gpio_pad_select_gpio_x(amp_control.gpio); + gpio_set_direction_x(amp_control.gpio, GPIO_MODE_OUTPUT); + gpio_set_level_x(amp_control.gpio, !amp_control.active); + LOG_INFO("setting amplifier GPIO %d (active:%d)", amp_control.gpio, amp_control.active); + } + + if (jack_mutes_amp && jack_inserted_svc()) + adac->speaker(false); + else + adac->speaker(true); + + adac->headset(jack_inserted_svc()); - if (jack_mutes_amp && jack_inserted_svc()) adac->speaker(false); - else adac->speaker(true); - - adac->headset(jack_inserted_svc()); - // do we want stats - p = config_alloc_get_default(NVS_TYPE_STR, "stats", "n", 0); - if (p && (*p == '1' || *p == 'Y' || *p == 'y')) { + if (platform->has_services && platform->services.statistics) { pseudo_idle_chain = pseudo_idle_svc; pseudo_idle_svc = i2s_stats; } - free(p); // register a callback for inactivity - i2s_idle_since = pdTICKS_TO_MS(xTaskGetTickCount()); + i2s_idle_since = pdTICKS_TO_MS(xTaskGetTickCount()); services_sleep_setsleeper(i2s_idle_callback); - - // create task as a FreeRTOS task but uses stack in internal RAM - { - static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4))); - static EXT_RAM_ATTR StackType_t xStack[OUTPUT_THREAD_STACK_SIZE] __attribute__ ((aligned (4))); - output_i2s_task = xTaskCreateStaticPinnedToCore( (TaskFunction_t) output_thread_i2s, "output_i2s", OUTPUT_THREAD_STACK_SIZE, - NULL, CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT + 1, xStack, &xTaskBuffer, 0 ); - } + + // create task as a FreeRTOS task but uses stack in internal RAM + { + static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__((aligned(4))); + static EXT_RAM_ATTR StackType_t xStack[OUTPUT_THREAD_STACK_SIZE] + __attribute__((aligned(4))); + output_i2s_task = xTaskCreateStaticPinnedToCore((TaskFunction_t)output_thread_i2s, + "output_i2s", OUTPUT_THREAD_STACK_SIZE, NULL, + CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT + 1, xStack, &xTaskBuffer, 0); + } } /**************************************************************************************** * Terminate DAC output */ void output_close_i2s(void) { - LOCK; - running = false; - UNLOCK; - - while (!ended) vTaskDelay(20 / portTICK_PERIOD_MS); - - i2s_driver_uninstall(CONFIG_I2S_NUM); - free(obuf); - - equalizer_close(); - - adac->deinit(); + LOCK; + running = false; + UNLOCK; + + while (!ended) + vTaskDelay(20 / portTICK_PERIOD_MS); + + i2s_driver_uninstall(CONFIG_I2S_NUM); + free(obuf); + + equalizer_close(); + + adac->deinit(); } /**************************************************************************************** * change volume */ bool output_volume_i2s(unsigned left, unsigned right) { - if (mute_control.gpio >= 0) gpio_set_level(mute_control.gpio, (left | right) ? !mute_control.active : mute_control.active); - return adac->volume(left, right); -} + if (mute_control.gpio >= 0) + gpio_set_level( + mute_control.gpio, (left | right) ? !mute_control.active : mute_control.active); + return adac->volume(left, right); +} /**************************************************************************************** * Write frames to the output buffer */ -static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, - s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) { - if (!silence) { - if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) { - _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr); - } - - _apply_gain(outputbuf, out_frames, gainL, gainR, flags); - memcpy(obuf + oframes * BYTES_PER_FRAME, outputbuf->readp, out_frames * BYTES_PER_FRAME); - } else { - memcpy(obuf + oframes * BYTES_PER_FRAME, silencebuf, out_frames * BYTES_PER_FRAME); - } +static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, + u8_t flags, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T** cross_ptr) { + if (!silence) { + if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) { + _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr); + } - // don't update visu if we don't have enough data in buffer - if (silence || output.external || _buf_used(outputbuf) > outputbuf->size >> 2 ) { - output_visu_export(obuf + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, silence, (gainL + gainR) / 2); - } - - oframes += out_frames; - - return out_frames; + _apply_gain(outputbuf, out_frames, gainL, gainR, flags); + memcpy(obuf + oframes * BYTES_PER_FRAME, outputbuf->readp, out_frames * BYTES_PER_FRAME); + } else { + memcpy(obuf + oframes * BYTES_PER_FRAME, silencebuf, out_frames * BYTES_PER_FRAME); + } + + // don't update visu if we don't have enough data in buffer + if (silence || output.external || _buf_used(outputbuf) > outputbuf->size >> 2) { + output_visu_export(obuf + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, + silence, (gainL + gainR) / 2); + } + + oframes += out_frames; + + return out_frames; } /**************************************************************************************** * Main output thread */ -static void output_thread_i2s(void *arg) { - size_t bytes; - frames_t iframes = FRAME_BLOCK; - uint32_t timer_start = 0; - int discard = 0; - uint32_t fullness = gettime_ms(); - bool synced; - output_state state = OUTPUT_OFF - 1; - - while (running) { - - TIME_MEASUREMENT_START(timer_start); +static void output_thread_i2s(void* arg) { + size_t bytes; + frames_t iframes = FRAME_BLOCK; + uint32_t timer_start = 0; + int discard = 0; + uint32_t fullness = gettime_ms(); + bool synced; + output_state state = OUTPUT_OFF - 1; - LOCK; - - // manage led display & analogue - if (state != output.state) { - LOG_INFO("Output state is %d", output.state); - if (output.state == OUTPUT_OFF) { - led_blink(LED_GREEN, 100, 2500); - if (amp_control.gpio != -1) gpio_set_level_x(amp_control.gpio, !amp_control.active); - LOG_INFO("switching off amp GPIO %d", amp_control.gpio); - } else if (output.state == OUTPUT_STOPPED) { + while (running) { + + TIME_MEASUREMENT_START(timer_start); + + LOCK; + + // manage led display & analogue + if (state != output.state) { + LOG_INFO("Output state is %d", output.state); + if (output.state == OUTPUT_OFF) { + led_blink(LED_GREEN, 100, 2500); + if (amp_control.gpio != -1) gpio_set_level_x(amp_control.gpio, !amp_control.active); + LOG_INFO("switching off amp GPIO %d", amp_control.gpio); + } else if (output.state == OUTPUT_STOPPED) { i2s_idle_since = pdTICKS_TO_MS(xTaskGetTickCount()); - adac->speaker(false); - led_blink(LED_GREEN, 200, 1000); - } else if (output.state == OUTPUT_RUNNING) { - if (!jack_mutes_amp || !jack_inserted_svc()) { - if (amp_control.gpio != -1) gpio_set_level_x(amp_control.gpio, amp_control.active); - adac->speaker(true); - } - led_on(LED_GREEN); - } - } - state = output.state; - - if (output.state == OUTPUT_OFF) { - UNLOCK; - if (isI2SStarted) { - isI2SStarted = false; - i2s_stop(CONFIG_I2S_NUM); - adac->power(ADAC_STANDBY); - } - usleep(100000); - continue; - } else if (output.state == OUTPUT_STOPPED) { - synced = false; - } - - oframes = 0; - output.updated = gettime_ms(); - output.frames_played_dmp = output.frames_played; - // try to estimate how much we have consumed from the DMA buffer (calculation is incorrect at the very beginning ...) - output.device_frames = dma_buf_frames - ((output.updated - fullness) * output.current_sample_rate) / 1000; - // we'll try to produce iframes if we have any, but we might return less if outpuf does not have enough - _output_frames( iframes ); - // oframes must be a global updated by the write callback - output.frames_in_process = oframes; - - SET_MIN_MAX_SIZED(oframes,rec,iframes); - SET_MIN_MAX_SIZED(_buf_used(outputbuf),o,outputbuf->size); - SET_MIN_MAX_SIZED(_buf_used(streambuf),s,streambuf->size); - SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),buffering); - - /* must skip first whatever is in the pipe (but not when resuming). - This test is incorrect when we pause a track that has just started, - but this is higly unlikely and I don't have a better one for now */ - if (output.state == OUTPUT_START_AT) { - discard = output.frames_played_dmp ? 0 : output.device_frames; - synced = true; - } else if (discard) { + adac->speaker(false); + led_blink(LED_GREEN, 200, 1000); + } else if (output.state == OUTPUT_RUNNING) { + if (!jack_mutes_amp || !jack_inserted_svc()) { + if (amp_control.gpio != -1) + gpio_set_level_x(amp_control.gpio, amp_control.active); + adac->speaker(true); + } + led_on(LED_GREEN); + } + } + state = output.state; + + if (output.state == OUTPUT_OFF) { + UNLOCK; + if (isI2SStarted) { + isI2SStarted = false; + i2s_stop(CONFIG_I2S_NUM); + adac->power(ADAC_STANDBY); + } + usleep(100000); + continue; + } else if (output.state == OUTPUT_STOPPED) { + synced = false; + } + + oframes = 0; + output.updated = gettime_ms(); + output.frames_played_dmp = output.frames_played; + // try to estimate how much we have consumed from the DMA buffer (calculation is incorrect + // at the very beginning ...) + output.device_frames = + dma_buf_frames - ((output.updated - fullness) * output.current_sample_rate) / 1000; + // we'll try to produce iframes if we have any, but we might return less if outpuf does not + // have enough + _output_frames(iframes); + // oframes must be a global updated by the write callback + output.frames_in_process = oframes; + + SET_MIN_MAX_SIZED(oframes, rec, iframes); + SET_MIN_MAX_SIZED(_buf_used(outputbuf), o, outputbuf->size); + SET_MIN_MAX_SIZED(_buf_used(streambuf), s, streambuf->size); + SET_MIN_MAX(TIME_MEASUREMENT_GET(timer_start), buffering); + + /* must skip first whatever is in the pipe (but not when resuming). + This test is incorrect when we pause a track that has just started, + but this is higly unlikely and I don't have a better one for now */ + if (output.state == OUTPUT_START_AT) { + discard = output.frames_played_dmp ? 0 : output.device_frames; + synced = true; + } else if (discard) { discard -= min(oframes, discard); iframes = discard ? min(FRAME_BLOCK, discard) : FRAME_BLOCK; - UNLOCK; - continue; - } + UNLOCK; + continue; + } - UNLOCK; - - // now send all the data - TIME_MEASUREMENT_START(timer_start); - - if (!isI2SStarted ) { - isI2SStarted = true; - LOG_INFO("Restarting I2S."); - i2s_zero_dma_buffer(CONFIG_I2S_NUM); - i2s_start(CONFIG_I2S_NUM); - adac->power(ADAC_ON); + UNLOCK; + + // now send all the data + TIME_MEASUREMENT_START(timer_start); + + if (!isI2SStarted) { + isI2SStarted = true; + LOG_INFO("Restarting I2S."); + i2s_zero_dma_buffer(CONFIG_I2S_NUM); + i2s_start(CONFIG_I2S_NUM); + adac->power(ADAC_ON); if (spdif.enabled) spdif_convert(NULL, 0, NULL); - } + } - // this does not work well as set_sample_rates resets the fifos (and it's too early) - if (i2s_config.sample_rate != output.current_sample_rate) { - LOG_INFO("changing sampling rate %u to %u", i2s_config.sample_rate, output.current_sample_rate); - if (synced) { - /* - // can sleep for a buffer_queue - 1 and then eat a buffer (discard) if we are synced - usleep(((DMA_BUF_COUNT - 1) * DMA_BUF_LEN * BYTES_PER_FRAME * 1000) / 44100 * 1000); - discard = DMA_BUF_COUNT * DMA_BUF_LEN * BYTES_PER_FRAME; - */ - } - i2s_config.sample_rate = output.current_sample_rate; - i2s_set_sample_rates(CONFIG_I2S_NUM, spdif.enabled ? i2s_config.sample_rate * 2 : i2s_config.sample_rate); - i2s_zero_dma_buffer(CONFIG_I2S_NUM); + // this does not work well as set_sample_rates resets the fifos (and it's too early) + if (i2s_config.sample_rate != output.current_sample_rate) { + LOG_INFO("changing sampling rate %u to %u", i2s_config.sample_rate, + output.current_sample_rate); + if (synced) { + /* + // can sleep for a buffer_queue - 1 and then eat a buffer (discard) if we are + synced usleep(((DMA_BUF_COUNT - 1) * DMA_BUF_LEN * BYTES_PER_FRAME * 1000) / + 44100 * 1000); discard = DMA_BUF_COUNT * DMA_BUF_LEN * BYTES_PER_FRAME; + */ + } + i2s_config.sample_rate = output.current_sample_rate; + i2s_set_sample_rates(CONFIG_I2S_NUM, + spdif.enabled ? i2s_config.sample_rate * 2 : i2s_config.sample_rate); + i2s_zero_dma_buffer(CONFIG_I2S_NUM); equalizer_set_samplerate(output.current_sample_rate); - } - - // run equalizer - equalizer_process(obuf, oframes * BYTES_PER_FRAME); + } - // we assume that here we have been able to entirely fill the DMA buffers - if (spdif.enabled) { - size_t obytes, count = 0; - bytes = 0; - // need IRAM for speed but can't allocate a FRAME_BLOCK * 16, so process by smaller chunks - while (count < oframes) { - size_t chunk = min(SPDIF_BLOCK, oframes - count); - spdif_convert((ISAMPLE_T*) obuf + count * 2, chunk, (u32_t*) spdif.buf); - i2s_write(CONFIG_I2S_NUM, spdif.buf, chunk * 16, &obytes, portMAX_DELAY); - bytes += obytes / (16 / BYTES_PER_FRAME); - count += chunk; - } -#if BYTES_PER_FRAME == 4 - } else if (i2s_config.bits_per_sample == 32) { - i2s_write_expand(CONFIG_I2S_NUM, obuf, oframes * BYTES_PER_FRAME, 16, 32, &bytes, portMAX_DELAY); -#endif - } else { - i2s_write(CONFIG_I2S_NUM, obuf, oframes * BYTES_PER_FRAME, &bytes, portMAX_DELAY); - } + // run equalizer + equalizer_process(obuf, oframes * BYTES_PER_FRAME); - fullness = gettime_ms(); + // we assume that here we have been able to entirely fill the DMA buffers + if (spdif.enabled) { + size_t obytes, count = 0; + bytes = 0; + // need IRAM for speed but can't allocate a FRAME_BLOCK * 16, so process by smaller + // chunks + while (count < oframes) { + size_t chunk = min(SPDIF_BLOCK, oframes - count); + spdif_convert((ISAMPLE_T*)obuf + count * 2, chunk, (u32_t*)spdif.buf); + i2s_write(CONFIG_I2S_NUM, spdif.buf, chunk * 16, &obytes, portMAX_DELAY); + bytes += obytes / (16 / BYTES_PER_FRAME); + count += chunk; + } +#if BYTES_PER_FRAME == 4 + } else if (i2s_config.bits_per_sample == 32) { + i2s_write_expand( + CONFIG_I2S_NUM, obuf, oframes * BYTES_PER_FRAME, 16, 32, &bytes, portMAX_DELAY); +#endif + } else { + i2s_write(CONFIG_I2S_NUM, obuf, oframes * BYTES_PER_FRAME, &bytes, portMAX_DELAY); + } - if (bytes != oframes * BYTES_PER_FRAME) { - LOG_WARN("I2S DMA Overflow! available bytes: %d, I2S wrote %d bytes", oframes * BYTES_PER_FRAME, bytes); - } - - SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),i2s_time); - - } + fullness = gettime_ms(); - if (spdif.enabled) free(spdif.buf); - ended = true; + if (bytes != oframes * BYTES_PER_FRAME) { + LOG_WARN("I2S DMA Overflow! available bytes: %d, I2S wrote %d bytes", + oframes * BYTES_PER_FRAME, bytes); + } - vTaskDelete(NULL); + SET_MIN_MAX(TIME_MEASUREMENT_GET(timer_start), i2s_time); + } + + if (spdif.enabled) free(spdif.buf); + ended = true; + + vTaskDelete(NULL); } /**************************************************************************************** @@ -650,154 +635,142 @@ static void output_thread_i2s(void *arg) { */ static void i2s_stats(uint32_t now) { static uint32_t last; - + // first chain to next handler if (pseudo_idle_chain) pseudo_idle_chain(now); - + // then see if we need to act - if (output.state <= OUTPUT_STOPPED || now < last + STATS_PERIOD_MS) return; + if (output.state <= OUTPUT_STOPPED || now < last + STATS_PERIOD_MS) return; last = now; - LOG_INFO( "Output State: %d, current sample rate: %d, bytes per frame: %d", output.state, output.current_sample_rate, BYTES_PER_FRAME); - LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD1); - LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD2); - LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD3); - LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD4); - LOG_INFO(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream",s)); - LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output",o)); - LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER); - LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec)); - LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER); - LOG_INFO(""); - LOG_INFO(" ----------+----------+-----------+-----------+ "); - LOG_INFO(" max (us) | min (us) | avg(us) | count | "); - LOG_INFO(" ----------+----------+-----------+-----------+ "); - LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Buffering(us)",buffering)); - LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("i2s tfr(us)",i2s_time)); - LOG_INFO(" ----------+----------+-----------+-----------+"); - RESET_ALL_MIN_MAX; + LOG_INFO("Output State: %d, current sample rate: %d, bytes per frame: %d", output.state, + output.current_sample_rate, BYTES_PER_FRAME); + LOG_INFO(LINE_MIN_MAX_FORMAT_HEAD1); + LOG_INFO(LINE_MIN_MAX_FORMAT_HEAD2); + LOG_INFO(LINE_MIN_MAX_FORMAT_HEAD3); + LOG_INFO(LINE_MIN_MAX_FORMAT_HEAD4); + LOG_INFO(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream", s)); + LOG_INFO(LINE_MIN_MAX_FORMAT, LINE_MIN_MAX("output", o)); + LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER); + LOG_INFO(LINE_MIN_MAX_FORMAT, LINE_MIN_MAX("received", rec)); + LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER); + LOG_INFO(""); + LOG_INFO(" ----------+----------+-----------+-----------+ "); + LOG_INFO(" max (us) | min (us) | avg(us) | count | "); + LOG_INFO(" ----------+----------+-----------+-----------+ "); + LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT, LINE_MIN_MAX_DURATION("Buffering(us)", buffering)); + LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT, LINE_MIN_MAX_DURATION("i2s tfr(us)", i2s_time)); + LOG_INFO(" ----------+----------+-----------+-----------+"); + RESET_ALL_MIN_MAX; } /**************************************************************************************** * SPDIF support */ -#define PREAMBLE_B (0xE8) //11101000 -#define PREAMBLE_M (0xE2) //11100010 -#define PREAMBLE_W (0xE4) //11100100 +#define PREAMBLE_B (0xE8) // 11101000 +#define PREAMBLE_M (0xE2) // 11100010 +#define PREAMBLE_W (0xE4) // 11100100 -static const u8_t VUCP24[2] = { 0xCC, 0x32 }; +static const u8_t VUCP24[2] = {0xCC, 0x32}; -static const u16_t spdif_bmclookup[256] = { - 0xcccc, 0xb333, 0xd333, 0xaccc, 0xcb33, 0xb4cc, 0xd4cc, 0xab33, - 0xcd33, 0xb2cc, 0xd2cc, 0xad33, 0xcacc, 0xb533, 0xd533, 0xaacc, - 0xccb3, 0xb34c, 0xd34c, 0xacb3, 0xcb4c, 0xb4b3, 0xd4b3, 0xab4c, - 0xcd4c, 0xb2b3, 0xd2b3, 0xad4c, 0xcab3, 0xb54c, 0xd54c, 0xaab3, - 0xccd3, 0xb32c, 0xd32c, 0xacd3, 0xcb2c, 0xb4d3, 0xd4d3, 0xab2c, - 0xcd2c, 0xb2d3, 0xd2d3, 0xad2c, 0xcad3, 0xb52c, 0xd52c, 0xaad3, - 0xccac, 0xb353, 0xd353, 0xacac, 0xcb53, 0xb4ac, 0xd4ac, 0xab53, - 0xcd53, 0xb2ac, 0xd2ac, 0xad53, 0xcaac, 0xb553, 0xd553, 0xaaac, - 0xcccb, 0xb334, 0xd334, 0xaccb, 0xcb34, 0xb4cb, 0xd4cb, 0xab34, - 0xcd34, 0xb2cb, 0xd2cb, 0xad34, 0xcacb, 0xb534, 0xd534, 0xaacb, - 0xccb4, 0xb34b, 0xd34b, 0xacb4, 0xcb4b, 0xb4b4, 0xd4b4, 0xab4b, - 0xcd4b, 0xb2b4, 0xd2b4, 0xad4b, 0xcab4, 0xb54b, 0xd54b, 0xaab4, - 0xccd4, 0xb32b, 0xd32b, 0xacd4, 0xcb2b, 0xb4d4, 0xd4d4, 0xab2b, - 0xcd2b, 0xb2d4, 0xd2d4, 0xad2b, 0xcad4, 0xb52b, 0xd52b, 0xaad4, - 0xccab, 0xb354, 0xd354, 0xacab, 0xcb54, 0xb4ab, 0xd4ab, 0xab54, - 0xcd54, 0xb2ab, 0xd2ab, 0xad54, 0xcaab, 0xb554, 0xd554, 0xaaab, - 0xcccd, 0xb332, 0xd332, 0xaccd, 0xcb32, 0xb4cd, 0xd4cd, 0xab32, - 0xcd32, 0xb2cd, 0xd2cd, 0xad32, 0xcacd, 0xb532, 0xd532, 0xaacd, - 0xccb2, 0xb34d, 0xd34d, 0xacb2, 0xcb4d, 0xb4b2, 0xd4b2, 0xab4d, - 0xcd4d, 0xb2b2, 0xd2b2, 0xad4d, 0xcab2, 0xb54d, 0xd54d, 0xaab2, - 0xccd2, 0xb32d, 0xd32d, 0xacd2, 0xcb2d, 0xb4d2, 0xd4d2, 0xab2d, - 0xcd2d, 0xb2d2, 0xd2d2, 0xad2d, 0xcad2, 0xb52d, 0xd52d, 0xaad2, - 0xccad, 0xb352, 0xd352, 0xacad, 0xcb52, 0xb4ad, 0xd4ad, 0xab52, - 0xcd52, 0xb2ad, 0xd2ad, 0xad52, 0xcaad, 0xb552, 0xd552, 0xaaad, - 0xccca, 0xb335, 0xd335, 0xacca, 0xcb35, 0xb4ca, 0xd4ca, 0xab35, - 0xcd35, 0xb2ca, 0xd2ca, 0xad35, 0xcaca, 0xb535, 0xd535, 0xaaca, - 0xccb5, 0xb34a, 0xd34a, 0xacb5, 0xcb4a, 0xb4b5, 0xd4b5, 0xab4a, - 0xcd4a, 0xb2b5, 0xd2b5, 0xad4a, 0xcab5, 0xb54a, 0xd54a, 0xaab5, - 0xccd5, 0xb32a, 0xd32a, 0xacd5, 0xcb2a, 0xb4d5, 0xd4d5, 0xab2a, - 0xcd2a, 0xb2d5, 0xd2d5, 0xad2a, 0xcad5, 0xb52a, 0xd52a, 0xaad5, - 0xccaa, 0xb355, 0xd355, 0xacaa, 0xcb55, 0xb4aa, 0xd4aa, 0xab55, - 0xcd55, 0xb2aa, 0xd2aa, 0xad55, 0xcaaa, 0xb555, 0xd555, 0xaaaa -}; +static const u16_t spdif_bmclookup[256] = {0xcccc, 0xb333, 0xd333, 0xaccc, 0xcb33, 0xb4cc, 0xd4cc, + 0xab33, 0xcd33, 0xb2cc, 0xd2cc, 0xad33, 0xcacc, 0xb533, 0xd533, 0xaacc, 0xccb3, 0xb34c, 0xd34c, + 0xacb3, 0xcb4c, 0xb4b3, 0xd4b3, 0xab4c, 0xcd4c, 0xb2b3, 0xd2b3, 0xad4c, 0xcab3, 0xb54c, 0xd54c, + 0xaab3, 0xccd3, 0xb32c, 0xd32c, 0xacd3, 0xcb2c, 0xb4d3, 0xd4d3, 0xab2c, 0xcd2c, 0xb2d3, 0xd2d3, + 0xad2c, 0xcad3, 0xb52c, 0xd52c, 0xaad3, 0xccac, 0xb353, 0xd353, 0xacac, 0xcb53, 0xb4ac, 0xd4ac, + 0xab53, 0xcd53, 0xb2ac, 0xd2ac, 0xad53, 0xcaac, 0xb553, 0xd553, 0xaaac, 0xcccb, 0xb334, 0xd334, + 0xaccb, 0xcb34, 0xb4cb, 0xd4cb, 0xab34, 0xcd34, 0xb2cb, 0xd2cb, 0xad34, 0xcacb, 0xb534, 0xd534, + 0xaacb, 0xccb4, 0xb34b, 0xd34b, 0xacb4, 0xcb4b, 0xb4b4, 0xd4b4, 0xab4b, 0xcd4b, 0xb2b4, 0xd2b4, + 0xad4b, 0xcab4, 0xb54b, 0xd54b, 0xaab4, 0xccd4, 0xb32b, 0xd32b, 0xacd4, 0xcb2b, 0xb4d4, 0xd4d4, + 0xab2b, 0xcd2b, 0xb2d4, 0xd2d4, 0xad2b, 0xcad4, 0xb52b, 0xd52b, 0xaad4, 0xccab, 0xb354, 0xd354, + 0xacab, 0xcb54, 0xb4ab, 0xd4ab, 0xab54, 0xcd54, 0xb2ab, 0xd2ab, 0xad54, 0xcaab, 0xb554, 0xd554, + 0xaaab, 0xcccd, 0xb332, 0xd332, 0xaccd, 0xcb32, 0xb4cd, 0xd4cd, 0xab32, 0xcd32, 0xb2cd, 0xd2cd, + 0xad32, 0xcacd, 0xb532, 0xd532, 0xaacd, 0xccb2, 0xb34d, 0xd34d, 0xacb2, 0xcb4d, 0xb4b2, 0xd4b2, + 0xab4d, 0xcd4d, 0xb2b2, 0xd2b2, 0xad4d, 0xcab2, 0xb54d, 0xd54d, 0xaab2, 0xccd2, 0xb32d, 0xd32d, + 0xacd2, 0xcb2d, 0xb4d2, 0xd4d2, 0xab2d, 0xcd2d, 0xb2d2, 0xd2d2, 0xad2d, 0xcad2, 0xb52d, 0xd52d, + 0xaad2, 0xccad, 0xb352, 0xd352, 0xacad, 0xcb52, 0xb4ad, 0xd4ad, 0xab52, 0xcd52, 0xb2ad, 0xd2ad, + 0xad52, 0xcaad, 0xb552, 0xd552, 0xaaad, 0xccca, 0xb335, 0xd335, 0xacca, 0xcb35, 0xb4ca, 0xd4ca, + 0xab35, 0xcd35, 0xb2ca, 0xd2ca, 0xad35, 0xcaca, 0xb535, 0xd535, 0xaaca, 0xccb5, 0xb34a, 0xd34a, + 0xacb5, 0xcb4a, 0xb4b5, 0xd4b5, 0xab4a, 0xcd4a, 0xb2b5, 0xd2b5, 0xad4a, 0xcab5, 0xb54a, 0xd54a, + 0xaab5, 0xccd5, 0xb32a, 0xd32a, 0xacd5, 0xcb2a, 0xb4d5, 0xd4d5, 0xab2a, 0xcd2a, 0xb2d5, 0xd2d5, + 0xad2a, 0xcad5, 0xb52a, 0xd52a, 0xaad5, 0xccaa, 0xb355, 0xd355, 0xacaa, 0xcb55, 0xb4aa, 0xd4aa, + 0xab55, 0xcd55, 0xb2aa, 0xd2aa, 0xad55, 0xcaaa, 0xb555, 0xd555, 0xaaaa}; -/* - SPDIF is supposed to be (before BMC encoding, from LSB to MSB) +/* + SPDIF is supposed to be (before BMC encoding, from LSB to MSB) 0.... 1... 191.. 0 BLFMRF MLFWRF MLFWRF BLFMRF (B,M,W=preamble-4, L/R=left/Right-24, F=Flags-4) - each xLF pattern is 32 bits - PPPP AAAA SSSS SSSS SSSS SSSS SSSS VUCP (P=preamble, A=auxiliary, S=sample-20bits, V=valid, U=user data, C=channel status, P=parity) - After BMC encoding, each bit becomes 2 hence this becomes a 64 bits word. The parity - is fixed by changing AAAA bits so that VUPC does not change. Then then trick is to - start not with a PPPP sequence but with an VUCP sequence to that the 16 bits samples + each xLF pattern is 32 bits + PPPP AAAA SSSS SSSS SSSS SSSS SSSS VUCP (P=preamble, A=auxiliary, S=sample-20bits, V=valid, + U=user data, C=channel status, P=parity) After BMC encoding, each bit becomes 2 hence this becomes + a 64 bits word. The parity is fixed by changing AAAA bits so that VUPC does not change. Then then + trick is to start not with a PPPP sequence but with an VUCP sequence to that the 16 bits samples are aligned with a BMC word boundary. Input buffer is left first => LRLR... The I2S interface must output first the B/M/W preamble which means that second - 32 bits words must be first and so must be marked right channel. + 32 bits words must be first and so must be marked right channel. */ -static void IRAM_ATTR spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst) { - static u8_t vu, count; - register u16_t hi, lo; +static void IRAM_ATTR spdif_convert(ISAMPLE_T* src, size_t frames, u32_t* dst) { + static u8_t vu, count; + register u16_t hi, lo; #if BYTES_PER_FRAME == 8 - register u16_t aux; + register u16_t aux; #endif - + // we assume frame == 0 as well... if (!src) { - count = 192; + count = 192; vu = VUCP24[0]; } - - while (frames--) { - // start with left channel -#if BYTES_PER_FRAME == 4 - hi = spdif_bmclookup[(u8_t)(*src >> 8)]; - lo = spdif_bmclookup[(u8_t)*src++]; - if (lo & 1) hi = ~hi; - - if (!count--) { - *dst++ = (vu << 24) | (PREAMBLE_B << 16) | 0xCCCC; - count = 192; - } else { - *dst++ = (vu << 24) | (PREAMBLE_M << 16) | 0xCCCC; - } -#else - hi = spdif_bmclookup[(u8_t)(*src >> 24)]; - lo = spdif_bmclookup[(u8_t)(*src >> 16)]; - aux = spdif_bmclookup[(u8_t)(*src++ >> 8)]; - if (aux & 1) lo = ~lo; - if (lo & 1) hi = ~hi; + while (frames--) { + // start with left channel +#if BYTES_PER_FRAME == 4 + hi = spdif_bmclookup[(u8_t)(*src >> 8)]; + lo = spdif_bmclookup[(u8_t)*src++]; + if (lo & 1) hi = ~hi; if (!count--) { - *dst++ = (vu << 24) | (PREAMBLE_B << 16) | aux; - count = 192; - } else { - *dst++ = (vu << 24) | (PREAMBLE_M << 16) | aux; - } -#endif - - vu = VUCP24[hi & 1]; - *dst++ = ((u32_t)lo << 16) | hi; - - // then do right channel, no need to check PREAMBLE_B -#if BYTES_PER_FRAME == 4 - hi = spdif_bmclookup[(u8_t)(*src >> 8)]; - lo = spdif_bmclookup[(u8_t)*src++]; - if (lo & 1) hi = ~hi; - - *dst++ = (vu << 24) | (PREAMBLE_W << 16) | 0xCCCC; + *dst++ = (vu << 24) | (PREAMBLE_B << 16) | 0xCCCC; + count = 192; + } else { + *dst++ = (vu << 24) | (PREAMBLE_M << 16) | 0xCCCC; + } #else - hi = spdif_bmclookup[(u8_t)(*src >> 24)]; - lo = spdif_bmclookup[(u8_t)(*src >> 16)]; - aux = spdif_bmclookup[(u8_t)(*src++ >> 8)]; - if (aux & 1) lo = ~lo; - if (lo & 1) hi = ~hi; + hi = spdif_bmclookup[(u8_t)(*src >> 24)]; + lo = spdif_bmclookup[(u8_t)(*src >> 16)]; + aux = spdif_bmclookup[(u8_t)(*src++ >> 8)]; + if (aux & 1) lo = ~lo; + if (lo & 1) hi = ~hi; - *dst++ = (vu << 24) | (PREAMBLE_W << 16) | aux; + if (!count--) { + *dst++ = (vu << 24) | (PREAMBLE_B << 16) | aux; + count = 192; + } else { + *dst++ = (vu << 24) | (PREAMBLE_M << 16) | aux; + } #endif vu = VUCP24[hi & 1]; - *dst++ = ((u32_t)lo << 16) | hi; - } + *dst++ = ((u32_t)lo << 16) | hi; + + // then do right channel, no need to check PREAMBLE_B +#if BYTES_PER_FRAME == 4 + hi = spdif_bmclookup[(u8_t)(*src >> 8)]; + lo = spdif_bmclookup[(u8_t)*src++]; + if (lo & 1) hi = ~hi; + + *dst++ = (vu << 24) | (PREAMBLE_W << 16) | 0xCCCC; +#else + hi = spdif_bmclookup[(u8_t)(*src >> 24)]; + lo = spdif_bmclookup[(u8_t)(*src >> 16)]; + aux = spdif_bmclookup[(u8_t)(*src++ >> 8)]; + if (aux & 1) lo = ~lo; + if (lo & 1) hi = ~hi; + + *dst++ = (vu << 24) | (PREAMBLE_W << 16) | aux; +#endif + + vu = VUCP24[hi & 1]; + *dst++ = ((u32_t)lo << 16) | hi; + } } diff --git a/components/squeezelite/squeezelite.h b/components/squeezelite/squeezelite.h index 60ac4f64..4e9197be 100644 --- a/components/squeezelite/squeezelite.h +++ b/components/squeezelite/squeezelite.h @@ -755,7 +755,7 @@ void _pa_open(void); #if EMBEDDED void set_volume(unsigned left, unsigned right); bool test_open(const char *device, unsigned rates[], bool userdef_rates); -void output_init_embedded(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle); +void output_init_embedded(); void output_close_embedded(void); #else // output_stdout.c diff --git a/components/squeezelite/tas57xx/dac_5713.c b/components/squeezelite/tas57xx/dac_5713.c index 1a45efac..4be86f62 100644 --- a/components/squeezelite/tas57xx/dac_5713.c +++ b/components/squeezelite/tas57xx/dac_5713.c @@ -45,7 +45,7 @@ static void headset(bool active) { } ; static bool volume(unsigned left, unsigned right); static void power(adac_power_e mode) { }; -const struct adac_s dac_tas5713 = {"TAS5713", init, adac_deinit, power, speaker, headset, volume}; +const struct adac_s dac_tas5713 = {sys_DACModelEnum_TAS5713, init, adac_deinit, power, speaker, headset, volume}; struct tas5713_cmd_s { uint8_t reg; diff --git a/components/squeezelite/tas57xx/dac_57xx.c b/components/squeezelite/tas57xx/dac_57xx.c index 45b073c8..88aff0b2 100644 --- a/components/squeezelite/tas57xx/dac_57xx.c +++ b/components/squeezelite/tas57xx/dac_57xx.c @@ -29,7 +29,7 @@ static void headset(bool active); static bool volume(unsigned left, unsigned right); static void power(adac_power_e mode); -const struct adac_s dac_tas57xx = { "TAS57xx", init, adac_deinit, power, speaker, headset, volume }; +const struct adac_s dac_tas57xx = { sys_DACModelEnum_TAS57xx, init, adac_deinit, power, speaker, headset, volume }; struct tas57xx_cmd_s { uint8_t reg; diff --git a/components/squeezelite/wm8978/wm8978.c b/components/squeezelite/wm8978/wm8978.c index 09621964..98123c6f 100644 --- a/components/squeezelite/wm8978/wm8978.c +++ b/components/squeezelite/wm8978/wm8978.c @@ -30,7 +30,7 @@ static uint16_t i2c_read_shadow(uint8_t reg); static int WM8978; -const struct adac_s dac_wm8978 = { "WM8978", init, adac_deinit, power, speaker, headset, volume }; +const struct adac_s dac_wm8978 = { sys_DACModelEnum_WM8978, init, adac_deinit, power, speaker, headset, volume }; // initiation table for non-readbale 9-bit i2c registers static uint16_t WM8978_REGVAL_TBL[58] = { diff --git a/components/telnet/telnet.c b/components/telnet/telnet.c index 0a3efbf6..b126209e 100644 --- a/components/telnet/telnet.c +++ b/components/telnet/telnet.c @@ -36,11 +36,11 @@ #include "soc/uart_struct.h" #include "driver/uart.h" #include "config.h" -#include "nvs_utilities.h" #include "platform_esp32.h" #include "messaging.h" #include "tools.h" - +#include "Configurator.h" +#include "accessors.h" /************************************ * Globals */ @@ -77,35 +77,24 @@ static void handle_telnet_conn(); static size_t process_logs( UBaseType_t bytes, bool make_room); void init_telnet(){ - char *val= get_nvs_value_alloc(NVS_TYPE_STR, "telnet_enable"); - - if (!val || strlen(val) == 0 || !strcasestr("YXD",val) ) { + sys_Telnet * telnet_svc=NULL; + if(!SYS_SERVICES_TELNET(telnet_svc) || !telnet_svc->enable){ ESP_LOGI(TAG,"Telnet support disabled"); - if(val) free(val); return; } - // if wifi manager is bypassed, there will possibly be no wifi available - bMirrorToUART = (strcasestr("D",val)!=NULL); - if (!bMirrorToUART && bypass_network_manager){ - // This isn't supposed to happen, as telnet won't start if wifi manager isn't - // started. So this is a safeguard only. - ESP_LOGW(TAG,"Wifi manager is not active. Forcing console on Serial output."); - } + #pragma message("Do we still need this logic for telnet?") + // // if wifi manager is bypassed, there will possibly be no wifi available + // bMirrorToUART = (strcasestr("D",val)!=NULL); + // if (!bMirrorToUART && bypass_network_manager){ + // // This isn't supposed to happen, as telnet won't start if wifi manager isn't + // // started. So this is a safeguard only. + // ESP_LOGW(TAG,"Wifi manager is not active. Forcing console on Serial output."); + // } + + if (telnet_svc->block > 0) send_chunk = telnet_svc->block; + if (telnet_svc->block > 0) log_buf_size = telnet_svc->buffer; - FREE_AND_NULL(val); - val = get_nvs_value_alloc(NVS_TYPE_STR, "telnet_block"); - if (val){ - int size = atol(val); - if (size > 0) send_chunk = size; - free(val); - } - val = get_nvs_value_alloc(NVS_TYPE_STR, "telnet_buffer"); - if (val){ - int size = atol(val); - if (size > 0) log_buf_size = size; - free(val); - } // Redirect the output to our telnet handler as soon as possible StaticRingbuffer_t *buffer_struct = (StaticRingbuffer_t *) heap_caps_malloc(sizeof(StaticRingbuffer_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); // All non-split ring buffer must have their memory alignment set to 32 bits. @@ -132,6 +121,7 @@ void init_telnet(){ freopen("/dev/pkspstdout", "w", stderr); bIsEnabled=true; + } void start_telnet(void * pvParameter){ diff --git a/components/tools/CMakeLists.txt b/components/tools/CMakeLists.txt index fbfd3d56..20950a0f 100644 --- a/components/tools/CMakeLists.txt +++ b/components/tools/CMakeLists.txt @@ -1,6 +1,6 @@ idf_component_register( SRCS operator.cpp tools.c trace.c REQUIRES esp_common pthread - PRIV_REQUIRES esp_http_client esp-tls json + PRIV_REQUIRES esp_http_client esp_http_server esp-tls json spiffs INCLUDE_DIRS . ) diff --git a/components/tools/tools.c b/components/tools/tools.c index 4d7fa0e1..676ee236 100644 --- a/components/tools/tools.c +++ b/components/tools/tools.c @@ -6,23 +6,25 @@ * https://opensource.org/licenses/MIT * */ -#include -#include -#include -#include -#include +// #define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#include "tools.h" +#include "esp_heap_caps.h" +#include "esp_http_client.h" +#include "esp_log.h" #include "esp_task.h" #include "esp_tls.h" -#include "esp_http_client.h" -#include "esp_heap_caps.h" -#include "esp_log.h" -#include "tools.h" - +#include +#include +#include +#include +#include +#include "esp_http_server.h" #if CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS < 2 #error CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS must be at least 2 #endif - +static bool initialized = false; const static char TAG[] = "tools"; +static esp_vfs_spiffs_conf_t* spiffs_conf = NULL; /**************************************************************************************** * UTF-8 tools @@ -38,145 +40,206 @@ const static char TAG[] = "tools"; #define UTF8_REJECT 1 static const uint8_t utf8d[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df - 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef - 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff - 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 - 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 - 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 - 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // 00..1f + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // 20..3f + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // 40..5f + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // 60..7f + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, // 80..9f + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, // a0..bf + 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, // c0..df + 0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // e0..ef + 0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // f0..ff + 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, + 1, // s1..s2 + 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, // s3..s4 + 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, + 1, // s5..s6 + 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, // s7..s8 }; static uint32_t decode(uint32_t* state, uint32_t* codep, uint32_t byte) { - uint32_t type = utf8d[byte]; + uint32_t type = utf8d[byte]; - *codep = (*state != UTF8_ACCEPT) ? - (byte & 0x3fu) | (*codep << 6) : - (0xff >> type) & (byte); + *codep = (*state != UTF8_ACCEPT) ? (byte & 0x3fu) | (*codep << 6) : (0xff >> type) & (byte); - *state = utf8d[256 + *state*16 + type]; - return *state; + *state = utf8d[256 + *state * 16 + type]; + return *state; } static uint8_t UNICODEtoCP1252(uint16_t chr) { - if (chr <= 0xff) - return (chr&0xff); - else { - ESP_LOGI(TAG, "some multi-byte %hx", chr); - switch(chr) { - case 0x20ac: return 0x80; break; - case 0x201a: return 0x82; break; - case 0x0192: return 0x83; break; - case 0x201e: return 0x84; break; - case 0x2026: return 0x85; break; - case 0x2020: return 0x86; break; - case 0x2021: return 0x87; break; - case 0x02c6: return 0x88; break; - case 0x2030: return 0x89; break; - case 0x0160: return 0x8a; break; - case 0x2039: return 0x8b; break; - case 0x0152: return 0x8c; break; - case 0x017d: return 0x8e; break; - case 0x2018: return 0x91; break; - case 0x2019: return 0x92; break; - case 0x201c: return 0x93; break; - case 0x201d: return 0x94; break; - case 0x2022: return 0x95; break; - case 0x2013: return 0x96; break; - case 0x2014: return 0x97; break; - case 0x02dc: return 0x98; break; - case 0x2122: return 0x99; break; - case 0x0161: return 0x9a; break; - case 0x203a: return 0x9b; break; - case 0x0153: return 0x9c; break; - case 0x017e: return 0x9e; break; - case 0x0178: return 0x9f; break; - default: return 0x00; break; - } - } + if (chr <= 0xff) + return (chr & 0xff); + else { + ESP_LOGI(TAG, "some multi-byte %hx", chr); + switch (chr) { + case 0x20ac: + return 0x80; + break; + case 0x201a: + return 0x82; + break; + case 0x0192: + return 0x83; + break; + case 0x201e: + return 0x84; + break; + case 0x2026: + return 0x85; + break; + case 0x2020: + return 0x86; + break; + case 0x2021: + return 0x87; + break; + case 0x02c6: + return 0x88; + break; + case 0x2030: + return 0x89; + break; + case 0x0160: + return 0x8a; + break; + case 0x2039: + return 0x8b; + break; + case 0x0152: + return 0x8c; + break; + case 0x017d: + return 0x8e; + break; + case 0x2018: + return 0x91; + break; + case 0x2019: + return 0x92; + break; + case 0x201c: + return 0x93; + break; + case 0x201d: + return 0x94; + break; + case 0x2022: + return 0x95; + break; + case 0x2013: + return 0x96; + break; + case 0x2014: + return 0x97; + break; + case 0x02dc: + return 0x98; + break; + case 0x2122: + return 0x99; + break; + case 0x0161: + return 0x9a; + break; + case 0x203a: + return 0x9b; + break; + case 0x0153: + return 0x9c; + break; + case 0x017e: + return 0x9e; + break; + case 0x0178: + return 0x9f; + break; + default: + return 0x00; + break; + } + } } -void utf8_decode(char *src) { - uint32_t codep = 0, state = UTF8_ACCEPT; - char *dst = src; +void utf8_decode(char* src) { + uint32_t codep = 0, state = UTF8_ACCEPT; + char* dst = src; - while (src && *src) { - if (!decode(&state, &codep, *src++)) *dst++ = UNICODEtoCP1252(codep); - } + while (src && *src) { + if (!decode(&state, &codep, *src++)) *dst++ = UNICODEtoCP1252(codep); + } - *dst = '\0'; + *dst = '\0'; } /**************************************************************************************** * URL tools */ -static inline char from_hex(char ch) { - return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; -} +static inline char from_hex(char ch) { return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; } -void url_decode(char *url) { - char *p, *src = strdup(url); - for (p = src; *src; url++) { - *url = *src++; - if (*url == '%') { - *url = from_hex(*src++) << 4; - *url |= from_hex(*src++); - } else if (*url == '+') { - *url = ' '; - } - } - *url = '\0'; - free(p); +void url_decode(char* url) { + char *p, *src = strdup(url); + for (p = src; *src; url++) { + *url = *src++; + if (*url == '%') { + *url = from_hex(*src++) << 4; + *url |= from_hex(*src++); + } else if (*url == '+') { + *url = ' '; + } + } + *url = '\0'; + free(p); } /**************************************************************************************** * Memory tools */ -void * malloc_init_external(size_t sz){ - void * ptr=NULL; - ptr = heap_caps_malloc(sz, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); - if(ptr==NULL){ - ESP_LOGE(TAG,"malloc_init_external: unable to allocate %d bytes of PSRAM!",sz); - } - else { - memset(ptr,0x00,sz); - } - return ptr; +void* malloc_init_external(size_t sz) { + void* ptr = NULL; + ptr = heap_caps_malloc(sz, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (ptr == NULL) { + ESP_LOGE(TAG, "malloc_init_external: unable to allocate %d bytes of PSRAM!", sz); + } else { + memset(ptr, 0x00, sz); + } + return ptr; } -void * clone_obj_psram(void * source, size_t source_sz){ - void * ptr=NULL; - ptr = heap_caps_malloc(source_sz, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); - if(ptr==NULL){ - ESP_LOGE(TAG,"clone_obj_psram: unable to allocate %d bytes of PSRAM!",source_sz); - } - else { - memcpy(ptr,source,source_sz); - } - return ptr; +void* clone_obj_psram(void* source, size_t source_sz) { + void* ptr = NULL; + ptr = heap_caps_malloc(source_sz, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (ptr == NULL) { + ESP_LOGE(TAG, "clone_obj_psram: unable to allocate %d bytes of PSRAM!", source_sz); + } else { + memcpy(ptr, source, source_sz); + } + return ptr; } -char * strdup_psram(const char * source){ - void * ptr=NULL; - size_t source_sz = strlen(source)+1; - ptr = heap_caps_malloc(source_sz, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); - if(ptr==NULL){ - ESP_LOGE(TAG,"strdup_psram: unable to allocate %d bytes of PSRAM! Cannot clone string %s",source_sz,source); - } - else { - memset(ptr,0x00,source_sz); - strcpy(ptr,source); - } - return ptr; +char* strdup_psram(const char* source) { + void* ptr = NULL; + size_t source_sz = strlen(source) + 1; + ptr = heap_caps_malloc(source_sz, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (ptr == NULL) { + ESP_LOGE(TAG, "strdup_psram: unable to allocate %d bytes of PSRAM! Cannot clone string %s", + source_sz, source); + } else { + memset(ptr, 0x00, source_sz); + strcpy(ptr, source); + } + return ptr; } /**************************************************************************************** @@ -185,43 +248,43 @@ char * strdup_psram(const char * source){ #define TASK_TLS_INDEX 1 typedef struct { - StaticTask_t *xTaskBuffer; - StackType_t *xStack; + StaticTask_t* xTaskBuffer; + StackType_t* xStack; } task_context_t; -static void task_cleanup(int index, task_context_t *context) { +static void task_cleanup(int index, task_context_t* context) { free(context->xTaskBuffer); free(context->xStack); - free(context); + free(context); } -BaseType_t xTaskCreateEXTRAM( TaskFunction_t pvTaskCode, - const char * const pcName, - configSTACK_DEPTH_TYPE usStackDepth, - void *pvParameters, - UBaseType_t uxPriority, - TaskHandle_t *pxCreatedTask) { +BaseType_t xTaskCreateEXTRAM(TaskFunction_t pvTaskCode, const char* const pcName, + configSTACK_DEPTH_TYPE usStackDepth, void* pvParameters, UBaseType_t uxPriority, + TaskHandle_t* pxCreatedTask) { // create the worker task as a static - task_context_t *context = calloc(1, sizeof(task_context_t)); - context->xTaskBuffer = (StaticTask_t*) heap_caps_malloc(sizeof(StaticTask_t), (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)); - context->xStack = heap_caps_malloc(usStackDepth,(MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT)); - TaskHandle_t handle = xTaskCreateStatic(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, context->xStack, context->xTaskBuffer); + task_context_t* context = calloc(1, sizeof(task_context_t)); + context->xTaskBuffer = (StaticTask_t*)heap_caps_malloc( + sizeof(StaticTask_t), (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)); + context->xStack = heap_caps_malloc(usStackDepth, (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT)); + TaskHandle_t handle = xTaskCreateStatic(pvTaskCode, pcName, usStackDepth, pvParameters, + uxPriority, context->xStack, context->xTaskBuffer); // store context in TCB or free everything in case of failure if (!handle) { free(context->xTaskBuffer); free(context->xStack); - free(context); + free(context); } else { - vTaskSetThreadLocalStoragePointerAndDelCallback( handle, TASK_TLS_INDEX, context, (TlsDeleteCallbackFunction_t) task_cleanup); + vTaskSetThreadLocalStoragePointerAndDelCallback( + handle, TASK_TLS_INDEX, context, (TlsDeleteCallbackFunction_t)task_cleanup); } - + if (pxCreatedTask) *pxCreatedTask = handle; return handle != NULL ? pdPASS : pdFAIL; } void vTaskDeleteEXTRAM(TaskHandle_t xTask) { - /* At this point we leverage FreeRTOS extension to have callbacks on task deletion. + /* At this point we leverage FreeRTOS extension to have callbacks on task deletion. * If not, we need to have here our own deletion implementation that include delayed * free for when this is called with NULL (self-deletion) */ @@ -233,106 +296,459 @@ void vTaskDeleteEXTRAM(TaskHandle_t xTask) { */ typedef struct { - void *user_context; - http_download_cb_t callback; - size_t max, bytes; - bool abort; - uint8_t *data; - esp_http_client_handle_t client; + void* user_context; + http_download_cb_t callback; + size_t max, bytes; + bool abort; + uint8_t* data; + esp_http_client_handle_t client; } http_context_t; -static void http_downloader(void *arg); -static esp_err_t http_event_handler(esp_http_client_event_t *evt); +static void http_downloader(void* arg); +static esp_err_t http_event_handler(esp_http_client_event_t* evt); -void http_download(char *url, size_t max, http_download_cb_t callback, void *context) { - http_context_t *http_context = (http_context_t*) heap_caps_calloc(sizeof(http_context_t), 1, MALLOC_CAP_SPIRAM); +void http_download(char* url, size_t max, http_download_cb_t callback, void* context) { + http_context_t* http_context = + (http_context_t*)heap_caps_calloc(sizeof(http_context_t), 1, MALLOC_CAP_SPIRAM); - esp_http_client_config_t config = { - .url = url, - .event_handler = http_event_handler, - .user_data = http_context, - }; + esp_http_client_config_t config = { + .url = url, + .event_handler = http_event_handler, + .user_data = http_context, + }; - http_context->callback = callback; - http_context->user_context = context; - http_context->max = max; - http_context->client = esp_http_client_init(&config); + http_context->callback = callback; + http_context->user_context = context; + http_context->max = max; + http_context->client = esp_http_client_init(&config); - xTaskCreateEXTRAM(http_downloader, "downloader", 8*1024, http_context, ESP_TASK_PRIO_MIN + 1, NULL); + xTaskCreateEXTRAM( + http_downloader, "downloader", 8 * 1024, http_context, ESP_TASK_PRIO_MIN + 1, NULL); } -static void http_downloader(void *arg) { - http_context_t *http_context = (http_context_t*) arg; +static void http_downloader(void* arg) { + http_context_t* http_context = (http_context_t*)arg; - esp_http_client_perform(http_context->client); - esp_http_client_cleanup(http_context->client); + esp_http_client_perform(http_context->client); + esp_http_client_cleanup(http_context->client); - free(http_context); - vTaskDeleteEXTRAM(NULL); + free(http_context); + vTaskDeleteEXTRAM(NULL); } -static esp_err_t http_event_handler(esp_http_client_event_t *evt) { - http_context_t *http_context = (http_context_t*) evt->user_data; +static esp_err_t http_event_handler(esp_http_client_event_t* evt) { + http_context_t* http_context = (http_context_t*)evt->user_data; - if (http_context->abort) return ESP_FAIL; + if (http_context->abort) return ESP_FAIL; - switch(evt->event_id) { - case HTTP_EVENT_ERROR: - http_context->callback(NULL, 0, http_context->user_context); - http_context->abort = true; - break; - case HTTP_EVENT_ON_HEADER: - if (!strcasecmp(evt->header_key, "Content-Length")) { - size_t len = atoi(evt->header_value); - if (!len || len > http_context->max) { - ESP_LOGI(TAG, "content-length null or too large %zu / %zu", len, http_context->max); - http_context->abort = true; - } - } - break; - case HTTP_EVENT_ON_DATA: { - size_t len = esp_http_client_get_content_length(evt->client); - if (!http_context->data) { - if ((http_context->data = (uint8_t*) malloc(len)) == NULL) { - http_context->abort = true; - ESP_LOGE(TAG, "failed to allocate memory for output buffer %zu", len); - return ESP_FAIL; - } - } - memcpy(http_context->data + http_context->bytes, evt->data, evt->data_len); - http_context->bytes += evt->data_len; - break; - } - case HTTP_EVENT_ON_FINISH: - http_context->callback(http_context->data, http_context->bytes, http_context->user_context); - break; - case HTTP_EVENT_DISCONNECTED: { - int mbedtls_err = 0; - esp_err_t err = esp_tls_get_and_clear_last_error(evt->data, &mbedtls_err, NULL); - if (err != ESP_OK) { - ESP_LOGE(TAG, "HTTP download disconnect %d", err); - if (http_context->data) free(http_context->data); - http_context->callback(NULL, 0, http_context->user_context); - return ESP_FAIL; - } - break; - } - default: - break; - - } + switch (evt->event_id) { + case HTTP_EVENT_ERROR: + http_context->callback(NULL, 0, http_context->user_context); + http_context->abort = true; + break; + case HTTP_EVENT_ON_HEADER: + if (!strcasecmp(evt->header_key, "Content-Length")) { + size_t len = atoi(evt->header_value); + if (!len || len > http_context->max) { + ESP_LOGI(TAG, "content-length null or too large %zu / %zu", len, http_context->max); + http_context->abort = true; + } + } + break; + case HTTP_EVENT_ON_DATA: { + size_t len = esp_http_client_get_content_length(evt->client); + if (!http_context->data) { + if ((http_context->data = (uint8_t*)malloc(len)) == NULL) { + http_context->abort = true; + ESP_LOGE(TAG, "failed to allocate memory for output buffer %zu", len); + return ESP_FAIL; + } + } + memcpy(http_context->data + http_context->bytes, evt->data, evt->data_len); + http_context->bytes += evt->data_len; + break; + } + case HTTP_EVENT_ON_FINISH: + http_context->callback(http_context->data, http_context->bytes, http_context->user_context); + break; + case HTTP_EVENT_DISCONNECTED: { + int mbedtls_err = 0; + esp_err_t err = esp_tls_get_and_clear_last_error(evt->data, &mbedtls_err, NULL); + if (err != ESP_OK) { + ESP_LOGE(TAG, "HTTP download disconnect %d", err); + if (http_context->data) free(http_context->data); + http_context->callback(NULL, 0, http_context->user_context); + return ESP_FAIL; + } + break; + } + default: + break; + } - return ESP_OK; + return ESP_OK; } void dump_json_content(const char* prefix, cJSON* json, int level) { - if (!json) { - ESP_LOG_LEVEL(level,TAG, "%s: empty!", prefix); - return; - } - char* output = cJSON_Print(json); - if (output) { - ESP_LOG_LEVEL(level,TAG, "%s: \n%s", prefix, output); - } - FREE_AND_NULL(output); + if (!json) { + ESP_LOG_LEVEL(level, TAG, "%s: empty!", prefix); + return; + } + char* output = cJSON_Print(json); + if (output) { + ESP_LOG_LEVEL(level, TAG, "%s: \n%s", prefix, output); + } + FREE_AND_NULL(output); +} +void init_spiffs() { + if (initialized) { + ESP_LOGD(TAG, "SPIFFS already initialized. returning"); + return; + } + ESP_LOGI(TAG, "Initializing the SPI File system"); + spiffs_conf = (esp_vfs_spiffs_conf_t*)malloc(sizeof(esp_vfs_spiffs_conf_t)); + spiffs_conf->base_path = "/spiffs"; + spiffs_conf->partition_label = NULL; + spiffs_conf->max_files = 5; + spiffs_conf->format_if_mount_failed = true; + + // Use settings defined above to initialize and mount SPIFFS filesystem. + // Note: esp_vfs_spiffs_register is an all-in-one convenience function. + esp_err_t ret = esp_vfs_spiffs_register(spiffs_conf); + + if (ret != ESP_OK) { + if (ret == ESP_FAIL) { + ESP_LOGE(TAG, "Failed to mount or format filesystem"); + } else if (ret == ESP_ERR_NOT_FOUND) { + ESP_LOGE(TAG, "Failed to find SPIFFS partition"); + } else { + ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret)); + } + return; + } + + size_t total = 0, used = 0; + ret = esp_spiffs_info(spiffs_conf->partition_label, &total, &used); + if (ret != ESP_OK) { + ESP_LOGW(TAG, "Failed to get SPIFFS partition information (%s). Formatting...", + esp_err_to_name(ret)); + esp_spiffs_format(spiffs_conf->partition_label); + } else { + ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used); + } + + + initialized = true; +} + +// Function to safely append a path part with '/' if needed +void append_path_part(char** dest, const char* part) { + if ((*dest)[-1] != '/' && part[0] != '/') { + strcat(*dest, "/"); + *dest += 1; // Move the pointer past the '/' + } + strcat(*dest, part); + *dest += strlen(part); +} + +// Function to calculate the total length needed for the new path +size_t calculate_total_length(const char* base_path, va_list args) { + ESP_LOGV(TAG, "%s, Starting with base path: %s", "calculate_total_length", base_path); + size_t length = strlen(base_path) + 1; // +1 for null terminator + const char* part; + va_list args_copy; + va_copy(args_copy, args); + while ((part = va_arg(args_copy, const char*)) != NULL) { + ESP_LOGV(TAG, "Adding length of %s", part); + length += strlen(part) + 1; // +1 for potential '/' + } + ESP_LOGV(TAG, "Done looping. calculated length: %d", length); + va_end(args_copy); + return length; +} + +// Main function to join paths +char* __alloc_join_path(const char* base_path, va_list args) { + size_t count = 0; + ESP_LOGD(TAG, "Getting path length starting with %s", base_path); + size_t total_length = calculate_total_length(base_path, args); + + // Allocate memory + char* full_path = malloc_init_external(total_length); + if (!full_path) { + ESP_LOGE(TAG, "Unable to allocate memory for path"); + return NULL; + } + + // Start constructing the path + strcpy(full_path, base_path); + char* current_position = full_path + strlen(full_path); + + // Append each path part + const char* part; + while ((part = va_arg(args, const char*)) != NULL) { + append_path_part(¤t_position, part); + } + *current_position = '\0'; // Null-terminate the string + return full_path; +} +char* _alloc_join_path(const char* base_path, ...) { + va_list args; + ESP_LOGD(TAG, "%s", "join_path_var_parms"); + va_start(args, base_path); + char* result = __alloc_join_path(base_path, args); + va_end(args); + return result; +} + +FILE* __open_file(const char* mode, va_list args) { + FILE* file = NULL; + char* fullfilename = __alloc_join_path(spiffs_conf->base_path, args); + if (!fullfilename) { + ESP_LOGE(TAG, "Open file failed: unable to determine name"); + } else { + ESP_LOGI(TAG, "Opening file %s in mode %s ", fullfilename, mode); + file = fopen(fullfilename, mode); + } + if (file == NULL) { + ESP_LOGE(TAG, "Open file failed"); + } + if (fullfilename) free(fullfilename); + return file; +} +FILE* _open_file(const char* mode, ...) { + va_list args; + FILE* file = NULL; + va_start(args, mode); + file = __open_file(mode, args); + va_end(args); + return file; +} +bool _write_file(uint8_t* data, size_t sz, ...) { + bool result = true; + FILE* file = NULL; + va_list args; + if (data == NULL) { + ESP_LOGE(TAG, "Cannot write file. Data not received"); + return false; + } + if (sz == 0) { + ESP_LOGE(TAG, "Cannot write file. Data length 0"); + return false; + } + va_start(args, sz); + file = __open_file("w+", args); + va_end(args); + if (file == NULL) { + return false; + } + size_t written = fwrite(data, 1, sz, file); + if (written != sz) { + ESP_LOGE(TAG, "Write error. Wrote %d bytes of %d.", written, sz); + result = false; + } + fclose(file); + return result; +} +const char* get_mem_flag_desc(int flags) { + static char flagString[101]; + memset(flagString,0x00,sizeof(flagString)); + if (flags & MALLOC_CAP_EXEC) strcat(flagString, "EXEC "); + if (flags & MALLOC_CAP_32BIT) strcat(flagString, "32BIT "); + if (flags & MALLOC_CAP_8BIT) strcat(flagString, "8BIT "); + if (flags & MALLOC_CAP_DMA) strcat(flagString, "DMA "); + if (flags & MALLOC_CAP_PID2) strcat(flagString, "PID2 "); + if (flags & MALLOC_CAP_PID3) strcat(flagString, "PID3 "); + if (flags & MALLOC_CAP_PID4) strcat(flagString, "PID4 "); + if (flags & MALLOC_CAP_PID5) strcat(flagString, "PID5 "); + if (flags & MALLOC_CAP_PID6) strcat(flagString, "PID6 "); + if (flags & MALLOC_CAP_PID7) strcat(flagString, "PID7 "); + if (flags & MALLOC_CAP_SPIRAM) strcat(flagString, "SPIRAM "); + if (flags & MALLOC_CAP_INTERNAL) strcat(flagString, "INTERNAL "); + if (flags & MALLOC_CAP_DEFAULT) strcat(flagString, "DEFAULT "); + if (flags & MALLOC_CAP_IRAM_8BIT) strcat(flagString, "IRAM_8BIT "); + if (flags & MALLOC_CAP_RETENTION) strcat(flagString, "RETENTION "); + + return flagString; +} +void* _load_file(uint32_t memflags,size_t* sz, ...) { + void* data = NULL; + FILE* file = NULL; + size_t fsz = 0; + va_list args; + va_start(args, sz); + file = __open_file("rb", args); + va_end(args); + + if (file == NULL) { + return data; + } + fseek(file, 0, SEEK_END); + fsz = ftell(file); + fseek(file, 0, SEEK_SET); + if (fsz > 0) { + ESP_LOGD(TAG, "Allocating %d bytes to load file content with flags: %s ", fsz,get_mem_flag_desc(memflags)); + data = (void*)heap_caps_calloc(1, fsz, memflags); + if (data == NULL) { + ESP_LOGE(TAG, "Failed to allocate %d bytes to load file", fsz); + } else { + fread(data, 1, fsz, file); + if (sz) { + *sz = fsz; + } + } + } else { + ESP_LOGW(TAG, "File is empty. Nothing to read"); + } + fclose(file); + return data; +} +bool _get_file_info(struct stat* pfileInfo, ...) { + va_list args; + struct stat fileInfo; + va_start(args, pfileInfo); + char* fullfilename = __alloc_join_path(spiffs_conf->base_path, args); + va_end(args); + ESP_LOGD(TAG, "Getting file info for %s", fullfilename); + + if (!fullfilename) { + ESP_LOGE(TAG, "Failed to construct full file path"); + return false; + } + bool result = false; + // Use stat to fill the fileInfo structure + if (stat(fullfilename, &fileInfo) != 0) { + ESP_LOGD(TAG, "File %s not found", fullfilename); + } else { + result = true; + if (pfileInfo) { + memcpy(pfileInfo, &fileInfo, sizeof(fileInfo)); + } + ESP_LOGD(TAG, "File %s has %lu bytes", fullfilename, fileInfo.st_size); + } + + free(fullfilename); + return result; +} +#define LOCAL_MAC_SIZE 10 +const char* get_mac_str() { + uint8_t mac[6]; + static char macStr[LOCAL_MAC_SIZE + 1] = {0}; + if (macStr[0] == 0) { + ESP_LOGD(TAG, "calling esp_read_mac"); + esp_read_mac((uint8_t*)&mac, ESP_MAC_WIFI_STA); + ESP_LOGD(TAG, "Writing mac to string"); + snprintf(macStr, sizeof(macStr), "%x%x%x", mac[3], mac[4], mac[5]); + ESP_LOGD(TAG, "Determined mac string: %s", macStr); + } + return macStr; +} +char* alloc_get_string_with_mac(const char* val) { + uint8_t mac[6]; + char macStr[LOCAL_MAC_SIZE + 1]; + char* fullvalue = NULL; + esp_read_mac((uint8_t*)&mac, ESP_MAC_WIFI_STA); + snprintf(macStr, LOCAL_MAC_SIZE - 1, "-%x%x%x", mac[3], mac[4], mac[5]); + fullvalue = (char*)malloc_init_external(strlen(val) + sizeof(macStr) + 1); + if (fullvalue) { + strcpy(fullvalue, val); + strcat(fullvalue, macStr); + } else { + ESP_LOGE(TAG, "malloc failed for value %s", val); + } + return fullvalue; +} +void listFiles(const char *path_requested) { + DIR *dir = NULL; + char * sep="---------------------------------------------------------\n"; + struct dirent *ent; + char type; + char size[21]; + char tpath[255]; + struct stat sb; + struct tm *tm_info; + char *lpath = NULL; + int statok; + char * path= alloc_join_path(spiffs_conf->base_path,path_requested); + + printf("\nList of Directory [%s]\n", path); + printf(sep); + // Open directory + dir = opendir(path); + if (!dir) { + printf("Error opening directory\n"); + free(path); + return; + } + + // Read directory entries + uint64_t total = 0; + int nfiles = 0; + printf("T Size Name\n"); + printf(sep); + while ((ent = readdir(dir)) != NULL) { + sprintf(tpath, path); + if (path[strlen(path)-1] != '/') strcat(tpath,"/"); + strcat(tpath,ent->d_name); + + // Get file stat + statok = stat(tpath, &sb); + + if (ent->d_type == DT_REG) { + type = 'f'; + nfiles++; + if (statok) strcpy(size, " ?"); + else { + total += sb.st_size; + if (sb.st_size < (1024*1024)) sprintf(size,"%8d", (int)sb.st_size); + else if ((sb.st_size/1024) < (1024*1024)) sprintf(size,"%6dKB", (int)(sb.st_size / 1024)); + else sprintf(size,"%6dMB", (int)(sb.st_size / (1024 * 1024))); + } + } + else { + type = 'd'; + strcpy(size, " -"); + } + + printf("%c %s %s\r\n", + type, + size, + ent->d_name + ); + + } + if (total) { + printf(sep); + if (total < (1024*1024)) printf(" %8d", (int)total); + else if ((total/1024) < (1024*1024)) printf(" %6dKB", (int)(total / 1024)); + else printf(" %6dMB", (int)(total / (1024 * 1024))); + printf(" in %d file(s)\n", nfiles); + } + printf(sep); + + closedir(dir); + + free(lpath); + free(path); + uint32_t tot=0, used=0; + esp_spiffs_info(NULL, &tot, &used); + printf("SPIFFS: free %d KB of %d KB\n", (tot-used) / 1024, tot / 1024); + printf(sep); +} + +bool out_file_binding(pb_ostream_t* stream, const uint8_t* buf, size_t count) { + FILE* file = (FILE*)stream->state; + ESP_LOGD(TAG, "Writing %d bytes to file", count); + return fwrite(buf, 1, count, file) == count; +} +bool in_file_binding(pb_istream_t* stream, pb_byte_t *buf, size_t count) { + FILE* file = (FILE*)stream->state; + ESP_LOGD(TAG, "Reading %d bytes from file", count); + return fread(buf, 1, count, file) == count; +} + +bool out_http_binding(pb_ostream_t* stream, const uint8_t* buf, size_t count) { + httpd_req_t* req = (httpd_req_t*)stream->state; + ESP_LOGD(TAG, "Writing %d bytes to file", count); + return httpd_resp_send_chunk(req, (const char*)buf, count) == ESP_OK; } diff --git a/components/tools/tools.h b/components/tools/tools.h index debae093..50fd588e 100644 --- a/components/tools/tools.h +++ b/components/tools/tools.h @@ -1,5 +1,5 @@ -/* - * Tools +/* + * Tools * * Philippe G. 2019, philippe_44@outlook.com * @@ -7,12 +7,17 @@ * https://opensource.org/licenses/MIT * */ - + #pragma once +#include "cJSON.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "cJSON.h" - +#include "esp_spiffs.h" +#include "stdio.h" +#include "sys/stat.h" +#include "pb_common.h" // Nanopb header for encoding (serialization) +#include "pb_decode.h" // Nanopb header for decoding (deserialization) +#include "pb_encode.h" // Nanopb header for encoding (serialization) #ifdef __cplusplus extern "C" { #endif @@ -22,64 +27,101 @@ extern "C" { #endif #ifndef STR -#define STR(macro) QUOTE(macro) +#define STR(macro) QUOTE(macro) #endif #ifndef STR_OR_ALT -#define STR_OR_ALT(str,alt) (str?str:alt) +#define STR_OR_ALT(str, alt) (str ? str : alt) #endif #ifndef STR_OR_BLANK #define STR_OR_BLANK(p) p == NULL ? "" : p #endif -#define ESP_LOG_DEBUG_EVENT(tag,e) ESP_LOGD(tag,"evt: " e) +#define ESP_LOG_DEBUG_EVENT(tag, e) ESP_LOGD(tag, "evt: " e) #ifndef FREE_AND_NULL -#define FREE_AND_NULL(x) if(x) { free(x); x=NULL; } +#define FREE_AND_NULL(x) \ + if (x) { \ + free(x); \ + x = NULL; \ + } #endif #ifndef CASE_TO_STR -#define CASE_TO_STR(x) case x: return STR(x); break; +#define CASE_TO_STR(x) \ + case x: \ + return STR(x); \ + break; #endif -#define ENUM_TO_STRING(g) \ - case g: \ - return STR(g); \ +#define ENUM_TO_STRING(g) \ + case g: \ + return STR(g); \ break; -void utf8_decode(char *src); -void url_decode(char *url); -void* malloc_init_external(size_t sz); -void* clone_obj_psram(void * source, size_t source_sz); -char* strdup_psram(const char * source); -const char* str_or_unknown(const char * str); -const char* str_or_null(const char * str); -void dump_json_content(const char* prefix, cJSON* json, int level); +void utf8_decode(char* src); +void url_decode(char* url); +void* malloc_init_external(size_t sz); +void* clone_obj_psram(void* source, size_t source_sz); +char* strdup_psram(const char* source); +const char* str_or_unknown(const char* str); +const char* str_or_null(const char* str); +void dump_json_content(const char* prefix, cJSON* json, int level); +void init_spiffs(); +char * alloc_get_string_with_mac(const char * val); +const char * get_mac_str(); +#define alloc_join_path(base_path, ...) _alloc_join_path(base_path,__VA_ARGS__, NULL) +char* _alloc_join_path(const char* base_path, ...); + +#define get_file_info(pfileInfo, ...) _get_file_info(pfileInfo,__VA_ARGS__, NULL) + +bool _get_file_info(struct stat* pfileInfo, ...); + +#define load_file(sz, ...) _load_file(MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT, sz, __VA_ARGS__, NULL) +#define load_file_dma(sz, ...) _load_file(MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA, sz, __VA_ARGS__, NULL) + +void* _load_file(uint32_t memflags, size_t* sz, ...); + +#define file_exists(pfileinfo,...) _file_exists(pfileInfo,__VA_ARGS__, NULL) +bool _file_exists(struct stat *fileInfo, ...); + +#define open_file(mode,...) _open_file(mode,__VA_ARGS__, NULL) +FILE* _open_file( const char* mode,...); + +bool in_file_binding(pb_istream_t* stream, pb_byte_t *buf, size_t count); +bool out_file_binding(pb_ostream_t* stream, const uint8_t* buf, size_t count); +bool out_http_binding(pb_ostream_t* stream, const uint8_t* buf, size_t count); + +#define write_file(data,sz,...) _write_file(data,sz,__VA_ARGS__, NULL) +bool _write_file(uint8_t* data, size_t sz, ...); + +void listFiles(const char *path_requested); #ifndef gettime_ms // body is provided somewhere else... uint32_t _gettime_ms_(void); #define gettime_ms _gettime_ms_ #endif -typedef void (*http_download_cb_t)(uint8_t* data, size_t len, void *context); -void http_download(char *url, size_t max, http_download_cb_t callback, void *context); +typedef void (*http_download_cb_t)(uint8_t* data, size_t len, void* context); +void http_download(char* url, size_t max, http_download_cb_t callback, void* context); -/* Use these to dynamically create tasks whose stack is on EXTRAM. Be aware that it +/* Use these to dynamically create tasks whose stack is on EXTRAM. Be aware that it * requires configNUM_THREAD_LOCAL_STORAGE_POINTERS to bet set to 2 at least (index 0 * is used by pthread and this uses index 1, obviously */ -BaseType_t xTaskCreateEXTRAM( TaskFunction_t pvTaskCode, - const char * const pcName, - configSTACK_DEPTH_TYPE usStackDepth, - void *pvParameters, - UBaseType_t uxPriority, - TaskHandle_t *pxCreatedTask); -void vTaskDeleteEXTRAM(TaskHandle_t xTask); +BaseType_t xTaskCreateEXTRAM(TaskFunction_t pvTaskCode, const char* const pcName, + configSTACK_DEPTH_TYPE usStackDepth, void* pvParameters, UBaseType_t uxPriority, + TaskHandle_t* pxCreatedTask); +void vTaskDeleteEXTRAM(TaskHandle_t xTask); extern const char unknown_string_placeholder[]; +#ifndef TRACE_DEBUG +#define TRACE_DEBUG(msgformat, ... ) printf("%-30s%-5d" msgformat "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) +#endif + #ifdef __cplusplus } #endif diff --git a/components/tools/trace.c b/components/tools/trace.c index cbfe1da6..44643f46 100644 --- a/components/tools/trace.c +++ b/components/tools/trace.c @@ -14,55 +14,55 @@ static const char TAG[] = "TRACE"; -// typedef struct mem_usage_trace_for_thread { -// TaskHandle_t task; -// size_t malloc_int_last; -// size_t malloc_spiram_last; -// size_t malloc_dma_last; -// const char *name; -// SLIST_ENTRY(mem_usage_trace_for_thread) next; -// } mem_usage_trace_for_thread_t; +typedef struct mem_usage_trace_for_thread { + TaskHandle_t task; + size_t malloc_int_last; + size_t malloc_spiram_last; + size_t malloc_dma_last; + const char *name; + SLIST_ENTRY(mem_usage_trace_for_thread) next; +} mem_usage_trace_for_thread_t; -// static EXT_RAM_ATTR SLIST_HEAD(memtrace, mem_usage_trace_for_thread) s_memtrace; +static EXT_RAM_ATTR SLIST_HEAD(memtrace, mem_usage_trace_for_thread) s_memtrace; -// mem_usage_trace_for_thread_t* memtrace_get_thread_entry(TaskHandle_t task) { -// if(!task) { -// ESP_LOGE(TAG, "memtrace_get_thread_entry: task is NULL"); -// return NULL; -// } -// ESP_LOGD(TAG,"Looking for task %s",STR_OR_ALT(pcTaskGetName(task ), "unknown")); -// mem_usage_trace_for_thread_t* it; -// SLIST_FOREACH(it, &s_memtrace, next) { -// if ( it->task == task ) { -// ESP_LOGD(TAG,"Found task %s",STR_OR_ALT(pcTaskGetName(task ), "unknown")); -// return it; -// } -// } -// return NULL; -// } -// void memtrace_add_thread_entry(TaskHandle_t task) { -// if(!task) { -// ESP_LOGE(TAG, "memtrace_get_thread_entry: task is NULL"); -// return ; -// } -// mem_usage_trace_for_thread_t* it = memtrace_get_thread_entry(task); -// if (it) { -// ESP_LOGW(TAG, "memtrace_add_thread_entry: thread already in list"); -// return; -// } -// it = (mem_usage_trace_for_thread_t*)malloc_init_external(sizeof(mem_usage_trace_for_thread_t)); -// if (!it) { -// ESP_LOGE(TAG, "memtrace_add_thread_entry: malloc failed"); -// return; -// } -// it->task = task; -// it->malloc_int_last = heap_caps_get_free_size(MALLOC_CAP_INTERNAL); -// it->malloc_spiram_last = heap_caps_get_free_size(MALLOC_CAP_SPIRAM); -// it->malloc_dma_last = heap_caps_get_free_size(MALLOC_CAP_DMA); -// it->name = pcTaskGetName(task); -// SLIST_INSERT_HEAD(&s_memtrace, it, next); -// return; -// } +mem_usage_trace_for_thread_t* memtrace_get_thread_entry(TaskHandle_t task) { + if(!task) { + ESP_LOGE(TAG, "memtrace_get_thread_entry: task is NULL"); + return NULL; + } + ESP_LOGD(TAG,"Looking for task %s",STR_OR_ALT(pcTaskGetName(task ), "unknown")); + mem_usage_trace_for_thread_t* it; + SLIST_FOREACH(it, &s_memtrace, next) { + if ( it->task == task ) { + ESP_LOGD(TAG,"Found task %s",STR_OR_ALT(pcTaskGetName(task ), "unknown")); + return it; + } + } + return NULL; +} +void memtrace_add_thread_entry(TaskHandle_t task) { + if(!task) { + ESP_LOGE(TAG, "memtrace_get_thread_entry: task is NULL"); + return ; + } + mem_usage_trace_for_thread_t* it = memtrace_get_thread_entry(task); + if (it) { + ESP_LOGW(TAG, "memtrace_add_thread_entry: thread already in list"); + return; + } + it = (mem_usage_trace_for_thread_t*)malloc_init_external(sizeof(mem_usage_trace_for_thread_t)); + if (!it) { + ESP_LOGE(TAG, "memtrace_add_thread_entry: malloc failed"); + return; + } + it->task = task; + it->malloc_int_last = heap_caps_get_free_size(MALLOC_CAP_INTERNAL); + it->malloc_spiram_last = heap_caps_get_free_size(MALLOC_CAP_SPIRAM); + it->malloc_dma_last = heap_caps_get_free_size(MALLOC_CAP_DMA); + it->name = pcTaskGetName(task); + SLIST_INSERT_HEAD(&s_memtrace, it, next); + return; +} // void memtrace_print_delta(){ // TaskHandle_t task = xTaskGetCurrentTaskHandle(); // mem_usage_trace_for_thread_t* it = memtrace_get_thread_entry(task); @@ -74,7 +74,7 @@ static const char TAG[] = "TRACE"; // size_t malloc_int_delta = heap_caps_get_free_size(MALLOC_CAP_INTERNAL) - it->malloc_int_last; // size_t malloc_spiram_delta = heap_caps_get_free_size(MALLOC_CAP_SPIRAM) - it->malloc_spiram_last; // size_t malloc_dma_delta = heap_caps_get_free_size(MALLOC_CAP_DMA) - it->malloc_dma_last; -// ESP_LOG(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu) dma:%zu (min:%zu)", +// ESP_LOGD(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu) dma:%zu (min:%zu)", // heap_caps_get_free_size(MALLOC_CAP_INTERNAL), // heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL), // heap_caps_get_free_size(MALLOC_CAP_SPIRAM), diff --git a/components/tools/trace.h b/components/tools/trace.h index e099aa7a..5a37492e 100644 --- a/components/tools/trace.h +++ b/components/tools/trace.h @@ -12,6 +12,7 @@ #pragma once #ifdef ENABLE_MEMTRACE +void memtrace_print_delta(const char * msg, const char * tag, const char * function); #define MEMTRACE_PRINT_DELTA() memtrace_print_delta(NULL,TAG,__FUNCTION__); #define MEMTRACE_PRINT_DELTA_MESSAGE(x) memtrace_print_delta(x,TAG,__FUNCTION__); #else diff --git a/components/wifi-manager/CMakeLists.txt b/components/wifi-manager/CMakeLists.txt index db3be0c6..fc4dba6e 100644 --- a/components/wifi-manager/CMakeLists.txt +++ b/components/wifi-manager/CMakeLists.txt @@ -5,10 +5,43 @@ if(IDF_TARGET STREQUAL "esp32") set(target_requires "driver_bt") endif() -idf_component_register( SRC_DIRS . webapp UML-State-Machine-in-C/src - INCLUDE_DIRS . webapp UML-State-Machine-in-C/src +idf_component_register( SRC_DIRS . UML-State-Machine-in-C/src + INCLUDE_DIRS . UML-State-Machine-in-C/src REQUIRES squeezelite-ota json mdns PRIV_REQUIRES tools services platform_config esp_common json newlib freertos spi_flash nvs_flash mdns pthread wpa_supplicant platform_console esp_http_server console ${target_requires} ) -include(webapp/webapp.cmake) \ No newline at end of file +# Define the source and destination directories +set(WEBAPP_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/webapp/dist") +set(WEBAPP_DEST_DIR "${CMAKE_SOURCE_DIR}/spiffs/www") + +# Collect all .gz and .png files in the source directory +file(GLOB_RECURSE WEBAPP_FILES + "${WEBAPP_SOURCE_DIR}/*.gz" + "${WEBAPP_SOURCE_DIR}/*.png") + + +# # Custom command to copy files, preserving the directory structure +# foreach(FILE_PATH ${WEBAPP_FILES}) +# # Get the relative path from the source directory +# file(RELATIVE_PATH REL_PATH "${WEBAPP_SOURCE_DIR}" "${FILE_PATH}") +# # Compute the destination file path +# set(DEST_PATH "${WEBAPP_DEST_DIR}/${REL_PATH}") + +# # Create a custom command to copy each file +# add_custom_command( +# OUTPUT "${DEST_PATH}" +# COMMAND ${CMAKE_COMMAND} -E copy "${FILE_PATH}" "${DEST_PATH}" +# DEPENDS "${FILE_PATH}" +# ) +# # Add the destination path to a list of outputs +# list(APPEND WEBAPP_OUTPUT_FILES "${DEST_PATH}") +# endforeach() + +# # Custom target that depends on all copied files +# add_custom_target(copy_webapp DEPENDS ${WEBAPP_OUTPUT_FILES} ) + +# # Ensure the destination directory exists +# add_custom_command(TARGET copy_webapp PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${WEBAPP_DEST_DIR}" ) + +# add_dependencies(${COMPONENT_LIB} copy_webapp) \ No newline at end of file diff --git a/components/wifi-manager/esp32_improv.cpp.txt b/components/wifi-manager/esp32_improv.cpp.txt new file mode 100644 index 00000000..34bb16e4 --- /dev/null +++ b/components/wifi-manager/esp32_improv.cpp.txt @@ -0,0 +1,285 @@ +#include "esp32_improv.h" + +namespace esp32_improv { + +static const char *const TAG = "esp32_improv.component"; +static const char *const ESPHOME_MY_LINK = "https://my.home-assistant.io/redirect/config_flow_start?domain=esphome"; + +namespace esp32_improv { +void ESP32Improv::setup() { + this->service_ = global_ble_server->create_service(improv::SERVICE_UUID, true); + this->setup_characteristics(); +} + +void ESP32Improv::setup_characteristics() { + this->status_ = this->service_->create_characteristic( + improv::STATUS_UUID, + BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); + BLEDescriptor *status_descriptor = new BLE2902(); + this->status_->add_descriptor(status_descriptor); + + this->error_ = this->service_->create_characteristic( + improv::ERROR_UUID, + BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); + BLEDescriptor *error_descriptor = new BLE2902(); + this->error_->add_descriptor(error_descriptor); + + this->rpc_ = this->service_->create_characteristic( + improv::RPC_COMMAND_UUID, + BLECharacteristic::PROPERTY_WRITE); + this->rpc_->on_write([this](const std::vector &data) { + if (!data.empty()) { + this->incoming_data_.insert(this->incoming_data_.end(), data.begin(), data.end()); + } + }); + BLEDescriptor *rpc_descriptor = new BLE2902(); + this->rpc_->add_descriptor(rpc_descriptor); + + this->rpc_response_ = this->service_->create_characteristic( + improv::RPC_RESULT_UUID, + BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); + BLEDescriptor *rpc_response_descriptor = new BLE2902(); + this->rpc_response_->add_descriptor(rpc_response_descriptor); + + this->capabilities_ = + this->service_->create_characteristic( + improv::CAPABILITIES_UUID, + BLECharacteristic::PROPERTY_READ); + + + BLEDescriptor *capabilities_descriptor = new BLE2902(); + this->capabilities_->add_descriptor(capabilities_descriptor); + uint8_t capabilities = 0x00; + if (this->status_indicator_ != nullptr) + capabilities |= improv::CAPABILITY_IDENTIFY; + this->capabilities_->set_value(capabilities); + this->setup_complete_ = true; +} + +void ESP32Improv::loop() { + if (!this->incoming_data_.empty()) + this->process_incoming_data_(); + uint32_t now = gettime_ms(); + + switch (this->state_) { + case improv::STATE_STOPPED: + if (this->status_indicator_ != nullptr) + this->status_indicator_->turn_off(); + + if (this->service_->is_created() && this->should_start_ && this->setup_complete_) { + if (this->service_->is_running()) { + esp32_ble::global_ble->get_advertising()->start(); + + this->set_state_(improv::STATE_AWAITING_AUTHORIZATION); + this->set_error_(improv::ERROR_NONE); + this->should_start_ = false; + ESP_LOGD(TAG, "Service started!"); + } else { + this->service_->start(); + } + } + break; + case improv::STATE_AWAITING_AUTHORIZATION: { + if (this->authorizer_ == nullptr || this->authorizer_->state) { + this->set_state_(improv::STATE_AUTHORIZED); + this->authorized_start_ = now; + } else { + if (this->status_indicator_ != nullptr) { + if (!this->check_identify_()) + this->status_indicator_->turn_on(); + } + } + break; + } + case improv::STATE_AUTHORIZED: { + if (this->authorizer_ != nullptr) { + if (now - this->authorized_start_ > this->authorized_duration_) { + ESP_LOGD(TAG, "Authorization timeout"); + this->set_state_(improv::STATE_AWAITING_AUTHORIZATION); + return; + } + } + if (this->status_indicator_ != nullptr) { + if (!this->check_identify_()) { + if ((now % 1000) < 500) { + this->status_indicator_->turn_on(); + } else { + this->status_indicator_->turn_off(); + } + } + } + break; + } + case improv::STATE_PROVISIONING: { + if (this->status_indicator_ != nullptr) { + if ((now % 200) < 100) { + this->status_indicator_->turn_on(); + } else { + this->status_indicator_->turn_off(); + } + } + if (wifi::global_wifi_component->is_connected()) { + wifi::global_wifi_component->save_wifi_sta(this->connecting_sta_.get_ssid(), + this->connecting_sta_.get_password()); + this->connecting_sta_ = {}; + this->cancel_timeout("wifi-connect-timeout"); + this->set_state_(improv::STATE_PROVISIONED); + + std::vector urls = {ESPHOME_MY_LINK}; +#ifdef USE_WEBSERVER + auto ip = wifi::global_wifi_component->wifi_sta_ip(); + std::string webserver_url = "http://" + ip.str() + ":" + to_string(USE_WEBSERVER_PORT); + urls.push_back(webserver_url); +#endif + std::vector data = improv::build_rpc_response(improv::WIFI_SETTINGS, urls); + this->send_response_(data); + this->set_timeout("end-service", 1000, [this] { + this->service_->stop(); + this->set_state_(improv::STATE_STOPPED); + }); + } + break; + } + case improv::STATE_PROVISIONED: { + this->incoming_data_.clear(); + if (this->status_indicator_ != nullptr) + this->status_indicator_->turn_off(); + break; + } + } +} + +bool ESP32Improv::check_identify_() { + uint32_t now = gettime_ms(); + + bool identify = this->identify_start_ != 0 && now - this->identify_start_ <= this->identify_duration_; + + if (identify) { + uint32_t time = now % 1000; + if (time < 600 && time % 200 < 100) { + this->status_indicator_->turn_on(); + } else { + this->status_indicator_->turn_off(); + } + } + return identify; +} + +void ESP32Improv::set_state_(improv::State state) { + ESP_LOGV(TAG, "Setting state: %d", state); + this->state_ = state; + if (this->status_->get_value().empty() || this->status_->get_value()[0] != state) { + uint8_t data[1]{state}; + this->status_->set_value(data, 1); + if (state != improv::STATE_STOPPED) + this->status_->notify(); + } +} + +void ESP32Improv::set_error_(improv::Error error) { + if (error != improv::ERROR_NONE) + ESP_LOGE(TAG, "Error: %d", error); + if (this->error_->get_value().empty() || this->error_->get_value()[0] != error) { + uint8_t data[1]{error}; + this->error_->set_value(data, 1); + if (this->state_ != improv::STATE_STOPPED) + this->error_->notify(); + } +} + +void ESP32Improv::send_response_(std::vector &response) { + this->rpc_response_->set_value(response); + if (this->state_ != improv::STATE_STOPPED) + this->rpc_response_->notify(); +} + +void ESP32Improv::start() { + if (this->state_ != improv::STATE_STOPPED) + return; + + ESP_LOGD(TAG, "Setting Improv to start"); + this->should_start_ = true; +} + +void ESP32Improv::stop() { + this->set_timeout("end-service", 1000, [this] { + this->service_->stop(); + this->set_state_(improv::STATE_STOPPED); + }); +} + +float ESP32Improv::get_setup_priority() const { return setup_priority::AFTER_BLUETOOTH; } + +void ESP32Improv::dump_config() { + ESP_LOGCONFIG(TAG, "ESP32 Improv:"); + LOG_BINARY_SENSOR(" ", "Authorizer", this->authorizer_); + ESP_LOGCONFIG(TAG, " Status Indicator: '%s'", YESNO(this->status_indicator_ != nullptr)); +} + +void ESP32Improv::process_incoming_data_() { + uint8_t length = this->incoming_data_[1]; + + ESP_LOGD(TAG, "Processing bytes - %s", format_hex_pretty(this->incoming_data_).c_str()); + if (this->incoming_data_.size() - 3 == length) { + this->set_error_(improv::ERROR_NONE); + improv::ImprovCommand command = improv::parse_improv_data(this->incoming_data_); + switch (command.command) { + case improv::BAD_CHECKSUM: + ESP_LOGW(TAG, "Error decoding Improv payload"); + this->set_error_(improv::ERROR_INVALID_RPC); + this->incoming_data_.clear(); + break; + case improv::WIFI_SETTINGS: { + if (this->state_ != improv::STATE_AUTHORIZED) { + ESP_LOGW(TAG, "Settings received, but not authorized"); + this->set_error_(improv::ERROR_NOT_AUTHORIZED); + this->incoming_data_.clear(); + return; + } + wifi::WiFiAP sta{}; + sta.set_ssid(command.ssid); + sta.set_password(command.password); + this->connecting_sta_ = sta; + + wifi::global_wifi_component->set_sta(sta); + wifi::global_wifi_component->start_scanning(); + this->set_state_(improv::STATE_PROVISIONING); + ESP_LOGD(TAG, "Received Improv wifi settings ssid=%s, password=" LOG_SECRET("%s"), command.ssid.c_str(), + command.password.c_str()); + + auto f = std::bind(&ESP32Improv::on_wifi_connect_timeout_, this); + this->set_timeout("wifi-connect-timeout", 30000, f); + this->incoming_data_.clear(); + break; + } + case improv::IDENTIFY: + this->incoming_data_.clear(); + this->identify_start_ = gettime_ms(); + break; + default: + ESP_LOGW(TAG, "Unknown Improv payload"); + this->set_error_(improv::ERROR_UNKNOWN_RPC); + this->incoming_data_.clear(); + } + } else if (this->incoming_data_.size() - 2 > length) { + ESP_LOGV(TAG, "Too much data came in, or malformed resetting buffer..."); + this->incoming_data_.clear(); + } else { + ESP_LOGV(TAG, "Waiting for split data packets..."); + } +} + +void ESP32Improv::on_wifi_connect_timeout_() { + this->set_error_(improv::ERROR_UNABLE_TO_CONNECT); + this->set_state_(improv::STATE_AUTHORIZED); + if (this->authorizer_ != nullptr) + this->authorized_start_ = gettime_ms(); + ESP_LOGW(TAG, "Timed out trying to connect to given WiFi network"); + wifi::global_wifi_component->clear_sta(); +} + +void ESP32Improv::on_client_disconnect() { this->set_error_(improv::ERROR_NONE); }; + +ESP32Improv *global_improv_component = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + +} // namespace esp32_improv diff --git a/components/wifi-manager/esp32_improv.h.txt b/components/wifi-manager/esp32_improv.h.txt new file mode 100644 index 00000000..d1ad92dc --- /dev/null +++ b/components/wifi-manager/esp32_improv.h.txt @@ -0,0 +1,71 @@ +#pragma once + +#include + +#include "esp_bt.h" +#include "esp_bt_main.h" +#include "esp_gap_bt_api.h" +#include "bt_app_core.h" + +#include "BLECharacteristic.h" +//#include "esphome/components/esp32_ble_server/ble_server.h" + +namespace esp32_improv { + +class ESP32Improv { + public: + ESP32Improv(); + void dump_config() ; + void loop() ; + void setup() ; + void setup_characteristics(); + void on_client_disconnect() ; + + float get_setup_priority() ; + void start() ; + void stop() ; + bool is_active() const { return this->state_ != improv::STATE_STOPPED; } + + void set_authorizer(binary_sensor::BinarySensor *authorizer) { this->authorizer_ = authorizer; } + void set_status_indicator(output::BinaryOutput *status_indicator) { this->status_indicator_ = status_indicator; } + void set_identify_duration(uint32_t identify_duration) { this->identify_duration_ = identify_duration; } + void set_authorized_duration(uint32_t authorized_duration) { this->authorized_duration_ = authorized_duration; } + + protected: + bool should_start_{false}; + bool setup_complete_{false}; + + uint32_t identify_start_{0}; + uint32_t identify_duration_; + uint32_t authorized_start_{0}; + uint32_t authorized_duration_; + + std::vector incoming_data_; + wifi::WiFiAP connecting_sta_; + + std::shared_ptr service_; + BLECharacteristic *status_; + BLECharacteristic *error_; + BLECharacteristic *rpc_; + BLECharacteristic *rpc_response_; + BLECharacteristic *capabilities_; + + binary_sensor::BinarySensor *authorizer_{nullptr}; + output::BinaryOutput *status_indicator_{nullptr}; + + improv::State state_{improv::STATE_STOPPED}; + improv::Error error_state_{improv::ERROR_NONE}; + + void set_state_(improv::State state); + void set_error_(improv::Error error); + void send_response_(std::vector &response); + void process_incoming_data_(); + void on_wifi_connect_timeout_(); + bool check_identify_(); +}; + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) +extern ESP32ImprovComponent *global_improv_component; + +} // namespace esp32_improv + diff --git a/components/wifi-manager/http_server_handlers.c b/components/wifi-manager/http_server_handlers.c index 331607a9..73471ed9 100644 --- a/components/wifi-manager/http_server_handlers.c +++ b/components/wifi-manager/http_server_handlers.c @@ -3,71 +3,73 @@ Copyright (c) 2017-2021 Sebastien L */ #include "http_server_handlers.h" -#include "esp_http_server.h" -#include "cmd_system.h" -#include -#include "squeezelite-ota.h" -#include "nvs_utilities.h" -#include -#include #include "cJSON.h" +#include "cmd_system.h" +#include "esp_http_server.h" #include "esp_system.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "platform_config.h" -#include "sys/param.h" +#include "squeezelite-ota.h" +#include +#include +#include +#include "Configurator.h" +#include "accessors.h" +#include "argtable3/argtable3.h" +#include "esp_console.h" #include "esp_vfs.h" #include "messaging.h" -#include "platform_esp32.h" -#include "esp_console.h" -#include "argtable3/argtable3.h" -#include "platform_console.h" -#include "accessors.h" -#include "webapp/webpack.h" -#include "network_wifi.h" #include "network_status.h" +#include "network_wifi.h" +#include "platform_console.h" +#include "platform_esp32.h" +#include "sys/param.h" #include "tools.h" - -#define HTTP_STACK_SIZE (5*1024) -const char str_na[]="N/A"; -#define STR_OR_NA(s) s?s:str_na +#include "pb_encode.h" +#include "pb_decode.h" +#include "Status.pb.h" +#define HTTP_STACK_SIZE (5 * 1024) +const char str_na[] = "N/A"; +#define STR_OR_NA(s) s ? s : str_na /* @brief tag used for ESP serial console messages */ static const char TAG[] = "httpd_handlers"; -/* @brief task handle for the http server */ +static const char* www_dir = "/spiffs/www"; SemaphoreHandle_t http_server_config_mutex = NULL; extern RingbufHandle_t messaging; #define AUTH_TOKEN_SIZE 50 typedef struct session_context { - char * auth_token; + char* auth_token; bool authenticated; - char * sess_ip_address; + char* sess_ip_address; u16_t port; } session_context_t; -extern cJSON * get_gpio_list(bool refresh); +extern cJSON* get_gpio_list(bool refresh); union sockaddr_aligned { - struct sockaddr sa; + struct sockaddr sa; struct sockaddr_storage st; - struct sockaddr_in sin; + struct sockaddr_in sin; struct sockaddr_in6 sin6; } aligned_sockaddr_t; -esp_err_t post_handler_buff_receive(httpd_req_t * req); -static const char redirect_payload1[]="Redirecting to Captive Portal

Please wait, refreshing. If page does not refresh, click here to login.

"; +esp_err_t post_handler_buff_receive(httpd_req_t* req); +static const char redirect_payload1[] = "Redirecting to Captive " + "Portal

Please wait, refreshing. If page does not refresh, click here to login.

"; /** * @brief embedded binary data. * @see file "component.mk" - * @see https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#embedding-binary-data + * @see + * https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#embedding-binary-data */ -esp_err_t redirect_processor(httpd_req_t *req, httpd_err_code_t error); +esp_err_t redirect_processor(httpd_req_t* req, httpd_err_code_t error); - -char * alloc_get_http_header(httpd_req_t * req, const char * key){ - char* buf = NULL; +char* alloc_get_http_header(httpd_req_t* req, const char* key) { + char* buf = NULL; size_t buf_len; /* Get header value string length and allocate memory for length + 1, @@ -77,106 +79,102 @@ char * alloc_get_http_header(httpd_req_t * req, const char * key){ buf = malloc_init_external(buf_len); /* Copy null terminated value string into buffer */ if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) { - ESP_LOGD_LOC(TAG, "Found header => %s: %s",key, buf); + ESP_LOGD_LOC(TAG, "Found header => %s: %s", key, buf); } } return buf; } +char* http_alloc_get_socket_address(httpd_req_t* req, u8_t local, in_port_t* portl) { -char * http_alloc_get_socket_address(httpd_req_t *req, u8_t local, in_port_t * portl) { + socklen_t len; + union sockaddr_aligned addr; + len = sizeof(addr); + ip_addr_t* ip_addr = NULL; + char* ipstr = malloc_init_external(INET6_ADDRSTRLEN); + typedef int (*getaddrname_fn_t)(int s, struct sockaddr* name, socklen_t* namelen); + getaddrname_fn_t get_addr = NULL; - socklen_t len; - union sockaddr_aligned addr; - len = sizeof(addr); - ip_addr_t * ip_addr=NULL; - char * ipstr = malloc_init_external(INET6_ADDRSTRLEN); - typedef int (*getaddrname_fn_t)(int s, struct sockaddr *name, socklen_t *namelen); - getaddrname_fn_t get_addr = NULL; - - int s = httpd_req_to_sockfd(req); - if(s == -1) { - free(ipstr); - return strdup_psram("httpd_req_to_sockfd error"); - } - ESP_LOGV_LOC(TAG,"httpd socket descriptor: %u", s); - - get_addr = local?&lwip_getsockname:&lwip_getpeername; - if(get_addr(s, (struct sockaddr *)&addr, &len) <0){ - ESP_LOGE_LOC(TAG,"Failed to retrieve socket address"); - sprintf(ipstr,"N/A (0.0.0.%u)",local); - } - else { - if (addr.sin.sin_family!= AF_INET) { - ip_addr = (ip_addr_t *)&(addr.sin6.sin6_addr); - inet_ntop(addr.sa.sa_family, ip_addr, ipstr, INET6_ADDRSTRLEN); - ESP_LOGV_LOC(TAG,"Processing an IPV6 address : %s", ipstr); - *portl = addr.sin6.sin6_port; - unmap_ipv4_mapped_ipv6(ip_2_ip4(ip_addr), ip_2_ip6(ip_addr)); - } - else { - ip_addr = (ip_addr_t *)&(addr.sin.sin_addr); - inet_ntop(addr.sa.sa_family, ip_addr, ipstr, INET6_ADDRSTRLEN); - ESP_LOGV_LOC(TAG,"Processing an IPV6 address : %s", ipstr); - *portl = addr.sin.sin_port; - } - inet_ntop(AF_INET, ip_addr, ipstr, INET6_ADDRSTRLEN); - ESP_LOGV_LOC(TAG,"Retrieved ip address:port = %s:%u",ipstr, *portl); - } - return ipstr; -} -bool is_captive_portal_host_name(httpd_req_t *req){ - const char * host_name=NULL; - const char * ap_host_name=NULL; - char * ap_ip_address=NULL; - bool request_contains_hostname = false; - esp_err_t hn_err =ESP_OK, err=ESP_OK; - ESP_LOGD_LOC(TAG, "Getting adapter host name"); - if((err = tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &host_name )) !=ESP_OK) { - ESP_LOGE_LOC(TAG, "Unable to get host name. Error: %s",esp_err_to_name(err)); - } - else { - ESP_LOGD_LOC(TAG, "Host name is %s",host_name); - } - - ESP_LOGD_LOC(TAG, "Getting host name from request"); - char *req_host = alloc_get_http_header(req, "Host"); - - if(tcpip_adapter_is_netif_up(TCPIP_ADAPTER_IF_AP)){ - ESP_LOGD_LOC(TAG, "Soft AP is enabled. getting ip info"); - // Access point is up and running. Get the current IP address - tcpip_adapter_ip_info_t ip_info; - esp_err_t ap_ip_err = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_info); - if(ap_ip_err != ESP_OK){ - ESP_LOGE_LOC(TAG, "Unable to get local AP ip address. Error: %s",esp_err_to_name(ap_ip_err)); - } - else { - ESP_LOGD_LOC(TAG, "getting host name for TCPIP_ADAPTER_IF_AP"); - if((hn_err = tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_AP, &ap_host_name )) !=ESP_OK) { - ESP_LOGE_LOC(TAG, "Unable to get host name. Error: %s",esp_err_to_name(hn_err)); - err=err==ESP_OK?hn_err:err; - } - else { - ESP_LOGD_LOC(TAG, "Soft AP Host name is %s",ap_host_name); - } - - ap_ip_address = malloc_init_external(IP4ADDR_STRLEN_MAX); - memset(ap_ip_address, 0x00, IP4ADDR_STRLEN_MAX); - if(ap_ip_address){ - ESP_LOGD_LOC(TAG, "Converting soft ip address to string"); - ip4addr_ntoa_r(&ip_info.ip, ap_ip_address, IP4ADDR_STRLEN_MAX); - ESP_LOGD_LOC(TAG,"TCPIP_ADAPTER_IF_AP is up and has ip address %s ", ap_ip_address); - } - } - - } - - - if((request_contains_hostname = (host_name!=NULL) && (req_host!=NULL) && strcasestr(req_host,host_name)) == true){ - ESP_LOGD_LOC(TAG,"http request host = system host name %s", req_host); + int s = httpd_req_to_sockfd(req); + if (s == -1) { + free(ipstr); + return strdup_psram("httpd_req_to_sockfd error"); } - else if((request_contains_hostname = (ap_host_name!=NULL) && (req_host!=NULL) && strcasestr(req_host,ap_host_name)) == true){ - ESP_LOGD_LOC(TAG,"http request host = AP system host name %s", req_host); + ESP_LOGV_LOC(TAG, "httpd socket descriptor: %u", s); + + get_addr = local ? &lwip_getsockname : &lwip_getpeername; + if (get_addr(s, (struct sockaddr*)&addr, &len) < 0) { + ESP_LOGE_LOC(TAG, "Failed to retrieve socket address"); + sprintf(ipstr, "N/A (0.0.0.%u)", local); + } else { + if (addr.sin.sin_family != AF_INET) { + ip_addr = (ip_addr_t*)&(addr.sin6.sin6_addr); + inet_ntop(addr.sa.sa_family, ip_addr, ipstr, INET6_ADDRSTRLEN); + ESP_LOGV_LOC(TAG, "Processing an IPV6 address : %s", ipstr); + *portl = addr.sin6.sin6_port; + unmap_ipv4_mapped_ipv6(ip_2_ip4(ip_addr), ip_2_ip6(ip_addr)); + } else { + ip_addr = (ip_addr_t*)&(addr.sin.sin_addr); + inet_ntop(addr.sa.sa_family, ip_addr, ipstr, INET6_ADDRSTRLEN); + ESP_LOGV_LOC(TAG, "Processing an IPV6 address : %s", ipstr); + *portl = addr.sin.sin_port; + } + inet_ntop(AF_INET, ip_addr, ipstr, INET6_ADDRSTRLEN); + ESP_LOGV_LOC(TAG, "Retrieved ip address:port = %s:%u", ipstr, *portl); + } + return ipstr; +} +bool is_captive_portal_host_name(httpd_req_t* req) { + const char* host_name = NULL; + const char* ap_host_name = NULL; + char* ap_ip_address = NULL; + bool request_contains_hostname = false; + esp_err_t hn_err = ESP_OK, err = ESP_OK; + ESP_LOGD_LOC(TAG, "Getting adapter host name"); + if ((err = tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &host_name)) != ESP_OK) { + ESP_LOGE_LOC(TAG, "Unable to get host name. Error: %s", esp_err_to_name(err)); + } else { + ESP_LOGD_LOC(TAG, "Host name is %s", host_name); + } + + ESP_LOGD_LOC(TAG, "Getting host name from request"); + char* req_host = alloc_get_http_header(req, "Host"); + + if (tcpip_adapter_is_netif_up(TCPIP_ADAPTER_IF_AP)) { + ESP_LOGD_LOC(TAG, "Soft AP is enabled. getting ip info"); + // Access point is up and running. Get the current IP address + tcpip_adapter_ip_info_t ip_info; + esp_err_t ap_ip_err = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_info); + if (ap_ip_err != ESP_OK) { + ESP_LOGE_LOC( + TAG, "Unable to get local AP ip address. Error: %s", esp_err_to_name(ap_ip_err)); + } else { + ESP_LOGD_LOC(TAG, "getting host name for TCPIP_ADAPTER_IF_AP"); + if ((hn_err = tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_AP, &ap_host_name)) != + ESP_OK) { + ESP_LOGE_LOC(TAG, "Unable to get host name. Error: %s", esp_err_to_name(hn_err)); + err = err == ESP_OK ? hn_err : err; + } else { + ESP_LOGD_LOC(TAG, "Soft AP Host name is %s", ap_host_name); + } + + ap_ip_address = malloc_init_external(IP4ADDR_STRLEN_MAX); + memset(ap_ip_address, 0x00, IP4ADDR_STRLEN_MAX); + if (ap_ip_address) { + ESP_LOGD_LOC(TAG, "Converting soft ip address to string"); + ip4addr_ntoa_r(&ip_info.ip, ap_ip_address, IP4ADDR_STRLEN_MAX); + ESP_LOGD_LOC( + TAG, "TCPIP_ADAPTER_IF_AP is up and has ip address %s ", ap_ip_address); + } + } + } + + if ((request_contains_hostname = (host_name != NULL) && (req_host != NULL) && + strcasestr(req_host, host_name)) == true) { + ESP_LOGD_LOC(TAG, "http request host = system host name %s", req_host); + } else if ((request_contains_hostname = (ap_host_name != NULL) && (req_host != NULL) && + strcasestr(req_host, ap_host_name)) == true) { + ESP_LOGD_LOC(TAG, "http request host = AP system host name %s", req_host); } FREE_AND_NULL(ap_ip_address); @@ -186,105 +184,101 @@ bool is_captive_portal_host_name(httpd_req_t *req){ } /* Custom function to free context */ -void free_ctx_func(void *ctx) -{ - session_context_t * context = (session_context_t *)ctx; - if(context){ - ESP_LOGD(TAG, "Freeing up socket context"); - FREE_AND_NULL(context->auth_token); - FREE_AND_NULL(context->sess_ip_address); - free(context); +void free_ctx_func(void* ctx) { + session_context_t* context = (session_context_t*)ctx; + if (context) { + ESP_LOGD(TAG, "Freeing up socket context"); + FREE_AND_NULL(context->auth_token); + FREE_AND_NULL(context->sess_ip_address); + free(context); } } -session_context_t* get_session_context(httpd_req_t *req){ - bool newConnection=false; - if (! req->sess_ctx) { - ESP_LOGD(TAG,"New connection context. Allocating session buffer"); - req->sess_ctx = malloc_init_external(sizeof(session_context_t)); - req->free_ctx = free_ctx_func; - newConnection = true; - // get the remote IP address only once per session - } - session_context_t *ctx_data = (session_context_t*)req->sess_ctx; - FREE_AND_NULL(ctx_data->sess_ip_address); - ctx_data->sess_ip_address = http_alloc_get_socket_address(req, 0, &ctx_data->port); - if(newConnection){ - ESP_LOGI(TAG, "serving %s to peer %s port %u", req->uri, ctx_data->sess_ip_address , ctx_data->port); - } - return (session_context_t *)req->sess_ctx; +session_context_t* get_session_context(httpd_req_t* req) { + bool newConnection = false; + if (!req->sess_ctx) { + ESP_LOGD(TAG, "New connection context. Allocating session buffer"); + req->sess_ctx = malloc_init_external(sizeof(session_context_t)); + req->free_ctx = free_ctx_func; + newConnection = true; + // get the remote IP address only once per session + } + session_context_t* ctx_data = (session_context_t*)req->sess_ctx; + FREE_AND_NULL(ctx_data->sess_ip_address); + ctx_data->sess_ip_address = http_alloc_get_socket_address(req, 0, &ctx_data->port); + if (newConnection) { + ESP_LOGI(TAG, "serving %s to peer %s port %u", req->uri, ctx_data->sess_ip_address, + ctx_data->port); + } + return (session_context_t*)req->sess_ctx; } -bool is_user_authenticated(httpd_req_t *req){ - session_context_t *ctx_data = get_session_context(req); +bool is_user_authenticated(httpd_req_t* req) { + session_context_t* ctx_data = get_session_context(req); - if(ctx_data->authenticated){ - ESP_LOGD_LOC(TAG,"User is authenticated."); - return true; - } + if (ctx_data->authenticated) { + ESP_LOGD_LOC(TAG, "User is authenticated."); + return true; + } - ESP_LOGD(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu) dma:%zu (min:%zu)", - heap_caps_get_free_size(MALLOC_CAP_INTERNAL), - heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL), - heap_caps_get_free_size(MALLOC_CAP_SPIRAM), - heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM), - heap_caps_get_free_size(MALLOC_CAP_DMA), - heap_caps_get_minimum_free_size(MALLOC_CAP_DMA)); + ESP_LOGD(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu) dma:%zu (min:%zu)", + heap_caps_get_free_size(MALLOC_CAP_INTERNAL), + heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL), + heap_caps_get_free_size(MALLOC_CAP_SPIRAM), + heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM), heap_caps_get_free_size(MALLOC_CAP_DMA), + heap_caps_get_minimum_free_size(MALLOC_CAP_DMA)); - // todo: ask for user to authenticate - return false; + // todo: ask for user to authenticate + return false; } - - /* Copies the full path into destination buffer and returns * pointer to requested file name */ -static const char* get_path_from_uri(char *dest, const char *uri, size_t destsize) -{ +static const char* get_path_from_uri(char* dest, const char* uri, size_t destsize) { size_t pathlen = strlen(uri); - memset(dest,0x0,destsize); + memset(dest, 0x0, destsize); - const char *quest = strchr(uri, '?'); + const char* quest = strchr(uri, '?'); if (quest) { pathlen = MIN(pathlen, quest - uri); } - const char *hash = strchr(uri, '#'); + const char* hash = strchr(uri, '#'); if (hash) { pathlen = MIN(pathlen, hash - uri); } - if ( pathlen + 1 > destsize) { + if (pathlen + 1 > destsize) { /* Full path string won't fit into destination buffer */ return NULL; } - strlcpy(dest , uri, pathlen + 1); + strlcpy(dest, uri, pathlen + 1); // strip trailing blanks - char * sr = dest+pathlen; - while(*sr== ' ') *sr-- = '\0'; + char* sr = dest + pathlen; + while (*sr == ' ') + *sr-- = '\0'; - char * last_fs = strchr(dest,'/'); - if(!last_fs) ESP_LOGD_LOC(TAG,"no / found in %s", dest); - char * p=last_fs; - while(p && *(++p)!='\0'){ - if(*p == '/') { - last_fs=p; - } + char* last_fs = strchr(dest, '/'); + if (!last_fs) ESP_LOGD_LOC(TAG, "no / found in %s", dest); + char* p = last_fs; + while (p && *(++p) != '\0') { + if (*p == '/') { + last_fs = p; + } } /* Return pointer to path, skipping the base */ - return last_fs? ++last_fs: dest; + return last_fs ? ++last_fs : dest; } -#define IS_FILE_EXT(filename, ext) \ +#define IS_FILE_EXT(filename, ext) \ (strcasecmp(&filename[strlen(filename) - sizeof(ext) + 1], ext) == 0) /* Set HTTP response content type according to file extension */ -static esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename) -{ - if(strlen(filename) ==0){ - // for root page, etc. - return httpd_resp_set_type(req, HTTPD_TYPE_TEXT); +static esp_err_t set_content_type_from_file(httpd_req_t* req, const char* filename) { + if (strlen(filename) == 0) { + // for root page, etc. + return httpd_resp_set_type(req, HTTPD_TYPE_TEXT); } else if (IS_FILE_EXT(filename, ".pdf")) { return httpd_resp_set_type(req, "application/pdf"); } else if (IS_FILE_EXT(filename, ".html")) { @@ -303,848 +297,1065 @@ static esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filena return httpd_resp_set_type(req, HTTPD_TYPE_JSON); } else if (IS_FILE_EXT(filename, ".map")) { return httpd_resp_set_type(req, "map"); + } else if (IS_FILE_EXT(filename, ".pro")) { + return httpd_resp_set_type(req, "application/octet-stream"); } - /* This is a limited set only */ /* For any other type always set as plain text */ return httpd_resp_set_type(req, "text/plain"); } -static esp_err_t set_content_type_from_req(httpd_req_t *req) -{ - char filepath[FILE_PATH_MAX]; - const char *filename = get_path_from_uri(filepath, req->uri, sizeof(filepath)); - if (!filename) { - ESP_LOGE_LOC(TAG, "Filename is too long"); - /* Respond with 500 Internal Server Error */ - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long"); - return ESP_FAIL; - } +static esp_err_t set_content_type_from_req(httpd_req_t* req) { + char filepath[FILE_PATH_MAX]; + const char* filename = get_path_from_uri(filepath, req->uri, sizeof(filepath)); + if (!filename) { + ESP_LOGE_LOC(TAG, "Filename is too long"); + /* Respond with 500 Internal Server Error */ + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long"); + return ESP_FAIL; + } - /* If name has trailing '/', respond with directory contents */ - if (filename[strlen(filename) - 1] == '/' && strlen(filename)>1) { - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Browsing files forbidden."); - return ESP_FAIL; - } - set_content_type_from_file(req, filename); - return ESP_OK; + /* If name has trailing '/', respond with directory contents */ + if (filename[strlen(filename) - 1] == '/' && strlen(filename) > 1) { + httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Browsing files forbidden."); + return ESP_FAIL; + } + set_content_type_from_file(req, filename); + return ESP_OK; } -int resource_get_index(const char * fileName){ - for(int i=0;resource_lookups[i][0]!='\0';i++){ - if(strstr(resource_lookups[i], fileName)){ - return i; - } - } - return -1; +// esp_err_t root_get_handler(httpd_req_t *req){ +// esp_err_t err = ESP_OK; +// ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); +// httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); +// httpd_resp_set_hdr(req, "Accept-Encoding", "identity"); + +// if(!is_user_authenticated(req)){ +// // todo: send password entry page and return +// } +// int idx=-1; +// if((idx=resource_get_index("index.html"))>=0){ +// const size_t file_size = (resource_map_end[idx] - resource_map_start[idx]); +// httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); +// err = set_content_type_from_req(req); +// if(err == ESP_OK){ +// httpd_resp_send(req, (const char *)resource_map_start[idx], file_size); +// } +// } +// else{ +// httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "index.html not found"); +// return ESP_FAIL; +// } +// ESP_LOGD_LOC(TAG, "done serving [%s]", req->uri); +// return err; +// } +static bool resolve_file_path(const char* uri, char* resolvedpath, size_t resolvedsize) { + struct stat file_stat; + + // Assume the base path is the directory where files are served from + // Generate the expected file path + snprintf(resolvedpath, resolvedsize, "%s%s", www_dir, uri); + + // Check if file exists + if (stat(resolvedpath, &file_stat) == 0) { + // File exists + return true; + } else { + // Check for compressed file + strncat(resolvedpath, ".gz", resolvedsize - strlen(resolvedpath) - 1); + if (stat(resolvedpath, &file_stat) == 0) { + // Compressed file exists + return true; + } + } + + // Neither uncompressed nor compressed file exists + return false; } -esp_err_t root_get_handler(httpd_req_t *req){ - esp_err_t err = ESP_OK; - ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); +esp_err_t file_get_handler(httpd_req_t* req) { + size_t sz; + char filepath[FILE_PATH_MAX]; + struct stat file_stat={}; + + httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); + + ESP_LOGD_LOC(TAG, "Serving file from [%s]", req->uri); + const char* filename = get_path_from_uri(filepath, req->uri, sizeof(filepath)); + if (!filename) { + ESP_LOGE_LOC(TAG, "Filename is too long"); + /* Respond with 500 Internal Server Error */ + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long"); + return ESP_FAIL; + } + /* If name has trailing '/', respond with directory contents */ + if (filename[strlen(filename) - 1] == '/') { + httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Browsing files forbidden."); + return ESP_FAIL; + } + if (strlen(filename) != 0 && IS_FILE_EXT(filename, ".map")) { + return httpd_resp_sendstr(req, ""); + } + if (!resolve_file_path(filename, filepath, sizeof(filepath))) { + httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File not found"); + return ESP_FAIL; + } + esp_err_t err = set_content_type_from_file(req, filepath); + if (err != ESP_OK) { + return ESP_FAIL; + } + + char* buffer = load_file(&sz,filepath); + if (buffer) { + if (sz == file_stat.st_size) { + httpd_resp_send(req, buffer, sz); + } else { + ESP_LOGE(TAG, "Failed to read full file : %s", filepath); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read full file"); + err = ESP_FAIL; + } + free(buffer); + } else { + ESP_LOGE(TAG, "Failed to allocate memory for file : %s", filepath); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Server out of memory"); + err = ESP_FAIL; + } + return ESP_OK; +} + +esp_err_t root_get_handler(httpd_req_t* req) { + size_t sz; + char filepath[FILE_PATH_MAX]; + esp_err_t err = ESP_OK; + ESP_LOGD(TAG, "Serving [%s]", req->uri); + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); httpd_resp_set_hdr(req, "Accept-Encoding", "identity"); - if(!is_user_authenticated(req)){ - // todo: send password entry page and return + if (!is_user_authenticated(req)) { + // TODO: Send password entry page and return } - int idx=-1; - if((idx=resource_get_index("index.html"))>=0){ - const size_t file_size = (resource_map_end[idx] - resource_map_start[idx]); - httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); - err = set_content_type_from_req(req); - if(err == ESP_OK){ - httpd_resp_send(req, (const char *)resource_map_start[idx], file_size); - } - } - else{ - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "index.html not found"); - return ESP_FAIL; - } - ESP_LOGD_LOC(TAG, "done serving [%s]", req->uri); + if (!resolve_file_path("index.html", filepath, sizeof(filepath))) { + httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File not found"); + return ESP_FAIL; + } + err = set_content_type_from_file(req, filepath); + if (err != ESP_OK) { + return ESP_FAIL; + } + + char* buffer = load_file(&sz,filepath); + if (buffer) { + httpd_resp_send(req, buffer, sz); + free(buffer); + } else { + ESP_LOGE(TAG, "Failed to allocate memory for file : %s", filepath); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Server out of memory"); + err = ESP_FAIL; + } + + ESP_LOGD(TAG, "Done serving [%s]", req->uri); + return err; +} + +esp_err_t resource_filehandler(httpd_req_t* req) { + ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); + esp_err_t err = file_get_handler(req); + ESP_LOGD_LOC(TAG, "Resource sending complete"); + return err; +} +esp_err_t ap_scan_handler(httpd_req_t* req) { + const char empty[] = "{}"; + ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; + } + network_async_scan(); + esp_err_t err = set_content_type_from_req(req); + if (err == ESP_OK) { + httpd_resp_send(req, (const char*)empty, HTTPD_RESP_USE_STRLEN); + } + return err; +} + +esp_err_t console_cmd_get_handler(httpd_req_t* req) { + ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; + } + /* if we can get the mutex, write the last version of the AP list */ + esp_err_t err = set_content_type_from_req(req); + cJSON* cmdlist = get_cmd_list(); + char* json_buffer = cJSON_Print(cmdlist); + if (json_buffer) { + httpd_resp_send(req, (const char*)json_buffer, HTTPD_RESP_USE_STRLEN); + free(json_buffer); + } else { + ESP_LOGD_LOC(TAG, "Error retrieving command json string. "); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to format command"); + } + cJSON_Delete(cmdlist); + ESP_LOGD_LOC(TAG, "done serving [%s]", req->uri); + return err; +} +esp_err_t console_cmd_post_handler(httpd_req_t* req) { + char success[] = "{\"Result\" : \"Success\" }"; + ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); + // bool bOTA=false; + // char * otaURL=NULL; + esp_err_t err = post_handler_buff_receive(req); + if (err != ESP_OK) { + return err; + } + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; + } + err = set_content_type_from_req(req); + if (err != ESP_OK) { + return err; + } + + char* command = ((rest_server_context_t*)(req->user_ctx))->scratch; + + cJSON* root = cJSON_Parse(command); + if (root == NULL) { + ESP_LOGE_LOC(TAG, "Parsing command. Received content was: %s", command); + httpd_resp_send_err( + req, HTTPD_400_BAD_REQUEST, "Malformed command json. Unable to parse content."); + return ESP_FAIL; + } + char* root_str = cJSON_Print(root); + if (root_str != NULL) { + ESP_LOGD(TAG, "Processing command item: \n%s", root_str); + free(root_str); + } + cJSON* item = cJSON_GetObjectItemCaseSensitive(root, "command"); + if (!item) { + ESP_LOGE_LOC(TAG, "Command not found. Received content was: %s", command); + httpd_resp_send_err( + req, HTTPD_400_BAD_REQUEST, "Malformed command json. Unable to parse content."); + err = ESP_FAIL; + + } else { + // navigate to the first child of the config structure + char* cmd = cJSON_GetStringValue(item); + if (!console_push(cmd, strlen(cmd) + 1)) { + httpd_resp_send_err( + req, HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to push command for execution"); + } else { + httpd_resp_send(req, (const char*)success, strlen(success)); + } + } + + ESP_LOGD_LOC(TAG, "done serving [%s]", req->uri); return err; } -esp_err_t resource_filehandler(httpd_req_t *req){ - char filepath[FILE_PATH_MAX]; - ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - - const char *filename = get_path_from_uri(filepath, req->uri, sizeof(filepath)); - if (!filename) { - ESP_LOGE_LOC(TAG, "Filename is too long"); - /* Respond with 500 Internal Server Error */ - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long"); - return ESP_FAIL; - } - - /* If name has trailing '/', respond with directory contents */ - if (filename[strlen(filename) - 1] == '/') { - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Browsing files forbidden."); - return ESP_FAIL; - } - - if(strlen(filename) !=0 && IS_FILE_EXT(filename, ".map")){ - return httpd_resp_sendstr(req, ""); - } - int idx=-1; - if((idx=resource_get_index(filename))>=0){ - set_content_type_from_file(req, filename); - if(strstr(resource_lookups[idx], ".gz")) { - httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); - } - const size_t file_size = (resource_map_end[idx] - resource_map_start[idx]); - httpd_resp_send(req, (const char *)resource_map_start[idx], file_size); - } - else { - ESP_LOGE_LOC(TAG, "Unknown resource [%s] from path [%s] ", filename,filepath); - /* Respond with 404 Not Found */ - httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist"); - return ESP_FAIL; - } - ESP_LOGD_LOC(TAG, "Resource sending complete"); - return ESP_OK; - -} -esp_err_t ap_scan_handler(httpd_req_t *req){ - const char empty[] = "{}"; - ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; - } - network_async_scan(); - esp_err_t err = set_content_type_from_req(req); - if(err == ESP_OK){ - httpd_resp_send(req, (const char *)empty, HTTPD_RESP_USE_STRLEN); - } - return err; -} - -esp_err_t console_cmd_get_handler(httpd_req_t *req){ +esp_err_t config_get_handler(httpd_req_t* req) { ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; } - /* if we can get the mutex, write the last version of the AP list */ - esp_err_t err = set_content_type_from_req(req); - cJSON * cmdlist = get_cmd_list(); - char * json_buffer = cJSON_Print(cmdlist); - if(json_buffer){ - httpd_resp_send(req, (const char *)json_buffer, HTTPD_RESP_USE_STRLEN); - free(json_buffer); - } - else{ - ESP_LOGD_LOC(TAG, "Error retrieving command json string. "); - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to format command"); - } - cJSON_Delete(cmdlist); - ESP_LOGD_LOC(TAG, "done serving [%s]", req->uri); - return err; + esp_err_t err = ESP_OK; + +// err= set_content_type_from_req(req); +// if(err == ESP_OK){ +// char * json = config_alloc_get_json(false); +// if(json==NULL){ +// ESP_LOGD_LOC(TAG, "Error retrieving config json string. "); +// httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Error retrieving configuration +// object"); err=ESP_FAIL; +// } +// else { +// ESP_LOGD_LOC(TAG, "config json : %s",json ); +// cJSON * gplist=get_gpio_list(false); +// char * gpliststr=cJSON_PrintUnformatted(gplist); +// httpd_resp_sendstr_chunk(req,"{ \"gpio\":"); +// httpd_resp_sendstr_chunk(req,gpliststr); +// httpd_resp_sendstr_chunk(req,", \"config\":"); +// httpd_resp_sendstr_chunk(req, (const char *)json); +// httpd_resp_sendstr_chunk(req,"}"); +// httpd_resp_sendstr_chunk(req,NULL); +// free(gpliststr); +// free(json); +// } +// } +// TODO: Add support for the commented code + return err; } -esp_err_t console_cmd_post_handler(httpd_req_t *req){ - char success[]="{\"Result\" : \"Success\" }"; - ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - //bool bOTA=false; - //char * otaURL=NULL; - esp_err_t err = post_handler_buff_receive(req); - if(err!=ESP_OK){ - return err; - } - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; - } - err = set_content_type_from_req(req); - if(err != ESP_OK){ - return err; - } - - char *command= ((rest_server_context_t *)(req->user_ctx))->scratch; - - cJSON *root = cJSON_Parse(command); - if(root == NULL){ - ESP_LOGE_LOC(TAG, "Parsing command. Received content was: %s",command); - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed command json. Unable to parse content."); - return ESP_FAIL; - } - char * root_str = cJSON_Print(root); - if(root_str!=NULL){ - ESP_LOGD(TAG, "Processing command item: \n%s", root_str); - free(root_str); - } - cJSON *item=cJSON_GetObjectItemCaseSensitive(root, "command"); - if(!item){ - ESP_LOGE_LOC(TAG, "Command not found. Received content was: %s",command); - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed command json. Unable to parse content."); - err = ESP_FAIL; - - } - else{ - // navigate to the first child of the config structure - char *cmd = cJSON_GetStringValue(item); - if(!console_push(cmd, strlen(cmd) + 1)){ - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to push command for execution"); - } - else { - httpd_resp_send(req, (const char *)success, strlen(success)); - } - } - - ESP_LOGD_LOC(TAG, "done serving [%s]", req->uri); - return err; -} -esp_err_t ap_get_handler(httpd_req_t *req){ - ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; - } - /* if we can get the mutex, write the last version of the AP list */ - esp_err_t err = set_content_type_from_req(req); - if( err == ESP_OK && network_status_lock_json_buffer(( TickType_t ) 200/portTICK_PERIOD_MS)){ - char *buff = network_status_alloc_get_ap_list_json(); - network_status_unlock_json_buffer(); - if(buff!=NULL){ - httpd_resp_send(req, (const char *)buff, HTTPD_RESP_USE_STRLEN); - free(buff); - } - else { - ESP_LOGD_LOC(TAG, "Error retrieving ap list json string. "); - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to retrieve AP list"); - } - } - else { - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "AP list unavailable"); - ESP_LOGE_LOC(TAG, "GET /ap.json failed to obtain mutex"); - } - ESP_LOGD_LOC(TAG, "done serving [%s]", req->uri); - return err; -} - -esp_err_t config_get_handler(httpd_req_t *req){ - ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; - } - esp_err_t err = set_content_type_from_req(req); - if(err == ESP_OK){ - char * json = config_alloc_get_json(false); - if(json==NULL){ - ESP_LOGD_LOC(TAG, "Error retrieving config json string. "); - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Error retrieving configuration object"); - err=ESP_FAIL; - } - else { - ESP_LOGD_LOC(TAG, "config json : %s",json ); - cJSON * gplist=get_gpio_list(false); - char * gpliststr=cJSON_PrintUnformatted(gplist); - httpd_resp_sendstr_chunk(req,"{ \"gpio\":"); - httpd_resp_sendstr_chunk(req,gpliststr); - httpd_resp_sendstr_chunk(req,", \"config\":"); - httpd_resp_sendstr_chunk(req, (const char *)json); - httpd_resp_sendstr_chunk(req,"}"); - httpd_resp_sendstr_chunk(req,NULL); - free(gpliststr); - free(json); - } - } - return err; -} -esp_err_t post_handler_buff_receive(httpd_req_t * req){ +esp_err_t post_handler_buff_receive(httpd_req_t* req) { esp_err_t err = ESP_OK; int total_len = req->content_len; int cur_len = 0; - char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch; + char* buf = ((rest_server_context_t*)(req->user_ctx))->scratch; int received = 0; if (total_len >= SCRATCH_BUFSIZE) { /* Respond with 500 Internal Server Error */ - ESP_LOGE_LOC(TAG,"Received content was too long. "); - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Content too long"); + ESP_LOGE_LOC(TAG, "Received content was too long. "); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Content too long"); err = ESP_FAIL; } while (err == ESP_OK && cur_len < total_len) { received = httpd_req_recv(req, buf + cur_len, total_len); if (received <= 0) { /* Respond with 500 Internal Server Error */ - ESP_LOGE_LOC(TAG,"Not all data was received. "); - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Not all data was received"); + ESP_LOGE_LOC(TAG, "Not all data was received. "); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Not all data was received"); err = ESP_FAIL; - } - else { - cur_len += received; + } else { + cur_len += received; } } - if(err == ESP_OK) { - buf[total_len] = '\0'; + if (err == ESP_OK) { + buf[total_len] = '\0'; } return err; } -esp_err_t config_post_handler(httpd_req_t *req){ +esp_err_t configurator_post_handler(httpd_req_t* req) { ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - bool bOTA=false; - char * otaURL=NULL; + bool bOTA = false; + char* otaURL = NULL; esp_err_t err = post_handler_buff_receive(req); - if(err!=ESP_OK){ + if (err != ESP_OK) { return err; } - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; } - err = set_content_type_from_req(req); - if(err != ESP_OK){ - return err; - } - - char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch; - cJSON *root = cJSON_Parse(buf); - if(root == NULL){ - ESP_LOGE_LOC(TAG, "Parsing config json failed. Received content was: %s",buf); - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed config json. Unable to parse content."); - return ESP_FAIL; + err = set_content_type_from_req(req); + if (err != ESP_OK) { + return err; } - char * root_str = cJSON_Print(root); - if(root_str!=NULL){ - ESP_LOGD(TAG, "Processing config item: \n%s", root_str); - free(root_str); - } - - cJSON *item=cJSON_GetObjectItemCaseSensitive(root, "config"); - if(!item){ - ESP_LOGE_LOC(TAG, "Parsing config json failed. Received content was: %s",buf); - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed config json. Unable to parse content."); - err = ESP_FAIL; - } - else{ - // navigate to the first child of the config structure - if(item->child) item=item->child; + char* buf = ((rest_server_context_t*)(req->user_ctx))->scratch; + cJSON* root = cJSON_Parse(buf); + if (root == NULL) { + ESP_LOGE_LOC(TAG, "Parsing config json failed. Received content was: %s", buf); + httpd_resp_send_err( + req, HTTPD_400_BAD_REQUEST, "Malformed config json. Unable to parse content."); + return ESP_FAIL; } - while (item && err == ESP_OK) - { - cJSON *prev_item = item; - item=item->next; - char * entry_str = cJSON_Print(prev_item); - if(entry_str!=NULL){ - ESP_LOGD_LOC(TAG, "Processing config item: \n%s", entry_str); - free(entry_str); - } + char* root_str = cJSON_Print(root); + if (root_str != NULL) { + ESP_LOGD(TAG, "Processing config item: \n%s", root_str); + free(root_str); + } - if(prev_item->string==NULL) { - ESP_LOGD_LOC(TAG,"Config value does not have a name"); - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed config json. Value does not have a name."); - err = ESP_FAIL; - } - if(err == ESP_OK){ - ESP_LOGD_LOC(TAG,"Found config value name [%s]", prev_item->string); - nvs_type_t item_type= config_get_item_type(prev_item); - if(item_type!=0){ - void * val = config_safe_alloc_get_entry_value(item_type, prev_item); - if(val!=NULL){ - if(strcmp(prev_item->string, "fwurl")==0) { - if(item_type!=NVS_TYPE_STR){ - ESP_LOGE_LOC(TAG,"Firmware url should be type %d. Found type %d instead.",NVS_TYPE_STR,item_type ); - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed config json. Wrong type for firmware URL."); - err = ESP_FAIL; - } - else { - // we're getting a request to do an OTA from that URL - ESP_LOGW_LOC(TAG, "Found OTA request!"); - otaURL=strdup_psram(val); - bOTA=true; - } - } - else { - if(config_set_value(item_type, prev_item->string , val) != ESP_OK){ - ESP_LOGE_LOC(TAG,"Unable to store value for [%s]", prev_item->string); - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Unable to store config value"); - err = ESP_FAIL; - } - else { - ESP_LOGD_LOC(TAG,"Successfully set value for [%s]",prev_item->string); - } - } - free(val); - } - else { - char messageBuffer[101]={}; - ESP_LOGE_LOC(TAG,"Value not found for [%s]", prev_item->string); - snprintf(messageBuffer,sizeof(messageBuffer),"Malformed config json. Missing value for entry %s.",prev_item->string); - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, messageBuffer); - err = ESP_FAIL; - } - } - else { - ESP_LOGE_LOC(TAG,"Unable to determine the type of config value [%s]", prev_item->string); - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed config json. Missing value for entry."); - err = ESP_FAIL; - } - } - } + cJSON* item = cJSON_GetObjectItemCaseSensitive(root, "config"); + if (!item) { + ESP_LOGE_LOC(TAG, "Parsing config json failed. Received content was: %s", buf); + httpd_resp_send_err( + req, HTTPD_400_BAD_REQUEST, "Malformed config json. Unable to parse content."); + err = ESP_FAIL; + } else { + // navigate to the first child of the config structure + if (item->child) item = item->child; + } + // while (item && err == ESP_OK) + // { + // cJSON *prev_item = item; + // item=item->next; + // char * entry_str = cJSON_Print(prev_item); + // if(entry_str!=NULL){ + // ESP_LOGD_LOC(TAG, "Processing config item: \n%s", entry_str); + // free(entry_str); + // } + + // if(prev_item->string==NULL) { + // ESP_LOGD_LOC(TAG,"Config value does not have a name"); + // httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed config json. Value does not + // have a name."); err = ESP_FAIL; + // } + // if(err == ESP_OK){ + // ESP_LOGD_LOC(TAG,"Found config value name [%s]", prev_item->string); + // nvs_type_t item_type= config_get_item_type(prev_item); + // if(item_type!=0){ + // void * val = config_safe_alloc_get_entry_value(item_type, prev_item); + // if(val!=NULL){ + // if(strcmp(prev_item->string, "fwurl")==0) { + // if(item_type!=NVS_TYPE_STR){ + // ESP_LOGE_LOC(TAG,"Firmware url should be type %d. Found type %d + // instead.",NVS_TYPE_STR,item_type ); httpd_resp_send_err(req, + // HTTPD_400_BAD_REQUEST, + // "Malformed config json. Wrong type for firmware URL."); err = ESP_FAIL; + // } + // else { + // // we're getting a request to do an OTA from that URL + // ESP_LOGW_LOC(TAG, "Found OTA request!"); + // otaURL=strdup_psram(val); + // bOTA=true; + // } + // } + // else { + // if(config_set_value(item_type, prev_item->string , val) != ESP_OK){ + // ESP_LOGE_LOC(TAG,"Unable to store value for [%s]", prev_item->string); + // httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Unable to store + // config value"); err = ESP_FAIL; + // } + // else { + // ESP_LOGD_LOC(TAG,"Successfully set value for [%s]",prev_item->string); + // } + // } + // free(val); + // } + // else { + // char messageBuffer[101]={}; + // ESP_LOGE_LOC(TAG,"Value not found for [%s]", prev_item->string); + // snprintf(messageBuffer,sizeof(messageBuffer),"Malformed config json. Missing value + // for entry %s.",prev_item->string); httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, + // messageBuffer); err = ESP_FAIL; + // } + // } + // else { + // ESP_LOGE_LOC(TAG,"Unable to determine the type of config value [%s]", + // prev_item->string); httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed config + // json. Missing value for entry."); err = ESP_FAIL; + // } + // } + // } - if(err==ESP_OK){ - httpd_resp_sendstr(req, "{ \"result\" : \"OK\" }"); - messaging_post_message(MESSAGING_INFO,MESSAGING_CLASS_SYSTEM,"Save Success"); - } cJSON_Delete(root); - if(bOTA) { + if (bOTA) { - if(is_recovery_running){ - ESP_LOGW_LOC(TAG, "Starting process OTA for url %s",otaURL); - } - else { - ESP_LOGW_LOC(TAG, "Restarting system to process OTA for url %s",otaURL); - } + if (is_recovery_running) { + ESP_LOGW_LOC(TAG, "Starting process OTA for url %s", otaURL); + } else { + ESP_LOGW_LOC(TAG, "Restarting system to process OTA for url %s", otaURL); + } - network_reboot_ota(otaURL); - free(otaURL); - } + network_reboot_ota(otaURL); + free(otaURL); + } return err; - } -esp_err_t connect_post_handler(httpd_req_t *req){ +esp_err_t configurator_get_handler(httpd_req_t* req) { ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - char success[]="{}"; - char * ssid=NULL; - char * password=NULL; - char * host_name=NULL; - - esp_err_t err = post_handler_buff_receive(req); - if(err!=ESP_OK){ - return err; - } - err = set_content_type_from_req(req); - if(err != ESP_OK){ - return err; - } - - char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch; - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; } - cJSON *root = cJSON_Parse(buf); + esp_err_t err = ESP_OK; + void* config = NULL; + size_t datalen; - if(root==NULL){ - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "JSON parsing error."); - return ESP_FAIL; - } + err = set_content_type_from_req(req); - cJSON * ssid_object = cJSON_GetObjectItem(root, "ssid"); - if(ssid_object !=NULL){ - ssid = strdup_psram(ssid_object->valuestring); - } - cJSON * password_object = cJSON_GetObjectItem(root, "pwd"); - if(password_object !=NULL){ - password = strdup_psram(password_object->valuestring); - } - cJSON * host_name_object = cJSON_GetObjectItem(root, "host_name"); - if(host_name_object !=NULL){ - host_name = strdup_psram(host_name_object->valuestring); - } - cJSON_Delete(root); + if (err == ESP_OK) { + config = configurator_alloc_get_config(&datalen); + if (!config) { + ESP_LOGE_LOC(TAG, "Unable to serialize configuration"); + httpd_resp_send_err( + req, HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to serialize configuration"); + err = ESP_FAIL; + } else { + httpd_resp_send(req, (const char*)config, datalen); + free(config); + } + } - if(host_name!=NULL){ - if(config_set_value(NVS_TYPE_STR, "host_name", host_name) != ESP_OK){ - ESP_LOGW_LOC(TAG, "Unable to save host name configuration"); - } - } - - if(ssid !=NULL && strlen(ssid) <= MAX_SSID_SIZE && strlen(password) <= MAX_PASSWORD_SIZE ){ - network_async_connect(ssid, password); - httpd_resp_send(req, (const char *)success, strlen(success)); - } - else { - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed json. Missing or invalid ssid/password."); - err = ESP_FAIL; - } - FREE_AND_NULL(ssid); - FREE_AND_NULL(password); - FREE_AND_NULL(host_name); - return err; +// if(err == ESP_OK){ +// char * json = config_alloc_get_json(false); +// if(json==NULL){ +// ESP_LOGD_LOC(TAG, "Error retrieving config json string. "); +// httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Error retrieving configuration +// object"); err=ESP_FAIL; +// } +// else { +// ESP_LOGD_LOC(TAG, "config json : %s",json ); +// cJSON * gplist=get_gpio_list(false); +// char * gpliststr=cJSON_PrintUnformatted(gplist); +// httpd_resp_sendstr_chunk(req,"{ \"gpio\":"); +// httpd_resp_sendstr_chunk(req,gpliststr); +// httpd_resp_sendstr_chunk(req,", \"config\":"); +// httpd_resp_sendstr_chunk(req, (const char *)json); +// httpd_resp_sendstr_chunk(req,"}"); +// httpd_resp_sendstr_chunk(req,NULL); +// free(gpliststr); +// free(json); +// } +// } +// TODO: Add support for the commented code + return err; } -esp_err_t connect_delete_handler(httpd_req_t *req){ - char success[]="{}"; + +esp_err_t config_post_handler(httpd_req_t* req) { ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; + bool bOTA = false; + char* otaURL = NULL; + esp_err_t err = post_handler_buff_receive(req); + if (err != ESP_OK) { + return err; } - esp_err_t err = set_content_type_from_req(req); - if(err != ESP_OK){ - return err; - } - httpd_resp_send(req, (const char *)success, strlen(success)); - network_async_delete(); + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; + } + err = set_content_type_from_req(req); + if (err != ESP_OK) { + return err; + } + + char* buf = ((rest_server_context_t*)(req->user_ctx))->scratch; + cJSON* root = cJSON_Parse(buf); + if (root == NULL) { + ESP_LOGE_LOC(TAG, "Parsing config json failed. Received content was: %s", buf); + httpd_resp_send_err( + req, HTTPD_400_BAD_REQUEST, "Malformed config json. Unable to parse content."); + return ESP_FAIL; + } + + char* root_str = cJSON_Print(root); + if (root_str != NULL) { + ESP_LOGD(TAG, "Processing config item: \n%s", root_str); + free(root_str); + } + + cJSON* item = cJSON_GetObjectItemCaseSensitive(root, "config"); + if (!item) { + ESP_LOGE_LOC(TAG, "Parsing config json failed. Received content was: %s", buf); + httpd_resp_send_err( + req, HTTPD_400_BAD_REQUEST, "Malformed config json. Unable to parse content."); + err = ESP_FAIL; + } else { + // navigate to the first child of the config structure + if (item->child) item = item->child; + } + + // while (item && err == ESP_OK) + // { + // cJSON *prev_item = item; + // item=item->next; + // char * entry_str = cJSON_Print(prev_item); + // if(entry_str!=NULL){ + // ESP_LOGD_LOC(TAG, "Processing config item: \n%s", entry_str); + // free(entry_str); + // } + + // if(prev_item->string==NULL) { + // ESP_LOGD_LOC(TAG,"Config value does not have a name"); + // httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed config json. Value does not + // have a name."); err = ESP_FAIL; + // } + // if(err == ESP_OK){ + // ESP_LOGD_LOC(TAG,"Found config value name [%s]", prev_item->string); + // nvs_type_t item_type= config_get_item_type(prev_item); + // if(item_type!=0){ + // void * val = config_safe_alloc_get_entry_value(item_type, prev_item); + // if(val!=NULL){ + // if(strcmp(prev_item->string, "fwurl")==0) { + // if(item_type!=NVS_TYPE_STR){ + // ESP_LOGE_LOC(TAG,"Firmware url should be type %d. Found type %d + // instead.",NVS_TYPE_STR,item_type ); httpd_resp_send_err(req, + // HTTPD_400_BAD_REQUEST, + // "Malformed config json. Wrong type for firmware URL."); err = ESP_FAIL; + // } + // else { + // // we're getting a request to do an OTA from that URL + // ESP_LOGW_LOC(TAG, "Found OTA request!"); + // otaURL=strdup_psram(val); + // bOTA=true; + // } + // } + // else { + // if(config_set_value(item_type, prev_item->string , val) != ESP_OK){ + // ESP_LOGE_LOC(TAG,"Unable to store value for [%s]", prev_item->string); + // httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Unable to store + // config value"); err = ESP_FAIL; + // } + // else { + // ESP_LOGD_LOC(TAG,"Successfully set value for [%s]",prev_item->string); + // } + // } + // free(val); + // } + // else { + // char messageBuffer[101]={}; + // ESP_LOGE_LOC(TAG,"Value not found for [%s]", prev_item->string); + // snprintf(messageBuffer,sizeof(messageBuffer),"Malformed config json. Missing value + // for entry %s.",prev_item->string); httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, + // messageBuffer); err = ESP_FAIL; + // } + // } + // else { + // ESP_LOGE_LOC(TAG,"Unable to determine the type of config value [%s]", + // prev_item->string); httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Malformed config + // json. Missing value for entry."); err = ESP_FAIL; + // } + // } + // } +// TODO: Add support for the commented code + + if (err == ESP_OK) { + httpd_resp_sendstr(req, "{ \"result\" : \"OK\" }"); + messaging_post_message(MESSAGING_INFO, MESSAGING_CLASS_SYSTEM, "Save Success"); + } + cJSON_Delete(root); + if (bOTA) { + + if (is_recovery_running) { + ESP_LOGW_LOC(TAG, "Starting process OTA for url %s", otaURL); + } else { + ESP_LOGW_LOC(TAG, "Restarting system to process OTA for url %s", otaURL); + } + + network_reboot_ota(otaURL); + free(otaURL); + } + return err; +} +esp_err_t connect_post_handler(httpd_req_t* req) { + ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); + char success[] = "{}"; + char* ssid = NULL; + char* password = NULL; + char* host_name = NULL; + + esp_err_t err = post_handler_buff_receive(req); + if (err != ESP_OK) { + return err; + } + err = set_content_type_from_req(req); + if (err != ESP_OK) { + return err; + } + + char* buf = ((rest_server_context_t*)(req->user_ctx))->scratch; + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; + } + cJSON* root = cJSON_Parse(buf); + + if (root == NULL) { + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "JSON parsing error."); + return ESP_FAIL; + } + + cJSON* ssid_object = cJSON_GetObjectItem(root, "ssid"); + if (ssid_object != NULL) { + ssid = strdup_psram(ssid_object->valuestring); + } + cJSON* password_object = cJSON_GetObjectItem(root, "pwd"); + if (password_object != NULL) { + password = strdup_psram(password_object->valuestring); + } + cJSON* host_name_object = cJSON_GetObjectItem(root, "host_name"); + if (host_name_object != NULL) { + host_name = strdup_psram(host_name_object->valuestring); + } + cJSON_Delete(root); + +// if(host_name!=NULL){ +// if(config_set_value(NVS_TYPE_STR, "host_name", host_name) != ESP_OK){ +// ESP_LOGW_LOC(TAG, "Unable to save host name configuration"); +// } +// } +// TODO: Add support for the commented code + + if (ssid != NULL && strlen(ssid) <= MAX_SSID_SIZE && strlen(password) <= MAX_PASSWORD_SIZE) { + network_async_connect(ssid, password); + httpd_resp_send(req, (const char*)success, strlen(success)); + } else { + httpd_resp_send_err( + req, HTTPD_400_BAD_REQUEST, "Malformed json. Missing or invalid ssid/password."); + err = ESP_FAIL; + } +// FREE_AND_NULL(ssid); +// FREE_AND_NULL(password); +// FREE_AND_NULL(host_name); +// TODO: Add support for the commented code + return err; +} +esp_err_t connect_delete_handler(httpd_req_t* req) { + char success[] = "{}"; + ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; + } + esp_err_t err = set_content_type_from_req(req); + if (err != ESP_OK) { + return err; + } + httpd_resp_send(req, (const char*)success, strlen(success)); + network_async_delete(); return ESP_OK; } -esp_err_t reboot_ota_post_handler(httpd_req_t *req){ - char success[]="{}"; - ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; +esp_err_t reboot_ota_post_handler(httpd_req_t* req) { + char success[] = "{}"; + ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; } esp_err_t err = set_content_type_from_req(req); - if(err != ESP_OK){ - return err; - } + if (err != ESP_OK) { + return err; + } - httpd_resp_send(req, (const char *)success, strlen(success)); - network_async_reboot(OTA); + httpd_resp_send(req, (const char*)success, strlen(success)); + network_async_reboot(OTA); return ESP_OK; } -esp_err_t reboot_post_handler(httpd_req_t *req){ +esp_err_t reboot_post_handler(httpd_req_t* req) { ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - char success[]="{}"; - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; + char success[] = "{}"; + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; } esp_err_t err = set_content_type_from_req(req); - if(err != ESP_OK){ - return err; - } - httpd_resp_send(req, (const char *)success, strlen(success)); - network_async_reboot(RESTART); - return ESP_OK; + if (err != ESP_OK) { + return err; + } + httpd_resp_send(req, (const char*)success, strlen(success)); + network_async_reboot(RESTART); + return ESP_OK; } -esp_err_t recovery_post_handler(httpd_req_t *req){ +esp_err_t recovery_post_handler(httpd_req_t* req) { ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - char success[]="{}"; - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; + char success[] = "{}"; + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; } esp_err_t err = set_content_type_from_req(req); - if(err != ESP_OK){ - return err; - } - httpd_resp_send(req, (const char *)success, strlen(success)); - network_async_reboot(RECOVERY); - return ESP_OK; + if (err != ESP_OK) { + return err; + } + httpd_resp_send(req, (const char*)success, strlen(success)); + network_async_reboot(RECOVERY); + return ESP_OK; } +esp_err_t flash_post_handler(httpd_req_t* req) { + esp_err_t err = ESP_OK; + if (is_recovery_running) { + ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); + char success[] = "File uploaded. Flashing started."; + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; + } + err = httpd_resp_set_type(req, HTTPD_TYPE_TEXT); + if (err != ESP_OK) { + return err; + } + char* binary_buffer = malloc_init_external(req->content_len); + if (binary_buffer == NULL) { + ESP_LOGE(TAG, "File too large : %d bytes", req->content_len); + /* Respond with 400 Bad Request */ + httpd_resp_send_err( + req, HTTPD_400_BAD_REQUEST, "Binary file too large. Unable to allocate memory!"); + return ESP_FAIL; + } + ESP_LOGI(TAG, "Receiving ota binary file"); + /* Retrieve the pointer to scratch buffer for temporary storage */ + char* buf = ((rest_server_context_t*)(req->user_ctx))->scratch; -esp_err_t flash_post_handler(httpd_req_t *req){ - esp_err_t err =ESP_OK; - if(is_recovery_running){ - ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - char success[]="File uploaded. Flashing started."; - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; - } - err = httpd_resp_set_type(req, HTTPD_TYPE_TEXT); - if(err != ESP_OK){ - return err; - } - char * binary_buffer = malloc_init_external(req->content_len); - if(binary_buffer == NULL){ - ESP_LOGE(TAG, "File too large : %d bytes", req->content_len); - /* Respond with 400 Bad Request */ - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, - "Binary file too large. Unable to allocate memory!"); - return ESP_FAIL; - } - ESP_LOGI(TAG, "Receiving ota binary file"); - /* Retrieve the pointer to scratch buffer for temporary storage */ - char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch; + char* head = binary_buffer; + int received; - char *head=binary_buffer; - int received; + /* Content length of the request gives + * the size of the file being uploaded */ + int remaining = req->content_len; - /* Content length of the request gives - * the size of the file being uploaded */ - int remaining = req->content_len; + while (remaining > 0) { - while (remaining > 0) { + ESP_LOGI(TAG, "Remaining size : %d", remaining); + /* Receive the file part by part into a buffer */ + if ((received = httpd_req_recv(req, buf, MIN(remaining, SCRATCH_BUFSIZE))) <= 0) { + if (received == HTTPD_SOCK_ERR_TIMEOUT) { + /* Retry if timeout occurred */ + continue; + } +// FREE_RESET(binary_buffer); +// TODO: Add support for the commented code + ESP_LOGE(TAG, "File reception failed!"); + /* Respond with 500 Internal Server Error */ + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to receive file"); + err = ESP_FAIL; + goto bail_out; + } - ESP_LOGI(TAG, "Remaining size : %d", remaining); - /* Receive the file part by part into a buffer */ - if ((received = httpd_req_recv(req, buf, MIN(remaining, SCRATCH_BUFSIZE))) <= 0) { - if (received == HTTPD_SOCK_ERR_TIMEOUT) { - /* Retry if timeout occurred */ - continue; - } - FREE_RESET(binary_buffer); - ESP_LOGE(TAG, "File reception failed!"); - /* Respond with 500 Internal Server Error */ - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to receive file"); - err = ESP_FAIL; - goto bail_out; - } + /* Write buffer content to file on storage */ + if (received) { + memcpy(head, buf, received); + head += received; + } - /* Write buffer content to file on storage */ - if (received ) { - memcpy(head,buf,received ); - head+=received; - } + /* Keep track of remaining size of + * the file left to be uploaded */ + remaining -= received; + } - /* Keep track of remaining size of - * the file left to be uploaded */ - remaining -= received; - } + /* Close file upon upload completion */ + ESP_LOGI(TAG, "File reception complete. Invoking OTA process."); + err = start_ota(NULL, binary_buffer, req->content_len); + if (err != ESP_OK) { + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "OTA processing failed"); + goto bail_out; + } - /* Close file upon upload completion */ - ESP_LOGI(TAG, "File reception complete. Invoking OTA process."); - err = start_ota(NULL, binary_buffer, req->content_len); - if(err!=ESP_OK){ - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "OTA processing failed"); - goto bail_out; - } - - //todo: handle this in ajax. For now, just send the root page - httpd_resp_send(req, (const char *)success, strlen(success)); - } + // todo: handle this in ajax. For now, just send the root page + httpd_resp_send(req, (const char*)success, strlen(success)); + } bail_out: - return err; + return err; } -char * get_ap_ip_address(){ - static char ap_ip_address[IP4ADDR_STRLEN_MAX]={}; +char* get_ap_ip_address() { + static char ap_ip_address[IP4ADDR_STRLEN_MAX] = {}; - tcpip_adapter_ip_info_t ip_info; - esp_err_t err=ESP_OK; - memset(ap_ip_address, 0x00, sizeof(ap_ip_address)); + tcpip_adapter_ip_info_t ip_info; + esp_err_t err = ESP_OK; + memset(ap_ip_address, 0x00, sizeof(ap_ip_address)); - ESP_LOGD_LOC(TAG, "checking if soft AP is enabled"); - if(tcpip_adapter_is_netif_up(TCPIP_ADAPTER_IF_AP)){ - ESP_LOGD_LOC(TAG, "Soft AP is enabled. getting ip info"); - // Access point is up and running. Get the current IP address - err = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_info); - if(err != ESP_OK){ - ESP_LOGE_LOC(TAG, "Unable to get local AP ip address. Error: %s",esp_err_to_name(err)); - } - else { - ESP_LOGV_LOC(TAG, "Converting soft ip address to string"); - ip4addr_ntoa_r(&ip_info.ip, ap_ip_address, IP4ADDR_STRLEN_MAX); - ESP_LOGD_LOC(TAG,"TCPIP_ADAPTER_IF_AP is up and has ip address %s ", ap_ip_address); - } - } - else{ - ESP_LOGD_LOC(TAG,"AP Is not enabled. Returning blank string"); - } - return ap_ip_address; + ESP_LOGD_LOC(TAG, "checking if soft AP is enabled"); + if (tcpip_adapter_is_netif_up(TCPIP_ADAPTER_IF_AP)) { + ESP_LOGD_LOC(TAG, "Soft AP is enabled. getting ip info"); + // Access point is up and running. Get the current IP address + err = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_info); + if (err != ESP_OK) { + ESP_LOGE_LOC(TAG, "Unable to get local AP ip address. Error: %s", esp_err_to_name(err)); + } else { + ESP_LOGV_LOC(TAG, "Converting soft ip address to string"); + ip4addr_ntoa_r(&ip_info.ip, ap_ip_address, IP4ADDR_STRLEN_MAX); + ESP_LOGD_LOC(TAG, "TCPIP_ADAPTER_IF_AP is up and has ip address %s ", ap_ip_address); + } + } else { + ESP_LOGD_LOC(TAG, "AP Is not enabled. Returning blank string"); + } + return ap_ip_address; } -esp_err_t process_redirect(httpd_req_t *req, const char * status){ - const char location_prefix[] = "http://"; - char * ap_ip_address=get_ap_ip_address(); - char * remote_ip=NULL; - in_port_t port=0; - char *redirect_url = NULL; +esp_err_t process_redirect(httpd_req_t* req, const char* status) { + const char location_prefix[] = "http://"; + char* ap_ip_address = get_ap_ip_address(); + char* remote_ip = NULL; + in_port_t port = 0; + char* redirect_url = NULL; - ESP_LOGD_LOC(TAG, "Getting remote socket address"); - remote_ip = http_alloc_get_socket_address(req,0, &port); + ESP_LOGD_LOC(TAG, "Getting remote socket address"); + remote_ip = http_alloc_get_socket_address(req, 0, &port); - size_t buf_size = strlen(redirect_payload1) +strlen(redirect_payload2) + strlen(redirect_payload3) +2*(strlen(location_prefix)+strlen(ap_ip_address))+1; - char * redirect=malloc_init_external(buf_size); + size_t buf_size = strlen(redirect_payload1) + strlen(redirect_payload2) + + strlen(redirect_payload3) + + 2 * (strlen(location_prefix) + strlen(ap_ip_address)) + 1; + char* redirect = malloc_init_external(buf_size); - if(strcasestr(status,"302")){ - size_t url_buf_size = strlen(location_prefix) + strlen(ap_ip_address)+1; - redirect_url = malloc_init_external(url_buf_size); - memset(redirect_url,0x00,url_buf_size); - snprintf(redirect_url, buf_size,"%s%s/",location_prefix, ap_ip_address); - ESP_LOGW_LOC(TAG, "Redirecting host [%s] to %s (from uri %s)",remote_ip, redirect_url,req->uri); - httpd_resp_set_hdr(req,"Location",redirect_url); - snprintf(redirect, buf_size,"OK"); - } - else { + if (strcasestr(status, "302")) { + size_t url_buf_size = strlen(location_prefix) + strlen(ap_ip_address) + 1; + redirect_url = malloc_init_external(url_buf_size); + memset(redirect_url, 0x00, url_buf_size); + snprintf(redirect_url, buf_size, "%s%s/", location_prefix, ap_ip_address); + ESP_LOGW_LOC( + TAG, "Redirecting host [%s] to %s (from uri %s)", remote_ip, redirect_url, req->uri); + httpd_resp_set_hdr(req, "Location", redirect_url); + snprintf(redirect, buf_size, "OK"); + } else { - snprintf(redirect, buf_size,"%s%s%s%s%s%s%s",redirect_payload1, location_prefix, ap_ip_address,redirect_payload2, location_prefix, ap_ip_address,redirect_payload3); - ESP_LOGW_LOC(TAG, "Responding to host [%s] (from uri %s) with redirect html page %s",remote_ip, req->uri,redirect); - } + snprintf(redirect, buf_size, "%s%s%s%s%s%s%s", redirect_payload1, location_prefix, + ap_ip_address, redirect_payload2, location_prefix, ap_ip_address, redirect_payload3); + ESP_LOGW_LOC(TAG, "Responding to host [%s] (from uri %s) with redirect html page %s", + remote_ip, req->uri, redirect); + } - httpd_resp_set_type(req, HTTPD_TYPE_TEXT); - httpd_resp_set_hdr(req,"Cache-Control","no-cache"); - httpd_resp_set_status(req, status); - httpd_resp_send(req, redirect, HTTPD_RESP_USE_STRLEN); - FREE_AND_NULL(redirect); - FREE_AND_NULL(redirect_url); - FREE_AND_NULL(remote_ip); + httpd_resp_set_type(req, HTTPD_TYPE_TEXT); + httpd_resp_set_hdr(req, "Cache-Control", "no-cache"); + httpd_resp_set_status(req, status); + httpd_resp_send(req, redirect, HTTPD_RESP_USE_STRLEN); + FREE_AND_NULL(redirect); + FREE_AND_NULL(redirect_url); + FREE_AND_NULL(remote_ip); - return ESP_OK; + return ESP_OK; } -esp_err_t redirect_200_ev_handler(httpd_req_t *req){ - ESP_LOGD_LOC(TAG,"Processing known redirect url %s",req->uri); - process_redirect(req,"200 OK"); - return ESP_OK; +esp_err_t redirect_200_ev_handler(httpd_req_t* req) { + ESP_LOGD_LOC(TAG, "Processing known redirect url %s", req->uri); + process_redirect(req, "200 OK"); + return ESP_OK; } -esp_err_t redirect_processor(httpd_req_t *req, httpd_err_code_t error){ - esp_err_t err=ESP_OK; - const char * host_name=NULL; - const char * ap_host_name=NULL; - char * user_agent=NULL; - char * remote_ip=NULL; - char * sta_ip_address=NULL; - char * ap_ip_address=get_ap_ip_address(); - char * socket_local_address=NULL; - bool request_contains_hostname = false; - bool request_contains_ap_ip_address = false; - bool request_is_sta_ip_address = false; - bool connected_to_ap_ip_interface = false; - bool connected_to_sta_ip_interface = false; - bool useragentiscaptivenetwork = false; +esp_err_t redirect_processor(httpd_req_t* req, httpd_err_code_t error) { + esp_err_t err = ESP_OK; + const char* host_name = NULL; + const char* ap_host_name = NULL; + char* user_agent = NULL; + char* remote_ip = NULL; + char* sta_ip_address = NULL; + char* ap_ip_address = get_ap_ip_address(); + char* socket_local_address = NULL; + bool request_contains_hostname = false; + bool request_contains_ap_ip_address = false; + bool request_is_sta_ip_address = false; + bool connected_to_ap_ip_interface = false; + bool connected_to_sta_ip_interface = false; + bool useragentiscaptivenetwork = false; - in_port_t port=0; - ESP_LOGV_LOC(TAG, "Getting remote socket address"); - remote_ip = http_alloc_get_socket_address(req,0, &port); + in_port_t port = 0; + ESP_LOGV_LOC(TAG, "Getting remote socket address"); + remote_ip = http_alloc_get_socket_address(req, 0, &port); - ESP_LOGW_LOC(TAG, "%s requested invalid URL: [%s]",remote_ip, req->uri); - if(network_status_lock_sta_ip_string(portMAX_DELAY)){ - sta_ip_address = strdup_psram(network_status_get_sta_ip_string()); - network_status_unlock_sta_ip_string(); - } - else { - ESP_LOGE(TAG,"Unable to obtain local IP address from WiFi Manager."); - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , NULL); - } - - - ESP_LOGV_LOC(TAG, "Getting host name from request"); - char *req_host = alloc_get_http_header(req, "Host"); - - user_agent = alloc_get_http_header(req,"User-Agent"); - if((useragentiscaptivenetwork = (user_agent!=NULL && strcasestr(user_agent,"CaptiveNetworkSupport"))==true)){ - ESP_LOGW_LOC(TAG,"Found user agent that supports captive networks! [%s]",user_agent); + ESP_LOGW_LOC(TAG, "%s requested invalid URL: [%s]", remote_ip, req->uri); + if (network_status_lock_structure(portMAX_DELAY)) { + sta_ip_address = strdup_psram(status.net.ip.ip); + network_status_unlock_structure(); + } else { + ESP_LOGE(TAG, "Unable to obtain local IP address from WiFi Manager."); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, NULL); } - esp_err_t hn_err = ESP_OK; - ESP_LOGV_LOC(TAG, "Getting adapter host name"); - if((hn_err = tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &host_name )) !=ESP_OK) { - ESP_LOGE_LOC(TAG, "Unable to get host name. Error: %s",esp_err_to_name(hn_err)); - err=err==ESP_OK?hn_err:err; - } - else { - ESP_LOGV_LOC(TAG, "Host name is %s",host_name); - } + ESP_LOGV_LOC(TAG, "Getting host name from request"); + char* req_host = alloc_get_http_header(req, "Host"); - - in_port_t loc_port=0; - ESP_LOGV_LOC(TAG, "Getting local socket address"); - socket_local_address= http_alloc_get_socket_address(req,1, &loc_port); - - - - ESP_LOGD_LOC(TAG, "Peer IP: %s [port %u], System AP IP address: %s, System host: %s. Requested Host: [%s], uri [%s]",STR_OR_NA(remote_ip), port, STR_OR_NA(ap_ip_address), STR_OR_NA(host_name), STR_OR_NA(req_host), req->uri); - /* captive portal functionality: redirect to access point IP for HOST that are not the access point IP OR the STA IP */ - /* determine if Host is from the STA IP address */ - - if((request_contains_hostname = (host_name!=NULL) && (req_host!=NULL) && strcasestr(req_host,host_name)) == true){ - ESP_LOGD_LOC(TAG,"http request host = system host name %s", req_host); - } - else if((request_contains_hostname = (ap_host_name!=NULL) && (req_host!=NULL) && strcasestr(req_host,ap_host_name)) == true){ - ESP_LOGD_LOC(TAG,"http request host = AP system host name %s", req_host); - } - if((request_contains_ap_ip_address = (ap_ip_address!=NULL) && (req_host!=NULL) && strcasestr(req_host,ap_ip_address))== true){ - ESP_LOGD_LOC(TAG,"http request host is access point ip address %s", req_host); - } - if((connected_to_ap_ip_interface = (ap_ip_address!=NULL) && (socket_local_address!=NULL) && strcasestr(socket_local_address,ap_ip_address))==true){ - ESP_LOGD_LOC(TAG,"http request is connected to access point interface IP %s", ap_ip_address); - } - if((request_is_sta_ip_address = (sta_ip_address!=NULL) && (req_host!=NULL) && strcasestr(req_host,sta_ip_address))==true){ - ESP_LOGD_LOC(TAG,"http request host is WiFi client ip address %s", req_host); - } - if((connected_to_sta_ip_interface = (sta_ip_address!=NULL) && (socket_local_address!=NULL) && strcasestr(sta_ip_address,socket_local_address))==true){ - ESP_LOGD_LOC(TAG,"http request is connected to WiFi client ip address %s", sta_ip_address); + user_agent = alloc_get_http_header(req, "User-Agent"); + if ((useragentiscaptivenetwork = + (user_agent != NULL && strcasestr(user_agent, "CaptiveNetworkSupport")) == true)) { + ESP_LOGW_LOC(TAG, "Found user agent that supports captive networks! [%s]", user_agent); } - if((error == 0) || (error == HTTPD_404_NOT_FOUND && connected_to_ap_ip_interface && !(request_contains_ap_ip_address || request_contains_hostname ))) { - process_redirect(req,"302 Found"); + esp_err_t hn_err = ESP_OK; + ESP_LOGV_LOC(TAG, "Getting adapter host name"); + if ((hn_err = tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &host_name)) != ESP_OK) { + ESP_LOGE_LOC(TAG, "Unable to get host name. Error: %s", esp_err_to_name(hn_err)); + err = err == ESP_OK ? hn_err : err; + } else { + ESP_LOGV_LOC(TAG, "Host name is %s", host_name); + } - } - else { - ESP_LOGD_LOC(TAG,"URL not found, and not processing captive portal so throw regular 404 error"); - httpd_resp_send_err(req, error, NULL); - } + in_port_t loc_port = 0; + ESP_LOGV_LOC(TAG, "Getting local socket address"); + socket_local_address = http_alloc_get_socket_address(req, 1, &loc_port); - FREE_AND_NULL(socket_local_address); + ESP_LOGD_LOC(TAG, + "Peer IP: %s [port %u], System AP IP address: %s, System host: %s. Requested Host: [%s], " + "uri [%s]", + STR_OR_NA(remote_ip), port, STR_OR_NA(ap_ip_address), STR_OR_NA(host_name), + STR_OR_NA(req_host), req->uri); + /* captive portal functionality: redirect to access point IP for HOST that are not the access + * point IP OR the STA IP */ + /* determine if Host is from the STA IP address */ - FREE_AND_NULL(req_host); - FREE_AND_NULL(user_agent); + if ((request_contains_hostname = (host_name != NULL) && (req_host != NULL) && + strcasestr(req_host, host_name)) == true) { + ESP_LOGD_LOC(TAG, "http request host = system host name %s", req_host); + } else if ((request_contains_hostname = (ap_host_name != NULL) && (req_host != NULL) && + strcasestr(req_host, ap_host_name)) == true) { + ESP_LOGD_LOC(TAG, "http request host = AP system host name %s", req_host); + } + if ((request_contains_ap_ip_address = (ap_ip_address != NULL) && (req_host != NULL) && + strcasestr(req_host, ap_ip_address)) == true) { + ESP_LOGD_LOC(TAG, "http request host is access point ip address %s", req_host); + } + if ((connected_to_ap_ip_interface = (ap_ip_address != NULL) && (socket_local_address != NULL) && + strcasestr(socket_local_address, ap_ip_address)) == true) { + ESP_LOGD_LOC( + TAG, "http request is connected to access point interface IP %s", ap_ip_address); + } + if ((request_is_sta_ip_address = (sta_ip_address != NULL) && (req_host != NULL) && + strcasestr(req_host, sta_ip_address)) == true) { + ESP_LOGD_LOC(TAG, "http request host is WiFi client ip address %s", req_host); + } + if ((connected_to_sta_ip_interface = + (sta_ip_address != NULL) && (socket_local_address != NULL) && + strcasestr(sta_ip_address, socket_local_address)) == true) { + ESP_LOGD_LOC(TAG, "http request is connected to WiFi client ip address %s", sta_ip_address); + } + + if ((error == 0) || (error == HTTPD_404_NOT_FOUND && connected_to_ap_ip_interface && + !(request_contains_ap_ip_address || request_contains_hostname))) { + process_redirect(req, "302 Found"); + + } else { + ESP_LOGD_LOC( + TAG, "URL not found, and not processing captive portal so throw regular 404 error"); + httpd_resp_send_err(req, error, NULL); + } + + FREE_AND_NULL(socket_local_address); + + FREE_AND_NULL(req_host); + FREE_AND_NULL(user_agent); FREE_AND_NULL(sta_ip_address); - FREE_AND_NULL(remote_ip); - return err; - -} -esp_err_t redirect_ev_handler(httpd_req_t *req){ - return redirect_processor(req,0); + FREE_AND_NULL(remote_ip); + return err; } +esp_err_t redirect_ev_handler(httpd_req_t* req) { return redirect_processor(req, 0); } -esp_err_t messages_get_handler(httpd_req_t *req){ +esp_err_t messages_get_handler(httpd_req_t* req) { ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; } esp_err_t err = set_content_type_from_req(req); - if(err != ESP_OK){ - return err; - } - cJSON * json_messages= messaging_retrieve_messages(messaging); - if(json_messages!=NULL){ - char * json_text= cJSON_Print(json_messages); - httpd_resp_send(req, (const char *)json_text, strlen(json_text)); - free(json_text); - cJSON_Delete(json_messages); - } - else { - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Unable to retrieve messages"); - } - return ESP_OK; -} - -esp_err_t status_get_handler(httpd_req_t *req){ - ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); - if(!is_user_authenticated(req)){ - // todo: redirect to login page - // return ESP_OK; + if (err != ESP_OK) { + return err; } - esp_err_t err = set_content_type_from_req(req); - if(err != ESP_OK){ - return err; - } - - if(network_status_lock_json_buffer(( TickType_t ) 200/portTICK_PERIOD_MS)) { - char *buff = network_status_alloc_get_ip_info_json(); - network_status_unlock_json_buffer(); - if(buff) { - httpd_resp_send(req, (const char *)buff, strlen(buff)); - free(buff); - } - else { - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Empty status object"); - } - } - else { - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Error retrieving status object"); - } - // update status for next status call - network_async_update_status(); - - return ESP_OK; + cJSON* json_messages = messaging_retrieve_messages(messaging); + if (json_messages != NULL) { + char* json_text = cJSON_Print(json_messages); + httpd_resp_send(req, (const char*)json_text, strlen(json_text)); + free(json_text); + cJSON_Delete(json_messages); + } else { + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to retrieve messages"); + } + return ESP_OK; } +esp_err_t status_get_handler(httpd_req_t* req) { + ESP_LOGD_LOC(TAG, "serving [%s]", req->uri); + if (!is_user_authenticated(req)) { + // todo: redirect to login page + // return ESP_OK; + } + esp_err_t err = httpd_resp_set_type(req, "application/octet-stream"); + if (err != ESP_OK) { + return err; + } -esp_err_t err_handler(httpd_req_t *req, httpd_err_code_t error){ - esp_err_t err = ESP_OK; - - if(error != HTTPD_404_NOT_FOUND){ - err = httpd_resp_send_err(req, error, NULL); + ESP_LOGD(TAG, "Creating binding"); + pb_ostream_t filestream = {&out_http_binding, req, SIZE_MAX, 0}; + ESP_LOGD(TAG, "Starting encode"); + if (!pb_encode(&filestream, sys_Config_fields, (void*)&status)) { + ESP_LOGE(TAG, "Encoding failed: %s\n", PB_GET_ERROR(&filestream)); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, PB_GET_ERROR(&filestream)); } else { - err = redirect_processor(req,error); + ESP_LOGD(TAG, "Encoded size: %d", filestream.bytes_written); + if (filestream.bytes_written == 0) { + ESP_LOGE(TAG, "Empty status!"); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Empty status!"); + } } - return err; + // update status for next status call + network_async_update_status(); + + return ESP_OK; +} + +esp_err_t err_handler(httpd_req_t* req, httpd_err_code_t error) { + esp_err_t err = ESP_OK; + + if (error != HTTPD_404_NOT_FOUND) { + err = httpd_resp_send_err(req, error, NULL); + } else { + err = redirect_processor(req, error); + } + + return err; } diff --git a/components/wifi-manager/http_server_handlers.h b/components/wifi-manager/http_server_handlers.h index 98227221..78f487c7 100644 --- a/components/wifi-manager/http_server_handlers.h +++ b/components/wifi-manager/http_server_handlers.h @@ -14,7 +14,6 @@ Copyright (c) 2017-2021 Sebastien L #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_wifi.h" -#include #include "nvs_flash.h" #include "esp_log.h" #include "driver/gpio.h" @@ -47,7 +46,6 @@ extern "C" { esp_err_t root_get_handler(httpd_req_t *req); esp_err_t resource_filehandler(httpd_req_t *req); -esp_err_t ap_get_handler(httpd_req_t *req); esp_err_t config_get_handler(httpd_req_t *req); esp_err_t config_post_handler(httpd_req_t *req); esp_err_t connect_post_handler(httpd_req_t *req); @@ -63,7 +61,8 @@ esp_err_t console_cmd_post_handler(httpd_req_t *req); esp_err_t ap_scan_handler(httpd_req_t *req); esp_err_t redirect_ev_handler(httpd_req_t *req); esp_err_t redirect_200_ev_handler(httpd_req_t *req); - +esp_err_t configurator_post_handler(httpd_req_t *req); +esp_err_t configurator_get_handler(httpd_req_t *req); esp_err_t err_handler(httpd_req_t *req, httpd_err_code_t error); #define SCRATCH_BUFSIZE (10240) diff --git a/components/wifi-manager/network_driver_DM9051.c b/components/wifi-manager/network_driver_DM9051.c index 82e228f5..8cbc8dd2 100644 --- a/components/wifi-manager/network_driver_DM9051.c +++ b/components/wifi-manager/network_driver_DM9051.c @@ -6,15 +6,15 @@ static EXT_RAM_ATTR spi_device_interface_config_t devcfg; static EXT_RAM_ATTR esp_netif_config_t cfg_spi; static EXT_RAM_ATTR esp_netif_inherent_config_t esp_netif_config; -static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) { +static esp_err_t start(spi_device_handle_t spi_handle, sys_Eth* ethernet_config) { #ifdef CONFIG_ETH_SPI_ETHERNET_DM9051 eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); eth_dm9051_config_t eth_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle); // we assume that isr has been installed already - eth_config.int_gpio_num = ethernet_config->intr; + eth_config.int_gpio_num = ethernet_config->ethType.spi.has_intr?ethernet_config->ethType.spi.intr.pin:-1; phy_config.phy_addr = -1; - phy_config.reset_gpio_num = ethernet_config->rst; + phy_config.reset_gpio_num = ethernet_config->common.has_rst?ethernet_config->common.rst.pin:-1; esp_eth_mac_t* mac = esp_eth_mac_new_dm9051(ð_config, &mac_config); esp_eth_phy_t* phy = esp_eth_phy_new_dm9051(&phy_config); @@ -25,14 +25,14 @@ static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_co #endif } -static void init_config(eth_config_t* ethernet_config) { +static void init_config(sys_Eth* ethernet_config) { esp_netif_inherent_config_t loc_esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH(); devcfg.command_bits = 1; devcfg.address_bits = 7; devcfg.mode = 0; - devcfg.clock_speed_hz = ethernet_config->speed > 0 ? ethernet_config->speed : SPI_MASTER_FREQ_20M; // default speed + devcfg.clock_speed_hz = ethernet_config->ethType.spi.speed > 0 ? ethernet_config->ethType.spi.speed : SPI_MASTER_FREQ_20M; // default speed devcfg.queue_size = 20; - devcfg.spics_io_num = ethernet_config->cs; + devcfg.spics_io_num = ethernet_config->ethType.spi.has_cs?ethernet_config->ethType.spi.cs.pin:-1; memcpy(&esp_netif_config, &loc_esp_netif_config, sizeof(loc_esp_netif_config)); cfg_spi.base = &esp_netif_config, cfg_spi.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH; @@ -41,8 +41,9 @@ static void init_config(eth_config_t* ethernet_config) { DM9051.start = start; } -network_ethernet_driver_t* DM9051_Detect(char* Driver) { - if (!strcasestr(Driver, "DM9051")) +network_ethernet_driver_t* DM9051_Detect(sys_Eth* ethernet_config) { + if (ethernet_config->common.model != sys_EthModelEnum_DM9051 || + ethernet_config->which_ethType != sys_Eth_spi_tag ) return NULL; DM9051.rmii = false; DM9051.spi = true; @@ -52,5 +53,6 @@ network_ethernet_driver_t* DM9051_Detect(char* Driver) { DM9051.valid = false; #endif DM9051.init_config = init_config; + DM9051.model = ethernet_config->common.model; return &DM9051; } diff --git a/components/wifi-manager/network_driver_LAN8720.c b/components/wifi-manager/network_driver_LAN8720.c index ac986262..1f29c9f2 100644 --- a/components/wifi-manager/network_driver_LAN8720.c +++ b/components/wifi-manager/network_driver_LAN8720.c @@ -5,15 +5,15 @@ static EXT_RAM_ATTR network_ethernet_driver_t LAN8720; static EXT_RAM_ATTR esp_netif_config_t cfg_rmii; static EXT_RAM_ATTR esp_netif_inherent_config_t esp_netif_config; -static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) { +static esp_err_t start(spi_device_handle_t spi_handle, sys_Eth * ethernet_config) { #ifdef CONFIG_ETH_PHY_INTERFACE_RMII eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); - mac_config.smi_mdc_gpio_num = ethernet_config->mdc; - mac_config.smi_mdio_gpio_num = ethernet_config->mdio; + mac_config.smi_mdc_gpio_num = ethernet_config->ethType.rmii.has_mdc?ethernet_config->ethType.rmii.mdc.pin:-1; + mac_config.smi_mdio_gpio_num = ethernet_config->ethType.rmii.has_mdio?ethernet_config->ethType.rmii.mdio.pin:-1; phy_config.phy_addr = 1; - phy_config.reset_gpio_num = ethernet_config->rst; + phy_config.reset_gpio_num = ethernet_config->common.has_rst?ethernet_config->common.rst.pin:-1; esp_eth_mac_t* mac = esp_eth_mac_new_esp32(&mac_config); esp_eth_phy_t* phy = esp_eth_phy_new_lan8720(&phy_config); @@ -24,7 +24,7 @@ static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_co #endif } -static void init_config(eth_config_t* ethernet_config) { +static void init_config(sys_Eth * ethernet_config) { esp_netif_inherent_config_t loc_esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH(); memcpy(&esp_netif_config, &loc_esp_netif_config, sizeof(loc_esp_netif_config)); @@ -35,8 +35,9 @@ static void init_config(eth_config_t* ethernet_config) { LAN8720.start = start; } -network_ethernet_driver_t* LAN8720_Detect(char* Driver) { - if (!strcasestr(Driver, "LAN8720")) +network_ethernet_driver_t* LAN8720_Detect(sys_Eth * ethernet_config) { + if (ethernet_config->common.model != sys_EthModelEnum_LAN8720 || + ethernet_config->which_ethType != sys_Eth_rmii_tag) return NULL; #ifdef CONFIG_ETH_PHY_INTERFACE_RMII LAN8720.valid = true; @@ -45,6 +46,7 @@ network_ethernet_driver_t* LAN8720_Detect(char* Driver) { #endif LAN8720.rmii = true; LAN8720.spi = false; + LAN8720.model = ethernet_config->common.model; LAN8720.init_config = init_config; return &LAN8720; } diff --git a/components/wifi-manager/network_driver_W5500.c b/components/wifi-manager/network_driver_W5500.c index 2586894c..cc892987 100644 --- a/components/wifi-manager/network_driver_W5500.c +++ b/components/wifi-manager/network_driver_W5500.c @@ -6,15 +6,15 @@ static EXT_RAM_ATTR spi_device_interface_config_t devcfg; static EXT_RAM_ATTR esp_netif_config_t cfg_spi; static EXT_RAM_ATTR esp_netif_inherent_config_t esp_netif_config; -static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) { +static esp_err_t start(spi_device_handle_t spi_handle, sys_Eth * ethernet_config) { #ifdef CONFIG_ETH_SPI_ETHERNET_W5500 eth_w5500_config_t eth_config = ETH_W5500_DEFAULT_CONFIG(spi_handle); eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); - eth_config.int_gpio_num = ethernet_config->intr; + eth_config.int_gpio_num = ethernet_config->ethType.spi.has_intr?ethernet_config->ethType.spi.intr.pin:-1; phy_config.phy_addr = -1; // let the system automatically find out the phy address - phy_config.reset_gpio_num = ethernet_config->rst; + phy_config.reset_gpio_num = ethernet_config->common.has_rst?ethernet_config->common.rst.pin:-1; esp_eth_mac_t* mac = esp_eth_mac_new_w5500(ð_config, &mac_config); esp_eth_phy_t* phy = esp_eth_phy_new_w5500(&phy_config); @@ -24,7 +24,7 @@ static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_co return ESP_ERR_NOT_SUPPORTED; #endif } -static void init_config(eth_config_t* ethernet_config) { +static void init_config(sys_Eth * ethernet_config) { // This function is called when the network interface is started // and performs any initialization that requires a valid ethernet // configuration . @@ -32,9 +32,9 @@ static void init_config(eth_config_t* ethernet_config) { devcfg.command_bits = 16; // Actually it's the address phase in W5500 SPI frame devcfg.address_bits = 8; // Actually it's the control phase in W5500 SPI frame devcfg.mode = 0; - devcfg.clock_speed_hz = ethernet_config->speed > 0 ? ethernet_config->speed : SPI_MASTER_FREQ_20M; // default speed + devcfg.clock_speed_hz = ethernet_config->ethType.spi.speed > 0 ? ethernet_config->ethType.spi.speed : SPI_MASTER_FREQ_20M; // default speed devcfg.queue_size = 20; - devcfg.spics_io_num = ethernet_config->cs; + devcfg.spics_io_num = ethernet_config->ethType.spi.has_cs?ethernet_config->ethType.spi.cs.pin:-1; memcpy(&esp_netif_config, &loc_esp_netif_config, sizeof(loc_esp_netif_config)); cfg_spi.base = &esp_netif_config, cfg_spi.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH; @@ -43,12 +43,14 @@ static void init_config(eth_config_t* ethernet_config) { W5500.start = start; } -network_ethernet_driver_t* W5500_Detect(char* Driver, network_ethernet_driver_t* Device) { - if (!strcasestr(Driver, "W5500")) +network_ethernet_driver_t* W5500_Detect(sys_Eth * ethernet_config) { + if (ethernet_config->common.model != sys_EthModelEnum_W5500 || + ethernet_config->which_ethType != sys_Eth_spi_tag ) return NULL; W5500.init_config = init_config; W5500.spi = true; W5500.rmii = false; + W5500.model = ethernet_config->common.model; #ifdef CONFIG_ETH_SPI_ETHERNET_W5500 W5500.valid = true; #else diff --git a/components/wifi-manager/network_ethernet.c b/components/wifi-manager/network_ethernet.c index e7b9da42..5f90e548 100644 --- a/components/wifi-manager/network_ethernet.c +++ b/components/wifi-manager/network_ethernet.c @@ -5,11 +5,12 @@ #include "freertos/timers.h" #include "messaging.h" #include "network_status.h" -#include "platform_config.h" -#include "tools.h" +// #include "Configurator.h" +#pragma message("fixme: search for TODO below") #include "accessors.h" #include "esp_log.h" #include "globdefs.h" +#include "tools.h" static char TAG[] = "network_ethernet"; TimerHandle_t ETH_timer; @@ -17,39 +18,24 @@ esp_netif_t* eth_netif = NULL; EventGroupHandle_t ethernet_event_group; const int LINK_UP_BIT = BIT0; -static const char* known_drivers[] = {"DM9051", "W5500", "LAN8720", NULL}; static network_ethernet_driver_t* network_driver = NULL; extern network_ethernet_detect_func_t DM9051_Detect, W5500_Detect, LAN8720_Detect; -static network_ethernet_detect_func_t* drivers[] = {DM9051_Detect, W5500_Detect, LAN8720_Detect, NULL}; +static network_ethernet_detect_func_t* drivers[] = { + DM9051_Detect, W5500_Detect, LAN8720_Detect, NULL}; #define ETH_TIMEOUT_MS (30 * 1000) -/**************************************************************************************** - * - */ -const char* network_ethernet_conf_get_driver_name(const char* driver) { - for (uint8_t i = 0; known_drivers[i] != NULL && strlen(known_drivers[i]) > 0; i++) { - if (strcasestr(driver, known_drivers[i])) { - return known_drivers[i]; - } - } - return NULL; -} -/**************************************************************************************** - * - */ -bool network_ethernet_is_valid_driver(const char* driver) { - return network_ethernet_conf_get_driver_name(driver) != NULL; -} +network_ethernet_driver_t* network_ethernet_driver_autodetect() { + sys_Eth* eth_config; + sys_EthCommon* eth_common; -network_ethernet_driver_t* network_ethernet_driver_autodetect(const char* Driver) { - if (!Driver) + if (!SYS_ETH(eth_config) || !SYS_ETH_COMMON(eth_common)) { + ESP_LOGD(TAG, "Ethernet not configured"); return NULL; - - for (int i = 0; drivers[i]; i++) { - network_ethernet_driver_t* found_driver = drivers[i](Driver); + } + for (uint8_t i = _sys_EthModelEnum_MIN; i < _sys_EthModelEnum_MAX; i++) { + network_ethernet_driver_t* found_driver = drivers[i](eth_config); if (found_driver) { - ESP_LOGI(TAG, "Detected driver %s ", Driver); - + ESP_LOGI(TAG, "Detected driver %s ", sys_EthModelEnum_name(eth_common->model)); network_driver = found_driver; return found_driver; } @@ -57,82 +43,107 @@ network_ethernet_driver_t* network_ethernet_driver_autodetect(const char* Driver return NULL; } -static void eth_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); -esp_netif_t *network_ethernet_get_interface(){ - return eth_netif; -} +static void eth_event_handler( + void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); +esp_netif_t* network_ethernet_get_interface() { return eth_netif; } bool network_ethernet_is_up() { - return (xEventGroupGetBits(ethernet_event_group) & LINK_UP_BIT)!=0; + return (xEventGroupGetBits(ethernet_event_group) & LINK_UP_BIT) != 0; } -bool network_ethernet_enabled() { - return network_driver !=NULL && network_driver->handle != NULL; -} -bool network_ethernet_wait_for_link(uint16_t max_wait_ms){ - if(!network_ethernet_enabled()) return false; - bool link_up=(xEventGroupGetBits(ethernet_event_group) & LINK_UP_BIT)!=0; - if(!link_up){ - ESP_LOGD(TAG,"Waiting for Ethernet link to be established..."); - link_up = (xEventGroupWaitBits(ethernet_event_group, LINK_UP_BIT,pdFALSE, pdTRUE, max_wait_ms / portTICK_PERIOD_MS)& LINK_UP_BIT)!=0; - if(!link_up){ - ESP_LOGW(TAG,"Ethernet Link timeout."); - } - else - { - ESP_LOGI(TAG,"Ethernet Link Up!"); - } - } +bool network_ethernet_enabled() { return network_driver != NULL && network_driver->handle != NULL; } +bool network_ethernet_wait_for_link(uint16_t max_wait_ms) { + if (!network_ethernet_enabled()) return false; + bool link_up = (xEventGroupGetBits(ethernet_event_group) & LINK_UP_BIT) != 0; + if (!link_up) { + ESP_LOGD(TAG, "Waiting for Ethernet link to be established..."); + link_up = (xEventGroupWaitBits(ethernet_event_group, LINK_UP_BIT, pdFALSE, pdTRUE, + max_wait_ms / portTICK_PERIOD_MS) & + LINK_UP_BIT) != 0; + if (!link_up) { + ESP_LOGW(TAG, "Ethernet Link timeout."); + } else { + ESP_LOGI(TAG, "Ethernet Link Up!"); + } + } return link_up; } static void ETH_Timeout(void* timer_id); -void destroy_network_ethernet() { -} +void destroy_network_ethernet() {} -static void network_ethernet_print_config(const eth_config_t* eth_config) { - ESP_LOGI(TAG,"Ethernet config => model: %s, valid: %s, type: %s, mdc:%d, mdio:%d, rst:%d, intr:%d, cs:%d, speed:%d, host:%d", - eth_config->model, eth_config->valid ? "YES" : "NO", eth_config->spi ? "SPI" : "RMII", - eth_config->mdc, eth_config->mdio, - eth_config->rst, eth_config->intr, eth_config->cs, eth_config->speed, eth_config->host); -} +static void network_ethernet_print_config(const network_ethernet_driver_t* eth_config) { + sys_Eth* sys_eth; + int mdc = -1, mdio = -1, rst = -1, intr = -1, cs = -1; + int16_t speed = 0; + int8_t host = 0; + if (SYS_ETH(sys_eth)) { + if (sys_eth->which_ethType == sys_Eth_spi_tag) { + if (sys_eth->ethType.spi.has_cs) { + cs = sys_eth->ethType.spi.cs.pin; + } + if (sys_eth->ethType.spi.has_intr) { + intr = sys_eth->ethType.spi.intr.pin; + } + speed = sys_eth->ethType.spi.speed; + host = sys_eth->ethType.spi.host; + + } else if (sys_eth->which_ethType == sys_Eth_rmii_tag) { + if (sys_eth->ethType.rmii.has_mdc) { + mdc = sys_eth->ethType.rmii.mdc.pin; + } + if (sys_eth->ethType.rmii.has_mdio) { + mdio = sys_eth->ethType.rmii.mdio.pin; + } + } + } + ESP_LOGI(TAG, + "Ethernet config => model: %s, valid: %s, type: %s, mdc:%d, mdio:%d, rst:%d, intr:%d, " + "cs:%d, speed:%d, host:%d", + sys_EthModelEnum_name(eth_config->model), eth_config->valid ? "YES" : "NO", + eth_config->spi ? "SPI" : "RMII", mdc, mdio, rst, intr, cs, speed, host); +} void init_network_ethernet() { esp_err_t err = ESP_OK; - eth_config_t eth; ESP_LOGI(TAG, "Attempting to initialize Ethernet"); - config_eth_init(ð); - if(!eth.valid){ - ESP_LOGI(TAG,"No Ethernet configuration, or configuration invalid"); + sys_Eth* sys_eth; + if(!SYS_ETH(sys_eth)){ + ESP_LOGD(TAG,"No ethernet configured"); + return; + } + network_ethernet_driver_t*driver= network_ethernet_driver_autodetect(); + if (!driver || !driver->valid) { + ESP_LOGI(TAG, "No Ethernet configuration, or configuration invalid"); return; } - network_driver->init_config(ð); - network_ethernet_print_config(ð); + network_driver->init_config(&platform->dev.eth); + network_ethernet_print_config(driver); eth_netif = esp_netif_new(network_driver->cfg_netif); esp_eth_set_default_handlers(eth_netif); esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, NULL); ethernet_event_group = xEventGroupCreate(); - xEventGroupClearBits(ethernet_event_group, LINK_UP_BIT); + xEventGroupClearBits(ethernet_event_group, LINK_UP_BIT); spi_device_handle_t spi_handle = NULL; - if (network_driver->spi) { - err = spi_bus_add_device(eth.host, network_driver->devcfg, &spi_handle); + if (sys_eth->which_ethType == sys_Eth_spi_tag) { + err = spi_bus_add_device(sys_eth->ethType.spi.host, network_driver->devcfg, &spi_handle); if (err != ESP_OK) { ESP_LOGE(TAG, "SPI host failed : %s", esp_err_to_name(err)); } } if (err == ESP_OK) { - err = network_driver->start(spi_handle,ð); + err = network_driver->start(spi_handle, sys_eth); } - if(err == ESP_OK){ + if (err == ESP_OK) { uint8_t mac_address[6]; - esp_read_mac(mac_address,ESP_MAC_ETH); - char * mac_string=network_manager_alloc_get_mac_string(mac_address); - ESP_LOGD(TAG,"Assigning mac address %s to ethernet interface", STR_OR_BLANK(mac_string)); + esp_read_mac(mac_address, ESP_MAC_ETH); + char* mac_string = network_manager_alloc_get_mac_string(mac_address); + ESP_LOGD(TAG, "Assigning mac address %s to ethernet interface", STR_OR_BLANK(mac_string)); FREE_AND_NULL(mac_string); esp_eth_ioctl(network_driver->handle, ETH_CMD_S_MAC_ADDR, mac_address); - } + } if (err == ESP_OK) { ESP_LOGD(TAG, "Attaching ethernet to network interface"); err = esp_netif_attach(eth_netif, esp_eth_new_netif_glue(network_driver->handle)); @@ -140,11 +151,11 @@ void init_network_ethernet() { if (err == ESP_OK) { ESP_LOGI(TAG, "Starting ethernet network"); err = esp_eth_start(network_driver->handle); - } if (err != ESP_OK) { - messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Configuring Ethernet failed: %s", esp_err_to_name(err)); - if(spi_handle) { + messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, + "Configuring Ethernet failed: %s", esp_err_to_name(err)); + if (spi_handle) { spi_bus_remove_device(spi_handle); } network_driver->handle = NULL; @@ -152,43 +163,43 @@ void init_network_ethernet() { } void network_ethernet_start_timer() { - ETH_timer = xTimerCreate("ETH check", pdMS_TO_TICKS(ETH_TIMEOUT_MS), pdFALSE, NULL, ETH_Timeout); + ETH_timer = + xTimerCreate("ETH check", pdMS_TO_TICKS(ETH_TIMEOUT_MS), pdFALSE, NULL, ETH_Timeout); } /** Event handler for Ethernet events */ -static void eth_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { +static void eth_event_handler( + void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { uint8_t mac_addr[6] = {0}; /* we can get the ethernet driver handle from event data */ if (event_base == ETH_EVENT) { esp_eth_handle_t eth_handle = *(esp_eth_handle_t*)event_data; switch (event_id) { - case ETHERNET_EVENT_CONNECTED: - xEventGroupSetBits(ethernet_event_group, LINK_UP_BIT); - esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr); - ESP_LOGI(TAG, ""); - ESP_LOGI(TAG, "Ethernet Link Up, HW Addr %02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); - network_async_link_up(); - break; - case ETHERNET_EVENT_DISCONNECTED: - ESP_LOGI(TAG, "Ethernet Link Down"); - xEventGroupClearBits(ethernet_event_group, LINK_UP_BIT); - network_async_link_down(); - break; - case ETHERNET_EVENT_START: - ESP_LOGI(TAG, "Ethernet Started. Setting host name"); - network_set_hostname(eth_netif); - network_async_success(); - break; - case ETHERNET_EVENT_STOP: - ESP_LOGI(TAG, "Ethernet Stopped"); - break; - default: - break; + case ETHERNET_EVENT_CONNECTED: + xEventGroupSetBits(ethernet_event_group, LINK_UP_BIT); + esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr); + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "Ethernet Link Up, HW Addr %02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], + mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + network_async_link_up(); + break; + case ETHERNET_EVENT_DISCONNECTED: + ESP_LOGI(TAG, "Ethernet Link Down"); + xEventGroupClearBits(ethernet_event_group, LINK_UP_BIT); + network_async_link_down(); + break; + case ETHERNET_EVENT_START: + ESP_LOGI(TAG, "Ethernet Started. Setting host name"); + network_set_hostname(eth_netif); + network_async_success(); + break; + case ETHERNET_EVENT_STOP: + ESP_LOGI(TAG, "Ethernet Stopped"); + break; + default: + break; } - } -} - -static void ETH_Timeout(void* timer_id) { - network_async_fail(); + } } +static void ETH_Timeout(void* timer_id) { network_async_fail(); } diff --git a/components/wifi-manager/network_ethernet.h b/components/wifi-manager/network_ethernet.h index e0b3a9e8..0858ef07 100644 --- a/components/wifi-manager/network_ethernet.h +++ b/components/wifi-manager/network_ethernet.h @@ -4,6 +4,7 @@ #include "accessors.h" #include #include "esp_netif_defaults.h" +#include "Configurator.h" #ifdef __cplusplus extern "C" { @@ -13,17 +14,18 @@ typedef struct { bool valid; bool rmii; bool spi; + sys_EthModelEnum model; esp_eth_handle_t handle; esp_netif_config_t * cfg_netif; spi_device_interface_config_t * devcfg; // This function is called when the network interface is started // and performs any initialization that requires a valid ethernet // configuration . - void (*init_config)(eth_config_t * eth_config); - esp_err_t (*start)(spi_device_handle_t spi_handle,eth_config_t *ethernet_config); + void (*init_config)(sys_Eth * config); + esp_err_t (*start)(spi_device_handle_t spi_handle,sys_Eth * config); } network_ethernet_driver_t; -typedef network_ethernet_driver_t* network_ethernet_detect_func_t(const char* Driver); -network_ethernet_driver_t* network_ethernet_driver_autodetect(const char* Driver); +typedef network_ethernet_driver_t* network_ethernet_detect_func_t(sys_Eth * config); +network_ethernet_driver_t* network_ethernet_driver_autodetect(); void destroy_network_ethernet(); void init_network_ethernet(); bool network_ethernet_wait_for_link(uint16_t max_wait_ms); diff --git a/components/wifi-manager/network_manager.c b/components/wifi-manager/network_manager.c index 2127ca70..313c7662 100644 --- a/components/wifi-manager/network_manager.c +++ b/components/wifi-manager/network_manager.c @@ -38,7 +38,8 @@ Copyright (c) 2017-2021 Sebastien L #include "mdns.h" #include "messaging.h" -#include "platform_config.h" +// #include "Configurator.h" +#pragma message("fixme: look for TODO below") #include "tools.h" #include "trace.h" @@ -46,6 +47,7 @@ Copyright (c) 2017-2021 Sebastien L #include "esp_err.h" #include "http_server_handlers.h" #include "network_manager.h" +#include "Configurator.h" QueueHandle_t network_queue; BaseType_t network_task_handle; @@ -405,14 +407,14 @@ void network_execute_cb(state_machine_t* const state_machine, const char * calle } bool network_is_wifi_prioritized() { - eth_config_t eth_config; - config_eth_init(ð_config); - // char* prioritize = (char*)config_alloc_get_default(NVS_TYPE_STR, "prio_wifi", "N", 0); - // bool result = strcasecmp("N", prioritize); + sys_EthCommon * common = NULL; bool result = s_wifi_prioritized; + bool valid_model = SYS_ETH_COMMON(common) && common->model == sys_EthModelEnum_UNSPECIFIED_ETHMODEL; if(result){ - result = network_wifi_get_known_count()>0 || !eth_config.valid; - ESP_LOGD(TAG,"Wifi is prioritized with %d known access points.%s %s",network_wifi_get_known_count(),eth_config.valid?" And a valid ethernet adapter":"",result?"Wifi prioritized":"Ethernet prioritized"); + result = network_wifi_get_known_count()>0 || !valid_model; + ESP_LOGD(TAG,"Wifi is prioritized with %d known access points.%s %s", + network_wifi_get_known_count(), + valid_model?" And a valid ethernet adapter":"",result?"Wifi prioritized":"Ethernet prioritized"); } return result; } @@ -421,10 +423,6 @@ void network_prioritize_wifi(bool activate) { if(s_wifi_prioritized == activate) return; s_wifi_prioritized = activate; ESP_LOGI(TAG,"Wifi is %s prioritized",activate?"":"not"); - // if (network_is_wifi_prioritized() != activate) { - // ESP_LOGW(TAG, "Wifi will %s be prioritized on next boot", activate ? "" : "NOT"); - // config_set_value(NVS_TYPE_STR, "prio_wifi", activate ? "Y" : "N"); - // } } @@ -727,16 +725,15 @@ void network_ip_event_handler(void* arg, esp_event_base_t event_base, int32_t ev void network_set_hostname(esp_netif_t* interface) { esp_err_t err; ESP_LOGD(TAG, "Retrieving host name from nvs"); - char* host_name = (char*)config_alloc_get(NVS_TYPE_STR, "host_name"); - if (host_name == NULL) { + if (!platform->has_names || strlen(platform->names.device) == 0 ) { ESP_LOGE(TAG, "Could not retrieve host name from nvs"); } else { - ESP_LOGD(TAG, "Setting host name to : %s", host_name); - if ((err = esp_netif_set_hostname(interface, host_name)) != ESP_OK) { + ESP_LOGD(TAG, "Setting host name to : %s", platform->names.device); + if ((err = esp_netif_set_hostname(interface, platform->names.device)) != ESP_OK) { ESP_LOGE(TAG, "Unable to set host name. Error: %s", esp_err_to_name(err)); } - free(host_name); } + } #define LOCAL_MAC_SIZE 20 char* network_manager_alloc_get_mac_string(uint8_t mac[6]) { diff --git a/components/wifi-manager/network_manager.h b/components/wifi-manager/network_manager.h index d3205c77..1edfa132 100644 --- a/components/wifi-manager/network_manager.h +++ b/components/wifi-manager/network_manager.h @@ -4,7 +4,6 @@ #include "esp_wifi.h" #include "esp_wifi_types.h" #include "squeezelite-ota.h" -#include "cJSON.h" #include "esp_eth.h" #include "freertos/event_groups.h" #include "hsm.h" @@ -250,17 +249,6 @@ void network_reboot_ota(char * url); * UPDATE_FAILED_ATTEMPT_AND_RESTORE - Web UI expects this when attempting to connect to a new access point fails and previous connection is restored * UPDATE_ETHERNET_CONNECTED = 5 */ -typedef enum update_reason_code_t { - UPDATE_CONNECTION_OK = 0, // expected when - UPDATE_FAILED_ATTEMPT = 1, - UPDATE_USER_DISCONNECT = 2, - UPDATE_LOST_CONNECTION = 3, - UPDATE_FAILED_ATTEMPT_AND_RESTORE = 4, - UPDATE_ETHERNET_CONNECTED = 5 - -}update_reason_code_t; - - @@ -278,10 +266,6 @@ void network_destroy(); void filter_unique( wifi_ap_record_t * aplist, uint16_t * ap_num); -char* network_status_alloc_get_ap_list_json(); -cJSON * network_manager_clear_ap_list_json(cJSON **old); - - /** * @brief A standard wifi event handler as recommended by Espressif @@ -290,14 +274,6 @@ esp_err_t network_manager_event_handler(void *ctx, system_event_t *event); -/** - * @brief Clears the connection status json. - * @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful. - */ -cJSON * network_status_clear_ip_info_json(cJSON **old); -cJSON * network_status_get_new_json(cJSON **old); - - /** * @brief Start the mDNS service diff --git a/components/wifi-manager/network_manager_handlers.c b/components/wifi-manager/network_manager_handlers.c index d05390a7..c7fe3819 100644 --- a/components/wifi-manager/network_manager_handlers.c +++ b/components/wifi-manager/network_manager_handlers.c @@ -34,7 +34,8 @@ #include "mdns.h" #include "messaging.h" -#include "platform_config.h" +// #include "Configurator.h" +#pragma message("fixme: look for TODO below") #include "trace.h" #include "accessors.h" @@ -166,7 +167,8 @@ static state_machine_result_t handle_global_event(state_machine_t* state_machine case EN_UPDATE_STATUS: // handle the event, but don't swicth MEMTRACE_PRINT_DELTA_MESSAGE("handle EN_UPDATE_STATUS - start"); - network_status_update_basic_info(); + // todo: fix this + // network_status_update_basic_info(); MEMTRACE_PRINT_DELTA_MESSAGE("handle EN_UPDATE_STATUS - end"); return EVENT_HANDLED; /* code */ @@ -224,16 +226,16 @@ static state_machine_result_t NETWORK_INSTANTIATED_STATE_handler(state_machine_t network_t* const nm = (network_t *)State_Machine; State_Machine->State = &network_states[NETWORK_INSTANTIATED_STATE]; State_Machine->Event = EN_START; - config_get_uint16t_from_str("pollmx",&nm->sta_polling_max_ms,600); - nm->sta_polling_max_ms = nm->sta_polling_max_ms * 1000; - config_get_uint16t_from_str("apdelay",&nm->ap_duration_ms,20); - nm->ap_duration_ms = nm->ap_duration_ms * 1000; - config_get_uint16t_from_str("pollmin",&nm->sta_polling_min_ms,15); - nm->sta_polling_min_ms = nm->sta_polling_min_ms*1000; - config_get_uint16t_from_str("ethtmout",&nm->eth_link_down_reboot_ms,30); - nm->eth_link_down_reboot_ms = nm->eth_link_down_reboot_ms*1000; - config_get_uint16t_from_str("dhcp_tmout",&nm->dhcp_timeout,30); - nm->dhcp_timeout = nm->dhcp_timeout*1000; + // config_get_uint16t_from_str("pollmx",&nm->sta_polling_max_ms,600); + // nm->sta_polling_max_ms = nm->sta_polling_max_ms * 1000; + // config_get_uint16t_from_str("apdelay",&nm->ap_duration_ms,20); + // nm->ap_duration_ms = nm->ap_duration_ms * 1000; + // config_get_uint16t_from_str("pollmin",&nm->sta_polling_min_ms,15); + // nm->sta_polling_min_ms = nm->sta_polling_min_ms*1000; + // config_get_uint16t_from_str("ethtmout",&nm->eth_link_down_reboot_ms,30); + // nm->eth_link_down_reboot_ms = nm->eth_link_down_reboot_ms*1000; + // config_get_uint16t_from_str("dhcp_tmout",&nm->dhcp_timeout,30); + // nm->dhcp_timeout = nm->dhcp_timeout*1000; ESP_LOGI(TAG,"Network manager configuration: polling max %d, polling min %d, ap delay %d, dhcp timeout %d, eth timeout %d", nm->sta_polling_max_ms,nm->sta_polling_min_ms,nm->ap_duration_ms,nm->dhcp_timeout, nm->eth_link_down_reboot_ms); HANDLE_GLOBAL_EVENT(State_Machine); @@ -386,13 +388,14 @@ static state_machine_result_t NETWORK_ETH_ACTIVE_STATE_handler(state_machine_t* break; case EN_SCAN: ESP_LOGW(TAG,"Wifi scan cannot be executed in this state"); - network_wifi_built_known_ap_list(); + //todo: fix this! + // network_wifi_built_known_ap_list(); result = EVENT_HANDLED; break; case EN_DELETE: { ESP_LOGD(TAG, "WiFi disconnected by user"); network_wifi_clear_config(); - network_status_update_ip_info(UPDATE_USER_DISCONNECT); + network_status_update_ip_info(sys_UPDATE_REASONS_R_USER_DISCONNECT); result= EVENT_HANDLED; } break; default: @@ -434,7 +437,7 @@ static state_machine_result_t ETH_CONNECTING_NEW_STATE_handler(state_machine_t* result= local_traverse_state(State_Machine, &network_states[WIFI_CONNECTED_STATE],__FUNCTION__); break; case EN_LOST_CONNECTION: - network_status_update_ip_info(UPDATE_FAILED_ATTEMPT); + network_status_update_ip_info(sys_UPDATE_REASONS_R_FAILED_ATTEMPT); messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Unable to connect to new WiFi access point."); // no existing configuration, or wifi wasn't the active connection when connection // attempt was made @@ -528,7 +531,7 @@ static state_machine_result_t NETWORK_WIFI_ACTIVE_STATE_handler(state_machine_t* network_interface_coexistence(State_Machine); break; case EN_GOT_IP: - network_status_update_ip_info(UPDATE_CONNECTION_OK); + network_status_update_ip_info(sys_UPDATE_REASONS_R_CONNECTION_OK); result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_CONNECTED_STATE],__FUNCTION__); break; case EN_SCAN: @@ -715,7 +718,7 @@ static state_machine_result_t WIFI_CONFIGURING_CONNECT_STATE_handler(state_machi network_set_timer(nm->dhcp_timeout,"DHCP Timeout"); break; case EN_GOT_IP: - network_status_update_ip_info(UPDATE_CONNECTION_OK); + network_status_update_ip_info(sys_UPDATE_REASONS_R_CONNECTION_OK); result= local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONFIGURING_CONNECT_SUCCESS_STATE],__FUNCTION__); break; case EN_LOST_CONNECTION: @@ -723,13 +726,13 @@ static state_machine_result_t WIFI_CONFIGURING_CONNECT_STATE_handler(state_machi ESP_LOGI(TAG,"Wifi was disconnected from previous access point. Waiting to connect."); } else { - network_status_update_ip_info(UPDATE_FAILED_ATTEMPT); + network_status_update_ip_info(sys_UPDATE_REASONS_R_FAILED_ATTEMPT); result = local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONFIGURING_STATE],__FUNCTION__); } break; case EN_TIMER: ESP_LOGW(TAG,"Connection timeout. (%s)",STR_OR_ALT(nm->timer_tag, "Unknown")); - network_status_update_ip_info(UPDATE_FAILED_ATTEMPT); + network_status_update_ip_info(sys_UPDATE_REASONS_R_FAILED_ATTEMPT); result = local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONFIGURING_STATE],__FUNCTION__); break; default: @@ -752,9 +755,10 @@ static state_machine_result_t WIFI_CONFIGURING_CONNECT_STATE_exit_handler(state_ */ static state_machine_result_t WIFI_CONFIGURING_CONNECT_SUCCESS_STATE_entry_handler(state_machine_t* const State_Machine) { network_handler_entry_print(State_Machine,true); - network_status_update_ip_info(UPDATE_CONNECTION_OK); + network_status_update_ip_info(sys_UPDATE_REASONS_R_CONNECTION_OK); ESP_LOGD(TAG, "Saving wifi configuration."); - network_wifi_save_sta_config(); + // todo: fix this! + // network_wifi_save_sta_config(); NETWORK_EXECUTE_CB(State_Machine); network_handler_entry_print(State_Machine,false); return EVENT_HANDLED; @@ -765,11 +769,13 @@ static state_machine_result_t WIFI_CONFIGURING_CONNECT_SUCCESS_STATE_handler(sta network_t* const nm = (network_t *)State_Machine; switch (State_Machine->Event) { case EN_UPDATE_STATUS: - network_status_update_basic_info(); + // todo: fix this + // network_status_update_basic_info(); network_set_timer(nm->ap_duration_ms,"Access point teardown"); // set a timer to tear down the AP mode break; case EN_TIMER: - network_status_update_basic_info(); + // todo: fix this + // network_status_update_basic_info(); result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_CONNECTED_STATE],__FUNCTION__); break; default: @@ -826,7 +832,7 @@ static state_machine_result_t WIFI_CONNECTING_STATE_handler(state_machine_t* con ESP_LOGI(TAG,"Wifi was disconnected from previous access point. Waiting to connect."); } else if(nm->event_parameters->disconnected_event->reason != WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT) { - network_status_update_ip_info(UPDATE_FAILED_ATTEMPT); + network_status_update_ip_info(sys_UPDATE_REASONS_R_FAILED_ATTEMPT); result = local_traverse_state(State_Machine, &Wifi_Configuring_State[WIFI_CONFIGURING_STATE],__FUNCTION__); } break; @@ -862,7 +868,7 @@ static state_machine_result_t WIFI_CONNECTING_NEW_STATE_handler(state_machine_t* state_machine_result_t result = EVENT_HANDLED; switch (State_Machine->Event) { case EN_GOT_IP: - network_status_update_ip_info(UPDATE_CONNECTION_OK); + network_status_update_ip_info(sys_UPDATE_REASONS_R_CONNECTION_OK); result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_CONNECTED_STATE],__FUNCTION__); break; case EN_CONNECTED: @@ -916,7 +922,7 @@ static state_machine_result_t WIFI_CONNECTING_NEW_FAILED_STATE_handler(state_mac state_machine_result_t result = EVENT_HANDLED; switch (State_Machine->Event) { case EN_GOT_IP: - network_status_update_ip_info(UPDATE_FAILED_ATTEMPT_AND_RESTORE); + network_status_update_ip_info(sys_UPDATE_REASONS_R_FAILED_ATTEMPT_AND_RESTORE); result= local_traverse_state(State_Machine, &Wifi_Active_State[WIFI_CONNECTED_STATE],__FUNCTION__); break; case EN_CONNECTED: @@ -924,7 +930,7 @@ static state_machine_result_t WIFI_CONNECTING_NEW_FAILED_STATE_handler(state_mac result = EVENT_HANDLED; break; case EN_LOST_CONNECTION: - network_status_update_ip_info(UPDATE_FAILED_ATTEMPT); + network_status_update_ip_info(sys_UPDATE_REASONS_R_FAILED_ATTEMPT); messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Unable to fall back to previous access point."); result = EVENT_HANDLED; break; @@ -958,7 +964,7 @@ static state_machine_result_t WIFI_CONNECTED_STATE_entry_handler(state_machine_t ESP_LOGD(TAG, "Checking if wifi config changed."); if (network_wifi_sta_config_changed()) { ESP_LOGD(TAG, "Wifi Config changed. Saving it."); - network_wifi_save_sta_config(); + configurator_raise_changed(); } ESP_LOGD(TAG, "Updating the ip info json."); network_interface_coexistence(State_Machine); @@ -997,7 +1003,7 @@ static state_machine_result_t WIFI_USER_DISCONNECTED_STATE_entry_handler(state_m network_handler_entry_print(State_Machine,true); ESP_LOGD(TAG, " WiFi disconnected by user"); network_wifi_clear_config(); - network_status_update_ip_info(UPDATE_USER_DISCONNECT); + network_status_update_ip_info(sys_UPDATE_REASONS_R_USER_DISCONNECT); NETWORK_EXECUTE_CB(State_Machine); network_handler_entry_print(State_Machine,false); return EVENT_HANDLED; @@ -1031,8 +1037,9 @@ static state_machine_result_t WIFI_LOST_CONNECTION_STATE_entry_handler(state_mac network_handler_entry_print(State_Machine,true); ESP_LOGE(TAG, " WiFi Connection lost."); messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "WiFi Connection lost"); - network_status_update_ip_info(UPDATE_LOST_CONNECTION); - network_status_safe_reset_sta_ip_string(); + network_status_update_ip_info(sys_UPDATE_REASONS_R_LOST_CONNECTION); + //todo: fix this! + // network_status_safe_reset_sta_ip_string(); if (nm->last_connected > 0) nm->total_connected_time += ((esp_timer_get_time() - nm->last_connected) / (1000 * 1000)); nm->last_connected = 0; @@ -1050,7 +1057,7 @@ static state_machine_result_t WIFI_LOST_CONNECTION_STATE_entry_handler(state_mac ESP_LOGW(TAG, "Cannot connect to Wifi. Falling back to Ethernet "); network_async(EN_ETHERNET_FALLBACK); } else { - network_status_update_ip_info(UPDATE_LOST_CONNECTION); + network_status_update_ip_info(sys_UPDATE_REASONS_R_LOST_CONNECTION); wifi_mode_t mode; ESP_LOGW(TAG, " All connect retry attempts failed."); @@ -1109,7 +1116,7 @@ static state_machine_result_t WIFI_LOST_CONNECTION_STATE_exit_handler(state_mach static state_machine_result_t ETH_ACTIVE_CONNECTED_STATE_entry_handler(state_machine_t* const State_Machine) { network_t* const nm = (network_t *)State_Machine; network_handler_entry_print(State_Machine,true); - network_status_update_ip_info(UPDATE_ETHERNET_CONNECTED); + network_status_update_ip_info(sys_UPDATE_REASONS_R_ETHERNET_CONNECTED); nm->ethernet_connected = true; // start a wifi Scan so web ui is populated with available entries NETWORK_EXECUTE_CB(State_Machine); @@ -1161,15 +1168,16 @@ static void network_interface_coexistence(state_machine_t* state_machine) { // found to be active at the same time network_t* nm = (network_t *)state_machine; if (nm->wifi_connected && state_machine->Event == EN_ETH_GOT_IP) { - char* eth_reboot = config_alloc_get_default(NVS_TYPE_STR, "eth_boot", "N", 0); - network_prioritize_wifi(false); - if (strcasecmp(eth_reboot, "N")) { - ESP_LOGW(TAG, "Option eth_reboot set to reboot when ethernet is connected. Rebooting"); - simple_restart(); - } else { - ESP_LOGW(TAG, "Option eth_reboot set to not reboot when ethernet is connected. Using Wifi interface until next reboot"); - } - FREE_AND_NULL(eth_reboot); + // char* eth_reboot = config_alloc_get_default(NVS_TYPE_STR, "eth_boot", "N", 0); + // network_prioritize_wifi(false); + // if (strcasecmp(eth_reboot, "N")) { + // ESP_LOGW(TAG, "Option eth_reboot set to reboot when ethernet is connected. Rebooting"); + // simple_restart(); + // } else { + // ESP_LOGW(TAG, "Option eth_reboot set to not reboot when ethernet is connected. Using Wifi interface until next reboot"); + // } + // FREE_AND_NULL(eth_reboot); + // TODO: Add support for the commented code } else if (get_root(state_machine->State)->Id == NETWORK_ETH_ACTIVE_STATE){ messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi Connected with Ethernet active. System reload needed"); simple_restart(); diff --git a/components/wifi-manager/network_status.c b/components/wifi-manager/network_status.c index d47fe418..29a08e0f 100644 --- a/components/wifi-manager/network_status.c +++ b/components/wifi-manager/network_status.c @@ -12,7 +12,8 @@ #include "monitor.h" #include "network_ethernet.h" #include "network_wifi.h" -#include "platform_config.h" +// #include "Configurator.h" +#pragma message("fixme: search for TODO below") #include "platform_esp32.h" #include "tools.h" #include "trace.h" @@ -21,162 +22,69 @@ #define CONFIG_SQUEEZELITE_ESP32_RELEASE_URL "https://github.com/sle118/squeezelite-esp32/releases" #endif static const char TAG[] = "network_status"; -SemaphoreHandle_t network_status_json_mutex = NULL; -static TaskHandle_t network_json_locked_task = NULL; -SemaphoreHandle_t network_status_ip_address_mutex = NULL; -static TaskHandle_t network_status_ip_address_locked_task = NULL; -char* release_url = NULL; -char* network_status_ip_address = NULL; -char* ip_info_json = NULL; -cJSON* ip_info_cjson = NULL; -static char lms_server_ip[IP4ADDR_STRLEN_MAX] = {0}; -static uint16_t lms_server_port = 0; -static uint16_t lms_server_cport = 0; +sys_Status status; +SemaphoreHandle_t network_status_structure_mutex = NULL; +static TaskHandle_t network_structure_locked_task = NULL; static void (*chained_notify)(in_addr_t, u16_t, u16_t); static void connect_notify(in_addr_t ip, u16_t hport, u16_t cport); + #define STA_IP_LEN sizeof(char) * IP4ADDR_STRLEN_MAX void init_network_status() { chained_notify = server_notify; server_notify = connect_notify; ESP_LOGD(TAG, "init_network_status. Creating mutexes"); - network_status_json_mutex = xSemaphoreCreateMutex(); - network_status_ip_address_mutex = xSemaphoreCreateMutex(); - ip_info_json = NULL; - ESP_LOGD(TAG, "init_network_status. Creating status json structure"); - ip_info_cjson = network_status_clear_ip_info_json(&ip_info_cjson); + network_status_structure_mutex = xSemaphoreCreateMutex(); ESP_LOGD(TAG, "Getting release url "); - char* release_url = (char*)config_alloc_get_default(NVS_TYPE_STR, "release_url", QUOTE(CONFIG_SQUEEZELITE_ESP32_RELEASE_URL), 0); - if (release_url == NULL) { - ESP_LOGE(TAG, "Unable to retrieve the release url from nvs"); - } else { - ESP_LOGD(TAG, "Found release url %s", release_url); + } - ESP_LOGD(TAG, "About to set the STA IP String to 0.0.0.0"); - network_status_ip_address = (char*)malloc_init_external(STA_IP_LEN); - network_status_safe_update_sta_ip_string(NULL); -} void destroy_network_status() { - FREE_AND_NULL(release_url); - FREE_AND_NULL(ip_info_json); - FREE_AND_NULL(network_status_ip_address); - cJSON_Delete(ip_info_cjson); - vSemaphoreDelete(network_status_json_mutex); - network_status_json_mutex = NULL; - vSemaphoreDelete(network_status_ip_address_mutex); - network_status_ip_address_mutex = NULL; - ip_info_cjson = NULL; -} -cJSON* network_status_get_new_json(cJSON** old) { - ESP_LOGV(TAG, "network_status_get_new_json called"); - cJSON* root = *old; - if (root != NULL) { - cJSON_Delete(root); - *old = NULL; - } - ESP_LOGV(TAG, "network_status_get_new_json done"); - return cJSON_CreateObject(); + vSemaphoreDelete(network_status_structure_mutex); + network_status_structure_mutex = NULL; } -cJSON* network_status_clear_ip_info_json(cJSON** old) { - ESP_LOGV(TAG, "network_status_clear_ip_info_json called"); - cJSON* root = network_status_get_basic_info(old); - cJSON_DeleteItemFromObjectCaseSensitive(root, "ip"); - cJSON_DeleteItemFromObjectCaseSensitive(root, "netmask"); - cJSON_DeleteItemFromObjectCaseSensitive(root, "gw"); - cJSON_DeleteItemFromObjectCaseSensitive(root, "rssi"); - cJSON_DeleteItemFromObjectCaseSensitive(root, "ssid"); - cJSON_DeleteItemFromObjectCaseSensitive(root, "eth"); - - ESP_LOGV(TAG, "network_status_clear_ip_info_json done"); - return root; -} -void network_status_clear_ip() { - if (network_status_lock_json_buffer(portMAX_DELAY)) { - ip_info_cjson = network_status_clear_ip_info_json(&ip_info_cjson); - network_status_unlock_json_buffer(); - } -} -char* network_status_alloc_get_ip_info_json() { - return cJSON_PrintUnformatted(ip_info_cjson); -} - -void network_status_unlock_json_buffer() { +void network_status_unlock_structure() { ESP_LOGV(TAG, "Unlocking json buffer!"); - network_json_locked_task = NULL; - xSemaphoreGive(network_status_json_mutex); + network_structure_locked_task = NULL; + xSemaphoreGive(network_status_structure_mutex); } -bool network_status_lock_json_buffer(TickType_t xTicksToWait) { - ESP_LOGV(TAG, "Locking json buffer"); +bool network_status_lock_structure(TickType_t xTicksToWait) { + ESP_LOGV(TAG, "Locking structure buffer"); TaskHandle_t calling_task = xTaskGetCurrentTaskHandle(); - if (calling_task == network_json_locked_task) { - ESP_LOGV(TAG, "json buffer already locked to current task"); + if (calling_task == network_structure_locked_task) { + ESP_LOGV(TAG, "structure buffer already locked to current task"); return true; } - if (network_status_json_mutex) { - if (xSemaphoreTake(network_status_json_mutex, xTicksToWait) == pdTRUE) { - ESP_LOGV(TAG, "Json buffer locked!"); - network_json_locked_task = calling_task; + if (network_status_structure_mutex) { + if (xSemaphoreTake(network_status_structure_mutex, xTicksToWait) == pdTRUE) { + ESP_LOGV(TAG, "structure locked!"); + network_structure_locked_task = calling_task; return true; } else { - ESP_LOGE(TAG, "Semaphore take failed. Unable to lock json buffer mutex"); + ESP_LOGE(TAG, "Semaphore take failed. Unable to lock structure mutex"); return false; } } else { - ESP_LOGV(TAG, "Unable to lock json buffer mutex"); + ESP_LOGV(TAG, "Unable to lock structure mutex"); return false; } } -bool network_status_lock_sta_ip_string(TickType_t xTicksToWait) { - TaskHandle_t calling_task = xTaskGetCurrentTaskHandle(); - if (calling_task == network_status_ip_address_locked_task) { - ESP_LOGD(TAG, "json buffer already locked to current task "); - return true; - } - if (network_status_ip_address_mutex) { - if (xSemaphoreTake(network_status_ip_address_mutex, xTicksToWait) == pdTRUE) { - network_status_ip_address_locked_task = calling_task; - return true; - } else { - return false; - } - } else { - return false; - } -} - -void network_status_unlock_sta_ip_string() { - network_status_ip_address_locked_task = NULL; - xSemaphoreGive(network_status_ip_address_mutex); -} - -void network_status_safe_update_sta_ip_string(esp_ip4_addr_t* ip4) { - if (network_status_lock_sta_ip_string(portMAX_DELAY)) { - strcpy(network_status_ip_address, ip4 != NULL ? ip4addr_ntoa((ip4_addr_t*)ip4) : "0.0.0.0"); - ESP_LOGD(TAG, "Set STA IP String to: %s", network_status_ip_address); - network_status_unlock_sta_ip_string(); - } -} -void network_status_safe_reset_sta_ip_string() { - if (network_status_lock_sta_ip_string(portMAX_DELAY)) { - strcpy(network_status_ip_address, "0.0.0.0"); - ESP_LOGD(TAG, "Set STA IP String to: %s", network_status_ip_address); - network_status_unlock_sta_ip_string(); - } -} char* network_status_get_sta_ip_string() { - return network_status_ip_address; + return status.has_net && status.net.has_ip?status.net.ip.ip:"0.0.0.0"; } void set_lms_server_details(in_addr_t ip, u16_t hport, u16_t cport) { - strncpy(lms_server_ip, inet_ntoa(ip), sizeof(lms_server_ip)); - lms_server_ip[sizeof(lms_server_ip) - 1] = '\0'; - ESP_LOGI(TAG, "LMS IP: %s, hport: %d, cport: %d", lms_server_ip, hport, cport); - lms_server_port = hport; - lms_server_cport = cport; + if (network_status_lock_structure(portMAX_DELAY)) { + status.has_LMS = true; + strncpy(status.LMS.ip, inet_ntoa(ip), sizeof(status.LMS.ip)); + status.LMS.port = hport; + status.LMS.cport = cport; + ESP_LOGI(TAG, "LMS IP: %s, hport: %d, cport: %d", status.LMS.ip, status.LMS.port, status.LMS.cport); + network_status_unlock_structure(); + } } static void connect_notify(in_addr_t ip, u16_t hport, u16_t cport) { set_lms_server_details(ip, hport, cport); @@ -185,163 +93,94 @@ static void connect_notify(in_addr_t ip, u16_t hport, u16_t cport) { network_async_update_status(); } -void network_status_update_basic_info() { - // locking happens below this level - network_status_get_basic_info(&ip_info_cjson); -} - -cJSON* network_status_update_float(cJSON** root, const char* key, float value) { - if (network_status_lock_json_buffer(portMAX_DELAY)) { - if (*root == NULL) { - *root = cJSON_CreateObject(); - } - - if (key && strlen(key) != 0) { - cJSON* cjsonvalue = cJSON_GetObjectItemCaseSensitive(*root, key); - if (cjsonvalue) { - cJSON_SetNumberValue(cjsonvalue, value); - } else { - cJSON_AddNumberToObject(*root, key, value); - } - } - network_status_unlock_json_buffer(); - } else { - ESP_LOGW(TAG, "Unable to lock status json buffer. "); - } - return *root; -} -cJSON* network_status_update_bool(cJSON** root, const char* key, bool value) { - if (network_status_lock_json_buffer(portMAX_DELAY)) { - if (*root == NULL) { - *root = cJSON_CreateObject(); - } - - if (key && strlen(key) != 0) { - cJSON* cjsonvalue = cJSON_GetObjectItemCaseSensitive(*root, key); - if (cjsonvalue) { - cjsonvalue->type = value ? cJSON_True : cJSON_False; - } else { - cJSON_AddBoolToObject(*root, key, value); - } - } - network_status_unlock_json_buffer(); - } else { - ESP_LOGW(TAG, "Unable to lock status json buffer. "); - } - return *root; -} -cJSON * network_update_cjson_string(cJSON** root, const char* key, const char* value){ - if (network_status_lock_json_buffer(portMAX_DELAY)) { - cjson_update_string(root, key, value); - network_status_unlock_json_buffer(); - } else { - ESP_LOGW(TAG, "Unable to lock status json buffer. "); - } - return *root; -} -cJSON * network_update_cjson_number(cJSON** root, const char* key, int value){ - if (network_status_lock_json_buffer(portMAX_DELAY)) { - cjson_update_number(root, key, value); - network_status_unlock_json_buffer(); - } else { - ESP_LOGW(TAG, "Unable to lock status json buffer. "); - } - return *root; -} -cJSON* network_status_get_basic_info(cJSON** old) { - if (network_status_lock_json_buffer(portMAX_DELAY)) { +void network_status_set_basic_info() { + if (network_status_lock_structure(portMAX_DELAY)) { network_t* nm = network_get_state_machine(); - monitor_gpio_t* mgpio = get_jack_insertion_gpio(); + sys_GPIO * gpio = NULL; const esp_app_desc_t* desc = esp_ota_get_app_description(); - - *old = network_update_cjson_string(old, "project_name", desc->project_name); + status.has_platform = true; + strncpy(status.platform.project, desc->project_name, sizeof(status.platform.project)); #ifdef CONFIG_FW_PLATFORM_NAME - *old = network_update_cjson_string(old, "platform_name", CONFIG_FW_PLATFORM_NAME); + strncpy(status.platform.name, CONFIG_FW_PLATFORM_NAME, sizeof(status.platform.name)); #endif - *old = network_update_cjson_string(old, "version", desc->version); - if (release_url != NULL) - *old = network_update_cjson_string(old, "release_url", release_url); - *old = network_update_cjson_number(old, "recovery", is_recovery_running ? 1 : 0); - *old = network_status_update_bool(old, "Jack", mgpio->gpio >= 0 && jack_inserted_svc()); - *old = network_status_update_float(old, "Voltage", battery_value_svc()); - *old = network_update_cjson_number(old, "disconnect_count", nm->num_disconnect); - *old = network_status_update_float(old, "avg_conn_time", nm->num_disconnect > 0 ? (nm->total_connected_time / nm->num_disconnect) : 0); + strncpy(status.platform.version, desc->version, sizeof(status.platform.version)); + strncpy(status.platform.version, desc->version, sizeof(status.platform.version)); + status.platform.recovery = is_recovery_running; + status.platform.depth = 16; +#if DEPTH == 16 || DEPTH == 32 + status.platform.depth = DEPTH; +#endif + status.has_hw = true; + + status.hw.jack_inserted = jack_inserted_svc(); + status.hw.has_jack_inserted = SYS_GPIOS_NAME(jack,gpio) && gpio->pin>=0; + status.hw.has_spk_fault = SYS_GPIOS_NAME(spkfault,gpio) && gpio->pin>=0; + status.hw.spk_fault = spkfault_svc(); + status.hw.batt_voltage = battery_value_svc(); + status.has_net = true; + status.net.has_wifi = true; + status.net.wifi.disconnect_count = nm->num_disconnect; + status.net.wifi.avg_conn_time = nm->num_disconnect > 0 ? (nm->total_connected_time / nm->num_disconnect) : 0; + #ifdef CONFIG_BT_ENABLED - *old = network_update_cjson_number(old, "bt_status", bt_app_source_get_a2d_state()); - *old = network_update_cjson_number(old, "bt_sub_status", bt_app_source_get_media_state()); + if(platform->has_services && platform->services.has_bt_sink && platform->services.bt_sink.enabled){ + status.has_bt = true; + status.bt.bt_status = bt_app_source_get_a2d_state(); + status.bt.bt_media_state = bt_app_source_get_media_state(); + } #endif -#if DEPTH == 16 - *old = network_update_cjson_number(old, "depth", 16); -#elif DEPTH == 32 - *old = network_update_cjson_number(old, "depth", 32); -#endif -#if CONFIG_I2C_LOCKED - *old = network_status_update_bool(old, "is_i2c_locked", true); -#else - *old = network_status_update_bool(old, "is_i2c_locked", false); -#endif + if (network_ethernet_enabled()) { - *old = network_status_update_bool(old, "eth_up", network_ethernet_is_up()); - } - if (lms_server_cport > 0) { - *old = network_update_cjson_number(old, "lms_cport", lms_server_cport); - } - - if (lms_server_port > 0) { - *old = network_update_cjson_number(old, "lms_port", lms_server_port); - } - - if (strlen(lms_server_ip) > 0) { - *old = network_update_cjson_string(old, "lms_ip", lms_server_ip); + status.net.eth_up = network_ethernet_is_up(); } ESP_LOGV(TAG, "network_status_get_basic_info done"); - network_status_unlock_json_buffer(); + network_status_unlock_structure(); } else { ESP_LOGW(TAG, "Unable to lock status json buffer. "); } - return *old; } -void network_status_update_address(cJSON* root, esp_netif_ip_info_t* ip_info) { - if (!root || !ip_info) { - ESP_LOGE(TAG, "Cannor update IP address. JSON structure or ip_info is null"); - return; - } - network_update_cjson_string(&root, "ip", ip4addr_ntoa((ip4_addr_t*)&ip_info->ip)); - network_update_cjson_string(&root, "netmask", ip4addr_ntoa((ip4_addr_t*)&ip_info->netmask)); - network_update_cjson_string(&root, "gw", ip4addr_ntoa((ip4_addr_t*)&ip_info->gw)); +void network_status_update_address(esp_netif_ip_info_t* ip_info) { + status.has_net = true; + status.net.has_ip = true; + strncpy(status.net.ip.ip,ip4addr_ntoa((ip4_addr_t*)&ip_info->ip),sizeof(status.net.ip.ip)); + strncpy(status.net.ip.netmask,ip4addr_ntoa((ip4_addr_t*)&ip_info->netmask),sizeof(status.net.ip.netmask)); + strncpy(status.net.ip.gw,ip4addr_ntoa((ip4_addr_t*)&ip_info->gw),sizeof(status.net.ip.gw)); } -void network_status_update_ip_info(update_reason_code_t update_reason_code) { +void network_status_update_ip_info(sys_UPDATE_REASONS update_reason_code) { ESP_LOGV(TAG, "network_status_update_ip_info called"); esp_netif_ip_info_t ip_info; - if (network_status_lock_json_buffer(portMAX_DELAY)) { + if (network_status_lock_structure(portMAX_DELAY)) { /* generate the connection info with success */ - ip_info_cjson = network_status_get_basic_info(&ip_info_cjson); - ip_info_cjson = network_update_cjson_number(&ip_info_cjson, "urc", (int)update_reason_code); + network_status_set_basic_info(); + status.net.updt_reason = update_reason_code; + status.net.wifi.has_connected_sta = false; + status.net.wifi.connected_sta.connected = false; + ESP_LOGD(TAG,"Updating ip info with reason code %d. Checking if Wifi interface is connected",update_reason_code); - if (network_is_interface_connected(network_wifi_get_interface()) || update_reason_code == UPDATE_FAILED_ATTEMPT ) { - network_update_cjson_string(&ip_info_cjson, "if", "wifi"); + if (network_is_interface_connected(network_wifi_get_interface()) || update_reason_code == sys_UPDATE_REASONS_R_FAILED_ATTEMPT ) { + status.net.interface = sys_CONNECTED_IF_IF_WIFI; + esp_netif_get_ip_info(network_wifi_get_interface(), &ip_info); - network_status_update_address(ip_info_cjson, &ip_info); + network_status_update_address(&ip_info); if (!network_wifi_is_ap_mode()) { /* wifi is active, and associated to an AP */ wifi_ap_record_t ap; esp_wifi_sta_get_ap_info(&ap); - network_update_cjson_string(&ip_info_cjson, "ssid", ((char*)ap.ssid)); - network_update_cjson_number(&ip_info_cjson, "rssi", ap.rssi); + network_wifi_esp_sta_to_sta(&ap, &status.net.wifi.connected_sta); + status.net.wifi.connected_sta.connected = true; + status.net.has_wifi = true; + status.net.wifi.has_connected_sta = true; } - } else { - cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "rssi"); - cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "ssid"); - } + } ESP_LOGD(TAG,"Checking if ethernet interface is connected"); if (network_is_interface_connected(network_ethernet_get_interface())) { - network_update_cjson_string(&ip_info_cjson, "if", "eth"); + status.net.interface = sys_CONNECTED_IF_IF_ETHERNET; esp_netif_get_ip_info(network_ethernet_get_interface(), &ip_info); - network_status_update_address(ip_info_cjson, &ip_info); + network_status_update_address(&ip_info); } - network_status_unlock_json_buffer(); + network_status_unlock_structure(); } else { ESP_LOGW(TAG, "Unable to lock status json buffer. "); } diff --git a/components/wifi-manager/network_status.h b/components/wifi-manager/network_status.h index 19a7dfb4..10b7bf3d 100644 --- a/components/wifi-manager/network_status.h +++ b/components/wifi-manager/network_status.h @@ -1,10 +1,12 @@ #pragma once #include "network_manager.h" #include "cJSON.h" +#include "Configurator.h" #ifdef __cplusplus extern "C" { #endif +extern sys_Status status; char* network_status_alloc_get_ip_info_json(); /** * @brief Tries to get access to json buffer mutex. @@ -21,39 +23,24 @@ char* network_status_alloc_get_ip_info_json(); * @param xTicksToWait The time in ticks to wait for the semaphore to become available. * @return true in success, false otherwise. */ -bool network_status_lock_json_buffer(TickType_t xTicksToWait); +bool network_status_lock_structure(TickType_t xTicksToWait); /** * @brief Releases the json buffer mutex. */ -void network_status_unlock_json_buffer(); - -bool network_status_lock_sta_ip_string(TickType_t xTicksToWait); -void network_status_unlock_sta_ip_string(); - -/** - * @brief gets the string representation of the STA IP address, e.g.: "192.168.1.69" - */ -char* network_status_get_sta_ip_string(); - -/** - * @brief thread safe char representation of the STA IP update - */ -void network_status_safe_update_sta_ip_string(esp_ip4_addr_t * ip4); +void network_status_unlock_structure(); /** * @brief Generates the connection status json: ssid and IP addresses. * @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful. */ -void network_status_update_ip_info(update_reason_code_t update_reason_code); +void network_status_update_ip_info(sys_UPDATE_REASONS update_reason_code); void init_network_status(); void destroy_network_status(); -cJSON* network_status_get_basic_info(cJSON** old); -void network_status_update_basic_info(); void network_status_clear_ip(); -void network_status_safe_reset_sta_ip_string(); +void network_status_safe_reset_sta_ip(); #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/components/wifi-manager/network_wifi.c b/components/wifi-manager/network_wifi.c index 3412d215..c9aa3bce 100644 --- a/components/wifi-manager/network_wifi.c +++ b/components/wifi-manager/network_wifi.c @@ -2,7 +2,6 @@ #define LOG_LOCAL_LEVEL NETWORK_WIFI_LOG_LEVEL #endif #include "network_wifi.h" -#include #include "cJSON.h" #include "dns_server.h" #include "esp_event.h" @@ -13,100 +12,175 @@ #include "lwip/sockets.h" #include "messaging.h" #include "network_status.h" -#include "nvs.h" -#include "nvs_flash.h" -#include "nvs_utilities.h" -#include "platform_config.h" +#include +#pragma message("fixme: search for TODO in the code below") #include "platform_esp32.h" #include "tools.h" #include "trace.h" -static void network_wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); +#include "accessors.h" +static void network_wifi_event_handler( + void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); static char* get_disconnect_code_desc(uint8_t reason); esp_err_t network_wifi_get_blob(void* target, size_t size, const char* key); static inline const char* ssid_string(const wifi_sta_config_t* sta); static inline const char* password_string(const wifi_sta_config_t* sta); -cJSON* accessp_cjson = NULL; - +static const char* status_file_name = "status.bin"; +#define MAX_CREDENTIALS sizeof(platform->net.credentials) / sizeof(sys_WifiSTAEntry) static const char TAG[] = "network_wifi"; -const char network_wifi_nvs_namespace[] = "config"; -const char ap_list_nsv_namespace[] = "aplist"; -/* rrm ctx */ -//Roaming support - int rrm_ctx = 0; - -uint16_t ap_num = 0; - esp_netif_t* wifi_netif; esp_netif_t* wifi_ap_netif; +extern sys_Status status; -wifi_ap_record_t* accessp_records = NULL; -#define UINT_TO_STRING(val) \ - static char loc[sizeof(val) + 1]; \ - memset(loc, 0x00, sizeof(loc)); \ - strlcpy(loc, (char*)val, sizeof(loc)); \ +#define UINT_TO_STRING(val) \ + static char loc[sizeof(val) + 1]; \ + memset(loc, 0x00, sizeof(loc)); \ + strlcpy(loc, (char*)val, sizeof(loc)); \ return loc; -static inline const char* ssid_string(const wifi_sta_config_t* sta) { - UINT_TO_STRING(sta->ssid); -} +static inline const char* ssid_string(const wifi_sta_config_t* sta) { UINT_TO_STRING(sta->ssid); } static inline const char* password_string(const wifi_sta_config_t* sta) { UINT_TO_STRING(sta->password); } -static inline const char* ap_ssid_string(const wifi_ap_record_t* ap) { - UINT_TO_STRING(ap->ssid); -} -typedef struct known_access_point { - char* ssid; - char* password; - bool found; - uint8_t bssid[6]; /**< MAC address of AP */ - uint8_t primary; /**< channel of AP */ - wifi_auth_mode_t authmode; /**< authmode of AP */ - uint32_t phy_11b : 1; /**< bit: 0 flag to identify if 11b mode is enabled or not */ - uint32_t phy_11g : 1; /**< bit: 1 flag to identify if 11g mode is enabled or not */ - uint32_t phy_11n : 1; /**< bit: 2 flag to identify if 11n mode is enabled or not */ - uint32_t phy_lr : 1; /**< bit: 3 flag to identify if low rate is enabled or not */ - time_t last_try; - SLIST_ENTRY(known_access_point) - next; //!< next callback -} known_access_point_t; - -/** linked list of command structures */ -static EXT_RAM_ATTR SLIST_HEAD(ap_list, known_access_point) s_ap_list; -known_access_point_t* network_wifi_get_ap_entry(const char* ssid) { - known_access_point_t* it; - - if (!ssid || strlen(ssid) == 0) { - ESP_LOGW(TAG, "network_wifi_get_ap_entry Invalid SSID %s", !ssid ? "IS NULL" : "IS BLANK"); - return NULL; +static inline const char* ap_ssid_string(const wifi_ap_record_t* ap) { UINT_TO_STRING(ap->ssid); } +bool network_wifi_reset_rssi() { + ESP_LOGD(TAG,"Resetting RSSI"); + if (network_status_lock_structure(pdMS_TO_TICKS(1000))) { + for (int index = 0; index < platform->net.credentials_count - 1; index++) { + platform->net.credentials[index].rssi = 0; + } + network_status_unlock_structure(); + return true; } - - SLIST_FOREACH(it, &s_ap_list, next) { - ESP_LOGD(TAG, "Looking for SSID %s = %s ?", ssid, it->ssid); - if (strcmp(it->ssid, ssid) == 0) { - ESP_LOGD(TAG, "network_wifi_get_ap_entry SSID %s found! ", ssid); - return it; + return false; +} +bool network_wifi_reset_connected() { + ESP_LOGD(TAG,"Resetting Connected"); + if (network_status_lock_structure(pdMS_TO_TICKS(1000))) { + for (int index = 0; index < platform->net.credentials_count - 1; index++) { + platform->net.credentials[index].connected = false; + } + network_status_unlock_structure(); + return true; + } + return false; +} +void network_wifi_format_bssid(char* buffer, size_t len, const uint8_t* bssid) { + snprintf(buffer, len, "%02X:%02X:%02X:%02X:%02X:%02X", bssid[0], bssid[1], bssid[2], bssid[3], + bssid[4], bssid[5]); +} +int network_wifi_get_ap_entry_index(const char* ssid) { + for (int i = 0; i < platform->net.credentials_count; i++) { + if (strcmp(platform->net.credentials[i].ssid, ssid) == 0) { + // found the SSID. + return i; } } - return NULL; + return -1; } -void network_wifi_remove_ap_entry(const char* ssid) { - if (!ssid || strlen(ssid) == 0) { - ESP_LOGE(TAG, "network_wifi_remove_ap_entry error empty SSID"); +sys_WifiSTAEntry * network_wifi_get_ap_entry(const char * ssid){ + sys_WifiSTAEntry * result = NULL; + int index = network_wifi_get_ap_entry_index(ssid); + if(index>=0 && index < platform->net.credentials_count){ + result = &platform->net.credentials[index]; } - known_access_point_t* it = network_wifi_get_ap_entry(ssid); - if (it) { - ESP_LOGW(TAG, "Removing %s from known list of access points", ssid); - FREE_AND_NULL(it->ssid); - FREE_AND_NULL(it->password); - SLIST_REMOVE(&s_ap_list, it, known_access_point, next); - FREE_AND_NULL(it); + return result; +} +void network_wifi_update_connected(const char * ssid){ + if(!ssid || strlen(ssid) == 0){ + ESP_LOGE(TAG, "Unable to update connected SSID. No ssid received"); + return; + } + sys_WifiSTAEntry * sta = network_wifi_get_ap_entry(ssid); + if (sta && network_status_lock_structure(pdMS_TO_TICKS(1000))) { + sta->connected = true; + network_status_unlock_structure(); + platform->net.has_last_connected = true; + memcpy(&platform->net.last_connected, sta,sizeof(platform->net.last_connected)); + } + +} +size_t network_wifi_get_known_count(){ + size_t result = 0; + for (int i = 0; i < platform->net.credentials_count; i++) { + if(strlen(platform->net.credentials[i].ssid)>0) result ++; + } + return result; + +} + +bool network_wifi_remove_credentials(int index) { + int cur_index = 0; + if (index == -1 || index >= platform->net.credentials_count) { + ESP_LOGW(TAG, "ssid not found or erorr finding SSID"); + return false; + } + if (network_status_lock_structure(pdMS_TO_TICKS(1000))) { + for (cur_index = index; cur_index < platform->net.credentials_count - 1; cur_index++) { + // Shift following ssid's starting at this slot. + memcpy(&platform->net.credentials[cur_index], &platform->net.credentials[cur_index + 1], + sizeof(sys_WifiSTAEntry)); + } + memset(&platform->net.credentials[cur_index + 1], 0x00, sizeof(sys_WifiSTAEntry)); + platform->net.credentials_count--; + network_status_unlock_structure(); + return true; + } + return false; +} + + +bool network_wifi_remove_ap_entry(const char* ssid) { + int index = network_wifi_get_ap_entry_index(ssid); + return network_wifi_remove_credentials(index); +} + +void network_wifi_sort_last_seen() { + sys_NetworkConfig* config = NULL; + + if (!SYS_NET(config)) return; + if (network_status_lock_structure(pdMS_TO_TICKS(1000))) { + bool swapped; + do { + swapped = false; + for (int i = 0; i < config->credentials_count - 1; i++) { + if (config->credentials[i].last_seen.seconds < config->credentials[i + 1].last_seen.seconds) { + sys_WifiSTAEntry temp = config->credentials[i]; + config->credentials[i] = config->credentials[i + 1]; + config->credentials[i + 1] = temp; + swapped = true; + } + } + } while (swapped); + network_status_unlock_structure(); + } +} +void network_wifi_sort_strength() { + sys_NetworkConfig* config = platform->has_net ? &platform->net : NULL; + if (!config) return; + if (network_status_lock_structure(pdMS_TO_TICKS(1000))) { + bool swapped; + do { + swapped = false; + for (int i = 0; i < config->credentials_count - 1; i++) { + if (config->credentials[i].rssi < config->credentials[i + 1].rssi) { + sys_WifiSTAEntry temp = config->credentials[i]; + config->credentials[i] = config->credentials[i + 1]; + config->credentials[i + 1] = temp; + swapped = true; + } + } + } while (swapped); + network_status_unlock_structure(); } } void network_wifi_empty_known_list() { - known_access_point_t* it; - while ((it = SLIST_FIRST(&s_ap_list)) != NULL) { - network_wifi_remove_ap_entry(it->ssid); + sys_WifiSTAEntry defaultWifi = sys_WifiSTAEntry_init_default; + sys_NetworkConfig* config = platform->has_net ? &platform->net : NULL; + if (!config) return; + for (int i = 0; i < config->credentials_count - 1; i++) { + memcpy(&config->credentials[i], &defaultWifi, sizeof(config->credentials[i])); } + config->credentials_count = 0; } const wifi_sta_config_t* network_wifi_get_active_config() { @@ -120,77 +194,117 @@ const wifi_sta_config_t* network_wifi_get_active_config() { } return NULL; } - -size_t network_wifi_get_known_count() { - size_t count = 0; - known_access_point_t* it; - SLIST_FOREACH(it, &s_ap_list, next) { - count++; - } - return count; -} -size_t network_wifi_get_known_count_in_range() { - size_t count = 0; - known_access_point_t* it; - SLIST_FOREACH(it, &s_ap_list, next) { - if(it->found) count++; - } - return count; -} -esp_err_t network_wifi_add_ap(known_access_point_t* item) { - known_access_point_t* last = SLIST_FIRST(&s_ap_list); - if (last == NULL) { - SLIST_INSERT_HEAD(&s_ap_list, item, next); - } else { - known_access_point_t* it; - while ((it = SLIST_NEXT(last, next)) != NULL) { - last = it; - } - SLIST_INSERT_AFTER(last, item, next); - } - return ESP_OK; -} -esp_err_t network_wifi_add_ap_copy(const known_access_point_t* known_ap) { - known_access_point_t* item = NULL; - esp_err_t err = ESP_OK; - - if (!known_ap) { - ESP_LOGE(TAG, "Invalid access point entry"); - return ESP_ERR_INVALID_ARG; - } - if (!known_ap->ssid || strlen(known_ap->ssid) == 0) { - ESP_LOGE(TAG, "Invalid access point ssid"); - return ESP_ERR_INVALID_ARG; - } - item = malloc_init_external(sizeof(known_access_point_t)); - if (item == NULL) { - ESP_LOGE(TAG, "Memory allocation failed"); - return ESP_ERR_NO_MEM; - } - item->ssid = strdup_psram(known_ap->ssid); - item->password = strdup_psram(known_ap->password); - memcpy(&item->bssid, known_ap->bssid, sizeof(item->bssid)); - item->primary = known_ap->primary; - item->authmode = known_ap->authmode; - item->phy_11b = known_ap->phy_11b; - item->phy_11g = known_ap->phy_11g; - item->phy_11n = known_ap->phy_11n; - item->phy_lr = known_ap->phy_lr; - err = network_wifi_add_ap(item); - return err; -} -const wifi_ap_record_t* network_wifi_get_ssid_info(const char* ssid) { - if (!accessp_records) - return NULL; - for (int i = 0; i < ap_num; i++) { - if (strcmp(ap_ssid_string(&accessp_records[i]), ssid) == 0) { - return &accessp_records[i]; +sys_WifiSTAEntry* network_wifi_get_free_ssid() { + for (int i = 0; i < MAX_CREDENTIALS; i++) { + if (strlen(platform->net.credentials[i].ssid) == 0) { + return &platform->net.credentials[i]; } } return NULL; } -esp_err_t network_wifi_add_ap_from_sta_copy(const wifi_sta_config_t* sta) { - known_access_point_t* item = NULL; + +bool network_wifi_add_ap(sys_WifiSTAEntry* item) { + sys_WifiSTAEntry* entry = network_wifi_get_free_ssid(); + if (!entry) { + network_wifi_sort_last_seen(); + network_wifi_remove_credentials(MAX_CREDENTIALS - 1); + platform->net.credentials_count--; + entry = network_wifi_get_free_ssid(); + } + if (!entry) { + ESP_LOGE(TAG, "Unable to find free slot to store wifi"); + return false; + } + memcpy(entry, item, sizeof(sys_WifiSTAEntry)); + platform->net.credentials_count++; + return true; +} + +sys_WifiSTAEntry* network_wifi_get_ssid_info(const char* ssid) { + if (!ssid || strlen(ssid) == 0) return NULL; + for (int i = 0; i < status.net.wifi.scan_result_count; i++) { + if (strcmp(status.net.wifi.scan_result[i].ssid, ssid) == 0) { + return &status.net.wifi.scan_result[i]; + } + } + return NULL; +} + +wifi_auth_mode_t network_wifi_get_auth_mode(sys_WifiAuthTypeEnum auth_type) { + switch (auth_type) { + case sys_WifiAuthTypeEnum_AUTH_OPEN: + return WIFI_AUTH_OPEN; + case sys_WifiAuthTypeEnum_AUTH_WEP: + return WIFI_AUTH_WEP; + case sys_WifiAuthTypeEnum_AUTH_WPA_PSK: + return WIFI_AUTH_WPA_PSK; + case sys_WifiAuthTypeEnum_AUTH_WPA2_PSK: + return WIFI_AUTH_WPA2_PSK; + case sys_WifiAuthTypeEnum_AUTH_WPA_WPA2_PSK: + return WIFI_AUTH_WPA_WPA2_PSK; + case sys_WifiAuthTypeEnum_AUTH_WPA2_ENTERPRISE: + return WIFI_AUTH_WPA2_ENTERPRISE; + case sys_WifiAuthTypeEnum_AUTH_WPA3_PSK: + return WIFI_AUTH_WPA3_PSK; + case sys_WifiAuthTypeEnum_AUTH_WPA2_WPA3_PSK: + return WIFI_AUTH_WPA2_WPA3_PSK; + case sys_WifiAuthTypeEnum_AUTH_WAPI_PSK: + return WIFI_AUTH_WAPI_PSK; + default: + return WIFI_AUTH_OPEN; // Default case + } +} +sys_WifiAuthTypeEnum network_wifi_get_auth_type(const wifi_auth_mode_t mode) { + switch (mode) { + case WIFI_AUTH_OPEN: + return sys_WifiAuthTypeEnum_AUTH_OPEN; + case WIFI_AUTH_WEP: + return sys_WifiAuthTypeEnum_AUTH_WEP; + case WIFI_AUTH_WPA_PSK: + return sys_WifiAuthTypeEnum_AUTH_WPA_PSK; + case WIFI_AUTH_WPA2_PSK: + return sys_WifiAuthTypeEnum_AUTH_WPA2_PSK; + case WIFI_AUTH_WPA_WPA2_PSK: + return sys_WifiAuthTypeEnum_AUTH_WPA_WPA2_PSK; + case WIFI_AUTH_WPA2_ENTERPRISE: + return sys_WifiAuthTypeEnum_AUTH_WPA2_ENTERPRISE; + case WIFI_AUTH_WPA3_PSK: + return sys_WifiAuthTypeEnum_AUTH_WPA3_PSK; + case WIFI_AUTH_WPA2_WPA3_PSK: + return sys_WifiAuthTypeEnum_AUTH_WPA2_WPA3_PSK; + case WIFI_AUTH_WAPI_PSK: + return sys_WifiAuthTypeEnum_AUTH_WAPI_PSK; + case WIFI_AUTH_MAX: + return sys_WifiAuthTypeEnum_AUTH_OPEN; + } + return sys_WifiAuthTypeEnum_AUTH_UNKNOWN; +} + +sys_WifiRadioTypesEnum network_wifi_get_radio_type(const wifi_ap_record_t* sta) { + if (sta == NULL) { + return sys_WifiRadioTypesEnum_PHY_UNKNOWN; + } + + // Check each bit field and return the corresponding enum value + if (sta->phy_11b) { + return sys_WifiRadioTypesEnum_PHY_11B; + } else if (sta->phy_11g) { + return sys_WifiRadioTypesEnum_PHY_11G; + } else if (sta->phy_11n) { + return sys_WifiRadioTypesEnum_PHY_11N; + } else if (sta->phy_lr) { + return sys_WifiRadioTypesEnum_PHY_LR; + } else if (sta->wps) { + return sys_WifiRadioTypesEnum_PHY_WPS; + } else if (sta->ftm_responder) { + return sys_WifiRadioTypesEnum_PHY_FTM_RESPONDER; + } else if (sta->ftm_initiator) { + return sys_WifiRadioTypesEnum_PHY_FTM_INITIATOR; + } + + return sys_WifiRadioTypesEnum_PHY_UNKNOWN; +} +esp_err_t network_wifi_add_update_ap_from_sta_copy(const wifi_sta_config_t* sta) { esp_err_t err = ESP_OK; if (!sta) { ESP_LOGE(TAG, "Invalid access point entry"); @@ -200,280 +314,40 @@ esp_err_t network_wifi_add_ap_from_sta_copy(const wifi_sta_config_t* sta) { ESP_LOGE(TAG, "Invalid access point ssid"); return ESP_ERR_INVALID_ARG; } - item = malloc_init_external(sizeof(known_access_point_t)); - if (item == NULL) { - ESP_LOGE(TAG, "Memory allocation failed"); - return ESP_ERR_NO_MEM; - } - item->ssid = strdup_psram(ssid_string(sta)); - item->password = strdup_psram(password_string(sta)); - memcpy(&item->bssid, sta->bssid, sizeof(item->bssid)); - item->primary = sta->channel; - const wifi_ap_record_t* seen = network_wifi_get_ssid_info(item->ssid); + sys_WifiSTAEntry item = sys_WifiSTAEntry_init_default; + strncpy(item.ssid, ssid_string(sta), sizeof(item.ssid)); + strncpy(item.password, password_string(sta), sizeof(item.ssid)); + network_wifi_format_bssid(item.bssid, sizeof(item.bssid), sta->bssid); + item.channel = sta->channel; + + sys_WifiSTAEntry* seen = network_wifi_get_ssid_info(item.ssid); if (seen) { - item->authmode = seen->authmode; - item->phy_11b = seen->phy_11b; - item->phy_11g = seen->phy_11g; - item->phy_11n = seen->phy_11n; - item->phy_lr = seen->phy_lr; + item.auth_type = seen->auth_type; + item.radio_type = seen->radio_type; } - err = network_wifi_add_ap(item); + err = network_wifi_add_ap(&item); return err; } -bool network_wifi_is_known_ap(const char* ssid) { - return network_wifi_get_ap_entry(ssid) != NULL; -} +bool network_wifi_is_known_ap(const char* ssid) { return network_wifi_get_ap_entry(ssid) != NULL; } -static bool network_wifi_was_ssid_seen(const char* ssid) { - if (!accessp_records || ap_num == 0 || ap_num == MAX_AP_NUM) { - return false; - } - for (int i = 0; i < ap_num; i++) { - if (strcmp(ap_ssid_string(&accessp_records[i]), ssid) == 0) { - return true; - } - } - return false; -} -void network_wifi_set_found_ap() { - known_access_point_t* it; - SLIST_FOREACH(it, &s_ap_list, next) { - if (network_wifi_was_ssid_seen(it->ssid)) { - it->found = true; - } else { - it->found = false; - } - } -} -bool network_wifi_known_ap_in_range(){ - known_access_point_t* it; - SLIST_FOREACH(it, &s_ap_list, next) { - if (it->found) { - return true; - } - } - return false; -} -const char * network_wifi_get_next_ap_in_range(){ - known_access_point_t* it; - time_t last_try_min=(esp_timer_get_time() / 1000); - SLIST_FOREACH(it, &s_ap_list, next) { - if (it->found && it->last_try < last_try_min) { - last_try_min = it->last_try; - } - } - SLIST_FOREACH(it, &s_ap_list, next) { - if (it->found && it->last_try == last_try_min) { - return it->ssid; - } - } - return NULL; -} - -esp_err_t network_wifi_alloc_ap_json(known_access_point_t* item, char** json_string) { - esp_err_t err = ESP_OK; - if (!item || !json_string) { - return ESP_ERR_INVALID_ARG; - } - cJSON* cjson_item = cJSON_CreateObject(); - if (!cjson_item) { - ESP_LOGE(TAG, "Memory allocation failure. Cannot save ap json"); - return ESP_ERR_NO_MEM; - } - cJSON_AddStringToObject(cjson_item, "ssid", item->ssid); - cJSON_AddStringToObject(cjson_item, "pass", item->password); - cJSON_AddNumberToObject(cjson_item, "chan", item->primary); - cJSON_AddNumberToObject(cjson_item, "auth", item->authmode); - char* bssid = network_manager_alloc_get_mac_string(item->bssid); - if (bssid) { - cJSON_AddItemToObject(cjson_item, "bssid", cJSON_CreateString(STR_OR_BLANK(bssid))); - } - FREE_AND_NULL(bssid); - cJSON_AddNumberToObject(cjson_item, "b", item->phy_11b ? 1 : 0); - cJSON_AddNumberToObject(cjson_item, "g", item->phy_11g ? 1 : 0); - cJSON_AddNumberToObject(cjson_item, "n", item->phy_11n ? 1 : 0); - cJSON_AddNumberToObject(cjson_item, "low_rate", item->phy_lr ? 1 : 0); - - *json_string = cJSON_PrintUnformatted(cjson_item); - if (!*json_string) { - ESP_LOGE(TAG, "Memory allocaiton failed. Cannot save ap entry."); - err = ESP_ERR_NO_MEM; - } - cJSON_Delete(cjson_item); - return err; -} bool network_wifi_str2mac(const char* mac, uint8_t* values) { - if (6 == sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &values[0], &values[1], &values[2], &values[3], &values[4], &values[5])) { + if (6 == sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &values[0], &values[1], &values[2], + &values[3], &values[4], &values[5])) { return true; } else { return false; } } -esp_err_t network_wifi_add_json_entry(const char* json_text) { - esp_err_t err = ESP_OK; - known_access_point_t known_ap; - if (!json_text || strlen(json_text) == 0) { - ESP_LOGE(TAG, "Invalid access point json"); - return ESP_ERR_INVALID_ARG; - } - cJSON* cjson_item = cJSON_Parse(json_text); - if (!cjson_item) { - ESP_LOGE(TAG, "Invalid JSON %s", json_text); - return ESP_ERR_INVALID_ARG; - } - cJSON* value = cJSON_GetObjectItemCaseSensitive(cjson_item, "ssid"); - if (!value || !cJSON_IsString(value) || strlen(cJSON_GetStringValue(value)) == 0) { - ESP_LOGE(TAG, "Missing ssid in : %s", json_text); - err = ESP_ERR_INVALID_ARG; - } else { - if (!network_wifi_get_ap_entry(cJSON_GetStringValue(value))) { - known_ap.ssid = strdup_psram(cJSON_GetStringValue(value)); - value = cJSON_GetObjectItemCaseSensitive(cjson_item, "pass"); - if (value && cJSON_IsString(value) && strlen(cJSON_GetStringValue(value)) > 0) { - known_ap.password = strdup_psram(cJSON_GetStringValue(value)); - } - value = cJSON_GetObjectItemCaseSensitive(cjson_item, "chan"); - if (value) { - known_ap.primary = value->valueint; - } - value = cJSON_GetObjectItemCaseSensitive(cjson_item, "auth"); - if (value) { - known_ap.authmode = value->valueint; - } - value = cJSON_GetObjectItemCaseSensitive(cjson_item, "b"); - if (value) { - known_ap.phy_11b = value->valueint; - } - value = cJSON_GetObjectItemCaseSensitive(cjson_item, "g"); - if (value) { - known_ap.phy_11g = value->valueint; - } - value = cJSON_GetObjectItemCaseSensitive(cjson_item, "n"); - if (value) { - known_ap.phy_11n = value->valueint; - } - value = cJSON_GetObjectItemCaseSensitive(cjson_item, "low_rate"); - if (value) { - known_ap.phy_lr = value->valueint; - } - value = cJSON_GetObjectItemCaseSensitive(cjson_item, "bssid"); - if (value && cJSON_IsString(value) && strlen(cJSON_GetStringValue(value)) > 0) { - network_wifi_str2mac(cJSON_GetStringValue(value), known_ap.bssid); - } - err = network_wifi_add_ap_copy(&known_ap); - } else { - ESP_LOGE(TAG, "Duplicate ssid %s found in storage", cJSON_GetStringValue(value)); - } - } - cJSON_Delete(cjson_item); - return err; -} -esp_err_t network_wifi_delete_ap(const char* key) { - esp_err_t esp_err = ESP_OK; - if (!key || strlen(key) == 0) { - ESP_LOGE(TAG, "SSID Empty. Cannot remove "); - return ESP_ERR_INVALID_ARG; - } - - known_access_point_t* it = network_wifi_get_ap_entry(key); - if (!it) { - ESP_LOGE(TAG, "Unknown AP entry"); - return ESP_ERR_INVALID_ARG; - } - - /* - * Check if we're deleting the active network - */ - ESP_LOGD(TAG, "Deleting AP %s. Checking if this is the active AP", key); - const wifi_sta_config_t* config = network_wifi_load_active_config(); - if (config && strlen(ssid_string(config)) > 0 && strcmp(ssid_string(config), it->ssid) == 0) { - ESP_LOGD(TAG, "Confirmed %s to be the active network. Removing it from flash.", key); - esp_err = network_wifi_erase_legacy(); - if (esp_err != ESP_OK) { - ESP_LOGW(TAG, "Legacy network details could not be removed from flash : %s", esp_err_to_name(esp_err)); - } - } - ESP_LOGD(TAG, "Removing network %s from the flash AP list", key); - esp_err = erase_nvs_for_partition(NVS_DEFAULT_PART_NAME, ap_list_nsv_namespace, it->ssid); - if (esp_err != ESP_OK) { - messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Deleting network entry %s error (%s). Error %s", key, ap_list_nsv_namespace, esp_err_to_name(esp_err)); - } - ESP_LOGD(TAG, "Removing network %s from the known AP list", key); - network_wifi_remove_ap_entry(it->ssid); - return esp_err; -} - -esp_err_t network_wifi_erase_legacy() { - esp_err_t err = erase_nvs_partition(NVS_DEFAULT_PART_NAME, network_wifi_nvs_namespace); - if (err == ESP_OK) { - ESP_LOGW(TAG, "Erased wifi configuration. Disconnecting from network"); - if ((err = esp_wifi_disconnect()) != ESP_OK) { - ESP_LOGW(TAG, "Could not disconnect from deleted network : %s", esp_err_to_name(err)); - } - } - return err; -} - esp_err_t network_wifi_erase_known_ap() { network_wifi_empty_known_list(); - esp_err_t err = erase_nvs_partition(NVS_DEFAULT_PART_NAME, ap_list_nsv_namespace); - return err; + return ESP_OK; } -esp_err_t network_wifi_write_ap(const char* key, const char* value, size_t size) { - size_t size_override = size > 0 ? size : strlen(value) + 1; - esp_err_t esp_err = store_nvs_value_len_for_partition(NVS_DEFAULT_PART_NAME, ap_list_nsv_namespace, NVS_TYPE_BLOB, key, value, size_override); - if (esp_err != ESP_OK) { - messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "%s (%s). Error %s", key, network_wifi_nvs_namespace, esp_err_to_name(esp_err)); - } - return esp_err; -} -esp_err_t network_wifi_write_nvs(const char* key, const char* value, size_t size) { - size_t size_override = size > 0 ? size : strlen(value) + 1; - esp_err_t esp_err = store_nvs_value_len_for_partition(NVS_DEFAULT_PART_NAME, network_wifi_nvs_namespace, NVS_TYPE_BLOB, key, value, size_override); - if (esp_err != ESP_OK) { - messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "%s (%s). Error %s", key, network_wifi_nvs_namespace, esp_err_to_name(esp_err)); - } - return esp_err; -} -esp_err_t network_wifi_store_ap_json(known_access_point_t* item) { - esp_err_t err = ESP_OK; - size_t size = 0; - char* json_string = NULL; - const wifi_sta_config_t* sta = network_wifi_get_active_config(); - - if ((err = network_wifi_alloc_ap_json(item, &json_string)) == ESP_OK) { - // get any existing entry from the nvs and compare - char* existing = get_nvs_value_alloc_for_partition(NVS_DEFAULT_PART_NAME, ap_list_nsv_namespace, NVS_TYPE_BLOB, item->ssid, &size); - if (!existing || strncmp(existing, json_string, strlen(json_string)) != 0) { - ESP_LOGI(TAG, "SSID %s was changed or is new. Committing to flash", item->ssid); - err = network_wifi_write_ap(item->ssid, json_string, 0); - if (sta && strlen(ssid_string(sta)) > 0 && strcmp(ssid_string(sta), item->ssid) == 0) { - ESP_LOGI(TAG, "Committing active access point"); - err = network_wifi_write_nvs("ssid", ssid_string(sta), 0); - if (err == ESP_OK) { - err = network_wifi_write_nvs("password", STR_OR_BLANK(password_string(sta)), 0); - } - if (err != ESP_OK) { - ESP_LOGE(TAG, "Error committing active access point : %s", esp_err_to_name(err)); - } - } - } - FREE_AND_NULL(existing); - FREE_AND_NULL(json_string); - } - return err; -} - -esp_netif_t* network_wifi_get_interface() { - return wifi_netif; -} -esp_netif_t* network_wifi_get_ap_interface() { - return wifi_ap_netif; -} +esp_netif_t* network_wifi_get_interface() { return wifi_netif; } +esp_netif_t* network_wifi_get_ap_interface() { return wifi_ap_netif; } esp_err_t network_wifi_set_sta_mode() { if (!wifi_netif) { ESP_LOGE(TAG, "Wifi not initialized. Cannot set sta mode"); @@ -493,8 +367,7 @@ esp_err_t network_wifi_set_sta_mode() { return err; } esp_netif_t* network_wifi_start() { - MEMTRACE_PRINT_DELTA_MESSAGE( "Starting wifi interface as STA mode"); - accessp_cjson = network_manager_clear_ap_list_json(&accessp_cjson); + MEMTRACE_PRINT_DELTA_MESSAGE("Starting wifi interface as STA mode"); if (!wifi_netif) { MEMTRACE_PRINT_DELTA_MESSAGE("Init STA mode - creating default interface. "); wifi_netif = esp_netif_create_default_wifi_sta(); @@ -502,12 +375,9 @@ esp_netif_t* network_wifi_start() { wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK_WITHOUT_ABORT(esp_wifi_init(&cfg)); MEMTRACE_PRINT_DELTA_MESSAGE("Registering wifi Handlers"); - //network_wifi_register_handlers(); - ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_instance_register(WIFI_EVENT, - ESP_EVENT_ANY_ID, - &network_wifi_event_handler, - NULL, - NULL)); + // network_wifi_register_handlers(); + ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_instance_register( + WIFI_EVENT, ESP_EVENT_ANY_ID, &network_wifi_event_handler, NULL, NULL)); MEMTRACE_PRINT_DELTA_MESSAGE("Setting up wifi Storage"); ESP_ERROR_CHECK_WITHOUT_ABORT(esp_wifi_set_storage(WIFI_STORAGE_RAM)); } @@ -519,17 +389,15 @@ esp_netif_t* network_wifi_start() { return wifi_netif; } void destroy_network_wifi() { - cJSON_Delete(accessp_cjson); - accessp_cjson = NULL; + } bool network_wifi_sta_config_changed() { bool changed = true; const wifi_sta_config_t* sta = network_wifi_get_active_config(); - if (!sta || strlen(ssid_string(sta)) == 0) - return false; + if (!sta || strlen(ssid_string(sta)) == 0) return false; - known_access_point_t* known = network_wifi_get_ap_entry(ssid_string(sta)); + sys_WifiSTAEntry* known = network_wifi_get_ap_entry(ssid_string(sta)); if (known && strcmp(known->ssid, ssid_string(sta)) == 0 && strcmp((char*)known->password, password_string(sta)) == 0) { changed = false; @@ -539,394 +407,232 @@ bool network_wifi_sta_config_changed() { return changed; } -esp_err_t network_wifi_save_sta_config() { - esp_err_t esp_err = ESP_OK; - known_access_point_t* item = NULL; - MEMTRACE_PRINT_DELTA_MESSAGE("Config Save"); - const wifi_sta_config_t* sta = network_wifi_get_active_config(); - if (sta && strlen(ssid_string(sta)) > 0) { - MEMTRACE_PRINT_DELTA_MESSAGE("Checking if current SSID is known"); - item = network_wifi_get_ap_entry(ssid_string(sta)); - if (!item) { - ESP_LOGD(TAG,"New SSID %s found", ssid_string(sta)); - // this is a new access point. First add it to the end of the AP list - esp_err = network_wifi_add_ap_from_sta_copy(sta); - } - } - // now traverse the list and commit - MEMTRACE_PRINT_DELTA_MESSAGE("Saving all known ap as json strings"); - known_access_point_t* it; - SLIST_FOREACH(it, &s_ap_list, next) { - if ((esp_err = network_wifi_store_ap_json(it)) != ESP_OK) { - ESP_LOGW(TAG, "Error saving wifi ap entry %s : %s", it->ssid, esp_err_to_name(esp_err)); - break; - } - } - return esp_err; -} - -void network_wifi_load_known_access_points() { - esp_err_t esp_err; - size_t size = 0; - if (network_wifi_get_known_count() > 0) { - ESP_LOGW(TAG, "Access points already loaded"); - return; - } - nvs_iterator_t it = nvs_entry_find(NVS_DEFAULT_PART_NAME, ap_list_nsv_namespace, NVS_TYPE_ANY); - if (it == NULL) { - ESP_LOGW(TAG, "No known access point found"); - return; - } - do { - nvs_entry_info_t info; - nvs_entry_info(it, &info); - if (strstr(info.namespace_name, ap_list_nsv_namespace)) { - void* value = get_nvs_value_alloc_for_partition(NVS_DEFAULT_PART_NAME, ap_list_nsv_namespace, info.type, info.key, &size); - if (value == NULL) { - ESP_LOGE(TAG, "nvs read failed for %s.", info.key); - } else if ((esp_err = network_wifi_add_json_entry(value)) != ESP_OK) { - ESP_LOGE(TAG, "Invalid entry or error for %s.", (char*)value); - } - FREE_AND_NULL(value); - } - it = nvs_entry_next(it); - } while (it != NULL); - - return; -} - -esp_err_t network_wifi_get_blob(void* target, size_t size, const char* key) { - esp_err_t esp_err = ESP_OK; - size_t found_size = 0; - if (!target) { - ESP_LOGE(TAG, "%s invalid target pointer", __FUNCTION__); - return ESP_ERR_INVALID_ARG; - } - memset(target, 0x00, size); - char* value = (char*)get_nvs_value_alloc_for_partition(NVS_DEFAULT_PART_NAME, network_wifi_nvs_namespace, NVS_TYPE_BLOB, key, &found_size); - if (!value) { - ESP_LOGD(TAG,"nvs key %s not found.", key); - esp_err = ESP_FAIL; - } else { - memcpy((char*)target, value, size > found_size ? found_size : size); - FREE_AND_NULL(value); - ESP_LOGD(TAG,"Successfully loaded key %s", key); - } - return esp_err; -} -const wifi_sta_config_t* network_wifi_load_active_config() { - static wifi_sta_config_t config; - esp_err_t esp_err = ESP_OK; - memset(&config, 0x00, sizeof(config)); - config.scan_method = WIFI_ALL_CHANNEL_SCAN; - MEMTRACE_PRINT_DELTA_MESSAGE("Fetching wifi sta config - ssid."); - esp_err = network_wifi_get_blob(&config.ssid, sizeof(config.ssid), "ssid"); - if (esp_err == ESP_OK && strlen((char*)config.ssid) > 0) { - ESP_LOGD(TAG,"network_wifi_load_active_config: ssid:%s. Fetching password (if any) ", ssid_string(&config)); - if (network_wifi_get_blob(&config.password, sizeof(config.password), "password") != ESP_OK) { - ESP_LOGW(TAG, "No wifi password found in nvs"); - } - } else { - if(network_wifi_get_known_count() > 0) { - ESP_LOGW(TAG, "No wifi ssid found in nvs, but known access points found. Using first known access point."); - known_access_point_t* ap = SLIST_FIRST(&s_ap_list); - if (ap) { - strncpy((char*)&config.ssid, ap->ssid, sizeof(config.ssid)); - strncpy((char*)&config.password, ap->password, sizeof(config.password)); - } - esp_err = ESP_OK; - } else { - ESP_LOGW(TAG, "network manager has no previous configuration. %s", esp_err_to_name(esp_err)); - return NULL; - } - } - return &config; -} -bool network_wifi_load_wifi_sta_config() { - network_wifi_load_known_access_points(); - const wifi_sta_config_t* config = network_wifi_load_active_config(); - if (config) { - known_access_point_t* item = network_wifi_get_ap_entry(ssid_string(config)); - if (!item) { - ESP_LOGI(TAG, "Adding legacy/active wifi connection to the known list"); - network_wifi_add_ap_from_sta_copy(config); - } - } - return config && config->ssid[0] != '\0'; -} -bool network_wifi_get_config_for_ssid(wifi_config_t* config, const char* ssid) { - known_access_point_t* item = network_wifi_get_ap_entry(ssid); - if (!item) { - ESP_LOGE(TAG, "Unknown ssid %s", ssid); - return false; - } - memset(&config->ap, 0x00, sizeof(config->ap)); - strncpy((char*)config->ap.ssid, item->ssid, sizeof(config->ap.ssid)); - strncpy((char*)config->ap.password, item->password, sizeof(config->ap.ssid)); - config->sta.scan_method = WIFI_ALL_CHANNEL_SCAN; - return true; -} - -static void network_wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - if (event_base != WIFI_EVENT) - return; +static void network_wifi_event_handler( + void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { + if (event_base != WIFI_EVENT) return; switch (event_id) { - case WIFI_EVENT_WIFI_READY: - ESP_LOGD(TAG, "WIFI_EVENT_WIFI_READY"); - break; + case WIFI_EVENT_WIFI_READY: + ESP_LOGD(TAG, "WIFI_EVENT_WIFI_READY"); + break; - case WIFI_EVENT_SCAN_DONE: - ESP_LOGD(TAG, "WIFI_EVENT_SCAN_DONE"); - network_async_scan_done(); - break; + case WIFI_EVENT_SCAN_DONE: + ESP_LOGD(TAG, "WIFI_EVENT_SCAN_DONE"); + network_async_scan_done(); + break; - case WIFI_EVENT_STA_AUTHMODE_CHANGE: - ESP_LOGD(TAG, "WIFI_EVENT_STA_AUTHMODE_CHANGE"); - break; + case WIFI_EVENT_STA_AUTHMODE_CHANGE: + ESP_LOGD(TAG, "WIFI_EVENT_STA_AUTHMODE_CHANGE"); + break; - case WIFI_EVENT_AP_START: - ESP_LOGD(TAG, "WIFI_EVENT_AP_START"); - break; + case WIFI_EVENT_AP_START: + ESP_LOGD(TAG, "WIFI_EVENT_AP_START"); + break; - case WIFI_EVENT_AP_STOP: - ESP_LOGD(TAG, "WIFI_EVENT_AP_STOP"); - break; + case WIFI_EVENT_AP_STOP: + ESP_LOGD(TAG, "WIFI_EVENT_AP_STOP"); + break; - case WIFI_EVENT_AP_PROBEREQRECVED: { - wifi_event_ap_probe_req_rx_t* s = (wifi_event_ap_probe_req_rx_t*)event_data; - char* mac = network_manager_alloc_get_mac_string(s->mac); - if (mac) { - ESP_LOGD(TAG, "WIFI_EVENT_AP_PROBEREQRECVED. RSSI: %d, MAC: %s", s->rssi, STR_OR_BLANK(mac)); - } - FREE_AND_NULL(mac); - } break; - case WIFI_EVENT_STA_WPS_ER_SUCCESS: - ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_SUCCESS"); - break; - case WIFI_EVENT_STA_WPS_ER_FAILED: - ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_FAILED"); - break; - case WIFI_EVENT_STA_WPS_ER_TIMEOUT: - ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_TIMEOUT"); - break; - case WIFI_EVENT_STA_WPS_ER_PIN: - ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_PIN"); - break; - case WIFI_EVENT_AP_STACONNECTED: { - wifi_event_ap_staconnected_t* stac = (wifi_event_ap_staconnected_t*)event_data; - char* mac = network_manager_alloc_get_mac_string(stac->mac); - if (mac) { - ESP_LOGD(TAG, "WIFI_EVENT_AP_STACONNECTED. aid: %d, mac: %s", stac->aid, STR_OR_BLANK(mac)); - } - FREE_AND_NULL(mac); - } break; - case WIFI_EVENT_AP_STADISCONNECTED: - ESP_LOGD(TAG, "WIFI_EVENT_AP_STADISCONNECTED"); - break; + case WIFI_EVENT_AP_PROBEREQRECVED: { + wifi_event_ap_probe_req_rx_t* s = (wifi_event_ap_probe_req_rx_t*)event_data; + char* mac = network_manager_alloc_get_mac_string(s->mac); + if (mac) { + ESP_LOGD( + TAG, "WIFI_EVENT_AP_PROBEREQRECVED. RSSI: %d, MAC: %s", s->rssi, STR_OR_BLANK(mac)); + } + FREE_AND_NULL(mac); + } break; + case WIFI_EVENT_STA_WPS_ER_SUCCESS: + ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_SUCCESS"); + break; + case WIFI_EVENT_STA_WPS_ER_FAILED: + ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_FAILED"); + break; + case WIFI_EVENT_STA_WPS_ER_TIMEOUT: + ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_TIMEOUT"); + break; + case WIFI_EVENT_STA_WPS_ER_PIN: + ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_PIN"); + break; + case WIFI_EVENT_AP_STACONNECTED: { + wifi_event_ap_staconnected_t* stac = (wifi_event_ap_staconnected_t*)event_data; + char* mac = network_manager_alloc_get_mac_string(stac->mac); + if (mac) { + ESP_LOGD( + TAG, "WIFI_EVENT_AP_STACONNECTED. aid: %d, mac: %s", stac->aid, STR_OR_BLANK(mac)); + } + FREE_AND_NULL(mac); + } break; + case WIFI_EVENT_AP_STADISCONNECTED: + ESP_LOGD(TAG, "WIFI_EVENT_AP_STADISCONNECTED"); + break; - case WIFI_EVENT_STA_START: - ESP_LOGD(TAG, "WIFI_EVENT_STA_START"); - break; + case WIFI_EVENT_STA_START: + ESP_LOGD(TAG, "WIFI_EVENT_STA_START"); + break; - case WIFI_EVENT_STA_STOP: - ESP_LOGD(TAG, "WIFI_EVENT_STA_STOP"); - break; + case WIFI_EVENT_STA_STOP: + ESP_LOGD(TAG, "WIFI_EVENT_STA_STOP"); + break; - case WIFI_EVENT_STA_CONNECTED: { - ESP_LOGD(TAG, "WIFI_EVENT_STA_CONNECTED. "); - wifi_event_sta_connected_t* s = (wifi_event_sta_connected_t*)event_data; - char* bssid = network_manager_alloc_get_mac_string(s->bssid); - char* ssid = strdup_psram((char*)s->ssid); - if (bssid && ssid) { - ESP_LOGD(TAG, "WIFI_EVENT_STA_CONNECTED. Channel: %d, Access point: %s, BSSID: %s ", s->channel, STR_OR_BLANK(ssid), (bssid)); - } - FREE_AND_NULL(bssid); - FREE_AND_NULL(ssid); - network_async(EN_CONNECTED); - - } break; - - case WIFI_EVENT_STA_DISCONNECTED: { - // structwifi_event_sta_disconnected_t - // Argument structure for WIFI_EVENT_STA_DISCONNECTED event - // - // Public Members - // - // uint8_t ssid[32] - // SSID of disconnected AP - // - // uint8_t ssid_len - // SSID length of disconnected AP - // - // uint8_t bssid[6] - // BSSID of disconnected AP - // - // uint8_t reason - // reason of disconnection - wifi_event_sta_disconnected_t* s = (wifi_event_sta_disconnected_t*)event_data; - char* bssid = network_manager_alloc_get_mac_string(s->bssid); - ESP_LOGW(TAG, "WIFI_EVENT_STA_DISCONNECTED. From BSSID: %s, reason code: %d (%s)", STR_OR_BLANK(bssid), s->reason, get_disconnect_code_desc(s->reason)); - FREE_AND_NULL(bssid); - if (s->reason == WIFI_REASON_ROAMING) { - ESP_LOGI(TAG, "WiFi Roaming to new access point"); - } else { - network_async_lost_connection((wifi_event_sta_disconnected_t*)event_data); - } - } break; - - default: - break; - } -} - -cJSON* network_wifi_get_new_array_json(cJSON** old) { - ESP_LOGV(TAG, "network_wifi_get_new_array_json called"); - cJSON* root = *old; - if (root != NULL) { - cJSON_Delete(root); - *old = NULL; - } - ESP_LOGV(TAG, "network_wifi_get_new_array_json done"); - return cJSON_CreateArray(); -} -void network_wifi_global_init() { - network_wifi_get_new_array_json(&accessp_cjson); - ESP_LOGD(TAG, "Loading existing wifi configuration (if any)"); - network_wifi_load_wifi_sta_config(); -} -void network_wifi_add_access_point_json(cJSON* ap_list, wifi_ap_record_t* ap_rec) { - cJSON* ap = cJSON_CreateObject(); - if (ap == NULL) { - ESP_LOGE(TAG, "Unable to allocate memory for access point %s", ap_rec->ssid); - return; - } - cJSON* radio = cJSON_CreateObject(); - if (radio == NULL) { - ESP_LOGE(TAG, "Unable to allocate memory for access point %s", ap_rec->ssid); - cJSON_Delete(ap); - return; - } - cJSON_AddItemToObject(ap, "ssid", cJSON_CreateString(ap_ssid_string(ap_rec))); - cJSON_AddBoolToObject(ap, "known", network_wifi_is_known_ap(ap_ssid_string(ap_rec))); - if (ap_rec->rssi != 0) { - // only add the rest of the details when record doesn't come from - // "known" access points that aren't in range - cJSON_AddNumberToObject(ap, "chan", ap_rec->primary); - cJSON_AddNumberToObject(ap, "rssi", ap_rec->rssi); - cJSON_AddNumberToObject(ap, "auth", ap_rec->authmode); - - char* bssid = network_manager_alloc_get_mac_string(ap_rec->bssid); - if (bssid) { - cJSON_AddItemToObject(ap, "bssid", cJSON_CreateString(STR_OR_BLANK(bssid))); + case WIFI_EVENT_STA_CONNECTED: { + ESP_LOGD(TAG, "WIFI_EVENT_STA_CONNECTED. "); + wifi_event_sta_connected_t* s = (wifi_event_sta_connected_t*)event_data; + char* bssid = network_manager_alloc_get_mac_string(s->bssid); + char* ssid = strdup_psram((char*)s->ssid); + if (bssid && ssid) { + ESP_LOGD(TAG, "WIFI_EVENT_STA_CONNECTED. Channel: %d, Access point: %s, BSSID: %s ", + s->channel, STR_OR_BLANK(ssid), (bssid)); + network_wifi_update_connected(ssid); + } FREE_AND_NULL(bssid); - cJSON_AddNumberToObject(radio, "b", ap_rec->phy_11b ? 1 : 0); - cJSON_AddNumberToObject(radio, "g", ap_rec->phy_11g ? 1 : 0); - cJSON_AddNumberToObject(radio, "n", ap_rec->phy_11n ? 1 : 0); - cJSON_AddNumberToObject(radio, "low_rate", ap_rec->phy_lr ? 1 : 0); - cJSON_AddItemToObject(ap, "radio", radio); - } - cJSON_AddItemToArray(ap_list, ap); - char* ap_json = cJSON_PrintUnformatted(ap); - if (ap_json != NULL) { - ESP_LOGD(TAG, "New access point found: %s", ap_json); - free(ap_json); - } -} -void network_wifi_generate_access_points_json(cJSON** ap_list) { - *ap_list = network_wifi_get_new_array_json(ap_list); - wifi_ap_record_t known_ap; - known_access_point_t* it; - if (*ap_list == NULL) - return; - for (int i = 0; i < ap_num; i++) { - network_wifi_add_access_point_json(*ap_list, &accessp_records[i]); - } - SLIST_FOREACH(it, &s_ap_list, next) { - if (!network_wifi_was_ssid_seen(it->ssid)) { - memset(&known_ap, 0x00, sizeof(known_ap)); - strlcpy((char*)known_ap.ssid, it->ssid, sizeof(known_ap.ssid)); - ESP_LOGD(TAG, "Adding known access point that is not in range: %s", it->ssid); - network_wifi_add_access_point_json(*ap_list, &known_ap); + FREE_AND_NULL(ssid); + network_async(EN_CONNECTED); + + } break; + + case WIFI_EVENT_STA_DISCONNECTED: { + // structwifi_event_sta_disconnected_t + // Argument structure for WIFI_EVENT_STA_DISCONNECTED event + // + // Public Members + // + // uint8_t ssid[32] + // SSID of disconnected AP + // + // uint8_t ssid_len + // SSID length of disconnected AP + // + // uint8_t bssid[6] + // BSSID of disconnected AP + // + // uint8_t reason + // reason of disconnection + wifi_event_sta_disconnected_t* s = (wifi_event_sta_disconnected_t*)event_data; + char* bssid = network_manager_alloc_get_mac_string(s->bssid); + ESP_LOGW(TAG, "WIFI_EVENT_STA_DISCONNECTED. From BSSID: %s, reason code: %d (%s)", + STR_OR_BLANK(bssid), s->reason, get_disconnect_code_desc(s->reason)); + FREE_AND_NULL(bssid); + if (s->reason == WIFI_REASON_ROAMING) { + ESP_LOGI(TAG, "WiFi Roaming to new access point"); + } else { + network_async_lost_connection((wifi_event_sta_disconnected_t*)event_data); } - } - char* ap_list_json = cJSON_PrintUnformatted(*ap_list); - if (ap_list_json != NULL) { - ESP_LOGV(TAG, "Full access point list: %s", ap_list_json); - free(ap_list_json); + } break; + + default: + break; } } -void network_wifi_set_ipv4val(const char* key, char* default_value, ip4_addr_t* target) { - char* value = config_alloc_get_default(NVS_TYPE_STR, key, default_value, 0); - if (value != NULL) { - ESP_LOGD(TAG, "%s: %s", key, value); - inet_pton(AF_INET, value, target); /* access point is on a static IP */ - } - FREE_AND_NULL(value); +void network_wifi_write_file(const char * filename, sys_Status * status_struct){ + FILE* file = open_file("wb", filename); + pb_ostream_t filestream = {&out_file_binding, file, SIZE_MAX, 0}; + ESP_LOGD(TAG, "Starting encode"); + if (!pb_encode(&filestream, sys_Config_fields, (void*)&status)) { + ESP_LOGE(TAG, "Encoding failed: %s\n", PB_GET_ERROR(&filestream)); + } + fclose(file); } +void network_wifi_global_init() { + pb_istream_t istream =PB_ISTREAM_EMPTY; + ESP_LOGD(TAG, "Loading existing wifi configuration (if any)"); + FILE* file = open_file("rb", status_file_name); + if (!file) { + network_wifi_write_file(status_file_name,&status); + file = open_file("rb", status_file_name); + } + if (!file) { + ESP_LOGE(TAG, "Unable to read status file"); + return; + } + + istream.callback = &in_file_binding; + istream.state = file; + pb_decode(&istream, &sys_Status_msg, &status); + fclose(file); +} + esp_netif_t* network_wifi_config_ap() { esp_netif_ip_info_t info; esp_err_t err = ESP_OK; - char* value = NULL; wifi_config_t ap_config = { - .ap = { - .ssid_len = 0, + .ap = {.ssid_len = 0, + .authmode = AP_AUTHMODE, + .ssid_hidden = DEFAULT_AP_SSID_HIDDEN, + .max_connection = DEFAULT_AP_MAX_CONNECTIONS, + .beacon_interval = DEFAULT_AP_BEACON_INTERVAL + }, }; ESP_LOGI(TAG, "Configuring Access Point."); if (!wifi_ap_netif) { wifi_ap_netif = esp_netif_create_default_wifi_ap(); } + if (platform->has_net && platform->net.has_ap && platform->net.ap.has_ip) { + inet_pton(AF_INET, platform->net.ap.ip.ip, + (ip4_addr_t*)&info.ip); /* access point is on a static IP */ + inet_pton(AF_INET, platform->net.ap.ip.gw, + (ip4_addr_t*)&info.gw); /* access point is on a static IP */ + inet_pton(AF_INET, platform->net.ap.ip.netmask, + (ip4_addr_t*)&info.netmask); /* access point is on a static IP */ + } else { + inet_pton( + AF_INET, DEFAULT_AP_IP, (ip4_addr_t*)&info.ip); /* access point is on a static IP */ + inet_pton(AF_INET, CONFIG_DEFAULT_AP_GATEWAY, + (ip4_addr_t*)&info.gw); /* access point is on a static IP */ + inet_pton(AF_INET, CONFIG_DEFAULT_AP_NETMASK, + (ip4_addr_t*)&info.netmask); /* access point is on a st */ + } - network_wifi_set_ipv4val("ap_ip_address", DEFAULT_AP_IP, (ip4_addr_t*)&info.ip); - network_wifi_set_ipv4val("ap_ip_gateway", CONFIG_DEFAULT_AP_GATEWAY, (ip4_addr_t*)&info.gw); - network_wifi_set_ipv4val("ap_ip_netmask", CONFIG_DEFAULT_AP_NETMASK, (ip4_addr_t*)&info.netmask); - /* In order to change the IP info structure, we have to first stop - * the DHCP server on the new interface - */ + /* In order to change the IP info structure, we have to first stop + * the DHCP server on the new interface + */ network_start_stop_dhcps(wifi_ap_netif, false); ESP_LOGD(TAG, "Setting tcp_ip info for access point"); if ((err = esp_netif_set_ip_info(wifi_ap_netif, &info)) != ESP_OK) { - ESP_LOGE(TAG, "Setting tcp_ip info for interface TCPIP_ADAPTER_IF_AP. Error %s", esp_err_to_name(err)); + ESP_LOGE(TAG, "Setting tcp_ip info for interface TCPIP_ADAPTER_IF_AP. Error %s", + esp_err_to_name(err)); return wifi_ap_netif; } network_start_stop_dhcps(wifi_ap_netif, true); /* - * Set Access Point configuration - */ - value = config_alloc_get_default(NVS_TYPE_STR, "ap_ssid", CONFIG_DEFAULT_AP_SSID, 0); - if (value != NULL) { - strlcpy((char*)ap_config.ap.ssid, value, sizeof(ap_config.ap.ssid)); - ESP_LOGI(TAG, "AP SSID: %s", (char*)ap_config.ap.ssid); + * Set Access Point configuration + */ + const char* ap_ssid = CONFIG_DEFAULT_AP_SSID; + if (platform->has_names && strlen(platform->names.wifi_ap_name) > 0) { + ap_ssid = platform->names.wifi_ap_name; } - FREE_AND_NULL(value); - - value = config_alloc_get_default(NVS_TYPE_STR, "ap_pwd", DEFAULT_AP_PASSWORD, 0); - if (value != NULL) { - strlcpy((char*)ap_config.ap.password, value, sizeof(ap_config.ap.password)); - ESP_LOGI(TAG, "AP Password: %s", (char*)ap_config.ap.password); + const char* ap_password = DEFAULT_AP_PASSWORD; + ap_config.ap.channel = CONFIG_DEFAULT_AP_CHANNEL; + if (platform->has_net && platform->net.has_ap) { + if (strlen(platform->net.ap.password) > 0) { + ap_password = platform->net.ap.password; + } + if (platform->net.ap.channel > 0) { + ap_config.ap.channel = platform->net.ap.channel; + } + if (platform->net.ap.auth_mode != sys_WifiAuthTypeEnum_AUTH_UNKNOWN) { + ap_config.ap.authmode = network_wifi_get_auth_mode(platform->net.ap.auth_mode); + } + ap_config.ap.ssid_hidden = platform->net.ap.hidden; + if (platform->net.ap.max_connection > 0) { + ap_config.ap.max_connection = platform->net.ap.max_connection; + } + if (platform->net.ap.beacon_interval > 0) { + ap_config.ap.beacon_interval = platform->net.ap.beacon_interval; + } } - FREE_AND_NULL(value); - value = config_alloc_get_default(NVS_TYPE_STR, "ap_channel", STR(CONFIG_DEFAULT_AP_CHANNEL), 0); - if (value != NULL) { - ESP_LOGD(TAG, "Channel: %s", value); - ap_config.ap.channel = atoi(value); - } - FREE_AND_NULL(value); - - ap_config.ap.authmode = AP_AUTHMODE; - ap_config.ap.ssid_hidden = DEFAULT_AP_SSID_HIDDEN; - ap_config.ap.max_connection = DEFAULT_AP_MAX_CONNECTIONS; - ap_config.ap.beacon_interval = DEFAULT_AP_BEACON_INTERVAL; - - ESP_LOGD(TAG, "Auth Mode: %d", ap_config.ap.authmode); - ESP_LOGD(TAG, "SSID Hidden: %d", ap_config.ap.ssid_hidden); - ESP_LOGD(TAG, "Max Connections: %d", ap_config.ap.max_connection); - ESP_LOGD(TAG, "Beacon interval: %d", ap_config.ap.beacon_interval); + strlcpy((char*)ap_config.ap.ssid, ap_ssid, sizeof(ap_config.ap.ssid)); + strlcpy((char*)ap_config.ap.password, ap_password, sizeof(ap_config.ap.password)); + ESP_LOGI(TAG, + "AP SSID: %s, PASSWORD: %s Auth Mode: %d SSID: %s Max Connections: %d Beacon interval: %d", + (char*)ap_config.ap.ssid, (char*)ap_config.ap.password, ap_config.ap.authmode, + ap_config.ap.ssid_hidden ? "HIDDEN" : "VISIBLE", ap_config.ap.max_connection, + ap_config.ap.beacon_interval); const char* msg = "Setting wifi mode as WIFI_MODE_APSTA"; ESP_LOGD(TAG, "%s", msg); @@ -944,7 +650,8 @@ esp_netif_t* network_wifi_config_ap() { msg = "Setting wifi bandwidth"; ESP_LOGD(TAG, "%s (%d)", msg, DEFAULT_AP_BANDWIDTH); - if ((err = esp_wifi_set_bandwidth(WIFI_IF_AP, DEFAULT_AP_BANDWIDTH)) != ESP_OK) /* stop AP DHCP server */ + if ((err = esp_wifi_set_bandwidth(WIFI_IF_AP, DEFAULT_AP_BANDWIDTH)) != ESP_OK) /* stop AP + DHCP server */ { ESP_LOGE(TAG, "%s failed. Error %s", msg, esp_err_to_name(err)); return wifi_ap_netif; @@ -958,7 +665,6 @@ esp_netif_t* network_wifi_config_ap() { ESP_LOGE(TAG, "%s failed. Error %s", msg, esp_err_to_name(err)); return wifi_ap_netif; } - ESP_LOGD(TAG, "Done configuring Soft Access Point"); return wifi_ap_netif; } @@ -974,8 +680,7 @@ void network_wifi_filter_unique(wifi_ap_record_t* aplist, uint16_t* aps) { wifi_ap_record_t* ap = &aplist[i]; /* skip the previously removed APs */ - if (ap->ssid[0] == 0) - continue; + if (ap->ssid[0] == 0) continue; /* remove the identical SSID+authmodes */ for (int j = i + 1; j < *aps; j++) { @@ -983,8 +688,7 @@ void network_wifi_filter_unique(wifi_ap_record_t* aplist, uint16_t* aps) { if ((strcmp((const char*)ap->ssid, (const char*)ap1->ssid) == 0) && (ap->authmode == ap1->authmode)) { /* same SSID, different auth mode is skipped */ /* save the rssi for the display */ - if ((ap1->rssi) > (ap->rssi)) - ap->rssi = ap1->rssi; + if ((ap1->rssi) > (ap->rssi)) ap->rssi = ap1->rssi; /* clearing the record */ memset(ap1, 0, sizeof(wifi_ap_record_t)); } @@ -996,8 +700,7 @@ void network_wifi_filter_unique(wifi_ap_record_t* aplist, uint16_t* aps) { /* skipping all that has no name */ if (ap->ssid[0] == 0) { /* mark the first free slot */ - if (first_free == NULL) - first_free = ap; + if (first_free == NULL) first_free = ap; total_unique--; continue; } @@ -1016,74 +719,91 @@ void network_wifi_filter_unique(wifi_ap_record_t* aplist, uint16_t* aps) { /* update the length of the list */ *aps = total_unique; } - -char* network_status_alloc_get_ap_list_json() { - return cJSON_PrintUnformatted(accessp_cjson); -} -cJSON* network_manager_clear_ap_list_json(cJSON** old) { - ESP_LOGV(TAG, "network_manager_clear_ap_list_json called"); - cJSON* root = network_wifi_get_new_array_json(old); - ESP_LOGV(TAG, "network_manager_clear_ap_list_json done"); - return root; -} - -esp_err_t network_wifi_built_known_ap_list() { - if (network_status_lock_json_buffer(pdMS_TO_TICKS(1000))) { - ESP_LOGD(TAG,"Building known AP list"); - accessp_cjson = network_manager_clear_ap_list_json(&accessp_cjson); - network_wifi_generate_access_points_json(&accessp_cjson); - network_status_unlock_json_buffer(); - ESP_LOGD(TAG, "Done building ap JSON list"); - } else { - ESP_LOGE(TAG, "Failed to lock json buffer"); - return ESP_FAIL; +void network_wifi_clear_scan_results() { + if (!status.net.wifi.scan_result || status.net.wifi.scan_result_count == 0) { + return; } - return ESP_OK; + free(status.net.wifi.scan_result); + status.net.wifi.scan_result = NULL; + status.net.wifi.scan_result_count = 0; +} +sys_WifiSTAEntry* network_wifi_alloc_scan_results(uint16_t count) { + network_wifi_clear_scan_results(); + status.net.wifi.scan_result = malloc_init_external(count * sizeof(sys_WifiSTAEntry)); + status.net.wifi.scan_result_count = count; + return status.net.wifi.scan_result; +} +void network_wifi_esp_sta_to_sta(wifi_ap_record_t* scan_res, sys_WifiSTAEntry* sta_entry) { + if(!sta_entry){ + return; + } + sta_entry->radio_type = network_wifi_get_radio_type(scan_res); + sta_entry->auth_type = network_wifi_get_auth_type(scan_res->authmode); + network_wifi_format_bssid(sta_entry->bssid, sizeof(sta_entry->bssid), scan_res->bssid); + sta_entry->channel = scan_res->primary; + gettimeofday((struct timeval*)&sta_entry->last_seen, NULL); + sta_entry->rssi = scan_res->rssi; + strncpy(sta_entry->ssid, ap_ssid_string(scan_res), sizeof(sta_entry->ssid)); + // also update any existing credential entry if any + network_wifi_esp_sta_to_sta(scan_res,network_wifi_get_ap_entry(sta_entry->ssid)); +} +bool network_wifi_update_scan_list(wifi_ap_record_t* accessp_records, uint16_t count) { + if (!network_wifi_alloc_scan_results(count)) { + ESP_LOGE(TAG, "Error allocating memory to store scan results"); + return false; + } + // reset RSSI values. This will help when choosing the + // strongest signal to connect to + network_wifi_reset_rssi(); + for (int i = 0; i < status.net.wifi.scan_result_count; i++) { + network_wifi_esp_sta_to_sta(&accessp_records[i], &status.net.wifi.scan_result[i]); + } + network_wifi_sort_strength(); + return true; } - esp_err_t wifi_scan_done() { esp_err_t err = ESP_OK; - /* As input param, it stores max AP number ap_records can hold. As output param, it receives the actual AP number this API returns. - * As a consequence, ap_num MUST be reset to MAX_AP_NUM at every scan */ + wifi_ap_record_t* accessp_records = NULL; + /* As input param, it stores max AP number ap_records can hold. As output param, it receives the + * actual AP number this API returns. As a consequence, ap_num MUST be reset to MAX_AP_NUM at + * every scan */ ESP_LOGD(TAG, "Getting AP list records"); - ap_num = MAX_AP_NUM; + uint16_t ap_num = MAX_AP_NUM; if ((err = esp_wifi_scan_get_ap_num(&ap_num)) != ESP_OK) { ESP_LOGE(TAG, "Failed to retrieve scan results count. Error %s", esp_err_to_name(err)); return err; } - FREE_AND_NULL(accessp_records); - if (ap_num > 0) { - accessp_records = (wifi_ap_record_t*)malloc_init_external(sizeof(wifi_ap_record_t) * ap_num); - if ((err = esp_wifi_scan_get_ap_records(&ap_num, accessp_records)) != ESP_OK) { - ESP_LOGE(TAG, "Failed to retrieve scan results list. Error %s", esp_err_to_name(err)); - return err; - } + if (ap_num <= 0) { + ESP_LOGI(TAG, "No AP found during scan"); + return err; + } + accessp_records = (wifi_ap_record_t*)malloc_init_external(sizeof(wifi_ap_record_t) * ap_num); + if (!accessp_records) { + ESP_LOGE(TAG, "Alloc failed for scan results"); + return ESP_FAIL; + } + if ((err = esp_wifi_scan_get_ap_records(&ap_num, accessp_records)) != ESP_OK) { + ESP_LOGE(TAG, "Failed to retrieve scan results list. Error %s", esp_err_to_name(err)); + } else { /* make sure the http server isn't trying to access the list while it gets refreshed */ - ESP_LOGD(TAG, "Preparing to build ap JSON list"); - if (network_status_lock_json_buffer(pdMS_TO_TICKS(1000))) { - /* Will remove the duplicate SSIDs from the list and update ap_num */ - network_wifi_filter_unique(accessp_records, &ap_num); - network_wifi_set_found_ap(); - network_wifi_generate_access_points_json(&accessp_cjson); - network_status_unlock_json_buffer(); - ESP_LOGD(TAG, "Done building ap JSON list"); + ESP_LOGD(TAG, "Retrieving scan list"); + /* Will remove the duplicate SSIDs from the list and update ap_num */ + network_wifi_filter_unique(accessp_records, &ap_num); + if (network_status_lock_structure(pdMS_TO_TICKS(1000))) { + network_wifi_update_scan_list(accessp_records, ap_num); + network_status_unlock_structure(); + ESP_LOGD(TAG, "Done retrieving scan list"); } else { ESP_LOGE(TAG, "could not get access to json mutex in wifi_scan"); err = ESP_FAIL; } - } else { - // - ESP_LOGD(TAG, "No AP Found. Emptying the list."); - accessp_cjson = network_wifi_get_new_array_json(&accessp_cjson); } + free(accessp_records); return err; } -bool is_wifi_up() { - return wifi_netif != NULL; -} +bool is_wifi_up() { return wifi_netif != NULL; } esp_err_t network_wifi_start_scan() { - wifi_scan_config_t scan_config = { - .ssid = 0, + wifi_scan_config_t scan_config = {.ssid = 0, .bssid = 0, .channel = 0, .scan_type = WIFI_SCAN_TYPE_ACTIVE, @@ -1091,14 +811,17 @@ esp_err_t network_wifi_start_scan() { esp_err_t err = ESP_OK; ESP_LOGI(TAG, "Initiating wifi network scan"); if (!is_wifi_up()) { - messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi not started. Cannot scan"); + messaging_post_message( + MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi not started. Cannot scan"); return ESP_FAIL; } - /* if a scan is already in progress this message is simply ignored thanks to the WIFI_MANAGER_SCAN_BIT uxBit */ + /* if a scan is already in progress this message is simply ignored thanks to the + * WIFI_MANAGER_SCAN_BIT uxBit */ if ((err = esp_wifi_scan_start(&scan_config, false)) != ESP_OK) { ESP_LOGW(TAG, "Unable to start scan; %s ", esp_err_to_name(err)); // set_status_message(WARNING, "Wifi Connecting. Cannot start scan."); - messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Scanning failed: %s", esp_err_to_name(err)); + messaging_post_message( + MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Scanning failed: %s", esp_err_to_name(err)); } return err; } @@ -1124,8 +847,10 @@ esp_err_t network_wifi_connect(const char* ssid, const char* password) { wifi_config_t config; memset(&config, 0x00, sizeof(config)); ESP_LOGD(TAG, "network_wifi_connect"); + network_wifi_reset_connected(); if (!is_wifi_up()) { - messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi not started. Cannot connect"); + messaging_post_message( + MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi not started. Cannot connect"); return ESP_FAIL; } if (!ssid || !password || strlen(ssid) == 0) { @@ -1169,32 +894,27 @@ esp_err_t network_wifi_connect(const char* ssid, const char* password) { } return err; } -esp_err_t network_wifi_connect_next_in_range(){ - const char * ssid = network_wifi_get_next_ap_in_range(); - if(ssid){ - return network_wifi_connect_ssid(ssid); - } - return ESP_FAIL; -} + esp_err_t network_wifi_connect_ssid(const char* ssid) { - known_access_point_t* item = network_wifi_get_ap_entry(ssid); + sys_WifiSTAEntry* item = network_wifi_get_ssid_info(ssid); if (item) { - item->last_try = (esp_timer_get_time() / 1000); + gettimeofday((struct timeval*)&item->last_try, NULL); return network_wifi_connect(item->ssid, item->password); } return ESP_FAIL; } esp_err_t network_wifi_connect_active_ssid() { - const wifi_sta_config_t* config = network_wifi_load_active_config(); - if (config) { - return network_wifi_connect(ssid_string(config), password_string(config)); + sys_WifiSTAEntry*connected = NULL; + if(status.has_net && platform->net.has_last_connected && strlen(platform->net.last_connected.ssid)>0){ + connected = &platform->net.last_connected.ssid; + return network_wifi_connect(connected->ssid,connected->password); } return ESP_FAIL; } void network_wifi_clear_config() { /* erase configuration */ const wifi_sta_config_t* sta = network_wifi_get_active_config(); - network_wifi_delete_ap(ssid_string(sta)); + network_wifi_remove_ap_entry(ssid_string(sta)); esp_err_t err = ESP_OK; if ((err = esp_wifi_disconnect()) != ESP_OK) { ESP_LOGW(TAG, "Could not disconnect from deleted network : %s", esp_err_to_name(err)); diff --git a/components/wifi-manager/network_wifi.h b/components/wifi-manager/network_wifi.h index 8293d3d2..f0d742db 100644 --- a/components/wifi-manager/network_wifi.h +++ b/components/wifi-manager/network_wifi.h @@ -1,38 +1,22 @@ #pragma once #include "network_manager.h" +#include "Configurator.h" #ifdef __cplusplus extern "C" { #endif esp_netif_t * network_wifi_start(); void destroy_network_wifi(); -/** - * @brief saves the current STA wifi config to flash ram storage. - */ -esp_err_t network_wifi_save_sta_config(); - - -/** - * @brief fetch a previously STA wifi config in the flash ram storage. - * @return true if a previously saved config was found, false otherwise. - */ -bool network_wifi_load_wifi_sta_config(); - /** * @brief Registers handler for wifi and ip events */ void network_wifi_register_handlers(); -/** - * @brief Generates the list of access points after a wifi scan. - * @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful. - */ -void network_wifi_generate_access_points_json(cJSON ** ap_list); /** * @brief Clear the list of access points. - * @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful. + * @note This is not thread-safe and should be called only if network_status_lock_structure call is successful. */ void network_wifi_clear_access_points_json(); @@ -46,7 +30,6 @@ esp_err_t network_wifi_load_restore(queue_message *msg); esp_err_t network_wifi_order_connect(queue_message *msg); esp_err_t network_wifi_disconnected(queue_message *msg); esp_err_t network_wifi_start_ap(queue_message *msg); -bool network_wifi_get_config_for_ssid(wifi_config_t* config, const char * ssid); esp_err_t network_wifi_handle_event(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); bool is_wifi_up(); wifi_config_t* network_wifi_set_wifi_sta_config(const char * ssid, const char * password) ; @@ -67,9 +50,9 @@ esp_err_t network_wifi_erase_known_ap(); esp_err_t network_wifi_set_sta_mode(); size_t network_wifi_get_known_count(); size_t network_wifi_get_known_count_in_range(); -esp_err_t network_wifi_built_known_ap_list(); esp_err_t network_wifi_connect_next_in_range(); -const wifi_sta_config_t* network_wifi_load_active_config(); +void network_wifi_esp_sta_to_sta(wifi_ap_record_t* scan_res, sys_WifiSTAEntry* sta_entry); +sys_WifiAuthTypeEnum network_wifi_get_auth_type(const wifi_auth_mode_t mode) ; #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/components/wifi-manager/webapp/dist/css/index.1ab179394339385e0a02.css b/components/wifi-manager/webapp/dist/css/index.1ab179394339385e0a02.css deleted file mode 100644 index bba2d84f..00000000 --- a/components/wifi-manager/webapp/dist/css/index.1ab179394339385e0a02.css +++ /dev/null @@ -1,6 +0,0 @@ -@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap); -/*! - * Bootstrap v5.3.2 (https://getbootstrap.com/) - * Copyright 2011-2023 The Bootstrap Authors - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */:root,[data-bs-theme=light]{--bs-blue:#375a7f;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#e83e8c;--bs-red:#e74c3c;--bs-orange:#fd7e14;--bs-yellow:#f39c12;--bs-green:#00bc8c;--bs-teal:#20c997;--bs-cyan:#3498db;--bs-black:#000;--bs-white:#fff;--bs-gray:#888;--bs-gray-dark:#303030;--bs-gray-100:#f8f9fa;--bs-gray-200:#ebebeb;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#888;--bs-gray-700:#444;--bs-gray-800:#303030;--bs-gray-900:#222;--bs-primary:#375a7f;--bs-secondary:#444;--bs-success:#00bc8c;--bs-info:#3498db;--bs-warning:#f39c12;--bs-danger:#e74c3c;--bs-light:#adb5bd;--bs-dark:#303030;--bs-primary-rgb:55,90,127;--bs-secondary-rgb:68,68,68;--bs-success-rgb:0,188,140;--bs-info-rgb:52,152,219;--bs-warning-rgb:243,156,18;--bs-danger-rgb:231,76,60;--bs-light-rgb:173,181,189;--bs-dark-rgb:48,48,48;--bs-primary-text-emphasis:#162433;--bs-secondary-text-emphasis:#1b1b1b;--bs-success-text-emphasis:#004b38;--bs-info-text-emphasis:#153d58;--bs-warning-text-emphasis:#613e07;--bs-danger-text-emphasis:#5c1e18;--bs-light-text-emphasis:#444;--bs-dark-text-emphasis:#444;--bs-primary-bg-subtle:#d7dee5;--bs-secondary-bg-subtle:#dadada;--bs-success-bg-subtle:#ccf2e8;--bs-info-bg-subtle:#d6eaf8;--bs-warning-bg-subtle:#fdebd0;--bs-danger-bg-subtle:#fadbd8;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#afbdcc;--bs-secondary-border-subtle:#b4b4b4;--bs-success-border-subtle:#99e4d1;--bs-info-border-subtle:#aed6f1;--bs-warning-border-subtle:#fad7a0;--bs-danger-border-subtle:#f5b7b1;--bs-light-border-subtle:#ebebeb;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg,hsla(0,0%,100%,.15),hsla(0,0%,100%,0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#fff;--bs-body-color-rgb:255,255,255;--bs-body-bg:#222;--bs-body-bg-rgb:34,34,34;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:hsla(0,0%,100%,.75);--bs-secondary-color-rgb:255,255,255;--bs-secondary-bg:#ebebeb;--bs-secondary-bg-rgb:235,235,235;--bs-tertiary-color:hsla(0,0%,100%,.5);--bs-tertiary-color-rgb:255,255,255;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#00bc8c;--bs-link-color-rgb:0,188,140;--bs-link-decoration:underline;--bs-link-hover-color:#009670;--bs-link-hover-color-rgb:0,150,112;--bs-code-color:#e83e8c;--bs-highlight-color:#fff;--bs-highlight-bg:#fdebd0;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0,0,0,.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0,0,0,.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0,0,0,.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0,0,0,.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0,0,0,.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(55,90,127,.25);--bs-form-valid-color:#00bc8c;--bs-form-valid-border-color:#00bc8c;--bs-form-invalid-color:#e74c3c;--bs-form-invalid-border-color:#e74c3c}[data-bs-theme=dark]{--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#222;--bs-body-bg-rgb:34,34,34;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222,226,230,.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#303030;--bs-secondary-bg-rgb:48,48,48;--bs-tertiary-color:rgba(222,226,230,.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#292929;--bs-tertiary-bg-rgb:41,41,41;--bs-primary-text-emphasis:#879cb2;--bs-secondary-text-emphasis:#8f8f8f;--bs-success-text-emphasis:#66d7ba;--bs-info-text-emphasis:#85c1e9;--bs-warning-text-emphasis:#f8c471;--bs-danger-text-emphasis:#f1948a;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#0b1219;--bs-secondary-bg-subtle:#0e0e0e;--bs-success-bg-subtle:#00261c;--bs-info-bg-subtle:#0a1e2c;--bs-warning-bg-subtle:#311f04;--bs-danger-bg-subtle:#2e0f0c;--bs-light-bg-subtle:#303030;--bs-dark-bg-subtle:#181818;--bs-primary-border-subtle:#21364c;--bs-secondary-border-subtle:#292929;--bs-success-border-subtle:#007154;--bs-info-border-subtle:#1f5b83;--bs-warning-border-subtle:#925e0b;--bs-danger-border-subtle:#8b2e24;--bs-light-border-subtle:#444;--bs-dark-border-subtle:#303030;--bs-heading-color:inherit;--bs-link-color:#879cb2;--bs-link-hover-color:#9fb0c1;--bs-link-color-rgb:135,156,178;--bs-link-hover-color-rgb:159,176,193;--bs-code-color:#f18bba;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#613e07;--bs-border-color:#444;--bs-border-color-translucent:hsla(0,0%,100%,.15);--bs-form-valid-color:#66d7ba;--bs-form-valid-border-color:#66d7ba;--bs-form-invalid-color:#f1948a;--bs-form-invalid-border-color:#f1948a;color-scheme:dark}*,:after,:before{box-sizing:border-box}@media(prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);background-color:var(--bs-body-bg);color:var(--bs-body-color);font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);margin:0;text-align:var(--bs-body-text-align)}hr{border:0;border-top:var(--bs-border-width) solid;color:inherit;margin:1rem 0;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{color:var(--bs-heading-color);font-weight:500;line-height:1.2;margin-bottom:.5rem;margin-top:0}.h1,h1{font-size:calc(1.425rem + 2.1vw)}@media(min-width:1200px){.h1,h1{font-size:3rem}}.h2,h2{font-size:calc(1.375rem + 1.5vw)}@media(min-width:1200px){.h2,h2{font-size:2.5rem}}.h3,h3{font-size:calc(1.325rem + .9vw)}@media(min-width:1200px){.h3,h3{font-size:2rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media(min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-bottom:1rem;margin-top:0}abbr[title]{cursor:help;text-decoration:underline dotted;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit;margin-bottom:1rem}ol,ul{padding-left:2rem}dl,ol,ul{margin-bottom:1rem;margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{background-color:var(--bs-highlight-bg);color:var(--bs-highlight-color);padding:.1875em}sub,sup{font-size:.75em;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;font-size:.875em;margin-bottom:1rem;margin-top:0;overflow:auto}pre,pre code{color:inherit}pre code{font-size:inherit;word-break:normal}code{word-wrap:break-word;color:var(--bs-code-color);font-size:.875em}a>code{color:inherit}kbd{background-color:var(--bs-body-color);border-radius:.25rem;color:var(--bs-body-bg);font-size:.875em;padding:.1875rem .375rem}kbd kbd{font-size:1em;padding:0}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{border-collapse:collapse;caption-side:bottom}caption{color:var(--bs-secondary-color);padding-bottom:.5rem;padding-top:.5rem;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border:0 solid;border-color:inherit}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit;margin:0}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{border-style:none;padding:0}textarea{resize:vertical}fieldset{border:0;margin:0;min-width:0;padding:0}legend{float:left;font-size:calc(1.275rem + .3vw);line-height:inherit;margin-bottom:.5rem;padding:0;width:100%}@media(min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{-webkit-appearance:button;font:inherit}output{display:inline-block}iframe{border:0}summary{cursor:pointer;display:list-item}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-6{font-size:2.5rem}}.list-inline,.list-unstyled{list-style:none;padding-left:0}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{font-size:1.25rem;margin-bottom:1rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{font-size:.875em;margin-bottom:1rem;margin-top:-1rem}.blockquote-footer:before{content:"— "}.img-fluid,.img-thumbnail{height:auto;max-width:100%}.img-thumbnail{background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);padding:.25rem}.figure{display:inline-block}.figure-img{line-height:1;margin-bottom:.5rem}.figure-caption{color:var(--bs-secondary-color);font-size:.875em}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;margin-left:auto;margin-right:auto;padding-left:calc(var(--bs-gutter-x)*.5);padding-right:calc(var(--bs-gutter-x)*.5);width:100%}@media(min-width:576px){.container,.container-sm{max-width:540px}}@media(min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media(min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media(min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media(min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-left:calc(var(--bs-gutter-x)*-.5);margin-right:calc(var(--bs-gutter-x)*-.5);margin-top:calc(var(--bs-gutter-y)*-1)}.row>*{flex-shrink:0;margin-top:var(--bs-gutter-y);max-width:100%;padding-left:calc(var(--bs-gutter-x)*.5);padding-right:calc(var(--bs-gutter-x)*.5);width:100%}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media(min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media(min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media(min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media(min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media(min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:#fff;--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:#444;--bs-table-accent-bg:transparent;--bs-table-striped-color:#fff;--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb),0.05);--bs-table-active-color:#fff;--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb),0.1);--bs-table-hover-color:#fff;--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb),0.075);border-color:var(--bs-table-border-color);margin-bottom:1rem;vertical-align:top;width:100%}.table>:not(caption)>*>*{background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)));color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));padding:.5rem}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width)*2) solid}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped-columns>:not(caption)>tr>:nth-child(2n),.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-active{--bs-table-color-state:var(--bs-table-active-color);--bs-table-bg-state:var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state:var(--bs-table-hover-color);--bs-table-bg-state:var(--bs-table-hover-bg)}.table-primary{--bs-table-color:#fff;--bs-table-bg:#375a7f;--bs-table-border-color:#5f7b99;--bs-table-striped-bg:#416285;--bs-table-striped-color:#fff;--bs-table-active-bg:#4b6b8c;--bs-table-active-color:#fff;--bs-table-hover-bg:#466689;--bs-table-hover-color:#fff}.table-primary,.table-secondary{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-secondary{--bs-table-color:#fff;--bs-table-bg:#444;--bs-table-border-color:dimgray;--bs-table-striped-bg:#4d4d4d;--bs-table-striped-color:#fff;--bs-table-active-bg:#575757;--bs-table-active-color:#fff;--bs-table-hover-bg:#525252;--bs-table-hover-color:#fff}.table-success{--bs-table-color:#fff;--bs-table-bg:#00bc8c;--bs-table-border-color:#33c9a3;--bs-table-striped-bg:#0dbf92;--bs-table-striped-color:#fff;--bs-table-active-bg:#1ac398;--bs-table-active-color:#fff;--bs-table-hover-bg:#13c195;--bs-table-hover-color:#fff}.table-info,.table-success{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-info{--bs-table-color:#fff;--bs-table-bg:#3498db;--bs-table-border-color:#5dade2;--bs-table-striped-bg:#3e9ddd;--bs-table-striped-color:#fff;--bs-table-active-bg:#48a2df;--bs-table-active-color:#fff;--bs-table-hover-bg:#43a0de;--bs-table-hover-color:#fff}.table-warning{--bs-table-color:#fff;--bs-table-bg:#f39c12;--bs-table-border-color:#f5b041;--bs-table-striped-bg:#f4a11e;--bs-table-striped-color:#fff;--bs-table-active-bg:#f4a62a;--bs-table-active-color:#fff;--bs-table-hover-bg:#f4a324;--bs-table-hover-color:#fff}.table-danger,.table-warning{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-danger{--bs-table-color:#fff;--bs-table-bg:#e74c3c;--bs-table-border-color:#ec7063;--bs-table-striped-bg:#e85546;--bs-table-striped-color:#fff;--bs-table-active-bg:#e95e50;--bs-table-active-color:#fff;--bs-table-hover-bg:#e9594b;--bs-table-hover-color:#fff}.table-light{--bs-table-color:#fff;--bs-table-bg:#adb5bd;--bs-table-border-color:#bdc4ca;--bs-table-striped-bg:#b1b9c0;--bs-table-striped-color:#fff;--bs-table-active-bg:#b5bcc4;--bs-table-active-color:#fff;--bs-table-hover-bg:#b3bbc2;--bs-table-hover-color:#fff}.table-dark,.table-light{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#303030;--bs-table-border-color:#595959;--bs-table-striped-bg:#3a3a3a;--bs-table-striped-color:#fff;--bs-table-active-bg:#454545;--bs-table-active-color:#fff;--bs-table-hover-bg:#404040;--bs-table-hover-color:#fff}.table-responsive{-webkit-overflow-scrolling:touch;overflow-x:auto}@media(max-width:575.98px){.table-responsive-sm{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media(max-width:767.98px){.table-responsive-md{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media(max-width:991.98px){.table-responsive-lg{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media(max-width:1199.98px){.table-responsive-xl{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media(max-width:1399.98px){.table-responsive-xxl{-webkit-overflow-scrolling:touch;overflow-x:auto}}.form-label{margin-bottom:.5rem}.col-form-label{font-size:inherit;line-height:1.5;margin-bottom:0;padding-bottom:calc(.375rem + var(--bs-border-width));padding-top:calc(.375rem + var(--bs-border-width))}.col-form-label-lg{font-size:1.25rem;padding-bottom:calc(.5rem + var(--bs-border-width));padding-top:calc(.5rem + var(--bs-border-width))}.col-form-label-sm{font-size:.875rem;padding-bottom:calc(.25rem + var(--bs-border-width));padding-top:calc(.25rem + var(--bs-border-width))}.form-text{color:var(--bs-secondary-color);font-size:.875em;margin-top:.25rem}.form-control{appearance:none;background-clip:padding-box;background-color:#fff;border:var(--bs-border-width) solid #222;border-radius:var(--bs-border-radius);color:#303030;display:block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media(prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{background-color:#fff;border-color:#9badbf;box-shadow:0 0 0 .25rem rgba(55,90,127,.25);color:#303030;outline:0}.form-control::-webkit-date-and-time-value{height:1.5em;margin:0;min-width:85px}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::placeholder{color:#888;opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::file-selector-button{background-color:#444;border:0 solid;border-color:inherit;border-inline-end-width:var(--bs-border-width);border-radius:0;color:#adb5bd;margin:-.375rem -.75rem;margin-inline-end:.75rem;padding:.375rem .75rem;pointer-events:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#373737}.form-control-plaintext{background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0;color:var(--bs-body-color);display:block;line-height:1.5;margin-bottom:0;padding:.375rem 0;width:100%}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-left:0;padding-right:0}.form-control-sm{border-radius:var(--bs-border-radius-sm);font-size:.875rem;min-height:calc(1.5em + .5rem + var(--bs-border-width)*2);padding:.25rem .5rem}.form-control-sm::file-selector-button{margin:-.25rem -.5rem;margin-inline-end:.5rem;padding:.25rem .5rem}.form-control-lg{border-radius:var(--bs-border-radius-lg);font-size:1.25rem;min-height:calc(1.5em + 1rem + var(--bs-border-width)*2);padding:.5rem 1rem}.form-control-lg::file-selector-button{margin:-.5rem -1rem;margin-inline-end:1rem;padding:.5rem 1rem}textarea.form-control{min-height:calc(1.5em + .75rem + var(--bs-border-width)*2)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + var(--bs-border-width)*2)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + var(--bs-border-width)*2)}.form-control-color{height:calc(1.5em + .75rem + var(--bs-border-width)*2);padding:.375rem;width:3rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color::-webkit-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + var(--bs-border-width)*2)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + var(--bs-border-width)*2)}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");appearance:none;background-color:#fff;background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-position:right .75rem center;background-repeat:no-repeat;background-size:16px 12px;border:var(--bs-border-width) solid #222;border-radius:var(--bs-border-radius);color:#303030;display:block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem 2.25rem .375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media(prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#9badbf;box-shadow:0 0 0 .25rem rgba(55,90,127,.25);outline:0}.form-select[multiple],.form-select[size]:not([size="1"]){background-image:none;padding-right:.75rem}.form-select:disabled{background-color:var(--bs-secondary-bg);color:#888}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #303030}.form-select-sm{border-radius:var(--bs-border-radius-sm);font-size:.875rem;padding-bottom:.25rem;padding-left:.5rem;padding-top:.25rem}.form-select-lg{border-radius:var(--bs-border-radius-lg);font-size:1.25rem;padding-bottom:.5rem;padding-left:1rem;padding-top:.5rem}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E")}.form-check{display:block;margin-bottom:.125rem;min-height:1.5rem;padding-left:1.5em}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-left:0;padding-right:1.5em;text-align:right}.form-check-reverse .form-check-input{float:right;margin-left:0;margin-right:-1.5em}.form-check-input{--bs-form-check-bg:#fff;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-position:50%;background-repeat:no-repeat;background-size:contain;border:none;flex-shrink:0;height:1em;margin-top:.25em;print-color-adjust:exact;vertical-align:top;width:1em}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#9badbf;box-shadow:0 0 0 .25rem rgba(55,90,127,.25);outline:0}.form-check-input:checked{background-color:#375a7f;border-color:#375a7f}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3E%3C/svg%3E")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='2' fill='%23fff'/%3E%3C/svg%3E")}.form-check-input[type=checkbox]:indeterminate{--bs-form-check-bg-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3E%3C/svg%3E");background-color:#375a7f;border-color:#375a7f}.form-check-input:disabled{filter:none;opacity:.5;pointer-events:none}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='rgba(0, 0, 0, 0.25)'/%3E%3C/svg%3E");background-image:var(--bs-form-switch-bg);background-position:0;border-radius:2em;margin-left:-2.5em;transition:background-position .15s ease-in-out;width:2em}@media(prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%239badbf'/%3E%3C/svg%3E")}.form-switch .form-check-input:checked{--bs-form-switch-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E");background-position:100%}.form-switch.form-check-reverse{padding-left:0;padding-right:2.5em}.form-switch.form-check-reverse .form-check-input{margin-left:0;margin-right:-2.5em}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{clip:rect(0,0,0,0);pointer-events:none;position:absolute}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{filter:none;opacity:.65;pointer-events:none}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='rgba(255, 255, 255, 0.25)'/%3E%3C/svg%3E")}.form-range{appearance:none;background-color:transparent;height:1.5rem;padding:0;width:100%}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{appearance:none;background-color:#375a7f;border:0;border-radius:1rem;height:1rem;margin-top:-.25rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media(prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#c3ced9}.form-range::-webkit-slider-runnable-track{background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.form-range::-moz-range-thumb{appearance:none;background-color:#375a7f;border:0;border-radius:1rem;height:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media(prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#c3ced9}.form-range::-moz-range-track{background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + var(--bs-border-width)*2);line-height:1.25;min-height:calc(3.5rem + var(--bs-border-width)*2)}.form-floating>label{border:var(--bs-border-width) solid transparent;height:100%;left:0;overflow:hidden;padding:1rem .75rem;pointer-events:none;position:absolute;text-align:start;text-overflow:ellipsis;top:0;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out;white-space:nowrap;z-index:2}@media(prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-select{padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label:after,.form-floating>.form-control:focus~label:after,.form-floating>.form-control:not(:placeholder-shown)~label:after,.form-floating>.form-select~label:after{background-color:#fff;border-radius:var(--bs-border-radius);content:"";height:1.5em;inset:1rem .375rem;position:absolute;z-index:-1}.form-floating>.form-control:-webkit-autofill~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label,.form-floating>:disabled~label{color:#888}.form-floating>.form-control:disabled~label:after,.form-floating>:disabled~label:after{background-color:var(--bs-secondary-bg)}.input-group{align-items:stretch;display:flex;flex-wrap:wrap;position:relative;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{flex:1 1 auto;min-width:0;position:relative;width:1%}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{align-items:center;background-color:#444;border:var(--bs-border-width) solid #222;border-radius:var(--bs-border-radius);color:#adb5bd;display:flex;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;white-space:nowrap}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{border-radius:var(--bs-border-radius-lg);font-size:1.25rem;padding:.5rem 1rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{border-radius:var(--bs-border-radius-sm);font-size:.875rem;padding:.25rem .5rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-bottom-right-radius:0;border-top-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:calc(var(--bs-border-width)*-1)}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-bottom-left-radius:0;border-top-left-radius:0}.valid-feedback{color:var(--bs-form-valid-color);display:none;font-size:.875em;margin-top:.25rem;width:100%}.valid-tooltip{background-color:var(--bs-success);border-radius:var(--bs-border-radius);color:#fff;display:none;font-size:.875rem;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-form-valid-border-color)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem);padding-right:4.125rem}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3.75rem + 1.5em)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-form-valid-border-color)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-form-valid-color)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-form-valid-color)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{color:var(--bs-form-invalid-color);display:none;font-size:.875em;margin-top:.25rem;width:100%}.invalid-tooltip{background-color:var(--bs-danger);border-radius:var(--bs-border-radius);color:#fff;display:none;font-size:.875rem;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23e74c3c'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-form-invalid-border-color)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23e74c3c'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3E%3C/svg%3E");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem);padding-right:4.125rem}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3.75rem + 1.5em)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-form-invalid-border-color)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-form-invalid-color)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-form-invalid-color)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 hsla(0,0%,100%,.15),0 1px 1px rgba(0,0,0,.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb),.5);background-color:var(--bs-btn-bg);border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);color:var(--bs-btn-color);cursor:pointer;display:inline-block;font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;user-select:none;vertical-align:middle}@media(prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);color:var(--bs-btn-hover-color)}.btn-check+.btn:hover{background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color);color:var(--bs-btn-color)}.btn:focus-visible{background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);box-shadow:var(--bs-btn-focus-box-shadow);color:var(--bs-btn-hover-color);outline:0}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);box-shadow:var(--bs-btn-focus-box-shadow);outline:0}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color);color:var(--bs-btn-active-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);color:var(--bs-btn-disabled-color);opacity:var(--bs-btn-disabled-opacity);pointer-events:none}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2f4d6c;--bs-btn-hover-border-color:#2c4866;--bs-btn-focus-shadow-rgb:85,115,146;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2c4866;--bs-btn-active-border-color:#29445f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#375a7f;--bs-btn-disabled-border-color:#375a7f}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3a3a3a;--bs-btn-hover-border-color:#363636;--bs-btn-focus-shadow-rgb:96,96,96;--bs-btn-active-color:#fff;--bs-btn-active-bg:#363636;--bs-btn-active-border-color:#333;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#444;--bs-btn-disabled-border-color:#444}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00a077;--bs-btn-hover-border-color:#009670;--bs-btn-focus-shadow-rgb:38,198,157;--bs-btn-active-color:#fff;--bs-btn-active-bg:#009670;--bs-btn-active-border-color:#008d69;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#00bc8c;--bs-btn-disabled-border-color:#00bc8c}.btn-info{--bs-btn-color:#fff;--bs-btn-bg:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2c81ba;--bs-btn-hover-border-color:#2a7aaf;--bs-btn-focus-shadow-rgb:82,167,224;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2a7aaf;--bs-btn-active-border-color:#2772a4;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#3498db;--bs-btn-disabled-border-color:#3498db}.btn-warning{--bs-btn-color:#fff;--bs-btn-bg:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#cf850f;--bs-btn-hover-border-color:#c27d0e;--bs-btn-focus-shadow-rgb:245,171,54;--bs-btn-active-color:#fff;--bs-btn-active-bg:#c27d0e;--bs-btn-active-border-color:#b6750e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#f39c12;--bs-btn-disabled-border-color:#f39c12}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#c44133;--bs-btn-hover-border-color:#b93d30;--bs-btn-focus-shadow-rgb:235,103,89;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b93d30;--bs-btn-active-border-color:#ad392d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#e74c3c;--bs-btn-disabled-border-color:#e74c3c}.btn-light{--bs-btn-color:#fff;--bs-btn-bg:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#939aa1;--bs-btn-hover-border-color:#8a9197;--bs-btn-focus-shadow-rgb:185,192,199;--bs-btn-active-color:#fff;--bs-btn-active-bg:#8a9197;--bs-btn-active-border-color:#82888e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#adb5bd;--bs-btn-disabled-border-color:#adb5bd}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#4f4f4f;--bs-btn-hover-border-color:#454545;--bs-btn-focus-shadow-rgb:79,79,79;--bs-btn-active-color:#fff;--bs-btn-active-bg:#595959;--bs-btn-active-border-color:#454545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#303030;--bs-btn-disabled-border-color:#303030}.btn-outline-primary{--bs-btn-color:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#375a7f;--bs-btn-hover-border-color:#375a7f;--bs-btn-focus-shadow-rgb:55,90,127;--bs-btn-active-color:#fff;--bs-btn-active-bg:#375a7f;--bs-btn-active-border-color:#375a7f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#375a7f;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#375a7f;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#444;--bs-btn-hover-border-color:#444;--bs-btn-focus-shadow-rgb:68,68,68;--bs-btn-active-color:#fff;--bs-btn-active-bg:#444;--bs-btn-active-border-color:#444;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#444;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#444;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00bc8c;--bs-btn-hover-border-color:#00bc8c;--bs-btn-focus-shadow-rgb:0,188,140;--bs-btn-active-color:#fff;--bs-btn-active-bg:#00bc8c;--bs-btn-active-border-color:#00bc8c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#00bc8c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#00bc8c;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3498db;--bs-btn-hover-border-color:#3498db;--bs-btn-focus-shadow-rgb:52,152,219;--bs-btn-active-color:#fff;--bs-btn-active-bg:#3498db;--bs-btn-active-border-color:#3498db;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#3498db;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#3498db;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#f39c12;--bs-btn-hover-border-color:#f39c12;--bs-btn-focus-shadow-rgb:243,156,18;--bs-btn-active-color:#fff;--bs-btn-active-bg:#f39c12;--bs-btn-active-border-color:#f39c12;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#f39c12;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f39c12;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#e74c3c;--bs-btn-hover-border-color:#e74c3c;--bs-btn-focus-shadow-rgb:231,76,60;--bs-btn-active-color:#fff;--bs-btn-active-bg:#e74c3c;--bs-btn-active-border-color:#e74c3c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#e74c3c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#e74c3c;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#adb5bd;--bs-btn-hover-border-color:#adb5bd;--bs-btn-focus-shadow-rgb:173,181,189;--bs-btn-active-color:#fff;--bs-btn-active-bg:#adb5bd;--bs-btn-active-border-color:#adb5bd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#adb5bd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#adb5bd;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#303030;--bs-btn-hover-border-color:#303030;--bs-btn-focus-shadow-rgb:48,48,48;--bs-btn-active-color:#fff;--bs-btn-active-bg:#303030;--bs-btn-active-border-color:#303030;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#303030;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#303030;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#888;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:0 0 0 #000;--bs-btn-focus-shadow-rgb:38,198,157;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:var(--bs-border-radius-lg)}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media(prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{height:auto;transition:width .35s ease;width:0}@media(prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{border-bottom:0;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:.3em solid;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:#222;--bs-dropdown-border-color:#444;--bs-dropdown-border-radius:var(--bs-border-radius);--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-dropdown-divider-bg:#444;--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:var(--bs-box-shadow);--bs-dropdown-link-color:#fff;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-link-hover-bg:#375a7f;--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:var(--bs-tertiary-color);--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#888;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;background-clip:padding-box;background-color:var(--bs-dropdown-bg);border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius);color:var(--bs-dropdown-color);display:none;font-size:var(--bs-dropdown-font-size);list-style:none;margin:0;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);position:absolute;text-align:left;z-index:var(--bs-dropdown-zindex)}.dropdown-menu[data-bs-popper]{left:0;margin-top:var(--bs-dropdown-spacer);top:100%}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{left:auto;right:0}@media(min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{left:auto;right:0}}@media(min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{left:auto;right:0}}@media(min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{left:auto;right:0}}@media(min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{left:auto;right:0}}@media(min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{left:auto;right:0}}.dropup .dropdown-menu[data-bs-popper]{bottom:100%;margin-bottom:var(--bs-dropdown-spacer);margin-top:0;top:auto}.dropup .dropdown-toggle:after{border-bottom:.3em solid;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:0;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{left:100%;margin-left:var(--bs-dropdown-spacer);margin-top:0;right:auto;top:0}.dropend .dropdown-toggle:after{border-bottom:.3em solid transparent;border-left:.3em solid;border-right:0;border-top:.3em solid transparent;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropend .dropdown-toggle:empty:after{margin-left:0}.dropend .dropdown-toggle:after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{left:auto;margin-right:var(--bs-dropdown-spacer);margin-top:0;right:100%;top:0}.dropstart .dropdown-toggle:after{content:"";display:inline-block;display:none;margin-left:.255em;vertical-align:.255em}.dropstart .dropdown-toggle:before{border-bottom:.3em solid transparent;border-right:.3em solid;border-top:.3em solid transparent;content:"";display:inline-block;margin-right:.255em;vertical-align:.255em}.dropstart .dropdown-toggle:empty:after{margin-left:0}.dropstart .dropdown-toggle:before{vertical-align:0}.dropdown-divider{border-top:1px solid var(--bs-dropdown-divider-bg);height:0;margin:var(--bs-dropdown-divider-margin-y) 0;opacity:1;overflow:hidden}.dropdown-item{background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0);clear:both;color:var(--bs-dropdown-link-color);display:block;font-weight:400;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);text-align:inherit;text-decoration:none;white-space:nowrap;width:100%}.dropdown-item:focus,.dropdown-item:hover{background-color:var(--bs-dropdown-link-hover-bg);color:var(--bs-dropdown-link-hover-color)}.dropdown-item.active,.dropdown-item:active{background-color:var(--bs-dropdown-link-active-bg);color:var(--bs-dropdown-link-active-color);text-decoration:none}.dropdown-item.disabled,.dropdown-item:disabled{background-color:transparent;color:var(--bs-dropdown-link-disabled-color);pointer-events:none}.dropdown-menu.show{display:block}.dropdown-header{color:var(--bs-dropdown-header-color);display:block;font-size:.875rem;margin-bottom:0;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);white-space:nowrap}.dropdown-item-text{color:var(--bs-dropdown-link-color);display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#303030;--bs-dropdown-border-color:#444;--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:#444;--bs-dropdown-link-hover-bg:hsla(0,0%,100%,.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{display:inline-flex;position:relative;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{flex:1 1 auto;position:relative}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:var(--bs-border-radius)}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(var(--bs-border-width)*-1)}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-bottom-left-radius:0;border-top-left-radius:0}.dropdown-toggle-split{padding-left:.5625rem;padding-right:.5625rem}.dropdown-toggle-split:after,.dropend .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after{margin-left:0}.dropstart .dropdown-toggle-split:before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-left:.375rem;padding-right:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-left:.75rem;padding-right:.75rem}.btn-group-vertical{align-items:flex-start;flex-direction:column;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(var(--bs-border-width)*-1)}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-left-radius:0;border-bottom-right-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:2rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#adb5bd;display:flex;flex-wrap:wrap;list-style:none;margin-bottom:0;padding-left:0}.nav-link{background:none;border:0;color:var(--bs-nav-link-color);display:block;font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media(prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{box-shadow:0 0 0 .25rem rgba(55,90,127,.25);outline:0}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);cursor:default;pointer-events:none}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:#444;--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:#444 #444 transparent;--bs-nav-tabs-link-active-color:#fff;--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:#444 #444 transparent;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius);margin-bottom:calc(var(--bs-nav-tabs-border-width)*-1)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:var(--bs-nav-tabs-link-hover-border-color);isolation:isolate}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color);color:var(--bs-nav-tabs-link-active-color)}.nav-tabs .dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:calc(var(--bs-nav-tabs-border-width)*-1)}.nav-pills{--bs-nav-pills-border-radius:var(--bs-border-radius);--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#375a7f}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{background-color:var(--bs-nav-pills-link-active-bg);color:var(--bs-nav-pills-link-active-color)}.nav-underline{--bs-nav-underline-gap:1rem;--bs-nav-underline-border-width:0.125rem;--bs-nav-underline-link-active-color:var(--bs-emphasis-color);gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{border-bottom:var(--bs-nav-underline-border-width) solid transparent;padding-left:0;padding-right:0}.nav-underline .nav-link:focus,.nav-underline .nav-link:hover{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{border-bottom-color:currentcolor;color:var(--bs-nav-underline-link-active-color);font-weight:700}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:1rem;--bs-navbar-color:rgba(34,34,34,.7);--bs-navbar-hover-color:#222;--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb),0.3);--bs-navbar-active-color:#222;--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:#222;--bs-navbar-brand-hover-color:#222;--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.75)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");--bs-navbar-toggler-border-color:rgba(34,34,34,.1);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x);position:relative}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{align-items:center;display:flex;flex-wrap:inherit;justify-content:space-between}.navbar-brand{color:var(--bs-navbar-brand-color);font-size:var(--bs-navbar-brand-font-size);margin-right:var(--bs-navbar-brand-margin-end);padding-bottom:var(--bs-navbar-brand-padding-y);padding-top:var(--bs-navbar-brand-padding-y);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;list-style:none;margin-bottom:0;padding-left:0}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{color:var(--bs-navbar-color);padding-bottom:.5rem;padding-top:.5rem}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{align-items:center;flex-basis:100%;flex-grow:1}.navbar-toggler{background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);color:var(--bs-navbar-color);font-size:var(--bs-navbar-toggler-font-size);line-height:1;padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);transition:var(--bs-navbar-toggler-transition)}@media(prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width);outline:0;text-decoration:none}.navbar-toggler-icon{background-image:var(--bs-navbar-toggler-icon-bg);background-position:50%;background-repeat:no-repeat;background-size:100%;display:inline-block;height:1.5em;vertical-align:middle;width:1.5em}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media(min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color:hsla(0,0%,100%,.6);--bs-navbar-hover-color:#fff;--bs-navbar-disabled-color:hsla(0,0%,100%,.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:hsla(0,0%,100%,.1)}.navbar-dark,.navbar[data-bs-theme=dark],[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.6)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:#444;--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:#303030;--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;word-wrap:break-word;background-clip:border-box;background-color:var(--bs-card-bg);border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius);color:var(--bs-body-color);display:flex;flex-direction:column;height:var(--bs-card-height);min-width:0;position:relative}.card>hr{margin-left:0;margin-right:0}.card>.list-group{border-bottom:inherit;border-top:inherit}.card>.list-group:first-child{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius);border-top-width:0}.card>.list-group:last-child{border-bottom-left-radius:var(--bs-card-inner-border-radius);border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-width:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{color:var(--bs-card-color);flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x)}.card-title{color:var(--bs-card-title-color);margin-bottom:var(--bs-card-title-spacer-y)}.card-subtitle{color:var(--bs-card-subtitle-color);margin-top:calc(var(--bs-card-title-spacer-y)*-.5)}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color);color:var(--bs-card-cap-color);margin-bottom:0;padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color);color:var(--bs-card-cap-color);padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{border-bottom:0;margin-bottom:calc(var(--bs-card-cap-padding-y)*-1);margin-left:calc(var(--bs-card-cap-padding-x)*-.5);margin-right:calc(var(--bs-card-cap-padding-x)*-.5)}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-left:calc(var(--bs-card-cap-padding-x)*-.5);margin-right:calc(var(--bs-card-cap-padding-x)*-.5)}.card-img-overlay{border-radius:var(--bs-card-inner-border-radius);bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);position:absolute;right:0;top:0}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-left-radius:var(--bs-card-inner-border-radius);border-bottom-right-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media(min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{border-left:0;margin-left:0}.card-group>.card:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23162433'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");--bs-accordion-btn-focus-border-color:#9badbf;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(55,90,127,.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text-emphasis);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{align-items:center;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;color:var(--bs-accordion-btn-color);display:flex;font-size:1rem;overflow-anchor:none;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);position:relative;text-align:left;transition:var(--bs-accordion-transition);width:100%}@media(prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(var(--bs-accordion-border-width)*-1) 0 var(--bs-accordion-border-color);color:var(--bs-accordion-active-color)}.accordion-button:not(.collapsed):after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button:after{background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);content:"";flex-shrink:0;height:var(--bs-accordion-btn-icon-width);margin-left:auto;transition:var(--bs-accordion-btn-icon-transition);width:var(--bs-accordion-btn-icon-width)}@media(prefers-reduced-motion:reduce){.accordion-button:after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{border-color:var(--bs-accordion-btn-focus-border-color);box-shadow:var(--bs-accordion-btn-focus-box-shadow);outline:0;z-index:3}.accordion-header{margin-bottom:0}.accordion-item{background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color);color:var(--bs-accordion-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-left-radius:var(--bs-accordion-border-radius);border-bottom-right-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-left-radius:var(--bs-accordion-inner-border-radius);border-bottom-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-left-radius:var(--bs-accordion-border-radius);border-bottom-right-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-left:0;border-radius:0;border-right:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button:after{--bs-accordion-btn-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23879cb2'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");--bs-accordion-btn-active-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23879cb2'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E")}.breadcrumb{--bs-breadcrumb-padding-x:0.75rem;--bs-breadcrumb-padding-y:0.375rem;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg:#444;--bs-breadcrumb-border-radius:0.25rem;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius);display:flex;flex-wrap:wrap;font-size:var(--bs-breadcrumb-font-size);list-style:none;margin-bottom:var(--bs-breadcrumb-margin-bottom);padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item:before{color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider,"/");float:left;padding-right:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:#fff;--bs-pagination-bg:#00bc8c;--bs-pagination-border-width:0;--bs-pagination-border-color:transparent;--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:#fff;--bs-pagination-hover-bg:#00efb2;--bs-pagination-hover-border-color:transparent;--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(55,90,127,.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#00efb2;--bs-pagination-active-border-color:transparent;--bs-pagination-disabled-color:#fff;--bs-pagination-disabled-bg:#007053;--bs-pagination-disabled-border-color:transparent;display:flex;list-style:none;padding-left:0}.page-link{background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);color:var(--bs-pagination-color);display:block;font-size:var(--bs-pagination-font-size);padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);position:relative;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color);color:var(--bs-pagination-hover-color);z-index:2}.page-link:focus{background-color:var(--bs-pagination-focus-bg);box-shadow:var(--bs-pagination-focus-box-shadow);color:var(--bs-pagination-focus-color);outline:0;z-index:3}.active>.page-link,.page-link.active{background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color);color:var(--bs-pagination-active-color);z-index:3}.disabled>.page-link,.page-link.disabled{background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color);color:var(--bs-pagination-disabled-color);pointer-events:none}.page-item:not(:first-child) .page-link{margin-left:0}.page-item:first-child .page-link{border-bottom-left-radius:var(--bs-pagination-border-radius);border-top-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-bottom-right-radius:var(--bs-pagination-border-radius);border-top-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:var(--bs-border-radius-lg)}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:var(--bs-border-radius-sm)}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);border-radius:var(--bs-badge-border-radius);color:var(--bs-badge-color);display:inline-block;font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);text-align:center;vertical-align:baseline;white-space:nowrap}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius);color:var(--bs-alert-color);margin-bottom:var(--bs-alert-margin-bottom);padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);position:relative}.alert-heading{color:inherit}.alert-link{color:var(--bs-alert-link-color);font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{padding:1.25rem 1rem;position:absolute;right:0;top:0;z-index:2}.alert-primary{--bs-alert-color:var(--bs-primary-text-emphasis);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text-emphasis);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color:var(--bs-success-text-emphasis);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color:var(--bs-info-text-emphasis);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color:var(--bs-warning-text-emphasis);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color:var(--bs-danger-text-emphasis);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color:var(--bs-light-text-emphasis);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color:var(--bs-dark-text-emphasis);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:#444;--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#375a7f;--bs-progress-bar-transition:width 0.6s ease;background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius);display:flex;font-size:var(--bs-progress-font-size);height:var(--bs-progress-height);overflow:hidden}.progress-bar{background-color:var(--bs-progress-bar-bg);color:var(--bs-progress-bar-color);display:flex;flex-direction:column;justify-content:center;overflow:hidden;text-align:center;transition:var(--bs-progress-bar-transition);white-space:nowrap}@media(prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media(prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:#fff;--bs-list-group-bg:#303030;--bs-list-group-border-color:#444;--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:#fff;--bs-list-group-action-hover-bg:#444;--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:#222;--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:#303030;--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#375a7f;--bs-list-group-active-border-color:#375a7f;border-radius:var(--bs-list-group-border-radius);display:flex;flex-direction:column;margin-bottom:0;padding-left:0}.list-group-numbered{counter-reset:section;list-style-type:none}.list-group-numbered>.list-group-item:before{content:counters(section,".") ". ";counter-increment:section}.list-group-item-action{color:var(--bs-list-group-action-color);text-align:inherit;width:100%}.list-group-item-action:focus,.list-group-item-action:hover{background-color:var(--bs-list-group-action-hover-bg);color:var(--bs-list-group-action-hover-color);text-decoration:none;z-index:1}.list-group-item-action:active{background-color:var(--bs-list-group-action-active-bg);color:var(--bs-list-group-action-active-color)}.list-group-item{background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color);color:var(--bs-list-group-color);display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);position:relative;text-decoration:none}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{background-color:var(--bs-list-group-disabled-bg);color:var(--bs-list-group-disabled-color);pointer-events:none}.list-group-item.active{background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color);color:var(--bs-list-group-active-color);z-index:2}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{border-top-width:var(--bs-list-group-border-width);margin-top:calc(var(--bs-list-group-border-width)*-1)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}@media(min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}@media(min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-md>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}@media(min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}@media(min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}@media(min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text-emphasis);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-primary-border-subtle);--bs-list-group-active-color:var(--bs-primary-bg-subtle);--bs-list-group-active-bg:var(--bs-primary-text-emphasis);--bs-list-group-active-border-color:var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text-emphasis);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-secondary-border-subtle);--bs-list-group-active-color:var(--bs-secondary-bg-subtle);--bs-list-group-active-bg:var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color:var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text-emphasis);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-success-border-subtle);--bs-list-group-active-color:var(--bs-success-bg-subtle);--bs-list-group-active-bg:var(--bs-success-text-emphasis);--bs-list-group-active-border-color:var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text-emphasis);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-info-border-subtle);--bs-list-group-active-color:var(--bs-info-bg-subtle);--bs-list-group-active-bg:var(--bs-info-text-emphasis);--bs-list-group-active-border-color:var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text-emphasis);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-warning-border-subtle);--bs-list-group-active-color:var(--bs-warning-bg-subtle);--bs-list-group-active-bg:var(--bs-warning-text-emphasis);--bs-list-group-active-border-color:var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text-emphasis);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-danger-border-subtle);--bs-list-group-active-color:var(--bs-danger-bg-subtle);--bs-list-group-active-bg:var(--bs-danger-text-emphasis);--bs-list-group-active-border-color:var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text-emphasis);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-light-border-subtle);--bs-list-group-active-color:var(--bs-light-bg-subtle);--bs-list-group-active-bg:var(--bs-light-text-emphasis);--bs-list-group-active-border-color:var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text-emphasis);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-dark-border-subtle);--bs-list-group-active-color:var(--bs-dark-bg-subtle);--bs-list-group-active-bg:var(--bs-dark-text-emphasis);--bs-list-group-active-border-color:var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color:#fff;--bs-btn-close-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3E%3C/svg%3E");--bs-btn-close-opacity:0.4;--bs-btn-close-hover-opacity:1;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(55,90,127,.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;--bs-btn-close-white-filter:invert(1) grayscale(100%) brightness(200%);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;border:0;border-radius:.375rem;box-sizing:content-box;height:1em;opacity:var(--bs-btn-close-opacity);padding:.25em;width:1em}.btn-close,.btn-close:hover{color:var(--bs-btn-close-color)}.btn-close:hover{opacity:var(--bs-btn-close-hover-opacity);text-decoration:none}.btn-close:focus{box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity);outline:0}.btn-close.disabled,.btn-close:disabled{opacity:var(--bs-btn-close-disabled-opacity);pointer-events:none;user-select:none}.btn-close-white,[data-bs-theme=dark] .btn-close{filter:var(--bs-btn-close-white-filter)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:#444;--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:#303030;--bs-toast-header-border-color:var(--bs-border-color-translucent);background-clip:padding-box;background-color:var(--bs-toast-bg);border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);border-radius:var(--bs-toast-border-radius);box-shadow:var(--bs-toast-box-shadow);color:var(--bs-toast-color);font-size:var(--bs-toast-font-size);max-width:100%;pointer-events:auto;width:var(--bs-toast-max-width)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;max-width:100%;pointer-events:none;position:absolute;width:max-content;z-index:var(--bs-toast-zindex)}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{align-items:center;background-clip:padding-box;background-color:var(--bs-toast-header-bg);border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));color:var(--bs-toast-header-color);display:flex;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x)}.toast-header .btn-close{margin-left:var(--bs-toast-padding-x);margin-right:calc(var(--bs-toast-padding-x)*-.5)}.toast-body{word-wrap:break-word;padding:var(--bs-toast-padding-x)}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:#303030;--bs-modal-border-color:#444;--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:var(--bs-box-shadow-sm);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:#444;--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:#444;--bs-modal-footer-border-width:var(--bs-border-width);display:none;height:100%;left:0;outline:0;overflow-x:hidden;overflow-y:auto;position:fixed;top:0;width:100%;z-index:var(--bs-modal-zindex)}.modal-dialog{margin:var(--bs-modal-margin);pointer-events:none;position:relative;width:auto}.modal.fade .modal-dialog{transform:translateY(-50px);transition:transform .3s ease-out}@media(prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin)*2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{align-items:center;display:flex;min-height:calc(100% - var(--bs-modal-margin)*2)}.modal-content{background-clip:padding-box;background-color:var(--bs-modal-bg);border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);color:var(--bs-modal-color);display:flex;flex-direction:column;outline:0;pointer-events:auto;position:relative;width:100%}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;background-color:var(--bs-backdrop-bg);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:var(--bs-backdrop-zindex)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{align-items:center;border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius);display:flex;flex-shrink:0;justify-content:space-between;padding:var(--bs-modal-header-padding)}.modal-header .btn-close{margin:calc(var(--bs-modal-header-padding-y)*-.5) calc(var(--bs-modal-header-padding-x)*-.5) calc(var(--bs-modal-header-padding-y)*-.5) auto;padding:calc(var(--bs-modal-header-padding-y)*.5) calc(var(--bs-modal-header-padding-x)*.5)}.modal-title{line-height:var(--bs-modal-title-line-height);margin-bottom:0}.modal-body{flex:1 1 auto;padding:var(--bs-modal-padding);position:relative}.modal-footer{align-items:center;background-color:var(--bs-modal-footer-bg);border-bottom-left-radius:var(--bs-modal-inner-border-radius);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);display:flex;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap)*.5)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap)*.5)}@media(min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:var(--bs-box-shadow)}.modal-dialog{margin-left:auto;margin-right:auto;max-width:var(--bs-modal-width)}.modal-sm{--bs-modal-width:300px}}@media(min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media(min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media(max-width:575.98px){.modal-fullscreen-sm-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-sm-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media(max-width:767.98px){.modal-fullscreen-md-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-md-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media(max-width:991.98px){.modal-fullscreen-lg-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-lg-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media(max-width:1199.98px){.modal-fullscreen-xl-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-xl-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media(max-width:1399.98px){.modal-fullscreen-xxl-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-xxl-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;word-wrap:break-word;display:block;font-family:var(--bs-font-sans-serif);font-size:var(--bs-tooltip-font-size);font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;margin:var(--bs-tooltip-margin);opacity:0;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:var(--bs-tooltip-zindex)}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;height:var(--bs-tooltip-arrow-height);width:var(--bs-tooltip-arrow-width)}.tooltip .tooltip-arrow:before{border-color:transparent;border-style:solid;content:"";position:absolute}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:calc(var(--bs-tooltip-arrow-height)*-1)}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow:before,.bs-tooltip-top .tooltip-arrow:before{border-top-color:var(--bs-tooltip-bg);border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;top:-1px}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{height:var(--bs-tooltip-arrow-width);left:calc(var(--bs-tooltip-arrow-height)*-1);width:var(--bs-tooltip-arrow-height)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow:before,.bs-tooltip-end .tooltip-arrow:before{border-right-color:var(--bs-tooltip-bg);border-width:calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;right:-1px}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:calc(var(--bs-tooltip-arrow-height)*-1)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow:before,.bs-tooltip-bottom .tooltip-arrow:before{border-bottom-color:var(--bs-tooltip-bg);border-width:0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);bottom:-1px}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{height:var(--bs-tooltip-arrow-width);right:calc(var(--bs-tooltip-arrow-height)*-1);width:var(--bs-tooltip-arrow-height)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow:before,.bs-tooltip-start .tooltip-arrow:before{border-left-color:var(--bs-tooltip-bg);border-width:calc(var(--bs-tooltip-arrow-width)*.5) 0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);left:-1px}.tooltip-inner{background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius);color:var(--bs-tooltip-color);max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);text-align:center}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:#303030;--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:var(--bs-box-shadow);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:inherit;--bs-popover-header-bg:#444;--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);word-wrap:break-word;background-clip:padding-box;background-color:var(--bs-popover-bg);border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius);display:block;font-family:var(--bs-font-sans-serif);font-size:var(--bs-popover-font-size);font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;max-width:var(--bs-popover-max-width);text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:var(--bs-popover-zindex)}.popover .popover-arrow{display:block;height:var(--bs-popover-arrow-height);width:var(--bs-popover-arrow-width)}.popover .popover-arrow:after,.popover .popover-arrow:before{border:0 solid transparent;content:"";display:block;position:absolute}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:before,.bs-popover-top>.popover-arrow:after,.bs-popover-top>.popover-arrow:before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:before,.bs-popover-top>.popover-arrow:before{border-top-color:var(--bs-popover-arrow-border);bottom:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:after,.bs-popover-top>.popover-arrow:after{border-top-color:var(--bs-popover-bg);bottom:var(--bs-popover-border-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{height:var(--bs-popover-arrow-width);left:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:before,.bs-popover-end>.popover-arrow:after,.bs-popover-end>.popover-arrow:before{border-width:calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:before,.bs-popover-end>.popover-arrow:before{border-right-color:var(--bs-popover-arrow-border);left:0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:after,.bs-popover-end>.popover-arrow:after{border-right-color:var(--bs-popover-bg);left:var(--bs-popover-border-width)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:before,.bs-popover-bottom>.popover-arrow:after,.bs-popover-bottom>.popover-arrow:before{border-width:0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:before,.bs-popover-bottom>.popover-arrow:before{border-bottom-color:var(--bs-popover-arrow-border);top:0}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:after,.bs-popover-bottom>.popover-arrow:after{border-bottom-color:var(--bs-popover-bg);top:var(--bs-popover-border-width)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before{border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg);content:"";display:block;left:50%;margin-left:calc(var(--bs-popover-arrow-width)*-.5);position:absolute;top:0;width:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{height:var(--bs-popover-arrow-width);right:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:before,.bs-popover-start>.popover-arrow:after,.bs-popover-start>.popover-arrow:before{border-width:calc(var(--bs-popover-arrow-width)*.5) 0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:before,.bs-popover-start>.popover-arrow:before{border-left-color:var(--bs-popover-arrow-border);right:0}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:after,.bs-popover-start>.popover-arrow:after{border-left-color:var(--bs-popover-bg);right:var(--bs-popover-border-width)}.popover-header{background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius);color:var(--bs-popover-header-color);font-size:var(--bs-popover-header-font-size);margin-bottom:0;padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x)}.popover-header:empty{display:none}.popover-body{color:var(--bs-popover-body-color);padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{overflow:hidden;position:relative;width:100%}.carousel-inner:after{clear:both;content:"";display:block}.carousel-item{backface-visibility:hidden;display:none;float:left;margin-right:-100%;position:relative;transition:transform .6s ease-in-out;width:100%}@media(prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transform:none;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{opacity:1;z-index:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{opacity:0;transition:opacity 0s .6s;z-index:0}@media(prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{align-items:center;background:none;border:0;bottom:0;color:#fff;display:flex;justify-content:center;opacity:.5;padding:0;position:absolute;text-align:center;top:0;transition:opacity .15s ease;width:15%;z-index:1}@media(prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;opacity:.9;outline:0;text-decoration:none}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{background-position:50%;background-repeat:no-repeat;background-size:100% 100%;display:inline-block;height:2rem;width:2rem}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E")}.carousel-indicators{bottom:0;display:flex;justify-content:center;left:0;margin-bottom:1rem;margin-left:15%;margin-right:15%;padding:0;position:absolute;right:0;z-index:2}.carousel-indicators [data-bs-target]{background-clip:padding-box;background-color:#fff;border:0;border-bottom:10px solid transparent;border-top:10px solid transparent;box-sizing:content-box;cursor:pointer;flex:0 1 auto;height:3px;margin-left:3px;margin-right:3px;opacity:.5;padding:0;text-indent:-999px;transition:opacity .6s ease;width:30px}@media(prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{bottom:1.25rem;color:#fff;left:15%;padding-bottom:1.25rem;padding-top:1.25rem;position:absolute;right:15%;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}[data-bs-theme=dark] .carousel .carousel-control-next-icon,[data-bs-theme=dark] .carousel .carousel-control-prev-icon,[data-bs-theme=dark].carousel .carousel-control-next-icon,[data-bs-theme=dark].carousel .carousel-control-prev-icon{filter:invert(1) grayscale(100)}[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target],[data-bs-theme=dark].carousel .carousel-indicators [data-bs-target]{background-color:#000}[data-bs-theme=dark] .carousel .carousel-caption,[data-bs-theme=dark].carousel .carousel-caption{color:#000}.spinner-border,.spinner-grow{animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);border-radius:50%;display:inline-block;height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);width:var(--bs-spinner-width)}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border-right-color:currentcolor;border:var(--bs-spinner-border-width) solid;border-right:var(--bs-spinner-border-width) solid transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media(prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:#444;--bs-offcanvas-box-shadow:var(--bs-box-shadow-sm);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media(max-width:575.98px){.offcanvas-sm{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media(max-width:575.98px)and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media(max-width:575.98px){.offcanvas-sm.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-sm.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-sm.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom,.offcanvas-sm.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-sm.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media(min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(max-width:767.98px){.offcanvas-md{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media(max-width:767.98px)and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media(max-width:767.98px){.offcanvas-md.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-md.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-md.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom,.offcanvas-md.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-md.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media(min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(max-width:991.98px){.offcanvas-lg{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media(max-width:991.98px)and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media(max-width:991.98px){.offcanvas-lg.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-lg.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-lg.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom,.offcanvas-lg.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-lg.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media(min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(max-width:1199.98px){.offcanvas-xl{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media(max-width:1199.98px)and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media(max-width:1199.98px){.offcanvas-xl.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-xl.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-xl.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom,.offcanvas-xl.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-xl.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media(min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(max-width:1399.98px){.offcanvas-xxl{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media(max-width:1399.98px)and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media(max-width:1399.98px){.offcanvas-xxl.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-xxl.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-xxl.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom,.offcanvas-xxl.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-xxl.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media(min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}.offcanvas{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}@media(prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas.offcanvas-bottom,.offcanvas.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{background-color:#000;height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:1040}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{align-items:center;display:flex;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{margin-bottom:calc(var(--bs-offcanvas-padding-y)*-.5);margin-right:calc(var(--bs-offcanvas-padding-x)*-.5);margin-top:calc(var(--bs-offcanvas-padding-y)*-.5);padding:calc(var(--bs-offcanvas-padding-y)*.5) calc(var(--bs-offcanvas-padding-x)*.5)}.offcanvas-title{line-height:var(--bs-offcanvas-title-line-height);margin-bottom:0}.offcanvas-body{flex-grow:1;overflow-y:auto;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.placeholder{background-color:currentcolor;cursor:wait;display:inline-block;min-height:1em;opacity:.5;vertical-align:middle}.placeholder.btn:before{content:"";display:inline-block}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{animation:placeholder-wave 2s linear infinite;mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,.8) 75%,#000 95%);mask-size:200% 100%}@keyframes placeholder-wave{to{mask-position:-200% 0}}.clearfix:after{clear:both;content:"";display:block}.text-bg-primary{background-color:RGBA(var(--bs-primary-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-secondary{background-color:RGBA(var(--bs-secondary-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-success{background-color:RGBA(var(--bs-success-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-info{background-color:RGBA(var(--bs-info-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-warning{background-color:RGBA(var(--bs-warning-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-danger{background-color:RGBA(var(--bs-danger-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-light{background-color:RGBA(var(--bs-light-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-dark{background-color:RGBA(var(--bs-dark-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.link-primary{color:RGBA(var(--bs-primary-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important}.link-primary:focus,.link-primary:hover{color:RGBA(44,72,102,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(44,72,102,var(--bs-link-underline-opacity,1))!important}.link-secondary{color:RGBA(var(--bs-secondary-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important}.link-secondary:focus,.link-secondary:hover{color:RGBA(54,54,54,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(54,54,54,var(--bs-link-underline-opacity,1))!important}.link-success{color:RGBA(var(--bs-success-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important}.link-success:focus,.link-success:hover{color:RGBA(0,150,112,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(0,150,112,var(--bs-link-underline-opacity,1))!important}.link-info{color:RGBA(var(--bs-info-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important}.link-info:focus,.link-info:hover{color:RGBA(42,122,175,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(42,122,175,var(--bs-link-underline-opacity,1))!important}.link-warning{color:RGBA(var(--bs-warning-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important}.link-warning:focus,.link-warning:hover{color:RGBA(194,125,14,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(194,125,14,var(--bs-link-underline-opacity,1))!important}.link-danger{color:RGBA(var(--bs-danger-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important}.link-danger:focus,.link-danger:hover{color:RGBA(185,61,48,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(185,61,48,var(--bs-link-underline-opacity,1))!important}.link-light{color:RGBA(var(--bs-light-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important}.link-light:focus,.link-light:hover{color:RGBA(138,145,151,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(138,145,151,var(--bs-link-underline-opacity,1))!important}.link-dark{color:RGBA(var(--bs-dark-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important}.link-dark:focus,.link-dark:hover{color:RGBA(38,38,38,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(38,38,38,var(--bs-link-underline-opacity,1))!important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-body-emphasis:focus,.link-body-emphasis:hover{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,.75))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,.75))!important}.focus-ring:focus{box-shadow:var(--bs-focus-ring-x,0) var(--bs-focus-ring-y,0) var(--bs-focus-ring-blur,0) var(--bs-focus-ring-width) var(--bs-focus-ring-color);outline:0}.icon-link{align-items:center;backface-visibility:hidden;display:inline-flex;gap:.375rem;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,.5));text-underline-offset:.25em}.icon-link>.bi{fill:currentcolor;flex-shrink:0;height:1em;transition:transform .2s ease-in-out;width:1em}@media(prefers-reduced-motion:reduce){.icon-link>.bi{transition:none}}.icon-link-hover:focus-visible>.bi,.icon-link-hover:hover>.bi{transform:var(--bs-icon-link-transform,translate3d(.25em,0,0))}.ratio{position:relative;width:100%}.ratio:before{content:"";display:block;padding-top:var(--bs-aspect-ratio)}.ratio>*{height:100%;left:0;position:absolute;top:0;width:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{top:0}.fixed-bottom,.fixed-top{left:0;position:fixed;right:0;z-index:1030}.fixed-bottom{bottom:0}.sticky-top{top:0}.sticky-bottom,.sticky-top{position:sticky;z-index:1020}.sticky-bottom{bottom:0}@media(min-width:576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}.sticky-sm-bottom{bottom:0;position:sticky;z-index:1020}}@media(min-width:768px){.sticky-md-top{position:sticky;top:0;z-index:1020}.sticky-md-bottom{bottom:0;position:sticky;z-index:1020}}@media(min-width:992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}.sticky-lg-bottom{bottom:0;position:sticky;z-index:1020}}@media(min-width:1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}.sticky-xl-bottom{bottom:0;position:sticky;z-index:1020}}@media(min-width:1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{bottom:0;position:sticky;z-index:1020}}.hstack{align-items:center;flex-direction:row}.hstack,.vstack{align-self:stretch;display:flex}.vstack{flex:1 1 auto;flex-direction:column}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;white-space:nowrap!important;width:1px!important}.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption),.visually-hidden:not(caption){position:absolute!important}.stretched-link:after{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:1}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{align-self:stretch;background-color:currentcolor;display:inline-block;min-height:1em;opacity:.25;width:var(--bs-border-width)}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{object-fit:contain!important}.object-fit-cover{object-fit:cover!important}.object-fit-fill{object-fit:fill!important}.object-fit-scale{object-fit:scale-down!important}.object-fit-none{object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:var(--bs-box-shadow)!important}.shadow-sm{box-shadow:var(--bs-box-shadow-sm)!important}.shadow-lg{box-shadow:var(--bs-box-shadow-lg)!important}.shadow-none{box-shadow:none!important}.focus-ring-primary{--bs-focus-ring-color:rgba(var(--bs-primary-rgb),var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color:rgba(var(--bs-secondary-rgb),var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color:rgba(var(--bs-success-rgb),var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color:rgba(var(--bs-info-rgb),var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color:rgba(var(--bs-warning-rgb),var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color:rgba(var(--bs-danger-rgb),var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color:rgba(var(--bs-light-rgb),var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color:rgba(var(--bs-dark-rgb),var(--bs-focus-ring-opacity))}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-black{--bs-border-opacity:1;border-color:rgba(var(--bs-black-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-left:0!important;margin-right:0!important}.mx-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-3{margin-left:1rem!important;margin-right:1rem!important}.mx-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-5{margin-left:3rem!important;margin-right:3rem!important}.mx-auto{margin-left:auto!important;margin-right:auto!important}.my-0{margin-bottom:0!important;margin-top:0!important}.my-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-left:0!important;padding-right:0!important}.px-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-3{padding-left:1rem!important;padding-right:1rem!important}.px-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-5{padding-left:3rem!important;padding-right:3rem!important}.py-0{padding-bottom:0!important;padding-top:0!important}.py-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{column-gap:0!important}.column-gap-1{column-gap:.25rem!important}.column-gap-2{column-gap:.5rem!important}.column-gap-3{column-gap:1rem!important}.column-gap-4{column-gap:1.5rem!important}.column-gap-5{column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.425rem + 2.1vw)!important}.fs-2{font-size:calc(1.375rem + 1.5vw)!important}.fs-3{font-size:calc(1.325rem + .9vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:hsla(0,0%,100%,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis)!important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis)!important}.text-success-emphasis{color:var(--bs-success-text-emphasis)!important}.text-info-emphasis{color:var(--bs-info-text-emphasis)!important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis)!important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis)!important}.text-light-emphasis{color:var(--bs-light-text-emphasis)!important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis)!important}.link-opacity-10,.link-opacity-10-hover:hover{--bs-link-opacity:0.1}.link-opacity-25,.link-opacity-25-hover:hover{--bs-link-opacity:0.25}.link-opacity-50,.link-opacity-50-hover:hover{--bs-link-opacity:0.5}.link-opacity-75,.link-opacity-75-hover:hover{--bs-link-opacity:0.75}.link-opacity-100,.link-opacity-100-hover:hover{--bs-link-opacity:1}.link-offset-1,.link-offset-1-hover:hover{text-underline-offset:.125em!important}.link-offset-2,.link-offset-2-hover:hover{text-underline-offset:.25em!important}.link-offset-3,.link-offset-3-hover:hover{text-underline-offset:.375em!important}.link-underline-primary{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-secondary{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-success{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important}.link-underline-info{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important}.link-underline-warning{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important}.link-underline-danger{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important}.link-underline-light{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important}.link-underline-dark{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important}.link-underline{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-underline-opacity-0,.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity:0}.link-underline-opacity-10,.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity:0.1}.link-underline-opacity-25,.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity:0.25}.link-underline-opacity-50,.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity:0.5}.link-underline-opacity-75,.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity:0.75}.link-underline-opacity-100,.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{user-select:all!important}.user-select-auto{user-select:auto!important}.user-select-none{user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-xxl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-bottom-right-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-bottom-right-radius:0!important;border-top-right-radius:0!important}.rounded-end-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-bottom-right-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-end-circle{border-bottom-right-radius:50%!important;border-top-right-radius:50%!important}.rounded-end-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-left-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}.rounded-bottom-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-bottom-right-radius:var(--bs-border-radius-xxl)!important}.rounded-bottom-circle{border-bottom-left-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-bottom-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-top-left-radius:var(--bs-border-radius-xxl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media(min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{object-fit:contain!important}.object-fit-sm-cover{object-fit:cover!important}.object-fit-sm-fill{object-fit:fill!important}.object-fit-sm-scale{object-fit:scale-down!important}.object-fit-sm-none{object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-left:0!important;margin-right:0!important}.mx-sm-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-sm-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-sm-3{margin-left:1rem!important;margin-right:1rem!important}.mx-sm-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-sm-5{margin-left:3rem!important;margin-right:3rem!important}.mx-sm-auto{margin-left:auto!important;margin-right:auto!important}.my-sm-0{margin-bottom:0!important;margin-top:0!important}.my-sm-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-sm-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-sm-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-sm-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-sm-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-sm-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-left:0!important;padding-right:0!important}.px-sm-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-sm-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-sm-3{padding-left:1rem!important;padding-right:1rem!important}.px-sm-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-sm-5{padding-left:3rem!important;padding-right:3rem!important}.py-sm-0{padding-bottom:0!important;padding-top:0!important}.py-sm-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-sm-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-sm-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-sm-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-sm-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{column-gap:0!important}.column-gap-sm-1{column-gap:.25rem!important}.column-gap-sm-2{column-gap:.5rem!important}.column-gap-sm-3{column-gap:1rem!important}.column-gap-sm-4{column-gap:1.5rem!important}.column-gap-sm-5{column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media(min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{object-fit:contain!important}.object-fit-md-cover{object-fit:cover!important}.object-fit-md-fill{object-fit:fill!important}.object-fit-md-scale{object-fit:scale-down!important}.object-fit-md-none{object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-left:0!important;margin-right:0!important}.mx-md-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-md-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-md-3{margin-left:1rem!important;margin-right:1rem!important}.mx-md-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-md-5{margin-left:3rem!important;margin-right:3rem!important}.mx-md-auto{margin-left:auto!important;margin-right:auto!important}.my-md-0{margin-bottom:0!important;margin-top:0!important}.my-md-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-md-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-md-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-md-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-md-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-md-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-left:0!important;padding-right:0!important}.px-md-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-md-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-md-3{padding-left:1rem!important;padding-right:1rem!important}.px-md-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-md-5{padding-left:3rem!important;padding-right:3rem!important}.py-md-0{padding-bottom:0!important;padding-top:0!important}.py-md-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-md-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-md-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-md-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-md-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{column-gap:0!important}.column-gap-md-1{column-gap:.25rem!important}.column-gap-md-2{column-gap:.5rem!important}.column-gap-md-3{column-gap:1rem!important}.column-gap-md-4{column-gap:1.5rem!important}.column-gap-md-5{column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media(min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{object-fit:contain!important}.object-fit-lg-cover{object-fit:cover!important}.object-fit-lg-fill{object-fit:fill!important}.object-fit-lg-scale{object-fit:scale-down!important}.object-fit-lg-none{object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-left:0!important;margin-right:0!important}.mx-lg-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-lg-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-lg-3{margin-left:1rem!important;margin-right:1rem!important}.mx-lg-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-lg-5{margin-left:3rem!important;margin-right:3rem!important}.mx-lg-auto{margin-left:auto!important;margin-right:auto!important}.my-lg-0{margin-bottom:0!important;margin-top:0!important}.my-lg-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-lg-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-lg-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-lg-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-lg-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-lg-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-left:0!important;padding-right:0!important}.px-lg-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-lg-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-lg-3{padding-left:1rem!important;padding-right:1rem!important}.px-lg-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-lg-5{padding-left:3rem!important;padding-right:3rem!important}.py-lg-0{padding-bottom:0!important;padding-top:0!important}.py-lg-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-lg-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-lg-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-lg-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-lg-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{column-gap:0!important}.column-gap-lg-1{column-gap:.25rem!important}.column-gap-lg-2{column-gap:.5rem!important}.column-gap-lg-3{column-gap:1rem!important}.column-gap-lg-4{column-gap:1.5rem!important}.column-gap-lg-5{column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media(min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{object-fit:contain!important}.object-fit-xl-cover{object-fit:cover!important}.object-fit-xl-fill{object-fit:fill!important}.object-fit-xl-scale{object-fit:scale-down!important}.object-fit-xl-none{object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-left:0!important;margin-right:0!important}.mx-xl-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-xl-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-xl-3{margin-left:1rem!important;margin-right:1rem!important}.mx-xl-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-xl-5{margin-left:3rem!important;margin-right:3rem!important}.mx-xl-auto{margin-left:auto!important;margin-right:auto!important}.my-xl-0{margin-bottom:0!important;margin-top:0!important}.my-xl-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-xl-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-xl-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-xl-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-xl-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-xl-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-left:0!important;padding-right:0!important}.px-xl-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-xl-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-xl-3{padding-left:1rem!important;padding-right:1rem!important}.px-xl-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-xl-5{padding-left:3rem!important;padding-right:3rem!important}.py-xl-0{padding-bottom:0!important;padding-top:0!important}.py-xl-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-xl-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-xl-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-xl-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-xl-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{column-gap:0!important}.column-gap-xl-1{column-gap:.25rem!important}.column-gap-xl-2{column-gap:.5rem!important}.column-gap-xl-3{column-gap:1rem!important}.column-gap-xl-4{column-gap:1.5rem!important}.column-gap-xl-5{column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media(min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{object-fit:contain!important}.object-fit-xxl-cover{object-fit:cover!important}.object-fit-xxl-fill{object-fit:fill!important}.object-fit-xxl-scale{object-fit:scale-down!important}.object-fit-xxl-none{object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-left:0!important;margin-right:0!important}.mx-xxl-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-xxl-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-xxl-3{margin-left:1rem!important;margin-right:1rem!important}.mx-xxl-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-xxl-5{margin-left:3rem!important;margin-right:3rem!important}.mx-xxl-auto{margin-left:auto!important;margin-right:auto!important}.my-xxl-0{margin-bottom:0!important;margin-top:0!important}.my-xxl-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-xxl-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-xxl-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-xxl-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-xxl-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-xxl-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-left:0!important;padding-right:0!important}.px-xxl-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-xxl-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-xxl-3{padding-left:1rem!important;padding-right:1rem!important}.px-xxl-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-xxl-5{padding-left:3rem!important;padding-right:3rem!important}.py-xxl-0{padding-bottom:0!important;padding-top:0!important}.py-xxl-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-xxl-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-xxl-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-xxl-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-xxl-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{column-gap:0!important}.column-gap-xxl-1{column-gap:.25rem!important}.column-gap-xxl-2{column-gap:.5rem!important}.column-gap-xxl-3{column-gap:1rem!important}.column-gap-xxl-4{column-gap:1.5rem!important}.column-gap-xxl-5{column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media(min-width:1200px){.fs-1{font-size:3rem!important}.fs-2{font-size:2.5rem!important}.fs-3{font-size:2rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}}.blockquote-footer{color:#888}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>label{color:#888}.breadcrumb a,.nav-pills .nav-item.open .nav-link,.nav-pills .nav-item.open .nav-link:focus,.nav-pills .nav-item.open .nav-link:hover,.nav-pills .nav-link,.nav-pills .nav-link.active,.nav-pills .nav-link.active:focus,.nav-pills .nav-link.active:hover,.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover,.nav-tabs .nav-link,.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover{color:#fff}.pagination a:hover{text-decoration:none}.alert{border:none;color:#fff}.alert .alert-link,.alert a{color:#fff;text-decoration:underline}.alert-primary{background-color:#375a7f}.alert-secondary{background-color:#444}.alert-success{background-color:#00bc8c}.alert-info{background-color:#3498db}.alert-warning{background-color:#f39c12}.alert-danger{background-color:#e74c3c}.alert-light{background-color:#adb5bd}.alert-dark{background-color:#303030}.tooltip{--bs-tooltip-bg:var(--bs-tertiary-bg);--bs-tooltip-color:var(--bs-emphasis-color)}body{min-height:100vh}.border-bottom{border-width:3px!important}.xl{font-size:1.5em;line-height:1em;vertical-align:-.075em}.border-top{border-width:3px!important}.rebooting,tr.hide{display:none}td.value{width:80%} \ No newline at end of file diff --git a/components/wifi-manager/webapp/dist/css/index.1ab179394339385e0a02.css.gz b/components/wifi-manager/webapp/dist/css/index.1ab179394339385e0a02.css.gz deleted file mode 100644 index 42965f2f..00000000 Binary files a/components/wifi-manager/webapp/dist/css/index.1ab179394339385e0a02.css.gz and /dev/null differ diff --git a/components/wifi-manager/webapp/dist/css/index.e8b465b654eff617dd1c.css b/components/wifi-manager/webapp/dist/css/index.e8b465b654eff617dd1c.css new file mode 100644 index 00000000..60cf410a --- /dev/null +++ b/components/wifi-manager/webapp/dist/css/index.e8b465b654eff617dd1c.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v5.3.2 (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg,hsla(0,0%,100%,.15),hsla(0,0%,100%,0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33,37,41,.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33,37,41,.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0,0,0,.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0,0,0,.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0,0,0,.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0,0,0,.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0,0,0,.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13,110,253,.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}*,:after,:before{box-sizing:border-box}@media(prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);background-color:var(--bs-body-bg);color:var(--bs-body-color);font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);margin:0;text-align:var(--bs-body-text-align)}.h1,.h2,.h3,.h4,.h5,h1,h2,h3,h4,h5{color:var(--bs-heading-color);font-weight:500;line-height:1.2;margin-bottom:.5rem;margin-top:0}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media(min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media(min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media(min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media(min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}p{margin-top:0}address,p{margin-bottom:1rem}address{font-style:normal;line-height:inherit}ul{margin-bottom:1rem;margin-top:0;padding-left:2rem}ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}b,strong{font-weight:bolder}.small,small{font-size:.875em}sub{bottom:-.25em;font-size:.75em;line-height:0;position:relative;vertical-align:baseline}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}svg{vertical-align:middle}table{border-collapse:collapse;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,th,thead,tr{border:0 solid;border-color:inherit}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,select{font-family:inherit;font-size:inherit;line-height:inherit;margin:0}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{border-style:none;padding:0}fieldset{border:0;margin:0;min-width:0;padding:0}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{-webkit-appearance:button;font:inherit}output{display:inline-block}progress{vertical-align:baseline}[hidden]{display:none!important}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-left:calc(var(--bs-gutter-x)*-.5);margin-right:calc(var(--bs-gutter-x)*-.5);margin-top:calc(var(--bs-gutter-y)*-1)}.row>*{flex-shrink:0;margin-top:var(--bs-gutter-y);max-width:100%;padding-left:calc(var(--bs-gutter-x)*.5);padding-right:calc(var(--bs-gutter-x)*.5);width:100%}.col{flex:1 0 0%}.col-auto{flex:0 0 auto;width:auto}.table{--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:var(--bs-emphasis-color);--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-emphasis-color);--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb),0.05);--bs-table-active-color:var(--bs-emphasis-color);--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb),0.1);--bs-table-hover-color:var(--bs-emphasis-color);--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb),0.075);border-color:var(--bs-table-border-color);margin-bottom:1rem;vertical-align:top;width:100%}.table>:not(caption)>*>*{background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)));color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));padding:.5rem}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state:var(--bs-table-hover-color);--bs-table-bg-state:var(--bs-table-hover-bg)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#a6b5cc;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000}.table-primary,.table-secondary{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#b5b6b7;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#a7b9b1;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000}.table-success,.table-warning{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#ccc2a4;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#c6acae;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000}.table-danger,.table-light{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#c6c7c8;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#4d5154;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.col-form-label{font-size:inherit;line-height:1.5;margin-bottom:0;padding-bottom:calc(.375rem + var(--bs-border-width));padding-top:calc(.375rem + var(--bs-border-width))}.form-text{color:var(--bs-secondary-color);font-size:.875em;margin-top:.25rem}.form-control{appearance:none;background-clip:padding-box;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);color:var(--bs-body-color);display:block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media(prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{background-color:var(--bs-body-bg);border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);color:var(--bs-body-color);outline:0}.form-control::-webkit-date-and-time-value{height:1.5em;margin:0;min-width:85px}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::file-selector-button{background-color:var(--bs-tertiary-bg);border:0 solid;border-color:inherit;border-inline-end-width:var(--bs-border-width);border-radius:0;color:var(--bs-body-color);margin:-.375rem -.75rem;margin-inline-end:.75rem;padding:.375rem .75rem;pointer-events:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-sm{border-radius:var(--bs-border-radius-sm);font-size:.875rem;min-height:calc(1.5em + .5rem + var(--bs-border-width)*2);padding:.25rem .5rem}.form-control-sm::file-selector-button{margin:-.25rem -.5rem;margin-inline-end:.5rem;padding:.25rem .5rem}.form-check{display:block;margin-bottom:.125rem;min-height:1.5rem;padding-left:1.5em}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-input{--bs-form-check-bg:var(--bs-body-bg);appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-position:50%;background-repeat:no-repeat;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);flex-shrink:0;height:1em;margin-top:.25em;print-color-adjust:exact;vertical-align:top;width:1em}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3E%3C/svg%3E")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='2' fill='%23fff'/%3E%3C/svg%3E")}.form-check-input[type=checkbox]:indeterminate{--bs-form-check-bg-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3E%3C/svg%3E");background-color:#0d6efd;border-color:#0d6efd}.form-check-input:disabled{filter:none;opacity:.5;pointer-events:none}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-check-inline{display:inline-block;margin-right:1rem}.form-control.is-valid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem)}.form-control.is-valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid,.form-control.is-valid:focus{border-color:var(--bs-form-valid-border-color)}.form-check-input.is-valid:checked{background-color:var(--bs-form-valid-color)}.form-check-input.is-valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label{color:var(--bs-form-valid-color)}.invalid-feedback{color:var(--bs-form-invalid-color);display:none;font-size:.875em;margin-top:.25rem;width:100%}.is-invalid~.invalid-feedback{display:block}.form-control.is-invalid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem)}.form-control.is-invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid,.form-control.is-invalid:focus{border-color:var(--bs-form-invalid-border-color)}.form-check-input.is-invalid:checked{background-color:var(--bs-form-invalid-color)}.form-check-input.is-invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label{color:var(--bs-form-invalid-color)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 hsla(0,0%,100%,.15),0 1px 1px rgba(0,0,0,.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb),.5);background-color:var(--bs-btn-bg);border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);color:var(--bs-btn-color);cursor:pointer;display:inline-block;font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;user-select:none;vertical-align:middle}@media(prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);color:var(--bs-btn-hover-color)}.btn:focus-visible{background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);box-shadow:var(--bs-btn-focus-box-shadow);color:var(--bs-btn-hover-color);outline:0}.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color);color:var(--bs-btn-active-color)}.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);color:var(--bs-btn-disabled-color);opacity:var(--bs-btn-disabled-opacity);pointer-events:none}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.dropdown-divider{border-top:1px solid var(--bs-dropdown-divider-bg);height:0;margin:var(--bs-dropdown-divider-margin-y) 0;opacity:1;overflow:hidden}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;list-style:none;margin-bottom:0;padding-left:0}.nav-link{background:none;border:0;color:var(--bs-nav-link-color);display:block;font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media(prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);cursor:default;pointer-events:none}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb),0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb),0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb),0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb),1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb),1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb),1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba(33, 37, 41, 0.75)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb),0.15);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x);position:relative}.navbar-brand{color:var(--bs-navbar-brand-color);font-size:var(--bs-navbar-brand-font-size);margin-right:var(--bs-navbar-brand-margin-end);padding-bottom:var(--bs-navbar-brand-padding-y);padding-top:var(--bs-navbar-brand-padding-y);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;list-style:none;margin-bottom:0;padding-left:0}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-collapse{align-items:center;flex-basis:100%;flex-grow:1}.navbar-toggler{background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);color:var(--bs-navbar-color);font-size:var(--bs-navbar-toggler-font-size);line-height:1;padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);transition:var(--bs-navbar-toggler-transition)}@media(prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width);outline:0;text-decoration:none}.navbar-toggler-icon{background-image:var(--bs-navbar-toggler-icon-bg);background-position:50%;background-repeat:no-repeat;background-size:100%;display:inline-block;height:1.5em;vertical-align:middle;width:1.5em}@media(min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}.navbar-dark{--bs-navbar-color:hsla(0,0%,100%,.55);--bs-navbar-hover-color:hsla(0,0%,100%,.75);--bs-navbar-disabled-color:hsla(0,0%,100%,.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:hsla(0,0%,100%,.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.55)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb),0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;word-wrap:break-word;background-clip:border-box;background-color:var(--bs-card-bg);border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius);color:var(--bs-body-color);display:flex;flex-direction:column;height:var(--bs-card-height);min-width:0;position:relative}.card-body{color:var(--bs-card-color);flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x)}.card-header{background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color);color:var(--bs-card-cap-color);margin-bottom:0;padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);border-radius:var(--bs-badge-border-radius);color:var(--bs-badge-color);display:inline-block;font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);text-align:center;vertical-align:baseline;white-space:nowrap}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius);color:var(--bs-alert-color);margin-bottom:var(--bs-alert-margin-bottom);padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);position:relative}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius);font-size:var(--bs-progress-font-size);height:var(--bs-progress-height)}.progress,.progress-bar{display:flex;overflow:hidden}.progress-bar{background-color:var(--bs-progress-bar-bg);color:var(--bs-progress-bar-color);flex-direction:column;justify-content:center;text-align:center;transition:var(--bs-progress-bar-transition);white-space:nowrap}@media(prefers-reduced-motion:reduce){.progress-bar{transition:none}}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3E%3C/svg%3E");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13,110,253,.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;--bs-btn-close-white-filter:invert(1) grayscale(100%) brightness(200%);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;border:0;border-radius:.375rem;box-sizing:content-box;height:1em;opacity:var(--bs-btn-close-opacity);padding:.25em;width:1em}.btn-close,.btn-close:hover{color:var(--bs-btn-close-color)}.btn-close:hover{opacity:var(--bs-btn-close-hover-opacity);text-decoration:none}.btn-close:focus{box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity);outline:0}.btn-close.disabled,.btn-close:disabled{opacity:var(--bs-btn-close-disabled-opacity);pointer-events:none;user-select:none}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb),0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb),0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);background-clip:padding-box;background-color:var(--bs-toast-bg);border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);border-radius:var(--bs-toast-border-radius);box-shadow:var(--bs-toast-box-shadow);color:var(--bs-toast-color);font-size:var(--bs-toast-font-size);max-width:100%;pointer-events:auto;width:var(--bs-toast-max-width)}.toast:not(.show){display:none}.toast-header{align-items:center;background-clip:padding-box;background-color:var(--bs-toast-header-bg);border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));color:var(--bs-toast-header-color);display:flex;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x)}.toast-header .btn-close{margin-left:var(--bs-toast-padding-x);margin-right:calc(var(--bs-toast-padding-x)*-.5)}.toast-body{word-wrap:break-word;padding:var(--bs-toast-padding-x)}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:var(--bs-box-shadow-sm);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);display:none;height:100%;left:0;outline:0;overflow-x:hidden;overflow-y:auto;position:fixed;top:0;width:100%;z-index:var(--bs-modal-zindex)}.modal-dialog{margin:var(--bs-modal-margin);pointer-events:none;position:relative;width:auto}.modal.fade .modal-dialog{transform:translateY(-50px);transition:transform .3s ease-out}@media(prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal-dialog-centered{align-items:center;display:flex;min-height:calc(100% - var(--bs-modal-margin)*2)}.modal-content{background-clip:padding-box;background-color:var(--bs-modal-bg);border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);color:var(--bs-modal-color);display:flex;flex-direction:column;outline:0;pointer-events:auto;position:relative;width:100%}.modal-header{align-items:center;border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius);display:flex;flex-shrink:0;justify-content:space-between;padding:var(--bs-modal-header-padding)}.modal-header .btn-close{margin:calc(var(--bs-modal-header-padding-y)*-.5) calc(var(--bs-modal-header-padding-x)*-.5) calc(var(--bs-modal-header-padding-y)*-.5) auto;padding:calc(var(--bs-modal-header-padding-y)*.5) calc(var(--bs-modal-header-padding-x)*.5)}.modal-title{line-height:var(--bs-modal-title-line-height);margin-bottom:0}.modal-body{flex:1 1 auto;padding:var(--bs-modal-padding);position:relative}.modal-footer{align-items:center;background-color:var(--bs-modal-footer-bg);border-bottom-left-radius:var(--bs-modal-inner-border-radius);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);display:flex;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap)*.5)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap)*.5)}@media(min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:var(--bs-box-shadow)}.modal-dialog{margin-left:auto;margin-right:auto;max-width:var(--bs-modal-width)}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;word-wrap:break-word;display:block;font-family:var(--bs-font-sans-serif);font-size:var(--bs-tooltip-font-size);font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;margin:var(--bs-tooltip-margin);opacity:0;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:var(--bs-tooltip-zindex)}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.spinner-border{animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);border-radius:50%;display:inline-block;height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);width:var(--bs-spinner-width)}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border-right-color:currentcolor;border:var(--bs-spinner-border-width) solid;border-right:var(--bs-spinner-border-width) solid transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@media(prefers-reduced-motion:reduce){.spinner-border{--bs-spinner-animation-speed:1.5s}}.placeholder{background-color:currentcolor;cursor:wait;display:inline-block;min-height:1em;opacity:.5;vertical-align:middle}.placeholder.btn:before{content:"";display:inline-block}@keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-wave{to{mask-position:-200% 0}}.fixed-bottom{bottom:0;left:0;position:fixed;right:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}.d-flex{display:flex!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.flex-column{flex-direction:column!important}.justify-content-between{justify-content:space-between!important}.mt-1{margin-top:.25rem!important}.mb-3{margin-bottom:1rem!important}.p-3{padding:1rem!important}.pt-0{padding-top:0!important}.pb-0{padding-bottom:0!important}.text-center{text-align:center!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.visible{visibility:visible!important}body{min-height:100vh}.border-bottom,.border-top{border-width:3px!important}.rebooting,tr.hide{display:none}td.value{width:80%} \ No newline at end of file diff --git a/components/wifi-manager/webapp/dist/css/index.e8b465b654eff617dd1c.css.gz b/components/wifi-manager/webapp/dist/css/index.e8b465b654eff617dd1c.css.gz new file mode 100644 index 00000000..34ca6420 Binary files /dev/null and b/components/wifi-manager/webapp/dist/css/index.e8b465b654eff617dd1c.css.gz differ diff --git a/components/wifi-manager/webapp/dist/index.html b/components/wifi-manager/webapp/dist/index.html index aedce50f..b99ff5ab 100644 --- a/components/wifi-manager/webapp/dist/index.html +++ b/components/wifi-manager/webapp/dist/index.html @@ -1 +1 @@ -
Software Updates
VersionDate/TimePlatformBranchBit Depth
Local Firmware Upload
KeyValue
Usage Templates

Supported: flac,pcm,mp3,ogg (mad,mpg for specific mp3 codec)
Close output device after timeout seconds, default is to keep it open while player is 'on'
Logs: all|slimproto|stream|decode|output, level: info|debug|sdebug
Supported: flac,pcm,mp3,ogg (mad,mpg for specific mp3 codec)
Format: ab:cd:ef:12:34:56
<maxrate>|<minrate><maxrate><rate1><rate2><rate3>

WiFi Status
Logs
TimestampMessage
Tasks
#Task NameCPUStateMin StackBase PriorityCur Priority
Credits

squeezelite-esp32
© 2020, philippe44, sle118, daduke
This software is released under the MIT License.

This app would not be possible without the following libraries:

  • squeezelite, © 2012-2019, Adrian Smith and Ralph Irving. Licensed under the GPL License.
  • esp32-wifi-manager, © 2017-2019, Tony Pottier. Licensed under the MIT License.
  • SpinKit, © 2015, Tobias Ahlin. Licensed under the MIT License.
  • jQuery, The jQuery Foundation. Licensed under the MIT License.
  • cJSON, © 2009-2017, Dave Gamble and cJSON contributors. Licensed under the MIT License.
  • esp32-rotary-encoder, © 2011-2019, David Antliff and Ben Buxton. Licensed under the GPL License.
  • tarablessd1306, © 2017-2018, Tara Keeling. Licensed under the MIT license.
  • CSpot, © 2020 feelfreelinux & alufers. Licensed under the GPL License
Extras/Overrides
\ No newline at end of file +
Software Updates
VersionDate/TimePlatformBranchBit Depth
Local Firmware Upload
KeyValue
Usage Templates

Supported: flac,pcm,mp3,ogg (mad,mpg for specific mp3 codec)
Close output device after timeout seconds, default is to keep it open while player is 'on'
Logs: all|slimproto|stream|decode|output, level: info|debug|sdebug
Supported: flac,pcm,mp3,ogg (mad,mpg for specific mp3 codec)
Format: ab:cd:ef:12:34:56
<maxrate>|<minrate><maxrate><rate1><rate2><rate3>

WiFi Status
Logs
TimestampMessage
Tasks
#Task NameCPUStateMin StackBase PriorityCur Priority
Credits

squeezelite-esp32
© 2020, philippe44, sle118, daduke
This software is released under the MIT License.

This app would not be possible without the following libraries:

  • squeezelite, © 2012-2019, Adrian Smith and Ralph Irving. Licensed under the GPL License.
  • esp32-wifi-manager, © 2017-2019, Tony Pottier. Licensed under the MIT License.
  • SpinKit, © 2015, Tobias Ahlin. Licensed under the MIT License.
  • jQuery, The jQuery Foundation. Licensed under the MIT License.
  • cJSON, © 2009-2017, Dave Gamble and cJSON contributors. Licensed under the MIT License.
  • esp32-rotary-encoder, © 2011-2019, David Antliff and Ben Buxton. Licensed under the GPL License.
  • tarablessd1306, © 2017-2018, Tara Keeling. Licensed under the MIT license.
  • CSpot, © 2020 feelfreelinux & alufers. Licensed under the GPL License
Extras/Overrides
\ No newline at end of file diff --git a/components/wifi-manager/webapp/dist/index.html.gz b/components/wifi-manager/webapp/dist/index.html.gz index 5a380a48..f0a947e9 100644 Binary files a/components/wifi-manager/webapp/dist/index.html.gz and b/components/wifi-manager/webapp/dist/index.html.gz differ diff --git a/components/wifi-manager/webapp/dist/js/index.1b8c7b.bundle.js b/components/wifi-manager/webapp/dist/js/index.1b8c7b.bundle.js deleted file mode 100644 index 2a300c72..00000000 --- a/components/wifi-manager/webapp/dist/js/index.1b8c7b.bundle.js +++ /dev/null @@ -1,2 +0,0 @@ -(()=>{"use strict";var t,e={322:(t,e,n)=>{n.r(e);var a=n(531),s=n(152),o=n(687),i=n.n(o),c=n(955),r=n(755);function l(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!n){if(Array.isArray(t)||(n=function(t,e){if(!t)return;if("string"==typeof t)return u(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);"Object"===n&&t.constructor&&(n=t.constructor.name);if("Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return u(t,e)}(t))||e&&t&&"number"==typeof t.length){n&&(t=n);var a=0,s=function(){};return{s,n:function(){return a>=t.length?{done:!0}:{done:!1,value:t[a++]}},e:function(t){throw t},f:s}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i=!0,c=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return i=t.done,t},e:function(t){c=!0,o=t},f:function(){try{i||null==n.return||n.return()}finally{if(c)throw o}}}}function u(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,a=new Array(e);n")}}),Object.assign(Date.prototype,{toLocalShort:function(){return this.toLocaleString(void 0,{dateStyle:"short",timeStyle:"short"})}});var v=1,b=17,g=2,S=18,_=4,y=20,w=8,T=24,E={bt_playing:{label:"",icon:"media_bluetooth_on"},bt_disconnected:{label:"",icon:"media_bluetooth_off"},bt_neutral:{label:"",icon:"bluetooth"},bt_connecting:{label:"",icon:"bluetooth_searching"},bt_connected:{label:"",icon:"bluetooth_connected"},bt_disabled:{label:"",icon:"bluetooth_disabled"},play_arrow:{label:"",icon:"play_circle_filled"},pause:{label:"",icon:"pause_circle"},stop:{label:"",icon:"stop_circle"},"":{label:"",icon:""}},O=[{icon:"battery_0_bar",label:"▪",ranges:[{f:5.8,t:6.8},{f:8.8,t:10.2}]},{icon:"battery_2_bar",label:"▪▪",ranges:[{f:6.8,t:7.4},{f:10.2,t:11.1}]},{icon:"battery_3_bar",label:"▪▪▪",ranges:[{f:7.4,t:7.5},{f:11.1,t:11.25}]},{icon:"battery_4_bar",label:"▪▪▪▪",ranges:[{f:7.5,t:7.8},{f:11.25,t:11.7}]}],A=[{desc:"Idle",sub:["bt_neutral"]},{desc:"Discovering",sub:["bt_connecting"]},{desc:"Discovered",sub:["bt_connecting"]},{desc:"Unconnected",sub:["bt_disconnected"]},{desc:"Connecting",sub:["bt_connecting"]},{desc:"Connected",sub:["bt_connected","play_arrow","bt_playing","pause","stop"]},{desc:"Disconnecting",sub:["bt_disconnected"]}],k={MESSAGING_INFO:"badge-success",MESSAGING_WARNING:"badge-warning",MESSAGING_ERROR:"badge-danger"},N={OK:0,FAIL:1,DISC:2,LOST:3,RESTORE:4,ETH:5},x={0:"eRunning",1:"eReady",2:"eBlocked",3:"eSuspended",4:"eDeleted"},R={NONE:0,REBOOT_TO_RECOVERY:2,SET_FWURL:5,FLASHING:6,DONE:7,UPLOADING:8,ERROR:9,UPLOADCOMPLETE:10,_state:-1,olderRecovery:!1,statusText:"",flashURL:"",flashFileName:"",statusPercent:0,Completed:!1,recovery:!1,prevRecovery:!1,updateModal:new bootstrap.Modal(document.getElementById("otadiv"),{}),reset:function(){return this.olderRecovery=!1,this.statusText="",this.statusPercent=-1,this.flashURL="",this.flashFileName=void 0,this.UpdateProgress(),r("#rTable tr.release").removeClass("table-success table-warning"),r(".flact").prop("disabled",!1),r("#flashfilename").value=null,r("#fw-url-input").value=null,this.isStateError()||(r("span#flash-status").html(""),r("#fwProgressLabel").parent().removeClass("bg-danger")),this._state=this.NONE,this},isStateUploadComplete:function(){return this._state==this.UPLOADCOMPLETE},isStateError:function(){return this._state==this.ERROR},isStateNone:function(){return this._state==this.NONE},isStateRebootRecovery:function(){return this._state==this.REBOOT_TO_RECOVERY},isStateSetUrl:function(){return this._state==this.SET_FWURL},isStateFlashing:function(){return this._state==this.FLASHING},isStateDone:function(){return this._state==this.DONE},isStateUploading:function(){return this._state==this.UPLOADING},init:function(){return this._state=this.NONE,this},SetStateError:function(){return this._state=this.ERROR,r("#fwProgressLabel").parent().addClass("bg-danger"),this},SetStateNone:function(){return this._state=this.NONE,this},SetStateRebootRecovery:function(){return this._state=this.REBOOT_TO_RECOVERY,this.SetStatusText("Starting recovery mode."),r.ajax({url:"/recovery.json",context:this,dataType:"text",method:"POST",cache:!1,contentType:"application/json; charset=utf-8",data:JSON.stringify({timestamp:Date.now()}),error:function(t,e,n){var a;this.setOTAError("Unexpected error while trying to restart to recovery. (status=".concat(null!==(a=t.status)&&void 0!==a?a:"",", error=").concat(null!=n?n:""," ) "))},complete:function(t){this.SetStatusText("Waiting for system to boot.")}}),this},SetStateSetUrl:function(){return this._state=this.SET_FWURL,this.statusText="Sending firmware download location.",G({fwurl:{value:this.flashURL,type:33}}),this},SetStateFlashing:function(){return this._state=this.FLASHING,this},SetStateDone:function(){return this._state=this.DONE,this.reset(),this},SetStateUploading:function(){return this._state=this.UPLOADING,this.SetStatusText("Sending file to device.")},SetStateUploadComplete:function(){return this._state=this.UPLOADCOMPLETE,this},isFlashExecuting:function(){return!0==(this._state!=this.UPLOADING&&(""!==this.statusText||this.statusPercent>=0))},toString:function(){var t=this;return Object.keys(this).find((function(e){return t[e]===t._state}))},setOTATargets:function(){this.flashURL="",this.flashFileName="",this.flashURL=r("#fw-url-input").val();var t=r("#flashfilename")[0].files;return t.length>0&&(this.flashFileName=t[0]),0==this.flashFileName.length&&0==this.flashURL.length&&this.setOTAError("Invalid url or file. Cannot start OTA"),this},setOTAError:function(t){return this.SetStateError().SetStatusPercent(0).SetStatusText(t).reset(),this},ShowDialog:function(){return this.isStateNone()||(this.updateModal.show(),r(".flact").prop("disabled",!0)),this},SetStatusPercent:function(t){var e=this.statusPercent!=t;return this.statusPercent=t,e&&(this.isStateUploading()||this.isStateFlashing()||this.SetStateFlashing(),100==t&&(this.isStateFlashing()?this.SetStateDone():this.isStateUploading()&&(this.statusPercent=0,this.SetStateFlashing())),this.UpdateProgress().ShowDialog()),this},SetStatusText:function(t){var e=this.statusText!=t;return this.statusText=t,e&&(r("span#flash-status").html(this.statusText),this.ShowDialog()),this},UpdateProgress:function(){return r(".progress-bar").css("width",this.statusPercent+"%").attr("aria-valuenow",this.statusPercent).text(this.statusPercent+"%"),r(".progress-bar").html((this.isStateDone()?100:this.statusPercent)+"%"),this},StartOTA:function(){return this.logEvent(this.StartOTA.name),r("#fwProgressLabel").parent().removeClass("bg-danger"),this.setOTATargets(),this.isStateError()||(W?this.SetStateFlashing().TargetReadyStartOTA():this.SetStateRebootRecovery()),this},UploadLocalFile:function(){this.SetStateUploading();var t=new XMLHttpRequest;t.context=this;var e=this.HandleUploadProgressEvent.bind(this),n=this.setOTAError.bind(this);t.upload.addEventListener("progress",e,!1),t.onreadystatechange=function(){4===t.readyState&&(0!==t.status&&404!==t.status||n("Upload Failed. Recovery version might not support uploading. Please use web update instead."))},t.open("POST","/flash.json",!0),t.send(this.flashFileName)},TargetReadyStartOTA:function(){return W&&this.prevRecovery&&!this.isStateRebootRecovery()&&!this.isStateFlashing()?this:(this.logEvent(this.TargetReadyStartOTA.name),W?(this.prevRecovery=!0,void(""!==this.flashFileName?this.UploadLocalFile():""!=this.flashURL?this.SetStateSetUrl():this.setOTAError("Invalid URL or file name while trying to start the OTa process"))):(console.error("Event TargetReadyStartOTA fired in the wrong mode "),this))},HandleUploadProgressEvent:function(t){this.logEvent(this.HandleUploadProgressEvent.name),this.SetStateUploading().SetStatusPercent(Math.round(t.loaded/t.total*100)).SetStatusText("Uploading file to device")},EventTargetStatus:function(t){var e,n;this.isStateNone()||this.logEvent(this.EventTargetStatus.name),null!==(e=t.ota_pct)&&void 0!==e&&e&&(this.olderRecovery=!0,this.SetStatusPercent(t.ota_pct)),""!=(null!==(n=t.ota_dsc)&&void 0!==n?n:"")&&(this.olderRecovery=!0,this.SetStatusText(t.ota_dsc)),null!=t.recovery&&(this.recovery=1===t.recovery),this.isStateRebootRecovery()&&this.recovery&&this.TargetReadyStartOTA()},EventOTAMessageClass:function(t){this.logEvent(this.EventOTAMessageClass.name);var e=JSON.parse(t);this.SetStatusPercent(e.ota_pct).SetStatusText(e.ota_dsc)},logEvent:function(t){console.log("".concat(t,", flash state ").concat(this.toString(),", recovery: ").concat(this.recovery,", ota pct: ").concat(this.statusPercent,", ota desc: ").concat(this.statusText))}};window.hideSurrounding=function(t){r(t).parent().parent().hide()};var C=!1,I=2500;function G(t){var e={timestamp:Date.now(),config:t};r.ajax({url:"/config.json",dataType:"text",method:"POST",cache:!1,contentType:"application/json; charset=utf-8",data:JSON.stringify(e),error:L})}function j(t){for(var e,n,a={},s="",o=t.match(/("[^"]+"|'[^']+'|\S+)/g),i=0;i0&&(e=e.substring(0,e.indexOf(" ")));return e}(a),n=function(t){var e;t.n&&(e=t.n.replace(/"/g,"").replace(/'/g,""));return e}(a);var u={btname:null,n:null};if(a.o&&"BT"===e.toUpperCase()){var d=j(a.o);d.name&&(u.btname=d.name),delete a.o}return a.n&&(u.n=a.n,delete a.n),{name:n,output:e,options:a,otherValues:s,otherOptions:u}}function P(){return it.hasOwnProperty("ip")&&"0.0.0.0"!=it.ip&&""!=it.ip}function M(t){return P()?t.icon:t.label}function U(t){r("#o_type").children("span").css({display:"none"});var e=!1;"bt"===t?(e="bt"!==Q&&""!==Q,Q="bt"):"spdif"===t?(e="spdif"!==Q&&""!==Q,Q="spdif"):(e="i2s"!==Q&&""!==Q,Q="i2s"),r("#"+Q).prop("checked",!0),r("#o_"+Q).css({display:"inline"}),e&&Object.keys(q[Q]).forEach((function(t){r("#cmd_opt_".concat(t)).val(q[Q][t])}))}function L(t,e,n){console.log(t.status),console.log(n),""!==n&&Nt(n,"MESSAGING_ERROR")}function F(t,e,n){var a=arguments.length>3&&void 0!==arguments[3]&&arguments[3],s="table-success";"MESSAGING_WARNING"===e?s="table-warning":"MESSAGING_ERROR"===e&&(s="table-danger"),r("#toast_"+t).removeClass("table-success").removeClass("table-warning").removeClass("table-danger").addClass(s).addClass("show");var o=n.substring(0,n.length-1).encodeHTML().replace(/\n/g,"
");o=(r("#msg_"+t).html().length>0&&a?r("#msg_"+t).html()+"
":"")+o,r("#msg_"+t).html(o)}window.hFlash=function(){r("#flashfilename").value=null,R.StartOTA()},window.handleReboot=function(t){"reboot_ota"==t?(r("#reboot_ota_nav").removeClass("active").prop("disabled",!0),dt(500,"","reboot_ota")):(r("#reboot_nav").removeClass("active"),dt(500,"",t))};var D,J="https://api.github.com/repos/sle118/squeezelite-esp32/releases",W=!1,H=!1,B="",q={i2s:{b:"500:2000",C:"30",W:"",Z:"96000",o:"I2S"},spdif:{b:"500:2000",C:"30",W:"",Z:"48000",o:"SPDIF"},bt:{b:"500:2000",C:"30",W:"",Z:"44100",o:"BT"}},Y={codecs:["flac","pcm","mp3","ogg","aac","wma","alac","dsd","mad","mpg"]},z=0,V="MESSAGING_INFO",Z={},K=null,Q="",X="",$="Squeezelite-ESP32",tt="",et=$,nt="",at=$,st="",ot="#cfg-audio-bt_source-sink_name",it={},ct={},rt="",lt={CONN:0,MAN:1,STS:2};function ut(t){var e={};r("input.nvs").each((function(n,a){if(t)e[a.id]=a.value;else{var s=parseInt(a.attributes.nvs_type.value,10);""!==a.id&&(e[a.id]={},e[a.id].value=s===v||s===b||s===g||s===S||s===_||s===y||s===w||s===T?parseInt(a.value):a.value,e[a.id].type=s)}}));var n=r("#nvs-new-key").val(),a=r("#nvs-new-value").val();return""!==n&&(t?e[n]=a:(e[n]={},e[n].value=a,e[n].type=33)),e}function dt(t,e){var n="/"+(arguments.length>2&&void 0!==arguments[2]?arguments[2]:"reboot")+".json";r("tbody#tasks").empty(),r("#tasks_sect").css("visibility","collapse"),h.resolve({cmdname:e,url:n}).delay(t).then((function(t){t.cmdname.length>0?F(t.cmdname,"MESSAGING_WARNING","System is rebooting.\n",!0):Nt("System is rebooting.\n","MESSAGING_WARNING"),console.log("now triggering reboot"),r("button[onclick*='handleReboot']").addClass("rebooting"),r.ajax({url:t.url,dataType:"text",method:"POST",cache:!1,contentType:"application/json; charset=utf-8",data:JSON.stringify({timestamp:Date.now()}),error:L,complete:function(){console.log("reboot call completed"),h.resolve(t).delay(6e3).then((function(t){t.cmdname.length>0&&function(t){r("#toast_"+t).removeClass("table-success").removeClass("table-warning").removeClass("table-danger").addClass("table-success").removeClass("show"),r("#msg_"+t).html("")}(t.cmdname),At(),kt()}))}})}))}function ht(t){return r(".upf").filter((function(){return r(this).text().toUpperCase()===t.toUpperCase()})).length>0&&(r("#splf").val(t).trigger("input"),!0)}function pt(t,e){var n="cmd_opt_".concat(t),a="".concat(n,"-error"),s=r("#".concat(a)),o=r("#".concat(n));return s&&0!=s.length||(o.after('
')),s=r("#".concat(a))),0==e.length?(s.hide(),o.removeClass("is-invalid"),o.addClass("is-valid"),s.text("")):(s.show(),s.text(e),o.removeClass("is-valid"),o.addClass("is-invalid")),s}function ft(t){return t>=-55?{label:"****",icon:"signal_wifi_statusbar_4_bar"}:t>=-60?{label:"***",icon:"network_wifi_3_bar"}:t>=-65?{label:"**",icon:"network_wifi_2_bar"}:t>=-70?{label:"*",icon:"network_wifi_1_bar"}:{label:".",icon:"signal_wifi_statusbar_null"}}function mt(){var t;(null===(t=it)||void 0===t?void 0:t.urc)!==N.ETH&&(r.ajaxSetup({timeout:3e3}),r.getJSON("/scan.json",(0,a.Z)(i().mark((function t(){return i().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,Rt(2e3);case 2:r.getJSON("/ap.json",(function(t){t.length>0&&(t.sort((function(t,e){var n=t.rssi,a=e.rssi;return na?-1:0})),bt(t))}));case 3:case"end":return t.stop()}}),t)})))))}function vt(t,e,n){var a=ft(e),s={label:0==n?"🔓":"🔒",icon:0==n?"no_encryption":"lock"};return''.concat(t,'\n ').concat(M(a),'\n \t\n ').concat(M(s),"\n ")}function bt(t){var e,n="";if(r("#wifiTable tr td:first-of-type").text(""),r("#wifiTable tr").removeClass("table-success table-warning"),t&&(t.forEach((function(t){n+=vt(t.ssid,t.rssi,t.auth)})),r("#wifiTable").html(n)),0==r(".manual_add").length&&(r("#wifiTable").append(vt("Manual add",0,0)),r("#wifiTable tr:last").addClass("table-light text-dark").addClass("manual_add")),!it.ssid||it.urc!==N.OK&&it.urc!==N.RESTORE)(null===(e=it)||void 0===e?void 0:e.urc)!==N.ETH&&r("span#foot-if").html("");else{var a,s='#wifiTable td:contains("'.concat(it.ssid,'")');if(0==r(s).filter((function(){return r(this).text()===it.ssid})).length)r("#wifiTable").prepend("".concat(vt(it.ssid,null!==(a=it.rssi)&&void 0!==a?a:0,0)));r(s).filter((function(){return r(this).text()===it.ssid})).siblings().first().html("✓").parent().addClass(it.urc===N.OK?"table-success":"table-warning"),r("span#foot-if").html("SSID: ".concat(it.ssid,", IP: ").concat(it.ip,"")),r("#wifiStsIcon").html(ft(it.rssi))}}function gt(t){console.debug(this.toLocaleString()+"\t"+t.nme+"\t"+t.cpu+"\t"+x[t.st]+"\t"+t.minstk+"\t"+t.bprio+"\t"+t.cprio+"\t"+t.num),r("tbody#tasks").append(''+t.num+""+t.nme+""+t.cpu+""+x[t.st]+""+t.minstk+""+t.bprio+""+t.cprio+"")}function St(t){return r("".concat(ot," option:contains('").concat(t,"')"))}function _t(){r.ajaxSetup({timeout:I}),r.getJSON("/messages.json",function(){var t=(0,a.Z)(i().mark((function t(e){var n,a,s,o,c,u,d,h,p,f;return i().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:n=l(e),t.prev=1,s=i().mark((function t(){var e,n;return i().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:e=a.value,n=e.current_time-e.sent_time,(o=new Date).setTime(o.getTime()-n),t.t0=e.class,t.next="MESSAGING_CLASS_OTA"===t.t0?7:"MESSAGING_CLASS_STATS"===t.t0?9:"MESSAGING_CLASS_SYSTEM"===t.t0?14:"MESSAGING_CLASS_CFGCMD"===t.t0?16:"MESSAGING_CLASS_BT"===t.t0?19:23;break;case 7:return R.EventOTAMessageClass(e.message),t.abrupt("break",24);case 9:return c=JSON.parse(e.message),console.debug(o.toLocalShort()+" - Number of running tasks: "+c.ntasks),console.debug(o.toLocalShort()+"\tname\tcpu\tstate\tminstk\tbprio\tcprio\tnum"),c.tasks?("collapse"===r("#tasks_sect").css("visibility")&&r("#tasks_sect").css("visibility","visible"),r("tbody#tasks").html(""),c.tasks.sort((function(t,e){return e.cpu-t.cpu})).forEach(gt,o)):"visible"===r("#tasks_sect").css("visibility")&&(r("tbody#tasks").empty(),r("#tasks_sect").css("visibility","collapse")),t.abrupt("break",24);case 14:return xt(e,o),t.abrupt("break",24);case 16:return F((u=e.message.split(/([^\n]*)\n([\s\S]*)/g))[1],e.type,u[2],!0),t.abrupt("break",24);case 19:if(r("#cfg-audio-bt_source-sink_name").is("input")){for(d=r("#cfg-audio-bt_source-sink_name")[0].attributes,h="",p=0;p "))}return JSON.parse(e.message).forEach((function(t){St(t.name).length>0||(r("#cfg-audio-bt_source-sink_name").append("")),xt({type:e.type,message:"BT Audio device found: ".concat(t.name," RSSI: ").concat(t.rssi," ")},o)),St(t.name).attr("data-bs-description","".concat(t.name," (").concat(t.rssi,"dB)")).attr("rssi",t.rssi).attr("value",t.name).text("".concat(t.name," [").concat(t.rssi,"dB]")).trigger("change")})),r(ot).append(r("".concat(ot," option")).remove().sort((function(t,e){return console.log("".concat(parseInt(r(t).attr("rssi"))," < ").concat(parseInt(r(e).attr("rssi"))," ? ")),parseInt(r(t).attr("rssi"))".concat(it.ip,""))):(r(".if_wifi").show(),bt())),yt(t)}function Et(){r.ajaxSetup({timeout:2e3}),r.getJSON("/status.json",(function(t){var e;if(function(t){var e;1===(null!==(e=t.recovery)&&void 0!==e?e:0)?(W=!0,r(".recovery_element").show(),r(".ota_element").hide(),r("#boot-button").html("Reboot"),r("#boot-form").attr("action","/reboot_ota.json")):(!W&&H&&(H=!1,setTimeout(_t,I)),W=!1,r(".recovery_element").hide(),r(".ota_element").show(),r("#boot-button").html("Recovery"),r("#boot-form").attr("action","/recovery.json"))}(t),f(),Tt(t),function(t){var e="",n="";if(void 0!==t.bt_status&&void 0!==t.bt_sub_status){var a=A[t.bt_status].sub[t.bt_sub_status];a?(e=E[a],n=A[t.bt_status].desc):(e=E.bt_connected,n="Output status")}r("#o_type").attr("title",n),r("#o_bt").html(P()?e.label:e.text)}(t),R.EventTargetStatus(t),t.depth&&(16==t.depth?r("#cmd_opt_R").show():r("#cmd_opt_R").hide()),t.project_name&&""!==t.project_name&&(et=t.project_name),t.platform_name&&""!==t.platform_name&&(at=t.platform_name),""===nt&&(nt=et),""===nt&&(nt="Squeezelite-ESP32"),t.version&&""!==t.version?($=t.version,r("#navtitle").html("".concat(nt).concat(W?"
[recovery]":"")),r("span#foot-fw").html("fw: ".concat($,", mode: ").concat(W?"Recovery":et,""))):r("span#flash-status").html(""),t.Voltage){var n=function(t){for(var e=0,n=O;e
'.concat(e.help.encodeHTML().replace(/\n/g,"
"),'
'),e.argtable&&e.argtable.forEach((function(n){var a=n.datatype||"",s=e.name+"-"+n.longopts,i=Ot(t,e.name,n.longopts),c="hasvalue="+n.hasvalue+" ";c+='longopts="'+n.longopts+'" ',c+='shortopts="'+n.shortopts+'" ',c+="checkbox="+n.checkbox+" ",c+='cmdname="'+e.name+'" ',c+='id="'+s+'" name="'+s+'" hasvalue="'+n.hasvalue+'" ';var r=n.mincount>0?"bg-success":"";"hidden"===n.glossary&&(c+=' style="visibility: hidden;"'),n.checkbox?o+='
"):(o+='
"),a.includes("|")?(r=a.startsWith("+")?" multiple ":"",a=a.replace("<","").replace("=","").replace(">",""),o+=""):o+='")),o+="".concat(n.checkbox?"
":"",'Previous value: ').concat(n.checkbox?i?"Checked":"Unchecked":i||"","").concat(n.checkbox?"":"
")})),o+='
\n '),o+=a?'\n'):''),o+="
",a?r(s).append(o):r("#commands-list").append(o)}})),r(".sclk").off("click").on("click",(function(){runCommand(this,!1)})),r(".cclk").off("click").on("click",(function(){runCommand(this,!0)})),t.commands.forEach((function(e){r("[cmdname="+e.name+"]:input").val(""),r("[cmdname="+e.name+"]:checkbox").prop("checked",!1),e.argtable&&e.argtable.forEach((function(n){var a="#"+e.name+"-"+n.longopts,s=Ot(t,e.name,n.longopts);n.checkbox?r(a)[0].checked=s:(void 0!==s&&r(a).val(s).trigger("change"),0===r(a)[0].value.length&&(n.datatype||"").includes("|")&&(r(a)[0].value="--"))}))})),0!=r("#cfg-hw-preset-model_config").length&&(C||(C=!0,r("#cfg-hw-preset-model_config").html(""),r.getJSON("https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/",{_:(new Date).getTime()},(function(t){r.each(t,(function(t,e){r("#cfg-hw-preset-model_config").append("")),""!==st&&st==e.name&&r("#cfg-hw-preset-model_config").val(st)})),""!==st&&"#prev_preset".show().val(st)})).fail((function(t,e,n){var a=e+", "+n;console.log("Request Failed: "+a)}))))})).fail((function(t,e,n){404==t.status?r(".orec").hide():L(t,0,n),r("#commands-list").empty()}))}function kt(){r.ajaxSetup({timeout:7e3}),r.getJSON("/config.json",(function(t){r("#nvsTable tr").remove();var e=t.config?t.config:t;Z=e,B="",Object.keys(e).sort().forEach((function(t){var n=e[t].value;"autoexec1"===t?function(t){var e=j(t);e.output.toUpperCase().startsWith("I2S")?U("i2s"):e.output.toUpperCase().startsWith("SPDIF")?U("spdif"):e.output.toUpperCase().startsWith("BT")&&(e.otherOptions.btname&&(B=e.otherOptions.btname),U("bt"));if(Object.keys(e.options).forEach((function(t){var n=e.options[t];r("#cmd_opt_".concat(t)).hasOwnProperty("checked")?r("#cmd_opt_".concat(t))[0].checked=n:r("#cmd_opt_".concat(t)).val(n)})),e.options.hasOwnProperty("u")){var n=e.options.u.split(":"),a=(0,s.Z)(n,2),o=a[0],i=a[1];r("#resample_".concat(o)).prop("checked",!0),i&&r("#resample_i").prop("checked",!0)}e.options.hasOwnProperty("s")&&("-disable"===e.options.s?r("#disable-squeezelite")[0].checked=!0:r("#disable-squeezelite")[0].checked=!1)}(n):"host_name"===t?(n=n.replaceAll('"',""),r("input#dhcp-name1").val(n),r("input#dhcp-name2").val(n),0==r("#cmd_opt_n").length&&r("#cmd_opt_n").val(n),document.title=n,X=n):"rel_api"===t?J=n:"enable_airplay"===t?r("#s_airplay").css({display:m(n)?"inline":"none"}):"enable_cspot"===t?r("#s_cspot").css({display:m(n)?"inline":"none"}):"preset_name"==t?st=n:"board_model"==t&&(nt=n),r("tbody#nvsTable").append(""+t+""),r("input#"+t).val(e[t].value)})),B.length>0&&r("#cfg-audio-bt_source-sink_name").val(B),r("tbody#nvsTable").append(""),t.gpio?(r("#pins").show(),r("tbody#gpiotable tr").remove(),t.gpio.forEach((function(t){r("tbody#gpiotable").append("'+t.group+""+t.name+""+t.gpio+""+(t.fixed?"Fixed":"Configuration")+"")}))):r("#pins").hide()})).fail((function(t,e,n){L(t,0,n)}))}function Nt(t,e){xt({message:t,type:e},new Date)}function xt(t,e){var n="table-success";"MESSAGING_WARNING"===t.type?(n="table-warning","MESSAGING_INFO"===V&&(V="MESSAGING_WARNING")):"MESSAGING_ERROR"===t.type&&("MESSAGING_INFO"!==V&&"MESSAGING_WARNING"!==V||(V="MESSAGING_ERROR"),n="table-danger"),++z>0&&(r("#msgcnt").removeClass("badge-success"),r("#msgcnt").removeClass("badge-warning"),r("#msgcnt").removeClass("badge-danger"),r("#msgcnt").addClass(k[V]),r("#msgcnt").text(z)),r("#syslogTable").append(""+e.toLocalShort()+""+t.message.encodeHTML()+"")}function Rt(t){return new h((function(e){return setTimeout(e,t)}))}h.prototype.delay=function(t){return this.then((function(e){return new h((function(n){setTimeout((function(){n(e)}),t)}))}),(function(e){return new h((function(n,a){setTimeout((function(){a(e)}),t)}))}))},window.saveAutoexec1=function(t){F("cfg-audio-tmpl","MESSAGING_INFO","Saving.\n",!1);var e="".concat("squeezelite "," -o ").concat(Q," ");r(".sqcmd").each((function(){var t=p(r(this)),n=t.opt,a=t.val;if(n&&n.length>0&&"boolean"==typeof a||a.length>0){var s=":"===n?n:" -".concat(n," ");a="boolean"==typeof a?"":a,e+="".concat(s," ").concat(a)}}));var n=r("#cmd_opt_R input[name=resample]:checked");n.length>0&&""!==n.attr("suffix")&&(e+=n.attr("suffix"),r("#resample_i").is(":checked")&&"true"==n.attr("aint")&&(e+=r("#resample_i").attr("suffix"))),"bt"===Q&&F("cfg-audio-tmpl","MESSAGING_INFO","Remember to configure the Bluetooth audio device name.\n",!0),e+=function(t){for(var e=" ",n=0,a=Object.entries(t);n8&&(r(this).val().startsWith("http://")||r(this).val().startsWith("https://"))?r("#start-flash").show():r("#start-flash").hide()})),r(".upSrch").on("input",(function(){var t=this.value;r("#rTable tr").removeClass(this.id+"_hide"),t.length>0&&r("#rTable td:nth-child(".concat(r(this).parent().index()+1,")")).filter((function(){return!r(this).text().toUpperCase().includes(t.toUpperCase())})).parent().addClass(this.id+"_hide"),r('[class*="_hide"]').hide(),r("#rTable tr").not('[class*="_hide"]').show()})),setTimeout(mt,1500),r("#options input").on("input",(function(){var t=p(this),e=t.opt,n=t.val;if("c"===e||"e"===e){"cmd_opt_".concat(e,"_codec-error");var a=n.split(",").map((function(t){return t.trim()})).filter((function(t){return!Y.codecs.includes(t)}));pt(e,a.length>0?"Invalid codec(s) ".concat(a.join(", ")):"")}if("m"===e){pt(e,/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/.test(n)?"":"Invalid MAC address")}if("r"===e){pt(e,/^(\d+\.?\d*|\.\d+)-(\d+\.?\d*|\.\d+)$|^(\d+\.?\d*)$|^(\d+\.?\d*,)+\d+\.?\d*$/.test(n)?"":"Invalid rate(s) ".concat(n,". Acceptable format: |-|,,"))}})),r("#WifiConnectDialog")[0].addEventListener("shown.bs.modal",(function(t){r("*[class*='connecting']").hide(),null!=t&&t.relatedTarget&&(ct.Action=lt.CONN,r(t.relatedTarget).children("td:eq(1)").text()==it.ssid?ct.Action=lt.STS:r(t.relatedTarget).is(":last-child")?(ct.Action=lt.MAN,ct.ssid="",r("#manual_ssid").val(ct.ssid)):(ct.ssid=r(t.relatedTarget).children("td:eq(1)").text(),r("#manual_ssid").val(ct.ssid))),ct.Action!==lt.STS?(r(".connecting-init").show(),r("#manual_ssid").trigger("focus")):yt()})),r("#WifiConnectDialog")[0].addEventListener("hidden.bs.modal",(function(){r("#WifiConnectDialog input").val("")})),r("#uCnfrm")[0].addEventListener("shown.bs.modal",(function(){r("#selectedFWURL").text(r("#fw-url-input").val())})),r("input#show-commands")[0].checked=1===K,r('a[href^="#tab-commands"]').hide(),r("#load-nvs").on("click",(function(){r("#nvsfilename").trigger("click")})),r("#nvsfilename").on("change",(function(){if("function"!=typeof window.FileReader)throw"The file API isn't supported on this browser.";if(!this.files)throw"This browser does not support the `files` property of the file input.";if(this.files[0]){var t=this.files[0],e=new FileReader;e.onload=function(t){var e={};try{e=JSON.parse(t.target.result)}catch(t){alert("Parsing failed!\r\n "+t)}r("input.nvs").each((function(t,n){r(this).parent().removeClass("bg-warning").removeClass("bg-success"),e[n.id]&&(e[n.id]!==n.value?(console.log("Changed "+n.id+" "+n.value+"==>"+e[n.id]),r(this).parent().addClass("bg-warning"),r(this).val(e[n.id])):r(this).parent().addClass("bg-success"))})),r("input.nvs").children(".bg-warning")&&alert("Highlighted values were changed. Press Commit to change on the device")},e.readAsText(t),this.value=null}})),r("#clear-syslog").on("click",(function(){z=0,V="MESSAGING_INFO",r("#msgcnt").text(""),r("#syslogTable").html("")})),r("#ok-credits").on("click",(function(){r("#credits").slideUp("fast",(function(){})),r("#app").slideDown("fast",(function(){}))})),r("#acredits").on("click",(function(t){t.preventDefault(),r("#app").slideUp("fast",(function(){})),r("#credits").slideDown("fast",(function(){}))})),r("input#show-commands").on("click",(function(){this.checked=this.checked?1:0,this.checked?(r('a[href^="#tab-commands"]').show(),K=1):(K=0,r('a[href^="#tab-commands"]').hide())})),r("#disable-squeezelite").on("click",(function(){if(this.checked){var t=r("#cmd_opt_s").val();r("#cmd_opt_s").data("originalValue",t),r("#cmd_opt_s").val("-disable")}else{var e=r("#cmd_opt_s").data("originalValue");r("#cmd_opt_s").val(e||"")}})),r("input#show-nvs").on("click",(function(){this.checked=this.checked?1:0,c.Z.set("show-nvs",this.checked?"Y":"N"),f()})),r("#btn_reboot_recovery").on("click",(function(){handleReboot("recovery")})),r("#btn_reboot").on("click",(function(){handleReboot("reboot")})),r("#btn_flash").on("click",(function(){hFlash()})),r("#save-autoexec1").on("click",(function(){saveAutoexec1(!1)})),r("#commit-autoexec1").on("click",(function(){saveAutoexec1(!0)})),r("#btn_disconnect").on("click",(function(){it={},bt(),r.ajax({url:"/connect.json",dataType:"text",method:"DELETE",cache:!1,contentType:"application/json; charset=utf-8",data:JSON.stringify({timestamp:Date.now()})})})),r("#btnJoin").on("click",(function(){handleConnect()})),r("#reboot_nav").on("click",(function(){handleReboot("reboot")})),r("#reboot_ota_nav").on("click",(function(){handleReboot("reboot_ota")})),r("#save-as-nvs").on("click",(function(){var t=ut(!0),e=document.createElement("a");e.href=URL.createObjectURL(new Blob([JSON.stringify(t,null,2)],{type:"text/plain"})),e.setAttribute("download","nvs_config_"+X+"_"+Date.now()+"json"),document.body.appendChild(e),e.click(),document.body.removeChild(e)})),r("#save-nvs").on("click",(function(){G(ut(!1))})),r("#fwUpload").on("click",(function(){0===document.getElementById("flashfilename").files.length?alert("No file selected!"):(r("#fw-url-input").value=null,R.StartOTA())})),r("[name=output-tmpl]").on("click",(function(){U(this.id)})),r("#chkUpdates").on("click",(function(){r("#rTable").html(""),r.getJSON(J,(function(t){var e=[];t.forEach((function(t){var n=t.name.split("#")[3];e.includes(n)||e.push(n)}));var n="";e.forEach((function(t){n+='"})),r("#fwbranch").append(n),t.forEach((function(t){var e="";t.assets.forEach((function(t){t.name.match(/\.bin$/)&&(e=t.browser_download_url)}));var n=t.name.split("#"),a=n[0],s=n[2],o=n[3],i=a.substr(a.lastIndexOf("-")+1);i="32"==i||"16"==i?i:"";var c=t.body;c=(c=(c=c.replace(/'/gi,'"')).replace(/[\s\S]+(### Revision Log[\s\S]+)### ESP-IDF Version Used[\s\S]+/,"$1")).replace(/- \(.+?\) /g,"- ").encodeHTML(),r("#rTable").append("\n ").concat(a,"").concat(new Date(t.created_at).toLocalShort(),"\n ").concat(s,"").concat(o,"").concat(i,""))})),r("#searchfw").css("display","inline"),ht(at)||ht(et),r("#rTable tr.release").on("click",(function(){var t=this.attributes.fwurl.value;D&&(t=t.replace(/.*\/download\//,D+"/plugins/SqueezeESP32/firmware/")),r("#fw-url-input").val(t),r("#start-flash").show(),r("#rTable tr.release").removeClass("table-success table-warning"),r(this).addClass("table-success table-warning")}))})).fail((function(){alert("failed to fetch release history!")}))})),r("#fwcheck").on("click",(function(){r("#releaseTable").html(""),r("#fwbranch").empty(),r.getJSON(J,(function(t){var e,n=0,a=[];t.forEach((function(t){var e=t.name.split("#")[3];a.includes(e)||a.push(e)})),a.forEach((function(t){e+='"})),r("#fwbranch").append(e),t.forEach((function(t){var e="";t.assets.forEach((function(t){t.name.match(/\.bin$/)&&(e=t.browser_download_url)}));var a=t.name.split("#"),s=a[0],o=a[1],i=a[2],c=a[3],l=t.body;l=(l=(l=l.replace(/'/gi,'"')).replace(/[\s\S]+(### Revision Log[\s\S]+)### ESP-IDF Version Used[\s\S]+/,"$1")).replace(/- \(.+?\) /g,"- ");var u=n++>6?" hide":"";r("#releaseTable").append(""+s+""+new Date(t.created_at).toLocalShort()+""+i+""+o+""+c+"")})),n>7&&(r("#releaseTable").append(""),r("#showallbutton").on("click",(function(){r("tr.hide").removeClass("hide"),r("tr#showall").addClass("hide")}))),r("#searchfw").css("display","inline")})).fail((function(){alert("failed to fetch release history!")}))})),r("#updateAP").on("click",(function(){mt(),console.log("refresh AP")})),kt(),At(),_t(),Et()})),window.setURL=function(t){var e=t.dataset.url;r('[data-bs-url^="http"]').addClass("btn-success").removeClass("btn-danger"),r('[data-bs-url="'+e+'"]').addClass("btn-danger").removeClass("btn-success"),D&&(e=e.replace(/.*\/download\//,D+"/plugins/SqueezeESP32/firmware/")),r("#fwurl").val(e)},window.runCommand=function(t,e){var n=t.attributes.cmdname.value;F(t.attributes.cmdname.value,"MESSAGING_INFO","Executing.",!1);var a=document.getElementById("flds-"+n),o=null==a?void 0:a.querySelectorAll("select,input");if("cfg-hw-preset"===n)return function(t,e){var n=JSON.parse(t[0].value),a=t[0].attributes.cmdname.value;console.log("selected model: ".concat(n.name));for(var o={timestamp:Date.now(),config:{model_config:{value:n.name,type:33}}},i=0,c=Object.entries(n.config);i{n.r(e)},607:(t,e,n)=>{n(138),n(393),n(861),n(322)},861:t=>{t.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAb1BMVEXIycuswsKMjI4rqqZyc3RQlpQ6jIEmJifW2dq5ursppJ8Om4zC0NAFdGYmmpb///8Hg3O4x8cHkoEggX0jko5Ks6/P0dM5r6ocoZb3+PgiiYVevrp/y8bg4uOS09FtxMDs7+7M6um529qoysik2tiNn72gAAAAF3RSTlP94Fr/Wf39BP26/////////////////kibhL0AAAGjSURBVDjLbZMJkoMgEEWtmETEJWpkiSC45P5nnF4wk7HmW2jLfzYIdFYUxbXUYp5nIbTOUFoLAR2ivIKZFQXYuu6TahSHmdAlAqWub0/QNI1jSxrHacKeWw9EdtH1xHbbyiRgCJn67JqVAr9nO2fJnBDMoUuYEvsfmxnJBM66Zj8/iYmaAPKlOvRNJAC/fz8OefINEAngAbYPEMiHTJCCAZrACciVMpCCgDEBKwsAowymMO3IAP3Btqa5vYJx0ZlcOSUZaE/AWznvnTHOyfZ/wMUQvAIg/wb27QNEH94BgGj+APsZiF8AXAhQQEMwkIYYLW7xvsENoyUoF0I0ysf0F2O743kDQNXzXM8+j8Eb6byzDEz7gtpsO1PgrXG5Nd6btNTP+YXarKTny1uQ9JiAN6vbqT9au+BzMQjAWtlq6BiYttdjiVVVqfXxWFWFkk6Cz0DTdYOFPmpHAAK/YQCJoTppQJ8A3TAxVAAhR439Bg5tKe7NgSDEje3mDsf+ovuGCUbYZb/BwoHS6ykHMYfo/U6lx8Xb/+qo3U/x/lf+VP9c/j9c3zy20WEMxgAAAABJRU5ErkJggg=="}},n={};function a(t){var s=n[t];if(void 0!==s)return s.exports;var o=n[t]={id:t,loaded:!1,exports:{}};return e[t].call(o.exports,o,o.exports,a),o.loaded=!0,o.exports}a.m=e,t=[],a.O=(e,n,s,o)=>{if(!n){var i=1/0;for(u=0;u=o)&&Object.keys(a.O).every((t=>a.O[t](n[r])))?n.splice(r--,1):(c=!1,o0&&t[u-1][2]>o;u--)t[u]=t[u-1];t[u]=[n,s,o]},a.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return a.d(e,{a:e}),e},a.d=(t,e)=>{for(var n in e)a.o(e,n)&&!a.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),a.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),a.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},a.nmd=t=>(t.paths=[],t.children||(t.children=[]),t),(()=>{var t={826:0};a.O.j=e=>0===t[e];var e=(e,n)=>{var s,o,[i,c,r]=n,l=0;if(i.some((e=>0!==t[e]))){for(s in c)a.o(c,s)&&(a.m[s]=c[s]);if(r)var u=r(a)}for(e&&e(n);la(607)));s=a.O(s)})(); -//# sourceMappingURL=index.1b8c7b.bundle.js.map \ No newline at end of file diff --git a/components/wifi-manager/webapp/dist/js/index.1b8c7b.bundle.js.gz b/components/wifi-manager/webapp/dist/js/index.1b8c7b.bundle.js.gz deleted file mode 100644 index 7dd7f928..00000000 Binary files a/components/wifi-manager/webapp/dist/js/index.1b8c7b.bundle.js.gz and /dev/null differ diff --git a/components/wifi-manager/webapp/dist/js/index.1b8c7b.bundle.js.map b/components/wifi-manager/webapp/dist/js/index.1b8c7b.bundle.js.map deleted file mode 100644 index e596d847..00000000 --- a/components/wifi-manager/webapp/dist/js/index.1b8c7b.bundle.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"./js/index.1b8c7b.bundle.js","mappings":"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","sources":["webpack://squeezelite-esp32/webpack/runtime/chunk loaded","webpack://squeezelite-esp32/./src/js/custom.js","webpack://squeezelite-esp32/./src/index.ts","webpack://squeezelite-esp32/webpack/bootstrap","webpack://squeezelite-esp32/webpack/runtime/compat get default export","webpack://squeezelite-esp32/webpack/runtime/define property getters","webpack://squeezelite-esp32/webpack/runtime/global","webpack://squeezelite-esp32/webpack/runtime/hasOwnProperty shorthand","webpack://squeezelite-esp32/webpack/runtime/make namespace object","webpack://squeezelite-esp32/webpack/runtime/node module decorator","webpack://squeezelite-esp32/webpack/runtime/jsonp chunk loading","webpack://squeezelite-esp32/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","var he = require('he');\nvar Promise = require('es6-promise').Promise;\nwindow.bootstrap = require('bootstrap');\nimport Cookies from 'js-cookie';\n\n\n\nif (!String.prototype.format) {\n Object.assign(String.prototype, {\n format() {\n const args = arguments;\n return this.replace(/{(\\d+)}/g, function (match, number) {\n return typeof args[number] !== 'undefined' ? args[number] : match;\n });\n },\n });\n}\nif (!String.prototype.encodeHTML) {\n Object.assign(String.prototype, {\n encodeHTML() {\n return he.encode(this).replace(/\\n/g, '
');\n },\n });\n}\nObject.assign(Date.prototype, {\n toLocalShort() {\n const opt = { dateStyle: 'short', timeStyle: 'short' };\n return this.toLocaleString(undefined, opt);\n },\n});\nfunction get_control_option_value(obj) {\n let ctrl,id,val,opt;\n let radio = false;\n let checked = false;\n if (typeof (obj) === 'string') {\n id = obj;\n ctrl = $(`#${id}`);\n } else {\n id = $(obj).attr('id');\n ctrl = $(obj);\n }\n if(ctrl.attr('type') === 'checkbox'){\n opt = $(obj).checked?id.replace('cmd_opt_', ''):'';\n val = true;\n }\n else {\n opt = id.replace('cmd_opt_', '');\n val = $(obj).val();\n val = `${val.includes(\" \") ? '\"' : ''}${val}${val.includes(\" \") ? '\"' : ''}`;\n }\n\n return { opt, val };\n}\nfunction handleNVSVisible() {\n let nvs_previous_checked = isEnabled(Cookies.get(\"show-nvs\"));\n $('input#show-nvs')[0].checked = nvs_previous_checked;\n if ($('input#show-nvs')[0].checked || recovery) {\n $('*[href*=\"-nvs\"]').show();\n } else {\n $('*[href*=\"-nvs\"]').hide();\n }\n}\nfunction concatenateOptions(options) {\n let commandLine = ' ';\n for (const [option, value] of Object.entries(options)) {\n if (option !== 'n' && option !== 'o') {\n commandLine += `-${option} `;\n if (value !== true) {\n commandLine += `${value} `;\n }\n }\n }\n return commandLine;\n}\n\nfunction isEnabled(val) {\n return val != undefined && typeof val === 'string' && val.match(\"[Yy1]\");\n}\n\nconst nvsTypes = {\n NVS_TYPE_U8: 0x01,\n /*! < Type uint8_t */\n NVS_TYPE_I8: 0x11,\n /*! < Type int8_t */\n NVS_TYPE_U16: 0x02,\n /*! < Type uint16_t */\n NVS_TYPE_I16: 0x12,\n /*! < Type int16_t */\n NVS_TYPE_U32: 0x04,\n /*! < Type uint32_t */\n NVS_TYPE_I32: 0x14,\n /*! < Type int32_t */\n NVS_TYPE_U64: 0x08,\n /*! < Type uint64_t */\n NVS_TYPE_I64: 0x18,\n /*! < Type int64_t */\n NVS_TYPE_STR: 0x21,\n /*! < Type string */\n NVS_TYPE_BLOB: 0x42,\n /*! < Type blob */\n NVS_TYPE_ANY: 0xff /*! < Must be last */,\n};\nconst btIcons = {\n bt_playing: { 'label': '', 'icon': 'media_bluetooth_on' },\n bt_disconnected: { 'label': '', 'icon': 'media_bluetooth_off' },\n bt_neutral: { 'label': '', 'icon': 'bluetooth' },\n bt_connecting: { 'label': '', 'icon': 'bluetooth_searching' },\n bt_connected: { 'label': '', 'icon': 'bluetooth_connected' },\n bt_disabled: { 'label': '', 'icon': 'bluetooth_disabled' },\n play_arrow: { 'label': '', 'icon': 'play_circle_filled' },\n pause: { 'label': '', 'icon': 'pause_circle' },\n stop: { 'label': '', 'icon': 'stop_circle' },\n '': { 'label': '', 'icon': '' }\n};\nconst batIcons = [\n { icon: \"battery_0_bar\", label: '▪', ranges: [{ f: 5.8, t: 6.8 }, { f: 8.8, t: 10.2 }] },\n { icon: \"battery_2_bar\", label: '▪▪', ranges: [{ f: 6.8, t: 7.4 }, { f: 10.2, t: 11.1 }] },\n { icon: \"battery_3_bar\", label: '▪▪▪', ranges: [{ f: 7.4, t: 7.5 }, { f: 11.1, t: 11.25 }] },\n { icon: \"battery_4_bar\", label: '▪▪▪▪', ranges: [{ f: 7.5, t: 7.8 }, { f: 11.25, t: 11.7 }] }\n];\nconst btStateIcons = [\n { desc: 'Idle', sub: ['bt_neutral'] },\n { desc: 'Discovering', sub: ['bt_connecting'] },\n { desc: 'Discovered', sub: ['bt_connecting'] },\n { desc: 'Unconnected', sub: ['bt_disconnected'] },\n { desc: 'Connecting', sub: ['bt_connecting'] },\n {\n desc: 'Connected',\n sub: ['bt_connected', 'play_arrow', 'bt_playing', 'pause', 'stop'],\n },\n { desc: 'Disconnecting', sub: ['bt_disconnected'] },\n];\n\nconst pillcolors = {\n MESSAGING_INFO: 'badge-success',\n MESSAGING_WARNING: 'badge-warning',\n MESSAGING_ERROR: 'badge-danger',\n};\nconst connectReturnCode = {\n OK: 0,\n FAIL: 1,\n DISC: 2,\n LOST: 3,\n RESTORE: 4,\n ETH: 5\n}\nconst taskStates = {\n 0: 'eRunning',\n /*! < A task is querying the state of itself, so must be running. */\n 1: 'eReady',\n /*! < The task being queried is in a read or pending ready list. */\n 2: 'eBlocked',\n /*! < The task being queried is in the Blocked state. */\n 3: 'eSuspended',\n /*! < The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */\n 4: 'eDeleted',\n};\nlet flashState = {\n NONE: 0,\n REBOOT_TO_RECOVERY: 2,\n SET_FWURL: 5,\n FLASHING: 6,\n DONE: 7,\n UPLOADING: 8,\n ERROR: 9,\n UPLOADCOMPLETE: 10,\n _state: -1,\n olderRecovery: false,\n statusText: '',\n flashURL: '',\n flashFileName: '',\n statusPercent: 0,\n Completed: false,\n recovery: false,\n prevRecovery: false,\n updateModal: new bootstrap.Modal(document.getElementById('otadiv'), {}),\n reset: function () {\n\n this.olderRecovery = false;\n this.statusText = '';\n this.statusPercent = -1;\n this.flashURL = '';\n this.flashFileName = undefined;\n this.UpdateProgress();\n $('#rTable tr.release').removeClass('table-success table-warning');\n $('.flact').prop('disabled', false);\n $('#flashfilename').value = null;\n $('#fw-url-input').value = null;\n if (!this.isStateError()) {\n $('span#flash-status').html('');\n $('#fwProgressLabel').parent().removeClass('bg-danger');\n }\n this._state = this.NONE\n return this;\n },\n isStateUploadComplete: function () {\n return this._state == this.UPLOADCOMPLETE;\n },\n isStateError: function () {\n return this._state == this.ERROR;\n },\n isStateNone: function () {\n return this._state == this.NONE;\n },\n isStateRebootRecovery: function () {\n return this._state == this.REBOOT_TO_RECOVERY;\n },\n isStateSetUrl: function () {\n return this._state == this.SET_FWURL;\n },\n isStateFlashing: function () {\n return this._state == this.FLASHING;\n },\n isStateDone: function () {\n return this._state == this.DONE;\n },\n isStateUploading: function () {\n return this._state == this.UPLOADING;\n },\n init: function () {\n this._state = this.NONE;\n return this;\n },\n\n SetStateError: function () {\n this._state = this.ERROR;\n $('#fwProgressLabel').parent().addClass('bg-danger');\n return this;\n },\n SetStateNone: function () {\n this._state = this.NONE;\n return this;\n },\n SetStateRebootRecovery: function () {\n this._state = this.REBOOT_TO_RECOVERY;\n // Reboot system to recovery mode\n this.SetStatusText('Starting recovery mode.')\n $.ajax({\n url: '/recovery.json',\n context: this,\n dataType: 'text',\n method: 'POST',\n cache: false,\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify({\n timestamp: Date.now(),\n }),\n error: function (xhr, _ajaxOptions, thrownError) {\n this.setOTAError(`Unexpected error while trying to restart to recovery. (status=${xhr.status ?? ''}, error=${thrownError ?? ''} ) `);\n },\n complete: function (response) {\n this.SetStatusText('Waiting for system to boot.')\n },\n });\n return this;\n },\n SetStateSetUrl: function () {\n this._state = this.SET_FWURL;\n this.statusText = 'Sending firmware download location.';\n let confData = {\n fwurl: {\n value: this.flashURL,\n type: 33,\n }\n };\n post_config(confData);\n return this;\n },\n SetStateFlashing: function () {\n this._state = this.FLASHING;\n return this;\n },\n SetStateDone: function () {\n this._state = this.DONE;\n this.reset();\n return this;\n },\n SetStateUploading: function () {\n this._state = this.UPLOADING;\n return this.SetStatusText('Sending file to device.');\n },\n SetStateUploadComplete: function () {\n this._state = this.UPLOADCOMPLETE;\n return this;\n },\n\n isFlashExecuting: function () {\n return true === (this._state != this.UPLOADING && (this.statusText !== '' || this.statusPercent >= 0));\n },\n\n\n\n toString: function () {\n let keys = Object.keys(this);\n return keys.find(x => this[x] === this._state);\n },\n\n setOTATargets: function () {\n this.flashURL = '';\n this.flashFileName = '';\n this.flashURL = $('#fw-url-input').val();\n let fileInput = $('#flashfilename')[0].files;\n if (fileInput.length > 0) {\n this.flashFileName = fileInput[0];\n }\n if (this.flashFileName.length == 0 && this.flashURL.length == 0) {\n this.setOTAError('Invalid url or file. Cannot start OTA');\n }\n return this;\n },\n\n setOTAError: function (message) {\n this.SetStateError().SetStatusPercent(0).SetStatusText(message).reset();\n return this;\n },\n\n ShowDialog: function () {\n if (!this.isStateNone()) {\n this.updateModal.show();\n $('.flact').prop('disabled', true);\n }\n return this;\n },\n\n SetStatusPercent: function (pct) {\n var pctChanged = (this.statusPercent != pct);\n this.statusPercent = pct;\n if (pctChanged) {\n if (!this.isStateUploading() && !this.isStateFlashing()) {\n this.SetStateFlashing();\n }\n if (pct == 100) {\n if (this.isStateFlashing()) {\n this.SetStateDone();\n }\n else if (this.isStateUploading()) {\n this.statusPercent = 0;\n this.SetStateFlashing();\n }\n }\n this.UpdateProgress().ShowDialog();\n }\n return this;\n },\n SetStatusText: function (txt) {\n var changed = (this.statusText != txt);\n this.statusText = txt;\n if (changed) {\n $('span#flash-status').html(this.statusText);\n this.ShowDialog();\n }\n\n return this;\n },\n UpdateProgress: function () {\n $('.progress-bar')\n .css('width', this.statusPercent + '%')\n .attr('aria-valuenow', this.statusPercent)\n .text(this.statusPercent + '%')\n $('.progress-bar').html((this.isStateDone() ? 100 : this.statusPercent) + '%');\n return this;\n },\n StartOTA: function () {\n this.logEvent(this.StartOTA.name);\n $('#fwProgressLabel').parent().removeClass('bg-danger');\n this.setOTATargets();\n if (this.isStateError()) {\n return this;\n }\n if (!recovery) {\n this.SetStateRebootRecovery();\n }\n else {\n this.SetStateFlashing().TargetReadyStartOTA();\n }\n\n return this;\n },\n UploadLocalFile: function () {\n this.SetStateUploading();\n const xhttp = new XMLHttpRequest();\n xhttp.context = this;\n var boundHandleUploadProgressEvent = this.HandleUploadProgressEvent.bind(this);\n var boundsetOTAError = this.setOTAError.bind(this);\n xhttp.upload.addEventListener(\"progress\", boundHandleUploadProgressEvent, false);\n xhttp.onreadystatechange = function () {\n if (xhttp.readyState === 4) {\n if (xhttp.status === 0 || xhttp.status === 404) {\n boundsetOTAError(`Upload Failed. Recovery version might not support uploading. Please use web update instead.`);\n }\n }\n };\n xhttp.open('POST', '/flash.json', true);\n xhttp.send(this.flashFileName);\n },\n TargetReadyStartOTA: function () {\n if (recovery && this.prevRecovery && !this.isStateRebootRecovery() && !this.isStateFlashing()) {\n // this should only execute once, while being in a valid state\n return this;\n }\n\n this.logEvent(this.TargetReadyStartOTA.name);\n if (!recovery) {\n console.error('Event TargetReadyStartOTA fired in the wrong mode ');\n return this;\n }\n this.prevRecovery = true;\n\n if (this.flashFileName !== '') {\n this.UploadLocalFile();\n }\n else if (this.flashURL != '') {\n this.SetStateSetUrl();\n }\n else {\n this.setOTAError('Invalid URL or file name while trying to start the OTa process')\n }\n },\n HandleUploadProgressEvent: function (data) {\n this.logEvent(this.HandleUploadProgressEvent.name);\n this.SetStateUploading().SetStatusPercent(Math.round(data.loaded / data.total * 100)).SetStatusText('Uploading file to device');\n },\n EventTargetStatus: function (data) {\n if (!this.isStateNone()) {\n this.logEvent(this.EventTargetStatus.name);\n }\n if (data.ota_pct ?? -1 >= 0) {\n this.olderRecovery = true;\n this.SetStatusPercent(data.ota_pct);\n }\n if ((data.ota_dsc ?? '') != '') {\n this.olderRecovery = true;\n this.SetStatusText(data.ota_dsc);\n }\n\n if (data.recovery != undefined) {\n this.recovery = data.recovery === 1 ? true : false;\n }\n if (this.isStateRebootRecovery() && this.recovery) {\n this.TargetReadyStartOTA();\n }\n },\n EventOTAMessageClass: function (data) {\n this.logEvent(this.EventOTAMessageClass.name);\n var otaData = JSON.parse(data);\n this.SetStatusPercent(otaData.ota_pct).SetStatusText(otaData.ota_dsc);\n },\n logEvent: function (fun) {\n console.log(`${fun}, flash state ${this.toString()}, recovery: ${this.recovery}, ota pct: ${this.statusPercent}, ota desc: ${this.statusText}`);\n }\n\n};\nwindow.hideSurrounding = function (obj) {\n $(obj).parent().parent().hide();\n}\n\nlet presetsloaded = false;\nlet is_i2c_locked = false;\nlet statusInterval = 2000;\nlet messageInterval = 2500;\nfunction post_config(data) {\n let confPayload = {\n timestamp: Date.now(),\n config: data\n };\n $.ajax({\n url: '/config.json',\n dataType: 'text',\n method: 'POST',\n cache: false,\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify(confPayload),\n error: handleExceptionResponse,\n });\n}\n\n\nwindow.hFlash = function () {\n // reset file upload selection if any;\n $('#flashfilename').value = null\n flashState.StartOTA();\n}\nwindow.handleReboot = function (link) {\n if (link == 'reboot_ota') {\n $('#reboot_ota_nav').removeClass('active').prop(\"disabled\", true); delayReboot(500, '', 'reboot_ota');\n }\n else {\n $('#reboot_nav').removeClass('active'); delayReboot(500, '', link);\n }\n}\n\nfunction parseSqueezeliteCommandLine(commandLine) {\n const options = {};\n let output, name;\n let otherValues = '';\n\n const argRegex = /(\"[^\"]+\"|'[^']+'|\\S+)/g;\n const args = commandLine.match(argRegex);\n\n let i = 0;\n\n while (i < args.length) {\n const arg = args[i];\n\n if (arg.startsWith('-')) {\n const option = arg.slice(1);\n\n if (option === '') {\n otherValues += args.slice(i).join(' ');\n break;\n }\n\n let value = true;\n\n if (i + 1 < args.length && !args[i + 1].startsWith('-')) {\n value = args[i + 1].replace(/\"/g, '').replace(/'/g, '');\n i++;\n }\n\n options[option] = value;\n } else {\n otherValues += arg + ' ';\n }\n\n i++;\n }\n\n otherValues = otherValues.trim();\n output = getOutput(options);\n name = getName(options);\n let otherOptions={btname:null,n:null};\n // assign o and n options to otheroptions if present\n if (options.o && output.toUpperCase() === 'BT') {\n let temp = parseSqueezeliteCommandLine(options.o);\n if(temp.name) {\n otherOptions.btname = temp.name;\n }\n delete options.o;\n }\n if (options.n) {\n otherOptions['n'] = options.n;\n delete options.n;\n }\n return { name, output, options, otherValues,otherOptions }; \n}\n\nfunction getOutput(options) {\n let output;\n if (options.o){\n output = options.o.replace(/\"/g, '').replace(/'/g, '');\n /* set output as the first alphanumerical word in the command line */\n if (output.indexOf(' ') > 0) {\n output = output.substring(0, output.indexOf(' '));\n }\n }\n return output;\n}\n\nfunction getName(options) {\n let name;\n /* if n option present, assign to name variable */\n if (options.n){\n name = options.n.replace(/\"/g, '').replace(/'/g, '');\n }\n return name;\n}\n\n\nfunction isConnected() {\n return ConnectedTo.hasOwnProperty('ip') && ConnectedTo.ip != '0.0.0.0' && ConnectedTo.ip != '';\n}\nfunction getIcon(icons) {\n return isConnected() ? icons.icon : icons.label;\n}\nfunction handlebtstate(data) {\n let icon = '';\n let tt = '';\n if (data.bt_status !== undefined && data.bt_sub_status !== undefined) {\n const iconindex = btStateIcons[data.bt_status].sub[data.bt_sub_status];\n if (iconindex) {\n icon = btIcons[iconindex];\n tt = btStateIcons[data.bt_status].desc;\n } else {\n icon = btIcons.bt_connected;\n tt = 'Output status';\n }\n }\n\n $('#o_type').attr('title', tt);\n $('#o_bt').html(isConnected() ? icon.label : icon.text);\n}\nfunction handleTemplateTypeRadio(outtype) {\n $('#o_type').children('span').css({ display: 'none' });\n let changed = false;\n if (outtype === 'bt') {\n changed = output !== 'bt' && output !== '';\n output = 'bt';\n } else if (outtype === 'spdif') {\n changed = output !== 'spdif' && output !== '';\n output = 'spdif';\n } else {\n changed = output !== 'i2s' && output !== '';\n output = 'i2s';\n }\n $('#' + output).prop('checked', true);\n $('#o_' + output).css({ display: 'inline' });\n if (changed) {\n Object.keys(commandDefaults[output]).forEach(function (key) {\n $(`#cmd_opt_${key}`).val(commandDefaults[output][key]);\n });\n }\n}\n\nfunction handleExceptionResponse(xhr, _ajaxOptions, thrownError) {\n console.log(xhr.status);\n console.log(thrownError);\n if (thrownError !== '') {\n showLocalMessage(thrownError, 'MESSAGING_ERROR');\n }\n}\nfunction HideCmdMessage(cmdname) {\n $('#toast_' + cmdname)\n .removeClass('table-success')\n .removeClass('table-warning')\n .removeClass('table-danger')\n .addClass('table-success')\n .removeClass('show');\n $('#msg_' + cmdname).html('');\n}\nfunction showCmdMessage(cmdname, msgtype, msgtext, append = false) {\n let color = 'table-success';\n if (msgtype === 'MESSAGING_WARNING') {\n color = 'table-warning';\n } else if (msgtype === 'MESSAGING_ERROR') {\n color = 'table-danger';\n }\n $('#toast_' + cmdname)\n .removeClass('table-success')\n .removeClass('table-warning')\n .removeClass('table-danger')\n .addClass(color)\n .addClass('show');\n let escapedtext = msgtext\n .substring(0, msgtext.length - 1)\n .encodeHTML()\n .replace(/\\n/g, '
');\n escapedtext =\n ($('#msg_' + cmdname).html().length > 0 && append\n ? $('#msg_' + cmdname).html() + '
'\n : '') + escapedtext;\n $('#msg_' + cmdname).html(escapedtext);\n}\n\nlet releaseURL =\n 'https://api.github.com/repos/sle118/squeezelite-esp32/releases';\n\nlet recovery = false;\nlet messagesHeld = false;\nlet commandBTSinkName = '';\nconst commandHeader = 'squeezelite ';\nconst commandDefaults = {\n i2s: { b: \"500:2000\", C: \"30\", W: \"\", Z: \"96000\", o: \"I2S\" },\n spdif: { b: \"500:2000\", C: \"30\", W: \"\", Z: \"48000\", o: \"SPDIF\" },\n bt: { b: \"500:2000\", C: \"30\", W: \"\", Z: \"44100\", o: \"BT\" },\n};\nlet validOptions = {\n codecs: ['flac', 'pcm', 'mp3', 'ogg', 'aac', 'wma', 'alac', 'dsd', 'mad', 'mpg']\n};\n\n//let blockFlashButton = false;\nlet apList = null;\n//let selectedSSID = '';\n//let checkStatusInterval = null;\nlet messagecount = 0;\nlet messageseverity = 'MESSAGING_INFO';\nlet SystemConfig = {};\nlet LastCommandsState = null;\nvar output = '';\nlet hostName = '';\nlet versionName = 'Squeezelite-ESP32';\nlet prevmessage = '';\nlet project_name = versionName;\nlet depth = 16;\nlet board_model = '';\nlet platform_name = versionName;\nlet preset_name = '';\nlet btSinkNamesOptSel = '#cfg-audio-bt_source-sink_name';\nlet ConnectedTo = {};\nlet ConnectingToSSID = {};\nlet lmsBaseUrl;\nlet prevLMSIP = '';\nconst ConnectingToActions = {\n 'CONN': 0, 'MAN': 1, 'STS': 2,\n}\n\nPromise.prototype.delay = function (duration) {\n return this.then(\n function (value) {\n return new Promise(function (resolve) {\n setTimeout(function () {\n resolve(value);\n }, duration);\n });\n },\n function (reason) {\n return new Promise(function (_resolve, reject) {\n setTimeout(function () {\n reject(reason);\n }, duration);\n });\n }\n );\n};\n\nfunction getConfigJson(slimMode) {\n const config = {};\n $('input.nvs').each(function (_index, entry) {\n if (!slimMode) {\n const nvsType = parseInt(entry.attributes.nvs_type.value, 10);\n if (entry.id !== '') {\n config[entry.id] = {};\n if (\n nvsType === nvsTypes.NVS_TYPE_U8 ||\n nvsType === nvsTypes.NVS_TYPE_I8 ||\n nvsType === nvsTypes.NVS_TYPE_U16 ||\n nvsType === nvsTypes.NVS_TYPE_I16 ||\n nvsType === nvsTypes.NVS_TYPE_U32 ||\n nvsType === nvsTypes.NVS_TYPE_I32 ||\n nvsType === nvsTypes.NVS_TYPE_U64 ||\n nvsType === nvsTypes.NVS_TYPE_I64\n ) {\n config[entry.id].value = parseInt(entry.value);\n } else {\n config[entry.id].value = entry.value;\n }\n config[entry.id].type = nvsType;\n }\n } else {\n config[entry.id] = entry.value;\n }\n });\n const key = $('#nvs-new-key').val();\n const val = $('#nvs-new-value').val();\n if (key !== '') {\n if (!slimMode) {\n config[key] = {};\n config[key].value = val;\n config[key].type = 33;\n } else {\n config[key] = val;\n }\n }\n return config;\n}\n\nfunction handleHWPreset(allfields, reboot) {\n\n const selJson = JSON.parse(allfields[0].value);\n var cmd = allfields[0].attributes.cmdname.value;\n\n console.log(`selected model: ${selJson.name}`);\n let confPayload = {\n timestamp: Date.now(),\n config: { model_config: { value: selJson.name, type: 33 } }\n };\n for (const [name, value] of Object.entries(selJson.config)) {\n const storedval = (typeof value === 'string' || value instanceof String) ? value : JSON.stringify(value);\n confPayload.config[name] = {\n value: storedval,\n type: 33,\n }\n showCmdMessage(\n cmd,\n 'MESSAGING_INFO',\n `Setting ${name}=${storedval} `,\n true\n );\n }\n\n showCmdMessage(\n cmd,\n 'MESSAGING_INFO',\n `Committing `,\n true\n );\n $.ajax({\n url: '/config.json',\n dataType: 'text',\n method: 'POST',\n cache: false,\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify(confPayload),\n error: function (xhr, _ajaxOptions, thrownError) {\n handleExceptionResponse(xhr, _ajaxOptions, thrownError);\n showCmdMessage(\n cmd,\n 'MESSAGING_ERROR',\n `Unexpected error ${(thrownError !== '') ? thrownError : 'with return status = ' + xhr.status} `,\n true\n );\n },\n success: function (response) {\n showCmdMessage(\n cmd,\n 'MESSAGING_INFO',\n `Saving complete `,\n true\n );\n console.log(response);\n if (reboot) {\n delayReboot(2500, cmd);\n }\n },\n });\n}\n\n\n// pull json file from https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/b462691f69e2ad31ac95c547af6ec97afb0f53db/squeezelite-esp32-presets.json and\nfunction loadPresets() {\n if ($(\"#cfg-hw-preset-model_config\").length == 0) return;\n if (presetsloaded) return;\n presetsloaded = true;\n $('#cfg-hw-preset-model_config').html('');\n $.getJSON(\n 'https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/',\n { _: new Date().getTime() },\n function (data) {\n $.each(data, function (key, val) {\n $('#cfg-hw-preset-model_config').append(``);\n if (preset_name !== '' && preset_name == val.name) {\n $('#cfg-hw-preset-model_config').val(preset_name);\n }\n });\n if (preset_name !== '') {\n ('#prev_preset').show().val(preset_name);\n }\n }\n\n ).fail(function (jqxhr, textStatus, error) {\n const err = textStatus + ', ' + error;\n console.log('Request Failed: ' + err);\n }\n );\n}\n\nfunction delayReboot(duration, cmdname, ota = 'reboot') {\n const url = '/' + ota + '.json';\n $('tbody#tasks').empty();\n $('#tasks_sect').css('visibility', 'collapse');\n Promise.resolve({ cmdname: cmdname, url: url })\n .delay(duration)\n .then(function (data) {\n if (data.cmdname.length > 0) {\n showCmdMessage(\n data.cmdname,\n 'MESSAGING_WARNING',\n 'System is rebooting.\\n',\n true\n );\n } else {\n showLocalMessage('System is rebooting.\\n', 'MESSAGING_WARNING');\n }\n console.log('now triggering reboot');\n $(\"button[onclick*='handleReboot']\").addClass('rebooting');\n $.ajax({\n url: data.url,\n dataType: 'text',\n method: 'POST',\n cache: false,\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify({\n timestamp: Date.now(),\n }),\n error: handleExceptionResponse,\n complete: function () {\n console.log('reboot call completed');\n Promise.resolve(data)\n .delay(6000)\n .then(function (rdata) {\n if (rdata.cmdname.length > 0) {\n HideCmdMessage(rdata.cmdname);\n }\n getCommands();\n getConfig();\n });\n },\n });\n });\n}\n// eslint-disable-next-line no-unused-vars\nwindow.saveAutoexec1 = function (apply) {\n showCmdMessage('cfg-audio-tmpl', 'MESSAGING_INFO', 'Saving.\\n', false);\n let commandLine = `${commandHeader} -o ${output} `;\n $('.sqcmd').each(function () {\n let { opt, val } = get_control_option_value($(this));\n if ((opt && opt.length>0 ) && typeof(val) == 'boolean' || val.length > 0) {\n const optStr=opt===':'?opt:(` -${opt} `);\n val = typeof(val) == 'boolean'?'':val;\n commandLine += `${optStr} ${val}`;\n }\n });\n const resample=$('#cmd_opt_R input[name=resample]:checked');\n if (resample.length>0 && resample.attr('suffix')!=='') {\n commandLine += resample.attr('suffix');\n // now check resample_i option and if checked, add suffix to command line\n if ($('#resample_i').is(\":checked\") && resample.attr('aint') =='true') {\n commandLine += $('#resample_i').attr('suffix');\n }\n}\n\n \n if (output === 'bt') {\n showCmdMessage(\n 'cfg-audio-tmpl',\n 'MESSAGING_INFO',\n 'Remember to configure the Bluetooth audio device name.\\n',\n true\n );\n }\n commandLine += concatenateOptions(options);\n const data = {\n timestamp: Date.now(),\n };\n data.config = {\n autoexec1: { value: commandLine, type: 33 },\n // autoexec: {\n // value: $('#disable-squeezelite').prop('checked') ? '0' : '1',\n // type: 33,\n // },\n };\n\n $.ajax({\n url: '/config.json',\n dataType: 'text',\n method: 'POST',\n cache: false,\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify(data),\n error: handleExceptionResponse,\n complete: function (response) {\n if (\n response.responseText &&\n JSON.parse(response.responseText).result === 'OK'\n ) {\n showCmdMessage('cfg-audio-tmpl', 'MESSAGING_INFO', 'Done.\\n', true);\n if (apply) {\n delayReboot(1500, 'cfg-audio-tmpl');\n }\n } else if (JSON.parse(response.responseText).result) {\n showCmdMessage(\n 'cfg-audio-tmpl',\n 'MESSAGING_WARNING',\n JSON.parse(response.responseText).Result + '\\n',\n true\n );\n } else {\n showCmdMessage(\n 'cfg-audio-tmpl',\n 'MESSAGING_ERROR',\n response.statusText + '\\n'\n );\n }\n console.log(response.responseText);\n },\n });\n console.log('sent data:', JSON.stringify(data));\n}\nwindow.handleDisconnect = function () {\n $.ajax({\n url: '/connect.json',\n dataType: 'text',\n method: 'DELETE',\n cache: false,\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify({\n timestamp: Date.now(),\n }),\n });\n}\nfunction setPlatformFilter(val) {\n if ($('.upf').filter(function () { return $(this).text().toUpperCase() === val.toUpperCase() }).length > 0) {\n $('#splf').val(val).trigger('input');\n return true;\n }\n return false;\n}\nwindow.handleConnect = function () {\n ConnectingToSSID.ssid = $('#manual_ssid').val();\n ConnectingToSSID.pwd = $('#manual_pwd').val();\n ConnectingToSSID.dhcpname = $('#dhcp-name2').val();\n $(\"*[class*='connecting']\").hide();\n $('#ssid-wait').text(ConnectingToSSID.ssid);\n $('.connecting').show();\n $.ajax({\n url: '/connect.json',\n dataType: 'text',\n method: 'POST',\n cache: false,\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify({\n timestamp: Date.now(),\n ssid: ConnectingToSSID.ssid,\n pwd: ConnectingToSSID.pwd\n }),\n error: handleExceptionResponse,\n });\n\n // now we can re-set the intervals regardless of result\n\n}\nfunction renderError(opt,error){\n const fieldname = `cmd_opt_${opt}`;\n let errorFieldName=`${fieldname}-error`;\n let errorField=$(`#${errorFieldName}`);\n let field=$(`#${fieldname}`);\n \n if (!errorField || errorField.length ==0) {\n field.after(`
`);\n errorField=$(`#${errorFieldName}`);\n }\n if(error.length ==0){\n errorField.hide();\n field.removeClass('is-invalid');\n field.addClass('is-valid');\n errorField.text('');\n }\n else { \n errorField.show();\n errorField.text(error);\n field.removeClass('is-valid');\n field.addClass('is-invalid');\n }\n return errorField;\n}\n$(document).ready(function () {\n $('.material-icons').each(function (_index, entry) {\n entry.attributes['icon'] = entry.textContent;\n });\n setIcons(true);\n handleNVSVisible();\n flashState.init();\n $('#fw-url-input').on('input', function () {\n if ($(this).val().length > 8 && ($(this).val().startsWith('http://') || $(this).val().startsWith('https://'))) {\n $('#start-flash').show();\n }\n else {\n $('#start-flash').hide();\n }\n });\n $('.upSrch').on('input', function () {\n const val = this.value;\n $(\"#rTable tr\").removeClass(this.id + '_hide');\n if (val.length > 0) {\n $(`#rTable td:nth-child(${$(this).parent().index() + 1})`).filter(function () {\n return !$(this).text().toUpperCase().includes(val.toUpperCase());\n }).parent().addClass(this.id + '_hide');\n }\n $('[class*=\"_hide\"]').hide();\n $('#rTable tr').not('[class*=\"_hide\"]').show()\n\n });\n setTimeout(refreshAP, 1500);\n /* add validation for cmd_opt_c, which accepts a comma separated list. \n getting known codecs from validOptions.codecs array\n use bootstrap classes to highlight the error with an overlay message */\n $('#options input').on('input', function () {\n const { opt, val } = get_control_option_value(this);\n if (opt === 'c' || opt === 'e') {\n const fieldname = `cmd_opt_${opt}_codec-error`;\n \n const values = val.split(',').map(function (item) {\n return item.trim();\n });\n /* get a list of invalid codecs */\n const invalid = values.filter(function (item) {\n return !validOptions.codecs.includes(item);\n });\n renderError(opt,invalid.length > 0 ? `Invalid codec(s) ${invalid.join(', ')}` : '');\n }\n /* add validation for cmd_opt_m, which accepts a mac_address */\n if (opt === 'm') {\n const mac_regex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;\n renderError(opt,mac_regex.test(val) ? '' : 'Invalid MAC address');\n }\n if (opt === 'r') {\n const rateRegex = /^(\\d+\\.?\\d*|\\.\\d+)-(\\d+\\.?\\d*|\\.\\d+)$|^(\\d+\\.?\\d*)$|^(\\d+\\.?\\d*,)+\\d+\\.?\\d*$/;\n renderError(opt,rateRegex.test(val)?'':`Invalid rate(s) ${val}. Acceptable format: |-|,,`);\n }\n\n\n\n }\n\n\n );\n\n\n\n\n\n $('#WifiConnectDialog')[0].addEventListener('shown.bs.modal', function (event) {\n $(\"*[class*='connecting']\").hide();\n\n if (event?.relatedTarget) {\n ConnectingToSSID.Action = ConnectingToActions.CONN;\n if ($(event.relatedTarget).children('td:eq(1)').text() == ConnectedTo.ssid) {\n ConnectingToSSID.Action = ConnectingToActions.STS;\n }\n else {\n if (!$(event.relatedTarget).is(':last-child')) {\n ConnectingToSSID.ssid = $(event.relatedTarget).children('td:eq(1)').text();\n $('#manual_ssid').val(ConnectingToSSID.ssid);\n }\n else {\n ConnectingToSSID.Action = ConnectingToActions.MAN;\n ConnectingToSSID.ssid = '';\n $('#manual_ssid').val(ConnectingToSSID.ssid);\n }\n }\n }\n\n\n if (ConnectingToSSID.Action !== ConnectingToActions.STS) {\n $('.connecting-init').show();\n $('#manual_ssid').trigger('focus');\n }\n else {\n handleWifiDialog();\n }\n });\n\n $('#WifiConnectDialog')[0].addEventListener('hidden.bs.modal', function () {\n $('#WifiConnectDialog input').val('');\n });\n\n $('#uCnfrm')[0].addEventListener('shown.bs.modal', function () {\n $('#selectedFWURL').text($('#fw-url-input').val());\n });\n\n $('input#show-commands')[0].checked = LastCommandsState === 1;\n $('a[href^=\"#tab-commands\"]').hide();\n $('#load-nvs').on('click', function () {\n $('#nvsfilename').trigger('click');\n });\n $('#nvsfilename').on('change', function () {\n if (typeof window.FileReader !== 'function') {\n throw \"The file API isn't supported on this browser.\";\n }\n if (!this.files) {\n throw 'This browser does not support the `files` property of the file input.';\n }\n if (!this.files[0]) {\n return undefined;\n }\n\n const file = this.files[0];\n let fr = new FileReader();\n fr.onload = function (e) {\n let data = {};\n try {\n data = JSON.parse(e.target.result);\n } catch (ex) {\n alert('Parsing failed!\\r\\n ' + ex);\n }\n $('input.nvs').each(function (_index, entry) {\n $(this).parent().removeClass('bg-warning').removeClass('bg-success');\n if (data[entry.id]) {\n if (data[entry.id] !== entry.value) {\n console.log(\n 'Changed ' + entry.id + ' ' + entry.value + '==>' + data[entry.id]\n );\n $(this).parent().addClass('bg-warning');\n $(this).val(data[entry.id]);\n }\n else {\n $(this).parent().addClass('bg-success');\n }\n }\n });\n var changed = $(\"input.nvs\").children('.bg-warning');\n if (changed) {\n alert('Highlighted values were changed. Press Commit to change on the device');\n }\n }\n fr.readAsText(file);\n this.value = null;\n\n }\n );\n $('#clear-syslog').on('click', function () {\n messagecount = 0;\n messageseverity = 'MESSAGING_INFO';\n $('#msgcnt').text('');\n $('#syslogTable').html('');\n });\n\n $('#ok-credits').on('click', function () {\n $('#credits').slideUp('fast', function () { });\n $('#app').slideDown('fast', function () { });\n });\n\n $('#acredits').on('click', function (event) {\n event.preventDefault();\n $('#app').slideUp('fast', function () { });\n $('#credits').slideDown('fast', function () { });\n });\n\n $('input#show-commands').on('click', function () {\n this.checked = this.checked ? 1 : 0;\n if (this.checked) {\n $('a[href^=\"#tab-commands\"]').show();\n LastCommandsState = 1;\n } else {\n LastCommandsState = 0;\n $('a[href^=\"#tab-commands\"]').hide();\n }\n });\n\n $('#disable-squeezelite').on('click', function () {\n // this.checked = this.checked ? 1 : 0;\n // $('#disable-squeezelite').prop('checked')\n if (this.checked) {\n // Store the current value before overwriting it\n const currentValue = $('#cmd_opt_s').val();\n $('#cmd_opt_s').data('originalValue', currentValue);\n \n // Overwrite the value with '-disable'\n $('#cmd_opt_s').val('-disable');\n } else {\n // Retrieve the original value\n const originalValue = $('#cmd_opt_s').data('originalValue');\n \n // Restore the original value if it exists, otherwise set it to an empty string\n $('#cmd_opt_s').val(originalValue ? originalValue : '');\n }\n \n });\n\n \n\n $('input#show-nvs').on('click', function () {\n this.checked = this.checked ? 1 : 0;\n Cookies.set(\"show-nvs\", this.checked ? 'Y' : 'N');\n handleNVSVisible();\n });\n $('#btn_reboot_recovery').on('click', function () {\n handleReboot('recovery');\n });\n $('#btn_reboot').on('click', function () {\n handleReboot('reboot');\n });\n $('#btn_flash').on('click', function () {\n hFlash();\n });\n $('#save-autoexec1').on('click', function () {\n saveAutoexec1(false);\n });\n $('#commit-autoexec1').on('click', function () {\n saveAutoexec1(true);\n });\n $('#btn_disconnect').on('click', function () {\n ConnectedTo = {};\n refreshAPHTML2();\n $.ajax({\n url: '/connect.json',\n dataType: 'text',\n method: 'DELETE',\n cache: false,\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify({\n timestamp: Date.now(),\n }),\n });\n });\n $('#btnJoin').on('click', function () {\n handleConnect();\n });\n $('#reboot_nav').on('click', function () {\n handleReboot('reboot');\n });\n $('#reboot_ota_nav').on('click', function () {\n handleReboot('reboot_ota');\n });\n\n $('#save-as-nvs').on('click', function () {\n const config = getConfigJson(true);\n const a = document.createElement('a');\n a.href = URL.createObjectURL(\n new Blob([JSON.stringify(config, null, 2)], {\n type: 'text/plain',\n })\n );\n a.setAttribute(\n 'download',\n 'nvs_config_' + hostName + '_' + Date.now() + 'json'\n );\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n });\n\n $('#save-nvs').on('click', function () {\n post_config(getConfigJson(false));\n });\n\n $('#fwUpload').on('click', function () {\n const fileInput = document.getElementById('flashfilename').files;\n if (fileInput.length === 0) {\n alert('No file selected!');\n } else {\n $('#fw-url-input').value = null;\n flashState.StartOTA();\n }\n\n });\n $('[name=output-tmpl]').on('click', function () {\n handleTemplateTypeRadio(this.id);\n });\n\n $('#chkUpdates').on('click', function () {\n $('#rTable').html('');\n $.getJSON(releaseURL, function (data) {\n let i = 0;\n const branches = [];\n data.forEach(function (release) {\n const namecomponents = release.name.split('#');\n const branch = namecomponents[3];\n if (!branches.includes(branch)) {\n branches.push(branch);\n }\n });\n let fwb = '';\n branches.forEach(function (branch) {\n fwb += '';\n });\n $('#fwbranch').append(fwb);\n\n data.forEach(function (release) {\n let url = '';\n release.assets.forEach(function (asset) {\n if (asset.name.match(/\\.bin$/)) {\n url = asset.browser_download_url;\n }\n });\n const namecomponents = release.name.split('#');\n const ver = namecomponents[0];\n const cfg = namecomponents[2];\n const branch = namecomponents[3];\n var bits = ver.substr(ver.lastIndexOf('-') + 1);\n bits = (bits == '32' || bits == '16') ? bits : '';\n\n let body = release.body;\n body = body.replace(/'/gi, '\"');\n body = body.replace(\n /[\\s\\S]+(### Revision Log[\\s\\S]+)### ESP-IDF Version Used[\\s\\S]+/,\n '$1'\n );\n body = body.replace(/- \\(.+?\\) /g, '- ').encodeHTML();\n $('#rTable').append(`\n ${ver}${new Date(release.created_at).toLocalShort()}\n ${cfg}${branch}${bits}`\n );\n });\n if (i > 7) {\n $('#releaseTable').append(\n \"\" +\n \"\" +\n \"\" +\n '' +\n ''\n );\n $('#showallbutton').on('click', function () {\n $('tr.hide').removeClass('hide');\n $('tr#showall').addClass('hide');\n });\n }\n $('#searchfw').css('display', 'inline');\n if (!setPlatformFilter(platform_name)) {\n setPlatformFilter(project_name)\n }\n $('#rTable tr.release').on('click', function () {\n var url = this.attributes['fwurl'].value;\n if (lmsBaseUrl) {\n url = url.replace(/.*\\/download\\//, lmsBaseUrl + '/plugins/SqueezeESP32/firmware/');\n }\n $('#fw-url-input').val(url);\n $('#start-flash').show();\n $('#rTable tr.release').removeClass('table-success table-warning');\n $(this).addClass('table-success table-warning');\n });\n\n }).fail(function () {\n alert('failed to fetch release history!');\n });\n });\n $('#fwcheck').on('click', function () {\n $('#releaseTable').html('');\n $('#fwbranch').empty();\n $.getJSON(releaseURL, function (data) {\n let i = 0;\n const branches = [];\n data.forEach(function (release) {\n const namecomponents = release.name.split('#');\n const branch = namecomponents[3];\n if (!branches.includes(branch)) {\n branches.push(branch);\n }\n });\n let fwb;\n branches.forEach(function (branch) {\n fwb += '';\n });\n $('#fwbranch').append(fwb);\n\n data.forEach(function (release) {\n let url = '';\n release.assets.forEach(function (asset) {\n if (asset.name.match(/\\.bin$/)) {\n url = asset.browser_download_url;\n }\n });\n const namecomponents = release.name.split('#');\n const ver = namecomponents[0];\n const idf = namecomponents[1];\n const cfg = namecomponents[2];\n const branch = namecomponents[3];\n\n let body = release.body;\n body = body.replace(/'/gi, '\"');\n body = body.replace(\n /[\\s\\S]+(### Revision Log[\\s\\S]+)### ESP-IDF Version Used[\\s\\S]+/,\n '$1'\n );\n body = body.replace(/- \\(.+?\\) /g, '- ');\n const trclass = i++ > 6 ? ' hide' : '';\n $('#releaseTable').append(\n \"\" +\n \"\" +\n ver +\n '' +\n '' +\n new Date(release.created_at).toLocalShort() +\n '' +\n '' +\n cfg +\n '' +\n '' +\n idf +\n '' +\n '' +\n branch +\n '' +\n \"\" +\n ''\n );\n });\n if (i > 7) {\n $('#releaseTable').append(\n \"\" +\n \"\" +\n \"\" +\n '' +\n ''\n );\n $('#showallbutton').on('click', function () {\n $('tr.hide').removeClass('hide');\n $('tr#showall').addClass('hide');\n });\n }\n $('#searchfw').css('display', 'inline');\n }).fail(function () {\n alert('failed to fetch release history!');\n });\n });\n\n $('#updateAP').on('click', function () {\n refreshAP();\n console.log('refresh AP');\n });\n\n // first time the page loads: attempt to get the connection status and start the wifi scan\n getConfig();\n getCommands();\n getMessages();\n checkStatus();\n\n});\n\n// eslint-disable-next-line no-unused-vars\nwindow.setURL = function (button) {\n let url = button.dataset.url;\n\n $('[data-bs-url^=\"http\"]')\n .addClass('btn-success')\n .removeClass('btn-danger');\n $('[data-bs-url=\"' + url + '\"]')\n .addClass('btn-danger')\n .removeClass('btn-success');\n\n // if user can proxy download through LMS, modify the URL\n if (lmsBaseUrl) {\n url = url.replace(/.*\\/download\\//, lmsBaseUrl + '/plugins/SqueezeESP32/firmware/');\n }\n\n $('#fwurl').val(url);\n}\n\n\nfunction rssiToIcon(rssi) {\n if (rssi >= -55) {\n return { 'label': '****', 'icon': `signal_wifi_statusbar_4_bar` };\n } else if (rssi >= -60) {\n return { 'label': '***', 'icon': `network_wifi_3_bar` };\n } else if (rssi >= -65) {\n return { 'label': '**', 'icon': `network_wifi_2_bar` };\n } else if (rssi >= -70) {\n return { 'label': '*', 'icon': `network_wifi_1_bar` };\n } else {\n return { 'label': '.', 'icon': `signal_wifi_statusbar_null` };\n }\n}\n\nfunction refreshAP() {\n if (ConnectedTo?.urc === connectReturnCode.ETH) return;\n $.ajaxSetup({\n timeout: 3000 //Time in milliseconds\n });\n $.getJSON('/scan.json', async function () {\n await sleep(2000);\n $.getJSON('/ap.json', function (data) {\n if (data.length > 0) {\n // sort by signal strength\n data.sort(function (a, b) {\n const x = a.rssi;\n const y = b.rssi;\n // eslint-disable-next-line no-nested-ternary\n return x < y ? 1 : x > y ? -1 : 0;\n });\n apList = data;\n refreshAPHTML2(apList);\n\n }\n });\n });\n}\nfunction formatAP(ssid, rssi, auth) {\n const rssi_icon = rssiToIcon(rssi);\n const auth_icon = { label: auth == 0 ? '🔓' : '🔒', icon: auth == 0 ? 'no_encryption' : 'lock' };\n\n return `${ssid}\n ${getIcon(rssi_icon)}\n \t\n ${getIcon(auth_icon)}\n `;\n}\nfunction refreshAPHTML2(data) {\n let h = '';\n $('#wifiTable tr td:first-of-type').text('');\n $('#wifiTable tr').removeClass('table-success table-warning');\n if (data) {\n data.forEach(function (e) {\n h += formatAP(e.ssid, e.rssi, e.auth);\n });\n $('#wifiTable').html(h);\n }\n if ($('.manual_add').length == 0) {\n $('#wifiTable').append(formatAP('Manual add', 0, 0));\n $('#wifiTable tr:last').addClass('table-light text-dark').addClass('manual_add');\n }\n if (ConnectedTo.ssid && (ConnectedTo.urc === connectReturnCode.OK || ConnectedTo.urc === connectReturnCode.RESTORE)) {\n const wifiSelector = `#wifiTable td:contains(\"${ConnectedTo.ssid}\")`;\n if ($(wifiSelector).filter(function () { return $(this).text() === ConnectedTo.ssid; }).length == 0) {\n $('#wifiTable').prepend(`${formatAP(ConnectedTo.ssid, ConnectedTo.rssi ?? 0, 0)}`);\n }\n $(wifiSelector).filter(function () { return $(this).text() === ConnectedTo.ssid; }).siblings().first().html('✓').parent().addClass((ConnectedTo.urc === connectReturnCode.OK ? 'table-success' : 'table-warning'));\n $('span#foot-if').html(`SSID: ${ConnectedTo.ssid}, IP: ${ConnectedTo.ip}`);\n $('#wifiStsIcon').html(rssiToIcon(ConnectedTo.rssi));\n\n }\n else if (ConnectedTo?.urc !== connectReturnCode.ETH) {\n $('span#foot-if').html('');\n }\n\n}\nfunction refreshETH() {\n\n if (ConnectedTo.urc === connectReturnCode.ETH) {\n $('span#foot-if').html(`Network: Ethernet, IP: ${ConnectedTo.ip}`);\n }\n}\nfunction showTask(task) {\n console.debug(\n this.toLocaleString() +\n '\\t' +\n task.nme +\n '\\t' +\n task.cpu +\n '\\t' +\n taskStates[task.st] +\n '\\t' +\n task.minstk +\n '\\t' +\n task.bprio +\n '\\t' +\n task.cprio +\n '\\t' +\n task.num\n );\n $('tbody#tasks').append(\n '' +\n task.num +\n '' +\n task.nme +\n '' +\n task.cpu +\n '' +\n taskStates[task.st] +\n '' +\n task.minstk +\n '' +\n task.bprio +\n '' +\n task.cprio +\n ''\n );\n}\nfunction btExists(name) {\n return getBTSinkOpt(name).length > 0;\n}\nfunction getBTSinkOpt(name) {\n return $(`${btSinkNamesOptSel} option:contains('${name}')`);\n}\nfunction getMessages() {\n $.ajaxSetup({\n timeout: messageInterval //Time in milliseconds\n });\n $.getJSON('/messages.json', async function (data) {\n for (const msg of data) {\n const msgAge = msg.current_time - msg.sent_time;\n var msgTime = new Date();\n msgTime.setTime(msgTime.getTime() - msgAge);\n switch (msg.class) {\n case 'MESSAGING_CLASS_OTA':\n flashState.EventOTAMessageClass(msg.message);\n break;\n case 'MESSAGING_CLASS_STATS':\n // for task states, check structure : task_state_t\n var statsData = JSON.parse(msg.message);\n console.debug(\n msgTime.toLocalShort() +\n ' - Number of running tasks: ' +\n statsData.ntasks\n );\n console.debug(\n msgTime.toLocalShort() +\n '\\tname' +\n '\\tcpu' +\n '\\tstate' +\n '\\tminstk' +\n '\\tbprio' +\n '\\tcprio' +\n '\\tnum'\n );\n if (statsData.tasks) {\n if ($('#tasks_sect').css('visibility') === 'collapse') {\n $('#tasks_sect').css('visibility', 'visible');\n }\n $('tbody#tasks').html('');\n statsData.tasks\n .sort(function (a, b) {\n return b.cpu - a.cpu;\n })\n .forEach(showTask, msgTime);\n } else if ($('#tasks_sect').css('visibility') === 'visible') {\n $('tbody#tasks').empty();\n $('#tasks_sect').css('visibility', 'collapse');\n }\n break;\n case 'MESSAGING_CLASS_SYSTEM':\n showMessage(msg, msgTime);\n break;\n case 'MESSAGING_CLASS_CFGCMD':\n var msgparts = msg.message.split(/([^\\n]*)\\n(.*)/gs);\n showCmdMessage(msgparts[1], msg.type, msgparts[2], true);\n break;\n case 'MESSAGING_CLASS_BT':\n if ($(\"#cfg-audio-bt_source-sink_name\").is('input')) {\n var attr = $(\"#cfg-audio-bt_source-sink_name\")[0].attributes;\n var attrs = '';\n for (var j = 0; j < attr.length; j++) {\n if (attr.item(j).name != \"type\") {\n attrs += `${attr.item(j).name} = \"${attr.item(j).value}\" `;\n }\n }\n var curOpt = $(\"#cfg-audio-bt_source-sink_name\")[0].value;\n $(\"#cfg-audio-bt_source-sink_name\").replaceWith(` `);\n }\n JSON.parse(msg.message).forEach(function (btEntry) {\n //\n // \n if (!btExists(btEntry.name)) {\n $(\"#cfg-audio-bt_source-sink_name\").append(``);\n showMessage({ type: msg.type, message: `BT Audio device found: ${btEntry.name} RSSI: ${btEntry.rssi} ` }, msgTime);\n }\n getBTSinkOpt(btEntry.name).attr('data-bs-description', `${btEntry.name} (${btEntry.rssi}dB)`)\n .attr('rssi', btEntry.rssi)\n .attr('value', btEntry.name)\n .text(`${btEntry.name} [${btEntry.rssi}dB]`).trigger('change');\n\n });\n $(btSinkNamesOptSel).append($(`${btSinkNamesOptSel} option`).remove().sort(function (a, b) {\n console.log(`${parseInt($(a).attr('rssi'))} < ${parseInt($(b).attr('rssi'))} ? `);\n return parseInt($(a).attr('rssi')) < parseInt($(b).attr('rssi')) ? 1 : -1;\n }));\n break;\n default:\n break;\n }\n }\n setTimeout(getMessages, messageInterval);\n }).fail(function (xhr, ajaxOptions, thrownError) {\n\n if (xhr.status == 404) {\n $('.orec').hide(); // system commands won't be available either\n messagesHeld = true;\n }\n else {\n handleExceptionResponse(xhr, ajaxOptions, thrownError);\n }\n if (xhr.status == 0 && xhr.readyState == 0) {\n // probably a timeout. Target is rebooting? \n setTimeout(getMessages, messageInterval * 2); // increase duration if a failure happens\n }\n else if (!messagesHeld) {\n // 404 here means we rebooted to an old recovery\n setTimeout(getMessages, messageInterval); // increase duration if a failure happens\n }\n\n }\n );\n\n /*\n Minstk is minimum stack space left\nBprio is base priority\ncprio is current priority\nnme is name\nst is task state. I provided a \"typedef\" that you can use to convert to text\ncpu is cpu percent used\n*/\n}\nfunction handleRecoveryMode(data) {\n const locRecovery = data.recovery ?? 0;\n if (locRecovery === 1) {\n recovery = true;\n $('.recovery_element').show();\n $('.ota_element').hide();\n $('#boot-button').html('Reboot');\n $('#boot-form').attr('action', '/reboot_ota.json');\n } else {\n if (!recovery && messagesHeld) {\n messagesHeld = false;\n setTimeout(getMessages, messageInterval); // increase duration if a failure happens\n }\n recovery = false;\n\n $('.recovery_element').hide();\n $('.ota_element').show();\n $('#boot-button').html('Recovery');\n $('#boot-form').attr('action', '/recovery.json');\n }\n\n}\n\nfunction hasConnectionChanged(data) {\n // gw: \"192.168.10.1\"\n // ip: \"192.168.10.225\"\n // netmask: \"255.255.255.0\"\n // ssid: \"MyTestSSID\"\n\n return (data.urc !== ConnectedTo.urc ||\n data.ssid !== ConnectedTo.ssid ||\n data.gw !== ConnectedTo.gw ||\n data.netmask !== ConnectedTo.netmask ||\n data.ip !== ConnectedTo.ip || data.rssi !== ConnectedTo.rssi)\n}\nfunction handleWifiDialog(data) {\n if ($('#WifiConnectDialog').is(':visible')) {\n if (ConnectedTo.ip) {\n $('#ipAddress').text(ConnectedTo.ip);\n }\n if (ConnectedTo.ssid) {\n $('#connectedToSSID').text(ConnectedTo.ssid);\n }\n if (ConnectedTo.gw) {\n $('#gateway').text(ConnectedTo.gw);\n }\n if (ConnectedTo.netmask) {\n $('#netmask').text(ConnectedTo.netmask);\n }\n if (ConnectingToSSID.Action === undefined || (ConnectingToSSID.Action && ConnectingToSSID.Action == ConnectingToActions.STS)) {\n $(\"*[class*='connecting']\").hide();\n $('.connecting-status').show();\n }\n if (SystemConfig.ap_ssid) {\n $('#apName').text(SystemConfig.ap_ssid.value);\n }\n if (SystemConfig.ap_pwd) {\n $('#apPass').text(SystemConfig.ap_pwd.value);\n }\n if (!data) {\n return;\n }\n else {\n switch (data.urc) {\n case connectReturnCode.OK:\n if (data.ssid && data.ssid === ConnectingToSSID.ssid) {\n $(\"*[class*='connecting']\").hide();\n $('.connecting-success').show();\n ConnectingToSSID.Action = ConnectingToActions.STS;\n }\n break;\n case connectReturnCode.FAIL:\n // \n if (ConnectingToSSID.Action != ConnectingToActions.STS && ConnectingToSSID.ssid == data.ssid) {\n $(\"*[class*='connecting']\").hide();\n $('.connecting-fail').show();\n }\n break;\n case connectReturnCode.LOST:\n\n break;\n case connectReturnCode.RESTORE:\n if (ConnectingToSSID.Action != ConnectingToActions.STS && ConnectingToSSID.ssid != data.ssid) {\n $(\"*[class*='connecting']\").hide();\n $('.connecting-fail').show();\n }\n break;\n case connectReturnCode.DISC:\n // that's a manual disconnect\n // if ($('#wifi-status').is(':visible')) {\n // $('#wifi-status').slideUp('fast', function() {});\n // $('span#foot-wifi').html('');\n\n // } \n break;\n default:\n break;\n }\n }\n\n }\n}\nfunction setIcons(offline) {\n $('.material-icons').each(function (_index, entry) {\n entry.textContent = entry.attributes[offline ? 'aria-label' : 'icon'].value;\n });\n}\nfunction handleNetworkStatus(data) {\n setIcons(!isConnected());\n if (hasConnectionChanged(data) || !data.urc) {\n ConnectedTo = data;\n $(\".if_eth\").hide();\n $('.if_wifi').hide();\n if (!data.urc || ConnectedTo.urc != connectReturnCode.ETH) {\n $('.if_wifi').show();\n refreshAPHTML2();\n }\n else {\n $(\".if_eth\").show();\n refreshETH();\n }\n\n }\n handleWifiDialog(data);\n}\n\n\n\nfunction batteryToIcon(voltage) {\n /* Assuming Li-ion 18650s as a power source, 3.9V per cell, or above is treated\n as full charge (>75% of capacity). 3.4V is empty. The gauge is loosely\n following the graph here:\n https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages\n using the 0.2C discharge profile for the rest of the values.\n*/\n\n for (const iconEntry of batIcons) {\n for (const entryRanges of iconEntry.ranges) {\n if (inRange(voltage, entryRanges.f, entryRanges.t)) {\n return { label: iconEntry.label, icon: iconEntry.icon };\n }\n }\n }\n\n\n return { label: '▪▪▪▪', icon: \"battery_full\" };\n}\nfunction checkStatus() {\n $.ajaxSetup({\n timeout: statusInterval //Time in milliseconds\n });\n $.getJSON('/status.json', function (data) {\n handleRecoveryMode(data);\n handleNVSVisible();\n handleNetworkStatus(data);\n handlebtstate(data);\n flashState.EventTargetStatus(data);\n if(data.depth) {\n depth = data.depth;\n if(depth==16){\n $('#cmd_opt_R').show();\n }\n else{\n $('#cmd_opt_R').hide();\n }\n }\n\n\n if (data.project_name && data.project_name !== '') {\n project_name = data.project_name;\n }\n if (data.platform_name && data.platform_name !== '') {\n platform_name = data.platform_name;\n }\n if (board_model === '') board_model = project_name;\n if (board_model === '') board_model = 'Squeezelite-ESP32';\n if (data.version && data.version !== '') {\n versionName = data.version;\n $(\"#navtitle\").html(`${board_model}${recovery ? '
[recovery]' : ''}`);\n $('span#foot-fw').html(`fw: ${versionName}, mode: ${recovery ? \"Recovery\" : project_name}`);\n } else {\n $('span#flash-status').html('');\n }\n if (data.Voltage) {\n const bat_icon = batteryToIcon(data.Voltage);\n $('#battery').html(`${getIcon(bat_icon)}`);\n $('#battery').attr(\"aria-label\", bat_icon.label);\n $('#battery').attr(\"icon\", bat_icon.icon);\n $('#battery').show();\n } else {\n $('#battery').hide();\n }\n if ((data.message ?? '') != '' && prevmessage != data.message) {\n // supporting older recovery firmwares - messages will come from the status.json structure\n prevmessage = data.message;\n showLocalMessage(data.message, 'MESSAGING_INFO')\n }\n is_i2c_locked = data.is_i2c_locked;\n if (is_i2c_locked) {\n $('flds-cfg-hw-preset').hide();\n }\n else {\n $('flds-cfg-hw-preset').show();\n }\n $(\"button[onclick*='handleReboot']\").removeClass('rebooting');\n\n if (typeof lmsBaseUrl == \"undefined\" || data.lms_ip != prevLMSIP && data.lms_ip && data.lms_port) {\n const baseUrl = 'http://' + data.lms_ip + ':' + data.lms_port;\n prevLMSIP = data.lms_ip;\n $.ajax({\n url: baseUrl + '/plugins/SqueezeESP32/firmware/-check.bin',\n type: 'HEAD',\n dataType: 'text',\n cache: false,\n error: function () {\n // define the value, so we don't check it any more.\n lmsBaseUrl = '';\n },\n success: function () {\n lmsBaseUrl = baseUrl;\n }\n });\n }\n $('#o_jack').css({ display: Number(data.Jack) ? 'inline' : 'none' });\n setTimeout(checkStatus, statusInterval);\n }).fail(function (xhr, ajaxOptions, thrownError) {\n handleExceptionResponse(xhr, ajaxOptions, thrownError);\n if (xhr.status == 0 && xhr.readyState == 0) {\n // probably a timeout. Target is rebooting? \n setTimeout(checkStatus, messageInterval * 2); // increase duration if a failure happens\n }\n else {\n setTimeout(checkStatus, messageInterval); // increase duration if a failure happens\n }\n });\n}\n// eslint-disable-next-line no-unused-vars\nwindow.runCommand = function (button, reboot) {\n let cmdstring = button.attributes.cmdname.value;\n showCmdMessage(\n button.attributes.cmdname.value,\n 'MESSAGING_INFO',\n 'Executing.',\n false\n );\n const fields = document.getElementById('flds-' + cmdstring);\n const allfields = fields?.querySelectorAll('select,input');\n if (cmdstring === 'cfg-hw-preset') return handleHWPreset(allfields, reboot);\n cmdstring += ' ';\n if (fields) {\n\n for (const field of allfields) {\n let qts = '';\n let opt = '';\n let attr = field.attributes;\n let isSelect = $(field).is('select');\n const hasValue = attr?.hasvalue?.value === 'true';\n const validVal = (isSelect && field.value !== '--') || (!isSelect && field.value !== '');\n\n if (!hasValue || hasValue && validVal) {\n if (attr?.longopts?.value !== 'undefined') {\n opt += '--' + attr?.longopts?.value;\n } else if (attr?.shortopts?.value !== 'undefined') {\n opt = '-' + attr.shortopts.value;\n }\n\n if (attr?.hasvalue?.value === 'true') {\n if (attr?.value !== '') {\n qts = /\\s/.test(field.value) ? '\"' : '';\n cmdstring += opt + ' ' + qts + field.value + qts + ' ';\n }\n } else {\n // this is a checkbox\n if (field?.checked) {\n cmdstring += opt + ' ';\n }\n }\n }\n }\n }\n\n console.log(cmdstring);\n\n const data = {\n timestamp: Date.now(),\n };\n data.command = cmdstring;\n\n $.ajax({\n url: '/commands.json',\n dataType: 'text',\n method: 'POST',\n cache: false,\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify(data),\n error: function (xhr, _ajaxOptions, thrownError) {\n var cmd = JSON.parse(this.data).command;\n if (xhr.status == 404) {\n showCmdMessage(\n cmd.substr(0, cmd.indexOf(' ')),\n 'MESSAGING_ERROR',\n `${recovery ? 'Limited recovery mode active. Unsupported action ' : 'Unexpected error while processing command'}`,\n true\n );\n }\n else {\n handleExceptionResponse(xhr, _ajaxOptions, thrownError);\n showCmdMessage(\n cmd.substr(0, cmd.indexOf(' ') - 1),\n 'MESSAGING_ERROR',\n `Unexpected error ${(thrownError !== '') ? thrownError : 'with return status = ' + xhr.status}`,\n true\n );\n }\n },\n success: function (response) {\n $('.orec').show();\n console.log(response);\n if (\n JSON.parse(response).Result === 'Success' &&\n reboot\n ) {\n delayReboot(2500, button.attributes.cmdname.value);\n }\n },\n });\n}\nfunction getLongOps(data, name, longopts) {\n return data.values[name] !== undefined ? data.values[name][longopts] : \"\";\n}\nfunction getCommands() {\n $.ajaxSetup({\n timeout: 7000 //Time in milliseconds\n });\n $.getJSON('/commands.json', function (data) {\n console.log(data);\n $('.orec').show();\n data.commands.forEach(function (command) {\n if ($('#flds-' + command.name).length === 0) {\n const cmdParts = command.name.split('-');\n const isConfig = cmdParts[0] === 'cfg';\n const targetDiv = '#tab-' + cmdParts[0] + '-' + cmdParts[1];\n let innerhtml = '';\n innerhtml += `
${command.help.encodeHTML().replace(/\\n/g, '
')}
`;\n if (command.argtable) {\n command.argtable.forEach(function (arg) {\n let placeholder = arg.datatype || '';\n const ctrlname = command.name + '-' + arg.longopts;\n const curvalue = getLongOps(data, command.name, arg.longopts);\n\n let attributes = 'hasvalue=' + arg.hasvalue + ' ';\n attributes += 'longopts=\"' + arg.longopts + '\" ';\n attributes += 'shortopts=\"' + arg.shortopts + '\" ';\n attributes += 'checkbox=' + arg.checkbox + ' ';\n attributes += 'cmdname=\"' + command.name + '\" ';\n attributes +=\n 'id=\"' +\n ctrlname +\n '\" name=\"' +\n ctrlname +\n '\" hasvalue=\"' +\n arg.hasvalue +\n '\" ';\n let extraclass = arg.mincount > 0 ? 'bg-success' : '';\n if (arg.glossary === 'hidden') {\n attributes += ' style=\"visibility: hidden;\"';\n }\n if (arg.checkbox) {\n innerhtml += `
`;\n } else {\n innerhtml += `
`;\n if (placeholder.includes('|')) {\n extraclass = placeholder.startsWith('+') ? ' multiple ' : '';\n placeholder = placeholder\n .replace('<', '')\n .replace('=', '')\n .replace('>', '');\n innerhtml += `';\n } else {\n innerhtml += ``;\n }\n }\n\n innerhtml += `${arg.checkbox ? '
' : ''}Previous value: ${arg.checkbox ? (curvalue ? 'Checked' : 'Unchecked') : (curvalue || '')}${arg.checkbox ? '' : '
'}`;\n });\n }\n innerhtml += `
\n
\n
\n Result\n
\n
\n
`;\n if (isConfig) {\n innerhtml +=\n `\n`;\n } else {\n innerhtml += ``;\n }\n innerhtml += '
';\n if (isConfig) {\n $(targetDiv).append(innerhtml);\n } else {\n $('#commands-list').append(innerhtml);\n }\n }\n });\n $(\".sclk\").off('click').on('click', function () { runCommand(this, false); });\n $(\".cclk\").off('click').on('click', function () { runCommand(this, true); });\n data.commands.forEach(function (command) {\n $('[cmdname=' + command.name + ']:input').val('');\n $('[cmdname=' + command.name + ']:checkbox').prop('checked', false);\n if (command.argtable) {\n command.argtable.forEach(function (arg) {\n const ctrlselector = '#' + command.name + '-' + arg.longopts;\n const ctrlValue = getLongOps(data, command.name, arg.longopts);\n if (arg.checkbox) {\n $(ctrlselector)[0].checked = ctrlValue;\n } else {\n if (ctrlValue !== undefined) {\n $(ctrlselector)\n .val(ctrlValue)\n .trigger('change');\n }\n if (\n $(ctrlselector)[0].value.length === 0 &&\n (arg.datatype || '').includes('|')\n ) {\n $(ctrlselector)[0].value = '--';\n }\n }\n });\n }\n });\n loadPresets();\n }).fail(function (xhr, ajaxOptions, thrownError) {\n if (xhr.status == 404) {\n $('.orec').hide();\n }\n else {\n handleExceptionResponse(xhr, ajaxOptions, thrownError);\n }\n $('#commands-list').empty();\n\n });\n}\n\nfunction getConfig() {\n $.ajaxSetup({\n timeout: 7000 //Time in milliseconds\n });\n $.getJSON('/config.json', function (entries) {\n $('#nvsTable tr').remove();\n const data = (entries.config ? entries.config : entries);\n SystemConfig = data;\n commandBTSinkName = '';\n Object.keys(data)\n .sort()\n .forEach(function (key) {\n let val = data[key].value;\n if (key === 'autoexec1') {\n /* call new function to parse the squeezelite options */\n processSqueezeliteCommandLine(val);\n } else if (key === 'host_name') {\n val = val.replaceAll('\"', '');\n $('input#dhcp-name1').val(val);\n $('input#dhcp-name2').val(val);\n if ($('#cmd_opt_n').length == 0) {\n $('#cmd_opt_n').val(val);\n }\n document.title = val;\n hostName = val;\n } else if (key === 'rel_api') {\n releaseURL = val;\n }\n else if (key === 'enable_airplay') {\n $(\"#s_airplay\").css({ display: isEnabled(val) ? 'inline' : 'none' })\n }\n else if (key === 'enable_cspot') {\n $(\"#s_cspot\").css({ display: isEnabled(val) ? 'inline' : 'none' })\n }\n else if (key == 'preset_name') {\n preset_name = val;\n }\n else if (key == 'board_model') {\n board_model = val;\n }\n\n $('tbody#nvsTable').append(\n '' +\n '' +\n key +\n '' +\n \"\" +\n \"' +\n '' +\n ''\n );\n $('input#' + key).val(data[key].value);\n });\n if(commandBTSinkName.length > 0) {\n // persist the sink name found in the autoexec1 command line\n $('#cfg-audio-bt_source-sink_name').val(commandBTSinkName);\n }\n $('tbody#nvsTable').append(\n \"\"\n );\n if (entries.gpio) {\n $('#pins').show();\n $('tbody#gpiotable tr').remove();\n entries.gpio.forEach(function (gpioEntry) {\n $('tbody#gpiotable').append(\n '' +\n gpioEntry.group +\n '' +\n gpioEntry.name +\n '' +\n gpioEntry.gpio +\n '' +\n (gpioEntry.fixed ? 'Fixed' : 'Configuration') +\n ''\n );\n });\n }\n else {\n $('#pins').hide();\n }\n }).fail(function (xhr, ajaxOptions, thrownError) {\n handleExceptionResponse(xhr, ajaxOptions, thrownError);\n });\n}\n\nfunction processSqueezeliteCommandLine(val) {\n const parsed = parseSqueezeliteCommandLine(val);\n if (parsed.output.toUpperCase().startsWith('I2S')) {\n handleTemplateTypeRadio('i2s');\n } else if (parsed.output.toUpperCase().startsWith('SPDIF')) {\n handleTemplateTypeRadio('spdif');\n } else if (parsed.output.toUpperCase().startsWith('BT')) {\n if(parsed.otherOptions.btname){ \n commandBTSinkName= parsed.otherOptions.btname;\n }\n handleTemplateTypeRadio('bt');\n\n }\n Object.keys(parsed.options).forEach(function (key) {\n const option = parsed.options[key];\n if (!$(`#cmd_opt_${key}`).hasOwnProperty('checked')) {\n $(`#cmd_opt_${key}`).val(option);\n } else {\n $(`#cmd_opt_${key}`)[0].checked = option;\n }\n });\n if (parsed.options.hasOwnProperty('u')) {\n // parse -u v[:i] and check the appropriate radio button with id #resample_v\n const [resampleValue, resampleInterpolation] = parsed.options.u.split(':');\n $(`#resample_${resampleValue}`).prop('checked', true);\n // if resampleinterpolation is set, check resample_i checkbox\n if (resampleInterpolation) {\n $('#resample_i').prop('checked', true);\n }\n }\n if (parsed.options.hasOwnProperty('s')) {\n // parse -u v[:i] and check the appropriate radio button with id #resample_v\n if(parsed.options.s === '-disable'){\n $('#disable-squeezelite')[0].checked = true;\n }\n else {\n $('#disable-squeezelite')[0].checked = false;\n }\n }\n\n \n\n\n}\n\nfunction showLocalMessage(message, severity) {\n const msg = {\n message: message,\n type: severity,\n };\n showMessage(msg, new Date());\n}\n\nfunction showMessage(msg, msgTime) {\n let color = 'table-success';\n\n if (msg.type === 'MESSAGING_WARNING') {\n color = 'table-warning';\n if (messageseverity === 'MESSAGING_INFO') {\n messageseverity = 'MESSAGING_WARNING';\n }\n } else if (msg.type === 'MESSAGING_ERROR') {\n if (\n messageseverity === 'MESSAGING_INFO' ||\n messageseverity === 'MESSAGING_WARNING'\n ) {\n messageseverity = 'MESSAGING_ERROR';\n }\n color = 'table-danger';\n }\n if (++messagecount > 0) {\n $('#msgcnt').removeClass('badge-success');\n $('#msgcnt').removeClass('badge-warning');\n $('#msgcnt').removeClass('badge-danger');\n $('#msgcnt').addClass(pillcolors[messageseverity]);\n $('#msgcnt').text(messagecount);\n }\n\n $('#syslogTable').append(\n \"\" +\n '' +\n msgTime.toLocalShort() +\n '' +\n '' +\n msg.message.encodeHTML() +\n '' +\n ''\n );\n}\n\nfunction inRange(x, min, max) {\n return (x - min) * (x - max) <= 0;\n}\n\nfunction sleep(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nrequire(\"bootstrap\");\nrequire(\"./sass/main.scss\");\nrequire(\"./assets/images/favicon-32x32.png\");\nrequire(\"./js/custom.js\");\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = (module) => {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t826: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunksqueezelite_esp32\"] = self[\"webpackChunksqueezelite_esp32\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [987], () => (__webpack_require__(607)))\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","he","require","Promise","get_control_option_value","obj","ctrl","id","val","opt","$","concat","attr","checked","replace","includes","handleNVSVisible","nvs_previous_checked","isEnabled","Cookies","get","recovery","show","hide","undefined","match","window","bootstrap","String","prototype","format","Object","assign","args","arguments","this","number","encodeHTML","encode","Date","toLocalShort","toLocaleString","dateStyle","timeStyle","nvsTypes","btIcons","bt_playing","bt_disconnected","bt_neutral","bt_connecting","bt_connected","bt_disabled","play_arrow","pause","stop","batIcons","icon","label","ranges","f","t","btStateIcons","desc","sub","pillcolors","MESSAGING_INFO","MESSAGING_WARNING","MESSAGING_ERROR","connectReturnCode","OK","FAIL","DISC","LOST","RESTORE","ETH","taskStates","flashState","NONE","REBOOT_TO_RECOVERY","SET_FWURL","FLASHING","DONE","UPLOADING","ERROR","UPLOADCOMPLETE","_state","olderRecovery","statusText","flashURL","flashFileName","statusPercent","Completed","prevRecovery","updateModal","Modal","document","getElementById","reset","UpdateProgress","removeClass","prop","value","isStateError","html","parent","isStateUploadComplete","isStateNone","isStateRebootRecovery","isStateSetUrl","isStateFlashing","isStateDone","isStateUploading","init","SetStateError","addClass","SetStateNone","SetStateRebootRecovery","SetStatusText","ajax","url","context","dataType","method","cache","contentType","data","JSON","stringify","timestamp","now","error","xhr","_ajaxOptions","thrownError","_xhr$status","setOTAError","status","complete","response","SetStateSetUrl","post_config","fwurl","type","SetStateFlashing","SetStateDone","SetStateUploading","SetStateUploadComplete","isFlashExecuting","toString","_this","keys","find","x","setOTATargets","fileInput","files","length","message","SetStatusPercent","ShowDialog","pct","pctChanged","txt","changed","css","text","StartOTA","logEvent","name","TargetReadyStartOTA","UploadLocalFile","xhttp","XMLHttpRequest","boundHandleUploadProgressEvent","HandleUploadProgressEvent","bind","boundsetOTAError","upload","addEventListener","onreadystatechange","readyState","open","send","console","Math","round","loaded","total","EventTargetStatus","_data$ota_pct","_data$ota_dsc","ota_pct","ota_dsc","EventOTAMessageClass","otaData","parse","fun","log","hideSurrounding","presetsloaded","messageInterval","confPayload","config","handleExceptionResponse","parseSqueezeliteCommandLine","commandLine","output","options","otherValues","i","arg","startsWith","option","slice","join","trim","o","indexOf","substring","getOutput","n","getName","otherOptions","btname","toUpperCase","temp","isConnected","ConnectedTo","hasOwnProperty","ip","getIcon","icons","handleTemplateTypeRadio","outtype","children","display","commandDefaults","forEach","key","showLocalMessage","showCmdMessage","cmdname","msgtype","msgtext","append","color","escapedtext","hFlash","handleReboot","link","delayReboot","lmsBaseUrl","releaseURL","messagesHeld","commandBTSinkName","i2s","b","C","W","Z","spdif","bt","validOptions","codecs","messagecount","messageseverity","SystemConfig","LastCommandsState","hostName","versionName","prevmessage","project_name","board_model","platform_name","preset_name","btSinkNamesOptSel","ConnectingToSSID","prevLMSIP","ConnectingToActions","getConfigJson","slimMode","each","_index","entry","nvsType","parseInt","attributes","nvs_type","duration","empty","resolve","delay","then","rdata","HideCmdMessage","getCommands","getConfig","setPlatformFilter","filter","trigger","renderError","fieldname","errorFieldName","errorField","field","after","rssiToIcon","rssi","refreshAP","_ConnectedTo","urc","ajaxSetup","timeout","getJSON","_asyncToGenerator","_regeneratorRuntime","_callee","_context","prev","next","sleep","sort","a","y","refreshAPHTML2","formatAP","ssid","auth","rssi_icon","auth_icon","_ConnectedTo2","h","e","_ConnectedTo$rssi","wifiSelector","prepend","siblings","first","showTask","task","debug","nme","cpu","st","minstk","bprio","cprio","num","getBTSinkOpt","getMessages","_ref2","_callee2","_iterator","_step","_loop","msgTime","statsData","msgparts","attrs","j","curOpt","_context3","_createForOfIteratorHelper","msg","msgAge","_context2","current_time","sent_time","setTime","getTime","t0","abrupt","ntasks","tasks","showMessage","split","is","item","replaceWith","btEntry","remove","s","done","delegateYield","t1","finish","setTimeout","_x","apply","fail","ajaxOptions","handleWifiDialog","gw","netmask","Action","STS","ap_ssid","ap_pwd","setIcons","offline","textContent","handleNetworkStatus","hasConnectionChanged","checkStatus","_data$message","_data$recovery","handleRecoveryMode","tt","bt_status","bt_sub_status","iconindex","handlebtstate","depth","version","Voltage","bat_icon","voltage","_i3","_batIcons","_step2","iconEntry","_iterator2","entryRanges","err","batteryToIcon","is_i2c_locked","lms_ip","lms_port","baseUrl","success","Number","Jack","getLongOps","longopts","values","commands","command","cmdParts","isConfig","targetDiv","innerhtml","help","argtable","placeholder","datatype","ctrlname","curvalue","hasvalue","shortopts","checkbox","extraclass","mincount","glossary","choice","off","on","runCommand","ctrlselector","ctrlValue","_","jqxhr","textStatus","entries","parsed","_parsed$options$u$spl","u","_parsed$options$u$spl2","_slicedToArray","resampleValue","resampleInterpolation","processSqueezeliteCommandLine","replaceAll","title","gpio","gpioEntry","fixed","group","severity","ms","reason","_resolve","reject","saveAutoexec1","_get_control_option_v","optStr","resample","_i","_Object$entries","_Object$entries$_i","concatenateOptions","autoexec1","responseText","result","Result","handleDisconnect","handleConnect","pwd","dhcpname","ready","index","not","_get_control_option_v2","invalid","map","test","event","relatedTarget","CONN","MAN","FileReader","file","fr","onload","target","ex","alert","readAsText","slideUp","slideDown","preventDefault","currentValue","originalValue","set","createElement","href","URL","createObjectURL","Blob","setAttribute","body","appendChild","click","removeChild","branches","release","branch","push","fwb","assets","asset","browser_download_url","namecomponents","ver","cfg","bits","substr","lastIndexOf","created_at","idf","trclass","setURL","button","dataset","reboot","cmdstring","fields","allfields","querySelectorAll","selJson","cmd","model_config","_i2","_Object$entries2","_Object$entries2$_i","storedval","handleHWPreset","_step3","_iterator3","_attr$hasvalue","qts","isSelect","hasValue","validVal","_attr$longopts","_attr$shortopts","_attr$hasvalue2","_attr$longopts2","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","exports","module","__webpack_modules__","call","m","O","chunkIds","fn","priority","notFulfilled","Infinity","fulfilled","every","splice","r","getter","__esModule","d","definition","defineProperty","enumerable","g","globalThis","Function","Symbol","toStringTag","nmd","paths","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","self","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file diff --git a/components/wifi-manager/webapp/dist/js/index.dd7cd3.bundle.js b/components/wifi-manager/webapp/dist/js/index.dd7cd3.bundle.js new file mode 100644 index 00000000..d33a8508 --- /dev/null +++ b/components/wifi-manager/webapp/dist/js/index.dd7cd3.bundle.js @@ -0,0 +1,2 @@ +(()=>{var e,t={874:(e,t,o)=>{var r=o(19),n=r,i=function(){return this?this:"undefined"!=typeof window?window:void 0!==i?i:"undefined"!=typeof self?self:Function("return this")()}.call(null),s=o(21);n.object.extend(proto,s),n.exportSymbol("proto.Conf.Artwork",null,i),n.exportSymbol("proto.Conf.Battery",null,i),n.exportSymbol("proto.Conf.BatteryAttenEnum",null,i),n.exportSymbol("proto.Conf.BatteryChannelEnum",null,i),n.exportSymbol("proto.Conf.Button",null,i),n.exportSymbol("proto.Conf.ButtonAction",null,i),n.exportSymbol("proto.Conf.ButtonActions",null,i),n.exportSymbol("proto.Conf.Config",null,i),n.exportSymbol("proto.Conf.DACDev",null,i),n.exportSymbol("proto.Conf.DACModelEnum",null,i),n.exportSymbol("proto.Conf.Dev",null,i),n.exportSymbol("proto.Conf.DeviceTypeEnum",null,i),n.exportSymbol("proto.Conf.DispCommon",null,i),n.exportSymbol("proto.Conf.DispOffsets",null,i),n.exportSymbol("proto.Conf.DisplayDev",null,i),n.exportSymbol("proto.Conf.DisplayDev.DisptypeCase",null,i),n.exportSymbol("proto.Conf.DisplayDriverEnum",null,i),n.exportSymbol("proto.Conf.Eth",null,i),n.exportSymbol("proto.Conf.Eth.EthtypeCase",null,i),n.exportSymbol("proto.Conf.EthCommon",null,i),n.exportSymbol("proto.Conf.EthModelEnum",null,i),n.exportSymbol("proto.Conf.EthRMII",null,i),n.exportSymbol("proto.Conf.EthSPI",null,i),n.exportSymbol("proto.Conf.EthType",null,i),n.exportSymbol("proto.Conf.GPIO",null,i),n.exportSymbol("proto.Conf.GPIOExp",null,i),n.exportSymbol("proto.Conf.GPIOExpModelEnum",null,i),n.exportSymbol("proto.Conf.Gpios",null,i),n.exportSymbol("proto.Conf.HostEnum",null,i),n.exportSymbol("proto.Conf.I2CBus",null,i),n.exportSymbol("proto.Conf.I2CDisplay",null,i),n.exportSymbol("proto.Conf.I2CPortEnum",null,i),n.exportSymbol("proto.Conf.LEDStrip",null,i),n.exportSymbol("proto.Conf.MCKEnum",null,i),n.exportSymbol("proto.Conf.Metadata",null,i),n.exportSymbol("proto.Conf.PortEnum",null,i),n.exportSymbol("proto.Conf.Rotary",null,i),n.exportSymbol("proto.Conf.SPDIFDev",null,i),n.exportSymbol("proto.Conf.SPIBus",null,i),n.exportSymbol("proto.Conf.SPIDisplay",null,i),n.exportSymbol("proto.Conf.Services",null,i),n.exportSymbol("proto.Conf.SleepService",null,i),n.exportSymbol("proto.Conf.WS2812",null,i),proto.Conf.GPIO=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.GPIO,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.GPIO.displayName="proto.Conf.GPIO"),proto.Conf.I2CBus=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.I2CBus,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.I2CBus.displayName="proto.Conf.I2CBus"),proto.Conf.DACDev=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.DACDev,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.DACDev.displayName="proto.Conf.DACDev"),proto.Conf.SPDIFDev=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.SPDIFDev,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.SPDIFDev.displayName="proto.Conf.SPDIFDev"),proto.Conf.DispOffsets=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.DispOffsets,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.DispOffsets.displayName="proto.Conf.DispOffsets"),proto.Conf.DispCommon=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.DispCommon,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.DispCommon.displayName="proto.Conf.DispCommon"),proto.Conf.I2CDisplay=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.I2CDisplay,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.I2CDisplay.displayName="proto.Conf.I2CDisplay"),proto.Conf.SPIDisplay=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.SPIDisplay,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.SPIDisplay.displayName="proto.Conf.SPIDisplay"),proto.Conf.SPIBus=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.SPIBus,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.SPIBus.displayName="proto.Conf.SPIBus"),proto.Conf.DisplayDev=function(e){r.Message.initialize(this,e,0,-1,null,proto.Conf.DisplayDev.oneofGroups_)},n.inherits(proto.Conf.DisplayDev,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.DisplayDev.displayName="proto.Conf.DisplayDev"),proto.Conf.GPIOExp=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.GPIOExp,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.GPIOExp.displayName="proto.Conf.GPIOExp"),proto.Conf.WS2812=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.WS2812,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.WS2812.displayName="proto.Conf.WS2812"),proto.Conf.LEDStrip=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.LEDStrip,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.LEDStrip.displayName="proto.Conf.LEDStrip"),proto.Conf.Rotary=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.Rotary,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.Rotary.displayName="proto.Conf.Rotary"),proto.Conf.ButtonActions=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.ButtonActions,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.ButtonActions.displayName="proto.Conf.ButtonActions"),proto.Conf.Button=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.Button,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.Button.displayName="proto.Conf.Button"),proto.Conf.EthCommon=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.EthCommon,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.EthCommon.displayName="proto.Conf.EthCommon"),proto.Conf.EthSPI=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.EthSPI,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.EthSPI.displayName="proto.Conf.EthSPI"),proto.Conf.EthRMII=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.EthRMII,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.EthRMII.displayName="proto.Conf.EthRMII"),proto.Conf.Eth=function(e){r.Message.initialize(this,e,0,-1,null,proto.Conf.Eth.oneofGroups_)},n.inherits(proto.Conf.Eth,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.Eth.displayName="proto.Conf.Eth"),proto.Conf.Battery=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.Battery,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.Battery.displayName="proto.Conf.Battery"),proto.Conf.Gpios=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.Gpios,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.Gpios.displayName="proto.Conf.Gpios"),proto.Conf.Dev=function(e){r.Message.initialize(this,e,0,-1,proto.Conf.Dev.repeatedFields_,null)},n.inherits(proto.Conf.Dev,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.Dev.displayName="proto.Conf.Dev"),proto.Conf.SleepService=function(e){r.Message.initialize(this,e,0,-1,proto.Conf.SleepService.repeatedFields_,null)},n.inherits(proto.Conf.SleepService,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.SleepService.displayName="proto.Conf.SleepService"),proto.Conf.Artwork=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.Artwork,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.Artwork.displayName="proto.Conf.Artwork"),proto.Conf.Metadata=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.Metadata,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.Metadata.displayName="proto.Conf.Metadata"),proto.Conf.Services=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.Services,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.Services.displayName="proto.Conf.Services"),proto.Conf.Config=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.Conf.Config,r.Message),n.DEBUG&&!COMPILED&&(proto.Conf.Config.displayName="proto.Conf.Config"),r.Message.GENERATE_TO_OBJECT&&(proto.Conf.GPIO.prototype.toObject=function(e){return proto.Conf.GPIO.toObject(e,this)},proto.Conf.GPIO.toObject=function(e,t){var o={pin:r.Message.getFieldWithDefault(t,1,0),level:r.Message.getFieldWithDefault(t,2,0)};return e&&(o.$jspbMessageInstance=t),o}),proto.Conf.GPIO.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.GPIO;return proto.Conf.GPIO.deserializeBinaryFromReader(o,t)},proto.Conf.GPIO.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readInt32();e.setPin(o);break;case 2:o=t.readInt32();e.setLevel(o);break;default:t.skipField()}}return e},proto.Conf.GPIO.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.GPIO.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.GPIO.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getPin())&&t.writeInt32(1,o),null!=(o=r.Message.getField(e,2))&&t.writeInt32(2,o)},proto.Conf.GPIO.prototype.getPin=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.GPIO.prototype.setPin=function(e){return r.Message.setProto3IntField(this,1,e)},proto.Conf.GPIO.prototype.getLevel=function(){return r.Message.getFieldWithDefault(this,2,0)},proto.Conf.GPIO.prototype.setLevel=function(e){return r.Message.setField(this,2,e)},proto.Conf.GPIO.prototype.clearLevel=function(){return r.Message.setField(this,2,void 0)},proto.Conf.GPIO.prototype.hasLevel=function(){return null!=r.Message.getField(this,2)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.I2CBus.prototype.toObject=function(e){return proto.Conf.I2CBus.toObject(e,this)},proto.Conf.I2CBus.toObject=function(e,t){var o,n={port:r.Message.getFieldWithDefault(t,1,0),speed:r.Message.getFieldWithDefault(t,2,0),sda:(o=t.getSda())&&proto.Conf.GPIO.toObject(e,o),scl:(o=t.getScl())&&proto.Conf.GPIO.toObject(e,o)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.I2CBus.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.I2CBus;return proto.Conf.I2CBus.deserializeBinaryFromReader(o,t)},proto.Conf.I2CBus.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readEnum();e.setPort(o);break;case 2:o=t.readInt32();e.setSpeed(o);break;case 3:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setSda(o);break;case 4:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setScl(o);break;default:t.skipField()}}return e},proto.Conf.I2CBus.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.I2CBus.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.I2CBus.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getPort())&&t.writeEnum(1,o),0!==(o=e.getSpeed())&&t.writeInt32(2,o),null!=(o=e.getSda())&&t.writeMessage(3,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getScl())&&t.writeMessage(4,o,proto.Conf.GPIO.serializeBinaryToWriter)},proto.Conf.I2CBus.prototype.getPort=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.I2CBus.prototype.setPort=function(e){return r.Message.setProto3EnumField(this,1,e)},proto.Conf.I2CBus.prototype.getSpeed=function(){return r.Message.getFieldWithDefault(this,2,0)},proto.Conf.I2CBus.prototype.setSpeed=function(e){return r.Message.setProto3IntField(this,2,e)},proto.Conf.I2CBus.prototype.getSda=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,3)},proto.Conf.I2CBus.prototype.setSda=function(e){return r.Message.setWrapperField(this,3,e)},proto.Conf.I2CBus.prototype.clearSda=function(){return this.setSda(void 0)},proto.Conf.I2CBus.prototype.hasSda=function(){return null!=r.Message.getField(this,3)},proto.Conf.I2CBus.prototype.getScl=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,4)},proto.Conf.I2CBus.prototype.setScl=function(e){return r.Message.setWrapperField(this,4,e)},proto.Conf.I2CBus.prototype.clearScl=function(){return this.setScl(void 0)},proto.Conf.I2CBus.prototype.hasScl=function(){return null!=r.Message.getField(this,4)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.DACDev.prototype.toObject=function(e){return proto.Conf.DACDev.toObject(e,this)},proto.Conf.DACDev.toObject=function(e,t){var o,n={bck:(o=t.getBck())&&proto.Conf.GPIO.toObject(e,o),ws:(o=t.getWs())&&proto.Conf.GPIO.toObject(e,o),dout:(o=t.getDout())&&proto.Conf.GPIO.toObject(e,o),mck:r.Message.getFieldWithDefault(t,4,0),mute:(o=t.getMute())&&proto.Conf.GPIO.toObject(e,o),model:r.Message.getFieldWithDefault(t,6,0),i2c:(o=t.getI2c())&&proto.Conf.I2CBus.toObject(e,o)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.DACDev.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.DACDev;return proto.Conf.DACDev.deserializeBinaryFromReader(o,t)},proto.Conf.DACDev.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setBck(o);break;case 2:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setWs(o);break;case 3:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setDout(o);break;case 4:o=t.readEnum();e.setMck(o);break;case 5:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setMute(o);break;case 6:o=t.readEnum();e.setModel(o);break;case 7:o=new proto.Conf.I2CBus;t.readMessage(o,proto.Conf.I2CBus.deserializeBinaryFromReader),e.setI2c(o);break;default:t.skipField()}}return e},proto.Conf.DACDev.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.DACDev.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.DACDev.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getBck())&&t.writeMessage(1,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getWs())&&t.writeMessage(2,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getDout())&&t.writeMessage(3,o,proto.Conf.GPIO.serializeBinaryToWriter),0!==(o=e.getMck())&&t.writeEnum(4,o),null!=(o=e.getMute())&&t.writeMessage(5,o,proto.Conf.GPIO.serializeBinaryToWriter),0!==(o=e.getModel())&&t.writeEnum(6,o),null!=(o=e.getI2c())&&t.writeMessage(7,o,proto.Conf.I2CBus.serializeBinaryToWriter)},proto.Conf.DACDev.prototype.getBck=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,1)},proto.Conf.DACDev.prototype.setBck=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.DACDev.prototype.clearBck=function(){return this.setBck(void 0)},proto.Conf.DACDev.prototype.hasBck=function(){return null!=r.Message.getField(this,1)},proto.Conf.DACDev.prototype.getWs=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,2)},proto.Conf.DACDev.prototype.setWs=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.DACDev.prototype.clearWs=function(){return this.setWs(void 0)},proto.Conf.DACDev.prototype.hasWs=function(){return null!=r.Message.getField(this,2)},proto.Conf.DACDev.prototype.getDout=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,3)},proto.Conf.DACDev.prototype.setDout=function(e){return r.Message.setWrapperField(this,3,e)},proto.Conf.DACDev.prototype.clearDout=function(){return this.setDout(void 0)},proto.Conf.DACDev.prototype.hasDout=function(){return null!=r.Message.getField(this,3)},proto.Conf.DACDev.prototype.getMck=function(){return r.Message.getFieldWithDefault(this,4,0)},proto.Conf.DACDev.prototype.setMck=function(e){return r.Message.setProto3EnumField(this,4,e)},proto.Conf.DACDev.prototype.getMute=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,5)},proto.Conf.DACDev.prototype.setMute=function(e){return r.Message.setWrapperField(this,5,e)},proto.Conf.DACDev.prototype.clearMute=function(){return this.setMute(void 0)},proto.Conf.DACDev.prototype.hasMute=function(){return null!=r.Message.getField(this,5)},proto.Conf.DACDev.prototype.getModel=function(){return r.Message.getFieldWithDefault(this,6,0)},proto.Conf.DACDev.prototype.setModel=function(e){return r.Message.setProto3EnumField(this,6,e)},proto.Conf.DACDev.prototype.getI2c=function(){return r.Message.getWrapperField(this,proto.Conf.I2CBus,7)},proto.Conf.DACDev.prototype.setI2c=function(e){return r.Message.setWrapperField(this,7,e)},proto.Conf.DACDev.prototype.clearI2c=function(){return this.setI2c(void 0)},proto.Conf.DACDev.prototype.hasI2c=function(){return null!=r.Message.getField(this,7)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.SPDIFDev.prototype.toObject=function(e){return proto.Conf.SPDIFDev.toObject(e,this)},proto.Conf.SPDIFDev.toObject=function(e,t){var o,r={dc:(o=t.getDc())&&proto.Conf.GPIO.toObject(e,o),data:(o=t.getData())&&proto.Conf.GPIO.toObject(e,o),clk:(o=t.getClk())&&proto.Conf.GPIO.toObject(e,o)};return e&&(r.$jspbMessageInstance=t),r}),proto.Conf.SPDIFDev.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.SPDIFDev;return proto.Conf.SPDIFDev.deserializeBinaryFromReader(o,t)},proto.Conf.SPDIFDev.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setDc(o);break;case 2:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setData(o);break;case 3:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setClk(o);break;default:t.skipField()}}return e},proto.Conf.SPDIFDev.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.SPDIFDev.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.SPDIFDev.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getDc())&&t.writeMessage(1,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getData())&&t.writeMessage(2,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getClk())&&t.writeMessage(3,o,proto.Conf.GPIO.serializeBinaryToWriter)},proto.Conf.SPDIFDev.prototype.getDc=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,1)},proto.Conf.SPDIFDev.prototype.setDc=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.SPDIFDev.prototype.clearDc=function(){return this.setDc(void 0)},proto.Conf.SPDIFDev.prototype.hasDc=function(){return null!=r.Message.getField(this,1)},proto.Conf.SPDIFDev.prototype.getData=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,2)},proto.Conf.SPDIFDev.prototype.setData=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.SPDIFDev.prototype.clearData=function(){return this.setData(void 0)},proto.Conf.SPDIFDev.prototype.hasData=function(){return null!=r.Message.getField(this,2)},proto.Conf.SPDIFDev.prototype.getClk=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,3)},proto.Conf.SPDIFDev.prototype.setClk=function(e){return r.Message.setWrapperField(this,3,e)},proto.Conf.SPDIFDev.prototype.clearClk=function(){return this.setClk(void 0)},proto.Conf.SPDIFDev.prototype.hasClk=function(){return null!=r.Message.getField(this,3)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.DispOffsets.prototype.toObject=function(e){return proto.Conf.DispOffsets.toObject(e,this)},proto.Conf.DispOffsets.toObject=function(e,t){var o={height:r.Message.getFieldWithDefault(t,1,0),width:r.Message.getFieldWithDefault(t,2,0)};return e&&(o.$jspbMessageInstance=t),o}),proto.Conf.DispOffsets.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.DispOffsets;return proto.Conf.DispOffsets.deserializeBinaryFromReader(o,t)},proto.Conf.DispOffsets.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readInt32();e.setHeight(o);break;case 2:o=t.readInt32();e.setWidth(o);break;default:t.skipField()}}return e},proto.Conf.DispOffsets.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.DispOffsets.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.DispOffsets.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getHeight())&&t.writeInt32(1,o),0!==(o=e.getWidth())&&t.writeInt32(2,o)},proto.Conf.DispOffsets.prototype.getHeight=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.DispOffsets.prototype.setHeight=function(e){return r.Message.setProto3IntField(this,1,e)},proto.Conf.DispOffsets.prototype.getWidth=function(){return r.Message.getFieldWithDefault(this,2,0)},proto.Conf.DispOffsets.prototype.setWidth=function(e){return r.Message.setProto3IntField(this,2,e)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.DispCommon.prototype.toObject=function(e){return proto.Conf.DispCommon.toObject(e,this)},proto.Conf.DispCommon.toObject=function(e,t){var o,n={width:r.Message.getFieldWithDefault(t,1,0),height:r.Message.getFieldWithDefault(t,2,0),hflip:r.Message.getBooleanFieldWithDefault(t,3,!1),vflip:r.Message.getBooleanFieldWithDefault(t,4,!1),driver:r.Message.getFieldWithDefault(t,5,0),bitdepth:r.Message.getFieldWithDefault(t,6,0),back:(o=t.getBack())&&proto.Conf.GPIO.toObject(e,o),reset:(o=t.getReset())&&proto.Conf.GPIO.toObject(e,o),ready:(o=t.getReady())&&proto.Conf.GPIO.toObject(e,o),offsets:(o=t.getOffsets())&&proto.Conf.DispOffsets.toObject(e,o)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.DispCommon.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.DispCommon;return proto.Conf.DispCommon.deserializeBinaryFromReader(o,t)},proto.Conf.DispCommon.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readInt32();e.setWidth(o);break;case 2:o=t.readInt32();e.setHeight(o);break;case 3:o=t.readBool();e.setHflip(o);break;case 4:o=t.readBool();e.setVflip(o);break;case 5:o=t.readEnum();e.setDriver(o);break;case 6:o=t.readInt32();e.setBitdepth(o);break;case 7:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setBack(o);break;case 8:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setReset(o);break;case 9:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setReady(o);break;case 10:o=new proto.Conf.DispOffsets;t.readMessage(o,proto.Conf.DispOffsets.deserializeBinaryFromReader),e.setOffsets(o);break;default:t.skipField()}}return e},proto.Conf.DispCommon.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.DispCommon.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.DispCommon.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getWidth())&&t.writeInt32(1,o),0!==(o=e.getHeight())&&t.writeInt32(2,o),(o=e.getHflip())&&t.writeBool(3,o),(o=e.getVflip())&&t.writeBool(4,o),0!==(o=e.getDriver())&&t.writeEnum(5,o),0!==(o=e.getBitdepth())&&t.writeInt32(6,o),null!=(o=e.getBack())&&t.writeMessage(7,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getReset())&&t.writeMessage(8,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getReady())&&t.writeMessage(9,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getOffsets())&&t.writeMessage(10,o,proto.Conf.DispOffsets.serializeBinaryToWriter)},proto.Conf.DispCommon.prototype.getWidth=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.DispCommon.prototype.setWidth=function(e){return r.Message.setProto3IntField(this,1,e)},proto.Conf.DispCommon.prototype.getHeight=function(){return r.Message.getFieldWithDefault(this,2,0)},proto.Conf.DispCommon.prototype.setHeight=function(e){return r.Message.setProto3IntField(this,2,e)},proto.Conf.DispCommon.prototype.getHflip=function(){return r.Message.getBooleanFieldWithDefault(this,3,!1)},proto.Conf.DispCommon.prototype.setHflip=function(e){return r.Message.setProto3BooleanField(this,3,e)},proto.Conf.DispCommon.prototype.getVflip=function(){return r.Message.getBooleanFieldWithDefault(this,4,!1)},proto.Conf.DispCommon.prototype.setVflip=function(e){return r.Message.setProto3BooleanField(this,4,e)},proto.Conf.DispCommon.prototype.getDriver=function(){return r.Message.getFieldWithDefault(this,5,0)},proto.Conf.DispCommon.prototype.setDriver=function(e){return r.Message.setProto3EnumField(this,5,e)},proto.Conf.DispCommon.prototype.getBitdepth=function(){return r.Message.getFieldWithDefault(this,6,0)},proto.Conf.DispCommon.prototype.setBitdepth=function(e){return r.Message.setProto3IntField(this,6,e)},proto.Conf.DispCommon.prototype.getBack=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,7)},proto.Conf.DispCommon.prototype.setBack=function(e){return r.Message.setWrapperField(this,7,e)},proto.Conf.DispCommon.prototype.clearBack=function(){return this.setBack(void 0)},proto.Conf.DispCommon.prototype.hasBack=function(){return null!=r.Message.getField(this,7)},proto.Conf.DispCommon.prototype.getReset=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,8)},proto.Conf.DispCommon.prototype.setReset=function(e){return r.Message.setWrapperField(this,8,e)},proto.Conf.DispCommon.prototype.clearReset=function(){return this.setReset(void 0)},proto.Conf.DispCommon.prototype.hasReset=function(){return null!=r.Message.getField(this,8)},proto.Conf.DispCommon.prototype.getReady=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,9)},proto.Conf.DispCommon.prototype.setReady=function(e){return r.Message.setWrapperField(this,9,e)},proto.Conf.DispCommon.prototype.clearReady=function(){return this.setReady(void 0)},proto.Conf.DispCommon.prototype.hasReady=function(){return null!=r.Message.getField(this,9)},proto.Conf.DispCommon.prototype.getOffsets=function(){return r.Message.getWrapperField(this,proto.Conf.DispOffsets,10)},proto.Conf.DispCommon.prototype.setOffsets=function(e){return r.Message.setWrapperField(this,10,e)},proto.Conf.DispCommon.prototype.clearOffsets=function(){return this.setOffsets(void 0)},proto.Conf.DispCommon.prototype.hasOffsets=function(){return null!=r.Message.getField(this,10)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.I2CDisplay.prototype.toObject=function(e){return proto.Conf.I2CDisplay.toObject(e,this)},proto.Conf.I2CDisplay.toObject=function(e,t){var o={address:r.Message.getFieldWithDefault(t,1,0)};return e&&(o.$jspbMessageInstance=t),o}),proto.Conf.I2CDisplay.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.I2CDisplay;return proto.Conf.I2CDisplay.deserializeBinaryFromReader(o,t)},proto.Conf.I2CDisplay.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){if(1===t.getFieldNumber()){var o=t.readInt32();e.setAddress(o)}else t.skipField()}return e},proto.Conf.I2CDisplay.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.I2CDisplay.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.I2CDisplay.serializeBinaryToWriter=function(e,t){var o;0!==(o=e.getAddress())&&t.writeInt32(1,o)},proto.Conf.I2CDisplay.prototype.getAddress=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.I2CDisplay.prototype.setAddress=function(e){return r.Message.setProto3IntField(this,1,e)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.SPIDisplay.prototype.toObject=function(e){return proto.Conf.SPIDisplay.toObject(e,this)},proto.Conf.SPIDisplay.toObject=function(e,t){var o,n={cs:(o=t.getCs())&&proto.Conf.GPIO.toObject(e,o),speed:r.Message.getFieldWithDefault(t,4,0),rotate:r.Message.getBooleanFieldWithDefault(t,5,!1)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.SPIDisplay.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.SPIDisplay;return proto.Conf.SPIDisplay.deserializeBinaryFromReader(o,t)},proto.Conf.SPIDisplay.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setCs(o);break;case 4:o=t.readInt32();e.setSpeed(o);break;case 5:o=t.readBool();e.setRotate(o);break;default:t.skipField()}}return e},proto.Conf.SPIDisplay.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.SPIDisplay.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.SPIDisplay.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getCs())&&t.writeMessage(1,o,proto.Conf.GPIO.serializeBinaryToWriter),0!==(o=e.getSpeed())&&t.writeInt32(4,o),(o=e.getRotate())&&t.writeBool(5,o)},proto.Conf.SPIDisplay.prototype.getCs=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,1)},proto.Conf.SPIDisplay.prototype.setCs=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.SPIDisplay.prototype.clearCs=function(){return this.setCs(void 0)},proto.Conf.SPIDisplay.prototype.hasCs=function(){return null!=r.Message.getField(this,1)},proto.Conf.SPIDisplay.prototype.getSpeed=function(){return r.Message.getFieldWithDefault(this,4,0)},proto.Conf.SPIDisplay.prototype.setSpeed=function(e){return r.Message.setProto3IntField(this,4,e)},proto.Conf.SPIDisplay.prototype.getRotate=function(){return r.Message.getBooleanFieldWithDefault(this,5,!1)},proto.Conf.SPIDisplay.prototype.setRotate=function(e){return r.Message.setProto3BooleanField(this,5,e)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.SPIBus.prototype.toObject=function(e){return proto.Conf.SPIBus.toObject(e,this)},proto.Conf.SPIBus.toObject=function(e,t){var o,n={mosi:(o=t.getMosi())&&proto.Conf.GPIO.toObject(e,o),miso:(o=t.getMiso())&&proto.Conf.GPIO.toObject(e,o),clk:(o=t.getClk())&&proto.Conf.GPIO.toObject(e,o),dc:(o=t.getDc())&&proto.Conf.GPIO.toObject(e,o),host:r.Message.getFieldWithDefault(t,5,0)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.SPIBus.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.SPIBus;return proto.Conf.SPIBus.deserializeBinaryFromReader(o,t)},proto.Conf.SPIBus.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setMosi(o);break;case 2:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setMiso(o);break;case 3:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setClk(o);break;case 4:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setDc(o);break;case 5:o=t.readEnum();e.setHost(o);break;default:t.skipField()}}return e},proto.Conf.SPIBus.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.SPIBus.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.SPIBus.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getMosi())&&t.writeMessage(1,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getMiso())&&t.writeMessage(2,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getClk())&&t.writeMessage(3,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getDc())&&t.writeMessage(4,o,proto.Conf.GPIO.serializeBinaryToWriter),0!==(o=e.getHost())&&t.writeEnum(5,o)},proto.Conf.SPIBus.prototype.getMosi=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,1)},proto.Conf.SPIBus.prototype.setMosi=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.SPIBus.prototype.clearMosi=function(){return this.setMosi(void 0)},proto.Conf.SPIBus.prototype.hasMosi=function(){return null!=r.Message.getField(this,1)},proto.Conf.SPIBus.prototype.getMiso=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,2)},proto.Conf.SPIBus.prototype.setMiso=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.SPIBus.prototype.clearMiso=function(){return this.setMiso(void 0)},proto.Conf.SPIBus.prototype.hasMiso=function(){return null!=r.Message.getField(this,2)},proto.Conf.SPIBus.prototype.getClk=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,3)},proto.Conf.SPIBus.prototype.setClk=function(e){return r.Message.setWrapperField(this,3,e)},proto.Conf.SPIBus.prototype.clearClk=function(){return this.setClk(void 0)},proto.Conf.SPIBus.prototype.hasClk=function(){return null!=r.Message.getField(this,3)},proto.Conf.SPIBus.prototype.getDc=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,4)},proto.Conf.SPIBus.prototype.setDc=function(e){return r.Message.setWrapperField(this,4,e)},proto.Conf.SPIBus.prototype.clearDc=function(){return this.setDc(void 0)},proto.Conf.SPIBus.prototype.hasDc=function(){return null!=r.Message.getField(this,4)},proto.Conf.SPIBus.prototype.getHost=function(){return r.Message.getFieldWithDefault(this,5,0)},proto.Conf.SPIBus.prototype.setHost=function(e){return r.Message.setProto3EnumField(this,5,e)},proto.Conf.DisplayDev.oneofGroups_=[[3,4]],proto.Conf.DisplayDev.DisptypeCase={DISPTYPE_NOT_SET:0,I2C:3,SPI:4},proto.Conf.DisplayDev.prototype.getDisptypeCase=function(){return r.Message.computeOneofCase(this,proto.Conf.DisplayDev.oneofGroups_[0])},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.DisplayDev.prototype.toObject=function(e){return proto.Conf.DisplayDev.toObject(e,this)},proto.Conf.DisplayDev.toObject=function(e,t){var o,n={type:r.Message.getFieldWithDefault(t,1,0),common:(o=t.getCommon())&&proto.Conf.DispCommon.toObject(e,o),i2c:(o=t.getI2c())&&proto.Conf.I2CDisplay.toObject(e,o),spi:(o=t.getSpi())&&proto.Conf.SPIDisplay.toObject(e,o)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.DisplayDev.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.DisplayDev;return proto.Conf.DisplayDev.deserializeBinaryFromReader(o,t)},proto.Conf.DisplayDev.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readEnum();e.setType(o);break;case 2:o=new proto.Conf.DispCommon;t.readMessage(o,proto.Conf.DispCommon.deserializeBinaryFromReader),e.setCommon(o);break;case 3:o=new proto.Conf.I2CDisplay;t.readMessage(o,proto.Conf.I2CDisplay.deserializeBinaryFromReader),e.setI2c(o);break;case 4:o=new proto.Conf.SPIDisplay;t.readMessage(o,proto.Conf.SPIDisplay.deserializeBinaryFromReader),e.setSpi(o);break;default:t.skipField()}}return e},proto.Conf.DisplayDev.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.DisplayDev.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.DisplayDev.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getType())&&t.writeEnum(1,o),null!=(o=e.getCommon())&&t.writeMessage(2,o,proto.Conf.DispCommon.serializeBinaryToWriter),null!=(o=e.getI2c())&&t.writeMessage(3,o,proto.Conf.I2CDisplay.serializeBinaryToWriter),null!=(o=e.getSpi())&&t.writeMessage(4,o,proto.Conf.SPIDisplay.serializeBinaryToWriter)},proto.Conf.DisplayDev.prototype.getType=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.DisplayDev.prototype.setType=function(e){return r.Message.setProto3EnumField(this,1,e)},proto.Conf.DisplayDev.prototype.getCommon=function(){return r.Message.getWrapperField(this,proto.Conf.DispCommon,2)},proto.Conf.DisplayDev.prototype.setCommon=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.DisplayDev.prototype.clearCommon=function(){return this.setCommon(void 0)},proto.Conf.DisplayDev.prototype.hasCommon=function(){return null!=r.Message.getField(this,2)},proto.Conf.DisplayDev.prototype.getI2c=function(){return r.Message.getWrapperField(this,proto.Conf.I2CDisplay,3)},proto.Conf.DisplayDev.prototype.setI2c=function(e){return r.Message.setOneofWrapperField(this,3,proto.Conf.DisplayDev.oneofGroups_[0],e)},proto.Conf.DisplayDev.prototype.clearI2c=function(){return this.setI2c(void 0)},proto.Conf.DisplayDev.prototype.hasI2c=function(){return null!=r.Message.getField(this,3)},proto.Conf.DisplayDev.prototype.getSpi=function(){return r.Message.getWrapperField(this,proto.Conf.SPIDisplay,4)},proto.Conf.DisplayDev.prototype.setSpi=function(e){return r.Message.setOneofWrapperField(this,4,proto.Conf.DisplayDev.oneofGroups_[0],e)},proto.Conf.DisplayDev.prototype.clearSpi=function(){return this.setSpi(void 0)},proto.Conf.DisplayDev.prototype.hasSpi=function(){return null!=r.Message.getField(this,4)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.GPIOExp.prototype.toObject=function(e){return proto.Conf.GPIOExp.toObject(e,this)},proto.Conf.GPIOExp.toObject=function(e,t){var o,n={model:r.Message.getFieldWithDefault(t,1,0),addr:r.Message.getFieldWithDefault(t,2,0),port:r.Message.getFieldWithDefault(t,3,0),base:r.Message.getFieldWithDefault(t,4,0),count:r.Message.getFieldWithDefault(t,5,0),intr:(o=t.getIntr())&&proto.Conf.GPIO.toObject(e,o),cs:(o=t.getCs())&&proto.Conf.GPIO.toObject(e,o),speed:r.Message.getFieldWithDefault(t,8,0)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.GPIOExp.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.GPIOExp;return proto.Conf.GPIOExp.deserializeBinaryFromReader(o,t)},proto.Conf.GPIOExp.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readEnum();e.setModel(o);break;case 2:o=t.readInt32();e.setAddr(o);break;case 3:o=t.readEnum();e.setPort(o);break;case 4:o=t.readInt32();e.setBase(o);break;case 5:o=t.readInt32();e.setCount(o);break;case 6:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setIntr(o);break;case 7:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setCs(o);break;case 8:o=t.readInt32();e.setSpeed(o);break;default:t.skipField()}}return e},proto.Conf.GPIOExp.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.GPIOExp.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.GPIOExp.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getModel())&&t.writeEnum(1,o),0!==(o=e.getAddr())&&t.writeInt32(2,o),0!==(o=e.getPort())&&t.writeEnum(3,o),0!==(o=e.getBase())&&t.writeInt32(4,o),0!==(o=e.getCount())&&t.writeInt32(5,o),null!=(o=e.getIntr())&&t.writeMessage(6,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getCs())&&t.writeMessage(7,o,proto.Conf.GPIO.serializeBinaryToWriter),0!==(o=e.getSpeed())&&t.writeInt32(8,o)},proto.Conf.GPIOExp.prototype.getModel=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.GPIOExp.prototype.setModel=function(e){return r.Message.setProto3EnumField(this,1,e)},proto.Conf.GPIOExp.prototype.getAddr=function(){return r.Message.getFieldWithDefault(this,2,0)},proto.Conf.GPIOExp.prototype.setAddr=function(e){return r.Message.setProto3IntField(this,2,e)},proto.Conf.GPIOExp.prototype.getPort=function(){return r.Message.getFieldWithDefault(this,3,0)},proto.Conf.GPIOExp.prototype.setPort=function(e){return r.Message.setProto3EnumField(this,3,e)},proto.Conf.GPIOExp.prototype.getBase=function(){return r.Message.getFieldWithDefault(this,4,0)},proto.Conf.GPIOExp.prototype.setBase=function(e){return r.Message.setProto3IntField(this,4,e)},proto.Conf.GPIOExp.prototype.getCount=function(){return r.Message.getFieldWithDefault(this,5,0)},proto.Conf.GPIOExp.prototype.setCount=function(e){return r.Message.setProto3IntField(this,5,e)},proto.Conf.GPIOExp.prototype.getIntr=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,6)},proto.Conf.GPIOExp.prototype.setIntr=function(e){return r.Message.setWrapperField(this,6,e)},proto.Conf.GPIOExp.prototype.clearIntr=function(){return this.setIntr(void 0)},proto.Conf.GPIOExp.prototype.hasIntr=function(){return null!=r.Message.getField(this,6)},proto.Conf.GPIOExp.prototype.getCs=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,7)},proto.Conf.GPIOExp.prototype.setCs=function(e){return r.Message.setWrapperField(this,7,e)},proto.Conf.GPIOExp.prototype.clearCs=function(){return this.setCs(void 0)},proto.Conf.GPIOExp.prototype.hasCs=function(){return null!=r.Message.getField(this,7)},proto.Conf.GPIOExp.prototype.getSpeed=function(){return r.Message.getFieldWithDefault(this,8,0)},proto.Conf.GPIOExp.prototype.setSpeed=function(e){return r.Message.setProto3IntField(this,8,e)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.WS2812.prototype.toObject=function(e){return proto.Conf.WS2812.toObject(e,this)},proto.Conf.WS2812.toObject=function(e,t){var o,n={length:r.Message.getFieldWithDefault(t,1,0),gpio:(o=t.getGpio())&&proto.Conf.GPIO.toObject(e,o)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.WS2812.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.WS2812;return proto.Conf.WS2812.deserializeBinaryFromReader(o,t)},proto.Conf.WS2812.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readInt32();e.setLength(o);break;case 2:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setGpio(o);break;default:t.skipField()}}return e},proto.Conf.WS2812.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.WS2812.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.WS2812.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getLength())&&t.writeInt32(1,o),null!=(o=e.getGpio())&&t.writeMessage(2,o,proto.Conf.GPIO.serializeBinaryToWriter)},proto.Conf.WS2812.prototype.getLength=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.WS2812.prototype.setLength=function(e){return r.Message.setProto3IntField(this,1,e)},proto.Conf.WS2812.prototype.getGpio=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,2)},proto.Conf.WS2812.prototype.setGpio=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.WS2812.prototype.clearGpio=function(){return this.setGpio(void 0)},proto.Conf.WS2812.prototype.hasGpio=function(){return null!=r.Message.getField(this,2)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.LEDStrip.prototype.toObject=function(e){return proto.Conf.LEDStrip.toObject(e,this)},proto.Conf.LEDStrip.toObject=function(e,t){var o,r={ws2812:(o=t.getWs2812())&&proto.Conf.WS2812.toObject(e,o)};return e&&(r.$jspbMessageInstance=t),r}),proto.Conf.LEDStrip.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.LEDStrip;return proto.Conf.LEDStrip.deserializeBinaryFromReader(o,t)},proto.Conf.LEDStrip.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){if(1===t.getFieldNumber()){var o=new proto.Conf.WS2812;t.readMessage(o,proto.Conf.WS2812.deserializeBinaryFromReader),e.setWs2812(o)}else t.skipField()}return e},proto.Conf.LEDStrip.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.LEDStrip.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.LEDStrip.serializeBinaryToWriter=function(e,t){var o;null!=(o=e.getWs2812())&&t.writeMessage(1,o,proto.Conf.WS2812.serializeBinaryToWriter)},proto.Conf.LEDStrip.prototype.getWs2812=function(){return r.Message.getWrapperField(this,proto.Conf.WS2812,1)},proto.Conf.LEDStrip.prototype.setWs2812=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.LEDStrip.prototype.clearWs2812=function(){return this.setWs2812(void 0)},proto.Conf.LEDStrip.prototype.hasWs2812=function(){return null!=r.Message.getField(this,1)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.Rotary.prototype.toObject=function(e){return proto.Conf.Rotary.toObject(e,this)},proto.Conf.Rotary.toObject=function(e,t){var o,n={a:(o=t.getA())&&proto.Conf.GPIO.toObject(e,o),b:(o=t.getB())&&proto.Conf.GPIO.toObject(e,o),sw:(o=t.getSw())&&proto.Conf.GPIO.toObject(e,o),knobonly:r.Message.getFieldWithDefault(t,4,0),volume:r.Message.getBooleanFieldWithDefault(t,5,!1),longpress:r.Message.getBooleanFieldWithDefault(t,6,!1)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.Rotary.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.Rotary;return proto.Conf.Rotary.deserializeBinaryFromReader(o,t)},proto.Conf.Rotary.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setA(o);break;case 2:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setB(o);break;case 3:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setSw(o);break;case 4:o=t.readInt32();e.setKnobonly(o);break;case 5:o=t.readBool();e.setVolume(o);break;case 6:o=t.readBool();e.setLongpress(o);break;default:t.skipField()}}return e},proto.Conf.Rotary.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.Rotary.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.Rotary.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getA())&&t.writeMessage(1,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getB())&&t.writeMessage(2,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getSw())&&t.writeMessage(3,o,proto.Conf.GPIO.serializeBinaryToWriter),0!==(o=e.getKnobonly())&&t.writeInt32(4,o),(o=e.getVolume())&&t.writeBool(5,o),(o=e.getLongpress())&&t.writeBool(6,o)},proto.Conf.Rotary.prototype.getA=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,1)},proto.Conf.Rotary.prototype.setA=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.Rotary.prototype.clearA=function(){return this.setA(void 0)},proto.Conf.Rotary.prototype.hasA=function(){return null!=r.Message.getField(this,1)},proto.Conf.Rotary.prototype.getB=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,2)},proto.Conf.Rotary.prototype.setB=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.Rotary.prototype.clearB=function(){return this.setB(void 0)},proto.Conf.Rotary.prototype.hasB=function(){return null!=r.Message.getField(this,2)},proto.Conf.Rotary.prototype.getSw=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,3)},proto.Conf.Rotary.prototype.setSw=function(e){return r.Message.setWrapperField(this,3,e)},proto.Conf.Rotary.prototype.clearSw=function(){return this.setSw(void 0)},proto.Conf.Rotary.prototype.hasSw=function(){return null!=r.Message.getField(this,3)},proto.Conf.Rotary.prototype.getKnobonly=function(){return r.Message.getFieldWithDefault(this,4,0)},proto.Conf.Rotary.prototype.setKnobonly=function(e){return r.Message.setProto3IntField(this,4,e)},proto.Conf.Rotary.prototype.getVolume=function(){return r.Message.getBooleanFieldWithDefault(this,5,!1)},proto.Conf.Rotary.prototype.setVolume=function(e){return r.Message.setProto3BooleanField(this,5,e)},proto.Conf.Rotary.prototype.getLongpress=function(){return r.Message.getBooleanFieldWithDefault(this,6,!1)},proto.Conf.Rotary.prototype.setLongpress=function(e){return r.Message.setProto3BooleanField(this,6,e)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.ButtonActions.prototype.toObject=function(e){return proto.Conf.ButtonActions.toObject(e,this)},proto.Conf.ButtonActions.toObject=function(e,t){var o={pressed:r.Message.getFieldWithDefault(t,1,0),released:r.Message.getFieldWithDefault(t,2,0)};return e&&(o.$jspbMessageInstance=t),o}),proto.Conf.ButtonActions.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.ButtonActions;return proto.Conf.ButtonActions.deserializeBinaryFromReader(o,t)},proto.Conf.ButtonActions.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readEnum();e.setPressed(o);break;case 2:o=t.readEnum();e.setReleased(o);break;default:t.skipField()}}return e},proto.Conf.ButtonActions.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.ButtonActions.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.ButtonActions.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getPressed())&&t.writeEnum(1,o),0!==(o=e.getReleased())&&t.writeEnum(2,o)},proto.Conf.ButtonActions.prototype.getPressed=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.ButtonActions.prototype.setPressed=function(e){return r.Message.setProto3EnumField(this,1,e)},proto.Conf.ButtonActions.prototype.getReleased=function(){return r.Message.getFieldWithDefault(this,2,0)},proto.Conf.ButtonActions.prototype.setReleased=function(e){return r.Message.setProto3EnumField(this,2,e)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.Button.prototype.toObject=function(e){return proto.Conf.Button.toObject(e,this)},proto.Conf.Button.toObject=function(e,t){var o,n={gpio:(o=t.getGpio())&&proto.Conf.GPIO.toObject(e,o),pull:r.Message.getBooleanFieldWithDefault(t,2,!1),debounce:r.Message.getFieldWithDefault(t,3,0),shifter:(o=t.getShifter())&&proto.Conf.GPIO.toObject(e,o),longduration:r.Message.getFieldWithDefault(t,5,0),normal:(o=t.getNormal())&&proto.Conf.ButtonActions.toObject(e,o),longpress:(o=t.getLongpress())&&proto.Conf.ButtonActions.toObject(e,o),shifted:(o=t.getShifted())&&proto.Conf.ButtonActions.toObject(e,o),longshifted:(o=t.getLongshifted())&&proto.Conf.ButtonActions.toObject(e,o)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.Button.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.Button;return proto.Conf.Button.deserializeBinaryFromReader(o,t)},proto.Conf.Button.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setGpio(o);break;case 2:o=t.readBool();e.setPull(o);break;case 3:o=t.readInt32();e.setDebounce(o);break;case 4:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setShifter(o);break;case 5:o=t.readInt32();e.setLongduration(o);break;case 6:o=new proto.Conf.ButtonActions;t.readMessage(o,proto.Conf.ButtonActions.deserializeBinaryFromReader),e.setNormal(o);break;case 7:o=new proto.Conf.ButtonActions;t.readMessage(o,proto.Conf.ButtonActions.deserializeBinaryFromReader),e.setLongpress(o);break;case 8:o=new proto.Conf.ButtonActions;t.readMessage(o,proto.Conf.ButtonActions.deserializeBinaryFromReader),e.setShifted(o);break;case 9:o=new proto.Conf.ButtonActions;t.readMessage(o,proto.Conf.ButtonActions.deserializeBinaryFromReader),e.setLongshifted(o);break;default:t.skipField()}}return e},proto.Conf.Button.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.Button.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.Button.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getGpio())&&t.writeMessage(1,o,proto.Conf.GPIO.serializeBinaryToWriter),(o=e.getPull())&&t.writeBool(2,o),0!==(o=e.getDebounce())&&t.writeInt32(3,o),null!=(o=e.getShifter())&&t.writeMessage(4,o,proto.Conf.GPIO.serializeBinaryToWriter),0!==(o=e.getLongduration())&&t.writeInt32(5,o),null!=(o=e.getNormal())&&t.writeMessage(6,o,proto.Conf.ButtonActions.serializeBinaryToWriter),null!=(o=e.getLongpress())&&t.writeMessage(7,o,proto.Conf.ButtonActions.serializeBinaryToWriter),null!=(o=e.getShifted())&&t.writeMessage(8,o,proto.Conf.ButtonActions.serializeBinaryToWriter),null!=(o=e.getLongshifted())&&t.writeMessage(9,o,proto.Conf.ButtonActions.serializeBinaryToWriter)},proto.Conf.Button.prototype.getGpio=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,1)},proto.Conf.Button.prototype.setGpio=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.Button.prototype.clearGpio=function(){return this.setGpio(void 0)},proto.Conf.Button.prototype.hasGpio=function(){return null!=r.Message.getField(this,1)},proto.Conf.Button.prototype.getPull=function(){return r.Message.getBooleanFieldWithDefault(this,2,!1)},proto.Conf.Button.prototype.setPull=function(e){return r.Message.setProto3BooleanField(this,2,e)},proto.Conf.Button.prototype.getDebounce=function(){return r.Message.getFieldWithDefault(this,3,0)},proto.Conf.Button.prototype.setDebounce=function(e){return r.Message.setProto3IntField(this,3,e)},proto.Conf.Button.prototype.getShifter=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,4)},proto.Conf.Button.prototype.setShifter=function(e){return r.Message.setWrapperField(this,4,e)},proto.Conf.Button.prototype.clearShifter=function(){return this.setShifter(void 0)},proto.Conf.Button.prototype.hasShifter=function(){return null!=r.Message.getField(this,4)},proto.Conf.Button.prototype.getLongduration=function(){return r.Message.getFieldWithDefault(this,5,0)},proto.Conf.Button.prototype.setLongduration=function(e){return r.Message.setProto3IntField(this,5,e)},proto.Conf.Button.prototype.getNormal=function(){return r.Message.getWrapperField(this,proto.Conf.ButtonActions,6)},proto.Conf.Button.prototype.setNormal=function(e){return r.Message.setWrapperField(this,6,e)},proto.Conf.Button.prototype.clearNormal=function(){return this.setNormal(void 0)},proto.Conf.Button.prototype.hasNormal=function(){return null!=r.Message.getField(this,6)},proto.Conf.Button.prototype.getLongpress=function(){return r.Message.getWrapperField(this,proto.Conf.ButtonActions,7)},proto.Conf.Button.prototype.setLongpress=function(e){return r.Message.setWrapperField(this,7,e)},proto.Conf.Button.prototype.clearLongpress=function(){return this.setLongpress(void 0)},proto.Conf.Button.prototype.hasLongpress=function(){return null!=r.Message.getField(this,7)},proto.Conf.Button.prototype.getShifted=function(){return r.Message.getWrapperField(this,proto.Conf.ButtonActions,8)},proto.Conf.Button.prototype.setShifted=function(e){return r.Message.setWrapperField(this,8,e)},proto.Conf.Button.prototype.clearShifted=function(){return this.setShifted(void 0)},proto.Conf.Button.prototype.hasShifted=function(){return null!=r.Message.getField(this,8)},proto.Conf.Button.prototype.getLongshifted=function(){return r.Message.getWrapperField(this,proto.Conf.ButtonActions,9)},proto.Conf.Button.prototype.setLongshifted=function(e){return r.Message.setWrapperField(this,9,e)},proto.Conf.Button.prototype.clearLongshifted=function(){return this.setLongshifted(void 0)},proto.Conf.Button.prototype.hasLongshifted=function(){return null!=r.Message.getField(this,9)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.EthCommon.prototype.toObject=function(e){return proto.Conf.EthCommon.toObject(e,this)},proto.Conf.EthCommon.toObject=function(e,t){var o,n={model:r.Message.getFieldWithDefault(t,1,0),rst:(o=t.getRst())&&proto.Conf.GPIO.toObject(e,o)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.EthCommon.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.EthCommon;return proto.Conf.EthCommon.deserializeBinaryFromReader(o,t)},proto.Conf.EthCommon.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readEnum();e.setModel(o);break;case 2:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setRst(o);break;default:t.skipField()}}return e},proto.Conf.EthCommon.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.EthCommon.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.EthCommon.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getModel())&&t.writeEnum(1,o),null!=(o=e.getRst())&&t.writeMessage(2,o,proto.Conf.GPIO.serializeBinaryToWriter)},proto.Conf.EthCommon.prototype.getModel=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.EthCommon.prototype.setModel=function(e){return r.Message.setProto3EnumField(this,1,e)},proto.Conf.EthCommon.prototype.getRst=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,2)},proto.Conf.EthCommon.prototype.setRst=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.EthCommon.prototype.clearRst=function(){return this.setRst(void 0)},proto.Conf.EthCommon.prototype.hasRst=function(){return null!=r.Message.getField(this,2)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.EthSPI.prototype.toObject=function(e){return proto.Conf.EthSPI.toObject(e,this)},proto.Conf.EthSPI.toObject=function(e,t){var o,n={cs:(o=t.getCs())&&proto.Conf.GPIO.toObject(e,o),speed:r.Message.getFieldWithDefault(t,2,0),intr:(o=t.getIntr())&&proto.Conf.GPIO.toObject(e,o),host:r.Message.getFieldWithDefault(t,4,0)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.EthSPI.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.EthSPI;return proto.Conf.EthSPI.deserializeBinaryFromReader(o,t)},proto.Conf.EthSPI.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setCs(o);break;case 2:o=t.readInt32();e.setSpeed(o);break;case 3:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setIntr(o);break;case 4:o=t.readInt32();e.setHost(o);break;default:t.skipField()}}return e},proto.Conf.EthSPI.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.EthSPI.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.EthSPI.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getCs())&&t.writeMessage(1,o,proto.Conf.GPIO.serializeBinaryToWriter),0!==(o=e.getSpeed())&&t.writeInt32(2,o),null!=(o=e.getIntr())&&t.writeMessage(3,o,proto.Conf.GPIO.serializeBinaryToWriter),0!==(o=e.getHost())&&t.writeInt32(4,o)},proto.Conf.EthSPI.prototype.getCs=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,1)},proto.Conf.EthSPI.prototype.setCs=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.EthSPI.prototype.clearCs=function(){return this.setCs(void 0)},proto.Conf.EthSPI.prototype.hasCs=function(){return null!=r.Message.getField(this,1)},proto.Conf.EthSPI.prototype.getSpeed=function(){return r.Message.getFieldWithDefault(this,2,0)},proto.Conf.EthSPI.prototype.setSpeed=function(e){return r.Message.setProto3IntField(this,2,e)},proto.Conf.EthSPI.prototype.getIntr=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,3)},proto.Conf.EthSPI.prototype.setIntr=function(e){return r.Message.setWrapperField(this,3,e)},proto.Conf.EthSPI.prototype.clearIntr=function(){return this.setIntr(void 0)},proto.Conf.EthSPI.prototype.hasIntr=function(){return null!=r.Message.getField(this,3)},proto.Conf.EthSPI.prototype.getHost=function(){return r.Message.getFieldWithDefault(this,4,0)},proto.Conf.EthSPI.prototype.setHost=function(e){return r.Message.setProto3IntField(this,4,e)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.EthRMII.prototype.toObject=function(e){return proto.Conf.EthRMII.toObject(e,this)},proto.Conf.EthRMII.toObject=function(e,t){var o,r={mdc:(o=t.getMdc())&&proto.Conf.GPIO.toObject(e,o),mdio:(o=t.getMdio())&&proto.Conf.GPIO.toObject(e,o)};return e&&(r.$jspbMessageInstance=t),r}),proto.Conf.EthRMII.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.EthRMII;return proto.Conf.EthRMII.deserializeBinaryFromReader(o,t)},proto.Conf.EthRMII.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setMdc(o);break;case 2:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setMdio(o);break;default:t.skipField()}}return e},proto.Conf.EthRMII.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.EthRMII.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.EthRMII.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getMdc())&&t.writeMessage(1,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getMdio())&&t.writeMessage(2,o,proto.Conf.GPIO.serializeBinaryToWriter)},proto.Conf.EthRMII.prototype.getMdc=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,1)},proto.Conf.EthRMII.prototype.setMdc=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.EthRMII.prototype.clearMdc=function(){return this.setMdc(void 0)},proto.Conf.EthRMII.prototype.hasMdc=function(){return null!=r.Message.getField(this,1)},proto.Conf.EthRMII.prototype.getMdio=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,2)},proto.Conf.EthRMII.prototype.setMdio=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.EthRMII.prototype.clearMdio=function(){return this.setMdio(void 0)},proto.Conf.EthRMII.prototype.hasMdio=function(){return null!=r.Message.getField(this,2)},proto.Conf.Eth.oneofGroups_=[[3,4]],proto.Conf.Eth.EthtypeCase={ETHTYPE_NOT_SET:0,SPI:3,RMII:4},proto.Conf.Eth.prototype.getEthtypeCase=function(){return r.Message.computeOneofCase(this,proto.Conf.Eth.oneofGroups_[0])},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.Eth.prototype.toObject=function(e){return proto.Conf.Eth.toObject(e,this)},proto.Conf.Eth.toObject=function(e,t){var o,n={type:r.Message.getFieldWithDefault(t,1,0),common:(o=t.getCommon())&&proto.Conf.EthCommon.toObject(e,o),spi:(o=t.getSpi())&&proto.Conf.EthSPI.toObject(e,o),rmii:(o=t.getRmii())&&proto.Conf.EthRMII.toObject(e,o)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.Eth.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.Eth;return proto.Conf.Eth.deserializeBinaryFromReader(o,t)},proto.Conf.Eth.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readEnum();e.setType(o);break;case 2:o=new proto.Conf.EthCommon;t.readMessage(o,proto.Conf.EthCommon.deserializeBinaryFromReader),e.setCommon(o);break;case 3:o=new proto.Conf.EthSPI;t.readMessage(o,proto.Conf.EthSPI.deserializeBinaryFromReader),e.setSpi(o);break;case 4:o=new proto.Conf.EthRMII;t.readMessage(o,proto.Conf.EthRMII.deserializeBinaryFromReader),e.setRmii(o);break;default:t.skipField()}}return e},proto.Conf.Eth.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.Eth.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.Eth.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getType())&&t.writeEnum(1,o),null!=(o=e.getCommon())&&t.writeMessage(2,o,proto.Conf.EthCommon.serializeBinaryToWriter),null!=(o=e.getSpi())&&t.writeMessage(3,o,proto.Conf.EthSPI.serializeBinaryToWriter),null!=(o=e.getRmii())&&t.writeMessage(4,o,proto.Conf.EthRMII.serializeBinaryToWriter)},proto.Conf.Eth.prototype.getType=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.Eth.prototype.setType=function(e){return r.Message.setProto3EnumField(this,1,e)},proto.Conf.Eth.prototype.getCommon=function(){return r.Message.getWrapperField(this,proto.Conf.EthCommon,2)},proto.Conf.Eth.prototype.setCommon=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.Eth.prototype.clearCommon=function(){return this.setCommon(void 0)},proto.Conf.Eth.prototype.hasCommon=function(){return null!=r.Message.getField(this,2)},proto.Conf.Eth.prototype.getSpi=function(){return r.Message.getWrapperField(this,proto.Conf.EthSPI,3)},proto.Conf.Eth.prototype.setSpi=function(e){return r.Message.setOneofWrapperField(this,3,proto.Conf.Eth.oneofGroups_[0],e)},proto.Conf.Eth.prototype.clearSpi=function(){return this.setSpi(void 0)},proto.Conf.Eth.prototype.hasSpi=function(){return null!=r.Message.getField(this,3)},proto.Conf.Eth.prototype.getRmii=function(){return r.Message.getWrapperField(this,proto.Conf.EthRMII,4)},proto.Conf.Eth.prototype.setRmii=function(e){return r.Message.setOneofWrapperField(this,4,proto.Conf.Eth.oneofGroups_[0],e)},proto.Conf.Eth.prototype.clearRmii=function(){return this.setRmii(void 0)},proto.Conf.Eth.prototype.hasRmii=function(){return null!=r.Message.getField(this,4)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.Battery.prototype.toObject=function(e){return proto.Conf.Battery.toObject(e,this)},proto.Conf.Battery.toObject=function(e,t){var o={channel:r.Message.getFieldWithDefault(t,1,0),scale:r.Message.getFloatingPointFieldWithDefault(t,2,0),cells:r.Message.getFieldWithDefault(t,3,0),atten:r.Message.getFieldWithDefault(t,4,0)};return e&&(o.$jspbMessageInstance=t),o}),proto.Conf.Battery.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.Battery;return proto.Conf.Battery.deserializeBinaryFromReader(o,t)},proto.Conf.Battery.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readEnum();e.setChannel(o);break;case 2:o=t.readFloat();e.setScale(o);break;case 3:o=t.readInt32();e.setCells(o);break;case 4:o=t.readEnum();e.setAtten(o);break;default:t.skipField()}}return e},proto.Conf.Battery.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.Battery.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.Battery.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getChannel())&&t.writeEnum(1,o),0!==(o=e.getScale())&&t.writeFloat(2,o),0!==(o=e.getCells())&&t.writeInt32(3,o),0!==(o=e.getAtten())&&t.writeEnum(4,o)},proto.Conf.Battery.prototype.getChannel=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.Battery.prototype.setChannel=function(e){return r.Message.setProto3EnumField(this,1,e)},proto.Conf.Battery.prototype.getScale=function(){return r.Message.getFloatingPointFieldWithDefault(this,2,0)},proto.Conf.Battery.prototype.setScale=function(e){return r.Message.setProto3FloatField(this,2,e)},proto.Conf.Battery.prototype.getCells=function(){return r.Message.getFieldWithDefault(this,3,0)},proto.Conf.Battery.prototype.setCells=function(e){return r.Message.setProto3IntField(this,3,e)},proto.Conf.Battery.prototype.getAtten=function(){return r.Message.getFieldWithDefault(this,4,0)},proto.Conf.Battery.prototype.setAtten=function(e){return r.Message.setProto3EnumField(this,4,e)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.Gpios.prototype.toObject=function(e){return proto.Conf.Gpios.toObject(e,this)},proto.Conf.Gpios.toObject=function(e,t){var o,r={greenled:(o=t.getGreenled())&&proto.Conf.GPIO.toObject(e,o),redled:(o=t.getRedled())&&proto.Conf.GPIO.toObject(e,o),audiojack:(o=t.getAudiojack())&&proto.Conf.GPIO.toObject(e,o),amp:(o=t.getAmp())&&proto.Conf.GPIO.toObject(e,o),power:(o=t.getPower())&&proto.Conf.GPIO.toObject(e,o),ir:(o=t.getIr())&&proto.Conf.GPIO.toObject(e,o),jack:(o=t.getJack())&&proto.Conf.GPIO.toObject(e,o),spkfault:(o=t.getSpkfault())&&proto.Conf.GPIO.toObject(e,o),vcc:(o=t.getVcc())&&proto.Conf.GPIO.toObject(e,o),gnd:(o=t.getGnd())&&proto.Conf.GPIO.toObject(e,o)};return e&&(r.$jspbMessageInstance=t),r}),proto.Conf.Gpios.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.Gpios;return proto.Conf.Gpios.deserializeBinaryFromReader(o,t)},proto.Conf.Gpios.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setGreenled(o);break;case 2:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setRedled(o);break;case 3:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setAudiojack(o);break;case 4:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setAmp(o);break;case 5:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setPower(o);break;case 6:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setIr(o);break;case 7:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setJack(o);break;case 8:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setSpkfault(o);break;case 9:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setVcc(o);break;case 10:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setGnd(o);break;default:t.skipField()}}return e},proto.Conf.Gpios.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.Gpios.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.Gpios.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getGreenled())&&t.writeMessage(1,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getRedled())&&t.writeMessage(2,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getAudiojack())&&t.writeMessage(3,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getAmp())&&t.writeMessage(4,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getPower())&&t.writeMessage(5,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getIr())&&t.writeMessage(6,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getJack())&&t.writeMessage(7,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getSpkfault())&&t.writeMessage(8,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getVcc())&&t.writeMessage(9,o,proto.Conf.GPIO.serializeBinaryToWriter),null!=(o=e.getGnd())&&t.writeMessage(10,o,proto.Conf.GPIO.serializeBinaryToWriter)},proto.Conf.Gpios.prototype.getGreenled=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,1)},proto.Conf.Gpios.prototype.setGreenled=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.Gpios.prototype.clearGreenled=function(){return this.setGreenled(void 0)},proto.Conf.Gpios.prototype.hasGreenled=function(){return null!=r.Message.getField(this,1)},proto.Conf.Gpios.prototype.getRedled=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,2)},proto.Conf.Gpios.prototype.setRedled=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.Gpios.prototype.clearRedled=function(){return this.setRedled(void 0)},proto.Conf.Gpios.prototype.hasRedled=function(){return null!=r.Message.getField(this,2)},proto.Conf.Gpios.prototype.getAudiojack=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,3)},proto.Conf.Gpios.prototype.setAudiojack=function(e){return r.Message.setWrapperField(this,3,e)},proto.Conf.Gpios.prototype.clearAudiojack=function(){return this.setAudiojack(void 0)},proto.Conf.Gpios.prototype.hasAudiojack=function(){return null!=r.Message.getField(this,3)},proto.Conf.Gpios.prototype.getAmp=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,4)},proto.Conf.Gpios.prototype.setAmp=function(e){return r.Message.setWrapperField(this,4,e)},proto.Conf.Gpios.prototype.clearAmp=function(){return this.setAmp(void 0)},proto.Conf.Gpios.prototype.hasAmp=function(){return null!=r.Message.getField(this,4)},proto.Conf.Gpios.prototype.getPower=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,5)},proto.Conf.Gpios.prototype.setPower=function(e){return r.Message.setWrapperField(this,5,e)},proto.Conf.Gpios.prototype.clearPower=function(){return this.setPower(void 0)},proto.Conf.Gpios.prototype.hasPower=function(){return null!=r.Message.getField(this,5)},proto.Conf.Gpios.prototype.getIr=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,6)},proto.Conf.Gpios.prototype.setIr=function(e){return r.Message.setWrapperField(this,6,e)},proto.Conf.Gpios.prototype.clearIr=function(){return this.setIr(void 0)},proto.Conf.Gpios.prototype.hasIr=function(){return null!=r.Message.getField(this,6)},proto.Conf.Gpios.prototype.getJack=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,7)},proto.Conf.Gpios.prototype.setJack=function(e){return r.Message.setWrapperField(this,7,e)},proto.Conf.Gpios.prototype.clearJack=function(){return this.setJack(void 0)},proto.Conf.Gpios.prototype.hasJack=function(){return null!=r.Message.getField(this,7)},proto.Conf.Gpios.prototype.getSpkfault=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,8)},proto.Conf.Gpios.prototype.setSpkfault=function(e){return r.Message.setWrapperField(this,8,e)},proto.Conf.Gpios.prototype.clearSpkfault=function(){return this.setSpkfault(void 0)},proto.Conf.Gpios.prototype.hasSpkfault=function(){return null!=r.Message.getField(this,8)},proto.Conf.Gpios.prototype.getVcc=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,9)},proto.Conf.Gpios.prototype.setVcc=function(e){return r.Message.setWrapperField(this,9,e)},proto.Conf.Gpios.prototype.clearVcc=function(){return this.setVcc(void 0)},proto.Conf.Gpios.prototype.hasVcc=function(){return null!=r.Message.getField(this,9)},proto.Conf.Gpios.prototype.getGnd=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,10)},proto.Conf.Gpios.prototype.setGnd=function(e){return r.Message.setWrapperField(this,10,e)},proto.Conf.Gpios.prototype.clearGnd=function(){return this.setGnd(void 0)},proto.Conf.Gpios.prototype.hasGnd=function(){return null!=r.Message.getField(this,10)},proto.Conf.Dev.repeatedFields_=[9],r.Message.GENERATE_TO_OBJECT&&(proto.Conf.Dev.prototype.toObject=function(e){return proto.Conf.Dev.toObject(e,this)},proto.Conf.Dev.toObject=function(e,t){var o,n={spi:(o=t.getSpi())&&proto.Conf.SPIBus.toObject(e,o),i2c:(o=t.getI2c())&&proto.Conf.I2CBus.toObject(e,o),dac:(o=t.getDac())&&proto.Conf.DACDev.toObject(e,o),spdif:(o=t.getSpdif())&&proto.Conf.SPDIFDev.toObject(e,o),display:(o=t.getDisplay())&&proto.Conf.DisplayDev.toObject(e,o),gpioExp:(o=t.getGpioExp())&&proto.Conf.GPIOExp.toObject(e,o),ledStrip:(o=t.getLedStrip())&&proto.Conf.LEDStrip.toObject(e,o),rotary:(o=t.getRotary())&&proto.Conf.Rotary.toObject(e,o),buttonsList:r.Message.toObjectList(t.getButtonsList(),proto.Conf.Button.toObject,e),eth:(o=t.getEth())&&proto.Conf.Eth.toObject(e,o),battery:(o=t.getBattery())&&proto.Conf.Battery.toObject(e,o)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.Dev.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.Dev;return proto.Conf.Dev.deserializeBinaryFromReader(o,t)},proto.Conf.Dev.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.SPIBus;t.readMessage(o,proto.Conf.SPIBus.deserializeBinaryFromReader),e.setSpi(o);break;case 2:o=new proto.Conf.I2CBus;t.readMessage(o,proto.Conf.I2CBus.deserializeBinaryFromReader),e.setI2c(o);break;case 3:o=new proto.Conf.DACDev;t.readMessage(o,proto.Conf.DACDev.deserializeBinaryFromReader),e.setDac(o);break;case 4:o=new proto.Conf.SPDIFDev;t.readMessage(o,proto.Conf.SPDIFDev.deserializeBinaryFromReader),e.setSpdif(o);break;case 5:o=new proto.Conf.DisplayDev;t.readMessage(o,proto.Conf.DisplayDev.deserializeBinaryFromReader),e.setDisplay(o);break;case 6:o=new proto.Conf.GPIOExp;t.readMessage(o,proto.Conf.GPIOExp.deserializeBinaryFromReader),e.setGpioExp(o);break;case 7:o=new proto.Conf.LEDStrip;t.readMessage(o,proto.Conf.LEDStrip.deserializeBinaryFromReader),e.setLedStrip(o);break;case 8:o=new proto.Conf.Rotary;t.readMessage(o,proto.Conf.Rotary.deserializeBinaryFromReader),e.setRotary(o);break;case 9:o=new proto.Conf.Button;t.readMessage(o,proto.Conf.Button.deserializeBinaryFromReader),e.addButtons(o);break;case 10:o=new proto.Conf.Eth;t.readMessage(o,proto.Conf.Eth.deserializeBinaryFromReader),e.setEth(o);break;case 11:o=new proto.Conf.Battery;t.readMessage(o,proto.Conf.Battery.deserializeBinaryFromReader),e.setBattery(o);break;default:t.skipField()}}return e},proto.Conf.Dev.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.Dev.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.Dev.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getSpi())&&t.writeMessage(1,o,proto.Conf.SPIBus.serializeBinaryToWriter),null!=(o=e.getI2c())&&t.writeMessage(2,o,proto.Conf.I2CBus.serializeBinaryToWriter),null!=(o=e.getDac())&&t.writeMessage(3,o,proto.Conf.DACDev.serializeBinaryToWriter),null!=(o=e.getSpdif())&&t.writeMessage(4,o,proto.Conf.SPDIFDev.serializeBinaryToWriter),null!=(o=e.getDisplay())&&t.writeMessage(5,o,proto.Conf.DisplayDev.serializeBinaryToWriter),null!=(o=e.getGpioExp())&&t.writeMessage(6,o,proto.Conf.GPIOExp.serializeBinaryToWriter),null!=(o=e.getLedStrip())&&t.writeMessage(7,o,proto.Conf.LEDStrip.serializeBinaryToWriter),null!=(o=e.getRotary())&&t.writeMessage(8,o,proto.Conf.Rotary.serializeBinaryToWriter),(o=e.getButtonsList()).length>0&&t.writeRepeatedMessage(9,o,proto.Conf.Button.serializeBinaryToWriter),null!=(o=e.getEth())&&t.writeMessage(10,o,proto.Conf.Eth.serializeBinaryToWriter),null!=(o=e.getBattery())&&t.writeMessage(11,o,proto.Conf.Battery.serializeBinaryToWriter)},proto.Conf.Dev.prototype.getSpi=function(){return r.Message.getWrapperField(this,proto.Conf.SPIBus,1)},proto.Conf.Dev.prototype.setSpi=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.Dev.prototype.clearSpi=function(){return this.setSpi(void 0)},proto.Conf.Dev.prototype.hasSpi=function(){return null!=r.Message.getField(this,1)},proto.Conf.Dev.prototype.getI2c=function(){return r.Message.getWrapperField(this,proto.Conf.I2CBus,2)},proto.Conf.Dev.prototype.setI2c=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.Dev.prototype.clearI2c=function(){return this.setI2c(void 0)},proto.Conf.Dev.prototype.hasI2c=function(){return null!=r.Message.getField(this,2)},proto.Conf.Dev.prototype.getDac=function(){return r.Message.getWrapperField(this,proto.Conf.DACDev,3)},proto.Conf.Dev.prototype.setDac=function(e){return r.Message.setWrapperField(this,3,e)},proto.Conf.Dev.prototype.clearDac=function(){return this.setDac(void 0)},proto.Conf.Dev.prototype.hasDac=function(){return null!=r.Message.getField(this,3)},proto.Conf.Dev.prototype.getSpdif=function(){return r.Message.getWrapperField(this,proto.Conf.SPDIFDev,4)},proto.Conf.Dev.prototype.setSpdif=function(e){return r.Message.setWrapperField(this,4,e)},proto.Conf.Dev.prototype.clearSpdif=function(){return this.setSpdif(void 0)},proto.Conf.Dev.prototype.hasSpdif=function(){return null!=r.Message.getField(this,4)},proto.Conf.Dev.prototype.getDisplay=function(){return r.Message.getWrapperField(this,proto.Conf.DisplayDev,5)},proto.Conf.Dev.prototype.setDisplay=function(e){return r.Message.setWrapperField(this,5,e)},proto.Conf.Dev.prototype.clearDisplay=function(){return this.setDisplay(void 0)},proto.Conf.Dev.prototype.hasDisplay=function(){return null!=r.Message.getField(this,5)},proto.Conf.Dev.prototype.getGpioExp=function(){return r.Message.getWrapperField(this,proto.Conf.GPIOExp,6)},proto.Conf.Dev.prototype.setGpioExp=function(e){return r.Message.setWrapperField(this,6,e)},proto.Conf.Dev.prototype.clearGpioExp=function(){return this.setGpioExp(void 0)},proto.Conf.Dev.prototype.hasGpioExp=function(){return null!=r.Message.getField(this,6)},proto.Conf.Dev.prototype.getLedStrip=function(){return r.Message.getWrapperField(this,proto.Conf.LEDStrip,7)},proto.Conf.Dev.prototype.setLedStrip=function(e){return r.Message.setWrapperField(this,7,e)},proto.Conf.Dev.prototype.clearLedStrip=function(){return this.setLedStrip(void 0)},proto.Conf.Dev.prototype.hasLedStrip=function(){return null!=r.Message.getField(this,7)},proto.Conf.Dev.prototype.getRotary=function(){return r.Message.getWrapperField(this,proto.Conf.Rotary,8)},proto.Conf.Dev.prototype.setRotary=function(e){return r.Message.setWrapperField(this,8,e)},proto.Conf.Dev.prototype.clearRotary=function(){return this.setRotary(void 0)},proto.Conf.Dev.prototype.hasRotary=function(){return null!=r.Message.getField(this,8)},proto.Conf.Dev.prototype.getButtonsList=function(){return r.Message.getRepeatedWrapperField(this,proto.Conf.Button,9)},proto.Conf.Dev.prototype.setButtonsList=function(e){return r.Message.setRepeatedWrapperField(this,9,e)},proto.Conf.Dev.prototype.addButtons=function(e,t){return r.Message.addToRepeatedWrapperField(this,9,e,proto.Conf.Button,t)},proto.Conf.Dev.prototype.clearButtonsList=function(){return this.setButtonsList([])},proto.Conf.Dev.prototype.getEth=function(){return r.Message.getWrapperField(this,proto.Conf.Eth,10)},proto.Conf.Dev.prototype.setEth=function(e){return r.Message.setWrapperField(this,10,e)},proto.Conf.Dev.prototype.clearEth=function(){return this.setEth(void 0)},proto.Conf.Dev.prototype.hasEth=function(){return null!=r.Message.getField(this,10)},proto.Conf.Dev.prototype.getBattery=function(){return r.Message.getWrapperField(this,proto.Conf.Battery,11)},proto.Conf.Dev.prototype.setBattery=function(e){return r.Message.setWrapperField(this,11,e)},proto.Conf.Dev.prototype.clearBattery=function(){return this.setBattery(void 0)},proto.Conf.Dev.prototype.hasBattery=function(){return null!=r.Message.getField(this,11)},proto.Conf.SleepService.repeatedFields_=[4,5],r.Message.GENERATE_TO_OBJECT&&(proto.Conf.SleepService.prototype.toObject=function(e){return proto.Conf.SleepService.toObject(e,this)},proto.Conf.SleepService.toObject=function(e,t){var o,n={delay:r.Message.getFieldWithDefault(t,1,0),spurious:r.Message.getFieldWithDefault(t,2,0),sleep:(o=t.getSleep())&&proto.Conf.GPIO.toObject(e,o),wakeList:r.Message.toObjectList(t.getWakeList(),proto.Conf.GPIO.toObject,e),rtcList:r.Message.toObjectList(t.getRtcList(),proto.Conf.GPIO.toObject,e),batt:r.Message.getFloatingPointFieldWithDefault(t,6,0)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.SleepService.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.SleepService;return proto.Conf.SleepService.deserializeBinaryFromReader(o,t)},proto.Conf.SleepService.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readUint32();e.setDelay(o);break;case 2:o=t.readInt32();e.setSpurious(o);break;case 3:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.setSleep(o);break;case 4:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.addWake(o);break;case 5:o=new proto.Conf.GPIO;t.readMessage(o,proto.Conf.GPIO.deserializeBinaryFromReader),e.addRtc(o);break;case 6:o=t.readFloat();e.setBatt(o);break;default:t.skipField()}}return e},proto.Conf.SleepService.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.SleepService.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.SleepService.serializeBinaryToWriter=function(e,t){var o=void 0;0!==(o=e.getDelay())&&t.writeUint32(1,o),0!==(o=e.getSpurious())&&t.writeInt32(2,o),null!=(o=e.getSleep())&&t.writeMessage(3,o,proto.Conf.GPIO.serializeBinaryToWriter),(o=e.getWakeList()).length>0&&t.writeRepeatedMessage(4,o,proto.Conf.GPIO.serializeBinaryToWriter),(o=e.getRtcList()).length>0&&t.writeRepeatedMessage(5,o,proto.Conf.GPIO.serializeBinaryToWriter),0!==(o=e.getBatt())&&t.writeFloat(6,o)},proto.Conf.SleepService.prototype.getDelay=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.Conf.SleepService.prototype.setDelay=function(e){return r.Message.setProto3IntField(this,1,e)},proto.Conf.SleepService.prototype.getSpurious=function(){return r.Message.getFieldWithDefault(this,2,0)},proto.Conf.SleepService.prototype.setSpurious=function(e){return r.Message.setProto3IntField(this,2,e)},proto.Conf.SleepService.prototype.getSleep=function(){return r.Message.getWrapperField(this,proto.Conf.GPIO,3)},proto.Conf.SleepService.prototype.setSleep=function(e){return r.Message.setWrapperField(this,3,e)},proto.Conf.SleepService.prototype.clearSleep=function(){return this.setSleep(void 0)},proto.Conf.SleepService.prototype.hasSleep=function(){return null!=r.Message.getField(this,3)},proto.Conf.SleepService.prototype.getWakeList=function(){return r.Message.getRepeatedWrapperField(this,proto.Conf.GPIO,4)},proto.Conf.SleepService.prototype.setWakeList=function(e){return r.Message.setRepeatedWrapperField(this,4,e)},proto.Conf.SleepService.prototype.addWake=function(e,t){return r.Message.addToRepeatedWrapperField(this,4,e,proto.Conf.GPIO,t)},proto.Conf.SleepService.prototype.clearWakeList=function(){return this.setWakeList([])},proto.Conf.SleepService.prototype.getRtcList=function(){return r.Message.getRepeatedWrapperField(this,proto.Conf.GPIO,5)},proto.Conf.SleepService.prototype.setRtcList=function(e){return r.Message.setRepeatedWrapperField(this,5,e)},proto.Conf.SleepService.prototype.addRtc=function(e,t){return r.Message.addToRepeatedWrapperField(this,5,e,proto.Conf.GPIO,t)},proto.Conf.SleepService.prototype.clearRtcList=function(){return this.setRtcList([])},proto.Conf.SleepService.prototype.getBatt=function(){return r.Message.getFloatingPointFieldWithDefault(this,6,0)},proto.Conf.SleepService.prototype.setBatt=function(e){return r.Message.setProto3FloatField(this,6,e)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.Artwork.prototype.toObject=function(e){return proto.Conf.Artwork.toObject(e,this)},proto.Conf.Artwork.toObject=function(e,t){var o={enabled:r.Message.getBooleanFieldWithDefault(t,1,!1),resize:r.Message.getFieldWithDefault(t,2,0)};return e&&(o.$jspbMessageInstance=t),o}),proto.Conf.Artwork.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.Artwork;return proto.Conf.Artwork.deserializeBinaryFromReader(o,t)},proto.Conf.Artwork.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readBool();e.setEnabled(o);break;case 2:o=t.readUint32();e.setResize(o);break;default:t.skipField()}}return e},proto.Conf.Artwork.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.Artwork.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.Artwork.serializeBinaryToWriter=function(e,t){var o=void 0;(o=e.getEnabled())&&t.writeBool(1,o),0!==(o=e.getResize())&&t.writeUint32(2,o)},proto.Conf.Artwork.prototype.getEnabled=function(){return r.Message.getBooleanFieldWithDefault(this,1,!1)},proto.Conf.Artwork.prototype.setEnabled=function(e){return r.Message.setProto3BooleanField(this,1,e)},proto.Conf.Artwork.prototype.getResize=function(){return r.Message.getFieldWithDefault(this,2,0)},proto.Conf.Artwork.prototype.setResize=function(e){return r.Message.setProto3IntField(this,2,e)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.Metadata.prototype.toObject=function(e){return proto.Conf.Metadata.toObject(e,this)},proto.Conf.Metadata.toObject=function(e,t){var o,n={format:r.Message.getFieldWithDefault(t,1,""),speed:r.Message.getFieldWithDefault(t,2,0),pause:r.Message.getFieldWithDefault(t,3,0),artwork:(o=t.getArtwork())&&proto.Conf.Artwork.toObject(e,o)};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.Metadata.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.Metadata;return proto.Conf.Metadata.deserializeBinaryFromReader(o,t)},proto.Conf.Metadata.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readString();e.setFormat(o);break;case 2:o=t.readUint32();e.setSpeed(o);break;case 3:o=t.readUint32();e.setPause(o);break;case 4:o=new proto.Conf.Artwork;t.readMessage(o,proto.Conf.Artwork.deserializeBinaryFromReader),e.setArtwork(o);break;default:t.skipField()}}return e},proto.Conf.Metadata.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.Metadata.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.Metadata.serializeBinaryToWriter=function(e,t){var o=void 0;(o=e.getFormat()).length>0&&t.writeString(1,o),0!==(o=e.getSpeed())&&t.writeUint32(2,o),0!==(o=e.getPause())&&t.writeUint32(3,o),null!=(o=e.getArtwork())&&t.writeMessage(4,o,proto.Conf.Artwork.serializeBinaryToWriter)},proto.Conf.Metadata.prototype.getFormat=function(){return r.Message.getFieldWithDefault(this,1,"")},proto.Conf.Metadata.prototype.setFormat=function(e){return r.Message.setProto3StringField(this,1,e)},proto.Conf.Metadata.prototype.getSpeed=function(){return r.Message.getFieldWithDefault(this,2,0)},proto.Conf.Metadata.prototype.setSpeed=function(e){return r.Message.setProto3IntField(this,2,e)},proto.Conf.Metadata.prototype.getPause=function(){return r.Message.getFieldWithDefault(this,3,0)},proto.Conf.Metadata.prototype.setPause=function(e){return r.Message.setProto3IntField(this,3,e)},proto.Conf.Metadata.prototype.getArtwork=function(){return r.Message.getWrapperField(this,proto.Conf.Artwork,4)},proto.Conf.Metadata.prototype.setArtwork=function(e){return r.Message.setWrapperField(this,4,e)},proto.Conf.Metadata.prototype.clearArtwork=function(){return this.setArtwork(void 0)},proto.Conf.Metadata.prototype.hasArtwork=function(){return null!=r.Message.getField(this,4)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.Services.prototype.toObject=function(e){return proto.Conf.Services.toObject(e,this)},proto.Conf.Services.toObject=function(e,t){var o,r={metadata:(o=t.getMetadata())&&proto.Conf.Metadata.toObject(e,o),sleep:(o=t.getSleep())&&proto.Conf.SleepService.toObject(e,o)};return e&&(r.$jspbMessageInstance=t),r}),proto.Conf.Services.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.Services;return proto.Conf.Services.deserializeBinaryFromReader(o,t)},proto.Conf.Services.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.Metadata;t.readMessage(o,proto.Conf.Metadata.deserializeBinaryFromReader),e.setMetadata(o);break;case 2:o=new proto.Conf.SleepService;t.readMessage(o,proto.Conf.SleepService.deserializeBinaryFromReader),e.setSleep(o);break;default:t.skipField()}}return e},proto.Conf.Services.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.Services.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.Services.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getMetadata())&&t.writeMessage(1,o,proto.Conf.Metadata.serializeBinaryToWriter),null!=(o=e.getSleep())&&t.writeMessage(2,o,proto.Conf.SleepService.serializeBinaryToWriter)},proto.Conf.Services.prototype.getMetadata=function(){return r.Message.getWrapperField(this,proto.Conf.Metadata,1)},proto.Conf.Services.prototype.setMetadata=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.Services.prototype.clearMetadata=function(){return this.setMetadata(void 0)},proto.Conf.Services.prototype.hasMetadata=function(){return null!=r.Message.getField(this,1)},proto.Conf.Services.prototype.getSleep=function(){return r.Message.getWrapperField(this,proto.Conf.SleepService,2)},proto.Conf.Services.prototype.setSleep=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.Services.prototype.clearSleep=function(){return this.setSleep(void 0)},proto.Conf.Services.prototype.hasSleep=function(){return null!=r.Message.getField(this,2)},r.Message.GENERATE_TO_OBJECT&&(proto.Conf.Config.prototype.toObject=function(e){return proto.Conf.Config.toObject(e,this)},proto.Conf.Config.toObject=function(e,t){var o,n={gpios:(o=t.getGpios())&&proto.Conf.Gpios.toObject(e,o),dev:(o=t.getDev())&&proto.Conf.Dev.toObject(e,o),services:(o=t.getServices())&&proto.Conf.Services.toObject(e,o),deviceName:r.Message.getFieldWithDefault(t,4,"")};return e&&(n.$jspbMessageInstance=t),n}),proto.Conf.Config.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.Conf.Config;return proto.Conf.Config.deserializeBinaryFromReader(o,t)},proto.Conf.Config.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=new proto.Conf.Gpios;t.readMessage(o,proto.Conf.Gpios.deserializeBinaryFromReader),e.setGpios(o);break;case 2:o=new proto.Conf.Dev;t.readMessage(o,proto.Conf.Dev.deserializeBinaryFromReader),e.setDev(o);break;case 3:o=new proto.Conf.Services;t.readMessage(o,proto.Conf.Services.deserializeBinaryFromReader),e.setServices(o);break;case 4:o=t.readString();e.setDeviceName(o);break;default:t.skipField()}}return e},proto.Conf.Config.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.Conf.Config.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.Conf.Config.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=e.getGpios())&&t.writeMessage(1,o,proto.Conf.Gpios.serializeBinaryToWriter),null!=(o=e.getDev())&&t.writeMessage(2,o,proto.Conf.Dev.serializeBinaryToWriter),null!=(o=e.getServices())&&t.writeMessage(3,o,proto.Conf.Services.serializeBinaryToWriter),(o=e.getDeviceName()).length>0&&t.writeString(4,o)},proto.Conf.Config.prototype.getGpios=function(){return r.Message.getWrapperField(this,proto.Conf.Gpios,1)},proto.Conf.Config.prototype.setGpios=function(e){return r.Message.setWrapperField(this,1,e)},proto.Conf.Config.prototype.clearGpios=function(){return this.setGpios(void 0)},proto.Conf.Config.prototype.hasGpios=function(){return null!=r.Message.getField(this,1)},proto.Conf.Config.prototype.getDev=function(){return r.Message.getWrapperField(this,proto.Conf.Dev,2)},proto.Conf.Config.prototype.setDev=function(e){return r.Message.setWrapperField(this,2,e)},proto.Conf.Config.prototype.clearDev=function(){return this.setDev(void 0)},proto.Conf.Config.prototype.hasDev=function(){return null!=r.Message.getField(this,2)},proto.Conf.Config.prototype.getServices=function(){return r.Message.getWrapperField(this,proto.Conf.Services,3)},proto.Conf.Config.prototype.setServices=function(e){return r.Message.setWrapperField(this,3,e)},proto.Conf.Config.prototype.clearServices=function(){return this.setServices(void 0)},proto.Conf.Config.prototype.hasServices=function(){return null!=r.Message.getField(this,3)},proto.Conf.Config.prototype.getDeviceName=function(){return r.Message.getFieldWithDefault(this,4,"")},proto.Conf.Config.prototype.setDeviceName=function(e){return r.Message.setProto3StringField(this,4,e)},proto.Conf.ButtonAction={ACTRLS_NONE:0,ACTRLS_POWER:1,ACTRLS_VOLUP:2,ACTRLS_VOLDOWN:3,ACTRLS_TOGGLE:4,ACTRLS_PLAY:5,ACTRLS_PAUSE:6,ACTRLS_STOP:7,ACTRLS_REW:8,ACTRLS_FWD:9,ACTRLS_PREV:10,ACTRLS_NEXT:11,BCTRLS_UP:12,BCTRLS_DOWN:13,BCTRLS_LEFT:14,BCTRLS_RIGHT:15,BCTRLS_PS1:16,BCTRLS_PS2:17,BCTRLS_PS3:18,BCTRLS_PS4:19,BCTRLS_PS5:20,BCTRLS_PS6:21,BCTRLS_PS7:22,BCTRLS_PS8:23,BCTRLS_PS9:24,BCTRLS_PS10:25,KNOB_LEFT:26,KNOB_RIGHT:27,KNOB_PUSH:28,ACTRLS_SLEEP:29},proto.Conf.DACModelEnum={UNSPECIFIED_MODEL:0,TAS57XX:1,TAS5713:2,AC101:3,WM8978:4,ES8388:5,I2S:6},proto.Conf.DeviceTypeEnum={UNSPECIFIED_TYPE:0,DEVTYPE_SPI:1,DEVTYPE_I2C:2,DEVTYPE__RMII:3},proto.Conf.DisplayDriverEnum={UNSPECIFIED_DRIVER:0,SSD1306:1,SSD1322:2,SSD1326:3,SSD1327:4,SH1106:5,SSD1675:6,ST7735:7,ST7789:8,ILI9341:9,ILI9341_24:10,SSD1351:11},proto.Conf.PortEnum={UNSPECIFIED_SYSTPORT:0,SYSTEM:1,DAC:2},proto.Conf.EthModelEnum={UNSPECIFIED_ETHMODEL:0,LAN8720:1,DM9051:2,W5500:3},proto.Conf.GPIOExpModelEnum={UNSPECIFIED_EXP:0,PCA9535:1,PCA85XX:2,MCP23017:3,MCP23S17:4},proto.Conf.HostEnum={UNSPECIFIED_HOST:0,HOST0:1,HOST1:2},proto.Conf.I2CPortEnum={UNSPECIFIED_PORT:0,I2CPORT0:1,I2CPORT1:2},proto.Conf.MCKEnum={UNSPECIFIED_MCK:0,MCK0:1,MCK1:2,MCK2:3},proto.Conf.BatteryChannelEnum={UNSPECIFIED_CH:0,CH0:1,CH1:2,CH2:3,CH3:4,CH4:5,CH5:6,CH6:7,CH7:8},proto.Conf.BatteryAttenEnum={UNSPECIFIED_ATT:0,ATT_0:1,ATT_1:2,ATT_2:3,ATT_3:4},proto.Conf.EthType={UNSPECIFIED_ETH:0,SPI:1,RMII:2},n.object.extend(t,proto.Conf)},21:(e,t,o)=>{var r=o(19),n=r,i=function(){return this?this:"undefined"!=typeof window?window:void 0!==i?i:"undefined"!=typeof self?self:Function("return this")()}.call(null),s=o(392);n.object.extend(proto,s),n.exportSymbol("proto.DescriptorSize",null,i),n.exportSymbol("proto.FieldType",null,i),n.exportSymbol("proto.IntSize",null,i),n.exportSymbol("proto.NanoPBOptions",null,i),n.exportSymbol("proto.TypenameMangling",null,i),n.exportSymbol("proto.nanopb",null,i),n.exportSymbol("proto.nanopbEnumopt",null,i),n.exportSymbol("proto.nanopbFileopt",null,i),n.exportSymbol("proto.nanopbMsgopt",null,i),proto.NanoPBOptions=function(e){r.Message.initialize(this,e,0,-1,proto.NanoPBOptions.repeatedFields_,null)},n.inherits(proto.NanoPBOptions,r.Message),n.DEBUG&&!COMPILED&&(proto.NanoPBOptions.displayName="proto.NanoPBOptions"),proto.NanoPBOptions.repeatedFields_=[24,26],r.Message.GENERATE_TO_OBJECT&&(proto.NanoPBOptions.prototype.toObject=function(e){return proto.NanoPBOptions.toObject(e,this)},proto.NanoPBOptions.toObject=function(e,t){var o,n={maxSize:null==(o=r.Message.getField(t,1))?void 0:o,maxLength:null==(o=r.Message.getField(t,14))?void 0:o,maxCount:null==(o=r.Message.getField(t,2))?void 0:o,intSize:r.Message.getFieldWithDefault(t,7,0),type:r.Message.getFieldWithDefault(t,3,0),longNames:r.Message.getBooleanFieldWithDefault(t,4,!0),packedStruct:r.Message.getBooleanFieldWithDefault(t,5,!1),packedEnum:r.Message.getBooleanFieldWithDefault(t,10,!1),skipMessage:r.Message.getBooleanFieldWithDefault(t,6,!1),noUnions:r.Message.getBooleanFieldWithDefault(t,8,!1),msgid:null==(o=r.Message.getField(t,9))?void 0:o,anonymousOneof:r.Message.getBooleanFieldWithDefault(t,11,!1),proto3:r.Message.getBooleanFieldWithDefault(t,12,!1),proto3SingularMsgs:r.Message.getBooleanFieldWithDefault(t,21,!1),enumToString:r.Message.getBooleanFieldWithDefault(t,13,!1),fixedLength:r.Message.getBooleanFieldWithDefault(t,15,!1),fixedCount:r.Message.getBooleanFieldWithDefault(t,16,!1),submsgCallback:r.Message.getBooleanFieldWithDefault(t,22,!1),mangleNames:r.Message.getFieldWithDefault(t,17,0),callbackDatatype:r.Message.getFieldWithDefault(t,18,"pb_callback_t"),callbackFunction:r.Message.getFieldWithDefault(t,19,"pb_default_field_callback"),descriptorsize:r.Message.getFieldWithDefault(t,20,0),defaultHas:r.Message.getBooleanFieldWithDefault(t,23,!1),includeList:null==(o=r.Message.getRepeatedField(t,24))?void 0:o,excludeList:null==(o=r.Message.getRepeatedField(t,26))?void 0:o,pb_package:null==(o=r.Message.getField(t,25))?void 0:o,typeOverride:null==(o=r.Message.getField(t,27))?void 0:o,sortByTag:r.Message.getBooleanFieldWithDefault(t,28,!0)};return e&&(n.$jspbMessageInstance=t),n}),proto.NanoPBOptions.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.NanoPBOptions;return proto.NanoPBOptions.deserializeBinaryFromReader(o,t)},proto.NanoPBOptions.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();){switch(t.getFieldNumber()){case 1:var o=t.readInt32();e.setMaxSize(o);break;case 14:o=t.readInt32();e.setMaxLength(o);break;case 2:o=t.readInt32();e.setMaxCount(o);break;case 7:o=t.readEnum();e.setIntSize(o);break;case 3:o=t.readEnum();e.setType(o);break;case 4:o=t.readBool();e.setLongNames(o);break;case 5:o=t.readBool();e.setPackedStruct(o);break;case 10:o=t.readBool();e.setPackedEnum(o);break;case 6:o=t.readBool();e.setSkipMessage(o);break;case 8:o=t.readBool();e.setNoUnions(o);break;case 9:o=t.readUint32();e.setMsgid(o);break;case 11:o=t.readBool();e.setAnonymousOneof(o);break;case 12:o=t.readBool();e.setProto3(o);break;case 21:o=t.readBool();e.setProto3SingularMsgs(o);break;case 13:o=t.readBool();e.setEnumToString(o);break;case 15:o=t.readBool();e.setFixedLength(o);break;case 16:o=t.readBool();e.setFixedCount(o);break;case 22:o=t.readBool();e.setSubmsgCallback(o);break;case 17:o=t.readEnum();e.setMangleNames(o);break;case 18:o=t.readString();e.setCallbackDatatype(o);break;case 19:o=t.readString();e.setCallbackFunction(o);break;case 20:o=t.readEnum();e.setDescriptorsize(o);break;case 23:o=t.readBool();e.setDefaultHas(o);break;case 24:o=t.readString();e.addInclude(o);break;case 26:o=t.readString();e.addExclude(o);break;case 25:o=t.readString();e.setPackage(o);break;case 27:o=t.readEnum();e.setTypeOverride(o);break;case 28:o=t.readBool();e.setSortByTag(o);break;default:t.skipField()}}return e},proto.NanoPBOptions.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.NanoPBOptions.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.NanoPBOptions.serializeBinaryToWriter=function(e,t){var o=void 0;null!=(o=r.Message.getField(e,1))&&t.writeInt32(1,o),null!=(o=r.Message.getField(e,14))&&t.writeInt32(14,o),null!=(o=r.Message.getField(e,2))&&t.writeInt32(2,o),null!=(o=r.Message.getField(e,7))&&t.writeEnum(7,o),null!=(o=r.Message.getField(e,3))&&t.writeEnum(3,o),null!=(o=r.Message.getField(e,4))&&t.writeBool(4,o),null!=(o=r.Message.getField(e,5))&&t.writeBool(5,o),null!=(o=r.Message.getField(e,10))&&t.writeBool(10,o),null!=(o=r.Message.getField(e,6))&&t.writeBool(6,o),null!=(o=r.Message.getField(e,8))&&t.writeBool(8,o),null!=(o=r.Message.getField(e,9))&&t.writeUint32(9,o),null!=(o=r.Message.getField(e,11))&&t.writeBool(11,o),null!=(o=r.Message.getField(e,12))&&t.writeBool(12,o),null!=(o=r.Message.getField(e,21))&&t.writeBool(21,o),null!=(o=r.Message.getField(e,13))&&t.writeBool(13,o),null!=(o=r.Message.getField(e,15))&&t.writeBool(15,o),null!=(o=r.Message.getField(e,16))&&t.writeBool(16,o),null!=(o=r.Message.getField(e,22))&&t.writeBool(22,o),null!=(o=r.Message.getField(e,17))&&t.writeEnum(17,o),null!=(o=r.Message.getField(e,18))&&t.writeString(18,o),null!=(o=r.Message.getField(e,19))&&t.writeString(19,o),null!=(o=r.Message.getField(e,20))&&t.writeEnum(20,o),null!=(o=r.Message.getField(e,23))&&t.writeBool(23,o),(o=e.getIncludeList()).length>0&&t.writeRepeatedString(24,o),(o=e.getExcludeList()).length>0&&t.writeRepeatedString(26,o),null!=(o=r.Message.getField(e,25))&&t.writeString(25,o),null!=(o=r.Message.getField(e,27))&&t.writeEnum(27,o),null!=(o=r.Message.getField(e,28))&&t.writeBool(28,o)},proto.NanoPBOptions.prototype.getMaxSize=function(){return r.Message.getFieldWithDefault(this,1,0)},proto.NanoPBOptions.prototype.setMaxSize=function(e){return r.Message.setField(this,1,e)},proto.NanoPBOptions.prototype.clearMaxSize=function(){return r.Message.setField(this,1,void 0)},proto.NanoPBOptions.prototype.hasMaxSize=function(){return null!=r.Message.getField(this,1)},proto.NanoPBOptions.prototype.getMaxLength=function(){return r.Message.getFieldWithDefault(this,14,0)},proto.NanoPBOptions.prototype.setMaxLength=function(e){return r.Message.setField(this,14,e)},proto.NanoPBOptions.prototype.clearMaxLength=function(){return r.Message.setField(this,14,void 0)},proto.NanoPBOptions.prototype.hasMaxLength=function(){return null!=r.Message.getField(this,14)},proto.NanoPBOptions.prototype.getMaxCount=function(){return r.Message.getFieldWithDefault(this,2,0)},proto.NanoPBOptions.prototype.setMaxCount=function(e){return r.Message.setField(this,2,e)},proto.NanoPBOptions.prototype.clearMaxCount=function(){return r.Message.setField(this,2,void 0)},proto.NanoPBOptions.prototype.hasMaxCount=function(){return null!=r.Message.getField(this,2)},proto.NanoPBOptions.prototype.getIntSize=function(){return r.Message.getFieldWithDefault(this,7,0)},proto.NanoPBOptions.prototype.setIntSize=function(e){return r.Message.setField(this,7,e)},proto.NanoPBOptions.prototype.clearIntSize=function(){return r.Message.setField(this,7,void 0)},proto.NanoPBOptions.prototype.hasIntSize=function(){return null!=r.Message.getField(this,7)},proto.NanoPBOptions.prototype.getType=function(){return r.Message.getFieldWithDefault(this,3,0)},proto.NanoPBOptions.prototype.setType=function(e){return r.Message.setField(this,3,e)},proto.NanoPBOptions.prototype.clearType=function(){return r.Message.setField(this,3,void 0)},proto.NanoPBOptions.prototype.hasType=function(){return null!=r.Message.getField(this,3)},proto.NanoPBOptions.prototype.getLongNames=function(){return r.Message.getBooleanFieldWithDefault(this,4,!0)},proto.NanoPBOptions.prototype.setLongNames=function(e){return r.Message.setField(this,4,e)},proto.NanoPBOptions.prototype.clearLongNames=function(){return r.Message.setField(this,4,void 0)},proto.NanoPBOptions.prototype.hasLongNames=function(){return null!=r.Message.getField(this,4)},proto.NanoPBOptions.prototype.getPackedStruct=function(){return r.Message.getBooleanFieldWithDefault(this,5,!1)},proto.NanoPBOptions.prototype.setPackedStruct=function(e){return r.Message.setField(this,5,e)},proto.NanoPBOptions.prototype.clearPackedStruct=function(){return r.Message.setField(this,5,void 0)},proto.NanoPBOptions.prototype.hasPackedStruct=function(){return null!=r.Message.getField(this,5)},proto.NanoPBOptions.prototype.getPackedEnum=function(){return r.Message.getBooleanFieldWithDefault(this,10,!1)},proto.NanoPBOptions.prototype.setPackedEnum=function(e){return r.Message.setField(this,10,e)},proto.NanoPBOptions.prototype.clearPackedEnum=function(){return r.Message.setField(this,10,void 0)},proto.NanoPBOptions.prototype.hasPackedEnum=function(){return null!=r.Message.getField(this,10)},proto.NanoPBOptions.prototype.getSkipMessage=function(){return r.Message.getBooleanFieldWithDefault(this,6,!1)},proto.NanoPBOptions.prototype.setSkipMessage=function(e){return r.Message.setField(this,6,e)},proto.NanoPBOptions.prototype.clearSkipMessage=function(){return r.Message.setField(this,6,void 0)},proto.NanoPBOptions.prototype.hasSkipMessage=function(){return null!=r.Message.getField(this,6)},proto.NanoPBOptions.prototype.getNoUnions=function(){return r.Message.getBooleanFieldWithDefault(this,8,!1)},proto.NanoPBOptions.prototype.setNoUnions=function(e){return r.Message.setField(this,8,e)},proto.NanoPBOptions.prototype.clearNoUnions=function(){return r.Message.setField(this,8,void 0)},proto.NanoPBOptions.prototype.hasNoUnions=function(){return null!=r.Message.getField(this,8)},proto.NanoPBOptions.prototype.getMsgid=function(){return r.Message.getFieldWithDefault(this,9,0)},proto.NanoPBOptions.prototype.setMsgid=function(e){return r.Message.setField(this,9,e)},proto.NanoPBOptions.prototype.clearMsgid=function(){return r.Message.setField(this,9,void 0)},proto.NanoPBOptions.prototype.hasMsgid=function(){return null!=r.Message.getField(this,9)},proto.NanoPBOptions.prototype.getAnonymousOneof=function(){return r.Message.getBooleanFieldWithDefault(this,11,!1)},proto.NanoPBOptions.prototype.setAnonymousOneof=function(e){return r.Message.setField(this,11,e)},proto.NanoPBOptions.prototype.clearAnonymousOneof=function(){return r.Message.setField(this,11,void 0)},proto.NanoPBOptions.prototype.hasAnonymousOneof=function(){return null!=r.Message.getField(this,11)},proto.NanoPBOptions.prototype.getProto3=function(){return r.Message.getBooleanFieldWithDefault(this,12,!1)},proto.NanoPBOptions.prototype.setProto3=function(e){return r.Message.setField(this,12,e)},proto.NanoPBOptions.prototype.clearProto3=function(){return r.Message.setField(this,12,void 0)},proto.NanoPBOptions.prototype.hasProto3=function(){return null!=r.Message.getField(this,12)},proto.NanoPBOptions.prototype.getProto3SingularMsgs=function(){return r.Message.getBooleanFieldWithDefault(this,21,!1)},proto.NanoPBOptions.prototype.setProto3SingularMsgs=function(e){return r.Message.setField(this,21,e)},proto.NanoPBOptions.prototype.clearProto3SingularMsgs=function(){return r.Message.setField(this,21,void 0)},proto.NanoPBOptions.prototype.hasProto3SingularMsgs=function(){return null!=r.Message.getField(this,21)},proto.NanoPBOptions.prototype.getEnumToString=function(){return r.Message.getBooleanFieldWithDefault(this,13,!1)},proto.NanoPBOptions.prototype.setEnumToString=function(e){return r.Message.setField(this,13,e)},proto.NanoPBOptions.prototype.clearEnumToString=function(){return r.Message.setField(this,13,void 0)},proto.NanoPBOptions.prototype.hasEnumToString=function(){return null!=r.Message.getField(this,13)},proto.NanoPBOptions.prototype.getFixedLength=function(){return r.Message.getBooleanFieldWithDefault(this,15,!1)},proto.NanoPBOptions.prototype.setFixedLength=function(e){return r.Message.setField(this,15,e)},proto.NanoPBOptions.prototype.clearFixedLength=function(){return r.Message.setField(this,15,void 0)},proto.NanoPBOptions.prototype.hasFixedLength=function(){return null!=r.Message.getField(this,15)},proto.NanoPBOptions.prototype.getFixedCount=function(){return r.Message.getBooleanFieldWithDefault(this,16,!1)},proto.NanoPBOptions.prototype.setFixedCount=function(e){return r.Message.setField(this,16,e)},proto.NanoPBOptions.prototype.clearFixedCount=function(){return r.Message.setField(this,16,void 0)},proto.NanoPBOptions.prototype.hasFixedCount=function(){return null!=r.Message.getField(this,16)},proto.NanoPBOptions.prototype.getSubmsgCallback=function(){return r.Message.getBooleanFieldWithDefault(this,22,!1)},proto.NanoPBOptions.prototype.setSubmsgCallback=function(e){return r.Message.setField(this,22,e)},proto.NanoPBOptions.prototype.clearSubmsgCallback=function(){return r.Message.setField(this,22,void 0)},proto.NanoPBOptions.prototype.hasSubmsgCallback=function(){return null!=r.Message.getField(this,22)},proto.NanoPBOptions.prototype.getMangleNames=function(){return r.Message.getFieldWithDefault(this,17,0)},proto.NanoPBOptions.prototype.setMangleNames=function(e){return r.Message.setField(this,17,e)},proto.NanoPBOptions.prototype.clearMangleNames=function(){return r.Message.setField(this,17,void 0)},proto.NanoPBOptions.prototype.hasMangleNames=function(){return null!=r.Message.getField(this,17)},proto.NanoPBOptions.prototype.getCallbackDatatype=function(){return r.Message.getFieldWithDefault(this,18,"pb_callback_t")},proto.NanoPBOptions.prototype.setCallbackDatatype=function(e){return r.Message.setField(this,18,e)},proto.NanoPBOptions.prototype.clearCallbackDatatype=function(){return r.Message.setField(this,18,void 0)},proto.NanoPBOptions.prototype.hasCallbackDatatype=function(){return null!=r.Message.getField(this,18)},proto.NanoPBOptions.prototype.getCallbackFunction=function(){return r.Message.getFieldWithDefault(this,19,"pb_default_field_callback")},proto.NanoPBOptions.prototype.setCallbackFunction=function(e){return r.Message.setField(this,19,e)},proto.NanoPBOptions.prototype.clearCallbackFunction=function(){return r.Message.setField(this,19,void 0)},proto.NanoPBOptions.prototype.hasCallbackFunction=function(){return null!=r.Message.getField(this,19)},proto.NanoPBOptions.prototype.getDescriptorsize=function(){return r.Message.getFieldWithDefault(this,20,0)},proto.NanoPBOptions.prototype.setDescriptorsize=function(e){return r.Message.setField(this,20,e)},proto.NanoPBOptions.prototype.clearDescriptorsize=function(){return r.Message.setField(this,20,void 0)},proto.NanoPBOptions.prototype.hasDescriptorsize=function(){return null!=r.Message.getField(this,20)},proto.NanoPBOptions.prototype.getDefaultHas=function(){return r.Message.getBooleanFieldWithDefault(this,23,!1)},proto.NanoPBOptions.prototype.setDefaultHas=function(e){return r.Message.setField(this,23,e)},proto.NanoPBOptions.prototype.clearDefaultHas=function(){return r.Message.setField(this,23,void 0)},proto.NanoPBOptions.prototype.hasDefaultHas=function(){return null!=r.Message.getField(this,23)},proto.NanoPBOptions.prototype.getIncludeList=function(){return r.Message.getRepeatedField(this,24)},proto.NanoPBOptions.prototype.setIncludeList=function(e){return r.Message.setField(this,24,e||[])},proto.NanoPBOptions.prototype.addInclude=function(e,t){return r.Message.addToRepeatedField(this,24,e,t)},proto.NanoPBOptions.prototype.clearIncludeList=function(){return this.setIncludeList([])},proto.NanoPBOptions.prototype.getExcludeList=function(){return r.Message.getRepeatedField(this,26)},proto.NanoPBOptions.prototype.setExcludeList=function(e){return r.Message.setField(this,26,e||[])},proto.NanoPBOptions.prototype.addExclude=function(e,t){return r.Message.addToRepeatedField(this,26,e,t)},proto.NanoPBOptions.prototype.clearExcludeList=function(){return this.setExcludeList([])},proto.NanoPBOptions.prototype.getPackage=function(){return r.Message.getFieldWithDefault(this,25,"")},proto.NanoPBOptions.prototype.setPackage=function(e){return r.Message.setField(this,25,e)},proto.NanoPBOptions.prototype.clearPackage=function(){return r.Message.setField(this,25,void 0)},proto.NanoPBOptions.prototype.hasPackage=function(){return null!=r.Message.getField(this,25)},proto.NanoPBOptions.prototype.getTypeOverride=function(){return r.Message.getFieldWithDefault(this,27,1)},proto.NanoPBOptions.prototype.setTypeOverride=function(e){return r.Message.setField(this,27,e)},proto.NanoPBOptions.prototype.clearTypeOverride=function(){return r.Message.setField(this,27,void 0)},proto.NanoPBOptions.prototype.hasTypeOverride=function(){return null!=r.Message.getField(this,27)},proto.NanoPBOptions.prototype.getSortByTag=function(){return r.Message.getBooleanFieldWithDefault(this,28,!0)},proto.NanoPBOptions.prototype.setSortByTag=function(e){return r.Message.setField(this,28,e)},proto.NanoPBOptions.prototype.clearSortByTag=function(){return r.Message.setField(this,28,void 0)},proto.NanoPBOptions.prototype.hasSortByTag=function(){return null!=r.Message.getField(this,28)},proto.FieldType={FT_DEFAULT:0,FT_CALLBACK:1,FT_POINTER:4,FT_STATIC:2,FT_IGNORE:3,FT_INLINE:5},proto.IntSize={IS_DEFAULT:0,IS_8:8,IS_16:16,IS_32:32,IS_64:64},proto.TypenameMangling={M_NONE:0,M_STRIP_PACKAGE:1,M_FLATTEN:2,M_PACKAGE_INITIALS:3},proto.DescriptorSize={DS_AUTO:0,DS_1:1,DS_2:2,DS_4:4,DS_8:8},proto.nanopbFileopt=new r.ExtensionFieldInfo(1010,{nanopbFileopt:0},proto.NanoPBOptions,proto.NanoPBOptions.toObject,0),s.FileOptions.extensionsBinary[1010]=new r.ExtensionFieldBinaryInfo(proto.nanopbFileopt,r.BinaryReader.prototype.readMessage,r.BinaryWriter.prototype.writeMessage,proto.NanoPBOptions.serializeBinaryToWriter,proto.NanoPBOptions.deserializeBinaryFromReader,!1),s.FileOptions.extensions[1010]=proto.nanopbFileopt,proto.nanopbMsgopt=new r.ExtensionFieldInfo(1010,{nanopbMsgopt:0},proto.NanoPBOptions,proto.NanoPBOptions.toObject,0),s.MessageOptions.extensionsBinary[1010]=new r.ExtensionFieldBinaryInfo(proto.nanopbMsgopt,r.BinaryReader.prototype.readMessage,r.BinaryWriter.prototype.writeMessage,proto.NanoPBOptions.serializeBinaryToWriter,proto.NanoPBOptions.deserializeBinaryFromReader,!1),s.MessageOptions.extensions[1010]=proto.nanopbMsgopt,proto.nanopbEnumopt=new r.ExtensionFieldInfo(1010,{nanopbEnumopt:0},proto.NanoPBOptions,proto.NanoPBOptions.toObject,0),s.EnumOptions.extensionsBinary[1010]=new r.ExtensionFieldBinaryInfo(proto.nanopbEnumopt,r.BinaryReader.prototype.readMessage,r.BinaryWriter.prototype.writeMessage,proto.NanoPBOptions.serializeBinaryToWriter,proto.NanoPBOptions.deserializeBinaryFromReader,!1),s.EnumOptions.extensions[1010]=proto.nanopbEnumopt,proto.nanopb=new r.ExtensionFieldInfo(1010,{nanopb:0},proto.NanoPBOptions,proto.NanoPBOptions.toObject,0),s.FieldOptions.extensionsBinary[1010]=new r.ExtensionFieldBinaryInfo(proto.nanopb,r.BinaryReader.prototype.readMessage,r.BinaryWriter.prototype.writeMessage,proto.NanoPBOptions.serializeBinaryToWriter,proto.NanoPBOptions.deserializeBinaryFromReader,!1),s.FieldOptions.extensions[1010]=proto.nanopb,n.object.extend(t,proto)},393:(e,t,o)=>{"use strict";o.r(t)},607:(e,t,o)=>{"use strict";o(138),o(393),o(861),o(44)},44:function(e,t,o){"use strict";var r=o(755),n=this&&this.__createBinding||(Object.create?function(e,t,o,r){void 0===r&&(r=o);var n=Object.getOwnPropertyDescriptor(t,o);n&&!("get"in n?!t.__esModule:n.writable||n.configurable)||(n={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,r,n)}:function(e,t,o,r){void 0===r&&(r=o),e[r]=t[o]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var o in e)"default"!==o&&Object.prototype.hasOwnProperty.call(e,o)&&n(t,e,o);return i(t,e),t},a=this&&this.__awaiter||function(e,t,o,r){return new(o||(o=Promise))((function(n,i){function s(e){try{p(r.next(e))}catch(e){i(e)}}function a(e){try{p(r.throw(e))}catch(e){i(e)}}function p(e){var t;e.done?n(e.value):(t=e.value,t instanceof o?t:new o((function(e){e(t)}))).then(s,a)}p((r=r.apply(e,t||[])).next())}))},p=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var l=o(492);const u=p(o(646)),f=s(o(874)),c=s(o(138));function d(){r("#flashfilename").val=null,O.StartOTA()}function g(e){"reboot_ota"==e?(r("#reboot_ota_nav").removeClass("active").prop("disabled",!0),le(500,"","reboot_ota")):(r("#reboot_nav").removeClass("active"),le(500,"",e))}function C(e){let t,o,n,i;return"string"==typeof e?(o=e,t=r(`#${o}`)):(o=r(e).attr("id"),t=r(e)),"checkbox"===t.attr("type")?(i=t.prop("checked")?o.replace("cmd_opt_",""):"",n=!0):(i=o.replace("cmd_opt_",""),n=t.val(),"string"==typeof n?n=`${n.includes(" ")?'"':""}${n}${n.includes(" ")?'"':""}`:"number"!=typeof n&&(n=n.toString())),{opt:i,val:n}}function h(){let e=y(u.default.get("show-nvs"));const t=r("input#show-nvs")[0];t.checked=e,t.checked||k?r('*[href*="-nvs"]').show():r('*[href*="-nvs"]').hide()}function y(e){return null!=e&&"string"==typeof e&&e.match("[Yy1]").length>0}var M;console.log(f),window.hideSurrounding=function(e){r(e).parent().parent().hide()},window.hFlash=function(){d()},window.handleReboot=function(e){g(e)},Object.assign(String.prototype,{format(...e){return this.replace(/{(\d+)}/g,(function(t,o){const r=parseInt(o,10);return void 0!==e[r]?e[r]:t}))}}),Object.assign(String.prototype,{encodeHTML(){return l.encode(this).replace(/\n/g,"
")}}),Object.assign(Date.prototype,{toLocalShort(){return this.toLocaleString(void 0,{dateStyle:"short",timeStyle:"short"})}}),function(e){e[e.NVS_TYPE_U8=1]="NVS_TYPE_U8",e[e.NVS_TYPE_I8=17]="NVS_TYPE_I8",e[e.NVS_TYPE_U16=2]="NVS_TYPE_U16",e[e.NVS_TYPE_I16=18]="NVS_TYPE_I16",e[e.NVS_TYPE_U32=4]="NVS_TYPE_U32",e[e.NVS_TYPE_I32=20]="NVS_TYPE_I32",e[e.NVS_TYPE_U64=8]="NVS_TYPE_U64",e[e.NVS_TYPE_I64=24]="NVS_TYPE_I64",e[e.NVS_TYPE_STR=33]="NVS_TYPE_STR",e[e.NVS_TYPE_BLOB=66]="NVS_TYPE_BLOB",e[e.NVS_TYPE_ANY=255]="NVS_TYPE_ANY"}(M||(M={}));const m={bt_playing:{label:"",icon:"media_bluetooth_on"},bt_disconnected:{label:"",icon:"media_bluetooth_off"},bt_neutral:{label:"",icon:"bluetooth"},bt_connecting:{label:"",icon:"bluetooth_searching"},bt_connected:{label:"",icon:"bluetooth_connected"},bt_disabled:{label:"",icon:"bluetooth_disabled"},play_arrow:{label:"",icon:"play_circle_filled"},pause:{label:"",icon:"pause_circle"},stop:{label:"",icon:"stop_circle"},"":{label:"",icon:""}},B=[{icon:"battery_0_bar",label:"▪",ranges:[{f:5.8,t:6.8},{f:8.8,t:10.2}]},{icon:"battery_2_bar",label:"▪▪",ranges:[{f:6.8,t:7.4},{f:10.2,t:11.1}]},{icon:"battery_3_bar",label:"▪▪▪",ranges:[{f:7.4,t:7.5},{f:11.1,t:11.25}]},{icon:"battery_4_bar",label:"▪▪▪▪",ranges:[{f:7.5,t:7.8},{f:11.25,t:11.7}]}],S=[{desc:"Idle",sub:["bt_neutral"]},{desc:"Discovering",sub:["bt_connecting"]},{desc:"Discovered",sub:["bt_connecting"]},{desc:"Unconnected",sub:["bt_disconnected"]},{desc:"Connecting",sub:["bt_connecting"]},{desc:"Connected",sub:["bt_connected","play_arrow","bt_playing","pause","stop"]},{desc:"Disconnecting",sub:["bt_disconnected"]}],v={OK:0,FAIL:1,DISC:2,LOST:3,RESTORE:4,ETH:5},b=["eRunning","eReady","eBlocked","eSuspended","eDeleted"];let O={NONE:0,REBOOT_TO_RECOVERY:2,SET_FWURL:5,FLASHING:6,DONE:7,UPLOADING:8,ERROR:9,UPLOADCOMPLETE:10,_state:-1,olderRecovery:!1,statusText:"",flashURL:"",flashFileName:"",statusPercent:0,Completed:!1,recovery:!1,prevRecovery:!1,updateModal:new c.Modal(document.getElementById("otadiv"),{}),reset:function(){return this.olderRecovery=!1,this.statusText="",this.statusPercent=-1,this.flashURL="",this.flashFileName=void 0,this.UpdateProgress(),r("#rTable tr.release").removeClass("table-success table-warning"),r(".flact").prop("disabled",!1),r("#flashfilename")[0].value=null,r("#fw-url-input")[0].value=null,this.isStateError()||(r("span#flash-status").html(""),r("#fwProgressLabel").parent().removeClass("bg-danger")),this._state=this.NONE,this},isStateUploadComplete:function(){return this._state==this.UPLOADCOMPLETE},isStateError:function(){return this._state==this.ERROR},isStateNone:function(){return this._state==this.NONE},isStateRebootRecovery:function(){return this._state==this.REBOOT_TO_RECOVERY},isStateSetUrl:function(){return this._state==this.SET_FWURL},isStateFlashing:function(){return this._state==this.FLASHING},isStateDone:function(){return this._state==this.DONE},isStateUploading:function(){return this._state==this.UPLOADING},init:function(){return this._state=this.NONE,this},SetStateError:function(){return this._state=this.ERROR,r("#fwProgressLabel").parent().addClass("bg-danger"),this},SetStateNone:function(){return this._state=this.NONE,this},SetStateRebootRecovery:function(){return this._state=this.REBOOT_TO_RECOVERY,this.SetStatusText("Starting recovery mode."),r.ajax({url:"/recovery.json",context:this,dataType:"text",method:"POST",cache:!1,contentType:"application/json; charset=utf-8",data:JSON.stringify({timestamp:Date.now()}),error:function(e,t,o){var r;this.setOTAError(`Unexpected error while trying to restart to recovery. (status=${null!==(r=e.status)&&void 0!==r?r:""}, error=${null!=o?o:""} ) `)},complete:function(e){this.SetStatusText("Waiting for system to boot.")}}),this},SetStateSetUrl:function(){return this._state=this.SET_FWURL,this.statusText="Sending firmware download location.",D({fwurl:{value:this.flashURL,type:33}}),this},SetStateFlashing:function(){return this._state=this.FLASHING,this},SetStateDone:function(){return this._state=this.DONE,this.reset(),this},SetStateUploading:function(){return this._state=this.UPLOADING,this.SetStatusText("Sending file to device.")},SetStateUploadComplete:function(){return this._state=this.UPLOADCOMPLETE,this},isFlashExecuting:function(){return!0==(this._state!=this.UPLOADING&&(""!==this.statusText||this.statusPercent>=0))},toString:function(){return Object.keys(this).find((e=>this[e]===this._state))},setOTATargets:function(){this.flashURL="",this.flashFileName="",this.flashURL=r("#fw-url-input").val();let e=r("#flashfilename")[0].files;return e.length>0&&(this.flashFileName=e[0]),0==this.flashFileName.length&&0==this.flashURL.length&&this.setOTAError("Invalid url or file. Cannot start OTA"),this},setOTAError:function(e){return this.SetStateError().SetStatusPercent(0).SetStatusText(e).reset(),this},ShowDialog:function(){return this.isStateNone()||(this.updateModal.show(),r(".flact").prop("disabled",!0)),this},SetStatusPercent:function(e){var t=this.statusPercent!=e;return this.statusPercent=e,t&&(this.isStateUploading()||this.isStateFlashing()||this.SetStateFlashing(),100==e&&(this.isStateFlashing()?this.SetStateDone():this.isStateUploading()&&(this.statusPercent=0,this.SetStateFlashing())),this.UpdateProgress().ShowDialog()),this},SetStatusText:function(e){var t=this.statusText!=e;return this.statusText=e,t&&(r("span#flash-status").html(this.statusText),this.ShowDialog()),this},UpdateProgress:function(){return r(".progress-bar").css("width",this.statusPercent+"%").attr("aria-valuenow",this.statusPercent).text(this.statusPercent+"%"),r(".progress-bar").html((this.isStateDone()?100:this.statusPercent)+"%"),this},StartOTA:function(){return this.logEvent(this.StartOTA.name),r("#fwProgressLabel").parent().removeClass("bg-danger"),this.setOTATargets(),this.isStateError()||(k?this.SetStateFlashing().TargetReadyStartOTA():this.SetStateRebootRecovery()),this},UploadLocalFile:function(){this.SetStateUploading();const e=new XMLHttpRequest;var t=this.HandleUploadProgressEvent.bind(this),o=this.setOTAError.bind(this);e.upload.addEventListener("progress",t,!1),e.onreadystatechange=function(){4===e.readyState&&(0!==e.status&&404!==e.status||o("Upload Failed. Recovery version might not support uploading. Please use web update instead."))},e.open("POST","/flash.json",!0),e.send(this.flashFileName)},TargetReadyStartOTA:function(){return k&&this.prevRecovery&&!this.isStateRebootRecovery()&&!this.isStateFlashing()?this:(this.logEvent(this.TargetReadyStartOTA.name),k?(this.prevRecovery=!0,void(""!==this.flashFileName?this.UploadLocalFile():""!=this.flashURL?this.SetStateSetUrl():this.setOTAError("Invalid URL or file name while trying to start the OTa process"))):(console.error("Event TargetReadyStartOTA fired in the wrong mode "),this))},HandleUploadProgressEvent:function(e){this.logEvent(this.HandleUploadProgressEvent.name),this.SetStateUploading().SetStatusPercent(Math.round(e.loaded/e.total*100)).SetStatusText("Uploading file to device")},EventTargetStatus:function(e){var t,o;this.isStateNone()||this.logEvent(this.EventTargetStatus.name),null!==(t=e.ota_pct)&&void 0!==t&&t&&(this.olderRecovery=!0,this.SetStatusPercent(e.ota_pct)),""!=(null!==(o=e.ota_dsc)&&void 0!==o?o:"")&&(this.olderRecovery=!0,this.SetStatusText(e.ota_dsc)),null!=e.recovery&&(this.recovery=1===e.recovery),this.isStateRebootRecovery()&&this.recovery&&this.TargetReadyStartOTA()},EventOTAMessageClass:function(e){this.logEvent(this.EventOTAMessageClass.name);var t=JSON.parse(e);this.SetStatusPercent(t.ota_pct).SetStatusText(t.ota_dsc)},logEvent:function(e){console.log(`${e}, flash state ${this.toString()}, recovery: ${this.recovery}, ota pct: ${this.statusPercent}, ota desc: ${this.statusText}`)}},F=!1,I=!1,P=2500;function D(e){let t={timestamp:Date.now(),config:e};r.ajax({url:"/config.json",dataType:"text",method:"POST",cache:!1,contentType:"application/json; charset=utf-8",data:JSON.stringify(t),error:T})}function E(e){const t={};let o,r,n="";const i=e.match(/("[^"]+"|'[^']+'|\S+)/g)||[];let s=0;for(;s0&&(t=t.substring(0,t.indexOf(" "))));return t}(t),r=function(e){let t;e.n&&(t=e.n.replace(/"/g,"").replace(/'/g,""));return t}(t);let a={btname:null,n:null};if(t.o&&"BT"===o.toUpperCase()){let e=E(t.o);e.name&&(a.btname=e.name),delete t.o}return t.n&&(a.n=t.n,delete t.n),{name:r,output:o,options:t,otherValues:n,otherOptions:a}}function w(){return V.hasOwnProperty("ip")&&"0.0.0.0"!=V.ip&&""!=V.ip}function G(e){return w()?e.icon:e.label}function W(e){r("#o_type").children("span").css({display:"none"});let t=!1;e!==H&&(t=!0,H=e),r("#"+H).prop("checked",!0),r("#o_"+H).css({display:"inline"}),t&&Object.entries(A[H]).forEach((([e,t])=>{r(`#cmd_opt_${e}`).val(t)}))}function T(e,t,o){console.log(e.status),console.log(o),""!==o&&Fe(o,"MESSAGING_ERROR")}function R(e,t,o,n=!1){let i="table-success";"MESSAGING_WARNING"===t?i="table-warning":"MESSAGING_ERROR"===t&&(i="table-danger"),r("#toast_"+e).removeClass("table-success").removeClass("table-warning").removeClass("table-danger").addClass(i).addClass("show");let s=o.substring(0,o.length-1).encodeHTML().replace(/\n/g,"
");s=(r("#msg_"+e).html().length>0&&n?r("#msg_"+e).html()+"
":"")+s,r("#msg_"+e).html(s)}let _="https://api.github.com/repos/sle118/squeezelite-esp32/releases",k=!1,N=!1,z="";const A={i2s:{b:"500:2000",C:"30",W:"",Z:"96000",o:"I2S"},spdif:{b:"500:2000",C:"30",W:"",Z:"48000",o:"SPDIF"},bt:{b:"500:2000",C:"30",W:"",Z:"44100",o:"BT"}};let x,j={codecs:["flac","pcm","mp3","ogg","aac","wma","alac","dsd","mad","mpg"]},L=null,$=0,U="MESSAGING_INFO",J=NaN;var H="";let V,Y,K="",q="Squeezelite-ESP32",X="",Z=q,Q=16,ee="",te=q,oe="",re="#cfg-audio-bt_source-sink_name",ne="",ie="";const se={CONN:0,MAN:1,STS:2};function ae(e,t){return new Promise(((o,r)=>{e.then((e=>setTimeout((()=>o(e)),t)),(e=>setTimeout((()=>r(e)),t)))}))}function pe(e){const t={};r("input.nvs").each((function(o,r){const n=r,i=n.attributes.getNamedItem("nvs_type");if(!e&&i){const e=parseInt(i.value,10);if(""!==n.id){const o=e<=M.NVS_TYPE_I64?parseInt(n.value,10):n.value;t[n.id]={value:o,type:e}}}else""!==n.id&&(t[n.id]=n.value)}));const o=r("#nvs-new-key").val(),n=r("#nvs-new-value").val();return o&&""!==o&&(t[o]=e?n:{value:n,type:M.NVS_TYPE_I8}),t}function le(e,t,o="reboot"){const n=`/${o}.json`;r("tbody#tasks").empty(),r("#tasks_sect").css("visibility","collapse"),ae(Promise.resolve({cmdname:t,url:n}),e).then((function(e){console.log("now triggering reboot"),r("button[onclick*='handleReboot']").addClass("rebooting"),r.ajax({complete:function(){console.log("reboot call completed"),ae(Promise.resolve(e),6e3).then((function(e){}))}})}))}function ue(e){R("cfg-audio-tmpl","MESSAGING_INFO","Saving.\n",!1);let t=`squeezelite -o ${H} `;r(".sqcmd").each((function(){let{opt:e,val:o}=C(r(this));if(e&&e.length>0&&"boolean"==typeof o||"string"==typeof o&&o.length>0){o="boolean"==typeof o?"":o,t+=`${":"===e?e:` -${e} `} ${o}`}}));const o=r("#cmd_opt_R input[name=resample]:checked");o.length>0&&""!==o.attr("suffix")&&(t+=o.attr("suffix"),r("#resample_i").is(":checked")&&"true"==o.attr("aint")&&(t+=r("#resample_i").attr("suffix"))),"bt"===H&&R("cfg-audio-tmpl","MESSAGING_INFO","Remember to configure the Bluetooth audio device name.\n",!0);const n={timestamp:Date.now(),config:{autoexec1:{value:t,type:M.NVS_TYPE_STR}}};r.ajax({url:"/config.json",dataType:"text",method:"POST",cache:!1,contentType:"application/json; charset=utf-8",data:JSON.stringify(n),error:T,complete:function(t){t.responseText&&"OK"===JSON.parse(t.responseText).result?(R("cfg-audio-tmpl","MESSAGING_INFO","Done.\n",!0),e&&le(1500,"cfg-audio-tmpl")):JSON.parse(t.responseText).result?R("cfg-audio-tmpl","MESSAGING_WARNING",JSON.parse(t.responseText).Result+"\n",!0):R("cfg-audio-tmpl","MESSAGING_ERROR",t.statusText+"\n"),console.log(t.responseText)}}),console.log("sent data:",JSON.stringify(n))}function fe(e){return r(".upf").filter((function(){return r(this).text().toUpperCase()===e.toUpperCase()})).length>0&&(r("#splf").val(e).trigger("input"),!0)}function ce(e,t){const o=`cmd_opt_${e}`;let n=`${o}-error`,i=r(`#${n}`),s=r(`#${o}`);return i&&0!=i.length||(s.after(`
`),i=r(`#${n}`)),0==t.length?(i.hide(),s.removeClass("is-invalid"),s.addClass("is-valid"),i.text("")):(i.show(),i.text(t),s.removeClass("is-valid"),s.addClass("is-invalid")),i}function de(e){return e>=-55?{label:"****",icon:"signal_wifi_statusbar_4_bar"}:e>=-60?{label:"***",icon:"network_wifi_3_bar"}:e>=-65?{label:"**",icon:"network_wifi_2_bar"}:e>=-70?{label:"*",icon:"network_wifi_1_bar"}:{label:".",icon:"signal_wifi_statusbar_null"}}function ge(){(null==V?void 0:V.urc)!==v.ETH&&(r.ajaxSetup({timeout:3e3}),r.getJSON("/scan.json",(function(){return a(this,void 0,void 0,(function*(){var e;yield(e=2e3,new Promise((t=>setTimeout(t,e)))),r.getJSON("/ap.json",(function(e){e.length>0&&(e.sort((function(e,t){const o=e.rssi,r=t.rssi;return or?-1:0})),L=e,he(L))}))}))})))}function Ce(e,t,o){const r=de(t),n={label:0==o?"🔓":"🔒",icon:0==o?"no_encryption":"lock"};return`${e}\n ${G(r)}\n \t\n ${G(n)}\n `}function he(e){var t;let o="";if(r("#wifiTable tr td:first-of-type").text(""),r("#wifiTable tr").removeClass("table-success table-warning"),e&&(e.forEach((function(e){o+=Ce(e.ssid,e.rssi,e.auth)})),r("#wifiTable").html(o)),0==r(".manual_add").length&&(r("#wifiTable").append(Ce("Manual add",0,0)),r("#wifiTable tr:last").addClass("table-light text-dark").addClass("manual_add")),!V.ssid||V.urc!==v.OK&&V.urc!==v.RESTORE)(null==V?void 0:V.urc)!==v.ETH&&r("span#foot-if").html("");else{const e=`#wifiTable td:contains("${V.ssid}")`;0==r(e).filter((function(){return r(this).text()===V.ssid})).length&&r("#wifiTable").prepend(`${Ce(V.ssid,null!==(t=V.rssi)&&void 0!==t?t:0,0)}`),r(e).filter((function(){return r(this).text()===V.ssid})).siblings().first().html("✓").parent().addClass(V.urc===v.OK?"table-success":"table-warning"),r("span#foot-if").html(`SSID: ${V.ssid}, IP: ${V.ip}`);const o=de(V.rssi),n=G(o);r("#wifiStsIcon").text(n),r("#wifiStsIcon").attr("aria-label",o.label),r("#wifiStsIcon").attr("icon",o.icon)}}function ye(e){console.debug(`${this.toLocaleString()}\t${e.nme}\t${e.cpu}\t${b[e.st]}\t${e.minstk}\t${e.bprio}\t${e.cprio}\t${e.num}`),r("tbody#tasks").append(`${e.num}${e.nme}${e.cpu}${b[e.st]}${e.minstk}${e.bprio}${e.cprio}`)}function Me(e){return r(`${re} option:contains('${e}')`)}function me(){r.ajaxSetup({timeout:P}),r.getJSON("/messages.json",(function(e){return a(this,void 0,void 0,(function*(){for(const l of e){const e=l.current_time-l.sent_time;var t=new Date;switch(t.setTime(t.getTime()-e),l.class){case"MESSAGING_CLASS_OTA":O.EventOTAMessageClass(l.message);break;case"MESSAGING_CLASS_STATS":var o=JSON.parse(l.message);if(console.debug(t.toLocalShort()+" - Number of running tasks: "+o.ntasks),console.debug(`${t.toLocalShort()}\tname\tcpu\tstate\tminstk\tbprio\tcprio\tnum`),o.tasks){o.tasks;"collapse"===r("#tasks_sect").css("visibility")&&r("#tasks_sect").css("visibility","visible"),r("tbody#tasks").html(""),o.taskList.sort((function(e,t){return t.cpu-e.cpu})).forEach(ye,t)}else"visible"===r("#tasks_sect").css("visibility")&&(r("tbody#tasks").empty(),r("#tasks_sect").css("visibility","collapse"));break;case"MESSAGING_CLASS_SYSTEM":Ie(l,t);break;case"MESSAGING_CLASS_CFGCMD":var n=l.message.split(/([^\n]*)\n(.*)/gs);R(n[1],l.type,n[2],!0);break;case"MESSAGING_CLASS_BT":if(r(re).is("input")){const e=r(re)[0];for(var i=e.attributes,s="",a=0;a `)}JSON.parse(l.message).forEach((function(e){Me(e.name).length>0||(r(re).append(``),Ie({type:l.type,message:`BT Audio device found: ${e.name} RSSI: ${e.rssi} `,class:"",sent_time:0,current_time:0},t)),Me(e.name).attr("data-bs-description",`${e.name} (${e.rssi}dB)`).attr("rssi",e.rssi).attr("value",e.name).text(`${e.name} [${e.rssi}dB]`).trigger("change")}));const e=Array.from(r(re).find("option"));e.sort((function(e,t){const o=parseInt(r(e).attr("rssi"),10),n=parseInt(r(t).attr("rssi"),10);return console.log(`${o} < ${n} ? `),n-o})),r(re).empty().append(e)}}setTimeout(me,P)}))})).fail((function(e,t,o){404==e.status?(r(".orec").hide(),N=!0):T(e,0,o),0==e.status&&0==e.readyState?setTimeout(me,2*P):N||setTimeout(me,P)}))}function Be(e){if(r("#WifiConnectDialog").is(":visible")){if(V.ip&&r("#ipAddress").text(V.ip),V.ssid&&r("#connectedToSSID").text(V.ssid),V.gw&&r("#gateway").text(V.gw),V.netmask&&r("#netmask").text(V.netmask),(void 0===Y.Action||Y.Action&&Y.Action==se.STS)&&(r("*[class*='connecting']").hide(),r(".connecting-status").show()),x.ap_ssid&&r("#apName").text(x.ap_ssid.value),x.ap_pwd&&r("#apPass").text(x.ap_pwd.value),!e)return;switch(e.urc){case v.OK:e.ssid&&e.ssid===Y.ssid&&(r("*[class*='connecting']").hide(),r(".connecting-success").show(),Y.Action=se.STS);break;case v.FAIL:Y.Action!=se.STS&&Y.ssid==e.ssid&&(r("*[class*='connecting']").hide(),r(".connecting-fail").show());break;case v.LOST:break;case v.RESTORE:Y.Action!=se.STS&&Y.ssid!=e.ssid&&(r("*[class*='connecting']").hide(),r(".connecting-fail").show());case v.DISC:}}}function Se(e){r(".material-icons").each((function(t,o){const r=o;r.textContent=r.getAttribute(e?"aria-label":"data-icon")||""}))}function ve(e){Se(!w()),!function(e){return e.urc!==V.urc||e.ssid!==V.ssid||e.gw!==V.gw||e.netmask!==V.netmask||e.ip!==V.ip||e.rssi!==V.rssi}(e)&&e.urc||(V=function(e){var t;return{urc:null!==(t=e.urc)&&void 0!==t?t:0,auth:void 0,pwd:void 0,dhcpname:void 0,Action:void 0,ip:e.ip,ssid:e.ssid,rssi:e.rssi,gw:e.gw,netmask:e.netmask}}(e),r(".if_eth").hide(),r(".if_wifi").hide(),e.urc&&V.urc==v.ETH?(r(".if_eth").show(),V.urc===v.ETH&&r("span#foot-if").html(`Network: Ethernet, IP: ${V.ip}`)):(r(".if_wifi").show(),he())),Be(e)}function be(){r.ajaxSetup({timeout:2e3}),r.getJSON("/status.json",(function(e){var t;if(function(e){var t;1===(null!==(t=e.recovery)&&void 0!==t?t:0)?(k=!0,r(".recovery_element").show(),r(".ota_element").hide(),r("#boot-button").html("Reboot"),r("#boot-form").attr("action","/reboot_ota.json")):(!k&&N&&(N=!1,setTimeout(me,P)),k=!1,r(".recovery_element").hide(),r(".ota_element").show(),r("#boot-button").html("Recovery"),r("#boot-form").attr("action","/recovery.json"))}(e),h(),ve(e),function(e){var t;let o={label:"",icon:""},n="";if(void 0!==e.bt_status&&void 0!==e.bt_sub_status){const r=null===(t=S[e.bt_status])||void 0===t?void 0:t.sub[e.bt_sub_status];r?(o=m[r],n=S[e.bt_status].desc):(o=m.bt_connected,n="Output status")}r("#o_type").attr("title",n),r("#o_bt").html(w()?o.label:o.icon)}(e),O.EventTargetStatus(e),e.depth&&(Q=e.depth,16==Q?r("#cmd_opt_R").show():r("#cmd_opt_R").hide()),e.project_name&&""!==e.project_name&&(Z=e.project_name),e.platform_name&&""!==e.platform_name&&(te=e.platform_name),""===ee&&(ee=Z),""===ee&&(ee="Squeezelite-ESP32"),e.version&&""!==e.version?(q=e.version,r("#navtitle").html(`${ee}${k?"
[recovery]":""}`),r("span#foot-fw").html(`fw: ${q}, mode: ${k?"Recovery":Z}`)):r("span#flash-status").html(""),e.Voltage){const t=function(e){for(const n of B)for(const i of n.ranges)if(t=e,o=i.f,r=i.t,(t-o)*(t-r)<=0)return{label:n.label,icon:n.icon};var t,o,r;return{label:"▪▪▪▪",icon:"battery_full"}}(e.Voltage);r("#battery").html(`${G(t)}`),r("#battery").attr("aria-label",t.label),r("#battery").attr("data-icon",t.icon),r("#battery").show()}else r("#battery").hide();if(""!=(null!==(t=e.message)&&void 0!==t?t:"")&&X!=e.message&&(X=e.message,Fe(e.message,"MESSAGING_INFO")),I=e.is_i2c_locked,I?r("flds-cfg-hw-preset").hide():r("flds-cfg-hw-preset").show(),r("button[onclick*='handleReboot']").removeClass("rebooting"),void 0===ne||e.lms_ip!=ie&&e.lms_ip&&e.lms_port){const t="http://"+e.lms_ip+":"+e.lms_port;ie=e.lms_ip,r.ajax({url:t+"/plugins/SqueezeESP32/firmware/-check.bin",type:"HEAD",dataType:"text",cache:!1,error:function(){ne=""},success:function(){ne=t}})}r("#o_jack").css({display:Number(e.Jack)?"inline":"none"}),setTimeout(be,2e3)})).fail((function(e,t,o){T(e,0,o),0==e.status&&0==e.readyState?setTimeout(be,2*P):setTimeout(be,P)}))}function Oe(e,t,o){return void 0!==e[t]?e[t][o]:""}function Fe(e,t){Ie({message:e,type:t,class:"",sent_time:0,current_time:0},new Date)}function Ie(e,t){let o="table-success";"MESSAGING_WARNING"===e.type?(o="table-warning","MESSAGING_INFO"===U&&(U="MESSAGING_WARNING")):"MESSAGING_ERROR"===e.type&&("MESSAGING_INFO"!==U&&"MESSAGING_WARNING"!==U||(U="MESSAGING_ERROR"),o="table-danger"),++$>0&&(r("#msgcnt").removeClass("badge-success"),r("#msgcnt").removeClass("badge-warning"),r("#msgcnt").removeClass("badge-danger"),r("#msgcnt").addClass({MESSAGING_INFO:"badge-success",MESSAGING_WARNING:"badge-warning",MESSAGING_ERROR:"badge-danger"}[U]),r("#msgcnt").text($)),r("#syslogTable").append(""+t.toLocalShort()+""+e.message.encodeHTML()+"")}r((function(){r(".material-icons").each((function(e,t){t.setAttribute("data-icon",t.textContent||"")})),Se(!0),h(),O.init(),r("#fw-url-input").on("input",(function(){const e=r(this).val().toString();e.length>8&&(e.startsWith("http://")||e.startsWith("https://"))?r("#start-flash").show():r("#start-flash").hide()})),r(".upSrch").on("input",(function(){const e=this,t=e.value;r("#rTable tr").removeClass(e.id+"_hide"),t.length>0&&r(`#rTable td:nth-child(${r(e).parent().index()+1})`).filter((function(){return!r(this).text().toUpperCase().includes(t.toUpperCase())})).parent().addClass(this.id+"_hide"),r('[class*="_hide"]').hide(),r("#rTable tr").not('[class*="_hide"]').show()})),setTimeout(ge,1500),r("#options input").on("input",(function(){const{opt:e,val:t}=C(this);if("c"===e||"e"===e){const o=t.toString().split(",").map((function(e){return e.trim()})).filter((function(e){return!j.codecs.includes(e)}));ce(e,o.length>0?`Invalid codec(s) ${o.join(", ")}`:"")}if("m"===e){ce(e,/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/.test(t.toString())?"":"Invalid MAC address")}if("r"===e){ce(e,/^(\d+\.?\d*|\.\d+)-(\d+\.?\d*|\.\d+)$|^(\d+\.?\d*)$|^(\d+\.?\d*,)+\d+\.?\d*$/.test(t.toString())?"":`Invalid rate(s) ${t}. Acceptable format: |-|,,`)}})),r("#WifiConnectDialog")[0].addEventListener("shown.bs.modal",(function(e){r("*[class*='connecting']").hide(),(null==e?void 0:e.relatedTarget)&&(Y.Action=se.CONN,r(e.relatedTarget).children("td:eq(1)").text()==V.ssid?Y.Action=se.STS:r(e.relatedTarget).is(":last-child")?(Y.Action=se.MAN,Y.ssid="",r("#manual_ssid").val(Y.ssid)):(Y.ssid=r(e.relatedTarget).children("td:eq(1)").text(),r("#manual_ssid").val(Y.ssid))),Y.Action!==se.STS?(r(".connecting-init").show(),r("#manual_ssid").trigger("focus")):Be()})),r("#WifiConnectDialog")[0].addEventListener("hidden.bs.modal",(function(){r("#WifiConnectDialog input").val("")})),r("#uCnfrm")[0].addEventListener("shown.bs.modal",(function(){r("#selectedFWURL").text(r("#fw-url-input").val().toString())})),r("input#show-commands")[0].checked=1===J,r('a[href^="#tab-commands"]').hide(),r("#load-nvs").on("click",(function(){r("#nvsfilename").trigger("click")})),r("#nvsfilename").on("change",(function(){const e=this;if("function"!=typeof window.FileReader)throw"The file API isn't supported on this browser.";if(!e.files)throw"This browser does not support the `files` property of the file input.";if(!e.files[0])return;const t=e.files[0];let o=new FileReader;o.onload=function(e){let t;try{t=JSON.parse(e.target.result.toString())}catch(e){alert("Parsing failed!\r\n "+e)}r("input.nvs").each((function(e,o){r(this).parent().removeClass("bg-warning").removeClass("bg-success"),t[o.id]&&(t[o.id]!==o.value?(console.log("Changed "+o.id+" "+o.value+"==>"+t[o.id]),r(this).parent().addClass("bg-warning"),r(this).val(t[o.id])):r(this).parent().addClass("bg-success"))})),r("input.nvs").children(".bg-warning")&&alert("Highlighted values were changed. Press Commit to change on the device")},o.readAsText(t),e.value=null})),r("#clear-syslog").on("click",(function(){$=0,U="MESSAGING_INFO",r("#msgcnt").text(""),r("#syslogTable").html("")})),r("#ok-credits").on("click",(function(){r("#credits").slideUp("fast",(function(){})),r("#app").slideDown("fast",(function(){}))})),r("#acredits").on("click",(function(e){e.preventDefault(),r("#app").slideUp("fast",(function(){})),r("#credits").slideDown("fast",(function(){}))})),r("input#show-commands").on("click",(function(){const e=this;e.checked=!!e.checked,e.checked?(r('a[href^="#tab-commands"]').show(),J=1):(J=0,r('a[href^="#tab-commands"]').hide())})),r("#disable-squeezelite").on("click",(function(){if(this.checked){const e=r("#cmd_opt_s").val();r("#cmd_opt_s").data("originalValue",e),r("#cmd_opt_s").val("-disable")}else{const e=r("#cmd_opt_s").data("originalValue");r("#cmd_opt_s").val(e||"")}})),r("input#show-nvs").on("click",(function(){const e=this;e.checked=!!e.checked,u.default.set("show-nvs",e.checked?"Y":"N"),h()})),r("#btn_reboot_recovery").on("click",(function(){g("recovery")})),r("#btn_reboot").on("click",(function(){g("reboot")})),r("#btn_flash").on("click",(function(){d()})),r("#save-autoexec1").on("click",(function(){ue(!1)})),r("#commit-autoexec1").on("click",(function(){ue(!0)})),r("#btn_disconnect").on("click",(function(){V={auth:void 0,pwd:void 0,dhcpname:void 0,Action:void 0,ip:void 0,ssid:void 0,rssi:void 0,gw:void 0,netmask:void 0,urc:0},he(),r.ajax({url:"/connect.json",dataType:"text",method:"DELETE",cache:!1,contentType:"application/json; charset=utf-8",data:JSON.stringify({timestamp:Date.now()})})})),r("#btnJoin").on("click",(function(){Y.ssid=r("#manual_ssid").val().toString(),Y.pwd=r("#manual_pwd").val().toString(),Y.dhcpname=r("#dhcp-name2").val().toString(),r("*[class*='connecting']").hide(),r("#ssid-wait").text(Y.ssid),r(".connecting").show(),r.ajax({url:"/connect.json",dataType:"text",method:"POST",cache:!1,contentType:"application/json; charset=utf-8",data:JSON.stringify({timestamp:Date.now(),ssid:Y.ssid,pwd:Y.pwd}),error:T})})),r("#reboot_nav").on("click",(function(){g("reboot")})),r("#reboot_ota_nav").on("click",(function(){g("reboot_ota")})),r("#save-as-nvs").on("click",(function(){const e=pe(!0),t=document.createElement("a");t.href=URL.createObjectURL(new Blob([JSON.stringify(e,null,2)],{type:"text/plain"})),t.setAttribute("download","nvs_config_"+K+"_"+Date.now()+"json"),document.body.appendChild(t),t.click(),document.body.removeChild(t)})),r("#save-nvs").on("click",(function(){D(pe(!1))})),r("#fwUpload").on("click",(function(){0===document.getElementById("flashfilename").files.length?alert("No file selected!"):(r("#fw-url-input").value=null,O.StartOTA())})),r("[name=output-tmpl]").on("click",(function(){W(this.id)})),r("#chkUpdates").on("click",(function(){r("#rTable").html(""),r.getJSON(_,(function(e){const t=[];e.forEach((function(e){const o=e.name.split("#")[3];t.includes(o)||t.push(o)}));let o="";t.forEach((function(e){o+='"})),r("#fwbranch").append(o),e.forEach((function(e){let t="";e.assets.forEach((function(e){e.name.match(/\.bin$/)&&(t=e.browser_download_url)}));const o=e.name.split("#"),n=o[0],i=o[2],s=o[3];var a=n.substr(n.lastIndexOf("-")+1);a="32"==a||"16"==a?a:"";let p=e.body;p=p.replace(/'/gi,'"'),p=p.replace(/[\s\S]+(### Revision Log[\s\S]+)### ESP-IDF Version Used[\s\S]+/,"$1"),p=p.replace(/- \(.+?\) /g,"- ").encodeHTML(),r("#rTable").append(`\n ${n}${new Date(e.created_at).toLocalShort()}\n ${i}${s}${a}`)})),r("#searchfw").css("display","inline"),fe(te)||fe(Z),r("#rTable tr.release").on("click",(function(){var e=this.getAttribute("fwurl");ne&&(e=e.replace(/.*\/download\//,ne+"/plugins/SqueezeESP32/firmware/")),r("#fw-url-input").val(e),r("#start-flash").show(),r("#rTable tr.release").removeClass("table-success table-warning"),r(this).addClass("table-success table-warning")}))})).fail((function(){alert("failed to fetch release history!")}))})),r("#fwcheck").on("click",(function(){r("#releaseTable").html(""),r("#fwbranch").empty(),r.getJSON(_,(function(e){let t=0;const o=[];let n;e.forEach((function(e){const t=e.name.split("#")[3];o.includes(t)||o.push(t)})),o.forEach((function(e){n+=``})),r("#fwbranch").append(n),e.forEach((function(e){let o="";e.assets.forEach((function(e){e.name.match(/\.bin$/)&&(o=e.browser_download_url)}));const n=e.name.split("#"),i=n[0],s=n[1],a=n[2],p=n[3];let l=e.body;l=l.replace(/'/gi,'"'),l=l.replace(/[\s\S]+(### Revision Log[\s\S]+)### ESP-IDF Version Used[\s\S]+/,"$1"),l=l.replace(/- \(.+?\) /g,"- ");const u=t++>6?" hide":"";r("#releaseTable").append(`${i}${new Date(e.created_at).toLocalShort()}${a}${s}${p}`)})),t>7&&(r("#releaseTable").append(""),r("#showallbutton").on("click",(function(){r("tr.hide").removeClass("hide"),r("tr#showall").addClass("hide")}))),r("#searchfw").css("display","inline")})).fail((function(){alert("failed to fetch release history!")}))})),r("#updateAP").on("click",(function(){ge(),console.log("refresh AP")})),r.ajaxSetup({timeout:7e3}),r.getJSON("/config.json",(function(e){r("#nvsTable tr").remove();const t=e.config?e.config:e;x=t,z="",Object.keys(t).sort().forEach((function(e){let o=t[e].value;"autoexec1"===e?function(e){const t=E(e);if(t.output.toUpperCase().startsWith("I2S")?W("i2s"):t.output.toUpperCase().startsWith("SPDIF")?W("spdif"):t.output.toUpperCase().startsWith("BT")&&(t.otherOptions.btname&&(z=t.otherOptions.btname),W("bt")),Object.keys(t.options).forEach((function(e){const o=t.options[e];r(`#cmd_opt_${e}`).hasOwnProperty("checked")?"boolean"==typeof o&&(r(`#cmd_opt_${e}`)[0].checked=o):r(`#cmd_opt_${e}`).val(o)})),t.options.hasOwnProperty("u")){const[e,o]=t.options.u.split(":");r(`#resample_${e}`).prop("checked",!0),o&&r("#resample_i").prop("checked",!0)}t.options.hasOwnProperty("s")&&("-disable"===t.options.s?r("#disable-squeezelite")[0].checked=!0:r("#disable-squeezelite")[0].checked=!1)}(o):"host_name"===e?(o=o.replaceAll('"',""),r("input#dhcp-name1").val(o),r("input#dhcp-name2").val(o),0==r("#cmd_opt_n").length&&r("#cmd_opt_n").val(o),document.title=o,K=o):"rel_api"===e?_=o:"enable_airplay"===e?r("#s_airplay").css({display:y(o)?"inline":"none"}):"enable_cspot"===e?r("#s_cspot").css({display:y(o)?"inline":"none"}):"preset_name"==e?oe=o:"board_model"==e&&(ee=o),r("tbody#nvsTable").append(`${e}`),r("input#"+e).val(t[e].value)})),z.length>0&&r("#cfg-audio-bt_source-sink_name").val(z),r("tbody#nvsTable").append(""),e.gpio?(r("#pins").show(),r("tbody#gpiotable tr").remove(),e.gpio.forEach((function(e){r("tbody#gpiotable").append(`${e.group}${e.name}${e.gpio}${e.fixed?"Fixed":"Configuration"}`)}))):r("#pins").hide()})).fail((function(e,t,o){T(e,0,o)})),r.ajaxSetup({timeout:7e3}),r.getJSON("/commands.json",(function(e){console.log(e),r(".orec").show(),e.commands.forEach((function(t){if(0===r("#flds-"+t.name).length){const o=t.name.split("-"),n="cfg"===o[0],i="#tab-"+o[0]+"-"+o[1];let s="";s+=`
${t.help.encodeHTML().replace(/\n/g,"
")}
`,t.argtable&&t.argtable.forEach((function(o){let r=o.datatype||"";const n=t.name+"-"+o.longopts,i=Oe(e.values,t.name,o.longopts);let a=`hasvalue=${o.hasvalue} `;a+='longopts="'+o.longopts+'" ',a+='shortopts="'+o.shortopts+'" ',a+="checkbox="+o.checkbox+" ",a+='cmdname="'+t.name+'" ',a+=`id="${n}" name="${n}" hasvalue="${o.hasvalue}" `;let p=o.mincount>0?"bg-success":"";"hidden"===o.glossary&&(a+=' style="visibility: hidden;"'),o.checkbox?s+=`
`:(s+=`
`,r.includes("|")?(p=r.startsWith("+")?" multiple ":"",r=r.replace("<","").replace("=","").replace(">",""),s+=`"):s+=``),s+=`${o.checkbox?"
":""}Previous value: ${o.checkbox?i?"Checked":"Unchecked":i||""}${o.checkbox?"":"
"}`})),s+=`
\n `,s+=n?`\n`:``,s+="
",n?r(i).append(s):r("#commands-list").append(s)}})),r(".sclk").off("click").on("click",(function(){window.runCommand(this,!1)})),r(".cclk").off("click").on("click",(function(){window.runCommand(this,!0)})),e.commands.forEach((function(t){r("[cmdname="+t.name+"]:input").val(""),r("[cmdname="+t.name+"]:checkbox").prop("checked",!1),t.argtable&&t.argtable.forEach((function(o){const n="#"+t.name+"-"+o.longopts;if(o.checkbox)r(n)[0].checked=Oe(e,t.name,o.longopts);else{let i=Oe(e,t.name,o.longopts);void 0!==i&&r(n).val(i.toString()).trigger("change"),0===r(n)[0].value.length&&(o.datatype||"").includes("|")&&(r(n)[0].value="--")}}))})),0!=r("#cfg-hw-preset-model_config").length&&(F||(F=!0,r("#cfg-hw-preset-model_config").html(""),r.getJSON("https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/",{_:(new Date).getTime()},(function(e){r.each(e,(function(e,t){r("#cfg-hw-preset-model_config").append(``),""!==oe&&oe==t.name&&r("#cfg-hw-preset-model_config").val(oe)})),""!==oe&&r("#prev_preset").show().val(oe)})).fail((function(e,t,o){const r=t+", "+o;console.log("Request Failed: "+r)}))))})).fail((function(e,t,o){404==e.status?r(".orec").hide():T(e,0,o),r("#commands-list").empty()})),me(),be()})),window.setURL=function(e){let t=e.dataset.url;r('[data-bs-url^="http"]').addClass("btn-success").removeClass("btn-danger"),r('[data-bs-url="'+t+'"]').addClass("btn-danger").removeClass("btn-success"),ne&&(t=t.replace(/.*\/download\//,ne+"/plugins/SqueezeESP32/firmware/")),r("#fwurl").val(t)},window.runCommand=function(e,t){let o=e.getAttribute("cmdname");R(o,"MESSAGING_INFO","Executing.",!1);const n=document.getElementById("flds-"+o),i=null==n?void 0:n.querySelectorAll("select,input");if("cfg-hw-preset"===o)return function(e,t){const o=JSON.parse(e[0].value),n=e[0].getAttribute("cmdname");console.log(`selected model: ${o.name}`);let i={timestamp:Date.now(),config:{model_config:{value:o.name,type:33}}};for(const[e,t]of Object.entries(o.config)){const o="string"==typeof t||t instanceof String?t:JSON.stringify(t);i.config[e]={value:o.toString(),type:M.NVS_TYPE_STR},R(n,"MESSAGING_INFO",`Setting ${e}=${o} `,!0)}R(n,"MESSAGING_INFO","Committing ",!0),r.ajax({url:"/config.json",dataType:"text",method:"POST",cache:!1,contentType:"application/json; charset=utf-8",data:JSON.stringify(i),error:function(e,t,o){T(e,0,o),R(n,"MESSAGING_ERROR",`Unexpected error ${""!==o?o:"with return status = "+e.status} `,!0)},success:function(e){R(n,"MESSAGING_INFO","Saving complete ",!0),console.log(e),t&&le(2500,n)}})}(i,t);if(o+=" ",n)for(const e of i){let t="",r="";const n="SELECT"===e.tagName,i="true"===e.getAttribute("hasvalue"),s=n&&"--"!==e.value||!n&&""!==e.value;if(!i||i&&s){const n=e.getAttribute("longopts"),s=e.getAttribute("shortopts");null!==n&&"undefined"!==n?r+="--"+n:null!==s&&"undefined"!==s&&(r="-"+s),i?(t=/\s/.test(e.value)?'"':"",o+=`${r} ${t}${e.value}${t} `):e.checked&&(o+=`${r} `)}}console.log(o);const s={timestamp:Date.now(),command:o};r.ajax({url:"/commands.json",dataType:"text",method:"POST",cache:!1,contentType:"application/json; charset=utf-8",data:JSON.stringify(s),error:function(e,t,o){var r=JSON.parse(this.data).command;404==e.status?R(r.substr(0,r.indexOf(" ")),"MESSAGING_ERROR",""+(k?"Limited recovery mode active. Unsupported action ":"Unexpected error while processing command"),!0):(T(e,0,o),R(r.substr(0,r.indexOf(" ")-1),"MESSAGING_ERROR",`Unexpected error ${""!==o?o:"with return status = "+e.status}`,!0))},success:function(o){r(".orec").show(),console.log(o),"Success"===JSON.parse(o).Result&&t&&le(2500,e.getAttribute("cmdname"))}})}},861:e=>{"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAb1BMVEXIycuswsKMjI4rqqZyc3RQlpQ6jIEmJifW2dq5ursppJ8Om4zC0NAFdGYmmpb///8Hg3O4x8cHkoEggX0jko5Ks6/P0dM5r6ocoZb3+PgiiYVevrp/y8bg4uOS09FtxMDs7+7M6um529qoysik2tiNn72gAAAAF3RSTlP94Fr/Wf39BP26/////////////////kibhL0AAAGjSURBVDjLbZMJkoMgEEWtmETEJWpkiSC45P5nnF4wk7HmW2jLfzYIdFYUxbXUYp5nIbTOUFoLAR2ivIKZFQXYuu6TahSHmdAlAqWub0/QNI1jSxrHacKeWw9EdtH1xHbbyiRgCJn67JqVAr9nO2fJnBDMoUuYEvsfmxnJBM66Zj8/iYmaAPKlOvRNJAC/fz8OefINEAngAbYPEMiHTJCCAZrACciVMpCCgDEBKwsAowymMO3IAP3Btqa5vYJx0ZlcOSUZaE/AWznvnTHOyfZ/wMUQvAIg/wb27QNEH94BgGj+APsZiF8AXAhQQEMwkIYYLW7xvsENoyUoF0I0ysf0F2O743kDQNXzXM8+j8Eb6byzDEz7gtpsO1PgrXG5Nd6btNTP+YXarKTny1uQ9JiAN6vbqT9au+BzMQjAWtlq6BiYttdjiVVVqfXxWFWFkk6Cz0DTdYOFPmpHAAK/YQCJoTppQJ8A3TAxVAAhR439Bg5tKe7NgSDEje3mDsf+ovuGCUbYZb/BwoHS6ykHMYfo/U6lx8Xb/+qo3U/x/lf+VP9c/j9c3zy20WEMxgAAAABJRU5ErkJggg=="}},o={};function r(e){var n=o[e];if(void 0!==n)return n.exports;var i=o[e]={id:e,loaded:!1,exports:{}};return t[e].call(i.exports,i,i.exports,r),i.loaded=!0,i.exports}r.m=t,e=[],r.O=(t,o,n,i)=>{if(!o){var s=1/0;for(u=0;u=i)&&Object.keys(r.O).every((e=>r.O[e](o[p])))?o.splice(p--,1):(a=!1,i0&&e[u-1][2]>i;u--)e[u]=e[u-1];e[u]=[o,n,i]},r.d=(e,t)=>{for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e={826:0};r.O.j=t=>0===e[t];var t=(t,o)=>{var n,i,[s,a,p]=o,l=0;if(s.some((t=>0!==e[t]))){for(n in a)r.o(a,n)&&(r.m[n]=a[n]);if(p)var u=p(r)}for(t&&t(o);lr(607)));n=r.O(n)})(); +//# sourceMappingURL=index.dd7cd3.bundle.js.map \ No newline at end of file diff --git a/components/wifi-manager/webapp/dist/js/index.dd7cd3.bundle.js.gz b/components/wifi-manager/webapp/dist/js/index.dd7cd3.bundle.js.gz new file mode 100644 index 00000000..9c899550 Binary files /dev/null and b/components/wifi-manager/webapp/dist/js/index.dd7cd3.bundle.js.gz differ diff --git a/components/wifi-manager/webapp/dist/js/index.dd7cd3.bundle.js.map b/components/wifi-manager/webapp/dist/js/index.dd7cd3.bundle.js.map new file mode 100644 index 00000000..038307be --- /dev/null +++ b/components/wifi-manager/webapp/dist/js/index.dd7cd3.bundle.js.map @@ -0,0 +1 @@ +{"version":3,"file":"./js/index.dd7cd3.bundle.js","mappings":"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","sources":["webpack://squeezelite-esp32/webpack/runtime/chunk loaded","webpack://squeezelite-esp32/./src/js/proto/configuration_pb.js","webpack://squeezelite-esp32/./src/js/proto/nanopb_pb.js","webpack://squeezelite-esp32/./src/index.ts","webpack://squeezelite-esp32/./src/js/custom.ts","webpack://squeezelite-esp32/webpack/bootstrap","webpack://squeezelite-esp32/webpack/runtime/define property getters","webpack://squeezelite-esp32/webpack/runtime/global","webpack://squeezelite-esp32/webpack/runtime/hasOwnProperty shorthand","webpack://squeezelite-esp32/webpack/runtime/make namespace object","webpack://squeezelite-esp32/webpack/runtime/node module decorator","webpack://squeezelite-esp32/webpack/runtime/jsonp chunk loading","webpack://squeezelite-esp32/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// source: configuration.proto\n/**\n * @fileoverview\n * @enhanceable\n * @suppress {missingRequire} reports error on implicit type usages.\n * @suppress {messageConventions} JS Compiler reports an error if a variable or\n * field starts with 'MSG_' and isn't a translatable message.\n * @public\n */\n// GENERATED CODE -- DO NOT EDIT!\n/* eslint-disable */\n// @ts-nocheck\n\nvar jspb = require('google-protobuf');\nvar goog = jspb;\nvar global = (function() {\n if (this) { return this; }\n if (typeof window !== 'undefined') { return window; }\n if (typeof global !== 'undefined') { return global; }\n if (typeof self !== 'undefined') { return self; }\n return Function('return this')();\n}.call(null));\n\nvar nanopb_pb = require('./nanopb_pb.js');\ngoog.object.extend(proto, nanopb_pb);\ngoog.exportSymbol('proto.Conf.Artwork', null, global);\ngoog.exportSymbol('proto.Conf.Battery', null, global);\ngoog.exportSymbol('proto.Conf.BatteryAttenEnum', null, global);\ngoog.exportSymbol('proto.Conf.BatteryChannelEnum', null, global);\ngoog.exportSymbol('proto.Conf.Button', null, global);\ngoog.exportSymbol('proto.Conf.ButtonAction', null, global);\ngoog.exportSymbol('proto.Conf.ButtonActions', null, global);\ngoog.exportSymbol('proto.Conf.Config', null, global);\ngoog.exportSymbol('proto.Conf.DACDev', null, global);\ngoog.exportSymbol('proto.Conf.DACModelEnum', null, global);\ngoog.exportSymbol('proto.Conf.Dev', null, global);\ngoog.exportSymbol('proto.Conf.DeviceTypeEnum', null, global);\ngoog.exportSymbol('proto.Conf.DispCommon', null, global);\ngoog.exportSymbol('proto.Conf.DispOffsets', null, global);\ngoog.exportSymbol('proto.Conf.DisplayDev', null, global);\ngoog.exportSymbol('proto.Conf.DisplayDev.DisptypeCase', null, global);\ngoog.exportSymbol('proto.Conf.DisplayDriverEnum', null, global);\ngoog.exportSymbol('proto.Conf.Eth', null, global);\ngoog.exportSymbol('proto.Conf.Eth.EthtypeCase', null, global);\ngoog.exportSymbol('proto.Conf.EthCommon', null, global);\ngoog.exportSymbol('proto.Conf.EthModelEnum', null, global);\ngoog.exportSymbol('proto.Conf.EthRMII', null, global);\ngoog.exportSymbol('proto.Conf.EthSPI', null, global);\ngoog.exportSymbol('proto.Conf.EthType', null, global);\ngoog.exportSymbol('proto.Conf.GPIO', null, global);\ngoog.exportSymbol('proto.Conf.GPIOExp', null, global);\ngoog.exportSymbol('proto.Conf.GPIOExpModelEnum', null, global);\ngoog.exportSymbol('proto.Conf.Gpios', null, global);\ngoog.exportSymbol('proto.Conf.HostEnum', null, global);\ngoog.exportSymbol('proto.Conf.I2CBus', null, global);\ngoog.exportSymbol('proto.Conf.I2CDisplay', null, global);\ngoog.exportSymbol('proto.Conf.I2CPortEnum', null, global);\ngoog.exportSymbol('proto.Conf.LEDStrip', null, global);\ngoog.exportSymbol('proto.Conf.MCKEnum', null, global);\ngoog.exportSymbol('proto.Conf.Metadata', null, global);\ngoog.exportSymbol('proto.Conf.PortEnum', null, global);\ngoog.exportSymbol('proto.Conf.Rotary', null, global);\ngoog.exportSymbol('proto.Conf.SPDIFDev', null, global);\ngoog.exportSymbol('proto.Conf.SPIBus', null, global);\ngoog.exportSymbol('proto.Conf.SPIDisplay', null, global);\ngoog.exportSymbol('proto.Conf.Services', null, global);\ngoog.exportSymbol('proto.Conf.SleepService', null, global);\ngoog.exportSymbol('proto.Conf.WS2812', null, global);\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.GPIO = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.GPIO, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.GPIO.displayName = 'proto.Conf.GPIO';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.I2CBus = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.I2CBus, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.I2CBus.displayName = 'proto.Conf.I2CBus';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.DACDev = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.DACDev, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.DACDev.displayName = 'proto.Conf.DACDev';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.SPDIFDev = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.SPDIFDev, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.SPDIFDev.displayName = 'proto.Conf.SPDIFDev';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.DispOffsets = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.DispOffsets, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.DispOffsets.displayName = 'proto.Conf.DispOffsets';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.DispCommon = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.DispCommon, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.DispCommon.displayName = 'proto.Conf.DispCommon';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.I2CDisplay = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.I2CDisplay, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.I2CDisplay.displayName = 'proto.Conf.I2CDisplay';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.SPIDisplay = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.SPIDisplay, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.SPIDisplay.displayName = 'proto.Conf.SPIDisplay';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.SPIBus = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.SPIBus, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.SPIBus.displayName = 'proto.Conf.SPIBus';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.DisplayDev = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, proto.Conf.DisplayDev.oneofGroups_);\n};\ngoog.inherits(proto.Conf.DisplayDev, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.DisplayDev.displayName = 'proto.Conf.DisplayDev';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.GPIOExp = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.GPIOExp, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.GPIOExp.displayName = 'proto.Conf.GPIOExp';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.WS2812 = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.WS2812, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.WS2812.displayName = 'proto.Conf.WS2812';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.LEDStrip = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.LEDStrip, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.LEDStrip.displayName = 'proto.Conf.LEDStrip';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.Rotary = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.Rotary, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.Rotary.displayName = 'proto.Conf.Rotary';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.ButtonActions = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.ButtonActions, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.ButtonActions.displayName = 'proto.Conf.ButtonActions';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.Button = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.Button, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.Button.displayName = 'proto.Conf.Button';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.EthCommon = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.EthCommon, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.EthCommon.displayName = 'proto.Conf.EthCommon';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.EthSPI = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.EthSPI, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.EthSPI.displayName = 'proto.Conf.EthSPI';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.EthRMII = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.EthRMII, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.EthRMII.displayName = 'proto.Conf.EthRMII';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.Eth = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, proto.Conf.Eth.oneofGroups_);\n};\ngoog.inherits(proto.Conf.Eth, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.Eth.displayName = 'proto.Conf.Eth';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.Battery = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.Battery, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.Battery.displayName = 'proto.Conf.Battery';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.Gpios = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.Gpios, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.Gpios.displayName = 'proto.Conf.Gpios';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.Dev = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, proto.Conf.Dev.repeatedFields_, null);\n};\ngoog.inherits(proto.Conf.Dev, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.Dev.displayName = 'proto.Conf.Dev';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.SleepService = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, proto.Conf.SleepService.repeatedFields_, null);\n};\ngoog.inherits(proto.Conf.SleepService, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.SleepService.displayName = 'proto.Conf.SleepService';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.Artwork = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.Artwork, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.Artwork.displayName = 'proto.Conf.Artwork';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.Metadata = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.Metadata, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.Metadata.displayName = 'proto.Conf.Metadata';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.Services = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.Services, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.Services.displayName = 'proto.Conf.Services';\n}\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.Conf.Config = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, null, null);\n};\ngoog.inherits(proto.Conf.Config, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.Conf.Config.displayName = 'proto.Conf.Config';\n}\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.GPIO.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.GPIO.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.GPIO} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.GPIO.toObject = function(includeInstance, msg) {\n var f, obj = {\n pin: jspb.Message.getFieldWithDefault(msg, 1, 0),\n level: jspb.Message.getFieldWithDefault(msg, 2, 0)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.GPIO}\n */\nproto.Conf.GPIO.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.GPIO;\n return proto.Conf.GPIO.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.GPIO} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.GPIO}\n */\nproto.Conf.GPIO.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setPin(value);\n break;\n case 2:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setLevel(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.GPIO.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.GPIO.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.GPIO} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.GPIO.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getPin();\n if (f !== 0) {\n writer.writeInt32(\n 1,\n f\n );\n }\n f = /** @type {number} */ (jspb.Message.getField(message, 2));\n if (f != null) {\n writer.writeInt32(\n 2,\n f\n );\n }\n};\n\n\n/**\n * optional int32 pin = 1;\n * @return {number}\n */\nproto.Conf.GPIO.prototype.getPin = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.GPIO} returns this\n */\nproto.Conf.GPIO.prototype.setPin = function(value) {\n return jspb.Message.setProto3IntField(this, 1, value);\n};\n\n\n/**\n * optional int32 level = 2;\n * @return {number}\n */\nproto.Conf.GPIO.prototype.getLevel = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.GPIO} returns this\n */\nproto.Conf.GPIO.prototype.setLevel = function(value) {\n return jspb.Message.setField(this, 2, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.Conf.GPIO} returns this\n */\nproto.Conf.GPIO.prototype.clearLevel = function() {\n return jspb.Message.setField(this, 2, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.GPIO.prototype.hasLevel = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.I2CBus.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.I2CBus.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.I2CBus} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.I2CBus.toObject = function(includeInstance, msg) {\n var f, obj = {\n port: jspb.Message.getFieldWithDefault(msg, 1, 0),\n speed: jspb.Message.getFieldWithDefault(msg, 2, 0),\n sda: (f = msg.getSda()) && proto.Conf.GPIO.toObject(includeInstance, f),\n scl: (f = msg.getScl()) && proto.Conf.GPIO.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.I2CBus}\n */\nproto.Conf.I2CBus.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.I2CBus;\n return proto.Conf.I2CBus.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.I2CBus} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.I2CBus}\n */\nproto.Conf.I2CBus.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {!proto.Conf.I2CPortEnum} */ (reader.readEnum());\n msg.setPort(value);\n break;\n case 2:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setSpeed(value);\n break;\n case 3:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setSda(value);\n break;\n case 4:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setScl(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.I2CBus.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.I2CBus.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.I2CBus} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.I2CBus.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getPort();\n if (f !== 0.0) {\n writer.writeEnum(\n 1,\n f\n );\n }\n f = message.getSpeed();\n if (f !== 0) {\n writer.writeInt32(\n 2,\n f\n );\n }\n f = message.getSda();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getScl();\n if (f != null) {\n writer.writeMessage(\n 4,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional I2CPortEnum port = 1;\n * @return {!proto.Conf.I2CPortEnum}\n */\nproto.Conf.I2CBus.prototype.getPort = function() {\n return /** @type {!proto.Conf.I2CPortEnum} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {!proto.Conf.I2CPortEnum} value\n * @return {!proto.Conf.I2CBus} returns this\n */\nproto.Conf.I2CBus.prototype.setPort = function(value) {\n return jspb.Message.setProto3EnumField(this, 1, value);\n};\n\n\n/**\n * optional int32 speed = 2;\n * @return {number}\n */\nproto.Conf.I2CBus.prototype.getSpeed = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.I2CBus} returns this\n */\nproto.Conf.I2CBus.prototype.setSpeed = function(value) {\n return jspb.Message.setProto3IntField(this, 2, value);\n};\n\n\n/**\n * optional GPIO sda = 3;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.I2CBus.prototype.getSda = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 3));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.I2CBus} returns this\n*/\nproto.Conf.I2CBus.prototype.setSda = function(value) {\n return jspb.Message.setWrapperField(this, 3, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.I2CBus} returns this\n */\nproto.Conf.I2CBus.prototype.clearSda = function() {\n return this.setSda(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.I2CBus.prototype.hasSda = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * optional GPIO scl = 4;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.I2CBus.prototype.getScl = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 4));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.I2CBus} returns this\n*/\nproto.Conf.I2CBus.prototype.setScl = function(value) {\n return jspb.Message.setWrapperField(this, 4, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.I2CBus} returns this\n */\nproto.Conf.I2CBus.prototype.clearScl = function() {\n return this.setScl(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.I2CBus.prototype.hasScl = function() {\n return jspb.Message.getField(this, 4) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.DACDev.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.DACDev.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.DACDev} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.DACDev.toObject = function(includeInstance, msg) {\n var f, obj = {\n bck: (f = msg.getBck()) && proto.Conf.GPIO.toObject(includeInstance, f),\n ws: (f = msg.getWs()) && proto.Conf.GPIO.toObject(includeInstance, f),\n dout: (f = msg.getDout()) && proto.Conf.GPIO.toObject(includeInstance, f),\n mck: jspb.Message.getFieldWithDefault(msg, 4, 0),\n mute: (f = msg.getMute()) && proto.Conf.GPIO.toObject(includeInstance, f),\n model: jspb.Message.getFieldWithDefault(msg, 6, 0),\n i2c: (f = msg.getI2c()) && proto.Conf.I2CBus.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.DACDev}\n */\nproto.Conf.DACDev.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.DACDev;\n return proto.Conf.DACDev.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.DACDev} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.DACDev}\n */\nproto.Conf.DACDev.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setBck(value);\n break;\n case 2:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setWs(value);\n break;\n case 3:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setDout(value);\n break;\n case 4:\n var value = /** @type {!proto.Conf.MCKEnum} */ (reader.readEnum());\n msg.setMck(value);\n break;\n case 5:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setMute(value);\n break;\n case 6:\n var value = /** @type {!proto.Conf.DACModelEnum} */ (reader.readEnum());\n msg.setModel(value);\n break;\n case 7:\n var value = new proto.Conf.I2CBus;\n reader.readMessage(value,proto.Conf.I2CBus.deserializeBinaryFromReader);\n msg.setI2c(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.DACDev.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.DACDev.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.DACDev} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.DACDev.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getBck();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getWs();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getDout();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getMck();\n if (f !== 0.0) {\n writer.writeEnum(\n 4,\n f\n );\n }\n f = message.getMute();\n if (f != null) {\n writer.writeMessage(\n 5,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getModel();\n if (f !== 0.0) {\n writer.writeEnum(\n 6,\n f\n );\n }\n f = message.getI2c();\n if (f != null) {\n writer.writeMessage(\n 7,\n f,\n proto.Conf.I2CBus.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional GPIO bck = 1;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.DACDev.prototype.getBck = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 1));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.DACDev} returns this\n*/\nproto.Conf.DACDev.prototype.setBck = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DACDev} returns this\n */\nproto.Conf.DACDev.prototype.clearBck = function() {\n return this.setBck(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DACDev.prototype.hasBck = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional GPIO ws = 2;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.DACDev.prototype.getWs = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 2));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.DACDev} returns this\n*/\nproto.Conf.DACDev.prototype.setWs = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DACDev} returns this\n */\nproto.Conf.DACDev.prototype.clearWs = function() {\n return this.setWs(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DACDev.prototype.hasWs = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n/**\n * optional GPIO dout = 3;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.DACDev.prototype.getDout = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 3));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.DACDev} returns this\n*/\nproto.Conf.DACDev.prototype.setDout = function(value) {\n return jspb.Message.setWrapperField(this, 3, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DACDev} returns this\n */\nproto.Conf.DACDev.prototype.clearDout = function() {\n return this.setDout(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DACDev.prototype.hasDout = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * optional MCKEnum mck = 4;\n * @return {!proto.Conf.MCKEnum}\n */\nproto.Conf.DACDev.prototype.getMck = function() {\n return /** @type {!proto.Conf.MCKEnum} */ (jspb.Message.getFieldWithDefault(this, 4, 0));\n};\n\n\n/**\n * @param {!proto.Conf.MCKEnum} value\n * @return {!proto.Conf.DACDev} returns this\n */\nproto.Conf.DACDev.prototype.setMck = function(value) {\n return jspb.Message.setProto3EnumField(this, 4, value);\n};\n\n\n/**\n * optional GPIO mute = 5;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.DACDev.prototype.getMute = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 5));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.DACDev} returns this\n*/\nproto.Conf.DACDev.prototype.setMute = function(value) {\n return jspb.Message.setWrapperField(this, 5, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DACDev} returns this\n */\nproto.Conf.DACDev.prototype.clearMute = function() {\n return this.setMute(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DACDev.prototype.hasMute = function() {\n return jspb.Message.getField(this, 5) != null;\n};\n\n\n/**\n * optional DACModelEnum model = 6;\n * @return {!proto.Conf.DACModelEnum}\n */\nproto.Conf.DACDev.prototype.getModel = function() {\n return /** @type {!proto.Conf.DACModelEnum} */ (jspb.Message.getFieldWithDefault(this, 6, 0));\n};\n\n\n/**\n * @param {!proto.Conf.DACModelEnum} value\n * @return {!proto.Conf.DACDev} returns this\n */\nproto.Conf.DACDev.prototype.setModel = function(value) {\n return jspb.Message.setProto3EnumField(this, 6, value);\n};\n\n\n/**\n * optional I2CBus i2c = 7;\n * @return {?proto.Conf.I2CBus}\n */\nproto.Conf.DACDev.prototype.getI2c = function() {\n return /** @type{?proto.Conf.I2CBus} */ (\n jspb.Message.getWrapperField(this, proto.Conf.I2CBus, 7));\n};\n\n\n/**\n * @param {?proto.Conf.I2CBus|undefined} value\n * @return {!proto.Conf.DACDev} returns this\n*/\nproto.Conf.DACDev.prototype.setI2c = function(value) {\n return jspb.Message.setWrapperField(this, 7, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DACDev} returns this\n */\nproto.Conf.DACDev.prototype.clearI2c = function() {\n return this.setI2c(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DACDev.prototype.hasI2c = function() {\n return jspb.Message.getField(this, 7) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.SPDIFDev.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.SPDIFDev.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.SPDIFDev} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.SPDIFDev.toObject = function(includeInstance, msg) {\n var f, obj = {\n dc: (f = msg.getDc()) && proto.Conf.GPIO.toObject(includeInstance, f),\n data: (f = msg.getData()) && proto.Conf.GPIO.toObject(includeInstance, f),\n clk: (f = msg.getClk()) && proto.Conf.GPIO.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.SPDIFDev}\n */\nproto.Conf.SPDIFDev.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.SPDIFDev;\n return proto.Conf.SPDIFDev.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.SPDIFDev} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.SPDIFDev}\n */\nproto.Conf.SPDIFDev.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setDc(value);\n break;\n case 2:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setData(value);\n break;\n case 3:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setClk(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.SPDIFDev.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.SPDIFDev.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.SPDIFDev} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.SPDIFDev.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getDc();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getData();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getClk();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional GPIO dc = 1;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.SPDIFDev.prototype.getDc = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 1));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.SPDIFDev} returns this\n*/\nproto.Conf.SPDIFDev.prototype.setDc = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.SPDIFDev} returns this\n */\nproto.Conf.SPDIFDev.prototype.clearDc = function() {\n return this.setDc(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.SPDIFDev.prototype.hasDc = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional GPIO data = 2;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.SPDIFDev.prototype.getData = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 2));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.SPDIFDev} returns this\n*/\nproto.Conf.SPDIFDev.prototype.setData = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.SPDIFDev} returns this\n */\nproto.Conf.SPDIFDev.prototype.clearData = function() {\n return this.setData(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.SPDIFDev.prototype.hasData = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n/**\n * optional GPIO clk = 3;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.SPDIFDev.prototype.getClk = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 3));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.SPDIFDev} returns this\n*/\nproto.Conf.SPDIFDev.prototype.setClk = function(value) {\n return jspb.Message.setWrapperField(this, 3, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.SPDIFDev} returns this\n */\nproto.Conf.SPDIFDev.prototype.clearClk = function() {\n return this.setClk(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.SPDIFDev.prototype.hasClk = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.DispOffsets.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.DispOffsets.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.DispOffsets} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.DispOffsets.toObject = function(includeInstance, msg) {\n var f, obj = {\n height: jspb.Message.getFieldWithDefault(msg, 1, 0),\n width: jspb.Message.getFieldWithDefault(msg, 2, 0)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.DispOffsets}\n */\nproto.Conf.DispOffsets.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.DispOffsets;\n return proto.Conf.DispOffsets.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.DispOffsets} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.DispOffsets}\n */\nproto.Conf.DispOffsets.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setHeight(value);\n break;\n case 2:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setWidth(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.DispOffsets.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.DispOffsets.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.DispOffsets} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.DispOffsets.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getHeight();\n if (f !== 0) {\n writer.writeInt32(\n 1,\n f\n );\n }\n f = message.getWidth();\n if (f !== 0) {\n writer.writeInt32(\n 2,\n f\n );\n }\n};\n\n\n/**\n * optional int32 height = 1;\n * @return {number}\n */\nproto.Conf.DispOffsets.prototype.getHeight = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.DispOffsets} returns this\n */\nproto.Conf.DispOffsets.prototype.setHeight = function(value) {\n return jspb.Message.setProto3IntField(this, 1, value);\n};\n\n\n/**\n * optional int32 width = 2;\n * @return {number}\n */\nproto.Conf.DispOffsets.prototype.getWidth = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.DispOffsets} returns this\n */\nproto.Conf.DispOffsets.prototype.setWidth = function(value) {\n return jspb.Message.setProto3IntField(this, 2, value);\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.DispCommon.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.DispCommon.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.DispCommon} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.DispCommon.toObject = function(includeInstance, msg) {\n var f, obj = {\n width: jspb.Message.getFieldWithDefault(msg, 1, 0),\n height: jspb.Message.getFieldWithDefault(msg, 2, 0),\n hflip: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),\n vflip: jspb.Message.getBooleanFieldWithDefault(msg, 4, false),\n driver: jspb.Message.getFieldWithDefault(msg, 5, 0),\n bitdepth: jspb.Message.getFieldWithDefault(msg, 6, 0),\n back: (f = msg.getBack()) && proto.Conf.GPIO.toObject(includeInstance, f),\n reset: (f = msg.getReset()) && proto.Conf.GPIO.toObject(includeInstance, f),\n ready: (f = msg.getReady()) && proto.Conf.GPIO.toObject(includeInstance, f),\n offsets: (f = msg.getOffsets()) && proto.Conf.DispOffsets.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.DispCommon}\n */\nproto.Conf.DispCommon.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.DispCommon;\n return proto.Conf.DispCommon.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.DispCommon} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.DispCommon}\n */\nproto.Conf.DispCommon.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setWidth(value);\n break;\n case 2:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setHeight(value);\n break;\n case 3:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setHflip(value);\n break;\n case 4:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setVflip(value);\n break;\n case 5:\n var value = /** @type {!proto.Conf.DisplayDriverEnum} */ (reader.readEnum());\n msg.setDriver(value);\n break;\n case 6:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setBitdepth(value);\n break;\n case 7:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setBack(value);\n break;\n case 8:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setReset(value);\n break;\n case 9:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setReady(value);\n break;\n case 10:\n var value = new proto.Conf.DispOffsets;\n reader.readMessage(value,proto.Conf.DispOffsets.deserializeBinaryFromReader);\n msg.setOffsets(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.DispCommon.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.DispCommon.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.DispCommon} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.DispCommon.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getWidth();\n if (f !== 0) {\n writer.writeInt32(\n 1,\n f\n );\n }\n f = message.getHeight();\n if (f !== 0) {\n writer.writeInt32(\n 2,\n f\n );\n }\n f = message.getHflip();\n if (f) {\n writer.writeBool(\n 3,\n f\n );\n }\n f = message.getVflip();\n if (f) {\n writer.writeBool(\n 4,\n f\n );\n }\n f = message.getDriver();\n if (f !== 0.0) {\n writer.writeEnum(\n 5,\n f\n );\n }\n f = message.getBitdepth();\n if (f !== 0) {\n writer.writeInt32(\n 6,\n f\n );\n }\n f = message.getBack();\n if (f != null) {\n writer.writeMessage(\n 7,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getReset();\n if (f != null) {\n writer.writeMessage(\n 8,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getReady();\n if (f != null) {\n writer.writeMessage(\n 9,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getOffsets();\n if (f != null) {\n writer.writeMessage(\n 10,\n f,\n proto.Conf.DispOffsets.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional int32 width = 1;\n * @return {number}\n */\nproto.Conf.DispCommon.prototype.getWidth = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.DispCommon} returns this\n */\nproto.Conf.DispCommon.prototype.setWidth = function(value) {\n return jspb.Message.setProto3IntField(this, 1, value);\n};\n\n\n/**\n * optional int32 height = 2;\n * @return {number}\n */\nproto.Conf.DispCommon.prototype.getHeight = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.DispCommon} returns this\n */\nproto.Conf.DispCommon.prototype.setHeight = function(value) {\n return jspb.Message.setProto3IntField(this, 2, value);\n};\n\n\n/**\n * optional bool HFlip = 3;\n * @return {boolean}\n */\nproto.Conf.DispCommon.prototype.getHflip = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.Conf.DispCommon} returns this\n */\nproto.Conf.DispCommon.prototype.setHflip = function(value) {\n return jspb.Message.setProto3BooleanField(this, 3, value);\n};\n\n\n/**\n * optional bool VFlip = 4;\n * @return {boolean}\n */\nproto.Conf.DispCommon.prototype.getVflip = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 4, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.Conf.DispCommon} returns this\n */\nproto.Conf.DispCommon.prototype.setVflip = function(value) {\n return jspb.Message.setProto3BooleanField(this, 4, value);\n};\n\n\n/**\n * optional DisplayDriverEnum driver = 5;\n * @return {!proto.Conf.DisplayDriverEnum}\n */\nproto.Conf.DispCommon.prototype.getDriver = function() {\n return /** @type {!proto.Conf.DisplayDriverEnum} */ (jspb.Message.getFieldWithDefault(this, 5, 0));\n};\n\n\n/**\n * @param {!proto.Conf.DisplayDriverEnum} value\n * @return {!proto.Conf.DispCommon} returns this\n */\nproto.Conf.DispCommon.prototype.setDriver = function(value) {\n return jspb.Message.setProto3EnumField(this, 5, value);\n};\n\n\n/**\n * optional int32 bitDepth = 6;\n * @return {number}\n */\nproto.Conf.DispCommon.prototype.getBitdepth = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.DispCommon} returns this\n */\nproto.Conf.DispCommon.prototype.setBitdepth = function(value) {\n return jspb.Message.setProto3IntField(this, 6, value);\n};\n\n\n/**\n * optional GPIO back = 7;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.DispCommon.prototype.getBack = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 7));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.DispCommon} returns this\n*/\nproto.Conf.DispCommon.prototype.setBack = function(value) {\n return jspb.Message.setWrapperField(this, 7, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DispCommon} returns this\n */\nproto.Conf.DispCommon.prototype.clearBack = function() {\n return this.setBack(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DispCommon.prototype.hasBack = function() {\n return jspb.Message.getField(this, 7) != null;\n};\n\n\n/**\n * optional GPIO reset = 8;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.DispCommon.prototype.getReset = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 8));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.DispCommon} returns this\n*/\nproto.Conf.DispCommon.prototype.setReset = function(value) {\n return jspb.Message.setWrapperField(this, 8, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DispCommon} returns this\n */\nproto.Conf.DispCommon.prototype.clearReset = function() {\n return this.setReset(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DispCommon.prototype.hasReset = function() {\n return jspb.Message.getField(this, 8) != null;\n};\n\n\n/**\n * optional GPIO ready = 9;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.DispCommon.prototype.getReady = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 9));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.DispCommon} returns this\n*/\nproto.Conf.DispCommon.prototype.setReady = function(value) {\n return jspb.Message.setWrapperField(this, 9, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DispCommon} returns this\n */\nproto.Conf.DispCommon.prototype.clearReady = function() {\n return this.setReady(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DispCommon.prototype.hasReady = function() {\n return jspb.Message.getField(this, 9) != null;\n};\n\n\n/**\n * optional DispOffsets offsets = 10;\n * @return {?proto.Conf.DispOffsets}\n */\nproto.Conf.DispCommon.prototype.getOffsets = function() {\n return /** @type{?proto.Conf.DispOffsets} */ (\n jspb.Message.getWrapperField(this, proto.Conf.DispOffsets, 10));\n};\n\n\n/**\n * @param {?proto.Conf.DispOffsets|undefined} value\n * @return {!proto.Conf.DispCommon} returns this\n*/\nproto.Conf.DispCommon.prototype.setOffsets = function(value) {\n return jspb.Message.setWrapperField(this, 10, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DispCommon} returns this\n */\nproto.Conf.DispCommon.prototype.clearOffsets = function() {\n return this.setOffsets(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DispCommon.prototype.hasOffsets = function() {\n return jspb.Message.getField(this, 10) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.I2CDisplay.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.I2CDisplay.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.I2CDisplay} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.I2CDisplay.toObject = function(includeInstance, msg) {\n var f, obj = {\n address: jspb.Message.getFieldWithDefault(msg, 1, 0)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.I2CDisplay}\n */\nproto.Conf.I2CDisplay.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.I2CDisplay;\n return proto.Conf.I2CDisplay.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.I2CDisplay} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.I2CDisplay}\n */\nproto.Conf.I2CDisplay.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setAddress(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.I2CDisplay.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.I2CDisplay.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.I2CDisplay} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.I2CDisplay.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getAddress();\n if (f !== 0) {\n writer.writeInt32(\n 1,\n f\n );\n }\n};\n\n\n/**\n * optional int32 address = 1;\n * @return {number}\n */\nproto.Conf.I2CDisplay.prototype.getAddress = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.I2CDisplay} returns this\n */\nproto.Conf.I2CDisplay.prototype.setAddress = function(value) {\n return jspb.Message.setProto3IntField(this, 1, value);\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.SPIDisplay.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.SPIDisplay.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.SPIDisplay} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.SPIDisplay.toObject = function(includeInstance, msg) {\n var f, obj = {\n cs: (f = msg.getCs()) && proto.Conf.GPIO.toObject(includeInstance, f),\n speed: jspb.Message.getFieldWithDefault(msg, 4, 0),\n rotate: jspb.Message.getBooleanFieldWithDefault(msg, 5, false)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.SPIDisplay}\n */\nproto.Conf.SPIDisplay.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.SPIDisplay;\n return proto.Conf.SPIDisplay.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.SPIDisplay} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.SPIDisplay}\n */\nproto.Conf.SPIDisplay.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setCs(value);\n break;\n case 4:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setSpeed(value);\n break;\n case 5:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setRotate(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.SPIDisplay.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.SPIDisplay.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.SPIDisplay} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.SPIDisplay.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getCs();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getSpeed();\n if (f !== 0) {\n writer.writeInt32(\n 4,\n f\n );\n }\n f = message.getRotate();\n if (f) {\n writer.writeBool(\n 5,\n f\n );\n }\n};\n\n\n/**\n * optional GPIO cs = 1;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.SPIDisplay.prototype.getCs = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 1));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.SPIDisplay} returns this\n*/\nproto.Conf.SPIDisplay.prototype.setCs = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.SPIDisplay} returns this\n */\nproto.Conf.SPIDisplay.prototype.clearCs = function() {\n return this.setCs(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.SPIDisplay.prototype.hasCs = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional int32 speed = 4;\n * @return {number}\n */\nproto.Conf.SPIDisplay.prototype.getSpeed = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.SPIDisplay} returns this\n */\nproto.Conf.SPIDisplay.prototype.setSpeed = function(value) {\n return jspb.Message.setProto3IntField(this, 4, value);\n};\n\n\n/**\n * optional bool rotate = 5;\n * @return {boolean}\n */\nproto.Conf.SPIDisplay.prototype.getRotate = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.Conf.SPIDisplay} returns this\n */\nproto.Conf.SPIDisplay.prototype.setRotate = function(value) {\n return jspb.Message.setProto3BooleanField(this, 5, value);\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.SPIBus.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.SPIBus.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.SPIBus} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.SPIBus.toObject = function(includeInstance, msg) {\n var f, obj = {\n mosi: (f = msg.getMosi()) && proto.Conf.GPIO.toObject(includeInstance, f),\n miso: (f = msg.getMiso()) && proto.Conf.GPIO.toObject(includeInstance, f),\n clk: (f = msg.getClk()) && proto.Conf.GPIO.toObject(includeInstance, f),\n dc: (f = msg.getDc()) && proto.Conf.GPIO.toObject(includeInstance, f),\n host: jspb.Message.getFieldWithDefault(msg, 5, 0)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.SPIBus}\n */\nproto.Conf.SPIBus.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.SPIBus;\n return proto.Conf.SPIBus.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.SPIBus} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.SPIBus}\n */\nproto.Conf.SPIBus.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setMosi(value);\n break;\n case 2:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setMiso(value);\n break;\n case 3:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setClk(value);\n break;\n case 4:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setDc(value);\n break;\n case 5:\n var value = /** @type {!proto.Conf.HostEnum} */ (reader.readEnum());\n msg.setHost(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.SPIBus.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.SPIBus.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.SPIBus} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.SPIBus.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getMosi();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getMiso();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getClk();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getDc();\n if (f != null) {\n writer.writeMessage(\n 4,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getHost();\n if (f !== 0.0) {\n writer.writeEnum(\n 5,\n f\n );\n }\n};\n\n\n/**\n * optional GPIO mosi = 1;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.SPIBus.prototype.getMosi = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 1));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.SPIBus} returns this\n*/\nproto.Conf.SPIBus.prototype.setMosi = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.SPIBus} returns this\n */\nproto.Conf.SPIBus.prototype.clearMosi = function() {\n return this.setMosi(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.SPIBus.prototype.hasMosi = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional GPIO miso = 2;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.SPIBus.prototype.getMiso = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 2));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.SPIBus} returns this\n*/\nproto.Conf.SPIBus.prototype.setMiso = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.SPIBus} returns this\n */\nproto.Conf.SPIBus.prototype.clearMiso = function() {\n return this.setMiso(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.SPIBus.prototype.hasMiso = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n/**\n * optional GPIO clk = 3;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.SPIBus.prototype.getClk = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 3));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.SPIBus} returns this\n*/\nproto.Conf.SPIBus.prototype.setClk = function(value) {\n return jspb.Message.setWrapperField(this, 3, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.SPIBus} returns this\n */\nproto.Conf.SPIBus.prototype.clearClk = function() {\n return this.setClk(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.SPIBus.prototype.hasClk = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * optional GPIO dc = 4;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.SPIBus.prototype.getDc = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 4));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.SPIBus} returns this\n*/\nproto.Conf.SPIBus.prototype.setDc = function(value) {\n return jspb.Message.setWrapperField(this, 4, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.SPIBus} returns this\n */\nproto.Conf.SPIBus.prototype.clearDc = function() {\n return this.setDc(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.SPIBus.prototype.hasDc = function() {\n return jspb.Message.getField(this, 4) != null;\n};\n\n\n/**\n * optional HostEnum host = 5;\n * @return {!proto.Conf.HostEnum}\n */\nproto.Conf.SPIBus.prototype.getHost = function() {\n return /** @type {!proto.Conf.HostEnum} */ (jspb.Message.getFieldWithDefault(this, 5, 0));\n};\n\n\n/**\n * @param {!proto.Conf.HostEnum} value\n * @return {!proto.Conf.SPIBus} returns this\n */\nproto.Conf.SPIBus.prototype.setHost = function(value) {\n return jspb.Message.setProto3EnumField(this, 5, value);\n};\n\n\n\n/**\n * Oneof group definitions for this message. Each group defines the field\n * numbers belonging to that group. When of these fields' value is set, all\n * other fields in the group are cleared. During deserialization, if multiple\n * fields are encountered for a group, only the last value seen will be kept.\n * @private {!Array>}\n * @const\n */\nproto.Conf.DisplayDev.oneofGroups_ = [[3,4]];\n\n/**\n * @enum {number}\n */\nproto.Conf.DisplayDev.DisptypeCase = {\n DISPTYPE_NOT_SET: 0,\n I2C: 3,\n SPI: 4\n};\n\n/**\n * @return {proto.Conf.DisplayDev.DisptypeCase}\n */\nproto.Conf.DisplayDev.prototype.getDisptypeCase = function() {\n return /** @type {proto.Conf.DisplayDev.DisptypeCase} */(jspb.Message.computeOneofCase(this, proto.Conf.DisplayDev.oneofGroups_[0]));\n};\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.DisplayDev.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.DisplayDev.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.DisplayDev} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.DisplayDev.toObject = function(includeInstance, msg) {\n var f, obj = {\n type: jspb.Message.getFieldWithDefault(msg, 1, 0),\n common: (f = msg.getCommon()) && proto.Conf.DispCommon.toObject(includeInstance, f),\n i2c: (f = msg.getI2c()) && proto.Conf.I2CDisplay.toObject(includeInstance, f),\n spi: (f = msg.getSpi()) && proto.Conf.SPIDisplay.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.DisplayDev}\n */\nproto.Conf.DisplayDev.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.DisplayDev;\n return proto.Conf.DisplayDev.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.DisplayDev} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.DisplayDev}\n */\nproto.Conf.DisplayDev.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {!proto.Conf.DeviceTypeEnum} */ (reader.readEnum());\n msg.setType(value);\n break;\n case 2:\n var value = new proto.Conf.DispCommon;\n reader.readMessage(value,proto.Conf.DispCommon.deserializeBinaryFromReader);\n msg.setCommon(value);\n break;\n case 3:\n var value = new proto.Conf.I2CDisplay;\n reader.readMessage(value,proto.Conf.I2CDisplay.deserializeBinaryFromReader);\n msg.setI2c(value);\n break;\n case 4:\n var value = new proto.Conf.SPIDisplay;\n reader.readMessage(value,proto.Conf.SPIDisplay.deserializeBinaryFromReader);\n msg.setSpi(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.DisplayDev.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.DisplayDev.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.DisplayDev} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.DisplayDev.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getType();\n if (f !== 0.0) {\n writer.writeEnum(\n 1,\n f\n );\n }\n f = message.getCommon();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.DispCommon.serializeBinaryToWriter\n );\n }\n f = message.getI2c();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.I2CDisplay.serializeBinaryToWriter\n );\n }\n f = message.getSpi();\n if (f != null) {\n writer.writeMessage(\n 4,\n f,\n proto.Conf.SPIDisplay.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional DeviceTypeEnum type = 1;\n * @return {!proto.Conf.DeviceTypeEnum}\n */\nproto.Conf.DisplayDev.prototype.getType = function() {\n return /** @type {!proto.Conf.DeviceTypeEnum} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {!proto.Conf.DeviceTypeEnum} value\n * @return {!proto.Conf.DisplayDev} returns this\n */\nproto.Conf.DisplayDev.prototype.setType = function(value) {\n return jspb.Message.setProto3EnumField(this, 1, value);\n};\n\n\n/**\n * optional DispCommon common = 2;\n * @return {?proto.Conf.DispCommon}\n */\nproto.Conf.DisplayDev.prototype.getCommon = function() {\n return /** @type{?proto.Conf.DispCommon} */ (\n jspb.Message.getWrapperField(this, proto.Conf.DispCommon, 2));\n};\n\n\n/**\n * @param {?proto.Conf.DispCommon|undefined} value\n * @return {!proto.Conf.DisplayDev} returns this\n*/\nproto.Conf.DisplayDev.prototype.setCommon = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DisplayDev} returns this\n */\nproto.Conf.DisplayDev.prototype.clearCommon = function() {\n return this.setCommon(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DisplayDev.prototype.hasCommon = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n/**\n * optional I2CDisplay i2c = 3;\n * @return {?proto.Conf.I2CDisplay}\n */\nproto.Conf.DisplayDev.prototype.getI2c = function() {\n return /** @type{?proto.Conf.I2CDisplay} */ (\n jspb.Message.getWrapperField(this, proto.Conf.I2CDisplay, 3));\n};\n\n\n/**\n * @param {?proto.Conf.I2CDisplay|undefined} value\n * @return {!proto.Conf.DisplayDev} returns this\n*/\nproto.Conf.DisplayDev.prototype.setI2c = function(value) {\n return jspb.Message.setOneofWrapperField(this, 3, proto.Conf.DisplayDev.oneofGroups_[0], value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DisplayDev} returns this\n */\nproto.Conf.DisplayDev.prototype.clearI2c = function() {\n return this.setI2c(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DisplayDev.prototype.hasI2c = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * optional SPIDisplay spi = 4;\n * @return {?proto.Conf.SPIDisplay}\n */\nproto.Conf.DisplayDev.prototype.getSpi = function() {\n return /** @type{?proto.Conf.SPIDisplay} */ (\n jspb.Message.getWrapperField(this, proto.Conf.SPIDisplay, 4));\n};\n\n\n/**\n * @param {?proto.Conf.SPIDisplay|undefined} value\n * @return {!proto.Conf.DisplayDev} returns this\n*/\nproto.Conf.DisplayDev.prototype.setSpi = function(value) {\n return jspb.Message.setOneofWrapperField(this, 4, proto.Conf.DisplayDev.oneofGroups_[0], value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.DisplayDev} returns this\n */\nproto.Conf.DisplayDev.prototype.clearSpi = function() {\n return this.setSpi(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.DisplayDev.prototype.hasSpi = function() {\n return jspb.Message.getField(this, 4) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.GPIOExp.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.GPIOExp.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.GPIOExp} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.GPIOExp.toObject = function(includeInstance, msg) {\n var f, obj = {\n model: jspb.Message.getFieldWithDefault(msg, 1, 0),\n addr: jspb.Message.getFieldWithDefault(msg, 2, 0),\n port: jspb.Message.getFieldWithDefault(msg, 3, 0),\n base: jspb.Message.getFieldWithDefault(msg, 4, 0),\n count: jspb.Message.getFieldWithDefault(msg, 5, 0),\n intr: (f = msg.getIntr()) && proto.Conf.GPIO.toObject(includeInstance, f),\n cs: (f = msg.getCs()) && proto.Conf.GPIO.toObject(includeInstance, f),\n speed: jspb.Message.getFieldWithDefault(msg, 8, 0)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.GPIOExp}\n */\nproto.Conf.GPIOExp.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.GPIOExp;\n return proto.Conf.GPIOExp.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.GPIOExp} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.GPIOExp}\n */\nproto.Conf.GPIOExp.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {!proto.Conf.GPIOExpModelEnum} */ (reader.readEnum());\n msg.setModel(value);\n break;\n case 2:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setAddr(value);\n break;\n case 3:\n var value = /** @type {!proto.Conf.PortEnum} */ (reader.readEnum());\n msg.setPort(value);\n break;\n case 4:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setBase(value);\n break;\n case 5:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setCount(value);\n break;\n case 6:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setIntr(value);\n break;\n case 7:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setCs(value);\n break;\n case 8:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setSpeed(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.GPIOExp.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.GPIOExp.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.GPIOExp} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.GPIOExp.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getModel();\n if (f !== 0.0) {\n writer.writeEnum(\n 1,\n f\n );\n }\n f = message.getAddr();\n if (f !== 0) {\n writer.writeInt32(\n 2,\n f\n );\n }\n f = message.getPort();\n if (f !== 0.0) {\n writer.writeEnum(\n 3,\n f\n );\n }\n f = message.getBase();\n if (f !== 0) {\n writer.writeInt32(\n 4,\n f\n );\n }\n f = message.getCount();\n if (f !== 0) {\n writer.writeInt32(\n 5,\n f\n );\n }\n f = message.getIntr();\n if (f != null) {\n writer.writeMessage(\n 6,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getCs();\n if (f != null) {\n writer.writeMessage(\n 7,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getSpeed();\n if (f !== 0) {\n writer.writeInt32(\n 8,\n f\n );\n }\n};\n\n\n/**\n * optional GPIOExpModelEnum model = 1;\n * @return {!proto.Conf.GPIOExpModelEnum}\n */\nproto.Conf.GPIOExp.prototype.getModel = function() {\n return /** @type {!proto.Conf.GPIOExpModelEnum} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {!proto.Conf.GPIOExpModelEnum} value\n * @return {!proto.Conf.GPIOExp} returns this\n */\nproto.Conf.GPIOExp.prototype.setModel = function(value) {\n return jspb.Message.setProto3EnumField(this, 1, value);\n};\n\n\n/**\n * optional int32 addr = 2;\n * @return {number}\n */\nproto.Conf.GPIOExp.prototype.getAddr = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.GPIOExp} returns this\n */\nproto.Conf.GPIOExp.prototype.setAddr = function(value) {\n return jspb.Message.setProto3IntField(this, 2, value);\n};\n\n\n/**\n * optional PortEnum port = 3;\n * @return {!proto.Conf.PortEnum}\n */\nproto.Conf.GPIOExp.prototype.getPort = function() {\n return /** @type {!proto.Conf.PortEnum} */ (jspb.Message.getFieldWithDefault(this, 3, 0));\n};\n\n\n/**\n * @param {!proto.Conf.PortEnum} value\n * @return {!proto.Conf.GPIOExp} returns this\n */\nproto.Conf.GPIOExp.prototype.setPort = function(value) {\n return jspb.Message.setProto3EnumField(this, 3, value);\n};\n\n\n/**\n * optional int32 base = 4;\n * @return {number}\n */\nproto.Conf.GPIOExp.prototype.getBase = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.GPIOExp} returns this\n */\nproto.Conf.GPIOExp.prototype.setBase = function(value) {\n return jspb.Message.setProto3IntField(this, 4, value);\n};\n\n\n/**\n * optional int32 count = 5;\n * @return {number}\n */\nproto.Conf.GPIOExp.prototype.getCount = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.GPIOExp} returns this\n */\nproto.Conf.GPIOExp.prototype.setCount = function(value) {\n return jspb.Message.setProto3IntField(this, 5, value);\n};\n\n\n/**\n * optional GPIO intr = 6;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.GPIOExp.prototype.getIntr = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 6));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.GPIOExp} returns this\n*/\nproto.Conf.GPIOExp.prototype.setIntr = function(value) {\n return jspb.Message.setWrapperField(this, 6, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.GPIOExp} returns this\n */\nproto.Conf.GPIOExp.prototype.clearIntr = function() {\n return this.setIntr(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.GPIOExp.prototype.hasIntr = function() {\n return jspb.Message.getField(this, 6) != null;\n};\n\n\n/**\n * optional GPIO cs = 7;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.GPIOExp.prototype.getCs = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 7));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.GPIOExp} returns this\n*/\nproto.Conf.GPIOExp.prototype.setCs = function(value) {\n return jspb.Message.setWrapperField(this, 7, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.GPIOExp} returns this\n */\nproto.Conf.GPIOExp.prototype.clearCs = function() {\n return this.setCs(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.GPIOExp.prototype.hasCs = function() {\n return jspb.Message.getField(this, 7) != null;\n};\n\n\n/**\n * optional int32 speed = 8;\n * @return {number}\n */\nproto.Conf.GPIOExp.prototype.getSpeed = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 8, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.GPIOExp} returns this\n */\nproto.Conf.GPIOExp.prototype.setSpeed = function(value) {\n return jspb.Message.setProto3IntField(this, 8, value);\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.WS2812.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.WS2812.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.WS2812} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.WS2812.toObject = function(includeInstance, msg) {\n var f, obj = {\n length: jspb.Message.getFieldWithDefault(msg, 1, 0),\n gpio: (f = msg.getGpio()) && proto.Conf.GPIO.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.WS2812}\n */\nproto.Conf.WS2812.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.WS2812;\n return proto.Conf.WS2812.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.WS2812} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.WS2812}\n */\nproto.Conf.WS2812.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setLength(value);\n break;\n case 2:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setGpio(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.WS2812.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.WS2812.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.WS2812} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.WS2812.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getLength();\n if (f !== 0) {\n writer.writeInt32(\n 1,\n f\n );\n }\n f = message.getGpio();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional int32 length = 1;\n * @return {number}\n */\nproto.Conf.WS2812.prototype.getLength = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.WS2812} returns this\n */\nproto.Conf.WS2812.prototype.setLength = function(value) {\n return jspb.Message.setProto3IntField(this, 1, value);\n};\n\n\n/**\n * optional GPIO gpio = 2;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.WS2812.prototype.getGpio = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 2));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.WS2812} returns this\n*/\nproto.Conf.WS2812.prototype.setGpio = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.WS2812} returns this\n */\nproto.Conf.WS2812.prototype.clearGpio = function() {\n return this.setGpio(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.WS2812.prototype.hasGpio = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.LEDStrip.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.LEDStrip.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.LEDStrip} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.LEDStrip.toObject = function(includeInstance, msg) {\n var f, obj = {\n ws2812: (f = msg.getWs2812()) && proto.Conf.WS2812.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.LEDStrip}\n */\nproto.Conf.LEDStrip.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.LEDStrip;\n return proto.Conf.LEDStrip.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.LEDStrip} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.LEDStrip}\n */\nproto.Conf.LEDStrip.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.WS2812;\n reader.readMessage(value,proto.Conf.WS2812.deserializeBinaryFromReader);\n msg.setWs2812(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.LEDStrip.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.LEDStrip.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.LEDStrip} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.LEDStrip.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getWs2812();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.WS2812.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional WS2812 WS2812 = 1;\n * @return {?proto.Conf.WS2812}\n */\nproto.Conf.LEDStrip.prototype.getWs2812 = function() {\n return /** @type{?proto.Conf.WS2812} */ (\n jspb.Message.getWrapperField(this, proto.Conf.WS2812, 1));\n};\n\n\n/**\n * @param {?proto.Conf.WS2812|undefined} value\n * @return {!proto.Conf.LEDStrip} returns this\n*/\nproto.Conf.LEDStrip.prototype.setWs2812 = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.LEDStrip} returns this\n */\nproto.Conf.LEDStrip.prototype.clearWs2812 = function() {\n return this.setWs2812(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.LEDStrip.prototype.hasWs2812 = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.Rotary.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.Rotary.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.Rotary} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Rotary.toObject = function(includeInstance, msg) {\n var f, obj = {\n a: (f = msg.getA()) && proto.Conf.GPIO.toObject(includeInstance, f),\n b: (f = msg.getB()) && proto.Conf.GPIO.toObject(includeInstance, f),\n sw: (f = msg.getSw()) && proto.Conf.GPIO.toObject(includeInstance, f),\n knobonly: jspb.Message.getFieldWithDefault(msg, 4, 0),\n volume: jspb.Message.getBooleanFieldWithDefault(msg, 5, false),\n longpress: jspb.Message.getBooleanFieldWithDefault(msg, 6, false)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.Rotary}\n */\nproto.Conf.Rotary.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.Rotary;\n return proto.Conf.Rotary.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.Rotary} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.Rotary}\n */\nproto.Conf.Rotary.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setA(value);\n break;\n case 2:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setB(value);\n break;\n case 3:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setSw(value);\n break;\n case 4:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setKnobonly(value);\n break;\n case 5:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setVolume(value);\n break;\n case 6:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setLongpress(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.Rotary.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.Rotary.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.Rotary} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Rotary.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getA();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getB();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getSw();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getKnobonly();\n if (f !== 0) {\n writer.writeInt32(\n 4,\n f\n );\n }\n f = message.getVolume();\n if (f) {\n writer.writeBool(\n 5,\n f\n );\n }\n f = message.getLongpress();\n if (f) {\n writer.writeBool(\n 6,\n f\n );\n }\n};\n\n\n/**\n * optional GPIO A = 1;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Rotary.prototype.getA = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 1));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Rotary} returns this\n*/\nproto.Conf.Rotary.prototype.setA = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Rotary} returns this\n */\nproto.Conf.Rotary.prototype.clearA = function() {\n return this.setA(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Rotary.prototype.hasA = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional GPIO B = 2;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Rotary.prototype.getB = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 2));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Rotary} returns this\n*/\nproto.Conf.Rotary.prototype.setB = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Rotary} returns this\n */\nproto.Conf.Rotary.prototype.clearB = function() {\n return this.setB(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Rotary.prototype.hasB = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n/**\n * optional GPIO SW = 3;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Rotary.prototype.getSw = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 3));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Rotary} returns this\n*/\nproto.Conf.Rotary.prototype.setSw = function(value) {\n return jspb.Message.setWrapperField(this, 3, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Rotary} returns this\n */\nproto.Conf.Rotary.prototype.clearSw = function() {\n return this.setSw(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Rotary.prototype.hasSw = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * optional int32 knobonly = 4;\n * @return {number}\n */\nproto.Conf.Rotary.prototype.getKnobonly = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.Rotary} returns this\n */\nproto.Conf.Rotary.prototype.setKnobonly = function(value) {\n return jspb.Message.setProto3IntField(this, 4, value);\n};\n\n\n/**\n * optional bool volume = 5;\n * @return {boolean}\n */\nproto.Conf.Rotary.prototype.getVolume = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.Conf.Rotary} returns this\n */\nproto.Conf.Rotary.prototype.setVolume = function(value) {\n return jspb.Message.setProto3BooleanField(this, 5, value);\n};\n\n\n/**\n * optional bool longpress = 6;\n * @return {boolean}\n */\nproto.Conf.Rotary.prototype.getLongpress = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 6, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.Conf.Rotary} returns this\n */\nproto.Conf.Rotary.prototype.setLongpress = function(value) {\n return jspb.Message.setProto3BooleanField(this, 6, value);\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.ButtonActions.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.ButtonActions.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.ButtonActions} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.ButtonActions.toObject = function(includeInstance, msg) {\n var f, obj = {\n pressed: jspb.Message.getFieldWithDefault(msg, 1, 0),\n released: jspb.Message.getFieldWithDefault(msg, 2, 0)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.ButtonActions}\n */\nproto.Conf.ButtonActions.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.ButtonActions;\n return proto.Conf.ButtonActions.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.ButtonActions} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.ButtonActions}\n */\nproto.Conf.ButtonActions.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {!proto.Conf.ButtonAction} */ (reader.readEnum());\n msg.setPressed(value);\n break;\n case 2:\n var value = /** @type {!proto.Conf.ButtonAction} */ (reader.readEnum());\n msg.setReleased(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.ButtonActions.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.ButtonActions.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.ButtonActions} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.ButtonActions.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getPressed();\n if (f !== 0.0) {\n writer.writeEnum(\n 1,\n f\n );\n }\n f = message.getReleased();\n if (f !== 0.0) {\n writer.writeEnum(\n 2,\n f\n );\n }\n};\n\n\n/**\n * optional ButtonAction pressed = 1;\n * @return {!proto.Conf.ButtonAction}\n */\nproto.Conf.ButtonActions.prototype.getPressed = function() {\n return /** @type {!proto.Conf.ButtonAction} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {!proto.Conf.ButtonAction} value\n * @return {!proto.Conf.ButtonActions} returns this\n */\nproto.Conf.ButtonActions.prototype.setPressed = function(value) {\n return jspb.Message.setProto3EnumField(this, 1, value);\n};\n\n\n/**\n * optional ButtonAction released = 2;\n * @return {!proto.Conf.ButtonAction}\n */\nproto.Conf.ButtonActions.prototype.getReleased = function() {\n return /** @type {!proto.Conf.ButtonAction} */ (jspb.Message.getFieldWithDefault(this, 2, 0));\n};\n\n\n/**\n * @param {!proto.Conf.ButtonAction} value\n * @return {!proto.Conf.ButtonActions} returns this\n */\nproto.Conf.ButtonActions.prototype.setReleased = function(value) {\n return jspb.Message.setProto3EnumField(this, 2, value);\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.Button.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.Button.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.Button} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Button.toObject = function(includeInstance, msg) {\n var f, obj = {\n gpio: (f = msg.getGpio()) && proto.Conf.GPIO.toObject(includeInstance, f),\n pull: jspb.Message.getBooleanFieldWithDefault(msg, 2, false),\n debounce: jspb.Message.getFieldWithDefault(msg, 3, 0),\n shifter: (f = msg.getShifter()) && proto.Conf.GPIO.toObject(includeInstance, f),\n longduration: jspb.Message.getFieldWithDefault(msg, 5, 0),\n normal: (f = msg.getNormal()) && proto.Conf.ButtonActions.toObject(includeInstance, f),\n longpress: (f = msg.getLongpress()) && proto.Conf.ButtonActions.toObject(includeInstance, f),\n shifted: (f = msg.getShifted()) && proto.Conf.ButtonActions.toObject(includeInstance, f),\n longshifted: (f = msg.getLongshifted()) && proto.Conf.ButtonActions.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.Button}\n */\nproto.Conf.Button.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.Button;\n return proto.Conf.Button.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.Button} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.Button}\n */\nproto.Conf.Button.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setGpio(value);\n break;\n case 2:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setPull(value);\n break;\n case 3:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setDebounce(value);\n break;\n case 4:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setShifter(value);\n break;\n case 5:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setLongduration(value);\n break;\n case 6:\n var value = new proto.Conf.ButtonActions;\n reader.readMessage(value,proto.Conf.ButtonActions.deserializeBinaryFromReader);\n msg.setNormal(value);\n break;\n case 7:\n var value = new proto.Conf.ButtonActions;\n reader.readMessage(value,proto.Conf.ButtonActions.deserializeBinaryFromReader);\n msg.setLongpress(value);\n break;\n case 8:\n var value = new proto.Conf.ButtonActions;\n reader.readMessage(value,proto.Conf.ButtonActions.deserializeBinaryFromReader);\n msg.setShifted(value);\n break;\n case 9:\n var value = new proto.Conf.ButtonActions;\n reader.readMessage(value,proto.Conf.ButtonActions.deserializeBinaryFromReader);\n msg.setLongshifted(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.Button.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.Button.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.Button} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Button.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getGpio();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getPull();\n if (f) {\n writer.writeBool(\n 2,\n f\n );\n }\n f = message.getDebounce();\n if (f !== 0) {\n writer.writeInt32(\n 3,\n f\n );\n }\n f = message.getShifter();\n if (f != null) {\n writer.writeMessage(\n 4,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getLongduration();\n if (f !== 0) {\n writer.writeInt32(\n 5,\n f\n );\n }\n f = message.getNormal();\n if (f != null) {\n writer.writeMessage(\n 6,\n f,\n proto.Conf.ButtonActions.serializeBinaryToWriter\n );\n }\n f = message.getLongpress();\n if (f != null) {\n writer.writeMessage(\n 7,\n f,\n proto.Conf.ButtonActions.serializeBinaryToWriter\n );\n }\n f = message.getShifted();\n if (f != null) {\n writer.writeMessage(\n 8,\n f,\n proto.Conf.ButtonActions.serializeBinaryToWriter\n );\n }\n f = message.getLongshifted();\n if (f != null) {\n writer.writeMessage(\n 9,\n f,\n proto.Conf.ButtonActions.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional GPIO gpio = 1;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Button.prototype.getGpio = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 1));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Button} returns this\n*/\nproto.Conf.Button.prototype.setGpio = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Button} returns this\n */\nproto.Conf.Button.prototype.clearGpio = function() {\n return this.setGpio(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Button.prototype.hasGpio = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional bool pull = 2;\n * @return {boolean}\n */\nproto.Conf.Button.prototype.getPull = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.Conf.Button} returns this\n */\nproto.Conf.Button.prototype.setPull = function(value) {\n return jspb.Message.setProto3BooleanField(this, 2, value);\n};\n\n\n/**\n * optional int32 debounce = 3;\n * @return {number}\n */\nproto.Conf.Button.prototype.getDebounce = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.Button} returns this\n */\nproto.Conf.Button.prototype.setDebounce = function(value) {\n return jspb.Message.setProto3IntField(this, 3, value);\n};\n\n\n/**\n * optional GPIO shifter = 4;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Button.prototype.getShifter = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 4));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Button} returns this\n*/\nproto.Conf.Button.prototype.setShifter = function(value) {\n return jspb.Message.setWrapperField(this, 4, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Button} returns this\n */\nproto.Conf.Button.prototype.clearShifter = function() {\n return this.setShifter(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Button.prototype.hasShifter = function() {\n return jspb.Message.getField(this, 4) != null;\n};\n\n\n/**\n * optional int32 longduration = 5;\n * @return {number}\n */\nproto.Conf.Button.prototype.getLongduration = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.Button} returns this\n */\nproto.Conf.Button.prototype.setLongduration = function(value) {\n return jspb.Message.setProto3IntField(this, 5, value);\n};\n\n\n/**\n * optional ButtonActions normal = 6;\n * @return {?proto.Conf.ButtonActions}\n */\nproto.Conf.Button.prototype.getNormal = function() {\n return /** @type{?proto.Conf.ButtonActions} */ (\n jspb.Message.getWrapperField(this, proto.Conf.ButtonActions, 6));\n};\n\n\n/**\n * @param {?proto.Conf.ButtonActions|undefined} value\n * @return {!proto.Conf.Button} returns this\n*/\nproto.Conf.Button.prototype.setNormal = function(value) {\n return jspb.Message.setWrapperField(this, 6, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Button} returns this\n */\nproto.Conf.Button.prototype.clearNormal = function() {\n return this.setNormal(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Button.prototype.hasNormal = function() {\n return jspb.Message.getField(this, 6) != null;\n};\n\n\n/**\n * optional ButtonActions longpress = 7;\n * @return {?proto.Conf.ButtonActions}\n */\nproto.Conf.Button.prototype.getLongpress = function() {\n return /** @type{?proto.Conf.ButtonActions} */ (\n jspb.Message.getWrapperField(this, proto.Conf.ButtonActions, 7));\n};\n\n\n/**\n * @param {?proto.Conf.ButtonActions|undefined} value\n * @return {!proto.Conf.Button} returns this\n*/\nproto.Conf.Button.prototype.setLongpress = function(value) {\n return jspb.Message.setWrapperField(this, 7, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Button} returns this\n */\nproto.Conf.Button.prototype.clearLongpress = function() {\n return this.setLongpress(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Button.prototype.hasLongpress = function() {\n return jspb.Message.getField(this, 7) != null;\n};\n\n\n/**\n * optional ButtonActions shifted = 8;\n * @return {?proto.Conf.ButtonActions}\n */\nproto.Conf.Button.prototype.getShifted = function() {\n return /** @type{?proto.Conf.ButtonActions} */ (\n jspb.Message.getWrapperField(this, proto.Conf.ButtonActions, 8));\n};\n\n\n/**\n * @param {?proto.Conf.ButtonActions|undefined} value\n * @return {!proto.Conf.Button} returns this\n*/\nproto.Conf.Button.prototype.setShifted = function(value) {\n return jspb.Message.setWrapperField(this, 8, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Button} returns this\n */\nproto.Conf.Button.prototype.clearShifted = function() {\n return this.setShifted(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Button.prototype.hasShifted = function() {\n return jspb.Message.getField(this, 8) != null;\n};\n\n\n/**\n * optional ButtonActions longshifted = 9;\n * @return {?proto.Conf.ButtonActions}\n */\nproto.Conf.Button.prototype.getLongshifted = function() {\n return /** @type{?proto.Conf.ButtonActions} */ (\n jspb.Message.getWrapperField(this, proto.Conf.ButtonActions, 9));\n};\n\n\n/**\n * @param {?proto.Conf.ButtonActions|undefined} value\n * @return {!proto.Conf.Button} returns this\n*/\nproto.Conf.Button.prototype.setLongshifted = function(value) {\n return jspb.Message.setWrapperField(this, 9, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Button} returns this\n */\nproto.Conf.Button.prototype.clearLongshifted = function() {\n return this.setLongshifted(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Button.prototype.hasLongshifted = function() {\n return jspb.Message.getField(this, 9) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.EthCommon.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.EthCommon.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.EthCommon} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.EthCommon.toObject = function(includeInstance, msg) {\n var f, obj = {\n model: jspb.Message.getFieldWithDefault(msg, 1, 0),\n rst: (f = msg.getRst()) && proto.Conf.GPIO.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.EthCommon}\n */\nproto.Conf.EthCommon.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.EthCommon;\n return proto.Conf.EthCommon.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.EthCommon} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.EthCommon}\n */\nproto.Conf.EthCommon.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {!proto.Conf.EthModelEnum} */ (reader.readEnum());\n msg.setModel(value);\n break;\n case 2:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setRst(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.EthCommon.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.EthCommon.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.EthCommon} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.EthCommon.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getModel();\n if (f !== 0.0) {\n writer.writeEnum(\n 1,\n f\n );\n }\n f = message.getRst();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional EthModelEnum model = 1;\n * @return {!proto.Conf.EthModelEnum}\n */\nproto.Conf.EthCommon.prototype.getModel = function() {\n return /** @type {!proto.Conf.EthModelEnum} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {!proto.Conf.EthModelEnum} value\n * @return {!proto.Conf.EthCommon} returns this\n */\nproto.Conf.EthCommon.prototype.setModel = function(value) {\n return jspb.Message.setProto3EnumField(this, 1, value);\n};\n\n\n/**\n * optional GPIO rst = 2;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.EthCommon.prototype.getRst = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 2));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.EthCommon} returns this\n*/\nproto.Conf.EthCommon.prototype.setRst = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.EthCommon} returns this\n */\nproto.Conf.EthCommon.prototype.clearRst = function() {\n return this.setRst(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.EthCommon.prototype.hasRst = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.EthSPI.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.EthSPI.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.EthSPI} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.EthSPI.toObject = function(includeInstance, msg) {\n var f, obj = {\n cs: (f = msg.getCs()) && proto.Conf.GPIO.toObject(includeInstance, f),\n speed: jspb.Message.getFieldWithDefault(msg, 2, 0),\n intr: (f = msg.getIntr()) && proto.Conf.GPIO.toObject(includeInstance, f),\n host: jspb.Message.getFieldWithDefault(msg, 4, 0)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.EthSPI}\n */\nproto.Conf.EthSPI.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.EthSPI;\n return proto.Conf.EthSPI.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.EthSPI} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.EthSPI}\n */\nproto.Conf.EthSPI.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setCs(value);\n break;\n case 2:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setSpeed(value);\n break;\n case 3:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setIntr(value);\n break;\n case 4:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setHost(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.EthSPI.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.EthSPI.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.EthSPI} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.EthSPI.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getCs();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getSpeed();\n if (f !== 0) {\n writer.writeInt32(\n 2,\n f\n );\n }\n f = message.getIntr();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getHost();\n if (f !== 0) {\n writer.writeInt32(\n 4,\n f\n );\n }\n};\n\n\n/**\n * optional GPIO cs = 1;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.EthSPI.prototype.getCs = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 1));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.EthSPI} returns this\n*/\nproto.Conf.EthSPI.prototype.setCs = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.EthSPI} returns this\n */\nproto.Conf.EthSPI.prototype.clearCs = function() {\n return this.setCs(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.EthSPI.prototype.hasCs = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional int32 speed = 2;\n * @return {number}\n */\nproto.Conf.EthSPI.prototype.getSpeed = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.EthSPI} returns this\n */\nproto.Conf.EthSPI.prototype.setSpeed = function(value) {\n return jspb.Message.setProto3IntField(this, 2, value);\n};\n\n\n/**\n * optional GPIO intr = 3;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.EthSPI.prototype.getIntr = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 3));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.EthSPI} returns this\n*/\nproto.Conf.EthSPI.prototype.setIntr = function(value) {\n return jspb.Message.setWrapperField(this, 3, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.EthSPI} returns this\n */\nproto.Conf.EthSPI.prototype.clearIntr = function() {\n return this.setIntr(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.EthSPI.prototype.hasIntr = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * optional int32 host = 4;\n * @return {number}\n */\nproto.Conf.EthSPI.prototype.getHost = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.EthSPI} returns this\n */\nproto.Conf.EthSPI.prototype.setHost = function(value) {\n return jspb.Message.setProto3IntField(this, 4, value);\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.EthRMII.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.EthRMII.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.EthRMII} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.EthRMII.toObject = function(includeInstance, msg) {\n var f, obj = {\n mdc: (f = msg.getMdc()) && proto.Conf.GPIO.toObject(includeInstance, f),\n mdio: (f = msg.getMdio()) && proto.Conf.GPIO.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.EthRMII}\n */\nproto.Conf.EthRMII.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.EthRMII;\n return proto.Conf.EthRMII.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.EthRMII} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.EthRMII}\n */\nproto.Conf.EthRMII.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setMdc(value);\n break;\n case 2:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setMdio(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.EthRMII.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.EthRMII.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.EthRMII} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.EthRMII.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getMdc();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getMdio();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional GPIO mdc = 1;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.EthRMII.prototype.getMdc = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 1));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.EthRMII} returns this\n*/\nproto.Conf.EthRMII.prototype.setMdc = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.EthRMII} returns this\n */\nproto.Conf.EthRMII.prototype.clearMdc = function() {\n return this.setMdc(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.EthRMII.prototype.hasMdc = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional GPIO mdio = 2;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.EthRMII.prototype.getMdio = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 2));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.EthRMII} returns this\n*/\nproto.Conf.EthRMII.prototype.setMdio = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.EthRMII} returns this\n */\nproto.Conf.EthRMII.prototype.clearMdio = function() {\n return this.setMdio(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.EthRMII.prototype.hasMdio = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n\n/**\n * Oneof group definitions for this message. Each group defines the field\n * numbers belonging to that group. When of these fields' value is set, all\n * other fields in the group are cleared. During deserialization, if multiple\n * fields are encountered for a group, only the last value seen will be kept.\n * @private {!Array>}\n * @const\n */\nproto.Conf.Eth.oneofGroups_ = [[3,4]];\n\n/**\n * @enum {number}\n */\nproto.Conf.Eth.EthtypeCase = {\n ETHTYPE_NOT_SET: 0,\n SPI: 3,\n RMII: 4\n};\n\n/**\n * @return {proto.Conf.Eth.EthtypeCase}\n */\nproto.Conf.Eth.prototype.getEthtypeCase = function() {\n return /** @type {proto.Conf.Eth.EthtypeCase} */(jspb.Message.computeOneofCase(this, proto.Conf.Eth.oneofGroups_[0]));\n};\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.Eth.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.Eth.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.Eth} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Eth.toObject = function(includeInstance, msg) {\n var f, obj = {\n type: jspb.Message.getFieldWithDefault(msg, 1, 0),\n common: (f = msg.getCommon()) && proto.Conf.EthCommon.toObject(includeInstance, f),\n spi: (f = msg.getSpi()) && proto.Conf.EthSPI.toObject(includeInstance, f),\n rmii: (f = msg.getRmii()) && proto.Conf.EthRMII.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.Eth}\n */\nproto.Conf.Eth.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.Eth;\n return proto.Conf.Eth.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.Eth} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.Eth}\n */\nproto.Conf.Eth.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {!proto.Conf.DeviceTypeEnum} */ (reader.readEnum());\n msg.setType(value);\n break;\n case 2:\n var value = new proto.Conf.EthCommon;\n reader.readMessage(value,proto.Conf.EthCommon.deserializeBinaryFromReader);\n msg.setCommon(value);\n break;\n case 3:\n var value = new proto.Conf.EthSPI;\n reader.readMessage(value,proto.Conf.EthSPI.deserializeBinaryFromReader);\n msg.setSpi(value);\n break;\n case 4:\n var value = new proto.Conf.EthRMII;\n reader.readMessage(value,proto.Conf.EthRMII.deserializeBinaryFromReader);\n msg.setRmii(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.Eth.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.Eth.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.Eth} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Eth.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getType();\n if (f !== 0.0) {\n writer.writeEnum(\n 1,\n f\n );\n }\n f = message.getCommon();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.EthCommon.serializeBinaryToWriter\n );\n }\n f = message.getSpi();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.EthSPI.serializeBinaryToWriter\n );\n }\n f = message.getRmii();\n if (f != null) {\n writer.writeMessage(\n 4,\n f,\n proto.Conf.EthRMII.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional DeviceTypeEnum type = 1;\n * @return {!proto.Conf.DeviceTypeEnum}\n */\nproto.Conf.Eth.prototype.getType = function() {\n return /** @type {!proto.Conf.DeviceTypeEnum} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {!proto.Conf.DeviceTypeEnum} value\n * @return {!proto.Conf.Eth} returns this\n */\nproto.Conf.Eth.prototype.setType = function(value) {\n return jspb.Message.setProto3EnumField(this, 1, value);\n};\n\n\n/**\n * optional EthCommon common = 2;\n * @return {?proto.Conf.EthCommon}\n */\nproto.Conf.Eth.prototype.getCommon = function() {\n return /** @type{?proto.Conf.EthCommon} */ (\n jspb.Message.getWrapperField(this, proto.Conf.EthCommon, 2));\n};\n\n\n/**\n * @param {?proto.Conf.EthCommon|undefined} value\n * @return {!proto.Conf.Eth} returns this\n*/\nproto.Conf.Eth.prototype.setCommon = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Eth} returns this\n */\nproto.Conf.Eth.prototype.clearCommon = function() {\n return this.setCommon(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Eth.prototype.hasCommon = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n/**\n * optional EthSPI spi = 3;\n * @return {?proto.Conf.EthSPI}\n */\nproto.Conf.Eth.prototype.getSpi = function() {\n return /** @type{?proto.Conf.EthSPI} */ (\n jspb.Message.getWrapperField(this, proto.Conf.EthSPI, 3));\n};\n\n\n/**\n * @param {?proto.Conf.EthSPI|undefined} value\n * @return {!proto.Conf.Eth} returns this\n*/\nproto.Conf.Eth.prototype.setSpi = function(value) {\n return jspb.Message.setOneofWrapperField(this, 3, proto.Conf.Eth.oneofGroups_[0], value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Eth} returns this\n */\nproto.Conf.Eth.prototype.clearSpi = function() {\n return this.setSpi(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Eth.prototype.hasSpi = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * optional EthRMII rmii = 4;\n * @return {?proto.Conf.EthRMII}\n */\nproto.Conf.Eth.prototype.getRmii = function() {\n return /** @type{?proto.Conf.EthRMII} */ (\n jspb.Message.getWrapperField(this, proto.Conf.EthRMII, 4));\n};\n\n\n/**\n * @param {?proto.Conf.EthRMII|undefined} value\n * @return {!proto.Conf.Eth} returns this\n*/\nproto.Conf.Eth.prototype.setRmii = function(value) {\n return jspb.Message.setOneofWrapperField(this, 4, proto.Conf.Eth.oneofGroups_[0], value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Eth} returns this\n */\nproto.Conf.Eth.prototype.clearRmii = function() {\n return this.setRmii(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Eth.prototype.hasRmii = function() {\n return jspb.Message.getField(this, 4) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.Battery.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.Battery.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.Battery} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Battery.toObject = function(includeInstance, msg) {\n var f, obj = {\n channel: jspb.Message.getFieldWithDefault(msg, 1, 0),\n scale: jspb.Message.getFloatingPointFieldWithDefault(msg, 2, 0.0),\n cells: jspb.Message.getFieldWithDefault(msg, 3, 0),\n atten: jspb.Message.getFieldWithDefault(msg, 4, 0)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.Battery}\n */\nproto.Conf.Battery.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.Battery;\n return proto.Conf.Battery.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.Battery} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.Battery}\n */\nproto.Conf.Battery.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {!proto.Conf.BatteryChannelEnum} */ (reader.readEnum());\n msg.setChannel(value);\n break;\n case 2:\n var value = /** @type {number} */ (reader.readFloat());\n msg.setScale(value);\n break;\n case 3:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setCells(value);\n break;\n case 4:\n var value = /** @type {!proto.Conf.BatteryAttenEnum} */ (reader.readEnum());\n msg.setAtten(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.Battery.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.Battery.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.Battery} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Battery.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getChannel();\n if (f !== 0.0) {\n writer.writeEnum(\n 1,\n f\n );\n }\n f = message.getScale();\n if (f !== 0.0) {\n writer.writeFloat(\n 2,\n f\n );\n }\n f = message.getCells();\n if (f !== 0) {\n writer.writeInt32(\n 3,\n f\n );\n }\n f = message.getAtten();\n if (f !== 0.0) {\n writer.writeEnum(\n 4,\n f\n );\n }\n};\n\n\n/**\n * optional BatteryChannelEnum channel = 1;\n * @return {!proto.Conf.BatteryChannelEnum}\n */\nproto.Conf.Battery.prototype.getChannel = function() {\n return /** @type {!proto.Conf.BatteryChannelEnum} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {!proto.Conf.BatteryChannelEnum} value\n * @return {!proto.Conf.Battery} returns this\n */\nproto.Conf.Battery.prototype.setChannel = function(value) {\n return jspb.Message.setProto3EnumField(this, 1, value);\n};\n\n\n/**\n * optional float scale = 2;\n * @return {number}\n */\nproto.Conf.Battery.prototype.getScale = function() {\n return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 2, 0.0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.Battery} returns this\n */\nproto.Conf.Battery.prototype.setScale = function(value) {\n return jspb.Message.setProto3FloatField(this, 2, value);\n};\n\n\n/**\n * optional int32 cells = 3;\n * @return {number}\n */\nproto.Conf.Battery.prototype.getCells = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.Battery} returns this\n */\nproto.Conf.Battery.prototype.setCells = function(value) {\n return jspb.Message.setProto3IntField(this, 3, value);\n};\n\n\n/**\n * optional BatteryAttenEnum atten = 4;\n * @return {!proto.Conf.BatteryAttenEnum}\n */\nproto.Conf.Battery.prototype.getAtten = function() {\n return /** @type {!proto.Conf.BatteryAttenEnum} */ (jspb.Message.getFieldWithDefault(this, 4, 0));\n};\n\n\n/**\n * @param {!proto.Conf.BatteryAttenEnum} value\n * @return {!proto.Conf.Battery} returns this\n */\nproto.Conf.Battery.prototype.setAtten = function(value) {\n return jspb.Message.setProto3EnumField(this, 4, value);\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.Gpios.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.Gpios.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.Gpios} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Gpios.toObject = function(includeInstance, msg) {\n var f, obj = {\n greenled: (f = msg.getGreenled()) && proto.Conf.GPIO.toObject(includeInstance, f),\n redled: (f = msg.getRedled()) && proto.Conf.GPIO.toObject(includeInstance, f),\n audiojack: (f = msg.getAudiojack()) && proto.Conf.GPIO.toObject(includeInstance, f),\n amp: (f = msg.getAmp()) && proto.Conf.GPIO.toObject(includeInstance, f),\n power: (f = msg.getPower()) && proto.Conf.GPIO.toObject(includeInstance, f),\n ir: (f = msg.getIr()) && proto.Conf.GPIO.toObject(includeInstance, f),\n jack: (f = msg.getJack()) && proto.Conf.GPIO.toObject(includeInstance, f),\n spkfault: (f = msg.getSpkfault()) && proto.Conf.GPIO.toObject(includeInstance, f),\n vcc: (f = msg.getVcc()) && proto.Conf.GPIO.toObject(includeInstance, f),\n gnd: (f = msg.getGnd()) && proto.Conf.GPIO.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.Gpios}\n */\nproto.Conf.Gpios.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.Gpios;\n return proto.Conf.Gpios.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.Gpios} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.Gpios}\n */\nproto.Conf.Gpios.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setGreenled(value);\n break;\n case 2:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setRedled(value);\n break;\n case 3:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setAudiojack(value);\n break;\n case 4:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setAmp(value);\n break;\n case 5:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setPower(value);\n break;\n case 6:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setIr(value);\n break;\n case 7:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setJack(value);\n break;\n case 8:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setSpkfault(value);\n break;\n case 9:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setVcc(value);\n break;\n case 10:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setGnd(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.Gpios.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.Gpios.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.Gpios} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Gpios.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getGreenled();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getRedled();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getAudiojack();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getAmp();\n if (f != null) {\n writer.writeMessage(\n 4,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getPower();\n if (f != null) {\n writer.writeMessage(\n 5,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getIr();\n if (f != null) {\n writer.writeMessage(\n 6,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getJack();\n if (f != null) {\n writer.writeMessage(\n 7,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getSpkfault();\n if (f != null) {\n writer.writeMessage(\n 8,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getVcc();\n if (f != null) {\n writer.writeMessage(\n 9,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getGnd();\n if (f != null) {\n writer.writeMessage(\n 10,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional GPIO greenLED = 1;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Gpios.prototype.getGreenled = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 1));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Gpios} returns this\n*/\nproto.Conf.Gpios.prototype.setGreenled = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Gpios} returns this\n */\nproto.Conf.Gpios.prototype.clearGreenled = function() {\n return this.setGreenled(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Gpios.prototype.hasGreenled = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional GPIO redLED = 2;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Gpios.prototype.getRedled = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 2));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Gpios} returns this\n*/\nproto.Conf.Gpios.prototype.setRedled = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Gpios} returns this\n */\nproto.Conf.Gpios.prototype.clearRedled = function() {\n return this.setRedled(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Gpios.prototype.hasRedled = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n/**\n * optional GPIO audioJack = 3;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Gpios.prototype.getAudiojack = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 3));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Gpios} returns this\n*/\nproto.Conf.Gpios.prototype.setAudiojack = function(value) {\n return jspb.Message.setWrapperField(this, 3, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Gpios} returns this\n */\nproto.Conf.Gpios.prototype.clearAudiojack = function() {\n return this.setAudiojack(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Gpios.prototype.hasAudiojack = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * optional GPIO amp = 4;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Gpios.prototype.getAmp = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 4));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Gpios} returns this\n*/\nproto.Conf.Gpios.prototype.setAmp = function(value) {\n return jspb.Message.setWrapperField(this, 4, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Gpios} returns this\n */\nproto.Conf.Gpios.prototype.clearAmp = function() {\n return this.setAmp(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Gpios.prototype.hasAmp = function() {\n return jspb.Message.getField(this, 4) != null;\n};\n\n\n/**\n * optional GPIO power = 5;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Gpios.prototype.getPower = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 5));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Gpios} returns this\n*/\nproto.Conf.Gpios.prototype.setPower = function(value) {\n return jspb.Message.setWrapperField(this, 5, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Gpios} returns this\n */\nproto.Conf.Gpios.prototype.clearPower = function() {\n return this.setPower(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Gpios.prototype.hasPower = function() {\n return jspb.Message.getField(this, 5) != null;\n};\n\n\n/**\n * optional GPIO ir = 6;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Gpios.prototype.getIr = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 6));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Gpios} returns this\n*/\nproto.Conf.Gpios.prototype.setIr = function(value) {\n return jspb.Message.setWrapperField(this, 6, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Gpios} returns this\n */\nproto.Conf.Gpios.prototype.clearIr = function() {\n return this.setIr(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Gpios.prototype.hasIr = function() {\n return jspb.Message.getField(this, 6) != null;\n};\n\n\n/**\n * optional GPIO jack = 7;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Gpios.prototype.getJack = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 7));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Gpios} returns this\n*/\nproto.Conf.Gpios.prototype.setJack = function(value) {\n return jspb.Message.setWrapperField(this, 7, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Gpios} returns this\n */\nproto.Conf.Gpios.prototype.clearJack = function() {\n return this.setJack(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Gpios.prototype.hasJack = function() {\n return jspb.Message.getField(this, 7) != null;\n};\n\n\n/**\n * optional GPIO spkfault = 8;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Gpios.prototype.getSpkfault = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 8));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Gpios} returns this\n*/\nproto.Conf.Gpios.prototype.setSpkfault = function(value) {\n return jspb.Message.setWrapperField(this, 8, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Gpios} returns this\n */\nproto.Conf.Gpios.prototype.clearSpkfault = function() {\n return this.setSpkfault(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Gpios.prototype.hasSpkfault = function() {\n return jspb.Message.getField(this, 8) != null;\n};\n\n\n/**\n * optional GPIO Vcc = 9;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Gpios.prototype.getVcc = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 9));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Gpios} returns this\n*/\nproto.Conf.Gpios.prototype.setVcc = function(value) {\n return jspb.Message.setWrapperField(this, 9, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Gpios} returns this\n */\nproto.Conf.Gpios.prototype.clearVcc = function() {\n return this.setVcc(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Gpios.prototype.hasVcc = function() {\n return jspb.Message.getField(this, 9) != null;\n};\n\n\n/**\n * optional GPIO GND = 10;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.Gpios.prototype.getGnd = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 10));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.Gpios} returns this\n*/\nproto.Conf.Gpios.prototype.setGnd = function(value) {\n return jspb.Message.setWrapperField(this, 10, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Gpios} returns this\n */\nproto.Conf.Gpios.prototype.clearGnd = function() {\n return this.setGnd(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Gpios.prototype.hasGnd = function() {\n return jspb.Message.getField(this, 10) != null;\n};\n\n\n\n/**\n * List of repeated fields within this message type.\n * @private {!Array}\n * @const\n */\nproto.Conf.Dev.repeatedFields_ = [9];\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.Dev.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.Dev.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.Dev} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Dev.toObject = function(includeInstance, msg) {\n var f, obj = {\n spi: (f = msg.getSpi()) && proto.Conf.SPIBus.toObject(includeInstance, f),\n i2c: (f = msg.getI2c()) && proto.Conf.I2CBus.toObject(includeInstance, f),\n dac: (f = msg.getDac()) && proto.Conf.DACDev.toObject(includeInstance, f),\n spdif: (f = msg.getSpdif()) && proto.Conf.SPDIFDev.toObject(includeInstance, f),\n display: (f = msg.getDisplay()) && proto.Conf.DisplayDev.toObject(includeInstance, f),\n gpioExp: (f = msg.getGpioExp()) && proto.Conf.GPIOExp.toObject(includeInstance, f),\n ledStrip: (f = msg.getLedStrip()) && proto.Conf.LEDStrip.toObject(includeInstance, f),\n rotary: (f = msg.getRotary()) && proto.Conf.Rotary.toObject(includeInstance, f),\n buttonsList: jspb.Message.toObjectList(msg.getButtonsList(),\n proto.Conf.Button.toObject, includeInstance),\n eth: (f = msg.getEth()) && proto.Conf.Eth.toObject(includeInstance, f),\n battery: (f = msg.getBattery()) && proto.Conf.Battery.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.Dev}\n */\nproto.Conf.Dev.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.Dev;\n return proto.Conf.Dev.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.Dev} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.Dev}\n */\nproto.Conf.Dev.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.SPIBus;\n reader.readMessage(value,proto.Conf.SPIBus.deserializeBinaryFromReader);\n msg.setSpi(value);\n break;\n case 2:\n var value = new proto.Conf.I2CBus;\n reader.readMessage(value,proto.Conf.I2CBus.deserializeBinaryFromReader);\n msg.setI2c(value);\n break;\n case 3:\n var value = new proto.Conf.DACDev;\n reader.readMessage(value,proto.Conf.DACDev.deserializeBinaryFromReader);\n msg.setDac(value);\n break;\n case 4:\n var value = new proto.Conf.SPDIFDev;\n reader.readMessage(value,proto.Conf.SPDIFDev.deserializeBinaryFromReader);\n msg.setSpdif(value);\n break;\n case 5:\n var value = new proto.Conf.DisplayDev;\n reader.readMessage(value,proto.Conf.DisplayDev.deserializeBinaryFromReader);\n msg.setDisplay(value);\n break;\n case 6:\n var value = new proto.Conf.GPIOExp;\n reader.readMessage(value,proto.Conf.GPIOExp.deserializeBinaryFromReader);\n msg.setGpioExp(value);\n break;\n case 7:\n var value = new proto.Conf.LEDStrip;\n reader.readMessage(value,proto.Conf.LEDStrip.deserializeBinaryFromReader);\n msg.setLedStrip(value);\n break;\n case 8:\n var value = new proto.Conf.Rotary;\n reader.readMessage(value,proto.Conf.Rotary.deserializeBinaryFromReader);\n msg.setRotary(value);\n break;\n case 9:\n var value = new proto.Conf.Button;\n reader.readMessage(value,proto.Conf.Button.deserializeBinaryFromReader);\n msg.addButtons(value);\n break;\n case 10:\n var value = new proto.Conf.Eth;\n reader.readMessage(value,proto.Conf.Eth.deserializeBinaryFromReader);\n msg.setEth(value);\n break;\n case 11:\n var value = new proto.Conf.Battery;\n reader.readMessage(value,proto.Conf.Battery.deserializeBinaryFromReader);\n msg.setBattery(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.Dev.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.Dev.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.Dev} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Dev.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getSpi();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.SPIBus.serializeBinaryToWriter\n );\n }\n f = message.getI2c();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.I2CBus.serializeBinaryToWriter\n );\n }\n f = message.getDac();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.DACDev.serializeBinaryToWriter\n );\n }\n f = message.getSpdif();\n if (f != null) {\n writer.writeMessage(\n 4,\n f,\n proto.Conf.SPDIFDev.serializeBinaryToWriter\n );\n }\n f = message.getDisplay();\n if (f != null) {\n writer.writeMessage(\n 5,\n f,\n proto.Conf.DisplayDev.serializeBinaryToWriter\n );\n }\n f = message.getGpioExp();\n if (f != null) {\n writer.writeMessage(\n 6,\n f,\n proto.Conf.GPIOExp.serializeBinaryToWriter\n );\n }\n f = message.getLedStrip();\n if (f != null) {\n writer.writeMessage(\n 7,\n f,\n proto.Conf.LEDStrip.serializeBinaryToWriter\n );\n }\n f = message.getRotary();\n if (f != null) {\n writer.writeMessage(\n 8,\n f,\n proto.Conf.Rotary.serializeBinaryToWriter\n );\n }\n f = message.getButtonsList();\n if (f.length > 0) {\n writer.writeRepeatedMessage(\n 9,\n f,\n proto.Conf.Button.serializeBinaryToWriter\n );\n }\n f = message.getEth();\n if (f != null) {\n writer.writeMessage(\n 10,\n f,\n proto.Conf.Eth.serializeBinaryToWriter\n );\n }\n f = message.getBattery();\n if (f != null) {\n writer.writeMessage(\n 11,\n f,\n proto.Conf.Battery.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional SPIBus spi = 1;\n * @return {?proto.Conf.SPIBus}\n */\nproto.Conf.Dev.prototype.getSpi = function() {\n return /** @type{?proto.Conf.SPIBus} */ (\n jspb.Message.getWrapperField(this, proto.Conf.SPIBus, 1));\n};\n\n\n/**\n * @param {?proto.Conf.SPIBus|undefined} value\n * @return {!proto.Conf.Dev} returns this\n*/\nproto.Conf.Dev.prototype.setSpi = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Dev} returns this\n */\nproto.Conf.Dev.prototype.clearSpi = function() {\n return this.setSpi(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Dev.prototype.hasSpi = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional I2CBus i2c = 2;\n * @return {?proto.Conf.I2CBus}\n */\nproto.Conf.Dev.prototype.getI2c = function() {\n return /** @type{?proto.Conf.I2CBus} */ (\n jspb.Message.getWrapperField(this, proto.Conf.I2CBus, 2));\n};\n\n\n/**\n * @param {?proto.Conf.I2CBus|undefined} value\n * @return {!proto.Conf.Dev} returns this\n*/\nproto.Conf.Dev.prototype.setI2c = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Dev} returns this\n */\nproto.Conf.Dev.prototype.clearI2c = function() {\n return this.setI2c(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Dev.prototype.hasI2c = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n/**\n * optional DACDev dac = 3;\n * @return {?proto.Conf.DACDev}\n */\nproto.Conf.Dev.prototype.getDac = function() {\n return /** @type{?proto.Conf.DACDev} */ (\n jspb.Message.getWrapperField(this, proto.Conf.DACDev, 3));\n};\n\n\n/**\n * @param {?proto.Conf.DACDev|undefined} value\n * @return {!proto.Conf.Dev} returns this\n*/\nproto.Conf.Dev.prototype.setDac = function(value) {\n return jspb.Message.setWrapperField(this, 3, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Dev} returns this\n */\nproto.Conf.Dev.prototype.clearDac = function() {\n return this.setDac(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Dev.prototype.hasDac = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * optional SPDIFDev spdif = 4;\n * @return {?proto.Conf.SPDIFDev}\n */\nproto.Conf.Dev.prototype.getSpdif = function() {\n return /** @type{?proto.Conf.SPDIFDev} */ (\n jspb.Message.getWrapperField(this, proto.Conf.SPDIFDev, 4));\n};\n\n\n/**\n * @param {?proto.Conf.SPDIFDev|undefined} value\n * @return {!proto.Conf.Dev} returns this\n*/\nproto.Conf.Dev.prototype.setSpdif = function(value) {\n return jspb.Message.setWrapperField(this, 4, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Dev} returns this\n */\nproto.Conf.Dev.prototype.clearSpdif = function() {\n return this.setSpdif(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Dev.prototype.hasSpdif = function() {\n return jspb.Message.getField(this, 4) != null;\n};\n\n\n/**\n * optional DisplayDev display = 5;\n * @return {?proto.Conf.DisplayDev}\n */\nproto.Conf.Dev.prototype.getDisplay = function() {\n return /** @type{?proto.Conf.DisplayDev} */ (\n jspb.Message.getWrapperField(this, proto.Conf.DisplayDev, 5));\n};\n\n\n/**\n * @param {?proto.Conf.DisplayDev|undefined} value\n * @return {!proto.Conf.Dev} returns this\n*/\nproto.Conf.Dev.prototype.setDisplay = function(value) {\n return jspb.Message.setWrapperField(this, 5, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Dev} returns this\n */\nproto.Conf.Dev.prototype.clearDisplay = function() {\n return this.setDisplay(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Dev.prototype.hasDisplay = function() {\n return jspb.Message.getField(this, 5) != null;\n};\n\n\n/**\n * optional GPIOExp gpio_exp = 6;\n * @return {?proto.Conf.GPIOExp}\n */\nproto.Conf.Dev.prototype.getGpioExp = function() {\n return /** @type{?proto.Conf.GPIOExp} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIOExp, 6));\n};\n\n\n/**\n * @param {?proto.Conf.GPIOExp|undefined} value\n * @return {!proto.Conf.Dev} returns this\n*/\nproto.Conf.Dev.prototype.setGpioExp = function(value) {\n return jspb.Message.setWrapperField(this, 6, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Dev} returns this\n */\nproto.Conf.Dev.prototype.clearGpioExp = function() {\n return this.setGpioExp(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Dev.prototype.hasGpioExp = function() {\n return jspb.Message.getField(this, 6) != null;\n};\n\n\n/**\n * optional LEDStrip led_strip = 7;\n * @return {?proto.Conf.LEDStrip}\n */\nproto.Conf.Dev.prototype.getLedStrip = function() {\n return /** @type{?proto.Conf.LEDStrip} */ (\n jspb.Message.getWrapperField(this, proto.Conf.LEDStrip, 7));\n};\n\n\n/**\n * @param {?proto.Conf.LEDStrip|undefined} value\n * @return {!proto.Conf.Dev} returns this\n*/\nproto.Conf.Dev.prototype.setLedStrip = function(value) {\n return jspb.Message.setWrapperField(this, 7, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Dev} returns this\n */\nproto.Conf.Dev.prototype.clearLedStrip = function() {\n return this.setLedStrip(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Dev.prototype.hasLedStrip = function() {\n return jspb.Message.getField(this, 7) != null;\n};\n\n\n/**\n * optional Rotary rotary = 8;\n * @return {?proto.Conf.Rotary}\n */\nproto.Conf.Dev.prototype.getRotary = function() {\n return /** @type{?proto.Conf.Rotary} */ (\n jspb.Message.getWrapperField(this, proto.Conf.Rotary, 8));\n};\n\n\n/**\n * @param {?proto.Conf.Rotary|undefined} value\n * @return {!proto.Conf.Dev} returns this\n*/\nproto.Conf.Dev.prototype.setRotary = function(value) {\n return jspb.Message.setWrapperField(this, 8, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Dev} returns this\n */\nproto.Conf.Dev.prototype.clearRotary = function() {\n return this.setRotary(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Dev.prototype.hasRotary = function() {\n return jspb.Message.getField(this, 8) != null;\n};\n\n\n/**\n * repeated Button buttons = 9;\n * @return {!Array}\n */\nproto.Conf.Dev.prototype.getButtonsList = function() {\n return /** @type{!Array} */ (\n jspb.Message.getRepeatedWrapperField(this, proto.Conf.Button, 9));\n};\n\n\n/**\n * @param {!Array} value\n * @return {!proto.Conf.Dev} returns this\n*/\nproto.Conf.Dev.prototype.setButtonsList = function(value) {\n return jspb.Message.setRepeatedWrapperField(this, 9, value);\n};\n\n\n/**\n * @param {!proto.Conf.Button=} opt_value\n * @param {number=} opt_index\n * @return {!proto.Conf.Button}\n */\nproto.Conf.Dev.prototype.addButtons = function(opt_value, opt_index) {\n return jspb.Message.addToRepeatedWrapperField(this, 9, opt_value, proto.Conf.Button, opt_index);\n};\n\n\n/**\n * Clears the list making it empty but non-null.\n * @return {!proto.Conf.Dev} returns this\n */\nproto.Conf.Dev.prototype.clearButtonsList = function() {\n return this.setButtonsList([]);\n};\n\n\n/**\n * optional Eth eth = 10;\n * @return {?proto.Conf.Eth}\n */\nproto.Conf.Dev.prototype.getEth = function() {\n return /** @type{?proto.Conf.Eth} */ (\n jspb.Message.getWrapperField(this, proto.Conf.Eth, 10));\n};\n\n\n/**\n * @param {?proto.Conf.Eth|undefined} value\n * @return {!proto.Conf.Dev} returns this\n*/\nproto.Conf.Dev.prototype.setEth = function(value) {\n return jspb.Message.setWrapperField(this, 10, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Dev} returns this\n */\nproto.Conf.Dev.prototype.clearEth = function() {\n return this.setEth(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Dev.prototype.hasEth = function() {\n return jspb.Message.getField(this, 10) != null;\n};\n\n\n/**\n * optional Battery battery = 11;\n * @return {?proto.Conf.Battery}\n */\nproto.Conf.Dev.prototype.getBattery = function() {\n return /** @type{?proto.Conf.Battery} */ (\n jspb.Message.getWrapperField(this, proto.Conf.Battery, 11));\n};\n\n\n/**\n * @param {?proto.Conf.Battery|undefined} value\n * @return {!proto.Conf.Dev} returns this\n*/\nproto.Conf.Dev.prototype.setBattery = function(value) {\n return jspb.Message.setWrapperField(this, 11, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Dev} returns this\n */\nproto.Conf.Dev.prototype.clearBattery = function() {\n return this.setBattery(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Dev.prototype.hasBattery = function() {\n return jspb.Message.getField(this, 11) != null;\n};\n\n\n\n/**\n * List of repeated fields within this message type.\n * @private {!Array}\n * @const\n */\nproto.Conf.SleepService.repeatedFields_ = [4,5];\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.SleepService.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.SleepService.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.SleepService} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.SleepService.toObject = function(includeInstance, msg) {\n var f, obj = {\n delay: jspb.Message.getFieldWithDefault(msg, 1, 0),\n spurious: jspb.Message.getFieldWithDefault(msg, 2, 0),\n sleep: (f = msg.getSleep()) && proto.Conf.GPIO.toObject(includeInstance, f),\n wakeList: jspb.Message.toObjectList(msg.getWakeList(),\n proto.Conf.GPIO.toObject, includeInstance),\n rtcList: jspb.Message.toObjectList(msg.getRtcList(),\n proto.Conf.GPIO.toObject, includeInstance),\n batt: jspb.Message.getFloatingPointFieldWithDefault(msg, 6, 0.0)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.SleepService}\n */\nproto.Conf.SleepService.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.SleepService;\n return proto.Conf.SleepService.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.SleepService} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.SleepService}\n */\nproto.Conf.SleepService.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {number} */ (reader.readUint32());\n msg.setDelay(value);\n break;\n case 2:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setSpurious(value);\n break;\n case 3:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.setSleep(value);\n break;\n case 4:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.addWake(value);\n break;\n case 5:\n var value = new proto.Conf.GPIO;\n reader.readMessage(value,proto.Conf.GPIO.deserializeBinaryFromReader);\n msg.addRtc(value);\n break;\n case 6:\n var value = /** @type {number} */ (reader.readFloat());\n msg.setBatt(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.SleepService.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.SleepService.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.SleepService} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.SleepService.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getDelay();\n if (f !== 0) {\n writer.writeUint32(\n 1,\n f\n );\n }\n f = message.getSpurious();\n if (f !== 0) {\n writer.writeInt32(\n 2,\n f\n );\n }\n f = message.getSleep();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getWakeList();\n if (f.length > 0) {\n writer.writeRepeatedMessage(\n 4,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getRtcList();\n if (f.length > 0) {\n writer.writeRepeatedMessage(\n 5,\n f,\n proto.Conf.GPIO.serializeBinaryToWriter\n );\n }\n f = message.getBatt();\n if (f !== 0.0) {\n writer.writeFloat(\n 6,\n f\n );\n }\n};\n\n\n/**\n * optional uint32 delay = 1;\n * @return {number}\n */\nproto.Conf.SleepService.prototype.getDelay = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.SleepService} returns this\n */\nproto.Conf.SleepService.prototype.setDelay = function(value) {\n return jspb.Message.setProto3IntField(this, 1, value);\n};\n\n\n/**\n * optional int32 spurious = 2;\n * @return {number}\n */\nproto.Conf.SleepService.prototype.getSpurious = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.SleepService} returns this\n */\nproto.Conf.SleepService.prototype.setSpurious = function(value) {\n return jspb.Message.setProto3IntField(this, 2, value);\n};\n\n\n/**\n * optional GPIO sleep = 3;\n * @return {?proto.Conf.GPIO}\n */\nproto.Conf.SleepService.prototype.getSleep = function() {\n return /** @type{?proto.Conf.GPIO} */ (\n jspb.Message.getWrapperField(this, proto.Conf.GPIO, 3));\n};\n\n\n/**\n * @param {?proto.Conf.GPIO|undefined} value\n * @return {!proto.Conf.SleepService} returns this\n*/\nproto.Conf.SleepService.prototype.setSleep = function(value) {\n return jspb.Message.setWrapperField(this, 3, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.SleepService} returns this\n */\nproto.Conf.SleepService.prototype.clearSleep = function() {\n return this.setSleep(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.SleepService.prototype.hasSleep = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * repeated GPIO wake = 4;\n * @return {!Array}\n */\nproto.Conf.SleepService.prototype.getWakeList = function() {\n return /** @type{!Array} */ (\n jspb.Message.getRepeatedWrapperField(this, proto.Conf.GPIO, 4));\n};\n\n\n/**\n * @param {!Array} value\n * @return {!proto.Conf.SleepService} returns this\n*/\nproto.Conf.SleepService.prototype.setWakeList = function(value) {\n return jspb.Message.setRepeatedWrapperField(this, 4, value);\n};\n\n\n/**\n * @param {!proto.Conf.GPIO=} opt_value\n * @param {number=} opt_index\n * @return {!proto.Conf.GPIO}\n */\nproto.Conf.SleepService.prototype.addWake = function(opt_value, opt_index) {\n return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.Conf.GPIO, opt_index);\n};\n\n\n/**\n * Clears the list making it empty but non-null.\n * @return {!proto.Conf.SleepService} returns this\n */\nproto.Conf.SleepService.prototype.clearWakeList = function() {\n return this.setWakeList([]);\n};\n\n\n/**\n * repeated GPIO rtc = 5;\n * @return {!Array}\n */\nproto.Conf.SleepService.prototype.getRtcList = function() {\n return /** @type{!Array} */ (\n jspb.Message.getRepeatedWrapperField(this, proto.Conf.GPIO, 5));\n};\n\n\n/**\n * @param {!Array} value\n * @return {!proto.Conf.SleepService} returns this\n*/\nproto.Conf.SleepService.prototype.setRtcList = function(value) {\n return jspb.Message.setRepeatedWrapperField(this, 5, value);\n};\n\n\n/**\n * @param {!proto.Conf.GPIO=} opt_value\n * @param {number=} opt_index\n * @return {!proto.Conf.GPIO}\n */\nproto.Conf.SleepService.prototype.addRtc = function(opt_value, opt_index) {\n return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.Conf.GPIO, opt_index);\n};\n\n\n/**\n * Clears the list making it empty but non-null.\n * @return {!proto.Conf.SleepService} returns this\n */\nproto.Conf.SleepService.prototype.clearRtcList = function() {\n return this.setRtcList([]);\n};\n\n\n/**\n * optional float batt = 6;\n * @return {number}\n */\nproto.Conf.SleepService.prototype.getBatt = function() {\n return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 6, 0.0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.SleepService} returns this\n */\nproto.Conf.SleepService.prototype.setBatt = function(value) {\n return jspb.Message.setProto3FloatField(this, 6, value);\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.Artwork.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.Artwork.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.Artwork} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Artwork.toObject = function(includeInstance, msg) {\n var f, obj = {\n enabled: jspb.Message.getBooleanFieldWithDefault(msg, 1, false),\n resize: jspb.Message.getFieldWithDefault(msg, 2, 0)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.Artwork}\n */\nproto.Conf.Artwork.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.Artwork;\n return proto.Conf.Artwork.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.Artwork} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.Artwork}\n */\nproto.Conf.Artwork.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setEnabled(value);\n break;\n case 2:\n var value = /** @type {number} */ (reader.readUint32());\n msg.setResize(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.Artwork.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.Artwork.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.Artwork} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Artwork.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getEnabled();\n if (f) {\n writer.writeBool(\n 1,\n f\n );\n }\n f = message.getResize();\n if (f !== 0) {\n writer.writeUint32(\n 2,\n f\n );\n }\n};\n\n\n/**\n * optional bool enabled = 1;\n * @return {boolean}\n */\nproto.Conf.Artwork.prototype.getEnabled = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.Conf.Artwork} returns this\n */\nproto.Conf.Artwork.prototype.setEnabled = function(value) {\n return jspb.Message.setProto3BooleanField(this, 1, value);\n};\n\n\n/**\n * optional uint32 resize = 2;\n * @return {number}\n */\nproto.Conf.Artwork.prototype.getResize = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.Artwork} returns this\n */\nproto.Conf.Artwork.prototype.setResize = function(value) {\n return jspb.Message.setProto3IntField(this, 2, value);\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.Metadata.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.Metadata.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.Metadata} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Metadata.toObject = function(includeInstance, msg) {\n var f, obj = {\n format: jspb.Message.getFieldWithDefault(msg, 1, \"\"),\n speed: jspb.Message.getFieldWithDefault(msg, 2, 0),\n pause: jspb.Message.getFieldWithDefault(msg, 3, 0),\n artwork: (f = msg.getArtwork()) && proto.Conf.Artwork.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.Metadata}\n */\nproto.Conf.Metadata.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.Metadata;\n return proto.Conf.Metadata.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.Metadata} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.Metadata}\n */\nproto.Conf.Metadata.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {string} */ (reader.readString());\n msg.setFormat(value);\n break;\n case 2:\n var value = /** @type {number} */ (reader.readUint32());\n msg.setSpeed(value);\n break;\n case 3:\n var value = /** @type {number} */ (reader.readUint32());\n msg.setPause(value);\n break;\n case 4:\n var value = new proto.Conf.Artwork;\n reader.readMessage(value,proto.Conf.Artwork.deserializeBinaryFromReader);\n msg.setArtwork(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.Metadata.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.Metadata.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.Metadata} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Metadata.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getFormat();\n if (f.length > 0) {\n writer.writeString(\n 1,\n f\n );\n }\n f = message.getSpeed();\n if (f !== 0) {\n writer.writeUint32(\n 2,\n f\n );\n }\n f = message.getPause();\n if (f !== 0) {\n writer.writeUint32(\n 3,\n f\n );\n }\n f = message.getArtwork();\n if (f != null) {\n writer.writeMessage(\n 4,\n f,\n proto.Conf.Artwork.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional string format = 1;\n * @return {string}\n */\nproto.Conf.Metadata.prototype.getFormat = function() {\n return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, \"\"));\n};\n\n\n/**\n * @param {string} value\n * @return {!proto.Conf.Metadata} returns this\n */\nproto.Conf.Metadata.prototype.setFormat = function(value) {\n return jspb.Message.setProto3StringField(this, 1, value);\n};\n\n\n/**\n * optional uint32 speed = 2;\n * @return {number}\n */\nproto.Conf.Metadata.prototype.getSpeed = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.Metadata} returns this\n */\nproto.Conf.Metadata.prototype.setSpeed = function(value) {\n return jspb.Message.setProto3IntField(this, 2, value);\n};\n\n\n/**\n * optional uint32 pause = 3;\n * @return {number}\n */\nproto.Conf.Metadata.prototype.getPause = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.Conf.Metadata} returns this\n */\nproto.Conf.Metadata.prototype.setPause = function(value) {\n return jspb.Message.setProto3IntField(this, 3, value);\n};\n\n\n/**\n * optional Artwork artwork = 4;\n * @return {?proto.Conf.Artwork}\n */\nproto.Conf.Metadata.prototype.getArtwork = function() {\n return /** @type{?proto.Conf.Artwork} */ (\n jspb.Message.getWrapperField(this, proto.Conf.Artwork, 4));\n};\n\n\n/**\n * @param {?proto.Conf.Artwork|undefined} value\n * @return {!proto.Conf.Metadata} returns this\n*/\nproto.Conf.Metadata.prototype.setArtwork = function(value) {\n return jspb.Message.setWrapperField(this, 4, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Metadata} returns this\n */\nproto.Conf.Metadata.prototype.clearArtwork = function() {\n return this.setArtwork(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Metadata.prototype.hasArtwork = function() {\n return jspb.Message.getField(this, 4) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.Services.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.Services.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.Services} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Services.toObject = function(includeInstance, msg) {\n var f, obj = {\n metadata: (f = msg.getMetadata()) && proto.Conf.Metadata.toObject(includeInstance, f),\n sleep: (f = msg.getSleep()) && proto.Conf.SleepService.toObject(includeInstance, f)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.Services}\n */\nproto.Conf.Services.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.Services;\n return proto.Conf.Services.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.Services} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.Services}\n */\nproto.Conf.Services.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.Metadata;\n reader.readMessage(value,proto.Conf.Metadata.deserializeBinaryFromReader);\n msg.setMetadata(value);\n break;\n case 2:\n var value = new proto.Conf.SleepService;\n reader.readMessage(value,proto.Conf.SleepService.deserializeBinaryFromReader);\n msg.setSleep(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.Services.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.Services.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.Services} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Services.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getMetadata();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.Metadata.serializeBinaryToWriter\n );\n }\n f = message.getSleep();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.SleepService.serializeBinaryToWriter\n );\n }\n};\n\n\n/**\n * optional Metadata metadata = 1;\n * @return {?proto.Conf.Metadata}\n */\nproto.Conf.Services.prototype.getMetadata = function() {\n return /** @type{?proto.Conf.Metadata} */ (\n jspb.Message.getWrapperField(this, proto.Conf.Metadata, 1));\n};\n\n\n/**\n * @param {?proto.Conf.Metadata|undefined} value\n * @return {!proto.Conf.Services} returns this\n*/\nproto.Conf.Services.prototype.setMetadata = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Services} returns this\n */\nproto.Conf.Services.prototype.clearMetadata = function() {\n return this.setMetadata(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Services.prototype.hasMetadata = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional SleepService sleep = 2;\n * @return {?proto.Conf.SleepService}\n */\nproto.Conf.Services.prototype.getSleep = function() {\n return /** @type{?proto.Conf.SleepService} */ (\n jspb.Message.getWrapperField(this, proto.Conf.SleepService, 2));\n};\n\n\n/**\n * @param {?proto.Conf.SleepService|undefined} value\n * @return {!proto.Conf.Services} returns this\n*/\nproto.Conf.Services.prototype.setSleep = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Services} returns this\n */\nproto.Conf.Services.prototype.clearSleep = function() {\n return this.setSleep(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Services.prototype.hasSleep = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.Conf.Config.prototype.toObject = function(opt_includeInstance) {\n return proto.Conf.Config.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.Conf.Config} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Config.toObject = function(includeInstance, msg) {\n var f, obj = {\n gpios: (f = msg.getGpios()) && proto.Conf.Gpios.toObject(includeInstance, f),\n dev: (f = msg.getDev()) && proto.Conf.Dev.toObject(includeInstance, f),\n services: (f = msg.getServices()) && proto.Conf.Services.toObject(includeInstance, f),\n deviceName: jspb.Message.getFieldWithDefault(msg, 4, \"\")\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.Conf.Config}\n */\nproto.Conf.Config.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.Conf.Config;\n return proto.Conf.Config.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.Conf.Config} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.Conf.Config}\n */\nproto.Conf.Config.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = new proto.Conf.Gpios;\n reader.readMessage(value,proto.Conf.Gpios.deserializeBinaryFromReader);\n msg.setGpios(value);\n break;\n case 2:\n var value = new proto.Conf.Dev;\n reader.readMessage(value,proto.Conf.Dev.deserializeBinaryFromReader);\n msg.setDev(value);\n break;\n case 3:\n var value = new proto.Conf.Services;\n reader.readMessage(value,proto.Conf.Services.deserializeBinaryFromReader);\n msg.setServices(value);\n break;\n case 4:\n var value = /** @type {string} */ (reader.readString());\n msg.setDeviceName(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.Conf.Config.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.Conf.Config.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.Conf.Config} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.Conf.Config.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = message.getGpios();\n if (f != null) {\n writer.writeMessage(\n 1,\n f,\n proto.Conf.Gpios.serializeBinaryToWriter\n );\n }\n f = message.getDev();\n if (f != null) {\n writer.writeMessage(\n 2,\n f,\n proto.Conf.Dev.serializeBinaryToWriter\n );\n }\n f = message.getServices();\n if (f != null) {\n writer.writeMessage(\n 3,\n f,\n proto.Conf.Services.serializeBinaryToWriter\n );\n }\n f = message.getDeviceName();\n if (f.length > 0) {\n writer.writeString(\n 4,\n f\n );\n }\n};\n\n\n/**\n * optional Gpios gpios = 1;\n * @return {?proto.Conf.Gpios}\n */\nproto.Conf.Config.prototype.getGpios = function() {\n return /** @type{?proto.Conf.Gpios} */ (\n jspb.Message.getWrapperField(this, proto.Conf.Gpios, 1));\n};\n\n\n/**\n * @param {?proto.Conf.Gpios|undefined} value\n * @return {!proto.Conf.Config} returns this\n*/\nproto.Conf.Config.prototype.setGpios = function(value) {\n return jspb.Message.setWrapperField(this, 1, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Config} returns this\n */\nproto.Conf.Config.prototype.clearGpios = function() {\n return this.setGpios(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Config.prototype.hasGpios = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional Dev dev = 2;\n * @return {?proto.Conf.Dev}\n */\nproto.Conf.Config.prototype.getDev = function() {\n return /** @type{?proto.Conf.Dev} */ (\n jspb.Message.getWrapperField(this, proto.Conf.Dev, 2));\n};\n\n\n/**\n * @param {?proto.Conf.Dev|undefined} value\n * @return {!proto.Conf.Config} returns this\n*/\nproto.Conf.Config.prototype.setDev = function(value) {\n return jspb.Message.setWrapperField(this, 2, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Config} returns this\n */\nproto.Conf.Config.prototype.clearDev = function() {\n return this.setDev(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Config.prototype.hasDev = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n/**\n * optional Services services = 3;\n * @return {?proto.Conf.Services}\n */\nproto.Conf.Config.prototype.getServices = function() {\n return /** @type{?proto.Conf.Services} */ (\n jspb.Message.getWrapperField(this, proto.Conf.Services, 3));\n};\n\n\n/**\n * @param {?proto.Conf.Services|undefined} value\n * @return {!proto.Conf.Config} returns this\n*/\nproto.Conf.Config.prototype.setServices = function(value) {\n return jspb.Message.setWrapperField(this, 3, value);\n};\n\n\n/**\n * Clears the message field making it undefined.\n * @return {!proto.Conf.Config} returns this\n */\nproto.Conf.Config.prototype.clearServices = function() {\n return this.setServices(undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.Conf.Config.prototype.hasServices = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * optional string device_name = 4;\n * @return {string}\n */\nproto.Conf.Config.prototype.getDeviceName = function() {\n return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, \"\"));\n};\n\n\n/**\n * @param {string} value\n * @return {!proto.Conf.Config} returns this\n */\nproto.Conf.Config.prototype.setDeviceName = function(value) {\n return jspb.Message.setProto3StringField(this, 4, value);\n};\n\n\n/**\n * @enum {number}\n */\nproto.Conf.ButtonAction = {\n ACTRLS_NONE: 0,\n ACTRLS_POWER: 1,\n ACTRLS_VOLUP: 2,\n ACTRLS_VOLDOWN: 3,\n ACTRLS_TOGGLE: 4,\n ACTRLS_PLAY: 5,\n ACTRLS_PAUSE: 6,\n ACTRLS_STOP: 7,\n ACTRLS_REW: 8,\n ACTRLS_FWD: 9,\n ACTRLS_PREV: 10,\n ACTRLS_NEXT: 11,\n BCTRLS_UP: 12,\n BCTRLS_DOWN: 13,\n BCTRLS_LEFT: 14,\n BCTRLS_RIGHT: 15,\n BCTRLS_PS1: 16,\n BCTRLS_PS2: 17,\n BCTRLS_PS3: 18,\n BCTRLS_PS4: 19,\n BCTRLS_PS5: 20,\n BCTRLS_PS6: 21,\n BCTRLS_PS7: 22,\n BCTRLS_PS8: 23,\n BCTRLS_PS9: 24,\n BCTRLS_PS10: 25,\n KNOB_LEFT: 26,\n KNOB_RIGHT: 27,\n KNOB_PUSH: 28,\n ACTRLS_SLEEP: 29\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.DACModelEnum = {\n UNSPECIFIED_MODEL: 0,\n TAS57XX: 1,\n TAS5713: 2,\n AC101: 3,\n WM8978: 4,\n ES8388: 5,\n I2S: 6\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.DeviceTypeEnum = {\n UNSPECIFIED_TYPE: 0,\n DEVTYPE_SPI: 1,\n DEVTYPE_I2C: 2,\n DEVTYPE__RMII: 3\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.DisplayDriverEnum = {\n UNSPECIFIED_DRIVER: 0,\n SSD1306: 1,\n SSD1322: 2,\n SSD1326: 3,\n SSD1327: 4,\n SH1106: 5,\n SSD1675: 6,\n ST7735: 7,\n ST7789: 8,\n ILI9341: 9,\n ILI9341_24: 10,\n SSD1351: 11\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.PortEnum = {\n UNSPECIFIED_SYSTPORT: 0,\n SYSTEM: 1,\n DAC: 2\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.EthModelEnum = {\n UNSPECIFIED_ETHMODEL: 0,\n LAN8720: 1,\n DM9051: 2,\n W5500: 3\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.GPIOExpModelEnum = {\n UNSPECIFIED_EXP: 0,\n PCA9535: 1,\n PCA85XX: 2,\n MCP23017: 3,\n MCP23S17: 4\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.HostEnum = {\n UNSPECIFIED_HOST: 0,\n HOST0: 1,\n HOST1: 2\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.I2CPortEnum = {\n UNSPECIFIED_PORT: 0,\n I2CPORT0: 1,\n I2CPORT1: 2\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.MCKEnum = {\n UNSPECIFIED_MCK: 0,\n MCK0: 1,\n MCK1: 2,\n MCK2: 3\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.BatteryChannelEnum = {\n UNSPECIFIED_CH: 0,\n CH0: 1,\n CH1: 2,\n CH2: 3,\n CH3: 4,\n CH4: 5,\n CH5: 6,\n CH6: 7,\n CH7: 8\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.BatteryAttenEnum = {\n UNSPECIFIED_ATT: 0,\n ATT_0: 1,\n ATT_1: 2,\n ATT_2: 3,\n ATT_3: 4\n};\n\n/**\n * @enum {number}\n */\nproto.Conf.EthType = {\n UNSPECIFIED_ETH: 0,\n SPI: 1,\n RMII: 2\n};\n\ngoog.object.extend(exports, proto.Conf);\n","// source: nanopb.proto\n/**\n * @fileoverview\n * @enhanceable\n * @suppress {missingRequire} reports error on implicit type usages.\n * @suppress {messageConventions} JS Compiler reports an error if a variable or\n * field starts with 'MSG_' and isn't a translatable message.\n * @public\n */\n// GENERATED CODE -- DO NOT EDIT!\n/* eslint-disable */\n// @ts-nocheck\n\nvar jspb = require('google-protobuf');\nvar goog = jspb;\nvar global = (function() {\n if (this) { return this; }\n if (typeof window !== 'undefined') { return window; }\n if (typeof global !== 'undefined') { return global; }\n if (typeof self !== 'undefined') { return self; }\n return Function('return this')();\n}.call(null));\n\nvar google_protobuf_descriptor_pb = require('google-protobuf/google/protobuf/descriptor_pb.js');\ngoog.object.extend(proto, google_protobuf_descriptor_pb);\ngoog.exportSymbol('proto.DescriptorSize', null, global);\ngoog.exportSymbol('proto.FieldType', null, global);\ngoog.exportSymbol('proto.IntSize', null, global);\ngoog.exportSymbol('proto.NanoPBOptions', null, global);\ngoog.exportSymbol('proto.TypenameMangling', null, global);\ngoog.exportSymbol('proto.nanopb', null, global);\ngoog.exportSymbol('proto.nanopbEnumopt', null, global);\ngoog.exportSymbol('proto.nanopbFileopt', null, global);\ngoog.exportSymbol('proto.nanopbMsgopt', null, global);\n/**\n * Generated by JsPbCodeGenerator.\n * @param {Array=} opt_data Optional initial data array, typically from a\n * server response, or constructed directly in Javascript. The array is used\n * in place and becomes part of the constructed object. It is not cloned.\n * If no data is provided, the constructed object will be empty, but still\n * valid.\n * @extends {jspb.Message}\n * @constructor\n */\nproto.NanoPBOptions = function(opt_data) {\n jspb.Message.initialize(this, opt_data, 0, -1, proto.NanoPBOptions.repeatedFields_, null);\n};\ngoog.inherits(proto.NanoPBOptions, jspb.Message);\nif (goog.DEBUG && !COMPILED) {\n /**\n * @public\n * @override\n */\n proto.NanoPBOptions.displayName = 'proto.NanoPBOptions';\n}\n\n/**\n * List of repeated fields within this message type.\n * @private {!Array}\n * @const\n */\nproto.NanoPBOptions.repeatedFields_ = [24,26];\n\n\n\nif (jspb.Message.GENERATE_TO_OBJECT) {\n/**\n * Creates an object representation of this proto.\n * Field names that are reserved in JavaScript and will be renamed to pb_name.\n * Optional fields that are not set will be set to undefined.\n * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n * For the list of reserved names please see:\n * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n * @param {boolean=} opt_includeInstance Deprecated. whether to include the\n * JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @return {!Object}\n */\nproto.NanoPBOptions.prototype.toObject = function(opt_includeInstance) {\n return proto.NanoPBOptions.toObject(opt_includeInstance, this);\n};\n\n\n/**\n * Static version of the {@see toObject} method.\n * @param {boolean|undefined} includeInstance Deprecated. Whether to include\n * the JSPB instance for transitional soy proto support:\n * http://goto/soy-param-migration\n * @param {!proto.NanoPBOptions} msg The msg instance to transform.\n * @return {!Object}\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.NanoPBOptions.toObject = function(includeInstance, msg) {\n var f, obj = {\n maxSize: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,\n maxLength: (f = jspb.Message.getField(msg, 14)) == null ? undefined : f,\n maxCount: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,\n intSize: jspb.Message.getFieldWithDefault(msg, 7, 0),\n type: jspb.Message.getFieldWithDefault(msg, 3, 0),\n longNames: jspb.Message.getBooleanFieldWithDefault(msg, 4, true),\n packedStruct: jspb.Message.getBooleanFieldWithDefault(msg, 5, false),\n packedEnum: jspb.Message.getBooleanFieldWithDefault(msg, 10, false),\n skipMessage: jspb.Message.getBooleanFieldWithDefault(msg, 6, false),\n noUnions: jspb.Message.getBooleanFieldWithDefault(msg, 8, false),\n msgid: (f = jspb.Message.getField(msg, 9)) == null ? undefined : f,\n anonymousOneof: jspb.Message.getBooleanFieldWithDefault(msg, 11, false),\n proto3: jspb.Message.getBooleanFieldWithDefault(msg, 12, false),\n proto3SingularMsgs: jspb.Message.getBooleanFieldWithDefault(msg, 21, false),\n enumToString: jspb.Message.getBooleanFieldWithDefault(msg, 13, false),\n fixedLength: jspb.Message.getBooleanFieldWithDefault(msg, 15, false),\n fixedCount: jspb.Message.getBooleanFieldWithDefault(msg, 16, false),\n submsgCallback: jspb.Message.getBooleanFieldWithDefault(msg, 22, false),\n mangleNames: jspb.Message.getFieldWithDefault(msg, 17, 0),\n callbackDatatype: jspb.Message.getFieldWithDefault(msg, 18, \"pb_callback_t\"),\n callbackFunction: jspb.Message.getFieldWithDefault(msg, 19, \"pb_default_field_callback\"),\n descriptorsize: jspb.Message.getFieldWithDefault(msg, 20, 0),\n defaultHas: jspb.Message.getBooleanFieldWithDefault(msg, 23, false),\n includeList: (f = jspb.Message.getRepeatedField(msg, 24)) == null ? undefined : f,\n excludeList: (f = jspb.Message.getRepeatedField(msg, 26)) == null ? undefined : f,\n pb_package: (f = jspb.Message.getField(msg, 25)) == null ? undefined : f,\n typeOverride: (f = jspb.Message.getField(msg, 27)) == null ? undefined : f,\n sortByTag: jspb.Message.getBooleanFieldWithDefault(msg, 28, true)\n };\n\n if (includeInstance) {\n obj.$jspbMessageInstance = msg;\n }\n return obj;\n};\n}\n\n\n/**\n * Deserializes binary data (in protobuf wire format).\n * @param {jspb.ByteSource} bytes The bytes to deserialize.\n * @return {!proto.NanoPBOptions}\n */\nproto.NanoPBOptions.deserializeBinary = function(bytes) {\n var reader = new jspb.BinaryReader(bytes);\n var msg = new proto.NanoPBOptions;\n return proto.NanoPBOptions.deserializeBinaryFromReader(msg, reader);\n};\n\n\n/**\n * Deserializes binary data (in protobuf wire format) from the\n * given reader into the given message object.\n * @param {!proto.NanoPBOptions} msg The message object to deserialize into.\n * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n * @return {!proto.NanoPBOptions}\n */\nproto.NanoPBOptions.deserializeBinaryFromReader = function(msg, reader) {\n while (reader.nextField()) {\n if (reader.isEndGroup()) {\n break;\n }\n var field = reader.getFieldNumber();\n switch (field) {\n case 1:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setMaxSize(value);\n break;\n case 14:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setMaxLength(value);\n break;\n case 2:\n var value = /** @type {number} */ (reader.readInt32());\n msg.setMaxCount(value);\n break;\n case 7:\n var value = /** @type {!proto.IntSize} */ (reader.readEnum());\n msg.setIntSize(value);\n break;\n case 3:\n var value = /** @type {!proto.FieldType} */ (reader.readEnum());\n msg.setType(value);\n break;\n case 4:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setLongNames(value);\n break;\n case 5:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setPackedStruct(value);\n break;\n case 10:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setPackedEnum(value);\n break;\n case 6:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setSkipMessage(value);\n break;\n case 8:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setNoUnions(value);\n break;\n case 9:\n var value = /** @type {number} */ (reader.readUint32());\n msg.setMsgid(value);\n break;\n case 11:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setAnonymousOneof(value);\n break;\n case 12:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setProto3(value);\n break;\n case 21:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setProto3SingularMsgs(value);\n break;\n case 13:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setEnumToString(value);\n break;\n case 15:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setFixedLength(value);\n break;\n case 16:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setFixedCount(value);\n break;\n case 22:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setSubmsgCallback(value);\n break;\n case 17:\n var value = /** @type {!proto.TypenameMangling} */ (reader.readEnum());\n msg.setMangleNames(value);\n break;\n case 18:\n var value = /** @type {string} */ (reader.readString());\n msg.setCallbackDatatype(value);\n break;\n case 19:\n var value = /** @type {string} */ (reader.readString());\n msg.setCallbackFunction(value);\n break;\n case 20:\n var value = /** @type {!proto.DescriptorSize} */ (reader.readEnum());\n msg.setDescriptorsize(value);\n break;\n case 23:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setDefaultHas(value);\n break;\n case 24:\n var value = /** @type {string} */ (reader.readString());\n msg.addInclude(value);\n break;\n case 26:\n var value = /** @type {string} */ (reader.readString());\n msg.addExclude(value);\n break;\n case 25:\n var value = /** @type {string} */ (reader.readString());\n msg.setPackage(value);\n break;\n case 27:\n var value = /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (reader.readEnum());\n msg.setTypeOverride(value);\n break;\n case 28:\n var value = /** @type {boolean} */ (reader.readBool());\n msg.setSortByTag(value);\n break;\n default:\n reader.skipField();\n break;\n }\n }\n return msg;\n};\n\n\n/**\n * Serializes the message to binary data (in protobuf wire format).\n * @return {!Uint8Array}\n */\nproto.NanoPBOptions.prototype.serializeBinary = function() {\n var writer = new jspb.BinaryWriter();\n proto.NanoPBOptions.serializeBinaryToWriter(this, writer);\n return writer.getResultBuffer();\n};\n\n\n/**\n * Serializes the given message to binary data (in protobuf wire\n * format), writing to the given BinaryWriter.\n * @param {!proto.NanoPBOptions} message\n * @param {!jspb.BinaryWriter} writer\n * @suppress {unusedLocalVariables} f is only used for nested messages\n */\nproto.NanoPBOptions.serializeBinaryToWriter = function(message, writer) {\n var f = undefined;\n f = /** @type {number} */ (jspb.Message.getField(message, 1));\n if (f != null) {\n writer.writeInt32(\n 1,\n f\n );\n }\n f = /** @type {number} */ (jspb.Message.getField(message, 14));\n if (f != null) {\n writer.writeInt32(\n 14,\n f\n );\n }\n f = /** @type {number} */ (jspb.Message.getField(message, 2));\n if (f != null) {\n writer.writeInt32(\n 2,\n f\n );\n }\n f = /** @type {!proto.IntSize} */ (jspb.Message.getField(message, 7));\n if (f != null) {\n writer.writeEnum(\n 7,\n f\n );\n }\n f = /** @type {!proto.FieldType} */ (jspb.Message.getField(message, 3));\n if (f != null) {\n writer.writeEnum(\n 3,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 4));\n if (f != null) {\n writer.writeBool(\n 4,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 5));\n if (f != null) {\n writer.writeBool(\n 5,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 10));\n if (f != null) {\n writer.writeBool(\n 10,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 6));\n if (f != null) {\n writer.writeBool(\n 6,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 8));\n if (f != null) {\n writer.writeBool(\n 8,\n f\n );\n }\n f = /** @type {number} */ (jspb.Message.getField(message, 9));\n if (f != null) {\n writer.writeUint32(\n 9,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 11));\n if (f != null) {\n writer.writeBool(\n 11,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 12));\n if (f != null) {\n writer.writeBool(\n 12,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 21));\n if (f != null) {\n writer.writeBool(\n 21,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 13));\n if (f != null) {\n writer.writeBool(\n 13,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 15));\n if (f != null) {\n writer.writeBool(\n 15,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 16));\n if (f != null) {\n writer.writeBool(\n 16,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 22));\n if (f != null) {\n writer.writeBool(\n 22,\n f\n );\n }\n f = /** @type {!proto.TypenameMangling} */ (jspb.Message.getField(message, 17));\n if (f != null) {\n writer.writeEnum(\n 17,\n f\n );\n }\n f = /** @type {string} */ (jspb.Message.getField(message, 18));\n if (f != null) {\n writer.writeString(\n 18,\n f\n );\n }\n f = /** @type {string} */ (jspb.Message.getField(message, 19));\n if (f != null) {\n writer.writeString(\n 19,\n f\n );\n }\n f = /** @type {!proto.DescriptorSize} */ (jspb.Message.getField(message, 20));\n if (f != null) {\n writer.writeEnum(\n 20,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 23));\n if (f != null) {\n writer.writeBool(\n 23,\n f\n );\n }\n f = message.getIncludeList();\n if (f.length > 0) {\n writer.writeRepeatedString(\n 24,\n f\n );\n }\n f = message.getExcludeList();\n if (f.length > 0) {\n writer.writeRepeatedString(\n 26,\n f\n );\n }\n f = /** @type {string} */ (jspb.Message.getField(message, 25));\n if (f != null) {\n writer.writeString(\n 25,\n f\n );\n }\n f = /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (jspb.Message.getField(message, 27));\n if (f != null) {\n writer.writeEnum(\n 27,\n f\n );\n }\n f = /** @type {boolean} */ (jspb.Message.getField(message, 28));\n if (f != null) {\n writer.writeBool(\n 28,\n f\n );\n }\n};\n\n\n/**\n * optional int32 max_size = 1;\n * @return {number}\n */\nproto.NanoPBOptions.prototype.getMaxSize = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setMaxSize = function(value) {\n return jspb.Message.setField(this, 1, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearMaxSize = function() {\n return jspb.Message.setField(this, 1, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasMaxSize = function() {\n return jspb.Message.getField(this, 1) != null;\n};\n\n\n/**\n * optional int32 max_length = 14;\n * @return {number}\n */\nproto.NanoPBOptions.prototype.getMaxLength = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 14, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setMaxLength = function(value) {\n return jspb.Message.setField(this, 14, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearMaxLength = function() {\n return jspb.Message.setField(this, 14, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasMaxLength = function() {\n return jspb.Message.getField(this, 14) != null;\n};\n\n\n/**\n * optional int32 max_count = 2;\n * @return {number}\n */\nproto.NanoPBOptions.prototype.getMaxCount = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setMaxCount = function(value) {\n return jspb.Message.setField(this, 2, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearMaxCount = function() {\n return jspb.Message.setField(this, 2, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasMaxCount = function() {\n return jspb.Message.getField(this, 2) != null;\n};\n\n\n/**\n * optional IntSize int_size = 7;\n * @return {!proto.IntSize}\n */\nproto.NanoPBOptions.prototype.getIntSize = function() {\n return /** @type {!proto.IntSize} */ (jspb.Message.getFieldWithDefault(this, 7, 0));\n};\n\n\n/**\n * @param {!proto.IntSize} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setIntSize = function(value) {\n return jspb.Message.setField(this, 7, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearIntSize = function() {\n return jspb.Message.setField(this, 7, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasIntSize = function() {\n return jspb.Message.getField(this, 7) != null;\n};\n\n\n/**\n * optional FieldType type = 3;\n * @return {!proto.FieldType}\n */\nproto.NanoPBOptions.prototype.getType = function() {\n return /** @type {!proto.FieldType} */ (jspb.Message.getFieldWithDefault(this, 3, 0));\n};\n\n\n/**\n * @param {!proto.FieldType} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setType = function(value) {\n return jspb.Message.setField(this, 3, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearType = function() {\n return jspb.Message.setField(this, 3, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasType = function() {\n return jspb.Message.getField(this, 3) != null;\n};\n\n\n/**\n * optional bool long_names = 4;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getLongNames = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 4, true));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setLongNames = function(value) {\n return jspb.Message.setField(this, 4, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearLongNames = function() {\n return jspb.Message.setField(this, 4, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasLongNames = function() {\n return jspb.Message.getField(this, 4) != null;\n};\n\n\n/**\n * optional bool packed_struct = 5;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getPackedStruct = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setPackedStruct = function(value) {\n return jspb.Message.setField(this, 5, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearPackedStruct = function() {\n return jspb.Message.setField(this, 5, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasPackedStruct = function() {\n return jspb.Message.getField(this, 5) != null;\n};\n\n\n/**\n * optional bool packed_enum = 10;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getPackedEnum = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 10, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setPackedEnum = function(value) {\n return jspb.Message.setField(this, 10, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearPackedEnum = function() {\n return jspb.Message.setField(this, 10, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasPackedEnum = function() {\n return jspb.Message.getField(this, 10) != null;\n};\n\n\n/**\n * optional bool skip_message = 6;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getSkipMessage = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 6, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setSkipMessage = function(value) {\n return jspb.Message.setField(this, 6, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearSkipMessage = function() {\n return jspb.Message.setField(this, 6, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasSkipMessage = function() {\n return jspb.Message.getField(this, 6) != null;\n};\n\n\n/**\n * optional bool no_unions = 8;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getNoUnions = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 8, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setNoUnions = function(value) {\n return jspb.Message.setField(this, 8, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearNoUnions = function() {\n return jspb.Message.setField(this, 8, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasNoUnions = function() {\n return jspb.Message.getField(this, 8) != null;\n};\n\n\n/**\n * optional uint32 msgid = 9;\n * @return {number}\n */\nproto.NanoPBOptions.prototype.getMsgid = function() {\n return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 9, 0));\n};\n\n\n/**\n * @param {number} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setMsgid = function(value) {\n return jspb.Message.setField(this, 9, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearMsgid = function() {\n return jspb.Message.setField(this, 9, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasMsgid = function() {\n return jspb.Message.getField(this, 9) != null;\n};\n\n\n/**\n * optional bool anonymous_oneof = 11;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getAnonymousOneof = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 11, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setAnonymousOneof = function(value) {\n return jspb.Message.setField(this, 11, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearAnonymousOneof = function() {\n return jspb.Message.setField(this, 11, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasAnonymousOneof = function() {\n return jspb.Message.getField(this, 11) != null;\n};\n\n\n/**\n * optional bool proto3 = 12;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getProto3 = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 12, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setProto3 = function(value) {\n return jspb.Message.setField(this, 12, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearProto3 = function() {\n return jspb.Message.setField(this, 12, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasProto3 = function() {\n return jspb.Message.getField(this, 12) != null;\n};\n\n\n/**\n * optional bool proto3_singular_msgs = 21;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getProto3SingularMsgs = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 21, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setProto3SingularMsgs = function(value) {\n return jspb.Message.setField(this, 21, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearProto3SingularMsgs = function() {\n return jspb.Message.setField(this, 21, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasProto3SingularMsgs = function() {\n return jspb.Message.getField(this, 21) != null;\n};\n\n\n/**\n * optional bool enum_to_string = 13;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getEnumToString = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 13, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setEnumToString = function(value) {\n return jspb.Message.setField(this, 13, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearEnumToString = function() {\n return jspb.Message.setField(this, 13, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasEnumToString = function() {\n return jspb.Message.getField(this, 13) != null;\n};\n\n\n/**\n * optional bool fixed_length = 15;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getFixedLength = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 15, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setFixedLength = function(value) {\n return jspb.Message.setField(this, 15, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearFixedLength = function() {\n return jspb.Message.setField(this, 15, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasFixedLength = function() {\n return jspb.Message.getField(this, 15) != null;\n};\n\n\n/**\n * optional bool fixed_count = 16;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getFixedCount = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 16, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setFixedCount = function(value) {\n return jspb.Message.setField(this, 16, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearFixedCount = function() {\n return jspb.Message.setField(this, 16, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasFixedCount = function() {\n return jspb.Message.getField(this, 16) != null;\n};\n\n\n/**\n * optional bool submsg_callback = 22;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getSubmsgCallback = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 22, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setSubmsgCallback = function(value) {\n return jspb.Message.setField(this, 22, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearSubmsgCallback = function() {\n return jspb.Message.setField(this, 22, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasSubmsgCallback = function() {\n return jspb.Message.getField(this, 22) != null;\n};\n\n\n/**\n * optional TypenameMangling mangle_names = 17;\n * @return {!proto.TypenameMangling}\n */\nproto.NanoPBOptions.prototype.getMangleNames = function() {\n return /** @type {!proto.TypenameMangling} */ (jspb.Message.getFieldWithDefault(this, 17, 0));\n};\n\n\n/**\n * @param {!proto.TypenameMangling} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setMangleNames = function(value) {\n return jspb.Message.setField(this, 17, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearMangleNames = function() {\n return jspb.Message.setField(this, 17, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasMangleNames = function() {\n return jspb.Message.getField(this, 17) != null;\n};\n\n\n/**\n * optional string callback_datatype = 18;\n * @return {string}\n */\nproto.NanoPBOptions.prototype.getCallbackDatatype = function() {\n return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 18, \"pb_callback_t\"));\n};\n\n\n/**\n * @param {string} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setCallbackDatatype = function(value) {\n return jspb.Message.setField(this, 18, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearCallbackDatatype = function() {\n return jspb.Message.setField(this, 18, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasCallbackDatatype = function() {\n return jspb.Message.getField(this, 18) != null;\n};\n\n\n/**\n * optional string callback_function = 19;\n * @return {string}\n */\nproto.NanoPBOptions.prototype.getCallbackFunction = function() {\n return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 19, \"pb_default_field_callback\"));\n};\n\n\n/**\n * @param {string} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setCallbackFunction = function(value) {\n return jspb.Message.setField(this, 19, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearCallbackFunction = function() {\n return jspb.Message.setField(this, 19, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasCallbackFunction = function() {\n return jspb.Message.getField(this, 19) != null;\n};\n\n\n/**\n * optional DescriptorSize descriptorsize = 20;\n * @return {!proto.DescriptorSize}\n */\nproto.NanoPBOptions.prototype.getDescriptorsize = function() {\n return /** @type {!proto.DescriptorSize} */ (jspb.Message.getFieldWithDefault(this, 20, 0));\n};\n\n\n/**\n * @param {!proto.DescriptorSize} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setDescriptorsize = function(value) {\n return jspb.Message.setField(this, 20, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearDescriptorsize = function() {\n return jspb.Message.setField(this, 20, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasDescriptorsize = function() {\n return jspb.Message.getField(this, 20) != null;\n};\n\n\n/**\n * optional bool default_has = 23;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getDefaultHas = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 23, false));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setDefaultHas = function(value) {\n return jspb.Message.setField(this, 23, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearDefaultHas = function() {\n return jspb.Message.setField(this, 23, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasDefaultHas = function() {\n return jspb.Message.getField(this, 23) != null;\n};\n\n\n/**\n * repeated string include = 24;\n * @return {!Array}\n */\nproto.NanoPBOptions.prototype.getIncludeList = function() {\n return /** @type {!Array} */ (jspb.Message.getRepeatedField(this, 24));\n};\n\n\n/**\n * @param {!Array} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setIncludeList = function(value) {\n return jspb.Message.setField(this, 24, value || []);\n};\n\n\n/**\n * @param {string} value\n * @param {number=} opt_index\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.addInclude = function(value, opt_index) {\n return jspb.Message.addToRepeatedField(this, 24, value, opt_index);\n};\n\n\n/**\n * Clears the list making it empty but non-null.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearIncludeList = function() {\n return this.setIncludeList([]);\n};\n\n\n/**\n * repeated string exclude = 26;\n * @return {!Array}\n */\nproto.NanoPBOptions.prototype.getExcludeList = function() {\n return /** @type {!Array} */ (jspb.Message.getRepeatedField(this, 26));\n};\n\n\n/**\n * @param {!Array} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setExcludeList = function(value) {\n return jspb.Message.setField(this, 26, value || []);\n};\n\n\n/**\n * @param {string} value\n * @param {number=} opt_index\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.addExclude = function(value, opt_index) {\n return jspb.Message.addToRepeatedField(this, 26, value, opt_index);\n};\n\n\n/**\n * Clears the list making it empty but non-null.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearExcludeList = function() {\n return this.setExcludeList([]);\n};\n\n\n/**\n * optional string package = 25;\n * @return {string}\n */\nproto.NanoPBOptions.prototype.getPackage = function() {\n return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 25, \"\"));\n};\n\n\n/**\n * @param {string} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setPackage = function(value) {\n return jspb.Message.setField(this, 25, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearPackage = function() {\n return jspb.Message.setField(this, 25, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasPackage = function() {\n return jspb.Message.getField(this, 25) != null;\n};\n\n\n/**\n * optional google.protobuf.FieldDescriptorProto.Type type_override = 27;\n * @return {!proto.google.protobuf.FieldDescriptorProto.Type}\n */\nproto.NanoPBOptions.prototype.getTypeOverride = function() {\n return /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (jspb.Message.getFieldWithDefault(this, 27, 1));\n};\n\n\n/**\n * @param {!proto.google.protobuf.FieldDescriptorProto.Type} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setTypeOverride = function(value) {\n return jspb.Message.setField(this, 27, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearTypeOverride = function() {\n return jspb.Message.setField(this, 27, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasTypeOverride = function() {\n return jspb.Message.getField(this, 27) != null;\n};\n\n\n/**\n * optional bool sort_by_tag = 28;\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.getSortByTag = function() {\n return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 28, true));\n};\n\n\n/**\n * @param {boolean} value\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.setSortByTag = function(value) {\n return jspb.Message.setField(this, 28, value);\n};\n\n\n/**\n * Clears the field making it undefined.\n * @return {!proto.NanoPBOptions} returns this\n */\nproto.NanoPBOptions.prototype.clearSortByTag = function() {\n return jspb.Message.setField(this, 28, undefined);\n};\n\n\n/**\n * Returns whether this field is set.\n * @return {boolean}\n */\nproto.NanoPBOptions.prototype.hasSortByTag = function() {\n return jspb.Message.getField(this, 28) != null;\n};\n\n\n/**\n * @enum {number}\n */\nproto.FieldType = {\n FT_DEFAULT: 0,\n FT_CALLBACK: 1,\n FT_POINTER: 4,\n FT_STATIC: 2,\n FT_IGNORE: 3,\n FT_INLINE: 5\n};\n\n/**\n * @enum {number}\n */\nproto.IntSize = {\n IS_DEFAULT: 0,\n IS_8: 8,\n IS_16: 16,\n IS_32: 32,\n IS_64: 64\n};\n\n/**\n * @enum {number}\n */\nproto.TypenameMangling = {\n M_NONE: 0,\n M_STRIP_PACKAGE: 1,\n M_FLATTEN: 2,\n M_PACKAGE_INITIALS: 3\n};\n\n/**\n * @enum {number}\n */\nproto.DescriptorSize = {\n DS_AUTO: 0,\n DS_1: 1,\n DS_2: 2,\n DS_4: 4,\n DS_8: 8\n};\n\n\n/**\n * A tuple of {field number, class constructor} for the extension\n * field named `nanopbFileopt`.\n * @type {!jspb.ExtensionFieldInfo}\n */\nproto.nanopbFileopt = new jspb.ExtensionFieldInfo(\n 1010,\n {nanopbFileopt: 0},\n proto.NanoPBOptions,\n /** @type {?function((boolean|undefined),!jspb.Message=): !Object} */ (\n proto.NanoPBOptions.toObject),\n 0);\n\ngoogle_protobuf_descriptor_pb.FileOptions.extensionsBinary[1010] = new jspb.ExtensionFieldBinaryInfo(\n proto.nanopbFileopt,\n jspb.BinaryReader.prototype.readMessage,\n jspb.BinaryWriter.prototype.writeMessage,\n proto.NanoPBOptions.serializeBinaryToWriter,\n proto.NanoPBOptions.deserializeBinaryFromReader,\n false);\n// This registers the extension field with the extended class, so that\n// toObject() will function correctly.\ngoogle_protobuf_descriptor_pb.FileOptions.extensions[1010] = proto.nanopbFileopt;\n\n\n/**\n * A tuple of {field number, class constructor} for the extension\n * field named `nanopbMsgopt`.\n * @type {!jspb.ExtensionFieldInfo}\n */\nproto.nanopbMsgopt = new jspb.ExtensionFieldInfo(\n 1010,\n {nanopbMsgopt: 0},\n proto.NanoPBOptions,\n /** @type {?function((boolean|undefined),!jspb.Message=): !Object} */ (\n proto.NanoPBOptions.toObject),\n 0);\n\ngoogle_protobuf_descriptor_pb.MessageOptions.extensionsBinary[1010] = new jspb.ExtensionFieldBinaryInfo(\n proto.nanopbMsgopt,\n jspb.BinaryReader.prototype.readMessage,\n jspb.BinaryWriter.prototype.writeMessage,\n proto.NanoPBOptions.serializeBinaryToWriter,\n proto.NanoPBOptions.deserializeBinaryFromReader,\n false);\n// This registers the extension field with the extended class, so that\n// toObject() will function correctly.\ngoogle_protobuf_descriptor_pb.MessageOptions.extensions[1010] = proto.nanopbMsgopt;\n\n\n/**\n * A tuple of {field number, class constructor} for the extension\n * field named `nanopbEnumopt`.\n * @type {!jspb.ExtensionFieldInfo}\n */\nproto.nanopbEnumopt = new jspb.ExtensionFieldInfo(\n 1010,\n {nanopbEnumopt: 0},\n proto.NanoPBOptions,\n /** @type {?function((boolean|undefined),!jspb.Message=): !Object} */ (\n proto.NanoPBOptions.toObject),\n 0);\n\ngoogle_protobuf_descriptor_pb.EnumOptions.extensionsBinary[1010] = new jspb.ExtensionFieldBinaryInfo(\n proto.nanopbEnumopt,\n jspb.BinaryReader.prototype.readMessage,\n jspb.BinaryWriter.prototype.writeMessage,\n proto.NanoPBOptions.serializeBinaryToWriter,\n proto.NanoPBOptions.deserializeBinaryFromReader,\n false);\n// This registers the extension field with the extended class, so that\n// toObject() will function correctly.\ngoogle_protobuf_descriptor_pb.EnumOptions.extensions[1010] = proto.nanopbEnumopt;\n\n\n/**\n * A tuple of {field number, class constructor} for the extension\n * field named `nanopb`.\n * @type {!jspb.ExtensionFieldInfo}\n */\nproto.nanopb = new jspb.ExtensionFieldInfo(\n 1010,\n {nanopb: 0},\n proto.NanoPBOptions,\n /** @type {?function((boolean|undefined),!jspb.Message=): !Object} */ (\n proto.NanoPBOptions.toObject),\n 0);\n\ngoogle_protobuf_descriptor_pb.FieldOptions.extensionsBinary[1010] = new jspb.ExtensionFieldBinaryInfo(\n proto.nanopb,\n jspb.BinaryReader.prototype.readMessage,\n jspb.BinaryWriter.prototype.writeMessage,\n proto.NanoPBOptions.serializeBinaryToWriter,\n proto.NanoPBOptions.deserializeBinaryFromReader,\n false);\n// This registers the extension field with the extended class, so that\n// toObject() will function correctly.\ngoogle_protobuf_descriptor_pb.FieldOptions.extensions[1010] = proto.nanopb;\n\ngoog.object.extend(exports, proto);\n","\"use strict\";\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nrequire(\"bootstrap\");\r\nrequire(\"./sass/main.scss\");\r\nrequire(\"./assets/images/favicon-32x32.png\");\r\nrequire(\"./js/custom.ts\");\r\n","\"use strict\";\r\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}));\r\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n});\r\nvar __importStar = (this && this.__importStar) || function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n};\r\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\nvar __importDefault = (this && this.__importDefault) || function (mod) {\r\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nvar he = require('he');\r\n// var Promise = require('es6-promise').Promise;\r\n// @ts-ignore\r\nconst js_cookie_1 = __importDefault(require(\"js-cookie\"));\r\nconst c = __importStar(require(\"./proto/configuration_pb.js\"));\r\nconst bootstrap = __importStar(require(\"bootstrap\"));\r\nconsole.log(c);\r\n// Function to reset a StatusObject\r\nfunction resetStatusObject() {\r\n return {\r\n netmask: undefined,\r\n ip: undefined,\r\n ssid: undefined,\r\n urc: undefined,\r\n rssi: undefined,\r\n gw: undefined,\r\n bt_status: undefined,\r\n bt_sub_status: undefined,\r\n loaded: undefined,\r\n total: undefined,\r\n ota_pct: undefined,\r\n ota_dsc: undefined,\r\n recovery: undefined\r\n };\r\n}\r\nfunction resetNetworkConnection() {\r\n return {\r\n auth: undefined,\r\n pwd: undefined,\r\n dhcpname: undefined,\r\n Action: undefined,\r\n ip: undefined,\r\n ssid: undefined,\r\n rssi: undefined,\r\n gw: undefined,\r\n netmask: undefined,\r\n urc: 0\r\n };\r\n}\r\nwindow.hideSurrounding = function (obj) {\r\n $(obj).parent().parent().hide();\r\n};\r\nfunction hFlash() {\r\n // reset file upload selection if any;\r\n $('#flashfilename').val = null;\r\n flashState.StartOTA();\r\n}\r\nwindow.hFlash = function () {\r\n hFlash();\r\n};\r\nfunction handleReboot(link) {\r\n if (link == 'reboot_ota') {\r\n $('#reboot_ota_nav').removeClass('active').prop(\"disabled\", true);\r\n delayReboot(500, '', 'reboot_ota');\r\n }\r\n else {\r\n $('#reboot_nav').removeClass('active');\r\n delayReboot(500, '', link);\r\n }\r\n}\r\nwindow.handleReboot = function (link) {\r\n handleReboot(link);\r\n};\r\nObject.assign(String.prototype, {\r\n format(...args) {\r\n return this.replace(/{(\\d+)}/g, function (match, number) {\r\n const index = parseInt(number, 10); // Convert string to number\r\n return typeof args[index] !== 'undefined' ? args[index] : match;\r\n });\r\n },\r\n});\r\nObject.assign(String.prototype, {\r\n encodeHTML() {\r\n return he.encode(this).replace(/\\n/g, '
');\r\n },\r\n});\r\nObject.assign(Date.prototype, {\r\n toLocalShort() {\r\n const opt = { dateStyle: 'short', timeStyle: 'short' };\r\n return this.toLocaleString(undefined, opt);\r\n },\r\n});\r\nfunction get_control_option_value(obj) {\r\n let ctrl, id, val, opt;\r\n if (typeof (obj) === 'string') {\r\n id = obj;\r\n ctrl = $(`#${id}`);\r\n }\r\n else {\r\n id = $(obj).attr('id');\r\n ctrl = $(obj);\r\n }\r\n if (ctrl.attr('type') === 'checkbox') {\r\n opt = ctrl.prop('checked') ? id.replace('cmd_opt_', '') : '';\r\n val = true;\r\n }\r\n else {\r\n opt = id.replace('cmd_opt_', '');\r\n val = ctrl.val();\r\n if (typeof val === 'string') {\r\n val = `${val.includes(\" \") ? '\"' : ''}${val}${val.includes(\" \") ? '\"' : ''}`;\r\n }\r\n else if (typeof val !== 'number') {\r\n val = val.toString();\r\n }\r\n }\r\n return { opt, val };\r\n}\r\nfunction handleNVSVisible() {\r\n let nvs_previous_checked = isEnabled(js_cookie_1.default.get(\"show-nvs\"));\r\n const checkBoxElement = $('input#show-nvs')[0];\r\n checkBoxElement.checked = nvs_previous_checked;\r\n if (checkBoxElement.checked || recovery) {\r\n $('*[href*=\"-nvs\"]').show();\r\n }\r\n else {\r\n $('*[href*=\"-nvs\"]').hide();\r\n }\r\n}\r\nfunction concatenateOptions(options) {\r\n let commandLine = ' ';\r\n for (const [option, value] of Object.entries(options)) {\r\n if (option !== 'n' && option !== 'o') {\r\n commandLine += `-${option} `;\r\n if (value !== true) {\r\n commandLine += `${value} `;\r\n }\r\n }\r\n }\r\n return commandLine;\r\n}\r\nfunction isEnabled(val) {\r\n return val != undefined && typeof val === 'string' && val.match(\"[Yy1]\").length > 0;\r\n}\r\nvar NVSType;\r\n(function (NVSType) {\r\n NVSType[NVSType[\"NVS_TYPE_U8\"] = 1] = \"NVS_TYPE_U8\";\r\n NVSType[NVSType[\"NVS_TYPE_I8\"] = 17] = \"NVS_TYPE_I8\";\r\n NVSType[NVSType[\"NVS_TYPE_U16\"] = 2] = \"NVS_TYPE_U16\";\r\n NVSType[NVSType[\"NVS_TYPE_I16\"] = 18] = \"NVS_TYPE_I16\";\r\n NVSType[NVSType[\"NVS_TYPE_U32\"] = 4] = \"NVS_TYPE_U32\";\r\n NVSType[NVSType[\"NVS_TYPE_I32\"] = 20] = \"NVS_TYPE_I32\";\r\n NVSType[NVSType[\"NVS_TYPE_U64\"] = 8] = \"NVS_TYPE_U64\";\r\n NVSType[NVSType[\"NVS_TYPE_I64\"] = 24] = \"NVS_TYPE_I64\";\r\n NVSType[NVSType[\"NVS_TYPE_STR\"] = 33] = \"NVS_TYPE_STR\";\r\n NVSType[NVSType[\"NVS_TYPE_BLOB\"] = 66] = \"NVS_TYPE_BLOB\";\r\n NVSType[NVSType[\"NVS_TYPE_ANY\"] = 255] = \"NVS_TYPE_ANY\";\r\n})(NVSType || (NVSType = {}));\r\n;\r\nconst btIcons = {\r\n bt_playing: { label: '', icon: 'media_bluetooth_on' },\r\n bt_disconnected: { label: '', icon: 'media_bluetooth_off' },\r\n bt_neutral: { label: '', icon: 'bluetooth' },\r\n bt_connecting: { label: '', icon: 'bluetooth_searching' },\r\n bt_connected: { label: '', icon: 'bluetooth_connected' },\r\n bt_disabled: { label: '', icon: 'bluetooth_disabled' },\r\n play_arrow: { label: '', icon: 'play_circle_filled' },\r\n pause: { label: '', icon: 'pause_circle' },\r\n stop: { label: '', icon: 'stop_circle' },\r\n '': { label: '', icon: '' }\r\n};\r\nconst batIcons = [\r\n { icon: \"battery_0_bar\", label: '▪', ranges: [{ f: 5.8, t: 6.8 }, { f: 8.8, t: 10.2 }] },\r\n { icon: \"battery_2_bar\", label: '▪▪', ranges: [{ f: 6.8, t: 7.4 }, { f: 10.2, t: 11.1 }] },\r\n { icon: \"battery_3_bar\", label: '▪▪▪', ranges: [{ f: 7.4, t: 7.5 }, { f: 11.1, t: 11.25 }] },\r\n { icon: \"battery_4_bar\", label: '▪▪▪▪', ranges: [{ f: 7.5, t: 7.8 }, { f: 11.25, t: 11.7 }] }\r\n];\r\nconst btStateIcons = [\r\n { desc: 'Idle', sub: ['bt_neutral'] },\r\n { desc: 'Discovering', sub: ['bt_connecting'] },\r\n { desc: 'Discovered', sub: ['bt_connecting'] },\r\n { desc: 'Unconnected', sub: ['bt_disconnected'] },\r\n { desc: 'Connecting', sub: ['bt_connecting'] },\r\n {\r\n desc: 'Connected',\r\n sub: ['bt_connected', 'play_arrow', 'bt_playing', 'pause', 'stop'],\r\n },\r\n { desc: 'Disconnecting', sub: ['bt_disconnected'] },\r\n];\r\nconst connectReturnCode = {\r\n OK: 0,\r\n FAIL: 1,\r\n DISC: 2,\r\n LOST: 3,\r\n RESTORE: 4,\r\n ETH: 5\r\n};\r\nconst taskStates = [\r\n 'eRunning',\r\n /*! < A task is querying the state of itself, so must be running. */\r\n 'eReady',\r\n /*! < The task being queried is in a read or pending ready list. */\r\n 'eBlocked',\r\n /*! < The task being queried is in the Blocked state. */\r\n 'eSuspended',\r\n /*! < The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */\r\n 'eDeleted'\r\n];\r\nlet flashState = {\r\n NONE: 0,\r\n REBOOT_TO_RECOVERY: 2,\r\n SET_FWURL: 5,\r\n FLASHING: 6,\r\n DONE: 7,\r\n UPLOADING: 8,\r\n ERROR: 9,\r\n UPLOADCOMPLETE: 10,\r\n _state: -1,\r\n olderRecovery: false,\r\n statusText: '',\r\n flashURL: '',\r\n flashFileName: '',\r\n statusPercent: 0,\r\n Completed: false,\r\n recovery: false,\r\n prevRecovery: false,\r\n updateModal: new bootstrap.Modal(document.getElementById('otadiv'), {}),\r\n reset: function () {\r\n this.olderRecovery = false;\r\n this.statusText = '';\r\n this.statusPercent = -1;\r\n this.flashURL = '';\r\n this.flashFileName = undefined;\r\n this.UpdateProgress();\r\n $('#rTable tr.release').removeClass('table-success table-warning');\r\n $('.flact').prop('disabled', false);\r\n $('#flashfilename')[0].value = null;\r\n $('#fw-url-input')[0].value = null;\r\n if (!this.isStateError()) {\r\n $('span#flash-status').html('');\r\n $('#fwProgressLabel').parent().removeClass('bg-danger');\r\n }\r\n this._state = this.NONE;\r\n return this;\r\n },\r\n isStateUploadComplete: function () {\r\n return this._state == this.UPLOADCOMPLETE;\r\n },\r\n isStateError: function () {\r\n return this._state == this.ERROR;\r\n },\r\n isStateNone: function () {\r\n return this._state == this.NONE;\r\n },\r\n isStateRebootRecovery: function () {\r\n return this._state == this.REBOOT_TO_RECOVERY;\r\n },\r\n isStateSetUrl: function () {\r\n return this._state == this.SET_FWURL;\r\n },\r\n isStateFlashing: function () {\r\n return this._state == this.FLASHING;\r\n },\r\n isStateDone: function () {\r\n return this._state == this.DONE;\r\n },\r\n isStateUploading: function () {\r\n return this._state == this.UPLOADING;\r\n },\r\n init: function () {\r\n this._state = this.NONE;\r\n return this;\r\n },\r\n SetStateError: function () {\r\n this._state = this.ERROR;\r\n $('#fwProgressLabel').parent().addClass('bg-danger');\r\n return this;\r\n },\r\n SetStateNone: function () {\r\n this._state = this.NONE;\r\n return this;\r\n },\r\n SetStateRebootRecovery: function () {\r\n this._state = this.REBOOT_TO_RECOVERY;\r\n // Reboot system to recovery mode\r\n this.SetStatusText('Starting recovery mode.');\r\n $.ajax({\r\n url: '/recovery.json',\r\n context: this,\r\n dataType: 'text',\r\n method: 'POST',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify({\r\n timestamp: Date.now(),\r\n }),\r\n error: function (xhr, _ajaxOptions, thrownError) {\r\n var _a;\r\n this.setOTAError(`Unexpected error while trying to restart to recovery. (status=${(_a = xhr.status) !== null && _a !== void 0 ? _a : ''}, error=${thrownError !== null && thrownError !== void 0 ? thrownError : ''} ) `);\r\n },\r\n complete: function (response) {\r\n this.SetStatusText('Waiting for system to boot.');\r\n },\r\n });\r\n return this;\r\n },\r\n SetStateSetUrl: function () {\r\n this._state = this.SET_FWURL;\r\n this.statusText = 'Sending firmware download location.';\r\n let confData = {\r\n fwurl: {\r\n value: this.flashURL,\r\n type: 33,\r\n }\r\n };\r\n post_config(confData);\r\n return this;\r\n },\r\n SetStateFlashing: function () {\r\n this._state = this.FLASHING;\r\n return this;\r\n },\r\n SetStateDone: function () {\r\n this._state = this.DONE;\r\n this.reset();\r\n return this;\r\n },\r\n SetStateUploading: function () {\r\n this._state = this.UPLOADING;\r\n return this.SetStatusText('Sending file to device.');\r\n },\r\n SetStateUploadComplete: function () {\r\n this._state = this.UPLOADCOMPLETE;\r\n return this;\r\n },\r\n isFlashExecuting: function () {\r\n return true === (this._state != this.UPLOADING && (this.statusText !== '' || this.statusPercent >= 0));\r\n },\r\n toString: function () {\r\n let keys = Object.keys(this);\r\n return keys.find(x => this[x] === this._state);\r\n },\r\n setOTATargets: function () {\r\n this.flashURL = '';\r\n this.flashFileName = '';\r\n this.flashURL = $('#fw-url-input').val();\r\n let fileInputctrl = $('#flashfilename')[0];\r\n let fileInput = fileInputctrl.files;\r\n if (fileInput.length > 0) {\r\n this.flashFileName = fileInput[0];\r\n }\r\n if (this.flashFileName.length == 0 && this.flashURL.length == 0) {\r\n this.setOTAError('Invalid url or file. Cannot start OTA');\r\n }\r\n return this;\r\n },\r\n setOTAError: function (message) {\r\n this.SetStateError().SetStatusPercent(0).SetStatusText(message).reset();\r\n return this;\r\n },\r\n ShowDialog: function () {\r\n if (!this.isStateNone()) {\r\n this.updateModal.show();\r\n $('.flact').prop('disabled', true);\r\n }\r\n return this;\r\n },\r\n SetStatusPercent: function (pct) {\r\n var pctChanged = (this.statusPercent != pct);\r\n this.statusPercent = pct;\r\n if (pctChanged) {\r\n if (!this.isStateUploading() && !this.isStateFlashing()) {\r\n this.SetStateFlashing();\r\n }\r\n if (pct == 100) {\r\n if (this.isStateFlashing()) {\r\n this.SetStateDone();\r\n }\r\n else if (this.isStateUploading()) {\r\n this.statusPercent = 0;\r\n this.SetStateFlashing();\r\n }\r\n }\r\n this.UpdateProgress().ShowDialog();\r\n }\r\n return this;\r\n },\r\n SetStatusText: function (txt) {\r\n var changed = (this.statusText != txt);\r\n this.statusText = txt;\r\n if (changed) {\r\n $('span#flash-status').html(this.statusText);\r\n this.ShowDialog();\r\n }\r\n return this;\r\n },\r\n UpdateProgress: function () {\r\n $('.progress-bar')\r\n .css('width', this.statusPercent + '%')\r\n .attr('aria-valuenow', this.statusPercent)\r\n .text(this.statusPercent + '%');\r\n $('.progress-bar').html((this.isStateDone() ? 100 : this.statusPercent) + '%');\r\n return this;\r\n },\r\n StartOTA: function () {\r\n this.logEvent(this.StartOTA.name);\r\n $('#fwProgressLabel').parent().removeClass('bg-danger');\r\n this.setOTATargets();\r\n if (this.isStateError()) {\r\n return this;\r\n }\r\n if (!recovery) {\r\n this.SetStateRebootRecovery();\r\n }\r\n else {\r\n this.SetStateFlashing().TargetReadyStartOTA();\r\n }\r\n return this;\r\n },\r\n UploadLocalFile: function () {\r\n this.SetStateUploading();\r\n const xhttp = new XMLHttpRequest();\r\n var boundHandleUploadProgressEvent = this.HandleUploadProgressEvent.bind(this);\r\n var boundsetOTAError = this.setOTAError.bind(this);\r\n xhttp.upload.addEventListener(\"progress\", boundHandleUploadProgressEvent, false);\r\n xhttp.onreadystatechange = function () {\r\n if (xhttp.readyState === 4) {\r\n if (xhttp.status === 0 || xhttp.status === 404) {\r\n boundsetOTAError(`Upload Failed. Recovery version might not support uploading. Please use web update instead.`);\r\n }\r\n }\r\n };\r\n xhttp.open('POST', '/flash.json', true);\r\n xhttp.send(this.flashFileName);\r\n },\r\n TargetReadyStartOTA: function () {\r\n if (recovery && this.prevRecovery && !this.isStateRebootRecovery() && !this.isStateFlashing()) {\r\n // this should only execute once, while being in a valid state\r\n return this;\r\n }\r\n this.logEvent(this.TargetReadyStartOTA.name);\r\n if (!recovery) {\r\n console.error('Event TargetReadyStartOTA fired in the wrong mode ');\r\n return this;\r\n }\r\n this.prevRecovery = true;\r\n if (this.flashFileName !== '') {\r\n this.UploadLocalFile();\r\n }\r\n else if (this.flashURL != '') {\r\n this.SetStateSetUrl();\r\n }\r\n else {\r\n this.setOTAError('Invalid URL or file name while trying to start the OTa process');\r\n }\r\n },\r\n HandleUploadProgressEvent: function (data) {\r\n this.logEvent(this.HandleUploadProgressEvent.name);\r\n this.SetStateUploading().SetStatusPercent(Math.round(data.loaded / data.total * 100)).SetStatusText('Uploading file to device');\r\n },\r\n EventTargetStatus: function (data) {\r\n var _a, _b;\r\n if (!this.isStateNone()) {\r\n this.logEvent(this.EventTargetStatus.name);\r\n }\r\n if ((_a = data.ota_pct) !== null && _a !== void 0 ? _a : -1 >= 0) {\r\n this.olderRecovery = true;\r\n this.SetStatusPercent(data.ota_pct);\r\n }\r\n if (((_b = data.ota_dsc) !== null && _b !== void 0 ? _b : '') != '') {\r\n this.olderRecovery = true;\r\n this.SetStatusText(data.ota_dsc);\r\n }\r\n if (data.recovery != undefined) {\r\n this.recovery = data.recovery === 1 ? true : false;\r\n }\r\n if (this.isStateRebootRecovery() && this.recovery) {\r\n this.TargetReadyStartOTA();\r\n }\r\n },\r\n EventOTAMessageClass: function (data) {\r\n this.logEvent(this.EventOTAMessageClass.name);\r\n var otaData = JSON.parse(data);\r\n this.SetStatusPercent(otaData.ota_pct).SetStatusText(otaData.ota_dsc);\r\n },\r\n logEvent: function (fun) {\r\n console.log(`${fun}, flash state ${this.toString()}, recovery: ${this.recovery}, ota pct: ${this.statusPercent}, ota desc: ${this.statusText}`);\r\n }\r\n};\r\nlet presetsloaded = false;\r\nlet is_i2c_locked = false;\r\nlet statusInterval = 2000;\r\nlet messageInterval = 2500;\r\nfunction post_config(data) {\r\n let confPayload = {\r\n timestamp: Date.now(),\r\n config: data\r\n };\r\n $.ajax({\r\n url: '/config.json',\r\n dataType: 'text',\r\n method: 'POST',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify(confPayload),\r\n error: handleExceptionResponse,\r\n });\r\n}\r\nfunction parseSqueezeliteCommandLine(commandLine) {\r\n const options = {};\r\n let output, name;\r\n let otherValues = '';\r\n const argRegex = /(\"[^\"]+\"|'[^']+'|\\S+)/g;\r\n const args = commandLine.match(argRegex) || [];\r\n let i = 0;\r\n while (i < args.length) {\r\n const arg = args[i];\r\n if (arg.startsWith('-')) {\r\n const option = arg.slice(1);\r\n if (option === '') {\r\n otherValues += args.slice(i).join(' ');\r\n break;\r\n }\r\n let value = \"\";\r\n if (i + 1 < args.length && !args[i + 1].startsWith('-')) {\r\n value = args[i + 1].replace(/\"/g, '').replace(/'/g, '');\r\n i++;\r\n }\r\n options[option] = value;\r\n }\r\n else {\r\n otherValues += arg + ' ';\r\n }\r\n i++;\r\n }\r\n otherValues = otherValues.trim();\r\n output = getOutput(options);\r\n name = getName(options);\r\n let otherOptions = { btname: null, n: null };\r\n // Assign 'o' and 'n' options to otherOptions if present\r\n if (options.o && output.toUpperCase() === 'BT') {\r\n let temp = parseSqueezeliteCommandLine(options.o);\r\n if (temp.name) {\r\n otherOptions.btname = temp.name;\r\n }\r\n delete options.o;\r\n }\r\n if (options.n) {\r\n otherOptions.n = options.n;\r\n delete options.n;\r\n }\r\n return { name, output, options, otherValues, otherOptions };\r\n}\r\nfunction getOutput(options) {\r\n let output;\r\n if (options.o) {\r\n output = options.o.replace(/\"/g, '').replace(/'/g, '');\r\n /* set output as the first alphanumerical word in the command line */\r\n if (output.indexOf(' ') > 0) {\r\n output = output.substring(0, output.indexOf(' '));\r\n }\r\n }\r\n return output;\r\n}\r\nfunction getName(options) {\r\n let name;\r\n /* if n option present, assign to name variable */\r\n if (options.n) {\r\n name = options.n.replace(/\"/g, '').replace(/'/g, '');\r\n }\r\n return name;\r\n}\r\nfunction isConnected() {\r\n return ConnectedTo.hasOwnProperty('ip') && ConnectedTo.ip != '0.0.0.0' && ConnectedTo.ip != '';\r\n}\r\nfunction getIcon(icons) {\r\n return isConnected() ? icons.icon : icons.label;\r\n}\r\nfunction handlebtstate(data) {\r\n var _a;\r\n let icon = { label: '', icon: '' };\r\n let tt = '';\r\n if (data.bt_status !== undefined && data.bt_sub_status !== undefined) {\r\n const iconIndex = (_a = btStateIcons[data.bt_status]) === null || _a === void 0 ? void 0 : _a.sub[data.bt_sub_status];\r\n if (iconIndex) {\r\n icon = btIcons[iconIndex];\r\n tt = btStateIcons[data.bt_status].desc;\r\n }\r\n else {\r\n icon = btIcons.bt_connected;\r\n tt = 'Output status';\r\n }\r\n }\r\n $('#o_type').attr('title', tt);\r\n $('#o_bt').html(isConnected() ? icon.label : icon.icon); // Note: Assuming `isConnected()` is defined elsewhere.\r\n}\r\nfunction handleTemplateTypeRadio(outtype) {\r\n $('#o_type').children('span').css({ display: 'none' });\r\n let changed = false;\r\n if (outtype !== output) {\r\n changed = true;\r\n output = outtype;\r\n }\r\n $('#' + output).prop('checked', true);\r\n $('#o_' + output).css({ display: 'inline' });\r\n if (changed) {\r\n Object.entries(commandDefaults[output]).forEach(([key, value]) => {\r\n $(`#cmd_opt_${key}`).val(value);\r\n });\r\n }\r\n}\r\nfunction handleExceptionResponse(xhr, _ajaxOptions, thrownError) {\r\n console.log(xhr.status);\r\n console.log(thrownError);\r\n if (thrownError !== '') {\r\n showLocalMessage(thrownError, 'MESSAGING_ERROR');\r\n }\r\n}\r\nfunction HideCmdMessage(cmdname) {\r\n $('#toast_' + cmdname)\r\n .removeClass('table-success')\r\n .removeClass('table-warning')\r\n .removeClass('table-danger')\r\n .addClass('table-success')\r\n .removeClass('show');\r\n $('#msg_' + cmdname).html('');\r\n}\r\nfunction showCmdMessage(cmdname, msgtype, msgtext, append = false) {\r\n let color = 'table-success';\r\n if (msgtype === 'MESSAGING_WARNING') {\r\n color = 'table-warning';\r\n }\r\n else if (msgtype === 'MESSAGING_ERROR') {\r\n color = 'table-danger';\r\n }\r\n $('#toast_' + cmdname)\r\n .removeClass('table-success')\r\n .removeClass('table-warning')\r\n .removeClass('table-danger')\r\n .addClass(color)\r\n .addClass('show');\r\n let escapedtext = msgtext\r\n .substring(0, msgtext.length - 1)\r\n .encodeHTML()\r\n .replace(/\\n/g, '
');\r\n escapedtext =\r\n ($('#msg_' + cmdname).html().length > 0 && append\r\n ? $('#msg_' + cmdname).html() + '
'\r\n : '') + escapedtext;\r\n $('#msg_' + cmdname).html(escapedtext);\r\n}\r\nlet releaseURL = 'https://api.github.com/repos/sle118/squeezelite-esp32/releases';\r\nlet recovery = false;\r\nlet messagesHeld = false;\r\nlet commandBTSinkName = '';\r\nconst commandHeader = 'squeezelite ';\r\nconst commandDefaults = {\r\n i2s: { b: \"500:2000\", C: \"30\", W: \"\", Z: \"96000\", o: \"I2S\" },\r\n spdif: { b: \"500:2000\", C: \"30\", W: \"\", Z: \"48000\", o: \"SPDIF\" },\r\n bt: { b: \"500:2000\", C: \"30\", W: \"\", Z: \"44100\", o: \"BT\" },\r\n};\r\nlet validOptions = {\r\n codecs: ['flac', 'pcm', 'mp3', 'ogg', 'aac', 'wma', 'alac', 'dsd', 'mad', 'mpg']\r\n};\r\n//let blockFlashButton = false;\r\nlet apList = null;\r\n//let selectedSSID = '';\r\n//let checkStatusInterval = null;\r\nlet messagecount = 0;\r\nlet messageseverity = 'MESSAGING_INFO';\r\nlet SystemConfig;\r\nlet LastCommandsState = NaN;\r\nvar output = '';\r\nlet hostName = '';\r\nlet versionName = 'Squeezelite-ESP32';\r\nlet prevmessage = '';\r\nlet project_name = versionName;\r\nlet depth = 16;\r\nlet board_model = '';\r\nlet platform_name = versionName;\r\nlet preset_name = '';\r\nlet btSinkNamesOptSel = '#cfg-audio-bt_source-sink_name';\r\nlet ConnectedTo;\r\nlet ConnectingToSSID;\r\nlet lmsBaseUrl = \"\";\r\nlet prevLMSIP = '';\r\nconst ConnectingToActions = {\r\n 'CONN': 0, 'MAN': 1, 'STS': 2,\r\n};\r\nfunction delay(promise, duration) {\r\n return new Promise((resolve, reject) => {\r\n promise.then(value => setTimeout(() => resolve(value), duration), reason => setTimeout(() => reject(reason), duration));\r\n });\r\n}\r\nfunction getConfigJson(slimMode) {\r\n const config = {};\r\n $('input.nvs').each(function (_index, element) {\r\n const entry = element;\r\n const nvsTypeAttr = entry.attributes.getNamedItem('nvs_type');\r\n if (!slimMode && nvsTypeAttr) {\r\n const nvsType = parseInt(nvsTypeAttr.value, 10);\r\n if (entry.id !== '') {\r\n const value = (nvsType <= NVSType.NVS_TYPE_I64) ? parseInt(entry.value, 10) : entry.value;\r\n config[entry.id] = {\r\n value: value,\r\n type: nvsType,\r\n };\r\n }\r\n }\r\n else {\r\n if (entry.id !== '') {\r\n config[entry.id] = entry.value;\r\n }\r\n }\r\n });\r\n // In the following, we assume that `#nvs-new-key` and `#nvs-new-value`\r\n // correspond to input elements and thus their values are always strings.\r\n const key = $('#nvs-new-key').val();\r\n const val = $('#nvs-new-value').val();\r\n if (key && key !== '') {\r\n if (!slimMode) {\r\n config[key] = {\r\n value: val,\r\n type: NVSType.NVS_TYPE_I8, // Assuming a default type here\r\n };\r\n }\r\n else {\r\n config[key] = val;\r\n }\r\n }\r\n return config;\r\n}\r\nfunction handleHWPreset(allfields, reboot) {\r\n const selJson = JSON.parse(allfields[0].value);\r\n const cmd = allfields[0].getAttribute(\"cmdname\");\r\n console.log(`selected model: ${selJson.name}`);\r\n let confPayload = {\r\n timestamp: Date.now(),\r\n config: { model_config: { value: selJson.name, type: 33 } } // Assuming 33 is some sort of default type\r\n };\r\n for (const [name, value] of Object.entries(selJson.config)) {\r\n const storedval = (typeof value === 'string' || value instanceof String) ? value : JSON.stringify(value);\r\n confPayload.config[name] = {\r\n value: storedval.toString(),\r\n type: NVSType.NVS_TYPE_STR,\r\n };\r\n showCmdMessage(cmd, 'MESSAGING_INFO', `Setting ${name}=${storedval} `, true);\r\n }\r\n showCmdMessage(cmd, 'MESSAGING_INFO', `Committing `, true);\r\n $.ajax({\r\n url: '/config.json',\r\n dataType: 'text',\r\n method: 'POST',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify(confPayload),\r\n error: function (xhr, _ajaxOptions, thrownError) {\r\n handleExceptionResponse(xhr, _ajaxOptions, thrownError);\r\n showCmdMessage(cmd, 'MESSAGING_ERROR', `Unexpected error ${(thrownError !== '') ? thrownError : 'with return status = ' + xhr.status} `, true);\r\n },\r\n success: function (response) {\r\n showCmdMessage(cmd, 'MESSAGING_INFO', `Saving complete `, true);\r\n console.log(response);\r\n if (reboot) {\r\n delayReboot(2500, cmd);\r\n }\r\n },\r\n });\r\n}\r\n// pull json file from https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/b462691f69e2ad31ac95c547af6ec97afb0f53db/squeezelite-esp32-presets.json and\r\nfunction loadPresets() {\r\n if ($(\"#cfg-hw-preset-model_config\").length == 0)\r\n return;\r\n if (presetsloaded)\r\n return;\r\n presetsloaded = true;\r\n $('#cfg-hw-preset-model_config').html('');\r\n $.getJSON('https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/', { _: new Date().getTime() }, function (data) {\r\n $.each(data, function (key, val) {\r\n $('#cfg-hw-preset-model_config').append(``);\r\n if (preset_name !== '' && preset_name == val.name) {\r\n $('#cfg-hw-preset-model_config').val(preset_name);\r\n }\r\n });\r\n if (preset_name !== '') {\r\n $('#prev_preset').show().val(preset_name);\r\n }\r\n }).fail(function (jqxhr, textStatus, error) {\r\n const err = textStatus + ', ' + error;\r\n console.log('Request Failed: ' + err);\r\n });\r\n}\r\nfunction delayReboot(duration, cmdname, ota = 'reboot') {\r\n const url = `/${ota}.json`;\r\n $('tbody#tasks').empty();\r\n $('#tasks_sect').css('visibility', 'collapse');\r\n delay(Promise.resolve({ cmdname: cmdname, url: url }), duration)\r\n .then(function (data) {\r\n // Your existing logic here\r\n console.log('now triggering reboot');\r\n $(\"button[onclick*='handleReboot']\").addClass('rebooting');\r\n $.ajax({\r\n // Your existing AJAX call setup here\r\n complete: function () {\r\n console.log('reboot call completed');\r\n delay(Promise.resolve(data), 6000)\r\n .then(function (rdata) {\r\n // Your existing logic here\r\n });\r\n },\r\n });\r\n });\r\n}\r\nfunction saveAutoexec1(apply) {\r\n showCmdMessage('cfg-audio-tmpl', 'MESSAGING_INFO', 'Saving.\\n', false);\r\n let commandLine = `${commandHeader} -o ${output} `;\r\n $('.sqcmd').each(function () {\r\n let { opt, val } = get_control_option_value($(this));\r\n if ((opt && opt.length > 0) && typeof (val) == 'boolean' || typeof (val) === 'string' && val.length > 0) {\r\n const optStr = opt === ':' ? opt : (` -${opt} `);\r\n val = typeof (val) == 'boolean' ? '' : val;\r\n commandLine += `${optStr} ${val}`;\r\n }\r\n });\r\n const resample = $('#cmd_opt_R input[name=resample]:checked');\r\n if (resample.length > 0 && resample.attr('suffix') !== '') {\r\n commandLine += resample.attr('suffix');\r\n // now check resample_i option and if checked, add suffix to command line\r\n if ($('#resample_i').is(\":checked\") && resample.attr('aint') == 'true') {\r\n commandLine += $('#resample_i').attr('suffix');\r\n }\r\n }\r\n if (output === 'bt') {\r\n showCmdMessage('cfg-audio-tmpl', 'MESSAGING_INFO', 'Remember to configure the Bluetooth audio device name.\\n', true);\r\n }\r\n // commandLine += concatenateOptions(options);\r\n const data = {\r\n timestamp: Date.now(),\r\n config: {\r\n autoexec1: { value: commandLine, type: NVSType.NVS_TYPE_STR }\r\n }\r\n };\r\n $.ajax({\r\n url: '/config.json',\r\n dataType: 'text',\r\n method: 'POST',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify(data),\r\n error: handleExceptionResponse,\r\n complete: function (response) {\r\n if (response.responseText &&\r\n JSON.parse(response.responseText).result === 'OK') {\r\n showCmdMessage('cfg-audio-tmpl', 'MESSAGING_INFO', 'Done.\\n', true);\r\n if (apply) {\r\n delayReboot(1500, 'cfg-audio-tmpl');\r\n }\r\n }\r\n else if (JSON.parse(response.responseText).result) {\r\n showCmdMessage('cfg-audio-tmpl', 'MESSAGING_WARNING', JSON.parse(response.responseText).Result + '\\n', true);\r\n }\r\n else {\r\n showCmdMessage('cfg-audio-tmpl', 'MESSAGING_ERROR', response.statusText + '\\n');\r\n }\r\n console.log(response.responseText);\r\n },\r\n });\r\n console.log('sent data:', JSON.stringify(data));\r\n}\r\nfunction handleDisconnect() {\r\n $.ajax({\r\n url: '/connect.json',\r\n dataType: 'text',\r\n method: 'DELETE',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify({\r\n timestamp: Date.now(),\r\n }),\r\n });\r\n}\r\nfunction setPlatformFilter(val) {\r\n if ($('.upf').filter(function () { return $(this).text().toUpperCase() === val.toUpperCase(); }).length > 0) {\r\n $('#splf').val(val).trigger('input');\r\n return true;\r\n }\r\n return false;\r\n}\r\nfunction handleConnect() {\r\n ConnectingToSSID.ssid = $('#manual_ssid').val().toString();\r\n ConnectingToSSID.pwd = $('#manual_pwd').val().toString();\r\n ConnectingToSSID.dhcpname = $('#dhcp-name2').val().toString();\r\n $(\"*[class*='connecting']\").hide();\r\n $('#ssid-wait').text(ConnectingToSSID.ssid);\r\n $('.connecting').show();\r\n $.ajax({\r\n url: '/connect.json',\r\n dataType: 'text',\r\n method: 'POST',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify({\r\n timestamp: Date.now(),\r\n ssid: ConnectingToSSID.ssid,\r\n pwd: ConnectingToSSID.pwd\r\n }),\r\n error: handleExceptionResponse,\r\n });\r\n // now we can re-set the intervals regardless of result\r\n}\r\nfunction renderError(opt, error) {\r\n const fieldname = `cmd_opt_${opt}`;\r\n let errorFieldName = `${fieldname}-error`;\r\n let errorField = $(`#${errorFieldName}`);\r\n let field = $(`#${fieldname}`);\r\n if (!errorField || errorField.length == 0) {\r\n field.after(`
`);\r\n errorField = $(`#${errorFieldName}`);\r\n }\r\n if (error.length == 0) {\r\n errorField.hide();\r\n field.removeClass('is-invalid');\r\n field.addClass('is-valid');\r\n errorField.text('');\r\n }\r\n else {\r\n errorField.show();\r\n errorField.text(error);\r\n field.removeClass('is-valid');\r\n field.addClass('is-invalid');\r\n }\r\n return errorField;\r\n}\r\n$(function () {\r\n $('.material-icons').each(function (_index, entry) {\r\n entry.setAttribute('data-icon', entry.textContent || '');\r\n });\r\n setIcons(true);\r\n handleNVSVisible();\r\n flashState.init();\r\n $('#fw-url-input').on('input', function () {\r\n const stringVal = $(this).val().toString();\r\n if (stringVal.length > 8 && (stringVal.startsWith('http://') || stringVal.startsWith('https://'))) {\r\n $('#start-flash').show();\r\n }\r\n else {\r\n $('#start-flash').hide();\r\n }\r\n });\r\n $('.upSrch').on('input', function () {\r\n const inputField = this;\r\n const val = inputField.value;\r\n $(\"#rTable tr\").removeClass(inputField.id + '_hide');\r\n if (val.length > 0) {\r\n $(`#rTable td:nth-child(${$(inputField).parent().index() + 1})`).filter(function () {\r\n return !$(this).text().toUpperCase().includes(val.toUpperCase());\r\n }).parent().addClass(this.id + '_hide');\r\n }\r\n $('[class*=\"_hide\"]').hide();\r\n $('#rTable tr').not('[class*=\"_hide\"]').show();\r\n });\r\n setTimeout(refreshAP, 1500);\r\n /* add validation for cmd_opt_c, which accepts a comma separated list.\r\n getting known codecs from validOptions.codecs array\r\n use bootstrap classes to highlight the error with an overlay message */\r\n $('#options input').on('input', function () {\r\n const inputField = this;\r\n const { opt, val } = get_control_option_value(this);\r\n if (opt === 'c' || opt === 'e') {\r\n const fieldname = `cmd_opt_${opt}_codec-error`;\r\n const values = val.toString().split(',').map(function (item) {\r\n return item.trim();\r\n });\r\n /* get a list of invalid codecs */\r\n const invalid = values.filter(function (item) {\r\n return !validOptions.codecs.includes(item);\r\n });\r\n renderError(opt, invalid.length > 0 ? `Invalid codec(s) ${invalid.join(', ')}` : '');\r\n }\r\n /* add validation for cmd_opt_m, which accepts a mac_address */\r\n if (opt === 'm') {\r\n const mac_regex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;\r\n renderError(opt, mac_regex.test(val.toString()) ? '' : 'Invalid MAC address');\r\n }\r\n if (opt === 'r') {\r\n const rateRegex = /^(\\d+\\.?\\d*|\\.\\d+)-(\\d+\\.?\\d*|\\.\\d+)$|^(\\d+\\.?\\d*)$|^(\\d+\\.?\\d*,)+\\d+\\.?\\d*$/;\r\n renderError(opt, rateRegex.test(val.toString()) ? '' : `Invalid rate(s) ${val}. Acceptable format: |-|,,`);\r\n }\r\n });\r\n $('#WifiConnectDialog')[0].addEventListener('shown.bs.modal', function (event) {\r\n $(\"*[class*='connecting']\").hide();\r\n if (event === null || event === void 0 ? void 0 : event.relatedTarget) {\r\n ConnectingToSSID.Action = ConnectingToActions.CONN;\r\n if ($(event.relatedTarget).children('td:eq(1)').text() == ConnectedTo.ssid) {\r\n ConnectingToSSID.Action = ConnectingToActions.STS;\r\n }\r\n else {\r\n if (!$(event.relatedTarget).is(':last-child')) {\r\n ConnectingToSSID.ssid = $(event.relatedTarget).children('td:eq(1)').text();\r\n $('#manual_ssid').val(ConnectingToSSID.ssid);\r\n }\r\n else {\r\n ConnectingToSSID.Action = ConnectingToActions.MAN;\r\n ConnectingToSSID.ssid = '';\r\n $('#manual_ssid').val(ConnectingToSSID.ssid);\r\n }\r\n }\r\n }\r\n if (ConnectingToSSID.Action !== ConnectingToActions.STS) {\r\n $('.connecting-init').show();\r\n $('#manual_ssid').trigger('focus');\r\n }\r\n else {\r\n handleWifiDialog();\r\n }\r\n });\r\n $('#WifiConnectDialog')[0].addEventListener('hidden.bs.modal', function () {\r\n $('#WifiConnectDialog input').val('');\r\n });\r\n $('#uCnfrm')[0].addEventListener('shown.bs.modal', function () {\r\n $('#selectedFWURL').text($('#fw-url-input').val().toString());\r\n });\r\n $('input#show-commands')[0].checked = LastCommandsState === 1;\r\n $('a[href^=\"#tab-commands\"]').hide();\r\n $('#load-nvs').on('click', function () {\r\n $('#nvsfilename').trigger('click');\r\n });\r\n $('#nvsfilename').on('change', function () {\r\n const _this = this;\r\n if (typeof window.FileReader !== 'function') {\r\n throw \"The file API isn't supported on this browser.\";\r\n }\r\n if (!_this.files) {\r\n throw 'This browser does not support the `files` property of the file input.';\r\n }\r\n if (!_this.files[0]) {\r\n return undefined;\r\n }\r\n const file = _this.files[0];\r\n let fr = new FileReader();\r\n fr.onload = function (e) {\r\n let data;\r\n try {\r\n data = JSON.parse(e.target.result.toString());\r\n }\r\n catch (ex) {\r\n alert('Parsing failed!\\r\\n ' + ex);\r\n }\r\n $('input.nvs').each(function (_index, entry) {\r\n $(this).parent().removeClass('bg-warning').removeClass('bg-success');\r\n if (data[entry.id]) {\r\n if (data[entry.id] !== entry.value) {\r\n console.log('Changed ' + entry.id + ' ' + entry.value + '==>' + data[entry.id]);\r\n $(this).parent().addClass('bg-warning');\r\n $(this).val(data[entry.id]);\r\n }\r\n else {\r\n $(this).parent().addClass('bg-success');\r\n }\r\n }\r\n });\r\n var changed = $(\"input.nvs\").children('.bg-warning');\r\n if (changed) {\r\n alert('Highlighted values were changed. Press Commit to change on the device');\r\n }\r\n };\r\n fr.readAsText(file);\r\n _this.value = null;\r\n });\r\n $('#clear-syslog').on('click', function () {\r\n messagecount = 0;\r\n messageseverity = 'MESSAGING_INFO';\r\n $('#msgcnt').text('');\r\n $('#syslogTable').html('');\r\n });\r\n $('#ok-credits').on('click', function () {\r\n $('#credits').slideUp('fast', function () { });\r\n $('#app').slideDown('fast', function () { });\r\n });\r\n $('#acredits').on('click', function (event) {\r\n event.preventDefault();\r\n $('#app').slideUp('fast', function () { });\r\n $('#credits').slideDown('fast', function () { });\r\n });\r\n $('input#show-commands').on('click', function () {\r\n const _this = this;\r\n _this.checked = _this.checked ? true : false;\r\n if (_this.checked) {\r\n $('a[href^=\"#tab-commands\"]').show();\r\n LastCommandsState = 1;\r\n }\r\n else {\r\n LastCommandsState = 0;\r\n $('a[href^=\"#tab-commands\"]').hide();\r\n }\r\n });\r\n $('#disable-squeezelite').on('click', function () {\r\n // this.checked = this.checked ? 1 : 0;\r\n // $('#disable-squeezelite').prop('checked')\r\n const _this = this;\r\n if (_this.checked) {\r\n // Store the current value before overwriting it\r\n const currentValue = $('#cmd_opt_s').val();\r\n $('#cmd_opt_s').data('originalValue', currentValue);\r\n // Overwrite the value with '-disable'\r\n $('#cmd_opt_s').val('-disable');\r\n }\r\n else {\r\n // Retrieve the original value\r\n const originalValue = $('#cmd_opt_s').data('originalValue');\r\n // Restore the original value if it exists, otherwise set it to an empty string\r\n $('#cmd_opt_s').val(originalValue ? originalValue : '');\r\n }\r\n });\r\n $('input#show-nvs').on('click', function () {\r\n const _this = this;\r\n _this.checked = _this.checked ? true : false;\r\n js_cookie_1.default.set(\"show-nvs\", _this.checked ? 'Y' : 'N');\r\n handleNVSVisible();\r\n });\r\n $('#btn_reboot_recovery').on('click', function () {\r\n handleReboot('recovery');\r\n });\r\n $('#btn_reboot').on('click', function () {\r\n handleReboot('reboot');\r\n });\r\n $('#btn_flash').on('click', function () {\r\n hFlash();\r\n });\r\n $('#save-autoexec1').on('click', function () {\r\n saveAutoexec1(false);\r\n });\r\n $('#commit-autoexec1').on('click', function () {\r\n saveAutoexec1(true);\r\n });\r\n $('#btn_disconnect').on('click', function () {\r\n ConnectedTo = resetNetworkConnection();\r\n refreshAPHTML2();\r\n $.ajax({\r\n url: '/connect.json',\r\n dataType: 'text',\r\n method: 'DELETE',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify({\r\n timestamp: Date.now(),\r\n }),\r\n });\r\n });\r\n $('#btnJoin').on('click', function () {\r\n handleConnect();\r\n });\r\n $('#reboot_nav').on('click', function () {\r\n handleReboot('reboot');\r\n });\r\n $('#reboot_ota_nav').on('click', function () {\r\n handleReboot('reboot_ota');\r\n });\r\n $('#save-as-nvs').on('click', function () {\r\n const config = getConfigJson(true);\r\n const a = document.createElement('a');\r\n a.href = URL.createObjectURL(new Blob([JSON.stringify(config, null, 2)], {\r\n type: 'text/plain',\r\n }));\r\n a.setAttribute('download', 'nvs_config_' + hostName + '_' + Date.now() + 'json');\r\n document.body.appendChild(a);\r\n a.click();\r\n document.body.removeChild(a);\r\n });\r\n $('#save-nvs').on('click', function () {\r\n post_config(getConfigJson(false));\r\n });\r\n $('#fwUpload').on('click', function () {\r\n const fileInput = document.getElementById('flashfilename').files;\r\n if (fileInput.length === 0) {\r\n alert('No file selected!');\r\n }\r\n else {\r\n $('#fw-url-input').value = null;\r\n flashState.StartOTA();\r\n }\r\n });\r\n $('[name=output-tmpl]').on('click', function () {\r\n const outputType = this.id;\r\n handleTemplateTypeRadio(outputType);\r\n });\r\n $('#chkUpdates').on('click', function () {\r\n $('#rTable').html('');\r\n $.getJSON(releaseURL, function (data) {\r\n let i = 0;\r\n const branches = [];\r\n data.forEach(function (release) {\r\n const namecomponents = release.name.split('#');\r\n const branch = namecomponents[3];\r\n if (!branches.includes(branch)) {\r\n branches.push(branch);\r\n }\r\n });\r\n let fwb = '';\r\n branches.forEach(function (branch) {\r\n fwb += '';\r\n });\r\n $('#fwbranch').append(fwb);\r\n data.forEach(function (release) {\r\n let url = '';\r\n release.assets.forEach(function (asset) {\r\n if (asset.name.match(/\\.bin$/)) {\r\n url = asset.browser_download_url;\r\n }\r\n });\r\n const namecomponents = release.name.split('#');\r\n const ver = namecomponents[0];\r\n const cfg = namecomponents[2];\r\n const branch = namecomponents[3];\r\n var bits = ver.substr(ver.lastIndexOf('-') + 1);\r\n bits = (bits == '32' || bits == '16') ? bits : '';\r\n let body = release.body;\r\n body = body.replace(/'/gi, '\"');\r\n body = body.replace(/[\\s\\S]+(### Revision Log[\\s\\S]+)### ESP-IDF Version Used[\\s\\S]+/, '$1');\r\n body = body.replace(/- \\(.+?\\) /g, '- ').encodeHTML();\r\n $('#rTable').append(`\r\n ${ver}${new Date(release.created_at).toLocalShort()}\r\n ${cfg}${branch}${bits}`);\r\n });\r\n if (i > 7) {\r\n $('#releaseTable').append(\"\" +\r\n \"\" +\r\n \"\" +\r\n '' +\r\n '');\r\n $('#showallbutton').on('click', function () {\r\n $('tr.hide').removeClass('hide');\r\n $('tr#showall').addClass('hide');\r\n });\r\n }\r\n $('#searchfw').css('display', 'inline');\r\n if (!setPlatformFilter(platform_name)) {\r\n setPlatformFilter(project_name);\r\n }\r\n $('#rTable tr.release').on('click', function () {\r\n var url = this.getAttribute('fwurl');\r\n if (lmsBaseUrl) {\r\n url = url.replace(/.*\\/download\\//, lmsBaseUrl + '/plugins/SqueezeESP32/firmware/');\r\n }\r\n $('#fw-url-input').val(url);\r\n $('#start-flash').show();\r\n $('#rTable tr.release').removeClass('table-success table-warning');\r\n $(this).addClass('table-success table-warning');\r\n });\r\n }).fail(function () {\r\n alert('failed to fetch release history!');\r\n });\r\n });\r\n $('#fwcheck').on('click', function () {\r\n $('#releaseTable').html('');\r\n $('#fwbranch').empty();\r\n $.getJSON(releaseURL, function (data) {\r\n let i = 0;\r\n const branches = [];\r\n data.forEach(function (release) {\r\n const namecomponents = release.name.split('#');\r\n const branch = namecomponents[3];\r\n if (!branches.includes(branch)) {\r\n branches.push(branch);\r\n }\r\n });\r\n let fwb;\r\n branches.forEach(function (branch) {\r\n fwb += ``;\r\n });\r\n $('#fwbranch').append(fwb);\r\n data.forEach(function (release) {\r\n let url = '';\r\n release.assets.forEach(function (asset) {\r\n if (asset.name.match(/\\.bin$/)) {\r\n url = asset.browser_download_url;\r\n }\r\n });\r\n const namecomponents = release.name.split('#');\r\n const ver = namecomponents[0];\r\n const idf = namecomponents[1];\r\n const cfg = namecomponents[2];\r\n const branch = namecomponents[3];\r\n let body = release.body;\r\n body = body.replace(/'/gi, '\"');\r\n body = body.replace(/[\\s\\S]+(### Revision Log[\\s\\S]+)### ESP-IDF Version Used[\\s\\S]+/, '$1');\r\n body = body.replace(/- \\(.+?\\) /g, '- ');\r\n const trclass = i++ > 6 ? ' hide' : '';\r\n $('#releaseTable').append(`${ver}${new Date(release.created_at).toLocalShort()}${cfg}${idf}${branch}`);\r\n });\r\n if (i > 7) {\r\n $('#releaseTable').append(``);\r\n $('#showallbutton').on('click', function () {\r\n $('tr.hide').removeClass('hide');\r\n $('tr#showall').addClass('hide');\r\n });\r\n }\r\n $('#searchfw').css('display', 'inline');\r\n }).fail(function () {\r\n alert('failed to fetch release history!');\r\n });\r\n });\r\n $('#updateAP').on('click', function () {\r\n refreshAP();\r\n console.log('refresh AP');\r\n });\r\n // first time the page loads: attempt to get the connection status and start the wifi scan\r\n getConfig();\r\n getCommands();\r\n getMessages();\r\n checkStatus();\r\n});\r\n// eslint-disable-next-line no-unused-vars\r\nwindow.setURL = function (button) {\r\n let url = button.dataset.url;\r\n $('[data-bs-url^=\"http\"]')\r\n .addClass('btn-success')\r\n .removeClass('btn-danger');\r\n $('[data-bs-url=\"' + url + '\"]')\r\n .addClass('btn-danger')\r\n .removeClass('btn-success');\r\n // if user can proxy download through LMS, modify the URL\r\n if (lmsBaseUrl) {\r\n url = url.replace(/.*\\/download\\//, lmsBaseUrl + '/plugins/SqueezeESP32/firmware/');\r\n }\r\n $('#fwurl').val(url);\r\n};\r\nfunction rssiToIcon(rssi) {\r\n if (rssi >= -55) {\r\n return { label: '****', icon: `signal_wifi_statusbar_4_bar` };\r\n }\r\n else if (rssi >= -60) {\r\n return { label: '***', icon: `network_wifi_3_bar` };\r\n }\r\n else if (rssi >= -65) {\r\n return { label: '**', icon: `network_wifi_2_bar` };\r\n }\r\n else if (rssi >= -70) {\r\n return { label: '*', icon: `network_wifi_1_bar` };\r\n }\r\n else {\r\n return { label: '.', icon: `signal_wifi_statusbar_null` };\r\n }\r\n}\r\nfunction refreshAP() {\r\n if ((ConnectedTo === null || ConnectedTo === void 0 ? void 0 : ConnectedTo.urc) === connectReturnCode.ETH)\r\n return;\r\n $.ajaxSetup({\r\n timeout: 3000 //Time in milliseconds\r\n });\r\n $.getJSON('/scan.json', function () {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n yield sleep(2000);\r\n $.getJSON('/ap.json', function (data) {\r\n if (data.length > 0) {\r\n // sort by signal strength\r\n data.sort(function (a, b) {\r\n const x = a.rssi;\r\n const y = b.rssi;\r\n // eslint-disable-next-line no-nested-ternary\r\n return x < y ? 1 : x > y ? -1 : 0;\r\n });\r\n apList = data;\r\n refreshAPHTML2(apList);\r\n }\r\n });\r\n });\r\n });\r\n}\r\nfunction formatAP(ssid, rssi, auth) {\r\n const rssi_icon = rssiToIcon(rssi);\r\n const auth_icon = { label: auth == 0 ? '🔓' : '🔒', icon: auth == 0 ? 'no_encryption' : 'lock' };\r\n return `${ssid}\r\n ${getIcon(rssi_icon)}\r\n \t\r\n ${getIcon(auth_icon)}\r\n `;\r\n}\r\nfunction refreshAPHTML2(data) {\r\n var _a;\r\n let h = '';\r\n $('#wifiTable tr td:first-of-type').text('');\r\n $('#wifiTable tr').removeClass('table-success table-warning');\r\n if (data) {\r\n data.forEach(function (e) {\r\n h += formatAP(e.ssid, e.rssi, e.auth);\r\n });\r\n $('#wifiTable').html(h);\r\n }\r\n if ($('.manual_add').length == 0) {\r\n $('#wifiTable').append(formatAP('Manual add', 0, 0));\r\n $('#wifiTable tr:last').addClass('table-light text-dark').addClass('manual_add');\r\n }\r\n if (ConnectedTo.ssid && (ConnectedTo.urc === connectReturnCode.OK || ConnectedTo.urc === connectReturnCode.RESTORE)) {\r\n const wifiSelector = `#wifiTable td:contains(\"${ConnectedTo.ssid}\")`;\r\n if ($(wifiSelector).filter(function () { return $(this).text() === ConnectedTo.ssid; }).length == 0) {\r\n $('#wifiTable').prepend(`${formatAP(ConnectedTo.ssid, (_a = ConnectedTo.rssi) !== null && _a !== void 0 ? _a : 0, 0)}`);\r\n }\r\n $(wifiSelector).filter(function () { return $(this).text() === ConnectedTo.ssid; }).siblings().first().html('✓').parent().addClass((ConnectedTo.urc === connectReturnCode.OK ? 'table-success' : 'table-warning'));\r\n $('span#foot-if').html(`SSID: ${ConnectedTo.ssid}, IP: ${ConnectedTo.ip}`);\r\n const rssiIconObj = rssiToIcon(ConnectedTo.rssi); // Assume this returns an object like { label: 'some_label', icon: 'some_icon_name' }\r\n const iconTextContent = getIcon(rssiIconObj); // Function to get the text content for the material icon\r\n // Set the icon text content\r\n $('#wifiStsIcon').text(iconTextContent);\r\n // Update the aria-label and custom icon attribute\r\n $('#wifiStsIcon').attr('aria-label', rssiIconObj.label);\r\n $('#wifiStsIcon').attr('icon', rssiIconObj.icon);\r\n }\r\n else if ((ConnectedTo === null || ConnectedTo === void 0 ? void 0 : ConnectedTo.urc) !== connectReturnCode.ETH) {\r\n $('span#foot-if').html('');\r\n }\r\n}\r\nfunction refreshETH() {\r\n if (ConnectedTo.urc === connectReturnCode.ETH) {\r\n $('span#foot-if').html(`Network: Ethernet, IP: ${ConnectedTo.ip}`);\r\n }\r\n}\r\nfunction showTask(task) {\r\n console.debug(`${this.toLocaleString()}\\t${task.nme}\\t${task.cpu}\\t${taskStates[task.st]}\\t${task.minstk}\\t${task.bprio}\\t${task.cprio}\\t${task.num}`);\r\n $('tbody#tasks').append(`${task.num}${task.nme}${task.cpu}${taskStates[task.st]}${task.minstk}${task.bprio}${task.cprio}`);\r\n}\r\nfunction btExists(name) {\r\n return getBTSinkOpt(name).length > 0;\r\n}\r\nfunction getBTSinkOpt(name) {\r\n return $(`${btSinkNamesOptSel} option:contains('${name}')`);\r\n}\r\nfunction getMessages() {\r\n $.ajaxSetup({\r\n timeout: messageInterval //Time in milliseconds\r\n });\r\n $.getJSON('/messages.json', function (data) {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n for (const msg of data) {\r\n const msgAge = msg.current_time - msg.sent_time;\r\n var msgTime = new Date();\r\n msgTime.setTime(msgTime.getTime() - msgAge);\r\n switch (msg.class) {\r\n case 'MESSAGING_CLASS_OTA':\r\n flashState.EventOTAMessageClass(msg.message);\r\n break;\r\n case 'MESSAGING_CLASS_STATS':\r\n // for task states, check structure : task_state_t\r\n var statsData = JSON.parse(msg.message);\r\n console.debug(msgTime.toLocalShort() +\r\n ' - Number of running tasks: ' +\r\n statsData.ntasks);\r\n console.debug(`${msgTime.toLocalShort()}\\tname\\tcpu\\tstate\\tminstk\\tbprio\\tcprio\\tnum`);\r\n if (statsData.tasks) {\r\n const taskList = statsData.tasks;\r\n if ($('#tasks_sect').css('visibility') === 'collapse') {\r\n $('#tasks_sect').css('visibility', 'visible');\r\n }\r\n $('tbody#tasks').html('');\r\n statsData.taskList\r\n .sort(function (a, b) {\r\n return b.cpu - a.cpu;\r\n })\r\n .forEach(showTask, msgTime);\r\n }\r\n else if ($('#tasks_sect').css('visibility') === 'visible') {\r\n $('tbody#tasks').empty();\r\n $('#tasks_sect').css('visibility', 'collapse');\r\n }\r\n break;\r\n case 'MESSAGING_CLASS_SYSTEM':\r\n showMessage(msg, msgTime);\r\n break;\r\n case 'MESSAGING_CLASS_CFGCMD':\r\n var msgparts = msg.message.split(/([^\\n]*)\\n(.*)/gs);\r\n showCmdMessage(msgparts[1], msg.type, msgparts[2], true);\r\n break;\r\n case 'MESSAGING_CLASS_BT':\r\n if ($(btSinkNamesOptSel).is('input')) {\r\n const sinkNameCtrl = $(btSinkNamesOptSel)[0];\r\n var attr = sinkNameCtrl.attributes;\r\n var attrs = '';\r\n for (var j = 0; j < attr.length; j++) {\r\n if (attr.item(j).name != \"type\") {\r\n attrs += `${attr.item(j).name} = \"${attr.item(j).value}\" `;\r\n }\r\n }\r\n var curOpt = sinkNameCtrl.value;\r\n $(btSinkNamesOptSel).replaceWith(` `);\r\n }\r\n JSON.parse(msg.message).forEach(function (btEntry) {\r\n // [{\\n\\t\\t\\\"name\\\":\\t\\\"SMSL BT4.2\\\",\\n\\t\\t\\\"rssi\\\":\\t-64\\n\\t}]\r\n //\r\n // \r\n if (!btExists(btEntry.name)) {\r\n $(btSinkNamesOptSel).append(``);\r\n showMessage({\r\n type: msg.type,\r\n message: `BT Audio device found: ${btEntry.name} RSSI: ${btEntry.rssi} `,\r\n class: '',\r\n sent_time: 0,\r\n current_time: 0\r\n }, msgTime);\r\n }\r\n getBTSinkOpt(btEntry.name).attr('data-bs-description', `${btEntry.name} (${btEntry.rssi}dB)`)\r\n .attr('rssi', btEntry.rssi)\r\n .attr('value', btEntry.name)\r\n .text(`${btEntry.name} [${btEntry.rssi}dB]`).trigger('change');\r\n });\r\n // Get the options as an array\r\n const btEntries = Array.from($(btSinkNamesOptSel).find('option'));\r\n // Sort the options based on the 'rssi' attribute\r\n btEntries.sort(function (a, b) {\r\n const rssiA = parseInt($(a).attr('rssi'), 10);\r\n const rssiB = parseInt($(b).attr('rssi'), 10);\r\n console.log(`${rssiA} < ${rssiB} ? `);\r\n return rssiB - rssiA; // Sort by descending RSSI values\r\n });\r\n // Clear the select element and append the sorted options\r\n $(btSinkNamesOptSel).empty().append(btEntries);\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n setTimeout(getMessages, messageInterval);\r\n });\r\n }).fail(function (xhr, ajaxOptions, thrownError) {\r\n if (xhr.status == 404) {\r\n $('.orec').hide(); // system commands won't be available either\r\n messagesHeld = true;\r\n }\r\n else {\r\n handleExceptionResponse(xhr, ajaxOptions, thrownError);\r\n }\r\n if (xhr.status == 0 && xhr.readyState == 0) {\r\n // probably a timeout. Target is rebooting? \r\n setTimeout(getMessages, messageInterval * 2); // increase duration if a failure happens\r\n }\r\n else if (!messagesHeld) {\r\n // 404 here means we rebooted to an old recovery\r\n setTimeout(getMessages, messageInterval); // increase duration if a failure happens\r\n }\r\n });\r\n /*\r\n Minstk is minimum stack space left\r\n Bprio is base priority\r\n cprio is current priority\r\n nme is name\r\n st is task state. I provided a \"typedef\" that you can use to convert to text\r\n cpu is cpu percent used\r\n */\r\n}\r\nfunction handleRecoveryMode(data) {\r\n var _a;\r\n const locRecovery = (_a = data.recovery) !== null && _a !== void 0 ? _a : 0;\r\n if (locRecovery === 1) {\r\n recovery = true;\r\n $('.recovery_element').show();\r\n $('.ota_element').hide();\r\n $('#boot-button').html('Reboot');\r\n $('#boot-form').attr('action', '/reboot_ota.json');\r\n }\r\n else {\r\n if (!recovery && messagesHeld) {\r\n messagesHeld = false;\r\n setTimeout(getMessages, messageInterval); // increase duration if a failure happens\r\n }\r\n recovery = false;\r\n $('.recovery_element').hide();\r\n $('.ota_element').show();\r\n $('#boot-button').html('Recovery');\r\n $('#boot-form').attr('action', '/recovery.json');\r\n }\r\n}\r\nfunction hasConnectionChanged(data) {\r\n // gw: \"192.168.10.1\"\r\n // ip: \"192.168.10.225\"\r\n // netmask: \"255.255.255.0\"\r\n // ssid: \"MyTestSSID\"\r\n return (data.urc !== ConnectedTo.urc ||\r\n data.ssid !== ConnectedTo.ssid ||\r\n data.gw !== ConnectedTo.gw ||\r\n data.netmask !== ConnectedTo.netmask ||\r\n data.ip !== ConnectedTo.ip || data.rssi !== ConnectedTo.rssi);\r\n}\r\nfunction handleWifiDialog(data) {\r\n if ($('#WifiConnectDialog').is(':visible')) {\r\n if (ConnectedTo.ip) {\r\n $('#ipAddress').text(ConnectedTo.ip);\r\n }\r\n if (ConnectedTo.ssid) {\r\n $('#connectedToSSID').text(ConnectedTo.ssid);\r\n }\r\n if (ConnectedTo.gw) {\r\n $('#gateway').text(ConnectedTo.gw);\r\n }\r\n if (ConnectedTo.netmask) {\r\n $('#netmask').text(ConnectedTo.netmask);\r\n }\r\n if (ConnectingToSSID.Action === undefined || (ConnectingToSSID.Action && ConnectingToSSID.Action == ConnectingToActions.STS)) {\r\n $(\"*[class*='connecting']\").hide();\r\n $('.connecting-status').show();\r\n }\r\n if (SystemConfig.ap_ssid) {\r\n $('#apName').text(SystemConfig.ap_ssid.value);\r\n }\r\n if (SystemConfig.ap_pwd) {\r\n $('#apPass').text(SystemConfig.ap_pwd.value);\r\n }\r\n if (!data) {\r\n return;\r\n }\r\n else {\r\n switch (data.urc) {\r\n case connectReturnCode.OK:\r\n if (data.ssid && data.ssid === ConnectingToSSID.ssid) {\r\n $(\"*[class*='connecting']\").hide();\r\n $('.connecting-success').show();\r\n ConnectingToSSID.Action = ConnectingToActions.STS;\r\n }\r\n break;\r\n case connectReturnCode.FAIL:\r\n // \r\n if (ConnectingToSSID.Action != ConnectingToActions.STS && ConnectingToSSID.ssid == data.ssid) {\r\n $(\"*[class*='connecting']\").hide();\r\n $('.connecting-fail').show();\r\n }\r\n break;\r\n case connectReturnCode.LOST:\r\n break;\r\n case connectReturnCode.RESTORE:\r\n if (ConnectingToSSID.Action != ConnectingToActions.STS && ConnectingToSSID.ssid != data.ssid) {\r\n $(\"*[class*='connecting']\").hide();\r\n $('.connecting-fail').show();\r\n }\r\n break;\r\n case connectReturnCode.DISC:\r\n // that's a manual disconnect\r\n // if ($('#wifi-status').is(':visible')) {\r\n // $('#wifi-status').slideUp('fast', function() {});\r\n // $('span#foot-wifi').html('');\r\n // } \r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n }\r\n}\r\nfunction setIcons(offline) {\r\n $('.material-icons').each(function (_index, entry) {\r\n const htmlEntry = entry;\r\n htmlEntry.textContent = htmlEntry.getAttribute(offline ? 'aria-label' : 'data-icon') || '';\r\n });\r\n}\r\nfunction assignStatusToNetworkConnection(data) {\r\n var _a;\r\n const connection = {\r\n urc: (_a = data.urc) !== null && _a !== void 0 ? _a : 0,\r\n auth: undefined,\r\n pwd: undefined,\r\n dhcpname: undefined,\r\n Action: undefined,\r\n ip: data.ip,\r\n ssid: data.ssid,\r\n rssi: data.rssi,\r\n gw: data.gw,\r\n netmask: data.netmask\r\n };\r\n return connection;\r\n}\r\nfunction handleNetworkStatus(data) {\r\n setIcons(!isConnected());\r\n if (hasConnectionChanged(data) || !data.urc) {\r\n ConnectedTo = assignStatusToNetworkConnection(data);\r\n $(\".if_eth\").hide();\r\n $('.if_wifi').hide();\r\n if (!data.urc || ConnectedTo.urc != connectReturnCode.ETH) {\r\n $('.if_wifi').show();\r\n refreshAPHTML2();\r\n }\r\n else {\r\n $(\".if_eth\").show();\r\n refreshETH();\r\n }\r\n }\r\n handleWifiDialog(data);\r\n}\r\nfunction batteryToIcon(voltage) {\r\n /* Assuming Li-ion 18650s as a power source, 3.9V per cell, or above is treated\r\n as full charge (>75% of capacity). 3.4V is empty. The gauge is loosely\r\n following the graph here:\r\n https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages\r\n using the 0.2C discharge profile for the rest of the values.\r\n */\r\n for (const iconEntry of batIcons) {\r\n for (const entryRanges of iconEntry.ranges) {\r\n if (inRange(voltage, entryRanges.f, entryRanges.t)) {\r\n return { label: iconEntry.label, icon: iconEntry.icon };\r\n }\r\n }\r\n }\r\n return { label: '▪▪▪▪', icon: \"battery_full\" };\r\n}\r\nfunction checkStatus() {\r\n $.ajaxSetup({\r\n timeout: statusInterval //Time in milliseconds\r\n });\r\n $.getJSON('/status.json', function (data) {\r\n var _a;\r\n handleRecoveryMode(data);\r\n handleNVSVisible();\r\n handleNetworkStatus(data);\r\n handlebtstate(data);\r\n flashState.EventTargetStatus(data);\r\n if (data.depth) {\r\n depth = data.depth;\r\n if (depth == 16) {\r\n $('#cmd_opt_R').show();\r\n }\r\n else {\r\n $('#cmd_opt_R').hide();\r\n }\r\n }\r\n if (data.project_name && data.project_name !== '') {\r\n project_name = data.project_name;\r\n }\r\n if (data.platform_name && data.platform_name !== '') {\r\n platform_name = data.platform_name;\r\n }\r\n if (board_model === '')\r\n board_model = project_name;\r\n if (board_model === '')\r\n board_model = 'Squeezelite-ESP32';\r\n if (data.version && data.version !== '') {\r\n versionName = data.version;\r\n $(\"#navtitle\").html(`${board_model}${recovery ? '
[recovery]' : ''}`);\r\n $('span#foot-fw').html(`fw: ${versionName}, mode: ${recovery ? \"Recovery\" : project_name}`);\r\n }\r\n else {\r\n $('span#flash-status').html('');\r\n }\r\n if (data.Voltage) {\r\n const bat_icon = batteryToIcon(data.Voltage);\r\n $('#battery').html(`${getIcon(bat_icon)}`);\r\n $('#battery').attr(\"aria-label\", bat_icon.label);\r\n $('#battery').attr(\"data-icon\", bat_icon.icon);\r\n $('#battery').show();\r\n }\r\n else {\r\n $('#battery').hide();\r\n }\r\n if (((_a = data.message) !== null && _a !== void 0 ? _a : '') != '' && prevmessage != data.message) {\r\n // supporting older recovery firmwares - messages will come from the status.json structure\r\n prevmessage = data.message;\r\n showLocalMessage(data.message, 'MESSAGING_INFO');\r\n }\r\n is_i2c_locked = data.is_i2c_locked;\r\n if (is_i2c_locked) {\r\n $('flds-cfg-hw-preset').hide();\r\n }\r\n else {\r\n $('flds-cfg-hw-preset').show();\r\n }\r\n $(\"button[onclick*='handleReboot']\").removeClass('rebooting');\r\n if (typeof lmsBaseUrl == \"undefined\" || data.lms_ip != prevLMSIP && data.lms_ip && data.lms_port) {\r\n const baseUrl = 'http://' + data.lms_ip + ':' + data.lms_port;\r\n prevLMSIP = data.lms_ip;\r\n $.ajax({\r\n url: baseUrl + '/plugins/SqueezeESP32/firmware/-check.bin',\r\n type: 'HEAD',\r\n dataType: 'text',\r\n cache: false,\r\n error: function () {\r\n // define the value, so we don't check it any more.\r\n lmsBaseUrl = '';\r\n },\r\n success: function () {\r\n lmsBaseUrl = baseUrl;\r\n }\r\n });\r\n }\r\n $('#o_jack').css({ display: Number(data.Jack) ? 'inline' : 'none' });\r\n setTimeout(checkStatus, statusInterval);\r\n }).fail(function (xhr, ajaxOptions, thrownError) {\r\n handleExceptionResponse(xhr, ajaxOptions, thrownError);\r\n if (xhr.status == 0 && xhr.readyState == 0) {\r\n // probably a timeout. Target is rebooting? \r\n setTimeout(checkStatus, messageInterval * 2); // increase duration if a failure happens\r\n }\r\n else {\r\n setTimeout(checkStatus, messageInterval); // increase duration if a failure happens\r\n }\r\n });\r\n}\r\n// eslint-disable-next-line no-unused-vars\r\nwindow.runCommand = function (button, reboot) {\r\n let cmdstring = button.getAttribute('cmdname');\r\n showCmdMessage(cmdstring, 'MESSAGING_INFO', 'Executing.', false);\r\n const fields = document.getElementById('flds-' + cmdstring);\r\n const allfields = fields === null || fields === void 0 ? void 0 : fields.querySelectorAll('select,input');\r\n if (cmdstring === 'cfg-hw-preset')\r\n return handleHWPreset(allfields, reboot);\r\n cmdstring += ' ';\r\n if (fields) {\r\n for (const field of allfields) {\r\n let qts = '';\r\n let opt = '';\r\n const isSelect = field.tagName === 'SELECT';\r\n const hasValue = field.getAttribute('hasvalue') === 'true';\r\n const validVal = (isSelect && field.value !== '--') || (!isSelect && field.value !== '');\r\n if (!hasValue || (hasValue && validVal)) {\r\n const longopts = field.getAttribute('longopts');\r\n const shortopts = field.getAttribute('shortopts');\r\n if (longopts !== null && longopts !== 'undefined') {\r\n opt += '--' + longopts;\r\n }\r\n else if (shortopts !== null && shortopts !== 'undefined') {\r\n opt = '-' + shortopts;\r\n }\r\n if (hasValue) {\r\n qts = /\\s/.test(field.value) ? '\"' : '';\r\n cmdstring += `${opt} ${qts}${field.value}${qts} `;\r\n }\r\n else {\r\n // this is a checkbox\r\n if (field.checked) {\r\n cmdstring += `${opt} `;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n console.log(cmdstring);\r\n const data = {\r\n timestamp: Date.now(),\r\n command: cmdstring\r\n };\r\n $.ajax({\r\n url: '/commands.json',\r\n dataType: 'text',\r\n method: 'POST',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify(data),\r\n error: function (xhr, _ajaxOptions, thrownError) {\r\n var cmd = JSON.parse(this.data).command;\r\n if (xhr.status == 404) {\r\n showCmdMessage(cmd.substr(0, cmd.indexOf(' ')), 'MESSAGING_ERROR', `${recovery ? 'Limited recovery mode active. Unsupported action ' : 'Unexpected error while processing command'}`, true);\r\n }\r\n else {\r\n handleExceptionResponse(xhr, _ajaxOptions, thrownError);\r\n showCmdMessage(cmd.substr(0, cmd.indexOf(' ') - 1), 'MESSAGING_ERROR', `Unexpected error ${(thrownError !== '') ? thrownError : 'with return status = ' + xhr.status}`, true);\r\n }\r\n },\r\n success: function (response) {\r\n $('.orec').show();\r\n console.log(response);\r\n if (JSON.parse(response).Result === 'Success' &&\r\n reboot) {\r\n delayReboot(2500, button.getAttribute('cmdname'));\r\n }\r\n },\r\n });\r\n};\r\nfunction getLongOps(data, name, longopts) {\r\n return data[name] !== undefined ? data[name][longopts] : \"\";\r\n}\r\nfunction getCommands() {\r\n $.ajaxSetup({\r\n timeout: 7000 //Time in milliseconds\r\n });\r\n $.getJSON('/commands.json', function (data) {\r\n console.log(data);\r\n $('.orec').show();\r\n data.commands.forEach(function (command) {\r\n if ($('#flds-' + command.name).length === 0) {\r\n const cmdParts = command.name.split('-');\r\n const isConfig = cmdParts[0] === 'cfg';\r\n const targetDiv = '#tab-' + cmdParts[0] + '-' + cmdParts[1];\r\n let innerhtml = '';\r\n innerhtml += `
${command.help.encodeHTML().replace(/\\n/g, '
')}
`;\r\n if (command.argtable) {\r\n command.argtable.forEach(function (arg) {\r\n let placeholder = arg.datatype || '';\r\n const ctrlname = command.name + '-' + arg.longopts;\r\n const curvalue = getLongOps(data.values, command.name, arg.longopts);\r\n let attributes = `hasvalue=${arg.hasvalue} `;\r\n attributes += 'longopts=\"' + arg.longopts + '\" ';\r\n attributes += 'shortopts=\"' + arg.shortopts + '\" ';\r\n attributes += 'checkbox=' + arg.checkbox + ' ';\r\n attributes += 'cmdname=\"' + command.name + '\" ';\r\n attributes +=\r\n `id=\"${ctrlname}\" name=\"${ctrlname}\" hasvalue=\"${arg.hasvalue}\" `;\r\n let extraclass = arg.mincount > 0 ? 'bg-success' : '';\r\n if (arg.glossary === 'hidden') {\r\n attributes += ' style=\"visibility: hidden;\"';\r\n }\r\n if (arg.checkbox) {\r\n innerhtml += `
`;\r\n }\r\n else {\r\n innerhtml += `
`;\r\n if (placeholder.includes('|')) {\r\n extraclass = placeholder.startsWith('+') ? ' multiple ' : '';\r\n placeholder = placeholder\r\n .replace('<', '')\r\n .replace('=', '')\r\n .replace('>', '');\r\n innerhtml += `';\r\n }\r\n else {\r\n innerhtml += ``;\r\n }\r\n }\r\n innerhtml += `${arg.checkbox ? '
' : ''}Previous value: ${arg.checkbox ? (curvalue ? 'Checked' : 'Unchecked') : (curvalue || '')}${arg.checkbox ? '' : '
'}`;\r\n });\r\n }\r\n innerhtml += `
\r\n
\r\n
\r\n Result\r\n
\r\n
\r\n
`;\r\n if (isConfig) {\r\n innerhtml +=\r\n `\r\n`;\r\n }\r\n else {\r\n innerhtml += ``;\r\n }\r\n innerhtml += '
';\r\n if (isConfig) {\r\n $(targetDiv).append(innerhtml);\r\n }\r\n else {\r\n $('#commands-list').append(innerhtml);\r\n }\r\n }\r\n });\r\n $(\".sclk\").off('click').on('click', function () { window.runCommand(this, false); });\r\n $(\".cclk\").off('click').on('click', function () { window.runCommand(this, true); });\r\n data.commands.forEach(function (command) {\r\n $('[cmdname=' + command.name + ']:input').val('');\r\n $('[cmdname=' + command.name + ']:checkbox').prop('checked', false);\r\n if (command.argtable) {\r\n command.argtable.forEach(function (arg) {\r\n const ctrlselector = '#' + command.name + '-' + arg.longopts;\r\n if (arg.checkbox) {\r\n $(ctrlselector)[0].checked = getLongOps(data, command.name, arg.longopts);\r\n }\r\n else {\r\n let ctrlValue = getLongOps(data, command.name, arg.longopts);\r\n if (ctrlValue !== undefined) {\r\n $(ctrlselector)\r\n .val(ctrlValue.toString())\r\n .trigger('change');\r\n }\r\n if ($(ctrlselector)[0].value.length === 0 &&\r\n (arg.datatype || '').includes('|')) {\r\n $(ctrlselector)[0].value = '--';\r\n }\r\n }\r\n });\r\n }\r\n });\r\n loadPresets();\r\n }).fail(function (xhr, ajaxOptions, thrownError) {\r\n if (xhr.status == 404) {\r\n $('.orec').hide();\r\n }\r\n else {\r\n handleExceptionResponse(xhr, ajaxOptions, thrownError);\r\n }\r\n $('#commands-list').empty();\r\n });\r\n}\r\nfunction getConfig() {\r\n $.ajaxSetup({\r\n timeout: 7000 //Time in milliseconds\r\n });\r\n $.getJSON('/config.json', function (entries) {\r\n $('#nvsTable tr').remove();\r\n const data = (entries.config ? entries.config : entries);\r\n SystemConfig = data;\r\n commandBTSinkName = '';\r\n Object.keys(data)\r\n .sort()\r\n .forEach(function (key) {\r\n let val = data[key].value;\r\n if (key === 'autoexec1') {\r\n /* call new function to parse the squeezelite options */\r\n processSqueezeliteCommandLine(val);\r\n }\r\n else if (key === 'host_name') {\r\n val = val.replaceAll('\"', '');\r\n $('input#dhcp-name1').val(val);\r\n $('input#dhcp-name2').val(val);\r\n if ($('#cmd_opt_n').length == 0) {\r\n $('#cmd_opt_n').val(val);\r\n }\r\n document.title = val;\r\n hostName = val;\r\n }\r\n else if (key === 'rel_api') {\r\n releaseURL = val;\r\n }\r\n else if (key === 'enable_airplay') {\r\n $(\"#s_airplay\").css({ display: isEnabled(val) ? 'inline' : 'none' });\r\n }\r\n else if (key === 'enable_cspot') {\r\n $(\"#s_cspot\").css({ display: isEnabled(val) ? 'inline' : 'none' });\r\n }\r\n else if (key == 'preset_name') {\r\n preset_name = val;\r\n }\r\n else if (key == 'board_model') {\r\n board_model = val;\r\n }\r\n $('tbody#nvsTable').append(`${key}`);\r\n $('input#' + key).val(data[key].value);\r\n });\r\n if (commandBTSinkName.length > 0) {\r\n // persist the sink name found in the autoexec1 command line\r\n $('#cfg-audio-bt_source-sink_name').val(commandBTSinkName);\r\n }\r\n $('tbody#nvsTable').append(\"\");\r\n if (entries.gpio) {\r\n $('#pins').show();\r\n $('tbody#gpiotable tr').remove();\r\n entries.gpio.forEach(function (gpioEntry) {\r\n $('tbody#gpiotable').append(`${gpioEntry.group}${gpioEntry.name}${gpioEntry.gpio}${gpioEntry.fixed ? 'Fixed' : 'Configuration'}`);\r\n });\r\n }\r\n else {\r\n $('#pins').hide();\r\n }\r\n }).fail(function (xhr, ajaxOptions, thrownError) {\r\n handleExceptionResponse(xhr, ajaxOptions, thrownError);\r\n });\r\n}\r\nfunction processSqueezeliteCommandLine(val) {\r\n const parsed = parseSqueezeliteCommandLine(val);\r\n if (parsed.output.toUpperCase().startsWith('I2S')) {\r\n handleTemplateTypeRadio('i2s');\r\n }\r\n else if (parsed.output.toUpperCase().startsWith('SPDIF')) {\r\n handleTemplateTypeRadio('spdif');\r\n }\r\n else if (parsed.output.toUpperCase().startsWith('BT')) {\r\n if (parsed.otherOptions.btname) {\r\n commandBTSinkName = parsed.otherOptions.btname;\r\n }\r\n handleTemplateTypeRadio('bt');\r\n }\r\n Object.keys(parsed.options).forEach(function (key) {\r\n const option = parsed.options[key];\r\n if (!$(`#cmd_opt_${key}`).hasOwnProperty('checked')) {\r\n $(`#cmd_opt_${key}`).val(option);\r\n }\r\n else {\r\n if (typeof option === 'boolean') {\r\n $(`#cmd_opt_${key}`)[0].checked = option;\r\n }\r\n }\r\n });\r\n if (parsed.options.hasOwnProperty('u')) {\r\n // parse -u v[:i] and check the appropriate radio button with id #resample_v\r\n const [resampleValue, resampleInterpolation] = parsed.options.u.split(':');\r\n $(`#resample_${resampleValue}`).prop('checked', true);\r\n // if resampleinterpolation is set, check resample_i checkbox\r\n if (resampleInterpolation) {\r\n $('#resample_i').prop('checked', true);\r\n }\r\n }\r\n if (parsed.options.hasOwnProperty('s')) {\r\n // parse -u v[:i] and check the appropriate radio button with id #resample_v\r\n if (parsed.options.s === '-disable') {\r\n $('#disable-squeezelite')[0].checked = true;\r\n }\r\n else {\r\n $('#disable-squeezelite')[0].checked = false;\r\n }\r\n }\r\n}\r\nfunction showLocalMessage(message, severity) {\r\n const msg = {\r\n message: message,\r\n type: severity,\r\n class: '',\r\n sent_time: 0,\r\n current_time: 0\r\n };\r\n showMessage(msg, new Date());\r\n}\r\nfunction showMessage(msg, msgTime) {\r\n let color = 'table-success';\r\n if (msg.type === 'MESSAGING_WARNING') {\r\n color = 'table-warning';\r\n if (messageseverity === 'MESSAGING_INFO') {\r\n messageseverity = 'MESSAGING_WARNING';\r\n }\r\n }\r\n else if (msg.type === 'MESSAGING_ERROR') {\r\n if (messageseverity === 'MESSAGING_INFO' ||\r\n messageseverity === 'MESSAGING_WARNING') {\r\n messageseverity = 'MESSAGING_ERROR';\r\n }\r\n color = 'table-danger';\r\n }\r\n if (++messagecount > 0) {\r\n $('#msgcnt').removeClass('badge-success');\r\n $('#msgcnt').removeClass('badge-warning');\r\n $('#msgcnt').removeClass('badge-danger');\r\n $('#msgcnt').addClass({\r\n MESSAGING_INFO: 'badge-success',\r\n MESSAGING_WARNING: 'badge-warning',\r\n MESSAGING_ERROR: 'badge-danger',\r\n }[messageseverity]);\r\n $('#msgcnt').text(messagecount);\r\n }\r\n $('#syslogTable').append(\"\" +\r\n '' +\r\n msgTime.toLocalShort() +\r\n '' +\r\n '' +\r\n msg.message.encodeHTML() +\r\n '' +\r\n '');\r\n}\r\nfunction inRange(x, min, max) {\r\n return (x - min) * (x - max) <= 0;\r\n}\r\nfunction sleep(ms) {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n}\r\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = (module) => {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t826: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunksqueezelite_esp32\"] = self[\"webpackChunksqueezelite_esp32\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [987], () => (__webpack_require__(607)))\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","jspb","require","goog","global","this","window","self","Function","call","nanopb_pb","object","extend","proto","exportSymbol","Conf","GPIO","opt_data","Message","initialize","inherits","DEBUG","COMPILED","displayName","I2CBus","DACDev","SPDIFDev","DispOffsets","DispCommon","I2CDisplay","SPIDisplay","SPIBus","DisplayDev","oneofGroups_","GPIOExp","WS2812","LEDStrip","Rotary","ButtonActions","Button","EthCommon","EthSPI","EthRMII","Eth","Battery","Gpios","Dev","repeatedFields_","SleepService","Artwork","Metadata","Services","Config","GENERATE_TO_OBJECT","prototype","toObject","opt_includeInstance","includeInstance","msg","obj","pin","getFieldWithDefault","level","$jspbMessageInstance","deserializeBinary","bytes","reader","BinaryReader","deserializeBinaryFromReader","nextField","isEndGroup","getFieldNumber","value","readInt32","setPin","setLevel","skipField","serializeBinary","writer","BinaryWriter","serializeBinaryToWriter","getResultBuffer","message","f","undefined","getPin","writeInt32","getField","setProto3IntField","getLevel","setField","clearLevel","hasLevel","port","speed","sda","getSda","scl","getScl","readEnum","setPort","setSpeed","readMessage","setSda","setScl","getPort","writeEnum","getSpeed","writeMessage","setProto3EnumField","getWrapperField","setWrapperField","clearSda","hasSda","clearScl","hasScl","bck","getBck","ws","getWs","dout","getDout","mck","mute","getMute","model","i2c","getI2c","setBck","setWs","setDout","setMck","setMute","setModel","setI2c","getMck","getModel","clearBck","hasBck","clearWs","hasWs","clearDout","hasDout","clearMute","hasMute","clearI2c","hasI2c","dc","getDc","data","getData","clk","getClk","setDc","setData","setClk","clearDc","hasDc","clearData","hasData","clearClk","hasClk","height","width","setHeight","setWidth","getHeight","getWidth","hflip","getBooleanFieldWithDefault","vflip","driver","bitdepth","back","getBack","reset","getReset","ready","getReady","offsets","getOffsets","readBool","setHflip","setVflip","setDriver","setBitdepth","setBack","setReset","setReady","setOffsets","getHflip","writeBool","getVflip","getDriver","getBitdepth","setProto3BooleanField","clearBack","hasBack","clearReset","hasReset","clearReady","hasReady","clearOffsets","hasOffsets","address","setAddress","getAddress","cs","getCs","rotate","setCs","setRotate","getRotate","clearCs","hasCs","mosi","getMosi","miso","getMiso","host","setMosi","setMiso","setHost","getHost","clearMosi","hasMosi","clearMiso","hasMiso","DisptypeCase","DISPTYPE_NOT_SET","I2C","SPI","getDisptypeCase","computeOneofCase","type","common","getCommon","spi","getSpi","setType","setCommon","setSpi","getType","clearCommon","hasCommon","setOneofWrapperField","clearSpi","hasSpi","addr","base","count","intr","getIntr","setAddr","setBase","setCount","setIntr","getAddr","getBase","getCount","clearIntr","hasIntr","length","gpio","getGpio","setLength","setGpio","getLength","clearGpio","hasGpio","ws2812","getWs2812","setWs2812","clearWs2812","hasWs2812","a","getA","b","getB","sw","getSw","knobonly","volume","longpress","setA","setB","setSw","setKnobonly","setVolume","setLongpress","getKnobonly","getVolume","getLongpress","clearA","hasA","clearB","hasB","clearSw","hasSw","pressed","released","setPressed","setReleased","getPressed","getReleased","pull","debounce","shifter","getShifter","longduration","normal","getNormal","shifted","getShifted","longshifted","getLongshifted","setPull","setDebounce","setShifter","setLongduration","setNormal","setShifted","setLongshifted","getPull","getDebounce","getLongduration","clearShifter","hasShifter","clearNormal","hasNormal","clearLongpress","hasLongpress","clearShifted","hasShifted","clearLongshifted","hasLongshifted","rst","getRst","setRst","clearRst","hasRst","mdc","getMdc","mdio","getMdio","setMdc","setMdio","clearMdc","hasMdc","clearMdio","hasMdio","EthtypeCase","ETHTYPE_NOT_SET","RMII","getEthtypeCase","rmii","getRmii","setRmii","clearRmii","hasRmii","channel","scale","getFloatingPointFieldWithDefault","cells","atten","setChannel","readFloat","setScale","setCells","setAtten","getChannel","getScale","writeFloat","getCells","getAtten","setProto3FloatField","greenled","getGreenled","redled","getRedled","audiojack","getAudiojack","amp","getAmp","power","getPower","ir","getIr","jack","getJack","spkfault","getSpkfault","vcc","getVcc","gnd","getGnd","setGreenled","setRedled","setAudiojack","setAmp","setPower","setIr","setJack","setSpkfault","setVcc","setGnd","clearGreenled","hasGreenled","clearRedled","hasRedled","clearAudiojack","hasAudiojack","clearAmp","hasAmp","clearPower","hasPower","clearIr","hasIr","clearJack","hasJack","clearSpkfault","hasSpkfault","clearVcc","hasVcc","clearGnd","hasGnd","dac","getDac","spdif","getSpdif","display","getDisplay","gpioExp","getGpioExp","ledStrip","getLedStrip","rotary","getRotary","buttonsList","toObjectList","getButtonsList","eth","getEth","battery","getBattery","setDac","setSpdif","setDisplay","setGpioExp","setLedStrip","setRotary","addButtons","setEth","setBattery","writeRepeatedMessage","clearDac","hasDac","clearSpdif","hasSpdif","clearDisplay","hasDisplay","clearGpioExp","hasGpioExp","clearLedStrip","hasLedStrip","clearRotary","hasRotary","getRepeatedWrapperField","setButtonsList","setRepeatedWrapperField","opt_value","opt_index","addToRepeatedWrapperField","clearButtonsList","clearEth","hasEth","clearBattery","hasBattery","delay","spurious","sleep","getSleep","wakeList","getWakeList","rtcList","getRtcList","batt","readUint32","setDelay","setSpurious","setSleep","addWake","addRtc","setBatt","getDelay","writeUint32","getSpurious","getBatt","clearSleep","hasSleep","setWakeList","clearWakeList","setRtcList","clearRtcList","enabled","resize","setEnabled","setResize","getEnabled","getResize","format","pause","artwork","getArtwork","readString","setFormat","setPause","setArtwork","getFormat","writeString","getPause","setProto3StringField","clearArtwork","hasArtwork","metadata","getMetadata","setMetadata","clearMetadata","hasMetadata","gpios","getGpios","dev","getDev","services","getServices","deviceName","setGpios","setDev","setServices","setDeviceName","getDeviceName","clearGpios","hasGpios","clearDev","hasDev","clearServices","hasServices","ButtonAction","ACTRLS_NONE","ACTRLS_POWER","ACTRLS_VOLUP","ACTRLS_VOLDOWN","ACTRLS_TOGGLE","ACTRLS_PLAY","ACTRLS_PAUSE","ACTRLS_STOP","ACTRLS_REW","ACTRLS_FWD","ACTRLS_PREV","ACTRLS_NEXT","BCTRLS_UP","BCTRLS_DOWN","BCTRLS_LEFT","BCTRLS_RIGHT","BCTRLS_PS1","BCTRLS_PS2","BCTRLS_PS3","BCTRLS_PS4","BCTRLS_PS5","BCTRLS_PS6","BCTRLS_PS7","BCTRLS_PS8","BCTRLS_PS9","BCTRLS_PS10","KNOB_LEFT","KNOB_RIGHT","KNOB_PUSH","ACTRLS_SLEEP","DACModelEnum","UNSPECIFIED_MODEL","TAS57XX","TAS5713","AC101","WM8978","ES8388","I2S","DeviceTypeEnum","UNSPECIFIED_TYPE","DEVTYPE_SPI","DEVTYPE_I2C","DEVTYPE__RMII","DisplayDriverEnum","UNSPECIFIED_DRIVER","SSD1306","SSD1322","SSD1326","SSD1327","SH1106","SSD1675","ST7735","ST7789","ILI9341","ILI9341_24","SSD1351","PortEnum","UNSPECIFIED_SYSTPORT","SYSTEM","DAC","EthModelEnum","UNSPECIFIED_ETHMODEL","LAN8720","DM9051","W5500","GPIOExpModelEnum","UNSPECIFIED_EXP","PCA9535","PCA85XX","MCP23017","MCP23S17","HostEnum","UNSPECIFIED_HOST","HOST0","HOST1","I2CPortEnum","UNSPECIFIED_PORT","I2CPORT0","I2CPORT1","MCKEnum","UNSPECIFIED_MCK","MCK0","MCK1","MCK2","BatteryChannelEnum","UNSPECIFIED_CH","CH0","CH1","CH2","CH3","CH4","CH5","CH6","CH7","BatteryAttenEnum","UNSPECIFIED_ATT","ATT_0","ATT_1","ATT_2","ATT_3","EthType","UNSPECIFIED_ETH","exports","google_protobuf_descriptor_pb","NanoPBOptions","maxSize","maxLength","maxCount","intSize","longNames","packedStruct","packedEnum","skipMessage","noUnions","msgid","anonymousOneof","proto3","proto3SingularMsgs","enumToString","fixedLength","fixedCount","submsgCallback","mangleNames","callbackDatatype","callbackFunction","descriptorsize","defaultHas","includeList","getRepeatedField","excludeList","pb_package","typeOverride","sortByTag","setMaxSize","setMaxLength","setMaxCount","setIntSize","setLongNames","setPackedStruct","setPackedEnum","setSkipMessage","setNoUnions","setMsgid","setAnonymousOneof","setProto3","setProto3SingularMsgs","setEnumToString","setFixedLength","setFixedCount","setSubmsgCallback","setMangleNames","setCallbackDatatype","setCallbackFunction","setDescriptorsize","setDefaultHas","addInclude","addExclude","setPackage","setTypeOverride","setSortByTag","getIncludeList","writeRepeatedString","getExcludeList","getMaxSize","clearMaxSize","hasMaxSize","getMaxLength","clearMaxLength","hasMaxLength","getMaxCount","clearMaxCount","hasMaxCount","getIntSize","clearIntSize","hasIntSize","clearType","hasType","getLongNames","clearLongNames","hasLongNames","getPackedStruct","clearPackedStruct","hasPackedStruct","getPackedEnum","clearPackedEnum","hasPackedEnum","getSkipMessage","clearSkipMessage","hasSkipMessage","getNoUnions","clearNoUnions","hasNoUnions","getMsgid","clearMsgid","hasMsgid","getAnonymousOneof","clearAnonymousOneof","hasAnonymousOneof","getProto3","clearProto3","hasProto3","getProto3SingularMsgs","clearProto3SingularMsgs","hasProto3SingularMsgs","getEnumToString","clearEnumToString","hasEnumToString","getFixedLength","clearFixedLength","hasFixedLength","getFixedCount","clearFixedCount","hasFixedCount","getSubmsgCallback","clearSubmsgCallback","hasSubmsgCallback","getMangleNames","clearMangleNames","hasMangleNames","getCallbackDatatype","clearCallbackDatatype","hasCallbackDatatype","getCallbackFunction","clearCallbackFunction","hasCallbackFunction","getDescriptorsize","clearDescriptorsize","hasDescriptorsize","getDefaultHas","clearDefaultHas","hasDefaultHas","setIncludeList","addToRepeatedField","clearIncludeList","setExcludeList","clearExcludeList","getPackage","clearPackage","hasPackage","getTypeOverride","clearTypeOverride","hasTypeOverride","getSortByTag","clearSortByTag","hasSortByTag","FieldType","FT_DEFAULT","FT_CALLBACK","FT_POINTER","FT_STATIC","FT_IGNORE","FT_INLINE","IntSize","IS_DEFAULT","IS_8","IS_16","IS_32","IS_64","TypenameMangling","M_NONE","M_STRIP_PACKAGE","M_FLATTEN","M_PACKAGE_INITIALS","DescriptorSize","DS_AUTO","DS_1","DS_2","DS_4","DS_8","nanopbFileopt","ExtensionFieldInfo","FileOptions","extensionsBinary","ExtensionFieldBinaryInfo","extensions","nanopbMsgopt","MessageOptions","nanopbEnumopt","EnumOptions","nanopb","FieldOptions","__createBinding","Object","create","o","m","k","k2","desc","getOwnPropertyDescriptor","__esModule","writable","configurable","enumerable","get","defineProperty","__setModuleDefault","v","__importStar","mod","result","hasOwnProperty","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","next","e","rejected","done","then","apply","__importDefault","he","js_cookie_1","c","bootstrap","hFlash","$","val","flashState","StartOTA","handleReboot","link","removeClass","prop","delayReboot","get_control_option_value","ctrl","id","opt","attr","replace","includes","toString","handleNVSVisible","nvs_previous_checked","isEnabled","default","checkBoxElement","checked","recovery","show","hide","match","NVSType","console","log","hideSurrounding","parent","assign","String","args","number","index","parseInt","encodeHTML","encode","Date","toLocalShort","toLocaleString","dateStyle","timeStyle","btIcons","bt_playing","label","icon","bt_disconnected","bt_neutral","bt_connecting","bt_connected","bt_disabled","play_arrow","stop","batIcons","ranges","t","btStateIcons","sub","connectReturnCode","OK","FAIL","DISC","LOST","RESTORE","ETH","taskStates","NONE","REBOOT_TO_RECOVERY","SET_FWURL","FLASHING","DONE","UPLOADING","ERROR","UPLOADCOMPLETE","_state","olderRecovery","statusText","flashURL","flashFileName","statusPercent","Completed","prevRecovery","updateModal","Modal","document","getElementById","UpdateProgress","isStateError","html","isStateUploadComplete","isStateNone","isStateRebootRecovery","isStateSetUrl","isStateFlashing","isStateDone","isStateUploading","init","SetStateError","addClass","SetStateNone","SetStateRebootRecovery","SetStatusText","ajax","url","context","dataType","method","cache","contentType","JSON","stringify","timestamp","now","error","xhr","_ajaxOptions","thrownError","_a","setOTAError","status","complete","response","SetStateSetUrl","post_config","fwurl","SetStateFlashing","SetStateDone","SetStateUploading","SetStateUploadComplete","isFlashExecuting","keys","find","x","setOTATargets","fileInput","files","SetStatusPercent","ShowDialog","pct","pctChanged","txt","changed","css","text","logEvent","name","TargetReadyStartOTA","UploadLocalFile","xhttp","XMLHttpRequest","boundHandleUploadProgressEvent","HandleUploadProgressEvent","bind","boundsetOTAError","upload","addEventListener","onreadystatechange","readyState","open","send","Math","round","loaded","total","EventTargetStatus","_b","ota_pct","ota_dsc","EventOTAMessageClass","otaData","parse","fun","presetsloaded","is_i2c_locked","messageInterval","confPayload","config","handleExceptionResponse","parseSqueezeliteCommandLine","commandLine","options","output","otherValues","i","arg","startsWith","option","slice","join","trim","indexOf","substring","getOutput","n","getName","otherOptions","btname","toUpperCase","temp","isConnected","ConnectedTo","ip","getIcon","icons","handleTemplateTypeRadio","outtype","children","entries","commandDefaults","forEach","key","showLocalMessage","showCmdMessage","cmdname","msgtype","msgtext","append","color","escapedtext","releaseURL","messagesHeld","commandBTSinkName","i2s","C","W","Z","bt","SystemConfig","validOptions","codecs","apList","messagecount","messageseverity","LastCommandsState","NaN","ConnectingToSSID","hostName","versionName","prevmessage","project_name","depth","board_model","platform_name","preset_name","btSinkNamesOptSel","lmsBaseUrl","prevLMSIP","ConnectingToActions","promise","duration","setTimeout","reason","getConfigJson","slimMode","each","_index","element","entry","nvsTypeAttr","attributes","getNamedItem","nvsType","NVS_TYPE_I64","NVS_TYPE_I8","ota","empty","rdata","saveAutoexec1","resample","is","autoexec1","NVS_TYPE_STR","responseText","Result","setPlatformFilter","filter","trigger","renderError","fieldname","errorFieldName","errorField","field","after","rssiToIcon","rssi","refreshAP","urc","ajaxSetup","timeout","getJSON","ms","sort","y","refreshAPHTML2","formatAP","ssid","auth","rssi_icon","auth_icon","h","wifiSelector","prepend","siblings","first","rssiIconObj","iconTextContent","showTask","task","debug","nme","cpu","st","minstk","bprio","cprio","num","getBTSinkOpt","getMessages","msgAge","current_time","sent_time","msgTime","setTime","getTime","class","statsData","ntasks","tasks","taskList","showMessage","msgparts","split","sinkNameCtrl","attrs","j","item","curOpt","replaceWith","btEntry","btEntries","Array","from","rssiA","rssiB","fail","ajaxOptions","handleWifiDialog","gw","netmask","Action","STS","ap_ssid","ap_pwd","setIcons","offline","htmlEntry","textContent","getAttribute","handleNetworkStatus","hasConnectionChanged","pwd","dhcpname","assignStatusToNetworkConnection","checkStatus","handleRecoveryMode","tt","bt_status","bt_sub_status","iconIndex","handlebtstate","version","Voltage","bat_icon","voltage","iconEntry","entryRanges","min","max","batteryToIcon","lms_ip","lms_port","baseUrl","success","Number","Jack","getLongOps","longopts","severity","MESSAGING_INFO","MESSAGING_WARNING","MESSAGING_ERROR","setAttribute","on","stringVal","inputField","not","invalid","map","test","event","relatedTarget","CONN","MAN","_this","FileReader","file","fr","onload","target","ex","alert","readAsText","slideUp","slideDown","preventDefault","currentValue","originalValue","set","createElement","href","URL","createObjectURL","Blob","body","appendChild","click","removeChild","branches","release","branch","push","fwb","assets","asset","browser_download_url","namecomponents","ver","cfg","bits","substr","lastIndexOf","created_at","idf","trclass","remove","parsed","resampleValue","resampleInterpolation","u","s","processSqueezeliteCommandLine","replaceAll","title","gpioEntry","fixed","group","commands","command","cmdParts","isConfig","targetDiv","innerhtml","help","argtable","placeholder","datatype","ctrlname","curvalue","values","hasvalue","shortopts","checkbox","extraclass","mincount","glossary","choice","off","runCommand","ctrlselector","ctrlValue","_","jqxhr","textStatus","err","setURL","button","dataset","reboot","cmdstring","fields","allfields","querySelectorAll","selJson","cmd","model_config","storedval","handleHWPreset","qts","isSelect","tagName","hasValue","validVal","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","module","__webpack_modules__","O","chunkIds","fn","priority","notFulfilled","Infinity","every","splice","r","d","definition","g","globalThis","Symbol","toStringTag","nmd","paths","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file diff --git a/components/wifi-manager/webapp/dist/js/node_vendors.1b8c7b.bundle.js b/components/wifi-manager/webapp/dist/js/node_vendors.1b8c7b.bundle.js deleted file mode 100644 index 393a499b..00000000 --- a/components/wifi-manager/webapp/dist/js/node_vendors.1b8c7b.bundle.js +++ /dev/null @@ -1,2 +0,0 @@ -(self.webpackChunksqueezelite_esp32=self.webpackChunksqueezelite_esp32||[]).push([[987],{138:(e,t,r)=>{"use strict";r.r(t),r.d(t,{Alert:()=>Ct,Button:()=>St,Carousel:()=>lr,Collapse:()=>xr,Dropdown:()=>Wr,Modal:()=>kn,Offcanvas:()=>Wn,Popover:()=>gi,ScrollSpy:()=>Ti,Tab:()=>Xi,Toast:()=>uo,Tooltip:()=>di});var n={};r.r(n),r.d(n,{afterMain:()=>E,afterRead:()=>w,afterWrite:()=>T,applyStyles:()=>O,arrow:()=>Z,auto:()=>l,basePlacements:()=>c,beforeMain:()=>_,beforeRead:()=>b,beforeWrite:()=>A,bottom:()=>o,clippingParents:()=>d,computeStyles:()=>ne,createPopper:()=>Oe,createPopperBase:()=>Ne,createPopperLite:()=>je,detectOverflow:()=>ye,end:()=>p,eventListeners:()=>oe,flip:()=>we,hide:()=>Ee,left:()=>a,main:()=>x,modifierPhases:()=>q,offset:()=>Ae,placements:()=>v,popper:()=>h,popperGenerator:()=>Le,popperOffsets:()=>De,preventOverflow:()=>Te,read:()=>y,reference:()=>g,right:()=>s,start:()=>u,top:()=>i,variationPlacements:()=>m,viewport:()=>f,write:()=>D});var i="top",o="bottom",s="right",a="left",l="auto",c=[i,o,s,a],u="start",p="end",d="clippingParents",f="viewport",h="popper",g="reference",m=c.reduce((function(e,t){return e.concat([t+"-"+u,t+"-"+p])}),[]),v=[].concat(c,[l]).reduce((function(e,t){return e.concat([t,t+"-"+u,t+"-"+p])}),[]),b="beforeRead",y="read",w="afterRead",_="beforeMain",x="main",E="afterMain",A="beforeWrite",D="write",T="afterWrite",q=[b,y,w,_,x,E,A,D,T];function C(e){return e?(e.nodeName||"").toLowerCase():null}function k(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function S(e){return e instanceof k(e).Element||e instanceof Element}function L(e){return e instanceof k(e).HTMLElement||e instanceof HTMLElement}function N(e){return"undefined"!=typeof ShadowRoot&&(e instanceof k(e).ShadowRoot||e instanceof ShadowRoot)}const O={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var r=t.styles[e]||{},n=t.attributes[e]||{},i=t.elements[e];L(i)&&C(i)&&(Object.assign(i.style,r),Object.keys(n).forEach((function(e){var t=n[e];!1===t?i.removeAttribute(e):i.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,r={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,r.popper),t.styles=r,t.elements.arrow&&Object.assign(t.elements.arrow.style,r.arrow),function(){Object.keys(t.elements).forEach((function(e){var n=t.elements[e],i=t.attributes[e]||{},o=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:r[e]).reduce((function(e,t){return e[t]="",e}),{});L(n)&&C(n)&&(Object.assign(n.style,o),Object.keys(i).forEach((function(e){n.removeAttribute(e)})))}))}},requires:["computeStyles"]};function j(e){return e.split("-")[0]}var R=Math.max,B=Math.min,F=Math.round;function I(){var e=navigator.userAgentData;return null!=e&&e.brands&&Array.isArray(e.brands)?e.brands.map((function(e){return e.brand+"/"+e.version})).join(" "):navigator.userAgent}function P(){return!/^((?!chrome|android).)*safari/i.test(I())}function H(e,t,r){void 0===t&&(t=!1),void 0===r&&(r=!1);var n=e.getBoundingClientRect(),i=1,o=1;t&&L(e)&&(i=e.offsetWidth>0&&F(n.width)/e.offsetWidth||1,o=e.offsetHeight>0&&F(n.height)/e.offsetHeight||1);var s=(S(e)?k(e):window).visualViewport,a=!P()&&r,l=(n.left+(a&&s?s.offsetLeft:0))/i,c=(n.top+(a&&s?s.offsetTop:0))/o,u=n.width/i,p=n.height/o;return{width:u,height:p,top:c,right:l+u,bottom:c+p,left:l,x:l,y:c}}function M(e){var t=H(e),r=e.offsetWidth,n=e.offsetHeight;return Math.abs(t.width-r)<=1&&(r=t.width),Math.abs(t.height-n)<=1&&(n=t.height),{x:e.offsetLeft,y:e.offsetTop,width:r,height:n}}function U(e,t){var r=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(r&&N(r)){var n=t;do{if(n&&e.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function V(e){return k(e).getComputedStyle(e)}function $(e){return["table","td","th"].indexOf(C(e))>=0}function z(e){return((S(e)?e.ownerDocument:e.document)||window.document).documentElement}function G(e){return"html"===C(e)?e:e.assignedSlot||e.parentNode||(N(e)?e.host:null)||z(e)}function W(e){return L(e)&&"fixed"!==V(e).position?e.offsetParent:null}function Y(e){for(var t=k(e),r=W(e);r&&$(r)&&"static"===V(r).position;)r=W(r);return r&&("html"===C(r)||"body"===C(r)&&"static"===V(r).position)?t:r||function(e){var t=/firefox/i.test(I());if(/Trident/i.test(I())&&L(e)&&"fixed"===V(e).position)return null;var r=G(e);for(N(r)&&(r=r.host);L(r)&&["html","body"].indexOf(C(r))<0;){var n=V(r);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||t&&"filter"===n.willChange||t&&n.filter&&"none"!==n.filter)return r;r=r.parentNode}return null}(e)||t}function X(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function K(e,t,r){return R(e,B(t,r))}function J(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function Q(e,t){return t.reduce((function(t,r){return t[r]=e,t}),{})}const Z={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,r=e.state,n=e.name,l=e.options,u=r.elements.arrow,p=r.modifiersData.popperOffsets,d=j(r.placement),f=X(d),h=[a,s].indexOf(d)>=0?"height":"width";if(u&&p){var g=function(e,t){return J("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:Q(e,c))}(l.padding,r),m=M(u),v="y"===f?i:a,b="y"===f?o:s,y=r.rects.reference[h]+r.rects.reference[f]-p[f]-r.rects.popper[h],w=p[f]-r.rects.reference[f],_=Y(u),x=_?"y"===f?_.clientHeight||0:_.clientWidth||0:0,E=y/2-w/2,A=g[v],D=x-m[h]-g[b],T=x/2-m[h]/2+E,q=K(A,T,D),C=f;r.modifiersData[n]=((t={})[C]=q,t.centerOffset=q-T,t)}},effect:function(e){var t=e.state,r=e.options.element,n=void 0===r?"[data-popper-arrow]":r;null!=n&&("string"!=typeof n||(n=t.elements.popper.querySelector(n)))&&U(t.elements.popper,n)&&(t.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ee(e){return e.split("-")[1]}var te={top:"auto",right:"auto",bottom:"auto",left:"auto"};function re(e){var t,r=e.popper,n=e.popperRect,l=e.placement,c=e.variation,u=e.offsets,d=e.position,f=e.gpuAcceleration,h=e.adaptive,g=e.roundOffsets,m=e.isFixed,v=u.x,b=void 0===v?0:v,y=u.y,w=void 0===y?0:y,_="function"==typeof g?g({x:b,y:w}):{x:b,y:w};b=_.x,w=_.y;var x=u.hasOwnProperty("x"),E=u.hasOwnProperty("y"),A=a,D=i,T=window;if(h){var q=Y(r),C="clientHeight",S="clientWidth";if(q===k(r)&&"static"!==V(q=z(r)).position&&"absolute"===d&&(C="scrollHeight",S="scrollWidth"),l===i||(l===a||l===s)&&c===p)D=o,w-=(m&&q===T&&T.visualViewport?T.visualViewport.height:q[C])-n.height,w*=f?1:-1;if(l===a||(l===i||l===o)&&c===p)A=s,b-=(m&&q===T&&T.visualViewport?T.visualViewport.width:q[S])-n.width,b*=f?1:-1}var L,N=Object.assign({position:d},h&&te),O=!0===g?function(e,t){var r=e.x,n=e.y,i=t.devicePixelRatio||1;return{x:F(r*i)/i||0,y:F(n*i)/i||0}}({x:b,y:w},k(r)):{x:b,y:w};return b=O.x,w=O.y,f?Object.assign({},N,((L={})[D]=E?"0":"",L[A]=x?"0":"",L.transform=(T.devicePixelRatio||1)<=1?"translate("+b+"px, "+w+"px)":"translate3d("+b+"px, "+w+"px, 0)",L)):Object.assign({},N,((t={})[D]=E?w+"px":"",t[A]=x?b+"px":"",t.transform="",t))}const ne={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,r=e.options,n=r.gpuAcceleration,i=void 0===n||n,o=r.adaptive,s=void 0===o||o,a=r.roundOffsets,l=void 0===a||a,c={placement:j(t.placement),variation:ee(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:i,isFixed:"fixed"===t.options.strategy};null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,re(Object.assign({},c,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:s,roundOffsets:l})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,re(Object.assign({},c,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}};var ie={passive:!0};const oe={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(e){var t=e.state,r=e.instance,n=e.options,i=n.scroll,o=void 0===i||i,s=n.resize,a=void 0===s||s,l=k(t.elements.popper),c=[].concat(t.scrollParents.reference,t.scrollParents.popper);return o&&c.forEach((function(e){e.addEventListener("scroll",r.update,ie)})),a&&l.addEventListener("resize",r.update,ie),function(){o&&c.forEach((function(e){e.removeEventListener("scroll",r.update,ie)})),a&&l.removeEventListener("resize",r.update,ie)}},data:{}};var se={left:"right",right:"left",bottom:"top",top:"bottom"};function ae(e){return e.replace(/left|right|bottom|top/g,(function(e){return se[e]}))}var le={start:"end",end:"start"};function ce(e){return e.replace(/start|end/g,(function(e){return le[e]}))}function ue(e){var t=k(e);return{scrollLeft:t.pageXOffset,scrollTop:t.pageYOffset}}function pe(e){return H(z(e)).left+ue(e).scrollLeft}function de(e){var t=V(e),r=t.overflow,n=t.overflowX,i=t.overflowY;return/auto|scroll|overlay|hidden/.test(r+i+n)}function fe(e){return["html","body","#document"].indexOf(C(e))>=0?e.ownerDocument.body:L(e)&&de(e)?e:fe(G(e))}function he(e,t){var r;void 0===t&&(t=[]);var n=fe(e),i=n===(null==(r=e.ownerDocument)?void 0:r.body),o=k(n),s=i?[o].concat(o.visualViewport||[],de(n)?n:[]):n,a=t.concat(s);return i?a:a.concat(he(G(s)))}function ge(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function me(e,t,r){return t===f?ge(function(e,t){var r=k(e),n=z(e),i=r.visualViewport,o=n.clientWidth,s=n.clientHeight,a=0,l=0;if(i){o=i.width,s=i.height;var c=P();(c||!c&&"fixed"===t)&&(a=i.offsetLeft,l=i.offsetTop)}return{width:o,height:s,x:a+pe(e),y:l}}(e,r)):S(t)?function(e,t){var r=H(e,!1,"fixed"===t);return r.top=r.top+e.clientTop,r.left=r.left+e.clientLeft,r.bottom=r.top+e.clientHeight,r.right=r.left+e.clientWidth,r.width=e.clientWidth,r.height=e.clientHeight,r.x=r.left,r.y=r.top,r}(t,r):ge(function(e){var t,r=z(e),n=ue(e),i=null==(t=e.ownerDocument)?void 0:t.body,o=R(r.scrollWidth,r.clientWidth,i?i.scrollWidth:0,i?i.clientWidth:0),s=R(r.scrollHeight,r.clientHeight,i?i.scrollHeight:0,i?i.clientHeight:0),a=-n.scrollLeft+pe(e),l=-n.scrollTop;return"rtl"===V(i||r).direction&&(a+=R(r.clientWidth,i?i.clientWidth:0)-o),{width:o,height:s,x:a,y:l}}(z(e)))}function ve(e,t,r,n){var i="clippingParents"===t?function(e){var t=he(G(e)),r=["absolute","fixed"].indexOf(V(e).position)>=0&&L(e)?Y(e):e;return S(r)?t.filter((function(e){return S(e)&&U(e,r)&&"body"!==C(e)})):[]}(e):[].concat(t),o=[].concat(i,[r]),s=o[0],a=o.reduce((function(t,r){var i=me(e,r,n);return t.top=R(i.top,t.top),t.right=B(i.right,t.right),t.bottom=B(i.bottom,t.bottom),t.left=R(i.left,t.left),t}),me(e,s,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}function be(e){var t,r=e.reference,n=e.element,l=e.placement,c=l?j(l):null,d=l?ee(l):null,f=r.x+r.width/2-n.width/2,h=r.y+r.height/2-n.height/2;switch(c){case i:t={x:f,y:r.y-n.height};break;case o:t={x:f,y:r.y+r.height};break;case s:t={x:r.x+r.width,y:h};break;case a:t={x:r.x-n.width,y:h};break;default:t={x:r.x,y:r.y}}var g=c?X(c):null;if(null!=g){var m="y"===g?"height":"width";switch(d){case u:t[g]=t[g]-(r[m]/2-n[m]/2);break;case p:t[g]=t[g]+(r[m]/2-n[m]/2)}}return t}function ye(e,t){void 0===t&&(t={});var r=t,n=r.placement,a=void 0===n?e.placement:n,l=r.strategy,u=void 0===l?e.strategy:l,p=r.boundary,m=void 0===p?d:p,v=r.rootBoundary,b=void 0===v?f:v,y=r.elementContext,w=void 0===y?h:y,_=r.altBoundary,x=void 0!==_&&_,E=r.padding,A=void 0===E?0:E,D=J("number"!=typeof A?A:Q(A,c)),T=w===h?g:h,q=e.rects.popper,C=e.elements[x?T:w],k=ve(S(C)?C:C.contextElement||z(e.elements.popper),m,b,u),L=H(e.elements.reference),N=be({reference:L,element:q,strategy:"absolute",placement:a}),O=ge(Object.assign({},q,N)),j=w===h?O:L,R={top:k.top-j.top+D.top,bottom:j.bottom-k.bottom+D.bottom,left:k.left-j.left+D.left,right:j.right-k.right+D.right},B=e.modifiersData.offset;if(w===h&&B){var F=B[a];Object.keys(R).forEach((function(e){var t=[s,o].indexOf(e)>=0?1:-1,r=[i,o].indexOf(e)>=0?"y":"x";R[e]+=F[r]*t}))}return R}const we={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,r=e.options,n=e.name;if(!t.modifiersData[n]._skip){for(var p=r.mainAxis,d=void 0===p||p,f=r.altAxis,h=void 0===f||f,g=r.fallbackPlacements,b=r.padding,y=r.boundary,w=r.rootBoundary,_=r.altBoundary,x=r.flipVariations,E=void 0===x||x,A=r.allowedAutoPlacements,D=t.options.placement,T=j(D),q=g||(T===D||!E?[ae(D)]:function(e){if(j(e)===l)return[];var t=ae(e);return[ce(e),t,ce(t)]}(D)),C=[D].concat(q).reduce((function(e,r){return e.concat(j(r)===l?function(e,t){void 0===t&&(t={});var r=t,n=r.placement,i=r.boundary,o=r.rootBoundary,s=r.padding,a=r.flipVariations,l=r.allowedAutoPlacements,u=void 0===l?v:l,p=ee(n),d=p?a?m:m.filter((function(e){return ee(e)===p})):c,f=d.filter((function(e){return u.indexOf(e)>=0}));0===f.length&&(f=d);var h=f.reduce((function(t,r){return t[r]=ye(e,{placement:r,boundary:i,rootBoundary:o,padding:s})[j(r)],t}),{});return Object.keys(h).sort((function(e,t){return h[e]-h[t]}))}(t,{placement:r,boundary:y,rootBoundary:w,padding:b,flipVariations:E,allowedAutoPlacements:A}):r)}),[]),k=t.rects.reference,S=t.rects.popper,L=new Map,N=!0,O=C[0],R=0;R=0,H=P?"width":"height",M=ye(t,{placement:B,boundary:y,rootBoundary:w,altBoundary:_,padding:b}),U=P?I?s:a:I?o:i;k[H]>S[H]&&(U=ae(U));var V=ae(U),$=[];if(d&&$.push(M[F]<=0),h&&$.push(M[U]<=0,M[V]<=0),$.every((function(e){return e}))){O=B,N=!1;break}L.set(B,$)}if(N)for(var z=function(e){var t=C.find((function(t){var r=L.get(t);if(r)return r.slice(0,e).every((function(e){return e}))}));if(t)return O=t,"break"},G=E?3:1;G>0;G--){if("break"===z(G))break}t.placement!==O&&(t.modifiersData[n]._skip=!0,t.placement=O,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function _e(e,t,r){return void 0===r&&(r={x:0,y:0}),{top:e.top-t.height-r.y,right:e.right-t.width+r.x,bottom:e.bottom-t.height+r.y,left:e.left-t.width-r.x}}function xe(e){return[i,s,o,a].some((function(t){return e[t]>=0}))}const Ee={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,r=e.name,n=t.rects.reference,i=t.rects.popper,o=t.modifiersData.preventOverflow,s=ye(t,{elementContext:"reference"}),a=ye(t,{altBoundary:!0}),l=_e(s,n),c=_e(a,i,o),u=xe(l),p=xe(c);t.modifiersData[r]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:u,hasPopperEscaped:p},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":u,"data-popper-escaped":p})}};const Ae={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,r=e.options,n=e.name,o=r.offset,l=void 0===o?[0,0]:o,c=v.reduce((function(e,r){return e[r]=function(e,t,r){var n=j(e),o=[a,i].indexOf(n)>=0?-1:1,l="function"==typeof r?r(Object.assign({},t,{placement:e})):r,c=l[0],u=l[1];return c=c||0,u=(u||0)*o,[a,s].indexOf(n)>=0?{x:u,y:c}:{x:c,y:u}}(r,t.rects,l),e}),{}),u=c[t.placement],p=u.x,d=u.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=p,t.modifiersData.popperOffsets.y+=d),t.modifiersData[n]=c}};const De={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state,r=e.name;t.modifiersData[r]=be({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}};const Te={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,r=e.options,n=e.name,l=r.mainAxis,c=void 0===l||l,p=r.altAxis,d=void 0!==p&&p,f=r.boundary,h=r.rootBoundary,g=r.altBoundary,m=r.padding,v=r.tether,b=void 0===v||v,y=r.tetherOffset,w=void 0===y?0:y,_=ye(t,{boundary:f,rootBoundary:h,padding:m,altBoundary:g}),x=j(t.placement),E=ee(t.placement),A=!E,D=X(x),T="x"===D?"y":"x",q=t.modifiersData.popperOffsets,C=t.rects.reference,k=t.rects.popper,S="function"==typeof w?w(Object.assign({},t.rects,{placement:t.placement})):w,L="number"==typeof S?{mainAxis:S,altAxis:S}:Object.assign({mainAxis:0,altAxis:0},S),N=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,O={x:0,y:0};if(q){if(c){var F,I="y"===D?i:a,P="y"===D?o:s,H="y"===D?"height":"width",U=q[D],V=U+_[I],$=U-_[P],z=b?-k[H]/2:0,G=E===u?C[H]:k[H],W=E===u?-k[H]:-C[H],J=t.elements.arrow,Q=b&&J?M(J):{width:0,height:0},Z=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=Z[I],re=Z[P],ne=K(0,C[H],Q[H]),ie=A?C[H]/2-z-ne-te-L.mainAxis:G-ne-te-L.mainAxis,oe=A?-C[H]/2+z+ne+re+L.mainAxis:W+ne+re+L.mainAxis,se=t.elements.arrow&&Y(t.elements.arrow),ae=se?"y"===D?se.clientTop||0:se.clientLeft||0:0,le=null!=(F=null==N?void 0:N[D])?F:0,ce=U+oe-le,ue=K(b?B(V,U+ie-le-ae):V,U,b?R($,ce):$);q[D]=ue,O[D]=ue-U}if(d){var pe,de="x"===D?i:a,fe="x"===D?o:s,he=q[T],ge="y"===T?"height":"width",me=he+_[de],ve=he-_[fe],be=-1!==[i,a].indexOf(x),we=null!=(pe=null==N?void 0:N[T])?pe:0,_e=be?me:he-C[ge]-k[ge]-we+L.altAxis,xe=be?he+C[ge]+k[ge]-we-L.altAxis:ve,Ee=b&&be?function(e,t,r){var n=K(e,t,r);return n>r?r:n}(_e,he,xe):K(b?_e:me,he,b?xe:ve);q[T]=Ee,O[T]=Ee-he}t.modifiersData[n]=O}},requiresIfExists:["offset"]};function qe(e,t,r){void 0===r&&(r=!1);var n,i,o=L(t),s=L(t)&&function(e){var t=e.getBoundingClientRect(),r=F(t.width)/e.offsetWidth||1,n=F(t.height)/e.offsetHeight||1;return 1!==r||1!==n}(t),a=z(t),l=H(e,s,r),c={scrollLeft:0,scrollTop:0},u={x:0,y:0};return(o||!o&&!r)&&(("body"!==C(t)||de(a))&&(c=(n=t)!==k(n)&&L(n)?{scrollLeft:(i=n).scrollLeft,scrollTop:i.scrollTop}:ue(n)),L(t)?((u=H(t,!0)).x+=t.clientLeft,u.y+=t.clientTop):a&&(u.x=pe(a))),{x:l.left+c.scrollLeft-u.x,y:l.top+c.scrollTop-u.y,width:l.width,height:l.height}}function Ce(e){var t=new Map,r=new Set,n=[];function i(e){r.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!r.has(e)){var n=t.get(e);n&&i(n)}})),n.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){r.has(e.name)||i(e)})),n}var ke={placement:"bottom",modifiers:[],strategy:"absolute"};function Se(){for(var e=arguments.length,t=new Array(e),r=0;rRe.has(e)&&Re.get(e).get(t)||null,remove(e,t){if(!Re.has(e))return;const r=Re.get(e);r.delete(t),0===r.size&&Re.delete(e)}},Fe="transitionend",Ie=e=>(e&&window.CSS&&window.CSS.escape&&(e=e.replace(/#([^\s"#']+)/g,((e,t)=>`#${CSS.escape(t)}`))),e),Pe=e=>{e.dispatchEvent(new Event(Fe))},He=e=>!(!e||"object"!=typeof e)&&(void 0!==e.jquery&&(e=e[0]),void 0!==e.nodeType),Me=e=>He(e)?e.jquery?e[0]:e:"string"==typeof e&&e.length>0?document.querySelector(Ie(e)):null,Ue=e=>{if(!He(e)||0===e.getClientRects().length)return!1;const t="visible"===getComputedStyle(e).getPropertyValue("visibility"),r=e.closest("details:not([open])");if(!r)return t;if(r!==e){const t=e.closest("summary");if(t&&t.parentNode!==r)return!1;if(null===t)return!1}return t},Ve=e=>!e||e.nodeType!==Node.ELEMENT_NODE||(!!e.classList.contains("disabled")||(void 0!==e.disabled?e.disabled:e.hasAttribute("disabled")&&"false"!==e.getAttribute("disabled"))),$e=e=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof e.getRootNode){const t=e.getRootNode();return t instanceof ShadowRoot?t:null}return e instanceof ShadowRoot?e:e.parentNode?$e(e.parentNode):null},ze=()=>{},Ge=e=>{e.offsetHeight},We=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,Ye=[],Xe=()=>"rtl"===document.documentElement.dir,Ke=e=>{var t;t=()=>{const t=We();if(t){const r=e.NAME,n=t.fn[r];t.fn[r]=e.jQueryInterface,t.fn[r].Constructor=e,t.fn[r].noConflict=()=>(t.fn[r]=n,e.jQueryInterface)}},"loading"===document.readyState?(Ye.length||document.addEventListener("DOMContentLoaded",(()=>{for(const e of Ye)e()})),Ye.push(t)):t()},Je=(e,t=[],r=e)=>"function"==typeof e?e(...t):r,Qe=(e,t,r=!0)=>{if(!r)return void Je(e);const n=(e=>{if(!e)return 0;let{transitionDuration:t,transitionDelay:r}=window.getComputedStyle(e);const n=Number.parseFloat(t),i=Number.parseFloat(r);return n||i?(t=t.split(",")[0],r=r.split(",")[0],1e3*(Number.parseFloat(t)+Number.parseFloat(r))):0})(t)+5;let i=!1;const o=({target:r})=>{r===t&&(i=!0,t.removeEventListener(Fe,o),Je(e))};t.addEventListener(Fe,o),setTimeout((()=>{i||Pe(t)}),n)},Ze=(e,t,r,n)=>{const i=e.length;let o=e.indexOf(t);return-1===o?!r&&n?e[i-1]:e[0]:(o+=r?1:-1,n&&(o=(o+i)%i),e[Math.max(0,Math.min(o,i-1))])},et=/[^.]*(?=\..*)\.|.*/,tt=/\..*/,rt=/::\d+$/,nt={};let it=1;const ot={mouseenter:"mouseover",mouseleave:"mouseout"},st=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function at(e,t){return t&&`${t}::${it++}`||e.uidEvent||it++}function lt(e){const t=at(e);return e.uidEvent=t,nt[t]=nt[t]||{},nt[t]}function ct(e,t,r=null){return Object.values(e).find((e=>e.callable===t&&e.delegationSelector===r))}function ut(e,t,r){const n="string"==typeof t,i=n?r:t||r;let o=ht(e);return st.has(o)||(o=e),[n,i,o]}function pt(e,t,r,n,i){if("string"!=typeof t||!e)return;let[o,s,a]=ut(t,r,n);if(t in ot){const e=e=>function(t){if(!t.relatedTarget||t.relatedTarget!==t.delegateTarget&&!t.delegateTarget.contains(t.relatedTarget))return e.call(this,t)};s=e(s)}const l=lt(e),c=l[a]||(l[a]={}),u=ct(c,s,o?r:null);if(u)return void(u.oneOff=u.oneOff&&i);const p=at(s,t.replace(et,"")),d=o?function(e,t,r){return function n(i){const o=e.querySelectorAll(t);for(let{target:s}=i;s&&s!==this;s=s.parentNode)for(const a of o)if(a===s)return mt(i,{delegateTarget:s}),n.oneOff&>.off(e,i.type,t,r),r.apply(s,[i])}}(e,r,s):function(e,t){return function r(n){return mt(n,{delegateTarget:e}),r.oneOff&>.off(e,n.type,t),t.apply(e,[n])}}(e,s);d.delegationSelector=o?r:null,d.callable=s,d.oneOff=i,d.uidEvent=p,c[p]=d,e.addEventListener(a,d,o)}function dt(e,t,r,n,i){const o=ct(t[r],n,i);o&&(e.removeEventListener(r,o,Boolean(i)),delete t[r][o.uidEvent])}function ft(e,t,r,n){const i=t[r]||{};for(const[o,s]of Object.entries(i))o.includes(n)&&dt(e,t,r,s.callable,s.delegationSelector)}function ht(e){return e=e.replace(tt,""),ot[e]||e}const gt={on(e,t,r,n){pt(e,t,r,n,!1)},one(e,t,r,n){pt(e,t,r,n,!0)},off(e,t,r,n){if("string"!=typeof t||!e)return;const[i,o,s]=ut(t,r,n),a=s!==t,l=lt(e),c=l[s]||{},u=t.startsWith(".");if(void 0===o){if(u)for(const r of Object.keys(l))ft(e,l,r,t.slice(1));for(const[r,n]of Object.entries(c)){const i=r.replace(rt,"");a&&!t.includes(i)||dt(e,l,s,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;dt(e,l,s,o,i?r:null)}},trigger(e,t,r){if("string"!=typeof t||!e)return null;const n=We();let i=null,o=!0,s=!0,a=!1;t!==ht(t)&&n&&(i=n.Event(t,r),n(e).trigger(i),o=!i.isPropagationStopped(),s=!i.isImmediatePropagationStopped(),a=i.isDefaultPrevented());const l=mt(new Event(t,{bubbles:o,cancelable:!0}),r);return a&&l.preventDefault(),s&&e.dispatchEvent(l),l.defaultPrevented&&i&&i.preventDefault(),l}};function mt(e,t={}){for(const[r,n]of Object.entries(t))try{e[r]=n}catch(t){Object.defineProperty(e,r,{configurable:!0,get:()=>n})}return e}function vt(e){if("true"===e)return!0;if("false"===e)return!1;if(e===Number(e).toString())return Number(e);if(""===e||"null"===e)return null;if("string"!=typeof e)return e;try{return JSON.parse(decodeURIComponent(e))}catch(t){return e}}function bt(e){return e.replace(/[A-Z]/g,(e=>`-${e.toLowerCase()}`))}const yt={setDataAttribute(e,t,r){e.setAttribute(`data-bs-${bt(t)}`,r)},removeDataAttribute(e,t){e.removeAttribute(`data-bs-${bt(t)}`)},getDataAttributes(e){if(!e)return{};const t={},r=Object.keys(e.dataset).filter((e=>e.startsWith("bs")&&!e.startsWith("bsConfig")));for(const n of r){let r=n.replace(/^bs/,"");r=r.charAt(0).toLowerCase()+r.slice(1,r.length),t[r]=vt(e.dataset[n])}return t},getDataAttribute:(e,t)=>vt(e.getAttribute(`data-bs-${bt(t)}`))};class wt{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(e){return e=this._mergeConfigObj(e),e=this._configAfterMerge(e),this._typeCheckConfig(e),e}_configAfterMerge(e){return e}_mergeConfigObj(e,t){const r=He(t)?yt.getDataAttribute(t,"config"):{};return{...this.constructor.Default,..."object"==typeof r?r:{},...He(t)?yt.getDataAttributes(t):{},..."object"==typeof e?e:{}}}_typeCheckConfig(e,t=this.constructor.DefaultType){for(const[n,i]of Object.entries(t)){const t=e[n],o=He(t)?"element":null==(r=t)?`${r}`:Object.prototype.toString.call(r).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(i).test(o))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${o}" but expected type "${i}".`)}var r}}class _t extends wt{constructor(e,t){super(),(e=Me(e))&&(this._element=e,this._config=this._getConfig(t),Be.set(this._element,this.constructor.DATA_KEY,this))}dispose(){Be.remove(this._element,this.constructor.DATA_KEY),gt.off(this._element,this.constructor.EVENT_KEY);for(const e of Object.getOwnPropertyNames(this))this[e]=null}_queueCallback(e,t,r=!0){Qe(e,t,r)}_getConfig(e){return e=this._mergeConfigObj(e,this._element),e=this._configAfterMerge(e),this._typeCheckConfig(e),e}static getInstance(e){return Be.get(Me(e),this.DATA_KEY)}static getOrCreateInstance(e,t={}){return this.getInstance(e)||new this(e,"object"==typeof t?t:null)}static get VERSION(){return"5.3.2"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(e){return`${e}${this.EVENT_KEY}`}}const xt=e=>{let t=e.getAttribute("data-bs-target");if(!t||"#"===t){let r=e.getAttribute("href");if(!r||!r.includes("#")&&!r.startsWith("."))return null;r.includes("#")&&!r.startsWith("#")&&(r=`#${r.split("#")[1]}`),t=r&&"#"!==r?Ie(r.trim()):null}return t},Et={find:(e,t=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(t,e)),findOne:(e,t=document.documentElement)=>Element.prototype.querySelector.call(t,e),children:(e,t)=>[].concat(...e.children).filter((e=>e.matches(t))),parents(e,t){const r=[];let n=e.parentNode.closest(t);for(;n;)r.push(n),n=n.parentNode.closest(t);return r},prev(e,t){let r=e.previousElementSibling;for(;r;){if(r.matches(t))return[r];r=r.previousElementSibling}return[]},next(e,t){let r=e.nextElementSibling;for(;r;){if(r.matches(t))return[r];r=r.nextElementSibling}return[]},focusableChildren(e){const t=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((e=>`${e}:not([tabindex^="-"])`)).join(",");return this.find(t,e).filter((e=>!Ve(e)&&Ue(e)))},getSelectorFromElement(e){const t=xt(e);return t&&Et.findOne(t)?t:null},getElementFromSelector(e){const t=xt(e);return t?Et.findOne(t):null},getMultipleElementsFromSelector(e){const t=xt(e);return t?Et.find(t):[]}},At=(e,t="hide")=>{const r=`click.dismiss${e.EVENT_KEY}`,n=e.NAME;gt.on(document,r,`[data-bs-dismiss="${n}"]`,(function(r){if(["A","AREA"].includes(this.tagName)&&r.preventDefault(),Ve(this))return;const i=Et.getElementFromSelector(this)||this.closest(`.${n}`);e.getOrCreateInstance(i)[t]()}))},Dt=".bs.alert",Tt=`close${Dt}`,qt=`closed${Dt}`;class Ct extends _t{static get NAME(){return"alert"}close(){if(gt.trigger(this._element,Tt).defaultPrevented)return;this._element.classList.remove("show");const e=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,e)}_destroyElement(){this._element.remove(),gt.trigger(this._element,qt),this.dispose()}static jQueryInterface(e){return this.each((function(){const t=Ct.getOrCreateInstance(this);if("string"==typeof e){if(void 0===t[e]||e.startsWith("_")||"constructor"===e)throw new TypeError(`No method named "${e}"`);t[e](this)}}))}}At(Ct,"close"),Ke(Ct);const kt='[data-bs-toggle="button"]';class St extends _t{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(e){return this.each((function(){const t=St.getOrCreateInstance(this);"toggle"===e&&t[e]()}))}}gt.on(document,"click.bs.button.data-api",kt,(e=>{e.preventDefault();const t=e.target.closest(kt);St.getOrCreateInstance(t).toggle()})),Ke(St);const Lt=".bs.swipe",Nt=`touchstart${Lt}`,Ot=`touchmove${Lt}`,jt=`touchend${Lt}`,Rt=`pointerdown${Lt}`,Bt=`pointerup${Lt}`,Ft={endCallback:null,leftCallback:null,rightCallback:null},It={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class Pt extends wt{constructor(e,t){super(),this._element=e,e&&Pt.isSupported()&&(this._config=this._getConfig(t),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return Ft}static get DefaultType(){return It}static get NAME(){return"swipe"}dispose(){gt.off(this._element,Lt)}_start(e){this._supportPointerEvents?this._eventIsPointerPenTouch(e)&&(this._deltaX=e.clientX):this._deltaX=e.touches[0].clientX}_end(e){this._eventIsPointerPenTouch(e)&&(this._deltaX=e.clientX-this._deltaX),this._handleSwipe(),Je(this._config.endCallback)}_move(e){this._deltaX=e.touches&&e.touches.length>1?0:e.touches[0].clientX-this._deltaX}_handleSwipe(){const e=Math.abs(this._deltaX);if(e<=40)return;const t=e/this._deltaX;this._deltaX=0,t&&Je(t>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(gt.on(this._element,Rt,(e=>this._start(e))),gt.on(this._element,Bt,(e=>this._end(e))),this._element.classList.add("pointer-event")):(gt.on(this._element,Nt,(e=>this._start(e))),gt.on(this._element,Ot,(e=>this._move(e))),gt.on(this._element,jt,(e=>this._end(e))))}_eventIsPointerPenTouch(e){return this._supportPointerEvents&&("pen"===e.pointerType||"touch"===e.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const Ht=".bs.carousel",Mt=".data-api",Ut="next",Vt="prev",$t="left",zt="right",Gt=`slide${Ht}`,Wt=`slid${Ht}`,Yt=`keydown${Ht}`,Xt=`mouseenter${Ht}`,Kt=`mouseleave${Ht}`,Jt=`dragstart${Ht}`,Qt=`load${Ht}${Mt}`,Zt=`click${Ht}${Mt}`,er="carousel",tr="active",rr=".active",nr=".carousel-item",ir=rr+nr,or={ArrowLeft:zt,ArrowRight:$t},sr={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},ar={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class lr extends _t{constructor(e,t){super(e,t),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=Et.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===er&&this.cycle()}static get Default(){return sr}static get DefaultType(){return ar}static get NAME(){return"carousel"}next(){this._slide(Ut)}nextWhenVisible(){!document.hidden&&Ue(this._element)&&this.next()}prev(){this._slide(Vt)}pause(){this._isSliding&&Pe(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?gt.one(this._element,Wt,(()=>this.cycle())):this.cycle())}to(e){const t=this._getItems();if(e>t.length-1||e<0)return;if(this._isSliding)return void gt.one(this._element,Wt,(()=>this.to(e)));const r=this._getItemIndex(this._getActive());if(r===e)return;const n=e>r?Ut:Vt;this._slide(n,t[e])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(e){return e.defaultInterval=e.interval,e}_addEventListeners(){this._config.keyboard&>.on(this._element,Yt,(e=>this._keydown(e))),"hover"===this._config.pause&&(gt.on(this._element,Xt,(()=>this.pause())),gt.on(this._element,Kt,(()=>this._maybeEnableCycle()))),this._config.touch&&Pt.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const e of Et.find(".carousel-item img",this._element))gt.on(e,Jt,(e=>e.preventDefault()));const e={leftCallback:()=>this._slide(this._directionToOrder($t)),rightCallback:()=>this._slide(this._directionToOrder(zt)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new Pt(this._element,e)}_keydown(e){if(/input|textarea/i.test(e.target.tagName))return;const t=or[e.key];t&&(e.preventDefault(),this._slide(this._directionToOrder(t)))}_getItemIndex(e){return this._getItems().indexOf(e)}_setActiveIndicatorElement(e){if(!this._indicatorsElement)return;const t=Et.findOne(rr,this._indicatorsElement);t.classList.remove(tr),t.removeAttribute("aria-current");const r=Et.findOne(`[data-bs-slide-to="${e}"]`,this._indicatorsElement);r&&(r.classList.add(tr),r.setAttribute("aria-current","true"))}_updateInterval(){const e=this._activeElement||this._getActive();if(!e)return;const t=Number.parseInt(e.getAttribute("data-bs-interval"),10);this._config.interval=t||this._config.defaultInterval}_slide(e,t=null){if(this._isSliding)return;const r=this._getActive(),n=e===Ut,i=t||Ze(this._getItems(),r,n,this._config.wrap);if(i===r)return;const o=this._getItemIndex(i),s=t=>gt.trigger(this._element,t,{relatedTarget:i,direction:this._orderToDirection(e),from:this._getItemIndex(r),to:o});if(s(Gt).defaultPrevented)return;if(!r||!i)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=i;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";i.classList.add(c),Ge(i),r.classList.add(l),i.classList.add(l);this._queueCallback((()=>{i.classList.remove(l,c),i.classList.add(tr),r.classList.remove(tr,c,l),this._isSliding=!1,s(Wt)}),r,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return Et.findOne(ir,this._element)}_getItems(){return Et.find(nr,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(e){return Xe()?e===$t?Vt:Ut:e===$t?Ut:Vt}_orderToDirection(e){return Xe()?e===Vt?$t:zt:e===Vt?zt:$t}static jQueryInterface(e){return this.each((function(){const t=lr.getOrCreateInstance(this,e);if("number"!=typeof e){if("string"==typeof e){if(void 0===t[e]||e.startsWith("_")||"constructor"===e)throw new TypeError(`No method named "${e}"`);t[e]()}}else t.to(e)}))}}gt.on(document,Zt,"[data-bs-slide], [data-bs-slide-to]",(function(e){const t=Et.getElementFromSelector(this);if(!t||!t.classList.contains(er))return;e.preventDefault();const r=lr.getOrCreateInstance(t),n=this.getAttribute("data-bs-slide-to");return n?(r.to(n),void r._maybeEnableCycle()):"next"===yt.getDataAttribute(this,"slide")?(r.next(),void r._maybeEnableCycle()):(r.prev(),void r._maybeEnableCycle())})),gt.on(window,Qt,(()=>{const e=Et.find('[data-bs-ride="carousel"]');for(const t of e)lr.getOrCreateInstance(t)})),Ke(lr);const cr=".bs.collapse",ur=`show${cr}`,pr=`shown${cr}`,dr=`hide${cr}`,fr=`hidden${cr}`,hr=`click${cr}.data-api`,gr="show",mr="collapse",vr="collapsing",br=`:scope .${mr} .${mr}`,yr='[data-bs-toggle="collapse"]',wr={parent:null,toggle:!0},_r={parent:"(null|element)",toggle:"boolean"};class xr extends _t{constructor(e,t){super(e,t),this._isTransitioning=!1,this._triggerArray=[];const r=Et.find(yr);for(const e of r){const t=Et.getSelectorFromElement(e),r=Et.find(t).filter((e=>e===this._element));null!==t&&r.length&&this._triggerArray.push(e)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return wr}static get DefaultType(){return _r}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let e=[];if(this._config.parent&&(e=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((e=>e!==this._element)).map((e=>xr.getOrCreateInstance(e,{toggle:!1})))),e.length&&e[0]._isTransitioning)return;if(gt.trigger(this._element,ur).defaultPrevented)return;for(const t of e)t.hide();const t=this._getDimension();this._element.classList.remove(mr),this._element.classList.add(vr),this._element.style[t]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const r=`scroll${t[0].toUpperCase()+t.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(vr),this._element.classList.add(mr,gr),this._element.style[t]="",gt.trigger(this._element,pr)}),this._element,!0),this._element.style[t]=`${this._element[r]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(gt.trigger(this._element,dr).defaultPrevented)return;const e=this._getDimension();this._element.style[e]=`${this._element.getBoundingClientRect()[e]}px`,Ge(this._element),this._element.classList.add(vr),this._element.classList.remove(mr,gr);for(const e of this._triggerArray){const t=Et.getElementFromSelector(e);t&&!this._isShown(t)&&this._addAriaAndCollapsedClass([e],!1)}this._isTransitioning=!0;this._element.style[e]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(vr),this._element.classList.add(mr),gt.trigger(this._element,fr)}),this._element,!0)}_isShown(e=this._element){return e.classList.contains(gr)}_configAfterMerge(e){return e.toggle=Boolean(e.toggle),e.parent=Me(e.parent),e}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const e=this._getFirstLevelChildren(yr);for(const t of e){const e=Et.getElementFromSelector(t);e&&this._addAriaAndCollapsedClass([t],this._isShown(e))}}_getFirstLevelChildren(e){const t=Et.find(br,this._config.parent);return Et.find(e,this._config.parent).filter((e=>!t.includes(e)))}_addAriaAndCollapsedClass(e,t){if(e.length)for(const r of e)r.classList.toggle("collapsed",!t),r.setAttribute("aria-expanded",t)}static jQueryInterface(e){const t={};return"string"==typeof e&&/show|hide/.test(e)&&(t.toggle=!1),this.each((function(){const r=xr.getOrCreateInstance(this,t);if("string"==typeof e){if(void 0===r[e])throw new TypeError(`No method named "${e}"`);r[e]()}}))}}gt.on(document,hr,yr,(function(e){("A"===e.target.tagName||e.delegateTarget&&"A"===e.delegateTarget.tagName)&&e.preventDefault();for(const e of Et.getMultipleElementsFromSelector(this))xr.getOrCreateInstance(e,{toggle:!1}).toggle()})),Ke(xr);const Er="dropdown",Ar=".bs.dropdown",Dr=".data-api",Tr="ArrowUp",qr="ArrowDown",Cr=`hide${Ar}`,kr=`hidden${Ar}`,Sr=`show${Ar}`,Lr=`shown${Ar}`,Nr=`click${Ar}${Dr}`,Or=`keydown${Ar}${Dr}`,jr=`keyup${Ar}${Dr}`,Rr="show",Br='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',Fr=`${Br}.${Rr}`,Ir=".dropdown-menu",Pr=Xe()?"top-end":"top-start",Hr=Xe()?"top-start":"top-end",Mr=Xe()?"bottom-end":"bottom-start",Ur=Xe()?"bottom-start":"bottom-end",Vr=Xe()?"left-start":"right-start",$r=Xe()?"right-start":"left-start",zr={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},Gr={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"};class Wr extends _t{constructor(e,t){super(e,t),this._popper=null,this._parent=this._element.parentNode,this._menu=Et.next(this._element,Ir)[0]||Et.prev(this._element,Ir)[0]||Et.findOne(Ir,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return zr}static get DefaultType(){return Gr}static get NAME(){return Er}toggle(){return this._isShown()?this.hide():this.show()}show(){if(Ve(this._element)||this._isShown())return;const e={relatedTarget:this._element};if(!gt.trigger(this._element,Sr,e).defaultPrevented){if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(".navbar-nav"))for(const e of[].concat(...document.body.children))gt.on(e,"mouseover",ze);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Rr),this._element.classList.add(Rr),gt.trigger(this._element,Lr,e)}}hide(){if(Ve(this._element)||!this._isShown())return;const e={relatedTarget:this._element};this._completeHide(e)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(e){if(!gt.trigger(this._element,Cr,e).defaultPrevented){if("ontouchstart"in document.documentElement)for(const e of[].concat(...document.body.children))gt.off(e,"mouseover",ze);this._popper&&this._popper.destroy(),this._menu.classList.remove(Rr),this._element.classList.remove(Rr),this._element.setAttribute("aria-expanded","false"),yt.removeDataAttribute(this._menu,"popper"),gt.trigger(this._element,kr,e)}}_getConfig(e){if("object"==typeof(e=super._getConfig(e)).reference&&!He(e.reference)&&"function"!=typeof e.reference.getBoundingClientRect)throw new TypeError(`${Er.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return e}_createPopper(){if(void 0===n)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let e=this._element;"parent"===this._config.reference?e=this._parent:He(this._config.reference)?e=Me(this._config.reference):"object"==typeof this._config.reference&&(e=this._config.reference);const t=this._getPopperConfig();this._popper=Oe(e,this._menu,t)}_isShown(){return this._menu.classList.contains(Rr)}_getPlacement(){const e=this._parent;if(e.classList.contains("dropend"))return Vr;if(e.classList.contains("dropstart"))return $r;if(e.classList.contains("dropup-center"))return"top";if(e.classList.contains("dropdown-center"))return"bottom";const t="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return e.classList.contains("dropup")?t?Hr:Pr:t?Ur:Mr}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:e}=this._config;return"string"==typeof e?e.split(",").map((e=>Number.parseInt(e,10))):"function"==typeof e?t=>e(t,this._element):e}_getPopperConfig(){const e={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(yt.setDataAttribute(this._menu,"popper","static"),e.modifiers=[{name:"applyStyles",enabled:!1}]),{...e,...Je(this._config.popperConfig,[e])}}_selectMenuItem({key:e,target:t}){const r=Et.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((e=>Ue(e)));r.length&&Ze(r,t,e===qr,!r.includes(t)).focus()}static jQueryInterface(e){return this.each((function(){const t=Wr.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e])throw new TypeError(`No method named "${e}"`);t[e]()}}))}static clearMenus(e){if(2===e.button||"keyup"===e.type&&"Tab"!==e.key)return;const t=Et.find(Fr);for(const r of t){const t=Wr.getInstance(r);if(!t||!1===t._config.autoClose)continue;const n=e.composedPath(),i=n.includes(t._menu);if(n.includes(t._element)||"inside"===t._config.autoClose&&!i||"outside"===t._config.autoClose&&i)continue;if(t._menu.contains(e.target)&&("keyup"===e.type&&"Tab"===e.key||/input|select|option|textarea|form/i.test(e.target.tagName)))continue;const o={relatedTarget:t._element};"click"===e.type&&(o.clickEvent=e),t._completeHide(o)}}static dataApiKeydownHandler(e){const t=/input|textarea/i.test(e.target.tagName),r="Escape"===e.key,n=[Tr,qr].includes(e.key);if(!n&&!r)return;if(t&&!r)return;e.preventDefault();const i=this.matches(Br)?this:Et.prev(this,Br)[0]||Et.next(this,Br)[0]||Et.findOne(Br,e.delegateTarget.parentNode),o=Wr.getOrCreateInstance(i);if(n)return e.stopPropagation(),o.show(),void o._selectMenuItem(e);o._isShown()&&(e.stopPropagation(),o.hide(),i.focus())}}gt.on(document,Or,Br,Wr.dataApiKeydownHandler),gt.on(document,Or,Ir,Wr.dataApiKeydownHandler),gt.on(document,Nr,Wr.clearMenus),gt.on(document,jr,Wr.clearMenus),gt.on(document,Nr,Br,(function(e){e.preventDefault(),Wr.getOrCreateInstance(this).toggle()})),Ke(Wr);const Yr="backdrop",Xr="show",Kr=`mousedown.bs.${Yr}`,Jr={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Qr={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Zr extends wt{constructor(e){super(),this._config=this._getConfig(e),this._isAppended=!1,this._element=null}static get Default(){return Jr}static get DefaultType(){return Qr}static get NAME(){return Yr}show(e){if(!this._config.isVisible)return void Je(e);this._append();const t=this._getElement();this._config.isAnimated&&Ge(t),t.classList.add(Xr),this._emulateAnimation((()=>{Je(e)}))}hide(e){this._config.isVisible?(this._getElement().classList.remove(Xr),this._emulateAnimation((()=>{this.dispose(),Je(e)}))):Je(e)}dispose(){this._isAppended&&(gt.off(this._element,Kr),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const e=document.createElement("div");e.className=this._config.className,this._config.isAnimated&&e.classList.add("fade"),this._element=e}return this._element}_configAfterMerge(e){return e.rootElement=Me(e.rootElement),e}_append(){if(this._isAppended)return;const e=this._getElement();this._config.rootElement.append(e),gt.on(e,Kr,(()=>{Je(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(e){Qe(e,this._getElement(),this._config.isAnimated)}}const en=".bs.focustrap",tn=`focusin${en}`,rn=`keydown.tab${en}`,nn="backward",on={autofocus:!0,trapElement:null},sn={autofocus:"boolean",trapElement:"element"};class an extends wt{constructor(e){super(),this._config=this._getConfig(e),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return on}static get DefaultType(){return sn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),gt.off(document,en),gt.on(document,tn,(e=>this._handleFocusin(e))),gt.on(document,rn,(e=>this._handleKeydown(e))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,gt.off(document,en))}_handleFocusin(e){const{trapElement:t}=this._config;if(e.target===document||e.target===t||t.contains(e.target))return;const r=Et.focusableChildren(t);0===r.length?t.focus():this._lastTabNavDirection===nn?r[r.length-1].focus():r[0].focus()}_handleKeydown(e){"Tab"===e.key&&(this._lastTabNavDirection=e.shiftKey?nn:"forward")}}const ln=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",cn=".sticky-top",un="padding-right",pn="margin-right";class dn{constructor(){this._element=document.body}getWidth(){const e=document.documentElement.clientWidth;return Math.abs(window.innerWidth-e)}hide(){const e=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,un,(t=>t+e)),this._setElementAttributes(ln,un,(t=>t+e)),this._setElementAttributes(cn,pn,(t=>t-e))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,un),this._resetElementAttributes(ln,un),this._resetElementAttributes(cn,pn)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(e,t,r){const n=this.getWidth();this._applyManipulationCallback(e,(e=>{if(e!==this._element&&window.innerWidth>e.clientWidth+n)return;this._saveInitialAttribute(e,t);const i=window.getComputedStyle(e).getPropertyValue(t);e.style.setProperty(t,`${r(Number.parseFloat(i))}px`)}))}_saveInitialAttribute(e,t){const r=e.style.getPropertyValue(t);r&&yt.setDataAttribute(e,t,r)}_resetElementAttributes(e,t){this._applyManipulationCallback(e,(e=>{const r=yt.getDataAttribute(e,t);null!==r?(yt.removeDataAttribute(e,t),e.style.setProperty(t,r)):e.style.removeProperty(t)}))}_applyManipulationCallback(e,t){if(He(e))t(e);else for(const r of Et.find(e,this._element))t(r)}}const fn=".bs.modal",hn=`hide${fn}`,gn=`hidePrevented${fn}`,mn=`hidden${fn}`,vn=`show${fn}`,bn=`shown${fn}`,yn=`resize${fn}`,wn=`click.dismiss${fn}`,_n=`mousedown.dismiss${fn}`,xn=`keydown.dismiss${fn}`,En=`click${fn}.data-api`,An="modal-open",Dn="show",Tn="modal-static",qn={backdrop:!0,focus:!0,keyboard:!0},Cn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class kn extends _t{constructor(e,t){super(e,t),this._dialog=Et.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new dn,this._addEventListeners()}static get Default(){return qn}static get DefaultType(){return Cn}static get NAME(){return"modal"}toggle(e){return this._isShown?this.hide():this.show(e)}show(e){if(this._isShown||this._isTransitioning)return;gt.trigger(this._element,vn,{relatedTarget:e}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(An),this._adjustDialog(),this._backdrop.show((()=>this._showElement(e))))}hide(){if(!this._isShown||this._isTransitioning)return;gt.trigger(this._element,hn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(Dn),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated()))}dispose(){gt.off(window,fn),gt.off(this._dialog,fn),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Zr({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new an({trapElement:this._element})}_showElement(e){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const t=Et.findOne(".modal-body",this._dialog);t&&(t.scrollTop=0),Ge(this._element),this._element.classList.add(Dn);this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,gt.trigger(this._element,bn,{relatedTarget:e})}),this._dialog,this._isAnimated())}_addEventListeners(){gt.on(this._element,xn,(e=>{"Escape"===e.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),gt.on(window,yn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),gt.on(this._element,_n,(e=>{gt.one(this._element,wn,(t=>{this._element===e.target&&this._element===t.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(An),this._resetAdjustments(),this._scrollBar.reset(),gt.trigger(this._element,mn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(gt.trigger(this._element,gn).defaultPrevented)return;const e=this._element.scrollHeight>document.documentElement.clientHeight,t=this._element.style.overflowY;"hidden"===t||this._element.classList.contains(Tn)||(e||(this._element.style.overflowY="hidden"),this._element.classList.add(Tn),this._queueCallback((()=>{this._element.classList.remove(Tn),this._queueCallback((()=>{this._element.style.overflowY=t}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const e=this._element.scrollHeight>document.documentElement.clientHeight,t=this._scrollBar.getWidth(),r=t>0;if(r&&!e){const e=Xe()?"paddingLeft":"paddingRight";this._element.style[e]=`${t}px`}if(!r&&e){const e=Xe()?"paddingRight":"paddingLeft";this._element.style[e]=`${t}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(e,t){return this.each((function(){const r=kn.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===r[e])throw new TypeError(`No method named "${e}"`);r[e](t)}}))}}gt.on(document,En,'[data-bs-toggle="modal"]',(function(e){const t=Et.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&e.preventDefault(),gt.one(t,vn,(e=>{e.defaultPrevented||gt.one(t,mn,(()=>{Ue(this)&&this.focus()}))}));const r=Et.findOne(".modal.show");r&&kn.getInstance(r).hide();kn.getOrCreateInstance(t).toggle(this)})),At(kn),Ke(kn);const Sn=".bs.offcanvas",Ln=".data-api",Nn=`load${Sn}${Ln}`,On="show",jn="showing",Rn="hiding",Bn=".offcanvas.show",Fn=`show${Sn}`,In=`shown${Sn}`,Pn=`hide${Sn}`,Hn=`hidePrevented${Sn}`,Mn=`hidden${Sn}`,Un=`resize${Sn}`,Vn=`click${Sn}${Ln}`,$n=`keydown.dismiss${Sn}`,zn={backdrop:!0,keyboard:!0,scroll:!1},Gn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Wn extends _t{constructor(e,t){super(e,t),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return zn}static get DefaultType(){return Gn}static get NAME(){return"offcanvas"}toggle(e){return this._isShown?this.hide():this.show(e)}show(e){if(this._isShown)return;if(gt.trigger(this._element,Fn,{relatedTarget:e}).defaultPrevented)return;this._isShown=!0,this._backdrop.show(),this._config.scroll||(new dn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(jn);this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(On),this._element.classList.remove(jn),gt.trigger(this._element,In,{relatedTarget:e})}),this._element,!0)}hide(){if(!this._isShown)return;if(gt.trigger(this._element,Pn).defaultPrevented)return;this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(Rn),this._backdrop.hide();this._queueCallback((()=>{this._element.classList.remove(On,Rn),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new dn).reset(),gt.trigger(this._element,Mn)}),this._element,!0)}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const e=Boolean(this._config.backdrop);return new Zr({className:"offcanvas-backdrop",isVisible:e,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:e?()=>{"static"!==this._config.backdrop?this.hide():gt.trigger(this._element,Hn)}:null})}_initializeFocusTrap(){return new an({trapElement:this._element})}_addEventListeners(){gt.on(this._element,$n,(e=>{"Escape"===e.key&&(this._config.keyboard?this.hide():gt.trigger(this._element,Hn))}))}static jQueryInterface(e){return this.each((function(){const t=Wn.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e]||e.startsWith("_")||"constructor"===e)throw new TypeError(`No method named "${e}"`);t[e](this)}}))}}gt.on(document,Vn,'[data-bs-toggle="offcanvas"]',(function(e){const t=Et.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&e.preventDefault(),Ve(this))return;gt.one(t,Mn,(()=>{Ue(this)&&this.focus()}));const r=Et.findOne(Bn);r&&r!==t&&Wn.getInstance(r).hide();Wn.getOrCreateInstance(t).toggle(this)})),gt.on(window,Nn,(()=>{for(const e of Et.find(Bn))Wn.getOrCreateInstance(e).show()})),gt.on(window,Un,(()=>{for(const e of Et.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(e).position&&Wn.getOrCreateInstance(e).hide()})),At(Wn),Ke(Wn);const Yn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Xn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Kn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Jn=(e,t)=>{const r=e.nodeName.toLowerCase();return t.includes(r)?!Xn.has(r)||Boolean(Kn.test(e.nodeValue)):t.filter((e=>e instanceof RegExp)).some((e=>e.test(r)))};const Qn={allowList:Yn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Zn={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},ei={entry:"(string|element|function|null)",selector:"(string|element)"};class ti extends wt{constructor(e){super(),this._config=this._getConfig(e)}static get Default(){return Qn}static get DefaultType(){return Zn}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((e=>this._resolvePossibleFunction(e))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(e){return this._checkContent(e),this._config.content={...this._config.content,...e},this}toHtml(){const e=document.createElement("div");e.innerHTML=this._maybeSanitize(this._config.template);for(const[t,r]of Object.entries(this._config.content))this._setContent(e,r,t);const t=e.children[0],r=this._resolvePossibleFunction(this._config.extraClass);return r&&t.classList.add(...r.split(" ")),t}_typeCheckConfig(e){super._typeCheckConfig(e),this._checkContent(e.content)}_checkContent(e){for(const[t,r]of Object.entries(e))super._typeCheckConfig({selector:t,entry:r},ei)}_setContent(e,t,r){const n=Et.findOne(r,e);n&&((t=this._resolvePossibleFunction(t))?He(t)?this._putElementInTemplate(Me(t),n):this._config.html?n.innerHTML=this._maybeSanitize(t):n.textContent=t:n.remove())}_maybeSanitize(e){return this._config.sanitize?function(e,t,r){if(!e.length)return e;if(r&&"function"==typeof r)return r(e);const n=(new window.DOMParser).parseFromString(e,"text/html"),i=[].concat(...n.body.querySelectorAll("*"));for(const e of i){const r=e.nodeName.toLowerCase();if(!Object.keys(t).includes(r)){e.remove();continue}const n=[].concat(...e.attributes),i=[].concat(t["*"]||[],t[r]||[]);for(const t of n)Jn(t,i)||e.removeAttribute(t.nodeName)}return n.body.innerHTML}(e,this._config.allowList,this._config.sanitizeFn):e}_resolvePossibleFunction(e){return Je(e,[this])}_putElementInTemplate(e,t){if(this._config.html)return t.innerHTML="",void t.append(e);t.textContent=e.textContent}}const ri=new Set(["sanitize","allowList","sanitizeFn"]),ni="fade",ii="show",oi=".modal",si="hide.bs.modal",ai="hover",li="focus",ci={AUTO:"auto",TOP:"top",RIGHT:Xe()?"left":"right",BOTTOM:"bottom",LEFT:Xe()?"right":"left"},ui={allowList:Yn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},pi={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class di extends _t{constructor(e,t){if(void 0===n)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(e,t),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return ui}static get DefaultType(){return pi}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),gt.off(this._element.closest(oi),si,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const e=gt.trigger(this._element,this.constructor.eventName("show")),t=($e(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(e.defaultPrevented||!t)return;this._disposePopper();const r=this._getTipElement();this._element.setAttribute("aria-describedby",r.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(r),gt.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(r),r.classList.add(ii),"ontouchstart"in document.documentElement)for(const e of[].concat(...document.body.children))gt.on(e,"mouseover",ze);this._queueCallback((()=>{gt.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(!this._isShown())return;if(gt.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented)return;if(this._getTipElement().classList.remove(ii),"ontouchstart"in document.documentElement)for(const e of[].concat(...document.body.children))gt.off(e,"mouseover",ze);this._activeTrigger.click=!1,this._activeTrigger[li]=!1,this._activeTrigger[ai]=!1,this._isHovered=null;this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),gt.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(e){const t=this._getTemplateFactory(e).toHtml();if(!t)return null;t.classList.remove(ni,ii),t.classList.add(`bs-${this.constructor.NAME}-auto`);const r=(e=>{do{e+=Math.floor(1e6*Math.random())}while(document.getElementById(e));return e})(this.constructor.NAME).toString();return t.setAttribute("id",r),this._isAnimated()&&t.classList.add(ni),t}setContent(e){this._newContent=e,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(e){return this._templateFactory?this._templateFactory.changeContent(e):this._templateFactory=new ti({...this._config,content:e,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(e){return this.constructor.getOrCreateInstance(e.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(ni)}_isShown(){return this.tip&&this.tip.classList.contains(ii)}_createPopper(e){const t=Je(this._config.placement,[this,e,this._element]),r=ci[t.toUpperCase()];return Oe(this._element,e,this._getPopperConfig(r))}_getOffset(){const{offset:e}=this._config;return"string"==typeof e?e.split(",").map((e=>Number.parseInt(e,10))):"function"==typeof e?t=>e(t,this._element):e}_resolvePossibleFunction(e){return Je(e,[this._element])}_getPopperConfig(e){const t={placement:e,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:e=>{this._getTipElement().setAttribute("data-popper-placement",e.state.placement)}}]};return{...t,...Je(this._config.popperConfig,[t])}}_setListeners(){const e=this._config.trigger.split(" ");for(const t of e)if("click"===t)gt.on(this._element,this.constructor.eventName("click"),this._config.selector,(e=>{this._initializeOnDelegatedTarget(e).toggle()}));else if("manual"!==t){const e=t===ai?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),r=t===ai?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");gt.on(this._element,e,this._config.selector,(e=>{const t=this._initializeOnDelegatedTarget(e);t._activeTrigger["focusin"===e.type?li:ai]=!0,t._enter()})),gt.on(this._element,r,this._config.selector,(e=>{const t=this._initializeOnDelegatedTarget(e);t._activeTrigger["focusout"===e.type?li:ai]=t._element.contains(e.relatedTarget),t._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},gt.on(this._element.closest(oi),si,this._hideModalHandler)}_fixTitle(){const e=this._element.getAttribute("title");e&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",e),this._element.setAttribute("data-bs-original-title",e),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(e,t){clearTimeout(this._timeout),this._timeout=setTimeout(e,t)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(e){const t=yt.getDataAttributes(this._element);for(const e of Object.keys(t))ri.has(e)&&delete t[e];return e={...t,..."object"==typeof e&&e?e:{}},e=this._mergeConfigObj(e),e=this._configAfterMerge(e),this._typeCheckConfig(e),e}_configAfterMerge(e){return e.container=!1===e.container?document.body:Me(e.container),"number"==typeof e.delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),e}_getDelegateConfig(){const e={};for(const[t,r]of Object.entries(this._config))this.constructor.Default[t]!==r&&(e[t]=r);return e.selector=!1,e.trigger="manual",e}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(e){return this.each((function(){const t=di.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e])throw new TypeError(`No method named "${e}"`);t[e]()}}))}}Ke(di);const fi={...di.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},hi={...di.DefaultType,content:"(null|string|element|function)"};class gi extends di{static get Default(){return fi}static get DefaultType(){return hi}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(e){return this.each((function(){const t=gi.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e])throw new TypeError(`No method named "${e}"`);t[e]()}}))}}Ke(gi);const mi=".bs.scrollspy",vi=`activate${mi}`,bi=`click${mi}`,yi=`load${mi}.data-api`,wi="active",_i="[href]",xi=".nav-link",Ei=`${xi}, .nav-item > ${xi}, .list-group-item`,Ai={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},Di={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Ti extends _t{constructor(e,t){super(e,t),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return Ai}static get DefaultType(){return Di}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const e of this._observableSections.values())this._observer.observe(e)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(e){return e.target=Me(e.target)||document.body,e.rootMargin=e.offset?`${e.offset}px 0px -30%`:e.rootMargin,"string"==typeof e.threshold&&(e.threshold=e.threshold.split(",").map((e=>Number.parseFloat(e)))),e}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(gt.off(this._config.target,bi),gt.on(this._config.target,bi,_i,(e=>{const t=this._observableSections.get(e.target.hash);if(t){e.preventDefault();const r=this._rootElement||window,n=t.offsetTop-this._element.offsetTop;if(r.scrollTo)return void r.scrollTo({top:n,behavior:"smooth"});r.scrollTop=n}})))}_getNewObserver(){const e={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((e=>this._observerCallback(e)),e)}_observerCallback(e){const t=e=>this._targetLinks.get(`#${e.target.id}`),r=e=>{this._previousScrollData.visibleEntryTop=e.target.offsetTop,this._process(t(e))},n=(this._rootElement||document.documentElement).scrollTop,i=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of e){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(t(o));continue}const e=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(i&&e){if(r(o),!n)return}else i||e||r(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const e=Et.find(_i,this._config.target);for(const t of e){if(!t.hash||Ve(t))continue;const e=Et.findOne(decodeURI(t.hash),this._element);Ue(e)&&(this._targetLinks.set(decodeURI(t.hash),t),this._observableSections.set(t.hash,e))}}_process(e){this._activeTarget!==e&&(this._clearActiveClass(this._config.target),this._activeTarget=e,e.classList.add(wi),this._activateParents(e),gt.trigger(this._element,vi,{relatedTarget:e}))}_activateParents(e){if(e.classList.contains("dropdown-item"))Et.findOne(".dropdown-toggle",e.closest(".dropdown")).classList.add(wi);else for(const t of Et.parents(e,".nav, .list-group"))for(const e of Et.prev(t,Ei))e.classList.add(wi)}_clearActiveClass(e){e.classList.remove(wi);const t=Et.find(`${_i}.${wi}`,e);for(const e of t)e.classList.remove(wi)}static jQueryInterface(e){return this.each((function(){const t=Ti.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e]||e.startsWith("_")||"constructor"===e)throw new TypeError(`No method named "${e}"`);t[e]()}}))}}gt.on(window,yi,(()=>{for(const e of Et.find('[data-bs-spy="scroll"]'))Ti.getOrCreateInstance(e)})),Ke(Ti);const qi=".bs.tab",Ci=`hide${qi}`,ki=`hidden${qi}`,Si=`show${qi}`,Li=`shown${qi}`,Ni=`click${qi}`,Oi=`keydown${qi}`,ji=`load${qi}`,Ri="ArrowLeft",Bi="ArrowRight",Fi="ArrowUp",Ii="ArrowDown",Pi="Home",Hi="End",Mi="active",Ui="fade",Vi="show",$i=".dropdown-toggle",zi=`:not(${$i})`,Gi='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Wi=`${`.nav-link${zi}, .list-group-item${zi}, [role="tab"]${zi}`}, ${Gi}`,Yi=`.${Mi}[data-bs-toggle="tab"], .${Mi}[data-bs-toggle="pill"], .${Mi}[data-bs-toggle="list"]`;class Xi extends _t{constructor(e){super(e),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),gt.on(this._element,Oi,(e=>this._keydown(e))))}static get NAME(){return"tab"}show(){const e=this._element;if(this._elemIsActive(e))return;const t=this._getActiveElem(),r=t?gt.trigger(t,Ci,{relatedTarget:e}):null;gt.trigger(e,Si,{relatedTarget:t}).defaultPrevented||r&&r.defaultPrevented||(this._deactivate(t,e),this._activate(e,t))}_activate(e,t){if(!e)return;e.classList.add(Mi),this._activate(Et.getElementFromSelector(e));this._queueCallback((()=>{"tab"===e.getAttribute("role")?(e.removeAttribute("tabindex"),e.setAttribute("aria-selected",!0),this._toggleDropDown(e,!0),gt.trigger(e,Li,{relatedTarget:t})):e.classList.add(Vi)}),e,e.classList.contains(Ui))}_deactivate(e,t){if(!e)return;e.classList.remove(Mi),e.blur(),this._deactivate(Et.getElementFromSelector(e));this._queueCallback((()=>{"tab"===e.getAttribute("role")?(e.setAttribute("aria-selected",!1),e.setAttribute("tabindex","-1"),this._toggleDropDown(e,!1),gt.trigger(e,ki,{relatedTarget:t})):e.classList.remove(Vi)}),e,e.classList.contains(Ui))}_keydown(e){if(![Ri,Bi,Fi,Ii,Pi,Hi].includes(e.key))return;e.stopPropagation(),e.preventDefault();const t=this._getChildren().filter((e=>!Ve(e)));let r;if([Pi,Hi].includes(e.key))r=t[e.key===Pi?0:t.length-1];else{const n=[Bi,Ii].includes(e.key);r=Ze(t,e.target,n,!0)}r&&(r.focus({preventScroll:!0}),Xi.getOrCreateInstance(r).show())}_getChildren(){return Et.find(Wi,this._parent)}_getActiveElem(){return this._getChildren().find((e=>this._elemIsActive(e)))||null}_setInitialAttributes(e,t){this._setAttributeIfNotExists(e,"role","tablist");for(const e of t)this._setInitialAttributesOnChild(e)}_setInitialAttributesOnChild(e){e=this._getInnerElement(e);const t=this._elemIsActive(e),r=this._getOuterElement(e);e.setAttribute("aria-selected",t),r!==e&&this._setAttributeIfNotExists(r,"role","presentation"),t||e.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(e,"role","tab"),this._setInitialAttributesOnTargetPanel(e)}_setInitialAttributesOnTargetPanel(e){const t=Et.getElementFromSelector(e);t&&(this._setAttributeIfNotExists(t,"role","tabpanel"),e.id&&this._setAttributeIfNotExists(t,"aria-labelledby",`${e.id}`))}_toggleDropDown(e,t){const r=this._getOuterElement(e);if(!r.classList.contains("dropdown"))return;const n=(e,n)=>{const i=Et.findOne(e,r);i&&i.classList.toggle(n,t)};n($i,Mi),n(".dropdown-menu",Vi),r.setAttribute("aria-expanded",t)}_setAttributeIfNotExists(e,t,r){e.hasAttribute(t)||e.setAttribute(t,r)}_elemIsActive(e){return e.classList.contains(Mi)}_getInnerElement(e){return e.matches(Wi)?e:Et.findOne(Wi,e)}_getOuterElement(e){return e.closest(".nav-item, .list-group-item")||e}static jQueryInterface(e){return this.each((function(){const t=Xi.getOrCreateInstance(this);if("string"==typeof e){if(void 0===t[e]||e.startsWith("_")||"constructor"===e)throw new TypeError(`No method named "${e}"`);t[e]()}}))}}gt.on(document,Ni,Gi,(function(e){["A","AREA"].includes(this.tagName)&&e.preventDefault(),Ve(this)||Xi.getOrCreateInstance(this).show()})),gt.on(window,ji,(()=>{for(const e of Et.find(Yi))Xi.getOrCreateInstance(e)})),Ke(Xi);const Ki=".bs.toast",Ji=`mouseover${Ki}`,Qi=`mouseout${Ki}`,Zi=`focusin${Ki}`,eo=`focusout${Ki}`,to=`hide${Ki}`,ro=`hidden${Ki}`,no=`show${Ki}`,io=`shown${Ki}`,oo="hide",so="show",ao="showing",lo={animation:"boolean",autohide:"boolean",delay:"number"},co={animation:!0,autohide:!0,delay:5e3};class uo extends _t{constructor(e,t){super(e,t),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return co}static get DefaultType(){return lo}static get NAME(){return"toast"}show(){if(gt.trigger(this._element,no).defaultPrevented)return;this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");this._element.classList.remove(oo),Ge(this._element),this._element.classList.add(so,ao),this._queueCallback((()=>{this._element.classList.remove(ao),gt.trigger(this._element,io),this._maybeScheduleHide()}),this._element,this._config.animation)}hide(){if(!this.isShown())return;if(gt.trigger(this._element,to).defaultPrevented)return;this._element.classList.add(ao),this._queueCallback((()=>{this._element.classList.add(oo),this._element.classList.remove(ao,so),gt.trigger(this._element,ro)}),this._element,this._config.animation)}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(so),super.dispose()}isShown(){return this._element.classList.contains(so)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(e,t){switch(e.type){case"mouseover":case"mouseout":this._hasMouseInteraction=t;break;case"focusin":case"focusout":this._hasKeyboardInteraction=t}if(t)return void this._clearTimeout();const r=e.relatedTarget;this._element===r||this._element.contains(r)||this._maybeScheduleHide()}_setListeners(){gt.on(this._element,Ji,(e=>this._onInteraction(e,!0))),gt.on(this._element,Qi,(e=>this._onInteraction(e,!1))),gt.on(this._element,Zi,(e=>this._onInteraction(e,!0))),gt.on(this._element,eo,(e=>this._onInteraction(e,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(e){return this.each((function(){const t=uo.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e])throw new TypeError(`No method named "${e}"`);t[e](this)}}))}}At(uo),Ke(uo)},702:function(e,t,r){e.exports=function(){"use strict";function e(e){var t=typeof e;return null!==e&&("object"===t||"function"===t)}function t(e){return"function"==typeof e}var n=Array.isArray?Array.isArray:function(e){return"[object Array]"===Object.prototype.toString.call(e)},i=0,o=void 0,s=void 0,a=function(e,t){w[i]=e,w[i+1]=t,2===(i+=2)&&(s?s(_):E())};function l(e){s=e}function c(e){a=e}var u="undefined"!=typeof window?window:void 0,p=u||{},d=p.MutationObserver||p.WebKitMutationObserver,f="undefined"==typeof self&&"undefined"!=typeof process&&"[object process]"==={}.toString.call(process),h="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel;function g(){return function(){return process.nextTick(_)}}function m(){return void 0!==o?function(){o(_)}:y()}function v(){var e=0,t=new d(_),r=document.createTextNode("");return t.observe(r,{characterData:!0}),function(){r.data=e=++e%2}}function b(){var e=new MessageChannel;return e.port1.onmessage=_,function(){return e.port2.postMessage(0)}}function y(){var e=setTimeout;return function(){return e(_,1)}}var w=new Array(1e3);function _(){for(var e=0;e\u20D2|\u205F\u200A|\u219D\u0338|\u2202\u0338|\u2220\u20D2|\u2229\uFE00|\u222A\uFE00|\u223C\u20D2|\u223D\u0331|\u223E\u0333|\u2242\u0338|\u224B\u0338|\u224D\u20D2|\u224E\u0338|\u224F\u0338|\u2250\u0338|\u2261\u20E5|\u2264\u20D2|\u2265\u20D2|\u2266\u0338|\u2267\u0338|\u2268\uFE00|\u2269\uFE00|\u226A\u0338|\u226A\u20D2|\u226B\u0338|\u226B\u20D2|\u227F\u0338|\u2282\u20D2|\u2283\u20D2|\u228A\uFE00|\u228B\uFE00|\u228F\u0338|\u2290\u0338|\u2293\uFE00|\u2294\uFE00|\u22B4\u20D2|\u22B5\u20D2|\u22D8\u0338|\u22D9\u0338|\u22DA\uFE00|\u22DB\uFE00|\u22F5\u0338|\u22F9\u0338|\u2933\u0338|\u29CF\u0338|\u29D0\u0338|\u2A6D\u0338|\u2A70\u0338|\u2A7D\u0338|\u2A7E\u0338|\u2AA1\u0338|\u2AA2\u0338|\u2AAC\uFE00|\u2AAD\uFE00|\u2AAF\u0338|\u2AB0\u0338|\u2AC5\u0338|\u2AC6\u0338|\u2ACB\uFE00|\u2ACC\uFE00|\u2AFD\u20E5|[\xA0-\u0113\u0116-\u0122\u0124-\u012B\u012E-\u014D\u0150-\u017E\u0192\u01B5\u01F5\u0237\u02C6\u02C7\u02D8-\u02DD\u0311\u0391-\u03A1\u03A3-\u03A9\u03B1-\u03C9\u03D1\u03D2\u03D5\u03D6\u03DC\u03DD\u03F0\u03F1\u03F5\u03F6\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E\u045F\u2002-\u2005\u2007-\u2010\u2013-\u2016\u2018-\u201A\u201C-\u201E\u2020-\u2022\u2025\u2026\u2030-\u2035\u2039\u203A\u203E\u2041\u2043\u2044\u204F\u2057\u205F-\u2063\u20AC\u20DB\u20DC\u2102\u2105\u210A-\u2113\u2115-\u211E\u2122\u2124\u2127-\u2129\u212C\u212D\u212F-\u2131\u2133-\u2138\u2145-\u2148\u2153-\u215E\u2190-\u219B\u219D-\u21A7\u21A9-\u21AE\u21B0-\u21B3\u21B5-\u21B7\u21BA-\u21DB\u21DD\u21E4\u21E5\u21F5\u21FD-\u2205\u2207-\u2209\u220B\u220C\u220F-\u2214\u2216-\u2218\u221A\u221D-\u2238\u223A-\u2257\u2259\u225A\u225C\u225F-\u2262\u2264-\u228B\u228D-\u229B\u229D-\u22A5\u22A7-\u22B0\u22B2-\u22BB\u22BD-\u22DB\u22DE-\u22E3\u22E6-\u22F7\u22F9-\u22FE\u2305\u2306\u2308-\u2310\u2312\u2313\u2315\u2316\u231C-\u231F\u2322\u2323\u232D\u232E\u2336\u233D\u233F\u237C\u23B0\u23B1\u23B4-\u23B6\u23DC-\u23DF\u23E2\u23E7\u2423\u24C8\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2550-\u256C\u2580\u2584\u2588\u2591-\u2593\u25A1\u25AA\u25AB\u25AD\u25AE\u25B1\u25B3-\u25B5\u25B8\u25B9\u25BD-\u25BF\u25C2\u25C3\u25CA\u25CB\u25EC\u25EF\u25F8-\u25FC\u2605\u2606\u260E\u2640\u2642\u2660\u2663\u2665\u2666\u266A\u266D-\u266F\u2713\u2717\u2720\u2736\u2758\u2772\u2773\u27C8\u27C9\u27E6-\u27ED\u27F5-\u27FA\u27FC\u27FF\u2902-\u2905\u290C-\u2913\u2916\u2919-\u2920\u2923-\u292A\u2933\u2935-\u2939\u293C\u293D\u2945\u2948-\u294B\u294E-\u2976\u2978\u2979\u297B-\u297F\u2985\u2986\u298B-\u2996\u299A\u299C\u299D\u29A4-\u29B7\u29B9\u29BB\u29BC\u29BE-\u29C5\u29C9\u29CD-\u29D0\u29DC-\u29DE\u29E3-\u29E5\u29EB\u29F4\u29F6\u2A00-\u2A02\u2A04\u2A06\u2A0C\u2A0D\u2A10-\u2A17\u2A22-\u2A27\u2A29\u2A2A\u2A2D-\u2A31\u2A33-\u2A3C\u2A3F\u2A40\u2A42-\u2A4D\u2A50\u2A53-\u2A58\u2A5A-\u2A5D\u2A5F\u2A66\u2A6A\u2A6D-\u2A75\u2A77-\u2A9A\u2A9D-\u2AA2\u2AA4-\u2AB0\u2AB3-\u2AC8\u2ACB\u2ACC\u2ACF-\u2ADB\u2AE4\u2AE6-\u2AE9\u2AEB-\u2AF3\u2AFD\uFB00-\uFB04]|\uD835[\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDD6B]/g,p={"­":"shy","‌":"zwnj","â€":"zwj","‎":"lrm","â£":"ic","â¢":"it","â¡":"af","â€":"rlm","​":"ZeroWidthSpace","â ":"NoBreak","Ì‘":"DownBreve","⃛":"tdot","⃜":"DotDot","\t":"Tab","\n":"NewLine"," ":"puncsp","âŸ":"MediumSpace"," ":"thinsp"," ":"hairsp"," ":"emsp13"," ":"ensp"," ":"emsp14"," ":"emsp"," ":"numsp"," ":"nbsp","âŸâ€Š":"ThickSpace","‾":"oline",_:"lowbar","â€":"dash","–":"ndash","—":"mdash","―":"horbar",",":"comma",";":"semi","â":"bsemi",":":"colon","â©´":"Colone","!":"excl","¡":"iexcl","?":"quest","¿":"iquest",".":"period","‥":"nldr","…":"mldr","·":"middot","'":"apos","‘":"lsquo","’":"rsquo","‚":"sbquo","‹":"lsaquo","›":"rsaquo",'"':"quot","“":"ldquo","â€":"rdquo","„":"bdquo","«":"laquo","»":"raquo","(":"lpar",")":"rpar","[":"lsqb","]":"rsqb","{":"lcub","}":"rcub","⌈":"lceil","⌉":"rceil","⌊":"lfloor","⌋":"rfloor","⦅":"lopar","⦆":"ropar","⦋":"lbrke","⦌":"rbrke","â¦":"lbrkslu","⦎":"rbrksld","â¦":"lbrksld","â¦":"rbrkslu","⦑":"langd","⦒":"rangd","⦓":"lparlt","⦔":"rpargt","⦕":"gtlPar","⦖":"ltrPar","⟦":"lobrk","⟧":"robrk","⟨":"lang","⟩":"rang","⟪":"Lang","⟫":"Rang","⟬":"loang","⟭":"roang","â²":"lbbrk","â³":"rbbrk","‖":"Vert","§":"sect","¶":"para","@":"commat","*":"ast","/":"sol",undefined:null,"&":"amp","#":"num","%":"percnt","‰":"permil","‱":"pertenk","†":"dagger","‡":"Dagger","•":"bull","âƒ":"hybull","′":"prime","″":"Prime","‴":"tprime","â—":"qprime","‵":"bprime","â":"caret","`":"grave","´":"acute","Ëœ":"tilde","^":"Hat","¯":"macr","˘":"breve","Ë™":"dot","¨":"die","Ëš":"ring","Ë":"dblac","¸":"cedil","Ë›":"ogon",ˆ:"circ",ˇ:"caron","°":"deg","©":"copy","®":"reg","â„—":"copysr",℘:"wp","℞":"rx","â„§":"mho","â„©":"iiota","â†":"larr","↚":"nlarr","→":"rarr","↛":"nrarr","↑":"uarr","↓":"darr","↔":"harr","↮":"nharr","↕":"varr","↖":"nwarr","↗":"nearr","↘":"searr","↙":"swarr","â†":"rarrw","â†Ì¸":"nrarrw","↞":"Larr","↟":"Uarr","↠":"Rarr","↡":"Darr","↢":"larrtl","↣":"rarrtl","↤":"mapstoleft","↥":"mapstoup","↦":"map","↧":"mapstodown","↩":"larrhk","↪":"rarrhk","↫":"larrlp","↬":"rarrlp","↭":"harrw","↰":"lsh","↱":"rsh","↲":"ldsh","↳":"rdsh","↵":"crarr","↶":"cularr","↷":"curarr","↺":"olarr","↻":"orarr","↼":"lharu","↽":"lhard","↾":"uharr","↿":"uharl","⇀":"rharu","â‡":"rhard","⇂":"dharr","⇃":"dharl","⇄":"rlarr","⇅":"udarr","⇆":"lrarr","⇇":"llarr","⇈":"uuarr","⇉":"rrarr","⇊":"ddarr","⇋":"lrhar","⇌":"rlhar","â‡":"lArr","â‡":"nlArr","⇑":"uArr","⇒":"rArr","â‡":"nrArr","⇓":"dArr","⇔":"iff","⇎":"nhArr","⇕":"vArr","⇖":"nwArr","⇗":"neArr","⇘":"seArr","⇙":"swArr","⇚":"lAarr","⇛":"rAarr","â‡":"zigrarr","⇤":"larrb","⇥":"rarrb","⇵":"duarr","⇽":"loarr","⇾":"roarr","⇿":"hoarr","∀":"forall","âˆ":"comp","∂":"part","∂̸":"npart","∃":"exist","∄":"nexist","∅":"empty","∇":"Del","∈":"in","∉":"notin","∋":"ni","∌":"notni","϶":"bepsi","âˆ":"prod","âˆ":"coprod","∑":"sum","+":"plus","±":"pm","÷":"div","×":"times","<":"lt","≮":"nlt","<⃒":"nvlt","=":"equals","≠":"ne","=⃥":"bne","⩵":"Equal",">":"gt","≯":"ngt",">⃒":"nvgt","¬":"not","|":"vert","¦":"brvbar","−":"minus","∓":"mp","∔":"plusdo","â„":"frasl","∖":"setmn","∗":"lowast","∘":"compfn","√":"Sqrt","âˆ":"prop","∞":"infin","∟":"angrt","∠":"ang","∠⃒":"nang","∡":"angmsd","∢":"angsph","∣":"mid","∤":"nmid","∥":"par","∦":"npar","∧":"and","∨":"or","∩":"cap","∩︀":"caps","∪":"cup","∪︀":"cups","∫":"int","∬":"Int","∭":"tint","⨌":"qint","∮":"oint","∯":"Conint","∰":"Cconint","∱":"cwint","∲":"cwconint","∳":"awconint","∴":"there4","∵":"becaus","∶":"ratio","∷":"Colon","∸":"minusd","∺":"mDDot","∻":"homtht","∼":"sim","â‰":"nsim","∼⃒":"nvsim","∽":"bsim","∽̱":"race","∾":"ac","∾̳":"acE","∿":"acd","≀":"wr","≂":"esim","≂̸":"nesim","≃":"sime","≄":"nsime","≅":"cong","≇":"ncong","≆":"simne","≈":"ap","≉":"nap","≊":"ape","≋":"apid","≋̸":"napid","≌":"bcong","â‰":"CupCap","≭":"NotCupCap","â‰âƒ’":"nvap","≎":"bump","≎̸":"nbump","â‰":"bumpe","â‰Ì¸":"nbumpe","â‰":"doteq","â‰Ì¸":"nedot","≑":"eDot","≒":"efDot","≓":"erDot","≔":"colone","≕":"ecolon","≖":"ecir","≗":"cire","≙":"wedgeq","≚":"veeeq","≜":"trie","≟":"equest","≡":"equiv","≢":"nequiv","≡⃥":"bnequiv","≤":"le","≰":"nle","≤⃒":"nvle","≥":"ge","≱":"nge","≥⃒":"nvge","≦":"lE","≦̸":"nlE","≧":"gE","≧̸":"ngE","≨︀":"lvnE","≨":"lnE","≩":"gnE","≩︀":"gvnE","≪":"ll","≪̸":"nLtv","≪⃒":"nLt","≫":"gg","≫̸":"nGtv","≫⃒":"nGt","≬":"twixt","≲":"lsim","≴":"nlsim","≳":"gsim","≵":"ngsim","≶":"lg","≸":"ntlg","≷":"gl","≹":"ntgl","≺":"pr","⊀":"npr","≻":"sc","âŠ":"nsc","≼":"prcue","â‹ ":"nprcue","≽":"sccue","â‹¡":"nsccue","≾":"prsim","≿":"scsim","≿̸":"NotSucceedsTilde","⊂":"sub","⊄":"nsub","⊂⃒":"vnsub","⊃":"sup","⊅":"nsup","⊃⃒":"vnsup","⊆":"sube","⊈":"nsube","⊇":"supe","⊉":"nsupe","⊊︀":"vsubne","⊊":"subne","⊋︀":"vsupne","⊋":"supne","âŠ":"cupdot","⊎":"uplus","âŠ":"sqsub","âŠÌ¸":"NotSquareSubset","âŠ":"sqsup","âŠÌ¸":"NotSquareSuperset","⊑":"sqsube","â‹¢":"nsqsube","⊒":"sqsupe","â‹£":"nsqsupe","⊓":"sqcap","⊓︀":"sqcaps","⊔":"sqcup","⊔︀":"sqcups","⊕":"oplus","⊖":"ominus","⊗":"otimes","⊘":"osol","⊙":"odot","⊚":"ocir","⊛":"oast","âŠ":"odash","⊞":"plusb","⊟":"minusb","⊠":"timesb","⊡":"sdotb","⊢":"vdash","⊬":"nvdash","⊣":"dashv","⊤":"top","⊥":"bot","⊧":"models","⊨":"vDash","⊭":"nvDash","⊩":"Vdash","⊮":"nVdash","⊪":"Vvdash","⊫":"VDash","⊯":"nVDash","⊰":"prurel","⊲":"vltri","⋪":"nltri","⊳":"vrtri","â‹«":"nrtri","⊴":"ltrie","⋬":"nltrie","⊴⃒":"nvltrie","⊵":"rtrie","â‹­":"nrtrie","⊵⃒":"nvrtrie","⊶":"origof","⊷":"imof","⊸":"mumap","⊹":"hercon","⊺":"intcal","⊻":"veebar","⊽":"barvee","⊾":"angrtvb","⊿":"lrtri","â‹€":"Wedge","â‹":"Vee","â‹‚":"xcap","⋃":"xcup","â‹„":"diam","â‹…":"sdot","⋆":"Star","⋇":"divonx","⋈":"bowtie","⋉":"ltimes","⋊":"rtimes","â‹‹":"lthree","⋌":"rthree","â‹":"bsime","⋎":"cuvee","â‹":"cuwed","â‹":"Sub","â‹‘":"Sup","â‹’":"Cap","â‹“":"Cup","â‹”":"fork","â‹•":"epar","â‹–":"ltdot","â‹—":"gtdot","⋘":"Ll","⋘̸":"nLl","â‹™":"Gg","⋙̸":"nGg","⋚︀":"lesg","⋚":"leg","â‹›":"gel","⋛︀":"gesl","⋞":"cuepr","⋟":"cuesc","⋦":"lnsim","â‹§":"gnsim","⋨":"prnsim","â‹©":"scnsim","â‹®":"vellip","⋯":"ctdot","â‹°":"utdot","⋱":"dtdot","⋲":"disin","⋳":"isinsv","â‹´":"isins","⋵":"isindot","⋵̸":"notindot","â‹¶":"notinvc","â‹·":"notinvb","⋹":"isinE","⋹̸":"notinE","⋺":"nisd","â‹»":"xnis","⋼":"nis","⋽":"notnivc","⋾":"notnivb","⌅":"barwed","⌆":"Barwed","⌌":"drcrop","âŒ":"dlcrop","⌎":"urcrop","âŒ":"ulcrop","âŒ":"bnot","⌒":"profline","⌓":"profsurf","⌕":"telrec","⌖":"target","⌜":"ulcorn","âŒ":"urcorn","⌞":"dlcorn","⌟":"drcorn","⌢":"frown","⌣":"smile","⌭":"cylcty","⌮":"profalar","⌶":"topbot","⌽":"ovbar","⌿":"solbar","â¼":"angzarr","⎰":"lmoust","⎱":"rmoust","⎴":"tbrk","⎵":"bbrk","⎶":"bbrktbrk","âœ":"OverParenthesis","â":"UnderParenthesis","âž":"OverBrace","âŸ":"UnderBrace","â¢":"trpezium","â§":"elinters","â£":"blank","─":"boxh","│":"boxv","┌":"boxdr","â”":"boxdl","â””":"boxur","┘":"boxul","├":"boxvr","┤":"boxvl","┬":"boxhd","â”´":"boxhu","┼":"boxvh","â•":"boxH","â•‘":"boxV","â•’":"boxdR","â•“":"boxDr","â•”":"boxDR","â••":"boxdL","â•–":"boxDl","â•—":"boxDL","╘":"boxuR","â•™":"boxUr","╚":"boxUR","â•›":"boxuL","╜":"boxUl","â•":"boxUL","╞":"boxvR","╟":"boxVr","â• ":"boxVR","â•¡":"boxvL","â•¢":"boxVl","â•£":"boxVL","╤":"boxHd","â•¥":"boxhD","╦":"boxHD","â•§":"boxHu","╨":"boxhU","â•©":"boxHU","╪":"boxvH","â•«":"boxVh","╬":"boxVH","â–€":"uhblk","â–„":"lhblk","â–ˆ":"block","â–‘":"blk14","â–’":"blk12","â–“":"blk34","â–¡":"squ","â–ª":"squf","â–«":"EmptyVerySmallSquare","â–­":"rect","â–®":"marker","â–±":"fltns","â–³":"xutri","â–´":"utrif","â–µ":"utri","â–¸":"rtrif","â–¹":"rtri","â–½":"xdtri","â–¾":"dtrif","â–¿":"dtri","â—‚":"ltrif","â—ƒ":"ltri","â—Š":"loz","â—‹":"cir","â—¬":"tridot","â—¯":"xcirc","â—¸":"ultri","â—¹":"urtri","â—º":"lltri","â—»":"EmptySmallSquare","â—¼":"FilledSmallSquare","★":"starf","☆":"star","☎":"phone","♀":"female","♂":"male","â™ ":"spades","♣":"clubs","♥":"hearts","♦":"diams","♪":"sung","✓":"check","✗":"cross","✠":"malt","✶":"sext","â˜":"VerticalSeparator","⟈":"bsolhsub","⟉":"suphsol","⟵":"xlarr","⟶":"xrarr","⟷":"xharr","⟸":"xlArr","⟹":"xrArr","⟺":"xhArr","⟼":"xmap","⟿":"dzigrarr","⤂":"nvlArr","⤃":"nvrArr","⤄":"nvHarr","⤅":"Map","⤌":"lbarr","â¤":"rbarr","⤎":"lBarr","â¤":"rBarr","â¤":"RBarr","⤑":"DDotrahd","⤒":"UpArrowBar","⤓":"DownArrowBar","⤖":"Rarrtl","⤙":"latail","⤚":"ratail","⤛":"lAtail","⤜":"rAtail","â¤":"larrfs","⤞":"rarrfs","⤟":"larrbfs","⤠":"rarrbfs","⤣":"nwarhk","⤤":"nearhk","⤥":"searhk","⤦":"swarhk","⤧":"nwnear","⤨":"toea","⤩":"tosa","⤪":"swnwar","⤳":"rarrc","⤳̸":"nrarrc","⤵":"cudarrr","⤶":"ldca","⤷":"rdca","⤸":"cudarrl","⤹":"larrpl","⤼":"curarrm","⤽":"cularrp","⥅":"rarrpl","⥈":"harrcir","⥉":"Uarrocir","⥊":"lurdshar","⥋":"ldrushar","⥎":"LeftRightVector","â¥":"RightUpDownVector","â¥":"DownLeftRightVector","⥑":"LeftUpDownVector","⥒":"LeftVectorBar","⥓":"RightVectorBar","⥔":"RightUpVectorBar","⥕":"RightDownVectorBar","⥖":"DownLeftVectorBar","⥗":"DownRightVectorBar","⥘":"LeftUpVectorBar","⥙":"LeftDownVectorBar","⥚":"LeftTeeVector","⥛":"RightTeeVector","⥜":"RightUpTeeVector","â¥":"RightDownTeeVector","⥞":"DownLeftTeeVector","⥟":"DownRightTeeVector","⥠":"LeftUpTeeVector","⥡":"LeftDownTeeVector","⥢":"lHar","⥣":"uHar","⥤":"rHar","⥥":"dHar","⥦":"luruhar","⥧":"ldrdhar","⥨":"ruluhar","⥩":"rdldhar","⥪":"lharul","⥫":"llhard","⥬":"rharul","⥭":"lrhard","⥮":"udhar","⥯":"duhar","⥰":"RoundImplies","⥱":"erarr","⥲":"simrarr","⥳":"larrsim","⥴":"rarrsim","⥵":"rarrap","⥶":"ltlarr","⥸":"gtrarr","⥹":"subrarr","⥻":"suplarr","⥼":"lfisht","⥽":"rfisht","⥾":"ufisht","⥿":"dfisht","⦚":"vzigzag","⦜":"vangrt","â¦":"angrtvbd","⦤":"ange","⦥":"range","⦦":"dwangle","⦧":"uwangle","⦨":"angmsdaa","⦩":"angmsdab","⦪":"angmsdac","⦫":"angmsdad","⦬":"angmsdae","⦭":"angmsdaf","⦮":"angmsdag","⦯":"angmsdah","⦰":"bemptyv","⦱":"demptyv","⦲":"cemptyv","⦳":"raemptyv","⦴":"laemptyv","⦵":"ohbar","⦶":"omid","⦷":"opar","⦹":"operp","⦻":"olcross","⦼":"odsold","⦾":"olcir","⦿":"ofcir","â§€":"olt","â§":"ogt","â§‚":"cirscir","⧃":"cirE","â§„":"solb","â§…":"bsolb","⧉":"boxbox","â§":"trisb","â§Ž":"rtriltri","â§":"LeftTriangleBar","â§Ì¸":"NotLeftTriangleBar","â§":"RightTriangleBar","â§Ì¸":"NotRightTriangleBar","â§œ":"iinfin","â§":"infintie","â§ž":"nvinfin","â§£":"eparsl","⧤":"smeparsl","â§¥":"eqvparsl","â§«":"lozf","â§´":"RuleDelayed","â§¶":"dsol","⨀":"xodot","â¨":"xoplus","⨂":"xotime","⨄":"xuplus","⨆":"xsqcup","â¨":"fpartint","â¨":"cirfnint","⨑":"awint","⨒":"rppolint","⨓":"scpolint","⨔":"npolint","⨕":"pointint","⨖":"quatint","⨗":"intlarhk","⨢":"pluscir","⨣":"plusacir","⨤":"simplus","⨥":"plusdu","⨦":"plussim","⨧":"plustwo","⨩":"mcomma","⨪":"minusdu","⨭":"loplus","⨮":"roplus","⨯":"Cross","⨰":"timesd","⨱":"timesbar","⨳":"smashp","⨴":"lotimes","⨵":"rotimes","⨶":"otimesas","⨷":"Otimes","⨸":"odiv","⨹":"triplus","⨺":"triminus","⨻":"tritime","⨼":"iprod","⨿":"amalg","â©€":"capdot","â©‚":"ncup","⩃":"ncap","â©„":"capand","â©…":"cupor","⩆":"cupcap","⩇":"capcup","⩈":"cupbrcap","⩉":"capbrcup","⩊":"cupcup","â©‹":"capcap","⩌":"ccups","â©":"ccaps","â©":"ccupssm","â©“":"And","â©”":"Or","â©•":"andand","â©–":"oror","â©—":"orslope","⩘":"andslope","⩚":"andv","â©›":"orv","⩜":"andd","â©":"ord","⩟":"wedbar","⩦":"sdote","⩪":"simdot","â©­":"congdot","⩭̸":"ncongdot","â©®":"easter","⩯":"apacir","â©°":"apE","⩰̸":"napE","⩱":"eplus","⩲":"pluse","⩳":"Esim","â©·":"eDDot","⩸":"equivDD","⩹":"ltcir","⩺":"gtcir","â©»":"ltquest","⩼":"gtquest","⩽":"les","⩽̸":"nles","⩾":"ges","⩾̸":"nges","â©¿":"lesdot","⪀":"gesdot","âª":"lesdoto","⪂":"gesdoto","⪃":"lesdotor","⪄":"gesdotol","⪅":"lap","⪆":"gap","⪇":"lne","⪈":"gne","⪉":"lnap","⪊":"gnap","⪋":"lEg","⪌":"gEl","âª":"lsime","⪎":"gsime","âª":"lsimg","âª":"gsiml","⪑":"lgE","⪒":"glE","⪓":"lesges","⪔":"gesles","⪕":"els","⪖":"egs","⪗":"elsdot","⪘":"egsdot","⪙":"el","⪚":"eg","âª":"siml","⪞":"simg","⪟":"simlE","⪠":"simgE","⪡":"LessLess","⪡̸":"NotNestedLessLess","⪢":"GreaterGreater","⪢̸":"NotNestedGreaterGreater","⪤":"glj","⪥":"gla","⪦":"ltcc","⪧":"gtcc","⪨":"lescc","⪩":"gescc","⪪":"smt","⪫":"lat","⪬":"smte","⪬︀":"smtes","⪭":"late","⪭︀":"lates","⪮":"bumpE","⪯":"pre","⪯̸":"npre","⪰":"sce","⪰̸":"nsce","⪳":"prE","⪴":"scE","⪵":"prnE","⪶":"scnE","⪷":"prap","⪸":"scap","⪹":"prnap","⪺":"scnap","⪻":"Pr","⪼":"Sc","⪽":"subdot","⪾":"supdot","⪿":"subplus","â«€":"supplus","â«":"submult","â«‚":"supmult","⫃":"subedot","â«„":"supedot","â«…":"subE","⫅̸":"nsubE","⫆":"supE","⫆̸":"nsupE","⫇":"subsim","⫈":"supsim","⫋︀":"vsubnE","â«‹":"subnE","⫌︀":"vsupnE","⫌":"supnE","â«":"csub","â«":"csup","â«‘":"csube","â«’":"csupe","â«“":"subsup","â«”":"supsub","â«•":"subsub","â«–":"supsup","â«—":"suphsub","⫘":"supdsub","â«™":"forkv","⫚":"topfork","â«›":"mlcp","⫤":"Dashv","⫦":"Vdashl","â«§":"Barv","⫨":"vBar","â«©":"vBarv","â««":"Vbar","⫬":"Not","â«­":"bNot","â«®":"rnmid","⫯":"cirmid","â«°":"midcir","⫱":"topcir","⫲":"nhpar","⫳":"parsim","⫽":"parsl","⫽⃥":"nparsl","â™­":"flat","â™®":"natur","♯":"sharp","¤":"curren","¢":"cent",$:"dollar","£":"pound","Â¥":"yen","€":"euro","¹":"sup1","½":"half","â…“":"frac13","¼":"frac14","â…•":"frac15","â…™":"frac16","â…›":"frac18","²":"sup2","â…”":"frac23","â…–":"frac25","³":"sup3","¾":"frac34","â…—":"frac35","â…œ":"frac38","â…˜":"frac45","â…š":"frac56","â…":"frac58","â…ž":"frac78",ð’¶:"ascr",ð•’:"aopf",ð”ž:"afr",ð”¸:"Aopf",ð”„:"Afr",ð’œ:"Ascr",ª:"ordf",á:"aacute",Ã:"Aacute",à:"agrave",À:"Agrave",ă:"abreve",Ä‚:"Abreve",â:"acirc",Â:"Acirc",Ã¥:"aring",Ã…:"angst",ä:"auml",Ä:"Auml",ã:"atilde",Ã:"Atilde",Ä…:"aogon",Ä„:"Aogon",Ä:"amacr",Ä€:"Amacr",æ:"aelig",Æ:"AElig",ð’·:"bscr",ð•“:"bopf",ð”Ÿ:"bfr",ð”¹:"Bopf",ℬ:"Bscr",ð”…:"Bfr",ð” :"cfr",ð’¸:"cscr",ð•”:"copf",â„­:"Cfr",ð’ž:"Cscr",â„‚:"Copf",ć:"cacute",Ć:"Cacute",ĉ:"ccirc",Ĉ:"Ccirc",Ä:"ccaron",ÄŒ:"Ccaron",Ä‹:"cdot",ÄŠ:"Cdot",ç:"ccedil",Ç:"Ccedil","â„…":"incare",ð”¡:"dfr",â…†:"dd",ð••:"dopf",ð’¹:"dscr",ð’Ÿ:"Dscr",ð”‡:"Dfr",â……:"DD",ð”»:"Dopf",Ä:"dcaron",ÄŽ:"Dcaron",Ä‘:"dstrok",Ä:"Dstrok",ð:"eth",Ã:"ETH",â…‡:"ee",ℯ:"escr",ð”¢:"efr",ð•–:"eopf",â„°:"Escr",ð”ˆ:"Efr",ð”¼:"Eopf",é:"eacute",É:"Eacute",è:"egrave",È:"Egrave",ê:"ecirc",Ê:"Ecirc",Ä›:"ecaron",Äš:"Ecaron",ë:"euml",Ë:"Euml",Ä—:"edot",Ä–:"Edot",Ä™:"eogon",Ę:"Eogon",Ä“:"emacr",Ä’:"Emacr",ð”£:"ffr",ð•—:"fopf",ð’»:"fscr",ð”‰:"Ffr",ð”½:"Fopf",ℱ:"Fscr",ff:"fflig",ffi:"ffilig",ffl:"ffllig",ï¬:"filig",fj:"fjlig",fl:"fllig",Æ’:"fnof",ℊ:"gscr",ð•˜:"gopf",ð”¤:"gfr",ð’¢:"Gscr",ð”¾:"Gopf",ð”Š:"Gfr",ǵ:"gacute",ÄŸ:"gbreve",Äž:"Gbreve",Ä:"gcirc",Äœ:"Gcirc",Ä¡:"gdot",Ä :"Gdot",Ä¢:"Gcedil",ð”¥:"hfr",ℎ:"planckh",ð’½:"hscr",ð•™:"hopf",â„‹:"Hscr",ℌ:"Hfr",â„:"Hopf",Ä¥:"hcirc",Ĥ:"Hcirc",â„:"hbar",ħ:"hstrok",Ħ:"Hstrok",ð•š:"iopf",ð”¦:"ifr",ð’¾:"iscr",â…ˆ:"ii",ð•€:"Iopf",â„:"Iscr",â„‘:"Im",í:"iacute",Ã:"Iacute",ì:"igrave",ÃŒ:"Igrave",î:"icirc",ÃŽ:"Icirc",ï:"iuml",Ã:"Iuml",Ä©:"itilde",Ĩ:"Itilde",İ:"Idot",į:"iogon",Ä®:"Iogon",Ä«:"imacr",Ī:"Imacr",ij:"ijlig",IJ:"IJlig",ı:"imath",ð’¿:"jscr",ð•›:"jopf",ð”§:"jfr",ð’¥:"Jscr",ð”:"Jfr",ð•:"Jopf",ĵ:"jcirc",Ä´:"Jcirc",È·:"jmath",ð•œ:"kopf",ð“€:"kscr",ð”¨:"kfr",ð’¦:"Kscr",ð•‚:"Kopf",ð”Ž:"Kfr",Ä·:"kcedil",Ķ:"Kcedil",ð”©:"lfr",ð“:"lscr",â„“:"ell",ð•:"lopf",â„’:"Lscr",ð”:"Lfr",ð•ƒ:"Lopf",ĺ:"lacute",Ĺ:"Lacute",ľ:"lcaron",Ľ:"Lcaron",ļ:"lcedil",Ä»:"Lcedil",Å‚:"lstrok",Å:"Lstrok",Å€:"lmidot",Ä¿:"Lmidot",ð”ª:"mfr",ð•ž:"mopf",ð“‚:"mscr",ð”:"Mfr",ð•„:"Mopf",ℳ:"Mscr",ð”«:"nfr",ð•Ÿ:"nopf",ð“ƒ:"nscr",â„•:"Nopf",ð’©:"Nscr",ð”‘:"Nfr",Å„:"nacute",Ń:"Nacute",ň:"ncaron",Ň:"Ncaron",ñ:"ntilde",Ñ:"Ntilde",ņ:"ncedil",Å…:"Ncedil","â„–":"numero",Å‹:"eng",ÅŠ:"ENG",ð• :"oopf",ð”¬:"ofr",â„´:"oscr",ð’ª:"Oscr",ð”’:"Ofr",ð•†:"Oopf",º:"ordm",ó:"oacute",Ó:"Oacute",ò:"ograve",Ã’:"Ograve",ô:"ocirc",Ô:"Ocirc",ö:"ouml",Ö:"Ouml",Å‘:"odblac",Å:"Odblac",õ:"otilde",Õ:"Otilde",ø:"oslash",Ø:"Oslash",Å:"omacr",ÅŒ:"Omacr",Å“:"oelig",Å’:"OElig",ð”­:"pfr",ð“…:"pscr",ð•¡:"popf",â„™:"Popf",ð”“:"Pfr",ð’«:"Pscr",ð•¢:"qopf",ð”®:"qfr",ð“†:"qscr",ð’¬:"Qscr",ð””:"Qfr",ℚ:"Qopf",ĸ:"kgreen",ð”¯:"rfr",ð•£:"ropf",ð“‡:"rscr",â„›:"Rscr",ℜ:"Re",â„:"Ropf",Å•:"racute",Å”:"Racute",Å™:"rcaron",Ř:"Rcaron",Å—:"rcedil",Å–:"Rcedil",ð•¤:"sopf",ð“ˆ:"sscr",ð”°:"sfr",ð•Š:"Sopf",ð”–:"Sfr",ð’®:"Sscr","Ⓢ":"oS",Å›:"sacute",Åš:"Sacute",Å:"scirc",Åœ:"Scirc",Å¡:"scaron",Å :"Scaron",ÅŸ:"scedil",Åž:"Scedil",ß:"szlig",ð”±:"tfr",ð“‰:"tscr",ð•¥:"topf",ð’¯:"Tscr",ð”—:"Tfr",ð•‹:"Topf",Å¥:"tcaron",Ť:"Tcaron",Å£:"tcedil",Å¢:"Tcedil","â„¢":"trade",ŧ:"tstrok",Ŧ:"Tstrok",ð“Š:"uscr",ð•¦:"uopf",ð”²:"ufr",ð•Œ:"Uopf",ð”˜:"Ufr",ð’°:"Uscr",ú:"uacute",Ú:"Uacute",ù:"ugrave",Ù:"Ugrave",Å­:"ubreve",Ŭ:"Ubreve",û:"ucirc",Û:"Ucirc",ů:"uring",Å®:"Uring",ü:"uuml",Ü:"Uuml",ű:"udblac",Ű:"Udblac",Å©:"utilde",Ũ:"Utilde",ų:"uogon",Ų:"Uogon",Å«:"umacr",Ū:"Umacr",ð”³:"vfr",ð•§:"vopf",ð“‹:"vscr",ð”™:"Vfr",ð•:"Vopf",ð’±:"Vscr",ð•¨:"wopf",ð“Œ:"wscr",ð”´:"wfr",ð’²:"Wscr",ð•Ž:"Wopf",ð”š:"Wfr",ŵ:"wcirc",Å´:"Wcirc",ð”µ:"xfr",ð“:"xscr",ð•©:"xopf",ð•:"Xopf",ð”›:"Xfr",ð’³:"Xscr",ð”¶:"yfr",ð“Ž:"yscr",ð•ª:"yopf",ð’´:"Yscr",ð”œ:"Yfr",ð•:"Yopf",ý:"yacute",Ã:"Yacute",Å·:"ycirc",Ŷ:"Ycirc",ÿ:"yuml",Ÿ:"Yuml",ð“:"zscr",ð”·:"zfr",ð•«:"zopf",ℨ:"Zfr",ℤ:"Zopf",ð’µ:"Zscr",ź:"zacute",Ź:"Zacute",ž:"zcaron",Ž:"Zcaron",ż:"zdot",Å»:"Zdot",Ƶ:"imped",þ:"thorn",Þ:"THORN",ʼn:"napos",α:"alpha",Α:"Alpha",β:"beta",Î’:"Beta",γ:"gamma",Γ:"Gamma",δ:"delta",Δ:"Delta",ε:"epsi",ϵ:"epsiv",Ε:"Epsilon",Ï:"gammad",Ïœ:"Gammad",ζ:"zeta",Ζ:"Zeta",η:"eta",Η:"Eta",θ:"theta",Ï‘:"thetav",Θ:"Theta",ι:"iota",Ι:"Iota",κ:"kappa",ϰ:"kappav",Κ:"Kappa",λ:"lambda",Λ:"Lambda",μ:"mu",µ:"micro",Μ:"Mu",ν:"nu",Î:"Nu",ξ:"xi",Ξ:"Xi",ο:"omicron",Ο:"Omicron",Ï€:"pi",Ï–:"piv",Π:"Pi",Ï:"rho",ϱ:"rhov",Ρ:"Rho",σ:"sigma",Σ:"Sigma",Ï‚:"sigmaf",Ï„:"tau",Τ:"Tau",Ï…:"upsi",Î¥:"Upsilon",Ï’:"Upsi",φ:"phi",Ï•:"phiv",Φ:"Phi",χ:"chi",Χ:"Chi",ψ:"psi",Ψ:"Psi",ω:"omega",Ω:"ohm",а:"acy",Ð:"Acy",б:"bcy",Б:"Bcy",в:"vcy",Ð’:"Vcy",г:"gcy",Г:"Gcy",Ñ“:"gjcy",Ѓ:"GJcy",д:"dcy",Д:"Dcy",Ñ’:"djcy",Ђ:"DJcy",е:"iecy",Е:"IEcy",Ñ‘:"iocy",Ð:"IOcy",Ñ”:"jukcy",Є:"Jukcy",ж:"zhcy",Ж:"ZHcy",з:"zcy",З:"Zcy",Ñ•:"dscy",Ð…:"DScy",и:"icy",И:"Icy",Ñ–:"iukcy",І:"Iukcy",Ñ—:"yicy",Ї:"YIcy",й:"jcy",Й:"Jcy",ј:"jsercy",Ј:"Jsercy",к:"kcy",К:"Kcy",Ñœ:"kjcy",ÐŒ:"KJcy",л:"lcy",Л:"Lcy",Ñ™:"ljcy",Љ:"LJcy",м:"mcy",М:"Mcy",н:"ncy",Ð:"Ncy",Ñš:"njcy",Њ:"NJcy",о:"ocy",О:"Ocy",п:"pcy",П:"Pcy",Ñ€:"rcy",Р:"Rcy",Ñ:"scy",С:"Scy",Ñ‚:"tcy",Т:"Tcy",Ñ›:"tshcy",Ћ:"TSHcy",у:"ucy",У:"Ucy",Ñž:"ubrcy",ÐŽ:"Ubrcy",Ñ„:"fcy",Ф:"Fcy",Ñ…:"khcy",Ð¥:"KHcy",ц:"tscy",Ц:"TScy",ч:"chcy",Ч:"CHcy",ÑŸ:"dzcy",Ð:"DZcy",ш:"shcy",Ш:"SHcy",щ:"shchcy",Щ:"SHCHcy",ÑŠ:"hardcy",Ъ:"HARDcy",Ñ‹:"ycy",Ы:"Ycy",ÑŒ:"softcy",Ь:"SOFTcy",Ñ:"ecy",Э:"Ecy",ÑŽ:"yucy",Ю:"YUcy",Ñ:"yacy",Я:"YAcy",ℵ:"aleph",â„¶:"beth",â„·:"gimel",ℸ:"daleth"},d=/["&'<>`]/g,f={'"':""","&":"&","'":"'","<":"<",">":">","`":"`"},h=/&#(?:[xX][^a-fA-F0-9]|[^0-9xX])/,g=/[\0-\x08\x0B\x0E-\x1F\x7F-\x9F\uFDD0-\uFDEF\uFFFE\uFFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,m=/&(CounterClockwiseContourIntegral|DoubleLongLeftRightArrow|ClockwiseContourIntegral|NotNestedGreaterGreater|NotSquareSupersetEqual|DiacriticalDoubleAcute|NotRightTriangleEqual|NotSucceedsSlantEqual|NotPrecedesSlantEqual|CloseCurlyDoubleQuote|NegativeVeryThinSpace|DoubleContourIntegral|FilledVerySmallSquare|CapitalDifferentialD|OpenCurlyDoubleQuote|EmptyVerySmallSquare|NestedGreaterGreater|DoubleLongRightArrow|NotLeftTriangleEqual|NotGreaterSlantEqual|ReverseUpEquilibrium|DoubleLeftRightArrow|NotSquareSubsetEqual|NotDoubleVerticalBar|RightArrowLeftArrow|NotGreaterFullEqual|NotRightTriangleBar|SquareSupersetEqual|DownLeftRightVector|DoubleLongLeftArrow|leftrightsquigarrow|LeftArrowRightArrow|NegativeMediumSpace|blacktriangleright|RightDownVectorBar|PrecedesSlantEqual|RightDoubleBracket|SucceedsSlantEqual|NotLeftTriangleBar|RightTriangleEqual|SquareIntersection|RightDownTeeVector|ReverseEquilibrium|NegativeThickSpace|longleftrightarrow|Longleftrightarrow|LongLeftRightArrow|DownRightTeeVector|DownRightVectorBar|GreaterSlantEqual|SquareSubsetEqual|LeftDownVectorBar|LeftDoubleBracket|VerticalSeparator|rightleftharpoons|NotGreaterGreater|NotSquareSuperset|blacktriangleleft|blacktriangledown|NegativeThinSpace|LeftDownTeeVector|NotLessSlantEqual|leftrightharpoons|DoubleUpDownArrow|DoubleVerticalBar|LeftTriangleEqual|FilledSmallSquare|twoheadrightarrow|NotNestedLessLess|DownLeftTeeVector|DownLeftVectorBar|RightAngleBracket|NotTildeFullEqual|NotReverseElement|RightUpDownVector|DiacriticalTilde|NotSucceedsTilde|circlearrowright|NotPrecedesEqual|rightharpoondown|DoubleRightArrow|NotSucceedsEqual|NonBreakingSpace|NotRightTriangle|LessEqualGreater|RightUpTeeVector|LeftAngleBracket|GreaterFullEqual|DownArrowUpArrow|RightUpVectorBar|twoheadleftarrow|GreaterEqualLess|downharpoonright|RightTriangleBar|ntrianglerighteq|NotSupersetEqual|LeftUpDownVector|DiacriticalAcute|rightrightarrows|vartriangleright|UpArrowDownArrow|DiacriticalGrave|UnderParenthesis|EmptySmallSquare|LeftUpVectorBar|leftrightarrows|DownRightVector|downharpoonleft|trianglerighteq|ShortRightArrow|OverParenthesis|DoubleLeftArrow|DoubleDownArrow|NotSquareSubset|bigtriangledown|ntrianglelefteq|UpperRightArrow|curvearrowright|vartriangleleft|NotLeftTriangle|nleftrightarrow|LowerRightArrow|NotHumpDownHump|NotGreaterTilde|rightthreetimes|LeftUpTeeVector|NotGreaterEqual|straightepsilon|LeftTriangleBar|rightsquigarrow|ContourIntegral|rightleftarrows|CloseCurlyQuote|RightDownVector|LeftRightVector|nLeftrightarrow|leftharpoondown|circlearrowleft|SquareSuperset|OpenCurlyQuote|hookrightarrow|HorizontalLine|DiacriticalDot|NotLessGreater|ntriangleright|DoubleRightTee|InvisibleComma|InvisibleTimes|LowerLeftArrow|DownLeftVector|NotSubsetEqual|curvearrowleft|trianglelefteq|NotVerticalBar|TildeFullEqual|downdownarrows|NotGreaterLess|RightTeeVector|ZeroWidthSpace|looparrowright|LongRightArrow|doublebarwedge|ShortLeftArrow|ShortDownArrow|RightVectorBar|GreaterGreater|ReverseElement|rightharpoonup|LessSlantEqual|leftthreetimes|upharpoonright|rightarrowtail|LeftDownVector|Longrightarrow|NestedLessLess|UpperLeftArrow|nshortparallel|leftleftarrows|leftrightarrow|Leftrightarrow|LeftRightArrow|longrightarrow|upharpoonleft|RightArrowBar|ApplyFunction|LeftTeeVector|leftarrowtail|NotEqualTilde|varsubsetneqq|varsupsetneqq|RightTeeArrow|SucceedsEqual|SucceedsTilde|LeftVectorBar|SupersetEqual|hookleftarrow|DifferentialD|VerticalTilde|VeryThinSpace|blacktriangle|bigtriangleup|LessFullEqual|divideontimes|leftharpoonup|UpEquilibrium|ntriangleleft|RightTriangle|measuredangle|shortparallel|longleftarrow|Longleftarrow|LongLeftArrow|DoubleLeftTee|Poincareplane|PrecedesEqual|triangleright|DoubleUpArrow|RightUpVector|fallingdotseq|looparrowleft|PrecedesTilde|NotTildeEqual|NotTildeTilde|smallsetminus|Proportional|triangleleft|triangledown|UnderBracket|NotHumpEqual|exponentiale|ExponentialE|NotLessTilde|HilbertSpace|RightCeiling|blacklozenge|varsupsetneq|HumpDownHump|GreaterEqual|VerticalLine|LeftTeeArrow|NotLessEqual|DownTeeArrow|LeftTriangle|varsubsetneq|Intersection|NotCongruent|DownArrowBar|LeftUpVector|LeftArrowBar|risingdotseq|GreaterTilde|RoundImplies|SquareSubset|ShortUpArrow|NotSuperset|quaternions|precnapprox|backepsilon|preccurlyeq|OverBracket|blacksquare|MediumSpace|VerticalBar|circledcirc|circleddash|CircleMinus|CircleTimes|LessGreater|curlyeqprec|curlyeqsucc|diamondsuit|UpDownArrow|Updownarrow|RuleDelayed|Rrightarrow|updownarrow|RightVector|nRightarrow|nrightarrow|eqslantless|LeftCeiling|Equilibrium|SmallCircle|expectation|NotSucceeds|thickapprox|GreaterLess|SquareUnion|NotPrecedes|NotLessLess|straightphi|succnapprox|succcurlyeq|SubsetEqual|sqsupseteq|Proportion|Laplacetrf|ImaginaryI|supsetneqq|NotGreater|gtreqqless|NotElement|ThickSpace|TildeEqual|TildeTilde|Fouriertrf|rmoustache|EqualTilde|eqslantgtr|UnderBrace|LeftVector|UpArrowBar|nLeftarrow|nsubseteqq|subsetneqq|nsupseteqq|nleftarrow|succapprox|lessapprox|UpTeeArrow|upuparrows|curlywedge|lesseqqgtr|varepsilon|varnothing|RightFloor|complement|CirclePlus|sqsubseteq|Lleftarrow|circledast|RightArrow|Rightarrow|rightarrow|lmoustache|Bernoullis|precapprox|mapstoleft|mapstodown|longmapsto|dotsquare|downarrow|DoubleDot|nsubseteq|supsetneq|leftarrow|nsupseteq|subsetneq|ThinSpace|ngeqslant|subseteqq|HumpEqual|NotSubset|triangleq|NotCupCap|lesseqgtr|heartsuit|TripleDot|Leftarrow|Coproduct|Congruent|varpropto|complexes|gvertneqq|LeftArrow|LessTilde|supseteqq|MinusPlus|CircleDot|nleqslant|NotExists|gtreqless|nparallel|UnionPlus|LeftFloor|checkmark|CenterDot|centerdot|Mellintrf|gtrapprox|bigotimes|OverBrace|spadesuit|therefore|pitchfork|rationals|PlusMinus|Backslash|Therefore|DownBreve|backsimeq|backprime|DownArrow|nshortmid|Downarrow|lvertneqq|eqvparsl|imagline|imagpart|infintie|integers|Integral|intercal|LessLess|Uarrocir|intlarhk|sqsupset|angmsdaf|sqsubset|llcorner|vartheta|cupbrcap|lnapprox|Superset|SuchThat|succnsim|succneqq|angmsdag|biguplus|curlyvee|trpezium|Succeeds|NotTilde|bigwedge|angmsdah|angrtvbd|triminus|cwconint|fpartint|lrcorner|smeparsl|subseteq|urcorner|lurdshar|laemptyv|DDotrahd|approxeq|ldrushar|awconint|mapstoup|backcong|shortmid|triangle|geqslant|gesdotol|timesbar|circledR|circledS|setminus|multimap|naturals|scpolint|ncongdot|RightTee|boxminus|gnapprox|boxtimes|andslope|thicksim|angmsdaa|varsigma|cirfnint|rtriltri|angmsdab|rppolint|angmsdac|barwedge|drbkarow|clubsuit|thetasym|bsolhsub|capbrcup|dzigrarr|doteqdot|DotEqual|dotminus|UnderBar|NotEqual|realpart|otimesas|ulcorner|hksearow|hkswarow|parallel|PartialD|elinters|emptyset|plusacir|bbrktbrk|angmsdad|pointint|bigoplus|angmsdae|Precedes|bigsqcup|varkappa|notindot|supseteq|precneqq|precnsim|profalar|profline|profsurf|leqslant|lesdotor|raemptyv|subplus|notnivb|notnivc|subrarr|zigrarr|vzigzag|submult|subedot|Element|between|cirscir|larrbfs|larrsim|lotimes|lbrksld|lbrkslu|lozenge|ldrdhar|dbkarow|bigcirc|epsilon|simrarr|simplus|ltquest|Epsilon|luruhar|gtquest|maltese|npolint|eqcolon|npreceq|bigodot|ddagger|gtrless|bnequiv|harrcir|ddotseq|equivDD|backsim|demptyv|nsqsube|nsqsupe|Upsilon|nsubset|upsilon|minusdu|nsucceq|swarrow|nsupset|coloneq|searrow|boxplus|napprox|natural|asympeq|alefsym|congdot|nearrow|bigstar|diamond|supplus|tritime|LeftTee|nvinfin|triplus|NewLine|nvltrie|nvrtrie|nwarrow|nexists|Diamond|ruluhar|Implies|supmult|angzarr|suplarr|suphsub|questeq|because|digamma|Because|olcross|bemptyv|omicron|Omicron|rotimes|NoBreak|intprod|angrtvb|orderof|uwangle|suphsol|lesdoto|orslope|DownTee|realine|cudarrl|rdldhar|OverBar|supedot|lessdot|supdsub|topfork|succsim|rbrkslu|rbrksld|pertenk|cudarrr|isindot|planckh|lessgtr|pluscir|gesdoto|plussim|plustwo|lesssim|cularrp|rarrsim|Cayleys|notinva|notinvb|notinvc|UpArrow|Uparrow|uparrow|NotLess|dwangle|precsim|Product|curarrm|Cconint|dotplus|rarrbfs|ccupssm|Cedilla|cemptyv|notniva|quatint|frac35|frac38|frac45|frac56|frac58|frac78|tridot|xoplus|gacute|gammad|Gammad|lfisht|lfloor|bigcup|sqsupe|gbreve|Gbreve|lharul|sqsube|sqcups|Gcedil|apacir|llhard|lmidot|Lmidot|lmoust|andand|sqcaps|approx|Abreve|spades|circeq|tprime|divide|topcir|Assign|topbot|gesdot|divonx|xuplus|timesd|gesles|atilde|solbar|SOFTcy|loplus|timesb|lowast|lowbar|dlcorn|dlcrop|softcy|dollar|lparlt|thksim|lrhard|Atilde|lsaquo|smashp|bigvee|thinsp|wreath|bkarow|lsquor|lstrok|Lstrok|lthree|ltimes|ltlarr|DotDot|simdot|ltrPar|weierp|xsqcup|angmsd|sigmav|sigmaf|zeetrf|Zcaron|zcaron|mapsto|vsupne|thetav|cirmid|marker|mcomma|Zacute|vsubnE|there4|gtlPar|vsubne|bottom|gtrarr|SHCHcy|shchcy|midast|midcir|middot|minusb|minusd|gtrdot|bowtie|sfrown|mnplus|models|colone|seswar|Colone|mstpos|searhk|gtrsim|nacute|Nacute|boxbox|telrec|hairsp|Tcedil|nbumpe|scnsim|ncaron|Ncaron|ncedil|Ncedil|hamilt|Scedil|nearhk|hardcy|HARDcy|tcedil|Tcaron|commat|nequiv|nesear|tcaron|target|hearts|nexist|varrho|scedil|Scaron|scaron|hellip|Sacute|sacute|hercon|swnwar|compfn|rtimes|rthree|rsquor|rsaquo|zacute|wedgeq|homtht|barvee|barwed|Barwed|rpargt|horbar|conint|swarhk|roplus|nltrie|hslash|hstrok|Hstrok|rmoust|Conint|bprime|hybull|hyphen|iacute|Iacute|supsup|supsub|supsim|varphi|coprod|brvbar|agrave|Supset|supset|igrave|Igrave|notinE|Agrave|iiiint|iinfin|copysr|wedbar|Verbar|vangrt|becaus|incare|verbar|inodot|bullet|drcorn|intcal|drcrop|cularr|vellip|Utilde|bumpeq|cupcap|dstrok|Dstrok|CupCap|cupcup|cupdot|eacute|Eacute|supdot|iquest|easter|ecaron|Ecaron|ecolon|isinsv|utilde|itilde|Itilde|curarr|succeq|Bumpeq|cacute|ulcrop|nparsl|Cacute|nprcue|egrave|Egrave|nrarrc|nrarrw|subsup|subsub|nrtrie|jsercy|nsccue|Jsercy|kappav|kcedil|Kcedil|subsim|ulcorn|nsimeq|egsdot|veebar|kgreen|capand|elsdot|Subset|subset|curren|aacute|lacute|Lacute|emptyv|ntilde|Ntilde|lagran|lambda|Lambda|capcap|Ugrave|langle|subdot|emsp13|numero|emsp14|nvdash|nvDash|nVdash|nVDash|ugrave|ufisht|nvHarr|larrfs|nvlArr|larrhk|larrlp|larrpl|nvrArr|Udblac|nwarhk|larrtl|nwnear|oacute|Oacute|latail|lAtail|sstarf|lbrace|odblac|Odblac|lbrack|udblac|odsold|eparsl|lcaron|Lcaron|ograve|Ograve|lcedil|Lcedil|Aacute|ssmile|ssetmn|squarf|ldquor|capcup|ominus|cylcty|rharul|eqcirc|dagger|rfloor|rfisht|Dagger|daleth|equals|origof|capdot|equest|dcaron|Dcaron|rdquor|oslash|Oslash|otilde|Otilde|otimes|Otimes|urcrop|Ubreve|ubreve|Yacute|Uacute|uacute|Rcedil|rcedil|urcorn|parsim|Rcaron|Vdashl|rcaron|Tstrok|percnt|period|permil|Exists|yacute|rbrack|rbrace|phmmat|ccaron|Ccaron|planck|ccedil|plankv|tstrok|female|plusdo|plusdu|ffilig|plusmn|ffllig|Ccedil|rAtail|dfisht|bernou|ratail|Rarrtl|rarrtl|angsph|rarrpl|rarrlp|rarrhk|xwedge|xotime|forall|ForAll|Vvdash|vsupnE|preceq|bigcap|frac12|frac13|frac14|primes|rarrfs|prnsim|frac15|Square|frac16|square|lesdot|frac18|frac23|propto|prurel|rarrap|rangle|puncsp|frac25|Racute|qprime|racute|lesges|frac34|abreve|AElig|eqsim|utdot|setmn|urtri|Equal|Uring|seArr|uring|searr|dashv|Dashv|mumap|nabla|iogon|Iogon|sdote|sdotb|scsim|napid|napos|equiv|natur|Acirc|dblac|erarr|nbump|iprod|erDot|ucirc|awint|esdot|angrt|ncong|isinE|scnap|Scirc|scirc|ndash|isins|Ubrcy|nearr|neArr|isinv|nedot|ubrcy|acute|Ycirc|iukcy|Iukcy|xutri|nesim|caret|jcirc|Jcirc|caron|twixt|ddarr|sccue|exist|jmath|sbquo|ngeqq|angst|ccaps|lceil|ngsim|UpTee|delta|Delta|rtrif|nharr|nhArr|nhpar|rtrie|jukcy|Jukcy|kappa|rsquo|Kappa|nlarr|nlArr|TSHcy|rrarr|aogon|Aogon|fflig|xrarr|tshcy|ccirc|nleqq|filig|upsih|nless|dharl|nlsim|fjlig|ropar|nltri|dharr|robrk|roarr|fllig|fltns|roang|rnmid|subnE|subne|lAarr|trisb|Ccirc|acirc|ccups|blank|VDash|forkv|Vdash|langd|cedil|blk12|blk14|laquo|strns|diams|notin|vDash|larrb|blk34|block|disin|uplus|vdash|vBarv|aelig|starf|Wedge|check|xrArr|lates|lbarr|lBarr|notni|lbbrk|bcong|frasl|lbrke|frown|vrtri|vprop|vnsup|gamma|Gamma|wedge|xodot|bdquo|srarr|doteq|ldquo|boxdl|boxdL|gcirc|Gcirc|boxDl|boxDL|boxdr|boxdR|boxDr|TRADE|trade|rlhar|boxDR|vnsub|npart|vltri|rlarr|boxhd|boxhD|nprec|gescc|nrarr|nrArr|boxHd|boxHD|boxhu|boxhU|nrtri|boxHu|clubs|boxHU|times|colon|Colon|gimel|xlArr|Tilde|nsime|tilde|nsmid|nspar|THORN|thorn|xlarr|nsube|nsubE|thkap|xhArr|comma|nsucc|boxul|boxuL|nsupe|nsupE|gneqq|gnsim|boxUl|boxUL|grave|boxur|boxuR|boxUr|boxUR|lescc|angle|bepsi|boxvh|varpi|boxvH|numsp|Theta|gsime|gsiml|theta|boxVh|boxVH|boxvl|gtcir|gtdot|boxvL|boxVl|boxVL|crarr|cross|Cross|nvsim|boxvr|nwarr|nwArr|sqsup|dtdot|Uogon|lhard|lharu|dtrif|ocirc|Ocirc|lhblk|duarr|odash|sqsub|Hacek|sqcup|llarr|duhar|oelig|OElig|ofcir|boxvR|uogon|lltri|boxVr|csube|uuarr|ohbar|csupe|ctdot|olarr|olcir|harrw|oline|sqcap|omacr|Omacr|omega|Omega|boxVR|aleph|lneqq|lnsim|loang|loarr|rharu|lobrk|hcirc|operp|oplus|rhard|Hcirc|orarr|Union|order|ecirc|Ecirc|cuepr|szlig|cuesc|breve|reals|eDDot|Breve|hoarr|lopar|utrif|rdquo|Umacr|umacr|efDot|swArr|ultri|alpha|rceil|ovbar|swarr|Wcirc|wcirc|smtes|smile|bsemi|lrarr|aring|parsl|lrhar|bsime|uhblk|lrtri|cupor|Aring|uharr|uharl|slarr|rbrke|bsolb|lsime|rbbrk|RBarr|lsimg|phone|rBarr|rbarr|icirc|lsquo|Icirc|emacr|Emacr|ratio|simne|plusb|simlE|simgE|simeq|pluse|ltcir|ltdot|empty|xharr|xdtri|iexcl|Alpha|ltrie|rarrw|pound|ltrif|xcirc|bumpe|prcue|bumpE|asymp|amacr|cuvee|Sigma|sigma|iiint|udhar|iiota|ijlig|IJlig|supnE|imacr|Imacr|prime|Prime|image|prnap|eogon|Eogon|rarrc|mdash|mDDot|cuwed|imath|supne|imped|Amacr|udarr|prsim|micro|rarrb|cwint|raquo|infin|eplus|range|rangd|Ucirc|radic|minus|amalg|veeeq|rAarr|epsiv|ycirc|quest|sharp|quot|zwnj|Qscr|race|qscr|Qopf|qopf|qint|rang|Rang|Zscr|zscr|Zopf|zopf|rarr|rArr|Rarr|Pscr|pscr|prop|prod|prnE|prec|ZHcy|zhcy|prap|Zeta|zeta|Popf|popf|Zdot|plus|zdot|Yuml|yuml|phiv|YUcy|yucy|Yscr|yscr|perp|Yopf|yopf|part|para|YIcy|Ouml|rcub|yicy|YAcy|rdca|ouml|osol|Oscr|rdsh|yacy|real|oscr|xvee|andd|rect|andv|Xscr|oror|ordm|ordf|xscr|ange|aopf|Aopf|rHar|Xopf|opar|Oopf|xopf|xnis|rhov|oopf|omid|xmap|oint|apid|apos|ogon|ascr|Ascr|odot|odiv|xcup|xcap|ocir|oast|nvlt|nvle|nvgt|nvge|nvap|Wscr|wscr|auml|ntlg|ntgl|nsup|nsub|nsim|Nscr|nscr|nsce|Wopf|ring|npre|wopf|npar|Auml|Barv|bbrk|Nopf|nopf|nmid|nLtv|beta|ropf|Ropf|Beta|beth|nles|rpar|nleq|bnot|bNot|nldr|NJcy|rscr|Rscr|Vscr|vscr|rsqb|njcy|bopf|nisd|Bopf|rtri|Vopf|nGtv|ngtr|vopf|boxh|boxH|boxv|nges|ngeq|boxV|bscr|scap|Bscr|bsim|Vert|vert|bsol|bull|bump|caps|cdot|ncup|scnE|ncap|nbsp|napE|Cdot|cent|sdot|Vbar|nang|vBar|chcy|Mscr|mscr|sect|semi|CHcy|Mopf|mopf|sext|circ|cire|mldr|mlcp|cirE|comp|shcy|SHcy|vArr|varr|cong|copf|Copf|copy|COPY|malt|male|macr|lvnE|cscr|ltri|sime|ltcc|simg|Cscr|siml|csub|Uuml|lsqb|lsim|uuml|csup|Lscr|lscr|utri|smid|lpar|cups|smte|lozf|darr|Lopf|Uscr|solb|lopf|sopf|Sopf|lneq|uscr|spar|dArr|lnap|Darr|dash|Sqrt|LJcy|ljcy|lHar|dHar|Upsi|upsi|diam|lesg|djcy|DJcy|leqq|dopf|Dopf|dscr|Dscr|dscy|ldsh|ldca|squf|DScy|sscr|Sscr|dsol|lcub|late|star|Star|Uopf|Larr|lArr|larr|uopf|dtri|dzcy|sube|subE|Lang|lang|Kscr|kscr|Kopf|kopf|KJcy|kjcy|KHcy|khcy|DZcy|ecir|edot|eDot|Jscr|jscr|succ|Jopf|jopf|Edot|uHar|emsp|ensp|Iuml|iuml|eopf|isin|Iscr|iscr|Eopf|epar|sung|epsi|escr|sup1|sup2|sup3|Iota|iota|supe|supE|Iopf|iopf|IOcy|iocy|Escr|esim|Esim|imof|Uarr|QUOT|uArr|uarr|euml|IEcy|iecy|Idot|Euml|euro|excl|Hscr|hscr|Hopf|hopf|TScy|tscy|Tscr|hbar|tscr|flat|tbrk|fnof|hArr|harr|half|fopf|Fopf|tdot|gvnE|fork|trie|gtcc|fscr|Fscr|gdot|gsim|Gscr|gscr|Gopf|gopf|gneq|Gdot|tosa|gnap|Topf|topf|geqq|toea|GJcy|gjcy|tint|gesl|mid|Sfr|ggg|top|ges|gla|glE|glj|geq|gne|gEl|gel|gnE|Gcy|gcy|gap|Tfr|tfr|Tcy|tcy|Hat|Tau|Ffr|tau|Tab|hfr|Hfr|ffr|Fcy|fcy|icy|Icy|iff|ETH|eth|ifr|Ifr|Eta|eta|int|Int|Sup|sup|ucy|Ucy|Sum|sum|jcy|ENG|ufr|Ufr|eng|Jcy|jfr|els|ell|egs|Efr|efr|Jfr|uml|kcy|Kcy|Ecy|ecy|kfr|Kfr|lap|Sub|sub|lat|lcy|Lcy|leg|Dot|dot|lEg|leq|les|squ|div|die|lfr|Lfr|lgE|Dfr|dfr|Del|deg|Dcy|dcy|lne|lnE|sol|loz|smt|Cup|lrm|cup|lsh|Lsh|sim|shy|map|Map|mcy|Mcy|mfr|Mfr|mho|gfr|Gfr|sfr|cir|Chi|chi|nap|Cfr|vcy|Vcy|cfr|Scy|scy|ncy|Ncy|vee|Vee|Cap|cap|nfr|scE|sce|Nfr|nge|ngE|nGg|vfr|Vfr|ngt|bot|nGt|nis|niv|Rsh|rsh|nle|nlE|bne|Bfr|bfr|nLl|nlt|nLt|Bcy|bcy|not|Not|rlm|wfr|Wfr|npr|nsc|num|ocy|ast|Ocy|ofr|xfr|Xfr|Ofr|ogt|ohm|apE|olt|Rho|ape|rho|Rfr|rfr|ord|REG|ang|reg|orv|And|and|AMP|Rcy|amp|Afr|ycy|Ycy|yen|yfr|Yfr|rcy|par|pcy|Pcy|pfr|Pfr|phi|Phi|afr|Acy|acy|zcy|Zcy|piv|acE|acd|zfr|Zfr|pre|prE|psi|Psi|qfr|Qfr|zwj|Or|ge|Gg|gt|gg|el|oS|lt|Lt|LT|Re|lg|gl|eg|ne|Im|it|le|DD|wp|wr|nu|Nu|dd|lE|Sc|sc|pi|Pi|ee|af|ll|Ll|rx|gE|xi|pm|Xi|ic|pr|Pr|in|ni|mp|mu|ac|Mu|or|ap|Gt|GT|ii);|&(Aacute|Agrave|Atilde|Ccedil|Eacute|Egrave|Iacute|Igrave|Ntilde|Oacute|Ograve|Oslash|Otilde|Uacute|Ugrave|Yacute|aacute|agrave|atilde|brvbar|ccedil|curren|divide|eacute|egrave|frac12|frac14|frac34|iacute|igrave|iquest|middot|ntilde|oacute|ograve|oslash|otilde|plusmn|uacute|ugrave|yacute|AElig|Acirc|Aring|Ecirc|Icirc|Ocirc|THORN|Ucirc|acirc|acute|aelig|aring|cedil|ecirc|icirc|iexcl|laquo|micro|ocirc|pound|raquo|szlig|thorn|times|ucirc|Auml|COPY|Euml|Iuml|Ouml|QUOT|Uuml|auml|cent|copy|euml|iuml|macr|nbsp|ordf|ordm|ouml|para|quot|sect|sup1|sup2|sup3|uuml|yuml|AMP|ETH|REG|amp|deg|eth|not|reg|shy|uml|yen|GT|LT|gt|lt)(?!;)([=a-zA-Z0-9]?)|&#([0-9]+)(;?)|&#[xX]([a-fA-F0-9]+)(;?)|&([0-9a-zA-Z]+)/g,v={aacute:"á",Aacute:"Ã",abreve:"ă",Abreve:"Ä‚",ac:"∾",acd:"∿",acE:"∾̳",acirc:"â",Acirc:"Â",acute:"´",acy:"а",Acy:"Ð",aelig:"æ",AElig:"Æ",af:"â¡",afr:"ð”ž",Afr:"ð”„",agrave:"à",Agrave:"À",alefsym:"ℵ",aleph:"ℵ",alpha:"α",Alpha:"Α",amacr:"Ä",Amacr:"Ä€",amalg:"⨿",amp:"&",AMP:"&",and:"∧",And:"â©“",andand:"â©•",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsd:"∡",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angrt:"∟",angrtvb:"⊾",angrtvbd:"â¦",angsph:"∢",angst:"Ã…",angzarr:"â¼",aogon:"Ä…",Aogon:"Ä„",aopf:"ð•’",Aopf:"ð”¸",ap:"≈",apacir:"⩯",ape:"≊",apE:"â©°",apid:"≋",apos:"'",ApplyFunction:"â¡",approx:"≈",approxeq:"≊",aring:"Ã¥",Aring:"Ã…",ascr:"ð’¶",Ascr:"ð’œ",Assign:"≔",ast:"*",asymp:"≈",asympeq:"â‰",atilde:"ã",Atilde:"Ã",auml:"ä",Auml:"Ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"â‹",Backslash:"∖",Barv:"â«§",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",bcy:"б",Bcy:"Б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",beta:"β",Beta:"Î’",beth:"â„¶",between:"≬",bfr:"ð”Ÿ",Bfr:"ð”…",bigcap:"â‹‚",bigcirc:"â—¯",bigcup:"⋃",bigodot:"⨀",bigoplus:"â¨",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"â–½",bigtriangleup:"â–³",biguplus:"⨄",bigvee:"â‹",bigwedge:"â‹€",bkarow:"â¤",blacklozenge:"â§«",blacksquare:"â–ª",blacktriangle:"â–´",blacktriangledown:"â–¾",blacktriangleleft:"â—‚",blacktriangleright:"â–¸",blank:"â£",blk12:"â–’",blk14:"â–‘",blk34:"â–“",block:"â–ˆ",bne:"=⃥",bnequiv:"≡⃥",bnot:"âŒ",bNot:"â«­",bopf:"ð•“",Bopf:"ð”¹",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"â”",boxdL:"â••",boxDl:"â•–",boxDL:"â•—",boxdr:"┌",boxdR:"â•’",boxDr:"â•“",boxDR:"â•”",boxh:"─",boxH:"â•",boxhd:"┬",boxhD:"â•¥",boxHd:"╤",boxHD:"╦",boxhu:"â”´",boxhU:"╨",boxHu:"â•§",boxHU:"â•©",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"â•›",boxUl:"╜",boxUL:"â•",boxur:"â””",boxuR:"╘",boxUr:"â•™",boxUR:"╚",boxv:"│",boxV:"â•‘",boxvh:"┼",boxvH:"╪",boxVh:"â•«",boxVH:"╬",boxvl:"┤",boxvL:"â•¡",boxVl:"â•¢",boxVL:"â•£",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"â• ",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"ð’·",Bscr:"ℬ",bsemi:"â",bsim:"∽",bsime:"â‹",bsol:"\\",bsolb:"â§…",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpe:"â‰",bumpE:"⪮",bumpeq:"â‰",Bumpeq:"≎",cacute:"ć",Cacute:"Ć",cap:"∩",Cap:"â‹’",capand:"â©„",capbrcup:"⩉",capcap:"â©‹",capcup:"⩇",capdot:"â©€",CapitalDifferentialD:"â……",caps:"∩︀",caret:"â",caron:"ˇ",Cayleys:"â„­",ccaps:"â©",ccaron:"Ä",Ccaron:"ÄŒ",ccedil:"ç",Ccedil:"Ç",ccirc:"ĉ",Ccirc:"Ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"â©",cdot:"Ä‹",Cdot:"ÄŠ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"ð” ",Cfr:"â„­",chcy:"ч",CHcy:"Ч",check:"✓",checkmark:"✓",chi:"χ",Chi:"Χ",cir:"â—‹",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"âŠ",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cire:"≗",cirE:"⧃",cirfnint:"â¨",cirmid:"⫯",cirscir:"â§‚",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"â€",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",colone:"≔",Colone:"â©´",coloneq:"≔",comma:",",commat:"@",comp:"âˆ",compfn:"∘",complement:"âˆ",complexes:"â„‚",cong:"≅",congdot:"â©­",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"ð•”",Copf:"â„‚",coprod:"âˆ",Coproduct:"âˆ",copy:"©",COPY:"©",copysr:"â„—",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",cscr:"ð’¸",Cscr:"ð’ž",csub:"â«",csube:"â«‘",csup:"â«",csupe:"â«’",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cup:"∪",Cup:"â‹“",cupbrcap:"⩈",cupcap:"⩆",CupCap:"â‰",cupcup:"⩊",cupdot:"âŠ",cupor:"â©…",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"â‹",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"â‹",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",dArr:"⇓",Darr:"↡",dash:"â€",dashv:"⊣",Dashv:"⫤",dbkarow:"â¤",dblac:"Ë",dcaron:"Ä",Dcaron:"ÄŽ",dcy:"д",Dcy:"Д",dd:"â…†",DD:"â……",ddagger:"‡",ddarr:"⇊",DDotrahd:"⤑",ddotseq:"â©·",deg:"°",Del:"∇",delta:"δ",Delta:"Δ",demptyv:"⦱",dfisht:"⥿",dfr:"ð”¡",Dfr:"ð”‡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"Ë™",DiacriticalDoubleAcute:"Ë",DiacriticalGrave:"`",DiacriticalTilde:"Ëœ",diam:"â‹„",diamond:"â‹„",Diamond:"â‹„",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"â…†",digamma:"Ï",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",djcy:"Ñ’",DJcy:"Ђ",dlcorn:"⌞",dlcrop:"âŒ",dollar:"$",dopf:"ð••",Dopf:"ð”»",dot:"Ë™",Dot:"¨",DotDot:"⃜",doteq:"â‰",doteqdot:"≑",DotEqual:"â‰",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"â‡",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",downarrow:"↓",Downarrow:"⇓",DownArrow:"↓",DownArrowBar:"⤓",DownArrowUpArrow:"⇵",DownBreve:"Ì‘",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"â¥",DownLeftTeeVector:"⥞",DownLeftVector:"↽",DownLeftVectorBar:"⥖",DownRightTeeVector:"⥟",DownRightVector:"â‡",DownRightVectorBar:"⥗",DownTee:"⊤",DownTeeArrow:"↧",drbkarow:"â¤",drcorn:"⌟",drcrop:"⌌",dscr:"ð’¹",Dscr:"ð’Ÿ",dscy:"Ñ•",DScy:"Ð…",dsol:"â§¶",dstrok:"Ä‘",Dstrok:"Ä",dtdot:"⋱",dtri:"â–¿",dtrif:"â–¾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",dzcy:"ÑŸ",DZcy:"Ð",dzigrarr:"⟿",eacute:"é",Eacute:"É",easter:"â©®",ecaron:"Ä›",Ecaron:"Äš",ecir:"≖",ecirc:"ê",Ecirc:"Ê",ecolon:"≕",ecy:"Ñ",Ecy:"Э",eDDot:"â©·",edot:"Ä—",eDot:"≑",Edot:"Ä–",ee:"â…‡",efDot:"≒",efr:"ð”¢",Efr:"ð”ˆ",eg:"⪚",egrave:"è",Egrave:"È",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"â§",ell:"â„“",els:"⪕",elsdot:"⪗",emacr:"Ä“",Emacr:"Ä’",empty:"∅",emptyset:"∅",EmptySmallSquare:"â—»",emptyv:"∅",EmptyVerySmallSquare:"â–«",emsp:" ",emsp13:" ",emsp14:" ",eng:"Å‹",ENG:"ÅŠ",ensp:" ",eogon:"Ä™",Eogon:"Ę",eopf:"ð•–",Eopf:"ð”¼",epar:"â‹•",eparsl:"â§£",eplus:"⩱",epsi:"ε",epsilon:"ε",Epsilon:"Ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"â§¥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"â„°",esdot:"â‰",esim:"≂",Esim:"⩳",eta:"η",Eta:"Η",eth:"ð",ETH:"Ã",euml:"ë",Euml:"Ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"â„°",exponentiale:"â…‡",ExponentialE:"â…‡",fallingdotseq:"≒",fcy:"Ñ„",Fcy:"Ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",ffr:"ð”£",Ffr:"ð”‰",filig:"ï¬",FilledSmallSquare:"â—¼",FilledVerySmallSquare:"â–ª",fjlig:"fj",flat:"â™­",fllig:"fl",fltns:"â–±",fnof:"Æ’",fopf:"ð•—",Fopf:"ð”½",forall:"∀",ForAll:"∀",fork:"â‹”",forkv:"â«™",Fouriertrf:"ℱ",fpartint:"â¨",frac12:"½",frac13:"â…“",frac14:"¼",frac15:"â…•",frac16:"â…™",frac18:"â…›",frac23:"â…”",frac25:"â…–",frac34:"¾",frac35:"â…—",frac38:"â…œ",frac45:"â…˜",frac56:"â…š",frac58:"â…",frac78:"â…ž",frasl:"â„",frown:"⌢",fscr:"ð’»",Fscr:"ℱ",gacute:"ǵ",gamma:"γ",Gamma:"Γ",gammad:"Ï",Gammad:"Ïœ",gap:"⪆",gbreve:"ÄŸ",Gbreve:"Äž",Gcedil:"Ä¢",gcirc:"Ä",Gcirc:"Äœ",gcy:"г",Gcy:"Г",gdot:"Ä¡",Gdot:"Ä ",ge:"≥",gE:"≧",gel:"â‹›",gEl:"⪌",geq:"≥",geqq:"≧",geqslant:"⩾",ges:"⩾",gescc:"⪩",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",gfr:"ð”¤",Gfr:"ð”Š",gg:"≫",Gg:"â‹™",ggg:"â‹™",gimel:"â„·",gjcy:"Ñ“",GJcy:"Ѓ",gl:"≷",gla:"⪥",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"â‹§",gopf:"ð•˜",Gopf:"ð”¾",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"â‹›",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",gscr:"ℊ",Gscr:"ð’¢",gsim:"≳",gsime:"⪎",gsiml:"âª",gt:">",Gt:"≫",GT:">",gtcc:"⪧",gtcir:"⩺",gtdot:"â‹—",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"â‹—",gtreqless:"â‹›",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"â„‹",hardcy:"ÑŠ",HARDcy:"Ъ",harr:"↔",hArr:"⇔",harrcir:"⥈",harrw:"↭",Hat:"^",hbar:"â„",hcirc:"Ä¥",Hcirc:"Ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"ð”¥",Hfr:"ℌ",HilbertSpace:"â„‹",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"ð•™",Hopf:"â„",horbar:"―",HorizontalLine:"─",hscr:"ð’½",Hscr:"â„‹",hslash:"â„",hstrok:"ħ",Hstrok:"Ħ",HumpDownHump:"≎",HumpEqual:"â‰",hybull:"âƒ",hyphen:"â€",iacute:"í",Iacute:"Ã",ic:"â£",icirc:"î",Icirc:"ÃŽ",icy:"и",Icy:"И",Idot:"İ",iecy:"е",IEcy:"Е",iexcl:"¡",iff:"⇔",ifr:"ð”¦",Ifr:"â„‘",igrave:"ì",Igrave:"ÃŒ",ii:"â…ˆ",iiiint:"⨌",iiint:"∭",iinfin:"â§œ",iiota:"â„©",ijlig:"ij",IJlig:"IJ",Im:"â„‘",imacr:"Ä«",Imacr:"Ī",image:"â„‘",ImaginaryI:"â…ˆ",imagline:"â„",imagpart:"â„‘",imath:"ı",imof:"⊷",imped:"Ƶ",Implies:"⇒",in:"∈",incare:"â„…",infin:"∞",infintie:"â§",inodot:"ı",int:"∫",Int:"∬",intcal:"⊺",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"â‹‚",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"â£",InvisibleTimes:"â¢",iocy:"Ñ‘",IOcy:"Ð",iogon:"į",Iogon:"Ä®",iopf:"ð•š",Iopf:"ð•€",iota:"ι",Iota:"Ι",iprod:"⨼",iquest:"¿",iscr:"ð’¾",Iscr:"â„",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"â‹´",isinsv:"⋳",isinv:"∈",it:"â¢",itilde:"Ä©",Itilde:"Ĩ",iukcy:"Ñ–",Iukcy:"І",iuml:"ï",Iuml:"Ã",jcirc:"ĵ",Jcirc:"Ä´",jcy:"й",Jcy:"Й",jfr:"ð”§",Jfr:"ð”",jmath:"È·",jopf:"ð•›",Jopf:"ð•",jscr:"ð’¿",Jscr:"ð’¥",jsercy:"ј",Jsercy:"Ј",jukcy:"Ñ”",Jukcy:"Є",kappa:"κ",Kappa:"Κ",kappav:"ϰ",kcedil:"Ä·",Kcedil:"Ķ",kcy:"к",Kcy:"К",kfr:"ð”¨",Kfr:"ð”Ž",kgreen:"ĸ",khcy:"Ñ…",KHcy:"Ð¥",kjcy:"Ñœ",KJcy:"ÐŒ",kopf:"ð•œ",Kopf:"ð•‚",kscr:"ð“€",Kscr:"ð’¦",lAarr:"⇚",lacute:"ĺ",Lacute:"Ĺ",laemptyv:"⦴",lagran:"â„’",lambda:"λ",Lambda:"Λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"â„’",laquo:"«",larr:"â†",lArr:"â‡",Larr:"↞",larrb:"⇤",larrbfs:"⤟",larrfs:"â¤",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",lat:"⪫",latail:"⤙",lAtail:"⤛",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"â²",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"â¦",lbrkslu:"â¦",lcaron:"ľ",Lcaron:"Ľ",lcedil:"ļ",Lcedil:"Ä»",lceil:"⌈",lcub:"{",lcy:"л",Lcy:"Л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",leftarrow:"â†",Leftarrow:"â‡",LeftArrow:"â†",LeftArrowBar:"⇤",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVector:"⇃",LeftDownVectorBar:"⥙",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",Leftrightarrow:"⇔",LeftRightArrow:"↔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTee:"⊣",LeftTeeArrow:"↤",LeftTeeVector:"⥚",leftthreetimes:"â‹‹",LeftTriangle:"⊲",LeftTriangleBar:"â§",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVector:"↿",LeftUpVectorBar:"⥘",LeftVector:"↼",LeftVectorBar:"⥒",leg:"⋚",lEg:"⪋",leq:"≤",leqq:"≦",leqslant:"⩽",les:"⩽",lescc:"⪨",lesdot:"â©¿",lesdoto:"âª",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"â‹–",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",lfr:"ð”©",Lfr:"ð”",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"â–„",ljcy:"Ñ™",LJcy:"Љ",ll:"≪",Ll:"⋘",llarr:"⇇",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"â—º",lmidot:"Å€",Lmidot:"Ä¿",lmoust:"⎰",lmoustache:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",Longleftarrow:"⟸",LongLeftArrow:"⟵",longleftrightarrow:"⟷",Longleftrightarrow:"⟺",LongLeftRightArrow:"⟷",longmapsto:"⟼",longrightarrow:"⟶",Longrightarrow:"⟹",LongRightArrow:"⟶",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",lopf:"ð•",Lopf:"ð•ƒ",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"â—Š",lozenge:"â—Š",lozf:"â§«",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"ð“",Lscr:"â„’",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"âª",lsimg:"âª",lsqb:"[",lsquo:"‘",lsquor:"‚",lstrok:"Å‚",Lstrok:"Å",lt:"<",Lt:"≪",LT:"<",ltcc:"⪦",ltcir:"⩹",ltdot:"â‹–",lthree:"â‹‹",ltimes:"⋉",ltlarr:"⥶",ltquest:"â©»",ltri:"â—ƒ",ltrie:"⊴",ltrif:"â—‚",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",map:"↦",Map:"⤅",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"â–®",mcomma:"⨩",mcy:"м",Mcy:"М",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:"âŸ",Mellintrf:"ℳ",mfr:"ð”ª",Mfr:"ð”",mho:"â„§",micro:"µ",mid:"∣",midast:"*",midcir:"â«°",middot:"·",minus:"−",minusb:"⊟",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"â«›",mldr:"…",mnplus:"∓",models:"⊧",mopf:"ð•ž",Mopf:"ð•„",mp:"∓",mscr:"ð“‚",Mscr:"ℳ",mstpos:"∾",mu:"μ",Mu:"Μ",multimap:"⊸",mumap:"⊸",nabla:"∇",nacute:"Å„",Nacute:"Ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natur:"â™®",natural:"â™®",naturals:"â„•",nbsp:" ",nbump:"≎̸",nbumpe:"â‰Ì¸",ncap:"⩃",ncaron:"ň",Ncaron:"Ň",ncedil:"ņ",Ncedil:"Å…",ncong:"≇",ncongdot:"⩭̸",ncup:"â©‚",ncy:"н",Ncy:"Ð",ndash:"–",ne:"≠",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",nedot:"â‰Ì¸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",nfr:"ð”«",Nfr:"ð”‘",nge:"≱",ngE:"≧̸",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",ngt:"≯",nGt:"≫⃒",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",njcy:"Ñš",NJcy:"Њ",nlarr:"↚",nlArr:"â‡",nldr:"‥",nle:"≰",nlE:"≦̸",nleftarrow:"↚",nLeftarrow:"â‡",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nlt:"≮",nLt:"≪⃒",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"â ",NonBreakingSpace:" ",nopf:"ð•Ÿ",Nopf:"â„•",not:"¬",Not:"⫬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"â‰Ì¸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"â‹·",notinvc:"â‹¶",NotLeftTriangle:"⋪",NotLeftTriangleBar:"â§Ì¸",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"â‹ ",NotReverseElement:"∌",NotRightTriangle:"â‹«",NotRightTriangleBar:"â§Ì¸",NotRightTriangleEqual:"â‹­",NotSquareSubset:"âŠÌ¸",NotSquareSubsetEqual:"â‹¢",NotSquareSuperset:"âŠÌ¸",NotSquareSupersetEqual:"â‹£",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"âŠ",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"â‹¡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"â‰",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",npar:"∦",nparallel:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"â‹ ",npre:"⪯̸",nprec:"⊀",npreceq:"⪯̸",nrarr:"↛",nrArr:"â‡",nrarrc:"⤳̸",nrarrw:"â†Ì¸",nrightarrow:"↛",nRightarrow:"â‡",nrtri:"â‹«",nrtrie:"â‹­",nsc:"âŠ",nsccue:"â‹¡",nsce:"⪰̸",nscr:"ð“ƒ",Nscr:"ð’©",nshortmid:"∤",nshortparallel:"∦",nsim:"â‰",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"â‹¢",nsqsupe:"â‹£",nsub:"⊄",nsube:"⊈",nsubE:"⫅̸",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"âŠ",nsucceq:"⪰̸",nsup:"⊅",nsupe:"⊉",nsupE:"⫆̸",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",ntilde:"ñ",Ntilde:"Ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"â‹«",ntrianglerighteq:"â‹­",nu:"ν",Nu:"Î",num:"#",numero:"â„–",numsp:" ",nvap:"â‰âƒ’",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"â§ž",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",oacute:"ó",Oacute:"Ó",oast:"⊛",ocir:"⊚",ocirc:"ô",Ocirc:"Ô",ocy:"о",Ocy:"О",odash:"âŠ",odblac:"Å‘",Odblac:"Å",odiv:"⨸",odot:"⊙",odsold:"⦼",oelig:"Å“",OElig:"Å’",ofcir:"⦿",ofr:"ð”¬",Ofr:"ð”’",ogon:"Ë›",ograve:"ò",Ograve:"Ã’",ogt:"â§",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"â§€",omacr:"Å",Omacr:"ÅŒ",omega:"ω",Omega:"Ω",omicron:"ο",Omicron:"Ο",omid:"⦶",ominus:"⊖",oopf:"ð• ",Oopf:"ð•†",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",or:"∨",Or:"â©”",orarr:"↻",ord:"â©",order:"â„´",orderof:"â„´",ordf:"ª",ordm:"º",origof:"⊶",oror:"â©–",orslope:"â©—",orv:"â©›",oS:"Ⓢ",oscr:"â„´",Oscr:"ð’ª",oslash:"ø",Oslash:"Ø",osol:"⊘",otilde:"õ",Otilde:"Õ",otimes:"⊗",Otimes:"⨷",otimesas:"⨶",ouml:"ö",Ouml:"Ö",ovbar:"⌽",OverBar:"‾",OverBrace:"âž",OverBracket:"⎴",OverParenthesis:"âœ",par:"∥",para:"¶",parallel:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",pcy:"п",Pcy:"П",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",pfr:"ð”­",Pfr:"ð”“",phi:"φ",Phi:"Φ",phiv:"Ï•",phmmat:"ℳ",phone:"☎",pi:"Ï€",Pi:"Π",pitchfork:"â‹”",piv:"Ï–",planck:"â„",planckh:"ℎ",plankv:"â„",plus:"+",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"ð•¡",Popf:"â„™",pound:"£",pr:"≺",Pr:"⪻",prap:"⪷",prcue:"≼",pre:"⪯",prE:"⪳",prec:"≺",precapprox:"⪷",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",precsim:"≾",prime:"′",Prime:"″",primes:"â„™",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"âˆ",Product:"âˆ",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"âˆ",Proportion:"∷",Proportional:"âˆ",propto:"âˆ",prsim:"≾",prurel:"⊰",pscr:"ð“…",Pscr:"ð’«",psi:"ψ",Psi:"Ψ",puncsp:" ",qfr:"ð”®",Qfr:"ð””",qint:"⨌",qopf:"ð•¢",Qopf:"ℚ",qprime:"â—",qscr:"ð“†",Qscr:"ð’¬",quaternions:"â„",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",racute:"Å•",Racute:"Å”",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarr:"→",rArr:"⇒",Rarr:"↠",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",rarrtl:"↣",Rarrtl:"⤖",rarrw:"â†",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"â¤",rBarr:"â¤",RBarr:"â¤",rbbrk:"â³",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"â¦",rcaron:"Å™",Rcaron:"Ř",rcedil:"Å—",Rcedil:"Å–",rceil:"⌉",rcub:"}",rcy:"Ñ€",Rcy:"Р",rdca:"⤷",rdldhar:"⥩",rdquo:"â€",rdquor:"â€",rdsh:"↳",Re:"ℜ",real:"ℜ",realine:"â„›",realpart:"ℜ",reals:"â„",rect:"â–­",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"ð”¯",Rfr:"ℜ",rHar:"⥤",rhard:"â‡",rharu:"⇀",rharul:"⥬",rho:"Ï",Rho:"Ρ",rhov:"ϱ",RightAngleBracket:"⟩",rightarrow:"→",Rightarrow:"⇒",RightArrow:"→",RightArrowBar:"⇥",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"â¥",RightDownVector:"⇂",RightDownVectorBar:"⥕",RightFloor:"⌋",rightharpoondown:"â‡",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"â†",RightTee:"⊢",RightTeeArrow:"↦",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangle:"⊳",RightTriangleBar:"â§",RightTriangleEqual:"⊵",RightUpDownVector:"â¥",RightUpTeeVector:"⥜",RightUpVector:"↾",RightUpVectorBar:"⥔",RightVector:"⇀",RightVectorBar:"⥓",ring:"Ëš",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"â€",rmoust:"⎱",rmoustache:"⎱",rnmid:"â«®",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"ð•£",Ropf:"â„",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"ð“‡",Rscr:"â„›",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"â–¹",rtrie:"⊵",rtrif:"â–¸",rtriltri:"â§Ž",RuleDelayed:"â§´",ruluhar:"⥨",rx:"℞",sacute:"Å›",Sacute:"Åš",sbquo:"‚",sc:"≻",Sc:"⪼",scap:"⪸",scaron:"Å¡",Scaron:"Å ",sccue:"≽",sce:"⪰",scE:"⪴",scedil:"ÅŸ",Scedil:"Åž",scirc:"Å",Scirc:"Åœ",scnap:"⪺",scnE:"⪶",scnsim:"â‹©",scpolint:"⨓",scsim:"≿",scy:"Ñ",Scy:"С",sdot:"â‹…",sdotb:"⊡",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",sfr:"ð”°",Sfr:"ð”–",sfrown:"⌢",sharp:"♯",shchcy:"щ",SHCHcy:"Щ",shcy:"ш",SHcy:"Ш",ShortDownArrow:"↓",ShortLeftArrow:"â†",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",sigma:"σ",Sigma:"Σ",sigmaf:"Ï‚",sigmav:"Ï‚",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"âª",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"â†",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",softcy:"ÑŒ",SOFTcy:"Ь",sol:"/",solb:"â§„",solbar:"⌿",sopf:"ð•¤",Sopf:"ð•Š",spades:"â™ ",spadesuit:"â™ ",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"âŠ",sqsube:"⊑",sqsubset:"âŠ",sqsubseteq:"⊑",sqsup:"âŠ",sqsupe:"⊒",sqsupset:"âŠ",sqsupseteq:"⊒",squ:"â–¡",square:"â–¡",Square:"â–¡",SquareIntersection:"⊓",SquareSubset:"âŠ",SquareSubsetEqual:"⊑",SquareSuperset:"âŠ",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"â–ª",squf:"â–ª",srarr:"→",sscr:"ð“ˆ",Sscr:"ð’®",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",star:"☆",Star:"⋆",starf:"★",straightepsilon:"ϵ",straightphi:"Ï•",strns:"¯",sub:"⊂",Sub:"â‹",subdot:"⪽",sube:"⊆",subE:"â«…",subedot:"⫃",submult:"â«",subne:"⊊",subnE:"â«‹",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"â‹",subseteq:"⊆",subseteqq:"â«…",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"â«‹",subsim:"⫇",subsub:"â«•",subsup:"â«“",succ:"≻",succapprox:"⪸",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"â‹©",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup:"⊃",Sup:"â‹‘",sup1:"¹",sup2:"²",sup3:"³",supdot:"⪾",supdsub:"⫘",supe:"⊇",supE:"⫆",supedot:"â«„",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"â«—",suplarr:"⥻",supmult:"â«‚",supne:"⊋",supnE:"⫌",supplus:"â«€",supset:"⊃",Supset:"â‹‘",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"â«”",supsup:"â«–",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",tau:"Ï„",Tau:"Τ",tbrk:"⎴",tcaron:"Å¥",Tcaron:"Ť",tcedil:"Å£",Tcedil:"Å¢",tcy:"Ñ‚",Tcy:"Т",tdot:"⃛",telrec:"⌕",tfr:"ð”±",Tfr:"ð”—",there4:"∴",therefore:"∴",Therefore:"∴",theta:"θ",Theta:"Θ",thetasym:"Ï‘",thetav:"Ï‘",thickapprox:"≈",thicksim:"∼",ThickSpace:"âŸâ€Š",thinsp:" ",ThinSpace:" ",thkap:"≈",thksim:"∼",thorn:"þ",THORN:"Þ",tilde:"Ëœ",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",times:"×",timesb:"⊠",timesbar:"⨱",timesd:"⨰",tint:"∭",toea:"⤨",top:"⊤",topbot:"⌶",topcir:"⫱",topf:"ð•¥",Topf:"ð•‹",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"â„¢",TRADE:"â„¢",triangle:"â–µ",triangledown:"â–¿",triangleleft:"â—ƒ",trianglelefteq:"⊴",triangleq:"≜",triangleright:"â–¹",trianglerighteq:"⊵",tridot:"â—¬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"â§",tritime:"⨻",trpezium:"â¢",tscr:"ð“‰",Tscr:"ð’¯",tscy:"ц",TScy:"Ц",tshcy:"Ñ›",TSHcy:"Ћ",tstrok:"ŧ",Tstrok:"Ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",uacute:"ú",Uacute:"Ú",uarr:"↑",uArr:"⇑",Uarr:"↟",Uarrocir:"⥉",ubrcy:"Ñž",Ubrcy:"ÐŽ",ubreve:"Å­",Ubreve:"Ŭ",ucirc:"û",Ucirc:"Û",ucy:"у",Ucy:"У",udarr:"⇅",udblac:"ű",Udblac:"Ű",udhar:"⥮",ufisht:"⥾",ufr:"ð”²",Ufr:"ð”˜",ugrave:"ù",Ugrave:"Ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"â–€",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"âŒ",ultri:"â—¸",umacr:"Å«",Umacr:"Ū",uml:"¨",UnderBar:"_",UnderBrace:"âŸ",UnderBracket:"⎵",UnderParenthesis:"â",Union:"⋃",UnionPlus:"⊎",uogon:"ų",Uogon:"Ų",uopf:"ð•¦",Uopf:"ð•Œ",uparrow:"↑",Uparrow:"⇑",UpArrow:"↑",UpArrowBar:"⤒",UpArrowDownArrow:"⇅",updownarrow:"↕",Updownarrow:"⇕",UpDownArrow:"↕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"Ï…",Upsi:"Ï’",upsih:"Ï’",upsilon:"Ï…",Upsilon:"Î¥",UpTee:"⊥",UpTeeArrow:"↥",upuparrows:"⇈",urcorn:"âŒ",urcorner:"âŒ",urcrop:"⌎",uring:"ů",Uring:"Å®",urtri:"â—¹",uscr:"ð“Š",Uscr:"ð’°",utdot:"â‹°",utilde:"Å©",Utilde:"Ũ",utri:"â–µ",utrif:"â–´",uuarr:"⇈",uuml:"ü",Uuml:"Ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"Ï•",varpi:"Ï–",varpropto:"âˆ",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"Ï‚",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"Ï‘",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"â««",vBarv:"â«©",vcy:"в",Vcy:"Ð’",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",vee:"∨",Vee:"â‹",veebar:"⊻",veeeq:"≚",vellip:"â‹®",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"â˜",VerticalTilde:"≀",VeryThinSpace:" ",vfr:"ð”³",Vfr:"ð”™",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",vopf:"ð•§",Vopf:"ð•",vprop:"âˆ",vrtri:"⊳",vscr:"ð“‹",Vscr:"ð’±",vsubne:"⊊︀",vsubnE:"⫋︀",vsupne:"⊋︀",vsupnE:"⫌︀",Vvdash:"⊪",vzigzag:"⦚",wcirc:"ŵ",Wcirc:"Å´",wedbar:"⩟",wedge:"∧",Wedge:"â‹€",wedgeq:"≙",weierp:"℘",wfr:"ð”´",Wfr:"ð”š",wopf:"ð•¨",Wopf:"ð•Ž",wp:"℘",wr:"≀",wreath:"≀",wscr:"ð“Œ",Wscr:"ð’²",xcap:"â‹‚",xcirc:"â—¯",xcup:"⋃",xdtri:"â–½",xfr:"ð”µ",Xfr:"ð”›",xharr:"⟷",xhArr:"⟺",xi:"ξ",Xi:"Ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"â‹»",xodot:"⨀",xopf:"ð•©",Xopf:"ð•",xoplus:"â¨",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",xscr:"ð“",Xscr:"ð’³",xsqcup:"⨆",xuplus:"⨄",xutri:"â–³",xvee:"â‹",xwedge:"â‹€",yacute:"ý",Yacute:"Ã",yacy:"Ñ",YAcy:"Я",ycirc:"Å·",Ycirc:"Ŷ",ycy:"Ñ‹",Ycy:"Ы",yen:"Â¥",yfr:"ð”¶",Yfr:"ð”œ",yicy:"Ñ—",YIcy:"Ї",yopf:"ð•ª",Yopf:"ð•",yscr:"ð“Ž",Yscr:"ð’´",yucy:"ÑŽ",YUcy:"Ю",yuml:"ÿ",Yuml:"Ÿ",zacute:"ź",Zacute:"Ź",zcaron:"ž",Zcaron:"Ž",zcy:"з",Zcy:"З",zdot:"ż",Zdot:"Å»",zeetrf:"ℨ",ZeroWidthSpace:"​",zeta:"ζ",Zeta:"Ζ",zfr:"ð”·",Zfr:"ℨ",zhcy:"ж",ZHcy:"Ж",zigrarr:"â‡",zopf:"ð•«",Zopf:"ℤ",zscr:"ð“",Zscr:"ð’µ",zwj:"â€",zwnj:"‌"},b={aacute:"á",Aacute:"Ã",acirc:"â",Acirc:"Â",acute:"´",aelig:"æ",AElig:"Æ",agrave:"à",Agrave:"À",amp:"&",AMP:"&",aring:"Ã¥",Aring:"Ã…",atilde:"ã",Atilde:"Ã",auml:"ä",Auml:"Ä",brvbar:"¦",ccedil:"ç",Ccedil:"Ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",eacute:"é",Eacute:"É",ecirc:"ê",Ecirc:"Ê",egrave:"è",Egrave:"È",eth:"ð",ETH:"Ã",euml:"ë",Euml:"Ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",iacute:"í",Iacute:"Ã",icirc:"î",Icirc:"ÃŽ",iexcl:"¡",igrave:"ì",Igrave:"ÃŒ",iquest:"¿",iuml:"ï",Iuml:"Ã",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",ntilde:"ñ",Ntilde:"Ñ",oacute:"ó",Oacute:"Ó",ocirc:"ô",Ocirc:"Ô",ograve:"ò",Ograve:"Ã’",ordf:"ª",ordm:"º",oslash:"ø",Oslash:"Ø",otilde:"õ",Otilde:"Õ",ouml:"ö",Ouml:"Ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",thorn:"þ",THORN:"Þ",times:"×",uacute:"ú",Uacute:"Ú",ucirc:"û",Ucirc:"Û",ugrave:"ù",Ugrave:"Ù",uml:"¨",uuml:"ü",Uuml:"Ü",yacute:"ý",Yacute:"Ã",yen:"Â¥",yuml:"ÿ"},y={0:"�",128:"€",130:"‚",131:"Æ’",132:"„",133:"…",134:"†",135:"‡",136:"ˆ",137:"‰",138:"Å ",139:"‹",140:"Å’",142:"Ž",145:"‘",146:"’",147:"“",148:"â€",149:"•",150:"–",151:"—",152:"Ëœ",153:"â„¢",154:"Å¡",155:"›",156:"Å“",158:"ž",159:"Ÿ"},w=[1,2,3,4,5,6,7,8,11,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,64976,64977,64978,64979,64980,64981,64982,64983,64984,64985,64986,64987,64988,64989,64990,64991,64992,64993,64994,64995,64996,64997,64998,64999,65e3,65001,65002,65003,65004,65005,65006,65007,65534,65535,131070,131071,196606,196607,262142,262143,327678,327679,393214,393215,458750,458751,524286,524287,589822,589823,655358,655359,720894,720895,786430,786431,851966,851967,917502,917503,983038,983039,1048574,1048575,1114110,1114111],_=String.fromCharCode,x={}.hasOwnProperty,E=function(e,t){return x.call(e,t)},A=function(e,t){if(!e)return t;var r,n={};for(r in t)n[r]=E(e,r)?e[r]:t[r];return n},D=function(e,t){var r="";return e>=55296&&e<=57343||e>1114111?(t&&C("character reference outside the permissible Unicode range"),"�"):E(y,e)?(t&&C("disallowed character reference"),y[e]):(t&&function(e,t){for(var r=-1,n=e.length;++r65535&&(r+=_((e-=65536)>>>10&1023|55296),e=56320|1023&e),r+=_(e))},T=function(e){return"&#x"+e.toString(16).toUpperCase()+";"},q=function(e){return"&#"+e+";"},C=function(e){throw Error("Parse error: "+e)},k=function(e,t){(t=A(t,k.options)).strict&&g.test(e)&&C("forbidden code point");var r=t.encodeEverything,n=t.useNamedReferences,i=t.allowUnsafeSymbols,o=t.decimal?q:T,s=function(e){return o(e.charCodeAt(0))};return r?(e=e.replace(l,(function(e){return n&&E(p,e)?"&"+p[e]+";":s(e)})),n&&(e=e.replace(/>\u20D2/g,">⃒").replace(/<\u20D2/g,"<⃒").replace(/fj/g,"fj")),n&&(e=e.replace(u,(function(e){return"&"+p[e]+";"})))):n?(i||(e=e.replace(d,(function(e){return"&"+p[e]+";"}))),e=(e=e.replace(/>\u20D2/g,">⃒").replace(/<\u20D2/g,"<⃒")).replace(u,(function(e){return"&"+p[e]+";"}))):i||(e=e.replace(d,s)),e.replace(a,(function(e){var t=e.charCodeAt(0),r=e.charCodeAt(1);return o(1024*(t-55296)+r-56320+65536)})).replace(c,s)};k.options={allowUnsafeSymbols:!1,encodeEverything:!1,strict:!1,useNamedReferences:!1,decimal:!1};var S=function(e,t){var r=(t=A(t,S.options)).strict;return r&&h.test(e)&&C("malformed character reference"),e.replace(m,(function(e,n,i,o,s,a,l,c,u){var p,d,f,h,g,m;return n?v[g=n]:i?(g=i,(m=o)&&t.isAttributeValue?(r&&"="==m&&C("`&` did not start a character reference"),e):(r&&C("named character reference was not terminated by a semicolon"),b[g]+(m||""))):s?(f=s,d=a,r&&!d&&C("character reference was not terminated by a semicolon"),p=parseInt(f,10),D(p,r)):l?(h=l,d=c,r&&!d&&C("character reference was not terminated by a semicolon"),p=parseInt(h,16),D(p,r)):(r&&C("named character reference was not terminated by a semicolon"),e)}))};S.options={isAttributeValue:!1,strict:!1};var L={version:"1.2.0",encode:k,decode:S,escape:function(e){return e.replace(d,(function(e){return f[e]}))},unescape:S};void 0===(n=function(){return L}.call(t,r,t,e))||(e.exports=n)}()},755:function(e,t){var r;!function(t,r){"use strict";"object"==typeof e.exports?e.exports=t.document?r(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return r(e)}:r(t)}("undefined"!=typeof window?window:this,(function(n,i){"use strict";var o=[],s=Object.getPrototypeOf,a=o.slice,l=o.flat?function(e){return o.flat.call(e)}:function(e){return o.concat.apply([],e)},c=o.push,u=o.indexOf,p={},d=p.toString,f=p.hasOwnProperty,h=f.toString,g=h.call(Object),m={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},b=function(e){return null!=e&&e===e.window},y=n.document,w={type:!0,src:!0,nonce:!0,noModule:!0};function _(e,t,r){var n,i,o=(r=r||y).createElement("script");if(o.text=e,t)for(n in w)(i=t[n]||t.getAttribute&&t.getAttribute(n))&&o.setAttribute(n,i);r.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?p[d.call(e)]||"object":typeof e}var E="3.7.1",A=/HTML$/i,D=function(e,t){return new D.fn.init(e,t)};function T(e){var t=!!e&&"length"in e&&e.length,r=x(e);return!v(e)&&!b(e)&&("array"===r||0===t||"number"==typeof t&&t>0&&t-1 in e)}function q(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}D.fn=D.prototype={jquery:E,constructor:D,length:0,toArray:function(){return a.call(this)},get:function(e){return null==e?a.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=D.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return D.each(this,e)},map:function(e){return this.pushStack(D.map(this,(function(t,r){return e.call(t,r,t)})))},slice:function(){return this.pushStack(a.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(D.grep(this,(function(e,t){return(t+1)%2})))},odd:function(){return this.pushStack(D.grep(this,(function(e,t){return t%2})))},eq:function(e){var t=this.length,r=+e+(e<0?t:0);return this.pushStack(r>=0&&r+~]|"+L+")"+L+"*"),M=new RegExp(L+"|>"),U=new RegExp(F),V=new RegExp("^"+O+"$"),$={ID:new RegExp("^#("+O+")"),CLASS:new RegExp("^\\.("+O+")"),TAG:new RegExp("^("+O+"|[*])"),ATTR:new RegExp("^"+j),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+T+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},z=/^(?:input|select|textarea|button)$/i,G=/^h\d$/i,W=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Y=/[+~]/,X=new RegExp("\\\\[\\da-fA-F]{1,6}"+L+"?|\\\\([^\\r\\n\\f])","g"),K=function(e,t){var r="0x"+e.slice(1)-65536;return t||(r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320))},J=function(){le()},Q=de((function(e){return!0===e.disabled&&q(e,"fieldset")}),{dir:"parentNode",next:"legend"});try{g.apply(o=a.call(R.childNodes),R.childNodes),o[R.childNodes.length].nodeType}catch(e){g={apply:function(e,t){B.apply(e,a.call(t))},call:function(e){B.apply(e,a.call(arguments,1))}}}function Z(e,t,r,n){var i,o,s,a,c,u,f,h=t&&t.ownerDocument,b=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==b&&9!==b&&11!==b)return r;if(!n&&(le(t),t=t||l,p)){if(11!==b&&(c=W.exec(e)))if(i=c[1]){if(9===b){if(!(s=t.getElementById(i)))return r;if(s.id===i)return g.call(r,s),r}else if(h&&(s=h.getElementById(i))&&Z.contains(t,s)&&s.id===i)return g.call(r,s),r}else{if(c[2])return g.apply(r,t.getElementsByTagName(e)),r;if((i=c[3])&&t.getElementsByClassName)return g.apply(r,t.getElementsByClassName(i)),r}if(!(E[e+" "]||d&&d.test(e))){if(f=e,h=t,1===b&&(M.test(e)||H.test(e))){for((h=Y.test(e)&&ae(t.parentNode)||t)==t&&m.scope||((a=t.getAttribute("id"))?a=D.escapeSelector(a):t.setAttribute("id",a=v)),o=(u=ue(e)).length;o--;)u[o]=(a?"#"+a:":scope")+" "+pe(u[o]);f=u.join(",")}try{return g.apply(r,h.querySelectorAll(f)),r}catch(t){E(e,!0)}finally{a===v&&t.removeAttribute("id")}}}return be(e.replace(N,"$1"),t,r,n)}function ee(){var e=[];return function r(n,i){return e.push(n+" ")>t.cacheLength&&delete r[e.shift()],r[n+" "]=i}}function te(e){return e[v]=!0,e}function re(e){var t=l.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ne(e){return function(t){return q(t,"input")&&t.type===e}}function ie(e){return function(t){return(q(t,"input")||q(t,"button"))&&t.type===e}}function oe(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&Q(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function se(e){return te((function(t){return t=+t,te((function(r,n){for(var i,o=e([],r.length,t),s=o.length;s--;)r[i=o[s]]&&(r[i]=!(n[i]=r[i]))}))}))}function ae(e){return e&&void 0!==e.getElementsByTagName&&e}function le(e){var r,n=e?e.ownerDocument||e:R;return n!=l&&9===n.nodeType&&n.documentElement?(c=(l=n).documentElement,p=!D.isXMLDoc(l),h=c.matches||c.webkitMatchesSelector||c.msMatchesSelector,c.msMatchesSelector&&R!=l&&(r=l.defaultView)&&r.top!==r&&r.addEventListener("unload",J),m.getById=re((function(e){return c.appendChild(e).id=D.expando,!l.getElementsByName||!l.getElementsByName(D.expando).length})),m.disconnectedMatch=re((function(e){return h.call(e,"*")})),m.scope=re((function(){return l.querySelectorAll(":scope")})),m.cssHas=re((function(){try{return l.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}})),m.getById?(t.filter.ID=function(e){var t=e.replace(X,K);return function(e){return e.getAttribute("id")===t}},t.find.ID=function(e,t){if(void 0!==t.getElementById&&p){var r=t.getElementById(e);return r?[r]:[]}}):(t.filter.ID=function(e){var t=e.replace(X,K);return function(e){var r=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return r&&r.value===t}},t.find.ID=function(e,t){if(void 0!==t.getElementById&&p){var r,n,i,o=t.getElementById(e);if(o){if((r=o.getAttributeNode("id"))&&r.value===e)return[o];for(i=t.getElementsByName(e),n=0;o=i[n++];)if((r=o.getAttributeNode("id"))&&r.value===e)return[o]}return[]}}),t.find.TAG=function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},t.find.CLASS=function(e,t){if(void 0!==t.getElementsByClassName&&p)return t.getElementsByClassName(e)},d=[],re((function(e){var t;c.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+L+"*(?:value|"+T+")"),e.querySelectorAll("[id~="+v+"-]").length||d.push("~="),e.querySelectorAll("a#"+v+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=l.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),c.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=l.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+L+"*name"+L+"*="+L+"*(?:''|\"\")")})),m.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),A=function(e,t){if(e===t)return s=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!m.sortDetached&&t.compareDocumentPosition(e)===r?e===l||e.ownerDocument==R&&Z.contains(R,e)?-1:t===l||t.ownerDocument==R&&Z.contains(R,t)?1:i?u.call(i,e)-u.call(i,t):0:4&r?-1:1)},l):l}for(e in Z.matches=function(e,t){return Z(e,null,null,t)},Z.matchesSelector=function(e,t){if(le(e),p&&!E[t+" "]&&(!d||!d.test(t)))try{var r=h.call(e,t);if(r||m.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){E(t,!0)}return Z(t,l,null,[e]).length>0},Z.contains=function(e,t){return(e.ownerDocument||e)!=l&&le(e),D.contains(e,t)},Z.attr=function(e,r){(e.ownerDocument||e)!=l&&le(e);var n=t.attrHandle[r.toLowerCase()],i=n&&f.call(t.attrHandle,r.toLowerCase())?n(e,r,!p):void 0;return void 0!==i?i:e.getAttribute(r)},Z.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},D.uniqueSort=function(e){var t,r=[],n=0,o=0;if(s=!m.sortStable,i=!m.sortStable&&a.call(e,0),k.call(e,A),s){for(;t=e[o++];)t===e[o]&&(n=r.push(o));for(;n--;)S.call(e,r[n],1)}return i=null,e},D.fn.uniqueSort=function(){return this.pushStack(D.uniqueSort(a.apply(this)))},t=D.expr={cacheLength:50,createPseudo:te,match:$,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(X,K),e[3]=(e[3]||e[4]||e[5]||"").replace(X,K),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||Z.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&Z.error(e[0]),e},PSEUDO:function(e){var t,r=!e[6]&&e[2];return $.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":r&&U.test(r)&&(t=ue(r,!0))&&(t=r.indexOf(")",r.length-t)-r.length)&&(e[0]=e[0].slice(0,t),e[2]=r.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(X,K).toLowerCase();return"*"===e?function(){return!0}:function(e){return q(e,t)}},CLASS:function(e){var t=w[e+" "];return t||(t=new RegExp("(^|"+L+")"+e+"("+L+"|$)"))&&w(e,(function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")}))},ATTR:function(e,t,r){return function(n){var i=Z.attr(n,e);return null==i?"!="===t:!t||(i+="","="===t?i===r:"!="===t?i!==r:"^="===t?r&&0===i.indexOf(r):"*="===t?r&&i.indexOf(r)>-1:"$="===t?r&&i.slice(-r.length)===r:"~="===t?(" "+i.replace(I," ")+" ").indexOf(r)>-1:"|="===t&&(i===r||i.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,r,n,i){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===n&&0===i?function(e){return!!e.parentNode}:function(t,r,l){var c,u,p,d,f,h=o!==s?"nextSibling":"previousSibling",g=t.parentNode,m=a&&t.nodeName.toLowerCase(),y=!l&&!a,w=!1;if(g){if(o){for(;h;){for(p=t;p=p[h];)if(a?q(p,m):1===p.nodeType)return!1;f=h="only"===e&&!f&&"nextSibling"}return!0}if(f=[s?g.firstChild:g.lastChild],s&&y){for(w=(d=(c=(u=g[v]||(g[v]={}))[e]||[])[0]===b&&c[1])&&c[2],p=d&&g.childNodes[d];p=++d&&p&&p[h]||(w=d=0)||f.pop();)if(1===p.nodeType&&++w&&p===t){u[e]=[b,d,w];break}}else if(y&&(w=d=(c=(u=t[v]||(t[v]={}))[e]||[])[0]===b&&c[1]),!1===w)for(;(p=++d&&p&&p[h]||(w=d=0)||f.pop())&&(!(a?q(p,m):1===p.nodeType)||!++w||(y&&((u=p[v]||(p[v]={}))[e]=[b,w]),p!==t)););return(w-=i)===n||w%n==0&&w/n>=0}}},PSEUDO:function(e,r){var n,i=t.pseudos[e]||t.setFilters[e.toLowerCase()]||Z.error("unsupported pseudo: "+e);return i[v]?i(r):i.length>1?(n=[e,e,"",r],t.setFilters.hasOwnProperty(e.toLowerCase())?te((function(e,t){for(var n,o=i(e,r),s=o.length;s--;)e[n=u.call(e,o[s])]=!(t[n]=o[s])})):function(e){return i(e,0,n)}):i}},pseudos:{not:te((function(e){var t=[],r=[],n=ve(e.replace(N,"$1"));return n[v]?te((function(e,t,r,i){for(var o,s=n(e,null,i,[]),a=e.length;a--;)(o=s[a])&&(e[a]=!(t[a]=o))})):function(e,i,o){return t[0]=e,n(t,null,o,r),t[0]=null,!r.pop()}})),has:te((function(e){return function(t){return Z(e,t).length>0}})),contains:te((function(e){return e=e.replace(X,K),function(t){return(t.textContent||D.text(t)).indexOf(e)>-1}})),lang:te((function(e){return V.test(e||"")||Z.error("unsupported lang: "+e),e=e.replace(X,K).toLowerCase(),function(t){var r;do{if(r=p?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(r=r.toLowerCase())===e||0===r.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}})),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===c},focus:function(e){return e===function(){try{return l.activeElement}catch(e){}}()&&l.hasFocus()&&!!(e.type||e.href||~e.tabIndex)},enabled:oe(!1),disabled:oe(!0),checked:function(e){return q(e,"input")&&!!e.checked||q(e,"option")&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!t.pseudos.empty(e)},header:function(e){return G.test(e.nodeName)},input:function(e){return z.test(e.nodeName)},button:function(e){return q(e,"input")&&"button"===e.type||q(e,"button")},text:function(e){var t;return q(e,"input")&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:se((function(){return[0]})),last:se((function(e,t){return[t-1]})),eq:se((function(e,t,r){return[r<0?r+t:r]})),even:se((function(e,t){for(var r=0;rt?t:r;--n>=0;)e.push(n);return e})),gt:se((function(e,t,r){for(var n=r<0?r+t:r;++n1?function(t,r,n){for(var i=e.length;i--;)if(!e[i](t,r,n))return!1;return!0}:e[0]}function he(e,t,r,n,i){for(var o,s=[],a=0,l=e.length,c=null!=t;a-1&&(o[c]=!(s[c]=d))}}else f=he(f===s?f.splice(v,f.length):f),i?i(null,s,f,l):g.apply(s,f)}))}function me(e){for(var n,i,o,s=e.length,a=t.relative[e[0].type],l=a||t.relative[" "],c=a?1:0,p=de((function(e){return e===n}),l,!0),d=de((function(e){return u.call(n,e)>-1}),l,!0),f=[function(e,t,i){var o=!a&&(i||t!=r)||((n=t).nodeType?p(e,t,i):d(e,t,i));return n=null,o}];c1&&fe(f),c>1&&pe(e.slice(0,c-1).concat({value:" "===e[c-2].type?"*":""})).replace(N,"$1"),i,c0,o=e.length>0,s=function(s,a,c,u,d){var f,h,m,v=0,y="0",w=s&&[],_=[],x=r,E=s||o&&t.find.TAG("*",d),A=b+=null==x?1:Math.random()||.1,T=E.length;for(d&&(r=a==l||a||d);y!==T&&null!=(f=E[y]);y++){if(o&&f){for(h=0,a||f.ownerDocument==l||(le(f),c=!p);m=e[h++];)if(m(f,a||l,c)){g.call(u,f);break}d&&(b=A)}i&&((f=!m&&f)&&v--,s&&w.push(f))}if(v+=y,i&&y!==v){for(h=0;m=n[h++];)m(w,_,a,c);if(s){if(v>0)for(;y--;)w[y]||_[y]||(_[y]=C.call(u));_=he(_)}g.apply(u,_),d&&!s&&_.length>0&&v+n.length>1&&D.uniqueSort(u)}return d&&(b=A,r=x),w};return i?te(s):s}(s,o)),a.selector=e}return a}function be(e,r,n,i){var o,s,a,l,c,u="function"==typeof e&&e,d=!i&&ue(e=u.selector||e);if(n=n||[],1===d.length){if((s=d[0]=d[0].slice(0)).length>2&&"ID"===(a=s[0]).type&&9===r.nodeType&&p&&t.relative[s[1].type]){if(!(r=(t.find.ID(a.matches[0].replace(X,K),r)||[])[0]))return n;u&&(r=r.parentNode),e=e.slice(s.shift().value.length)}for(o=$.needsContext.test(e)?0:s.length;o--&&(a=s[o],!t.relative[l=a.type]);)if((c=t.find[l])&&(i=c(a.matches[0].replace(X,K),Y.test(s[0].type)&&ae(r.parentNode)||r))){if(s.splice(o,1),!(e=i.length&&pe(s)))return g.apply(n,i),n;break}}return(u||ve(e,d))(i,r,!p,n,!r||Y.test(e)&&ae(r.parentNode)||r),n}ce.prototype=t.filters=t.pseudos,t.setFilters=new ce,m.sortStable=v.split("").sort(A).join("")===v,le(),m.sortDetached=re((function(e){return 1&e.compareDocumentPosition(l.createElement("fieldset"))})),D.find=Z,D.expr[":"]=D.expr.pseudos,D.unique=D.uniqueSort,Z.compile=ve,Z.select=be,Z.setDocument=le,Z.tokenize=ue,Z.escape=D.escapeSelector,Z.getText=D.text,Z.isXML=D.isXMLDoc,Z.selectors=D.expr,Z.support=D.support,Z.uniqueSort=D.uniqueSort}();var F=function(e,t,r){for(var n=[],i=void 0!==r;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&D(e).is(r))break;n.push(e)}return n},I=function(e,t){for(var r=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&r.push(e);return r},P=D.expr.match.needsContext,H=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function M(e,t,r){return v(t)?D.grep(e,(function(e,n){return!!t.call(e,n,e)!==r})):t.nodeType?D.grep(e,(function(e){return e===t!==r})):"string"!=typeof t?D.grep(e,(function(e){return u.call(t,e)>-1!==r})):D.filter(t,e,r)}D.filter=function(e,t,r){var n=t[0];return r&&(e=":not("+e+")"),1===t.length&&1===n.nodeType?D.find.matchesSelector(n,e)?[n]:[]:D.find.matches(e,D.grep(t,(function(e){return 1===e.nodeType})))},D.fn.extend({find:function(e){var t,r,n=this.length,i=this;if("string"!=typeof e)return this.pushStack(D(e).filter((function(){for(t=0;t1?D.uniqueSort(r):r},filter:function(e){return this.pushStack(M(this,e||[],!1))},not:function(e){return this.pushStack(M(this,e||[],!0))},is:function(e){return!!M(this,"string"==typeof e&&P.test(e)?D(e):e||[],!1).length}});var U,V=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(D.fn.init=function(e,t,r){var n,i;if(!e)return this;if(r=r||U,"string"==typeof e){if(!(n="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:V.exec(e))||!n[1]&&t)return!t||t.jquery?(t||r).find(e):this.constructor(t).find(e);if(n[1]){if(t=t instanceof D?t[0]:t,D.merge(this,D.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:y,!0)),H.test(n[1])&&D.isPlainObject(t))for(n in t)v(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}return(i=y.getElementById(n[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==r.ready?r.ready(e):e(D):D.makeArray(e,this)}).prototype=D.fn,U=D(y);var $=/^(?:parents|prev(?:Until|All))/,z={children:!0,contents:!0,next:!0,prev:!0};function G(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}D.fn.extend({has:function(e){var t=D(e,this),r=t.length;return this.filter((function(){for(var e=0;e-1:1===r.nodeType&&D.find.matchesSelector(r,e))){o.push(r);break}return this.pushStack(o.length>1?D.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(D(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(D.uniqueSort(D.merge(this.get(),D(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),D.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return F(e,"parentNode")},parentsUntil:function(e,t,r){return F(e,"parentNode",r)},next:function(e){return G(e,"nextSibling")},prev:function(e){return G(e,"previousSibling")},nextAll:function(e){return F(e,"nextSibling")},prevAll:function(e){return F(e,"previousSibling")},nextUntil:function(e,t,r){return F(e,"nextSibling",r)},prevUntil:function(e,t,r){return F(e,"previousSibling",r)},siblings:function(e){return I((e.parentNode||{}).firstChild,e)},children:function(e){return I(e.firstChild)},contents:function(e){return null!=e.contentDocument&&s(e.contentDocument)?e.contentDocument:(q(e,"template")&&(e=e.content||e),D.merge([],e.childNodes))}},(function(e,t){D.fn[e]=function(r,n){var i=D.map(this,t,r);return"Until"!==e.slice(-5)&&(n=r),n&&"string"==typeof n&&(i=D.filter(n,i)),this.length>1&&(z[e]||D.uniqueSort(i),$.test(e)&&i.reverse()),this.pushStack(i)}}));var W=/[^\x20\t\r\n\f]+/g;function Y(e){return e}function X(e){throw e}function K(e,t,r,n){var i;try{e&&v(i=e.promise)?i.call(e).done(t).fail(r):e&&v(i=e.then)?i.call(e,t,r):t.apply(void 0,[e].slice(n))}catch(e){r.apply(void 0,[e])}}D.Callbacks=function(e){e="string"==typeof e?function(e){var t={};return D.each(e.match(W)||[],(function(e,r){t[r]=!0})),t}(e):D.extend({},e);var t,r,n,i,o=[],s=[],a=-1,l=function(){for(i=i||e.once,n=t=!0;s.length;a=-1)for(r=s.shift();++a-1;)o.splice(r,1),r<=a&&a--})),this},has:function(e){return e?D.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=s=[],o=r="",this},disabled:function(){return!o},lock:function(){return i=s=[],r||t||(o=r=""),this},locked:function(){return!!i},fireWith:function(e,r){return i||(r=[e,(r=r||[]).slice?r.slice():r],s.push(r),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!n}};return c},D.extend({Deferred:function(e){var t=[["notify","progress",D.Callbacks("memory"),D.Callbacks("memory"),2],["resolve","done",D.Callbacks("once memory"),D.Callbacks("once memory"),0,"resolved"],["reject","fail",D.Callbacks("once memory"),D.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return D.Deferred((function(r){D.each(t,(function(t,n){var i=v(e[n[4]])&&e[n[4]];o[n[1]]((function(){var e=i&&i.apply(this,arguments);e&&v(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[n[0]+"With"](this,i?[e]:arguments)}))})),e=null})).promise()},then:function(e,r,i){var o=0;function s(e,t,r,i){return function(){var a=this,l=arguments,c=function(){var n,c;if(!(e=o&&(r!==X&&(a=void 0,l=[n]),t.rejectWith(a,l))}};e?u():(D.Deferred.getErrorHook?u.error=D.Deferred.getErrorHook():D.Deferred.getStackHook&&(u.error=D.Deferred.getStackHook()),n.setTimeout(u))}}return D.Deferred((function(n){t[0][3].add(s(0,n,v(i)?i:Y,n.notifyWith)),t[1][3].add(s(0,n,v(e)?e:Y)),t[2][3].add(s(0,n,v(r)?r:X))})).promise()},promise:function(e){return null!=e?D.extend(e,i):i}},o={};return D.each(t,(function(e,n){var s=n[2],a=n[5];i[n[1]]=s.add,a&&s.add((function(){r=a}),t[3-e][2].disable,t[3-e][3].disable,t[0][2].lock,t[0][3].lock),s.add(n[3].fire),o[n[0]]=function(){return o[n[0]+"With"](this===o?void 0:this,arguments),this},o[n[0]+"With"]=s.fireWith})),i.promise(o),e&&e.call(o,o),o},when:function(e){var t=arguments.length,r=t,n=Array(r),i=a.call(arguments),o=D.Deferred(),s=function(e){return function(r){n[e]=this,i[e]=arguments.length>1?a.call(arguments):r,--t||o.resolveWith(n,i)}};if(t<=1&&(K(e,o.done(s(r)).resolve,o.reject,!t),"pending"===o.state()||v(i[r]&&i[r].then)))return o.then();for(;r--;)K(i[r],s(r),o.reject);return o.promise()}});var J=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;D.Deferred.exceptionHook=function(e,t){n.console&&n.console.warn&&e&&J.test(e.name)&&n.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},D.readyException=function(e){n.setTimeout((function(){throw e}))};var Q=D.Deferred();function Z(){y.removeEventListener("DOMContentLoaded",Z),n.removeEventListener("load",Z),D.ready()}D.fn.ready=function(e){return Q.then(e).catch((function(e){D.readyException(e)})),this},D.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--D.readyWait:D.isReady)||(D.isReady=!0,!0!==e&&--D.readyWait>0||Q.resolveWith(y,[D]))}}),D.ready.then=Q.then,"complete"===y.readyState||"loading"!==y.readyState&&!y.documentElement.doScroll?n.setTimeout(D.ready):(y.addEventListener("DOMContentLoaded",Z),n.addEventListener("load",Z));var ee=function(e,t,r,n,i,o,s){var a=0,l=e.length,c=null==r;if("object"===x(r))for(a in i=!0,r)ee(e,t,a,r[a],!0,o,s);else if(void 0!==n&&(i=!0,v(n)||(s=!0),c&&(s?(t.call(e,n),t=null):(c=t,t=function(e,t,r){return c.call(D(e),r)})),t))for(;a1,null,!0)},removeData:function(e){return this.each((function(){le.remove(this,e)}))}}),D.extend({queue:function(e,t,r){var n;if(e)return t=(t||"fx")+"queue",n=ae.get(e,t),r&&(!n||Array.isArray(r)?n=ae.access(e,t,D.makeArray(r)):n.push(r)),n||[]},dequeue:function(e,t){t=t||"fx";var r=D.queue(e,t),n=r.length,i=r.shift(),o=D._queueHooks(e,t);"inprogress"===i&&(i=r.shift(),n--),i&&("fx"===t&&r.unshift("inprogress"),delete o.stop,i.call(e,(function(){D.dequeue(e,t)}),o)),!n&&o&&o.empty.fire()},_queueHooks:function(e,t){var r=t+"queueHooks";return ae.get(e,r)||ae.access(e,r,{empty:D.Callbacks("once memory").add((function(){ae.remove(e,[t+"queue",r])}))})}}),D.fn.extend({queue:function(e,t){var r=2;return"string"!=typeof e&&(t=e,e="fx",r--),arguments.length\x20\t\r\n\f]*)/i,qe=/^$|^module$|\/(?:java|ecma)script/i;Ee=y.createDocumentFragment().appendChild(y.createElement("div")),(Ae=y.createElement("input")).setAttribute("type","radio"),Ae.setAttribute("checked","checked"),Ae.setAttribute("name","t"),Ee.appendChild(Ae),m.checkClone=Ee.cloneNode(!0).cloneNode(!0).lastChild.checked,Ee.innerHTML="",m.noCloneChecked=!!Ee.cloneNode(!0).lastChild.defaultValue,Ee.innerHTML="",m.option=!!Ee.lastChild;var Ce={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ke(e,t){var r;return r=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&q(e,t)?D.merge([e],r):r}function Se(e,t){for(var r=0,n=e.length;r",""]);var Le=/<|&#?\w+;/;function Ne(e,t,r,n,i){for(var o,s,a,l,c,u,p=t.createDocumentFragment(),d=[],f=0,h=e.length;f-1)i&&i.push(o);else if(c=me(o),s=ke(p.appendChild(o),"script"),c&&Se(s),r)for(u=0;o=s[u++];)qe.test(o.type||"")&&r.push(o);return p}var Oe=/^([^.]*)(?:\.(.+)|)/;function je(){return!0}function Re(){return!1}function Be(e,t,r,n,i,o){var s,a;if("object"==typeof t){for(a in"string"!=typeof r&&(n=n||r,r=void 0),t)Be(e,a,r,n,t[a],o);return e}if(null==n&&null==i?(i=r,n=r=void 0):null==i&&("string"==typeof r?(i=n,n=void 0):(i=n,n=r,r=void 0)),!1===i)i=Re;else if(!i)return e;return 1===o&&(s=i,i=function(e){return D().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=D.guid++)),e.each((function(){D.event.add(this,t,i,n,r)}))}function Fe(e,t,r){r?(ae.set(e,t,!1),D.event.add(e,t,{namespace:!1,handler:function(e){var r,n=ae.get(this,t);if(1&e.isTrigger&&this[t]){if(n)(D.event.special[t]||{}).delegateType&&e.stopPropagation();else if(n=a.call(arguments),ae.set(this,t,n),this[t](),r=ae.get(this,t),ae.set(this,t,!1),n!==r)return e.stopImmediatePropagation(),e.preventDefault(),r}else n&&(ae.set(this,t,D.event.trigger(n[0],n.slice(1),this)),e.stopPropagation(),e.isImmediatePropagationStopped=je)}})):void 0===ae.get(e,t)&&D.event.add(e,t,je)}D.event={global:{},add:function(e,t,r,n,i){var o,s,a,l,c,u,p,d,f,h,g,m=ae.get(e);if(oe(e))for(r.handler&&(r=(o=r).handler,i=o.selector),i&&D.find.matchesSelector(ge,i),r.guid||(r.guid=D.guid++),(l=m.events)||(l=m.events=Object.create(null)),(s=m.handle)||(s=m.handle=function(t){return void 0!==D&&D.event.triggered!==t.type?D.event.dispatch.apply(e,arguments):void 0}),c=(t=(t||"").match(W)||[""]).length;c--;)f=g=(a=Oe.exec(t[c])||[])[1],h=(a[2]||"").split(".").sort(),f&&(p=D.event.special[f]||{},f=(i?p.delegateType:p.bindType)||f,p=D.event.special[f]||{},u=D.extend({type:f,origType:g,data:n,handler:r,guid:r.guid,selector:i,needsContext:i&&D.expr.match.needsContext.test(i),namespace:h.join(".")},o),(d=l[f])||((d=l[f]=[]).delegateCount=0,p.setup&&!1!==p.setup.call(e,n,h,s)||e.addEventListener&&e.addEventListener(f,s)),p.add&&(p.add.call(e,u),u.handler.guid||(u.handler.guid=r.guid)),i?d.splice(d.delegateCount++,0,u):d.push(u),D.event.global[f]=!0)},remove:function(e,t,r,n,i){var o,s,a,l,c,u,p,d,f,h,g,m=ae.hasData(e)&&ae.get(e);if(m&&(l=m.events)){for(c=(t=(t||"").match(W)||[""]).length;c--;)if(f=g=(a=Oe.exec(t[c])||[])[1],h=(a[2]||"").split(".").sort(),f){for(p=D.event.special[f]||{},d=l[f=(n?p.delegateType:p.bindType)||f]||[],a=a[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=d.length;o--;)u=d[o],!i&&g!==u.origType||r&&r.guid!==u.guid||a&&!a.test(u.namespace)||n&&n!==u.selector&&("**"!==n||!u.selector)||(d.splice(o,1),u.selector&&d.delegateCount--,p.remove&&p.remove.call(e,u));s&&!d.length&&(p.teardown&&!1!==p.teardown.call(e,h,m.handle)||D.removeEvent(e,f,m.handle),delete l[f])}else for(f in l)D.event.remove(e,f+t[c],r,n,!0);D.isEmptyObject(l)&&ae.remove(e,"handle events")}},dispatch:function(e){var t,r,n,i,o,s,a=new Array(arguments.length),l=D.event.fix(e),c=(ae.get(this,"events")||Object.create(null))[l.type]||[],u=D.event.special[l.type]||{};for(a[0]=l,t=1;t=1))for(;c!==this;c=c.parentNode||this)if(1===c.nodeType&&("click"!==e.type||!0!==c.disabled)){for(o=[],s={},r=0;r-1:D.find(i,this,null,[c]).length),s[i]&&o.push(n);o.length&&a.push({elem:c,handlers:o})}return c=this,l\s*$/g;function Me(e,t){return q(e,"table")&&q(11!==t.nodeType?t:t.firstChild,"tr")&&D(e).children("tbody")[0]||e}function Ue(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Ve(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function $e(e,t){var r,n,i,o,s,a;if(1===t.nodeType){if(ae.hasData(e)&&(a=ae.get(e).events))for(i in ae.remove(t,"handle events"),a)for(r=0,n=a[i].length;r1&&"string"==typeof h&&!m.checkClone&&Pe.test(h))return e.each((function(i){var o=e.eq(i);g&&(t[0]=h.call(this,i,o.html())),Ge(o,t,r,n)}));if(d&&(o=(i=Ne(t,e[0].ownerDocument,!1,e,n)).firstChild,1===i.childNodes.length&&(i=o),o||n)){for(a=(s=D.map(ke(i,"script"),Ue)).length;p0&&Se(s,!l&&ke(e,"script")),a},cleanData:function(e){for(var t,r,n,i=D.event.special,o=0;void 0!==(r=e[o]);o++)if(oe(r)){if(t=r[ae.expando]){if(t.events)for(n in t.events)i[n]?D.event.remove(r,n):D.removeEvent(r,n,t.handle);r[ae.expando]=void 0}r[le.expando]&&(r[le.expando]=void 0)}}}),D.fn.extend({detach:function(e){return We(this,e,!0)},remove:function(e){return We(this,e)},text:function(e){return ee(this,(function(e){return void 0===e?D.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return Ge(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Me(this,e).appendChild(e)}))},prepend:function(){return Ge(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Me(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return Ge(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return Ge(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(D.cleanData(ke(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return D.clone(this,e,t)}))},html:function(e){return ee(this,(function(e){var t=this[0]||{},r=0,n=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ie.test(e)&&!Ce[(Te.exec(e)||["",""])[1].toLowerCase()]){e=D.htmlPrefilter(e);try{for(;r=0&&(l+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-l-a-.5))||0),l+c}function ut(e,t,r){var n=Ke(e),i=(!m.boxSizingReliable()||r)&&"border-box"===D.css(e,"boxSizing",!1,n),o=i,s=Ze(e,t,n),a="offset"+t[0].toUpperCase()+t.slice(1);if(Ye.test(s)){if(!r)return s;s="auto"}return(!m.boxSizingReliable()&&i||!m.reliableTrDimensions()&&q(e,"tr")||"auto"===s||!parseFloat(s)&&"inline"===D.css(e,"display",!1,n))&&e.getClientRects().length&&(i="border-box"===D.css(e,"boxSizing",!1,n),(o=a in e)&&(s=e[a])),(s=parseFloat(s)||0)+ct(e,t,r||(i?"border":"content"),o,n,s)+"px"}function pt(e,t,r,n,i){return new pt.prototype.init(e,t,r,n,i)}D.extend({cssHooks:{opacity:{get:function(e,t){if(t){var r=Ze(e,"opacity");return""===r?"1":r}}}},cssNumber:{animationIterationCount:!0,aspectRatio:!0,borderImageSlice:!0,columnCount:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,scale:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeMiterlimit:!0,strokeOpacity:!0},cssProps:{},style:function(e,t,r,n){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=ie(t),l=Xe.test(t),c=e.style;if(l||(t=it(a)),s=D.cssHooks[t]||D.cssHooks[a],void 0===r)return s&&"get"in s&&void 0!==(i=s.get(e,!1,n))?i:c[t];"string"===(o=typeof r)&&(i=fe.exec(r))&&i[1]&&(r=ye(e,t,i),o="number"),null!=r&&r==r&&("number"!==o||l||(r+=i&&i[3]||(D.cssNumber[a]?"":"px")),m.clearCloneStyle||""!==r||0!==t.indexOf("background")||(c[t]="inherit"),s&&"set"in s&&void 0===(r=s.set(e,r,n))||(l?c.setProperty(t,r):c[t]=r))}},css:function(e,t,r,n){var i,o,s,a=ie(t);return Xe.test(t)||(t=it(a)),(s=D.cssHooks[t]||D.cssHooks[a])&&"get"in s&&(i=s.get(e,!0,r)),void 0===i&&(i=Ze(e,t,n)),"normal"===i&&t in at&&(i=at[t]),""===r||r?(o=parseFloat(i),!0===r||isFinite(o)?o||0:i):i}}),D.each(["height","width"],(function(e,t){D.cssHooks[t]={get:function(e,r,n){if(r)return!ot.test(D.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?ut(e,t,n):Je(e,st,(function(){return ut(e,t,n)}))},set:function(e,r,n){var i,o=Ke(e),s=!m.scrollboxSize()&&"absolute"===o.position,a=(s||n)&&"border-box"===D.css(e,"boxSizing",!1,o),l=n?ct(e,t,n,a,o):0;return a&&s&&(l-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-ct(e,t,"border",!1,o)-.5)),l&&(i=fe.exec(r))&&"px"!==(i[3]||"px")&&(e.style[t]=r,r=D.css(e,t)),lt(0,r,l)}}})),D.cssHooks.marginLeft=et(m.reliableMarginLeft,(function(e,t){if(t)return(parseFloat(Ze(e,"marginLeft"))||e.getBoundingClientRect().left-Je(e,{marginLeft:0},(function(){return e.getBoundingClientRect().left})))+"px"})),D.each({margin:"",padding:"",border:"Width"},(function(e,t){D.cssHooks[e+t]={expand:function(r){for(var n=0,i={},o="string"==typeof r?r.split(" "):[r];n<4;n++)i[e+he[n]+t]=o[n]||o[n-2]||o[0];return i}},"margin"!==e&&(D.cssHooks[e+t].set=lt)})),D.fn.extend({css:function(e,t){return ee(this,(function(e,t,r){var n,i,o={},s=0;if(Array.isArray(t)){for(n=Ke(e),i=t.length;s1)}}),D.Tween=pt,pt.prototype={constructor:pt,init:function(e,t,r,n,i,o){this.elem=e,this.prop=r,this.easing=i||D.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=n,this.unit=o||(D.cssNumber[r]?"":"px")},cur:function(){var e=pt.propHooks[this.prop];return e&&e.get?e.get(this):pt.propHooks._default.get(this)},run:function(e){var t,r=pt.propHooks[this.prop];return this.options.duration?this.pos=t=D.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),r&&r.set?r.set(this):pt.propHooks._default.set(this),this}},pt.prototype.init.prototype=pt.prototype,pt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=D.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){D.fx.step[e.prop]?D.fx.step[e.prop](e):1!==e.elem.nodeType||!D.cssHooks[e.prop]&&null==e.elem.style[it(e.prop)]?e.elem[e.prop]=e.now:D.style(e.elem,e.prop,e.now+e.unit)}}},pt.propHooks.scrollTop=pt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},D.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},D.fx=pt.prototype.init,D.fx.step={};var dt,ft,ht=/^(?:toggle|show|hide)$/,gt=/queueHooks$/;function mt(){ft&&(!1===y.hidden&&n.requestAnimationFrame?n.requestAnimationFrame(mt):n.setTimeout(mt,D.fx.interval),D.fx.tick())}function vt(){return n.setTimeout((function(){dt=void 0})),dt=Date.now()}function bt(e,t){var r,n=0,i={height:e};for(t=t?1:0;n<4;n+=2-t)i["margin"+(r=he[n])]=i["padding"+r]=e;return t&&(i.opacity=i.width=e),i}function yt(e,t,r){for(var n,i=(wt.tweeners[t]||[]).concat(wt.tweeners["*"]),o=0,s=i.length;o1)},removeAttr:function(e){return this.each((function(){D.removeAttr(this,e)}))}}),D.extend({attr:function(e,t,r){var n,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?D.prop(e,t,r):(1===o&&D.isXMLDoc(e)||(i=D.attrHooks[t.toLowerCase()]||(D.expr.match.bool.test(t)?_t:void 0)),void 0!==r?null===r?void D.removeAttr(e,t):i&&"set"in i&&void 0!==(n=i.set(e,r,t))?n:(e.setAttribute(t,r+""),r):i&&"get"in i&&null!==(n=i.get(e,t))?n:null==(n=D.find.attr(e,t))?void 0:n)},attrHooks:{type:{set:function(e,t){if(!m.radioValue&&"radio"===t&&q(e,"input")){var r=e.value;return e.setAttribute("type",t),r&&(e.value=r),t}}}},removeAttr:function(e,t){var r,n=0,i=t&&t.match(W);if(i&&1===e.nodeType)for(;r=i[n++];)e.removeAttribute(r)}}),_t={set:function(e,t,r){return!1===t?D.removeAttr(e,r):e.setAttribute(r,r),r}},D.each(D.expr.match.bool.source.match(/\w+/g),(function(e,t){var r=xt[t]||D.find.attr;xt[t]=function(e,t,n){var i,o,s=t.toLowerCase();return n||(o=xt[s],xt[s]=i,i=null!=r(e,t,n)?s:null,xt[s]=o),i}}));var Et=/^(?:input|select|textarea|button)$/i,At=/^(?:a|area)$/i;function Dt(e){return(e.match(W)||[]).join(" ")}function Tt(e){return e.getAttribute&&e.getAttribute("class")||""}function qt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(W)||[]}D.fn.extend({prop:function(e,t){return ee(this,D.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each((function(){delete this[D.propFix[e]||e]}))}}),D.extend({prop:function(e,t,r){var n,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&D.isXMLDoc(e)||(t=D.propFix[t]||t,i=D.propHooks[t]),void 0!==r?i&&"set"in i&&void 0!==(n=i.set(e,r,t))?n:e[t]=r:i&&"get"in i&&null!==(n=i.get(e,t))?n:e[t]},propHooks:{tabIndex:{get:function(e){var t=D.find.attr(e,"tabindex");return t?parseInt(t,10):Et.test(e.nodeName)||At.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),m.optSelected||(D.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),D.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){D.propFix[this.toLowerCase()]=this})),D.fn.extend({addClass:function(e){var t,r,n,i,o,s;return v(e)?this.each((function(t){D(this).addClass(e.call(this,t,Tt(this)))})):(t=qt(e)).length?this.each((function(){if(n=Tt(this),r=1===this.nodeType&&" "+Dt(n)+" "){for(o=0;o-1;)r=r.replace(" "+i+" "," ");s=Dt(r),n!==s&&this.setAttribute("class",s)}})):this:this.attr("class","")},toggleClass:function(e,t){var r,n,i,o,s=typeof e,a="string"===s||Array.isArray(e);return v(e)?this.each((function(r){D(this).toggleClass(e.call(this,r,Tt(this),t),t)})):"boolean"==typeof t&&a?t?this.addClass(e):this.removeClass(e):(r=qt(e),this.each((function(){if(a)for(o=D(this),i=0;i-1)return!0;return!1}});var Ct=/\r/g;D.fn.extend({val:function(e){var t,r,n,i=this[0];return arguments.length?(n=v(e),this.each((function(r){var i;1===this.nodeType&&(null==(i=n?e.call(this,r,D(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=D.map(i,(function(e){return null==e?"":e+""}))),(t=D.valHooks[this.type]||D.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))}))):i?(t=D.valHooks[i.type]||D.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(r=t.get(i,"value"))?r:"string"==typeof(r=i.value)?r.replace(Ct,""):null==r?"":r:void 0}}),D.extend({valHooks:{option:{get:function(e){var t=D.find.attr(e,"value");return null!=t?t:Dt(D.text(e))}},select:{get:function(e){var t,r,n,i=e.options,o=e.selectedIndex,s="select-one"===e.type,a=s?null:[],l=s?o+1:i.length;for(n=o<0?l:s?o:0;n-1)&&(r=!0);return r||(e.selectedIndex=-1),o}}}}),D.each(["radio","checkbox"],(function(){D.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=D.inArray(D(e).val(),t)>-1}},m.checkOn||(D.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}));var kt=n.location,St={guid:Date.now()},Lt=/\?/;D.parseXML=function(e){var t,r;if(!e||"string"!=typeof e)return null;try{t=(new n.DOMParser).parseFromString(e,"text/xml")}catch(e){}return r=t&&t.getElementsByTagName("parsererror")[0],t&&!r||D.error("Invalid XML: "+(r?D.map(r.childNodes,(function(e){return e.textContent})).join("\n"):e)),t};var Nt=/^(?:focusinfocus|focusoutblur)$/,Ot=function(e){e.stopPropagation()};D.extend(D.event,{trigger:function(e,t,r,i){var o,s,a,l,c,u,p,d,h=[r||y],g=f.call(e,"type")?e.type:e,m=f.call(e,"namespace")?e.namespace.split("."):[];if(s=d=a=r=r||y,3!==r.nodeType&&8!==r.nodeType&&!Nt.test(g+D.event.triggered)&&(g.indexOf(".")>-1&&(m=g.split("."),g=m.shift(),m.sort()),c=g.indexOf(":")<0&&"on"+g,(e=e[D.expando]?e:new D.Event(g,"object"==typeof e&&e)).isTrigger=i?2:3,e.namespace=m.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=r),t=null==t?[e]:D.makeArray(t,[e]),p=D.event.special[g]||{},i||!p.trigger||!1!==p.trigger.apply(r,t))){if(!i&&!p.noBubble&&!b(r)){for(l=p.delegateType||g,Nt.test(l+g)||(s=s.parentNode);s;s=s.parentNode)h.push(s),a=s;a===(r.ownerDocument||y)&&h.push(a.defaultView||a.parentWindow||n)}for(o=0;(s=h[o++])&&!e.isPropagationStopped();)d=s,e.type=o>1?l:p.bindType||g,(u=(ae.get(s,"events")||Object.create(null))[e.type]&&ae.get(s,"handle"))&&u.apply(s,t),(u=c&&s[c])&&u.apply&&oe(s)&&(e.result=u.apply(s,t),!1===e.result&&e.preventDefault());return e.type=g,i||e.isDefaultPrevented()||p._default&&!1!==p._default.apply(h.pop(),t)||!oe(r)||c&&v(r[g])&&!b(r)&&((a=r[c])&&(r[c]=null),D.event.triggered=g,e.isPropagationStopped()&&d.addEventListener(g,Ot),r[g](),e.isPropagationStopped()&&d.removeEventListener(g,Ot),D.event.triggered=void 0,a&&(r[c]=a)),e.result}},simulate:function(e,t,r){var n=D.extend(new D.Event,r,{type:e,isSimulated:!0});D.event.trigger(n,null,t)}}),D.fn.extend({trigger:function(e,t){return this.each((function(){D.event.trigger(e,t,this)}))},triggerHandler:function(e,t){var r=this[0];if(r)return D.event.trigger(e,t,r,!0)}});var jt=/\[\]$/,Rt=/\r?\n/g,Bt=/^(?:submit|button|image|reset|file)$/i,Ft=/^(?:input|select|textarea|keygen)/i;function It(e,t,r,n){var i;if(Array.isArray(t))D.each(t,(function(t,i){r||jt.test(e)?n(e,i):It(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,r,n)}));else if(r||"object"!==x(t))n(e,t);else for(i in t)It(e+"["+i+"]",t[i],r,n)}D.param=function(e,t){var r,n=[],i=function(e,t){var r=v(t)?t():t;n[n.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==r?"":r)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!D.isPlainObject(e))D.each(e,(function(){i(this.name,this.value)}));else for(r in e)It(r,e[r],t,i);return n.join("&")},D.fn.extend({serialize:function(){return D.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var e=D.prop(this,"elements");return e?D.makeArray(e):this})).filter((function(){var e=this.type;return this.name&&!D(this).is(":disabled")&&Ft.test(this.nodeName)&&!Bt.test(e)&&(this.checked||!De.test(e))})).map((function(e,t){var r=D(this).val();return null==r?null:Array.isArray(r)?D.map(r,(function(e){return{name:t.name,value:e.replace(Rt,"\r\n")}})):{name:t.name,value:r.replace(Rt,"\r\n")}})).get()}});var Pt=/%20/g,Ht=/#.*$/,Mt=/([?&])_=[^&]*/,Ut=/^(.*?):[ \t]*([^\r\n]*)$/gm,Vt=/^(?:GET|HEAD)$/,$t=/^\/\//,zt={},Gt={},Wt="*/".concat("*"),Yt=y.createElement("a");function Xt(e){return function(t,r){"string"!=typeof t&&(r=t,t="*");var n,i=0,o=t.toLowerCase().match(W)||[];if(v(r))for(;n=o[i++];)"+"===n[0]?(n=n.slice(1)||"*",(e[n]=e[n]||[]).unshift(r)):(e[n]=e[n]||[]).push(r)}}function Kt(e,t,r,n){var i={},o=e===Gt;function s(a){var l;return i[a]=!0,D.each(e[a]||[],(function(e,a){var c=a(t,r,n);return"string"!=typeof c||o||i[c]?o?!(l=c):void 0:(t.dataTypes.unshift(c),s(c),!1)})),l}return s(t.dataTypes[0])||!i["*"]&&s("*")}function Jt(e,t){var r,n,i=D.ajaxSettings.flatOptions||{};for(r in t)void 0!==t[r]&&((i[r]?e:n||(n={}))[r]=t[r]);return n&&D.extend(!0,e,n),e}Yt.href=kt.href,D.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:kt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(kt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Wt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":D.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Jt(Jt(e,D.ajaxSettings),t):Jt(D.ajaxSettings,e)},ajaxPrefilter:Xt(zt),ajaxTransport:Xt(Gt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var r,i,o,s,a,l,c,u,p,d,f=D.ajaxSetup({},t),h=f.context||f,g=f.context&&(h.nodeType||h.jquery)?D(h):D.event,m=D.Deferred(),v=D.Callbacks("once memory"),b=f.statusCode||{},w={},_={},x="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s)for(s={};t=Ut.exec(o);)s[t[1].toLowerCase()+" "]=(s[t[1].toLowerCase()+" "]||[]).concat(t[2]);t=s[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return c?o:null},setRequestHeader:function(e,t){return null==c&&(e=_[e.toLowerCase()]=_[e.toLowerCase()]||e,w[e]=t),this},overrideMimeType:function(e){return null==c&&(f.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)b[t]=[b[t],e[t]];return this},abort:function(e){var t=e||x;return r&&r.abort(t),A(0,t),this}};if(m.promise(E),f.url=((e||f.url||kt.href)+"").replace($t,kt.protocol+"//"),f.type=t.method||t.type||f.method||f.type,f.dataTypes=(f.dataType||"*").toLowerCase().match(W)||[""],null==f.crossDomain){l=y.createElement("a");try{l.href=f.url,l.href=l.href,f.crossDomain=Yt.protocol+"//"+Yt.host!=l.protocol+"//"+l.host}catch(e){f.crossDomain=!0}}if(f.data&&f.processData&&"string"!=typeof f.data&&(f.data=D.param(f.data,f.traditional)),Kt(zt,f,t,E),c)return E;for(p in(u=D.event&&f.global)&&0==D.active++&&D.event.trigger("ajaxStart"),f.type=f.type.toUpperCase(),f.hasContent=!Vt.test(f.type),i=f.url.replace(Ht,""),f.hasContent?f.data&&f.processData&&0===(f.contentType||"").indexOf("application/x-www-form-urlencoded")&&(f.data=f.data.replace(Pt,"+")):(d=f.url.slice(i.length),f.data&&(f.processData||"string"==typeof f.data)&&(i+=(Lt.test(i)?"&":"?")+f.data,delete f.data),!1===f.cache&&(i=i.replace(Mt,"$1"),d=(Lt.test(i)?"&":"?")+"_="+St.guid+++d),f.url=i+d),f.ifModified&&(D.lastModified[i]&&E.setRequestHeader("If-Modified-Since",D.lastModified[i]),D.etag[i]&&E.setRequestHeader("If-None-Match",D.etag[i])),(f.data&&f.hasContent&&!1!==f.contentType||t.contentType)&&E.setRequestHeader("Content-Type",f.contentType),E.setRequestHeader("Accept",f.dataTypes[0]&&f.accepts[f.dataTypes[0]]?f.accepts[f.dataTypes[0]]+("*"!==f.dataTypes[0]?", "+Wt+"; q=0.01":""):f.accepts["*"]),f.headers)E.setRequestHeader(p,f.headers[p]);if(f.beforeSend&&(!1===f.beforeSend.call(h,E,f)||c))return E.abort();if(x="abort",v.add(f.complete),E.done(f.success),E.fail(f.error),r=Kt(Gt,f,t,E)){if(E.readyState=1,u&&g.trigger("ajaxSend",[E,f]),c)return E;f.async&&f.timeout>0&&(a=n.setTimeout((function(){E.abort("timeout")}),f.timeout));try{c=!1,r.send(w,A)}catch(e){if(c)throw e;A(-1,e)}}else A(-1,"No Transport");function A(e,t,s,l){var p,d,y,w,_,x=t;c||(c=!0,a&&n.clearTimeout(a),r=void 0,o=l||"",E.readyState=e>0?4:0,p=e>=200&&e<300||304===e,s&&(w=function(e,t,r){for(var n,i,o,s,a=e.contents,l=e.dataTypes;"*"===l[0];)l.shift(),void 0===n&&(n=e.mimeType||t.getResponseHeader("Content-Type"));if(n)for(i in a)if(a[i]&&a[i].test(n)){l.unshift(i);break}if(l[0]in r)o=l[0];else{for(i in r){if(!l[0]||e.converters[i+" "+l[0]]){o=i;break}s||(s=i)}o=o||s}if(o)return o!==l[0]&&l.unshift(o),r[o]}(f,E,s)),!p&&D.inArray("script",f.dataTypes)>-1&&D.inArray("json",f.dataTypes)<0&&(f.converters["text script"]=function(){}),w=function(e,t,r,n){var i,o,s,a,l,c={},u=e.dataTypes.slice();if(u[1])for(s in e.converters)c[s.toLowerCase()]=e.converters[s];for(o=u.shift();o;)if(e.responseFields[o]&&(r[e.responseFields[o]]=t),!l&&n&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=u.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(!(s=c[l+" "+o]||c["* "+o]))for(i in c)if((a=i.split(" "))[1]===o&&(s=c[l+" "+a[0]]||c["* "+a[0]])){!0===s?s=c[i]:!0!==c[i]&&(o=a[0],u.unshift(a[1]));break}if(!0!==s)if(s&&e.throws)t=s(t);else try{t=s(t)}catch(e){return{state:"parsererror",error:s?e:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}(f,w,E,p),p?(f.ifModified&&((_=E.getResponseHeader("Last-Modified"))&&(D.lastModified[i]=_),(_=E.getResponseHeader("etag"))&&(D.etag[i]=_)),204===e||"HEAD"===f.type?x="nocontent":304===e?x="notmodified":(x=w.state,d=w.data,p=!(y=w.error))):(y=x,!e&&x||(x="error",e<0&&(e=0))),E.status=e,E.statusText=(t||x)+"",p?m.resolveWith(h,[d,x,E]):m.rejectWith(h,[E,x,y]),E.statusCode(b),b=void 0,u&&g.trigger(p?"ajaxSuccess":"ajaxError",[E,f,p?d:y]),v.fireWith(h,[E,x]),u&&(g.trigger("ajaxComplete",[E,f]),--D.active||D.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,r){return D.get(e,t,r,"json")},getScript:function(e,t){return D.get(e,void 0,t,"script")}}),D.each(["get","post"],(function(e,t){D[t]=function(e,r,n,i){return v(r)&&(i=i||n,n=r,r=void 0),D.ajax(D.extend({url:e,type:t,dataType:i,data:r,success:n},D.isPlainObject(e)&&e))}})),D.ajaxPrefilter((function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")})),D._evalUrl=function(e,t,r){return D.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){D.globalEval(e,t,r)}})},D.fn.extend({wrapAll:function(e){var t;return this[0]&&(v(e)&&(e=e.call(this[0])),t=D(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map((function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e})).append(this)),this},wrapInner:function(e){return v(e)?this.each((function(t){D(this).wrapInner(e.call(this,t))})):this.each((function(){var t=D(this),r=t.contents();r.length?r.wrapAll(e):t.append(e)}))},wrap:function(e){var t=v(e);return this.each((function(r){D(this).wrapAll(t?e.call(this,r):e)}))},unwrap:function(e){return this.parent(e).not("body").each((function(){D(this).replaceWith(this.childNodes)})),this}}),D.expr.pseudos.hidden=function(e){return!D.expr.pseudos.visible(e)},D.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},D.ajaxSettings.xhr=function(){try{return new n.XMLHttpRequest}catch(e){}};var Qt={0:200,1223:204},Zt=D.ajaxSettings.xhr();m.cors=!!Zt&&"withCredentials"in Zt,m.ajax=Zt=!!Zt,D.ajaxTransport((function(e){var t,r;if(m.cors||Zt&&!e.crossDomain)return{send:function(i,o){var s,a=e.xhr();if(a.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(s in e.xhrFields)a[s]=e.xhrFields[s];for(s in e.mimeType&&a.overrideMimeType&&a.overrideMimeType(e.mimeType),e.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest"),i)a.setRequestHeader(s,i[s]);t=function(e){return function(){t&&(t=r=a.onload=a.onerror=a.onabort=a.ontimeout=a.onreadystatechange=null,"abort"===e?a.abort():"error"===e?"number"!=typeof a.status?o(0,"error"):o(a.status,a.statusText):o(Qt[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=t(),r=a.onerror=a.ontimeout=t("error"),void 0!==a.onabort?a.onabort=r:a.onreadystatechange=function(){4===a.readyState&&n.setTimeout((function(){t&&r()}))},t=t("abort");try{a.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}})),D.ajaxPrefilter((function(e){e.crossDomain&&(e.contents.script=!1)})),D.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return D.globalEval(e),e}}}),D.ajaxPrefilter("script",(function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")})),D.ajaxTransport("script",(function(e){var t,r;if(e.crossDomain||e.scriptAttrs)return{send:function(n,i){t=D(" - - - - - -
- - - \ No newline at end of file diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/Gruntfile.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/Gruntfile.d.ts deleted file mode 100644 index cb50cca6..00000000 --- a/components/wifi-manager/webapp/dist/src/bootswatch/Gruntfile.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare function _exports(grunt: any): void; -export = _exports; diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/2/Gruntfile.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/docs/2/Gruntfile.d.ts deleted file mode 100644 index cb50cca6..00000000 --- a/components/wifi-manager/webapp/dist/src/bootswatch/docs/2/Gruntfile.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare function _exports(grunt: any): void; -export = _exports; diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/2/js/bootswatch.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/docs/2/js/bootswatch.d.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/2/swatchmaker/test/bootswatch.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/docs/2/swatchmaker/test/bootswatch.d.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/3/Gruntfile.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/docs/3/Gruntfile.d.ts deleted file mode 100644 index cb50cca6..00000000 --- a/components/wifi-manager/webapp/dist/src/bootswatch/docs/3/Gruntfile.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare function _exports(grunt: any): void; -export = _exports; diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/3/assets/js/custom.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/docs/3/assets/js/custom.d.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/4/_assets/js/custom.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/docs/4/_assets/js/custom.d.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/_assets/js/custom.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/docs/_assets/js/custom.d.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/bootstrap/dist/js/bootstrap.bundle.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/bootstrap/dist/js/bootstrap.bundle.d.ts deleted file mode 100644 index 822c0cbf..00000000 --- a/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/bootstrap/dist/js/bootstrap.bundle.d.ts +++ /dev/null @@ -1,1129 +0,0 @@ -declare const Alert_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Alert extends Alert_base { - static get NAME(): string; - static jQueryInterface(config: any): any; - close(): void; - _destroyElement(): void; -} -declare const Button_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Button extends Button_base { - static get NAME(): string; - static jQueryInterface(config: any): any; - toggle(): void; -} -declare const Carousel_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Carousel extends Carousel_base { - static get Default(): { - interval: number; - keyboard: boolean; - pause: string; - ride: boolean; - touch: boolean; - wrap: boolean; - }; - static get DefaultType(): { - interval: string; - keyboard: string; - pause: string; - ride: string; - touch: string; - wrap: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _interval: NodeJS.Timeout; - _activeElement: any; - _isSliding: boolean; - touchTimeout: NodeJS.Timeout; - _swipeHelper: { - _element: any; - _config: any; - _deltaX: number; - _supportPointerEvents: boolean; - dispose(): void; - _start(event: any): void; - _end(event: any): void; - _move(event: any): void; - _handleSwipe(): void; - _initEvents(): void; - _eventIsPointerPenTouch(event: any): boolean; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _indicatorsElement: any; - next(): void; - nextWhenVisible(): void; - prev(): void; - pause(): void; - cycle(): void; - _maybeEnableCycle(): void; - to(index: any): void; - _addEventListeners(): void; - _addTouchEventListeners(): void; - _keydown(event: any): void; - _getItemIndex(element: any): number; - _setActiveIndicatorElement(index: any): void; - _updateInterval(): void; - _slide(order: any, element?: any): void; - _isAnimated(): any; - _getActive(): any; - _getItems(): any[]; - _clearInterval(): void; - _directionToOrder(direction: any): "next" | "prev"; - _orderToDirection(order: any): "right" | "left"; -} -declare const Collapse_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Collapse extends Collapse_base { - static get Default(): { - parent: any; - toggle: boolean; - }; - static get DefaultType(): { - parent: string; - toggle: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _isTransitioning: boolean; - _triggerArray: any[]; - toggle(): void; - show(): void; - hide(): void; - _isShown(element?: any): any; - _getDimension(): "width" | "height"; - _initializeChildren(): void; - _getFirstLevelChildren(selector: any): any[]; - _addAriaAndCollapsedClass(triggerArray: any, isOpen: any): void; -} -declare const Dropdown_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Dropdown extends Dropdown_base { - static get Default(): { - autoClose: boolean; - boundary: string; - display: string; - offset: number[]; - popperConfig: any; - reference: string; - }; - static get DefaultType(): { - autoClose: string; - boundary: string; - display: string; - offset: string; - popperConfig: string; - reference: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - static clearMenus(event: any): void; - static dataApiKeydownHandler(event: any): void; - _popper: { - state: { - placement: string; - orderedModifiers: any[]; - options: any; - modifiersData: {}; - elements: { - reference: any; - popper: any; - }; - attributes: {}; - styles: {}; - }; - setOptions: (setOptionsAction: any) => any; - forceUpdate: () => void; - update: () => any; - destroy: () => void; - }; - _parent: any; - _menu: any; - _inNavbar: boolean; - toggle(): void; - show(): void; - hide(): void; - update(): void; - _completeHide(relatedTarget: any): void; - _createPopper(): void; - _isShown(): any; - _getPlacement(): "top" | "bottom" | "top-end" | "top-start" | "bottom-end" | "bottom-start" | "left-start" | "right-start"; - _detectNavbar(): boolean; - _getOffset(): any; - _getPopperConfig(): any; - _selectMenuItem({ key, target }: { - key: any; - target: any; - }): void; -} -declare const Modal_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Modal extends Modal_base { - static get Default(): { - backdrop: boolean; - focus: boolean; - keyboard: boolean; - }; - static get DefaultType(): { - backdrop: string; - focus: string; - keyboard: string; - }; - static get NAME(): string; - static jQueryInterface(config: any, relatedTarget: any): any; - _dialog: any; - _backdrop: { - _config: any; - _isAppended: boolean; - _element: HTMLDivElement; - show(callback: any): void; - hide(callback: any): void; - dispose(): void; - _getElement(): HTMLDivElement; - _configAfterMerge(config: any): any; - _append(): void; - _emulateAnimation(callback: any): void; - _getConfig(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _focustrap: { - _config: any; - _isActive: boolean; - _lastTabNavDirection: string; - activate(): void; - deactivate(): void; - _handleFocusin(event: any): void; - _handleKeydown(event: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _isShown: boolean; - _isTransitioning: boolean; - _scrollBar: { - _element: HTMLElement; - getWidth(): number; - hide(): void; - reset(): void; - isOverflowing(): boolean; - _disableOverFlow(): void; - _setElementAttributes(selector: any, styleProperty: any, callback: any): void; - _saveInitialAttribute(element: any, styleProperty: any): void; - _resetElementAttributes(selector: any, styleProperty: any): void; - _applyManipulationCallback(selector: any, callBack: any): void; - }; - toggle(relatedTarget: any): void; - show(relatedTarget: any): void; - hide(): void; - handleUpdate(): void; - _initializeBackDrop(): { - _config: any; - _isAppended: boolean; - _element: HTMLDivElement; - show(callback: any): void; - hide(callback: any): void; - dispose(): void; - _getElement(): HTMLDivElement; - _configAfterMerge(config: any): any; - _append(): void; - _emulateAnimation(callback: any): void; - _getConfig(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _initializeFocusTrap(): { - _config: any; - _isActive: boolean; - _lastTabNavDirection: string; - activate(): void; - deactivate(): void; - _handleFocusin(event: any): void; - _handleKeydown(event: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _showElement(relatedTarget: any): void; - _addEventListeners(): void; - _hideModal(): void; - _isAnimated(): any; - _triggerBackdropTransition(): void; - /** - * The following methods are used to handle overflowing modals - */ - _adjustDialog(): void; - _resetAdjustments(): void; -} -declare const Offcanvas_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Offcanvas extends Offcanvas_base { - static get Default(): { - backdrop: boolean; - keyboard: boolean; - scroll: boolean; - }; - static get DefaultType(): { - backdrop: string; - keyboard: string; - scroll: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _isShown: boolean; - _backdrop: { - _config: any; - _isAppended: boolean; - _element: HTMLDivElement; - show(callback: any): void; - hide(callback: any): void; - dispose(): void; - _getElement(): HTMLDivElement; - _configAfterMerge(config: any): any; - _append(): void; - _emulateAnimation(callback: any): void; - _getConfig(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _focustrap: { - _config: any; - _isActive: boolean; - _lastTabNavDirection: string; - activate(): void; - deactivate(): void; - _handleFocusin(event: any): void; - _handleKeydown(event: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - toggle(relatedTarget: any): void; - show(relatedTarget: any): void; - hide(): void; - _initializeBackDrop(): { - _config: any; - _isAppended: boolean; - _element: HTMLDivElement; - show(callback: any): void; - hide(callback: any): void; - dispose(): void; - _getElement(): HTMLDivElement; - _configAfterMerge(config: any): any; - _append(): void; - _emulateAnimation(callback: any): void; - _getConfig(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _initializeFocusTrap(): { - _config: any; - _isActive: boolean; - _lastTabNavDirection: string; - activate(): void; - deactivate(): void; - _handleFocusin(event: any): void; - _handleKeydown(event: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _addEventListeners(): void; -} -declare const Popover_base: { - new (element: any, config: any): { - _isEnabled: boolean; - _timeout: number; - _isHovered: boolean; - _activeTrigger: {}; - _popper: { - state: { - placement: string; - orderedModifiers: any[]; - options: any; - modifiersData: {}; - elements: { - reference: any; - popper: any; - }; - attributes: {}; - styles: {}; - }; - setOptions: (setOptionsAction: any) => any; - forceUpdate: () => void; - update: () => any; - destroy: () => void; - }; - _templateFactory: { - _config: any; - getContent(): any[]; - hasContent(): boolean; - changeContent(content: any): any; - toHtml(): Element; - _typeCheckConfig(config: any): void; - _checkContent(arg: any): void; - _setContent(template: any, content: any, selector: any): void; - _maybeSanitize(arg: any): any; - _resolvePossibleFunction(arg: any): any; - _putElementInTemplate(element: any, templateElement: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - }; - _newContent: any; - tip: Element; - enable(): void; - disable(): void; - toggleEnabled(): void; - toggle(): void; - dispose(): void; - show(): void; - hide(): void; - update(): void; - _isWithContent(): boolean; - _getTipElement(): Element; - _createTipElement(content: any): Element; - setContent(content: any): void; - _getTemplateFactory(content: any): { - _config: any; - getContent(): any[]; - hasContent(): boolean; - changeContent(content: any): any; - toHtml(): Element; - _typeCheckConfig(config: any): void; - _checkContent(arg: any): void; - _setContent(template: any, content: any, selector: any): void; - _maybeSanitize(arg: any): any; - _resolvePossibleFunction(arg: any): any; - _putElementInTemplate(element: any, templateElement: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - }; - _getContentForTemplate(): { - ".tooltip-inner": any; - }; - _getTitle(): any; - _initializeOnDelegatedTarget(event: any): any; - _isAnimated(): any; - _isShown(): boolean; - _createPopper(tip: any): { - state: { - placement: string; - orderedModifiers: any[]; - options: any; - modifiersData: {}; - elements: { - reference: any; - popper: any; - }; - attributes: {}; - styles: {}; - }; - setOptions: (setOptionsAction: any) => any; - forceUpdate: () => void; - update: () => any; - destroy: () => void; - }; - _getOffset(): any; - _resolvePossibleFunction(arg: any): any; - _getPopperConfig(attachment: any): any; - _setListeners(): void; - _hideModalHandler: () => void; - _fixTitle(): void; - _enter(): void; - _leave(): void; - _setTimeout(handler: any, timeout: any): void; - _isWithActiveTrigger(): boolean; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _getDelegateConfig(): { - selector: boolean; - trigger: string; - }; - _disposePopper(): void; - _element: any; - _config: any; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - readonly Default: { - allowList: { - '*': (string | RegExp)[]; - a: string[]; - area: any[]; - b: any[]; - br: any[]; - col: any[]; - code: any[]; - div: any[]; - em: any[]; - hr: any[]; - h1: any[]; - h2: any[]; - h3: any[]; - h4: any[]; - h5: any[]; - h6: any[]; - i: any[]; - img: string[]; - li: any[]; - ol: any[]; - p: any[]; - pre: any[]; - s: any[]; - small: any[]; - span: any[]; - sub: any[]; - sup: any[]; - strong: any[]; - u: any[]; - ul: any[]; - }; - animation: boolean; - boundary: string; - container: boolean; - customClass: string; - delay: number; - fallbackPlacements: string[]; - html: boolean; - offset: number[]; - placement: string; - popperConfig: any; - sanitize: boolean; - sanitizeFn: any; - selector: boolean; - template: string; - title: string; - trigger: string; - }; - readonly DefaultType: { - allowList: string; - animation: string; - boundary: string; - container: string; - customClass: string; - delay: string; - fallbackPlacements: string; - html: string; - offset: string; - placement: string; - popperConfig: string; - sanitize: string; - sanitizeFn: string; - selector: string; - template: string; - title: string; - trigger: string; - }; - readonly NAME: string; - jQueryInterface(config: any): any; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; -}; -/** - * Class definition - */ -export class Popover extends Popover_base { - static get Default(): { - content: string; - offset: number[]; - placement: string; - template: string; - trigger: string; - allowList: { - '*': (string | RegExp)[]; - a: string[]; - area: any[]; - b: any[]; - br: any[]; - col: any[]; - code: any[]; - div: any[]; - em: any[]; - hr: any[]; - h1: any[]; - h2: any[]; - h3: any[]; - h4: any[]; - h5: any[]; - h6: any[]; - i: any[]; - img: string[]; - li: any[]; - ol: any[]; - p: any[]; - pre: any[]; - s: any[]; - small: any[]; - span: any[]; - sub: any[]; - sup: any[]; - strong: any[]; - u: any[]; - ul: any[]; - }; - animation: boolean; - boundary: string; - container: boolean; - customClass: string; - delay: number; - fallbackPlacements: string[]; - html: boolean; - popperConfig: any; - sanitize: boolean; - sanitizeFn: any; - selector: boolean; - title: string; - }; - static get DefaultType(): { - content: string; - allowList: string; - animation: string; - boundary: string; - container: string; - customClass: string; - delay: string; - fallbackPlacements: string; - html: string; - offset: string; - placement: string; - popperConfig: string; - sanitize: string; - sanitizeFn: string; - selector: string; - template: string; - title: string; - trigger: string; - }; - _isWithContent(): any; - _getContentForTemplate(): { - ".popover-header": any; - ".popover-body": any; - }; - _getContent(): any; -} -declare const ScrollSpy_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class ScrollSpy extends ScrollSpy_base { - static get Default(): { - offset: any; - rootMargin: string; - smoothScroll: boolean; - target: any; - threshold: number[]; - }; - static get DefaultType(): { - offset: string; - rootMargin: string; - smoothScroll: string; - target: string; - threshold: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _targetLinks: Map; - _observableSections: Map; - _rootElement: any; - _activeTarget: any; - _observer: IntersectionObserver; - _previousScrollData: { - visibleEntryTop: number; - parentScrollTop: number; - }; - refresh(): void; - _maybeEnableSmoothScroll(): void; - _getNewObserver(): IntersectionObserver; - _observerCallback(entries: any): void; - _initializeTargetsAndObservables(): void; - _process(target: any): void; - _activateParents(target: any): void; - _clearActiveClass(parent: any): void; -} -declare const Tab_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Tab extends Tab_base { - static get NAME(): string; - static jQueryInterface(config: any): any; - constructor(element: any); - _parent: any; - show(): void; - _activate(element: any, relatedElem: any): void; - _deactivate(element: any, relatedElem: any): void; - _keydown(event: any): void; - _getChildren(): any[]; - _getActiveElem(): any; - _setInitialAttributes(parent: any, children: any): void; - _setInitialAttributesOnChild(child: any): void; - _setInitialAttributesOnTargetPanel(child: any): void; - _toggleDropDown(element: any, open: any): void; - _setAttributeIfNotExists(element: any, attribute: any, value: any): void; - _elemIsActive(elem: any): any; - _getInnerElement(elem: any): any; - _getOuterElement(elem: any): any; -} -declare const Toast_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Toast extends Toast_base { - static get Default(): { - animation: boolean; - autohide: boolean; - delay: number; - }; - static get DefaultType(): { - animation: string; - autohide: string; - delay: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _timeout: NodeJS.Timeout; - _hasMouseInteraction: boolean; - _hasKeyboardInteraction: boolean; - show(): void; - hide(): void; - isShown(): any; - _maybeScheduleHide(): void; - _onInteraction(event: any, isInteracting: any): void; - _setListeners(): void; - _clearTimeout(): void; -} -declare const Tooltip_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Tooltip extends Tooltip_base { - static get Default(): { - allowList: { - '*': (string | RegExp)[]; - a: string[]; - area: any[]; - b: any[]; - br: any[]; - col: any[]; - code: any[]; - div: any[]; - em: any[]; - hr: any[]; - h1: any[]; - h2: any[]; - h3: any[]; - h4: any[]; - h5: any[]; - h6: any[]; - i: any[]; - img: string[]; - li: any[]; - ol: any[]; - p: any[]; - pre: any[]; - s: any[]; - small: any[]; - span: any[]; - sub: any[]; - sup: any[]; - strong: any[]; - u: any[]; - ul: any[]; - }; - animation: boolean; - boundary: string; - container: boolean; - customClass: string; - delay: number; - fallbackPlacements: string[]; - html: boolean; - offset: number[]; - placement: string; - popperConfig: any; - sanitize: boolean; - sanitizeFn: any; - selector: boolean; - template: string; - title: string; - trigger: string; - }; - static get DefaultType(): { - allowList: string; - animation: string; - boundary: string; - container: string; - customClass: string; - delay: string; - fallbackPlacements: string; - html: string; - offset: string; - placement: string; - popperConfig: string; - sanitize: string; - sanitizeFn: string; - selector: string; - template: string; - title: string; - trigger: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _isEnabled: boolean; - _timeout: number; - _isHovered: boolean; - _activeTrigger: {}; - _popper: { - state: { - placement: string; - orderedModifiers: any[]; - options: any; - modifiersData: {}; - elements: { - reference: any; - popper: any; - }; - attributes: {}; - styles: {}; - }; - setOptions: (setOptionsAction: any) => any; - forceUpdate: () => void; - update: () => any; - destroy: () => void; - }; - _templateFactory: { - _config: any; - getContent(): any[]; - hasContent(): boolean; - changeContent(content: any): any; - toHtml(): Element; - _typeCheckConfig(config: any): void; - _checkContent(arg: any): void; - _setContent(template: any, content: any, selector: any): void; - _maybeSanitize(arg: any): any; - _resolvePossibleFunction(arg: any): any; - _putElementInTemplate(element: any, templateElement: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - }; - _newContent: any; - tip: Element; - enable(): void; - disable(): void; - toggleEnabled(): void; - toggle(): void; - show(): void; - hide(): void; - update(): void; - _isWithContent(): boolean; - _getTipElement(): Element; - _createTipElement(content: any): Element; - setContent(content: any): void; - _getTemplateFactory(content: any): { - _config: any; - getContent(): any[]; - hasContent(): boolean; - changeContent(content: any): any; - toHtml(): Element; - _typeCheckConfig(config: any): void; - _checkContent(arg: any): void; - _setContent(template: any, content: any, selector: any): void; - _maybeSanitize(arg: any): any; - _resolvePossibleFunction(arg: any): any; - _putElementInTemplate(element: any, templateElement: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - }; - _getContentForTemplate(): { - ".tooltip-inner": any; - }; - _getTitle(): any; - _initializeOnDelegatedTarget(event: any): any; - _isAnimated(): any; - _isShown(): boolean; - _createPopper(tip: any): { - state: { - placement: string; - orderedModifiers: any[]; - options: any; - modifiersData: {}; - elements: { - reference: any; - popper: any; - }; - attributes: {}; - styles: {}; - }; - setOptions: (setOptionsAction: any) => any; - forceUpdate: () => void; - update: () => any; - destroy: () => void; - }; - _getOffset(): any; - _resolvePossibleFunction(arg: any): any; - _getPopperConfig(attachment: any): any; - _setListeners(): void; - _hideModalHandler: () => void; - _fixTitle(): void; - _enter(): void; - _leave(): void; - _setTimeout(handler: any, timeout: any): void; - _isWithActiveTrigger(): boolean; - _getDelegateConfig(): { - selector: boolean; - trigger: string; - }; - _disposePopper(): void; -} -export {}; diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/bootstrap/dist/js/bootstrap.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/bootstrap/dist/js/bootstrap.d.ts deleted file mode 100644 index d6d6bd89..00000000 --- a/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/bootstrap/dist/js/bootstrap.d.ts +++ /dev/null @@ -1,1044 +0,0 @@ -declare const Alert_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Alert extends Alert_base { - static get NAME(): string; - static jQueryInterface(config: any): any; - close(): void; - _destroyElement(): void; -} -declare const Button_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Button extends Button_base { - static get NAME(): string; - static jQueryInterface(config: any): any; - toggle(): void; -} -declare const Carousel_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Carousel extends Carousel_base { - static get Default(): { - interval: number; - keyboard: boolean; - pause: string; - ride: boolean; - touch: boolean; - wrap: boolean; - }; - static get DefaultType(): { - interval: string; - keyboard: string; - pause: string; - ride: string; - touch: string; - wrap: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _interval: NodeJS.Timeout; - _activeElement: any; - _isSliding: boolean; - touchTimeout: NodeJS.Timeout; - _swipeHelper: { - _element: any; - _config: any; - _deltaX: number; - _supportPointerEvents: boolean; - dispose(): void; - _start(event: any): void; - _end(event: any): void; - _move(event: any): void; - _handleSwipe(): void; - _initEvents(): void; - _eventIsPointerPenTouch(event: any): boolean; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _indicatorsElement: any; - next(): void; - nextWhenVisible(): void; - prev(): void; - pause(): void; - cycle(): void; - _maybeEnableCycle(): void; - to(index: any): void; - _addEventListeners(): void; - _addTouchEventListeners(): void; - _keydown(event: any): void; - _getItemIndex(element: any): number; - _setActiveIndicatorElement(index: any): void; - _updateInterval(): void; - _slide(order: any, element?: any): void; - _isAnimated(): any; - _getActive(): any; - _getItems(): any[]; - _clearInterval(): void; - _directionToOrder(direction: any): "next" | "prev"; - _orderToDirection(order: any): "right" | "left"; -} -declare const Collapse_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Collapse extends Collapse_base { - static get Default(): { - parent: any; - toggle: boolean; - }; - static get DefaultType(): { - parent: string; - toggle: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _isTransitioning: boolean; - _triggerArray: any[]; - toggle(): void; - show(): void; - hide(): void; - _isShown(element?: any): any; - _getDimension(): "width" | "height"; - _initializeChildren(): void; - _getFirstLevelChildren(selector: any): any[]; - _addAriaAndCollapsedClass(triggerArray: any, isOpen: any): void; -} -declare const Dropdown_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Dropdown extends Dropdown_base { - static get Default(): { - autoClose: boolean; - boundary: string; - display: string; - offset: number[]; - popperConfig: any; - reference: string; - }; - static get DefaultType(): { - autoClose: string; - boundary: string; - display: string; - offset: string; - popperConfig: string; - reference: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - static clearMenus(event: any): void; - static dataApiKeydownHandler(event: any): void; - _popper: any; - _parent: any; - _menu: any; - _inNavbar: boolean; - toggle(): void; - show(): void; - hide(): void; - update(): void; - _completeHide(relatedTarget: any): void; - _createPopper(): void; - _isShown(): any; - _getPlacement(): "top" | "bottom" | "top-end" | "top-start" | "bottom-end" | "bottom-start" | "left-start" | "right-start"; - _detectNavbar(): boolean; - _getOffset(): any; - _getPopperConfig(): any; - _selectMenuItem({ key, target }: { - key: any; - target: any; - }): void; -} -declare const Modal_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Modal extends Modal_base { - static get Default(): { - backdrop: boolean; - focus: boolean; - keyboard: boolean; - }; - static get DefaultType(): { - backdrop: string; - focus: string; - keyboard: string; - }; - static get NAME(): string; - static jQueryInterface(config: any, relatedTarget: any): any; - _dialog: any; - _backdrop: { - _config: any; - _isAppended: boolean; - _element: HTMLDivElement; - show(callback: any): void; - hide(callback: any): void; - dispose(): void; - _getElement(): HTMLDivElement; - _configAfterMerge(config: any): any; - _append(): void; - _emulateAnimation(callback: any): void; - _getConfig(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _focustrap: { - _config: any; - _isActive: boolean; - _lastTabNavDirection: string; - activate(): void; - deactivate(): void; - _handleFocusin(event: any): void; - _handleKeydown(event: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _isShown: boolean; - _isTransitioning: boolean; - _scrollBar: { - _element: HTMLElement; - getWidth(): number; - hide(): void; - reset(): void; - isOverflowing(): boolean; - _disableOverFlow(): void; - _setElementAttributes(selector: any, styleProperty: any, callback: any): void; - _saveInitialAttribute(element: any, styleProperty: any): void; - _resetElementAttributes(selector: any, styleProperty: any): void; - _applyManipulationCallback(selector: any, callBack: any): void; - }; - toggle(relatedTarget: any): void; - show(relatedTarget: any): void; - hide(): void; - handleUpdate(): void; - _initializeBackDrop(): { - _config: any; - _isAppended: boolean; - _element: HTMLDivElement; - show(callback: any): void; - hide(callback: any): void; - dispose(): void; - _getElement(): HTMLDivElement; - _configAfterMerge(config: any): any; - _append(): void; - _emulateAnimation(callback: any): void; - _getConfig(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _initializeFocusTrap(): { - _config: any; - _isActive: boolean; - _lastTabNavDirection: string; - activate(): void; - deactivate(): void; - _handleFocusin(event: any): void; - _handleKeydown(event: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _showElement(relatedTarget: any): void; - _addEventListeners(): void; - _hideModal(): void; - _isAnimated(): any; - _triggerBackdropTransition(): void; - /** - * The following methods are used to handle overflowing modals - */ - _adjustDialog(): void; - _resetAdjustments(): void; -} -declare const Offcanvas_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Offcanvas extends Offcanvas_base { - static get Default(): { - backdrop: boolean; - keyboard: boolean; - scroll: boolean; - }; - static get DefaultType(): { - backdrop: string; - keyboard: string; - scroll: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _isShown: boolean; - _backdrop: { - _config: any; - _isAppended: boolean; - _element: HTMLDivElement; - show(callback: any): void; - hide(callback: any): void; - dispose(): void; - _getElement(): HTMLDivElement; - _configAfterMerge(config: any): any; - _append(): void; - _emulateAnimation(callback: any): void; - _getConfig(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _focustrap: { - _config: any; - _isActive: boolean; - _lastTabNavDirection: string; - activate(): void; - deactivate(): void; - _handleFocusin(event: any): void; - _handleKeydown(event: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - toggle(relatedTarget: any): void; - show(relatedTarget: any): void; - hide(): void; - _initializeBackDrop(): { - _config: any; - _isAppended: boolean; - _element: HTMLDivElement; - show(callback: any): void; - hide(callback: any): void; - dispose(): void; - _getElement(): HTMLDivElement; - _configAfterMerge(config: any): any; - _append(): void; - _emulateAnimation(callback: any): void; - _getConfig(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _initializeFocusTrap(): { - _config: any; - _isActive: boolean; - _lastTabNavDirection: string; - activate(): void; - deactivate(): void; - _handleFocusin(event: any): void; - _handleKeydown(event: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - _addEventListeners(): void; -} -declare const Popover_base: { - new (element: any, config: any): { - _isEnabled: boolean; - _timeout: number; - _isHovered: boolean; - _activeTrigger: {}; - _popper: any; - _templateFactory: { - _config: any; - getContent(): any[]; - hasContent(): boolean; - changeContent(content: any): any; - toHtml(): Element; - _typeCheckConfig(config: any): void; - _checkContent(arg: any): void; - _setContent(template: any, content: any, selector: any): void; - _maybeSanitize(arg: any): any; - _resolvePossibleFunction(arg: any): any; - _putElementInTemplate(element: any, templateElement: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - }; - _newContent: any; - tip: Element; - enable(): void; - disable(): void; - toggleEnabled(): void; - toggle(): void; - dispose(): void; - show(): void; - hide(): void; - update(): void; - _isWithContent(): boolean; - _getTipElement(): Element; - _createTipElement(content: any): Element; - setContent(content: any): void; - _getTemplateFactory(content: any): { - _config: any; - getContent(): any[]; - hasContent(): boolean; - changeContent(content: any): any; - toHtml(): Element; - _typeCheckConfig(config: any): void; - _checkContent(arg: any): void; - _setContent(template: any, content: any, selector: any): void; - _maybeSanitize(arg: any): any; - _resolvePossibleFunction(arg: any): any; - _putElementInTemplate(element: any, templateElement: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - }; - _getContentForTemplate(): { - ".tooltip-inner": any; - }; - _getTitle(): any; - _initializeOnDelegatedTarget(event: any): any; - _isAnimated(): any; - _isShown(): boolean; - _createPopper(tip: any): any; - _getOffset(): any; - _resolvePossibleFunction(arg: any): any; - _getPopperConfig(attachment: any): any; - _setListeners(): void; - _hideModalHandler: () => void; - _fixTitle(): void; - _enter(): void; - _leave(): void; - _setTimeout(handler: any, timeout: any): void; - _isWithActiveTrigger(): boolean; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _getDelegateConfig(): { - selector: boolean; - trigger: string; - }; - _disposePopper(): void; - _element: any; - _config: any; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - readonly Default: { - allowList: { - '*': (string | RegExp)[]; - a: string[]; - area: any[]; - b: any[]; - br: any[]; - col: any[]; - code: any[]; - div: any[]; - em: any[]; - hr: any[]; - h1: any[]; - h2: any[]; - h3: any[]; - h4: any[]; - h5: any[]; - h6: any[]; - i: any[]; - img: string[]; - li: any[]; - ol: any[]; - p: any[]; - pre: any[]; - s: any[]; - small: any[]; - span: any[]; - sub: any[]; - sup: any[]; - strong: any[]; - u: any[]; - ul: any[]; - }; - animation: boolean; - boundary: string; - container: boolean; - customClass: string; - delay: number; - fallbackPlacements: string[]; - html: boolean; - offset: number[]; - placement: string; - popperConfig: any; - sanitize: boolean; - sanitizeFn: any; - selector: boolean; - template: string; - title: string; - trigger: string; - }; - readonly DefaultType: { - allowList: string; - animation: string; - boundary: string; - container: string; - customClass: string; - delay: string; - fallbackPlacements: string; - html: string; - offset: string; - placement: string; - popperConfig: string; - sanitize: string; - sanitizeFn: string; - selector: string; - template: string; - title: string; - trigger: string; - }; - readonly NAME: string; - jQueryInterface(config: any): any; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; -}; -/** - * Class definition - */ -export class Popover extends Popover_base { - static get Default(): { - content: string; - offset: number[]; - placement: string; - template: string; - trigger: string; - allowList: { - '*': (string | RegExp)[]; - a: string[]; - area: any[]; - b: any[]; - br: any[]; - col: any[]; - code: any[]; - div: any[]; - em: any[]; - hr: any[]; - h1: any[]; - h2: any[]; - h3: any[]; - h4: any[]; - h5: any[]; - h6: any[]; - i: any[]; - img: string[]; - li: any[]; - ol: any[]; - p: any[]; - pre: any[]; - s: any[]; - small: any[]; - span: any[]; - sub: any[]; - sup: any[]; - strong: any[]; - u: any[]; - ul: any[]; - }; - animation: boolean; - boundary: string; - container: boolean; - customClass: string; - delay: number; - fallbackPlacements: string[]; - html: boolean; - popperConfig: any; - sanitize: boolean; - sanitizeFn: any; - selector: boolean; - title: string; - }; - static get DefaultType(): { - content: string; - allowList: string; - animation: string; - boundary: string; - container: string; - customClass: string; - delay: string; - fallbackPlacements: string; - html: string; - offset: string; - placement: string; - popperConfig: string; - sanitize: string; - sanitizeFn: string; - selector: string; - template: string; - title: string; - trigger: string; - }; - _isWithContent(): any; - _getContentForTemplate(): { - ".popover-header": any; - ".popover-body": any; - }; - _getContent(): any; -} -declare const ScrollSpy_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class ScrollSpy extends ScrollSpy_base { - static get Default(): { - offset: any; - rootMargin: string; - smoothScroll: boolean; - target: any; - threshold: number[]; - }; - static get DefaultType(): { - offset: string; - rootMargin: string; - smoothScroll: string; - target: string; - threshold: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _targetLinks: Map; - _observableSections: Map; - _rootElement: any; - _activeTarget: any; - _observer: IntersectionObserver; - _previousScrollData: { - visibleEntryTop: number; - parentScrollTop: number; - }; - refresh(): void; - _maybeEnableSmoothScroll(): void; - _getNewObserver(): IntersectionObserver; - _observerCallback(entries: any): void; - _initializeTargetsAndObservables(): void; - _process(target: any): void; - _activateParents(target: any): void; - _clearActiveClass(parent: any): void; -} -declare const Tab_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Tab extends Tab_base { - static get NAME(): string; - static jQueryInterface(config: any): any; - constructor(element: any); - _parent: any; - show(): void; - _activate(element: any, relatedElem: any): void; - _deactivate(element: any, relatedElem: any): void; - _keydown(event: any): void; - _getChildren(): any[]; - _getActiveElem(): any; - _setInitialAttributes(parent: any, children: any): void; - _setInitialAttributesOnChild(child: any): void; - _setInitialAttributesOnTargetPanel(child: any): void; - _toggleDropDown(element: any, open: any): void; - _setAttributeIfNotExists(element: any, attribute: any, value: any): void; - _elemIsActive(elem: any): any; - _getInnerElement(elem: any): any; - _getOuterElement(elem: any): any; -} -declare const Toast_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Toast extends Toast_base { - static get Default(): { - animation: boolean; - autohide: boolean; - delay: number; - }; - static get DefaultType(): { - animation: string; - autohide: string; - delay: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _timeout: NodeJS.Timeout; - _hasMouseInteraction: boolean; - _hasKeyboardInteraction: boolean; - show(): void; - hide(): void; - isShown(): any; - _maybeScheduleHide(): void; - _onInteraction(event: any, isInteracting: any): void; - _setListeners(): void; - _clearTimeout(): void; -} -declare const Tooltip_base: { - new (element: any, config: any): { - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; - }; - getInstance(element: any): any; - getOrCreateInstance(element: any, config?: {}): any; - readonly VERSION: string; - readonly DATA_KEY: string; - readonly EVENT_KEY: string; - eventName(name: any): string; - readonly Default: {}; - readonly DefaultType: {}; - readonly NAME: void; -}; -/** - * Class definition - */ -export class Tooltip extends Tooltip_base { - static get Default(): { - allowList: { - '*': (string | RegExp)[]; - a: string[]; - area: any[]; - b: any[]; - br: any[]; - col: any[]; - code: any[]; - div: any[]; - em: any[]; - hr: any[]; - h1: any[]; - h2: any[]; - h3: any[]; - h4: any[]; - h5: any[]; - h6: any[]; - i: any[]; - img: string[]; - li: any[]; - ol: any[]; - p: any[]; - pre: any[]; - s: any[]; - small: any[]; - span: any[]; - sub: any[]; - sup: any[]; - strong: any[]; - u: any[]; - ul: any[]; - }; - animation: boolean; - boundary: string; - container: boolean; - customClass: string; - delay: number; - fallbackPlacements: string[]; - html: boolean; - offset: number[]; - placement: string; - popperConfig: any; - sanitize: boolean; - sanitizeFn: any; - selector: boolean; - template: string; - title: string; - trigger: string; - }; - static get DefaultType(): { - allowList: string; - animation: string; - boundary: string; - container: string; - customClass: string; - delay: string; - fallbackPlacements: string; - html: string; - offset: string; - placement: string; - popperConfig: string; - sanitize: string; - sanitizeFn: string; - selector: string; - template: string; - title: string; - trigger: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _isEnabled: boolean; - _timeout: number; - _isHovered: boolean; - _activeTrigger: {}; - _popper: any; - _templateFactory: { - _config: any; - getContent(): any[]; - hasContent(): boolean; - changeContent(content: any): any; - toHtml(): Element; - _typeCheckConfig(config: any): void; - _checkContent(arg: any): void; - _setContent(template: any, content: any, selector: any): void; - _maybeSanitize(arg: any): any; - _resolvePossibleFunction(arg: any): any; - _putElementInTemplate(element: any, templateElement: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - }; - _newContent: any; - tip: Element; - enable(): void; - disable(): void; - toggleEnabled(): void; - toggle(): void; - show(): void; - hide(): void; - update(): void; - _isWithContent(): boolean; - _getTipElement(): Element; - _createTipElement(content: any): Element; - setContent(content: any): void; - _getTemplateFactory(content: any): { - _config: any; - getContent(): any[]; - hasContent(): boolean; - changeContent(content: any): any; - toHtml(): Element; - _typeCheckConfig(config: any): void; - _checkContent(arg: any): void; - _setContent(template: any, content: any, selector: any): void; - _maybeSanitize(arg: any): any; - _resolvePossibleFunction(arg: any): any; - _putElementInTemplate(element: any, templateElement: any): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - }; - _getContentForTemplate(): { - ".tooltip-inner": any; - }; - _getTitle(): any; - _initializeOnDelegatedTarget(event: any): any; - _isAnimated(): any; - _isShown(): boolean; - _createPopper(tip: any): any; - _getOffset(): any; - _resolvePossibleFunction(arg: any): any; - _getPopperConfig(attachment: any): any; - _setListeners(): void; - _hideModalHandler: () => void; - _fixTitle(): void; - _enter(): void; - _leave(): void; - _setTimeout(handler: any, timeout: any): void; - _isWithActiveTrigger(): boolean; - _getDelegateConfig(): { - selector: boolean; - trigger: string; - }; - _disposePopper(): void; -} -export {}; diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/bootstrap/dist/js/bootstrap.esm.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/bootstrap/dist/js/bootstrap.esm.d.ts deleted file mode 100644 index 87d80a27..00000000 --- a/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/bootstrap/dist/js/bootstrap.esm.d.ts +++ /dev/null @@ -1,688 +0,0 @@ -/** - * Class definition - */ -export class Alert extends BaseComponent { - static get NAME(): string; - static jQueryInterface(config: any): any; - close(): void; - _destroyElement(): void; -} -/** - * Class definition - */ -export class Button extends BaseComponent { - static get NAME(): string; - static jQueryInterface(config: any): any; - toggle(): void; -} -/** - * Class definition - */ -export class Carousel extends BaseComponent { - static get Default(): { - interval: number; - keyboard: boolean; - pause: string; - ride: boolean; - touch: boolean; - wrap: boolean; - }; - static get DefaultType(): { - interval: string; - keyboard: string; - pause: string; - ride: string; - touch: string; - wrap: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _interval: NodeJS.Timeout; - _activeElement: any; - _isSliding: boolean; - touchTimeout: NodeJS.Timeout; - _swipeHelper: Swipe; - _indicatorsElement: any; - next(): void; - nextWhenVisible(): void; - prev(): void; - pause(): void; - cycle(): void; - _maybeEnableCycle(): void; - to(index: any): void; - _addEventListeners(): void; - _addTouchEventListeners(): void; - _keydown(event: any): void; - _getItemIndex(element: any): number; - _setActiveIndicatorElement(index: any): void; - _updateInterval(): void; - _slide(order: any, element?: any): void; - _isAnimated(): any; - _getActive(): any; - _getItems(): any[]; - _clearInterval(): void; - _directionToOrder(direction: any): "next" | "prev"; - _orderToDirection(order: any): "right" | "left"; -} -/** - * Class definition - */ -export class Collapse extends BaseComponent { - static get Default(): { - parent: any; - toggle: boolean; - }; - static get DefaultType(): { - parent: string; - toggle: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _isTransitioning: boolean; - _triggerArray: any[]; - toggle(): void; - show(): void; - hide(): void; - _isShown(element?: any): any; - _getDimension(): "width" | "height"; - _initializeChildren(): void; - _getFirstLevelChildren(selector: any): any[]; - _addAriaAndCollapsedClass(triggerArray: any, isOpen: any): void; -} -/** - * Class definition - */ -export class Dropdown extends BaseComponent { - static get Default(): { - autoClose: boolean; - boundary: string; - display: string; - offset: number[]; - popperConfig: any; - reference: string; - }; - static get DefaultType(): { - autoClose: string; - boundary: string; - display: string; - offset: string; - popperConfig: string; - reference: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - static clearMenus(event: any): void; - static dataApiKeydownHandler(event: any): void; - _popper: Popper.Instance; - _parent: any; - _menu: any; - _inNavbar: boolean; - toggle(): void; - show(): void; - hide(): void; - update(): void; - _completeHide(relatedTarget: any): void; - _createPopper(): void; - _isShown(): any; - _getPlacement(): "top" | "bottom" | "top-end" | "top-start" | "bottom-end" | "bottom-start" | "left-start" | "right-start"; - _detectNavbar(): boolean; - _getOffset(): any; - _getPopperConfig(): any; - _selectMenuItem({ key, target }: { - key: any; - target: any; - }): void; -} -/** - * Class definition - */ -export class Modal extends BaseComponent { - static get Default(): { - backdrop: boolean; - focus: boolean; - keyboard: boolean; - }; - static get DefaultType(): { - backdrop: string; - focus: string; - keyboard: string; - }; - static get NAME(): string; - static jQueryInterface(config: any, relatedTarget: any): any; - _dialog: any; - _backdrop: Backdrop; - _focustrap: FocusTrap; - _isShown: boolean; - _isTransitioning: boolean; - _scrollBar: ScrollBarHelper; - toggle(relatedTarget: any): void; - show(relatedTarget: any): void; - hide(): void; - handleUpdate(): void; - _initializeBackDrop(): Backdrop; - _initializeFocusTrap(): FocusTrap; - _showElement(relatedTarget: any): void; - _addEventListeners(): void; - _hideModal(): void; - _isAnimated(): any; - _triggerBackdropTransition(): void; - /** - * The following methods are used to handle overflowing modals - */ - _adjustDialog(): void; - _resetAdjustments(): void; -} -/** - * Class definition - */ -export class Offcanvas extends BaseComponent { - static get Default(): { - backdrop: boolean; - keyboard: boolean; - scroll: boolean; - }; - static get DefaultType(): { - backdrop: string; - keyboard: string; - scroll: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _isShown: boolean; - _backdrop: Backdrop; - _focustrap: FocusTrap; - toggle(relatedTarget: any): void; - show(relatedTarget: any): void; - hide(): void; - _initializeBackDrop(): Backdrop; - _initializeFocusTrap(): FocusTrap; - _addEventListeners(): void; -} -/** - * Class definition - */ -export class Popover extends Tooltip { - static get Default(): { - content: string; - offset: number[]; - placement: string; - template: string; - trigger: string; - allowList: { - '*': (string | RegExp)[]; - a: string[]; - area: any[]; - b: any[]; - br: any[]; - col: any[]; - code: any[]; - div: any[]; - em: any[]; - hr: any[]; - h1: any[]; - h2: any[]; - h3: any[]; - h4: any[]; - h5: any[]; - h6: any[]; - i: any[]; - img: string[]; - li: any[]; - ol: any[]; - p: any[]; - pre: any[]; - s: any[]; - small: any[]; - span: any[]; - sub: any[]; - sup: any[]; - strong: any[]; - u: any[]; - ul: any[]; - }; - animation: boolean; - boundary: string; - container: boolean; - customClass: string; - delay: number; - fallbackPlacements: string[]; - html: boolean; - popperConfig: any; - sanitize: boolean; - sanitizeFn: any; - selector: boolean; - title: string; - }; - static get DefaultType(): { - content: string; - allowList: string; - animation: string; - boundary: string; - container: string; - customClass: string; - delay: string; - fallbackPlacements: string; - html: string; - offset: string; - placement: string; - popperConfig: string; - sanitize: string; - sanitizeFn: string; - selector: string; - template: string; - title: string; - trigger: string; - }; - _isWithContent(): any; - _getContentForTemplate(): { - ".popover-header": any; - ".popover-body": any; - }; - _getContent(): any; -} -/** - * Class definition - */ -export class ScrollSpy extends BaseComponent { - static get Default(): { - offset: any; - rootMargin: string; - smoothScroll: boolean; - target: any; - threshold: number[]; - }; - static get DefaultType(): { - offset: string; - rootMargin: string; - smoothScroll: string; - target: string; - threshold: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _targetLinks: Map; - _observableSections: Map; - _rootElement: any; - _activeTarget: any; - _observer: IntersectionObserver; - _previousScrollData: { - visibleEntryTop: number; - parentScrollTop: number; - }; - refresh(): void; - _maybeEnableSmoothScroll(): void; - _getNewObserver(): IntersectionObserver; - _observerCallback(entries: any): void; - _initializeTargetsAndObservables(): void; - _process(target: any): void; - _activateParents(target: any): void; - _clearActiveClass(parent: any): void; -} -/** - * Class definition - */ -export class Tab extends BaseComponent { - static get NAME(): string; - static jQueryInterface(config: any): any; - constructor(element: any); - _parent: any; - show(): void; - _activate(element: any, relatedElem: any): void; - _deactivate(element: any, relatedElem: any): void; - _keydown(event: any): void; - _getChildren(): any[]; - _getActiveElem(): any; - _setInitialAttributes(parent: any, children: any): void; - _setInitialAttributesOnChild(child: any): void; - _setInitialAttributesOnTargetPanel(child: any): void; - _toggleDropDown(element: any, open: any): void; - _setAttributeIfNotExists(element: any, attribute: any, value: any): void; - _elemIsActive(elem: any): any; - _getInnerElement(elem: any): any; - _getOuterElement(elem: any): any; -} -/** - * Class definition - */ -export class Toast extends BaseComponent { - static get Default(): { - animation: boolean; - autohide: boolean; - delay: number; - }; - static get DefaultType(): { - animation: string; - autohide: string; - delay: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _timeout: NodeJS.Timeout; - _hasMouseInteraction: boolean; - _hasKeyboardInteraction: boolean; - show(): void; - hide(): void; - isShown(): any; - _maybeScheduleHide(): void; - _onInteraction(event: any, isInteracting: any): void; - _setListeners(): void; - _clearTimeout(): void; -} -/** - * Class definition - */ -export class Tooltip extends BaseComponent { - static get Default(): { - allowList: { - '*': (string | RegExp)[]; - a: string[]; - area: any[]; - b: any[]; - br: any[]; - col: any[]; - code: any[]; - div: any[]; - em: any[]; - hr: any[]; - h1: any[]; - h2: any[]; - h3: any[]; - h4: any[]; - h5: any[]; - h6: any[]; - i: any[]; - img: string[]; - li: any[]; - ol: any[]; - p: any[]; - pre: any[]; - s: any[]; - small: any[]; - span: any[]; - sub: any[]; - sup: any[]; - strong: any[]; - u: any[]; - ul: any[]; - }; - animation: boolean; - boundary: string; - container: boolean; - customClass: string; - delay: number; - fallbackPlacements: string[]; - html: boolean; - offset: number[]; - placement: string; - popperConfig: any; - sanitize: boolean; - sanitizeFn: any; - selector: boolean; - template: string; - title: string; - trigger: string; - }; - static get DefaultType(): { - allowList: string; - animation: string; - boundary: string; - container: string; - customClass: string; - delay: string; - fallbackPlacements: string; - html: string; - offset: string; - placement: string; - popperConfig: string; - sanitize: string; - sanitizeFn: string; - selector: string; - template: string; - title: string; - trigger: string; - }; - static get NAME(): string; - static jQueryInterface(config: any): any; - _isEnabled: boolean; - _timeout: number; - _isHovered: boolean; - _activeTrigger: {}; - _popper: Popper.Instance; - _templateFactory: TemplateFactory; - _newContent: any; - tip: Element; - enable(): void; - disable(): void; - toggleEnabled(): void; - toggle(): void; - show(): void; - hide(): void; - update(): void; - _isWithContent(): boolean; - _getTipElement(): Element; - _createTipElement(content: any): Element; - setContent(content: any): void; - _getTemplateFactory(content: any): TemplateFactory; - _getContentForTemplate(): { - ".tooltip-inner": any; - }; - _getTitle(): any; - _initializeOnDelegatedTarget(event: any): any; - _isAnimated(): any; - _isShown(): boolean; - _createPopper(tip: any): Popper.Instance; - _getOffset(): any; - _resolvePossibleFunction(arg: any): any; - _getPopperConfig(attachment: any): any; - _setListeners(): void; - _hideModalHandler: () => void; - _fixTitle(): void; - _enter(): void; - _leave(): void; - _setTimeout(handler: any, timeout: any): void; - _isWithActiveTrigger(): boolean; - _getDelegateConfig(): { - selector: boolean; - trigger: string; - }; - _disposePopper(): void; -} -/** - * Class definition - */ -declare class BaseComponent extends Config { - static getInstance(element: any): any; - static getOrCreateInstance(element: any, config?: {}): any; - static get VERSION(): string; - static get DATA_KEY(): string; - static get EVENT_KEY(): string; - static eventName(name: any): string; - constructor(element: any, config: any); - _element: any; - _config: any; - dispose(): void; - _queueCallback(callback: any, element: any, isAnimated?: boolean): void; -} -/** - * Class definition - */ -declare class Swipe extends Config { - static get Default(): { - endCallback: any; - leftCallback: any; - rightCallback: any; - }; - static get DefaultType(): { - endCallback: string; - leftCallback: string; - rightCallback: string; - }; - static get NAME(): string; - static isSupported(): boolean; - constructor(element: any, config: any); - _element: any; - _config: any; - _deltaX: number; - _supportPointerEvents: boolean; - dispose(): void; - _start(event: any): void; - _end(event: any): void; - _move(event: any): void; - _handleSwipe(): void; - _initEvents(): void; - _eventIsPointerPenTouch(event: any): boolean; -} -import * as Popper from "@popperjs/core"; -/** - * Class definition - */ -declare class Backdrop extends Config { - static get Default(): { - className: string; - clickCallback: any; - isAnimated: boolean; - isVisible: boolean; - rootElement: string; - }; - static get DefaultType(): { - className: string; - clickCallback: string; - isAnimated: string; - isVisible: string; - rootElement: string; - }; - static get NAME(): string; - constructor(config: any); - _config: any; - _isAppended: boolean; - _element: HTMLDivElement; - show(callback: any): void; - hide(callback: any): void; - dispose(): void; - _getElement(): HTMLDivElement; - _append(): void; - _emulateAnimation(callback: any): void; -} -/** - * Class definition - */ -declare class FocusTrap extends Config { - static get Default(): { - autofocus: boolean; - trapElement: any; - }; - static get DefaultType(): { - autofocus: string; - trapElement: string; - }; - static get NAME(): string; - constructor(config: any); - _config: any; - _isActive: boolean; - _lastTabNavDirection: string; - activate(): void; - deactivate(): void; - _handleFocusin(event: any): void; - _handleKeydown(event: any): void; -} -/** - * Class definition - */ -declare class ScrollBarHelper { - _element: HTMLElement; - getWidth(): number; - hide(): void; - reset(): void; - isOverflowing(): boolean; - _disableOverFlow(): void; - _setElementAttributes(selector: any, styleProperty: any, callback: any): void; - _saveInitialAttribute(element: any, styleProperty: any): void; - _resetElementAttributes(selector: any, styleProperty: any): void; - _applyManipulationCallback(selector: any, callBack: any): void; -} -/** - * Class definition - */ -declare class TemplateFactory extends Config { - static get Default(): { - allowList: { - '*': (string | RegExp)[]; - a: string[]; - area: any[]; - b: any[]; - br: any[]; - col: any[]; - code: any[]; - div: any[]; - em: any[]; - hr: any[]; - h1: any[]; - h2: any[]; - h3: any[]; - h4: any[]; - h5: any[]; - h6: any[]; - i: any[]; - img: string[]; - li: any[]; - ol: any[]; - p: any[]; - pre: any[]; - s: any[]; - small: any[]; - span: any[]; - sub: any[]; - sup: any[]; - strong: any[]; - u: any[]; - ul: any[]; - }; - content: {}; - extraClass: string; - html: boolean; - sanitize: boolean; - sanitizeFn: any; - template: string; - }; - static get DefaultType(): { - allowList: string; - content: string; - extraClass: string; - html: string; - sanitize: string; - sanitizeFn: string; - template: string; - }; - static get NAME(): string; - constructor(config: any); - _config: any; - getContent(): any[]; - hasContent(): boolean; - changeContent(content: any): TemplateFactory; - toHtml(): Element; - _typeCheckConfig(config: any): void; - _checkContent(arg: any): void; - _setContent(template: any, content: any, selector: any): void; - _maybeSanitize(arg: any): any; - _resolvePossibleFunction(arg: any): any; - _putElementInTemplate(element: any, templateElement: any): void; -} -/** - * -------------------------------------------------------------------------- - * Bootstrap util/config.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ -/** - * Class definition - */ -declare class Config { - static get Default(): {}; - static get DefaultType(): {}; - static get NAME(): void; - _getConfig(config: any): any; - _configAfterMerge(config: any): any; - _mergeConfigObj(config: any, element: any): any; - _typeCheckConfig(config: any, configTypes?: any): void; -} -export {}; diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/prismjs/prism.d.ts b/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/prismjs/prism.d.ts deleted file mode 100644 index acce194c..00000000 --- a/components/wifi-manager/webapp/dist/src/bootswatch/docs/_vendor/prismjs/prism.d.ts +++ /dev/null @@ -1,93 +0,0 @@ -/// -export namespace languages { - export namespace markup { - namespace tag { } - } - import html = markup; - export { html }; - import mathml = markup; - export { mathml }; - import svg = markup; - export { svg }; - export const xml: { - [x: string]: RegExp | GrammarToken | (RegExp | GrammarToken)[]; - }; - import ssml = xml; - export { ssml }; - import atom = xml; - export { atom }; - import rss = xml; - export { rss }; - export const clike: { - comment: { - pattern: RegExp; - lookbehind: boolean; - greedy: boolean; - }[]; - string: { - pattern: RegExp; - greedy: boolean; - }; - 'class-name': { - pattern: RegExp; - lookbehind: boolean; - inside: { - punctuation: RegExp; - }; - }; - keyword: RegExp; - boolean: RegExp; - function: RegExp; - number: RegExp; - operator: RegExp; - punctuation: RegExp; - }; - export const javascript: { - [x: string]: RegExp | GrammarToken | (RegExp | GrammarToken)[]; - }; - import js = javascript; - export { js }; -} -/** - * The expansion of a simple `RegExp` literal to support additional properties. - */ -export type GrammarToken = { - /** - * The regular expression of the token. - */ - pattern: RegExp; - /** - * If `true`, then the first capturing group of `pattern` will (effectively) - * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token. - */ - lookbehind?: boolean; - /** - * Whether the token is greedy. - */ - greedy?: boolean; - /** - * An optional alias or list of aliases. - */ - alias?: string | string[]; - /** - * The nested grammar of this token. - * - * The `inside` grammar will be used to tokenize the text value of each token of this kind. - * - * This can be used to make nested and even recursive language definitions. - * - * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into - * each another. - */ - inside?: Grammar; -}; -export type Grammar = { - [x: string]: RegExp | GrammarToken | Array; -}; -/** - * A function which will invoked after an element was successfully highlighted. - */ -export type HighlightCallback = (element: Element) => void; -export type HookCallback = (env: { - [x: string]: any; -}) => void; diff --git a/components/wifi-manager/webapp/dist/src/index.d.ts b/components/wifi-manager/webapp/dist/src/index.d.ts index 33b60c1a..ef581c15 100644 --- a/components/wifi-manager/webapp/dist/src/index.d.ts +++ b/components/wifi-manager/webapp/dist/src/index.d.ts @@ -1,4 +1,4 @@ import 'bootstrap'; import './sass/main.scss'; import './assets/images/favicon-32x32.png'; -import './js/custom.js'; +import './js/custom.ts'; diff --git a/components/wifi-manager/webapp/dist/src/js/custom.d.ts b/components/wifi-manager/webapp/dist/src/js/custom.d.ts index cb0ff5c3..89259a98 100644 --- a/components/wifi-manager/webapp/dist/src/js/custom.d.ts +++ b/components/wifi-manager/webapp/dist/src/js/custom.d.ts @@ -1 +1,17 @@ +declare global { + interface Window { + hideSurrounding: (obj: HTMLElement) => void; + hFlash: () => void; + handleReboot: (link: string) => void; + setURL: (button: HTMLButtonElement) => void; + runCommand: (button: HTMLButtonElement, reboot: boolean) => void; + } + interface String { + format(...args: any[]): string; + encodeHTML(): string; + } + interface Date { + toLocalShort(): string; + } +} export {}; diff --git a/components/wifi-manager/webapp/dist/postcss.config.d.ts b/components/wifi-manager/webapp/dist/src/js/proto/configuration_pb.d.ts similarity index 100% rename from components/wifi-manager/webapp/dist/postcss.config.d.ts rename to components/wifi-manager/webapp/dist/src/js/proto/configuration_pb.d.ts diff --git a/components/wifi-manager/webapp/dist/test.d.ts b/components/wifi-manager/webapp/dist/src/js/proto/nanopb_pb.d.ts similarity index 100% rename from components/wifi-manager/webapp/dist/test.d.ts rename to components/wifi-manager/webapp/dist/src/js/proto/nanopb_pb.d.ts diff --git a/components/wifi-manager/webapp/dist/test/test.d.ts b/components/wifi-manager/webapp/dist/src/js/proto/status_pb.d.ts similarity index 100% rename from components/wifi-manager/webapp/dist/test/test.d.ts rename to components/wifi-manager/webapp/dist/src/js/proto/status_pb.d.ts diff --git a/components/wifi-manager/webapp/dist/src/js/test.d.ts b/components/wifi-manager/webapp/dist/src/js/test.d.ts index 60456425..64567b1e 100644 --- a/components/wifi-manager/webapp/dist/src/js/test.d.ts +++ b/components/wifi-manager/webapp/dist/src/js/test.d.ts @@ -1,204 +1,6 @@ declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getStatus(): {}; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; -declare function getRadioButton(entry: any): string; declare function getRadioButton(entry: any): string; declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; -declare function pushStatus(): void; declare let sd: {}; declare let rf: boolean; declare function refreshStatus(): void; diff --git a/components/wifi-manager/webapp/dist/webpack.config.d.ts b/components/wifi-manager/webapp/dist/webpack.config.d.ts deleted file mode 100644 index 4d5b5a04..00000000 --- a/components/wifi-manager/webapp/dist/webpack.config.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare function _exports(env: any, options: any): {}; -export = _exports; diff --git a/components/wifi-manager/webapp/dist/webpack/cmdline.d.ts b/components/wifi-manager/webapp/dist/webpack/cmdline.d.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/components/wifi-manager/webapp/dist/webpack/postcss.config.d.ts b/components/wifi-manager/webapp/dist/webpack/postcss.config.d.ts deleted file mode 100644 index 862bb978..00000000 --- a/components/wifi-manager/webapp/dist/webpack/postcss.config.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const parser: string; -export const plugins: { - 'postcss-import': {}; - 'postcss-cssnext': {}; - cssnano: {}; -}; diff --git a/components/wifi-manager/webapp/dist/webpack/webpack.dev.d.ts b/components/wifi-manager/webapp/dist/webpack/webpack.dev.d.ts deleted file mode 100644 index 51c54f97..00000000 --- a/components/wifi-manager/webapp/dist/webpack/webpack.dev.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -declare const PORT: 9100; -import HtmlWebPackPlugin = require("html-webpack-plugin"); -export namespace entry { - const test: string; -} -export namespace devServer { - export namespace _static { - const directory: string; - const staticOptions: {}; - const publicPath: string; - const serveIndex: boolean; - const watch: boolean; - } - export { _static as static }; - export namespace devMiddleware { - const publicPath_1: string; - export { publicPath_1 as publicPath }; - } - export const open: boolean; - export const compress: boolean; - export { PORT as port }; - export const host: string; - export const allowedHosts: string; - export const headers: { - 'Access-Control-Allow-Origin': string; - 'Accept-Encoding': string; - }; - export namespace client { - const logging: string; - const overlay: boolean; - const progress: boolean; - } - export function onListening(devServer: any): void; - export function onBeforeSetupMiddleware(devServer: any): void; -} -export const plugins: HtmlWebPackPlugin[]; -export {}; diff --git a/components/wifi-manager/webapp/jsconfig.json b/components/wifi-manager/webapp/jsconfig.json new file mode 100644 index 00000000..241087c9 --- /dev/null +++ b/components/wifi-manager/webapp/jsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6" + }, + "include": ["src/**/*"] + } \ No newline at end of file diff --git a/components/wifi-manager/webapp/package.json b/components/wifi-manager/webapp/package.json index 1d5ac53e..cf40a739 100644 --- a/components/wifi-manager/webapp/package.json +++ b/components/wifi-manager/webapp/package.json @@ -10,7 +10,8 @@ "build": "webpack --mode=production ", "stats": "webpack --env ANALYZE_SIZE=1 --mode=production ", "watch": "webpack --progress --watch --mode=development ", - "dev": "webpack serve --open --mode=development" + "dev": "webpack serve --open --mode=development", + "build:proto": "tsc ./webpack/GrpcToolsNodeProtocPlugin.ts" }, "devDependencies": { "@babel/core": "^7.16.12", @@ -18,11 +19,14 @@ "@babel/preset-env": "^7.16.11", "@babel/preset-typescript": "^7.16.7", "@squoosh/lib": "^0.4.0", + "@types/bootstrap": "^5.2.8", + "@types/he": "^1.2.2", + "@types/jquery": "^3.5.25", + "@types/js-cookie": "^3.0.5", "autoprefixer": "^10.4.2", "babel": "^6.23.0", "babel-loader": "^8.2.3", "babel-runtime": "^6.26.0", - "bootswatch": "file:src/bootswatch", "clean-webpack-plugin": "^4.0.0", "commander": "^8.3.0", "compression-webpack-plugin": "^9.2.0", @@ -35,6 +39,7 @@ "glob": "^7.2.0", "glob-all": "^3.2.1", "google-fonts-webpack-plugin": "^0.4.4", + "grpc-tools": "^1.12.4", "html-loader": "^3.1.0", "html-minimizer-webpack-plugin": "^3.5.0", "html-webpack-plugin": "^5.5.0", @@ -46,7 +51,7 @@ "imagemin-optipng": "^8.0.0", "imagemin-pngquant": "^9.0.2", "imagemin-svgo": "^10.0.1", - "js-cookie": "^3.0.1", + "js-cookie": "^3.0.5", "lodash": "^4.17.21", "lodash-es": "^4.17.21", "lodash-webpack-plugin": "^0.11.6", @@ -55,6 +60,7 @@ "open": "^9.1.0", "postcss": "^8.4.5", "postcss-loader": "^6.2.1", + "protobufjs-loader": "^2.0.2", "purgecss-webpack-plugin": "^4.1.3", "purgecss-whitelister": "^2.4.0", "purify-css": "^1.2.5", @@ -73,11 +79,16 @@ }, "dependencies": { "@babel/runtime": "^7.16.7", + "@grpc/grpc-js": "^1.9.9", + "@grpc/proto-loader": "^0.7.10", "async-mutex": "^0.3.2", "bootstrap": "^5.1.3", + "google-protobuf": "^3.21.2", + "he": "^1.2.0", "jquery": "^3.6.0", "npm": "^10.1.0", "popper.js": "^1.16.1", + "protobufjs": "^7.2.5", "webpack-visualizer-plugin": "^0.1.11", "webpack-visualizer-plugin2": "^1.0.0" }, diff --git a/components/wifi-manager/webapp/src/bootswatch b/components/wifi-manager/webapp/src/bootswatch deleted file mode 160000 index 3038872b..00000000 --- a/components/wifi-manager/webapp/src/bootswatch +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3038872b8389763b64857bac00e102a71251a331 diff --git a/components/wifi-manager/webapp/src/index.ts b/components/wifi-manager/webapp/src/index.ts index 80f32385..c8900095 100644 --- a/components/wifi-manager/webapp/src/index.ts +++ b/components/wifi-manager/webapp/src/index.ts @@ -2,5 +2,5 @@ import 'bootstrap'; import './sass/main.scss'; import './assets/images/favicon-32x32.png'; -import './js/custom.js'; +import './js/custom.ts'; diff --git a/components/wifi-manager/webapp/src/js/custom.js b/components/wifi-manager/webapp/src/js/custom.ts similarity index 70% rename from components/wifi-manager/webapp/src/js/custom.js rename to components/wifi-manager/webapp/src/js/custom.ts index ddb6721b..6a5bdbeb 100644 --- a/components/wifi-manager/webapp/src/js/custom.js +++ b/components/wifi-manager/webapp/src/js/custom.ts @@ -1,37 +1,217 @@ var he = require('he'); -var Promise = require('es6-promise').Promise; -window.bootstrap = require('bootstrap'); +// var Promise = require('es6-promise').Promise; + +// @ts-ignore import Cookies from 'js-cookie'; +var protobuf = require("protobufjs"); +import * as bootstrap from 'bootstrap'; -if (!String.prototype.format) { - Object.assign(String.prototype, { - format() { - const args = arguments; - return this.replace(/{(\d+)}/g, function (match, number) { - return typeof args[number] !== 'undefined' ? args[number] : match; - }); - }, - }); + + +declare global { + interface Window { + hideSurrounding: (obj: HTMLElement) => void; + hFlash: () => void; + handleReboot: (link: string) => void; + setURL: (button: HTMLButtonElement) => void; + runCommand: (button: HTMLButtonElement, reboot: boolean) => void; + } + interface String { + format(...args: any[]): string; + encodeHTML(): string; + } + interface Date { + toLocalShort(): string; + } } -if (!String.prototype.encodeHTML) { - Object.assign(String.prototype, { - encodeHTML() { - return he.encode(this).replace(/\n/g, '
'); - }, - }); +interface Field { + value: string; + attributes: { + cmdname: { + value: string; + }; + }; } -Object.assign(Date.prototype, { - toLocalShort() { - const opt = { dateStyle: 'short', timeStyle: 'short' }; - return this.toLocaleString(undefined, opt); +type GPIOEntry = { + fixed: any; + group: string; + name: string; + gpio: string; +}; +type BTDevice = { + name: string; + rssi: number; +}; +interface ArgTableEntry { + glossary: string; + longopts: string; + checkbox: boolean; + remark: boolean; + hasvalue: boolean; + mincount: number; + maxcount: number; + datatype?: string; + shortopts?: string; +} +type MessageEntry = { + type: string; + message: string; + class: string; + sent_time:number; + current_time:number; +}; +interface CommandEntry { + help: string; + hascb: boolean; + name: string; + argtable?: ArgTableEntry[]; + hint?: string; +} +type ReleaseEntry = { + assets: { + browser_download_url: string; + name: string + }[]; + body: any; + created_at: string | number | Date; + name: string; +}; +type OutputType = 'i2s' | 'spdif' | 'bt'; +interface TaskDetails { + nme: string; cpu: number; st: number; minstk: number; bprio: number; cprio: number; num: number; +} +interface ConfigValue { + value: string | number; + type: number; +} + +interface ConfigPayload { + timestamp: number; + config: { [key: string]: ConfigValue }; +} +interface NetworkConnection { + urc: number; + auth: number ; + pwd: string ; + dhcpname: string ; + Action: number ; + ip: string ; + ssid: string ; + rssi: number ; + gw: string ; + netmask: string ; +} +interface StatusObject { + project_name?: string; + version?: string; + recovery?: number; + Jack?: string; + Voltage?: number; + disconnect_count?: number; + avg_conn_time?: number; + is_i2c_locked?: boolean; + urc?: number; + bt_status?: number; + bt_sub_status?: number; + rssi?: number; + ssid?: string; + ip?: string; + netmask?: string; + gw?: string; + lms_cport?: number; + lms_port?: number; + lms_ip?: string; + if?: string; + platform_name?: string; + depth?: number; + loaded?: number; + total?: number; + ota_pct?: number; + ota_dsc?: string; +} +// Function to reset a StatusObject +function resetStatusObject(): StatusObject { + return { + netmask: undefined, + ip: undefined, + ssid: undefined, + urc: undefined, + rssi: undefined, + gw: undefined, + bt_status: undefined, + bt_sub_status: undefined, + loaded: undefined, + total: undefined, + ota_pct: undefined, + ota_dsc: undefined, + recovery: undefined + }; +} +function resetNetworkConnection(): NetworkConnection { + return { + auth: undefined, + pwd: undefined, + dhcpname: undefined, + Action: undefined, + ip: undefined, + ssid: undefined, + rssi: undefined, + gw: undefined, + netmask: undefined, + urc: 0 + }; +} + +window.hideSurrounding = function (obj: HTMLElement): void { + $(obj).parent().parent().hide(); +} +function hFlash() { + // reset file upload selection if any; + $('#flashfilename').val = null + flashState.StartOTA(); +} +window.hFlash = function () { + hFlash() +} +function handleReboot(link: string) { + if (link == 'reboot_ota') { + $('#reboot_ota_nav').removeClass('active').prop("disabled", true); delayReboot(500, '', 'reboot_ota'); + } + else { + $('#reboot_nav').removeClass('active'); delayReboot(500, '', link); + } +} +window.handleReboot = function (link) { + handleReboot(link); +} + +Object.assign(String.prototype, { + format(...args: any[]): string { + return this.replace(/{(\d+)}/g, function (match: string, number: string) { + const index = parseInt(number, 10); // Convert string to number + return typeof args[index] !== 'undefined' ? args[index] : match; + }); }, }); -function get_control_option_value(obj) { - let ctrl,id,val,opt; - let radio = false; - let checked = false; + +Object.assign(String.prototype, { + encodeHTML() { + return he.encode(this).replace(/\n/g, '
'); + }, +}); + +Object.assign(Date.prototype, { + toLocalShort() { + const opt: Intl.DateTimeFormatOptions = { dateStyle: 'short', timeStyle: 'short' }; + return this.toLocaleString(undefined, opt); + + }, +}); + +function get_control_option_value(obj: (string | JQuery | HTMLElement | HTMLInputElement)): { opt: string, val: string | boolean | number } { + let ctrl, id, val, opt; if (typeof (obj) === 'string') { id = obj; ctrl = $(`#${id}`); @@ -39,28 +219,35 @@ function get_control_option_value(obj) { id = $(obj).attr('id'); ctrl = $(obj); } - if(ctrl.attr('type') === 'checkbox'){ - opt = $(obj).checked?id.replace('cmd_opt_', ''):''; + if (ctrl.attr('type') === 'checkbox') { + opt = ctrl.prop('checked') ? id.replace('cmd_opt_', '') : ''; val = true; } else { opt = id.replace('cmd_opt_', ''); - val = $(obj).val(); - val = `${val.includes(" ") ? '"' : ''}${val}${val.includes(" ") ? '"' : ''}`; + val = ctrl.val(); + if (typeof val === 'string') { + val = `${val.includes(" ") ? '"' : ''}${val}${val.includes(" ") ? '"' : ''}`; + } + else if (typeof val !== 'number') { + val = val.toString(); + } } return { opt, val }; } function handleNVSVisible() { - let nvs_previous_checked = isEnabled(Cookies.get("show-nvs")); - $('input#show-nvs')[0].checked = nvs_previous_checked; - if ($('input#show-nvs')[0].checked || recovery) { + let nvs_previous_checked: boolean = isEnabled(Cookies.get("show-nvs")); + const checkBoxElement = $('input#show-nvs')[0] as HTMLInputElement; + checkBoxElement.checked = nvs_previous_checked; + + if (checkBoxElement.checked || recovery) { $('*[href*="-nvs"]').show(); } else { $('*[href*="-nvs"]').hide(); } } -function concatenateOptions(options) { +function concatenateOptions(options: object): string { let commandLine = ' '; for (const [option, value] of Object.entries(options)) { if (option !== 'n' && option !== 'o') { @@ -73,52 +260,69 @@ function concatenateOptions(options) { return commandLine; } -function isEnabled(val) { - return val != undefined && typeof val === 'string' && val.match("[Yy1]"); +function isEnabled(val:string) { + const matchResult = val && typeof val === 'string' && val.match("[Yy1]"); + return matchResult && matchResult !== null && matchResult.length > 0; } -const nvsTypes = { - NVS_TYPE_U8: 0x01, - /*! < Type uint8_t */ - NVS_TYPE_I8: 0x11, - /*! < Type int8_t */ - NVS_TYPE_U16: 0x02, - /*! < Type uint16_t */ - NVS_TYPE_I16: 0x12, - /*! < Type int16_t */ - NVS_TYPE_U32: 0x04, - /*! < Type uint32_t */ - NVS_TYPE_I32: 0x14, - /*! < Type int32_t */ - NVS_TYPE_U64: 0x08, - /*! < Type uint64_t */ - NVS_TYPE_I64: 0x18, - /*! < Type int64_t */ - NVS_TYPE_STR: 0x21, - /*! < Type string */ - NVS_TYPE_BLOB: 0x42, - /*! < Type blob */ - NVS_TYPE_ANY: 0xff /*! < Must be last */, +enum NVSType { + NVS_TYPE_U8 = 0x01, + NVS_TYPE_I8 = 0x11, + NVS_TYPE_U16 = 0x02, + NVS_TYPE_I16 = 0x12, + NVS_TYPE_U32 = 0x04, + NVS_TYPE_I32 = 0x14, + NVS_TYPE_U64 = 0x08, + NVS_TYPE_I64 = 0x18, + NVS_TYPE_STR = 0x21, + NVS_TYPE_BLOB = 0x42, + NVS_TYPE_ANY = 0xff }; -const btIcons = { - bt_playing: { 'label': '', 'icon': 'media_bluetooth_on' }, - bt_disconnected: { 'label': '', 'icon': 'media_bluetooth_off' }, - bt_neutral: { 'label': '', 'icon': 'bluetooth' }, - bt_connecting: { 'label': '', 'icon': 'bluetooth_searching' }, - bt_connected: { 'label': '', 'icon': 'bluetooth_connected' }, - bt_disabled: { 'label': '', 'icon': 'bluetooth_disabled' }, - play_arrow: { 'label': '', 'icon': 'play_circle_filled' }, - pause: { 'label': '', 'icon': 'pause_circle' }, - stop: { 'label': '', 'icon': 'stop_circle' }, - '': { 'label': '', 'icon': '' } + +interface ConfigEntry { + value: number | string; + type?: NVSType; +} + +interface Config { + [key: string]: ConfigEntry | string; +} +interface BtIcon { + label: string; + icon: string; +} + +interface BatIcon { + icon: string; + label: string; + ranges: Array<{ f: number; t: number }>; +} + +interface BtStateIcon { + desc: string; + sub: string[]; +} +const btIcons: { [key: string]: BtIcon } = { + bt_playing: { label: '', icon: 'media_bluetooth_on' }, + bt_disconnected: { label: '', icon: 'media_bluetooth_off' }, + bt_neutral: { label: '', icon: 'bluetooth' }, + bt_connecting: { label: '', icon: 'bluetooth_searching' }, + bt_connected: { label: '', icon: 'bluetooth_connected' }, + bt_disabled: { label: '', icon: 'bluetooth_disabled' }, + play_arrow: { label: '', icon: 'play_circle_filled' }, + pause: { label: '', icon: 'pause_circle' }, + stop: { label: '', icon: 'stop_circle' }, + '': { label: '', icon: '' } }; -const batIcons = [ + +const batIcons: BatIcon[] = [ { icon: "battery_0_bar", label: '▪', ranges: [{ f: 5.8, t: 6.8 }, { f: 8.8, t: 10.2 }] }, { icon: "battery_2_bar", label: '▪▪', ranges: [{ f: 6.8, t: 7.4 }, { f: 10.2, t: 11.1 }] }, { icon: "battery_3_bar", label: '▪▪▪', ranges: [{ f: 7.4, t: 7.5 }, { f: 11.1, t: 11.25 }] }, { icon: "battery_4_bar", label: '▪▪▪▪', ranges: [{ f: 7.5, t: 7.8 }, { f: 11.25, t: 11.7 }] } ]; -const btStateIcons = [ + +const btStateIcons: BtStateIcon[] = [ { desc: 'Idle', sub: ['bt_neutral'] }, { desc: 'Discovering', sub: ['bt_connecting'] }, { desc: 'Discovered', sub: ['bt_connecting'] }, @@ -131,11 +335,6 @@ const btStateIcons = [ { desc: 'Disconnecting', sub: ['bt_disconnected'] }, ]; -const pillcolors = { - MESSAGING_INFO: 'badge-success', - MESSAGING_WARNING: 'badge-warning', - MESSAGING_ERROR: 'badge-danger', -}; const connectReturnCode = { OK: 0, FAIL: 1, @@ -144,17 +343,17 @@ const connectReturnCode = { RESTORE: 4, ETH: 5 } -const taskStates = { - 0: 'eRunning', +const taskStates = [ + 'eRunning', /*! < A task is querying the state of itself, so must be running. */ - 1: 'eReady', + 'eReady', /*! < The task being queried is in a read or pending ready list. */ - 2: 'eBlocked', + 'eBlocked', /*! < The task being queried is in the Blocked state. */ - 3: 'eSuspended', + 'eSuspended', /*! < The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ - 4: 'eDeleted', -}; + 'eDeleted' +]; let flashState = { NONE: 0, REBOOT_TO_RECOVERY: 2, @@ -184,8 +383,9 @@ let flashState = { this.UpdateProgress(); $('#rTable tr.release').removeClass('table-success table-warning'); $('.flact').prop('disabled', false); - $('#flashfilename').value = null; - $('#fw-url-input').value = null; + ($('#flashfilename')[0] as HTMLInputElement).value = null; + ($('#fw-url-input')[0] as HTMLInputElement).value = null; + if (!this.isStateError()) { $('span#flash-status').html(''); $('#fwProgressLabel').parent().removeClass('bg-danger'); @@ -299,7 +499,8 @@ let flashState = { this.flashURL = ''; this.flashFileName = ''; this.flashURL = $('#fw-url-input').val(); - let fileInput = $('#flashfilename')[0].files; + let fileInputctrl = $('#flashfilename')[0] as HTMLInputElement; + let fileInput = fileInputctrl.files; if (fileInput.length > 0) { this.flashFileName = fileInput[0]; } @@ -309,7 +510,7 @@ let flashState = { return this; }, - setOTAError: function (message) { + setOTAError: function (message: string) { this.SetStateError().SetStatusPercent(0).SetStatusText(message).reset(); return this; }, @@ -322,7 +523,7 @@ let flashState = { return this; }, - SetStatusPercent: function (pct) { + SetStatusPercent: function (pct: number) { var pctChanged = (this.statusPercent != pct); this.statusPercent = pct; if (pctChanged) { @@ -342,7 +543,7 @@ let flashState = { } return this; }, - SetStatusText: function (txt) { + SetStatusText: function (txt: string) { var changed = (this.statusText != txt); this.statusText = txt; if (changed) { @@ -379,7 +580,6 @@ let flashState = { UploadLocalFile: function () { this.SetStateUploading(); const xhttp = new XMLHttpRequest(); - xhttp.context = this; var boundHandleUploadProgressEvent = this.HandleUploadProgressEvent.bind(this); var boundsetOTAError = this.setOTAError.bind(this); xhttp.upload.addEventListener("progress", boundHandleUploadProgressEvent, false); @@ -416,11 +616,12 @@ let flashState = { this.setOTAError('Invalid URL or file name while trying to start the OTa process') } }, - HandleUploadProgressEvent: function (data) { + + HandleUploadProgressEvent: function (data: StatusObject) { this.logEvent(this.HandleUploadProgressEvent.name); this.SetStateUploading().SetStatusPercent(Math.round(data.loaded / data.total * 100)).SetStatusText('Uploading file to device'); }, - EventTargetStatus: function (data) { + EventTargetStatus: function (data: StatusObject) { if (!this.isStateNone()) { this.logEvent(this.EventTargetStatus.name); } @@ -440,25 +641,23 @@ let flashState = { this.TargetReadyStartOTA(); } }, - EventOTAMessageClass: function (data) { + EventOTAMessageClass: function (data: string) { this.logEvent(this.EventOTAMessageClass.name); - var otaData = JSON.parse(data); + var otaData: StatusObject = JSON.parse(data); this.SetStatusPercent(otaData.ota_pct).SetStatusText(otaData.ota_dsc); }, - logEvent: function (fun) { + logEvent: function (fun: string) { console.log(`${fun}, flash state ${this.toString()}, recovery: ${this.recovery}, ota pct: ${this.statusPercent}, ota desc: ${this.statusText}`); } }; -window.hideSurrounding = function (obj) { - $(obj).parent().parent().hide(); -} + let presetsloaded = false; let is_i2c_locked = false; let statusInterval = 2000; let messageInterval = 2500; -function post_config(data) { +function post_config(data: object) { let confPayload = { timestamp: Date.now(), config: data @@ -474,28 +673,23 @@ function post_config(data) { }); } - -window.hFlash = function () { - // reset file upload selection if any; - $('#flashfilename').value = null - flashState.StartOTA(); -} -window.handleReboot = function (link) { - if (link == 'reboot_ota') { - $('#reboot_ota_nav').removeClass('active').prop("disabled", true); delayReboot(500, '', 'reboot_ota'); - } - else { - $('#reboot_nav').removeClass('active'); delayReboot(500, '', link); - } +type CommandValuesEntry = Record; +type CommandValues = Record; +interface ParsedCommand { + name: string; + output: string; + options: Record; + otherValues: string; + otherOptions: { btname: string | null; n: string | null }; } -function parseSqueezeliteCommandLine(commandLine) { - const options = {}; - let output, name; +function parseSqueezeliteCommandLine(commandLine: string): ParsedCommand { + const options: Record = {}; + let output: string, name: string; let otherValues = ''; const argRegex = /("[^"]+"|'[^']+'|\S+)/g; - const args = commandLine.match(argRegex); + const args = commandLine.match(argRegex) || []; let i = 0; @@ -510,7 +704,7 @@ function parseSqueezeliteCommandLine(commandLine) { break; } - let value = true; + let value = ""; if (i + 1 < args.length && !args[i + 1].startsWith('-')) { value = args[i + 1].replace(/"/g, '').replace(/'/g, ''); @@ -528,25 +722,28 @@ function parseSqueezeliteCommandLine(commandLine) { otherValues = otherValues.trim(); output = getOutput(options); name = getName(options); - let otherOptions={btname:null,n:null}; - // assign o and n options to otheroptions if present + + let otherOptions: { btname: string | null; n: string | null } = { btname: null, n: null }; + + // Assign 'o' and 'n' options to otherOptions if present if (options.o && output.toUpperCase() === 'BT') { let temp = parseSqueezeliteCommandLine(options.o); - if(temp.name) { + if (temp.name) { otherOptions.btname = temp.name; } delete options.o; } if (options.n) { - otherOptions['n'] = options.n; + otherOptions.n = options.n; delete options.n; } - return { name, output, options, otherValues,otherOptions }; + return { name, output, options, otherValues, otherOptions }; } -function getOutput(options) { + +function getOutput(options: Record) { let output; - if (options.o){ + if (options.o) { output = options.o.replace(/"/g, '').replace(/'/g, ''); /* set output as the first alphanumerical word in the command line */ if (output.indexOf(' ') > 0) { @@ -556,29 +753,30 @@ function getOutput(options) { return output; } -function getName(options) { +function getName(options: Record) { let name; /* if n option present, assign to name variable */ - if (options.n){ + if (options.n) { name = options.n.replace(/"/g, '').replace(/'/g, ''); } return name; } -function isConnected() { - return ConnectedTo.hasOwnProperty('ip') && ConnectedTo.ip != '0.0.0.0' && ConnectedTo.ip != ''; +function isConnected(): boolean { + return ConnectedTo != undefined && ConnectedTo.hasOwnProperty('ip') && ConnectedTo.ip != '0.0.0.0' && ConnectedTo.ip != ''; } -function getIcon(icons) { +function getIcon(icons: RssiIcon) { return isConnected() ? icons.icon : icons.label; } -function handlebtstate(data) { - let icon = ''; +function handlebtstate(data: StatusObject) { + let icon: BtIcon = { label: '', icon: '' }; let tt = ''; + if (data.bt_status !== undefined && data.bt_sub_status !== undefined) { - const iconindex = btStateIcons[data.bt_status].sub[data.bt_sub_status]; - if (iconindex) { - icon = btIcons[iconindex]; + const iconIndex = btStateIcons[data.bt_status]?.sub[data.bt_sub_status]; + if (iconIndex) { + icon = btIcons[iconIndex]; tt = btStateIcons[data.bt_status].desc; } else { icon = btIcons.bt_connected; @@ -587,38 +785,37 @@ function handlebtstate(data) { } $('#o_type').attr('title', tt); - $('#o_bt').html(isConnected() ? icon.label : icon.text); + $('#o_bt').html(isConnected() ? icon.label : icon.icon); // Note: Assuming `isConnected()` is defined elsewhere. } -function handleTemplateTypeRadio(outtype) { + +function handleTemplateTypeRadio(outtype: OutputType): void { $('#o_type').children('span').css({ display: 'none' }); let changed = false; - if (outtype === 'bt') { - changed = output !== 'bt' && output !== ''; - output = 'bt'; - } else if (outtype === 'spdif') { - changed = output !== 'spdif' && output !== ''; - output = 'spdif'; - } else { - changed = output !== 'i2s' && output !== ''; - output = 'i2s'; + + if (outtype !== output) { + changed = true; + output = outtype; } + $('#' + output).prop('checked', true); $('#o_' + output).css({ display: 'inline' }); + if (changed) { - Object.keys(commandDefaults[output]).forEach(function (key) { - $(`#cmd_opt_${key}`).val(commandDefaults[output][key]); + Object.entries(commandDefaults[output]).forEach(([key, value]) => { + $(`#cmd_opt_${key}`).val(value); }); } } -function handleExceptionResponse(xhr, _ajaxOptions, thrownError) { +function handleExceptionResponse(xhr: JQuery.jqXHR + , _ajaxOptions: JQuery.Ajax.ErrorTextStatus, thrownError: string) { console.log(xhr.status); console.log(thrownError); if (thrownError !== '') { showLocalMessage(thrownError, 'MESSAGING_ERROR'); } } -function HideCmdMessage(cmdname) { +function HideCmdMessage(cmdname: string) { $('#toast_' + cmdname) .removeClass('table-success') .removeClass('table-warning') @@ -627,7 +824,7 @@ function HideCmdMessage(cmdname) { .removeClass('show'); $('#msg_' + cmdname).html(''); } -function showCmdMessage(cmdname, msgtype, msgtext, append = false) { +function showCmdMessage(cmdname: string, msgtype: string, msgtext: string, append = false) { let color = 'table-success'; if (msgtype === 'MESSAGING_WARNING') { color = 'table-warning'; @@ -658,11 +855,20 @@ let recovery = false; let messagesHeld = false; let commandBTSinkName = ''; const commandHeader = 'squeezelite '; -const commandDefaults = { +interface CommandOptions { + b: string; + C: string; + W: string; + Z: string; + o: string; +} + +const commandDefaults: { [key: string]: CommandOptions } = { i2s: { b: "500:2000", C: "30", W: "", Z: "96000", o: "I2S" }, spdif: { b: "500:2000", C: "30", W: "", Z: "48000", o: "SPDIF" }, bt: { b: "500:2000", C: "30", W: "", Z: "44100", o: "BT" }, }; + let validOptions = { codecs: ['flac', 'pcm', 'mp3', 'ogg', 'aac', 'wma', 'alac', 'dsd', 'mad', 'mpg'] }; @@ -672,9 +878,9 @@ let apList = null; //let selectedSSID = ''; //let checkStatusInterval = null; let messagecount = 0; -let messageseverity = 'MESSAGING_INFO'; -let SystemConfig = {}; -let LastCommandsState = null; +let messageseverity:string = 'MESSAGING_INFO'; +let SystemConfig: any; +let LastCommandsState: number = NaN; var output = ''; let hostName = ''; let versionName = 'Squeezelite-ESP32'; @@ -685,67 +891,55 @@ let board_model = ''; let platform_name = versionName; let preset_name = ''; let btSinkNamesOptSel = '#cfg-audio-bt_source-sink_name'; -let ConnectedTo = {}; -let ConnectingToSSID = {}; -let lmsBaseUrl; +let ConnectedTo: NetworkConnection; +let ConnectingToSSID: NetworkConnection; +let lmsBaseUrl: string = ""; let prevLMSIP = ''; const ConnectingToActions = { 'CONN': 0, 'MAN': 1, 'STS': 2, } -Promise.prototype.delay = function (duration) { - return this.then( - function (value) { - return new Promise(function (resolve) { - setTimeout(function () { - resolve(value); - }, duration); - }); - }, - function (reason) { - return new Promise(function (_resolve, reject) { - setTimeout(function () { - reject(reason); - }, duration); - }); - } - ); -}; +function delay(promise: Promise, duration: number): Promise { + return new Promise((resolve, reject) => { + promise.then( + value => setTimeout(() => resolve(value), duration), + reason => setTimeout(() => reject(reason), duration) + ); + }); +} -function getConfigJson(slimMode) { - const config = {}; - $('input.nvs').each(function (_index, entry) { - if (!slimMode) { - const nvsType = parseInt(entry.attributes.nvs_type.value, 10); +function getConfigJson(slimMode: boolean): Config { + const config: Config = {}; + $('input.nvs').each(function (_index, element) { + const entry = element as HTMLInputElement; + const nvsTypeAttr = entry.attributes.getNamedItem('nvs_type'); + if (!slimMode && nvsTypeAttr) { + const nvsType = parseInt(nvsTypeAttr.value, 10) as NVSType; if (entry.id !== '') { - config[entry.id] = {}; - if ( - nvsType === nvsTypes.NVS_TYPE_U8 || - nvsType === nvsTypes.NVS_TYPE_I8 || - nvsType === nvsTypes.NVS_TYPE_U16 || - nvsType === nvsTypes.NVS_TYPE_I16 || - nvsType === nvsTypes.NVS_TYPE_U32 || - nvsType === nvsTypes.NVS_TYPE_I32 || - nvsType === nvsTypes.NVS_TYPE_U64 || - nvsType === nvsTypes.NVS_TYPE_I64 - ) { - config[entry.id].value = parseInt(entry.value); - } else { - config[entry.id].value = entry.value; - } - config[entry.id].type = nvsType; + const value = (nvsType <= NVSType.NVS_TYPE_I64) ? parseInt(entry.value, 10) : entry.value; + config[entry.id] = { + value: value, + type: nvsType, + }; } } else { - config[entry.id] = entry.value; + if (entry.id !== '') { + config[entry.id] = entry.value; + } } }); - const key = $('#nvs-new-key').val(); - const val = $('#nvs-new-value').val(); - if (key !== '') { + + // In the following, we assume that `#nvs-new-key` and `#nvs-new-value` + // correspond to input elements and thus their values are always strings. + const key = ($('#nvs-new-key') as JQuery).val(); + const val = ($('#nvs-new-value') as JQuery).val(); + + if (key && key !== '') { if (!slimMode) { - config[key] = {}; - config[key].value = val; - config[key].type = 33; + config[key] = { + value: val, + type: NVSType.NVS_TYPE_I8, // Assuming a default type here + }; } else { config[key] = val; } @@ -753,22 +947,23 @@ function getConfigJson(slimMode) { return config; } -function handleHWPreset(allfields, reboot) { + +function handleHWPreset(allfields: NodeListOf, reboot: boolean): void { const selJson = JSON.parse(allfields[0].value); - var cmd = allfields[0].attributes.cmdname.value; - + const cmd = allfields[0].getAttribute("cmdname"); console.log(`selected model: ${selJson.name}`); - let confPayload = { + let confPayload: ConfigPayload = { timestamp: Date.now(), - config: { model_config: { value: selJson.name, type: 33 } } + config: { model_config: { value: selJson.name, type: 33 } } // Assuming 33 is some sort of default type }; + for (const [name, value] of Object.entries(selJson.config)) { const storedval = (typeof value === 'string' || value instanceof String) ? value : JSON.stringify(value); confPayload.config[name] = { - value: storedval, - type: 33, - } + value: storedval.toString(), + type: NVSType.NVS_TYPE_STR, + }; showCmdMessage( cmd, 'MESSAGING_INFO', @@ -783,6 +978,7 @@ function handleHWPreset(allfields, reboot) { `Committing `, true ); + $.ajax({ url: '/config.json', dataType: 'text', @@ -814,7 +1010,6 @@ function handleHWPreset(allfields, reboot) { }); } - // pull json file from https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/b462691f69e2ad31ac95c547af6ec97afb0f53db/squeezelite-esp32-presets.json and function loadPresets() { if ($("#cfg-hw-preset-model_config").length == 0) return; @@ -832,7 +1027,7 @@ function loadPresets() { } }); if (preset_name !== '') { - ('#prev_preset').show().val(preset_name); + $('#prev_preset').show().val(preset_name); } } @@ -843,72 +1038,50 @@ function loadPresets() { ); } -function delayReboot(duration, cmdname, ota = 'reboot') { - const url = '/' + ota + '.json'; +function delayReboot(duration: number, cmdname: string, ota = 'reboot'): void { + const url = `/${ota}.json`; $('tbody#tasks').empty(); $('#tasks_sect').css('visibility', 'collapse'); - Promise.resolve({ cmdname: cmdname, url: url }) - .delay(duration) + + delay(Promise.resolve({ cmdname: cmdname, url: url }), duration) .then(function (data) { - if (data.cmdname.length > 0) { - showCmdMessage( - data.cmdname, - 'MESSAGING_WARNING', - 'System is rebooting.\n', - true - ); - } else { - showLocalMessage('System is rebooting.\n', 'MESSAGING_WARNING'); - } + // Your existing logic here console.log('now triggering reboot'); $("button[onclick*='handleReboot']").addClass('rebooting'); $.ajax({ - url: data.url, - dataType: 'text', - method: 'POST', - cache: false, - contentType: 'application/json; charset=utf-8', - data: JSON.stringify({ - timestamp: Date.now(), - }), - error: handleExceptionResponse, + // Your existing AJAX call setup here complete: function () { console.log('reboot call completed'); - Promise.resolve(data) - .delay(6000) + delay(Promise.resolve(data), 6000) .then(function (rdata) { - if (rdata.cmdname.length > 0) { - HideCmdMessage(rdata.cmdname); - } - getCommands(); - getConfig(); + // Your existing logic here }); }, }); }); } -// eslint-disable-next-line no-unused-vars -window.saveAutoexec1 = function (apply) { + +function saveAutoexec1(apply: boolean) { showCmdMessage('cfg-audio-tmpl', 'MESSAGING_INFO', 'Saving.\n', false); let commandLine = `${commandHeader} -o ${output} `; $('.sqcmd').each(function () { let { opt, val } = get_control_option_value($(this)); - if ((opt && opt.length>0 ) && typeof(val) == 'boolean' || val.length > 0) { - const optStr=opt===':'?opt:(` -${opt} `); - val = typeof(val) == 'boolean'?'':val; + if ((opt && opt.length > 0) && typeof (val) == 'boolean' || typeof (val) === 'string' && val.length > 0) { + const optStr = opt === ':' ? opt : (` -${opt} `); + val = typeof (val) == 'boolean' ? '' : val; commandLine += `${optStr} ${val}`; } }); - const resample=$('#cmd_opt_R input[name=resample]:checked'); - if (resample.length>0 && resample.attr('suffix')!=='') { + const resample = $('#cmd_opt_R input[name=resample]:checked'); + if (resample.length > 0 && resample.attr('suffix') !== '') { commandLine += resample.attr('suffix'); // now check resample_i option and if checked, add suffix to command line - if ($('#resample_i').is(":checked") && resample.attr('aint') =='true') { - commandLine += $('#resample_i').attr('suffix'); + if ($('#resample_i').is(":checked") && resample.attr('aint') == 'true') { + commandLine += $('#resample_i').attr('suffix'); } -} + } + - if (output === 'bt') { showCmdMessage( 'cfg-audio-tmpl', @@ -917,16 +1090,12 @@ window.saveAutoexec1 = function (apply) { true ); } - commandLine += concatenateOptions(options); + // commandLine += concatenateOptions(options); const data = { timestamp: Date.now(), - }; - data.config = { - autoexec1: { value: commandLine, type: 33 }, - // autoexec: { - // value: $('#disable-squeezelite').prop('checked') ? '0' : '1', - // type: 33, - // }, + config: { + autoexec1: { value: commandLine, type: NVSType.NVS_TYPE_STR } + } }; $.ajax({ @@ -965,7 +1134,7 @@ window.saveAutoexec1 = function (apply) { }); console.log('sent data:', JSON.stringify(data)); } -window.handleDisconnect = function () { +function handleDisconnect() { $.ajax({ url: '/connect.json', dataType: 'text', @@ -977,17 +1146,17 @@ window.handleDisconnect = function () { }), }); } -function setPlatformFilter(val) { +function setPlatformFilter(val: string) { if ($('.upf').filter(function () { return $(this).text().toUpperCase() === val.toUpperCase() }).length > 0) { $('#splf').val(val).trigger('input'); return true; } return false; } -window.handleConnect = function () { - ConnectingToSSID.ssid = $('#manual_ssid').val(); - ConnectingToSSID.pwd = $('#manual_pwd').val(); - ConnectingToSSID.dhcpname = $('#dhcp-name2').val(); +function handleConnect() { + ConnectingToSSID.ssid = $('#manual_ssid').val().toString(); + ConnectingToSSID.pwd = $('#manual_pwd').val().toString(); + ConnectingToSSID.dhcpname = $('#dhcp-name2').val().toString(); $("*[class*='connecting']").hide(); $('#ssid-wait').text(ConnectingToSSID.ssid); $('.connecting').show(); @@ -1008,39 +1177,40 @@ window.handleConnect = function () { // now we can re-set the intervals regardless of result } -function renderError(opt,error){ +function renderError(opt: string, error: string) { const fieldname = `cmd_opt_${opt}`; - let errorFieldName=`${fieldname}-error`; - let errorField=$(`#${errorFieldName}`); - let field=$(`#${fieldname}`); - - if (!errorField || errorField.length ==0) { + let errorFieldName = `${fieldname}-error`; + let errorField = $(`#${errorFieldName}`); + let field = $(`#${fieldname}`); + + if (!errorField || errorField.length == 0) { field.after(`
`); - errorField=$(`#${errorFieldName}`); + errorField = $(`#${errorFieldName}`); } - if(error.length ==0){ - errorField.hide(); - field.removeClass('is-invalid'); - field.addClass('is-valid'); - errorField.text(''); + if (error.length == 0) { + errorField.hide(); + field.removeClass('is-invalid'); + field.addClass('is-valid'); + errorField.text(''); } - else { - errorField.show(); - errorField.text(error); - field.removeClass('is-valid'); - field.addClass('is-invalid'); + else { + errorField.show(); + errorField.text(error); + field.removeClass('is-valid'); + field.addClass('is-invalid'); } return errorField; } -$(document).ready(function () { +$(function () { $('.material-icons').each(function (_index, entry) { - entry.attributes['icon'] = entry.textContent; + entry.setAttribute('data-icon', entry.textContent || ''); }); setIcons(true); handleNVSVisible(); flashState.init(); $('#fw-url-input').on('input', function () { - if ($(this).val().length > 8 && ($(this).val().startsWith('http://') || $(this).val().startsWith('https://'))) { + const stringVal = $(this).val().toString(); + if (stringVal.length > 8 && (stringVal.startsWith('http://') || stringVal.startsWith('https://'))) { $('#start-flash').show(); } else { @@ -1048,10 +1218,11 @@ $(document).ready(function () { } }); $('.upSrch').on('input', function () { - const val = this.value; - $("#rTable tr").removeClass(this.id + '_hide'); + const inputField: HTMLInputElement = this as HTMLInputElement; + const val = inputField.value; + $("#rTable tr").removeClass(inputField.id + '_hide'); if (val.length > 0) { - $(`#rTable td:nth-child(${$(this).parent().index() + 1})`).filter(function () { + $(`#rTable td:nth-child(${$(inputField).parent().index() + 1})`).filter(function () { return !$(this).text().toUpperCase().includes(val.toUpperCase()); }).parent().addClass(this.id + '_hide'); } @@ -1064,27 +1235,28 @@ $(document).ready(function () { getting known codecs from validOptions.codecs array use bootstrap classes to highlight the error with an overlay message */ $('#options input').on('input', function () { + const inputField: HTMLInputElement = this as HTMLInputElement; const { opt, val } = get_control_option_value(this); if (opt === 'c' || opt === 'e') { const fieldname = `cmd_opt_${opt}_codec-error`; - - const values = val.split(',').map(function (item) { + + const values = val.toString().split(',').map(function (item) { return item.trim(); }); /* get a list of invalid codecs */ const invalid = values.filter(function (item) { return !validOptions.codecs.includes(item); }); - renderError(opt,invalid.length > 0 ? `Invalid codec(s) ${invalid.join(', ')}` : ''); + renderError(opt, invalid.length > 0 ? `Invalid codec(s) ${invalid.join(', ')}` : ''); } /* add validation for cmd_opt_m, which accepts a mac_address */ if (opt === 'm') { const mac_regex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/; - renderError(opt,mac_regex.test(val) ? '' : 'Invalid MAC address'); + renderError(opt, mac_regex.test(val.toString()) ? '' : 'Invalid MAC address'); } if (opt === 'r') { - const rateRegex = /^(\d+\.?\d*|\.\d+)-(\d+\.?\d*|\.\d+)$|^(\d+\.?\d*)$|^(\d+\.?\d*,)+\d+\.?\d*$/; - renderError(opt,rateRegex.test(val)?'':`Invalid rate(s) ${val}. Acceptable format: |-|,,`); + const rateRegex = /^(\d+\.?\d*|\.\d+)-(\d+\.?\d*|\.\d+)$|^(\d+\.?\d*)$|^(\d+\.?\d*,)+\d+\.?\d*$/; + renderError(opt, rateRegex.test(val.toString()) ? '' : `Invalid rate(s) ${val}. Acceptable format: |-|,,`); } @@ -1098,7 +1270,7 @@ $(document).ready(function () { - $('#WifiConnectDialog')[0].addEventListener('shown.bs.modal', function (event) { + $('#WifiConnectDialog')[0].addEventListener('shown.bs.modal', function (event: any) { $("*[class*='connecting']").hide(); if (event?.relatedTarget) { @@ -1134,35 +1306,36 @@ $(document).ready(function () { }); $('#uCnfrm')[0].addEventListener('shown.bs.modal', function () { - $('#selectedFWURL').text($('#fw-url-input').val()); + $('#selectedFWURL').text($('#fw-url-input').val().toString()); }); - $('input#show-commands')[0].checked = LastCommandsState === 1; + ($('input#show-commands')[0] as HTMLInputElement).checked = LastCommandsState === 1; $('a[href^="#tab-commands"]').hide(); $('#load-nvs').on('click', function () { $('#nvsfilename').trigger('click'); }); $('#nvsfilename').on('change', function () { + const _this = this as HTMLInputElement; if (typeof window.FileReader !== 'function') { throw "The file API isn't supported on this browser."; } - if (!this.files) { + if (!_this.files) { throw 'This browser does not support the `files` property of the file input.'; } - if (!this.files[0]) { + if (!_this.files[0]) { return undefined; } - const file = this.files[0]; + const file = _this.files[0]; let fr = new FileReader(); fr.onload = function (e) { - let data = {}; + let data: Record; try { - data = JSON.parse(e.target.result); + data = JSON.parse(e.target.result.toString()); } catch (ex) { alert('Parsing failed!\r\n ' + ex); } - $('input.nvs').each(function (_index, entry) { + $('input.nvs').each(function (_index, entry: HTMLInputElement) { $(this).parent().removeClass('bg-warning').removeClass('bg-success'); if (data[entry.id]) { if (data[entry.id] !== entry.value) { @@ -1183,7 +1356,7 @@ $(document).ready(function () { } } fr.readAsText(file); - this.value = null; + _this.value = null; } ); @@ -1206,8 +1379,9 @@ $(document).ready(function () { }); $('input#show-commands').on('click', function () { - this.checked = this.checked ? 1 : 0; - if (this.checked) { + const _this = this as HTMLInputElement; + _this.checked = _this.checked ? true : false; + if (_this.checked) { $('a[href^="#tab-commands"]').show(); LastCommandsState = 1; } else { @@ -1219,28 +1393,30 @@ $(document).ready(function () { $('#disable-squeezelite').on('click', function () { // this.checked = this.checked ? 1 : 0; // $('#disable-squeezelite').prop('checked') - if (this.checked) { + const _this = this as HTMLInputElement; + if (_this.checked) { // Store the current value before overwriting it const currentValue = $('#cmd_opt_s').val(); $('#cmd_opt_s').data('originalValue', currentValue); - + // Overwrite the value with '-disable' $('#cmd_opt_s').val('-disable'); } else { // Retrieve the original value const originalValue = $('#cmd_opt_s').data('originalValue'); - + // Restore the original value if it exists, otherwise set it to an empty string $('#cmd_opt_s').val(originalValue ? originalValue : ''); } - + }); - + $('input#show-nvs').on('click', function () { - this.checked = this.checked ? 1 : 0; - Cookies.set("show-nvs", this.checked ? 'Y' : 'N'); + const _this = this as HTMLInputElement; + _this.checked = _this.checked ? true : false; + Cookies.set("show-nvs", _this.checked ? 'Y' : 'N'); handleNVSVisible(); }); $('#btn_reboot_recovery').on('click', function () { @@ -1259,7 +1435,7 @@ $(document).ready(function () { saveAutoexec1(true); }); $('#btn_disconnect').on('click', function () { - ConnectedTo = {}; + ConnectedTo = resetNetworkConnection(); refreshAPHTML2(); $.ajax({ url: '/connect.json', @@ -1304,25 +1480,26 @@ $(document).ready(function () { }); $('#fwUpload').on('click', function () { - const fileInput = document.getElementById('flashfilename').files; + const fileInput = (document.getElementById('flashfilename') as HTMLInputElement).files; if (fileInput.length === 0) { alert('No file selected!'); } else { - $('#fw-url-input').value = null; + ($('#fw-url-input') as unknown as HTMLInputElement).value = null; flashState.StartOTA(); } }); $('[name=output-tmpl]').on('click', function () { - handleTemplateTypeRadio(this.id); + const outputType = this.id as OutputType; + handleTemplateTypeRadio(outputType); }); $('#chkUpdates').on('click', function () { $('#rTable').html(''); $.getJSON(releaseURL, function (data) { let i = 0; - const branches = []; - data.forEach(function (release) { + const branches: string[] = []; + data.forEach(function (release: ReleaseEntry) { const namecomponents = release.name.split('#'); const branch = namecomponents[3]; if (!branches.includes(branch)) { @@ -1335,7 +1512,7 @@ $(document).ready(function () { }); $('#fwbranch').append(fwb); - data.forEach(function (release) { + data.forEach(function (release: ReleaseEntry) { let url = ''; release.assets.forEach(function (asset) { if (asset.name.match(/\.bin$/)) { @@ -1379,7 +1556,7 @@ $(document).ready(function () { setPlatformFilter(project_name) } $('#rTable tr.release').on('click', function () { - var url = this.attributes['fwurl'].value; + var url = this.getAttribute('fwurl'); if (lmsBaseUrl) { url = url.replace(/.*\/download\//, lmsBaseUrl + '/plugins/SqueezeESP32/firmware/'); } @@ -1398,21 +1575,21 @@ $(document).ready(function () { $('#fwbranch').empty(); $.getJSON(releaseURL, function (data) { let i = 0; - const branches = []; - data.forEach(function (release) { + const branches: string[] = []; + data.forEach(function (release: ReleaseEntry) { const namecomponents = release.name.split('#'); const branch = namecomponents[3]; if (!branches.includes(branch)) { branches.push(branch); } }); - let fwb; + let fwb: string; branches.forEach(function (branch) { - fwb += ''; + fwb += ``; }); $('#fwbranch').append(fwb); - data.forEach(function (release) { + data.forEach(function (release: ReleaseEntry) { let url = ''; release.assets.forEach(function (asset) { if (asset.name.match(/\.bin$/)) { @@ -1434,39 +1611,12 @@ $(document).ready(function () { body = body.replace(/- \(.+?\) /g, '- '); const trclass = i++ > 6 ? ' hide' : ''; $('#releaseTable').append( - "" + - "" + - ver + - '' + - '' + - new Date(release.created_at).toLocalShort() + - '' + - '' + - cfg + - '' + - '' + - idf + - '' + - '' + - branch + - '' + - "" + - '' + `${ver}${new Date(release.created_at).toLocalShort()}${cfg}${idf}${branch}` ); }); if (i > 7) { $('#releaseTable').append( - "" + - "" + - "" + - '' + - '' + `` ); $('#showallbutton').on('click', function () { $('tr.hide').removeClass('hide'); @@ -1493,7 +1643,7 @@ $(document).ready(function () { }); // eslint-disable-next-line no-unused-vars -window.setURL = function (button) { +window.setURL = function (button: HTMLButtonElement) { let url = button.dataset.url; $('[data-bs-url^="http"]') @@ -1511,21 +1661,26 @@ window.setURL = function (button) { $('#fwurl').val(url); } +interface RssiIcon { + label: string; + icon: string; +} -function rssiToIcon(rssi) { +function rssiToIcon(rssi: number): RssiIcon { if (rssi >= -55) { - return { 'label': '****', 'icon': `signal_wifi_statusbar_4_bar` }; + return { label: '****', icon: `signal_wifi_statusbar_4_bar` }; } else if (rssi >= -60) { - return { 'label': '***', 'icon': `network_wifi_3_bar` }; + return { label: '***', icon: `network_wifi_3_bar` }; } else if (rssi >= -65) { - return { 'label': '**', 'icon': `network_wifi_2_bar` }; + return { label: '**', icon: `network_wifi_2_bar` }; } else if (rssi >= -70) { - return { 'label': '*', 'icon': `network_wifi_1_bar` }; + return { label: '*', icon: `network_wifi_1_bar` }; } else { - return { 'label': '.', 'icon': `signal_wifi_statusbar_null` }; + return { label: '.', icon: `signal_wifi_statusbar_null` }; } } + function refreshAP() { if (ConnectedTo?.urc === connectReturnCode.ETH) return; $.ajaxSetup({ @@ -1533,7 +1688,7 @@ function refreshAP() { }); $.getJSON('/scan.json', async function () { await sleep(2000); - $.getJSON('/ap.json', function (data) { + $.getJSON('/ap.json', function (data: NetworkConnection[]) { if (data.length > 0) { // sort by signal strength data.sort(function (a, b) { @@ -1549,8 +1704,8 @@ function refreshAP() { }); }); } -function formatAP(ssid, rssi, auth) { - const rssi_icon = rssiToIcon(rssi); +function formatAP(ssid: string, rssi: number, auth: number) { + const rssi_icon: RssiIcon = rssiToIcon(rssi); const auth_icon = { label: auth == 0 ? '🔓' : '🔒', icon: auth == 0 ? 'no_encryption' : 'lock' }; return `${ssid} @@ -1559,12 +1714,12 @@ function formatAP(ssid, rssi, auth) { ${getIcon(auth_icon)} `; } -function refreshAPHTML2(data) { +function refreshAPHTML2(data?: NetworkConnection[]) { let h = ''; $('#wifiTable tr td:first-of-type').text(''); $('#wifiTable tr').removeClass('table-success table-warning'); if (data) { - data.forEach(function (e) { + data.forEach(function (e: NetworkConnection) { h += formatAP(e.ssid, e.rssi, e.auth); }); $('#wifiTable').html(h); @@ -1573,15 +1728,22 @@ function refreshAPHTML2(data) { $('#wifiTable').append(formatAP('Manual add', 0, 0)); $('#wifiTable tr:last').addClass('table-light text-dark').addClass('manual_add'); } - if (ConnectedTo.ssid && (ConnectedTo.urc === connectReturnCode.OK || ConnectedTo.urc === connectReturnCode.RESTORE)) { + if (ConnectedTo && ConnectedTo.ssid && (ConnectedTo.urc === connectReturnCode.OK || ConnectedTo.urc === connectReturnCode.RESTORE)) { const wifiSelector = `#wifiTable td:contains("${ConnectedTo.ssid}")`; if ($(wifiSelector).filter(function () { return $(this).text() === ConnectedTo.ssid; }).length == 0) { $('#wifiTable').prepend(`${formatAP(ConnectedTo.ssid, ConnectedTo.rssi ?? 0, 0)}`); } $(wifiSelector).filter(function () { return $(this).text() === ConnectedTo.ssid; }).siblings().first().html('✓').parent().addClass((ConnectedTo.urc === connectReturnCode.OK ? 'table-success' : 'table-warning')); $('span#foot-if').html(`SSID: ${ConnectedTo.ssid}, IP: ${ConnectedTo.ip}`); - $('#wifiStsIcon').html(rssiToIcon(ConnectedTo.rssi)); + const rssiIconObj = rssiToIcon(ConnectedTo.rssi); // Assume this returns an object like { label: 'some_label', icon: 'some_icon_name' } + const iconTextContent = getIcon(rssiIconObj); // Function to get the text content for the material icon + // Set the icon text content + $('#wifiStsIcon').text(iconTextContent); + + // Update the aria-label and custom icon attribute + $('#wifiStsIcon').attr('aria-label', rssiIconObj.label); + $('#wifiStsIcon').attr('icon', rssiIconObj.icon); } else if (ConnectedTo?.urc !== connectReturnCode.ETH) { $('span#foot-if').html(''); @@ -1594,46 +1756,18 @@ function refreshETH() { $('span#foot-if').html(`Network: Ethernet, IP: ${ConnectedTo.ip}`); } } -function showTask(task) { +function showTask(task: TaskDetails) { console.debug( - this.toLocaleString() + - '\t' + - task.nme + - '\t' + - task.cpu + - '\t' + - taskStates[task.st] + - '\t' + - task.minstk + - '\t' + - task.bprio + - '\t' + - task.cprio + - '\t' + - task.num + `${this.toLocaleString()}\t${task.nme}\t${task.cpu}\t${taskStates[task.st]}\t${task.minstk}\t${task.bprio}\t${task.cprio}\t${task.num}` ); $('tbody#tasks').append( - '' + - task.num + - '' + - task.nme + - '' + - task.cpu + - '' + - taskStates[task.st] + - '' + - task.minstk + - '' + - task.bprio + - '' + - task.cprio + - '' + `${task.num}${task.nme}${task.cpu}${taskStates[task.st]}${task.minstk}${task.bprio}${task.cprio}` ); } -function btExists(name) { +function btExists(name: string) { return getBTSinkOpt(name).length > 0; } -function getBTSinkOpt(name) { +function getBTSinkOpt(name: string) { return $(`${btSinkNamesOptSel} option:contains('${name}')`); } function getMessages() { @@ -1658,22 +1792,16 @@ function getMessages() { statsData.ntasks ); console.debug( - msgTime.toLocalShort() + - '\tname' + - '\tcpu' + - '\tstate' + - '\tminstk' + - '\tbprio' + - '\tcprio' + - '\tnum' + `${msgTime.toLocalShort()}\tname\tcpu\tstate\tminstk\tbprio\tcprio\tnum` ); if (statsData.tasks) { + const taskList = statsData.tasks as TaskDetails[] if ($('#tasks_sect').css('visibility') === 'collapse') { $('#tasks_sect').css('visibility', 'visible'); } $('tbody#tasks').html(''); - statsData.tasks - .sort(function (a, b) { + statsData.taskList + .sort(function (a: TaskDetails, b: TaskDetails) { return b.cpu - a.cpu; }) .forEach(showTask, msgTime); @@ -1690,23 +1818,32 @@ function getMessages() { showCmdMessage(msgparts[1], msg.type, msgparts[2], true); break; case 'MESSAGING_CLASS_BT': - if ($("#cfg-audio-bt_source-sink_name").is('input')) { - var attr = $("#cfg-audio-bt_source-sink_name")[0].attributes; + if ($(btSinkNamesOptSel).is('input')) { + const sinkNameCtrl = $(btSinkNamesOptSel)[0] as HTMLInputElement; + var attr = sinkNameCtrl.attributes; var attrs = ''; for (var j = 0; j < attr.length; j++) { if (attr.item(j).name != "type") { attrs += `${attr.item(j).name} = "${attr.item(j).value}" `; } } - var curOpt = $("#cfg-audio-bt_source-sink_name")[0].value; - $("#cfg-audio-bt_source-sink_name").replaceWith(` `); + var curOpt = sinkNameCtrl.value; + $(btSinkNamesOptSel).replaceWith(` `); } - JSON.parse(msg.message).forEach(function (btEntry) { + + JSON.parse(msg.message).forEach(function (btEntry: BTDevice) { + // [{\n\t\t\"name\":\t\"SMSL BT4.2\",\n\t\t\"rssi\":\t-64\n\t}] // // if (!btExists(btEntry.name)) { - $("#cfg-audio-bt_source-sink_name").append(``); - showMessage({ type: msg.type, message: `BT Audio device found: ${btEntry.name} RSSI: ${btEntry.rssi} ` }, msgTime); + $(btSinkNamesOptSel).append(``); + showMessage({ + type: msg.type, + message: `BT Audio device found: ${btEntry.name} RSSI: ${btEntry.rssi} `, + class: '', + sent_time: 0, + current_time: 0 + }, msgTime); } getBTSinkOpt(btEntry.name).attr('data-bs-description', `${btEntry.name} (${btEntry.rssi}dB)`) .attr('rssi', btEntry.rssi) @@ -1714,10 +1851,19 @@ function getMessages() { .text(`${btEntry.name} [${btEntry.rssi}dB]`).trigger('change'); }); - $(btSinkNamesOptSel).append($(`${btSinkNamesOptSel} option`).remove().sort(function (a, b) { - console.log(`${parseInt($(a).attr('rssi'))} < ${parseInt($(b).attr('rssi'))} ? `); - return parseInt($(a).attr('rssi')) < parseInt($(b).attr('rssi')) ? 1 : -1; - })); + // Get the options as an array + const btEntries = Array.from($(btSinkNamesOptSel).find('option')); + + // Sort the options based on the 'rssi' attribute + btEntries.sort(function (a, b) { + const rssiA = parseInt($(a).attr('rssi'), 10); + const rssiB = parseInt($(b).attr('rssi'), 10); + console.log(`${rssiA} < ${rssiB} ? `); + return rssiB - rssiA; // Sort by descending RSSI values + }); + + // Clear the select element and append the sorted options + $(btSinkNamesOptSel).empty().append(btEntries); break; default: break; @@ -1754,7 +1900,7 @@ st is task state. I provided a "typedef" that you can use to convert to text cpu is cpu percent used */ } -function handleRecoveryMode(data) { +function handleRecoveryMode(data: StatusObject) { const locRecovery = data.recovery ?? 0; if (locRecovery === 1) { recovery = true; @@ -1777,19 +1923,19 @@ function handleRecoveryMode(data) { } -function hasConnectionChanged(data) { +function hasConnectionChanged(data: StatusObject) { // gw: "192.168.10.1" // ip: "192.168.10.225" // netmask: "255.255.255.0" // ssid: "MyTestSSID" - return (data.urc !== ConnectedTo.urc || + return (ConnectedTo && (data.urc !== ConnectedTo.urc || data.ssid !== ConnectedTo.ssid || data.gw !== ConnectedTo.gw || data.netmask !== ConnectedTo.netmask || - data.ip !== ConnectedTo.ip || data.rssi !== ConnectedTo.rssi) + data.ip !== ConnectedTo.ip || data.rssi !== ConnectedTo.rssi)) } -function handleWifiDialog(data) { +function handleWifiDialog(data?: StatusObject) { if ($('#WifiConnectDialog').is(':visible')) { if (ConnectedTo.ip) { $('#ipAddress').text(ConnectedTo.ip); @@ -1856,15 +2002,31 @@ function handleWifiDialog(data) { } } -function setIcons(offline) { - $('.material-icons').each(function (_index, entry) { - entry.textContent = entry.attributes[offline ? 'aria-label' : 'icon'].value; +function setIcons(offline: boolean): void { + $('.material-icons').each(function (_index, entry: Element) { + const htmlEntry = entry as HTMLElement; + htmlEntry.textContent = htmlEntry.getAttribute(offline ? 'aria-label' : 'data-icon') || ''; }); } -function handleNetworkStatus(data) { +function assignStatusToNetworkConnection(data: StatusObject): NetworkConnection { + const connection: NetworkConnection = { + urc: data.urc ?? 0, // Assuming `urc` should default to 0 if undefined in data + auth: undefined, // This doesn't exist in StatusObject, so it remains undefined + pwd: undefined, // Also doesn't exist in StatusObject + dhcpname: undefined, // Also doesn't exist in StatusObject + Action: undefined, // Also doesn't exist in StatusObject + ip: data.ip, + ssid: data.ssid, + rssi: data.rssi, + gw: data.gw, + netmask: data.netmask + }; + return connection; +} +function handleNetworkStatus(data: StatusObject) { setIcons(!isConnected()); if (hasConnectionChanged(data) || !data.urc) { - ConnectedTo = data; + ConnectedTo = assignStatusToNetworkConnection(data); $(".if_eth").hide(); $('.if_wifi').hide(); if (!data.urc || ConnectedTo.urc != connectReturnCode.ETH) { @@ -1882,7 +2044,7 @@ function handleNetworkStatus(data) { -function batteryToIcon(voltage) { +function batteryToIcon(voltage: number) { /* Assuming Li-ion 18650s as a power source, 3.9V per cell, or above is treated as full charge (>75% of capacity). 3.4V is empty. The gauge is loosely following the graph here: @@ -1911,12 +2073,12 @@ function checkStatus() { handleNetworkStatus(data); handlebtstate(data); flashState.EventTargetStatus(data); - if(data.depth) { + if (data.depth) { depth = data.depth; - if(depth==16){ + if (depth == 16) { $('#cmd_opt_R').show(); } - else{ + else { $('#cmd_opt_R').hide(); } } @@ -1941,7 +2103,7 @@ function checkStatus() { const bat_icon = batteryToIcon(data.Voltage); $('#battery').html(`${getIcon(bat_icon)}`); $('#battery').attr("aria-label", bat_icon.label); - $('#battery').attr("icon", bat_icon.icon); + $('#battery').attr("data-icon", bat_icon.icon); $('#battery').show(); } else { $('#battery').hide(); @@ -1992,43 +2154,42 @@ function checkStatus() { } // eslint-disable-next-line no-unused-vars window.runCommand = function (button, reboot) { - let cmdstring = button.attributes.cmdname.value; + let cmdstring = button.getAttribute('cmdname'); showCmdMessage( - button.attributes.cmdname.value, + cmdstring, 'MESSAGING_INFO', 'Executing.', false ); const fields = document.getElementById('flds-' + cmdstring); - const allfields = fields?.querySelectorAll('select,input'); + const allfields = fields?.querySelectorAll('select,input') as NodeListOf; if (cmdstring === 'cfg-hw-preset') return handleHWPreset(allfields, reboot); cmdstring += ' '; if (fields) { - for (const field of allfields) { let qts = ''; let opt = ''; - let attr = field.attributes; - let isSelect = $(field).is('select'); - const hasValue = attr?.hasvalue?.value === 'true'; + const isSelect = field.tagName === 'SELECT'; + const hasValue = field.getAttribute('hasvalue') === 'true'; const validVal = (isSelect && field.value !== '--') || (!isSelect && field.value !== ''); - if (!hasValue || hasValue && validVal) { - if (attr?.longopts?.value !== 'undefined') { - opt += '--' + attr?.longopts?.value; - } else if (attr?.shortopts?.value !== 'undefined') { - opt = '-' + attr.shortopts.value; + if (!hasValue || (hasValue && validVal)) { + const longopts = field.getAttribute('longopts'); + const shortopts = field.getAttribute('shortopts'); + + if (longopts !== null && longopts !== 'undefined') { + opt += '--' + longopts; + } else if (shortopts !== null && shortopts !== 'undefined') { + opt = '-' + shortopts; } - if (attr?.hasvalue?.value === 'true') { - if (attr?.value !== '') { - qts = /\s/.test(field.value) ? '"' : ''; - cmdstring += opt + ' ' + qts + field.value + qts + ' '; - } + if (hasValue) { + qts = /\s/.test(field.value) ? '"' : ''; + cmdstring += `${opt} ${qts}${field.value}${qts} `; } else { // this is a checkbox - if (field?.checked) { - cmdstring += opt + ' '; + if (field.checked) { + cmdstring += `${opt} `; } } } @@ -2039,8 +2200,9 @@ window.runCommand = function (button, reboot) { const data = { timestamp: Date.now(), + command: cmdstring }; - data.command = cmdstring; + $.ajax({ url: '/commands.json', @@ -2076,13 +2238,13 @@ window.runCommand = function (button, reboot) { JSON.parse(response).Result === 'Success' && reboot ) { - delayReboot(2500, button.attributes.cmdname.value); + delayReboot(2500, button.getAttribute('cmdname')); } }, }); } -function getLongOps(data, name, longopts) { - return data.values[name] !== undefined ? data.values[name][longopts] : ""; +function getLongOps(data:CommandValues, name:string, longopts:string) { + return data[name] !== undefined ? data[name][longopts] : ""; } function getCommands() { $.ajaxSetup({ @@ -2091,7 +2253,7 @@ function getCommands() { $.getJSON('/commands.json', function (data) { console.log(data); $('.orec').show(); - data.commands.forEach(function (command) { + data.commands.forEach(function (command:CommandEntry) { if ($('#flds-' + command.name).length === 0) { const cmdParts = command.name.split('-'); const isConfig = cmdParts[0] === 'cfg'; @@ -2102,21 +2264,15 @@ function getCommands() { command.argtable.forEach(function (arg) { let placeholder = arg.datatype || ''; const ctrlname = command.name + '-' + arg.longopts; - const curvalue = getLongOps(data, command.name, arg.longopts); + const curvalue = getLongOps(data.values, command.name, arg.longopts); - let attributes = 'hasvalue=' + arg.hasvalue + ' '; + let attributes = `hasvalue=${arg.hasvalue} `; attributes += 'longopts="' + arg.longopts + '" '; attributes += 'shortopts="' + arg.shortopts + '" '; attributes += 'checkbox=' + arg.checkbox + ' '; attributes += 'cmdname="' + command.name + '" '; attributes += - 'id="' + - ctrlname + - '" name="' + - ctrlname + - '" hasvalue="' + - arg.hasvalue + - '" '; + `id="${ctrlname}" name="${ctrlname}" hasvalue="${arg.hasvalue}" `; let extraclass = arg.mincount > 0 ? 'bg-success' : ''; if (arg.glossary === 'hidden') { attributes += ' style="visibility: hidden;"'; @@ -2168,28 +2324,28 @@ function getCommands() { } } }); - $(".sclk").off('click').on('click', function () { runCommand(this, false); }); - $(".cclk").off('click').on('click', function () { runCommand(this, true); }); - data.commands.forEach(function (command) { + $(".sclk").off('click').on('click', function () { window.runCommand((this as HTMLButtonElement), false); }); + $(".cclk").off('click').on('click', function () { window.runCommand((this as HTMLButtonElement), true); }); + data.commands.forEach(function (command:CommandEntry) { $('[cmdname=' + command.name + ']:input').val(''); $('[cmdname=' + command.name + ']:checkbox').prop('checked', false); if (command.argtable) { command.argtable.forEach(function (arg) { const ctrlselector = '#' + command.name + '-' + arg.longopts; - const ctrlValue = getLongOps(data, command.name, arg.longopts); if (arg.checkbox) { - $(ctrlselector)[0].checked = ctrlValue; + ($(ctrlselector)[0] as HTMLInputElement).checked = getLongOps(data, command.name, arg.longopts) as boolean; } else { + let ctrlValue = getLongOps(data, command.name, arg.longopts); if (ctrlValue !== undefined) { $(ctrlselector) - .val(ctrlValue) + .val(ctrlValue.toString()) .trigger('change'); } if ( - $(ctrlselector)[0].value.length === 0 && + ($(ctrlselector)[0] as HTMLInputElement).value.length === 0 && (arg.datatype || '').includes('|') ) { - $(ctrlselector)[0].value = '--'; + ($(ctrlselector)[0] as HTMLInputElement).value = '--'; } } }); @@ -2221,7 +2377,7 @@ function getConfig() { .sort() .forEach(function (key) { let val = data[key].value; - if (key === 'autoexec1') { + if (key === 'autoexec1') { /* call new function to parse the squeezelite options */ processSqueezeliteCommandLine(val); } else if (key === 'host_name') { @@ -2250,22 +2406,11 @@ function getConfig() { } $('tbody#nvsTable').append( - '' + - '' + - key + - '' + - "" + - "' + - gpioEntry.group + - '' + - gpioEntry.name + - '' + - gpioEntry.gpio + - '' + - (gpioEntry.fixed ? 'Fixed' : 'Configuration') + - '' + `${gpioEntry.group}${gpioEntry.name}${gpioEntry.gpio}${gpioEntry.fixed ? 'Fixed' : 'Configuration'}` ); }); } @@ -2299,15 +2436,15 @@ function getConfig() { }); } -function processSqueezeliteCommandLine(val) { +function processSqueezeliteCommandLine(val:string) { const parsed = parseSqueezeliteCommandLine(val); if (parsed.output.toUpperCase().startsWith('I2S')) { handleTemplateTypeRadio('i2s'); } else if (parsed.output.toUpperCase().startsWith('SPDIF')) { handleTemplateTypeRadio('spdif'); } else if (parsed.output.toUpperCase().startsWith('BT')) { - if(parsed.otherOptions.btname){ - commandBTSinkName= parsed.otherOptions.btname; + if (parsed.otherOptions.btname) { + commandBTSinkName = parsed.otherOptions.btname; } handleTemplateTypeRadio('bt'); @@ -2317,7 +2454,9 @@ function processSqueezeliteCommandLine(val) { if (!$(`#cmd_opt_${key}`).hasOwnProperty('checked')) { $(`#cmd_opt_${key}`).val(option); } else { - $(`#cmd_opt_${key}`)[0].checked = option; + if(typeof option === 'boolean'){ + ($(`#cmd_opt_${key}`)[0] as HTMLInputElement).checked = option ; + } } }); if (parsed.options.hasOwnProperty('u')) { @@ -2331,28 +2470,31 @@ function processSqueezeliteCommandLine(val) { } if (parsed.options.hasOwnProperty('s')) { // parse -u v[:i] and check the appropriate radio button with id #resample_v - if(parsed.options.s === '-disable'){ - $('#disable-squeezelite')[0].checked = true; + if (parsed.options.s === '-disable') { + ($('#disable-squeezelite')[0] as HTMLInputElement).checked = true; } else { - $('#disable-squeezelite')[0].checked = false; + ($('#disable-squeezelite')[0] as HTMLInputElement).checked = false; } } - + } -function showLocalMessage(message, severity) { - const msg = { +function showLocalMessage(message:string, severity:string) { + const msg:MessageEntry = { message: message, type: severity, + class: '', + sent_time: 0, + current_time: 0 }; showMessage(msg, new Date()); } -function showMessage(msg, msgTime) { +function showMessage(msg: MessageEntry, msgTime: Date) { let color = 'table-success'; if (msg.type === 'MESSAGING_WARNING') { @@ -2373,28 +2515,23 @@ function showMessage(msg, msgTime) { $('#msgcnt').removeClass('badge-success'); $('#msgcnt').removeClass('badge-warning'); $('#msgcnt').removeClass('badge-danger'); - $('#msgcnt').addClass(pillcolors[messageseverity]); + $('#msgcnt').addClass({ + MESSAGING_INFO: 'badge-success', + MESSAGING_WARNING: 'badge-warning', + MESSAGING_ERROR: 'badge-danger', + }[messageseverity]); $('#msgcnt').text(messagecount); } $('#syslogTable').append( - "" + - '' + - msgTime.toLocalShort() + - '' + - '' + - msg.message.encodeHTML() + - '' + - '' + `${msgTime.toLocalShort()}${msg.message.encodeHTML()}` ); } -function inRange(x, min, max) { +function inRange(x:number, min:number, max:number) { return (x - min) * (x - max) <= 0; } -function sleep(ms) { +function sleep(ms:number) { return new Promise(resolve => setTimeout(resolve, ms)); } diff --git a/components/wifi-manager/webapp/src/js/proto/nanopb_pb.js b/components/wifi-manager/webapp/src/js/proto/nanopb_pb.js new file mode 100644 index 00000000..4520cd8c --- /dev/null +++ b/components/wifi-manager/webapp/src/js/proto/nanopb_pb.js @@ -0,0 +1,1653 @@ +// source: nanopb.proto +/** + * @fileoverview + * @enhanceable + * @suppress {missingRequire} reports error on implicit type usages. + * @suppress {messageConventions} JS Compiler reports an error if a variable or + * field starts with 'MSG_' and isn't a translatable message. + * @public + */ +// GENERATED CODE -- DO NOT EDIT! +/* eslint-disable */ +// @ts-nocheck + +var jspb = require('google-protobuf'); +var goog = jspb; +var global = (function() { + if (this) { return this; } + if (typeof window !== 'undefined') { return window; } + if (typeof global !== 'undefined') { return global; } + if (typeof self !== 'undefined') { return self; } + return Function('return this')(); +}.call(null)); + +var google_protobuf_descriptor_pb = require('google-protobuf/google/protobuf/descriptor_pb.js'); +goog.object.extend(proto, google_protobuf_descriptor_pb); +goog.exportSymbol('proto.DescriptorSize', null, global); +goog.exportSymbol('proto.FieldType', null, global); +goog.exportSymbol('proto.IntSize', null, global); +goog.exportSymbol('proto.NanoPBOptions', null, global); +goog.exportSymbol('proto.TypenameMangling', null, global); +goog.exportSymbol('proto.nanopb', null, global); +goog.exportSymbol('proto.nanopbEnumopt', null, global); +goog.exportSymbol('proto.nanopbFileopt', null, global); +goog.exportSymbol('proto.nanopbMsgopt', null, global); +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.NanoPBOptions = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.NanoPBOptions.repeatedFields_, null); +}; +goog.inherits(proto.NanoPBOptions, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.NanoPBOptions.displayName = 'proto.NanoPBOptions'; +} + +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.NanoPBOptions.repeatedFields_ = [24,26]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.NanoPBOptions.prototype.toObject = function(opt_includeInstance) { + return proto.NanoPBOptions.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.NanoPBOptions} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.NanoPBOptions.toObject = function(includeInstance, msg) { + var f, obj = { + maxSize: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f, + maxLength: (f = jspb.Message.getField(msg, 14)) == null ? undefined : f, + maxCount: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f, + intSize: jspb.Message.getFieldWithDefault(msg, 7, 0), + type: jspb.Message.getFieldWithDefault(msg, 3, 0), + longNames: jspb.Message.getBooleanFieldWithDefault(msg, 4, true), + packedStruct: jspb.Message.getBooleanFieldWithDefault(msg, 5, false), + packedEnum: jspb.Message.getBooleanFieldWithDefault(msg, 10, false), + skipMessage: jspb.Message.getBooleanFieldWithDefault(msg, 6, false), + noUnions: jspb.Message.getBooleanFieldWithDefault(msg, 8, false), + msgid: (f = jspb.Message.getField(msg, 9)) == null ? undefined : f, + anonymousOneof: jspb.Message.getBooleanFieldWithDefault(msg, 11, false), + proto3: jspb.Message.getBooleanFieldWithDefault(msg, 12, false), + proto3SingularMsgs: jspb.Message.getBooleanFieldWithDefault(msg, 21, false), + enumToString: jspb.Message.getBooleanFieldWithDefault(msg, 13, false), + fixedLength: jspb.Message.getBooleanFieldWithDefault(msg, 15, false), + fixedCount: jspb.Message.getBooleanFieldWithDefault(msg, 16, false), + submsgCallback: jspb.Message.getBooleanFieldWithDefault(msg, 22, false), + mangleNames: jspb.Message.getFieldWithDefault(msg, 17, 0), + callbackDatatype: jspb.Message.getFieldWithDefault(msg, 18, "pb_callback_t"), + callbackFunction: jspb.Message.getFieldWithDefault(msg, 19, "pb_default_field_callback"), + descriptorsize: jspb.Message.getFieldWithDefault(msg, 20, 0), + defaultHas: jspb.Message.getBooleanFieldWithDefault(msg, 23, false), + includeList: (f = jspb.Message.getRepeatedField(msg, 24)) == null ? undefined : f, + excludeList: (f = jspb.Message.getRepeatedField(msg, 26)) == null ? undefined : f, + pb_package: (f = jspb.Message.getField(msg, 25)) == null ? undefined : f, + typeOverride: (f = jspb.Message.getField(msg, 27)) == null ? undefined : f, + sortByTag: jspb.Message.getBooleanFieldWithDefault(msg, 28, true) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.NanoPBOptions} + */ +proto.NanoPBOptions.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.NanoPBOptions; + return proto.NanoPBOptions.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.NanoPBOptions} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.NanoPBOptions} + */ +proto.NanoPBOptions.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readInt32()); + msg.setMaxSize(value); + break; + case 14: + var value = /** @type {number} */ (reader.readInt32()); + msg.setMaxLength(value); + break; + case 2: + var value = /** @type {number} */ (reader.readInt32()); + msg.setMaxCount(value); + break; + case 7: + var value = /** @type {!proto.IntSize} */ (reader.readEnum()); + msg.setIntSize(value); + break; + case 3: + var value = /** @type {!proto.FieldType} */ (reader.readEnum()); + msg.setType(value); + break; + case 4: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setLongNames(value); + break; + case 5: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setPackedStruct(value); + break; + case 10: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setPackedEnum(value); + break; + case 6: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setSkipMessage(value); + break; + case 8: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setNoUnions(value); + break; + case 9: + var value = /** @type {number} */ (reader.readUint32()); + msg.setMsgid(value); + break; + case 11: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setAnonymousOneof(value); + break; + case 12: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setProto3(value); + break; + case 21: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setProto3SingularMsgs(value); + break; + case 13: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setEnumToString(value); + break; + case 15: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setFixedLength(value); + break; + case 16: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setFixedCount(value); + break; + case 22: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setSubmsgCallback(value); + break; + case 17: + var value = /** @type {!proto.TypenameMangling} */ (reader.readEnum()); + msg.setMangleNames(value); + break; + case 18: + var value = /** @type {string} */ (reader.readString()); + msg.setCallbackDatatype(value); + break; + case 19: + var value = /** @type {string} */ (reader.readString()); + msg.setCallbackFunction(value); + break; + case 20: + var value = /** @type {!proto.DescriptorSize} */ (reader.readEnum()); + msg.setDescriptorsize(value); + break; + case 23: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setDefaultHas(value); + break; + case 24: + var value = /** @type {string} */ (reader.readString()); + msg.addInclude(value); + break; + case 26: + var value = /** @type {string} */ (reader.readString()); + msg.addExclude(value); + break; + case 25: + var value = /** @type {string} */ (reader.readString()); + msg.setPackage(value); + break; + case 27: + var value = /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (reader.readEnum()); + msg.setTypeOverride(value); + break; + case 28: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setSortByTag(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.NanoPBOptions.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.NanoPBOptions.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.NanoPBOptions} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.NanoPBOptions.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = /** @type {number} */ (jspb.Message.getField(message, 1)); + if (f != null) { + writer.writeInt32( + 1, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 14)); + if (f != null) { + writer.writeInt32( + 14, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 2)); + if (f != null) { + writer.writeInt32( + 2, + f + ); + } + f = /** @type {!proto.IntSize} */ (jspb.Message.getField(message, 7)); + if (f != null) { + writer.writeEnum( + 7, + f + ); + } + f = /** @type {!proto.FieldType} */ (jspb.Message.getField(message, 3)); + if (f != null) { + writer.writeEnum( + 3, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 4)); + if (f != null) { + writer.writeBool( + 4, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 5)); + if (f != null) { + writer.writeBool( + 5, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 10)); + if (f != null) { + writer.writeBool( + 10, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 6)); + if (f != null) { + writer.writeBool( + 6, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 8)); + if (f != null) { + writer.writeBool( + 8, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 9)); + if (f != null) { + writer.writeUint32( + 9, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 11)); + if (f != null) { + writer.writeBool( + 11, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 12)); + if (f != null) { + writer.writeBool( + 12, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 21)); + if (f != null) { + writer.writeBool( + 21, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 13)); + if (f != null) { + writer.writeBool( + 13, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 15)); + if (f != null) { + writer.writeBool( + 15, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 16)); + if (f != null) { + writer.writeBool( + 16, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 22)); + if (f != null) { + writer.writeBool( + 22, + f + ); + } + f = /** @type {!proto.TypenameMangling} */ (jspb.Message.getField(message, 17)); + if (f != null) { + writer.writeEnum( + 17, + f + ); + } + f = /** @type {string} */ (jspb.Message.getField(message, 18)); + if (f != null) { + writer.writeString( + 18, + f + ); + } + f = /** @type {string} */ (jspb.Message.getField(message, 19)); + if (f != null) { + writer.writeString( + 19, + f + ); + } + f = /** @type {!proto.DescriptorSize} */ (jspb.Message.getField(message, 20)); + if (f != null) { + writer.writeEnum( + 20, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 23)); + if (f != null) { + writer.writeBool( + 23, + f + ); + } + f = message.getIncludeList(); + if (f.length > 0) { + writer.writeRepeatedString( + 24, + f + ); + } + f = message.getExcludeList(); + if (f.length > 0) { + writer.writeRepeatedString( + 26, + f + ); + } + f = /** @type {string} */ (jspb.Message.getField(message, 25)); + if (f != null) { + writer.writeString( + 25, + f + ); + } + f = /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (jspb.Message.getField(message, 27)); + if (f != null) { + writer.writeEnum( + 27, + f + ); + } + f = /** @type {boolean} */ (jspb.Message.getField(message, 28)); + if (f != null) { + writer.writeBool( + 28, + f + ); + } +}; + + +/** + * optional int32 max_size = 1; + * @return {number} + */ +proto.NanoPBOptions.prototype.getMaxSize = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setMaxSize = function(value) { + return jspb.Message.setField(this, 1, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearMaxSize = function() { + return jspb.Message.setField(this, 1, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasMaxSize = function() { + return jspb.Message.getField(this, 1) != null; +}; + + +/** + * optional int32 max_length = 14; + * @return {number} + */ +proto.NanoPBOptions.prototype.getMaxLength = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 14, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setMaxLength = function(value) { + return jspb.Message.setField(this, 14, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearMaxLength = function() { + return jspb.Message.setField(this, 14, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasMaxLength = function() { + return jspb.Message.getField(this, 14) != null; +}; + + +/** + * optional int32 max_count = 2; + * @return {number} + */ +proto.NanoPBOptions.prototype.getMaxCount = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setMaxCount = function(value) { + return jspb.Message.setField(this, 2, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearMaxCount = function() { + return jspb.Message.setField(this, 2, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasMaxCount = function() { + return jspb.Message.getField(this, 2) != null; +}; + + +/** + * optional IntSize int_size = 7; + * @return {!proto.IntSize} + */ +proto.NanoPBOptions.prototype.getIntSize = function() { + return /** @type {!proto.IntSize} */ (jspb.Message.getFieldWithDefault(this, 7, 0)); +}; + + +/** + * @param {!proto.IntSize} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setIntSize = function(value) { + return jspb.Message.setField(this, 7, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearIntSize = function() { + return jspb.Message.setField(this, 7, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasIntSize = function() { + return jspb.Message.getField(this, 7) != null; +}; + + +/** + * optional FieldType type = 3; + * @return {!proto.FieldType} + */ +proto.NanoPBOptions.prototype.getType = function() { + return /** @type {!proto.FieldType} */ (jspb.Message.getFieldWithDefault(this, 3, 0)); +}; + + +/** + * @param {!proto.FieldType} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setType = function(value) { + return jspb.Message.setField(this, 3, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearType = function() { + return jspb.Message.setField(this, 3, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasType = function() { + return jspb.Message.getField(this, 3) != null; +}; + + +/** + * optional bool long_names = 4; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getLongNames = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 4, true)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setLongNames = function(value) { + return jspb.Message.setField(this, 4, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearLongNames = function() { + return jspb.Message.setField(this, 4, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasLongNames = function() { + return jspb.Message.getField(this, 4) != null; +}; + + +/** + * optional bool packed_struct = 5; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getPackedStruct = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setPackedStruct = function(value) { + return jspb.Message.setField(this, 5, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearPackedStruct = function() { + return jspb.Message.setField(this, 5, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasPackedStruct = function() { + return jspb.Message.getField(this, 5) != null; +}; + + +/** + * optional bool packed_enum = 10; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getPackedEnum = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 10, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setPackedEnum = function(value) { + return jspb.Message.setField(this, 10, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearPackedEnum = function() { + return jspb.Message.setField(this, 10, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasPackedEnum = function() { + return jspb.Message.getField(this, 10) != null; +}; + + +/** + * optional bool skip_message = 6; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getSkipMessage = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 6, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setSkipMessage = function(value) { + return jspb.Message.setField(this, 6, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearSkipMessage = function() { + return jspb.Message.setField(this, 6, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasSkipMessage = function() { + return jspb.Message.getField(this, 6) != null; +}; + + +/** + * optional bool no_unions = 8; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getNoUnions = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 8, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setNoUnions = function(value) { + return jspb.Message.setField(this, 8, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearNoUnions = function() { + return jspb.Message.setField(this, 8, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasNoUnions = function() { + return jspb.Message.getField(this, 8) != null; +}; + + +/** + * optional uint32 msgid = 9; + * @return {number} + */ +proto.NanoPBOptions.prototype.getMsgid = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 9, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setMsgid = function(value) { + return jspb.Message.setField(this, 9, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearMsgid = function() { + return jspb.Message.setField(this, 9, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasMsgid = function() { + return jspb.Message.getField(this, 9) != null; +}; + + +/** + * optional bool anonymous_oneof = 11; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getAnonymousOneof = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 11, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setAnonymousOneof = function(value) { + return jspb.Message.setField(this, 11, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearAnonymousOneof = function() { + return jspb.Message.setField(this, 11, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasAnonymousOneof = function() { + return jspb.Message.getField(this, 11) != null; +}; + + +/** + * optional bool proto3 = 12; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getProto3 = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 12, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setProto3 = function(value) { + return jspb.Message.setField(this, 12, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearProto3 = function() { + return jspb.Message.setField(this, 12, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasProto3 = function() { + return jspb.Message.getField(this, 12) != null; +}; + + +/** + * optional bool proto3_singular_msgs = 21; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getProto3SingularMsgs = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 21, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setProto3SingularMsgs = function(value) { + return jspb.Message.setField(this, 21, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearProto3SingularMsgs = function() { + return jspb.Message.setField(this, 21, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasProto3SingularMsgs = function() { + return jspb.Message.getField(this, 21) != null; +}; + + +/** + * optional bool enum_to_string = 13; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getEnumToString = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 13, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setEnumToString = function(value) { + return jspb.Message.setField(this, 13, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearEnumToString = function() { + return jspb.Message.setField(this, 13, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasEnumToString = function() { + return jspb.Message.getField(this, 13) != null; +}; + + +/** + * optional bool fixed_length = 15; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getFixedLength = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 15, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setFixedLength = function(value) { + return jspb.Message.setField(this, 15, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearFixedLength = function() { + return jspb.Message.setField(this, 15, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasFixedLength = function() { + return jspb.Message.getField(this, 15) != null; +}; + + +/** + * optional bool fixed_count = 16; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getFixedCount = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 16, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setFixedCount = function(value) { + return jspb.Message.setField(this, 16, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearFixedCount = function() { + return jspb.Message.setField(this, 16, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasFixedCount = function() { + return jspb.Message.getField(this, 16) != null; +}; + + +/** + * optional bool submsg_callback = 22; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getSubmsgCallback = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 22, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setSubmsgCallback = function(value) { + return jspb.Message.setField(this, 22, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearSubmsgCallback = function() { + return jspb.Message.setField(this, 22, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasSubmsgCallback = function() { + return jspb.Message.getField(this, 22) != null; +}; + + +/** + * optional TypenameMangling mangle_names = 17; + * @return {!proto.TypenameMangling} + */ +proto.NanoPBOptions.prototype.getMangleNames = function() { + return /** @type {!proto.TypenameMangling} */ (jspb.Message.getFieldWithDefault(this, 17, 0)); +}; + + +/** + * @param {!proto.TypenameMangling} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setMangleNames = function(value) { + return jspb.Message.setField(this, 17, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearMangleNames = function() { + return jspb.Message.setField(this, 17, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasMangleNames = function() { + return jspb.Message.getField(this, 17) != null; +}; + + +/** + * optional string callback_datatype = 18; + * @return {string} + */ +proto.NanoPBOptions.prototype.getCallbackDatatype = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 18, "pb_callback_t")); +}; + + +/** + * @param {string} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setCallbackDatatype = function(value) { + return jspb.Message.setField(this, 18, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearCallbackDatatype = function() { + return jspb.Message.setField(this, 18, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasCallbackDatatype = function() { + return jspb.Message.getField(this, 18) != null; +}; + + +/** + * optional string callback_function = 19; + * @return {string} + */ +proto.NanoPBOptions.prototype.getCallbackFunction = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 19, "pb_default_field_callback")); +}; + + +/** + * @param {string} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setCallbackFunction = function(value) { + return jspb.Message.setField(this, 19, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearCallbackFunction = function() { + return jspb.Message.setField(this, 19, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasCallbackFunction = function() { + return jspb.Message.getField(this, 19) != null; +}; + + +/** + * optional DescriptorSize descriptorsize = 20; + * @return {!proto.DescriptorSize} + */ +proto.NanoPBOptions.prototype.getDescriptorsize = function() { + return /** @type {!proto.DescriptorSize} */ (jspb.Message.getFieldWithDefault(this, 20, 0)); +}; + + +/** + * @param {!proto.DescriptorSize} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setDescriptorsize = function(value) { + return jspb.Message.setField(this, 20, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearDescriptorsize = function() { + return jspb.Message.setField(this, 20, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasDescriptorsize = function() { + return jspb.Message.getField(this, 20) != null; +}; + + +/** + * optional bool default_has = 23; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getDefaultHas = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 23, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setDefaultHas = function(value) { + return jspb.Message.setField(this, 23, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearDefaultHas = function() { + return jspb.Message.setField(this, 23, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasDefaultHas = function() { + return jspb.Message.getField(this, 23) != null; +}; + + +/** + * repeated string include = 24; + * @return {!Array} + */ +proto.NanoPBOptions.prototype.getIncludeList = function() { + return /** @type {!Array} */ (jspb.Message.getRepeatedField(this, 24)); +}; + + +/** + * @param {!Array} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setIncludeList = function(value) { + return jspb.Message.setField(this, 24, value || []); +}; + + +/** + * @param {string} value + * @param {number=} opt_index + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.addInclude = function(value, opt_index) { + return jspb.Message.addToRepeatedField(this, 24, value, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearIncludeList = function() { + return this.setIncludeList([]); +}; + + +/** + * repeated string exclude = 26; + * @return {!Array} + */ +proto.NanoPBOptions.prototype.getExcludeList = function() { + return /** @type {!Array} */ (jspb.Message.getRepeatedField(this, 26)); +}; + + +/** + * @param {!Array} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setExcludeList = function(value) { + return jspb.Message.setField(this, 26, value || []); +}; + + +/** + * @param {string} value + * @param {number=} opt_index + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.addExclude = function(value, opt_index) { + return jspb.Message.addToRepeatedField(this, 26, value, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearExcludeList = function() { + return this.setExcludeList([]); +}; + + +/** + * optional string package = 25; + * @return {string} + */ +proto.NanoPBOptions.prototype.getPackage = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 25, "")); +}; + + +/** + * @param {string} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setPackage = function(value) { + return jspb.Message.setField(this, 25, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearPackage = function() { + return jspb.Message.setField(this, 25, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasPackage = function() { + return jspb.Message.getField(this, 25) != null; +}; + + +/** + * optional google.protobuf.FieldDescriptorProto.Type type_override = 27; + * @return {!proto.google.protobuf.FieldDescriptorProto.Type} + */ +proto.NanoPBOptions.prototype.getTypeOverride = function() { + return /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (jspb.Message.getFieldWithDefault(this, 27, 1)); +}; + + +/** + * @param {!proto.google.protobuf.FieldDescriptorProto.Type} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setTypeOverride = function(value) { + return jspb.Message.setField(this, 27, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearTypeOverride = function() { + return jspb.Message.setField(this, 27, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasTypeOverride = function() { + return jspb.Message.getField(this, 27) != null; +}; + + +/** + * optional bool sort_by_tag = 28; + * @return {boolean} + */ +proto.NanoPBOptions.prototype.getSortByTag = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 28, true)); +}; + + +/** + * @param {boolean} value + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.setSortByTag = function(value) { + return jspb.Message.setField(this, 28, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.NanoPBOptions} returns this + */ +proto.NanoPBOptions.prototype.clearSortByTag = function() { + return jspb.Message.setField(this, 28, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.NanoPBOptions.prototype.hasSortByTag = function() { + return jspb.Message.getField(this, 28) != null; +}; + + +/** + * @enum {number} + */ +proto.FieldType = { + FT_DEFAULT: 0, + FT_CALLBACK: 1, + FT_POINTER: 4, + FT_STATIC: 2, + FT_IGNORE: 3, + FT_INLINE: 5 +}; + +/** + * @enum {number} + */ +proto.IntSize = { + IS_DEFAULT: 0, + IS_8: 8, + IS_16: 16, + IS_32: 32, + IS_64: 64 +}; + +/** + * @enum {number} + */ +proto.TypenameMangling = { + M_NONE: 0, + M_STRIP_PACKAGE: 1, + M_FLATTEN: 2, + M_PACKAGE_INITIALS: 3 +}; + +/** + * @enum {number} + */ +proto.DescriptorSize = { + DS_AUTO: 0, + DS_1: 1, + DS_2: 2, + DS_4: 4, + DS_8: 8 +}; + + +/** + * A tuple of {field number, class constructor} for the extension + * field named `nanopbFileopt`. + * @type {!jspb.ExtensionFieldInfo} + */ +proto.nanopbFileopt = new jspb.ExtensionFieldInfo( + 1010, + {nanopbFileopt: 0}, + proto.NanoPBOptions, + /** @type {?function((boolean|undefined),!jspb.Message=): !Object} */ ( + proto.NanoPBOptions.toObject), + 0); + +google_protobuf_descriptor_pb.FileOptions.extensionsBinary[1010] = new jspb.ExtensionFieldBinaryInfo( + proto.nanopbFileopt, + jspb.BinaryReader.prototype.readMessage, + jspb.BinaryWriter.prototype.writeMessage, + proto.NanoPBOptions.serializeBinaryToWriter, + proto.NanoPBOptions.deserializeBinaryFromReader, + false); +// This registers the extension field with the extended class, so that +// toObject() will function correctly. +google_protobuf_descriptor_pb.FileOptions.extensions[1010] = proto.nanopbFileopt; + + +/** + * A tuple of {field number, class constructor} for the extension + * field named `nanopbMsgopt`. + * @type {!jspb.ExtensionFieldInfo} + */ +proto.nanopbMsgopt = new jspb.ExtensionFieldInfo( + 1010, + {nanopbMsgopt: 0}, + proto.NanoPBOptions, + /** @type {?function((boolean|undefined),!jspb.Message=): !Object} */ ( + proto.NanoPBOptions.toObject), + 0); + +google_protobuf_descriptor_pb.MessageOptions.extensionsBinary[1010] = new jspb.ExtensionFieldBinaryInfo( + proto.nanopbMsgopt, + jspb.BinaryReader.prototype.readMessage, + jspb.BinaryWriter.prototype.writeMessage, + proto.NanoPBOptions.serializeBinaryToWriter, + proto.NanoPBOptions.deserializeBinaryFromReader, + false); +// This registers the extension field with the extended class, so that +// toObject() will function correctly. +google_protobuf_descriptor_pb.MessageOptions.extensions[1010] = proto.nanopbMsgopt; + + +/** + * A tuple of {field number, class constructor} for the extension + * field named `nanopbEnumopt`. + * @type {!jspb.ExtensionFieldInfo} + */ +proto.nanopbEnumopt = new jspb.ExtensionFieldInfo( + 1010, + {nanopbEnumopt: 0}, + proto.NanoPBOptions, + /** @type {?function((boolean|undefined),!jspb.Message=): !Object} */ ( + proto.NanoPBOptions.toObject), + 0); + +google_protobuf_descriptor_pb.EnumOptions.extensionsBinary[1010] = new jspb.ExtensionFieldBinaryInfo( + proto.nanopbEnumopt, + jspb.BinaryReader.prototype.readMessage, + jspb.BinaryWriter.prototype.writeMessage, + proto.NanoPBOptions.serializeBinaryToWriter, + proto.NanoPBOptions.deserializeBinaryFromReader, + false); +// This registers the extension field with the extended class, so that +// toObject() will function correctly. +google_protobuf_descriptor_pb.EnumOptions.extensions[1010] = proto.nanopbEnumopt; + + +/** + * A tuple of {field number, class constructor} for the extension + * field named `nanopb`. + * @type {!jspb.ExtensionFieldInfo} + */ +proto.nanopb = new jspb.ExtensionFieldInfo( + 1010, + {nanopb: 0}, + proto.NanoPBOptions, + /** @type {?function((boolean|undefined),!jspb.Message=): !Object} */ ( + proto.NanoPBOptions.toObject), + 0); + +google_protobuf_descriptor_pb.FieldOptions.extensionsBinary[1010] = new jspb.ExtensionFieldBinaryInfo( + proto.nanopb, + jspb.BinaryReader.prototype.readMessage, + jspb.BinaryWriter.prototype.writeMessage, + proto.NanoPBOptions.serializeBinaryToWriter, + proto.NanoPBOptions.deserializeBinaryFromReader, + false); +// This registers the extension field with the extended class, so that +// toObject() will function correctly. +google_protobuf_descriptor_pb.FieldOptions.extensions[1010] = proto.nanopb; + +goog.object.extend(exports, proto); diff --git a/components/wifi-manager/webapp/src/sass/main.scss b/components/wifi-manager/webapp/src/sass/main.scss index 66ab125c..d57cab05 100644 --- a/components/wifi-manager/webapp/src/sass/main.scss +++ b/components/wifi-manager/webapp/src/sass/main.scss @@ -1,5 +1,3 @@ - -@import "~bootswatch/dist/darkly/variables"; @import "utils/variables"; @import "~bootstrap/scss/bootstrap"; // @import "~bootstrap/scss/functions"; @@ -38,5 +36,4 @@ // // Utilities // @import "~bootstrap/scss/utilities/api"; -@import "~bootswatch/dist/darkly/bootswatch"; @import "utils/style"; \ No newline at end of file diff --git a/components/wifi-manager/webapp/tsconfig.json b/components/wifi-manager/webapp/tsconfig.json index e6a52186..13b201a5 100644 --- a/components/wifi-manager/webapp/tsconfig.json +++ b/components/wifi-manager/webapp/tsconfig.json @@ -1,9 +1,7 @@ { "compilerOptions": { "baseUrl": "./", - "paths": { - "@/*": [ "src/*"], - "@node_modules/*" : ["./node_modules/*"]}, + "outDir": "./dist/", "noImplicitAny": true, "target": "es6", @@ -11,11 +9,15 @@ "composite": true, // "jsx": "react", "allowJs": true, + // "checkJs": true, "allowSyntheticDefaultImports" : true, "esModuleInterop" : true }, + "include": [ + "src/**/*" // Adjust the path to include your source files + ], "exclude": [ - "./node_modules" + "node_modules" ] } diff --git a/components/wifi-manager/webapp/webapp.cmake b/components/wifi-manager/webapp/webapp.cmake deleted file mode 100644 index 6a94730f..00000000 --- a/components/wifi-manager/webapp/webapp.cmake +++ /dev/null @@ -1,5 +0,0 @@ -target_add_binary_data( __idf_wifi-manager webapp/dist/css/index.1ab179394339385e0a02.css.gz BINARY) -target_add_binary_data( __idf_wifi-manager webapp/dist/favicon-32x32.png BINARY) -target_add_binary_data( __idf_wifi-manager webapp/dist/index.html.gz BINARY) -target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.1b8c7b.bundle.js.gz BINARY) -target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.1b8c7b.bundle.js.gz BINARY) diff --git a/components/wifi-manager/webapp/webpack.c b/components/wifi-manager/webapp/webpack.c deleted file mode 100644 index 13649f42..00000000 --- a/components/wifi-manager/webapp/webpack.c +++ /dev/null @@ -1,34 +0,0 @@ -// Automatically generated. Do not edit manually!. -#include -extern const uint8_t _index_1ab179394339385e0a02_css_gz_start[] asm("_binary_index_1ab179394339385e0a02_css_gz_start"); -extern const uint8_t _index_1ab179394339385e0a02_css_gz_end[] asm("_binary_index_1ab179394339385e0a02_css_gz_end"); -extern const uint8_t _favicon_32x32_png_start[] asm("_binary_favicon_32x32_png_start"); -extern const uint8_t _favicon_32x32_png_end[] asm("_binary_favicon_32x32_png_end"); -extern const uint8_t _index_html_gz_start[] asm("_binary_index_html_gz_start"); -extern const uint8_t _index_html_gz_end[] asm("_binary_index_html_gz_end"); -extern const uint8_t _index_1b8c7b_bundle_js_gz_start[] asm("_binary_index_1b8c7b_bundle_js_gz_start"); -extern const uint8_t _index_1b8c7b_bundle_js_gz_end[] asm("_binary_index_1b8c7b_bundle_js_gz_end"); -extern const uint8_t _node_vendors_1b8c7b_bundle_js_gz_start[] asm("_binary_node_vendors_1b8c7b_bundle_js_gz_start"); -extern const uint8_t _node_vendors_1b8c7b_bundle_js_gz_end[] asm("_binary_node_vendors_1b8c7b_bundle_js_gz_end"); -const char * resource_lookups[] = { - "/css/index.1ab179394339385e0a02.css.gz", - "/favicon-32x32.png", - "/index.html.gz", - "/js/index.1b8c7b.bundle.js.gz", - "/js/node_vendors.1b8c7b.bundle.js.gz", -"" -}; -const uint8_t * resource_map_start[] = { - _index_1ab179394339385e0a02_css_gz_start, - _favicon_32x32_png_start, - _index_html_gz_start, - _index_1b8c7b_bundle_js_gz_start, - _node_vendors_1b8c7b_bundle_js_gz_start -}; -const uint8_t * resource_map_end[] = { - _index_1ab179394339385e0a02_css_gz_end, - _favicon_32x32_png_end, - _index_html_gz_end, - _index_1b8c7b_bundle_js_gz_end, - _node_vendors_1b8c7b_bundle_js_gz_end -}; diff --git a/components/wifi-manager/webapp/webpack.config.js b/components/wifi-manager/webapp/webpack.config.js index b5d212fe..981c1bb1 100644 --- a/components/wifi-manager/webapp/webpack.config.js +++ b/components/wifi-manager/webapp/webpack.config.js @@ -10,15 +10,19 @@ const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin"); const webpack = require("webpack"); const path = require("path"); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; - const globSync = require("glob").sync; const glob = require('glob'); const { merge } = require('webpack-merge'); const devserver = require('./webpack/webpack.dev.js'); -const fs = require('fs'); -const zlib = require("zlib"); + const PurgeCSSPlugin = require('purgecss-webpack-plugin') const whitelister = require('purgecss-whitelister'); +const GrpcToolsNodeProtocPlugin = require('./webpack/GrpcToolsNodeProtocPlugin.js'); +const buildRootPath = path.join(process.cwd(), '..', '..', '..'); +const wifiManagerPath = glob.sync(path.join(buildRootPath, 'components/**/wifi-manager*'))[0]; +const ComponentsPath = glob.sync(path.join(buildRootPath, 'components/'))[0]; +const buildCRootPath = glob.sync(buildRootPath)[0]; +const SPIFFSPath = glob.sync(path.join(buildRootPath, 'SPIFFS'))[0]; const PATHS = { @@ -39,22 +43,24 @@ class BuildEventsHook { module.exports = (env, options) => ( merge( - env.WEBPACK_SERVE ? devserver : {}, - env.ANALYZE_SIZE?{ plugins: [ new BundleAnalyzerPlugin( - { - analyzerMode: 'static', - generateStatsFile: true, - statsFilename: 'stats.json', - } - ) ]}:{}, + env.WEBPACK_SERVE ? devserver : {}, + env.ANALYZE_SIZE ? { + plugins: [new BundleAnalyzerPlugin( + { + analyzerMode: 'static', + generateStatsFile: true, + statsFilename: 'stats.json', + } + )] + } : {}, - + // { stats: 'verbose', }, { - entry: + entry: { - index: './src/index.ts' + index: './src/index.ts' }, - devtool:"source-map", + devtool: "source-map", module: { rules: [ { @@ -62,10 +68,10 @@ module.exports = (env, options) => ( loader: 'ejs-loader', options: { variable: 'data', - interpolate : '\\{\\{(.+?)\\}\\}', - evaluate : '\\[\\[(.+?)\\]\\]' + interpolate: '\\{\\{(.+?)\\}\\}', + evaluate: '\\[\\[(.+?)\\]\\]' } - }, + }, { test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/, use: [ @@ -77,10 +83,10 @@ module.exports = (env, options) => ( } } ] - }, + }, // { // test: /\.s[ac]ss$/i, - + // use: [{ // loader: 'style-loader', // inject CSS to page // }, @@ -105,42 +111,42 @@ module.exports = (env, options) => ( { test: /\.(scss)$/, use: [ - + { loader: MiniCssExtractPlugin.loader, options: { publicPath: "../", }, }, - // { - // // inject CSS to page - // loader: 'style-loader' - // }, - { - // translates CSS into CommonJS modules - loader: 'css-loader' - }, - - { - // Run postcss actions - loader: 'postcss-loader', - options: { - // `postcssOptions` is needed for postcss 8.x; - // if you use postcss 7.x skip the key - postcssOptions: { - // postcss plugins, can be exported to postcss.config.js - plugins: function () { - return [ - require('autoprefixer') - ]; + // { + // // inject CSS to page + // loader: 'style-loader' + // }, + { + // translates CSS into CommonJS modules + loader: 'css-loader' + }, + + { + // Run postcss actions + loader: 'postcss-loader', + options: { + // `postcssOptions` is needed for postcss 8.x; + // if you use postcss 7.x skip the key + postcssOptions: { + // postcss plugins, can be exported to postcss.config.js + plugins: function () { + return [ + require('autoprefixer') + ]; + } } } - } - }, { - // compiles Sass to CSS - loader: 'sass-loader' - }] - }, + }, { + // compiles Sass to CSS + loader: 'sass-loader' + }] + }, { test: /\.js$/, exclude: /(node_modules|bower_components)/, @@ -156,62 +162,70 @@ module.exports = (env, options) => ( { test: /\.(jpe?g|png|gif|svg)$/i, type: "asset", - }, + }, // { // test: /\.html$/i, // type: "asset/resource", // }, - { - test: /\.html$/i, - loader: "html-loader", - options: { - minimize: true, - - } - }, + { + test: /\.html$/i, + loader: "html-loader", + options: { + minimize: true, + + } + }, { test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/, - }, - - + } + + ], }, plugins: [ + new GrpcToolsNodeProtocPlugin({ + protoPaths: [`${path.join(ComponentsPath, 'spotify/cspot/bell/external/nanopb/generator/proto')}`, + `${path.join(buildCRootPath, 'protobuf')}`], + protoSources: [`${path.join(buildCRootPath, 'protobuf/*.proto')}`, + `${path.join(ComponentsPath, 'spotify/cspot/bell/external/nanopb/generator/proto/*.proto')}`], + outputDir: './src/js/proto' + } + ), new HtmlWebpackPlugin({ title: 'SqueezeESP32', template: './src/index.ejs', filename: 'index.html', inject: 'body', minify: { - html5 : true, - collapseWhitespace : true, - minifyCSS : true, - minifyJS : true, - minifyURLs : false, - removeAttributeQuotes : true, - removeComments : true, // false for Vue SSR to find app placeholder - removeEmptyAttributes : true, - removeOptionalTags : true, - removeRedundantAttributes : true, - removeScriptTypeAttributes : true, - removeStyleLinkTypeAttributese : true, - useShortDoctype : true + html5: true, + collapseWhitespace: true, + minifyCSS: true, + minifyJS: true, + minifyURLs: false, + removeAttributeQuotes: true, + removeComments: true, // false for Vue SSR to find app placeholder + removeEmptyAttributes: true, + removeOptionalTags: true, + removeRedundantAttributes: true, + removeScriptTypeAttributes: true, + removeStyleLinkTypeAttributese: true, + useShortDoctype: true }, favicon: "./src/assets/images/favicon-32x32.png", excludeChunks: ['test'], - }), - // new CompressionPlugin({ - // test: /\.(js|css|html|svg)$/, - // //filename: '[path].br[query]', - // filename: "[path][base].br", - // algorithm: 'brotliCompress', - // compressionOptions: { level: 11 }, - // threshold: 100, - // minRatio: 0.8, - // deleteOriginalAssets: false - // }), + }), + // new CompressionPlugin({ + // test: /\.(js|css|html|svg)$/, + // //filename: '[path].br[query]', + // filename: "[path][base].br", + // algorithm: 'brotliCompress', + // compressionOptions: { level: 11 }, + // threshold: 100, + // minRatio: 0.8, + // deleteOriginalAssets: false + // }), new MiniCssExtractPlugin({ filename: "css/[name].[contenthash].css", }), @@ -220,13 +234,14 @@ module.exports = (env, options) => ( paths: glob.sync(`${path.join(__dirname, 'src')}/**/*`, { nodir: true }), + whitelist: whitelister('bootstrap/dist/css/bootstrap.css') }), new webpack.ProvidePlugin({ $: "jquery", -// jQuery: "jquery", - // "window.jQuery": "jquery", - // Popper: ["popper.js", "default"], + // jQuery: "jquery", + // "window.jQuery": "jquery", + // Popper: ["popper.js", "default"], // Util: "exports-loader?Util!bootstrap/js/dist/util", // Dropdown: "exports-loader?Dropdown!bootstrap/js/dist/dropdown", }), @@ -236,117 +251,26 @@ module.exports = (env, options) => ( filename: "[path][base].gz", algorithm: 'gzip', - + threshold: 100, minRatio: 0.8, - }), - - new BuildEventsHook('Update C App', - function (stats, arguments) { + }), - if (options.mode !== "production") return; - let buildRootPath = path.join(process.cwd(),'..','..','..'); - let wifiManagerPath=glob.sync(path.join(buildRootPath,'components/**/wifi-manager*'))[0]; - let buildCRootPath=glob.sync(buildRootPath)[0]; - fs.appendFileSync('./dist/index.html.gz', - zlib.gzipSync(fs.readFileSync('./dist/index.html'), - { - chunckSize: 65536, - level: zlib.constants.Z_BEST_COMPRESSION - })); - - var getDirectories = function (src, callback) { - var searchPath = path.posix.join(src, '/**/*(*.gz|favicon-32x32.png)'); - console.log(`Post build: Getting file list from ${searchPath}`); - glob(searchPath, callback); - }; - var cleanUpPath = path.posix.join(buildCRootPath, '/build/*.S'); - console.log(`Post build: Cleaning up previous builds in ${cleanUpPath}`); - glob(cleanUpPath, function (err, list) { - if (err) { - console.error('Error', err); - } else { - list.forEach(fileName => { - try { - console.log(`Post build: Purging old binary file ${fileName} from C project.`); - fs.unlinkSync(fileName) - //file removed - } catch (ferr) { - console.error(ferr) - } - }); - } - }, - 'afterEmit' - ); - console.log('Generating C include files from webpack build output'); - getDirectories('./dist', function (err, list) { - console.log(`Post build: found ${list.length} files. Relative path: ${wifiManagerPath}.`); - if (err) { - console.log('Error', err); - } else { - - let exportDefHead = -`/*********************************** -webpack_headers -${arguments[1]} -***********************************/ -#pragma once -#include -extern const char * resource_lookups[]; -extern const uint8_t * resource_map_start[]; -extern const uint8_t * resource_map_end[];`; - let exportDef = '// Automatically generated. Do not edit manually!.\n' + - '#include \n'; - let lookupDef = 'const char * resource_lookups[] = {\n'; - let lookupMapStart = 'const uint8_t * resource_map_start[] = {\n'; - let lookupMapEnd = 'const uint8_t * resource_map_end[] = {\n'; - let cMake=''; - - list.forEach(foundFile => { - let exportName = path.basename(foundFile).replace(/[\. \-]/gm, '_'); - //take the full path of the file and make it relative to the build directory - let cmakeFileName = path.posix.relative(wifiManagerPath,glob.sync(path.resolve(foundFile))[0]); - let httpRelativePath=path.posix.join('/',path.posix.relative('dist',foundFile)); - exportDef += `extern const uint8_t _${exportName}_start[] asm("_binary_${exportName}_start");\nextern const uint8_t _${exportName}_end[] asm("_binary_${exportName}_end");\n`; - lookupDef += `\t"${httpRelativePath}",\n`; - lookupMapStart += '\t_' + exportName + '_start,\n'; - lookupMapEnd += '\t_' + exportName + '_end,\n'; - cMake += `target_add_binary_data( __idf_wifi-manager ${cmakeFileName} BINARY)\n`; - console.log(`Post build: adding cmake file reference to ${cmakeFileName} from C project, with web path ${httpRelativePath}.`); - }); - - lookupDef += '""\n};\n'; - lookupMapStart = lookupMapStart.substring(0, lookupMapStart.length - 2) + '\n};\n'; - lookupMapEnd = lookupMapEnd.substring(0, lookupMapEnd.length - 2) + '\n};\n'; - try { - fs.writeFileSync('webapp.cmake', cMake); - fs.writeFileSync('webpack.c', exportDef + lookupDef + lookupMapStart + lookupMapEnd); - fs.writeFileSync('webpack.h', exportDefHead); - //file written successfully - } catch (e) { - console.error(e); - } - } - }); - console.log('Post build completed.'); - - }) ], optimization: { minimize: true, providedExports: true, usedExports: true, minimizer: [ - + new TerserPlugin({ terserOptions: { format: { - comments: false, + comments: false, }, }, extractComments: false, - // enable parallel running + // enable parallel running parallel: true, }), new HtmlMinimizerPlugin({ @@ -373,40 +297,40 @@ extern const uint8_t * resource_map_end[];`; "svgo", { plugins: [ - { + { name: 'preset-default', - params: { - overrides: { - // customize default plugin options - inlineStyles: { - onlyMatchedOnce: false, + params: { + overrides: { + // customize default plugin options + inlineStyles: { + onlyMatchedOnce: false, + }, + + // or disable plugins + removeDoctype: false, }, - - // or disable plugins - removeDoctype: false, }, - }, - } + } ], }, ], ], }, }, - }), - + }), + ], splitChunks: { cacheGroups: { - vendor: { - name: "node_vendors", - test: /[\\/]node_modules[\\/]/, - chunks: "all", - } + vendor: { + name: "node_vendors", + test: /[\\/]node_modules[\\/]/, + chunks: "all", + } } - } - + } + }, // output: { // filename: "[name].js", @@ -414,11 +338,11 @@ extern const uint8_t * resource_map_end[];`; // publicPath: "", // }, resolve: { - extensions: ['.tsx', '.ts', '.js', '.ejs' ], + extensions: ['.tsx', '.ts', '.js', '.ejs'], }, output: { path: path.resolve(__dirname, 'dist'), - filename: './js/[name].[fullhash:6].bundle.js', + filename: './js/[name].[hash:6].bundle.js', clean: true }, } diff --git a/components/wifi-manager/webapp/webpack.h b/components/wifi-manager/webapp/webpack.h deleted file mode 100644 index f10df481..00000000 --- a/components/wifi-manager/webapp/webpack.h +++ /dev/null @@ -1,9 +0,0 @@ -/*********************************** -webpack_headers -dist/css/index.1ab179394339385e0a02.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.1b8c7b.bundle.js.gz,dist/js/node_vendors.1b8c7b.bundle.js.gz -***********************************/ -#pragma once -#include -extern const char * resource_lookups[]; -extern const uint8_t * resource_map_start[]; -extern const uint8_t * resource_map_end[]; \ No newline at end of file diff --git a/components/wifi-manager/webapp/webpack/GrpcToolsNodeProtocPlugin.js b/components/wifi-manager/webapp/webpack/GrpcToolsNodeProtocPlugin.js new file mode 100644 index 00000000..1dc6ac24 --- /dev/null +++ b/components/wifi-manager/webapp/webpack/GrpcToolsNodeProtocPlugin.js @@ -0,0 +1,59 @@ +"use strict"; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +var grpcTools = require('grpc-tools'); +var execSync = require('child_process').execSync; +var path = require('path'); +var fs = require('fs'); +var glob = require('glob'); +function clearOutputDirectory(directory) { + if (fs.existsSync(directory)) { + var files = fs.readdirSync(directory); + for (var _i = 0, files_1 = files; _i < files_1.length; _i++) { + var file = files_1[_i]; + var filePath = path.join(directory, file); + fs.unlinkSync(filePath); + } + } +} +var GrpcToolsNodeProtocPlugin = /** @class */ (function () { + function GrpcToolsNodeProtocPlugin(options) { + this.protoPaths = options.protoPaths || []; // Array of proto_path directories + this.protoSources = options.protoSources || []; // Array of proto source files or directories + this.outputDir = options.outputDir || './'; // Output directory + } + GrpcToolsNodeProtocPlugin.prototype.apply = function (compiler) { + var _this = this; + compiler.hooks.environment.tap('GrpcToolsNodeProtocPlugin', function () { + try { + console.log("Cleaning existing files, if any"); + clearOutputDirectory(_this.outputDir); + console.log("Writing protocol buffer files into ".concat(_this.outputDir)); + // Resolve proto_path directories + var resolvedProtoPaths = _this.protoPaths.map(function (p) { return path.resolve(__dirname, p); }); + var resolvedProtoSources = []; + _this.protoSources.forEach(function (s) { + var matches = glob.sync(path.resolve(__dirname, s)); + resolvedProtoSources = resolvedProtoSources.concat(matches); + }); + var protocArgs = __spreadArray(__spreadArray([ + "--js_out=import_style=commonjs,binary:".concat(_this.outputDir) + ], resolvedProtoPaths.map(function (p) { return "--proto_path=".concat(p); }), true), resolvedProtoSources, true); + var command = "npx grpc_tools_node_protoc ".concat(protocArgs.join(' ')); + execSync(command, { stdio: 'inherit' }); + } + catch (error) { + console.error('Error running grpc tools', error); + } + }); + }; + return GrpcToolsNodeProtocPlugin; +}()); +module.exports = GrpcToolsNodeProtocPlugin; diff --git a/components/wifi-manager/webapp/webpack/GrpcToolsNodeProtocPlugin.ts b/components/wifi-manager/webapp/webpack/GrpcToolsNodeProtocPlugin.ts new file mode 100644 index 00000000..8d48658b --- /dev/null +++ b/components/wifi-manager/webapp/webpack/GrpcToolsNodeProtocPlugin.ts @@ -0,0 +1,70 @@ +import { Compiler } from 'webpack'; +const grpcTools = require('grpc-tools'); +const { execSync } = require('child_process'); +const path = require('path'); +const fs = require('fs'); +const glob = require('glob'); + +function clearOutputDirectory(directory:string) { + if (fs.existsSync(directory)) { + const files = fs.readdirSync(directory); + for (const file of files) { + const filePath = path.join(directory, file); + fs.unlinkSync(filePath); + } + } +} +export = GrpcToolsNodeProtocPlugin; +// Define the interface for the plugin options +interface GrpcToolsNodeProtocPluginOptions { + protoPaths?: string[]; + protoSources?: string[]; + outputDir?: string; + } + + class GrpcToolsNodeProtocPlugin { + private protoPaths: string[]; + private protoSources: string[]; + private outputDir: string; + + constructor(options: GrpcToolsNodeProtocPluginOptions) { + this.protoPaths = options.protoPaths || []; // Array of proto_path directories + this.protoSources = options.protoSources || []; // Array of proto source files or directories + this.outputDir = options.outputDir || './'; // Output directory + } + + apply(compiler:Compiler) { + compiler.hooks.environment.tap('GrpcToolsNodeProtocPlugin', () => { + try { + console.log(`Cleaning existing files, if any`) + clearOutputDirectory(this.outputDir); + console.log(`Writing protocol buffer files into ${this.outputDir}`) + + // Resolve proto_path directories + const resolvedProtoPaths = this.protoPaths.map(p => path.resolve(__dirname, p)); + + var resolvedProtoSources:string[] = []; + this.protoSources.forEach(function (s) { + var matches = glob.sync(path.resolve(__dirname, s)); + resolvedProtoSources = resolvedProtoSources.concat(matches); + }); + + + + const protocArgs = [ + `--js_out=import_style=commonjs,binary:${this.outputDir}`, + // `--grpc_out=generate_package_definition:${this.outputDir}`, + ...resolvedProtoPaths.map(p => `--proto_path=${p}`), + ...resolvedProtoSources + ]; + + const command = `npx grpc_tools_node_protoc ${protocArgs.join(' ')}`; + execSync(command, { stdio: 'inherit' }); + + } catch (error) { + console.error('Error running grpc tools', error); + } + }); + } +} + diff --git a/components/wifi-manager/webapp/webpack/SPIFFSUpdate.ts b/components/wifi-manager/webapp/webpack/SPIFFSUpdate.ts new file mode 100644 index 00000000..18455050 --- /dev/null +++ b/components/wifi-manager/webapp/webpack/SPIFFSUpdate.ts @@ -0,0 +1,143 @@ +import { Compiler } from 'webpack'; +const path = require('path'); +const fs = require('fs'); +const zlib = require("zlib"); + +export = SPIFFSUpdate; +// Define the interface for the plugin options +interface SPIFFSUpdateOptions { + sourceFiles?: string[]; + targetFiles?: string[]; + compress?: boolean; +} + +class SPIFFSUpdate { + private sourceFiles: string[]; + private targetFiles: string[]; + private compress: boolean; + + constructor(options: SPIFFSUpdateOptions) { + this.sourceFiles = options.sourceFiles || []; // Array of proto_path directories + this.targetFiles = options.targetFiles || []; // Array of proto source files or directories + this.compress = options.compress || true; // Output directory + } + + apply(compiler: Compiler) { + compiler.hooks.afterEmit.tapAsync('GrpcToolsNodeProtocPlugin', (compilation, callback) => { + try { + + fs.appendFileSync('./dist/index.html.gz', + zlib.gzipSync(fs.readFileSync('./dist/index.html'), + { + chunckSize: 65536, + level: zlib.constants.Z_BEST_COMPRESSION + }) + ); + + + // if (options.mode !== "production") return; + // let buildRootPath = path.join(process.cwd(), '..', '..', '..'); + // let wifiManagerPath = glob.sync(path.join(buildRootPath, 'components/**/wifi-manager*'))[0]; + // let buildCRootPath = glob.sync(buildRootPath)[0]; + // fs.appendFileSync('./dist/index.html.gz', + // zlib.gzipSync(fs.readFileSync('./dist/index.html'), + // { + // chunckSize: 65536, + // level: zlib.constants.Z_BEST_COMPRESSION + // })); + + // var getDirectories = function (src, callback) { + // var searchPath = path.posix.join(src, '/**/*(*.gz|favicon-32x32.png)'); + // console.log(`Post build: Getting file list from ${searchPath}`); + // glob(searchPath, callback); + // }; + // var cleanUpPath = path.posix.join(buildCRootPath, '/build/*.S'); + // console.log(`Post build: Cleaning up previous builds in ${cleanUpPath}`); + // glob(cleanUpPath, function (err, list) { + // if (err) { + // console.error('Error', err); + // } else { + // list.forEach(fileName => { + // try { + // console.log(`Post build: Purging old binary file ${fileName} from C project.`); + // fs.unlinkSync(fileName) + // //file removed + // } catch (ferr) { + // console.error(ferr) + // } + // }); + // } + // }, + // 'afterEmit' + // ); + // console.log('Generating C include files from webpack build output'); + // getDirectories('./dist', function (err, list) { + // console.log(`Post build: found ${list.length} files. Relative path: ${wifiManagerPath}.`); + // if (err) { + // console.log('Error', err); + // } else { + + // let exportDefHead = + // `/*********************************** + // webpack_headers + // ${arguments[1]} + // ***********************************/ + // #pragma once + // #include + // extern const char * resource_lookups[]; + // extern const uint8_t * resource_map_start[]; + // extern const uint8_t * resource_map_end[];`; + // let exportDef = '// Automatically generated. Do not edit manually!.\n' + + // '#include \n'; + // let lookupDef = 'const char * resource_lookups[] = {\n'; + // let lookupMapStart = 'const uint8_t * resource_map_start[] = {\n'; + // let lookupMapEnd = 'const uint8_t * resource_map_end[] = {\n'; + // let cMake = ''; + + // list.forEach(foundFile => { + // let exportName = path.basename(foundFile).replace(/[\. \-]/gm, '_'); + // //take the full path of the file and make it relative to the build directory + // let cmakeFileName = path.posix.relative(wifiManagerPath, glob.sync(path.resolve(foundFile))[0]); + // let httpRelativePath = path.posix.join('/', path.posix.relative('dist', foundFile)); + // exportDef += `extern const uint8_t _${exportName}_start[] asm("_binary_${exportName}_start");\nextern const uint8_t _${exportName}_end[] asm("_binary_${exportName}_end");\n`; + // lookupDef += `\t"${httpRelativePath}",\n`; + // lookupMapStart += '\t_' + exportName + '_start,\n'; + // lookupMapEnd += '\t_' + exportName + '_end,\n'; + // cMake += `target_add_binary_data( __idf_wifi-manager ${cmakeFileName} BINARY)\n`; + // console.log(`Post build: adding cmake file reference to ${cmakeFileName} from C project, with web path ${httpRelativePath}.`); + // }); + + // lookupDef += '""\n};\n'; + // lookupMapStart = lookupMapStart.substring(0, lookupMapStart.length - 2) + '\n};\n'; + // lookupMapEnd = lookupMapEnd.substring(0, lookupMapEnd.length - 2) + '\n};\n'; + // try { + // fs.writeFileSync('webapp.cmake', cMake); + // fs.writeFileSync('webpack.c', exportDef + lookupDef + lookupMapStart + lookupMapEnd); + // fs.writeFileSync('webpack.h', exportDefHead); + // //file written successfully + // } catch (e) { + // console.error(e); + // } + // } + // }); + // console.log('Post build completed.'); + + // }) + + + + + + + + + + + } catch (error) { + console.error('Error setting up grpc-tools protoc', error); + } + callback(); + }); + } +} + diff --git a/components/wifi-manager/wifi_manager_http_server.c b/components/wifi-manager/wifi_manager_http_server.c index a667676f..af869c61 100644 --- a/components/wifi-manager/wifi_manager_http_server.c +++ b/components/wifi-manager/wifi_manager_http_server.c @@ -60,9 +60,6 @@ void register_common_handlers(httpd_handle_t server){ void register_regular_handlers(httpd_handle_t server){ httpd_uri_t root_get = { .uri = "/", .method = HTTP_GET, .handler = root_get_handler, .user_ctx = rest_context }; httpd_register_uri_handler(server, &root_get); - - httpd_uri_t ap_get = { .uri = "/ap.json", .method = HTTP_GET, .handler = ap_get_handler, .user_ctx = rest_context }; - httpd_register_uri_handler(server, &ap_get); httpd_uri_t scan_get = { .uri = "/scan.json", .method = HTTP_GET, .handler = ap_scan_handler, .user_ctx = rest_context }; httpd_register_uri_handler(server, &scan_get); httpd_uri_t config_get = { .uri = "/config.json", .method = HTTP_GET, .handler = config_get_handler, .user_ctx = rest_context }; @@ -123,7 +120,11 @@ void register_regular_handlers(httpd_handle_t server){ httpd_uri_t connect_redirect_8 = { .uri = "/success.txt", .method = HTTP_GET, .handler = redirect_ev_handler, .user_ctx = rest_context }; // OSX httpd_register_uri_handler(server, &connect_redirect_8); - + httpd_uri_t configurator_post = { .uri = "/config.pro", .method = HTTP_POST, .handler = configurator_post_handler, .user_ctx = rest_context }; + httpd_register_uri_handler(server, &configurator_post); + httpd_uri_t configurator_get = { .uri = "/config.pro", .method = HTTP_POST, .handler = configurator_get_handler, .user_ctx = rest_context }; + httpd_register_uri_handler(server, &configurator_get); + ESP_LOGD(TAG,"Registering default error handler for 404"); httpd_register_err_handler(server, HTTPD_404_NOT_FOUND,&err_handler); diff --git a/esp-idf-vscode-generated.gdb b/esp-idf-vscode-generated.gdb new file mode 100644 index 00000000..14b7964c --- /dev/null +++ b/esp-idf-vscode-generated.gdb @@ -0,0 +1,7 @@ +set remote hardware-watchpoint-limit 2 +target remote :3333 +symbol-file C:\Users\sle11\Documents\VSCode\squeezelite-esp32/build/recovery.elf +mon reset halt +flushregs +thb app_main +c \ No newline at end of file diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 626892b4..b7c081df 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRC_DIRS . - PRIV_REQUIRES _override esp_common wifi-manager pthread squeezelite-ota platform_console telnet display targets led_strip metrics + PRIV_REQUIRES _override esp_common wifi-manager pthread squeezelite-ota platform_console telnet display targets led_strip metrics platform_config LDFRAGMENTS "linker.lf" ) diff --git a/main/esp_app_main.c b/main/esp_app_main.c index 652bc5f3..6d07ef67 100644 --- a/main/esp_app_main.c +++ b/main/esp_app_main.c @@ -17,24 +17,21 @@ #include "driver/gpio.h" #include "driver/spi_master.h" #include "freertos/task.h" -#include "esp_system.h" #include "esp_spi_flash.h" #include "esp_wifi.h" #include -#include "nvs_flash.h" #include "esp_log.h" #include "freertos/event_groups.h" #include "mdns.h" #include "lwip/api.h" #include "lwip/err.h" #include "lwip/netdb.h" -#include "nvs_utilities.h" #include "trace.h" #include "network_manager.h" #include "squeezelite-ota.h" #include #include "audio_controls.h" -#include "platform_config.h" +#include "Configurator.h" #include "telnet.h" #include "messaging.h" #include "gds.h" @@ -61,7 +58,6 @@ const int CONNECTED_BIT = BIT0; #define LOCAL_MAC_SIZE 20 static const char TAG[] = "esp_app_main"; #define DEFAULT_HOST_NAME "squeezelite" -char * fwurl = NULL; RTC_NOINIT_ATTR uint32_t RebootCounter ; RTC_NOINIT_ATTR uint32_t RecoveryRebootCounter ; RTC_NOINIT_ATTR uint16_t ColdBootIndicatorFlag; @@ -71,68 +67,7 @@ bool cold_boot=true; extern const char _ctype_[]; const char* __ctype_ptr__ = _ctype_; #endif -typedef struct { - const char *key; - const char *value; -} DefaultStringVal; -typedef struct { - const char *key; - unsigned int uint_value; - bool is_signed; -} DefaultNumVal; -const DefaultNumVal defaultNumVals[] = { - {"ota_erase_blk", OTA_FLASH_ERASE_BLOCK, 0}, - {"ota_stack", OTA_STACK_SIZE, 0}, - {"ota_prio", OTA_TASK_PRIOTITY, 1} -}; -const DefaultStringVal defaultStringVals[] = { - {"equalizer", ""}, - {"loudness", "0"}, - {"actrls_config", ""}, - {"lms_ctrls_raw", "n"}, - {"rotary_config", CONFIG_ROTARY_ENCODER}, - {"display_config", CONFIG_DISPLAY_CONFIG}, - {"eth_config", CONFIG_ETH_CONFIG}, - {"i2c_config", CONFIG_I2C_CONFIG}, - {"spi_config", CONFIG_SPI_CONFIG}, - {"set_GPIO", CONFIG_SET_GPIO}, - {"sleep_config", ""}, - {"led_brightness", ""}, - {"spdif_config", ""}, - {"dac_config", ""}, - {"dac_controlset", ""}, - {"jack_mutes_amp", "n"}, - {"gpio_exp_config", CONFIG_GPIO_EXP_CONFIG}, - {"bat_config", ""}, - {"metadata_config", ""}, - {"telnet_enable", ""}, - {"telnet_buffer", "40000"}, - {"telnet_block", "500"}, - {"stats", "n"}, - {"rel_api", CONFIG_RELEASE_API}, - {"pollmx", "600"}, - {"pollmin", "15"}, - {"ethtmout", "8"}, - {"dhcp_tmout", "8"}, - {"target", CONFIG_TARGET}, - {"led_vu_config", ""}, -#ifdef CONFIG_BT_SINK - {"bt_sink_pin", STR(CONFIG_BT_SINK_PIN)}, - {"bt_sink_volume", "127"}, - // Note: register_default_with_mac("bt_name", CONFIG_BT_NAME); is a special case - {"enable_bt_sink", STR(CONFIG_BT_SINK)}, - {"a2dp_dev_name", CONFIG_A2DP_DEV_NAME}, - {"a2dp_ctmt", STR(CONFIG_A2DP_CONNECT_TIMEOUT_MS)}, - {"a2dp_ctrld", STR(CONFIG_A2DP_CONTROL_DELAY_MS)}, - {"a2dp_sink_name", CONFIG_A2DP_SINK_NAME}, - {"autoexec", "1"}, -#ifdef CONFIG_AIRPLAY_SINK - {"airplay_port", CONFIG_AIRPLAY_PORT}, - {"enable_airplay", STR(CONFIG_AIRPLAY_SINK)} -#endif -#endif -}; static bool bNetworkConnected=false; // as an exception _init function don't need include @@ -141,8 +76,10 @@ extern void services_sleep_init(void); extern void display_init(char *welcome); extern void led_vu_init(void); extern void target_init(char *target); +extern void start_squeezelite(); const char * str_or_unknown(const char * str) { return (str?str:unknown_string_placeholder); } const char * str_or_null(const char * str) { return (str?str:null_string_placeholder); } + bool is_recovery_running; bool is_network_connected(){ return bNetworkConnected; @@ -154,7 +91,7 @@ void cb_connection_got_ip(nm_state_t new_state, int sub_state){ network_get_ip_info(&ipInfo); if (ip.addr && ipInfo.ip.addr != ip.addr) { ESP_LOGW(TAG, "IP change, need to reboot"); - if(!wait_for_commit()){ + if(!configurator_waitcommit()){ ESP_LOGW(TAG,"Unable to commit configuration. "); } esp_restart(); @@ -203,17 +140,6 @@ bool wait_for_wifi(){ return connected; } -char * process_ota_url(){ - ESP_LOGI(TAG,"Checking for update url"); - char * fwurl=config_alloc_get(NVS_TYPE_STR, "fwurl"); - if(fwurl!=NULL) - { - ESP_LOGD(TAG,"Deleting nvs entry for Firmware URL %s", fwurl); - config_delete_key("fwurl"); - } - return fwurl; -} - esp_log_level_t get_log_level_from_char(char * level){ if(!strcasecmp(level, "NONE" )) { return ESP_LOG_NONE ;} if(!strcasecmp(level, "ERROR" )) { return ESP_LOG_ERROR ;} @@ -228,96 +154,6 @@ void set_log_level(char * tag, char * level){ esp_log_level_set(tag, get_log_level_from_char(level)); } -#define DEFAULT_NAME_WITH_MAC(var,defval) char var[strlen(defval)+sizeof(macStr)]; strcpy(var,defval); strcat(var,macStr) -void register_default_string_val(const char * key, const char * value){ - char * existing =(char *)config_alloc_get(NVS_TYPE_STR,key ); - ESP_LOGD(TAG,"Register default called with: %s= %s",key,value ); - if(!existing) { - ESP_LOGI(TAG,"Registering default value for key %s, value %s", key, value ); - config_set_default(NVS_TYPE_STR, key, value, 0); - } - else { - ESP_LOGD(TAG,"Value found for %s: %s",key,existing ); - } - FREE_AND_NULL(existing); -} -void register_single_default_num_val(const DefaultNumVal *entry) { - char number_buffer[101] = {}; - if (entry->is_signed) { - snprintf(number_buffer, sizeof(number_buffer) - 1, "%d", entry->uint_value); - } else { - snprintf(number_buffer, sizeof(number_buffer) - 1, "%u", entry->uint_value); - } - register_default_string_val(entry->key, number_buffer); -} -char * alloc_get_string_with_mac(const char * val) { - uint8_t mac[6]; - char macStr[LOCAL_MAC_SIZE + 1]; - char* fullvalue = NULL; - esp_read_mac((uint8_t*)&mac, ESP_MAC_WIFI_STA); - snprintf(macStr, LOCAL_MAC_SIZE - 1, "-%x%x%x", mac[3], mac[4], mac[5]); - fullvalue = malloc_init_external(strlen(val)+sizeof(macStr)+1); - if(fullvalue){ - strcpy(fullvalue, val); - strcat(fullvalue, macStr); - } - else { - ESP_LOGE(TAG,"malloc failed for value %s", val); - } - return fullvalue; - -} -void register_default_with_mac(const char* key, char* defval) { - char * fullvalue=alloc_get_string_with_mac(defval); - if(fullvalue){ - register_default_string_val(key,fullvalue); - FREE_AND_NULL(fullvalue); - } - else { - ESP_LOGE(TAG,"malloc failed for value %s", key); - } -} - -void register_default_nvs(){ -#ifdef CONFIG_CSPOT_SINK - register_default_string_val("enable_cspot", STR(CONFIG_CSPOT_SINK)); - cJSON * cspot_config=config_alloc_get_cjson("cspot_config"); - if(!cspot_config){ - char * name = alloc_get_string_with_mac(DEFAULT_HOST_NAME); - if(name){ - cjson_update_string(&cspot_config,"deviceName",name); - cjson_update_number(&cspot_config,"bitrate",160); - // the call below saves the config and frees the json pointer - config_set_cjson_str_and_free("cspot_config",cspot_config); - FREE_AND_NULL(name); - } - else { - register_default_string_val("cspot_config", ""); - } - - } - -#endif - -#ifdef CONFIG_AIRPLAY_SINK - register_default_with_mac("airplay_name", CONFIG_AIRPLAY_NAME); -#endif -#ifdef CONFIG_BT_SINK - register_default_with_mac("bt_name", CONFIG_BT_NAME); -#endif - register_default_with_mac("host_name", DEFAULT_HOST_NAME); - register_default_with_mac("ap_ssid", CONFIG_DEFAULT_AP_SSID); - register_default_with_mac("autoexec1",CONFIG_DEFAULT_COMMAND_LINE " -n " DEFAULT_HOST_NAME); - for (int i = 0; i < sizeof(defaultStringVals) / sizeof(DefaultStringVal); ++i) { - register_default_string_val(defaultStringVals[i].key, defaultStringVals[i].value); - } - for (int i = 0; i < sizeof(defaultNumVals) / sizeof(DefaultNumVal); ++i) { - register_single_default_num_val(&defaultNumVals[i]); - } - - wait_for_commit(); - ESP_LOGD(TAG,"Done setting default values in nvs."); -} uint32_t halSTORAGE_RebootCounterRead(void) { return RebootCounter ; } uint32_t halSTORAGE_RebootCounterUpdate(int32_t xValue) { @@ -351,7 +187,10 @@ void app_main() const esp_partition_t *running = esp_ota_get_running_partition(); is_recovery_running = (running->subtype == ESP_PARTITION_SUBTYPE_APP_FACTORY); xReason = esp_reset_reason(); - ESP_LOGI(TAG,"Reset reason is: %u", xReason); + ESP_LOGI(TAG,"Reset reason is: %u. Running from partition %s type %s ", + xReason, + running->label, + running->subtype == ESP_PARTITION_SUBTYPE_APP_FACTORY?"Factory":"Application"); if(!is_recovery_running ) { /* unscheduled restart (HW, Watchdog or similar) thus increment dynamic * counter then log current boot statistics as a warning */ @@ -370,8 +209,10 @@ void app_main() ESP_LOGI(TAG,"Recovery Reboot counter=%u\n", Counter) ; if (RecoveryRebootCounter == 5) { ESP_LOGW(TAG,"System rebooted too many times. This could be an indication that configuration is corrupted. Erasing config."); - erase_settings_partition(); + // TODO: Add support for the commented code + // erase_settings_partition(); // reboot one more time + #pragma message("Add support for erasing the configuration") guided_factory(); } @@ -381,10 +222,12 @@ void app_main() } - char * fwurl = NULL; MEMTRACE_PRINT_DELTA(); ESP_LOGI(TAG,"Starting app_main"); - initialize_nvs(); + init_spiffs(); + listFiles("/"); + ESP_LOGI(TAG,"Setting up config subsystem."); + configurator_load(); MEMTRACE_PRINT_DELTA(); #if defined(CONFIG_WITH_METRICS) ESP_LOGI(TAG,"Setting up metrics."); @@ -394,15 +237,10 @@ void app_main() ESP_LOGI(TAG,"Setting up telnet."); init_telnet(); // align on 32 bits boundaries MEMTRACE_PRINT_DELTA(); - ESP_LOGI(TAG,"Setting up config subsystem."); - config_init(); - MEMTRACE_PRINT_DELTA(); ESP_LOGD(TAG,"Creating event group for wifi"); network_event_group = xEventGroupCreate(); ESP_LOGD(TAG,"Clearing CONNECTED_BIT from wifi group"); xEventGroupClearBits(network_event_group, CONNECTED_BIT); - ESP_LOGI(TAG,"Registering default values"); - register_default_nvs(); MEMTRACE_PRINT_DELTA(); ESP_LOGI(TAG,"Configuring services"); services_init(); @@ -410,18 +248,16 @@ void app_main() ESP_LOGI(TAG,"Initializing display"); display_init("SqueezeESP32"); MEMTRACE_PRINT_DELTA(); - char *target = config_alloc_get_str("target", CONFIG_TARGET, NULL); - if (target) { - target_init(target); - free(target); + if(strlen(platform->target)>0){ + target_init(platform->target); } ESP_LOGI(TAG,"Initializing led_vu"); led_vu_init(); - if(is_recovery_running) { + ESP_LOGI(TAG,"Turning on display"); if (display) { GDS_ClearExt(display, true); - GDS_SetFont(display, &Font_line_2 ); + GDS_SetFont(display, Font_line_2 ); GDS_TextPos(display, GDS_FONT_DEFAULT, GDS_TEXT_CENTERED, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, "RECOVERY"); } if(led_display) { @@ -431,30 +267,21 @@ void app_main() #if defined(CONFIG_WITH_METRICS) metrics_event_boot(is_recovery_running?"recovery":"ota"); #endif - - ESP_LOGD(TAG,"Getting firmware OTA URL (if any)"); - fwurl = process_ota_url(); - - ESP_LOGD(TAG,"Getting value for WM bypass, nvs 'bypass_wm'"); - char * bypass_wm = config_alloc_get_default(NVS_TYPE_STR, "bypass_wm", "0", 0); - if(bypass_wm==NULL) - { - ESP_LOGE(TAG, "Unable to retrieve the Wifi Manager bypass flag"); - bypass_network_manager = false; - } - else { - bypass_network_manager=(strcmp(bypass_wm,"1")==0 ||strcasecmp(bypass_wm,"y")==0); - } if(!is_recovery_running){ - ESP_LOGD(TAG,"Getting audio control mapping "); - char *actrls_config = config_alloc_get_default(NVS_TYPE_STR, "actrls_config", "", 0); - if (actrls_init(actrls_config) == ESP_OK) { - ESP_LOGD(TAG,"Initializing audio control buttons type %s", actrls_config); - } else { - ESP_LOGD(TAG,"No audio control buttons"); - } - if (actrls_config) free(actrls_config); + #pragma message("Add audio controls support") + // ESP_LOGD(TAG,"Getting audio control mapping "); + // if(platform->has_dev && platform->dev.buttons_count >0){ + // ESP_LOGD(TAG,"Initializing audio control buttons"); + // } + // char *actrls_config = config_alloc_get_default(NVS_TYPE_STR, "actrls_config", "", 0); + // if (actrls_init(actrls_config) == ESP_OK) { + + // } else { + // ESP_LOGD(TAG,"No audio control buttons"); + // } + // if (actrls_config) free(actrls_config); + // TODO: Add support for the commented code } /* start the wifi manager */ @@ -479,26 +306,33 @@ void app_main() network_register_state_callback(NETWORK_WIFI_ACTIVE_STATE,WIFI_INITIALIZING_STATE, "handle_network_up", &handle_network_up); MEMTRACE_PRINT_DELTA(); } + if(!is_recovery_running){ + MEMTRACE_PRINT_DELTA_MESSAGE("Launching Squeezelite"); + start_squeezelite(); + MEMTRACE_PRINT_DELTA_MESSAGE("Squeezelite Started"); + } MEMTRACE_PRINT_DELTA_MESSAGE("Starting Console"); console_start(); MEMTRACE_PRINT_DELTA_MESSAGE("Console started"); - if(fwurl && strlen(fwurl)>0){ + + if(sys_state && sys_state->ota_url && strlen(sys_state->ota_url)){ + ESP_LOGD(TAG,"Found OTA URL %s",sys_state->ota_url); if(is_recovery_running){ while(!bNetworkConnected){ wait_for_wifi(); taskYIELD(); } - ESP_LOGI(TAG,"Updating firmware from link: %s",fwurl); + ESP_LOGI(TAG,"Updating firmware from link: %s",sys_state->ota_url); #if defined(CONFIG_WITH_METRICS) metrics_event("fw_update"); #endif - start_ota(fwurl, NULL, 0); + start_ota(sys_state->ota_url, NULL, 0); } else { ESP_LOGE(TAG,"Restarted to application partition. We're not going to perform OTA!"); - } - free(fwurl); + } } + services_sleep_init(); messaging_post_message(MESSAGING_INFO,MESSAGING_CLASS_SYSTEM,"System started"); } diff --git a/partitions.csv b/partitions.csv index 72a7e110..ef065929 100644 --- a/partitions.csv +++ b/partitions.csv @@ -1,8 +1,5 @@ -# Name, Type, SubType, Offset, Size, Flags -# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild -nvs, data, nvs, 0x9000, 0x4000, -otadata, data, ota, 0xD000, 0x2000, -phy_init, data, phy, 0xF000, 0x1000, -recovery, app, factory, 0x10000, 0x140000, -ota_0, app, ota_0, , 0x2A0000, -settings, data, nvs, , 0x10000, \ No newline at end of file +otadata, data, ota, 0xD000, 0x2000, +phy_init, data, phy, 0xF000, 0x1000, +recovery, app, factory, 0x10000, 0x130000, +ota_0, app, ota_0, , 0x290000, +spiffs, data, spiffs, , 0x2D000, \ No newline at end of file diff --git a/protobuf/CMakeLists.txt b/protobuf/CMakeLists.txt new file mode 100644 index 00000000..3fa7a098 --- /dev/null +++ b/protobuf/CMakeLists.txt @@ -0,0 +1,195 @@ +# Append nanopb path to CMAKE_MODULE_PATH for finding the nanopb package +cmake_minimum_required(VERSION 3.16) +message(STATUS "==================================================================================") +message(STATUS "=== PLATFORM PROTOBUF GENERATION ==") +message(STATUS "==================================================================================") +include(protobuf_utils.cmake) + +configure_env() +add_subdirectory(proto) +file(MAKE_DIRECTORY "${GENERATED_DIRECTORY}") +file(MAKE_DIRECTORY "${GENERATED_PY_DIRECTORY}") +file(MAKE_DIRECTORY "${GENERATED_JS_DIRECTORY}") + + +# Custom command to run protodot when a .proto file changes +foreach(PROTO_FILE IN ITEMS ${PROTO_FILES}) + get_filename_component(PROTO_NAME ${PROTO_FILE} NAME_WE) + set(GENERATED_PY "${GENERATED_PY_DIRECTORY}/${PROTO_NAME}_pb2.py") + set(GENERATED_JS "${GENERATED_JS_DIRECTORY}/${PROTO_NAME}_pb2.js") + set(GENERATED_DOT "${GENERATED_DIRECTORY}/${PROTO_NAME}.dot") + + # Prepare the protodot command and its arguments + set(PROTODOT_COMMAND + ${PROTODOT_BINARY} + -src ${PROTO_FILE} + -select "*" + -config ${CONFIG_FILE} + -output ${PROTO_NAME} + -generated "${GENERATED_DIRECTORY}" + -inc "${PROTO_INCLUDE_DIRECTORIES}" + ) + add_custom_command( + OUTPUT ${GENERATED_DOT} + COMMAND ${PROTODOT_COMMAND} + DEPENDS ${PROTO_FILE} + COMMENT "Generating DOT file for ${PROTO_NAME}" + VERBATIM + ) + + + list(APPEND GENERATED_PY_FILES ${GENERATED_PY} ) + list(APPEND GENERATED_JS_FILES ${GENERATED_JS} ) + list(APPEND GENERATED_DOT_FILES ${GENERATED_DOT}) +endforeach() + +set(PROTOC_PATH_LIST +--proto_path=${TOOLS_DIR}/protoc_utils +--proto_path=${CMAKE_CURRENT_SOURCE_DIR}/proto +--proto_path=${NANOPB_GENERATOR_SOURCE_DIR}/proto +--proto_path=${CMAKE_CURRENT_BINARY_DIR}/proto/nanopb/generator/proto +) + +# now generate python files +set(PROTOC_PYTHON_ARGS + --python_out=${GENERATED_PY_DIRECTORY} + # --js_out=${GENERATED_JS_DIRECTORY} + ${PROTOC_PATH_LIST} + ${PROTO_FILES} +) + +add_custom_command( + OUTPUT ${GENERATED_PY_FILES} + COMMAND ${PROTOC_BINARY} + ARGS ${PROTOC_PYTHON_ARGS} + DEPENDS ${PROTO_FILES} + COMMENT "Generating Python source ${GENERATED_PY_FILES}" +) +add_custom_target(generate_graph_files DEPENDS ${GENERATED_DOT_FILES} ) +add_custom_target(generate_py_files DEPENDS ${GENERATED_PY_FILES} ) +set_source_files_properties(${GENERATED_DOT_FILES} ${GENERATED_PY_FILES} PROPERTIES GENERATED TRUE) +add_dependencies(generate_py_files generate_system_proto ) + + + +set(PROTOC_UTILS_DIR ${TOOLS_DIR}/protoc_utils) +set(GENERATED_PLUGIN_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/plugins") +file(MAKE_DIRECTORY "${GENERATED_PLUGIN_DIRECTORY}") +set(ENV{PATH} "${PROTOC_UTILS_DIR};$ENV{PATH}") + +if(CMAKE_HOST_UNIX) + file(GLOB PLUGINS_EXECUTABLES "${PROTOC_UTILS_DIR}/protoc-gen-*") + + # Add custom target to set executable permissions for plugin executables + add_custom_target(set_proto_plugins_permissions + COMMAND ${CMAKE_COMMAND} -E echo "**** Setting permissions for required files" + COMMAND chmod +x ${PLUGINS_EXECUTABLES} + COMMAND ${CMAKE_COMMAND} -E echo "**** Permissions set for plugin executables" + COMMAND ${CMAKE_COMMAND} -E echo "************************************************************************************************" + ) + + # Add a dependency to ensure permissions are set before building cspot component + add_dependencies(generate_py_files set_proto_plugins_permissions) +endif() + +set(GENERATED_BIN_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") +set(PROTO_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/proto;${NANOPB_GENERATOR_SOURCE_DIR}/proto") +file(MAKE_DIRECTORY "${GENERATED_BIN_DIRECTORY}") + +string(REPLACE ":" "%3A" GENERATED_PY_DIRECTORY_ENC ${GENERATED_PY_DIRECTORY}) +string(REPLACE ":" "%3A" GENERATED_BIN_DIRECTORY_ENC ${GENERATED_BIN_DIRECTORY}) +list(APPEND PROTOC_PATH_LIST "--proto_path=${GENERATED_PY_DIRECTORY}") +array_to_delimited("?" PROTOC_PATH_LIST ) +string(REPLACE "--proto_path=" "" PROTOC_PATH_LIST_DELIMITED ${PROTOC_PATH_LIST_DELIMITED}) + + +# message(STATUS "Encoded bin folder ${GENERATED_BIN_DIRECTORY_ENC}") +# message(STATUS "Encoded protoc path list ${PROTOC_PATH_LIST_DELIMITED}") +set(DEFAULTS_OUTPUT "${CMAKE_SOURCE_DIR}/spiffs/Config_defaults_pb.bin") + +set(PLUGINS_OPT + --plugin=protoc-gen-ZZZZ=${PROTOC_UTILS_DIR}/protoc-gen-ZZZZ${PROTOC_PLUGIN_SUFFIX} + --ZZZZ_out=main_class=sys.Config!sys.Status!sys.State:${GENERATED_PLUGIN_DIRECTORY} + --ZZZZ_opt=options=customoptions + --ZZZZ_opt=path=${PROTOC_PATH_LIST_DELIMITED} + --ZZZZ_opt=binpath=${GENERATED_BIN_DIRECTORY} + --ZZZZ_opt=const_prefix=squeezelite- + --ZZZZ_opt=defaultspath=${CMAKE_SOURCE_DIR}/spiffs +) + + +replace_in_list(PLUGINS_OPT "ZZZZ" "dump" DUMP_OUT_OPTS) +replace_in_list(PLUGINS_OPT "ZZZZ" "json" DUMP_JSON_OPTS) +replace_in_list(PLUGINS_OPT "ZZZZ" "defaults" DUMP_DEFAULTS_OPTS) +replace_in_list(PLUGINS_OPT "ZZZZ" "options" DUMP_OPTIONS_OPTS) + + +# print_array("DUMP_OUT_OPTS plugins options:" "${DUMP_OUT_OPTS}" "NEWLINE") + + +set(PROTOC_ARGS +${DUMP_OUT_OPTS} +${DUMP_JSON_OPTS} +${DUMP_DEFAULTS_OPTS} +${DUMP_OPTIONS_OPTS} +${PROTOC_PATH_LIST} +${PROTO_FILES} +) + +# print_array("PROTOC Args:" "${PROTOC_ARGS}" "NEWLINE") + +SET(PLUGINS_OUTPUT + "${GENERATED_BIN_DIRECTORY}/code_generator_request.bin" + "${GENERATED_PLUGIN_DIRECTORY}/Config_pb2.json" + "${GENERATED_PLUGIN_DIRECTORY}/Status_pb2.json" + "${DEFAULTS_OUTPUT}" +) + +add_custom_command( + OUTPUT ${PLUGINS_OUTPUT} + COMMAND ${PROTOC_BINARY} + ARGS ${PROTOC_ARGS} + DEPENDS ${PROTO_FILES} + COMMENT "Generating various sources for ${PLUGINS_OUTPUT}" +) + +add_dependencies(generate_graph_files generate_system_proto ) +add_custom_target(generate_plugins_files DEPENDS ${PLUGINS_OUTPUT} ) +add_dependencies(generate_plugins_files generate_py_files) +add_dependencies(__idf_platform_config generate_plugins_files) +set_source_files_properties( ${PLUGINS_OUTPUT} PROPERTIES GENERATED TRUE) + + +file(GLOB SOURCE_JSON_FILES "${CMAKE_CURRENT_SOURCE_DIR}/targets/*.json") +set(GENERATED_BIN_DIRECTORY "${CMAKE_SOURCE_DIR}/spiffs/targets") +file(MAKE_DIRECTORY "${GENERATED_BIN_DIRECTORY}") +foreach(SOURCE_JSON_FILE IN ITEMS ${SOURCE_JSON_FILES}) + get_filename_component(TARGET_NAME ${SOURCE_JSON_FILE} NAME_WE) + set(GENERATED_BIN "${GENERATED_BIN_DIRECTORY}/${TARGET_NAME}.bin") + # Prepare the protodot command and its arguments + set(PROTOBIN_COMMAND + ${PYTHON_EXECUTABLE} + ${TOOLS_DIR}/protoc_utils/generate_bin.py + --proto_file "${CMAKE_CURRENT_BINARY_DIR}/py/configuration" + --main_class "Config" + --target_dir "${GENERATED_BIN_DIRECTORY}" + --json ${SOURCE_JSON_FILE} + --include "${CMAKE_CURRENT_BINARY_DIR}/proto/nanopb/generator/proto" + --include "${CMAKE_CURRENT_BINARY_DIR}/py/" + ) + add_custom_command( + OUTPUT ${GENERATED_BIN} + COMMAND ${PROTOBIN_COMMAND} + DEPENDS ${SOURCE_JSON_FILE} ${PROTO_FILES} ${GENERATED_PY_FILES} + COMMENT "Generating BIN file for target ${TARGET_NAME}" + VERBATIM + ) + list(APPEND GENERATED_BIN_FILES ${GENERATED_BIN} ) +endforeach() + + +add_custom_target(generate_spiffs_bin DEPENDS ${GENERATED_BIN_FILES} ${DEFAULTS_OUTPUT}) +set_source_files_properties(${GENERATED_BIN_FILES} PROPERTIES GENERATED TRUE) +add_dependencies(generate_spiffs_bin generate_system_proto) + +message(STATUS "==================================================================================") \ No newline at end of file diff --git a/components/wifi-manager/webapp/dist/dist/js/index.b02584.bundle.d.ts b/protobuf/Config_defaults_pb.bin similarity index 100% rename from components/wifi-manager/webapp/dist/dist/js/index.b02584.bundle.d.ts rename to protobuf/Config_defaults_pb.bin diff --git a/components/wifi-manager/webapp/dist/dist/js/node_vendors.b02584.bundle.d.ts b/protobuf/Status_defaults_pb.bin similarity index 100% rename from components/wifi-manager/webapp/dist/dist/js/node_vendors.b02584.bundle.d.ts rename to protobuf/Status_defaults_pb.bin diff --git a/protobuf/code_generator_request.bin b/protobuf/code_generator_request.bin new file mode 100644 index 00000000..17765109 Binary files /dev/null and b/protobuf/code_generator_request.bin differ diff --git a/protobuf/generated/AirPlay.dot b/protobuf/generated/AirPlay.dot new file mode 100644 index 00000000..11fc7d66 --- /dev/null +++ b/protobuf/generated/AirPlay.dot @@ -0,0 +1,29 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/AirPlay.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_101 [shape=plaintext tooltip="platform.AirPlay" label=<
AirPlay
1enabledbool
2device_namestring
3portuint32
>]; + + /* ------ connections ------ */ + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:16 EST */ +} diff --git a/protobuf/generated/AirPlay.dot.png b/protobuf/generated/AirPlay.dot.png new file mode 100644 index 00000000..afe1e5e2 Binary files /dev/null and b/protobuf/generated/AirPlay.dot.png differ diff --git a/protobuf/generated/AirPlay.dot.svg b/protobuf/generated/AirPlay.dot.svg new file mode 100644 index 00000000..37842cd1 --- /dev/null +++ b/protobuf/generated/AirPlay.dot.svg @@ -0,0 +1,39 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_101 + + + +AirPlay +1 +enabled + +bool +2 +device_name + +string +3 +port + +uint32 + + + + + + diff --git a/protobuf/generated/Artwork.dot b/protobuf/generated/Artwork.dot new file mode 100644 index 00000000..ee1b4076 --- /dev/null +++ b/protobuf/generated/Artwork.dot @@ -0,0 +1,29 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/Artwork.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_100 [shape=plaintext tooltip="platform.Artwork" label=<
Artwork
1enabledbool
2resizebool
>]; + + /* ------ connections ------ */ + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:16 EST */ +} diff --git a/protobuf/generated/Artwork.dot.png b/protobuf/generated/Artwork.dot.png new file mode 100644 index 00000000..9adb0ca4 Binary files /dev/null and b/protobuf/generated/Artwork.dot.png differ diff --git a/protobuf/generated/Artwork.dot.svg b/protobuf/generated/Artwork.dot.svg new file mode 100644 index 00000000..a7dfaf1e --- /dev/null +++ b/protobuf/generated/Artwork.dot.svg @@ -0,0 +1,35 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_100 + + + +Artwork +1 +enabled + +bool +2 +resize + +bool + + + + + + diff --git a/protobuf/generated/Battery.dot b/protobuf/generated/Battery.dot new file mode 100644 index 00000000..b49a22cd --- /dev/null +++ b/protobuf/generated/Battery.dot @@ -0,0 +1,33 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/Battery.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_102 [shape=plaintext tooltip="platform.Battery" label=<
Battery
1channelBatteryChannelEnum
2scalefloat
3cellsint32
4attenBatteryAttenEnum
>]; + Node_Ja_100 [shape=plaintext tooltip="BatteryChannelEnum" label=<
enum BatteryChannelEnum
UNSPECIFIED_CH0
CH01
CH12
CH23
CH34
CH45
CH56
CH67
CH78
>]; + Node_Ja_101 [shape=plaintext tooltip="BatteryAttenEnum" label=<
enum BatteryAttenEnum
UNSPECIFIED_ATT0
ATT_01
ATT_12
ATT_23
ATT_34
>]; + + /* ------ connections ------ */ + Node_Ja_102:pochannel:e -> Node_Ja_100 [color="#008000" tooltip="Ja_102 --> Ja_100"]; + Node_Ja_102:poatten:e -> Node_Ja_101 [color="#008000" tooltip="Ja_102 --> Ja_101"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:38 EST */ +} diff --git a/protobuf/generated/Battery.dot.png b/protobuf/generated/Battery.dot.png new file mode 100644 index 00000000..1c571253 Binary files /dev/null and b/protobuf/generated/Battery.dot.png differ diff --git a/protobuf/generated/Battery.dot.svg b/protobuf/generated/Battery.dot.svg new file mode 100644 index 00000000..bf99589a --- /dev/null +++ b/protobuf/generated/Battery.dot.svg @@ -0,0 +1,141 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_102 + + + +Battery +1 +channel + +BatteryChannelEnum +2 +scale + +float +3 +cells + +int32 +4 +atten + +BatteryAttenEnum + + + + + + +Node_Ja_100 + + + +enum +BatteryChannelEnum + +UNSPECIFIED_CH + +0 + +CH0 + +1 + +CH1 + +2 + +CH2 + +3 + +CH3 + +4 + +CH4 + +5 + +CH5 + +6 + +CH6 + +7 + +CH7 + +8 + + + + + + +Node_Ja_102:e->Node_Ja_100 + + + + + + + + +Node_Ja_101 + + + +enum +BatteryAttenEnum + +UNSPECIFIED_ATT + +0 + +ATT_0 + +1 + +ATT_1 + +2 + +ATT_2 + +3 + +ATT_3 + +4 + + + + + + +Node_Ja_102:e->Node_Ja_101 + + + + + + + + diff --git a/protobuf/generated/Buttons.dot b/protobuf/generated/Buttons.dot new file mode 100644 index 00000000..bf159212 --- /dev/null +++ b/protobuf/generated/Buttons.dot @@ -0,0 +1,46 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/Buttons.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_113 [shape=plaintext tooltip="platform.KnobOnly" label=<
KnobOnly
1enablebool
2delay_msint32
>]; + Node_Ja_110 [shape=plaintext tooltip="ButtonAction" label=<
enum ButtonAction
ACTRLS_NONE0
ACTRLS_POWER1
ACTRLS_VOLUP2
ACTRLS_VOLDOWN3
ACTRLS_TOGGLE4
ACTRLS_PLAY5
ACTRLS_PAUSE6
ACTRLS_STOP7
ACTRLS_REW8
ACTRLS_FWD9
ACTRLS_PREV10
ACTRLS_NEXT11
BCTRLS_UP12
BCTRLS_DOWN13
BCTRLS_LEFT14
BCTRLS_RIGHT15
BCTRLS_PS116
BCTRLS_PS217
BCTRLS_PS318
BCTRLS_PS419
BCTRLS_PS520
BCTRLS_PS621
BCTRLS_PS722
BCTRLS_PS823
BCTRLS_PS924
BCTRLS_PS1025
KNOB_LEFT26
KNOB_RIGHT27
KNOB_PUSH28
ACTRLS_SLEEP29
>]; + Node_Ja_104 [shape=plaintext tooltip="platform.GPIO" label=<
GPIO
1pinint32
2levelint32
>]; + Node_Ja_111 [shape=plaintext tooltip="platform.ButtonActions" label=<
ButtonActions
1pressedButtonAction
2releasedButtonAction
>]; + Node_Ja_112 [shape=plaintext tooltip="platform.Button" label=<
Button
1gpioGPIO
2pullbool
3debounceint32
4shifterGPIO
5longdurationint32
6normalButtonActions
7longpressButtonActions
8shiftedButtonActions
9longshiftedButtonActions
>]; + Node_Ja_114 [shape=plaintext tooltip="platform.Rotary" label=<
Rotary
1AGPIO
2BGPIO
3SWGPIO
4knobonlyKnobOnly
5volumebool
6longpressbool
>]; + + /* ------ connections ------ */ + Node_Ja_112:pogpio:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_112 --> Ja_104"]; + Node_Ja_112:polongshifted:e -> Node_Ja_111:header [color="#000000" tooltip="Ja_112 --> Ja_111"]; + Node_Ja_112:poshifted:e -> Node_Ja_111:header [color="#000000" tooltip="Ja_112 --> Ja_111"]; + Node_Ja_114:poSW:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_114 --> Ja_104"]; + Node_Ja_114:poA:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_114 --> Ja_104"]; + Node_Ja_111:poreleased:e -> Node_Ja_110 [color="#008000" tooltip="Ja_111 --> Ja_110"]; + Node_Ja_111:popressed:e -> Node_Ja_110 [color="#008000" tooltip="Ja_111 --> Ja_110"]; + Node_Ja_112:poshifter:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_112 --> Ja_104"]; + Node_Ja_112:polongpress:e -> Node_Ja_111:header [color="#000000" tooltip="Ja_112 --> Ja_111"]; + Node_Ja_112:ponormal:e -> Node_Ja_111:header [color="#000000" tooltip="Ja_112 --> Ja_111"]; + Node_Ja_114:poknobonly:e -> Node_Ja_113:header [color="#000000" tooltip="Ja_114 --> Ja_113"]; + Node_Ja_114:poB:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_114 --> Ja_104"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:16 EST */ +} diff --git a/protobuf/generated/Buttons.dot.png b/protobuf/generated/Buttons.dot.png new file mode 100644 index 00000000..3383b07a Binary files /dev/null and b/protobuf/generated/Buttons.dot.png differ diff --git a/protobuf/generated/Buttons.dot.svg b/protobuf/generated/Buttons.dot.svg new file mode 100644 index 00000000..b8756627 --- /dev/null +++ b/protobuf/generated/Buttons.dot.svg @@ -0,0 +1,395 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_113 + + + +KnobOnly +1 +enable + +bool +2 +delay_ms + +int32 + + + + + + +Node_Ja_110 + + + +enum +ButtonAction + +ACTRLS_NONE + +0 + +ACTRLS_POWER + +1 + +ACTRLS_VOLUP + +2 + +ACTRLS_VOLDOWN + +3 + +ACTRLS_TOGGLE + +4 + +ACTRLS_PLAY + +5 + +ACTRLS_PAUSE + +6 + +ACTRLS_STOP + +7 + +ACTRLS_REW + +8 + +ACTRLS_FWD + +9 + +ACTRLS_PREV + +10 + +ACTRLS_NEXT + +11 + +BCTRLS_UP + +12 + +BCTRLS_DOWN + +13 + +BCTRLS_LEFT + +14 + +BCTRLS_RIGHT + +15 + +BCTRLS_PS1 + +16 + +BCTRLS_PS2 + +17 + +BCTRLS_PS3 + +18 + +BCTRLS_PS4 + +19 + +BCTRLS_PS5 + +20 + +BCTRLS_PS6 + +21 + +BCTRLS_PS7 + +22 + +BCTRLS_PS8 + +23 + +BCTRLS_PS9 + +24 + +BCTRLS_PS10 + +25 + +KNOB_LEFT + +26 + +KNOB_RIGHT + +27 + +KNOB_PUSH + +28 + +ACTRLS_SLEEP + +29 + + + + + + +Node_Ja_104 + + + +GPIO +1 +pin + +int32 +2 +level + +int32 + + + + + + +Node_Ja_111 + + + +ButtonActions +1 +pressed + +ButtonAction +2 +released + +ButtonAction + + + + + + +Node_Ja_111:e->Node_Ja_110 + + + + + + + + +Node_Ja_111:e->Node_Ja_110 + + + + + + + + +Node_Ja_112 + + + +Button +1 +gpio + +GPIO +2 +pull + +bool +3 +debounce + +int32 +4 +shifter + +GPIO +5 +longduration + +int32 +6 +normal + +ButtonActions +7 +longpress + +ButtonActions +8 +shifted + +ButtonActions +9 +longshifted + +ButtonActions + + + + + + +Node_Ja_112:e->Node_Ja_104:header + + + + + + + + +Node_Ja_112:e->Node_Ja_104:header + + + + + + + + +Node_Ja_112:e->Node_Ja_111:header + + + + + + + + +Node_Ja_112:e->Node_Ja_111:header + + + + + + + + +Node_Ja_112:e->Node_Ja_111:header + + + + + + + + +Node_Ja_112:e->Node_Ja_111:header + + + + + + + + +Node_Ja_114 + + + +Rotary +1 +A + +GPIO +2 +B + +GPIO +3 +SW + +GPIO +4 +knobonly + +KnobOnly +5 +volume + +bool +6 +longpress + +bool + + + + + + +Node_Ja_114:e->Node_Ja_113:header + + + + + + + + +Node_Ja_114:e->Node_Ja_104:header + + + + + + + + +Node_Ja_114:e->Node_Ja_104:header + + + + + + + + +Node_Ja_114:e->Node_Ja_104:header + + + + + + + + diff --git a/protobuf/generated/Common.dot b/protobuf/generated/Common.dot new file mode 100644 index 00000000..4807db90 --- /dev/null +++ b/protobuf/generated/Common.dot @@ -0,0 +1,28 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/Common.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + + /* ------ connections ------ */ + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:16 EST */ +} diff --git a/protobuf/generated/Common.dot.png b/protobuf/generated/Common.dot.png new file mode 100644 index 00000000..2df2cad2 Binary files /dev/null and b/protobuf/generated/Common.dot.png differ diff --git a/protobuf/generated/Common.dot.svg b/protobuf/generated/Common.dot.svg new file mode 100644 index 00000000..14725b7b --- /dev/null +++ b/protobuf/generated/Common.dot.svg @@ -0,0 +1,16 @@ + + + + + + +protodot + +platform + + + + diff --git a/protobuf/generated/DAC.dot b/protobuf/generated/DAC.dot new file mode 100644 index 00000000..3ec10740 --- /dev/null +++ b/protobuf/generated/DAC.dot @@ -0,0 +1,62 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/DAC.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_114 [shape=plaintext tooltip="platform.RegisterAction" label=<
RegisterAction
1regint32
2valint32
3modeMode
>]; + Node_Ja_117 [shape=plaintext tooltip="platform.DelayAction" label=<
DelayAction
1delayint32
>]; + Node_Ja_110 [shape=plaintext tooltip="platform.DacControlSet" label=<
DacControlSet
[...]1commandsControlCommand
>]; + Node_Ja_119 [shape=plaintext tooltip="I2CPortEnum" label=<
enum I2CPortEnum
UNSPECIFIED_PORT0
I2CPort01
I2CPort12
>]; + Node_Ja_116 [shape=plaintext tooltip="platform.GpioAction" label=<
GpioAction
1gpioint32
2levelGpioActionLevel
>]; + Node_Ja_104 [shape=plaintext tooltip="platform.GPIO" label=<
GPIO
1pinint32
2levelint32
>]; + Node_Ja_120 [shape=plaintext tooltip="platform.I2CBus" label=<
I2CBus
1portI2CPortEnum
2speedint32
3sdaGPIO
4sclGPIO
>]; + Node_Ja_111 [shape=plaintext tooltip="platform.ControlCommand" label=<
ControlCommand
1typeControlCommandType
[...]2itemsControlItem
>]; + Node_Ja_115 [shape=plaintext tooltip="GpioActionLevel" label=<
enum GpioActionLevel
ACTION_LEVEL_UNDEFINED0
ACTION_LEVEL_11
ACTION_LEVEL_02
>]; + Node_Ja_112 [shape=plaintext tooltip="ControlCommandType" label=<
enum ControlCommandType
INIT0
POWER_ON1
POWER_OFF2
SPEAKER_ON3
SPEAKER_OFF4
HEADSET_ON5
HEADSET_OFF6
>]; + Node_Ja_118 [shape=plaintext tooltip="Mode" label=<
enum Mode
REG_MODE_NOTHING0
REG_MODE_OR1
REG_MODE_AND2
>]; + Node_Ja_123 [shape=plaintext tooltip="platform.DAC" label=<
DAC
1bckGPIO
2wsGPIO
3doutGPIO
4mckMCKEnum
5muteGPIO
6modelDACModelEnum
7i2cI2CBus
8daccontrolsetDacControlSet
>]; + Node_Ja_121 [shape=plaintext tooltip="DACModelEnum" label=<
enum DACModelEnum
UNSPECIFIED_MODEL0
TAS57xx1
TAS57132
AC1013
WM89784
ES83885
I2S6
>]; + Node_Ja_122 [shape=plaintext tooltip="MCKEnum" label=<
enum MCKEnum
UNSPECIFIED_MCK0
MCK01
MCK12
MCK23
>]; + Node_Ja_113 [shape=plaintext tooltip="platform.ControlItem" label=<
ControlItem
item_type
1reg_actionRegisterAction
2gpio_actionGpioAction
3delay_actionDelayAction
>]; + + /* ------ connections ------ */ + Node_Ja_114:pomode:e -> Node_Ja_118 [color="#008000" tooltip="Ja_114 --> Ja_118"]; + Node_Ja_123:pomute:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_123 --> Ja_104"]; + Node_Ja_123:pomodel:e -> Node_Ja_121 [color="#008000" tooltip="Ja_123 --> Ja_121"]; + Node_Ja_123:pomck:e -> Node_Ja_122 [color="#008000" tooltip="Ja_123 --> Ja_122"]; + Node_Ja_110:pocommands:e -> Node_Ja_111:header [color="#000000" tooltip="Ja_110 --> Ja_111"]; + Node_Ja_120:poport:e -> Node_Ja_119 [color="#008000" tooltip="Ja_120 --> Ja_119"]; + Node_Ja_113:poreg_action:e -> Node_Ja_114:header [color="#000000" tooltip="Ja_113 --> Ja_114"]; + Node_Ja_120:posda:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_120 --> Ja_104"]; + Node_Ja_111:poitems:e -> Node_Ja_113:header [color="#000000" tooltip="Ja_111 --> Ja_113"]; + Node_Ja_113:pogpio_action:e -> Node_Ja_116:header [color="#000000" tooltip="Ja_113 --> Ja_116"]; + Node_Ja_113:podelay_action:e -> Node_Ja_117:header [color="#000000" tooltip="Ja_113 --> Ja_117"]; + Node_Ja_116:polevel:e -> Node_Ja_115 [color="#008000" tooltip="Ja_116 --> Ja_115"]; + Node_Ja_123:pobck:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_123 --> Ja_104"]; + Node_Ja_123:podaccontrolset:e -> Node_Ja_110:header [color="#000000" tooltip="Ja_123 --> Ja_110"]; + Node_Ja_123:podout:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_123 --> Ja_104"]; + Node_Ja_123:poi2c:e -> Node_Ja_120:header [color="#000000" tooltip="Ja_123 --> Ja_120"]; + Node_Ja_120:poscl:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_120 --> Ja_104"]; + Node_Ja_123:pows:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_123 --> Ja_104"]; + Node_Ja_111:potype:e -> Node_Ja_112 [color="#008000" tooltip="Ja_111 --> Ja_112"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:16 EST */ +} diff --git a/protobuf/generated/DAC.dot.png b/protobuf/generated/DAC.dot.png new file mode 100644 index 00000000..d6842dd1 Binary files /dev/null and b/protobuf/generated/DAC.dot.png differ diff --git a/protobuf/generated/DAC.dot.svg b/protobuf/generated/DAC.dot.svg new file mode 100644 index 00000000..25fcb5a8 --- /dev/null +++ b/protobuf/generated/DAC.dot.svg @@ -0,0 +1,578 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_114 + + + +RegisterAction +1 +reg + +int32 +2 +val + +int32 +3 +mode + +Mode + + + + + + +Node_Ja_118 + + + +enum +Mode + +REG_MODE_NOTHING + +0 + +REG_MODE_OR + +1 + +REG_MODE_AND + +2 + + + + + + +Node_Ja_114:e->Node_Ja_118 + + + + + + + + +Node_Ja_117 + + + +DelayAction +1 +delay + +int32 + + + + + + +Node_Ja_110 + + + +DacControlSet +[...] +1 +commands + +ControlCommand + + + + + + +Node_Ja_111 + + + +ControlCommand +1 +type + +ControlCommandType +[...] +2 +items + +ControlItem + + + + + + +Node_Ja_110:e->Node_Ja_111:header + + + + + + + + +Node_Ja_119 + + + +enum +I2CPortEnum + +UNSPECIFIED_PORT + +0 + +I2CPort0 + +1 + +I2CPort1 + +2 + + + + + + +Node_Ja_116 + + + +GpioAction +1 +gpio + +int32 +2 +level + +GpioActionLevel + + + + + + +Node_Ja_115 + + + +enum +GpioActionLevel + +ACTION_LEVEL_UNDEFINED + +0 + +ACTION_LEVEL_1 + +1 + +ACTION_LEVEL_0 + +2 + + + + + + +Node_Ja_116:e->Node_Ja_115 + + + + + + + + +Node_Ja_104 + + + +GPIO +1 +pin + +int32 +2 +level + +int32 + + + + + + +Node_Ja_120 + + + +I2CBus +1 +port + +I2CPortEnum +2 +speed + +int32 +3 +sda + +GPIO +4 +scl + +GPIO + + + + + + +Node_Ja_120:e->Node_Ja_119 + + + + + + + + +Node_Ja_120:e->Node_Ja_104:header + + + + + + + + +Node_Ja_120:e->Node_Ja_104:header + + + + + + + + +Node_Ja_112 + + + +enum +ControlCommandType + +INIT + +0 + +POWER_ON + +1 + +POWER_OFF + +2 + +SPEAKER_ON + +3 + +SPEAKER_OFF + +4 + +HEADSET_ON + +5 + +HEADSET_OFF + +6 + + + + + + +Node_Ja_111:e->Node_Ja_112 + + + + + + + + +Node_Ja_113 + + + +ControlItem + +item_type + +1 +reg_action + +RegisterAction + +2 +gpio_action + +GpioAction + +3 +delay_action + +DelayAction + + + + + + + +Node_Ja_111:e->Node_Ja_113:header + + + + + + + + +Node_Ja_123 + + + +DAC +1 +bck + +GPIO +2 +ws + +GPIO +3 +dout + +GPIO +4 +mck + +MCKEnum +5 +mute + +GPIO +6 +model + +DACModelEnum +7 +i2c + +I2CBus +8 +daccontrolset + +DacControlSet + + + + + + +Node_Ja_123:e->Node_Ja_110:header + + + + + + + + +Node_Ja_123:e->Node_Ja_104:header + + + + + + + + +Node_Ja_123:e->Node_Ja_104:header + + + + + + + + +Node_Ja_123:e->Node_Ja_104:header + + + + + + + + +Node_Ja_123:e->Node_Ja_104:header + + + + + + + + +Node_Ja_123:e->Node_Ja_120:header + + + + + + + + +Node_Ja_121 + + + +enum +DACModelEnum + +UNSPECIFIED_MODEL + +0 + +TAS57xx + +1 + +TAS5713 + +2 + +AC101 + +3 + +WM8978 + +4 + +ES8388 + +5 + +I2S + +6 + + + + + + +Node_Ja_123:e->Node_Ja_121 + + + + + + + + +Node_Ja_122 + + + +enum +MCKEnum + +UNSPECIFIED_MCK + +0 + +MCK0 + +1 + +MCK1 + +2 + +MCK2 + +3 + + + + + + +Node_Ja_123:e->Node_Ja_122 + + + + + + + + +Node_Ja_113:e->Node_Ja_114:header + + + + + + + + +Node_Ja_113:e->Node_Ja_117:header + + + + + + + + +Node_Ja_113:e->Node_Ja_116:header + + + + + + + + diff --git a/protobuf/generated/DacControlSet.dot b/protobuf/generated/DacControlSet.dot new file mode 100644 index 00000000..590a65c9 --- /dev/null +++ b/protobuf/generated/DacControlSet.dot @@ -0,0 +1,45 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/DacControlSet.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_104 [shape=plaintext tooltip="platform.RegisterAction" label=<
RegisterAction
1regint32
2valint32
3modeMode
>]; + Node_Ja_106 [shape=plaintext tooltip="platform.GpioAction" label=<
GpioAction
1gpioint32
2levelGpioActionLevel
>]; + Node_Ja_107 [shape=plaintext tooltip="platform.DelayAction" label=<
DelayAction
1delayint32
>]; + Node_Ja_100 [shape=plaintext tooltip="platform.DacControlSet" label=<
DacControlSet
[...]1commandsControlCommand
>]; + Node_Ja_102 [shape=plaintext tooltip="ControlCommandType" label=<
enum ControlCommandType
INIT0
POWER_ON1
POWER_OFF2
SPEAKER_ON3
SPEAKER_OFF4
HEADSET_ON5
HEADSET_OFF6
>]; + Node_Ja_105 [shape=plaintext tooltip="GpioActionLevel" label=<
enum GpioActionLevel
ACTION_LEVEL_UNDEFINED0
ACTION_LEVEL_11
ACTION_LEVEL_02
>]; + Node_Ja_101 [shape=plaintext tooltip="platform.ControlCommand" label=<
ControlCommand
1typeControlCommandType
[...]2itemsControlItem
>]; + Node_Ja_108 [shape=plaintext tooltip="Mode" label=<
enum Mode
REG_MODE_NOTHING0
REG_MODE_OR1
REG_MODE_AND2
>]; + Node_Ja_103 [shape=plaintext tooltip="platform.ControlItem" label=<
ControlItem
item_type
1reg_actionRegisterAction
2gpio_actionGpioAction
3delay_actionDelayAction
>]; + + /* ------ connections ------ */ + Node_Ja_104:pomode:e -> Node_Ja_108 [color="#008000" tooltip="Ja_104 --> Ja_108"]; + Node_Ja_106:polevel:e -> Node_Ja_105 [color="#008000" tooltip="Ja_106 --> Ja_105"]; + Node_Ja_100:pocommands:e -> Node_Ja_101:header [color="#000000" tooltip="Ja_100 --> Ja_101"]; + Node_Ja_103:poreg_action:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_103 --> Ja_104"]; + Node_Ja_103:pogpio_action:e -> Node_Ja_106:header [color="#000000" tooltip="Ja_103 --> Ja_106"]; + Node_Ja_103:podelay_action:e -> Node_Ja_107:header [color="#000000" tooltip="Ja_103 --> Ja_107"]; + Node_Ja_101:potype:e -> Node_Ja_102 [color="#008000" tooltip="Ja_101 --> Ja_102"]; + Node_Ja_101:poitems:e -> Node_Ja_103:header [color="#000000" tooltip="Ja_101 --> Ja_103"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:38 EST */ +} diff --git a/protobuf/generated/DacControlSet.dot.png b/protobuf/generated/DacControlSet.dot.png new file mode 100644 index 00000000..5e195f87 Binary files /dev/null and b/protobuf/generated/DacControlSet.dot.png differ diff --git a/protobuf/generated/DacControlSet.dot.svg b/protobuf/generated/DacControlSet.dot.svg new file mode 100644 index 00000000..14e19fbd --- /dev/null +++ b/protobuf/generated/DacControlSet.dot.svg @@ -0,0 +1,298 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_104 + + + +RegisterAction +1 +reg + +int32 +2 +val + +int32 +3 +mode + +Mode + + + + + + +Node_Ja_108 + + + +enum +Mode + +REG_MODE_NOTHING + +0 + +REG_MODE_OR + +1 + +REG_MODE_AND + +2 + + + + + + +Node_Ja_104:e->Node_Ja_108 + + + + + + + + +Node_Ja_106 + + + +GpioAction +1 +gpio + +int32 +2 +level + +GpioActionLevel + + + + + + +Node_Ja_105 + + + +enum +GpioActionLevel + +ACTION_LEVEL_UNDEFINED + +0 + +ACTION_LEVEL_1 + +1 + +ACTION_LEVEL_0 + +2 + + + + + + +Node_Ja_106:e->Node_Ja_105 + + + + + + + + +Node_Ja_107 + + + +DelayAction +1 +delay + +int32 + + + + + + +Node_Ja_100 + + + +DacControlSet +[...] +1 +commands + +ControlCommand + + + + + + +Node_Ja_101 + + + +ControlCommand +1 +type + +ControlCommandType +[...] +2 +items + +ControlItem + + + + + + +Node_Ja_100:e->Node_Ja_101:header + + + + + + + + +Node_Ja_102 + + + +enum +ControlCommandType + +INIT + +0 + +POWER_ON + +1 + +POWER_OFF + +2 + +SPEAKER_ON + +3 + +SPEAKER_OFF + +4 + +HEADSET_ON + +5 + +HEADSET_OFF + +6 + + + + + + +Node_Ja_101:e->Node_Ja_102 + + + + + + + + +Node_Ja_103 + + + +ControlItem + +item_type + +1 +reg_action + +RegisterAction + +2 +gpio_action + +GpioAction + +3 +delay_action + +DelayAction + + + + + + + +Node_Ja_101:e->Node_Ja_103:header + + + + + + + + +Node_Ja_103:e->Node_Ja_104:header + + + + + + + + +Node_Ja_103:e->Node_Ja_106:header + + + + + + + + +Node_Ja_103:e->Node_Ja_107:header + + + + + + + + diff --git a/protobuf/generated/Devices.dot b/protobuf/generated/Devices.dot new file mode 100644 index 00000000..2d95ea4e --- /dev/null +++ b/protobuf/generated/Devices.dot @@ -0,0 +1,155 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/Devices.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_144 [shape=plaintext tooltip="platform.SPDIF" label=<
SPDIF
1dcGPIO
2dataGPIO
3clkGPIO
>]; + Node_Ja_129 [shape=plaintext tooltip="platform.Display" label=<
Display
1typeDeviceTypeEnum
2commonDispCommon
dispType
3i2cI2CDisplay
4spiSPIDisplay
>]; + Node_Ja_121 [shape=plaintext tooltip="DACModelEnum" label=<
enum DACModelEnum
UNSPECIFIED_MODEL0
TAS57xx1
TAS57132
AC1013
WM89784
ES83885
I2S6
>]; + Node_Ja_141 [shape=plaintext tooltip="platform.EthSPI" label=<
EthSPI
1csGPIO
2speedint32
3intrGPIO
4hostint32
>]; + Node_Ja_131 [shape=plaintext tooltip="platform.ButtonActions" label=<
ButtonActions
1pressedButtonAction
2releasedButtonAction
>]; + Node_Ja_125 [shape=plaintext tooltip="DisplayDriverEnum" label=<
enum DisplayDriverEnum
UNSPECIFIED_DRIVER0
SSD13061
SSD13222
SSD13263
SSD13274
SH11065
SSD16756
ST77357
ST77898
ILI93419
ILI9341_2410
SSD135111
>]; + Node_Ja_109 [shape=plaintext tooltip="platform.GPIOExp" label=<
GPIOExp
1modelGPIOExpModelEnum
2addrint32
ExpType
3i2cGPIOExpI2C
4spiGPIOExpSPI
5baseint32
6countint32
7intrGPIO
>]; + Node_Ja_127 [shape=plaintext tooltip="platform.SPIDisplay" label=<
SPIDisplay
1csGPIO
4speedint32
5rotatebool
>]; + Node_Ja_101 [shape=plaintext tooltip="PortEnum" label=<
enum PortEnum
UNSPECIFIED_SYSTPORT0
SYSTEM1
DAC_PORT2
>]; + Node_Ja_147 [shape=plaintext tooltip="platform.LEDStrip" label=<
LEDStrip
1WS2812WS2812
>]; + Node_Ja_102 [shape=plaintext tooltip="HostEnum" label=<
enum HostEnum
UNSPECIFIED_HOST0
Host01
Host12
>]; + Node_Ja_123 [shape=plaintext tooltip="platform.DAC" label=<
DAC
1bckGPIO
2wsGPIO
3doutGPIO
4mckMCKEnum
5muteGPIO
6modelDACModelEnum
7i2cI2CBus
8daccontrolsetDacControlSet
>]; + Node_Ja_132 [shape=plaintext tooltip="platform.Button" label=<
Button
1gpioGPIO
2pullbool
3debounceint32
4shifterGPIO
5longdurationint32
6normalButtonActions
7longpressButtonActions
8shiftedButtonActions
9longshiftedButtonActions
>]; + Node_Ja_111 [shape=plaintext tooltip="platform.I2CBus" label=<
I2CBus
1portI2CPortEnum
2speedint32
3sdaGPIO
4sclGPIO
>]; + Node_Ja_112 [shape=plaintext tooltip="platform.DacControlSet" label=<
DacControlSet
[...]1commandsControlCommand
>]; + Node_Ja_133 [shape=plaintext tooltip="platform.KnobOnly" label=<
KnobOnly
1enablebool
2delay_msint32
>]; + Node_Ja_118 [shape=plaintext tooltip="platform.GpioAction" label=<
GpioAction
1gpioint32
2levelGpioActionLevel
>]; + Node_Ja_120 [shape=plaintext tooltip="Mode" label=<
enum Mode
REG_MODE_NOTHING0
REG_MODE_OR1
REG_MODE_AND2
>]; + Node_Ja_117 [shape=plaintext tooltip="GpioActionLevel" label=<
enum GpioActionLevel
ACTION_LEVEL_UNDEFINED0
ACTION_LEVEL_11
ACTION_LEVEL_02
>]; + Node_Ja_122 [shape=plaintext tooltip="MCKEnum" label=<
enum MCKEnum
UNSPECIFIED_MCK0
MCK01
MCK12
MCK23
>]; + Node_Ja_135 [shape=plaintext tooltip="BatteryChannelEnum" label=<
enum BatteryChannelEnum
UNSPECIFIED_CH0
CH01
CH12
CH23
CH34
CH45
CH56
CH67
CH78
>]; + Node_Ja_142 [shape=plaintext tooltip="platform.EthRMII" label=<
EthRMII
1mdcGPIO
2mdioGPIO
>]; + Node_Ja_130 [shape=plaintext tooltip="ButtonAction" label=<
enum ButtonAction
ACTRLS_NONE0
ACTRLS_POWER1
ACTRLS_VOLUP2
ACTRLS_VOLDOWN3
ACTRLS_TOGGLE4
ACTRLS_PLAY5
ACTRLS_PAUSE6
ACTRLS_STOP7
ACTRLS_REW8
ACTRLS_FWD9
ACTRLS_PREV10
ACTRLS_NEXT11
BCTRLS_UP12
BCTRLS_DOWN13
BCTRLS_LEFT14
BCTRLS_RIGHT15
BCTRLS_PS116
BCTRLS_PS217
BCTRLS_PS318
BCTRLS_PS419
BCTRLS_PS520
BCTRLS_PS621
BCTRLS_PS722
BCTRLS_PS823
BCTRLS_PS924
BCTRLS_PS1025
KNOB_LEFT26
KNOB_RIGHT27
KNOB_PUSH28
ACTRLS_SLEEP29
>]; + Node_Ja_119 [shape=plaintext tooltip="platform.DelayAction" label=<
DelayAction
1delayint32
>]; + Node_Ja_146 [shape=plaintext tooltip="platform.WS2812" label=<
WS2812
1lengthint32
2gpioGPIO
>]; + Node_Ja_104 [shape=plaintext tooltip="platform.GPIO" label=<
GPIO
1pinint32
2levelint32
>]; + Node_Ja_106 [shape=plaintext tooltip="GPIOExpModelEnum" label=<
enum GPIOExpModelEnum
UNSPECIFIED_EXP0
PCA95351
PCA85XX2
MCP230173
MCP23S174
>]; + Node_Ja_126 [shape=plaintext tooltip="platform.I2CDisplay" label=<
I2CDisplay
1addressint32
>]; + Node_Ja_114 [shape=plaintext tooltip="ControlCommandType" label=<
enum ControlCommandType
INIT0
POWER_ON1
POWER_OFF2
SPEAKER_ON3
SPEAKER_OFF4
HEADSET_ON5
HEADSET_OFF6
>]; + Node_Ja_115 [shape=plaintext tooltip="platform.ControlItem" label=<
ControlItem
item_type
1reg_actionRegisterAction
2gpio_actionGpioAction
3delay_actionDelayAction
>]; + Node_Ja_116 [shape=plaintext tooltip="platform.RegisterAction" label=<
RegisterAction
1regint32
2valint32
3modeMode
>]; + Node_Ja_148 [shape=plaintext tooltip="platform.Dev" label=<
Dev
1spiSPIBus
2i2cI2CBus
3dacDAC
4spdifSPDIF
5displayDisplay
[...]6gpio_expGPIOExp
7led_stripLEDStrip
8rotaryRotary
[...]9buttonsButton
10ethEth
11batteryBattery
>]; + Node_Ja_140 [shape=plaintext tooltip="platform.EthCommon" label=<
EthCommon
1modelEthModelEnum
2rstGPIO
>]; + Node_Ja_124 [shape=plaintext tooltip="platform.DispOffsets" label=<
DispOffsets
1heightint32
2widthint32
>]; + Node_Ja_137 [shape=plaintext tooltip="platform.Battery" label=<
Battery
1channelBatteryChannelEnum
2scalefloat
3cellsint32
4attenBatteryAttenEnum
>]; + Node_Ja_143 [shape=plaintext tooltip="platform.Eth" label=<
Eth
1typeDeviceTypeEnum
2commonEthCommon
ethType
3spiEthSPI
4rmiiEthRMII
>]; + Node_Ja_134 [shape=plaintext tooltip="platform.Rotary" label=<
Rotary
1AGPIO
2BGPIO
3SWGPIO
4knobonlyKnobOnly
5volumebool
6longpressbool
>]; + Node_Ja_136 [shape=plaintext tooltip="BatteryAttenEnum" label=<
enum BatteryAttenEnum
UNSPECIFIED_ATT0
ATT_01
ATT_12
ATT_23
ATT_34
>]; + Node_Ja_107 [shape=plaintext tooltip="platform.GPIOExpSPI" label=<
GPIOExpSPI
1speedint32
2hostHostEnum
3csGPIO
>]; + Node_Ja_128 [shape=plaintext tooltip="platform.DispCommon" label=<
DispCommon
1widthint32
2heightint32
3HFlipbool
4VFlipbool
5driverDisplayDriverEnum
6bitDepthint32
7backGPIO
8resetGPIO
9readyGPIO
10offsetsDispOffsets
>]; + Node_Ja_113 [shape=plaintext tooltip="platform.ControlCommand" label=<
ControlCommand
1typeControlCommandType
[...]2itemsControlItem
>]; + Node_Ja_145 [shape=plaintext tooltip="platform.SPIBus" label=<
SPIBus
1mosiGPIO
2misoGPIO
3clkGPIO
4dcGPIO
5hostHostEnum
>]; + Node_Ja_100 [shape=plaintext tooltip="DeviceTypeEnum" label=<
enum DeviceTypeEnum
UNSPECIFIED_TYPE0
DEVTYPE_SPI1
DEVTYPE_I2C2
DEVTYPE__RMII3
>]; + Node_Ja_108 [shape=plaintext tooltip="platform.GPIOExpI2C" label=<
GPIOExpI2C
5portPortEnum
>]; + Node_Ja_110 [shape=plaintext tooltip="I2CPortEnum" label=<
enum I2CPortEnum
UNSPECIFIED_PORT0
I2CPort01
I2CPort12
>]; + Node_Ja_138 [shape=plaintext tooltip="EthModelEnum" label=<
enum EthModelEnum
UNSPECIFIED_ETHMODEL0
LAN87201
DM90512
W55003
>]; + + /* ------ connections ------ */ + Node_Ja_147:poWS2812:e -> Node_Ja_146:header [color="#000000" tooltip="Ja_147 --> Ja_146"]; + Node_Ja_148:pobuttons:e -> Node_Ja_132:header [color="#000000" tooltip="Ja_148 --> Ja_132"]; + Node_Ja_148:poi2c:e -> Node_Ja_111:header [color="#000000" tooltip="Ja_148 --> Ja_111"]; + Node_Ja_128:podriver:e -> Node_Ja_125 [color="#008000" tooltip="Ja_128 --> Ja_125"]; + Node_Ja_118:polevel:e -> Node_Ja_117 [color="#008000" tooltip="Ja_118 --> Ja_117"]; + Node_Ja_145:podc:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_145 --> Ja_104"]; + Node_Ja_137:pochannel:e -> Node_Ja_135 [color="#008000" tooltip="Ja_137 --> Ja_135"]; + Node_Ja_129:potype:e -> Node_Ja_100 [color="#008000" tooltip="Ja_129 --> Ja_100"]; + Node_Ja_140:porst:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_140 --> Ja_104"]; + Node_Ja_131:popressed:e -> Node_Ja_130 [color="#008000" tooltip="Ja_131 --> Ja_130"]; + Node_Ja_143:pocommon:e -> Node_Ja_140:header [color="#000000" tooltip="Ja_143 --> Ja_140"]; + Node_Ja_143:potype:e -> Node_Ja_100 [color="#008000" tooltip="Ja_143 --> Ja_100"]; + Node_Ja_109:pomodel:e -> Node_Ja_106 [color="#008000" tooltip="Ja_109 --> Ja_106"]; + Node_Ja_132:ponormal:e -> Node_Ja_131:header [color="#000000" tooltip="Ja_132 --> Ja_131"]; + Node_Ja_148:podac:e -> Node_Ja_123:header [color="#000000" tooltip="Ja_148 --> Ja_123"]; + Node_Ja_123:pomute:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_123 --> Ja_104"]; + Node_Ja_134:poknobonly:e -> Node_Ja_133:header [color="#000000" tooltip="Ja_134 --> Ja_133"]; + Node_Ja_113:poitems:e -> Node_Ja_115:header [color="#000000" tooltip="Ja_113 --> Ja_115"]; + Node_Ja_148:porotary:e -> Node_Ja_134:header [color="#000000" tooltip="Ja_148 --> Ja_134"]; + Node_Ja_132:polongpress:e -> Node_Ja_131:header [color="#000000" tooltip="Ja_132 --> Ja_131"]; + Node_Ja_142:pomdc:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_142 --> Ja_104"]; + Node_Ja_128:poreset:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_128 --> Ja_104"]; + Node_Ja_140:pomodel:e -> Node_Ja_138 [color="#008000" tooltip="Ja_140 --> Ja_138"]; + Node_Ja_113:potype:e -> Node_Ja_114 [color="#008000" tooltip="Ja_113 --> Ja_114"]; + Node_Ja_115:pogpio_action:e -> Node_Ja_118:header [color="#000000" tooltip="Ja_115 --> Ja_118"]; + Node_Ja_146:pogpio:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_146 --> Ja_104"]; + Node_Ja_123:podaccontrolset:e -> Node_Ja_112:header [color="#000000" tooltip="Ja_123 --> Ja_112"]; + Node_Ja_132:poshifter:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_132 --> Ja_104"]; + Node_Ja_132:polongshifted:e -> Node_Ja_131:header [color="#000000" tooltip="Ja_132 --> Ja_131"]; + Node_Ja_109:pospi:e -> Node_Ja_107:header [color="#000000" tooltip="Ja_109 --> Ja_107"]; + Node_Ja_111:posda:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_111 --> Ja_104"]; + Node_Ja_127:pocs:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_127 --> Ja_104"]; + Node_Ja_128:poback:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_128 --> Ja_104"]; + Node_Ja_145:poclk:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_145 --> Ja_104"]; + Node_Ja_145:pohost:e -> Node_Ja_102 [color="#008000" tooltip="Ja_145 --> Ja_102"]; + Node_Ja_137:poatten:e -> Node_Ja_136 [color="#008000" tooltip="Ja_137 --> Ja_136"]; + Node_Ja_143:pormii:e -> Node_Ja_142:header [color="#000000" tooltip="Ja_143 --> Ja_142"]; + Node_Ja_141:pointr:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_141 --> Ja_104"]; + Node_Ja_115:podelay_action:e -> Node_Ja_119:header [color="#000000" tooltip="Ja_115 --> Ja_119"]; + Node_Ja_109:pointr:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_109 --> Ja_104"]; + Node_Ja_134:poB:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_134 --> Ja_104"]; + Node_Ja_111:poport:e -> Node_Ja_110 [color="#008000" tooltip="Ja_111 --> Ja_110"]; + Node_Ja_112:pocommands:e -> Node_Ja_113:header [color="#000000" tooltip="Ja_112 --> Ja_113"]; + Node_Ja_148:poeth:e -> Node_Ja_143:header [color="#000000" tooltip="Ja_148 --> Ja_143"]; + Node_Ja_131:poreleased:e -> Node_Ja_130 [color="#008000" tooltip="Ja_131 --> Ja_130"]; + Node_Ja_129:poi2c:e -> Node_Ja_126:header [color="#000000" tooltip="Ja_129 --> Ja_126"]; + Node_Ja_141:pocs:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_141 --> Ja_104"]; + Node_Ja_132:pogpio:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_132 --> Ja_104"]; + Node_Ja_148:pospdif:e -> Node_Ja_144:header [color="#000000" tooltip="Ja_148 --> Ja_144"]; + Node_Ja_148:pobattery:e -> Node_Ja_137:header [color="#000000" tooltip="Ja_148 --> Ja_137"]; + Node_Ja_148:podisplay:e -> Node_Ja_129:header [color="#000000" tooltip="Ja_148 --> Ja_129"]; + Node_Ja_134:poA:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_134 --> Ja_104"]; + Node_Ja_134:poSW:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_134 --> Ja_104"]; + Node_Ja_129:pocommon:e -> Node_Ja_128:header [color="#000000" tooltip="Ja_129 --> Ja_128"]; + Node_Ja_116:pomode:e -> Node_Ja_120 [color="#008000" tooltip="Ja_116 --> Ja_120"]; + Node_Ja_145:pomiso:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_145 --> Ja_104"]; + Node_Ja_144:poclk:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_144 --> Ja_104"]; + Node_Ja_123:podout:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_123 --> Ja_104"]; + Node_Ja_109:poi2c:e -> Node_Ja_108:header [color="#000000" tooltip="Ja_109 --> Ja_108"]; + Node_Ja_107:pohost:e -> Node_Ja_102 [color="#008000" tooltip="Ja_107 --> Ja_102"]; + Node_Ja_145:pomosi:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_145 --> Ja_104"]; + Node_Ja_144:podc:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_144 --> Ja_104"]; + Node_Ja_123:pobck:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_123 --> Ja_104"]; + Node_Ja_123:poi2c:e -> Node_Ja_111:header [color="#000000" tooltip="Ja_123 --> Ja_111"]; + Node_Ja_123:pomck:e -> Node_Ja_122 [color="#008000" tooltip="Ja_123 --> Ja_122"]; + Node_Ja_107:pocs:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_107 --> Ja_104"]; + Node_Ja_108:poport:e -> Node_Ja_101 [color="#008000" tooltip="Ja_108 --> Ja_101"]; + Node_Ja_128:pooffsets:e -> Node_Ja_124:header [color="#000000" tooltip="Ja_128 --> Ja_124"]; + Node_Ja_128:poready:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_128 --> Ja_104"]; + Node_Ja_144:podata:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_144 --> Ja_104"]; + Node_Ja_123:pows:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_123 --> Ja_104"]; + Node_Ja_143:pospi:e -> Node_Ja_141:header [color="#000000" tooltip="Ja_143 --> Ja_141"]; + Node_Ja_132:poshifted:e -> Node_Ja_131:header [color="#000000" tooltip="Ja_132 --> Ja_131"]; + Node_Ja_111:poscl:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_111 --> Ja_104"]; + Node_Ja_129:pospi:e -> Node_Ja_127:header [color="#000000" tooltip="Ja_129 --> Ja_127"]; + Node_Ja_142:pomdio:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_142 --> Ja_104"]; + Node_Ja_115:poreg_action:e -> Node_Ja_116:header [color="#000000" tooltip="Ja_115 --> Ja_116"]; + Node_Ja_148:poled_strip:e -> Node_Ja_147:header [color="#000000" tooltip="Ja_148 --> Ja_147"]; + Node_Ja_148:pospi:e -> Node_Ja_145:header [color="#000000" tooltip="Ja_148 --> Ja_145"]; + Node_Ja_148:pogpio_exp:e -> Node_Ja_109:header [color="#000000" tooltip="Ja_148 --> Ja_109"]; + Node_Ja_123:pomodel:e -> Node_Ja_121 [color="#008000" tooltip="Ja_123 --> Ja_121"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:16 EST */ +} diff --git a/protobuf/generated/Devices.dot.png b/protobuf/generated/Devices.dot.png new file mode 100644 index 00000000..3211a822 Binary files /dev/null and b/protobuf/generated/Devices.dot.png differ diff --git a/protobuf/generated/Devices.dot.svg b/protobuf/generated/Devices.dot.svg new file mode 100644 index 00000000..3e2b7683 --- /dev/null +++ b/protobuf/generated/Devices.dot.svg @@ -0,0 +1,2155 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_144 + + + +SPDIF +1 +dc + +GPIO +2 +data + +GPIO +3 +clk + +GPIO + + + + + + +Node_Ja_104 + + + +GPIO +1 +pin + +int32 +2 +level + +int32 + + + + + + +Node_Ja_144:e->Node_Ja_104:header + + + + + + + + +Node_Ja_144:e->Node_Ja_104:header + + + + + + + + +Node_Ja_144:e->Node_Ja_104:header + + + + + + + + +Node_Ja_129 + + + +Display +1 +type + +DeviceTypeEnum +2 +common + +DispCommon + +dispType + +3 +i2c + +I2CDisplay + +4 +spi + +SPIDisplay + + + + + + + +Node_Ja_127 + + + +SPIDisplay +1 +cs + +GPIO +4 +speed + +int32 +5 +rotate + +bool + + + + + + +Node_Ja_129:e->Node_Ja_127:header + + + + + + + + +Node_Ja_126 + + + +I2CDisplay +1 +address + +int32 + + + + + + +Node_Ja_129:e->Node_Ja_126:header + + + + + + + + +Node_Ja_128 + + + +DispCommon +1 +width + +int32 +2 +height + +int32 +3 +HFlip + +bool +4 +VFlip + +bool +5 +driver + +DisplayDriverEnum +6 +bitDepth + +int32 +7 +back + +GPIO +8 +reset + +GPIO +9 +ready + +GPIO +10 +offsets + +DispOffsets + + + + + + +Node_Ja_129:e->Node_Ja_128:header + + + + + + + + +Node_Ja_100 + + + +enum +DeviceTypeEnum + +UNSPECIFIED_TYPE + +0 + +DEVTYPE_SPI + +1 + +DEVTYPE_I2C + +2 + +DEVTYPE__RMII + +3 + + + + + + +Node_Ja_129:e->Node_Ja_100 + + + + + + + + +Node_Ja_121 + + + +enum +DACModelEnum + +UNSPECIFIED_MODEL + +0 + +TAS57xx + +1 + +TAS5713 + +2 + +AC101 + +3 + +WM8978 + +4 + +ES8388 + +5 + +I2S + +6 + + + + + + +Node_Ja_141 + + + +EthSPI +1 +cs + +GPIO +2 +speed + +int32 +3 +intr + +GPIO +4 +host + +int32 + + + + + + +Node_Ja_141:e->Node_Ja_104:header + + + + + + + + +Node_Ja_141:e->Node_Ja_104:header + + + + + + + + +Node_Ja_131 + + + +ButtonActions +1 +pressed + +ButtonAction +2 +released + +ButtonAction + + + + + + +Node_Ja_130 + + + +enum +ButtonAction + +ACTRLS_NONE + +0 + +ACTRLS_POWER + +1 + +ACTRLS_VOLUP + +2 + +ACTRLS_VOLDOWN + +3 + +ACTRLS_TOGGLE + +4 + +ACTRLS_PLAY + +5 + +ACTRLS_PAUSE + +6 + +ACTRLS_STOP + +7 + +ACTRLS_REW + +8 + +ACTRLS_FWD + +9 + +ACTRLS_PREV + +10 + +ACTRLS_NEXT + +11 + +BCTRLS_UP + +12 + +BCTRLS_DOWN + +13 + +BCTRLS_LEFT + +14 + +BCTRLS_RIGHT + +15 + +BCTRLS_PS1 + +16 + +BCTRLS_PS2 + +17 + +BCTRLS_PS3 + +18 + +BCTRLS_PS4 + +19 + +BCTRLS_PS5 + +20 + +BCTRLS_PS6 + +21 + +BCTRLS_PS7 + +22 + +BCTRLS_PS8 + +23 + +BCTRLS_PS9 + +24 + +BCTRLS_PS10 + +25 + +KNOB_LEFT + +26 + +KNOB_RIGHT + +27 + +KNOB_PUSH + +28 + +ACTRLS_SLEEP + +29 + + + + + + +Node_Ja_131:e->Node_Ja_130 + + + + + + + + +Node_Ja_131:e->Node_Ja_130 + + + + + + + + +Node_Ja_125 + + + +enum +DisplayDriverEnum + +UNSPECIFIED_DRIVER + +0 + +SSD1306 + +1 + +SSD1322 + +2 + +SSD1326 + +3 + +SSD1327 + +4 + +SH1106 + +5 + +SSD1675 + +6 + +ST7735 + +7 + +ST7789 + +8 + +ILI9341 + +9 + +ILI9341_24 + +10 + +SSD1351 + +11 + + + + + + +Node_Ja_109 + + + +GPIOExp +1 +model + +GPIOExpModelEnum +2 +addr + +int32 + +ExpType + +3 +i2c + +GPIOExpI2C + +4 +spi + +GPIOExpSPI + +5 +base + +int32 +6 +count + +int32 +7 +intr + +GPIO + + + + + + +Node_Ja_109:e->Node_Ja_104:header + + + + + + + + +Node_Ja_106 + + + +enum +GPIOExpModelEnum + +UNSPECIFIED_EXP + +0 + +PCA9535 + +1 + +PCA85XX + +2 + +MCP23017 + +3 + +MCP23S17 + +4 + + + + + + +Node_Ja_109:e->Node_Ja_106 + + + + + + + + +Node_Ja_107 + + + +GPIOExpSPI +1 +speed + +int32 +2 +host + +HostEnum +3 +cs + +GPIO + + + + + + +Node_Ja_109:e->Node_Ja_107:header + + + + + + + + +Node_Ja_108 + + + +GPIOExpI2C +5 +port + +PortEnum + + + + + + +Node_Ja_109:e->Node_Ja_108:header + + + + + + + + +Node_Ja_127:e->Node_Ja_104:header + + + + + + + + +Node_Ja_101 + + + +enum +PortEnum + +UNSPECIFIED_SYSTPORT + +0 + +SYSTEM + +1 + +DAC_PORT + +2 + + + + + + +Node_Ja_147 + + + +LEDStrip +1 +WS2812 + +WS2812 + + + + + + +Node_Ja_146 + + + +WS2812 +1 +length + +int32 +2 +gpio + +GPIO + + + + + + +Node_Ja_147:e->Node_Ja_146:header + + + + + + + + +Node_Ja_102 + + + +enum +HostEnum + +UNSPECIFIED_HOST + +0 + +Host0 + +1 + +Host1 + +2 + + + + + + +Node_Ja_123 + + + +DAC +1 +bck + +GPIO +2 +ws + +GPIO +3 +dout + +GPIO +4 +mck + +MCKEnum +5 +mute + +GPIO +6 +model + +DACModelEnum +7 +i2c + +I2CBus +8 +daccontrolset + +DacControlSet + + + + + + +Node_Ja_123:e->Node_Ja_121 + + + + + + + + +Node_Ja_111 + + + +I2CBus +1 +port + +I2CPortEnum +2 +speed + +int32 +3 +sda + +GPIO +4 +scl + +GPIO + + + + + + +Node_Ja_123:e->Node_Ja_111:header + + + + + + + + +Node_Ja_112 + + + +DacControlSet +[...] +1 +commands + +ControlCommand + + + + + + +Node_Ja_123:e->Node_Ja_112:header + + + + + + + + +Node_Ja_122 + + + +enum +MCKEnum + +UNSPECIFIED_MCK + +0 + +MCK0 + +1 + +MCK1 + +2 + +MCK2 + +3 + + + + + + +Node_Ja_123:e->Node_Ja_122 + + + + + + + + +Node_Ja_123:e->Node_Ja_104:header + + + + + + + + +Node_Ja_123:e->Node_Ja_104:header + + + + + + + + +Node_Ja_123:e->Node_Ja_104:header + + + + + + + + +Node_Ja_123:e->Node_Ja_104:header + + + + + + + + +Node_Ja_132 + + + +Button +1 +gpio + +GPIO +2 +pull + +bool +3 +debounce + +int32 +4 +shifter + +GPIO +5 +longduration + +int32 +6 +normal + +ButtonActions +7 +longpress + +ButtonActions +8 +shifted + +ButtonActions +9 +longshifted + +ButtonActions + + + + + + +Node_Ja_132:e->Node_Ja_131:header + + + + + + + + +Node_Ja_132:e->Node_Ja_131:header + + + + + + + + +Node_Ja_132:e->Node_Ja_131:header + + + + + + + + +Node_Ja_132:e->Node_Ja_131:header + + + + + + + + +Node_Ja_132:e->Node_Ja_104:header + + + + + + + + +Node_Ja_132:e->Node_Ja_104:header + + + + + + + + +Node_Ja_111:e->Node_Ja_104:header + + + + + + + + +Node_Ja_111:e->Node_Ja_104:header + + + + + + + + +Node_Ja_110 + + + +enum +I2CPortEnum + +UNSPECIFIED_PORT + +0 + +I2CPort0 + +1 + +I2CPort1 + +2 + + + + + + +Node_Ja_111:e->Node_Ja_110 + + + + + + + + +Node_Ja_113 + + + +ControlCommand +1 +type + +ControlCommandType +[...] +2 +items + +ControlItem + + + + + + +Node_Ja_112:e->Node_Ja_113:header + + + + + + + + +Node_Ja_133 + + + +KnobOnly +1 +enable + +bool +2 +delay_ms + +int32 + + + + + + +Node_Ja_118 + + + +GpioAction +1 +gpio + +int32 +2 +level + +GpioActionLevel + + + + + + +Node_Ja_117 + + + +enum +GpioActionLevel + +ACTION_LEVEL_UNDEFINED + +0 + +ACTION_LEVEL_1 + +1 + +ACTION_LEVEL_0 + +2 + + + + + + +Node_Ja_118:e->Node_Ja_117 + + + + + + + + +Node_Ja_120 + + + +enum +Mode + +REG_MODE_NOTHING + +0 + +REG_MODE_OR + +1 + +REG_MODE_AND + +2 + + + + + + +Node_Ja_135 + + + +enum +BatteryChannelEnum + +UNSPECIFIED_CH + +0 + +CH0 + +1 + +CH1 + +2 + +CH2 + +3 + +CH3 + +4 + +CH4 + +5 + +CH5 + +6 + +CH6 + +7 + +CH7 + +8 + + + + + + +Node_Ja_142 + + + +EthRMII +1 +mdc + +GPIO +2 +mdio + +GPIO + + + + + + +Node_Ja_142:e->Node_Ja_104:header + + + + + + + + +Node_Ja_142:e->Node_Ja_104:header + + + + + + + + +Node_Ja_119 + + + +DelayAction +1 +delay + +int32 + + + + + + +Node_Ja_146:e->Node_Ja_104:header + + + + + + + + +Node_Ja_114 + + + +enum +ControlCommandType + +INIT + +0 + +POWER_ON + +1 + +POWER_OFF + +2 + +SPEAKER_ON + +3 + +SPEAKER_OFF + +4 + +HEADSET_ON + +5 + +HEADSET_OFF + +6 + + + + + + +Node_Ja_115 + + + +ControlItem + +item_type + +1 +reg_action + +RegisterAction + +2 +gpio_action + +GpioAction + +3 +delay_action + +DelayAction + + + + + + + +Node_Ja_115:e->Node_Ja_118:header + + + + + + + + +Node_Ja_115:e->Node_Ja_119:header + + + + + + + + +Node_Ja_116 + + + +RegisterAction +1 +reg + +int32 +2 +val + +int32 +3 +mode + +Mode + + + + + + +Node_Ja_115:e->Node_Ja_116:header + + + + + + + + +Node_Ja_116:e->Node_Ja_120 + + + + + + + + +Node_Ja_148 + + + +Dev +1 +spi + +SPIBus +2 +i2c + +I2CBus +3 +dac + +DAC +4 +spdif + +SPDIF +5 +display + +Display +[...] +6 +gpio_exp + +GPIOExp +7 +led_strip + +LEDStrip +8 +rotary + +Rotary +[...] +9 +buttons + +Button +10 +eth + +Eth +11 +battery + +Battery + + + + + + +Node_Ja_148:e->Node_Ja_144:header + + + + + + + + +Node_Ja_148:e->Node_Ja_129:header + + + + + + + + +Node_Ja_148:e->Node_Ja_109:header + + + + + + + + +Node_Ja_148:e->Node_Ja_147:header + + + + + + + + +Node_Ja_148:e->Node_Ja_123:header + + + + + + + + +Node_Ja_148:e->Node_Ja_132:header + + + + + + + + +Node_Ja_148:e->Node_Ja_111:header + + + + + + + + +Node_Ja_137 + + + +Battery +1 +channel + +BatteryChannelEnum +2 +scale + +float +3 +cells + +int32 +4 +atten + +BatteryAttenEnum + + + + + + +Node_Ja_148:e->Node_Ja_137:header + + + + + + + + +Node_Ja_143 + + + +Eth +1 +type + +DeviceTypeEnum +2 +common + +EthCommon + +ethType + +3 +spi + +EthSPI + +4 +rmii + +EthRMII + + + + + + + +Node_Ja_148:e->Node_Ja_143:header + + + + + + + + +Node_Ja_134 + + + +Rotary +1 +A + +GPIO +2 +B + +GPIO +3 +SW + +GPIO +4 +knobonly + +KnobOnly +5 +volume + +bool +6 +longpress + +bool + + + + + + +Node_Ja_148:e->Node_Ja_134:header + + + + + + + + +Node_Ja_145 + + + +SPIBus +1 +mosi + +GPIO +2 +miso + +GPIO +3 +clk + +GPIO +4 +dc + +GPIO +5 +host + +HostEnum + + + + + + +Node_Ja_148:e->Node_Ja_145:header + + + + + + + + +Node_Ja_140 + + + +EthCommon +1 +model + +EthModelEnum +2 +rst + +GPIO + + + + + + +Node_Ja_140:e->Node_Ja_104:header + + + + + + + + +Node_Ja_138 + + + +enum +EthModelEnum + +UNSPECIFIED_ETHMODEL + +0 + +LAN8720 + +1 + +DM9051 + +2 + +W5500 + +3 + + + + + + +Node_Ja_140:e->Node_Ja_138 + + + + + + + + +Node_Ja_124 + + + +DispOffsets +1 +height + +int32 +2 +width + +int32 + + + + + + +Node_Ja_137:e->Node_Ja_135 + + + + + + + + +Node_Ja_136 + + + +enum +BatteryAttenEnum + +UNSPECIFIED_ATT + +0 + +ATT_0 + +1 + +ATT_1 + +2 + +ATT_2 + +3 + +ATT_3 + +4 + + + + + + +Node_Ja_137:e->Node_Ja_136 + + + + + + + + +Node_Ja_143:e->Node_Ja_141:header + + + + + + + + +Node_Ja_143:e->Node_Ja_142:header + + + + + + + + +Node_Ja_143:e->Node_Ja_140:header + + + + + + + + +Node_Ja_143:e->Node_Ja_100 + + + + + + + + +Node_Ja_134:e->Node_Ja_133:header + + + + + + + + +Node_Ja_134:e->Node_Ja_104:header + + + + + + + + +Node_Ja_134:e->Node_Ja_104:header + + + + + + + + +Node_Ja_134:e->Node_Ja_104:header + + + + + + + + +Node_Ja_107:e->Node_Ja_102 + + + + + + + + +Node_Ja_107:e->Node_Ja_104:header + + + + + + + + +Node_Ja_128:e->Node_Ja_125 + + + + + + + + +Node_Ja_128:e->Node_Ja_104:header + + + + + + + + +Node_Ja_128:e->Node_Ja_104:header + + + + + + + + +Node_Ja_128:e->Node_Ja_104:header + + + + + + + + +Node_Ja_128:e->Node_Ja_124:header + + + + + + + + +Node_Ja_113:e->Node_Ja_114 + + + + + + + + +Node_Ja_113:e->Node_Ja_115:header + + + + + + + + +Node_Ja_145:e->Node_Ja_102 + + + + + + + + +Node_Ja_145:e->Node_Ja_104:header + + + + + + + + +Node_Ja_145:e->Node_Ja_104:header + + + + + + + + +Node_Ja_145:e->Node_Ja_104:header + + + + + + + + +Node_Ja_145:e->Node_Ja_104:header + + + + + + + + +Node_Ja_108:e->Node_Ja_101 + + + + + + + + diff --git a/protobuf/generated/Display.dot b/protobuf/generated/Display.dot new file mode 100644 index 00000000..21a1a96f --- /dev/null +++ b/protobuf/generated/Display.dot @@ -0,0 +1,46 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/Display.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_104 [shape=plaintext tooltip="platform.GPIO" label=<
GPIO
1pinint32
2levelint32
>]; + Node_Ja_111 [shape=plaintext tooltip="DisplayDriverEnum" label=<
enum DisplayDriverEnum
UNSPECIFIED_DRIVER0
SSD13061
SSD13222
SSD13263
SSD13274
SH11065
SSD16756
ST77357
ST77898
ILI93419
ILI9341_2410
SSD135111
>]; + Node_Ja_100 [shape=plaintext tooltip="DeviceTypeEnum" label=<
enum DeviceTypeEnum
UNSPECIFIED_TYPE0
DEVTYPE_SPI1
DEVTYPE_I2C2
DEVTYPE__RMII3
>]; + Node_Ja_110 [shape=plaintext tooltip="platform.DispOffsets" label=<
DispOffsets
1heightint32
2widthint32
>]; + Node_Ja_112 [shape=plaintext tooltip="platform.I2CDisplay" label=<
I2CDisplay
1addressint32
>]; + Node_Ja_113 [shape=plaintext tooltip="platform.SPIDisplay" label=<
SPIDisplay
1csGPIO
4speedint32
5rotatebool
>]; + Node_Ja_114 [shape=plaintext tooltip="platform.DispCommon" label=<
DispCommon
1widthint32
2heightint32
3HFlipbool
4VFlipbool
5driverDisplayDriverEnum
6bitDepthint32
7backGPIO
8resetGPIO
9readyGPIO
10offsetsDispOffsets
>]; + Node_Ja_115 [shape=plaintext tooltip="platform.Display" label=<
Display
1typeDeviceTypeEnum
2commonDispCommon
dispType
3i2cI2CDisplay
4spiSPIDisplay
>]; + + /* ------ connections ------ */ + Node_Ja_114:poback:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_114 --> Ja_104"]; + Node_Ja_114:pooffsets:e -> Node_Ja_110:header [color="#000000" tooltip="Ja_114 --> Ja_110"]; + Node_Ja_115:poi2c:e -> Node_Ja_112:header [color="#000000" tooltip="Ja_115 --> Ja_112"]; + Node_Ja_115:pocommon:e -> Node_Ja_114:header [color="#000000" tooltip="Ja_115 --> Ja_114"]; + Node_Ja_115:potype:e -> Node_Ja_100 [color="#008000" tooltip="Ja_115 --> Ja_100"]; + Node_Ja_114:podriver:e -> Node_Ja_111 [color="#008000" tooltip="Ja_114 --> Ja_111"]; + Node_Ja_114:poreset:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_114 --> Ja_104"]; + Node_Ja_115:pospi:e -> Node_Ja_113:header [color="#000000" tooltip="Ja_115 --> Ja_113"]; + Node_Ja_113:pocs:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_113 --> Ja_104"]; + Node_Ja_114:poready:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_114 --> Ja_104"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:16 EST */ +} diff --git a/protobuf/generated/Display.dot.png b/protobuf/generated/Display.dot.png new file mode 100644 index 00000000..51a1ad25 Binary files /dev/null and b/protobuf/generated/Display.dot.png differ diff --git a/protobuf/generated/Display.dot.svg b/protobuf/generated/Display.dot.svg new file mode 100644 index 00000000..f85af6ed --- /dev/null +++ b/protobuf/generated/Display.dot.svg @@ -0,0 +1,353 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_104 + + + +GPIO +1 +pin + +int32 +2 +level + +int32 + + + + + + +Node_Ja_111 + + + +enum +DisplayDriverEnum + +UNSPECIFIED_DRIVER + +0 + +SSD1306 + +1 + +SSD1322 + +2 + +SSD1326 + +3 + +SSD1327 + +4 + +SH1106 + +5 + +SSD1675 + +6 + +ST7735 + +7 + +ST7789 + +8 + +ILI9341 + +9 + +ILI9341_24 + +10 + +SSD1351 + +11 + + + + + + +Node_Ja_100 + + + +enum +DeviceTypeEnum + +UNSPECIFIED_TYPE + +0 + +DEVTYPE_SPI + +1 + +DEVTYPE_I2C + +2 + +DEVTYPE__RMII + +3 + + + + + + +Node_Ja_110 + + + +DispOffsets +1 +height + +int32 +2 +width + +int32 + + + + + + +Node_Ja_112 + + + +I2CDisplay +1 +address + +int32 + + + + + + +Node_Ja_113 + + + +SPIDisplay +1 +cs + +GPIO +4 +speed + +int32 +5 +rotate + +bool + + + + + + +Node_Ja_113:e->Node_Ja_104:header + + + + + + + + +Node_Ja_114 + + + +DispCommon +1 +width + +int32 +2 +height + +int32 +3 +HFlip + +bool +4 +VFlip + +bool +5 +driver + +DisplayDriverEnum +6 +bitDepth + +int32 +7 +back + +GPIO +8 +reset + +GPIO +9 +ready + +GPIO +10 +offsets + +DispOffsets + + + + + + +Node_Ja_114:e->Node_Ja_104:header + + + + + + + + +Node_Ja_114:e->Node_Ja_104:header + + + + + + + + +Node_Ja_114:e->Node_Ja_104:header + + + + + + + + +Node_Ja_114:e->Node_Ja_111 + + + + + + + + +Node_Ja_114:e->Node_Ja_110:header + + + + + + + + +Node_Ja_115 + + + +Display +1 +type + +DeviceTypeEnum +2 +common + +DispCommon + +dispType + +3 +i2c + +I2CDisplay + +4 +spi + +SPIDisplay + + + + + + + +Node_Ja_115:e->Node_Ja_100 + + + + + + + + +Node_Ja_115:e->Node_Ja_112:header + + + + + + + + +Node_Ja_115:e->Node_Ja_113:header + + + + + + + + +Node_Ja_115:e->Node_Ja_114:header + + + + + + + + diff --git a/protobuf/generated/Ethernet.dot b/protobuf/generated/Ethernet.dot new file mode 100644 index 00000000..31d301dc --- /dev/null +++ b/protobuf/generated/Ethernet.dot @@ -0,0 +1,45 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/Ethernet.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_110 [shape=plaintext tooltip="EthModelEnum" label=<
enum EthModelEnum
UNSPECIFIED_ETHMODEL0
LAN87201
DM90512
W55003
>]; + Node_Ja_100 [shape=plaintext tooltip="DeviceTypeEnum" label=<
enum DeviceTypeEnum
UNSPECIFIED_TYPE0
DEVTYPE_SPI1
DEVTYPE_I2C2
DEVTYPE__RMII3
>]; + Node_Ja_113 [shape=plaintext tooltip="platform.EthSPI" label=<
EthSPI
1csGPIO
2speedint32
3intrGPIO
4hostint32
>]; + Node_Ja_114 [shape=plaintext tooltip="platform.EthRMII" label=<
EthRMII
1mdcGPIO
2mdioGPIO
>]; + Node_Ja_112 [shape=plaintext tooltip="platform.EthCommon" label=<
EthCommon
1modelEthModelEnum
2rstGPIO
>]; + Node_Ja_115 [shape=plaintext tooltip="platform.Eth" label=<
Eth
1typeDeviceTypeEnum
2commonEthCommon
ethType
3spiEthSPI
4rmiiEthRMII
>]; + Node_Ja_104 [shape=plaintext tooltip="platform.GPIO" label=<
GPIO
1pinint32
2levelint32
>]; + + /* ------ connections ------ */ + Node_Ja_113:pocs:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_113 --> Ja_104"]; + Node_Ja_115:pocommon:e -> Node_Ja_112:header [color="#000000" tooltip="Ja_115 --> Ja_112"]; + Node_Ja_115:pospi:e -> Node_Ja_113:header [color="#000000" tooltip="Ja_115 --> Ja_113"]; + Node_Ja_115:potype:e -> Node_Ja_100 [color="#008000" tooltip="Ja_115 --> Ja_100"]; + Node_Ja_113:pointr:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_113 --> Ja_104"]; + Node_Ja_114:pomdio:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_114 --> Ja_104"]; + Node_Ja_114:pomdc:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_114 --> Ja_104"]; + Node_Ja_112:porst:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_112 --> Ja_104"]; + Node_Ja_112:pomodel:e -> Node_Ja_110 [color="#008000" tooltip="Ja_112 --> Ja_110"]; + Node_Ja_115:pormii:e -> Node_Ja_114:header [color="#000000" tooltip="Ja_115 --> Ja_114"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:16 EST */ +} diff --git a/protobuf/generated/Ethernet.dot.png b/protobuf/generated/Ethernet.dot.png new file mode 100644 index 00000000..bb643a8a Binary files /dev/null and b/protobuf/generated/Ethernet.dot.png differ diff --git a/protobuf/generated/Ethernet.dot.svg b/protobuf/generated/Ethernet.dot.svg new file mode 100644 index 00000000..6f9be5f0 --- /dev/null +++ b/protobuf/generated/Ethernet.dot.svg @@ -0,0 +1,278 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_110 + + + +enum +EthModelEnum + +UNSPECIFIED_ETHMODEL + +0 + +LAN8720 + +1 + +DM9051 + +2 + +W5500 + +3 + + + + + + +Node_Ja_100 + + + +enum +DeviceTypeEnum + +UNSPECIFIED_TYPE + +0 + +DEVTYPE_SPI + +1 + +DEVTYPE_I2C + +2 + +DEVTYPE__RMII + +3 + + + + + + +Node_Ja_113 + + + +EthSPI +1 +cs + +GPIO +2 +speed + +int32 +3 +intr + +GPIO +4 +host + +int32 + + + + + + +Node_Ja_104 + + + +GPIO +1 +pin + +int32 +2 +level + +int32 + + + + + + +Node_Ja_113:e->Node_Ja_104:header + + + + + + + + +Node_Ja_113:e->Node_Ja_104:header + + + + + + + + +Node_Ja_114 + + + +EthRMII +1 +mdc + +GPIO +2 +mdio + +GPIO + + + + + + +Node_Ja_114:e->Node_Ja_104:header + + + + + + + + +Node_Ja_114:e->Node_Ja_104:header + + + + + + + + +Node_Ja_112 + + + +EthCommon +1 +model + +EthModelEnum +2 +rst + +GPIO + + + + + + +Node_Ja_112:e->Node_Ja_110 + + + + + + + + +Node_Ja_112:e->Node_Ja_104:header + + + + + + + + +Node_Ja_115 + + + +Eth +1 +type + +DeviceTypeEnum +2 +common + +EthCommon + +ethType + +3 +spi + +EthSPI + +4 +rmii + +EthRMII + + + + + + + +Node_Ja_115:e->Node_Ja_100 + + + + + + + + +Node_Ja_115:e->Node_Ja_113:header + + + + + + + + +Node_Ja_115:e->Node_Ja_114:header + + + + + + + + +Node_Ja_115:e->Node_Ja_112:header + + + + + + + + diff --git a/protobuf/generated/GPIO.dot b/protobuf/generated/GPIO.dot new file mode 100644 index 00000000..2c848377 --- /dev/null +++ b/protobuf/generated/GPIO.dot @@ -0,0 +1,53 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/GPIO.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_107 [shape=plaintext tooltip="platform.GPIOExpSPI" label=<
GPIOExpSPI
1speedint32
2hostHostEnum
3csGPIO
>]; + Node_Ja_108 [shape=plaintext tooltip="platform.GPIOExpI2C" label=<
GPIOExpI2C
5portPortEnum
>]; + Node_Ja_106 [shape=plaintext tooltip="GPIOExpModelEnum" label=<
enum GPIOExpModelEnum
UNSPECIFIED_EXP0
PCA95351
PCA85XX2
MCP230173
MCP23S174
>]; + Node_Ja_102 [shape=plaintext tooltip="HostEnum" label=<
enum HostEnum
UNSPECIFIED_HOST0
Host01
Host12
>]; + Node_Ja_101 [shape=plaintext tooltip="PortEnum" label=<
enum PortEnum
UNSPECIFIED_SYSTPORT0
SYSTEM1
DAC_PORT2
>]; + Node_Ja_104 [shape=plaintext tooltip="platform.GPIO" label=<
GPIO
1pinint32
2levelint32
>]; + Node_Ja_105 [shape=plaintext tooltip="platform.Gpios" label=<
Gpios
1greenLEDGPIO
2redLEDGPIO
3audioJackGPIO
4ampGPIO
5powerGPIO
6irGPIO
7jackGPIO
8spkfaultGPIO
9VccGPIO
10GNDGPIO
>]; + Node_Ja_109 [shape=plaintext tooltip="platform.GPIOExp" label=<
GPIOExp
1modelGPIOExpModelEnum
2addrint32
ExpType
3i2cGPIOExpI2C
4spiGPIOExpSPI
5baseint32
6countint32
7intrGPIO
>]; + + /* ------ connections ------ */ + Node_Ja_105:poir:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_105:poredLED:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_109:pospi:e -> Node_Ja_107:header [color="#000000" tooltip="Ja_109 --> Ja_107"]; + Node_Ja_109:pointr:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_109 --> Ja_104"]; + Node_Ja_105:poaudioJack:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_109:poi2c:e -> Node_Ja_108:header [color="#000000" tooltip="Ja_109 --> Ja_108"]; + Node_Ja_107:pohost:e -> Node_Ja_102 [color="#008000" tooltip="Ja_107 --> Ja_102"]; + Node_Ja_108:poport:e -> Node_Ja_101 [color="#008000" tooltip="Ja_108 --> Ja_101"]; + Node_Ja_105:pogreenLED:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_105:poVcc:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_109:pomodel:e -> Node_Ja_106 [color="#008000" tooltip="Ja_109 --> Ja_106"]; + Node_Ja_107:pocs:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_107 --> Ja_104"]; + Node_Ja_105:popower:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_105:pojack:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_105:pospkfault:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_105:poamp:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_105:poGND:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:16 EST */ +} diff --git a/protobuf/generated/GPIO.dot.png b/protobuf/generated/GPIO.dot.png new file mode 100644 index 00000000..409b3484 Binary files /dev/null and b/protobuf/generated/GPIO.dot.png differ diff --git a/protobuf/generated/GPIO.dot.svg b/protobuf/generated/GPIO.dot.svg new file mode 100644 index 00000000..7ac861a5 --- /dev/null +++ b/protobuf/generated/GPIO.dot.svg @@ -0,0 +1,401 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_107 + + + +GPIOExpSPI +1 +speed + +int32 +2 +host + +HostEnum +3 +cs + +GPIO + + + + + + +Node_Ja_102 + + + +enum +HostEnum + +UNSPECIFIED_HOST + +0 + +Host0 + +1 + +Host1 + +2 + + + + + + +Node_Ja_107:e->Node_Ja_102 + + + + + + + + +Node_Ja_104 + + + +GPIO +1 +pin + +int32 +2 +level + +int32 + + + + + + +Node_Ja_107:e->Node_Ja_104:header + + + + + + + + +Node_Ja_108 + + + +GPIOExpI2C +5 +port + +PortEnum + + + + + + +Node_Ja_101 + + + +enum +PortEnum + +UNSPECIFIED_SYSTPORT + +0 + +SYSTEM + +1 + +DAC_PORT + +2 + + + + + + +Node_Ja_108:e->Node_Ja_101 + + + + + + + + +Node_Ja_106 + + + +enum +GPIOExpModelEnum + +UNSPECIFIED_EXP + +0 + +PCA9535 + +1 + +PCA85XX + +2 + +MCP23017 + +3 + +MCP23S17 + +4 + + + + + + +Node_Ja_105 + + + +Gpios +1 +greenLED + +GPIO +2 +redLED + +GPIO +3 +audioJack + +GPIO +4 +amp + +GPIO +5 +power + +GPIO +6 +ir + +GPIO +7 +jack + +GPIO +8 +spkfault + +GPIO +9 +Vcc + +GPIO +10 +GND + +GPIO + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_109 + + + +GPIOExp +1 +model + +GPIOExpModelEnum +2 +addr + +int32 + +ExpType + +3 +i2c + +GPIOExpI2C + +4 +spi + +GPIOExpSPI + +5 +base + +int32 +6 +count + +int32 +7 +intr + +GPIO + + + + + + +Node_Ja_109:e->Node_Ja_107:header + + + + + + + + +Node_Ja_109:e->Node_Ja_108:header + + + + + + + + +Node_Ja_109:e->Node_Ja_106 + + + + + + + + +Node_Ja_109:e->Node_Ja_104:header + + + + + + + + diff --git a/protobuf/generated/I2CBus.dot b/protobuf/generated/I2CBus.dot new file mode 100644 index 00000000..38453605 --- /dev/null +++ b/protobuf/generated/I2CBus.dot @@ -0,0 +1,34 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/I2CBus.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_111 [shape=plaintext tooltip="platform.I2CBus" label=<
I2CBus
1portI2CPortEnum
2speedint32
3sdaGPIO
4sclGPIO
>]; + Node_Ja_104 [shape=plaintext tooltip="platform.GPIO" label=<
GPIO
1pinint32
2levelint32
>]; + Node_Ja_110 [shape=plaintext tooltip="I2CPortEnum" label=<
enum I2CPortEnum
UNSPECIFIED_PORT0
I2CPort01
I2CPort12
>]; + + /* ------ connections ------ */ + Node_Ja_111:poscl:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_111 --> Ja_104"]; + Node_Ja_111:posda:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_111 --> Ja_104"]; + Node_Ja_111:poport:e -> Node_Ja_110 [color="#008000" tooltip="Ja_111 --> Ja_110"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:16 EST */ +} diff --git a/protobuf/generated/I2CBus.dot.png b/protobuf/generated/I2CBus.dot.png new file mode 100644 index 00000000..6b9daa74 Binary files /dev/null and b/protobuf/generated/I2CBus.dot.png differ diff --git a/protobuf/generated/I2CBus.dot.svg b/protobuf/generated/I2CBus.dot.svg new file mode 100644 index 00000000..ea8d691d --- /dev/null +++ b/protobuf/generated/I2CBus.dot.svg @@ -0,0 +1,113 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_111 + + + +I2CBus +1 +port + +I2CPortEnum +2 +speed + +int32 +3 +sda + +GPIO +4 +scl + +GPIO + + + + + + +Node_Ja_104 + + + +GPIO +1 +pin + +int32 +2 +level + +int32 + + + + + + +Node_Ja_111:e->Node_Ja_104:header + + + + + + + + +Node_Ja_111:e->Node_Ja_104:header + + + + + + + + +Node_Ja_110 + + + +enum +I2CPortEnum + +UNSPECIFIED_PORT + +0 + +I2CPort0 + +1 + +I2CPort1 + +2 + + + + + + +Node_Ja_111:e->Node_Ja_110 + + + + + + + + diff --git a/protobuf/generated/Services.dot b/protobuf/generated/Services.dot new file mode 100644 index 00000000..739774ad --- /dev/null +++ b/protobuf/generated/Services.dot @@ -0,0 +1,61 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/Services.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_119 [shape=plaintext tooltip="DebugComponent" label=<
enum DebugComponent
NONE0
SLIMPROTO1
STREAM2
DECODE3
OUTPUT4
IR5
ALL6
>]; + Node_Ja_125 [shape=plaintext tooltip="platform.Metadata" label=<
Metadata
1formatstring
2speeduint32
3pauseuint32
4artworkArtwork
>]; + Node_Ja_111 [shape=plaintext tooltip="platform.Spotify" label=<
Spotify
1enabledbool
2device_namestring
3bitrateuint32
4zeroconfbool
5volumeuint32
>]; + Node_Ja_112 [shape=plaintext tooltip="platform.AirPlay" label=<
AirPlay
1enabledbool
2device_namestring
3portuint32
>]; + Node_Ja_114 [shape=plaintext tooltip="platform.OutputBT" label=<
OutputBT
1sink_namestring
>]; + Node_Ja_126 [shape=plaintext tooltip="platform.Services" label=<
Services
1metadataMetadata
2sleepSleepService
3ota_urlstring
4cspotSpotify
5airplayAirPlay
6squeezeliteSqueezelite
>]; + Node_Ja_113 [shape=plaintext tooltip="OutputTypeEnum" label=<
enum OutputTypeEnum
OUTPUT_UNKNOWN0
OUTPUT_I2S1
OUTPUT_SPDIF2
OUTPUT_Bluetooth3
>]; + Node_Ja_120 [shape=plaintext tooltip="platform.RatesOption" label=<
RatesOption
1minSampleRate
2maxSampleRate
[...]3listSampleRate
>]; + Node_Ja_118 [shape=plaintext tooltip="DebugLevelEnum" label=<
enum DebugLevelEnum
DEFAULT0
INFO1
DEBUG2
SDEBUG3
>]; + Node_Ja_104 [shape=plaintext tooltip="platform.GPIO" label=<
GPIO
1pinint32
2levelint32
>]; + Node_Ja_110 [shape=plaintext tooltip="platform.Artwork" label=<
Artwork
1enabledbool
2resizebool
>]; + Node_Ja_122 [shape=plaintext tooltip="platform.DebugOption" label=<
DebugOption
1componentDebugComponent
2levelDebugLevelEnum
>]; + Node_Ja_124 [shape=plaintext tooltip="platform.SleepService" label=<
SleepService
1delayuint32
2spuriousint32
3sleepGPIO
[...]4wakeGPIO
[...]5rtcGPIO
6battfloat
>]; + Node_Ja_123 [shape=plaintext tooltip="platform.Squeezelite" label=<
Squeezelite
1output_typeOutputTypeEnum
2ratesRatesOption
3amp_gpio_timeoutint32
4wav_aiff_header_parsingbool
5server_name_ipstring
6server_portuint32
7enabledbool
10device_namestring
11bluetoothOutputBT
[...]12logging_optionsDebugOption
13max_rateuint32
>]; + Node_Ja_117 [shape=plaintext tooltip="SampleRate" label=<
enum SampleRate
SAMPLE_RATE_UNSPECIFIED0
SAMPLE_RATE_80001
SAMPLE_RATE_110252
SAMPLE_RATE_120003
SAMPLE_RATE_160004
SAMPLE_RATE_220505
SAMPLE_RATE_240006
SAMPLE_RATE_320007
SAMPLE_RATE_441008
SAMPLE_RATE_480009
SAMPLE_RATE_8820010
SAMPLE_RATE_9600011
SAMPLE_RATE_17640012
SAMPLE_RATE_19200013
SAMPLE_RATE_35280014
SAMPLE_RATE_38400015
SAMPLE_RATE_70560016
SAMPLE_RATE_76800017
>]; + + /* ------ connections ------ */ + Node_Ja_125:poartwork:e -> Node_Ja_110:header [color="#000000" tooltip="Ja_125 --> Ja_110"]; + Node_Ja_126:pocspot:e -> Node_Ja_111:header [color="#000000" tooltip="Ja_126 --> Ja_111"]; + Node_Ja_123:pologging_options:e -> Node_Ja_122:header [color="#000000" tooltip="Ja_123 --> Ja_122"]; + Node_Ja_123:porates:e -> Node_Ja_120:header [color="#000000" tooltip="Ja_123 --> Ja_120"]; + Node_Ja_122:polevel:e -> Node_Ja_118 [color="#008000" tooltip="Ja_122 --> Ja_118"]; + Node_Ja_124:posleep:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_124 --> Ja_104"]; + Node_Ja_120:pomax:e -> Node_Ja_117 [color="#008000" tooltip="Ja_120 --> Ja_117"]; + Node_Ja_124:portc:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_124 --> Ja_104"]; + Node_Ja_126:posqueezelite:e -> Node_Ja_123:header [color="#000000" tooltip="Ja_126 --> Ja_123"]; + Node_Ja_123:pooutput_type:e -> Node_Ja_113 [color="#008000" tooltip="Ja_123 --> Ja_113"]; + Node_Ja_120:polist:e -> Node_Ja_117 [color="#008000" tooltip="Ja_120 --> Ja_117"]; + Node_Ja_120:pomin:e -> Node_Ja_117 [color="#008000" tooltip="Ja_120 --> Ja_117"]; + Node_Ja_126:pometadata:e -> Node_Ja_125:header [color="#000000" tooltip="Ja_126 --> Ja_125"]; + Node_Ja_126:posleep:e -> Node_Ja_124:header [color="#000000" tooltip="Ja_126 --> Ja_124"]; + Node_Ja_126:poairplay:e -> Node_Ja_112:header [color="#000000" tooltip="Ja_126 --> Ja_112"]; + Node_Ja_123:pobluetooth:e -> Node_Ja_114:header [color="#000000" tooltip="Ja_123 --> Ja_114"]; + Node_Ja_122:pocomponent:e -> Node_Ja_119 [color="#008000" tooltip="Ja_122 --> Ja_119"]; + Node_Ja_124:powake:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_124 --> Ja_104"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:16 EST */ +} diff --git a/protobuf/generated/Services.dot.png b/protobuf/generated/Services.dot.png new file mode 100644 index 00000000..3e5ba23a Binary files /dev/null and b/protobuf/generated/Services.dot.png differ diff --git a/protobuf/generated/Services.dot.svg b/protobuf/generated/Services.dot.svg new file mode 100644 index 00000000..6fe6763c --- /dev/null +++ b/protobuf/generated/Services.dot.svg @@ -0,0 +1,663 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_119 + + + +enum +DebugComponent + +NONE + +0 + +SLIMPROTO + +1 + +STREAM + +2 + +DECODE + +3 + +OUTPUT + +4 + +IR + +5 + +ALL + +6 + + + + + + +Node_Ja_125 + + + +Metadata +1 +format + +string +2 +speed + +uint32 +3 +pause + +uint32 +4 +artwork + +Artwork + + + + + + +Node_Ja_110 + + + +Artwork +1 +enabled + +bool +2 +resize + +bool + + + + + + +Node_Ja_125:e->Node_Ja_110:header + + + + + + + + +Node_Ja_111 + + + +Spotify +1 +enabled + +bool +2 +device_name + +string +3 +bitrate + +uint32 +4 +zeroconf + +bool +5 +volume + +uint32 + + + + + + +Node_Ja_112 + + + +AirPlay +1 +enabled + +bool +2 +device_name + +string +3 +port + +uint32 + + + + + + +Node_Ja_114 + + + +OutputBT +1 +sink_name + +string + + + + + + +Node_Ja_126 + + + +Services +1 +metadata + +Metadata +2 +sleep + +SleepService +3 +ota_url + +string +4 +cspot + +Spotify +5 +airplay + +AirPlay +6 +squeezelite + +Squeezelite + + + + + + +Node_Ja_126:e->Node_Ja_125:header + + + + + + + + +Node_Ja_126:e->Node_Ja_111:header + + + + + + + + +Node_Ja_126:e->Node_Ja_112:header + + + + + + + + +Node_Ja_124 + + + +SleepService +1 +delay + +uint32 +2 +spurious + +int32 +3 +sleep + +GPIO +[...] +4 +wake + +GPIO +[...] +5 +rtc + +GPIO +6 +batt + +float + + + + + + +Node_Ja_126:e->Node_Ja_124:header + + + + + + + + +Node_Ja_123 + + + +Squeezelite +1 +output_type + +OutputTypeEnum +2 +rates + +RatesOption +3 +amp_gpio_timeout + +int32 +4 +wav_aiff_header_parsing + +bool +5 +server_name_ip + +string +6 +server_port + +uint32 +7 +enabled + +bool +10 +device_name + +string +11 +bluetooth + +OutputBT +[...] +12 +logging_options + +DebugOption +13 +max_rate + +uint32 + + + + + + +Node_Ja_126:e->Node_Ja_123:header + + + + + + + + +Node_Ja_113 + + + +enum +OutputTypeEnum + +OUTPUT_UNKNOWN + +0 + +OUTPUT_I2S + +1 + +OUTPUT_SPDIF + +2 + +OUTPUT_Bluetooth + +3 + + + + + + +Node_Ja_120 + + + +RatesOption +1 +min + +SampleRate +2 +max + +SampleRate +[...] +3 +list + +SampleRate + + + + + + +Node_Ja_117 + + + +enum +SampleRate + +SAMPLE_RATE_UNSPECIFIED + +0 + +SAMPLE_RATE_8000 + +1 + +SAMPLE_RATE_11025 + +2 + +SAMPLE_RATE_12000 + +3 + +SAMPLE_RATE_16000 + +4 + +SAMPLE_RATE_22050 + +5 + +SAMPLE_RATE_24000 + +6 + +SAMPLE_RATE_32000 + +7 + +SAMPLE_RATE_44100 + +8 + +SAMPLE_RATE_48000 + +9 + +SAMPLE_RATE_88200 + +10 + +SAMPLE_RATE_96000 + +11 + +SAMPLE_RATE_176400 + +12 + +SAMPLE_RATE_192000 + +13 + +SAMPLE_RATE_352800 + +14 + +SAMPLE_RATE_384000 + +15 + +SAMPLE_RATE_705600 + +16 + +SAMPLE_RATE_768000 + +17 + + + + + + +Node_Ja_120:e->Node_Ja_117 + + + + + + + + +Node_Ja_120:e->Node_Ja_117 + + + + + + + + +Node_Ja_120:e->Node_Ja_117 + + + + + + + + +Node_Ja_118 + + + +enum +DebugLevelEnum + +DEFAULT + +0 + +INFO + +1 + +DEBUG + +2 + +SDEBUG + +3 + + + + + + +Node_Ja_104 + + + +GPIO +1 +pin + +int32 +2 +level + +int32 + + + + + + +Node_Ja_122 + + + +DebugOption +1 +component + +DebugComponent +2 +level + +DebugLevelEnum + + + + + + +Node_Ja_122:e->Node_Ja_119 + + + + + + + + +Node_Ja_122:e->Node_Ja_118 + + + + + + + + +Node_Ja_124:e->Node_Ja_104:header + + + + + + + + +Node_Ja_124:e->Node_Ja_104:header + + + + + + + + +Node_Ja_124:e->Node_Ja_104:header + + + + + + + + +Node_Ja_123:e->Node_Ja_114:header + + + + + + + + +Node_Ja_123:e->Node_Ja_113 + + + + + + + + +Node_Ja_123:e->Node_Ja_120:header + + + + + + + + +Node_Ja_123:e->Node_Ja_122:header + + + + + + + + diff --git a/protobuf/generated/Spotify.dot b/protobuf/generated/Spotify.dot new file mode 100644 index 00000000..1c1e0358 --- /dev/null +++ b/protobuf/generated/Spotify.dot @@ -0,0 +1,29 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/Spotify.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_101 [shape=plaintext tooltip="platform.Spotify" label=<
Spotify
1enabledbool
2device_namestring
3bitrateuint32
4zeroconfbool
5volumeuint32
>]; + + /* ------ connections ------ */ + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:38 EST */ +} diff --git a/protobuf/generated/Spotify.dot.png b/protobuf/generated/Spotify.dot.png new file mode 100644 index 00000000..8e2b38a9 Binary files /dev/null and b/protobuf/generated/Spotify.dot.png differ diff --git a/protobuf/generated/Spotify.dot.svg b/protobuf/generated/Spotify.dot.svg new file mode 100644 index 00000000..bf6c86bc --- /dev/null +++ b/protobuf/generated/Spotify.dot.svg @@ -0,0 +1,47 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_101 + + + +Spotify +1 +enabled + +bool +2 +device_name + +string +3 +bitrate + +uint32 +4 +zeroconf + +bool +5 +volume + +uint32 + + + + + + diff --git a/protobuf/generated/Squeezelite.dot b/protobuf/generated/Squeezelite.dot new file mode 100644 index 00000000..36144ae4 --- /dev/null +++ b/protobuf/generated/Squeezelite.dot @@ -0,0 +1,49 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/Squeezelite.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_110 [shape=plaintext tooltip="platform.DebugOption" label=<
DebugOption
1componentDebugComponent
2levelDebugLevelEnum
>]; + Node_Ja_105 [shape=plaintext tooltip="SampleRate" label=<
enum SampleRate
SAMPLE_RATE_UNSPECIFIED0
SAMPLE_RATE_80001
SAMPLE_RATE_110252
SAMPLE_RATE_120003
SAMPLE_RATE_160004
SAMPLE_RATE_220505
SAMPLE_RATE_240006
SAMPLE_RATE_320007
SAMPLE_RATE_441008
SAMPLE_RATE_480009
SAMPLE_RATE_8820010
SAMPLE_RATE_9600011
SAMPLE_RATE_17640012
SAMPLE_RATE_19200013
SAMPLE_RATE_35280014
SAMPLE_RATE_38400015
SAMPLE_RATE_70560016
SAMPLE_RATE_76800017
>]; + Node_Ja_106 [shape=plaintext tooltip="DebugLevelEnum" label=<
enum DebugLevelEnum
DEFAULT0
INFO1
DEBUG2
SDEBUG3
>]; + Node_Ja_101 [shape=plaintext tooltip="OutputTypeEnum" label=<
enum OutputTypeEnum
OUTPUT_UNKNOWN0
OUTPUT_I2S1
OUTPUT_SPDIF2
OUTPUT_Bluetooth3
>]; + Node_Ja_108 [shape=plaintext tooltip="platform.RatesOption" label=<
RatesOption
1minSampleRate
2maxSampleRate
[...]3listSampleRate
>]; + Node_Ja_109 [shape=plaintext tooltip="platform.BufferOption" label=<
BufferOption
1stream_bufferuint32
2output_vufferuint32
>]; + Node_Ja_111 [shape=plaintext tooltip="platform.Squeezelite" label=<
Squeezelite
1output_typeOutputTypeEnum
2ratesRatesOption
3amp_gpio_timeoutint32
4wav_aiff_header_parsingbool
5server_name_ipstring
6server_portuint32
7enabledbool
10device_namestring
11bluetoothOutputBT
[...]12logging_optionsDebugOption
13max_rateuint32
>]; + Node_Ja_103 [shape=plaintext tooltip="ResampleAlgorithm" label=<
enum ResampleAlgorithm
RESAMPLEDISABLED0
RESAMPLEBASIC_LINEAR1
RESAMPLETHIRTEEN_TAPS2
RESAMPLETWENTY_ONE_TAPS3
>]; + Node_Ja_107 [shape=plaintext tooltip="DebugComponent" label=<
enum DebugComponent
NONE0
SLIMPROTO1
STREAM2
DECODE3
OUTPUT4
IR5
ALL6
>]; + Node_Ja_102 [shape=plaintext tooltip="platform.OutputBT" label=<
OutputBT
1sink_namestring
>]; + Node_Ja_104 [shape=plaintext tooltip="platform.ResampleOptions" label=<
ResampleOptions
1algorithmResampleAlgorithm
2interpolate_filter_coefficientsbool
>]; + + /* ------ connections ------ */ + Node_Ja_108:pomin:e -> Node_Ja_105 [color="#008000" tooltip="Ja_108 --> Ja_105"]; + Node_Ja_111:porates:e -> Node_Ja_108:header [color="#000000" tooltip="Ja_111 --> Ja_108"]; + Node_Ja_111:pooutput_type:e -> Node_Ja_101 [color="#008000" tooltip="Ja_111 --> Ja_101"]; + Node_Ja_111:pobluetooth:e -> Node_Ja_102:header [color="#000000" tooltip="Ja_111 --> Ja_102"]; + Node_Ja_111:pologging_options:e -> Node_Ja_110:header [color="#000000" tooltip="Ja_111 --> Ja_110"]; + Node_Ja_104:poalgorithm:e -> Node_Ja_103 [color="#008000" tooltip="Ja_104 --> Ja_103"]; + Node_Ja_108:polist:e -> Node_Ja_105 [color="#008000" tooltip="Ja_108 --> Ja_105"]; + Node_Ja_108:pomax:e -> Node_Ja_105 [color="#008000" tooltip="Ja_108 --> Ja_105"]; + Node_Ja_110:polevel:e -> Node_Ja_106 [color="#008000" tooltip="Ja_110 --> Ja_106"]; + Node_Ja_110:pocomponent:e -> Node_Ja_107 [color="#008000" tooltip="Ja_110 --> Ja_107"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:38 EST */ +} diff --git a/protobuf/generated/Squeezelite.dot.png b/protobuf/generated/Squeezelite.dot.png new file mode 100644 index 00000000..c81a8a91 Binary files /dev/null and b/protobuf/generated/Squeezelite.dot.png differ diff --git a/protobuf/generated/Squeezelite.dot.svg b/protobuf/generated/Squeezelite.dot.svg new file mode 100644 index 00000000..668b02a3 --- /dev/null +++ b/protobuf/generated/Squeezelite.dot.svg @@ -0,0 +1,466 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_110 + + + +DebugOption +1 +component + +DebugComponent +2 +level + +DebugLevelEnum + + + + + + +Node_Ja_106 + + + +enum +DebugLevelEnum + +DEFAULT + +0 + +INFO + +1 + +DEBUG + +2 + +SDEBUG + +3 + + + + + + +Node_Ja_110:e->Node_Ja_106 + + + + + + + + +Node_Ja_107 + + + +enum +DebugComponent + +NONE + +0 + +SLIMPROTO + +1 + +STREAM + +2 + +DECODE + +3 + +OUTPUT + +4 + +IR + +5 + +ALL + +6 + + + + + + +Node_Ja_110:e->Node_Ja_107 + + + + + + + + +Node_Ja_105 + + + +enum +SampleRate + +SAMPLE_RATE_UNSPECIFIED + +0 + +SAMPLE_RATE_8000 + +1 + +SAMPLE_RATE_11025 + +2 + +SAMPLE_RATE_12000 + +3 + +SAMPLE_RATE_16000 + +4 + +SAMPLE_RATE_22050 + +5 + +SAMPLE_RATE_24000 + +6 + +SAMPLE_RATE_32000 + +7 + +SAMPLE_RATE_44100 + +8 + +SAMPLE_RATE_48000 + +9 + +SAMPLE_RATE_88200 + +10 + +SAMPLE_RATE_96000 + +11 + +SAMPLE_RATE_176400 + +12 + +SAMPLE_RATE_192000 + +13 + +SAMPLE_RATE_352800 + +14 + +SAMPLE_RATE_384000 + +15 + +SAMPLE_RATE_705600 + +16 + +SAMPLE_RATE_768000 + +17 + + + + + + +Node_Ja_101 + + + +enum +OutputTypeEnum + +OUTPUT_UNKNOWN + +0 + +OUTPUT_I2S + +1 + +OUTPUT_SPDIF + +2 + +OUTPUT_Bluetooth + +3 + + + + + + +Node_Ja_108 + + + +RatesOption +1 +min + +SampleRate +2 +max + +SampleRate +[...] +3 +list + +SampleRate + + + + + + +Node_Ja_108:e->Node_Ja_105 + + + + + + + + +Node_Ja_108:e->Node_Ja_105 + + + + + + + + +Node_Ja_108:e->Node_Ja_105 + + + + + + + + +Node_Ja_109 + + + +BufferOption +1 +stream_buffer + +uint32 +2 +output_vuffer + +uint32 + + + + + + +Node_Ja_111 + + + +Squeezelite +1 +output_type + +OutputTypeEnum +2 +rates + +RatesOption +3 +amp_gpio_timeout + +int32 +4 +wav_aiff_header_parsing + +bool +5 +server_name_ip + +string +6 +server_port + +uint32 +7 +enabled + +bool +10 +device_name + +string +11 +bluetooth + +OutputBT +[...] +12 +logging_options + +DebugOption +13 +max_rate + +uint32 + + + + + + +Node_Ja_111:e->Node_Ja_110:header + + + + + + + + +Node_Ja_111:e->Node_Ja_101 + + + + + + + + +Node_Ja_111:e->Node_Ja_108:header + + + + + + + + +Node_Ja_102 + + + +OutputBT +1 +sink_name + +string + + + + + + +Node_Ja_111:e->Node_Ja_102:header + + + + + + + + +Node_Ja_103 + + + +enum +ResampleAlgorithm + +RESAMPLEDISABLED + +0 + +RESAMPLEBASIC_LINEAR + +1 + +RESAMPLETHIRTEEN_TAPS + +2 + +RESAMPLETWENTY_ONE_TAPS + +3 + + + + + + +Node_Ja_104 + + + +ResampleOptions +1 +algorithm + +ResampleAlgorithm +2 +interpolate_filter_coefficients + +bool + + + + + + +Node_Ja_104:e->Node_Ja_103 + + + + + + + + diff --git a/protobuf/generated/Status.dot b/protobuf/generated/Status.dot new file mode 100644 index 00000000..cb7fdafb --- /dev/null +++ b/protobuf/generated/Status.dot @@ -0,0 +1,49 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: system */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/Status.proto */ + /* selection: * */ + + rankdir=LR; + label="system"; + tooltip="system"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_107 [shape=plaintext tooltip="system.BT" label=<
BT
1bt_statusAPP_AV_STATE
2bt_sub_statusESP_AVRC_CT
>]; + Node_Ja_100 [shape=plaintext tooltip="UpdateReasonCode" label=<
enum UpdateReasonCode
UPDATE_CONNECTION_OK0
UPDATE_FAILED_ATTEMPT1
UPDATE_USER_DISCONNECT2
UPDATE_LOST_CONNECTION3
UPDATE_FAILED_ATTEMPT_AND_RESTORE4
UPDATE_ETHERNET_CONNECTED5
>]; + Node_Ja_102 [shape=plaintext tooltip="ESP_AVRC_CT" label=<
enum ESP_AVRC_CT
ESP_AVRC_CT_CONNECTION_STATE_EVT0
ESP_AVRC_CT_PASSTHROUGH_RSP_EVT1
ESP_AVRC_CT_METADATA_RSP_EVT2
ESP_AVRC_CT_PLAY_STATUS_RSP_EVT3
ESP_AVRC_CT_CHANGE_NOTIFY_EVT4
ESP_AVRC_CT_REMOTE_FEATURES_EVT5
ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT6
ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT7
>]; + Node_Ja_108 [shape=plaintext tooltip="system.PLATFORM" label=<
PLATFORM
1projectstring
2versionstring
3recoverybool
4namestring
5depthint32
>]; + Node_Ja_110 [shape=plaintext tooltip="system.Status" label=<
Status
1platformPLATFORM
2hwHW
3btBT
4LMSLMS
5netNET
>]; + Node_Ja_103 [shape=plaintext tooltip="system.LMS" label=<
LMS
1cportint32
2portint32
3ipstring
>]; + Node_Ja_106 [shape=plaintext tooltip="system.NET" label=<
NET
1wifiWIFI
2ipIP
3urcUpdateReasonCode
4interfacestring
>]; + Node_Ja_105 [shape=plaintext tooltip="system.WIFI" label=<
WIFI
1rssiint32
2ssidstring
3disconnect_countint32
4avg_conn_timefloat
>]; + Node_Ja_104 [shape=plaintext tooltip="system.IP" label=<
IP
14ipstring
15netmaskstring
16gwstring
>]; + Node_Ja_109 [shape=plaintext tooltip="system.HW" label=<
HW
1jack_insertedbool
2batt_voltagefloat
>]; + Node_Ja_101 [shape=plaintext tooltip="APP_AV_STATE" label=<
enum APP_AV_STATE
APP_AV_STATE_IDLE0
APP_AV_STATE_DISCOVERING1
APP_AV_STATE_DISCOVERED2
APP_AV_STATE_UNCONNECTED3
APP_AV_STATE_CONNECTING4
APP_AV_STATE_CONNECTED5
APP_AV_STATE_DISCONNECTING6
>]; + + /* ------ connections ------ */ + Node_Ja_110:pohw:e -> Node_Ja_109:header [color="#000000" tooltip="Ja_110 --> Ja_109"]; + Node_Ja_110:poplatform:e -> Node_Ja_108:header [color="#000000" tooltip="Ja_110 --> Ja_108"]; + Node_Ja_110:poLMS:e -> Node_Ja_103:header [color="#000000" tooltip="Ja_110 --> Ja_103"]; + Node_Ja_110:ponet:e -> Node_Ja_106:header [color="#000000" tooltip="Ja_110 --> Ja_106"]; + Node_Ja_106:powifi:e -> Node_Ja_105:header [color="#000000" tooltip="Ja_106 --> Ja_105"]; + Node_Ja_110:pobt:e -> Node_Ja_107:header [color="#000000" tooltip="Ja_110 --> Ja_107"]; + Node_Ja_106:pourc:e -> Node_Ja_100 [color="#008000" tooltip="Ja_106 --> Ja_100"]; + Node_Ja_106:poip:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_106 --> Ja_104"]; + Node_Ja_107:pobt_sub_status:e -> Node_Ja_102 [color="#008000" tooltip="Ja_107 --> Ja_102"]; + Node_Ja_107:pobt_status:e -> Node_Ja_101 [color="#008000" tooltip="Ja_107 --> Ja_101"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:38 EST */ +} diff --git a/protobuf/generated/Status.dot.png b/protobuf/generated/Status.dot.png new file mode 100644 index 00000000..8c4a4722 Binary files /dev/null and b/protobuf/generated/Status.dot.png differ diff --git a/protobuf/generated/Status.dot.svg b/protobuf/generated/Status.dot.svg new file mode 100644 index 00000000..a0e13fac --- /dev/null +++ b/protobuf/generated/Status.dot.svg @@ -0,0 +1,426 @@ + + + + + + +protodot + +system + + + + +Node_Ja_107 + + + +BT +1 +bt_status + +APP_AV_STATE +2 +bt_sub_status + +ESP_AVRC_CT + + + + + + +Node_Ja_102 + + + +enum +ESP_AVRC_CT + +ESP_AVRC_CT_CONNECTION_STATE_EVT + +0 + +ESP_AVRC_CT_PASSTHROUGH_RSP_EVT + +1 + +ESP_AVRC_CT_METADATA_RSP_EVT + +2 + +ESP_AVRC_CT_PLAY_STATUS_RSP_EVT + +3 + +ESP_AVRC_CT_CHANGE_NOTIFY_EVT + +4 + +ESP_AVRC_CT_REMOTE_FEATURES_EVT + +5 + +ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT + +6 + +ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT + +7 + + + + + + +Node_Ja_107:e->Node_Ja_102 + + + + + + + + +Node_Ja_101 + + + +enum +APP_AV_STATE + +APP_AV_STATE_IDLE + +0 + +APP_AV_STATE_DISCOVERING + +1 + +APP_AV_STATE_DISCOVERED + +2 + +APP_AV_STATE_UNCONNECTED + +3 + +APP_AV_STATE_CONNECTING + +4 + +APP_AV_STATE_CONNECTED + +5 + +APP_AV_STATE_DISCONNECTING + +6 + + + + + + +Node_Ja_107:e->Node_Ja_101 + + + + + + + + +Node_Ja_100 + + + +enum +UpdateReasonCode + +UPDATE_CONNECTION_OK + +0 + +UPDATE_FAILED_ATTEMPT + +1 + +UPDATE_USER_DISCONNECT + +2 + +UPDATE_LOST_CONNECTION + +3 + +UPDATE_FAILED_ATTEMPT_AND_RESTORE + +4 + +UPDATE_ETHERNET_CONNECTED + +5 + + + + + + +Node_Ja_108 + + + +PLATFORM +1 +project + +string +2 +version + +string +3 +recovery + +bool +4 +name + +string +5 +depth + +int32 + + + + + + +Node_Ja_110 + + + +Status +1 +platform + +PLATFORM +2 +hw + +HW +3 +bt + +BT +4 +LMS + +LMS +5 +net + +NET + + + + + + +Node_Ja_110:e->Node_Ja_107:header + + + + + + + + +Node_Ja_110:e->Node_Ja_108:header + + + + + + + + +Node_Ja_103 + + + +LMS +1 +cport + +int32 +2 +port + +int32 +3 +ip + +string + + + + + + +Node_Ja_110:e->Node_Ja_103:header + + + + + + + + +Node_Ja_106 + + + +NET +1 +wifi + +WIFI +2 +ip + +IP +3 +urc + +UpdateReasonCode +4 +interface + +string + + + + + + +Node_Ja_110:e->Node_Ja_106:header + + + + + + + + +Node_Ja_109 + + + +HW +1 +jack_inserted + +bool +2 +batt_voltage + +float + + + + + + +Node_Ja_110:e->Node_Ja_109:header + + + + + + + + +Node_Ja_106:e->Node_Ja_100 + + + + + + + + +Node_Ja_105 + + + +WIFI +1 +rssi + +int32 +2 +ssid + +string +3 +disconnect_count + +int32 +4 +avg_conn_time + +float + + + + + + +Node_Ja_106:e->Node_Ja_105:header + + + + + + + + +Node_Ja_104 + + + +IP +14 +ip + +string +15 +netmask + +string +16 +gw + +string + + + + + + +Node_Ja_106:e->Node_Ja_104:header + + + + + + + + diff --git a/protobuf/generated/configuration.dot b/protobuf/generated/configuration.dot new file mode 100644 index 00000000..86a24919 --- /dev/null +++ b/protobuf/generated/configuration.dot @@ -0,0 +1,202 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: platform */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/configuration.proto */ + /* selection: * */ + + rankdir=LR; + label="platform"; + tooltip="platform"; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_150 [shape=plaintext tooltip="platform.KnobOnly" label=<
KnobOnly
1enablebool
2delay_msint32
>]; + Node_Ja_163 [shape=plaintext tooltip="platform.WS2812" label=<
WS2812
1lengthint32
2gpioGPIO
>]; + Node_Ja_153 [shape=plaintext tooltip="BatteryAttenEnum" label=<
enum BatteryAttenEnum
UNSPECIFIED_ATT0
ATT_01
ATT_12
ATT_23
ATT_34
>]; + Node_Ja_117 [shape=plaintext tooltip="SampleRate" label=<
enum SampleRate
SAMPLE_RATE_UNSPECIFIED0
SAMPLE_RATE_80001
SAMPLE_RATE_110252
SAMPLE_RATE_120003
SAMPLE_RATE_160004
SAMPLE_RATE_220505
SAMPLE_RATE_240006
SAMPLE_RATE_320007
SAMPLE_RATE_441008
SAMPLE_RATE_480009
SAMPLE_RATE_8820010
SAMPLE_RATE_9600011
SAMPLE_RATE_17640012
SAMPLE_RATE_19200013
SAMPLE_RATE_35280014
SAMPLE_RATE_38400015
SAMPLE_RATE_70560016
SAMPLE_RATE_76800017
>]; + Node_Ja_137 [shape=plaintext tooltip="Mode" label=<
enum Mode
REG_MODE_NOTHING0
REG_MODE_OR1
REG_MODE_AND2
>]; + Node_Ja_139 [shape=plaintext tooltip="MCKEnum" label=<
enum MCKEnum
UNSPECIFIED_MCK0
MCK01
MCK12
MCK23
>]; + Node_Ja_143 [shape=plaintext tooltip="platform.I2CDisplay" label=<
I2CDisplay
1addressint32
>]; + Node_Ja_141 [shape=plaintext tooltip="platform.DispOffsets" label=<
DispOffsets
1heightint32
2widthint32
>]; + Node_Ja_126 [shape=plaintext tooltip="platform.Services" label=<
Services
1metadataMetadata
2sleepSleepService
3ota_urlstring
4cspotSpotify
5airplayAirPlay
6squeezeliteSqueezelite
>]; + Node_Ja_162 [shape=plaintext tooltip="platform.SPIBus" label=<
SPIBus
1mosiGPIO
2misoGPIO
3clkGPIO
4dcGPIO
5hostHostEnum
>]; + Node_Ja_130 [shape=plaintext tooltip="platform.ControlCommand" label=<
ControlCommand
1typeControlCommandType
[...]2itemsControlItem
>]; + Node_Ja_132 [shape=plaintext tooltip="platform.ControlItem" label=<
ControlItem
item_type
1reg_actionRegisterAction
2gpio_actionGpioAction
3delay_actionDelayAction
>]; + Node_Ja_166 [shape=plaintext tooltip="platform.Config" label=<
Config
1gpiosGpios
2devDev
3servicesServices
4device_namestring
>]; + Node_Ja_164 [shape=plaintext tooltip="platform.LEDStrip" label=<
LEDStrip
1WS2812WS2812
>]; + Node_Ja_128 [shape=plaintext tooltip="platform.I2CBus" label=<
I2CBus
1portI2CPortEnum
2speedint32
3sdaGPIO
4sclGPIO
>]; + Node_Ja_148 [shape=plaintext tooltip="platform.ButtonActions" label=<
ButtonActions
1pressedButtonAction
2releasedButtonAction
>]; + Node_Ja_107 [shape=plaintext tooltip="platform.GPIOExpSPI" label=<
GPIOExpSPI
1speedint32
2hostHostEnum
3csGPIO
>]; + Node_Ja_124 [shape=plaintext tooltip="platform.SleepService" label=<
SleepService
1delayuint32
2spuriousint32
3sleepGPIO
[...]4wakeGPIO
[...]5rtcGPIO
6battfloat
>]; + Node_Ja_100 [shape=plaintext tooltip="DeviceTypeEnum" label=<
enum DeviceTypeEnum
UNSPECIFIED_TYPE0
DEVTYPE_SPI1
DEVTYPE_I2C2
DEVTYPE__RMII3
>]; + Node_Ja_101 [shape=plaintext tooltip="PortEnum" label=<
enum PortEnum
UNSPECIFIED_SYSTPORT0
SYSTEM1
DAC_PORT2
>]; + Node_Ja_133 [shape=plaintext tooltip="platform.RegisterAction" label=<
RegisterAction
1regint32
2valint32
3modeMode
>]; + Node_Ja_159 [shape=plaintext tooltip="platform.EthRMII" label=<
EthRMII
1mdcGPIO
2mdioGPIO
>]; + Node_Ja_131 [shape=plaintext tooltip="ControlCommandType" label=<
enum ControlCommandType
INIT0
POWER_ON1
POWER_OFF2
SPEAKER_ON3
SPEAKER_OFF4
HEADSET_ON5
HEADSET_OFF6
>]; + Node_Ja_105 [shape=plaintext tooltip="platform.Gpios" label=<
Gpios
1greenLEDGPIO
2redLEDGPIO
3audioJackGPIO
4ampGPIO
5powerGPIO
6irGPIO
7jackGPIO
8spkfaultGPIO
9VccGPIO
10GNDGPIO
>]; + Node_Ja_111 [shape=plaintext tooltip="platform.Spotify" label=<
Spotify
1enabledbool
2device_namestring
3bitrateuint32
4zeroconfbool
5volumeuint32
>]; + Node_Ja_160 [shape=plaintext tooltip="platform.Eth" label=<
Eth
1typeDeviceTypeEnum
2commonEthCommon
ethType
3spiEthSPI
4rmiiEthRMII
>]; + Node_Ja_109 [shape=plaintext tooltip="platform.GPIOExp" label=<
GPIOExp
1modelGPIOExpModelEnum
2addrint32
ExpType
3i2cGPIOExpI2C
4spiGPIOExpSPI
5baseint32
6countint32
7intrGPIO
>]; + Node_Ja_129 [shape=plaintext tooltip="platform.DacControlSet" label=<
DacControlSet
[...]1commandsControlCommand
>]; + Node_Ja_149 [shape=plaintext tooltip="platform.Button" label=<
Button
1gpioGPIO
2pullbool
3debounceint32
4shifterGPIO
5longdurationint32
6normalButtonActions
7longpressButtonActions
8shiftedButtonActions
9longshiftedButtonActions
>]; + Node_Ja_119 [shape=plaintext tooltip="DebugComponent" label=<
enum DebugComponent
NONE0
SLIMPROTO1
STREAM2
DECODE3
OUTPUT4
IR5
ALL6
>]; + Node_Ja_147 [shape=plaintext tooltip="ButtonAction" label=<
enum ButtonAction
ACTRLS_NONE0
ACTRLS_POWER1
ACTRLS_VOLUP2
ACTRLS_VOLDOWN3
ACTRLS_TOGGLE4
ACTRLS_PLAY5
ACTRLS_PAUSE6
ACTRLS_STOP7
ACTRLS_REW8
ACTRLS_FWD9
ACTRLS_PREV10
ACTRLS_NEXT11
BCTRLS_UP12
BCTRLS_DOWN13
BCTRLS_LEFT14
BCTRLS_RIGHT15
BCTRLS_PS116
BCTRLS_PS217
BCTRLS_PS318
BCTRLS_PS419
BCTRLS_PS520
BCTRLS_PS621
BCTRLS_PS722
BCTRLS_PS823
BCTRLS_PS924
BCTRLS_PS1025
KNOB_LEFT26
KNOB_RIGHT27
KNOB_PUSH28
ACTRLS_SLEEP29
>]; + Node_Ja_134 [shape=plaintext tooltip="GpioActionLevel" label=<
enum GpioActionLevel
ACTION_LEVEL_UNDEFINED0
ACTION_LEVEL_11
ACTION_LEVEL_02
>]; + Node_Ja_108 [shape=plaintext tooltip="platform.GPIOExpI2C" label=<
GPIOExpI2C
5portPortEnum
>]; + Node_Ja_125 [shape=plaintext tooltip="platform.Metadata" label=<
Metadata
1formatstring
2speeduint32
3pauseuint32
4artworkArtwork
>]; + Node_Ja_151 [shape=plaintext tooltip="platform.Rotary" label=<
Rotary
1AGPIO
2BGPIO
3SWGPIO
4knobonlyKnobOnly
5volumebool
6longpressbool
>]; + Node_Ja_120 [shape=plaintext tooltip="platform.RatesOption" label=<
RatesOption
1minSampleRate
2maxSampleRate
[...]3listSampleRate
>]; + Node_Ja_122 [shape=plaintext tooltip="platform.DebugOption" label=<
DebugOption
1componentDebugComponent
2levelDebugLevelEnum
>]; + Node_Ja_106 [shape=plaintext tooltip="GPIOExpModelEnum" label=<
enum GPIOExpModelEnum
UNSPECIFIED_EXP0
PCA95351
PCA85XX2
MCP230173
MCP23S174
>]; + Node_Ja_135 [shape=plaintext tooltip="platform.GpioAction" label=<
GpioAction
1gpioint32
2levelGpioActionLevel
>]; + Node_Ja_154 [shape=plaintext tooltip="platform.Battery" label=<
Battery
1channelBatteryChannelEnum
2scalefloat
3cellsint32
4attenBatteryAttenEnum
>]; + Node_Ja_161 [shape=plaintext tooltip="platform.SPDIF" label=<
SPDIF
1dcGPIO
2dataGPIO
3clkGPIO
>]; + Node_Ja_113 [shape=plaintext tooltip="OutputTypeEnum" label=<
enum OutputTypeEnum
OUTPUT_UNKNOWN0
OUTPUT_I2S1
OUTPUT_SPDIF2
OUTPUT_Bluetooth3
>]; + Node_Ja_152 [shape=plaintext tooltip="BatteryChannelEnum" label=<
enum BatteryChannelEnum
UNSPECIFIED_CH0
CH01
CH12
CH23
CH34
CH45
CH56
CH67
CH78
>]; + Node_Ja_157 [shape=plaintext tooltip="platform.EthCommon" label=<
EthCommon
1modelEthModelEnum
2rstGPIO
>]; + Node_Ja_112 [shape=plaintext tooltip="platform.AirPlay" label=<
AirPlay
1enabledbool
2device_namestring
3portuint32
>]; + Node_Ja_165 [shape=plaintext tooltip="platform.Dev" label=<
Dev
1spiSPIBus
2i2cI2CBus
3dacDAC
4spdifSPDIF
5displayDisplay
[...]6gpio_expGPIOExp
7led_stripLEDStrip
8rotaryRotary
[...]9buttonsButton
10ethEth
11batteryBattery
>]; + Node_Ja_144 [shape=plaintext tooltip="platform.SPIDisplay" label=<
SPIDisplay
1csGPIO
4speedint32
5rotatebool
>]; + Node_Ja_146 [shape=plaintext tooltip="platform.Display" label=<
Display
1typeDeviceTypeEnum
2commonDispCommon
dispType
3i2cI2CDisplay
4spiSPIDisplay
>]; + Node_Ja_114 [shape=plaintext tooltip="platform.OutputBT" label=<
OutputBT
1sink_namestring
>]; + Node_Ja_138 [shape=plaintext tooltip="DACModelEnum" label=<
enum DACModelEnum
UNSPECIFIED_MODEL0
TAS57xx1
TAS57132
AC1013
WM89784
ES83885
I2S6
>]; + Node_Ja_102 [shape=plaintext tooltip="HostEnum" label=<
enum HostEnum
UNSPECIFIED_HOST0
Host01
Host12
>]; + Node_Ja_140 [shape=plaintext tooltip="platform.DAC" label=<
DAC
1bckGPIO
2wsGPIO
3doutGPIO
4mckMCKEnum
5muteGPIO
6modelDACModelEnum
7i2cI2CBus
8daccontrolsetDacControlSet
>]; + Node_Ja_118 [shape=plaintext tooltip="DebugLevelEnum" label=<
enum DebugLevelEnum
DEFAULT0
INFO1
DEBUG2
SDEBUG3
>]; + Node_Ja_123 [shape=plaintext tooltip="platform.Squeezelite" label=<
Squeezelite
1output_typeOutputTypeEnum
2ratesRatesOption
3amp_gpio_timeoutint32
4wav_aiff_header_parsingbool
5server_name_ipstring
6server_portuint32
7enabledbool
10device_namestring
11bluetoothOutputBT
[...]12logging_optionsDebugOption
13max_rateuint32
>]; + Node_Ja_145 [shape=plaintext tooltip="platform.DispCommon" label=<
DispCommon
1widthint32
2heightint32
3HFlipbool
4VFlipbool
5driverDisplayDriverEnum
6bitDepthint32
7backGPIO
8resetGPIO
9readyGPIO
10offsetsDispOffsets
>]; + Node_Ja_127 [shape=plaintext tooltip="I2CPortEnum" label=<
enum I2CPortEnum
UNSPECIFIED_PORT0
I2CPort01
I2CPort12
>]; + Node_Ja_155 [shape=plaintext tooltip="EthModelEnum" label=<
enum EthModelEnum
UNSPECIFIED_ETHMODEL0
LAN87201
DM90512
W55003
>]; + Node_Ja_104 [shape=plaintext tooltip="platform.GPIO" label=<
GPIO
1pinint32
2levelint32
>]; + Node_Ja_110 [shape=plaintext tooltip="platform.Artwork" label=<
Artwork
1enabledbool
2resizebool
>]; + Node_Ja_142 [shape=plaintext tooltip="DisplayDriverEnum" label=<
enum DisplayDriverEnum
UNSPECIFIED_DRIVER0
SSD13061
SSD13222
SSD13263
SSD13274
SH11065
SSD16756
ST77357
ST77898
ILI93419
ILI9341_2410
SSD135111
>]; + Node_Ja_136 [shape=plaintext tooltip="platform.DelayAction" label=<
DelayAction
1delayint32
>]; + Node_Ja_158 [shape=plaintext tooltip="platform.EthSPI" label=<
EthSPI
1csGPIO
2speedint32
3intrGPIO
4hostint32
>]; + + /* ------ connections ------ */ + Node_Ja_162:poclk:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_162 --> Ja_104"]; + Node_Ja_107:pohost:e -> Node_Ja_102 [color="#008000" tooltip="Ja_107 --> Ja_102"]; + Node_Ja_140:pomck:e -> Node_Ja_139 [color="#008000" tooltip="Ja_140 --> Ja_139"]; + Node_Ja_160:pormii:e -> Node_Ja_159:header [color="#000000" tooltip="Ja_160 --> Ja_159"]; + Node_Ja_124:portc:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_124 --> Ja_104"]; + Node_Ja_165:pospdif:e -> Node_Ja_161:header [color="#000000" tooltip="Ja_165 --> Ja_161"]; + Node_Ja_105:poredLED:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_125:poartwork:e -> Node_Ja_110:header [color="#000000" tooltip="Ja_125 --> Ja_110"]; + Node_Ja_107:pocs:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_107 --> Ja_104"]; + Node_Ja_166:poservices:e -> Node_Ja_126:header [color="#000000" tooltip="Ja_166 --> Ja_126"]; + Node_Ja_162:pomosi:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_162 --> Ja_104"]; + Node_Ja_120:pomax:e -> Node_Ja_117 [color="#008000" tooltip="Ja_120 --> Ja_117"]; + Node_Ja_122:pocomponent:e -> Node_Ja_119 [color="#008000" tooltip="Ja_122 --> Ja_119"]; + Node_Ja_123:porates:e -> Node_Ja_120:header [color="#000000" tooltip="Ja_123 --> Ja_120"]; + Node_Ja_165:podisplay:e -> Node_Ja_146:header [color="#000000" tooltip="Ja_165 --> Ja_146"]; + Node_Ja_162:pomiso:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_162 --> Ja_104"]; + Node_Ja_126:posqueezelite:e -> Node_Ja_123:header [color="#000000" tooltip="Ja_126 --> Ja_123"]; + Node_Ja_146:potype:e -> Node_Ja_100 [color="#008000" tooltip="Ja_146 --> Ja_100"]; + Node_Ja_109:pomodel:e -> Node_Ja_106 [color="#008000" tooltip="Ja_109 --> Ja_106"]; + Node_Ja_158:pointr:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_158 --> Ja_104"]; + Node_Ja_105:poamp:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_140:pomute:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_140 --> Ja_104"]; + Node_Ja_146:pospi:e -> Node_Ja_144:header [color="#000000" tooltip="Ja_146 --> Ja_144"]; + Node_Ja_109:pointr:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_109 --> Ja_104"]; + Node_Ja_159:pomdc:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_159 --> Ja_104"]; + Node_Ja_132:podelay_action:e -> Node_Ja_136:header [color="#000000" tooltip="Ja_132 --> Ja_136"]; + Node_Ja_132:poreg_action:e -> Node_Ja_133:header [color="#000000" tooltip="Ja_132 --> Ja_133"]; + Node_Ja_105:poaudioJack:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_105:popower:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_140:pomodel:e -> Node_Ja_138 [color="#008000" tooltip="Ja_140 --> Ja_138"]; + Node_Ja_157:porst:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_157 --> Ja_104"]; + Node_Ja_126:pocspot:e -> Node_Ja_111:header [color="#000000" tooltip="Ja_126 --> Ja_111"]; + Node_Ja_151:poSW:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_151 --> Ja_104"]; + Node_Ja_160:pocommon:e -> Node_Ja_157:header [color="#000000" tooltip="Ja_160 --> Ja_157"]; + Node_Ja_128:posda:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_128 --> Ja_104"]; + Node_Ja_128:poscl:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_128 --> Ja_104"]; + Node_Ja_159:pomdio:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_159 --> Ja_104"]; + Node_Ja_126:poairplay:e -> Node_Ja_112:header [color="#000000" tooltip="Ja_126 --> Ja_112"]; + Node_Ja_105:poVcc:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_165:poi2c:e -> Node_Ja_128:header [color="#000000" tooltip="Ja_165 --> Ja_128"]; + Node_Ja_160:potype:e -> Node_Ja_100 [color="#008000" tooltip="Ja_160 --> Ja_100"]; + Node_Ja_109:poi2c:e -> Node_Ja_108:header [color="#000000" tooltip="Ja_109 --> Ja_108"]; + Node_Ja_129:pocommands:e -> Node_Ja_130:header [color="#000000" tooltip="Ja_129 --> Ja_130"]; + Node_Ja_154:pochannel:e -> Node_Ja_152 [color="#008000" tooltip="Ja_154 --> Ja_152"]; + Node_Ja_149:poshifter:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_149 --> Ja_104"]; + Node_Ja_158:pocs:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_158 --> Ja_104"]; + Node_Ja_165:porotary:e -> Node_Ja_151:header [color="#000000" tooltip="Ja_165 --> Ja_151"]; + Node_Ja_165:pospi:e -> Node_Ja_162:header [color="#000000" tooltip="Ja_165 --> Ja_162"]; + Node_Ja_140:pows:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_140 --> Ja_104"]; + Node_Ja_157:pomodel:e -> Node_Ja_155 [color="#008000" tooltip="Ja_157 --> Ja_155"]; + Node_Ja_120:pomin:e -> Node_Ja_117 [color="#008000" tooltip="Ja_120 --> Ja_117"]; + Node_Ja_163:pogpio:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_163 --> Ja_104"]; + Node_Ja_165:pobattery:e -> Node_Ja_154:header [color="#000000" tooltip="Ja_165 --> Ja_154"]; + Node_Ja_165:pobuttons:e -> Node_Ja_149:header [color="#000000" tooltip="Ja_165 --> Ja_149"]; + Node_Ja_165:pogpio_exp:e -> Node_Ja_109:header [color="#000000" tooltip="Ja_165 --> Ja_109"]; + Node_Ja_151:poknobonly:e -> Node_Ja_150:header [color="#000000" tooltip="Ja_151 --> Ja_150"]; + Node_Ja_161:podc:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_161 --> Ja_104"]; + Node_Ja_161:podata:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_161 --> Ja_104"]; + Node_Ja_120:polist:e -> Node_Ja_117 [color="#008000" tooltip="Ja_120 --> Ja_117"]; + Node_Ja_109:pospi:e -> Node_Ja_107:header [color="#000000" tooltip="Ja_109 --> Ja_107"]; + Node_Ja_123:pobluetooth:e -> Node_Ja_114:header [color="#000000" tooltip="Ja_123 --> Ja_114"]; + Node_Ja_145:pooffsets:e -> Node_Ja_141:header [color="#000000" tooltip="Ja_145 --> Ja_141"]; + Node_Ja_108:poport:e -> Node_Ja_101 [color="#008000" tooltip="Ja_108 --> Ja_101"]; + Node_Ja_105:pogreenLED:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_165:poeth:e -> Node_Ja_160:header [color="#000000" tooltip="Ja_165 --> Ja_160"]; + Node_Ja_105:pojack:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_154:poatten:e -> Node_Ja_153 [color="#008000" tooltip="Ja_154 --> Ja_153"]; + Node_Ja_149:polongpress:e -> Node_Ja_148:header [color="#000000" tooltip="Ja_149 --> Ja_148"]; + Node_Ja_132:pogpio_action:e -> Node_Ja_135:header [color="#000000" tooltip="Ja_132 --> Ja_135"]; + Node_Ja_126:posleep:e -> Node_Ja_124:header [color="#000000" tooltip="Ja_126 --> Ja_124"]; + Node_Ja_151:poB:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_151 --> Ja_104"]; + Node_Ja_105:pospkfault:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_146:pocommon:e -> Node_Ja_145:header [color="#000000" tooltip="Ja_146 --> Ja_145"]; + Node_Ja_124:powake:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_124 --> Ja_104"]; + Node_Ja_160:pospi:e -> Node_Ja_158:header [color="#000000" tooltip="Ja_160 --> Ja_158"]; + Node_Ja_122:polevel:e -> Node_Ja_118 [color="#008000" tooltip="Ja_122 --> Ja_118"]; + Node_Ja_123:pologging_options:e -> Node_Ja_122:header [color="#000000" tooltip="Ja_123 --> Ja_122"]; + Node_Ja_145:poready:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_145 --> Ja_104"]; + Node_Ja_130:poitems:e -> Node_Ja_132:header [color="#000000" tooltip="Ja_130 --> Ja_132"]; + Node_Ja_126:pometadata:e -> Node_Ja_125:header [color="#000000" tooltip="Ja_126 --> Ja_125"]; + Node_Ja_162:podc:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_162 --> Ja_104"]; + Node_Ja_148:poreleased:e -> Node_Ja_147 [color="#008000" tooltip="Ja_148 --> Ja_147"]; + Node_Ja_151:poA:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_151 --> Ja_104"]; + Node_Ja_164:poWS2812:e -> Node_Ja_163:header [color="#000000" tooltip="Ja_164 --> Ja_163"]; + Node_Ja_149:poshifted:e -> Node_Ja_148:header [color="#000000" tooltip="Ja_149 --> Ja_148"]; + Node_Ja_148:popressed:e -> Node_Ja_147 [color="#008000" tooltip="Ja_148 --> Ja_147"]; + Node_Ja_133:pomode:e -> Node_Ja_137 [color="#008000" tooltip="Ja_133 --> Ja_137"]; + Node_Ja_140:podaccontrolset:e -> Node_Ja_129:header [color="#000000" tooltip="Ja_140 --> Ja_129"]; + Node_Ja_124:posleep:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_124 --> Ja_104"]; + Node_Ja_149:polongshifted:e -> Node_Ja_148:header [color="#000000" tooltip="Ja_149 --> Ja_148"]; + Node_Ja_145:poreset:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_145 --> Ja_104"]; + Node_Ja_130:potype:e -> Node_Ja_131 [color="#008000" tooltip="Ja_130 --> Ja_131"]; + Node_Ja_166:podev:e -> Node_Ja_165:header [color="#000000" tooltip="Ja_166 --> Ja_165"]; + Node_Ja_145:poback:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_145 --> Ja_104"]; + Node_Ja_135:polevel:e -> Node_Ja_134 [color="#008000" tooltip="Ja_135 --> Ja_134"]; + Node_Ja_165:podac:e -> Node_Ja_140:header [color="#000000" tooltip="Ja_165 --> Ja_140"]; + Node_Ja_123:pooutput_type:e -> Node_Ja_113 [color="#008000" tooltip="Ja_123 --> Ja_113"]; + Node_Ja_146:poi2c:e -> Node_Ja_143:header [color="#000000" tooltip="Ja_146 --> Ja_143"]; + Node_Ja_162:pohost:e -> Node_Ja_102 [color="#008000" tooltip="Ja_162 --> Ja_102"]; + Node_Ja_105:poir:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_149:ponormal:e -> Node_Ja_148:header [color="#000000" tooltip="Ja_149 --> Ja_148"]; + Node_Ja_149:pogpio:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_149 --> Ja_104"]; + Node_Ja_140:poi2c:e -> Node_Ja_128:header [color="#000000" tooltip="Ja_140 --> Ja_128"]; + Node_Ja_140:pobck:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_140 --> Ja_104"]; + Node_Ja_140:podout:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_140 --> Ja_104"]; + Node_Ja_161:poclk:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_161 --> Ja_104"]; + Node_Ja_145:podriver:e -> Node_Ja_142 [color="#008000" tooltip="Ja_145 --> Ja_142"]; + Node_Ja_165:poled_strip:e -> Node_Ja_164:header [color="#000000" tooltip="Ja_165 --> Ja_164"]; + Node_Ja_144:pocs:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_144 --> Ja_104"]; + Node_Ja_105:poGND:e -> Node_Ja_104:header [color="#000000" tooltip="Ja_105 --> Ja_104"]; + Node_Ja_128:poport:e -> Node_Ja_127 [color="#008000" tooltip="Ja_128 --> Ja_127"]; + Node_Ja_166:pogpios:e -> Node_Ja_105:header [color="#000000" tooltip="Ja_166 --> Ja_105"]; + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:38 EST */ +} diff --git a/protobuf/generated/configuration.dot.png b/protobuf/generated/configuration.dot.png new file mode 100644 index 00000000..f41c6ace Binary files /dev/null and b/protobuf/generated/configuration.dot.png differ diff --git a/protobuf/generated/configuration.dot.svg b/protobuf/generated/configuration.dot.svg new file mode 100644 index 00000000..08b54bdf --- /dev/null +++ b/protobuf/generated/configuration.dot.svg @@ -0,0 +1,2978 @@ + + + + + + +protodot + +platform + + + + +Node_Ja_150 + + + +KnobOnly +1 +enable + +bool +2 +delay_ms + +int32 + + + + + + +Node_Ja_163 + + + +WS2812 +1 +length + +int32 +2 +gpio + +GPIO + + + + + + +Node_Ja_104 + + + +GPIO +1 +pin + +int32 +2 +level + +int32 + + + + + + +Node_Ja_163:e->Node_Ja_104:header + + + + + + + + +Node_Ja_153 + + + +enum +BatteryAttenEnum + +UNSPECIFIED_ATT + +0 + +ATT_0 + +1 + +ATT_1 + +2 + +ATT_2 + +3 + +ATT_3 + +4 + + + + + + +Node_Ja_117 + + + +enum +SampleRate + +SAMPLE_RATE_UNSPECIFIED + +0 + +SAMPLE_RATE_8000 + +1 + +SAMPLE_RATE_11025 + +2 + +SAMPLE_RATE_12000 + +3 + +SAMPLE_RATE_16000 + +4 + +SAMPLE_RATE_22050 + +5 + +SAMPLE_RATE_24000 + +6 + +SAMPLE_RATE_32000 + +7 + +SAMPLE_RATE_44100 + +8 + +SAMPLE_RATE_48000 + +9 + +SAMPLE_RATE_88200 + +10 + +SAMPLE_RATE_96000 + +11 + +SAMPLE_RATE_176400 + +12 + +SAMPLE_RATE_192000 + +13 + +SAMPLE_RATE_352800 + +14 + +SAMPLE_RATE_384000 + +15 + +SAMPLE_RATE_705600 + +16 + +SAMPLE_RATE_768000 + +17 + + + + + + +Node_Ja_137 + + + +enum +Mode + +REG_MODE_NOTHING + +0 + +REG_MODE_OR + +1 + +REG_MODE_AND + +2 + + + + + + +Node_Ja_139 + + + +enum +MCKEnum + +UNSPECIFIED_MCK + +0 + +MCK0 + +1 + +MCK1 + +2 + +MCK2 + +3 + + + + + + +Node_Ja_143 + + + +I2CDisplay +1 +address + +int32 + + + + + + +Node_Ja_141 + + + +DispOffsets +1 +height + +int32 +2 +width + +int32 + + + + + + +Node_Ja_126 + + + +Services +1 +metadata + +Metadata +2 +sleep + +SleepService +3 +ota_url + +string +4 +cspot + +Spotify +5 +airplay + +AirPlay +6 +squeezelite + +Squeezelite + + + + + + +Node_Ja_124 + + + +SleepService +1 +delay + +uint32 +2 +spurious + +int32 +3 +sleep + +GPIO +[...] +4 +wake + +GPIO +[...] +5 +rtc + +GPIO +6 +batt + +float + + + + + + +Node_Ja_126:e->Node_Ja_124:header + + + + + + + + +Node_Ja_111 + + + +Spotify +1 +enabled + +bool +2 +device_name + +string +3 +bitrate + +uint32 +4 +zeroconf + +bool +5 +volume + +uint32 + + + + + + +Node_Ja_126:e->Node_Ja_111:header + + + + + + + + +Node_Ja_125 + + + +Metadata +1 +format + +string +2 +speed + +uint32 +3 +pause + +uint32 +4 +artwork + +Artwork + + + + + + +Node_Ja_126:e->Node_Ja_125:header + + + + + + + + +Node_Ja_112 + + + +AirPlay +1 +enabled + +bool +2 +device_name + +string +3 +port + +uint32 + + + + + + +Node_Ja_126:e->Node_Ja_112:header + + + + + + + + +Node_Ja_123 + + + +Squeezelite +1 +output_type + +OutputTypeEnum +2 +rates + +RatesOption +3 +amp_gpio_timeout + +int32 +4 +wav_aiff_header_parsing + +bool +5 +server_name_ip + +string +6 +server_port + +uint32 +7 +enabled + +bool +10 +device_name + +string +11 +bluetooth + +OutputBT +[...] +12 +logging_options + +DebugOption +13 +max_rate + +uint32 + + + + + + +Node_Ja_126:e->Node_Ja_123:header + + + + + + + + +Node_Ja_162 + + + +SPIBus +1 +mosi + +GPIO +2 +miso + +GPIO +3 +clk + +GPIO +4 +dc + +GPIO +5 +host + +HostEnum + + + + + + +Node_Ja_102 + + + +enum +HostEnum + +UNSPECIFIED_HOST + +0 + +Host0 + +1 + +Host1 + +2 + + + + + + +Node_Ja_162:e->Node_Ja_102 + + + + + + + + +Node_Ja_162:e->Node_Ja_104:header + + + + + + + + +Node_Ja_162:e->Node_Ja_104:header + + + + + + + + +Node_Ja_162:e->Node_Ja_104:header + + + + + + + + +Node_Ja_162:e->Node_Ja_104:header + + + + + + + + +Node_Ja_130 + + + +ControlCommand +1 +type + +ControlCommandType +[...] +2 +items + +ControlItem + + + + + + +Node_Ja_132 + + + +ControlItem + +item_type + +1 +reg_action + +RegisterAction + +2 +gpio_action + +GpioAction + +3 +delay_action + +DelayAction + + + + + + + +Node_Ja_130:e->Node_Ja_132:header + + + + + + + + +Node_Ja_131 + + + +enum +ControlCommandType + +INIT + +0 + +POWER_ON + +1 + +POWER_OFF + +2 + +SPEAKER_ON + +3 + +SPEAKER_OFF + +4 + +HEADSET_ON + +5 + +HEADSET_OFF + +6 + + + + + + +Node_Ja_130:e->Node_Ja_131 + + + + + + + + +Node_Ja_133 + + + +RegisterAction +1 +reg + +int32 +2 +val + +int32 +3 +mode + +Mode + + + + + + +Node_Ja_132:e->Node_Ja_133:header + + + + + + + + +Node_Ja_135 + + + +GpioAction +1 +gpio + +int32 +2 +level + +GpioActionLevel + + + + + + +Node_Ja_132:e->Node_Ja_135:header + + + + + + + + +Node_Ja_136 + + + +DelayAction +1 +delay + +int32 + + + + + + +Node_Ja_132:e->Node_Ja_136:header + + + + + + + + +Node_Ja_166 + + + +Config +1 +gpios + +Gpios +2 +dev + +Dev +3 +services + +Services +4 +device_name + +string + + + + + + +Node_Ja_166:e->Node_Ja_126:header + + + + + + + + +Node_Ja_105 + + + +Gpios +1 +greenLED + +GPIO +2 +redLED + +GPIO +3 +audioJack + +GPIO +4 +amp + +GPIO +5 +power + +GPIO +6 +ir + +GPIO +7 +jack + +GPIO +8 +spkfault + +GPIO +9 +Vcc + +GPIO +10 +GND + +GPIO + + + + + + +Node_Ja_166:e->Node_Ja_105:header + + + + + + + + +Node_Ja_165 + + + +Dev +1 +spi + +SPIBus +2 +i2c + +I2CBus +3 +dac + +DAC +4 +spdif + +SPDIF +5 +display + +Display +[...] +6 +gpio_exp + +GPIOExp +7 +led_strip + +LEDStrip +8 +rotary + +Rotary +[...] +9 +buttons + +Button +10 +eth + +Eth +11 +battery + +Battery + + + + + + +Node_Ja_166:e->Node_Ja_165:header + + + + + + + + +Node_Ja_164 + + + +LEDStrip +1 +WS2812 + +WS2812 + + + + + + +Node_Ja_164:e->Node_Ja_163:header + + + + + + + + +Node_Ja_128 + + + +I2CBus +1 +port + +I2CPortEnum +2 +speed + +int32 +3 +sda + +GPIO +4 +scl + +GPIO + + + + + + +Node_Ja_127 + + + +enum +I2CPortEnum + +UNSPECIFIED_PORT + +0 + +I2CPort0 + +1 + +I2CPort1 + +2 + + + + + + +Node_Ja_128:e->Node_Ja_127 + + + + + + + + +Node_Ja_128:e->Node_Ja_104:header + + + + + + + + +Node_Ja_128:e->Node_Ja_104:header + + + + + + + + +Node_Ja_148 + + + +ButtonActions +1 +pressed + +ButtonAction +2 +released + +ButtonAction + + + + + + +Node_Ja_147 + + + +enum +ButtonAction + +ACTRLS_NONE + +0 + +ACTRLS_POWER + +1 + +ACTRLS_VOLUP + +2 + +ACTRLS_VOLDOWN + +3 + +ACTRLS_TOGGLE + +4 + +ACTRLS_PLAY + +5 + +ACTRLS_PAUSE + +6 + +ACTRLS_STOP + +7 + +ACTRLS_REW + +8 + +ACTRLS_FWD + +9 + +ACTRLS_PREV + +10 + +ACTRLS_NEXT + +11 + +BCTRLS_UP + +12 + +BCTRLS_DOWN + +13 + +BCTRLS_LEFT + +14 + +BCTRLS_RIGHT + +15 + +BCTRLS_PS1 + +16 + +BCTRLS_PS2 + +17 + +BCTRLS_PS3 + +18 + +BCTRLS_PS4 + +19 + +BCTRLS_PS5 + +20 + +BCTRLS_PS6 + +21 + +BCTRLS_PS7 + +22 + +BCTRLS_PS8 + +23 + +BCTRLS_PS9 + +24 + +BCTRLS_PS10 + +25 + +KNOB_LEFT + +26 + +KNOB_RIGHT + +27 + +KNOB_PUSH + +28 + +ACTRLS_SLEEP + +29 + + + + + + +Node_Ja_148:e->Node_Ja_147 + + + + + + + + +Node_Ja_148:e->Node_Ja_147 + + + + + + + + +Node_Ja_107 + + + +GPIOExpSPI +1 +speed + +int32 +2 +host + +HostEnum +3 +cs + +GPIO + + + + + + +Node_Ja_107:e->Node_Ja_102 + + + + + + + + +Node_Ja_107:e->Node_Ja_104:header + + + + + + + + +Node_Ja_124:e->Node_Ja_104:header + + + + + + + + +Node_Ja_124:e->Node_Ja_104:header + + + + + + + + +Node_Ja_124:e->Node_Ja_104:header + + + + + + + + +Node_Ja_100 + + + +enum +DeviceTypeEnum + +UNSPECIFIED_TYPE + +0 + +DEVTYPE_SPI + +1 + +DEVTYPE_I2C + +2 + +DEVTYPE__RMII + +3 + + + + + + +Node_Ja_101 + + + +enum +PortEnum + +UNSPECIFIED_SYSTPORT + +0 + +SYSTEM + +1 + +DAC_PORT + +2 + + + + + + +Node_Ja_133:e->Node_Ja_137 + + + + + + + + +Node_Ja_159 + + + +EthRMII +1 +mdc + +GPIO +2 +mdio + +GPIO + + + + + + +Node_Ja_159:e->Node_Ja_104:header + + + + + + + + +Node_Ja_159:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_105:e->Node_Ja_104:header + + + + + + + + +Node_Ja_160 + + + +Eth +1 +type + +DeviceTypeEnum +2 +common + +EthCommon + +ethType + +3 +spi + +EthSPI + +4 +rmii + +EthRMII + + + + + + + +Node_Ja_160:e->Node_Ja_100 + + + + + + + + +Node_Ja_160:e->Node_Ja_159:header + + + + + + + + +Node_Ja_157 + + + +EthCommon +1 +model + +EthModelEnum +2 +rst + +GPIO + + + + + + +Node_Ja_160:e->Node_Ja_157:header + + + + + + + + +Node_Ja_158 + + + +EthSPI +1 +cs + +GPIO +2 +speed + +int32 +3 +intr + +GPIO +4 +host + +int32 + + + + + + +Node_Ja_160:e->Node_Ja_158:header + + + + + + + + +Node_Ja_109 + + + +GPIOExp +1 +model + +GPIOExpModelEnum +2 +addr + +int32 + +ExpType + +3 +i2c + +GPIOExpI2C + +4 +spi + +GPIOExpSPI + +5 +base + +int32 +6 +count + +int32 +7 +intr + +GPIO + + + + + + +Node_Ja_109:e->Node_Ja_107:header + + + + + + + + +Node_Ja_108 + + + +GPIOExpI2C +5 +port + +PortEnum + + + + + + +Node_Ja_109:e->Node_Ja_108:header + + + + + + + + +Node_Ja_106 + + + +enum +GPIOExpModelEnum + +UNSPECIFIED_EXP + +0 + +PCA9535 + +1 + +PCA85XX + +2 + +MCP23017 + +3 + +MCP23S17 + +4 + + + + + + +Node_Ja_109:e->Node_Ja_106 + + + + + + + + +Node_Ja_109:e->Node_Ja_104:header + + + + + + + + +Node_Ja_129 + + + +DacControlSet +[...] +1 +commands + +ControlCommand + + + + + + +Node_Ja_129:e->Node_Ja_130:header + + + + + + + + +Node_Ja_149 + + + +Button +1 +gpio + +GPIO +2 +pull + +bool +3 +debounce + +int32 +4 +shifter + +GPIO +5 +longduration + +int32 +6 +normal + +ButtonActions +7 +longpress + +ButtonActions +8 +shifted + +ButtonActions +9 +longshifted + +ButtonActions + + + + + + +Node_Ja_149:e->Node_Ja_148:header + + + + + + + + +Node_Ja_149:e->Node_Ja_148:header + + + + + + + + +Node_Ja_149:e->Node_Ja_148:header + + + + + + + + +Node_Ja_149:e->Node_Ja_148:header + + + + + + + + +Node_Ja_149:e->Node_Ja_104:header + + + + + + + + +Node_Ja_149:e->Node_Ja_104:header + + + + + + + + +Node_Ja_119 + + + +enum +DebugComponent + +NONE + +0 + +SLIMPROTO + +1 + +STREAM + +2 + +DECODE + +3 + +OUTPUT + +4 + +IR + +5 + +ALL + +6 + + + + + + +Node_Ja_134 + + + +enum +GpioActionLevel + +ACTION_LEVEL_UNDEFINED + +0 + +ACTION_LEVEL_1 + +1 + +ACTION_LEVEL_0 + +2 + + + + + + +Node_Ja_108:e->Node_Ja_101 + + + + + + + + +Node_Ja_110 + + + +Artwork +1 +enabled + +bool +2 +resize + +bool + + + + + + +Node_Ja_125:e->Node_Ja_110:header + + + + + + + + +Node_Ja_151 + + + +Rotary +1 +A + +GPIO +2 +B + +GPIO +3 +SW + +GPIO +4 +knobonly + +KnobOnly +5 +volume + +bool +6 +longpress + +bool + + + + + + +Node_Ja_151:e->Node_Ja_150:header + + + + + + + + +Node_Ja_151:e->Node_Ja_104:header + + + + + + + + +Node_Ja_151:e->Node_Ja_104:header + + + + + + + + +Node_Ja_151:e->Node_Ja_104:header + + + + + + + + +Node_Ja_120 + + + +RatesOption +1 +min + +SampleRate +2 +max + +SampleRate +[...] +3 +list + +SampleRate + + + + + + +Node_Ja_120:e->Node_Ja_117 + + + + + + + + +Node_Ja_120:e->Node_Ja_117 + + + + + + + + +Node_Ja_120:e->Node_Ja_117 + + + + + + + + +Node_Ja_122 + + + +DebugOption +1 +component + +DebugComponent +2 +level + +DebugLevelEnum + + + + + + +Node_Ja_122:e->Node_Ja_119 + + + + + + + + +Node_Ja_118 + + + +enum +DebugLevelEnum + +DEFAULT + +0 + +INFO + +1 + +DEBUG + +2 + +SDEBUG + +3 + + + + + + +Node_Ja_122:e->Node_Ja_118 + + + + + + + + +Node_Ja_135:e->Node_Ja_134 + + + + + + + + +Node_Ja_154 + + + +Battery +1 +channel + +BatteryChannelEnum +2 +scale + +float +3 +cells + +int32 +4 +atten + +BatteryAttenEnum + + + + + + +Node_Ja_154:e->Node_Ja_153 + + + + + + + + +Node_Ja_152 + + + +enum +BatteryChannelEnum + +UNSPECIFIED_CH + +0 + +CH0 + +1 + +CH1 + +2 + +CH2 + +3 + +CH3 + +4 + +CH4 + +5 + +CH5 + +6 + +CH6 + +7 + +CH7 + +8 + + + + + + +Node_Ja_154:e->Node_Ja_152 + + + + + + + + +Node_Ja_161 + + + +SPDIF +1 +dc + +GPIO +2 +data + +GPIO +3 +clk + +GPIO + + + + + + +Node_Ja_161:e->Node_Ja_104:header + + + + + + + + +Node_Ja_161:e->Node_Ja_104:header + + + + + + + + +Node_Ja_161:e->Node_Ja_104:header + + + + + + + + +Node_Ja_113 + + + +enum +OutputTypeEnum + +OUTPUT_UNKNOWN + +0 + +OUTPUT_I2S + +1 + +OUTPUT_SPDIF + +2 + +OUTPUT_Bluetooth + +3 + + + + + + +Node_Ja_155 + + + +enum +EthModelEnum + +UNSPECIFIED_ETHMODEL + +0 + +LAN8720 + +1 + +DM9051 + +2 + +W5500 + +3 + + + + + + +Node_Ja_157:e->Node_Ja_155 + + + + + + + + +Node_Ja_157:e->Node_Ja_104:header + + + + + + + + +Node_Ja_165:e->Node_Ja_162:header + + + + + + + + +Node_Ja_165:e->Node_Ja_164:header + + + + + + + + +Node_Ja_165:e->Node_Ja_128:header + + + + + + + + +Node_Ja_165:e->Node_Ja_160:header + + + + + + + + +Node_Ja_165:e->Node_Ja_109:header + + + + + + + + +Node_Ja_165:e->Node_Ja_149:header + + + + + + + + +Node_Ja_165:e->Node_Ja_151:header + + + + + + + + +Node_Ja_165:e->Node_Ja_154:header + + + + + + + + +Node_Ja_165:e->Node_Ja_161:header + + + + + + + + +Node_Ja_146 + + + +Display +1 +type + +DeviceTypeEnum +2 +common + +DispCommon + +dispType + +3 +i2c + +I2CDisplay + +4 +spi + +SPIDisplay + + + + + + + +Node_Ja_165:e->Node_Ja_146:header + + + + + + + + +Node_Ja_140 + + + +DAC +1 +bck + +GPIO +2 +ws + +GPIO +3 +dout + +GPIO +4 +mck + +MCKEnum +5 +mute + +GPIO +6 +model + +DACModelEnum +7 +i2c + +I2CBus +8 +daccontrolset + +DacControlSet + + + + + + +Node_Ja_165:e->Node_Ja_140:header + + + + + + + + +Node_Ja_144 + + + +SPIDisplay +1 +cs + +GPIO +4 +speed + +int32 +5 +rotate + +bool + + + + + + +Node_Ja_144:e->Node_Ja_104:header + + + + + + + + +Node_Ja_146:e->Node_Ja_143:header + + + + + + + + +Node_Ja_146:e->Node_Ja_100 + + + + + + + + +Node_Ja_146:e->Node_Ja_144:header + + + + + + + + +Node_Ja_145 + + + +DispCommon +1 +width + +int32 +2 +height + +int32 +3 +HFlip + +bool +4 +VFlip + +bool +5 +driver + +DisplayDriverEnum +6 +bitDepth + +int32 +7 +back + +GPIO +8 +reset + +GPIO +9 +ready + +GPIO +10 +offsets + +DispOffsets + + + + + + +Node_Ja_146:e->Node_Ja_145:header + + + + + + + + +Node_Ja_114 + + + +OutputBT +1 +sink_name + +string + + + + + + +Node_Ja_138 + + + +enum +DACModelEnum + +UNSPECIFIED_MODEL + +0 + +TAS57xx + +1 + +TAS5713 + +2 + +AC101 + +3 + +WM8978 + +4 + +ES8388 + +5 + +I2S + +6 + + + + + + +Node_Ja_140:e->Node_Ja_139 + + + + + + + + +Node_Ja_140:e->Node_Ja_128:header + + + + + + + + +Node_Ja_140:e->Node_Ja_129:header + + + + + + + + +Node_Ja_140:e->Node_Ja_138 + + + + + + + + +Node_Ja_140:e->Node_Ja_104:header + + + + + + + + +Node_Ja_140:e->Node_Ja_104:header + + + + + + + + +Node_Ja_140:e->Node_Ja_104:header + + + + + + + + +Node_Ja_140:e->Node_Ja_104:header + + + + + + + + +Node_Ja_123:e->Node_Ja_120:header + + + + + + + + +Node_Ja_123:e->Node_Ja_122:header + + + + + + + + +Node_Ja_123:e->Node_Ja_113 + + + + + + + + +Node_Ja_123:e->Node_Ja_114:header + + + + + + + + +Node_Ja_145:e->Node_Ja_141:header + + + + + + + + +Node_Ja_145:e->Node_Ja_104:header + + + + + + + + +Node_Ja_145:e->Node_Ja_104:header + + + + + + + + +Node_Ja_145:e->Node_Ja_104:header + + + + + + + + +Node_Ja_142 + + + +enum +DisplayDriverEnum + +UNSPECIFIED_DRIVER + +0 + +SSD1306 + +1 + +SSD1322 + +2 + +SSD1326 + +3 + +SSD1327 + +4 + +SH1106 + +5 + +SSD1675 + +6 + +ST7735 + +7 + +ST7789 + +8 + +ILI9341 + +9 + +ILI9341_24 + +10 + +SSD1351 + +11 + + + + + + +Node_Ja_145:e->Node_Ja_142 + + + + + + + + +Node_Ja_158:e->Node_Ja_104:header + + + + + + + + +Node_Ja_158:e->Node_Ja_104:header + + + + + + + + diff --git a/protobuf/generated/customoptions.dot b/protobuf/generated/customoptions.dot new file mode 100644 index 00000000..23ede03e --- /dev/null +++ b/protobuf/generated/customoptions.dot @@ -0,0 +1,29 @@ +/* + do not edit: + auto-generated by github.com/seamia/protodot +*/ +digraph protodot { + + /* package: */ + /* source: C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/proto/customoptions.proto */ + /* selection: * */ + + rankdir=LR; + label=""; + tooltip=""; + bgcolor="transparent" + + node [ + shape=plaintext + fontsize=10 + fontname="Ubuntu" + ]; + + + /* ------ nodes ------ */ + Node_Ja_100 [shape=plaintext tooltip=".CustomOptions" label=<
CustomOptions
50001init_from_macbool
50002const_prefixstring
50003read_onlybool
50004default_valuestring
50005global_namestring
>]; + + /* ------ connections ------ */ + + /* generated by github.com/seamia/protodot on Friday, 24-Nov-23 14:36:38 EST */ +} diff --git a/protobuf/generated/customoptions.dot.png b/protobuf/generated/customoptions.dot.png new file mode 100644 index 00000000..ae74d717 Binary files /dev/null and b/protobuf/generated/customoptions.dot.png differ diff --git a/protobuf/generated/customoptions.dot.svg b/protobuf/generated/customoptions.dot.svg new file mode 100644 index 00000000..4e58ce49 --- /dev/null +++ b/protobuf/generated/customoptions.dot.svg @@ -0,0 +1,43 @@ + + + + + + +protodot + + +Node_Ja_100 + + + +CustomOptions +50001 +init_from_mac + +bool +50002 +const_prefix + +string +50003 +read_only + +bool +50004 +default_value + +string +50005 +global_name + +string + + + + + + diff --git a/protobuf/proto/AirPlay.proto b/protobuf/proto/AirPlay.proto new file mode 100644 index 00000000..8c5b0440 --- /dev/null +++ b/protobuf/proto/AirPlay.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; +import "nanopb.proto"; +package sys; +message AirPlay { + option (nanopb_msgopt).msgid = 1001; + bool enabled = 1; + uint32 port = 2 [(nanopb).int_size = IS_8]; +} \ No newline at end of file diff --git a/protobuf/proto/Artwork.proto b/protobuf/proto/Artwork.proto new file mode 100644 index 00000000..4006a9d4 --- /dev/null +++ b/protobuf/proto/Artwork.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; +package sys; +import "nanopb.proto"; + +message Artwork { + option (nanopb_msgopt).msgid = 1002; + bool enabled = 1 ; // Enable cover art display + bool resize = 2 ; // Optional parameter to indicate if the artwork should be resized + } \ No newline at end of file diff --git a/protobuf/proto/Battery.proto b/protobuf/proto/Battery.proto new file mode 100644 index 00000000..6abf6f12 --- /dev/null +++ b/protobuf/proto/Battery.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +package sys; +import "nanopb.proto"; +option (nanopb_fileopt).enum_to_string = true; +enum BatteryChannelEnum { + UNSPECIFIED_CH = 0; + CH0 = 1; + CH1 = 2; + CH2 = 3; + CH3 = 4; + CH4 = 5; + CH5 = 6; + CH6 = 7; + CH7 = 8; + } + + enum BatteryAttenEnum { + UNSPECIFIED_ATT = 0; + ATT_0 = 1; + ATT_1 = 2; + ATT_2 = 3; + ATT_3 = 4; + } + message Battery { + option (nanopb_msgopt).msgid = 1003; + BatteryChannelEnum channel = 1; + float scale = 2; + int32 cells = 3 [(nanopb).int_size = IS_8]; + BatteryAttenEnum atten = 4; + } \ No newline at end of file diff --git a/protobuf/proto/Buttons.proto b/protobuf/proto/Buttons.proto new file mode 100644 index 00000000..b2be769b --- /dev/null +++ b/protobuf/proto/Buttons.proto @@ -0,0 +1,85 @@ +syntax = "proto3"; + +package sys; +import "GPIO.proto"; +import "nanopb.proto"; +option (nanopb_fileopt).enum_to_string = true; + +enum ButtonAction { + ACTRLS_NONE = 0; + ACTRLS_POWER = 1; + ACTRLS_VOLUP = 2; + ACTRLS_VOLDOWN = 3; + ACTRLS_TOGGLE = 4; + ACTRLS_PLAY = 5; + ACTRLS_PAUSE = 6; + ACTRLS_STOP = 7; + ACTRLS_REW = 8; + ACTRLS_FWD = 9; + ACTRLS_PREV = 10; + ACTRLS_NEXT = 11; + BCTRLS_UP = 12; + BCTRLS_DOWN = 13; + BCTRLS_LEFT = 14; + BCTRLS_RIGHT = 15; + BCTRLS_PS1 = 16; + BCTRLS_PS2 = 17; + BCTRLS_PS3 = 18; + BCTRLS_PS4 = 19; + BCTRLS_PS5 = 20; + BCTRLS_PS6 = 21; + BCTRLS_PS7 = 22; + BCTRLS_PS8 = 23; + BCTRLS_PS9 = 24; + BCTRLS_PS10 = 25; + KNOB_LEFT = 26; + KNOB_RIGHT = 27; + KNOB_PUSH = 28; + ACTRLS_SLEEP = 29; +} +// Message for ButtonActions +message ButtonActions { + option (nanopb_msgopt).msgid = 10004; + ButtonAction pressed = 1 ; + ButtonAction released = 2 ; +} +message Button { + option (nanopb_msgopt).msgid = 10005; + GPIO gpio = 1; + bool pull = 2; + int32 debounce = 3; + GPIO shifter = 4; + int32 longduration = 5; + ButtonActions normal = 6; + ButtonActions longpress = 7; + ButtonActions shifted = 8; + ButtonActions longshifted = 9; +} +message KnobOnly { + option (nanopb_msgopt).msgid = 10006; + // This mode attempts to offer a single knob full navigation which is a bit contorded due to LMS UI's + // principles. Left, Right and Press obey to LMS's navigation rules and especially Press always goes to + // lower submenu item, even when navigating in the Music Library. That causes a challenge as there is no + // 'Play', 'Back' or 'Pause' button. Workaround are as of below: + // - longpress is 'Play' + // - double press is 'Back' (Left in LMS's terminology). + // - a quick left-right movement on the encoder is 'Pause' + // + // The speed of double click (or left-right) can be set using the optional parameter of 'knobonly'. + // This is not a perfect solution, and other ideas are welcome. Be aware that the longer you set double + // click speed, the less responsive the interface will be. The reason is that I need to wait for that + // delay before deciding if it's a single or double click. It can also make menu navigation "hesitations" + // being easily interpreted as 'Pause' + bool enable = 1; // Enable/disable + int32 delay_ms = 2; // optionally set the delay + +} +message Rotary { + option (nanopb_msgopt).msgid = 10007; + GPIO A = 1; + GPIO B = 2; + GPIO SW = 3; + KnobOnly knobonly = 4; + bool volume = 5; + bool longpress = 6; +} diff --git a/protobuf/proto/CMakeLists.txt b/protobuf/proto/CMakeLists.txt new file mode 100644 index 00000000..02cfb79f --- /dev/null +++ b/protobuf/proto/CMakeLists.txt @@ -0,0 +1,46 @@ +# Append nanopb path to CMAKE_MODULE_PATH for finding the nanopb package +cmake_minimum_required(VERSION 3.16) +include(../protobuf_utils.cmake) +configure_env() + +file(GLOB_RECURSE PROTO_FILES *.proto) +# set(NANOPB_OPTIONS "-I${CMAKE_CURRENT_SOURCE_DIR}") +nanopb_generate_cpp(PROTO_SRCS PROTO_HDRS RELPATH ${CMAKE_CURRENT_SOURCE_DIR} ${PROTO_FILES}) + + +# Create a custom target to generate the proto files +set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS} PROPERTIES GENERATED TRUE) +add_custom_target(generate_system_proto DEPENDS ${PROTO_SRCS} ${PROTO_HDRS}) + + +add_library(platform_protobuf STATIC ${PROTO_SRCS} ${PROTO_HDRS}) +# PUBLIC to propagate includes from bell to cspot dependents +target_compile_definitions(platform_protobuf PUBLIC PB_ENABLE_MALLOC) +target_compile_definitions(platform_protobuf PUBLIC PB_FIELD_32BIT) +target_include_directories(platform_protobuf PUBLIC "include" ${CMAKE_CURRENT_BINARY_DIR} ${NANOPB_INCLUDE_DIRS} ${EXTRA_INCLUDES}) + + + +# Link the generated proto library to your main targets +target_link_libraries(__idf_platform_config PRIVATE platform_protobuf) +target_link_libraries(__idf_wifi-manager PRIVATE platform_protobuf) +target_include_directories(__idf_platform_config PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/proto) + + + +# Add nanopb includes +set(CMAKE_INCLUDE_GLOBAL_DIRS ON) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${NANOPB_INCLUDE_DIRS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I") +idf_build_set_property(INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR} APPEND) +foreach(PATH_ENTRY ${NANOPB_INCLUDE_DIRS}) + idf_build_set_property(INCLUDE_DIRECTORIES ${PATH_ENTRY} APPEND) +endforeach() + +set(NANOPB_GENERATOR_SOURCE_DIR "${NANOPB_GENERATOR_SOURCE_DIR}" PARENT_SCOPE) +set(PROTO_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/proto;${NANOPB_GENERATOR_SOURCE_DIR}/proto" PARENT_SCOPE) +set(PROTO_FILES "${PROTO_FILES}" PARENT_SCOPE) +set(PROTO_SRCS "${PROTO_SRCS}" PARENT_SCOPE) +set(PROTO_HDRS "${PROTO_HDRS}" PARENT_SCOPE) + diff --git a/protobuf/proto/Common.proto b/protobuf/proto/Common.proto new file mode 100644 index 00000000..383c3ba8 --- /dev/null +++ b/protobuf/proto/Common.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + +package sys; +import "nanopb.proto"; +option (nanopb_fileopt).enum_to_string = true; + +enum DeviceTypeEnum { + UNSPECIFIED_TYPE = 0; + DEVTYPE_SPI = 1; + DEVTYPE_I2C = 2; + DEVTYPE__RMII = 3; +} + +enum PortEnum { + UNSPECIFIED_SYSTPORT = 0; + SYSTEM = 1; + DAC_PORT = 2; +} + +enum HostEnum { + UNSPECIFIED_HOST = 0; + Host0 = 1; + Host1 = 2; +} diff --git a/protobuf/proto/DAC.proto b/protobuf/proto/DAC.proto new file mode 100644 index 00000000..fb85adb5 --- /dev/null +++ b/protobuf/proto/DAC.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; + +package sys; +import "GPIO.proto"; +import "DacControlSet.proto"; +import "I2CBus.proto"; +import "customoptions.proto"; +import "nanopb.proto"; +option (nanopb_fileopt).enum_to_string = true; + +enum DACModelEnum { + UNSPECIFIED_MODEL = 0; + TAS57xx = 1; + TAS5713 = 2; + AC101 = 3; + WM8978 = 4; + ES8388 = 5; + I2S = 6; + CS4265 = 7; +} +enum MCKEnum { + UNSPECIFIED_MCK = 0; + MCK0 = 1; + MCK1 = 2; + MCK2 = 3; +} + +message DAC { + option (nanopb_msgopt).msgid = 10008; + GPIO bck = 1 [(cust_field).read_only = true] ; + GPIO ws = 2; + GPIO dout = 3; + MCKEnum mck = 4; + GPIO mute = 5; + DACModelEnum model = 6; + I2CBus i2c = 7; + DacControlSet daccontrolset = 8; + bool jack_mutes_amp = 9; +} \ No newline at end of file diff --git a/protobuf/proto/DacControlSet.proto b/protobuf/proto/DacControlSet.proto new file mode 100644 index 00000000..65c304db --- /dev/null +++ b/protobuf/proto/DacControlSet.proto @@ -0,0 +1,63 @@ +syntax = "proto3"; +package sys; +import "nanopb.proto"; +option (nanopb_fileopt).enum_to_string = true; + +message DacControlSet { + option (nanopb_msgopt).msgid = 10009; + repeated ControlCommand commands = 1 [(nanopb).type = FT_POINTER]; //[(nanopb).max_count= 10]; +} + +message ControlCommand { + option (nanopb_msgopt).msgid = 10010; + ControlCommandType type = 1; + repeated ControlItem items = 2 [(nanopb).type = FT_POINTER]; //[(nanopb).max_count= 50]; +} + +enum ControlCommandType { + INIT = 0; + POWER_ON = 1; + POWER_OFF = 2; + SPEAKER_ON = 3; + SPEAKER_OFF = 4; + HEADSET_ON = 5; + HEADSET_OFF = 6; +} + +message ControlItem { + option (nanopb_msgopt).msgid = 10011; + oneof item_type { + RegisterAction reg_action = 1; + GpioAction gpio_action = 2; + DelayAction delay_action = 3; + } +} + +message RegisterAction { + option (nanopb_msgopt).msgid = 10012; + int32 reg = 1[(nanopb).int_size = IS_8]; + int32 val = 2 [(nanopb).int_size = IS_8]; + Mode mode = 3; +} + +enum GpioActionLevel { + ACTION_LEVEL_UNDEFINED = 0; + ACTION_LEVEL_1 = 1; + ACTION_LEVEL_0 = 2; +} +message GpioAction { + option (nanopb_msgopt).msgid = 10013; + int32 gpio = 1 [(nanopb).int_size = IS_8]; + GpioActionLevel level = 2; +} + +message DelayAction { + option (nanopb_msgopt).msgid = 10014; + int32 delay = 1; // Delay in milliseconds +} + +enum Mode { + REG_MODE_NOTHING = 0; + REG_MODE_OR = 1; + REG_MODE_AND = 2; +} diff --git a/protobuf/proto/Devices.proto b/protobuf/proto/Devices.proto new file mode 100644 index 00000000..e2c440a9 --- /dev/null +++ b/protobuf/proto/Devices.proto @@ -0,0 +1,69 @@ +syntax = "proto3"; + +package sys; +import "GPIO.proto"; +import "Common.proto"; +import "I2CBus.proto"; +import "DAC.proto"; +import "Display.proto"; +import "Buttons.proto"; +import "Battery.proto"; +import "Ethernet.proto"; +import "nanopb.proto"; +message SPDIF { + option (nanopb_msgopt).msgid = 10015; + GPIO dc = 1; + GPIO data = 2; + GPIO clk = 3; + } + + + message SPIBus { + option (nanopb_msgopt).msgid = 10016; + GPIO mosi = 1; + GPIO miso = 2; + GPIO clk = 3; + GPIO dc = 4; + HostEnum host = 5; // Defaults to Host1 in your application logic + } + enum LEDStripType { + LS_UNKNOWN = 0; + LS_WS2812 = 1; + //unsupported + LS_SK6812 = 2; + //unsupported + LS_APA106 = 3; + } + + + message LEDStrip { + option (nanopb_msgopt).msgid = 10018; + GPIO gpio = 1; + int32 length = 2 [(nanopb).int_size = IS_16]; + LEDStripType strip_type = 3; + } + enum InfraredType { + IR_UNKNOWN = 0; + IR_RC5 = 1; + IR_NEC = 2; + } + message Infrared { + InfraredType type = 1; + GPIO gpio = 2; + } + + message Dev { + option (nanopb_msgopt).msgid = 10019; + SPIBus spi = 1; + I2CBus i2c = 2; + DAC dac = 3; + SPDIF spdif = 4; + Display display = 5; + repeated GPIOExp gpio_exp = 6 [(nanopb).type = FT_POINTER]; //[(nanopb).max_count= 4]; + LEDStrip led_strip = 7; + Rotary rotary = 8; + repeated Button buttons = 9 [(nanopb).type = FT_POINTER]; //[(nanopb).max_count= 15]; + Eth eth = 10; + Battery battery = 11; + Infrared ir = 12; + } \ No newline at end of file diff --git a/protobuf/proto/Display.proto b/protobuf/proto/Display.proto new file mode 100644 index 00000000..645fcb35 --- /dev/null +++ b/protobuf/proto/Display.proto @@ -0,0 +1,68 @@ +syntax = "proto3"; + +package sys; +import "GPIO.proto"; +import "Common.proto"; +import "nanopb.proto"; +option (nanopb_fileopt).enum_to_string = true; + +message DispOffsets { + option (nanopb_msgopt).msgid = 10020; + int32 height =1 [(nanopb).int_size = IS_16]; + int32 width =2 [(nanopb).int_size = IS_16]; +} + +enum DisplayDriverEnum { + UNSPECIFIED_DRIVER = 0; + SSD1306 = 1; + SSD1322 = 2; + SSD1326 = 3; + SSD1327 = 4; + SH1106 = 5; + SSD1675 = 6; + ST7735 = 7; + ST7789 = 8; + ILI9341 = 9; + ILI9341_24 = 10; + SSD1351 = 11; +} + + +message I2CDisplay { + option (nanopb_msgopt).msgid = 10021; + int32 address = 1 [(nanopb).int_size = IS_8]; +} + +message SPIDisplay { + option (nanopb_msgopt).msgid = 10022; + GPIO cs = 1; + int32 speed = 4 ; +} + + +message DispCommon { + option (nanopb_msgopt).msgid = 10023; + int32 width = 1 [(nanopb).int_size = IS_16]; + int32 height = 2 [(nanopb).int_size = IS_16]; + bool HFlip = 3; + bool VFlip = 4; + DisplayDriverEnum driver = 5; + int32 bitDepth = 6 [(nanopb).int_size = IS_8]; // Defaults to Depth1 in your application logic + GPIO back = 7; + GPIO reset = 8; + GPIO ready = 9; + DispOffsets offsets = 10; + bool rotate = 11; + bool invert = 12; + bool colow_swap = 13; +} + +message Display { + option (nanopb_msgopt).msgid = 10024; + DeviceTypeEnum type = 1; + DispCommon common = 2; + oneof dispType { + I2CDisplay i2c = 3; + SPIDisplay spi = 4; + } +} \ No newline at end of file diff --git a/protobuf/proto/Equalizer.proto b/protobuf/proto/Equalizer.proto new file mode 100644 index 00000000..7e79bb69 --- /dev/null +++ b/protobuf/proto/Equalizer.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package sys; + +import "nanopb.proto"; + +message Equalizer { + repeated float gains = 1 [(nanopb).max_count = 10]; + float loudness = 2; +} \ No newline at end of file diff --git a/protobuf/proto/Ethernet.proto b/protobuf/proto/Ethernet.proto new file mode 100644 index 00000000..e9e3ebe6 --- /dev/null +++ b/protobuf/proto/Ethernet.proto @@ -0,0 +1,52 @@ +syntax = "proto3"; + +package sys; +import "Common.proto"; +import "GPIO.proto"; +import "nanopb.proto"; +import "customoptions.proto"; +option (nanopb_fileopt).enum_to_string = true; + +enum EthModelEnum { + UNSPECIFIED_ETHMODEL = 0; + LAN8720 = 1; + DM9051 = 2; + W5500 = 3; +} +enum EthType { // This enum is used to define the union type for Eth + UNSPECIFIED_ETH = 0; // for unspecified type + SPI = 1; + RMII = 2; +} +message EthCommon { + option (nanopb_msgopt).msgid = 10025; + EthModelEnum model = 1; + GPIO rst = 2; +} + +// SPI Specific Ethernet definitions +message EthSPI { + option (nanopb_msgopt).msgid = 10026; + GPIO cs = 1; // CS pin + int32 speed = 2 [(nanopb).int_size = IS_16]; // SPI Bus speed + GPIO intr = 3; + int32 host = 4 [(nanopb).int_size = IS_8,(cust_field).v_int32 = 2 ]; // Defaults to 2 in your application logic +} + +// RMII Specific Ethernet definitions +message EthRMII { + option (nanopb_msgopt).msgid = 10027; + GPIO mdc = 1; + GPIO mdio = 2; +} + +// Ethernet module configuration +message Eth { + option (nanopb_msgopt).msgid = 10028; + DeviceTypeEnum type = 1; + EthCommon common = 2; + oneof ethType { + EthSPI spi = 3; + EthRMII rmii = 4; + } +} \ No newline at end of file diff --git a/protobuf/proto/GPIO.proto b/protobuf/proto/GPIO.proto new file mode 100644 index 00000000..b188963f --- /dev/null +++ b/protobuf/proto/GPIO.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; + +package sys; +import "Common.proto"; +import "customoptions.proto"; +import "nanopb.proto"; +option (nanopb_fileopt).enum_to_string = true; + +enum LevelsEnum { + L_LOW = 0; + L_HIGH = 1; +} +// GPIO to use for the specified function +message GPIO { + option (nanopb_msgopt).msgid = 10130; + int32 pin = 1 [(nanopb).int_size = IS_8, (cust_field).v_int32 = -1]; // a valid esp32 gpio pin that supports the intended mode + LevelsEnum level = 2 [(cust_field).v_enum = "L_HIGH"]; // 0 or 1 +} +enum LedTypesEnum { + UNKNOWN = 0; + LED_TYPE_GPIO = 1; + LED_TYPE_WS2812 = 2; +} +message LED { + option (nanopb_msgopt).msgid = 10029; + GPIO gpio = 1 [(nanopb).int_size = IS_8]; // a valid esp32 gpio pin that supports the intended mode + int32 brightness = 2 [(nanopb).int_size = IS_8]; // 0 to 100% + LedTypesEnum led_type = 3; +} +message Gpios { + option (nanopb_msgopt).msgid = 10030; + LED greenLED = 1; + LED redLED = 2; + GPIO audioJack = 3; + GPIO amp = 4; + GPIO power = 5 ; + GPIO jack = 6; + GPIO spkfault = 7; + GPIO Vcc = 8; + GPIO GND = 9; +} +enum GPIOExpModelEnum { + UNSPECIFIED_EXP = 0; + PCA9535 = 1; + PCA85XX = 2; + MCP23017 = 3; + MCP23S17 = 4; +} + +message GPIOExpI2C { + option (nanopb_msgopt).msgid = 10032; + PortEnum port = 5 [(cust_field).v_string = "SYSTEM"]; // Defaults to system +} +message GPIOExpSPI { + option (nanopb_msgopt).msgid = 10031; + int32 speed = 1 [(nanopb).int_size = IS_16]; + HostEnum host = 2; + GPIO cs = 3; +} +message GPIOExp { + option (nanopb_msgopt).msgid = 10033; + GPIOExpModelEnum model = 1; + int32 addr = 2 [(nanopb).int_size = IS_8]; + oneof ExpType { + GPIOExpI2C i2c = 3; + GPIOExpSPI spi = 4; + } + int32 base = 5 [(cust_field).v_int32 = 40]; // Defaults to 40 + int32 count = 6 [(cust_field).v_int32 = 16]; // Defaults to 16 + GPIO intr = 7; + + +} \ No newline at end of file diff --git a/protobuf/proto/I2CBus.proto b/protobuf/proto/I2CBus.proto new file mode 100644 index 00000000..dca532da --- /dev/null +++ b/protobuf/proto/I2CBus.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package sys; +import "GPIO.proto"; +import "nanopb.proto"; +option (nanopb_fileopt).enum_to_string = true; + +enum I2CPortEnum { + UNSPECIFIED_PORT = 0; + I2CPort0 = 1; + I2CPort1 = 2; +} +message I2CBus { + option (nanopb_msgopt).msgid = 10034; + I2CPortEnum port = 1 ; + int32 speed = 2 [(nanopb).int_size = IS_16]; + GPIO sda = 3; + GPIO scl = 4; +} \ No newline at end of file diff --git a/protobuf/proto/Names.proto b/protobuf/proto/Names.proto new file mode 100644 index 00000000..4453a2e2 --- /dev/null +++ b/protobuf/proto/Names.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package sys; + +import "customoptions.proto"; +import "nanopb.proto"; +// Main system configuration definition. This gets loaded in a pointer +// named platform-> which is available across the build +message Names { + option (cust_msg).init_from_mac = true; + option (cust_msg).const_prefix = "squeezelite-"; + option (nanopb_msgopt).max_length= 128; + // Network device name + string device = 1 ; + // AirPlay device name + string airplay = 2; + // Spotify device name + string spotify = 3; + // Bluetooth player name advertized + string bluetooth = 4; + // Player name reported to the Logitech Media Server + string squeezelite = 5; + // Wifi Access Point name + string wifi_ap_name = 6; +} \ No newline at end of file diff --git a/protobuf/proto/Network.proto b/protobuf/proto/Network.proto new file mode 100644 index 00000000..2b9194b1 --- /dev/null +++ b/protobuf/proto/Network.proto @@ -0,0 +1,74 @@ +syntax = "proto3"; +import "google/protobuf/timestamp.proto"; + + +package sys; +import "customoptions.proto"; +import "nanopb.proto"; +enum WifiAuthTypeEnum{ + AUTH_UNKNOWN = 0; + AUTH_OPEN = 1; + AUTH_WEP = 2; + AUTH_WPA_PSK = 3; + AUTH_WPA2_PSK = 4; + AUTH_WPA_WPA2_PSK = 5; + AUTH_WPA2_ENTERPRISE = 6; + AUTH_WPA3_PSK = 7; + AUTH_WPA2_WPA3_PSK = 8; + AUTH_WAPI_PSK = 9; +} +enum WifiRadioTypesEnum { + PHY_UNKNOWN = 0; + PHY_11B = 1; + PHY_11G = 2; + PHY_11N = 3; + PHY_LR = 4; + PHY_WPS = 5; + PHY_FTM_RESPONDER = 6; + PHY_FTM_INITIATOR = 7; +} + +message IP { + option (nanopb_msgopt).msgid = 10051; + string ip = 14 [(nanopb).max_length = 15]; + string netmask = 15 [(nanopb).max_length = 15]; + string gw = 16 [(nanopb).max_length = 15]; + } + + message WifiSTAEntry { + string ssid = 1 [(nanopb).max_length = 32]; + string bssid = 2 [(nanopb).max_length = 32]; + uint32 channel = 3 [(nanopb).int_size = IS_8]; /**< channel of target AP. Set to 1~13 to scan starting from the specified channel before connecting to AP. If the channel of AP is unknown, set it to 0.*/ + WifiAuthTypeEnum auth_type = 4; + WifiRadioTypesEnum radio_type = 5; + google.protobuf.Timestamp last_try = 6; + google.protobuf.Timestamp last_seen = 7; + bool connected = 8; + string password = 9 [(nanopb).max_length = 64]; + uint32 rssi = 10 [(nanopb).max_length = 8]; +} +message WifiAP { + IP ip = 1; + string password = 2 [(nanopb).max_length = 64]; + uint32 channel = 3 [(nanopb).int_size = IS_8]; /**< channel of Access point AP. */ + WifiAuthTypeEnum auth_mode = 4 [(cust_field).v_enum = "AUTH_WPA2_PSK"]; + bool hidden = 5; + // Max allowed connections. 4 is recommended + uint32 max_connection = 6 [(nanopb).int_size = IS_8]; + // Recommended value: 100 + uint32 beacon_interval = 7 [(nanopb).int_size = IS_16]; +} +message Server { + option (nanopb_msgopt).msgid = 10050; + int32 cport = 1; + int32 port = 2; + string ip = 3 [(nanopb).max_length = 15]; + } +message NetworkConfig { + bool disable_dhcp = 1; + IP manual_ip = 2; + // Wifi Credentials + repeated WifiSTAEntry credentials = 3 [ (nanopb).max_count = 5 ]; + WifiAP ap = 4; + WifiSTAEntry last_connected = 5 ; +} \ No newline at end of file diff --git a/protobuf/proto/Services.proto b/protobuf/proto/Services.proto new file mode 100644 index 00000000..7a02418f --- /dev/null +++ b/protobuf/proto/Services.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; + +package sys; + +import "GPIO.proto"; +import "Artwork.proto"; +import "Spotify.proto"; +import "AirPlay.proto"; +import "Squeezelite.proto"; +import "Equalizer.proto"; +import "nanopb.proto"; +import "customoptions.proto"; + +// Configuration for sleep service +message SleepService { + option (nanopb_msgopt).msgid = 10035; + // Inactivity in minutes before going to sleep + uint32 delay = 1; + + // Inactivity delay in minutes after which sleep resumes + int32 spurious = 2 [(nanopb).int_size = IS_16]; + + // GPIO for sleep + GPIO sleep = 3; + + // List of GPIOs that will cause the system to wake up + repeated GPIO wake = 4 [(nanopb).type = FT_POINTER]; //[(nanopb).max_count= 10]; + + // List of RTC GPIOs to keep active + repeated GPIO rtc = 5 [(nanopb).type = FT_POINTER]; //[(nanopb).max_count= 10]; + + // Threshold in volts under which the system will enter into sleep + float batt = 6; + } +message Telnet { + bool enable = 1; + uint32 block = 2 [(nanopb).int_size = IS_16]; + uint32 buffer = 3 [(nanopb).int_size = IS_16]; + +} + message Metadata { + option (nanopb_msgopt).msgid = 10036; + // Optional parameters controlling bluetooth and airplay + // Display format with optional keywords %artist%, %album%, %title% + string format = 1 [(nanopb).max_length= 50]; + + // Scrolling speed in ms + uint32 speed = 2 ; + + // Pause time between scrolls in ms + uint32 pause = 3; + + // Cover art display configuration + Artwork artwork = 4; + } + + message BluetoothSink { + bool enabled = 1; + uint32 volume = 2; + string pin = 3 [(nanopb).max_length = 16,(cust_field).v_string = "0000" ]; + + } + + message Services { + option (nanopb_msgopt).msgid = 10037; + Metadata metadata = 1; + SleepService sleep = 2; + Spotify cspot = 4; + AirPlay airplay = 5; + Squeezelite squeezelite = 6; + string release_url = 7 [(nanopb).max_length = 256, (cust_field).v_string = "https://api.github.com/repos/sle118/squeezelite-esp32/releases"]; + BluetoothSink bt_sink = 8; + bool statistics = 9 [(cust_field).v_bool = false]; + Telnet telnet = 10; + Equalizer equalizer = 11; + } \ No newline at end of file diff --git a/protobuf/proto/Spotify.proto b/protobuf/proto/Spotify.proto new file mode 100644 index 00000000..3646e234 --- /dev/null +++ b/protobuf/proto/Spotify.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +import "customoptions.proto"; +import "nanopb.proto"; +package sys; +message Spotify { + option (nanopb_msgopt).msgid = 10038; + bool enabled = 1; + uint32 bitrate = 2 [(nanopb).int_size = IS_16]; + bool zeroconf = 3 [(cust_field).v_bool = true] ; + uint32 volume = 4 ; +} \ No newline at end of file diff --git a/protobuf/proto/Squeezelite.proto b/protobuf/proto/Squeezelite.proto new file mode 100644 index 00000000..66ba757d --- /dev/null +++ b/protobuf/proto/Squeezelite.proto @@ -0,0 +1,127 @@ +syntax = "proto3"; +import "customoptions.proto"; +import "nanopb.proto"; +option (nanopb_fileopt).enum_to_string = true; + +package sys; +enum OutputTypeEnum { + OUTPUT_UNKNOWN = 0; + OUTPUT_I2S = 1; + OUTPUT_SPDIF = 2; + OUTPUT_Bluetooth = 3; +} +message OutputBT { + option (nanopb_msgopt).msgid = 10039; + string sink_name = 1 [(nanopb).max_length= 128]; + string pin = 2 [(nanopb).max_length= 16]; +} +// Enum for the type of resampling algorithm +enum ResampleAlgorithm { + RA_DISABLED = 0; + RA_BASIC_LINEAR = 1; // Basic linear interpolation + RA_THIRTEEN_TAPS = 2; // 13 taps + RA_TWENTY_ONE_TAPS = 3; // 21 taps +} + +// ResampleOptions represents the resampling options for Squeezelite +message ResampleOptions { + option (nanopb_msgopt).msgid = 10040; + ResampleAlgorithm algorithm = 1; // The resampling algorithm to use + bool interpolate_filter_coefficients = 2; // Whether to interpolate filter coefficients +} + +enum SampleRate { + SAMPLE_RATE_UNSPECIFIED = 0; // Default value, can be used to represent an unspecified rate + SAMPLE_RATE_8000 = 8000; + SAMPLE_RATE_11025 = 11025; + SAMPLE_RATE_12000 = 12000; + SAMPLE_RATE_16000 = 16000; + SAMPLE_RATE_22050 = 22050; + SAMPLE_RATE_24000 = 24000; + SAMPLE_RATE_32000 = 32000; + SAMPLE_RATE_44100 = 44100; + SAMPLE_RATE_48000 = 48000; + SAMPLE_RATE_88200 = 88200; + SAMPLE_RATE_96000 = 96000; + SAMPLE_RATE_176400 = 176400; + SAMPLE_RATE_192000 = 192000; + SAMPLE_RATE_352800 = 352800; + SAMPLE_RATE_384000 = 384000; + SAMPLE_RATE_705600 = 705600; + SAMPLE_RATE_768000 = 768000; +} +enum DebugLevelEnum { + DEFAULT = 0; + ERROR = 1; + WARN = 2; + INFO = 3; + DEBUG = 4; + SDEBUG = 5; +} +enum CodexEnum { + c_undefined = 0; + c_alac = 1; + c_ogg = 2; + c_ops = 3; + c_flac = 4; + c_pcm = 5; + c_mp3 = 6; + c_mad = 7; + c_mpg = 8; +} +message RatesOption { + option (nanopb_msgopt).msgid = 10041; + SampleRate min = 1; + SampleRate max = 2; + repeated SampleRate list = 3 [(nanopb).type = FT_POINTER]; // [(nanopb).max_count= 10]; +} +message BufferOption { + option (nanopb_msgopt).msgid = 10042; + uint32 stream = 1 [(cust_field).v_uint32 = 500]; + uint32 output = 2 [(cust_field).v_uint32 = 2000]; +} +message DebugOptions { + DebugLevelEnum output = 1 [(cust_field).v_string = "WARN"]; + DebugLevelEnum stream = 2 [(cust_field).v_string = "WARN"]; + DebugLevelEnum decode = 3 [(cust_field).v_string = "WARN"]; + DebugLevelEnum slimproto = 4 [(cust_field).v_string = "WARN"]; + DebugLevelEnum ir = 5 [(cust_field).v_string = "WARN"]; +} + +message Squeezelite { + option (nanopb_msgopt).msgid = 10044; + // Output device configuration + OutputTypeEnum output_type = 1 [(cust_field).v_string = "OUTPUT_I2S"]; + + // Sample rates supported + RatesOption rates = 2; + + // Timeout (seconds) for switching off amp GPIO + // default is to keep the device 'on' all the time + int32 amp_gpio_timeout = 3 [(cust_field).v_int32 = 30]; + + // tRead wave and aiff format from header, ignore server parameters + bool wav_aiff_header_parsing = 4; + + // Server connection options + string server_name_ip = 5 [(nanopb).max_length= 128]; + uint32 server_port = 6; + + // Allow disabling squeezelite to use the + // device in "detached mode" + bool enabled = 7; + + OutputBT output_bt = 8; + + // enable debugging here + DebugOptions log = 9 ; + + // Max sample rate reported to server + uint32 max_rate = 10; + + BufferOption buffers = 11; + string resample = 12 [(nanopb).type = FT_POINTER]; + repeated CodexEnum included_codex = 13 [(nanopb).type = FT_POINTER]; + repeated CodexEnum excluded_codex = 14 [(nanopb).type = FT_POINTER]; + +} \ No newline at end of file diff --git a/protobuf/proto/State.proto b/protobuf/proto/State.proto new file mode 100644 index 00000000..67d91bad --- /dev/null +++ b/protobuf/proto/State.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package sys; +import "Network.proto"; +import "Equalizer.proto"; +import "nanopb.proto"; + +option (nanopb_fileopt).enum_to_string = true; + +message State { + WifiSTAEntry connected_sta = 1; + Server lms = 2; + string ota_url = 3 [(nanopb).type = FT_POINTER]; + string cspot_credentials = 4 [(nanopb).type = FT_POINTER]; + int32 bt_sink_volume = 5 ; + Equalizer equalizer = 6; +} \ No newline at end of file diff --git a/protobuf/proto/Status.proto b/protobuf/proto/Status.proto new file mode 100644 index 00000000..5f6dda94 --- /dev/null +++ b/protobuf/proto/Status.proto @@ -0,0 +1,125 @@ +syntax = "proto3"; +package sys; +import "Network.proto"; +import "nanopb.proto"; + +option (nanopb_fileopt).enum_to_string = true; +// Enum for APP_AV_STATE +enum CONNECTED_IF { + IF_UNKNOWN = 0; + IF_WIFI = 1; + IF_ETHERNET = 2; +} +enum AV_STATE { + A_IDLE = 0; + A_DISCOVERING = 1; + A_DISCOVERED = 2; + A_UNCONNECTED = 3; + A_CONNECTING = 4; + A_CONNECTED = 5; + A_DISCONNECTING = 6; + } + enum MEDIA_STATE { + M_IDLE = 0; + M_STARTING = 1; + M_STARTED = 2; + M_STOPPING = 3; + M_WAIT_DISCONNECT = 4; + } + enum UPDATE_REASONS { + R_UNKNOWN = 0; + R_CONNECTION_OK = 1; + R_FAILED_ATTEMPT = 2; + R_USER_DISCONNECT = 3; + R_LOST_CONNECTION = 4; + R_FAILED_ATTEMPT_AND_RESTORE = 5; + R_ETHERNET_CONNECTED = 6; + } + // Enum for ESP_AVRC_CT + enum ESP_AVRC_CT { + ESP_AVRC_CT_CONNECTION_STATE_EVT = 0; + ESP_AVRC_CT_PASSTHROUGH_RSP_EVT = 1; + ESP_AVRC_CT_METADATA_RSP_EVT = 2; + ESP_AVRC_CT_PLAY_STATUS_RSP_EVT = 3; + ESP_AVRC_CT_CHANGE_NOTIFY_EVT = 4; + ESP_AVRC_CT_REMOTE_FEATURES_EVT = 5; + ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT = 6; + ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT = 7; + } + enum NetworkStates { + NET_UNKNOWN = 0; + NET_INSTANTIATED = 1; + NET_INITIALIZING = 2; + NET_ETH_ACTIVE = 3; + NET_WIFI_ACTIVE = 4; + NET_WIFI_CONFIGURING_ACTIVE = 5; + } + enum EthStates { + ETH_UNKNOWN = 0; + ETH_STARTING = 1; + ETH_ACTIVE_LINKUP = 2; + ETH_ACTIVE_LINKDOWN = 3; + ETH_ACTIVE_CONNECTED = 4; + ETH_CONNECTING_NEW = 5; + } + enum WifiState { + WIFI_UNKNOWN = 0; + WIFI_INITIALIZING = 1; + WIFI_CONNECTING = 2; + WIFI_CONNECTING_NEW = 3; + WIFI_CONNECTING_NEW_FAILED = 4; + WIFI_CONNECTED = 5; + WIFI_USER_DISCONNECTED = 6; + WIFI_LOST_CONNECTION = 7; + } + + +message WIFI { + option (nanopb_msgopt).msgid = 10052; + WifiSTAEntry connected_sta = 1; + int32 disconnect_count = 2; + float avg_conn_time = 3; + repeated WifiSTAEntry scan_result = 4 [ (nanopb).type = FT_POINTER ]; + WifiState wifi_state = 5; +} +message NET { + option (nanopb_msgopt).msgid = 10053; + WIFI wifi = 1; + IP ip = 2; + NetworkStates network_state = 5; + EthStates eth_state = 6; + bool eth_up = 7; + UPDATE_REASONS updt_reason = 8; + CONNECTED_IF interface = 9; + +} +message BT { + option (nanopb_msgopt).msgid = 10054; + AV_STATE bt_status = 1; + ESP_AVRC_CT bt_sub_status = 2; + MEDIA_STATE bt_media_state = 3; +} +message PLATFORM { + option (nanopb_msgopt).msgid = 10055; + string project = 1 [(nanopb).max_length = 128]; + string version = 2 [(nanopb).max_length = 25]; + bool recovery = 3; + string name = 4 [(nanopb).max_length = 55]; + int32 depth = 5; +} +message HW { + option (nanopb_msgopt).msgid = 10056; + bool jack_inserted = 1; + float batt_voltage = 2; + bool has_jack_inserted = 3; + bool spk_fault = 4; + bool has_spk_fault = 5; +} +message Status { + option (nanopb_msgopt).msgid = 10057; + PLATFORM platform = 1; + HW hw = 2; + BT bt = 3; + Server LMS = 4; + NET net = 5; +} diff --git a/protobuf/proto/configuration.proto b/protobuf/proto/configuration.proto new file mode 100644 index 00000000..0637509b --- /dev/null +++ b/protobuf/proto/configuration.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; + +package sys; + +import "Services.proto"; +import "GPIO.proto"; +import "Devices.proto"; +import "Names.proto"; +import "Network.proto"; +import "customoptions.proto"; +import "nanopb.proto"; + + +// Main configuration structure +message Config { + + // Provides the global name for the pointer to + // protoc plugins + option (cust_msg).global_name = "platform->"; + option (nanopb_msgopt).msgid = 1000; + + // GPIO structure definition with leds, etc + Gpios gpios = 1; + + // Device tree with SPI, I2C, SPDIF, Display, etc + Dev dev = 2; + + // Platform services definition with options + Services services = 3 ; + + // Main device name used for networking, etc. Services which + // need a name typically has the option to overwrite its own name + Names names = 4; + + // Hardware platform (e.g. SqueezeAMP, MUSE, etc.) + string platform = 5 [(nanopb).type = FT_POINTER]; + + NetworkConfig net = 6; + string target = 7 [(nanopb).max_length = 55]; + +} + diff --git a/protobuf/proto/customoptions.proto b/protobuf/proto/customoptions.proto new file mode 100644 index 00000000..7f6e6183 --- /dev/null +++ b/protobuf/proto/customoptions.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; + +import "google/protobuf/descriptor.proto"; +import "nanopb.proto"; + +// Extend the field options +message CustomOptions { + bool init_from_mac = 50001; // Unique identifier for the option + string const_prefix = 50002 [(nanopb).type = FT_POINTER]; // Unique identifier for the option + bool read_only = 50003; + oneof default_value { + string v_string = 50050 [(nanopb).type = FT_POINTER]; + uint32 v_uint32 = 50051; + int32 v_int32 = 50052; + uint64 v_uint64 = 50053; + int64 v_int64 = 50054; + double v_double = 50055; + float v_float = 50056; + bool v_bool = 50057; + string v_enum = 50058 [(nanopb).type = FT_POINTER]; + bytes v_bytes = 50059 [(nanopb).type = FT_POINTER]; + } + + string global_name = 50005 [(nanopb).type = FT_POINTER]; +} + + +extend google.protobuf.FileOptions { + optional CustomOptions cust_file = 2010; +} + + +extend google.protobuf.MessageOptions { + optional CustomOptions cust_msg = 2010; +} + +extend google.protobuf.EnumOptions { + optional CustomOptions cust_enum = 2010; +} + +extend google.protobuf.FieldOptions { + optional CustomOptions cust_field = 2010; +} diff --git a/protobuf/proto/google/protobuf/timestamp.proto b/protobuf/proto/google/protobuf/timestamp.proto new file mode 100644 index 00000000..fd0bc07d --- /dev/null +++ b/protobuf/proto/google/protobuf/timestamp.proto @@ -0,0 +1,144 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/timestamppb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TimestampProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; + +// A Timestamp represents a point in time independent of any time zone or local +// calendar, encoded as a count of seconds and fractions of seconds at +// nanosecond resolution. The count is relative to an epoch at UTC midnight on +// January 1, 1970, in the proleptic Gregorian calendar which extends the +// Gregorian calendar backwards to year one. +// +// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap +// second table is needed for interpretation, using a [24-hour linear +// smear](https://developers.google.com/time/smear). +// +// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By +// restricting to that range, we ensure that we can convert to and from [RFC +// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. +// +// # Examples +// +// Example 1: Compute Timestamp from POSIX `time()`. +// +// Timestamp timestamp; +// timestamp.set_seconds(time(NULL)); +// timestamp.set_nanos(0); +// +// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +// +// struct timeval tv; +// gettimeofday(&tv, NULL); +// +// Timestamp timestamp; +// timestamp.set_seconds(tv.tv_sec); +// timestamp.set_nanos(tv.tv_usec * 1000); +// +// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +// +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); +// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +// +// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +// Timestamp timestamp; +// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +// +// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +// +// long millis = System.currentTimeMillis(); +// +// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +// .setNanos((int) ((millis % 1000) * 1000000)).build(); +// +// Example 5: Compute Timestamp from Java `Instant.now()`. +// +// Instant now = Instant.now(); +// +// Timestamp timestamp = +// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) +// .setNanos(now.getNano()).build(); +// +// Example 6: Compute Timestamp from current time in Python. +// +// timestamp = Timestamp() +// timestamp.GetCurrentTime() +// +// # JSON Mapping +// +// In JSON format, the Timestamp type is encoded as a string in the +// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +// where {year} is always expressed using four digits while {month}, {day}, +// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). +// +// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +// 01:30 UTC on January 15, 2017. +// +// In JavaScript, one can convert a Date object to this format using the +// standard +// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +// method. In Python, a standard `datetime.datetime` object can be converted +// to this format using +// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with +// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use +// the Joda Time's [`ISODateTimeFormat.dateTime()`]( +// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime() +// ) to obtain a formatter capable of generating timestamps in this format. +// +message Timestamp { + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + int64 seconds = 1; + + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + int32 nanos = 2; +} diff --git a/protobuf/proto/requirements.txt b/protobuf/proto/requirements.txt new file mode 100644 index 00000000..2972f9d9 --- /dev/null +++ b/protobuf/proto/requirements.txt @@ -0,0 +1,2 @@ +mypy-protobuf +importlib \ No newline at end of file diff --git a/protobuf/protobuf_utils.cmake b/protobuf/protobuf_utils.cmake new file mode 100644 index 00000000..1c3c741a --- /dev/null +++ b/protobuf/protobuf_utils.cmake @@ -0,0 +1,158 @@ +cmake_minimum_required(VERSION 3.16) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/components/spotify/cspot/bell/external/nanopb/extra") + +set(TOOLS_DIR "${CMAKE_SOURCE_DIR}/tools" ) +set(GENERATED_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/generated") +set(GENERATED_PY_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/py") +set(GENERATED_JS_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/js") + + + +find_package(PythonInterp REQUIRED) +# Function to replace a placeholder in a list +function(replace_in_list INPUT_LIST PLACEHOLDER REPLACEMENT OUTPUT_LIST) + set(TEMP_LIST "") + foreach(ITEM ${${INPUT_LIST}}) + string(REPLACE ${PLACEHOLDER} ${REPLACEMENT} ITEM ${ITEM}) + list(APPEND TEMP_LIST "${ITEM}") + endforeach() + set(${OUTPUT_LIST} ${TEMP_LIST} PARENT_SCOPE) +endfunction() + +function(encode_special_chars INPUT_VAR) + set(ENCODED_STRING "${${INPUT_VAR}}") + + # Encoding common special characters. Start with % so that + # we don't collide with encodings if we process that char + # later. + string(REPLACE "%" "%25" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE ":" "%3A" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "-" "%2D" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "=" "%3D" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "&" "%26" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "?" "%3F" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "/" "%2F" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE " " "%20" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "!" "%21" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "@" "%40" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "#" "%23" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "$" "%24" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "^" "%5E" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "*" "%2A" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "(" "%28" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE ")" "%29" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "+" "%2B" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "{" "%7B" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "}" "%7D" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "[" "%5B" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "]" "%5D" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "|" "%7C" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "\\" "%5C" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE ";" "%3B" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "'" "%27" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "\"" "%22" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "<" "%3C" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE ">" "%3E" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "," "%2C" ENCODED_STRING "${ENCODED_STRING}") + string(REPLACE "`" "%60" ENCODED_STRING "${ENCODED_STRING}") + # Add more replacements as needed + + # Set the result in the parent scope + set(${INPUT_VAR} "${ENCODED_STRING}" PARENT_SCOPE) +endfunction() + + +function(array_to_delimited DELIMITER VAR_NAME) + # Initialize the result variable + set(RESULT "") + set(ARR "${${VAR_NAME}}") + # Determine if ARR is a list + list(LENGTH ARR ARR_LENGTH) + + if(${ARR_LENGTH} GREATER 0) + # Handle ARR as ITEMS + foreach(ARRAY_ENTRY IN ITEMS ${ARR}) + set(RESULT "${RESULT}${ARRAY_ENTRY}${DELIMITER}") + endforeach() + else() + # Handle ARR as a LIST + foreach(ARRAY_ENTRY IN LISTS ${ARR}) + set(RESULT "${RESULT}${ARRAY_ENTRY}${DELIMITER}") + endforeach() + endif() + + # Remove the trailing delimiter + # string(REGEX REPLACE "${DELIMITER}$" "" RESULT "${RESULT}") + # encode_special_chars(RESULT) + set(${VAR_NAME}_DELIMITED "${RESULT}" PARENT_SCOPE) +endfunction() + + + + +function(print_array MSG ARR) + # Determine if ARR is a list + list(LENGTH ARR ARR_LENGTH) + + # Check for the optional parameter to print each item on a new line + list(LENGTH ARGN ARG_COUNT) + + + if(ARG_COUNT EQUAL 1) + # Get the first (and only) item in ARGN + list(GET ARGN 0 ARGN_FIRST_ITEM) + endif() + if(ARG_COUNT EQUAL 1 AND ARGN_FIRST_ITEM STREQUAL "NEWLINE") + if(${ARR_LENGTH} GREATER 0) + message(STATUS "${MSG} [ITEMS]") + foreach(ARRAY_ENTRY IN ITEMS ${ARR}) + message(STATUS " - ${ARRAY_ENTRY}") + endforeach() + else() + message(STATUS "${MSG} [LISTS]") + foreach(ARRAY_ENTRY IN LISTS ${ARR}) + message(STATUS " - ${ARRAY_ENTRY}") + endforeach() + endif() + else() + # Default behavior: concatenate the message and array entries + set(OUTSTRING "") + + if(${ARR_LENGTH} GREATER 0) + foreach(ARRAY_ENTRY IN ITEMS ${ARR}) + set(OUTSTRING "${OUTSTRING} ${ARRAY_ENTRY}") + endforeach() + else() + foreach(ARRAY_ENTRY IN LISTS ${ARR}) + set(OUTSTRING "${OUTSTRING} ${ARRAY_ENTRY}") + endforeach() + endif() + + message(STATUS "${MSG}${OUTSTRING}") + endif() +endfunction() + +function(configure_env) + if(CMAKE_HOST_WIN32) + set(PROTODOT_BINARY "${TOOLS_DIR}/protodot/binaries/protodot-windows-amd64.exe" PARENT_SCOPE) + set(CONFIG_FILE "${TOOLS_DIR}/protodot/config-win.json" PARENT_SCOPE) + set(PROTOC_BINARY "${TOOLS_DIR}/protobuf/win64/bin/protoc.exe" PARENT_SCOPE) + set(PROTOBUF_INCLUDE_DIR "${TOOLS_DIR}/protobuf/win64/include/google/protobuf" PARENT_SCOPE) + set(PROTOC_PLUGIN_SUFFIX ".bat" PARENT_SCOPE) + else() + set(PROTODOT_BINARY "${TOOLS_DIR}/protodot/binaries/protodot-linux-amd64" PARENT_SCOPE) + set(CONFIG_FILE "${TOOLS_DIR}/protodot/config.json" PARENT_SCOPE) + set(PROTOC_BINARY "${TOOLS_DIR}/protobuf/linux-x86_64/bin/protoc" PARENT_SCOPE) + set(PROTOBUF_INCLUDE_DIR "${TOOLS_DIR}/protobuf/linux-x86_64/include/google/protobuf" PARENT_SCOPE) + set(PROTOC_PLUGIN_SUFFIX ".py" PARENT_SCOPE) + # else() + # message(FATAL_ERROR "Unsupported operating system") + endif() +endfunction() + +set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + APPEND PROPERTY + ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/protobuf" +) + +set(PROTO_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/proto;${NANOPB_GENERATOR_SOURCE_DIR}/proto" ) \ No newline at end of file diff --git a/protobuf/targets/bureau-oled.json b/protobuf/targets/bureau-oled.json new file mode 100644 index 00000000..65eb8d39 --- /dev/null +++ b/protobuf/targets/bureau-oled.json @@ -0,0 +1,65 @@ +{ + "dev": { + "spi": { + "mosi": { + "pin": 4 + }, + "clk": { + "pin": 5 + }, + "dc": { + "pin": 18 + }, + "host": "Host1" + }, + "dac": { + "bck": { + "pin": 25 + }, + "ws": { + "pin": 26 + }, + "dout": { + "pin": 33 + }, + "model": "I2S" + }, + "display": { + "type": "DEVTYPE_SPI", + "common": { + "width": 256, + "height": 64, + "HFlip": false, + "VFlip": false, + "rotate": false, + "driver": "SSD1322", + "reset": { + "pin": 21 + } + }, + "spi": { + "cs": { + "pin": 19 + }, + "speed": 8000000 + + } + }, + "rotary": { + "A": { + "pin": 23 + }, + "B": { + "pin": 22 + }, + "SW": { + "pin": 34 + }, + "volume": true, + "longpress": true + } + }, + "names": { + "device": "bureau-oled" + } +} \ No newline at end of file diff --git a/protobuf/targets/esp32.json b/protobuf/targets/esp32.json new file mode 100644 index 00000000..2e771415 --- /dev/null +++ b/protobuf/targets/esp32.json @@ -0,0 +1,65 @@ +{ + "dev": { + "spi": { + "mosi": { + "pin": 4 + }, + "clk": { + "pin": 5 + }, + "dc": { + "pin": 18 + }, + "host": "Host1" + }, + "dac": { + "bck": { + "pin": 25 + }, + "ws": { + "pin": 26 + }, + "dout": { + "pin": 33 + }, + "model": "I2S" + }, + "display": { + "type": "DEVTYPE_SPI", + "common": { + "width": 256, + "height": 64, + "HFlip": false, + "VFlip": false, + "driver": "SSD1322", + "rotate": false, + "reset": { + "pin": 21 + } + }, + "spi": { + "cs": { + "pin": 19 + }, + "speed": 8000000 + + } + }, + "rotary": { + "A": { + "pin": 23 + }, + "B": { + "pin": 22 + }, + "SW": { + "pin": 34 + }, + "volume": true, + "longpress": true + } + }, + "names": { + "device": "bureau-oled" + } +} \ No newline at end of file diff --git a/sdkconfig b/sdkconfig index 6182580f..d6fad9e8 100644 --- a/sdkconfig +++ b/sdkconfig @@ -55,6 +55,7 @@ CONFIG_BOOTLOADER_SPI_WP_PIN=7 CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y # CONFIG_BOOTLOADER_FACTORY_RESET is not set # CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 @@ -84,6 +85,7 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set # CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y CONFIG_ESPTOOLPY_FLASHMODE="dio" CONFIG_ESPTOOLPY_FLASHFREQ_80M=y # CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set @@ -95,6 +97,9 @@ CONFIG_ESPTOOLPY_FLASHFREQ="80m" CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="4MB" CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y CONFIG_ESPTOOLPY_BEFORE_RESET=y @@ -119,6 +124,7 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # Partition Table # # CONFIG_PARTITION_TABLE_SINGLE_APP is not set +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" @@ -127,45 +133,6 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table -# -# Network Manager Configuration -# - -# -# WiFi Options -# -CONFIG_WIFI_MANAGER_TASK_PRIORITY=5 -CONFIG_WIFI_MANAGER_MAX_RETRY=2 -CONFIG_DEFAULT_AP_SSID="squeezelite" -CONFIG_DEFAULT_AP_PASSWORD="squeezelite" -CONFIG_DEFAULT_AP_CHANNEL=1 -CONFIG_DEFAULT_AP_IP="192.168.4.1" -CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1" -CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" -CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 -CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 -# end of WiFi Options - -# -# Ethernet Options -# -CONFIG_ETH_NODRIVER=y -# CONFIG_ETH_LAN8720 is not set -# CONFIG_ETH_DM9051 is not set -# CONFIG_ETH_W5500 is not set -CONFIG_ETH_PHY_RST_IO=-1 -CONFIG_ETH_MDC_IO=-1 -CONFIG_ETH_MDIO_IO=-1 -CONFIG_ETH_SPI_HOST=-1 -CONFIG_ETH_SPI_INTR_IO=-1 -CONFIG_ETH_SPI_CS_IO=-1 -CONFIG_ETH_SPI_CLK_IO=-1 -CONFIG_ETH_SPI_MOSI_IO=-1 -CONFIG_ETH_SPI_MISO_IO=-1 -CONFIG_ETH_SPI_SPEED=20000000 -# end of Ethernet Options -# end of Network Manager Configuration - CONFIG_LWIP_MAX_SOCKETS=20 # @@ -190,6 +157,8 @@ CONFIG_MUTE_GPIO_LEVEL=0 # CONFIG_MUSE is not set CONFIG_BASIC_I2C_BT=y # CONFIG_TWATCH2020 is not set +# CONFIG_WITH_CONFIG_UI is not set +# CONFIG_WITH_METRICS is not set CONFIG_RELEASE_API="https://api.github.com/repos/sle118/squeezelite-esp32/releases" CONFIG_SQUEEZELITE_ESP32_RELEASE_URL="https://github.com/sle118/squeezelite-esp32/releases" CONFIG_PROJECT_NAME="Squeezelite-ESP32" @@ -205,11 +174,13 @@ CONFIG_AUDIO_CONTROLS="" CONFIG_BAT_CONFIG="" CONFIG_TARGET="" CONFIG_AMP_GPIO=-1 +CONFIG_POWER_GPIO=-1 CONFIG_JACK_GPIO=-1 CONFIG_SPKFAULT_GPIO=-1 CONFIG_BAT_CHANNEL=-1 CONFIG_LED_GREEN_GPIO=-1 CONFIG_LED_RED_GPIO=-1 +CONFIG_SET_GPIO="" # end of Target # @@ -228,6 +199,7 @@ CONFIG_I2S_BCK_IO=-1 CONFIG_I2S_WS_IO=-1 CONFIG_I2S_DO_IO=-1 CONFIG_I2S_DI_IO=-1 +CONFIG_I2S_MCK_IO=-1 # end of I2S settings # @@ -285,7 +257,6 @@ CONFIG_CSPOT_SINK=y # Various I/O # CONFIG_I2C_CONFIG="" -CONFIG_SET_GPIO="" CONFIG_ROTARY_ENCODER="" # end of Various I/O @@ -300,9 +271,14 @@ CONFIG_ROTARY_ENCODER="" # end of Audio JACK # -# Amplifier +# External amplifier control # -# end of Amplifier +# end of External amplifier control + +# +# Power on/off status +# +# end of Power on/off status # # Speaker Fault @@ -317,6 +293,45 @@ CONFIG_ROTARY_ENCODER="" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -C 30 -W" # end of Squeezelite-ESP32 +# +# Network Manager Configuration +# + +# +# WiFi Options +# +CONFIG_WIFI_MANAGER_TASK_PRIORITY=5 +CONFIG_WIFI_MANAGER_MAX_RETRY=2 +CONFIG_DEFAULT_AP_SSID="squeezelite" +CONFIG_DEFAULT_AP_PASSWORD="squeezelite" +CONFIG_DEFAULT_AP_CHANNEL=1 +CONFIG_DEFAULT_AP_IP="192.168.4.1" +CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1" +CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" +CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 +CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 +# end of WiFi Options + +# +# Ethernet Options +# +CONFIG_ETH_NODRIVER=y +# CONFIG_ETH_LAN8720 is not set +# CONFIG_ETH_DM9051 is not set +# CONFIG_ETH_W5500 is not set +CONFIG_ETH_PHY_RST_IO=-1 +CONFIG_ETH_MDC_IO=-1 +CONFIG_ETH_MDIO_IO=-1 +CONFIG_ETH_SPI_HOST=-1 +CONFIG_ETH_SPI_INTR_IO=-1 +CONFIG_ETH_SPI_CS_IO=-1 +CONFIG_ETH_SPI_CLK_IO=-1 +CONFIG_ETH_SPI_MOSI_IO=-1 +CONFIG_ETH_SPI_MISO_IO=-1 +CONFIG_ETH_SPI_SPEED=20000000 +# end of Ethernet Options +# end of Network Manager Configuration + # # Compiler options # @@ -327,6 +342,9 @@ CONFIG_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE is not set CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=1 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y CONFIG_COMPILER_CXX_EXCEPTIONS=y CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 # CONFIG_COMPILER_CXX_RTTI is not set @@ -346,7 +364,7 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # # Application Level Tracing # -# CONFIG_APPTRACE_DEST_TRAX is not set +# CONFIG_APPTRACE_DEST_JTAG is not set CONFIG_APPTRACE_DEST_NONE=y CONFIG_APPTRACE_LOCK_ENABLE=y # end of Application Level Tracing @@ -361,10 +379,9 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # Bluetooth # CONFIG_BT_ENABLED=y -CONFIG_BT_CTRL_ESP32=y # -# Bluetooth controller(ESP32 Dual Mode Bluetooth) +# Bluetooth controller # # CONFIG_BTDM_CTRL_MODE_BLE_ONLY is not set CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y @@ -402,37 +419,9 @@ CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y # end of MODEM SLEEP Options CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 -# end of Bluetooth controller(ESP32 Dual Mode Bluetooth) - -CONFIG_BT_CTRL_MODE_EFF=1 -CONFIG_BT_CTRL_BLE_MAX_ACT=10 -CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=10 -CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0 -CONFIG_BT_CTRL_PINNED_TO_CORE=0 -CONFIG_BT_CTRL_HCI_TL=1 -CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30 -CONFIG_BT_CTRL_HW_CCA_EFF=0 -CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=0 -CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y -CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 -CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 -CONFIG_BT_CTRL_BLE_SCAN_DUPL=y -CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0 -CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100 - -# -# MODEM SLEEP Options -# -# end of MODEM SLEEP Options - -CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 -CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 -CONFIG_BT_CTRL_HCI_TL_EFF=1 - -# -# MODEM SLEEP Options -# -# end of MODEM SLEEP Options +CONFIG_BTDM_RESERVE_DRAM=0xdb5c +CONFIG_BTDM_CTRL_HLI=y +# end of Bluetooth controller CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set @@ -451,7 +440,7 @@ CONFIG_BT_CLASSIC_ENABLED=y CONFIG_BT_A2DP_ENABLE=y # CONFIG_BT_SPP_ENABLED is not set # CONFIG_BT_HFP_ENABLE is not set -# CONFIG_BT_HID_HOST_ENABLED is not set +# CONFIG_BT_HID_ENABLED is not set CONFIG_BT_SSP_ENABLED=y # CONFIG_BT_BLE_ENABLED is not set CONFIG_BT_STACK_NO_LOG=y @@ -464,10 +453,9 @@ CONFIG_BT_SMP_ENABLE=y CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_MAX_DEVICE_NAME_LEN=32 # CONFIG_BT_BLE_RPA_SUPPORTED is not set -CONFIG_BT_RESERVE_DRAM=0xdb5c +CONFIG_BT_BLE_RPA_TIMEOUT=900 +# CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL is not set # end of Bluedroid Options - -CONFIG_BT_NIMBLE_USE_ESP_TIMER=y # end of Bluetooth # CONFIG_BLE_MESH is not set @@ -492,6 +480,12 @@ CONFIG_COAP_LOG_DEFAULT_LEVEL=0 CONFIG_ADC_DISABLE_DAC=y # end of ADC configuration +# +# MCPWM configuration +# +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# end of MCPWM configuration + # # SPI configuration # @@ -509,6 +503,7 @@ CONFIG_SPI_MASTER_ISR_IN_IRAM=y # CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST is not set # CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID is not set # CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT is not set +# CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM is not set # end of TWAI configuration # @@ -528,6 +523,13 @@ CONFIG_SPI_MASTER_ISR_IN_IRAM=y # # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set # end of GPIO Configuration + +# +# GDMA Configuration +# +# CONFIG_GDMA_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GDMA_ISR_IRAM_SAFE is not set +# end of GDMA Configuration # end of Driver configurations # @@ -546,6 +548,7 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # CONFIG_ESP_TLS_USING_MBEDTLS=y # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set # CONFIG_ESP_TLS_SERVER is not set # CONFIG_ESP_TLS_PSK_VERIFICATION is not set CONFIG_ESP_TLS_INSECURE=y @@ -558,9 +561,16 @@ CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY=y CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y # CONFIG_ESP32_REV_MIN_0 is not set CONFIG_ESP32_REV_MIN_1=y +# CONFIG_ESP32_REV_MIN_1_1 is not set # CONFIG_ESP32_REV_MIN_2 is not set # CONFIG_ESP32_REV_MIN_3 is not set +# CONFIG_ESP32_REV_MIN_3_1 is not set CONFIG_ESP32_REV_MIN=1 +CONFIG_ESP32_REV_MIN_FULL=100 +CONFIG_ESP_REV_MIN_FULL=100 +CONFIG_ESP32_REV_MAX_FULL_STR_OPT=y +CONFIG_ESP32_REV_MAX_FULL=399 +CONFIG_ESP_REV_MAX_FULL=399 CONFIG_ESP32_DPORT_WORKAROUND=y # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set @@ -588,6 +598,7 @@ CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=256 CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536 CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set CONFIG_SPIRAM_CACHE_WORKAROUND=y # @@ -598,6 +609,23 @@ CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_MEMW=y # CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_NOPS is not set # end of SPIRAM cache workaround debugging +# +# SPIRAM workaround libraries placement +# +CONFIG_SPIRAM_CACHE_LIBJMP_IN_IRAM=y +CONFIG_SPIRAM_CACHE_LIBMATH_IN_IRAM=y +CONFIG_SPIRAM_CACHE_LIBNUMPARSER_IN_IRAM=y +CONFIG_SPIRAM_CACHE_LIBIO_IN_IRAM=y +CONFIG_SPIRAM_CACHE_LIBTIME_IN_IRAM=y +CONFIG_SPIRAM_CACHE_LIBCHAR_IN_IRAM=y +CONFIG_SPIRAM_CACHE_LIBMEM_IN_IRAM=y +CONFIG_SPIRAM_CACHE_LIBSTR_IN_IRAM=y +CONFIG_SPIRAM_CACHE_LIBRAND_IN_IRAM=y +CONFIG_SPIRAM_CACHE_LIBENV_IN_IRAM=y +CONFIG_SPIRAM_CACHE_LIBFILE_IN_IRAM=y +CONFIG_SPIRAM_CACHE_LIBMISC_IN_IRAM=y +# end of SPIRAM workaround libraries placement + # CONFIG_SPIRAM_BANKSWITCH_ENABLE is not set CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y # CONFIG_SPIRAM_OCCUPY_HSPI_HOST is not set @@ -629,9 +657,6 @@ CONFIG_PICO_PSRAM_CS_IO=10 # CONFIG_ESP32_TRAX is not set CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP32_ULP_COPROC_ENABLED is not set CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0 CONFIG_ESP32_DEBUG_OCDAWARE=y @@ -645,7 +670,6 @@ CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_ESP32_BROWNOUT_DET_LVL=0 -CONFIG_ESP32_REDUCE_PHY_TX_POWER=y CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y # CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set # CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set @@ -679,32 +703,6 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # Common ESP-related # CONFIG_ESP_ERR_TO_NAME_LOOKUP=y -CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3400 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 -CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 -CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y -CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 -CONFIG_ESP_CONSOLE_UART_DEFAULT=y -# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_NONE is not set -CONFIG_ESP_CONSOLE_UART=y -CONFIG_ESP_CONSOLE_MULTIPLE_UART=y -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 -CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 -CONFIG_ESP_INT_WDT_CHECK_CPU1=y -CONFIG_ESP_TASK_WDT=y -# CONFIG_ESP_TASK_WDT_PANIC is not set -CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP_PANIC_HANDLER_IRAM is not set -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y CONFIG_ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y # end of Common ESP-related @@ -714,7 +712,6 @@ CONFIG_ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y CONFIG_ETH_ENABLED=y CONFIG_ETH_USE_ESP32_EMAC=y CONFIG_ETH_PHY_INTERFACE_RMII=y -# CONFIG_ETH_PHY_INTERFACE_MII is not set CONFIG_ETH_RMII_CLK_INPUT=y # CONFIG_ETH_RMII_CLK_OUTPUT is not set CONFIG_ETH_RMII_CLK_IN_GPIO=0 @@ -724,6 +721,7 @@ CONFIG_ETH_DMA_TX_BUFFER_NUM=10 CONFIG_ETH_USE_SPI_ETHERNET=y CONFIG_ETH_SPI_ETHERNET_DM9051=y CONFIG_ETH_SPI_ETHERNET_W5500=y +# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set # CONFIG_ETH_USE_OPENETH is not set # end of Ethernet @@ -745,6 +743,7 @@ CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y # CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y # end of ESP HTTP client # @@ -770,6 +769,58 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32 # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set # end of ESP HTTPS server +# +# Hardware Settings +# + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# end of MAC Config + +# +# Sleep Config +# +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND=y +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +# end of Sleep Config + +# +# RTC Clock Config +# +# end of RTC Clock Config +# end of Hardware Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# LCD and Touch Panel +# + +# +# LCD Peripheral Configuration +# +CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + # # ESP NETIF Adapter # @@ -779,12 +830,33 @@ CONFIG_ESP_NETIF_TCPIP_LWIP=y CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y # end of ESP NETIF Adapter +# +# PHY +# +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +CONFIG_ESP_PHY_REDUCE_TX_POWER=y +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# end of PHY + # # Power Management # # CONFIG_PM_ENABLE is not set # end of Power Management +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + # # ESP System Settings # @@ -792,13 +864,39 @@ CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set # CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set -# CONFIG_ESP_SYSTEM_PSRAM_LEAKAGE_WORKAROUND is not set -# CONFIG_ESP_SYSTEM_FLASH_LEAKAGE_WORKAROUND is not set +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set # # Memory protection # # end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3400 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=14336 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_MULTIPLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5=y # end of ESP System Settings # @@ -808,6 +906,8 @@ CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set # CONFIG_ESP_TIMER_IMPL_FRC2 is not set CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # end of High resolution timer (esp_timer) @@ -815,6 +915,7 @@ CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # # Wi-Fi # +CONFIG_ESP32_WIFI_ENABLED=y CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=12 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=40 @@ -831,31 +932,21 @@ CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -# CONFIG_WIFI_LOG_DEFAULT_LEVEL_NONE is not set -# CONFIG_WIFI_LOG_DEFAULT_LEVEL_ERROR is not set -# CONFIG_WIFI_LOG_DEFAULT_LEVEL_WARN is not set -CONFIG_WIFI_LOG_DEFAULT_LEVEL_INFO=y -# CONFIG_WIFI_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_WIFI_LOG_DEFAULT_LEVEL_VERBOSE is not set # CONFIG_ESP32_WIFI_IRAM_OPT is not set # CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set # CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 # end of Wi-Fi -# -# PHY -# -CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP32_PHY_MAX_TX_POWER=20 -# end of PHY - # # Core dump # +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set # CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y # end of Core dump @@ -920,11 +1011,7 @@ CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 # CONFIG_FMB_TIMER_PORT_ENABLED is not set -CONFIG_FMB_TIMER_GROUP=0 -CONFIG_FMB_TIMER_INDEX=0 -CONFIG_FMB_MASTER_TIMER_GROUP=0 -CONFIG_FMB_MASTER_TIMER_INDEX=0 -# CONFIG_FMB_TIMER_ISR_IN_IRAM is not set +# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set # end of Modbus configuration # @@ -932,8 +1019,10 @@ CONFIG_FMB_MASTER_TIMER_INDEX=0 # # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y CONFIG_FREERTOS_HZ=100 CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set @@ -941,12 +1030,12 @@ CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 -CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=2 +# CONFIG_FREERTOS_ASSERT_FAIL_ABORT is not set # CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set -# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_ASSERT_DISABLE=y CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_ISR_STACKSIZE=2096 # CONFIG_FREERTOS_LEGACY_HOOKS is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y @@ -966,8 +1055,19 @@ CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_FREERTOS_DEBUG_OCDAWARE=y # CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set # end of FreeRTOS +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=1 +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + # # Heap memory debugging # @@ -1002,6 +1102,10 @@ CONFIG_LOG_DEFAULT_LEVEL_INFO=y # CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=3 CONFIG_LOG_COLORS=y CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set @@ -1011,6 +1115,9 @@ CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # LWIP # CONFIG_LWIP_LOCAL_HOSTNAME="SqueezeESP32" +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # CONFIG_LWIP_L2_TO_L3_COPY is not set # CONFIG_LWIP_IRAM_OPTIMIZATION is not set @@ -1030,10 +1137,15 @@ CONFIG_LWIP_IP6_REASSEMBLY=y # CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set CONFIG_LWIP_ESP_GRATUITOUS_ARP=y CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_ESP_MLDV6_REPORT=y +CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y CONFIG_LWIP_DHCP_RESTORE_LAST_IP=y +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 # # DHCP server @@ -1046,6 +1158,9 @@ CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 # CONFIG_LWIP_AUTOIP is not set CONFIG_LWIP_IPV6=y # CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -1060,6 +1175,7 @@ CONFIG_LWIP_TCP_SYNMAXRTX=6 CONFIG_LWIP_TCP_MSS=1440 CONFIG_LWIP_TCP_TMR_INTERVAL=250 CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 CONFIG_LWIP_TCP_SND_BUF_DEFAULT=8192 CONFIG_LWIP_TCP_WND_DEFAULT=32768 CONFIG_LWIP_TCP_RECVMBOX_SIZE=32 @@ -1115,11 +1231,12 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # # SNTP # -CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 # end of SNTP -# CONFIG_LWIP_ESP_LWIP_ASSERT is not set +CONFIG_LWIP_ESP_LWIP_ASSERT=y # # Hooks @@ -1130,6 +1247,9 @@ CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y # CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set # CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y # CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set # CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set @@ -1153,6 +1273,15 @@ CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA is not set # CONFIG_MBEDTLS_DEBUG is not set +# +# mbedTLS v2.28.x related +# +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +# end of mbedTLS v2.28.x related + # # Certificate Bundle # @@ -1161,6 +1290,7 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set @@ -1200,6 +1330,7 @@ CONFIG_MBEDTLS_SSL_RENEGOTIATION=y # CONFIG_MBEDTLS_SSL_PROTO_TLS1 is not set # CONFIG_MBEDTLS_SSL_PROTO_TLS1_1 is not set CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y @@ -1272,6 +1403,8 @@ CONFIG_MDNS_TASK_AFFINITY=0x0 CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 # CONFIG_MDNS_STRICT_MODE is not set CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y # end of mDNS # @@ -1302,6 +1435,7 @@ CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y # # NVS # +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set # end of NVS # @@ -1313,6 +1447,12 @@ CONFIG_OPENSSL_ASSERT_DO_NOTHING=y # CONFIG_OPENSSL_ASSERT_EXIT is not set # end of OpenSSL +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set +# end of OpenThread + # # PThreads # @@ -1344,6 +1484,7 @@ CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set # # Auto-detect flash chips @@ -1352,6 +1493,8 @@ CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set # end of Auto-detect flash chips CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y @@ -1404,22 +1547,23 @@ CONFIG_SPIFFS_USE_MTIME=y # end of Websocket # end of TCP Transport -# -# TinyUSB -# -# end of TinyUSB - # # Unity unit testing library # CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set # CONFIG_UNITY_ENABLE_COLOR is not set CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y # CONFIG_UNITY_ENABLE_FIXTURE is not set # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library +# +# Root Hub configuration +# +# end of Root Hub configuration + # # Virtual file system # @@ -1432,7 +1576,6 @@ CONFIG_VFS_SUPPORT_DIR=y # Host File System I/O (Semihosting) # CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 # end of Host File System I/O (Semihosting) # end of Virtual file system @@ -1450,6 +1593,8 @@ CONFIG_WL_SECTOR_SIZE=4096 CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 # CONFIG_WIFI_PROV_BLE_BONDING is not set +# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set # end of Wi-Fi Provisioning Manager # @@ -1457,10 +1602,13 @@ CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 # CONFIG_WPA_MBEDTLS_CRYPTO=y # CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_SUITE_B_192 is not set # CONFIG_WPA_DEBUG_PRINT is not set # CONFIG_WPA_TESTING_OPTIONS is not set # CONFIG_WPA_WPS_STRICT is not set # CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set # end of Supplicant # @@ -1515,6 +1663,7 @@ CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y # CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED is not set CONFIG_OPTIMIZATION_ASSERTIONS_SILENT=y # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=1 CONFIG_CXX_EXCEPTIONS=y CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 CONFIG_STACK_CHECK_NONE=y @@ -1556,9 +1705,6 @@ CONFIG_ADC2_DISABLE_DAC=y CONFIG_SPIRAM_SUPPORT=y CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST=y CONFIG_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set -CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y -CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 # CONFIG_ULP_COPROC_ENABLED is not set CONFIG_ULP_COPROC_RESERVE_MEM=0 CONFIG_BROWNOUT_DET=y @@ -1571,17 +1717,32 @@ CONFIG_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set # CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_BROWNOUT_DET_LVL=0 -CONFIG_REDUCE_PHY_TX_POWER=y CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y # CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set # CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set # CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set # CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set # CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set +CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y +CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +CONFIG_ESP32_REDUCE_PHY_TX_POWER=y +# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set +CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32S2_PANIC_GDBSTUB is not set CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=3400 -CONFIG_MAIN_TASK_STACK_SIZE=8192 -CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_MAIN_TASK_STACK_SIZE=14336 CONFIG_CONSOLE_UART_DEFAULT=y # CONFIG_CONSOLE_UART_CUSTOM is not set # CONFIG_ESP_CONSOLE_UART_NONE is not set @@ -1596,15 +1757,10 @@ CONFIG_TASK_WDT=y CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_EVENT_LOOP_PROFILING is not set -CONFIG_POST_EVENTS_FROM_ISR=y -CONFIG_POST_EVENTS_FROM_IRAM_ISR=y -# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set -CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y -# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP32S2_PANIC_GDBSTUB is not set +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set CONFIG_TIMER_TASK_STACK_SIZE=3584 CONFIG_SW_COEXIST_ENABLE=y +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 @@ -1619,8 +1775,6 @@ CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 CONFIG_MB_CONTROLLER_STACK_SIZE=4096 CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 # CONFIG_MB_TIMER_PORT_ENABLED is not set -CONFIG_MB_TIMER_GROUP=0 -CONFIG_MB_TIMER_INDEX=0 # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=3800 @@ -1662,5 +1816,4 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set # CONFIG_SUPPORT_TERMIOS is not set CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 # End of deprecated options diff --git a/spiffs/Config_defaults_pb.bin b/spiffs/Config_defaults_pb.bin new file mode 100644 index 00000000..9c6c5869 --- /dev/null +++ b/spiffs/Config_defaults_pb.bin @@ -0,0 +1,2 @@ +"º +squeezelite-@@init_from_mac@@squeezelite-@@init_from_mac@@squeezelite-@@init_from_mac@@"squeezelite-@@init_from_mac@@*squeezelite-@@init_from_mac@@2squeezelite-@@init_from_mac@@ \ No newline at end of file diff --git a/spiffs/fonts/droid_sans_fb_11x13.bin b/spiffs/fonts/droid_sans_fb_11x13.bin new file mode 100644 index 00000000..4f725d81 Binary files /dev/null and b/spiffs/fonts/droid_sans_fb_11x13.bin differ diff --git a/spiffs/fonts/line_1.bin b/spiffs/fonts/line_1.bin new file mode 100644 index 00000000..6f4e8c3c Binary files /dev/null and b/spiffs/fonts/line_1.bin differ diff --git a/spiffs/fonts/line_2.bin b/spiffs/fonts/line_2.bin new file mode 100644 index 00000000..01af8e69 Binary files /dev/null and b/spiffs/fonts/line_2.bin differ diff --git a/spiffs/targets/bureau-oled.bin b/spiffs/targets/bureau-oled.bin new file mode 100644 index 00000000..3e5342e8 --- /dev/null +++ b/spiffs/targets/bureau-oled.bin @@ -0,0 +1,7 @@ +N + +"( +!0* €@(B" + €¤èB +"(0" + bureau-oled \ No newline at end of file diff --git a/spiffs/targets/esp32.bin b/spiffs/targets/esp32.bin new file mode 100644 index 00000000..3e5342e8 --- /dev/null +++ b/spiffs/targets/esp32.bin @@ -0,0 +1,7 @@ +N + +"( +!0* €@(B" + €¤èB +"(0" + bureau-oled \ No newline at end of file diff --git a/squeezelite-esp32.code-workspace b/squeezelite-esp32.code-workspace new file mode 100644 index 00000000..92ca380b --- /dev/null +++ b/squeezelite-esp32.code-workspace @@ -0,0 +1,208 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "files.associations": { + "*.cps": "javascript", + "coroutine": "c", + "xmemory": "c", + "atomic": "c", + "w5500.h": "c", + "array": "c", + "bitset": "c", + "string_view": "cpp", + "initializer_list": "c", + "regex": "cpp", + "utility": "c", + "*.ipp": "c", + "deque": "c", + "list": "c", + "string": "c", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "c", + "*.tcc": "c", + "fstream": "cpp", + "strstream": "cpp", + "cctype": "cpp", + "chrono": "c", + "clocale": "cpp", + "cmath": "c", + "codecvt": "c", + "condition_variable": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "c", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "exception": "cpp", + "algorithm": "c", + "functional": "c", + "iterator": "c", + "map": "cpp", + "memory": "c", + "memory_resource": "cpp", + "numeric": "c", + "optional": "c", + "random": "c", + "ratio": "c", + "set": "cpp", + "system_error": "c", + "tuple": "c", + "type_traits": "c", + "future": "c", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "c", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "ostream": "c", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "c", + "*.inc": "c", + "network_manager.h": "c", + "platform_esp32.h": "c", + "improv.h": "c", + "esp_err.h": "c", + "esp_bt.h": "c", + "improv_server.h": "c", + "esp_bt_defs.h": "c", + "variant": "c", + "network_ethernet.h": "c", + "esp_eth.h": "c", + "esp_eth_phy.h": "c", + "accessors.h": "c", + "esp_eth_com.h": "c", + "timers.h": "c", + "esp_log.h": "c", + "adac.h": "c", + "esp_attr.h": "c", + "freertos.h": "c", + "task.h": "c", + "string.h": "c", + "queue.h": "c", + "spi_master.h": "c", + "i2s_periph.h": "c", + "rtc_periph.h": "c", + "rtc_io_periph.h": "c", + "argtable3.h": "c", + "cmd_config.h": "c", + "platform_console.h": "c", + "tools.h": "c", + "messaging.h": "c", + "Configurator.h": "c", + "esp_system.h": "c", + "esp_equalizer.h": "c", + "xiosbase": "c", + "xhash": "c", + "xtree": "c", + "xutility": "c", + "ranges": "c", + "complex": "c", + "valarray": "c", + "typeindex": "c", + "xlocale": "c", + "squeezelite.h": "c", + "nvs_flash.h": "c", + "format": "c", + "queue": "c", + "span": "c", + "stack": "c", + "xstring": "c", + "xlocmon": "c", + "xlocnum": "c", + "xtr1common": "c", + "filesystem": "c", + "network_status.h": "c", + "monitor.h": "c", + "bt_app_core.h": "c", + "squeezelite-ota.h": "c", + "esp_tls.h": "c", + "esp_image_format.h": "c", + "esp_ota_ops.h": "c", + "ESP_OTA_OPS.H": "cpp", + "compare": "c", + "esp_wifi.h": "c", + "network_wifi.h": "c", + "forward_list": "cpp", + "ios": "cpp", + "any": "cpp", + "cjson.h": "c", + "bit": "cpp", + "charconv": "cpp", + "concepts": "cpp", + "locale": "cpp", + "stop_token": "cpp", + "xfacet": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xloctime": "cpp", + "xstddef": "cpp", + "http_handlers.h": "c", + "esp_http_client.h": "c", + "stdint.h": "c", + "platform.h": "c", + "gpio.h": "c", + "configurator.h": "c", + "nvs_utilities.h": "c", + "gpio_exp.h": "c", + "gds_text.h": "c", + "gds_font.h": "c", + "gds.h": "c", + "gds_private.h": "c", + "gds_draw.h": "c", + "configuration.pb.h": "c", + "gds_default_if.h": "c", + "globdefs.h": "c", + "services.h": "c", + "esp_avrc_api.h": "c", + "status.pb.h": "c", + "daccontrolset.pb.h": "c", + "esp_spiffs.h": "c", + "custom_options.pb.h": "c", + "esp_heap_caps.h": "c", + "esp_rom_efuse.h": "c", + "pb.h": "c", + "customoptions.pb.h": "c", + "devices.pb.h": "c", + "gpio.pb.h": "c", + "services.pb.h": "c", + "esp_wifi_types.h": "c", + "names.pb.h": "c", + "network.pb.h": "c", + "stdlib.h": "c", + "dirent.h": "c", + "equalizer.h": "c", + "sys_options.h": "c", + "_stdint.h": "c", + "network_services.h": "c" + }, + "idf.espIdfPath": "/opt/esp/idf", + "idf.pythonBinPath": "/opt/esp/python_env/idf4.4_py3.8_env/bin/python", + "idf.toolsPath": "/opt/esp", + "idf.customExtraPaths": "/opt/esp/tools/xtensa-esp-elf-gdb/11.2_20220823/xtensa-esp-elf-gdb/bin:/opt/esp/tools/riscv32-esp-elf-gdb/11.2_20220823/riscv32-esp-elf-gdb/bin:/opt/esp/tools/xtensa-esp32-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32-elf/bin:/opt/esp/tools/xtensa-esp32s2-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32s2-elf/bin:/opt/esp/tools/xtensa-esp32s3-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32s3-elf/bin:/opt/esp/tools/riscv32-esp-elf/esp-2021r2-patch5-8.4.0/riscv32-esp-elf/bin:/opt/esp/tools/esp32ulp-elf/2.35_20220830/esp32ulp-elf/bin:/opt/esp/tools/cmake/3.23.1/bin:/opt/esp/tools/openocd-esp32/v0.12.0-esp32-20230419/openocd-esp32/bin", + "idf.customExtraVars": { + "OPENOCD_SCRIPTS": "/opt/esp/tools/openocd-esp32/v0.12.0-esp32-20230419/openocd-esp32/share/openocd/scripts" + }, + "idf.gitPath": "git" + }, + "launch": { + "version": "0.2.0", + "configurations": [] + } +} \ No newline at end of file diff --git a/test/CMakelists.txt b/test/CMakelists.txt index 3ca1a8b8..ee1513d0 100644 --- a/test/CMakelists.txt +++ b/test/CMakelists.txt @@ -1,9 +1,9 @@ # This is the project CMakeLists.txt file for the test subproject cmake_minimum_required(VERSION 3.5) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) # Include the components directory of the main application: # -set(EXTRA_COMPONENT_DIRS "../components") # Set the components to include the tests for. # This can be overriden from CMake cache: @@ -11,9 +11,42 @@ set(EXTRA_COMPONENT_DIRS "../components") # - when using idf.py: idf.py -T xxxxx build # set(TEST_COMPONENTS "platform_console" CACHE STRING "List of components to test") +set(COMPONENTS main) + +# Freertos is included via common components, however, currently only the mock component is compatible with linux +# target. +list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/") +list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/driver/") +list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/") +list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/spi_flash/") +list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/components/unity/") +idf_build_set_property(COMPILE_DEFINITIONS "-DNO_DEBUG_STORAGE" APPEND) + +# list(APPEND EXTRA_COMPONENT_DIRS "${PROJECT_SOURCE_DIR}/../components") +# list(APPEND EXTRA_COMPONENT_DIRS "${PROJECT_SOURCE_DIR}/../components/tools") + -include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(squeezelite_esp32_test) -add_definitions(-include "${PROJECT_SOURCE_DIR}/../build/config/sdkconfig.h") +# add_definitions(-include "${PROJECT_SOURCE_DIR}/../build/config/sdkconfig.h") + set_property(TARGET squeezelite_esp32_test.elf PROPERTY RECOVERY_PREFIX app_update ) +add_custom_command( + OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/build/coverage.info" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/build" + COMMAND lcov --capture --directory . --output-file coverage.info + COMMENT "Create coverage report" + ) + +add_custom_command( + OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/build/coverage_report/" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/build/coverage.info" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/build" + COMMAND genhtml coverage.info --output-directory coverage_report/ + COMMENT "Turn coverage report into html-based visualization" + ) + +add_custom_target(coverage + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/build" + DEPENDS "coverage_report/" + ) \ No newline at end of file diff --git a/test/main/CMakeLists.txt b/test/main/CMakeLists.txt index b0bb8924..ab820aaa 100644 --- a/test/main/CMakeLists.txt +++ b/test/main/CMakeLists.txt @@ -1,2 +1,2 @@ idf_component_register(SRCS "unit_tests.c" - INCLUDE_DIRS ".") \ No newline at end of file + INCLUDE_DIRS "." "${PROJECT_SOURCE_DIR}/../components/tools" REQUIRES unity ) \ No newline at end of file diff --git a/test/main/unit_tests.c b/test/main/unit_tests.c index 355c1321..0295cdb6 100644 --- a/test/main/unit_tests.c +++ b/test/main/unit_tests.c @@ -47,7 +47,8 @@ #include "squeezelite-ota.h" #include #include "audio_controls.h" -#include "platform_config.h" +// #include "Configurator.h" +#pragma message("fixme: search for TODO below") #include "telnet.h" #include "messaging.h" #include "gds.h" @@ -78,6 +79,8 @@ void init_commands(){ register_config_cmd(); register_nvs(); register_i2ctools(); +#if CONFIG_WITH_CONFIG_UI +#endif } void test_init() { @@ -111,6 +114,13 @@ void app_main() unity_run_menu(); } +int main(int argc, char **argv) +{ + setbuf(stdout, NULL); + app_main(); + + return 0; +} static void print_banner(const char* text) { printf("\n#### %s #####\n\n", text); diff --git a/test/sdkconfig.defaults b/test/sdkconfig.defaults new file mode 100644 index 00000000..e0f6845e --- /dev/null +++ b/test/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n +CONFIG_IDF_TARGET="linux" +CONFIG_COMPILER_CXX_EXCEPTIONS=y \ No newline at end of file diff --git a/tools/mkspiffs-0.2.3-esp-idf-win32/mkspiffs.exe b/tools/mkspiffs-0.2.3-esp-idf-win32/mkspiffs.exe new file mode 100644 index 00000000..c1d8e28e Binary files /dev/null and b/tools/mkspiffs-0.2.3-esp-idf-win32/mkspiffs.exe differ diff --git a/tools/mkspiffs-0.2.3-esp-idf-win32/temp/fonts/droid_sans_fb_11x13.bin b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/fonts/droid_sans_fb_11x13.bin new file mode 100644 index 00000000..4f725d81 Binary files /dev/null and b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/fonts/droid_sans_fb_11x13.bin differ diff --git a/tools/mkspiffs-0.2.3-esp-idf-win32/temp/fonts/line_1.bin b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/fonts/line_1.bin new file mode 100644 index 00000000..6f4e8c3c Binary files /dev/null and b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/fonts/line_1.bin differ diff --git a/tools/mkspiffs-0.2.3-esp-idf-win32/temp/fonts/line_2.bin b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/fonts/line_2.bin new file mode 100644 index 00000000..01af8e69 Binary files /dev/null and b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/fonts/line_2.bin differ diff --git a/tools/mkspiffs-0.2.3-esp-idf-win32/temp/foo.txt b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/foo.txt new file mode 100644 index 00000000..980a0d5f --- /dev/null +++ b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/foo.txt @@ -0,0 +1 @@ +Hello World! diff --git a/tools/mkspiffs-0.2.3-esp-idf-win32/temp/settings.pro b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/settings.pro new file mode 100644 index 00000000..34179c11 --- /dev/null +++ b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/settings.pro @@ -0,0 +1 @@ + "squeezelite--c29d18 \ No newline at end of file diff --git a/tools/mkspiffs-0.2.3-esp-idf-win32/temp/targets/bureau-oled.bin b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/targets/bureau-oled.bin new file mode 100644 index 00000000..01ac082b Binary files /dev/null and b/tools/mkspiffs-0.2.3-esp-idf-win32/temp/targets/bureau-oled.bin differ diff --git a/tools/protobuf/linux-x86_64/bin/protoc b/tools/protobuf/linux-x86_64/bin/protoc new file mode 100644 index 00000000..54a116af Binary files /dev/null and b/tools/protobuf/linux-x86_64/bin/protoc differ diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/any.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/any.proto new file mode 100644 index 00000000..eff44e50 --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/any.proto @@ -0,0 +1,162 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option go_package = "google.golang.org/protobuf/types/known/anypb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "AnyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// // or ... +// if (any.isSameTypeAs(Foo.getDefaultInstance())) { +// foo = any.unpack(Foo.getDefaultInstance()); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := anypb.New(foo) +// if err != nil { +// ... +// } +// ... +// foo := &pb.Foo{} +// if err := any.UnmarshalTo(foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +message Any { + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. This string must contain at least + // one "/" character. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // * If no scheme is provided, `https` is assumed. + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. As of May 2023, there are no widely used type server + // implementations and no plans to implement one. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + string type_url = 1; + + // Must be a valid serialized protocol buffer of the above specified type. + bytes value = 2; +} diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/api.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/api.proto new file mode 100644 index 00000000..42223516 --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/api.proto @@ -0,0 +1,207 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/source_context.proto"; +import "google/protobuf/type.proto"; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "ApiProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/apipb"; + +// Api is a light-weight descriptor for an API Interface. +// +// Interfaces are also described as "protocol buffer services" in some contexts, +// such as by the "service" keyword in a .proto file, but they are different +// from API Services, which represent a concrete implementation of an interface +// as opposed to simply a description of methods and bindings. They are also +// sometimes simply referred to as "APIs" in other contexts, such as the name of +// this message itself. See https://cloud.google.com/apis/design/glossary for +// detailed terminology. +message Api { + // The fully qualified name of this interface, including package name + // followed by the interface's simple name. + string name = 1; + + // The methods of this interface, in unspecified order. + repeated Method methods = 2; + + // Any metadata attached to the interface. + repeated Option options = 3; + + // A version string for this interface. If specified, must have the form + // `major-version.minor-version`, as in `1.10`. If the minor version is + // omitted, it defaults to zero. If the entire version field is empty, the + // major version is derived from the package name, as outlined below. If the + // field is not empty, the version in the package name will be verified to be + // consistent with what is provided here. + // + // The versioning schema uses [semantic + // versioning](http://semver.org) where the major version number + // indicates a breaking change and the minor version an additive, + // non-breaking change. Both version numbers are signals to users + // what to expect from different versions, and should be carefully + // chosen based on the product plan. + // + // The major version is also reflected in the package name of the + // interface, which must end in `v`, as in + // `google.feature.v1`. For major versions 0 and 1, the suffix can + // be omitted. Zero major versions must only be used for + // experimental, non-GA interfaces. + // + string version = 4; + + // Source context for the protocol buffer service represented by this + // message. + SourceContext source_context = 5; + + // Included interfaces. See [Mixin][]. + repeated Mixin mixins = 6; + + // The source syntax of the service. + Syntax syntax = 7; +} + +// Method represents a method of an API interface. +message Method { + // The simple name of this method. + string name = 1; + + // A URL of the input message type. + string request_type_url = 2; + + // If true, the request is streamed. + bool request_streaming = 3; + + // The URL of the output message type. + string response_type_url = 4; + + // If true, the response is streamed. + bool response_streaming = 5; + + // Any metadata attached to the method. + repeated Option options = 6; + + // The source syntax of this method. + Syntax syntax = 7; +} + +// Declares an API Interface to be included in this interface. The including +// interface must redeclare all the methods from the included interface, but +// documentation and options are inherited as follows: +// +// - If after comment and whitespace stripping, the documentation +// string of the redeclared method is empty, it will be inherited +// from the original method. +// +// - Each annotation belonging to the service config (http, +// visibility) which is not set in the redeclared method will be +// inherited. +// +// - If an http annotation is inherited, the path pattern will be +// modified as follows. Any version prefix will be replaced by the +// version of the including interface plus the [root][] path if +// specified. +// +// Example of a simple mixin: +// +// package google.acl.v1; +// service AccessControl { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v1/{resource=**}:getAcl"; +// } +// } +// +// package google.storage.v2; +// service Storage { +// rpc GetAcl(GetAclRequest) returns (Acl); +// +// // Get a data record. +// rpc GetData(GetDataRequest) returns (Data) { +// option (google.api.http).get = "/v2/{resource=**}"; +// } +// } +// +// Example of a mixin configuration: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// +// The mixin construct implies that all methods in `AccessControl` are +// also declared with same name and request/response types in +// `Storage`. A documentation generator or annotation processor will +// see the effective `Storage.GetAcl` method after inherting +// documentation and annotations as follows: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/{resource=**}:getAcl"; +// } +// ... +// } +// +// Note how the version in the path pattern changed from `v1` to `v2`. +// +// If the `root` field in the mixin is specified, it should be a +// relative path under which inherited HTTP paths are placed. Example: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// root: acls +// +// This implies the following inherited HTTP annotation: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; +// } +// ... +// } +message Mixin { + // The fully qualified name of the interface which is included. + string name = 1; + + // If non-empty specifies a path under which inherited HTTP paths + // are rooted. + string root = 2; +} diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/compiler/plugin.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/compiler/plugin.proto new file mode 100644 index 00000000..829cf412 --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/compiler/plugin.proto @@ -0,0 +1,168 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// Author: kenton@google.com (Kenton Varda) +// +// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path. The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +syntax = "proto2"; + +package google.protobuf.compiler; +option java_package = "com.google.protobuf.compiler"; +option java_outer_classname = "PluginProtos"; + +option csharp_namespace = "Google.Protobuf.Compiler"; +option go_package = "google.golang.org/protobuf/types/pluginpb"; + +import "google/protobuf/descriptor.proto"; + +// The version number of protocol compiler. +message Version { + optional int32 major = 1; + optional int32 minor = 2; + optional int32 patch = 3; + // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should + // be empty for mainline stable releases. + optional string suffix = 4; +} + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + repeated string file_to_generate = 1; + + // The generator parameter passed on the command-line. + optional string parameter = 2; + + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // Note: the files listed in files_to_generate will include runtime-retention + // options only, but all other files will include source-retention options. + // The source_file_descriptors field below is available in case you need + // source-retention options for files_to_generate. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + // + // Type names of fields and extensions in the FileDescriptorProto are always + // fully qualified. + repeated FileDescriptorProto proto_file = 15; + + // File descriptors with all options, including source-retention options. + // These descriptors are only provided for the files listed in + // files_to_generate. + repeated FileDescriptorProto source_file_descriptors = 17; + + // The version number of protocol compiler. + optional Version compiler_version = 3; +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + optional string error = 1; + + // A bitmask of supported features that the code generator supports. + // This is a bitwise "or" of values from the Feature enum. + optional uint64 supported_features = 2; + + // Sync with code_generator.h. + enum Feature { + FEATURE_NONE = 0; + FEATURE_PROTO3_OPTIONAL = 1; + FEATURE_SUPPORTS_EDITIONS = 2; + } + + // Represents a single generated file. + message File { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + optional string name = 1; + + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + optional string insertion_point = 2; + + // The file contents. + optional string content = 15; + + // Information describing the file content being inserted. If an insertion + // point is used, this information will be appropriately offset and inserted + // into the code generation metadata for the generated files. + optional GeneratedCodeInfo generated_code_info = 16; + } + repeated File file = 15; +} diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/descriptor.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/descriptor.proto new file mode 100644 index 00000000..47486435 --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/descriptor.proto @@ -0,0 +1,1218 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + +syntax = "proto2"; + +package google.protobuf; + +option go_package = "google.golang.org/protobuf/types/descriptorpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; +option csharp_namespace = "Google.Protobuf.Reflection"; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; +} + +// The full set of known editions. +enum Edition { + // A placeholder for an unknown edition value. + EDITION_UNKNOWN = 0; + + // Legacy syntax "editions". These pre-date editions, but behave much like + // distinct editions. These can't be used to specify the edition of proto + // files, but feature definitions must supply proto2/proto3 defaults for + // backwards compatibility. + EDITION_PROTO2 = 998; + EDITION_PROTO3 = 999; + + // Editions that have been released. The specific values are arbitrary and + // should not be depended on, but they will always be time-ordered for easy + // comparison. + EDITION_2023 = 1000; + + // Placeholder editions for testing feature resolution. These should not be + // used or relyed on outside of tests. + EDITION_1_TEST_ONLY = 1; + EDITION_2_TEST_ONLY = 2; + EDITION_99997_TEST_ONLY = 99997; + EDITION_99998_TEST_ONLY = 99998; + EDITION_99999_TEST_ONLY = 99999; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; + + // The syntax of the proto file. + // The supported values are "proto2", "proto3", and "editions". + // + // If `edition` is present, this value must be "editions". + optional string syntax = 12; + + // The edition of the proto file. + optional Edition edition = 14; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + + optional ExtensionRangeOptions options = 3; + } + repeated ExtensionRange extension_range = 5; + + repeated OneofDescriptorProto oneof_decl = 8; + + optional MessageOptions options = 7; + + // Range of reserved tag numbers. Reserved tag numbers may not be used by + // fields or extension ranges in the same message. Reserved ranges may + // not overlap. + message ReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + } + repeated ReservedRange reserved_range = 9; + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + repeated string reserved_name = 10; +} + +message ExtensionRangeOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + message Declaration { + // The extension number declared within the extension range. + optional int32 number = 1; + + // The fully-qualified name of the extension field. There must be a leading + // dot in front of the full name. + optional string full_name = 2; + + // The fully-qualified type name of the extension field. Unlike + // Metadata.type, Declaration.type must have a leading dot for messages + // and enums. + optional string type = 3; + + // If true, indicates that the number is reserved in the extension range, + // and any extension field with the number will fail to compile. Set this + // when a declared extension field is deleted. + optional bool reserved = 5; + + // If true, indicates that the extension must be defined as repeated. + // Otherwise the extension must be defined as optional. + optional bool repeated = 6; + + reserved 4; // removed is_repeated + } + + // For external users: DO NOT USE. We are in the process of open sourcing + // extension declaration and executing internal cleanups before it can be + // used externally. + repeated Declaration declaration = 2 [retention = RETENTION_SOURCE]; + + // Any features defined in the specific edition. + optional FeatureSet features = 50; + + // The verification state of the extension range. + enum VerificationState { + // All the extensions of the range must be declared. + DECLARATION = 0; + UNVERIFIED = 1; + } + + // The verification state of the range. + // TODO: flip the default to DECLARATION once all empty ranges + // are marked as UNVERIFIED. + optional VerificationState verification = 3 [default = UNVERIFIED]; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + // Tag-delimited aggregate. + // Group type is deprecated and not supported after google.protobuf. However, Proto3 + // implementations should still be able to parse the group wire format and + // treat group fields as unknown fields. In Editions, the group wire format + // can be enabled via the `message_encoding` feature. + TYPE_GROUP = 10; + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + } + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REPEATED = 3; + // The required label is only allowed in google.protobuf. In proto3 and Editions + // it's explicitly prohibited. In Editions, the `field_presence` feature + // can be used to get this behavior. + LABEL_REQUIRED = 2; + } + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + optional string default_value = 7; + + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + optional int32 oneof_index = 9; + + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + optional string json_name = 10; + + optional FieldOptions options = 8; + + // If true, this is a proto3 "optional". When a proto3 field is optional, it + // tracks presence regardless of field type. + // + // When proto3_optional is true, this field must be belong to a oneof to + // signal to old proto3 clients that presence is tracked for this field. This + // oneof is known as a "synthetic" oneof, and this field must be its sole + // member (each proto3 optional field gets its own synthetic oneof). Synthetic + // oneofs exist in the descriptor only, and do not generate any API. Synthetic + // oneofs must be ordered after all "real" oneofs. + // + // For message fields, proto3_optional doesn't create any semantic change, + // since non-repeated message fields always track presence. However it still + // indicates the semantic detail of whether the user wrote "optional" or not. + // This can be useful for round-tripping the .proto file. For consistency we + // give message fields a synthetic oneof also, even though it is not required + // to track presence. This is especially important because the parser can't + // tell if a field is a message or an enum, so it must always create a + // synthetic oneof. + // + // Proto2 optional fields do not set this flag, because they already indicate + // optional with `LABEL_OPTIONAL`. + optional bool proto3_optional = 17; +} + +// Describes a oneof. +message OneofDescriptorProto { + optional string name = 1; + optional OneofOptions options = 2; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; + + // Range of reserved numeric values. Reserved values may not be used by + // entries in the same enum. Reserved ranges may not overlap. + // + // Note that this is distinct from DescriptorProto.ReservedRange in that it + // is inclusive such that it can appropriately represent the entire int32 + // domain. + message EnumReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Inclusive. + } + + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + repeated EnumReservedRange reserved_range = 4; + + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + repeated string reserved_name = 5; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; + + // Identifies if client streams multiple client messages + optional bool client_streaming = 5 [default = false]; + // Identifies if server streams multiple server messages + optional bool server_streaming = 6 [default = false]; +} + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Objective-C plugin) and your project website (if available) -- there's no +// need to explain how you intend to use them. Usually you only need one +// extension number. You can declare multiple options with only one extension +// number by putting them in a sub-message. See the Custom Options section of +// the docs for examples: +// https://developers.google.com/protocol-buffers/docs/proto#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + // Controls the name of the wrapper Java class generated for the .proto file. + // That class will always contain the .proto file's getDescriptor() method as + // well as any top-level extensions defined in the .proto file. + // If java_multiple_files is disabled, then all the other classes from the + // .proto file will be nested inside the single wrapper outer class. + optional string java_outer_classname = 8; + + // If enabled, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the wrapper class + // named by java_outer_classname. However, the wrapper class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [default = false]; + + // This option does nothing. + optional bool java_generate_equals_and_hash = 20 [deprecated=true]; + + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + optional bool java_string_check_utf8 = 27 [default = false]; + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default = SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + optional string go_package = 11; + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default = false]; + optional bool java_generic_services = 17 [default = false]; + optional bool py_generic_services = 18 [default = false]; + optional bool php_generic_services = 42 [default = false]; + + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + optional bool deprecated = 23 [default = false]; + + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + optional bool cc_enable_arenas = 31 [default = true]; + + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + optional string objc_class_prefix = 36; + + // Namespace for generated classes; defaults to the package. + optional string csharp_namespace = 37; + + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + optional string swift_prefix = 39; + + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + optional string php_class_prefix = 40; + + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + optional string php_namespace = 41; + + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be + // used for determining the namespace. + optional string php_metadata_namespace = 44; + + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + optional string ruby_package = 45; + + // Any features defined in the specific edition. + optional FeatureSet features = 50; + + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. + // See the documentation for the "Options" section above. + extensions 1000 to max; + + reserved 38; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default = false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default = false]; + + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + optional bool deprecated = 3 [default = false]; + + reserved 4, 5, 6; + + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + // + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementations still need to work as + // if the field is a repeated message field. + optional bool map_entry = 7; + + reserved 8; // javalite_serializable + reserved 9; // javanano_as_lite + + // Enable the legacy handling of JSON field name conflicts. This lowercases + // and strips underscored from the fields before comparison in proto3 only. + // The new behavior takes `json_name` into account and applies to proto2 as + // well. + // + // This should only be used as a temporary measure against broken builds due + // to the change in behavior for JSON field name conflicts. + // + // TODO This is legacy behavior we plan to remove once downstream + // teams have had time to migrate. + optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true]; + + // Any features defined in the specific edition. + optional FeatureSet features = 12; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is only implemented to support use of + // [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of + // type "bytes" in the open source release -- sorry, we'll try to include + // other types in a future version! + optional CType ctype = 1 [default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + // The option [ctype=CORD] may be applied to a non-repeated field of type + // "bytes". It indicates that in C++, the data should be stored in a Cord + // instead of a string. For very large strings, this may reduce memory + // fragmentation. It may also allow better performance when parsing from a + // Cord, or when parsing with aliasing enabled, as the parsed Cord may then + // alias the original buffer. + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. This option is prohibited in + // Editions, but the `repeated_field_encoding` feature can be used to control + // the behavior. + optional bool packed = 2; + + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + optional JSType jstype = 6 [default = JS_NORMAL]; + enum JSType { + // Use the default type. + JS_NORMAL = 0; + + // Use JavaScript strings. + JS_STRING = 1; + + // Use JavaScript numbers. + JS_NUMBER = 2; + } + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outer message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + // + // As of May 2022, lazy verifies the contents of the byte stream during + // parsing. An invalid byte stream will cause the overall parsing to fail. + optional bool lazy = 5 [default = false]; + + // unverified_lazy does no correctness checks on the byte stream. This should + // only be used where lazy with verification is prohibitive for performance + // reasons. + optional bool unverified_lazy = 15 [default = false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default = false]; + + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default = false]; + + // Indicate that the field value should not be printed out when using debug + // formats, e.g. when the field contains sensitive credentials. + optional bool debug_redact = 16 [default = false]; + + // If set to RETENTION_SOURCE, the option will be omitted from the binary. + // Note: as of January 2023, support for this is in progress and does not yet + // have an effect (b/264593489). + enum OptionRetention { + RETENTION_UNKNOWN = 0; + RETENTION_RUNTIME = 1; + RETENTION_SOURCE = 2; + } + + optional OptionRetention retention = 17; + + // This indicates the types of entities that the field may apply to when used + // as an option. If it is unset, then the field may be freely used as an + // option on any kind of entity. Note: as of January 2023, support for this is + // in progress and does not yet have an effect (b/264593489). + enum OptionTargetType { + TARGET_TYPE_UNKNOWN = 0; + TARGET_TYPE_FILE = 1; + TARGET_TYPE_EXTENSION_RANGE = 2; + TARGET_TYPE_MESSAGE = 3; + TARGET_TYPE_FIELD = 4; + TARGET_TYPE_ONEOF = 5; + TARGET_TYPE_ENUM = 6; + TARGET_TYPE_ENUM_ENTRY = 7; + TARGET_TYPE_SERVICE = 8; + TARGET_TYPE_METHOD = 9; + } + + repeated OptionTargetType targets = 19; + + message EditionDefault { + optional Edition edition = 3; + optional string value = 2; // Textproto value. + } + repeated EditionDefault edition_defaults = 20; + + // Any features defined in the specific edition. + optional FeatureSet features = 21; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; + + reserved 4; // removed jtype + reserved 18; // reserve target, target_obsolete_do_not_use +} + +message OneofOptions { + // Any features defined in the specific edition. + optional FeatureSet features = 1; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to true to allow mapping different tag names to the same + // value. + optional bool allow_alias = 2; + + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + optional bool deprecated = 3 [default = false]; + + reserved 5; // javanano_as_lite + + // Enable the legacy handling of JSON field name conflicts. This lowercases + // and strips underscored from the fields before comparison in proto3 only. + // The new behavior takes `json_name` into account and applies to proto2 as + // well. + // TODO Remove this legacy behavior once downstream teams have + // had time to migrate. + optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true]; + + // Any features defined in the specific edition. + optional FeatureSet features = 7; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + optional bool deprecated = 1 [default = false]; + + // Any features defined in the specific edition. + optional FeatureSet features = 2; + + // Indicate that fields annotated with this enum value should not be printed + // out when using debug formats, e.g. when the field contains sensitive + // credentials. + optional bool debug_redact = 3 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Any features defined in the specific edition. + optional FeatureSet features = 34; + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + optional bool deprecated = 33 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + optional bool deprecated = 33 [default = false]; + + // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, + // or neither? HTTP based RPC implementation may choose GET verb for safe + // methods, and PUT verb for idempotent methods instead of the default POST. + enum IdempotencyLevel { + IDEMPOTENCY_UNKNOWN = 0; + NO_SIDE_EFFECTS = 1; // implies idempotent + IDEMPOTENT = 2; // idempotent, but may have side effects + } + optional IdempotencyLevel idempotency_level = 34 + [default = IDEMPOTENCY_UNKNOWN]; + + // Any features defined in the specific edition. + optional FeatureSet features = 35; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // The name of the uninterpreted option. Each string represents a segment in + // a dot-separated name. is_extension is true iff a segment represents an + // extension (denoted with parentheses in options specs in .proto files). + // E.g.,{ ["foo", false], ["bar.baz", true], ["moo", false] } represents + // "foo.(bar.baz).moo". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Features + +// TODO Enums in C++ gencode (and potentially other languages) are +// not well scoped. This means that each of the feature enums below can clash +// with each other. The short names we've chosen maximize call-site +// readability, but leave us very open to this scenario. A future feature will +// be designed and implemented to handle this, hopefully before we ever hit a +// conflict here. +message FeatureSet { + enum FieldPresence { + FIELD_PRESENCE_UNKNOWN = 0; + EXPLICIT = 1; + IMPLICIT = 2; + LEGACY_REQUIRED = 3; + } + optional FieldPresence field_presence = 1 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "EXPLICIT" }, + edition_defaults = { edition: EDITION_PROTO3, value: "IMPLICIT" }, + edition_defaults = { edition: EDITION_2023, value: "EXPLICIT" } + ]; + + enum EnumType { + ENUM_TYPE_UNKNOWN = 0; + OPEN = 1; + CLOSED = 2; + } + optional EnumType enum_type = 2 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_ENUM, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "CLOSED" }, + edition_defaults = { edition: EDITION_PROTO3, value: "OPEN" } + ]; + + enum RepeatedFieldEncoding { + REPEATED_FIELD_ENCODING_UNKNOWN = 0; + PACKED = 1; + EXPANDED = 2; + } + optional RepeatedFieldEncoding repeated_field_encoding = 3 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "EXPANDED" }, + edition_defaults = { edition: EDITION_PROTO3, value: "PACKED" } + ]; + + enum Utf8Validation { + UTF8_VALIDATION_UNKNOWN = 0; + NONE = 1; + VERIFY = 2; + } + optional Utf8Validation utf8_validation = 4 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "NONE" }, + edition_defaults = { edition: EDITION_PROTO3, value: "VERIFY" } + ]; + + enum MessageEncoding { + MESSAGE_ENCODING_UNKNOWN = 0; + LENGTH_PREFIXED = 1; + DELIMITED = 2; + } + optional MessageEncoding message_encoding = 5 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "LENGTH_PREFIXED" } + ]; + + enum JsonFormat { + JSON_FORMAT_UNKNOWN = 0; + ALLOW = 1; + LEGACY_BEST_EFFORT = 2; + } + optional JsonFormat json_format = 6 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_MESSAGE, + targets = TARGET_TYPE_ENUM, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "LEGACY_BEST_EFFORT" }, + edition_defaults = { edition: EDITION_PROTO3, value: "ALLOW" } + ]; + + reserved 999; + + extensions 1000; // for Protobuf C++ + extensions 1001; // for Protobuf Java + + extensions 9995 to 9999; // For internal testing +} + +// A compiled specification for the defaults of a set of features. These +// messages are generated from FeatureSet extensions and can be used to seed +// feature resolution. The resolution with this object becomes a simple search +// for the closest matching edition, followed by proto merges. +message FeatureSetDefaults { + // A map from every known edition with a unique set of defaults to its + // defaults. Not all editions may be contained here. For a given edition, + // the defaults at the closest matching edition ordered at or before it should + // be used. This field must be in strict ascending order by edition. + message FeatureSetEditionDefault { + optional Edition edition = 3; + optional FeatureSet features = 2; + } + repeated FeatureSetEditionDefault defaults = 1; + + // The minimum supported edition (inclusive) when this was constructed. + // Editions before this will not have defaults. + optional Edition minimum_edition = 4; + + // The maximum known edition (inclusive) when this was constructed. Editions + // after this will not have reliable defaults. + optional Edition maximum_edition = 5; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendant. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition occurs. + // For example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed = true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed = true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to moo. + // // + // // Another line attached to moo. + // optional double moo = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to moo or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + optional string leading_comments = 3; + optional string trailing_comments = 4; + repeated string leading_detached_comments = 6; + } +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +message GeneratedCodeInfo { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + repeated Annotation annotation = 1; + message Annotation { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + repeated int32 path = 1 [packed = true]; + + // Identifies the filesystem path to the original source .proto. + optional string source_file = 2; + + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + optional int32 begin = 3; + + // Identifies the ending offset in bytes in the generated code that + // relates to the identified object. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + optional int32 end = 4; + + // Represents the identified object's effect on the element in the original + // .proto file. + enum Semantic { + // There is no effect or the effect is indescribable. + NONE = 0; + // The element is set or otherwise mutated. + SET = 1; + // An alias to the element is returned. + ALIAS = 2; + } + optional Semantic semantic = 5; + } +} diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/duration.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/duration.proto new file mode 100644 index 00000000..41f40c22 --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/duration.proto @@ -0,0 +1,115 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/durationpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DurationProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; + +// A Duration represents a signed, fixed-length span of time represented +// as a count of seconds and fractions of seconds at nanosecond +// resolution. It is independent of any calendar and concepts like "day" +// or "month". It is related to Timestamp in that the difference between +// two Timestamp values is a Duration and it can be added or subtracted +// from a Timestamp. Range is approximately +-10,000 years. +// +// # Examples +// +// Example 1: Compute Duration from two Timestamps in pseudo code. +// +// Timestamp start = ...; +// Timestamp end = ...; +// Duration duration = ...; +// +// duration.seconds = end.seconds - start.seconds; +// duration.nanos = end.nanos - start.nanos; +// +// if (duration.seconds < 0 && duration.nanos > 0) { +// duration.seconds += 1; +// duration.nanos -= 1000000000; +// } else if (duration.seconds > 0 && duration.nanos < 0) { +// duration.seconds -= 1; +// duration.nanos += 1000000000; +// } +// +// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. +// +// Timestamp start = ...; +// Duration duration = ...; +// Timestamp end = ...; +// +// end.seconds = start.seconds + duration.seconds; +// end.nanos = start.nanos + duration.nanos; +// +// if (end.nanos < 0) { +// end.seconds -= 1; +// end.nanos += 1000000000; +// } else if (end.nanos >= 1000000000) { +// end.seconds += 1; +// end.nanos -= 1000000000; +// } +// +// Example 3: Compute Duration from datetime.timedelta in Python. +// +// td = datetime.timedelta(days=3, minutes=10) +// duration = Duration() +// duration.FromTimedelta(td) +// +// # JSON Mapping +// +// In JSON format, the Duration type is encoded as a string rather than an +// object, where the string ends in the suffix "s" (indicating seconds) and +// is preceded by the number of seconds, with nanoseconds expressed as +// fractional seconds. For example, 3 seconds with 0 nanoseconds should be +// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should +// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 +// microsecond should be expressed in JSON format as "3.000001s". +// +message Duration { + // Signed seconds of the span of time. Must be from -315,576,000,000 + // to +315,576,000,000 inclusive. Note: these bounds are computed from: + // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + int64 seconds = 1; + + // Signed fractions of a second at nanosecond resolution of the span + // of time. Durations less than one second are represented with a 0 + // `seconds` field and a positive or negative `nanos` field. For durations + // of one second or more, a non-zero value for the `nanos` field must be + // of the same sign as the `seconds` field. Must be from -999,999,999 + // to +999,999,999 inclusive. + int32 nanos = 2; +} diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/empty.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/empty.proto new file mode 100644 index 00000000..b87c89dc --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/empty.proto @@ -0,0 +1,51 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option go_package = "google.golang.org/protobuf/types/known/emptypb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "EmptyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; + +// A generic empty message that you can re-use to avoid defining duplicated +// empty messages in your APIs. A typical example is to use it as the request +// or the response type of an API method. For instance: +// +// service Foo { +// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); +// } +// +message Empty {} diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/field_mask.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/field_mask.proto new file mode 100644 index 00000000..b28334b9 --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/field_mask.proto @@ -0,0 +1,245 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "FieldMaskProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/fieldmaskpb"; +option cc_enable_arenas = true; + +// `FieldMask` represents a set of symbolic field paths, for example: +// +// paths: "f.a" +// paths: "f.b.d" +// +// Here `f` represents a field in some root message, `a` and `b` +// fields in the message found in `f`, and `d` a field found in the +// message in `f.b`. +// +// Field masks are used to specify a subset of fields that should be +// returned by a get operation or modified by an update operation. +// Field masks also have a custom JSON encoding (see below). +// +// # Field Masks in Projections +// +// When used in the context of a projection, a response message or +// sub-message is filtered by the API to only contain those fields as +// specified in the mask. For example, if the mask in the previous +// example is applied to a response message as follows: +// +// f { +// a : 22 +// b { +// d : 1 +// x : 2 +// } +// y : 13 +// } +// z: 8 +// +// The result will not contain specific values for fields x,y and z +// (their value will be set to the default, and omitted in proto text +// output): +// +// +// f { +// a : 22 +// b { +// d : 1 +// } +// } +// +// A repeated field is not allowed except at the last position of a +// paths string. +// +// If a FieldMask object is not present in a get operation, the +// operation applies to all fields (as if a FieldMask of all fields +// had been specified). +// +// Note that a field mask does not necessarily apply to the +// top-level response message. In case of a REST get operation, the +// field mask applies directly to the response, but in case of a REST +// list operation, the mask instead applies to each individual message +// in the returned resource list. In case of a REST custom method, +// other definitions may be used. Where the mask applies will be +// clearly documented together with its declaration in the API. In +// any case, the effect on the returned resource/resources is required +// behavior for APIs. +// +// # Field Masks in Update Operations +// +// A field mask in update operations specifies which fields of the +// targeted resource are going to be updated. The API is required +// to only change the values of the fields as specified in the mask +// and leave the others untouched. If a resource is passed in to +// describe the updated values, the API ignores the values of all +// fields not covered by the mask. +// +// If a repeated field is specified for an update operation, new values will +// be appended to the existing repeated field in the target resource. Note that +// a repeated field is only allowed in the last position of a `paths` string. +// +// If a sub-message is specified in the last position of the field mask for an +// update operation, then new value will be merged into the existing sub-message +// in the target resource. +// +// For example, given the target message: +// +// f { +// b { +// d: 1 +// x: 2 +// } +// c: [1] +// } +// +// And an update message: +// +// f { +// b { +// d: 10 +// } +// c: [2] +// } +// +// then if the field mask is: +// +// paths: ["f.b", "f.c"] +// +// then the result will be: +// +// f { +// b { +// d: 10 +// x: 2 +// } +// c: [1, 2] +// } +// +// An implementation may provide options to override this default behavior for +// repeated and message fields. +// +// In order to reset a field's value to the default, the field must +// be in the mask and set to the default value in the provided resource. +// Hence, in order to reset all fields of a resource, provide a default +// instance of the resource and set all fields in the mask, or do +// not provide a mask as described below. +// +// If a field mask is not present on update, the operation applies to +// all fields (as if a field mask of all fields has been specified). +// Note that in the presence of schema evolution, this may mean that +// fields the client does not know and has therefore not filled into +// the request will be reset to their default. If this is unwanted +// behavior, a specific service may require a client to always specify +// a field mask, producing an error if not. +// +// As with get operations, the location of the resource which +// describes the updated values in the request message depends on the +// operation kind. In any case, the effect of the field mask is +// required to be honored by the API. +// +// ## Considerations for HTTP REST +// +// The HTTP kind of an update operation which uses a field mask must +// be set to PATCH instead of PUT in order to satisfy HTTP semantics +// (PUT must only be used for full updates). +// +// # JSON Encoding of Field Masks +// +// In JSON, a field mask is encoded as a single string where paths are +// separated by a comma. Fields name in each path are converted +// to/from lower-camel naming conventions. +// +// As an example, consider the following message declarations: +// +// message Profile { +// User user = 1; +// Photo photo = 2; +// } +// message User { +// string display_name = 1; +// string address = 2; +// } +// +// In proto a field mask for `Profile` may look as such: +// +// mask { +// paths: "user.display_name" +// paths: "photo" +// } +// +// In JSON, the same mask is represented as below: +// +// { +// mask: "user.displayName,photo" +// } +// +// # Field Masks and Oneof Fields +// +// Field masks treat fields in oneofs just as regular fields. Consider the +// following message: +// +// message SampleMessage { +// oneof test_oneof { +// string name = 4; +// SubMessage sub_message = 9; +// } +// } +// +// The field mask can be: +// +// mask { +// paths: "name" +// } +// +// Or: +// +// mask { +// paths: "sub_message" +// } +// +// Note that oneof type names ("test_oneof" in this case) cannot be used in +// paths. +// +// ## Field Mask Verification +// +// The implementation of any API method which has a FieldMask type field in the +// request should verify the included field paths, and return an +// `INVALID_ARGUMENT` error if any path is unmappable. +message FieldMask { + // The set of field mask paths. + repeated string paths = 1; +} diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/source_context.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/source_context.proto new file mode 100644 index 00000000..135f50fe --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/source_context.proto @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "SourceContextProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/sourcecontextpb"; + +// `SourceContext` represents information about the source of a +// protobuf element, like the file in which it is defined. +message SourceContext { + // The path-qualified name of the .proto file that contained the associated + // protobuf element. For example: `"google/protobuf/source_context.proto"`. + string file_name = 1; +} diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/struct.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/struct.proto new file mode 100644 index 00000000..1bf0c1ad --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/struct.proto @@ -0,0 +1,95 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/structpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "StructProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; + +// `Struct` represents a structured data value, consisting of fields +// which map to dynamically typed values. In some languages, `Struct` +// might be supported by a native representation. For example, in +// scripting languages like JS a struct is represented as an +// object. The details of that representation are described together +// with the proto support for the language. +// +// The JSON representation for `Struct` is JSON object. +message Struct { + // Unordered map of dynamically typed values. + map fields = 1; +} + +// `Value` represents a dynamically typed value which can be either +// null, a number, a string, a boolean, a recursive struct value, or a +// list of values. A producer of value is expected to set one of these +// variants. Absence of any variant indicates an error. +// +// The JSON representation for `Value` is JSON value. +message Value { + // The kind of value. + oneof kind { + // Represents a null value. + NullValue null_value = 1; + // Represents a double value. + double number_value = 2; + // Represents a string value. + string string_value = 3; + // Represents a boolean value. + bool bool_value = 4; + // Represents a structured value. + Struct struct_value = 5; + // Represents a repeated `Value`. + ListValue list_value = 6; + } +} + +// `NullValue` is a singleton enumeration to represent the null value for the +// `Value` type union. +// +// The JSON representation for `NullValue` is JSON `null`. +enum NullValue { + // Null value. + NULL_VALUE = 0; +} + +// `ListValue` is a wrapper around a repeated field of values. +// +// The JSON representation for `ListValue` is JSON array. +message ListValue { + // Repeated field of dynamically typed values. + repeated Value values = 1; +} diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/timestamp.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/timestamp.proto new file mode 100644 index 00000000..fd0bc07d --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/timestamp.proto @@ -0,0 +1,144 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/timestamppb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TimestampProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; + +// A Timestamp represents a point in time independent of any time zone or local +// calendar, encoded as a count of seconds and fractions of seconds at +// nanosecond resolution. The count is relative to an epoch at UTC midnight on +// January 1, 1970, in the proleptic Gregorian calendar which extends the +// Gregorian calendar backwards to year one. +// +// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap +// second table is needed for interpretation, using a [24-hour linear +// smear](https://developers.google.com/time/smear). +// +// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By +// restricting to that range, we ensure that we can convert to and from [RFC +// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. +// +// # Examples +// +// Example 1: Compute Timestamp from POSIX `time()`. +// +// Timestamp timestamp; +// timestamp.set_seconds(time(NULL)); +// timestamp.set_nanos(0); +// +// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +// +// struct timeval tv; +// gettimeofday(&tv, NULL); +// +// Timestamp timestamp; +// timestamp.set_seconds(tv.tv_sec); +// timestamp.set_nanos(tv.tv_usec * 1000); +// +// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +// +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); +// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +// +// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +// Timestamp timestamp; +// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +// +// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +// +// long millis = System.currentTimeMillis(); +// +// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +// .setNanos((int) ((millis % 1000) * 1000000)).build(); +// +// Example 5: Compute Timestamp from Java `Instant.now()`. +// +// Instant now = Instant.now(); +// +// Timestamp timestamp = +// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) +// .setNanos(now.getNano()).build(); +// +// Example 6: Compute Timestamp from current time in Python. +// +// timestamp = Timestamp() +// timestamp.GetCurrentTime() +// +// # JSON Mapping +// +// In JSON format, the Timestamp type is encoded as a string in the +// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +// where {year} is always expressed using four digits while {month}, {day}, +// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). +// +// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +// 01:30 UTC on January 15, 2017. +// +// In JavaScript, one can convert a Date object to this format using the +// standard +// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +// method. In Python, a standard `datetime.datetime` object can be converted +// to this format using +// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with +// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use +// the Joda Time's [`ISODateTimeFormat.dateTime()`]( +// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime() +// ) to obtain a formatter capable of generating timestamps in this format. +// +message Timestamp { + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + int64 seconds = 1; + + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + int32 nanos = 2; +} diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/type.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/type.proto new file mode 100644 index 00000000..48cb11e7 --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/type.proto @@ -0,0 +1,193 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/any.proto"; +import "google/protobuf/source_context.proto"; + +option cc_enable_arenas = true; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TypeProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/typepb"; + +// A protocol buffer message type. +message Type { + // The fully qualified message name. + string name = 1; + // The list of fields. + repeated Field fields = 2; + // The list of types appearing in `oneof` definitions in this type. + repeated string oneofs = 3; + // The protocol buffer options. + repeated Option options = 4; + // The source context. + SourceContext source_context = 5; + // The source syntax. + Syntax syntax = 6; + // The source edition string, only valid when syntax is SYNTAX_EDITIONS. + string edition = 7; +} + +// A single field of a message type. +message Field { + // Basic field types. + enum Kind { + // Field type unknown. + TYPE_UNKNOWN = 0; + // Field type double. + TYPE_DOUBLE = 1; + // Field type float. + TYPE_FLOAT = 2; + // Field type int64. + TYPE_INT64 = 3; + // Field type uint64. + TYPE_UINT64 = 4; + // Field type int32. + TYPE_INT32 = 5; + // Field type fixed64. + TYPE_FIXED64 = 6; + // Field type fixed32. + TYPE_FIXED32 = 7; + // Field type bool. + TYPE_BOOL = 8; + // Field type string. + TYPE_STRING = 9; + // Field type group. Proto2 syntax only, and deprecated. + TYPE_GROUP = 10; + // Field type message. + TYPE_MESSAGE = 11; + // Field type bytes. + TYPE_BYTES = 12; + // Field type uint32. + TYPE_UINT32 = 13; + // Field type enum. + TYPE_ENUM = 14; + // Field type sfixed32. + TYPE_SFIXED32 = 15; + // Field type sfixed64. + TYPE_SFIXED64 = 16; + // Field type sint32. + TYPE_SINT32 = 17; + // Field type sint64. + TYPE_SINT64 = 18; + } + + // Whether a field is optional, required, or repeated. + enum Cardinality { + // For fields with unknown cardinality. + CARDINALITY_UNKNOWN = 0; + // For optional fields. + CARDINALITY_OPTIONAL = 1; + // For required fields. Proto2 syntax only. + CARDINALITY_REQUIRED = 2; + // For repeated fields. + CARDINALITY_REPEATED = 3; + } + + // The field type. + Kind kind = 1; + // The field cardinality. + Cardinality cardinality = 2; + // The field number. + int32 number = 3; + // The field name. + string name = 4; + // The field type URL, without the scheme, for message or enumeration + // types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + string type_url = 6; + // The index of the field type in `Type.oneofs`, for message or enumeration + // types. The first type has index 1; zero means the type is not in the list. + int32 oneof_index = 7; + // Whether to use alternative packed wire representation. + bool packed = 8; + // The protocol buffer options. + repeated Option options = 9; + // The field JSON name. + string json_name = 10; + // The string value of the default value of this field. Proto2 syntax only. + string default_value = 11; +} + +// Enum type definition. +message Enum { + // Enum type name. + string name = 1; + // Enum value definitions. + repeated EnumValue enumvalue = 2; + // Protocol buffer options. + repeated Option options = 3; + // The source context. + SourceContext source_context = 4; + // The source syntax. + Syntax syntax = 5; + // The source edition string, only valid when syntax is SYNTAX_EDITIONS. + string edition = 6; +} + +// Enum value definition. +message EnumValue { + // Enum value name. + string name = 1; + // Enum value number. + int32 number = 2; + // Protocol buffer options. + repeated Option options = 3; +} + +// A protocol buffer option, which can be attached to a message, field, +// enumeration, etc. +message Option { + // The option's name. For protobuf built-in options (options defined in + // descriptor.proto), this is the short name. For example, `"map_entry"`. + // For custom options, it should be the fully-qualified name. For example, + // `"google.api.http"`. + string name = 1; + // The option's value packed in an Any message. If the value is a primitive, + // the corresponding wrapper type defined in google/protobuf/wrappers.proto + // should be used. If the value is an enum, it should be stored as an int32 + // value using the google.protobuf.Int32Value type. + Any value = 2; +} + +// The syntax in which a protocol buffer element is defined. +enum Syntax { + // Syntax `proto2`. + SYNTAX_PROTO2 = 0; + // Syntax `proto3`. + SYNTAX_PROTO3 = 1; + // Syntax `editions`. + SYNTAX_EDITIONS = 2; +} diff --git a/tools/protobuf/linux-x86_64/include/google/protobuf/wrappers.proto b/tools/protobuf/linux-x86_64/include/google/protobuf/wrappers.proto new file mode 100644 index 00000000..1959fa55 --- /dev/null +++ b/tools/protobuf/linux-x86_64/include/google/protobuf/wrappers.proto @@ -0,0 +1,123 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Wrappers for primitive (non-message) types. These types are useful +// for embedding primitives in the `google.protobuf.Any` type and for places +// where we need to distinguish between the absence of a primitive +// typed field and its default value. +// +// These wrappers have no meaningful use within repeated fields as they lack +// the ability to detect presence on individual elements. +// These wrappers have no meaningful use within a map or a oneof since +// individual entries of a map or fields of a oneof can already detect presence. + +syntax = "proto3"; + +package google.protobuf; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/wrapperspb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "WrappersProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; + +// Wrapper message for `double`. +// +// The JSON representation for `DoubleValue` is JSON number. +message DoubleValue { + // The double value. + double value = 1; +} + +// Wrapper message for `float`. +// +// The JSON representation for `FloatValue` is JSON number. +message FloatValue { + // The float value. + float value = 1; +} + +// Wrapper message for `int64`. +// +// The JSON representation for `Int64Value` is JSON string. +message Int64Value { + // The int64 value. + int64 value = 1; +} + +// Wrapper message for `uint64`. +// +// The JSON representation for `UInt64Value` is JSON string. +message UInt64Value { + // The uint64 value. + uint64 value = 1; +} + +// Wrapper message for `int32`. +// +// The JSON representation for `Int32Value` is JSON number. +message Int32Value { + // The int32 value. + int32 value = 1; +} + +// Wrapper message for `uint32`. +// +// The JSON representation for `UInt32Value` is JSON number. +message UInt32Value { + // The uint32 value. + uint32 value = 1; +} + +// Wrapper message for `bool`. +// +// The JSON representation for `BoolValue` is JSON `true` and `false`. +message BoolValue { + // The bool value. + bool value = 1; +} + +// Wrapper message for `string`. +// +// The JSON representation for `StringValue` is JSON string. +message StringValue { + // The string value. + string value = 1; +} + +// Wrapper message for `bytes`. +// +// The JSON representation for `BytesValue` is JSON string. +message BytesValue { + // The bytes value. + bytes value = 1; +} diff --git a/tools/protobuf/linux-x86_64/readme.txt b/tools/protobuf/linux-x86_64/readme.txt new file mode 100644 index 00000000..f7f091fb --- /dev/null +++ b/tools/protobuf/linux-x86_64/readme.txt @@ -0,0 +1,12 @@ +Protocol Buffers - Google's data interchange format +Copyright 2008 Google Inc. +https://developers.google.com/protocol-buffers/ +This package contains a precompiled binary version of the protocol buffer +compiler (protoc). This binary is intended for users who want to use Protocol +Buffers in languages other than C++ but do not want to compile protoc +themselves. To install, simply place this binary somewhere in your PATH. +If you intend to use the included well known types then don't forget to +copy the contents of the 'include' directory somewhere as well, for example +into '/usr/local/include/'. +Please refer to our official github site for more installation instructions: + https://github.com/protocolbuffers/protobuf diff --git a/tools/protobuf/win64/bin/protoc.exe b/tools/protobuf/win64/bin/protoc.exe new file mode 100644 index 00000000..0ceca2d5 Binary files /dev/null and b/tools/protobuf/win64/bin/protoc.exe differ diff --git a/tools/protobuf/win64/include/google/protobuf/any.proto b/tools/protobuf/win64/include/google/protobuf/any.proto new file mode 100644 index 00000000..eff44e50 --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/any.proto @@ -0,0 +1,162 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option go_package = "google.golang.org/protobuf/types/known/anypb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "AnyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// // or ... +// if (any.isSameTypeAs(Foo.getDefaultInstance())) { +// foo = any.unpack(Foo.getDefaultInstance()); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := anypb.New(foo) +// if err != nil { +// ... +// } +// ... +// foo := &pb.Foo{} +// if err := any.UnmarshalTo(foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +message Any { + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. This string must contain at least + // one "/" character. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // * If no scheme is provided, `https` is assumed. + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. As of May 2023, there are no widely used type server + // implementations and no plans to implement one. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + string type_url = 1; + + // Must be a valid serialized protocol buffer of the above specified type. + bytes value = 2; +} diff --git a/tools/protobuf/win64/include/google/protobuf/api.proto b/tools/protobuf/win64/include/google/protobuf/api.proto new file mode 100644 index 00000000..42223516 --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/api.proto @@ -0,0 +1,207 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/source_context.proto"; +import "google/protobuf/type.proto"; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "ApiProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/apipb"; + +// Api is a light-weight descriptor for an API Interface. +// +// Interfaces are also described as "protocol buffer services" in some contexts, +// such as by the "service" keyword in a .proto file, but they are different +// from API Services, which represent a concrete implementation of an interface +// as opposed to simply a description of methods and bindings. They are also +// sometimes simply referred to as "APIs" in other contexts, such as the name of +// this message itself. See https://cloud.google.com/apis/design/glossary for +// detailed terminology. +message Api { + // The fully qualified name of this interface, including package name + // followed by the interface's simple name. + string name = 1; + + // The methods of this interface, in unspecified order. + repeated Method methods = 2; + + // Any metadata attached to the interface. + repeated Option options = 3; + + // A version string for this interface. If specified, must have the form + // `major-version.minor-version`, as in `1.10`. If the minor version is + // omitted, it defaults to zero. If the entire version field is empty, the + // major version is derived from the package name, as outlined below. If the + // field is not empty, the version in the package name will be verified to be + // consistent with what is provided here. + // + // The versioning schema uses [semantic + // versioning](http://semver.org) where the major version number + // indicates a breaking change and the minor version an additive, + // non-breaking change. Both version numbers are signals to users + // what to expect from different versions, and should be carefully + // chosen based on the product plan. + // + // The major version is also reflected in the package name of the + // interface, which must end in `v`, as in + // `google.feature.v1`. For major versions 0 and 1, the suffix can + // be omitted. Zero major versions must only be used for + // experimental, non-GA interfaces. + // + string version = 4; + + // Source context for the protocol buffer service represented by this + // message. + SourceContext source_context = 5; + + // Included interfaces. See [Mixin][]. + repeated Mixin mixins = 6; + + // The source syntax of the service. + Syntax syntax = 7; +} + +// Method represents a method of an API interface. +message Method { + // The simple name of this method. + string name = 1; + + // A URL of the input message type. + string request_type_url = 2; + + // If true, the request is streamed. + bool request_streaming = 3; + + // The URL of the output message type. + string response_type_url = 4; + + // If true, the response is streamed. + bool response_streaming = 5; + + // Any metadata attached to the method. + repeated Option options = 6; + + // The source syntax of this method. + Syntax syntax = 7; +} + +// Declares an API Interface to be included in this interface. The including +// interface must redeclare all the methods from the included interface, but +// documentation and options are inherited as follows: +// +// - If after comment and whitespace stripping, the documentation +// string of the redeclared method is empty, it will be inherited +// from the original method. +// +// - Each annotation belonging to the service config (http, +// visibility) which is not set in the redeclared method will be +// inherited. +// +// - If an http annotation is inherited, the path pattern will be +// modified as follows. Any version prefix will be replaced by the +// version of the including interface plus the [root][] path if +// specified. +// +// Example of a simple mixin: +// +// package google.acl.v1; +// service AccessControl { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v1/{resource=**}:getAcl"; +// } +// } +// +// package google.storage.v2; +// service Storage { +// rpc GetAcl(GetAclRequest) returns (Acl); +// +// // Get a data record. +// rpc GetData(GetDataRequest) returns (Data) { +// option (google.api.http).get = "/v2/{resource=**}"; +// } +// } +// +// Example of a mixin configuration: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// +// The mixin construct implies that all methods in `AccessControl` are +// also declared with same name and request/response types in +// `Storage`. A documentation generator or annotation processor will +// see the effective `Storage.GetAcl` method after inherting +// documentation and annotations as follows: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/{resource=**}:getAcl"; +// } +// ... +// } +// +// Note how the version in the path pattern changed from `v1` to `v2`. +// +// If the `root` field in the mixin is specified, it should be a +// relative path under which inherited HTTP paths are placed. Example: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// root: acls +// +// This implies the following inherited HTTP annotation: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; +// } +// ... +// } +message Mixin { + // The fully qualified name of the interface which is included. + string name = 1; + + // If non-empty specifies a path under which inherited HTTP paths + // are rooted. + string root = 2; +} diff --git a/tools/protobuf/win64/include/google/protobuf/compiler/plugin.proto b/tools/protobuf/win64/include/google/protobuf/compiler/plugin.proto new file mode 100644 index 00000000..829cf412 --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/compiler/plugin.proto @@ -0,0 +1,168 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// Author: kenton@google.com (Kenton Varda) +// +// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path. The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +syntax = "proto2"; + +package google.protobuf.compiler; +option java_package = "com.google.protobuf.compiler"; +option java_outer_classname = "PluginProtos"; + +option csharp_namespace = "Google.Protobuf.Compiler"; +option go_package = "google.golang.org/protobuf/types/pluginpb"; + +import "google/protobuf/descriptor.proto"; + +// The version number of protocol compiler. +message Version { + optional int32 major = 1; + optional int32 minor = 2; + optional int32 patch = 3; + // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should + // be empty for mainline stable releases. + optional string suffix = 4; +} + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + repeated string file_to_generate = 1; + + // The generator parameter passed on the command-line. + optional string parameter = 2; + + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // Note: the files listed in files_to_generate will include runtime-retention + // options only, but all other files will include source-retention options. + // The source_file_descriptors field below is available in case you need + // source-retention options for files_to_generate. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + // + // Type names of fields and extensions in the FileDescriptorProto are always + // fully qualified. + repeated FileDescriptorProto proto_file = 15; + + // File descriptors with all options, including source-retention options. + // These descriptors are only provided for the files listed in + // files_to_generate. + repeated FileDescriptorProto source_file_descriptors = 17; + + // The version number of protocol compiler. + optional Version compiler_version = 3; +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + optional string error = 1; + + // A bitmask of supported features that the code generator supports. + // This is a bitwise "or" of values from the Feature enum. + optional uint64 supported_features = 2; + + // Sync with code_generator.h. + enum Feature { + FEATURE_NONE = 0; + FEATURE_PROTO3_OPTIONAL = 1; + FEATURE_SUPPORTS_EDITIONS = 2; + } + + // Represents a single generated file. + message File { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + optional string name = 1; + + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + optional string insertion_point = 2; + + // The file contents. + optional string content = 15; + + // Information describing the file content being inserted. If an insertion + // point is used, this information will be appropriately offset and inserted + // into the code generation metadata for the generated files. + optional GeneratedCodeInfo generated_code_info = 16; + } + repeated File file = 15; +} diff --git a/tools/protobuf/win64/include/google/protobuf/descriptor.proto b/tools/protobuf/win64/include/google/protobuf/descriptor.proto new file mode 100644 index 00000000..47486435 --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/descriptor.proto @@ -0,0 +1,1218 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + +syntax = "proto2"; + +package google.protobuf; + +option go_package = "google.golang.org/protobuf/types/descriptorpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; +option csharp_namespace = "Google.Protobuf.Reflection"; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; +} + +// The full set of known editions. +enum Edition { + // A placeholder for an unknown edition value. + EDITION_UNKNOWN = 0; + + // Legacy syntax "editions". These pre-date editions, but behave much like + // distinct editions. These can't be used to specify the edition of proto + // files, but feature definitions must supply proto2/proto3 defaults for + // backwards compatibility. + EDITION_PROTO2 = 998; + EDITION_PROTO3 = 999; + + // Editions that have been released. The specific values are arbitrary and + // should not be depended on, but they will always be time-ordered for easy + // comparison. + EDITION_2023 = 1000; + + // Placeholder editions for testing feature resolution. These should not be + // used or relyed on outside of tests. + EDITION_1_TEST_ONLY = 1; + EDITION_2_TEST_ONLY = 2; + EDITION_99997_TEST_ONLY = 99997; + EDITION_99998_TEST_ONLY = 99998; + EDITION_99999_TEST_ONLY = 99999; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; + + // The syntax of the proto file. + // The supported values are "proto2", "proto3", and "editions". + // + // If `edition` is present, this value must be "editions". + optional string syntax = 12; + + // The edition of the proto file. + optional Edition edition = 14; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + + optional ExtensionRangeOptions options = 3; + } + repeated ExtensionRange extension_range = 5; + + repeated OneofDescriptorProto oneof_decl = 8; + + optional MessageOptions options = 7; + + // Range of reserved tag numbers. Reserved tag numbers may not be used by + // fields or extension ranges in the same message. Reserved ranges may + // not overlap. + message ReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + } + repeated ReservedRange reserved_range = 9; + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + repeated string reserved_name = 10; +} + +message ExtensionRangeOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + message Declaration { + // The extension number declared within the extension range. + optional int32 number = 1; + + // The fully-qualified name of the extension field. There must be a leading + // dot in front of the full name. + optional string full_name = 2; + + // The fully-qualified type name of the extension field. Unlike + // Metadata.type, Declaration.type must have a leading dot for messages + // and enums. + optional string type = 3; + + // If true, indicates that the number is reserved in the extension range, + // and any extension field with the number will fail to compile. Set this + // when a declared extension field is deleted. + optional bool reserved = 5; + + // If true, indicates that the extension must be defined as repeated. + // Otherwise the extension must be defined as optional. + optional bool repeated = 6; + + reserved 4; // removed is_repeated + } + + // For external users: DO NOT USE. We are in the process of open sourcing + // extension declaration and executing internal cleanups before it can be + // used externally. + repeated Declaration declaration = 2 [retention = RETENTION_SOURCE]; + + // Any features defined in the specific edition. + optional FeatureSet features = 50; + + // The verification state of the extension range. + enum VerificationState { + // All the extensions of the range must be declared. + DECLARATION = 0; + UNVERIFIED = 1; + } + + // The verification state of the range. + // TODO: flip the default to DECLARATION once all empty ranges + // are marked as UNVERIFIED. + optional VerificationState verification = 3 [default = UNVERIFIED]; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + // Tag-delimited aggregate. + // Group type is deprecated and not supported after google.protobuf. However, Proto3 + // implementations should still be able to parse the group wire format and + // treat group fields as unknown fields. In Editions, the group wire format + // can be enabled via the `message_encoding` feature. + TYPE_GROUP = 10; + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + } + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REPEATED = 3; + // The required label is only allowed in google.protobuf. In proto3 and Editions + // it's explicitly prohibited. In Editions, the `field_presence` feature + // can be used to get this behavior. + LABEL_REQUIRED = 2; + } + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + optional string default_value = 7; + + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + optional int32 oneof_index = 9; + + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + optional string json_name = 10; + + optional FieldOptions options = 8; + + // If true, this is a proto3 "optional". When a proto3 field is optional, it + // tracks presence regardless of field type. + // + // When proto3_optional is true, this field must be belong to a oneof to + // signal to old proto3 clients that presence is tracked for this field. This + // oneof is known as a "synthetic" oneof, and this field must be its sole + // member (each proto3 optional field gets its own synthetic oneof). Synthetic + // oneofs exist in the descriptor only, and do not generate any API. Synthetic + // oneofs must be ordered after all "real" oneofs. + // + // For message fields, proto3_optional doesn't create any semantic change, + // since non-repeated message fields always track presence. However it still + // indicates the semantic detail of whether the user wrote "optional" or not. + // This can be useful for round-tripping the .proto file. For consistency we + // give message fields a synthetic oneof also, even though it is not required + // to track presence. This is especially important because the parser can't + // tell if a field is a message or an enum, so it must always create a + // synthetic oneof. + // + // Proto2 optional fields do not set this flag, because they already indicate + // optional with `LABEL_OPTIONAL`. + optional bool proto3_optional = 17; +} + +// Describes a oneof. +message OneofDescriptorProto { + optional string name = 1; + optional OneofOptions options = 2; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; + + // Range of reserved numeric values. Reserved values may not be used by + // entries in the same enum. Reserved ranges may not overlap. + // + // Note that this is distinct from DescriptorProto.ReservedRange in that it + // is inclusive such that it can appropriately represent the entire int32 + // domain. + message EnumReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Inclusive. + } + + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + repeated EnumReservedRange reserved_range = 4; + + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + repeated string reserved_name = 5; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; + + // Identifies if client streams multiple client messages + optional bool client_streaming = 5 [default = false]; + // Identifies if server streams multiple server messages + optional bool server_streaming = 6 [default = false]; +} + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Objective-C plugin) and your project website (if available) -- there's no +// need to explain how you intend to use them. Usually you only need one +// extension number. You can declare multiple options with only one extension +// number by putting them in a sub-message. See the Custom Options section of +// the docs for examples: +// https://developers.google.com/protocol-buffers/docs/proto#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + // Controls the name of the wrapper Java class generated for the .proto file. + // That class will always contain the .proto file's getDescriptor() method as + // well as any top-level extensions defined in the .proto file. + // If java_multiple_files is disabled, then all the other classes from the + // .proto file will be nested inside the single wrapper outer class. + optional string java_outer_classname = 8; + + // If enabled, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the wrapper class + // named by java_outer_classname. However, the wrapper class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [default = false]; + + // This option does nothing. + optional bool java_generate_equals_and_hash = 20 [deprecated=true]; + + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + optional bool java_string_check_utf8 = 27 [default = false]; + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default = SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + optional string go_package = 11; + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default = false]; + optional bool java_generic_services = 17 [default = false]; + optional bool py_generic_services = 18 [default = false]; + optional bool php_generic_services = 42 [default = false]; + + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + optional bool deprecated = 23 [default = false]; + + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + optional bool cc_enable_arenas = 31 [default = true]; + + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + optional string objc_class_prefix = 36; + + // Namespace for generated classes; defaults to the package. + optional string csharp_namespace = 37; + + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + optional string swift_prefix = 39; + + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + optional string php_class_prefix = 40; + + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + optional string php_namespace = 41; + + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be + // used for determining the namespace. + optional string php_metadata_namespace = 44; + + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + optional string ruby_package = 45; + + // Any features defined in the specific edition. + optional FeatureSet features = 50; + + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. + // See the documentation for the "Options" section above. + extensions 1000 to max; + + reserved 38; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default = false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default = false]; + + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + optional bool deprecated = 3 [default = false]; + + reserved 4, 5, 6; + + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + // + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementations still need to work as + // if the field is a repeated message field. + optional bool map_entry = 7; + + reserved 8; // javalite_serializable + reserved 9; // javanano_as_lite + + // Enable the legacy handling of JSON field name conflicts. This lowercases + // and strips underscored from the fields before comparison in proto3 only. + // The new behavior takes `json_name` into account and applies to proto2 as + // well. + // + // This should only be used as a temporary measure against broken builds due + // to the change in behavior for JSON field name conflicts. + // + // TODO This is legacy behavior we plan to remove once downstream + // teams have had time to migrate. + optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true]; + + // Any features defined in the specific edition. + optional FeatureSet features = 12; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is only implemented to support use of + // [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of + // type "bytes" in the open source release -- sorry, we'll try to include + // other types in a future version! + optional CType ctype = 1 [default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + // The option [ctype=CORD] may be applied to a non-repeated field of type + // "bytes". It indicates that in C++, the data should be stored in a Cord + // instead of a string. For very large strings, this may reduce memory + // fragmentation. It may also allow better performance when parsing from a + // Cord, or when parsing with aliasing enabled, as the parsed Cord may then + // alias the original buffer. + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. This option is prohibited in + // Editions, but the `repeated_field_encoding` feature can be used to control + // the behavior. + optional bool packed = 2; + + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + optional JSType jstype = 6 [default = JS_NORMAL]; + enum JSType { + // Use the default type. + JS_NORMAL = 0; + + // Use JavaScript strings. + JS_STRING = 1; + + // Use JavaScript numbers. + JS_NUMBER = 2; + } + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outer message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + // + // As of May 2022, lazy verifies the contents of the byte stream during + // parsing. An invalid byte stream will cause the overall parsing to fail. + optional bool lazy = 5 [default = false]; + + // unverified_lazy does no correctness checks on the byte stream. This should + // only be used where lazy with verification is prohibitive for performance + // reasons. + optional bool unverified_lazy = 15 [default = false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default = false]; + + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default = false]; + + // Indicate that the field value should not be printed out when using debug + // formats, e.g. when the field contains sensitive credentials. + optional bool debug_redact = 16 [default = false]; + + // If set to RETENTION_SOURCE, the option will be omitted from the binary. + // Note: as of January 2023, support for this is in progress and does not yet + // have an effect (b/264593489). + enum OptionRetention { + RETENTION_UNKNOWN = 0; + RETENTION_RUNTIME = 1; + RETENTION_SOURCE = 2; + } + + optional OptionRetention retention = 17; + + // This indicates the types of entities that the field may apply to when used + // as an option. If it is unset, then the field may be freely used as an + // option on any kind of entity. Note: as of January 2023, support for this is + // in progress and does not yet have an effect (b/264593489). + enum OptionTargetType { + TARGET_TYPE_UNKNOWN = 0; + TARGET_TYPE_FILE = 1; + TARGET_TYPE_EXTENSION_RANGE = 2; + TARGET_TYPE_MESSAGE = 3; + TARGET_TYPE_FIELD = 4; + TARGET_TYPE_ONEOF = 5; + TARGET_TYPE_ENUM = 6; + TARGET_TYPE_ENUM_ENTRY = 7; + TARGET_TYPE_SERVICE = 8; + TARGET_TYPE_METHOD = 9; + } + + repeated OptionTargetType targets = 19; + + message EditionDefault { + optional Edition edition = 3; + optional string value = 2; // Textproto value. + } + repeated EditionDefault edition_defaults = 20; + + // Any features defined in the specific edition. + optional FeatureSet features = 21; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; + + reserved 4; // removed jtype + reserved 18; // reserve target, target_obsolete_do_not_use +} + +message OneofOptions { + // Any features defined in the specific edition. + optional FeatureSet features = 1; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to true to allow mapping different tag names to the same + // value. + optional bool allow_alias = 2; + + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + optional bool deprecated = 3 [default = false]; + + reserved 5; // javanano_as_lite + + // Enable the legacy handling of JSON field name conflicts. This lowercases + // and strips underscored from the fields before comparison in proto3 only. + // The new behavior takes `json_name` into account and applies to proto2 as + // well. + // TODO Remove this legacy behavior once downstream teams have + // had time to migrate. + optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true]; + + // Any features defined in the specific edition. + optional FeatureSet features = 7; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + optional bool deprecated = 1 [default = false]; + + // Any features defined in the specific edition. + optional FeatureSet features = 2; + + // Indicate that fields annotated with this enum value should not be printed + // out when using debug formats, e.g. when the field contains sensitive + // credentials. + optional bool debug_redact = 3 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Any features defined in the specific edition. + optional FeatureSet features = 34; + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + optional bool deprecated = 33 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + optional bool deprecated = 33 [default = false]; + + // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, + // or neither? HTTP based RPC implementation may choose GET verb for safe + // methods, and PUT verb for idempotent methods instead of the default POST. + enum IdempotencyLevel { + IDEMPOTENCY_UNKNOWN = 0; + NO_SIDE_EFFECTS = 1; // implies idempotent + IDEMPOTENT = 2; // idempotent, but may have side effects + } + optional IdempotencyLevel idempotency_level = 34 + [default = IDEMPOTENCY_UNKNOWN]; + + // Any features defined in the specific edition. + optional FeatureSet features = 35; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // The name of the uninterpreted option. Each string represents a segment in + // a dot-separated name. is_extension is true iff a segment represents an + // extension (denoted with parentheses in options specs in .proto files). + // E.g.,{ ["foo", false], ["bar.baz", true], ["moo", false] } represents + // "foo.(bar.baz).moo". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Features + +// TODO Enums in C++ gencode (and potentially other languages) are +// not well scoped. This means that each of the feature enums below can clash +// with each other. The short names we've chosen maximize call-site +// readability, but leave us very open to this scenario. A future feature will +// be designed and implemented to handle this, hopefully before we ever hit a +// conflict here. +message FeatureSet { + enum FieldPresence { + FIELD_PRESENCE_UNKNOWN = 0; + EXPLICIT = 1; + IMPLICIT = 2; + LEGACY_REQUIRED = 3; + } + optional FieldPresence field_presence = 1 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "EXPLICIT" }, + edition_defaults = { edition: EDITION_PROTO3, value: "IMPLICIT" }, + edition_defaults = { edition: EDITION_2023, value: "EXPLICIT" } + ]; + + enum EnumType { + ENUM_TYPE_UNKNOWN = 0; + OPEN = 1; + CLOSED = 2; + } + optional EnumType enum_type = 2 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_ENUM, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "CLOSED" }, + edition_defaults = { edition: EDITION_PROTO3, value: "OPEN" } + ]; + + enum RepeatedFieldEncoding { + REPEATED_FIELD_ENCODING_UNKNOWN = 0; + PACKED = 1; + EXPANDED = 2; + } + optional RepeatedFieldEncoding repeated_field_encoding = 3 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "EXPANDED" }, + edition_defaults = { edition: EDITION_PROTO3, value: "PACKED" } + ]; + + enum Utf8Validation { + UTF8_VALIDATION_UNKNOWN = 0; + NONE = 1; + VERIFY = 2; + } + optional Utf8Validation utf8_validation = 4 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "NONE" }, + edition_defaults = { edition: EDITION_PROTO3, value: "VERIFY" } + ]; + + enum MessageEncoding { + MESSAGE_ENCODING_UNKNOWN = 0; + LENGTH_PREFIXED = 1; + DELIMITED = 2; + } + optional MessageEncoding message_encoding = 5 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "LENGTH_PREFIXED" } + ]; + + enum JsonFormat { + JSON_FORMAT_UNKNOWN = 0; + ALLOW = 1; + LEGACY_BEST_EFFORT = 2; + } + optional JsonFormat json_format = 6 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_MESSAGE, + targets = TARGET_TYPE_ENUM, + targets = TARGET_TYPE_FILE, + edition_defaults = { edition: EDITION_PROTO2, value: "LEGACY_BEST_EFFORT" }, + edition_defaults = { edition: EDITION_PROTO3, value: "ALLOW" } + ]; + + reserved 999; + + extensions 1000; // for Protobuf C++ + extensions 1001; // for Protobuf Java + + extensions 9995 to 9999; // For internal testing +} + +// A compiled specification for the defaults of a set of features. These +// messages are generated from FeatureSet extensions and can be used to seed +// feature resolution. The resolution with this object becomes a simple search +// for the closest matching edition, followed by proto merges. +message FeatureSetDefaults { + // A map from every known edition with a unique set of defaults to its + // defaults. Not all editions may be contained here. For a given edition, + // the defaults at the closest matching edition ordered at or before it should + // be used. This field must be in strict ascending order by edition. + message FeatureSetEditionDefault { + optional Edition edition = 3; + optional FeatureSet features = 2; + } + repeated FeatureSetEditionDefault defaults = 1; + + // The minimum supported edition (inclusive) when this was constructed. + // Editions before this will not have defaults. + optional Edition minimum_edition = 4; + + // The maximum known edition (inclusive) when this was constructed. Editions + // after this will not have reliable defaults. + optional Edition maximum_edition = 5; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendant. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition occurs. + // For example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed = true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed = true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to moo. + // // + // // Another line attached to moo. + // optional double moo = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to moo or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + optional string leading_comments = 3; + optional string trailing_comments = 4; + repeated string leading_detached_comments = 6; + } +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +message GeneratedCodeInfo { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + repeated Annotation annotation = 1; + message Annotation { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + repeated int32 path = 1 [packed = true]; + + // Identifies the filesystem path to the original source .proto. + optional string source_file = 2; + + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + optional int32 begin = 3; + + // Identifies the ending offset in bytes in the generated code that + // relates to the identified object. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + optional int32 end = 4; + + // Represents the identified object's effect on the element in the original + // .proto file. + enum Semantic { + // There is no effect or the effect is indescribable. + NONE = 0; + // The element is set or otherwise mutated. + SET = 1; + // An alias to the element is returned. + ALIAS = 2; + } + optional Semantic semantic = 5; + } +} diff --git a/tools/protobuf/win64/include/google/protobuf/duration.proto b/tools/protobuf/win64/include/google/protobuf/duration.proto new file mode 100644 index 00000000..41f40c22 --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/duration.proto @@ -0,0 +1,115 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/durationpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DurationProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; + +// A Duration represents a signed, fixed-length span of time represented +// as a count of seconds and fractions of seconds at nanosecond +// resolution. It is independent of any calendar and concepts like "day" +// or "month". It is related to Timestamp in that the difference between +// two Timestamp values is a Duration and it can be added or subtracted +// from a Timestamp. Range is approximately +-10,000 years. +// +// # Examples +// +// Example 1: Compute Duration from two Timestamps in pseudo code. +// +// Timestamp start = ...; +// Timestamp end = ...; +// Duration duration = ...; +// +// duration.seconds = end.seconds - start.seconds; +// duration.nanos = end.nanos - start.nanos; +// +// if (duration.seconds < 0 && duration.nanos > 0) { +// duration.seconds += 1; +// duration.nanos -= 1000000000; +// } else if (duration.seconds > 0 && duration.nanos < 0) { +// duration.seconds -= 1; +// duration.nanos += 1000000000; +// } +// +// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. +// +// Timestamp start = ...; +// Duration duration = ...; +// Timestamp end = ...; +// +// end.seconds = start.seconds + duration.seconds; +// end.nanos = start.nanos + duration.nanos; +// +// if (end.nanos < 0) { +// end.seconds -= 1; +// end.nanos += 1000000000; +// } else if (end.nanos >= 1000000000) { +// end.seconds += 1; +// end.nanos -= 1000000000; +// } +// +// Example 3: Compute Duration from datetime.timedelta in Python. +// +// td = datetime.timedelta(days=3, minutes=10) +// duration = Duration() +// duration.FromTimedelta(td) +// +// # JSON Mapping +// +// In JSON format, the Duration type is encoded as a string rather than an +// object, where the string ends in the suffix "s" (indicating seconds) and +// is preceded by the number of seconds, with nanoseconds expressed as +// fractional seconds. For example, 3 seconds with 0 nanoseconds should be +// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should +// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 +// microsecond should be expressed in JSON format as "3.000001s". +// +message Duration { + // Signed seconds of the span of time. Must be from -315,576,000,000 + // to +315,576,000,000 inclusive. Note: these bounds are computed from: + // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + int64 seconds = 1; + + // Signed fractions of a second at nanosecond resolution of the span + // of time. Durations less than one second are represented with a 0 + // `seconds` field and a positive or negative `nanos` field. For durations + // of one second or more, a non-zero value for the `nanos` field must be + // of the same sign as the `seconds` field. Must be from -999,999,999 + // to +999,999,999 inclusive. + int32 nanos = 2; +} diff --git a/tools/protobuf/win64/include/google/protobuf/empty.proto b/tools/protobuf/win64/include/google/protobuf/empty.proto new file mode 100644 index 00000000..b87c89dc --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/empty.proto @@ -0,0 +1,51 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option go_package = "google.golang.org/protobuf/types/known/emptypb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "EmptyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; + +// A generic empty message that you can re-use to avoid defining duplicated +// empty messages in your APIs. A typical example is to use it as the request +// or the response type of an API method. For instance: +// +// service Foo { +// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); +// } +// +message Empty {} diff --git a/tools/protobuf/win64/include/google/protobuf/field_mask.proto b/tools/protobuf/win64/include/google/protobuf/field_mask.proto new file mode 100644 index 00000000..b28334b9 --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/field_mask.proto @@ -0,0 +1,245 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "FieldMaskProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/fieldmaskpb"; +option cc_enable_arenas = true; + +// `FieldMask` represents a set of symbolic field paths, for example: +// +// paths: "f.a" +// paths: "f.b.d" +// +// Here `f` represents a field in some root message, `a` and `b` +// fields in the message found in `f`, and `d` a field found in the +// message in `f.b`. +// +// Field masks are used to specify a subset of fields that should be +// returned by a get operation or modified by an update operation. +// Field masks also have a custom JSON encoding (see below). +// +// # Field Masks in Projections +// +// When used in the context of a projection, a response message or +// sub-message is filtered by the API to only contain those fields as +// specified in the mask. For example, if the mask in the previous +// example is applied to a response message as follows: +// +// f { +// a : 22 +// b { +// d : 1 +// x : 2 +// } +// y : 13 +// } +// z: 8 +// +// The result will not contain specific values for fields x,y and z +// (their value will be set to the default, and omitted in proto text +// output): +// +// +// f { +// a : 22 +// b { +// d : 1 +// } +// } +// +// A repeated field is not allowed except at the last position of a +// paths string. +// +// If a FieldMask object is not present in a get operation, the +// operation applies to all fields (as if a FieldMask of all fields +// had been specified). +// +// Note that a field mask does not necessarily apply to the +// top-level response message. In case of a REST get operation, the +// field mask applies directly to the response, but in case of a REST +// list operation, the mask instead applies to each individual message +// in the returned resource list. In case of a REST custom method, +// other definitions may be used. Where the mask applies will be +// clearly documented together with its declaration in the API. In +// any case, the effect on the returned resource/resources is required +// behavior for APIs. +// +// # Field Masks in Update Operations +// +// A field mask in update operations specifies which fields of the +// targeted resource are going to be updated. The API is required +// to only change the values of the fields as specified in the mask +// and leave the others untouched. If a resource is passed in to +// describe the updated values, the API ignores the values of all +// fields not covered by the mask. +// +// If a repeated field is specified for an update operation, new values will +// be appended to the existing repeated field in the target resource. Note that +// a repeated field is only allowed in the last position of a `paths` string. +// +// If a sub-message is specified in the last position of the field mask for an +// update operation, then new value will be merged into the existing sub-message +// in the target resource. +// +// For example, given the target message: +// +// f { +// b { +// d: 1 +// x: 2 +// } +// c: [1] +// } +// +// And an update message: +// +// f { +// b { +// d: 10 +// } +// c: [2] +// } +// +// then if the field mask is: +// +// paths: ["f.b", "f.c"] +// +// then the result will be: +// +// f { +// b { +// d: 10 +// x: 2 +// } +// c: [1, 2] +// } +// +// An implementation may provide options to override this default behavior for +// repeated and message fields. +// +// In order to reset a field's value to the default, the field must +// be in the mask and set to the default value in the provided resource. +// Hence, in order to reset all fields of a resource, provide a default +// instance of the resource and set all fields in the mask, or do +// not provide a mask as described below. +// +// If a field mask is not present on update, the operation applies to +// all fields (as if a field mask of all fields has been specified). +// Note that in the presence of schema evolution, this may mean that +// fields the client does not know and has therefore not filled into +// the request will be reset to their default. If this is unwanted +// behavior, a specific service may require a client to always specify +// a field mask, producing an error if not. +// +// As with get operations, the location of the resource which +// describes the updated values in the request message depends on the +// operation kind. In any case, the effect of the field mask is +// required to be honored by the API. +// +// ## Considerations for HTTP REST +// +// The HTTP kind of an update operation which uses a field mask must +// be set to PATCH instead of PUT in order to satisfy HTTP semantics +// (PUT must only be used for full updates). +// +// # JSON Encoding of Field Masks +// +// In JSON, a field mask is encoded as a single string where paths are +// separated by a comma. Fields name in each path are converted +// to/from lower-camel naming conventions. +// +// As an example, consider the following message declarations: +// +// message Profile { +// User user = 1; +// Photo photo = 2; +// } +// message User { +// string display_name = 1; +// string address = 2; +// } +// +// In proto a field mask for `Profile` may look as such: +// +// mask { +// paths: "user.display_name" +// paths: "photo" +// } +// +// In JSON, the same mask is represented as below: +// +// { +// mask: "user.displayName,photo" +// } +// +// # Field Masks and Oneof Fields +// +// Field masks treat fields in oneofs just as regular fields. Consider the +// following message: +// +// message SampleMessage { +// oneof test_oneof { +// string name = 4; +// SubMessage sub_message = 9; +// } +// } +// +// The field mask can be: +// +// mask { +// paths: "name" +// } +// +// Or: +// +// mask { +// paths: "sub_message" +// } +// +// Note that oneof type names ("test_oneof" in this case) cannot be used in +// paths. +// +// ## Field Mask Verification +// +// The implementation of any API method which has a FieldMask type field in the +// request should verify the included field paths, and return an +// `INVALID_ARGUMENT` error if any path is unmappable. +message FieldMask { + // The set of field mask paths. + repeated string paths = 1; +} diff --git a/tools/protobuf/win64/include/google/protobuf/source_context.proto b/tools/protobuf/win64/include/google/protobuf/source_context.proto new file mode 100644 index 00000000..135f50fe --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/source_context.proto @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "SourceContextProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/sourcecontextpb"; + +// `SourceContext` represents information about the source of a +// protobuf element, like the file in which it is defined. +message SourceContext { + // The path-qualified name of the .proto file that contained the associated + // protobuf element. For example: `"google/protobuf/source_context.proto"`. + string file_name = 1; +} diff --git a/tools/protobuf/win64/include/google/protobuf/struct.proto b/tools/protobuf/win64/include/google/protobuf/struct.proto new file mode 100644 index 00000000..1bf0c1ad --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/struct.proto @@ -0,0 +1,95 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/structpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "StructProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; + +// `Struct` represents a structured data value, consisting of fields +// which map to dynamically typed values. In some languages, `Struct` +// might be supported by a native representation. For example, in +// scripting languages like JS a struct is represented as an +// object. The details of that representation are described together +// with the proto support for the language. +// +// The JSON representation for `Struct` is JSON object. +message Struct { + // Unordered map of dynamically typed values. + map fields = 1; +} + +// `Value` represents a dynamically typed value which can be either +// null, a number, a string, a boolean, a recursive struct value, or a +// list of values. A producer of value is expected to set one of these +// variants. Absence of any variant indicates an error. +// +// The JSON representation for `Value` is JSON value. +message Value { + // The kind of value. + oneof kind { + // Represents a null value. + NullValue null_value = 1; + // Represents a double value. + double number_value = 2; + // Represents a string value. + string string_value = 3; + // Represents a boolean value. + bool bool_value = 4; + // Represents a structured value. + Struct struct_value = 5; + // Represents a repeated `Value`. + ListValue list_value = 6; + } +} + +// `NullValue` is a singleton enumeration to represent the null value for the +// `Value` type union. +// +// The JSON representation for `NullValue` is JSON `null`. +enum NullValue { + // Null value. + NULL_VALUE = 0; +} + +// `ListValue` is a wrapper around a repeated field of values. +// +// The JSON representation for `ListValue` is JSON array. +message ListValue { + // Repeated field of dynamically typed values. + repeated Value values = 1; +} diff --git a/tools/protobuf/win64/include/google/protobuf/timestamp.proto b/tools/protobuf/win64/include/google/protobuf/timestamp.proto new file mode 100644 index 00000000..fd0bc07d --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/timestamp.proto @@ -0,0 +1,144 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/timestamppb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TimestampProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; + +// A Timestamp represents a point in time independent of any time zone or local +// calendar, encoded as a count of seconds and fractions of seconds at +// nanosecond resolution. The count is relative to an epoch at UTC midnight on +// January 1, 1970, in the proleptic Gregorian calendar which extends the +// Gregorian calendar backwards to year one. +// +// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap +// second table is needed for interpretation, using a [24-hour linear +// smear](https://developers.google.com/time/smear). +// +// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By +// restricting to that range, we ensure that we can convert to and from [RFC +// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. +// +// # Examples +// +// Example 1: Compute Timestamp from POSIX `time()`. +// +// Timestamp timestamp; +// timestamp.set_seconds(time(NULL)); +// timestamp.set_nanos(0); +// +// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +// +// struct timeval tv; +// gettimeofday(&tv, NULL); +// +// Timestamp timestamp; +// timestamp.set_seconds(tv.tv_sec); +// timestamp.set_nanos(tv.tv_usec * 1000); +// +// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +// +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); +// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +// +// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +// Timestamp timestamp; +// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +// +// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +// +// long millis = System.currentTimeMillis(); +// +// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +// .setNanos((int) ((millis % 1000) * 1000000)).build(); +// +// Example 5: Compute Timestamp from Java `Instant.now()`. +// +// Instant now = Instant.now(); +// +// Timestamp timestamp = +// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) +// .setNanos(now.getNano()).build(); +// +// Example 6: Compute Timestamp from current time in Python. +// +// timestamp = Timestamp() +// timestamp.GetCurrentTime() +// +// # JSON Mapping +// +// In JSON format, the Timestamp type is encoded as a string in the +// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +// where {year} is always expressed using four digits while {month}, {day}, +// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). +// +// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +// 01:30 UTC on January 15, 2017. +// +// In JavaScript, one can convert a Date object to this format using the +// standard +// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +// method. In Python, a standard `datetime.datetime` object can be converted +// to this format using +// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with +// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use +// the Joda Time's [`ISODateTimeFormat.dateTime()`]( +// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime() +// ) to obtain a formatter capable of generating timestamps in this format. +// +message Timestamp { + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + int64 seconds = 1; + + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + int32 nanos = 2; +} diff --git a/tools/protobuf/win64/include/google/protobuf/type.proto b/tools/protobuf/win64/include/google/protobuf/type.proto new file mode 100644 index 00000000..48cb11e7 --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/type.proto @@ -0,0 +1,193 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/any.proto"; +import "google/protobuf/source_context.proto"; + +option cc_enable_arenas = true; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TypeProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/typepb"; + +// A protocol buffer message type. +message Type { + // The fully qualified message name. + string name = 1; + // The list of fields. + repeated Field fields = 2; + // The list of types appearing in `oneof` definitions in this type. + repeated string oneofs = 3; + // The protocol buffer options. + repeated Option options = 4; + // The source context. + SourceContext source_context = 5; + // The source syntax. + Syntax syntax = 6; + // The source edition string, only valid when syntax is SYNTAX_EDITIONS. + string edition = 7; +} + +// A single field of a message type. +message Field { + // Basic field types. + enum Kind { + // Field type unknown. + TYPE_UNKNOWN = 0; + // Field type double. + TYPE_DOUBLE = 1; + // Field type float. + TYPE_FLOAT = 2; + // Field type int64. + TYPE_INT64 = 3; + // Field type uint64. + TYPE_UINT64 = 4; + // Field type int32. + TYPE_INT32 = 5; + // Field type fixed64. + TYPE_FIXED64 = 6; + // Field type fixed32. + TYPE_FIXED32 = 7; + // Field type bool. + TYPE_BOOL = 8; + // Field type string. + TYPE_STRING = 9; + // Field type group. Proto2 syntax only, and deprecated. + TYPE_GROUP = 10; + // Field type message. + TYPE_MESSAGE = 11; + // Field type bytes. + TYPE_BYTES = 12; + // Field type uint32. + TYPE_UINT32 = 13; + // Field type enum. + TYPE_ENUM = 14; + // Field type sfixed32. + TYPE_SFIXED32 = 15; + // Field type sfixed64. + TYPE_SFIXED64 = 16; + // Field type sint32. + TYPE_SINT32 = 17; + // Field type sint64. + TYPE_SINT64 = 18; + } + + // Whether a field is optional, required, or repeated. + enum Cardinality { + // For fields with unknown cardinality. + CARDINALITY_UNKNOWN = 0; + // For optional fields. + CARDINALITY_OPTIONAL = 1; + // For required fields. Proto2 syntax only. + CARDINALITY_REQUIRED = 2; + // For repeated fields. + CARDINALITY_REPEATED = 3; + } + + // The field type. + Kind kind = 1; + // The field cardinality. + Cardinality cardinality = 2; + // The field number. + int32 number = 3; + // The field name. + string name = 4; + // The field type URL, without the scheme, for message or enumeration + // types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + string type_url = 6; + // The index of the field type in `Type.oneofs`, for message or enumeration + // types. The first type has index 1; zero means the type is not in the list. + int32 oneof_index = 7; + // Whether to use alternative packed wire representation. + bool packed = 8; + // The protocol buffer options. + repeated Option options = 9; + // The field JSON name. + string json_name = 10; + // The string value of the default value of this field. Proto2 syntax only. + string default_value = 11; +} + +// Enum type definition. +message Enum { + // Enum type name. + string name = 1; + // Enum value definitions. + repeated EnumValue enumvalue = 2; + // Protocol buffer options. + repeated Option options = 3; + // The source context. + SourceContext source_context = 4; + // The source syntax. + Syntax syntax = 5; + // The source edition string, only valid when syntax is SYNTAX_EDITIONS. + string edition = 6; +} + +// Enum value definition. +message EnumValue { + // Enum value name. + string name = 1; + // Enum value number. + int32 number = 2; + // Protocol buffer options. + repeated Option options = 3; +} + +// A protocol buffer option, which can be attached to a message, field, +// enumeration, etc. +message Option { + // The option's name. For protobuf built-in options (options defined in + // descriptor.proto), this is the short name. For example, `"map_entry"`. + // For custom options, it should be the fully-qualified name. For example, + // `"google.api.http"`. + string name = 1; + // The option's value packed in an Any message. If the value is a primitive, + // the corresponding wrapper type defined in google/protobuf/wrappers.proto + // should be used. If the value is an enum, it should be stored as an int32 + // value using the google.protobuf.Int32Value type. + Any value = 2; +} + +// The syntax in which a protocol buffer element is defined. +enum Syntax { + // Syntax `proto2`. + SYNTAX_PROTO2 = 0; + // Syntax `proto3`. + SYNTAX_PROTO3 = 1; + // Syntax `editions`. + SYNTAX_EDITIONS = 2; +} diff --git a/tools/protobuf/win64/include/google/protobuf/wrappers.proto b/tools/protobuf/win64/include/google/protobuf/wrappers.proto new file mode 100644 index 00000000..1959fa55 --- /dev/null +++ b/tools/protobuf/win64/include/google/protobuf/wrappers.proto @@ -0,0 +1,123 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Wrappers for primitive (non-message) types. These types are useful +// for embedding primitives in the `google.protobuf.Any` type and for places +// where we need to distinguish between the absence of a primitive +// typed field and its default value. +// +// These wrappers have no meaningful use within repeated fields as they lack +// the ability to detect presence on individual elements. +// These wrappers have no meaningful use within a map or a oneof since +// individual entries of a map or fields of a oneof can already detect presence. + +syntax = "proto3"; + +package google.protobuf; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/wrapperspb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "WrappersProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; + +// Wrapper message for `double`. +// +// The JSON representation for `DoubleValue` is JSON number. +message DoubleValue { + // The double value. + double value = 1; +} + +// Wrapper message for `float`. +// +// The JSON representation for `FloatValue` is JSON number. +message FloatValue { + // The float value. + float value = 1; +} + +// Wrapper message for `int64`. +// +// The JSON representation for `Int64Value` is JSON string. +message Int64Value { + // The int64 value. + int64 value = 1; +} + +// Wrapper message for `uint64`. +// +// The JSON representation for `UInt64Value` is JSON string. +message UInt64Value { + // The uint64 value. + uint64 value = 1; +} + +// Wrapper message for `int32`. +// +// The JSON representation for `Int32Value` is JSON number. +message Int32Value { + // The int32 value. + int32 value = 1; +} + +// Wrapper message for `uint32`. +// +// The JSON representation for `UInt32Value` is JSON number. +message UInt32Value { + // The uint32 value. + uint32 value = 1; +} + +// Wrapper message for `bool`. +// +// The JSON representation for `BoolValue` is JSON `true` and `false`. +message BoolValue { + // The bool value. + bool value = 1; +} + +// Wrapper message for `string`. +// +// The JSON representation for `StringValue` is JSON string. +message StringValue { + // The string value. + string value = 1; +} + +// Wrapper message for `bytes`. +// +// The JSON representation for `BytesValue` is JSON string. +message BytesValue { + // The bytes value. + bytes value = 1; +} diff --git a/tools/protobuf/win64/readme.txt b/tools/protobuf/win64/readme.txt new file mode 100644 index 00000000..f7f091fb --- /dev/null +++ b/tools/protobuf/win64/readme.txt @@ -0,0 +1,12 @@ +Protocol Buffers - Google's data interchange format +Copyright 2008 Google Inc. +https://developers.google.com/protocol-buffers/ +This package contains a precompiled binary version of the protocol buffer +compiler (protoc). This binary is intended for users who want to use Protocol +Buffers in languages other than C++ but do not want to compile protoc +themselves. To install, simply place this binary somewhere in your PATH. +If you intend to use the included well known types then don't forget to +copy the contents of the 'include' directory somewhere as well, for example +into '/usr/local/include/'. +Please refer to our official github site for more installation instructions: + https://github.com/protocolbuffers/protobuf diff --git a/tools/protoc_utils/ProtoElement.py b/tools/protoc_utils/ProtoElement.py new file mode 100644 index 00000000..49e2c3e2 --- /dev/null +++ b/tools/protoc_utils/ProtoElement.py @@ -0,0 +1,185 @@ +from __future__ import annotations +from functools import partial +from typing import ClassVar, List, Any, Dict +from typing import Callable +from google.protobuf import message +from google.protobuf.descriptor import Descriptor, FieldDescriptor, FileDescriptor +from google.protobuf.descriptor_pb2 import FieldDescriptorProto,DescriptorProto,EnumDescriptorProto +import google.protobuf.descriptor_pool as descriptor_pool +import logging +import copy +# import custom_options_pb2 as custom + +RendererType = Callable[['ProtoElement'], Dict] +class ProtoElement: + childs:List[ProtoElement] + descriptor:Descriptor|FieldDescriptor + comments: Dict[str,str] + enum_type:EnumDescriptorProto + _comments: Dict[str,str] ={} + pool:descriptor_pool.DescriptorPool + prototypes: dict[str, type[message.Message]] + renderer:RendererType + package:str + file:FileDescriptor + message:str + options:Dict[str,any] + _message_instance:ClassVar + @classmethod + def set_prototypes(cls,prototypes:dict[str, type[message.Message]]): + cls.prototypes = prototypes + @classmethod + def set_comments_base(cls,comments:Dict[str,str]): + cls._comments = comments + @classmethod + def set_pool(cls,pool:descriptor_pool.DescriptorPool): + cls.pool = pool + @classmethod + def set_logger(cls,logger = None): + if not logger and not cls.logger: + cls.logger = logging.getLogger(__name__) + logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" + ) + elif logger: + cls.logger = logger + @classmethod + def set_render(cls,render): + cls.render_class = render + def __init__(self, descriptor: Descriptor|FieldDescriptor, parent=None): + ProtoElement.set_logger() + self.descriptor = descriptor + self.file = descriptor.file + self.package = getattr(descriptor,"file",parent).package + self.descriptorname = descriptor.name + self.json_name = getattr(descriptor,'json_name','') + self.type_name = getattr(descriptor,'type_name',descriptor.name) + + self.parent = parent + self.fullname = descriptor.full_name + self.type = getattr(descriptor,'type',FieldDescriptor.TYPE_MESSAGE) + + if self.type ==FieldDescriptor.TYPE_MESSAGE: + try: + self._message_instance = self.prototypes[self.descriptor.message_type.full_name]() + # self.logger.debug(f'Found instance for {self.descriptor.message_type.full_name}') + except: + # self.logger.error(f'Could not find instance for {self.descriptor.full_name}') + self._message_instance = self.prototypes[self.descriptor.full_name]() + self.label = getattr(descriptor,'label',None) + self.childs = [] + if descriptor.has_options: + self.options = {descr.name: value for descr, value in descriptor.GetOptions().ListFields()} + else: + self.options = {} + try: + if descriptor.containing_type.has_options: + self.options.update({descr.name: value for descr, value in descriptor.containing_type.GetOptions().ListFields()}) + except: + pass + + + + self.render = partial(self.render_class, self) + self.comments = {comment.split('.')[-1]:self._comments[comment] for comment in self._comments.keys() if comment.startswith(self.path)} + @property + def cpp_type(self)->str: + return f'{self.package}_{self.descriptor.containing_type.name}' + @property + def cpp_member(self)->str: + return self.name + @property + def cpp_type_member_prefix(self)->str: + return f'{self.cpp_type}_{self.cpp_member}' + @property + def cpp_type_member(self)->str: + return f'{self.cpp_type}.{self.cpp_member}' + @property + def main_message(self)->bool: + return self.parent == None + @property + def parent(self)->ProtoElement: + return self._parent + @parent.setter + def parent(self,value:ProtoElement): + self._parent = value + if value: + self._parent.childs.append(self) + @property + def root(self)->ProtoElement: + return self if not self.parent else self.parent + @property + def enum_type(self)->EnumDescriptorProto: + return self.descriptor.enum_type + @property + def cpp_root(self): + return f'{self.cpp_type}_ROOT' + @property + def cpp_child(self): + return f'{self.cpp_type}_CHILD' + @property + def message_instance(self): + return getattr(self,'_message_instance',getattr(self.parent,'message_instance',None)) + @property + def tree(self): + childs = '->('+', '.join(c.tree for c in self.childs ) + ')' if len(self.childs)>0 else '' + return f'{self.name}{childs}' + @property + def name(self): + return self.descriptorname if len(self.descriptorname)>0 else self.parent.name if self.parent else self.package + @property + def enum_values(self)->List[str]: + return [n.name for n in getattr(self.enum_type,"values",getattr(self.enum_type,"value",[])) ] + @property + def enum_values_str(self)->str: + return ', '.join(self.enum_values) + @property + def fields(self)->List[FieldDescriptor]: + return getattr(self.descriptor,"fields",getattr(getattr(self.descriptor,"message_type",None),"fields",None)) + @property + def _default_value(self): + if 'default_value' in self.options: + return self.options['default_value'] + if self.type in [FieldDescriptorProto.TYPE_INT32, FieldDescriptorProto.TYPE_INT64, + FieldDescriptorProto.TYPE_UINT32, FieldDescriptorProto.TYPE_UINT64, + FieldDescriptorProto.TYPE_SINT32, FieldDescriptorProto.TYPE_SINT64, + FieldDescriptorProto.TYPE_FIXED32, FieldDescriptorProto.TYPE_FIXED64, + FieldDescriptorProto.TYPE_SFIXED32, FieldDescriptorProto.TYPE_SFIXED64]: + return 0 + elif self.type in [FieldDescriptorProto.TYPE_FLOAT, FieldDescriptorProto.TYPE_DOUBLE]: + return 0.0 + elif self.type == FieldDescriptorProto.TYPE_BOOL: + return False + elif self.type in [FieldDescriptorProto.TYPE_STRING, FieldDescriptorProto.TYPE_BYTES]: + return "" + elif self.is_enum: + return self.enum_values[0] if self.enum_values else 0 + @property + def detached_leading_comments(self)->str: + return self.comments["leading"] if "detached" in self.comments else "" + + @property + def leading_comment(self)->str: + return self.comments["leading"] if "leading" in self.comments else "" + @property + def trailing_comment(self)->str: + return self.comments["trailing"] if "trailing" in self.comments else "" + @property + def is_enum(self): + return self.type == FieldDescriptorProto.TYPE_ENUM + @property + def path(self) -> str: + return self.descriptor.full_name + + @property + def enum_name(self)-> str: + return self.type_name.split('.', maxsplit=1)[-1] + @property + def repeated(self)->bool: + return self.label== FieldDescriptor.LABEL_REPEATED + + + + + + diff --git a/tools/protoc_utils/ProtocParser.py b/tools/protoc_utils/ProtocParser.py new file mode 100644 index 00000000..0cc8f985 --- /dev/null +++ b/tools/protoc_utils/ProtocParser.py @@ -0,0 +1,291 @@ +# !/usr/bin/env python +from functools import partial +import sys +import json +from typing import Callable, Dict, List +import argparse +from abc import ABC, abstractmethod +import google.protobuf.descriptor_pool as descriptor_pool + +from google.protobuf import message_factory,message +from google.protobuf.message_factory import GetMessageClassesForFiles +from google.protobuf.compiler import plugin_pb2 as plugin +from google.protobuf.descriptor import FieldDescriptor, Descriptor, FileDescriptor +from google.protobuf.descriptor_pb2 import FileDescriptorProto, DescriptorProto, FieldDescriptorProto,FieldOptions +from urllib import parse +from ProtoElement import ProtoElement +import logging + +logger = logging.getLogger(__name__) +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) + + +class ProtocParser(ABC) : + + request:plugin.CodeGeneratorRequest + response:plugin.CodeGeneratorResponse + elements:List[ProtoElement] = [] + comments: Dict[str, str] = {} + json_content = {} + main_class_list:List[str] = [] + param_dict:Dict[str,str] = {} + pool:descriptor_pool.DescriptorPool + factory:message_factory + + @abstractmethod + def render(self,element: ProtoElement): + pass + + @abstractmethod + def get_name(self)->str: + pass + @abstractmethod + # def start_element(self,element:ProtoElement): + # logger.debug(f'START Processing ELEMENT {element.path}') + # @abstractmethod + # def end_element(self,element:ProtoElement): + # logger.debug(f'END Processing ELEMENT {element.path}') + @abstractmethod + def end_message(self,classElement:ProtoElement): + logger.debug(f'END Processing MESSAGE {classElement.name}') + @abstractmethod + def start_message(self,classElement:ProtoElement) : + logger.debug(f'START Processing MESSAGE {classElement.name}') + @abstractmethod + def start_file(self,file:FileDescriptor) : + logger.debug(f'START Processing file {file.name}') + @abstractmethod + def end_file(self,file:FileDescriptor) : + logger.debug(f'END Processing file {file.name}') + + def __init__(self,data): + self.request = plugin.CodeGeneratorRequest.FromString(data) + self.response = plugin.CodeGeneratorResponse() + logger.info(f'Received ${self.get_name()} parameter(s): {self.request.parameter}') + params = self.request.parameter.split(',') + self.param_dict = {p.split('=')[0]: parse.unquote(p.split('=')[1]) for p in params if '=' in p} + if not 'const_prefix' in self.param_dict: + self.param_dict['const_prefix'] = "" + logger.warn("No option passed for const_prefix. No prefix will be used for option init_from_mac") + self.main_class_list = self.get_arg(name= 'main_class',split=True,split_char='!') + if 'path' in self.param_dict: + self.param_dict['path'] = self.param_dict['path'].split('?') + for p in self.param_dict['path']: + logger.debug(f'Adding to path: {p}') + sys.path.append(p) + import customoptions_pb2 as custom__options__pb2 + + def get_arg(self,name:str,default=None,split:bool=False,split_char:str=';'): + result = self.param_dict.get(name, default) + if result and len(result) == 0: + if not default: + logger.error(f'Plugin parameter {name} not found') + result = None + else: + result = default + logger.warn(f'Plugin parameter {name} not found. Defaulting to {str(default)}') + if split and result: + result = result.split(split_char) + logger.debug(f'Returning argument {name}={str(result)}') + return result + def get_name_attr(self,proto_element): + attributes = ['package','name'] + for att in attributes: + if hasattr(proto_element, att): + return att + return None + def interpret_path(self,path, proto_element): + if not path: + if hasattr(proto_element,"name"): + return proto_element.name + else: + return '' + + # Get the next path element + path_elem = path[0] + name_att = self.get_name_attr(proto_element) + if name_att: + elem_name = getattr(proto_element, name_att) + elem_sep = '.' + else: + elem_name = '' + elem_sep = '' + + # Ensure the proto_element has a DESCRIPTOR attribute + if hasattr(proto_element, 'DESCRIPTOR'): + # Use the DESCRIPTOR to access field information + descriptor = proto_element.DESCRIPTOR + + # Get the field name from the descriptor + try: + field = descriptor.fields_by_number[path_elem] + except: + return None + + field_name = field.name + field_name = field_name.lower().replace('_field_number', '') + + # Access the field if it exists + if field_name == "extension" : + return field_name + + elif hasattr(proto_element, field_name): + next_element = getattr(proto_element, field_name) + if isinstance(next_element,list): + # If the next element is a list, use the next path element as an index + return f'{elem_name}{elem_sep}{self.interpret_path(path[1:], next_element[path[1]])}' + else: + # If it's not a list, just continue with the next path element + return f'{elem_name}{elem_sep}{self.interpret_path(path[1:], next_element)}' + else: + return f'{elem_name}{elem_sep}{self.interpret_path(path[1:], proto_element[path_elem])}' + # If the path cannot be interpreted, return None or raise an error + return None + + + def extract_comments(self,proto_file: FileDescriptorProto): + for location in proto_file.source_code_info.location: + # The path is a sequence of integers identifying the syntactic location + path = tuple(location.path) + leading_comments = location.leading_comments.strip() + trailing_comments = location.trailing_comments.strip() + if len(location.leading_detached_comments)>0: + logger.debug('found detached comments') + + leading_detached_comments = '\r\n'.join(location.leading_detached_comments) + if len(leading_comments) == 0 and len(trailing_comments) == 0 and len(leading_detached_comments) == 0: + continue + # Interpret the path and map it to a specific element + # This is where you'll need to add logic based on your protobuf structure + element_identifier = self.interpret_path(path, proto_file) + if element_identifier is not None: + self.comments[f"{element_identifier}.leading"] = leading_comments + self.comments[f"{element_identifier}.trailing"] = trailing_comments + self.comments[f"{element_identifier}.detached"] = leading_detached_comments + + + + def get_comments(self,field: FieldDescriptorProto, proto_file: FileDescriptorProto,message: DescriptorProto): + if hasattr(field,'name') : + name = getattr(field,'name') + commentspath = f"{proto_file.package}.{message.name}.{name}" + if commentspath in self.comments: + return commentspath,self.comments[commentspath] + return None,None + + def get_nested_message(self, field: FieldDescriptorProto, proto_file: FileDescriptorProto): + # Handle nested message types + if field.type != FieldDescriptorProto.TYPE_MESSAGE: + return None + + nested_message_name = field.type_name.split('.')[-1] + # logger.debug(f'Looking for {field.type_name} ({nested_message_name}) in {nested_list}') + + nested_message= next((m for m in proto_file.message_type if m.name == nested_message_name), None) + if not nested_message: + # logger.debug(f'Type {nested_message_name} was not found in file {proto_file.name}. Checking in processed list: {processed_list}') + nested_message = next((m for m in self.elements if m.name == nested_message_name), None) + if not nested_message: + logger.error(f'Could not locate message class {field.type_name} ({nested_message_name})') + return nested_message + + def process_message(self,message: ProtoElement, parent:ProtoElement = None )->ProtoElement: + if not message: + return + + if not message.fields: + logger.warn(f"{message.path} doesn't have fields!") + return + for field in message.fields: + element = ProtoElement( + parent=message, + descriptor=field + ) + logging.debug(f'Element: {element.path}') + if getattr(field,"message_type",None): + self.process_message(element,message) + + @property + def packages(self)->List[str]: + return list(set([proto_file.package for proto_file in self.request.proto_file if proto_file.package])) + @property + def file_set(self)->List[FileDescriptor]: + return list(set([ self.pool.FindMessageTypeByName(message).file for message in self.main_class_list if self.pool.FindMessageTypeByName(message)])) + + @property + def proto_files(self)->List[FileDescriptorProto]: + return list( + proto_file for proto_file in self.request.proto_file if + not proto_file.name.startswith("google/") + and not proto_file.name.startswith("nanopb") + and not proto_file.package.startswith("google.protobuf") + ) + + + def get_main_messages_from_file(self,fileDescriptor:FileDescriptor)->List[Descriptor]: + return [message for name,message in fileDescriptor.message_types_by_name.items() if message.full_name in self.main_class_list] + def process(self) -> None: + if len(self.proto_files) == 0: + logger.error('No protocol buffer file selected for processing') + return + self.setup() + logger.info(f'Processing message(s) {", ".join([name for name in self.main_class_list ])}') + + for fileObj in self.file_set : + self.start_file(fileObj) + for message in self.get_main_messages_from_file(fileObj): + element = ProtoElement( descriptor=message ) + self.start_message(element) + self.process_message(element) + self.end_message(element) + self.end_file(fileObj) + sys.stdout.buffer.write(self.response.SerializeToString()) + + def setup(self): + + for proto_file in self.proto_files: + logger.debug(f"Extracting comments from : {proto_file.name}") + self.extract_comments(proto_file) + self.pool = descriptor_pool.DescriptorPool() + self.factory = message_factory.MessageFactory(self.pool) + for proto_file in self.request.proto_file: + logger.debug(f'Adding {proto_file.name} to pool') + self.pool.Add(proto_file) + self.messages = GetMessageClassesForFiles([f.name for f in self.request.proto_file], self.pool) + ProtoElement.set_pool(self.pool) + ProtoElement.set_render(self.render) + ProtoElement.set_logger(logger) + ProtoElement.set_comments_base(self.comments) + ProtoElement.set_prototypes(self.messages) + + @property + def main_messages(self)->List[ProtoElement]: + return [ele for ele in self.elements if ele.main_message ] + + def get_message_descriptor(self, name) -> Descriptor: + for package in self.packages: + qualified_name = f'{package}.{name}' if package else name + + try: + descriptor = self.pool.FindMessageTypeByName(qualified_name) + if descriptor: + return descriptor + except: + pass + return None + + @classmethod + def get_data(cls): + parser = argparse.ArgumentParser(description='Process protobuf and JSON files.') + parser.add_argument('--source', help='Python source file', default=None) + args = parser.parse_args() + if args.source: + logger.info(f'Loading request data from {args.source}') + with open(args.source, 'rb') as file: + data = file.read() + else: + data = sys.stdin.buffer.read() + return data + diff --git a/tools/protoc_utils/__pycache__/ProtoElement.cpython-38.pyc b/tools/protoc_utils/__pycache__/ProtoElement.cpython-38.pyc new file mode 100644 index 00000000..86efee21 Binary files /dev/null and b/tools/protoc_utils/__pycache__/ProtoElement.cpython-38.pyc differ diff --git a/tools/protoc_utils/__pycache__/ProtocParser.cpython-38.pyc b/tools/protoc_utils/__pycache__/ProtocParser.cpython-38.pyc new file mode 100644 index 00000000..f4f2cc29 Binary files /dev/null and b/tools/protoc_utils/__pycache__/ProtocParser.cpython-38.pyc differ diff --git a/tools/protoc_utils/generate_bin.py b/tools/protoc_utils/generate_bin.py new file mode 100644 index 00000000..a2fd3ba8 --- /dev/null +++ b/tools/protoc_utils/generate_bin.py @@ -0,0 +1,84 @@ +import json +import os +import sys +import argparse +import importlib.util +import logging +from pathlib import Path +from google.protobuf import json_format +from google.protobuf.json_format import MessageToJson + +# Assuming this script is in the same directory as the generated Python files +# script_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),'generated/src') +# sys.path.append(script_dir) + +# Configure logging +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + + +def load_protobuf_module(source, includes): + """Dynamically load a protobuf module given its file name.""" + for include in includes: + sys.path.append(include) + + module_name = Path(source).stem + module_file = module_name + '_pb2.py' + module_location = Path(source).parent / module_file + + logging.debug(f'Loading module {module_file} from {module_location} with includes [{", ".join(includes)}]') + + spec = importlib.util.spec_from_file_location(name=module_name, location=str(module_location)) + if spec is not None: + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + logging.debug(f'Loaded protobuf module: {module_name}') + return module + + else: + logging.error(f'Failed to load module {module_file} from {module_location}') + return None + + + +def protobuf_to_dict(message): + """Convert a protobuf message to a dictionary.""" + # Convert the protobuf message to a JSON string + json_str = MessageToJson(message, including_default_value_fields=True) + # Parse the JSON string back into a dictionary + return json.loads(json_str) + + +def main(): + parser = argparse.ArgumentParser(description='Process protobuf and JSON files.') + parser.add_argument('--proto_file', help='Name of the protobuf file (without extension)') + parser.add_argument('--main_class', help='Main message class to process') + parser.add_argument('--target_dir', help='Target directory for output files') + parser.add_argument('--include', help='Directory where message python files can be found', default=None,action = 'append' ) + parser.add_argument('--json', help='Source JSON file(s)',action = 'append' ) + + args = parser.parse_args() + + # Load the protobuf module + logging.debug(f'Loading modules') + proto_module = load_protobuf_module(args.proto_file, args.include) + + # Determine the main message class + main_message_class = getattr(proto_module, args.main_class) + message = main_message_class() + + proto_base_name = Path(args.proto_file).stem + + for jsonfile in args.json: + output_file_base = os.path.join(args.target_dir, Path(jsonfile).stem+".bin") + logging.debug(f'Converting JSON file {jsonfile} to binary format') + with open(jsonfile, 'r') as json_file: + json_data = json.load(json_file) + json_format.ParseDict(json_data, message) + binary_data = message.SerializeToString() + with open(output_file_base, 'wb') as bin_file: + bin_file.write(binary_data) + logging.info(f'Binary file written to {output_file_base}') + + +if __name__ == '__main__': + main() diff --git a/tools/protoc_utils/parse_bin.py b/tools/protoc_utils/parse_bin.py new file mode 100644 index 00000000..ad1bb427 --- /dev/null +++ b/tools/protoc_utils/parse_bin.py @@ -0,0 +1,92 @@ +import json +import os +import sys +import argparse +import importlib.util +import logging +from pathlib import Path +from google.protobuf import json_format +from google.protobuf.json_format import MessageToJson + + +# Assuming this script is in the same directory as the generated Python files +# script_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),'generated/src') +# sys.path.append(script_dir) + +# Configure logging +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + + +def load_protobuf_module(source, includes): + """Dynamically load a protobuf module given its file name.""" + for include in includes: + sys.path.append(include) + + module_name = Path(source).stem + module_file = module_name + '_pb2.py' + module_location = Path(source).parent / module_file + + logging.info(f'Loading module {module_file} from {module_location} with includes [{", ".join(includes)}]') + + spec = importlib.util.spec_from_file_location(name=module_name, location=str(module_location)) + if spec is not None: + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + logging.info(f'Loaded protobuf module: {module_name}') + return module + + else: + logging.error(f'Failed to load module {module_file} from {module_location}') + return None + + + +def protobuf_to_dict(message): + """Convert a protobuf message to a dictionary.""" + # Convert the protobuf message to a JSON string + json_str = MessageToJson(message, including_default_value_fields=True) + # Parse the JSON string back into a dictionary + return json.loads(json_str) + + +def main(): + parser = argparse.ArgumentParser(description='Process protobuf and JSON files.') + parser.add_argument('--proto_file', help='Name of the protobuf file (without extension)') + parser.add_argument('--main_class', help='Main message class to process') + parser.add_argument('--source', help='Source file to parse') + parser.add_argument('--include', help='Directory where message python files can be found', default=None,action = 'append' ) + parser.add_argument('--json', help='Source JSON file(s)',action = 'append' ) + args = parser.parse_args() + + # Load the protobuf module + logging.info(f'Loading modules') + proto_module = load_protobuf_module(args.proto_file, args.include) + + # Determine the main message class + main_message_class = getattr(proto_module, args.main_class) + message = main_message_class() + + proto_base_name = Path(args.proto_file).stem + import configuration_pb2 + config = configuration_pb2.Config() + + with open(args.source, 'rb') as bin_file: # Open in binary mode + data =bin_file.read() + config.ParseFromString(data) + logging.info(f'Parsed: {json.dumps(config)}') + + + # for jsonfile in args.json: + # output_file_base = os.path.join(args.target_dir, Path(jsonfile).stem+".bin") + # logging.info(f'Converting JSON file {jsonfile} to binary format') + # with open(jsonfile, 'r') as json_file: + # json_data = json.load(json_file) + # json_format.ParseDict(json_data, message) + # binary_data = message.SerializeToString() + # with open(output_file_base, 'wb') as bin_file: + # bin_file.write(binary_data) + # logging.info(f'Binary file written to {output_file_base}') + + +if __name__ == '__main__': + main() diff --git a/components/wifi-manager/webapp/dist/src/bootswatch/docs/2/js/bootstrap.d.ts b/tools/protoc_utils/protoc-commands-utils.py similarity index 100% rename from components/wifi-manager/webapp/dist/src/bootswatch/docs/2/js/bootstrap.d.ts rename to tools/protoc_utils/protoc-commands-utils.py diff --git a/tools/protoc_utils/protoc-gen-defaults.bat b/tools/protoc_utils/protoc-gen-defaults.bat new file mode 100644 index 00000000..a56b4816 --- /dev/null +++ b/tools/protoc_utils/protoc-gen-defaults.bat @@ -0,0 +1,2 @@ +@echo off +python.exe "%~dp0protoc-gen-defaults.py" %* diff --git a/tools/protoc_utils/protoc-gen-defaults.py b/tools/protoc_utils/protoc-gen-defaults.py new file mode 100644 index 00000000..ce5be6c6 --- /dev/null +++ b/tools/protoc_utils/protoc-gen-defaults.py @@ -0,0 +1,132 @@ +# !/usr/bin/env python +import os + +import logging +import json +from pathlib import Path +from typing import Dict, List +from google.protobuf.compiler import plugin_pb2 as plugin +from google.protobuf.message_factory import GetMessageClass +from google.protobuf.descriptor_pb2 import FileDescriptorProto, DescriptorProto, FieldDescriptorProto,FieldOptions +from google.protobuf.descriptor import FieldDescriptor, Descriptor, FileDescriptor +from ProtoElement import ProtoElement +from ProtocParser import ProtocParser + + +logger = logging.getLogger(__name__) +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) +class BinDefaultsParser(ProtocParser) : + def start_message(self,message:ProtoElement) : + super().start_message(message) + def end_message(self,message:ProtoElement): + super().end_message(message) + self.has_error = False + default_structure = message.render() + if not default_structure: + logger.warn(f'No default values for {message.name}') + return + respfile = self.response.file.add() + + outfilename = f'{message.name}_defaults_pb.bin' + with open(os.path.join(self.param_dict.get('defaultspath','.'),outfilename), 'wb') as bin_file: + res = default_structure.SerializeToString() + bin_file.write(res) + logger.info(f'Wrote {bin_file.name}') + respfile.name = f'{outfilename}.gen' + logger.info(f"Creating binary file for defaults: {respfile.name}") + respfile.content = f'Content written to {respfile.name}' + + def start_file(self,file:FileDescriptor) : + super().start_file(file) + + + def end_file(self,file:ProtoElement) : + super().end_file(file) + + + def get_name(self)->str: + return 'protoc_plugin_defaults' + + def add_comment_if_exists(element, comment_type: str, path: str) -> dict: + comment = getattr(element, f"{comment_type}_comment", "").strip() + return {f"__{comment_type}_{path}": comment} if comment else {} + def repeated_render(self,element:ProtoElement,obj:any): + return [obj] if element.repeated else obj + def render(self,element: ProtoElement): + if len(element.childs)>0: + oneof = getattr(element.descriptor,'containing_oneof',None) + if oneof: + # we probably shouldn't set default values here + pass + has_render = False + for child in element.childs: + rendered = child.render() + if rendered: + has_render = True + # try: + if child.repeated: + try: + getattr(element.message_instance,child.name).extend(rendered) + except: + getattr(element.message_instance,child.name).extend( [rendered]) + + elif child.type == FieldDescriptor.TYPE_MESSAGE: + getattr(element.message_instance,child.name).CopyFrom(rendered) + else: + setattr(element.message_instance,child.name,rendered) + # except: + # logger.error(f'Unable to assign value from {child.fullname} to {element.fullname}') + element.message_instance.SetInParent() + if not has_render: + return None + + else: + + default_value = element._default_value + options = element.options['cust_field'] if 'cust_field' in element.options else None + msg_options = element.options['cust_msg'] if 'cust_msg' in element.options else None + init_from_mac = getattr(options,'init_from_mac', False) or getattr(msg_options,'init_from_mac', False) + + + default_value = getattr(options,'default_value', None) + global_name = getattr(options,'global_name', None) + const_prefix = getattr(options,'const_prefix', self.param_dict['const_prefix']) + if init_from_mac: + default_value = f'{const_prefix}@@init_from_mac@@' + elif default_value: + if element.descriptor.cpp_type == FieldDescriptor.CPPTYPE_STRING: + default_value = default_value + elif element.descriptor.cpp_type == FieldDescriptor.CPPTYPE_ENUM: + try: + default_value = element.enum_values.index(default_value) + except: + raise ValueError(f'Invalid default value {default_value} for {element.path}') + elif element.descriptor.cpp_type in [FieldDescriptor.CPPTYPE_INT32, FieldDescriptor.CPPTYPE_INT64, + FieldDescriptor.CPPTYPE_UINT32, FieldDescriptor.CPPTYPE_UINT64]: + int_value = int(default_value) + if element.descriptor.cpp_type in [FieldDescriptor.CPPTYPE_UINT32, FieldDescriptor.CPPTYPE_UINT64] and int_value < 0: + raise ValueError(f"Negative value for unsigned int type trying to assign {element.path} = {default_value}") + default_value = int_value + elif element.descriptor.cpp_type in [FieldDescriptor.CPPTYPE_DOUBLE, FieldDescriptor.CPPTYPE_FLOAT]: + float_value = float(default_value) + if '.' not in default_value: + raise ValueError(f"Integer string for float/double type trying to assign {element.path} = {default_value}") + default_value = float_value + elif element.descriptor.cpp_type == FieldDescriptor.CPPTYPE_BOOL: + if default_value.lower() in ['true', 'false']: + default_value = default_value.lower() == 'true' + else: + raise ValueError(f'Invalid boolean value trying to assign {element.path} = {default_value}') + if default_value: + element.message_instance.SetInParent() + return self.repeated_render(element,default_value) if default_value else None + return element.message_instance + +if __name__ == '__main__': + data = ProtocParser.get_data() + logger.info(f"Generating binary files for defaults") + protocParser:BinDefaultsParser = BinDefaultsParser(data) + protocParser.process() + logger.debug('Done generating JSON file(s)') diff --git a/tools/protoc_utils/protoc-gen-dump.bat b/tools/protoc_utils/protoc-gen-dump.bat new file mode 100644 index 00000000..8648f8eb --- /dev/null +++ b/tools/protoc_utils/protoc-gen-dump.bat @@ -0,0 +1,2 @@ +@echo off +python.exe "%~dp0protoc-gen-dump.py" %* diff --git a/tools/protoc_utils/protoc-gen-dump.py b/tools/protoc_utils/protoc-gen-dump.py new file mode 100644 index 00000000..59f796e3 --- /dev/null +++ b/tools/protoc_utils/protoc-gen-dump.py @@ -0,0 +1,66 @@ +# !/usr/bin/env python +import argparse +import sys +import os +from google.protobuf.compiler import plugin_pb2 as plugin +from google.protobuf.compiler.plugin_pb2 import CodeGeneratorResponse +from urllib import parse + +import logging +logger = logging.getLogger(__name__) +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) + +# def main(): +# data = sys.stdin.buffer.read() + # with open("C:/Users/sle11/Documents/VSCode/squeezelite-esp32/protobuf/generated/src/code_generator_request.bin", "wb") as file: + # file.write(data) + +# if __name__ == "__main__": +# main() + + + +def process( + request: plugin.CodeGeneratorRequest, response: CodeGeneratorResponse, data +) -> None: + logger.info(f'Received parameter(s): {request.parameter}') + params = request.parameter.split(',') + param_dict = {p.split('=')[0]: parse.unquote(p.split('=')[1]) for p in params if '=' in p} + param_dict['path'] = param_dict['path'].split('?') + basename = "code_generator_request.bin" + binpath = os.path.join(param_dict.get('binpath', './'),basename) + file:CodeGeneratorResponse.File = response.file.add() + file.name = f"{basename}.txt" + file.content = f'Generated binary file {binpath}' + logger.info(f"Dumping CodeGeneratorRequest object to : {binpath}") + + with open(binpath, "wb") as file: + file.write(data) +def GetData(): + + parser = argparse.ArgumentParser(description='Process protobuf and JSON files.') + parser.add_argument('--source', help='Python source file', default=None) + args = parser.parse_args() + if args.source: + logger.info(f'Loading request data from {args.source}') + with open(args.source, 'rb') as file: + data = file.read() + else: + data = sys.stdin.buffer.read() + return data + +def main(): + data = GetData() + request = plugin.CodeGeneratorRequest.FromString(data) + response = CodeGeneratorResponse() + process(request, response,data) + sys.stdout.buffer.write(response.SerializeToString()) + logger.info('Done dumping request') + + + +if __name__ == '__main__': + main() + diff --git a/tools/protoc_utils/protoc-gen-json b/tools/protoc_utils/protoc-gen-json new file mode 100644 index 00000000..d4fb1382 --- /dev/null +++ b/tools/protoc_utils/protoc-gen-json @@ -0,0 +1,2 @@ +#!/bin/bash +python "$(dirname "$0")/protoc-gen-json.py" "$@" diff --git a/tools/protoc_utils/protoc-gen-json.bat b/tools/protoc_utils/protoc-gen-json.bat new file mode 100644 index 00000000..caa88aa4 --- /dev/null +++ b/tools/protoc_utils/protoc-gen-json.bat @@ -0,0 +1,2 @@ +@echo off +python.exe "%~dp0protoc-gen-json.py" %* diff --git a/tools/protoc_utils/protoc-gen-json.py b/tools/protoc_utils/protoc-gen-json.py new file mode 100644 index 00000000..87afa600 --- /dev/null +++ b/tools/protoc_utils/protoc-gen-json.py @@ -0,0 +1,79 @@ +# !/usr/bin/env python +import os + +import logging +import json +from pathlib import Path +from typing import Dict, List +from google.protobuf.compiler import plugin_pb2 as plugin +from google.protobuf.descriptor_pb2 import FileDescriptorProto, DescriptorProto, FieldDescriptorProto,FieldOptions +from google.protobuf.descriptor import FieldDescriptor, Descriptor, FileDescriptor +from ProtoElement import ProtoElement +from ProtocParser import ProtocParser + + +logger = logging.getLogger(__name__) +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) +class JsonParser(ProtocParser) : + def start_message(self,message:ProtoElement) : + super().start_message(message) + def end_message(self,message:ProtoElement): + super().end_message(message) + jsonmessage = message.render() + respfile = self.response.file.add() + respfile.name = f'{message.name}_pb2.json' + logger.info(f"Creating new template json file: {respfile.name}") + respfile.content = json.dumps(jsonmessage, indent=2) + "\r\n" + + def start_file(self,file:FileDescriptor) : + super().start_file(file) + self.jsonmessages = {} + def end_file(self,file:ProtoElement) : + super().end_file(file) + + + def get_name(self)->str: + return 'protoc_plugin_json' + + def add_comment_if_exists(element, comment_type: str, path: str) -> dict: + comment = getattr(element, f"{comment_type}_comment", "").strip() + return {f"__{comment_type}_{path}": comment} if comment else {} + def repeated_render(self,element:ProtoElement,obj:any): + return [obj] if element.repeated else obj + def render(self,element: ProtoElement) -> Dict: + result = {} + if len(element.childs)>0: + oneof = getattr(element.descriptor,'containing_oneof',None) + if oneof: + result[f'__one_of_{element.name}'] = f'Choose only one structure for {oneof.full_name}' + for child in element.childs: + child_result = child.render() + if len(child.childs) > 0: + result[child.name] = child_result + elif isinstance(child_result, dict): + result.update(child_result) + + else: + result.update({ + **({f'__comments_{element.name}': element.leading_comment} if element.leading_comment.strip() else {}), + **({f'__values_{element.name}': element.enum_values_str} if element.is_enum else {}), + element.name: element._default_value, + **({f'__comments2_{element.name}': element.trailing_comment} if element.trailing_comment.strip() else {}) + }) + + optnames = ['init_from_mac', 'const_prefix','read_only','default_value'] + if len(element.options)>0: + logger.debug(f'{element.name} has options') + for optname in [optname for optname in optnames if optname in element.options]: + logger.debug(f"{element.name} [{optname} = {element.options[optname]}]") + return self.repeated_render(element,result) + + +if __name__ == '__main__': + data = ProtocParser.get_data() + logger.debug(f"Generating blank json file(s)") + protocParser:JsonParser = JsonParser(data) + protocParser.process() + logger.debug('Done generating JSON file(s)') diff --git a/tools/protoc_utils/protoc-gen-options.bat b/tools/protoc_utils/protoc-gen-options.bat new file mode 100644 index 00000000..ea2ddeb7 --- /dev/null +++ b/tools/protoc_utils/protoc-gen-options.bat @@ -0,0 +1,2 @@ +@echo off +python.exe "%~dp0protoc-gen-options.py" %* diff --git a/tools/protoc_utils/protoc-gen-options.py b/tools/protoc_utils/protoc-gen-options.py new file mode 100644 index 00000000..fae2fda1 --- /dev/null +++ b/tools/protoc_utils/protoc-gen-options.py @@ -0,0 +1,255 @@ +# !/usr/bin/env python +import io +import os + +import logging +import json +from pathlib import Path +from typing import Dict, List +from google.protobuf.compiler import plugin_pb2 as plugin +from google.protobuf.descriptor_pb2 import FileDescriptorProto, DescriptorProto, FieldDescriptorProto,FieldOptions +from google.protobuf.descriptor import FieldDescriptor, Descriptor, FileDescriptor +from ProtoElement import ProtoElement +from ProtocParser import ProtocParser +file_suffix = "_options_pb2" +head_comments =""" +/* Automatically generated nanopb header */ +/* Generated by protoc-plugin-options */ +""" + +PROCESSED_PREFIX = 'processed_' +logger = logging.getLogger(__name__) +logging.basicConfig( + level=logging.DEBUG, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) +class OptionsParser(ProtocParser) : + + def start_message(self,message:ProtoElement) : + super().start_message(message) + def reset_data(self): + self.all_members_defaults:Dict([str,str]) = {} + self.lines = {} + self.lines['init_from_mac'] = [] + # self.lines['read_only'] = {} + # self.lines['default_value'] = {} + # self.lines['init_from_mac']['source'] = ['void set_init_from_mac(self.message_type_name * data){'] + # self.lines['init_from_mac']['header'] = [] + # self.lines['read_only']['source'] = [] + # self.lines['read_only']['header'] = [] + # self.lines['default_value']['source'] = [] + # self.lines['default_value']['header'] = [] + def writelines(self,lines, out:io.StringIO): + for l in lines: + out.write(f'{l}\r\n') + + # def render_all_members_for_message(self,name,roottype:bool=False): + # elements= self.lines['init_from_mac'] + # for element in [element for element in elements if element.descriptor.containing_type.name == name]: + # suffix = "ROOT" if roottype else "CHILD(msg, member)" + # const_prefix = self.get_option(element,'const_prefix') or "" + + # memberprefix = '' if roottype else 'member.' + # msg = element.name if roottype else "msg" + # self.c_header.writelines(f'MSG_INIT_FROM_MAC_DECLARATION({element.cpp_type})') + # self.c_header.writelines(f'#define {element.cpp_type}_ALL_MEMBERS_{suffix}') + # if(elements.index(element)>0): + # self.c_header.writelines(f',\\\n') + # else: + # self.c_source.writelines(f'MSG_INIT_FROM_MAC_IMPLEMENTATION({msg_ctype});') + + + def render_all_members(self): + for key in [key for key in self.all_members_defaults.keys() if not '.' in key and not key.startswith(PROCESSED_PREFIX)]: + # make each line unique + self.all_members_defaults[key] = set(self.all_members_defaults[key]) + self.all_members_defaults[key] = '\\\n'.join(self.all_members_defaults[key]) + + # WRITE DEPENDENCIES FOR THE CURRENT FILE + + + member_defines = '\n'.join([ self.all_members_defaults.get(key) for key in self.all_members_defaults.keys() if '.' in key]) + self.c_header.writelines(member_defines) + message_defines = ',\\\n'.join([key for key in self.all_members_defaults.keys() if not '.' in key]) + self.c_header.writelines(message_defines) + + + def end_message(self,message:ProtoElement): + super().end_message(message) + self.message_type_name = message.path.replace('.','_') + self.global_name = message.options.get("global_name",message.path) + message.render() + self.render_all_members() + # self.c_source.writelines() + def start_file(self,file:FileDescriptor) : + super().start_file(file) + self.set_source(Path(file.name).stem) + self.reset_data() + + def end_file(self,file:ProtoElement) : + super().end_file(file) + # Parse request + # self.lines['init_from_mac']['source'] = ['}'] + # self.c_header.writelines(self.lines['init_from_mac']['source']) + # self.c_source.writelines(self.lines['init_from_mac']['header']) + self.set_source(None) + + + + def get_name(self)->str: + return 'protoc_plugin_options' + + def add_comment_if_exists(element, comment_type: str, path: str) -> dict: + comment = getattr(element, f"{comment_type}_comment", "").strip() + return {f"__{comment_type}_{path}": comment} if comment else {} + def repeated_render(self,element:ProtoElement,obj:any): + return [obj] if element.repeated else obj + def get_option(self,element:ProtoElement,optname:str): + options = element.options.get('cust_field',dict()) + msg_options = element.options.get('cust_msg',dict()) + return getattr(options,optname,None) or getattr(msg_options,optname,None) + def get_nanoppb_option(self,element:ProtoElement,optname:str): + options = element.options.get('nanopb_msgopt',dict()) + msg_options = element.options.get('nanopb',dict()) + return getattr(options,optname,None) or getattr(msg_options,optname,None) + def get_mkey(self,key)->list([str]): + if not self.all_members_defaults.get(key): + self.all_members_defaults[key] = list() + return self.all_members_defaults[key] + def append_line(self,key,line): + self.get_mkey(key).append(line) + + def get_member_assignment(self, element: ProtoElement, value) -> str: + member = "default_value." + cpptype = element.descriptor.cpp_type + + if cpptype == FieldDescriptor.CPPTYPE_ENUM: + member += f'v_enum = {element.cpp_type_member_prefix}_{value}' + elif cpptype == FieldDescriptor.CPPTYPE_INT32: + member += f'v_int32 = {value}' + elif cpptype == FieldDescriptor.CPPTYPE_INT64: + member += f'v_int64 = {value}' + elif cpptype == FieldDescriptor.CPPTYPE_UINT32: + member += f'v_uint32 = {value}' + elif cpptype == FieldDescriptor.CPPTYPE_UINT64: + member += f'v_uint64 = {value}' + elif cpptype == FieldDescriptor.CPPTYPE_DOUBLE: + member += f'v_double = {value}' + elif cpptype == FieldDescriptor.CPPTYPE_FLOAT: + member += f'v_float = {value}' + elif cpptype == FieldDescriptor.CPPTYPE_BOOL: + member += f'v_bool = {value}' + elif cpptype == FieldDescriptor.CPPTYPE_STRING: + member += f'v_string = {value}' + elif cpptype == FieldDescriptor.CPPTYPE_MESSAGE: + # Assuming value is a serialized string or similar + member += f'v_bytes = {value}' + else: + raise ValueError(f"Unsupported C++ type: {cpptype}") + + return member + + def render(self,element: ProtoElement) -> Dict: + result = {} + if len(element.childs)>0: + # oneof = getattr(element.descriptor,'containing_oneof',None) + # if oneof: + # result[f'__one_of_{element.name}'] = f'Choose only one structure for {oneof.full_name}' + for child in element.childs: + child.render() + + else: + options = element.options.get('cust_field',dict()) + nanopb_msgopt = element.options.get('',dict()) + nanopb = element.options.get('nanopb',dict()) + msg_options = element.options.get('cust_msg',dict()) + init_from_mac = getattr(options,'init_from_mac',False) or getattr(msg_options,'init_from_mac',False) + read_only = getattr(options,'read_only',False) or getattr(msg_options,'read_only',False) + default_value = getattr(options,'default_value',None) or getattr(msg_options,'default_value',None) + init_from_mac = self.get_option(element,'init_from_mac') or False + const_prefix = self.get_option(element,'const_prefix') or False + read_only = self.get_option(element,'read_only') or False + default_value = self.get_option(element,'default_value') or False + global_name = self.get_option(element,'global_name') or False + +# pb_size_t which_default_value; +# union { +# char *v_string; +# uint32_t v_uint32; +# int32_t v_int32; +# uint64_t v_uint64; +# int64_t v_int64; +# double v_double; +# float v_float; +# bool v_bool; +# int16_t v_enum; +# pb_bytes_array_t *v_bytes; +# } default_value; + + + if element.descriptor.cpp_type in [ FieldDescriptor.CPPTYPE_STRING ] and ( init_from_mac or const_prefix or read_only or default_value or global_name ): + + + + + + + + if not self.all_members_defaults.get(f'{PROCESSED_PREFIX}{element.cpp_type}'): + self.get_mkey(element.cpp_child).append(f'#define {element.cpp_type}_ALL_MEMBERS_CHILD(msg,member)') + self.get_mkey(element.cpp_root).append(f'#define {element.cpp_type}_ALL_MEMBERS_ROOT ') + c_source, c_header = self.get_source_names(Path(element.file.name).stem) + self.get_mkey(f'{element.cpp_type}_INCLUDES').append(f'#include "{c_header}"') + self.all_members_defaults[f'processed_{element.cpp_type}'] = True + + member_prefix = f'{element.cpp_type_member.replace(".","_")}_OPTIONS' + init_from_mac_str = 'true' if init_from_mac else 'false' + const_prefix_str = f'"{const_prefix}"' if const_prefix else '""' + read_only_str = "true" if read_only else "false" + default_value_str = f'"{default_value}"' if default_value else '""' + global_name_str = f'"{global_name}"' if global_name else '""' + opt_member = 'STRING_ARRAY' if self.get_nanoppb_option(element,'max_length') >0 else 'STRING_POINTER' + opt_member_type = opt_member + '_MEMBER' + + self.get_mkey(element.cpp_type).append(f'#define {member_prefix} {opt_member_type}({init_from_mac_str}, {const_prefix_str}, {read_only_str}, {default_value_str}, {global_name_str})') + if element.detached_leading_comments: + logger.debug(f'{element.detached_leading_comments}') + logger.info(f'INITFROMMAC: {self.global_name}{element.path}') + self.get_mkey(element.cpp_child).append(f'{opt_member}(msg, member.{element.cpp_member},{opt_member_type}) ') + self.get_mkey(element.cpp_root).append(f'{opt_member}({element.cpp_type},{element.cpp_member},{opt_member_type})') + + + return self.repeated_render(element,result) + + def add_file(self,name:str,stream:io.StringIO): + if stream and not stream.closed: + f = self.response.file.add() + f.name = name + f.content = stream.getvalue() + stream.close() + def get_source_names(self,name)->(str,str): + csource_name = f'{name}{file_suffix}' + return (f'{csource_name}.c',f'{csource_name}.h') + + def set_source(self,name): + if hasattr(self,"c_source"): + self.add_file(self.c_source_name,self.c_source) + self.add_file(self.c_header_name,self.c_header) + if name: + self.c_source_name,self.c_header_name = self.get_source_names(name) + + + + self.c_header = io.StringIO() + self.c_header.write(head_comments) + self.c_header.write(f'#pragma once\n') + self.c_header.write(f'#include "sys_options.h"\n') + self.c_header.write(f'#include "configuration.pb.h"\n') + self.c_source = io.StringIO() + self.c_source.write(head_comments) + self.c_source.write(f'#include "{self.c_header_name}"\n') +if __name__ == '__main__': + data = ProtocParser.get_data() + logger.info(f"Generating c source file(s) for options") + protocParser:OptionsParser = OptionsParser(data) + protocParser.process() + logger.info('Done generating c source file(s) for options') diff --git a/tools/protodot b/tools/protodot new file mode 160000 index 00000000..0ff55f38 --- /dev/null +++ b/tools/protodot @@ -0,0 +1 @@ +Subproject commit 0ff55f3828fa5da04814db8f03c6e54cdbcb810c diff --git a/tools/spiffs b/tools/spiffs new file mode 100644 index 00000000..4c7073ca Binary files /dev/null and b/tools/spiffs differ