From 84b5d9b21c90f8e38e360762b4368bbf8b29e511 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Mon, 22 Dec 2025 14:00:12 -0500 Subject: [PATCH 001/302] [core] Remove deprecated config options from before 2025 (#12622) Co-authored-by: Claude --- esphome/components/bedjet/climate/__init__.py | 25 ++----------------- esphome/components/bh1750/sensor.py | 10 -------- esphome/components/ethernet/__init__.py | 4 --- esphome/components/i2c/__init__.py | 4 --- esphome/components/remote_base/__init__.py | 15 +---------- esphome/components/sensor/__init__.py | 3 --- esphome/components/tca9548a/__init__.py | 3 +-- .../components/template/switch/__init__.py | 4 --- esphome/components/tuya/light/__init__.py | 6 ----- esphome/components/uart/__init__.py | 4 --- esphome/components/wifi/__init__.py | 4 --- 11 files changed, 4 insertions(+), 78 deletions(-) diff --git a/esphome/components/bedjet/climate/__init__.py b/esphome/components/bedjet/climate/__init__.py index 0da2107d43..4de9dcca0b 100644 --- a/esphome/components/bedjet/climate/__init__.py +++ b/esphome/components/bedjet/climate/__init__.py @@ -1,12 +1,7 @@ import esphome.codegen as cg -from esphome.components import ble_client, climate +from esphome.components import climate import esphome.config_validation as cv -from esphome.const import ( - CONF_HEAT_MODE, - CONF_RECEIVE_TIMEOUT, - CONF_TEMPERATURE_SOURCE, - CONF_TIME_ID, -) +from esphome.const import CONF_HEAT_MODE, CONF_TEMPERATURE_SOURCE from .. import BEDJET_CLIENT_SCHEMA, bedjet_ns, register_bedjet_child @@ -38,22 +33,6 @@ CONFIG_SCHEMA = ( } ) .extend(cv.polling_component_schema("60s")) - .extend( - # TODO: remove compat layer. - { - cv.Optional(ble_client.CONF_BLE_CLIENT_ID): cv.invalid( - "The 'ble_client_id' option has been removed. Please migrate " - "to the new `bedjet_id` option in the `bedjet` component.\n" - "See https://esphome.io/components/climate/bedjet/" - ), - cv.Optional(CONF_TIME_ID): cv.invalid( - "The 'time_id' option has been moved to the `bedjet` component." - ), - cv.Optional(CONF_RECEIVE_TIMEOUT): cv.invalid( - "The 'receive_timeout' option has been moved to the `bedjet` component." - ), - } - ) .extend(BEDJET_CLIENT_SCHEMA) ) diff --git a/esphome/components/bh1750/sensor.py b/esphome/components/bh1750/sensor.py index 7c7eecb88c..36af5aeef9 100644 --- a/esphome/components/bh1750/sensor.py +++ b/esphome/components/bh1750/sensor.py @@ -20,16 +20,6 @@ CONFIG_SCHEMA = ( device_class=DEVICE_CLASS_ILLUMINANCE, state_class=STATE_CLASS_MEASUREMENT, ) - .extend( - { - cv.Optional("resolution"): cv.invalid( - "The 'resolution' option has been removed. The optimal value is now dynamically calculated." - ), - cv.Optional("measurement_duration"): cv.invalid( - "The 'measurement_duration' option has been removed. The optimal value is now dynamically calculated." - ), - } - ) .extend(cv.polling_component_schema("60s")) .extend(i2c.i2c_device_schema(0x23)) ) diff --git a/esphome/components/ethernet/__init__.py b/esphome/components/ethernet/__init__.py index e1ed327fb9..f140f395e4 100644 --- a/esphome/components/ethernet/__init__.py +++ b/esphome/components/ethernet/__init__.py @@ -220,10 +220,6 @@ BASE_SCHEMA = cv.Schema( cv.Optional(CONF_MANUAL_IP): MANUAL_IP_SCHEMA, cv.Optional(CONF_DOMAIN, default=".local"): cv.domain_name, cv.Optional(CONF_USE_ADDRESS): cv.string_strict, - cv.Optional("enable_mdns"): cv.invalid( - "This option has been removed. Please use the [disabled] option under the " - "new mdns component instead." - ), cv.Optional(CONF_MAC_ADDRESS): cv.mac_address, } ).extend(cv.COMPONENT_SCHEMA) diff --git a/esphome/components/i2c/__init__.py b/esphome/components/i2c/__init__.py index 7706484e97..b7436ccc39 100644 --- a/esphome/components/i2c/__init__.py +++ b/esphome/components/i2c/__init__.py @@ -237,10 +237,6 @@ def i2c_device_schema(default_address): """ schema = { cv.GenerateID(CONF_I2C_ID): cv.use_id(I2CBus), - cv.Optional("multiplexer"): cv.invalid( - "This option has been removed, please see " - "the tca9584a docs for the updated way to use multiplexers" - ), } if default_address is None: schema[cv.Required(CONF_ADDRESS)] = cv.i2c_address diff --git a/esphome/components/remote_base/__init__.py b/esphome/components/remote_base/__init__.py index d24d24b000..9d3e655c57 100644 --- a/esphome/components/remote_base/__init__.py +++ b/esphome/components/remote_base/__init__.py @@ -108,9 +108,6 @@ def register_trigger(name, type, data_type): validator = automation.validate_automation( { cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(type), - cv.Optional(CONF_RECEIVER_ID): cv.invalid( - "This has been removed in ESPHome 2022.3.0 and the trigger attaches directly to the parent receiver." - ), } ) registerer = TRIGGER_REGISTRY.register(f"on_{name}", validator) @@ -207,13 +204,7 @@ validate_binary_sensor = cv.validate_registry_entry( "remote receiver", BINARY_SENSOR_REGISTRY ) TRIGGER_REGISTRY = SimpleRegistry() -DUMPER_REGISTRY = Registry( - { - cv.Optional(CONF_RECEIVER_ID): cv.invalid( - "This has been removed in ESPHome 1.20.0 and the dumper attaches directly to the parent receiver." - ), - } -) +DUMPER_REGISTRY = Registry() def validate_dumpers(value): @@ -480,10 +471,6 @@ COOLIX_BASE_SCHEMA = cv.Schema( { cv.Required(CONF_FIRST): cv.hex_int_range(0, 16777215), cv.Optional(CONF_SECOND, default=0): cv.hex_int_range(0, 16777215), - cv.Optional(CONF_DATA): cv.invalid( - "'data' option has been removed in ESPHome 2023.8. " - "Use the 'first' and 'second' options instead." - ), } ) diff --git a/esphome/components/sensor/__init__.py b/esphome/components/sensor/__init__.py index 027d9a69b8..83b2656661 100644 --- a/esphome/components/sensor/__init__.py +++ b/esphome/components/sensor/__init__.py @@ -304,9 +304,6 @@ _SENSOR_SCHEMA = ( cv.Optional(CONF_DEVICE_CLASS): validate_device_class, cv.Optional(CONF_STATE_CLASS): validate_state_class, cv.Optional(CONF_ENTITY_CATEGORY): sensor_entity_category, - cv.Optional("last_reset_type"): cv.invalid( - "last_reset_type has been removed since 2021.9.0. state_class: total_increasing should be used for total values." - ), cv.Optional(CONF_FORCE_UPDATE, default=False): cv.boolean, cv.Optional(CONF_EXPIRE_AFTER): cv.All( cv.requires_component("mqtt"), diff --git a/esphome/components/tca9548a/__init__.py b/esphome/components/tca9548a/__init__.py index cef779de2e..72973a54ad 100644 --- a/esphome/components/tca9548a/__init__.py +++ b/esphome/components/tca9548a/__init__.py @@ -1,7 +1,7 @@ import esphome.codegen as cg from esphome.components import i2c import esphome.config_validation as cv -from esphome.const import CONF_CHANNEL, CONF_CHANNELS, CONF_ID, CONF_SCAN +from esphome.const import CONF_CHANNEL, CONF_CHANNELS, CONF_ID CODEOWNERS = ["@andreashergert1984"] @@ -18,7 +18,6 @@ CONFIG_SCHEMA = ( cv.Schema( { cv.GenerateID(): cv.declare_id(TCA9548AComponent), - cv.Optional(CONF_SCAN): cv.invalid("This option has been removed"), cv.Optional(CONF_CHANNELS, default=[]): cv.ensure_list( { cv.Required(CONF_BUS_ID): cv.declare_id(TCA9548AChannel), diff --git a/esphome/components/template/switch/__init__.py b/esphome/components/template/switch/__init__.py index e86657510f..8ae5a07dc3 100644 --- a/esphome/components/template/switch/__init__.py +++ b/esphome/components/template/switch/__init__.py @@ -7,7 +7,6 @@ from esphome.const import ( CONF_ID, CONF_LAMBDA, CONF_OPTIMISTIC, - CONF_RESTORE_STATE, CONF_STATE, CONF_TURN_OFF_ACTION, CONF_TURN_ON_ACTION, @@ -44,9 +43,6 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_TURN_ON_ACTION): automation.validate_automation( single=True ), - cv.Optional(CONF_RESTORE_STATE): cv.invalid( - "The restore_state option has been removed in 2023.7.0. Use the restore_mode option instead" - ), } ) .extend(cv.COMPONENT_SCHEMA), diff --git a/esphome/components/tuya/light/__init__.py b/esphome/components/tuya/light/__init__.py index 1d2286e3c7..4d2ccba8b1 100644 --- a/esphome/components/tuya/light/__init__.py +++ b/esphome/components/tuya/light/__init__.py @@ -37,10 +37,6 @@ COLOR_TYPES = { TuyaLight = tuya_ns.class_("TuyaLight", light.LightOutput, cg.Component) -COLOR_CONFIG_ERROR = ( - "This option has been removed, use color_datapoint and color_type instead." -) - CONFIG_SCHEMA = cv.All( light.BRIGHTNESS_ONLY_LIGHT_SCHEMA.extend( { @@ -49,8 +45,6 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_DIMMER_DATAPOINT): cv.uint8_t, cv.Optional(CONF_MIN_VALUE_DATAPOINT): cv.uint8_t, cv.Optional(CONF_SWITCH_DATAPOINT): cv.uint8_t, - cv.Optional(CONF_RGB_DATAPOINT): cv.invalid(COLOR_CONFIG_ERROR), - cv.Optional(CONF_HSV_DATAPOINT): cv.invalid(COLOR_CONFIG_ERROR), cv.Inclusive(CONF_COLOR_DATAPOINT, "color"): cv.uint8_t, cv.Inclusive(CONF_COLOR_TYPE, "color"): cv.enum(COLOR_TYPES, upper=True), cv.Optional(CONF_COLOR_INTERLOCK, default=False): cv.boolean, diff --git a/esphome/components/uart/__init__.py b/esphome/components/uart/__init__.py index 6494aaa286..9baa6ebd81 100644 --- a/esphome/components/uart/__init__.py +++ b/esphome/components/uart/__init__.py @@ -19,7 +19,6 @@ from esphome.const import ( CONF_DUMMY_RECEIVER_ID, CONF_FLOW_CONTROL_PIN, CONF_ID, - CONF_INVERT, CONF_LAMBDA, CONF_NUMBER, CONF_PORT, @@ -304,9 +303,6 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_PARITY, default="NONE"): cv.enum( UART_PARITY_OPTIONS, upper=True ), - cv.Optional(CONF_INVERT): cv.invalid( - "This option has been removed. Please instead use invert in the tx/rx pin schemas." - ), cv.Optional(CONF_DEBUG): maybe_empty_debug, } ).extend(cv.COMPONENT_SCHEMA), diff --git a/esphome/components/wifi/__init__.py b/esphome/components/wifi/__init__.py index 2c10506011..fb23837e78 100644 --- a/esphome/components/wifi/__init__.py +++ b/esphome/components/wifi/__init__.py @@ -348,10 +348,6 @@ CONFIG_SCHEMA = cv.All( cv.boolean, cv.only_on_esp32 ), cv.Optional(CONF_PASSIVE_SCAN, default=False): cv.boolean, - cv.Optional("enable_mdns"): cv.invalid( - "This option has been removed. Please use the [disabled] option under the " - "new mdns component instead." - ), cv.Optional(CONF_ENABLE_ON_BOOT, default=True): cv.boolean, cv.Optional(CONF_ON_CONNECT): automation.validate_automation(single=True), cv.Optional(CONF_ON_DISCONNECT): automation.validate_automation( From cd45fe0c3a72eeeb474e8c748c3dc7368288f38c Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Mon, 22 Dec 2025 13:13:03 -0600 Subject: [PATCH 002/302] [thermostat] Optimizations to reduce binary size (#12621) --- .../thermostat/thermostat_climate.cpp | 54 +++++++++++++++---- .../thermostat/thermostat_climate.h | 29 +++------- 2 files changed, 52 insertions(+), 31 deletions(-) diff --git a/esphome/components/thermostat/thermostat_climate.cpp b/esphome/components/thermostat/thermostat_climate.cpp index e588407c4a..d5fb259dad 100644 --- a/esphome/components/thermostat/thermostat_climate.cpp +++ b/esphome/components/thermostat/thermostat_climate.cpp @@ -3,8 +3,7 @@ #include "esphome/core/helpers.h" #include "esphome/core/log.h" -namespace esphome { -namespace thermostat { +namespace esphome::thermostat { static const char *const TAG = "thermostat.climate"; @@ -66,10 +65,12 @@ void ThermostatClimate::setup() { } void ThermostatClimate::loop() { - for (auto &timer : this->timer_) { - if (timer.active && (timer.started + timer.time < App.get_loop_component_start_time())) { + uint32_t now = App.get_loop_component_start_time(); + for (uint8_t i = 0; i < THERMOSTAT_TIMER_COUNT; i++) { + auto &timer = this->timer_[i]; + if (timer.active && (now - timer.started >= timer.time)) { timer.active = false; - timer.func(); + this->call_timer_callback_(static_cast(i)); } } } @@ -916,8 +917,42 @@ uint32_t ThermostatClimate::timer_duration_(ThermostatClimateTimerIndex timer_in return this->timer_[timer_index].time; } -std::function ThermostatClimate::timer_cbf_(ThermostatClimateTimerIndex timer_index) { - return this->timer_[timer_index].func; +void ThermostatClimate::call_timer_callback_(ThermostatClimateTimerIndex timer_index) { + switch (timer_index) { + case THERMOSTAT_TIMER_COOLING_MAX_RUN_TIME: + this->cooling_max_run_time_timer_callback_(); + break; + case THERMOSTAT_TIMER_COOLING_OFF: + this->cooling_off_timer_callback_(); + break; + case THERMOSTAT_TIMER_COOLING_ON: + this->cooling_on_timer_callback_(); + break; + case THERMOSTAT_TIMER_FAN_MODE: + this->fan_mode_timer_callback_(); + break; + case THERMOSTAT_TIMER_FANNING_OFF: + this->fanning_off_timer_callback_(); + break; + case THERMOSTAT_TIMER_FANNING_ON: + this->fanning_on_timer_callback_(); + break; + case THERMOSTAT_TIMER_HEATING_MAX_RUN_TIME: + this->heating_max_run_time_timer_callback_(); + break; + case THERMOSTAT_TIMER_HEATING_OFF: + this->heating_off_timer_callback_(); + break; + case THERMOSTAT_TIMER_HEATING_ON: + this->heating_on_timer_callback_(); + break; + case THERMOSTAT_TIMER_IDLE_ON: + this->idle_on_timer_callback_(); + break; + case THERMOSTAT_TIMER_COUNT: + default: + break; + } } void ThermostatClimate::cooling_max_run_time_timer_callback_() { @@ -1344,7 +1379,7 @@ void ThermostatClimate::set_timer_duration_in_sec_(ThermostatClimateTimerIndex t ESP_LOGVV(TAG, "timer %d completing immediately (elapsed %d >= new %d)", timer_index, elapsed, new_duration_ms); this->timer_[timer_index].active = false; // Trigger the timer callback immediately - this->timer_[timer_index].func(); + this->call_timer_callback_(timer_index); return; } else { // Adjust timer to run for remaining time - keep original start time @@ -1672,5 +1707,4 @@ ThermostatClimateTargetTempConfig::ThermostatClimateTargetTempConfig(float defau float default_temperature_high) : default_temperature_low(default_temperature_low), default_temperature_high(default_temperature_high) {} -} // namespace thermostat -} // namespace esphome +} // namespace esphome::thermostat diff --git a/esphome/components/thermostat/thermostat_climate.h b/esphome/components/thermostat/thermostat_climate.h index 2443af58d6..564b6127b3 100644 --- a/esphome/components/thermostat/thermostat_climate.h +++ b/esphome/components/thermostat/thermostat_climate.h @@ -10,8 +10,7 @@ #include #include -namespace esphome { -namespace thermostat { +namespace esphome::thermostat { enum HumidificationAction : uint8_t { THERMOSTAT_HUMIDITY_CONTROL_ACTION_OFF = 0, @@ -41,13 +40,11 @@ enum OnBootRestoreFrom : uint8_t { struct ThermostatClimateTimer { ThermostatClimateTimer() = default; - ThermostatClimateTimer(bool active, uint32_t time, uint32_t started, std::function func) - : active(active), time(time), started(started), func(std::move(func)) {} + ThermostatClimateTimer(bool active, uint32_t time, uint32_t started) : active(active), time(time), started(started) {} bool active; uint32_t time; uint32_t started; - std::function func; }; struct ThermostatClimateTargetTempConfig { @@ -266,7 +263,8 @@ class ThermostatClimate : public climate::Climate, public Component { bool cancel_timer_(ThermostatClimateTimerIndex timer_index); bool timer_active_(ThermostatClimateTimerIndex timer_index); uint32_t timer_duration_(ThermostatClimateTimerIndex timer_index); - std::function timer_cbf_(ThermostatClimateTimerIndex timer_index); + /// Call the appropriate timer callback based on timer index + void call_timer_callback_(ThermostatClimateTimerIndex timer_index); /// Enhanced timer duration setter with running timer adjustment void set_timer_duration_in_sec_(ThermostatClimateTimerIndex timer_index, uint32_t time); @@ -534,27 +532,16 @@ class ThermostatClimate : public climate::Climate, public Component { Trigger<> *prev_humidity_control_trigger_{nullptr}; /// Climate action timers - std::array timer_{ - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::cooling_max_run_time_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::cooling_off_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::cooling_on_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::fan_mode_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::fanning_off_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::fanning_on_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::heating_max_run_time_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::heating_off_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::heating_on_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::idle_on_timer_callback_, this)), - }; + std::array timer_{}; /// The set of standard preset configurations this thermostat supports (Eg. AWAY, ECO, etc) FixedVector preset_config_{}; /// The set of custom preset configurations this thermostat supports (eg. "My Custom Preset") FixedVector custom_preset_config_{}; - /// Default custom preset to use on start up (pointer to entry in custom_preset_config_) + private: + /// Default custom preset to use on start up (pointer to entry in custom_preset_config_) const char *default_custom_preset_{nullptr}; }; -} // namespace thermostat -} // namespace esphome +} // namespace esphome::thermostat From 08c0f65f30e711e48b4af20d1ce77d2d7ca30b28 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Mon, 22 Dec 2025 13:13:18 -0600 Subject: [PATCH 003/302] [sprinkler] Remove internal latching valve support (#12603) --- esphome/components/sprinkler/__init__.py | 109 ++++-------- esphome/components/sprinkler/sprinkler.cpp | 195 +++++---------------- esphome/components/sprinkler/sprinkler.h | 51 +----- 3 files changed, 84 insertions(+), 271 deletions(-) diff --git a/esphome/components/sprinkler/__init__.py b/esphome/components/sprinkler/__init__.py index 2dccb6896a..50c69f9496 100644 --- a/esphome/components/sprinkler/__init__.py +++ b/esphome/components/sprinkler/__init__.py @@ -19,6 +19,7 @@ from esphome.const import ( UNIT_MINUTE, UNIT_SECOND, ) +from esphome.helpers import docs_url AUTO_LOAD = ["number", "switch"] CODEOWNERS = ["@kbx81"] @@ -162,55 +163,9 @@ def validate_sprinkler(config): raise cv.Invalid( f"{CONF_RUN_DURATION} must be greater than {CONF_VALVE_OPEN_DELAY}" ) - if ( - CONF_PUMP_OFF_SWITCH_ID in valve and CONF_PUMP_ON_SWITCH_ID not in valve - ) or ( - CONF_PUMP_ON_SWITCH_ID in valve and CONF_PUMP_OFF_SWITCH_ID not in valve - ): + if CONF_VALVE_SWITCH_ID not in valve: raise cv.Invalid( - f"Both {CONF_PUMP_OFF_SWITCH_ID} and {CONF_PUMP_ON_SWITCH_ID} must be specified for latching pump configuration" - ) - if CONF_PUMP_SWITCH_ID in valve and ( - CONF_PUMP_OFF_SWITCH_ID in valve or CONF_PUMP_ON_SWITCH_ID in valve - ): - raise cv.Invalid( - f"Do not specify {CONF_PUMP_OFF_SWITCH_ID} or {CONF_PUMP_ON_SWITCH_ID} when using {CONF_PUMP_SWITCH_ID}" - ) - if CONF_PUMP_PULSE_DURATION not in sprinkler_controller and ( - CONF_PUMP_OFF_SWITCH_ID in valve or CONF_PUMP_ON_SWITCH_ID in valve - ): - raise cv.Invalid( - f"{CONF_PUMP_PULSE_DURATION} must be specified when using {CONF_PUMP_OFF_SWITCH_ID} and {CONF_PUMP_ON_SWITCH_ID}" - ) - if ( - CONF_VALVE_OFF_SWITCH_ID in valve - and CONF_VALVE_ON_SWITCH_ID not in valve - ) or ( - CONF_VALVE_ON_SWITCH_ID in valve - and CONF_VALVE_OFF_SWITCH_ID not in valve - ): - raise cv.Invalid( - f"Both {CONF_VALVE_OFF_SWITCH_ID} and {CONF_VALVE_ON_SWITCH_ID} must be specified for latching valve configuration" - ) - if CONF_VALVE_SWITCH_ID in valve and ( - CONF_VALVE_OFF_SWITCH_ID in valve or CONF_VALVE_ON_SWITCH_ID in valve - ): - raise cv.Invalid( - f"Do not specify {CONF_VALVE_OFF_SWITCH_ID} or {CONF_VALVE_ON_SWITCH_ID} when using {CONF_VALVE_SWITCH_ID}" - ) - if CONF_VALVE_PULSE_DURATION not in sprinkler_controller and ( - CONF_VALVE_OFF_SWITCH_ID in valve or CONF_VALVE_ON_SWITCH_ID in valve - ): - raise cv.Invalid( - f"{CONF_VALVE_PULSE_DURATION} must be specified when using {CONF_VALVE_OFF_SWITCH_ID} and {CONF_VALVE_ON_SWITCH_ID}" - ) - if ( - CONF_VALVE_SWITCH_ID not in valve - and CONF_VALVE_OFF_SWITCH_ID not in valve - and CONF_VALVE_ON_SWITCH_ID not in valve - ): - raise cv.Invalid( - f"Either {CONF_VALVE_SWITCH_ID} or {CONF_VALVE_OFF_SWITCH_ID} and {CONF_VALVE_ON_SWITCH_ID} must be specified in valve configuration" + f"{CONF_VALVE_SWITCH_ID} must be specified in valve configuration" ) if CONF_RUN_DURATION not in valve and CONF_RUN_DURATION_NUMBER not in valve: raise cv.Invalid( @@ -290,8 +245,15 @@ SPRINKLER_VALVE_SCHEMA = cv.Schema( ), key=CONF_NAME, ), - cv.Optional(CONF_PUMP_OFF_SWITCH_ID): cv.use_id(switch.Switch), - cv.Optional(CONF_PUMP_ON_SWITCH_ID): cv.use_id(switch.Switch), + # Removed latching pump keys - accepted for validation error reporting + cv.Optional(CONF_PUMP_OFF_SWITCH_ID): cv.invalid( + f"This option was removed in 2026.1.0; for latching pumps, use {CONF_PUMP_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), + cv.Optional(CONF_PUMP_ON_SWITCH_ID): cv.invalid( + f"This option was removed in 2026.1.0; for latching pumps, use {CONF_PUMP_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), cv.Optional(CONF_PUMP_SWITCH_ID): cv.use_id(switch.Switch), cv.Optional(CONF_RUN_DURATION): cv.positive_time_period_seconds, cv.Optional(CONF_RUN_DURATION_NUMBER): cv.maybe_simple_value( @@ -321,8 +283,15 @@ SPRINKLER_VALVE_SCHEMA = cv.Schema( switch.switch_schema(SprinklerControllerSwitch), key=CONF_NAME, ), - cv.Optional(CONF_VALVE_OFF_SWITCH_ID): cv.use_id(switch.Switch), - cv.Optional(CONF_VALVE_ON_SWITCH_ID): cv.use_id(switch.Switch), + # Removed latching valve keys - accepted for validation error reporting + cv.Optional(CONF_VALVE_OFF_SWITCH_ID): cv.invalid( + f"This option was removed in 2026.1.0; for latching valves, use {CONF_VALVE_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), + cv.Optional(CONF_VALVE_ON_SWITCH_ID): cv.invalid( + f"This option was removed in 2026.1.0; for latching valves, use {CONF_VALVE_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), cv.Optional(CONF_VALVE_SWITCH_ID): cv.use_id(switch.Switch), } ) @@ -410,8 +379,15 @@ SPRINKLER_CONTROLLER_SCHEMA = cv.Schema( validate_min_max, key=CONF_NAME, ), - cv.Optional(CONF_PUMP_PULSE_DURATION): cv.positive_time_period_milliseconds, - cv.Optional(CONF_VALVE_PULSE_DURATION): cv.positive_time_period_milliseconds, + # Removed latching valve keys - accepted for validation error reporting + cv.Optional(CONF_PUMP_PULSE_DURATION): cv.invalid( + f"This option was removed in 2026.1.0; for latching pumps, use {CONF_PUMP_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), + cv.Optional(CONF_VALVE_PULSE_DURATION): cv.invalid( + f"This option was removed in 2026.1.0; for latching valves, use {CONF_VALVE_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), cv.Exclusive( CONF_PUMP_START_PUMP_DELAY, "pump_start_xxxx_delay" ): cv.positive_time_period_seconds, @@ -765,35 +741,10 @@ async def to_code(config): valve_index, valve_switch, valve[CONF_RUN_DURATION] ) ) - elif CONF_VALVE_OFF_SWITCH_ID in valve and CONF_VALVE_ON_SWITCH_ID in valve: - valve_switch_off = await cg.get_variable( - valve[CONF_VALVE_OFF_SWITCH_ID] - ) - valve_switch_on = await cg.get_variable(valve[CONF_VALVE_ON_SWITCH_ID]) - cg.add( - var.configure_valve_switch_pulsed( - valve_index, - valve_switch_off, - valve_switch_on, - sprinkler_controller[CONF_VALVE_PULSE_DURATION], - valve[CONF_RUN_DURATION], - ) - ) if CONF_PUMP_SWITCH_ID in valve: pump = await cg.get_variable(valve[CONF_PUMP_SWITCH_ID]) cg.add(var.configure_valve_pump_switch(valve_index, pump)) - elif CONF_PUMP_OFF_SWITCH_ID in valve and CONF_PUMP_ON_SWITCH_ID in valve: - pump_off = await cg.get_variable(valve[CONF_PUMP_OFF_SWITCH_ID]) - pump_on = await cg.get_variable(valve[CONF_PUMP_ON_SWITCH_ID]) - cg.add( - var.configure_valve_pump_switch_pulsed( - valve_index, - pump_off, - pump_on, - sprinkler_controller[CONF_PUMP_PULSE_DURATION], - ) - ) if CONF_RUN_DURATION_NUMBER in valve: num_rd_var = await number.new_number( diff --git a/esphome/components/sprinkler/sprinkler.cpp b/esphome/components/sprinkler/sprinkler.cpp index 69452f2e9e..ca9f85abd8 100644 --- a/esphome/components/sprinkler/sprinkler.cpp +++ b/esphome/components/sprinkler/sprinkler.cpp @@ -11,70 +11,6 @@ namespace esphome::sprinkler { static const char *const TAG = "sprinkler"; -SprinklerSwitch::SprinklerSwitch() {} -SprinklerSwitch::SprinklerSwitch(switch_::Switch *sprinkler_switch) : on_switch_(sprinkler_switch) {} -SprinklerSwitch::SprinklerSwitch(switch_::Switch *off_switch, switch_::Switch *on_switch, uint32_t pulse_duration) - : pulse_duration_(pulse_duration), off_switch_(off_switch), on_switch_(on_switch) {} - -bool SprinklerSwitch::is_latching_valve() { return (this->off_switch_ != nullptr) && (this->on_switch_ != nullptr); } - -void SprinklerSwitch::loop() { - if ((this->pinned_millis_) && (App.get_loop_component_start_time() > this->pinned_millis_ + this->pulse_duration_)) { - this->pinned_millis_ = 0; // reset tracker - if (this->off_switch_->state) { - this->off_switch_->turn_off(); - } - if (this->on_switch_->state) { - this->on_switch_->turn_off(); - } - } -} - -void SprinklerSwitch::turn_off() { - if (!this->state()) { // do nothing if we're already in the requested state - return; - } - if (this->off_switch_ != nullptr) { // latching valve, start a pulse - if (!this->off_switch_->state) { - this->off_switch_->turn_on(); - } - this->pinned_millis_ = millis(); - } else if (this->on_switch_ != nullptr) { // non-latching valve - this->on_switch_->turn_off(); - } - this->state_ = false; -} - -void SprinklerSwitch::turn_on() { - if (this->state()) { // do nothing if we're already in the requested state - return; - } - if (this->off_switch_ != nullptr) { // latching valve, start a pulse - if (!this->on_switch_->state) { - this->on_switch_->turn_on(); - } - this->pinned_millis_ = millis(); - } else if (this->on_switch_ != nullptr) { // non-latching valve - this->on_switch_->turn_on(); - } - this->state_ = true; -} - -bool SprinklerSwitch::state() { - if ((this->off_switch_ == nullptr) && (this->on_switch_ != nullptr)) { // latching valve is not configured... - return this->on_switch_->state; // ...so just return the pump switch state - } - return this->state_; -} - -void SprinklerSwitch::sync_valve_state(bool latch_state) { - if (this->is_latching_valve()) { - this->state_ = latch_state; - } else if (this->on_switch_ != nullptr) { - this->state_ = this->on_switch_->state; - } -} - void SprinklerControllerNumber::setup() { float value; if (!this->restore_value_) { @@ -219,8 +155,8 @@ void SprinklerValveOperator::start() { this->state_ = STARTING; // STARTING state requires both a pump and a start_delay_ if (this->start_delay_is_valve_delay_) { this->pump_on_(); - } else if (!this->pump_switch()->state()) { // if the pump is already on, wait to switch on the valve - this->valve_on_(); // to ensure consistent run time + } else if (!this->pump_switch()->state) { // if the pump is already on, wait to switch on the valve + this->valve_on_(); // to ensure consistent run time } } else { this->run_(); // there is no start_delay_, so just start the pump and valve @@ -240,8 +176,8 @@ void SprinklerValveOperator::stop() { } else { this->valve_off_(); } - if (this->pump_switch()->state()) { // if the pump is still on at this point, it may be in use... - this->valve_off_(); // ...so just switch the valve off now to ensure consistent run time + if (this->pump_switch()->state) { // if the pump is still on at this point, it may be in use... + this->valve_off_(); // ...so just switch the valve off now to ensure consistent run time } } else { this->kill_(); // there is no stop_delay_, so just stop the pump and valve @@ -274,7 +210,7 @@ uint32_t SprinklerValveOperator::time_remaining() { SprinklerState SprinklerValveOperator::state() { return this->state_; } -SprinklerSwitch *SprinklerValveOperator::pump_switch() { +switch_::Switch *SprinklerValveOperator::pump_switch() { if ((this->controller_ == nullptr) || (this->valve_ == nullptr)) { return nullptr; } @@ -285,48 +221,50 @@ SprinklerSwitch *SprinklerValveOperator::pump_switch() { } void SprinklerValveOperator::pump_off_() { - if ((this->valve_ == nullptr) || (this->pump_switch() == nullptr)) { // safety first! + auto *pump = this->pump_switch(); + if ((this->valve_ == nullptr) || (pump == nullptr)) { // safety first! return; } if (this->controller_ == nullptr) { // safety first! - this->pump_switch()->turn_off(); // if no controller was set, just switch off the pump + pump->turn_off(); // if no controller was set, just switch off the pump } else { // ...otherwise, do it "safely" auto state = this->state_; // this is silly, but... this->state_ = BYPASS; // ...exclude me from the pump-in-use check that set_pump_state() does - this->controller_->set_pump_state(this->pump_switch(), false); + this->controller_->set_pump_state(pump, false); this->state_ = state; } } void SprinklerValveOperator::pump_on_() { - if ((this->valve_ == nullptr) || (this->pump_switch() == nullptr)) { // safety first! + auto *pump = this->pump_switch(); + if ((this->valve_ == nullptr) || (pump == nullptr)) { // safety first! return; } if (this->controller_ == nullptr) { // safety first! - this->pump_switch()->turn_on(); // if no controller was set, just switch on the pump + pump->turn_on(); // if no controller was set, just switch on the pump } else { // ...otherwise, do it "safely" auto state = this->state_; // this is silly, but... this->state_ = BYPASS; // ...exclude me from the pump-in-use check that set_pump_state() does - this->controller_->set_pump_state(this->pump_switch(), true); + this->controller_->set_pump_state(pump, true); this->state_ = state; } } void SprinklerValveOperator::valve_off_() { - if (this->valve_ == nullptr) { // safety first! + if ((this->valve_ == nullptr) || (this->valve_->valve_switch == nullptr)) { // safety first! return; } - if (this->valve_->valve_switch.state()) { - this->valve_->valve_switch.turn_off(); + if (this->valve_->valve_switch->state) { + this->valve_->valve_switch->turn_off(); } } void SprinklerValveOperator::valve_on_() { - if (this->valve_ == nullptr) { // safety first! + if ((this->valve_ == nullptr) || (this->valve_->valve_switch == nullptr)) { // safety first! return; } - if (!this->valve_->valve_switch.state()) { - this->valve_->valve_switch.turn_on(); + if (!this->valve_->valve_switch->state) { + this->valve_->valve_switch->turn_on(); } } @@ -401,12 +339,6 @@ Sprinkler::Sprinkler(const std::string &name) { void Sprinkler::setup() { this->all_valves_off_(true); } void Sprinkler::loop() { - for (auto &p : this->pump_) { - p.loop(); - } - for (auto &v : this->valve_) { - v.valve_switch.loop(); - } for (auto &vo : this->valve_op_) { vo.loop(); } @@ -423,10 +355,15 @@ void Sprinkler::add_valve(SprinklerControllerSwitch *valve_sw, SprinklerControll new_valve->controller_switch = valve_sw; new_valve->controller_switch->set_state_lambda([this, new_valve_number]() -> optional { - if (this->valve_pump_switch(new_valve_number) != nullptr) { - return this->valve_switch(new_valve_number)->state() && this->valve_pump_switch(new_valve_number)->state(); + auto *valve = this->valve_switch(new_valve_number); + auto *pump = this->valve_pump_switch(new_valve_number); + if (valve == nullptr) { + return false; } - return this->valve_switch(new_valve_number)->state(); + if (pump != nullptr) { + return valve->state && pump->state; + } + return valve->state; }); new_valve->valve_turn_off_automation = @@ -496,18 +433,7 @@ void Sprinkler::set_controller_repeat_number(SprinklerControllerNumber *repeat_n void Sprinkler::configure_valve_switch(size_t valve_number, switch_::Switch *valve_switch, uint32_t run_duration) { if (this->is_a_valid_valve(valve_number)) { - this->valve_[valve_number].valve_switch.set_on_switch(valve_switch); - this->valve_[valve_number].run_duration = run_duration; - } -} - -void Sprinkler::configure_valve_switch_pulsed(size_t valve_number, switch_::Switch *valve_switch_off, - switch_::Switch *valve_switch_on, uint32_t pulse_duration, - uint32_t run_duration) { - if (this->is_a_valid_valve(valve_number)) { - this->valve_[valve_number].valve_switch.set_off_switch(valve_switch_off); - this->valve_[valve_number].valve_switch.set_on_switch(valve_switch_on); - this->valve_[valve_number].valve_switch.set_pulse_duration(pulse_duration); + this->valve_[valve_number].valve_switch = valve_switch; this->valve_[valve_number].run_duration = run_duration; } } @@ -515,31 +441,12 @@ void Sprinkler::configure_valve_switch_pulsed(size_t valve_number, switch_::Swit void Sprinkler::configure_valve_pump_switch(size_t valve_number, switch_::Switch *pump_switch) { if (this->is_a_valid_valve(valve_number)) { for (size_t i = 0; i < this->pump_.size(); i++) { // check each existing registered pump - if (this->pump_[i].on_switch() == pump_switch) { // if the "new" pump matches one we already have... - this->valve_[valve_number].pump_switch_index = i; // ...save its index in the SprinklerSwitch vector pump_... + if (this->pump_[i] == pump_switch) { // if the "new" pump matches one we already have... + this->valve_[valve_number].pump_switch_index = i; // ...save its index in the pump vector... return; // ...and we are done } - } // if we end up here, no pumps matched, so add a new one and set the valve's SprinklerSwitch at it - this->pump_.resize(this->pump_.size() + 1); - this->pump_.back().set_on_switch(pump_switch); - this->valve_[valve_number].pump_switch_index = this->pump_.size() - 1; // save the index to the new pump - } -} - -void Sprinkler::configure_valve_pump_switch_pulsed(size_t valve_number, switch_::Switch *pump_switch_off, - switch_::Switch *pump_switch_on, uint32_t pulse_duration) { - if (this->is_a_valid_valve(valve_number)) { - for (size_t i = 0; i < this->pump_.size(); i++) { // check each existing registered pump - if ((this->pump_[i].off_switch() == pump_switch_off) && - (this->pump_[i].on_switch() == pump_switch_on)) { // if the "new" pump matches one we already have... - this->valve_[valve_number].pump_switch_index = i; // ...save its index in the SprinklerSwitch vector pump_... - return; // ...and we are done - } - } // if we end up here, no pumps matched, so add a new one and set the valve's SprinklerSwitch at it - this->pump_.resize(this->pump_.size() + 1); - this->pump_.back().set_off_switch(pump_switch_off); - this->pump_.back().set_on_switch(pump_switch_on); - this->pump_.back().set_pulse_duration(pulse_duration); + } // if we end up here, no pumps matched, so add a new one + this->pump_.push_back(pump_switch); this->valve_[valve_number].pump_switch_index = this->pump_.size() - 1; // save the index to the new pump } } @@ -1041,7 +948,7 @@ size_t Sprinkler::number_of_valves() { return this->valve_.size(); } bool Sprinkler::is_a_valid_valve(const size_t valve_number) { return (valve_number < this->number_of_valves()); } -bool Sprinkler::pump_in_use(SprinklerSwitch *pump_switch) { +bool Sprinkler::pump_in_use(switch_::Switch *pump_switch) { if (pump_switch == nullptr) { return false; // we can't do anything if there's nothing to check } @@ -1054,8 +961,7 @@ bool Sprinkler::pump_in_use(SprinklerSwitch *pump_switch) { for (auto &vo : this->valve_op_) { // first, check if any SprinklerValveOperator has a valve dependent on this pump if ((vo.state() != BYPASS) && (vo.pump_switch() != nullptr)) { // the SprinklerValveOperator is configured with a pump; now check if it is the pump of interest - if ((vo.pump_switch()->off_switch() == pump_switch->off_switch()) && - (vo.pump_switch()->on_switch() == pump_switch->on_switch())) { + if (vo.pump_switch() == pump_switch) { // now if the SprinklerValveOperator has a pump and it is either ACTIVE, is STARTING with a valve delay or // is STOPPING with a valve delay, its pump can be considered "in use", so just return indicating this now if ((vo.state() == ACTIVE) || @@ -1074,13 +980,12 @@ bool Sprinkler::pump_in_use(SprinklerSwitch *pump_switch) { if (valve_pump == nullptr) { return false; // valve has no pump, so this pump isn't in use by it } - return (pump_switch->off_switch() == valve_pump->off_switch()) && - (pump_switch->on_switch() == valve_pump->on_switch()); + return pump_switch == valve_pump; } return false; } -void Sprinkler::set_pump_state(SprinklerSwitch *pump_switch, bool state) { +void Sprinkler::set_pump_state(switch_::Switch *pump_switch, bool state) { if (pump_switch == nullptr) { return; // we can't do anything if there's nothing to check } @@ -1091,15 +996,10 @@ void Sprinkler::set_pump_state(SprinklerSwitch *pump_switch, bool state) { if (controller != this) { // dummy check if (controller->pump_in_use(pump_switch)) { hold_pump_on = true; // if another controller says it's using this pump, keep it on - // at this point we know if there exists another SprinklerSwitch that is "on" with its - // off_switch_ and on_switch_ pointers pointing to the same pair of switch objects } } } if (hold_pump_on) { - // at this point we know if there exists another SprinklerSwitch that is "on" with its - // off_switch_ and on_switch_ pointers pointing to the same pair of switch objects... - pump_switch->sync_valve_state(true); // ...so ensure our state is consistent ESP_LOGD(TAG, "Leaving pump on because another controller instance is using it"); } @@ -1107,8 +1007,6 @@ void Sprinkler::set_pump_state(SprinklerSwitch *pump_switch, bool state) { pump_switch->turn_on(); } else if (!hold_pump_on && !this->pump_in_use(pump_switch)) { pump_switch->turn_off(); - } else if (hold_pump_on) { // we must assume the other controller will switch off the pump when done... - pump_switch->sync_valve_state(false); // ...this only impacts latching valves } } @@ -1274,23 +1172,23 @@ SprinklerControllerSwitch *Sprinkler::enable_switch(size_t valve_number) { return nullptr; } -SprinklerSwitch *Sprinkler::valve_switch(const size_t valve_number) { +switch_::Switch *Sprinkler::valve_switch(const size_t valve_number) { if (this->is_a_valid_valve(valve_number)) { - return &this->valve_[valve_number].valve_switch; + return this->valve_[valve_number].valve_switch; } return nullptr; } -SprinklerSwitch *Sprinkler::valve_pump_switch(const size_t valve_number) { +switch_::Switch *Sprinkler::valve_pump_switch(const size_t valve_number) { if (this->is_a_valid_valve(valve_number) && this->valve_[valve_number].pump_switch_index.has_value()) { - return &this->pump_[this->valve_[valve_number].pump_switch_index.value()]; + return this->pump_[this->valve_[valve_number].pump_switch_index.value()]; } return nullptr; } -SprinklerSwitch *Sprinkler::valve_pump_switch_by_pump_index(size_t pump_index) { +switch_::Switch *Sprinkler::valve_pump_switch_by_pump_index(size_t pump_index) { if (pump_index < this->pump_.size()) { - return &this->pump_[pump_index]; + return this->pump_[pump_index]; } return nullptr; } @@ -1454,8 +1352,9 @@ void Sprinkler::start_valve_(SprinklerValveRunRequest *req) { void Sprinkler::all_valves_off_(const bool include_pump) { for (size_t valve_index = 0; valve_index < this->number_of_valves(); valve_index++) { - if (this->valve_[valve_index].valve_switch.state()) { - this->valve_[valve_index].valve_switch.turn_off(); + auto *valve_sw = this->valve_[valve_index].valve_switch; + if ((valve_sw != nullptr) && valve_sw->state) { + valve_sw->turn_off(); } if (include_pump) { this->set_pump_state(this->valve_pump_switch(valve_index), false); @@ -1754,10 +1653,6 @@ void Sprinkler::dump_config() { " Name: %s\n" " Run Duration: %" PRIu32 " seconds", valve_number, this->valve_name(valve_number), this->valve_run_duration(valve_number)); - if (this->valve_[valve_number].valve_switch.pulse_duration()) { - ESP_LOGCONFIG(TAG, " Pulse Duration: %" PRIu32 " milliseconds", - this->valve_[valve_number].valve_switch.pulse_duration()); - } } if (!this->pump_.empty()) { ESP_LOGCONFIG(TAG, " Total number of pumps: %zu", this->pump_.size()); diff --git a/esphome/components/sprinkler/sprinkler.h b/esphome/components/sprinkler/sprinkler.h index 7aa33c2df9..25e2d42446 100644 --- a/esphome/components/sprinkler/sprinkler.h +++ b/esphome/components/sprinkler/sprinkler.h @@ -35,7 +35,6 @@ enum SprinklerValveRunRequestOrigin : uint8_t { class Sprinkler; // this component class SprinklerControllerNumber; // number components that appear in the front end; based on number core class SprinklerControllerSwitch; // switches that appear in the front end; based on switch core -class SprinklerSwitch; // switches representing any valve or pump; provides abstraction for latching valves class SprinklerValveOperator; // manages all switching on/off of valves and associated pumps class SprinklerValveRunRequest; // tells the sprinkler controller what valve to run and for how long as well as what // SprinklerValveOperator is handling it @@ -43,34 +42,6 @@ template class StartSingleValveAction; template class ShutdownAction; template class ResumeOrStartAction; -class SprinklerSwitch { - public: - SprinklerSwitch(); - SprinklerSwitch(switch_::Switch *sprinkler_switch); - SprinklerSwitch(switch_::Switch *off_switch, switch_::Switch *on_switch, uint32_t pulse_duration); - - bool is_latching_valve(); // returns true if configured as a latching valve - void loop(); // called as a part of loop(), used for latching valve pulses - uint32_t pulse_duration() { return this->pulse_duration_; } - bool state(); // returns the switch's current state - void set_off_switch(switch_::Switch *off_switch) { this->off_switch_ = off_switch; } - void set_on_switch(switch_::Switch *on_switch) { this->on_switch_ = on_switch; } - void set_pulse_duration(uint32_t pulse_duration) { this->pulse_duration_ = pulse_duration; } - void sync_valve_state( - bool latch_state); // syncs internal state to switch; if latching valve, sets state to latch_state - void turn_off(); // sets internal flag and actuates the switch - void turn_on(); // sets internal flag and actuates the switch - switch_::Switch *off_switch() { return this->off_switch_; } - switch_::Switch *on_switch() { return this->on_switch_; } - - protected: - bool state_{false}; - uint32_t pulse_duration_{0}; - uint64_t pinned_millis_{0}; - switch_::Switch *off_switch_{nullptr}; // only used for latching valves - switch_::Switch *on_switch_{nullptr}; // used for both latching and non-latching valves -}; - struct SprinklerQueueItem { size_t valve_number; uint32_t run_duration; @@ -88,7 +59,7 @@ struct SprinklerValve { SprinklerControllerNumber *run_duration_number; SprinklerControllerSwitch *controller_switch; SprinklerControllerSwitch *enable_switch; - SprinklerSwitch valve_switch; + switch_::Switch *valve_switch; uint32_t run_duration; optional pump_switch_index; bool valve_cycle_complete; @@ -155,7 +126,7 @@ class SprinklerValveOperator { uint32_t run_duration(); // returns the desired run duration in seconds uint32_t time_remaining(); // returns seconds remaining (does not include stop_delay_) SprinklerState state(); // returns the valve's state/status - SprinklerSwitch *pump_switch(); // returns this SprinklerValveOperator's pump's SprinklerSwitch + switch_::Switch *pump_switch(); // returns this SprinklerValveOperator's pump switch protected: void pump_off_(); @@ -228,13 +199,9 @@ class Sprinkler : public Component { /// configure a valve's switch object and run duration. run_duration is time in seconds. void configure_valve_switch(size_t valve_number, switch_::Switch *valve_switch, uint32_t run_duration); - void configure_valve_switch_pulsed(size_t valve_number, switch_::Switch *valve_switch_off, - switch_::Switch *valve_switch_on, uint32_t pulse_duration, uint32_t run_duration); /// configure a valve's associated pump switch object void configure_valve_pump_switch(size_t valve_number, switch_::Switch *pump_switch); - void configure_valve_pump_switch_pulsed(size_t valve_number, switch_::Switch *pump_switch_off, - switch_::Switch *pump_switch_on, uint32_t pulse_duration); /// configure a valve's run duration number component void configure_valve_run_duration_number(size_t valve_number, SprinklerControllerNumber *run_duration_number); @@ -383,10 +350,10 @@ class Sprinkler : public Component { bool is_a_valid_valve(size_t valve_number); /// returns true if the pump the pointer points to is in use - bool pump_in_use(SprinklerSwitch *pump_switch); + bool pump_in_use(switch_::Switch *pump_switch); /// switches on/off a pump "safely" by checking that the new state will not conflict with another controller - void set_pump_state(SprinklerSwitch *pump_switch, bool state); + void set_pump_state(switch_::Switch *pump_switch, bool state); /// returns the amount of time in seconds required for all valves uint32_t total_cycle_time_all_valves(); @@ -419,13 +386,13 @@ class Sprinkler : public Component { SprinklerControllerSwitch *enable_switch(size_t valve_number); /// returns a pointer to a valve's switch object - SprinklerSwitch *valve_switch(size_t valve_number); + switch_::Switch *valve_switch(size_t valve_number); /// returns a pointer to a valve's pump switch object - SprinklerSwitch *valve_pump_switch(size_t valve_number); + switch_::Switch *valve_pump_switch(size_t valve_number); /// returns a pointer to a valve's pump switch object - SprinklerSwitch *valve_pump_switch_by_pump_index(size_t pump_index); + switch_::Switch *valve_pump_switch_by_pump_index(size_t pump_index); protected: /// returns true if valve number is enabled @@ -577,8 +544,8 @@ class Sprinkler : public Component { /// Queue of valves to activate next, regardless of auto-advance std::vector queued_valves_; - /// Sprinkler valve pump objects - std::vector pump_; + /// Sprinkler valve pump switches + std::vector pump_; /// Sprinkler valve objects std::vector valve_; From 918bc4b74f2f9af49d1c3efa8846d392e1ee324e Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Mon, 22 Dec 2025 15:41:14 -0500 Subject: [PATCH 004/302] [esp32] Remove remaining using_esp_idf checks (#12623) Co-authored-by: Claude --- esphome/components/captive_portal/__init__.py | 2 +- esphome/components/i2c/__init__.py | 2 +- esphome/components/i2s_audio/__init__.py | 5 +++-- esphome/components/improv_serial/__init__.py | 2 +- esphome/components/mdns/__init__.py | 6 ++---- esphome/components/network/__init__.py | 10 +++++----- esphome/components/wifi/__init__.py | 4 ++-- esphome/core/__init__.py | 5 +++++ 8 files changed, 20 insertions(+), 16 deletions(-) diff --git a/esphome/components/captive_portal/__init__.py b/esphome/components/captive_portal/__init__.py index 25d0a22083..763e2e4ec5 100644 --- a/esphome/components/captive_portal/__init__.py +++ b/esphome/components/captive_portal/__init__.py @@ -25,7 +25,7 @@ _LOGGER = logging.getLogger(__name__) def AUTO_LOAD() -> list[str]: auto_load = ["web_server_base", "ota.web_server"] - if CORE.using_esp_idf: + if CORE.is_esp32: auto_load.append("socket") return auto_load diff --git a/esphome/components/i2c/__init__.py b/esphome/components/i2c/__init__.py index b7436ccc39..56e0c8e4ab 100644 --- a/esphome/components/i2c/__init__.py +++ b/esphome/components/i2c/__init__.py @@ -146,7 +146,7 @@ def _final_validate(config): full_config = fv.full_config.get()[CONF_I2C] if CORE.using_zephyr and len(full_config) > 1: raise cv.Invalid("Second i2c is not implemented on Zephyr yet") - if CORE.using_esp_idf and get_esp32_variant() in ESP32_I2C_CAPABILITIES: + if CORE.is_esp32 and get_esp32_variant() in ESP32_I2C_CAPABILITIES: variant = get_esp32_variant() max_num = ESP32_I2C_CAPABILITIES[variant]["NUM"] if len(full_config) > max_num: diff --git a/esphome/components/i2s_audio/__init__.py b/esphome/components/i2s_audio/__init__.py index 61c5ca4ec1..d3128c5f4c 100644 --- a/esphome/components/i2s_audio/__init__.py +++ b/esphome/components/i2s_audio/__init__.py @@ -232,6 +232,8 @@ def validate_use_legacy(value): if (not value[CONF_USE_LEGACY]) and (CORE.using_arduino): raise cv.Invalid("Arduino supports only the legacy i2s driver") _set_use_legacy_driver(value[CONF_USE_LEGACY]) + elif CORE.using_arduino: + _set_use_legacy_driver(True) return value @@ -261,8 +263,7 @@ def _final_validate(_): def use_legacy(): - legacy_driver = _get_use_legacy_driver() - return not (CORE.using_esp_idf and not legacy_driver) + return _get_use_legacy_driver() FINAL_VALIDATE_SCHEMA = _final_validate diff --git a/esphome/components/improv_serial/__init__.py b/esphome/components/improv_serial/__init__.py index 7f88b17e11..9a2ac2f40f 100644 --- a/esphome/components/improv_serial/__init__.py +++ b/esphome/components/improv_serial/__init__.py @@ -26,7 +26,7 @@ def validate_logger(config): logger_conf = fv.full_config.get()[CONF_LOGGER] if logger_conf[CONF_BAUD_RATE] == 0: raise cv.Invalid("improv_serial requires the logger baud_rate to be not 0") - if CORE.using_esp_idf and ( + if CORE.is_esp32 and ( logger_conf[CONF_HARDWARE_UART] == USB_CDC and get_esp32_variant() == VARIANT_ESP32S3 ): diff --git a/esphome/components/mdns/__init__.py b/esphome/components/mdns/__init__.py index 99b728b249..3088d8ad7e 100644 --- a/esphome/components/mdns/__init__.py +++ b/esphome/components/mdns/__init__.py @@ -157,14 +157,12 @@ async def to_code(config): return if CORE.using_arduino: - if CORE.is_esp32: - cg.add_library("ESPmDNS", None) - elif CORE.is_esp8266: + if CORE.is_esp8266: cg.add_library("ESP8266mDNS", None) elif CORE.is_rp2040: cg.add_library("LEAmDNS", None) - if CORE.using_esp_idf: + if CORE.is_esp32: add_idf_component(name="espressif/mdns", ref="1.9.1") cg.add_define("USE_MDNS") diff --git a/esphome/components/network/__init__.py b/esphome/components/network/__init__.py index d7a51fb0c6..5b63bbfce9 100644 --- a/esphome/components/network/__init__.py +++ b/esphome/components/network/__init__.py @@ -156,7 +156,7 @@ async def to_code(config): "High performance networking disabled by user configuration (overriding component request)" ) - if CORE.is_esp32 and CORE.using_esp_idf and should_enable: + if CORE.is_esp32 and should_enable: # Check if PSRAM is guaranteed (set by psram component during final validation) psram_guaranteed = psram_is_guaranteed() @@ -210,12 +210,12 @@ async def to_code(config): "USE_NETWORK_MIN_IPV6_ADDR_COUNT", config[CONF_MIN_IPV6_ADDR_COUNT] ) if CORE.is_esp32: - if CORE.using_esp_idf: - add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", enable_ipv6) - add_idf_sdkconfig_option("CONFIG_LWIP_IPV6_AUTOCONFIG", enable_ipv6) - else: + if CORE.using_arduino: add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", True) add_idf_sdkconfig_option("CONFIG_LWIP_IPV6_AUTOCONFIG", True) + else: + add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", enable_ipv6) + add_idf_sdkconfig_option("CONFIG_LWIP_IPV6_AUTOCONFIG", enable_ipv6) elif enable_ipv6: cg.add_build_flag("-DCONFIG_LWIP_IPV6") cg.add_build_flag("-DCONFIG_LWIP_IPV6_AUTOCONFIG") diff --git a/esphome/components/wifi/__init__.py b/esphome/components/wifi/__init__.py index fb23837e78..232e8d4f27 100644 --- a/esphome/components/wifi/__init__.py +++ b/esphome/components/wifi/__init__.py @@ -464,7 +464,7 @@ async def to_code(config): ) cg.add(var.set_ap_timeout(conf[CONF_AP_TIMEOUT])) cg.add_define("USE_WIFI_AP") - elif CORE.is_esp32 and CORE.using_esp_idf: + elif CORE.is_esp32 and not CORE.using_arduino: add_idf_sdkconfig_option("CONFIG_ESP_WIFI_SOFTAP_SUPPORT", False) add_idf_sdkconfig_option("CONFIG_LWIP_DHCPS", False) @@ -509,7 +509,7 @@ async def to_code(config): add_idf_sdkconfig_option("CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP", True) # Apply high performance WiFi settings if high performance networking is enabled - if CORE.is_esp32 and CORE.using_esp_idf and has_high_performance_networking(): + if CORE.is_esp32 and has_high_performance_networking(): # Check if PSRAM is guaranteed (set by psram component during final validation) psram_guaranteed = psram_is_guaranteed() diff --git a/esphome/core/__init__.py b/esphome/core/__init__.py index ad9844a3bf..3baec93186 100644 --- a/esphome/core/__init__.py +++ b/esphome/core/__init__.py @@ -798,6 +798,11 @@ class EsphomeCore: @property def using_esp_idf(self): + _LOGGER.warning( + "CORE.using_esp_idf was deprecated in 2026.1, will change behavior in 2026.6. " + "ESP32 Arduino builds on top of ESP-IDF, so ESP-IDF features are available in both frameworks. " + "Use CORE.is_esp32 and/or CORE.using_arduino instead." + ) return self.target_framework == "esp-idf" @property From c8b531ac06d569197da9b6740dd7062f1a7e77d9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 22 Dec 2025 11:13:51 -1000 Subject: [PATCH 005/302] [safe_mode] Defer preference sync in clean_rtc to avoid blocking event loop (#12625) --- esphome/components/safe_mode/safe_mode.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/esphome/components/safe_mode/safe_mode.cpp b/esphome/components/safe_mode/safe_mode.cpp index f8e5d7d8e5..c933222273 100644 --- a/esphome/components/safe_mode/safe_mode.cpp +++ b/esphome/components/safe_mode/safe_mode.cpp @@ -141,7 +141,14 @@ uint32_t SafeModeComponent::read_rtc_() { return val; } -void SafeModeComponent::clean_rtc() { this->write_rtc_(0); } +void SafeModeComponent::clean_rtc() { + // Save without sync - preferences will be written at shutdown or by IntervalSyncer. + // This avoids blocking the loop for 50+ ms on flash write. If the device crashes + // before sync, the boot wasn't really successful anyway and the counter should + // remain incremented. + uint32_t val = 0; + this->rtc_.save(&val); +} void SafeModeComponent::on_safe_shutdown() { if (this->read_rtc_() != SafeModeComponent::ENTER_SAFE_MODE_MAGIC) From bdbe72b7f15e0f0dc861546565798dfa9ed86fa9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 22 Dec 2025 11:14:11 -1000 Subject: [PATCH 006/302] [web_server] Make internal JSON helper methods private (#12624) --- esphome/components/web_server/web_server.cpp | 182 +++++++++---------- esphome/components/web_server/web_server.h | 105 ++++++----- 2 files changed, 154 insertions(+), 133 deletions(-) diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index 207eafad5c..ece9d65121 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -455,7 +455,7 @@ void WebServer::handle_sensor_request(AsyncWebServerRequest *request, const UrlM // Note: request->method() is always HTTP_GET here (canHandle ensures this) if (match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->sensor_json(obj, obj->state, detail); + std::string data = this->sensor_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); return; } @@ -463,12 +463,12 @@ void WebServer::handle_sensor_request(AsyncWebServerRequest *request, const UrlM request->send(404); } std::string WebServer::sensor_state_json_generator(WebServer *web_server, void *source) { - return web_server->sensor_json((sensor::Sensor *) (source), ((sensor::Sensor *) (source))->state, DETAIL_STATE); + return web_server->sensor_json_((sensor::Sensor *) (source), ((sensor::Sensor *) (source))->state, DETAIL_STATE); } std::string WebServer::sensor_all_json_generator(WebServer *web_server, void *source) { - return web_server->sensor_json((sensor::Sensor *) (source), ((sensor::Sensor *) (source))->state, DETAIL_ALL); + return web_server->sensor_json_((sensor::Sensor *) (source), ((sensor::Sensor *) (source))->state, DETAIL_ALL); } -std::string WebServer::sensor_json(sensor::Sensor *obj, float value, JsonDetail start_config) { +std::string WebServer::sensor_json_(sensor::Sensor *obj, float value, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -500,7 +500,7 @@ void WebServer::handle_text_sensor_request(AsyncWebServerRequest *request, const // Note: request->method() is always HTTP_GET here (canHandle ensures this) if (match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->text_sensor_json(obj, obj->state, detail); + std::string data = this->text_sensor_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); return; } @@ -508,15 +508,15 @@ void WebServer::handle_text_sensor_request(AsyncWebServerRequest *request, const request->send(404); } std::string WebServer::text_sensor_state_json_generator(WebServer *web_server, void *source) { - return web_server->text_sensor_json((text_sensor::TextSensor *) (source), - ((text_sensor::TextSensor *) (source))->state, DETAIL_STATE); + return web_server->text_sensor_json_((text_sensor::TextSensor *) (source), + ((text_sensor::TextSensor *) (source))->state, DETAIL_STATE); } std::string WebServer::text_sensor_all_json_generator(WebServer *web_server, void *source) { - return web_server->text_sensor_json((text_sensor::TextSensor *) (source), - ((text_sensor::TextSensor *) (source))->state, DETAIL_ALL); + return web_server->text_sensor_json_((text_sensor::TextSensor *) (source), + ((text_sensor::TextSensor *) (source))->state, DETAIL_ALL); } -std::string WebServer::text_sensor_json(text_sensor::TextSensor *obj, const std::string &value, - JsonDetail start_config) { +std::string WebServer::text_sensor_json_(text_sensor::TextSensor *obj, const std::string &value, + JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -542,7 +542,7 @@ void WebServer::handle_switch_request(AsyncWebServerRequest *request, const UrlM if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->switch_json(obj, obj->state, detail); + std::string data = this->switch_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); return; } @@ -584,12 +584,12 @@ void WebServer::handle_switch_request(AsyncWebServerRequest *request, const UrlM request->send(404); } std::string WebServer::switch_state_json_generator(WebServer *web_server, void *source) { - return web_server->switch_json((switch_::Switch *) (source), ((switch_::Switch *) (source))->state, DETAIL_STATE); + return web_server->switch_json_((switch_::Switch *) (source), ((switch_::Switch *) (source))->state, DETAIL_STATE); } std::string WebServer::switch_all_json_generator(WebServer *web_server, void *source) { - return web_server->switch_json((switch_::Switch *) (source), ((switch_::Switch *) (source))->state, DETAIL_ALL); + return web_server->switch_json_((switch_::Switch *) (source), ((switch_::Switch *) (source))->state, DETAIL_ALL); } -std::string WebServer::switch_json(switch_::Switch *obj, bool value, JsonDetail start_config) { +std::string WebServer::switch_json_(switch_::Switch *obj, bool value, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -610,7 +610,7 @@ void WebServer::handle_button_request(AsyncWebServerRequest *request, const UrlM continue; if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->button_json(obj, detail); + std::string data = this->button_json_(obj, detail); request->send(200, "application/json", data.c_str()); } else if (match.method_equals("press")) { this->defer([obj]() { obj->press(); }); @@ -624,12 +624,12 @@ void WebServer::handle_button_request(AsyncWebServerRequest *request, const UrlM request->send(404); } std::string WebServer::button_state_json_generator(WebServer *web_server, void *source) { - return web_server->button_json((button::Button *) (source), DETAIL_STATE); + return web_server->button_json_((button::Button *) (source), DETAIL_STATE); } std::string WebServer::button_all_json_generator(WebServer *web_server, void *source) { - return web_server->button_json((button::Button *) (source), DETAIL_ALL); + return web_server->button_json_((button::Button *) (source), DETAIL_ALL); } -std::string WebServer::button_json(button::Button *obj, JsonDetail start_config) { +std::string WebServer::button_json_(button::Button *obj, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -655,7 +655,7 @@ void WebServer::handle_binary_sensor_request(AsyncWebServerRequest *request, con // Note: request->method() is always HTTP_GET here (canHandle ensures this) if (match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->binary_sensor_json(obj, obj->state, detail); + std::string data = this->binary_sensor_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); return; } @@ -663,14 +663,14 @@ void WebServer::handle_binary_sensor_request(AsyncWebServerRequest *request, con request->send(404); } std::string WebServer::binary_sensor_state_json_generator(WebServer *web_server, void *source) { - return web_server->binary_sensor_json((binary_sensor::BinarySensor *) (source), - ((binary_sensor::BinarySensor *) (source))->state, DETAIL_STATE); + return web_server->binary_sensor_json_((binary_sensor::BinarySensor *) (source), + ((binary_sensor::BinarySensor *) (source))->state, DETAIL_STATE); } std::string WebServer::binary_sensor_all_json_generator(WebServer *web_server, void *source) { - return web_server->binary_sensor_json((binary_sensor::BinarySensor *) (source), - ((binary_sensor::BinarySensor *) (source))->state, DETAIL_ALL); + return web_server->binary_sensor_json_((binary_sensor::BinarySensor *) (source), + ((binary_sensor::BinarySensor *) (source))->state, DETAIL_ALL); } -std::string WebServer::binary_sensor_json(binary_sensor::BinarySensor *obj, bool value, JsonDetail start_config) { +std::string WebServer::binary_sensor_json_(binary_sensor::BinarySensor *obj, bool value, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -696,7 +696,7 @@ void WebServer::handle_fan_request(AsyncWebServerRequest *request, const UrlMatc if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->fan_json(obj, detail); + std::string data = this->fan_json_(obj, detail); request->send(200, "application/json", data.c_str()); } else if (match.method_equals("toggle")) { this->defer([obj]() { obj->toggle().perform(); }); @@ -738,12 +738,12 @@ void WebServer::handle_fan_request(AsyncWebServerRequest *request, const UrlMatc request->send(404); } std::string WebServer::fan_state_json_generator(WebServer *web_server, void *source) { - return web_server->fan_json((fan::Fan *) (source), DETAIL_STATE); + return web_server->fan_json_((fan::Fan *) (source), DETAIL_STATE); } std::string WebServer::fan_all_json_generator(WebServer *web_server, void *source) { - return web_server->fan_json((fan::Fan *) (source), DETAIL_ALL); + return web_server->fan_json_((fan::Fan *) (source), DETAIL_ALL); } -std::string WebServer::fan_json(fan::Fan *obj, JsonDetail start_config) { +std::string WebServer::fan_json_(fan::Fan *obj, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -776,7 +776,7 @@ void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMa if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->light_json(obj, detail); + std::string data = this->light_json_(obj, detail); request->send(200, "application/json", data.c_str()); } else if (match.method_equals("toggle")) { this->defer([obj]() { obj->toggle().perform(); }); @@ -816,12 +816,12 @@ void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMa request->send(404); } std::string WebServer::light_state_json_generator(WebServer *web_server, void *source) { - return web_server->light_json((light::LightState *) (source), DETAIL_STATE); + return web_server->light_json_((light::LightState *) (source), DETAIL_STATE); } std::string WebServer::light_all_json_generator(WebServer *web_server, void *source) { - return web_server->light_json((light::LightState *) (source), DETAIL_ALL); + return web_server->light_json_((light::LightState *) (source), DETAIL_ALL); } -std::string WebServer::light_json(light::LightState *obj, JsonDetail start_config) { +std::string WebServer::light_json_(light::LightState *obj, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -854,7 +854,7 @@ void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMa if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->cover_json(obj, detail); + std::string data = this->cover_json_(obj, detail); request->send(200, "application/json", data.c_str()); return; } @@ -903,12 +903,12 @@ void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMa request->send(404); } std::string WebServer::cover_state_json_generator(WebServer *web_server, void *source) { - return web_server->cover_json((cover::Cover *) (source), DETAIL_STATE); + return web_server->cover_json_((cover::Cover *) (source), DETAIL_STATE); } std::string WebServer::cover_all_json_generator(WebServer *web_server, void *source) { - return web_server->cover_json((cover::Cover *) (source), DETAIL_ALL); + return web_server->cover_json_((cover::Cover *) (source), DETAIL_ALL); } -std::string WebServer::cover_json(cover::Cover *obj, JsonDetail start_config) { +std::string WebServer::cover_json_(cover::Cover *obj, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -942,7 +942,7 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->number_json(obj, obj->state, detail); + std::string data = this->number_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); return; } @@ -962,12 +962,12 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM } std::string WebServer::number_state_json_generator(WebServer *web_server, void *source) { - return web_server->number_json((number::Number *) (source), ((number::Number *) (source))->state, DETAIL_STATE); + return web_server->number_json_((number::Number *) (source), ((number::Number *) (source))->state, DETAIL_STATE); } std::string WebServer::number_all_json_generator(WebServer *web_server, void *source) { - return web_server->number_json((number::Number *) (source), ((number::Number *) (source))->state, DETAIL_ALL); + return web_server->number_json_((number::Number *) (source), ((number::Number *) (source))->state, DETAIL_ALL); } -std::string WebServer::number_json(number::Number *obj, float value, JsonDetail start_config) { +std::string WebServer::number_json_(number::Number *obj, float value, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -1009,7 +1009,7 @@ void WebServer::handle_date_request(AsyncWebServerRequest *request, const UrlMat continue; if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->date_json(obj, detail); + std::string data = this->date_json_(obj, detail); request->send(200, "application/json", data.c_str()); return; } @@ -1035,12 +1035,12 @@ void WebServer::handle_date_request(AsyncWebServerRequest *request, const UrlMat } std::string WebServer::date_state_json_generator(WebServer *web_server, void *source) { - return web_server->date_json((datetime::DateEntity *) (source), DETAIL_STATE); + return web_server->date_json_((datetime::DateEntity *) (source), DETAIL_STATE); } std::string WebServer::date_all_json_generator(WebServer *web_server, void *source) { - return web_server->date_json((datetime::DateEntity *) (source), DETAIL_ALL); + return web_server->date_json_((datetime::DateEntity *) (source), DETAIL_ALL); } -std::string WebServer::date_json(datetime::DateEntity *obj, JsonDetail start_config) { +std::string WebServer::date_json_(datetime::DateEntity *obj, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -1072,7 +1072,7 @@ void WebServer::handle_time_request(AsyncWebServerRequest *request, const UrlMat continue; if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->time_json(obj, detail); + std::string data = this->time_json_(obj, detail); request->send(200, "application/json", data.c_str()); return; } @@ -1097,12 +1097,12 @@ void WebServer::handle_time_request(AsyncWebServerRequest *request, const UrlMat request->send(404); } std::string WebServer::time_state_json_generator(WebServer *web_server, void *source) { - return web_server->time_json((datetime::TimeEntity *) (source), DETAIL_STATE); + return web_server->time_json_((datetime::TimeEntity *) (source), DETAIL_STATE); } std::string WebServer::time_all_json_generator(WebServer *web_server, void *source) { - return web_server->time_json((datetime::TimeEntity *) (source), DETAIL_ALL); + return web_server->time_json_((datetime::TimeEntity *) (source), DETAIL_ALL); } -std::string WebServer::time_json(datetime::TimeEntity *obj, JsonDetail start_config) { +std::string WebServer::time_json_(datetime::TimeEntity *obj, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -1134,7 +1134,7 @@ void WebServer::handle_datetime_request(AsyncWebServerRequest *request, const Ur continue; if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->datetime_json(obj, detail); + std::string data = this->datetime_json_(obj, detail); request->send(200, "application/json", data.c_str()); return; } @@ -1159,12 +1159,12 @@ void WebServer::handle_datetime_request(AsyncWebServerRequest *request, const Ur request->send(404); } std::string WebServer::datetime_state_json_generator(WebServer *web_server, void *source) { - return web_server->datetime_json((datetime::DateTimeEntity *) (source), DETAIL_STATE); + return web_server->datetime_json_((datetime::DateTimeEntity *) (source), DETAIL_STATE); } std::string WebServer::datetime_all_json_generator(WebServer *web_server, void *source) { - return web_server->datetime_json((datetime::DateTimeEntity *) (source), DETAIL_ALL); + return web_server->datetime_json_((datetime::DateTimeEntity *) (source), DETAIL_ALL); } -std::string WebServer::datetime_json(datetime::DateTimeEntity *obj, JsonDetail start_config) { +std::string WebServer::datetime_json_(datetime::DateTimeEntity *obj, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -1199,7 +1199,7 @@ void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMat if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->text_json(obj, obj->state, detail); + std::string data = this->text_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); return; } @@ -1219,12 +1219,12 @@ void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMat } std::string WebServer::text_state_json_generator(WebServer *web_server, void *source) { - return web_server->text_json((text::Text *) (source), ((text::Text *) (source))->state, DETAIL_STATE); + return web_server->text_json_((text::Text *) (source), ((text::Text *) (source))->state, DETAIL_STATE); } std::string WebServer::text_all_json_generator(WebServer *web_server, void *source) { - return web_server->text_json((text::Text *) (source), ((text::Text *) (source))->state, DETAIL_ALL); + return web_server->text_json_((text::Text *) (source), ((text::Text *) (source))->state, DETAIL_ALL); } -std::string WebServer::text_json(text::Text *obj, const std::string &value, JsonDetail start_config) { +std::string WebServer::text_json_(text::Text *obj, const std::string &value, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -1255,7 +1255,7 @@ void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlM if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->select_json(obj, obj->has_state() ? obj->current_option() : "", detail); + std::string data = this->select_json_(obj, obj->has_state() ? obj->current_option() : "", detail); request->send(200, "application/json", data.c_str()); return; } @@ -1276,13 +1276,13 @@ void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlM } std::string WebServer::select_state_json_generator(WebServer *web_server, void *source) { auto *obj = (select::Select *) (source); - return web_server->select_json(obj, obj->has_state() ? obj->current_option() : "", DETAIL_STATE); + return web_server->select_json_(obj, obj->has_state() ? obj->current_option() : "", DETAIL_STATE); } std::string WebServer::select_all_json_generator(WebServer *web_server, void *source) { auto *obj = (select::Select *) (source); - return web_server->select_json(obj, obj->has_state() ? obj->current_option() : "", DETAIL_ALL); + return web_server->select_json_(obj, obj->has_state() ? obj->current_option() : "", DETAIL_ALL); } -std::string WebServer::select_json(select::Select *obj, const char *value, JsonDetail start_config) { +std::string WebServer::select_json_(select::Select *obj, const char *value, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -1312,7 +1312,7 @@ void WebServer::handle_climate_request(AsyncWebServerRequest *request, const Url if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->climate_json(obj, detail); + std::string data = this->climate_json_(obj, detail); request->send(200, "application/json", data.c_str()); return; } @@ -1342,13 +1342,13 @@ void WebServer::handle_climate_request(AsyncWebServerRequest *request, const Url } std::string WebServer::climate_state_json_generator(WebServer *web_server, void *source) { // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson - return web_server->climate_json((climate::Climate *) (source), DETAIL_STATE); + return web_server->climate_json_((climate::Climate *) (source), DETAIL_STATE); } std::string WebServer::climate_all_json_generator(WebServer *web_server, void *source) { // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson - return web_server->climate_json((climate::Climate *) (source), DETAIL_ALL); + return web_server->climate_json_((climate::Climate *) (source), DETAIL_ALL); } -std::string WebServer::climate_json(climate::Climate *obj, JsonDetail start_config) { +std::string WebServer::climate_json_(climate::Climate *obj, JsonDetail start_config) { // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson json::JsonBuilder builder; JsonObject root = builder.root(); @@ -1456,7 +1456,7 @@ void WebServer::handle_lock_request(AsyncWebServerRequest *request, const UrlMat if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->lock_json(obj, obj->state, detail); + std::string data = this->lock_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); return; } @@ -1498,12 +1498,12 @@ void WebServer::handle_lock_request(AsyncWebServerRequest *request, const UrlMat request->send(404); } std::string WebServer::lock_state_json_generator(WebServer *web_server, void *source) { - return web_server->lock_json((lock::Lock *) (source), ((lock::Lock *) (source))->state, DETAIL_STATE); + return web_server->lock_json_((lock::Lock *) (source), ((lock::Lock *) (source))->state, DETAIL_STATE); } std::string WebServer::lock_all_json_generator(WebServer *web_server, void *source) { - return web_server->lock_json((lock::Lock *) (source), ((lock::Lock *) (source))->state, DETAIL_ALL); + return web_server->lock_json_((lock::Lock *) (source), ((lock::Lock *) (source))->state, DETAIL_ALL); } -std::string WebServer::lock_json(lock::Lock *obj, lock::LockState value, JsonDetail start_config) { +std::string WebServer::lock_json_(lock::Lock *obj, lock::LockState value, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -1530,7 +1530,7 @@ void WebServer::handle_valve_request(AsyncWebServerRequest *request, const UrlMa if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->valve_json(obj, detail); + std::string data = this->valve_json_(obj, detail); request->send(200, "application/json", data.c_str()); return; } @@ -1577,12 +1577,12 @@ void WebServer::handle_valve_request(AsyncWebServerRequest *request, const UrlMa request->send(404); } std::string WebServer::valve_state_json_generator(WebServer *web_server, void *source) { - return web_server->valve_json((valve::Valve *) (source), DETAIL_STATE); + return web_server->valve_json_((valve::Valve *) (source), DETAIL_STATE); } std::string WebServer::valve_all_json_generator(WebServer *web_server, void *source) { - return web_server->valve_json((valve::Valve *) (source), DETAIL_ALL); + return web_server->valve_json_((valve::Valve *) (source), DETAIL_ALL); } -std::string WebServer::valve_json(valve::Valve *obj, JsonDetail start_config) { +std::string WebServer::valve_json_(valve::Valve *obj, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -1614,7 +1614,7 @@ void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *reques if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->alarm_control_panel_json(obj, obj->get_state(), detail); + std::string data = this->alarm_control_panel_json_(obj, obj->get_state(), detail); request->send(200, "application/json", data.c_str()); return; } @@ -1655,18 +1655,18 @@ void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *reques request->send(404); } std::string WebServer::alarm_control_panel_state_json_generator(WebServer *web_server, void *source) { - return web_server->alarm_control_panel_json((alarm_control_panel::AlarmControlPanel *) (source), - ((alarm_control_panel::AlarmControlPanel *) (source))->get_state(), - DETAIL_STATE); + return web_server->alarm_control_panel_json_((alarm_control_panel::AlarmControlPanel *) (source), + ((alarm_control_panel::AlarmControlPanel *) (source))->get_state(), + DETAIL_STATE); } std::string WebServer::alarm_control_panel_all_json_generator(WebServer *web_server, void *source) { - return web_server->alarm_control_panel_json((alarm_control_panel::AlarmControlPanel *) (source), - ((alarm_control_panel::AlarmControlPanel *) (source))->get_state(), - DETAIL_ALL); + return web_server->alarm_control_panel_json_((alarm_control_panel::AlarmControlPanel *) (source), + ((alarm_control_panel::AlarmControlPanel *) (source))->get_state(), + DETAIL_ALL); } -std::string WebServer::alarm_control_panel_json(alarm_control_panel::AlarmControlPanel *obj, - alarm_control_panel::AlarmControlPanelState value, - JsonDetail start_config) { +std::string WebServer::alarm_control_panel_json_(alarm_control_panel::AlarmControlPanel *obj, + alarm_control_panel::AlarmControlPanelState value, + JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -1696,7 +1696,7 @@ void WebServer::handle_event_request(AsyncWebServerRequest *request, const UrlMa // Note: request->method() is always HTTP_GET here (canHandle ensures this) if (match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->event_json(obj, "", detail); + std::string data = this->event_json_(obj, "", detail); request->send(200, "application/json", data.c_str()); return; } @@ -1711,14 +1711,14 @@ static std::string get_event_type(event::Event *event) { std::string WebServer::event_state_json_generator(WebServer *web_server, void *source) { auto *event = static_cast(source); - return web_server->event_json(event, get_event_type(event), DETAIL_STATE); + return web_server->event_json_(event, get_event_type(event), DETAIL_STATE); } // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson std::string WebServer::event_all_json_generator(WebServer *web_server, void *source) { auto *event = static_cast(source); - return web_server->event_json(event, get_event_type(event), DETAIL_ALL); + return web_server->event_json_(event, get_event_type(event), DETAIL_ALL); } -std::string WebServer::event_json(event::Event *obj, const std::string &event_type, JsonDetail start_config) { +std::string WebServer::event_json_(event::Event *obj, const std::string &event_type, JsonDetail start_config) { json::JsonBuilder builder; JsonObject root = builder.root(); @@ -1764,7 +1764,7 @@ void WebServer::handle_update_request(AsyncWebServerRequest *request, const UrlM if (request->method() == HTTP_GET && match.method_empty()) { auto detail = get_request_detail(request); - std::string data = this->update_json(obj, detail); + std::string data = this->update_json_(obj, detail); request->send(200, "application/json", data.c_str()); return; } @@ -1782,13 +1782,13 @@ void WebServer::handle_update_request(AsyncWebServerRequest *request, const UrlM } std::string WebServer::update_state_json_generator(WebServer *web_server, void *source) { // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson - return web_server->update_json((update::UpdateEntity *) (source), DETAIL_STATE); + return web_server->update_json_((update::UpdateEntity *) (source), DETAIL_STATE); } std::string WebServer::update_all_json_generator(WebServer *web_server, void *source) { // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson - return web_server->update_json((update::UpdateEntity *) (source), DETAIL_STATE); + return web_server->update_json_((update::UpdateEntity *) (source), DETAIL_STATE); } -std::string WebServer::update_json(update::UpdateEntity *obj, JsonDetail start_config) { +std::string WebServer::update_json_(update::UpdateEntity *obj, JsonDetail start_config) { // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson json::JsonBuilder builder; JsonObject root = builder.root(); diff --git a/esphome/components/web_server/web_server.h b/esphome/components/web_server/web_server.h index 98234ec1ae..0078146284 100644 --- a/esphome/components/web_server/web_server.h +++ b/esphome/components/web_server/web_server.h @@ -271,8 +271,6 @@ class WebServer : public Controller, static std::string sensor_state_json_generator(WebServer *web_server, void *source); static std::string sensor_all_json_generator(WebServer *web_server, void *source); - /// Dump the sensor state with its value as a JSON string. - std::string sensor_json(sensor::Sensor *obj, float value, JsonDetail start_config); #endif #ifdef USE_SWITCH @@ -283,8 +281,6 @@ class WebServer : public Controller, static std::string switch_state_json_generator(WebServer *web_server, void *source); static std::string switch_all_json_generator(WebServer *web_server, void *source); - /// Dump the switch state with its value as a JSON string. - std::string switch_json(switch_::Switch *obj, bool value, JsonDetail start_config); #endif #ifdef USE_BUTTON @@ -293,8 +289,6 @@ class WebServer : public Controller, static std::string button_state_json_generator(WebServer *web_server, void *source); static std::string button_all_json_generator(WebServer *web_server, void *source); - /// Dump the button details with its value as a JSON string. - std::string button_json(button::Button *obj, JsonDetail start_config); #endif #ifdef USE_BINARY_SENSOR @@ -305,8 +299,6 @@ class WebServer : public Controller, static std::string binary_sensor_state_json_generator(WebServer *web_server, void *source); static std::string binary_sensor_all_json_generator(WebServer *web_server, void *source); - /// Dump the binary sensor state with its value as a JSON string. - std::string binary_sensor_json(binary_sensor::BinarySensor *obj, bool value, JsonDetail start_config); #endif #ifdef USE_FAN @@ -317,8 +309,6 @@ class WebServer : public Controller, static std::string fan_state_json_generator(WebServer *web_server, void *source); static std::string fan_all_json_generator(WebServer *web_server, void *source); - /// Dump the fan state as a JSON string. - std::string fan_json(fan::Fan *obj, JsonDetail start_config); #endif #ifdef USE_LIGHT @@ -329,8 +319,6 @@ class WebServer : public Controller, static std::string light_state_json_generator(WebServer *web_server, void *source); static std::string light_all_json_generator(WebServer *web_server, void *source); - /// Dump the light state as a JSON string. - std::string light_json(light::LightState *obj, JsonDetail start_config); #endif #ifdef USE_TEXT_SENSOR @@ -341,8 +329,6 @@ class WebServer : public Controller, static std::string text_sensor_state_json_generator(WebServer *web_server, void *source); static std::string text_sensor_all_json_generator(WebServer *web_server, void *source); - /// Dump the text sensor state with its value as a JSON string. - std::string text_sensor_json(text_sensor::TextSensor *obj, const std::string &value, JsonDetail start_config); #endif #ifdef USE_COVER @@ -353,8 +339,6 @@ class WebServer : public Controller, static std::string cover_state_json_generator(WebServer *web_server, void *source); static std::string cover_all_json_generator(WebServer *web_server, void *source); - /// Dump the cover state as a JSON string. - std::string cover_json(cover::Cover *obj, JsonDetail start_config); #endif #ifdef USE_NUMBER @@ -364,8 +348,6 @@ class WebServer : public Controller, static std::string number_state_json_generator(WebServer *web_server, void *source); static std::string number_all_json_generator(WebServer *web_server, void *source); - /// Dump the number state with its value as a JSON string. - std::string number_json(number::Number *obj, float value, JsonDetail start_config); #endif #ifdef USE_DATETIME_DATE @@ -375,8 +357,6 @@ class WebServer : public Controller, static std::string date_state_json_generator(WebServer *web_server, void *source); static std::string date_all_json_generator(WebServer *web_server, void *source); - /// Dump the date state with its value as a JSON string. - std::string date_json(datetime::DateEntity *obj, JsonDetail start_config); #endif #ifdef USE_DATETIME_TIME @@ -386,8 +366,6 @@ class WebServer : public Controller, static std::string time_state_json_generator(WebServer *web_server, void *source); static std::string time_all_json_generator(WebServer *web_server, void *source); - /// Dump the time state with its value as a JSON string. - std::string time_json(datetime::TimeEntity *obj, JsonDetail start_config); #endif #ifdef USE_DATETIME_DATETIME @@ -397,8 +375,6 @@ class WebServer : public Controller, static std::string datetime_state_json_generator(WebServer *web_server, void *source); static std::string datetime_all_json_generator(WebServer *web_server, void *source); - /// Dump the datetime state with its value as a JSON string. - std::string datetime_json(datetime::DateTimeEntity *obj, JsonDetail start_config); #endif #ifdef USE_TEXT @@ -408,8 +384,6 @@ class WebServer : public Controller, static std::string text_state_json_generator(WebServer *web_server, void *source); static std::string text_all_json_generator(WebServer *web_server, void *source); - /// Dump the text state with its value as a JSON string. - std::string text_json(text::Text *obj, const std::string &value, JsonDetail start_config); #endif #ifdef USE_SELECT @@ -419,8 +393,6 @@ class WebServer : public Controller, static std::string select_state_json_generator(WebServer *web_server, void *source); static std::string select_all_json_generator(WebServer *web_server, void *source); - /// Dump the select state with its value as a JSON string. - std::string select_json(select::Select *obj, const char *value, JsonDetail start_config); #endif #ifdef USE_CLIMATE @@ -430,8 +402,6 @@ class WebServer : public Controller, static std::string climate_state_json_generator(WebServer *web_server, void *source); static std::string climate_all_json_generator(WebServer *web_server, void *source); - /// Dump the climate details - std::string climate_json(climate::Climate *obj, JsonDetail start_config); #endif #ifdef USE_LOCK @@ -442,8 +412,6 @@ class WebServer : public Controller, static std::string lock_state_json_generator(WebServer *web_server, void *source); static std::string lock_all_json_generator(WebServer *web_server, void *source); - /// Dump the lock state with its value as a JSON string. - std::string lock_json(lock::Lock *obj, lock::LockState value, JsonDetail start_config); #endif #ifdef USE_VALVE @@ -454,8 +422,6 @@ class WebServer : public Controller, static std::string valve_state_json_generator(WebServer *web_server, void *source); static std::string valve_all_json_generator(WebServer *web_server, void *source); - /// Dump the valve state as a JSON string. - std::string valve_json(valve::Valve *obj, JsonDetail start_config); #endif #ifdef USE_ALARM_CONTROL_PANEL @@ -466,9 +432,6 @@ class WebServer : public Controller, static std::string alarm_control_panel_state_json_generator(WebServer *web_server, void *source); static std::string alarm_control_panel_all_json_generator(WebServer *web_server, void *source); - /// Dump the alarm_control_panel state with its value as a JSON string. - std::string alarm_control_panel_json(alarm_control_panel::AlarmControlPanel *obj, - alarm_control_panel::AlarmControlPanelState value, JsonDetail start_config); #endif #ifdef USE_EVENT @@ -479,9 +442,6 @@ class WebServer : public Controller, /// Handle a event request under '/event'. void handle_event_request(AsyncWebServerRequest *request, const UrlMatch &match); - - /// Dump the event details with its value as a JSON string. - std::string event_json(event::Event *obj, const std::string &event_type, JsonDetail start_config); #endif #ifdef USE_UPDATE @@ -492,8 +452,6 @@ class WebServer : public Controller, static std::string update_state_json_generator(WebServer *web_server, void *source); static std::string update_all_json_generator(WebServer *web_server, void *source); - /// Dump the update state with its value as a JSON string. - std::string update_json(update::UpdateEntity *obj, JsonDetail start_config); #endif /// Override the web handler's canHandle method. @@ -593,6 +551,69 @@ class WebServer : public Controller, const char *js_include_{nullptr}; #endif bool expose_log_{true}; + + private: +#ifdef USE_SENSOR + std::string sensor_json_(sensor::Sensor *obj, float value, JsonDetail start_config); +#endif +#ifdef USE_SWITCH + std::string switch_json_(switch_::Switch *obj, bool value, JsonDetail start_config); +#endif +#ifdef USE_BUTTON + std::string button_json_(button::Button *obj, JsonDetail start_config); +#endif +#ifdef USE_BINARY_SENSOR + std::string binary_sensor_json_(binary_sensor::BinarySensor *obj, bool value, JsonDetail start_config); +#endif +#ifdef USE_FAN + std::string fan_json_(fan::Fan *obj, JsonDetail start_config); +#endif +#ifdef USE_LIGHT + std::string light_json_(light::LightState *obj, JsonDetail start_config); +#endif +#ifdef USE_TEXT_SENSOR + std::string text_sensor_json_(text_sensor::TextSensor *obj, const std::string &value, JsonDetail start_config); +#endif +#ifdef USE_COVER + std::string cover_json_(cover::Cover *obj, JsonDetail start_config); +#endif +#ifdef USE_NUMBER + std::string number_json_(number::Number *obj, float value, JsonDetail start_config); +#endif +#ifdef USE_DATETIME_DATE + std::string date_json_(datetime::DateEntity *obj, JsonDetail start_config); +#endif +#ifdef USE_DATETIME_TIME + std::string time_json_(datetime::TimeEntity *obj, JsonDetail start_config); +#endif +#ifdef USE_DATETIME_DATETIME + std::string datetime_json_(datetime::DateTimeEntity *obj, JsonDetail start_config); +#endif +#ifdef USE_TEXT + std::string text_json_(text::Text *obj, const std::string &value, JsonDetail start_config); +#endif +#ifdef USE_SELECT + std::string select_json_(select::Select *obj, const char *value, JsonDetail start_config); +#endif +#ifdef USE_CLIMATE + std::string climate_json_(climate::Climate *obj, JsonDetail start_config); +#endif +#ifdef USE_LOCK + std::string lock_json_(lock::Lock *obj, lock::LockState value, JsonDetail start_config); +#endif +#ifdef USE_VALVE + std::string valve_json_(valve::Valve *obj, JsonDetail start_config); +#endif +#ifdef USE_ALARM_CONTROL_PANEL + std::string alarm_control_panel_json_(alarm_control_panel::AlarmControlPanel *obj, + alarm_control_panel::AlarmControlPanelState value, JsonDetail start_config); +#endif +#ifdef USE_EVENT + std::string event_json_(event::Event *obj, const std::string &event_type, JsonDetail start_config); +#endif +#ifdef USE_UPDATE + std::string update_json_(update::UpdateEntity *obj, JsonDetail start_config); +#endif }; } // namespace web_server From f238f9331272c25bf073b921f443e62e75c73c6c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 22 Dec 2025 11:37:51 -1000 Subject: [PATCH 007/302] [core] Move comment to PROGMEM on ESP8266 (#12554) --- esphome/components/web_server/web_server.cpp | 4 +- esphome/core/application.h | 23 +++--- esphome/core/build_info_data.h | 2 + esphome/core/config.py | 3 +- esphome/writer.py | 25 +++++-- tests/dummy_main.cpp | 2 +- tests/unit_tests/test_writer.py | 76 +++++++++++++++++--- 7 files changed, 105 insertions(+), 30 deletions(-) diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index ece9d65121..b0731f335b 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -287,7 +287,9 @@ std::string WebServer::get_config_json() { JsonObject root = builder.root(); root[ESPHOME_F("title")] = App.get_friendly_name().empty() ? App.get_name() : App.get_friendly_name(); - root[ESPHOME_F("comment")] = App.get_comment_ref(); + char comment_buffer[ESPHOME_COMMENT_SIZE]; + App.get_comment_string(comment_buffer); + root[ESPHOME_F("comment")] = comment_buffer; #if defined(USE_WEBSERVER_OTA_DISABLED) || !defined(USE_WEBSERVER_OTA) root[ESPHOME_F("ota")] = false; // Note: USE_WEBSERVER_OTA_DISABLED only affects web_server, not captive_portal #else diff --git a/esphome/core/application.h b/esphome/core/application.h index d2146a6c16..13461b3ebd 100644 --- a/esphome/core/application.h +++ b/esphome/core/application.h @@ -12,6 +12,7 @@ #include "esphome/core/hal.h" #include "esphome/core/helpers.h" #include "esphome/core/preferences.h" +#include "esphome/core/progmem.h" #include "esphome/core/scheduler.h" #include "esphome/core/string_ref.h" #include "esphome/core/version.h" @@ -107,8 +108,7 @@ static const uint32_t TEARDOWN_TIMEOUT_REBOOT_MS = 1000; // 1 second for quick class Application { public: - void pre_setup(const std::string &name, const std::string &friendly_name, const char *comment, - bool name_add_mac_suffix) { + void pre_setup(const std::string &name, const std::string &friendly_name, bool name_add_mac_suffix) { arch_init(); this->name_add_mac_suffix_ = name_add_mac_suffix; if (name_add_mac_suffix) { @@ -127,7 +127,6 @@ class Application { this->name_ = name; this->friendly_name_ = friendly_name; } - this->comment_ = comment; } #ifdef USE_DEVICES @@ -264,10 +263,19 @@ class Application { return ""; } - /// Get the comment of this Application set by pre_setup(). - std::string get_comment() const { return this->comment_; } - /// Get the comment as StringRef (avoids allocation) - StringRef get_comment_ref() const { return StringRef(this->comment_); } + /// Copy the comment string into the provided buffer + /// Buffer must be ESPHOME_COMMENT_SIZE bytes (compile-time enforced) + void get_comment_string(std::span buffer) { + ESPHOME_strncpy_P(buffer.data(), ESPHOME_COMMENT_STR, buffer.size()); + buffer[buffer.size() - 1] = '\0'; + } + + /// Get the comment of this Application as a string + std::string get_comment() { + char buffer[ESPHOME_COMMENT_SIZE]; + this->get_comment_string(buffer); + return std::string(buffer); + } bool is_name_add_mac_suffix_enabled() const { return this->name_add_mac_suffix_; } @@ -513,7 +521,6 @@ class Application { // Pointer-sized members first Component *current_component_{nullptr}; - const char *comment_{nullptr}; // std::vector (3 pointers each: begin, end, capacity) // Partitioned vector design for looping components diff --git a/esphome/core/build_info_data.h b/esphome/core/build_info_data.h index 5e424ffaca..02bb465e44 100644 --- a/esphome/core/build_info_data.h +++ b/esphome/core/build_info_data.h @@ -7,4 +7,6 @@ #define ESPHOME_CONFIG_HASH 0x12345678U // NOLINT #define ESPHOME_BUILD_TIME 1700000000 // NOLINT +#define ESPHOME_COMMENT_SIZE 1 // NOLINT static const char ESPHOME_BUILD_TIME_STR[] = "2024-01-01 00:00:00 +0000"; +static const char ESPHOME_COMMENT_STR[] = ""; diff --git a/esphome/core/config.py b/esphome/core/config.py index 507a39b401..5e32b9380d 100644 --- a/esphome/core/config.py +++ b/esphome/core/config.py @@ -209,7 +209,7 @@ CONFIG_SCHEMA = cv.All( cv.Required(CONF_NAME): cv.valid_name, cv.Optional(CONF_FRIENDLY_NAME, ""): cv.All(cv.string, cv.Length(max=120)), cv.Optional(CONF_AREA): validate_area_config, - cv.Optional(CONF_COMMENT): cv.string, + cv.Optional(CONF_COMMENT): cv.All(cv.string, cv.Length(max=255)), cv.Required(CONF_BUILD_PATH): cv.string, cv.Optional(CONF_PLATFORMIO_OPTIONS, default={}): cv.Schema( { @@ -505,7 +505,6 @@ async def to_code(config: ConfigType) -> None: cg.App.pre_setup( config[CONF_NAME], config[CONF_FRIENDLY_NAME], - config.get(CONF_COMMENT, ""), config[CONF_NAME_ADD_MAC_SUFFIX], ) ) diff --git a/esphome/writer.py b/esphome/writer.py index 183fff8730..9ae40e417a 100644 --- a/esphome/writer.py +++ b/esphome/writer.py @@ -21,6 +21,7 @@ from esphome.const import ( from esphome.core import CORE, EsphomeError from esphome.helpers import ( copy_file_if_changed, + cpp_string_escape, get_str_env, is_ha_addon, read_file, @@ -271,7 +272,7 @@ def copy_src_tree(): "esphome", "core", "build_info_data.h" ) build_info_json_path = CORE.relative_build_path("build_info.json") - config_hash, build_time, build_time_str = get_build_info() + config_hash, build_time, build_time_str, comment = get_build_info() # Defensively force a rebuild if the build_info files don't exist, or if # there was a config change which didn't actually cause a source change @@ -292,7 +293,9 @@ def copy_src_tree(): if sources_changed: write_file( build_info_data_h_path, - generate_build_info_data_h(config_hash, build_time, build_time_str), + generate_build_info_data_h( + config_hash, build_time, build_time_str, comment + ), ) write_file( build_info_json_path, @@ -332,31 +335,39 @@ def generate_version_h(): ) -def get_build_info() -> tuple[int, int, str]: +def get_build_info() -> tuple[int, int, str, str]: """Calculate build_info values from current config. Returns: - Tuple of (config_hash, build_time, build_time_str) + Tuple of (config_hash, build_time, build_time_str, comment) """ config_hash = CORE.config_hash build_time = int(time.time()) build_time_str = time.strftime("%Y-%m-%d %H:%M:%S %z", time.localtime(build_time)) - return config_hash, build_time, build_time_str + comment = CORE.comment or "" + return config_hash, build_time, build_time_str, comment def generate_build_info_data_h( - config_hash: int, build_time: int, build_time_str: str + config_hash: int, build_time: int, build_time_str: str, comment: str ) -> str: - """Generate build_info_data.h header with config hash and build time.""" + """Generate build_info_data.h header with config hash, build time, and comment.""" + # cpp_string_escape returns '"escaped"', slice off the quotes since template has them + escaped_comment = cpp_string_escape(comment)[1:-1] + # +1 for null terminator + comment_size = len(comment) + 1 return f"""#pragma once // Auto-generated build_info data #define ESPHOME_CONFIG_HASH 0x{config_hash:08x}U // NOLINT #define ESPHOME_BUILD_TIME {build_time} // NOLINT +#define ESPHOME_COMMENT_SIZE {comment_size} // NOLINT #ifdef USE_ESP8266 #include static const char ESPHOME_BUILD_TIME_STR[] PROGMEM = "{build_time_str}"; +static const char ESPHOME_COMMENT_STR[] PROGMEM = "{escaped_comment}"; #else static const char ESPHOME_BUILD_TIME_STR[] = "{build_time_str}"; +static const char ESPHOME_COMMENT_STR[] = "{escaped_comment}"; #endif """ diff --git a/tests/dummy_main.cpp b/tests/dummy_main.cpp index 5849f4eb95..e6fe733807 100644 --- a/tests/dummy_main.cpp +++ b/tests/dummy_main.cpp @@ -12,7 +12,7 @@ using namespace esphome; void setup() { - App.pre_setup("livingroom", "LivingRoom", "comment", false); + App.pre_setup("livingroom", "LivingRoom", false); auto *log = new logger::Logger(115200, 512); // NOLINT log->pre_setup(); log->set_uart_selection(logger::UART_SELECTION_UART0); diff --git a/tests/unit_tests/test_writer.py b/tests/unit_tests/test_writer.py index 06a7d5dbdf..f354d71bb7 100644 --- a/tests/unit_tests/test_writer.py +++ b/tests/unit_tests/test_writer.py @@ -1186,8 +1186,9 @@ def test_get_build_info_new_build( build_info_path = tmp_path / "build_info.json" mock_core.relative_build_path.return_value = build_info_path mock_core.config_hash = 0x12345678 + mock_core.comment = "Test comment" - config_hash, build_time, build_time_str = get_build_info() + config_hash, build_time, build_time_str, comment = get_build_info() assert config_hash == 0x12345678 assert isinstance(build_time, int) @@ -1195,6 +1196,7 @@ def test_get_build_info_new_build( assert isinstance(build_time_str, str) # Verify build_time_str format matches expected pattern assert len(build_time_str) >= 19 # e.g., "2025-12-15 16:27:44 +0000" + assert comment == "Test comment" @patch("esphome.writer.CORE") @@ -1206,6 +1208,7 @@ def test_get_build_info_always_returns_current_time( build_info_path = tmp_path / "build_info.json" mock_core.relative_build_path.return_value = build_info_path mock_core.config_hash = 0x12345678 + mock_core.comment = "" # Create existing build_info.json with matching config_hash and version existing_build_time = 1700000000 @@ -1222,7 +1225,7 @@ def test_get_build_info_always_returns_current_time( ) with patch("esphome.writer.__version__", "2025.1.0-dev"): - config_hash, build_time, build_time_str = get_build_info() + config_hash, build_time, build_time_str, comment = get_build_info() assert config_hash == 0x12345678 # get_build_info now always returns current time @@ -1240,6 +1243,7 @@ def test_get_build_info_config_changed( build_info_path = tmp_path / "build_info.json" mock_core.relative_build_path.return_value = build_info_path mock_core.config_hash = 0xABCDEF00 # Different from existing + mock_core.comment = "" # Create existing build_info.json with different config_hash existing_build_time = 1700000000 @@ -1255,7 +1259,7 @@ def test_get_build_info_config_changed( ) with patch("esphome.writer.__version__", "2025.1.0-dev"): - config_hash, build_time, build_time_str = get_build_info() + config_hash, build_time, build_time_str, comment = get_build_info() assert config_hash == 0xABCDEF00 assert build_time != existing_build_time # New time generated @@ -1271,6 +1275,7 @@ def test_get_build_info_version_changed( build_info_path = tmp_path / "build_info.json" mock_core.relative_build_path.return_value = build_info_path mock_core.config_hash = 0x12345678 + mock_core.comment = "" # Create existing build_info.json with different version existing_build_time = 1700000000 @@ -1286,7 +1291,7 @@ def test_get_build_info_version_changed( ) with patch("esphome.writer.__version__", "2025.1.0-dev"): # New version - config_hash, build_time, build_time_str = get_build_info() + config_hash, build_time, build_time_str, comment = get_build_info() assert config_hash == 0x12345678 assert build_time != existing_build_time # New time generated @@ -1302,11 +1307,12 @@ def test_get_build_info_invalid_json( build_info_path = tmp_path / "build_info.json" mock_core.relative_build_path.return_value = build_info_path mock_core.config_hash = 0x12345678 + mock_core.comment = "" # Create invalid JSON file build_info_path.write_text("not valid json {{{") - config_hash, build_time, build_time_str = get_build_info() + config_hash, build_time, build_time_str, comment = get_build_info() assert config_hash == 0x12345678 assert isinstance(build_time, int) @@ -1322,12 +1328,13 @@ def test_get_build_info_missing_keys( build_info_path = tmp_path / "build_info.json" mock_core.relative_build_path.return_value = build_info_path mock_core.config_hash = 0x12345678 + mock_core.comment = "" # Create JSON with missing keys build_info_path.write_text(json.dumps({"config_hash": 0x12345678})) with patch("esphome.writer.__version__", "2025.1.0-dev"): - config_hash, build_time, build_time_str = get_build_info() + config_hash, build_time, build_time_str, comment = get_build_info() assert config_hash == 0x12345678 assert isinstance(build_time, int) @@ -1343,8 +1350,9 @@ def test_get_build_info_build_time_str_format( build_info_path = tmp_path / "build_info.json" mock_core.relative_build_path.return_value = build_info_path mock_core.config_hash = 0x12345678 + mock_core.comment = "" - config_hash, build_time, build_time_str = get_build_info() + config_hash, build_time, build_time_str, comment = get_build_info() # Verify the format matches "%Y-%m-%d %H:%M:%S %z" # e.g., "2025-12-15 16:27:44 +0000" @@ -1357,36 +1365,73 @@ def test_generate_build_info_data_h_format() -> None: config_hash = 0x12345678 build_time = 1700000000 build_time_str = "2023-11-14 22:13:20 +0000" + comment = "Test comment" - result = generate_build_info_data_h(config_hash, build_time, build_time_str) + result = generate_build_info_data_h( + config_hash, build_time, build_time_str, comment + ) assert "#pragma once" in result assert "#define ESPHOME_CONFIG_HASH 0x12345678U" in result assert "#define ESPHOME_BUILD_TIME 1700000000" in result + assert "#define ESPHOME_COMMENT_SIZE 13" in result # len("Test comment") + 1 assert 'ESPHOME_BUILD_TIME_STR[] = "2023-11-14 22:13:20 +0000"' in result + assert 'ESPHOME_COMMENT_STR[] = "Test comment"' in result def test_generate_build_info_data_h_esp8266_progmem() -> None: """Test generate_build_info_data_h includes PROGMEM for ESP8266.""" - result = generate_build_info_data_h(0xABCDEF01, 1700000000, "test") + result = generate_build_info_data_h(0xABCDEF01, 1700000000, "test", "comment") # Should have ESP8266 PROGMEM conditional assert "#ifdef USE_ESP8266" in result assert "#include " in result assert "PROGMEM" in result + # Both build time and comment should have PROGMEM versions + assert 'ESPHOME_BUILD_TIME_STR[] PROGMEM = "test"' in result + assert 'ESPHOME_COMMENT_STR[] PROGMEM = "comment"' in result def test_generate_build_info_data_h_hash_formatting() -> None: """Test generate_build_info_data_h formats hash with leading zeros.""" # Test with small hash value that needs leading zeros - result = generate_build_info_data_h(0x00000001, 0, "test") + result = generate_build_info_data_h(0x00000001, 0, "test", "") assert "#define ESPHOME_CONFIG_HASH 0x00000001U" in result # Test with larger hash value - result = generate_build_info_data_h(0xFFFFFFFF, 0, "test") + result = generate_build_info_data_h(0xFFFFFFFF, 0, "test", "") assert "#define ESPHOME_CONFIG_HASH 0xffffffffU" in result +def test_generate_build_info_data_h_comment_escaping() -> None: + r"""Test generate_build_info_data_h properly escapes special characters in comment. + + Uses cpp_string_escape which outputs octal escapes for special characters: + - backslash (ASCII 92) -> \134 + - double quote (ASCII 34) -> \042 + - newline (ASCII 10) -> \012 + """ + # Test backslash escaping (ASCII 92 = octal 134) + result = generate_build_info_data_h(0, 0, "test", "backslash\\here") + assert 'ESPHOME_COMMENT_STR[] = "backslash\\134here"' in result + + # Test quote escaping (ASCII 34 = octal 042) + result = generate_build_info_data_h(0, 0, "test", 'has "quotes"') + assert 'ESPHOME_COMMENT_STR[] = "has \\042quotes\\042"' in result + + # Test newline escaping (ASCII 10 = octal 012) + result = generate_build_info_data_h(0, 0, "test", "line1\nline2") + assert 'ESPHOME_COMMENT_STR[] = "line1\\012line2"' in result + + +def test_generate_build_info_data_h_empty_comment() -> None: + """Test generate_build_info_data_h handles empty comment.""" + result = generate_build_info_data_h(0, 0, "test", "") + + assert "#define ESPHOME_COMMENT_SIZE 1" in result # Just null terminator + assert 'ESPHOME_COMMENT_STR[] = ""' in result + + @patch("esphome.writer.CORE") @patch("esphome.writer.iter_components") @patch("esphome.writer.walk_files") @@ -1445,6 +1490,7 @@ def test_copy_src_tree_writes_build_info_files( mock_core.relative_build_path.side_effect = lambda *args: build_path.joinpath(*args) mock_core.defines = [] mock_core.config_hash = 0xDEADBEEF + mock_core.comment = "Test comment" mock_core.target_platform = "test_platform" mock_core.config = {} mock_iter_components.return_value = [("core", mock_component)] @@ -1466,6 +1512,8 @@ def test_copy_src_tree_writes_build_info_files( assert "#define ESPHOME_CONFIG_HASH 0xdeadbeefU" in build_info_h_content assert "#define ESPHOME_BUILD_TIME" in build_info_h_content assert "ESPHOME_BUILD_TIME_STR" in build_info_h_content + assert "#define ESPHOME_COMMENT_SIZE" in build_info_h_content + assert "ESPHOME_COMMENT_STR" in build_info_h_content # Verify build_info.json was written build_info_json_path = build_path / "build_info.json" @@ -1517,6 +1565,7 @@ def test_copy_src_tree_detects_config_hash_change( mock_core.relative_build_path.side_effect = lambda *args: build_path.joinpath(*args) mock_core.defines = [] mock_core.config_hash = 0xDEADBEEF # Different from existing + mock_core.comment = "" mock_core.target_platform = "test_platform" mock_core.config = {} mock_iter_components.return_value = [] @@ -1578,6 +1627,7 @@ def test_copy_src_tree_detects_version_change( mock_core.relative_build_path.side_effect = lambda *args: build_path.joinpath(*args) mock_core.defines = [] mock_core.config_hash = 0xDEADBEEF + mock_core.comment = "" mock_core.target_platform = "test_platform" mock_core.config = {} mock_iter_components.return_value = [] @@ -1627,6 +1677,7 @@ def test_copy_src_tree_handles_invalid_build_info_json( mock_core.relative_build_path.side_effect = lambda *args: build_path.joinpath(*args) mock_core.defines = [] mock_core.config_hash = 0xDEADBEEF + mock_core.comment = "" mock_core.target_platform = "test_platform" mock_core.config = {} mock_iter_components.return_value = [] @@ -1700,6 +1751,7 @@ def test_copy_src_tree_build_info_timestamp_behavior( mock_core.relative_build_path.side_effect = lambda *args: build_path.joinpath(*args) mock_core.defines = [] mock_core.config_hash = 0xDEADBEEF + mock_core.comment = "" mock_core.target_platform = "test_platform" mock_core.config = {} mock_iter_components.return_value = [("test", mock_component)] @@ -1794,6 +1846,7 @@ def test_copy_src_tree_detects_removed_source_file( mock_core.relative_build_path.side_effect = lambda *args: build_path.joinpath(*args) mock_core.defines = [] mock_core.config_hash = 0xDEADBEEF + mock_core.comment = "" mock_core.target_platform = "test_platform" mock_core.config = {} mock_iter_components.return_value = [] # No components = file should be removed @@ -1855,6 +1908,7 @@ def test_copy_src_tree_ignores_removed_generated_file( mock_core.relative_build_path.side_effect = lambda *args: build_path.joinpath(*args) mock_core.defines = [] mock_core.config_hash = 0xDEADBEEF + mock_core.comment = "" mock_core.target_platform = "test_platform" mock_core.config = {} mock_iter_components.return_value = [] From af0d4d2c2cfd6c955bd2903af7a4039d7793c1cf Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 22 Dec 2025 11:56:07 -1000 Subject: [PATCH 008/302] [web_server] Use stack buffers for value formatting to reduce flash usage (#12575) --- esphome/components/web_server/web_server.cpp | 68 +++++++++++--------- esphome/core/helpers.cpp | 34 ++++++---- esphome/core/helpers.h | 11 +++- 3 files changed, 68 insertions(+), 45 deletions(-) diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index b0731f335b..df8a5364cf 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -432,7 +432,7 @@ static void set_json_value(JsonObject &root, EntityBase *obj, const char *prefix } template -static void set_json_icon_state_value(JsonObject &root, EntityBase *obj, const char *prefix, const std::string &state, +static void set_json_icon_state_value(JsonObject &root, EntityBase *obj, const char *prefix, const char *state, const T &value, JsonDetail start_config) { set_json_value(root, obj, prefix, value, start_config); root[ESPHOME_F("state")] = state; @@ -475,9 +475,10 @@ std::string WebServer::sensor_json_(sensor::Sensor *obj, float value, JsonDetail JsonObject root = builder.root(); const auto uom_ref = obj->get_unit_of_measurement_ref(); - - std::string state = - std::isnan(value) ? "NA" : value_accuracy_with_uom_to_string(value, obj->get_accuracy_decimals(), uom_ref); + char buf[VALUE_ACCURACY_MAX_LEN]; + const char *state = std::isnan(value) + ? "NA" + : (value_accuracy_with_uom_to_buf(buf, value, obj->get_accuracy_decimals(), uom_ref), buf); set_json_icon_state_value(root, obj, "sensor", state, value, start_config); if (start_config == DETAIL_ALL) { this->add_sorting_info_(root, obj); @@ -522,7 +523,7 @@ std::string WebServer::text_sensor_json_(text_sensor::TextSensor *obj, const std json::JsonBuilder builder; JsonObject root = builder.root(); - set_json_icon_state_value(root, obj, "text_sensor", value, value, start_config); + set_json_icon_state_value(root, obj, "text_sensor", value.c_str(), value.c_str(), start_config); if (start_config == DETAIL_ALL) { this->add_sorting_info_(root, obj); } @@ -974,21 +975,20 @@ std::string WebServer::number_json_(number::Number *obj, float value, JsonDetail JsonObject root = builder.root(); const auto uom_ref = obj->traits.get_unit_of_measurement_ref(); + const int8_t accuracy = step_to_accuracy_decimals(obj->traits.get_step()); - std::string val_str = std::isnan(value) - ? "\"NaN\"" - : value_accuracy_to_string(value, step_to_accuracy_decimals(obj->traits.get_step())); - std::string state_str = std::isnan(value) ? "NA" - : value_accuracy_with_uom_to_string( - value, step_to_accuracy_decimals(obj->traits.get_step()), uom_ref); + // Need two buffers: one for value, one for state with UOM + char val_buf[VALUE_ACCURACY_MAX_LEN]; + char state_buf[VALUE_ACCURACY_MAX_LEN]; + const char *val_str = std::isnan(value) ? "\"NaN\"" : (value_accuracy_to_buf(val_buf, value, accuracy), val_buf); + const char *state_str = + std::isnan(value) ? "NA" : (value_accuracy_with_uom_to_buf(state_buf, value, accuracy, uom_ref), state_buf); set_json_icon_state_value(root, obj, "number", state_str, val_str, start_config); if (start_config == DETAIL_ALL) { - root[ESPHOME_F("min_value")] = - value_accuracy_to_string(obj->traits.get_min_value(), step_to_accuracy_decimals(obj->traits.get_step())); - root[ESPHOME_F("max_value")] = - value_accuracy_to_string(obj->traits.get_max_value(), step_to_accuracy_decimals(obj->traits.get_step())); - root[ESPHOME_F("step")] = - value_accuracy_to_string(obj->traits.get_step(), step_to_accuracy_decimals(obj->traits.get_step())); + // ArduinoJson copies the string immediately, so we can reuse val_buf + root[ESPHOME_F("min_value")] = (value_accuracy_to_buf(val_buf, obj->traits.get_min_value(), accuracy), val_buf); + root[ESPHOME_F("max_value")] = (value_accuracy_to_buf(val_buf, obj->traits.get_max_value(), accuracy), val_buf); + root[ESPHOME_F("step")] = (value_accuracy_to_buf(val_buf, obj->traits.get_step(), accuracy), val_buf); root[ESPHOME_F("mode")] = (int) obj->traits.get_mode(); if (!uom_ref.empty()) root[ESPHOME_F("uom")] = uom_ref; @@ -1230,8 +1230,8 @@ std::string WebServer::text_json_(text::Text *obj, const std::string &value, Jso json::JsonBuilder builder; JsonObject root = builder.root(); - std::string state = obj->traits.get_mode() == text::TextMode::TEXT_MODE_PASSWORD ? "********" : value; - set_json_icon_state_value(root, obj, "text", state, value, start_config); + const char *state = obj->traits.get_mode() == text::TextMode::TEXT_MODE_PASSWORD ? "********" : value.c_str(); + set_json_icon_state_value(root, obj, "text", state, value.c_str(), start_config); root[ESPHOME_F("min_length")] = obj->traits.get_min_length(); root[ESPHOME_F("max_length")] = obj->traits.get_max_length(); root[ESPHOME_F("pattern")] = obj->traits.get_pattern_c_str(); @@ -1359,6 +1359,7 @@ std::string WebServer::climate_json_(climate::Climate *obj, JsonDetail start_con int8_t target_accuracy = traits.get_target_temperature_accuracy_decimals(); int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals(); char buf[PSTR_LOCAL_SIZE]; + char temp_buf[VALUE_ACCURACY_MAX_LEN]; if (start_config == DETAIL_ALL) { JsonArray opt = root[ESPHOME_F("modes")].to(); @@ -1395,8 +1396,10 @@ std::string WebServer::climate_json_(climate::Climate *obj, JsonDetail start_con bool has_state = false; root[ESPHOME_F("mode")] = PSTR_LOCAL(climate_mode_to_string(obj->mode)); - root[ESPHOME_F("max_temp")] = value_accuracy_to_string(traits.get_visual_max_temperature(), target_accuracy); - root[ESPHOME_F("min_temp")] = value_accuracy_to_string(traits.get_visual_min_temperature(), target_accuracy); + root[ESPHOME_F("max_temp")] = + (value_accuracy_to_buf(temp_buf, traits.get_visual_max_temperature(), target_accuracy), temp_buf); + root[ESPHOME_F("min_temp")] = + (value_accuracy_to_buf(temp_buf, traits.get_visual_min_temperature(), target_accuracy), temp_buf); root[ESPHOME_F("step")] = traits.get_visual_target_temperature_step(); if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_ACTION)) { root[ESPHOME_F("action")] = PSTR_LOCAL(climate_action_to_string(obj->action)); @@ -1419,23 +1422,26 @@ std::string WebServer::climate_json_(climate::Climate *obj, JsonDetail start_con root[ESPHOME_F("swing_mode")] = PSTR_LOCAL(climate_swing_mode_to_string(obj->swing_mode)); } if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_TEMPERATURE)) { - if (!std::isnan(obj->current_temperature)) { - root[ESPHOME_F("current_temperature")] = value_accuracy_to_string(obj->current_temperature, current_accuracy); - } else { - root[ESPHOME_F("current_temperature")] = "NA"; - } + root[ESPHOME_F("current_temperature")] = + std::isnan(obj->current_temperature) + ? "NA" + : (value_accuracy_to_buf(temp_buf, obj->current_temperature, current_accuracy), temp_buf); } if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE | climate::CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE)) { - root[ESPHOME_F("target_temperature_low")] = value_accuracy_to_string(obj->target_temperature_low, target_accuracy); + root[ESPHOME_F("target_temperature_low")] = + (value_accuracy_to_buf(temp_buf, obj->target_temperature_low, target_accuracy), temp_buf); root[ESPHOME_F("target_temperature_high")] = - value_accuracy_to_string(obj->target_temperature_high, target_accuracy); + (value_accuracy_to_buf(temp_buf, obj->target_temperature_high, target_accuracy), temp_buf); if (!has_state) { - root[ESPHOME_F("state")] = value_accuracy_to_string( - (obj->target_temperature_high + obj->target_temperature_low) / 2.0f, target_accuracy); + root[ESPHOME_F("state")] = + (value_accuracy_to_buf(temp_buf, (obj->target_temperature_high + obj->target_temperature_low) / 2.0f, + target_accuracy), + temp_buf); } } else { - root[ESPHOME_F("target_temperature")] = value_accuracy_to_string(obj->target_temperature, target_accuracy); + root[ESPHOME_F("target_temperature")] = + (value_accuracy_to_buf(temp_buf, obj->target_temperature, target_accuracy), temp_buf); if (!has_state) root[ESPHOME_F("state")] = root[ESPHOME_F("target_temperature")]; } diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index f55f53f16b..d7d32ea28f 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -383,23 +383,33 @@ static inline void normalize_accuracy_decimals(float &value, int8_t &accuracy_de } std::string value_accuracy_to_string(float value, int8_t accuracy_decimals) { - normalize_accuracy_decimals(value, accuracy_decimals); - char tmp[32]; // should be enough, but we should maybe improve this at some point. - snprintf(tmp, sizeof(tmp), "%.*f", accuracy_decimals, value); - return std::string(tmp); + char buf[VALUE_ACCURACY_MAX_LEN]; + value_accuracy_to_buf(buf, value, accuracy_decimals); + return std::string(buf); } -std::string value_accuracy_with_uom_to_string(float value, int8_t accuracy_decimals, StringRef unit_of_measurement) { +size_t value_accuracy_to_buf(std::span buf, float value, int8_t accuracy_decimals) { normalize_accuracy_decimals(value, accuracy_decimals); - // Buffer sized for float (up to ~15 chars) + space + typical UOM (usually <20 chars like "μS/cm") - // snprintf truncates safely if exceeded, though ESPHome UOMs are typically short - char tmp[64]; + // snprintf returns chars that would be written (excluding null), or negative on error + int len = snprintf(buf.data(), buf.size(), "%.*f", accuracy_decimals, value); + if (len < 0) + return 0; // encoding error + // On truncation, snprintf returns would-be length; actual written is buf.size() - 1 + return static_cast(len) >= buf.size() ? buf.size() - 1 : static_cast(len); +} + +size_t value_accuracy_with_uom_to_buf(std::span buf, float value, + int8_t accuracy_decimals, StringRef unit_of_measurement) { if (unit_of_measurement.empty()) { - snprintf(tmp, sizeof(tmp), "%.*f", accuracy_decimals, value); - } else { - snprintf(tmp, sizeof(tmp), "%.*f %s", accuracy_decimals, value, unit_of_measurement.c_str()); + return value_accuracy_to_buf(buf, value, accuracy_decimals); } - return std::string(tmp); + normalize_accuracy_decimals(value, accuracy_decimals); + // snprintf returns chars that would be written (excluding null), or negative on error + int len = snprintf(buf.data(), buf.size(), "%.*f %s", accuracy_decimals, value, unit_of_measurement.c_str()); + if (len < 0) + return 0; // encoding error + // On truncation, snprintf returns would-be length; actual written is buf.size() - 1 + return static_cast(len) >= buf.size() ? buf.size() - 1 : static_cast(len); } int8_t step_to_accuracy_decimals(float step) { diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index b575a14d14..769041160c 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -886,8 +886,15 @@ ParseOnOffState parse_on_off(const char *str, const char *on = nullptr, const ch /// Create a string from a value and an accuracy in decimals. std::string value_accuracy_to_string(float value, int8_t accuracy_decimals); -/// Create a string from a value, an accuracy in decimals, and a unit of measurement. -std::string value_accuracy_with_uom_to_string(float value, int8_t accuracy_decimals, StringRef unit_of_measurement); + +/// Maximum buffer size for value_accuracy formatting (float ~15 chars + space + UOM ~40 chars + null) +static constexpr size_t VALUE_ACCURACY_MAX_LEN = 64; + +/// Format value with accuracy to buffer, returns chars written (excluding null) +size_t value_accuracy_to_buf(std::span buf, float value, int8_t accuracy_decimals); +/// Format value with accuracy and UOM to buffer, returns chars written (excluding null) +size_t value_accuracy_with_uom_to_buf(std::span buf, float value, + int8_t accuracy_decimals, StringRef unit_of_measurement); /// Derive accuracy in decimals from an increment step. int8_t step_to_accuracy_decimals(float step); From 1b31253287343b150a01a3a04e8673dabc68f73e Mon Sep 17 00:00:00 2001 From: eoasmxd <42328021+eoasmxd@users.noreply.github.com> Date: Tue, 23 Dec 2025 06:19:48 +0800 Subject: [PATCH 009/302] Add Event Component to UART (#11765) Co-authored-by: J. Nick Koston --- CODEOWNERS | 1 + esphome/components/uart/event/__init__.py | 90 ++++++++++++++++++++ esphome/components/uart/event/uart_event.cpp | 48 +++++++++++ esphome/components/uart/event/uart_event.h | 31 +++++++ tests/components/uart/test.esp32-idf.yaml | 8 ++ tests/components/uart/test.esp8266-ard.yaml | 8 ++ 6 files changed, 186 insertions(+) create mode 100644 esphome/components/uart/event/__init__.py create mode 100644 esphome/components/uart/event/uart_event.cpp create mode 100644 esphome/components/uart/event/uart_event.h diff --git a/CODEOWNERS b/CODEOWNERS index 941c2e2849..f95d68a46d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -519,6 +519,7 @@ esphome/components/tuya/switch/* @jesserockz esphome/components/tuya/text_sensor/* @dentra esphome/components/uart/* @esphome/core esphome/components/uart/button/* @ssieb +esphome/components/uart/event/* @eoasmxd esphome/components/uart/packet_transport/* @clydebarrow esphome/components/udp/* @clydebarrow esphome/components/ufire_ec/* @pvizeli diff --git a/esphome/components/uart/event/__init__.py b/esphome/components/uart/event/__init__.py new file mode 100644 index 0000000000..64af318a11 --- /dev/null +++ b/esphome/components/uart/event/__init__.py @@ -0,0 +1,90 @@ +import esphome.codegen as cg +from esphome.components import event, uart +import esphome.config_validation as cv +from esphome.const import CONF_EVENT_TYPES, CONF_ID +from esphome.core import ID +from esphome.types import ConfigType + +from .. import uart_ns + +CODEOWNERS = ["@eoasmxd"] + +DEPENDENCIES = ["uart"] + +UARTEvent = uart_ns.class_("UARTEvent", event.Event, uart.UARTDevice, cg.Component) + + +def validate_event_types(value) -> list[tuple[str, str | list[int]]]: + if not isinstance(value, list): + raise cv.Invalid("Event type must be a list of key-value mappings.") + + processed: list[tuple[str, str | list[int]]] = [] + for item in value: + if not isinstance(item, dict): + raise cv.Invalid(f"Event type item must be a mapping (dictionary): {item}") + if len(item) != 1: + raise cv.Invalid( + f"Event type item must be a single key-value mapping: {item}" + ) + + # Get the single key-value pair + event_name, match_data = next(iter(item.items())) + + if not isinstance(event_name, str): + raise cv.Invalid(f"Event name (key) must be a string: {event_name}") + + try: + # Try to validate as list of hex bytes + match_data_bin = cv.ensure_list(cv.hex_uint8_t)(match_data) + processed.append((event_name, match_data_bin)) + continue + except cv.Invalid: + pass # Not binary, try string + + try: + # Try to validate as string + match_data_str = cv.string_strict(match_data) + processed.append((event_name, match_data_str)) + continue + except cv.Invalid: + pass # Not string either + + # If neither validation passed + raise cv.Invalid( + f"Event match data for '{event_name}' must be a string or a list of hex bytes. Invalid data: {match_data}" + ) + + if not processed: + raise cv.Invalid("event_types must contain at least one event mapping.") + + return processed + + +CONFIG_SCHEMA = ( + event.event_schema(UARTEvent) + .extend( + { + cv.Required(CONF_EVENT_TYPES): validate_event_types, + } + ) + .extend(uart.UART_DEVICE_SCHEMA) + .extend(cv.COMPONENT_SCHEMA) +) + + +async def to_code(config: ConfigType) -> None: + event_names = [item[0] for item in config[CONF_EVENT_TYPES]] + var = await event.new_event(config, event_types=event_names) + await cg.register_component(var, config) + await uart.register_uart_device(var, config) + for i, (event_name, match_data) in enumerate(config[CONF_EVENT_TYPES]): + if isinstance(match_data, str): + match_data = [ord(c) for c in match_data] + + match_data_var_id = ID( + f"match_data_{config[CONF_ID]}_{i}", is_declaration=True, type=cg.uint8 + ) + match_data_var = cg.static_const_array( + match_data_var_id, cg.ArrayInitializer(*match_data) + ) + cg.add(var.add_event_matcher(event_name, match_data_var, len(match_data))) diff --git a/esphome/components/uart/event/uart_event.cpp b/esphome/components/uart/event/uart_event.cpp new file mode 100644 index 0000000000..02c5f2e631 --- /dev/null +++ b/esphome/components/uart/event/uart_event.cpp @@ -0,0 +1,48 @@ +#include "uart_event.h" +#include "esphome/core/log.h" +#include + +namespace esphome::uart { + +static const char *const TAG = "uart.event"; + +void UARTEvent::setup() {} + +void UARTEvent::dump_config() { LOG_EVENT("", "UART Event", this); } + +void UARTEvent::loop() { this->read_data_(); } + +void UARTEvent::add_event_matcher(const char *event_name, const uint8_t *match_data, size_t match_data_len) { + this->matchers_.push_back({event_name, match_data, match_data_len}); + if (match_data_len > this->max_matcher_len_) { + this->max_matcher_len_ = match_data_len; + } +} + +void UARTEvent::read_data_() { + while (this->available()) { + uint8_t data; + this->read_byte(&data); + this->buffer_.push_back(data); + + bool match_found = false; + for (const auto &matcher : this->matchers_) { + if (this->buffer_.size() < matcher.data_len) { + continue; + } + + if (std::equal(matcher.data, matcher.data + matcher.data_len, this->buffer_.end() - matcher.data_len)) { + this->trigger(matcher.event_name); + this->buffer_.clear(); + match_found = true; + break; + } + } + + if (!match_found && this->max_matcher_len_ > 0 && this->buffer_.size() > this->max_matcher_len_) { + this->buffer_.erase(this->buffer_.begin()); + } + } +} + +} // namespace esphome::uart diff --git a/esphome/components/uart/event/uart_event.h b/esphome/components/uart/event/uart_event.h new file mode 100644 index 0000000000..8a00b5894b --- /dev/null +++ b/esphome/components/uart/event/uart_event.h @@ -0,0 +1,31 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/components/event/event.h" +#include "esphome/components/uart/uart.h" +#include + +namespace esphome::uart { + +class UARTEvent : public event::Event, public UARTDevice, public Component { + public: + void setup() override; + void loop() override; + void dump_config() override; + + void add_event_matcher(const char *event_name, const uint8_t *match_data, size_t match_data_len); + + protected: + struct EventMatcher { + const char *event_name; + const uint8_t *data; + size_t data_len; + }; + + void read_data_(); + std::vector matchers_; + std::vector buffer_; + size_t max_matcher_len_ = 0; +}; + +} // namespace esphome::uart diff --git a/tests/components/uart/test.esp32-idf.yaml b/tests/components/uart/test.esp32-idf.yaml index 6ffd0d7282..2a97f9a5de 100644 --- a/tests/components/uart/test.esp32-idf.yaml +++ b/tests/components/uart/test.esp32-idf.yaml @@ -75,3 +75,11 @@ button: - uart.write: !lambda |- std::string cmd = "VALUE=" + str_sprintf("%.0f", id(test_number).state) + "\r\n"; return std::vector(cmd.begin(), cmd.end()); + +event: + - platform: uart + uart_id: uart_uart + name: "UART Event" + event_types: + - "string_event_A": "*A#" + - "bytes_event_B": [0x2A, 0x42, 0x23] diff --git a/tests/components/uart/test.esp8266-ard.yaml b/tests/components/uart/test.esp8266-ard.yaml index 566038ee3e..c2670b289a 100644 --- a/tests/components/uart/test.esp8266-ard.yaml +++ b/tests/components/uart/test.esp8266-ard.yaml @@ -31,3 +31,11 @@ button: name: "UART Button" uart_id: uart_uart data: [0xFF, 0xEE] + +event: + - platform: uart + uart_id: uart_uart + name: "UART Event" + event_types: + - "string_event_A": "*A#" + - "bytes_event_B": [0x2A, 0x42, 0x23] From b4c92dd8cbbf61810e876c3fbb3ca0ebaa199600 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 22 Dec 2025 14:29:47 -1000 Subject: [PATCH 010/302] [logger] Zephyr: Use k_str_out() with known length instead of printk() (#12619) --- esphome/components/logger/logger.h | 4 ++-- esphome/components/logger/logger_zephyr.cpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/esphome/components/logger/logger.h b/esphome/components/logger/logger.h index 36195b919a..2cedd7a76f 100644 --- a/esphome/components/logger/logger.h +++ b/esphome/components/logger/logger.h @@ -118,11 +118,11 @@ static constexpr uint16_t MAX_HEADER_SIZE = 128; static constexpr size_t MAX_POINTER_REPRESENTATION = 2 + sizeof(void *) * 2 + 1; // Platform-specific: does write_msg_ add its own newline? -// false: Caller must add newline to buffer before calling write_msg_ (ESP32, ESP8266, RP2040, LibreTiny) +// false: Caller must add newline to buffer before calling write_msg_ (ESP32, ESP8266, RP2040, LibreTiny, Zephyr) // Allows single write call with newline included for efficiency // true: write_msg_ adds newline itself via puts()/println() (other platforms) // Newline should NOT be added to buffer -#if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_LIBRETINY) +#if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR) static constexpr bool WRITE_MSG_ADDS_NEWLINE = false; #else static constexpr bool WRITE_MSG_ADDS_NEWLINE = true; diff --git a/esphome/components/logger/logger_zephyr.cpp b/esphome/components/logger/logger_zephyr.cpp index ec2ff3013c..330dfa96ec 100644 --- a/esphome/components/logger/logger_zephyr.cpp +++ b/esphome/components/logger/logger_zephyr.cpp @@ -6,6 +6,7 @@ #include #include +#include #include namespace esphome::logger { @@ -14,7 +15,7 @@ static const char *const TAG = "logger"; #ifdef USE_LOGGER_USB_CDC void Logger::loop() { - if (this->uart_ != UART_SELECTION_USB_CDC || nullptr == this->uart_dev_) { + if (this->uart_ != UART_SELECTION_USB_CDC || this->uart_dev_ == nullptr) { return; } static bool opened = false; @@ -62,18 +63,17 @@ void Logger::pre_setup() { ESP_LOGI(TAG, "Log initialized"); } -void HOT Logger::write_msg_(const char *msg, size_t) { +void HOT Logger::write_msg_(const char *msg, size_t len) { + // Single write with newline already in buffer (added by caller) #ifdef CONFIG_PRINTK - printk("%s\n", msg); + k_str_out(const_cast(msg), len); #endif - if (nullptr == this->uart_dev_) { + if (this->uart_dev_ == nullptr) { return; } - while (*msg) { - uart_poll_out(this->uart_dev_, *msg); - ++msg; + for (size_t i = 0; i < len; ++i) { + uart_poll_out(this->uart_dev_, msg[i]); } - uart_poll_out(this->uart_dev_, '\n'); } const LogString *Logger::get_uart_selection_() { From 7d5342bca5df37ba48e735342f72f3d615a01555 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 22 Dec 2025 16:45:22 -1000 Subject: [PATCH 011/302] [logger] Host: Use fwrite() with explicit length and remove platform branching (#12628) --- esphome/components/logger/logger.cpp | 4 +-- esphome/components/logger/logger.h | 41 ++++++++--------------- esphome/components/logger/logger_host.cpp | 23 ++++++++----- 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/esphome/components/logger/logger.cpp b/esphome/components/logger/logger.cpp index 21e2b44808..474eb9ec38 100644 --- a/esphome/components/logger/logger.cpp +++ b/esphome/components/logger/logger.cpp @@ -65,8 +65,8 @@ void HOT Logger::log_vprintf_(uint8_t level, const char *tag, int line, const ch uint16_t buffer_at = 0; // Initialize buffer position this->format_log_to_buffer_with_terminator_(level, tag, line, format, args, console_buffer, &buffer_at, MAX_CONSOLE_LOG_MSG_SIZE); - // Add newline if platform needs it (ESP32 doesn't add via write_msg_) - this->add_newline_to_buffer_if_needed_(console_buffer, &buffer_at, MAX_CONSOLE_LOG_MSG_SIZE); + // Add newline before writing to console + this->add_newline_to_buffer_(console_buffer, &buffer_at, MAX_CONSOLE_LOG_MSG_SIZE); this->write_msg_(console_buffer, buffer_at); } diff --git a/esphome/components/logger/logger.h b/esphome/components/logger/logger.h index 2cedd7a76f..ba8d4667b6 100644 --- a/esphome/components/logger/logger.h +++ b/esphome/components/logger/logger.h @@ -117,17 +117,6 @@ static constexpr uint16_t MAX_HEADER_SIZE = 128; // "0x" + 2 hex digits per byte + '\0' static constexpr size_t MAX_POINTER_REPRESENTATION = 2 + sizeof(void *) * 2 + 1; -// Platform-specific: does write_msg_ add its own newline? -// false: Caller must add newline to buffer before calling write_msg_ (ESP32, ESP8266, RP2040, LibreTiny, Zephyr) -// Allows single write call with newline included for efficiency -// true: write_msg_ adds newline itself via puts()/println() (other platforms) -// Newline should NOT be added to buffer -#if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR) -static constexpr bool WRITE_MSG_ADDS_NEWLINE = false; -#else -static constexpr bool WRITE_MSG_ADDS_NEWLINE = true; -#endif - #if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR) /** Enum for logging UART selection * @@ -259,22 +248,20 @@ class Logger : public Component { } } - // Helper to add newline to buffer for platforms that need it + // Helper to add newline to buffer before writing to console // Modifies buffer_at to include the newline - inline void HOT add_newline_to_buffer_if_needed_(char *buffer, uint16_t *buffer_at, uint16_t buffer_size) { - if constexpr (!WRITE_MSG_ADDS_NEWLINE) { - // Add newline - don't need to maintain null termination - // write_msg_ now always receives explicit length, so we can safely overwrite the null terminator - // This is safe because: - // 1. Callbacks already received the message (before we add newline) - // 2. write_msg_ receives the length explicitly (doesn't need null terminator) - if (*buffer_at < buffer_size) { - buffer[(*buffer_at)++] = '\n'; - } else if (buffer_size > 0) { - // Buffer was full - replace last char with newline to ensure it's visible - buffer[buffer_size - 1] = '\n'; - *buffer_at = buffer_size; - } + inline void HOT add_newline_to_buffer_(char *buffer, uint16_t *buffer_at, uint16_t buffer_size) { + // Add newline - don't need to maintain null termination + // write_msg_ receives explicit length, so we can safely overwrite the null terminator + // This is safe because: + // 1. Callbacks already received the message (before we add newline) + // 2. write_msg_ receives the length explicitly (doesn't need null terminator) + if (*buffer_at < buffer_size) { + buffer[(*buffer_at)++] = '\n'; + } else if (buffer_size > 0) { + // Buffer was full - replace last char with newline to ensure it's visible + buffer[buffer_size - 1] = '\n'; + *buffer_at = buffer_size; } } @@ -283,7 +270,7 @@ class Logger : public Component { inline void HOT write_tx_buffer_to_console_(uint16_t offset = 0, uint16_t *length = nullptr) { if (this->baud_rate_ > 0) { uint16_t *len_ptr = length ? length : &this->tx_buffer_at_; - this->add_newline_to_buffer_if_needed_(this->tx_buffer_ + offset, len_ptr, this->tx_buffer_size_ - offset); + this->add_newline_to_buffer_(this->tx_buffer_ + offset, len_ptr, this->tx_buffer_size_ - offset); this->write_msg_(this->tx_buffer_ + offset, *len_ptr); } } diff --git a/esphome/components/logger/logger_host.cpp b/esphome/components/logger/logger_host.cpp index c5e1e6f865..cbca06e431 100644 --- a/esphome/components/logger/logger_host.cpp +++ b/esphome/components/logger/logger_host.cpp @@ -3,16 +3,23 @@ namespace esphome::logger { -void HOT Logger::write_msg_(const char *msg, size_t) { - time_t rawtime; - struct tm *timeinfo; - char buffer[80]; +void HOT Logger::write_msg_(const char *msg, size_t len) { + static constexpr size_t TIMESTAMP_LEN = 10; // "[HH:MM:SS]" + // tx_buffer_size_ defaults to 512, so 768 covers default + headroom + char buffer[TIMESTAMP_LEN + 768]; + time_t rawtime; time(&rawtime); - timeinfo = localtime(&rawtime); - strftime(buffer, sizeof buffer, "[%H:%M:%S]", timeinfo); - fputs(buffer, stdout); - puts(msg); + struct tm *timeinfo = localtime(&rawtime); + size_t pos = strftime(buffer, TIMESTAMP_LEN + 1, "[%H:%M:%S]", timeinfo); + + // Copy message (with newline already included by caller) + size_t copy_len = std::min(len, sizeof(buffer) - pos); + memcpy(buffer + pos, msg, copy_len); + pos += copy_len; + + // Single write for everything + fwrite(buffer, 1, pos, stdout); } void Logger::pre_setup() { global_logger = this; } From ffefa8929ede21b22c1c37d8415074699778a34c Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 23 Dec 2025 09:05:48 -0500 Subject: [PATCH 012/302] [cc1101] Fix packet mode RSSI/LQI (#12630) Co-authored-by: Claude --- esphome/components/cc1101/cc1101.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/esphome/components/cc1101/cc1101.cpp b/esphome/components/cc1101/cc1101.cpp index f98afd94a1..7e5309e165 100644 --- a/esphome/components/cc1101/cc1101.cpp +++ b/esphome/components/cc1101/cc1101.cpp @@ -169,14 +169,16 @@ void CC1101Component::loop() { } // Read packet - uint8_t payload_length; + uint8_t payload_length, expected_rx; if (this->state_.LENGTH_CONFIG == static_cast(LengthConfig::LENGTH_CONFIG_VARIABLE)) { this->read_(Register::FIFO, &payload_length, 1); + expected_rx = payload_length + 1; } else { payload_length = this->state_.PKTLEN; + expected_rx = payload_length; } - if (payload_length == 0 || payload_length > 64) { - ESP_LOGW(TAG, "Invalid payload length: %u", payload_length); + if (payload_length == 0 || payload_length > 64 || rx_bytes != expected_rx) { + ESP_LOGW(TAG, "Invalid packet: rx_bytes %u, payload_length %u", rx_bytes, payload_length); this->enter_idle_(); this->strobe_(Command::FRX); this->strobe_(Command::RX); @@ -186,13 +188,12 @@ void CC1101Component::loop() { this->packet_.resize(payload_length); this->read_(Register::FIFO, this->packet_.data(), payload_length); - // Read status and trigger - uint8_t status[2]; - this->read_(Register::FIFO, status, 2); - int8_t rssi_raw = static_cast(status[0]); - float rssi = (rssi_raw * RSSI_STEP) - RSSI_OFFSET; - bool crc_ok = (status[1] & STATUS_CRC_OK_MASK) != 0; - uint8_t lqi = status[1] & STATUS_LQI_MASK; + // Read status from registers (more reliable than FIFO status bytes due to timing issues) + this->read_(Register::RSSI); + this->read_(Register::LQI); + float rssi = (this->state_.RSSI * RSSI_STEP) - RSSI_OFFSET; + bool crc_ok = (this->state_.LQI & STATUS_CRC_OK_MASK) != 0; + uint8_t lqi = this->state_.LQI & STATUS_LQI_MASK; if (this->state_.CRC_EN == 0 || crc_ok) { this->packet_trigger_->trigger(this->packet_, rssi, lqi); } @@ -616,12 +617,15 @@ void CC1101Component::set_packet_mode(bool value) { this->state_.GDO0_CFG = 0x01; // Set max RX FIFO threshold to ensure we only trigger on end-of-packet this->state_.FIFO_THR = 15; + // Don't append status bytes to FIFO - we read from registers instead + this->state_.APPEND_STATUS = 0; } else { // Configure GDO0 for serial data (async serial mode) this->state_.GDO0_CFG = 0x0D; } if (this->initialized_) { this->write_(Register::PKTCTRL0); + this->write_(Register::PKTCTRL1); this->write_(Register::IOCFG0); this->write_(Register::FIFOTHR); } From dc943d7e7a5cf2cb7be4081d69fe605ffe0e63ca Mon Sep 17 00:00:00 2001 From: Thomas Rupprecht Date: Wed, 17 Dec 2025 04:52:28 +0100 Subject: [PATCH 013/302] [pca9685,sx126x,sx127x] Use frequency/float_range check (#12490) Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> --- esphome/components/ade7880/sensor.py | 2 +- esphome/components/cc1101/__init__.py | 2 +- esphome/components/esp32_camera/__init__.py | 2 +- esphome/components/esp8266_pwm/output.py | 2 +- esphome/components/i2c/__init__.py | 2 +- esphome/components/ledc/output.py | 4 +++- esphome/components/libretiny_pwm/output.py | 4 +++- esphome/components/pca9685/__init__.py | 2 +- esphome/components/rp2040_pwm/output.py | 2 +- esphome/components/sx126x/__init__.py | 8 ++++++-- esphome/components/sx127x/__init__.py | 8 ++++++-- 11 files changed, 25 insertions(+), 13 deletions(-) diff --git a/esphome/components/ade7880/sensor.py b/esphome/components/ade7880/sensor.py index 39dbeb225f..beb74d7310 100644 --- a/esphome/components/ade7880/sensor.py +++ b/esphome/components/ade7880/sensor.py @@ -227,7 +227,7 @@ CONFIG_SCHEMA = cv.All( { cv.GenerateID(): cv.declare_id(ADE7880), cv.Optional(CONF_FREQUENCY, default="50Hz"): cv.All( - cv.frequency, cv.Range(min=45.0, max=66.0) + cv.frequency, cv.float_range(min=45.0, max=66.0) ), cv.Optional(CONF_IRQ0_PIN): pins.internal_gpio_input_pin_schema, cv.Required(CONF_IRQ1_PIN): pins.internal_gpio_input_pin_schema, diff --git a/esphome/components/cc1101/__init__.py b/esphome/components/cc1101/__init__.py index 1971817fb1..e314da7079 100644 --- a/esphome/components/cc1101/__init__.py +++ b/esphome/components/cc1101/__init__.py @@ -165,7 +165,7 @@ CONFIG_MAP = { CONF_OUTPUT_POWER: cv.float_range(min=-30.0, max=11.0), CONF_RX_ATTENUATION: cv.enum(RX_ATTENUATION, upper=False), CONF_DC_BLOCKING_FILTER: cv.boolean, - CONF_FREQUENCY: cv.All(cv.frequency, cv.float_range(min=300000000, max=928000000)), + CONF_FREQUENCY: cv.All(cv.frequency, cv.float_range(min=300.0e6, max=928.0e6)), CONF_IF_FREQUENCY: cv.All(cv.frequency, cv.float_range(min=25000, max=788000)), CONF_FILTER_BANDWIDTH: cv.All(cv.frequency, cv.float_range(min=58000, max=812000)), CONF_CHANNEL: cv.uint8_t, diff --git a/esphome/components/esp32_camera/__init__.py b/esphome/components/esp32_camera/__init__.py index 2ad48173f1..ca37cb392d 100644 --- a/esphome/components/esp32_camera/__init__.py +++ b/esphome/components/esp32_camera/__init__.py @@ -186,7 +186,7 @@ CONFIG_SCHEMA = cv.All( { cv.Required(CONF_PIN): pins.internal_gpio_input_pin_number, cv.Optional(CONF_FREQUENCY, default="20MHz"): cv.All( - cv.frequency, cv.Range(min=8e6, max=20e6) + cv.frequency, cv.float_range(min=8e6, max=20e6) ), } ), diff --git a/esphome/components/esp8266_pwm/output.py b/esphome/components/esp8266_pwm/output.py index 1404ef8ac3..2ddf4b9014 100644 --- a/esphome/components/esp8266_pwm/output.py +++ b/esphome/components/esp8266_pwm/output.py @@ -16,7 +16,7 @@ def valid_pwm_pin(value): esp8266_pwm_ns = cg.esphome_ns.namespace("esp8266_pwm") ESP8266PWM = esp8266_pwm_ns.class_("ESP8266PWM", output.FloatOutput, cg.Component) SetFrequencyAction = esp8266_pwm_ns.class_("SetFrequencyAction", automation.Action) -validate_frequency = cv.All(cv.frequency, cv.Range(min=1.0e-6)) +validate_frequency = cv.All(cv.frequency, cv.float_range(min=1.0e-6)) CONFIG_SCHEMA = cv.All( output.FLOAT_OUTPUT_SCHEMA.extend( diff --git a/esphome/components/i2c/__init__.py b/esphome/components/i2c/__init__.py index 9e7c9d702c..7706484e97 100644 --- a/esphome/components/i2c/__init__.py +++ b/esphome/components/i2c/__init__.py @@ -121,7 +121,7 @@ CONFIG_SCHEMA = cv.All( nrf52="100kHz", ): cv.All( cv.frequency, - cv.Range(min=0, min_included=False), + cv.float_range(min=0, min_included=False), ), cv.Optional(CONF_TIMEOUT): cv.All( cv.only_with_framework(["arduino", "esp-idf"]), diff --git a/esphome/components/ledc/output.py b/esphome/components/ledc/output.py index 2133c4daf9..7ce79aa514 100644 --- a/esphome/components/ledc/output.py +++ b/esphome/components/ledc/output.py @@ -45,7 +45,9 @@ CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend( { cv.Required(CONF_ID): cv.declare_id(LEDCOutput), cv.Required(CONF_PIN): pins.internal_gpio_output_pin_schema, - cv.Optional(CONF_FREQUENCY, default="1kHz"): cv.frequency, + cv.Optional(CONF_FREQUENCY, default="1kHz"): cv.All( + cv.frequency, cv.float_range(min=0, min_included=False) + ), cv.Optional(CONF_CHANNEL): cv.int_range(min=0, max=15), cv.Optional(CONF_PHASE_ANGLE): cv.All( cv.only_with_esp_idf, cv.angle, cv.float_range(min=0.0, max=360.0) diff --git a/esphome/components/libretiny_pwm/output.py b/esphome/components/libretiny_pwm/output.py index 1eb4869da3..28556514d8 100644 --- a/esphome/components/libretiny_pwm/output.py +++ b/esphome/components/libretiny_pwm/output.py @@ -14,7 +14,9 @@ CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend( { cv.Required(CONF_ID): cv.declare_id(LibreTinyPWM), cv.Required(CONF_PIN): pins.internal_gpio_output_pin_schema, - cv.Optional(CONF_FREQUENCY, default="1kHz"): cv.frequency, + cv.Optional(CONF_FREQUENCY, default="1kHz"): cv.All( + cv.frequency, cv.float_range(min=0, min_included=False) + ), } ).extend(cv.COMPONENT_SCHEMA) diff --git a/esphome/components/pca9685/__init__.py b/esphome/components/pca9685/__init__.py index 56101c2d62..0e238ff7da 100644 --- a/esphome/components/pca9685/__init__.py +++ b/esphome/components/pca9685/__init__.py @@ -38,7 +38,7 @@ CONFIG_SCHEMA = cv.All( { cv.GenerateID(): cv.declare_id(PCA9685Output), cv.Optional(CONF_FREQUENCY): cv.All( - cv.frequency, cv.Range(min=23.84, max=1525.88) + cv.frequency, cv.float_range(min=23.84, max=1525.88) ), cv.Optional(CONF_EXTERNAL_CLOCK_INPUT, default=False): cv.boolean, cv.Optional(CONF_PHASE_BALANCER, default="linear"): cv.enum( diff --git a/esphome/components/rp2040_pwm/output.py b/esphome/components/rp2040_pwm/output.py index ac1892fa29..441a52de7f 100644 --- a/esphome/components/rp2040_pwm/output.py +++ b/esphome/components/rp2040_pwm/output.py @@ -11,7 +11,7 @@ DEPENDENCIES = ["rp2040"] rp2040_pwm_ns = cg.esphome_ns.namespace("rp2040_pwm") RP2040PWM = rp2040_pwm_ns.class_("RP2040PWM", output.FloatOutput, cg.Component) SetFrequencyAction = rp2040_pwm_ns.class_("SetFrequencyAction", automation.Action) -validate_frequency = cv.All(cv.frequency, cv.Range(min=1.0e-6)) +validate_frequency = cv.All(cv.frequency, cv.float_range(min=1.0e-6)) CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend( { diff --git a/esphome/components/sx126x/__init__.py b/esphome/components/sx126x/__init__.py index 4641db6483..ed878ed0d4 100644 --- a/esphome/components/sx126x/__init__.py +++ b/esphome/components/sx126x/__init__.py @@ -199,9 +199,13 @@ CONFIG_SCHEMA = ( cv.Optional(CONF_CRC_INITIAL, default=0x1D0F): cv.All( cv.hex_int, cv.Range(min=0, max=0xFFFF) ), - cv.Optional(CONF_DEVIATION, default=5000): cv.int_range(min=0, max=100000), + cv.Optional(CONF_DEVIATION, default="5kHz"): cv.All( + cv.frequency, cv.float_range(min=0, max=100000) + ), cv.Required(CONF_DIO1_PIN): pins.gpio_input_pin_schema, - cv.Required(CONF_FREQUENCY): cv.int_range(min=137000000, max=1020000000), + cv.Required(CONF_FREQUENCY): cv.All( + cv.frequency, cv.float_range(min=137.0e6, max=1020.0e6) + ), cv.Required(CONF_HW_VERSION): cv.one_of( "sx1261", "sx1262", "sx1268", "llcc68", lower=True ), diff --git a/esphome/components/sx127x/__init__.py b/esphome/components/sx127x/__init__.py index b569a75972..f3a9cca93f 100644 --- a/esphome/components/sx127x/__init__.py +++ b/esphome/components/sx127x/__init__.py @@ -196,9 +196,13 @@ CONFIG_SCHEMA = ( cv.Optional(CONF_BITSYNC): cv.boolean, cv.Optional(CONF_CODING_RATE, default="CR_4_5"): cv.enum(CODING_RATE), cv.Optional(CONF_CRC_ENABLE, default=False): cv.boolean, - cv.Optional(CONF_DEVIATION, default=5000): cv.int_range(min=0, max=100000), + cv.Optional(CONF_DEVIATION, default="5kHz"): cv.All( + cv.frequency, cv.float_range(min=0, max=100000) + ), cv.Optional(CONF_DIO0_PIN): pins.internal_gpio_input_pin_schema, - cv.Required(CONF_FREQUENCY): cv.int_range(min=137000000, max=1020000000), + cv.Required(CONF_FREQUENCY): cv.All( + cv.frequency, cv.float_range(min=137.0e6, max=1020.0e6) + ), cv.Required(CONF_MODULATION): cv.enum(MOD), cv.Optional(CONF_ON_PACKET): automation.validate_automation(single=True), cv.Optional(CONF_PA_PIN, default="BOOST"): cv.enum(PA_PIN), From 1922455fa74082b8fc22455080b98cd848cdea04 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Fri, 19 Dec 2025 20:25:16 -0600 Subject: [PATCH 014/302] [wifi] Fix for `wifi_info` when static IP is configured (#12576) --- esphome/components/wifi/wifi_component_esp8266.cpp | 10 ++++++++++ esphome/components/wifi/wifi_component_esp_idf.cpp | 8 ++++++++ esphome/components/wifi/wifi_component_libretiny.cpp | 8 ++++++++ esphome/components/wifi/wifi_component_pico_w.cpp | 9 +++++++++ 4 files changed, 35 insertions(+) diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index 3b1a442bdb..41594b947c 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -528,6 +528,16 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { for (auto *listener : global_wifi_component->connect_state_listeners_) { listener->on_wifi_connect_state(global_wifi_component->wifi_ssid(), global_wifi_component->wifi_bssid()); } + // For static IP configurations, GOT_IP event may not fire, so notify IP listeners here +#ifdef USE_WIFI_MANUAL_IP + if (const WiFiAP *config = global_wifi_component->get_selected_sta_(); + config && config->get_manual_ip().has_value()) { + for (auto *listener : global_wifi_component->ip_state_listeners_) { + listener->on_ip_state(global_wifi_component->wifi_sta_ip_addresses(), + global_wifi_component->get_dns_address(0), global_wifi_component->get_dns_address(1)); + } + } +#endif #endif break; } diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 4a3c40a119..380e4ea7fd 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -739,6 +739,14 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { for (auto *listener : this->connect_state_listeners_) { listener->on_wifi_connect_state(this->wifi_ssid(), this->wifi_bssid()); } + // For static IP configurations, GOT_IP event may not fire, so notify IP listeners here +#ifdef USE_WIFI_MANUAL_IP + if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) { + for (auto *listener : this->ip_state_listeners_) { + listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1)); + } + } +#endif #endif } else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_STA_DISCONNECTED) { diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index 36003a6eb4..1012b0be6c 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -305,6 +305,14 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ for (auto *listener : this->connect_state_listeners_) { listener->on_wifi_connect_state(this->wifi_ssid(), this->wifi_bssid()); } + // For static IP configurations, GOT_IP event may not fire, so notify IP listeners here +#ifdef USE_WIFI_MANUAL_IP + if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) { + for (auto *listener : this->ip_state_listeners_) { + listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1)); + } + } +#endif #endif break; } diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index 0228755432..c88aeb2d4f 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -259,6 +259,15 @@ void WiFiComponent::wifi_loop_() { for (auto *listener : this->connect_state_listeners_) { listener->on_wifi_connect_state(this->wifi_ssid(), this->wifi_bssid()); } + // For static IP configurations, notify IP listeners immediately as the IP is already configured +#ifdef USE_WIFI_MANUAL_IP + if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) { + s_sta_had_ip = true; + for (auto *listener : this->ip_state_listeners_) { + listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1)); + } + } +#endif #endif } else if (!is_connected && s_sta_was_connected) { // Just disconnected From 726db746c815751618def87a15218ee228be8f98 Mon Sep 17 00:00:00 2001 From: Eduard Llull Date: Sat, 20 Dec 2025 16:59:14 +0100 Subject: [PATCH 015/302] [display_menu_base] Call on_value_ after updating the select (#12584) --- esphome/components/display_menu_base/menu_item.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/components/display_menu_base/menu_item.cpp b/esphome/components/display_menu_base/menu_item.cpp index 8224adf3fe..08f758045e 100644 --- a/esphome/components/display_menu_base/menu_item.cpp +++ b/esphome/components/display_menu_base/menu_item.cpp @@ -54,6 +54,7 @@ bool MenuItemSelect::select_next() { if (this->select_var_ != nullptr) { this->select_var_->make_call().select_next(true).perform(); + this->on_value_(); changed = true; } @@ -65,6 +66,7 @@ bool MenuItemSelect::select_prev() { if (this->select_var_ != nullptr) { this->select_var_->make_call().select_previous(true).perform(); + this->on_value_(); changed = true; } From b055f5b4bf9783d59b72833976a23c2a835606ec Mon Sep 17 00:00:00 2001 From: Stuart Parmenter Date: Sat, 20 Dec 2025 10:18:20 -0800 Subject: [PATCH 016/302] [hub75] Bump esp-hub75 version to 0.1.7 (#12564) --- .clang-tidy.hash | 2 +- esphome/components/hub75/display.py | 46 ++++++++++++++--------------- esphome/idf_component.yml | 4 +++ platformio.ini | 2 -- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/.clang-tidy.hash b/.clang-tidy.hash index a3322ba731..240b205158 100644 --- a/.clang-tidy.hash +++ b/.clang-tidy.hash @@ -1 +1 @@ -766420905c06eeb6c5f360f68fd965e5ddd9c4a5db6b823263d3ad3accb64a07 +4268ab0b5150f79ab1c317e8f3834c8bb0b4c8122da4f6b1fd67c49d0f2098c9 diff --git a/esphome/components/hub75/display.py b/esphome/components/hub75/display.py index 81dd4ffc1c..0518731a6a 100644 --- a/esphome/components/hub75/display.py +++ b/esphome/components/hub75/display.py @@ -93,35 +93,35 @@ CONF_DOUBLE_BUFFER = "double_buffer" CONF_MIN_REFRESH_RATE = "min_refresh_rate" # Map to hub75 library enums (in global namespace) -ShiftDriver = cg.global_ns.enum("ShiftDriver", is_class=True) +Hub75ShiftDriver = cg.global_ns.enum("Hub75ShiftDriver", is_class=True) SHIFT_DRIVERS = { - "GENERIC": ShiftDriver.GENERIC, - "FM6126A": ShiftDriver.FM6126A, - "ICN2038S": ShiftDriver.ICN2038S, - "FM6124": ShiftDriver.FM6124, - "MBI5124": ShiftDriver.MBI5124, - "DP3246": ShiftDriver.DP3246, + "GENERIC": Hub75ShiftDriver.GENERIC, + "FM6126A": Hub75ShiftDriver.FM6126A, + "ICN2038S": Hub75ShiftDriver.ICN2038S, + "FM6124": Hub75ShiftDriver.FM6124, + "MBI5124": Hub75ShiftDriver.MBI5124, + "DP3246": Hub75ShiftDriver.DP3246, } -PanelLayout = cg.global_ns.enum("PanelLayout", is_class=True) +Hub75PanelLayout = cg.global_ns.enum("Hub75PanelLayout", is_class=True) PANEL_LAYOUTS = { - "HORIZONTAL": PanelLayout.HORIZONTAL, - "TOP_LEFT_DOWN": PanelLayout.TOP_LEFT_DOWN, - "TOP_RIGHT_DOWN": PanelLayout.TOP_RIGHT_DOWN, - "BOTTOM_LEFT_UP": PanelLayout.BOTTOM_LEFT_UP, - "BOTTOM_RIGHT_UP": PanelLayout.BOTTOM_RIGHT_UP, - "TOP_LEFT_DOWN_ZIGZAG": PanelLayout.TOP_LEFT_DOWN_ZIGZAG, - "TOP_RIGHT_DOWN_ZIGZAG": PanelLayout.TOP_RIGHT_DOWN_ZIGZAG, - "BOTTOM_LEFT_UP_ZIGZAG": PanelLayout.BOTTOM_LEFT_UP_ZIGZAG, - "BOTTOM_RIGHT_UP_ZIGZAG": PanelLayout.BOTTOM_RIGHT_UP_ZIGZAG, + "HORIZONTAL": Hub75PanelLayout.HORIZONTAL, + "TOP_LEFT_DOWN": Hub75PanelLayout.TOP_LEFT_DOWN, + "TOP_RIGHT_DOWN": Hub75PanelLayout.TOP_RIGHT_DOWN, + "BOTTOM_LEFT_UP": Hub75PanelLayout.BOTTOM_LEFT_UP, + "BOTTOM_RIGHT_UP": Hub75PanelLayout.BOTTOM_RIGHT_UP, + "TOP_LEFT_DOWN_ZIGZAG": Hub75PanelLayout.TOP_LEFT_DOWN_ZIGZAG, + "TOP_RIGHT_DOWN_ZIGZAG": Hub75PanelLayout.TOP_RIGHT_DOWN_ZIGZAG, + "BOTTOM_LEFT_UP_ZIGZAG": Hub75PanelLayout.BOTTOM_LEFT_UP_ZIGZAG, + "BOTTOM_RIGHT_UP_ZIGZAG": Hub75PanelLayout.BOTTOM_RIGHT_UP_ZIGZAG, } -ScanPattern = cg.global_ns.enum("ScanPattern", is_class=True) +Hub75ScanWiring = cg.global_ns.enum("Hub75ScanWiring", is_class=True) SCAN_PATTERNS = { - "STANDARD_TWO_SCAN": ScanPattern.STANDARD_TWO_SCAN, - "FOUR_SCAN_16PX_HIGH": ScanPattern.FOUR_SCAN_16PX_HIGH, - "FOUR_SCAN_32PX_HIGH": ScanPattern.FOUR_SCAN_32PX_HIGH, - "FOUR_SCAN_64PX_HIGH": ScanPattern.FOUR_SCAN_64PX_HIGH, + "STANDARD_TWO_SCAN": Hub75ScanWiring.STANDARD_TWO_SCAN, + "FOUR_SCAN_16PX_HIGH": Hub75ScanWiring.FOUR_SCAN_16PX_HIGH, + "FOUR_SCAN_32PX_HIGH": Hub75ScanWiring.FOUR_SCAN_32PX_HIGH, + "FOUR_SCAN_64PX_HIGH": Hub75ScanWiring.FOUR_SCAN_64PX_HIGH, } Hub75ClockSpeed = cg.global_ns.enum("Hub75ClockSpeed", is_class=True) @@ -528,7 +528,7 @@ def _build_config_struct( async def to_code(config: ConfigType) -> None: add_idf_component( name="esphome/esp-hub75", - ref="0.1.6", + ref="0.1.7", ) # Set compile-time configuration via defines diff --git a/esphome/idf_component.yml b/esphome/idf_component.yml index 9bb5967248..4573391bc1 100644 --- a/esphome/idf_component.yml +++ b/esphome/idf_component.yml @@ -27,3 +27,7 @@ dependencies: version: "1.7.6~1" rules: - if: "target in [esp32s2, esp32s3, esp32p4]" + esphome/esp-hub75: + version: 0.1.7 + rules: + - if: "target in [esp32, esp32s2, esp32s3, esp32p4]" diff --git a/platformio.ini b/platformio.ini index d37c798c05..a27fb1f537 100644 --- a/platformio.ini +++ b/platformio.ini @@ -156,7 +156,6 @@ lib_deps = esphome/ESP32-audioI2S@2.3.0 ; i2s_audio droscy/esp_wireguard@0.4.2 ; wireguard esphome/esp-audio-libs@2.0.1 ; audio - esphome/esp-hub75@0.1.6 ; hub75 build_flags = ${common:arduino.build_flags} @@ -180,7 +179,6 @@ lib_deps = droscy/esp_wireguard@0.4.2 ; wireguard kahrendt/ESPMicroSpeechFeatures@1.1.0 ; micro_wake_word esphome/esp-audio-libs@2.0.1 ; audio - esphome/esp-hub75@0.1.6 ; hub75 build_flags = ${common:idf.build_flags} -Wno-nonnull-compare From 086ec770ea3dfef98abafd3fe30deeecc6f61e3a Mon Sep 17 00:00:00 2001 From: Leo Bergolth Date: Sat, 20 Dec 2025 21:04:59 +0100 Subject: [PATCH 017/302] send NIL ("-") as timestamp if time source is not valid (#12588) --- esphome/components/syslog/esphome_syslog.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/esphome/components/syslog/esphome_syslog.cpp b/esphome/components/syslog/esphome_syslog.cpp index f5c20c891e..851fb30c22 100644 --- a/esphome/components/syslog/esphome_syslog.cpp +++ b/esphome/components/syslog/esphome_syslog.cpp @@ -34,7 +34,15 @@ void Syslog::log_(const int level, const char *tag, const char *message, size_t severity = LOG_LEVEL_TO_SYSLOG_SEVERITY[level]; } int pri = this->facility_ * 8 + severity; - auto timestamp = this->time_->now().strftime("%b %e %H:%M:%S"); + auto now = this->time_->now(); + std::string timestamp; + if (now.is_valid()) { + timestamp = now.strftime("%b %e %H:%M:%S"); + } else { + // RFC 5424: A syslog application MUST use the NILVALUE as TIMESTAMP if the syslog application is incapable of + // obtaining system time. + timestamp = "-"; + } size_t len = message_len; // remove color formatting if (this->strip_ && message[0] == 0x1B && len > 11) { From 61ec3508ed75f826ab0f20dacceadc1f212985bf Mon Sep 17 00:00:00 2001 From: Anna Oake Date: Sun, 21 Dec 2025 19:04:17 +0100 Subject: [PATCH 018/302] [cc1101] Fix option defaults and move them to YAML (#12608) --- esphome/components/cc1101/__init__.py | 95 +++++++++++++++++---------- esphome/components/cc1101/cc1101.cpp | 17 ----- 2 files changed, 59 insertions(+), 53 deletions(-) diff --git a/esphome/components/cc1101/__init__.py b/esphome/components/cc1101/__init__.py index e314da7079..c205ff2f69 100644 --- a/esphome/components/cc1101/__init__.py +++ b/esphome/components/cc1101/__init__.py @@ -160,41 +160,63 @@ HYST_LEVEL = { "High": HystLevel.HYST_LEVEL_HIGH, } -# Config key -> Validator mapping +# Optional settings to generate setter calls for CONFIG_MAP = { - CONF_OUTPUT_POWER: cv.float_range(min=-30.0, max=11.0), - CONF_RX_ATTENUATION: cv.enum(RX_ATTENUATION, upper=False), - CONF_DC_BLOCKING_FILTER: cv.boolean, - CONF_FREQUENCY: cv.All(cv.frequency, cv.float_range(min=300.0e6, max=928.0e6)), - CONF_IF_FREQUENCY: cv.All(cv.frequency, cv.float_range(min=25000, max=788000)), - CONF_FILTER_BANDWIDTH: cv.All(cv.frequency, cv.float_range(min=58000, max=812000)), - CONF_CHANNEL: cv.uint8_t, - CONF_CHANNEL_SPACING: cv.All(cv.frequency, cv.float_range(min=25000, max=405000)), - CONF_FSK_DEVIATION: cv.All(cv.frequency, cv.float_range(min=1500, max=381000)), - CONF_MSK_DEVIATION: cv.int_range(min=1, max=8), - CONF_SYMBOL_RATE: cv.float_range(min=600, max=500000), - CONF_SYNC_MODE: cv.enum(SYNC_MODE, upper=False), - CONF_CARRIER_SENSE_ABOVE_THRESHOLD: cv.boolean, - CONF_MODULATION_TYPE: cv.enum(MODULATION, upper=False), - CONF_MANCHESTER: cv.boolean, - CONF_NUM_PREAMBLE: cv.int_range(min=0, max=7), - CONF_SYNC1: cv.hex_uint8_t, - CONF_SYNC0: cv.hex_uint8_t, - CONF_MAGN_TARGET: cv.enum(MAGN_TARGET, upper=False), - CONF_MAX_LNA_GAIN: cv.enum(MAX_LNA_GAIN, upper=False), - CONF_MAX_DVGA_GAIN: cv.enum(MAX_DVGA_GAIN, upper=False), - CONF_CARRIER_SENSE_ABS_THR: cv.int_range(min=-8, max=7), - CONF_CARRIER_SENSE_REL_THR: cv.enum(CARRIER_SENSE_REL_THR, upper=False), - CONF_LNA_PRIORITY: cv.boolean, - CONF_FILTER_LENGTH_FSK_MSK: cv.enum(FILTER_LENGTH_FSK_MSK, upper=False), - CONF_FILTER_LENGTH_ASK_OOK: cv.enum(FILTER_LENGTH_ASK_OOK, upper=False), - CONF_FREEZE: cv.enum(FREEZE, upper=False), - CONF_WAIT_TIME: cv.enum(WAIT_TIME, upper=False), - CONF_HYST_LEVEL: cv.enum(HYST_LEVEL, upper=False), - CONF_PACKET_MODE: cv.boolean, - CONF_PACKET_LENGTH: cv.uint8_t, - CONF_CRC_ENABLE: cv.boolean, - CONF_WHITENING: cv.boolean, + cv.Optional(CONF_OUTPUT_POWER, default=10): cv.float_range(min=-30.0, max=11.0), + cv.Optional(CONF_RX_ATTENUATION, default="0dB"): cv.enum( + RX_ATTENUATION, upper=False + ), + cv.Optional(CONF_DC_BLOCKING_FILTER, default=True): cv.boolean, + cv.Optional(CONF_FREQUENCY, default="433.92MHz"): cv.All( + cv.frequency, cv.float_range(min=300.0e6, max=928.0e6) + ), + cv.Optional(CONF_IF_FREQUENCY, default="153kHz"): cv.All( + cv.frequency, cv.float_range(min=25000, max=788000) + ), + cv.Optional(CONF_FILTER_BANDWIDTH, default="203kHz"): cv.All( + cv.frequency, cv.float_range(min=58000, max=812000) + ), + cv.Optional(CONF_CHANNEL, default=0): cv.uint8_t, + cv.Optional(CONF_CHANNEL_SPACING, default="200kHz"): cv.All( + cv.frequency, cv.float_range(min=25000, max=405000) + ), + cv.Optional(CONF_FSK_DEVIATION): cv.All( + cv.frequency, cv.float_range(min=1500, max=381000) + ), + cv.Optional(CONF_MSK_DEVIATION): cv.int_range(min=1, max=8), + cv.Optional(CONF_SYMBOL_RATE, default=5000): cv.float_range(min=600, max=500000), + cv.Optional(CONF_SYNC_MODE, default="16/16"): cv.enum(SYNC_MODE, upper=False), + cv.Optional(CONF_CARRIER_SENSE_ABOVE_THRESHOLD, default=False): cv.boolean, + cv.Optional(CONF_MODULATION_TYPE, default="ASK/OOK"): cv.enum( + MODULATION, upper=False + ), + cv.Optional(CONF_MANCHESTER, default=False): cv.boolean, + cv.Optional(CONF_NUM_PREAMBLE, default=2): cv.int_range(min=0, max=7), + cv.Optional(CONF_SYNC1, default=0xD3): cv.hex_uint8_t, + cv.Optional(CONF_SYNC0, default=0x91): cv.hex_uint8_t, + cv.Optional(CONF_MAGN_TARGET, default="42dB"): cv.enum(MAGN_TARGET, upper=False), + cv.Optional(CONF_MAX_LNA_GAIN, default="Default"): cv.enum( + MAX_LNA_GAIN, upper=False + ), + cv.Optional(CONF_MAX_DVGA_GAIN, default="-3"): cv.enum(MAX_DVGA_GAIN, upper=False), + cv.Optional(CONF_CARRIER_SENSE_ABS_THR): cv.int_range(min=-8, max=7), + cv.Optional(CONF_CARRIER_SENSE_REL_THR): cv.enum( + CARRIER_SENSE_REL_THR, upper=False + ), + cv.Optional(CONF_LNA_PRIORITY, default=False): cv.boolean, + cv.Optional(CONF_FILTER_LENGTH_FSK_MSK): cv.enum( + FILTER_LENGTH_FSK_MSK, upper=False + ), + cv.Optional(CONF_FILTER_LENGTH_ASK_OOK): cv.enum( + FILTER_LENGTH_ASK_OOK, upper=False + ), + cv.Optional(CONF_FREEZE): cv.enum(FREEZE, upper=False), + cv.Optional(CONF_WAIT_TIME, default="32"): cv.enum(WAIT_TIME, upper=False), + cv.Optional(CONF_HYST_LEVEL): cv.enum(HYST_LEVEL, upper=False), + cv.Optional(CONF_PACKET_MODE, default=False): cv.boolean, + cv.Optional(CONF_PACKET_LENGTH): cv.uint8_t, + cv.Optional(CONF_CRC_ENABLE, default=False): cv.boolean, + cv.Optional(CONF_WHITENING, default=False): cv.boolean, } @@ -217,7 +239,7 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_ON_PACKET): automation.validate_automation(single=True), } ) - .extend({cv.Optional(key): validator for key, validator in CONFIG_MAP.items()}) + .extend(CONFIG_MAP) .extend(cv.COMPONENT_SCHEMA) .extend(spi.spi_device_schema(cs_pin_required=True)), _validate_packet_mode, @@ -229,7 +251,8 @@ async def to_code(config): await cg.register_component(var, config) await spi.register_spi_device(var, config) - for key in CONFIG_MAP: + for opt in CONFIG_MAP: + key = opt.schema if key in config: cg.add(getattr(var, f"set_{key}")(config[key])) diff --git a/esphome/components/cc1101/cc1101.cpp b/esphome/components/cc1101/cc1101.cpp index 1fe402d6c6..f98afd94a1 100644 --- a/esphome/components/cc1101/cc1101.cpp +++ b/esphome/components/cc1101/cc1101.cpp @@ -98,25 +98,8 @@ CC1101Component::CC1101Component() { this->state_.LENGTH_CONFIG = 2; this->state_.FS_AUTOCAL = 1; - // Default Settings - this->set_frequency(433920000); - this->set_if_frequency(153000); - this->set_filter_bandwidth(203000); - this->set_channel(0); - this->set_channel_spacing(200000); - this->set_symbol_rate(5000); - this->set_sync_mode(SyncMode::SYNC_MODE_NONE); - this->set_carrier_sense_above_threshold(true); - this->set_modulation_type(Modulation::MODULATION_ASK_OOK); - this->set_magn_target(MagnTarget::MAGN_TARGET_42DB); - this->set_max_lna_gain(MaxLnaGain::MAX_LNA_GAIN_DEFAULT); - this->set_max_dvga_gain(MaxDvgaGain::MAX_DVGA_GAIN_MINUS_3); - this->set_lna_priority(false); - this->set_wait_time(WaitTime::WAIT_TIME_32_SAMPLES); - // CRITICAL: Initialize PA Table to avoid transmitting 0 power (Silence) memset(this->pa_table_, 0, sizeof(this->pa_table_)); - this->set_output_power(10.0f); } void CC1101Component::setup() { From 6054685daee93e6c4baad681df16024d88613112 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 21 Dec 2025 09:04:43 -1000 Subject: [PATCH 019/302] [esp32_camera] Throttle frame logging to reduce overhead and improve throughput (#12586) --- .../components/esp32_camera/esp32_camera.cpp | 18 +++++++++++++++++- esphome/components/esp32_camera/esp32_camera.h | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/esphome/components/esp32_camera/esp32_camera.cpp b/esphome/components/esp32_camera/esp32_camera.cpp index 5080a6f32d..a3677330ca 100644 --- a/esphome/components/esp32_camera/esp32_camera.cpp +++ b/esphome/components/esp32_camera/esp32_camera.cpp @@ -11,6 +11,9 @@ namespace esphome { namespace esp32_camera { static const char *const TAG = "esp32_camera"; +#if ESPHOME_LOG_LEVEL < ESPHOME_LOG_LEVEL_VERBOSE +static constexpr uint32_t FRAME_LOG_INTERVAL_MS = 60000; +#endif /* ---------------- public API (derivated) ---------------- */ void ESP32Camera::setup() { @@ -204,7 +207,20 @@ void ESP32Camera::loop() { } this->current_image_ = std::make_shared(fb, this->single_requesters_ | this->stream_requesters_); - ESP_LOGD(TAG, "Got Image: len=%u", fb->len); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + ESP_LOGV(TAG, "Got Image: len=%u", fb->len); +#else + // Initialize log time on first frame to ensure accurate interval measurement + if (this->frame_count_ == 0) { + this->last_log_time_ = now; + } + this->frame_count_++; + if (now - this->last_log_time_ >= FRAME_LOG_INTERVAL_MS) { + ESP_LOGD(TAG, "Received %u images in last %us", this->frame_count_, FRAME_LOG_INTERVAL_MS / 1000); + this->last_log_time_ = now; + this->frame_count_ = 0; + } +#endif for (auto *listener : this->listeners_) { listener->on_camera_image(this->current_image_); } diff --git a/esphome/components/esp32_camera/esp32_camera.h b/esphome/components/esp32_camera/esp32_camera.h index 54a7d6064a..a49fca6511 100644 --- a/esphome/components/esp32_camera/esp32_camera.h +++ b/esphome/components/esp32_camera/esp32_camera.h @@ -213,6 +213,10 @@ class ESP32Camera : public camera::Camera { uint32_t last_idle_request_{0}; uint32_t last_update_{0}; +#if ESPHOME_LOG_LEVEL < ESPHOME_LOG_LEVEL_VERBOSE + uint32_t last_log_time_{0}; + uint16_t frame_count_{0}; +#endif #ifdef USE_I2C i2c::InternalI2CBus *i2c_bus_{nullptr}; #endif // USE_I2C From c8fb694dcbdc1b837fcaf6683b13e43722bd6431 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 23 Dec 2025 09:05:48 -0500 Subject: [PATCH 020/302] [cc1101] Fix packet mode RSSI/LQI (#12630) Co-authored-by: Claude --- esphome/components/cc1101/cc1101.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/esphome/components/cc1101/cc1101.cpp b/esphome/components/cc1101/cc1101.cpp index f98afd94a1..7e5309e165 100644 --- a/esphome/components/cc1101/cc1101.cpp +++ b/esphome/components/cc1101/cc1101.cpp @@ -169,14 +169,16 @@ void CC1101Component::loop() { } // Read packet - uint8_t payload_length; + uint8_t payload_length, expected_rx; if (this->state_.LENGTH_CONFIG == static_cast(LengthConfig::LENGTH_CONFIG_VARIABLE)) { this->read_(Register::FIFO, &payload_length, 1); + expected_rx = payload_length + 1; } else { payload_length = this->state_.PKTLEN; + expected_rx = payload_length; } - if (payload_length == 0 || payload_length > 64) { - ESP_LOGW(TAG, "Invalid payload length: %u", payload_length); + if (payload_length == 0 || payload_length > 64 || rx_bytes != expected_rx) { + ESP_LOGW(TAG, "Invalid packet: rx_bytes %u, payload_length %u", rx_bytes, payload_length); this->enter_idle_(); this->strobe_(Command::FRX); this->strobe_(Command::RX); @@ -186,13 +188,12 @@ void CC1101Component::loop() { this->packet_.resize(payload_length); this->read_(Register::FIFO, this->packet_.data(), payload_length); - // Read status and trigger - uint8_t status[2]; - this->read_(Register::FIFO, status, 2); - int8_t rssi_raw = static_cast(status[0]); - float rssi = (rssi_raw * RSSI_STEP) - RSSI_OFFSET; - bool crc_ok = (status[1] & STATUS_CRC_OK_MASK) != 0; - uint8_t lqi = status[1] & STATUS_LQI_MASK; + // Read status from registers (more reliable than FIFO status bytes due to timing issues) + this->read_(Register::RSSI); + this->read_(Register::LQI); + float rssi = (this->state_.RSSI * RSSI_STEP) - RSSI_OFFSET; + bool crc_ok = (this->state_.LQI & STATUS_CRC_OK_MASK) != 0; + uint8_t lqi = this->state_.LQI & STATUS_LQI_MASK; if (this->state_.CRC_EN == 0 || crc_ok) { this->packet_trigger_->trigger(this->packet_, rssi, lqi); } @@ -616,12 +617,15 @@ void CC1101Component::set_packet_mode(bool value) { this->state_.GDO0_CFG = 0x01; // Set max RX FIFO threshold to ensure we only trigger on end-of-packet this->state_.FIFO_THR = 15; + // Don't append status bytes to FIFO - we read from registers instead + this->state_.APPEND_STATUS = 0; } else { // Configure GDO0 for serial data (async serial mode) this->state_.GDO0_CFG = 0x0D; } if (this->initialized_) { this->write_(Register::PKTCTRL0); + this->write_(Register::PKTCTRL1); this->write_(Register::IOCFG0); this->write_(Register::FIFOTHR); } From 0922f240e0ab48a8dd86e59876980481358a47ca Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 23 Dec 2025 09:23:04 -0500 Subject: [PATCH 021/302] Bump version to 2025.12.2 --- Doxyfile | 2 +- esphome/const.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doxyfile b/Doxyfile index 4c533ec87f..d41459ea46 100644 --- a/Doxyfile +++ b/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = ESPHome # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 2025.12.1 +PROJECT_NUMBER = 2025.12.2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/esphome/const.py b/esphome/const.py index 8f9a3497ff..41bb419aaf 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -4,7 +4,7 @@ from enum import Enum from esphome.enum import StrEnum -__version__ = "2025.12.1" +__version__ = "2025.12.2" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From ebb6babb3d9db6952c0dd6af6c4cc14c898d94b1 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 23 Dec 2025 09:26:38 -0500 Subject: [PATCH 022/302] Fix hash --- .clang-tidy.hash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy.hash b/.clang-tidy.hash index 240b205158..18379de92e 100644 --- a/.clang-tidy.hash +++ b/.clang-tidy.hash @@ -1 +1 @@ -4268ab0b5150f79ab1c317e8f3834c8bb0b4c8122da4f6b1fd67c49d0f2098c9 +5969e705693278d984c5292e998df0cbaf34f7e1f04dfc7f7b7ad7168527bfa7 From 0c566c6f00b1bf2fc11a4bb019f1f9292c2f0d5f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 23 Dec 2025 06:59:07 -1000 Subject: [PATCH 023/302] [core] Deprecate get_object_id() and migrate remaining usages to get_object_id_to() (#12629) --- esphome/components/pid/pid_climate.cpp | 6 +++--- esphome/components/prometheus/prometheus_handler.cpp | 6 +++++- esphome/core/entity_base.h | 9 +++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/esphome/components/pid/pid_climate.cpp b/esphome/components/pid/pid_climate.cpp index fd74eabd87..2094c0e942 100644 --- a/esphome/components/pid/pid_climate.cpp +++ b/esphome/components/pid/pid_climate.cpp @@ -162,14 +162,14 @@ void PIDClimate::start_autotune(std::unique_ptr &&autotune) { float min_value = this->supports_cool_() ? -1.0f : 0.0f; float max_value = this->supports_heat_() ? 1.0f : 0.0f; this->autotuner_->config(min_value, max_value); - this->autotuner_->set_autotuner_id(this->get_object_id()); + this->autotuner_->set_autotuner_id(this->get_name()); ESP_LOGI(TAG, "%s: Autotune has started. This can take a long time depending on the " "responsiveness of your system. Your system " "output will be altered to deliberately oscillate above and below the setpoint multiple times. " "Until your sensor provides a reading, the autotuner may display \'nan\'", - this->get_object_id().c_str()); + this->get_name().c_str()); this->set_interval("autotune-progress", 10000, [this]() { if (this->autotuner_ != nullptr && !this->autotuner_->is_finished()) @@ -178,7 +178,7 @@ void PIDClimate::start_autotune(std::unique_ptr &&autotune) { if (mode != climate::CLIMATE_MODE_HEAT_COOL) { ESP_LOGW(TAG, "%s: !!! For PID autotuner you need to set AUTO (also called heat/cool) mode!", - this->get_object_id().c_str()); + this->get_name().c_str()); } } diff --git a/esphome/components/prometheus/prometheus_handler.cpp b/esphome/components/prometheus/prometheus_handler.cpp index 4b5d834ebf..88b357041a 100644 --- a/esphome/components/prometheus/prometheus_handler.cpp +++ b/esphome/components/prometheus/prometheus_handler.cpp @@ -112,7 +112,11 @@ void PrometheusHandler::handleRequest(AsyncWebServerRequest *req) { std::string PrometheusHandler::relabel_id_(EntityBase *obj) { auto item = relabel_map_id_.find(obj); - return item == relabel_map_id_.end() ? obj->get_object_id() : item->second; + if (item != relabel_map_id_.end()) { + return item->second; + } + char object_id_buf[OBJECT_ID_MAX_LEN]; + return obj->get_object_id_to(object_id_buf).str(); } std::string PrometheusHandler::relabel_name_(EntityBase *obj) { diff --git a/esphome/core/entity_base.h b/esphome/core/entity_base.h index eb1ba46c94..93f989934a 100644 --- a/esphome/core/entity_base.h +++ b/esphome/core/entity_base.h @@ -33,6 +33,15 @@ class EntityBase { bool has_own_name() const { return this->flags_.has_own_name; } // Get the sanitized name of this Entity as an ID. + // Deprecated: object_id mangles names and all object_id methods are planned for removal. + // See https://github.com/esphome/backlog/issues/76 + // Now is the time to stop using object_id entirely. If you still need it temporarily, + // use get_object_id_to() which will remain available longer but will also eventually be removed. + ESPDEPRECATED("object_id mangles names and all object_id methods are planned for removal " + "(see https://github.com/esphome/backlog/issues/76). " + "Now is the time to stop using object_id. If still needed, use get_object_id_to() " + "which will remain available longer. get_object_id() will be removed in 2026.7.0", + "2025.12.0") std::string get_object_id() const; void set_object_id(const char *object_id); From 958a35e26279a302f6da4d0efd8b7191355b09d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Dec 2025 14:17:52 -1000 Subject: [PATCH 024/302] Bump aioesphomeapi from 43.5.0 to 43.6.0 (#12644) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5718ced617..e741a70f48 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile esptool==5.1.0 click==8.1.7 esphome-dashboard==20251013.0 -aioesphomeapi==43.5.0 +aioesphomeapi==43.6.0 zeroconf==0.148.0 puremagic==1.30 ruamel.yaml==0.18.17 # dashboard_import From 4f706636584137d9c697320928162c8743b03e91 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 26 Dec 2025 07:57:33 -1000 Subject: [PATCH 025/302] [alarm_control_panel] Use C++17 nested namespace and remove unused include (#12662) --- .../alarm_control_panel/alarm_control_panel.cpp | 6 ++---- .../components/alarm_control_panel/alarm_control_panel.h | 8 ++------ .../alarm_control_panel/alarm_control_panel_call.cpp | 6 ++---- .../alarm_control_panel/alarm_control_panel_call.h | 6 ++---- .../alarm_control_panel/alarm_control_panel_state.cpp | 6 ++---- .../alarm_control_panel/alarm_control_panel_state.h | 6 ++---- esphome/components/alarm_control_panel/automation.h | 6 ++---- 7 files changed, 14 insertions(+), 30 deletions(-) diff --git a/esphome/components/alarm_control_panel/alarm_control_panel.cpp b/esphome/components/alarm_control_panel/alarm_control_panel.cpp index f938155dd3..89c0908a74 100644 --- a/esphome/components/alarm_control_panel/alarm_control_panel.cpp +++ b/esphome/components/alarm_control_panel/alarm_control_panel.cpp @@ -8,8 +8,7 @@ #include "esphome/core/helpers.h" #include "esphome/core/log.h" -namespace esphome { -namespace alarm_control_panel { +namespace esphome::alarm_control_panel { static const char *const TAG = "alarm_control_panel"; @@ -115,5 +114,4 @@ void AlarmControlPanel::disarm(optional code) { call.perform(); } -} // namespace alarm_control_panel -} // namespace esphome +} // namespace esphome::alarm_control_panel diff --git a/esphome/components/alarm_control_panel/alarm_control_panel.h b/esphome/components/alarm_control_panel/alarm_control_panel.h index 59ccf0e484..340f15bcd6 100644 --- a/esphome/components/alarm_control_panel/alarm_control_panel.h +++ b/esphome/components/alarm_control_panel/alarm_control_panel.h @@ -1,7 +1,5 @@ #pragma once -#include - #include "alarm_control_panel_call.h" #include "alarm_control_panel_state.h" @@ -9,8 +7,7 @@ #include "esphome/core/entity_base.h" #include "esphome/core/log.h" -namespace esphome { -namespace alarm_control_panel { +namespace esphome::alarm_control_panel { enum AlarmControlPanelFeature : uint8_t { // Matches Home Assistant values @@ -141,5 +138,4 @@ class AlarmControlPanel : public EntityBase { LazyCallbackManager ready_callback_{}; }; -} // namespace alarm_control_panel -} // namespace esphome +} // namespace esphome::alarm_control_panel diff --git a/esphome/components/alarm_control_panel/alarm_control_panel_call.cpp b/esphome/components/alarm_control_panel/alarm_control_panel_call.cpp index 7bb9b9989c..5e98d58368 100644 --- a/esphome/components/alarm_control_panel/alarm_control_panel_call.cpp +++ b/esphome/components/alarm_control_panel/alarm_control_panel_call.cpp @@ -4,8 +4,7 @@ #include "esphome/core/log.h" -namespace esphome { -namespace alarm_control_panel { +namespace esphome::alarm_control_panel { static const char *const TAG = "alarm_control_panel"; @@ -99,5 +98,4 @@ void AlarmControlPanelCall::perform() { } } -} // namespace alarm_control_panel -} // namespace esphome +} // namespace esphome::alarm_control_panel diff --git a/esphome/components/alarm_control_panel/alarm_control_panel_call.h b/esphome/components/alarm_control_panel/alarm_control_panel_call.h index 034e3142da..cff00900dd 100644 --- a/esphome/components/alarm_control_panel/alarm_control_panel_call.h +++ b/esphome/components/alarm_control_panel/alarm_control_panel_call.h @@ -6,8 +6,7 @@ #include "esphome/core/helpers.h" -namespace esphome { -namespace alarm_control_panel { +namespace esphome::alarm_control_panel { class AlarmControlPanel; @@ -36,5 +35,4 @@ class AlarmControlPanelCall { void validate_(); }; -} // namespace alarm_control_panel -} // namespace esphome +} // namespace esphome::alarm_control_panel diff --git a/esphome/components/alarm_control_panel/alarm_control_panel_state.cpp b/esphome/components/alarm_control_panel/alarm_control_panel_state.cpp index abe6f51995..862c620497 100644 --- a/esphome/components/alarm_control_panel/alarm_control_panel_state.cpp +++ b/esphome/components/alarm_control_panel/alarm_control_panel_state.cpp @@ -1,7 +1,6 @@ #include "alarm_control_panel_state.h" -namespace esphome { -namespace alarm_control_panel { +namespace esphome::alarm_control_panel { const LogString *alarm_control_panel_state_to_string(AlarmControlPanelState state) { switch (state) { @@ -30,5 +29,4 @@ const LogString *alarm_control_panel_state_to_string(AlarmControlPanelState stat } } -} // namespace alarm_control_panel -} // namespace esphome +} // namespace esphome::alarm_control_panel diff --git a/esphome/components/alarm_control_panel/alarm_control_panel_state.h b/esphome/components/alarm_control_panel/alarm_control_panel_state.h index ad16222dc0..dd0b91f064 100644 --- a/esphome/components/alarm_control_panel/alarm_control_panel_state.h +++ b/esphome/components/alarm_control_panel/alarm_control_panel_state.h @@ -3,8 +3,7 @@ #include #include "esphome/core/log.h" -namespace esphome { -namespace alarm_control_panel { +namespace esphome::alarm_control_panel { enum AlarmControlPanelState : uint8_t { ACP_STATE_DISARMED = 0, @@ -25,5 +24,4 @@ enum AlarmControlPanelState : uint8_t { */ const LogString *alarm_control_panel_state_to_string(AlarmControlPanelState state); -} // namespace alarm_control_panel -} // namespace esphome +} // namespace esphome::alarm_control_panel diff --git a/esphome/components/alarm_control_panel/automation.h b/esphome/components/alarm_control_panel/automation.h index af4a14e27a..ce5ceadb47 100644 --- a/esphome/components/alarm_control_panel/automation.h +++ b/esphome/components/alarm_control_panel/automation.h @@ -3,8 +3,7 @@ #include "esphome/core/automation.h" #include "alarm_control_panel.h" -namespace esphome { -namespace alarm_control_panel { +namespace esphome::alarm_control_panel { /// Trigger on any state change class StateTrigger : public Trigger<> { @@ -165,5 +164,4 @@ template class AlarmControlPanelCondition : public Condition Date: Fri, 26 Dec 2025 07:58:46 -1000 Subject: [PATCH 026/302] [text_sensor] Return state by const reference to avoid copies (#12661) --- esphome/components/text_sensor/text_sensor.cpp | 4 ++-- esphome/components/text_sensor/text_sensor.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/text_sensor/text_sensor.cpp b/esphome/components/text_sensor/text_sensor.cpp index ad1dc0f521..8dfb9dad05 100644 --- a/esphome/components/text_sensor/text_sensor.cpp +++ b/esphome/components/text_sensor/text_sensor.cpp @@ -78,8 +78,8 @@ void TextSensor::add_on_raw_state_callback(std::functionraw_callback_.add(std::move(callback)); } -std::string TextSensor::get_state() const { return this->state; } -std::string TextSensor::get_raw_state() const { +const std::string &TextSensor::get_state() const { return this->state; } +const std::string &TextSensor::get_raw_state() const { // Suppress deprecation warning - get_raw_state() is the replacement API #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" diff --git a/esphome/components/text_sensor/text_sensor.h b/esphome/components/text_sensor/text_sensor.h index 919bf81c8c..2cd8a65e87 100644 --- a/esphome/components/text_sensor/text_sensor.h +++ b/esphome/components/text_sensor/text_sensor.h @@ -37,9 +37,9 @@ class TextSensor : public EntityBase, public EntityBase_DeviceClass { #pragma GCC diagnostic pop /// Getter-syntax for .state. - std::string get_state() const; + const std::string &get_state() const; /// Getter-syntax for .raw_state - std::string get_raw_state() const; + const std::string &get_raw_state() const; void publish_state(const std::string &state); From 0919017d496a8c3613b4fbaeff2447986781201b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 26 Dec 2025 08:44:03 -1000 Subject: [PATCH 027/302] [wifi] Avoid unnecessary string copy in failed connection logging (#12659) --- esphome/components/wifi/wifi_component.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 242265344d..5fa894d8f9 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -1523,12 +1523,12 @@ void WiFiComponent::log_and_adjust_priority_for_failed_connect_() { return; // No BSSID to penalize } - // Get SSID for logging - std::string ssid; + // Get SSID for logging (use pointer to avoid copy) + const std::string *ssid = nullptr; if (this->retry_phase_ == WiFiRetryPhase::SCAN_CONNECTING && !this->scan_result_.empty()) { - ssid = this->scan_result_[0].get_ssid(); + ssid = &this->scan_result_[0].get_ssid(); } else if (const WiFiAP *config = this->get_selected_sta_()) { - ssid = config->get_ssid(); + ssid = &config->get_ssid(); } // Only decrease priority on the last attempt for this phase @@ -1548,8 +1548,8 @@ void WiFiComponent::log_and_adjust_priority_for_failed_connect_() { } char bssid_s[18]; format_mac_addr_upper(failed_bssid.value().data(), bssid_s); - ESP_LOGD(TAG, "Failed " LOG_SECRET("'%s'") " " LOG_SECRET("(%s)") ", priority %d → %d", ssid.c_str(), bssid_s, - old_priority, new_priority); + ESP_LOGD(TAG, "Failed " LOG_SECRET("'%s'") " " LOG_SECRET("(%s)") ", priority %d → %d", + ssid != nullptr ? ssid->c_str() : "", bssid_s, old_priority, new_priority); // After adjusting priority, check if all priorities are now at minimum // If so, clear the vector to save memory and reset for fresh start From f1fecd22e30748759490ca10be1fd4848a08eb72 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 26 Dec 2025 08:44:17 -1000 Subject: [PATCH 028/302] [web_server] Move HTTP header strings to flash on ESP8266 (#12668) --- esphome/components/web_server/web_server.cpp | 23 +++++++------------ .../web_server_base/web_server_base.h | 2 +- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index df8a5364cf..8a1ed49408 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -45,13 +45,6 @@ static const char *const TAG = "web_server"; static constexpr size_t PSTR_LOCAL_SIZE = 18; #define PSTR_LOCAL(mode_s) ESPHOME_strncpy_P(buf, (ESPHOME_PGM_P) ((mode_s)), PSTR_LOCAL_SIZE - 1) -#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS -static const char *const HEADER_PNA_NAME = "Private-Network-Access-Name"; -static const char *const HEADER_PNA_ID = "Private-Network-Access-ID"; -static const char *const HEADER_CORS_REQ_PNA = "Access-Control-Request-Private-Network"; -static const char *const HEADER_CORS_ALLOW_PNA = "Access-Control-Allow-Private-Network"; -#endif - // Parse URL and return match info static UrlMatch match_url(const char *url_ptr, size_t url_len, bool only_domain) { UrlMatch match{}; @@ -348,7 +341,7 @@ void WebServer::handle_index_request(AsyncWebServerRequest *request) { #else AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", INDEX_GZ, sizeof(INDEX_GZ)); #endif - response->addHeader("Content-Encoding", "gzip"); + response->addHeader(ESPHOME_F("Content-Encoding"), ESPHOME_F("gzip")); request->send(response); } #elif USE_WEBSERVER_VERSION >= 2 @@ -368,10 +361,10 @@ void WebServer::handle_index_request(AsyncWebServerRequest *request) { #ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS void WebServer::handle_pna_cors_request(AsyncWebServerRequest *request) { AsyncWebServerResponse *response = request->beginResponse(200, ""); - response->addHeader(HEADER_CORS_ALLOW_PNA, "true"); - response->addHeader(HEADER_PNA_NAME, App.get_name().c_str()); + response->addHeader(ESPHOME_F("Access-Control-Allow-Private-Network"), ESPHOME_F("true")); + response->addHeader(ESPHOME_F("Private-Network-Access-Name"), App.get_name().c_str()); char mac_s[18]; - response->addHeader(HEADER_PNA_ID, get_mac_address_pretty_into_buffer(mac_s)); + response->addHeader(ESPHOME_F("Private-Network-Access-ID"), get_mac_address_pretty_into_buffer(mac_s)); request->send(response); } #endif @@ -385,7 +378,7 @@ void WebServer::handle_css_request(AsyncWebServerRequest *request) { AsyncWebServerResponse *response = request->beginResponse_P(200, "text/css", ESPHOME_WEBSERVER_CSS_INCLUDE, ESPHOME_WEBSERVER_CSS_INCLUDE_SIZE); #endif - response->addHeader("Content-Encoding", "gzip"); + response->addHeader(ESPHOME_F("Content-Encoding"), ESPHOME_F("gzip")); request->send(response); } #endif @@ -399,7 +392,7 @@ void WebServer::handle_js_request(AsyncWebServerRequest *request) { AsyncWebServerResponse *response = request->beginResponse_P(200, "text/javascript", ESPHOME_WEBSERVER_JS_INCLUDE, ESPHOME_WEBSERVER_JS_INCLUDE_SIZE); #endif - response->addHeader("Content-Encoding", "gzip"); + response->addHeader(ESPHOME_F("Content-Encoding"), ESPHOME_F("gzip")); request->send(response); } #endif @@ -1841,7 +1834,7 @@ bool WebServer::canHandle(AsyncWebServerRequest *request) const { } #ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS - if (method == HTTP_OPTIONS && request->hasHeader(HEADER_CORS_REQ_PNA)) + if (method == HTTP_OPTIONS && request->hasHeader(ESPHOME_F("Access-Control-Request-Private-Network"))) return true; #endif @@ -1974,7 +1967,7 @@ void WebServer::handleRequest(AsyncWebServerRequest *request) { #endif #ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS - if (request->method() == HTTP_OPTIONS && request->hasHeader(HEADER_CORS_REQ_PNA)) { + if (request->method() == HTTP_OPTIONS && request->hasHeader(ESPHOME_F("Access-Control-Request-Private-Network"))) { this->handle_pna_cors_request(request); return; } diff --git a/esphome/components/web_server_base/web_server_base.h b/esphome/components/web_server_base/web_server_base.h index 54ec997671..7e95e00f29 100644 --- a/esphome/components/web_server_base/web_server_base.h +++ b/esphome/components/web_server_base/web_server_base.h @@ -100,7 +100,7 @@ class WebServerBase : public Component { } this->server_ = std::make_unique(this->port_); // All content is controlled and created by user - so allowing all origins is fine here. - DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); + DefaultHeaders::Instance().addHeader(ESPHOME_F("Access-Control-Allow-Origin"), ESPHOME_F("*")); this->server_->begin(); for (auto *handler : this->handlers_) From 5a2e0612a818a73543fca92d5126b9dda523d1b1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 26 Dec 2025 08:44:34 -1000 Subject: [PATCH 029/302] [web_server] Use C++17 nested namespace syntax (#12663) --- esphome/components/web_server/list_entities.cpp | 6 ++---- esphome/components/web_server/list_entities.h | 11 +++++------ esphome/components/web_server/ota/ota_web_server.cpp | 6 ++---- esphome/components/web_server/ota/ota_web_server.h | 6 ++---- esphome/components/web_server/server_index_v2.h | 6 ++---- esphome/components/web_server/server_index_v3.h | 6 ++---- esphome/components/web_server/web_server.cpp | 6 ++---- esphome/components/web_server/web_server.h | 6 ++---- esphome/components/web_server/web_server_v1.cpp | 6 ++---- 9 files changed, 21 insertions(+), 38 deletions(-) diff --git a/esphome/components/web_server/list_entities.cpp b/esphome/components/web_server/list_entities.cpp index 16b1d1e797..55beed812f 100644 --- a/esphome/components/web_server/list_entities.cpp +++ b/esphome/components/web_server/list_entities.cpp @@ -6,8 +6,7 @@ #include "web_server.h" -namespace esphome { -namespace web_server { +namespace esphome::web_server { #ifdef USE_ESP32 ListEntitiesIterator::ListEntitiesIterator(const WebServer *ws, AsyncEventSource *es) : web_server_(ws), events_(es) {} @@ -157,6 +156,5 @@ bool ListEntitiesIterator::on_update(update::UpdateEntity *obj) { } #endif -} // namespace web_server -} // namespace esphome +} // namespace esphome::web_server #endif diff --git a/esphome/components/web_server/list_entities.h b/esphome/components/web_server/list_entities.h index 5d9049b082..56fd91a8c6 100644 --- a/esphome/components/web_server/list_entities.h +++ b/esphome/components/web_server/list_entities.h @@ -4,13 +4,13 @@ #ifdef USE_WEBSERVER #include "esphome/core/component.h" #include "esphome/core/component_iterator.h" -namespace esphome { +namespace esphome::web_server_idf { #ifdef USE_ESP32 -namespace web_server_idf { class AsyncEventSource; -} #endif -namespace web_server { +} // namespace esphome::web_server_idf + +namespace esphome::web_server { #if !defined(USE_ESP32) && defined(USE_ARDUINO) class DeferredUpdateEventSource; @@ -99,6 +99,5 @@ class ListEntitiesIterator : public ComponentIterator { #endif }; -} // namespace web_server -} // namespace esphome +} // namespace esphome::web_server #endif diff --git a/esphome/components/web_server/ota/ota_web_server.cpp b/esphome/components/web_server/ota/ota_web_server.cpp index f612aa056c..572c351245 100644 --- a/esphome/components/web_server/ota/ota_web_server.cpp +++ b/esphome/components/web_server/ota/ota_web_server.cpp @@ -23,8 +23,7 @@ using PlatformString = std::string; using PlatformString = String; #endif -namespace esphome { -namespace web_server { +namespace esphome::web_server { static const char *const TAG = "web_server.ota"; @@ -236,7 +235,6 @@ void WebServerOTAComponent::setup() { void WebServerOTAComponent::dump_config() { ESP_LOGCONFIG(TAG, "Web Server OTA"); } -} // namespace web_server -} // namespace esphome +} // namespace esphome::web_server #endif // USE_WEBSERVER_OTA diff --git a/esphome/components/web_server/ota/ota_web_server.h b/esphome/components/web_server/ota/ota_web_server.h index a7170c0e34..53ff99899c 100644 --- a/esphome/components/web_server/ota/ota_web_server.h +++ b/esphome/components/web_server/ota/ota_web_server.h @@ -7,8 +7,7 @@ #include "esphome/components/web_server_base/web_server_base.h" #include "esphome/core/component.h" -namespace esphome { -namespace web_server { +namespace esphome::web_server { class WebServerOTAComponent : public ota::OTAComponent { public: @@ -20,7 +19,6 @@ class WebServerOTAComponent : public ota::OTAComponent { friend class OTARequestHandler; }; -} // namespace web_server -} // namespace esphome +} // namespace esphome::web_server #endif // USE_WEBSERVER_OTA diff --git a/esphome/components/web_server/server_index_v2.h b/esphome/components/web_server/server_index_v2.h index e675d81552..b2d204c9e7 100644 --- a/esphome/components/web_server/server_index_v2.h +++ b/esphome/components/web_server/server_index_v2.h @@ -6,8 +6,7 @@ #include "esphome/core/hal.h" -namespace esphome { -namespace web_server { +namespace esphome::web_server { const uint8_t INDEX_GZ[] PROGMEM = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xcd, 0x7d, 0xdb, 0x72, 0xdb, 0xc6, 0xb6, 0xe0, 0xf3, @@ -644,8 +643,7 @@ const uint8_t INDEX_GZ[] PROGMEM = { 0x2b, 0x4d, 0x17, 0xb8, 0x87, 0x4c, 0xe9, 0x50, 0x19, 0x14, 0xba, 0x92, 0xde, 0x0a, 0xea, 0x97, 0xce, 0xad, 0x80, 0x4f, 0xc7, 0xf5, 0xfe, 0x1f, 0xe7, 0xe0, 0x1c, 0x12, 0xcf, 0x89, 0x00, 0x00}; -} // namespace web_server -} // namespace esphome +} // namespace esphome::web_server #endif #endif diff --git a/esphome/components/web_server/server_index_v3.h b/esphome/components/web_server/server_index_v3.h index 39518197a3..8a8ced9153 100644 --- a/esphome/components/web_server/server_index_v3.h +++ b/esphome/components/web_server/server_index_v3.h @@ -6,8 +6,7 @@ #include "esphome/core/hal.h" -namespace esphome { -namespace web_server { +namespace esphome::web_server { const uint8_t INDEX_GZ[] PROGMEM = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xcc, 0xbd, 0xeb, 0x7a, 0x1b, 0xb7, 0xb2, 0x20, 0xfa, @@ -4048,8 +4047,7 @@ const uint8_t INDEX_GZ[] PROGMEM = { 0x3b, 0x6c, 0x78, 0x02, 0xa6, 0xdc, 0xb4, 0xe8, 0xee, 0x6a, 0xc5, 0x97, 0x94, 0x7e, 0xd1, 0x9b, 0x83, 0x45, 0xb2, 0xf4, 0x87, 0xff, 0x07, 0x52, 0xaf, 0x09, 0x6c, 0x30, 0x6a, 0x03, 0x00}; -} // namespace web_server -} // namespace esphome +} // namespace esphome::web_server #endif #endif diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index 8a1ed49408..f613d6bc36 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -36,8 +36,7 @@ #endif #endif -namespace esphome { -namespace web_server { +namespace esphome::web_server { static const char *const TAG = "web_server"; @@ -2105,6 +2104,5 @@ void WebServer::add_sorting_group(uint64_t group_id, const std::string &group_na } #endif -} // namespace web_server -} // namespace esphome +} // namespace esphome::web_server #endif diff --git a/esphome/components/web_server/web_server.h b/esphome/components/web_server/web_server.h index 0078146284..b9e852c745 100644 --- a/esphome/components/web_server/web_server.h +++ b/esphome/components/web_server/web_server.h @@ -33,8 +33,7 @@ extern const uint8_t ESPHOME_WEBSERVER_JS_INCLUDE[] PROGMEM; extern const size_t ESPHOME_WEBSERVER_JS_INCLUDE_SIZE; #endif -namespace esphome { -namespace web_server { +namespace esphome::web_server { /// Internal helper struct that is used to parse incoming URLs struct UrlMatch { @@ -616,6 +615,5 @@ class WebServer : public Controller, #endif }; -} // namespace web_server -} // namespace esphome +} // namespace esphome::web_server #endif diff --git a/esphome/components/web_server/web_server_v1.cpp b/esphome/components/web_server/web_server_v1.cpp index cbc25b9dec..e27306ad78 100644 --- a/esphome/components/web_server/web_server_v1.cpp +++ b/esphome/components/web_server/web_server_v1.cpp @@ -3,8 +3,7 @@ #if USE_WEBSERVER_VERSION == 1 -namespace esphome { -namespace web_server { +namespace esphome::web_server { void write_row(AsyncResponseStream *stream, EntityBase *obj, const std::string &klass, const std::string &action, const std::function &action_func = nullptr) { @@ -215,6 +214,5 @@ void WebServer::handle_index_request(AsyncWebServerRequest *request) { request->send(stream); } -} // namespace web_server -} // namespace esphome +} // namespace esphome::web_server #endif From bdc087148a541241277ce13c489763c8064efa6e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 26 Dec 2025 12:52:41 -1000 Subject: [PATCH 030/302] [wifi_info] Reduce heap allocations in text sensor formatting (#12660) --- esphome/components/network/ip_address.h | 9 ++++ .../wifi_info/wifi_info_text_sensor.cpp | 45 +++++++++++++------ esphome/core/helpers.h | 24 ++++++++++ 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/esphome/components/network/ip_address.h b/esphome/components/network/ip_address.h index 3d8b062d0b..27cc212a47 100644 --- a/esphome/components/network/ip_address.h +++ b/esphome/components/network/ip_address.h @@ -40,6 +40,9 @@ using ip4_addr_t = in_addr; namespace esphome { namespace network { +/// Buffer size for IP address string (IPv6 max: 39 chars + null) +static constexpr size_t IP_ADDRESS_BUFFER_SIZE = 40; + struct IPAddress { public: #ifdef USE_HOST @@ -50,6 +53,10 @@ struct IPAddress { IPAddress(const std::string &in_address) { inet_aton(in_address.c_str(), &ip_addr_); } IPAddress(const ip_addr_t *other_ip) { ip_addr_ = *other_ip; } std::string str() const { return str_lower_case(inet_ntoa(ip_addr_)); } + /// Write IP address to buffer. Buffer must be at least IP_ADDRESS_BUFFER_SIZE bytes. + char *str_to(char *buf) const { + return const_cast(inet_ntop(AF_INET, &ip_addr_, buf, IP_ADDRESS_BUFFER_SIZE)); + } #else IPAddress() { ip_addr_set_zero(&ip_addr_); } IPAddress(uint8_t first, uint8_t second, uint8_t third, uint8_t fourth) { @@ -128,6 +135,8 @@ struct IPAddress { bool is_ip6() const { return IP_IS_V6(&ip_addr_); } bool is_multicast() const { return ip_addr_ismulticast(&ip_addr_); } std::string str() const { return str_lower_case(ipaddr_ntoa(&ip_addr_)); } + /// Write IP address to buffer. Buffer must be at least IP_ADDRESS_BUFFER_SIZE bytes. + char *str_to(char *buf) const { return ipaddr_ntoa_r(&ip_addr_, buf, IP_ADDRESS_BUFFER_SIZE); } bool operator==(const IPAddress &other) const { return ip_addr_cmp(&ip_addr_, &other.ip_addr_); } bool operator!=(const IPAddress &other) const { return !ip_addr_cmp(&ip_addr_, &other.ip_addr_); } IPAddress &operator+=(uint8_t increase) { diff --git a/esphome/components/wifi_info/wifi_info_text_sensor.cpp b/esphome/components/wifi_info/wifi_info_text_sensor.cpp index 56cf49028c..eae0f87b40 100644 --- a/esphome/components/wifi_info/wifi_info_text_sensor.cpp +++ b/esphome/components/wifi_info/wifi_info_text_sensor.cpp @@ -46,8 +46,13 @@ void DNSAddressWifiInfo::dump_config() { LOG_TEXT_SENSOR("", "DNS Address", this void DNSAddressWifiInfo::on_ip_state(const network::IPAddresses &ips, const network::IPAddress &dns1, const network::IPAddress &dns2) { - std::string dns_results = dns1.str() + " " + dns2.str(); - this->publish_state(dns_results); + // IP_ADDRESS_BUFFER_SIZE (40) = max IP (39) + null; space reuses first null's slot + char buf[network::IP_ADDRESS_BUFFER_SIZE * 2]; + dns1.str_to(buf); + size_t len1 = strlen(buf); + buf[len1] = ' '; + dns2.str_to(buf + len1 + 1); + this->publish_state(buf); } /********************** @@ -58,22 +63,36 @@ void ScanResultsWiFiInfo::setup() { wifi::global_wifi_component->add_scan_result void ScanResultsWiFiInfo::dump_config() { LOG_TEXT_SENSOR("", "Scan Results", this); } +// Format: "SSID: -XXdB\n" - caller must ensure ssid_len + 9 bytes available in buffer +static char *format_scan_entry(char *buf, const char *ssid, size_t ssid_len, int8_t rssi) { + memcpy(buf, ssid, ssid_len); + buf += ssid_len; + *buf++ = ':'; + *buf++ = ' '; + buf = int8_to_str(buf, rssi); + *buf++ = 'd'; + *buf++ = 'B'; + *buf++ = '\n'; + return buf; +} + void ScanResultsWiFiInfo::on_wifi_scan_results(const wifi::wifi_scan_vector_t &results) { - std::string scan_results; + char buf[MAX_STATE_LENGTH + 1]; + char *ptr = buf; + const char *end = buf + MAX_STATE_LENGTH; + for (const auto &scan : results) { if (scan.get_is_hidden()) continue; + const std::string &ssid = scan.get_ssid(); + // Max space: ssid + ": " (2) + "-128" (4) + "dB\n" (3) = ssid + 9 + if (ptr + ssid.size() + 9 > end) + break; + ptr = format_scan_entry(ptr, ssid.c_str(), ssid.size(), scan.get_rssi()); + } - scan_results += scan.get_ssid(); - scan_results += ": "; - scan_results += esphome::to_string(scan.get_rssi()); - scan_results += "dB\n"; - } - // There's a limit of 255 characters per state; longer states just don't get sent so we truncate it - if (scan_results.length() > MAX_STATE_LENGTH) { - scan_results.resize(MAX_STATE_LENGTH); - } - this->publish_state(scan_results); + *ptr = '\0'; + this->publish_state(buf); } /*************** diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 769041160c..48a2313e2c 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -684,6 +684,30 @@ inline char format_hex_char(uint8_t v) { return v >= 10 ? 'a' + (v - 10) : '0' + /// This always uses uppercase (A-F) for pretty/human-readable output inline char format_hex_pretty_char(uint8_t v) { return v >= 10 ? 'A' + (v - 10) : '0' + v; } +/// Write int8 value to buffer without modulo operations. +/// Buffer must have at least 4 bytes free. Returns pointer past last char written. +inline char *int8_to_str(char *buf, int8_t val) { + int32_t v = val; + if (v < 0) { + *buf++ = '-'; + v = -v; + } + if (v >= 100) { + *buf++ = '1'; // int8 max is 128, so hundreds digit is always 1 + v -= 100; + // Must write tens digit (even if 0) after hundreds + int32_t tens = v / 10; + *buf++ = '0' + tens; + v -= tens * 10; + } else if (v >= 10) { + int32_t tens = v / 10; + *buf++ = '0' + tens; + v -= tens * 10; + } + *buf++ = '0' + v; + return buf; +} + /// Format MAC address as XX:XX:XX:XX:XX:XX (uppercase) inline void format_mac_addr_upper(const uint8_t *mac, char *output) { for (size_t i = 0; i < 6; i++) { From 34067f8b15b7159e8391c9905a301e110d610e94 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 27 Dec 2025 08:29:15 -1000 Subject: [PATCH 031/302] [esp8266] Native OTA backend to reduce Arduino dependencies (#12675) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- esphome/components/esp8266/__init__.py | 8 +- .../esp8266/exclude_updater.py.script | 21 ++ .../components/esphome/ota/ota_esphome.cpp | 2 +- .../http_request/ota/ota_http_request.cpp | 2 +- esphome/components/ota/__init__.py | 2 +- .../ota/ota_backend_arduino_esp8266.cpp | 89 ----- .../ota/ota_backend_arduino_esp8266.h | 33 -- .../components/ota/ota_backend_esp8266.cpp | 356 ++++++++++++++++++ esphome/components/ota/ota_backend_esp8266.h | 58 +++ .../web_server/ota/ota_web_server.cpp | 7 +- 10 files changed, 446 insertions(+), 132 deletions(-) create mode 100644 esphome/components/esp8266/exclude_updater.py.script delete mode 100644 esphome/components/ota/ota_backend_arduino_esp8266.cpp delete mode 100644 esphome/components/ota/ota_backend_arduino_esp8266.h create mode 100644 esphome/components/ota/ota_backend_esp8266.cpp create mode 100644 esphome/components/ota/ota_backend_esp8266.h diff --git a/esphome/components/esp8266/__init__.py b/esphome/components/esp8266/__init__.py index a74f9ee8ce..c4969a79b2 100644 --- a/esphome/components/esp8266/__init__.py +++ b/esphome/components/esp8266/__init__.py @@ -191,7 +191,8 @@ async def to_code(config): cg.add_define(ThreadModel.SINGLE) cg.add_platformio_option( - "extra_scripts", ["pre:testing_mode.py", "post:post_build.py"] + "extra_scripts", + ["pre:testing_mode.py", "pre:exclude_updater.py", "post:post_build.py"], ) conf = config[CONF_FRAMEWORK] @@ -278,3 +279,8 @@ def copy_files(): testing_mode_file, CORE.relative_build_path("testing_mode.py"), ) + exclude_updater_file = dir / "exclude_updater.py.script" + copy_file_if_changed( + exclude_updater_file, + CORE.relative_build_path("exclude_updater.py"), + ) diff --git a/esphome/components/esp8266/exclude_updater.py.script b/esphome/components/esp8266/exclude_updater.py.script new file mode 100644 index 0000000000..69331e3b03 --- /dev/null +++ b/esphome/components/esp8266/exclude_updater.py.script @@ -0,0 +1,21 @@ +# pylint: disable=E0602 +Import("env") # noqa + +import os + +# Filter out Updater.cpp from the Arduino core build +# This saves 228 bytes of .bss by not instantiating the global Update object +# ESPHome uses its own native OTA backend instead + + +def filter_updater_from_core(env, node): + """Filter callback to exclude Updater.cpp from framework build.""" + path = node.get_path() + if path.endswith("Updater.cpp"): + print(f"ESPHome: Excluding {os.path.basename(path)} from build (using native OTA backend)") + return None + return node + + +# Apply the filter to framework sources +env.AddBuildMiddleware(filter_updater_from_core, "**/cores/esp8266/Updater.cpp") diff --git a/esphome/components/esphome/ota/ota_esphome.cpp b/esphome/components/esphome/ota/ota_esphome.cpp index b589a6119f..f9984e1425 100644 --- a/esphome/components/esphome/ota/ota_esphome.cpp +++ b/esphome/components/esphome/ota/ota_esphome.cpp @@ -10,7 +10,7 @@ #endif #include "esphome/components/network/util.h" #include "esphome/components/ota/ota_backend.h" -#include "esphome/components/ota/ota_backend_arduino_esp8266.h" +#include "esphome/components/ota/ota_backend_esp8266.h" #include "esphome/components/ota/ota_backend_arduino_libretiny.h" #include "esphome/components/ota/ota_backend_arduino_rp2040.h" #include "esphome/components/ota/ota_backend_esp_idf.h" diff --git a/esphome/components/http_request/ota/ota_http_request.cpp b/esphome/components/http_request/ota/ota_http_request.cpp index 058579752e..2cd7489e38 100644 --- a/esphome/components/http_request/ota/ota_http_request.cpp +++ b/esphome/components/http_request/ota/ota_http_request.cpp @@ -7,7 +7,7 @@ #include "esphome/components/md5/md5.h" #include "esphome/components/watchdog/watchdog.h" #include "esphome/components/ota/ota_backend.h" -#include "esphome/components/ota/ota_backend_arduino_esp8266.h" +#include "esphome/components/ota/ota_backend_esp8266.h" #include "esphome/components/ota/ota_backend_arduino_rp2040.h" #include "esphome/components/ota/ota_backend_esp_idf.h" diff --git a/esphome/components/ota/__init__.py b/esphome/components/ota/__init__.py index 8bed9cee42..a514a7482f 100644 --- a/esphome/components/ota/__init__.py +++ b/esphome/components/ota/__init__.py @@ -148,7 +148,7 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform( PlatformFramework.ESP32_ARDUINO, PlatformFramework.ESP32_IDF, }, - "ota_backend_arduino_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, + "ota_backend_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, "ota_backend_arduino_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO}, "ota_backend_arduino_libretiny.cpp": { PlatformFramework.BK72XX_ARDUINO, diff --git a/esphome/components/ota/ota_backend_arduino_esp8266.cpp b/esphome/components/ota/ota_backend_arduino_esp8266.cpp deleted file mode 100644 index 375c4e7200..0000000000 --- a/esphome/components/ota/ota_backend_arduino_esp8266.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#ifdef USE_ARDUINO -#ifdef USE_ESP8266 -#include "ota_backend_arduino_esp8266.h" -#include "ota_backend.h" - -#include "esphome/components/esp8266/preferences.h" -#include "esphome/core/defines.h" -#include "esphome/core/log.h" - -#include - -namespace esphome { -namespace ota { - -static const char *const TAG = "ota.arduino_esp8266"; - -std::unique_ptr make_ota_backend() { return make_unique(); } - -OTAResponseTypes ArduinoESP8266OTABackend::begin(size_t image_size) { - // Handle UPDATE_SIZE_UNKNOWN (0) by calculating available space - if (image_size == 0) { - // NOLINTNEXTLINE(readability-static-accessed-through-instance) - image_size = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; - } - bool ret = Update.begin(image_size, U_FLASH); - if (ret) { - esp8266::preferences_prevent_write(true); - return OTA_RESPONSE_OK; - } - - uint8_t error = Update.getError(); - if (error == UPDATE_ERROR_BOOTSTRAP) - return OTA_RESPONSE_ERROR_INVALID_BOOTSTRAPPING; - if (error == UPDATE_ERROR_NEW_FLASH_CONFIG) - return OTA_RESPONSE_ERROR_WRONG_NEW_FLASH_CONFIG; - if (error == UPDATE_ERROR_FLASH_CONFIG) - return OTA_RESPONSE_ERROR_WRONG_CURRENT_FLASH_CONFIG; - if (error == UPDATE_ERROR_SPACE) - return OTA_RESPONSE_ERROR_ESP8266_NOT_ENOUGH_SPACE; - - ESP_LOGE(TAG, "Begin error: %d", error); - - return OTA_RESPONSE_ERROR_UNKNOWN; -} - -void ArduinoESP8266OTABackend::set_update_md5(const char *md5) { - Update.setMD5(md5); - this->md5_set_ = true; -} - -OTAResponseTypes ArduinoESP8266OTABackend::write(uint8_t *data, size_t len) { - size_t written = Update.write(data, len); - if (written == len) { - return OTA_RESPONSE_OK; - } - - uint8_t error = Update.getError(); - ESP_LOGE(TAG, "Write error: %d", error); - - return OTA_RESPONSE_ERROR_WRITING_FLASH; -} - -OTAResponseTypes ArduinoESP8266OTABackend::end() { - // Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5 - // This matches the behavior of the old web_server OTA implementation - bool success = Update.end(!this->md5_set_); - - // On ESP8266, Update.end() might return false even with error code 0 - // Check the actual error code to determine success - uint8_t error = Update.getError(); - - if (success || error == UPDATE_ERROR_OK) { - return OTA_RESPONSE_OK; - } - - ESP_LOGE(TAG, "End error: %d", error); - return OTA_RESPONSE_ERROR_UPDATE_END; -} - -void ArduinoESP8266OTABackend::abort() { - Update.end(); - esp8266::preferences_prevent_write(false); -} - -} // namespace ota -} // namespace esphome - -#endif -#endif diff --git a/esphome/components/ota/ota_backend_arduino_esp8266.h b/esphome/components/ota/ota_backend_arduino_esp8266.h deleted file mode 100644 index e1b9015cc7..0000000000 --- a/esphome/components/ota/ota_backend_arduino_esp8266.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#ifdef USE_ARDUINO -#ifdef USE_ESP8266 -#include "ota_backend.h" - -#include "esphome/core/defines.h" -#include "esphome/core/macros.h" - -namespace esphome { -namespace ota { - -class ArduinoESP8266OTABackend : public OTABackend { - public: - OTAResponseTypes begin(size_t image_size) override; - void set_update_md5(const char *md5) override; - OTAResponseTypes write(uint8_t *data, size_t len) override; - OTAResponseTypes end() override; - void abort() override; -#if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 7, 0) - bool supports_compression() override { return true; } -#else - bool supports_compression() override { return false; } -#endif - - private: - bool md5_set_{false}; -}; - -} // namespace ota -} // namespace esphome - -#endif -#endif diff --git a/esphome/components/ota/ota_backend_esp8266.cpp b/esphome/components/ota/ota_backend_esp8266.cpp new file mode 100644 index 0000000000..4b84708cd9 --- /dev/null +++ b/esphome/components/ota/ota_backend_esp8266.cpp @@ -0,0 +1,356 @@ +#ifdef USE_ESP8266 +#include "ota_backend_esp8266.h" +#include "ota_backend.h" + +#include "esphome/components/esp8266/preferences.h" +#include "esphome/core/application.h" +#include "esphome/core/defines.h" +#include "esphome/core/helpers.h" +#include "esphome/core/log.h" + +#include +#include + +#include + +extern "C" { +#include +#include +#include +#include +#include +} + +// Note: FLASH_SECTOR_SIZE (0x1000) is already defined in spi_flash_geometry.h + +// Flash header offsets +static constexpr uint8_t FLASH_MODE_OFFSET = 2; + +// Firmware magic bytes +static constexpr uint8_t FIRMWARE_MAGIC = 0xE9; +static constexpr uint8_t GZIP_MAGIC_1 = 0x1F; +static constexpr uint8_t GZIP_MAGIC_2 = 0x8B; + +// ESP8266 flash memory base address (memory-mapped flash starts here) +static constexpr uint32_t FLASH_BASE_ADDRESS = 0x40200000; + +// Boot mode extraction from GPI register (bits 16-19 contain boot mode) +static constexpr int BOOT_MODE_SHIFT = 16; +static constexpr int BOOT_MODE_MASK = 0xf; + +// Boot mode indicating UART download mode (OTA not possible) +static constexpr int BOOT_MODE_UART_DOWNLOAD = 1; + +// Minimum buffer size when memory is constrained +static constexpr size_t MIN_BUFFER_SIZE = 256; + +namespace esphome::ota { + +static const char *const TAG = "ota.esp8266"; + +std::unique_ptr make_ota_backend() { return make_unique(); } + +OTAResponseTypes ESP8266OTABackend::begin(size_t image_size) { + // Handle UPDATE_SIZE_UNKNOWN (0) by calculating available space + if (image_size == 0) { + // Round down to sector boundary: subtract one sector, then mask to sector alignment + // NOLINTNEXTLINE(readability-static-accessed-through-instance) + image_size = (ESP.getFreeSketchSpace() - FLASH_SECTOR_SIZE) & ~(FLASH_SECTOR_SIZE - 1); + } + + // Check boot mode - if boot mode is UART download mode, + // we will not be able to reset into normal mode once update is done + int boot_mode = (GPI >> BOOT_MODE_SHIFT) & BOOT_MODE_MASK; + if (boot_mode == BOOT_MODE_UART_DOWNLOAD) { + return OTA_RESPONSE_ERROR_INVALID_BOOTSTRAPPING; + } + + // Check flash configuration - real size must be >= configured size + // NOLINTNEXTLINE(readability-static-accessed-through-instance) + if (!ESP.checkFlashConfig(false)) { + return OTA_RESPONSE_ERROR_WRONG_CURRENT_FLASH_CONFIG; + } + + // Get current sketch size + // NOLINTNEXTLINE(readability-static-accessed-through-instance) + uint32_t sketch_size = ESP.getSketchSize(); + + // Size of current sketch rounded to sector boundary + uint32_t current_sketch_size = (sketch_size + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); + + // Size of update rounded to sector boundary + uint32_t rounded_size = (image_size + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); + + // End of available space for sketch and update (start of filesystem) + uint32_t update_end_address = FS_start - FLASH_BASE_ADDRESS; + + // Calculate start address for the update (write from end backwards) + this->start_address_ = (update_end_address > rounded_size) ? (update_end_address - rounded_size) : 0; + + // Check if there's enough space for both current sketch and update + if (this->start_address_ < current_sketch_size) { + return OTA_RESPONSE_ERROR_ESP8266_NOT_ENOUGH_SPACE; + } + + // Allocate buffer for sector writes (use smaller buffer if memory constrained) + // NOLINTNEXTLINE(readability-static-accessed-through-instance) + this->buffer_size_ = (ESP.getFreeHeap() > 2 * FLASH_SECTOR_SIZE) ? FLASH_SECTOR_SIZE : MIN_BUFFER_SIZE; + + // ESP8266's umm_malloc guarantees 4-byte aligned allocations, which is required + // for spi_flash_write(). This is the same pattern used by Arduino's Updater class. + this->buffer_ = make_unique(this->buffer_size_); + if (!this->buffer_) { + return OTA_RESPONSE_ERROR_UNKNOWN; + } + + this->current_address_ = this->start_address_; + this->image_size_ = image_size; + this->buffer_len_ = 0; + this->md5_set_ = false; + + // Disable WiFi sleep during update + wifi_set_sleep_type(NONE_SLEEP_T); + + // Prevent preference writes during update + esp8266::preferences_prevent_write(true); + + // Initialize MD5 computation + this->md5_.init(); + + ESP_LOGD(TAG, "OTA begin: start=0x%08" PRIX32 ", size=%zu", this->start_address_, image_size); + + return OTA_RESPONSE_OK; +} + +void ESP8266OTABackend::set_update_md5(const char *md5) { + // Parse hex string to bytes + if (parse_hex(md5, this->expected_md5_, 16)) { + this->md5_set_ = true; + } +} + +OTAResponseTypes ESP8266OTABackend::write(uint8_t *data, size_t len) { + if (!this->buffer_) { + return OTA_RESPONSE_ERROR_UNKNOWN; + } + + size_t written = 0; + while (written < len) { + // Calculate how much we can buffer + size_t to_buffer = std::min(len - written, this->buffer_size_ - this->buffer_len_); + memcpy(this->buffer_.get() + this->buffer_len_, data + written, to_buffer); + this->buffer_len_ += to_buffer; + written += to_buffer; + + // If buffer is full, write to flash + if (this->buffer_len_ == this->buffer_size_ && !this->write_buffer_()) { + return OTA_RESPONSE_ERROR_WRITING_FLASH; + } + } + + return OTA_RESPONSE_OK; +} + +bool ESP8266OTABackend::erase_sector_if_needed_() { + if ((this->current_address_ % FLASH_SECTOR_SIZE) != 0) { + return true; // Not at sector boundary + } + + App.feed_wdt(); + if (spi_flash_erase_sector(this->current_address_ / FLASH_SECTOR_SIZE) != SPI_FLASH_RESULT_OK) { + ESP_LOGE(TAG, "Flash erase failed at 0x%08" PRIX32, this->current_address_); + return false; + } + return true; +} + +bool ESP8266OTABackend::flash_write_() { + App.feed_wdt(); + if (spi_flash_write(this->current_address_, reinterpret_cast(this->buffer_.get()), this->buffer_len_) != + SPI_FLASH_RESULT_OK) { + ESP_LOGE(TAG, "Flash write failed at 0x%08" PRIX32, this->current_address_); + return false; + } + return true; +} + +bool ESP8266OTABackend::write_buffer_() { + if (this->buffer_len_ == 0) { + return true; + } + + if (!this->erase_sector_if_needed_()) { + return false; + } + + // Patch flash mode in first sector if needed + // This is analogous to what esptool.py does when it receives a --flash_mode argument + bool is_first_sector = (this->current_address_ == this->start_address_); + uint8_t original_flash_mode = 0; + bool patched_flash_mode = false; + + // Only patch if we have enough bytes to access flash mode offset and it's not GZIP + if (is_first_sector && this->buffer_len_ > FLASH_MODE_OFFSET && this->buffer_[0] != GZIP_MAGIC_1) { + // Not GZIP compressed - check and patch flash mode + uint8_t current_flash_mode = this->get_flash_chip_mode_(); + uint8_t buffer_flash_mode = this->buffer_[FLASH_MODE_OFFSET]; + + if (buffer_flash_mode != current_flash_mode) { + original_flash_mode = buffer_flash_mode; + this->buffer_[FLASH_MODE_OFFSET] = current_flash_mode; + patched_flash_mode = true; + } + } + + if (!this->flash_write_()) { + return false; + } + + // Restore original flash mode for MD5 calculation + if (patched_flash_mode) { + this->buffer_[FLASH_MODE_OFFSET] = original_flash_mode; + } + + // Update MD5 with original (unpatched) data + this->md5_.add(this->buffer_.get(), this->buffer_len_); + + this->current_address_ += this->buffer_len_; + this->buffer_len_ = 0; + + return true; +} + +bool ESP8266OTABackend::write_buffer_final_() { + // Similar to write_buffer_(), but without flash mode patching or MD5 update (for final padded write) + if (this->buffer_len_ == 0) { + return true; + } + + if (!this->erase_sector_if_needed_() || !this->flash_write_()) { + return false; + } + + this->current_address_ += this->buffer_len_; + this->buffer_len_ = 0; + + return true; +} + +OTAResponseTypes ESP8266OTABackend::end() { + // Write any remaining buffered data + if (this->buffer_len_ > 0) { + // Add actual data to MD5 before padding + this->md5_.add(this->buffer_.get(), this->buffer_len_); + + // Pad to 4-byte alignment for flash write + while (this->buffer_len_ % 4 != 0) { + this->buffer_[this->buffer_len_++] = 0xFF; + } + if (!this->write_buffer_final_()) { + this->abort(); + return OTA_RESPONSE_ERROR_WRITING_FLASH; + } + } + + // Calculate actual bytes written + size_t actual_size = this->current_address_ - this->start_address_; + + // Check if any data was written + if (actual_size == 0) { + ESP_LOGE(TAG, "No data written"); + this->abort(); + return OTA_RESPONSE_ERROR_UPDATE_END; + } + + // Verify MD5 if set (strict mode), otherwise use lenient mode + // In lenient mode (no MD5), we accept whatever was written + if (this->md5_set_) { + this->md5_.calculate(); + if (!this->md5_.equals_bytes(this->expected_md5_)) { + ESP_LOGE(TAG, "MD5 mismatch"); + this->abort(); + return OTA_RESPONSE_ERROR_MD5_MISMATCH; + } + } else { + // Lenient mode: adjust size to what was actually written + // This matches Arduino's Update.end(true) behavior + this->image_size_ = actual_size; + } + + // Verify firmware header + if (!this->verify_end_()) { + this->abort(); + return OTA_RESPONSE_ERROR_UPDATE_END; + } + + // Write eboot command to copy firmware on next boot + eboot_command ebcmd; + ebcmd.action = ACTION_COPY_RAW; + ebcmd.args[0] = this->start_address_; + ebcmd.args[1] = 0x00000; // Destination: start of flash + ebcmd.args[2] = this->image_size_; + eboot_command_write(&ebcmd); + + ESP_LOGI(TAG, "OTA update staged: 0x%08" PRIX32 " -> 0x00000, size=%zu", this->start_address_, this->image_size_); + + // Clean up + this->buffer_.reset(); + esp8266::preferences_prevent_write(false); + + return OTA_RESPONSE_OK; +} + +void ESP8266OTABackend::abort() { + this->buffer_.reset(); + this->buffer_len_ = 0; + this->image_size_ = 0; + esp8266::preferences_prevent_write(false); +} + +bool ESP8266OTABackend::verify_end_() { + uint32_t buf; + if (spi_flash_read(this->start_address_, &buf, 4) != SPI_FLASH_RESULT_OK) { + ESP_LOGE(TAG, "Failed to read firmware header"); + return false; + } + + uint8_t *bytes = reinterpret_cast(&buf); + + // Check for GZIP (compressed firmware) + if (bytes[0] == GZIP_MAGIC_1 && bytes[1] == GZIP_MAGIC_2) { + // GZIP compressed - can't verify further + return true; + } + + // Check firmware magic byte + if (bytes[0] != FIRMWARE_MAGIC) { + ESP_LOGE(TAG, "Invalid firmware magic: 0x%02X (expected 0x%02X)", bytes[0], FIRMWARE_MAGIC); + return false; + } + +#if !FLASH_MAP_SUPPORT + // Check if new firmware's flash size fits (only when auto-detection is disabled) + // With FLASH_MAP_SUPPORT (modern cores), flash size is auto-detected from chip + // NOLINTNEXTLINE(readability-static-accessed-through-instance) + uint32_t bin_flash_size = ESP.magicFlashChipSize((bytes[3] & 0xf0) >> 4); + // NOLINTNEXTLINE(readability-static-accessed-through-instance) + if (bin_flash_size > ESP.getFlashChipRealSize()) { + ESP_LOGE(TAG, "Firmware flash size (%" PRIu32 ") exceeds chip size (%" PRIu32 ")", bin_flash_size, + ESP.getFlashChipRealSize()); + return false; + } +#endif + + return true; +} + +uint8_t ESP8266OTABackend::get_flash_chip_mode_() { + uint32_t data; + if (spi_flash_read(0x0000, &data, 4) != SPI_FLASH_RESULT_OK) { + return 0; // Default to QIO + } + return (reinterpret_cast(&data))[FLASH_MODE_OFFSET]; +} + +} // namespace esphome::ota +#endif // USE_ESP8266 diff --git a/esphome/components/ota/ota_backend_esp8266.h b/esphome/components/ota/ota_backend_esp8266.h new file mode 100644 index 0000000000..a9d6dd2ccc --- /dev/null +++ b/esphome/components/ota/ota_backend_esp8266.h @@ -0,0 +1,58 @@ +#pragma once +#ifdef USE_ESP8266 +#include "ota_backend.h" + +#include "esphome/components/md5/md5.h" +#include "esphome/core/defines.h" + +#include + +namespace esphome::ota { + +/// OTA backend for ESP8266 using native SDK functions. +/// This implementation bypasses the Arduino Updater library to save ~228 bytes of RAM +/// by not having a global Update object in .bss. +class ESP8266OTABackend : public OTABackend { + public: + OTAResponseTypes begin(size_t image_size) override; + void set_update_md5(const char *md5) override; + OTAResponseTypes write(uint8_t *data, size_t len) override; + OTAResponseTypes end() override; + void abort() override; + // Compression supported in all ESP8266 Arduino versions ESPHome supports (>= 2.7.0) + bool supports_compression() override { return true; } + + protected: + /// Erase flash sector if current address is at sector boundary + bool erase_sector_if_needed_(); + + /// Write buffer to flash (does not update address or clear buffer) + bool flash_write_(); + + /// Write buffered data to flash and update MD5 + bool write_buffer_(); + + /// Write buffered data to flash without MD5 update (for final padded write) + bool write_buffer_final_(); + + /// Verify the firmware header is valid + bool verify_end_(); + + /// Get current flash chip mode from flash header + uint8_t get_flash_chip_mode_(); + + std::unique_ptr buffer_; + size_t buffer_size_{0}; + size_t buffer_len_{0}; + + uint32_t start_address_{0}; + uint32_t current_address_{0}; + size_t image_size_{0}; + + md5::MD5Digest md5_{}; + uint8_t expected_md5_[16]; // Fixed-size buffer for 128-bit (16-byte) MD5 digest + bool md5_set_{false}; +}; + +} // namespace esphome::ota +#endif // USE_ESP8266 diff --git a/esphome/components/web_server/ota/ota_web_server.cpp b/esphome/components/web_server/ota/ota_web_server.cpp index 572c351245..b8bea40b84 100644 --- a/esphome/components/web_server/ota/ota_web_server.cpp +++ b/esphome/components/web_server/ota/ota_web_server.cpp @@ -10,9 +10,7 @@ #endif #ifdef USE_ARDUINO -#ifdef USE_ESP8266 -#include -#elif defined(USE_ESP32) || defined(USE_LIBRETINY) +#if defined(USE_ESP32) || defined(USE_LIBRETINY) #include #endif #endif // USE_ARDUINO @@ -120,9 +118,6 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Platf // Platform-specific pre-initialization #ifdef USE_ARDUINO -#ifdef USE_ESP8266 - Update.runAsync(true); -#endif #if defined(USE_ESP32) || defined(USE_LIBRETINY) if (Update.isRunning()) { Update.abort(); From e9f2d75aab3a8e31f82e82e30ac7d0bc811e617d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 27 Dec 2025 08:34:45 -1000 Subject: [PATCH 032/302] [core] Add format_hex_to helper for zero-allocation hex formatting (#12670) --- esphome/components/one_wire/one_wire_bus.cpp | 6 ++++-- esphome/components/sx126x/sx126x.cpp | 4 +++- esphome/components/sx127x/sx127x.cpp | 4 +++- esphome/core/helpers.cpp | 13 +++++++++++++ esphome/core/helpers.h | 18 ++++++++++++++++++ 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/esphome/components/one_wire/one_wire_bus.cpp b/esphome/components/one_wire/one_wire_bus.cpp index c2542177cf..27b7d58a0f 100644 --- a/esphome/components/one_wire/one_wire_bus.cpp +++ b/esphome/components/one_wire/one_wire_bus.cpp @@ -49,7 +49,8 @@ void OneWireBus::search() { break; auto *address8 = reinterpret_cast(&address); if (crc8(address8, 7) != address8[7]) { - ESP_LOGW(TAG, "Dallas device 0x%s has invalid CRC.", format_hex(address).c_str()); + char hex_buf[17]; + ESP_LOGW(TAG, "Dallas device 0x%s has invalid CRC.", format_hex_to(hex_buf, address)); } else { this->devices_.push_back(address); } @@ -82,8 +83,9 @@ void OneWireBus::dump_devices_(const char *tag) { ESP_LOGW(tag, " Found no devices!"); } else { ESP_LOGCONFIG(tag, " Found devices:"); + char hex_buf[17]; // uint64_t = 16 hex chars + null for (auto &address : this->devices_) { - ESP_LOGCONFIG(tag, " 0x%s (%s)", format_hex(address).c_str(), LOG_STR_ARG(get_model_str(address & 0xff))); + ESP_LOGCONFIG(tag, " 0x%s (%s)", format_hex_to(hex_buf, address), LOG_STR_ARG(get_model_str(address & 0xff))); } } } diff --git a/esphome/components/sx126x/sx126x.cpp b/esphome/components/sx126x/sx126x.cpp index bb59f26b79..707d6f1fbf 100644 --- a/esphome/components/sx126x/sx126x.cpp +++ b/esphome/components/sx126x/sx126x.cpp @@ -527,7 +527,9 @@ void SX126x::dump_config() { this->spreading_factor_, cr, this->preamble_size_); } if (!this->sync_value_.empty()) { - ESP_LOGCONFIG(TAG, " Sync Value: 0x%s", format_hex(this->sync_value_).c_str()); + char hex_buf[17]; // 8 bytes max = 16 hex chars + null + ESP_LOGCONFIG(TAG, " Sync Value: 0x%s", + format_hex_to(hex_buf, this->sync_value_.data(), this->sync_value_.size())); } if (this->is_failed()) { ESP_LOGE(TAG, "Configuring SX126x failed"); diff --git a/esphome/components/sx127x/sx127x.cpp b/esphome/components/sx127x/sx127x.cpp index 8e6db5dc9e..3185574b1a 100644 --- a/esphome/components/sx127x/sx127x.cpp +++ b/esphome/components/sx127x/sx127x.cpp @@ -476,7 +476,9 @@ void SX127x::dump_config() { ESP_LOGCONFIG(TAG, " Payload Length: %" PRIu32, this->payload_length_); } if (!this->sync_value_.empty()) { - ESP_LOGCONFIG(TAG, " Sync Value: 0x%s", format_hex(this->sync_value_).c_str()); + char hex_buf[17]; // 8 bytes max = 16 hex chars + null + ESP_LOGCONFIG(TAG, " Sync Value: 0x%s", + format_hex_to(hex_buf, this->sync_value_.data(), this->sync_value_.size())); } if (this->preamble_size_ > 0 || this->preamble_detect_ > 0) { ESP_LOGCONFIG(TAG, diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index d7d32ea28f..5e361ecce2 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -297,6 +297,19 @@ std::string format_hex(const uint8_t *data, size_t length) { } std::string format_hex(const std::vector &data) { return format_hex(data.data(), data.size()); } +char *format_hex_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length) { + size_t max_bytes = (buffer_size - 1) / 2; + if (length > max_bytes) { + length = max_bytes; + } + for (size_t i = 0; i < length; i++) { + buffer[2 * i] = format_hex_char(data[i] >> 4); + buffer[2 * i + 1] = format_hex_char(data[i] & 0x0F); + } + buffer[length * 2] = '\0'; + return buffer; +} + // Shared implementation for uint8_t and string hex formatting static std::string format_hex_pretty_uint8(const uint8_t *data, size_t length, char separator, bool show_length) { if (data == nullptr || length == 0) diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 48a2313e2c..4319e32510 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -730,6 +730,24 @@ inline void format_mac_addr_lower_no_sep(const uint8_t *mac, char *output) { output[12] = '\0'; } +/// Format byte array as lowercase hex to buffer (base implementation). +char *format_hex_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length); + +/// Format byte array as lowercase hex to buffer. Automatically deduces buffer size. +/// Truncates output if data exceeds buffer capacity. Returns pointer to buffer. +template inline char *format_hex_to(char (&buffer)[N], const uint8_t *data, size_t length) { + static_assert(N >= 3, "Buffer must hold at least one hex byte (3 chars)"); + return format_hex_to(buffer, N, data, length); +} + +/// Format an unsigned integer in lowercased hex to buffer, starting with the most significant byte. +template::value, int> = 0> +inline char *format_hex_to(char (&buffer)[N], T val) { + static_assert(N >= sizeof(T) * 2 + 1, "Buffer too small for type"); + val = convert_big_endian(val); + return format_hex_to(buffer, reinterpret_cast(&val), sizeof(T)); +} + /// Format the six-byte array \p mac into a MAC address. std::string format_mac_address_pretty(const uint8_t mac[6]); /// Format the byte array \p data of length \p len in lowercased hex. From a275f37135ae249196691d813b93abc5bcf60dd4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 27 Dec 2025 08:35:16 -1000 Subject: [PATCH 033/302] [udp] Use stack buffer for listen address logging in dump_config (#12667) --- esphome/components/udp/udp_component.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esphome/components/udp/udp_component.cpp b/esphome/components/udp/udp_component.cpp index 9105ced21e..daa6c52f98 100644 --- a/esphome/components/udp/udp_component.cpp +++ b/esphome/components/udp/udp_component.cpp @@ -130,7 +130,8 @@ void UDPComponent::dump_config() { for (const auto &address : this->addresses_) ESP_LOGCONFIG(TAG, " Address: %s", address.c_str()); if (this->listen_address_.has_value()) { - ESP_LOGCONFIG(TAG, " Listen address: %s", this->listen_address_.value().str().c_str()); + char addr_buf[network::IP_ADDRESS_BUFFER_SIZE]; + ESP_LOGCONFIG(TAG, " Listen address: %s", this->listen_address_.value().str_to(addr_buf)); } ESP_LOGCONFIG(TAG, " Broadcasting: %s\n" From be0bf1e5b92a736d0b7bdc6ae95f60a68e92e2ad Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 27 Dec 2025 08:35:36 -1000 Subject: [PATCH 034/302] [lvgl] Fix lambdas in canvas actions called from outside LVGL context (#12671) --- esphome/components/lvgl/defines.py | 10 +++------- esphome/components/lvgl/lv_validation.py | 11 +++-------- esphome/components/lvgl/lvcode.py | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/esphome/components/lvgl/defines.py b/esphome/components/lvgl/defines.py index 1d528b2f73..91077a1ff4 100644 --- a/esphome/components/lvgl/defines.py +++ b/esphome/components/lvgl/defines.py @@ -5,7 +5,7 @@ Constants already defined in esphome.const are not duplicated here and must be i """ import logging -from typing import TYPE_CHECKING, Any +from typing import Any from esphome import codegen as cg, config_validation as cv from esphome.const import CONF_ITEMS @@ -96,13 +96,9 @@ class LValidator: return None if isinstance(value, Lambda): # Local import to avoid circular import - from .lvcode import CodeContext, LambdaContext + from .lvcode import get_lambda_context_args - if TYPE_CHECKING: - # CodeContext does not have get_automation_parameters - # so we need to assert the type here - assert isinstance(CodeContext.code_context, LambdaContext) - args = args or CodeContext.code_context.get_automation_parameters() + args = args or get_lambda_context_args() return cg.RawExpression( call_lambda( await cg.process_lambda(value, args, return_type=self.rtype) diff --git a/esphome/components/lvgl/lv_validation.py b/esphome/components/lvgl/lv_validation.py index 9c1dd22085..947e44b131 100644 --- a/esphome/components/lvgl/lv_validation.py +++ b/esphome/components/lvgl/lv_validation.py @@ -1,5 +1,5 @@ import re -from typing import TYPE_CHECKING, Any +from typing import Any import esphome.codegen as cg from esphome.components import image @@ -404,14 +404,9 @@ class TextValidator(LValidator): self, value: Any, args: list[tuple[SafeExpType, str]] | None = None ) -> Expression: # Local import to avoid circular import at module level + from .lvcode import get_lambda_context_args - from .lvcode import CodeContext, LambdaContext - - if TYPE_CHECKING: - # CodeContext does not have get_automation_parameters - # so we need to assert the type here - assert isinstance(CodeContext.code_context, LambdaContext) - args = args or CodeContext.code_context.get_automation_parameters() + args = args or get_lambda_context_args() if isinstance(value, dict): if format_str := value.get(CONF_FORMAT): diff --git a/esphome/components/lvgl/lvcode.py b/esphome/components/lvgl/lvcode.py index e2c70642a8..b79d1e88dd 100644 --- a/esphome/components/lvgl/lvcode.py +++ b/esphome/components/lvgl/lvcode.py @@ -1,4 +1,5 @@ import abc +from typing import TYPE_CHECKING from esphome import codegen as cg from esphome.config import Config @@ -200,6 +201,21 @@ class LvContext(LambdaContext): return self.add(*args) +def get_lambda_context_args() -> list[tuple[SafeExpType, str]]: + """Get automation parameters from the current lambda context if available. + + When called from outside LVGL's context (e.g., from interval), + CodeContext.code_context will be None, so return empty args. + """ + if CodeContext.code_context is None: + return [] + if TYPE_CHECKING: + # CodeContext base class doesn't define get_automation_parameters(), + # but LambdaContext and LvContext (the concrete implementations) do. + assert isinstance(CodeContext.code_context, LambdaContext) + return CodeContext.code_context.get_automation_parameters() + + class LocalVariable(MockObj): """ Create a local variable and enclose the code using it within a block. From f243e609a51b96771269b37e206e4aaaec811930 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 27 Dec 2025 08:35:58 -1000 Subject: [PATCH 035/302] [wifi] Use StringRef and std::span in WiFiConnectStateListener to avoid allocations (#12672) --- esphome/components/wifi/wifi_component.h | 4 +++- esphome/components/wifi/wifi_component_esp8266.cpp | 5 +++-- esphome/components/wifi/wifi_component_esp_idf.cpp | 5 +++-- esphome/components/wifi/wifi_component_libretiny.cpp | 5 +++-- esphome/components/wifi/wifi_component_pico_w.cpp | 7 +++++-- esphome/components/wifi_info/wifi_info_text_sensor.cpp | 6 +++--- esphome/components/wifi_info/wifi_info_text_sensor.h | 6 ++++-- esphome/components/wifi_signal/wifi_signal_sensor.h | 4 +++- 8 files changed, 27 insertions(+), 15 deletions(-) diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 604efa8a7e..4f888292f1 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -6,7 +6,9 @@ #include "esphome/core/automation.h" #include "esphome/core/component.h" #include "esphome/core/helpers.h" +#include "esphome/core/string_ref.h" +#include #include #include @@ -274,7 +276,7 @@ class WiFiScanResultsListener { */ class WiFiConnectStateListener { public: - virtual void on_wifi_connect_state(const std::string &ssid, const bssid_t &bssid) = 0; + virtual void on_wifi_connect_state(StringRef ssid, std::span bssid) = 0; }; /** Listener interface for WiFi power save mode changes. diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index 550b5579ff..598ae2d5b7 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -526,7 +526,7 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { s_sta_connected = true; #ifdef USE_WIFI_LISTENERS for (auto *listener : global_wifi_component->connect_state_listeners_) { - listener->on_wifi_connect_state(global_wifi_component->wifi_ssid(), global_wifi_component->wifi_bssid()); + listener->on_wifi_connect_state(StringRef(buf, it.ssid_len), it.bssid); } // For static IP configurations, GOT_IP event may not fire, so notify IP listeners here #ifdef USE_WIFI_MANUAL_IP @@ -559,8 +559,9 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { s_sta_connected = false; s_sta_connecting = false; #ifdef USE_WIFI_LISTENERS + static constexpr uint8_t EMPTY_BSSID[6] = {}; for (auto *listener : global_wifi_component->connect_state_listeners_) { - listener->on_wifi_connect_state("", bssid_t({0, 0, 0, 0, 0, 0})); + listener->on_wifi_connect_state(StringRef(), EMPTY_BSSID); } #endif break; diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 212514af93..67314ae31f 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -737,7 +737,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { s_sta_connected = true; #ifdef USE_WIFI_LISTENERS for (auto *listener : this->connect_state_listeners_) { - listener->on_wifi_connect_state(this->wifi_ssid(), this->wifi_bssid()); + listener->on_wifi_connect_state(StringRef(buf, it.ssid_len), it.bssid); } // For static IP configurations, GOT_IP event may not fire, so notify IP listeners here #ifdef USE_WIFI_MANUAL_IP @@ -772,8 +772,9 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { s_sta_connecting = false; error_from_callback_ = true; #ifdef USE_WIFI_LISTENERS + static constexpr uint8_t EMPTY_BSSID[6] = {}; for (auto *listener : this->connect_state_listeners_) { - listener->on_wifi_connect_state("", bssid_t({0, 0, 0, 0, 0, 0})); + listener->on_wifi_connect_state(StringRef(), EMPTY_BSSID); } #endif diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index 340537b228..2aa6fa3484 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -303,7 +303,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ format_mac_address_pretty(it.bssid).c_str(), it.channel, get_auth_mode_str(it.authmode)); #ifdef USE_WIFI_LISTENERS for (auto *listener : this->connect_state_listeners_) { - listener->on_wifi_connect_state(this->wifi_ssid(), this->wifi_bssid()); + listener->on_wifi_connect_state(StringRef(buf, it.ssid_len), it.bssid); } // For static IP configurations, GOT_IP event may not fire, so notify IP listeners here #ifdef USE_WIFI_MANUAL_IP @@ -357,8 +357,9 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ s_sta_connecting = false; #ifdef USE_WIFI_LISTENERS + static constexpr uint8_t EMPTY_BSSID[6] = {}; for (auto *listener : this->connect_state_listeners_) { - listener->on_wifi_connect_state("", bssid_t({0, 0, 0, 0, 0, 0})); + listener->on_wifi_connect_state(StringRef(), EMPTY_BSSID); } #endif break; diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index 61709852ff..b755b8544f 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -256,8 +256,10 @@ void WiFiComponent::wifi_loop_() { s_sta_was_connected = true; ESP_LOGV(TAG, "Connected"); #ifdef USE_WIFI_LISTENERS + String ssid = WiFi.SSID(); + bssid_t bssid = this->wifi_bssid(); for (auto *listener : this->connect_state_listeners_) { - listener->on_wifi_connect_state(this->wifi_ssid(), this->wifi_bssid()); + listener->on_wifi_connect_state(StringRef(ssid.c_str(), ssid.length()), bssid); } // For static IP configurations, notify IP listeners immediately as the IP is already configured #ifdef USE_WIFI_MANUAL_IP @@ -275,8 +277,9 @@ void WiFiComponent::wifi_loop_() { s_sta_had_ip = false; ESP_LOGV(TAG, "Disconnected"); #ifdef USE_WIFI_LISTENERS + static constexpr uint8_t EMPTY_BSSID[6] = {}; for (auto *listener : this->connect_state_listeners_) { - listener->on_wifi_connect_state("", bssid_t({0, 0, 0, 0, 0, 0})); + listener->on_wifi_connect_state(StringRef(), EMPTY_BSSID); } #endif } diff --git a/esphome/components/wifi_info/wifi_info_text_sensor.cpp b/esphome/components/wifi_info/wifi_info_text_sensor.cpp index eae0f87b40..0cca3e16ef 100644 --- a/esphome/components/wifi_info/wifi_info_text_sensor.cpp +++ b/esphome/components/wifi_info/wifi_info_text_sensor.cpp @@ -103,8 +103,8 @@ void SSIDWiFiInfo::setup() { wifi::global_wifi_component->add_connect_state_list void SSIDWiFiInfo::dump_config() { LOG_TEXT_SENSOR("", "SSID", this); } -void SSIDWiFiInfo::on_wifi_connect_state(const std::string &ssid, const wifi::bssid_t &bssid) { - this->publish_state(ssid); +void SSIDWiFiInfo::on_wifi_connect_state(StringRef ssid, std::span bssid) { + this->publish_state(ssid.str()); } /**************** @@ -115,7 +115,7 @@ void BSSIDWiFiInfo::setup() { wifi::global_wifi_component->add_connect_state_lis void BSSIDWiFiInfo::dump_config() { LOG_TEXT_SENSOR("", "BSSID", this); } -void BSSIDWiFiInfo::on_wifi_connect_state(const std::string &ssid, const wifi::bssid_t &bssid) { +void BSSIDWiFiInfo::on_wifi_connect_state(StringRef ssid, std::span bssid) { char buf[18] = "unknown"; if (mac_address_is_valid(bssid.data())) { format_mac_addr_upper(bssid.data(), buf); diff --git a/esphome/components/wifi_info/wifi_info_text_sensor.h b/esphome/components/wifi_info/wifi_info_text_sensor.h index b2242372da..6beb1372f5 100644 --- a/esphome/components/wifi_info/wifi_info_text_sensor.h +++ b/esphome/components/wifi_info/wifi_info_text_sensor.h @@ -2,10 +2,12 @@ #include "esphome/core/component.h" #include "esphome/core/helpers.h" +#include "esphome/core/string_ref.h" #include "esphome/components/text_sensor/text_sensor.h" #include "esphome/components/wifi/wifi_component.h" #ifdef USE_WIFI #include +#include namespace esphome::wifi_info { @@ -52,7 +54,7 @@ class SSIDWiFiInfo final : public Component, public text_sensor::TextSensor, pub void dump_config() override; // WiFiConnectStateListener interface - void on_wifi_connect_state(const std::string &ssid, const wifi::bssid_t &bssid) override; + void on_wifi_connect_state(StringRef ssid, std::span bssid) override; }; class BSSIDWiFiInfo final : public Component, public text_sensor::TextSensor, public wifi::WiFiConnectStateListener { @@ -61,7 +63,7 @@ class BSSIDWiFiInfo final : public Component, public text_sensor::TextSensor, pu void dump_config() override; // WiFiConnectStateListener interface - void on_wifi_connect_state(const std::string &ssid, const wifi::bssid_t &bssid) override; + void on_wifi_connect_state(StringRef ssid, std::span bssid) override; }; class PowerSaveModeWiFiInfo final : public Component, diff --git a/esphome/components/wifi_signal/wifi_signal_sensor.h b/esphome/components/wifi_signal/wifi_signal_sensor.h index 9f581f1eb2..2e1f8cbb2b 100644 --- a/esphome/components/wifi_signal/wifi_signal_sensor.h +++ b/esphome/components/wifi_signal/wifi_signal_sensor.h @@ -2,9 +2,11 @@ #include "esphome/core/component.h" #include "esphome/core/helpers.h" +#include "esphome/core/string_ref.h" #include "esphome/components/sensor/sensor.h" #include "esphome/components/wifi/wifi_component.h" #ifdef USE_WIFI +#include namespace esphome::wifi_signal { #ifdef USE_WIFI_LISTENERS @@ -28,7 +30,7 @@ class WiFiSignalSensor : public sensor::Sensor, public PollingComponent { #ifdef USE_WIFI_LISTENERS // WiFiConnectStateListener interface - update RSSI immediately on connect - void on_wifi_connect_state(const std::string &ssid, const wifi::bssid_t &bssid) override { this->update(); } + void on_wifi_connect_state(StringRef ssid, std::span bssid) override { this->update(); } #endif }; From a6097f4a0f7fd8229d12fdd61bf627b08aad7aff Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 27 Dec 2025 08:36:19 -1000 Subject: [PATCH 036/302] [wifi] Eliminate heap allocations in dump_config logging (#12664) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- esphome/components/wifi/wifi_component.cpp | 16 ++++++++++++---- esphome/components/wifi/wifi_component.h | 6 ++++++ .../components/wifi/wifi_component_esp8266.cpp | 12 ++++++++++++ .../components/wifi/wifi_component_esp_idf.cpp | 13 +++++++++++++ .../components/wifi/wifi_component_libretiny.cpp | 8 ++++++++ .../components/wifi/wifi_component_pico_w.cpp | 8 ++++++++ 6 files changed, 59 insertions(+), 4 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 5fa894d8f9..50c0938cf1 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -899,12 +899,20 @@ void WiFiComponent::print_connect_params_() { ESP_LOGCONFIG(TAG, " Disabled"); return; } + // Use stack buffers for IP address formatting to avoid heap allocations + char ip_buf[network::IP_ADDRESS_BUFFER_SIZE]; for (auto &ip : wifi_sta_ip_addresses()) { if (ip.is_set()) { - ESP_LOGCONFIG(TAG, " IP Address: %s", ip.str().c_str()); + ESP_LOGCONFIG(TAG, " IP Address: %s", ip.str_to(ip_buf)); } } int8_t rssi = wifi_rssi(); + // Use stack buffers for SSID and all IP addresses to avoid heap allocations + char ssid_buf[SSID_BUFFER_SIZE]; + char subnet_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char gateway_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char dns1_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char dns2_buf[network::IP_ADDRESS_BUFFER_SIZE]; ESP_LOGCONFIG(TAG, " SSID: " LOG_SECRET("'%s'") "\n" " BSSID: " LOG_SECRET("%s") "\n" @@ -915,9 +923,9 @@ void WiFiComponent::print_connect_params_() { " Gateway: %s\n" " DNS1: %s\n" " DNS2: %s", - wifi_ssid().c_str(), bssid_s, App.get_name().c_str(), rssi, LOG_STR_ARG(get_signal_bars(rssi)), - get_wifi_channel(), wifi_subnet_mask_().str().c_str(), wifi_gateway_ip_().str().c_str(), - wifi_dns_ip_(0).str().c_str(), wifi_dns_ip_(1).str().c_str()); + wifi_ssid_to(ssid_buf), bssid_s, App.get_name().c_str(), rssi, LOG_STR_ARG(get_signal_bars(rssi)), + get_wifi_channel(), wifi_subnet_mask_().str_to(subnet_buf), wifi_gateway_ip_().str_to(gateway_buf), + wifi_dns_ip_(0).str_to(dns1_buf), wifi_dns_ip_(1).str_to(dns2_buf)); #ifdef ESPHOME_LOG_HAS_VERBOSE if (const WiFiAP *config = this->get_selected_sta_(); config && config->has_bssid()) { ESP_LOGV(TAG, " Priority: %d", this->get_sta_priority(config->get_bssid())); diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 4f888292f1..ff2bfe12a4 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -61,6 +61,9 @@ namespace esphome::wifi { /// Sentinel value for RSSI when WiFi is not connected static constexpr int8_t WIFI_RSSI_DISCONNECTED = -127; +/// Buffer size for SSID (IEEE 802.11 max 32 bytes + null terminator) +static constexpr size_t SSID_BUFFER_SIZE = 33; + struct SavedWifiSettings { char ssid[33]; char password[65]; @@ -408,6 +411,9 @@ class WiFiComponent : public Component { network::IPAddresses wifi_sta_ip_addresses(); std::string wifi_ssid(); + /// Write SSID to buffer without heap allocation. + /// Returns pointer to buffer, or empty string if not connected. + const char *wifi_ssid_to(std::span buffer); bssid_t wifi_bssid(); int8_t wifi_rssi(); diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index 598ae2d5b7..1c744648bb 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -913,6 +913,18 @@ bssid_t WiFiComponent::wifi_bssid() { return bssid; } std::string WiFiComponent::wifi_ssid() { return WiFi.SSID().c_str(); } +const char *WiFiComponent::wifi_ssid_to(std::span buffer) { + struct station_config conf {}; + if (!wifi_station_get_config(&conf)) { + buffer[0] = '\0'; + return buffer.data(); + } + // conf.ssid is uint8[32], not null-terminated if full + size_t len = strnlen(reinterpret_cast(conf.ssid), sizeof(conf.ssid)); + memcpy(buffer.data(), conf.ssid, len); + buffer[len] = '\0'; + return buffer.data(); +} int8_t WiFiComponent::wifi_rssi() { if (WiFi.status() != WL_CONNECTED) return WIFI_RSSI_DISCONNECTED; diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 67314ae31f..b26ac3d2e2 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -1086,6 +1086,19 @@ std::string WiFiComponent::wifi_ssid() { size_t len = strnlen(ssid_s, sizeof(info.ssid)); return {ssid_s, len}; } +const char *WiFiComponent::wifi_ssid_to(std::span buffer) { + wifi_ap_record_t info{}; + esp_err_t err = esp_wifi_sta_get_ap_info(&info); + if (err != ESP_OK) { + buffer[0] = '\0'; + return buffer.data(); + } + // info.ssid is uint8[33], but only 32 bytes are SSID data + size_t len = strnlen(reinterpret_cast(info.ssid), 32); + memcpy(buffer.data(), info.ssid, len); + buffer[len] = '\0'; + return buffer.data(); +} int8_t WiFiComponent::wifi_rssi() { wifi_ap_record_t info; esp_err_t err = esp_wifi_sta_get_ap_info(&info); diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index 2aa6fa3484..9b8653d0db 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -554,6 +554,14 @@ bssid_t WiFiComponent::wifi_bssid() { return bssid; } std::string WiFiComponent::wifi_ssid() { return WiFi.SSID().c_str(); } +const char *WiFiComponent::wifi_ssid_to(std::span buffer) { + // TODO: Find direct LibreTiny API to avoid Arduino String allocation + String ssid = WiFi.SSID(); + size_t len = std::min(static_cast(ssid.length()), SSID_BUFFER_SIZE - 1); + memcpy(buffer.data(), ssid.c_str(), len); + buffer[len] = '\0'; + return buffer.data(); +} int8_t WiFiComponent::wifi_rssi() { return WiFi.status() == WL_CONNECTED ? WiFi.RSSI() : WIFI_RSSI_DISCONNECTED; } int32_t WiFiComponent::get_wifi_channel() { return WiFi.channel(); } network::IPAddress WiFiComponent::wifi_subnet_mask_() { return {WiFi.subnetMask()}; } diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index b755b8544f..1aa737ff4a 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -214,6 +214,14 @@ bssid_t WiFiComponent::wifi_bssid() { return bssid; } std::string WiFiComponent::wifi_ssid() { return WiFi.SSID().c_str(); } +const char *WiFiComponent::wifi_ssid_to(std::span buffer) { + // TODO: Find direct CYW43 API to avoid Arduino String allocation + String ssid = WiFi.SSID(); + size_t len = std::min(static_cast(ssid.length()), SSID_BUFFER_SIZE - 1); + memcpy(buffer.data(), ssid.c_str(), len); + buffer[len] = '\0'; + return buffer.data(); +} int8_t WiFiComponent::wifi_rssi() { return WiFi.status() == WL_CONNECTED ? WiFi.RSSI() : WIFI_RSSI_DISCONNECTED; } int32_t WiFiComponent::get_wifi_channel() { return WiFi.channel(); } From 5e99dd14ae78a9c0a59f4595a91af945430c3ed3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 27 Dec 2025 08:36:35 -1000 Subject: [PATCH 037/302] [ethernet] Eliminate heap allocations in dump_config logging (#12665) --- .../ethernet/ethernet_component.cpp | 28 +++++++++++++------ .../components/ethernet/ethernet_component.h | 2 ++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/esphome/components/ethernet/ethernet_component.cpp b/esphome/components/ethernet/ethernet_component.cpp index 793ebdec42..114000401f 100644 --- a/esphome/components/ethernet/ethernet_component.cpp +++ b/esphome/components/ethernet/ethernet_component.cpp @@ -644,6 +644,12 @@ void EthernetComponent::dump_connect_params_() { dns_ip2 = dns_getserver(1); } + // Use stack buffers for IP address formatting to avoid heap allocations + char ip_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char subnet_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char gateway_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char dns1_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char dns2_buf[network::IP_ADDRESS_BUFFER_SIZE]; ESP_LOGCONFIG(TAG, " IP Address: %s\n" " Hostname: '%s'\n" @@ -651,9 +657,9 @@ void EthernetComponent::dump_connect_params_() { " Gateway: %s\n" " DNS1: %s\n" " DNS2: %s", - network::IPAddress(&ip.ip).str().c_str(), App.get_name().c_str(), - network::IPAddress(&ip.netmask).str().c_str(), network::IPAddress(&ip.gw).str().c_str(), - network::IPAddress(dns_ip1).str().c_str(), network::IPAddress(dns_ip2).str().c_str()); + network::IPAddress(&ip.ip).str_to(ip_buf), App.get_name().c_str(), + network::IPAddress(&ip.netmask).str_to(subnet_buf), network::IPAddress(&ip.gw).str_to(gateway_buf), + network::IPAddress(dns_ip1).str_to(dns1_buf), network::IPAddress(dns_ip2).str_to(dns2_buf)); #if USE_NETWORK_IPV6 struct esp_ip6_addr if_ip6s[CONFIG_LWIP_IPV6_NUM_ADDRESSES]; @@ -665,12 +671,13 @@ void EthernetComponent::dump_connect_params_() { } #endif /* USE_NETWORK_IPV6 */ + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; ESP_LOGCONFIG(TAG, " MAC Address: %s\n" " Is Full Duplex: %s\n" " Link Speed: %u", - this->get_eth_mac_address_pretty().c_str(), YESNO(this->get_duplex_mode() == ETH_DUPLEX_FULL), - this->get_link_speed() == ETH_SPEED_100M ? 100 : 10); + this->get_eth_mac_address_pretty_into_buffer(mac_buf), + YESNO(this->get_duplex_mode() == ETH_DUPLEX_FULL), this->get_link_speed() == ETH_SPEED_100M ? 100 : 10); } #ifdef USE_ETHERNET_SPI @@ -711,11 +718,16 @@ void EthernetComponent::get_eth_mac_address_raw(uint8_t *mac) { } std::string EthernetComponent::get_eth_mac_address_pretty() { + char buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + return std::string(this->get_eth_mac_address_pretty_into_buffer(buf)); +} + +const char *EthernetComponent::get_eth_mac_address_pretty_into_buffer( + std::span buf) { uint8_t mac[6]; get_eth_mac_address_raw(mac); - char buf[18]; - format_mac_addr_upper(mac, buf); - return std::string(buf); + format_mac_addr_upper(mac, buf.data()); + return buf.data(); } eth_duplex_t EthernetComponent::get_duplex_mode() { diff --git a/esphome/components/ethernet/ethernet_component.h b/esphome/components/ethernet/ethernet_component.h index bffed4dc4a..490a9d026e 100644 --- a/esphome/components/ethernet/ethernet_component.h +++ b/esphome/components/ethernet/ethernet_component.h @@ -3,6 +3,7 @@ #include "esphome/core/component.h" #include "esphome/core/defines.h" #include "esphome/core/hal.h" +#include "esphome/core/helpers.h" #include "esphome/components/network/ip_address.h" #ifdef USE_ESP32 @@ -93,6 +94,7 @@ class EthernetComponent : public Component { void set_use_address(const char *use_address); void get_eth_mac_address_raw(uint8_t *mac); std::string get_eth_mac_address_pretty(); + const char *get_eth_mac_address_pretty_into_buffer(std::span buf); eth_duplex_t get_duplex_mode(); eth_speed_t get_link_speed(); bool powerdown(); From 45e61f100c0e45c957a081ad9e3fdade7a7f4041 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:59:55 -0500 Subject: [PATCH 038/302] [core] Replace USE_ESP_IDF with USE_ESP32 across components (#12673) Co-authored-by: Claude Co-authored-by: J. Nick Koston --- .clang-tidy.hash | 2 +- esphome/components/audio/audio_reader.cpp | 2 +- esphome/components/audio/audio_reader.h | 2 +- esphome/components/captive_portal/__init__.py | 9 ++++----- .../captive_portal/captive_portal.cpp | 5 ++--- .../captive_portal/captive_portal.h | 20 +++++++++---------- .../captive_portal/dns_server_esp32_idf.cpp | 4 ++-- .../captive_portal/dns_server_esp32_idf.h | 4 ++-- esphome/components/climate/climate.cpp | 2 +- esphome/components/debug/debug_esp32.cpp | 2 +- esphome/components/esp32_ble/ble.cpp | 18 +++-------------- esphome/components/esp_ldo/__init__.py | 2 +- .../components/micro_wake_word/__init__.py | 2 +- .../components/micro_wake_word/automation.h | 2 +- .../micro_wake_word/micro_wake_word.cpp | 4 ++-- .../micro_wake_word/micro_wake_word.h | 4 ++-- .../micro_wake_word/preprocessor_settings.h | 2 +- .../micro_wake_word/streaming_model.cpp | 2 +- .../micro_wake_word/streaming_model.h | 2 +- esphome/components/mipi_dsi/display.py | 2 +- esphome/components/mipi_rgb/display.py | 2 +- esphome/components/mipi_spi/display.py | 2 +- esphome/components/mixer/speaker/__init__.py | 4 +--- .../components/mqtt/mqtt_backend_esp32.cpp | 10 ---------- esphome/components/network/ip_address.h | 2 +- esphome/components/openthread/__init__.py | 1 - .../components/openthread/openthread_esp.cpp | 2 +- esphome/components/qspi_dbi/display.py | 2 +- esphome/components/qspi_dbi/qspi_dbi.cpp | 2 +- esphome/components/qspi_dbi/qspi_dbi.h | 2 +- esphome/components/rpi_dpi_rgb/display.py | 1 - .../speaker/media_player/__init__.py | 2 +- .../speaker/media_player/audio_pipeline.cpp | 2 +- .../speaker/media_player/audio_pipeline.h | 2 +- .../speaker/media_player/automation.h | 2 +- .../media_player/speaker_media_player.cpp | 2 +- .../media_player/speaker_media_player.h | 2 +- esphome/components/spi/__init__.py | 4 ++-- esphome/components/st7701s/display.py | 2 +- esphome/components/usb_host/__init__.py | 1 - .../voice_assistant/voice_assistant.cpp | 2 +- .../web_server/ota/ota_web_server.cpp | 4 ++-- esphome/config_validation.py | 11 +++++++++- esphome/core/defines.h | 8 ++------ esphome/core/log.cpp | 2 +- esphome/core/log.h | 7 ++----- platformio.ini | 1 + tests/component_tests/mipi_spi/test_init.py | 17 ---------------- 48 files changed, 74 insertions(+), 119 deletions(-) diff --git a/.clang-tidy.hash b/.clang-tidy.hash index 240b205158..e1f5e096c0 100644 --- a/.clang-tidy.hash +++ b/.clang-tidy.hash @@ -1 +1 @@ -4268ab0b5150f79ab1c317e8f3834c8bb0b4c8122da4f6b1fd67c49d0f2098c9 +5ac05ac603766d76b86a05cdf6a43febcaae807fe9e2406d812c47d4b5fed91d diff --git a/esphome/components/audio/audio_reader.cpp b/esphome/components/audio/audio_reader.cpp index 6966c95db7..7794187a69 100644 --- a/esphome/components/audio/audio_reader.cpp +++ b/esphome/components/audio/audio_reader.cpp @@ -1,6 +1,6 @@ #include "audio_reader.h" -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "esphome/core/defines.h" #include "esphome/core/hal.h" diff --git a/esphome/components/audio/audio_reader.h b/esphome/components/audio/audio_reader.h index 3fdc3c3ff2..0b73923e84 100644 --- a/esphome/components/audio/audio_reader.h +++ b/esphome/components/audio/audio_reader.h @@ -1,6 +1,6 @@ #pragma once -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "audio.h" #include "audio_transfer_buffer.h" diff --git a/esphome/components/captive_portal/__init__.py b/esphome/components/captive_portal/__init__.py index 763e2e4ec5..232b868e82 100644 --- a/esphome/components/captive_portal/__init__.py +++ b/esphome/components/captive_portal/__init__.py @@ -97,10 +97,6 @@ async def to_code(config): cg.add_define("USE_CAPTIVE_PORTAL") if CORE.using_arduino: - if CORE.is_esp32: - cg.add_library("ESP32 Async UDP", None) - cg.add_library("DNSServer", None) - cg.add_library("WiFi", None) if CORE.is_esp8266: cg.add_library("DNSServer", None) if CORE.is_libretiny: @@ -110,6 +106,9 @@ async def to_code(config): # Only compile the ESP-IDF DNS server when using ESP-IDF framework FILTER_SOURCE_FILES = filter_source_files_from_platform( { - "dns_server_esp32_idf.cpp": {PlatformFramework.ESP32_IDF}, + "dns_server_esp32_idf.cpp": { + PlatformFramework.ESP32_ARDUINO, + PlatformFramework.ESP32_IDF, + }, } ) diff --git a/esphome/components/captive_portal/captive_portal.cpp b/esphome/components/captive_portal/captive_portal.cpp index e1f92d2d2b..749aa705df 100644 --- a/esphome/components/captive_portal/captive_portal.cpp +++ b/esphome/components/captive_portal/captive_portal.cpp @@ -69,12 +69,11 @@ void CaptivePortal::start() { network::IPAddress ip = wifi::global_wifi_component->wifi_soft_ap_ip(); -#ifdef USE_ESP_IDF +#if defined(USE_ESP32) // Create DNS server instance for ESP-IDF this->dns_server_ = make_unique(); this->dns_server_->start(ip); -#endif -#ifdef USE_ARDUINO +#elif defined(USE_ARDUINO) this->dns_server_ = make_unique(); this->dns_server_->setErrorReplyCode(DNSReplyCode::NoError); this->dns_server_->start(53, ESPHOME_F("*"), ip); diff --git a/esphome/components/captive_portal/captive_portal.h b/esphome/components/captive_portal/captive_portal.h index f48c286f0c..0c63a3670a 100644 --- a/esphome/components/captive_portal/captive_portal.h +++ b/esphome/components/captive_portal/captive_portal.h @@ -2,11 +2,10 @@ #include "esphome/core/defines.h" #ifdef USE_CAPTIVE_PORTAL #include -#ifdef USE_ARDUINO -#include -#endif -#ifdef USE_ESP_IDF +#if defined(USE_ESP32) #include "dns_server_esp32_idf.h" +#elif defined(USE_ARDUINO) +#include #endif #include "esphome/core/component.h" #include "esphome/core/helpers.h" @@ -23,15 +22,14 @@ class CaptivePortal : public AsyncWebHandler, public Component { void setup() override; void dump_config() override; void loop() override { -#ifdef USE_ARDUINO - if (this->dns_server_ != nullptr) { - this->dns_server_->processNextRequest(); - } -#endif -#ifdef USE_ESP_IDF +#if defined(USE_ESP32) if (this->dns_server_ != nullptr) { this->dns_server_->process_next_request(); } +#elif defined(USE_ARDUINO) + if (this->dns_server_ != nullptr) { + this->dns_server_->processNextRequest(); + } #endif } float get_setup_priority() const override; @@ -64,7 +62,7 @@ class CaptivePortal : public AsyncWebHandler, public Component { web_server_base::WebServerBase *base_; bool initialized_{false}; bool active_{false}; -#if defined(USE_ARDUINO) || defined(USE_ESP_IDF) +#if defined(USE_ARDUINO) || defined(USE_ESP32) std::unique_ptr dns_server_{nullptr}; #endif }; diff --git a/esphome/components/captive_portal/dns_server_esp32_idf.cpp b/esphome/components/captive_portal/dns_server_esp32_idf.cpp index 740107400a..5188b2047f 100644 --- a/esphome/components/captive_portal/dns_server_esp32_idf.cpp +++ b/esphome/components/captive_portal/dns_server_esp32_idf.cpp @@ -1,5 +1,5 @@ #include "dns_server_esp32_idf.h" -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "esphome/core/log.h" #include "esphome/core/hal.h" @@ -202,4 +202,4 @@ void DNSServer::process_next_request() { } // namespace esphome::captive_portal -#endif // USE_ESP_IDF +#endif // USE_ESP32 diff --git a/esphome/components/captive_portal/dns_server_esp32_idf.h b/esphome/components/captive_portal/dns_server_esp32_idf.h index 13d9def8e3..3e0ac07373 100644 --- a/esphome/components/captive_portal/dns_server_esp32_idf.h +++ b/esphome/components/captive_portal/dns_server_esp32_idf.h @@ -1,5 +1,5 @@ #pragma once -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include #include "esphome/core/helpers.h" @@ -24,4 +24,4 @@ class DNSServer { } // namespace esphome::captive_portal -#endif // USE_ESP_IDF +#endif // USE_ESP32 diff --git a/esphome/components/climate/climate.cpp b/esphome/components/climate/climate.cpp index 229862ce01..2d35509493 100644 --- a/esphome/components/climate/climate.cpp +++ b/esphome/components/climate/climate.cpp @@ -369,7 +369,7 @@ optional Climate::restore_state_() { } void Climate::save_state_() { -#if (defined(USE_ESP_IDF) || (defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(3, 0, 0))) && \ +#if (defined(USE_ESP32) || (defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(3, 0, 0))) && \ !defined(CLANG_TIDY) #pragma GCC diagnostic ignored "-Wclass-memaccess" #define TEMP_IGNORE_MEMACCESS diff --git a/esphome/components/debug/debug_esp32.cpp b/esphome/components/debug/debug_esp32.cpp index 1c3dc3699b..25852b32a7 100644 --- a/esphome/components/debug/debug_esp32.cpp +++ b/esphome/components/debug/debug_esp32.cpp @@ -200,7 +200,7 @@ void DebugComponent::get_device_info_(std::string &device_info) { #ifdef USE_ARDUINO ESP_LOGD(TAG, "Framework: Arduino"); device_info += "Arduino"; -#elif defined(USE_ESP_IDF) +#elif defined(USE_ESP32) ESP_LOGD(TAG, "Framework: ESP-IDF"); device_info += "ESP-IDF"; #else diff --git a/esphome/components/esp32_ble/ble.cpp b/esphome/components/esp32_ble/ble.cpp index 42f8ab8fd4..87b5e2b738 100644 --- a/esphome/components/esp32_ble/ble.cpp +++ b/esphome/components/esp32_ble/ble.cpp @@ -24,7 +24,9 @@ extern "C" { #include #ifdef USE_ARDUINO -#include +// Prevent Arduino from releasing BT memory at startup (esp32-hal-misc.c). +// Without this, esp_bt_controller_init() fails with ESP_ERR_INVALID_STATE. +extern "C" bool btInUse() { return true; } // NOLINT(readability-identifier-naming) #endif namespace esphome::esp32_ble { @@ -165,12 +167,6 @@ void ESP32BLE::advertising_init_() { bool ESP32BLE::ble_setup_() { esp_err_t err; #ifndef CONFIG_ESP_HOSTED_ENABLE_BT_BLUEDROID -#ifdef USE_ARDUINO - if (!btStart()) { - ESP_LOGE(TAG, "btStart failed: %d", esp_bt_controller_get_status()); - return false; - } -#else if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { // start bt controller if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE) { @@ -195,7 +191,6 @@ bool ESP32BLE::ble_setup_() { return false; } } -#endif esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); #else @@ -334,12 +329,6 @@ bool ESP32BLE::ble_dismantle_() { } #ifndef CONFIG_ESP_HOSTED_ENABLE_BT_BLUEDROID -#ifdef USE_ARDUINO - if (!btStop()) { - ESP_LOGE(TAG, "btStop failed: %d", esp_bt_controller_get_status()); - return false; - } -#else if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) { // stop bt controller if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED) { @@ -363,7 +352,6 @@ bool ESP32BLE::ble_dismantle_() { return false; } } -#endif #else if (esp_hosted_bt_controller_disable() != ESP_OK) { ESP_LOGW(TAG, "esp_hosted_bt_controller_disable failed"); diff --git a/esphome/components/esp_ldo/__init__.py b/esphome/components/esp_ldo/__init__.py index 38e684c537..f136dd149b 100644 --- a/esphome/components/esp_ldo/__init__.py +++ b/esphome/components/esp_ldo/__init__.py @@ -31,7 +31,7 @@ CONFIG_SCHEMA = cv.All( } ) ), - cv.only_with_esp_idf, + cv.only_on_esp32, only_on_variant(supported=[VARIANT_ESP32P4]), ) diff --git a/esphome/components/micro_wake_word/__init__.py b/esphome/components/micro_wake_word/__init__.py index 0d478f749b..74696584da 100644 --- a/esphome/components/micro_wake_word/__init__.py +++ b/esphome/components/micro_wake_word/__init__.py @@ -368,7 +368,7 @@ CONFIG_SCHEMA = cv.All( ), } ).extend(cv.COMPONENT_SCHEMA), - cv.only_with_esp_idf, + cv.only_on_esp32, ) diff --git a/esphome/components/micro_wake_word/automation.h b/esphome/components/micro_wake_word/automation.h index e1795a7e64..218ce9e4bc 100644 --- a/esphome/components/micro_wake_word/automation.h +++ b/esphome/components/micro_wake_word/automation.h @@ -3,7 +3,7 @@ #include "micro_wake_word.h" #include "streaming_model.h" -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 namespace esphome { namespace micro_wake_word { diff --git a/esphome/components/micro_wake_word/micro_wake_word.cpp b/esphome/components/micro_wake_word/micro_wake_word.cpp index b8377ead38..d7e80efc84 100644 --- a/esphome/components/micro_wake_word/micro_wake_word.cpp +++ b/esphome/components/micro_wake_word/micro_wake_word.cpp @@ -1,6 +1,6 @@ #include "micro_wake_word.h" -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "esphome/core/application.h" #include "esphome/core/hal.h" @@ -473,4 +473,4 @@ bool MicroWakeWord::update_model_probabilities_(const int8_t audio_features[PREP } // namespace micro_wake_word } // namespace esphome -#endif // USE_ESP_IDF +#endif // USE_ESP32 diff --git a/esphome/components/micro_wake_word/micro_wake_word.h b/esphome/components/micro_wake_word/micro_wake_word.h index 84261eaa5b..b427e4dfcb 100644 --- a/esphome/components/micro_wake_word/micro_wake_word.h +++ b/esphome/components/micro_wake_word/micro_wake_word.h @@ -1,6 +1,6 @@ #pragma once -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "preprocessor_settings.h" #include "streaming_model.h" @@ -140,4 +140,4 @@ class MicroWakeWord : public Component } // namespace micro_wake_word } // namespace esphome -#endif // USE_ESP_IDF +#endif // USE_ESP32 diff --git a/esphome/components/micro_wake_word/preprocessor_settings.h b/esphome/components/micro_wake_word/preprocessor_settings.h index 3de21de92e..c9d195b49b 100644 --- a/esphome/components/micro_wake_word/preprocessor_settings.h +++ b/esphome/components/micro_wake_word/preprocessor_settings.h @@ -1,6 +1,6 @@ #pragma once -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include diff --git a/esphome/components/micro_wake_word/streaming_model.cpp b/esphome/components/micro_wake_word/streaming_model.cpp index 2b073cce56..47d2c70e13 100644 --- a/esphome/components/micro_wake_word/streaming_model.cpp +++ b/esphome/components/micro_wake_word/streaming_model.cpp @@ -1,6 +1,6 @@ #include "streaming_model.h" -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "esphome/core/helpers.h" #include "esphome/core/log.h" diff --git a/esphome/components/micro_wake_word/streaming_model.h b/esphome/components/micro_wake_word/streaming_model.h index b7b22b9700..0811bfb19b 100644 --- a/esphome/components/micro_wake_word/streaming_model.h +++ b/esphome/components/micro_wake_word/streaming_model.h @@ -1,6 +1,6 @@ #pragma once -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "preprocessor_settings.h" diff --git a/esphome/components/mipi_dsi/display.py b/esphome/components/mipi_dsi/display.py index 90c4cc082e..c288b33cd2 100644 --- a/esphome/components/mipi_dsi/display.py +++ b/esphome/components/mipi_dsi/display.py @@ -165,8 +165,8 @@ def model_schema(config): ) return cv.All( schema, + cv.only_on_esp32, only_on_variant(supported=[VARIANT_ESP32P4]), - cv.only_with_esp_idf, ) diff --git a/esphome/components/mipi_rgb/display.py b/esphome/components/mipi_rgb/display.py index 61dbeb8ed4..96e167b2e6 100644 --- a/esphome/components/mipi_rgb/display.py +++ b/esphome/components/mipi_rgb/display.py @@ -224,8 +224,8 @@ def _config_schema(config): schema = model_schema(config) return cv.All( schema, + cv.only_on_esp32, only_on_variant(supported=[VARIANT_ESP32S3]), - cv.only_with_esp_idf, )(config) diff --git a/esphome/components/mipi_spi/display.py b/esphome/components/mipi_spi/display.py index 50ea826eab..69bf133c68 100644 --- a/esphome/components/mipi_spi/display.py +++ b/esphome/components/mipi_spi/display.py @@ -224,7 +224,7 @@ def model_schema(config): } ) if bus_mode != TYPE_SINGLE: - return cv.All(schema, cv.only_with_esp_idf) + return cv.All(schema, cv.only_on_esp32) return schema diff --git a/esphome/components/mixer/speaker/__init__.py b/esphome/components/mixer/speaker/__init__.py index 46729f8eda..c4069851af 100644 --- a/esphome/components/mixer/speaker/__init__.py +++ b/esphome/components/mixer/speaker/__init__.py @@ -93,9 +93,7 @@ CONFIG_SCHEMA = cv.All( ), cv.Optional(CONF_NUM_CHANNELS): cv.int_range(min=1, max=2), cv.Optional(CONF_QUEUE_MODE, default=False): cv.boolean, - cv.SplitDefault(CONF_TASK_STACK_IN_PSRAM, esp32_idf=False): cv.All( - cv.boolean, cv.only_with_esp_idf - ), + cv.Optional(CONF_TASK_STACK_IN_PSRAM, default=False): cv.boolean, } ), cv.only_on([PLATFORM_ESP32]), diff --git a/esphome/components/mqtt/mqtt_backend_esp32.cpp b/esphome/components/mqtt/mqtt_backend_esp32.cpp index dcc51ed60e..e3105f4860 100644 --- a/esphome/components/mqtt/mqtt_backend_esp32.cpp +++ b/esphome/components/mqtt/mqtt_backend_esp32.cpp @@ -232,16 +232,6 @@ void MQTTBackendESP32::esphome_mqtt_task(void *params) { this_mqtt->mqtt_event_pool_.release(elem); } } - - // Clean up any remaining items in the queue - struct QueueElement *elem; - while ((elem = this_mqtt->mqtt_queue_.pop()) != nullptr) { - this_mqtt->mqtt_event_pool_.release(elem); - } - - // Note: EventPool destructor will clean up the pool itself - // Task will delete itself - vTaskDelete(nullptr); } bool MQTTBackendESP32::enqueue_(MqttQueueTypeT type, const char *topic, int qos, bool retain, const char *payload, diff --git a/esphome/components/network/ip_address.h b/esphome/components/network/ip_address.h index 27cc212a47..b719d1a70e 100644 --- a/esphome/components/network/ip_address.h +++ b/esphome/components/network/ip_address.h @@ -8,7 +8,7 @@ #include "esphome/core/helpers.h" #include "esphome/core/macros.h" -#if defined(USE_ESP_IDF) || defined(USE_LIBRETINY) || USE_ARDUINO_VERSION_CODE > VERSION_CODE(3, 0, 0) +#if defined(USE_ESP32) || defined(USE_LIBRETINY) || USE_ARDUINO_VERSION_CODE > VERSION_CODE(3, 0, 0) #include #endif diff --git a/esphome/components/openthread/__init__.py b/esphome/components/openthread/__init__.py index 050e45cdc9..26c05a0a86 100644 --- a/esphome/components/openthread/__init__.py +++ b/esphome/components/openthread/__init__.py @@ -152,7 +152,6 @@ CONFIG_SCHEMA = cv.All( } ).extend(_CONNECTION_SCHEMA), cv.has_exactly_one_key(CONF_NETWORK_KEY, CONF_TLV), - cv.only_with_esp_idf, only_on_variant(supported=[VARIANT_ESP32C5, VARIANT_ESP32C6, VARIANT_ESP32H2]), _validate, _require_vfs_select, diff --git a/esphome/components/openthread/openthread_esp.cpp b/esphome/components/openthread/openthread_esp.cpp index b47e4b884a..1f18e51496 100644 --- a/esphome/components/openthread/openthread_esp.cpp +++ b/esphome/components/openthread/openthread_esp.cpp @@ -1,5 +1,5 @@ #include "esphome/core/defines.h" -#if defined(USE_OPENTHREAD) && defined(USE_ESP_IDF) +#if defined(USE_OPENTHREAD) && defined(USE_ESP32) #include #include "openthread.h" diff --git a/esphome/components/qspi_dbi/display.py b/esphome/components/qspi_dbi/display.py index 74d837a794..e4440c9b81 100644 --- a/esphome/components/qspi_dbi/display.py +++ b/esphome/components/qspi_dbi/display.py @@ -154,7 +154,7 @@ CONFIG_SCHEMA = cv.All( upper=True, key=CONF_MODEL, ), - cv.only_with_esp_idf, + cv.only_on_esp32, ) diff --git a/esphome/components/qspi_dbi/qspi_dbi.cpp b/esphome/components/qspi_dbi/qspi_dbi.cpp index 6c95bb7cf2..24b9a0ce0a 100644 --- a/esphome/components/qspi_dbi/qspi_dbi.cpp +++ b/esphome/components/qspi_dbi/qspi_dbi.cpp @@ -1,4 +1,4 @@ -#if defined(USE_ESP_IDF) && defined(USE_ESP32_VARIANT_ESP32S3) +#if defined(USE_ESP32) && defined(USE_ESP32_VARIANT_ESP32S3) #include "qspi_dbi.h" #include "esphome/core/log.h" diff --git a/esphome/components/qspi_dbi/qspi_dbi.h b/esphome/components/qspi_dbi/qspi_dbi.h index f35f0e519c..3eee9bec47 100644 --- a/esphome/components/qspi_dbi/qspi_dbi.h +++ b/esphome/components/qspi_dbi/qspi_dbi.h @@ -3,7 +3,7 @@ // #pragma once -#if defined(USE_ESP_IDF) && defined(USE_ESP32_VARIANT_ESP32S3) +#if defined(USE_ESP32) && defined(USE_ESP32_VARIANT_ESP32S3) #include "esphome/components/spi/spi.h" #include "esphome/components/display/display.h" #include "esphome/components/display/display_buffer.h" diff --git a/esphome/components/rpi_dpi_rgb/display.py b/esphome/components/rpi_dpi_rgb/display.py index 8e9da43a74..e92eee7c0c 100644 --- a/esphome/components/rpi_dpi_rgb/display.py +++ b/esphome/components/rpi_dpi_rgb/display.py @@ -122,7 +122,6 @@ CONFIG_SCHEMA = cv.All( ) ), only_on_variant(supported=[VARIANT_ESP32S3]), - cv.only_with_esp_idf, ) diff --git a/esphome/components/speaker/media_player/__init__.py b/esphome/components/speaker/media_player/__init__.py index 4ca57f2c4a..370b4576a7 100644 --- a/esphome/components/speaker/media_player/__init__.py +++ b/esphome/components/speaker/media_player/__init__.py @@ -315,7 +315,7 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_ON_VOLUME): automation.validate_automation(single=True), } ), - cv.only_with_esp_idf, + cv.only_on_esp32, _validate_repeated_speaker, _request_high_performance_networking, ) diff --git a/esphome/components/speaker/media_player/audio_pipeline.cpp b/esphome/components/speaker/media_player/audio_pipeline.cpp index dc8572ae43..8be37d740a 100644 --- a/esphome/components/speaker/media_player/audio_pipeline.cpp +++ b/esphome/components/speaker/media_player/audio_pipeline.cpp @@ -1,6 +1,6 @@ #include "audio_pipeline.h" -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "esphome/core/defines.h" #include "esphome/core/hal.h" diff --git a/esphome/components/speaker/media_player/audio_pipeline.h b/esphome/components/speaker/media_player/audio_pipeline.h index 98f43fda6e..6fffde6c20 100644 --- a/esphome/components/speaker/media_player/audio_pipeline.h +++ b/esphome/components/speaker/media_player/audio_pipeline.h @@ -1,6 +1,6 @@ #pragma once -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "esphome/components/audio/audio.h" #include "esphome/components/audio/audio_reader.h" diff --git a/esphome/components/speaker/media_player/automation.h b/esphome/components/speaker/media_player/automation.h index fdf3db07f9..6270da7bd4 100644 --- a/esphome/components/speaker/media_player/automation.h +++ b/esphome/components/speaker/media_player/automation.h @@ -2,7 +2,7 @@ #include "speaker_media_player.h" -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "esphome/components/audio/audio.h" #include "esphome/core/automation.h" diff --git a/esphome/components/speaker/media_player/speaker_media_player.cpp b/esphome/components/speaker/media_player/speaker_media_player.cpp index 5722aab195..9a3a47bac8 100644 --- a/esphome/components/speaker/media_player/speaker_media_player.cpp +++ b/esphome/components/speaker/media_player/speaker_media_player.cpp @@ -1,6 +1,6 @@ #include "speaker_media_player.h" -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "esphome/core/log.h" diff --git a/esphome/components/speaker/media_player/speaker_media_player.h b/esphome/components/speaker/media_player/speaker_media_player.h index f1c564b63d..065926d0cf 100644 --- a/esphome/components/speaker/media_player/speaker_media_player.h +++ b/esphome/components/speaker/media_player/speaker_media_player.h @@ -1,6 +1,6 @@ #pragma once -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #include "audio_pipeline.h" diff --git a/esphome/components/spi/__init__.py b/esphome/components/spi/__init__.py index ad279dcf1a..045cdd09d3 100644 --- a/esphome/components/spi/__init__.py +++ b/esphome/components/spi/__init__.py @@ -311,7 +311,7 @@ def spi_mode_schema(mode): if mode == TYPE_SINGLE: return SPI_SINGLE_SCHEMA pin_count = 4 if mode == TYPE_QUAD else 8 - onlys = [cv.only_on([PLATFORM_ESP32]), cv.only_with_esp_idf] + onlys = [cv.only_on([PLATFORM_ESP32])] if pin_count == 8: onlys.append( only_on_variant( @@ -399,7 +399,7 @@ def spi_device_schema( cv.Optional(CONF_SPI_MODE, default=default_mode): cv.enum( SPI_MODE_OPTIONS, upper=True ), - cv.Optional(CONF_RELEASE_DEVICE): cv.All(cv.boolean, cv.only_with_esp_idf), + cv.Optional(CONF_RELEASE_DEVICE): cv.All(cv.boolean, cv.only_on_esp32), } if cs_pin_required: schema[cv.Required(CONF_CS_PIN)] = pins.gpio_output_pin_schema diff --git a/esphome/components/st7701s/display.py b/esphome/components/st7701s/display.py index 6e4bff6431..3078158d25 100644 --- a/esphome/components/st7701s/display.py +++ b/esphome/components/st7701s/display.py @@ -161,8 +161,8 @@ CONFIG_SCHEMA = cv.All( } ).extend(spi.spi_device_schema(cs_pin_required=False, default_data_rate=1e6)) ), + cv.only_on_esp32, only_on_variant(supported=[VARIANT_ESP32S3]), - cv.only_with_esp_idf, ) FINAL_VALIDATE_SCHEMA = spi.final_validate_device_schema( diff --git a/esphome/components/usb_host/__init__.py b/esphome/components/usb_host/__init__.py index cccabcf646..9e058ee20b 100644 --- a/esphome/components/usb_host/__init__.py +++ b/esphome/components/usb_host/__init__.py @@ -53,7 +53,6 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_DEVICES): cv.ensure_list(usb_device_schema()), } ), - cv.only_with_esp_idf, only_on_variant(supported=[VARIANT_ESP32S2, VARIANT_ESP32S3, VARIANT_ESP32P4]), ) diff --git a/esphome/components/voice_assistant/voice_assistant.cpp b/esphome/components/voice_assistant/voice_assistant.cpp index 551f0370f2..b946e3b38a 100644 --- a/esphome/components/voice_assistant/voice_assistant.cpp +++ b/esphome/components/voice_assistant/voice_assistant.cpp @@ -947,7 +947,7 @@ void VoiceAssistant::on_set_configuration(const std::vector &active } // Enable only active wake words - for (auto ww_id : active_wake_words) { + for (const auto &ww_id : active_wake_words) { for (auto &model : this->micro_wake_word_->get_wake_words()) { if (model->get_id() == ww_id) { model->enable(); diff --git a/esphome/components/web_server/ota/ota_web_server.cpp b/esphome/components/web_server/ota/ota_web_server.cpp index b8bea40b84..3793f01eb5 100644 --- a/esphome/components/web_server/ota/ota_web_server.cpp +++ b/esphome/components/web_server/ota/ota_web_server.cpp @@ -10,7 +10,7 @@ #endif #ifdef USE_ARDUINO -#if defined(USE_ESP32) || defined(USE_LIBRETINY) +#if defined(USE_LIBRETINY) #include #endif #endif // USE_ARDUINO @@ -118,7 +118,7 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Platf // Platform-specific pre-initialization #ifdef USE_ARDUINO -#if defined(USE_ESP32) || defined(USE_LIBRETINY) +#if defined(USE_LIBRETINY) if (Update.isRunning()) { Update.abort(); } diff --git a/esphome/config_validation.py b/esphome/config_validation.py index 08fffa6cec..d085206ee8 100644 --- a/esphome/config_validation.py +++ b/esphome/config_validation.py @@ -697,7 +697,16 @@ only_on_esp32 = only_on(PLATFORM_ESP32) only_on_esp8266 = only_on(PLATFORM_ESP8266) only_on_rp2040 = only_on(PLATFORM_RP2040) only_with_arduino = only_with_framework(Framework.ARDUINO) -only_with_esp_idf = only_with_framework(Framework.ESP_IDF) + + +def only_with_esp_idf(obj): + """Deprecated: use only_on_esp32 instead.""" + _LOGGER.warning( + "cv.only_with_esp_idf was deprecated in 2026.1, will change behavior in 2026.6. " + "ESP32 Arduino builds on top of ESP-IDF, so ESP-IDF features are available in both frameworks. " + "Use cv.only_on_esp32 and/or cv.only_with_arduino instead." + ) + return only_with_framework(Framework.ESP_IDF)(obj) # Adapted from: diff --git a/esphome/core/defines.h b/esphome/core/defines.h index 11c5062140..a269f40479 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -164,13 +164,9 @@ #define USE_I2S_LEGACY #endif -// IDF-specific feature flags -#ifdef USE_ESP_IDF -#define USE_MQTT_IDF_ENQUEUE -#endif - // ESP32-specific feature flags #ifdef USE_ESP32 +#define USE_MQTT_IDF_ENQUEUE #define USE_ESPHOME_TASK_LOG_BUFFER #define USE_OTA_ROLLBACK @@ -231,7 +227,7 @@ #define USE_ETHERNET_MANUAL_IP #endif -#ifdef USE_ESP_IDF +#ifdef USE_ESP32 #define USE_MICRO_WAKE_WORD #define USE_MICRO_WAKE_WORD_VAD #if defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32H2) diff --git a/esphome/core/log.cpp b/esphome/core/log.cpp index 909319dd28..8338efbb33 100644 --- a/esphome/core/log.cpp +++ b/esphome/core/log.cpp @@ -46,7 +46,7 @@ void HOT esp_log_vprintf_(int level, const char *tag, int line, const __FlashStr } #endif -#if defined(USE_ESP32_FRAMEWORK_ARDUINO) || defined(USE_ESP_IDF) +#ifdef USE_ESP32 int HOT esp_idf_log_vprintf_(const char *format, va_list args) { // NOLINT #ifdef USE_LOGGER auto *log = logger::global_logger; diff --git a/esphome/core/log.h b/esphome/core/log.h index cade6a74c1..a2c4b35c6e 100644 --- a/esphome/core/log.h +++ b/esphome/core/log.h @@ -14,13 +14,10 @@ #endif // Include ESP-IDF/Arduino based logging methods here so they don't undefine ours later -#if defined(USE_ESP32_FRAMEWORK_ARDUINO) || defined(USE_ESP_IDF) +#if defined(USE_ESP32) #include #include #endif -#ifdef USE_ESP32_FRAMEWORK_ARDUINO -#include -#endif #ifdef USE_LIBRETINY #include #endif @@ -66,7 +63,7 @@ void esp_log_vprintf_(int level, const char *tag, int line, const char *format, #ifdef USE_STORE_LOG_STR_IN_FLASH void esp_log_vprintf_(int level, const char *tag, int line, const __FlashStringHelper *format, va_list args); #endif -#if defined(USE_ESP32_FRAMEWORK_ARDUINO) || defined(USE_ESP_IDF) +#if defined(USE_ESP32) int esp_idf_log_vprintf_(const char *format, va_list args); // NOLINT #endif diff --git a/platformio.ini b/platformio.ini index a27fb1f537..e38e1a5f3c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -156,6 +156,7 @@ lib_deps = esphome/ESP32-audioI2S@2.3.0 ; i2s_audio droscy/esp_wireguard@0.4.2 ; wireguard esphome/esp-audio-libs@2.0.1 ; audio + kahrendt/ESPMicroSpeechFeatures@1.1.0 ; micro_wake_word build_flags = ${common:arduino.build_flags} diff --git a/tests/component_tests/mipi_spi/test_init.py b/tests/component_tests/mipi_spi/test_init.py index 0c7dea2286..f752c41d8c 100644 --- a/tests/component_tests/mipi_spi/test_init.py +++ b/tests/component_tests/mipi_spi/test_init.py @@ -227,23 +227,6 @@ def test_esp32s3_specific_errors( run_schema_validation(config) -def test_framework_specific_errors( - set_core_config: SetCoreConfigCallable, -) -> None: - """Test framework-specific configuration errors""" - - set_core_config( - PlatformFramework.ESP32_ARDUINO, - platform_data={KEY_BOARD: "esp32dev", KEY_VARIANT: VARIANT_ESP32}, - ) - - with pytest.raises( - cv.Invalid, - match=r"This feature is only available with framework\(s\) esp-idf", - ): - run_schema_validation({"model": "wt32-sc01-plus"}) - - def test_custom_model_with_all_options( set_core_config: SetCoreConfigCallable, ) -> None: From eb050ff13e334ee5ca20453c3fa30124e8f521d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Dec 2025 16:48:08 -1000 Subject: [PATCH 039/302] Bump aioesphomeapi from 43.6.0 to 43.7.0 (#12699) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e741a70f48..30726006de 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile esptool==5.1.0 click==8.1.7 esphome-dashboard==20251013.0 -aioesphomeapi==43.6.0 +aioesphomeapi==43.7.0 zeroconf==0.148.0 puremagic==1.30 ruamel.yaml==0.18.17 # dashboard_import From a1e0121330f730723862f2a1dbd3d4b8d9de8877 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Dec 2025 16:48:20 -1000 Subject: [PATCH 040/302] Bump bleak from 2.0.0 to 2.1.0 (#12700) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 30726006de..d40db03bc2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ pillow==11.3.0 cairosvg==2.8.2 freetype-py==2.5.1 jinja2==3.1.6 -bleak==2.0.0 +bleak==2.1.0 # esp-idf >= 5.0 requires this pyparsing >= 3.0 From 5cbef3ef95ddc280cd4e04b3b4a0141cd7b9c839 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Dec 2025 03:15:40 +0000 Subject: [PATCH 041/302] Bump aioesphomeapi from 43.7.0 to 43.8.0 (#12701) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d40db03bc2..efd143a44a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile esptool==5.1.0 click==8.1.7 esphome-dashboard==20251013.0 -aioesphomeapi==43.7.0 +aioesphomeapi==43.8.0 zeroconf==0.148.0 puremagic==1.30 ruamel.yaml==0.18.17 # dashboard_import From d0673122a86415da4e3b87702a8d13aa628806fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Dec 2025 18:15:06 -1000 Subject: [PATCH 042/302] Bump aioesphomeapi from 43.8.0 to 43.9.0 (#12702) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index efd143a44a..65ff74a4a6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile esptool==5.1.0 click==8.1.7 esphome-dashboard==20251013.0 -aioesphomeapi==43.8.0 +aioesphomeapi==43.9.0 zeroconf==0.148.0 puremagic==1.30 ruamel.yaml==0.18.17 # dashboard_import From 6a6c6b648f95c9b92ce57995677b1775e4885a38 Mon Sep 17 00:00:00 2001 From: Swaptor Date: Mon, 29 Dec 2025 17:32:32 +0100 Subject: [PATCH 043/302] [internal_temperature] Add ESP32-C5 support (#12713) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- .../internal_temperature.cpp | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/esphome/components/internal_temperature/internal_temperature.cpp b/esphome/components/internal_temperature/internal_temperature.cpp index 2ef8cf2649..34d7baf880 100644 --- a/esphome/components/internal_temperature/internal_temperature.cpp +++ b/esphome/components/internal_temperature/internal_temperature.cpp @@ -8,8 +8,9 @@ extern "C" { uint8_t temprature_sens_read(); } #elif defined(USE_ESP32_VARIANT_ESP32C2) || defined(USE_ESP32_VARIANT_ESP32C3) || \ - defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32C61) || defined(USE_ESP32_VARIANT_ESP32H2) || \ - defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) + defined(USE_ESP32_VARIANT_ESP32C5) || defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32C61) || \ + defined(USE_ESP32_VARIANT_ESP32H2) || defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || \ + defined(USE_ESP32_VARIANT_ESP32S3) #include "driver/temperature_sensor.h" #endif // USE_ESP32_VARIANT #endif // USE_ESP32 @@ -27,9 +28,9 @@ namespace internal_temperature { static const char *const TAG = "internal_temperature"; #ifdef USE_ESP32 -#if defined(USE_ESP32_VARIANT_ESP32C2) || defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) || \ - defined(USE_ESP32_VARIANT_ESP32C61) || defined(USE_ESP32_VARIANT_ESP32H2) || defined(USE_ESP32_VARIANT_ESP32P4) || \ - defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) +#if defined(USE_ESP32_VARIANT_ESP32C2) || defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C5) || \ + defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32C61) || defined(USE_ESP32_VARIANT_ESP32H2) || \ + defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) static temperature_sensor_handle_t tsensNew = NULL; #endif // USE_ESP32_VARIANT #endif // USE_ESP32 @@ -44,8 +45,9 @@ void InternalTemperatureSensor::update() { temperature = (raw - 32) / 1.8f; success = (raw != 128); #elif defined(USE_ESP32_VARIANT_ESP32C2) || defined(USE_ESP32_VARIANT_ESP32C3) || \ - defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32C61) || defined(USE_ESP32_VARIANT_ESP32H2) || \ - defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) + defined(USE_ESP32_VARIANT_ESP32C5) || defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32C61) || \ + defined(USE_ESP32_VARIANT_ESP32H2) || defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || \ + defined(USE_ESP32_VARIANT_ESP32S3) esp_err_t result = temperature_sensor_get_celsius(tsensNew, &temperature); success = (result == ESP_OK); if (!success) { @@ -81,9 +83,9 @@ void InternalTemperatureSensor::update() { void InternalTemperatureSensor::setup() { #ifdef USE_ESP32 -#if defined(USE_ESP32_VARIANT_ESP32C2) || defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) || \ - defined(USE_ESP32_VARIANT_ESP32C61) || defined(USE_ESP32_VARIANT_ESP32H2) || defined(USE_ESP32_VARIANT_ESP32P4) || \ - defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) +#if defined(USE_ESP32_VARIANT_ESP32C2) || defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C5) || \ + defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32C61) || defined(USE_ESP32_VARIANT_ESP32H2) || \ + defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) temperature_sensor_config_t tsens_config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(-10, 80); esp_err_t result = temperature_sensor_install(&tsens_config, &tsensNew); From 890d531cea5e595319caec584ec8f9bf3da0ea2d Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Mon, 29 Dec 2025 11:35:54 -0500 Subject: [PATCH 044/302] [esp32] Bump to ESP-IDF 5.5.2, Arduino 3.3.5, platform 55.3.35 (#12681) Co-authored-by: Claude Co-authored-by: J. Nick Koston --- .clang-tidy.hash | 2 +- esphome/components/esp32/__init__.py | 20 +++++++++++--------- esphome/components/esp32/boards.py | 18 +++++++++++++++--- esphome/core/defines.h | 2 +- platformio.ini | 8 ++++---- 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/.clang-tidy.hash b/.clang-tidy.hash index e1f5e096c0..a14b44ef96 100644 --- a/.clang-tidy.hash +++ b/.clang-tidy.hash @@ -1 +1 @@ -5ac05ac603766d76b86a05cdf6a43febcaae807fe9e2406d812c47d4b5fed91d +94557f94be073390342833aff12ef8676a8b597db5fa770a5a1232e9425cb48f diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index dc442cfbd2..d307ae75c8 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -357,11 +357,12 @@ def _is_framework_url(source: str) -> bool: # The default/recommended arduino framework version # - https://github.com/espressif/arduino-esp32/releases ARDUINO_FRAMEWORK_VERSION_LOOKUP = { - "recommended": cv.Version(3, 3, 2), - "latest": cv.Version(3, 3, 4), - "dev": cv.Version(3, 3, 4), + "recommended": cv.Version(3, 3, 5), + "latest": cv.Version(3, 3, 5), + "dev": cv.Version(3, 3, 5), } ARDUINO_PLATFORM_VERSION_LOOKUP = { + cv.Version(3, 3, 5): cv.Version(55, 3, 35), cv.Version(3, 3, 4): cv.Version(55, 3, 31, "2"), cv.Version(3, 3, 3): cv.Version(55, 3, 31, "2"), cv.Version(3, 3, 2): cv.Version(55, 3, 31, "2"), @@ -378,11 +379,12 @@ ARDUINO_PLATFORM_VERSION_LOOKUP = { # The default/recommended esp-idf framework version # - https://github.com/espressif/esp-idf/releases ESP_IDF_FRAMEWORK_VERSION_LOOKUP = { - "recommended": cv.Version(5, 5, 1), - "latest": cv.Version(5, 5, 1), - "dev": cv.Version(5, 5, 1), + "recommended": cv.Version(5, 5, 2), + "latest": cv.Version(5, 5, 2), + "dev": cv.Version(5, 5, 2), } ESP_IDF_PLATFORM_VERSION_LOOKUP = { + cv.Version(5, 5, 2): cv.Version(55, 3, 35), cv.Version(5, 5, 1): cv.Version(55, 3, 31, "2"), cv.Version(5, 5, 0): cv.Version(55, 3, 31, "2"), cv.Version(5, 4, 3): cv.Version(55, 3, 32), @@ -399,9 +401,9 @@ ESP_IDF_PLATFORM_VERSION_LOOKUP = { # The platform-espressif32 version # - https://github.com/pioarduino/platform-espressif32/releases PLATFORM_VERSION_LOOKUP = { - "recommended": cv.Version(55, 3, 31, "2"), - "latest": cv.Version(55, 3, 31, "2"), - "dev": cv.Version(55, 3, 31, "2"), + "recommended": cv.Version(55, 3, 35), + "latest": cv.Version(55, 3, 35), + "dev": cv.Version(55, 3, 35), } diff --git a/esphome/components/esp32/boards.py b/esphome/components/esp32/boards.py index 514d674b55..8a7a9428db 100644 --- a/esphome/components/esp32/boards.py +++ b/esphome/components/esp32/boards.py @@ -1488,6 +1488,10 @@ BOARDS = { "name": "Arduino Nano ESP32", "variant": VARIANT_ESP32S3, }, + "arduino_nesso_n1": { + "name": "Arduino Nesso-N1", + "variant": VARIANT_ESP32C6, + }, "atd147_s3": { "name": "ArtronShop ATD1.47-S3", "variant": VARIANT_ESP32S3, @@ -1656,6 +1660,10 @@ BOARDS = { "name": "Espressif ESP32-C6-DevKitM-1", "variant": VARIANT_ESP32C6, }, + "esp32-c61-devkitc1-n8r2": { + "name": "Espressif ESP32-C61-DevKitC-1 N8R2 (8 MB Flash Quad, 2 MB PSRAM Quad)", + "variant": VARIANT_ESP32C61, + }, "esp32-devkitlipo": { "name": "OLIMEX ESP32-DevKit-LiPo", "variant": VARIANT_ESP32, @@ -1673,11 +1681,15 @@ BOARDS = { "variant": VARIANT_ESP32H2, }, "esp32-p4": { - "name": "Espressif ESP32-P4 generic", + "name": "Espressif ESP32-P4 ES (pre rev.300) generic", "variant": VARIANT_ESP32P4, }, "esp32-p4-evboard": { - "name": "Espressif ESP32-P4 Function EV Board", + "name": "Espressif ESP32-P4 Function EV Board (ES pre rev.300)", + "variant": VARIANT_ESP32P4, + }, + "esp32-p4_r3": { + "name": "Espressif ESP32-P4 rev.300 generic", "variant": VARIANT_ESP32P4, }, "esp32-pico-devkitm-2": { @@ -2093,7 +2105,7 @@ BOARDS = { "variant": VARIANT_ESP32, }, "m5stack-tab5-p4": { - "name": "M5STACK Tab5 esp32-p4 Board", + "name": "M5STACK Tab5 esp32-p4 Board (ES pre rev.300)", "variant": VARIANT_ESP32P4, }, "m5stack-timer-cam": { diff --git a/esphome/core/defines.h b/esphome/core/defines.h index a269f40479..be429a9784 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -221,7 +221,7 @@ #define USB_HOST_MAX_REQUESTS 16 #ifdef USE_ARDUINO -#define USE_ARDUINO_VERSION_CODE VERSION_CODE(3, 3, 2) +#define USE_ARDUINO_VERSION_CODE VERSION_CODE(3, 3, 5) #define USE_ETHERNET #define USE_ETHERNET_KSZ8081 #define USE_ETHERNET_MANUAL_IP diff --git a/platformio.ini b/platformio.ini index e38e1a5f3c..e58989c566 100644 --- a/platformio.ini +++ b/platformio.ini @@ -133,9 +133,9 @@ extra_scripts = post:esphome/components/esp8266/post_build.py.script ; This are common settings for the ESP32 (all variants) using Arduino. [common:esp32-arduino] extends = common:arduino -platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.31-1/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.35/platform-espressif32.zip platform_packages = - pioarduino/framework-arduinoespressif32@https://github.com/espressif/arduino-esp32/releases/download/3.3.2/esp32-3.3.2.zip + pioarduino/framework-arduinoespressif32@https://github.com/espressif/arduino-esp32/releases/download/3.3.5/esp32-3.3.5.zip framework = arduino, espidf ; Arduino as an ESP-IDF component lib_deps = @@ -170,9 +170,9 @@ extra_scripts = post:esphome/components/esp32/post_build.py.script ; This are common settings for the ESP32 (all variants) using IDF. [common:esp32-idf] extends = common:idf -platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.31-1/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.35/platform-espressif32.zip platform_packages = - pioarduino/framework-espidf@https://github.com/pioarduino/esp-idf/releases/download/v5.5.1/esp-idf-v5.5.1.zip + pioarduino/framework-espidf@https://github.com/pioarduino/esp-idf/releases/download/v5.5.2/esp-idf-v5.5.2.tar.xz framework = espidf lib_deps = From 7e362cdafc260bf2a8ec1d987fa7ec1a73451290 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 29 Dec 2025 08:43:54 -1000 Subject: [PATCH 045/302] [ota] Use precision format specifier for auth logging (#12706) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../components/esphome/ota/ota_esphome.cpp | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/esphome/components/esphome/ota/ota_esphome.cpp b/esphome/components/esphome/ota/ota_esphome.cpp index f9984e1425..98569c96cb 100644 --- a/esphome/components/esphome/ota/ota_esphome.cpp +++ b/esphome/components/esphome/ota/ota_esphome.cpp @@ -654,12 +654,7 @@ bool ESPHomeOTAComponent::handle_auth_send_() { this->auth_buf_[0] = this->auth_type_; hasher->get_hex(buf); -#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE - char log_buf[65]; // Fixed size for SHA256 hex (64) + null, works for MD5 (32) too - memcpy(log_buf, buf, hex_size); - log_buf[hex_size] = '\0'; - ESP_LOGV(TAG, "Auth: Nonce is %s", log_buf); -#endif + ESP_LOGV(TAG, "Auth: Nonce is %.*s", hex_size, buf); } // Try to write auth_type + nonce @@ -739,23 +734,13 @@ bool ESPHomeOTAComponent::handle_auth_read_() { hasher->add(nonce, hex_size * 2); // Add both nonce and cnonce (contiguous in buffer) hasher->calculate(); + ESP_LOGV(TAG, "Auth: CNonce is %.*s", hex_size, cnonce); #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE - char log_buf[65]; // Fixed size for SHA256 hex (64) + null, works for MD5 (32) too - // Log CNonce - memcpy(log_buf, cnonce, hex_size); - log_buf[hex_size] = '\0'; - ESP_LOGV(TAG, "Auth: CNonce is %s", log_buf); - - // Log computed hash - hasher->get_hex(log_buf); - log_buf[hex_size] = '\0'; - ESP_LOGV(TAG, "Auth: Result is %s", log_buf); - - // Log received response - memcpy(log_buf, response, hex_size); - log_buf[hex_size] = '\0'; - ESP_LOGV(TAG, "Auth: Response is %s", log_buf); + char computed_hash[65]; // Buffer for hex-encoded hash (max expected length + null terminator) + hasher->get_hex(computed_hash); + ESP_LOGV(TAG, "Auth: Result is %.*s", hex_size, computed_hash); #endif + ESP_LOGV(TAG, "Auth: Response is %.*s", hex_size, response); // Compare response bool matches = hasher->equals_hex(response); From 97af01c5edf08347b314642cdc26a103dd5a8538 Mon Sep 17 00:00:00 2001 From: Thomas Rupprecht Date: Mon, 29 Dec 2025 20:19:36 +0100 Subject: [PATCH 046/302] [usb_host] sort esp32 variants (#12720) --- esphome/components/usb_host/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/usb_host/__init__.py b/esphome/components/usb_host/__init__.py index 9e058ee20b..e4c11be489 100644 --- a/esphome/components/usb_host/__init__.py +++ b/esphome/components/usb_host/__init__.py @@ -53,7 +53,7 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_DEVICES): cv.ensure_list(usb_device_schema()), } ), - only_on_variant(supported=[VARIANT_ESP32S2, VARIANT_ESP32S3, VARIANT_ESP32P4]), + only_on_variant(supported=[VARIANT_ESP32P4, VARIANT_ESP32S2, VARIANT_ESP32S3]), ) From dd3beb58418bb4c08e4617fd130d06e35cc06d1d Mon Sep 17 00:00:00 2001 From: Thomas Rupprecht Date: Mon, 29 Dec 2025 20:20:38 +0100 Subject: [PATCH 047/302] [tests] fix typo mipi tests (#12715) --- tests/component_tests/mipi_spi/test_init.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/component_tests/mipi_spi/test_init.py b/tests/component_tests/mipi_spi/test_init.py index f752c41d8c..bae39d3879 100644 --- a/tests/component_tests/mipi_spi/test_init.py +++ b/tests/component_tests/mipi_spi/test_init.py @@ -1,4 +1,4 @@ -"""Tests for mpip_spi configuration validation.""" +"""Tests for mipi_spi configuration validation.""" from collections.abc import Callable from pathlib import Path From 93e2a1bd1aee8fe9a8c8d4b841dedd074bdba243 Mon Sep 17 00:00:00 2001 From: Thomas Rupprecht Date: Mon, 29 Dec 2025 20:21:07 +0100 Subject: [PATCH 048/302] [tests] improve mipi_spi variable naming (#12716) --- tests/component_tests/mipi_spi/conftest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/component_tests/mipi_spi/conftest.py b/tests/component_tests/mipi_spi/conftest.py index c3070c7965..eddf0987d0 100644 --- a/tests/component_tests/mipi_spi/conftest.py +++ b/tests/component_tests/mipi_spi/conftest.py @@ -20,9 +20,9 @@ def choose_variant_with_pins() -> Generator[Callable[[list], None]]: """ def chooser(pins: list) -> None: - for v in VARIANTS: + for variant in VARIANTS: try: - CORE.data[KEY_ESP32][KEY_VARIANT] = v + CORE.data[KEY_ESP32][KEY_VARIANT] = variant for pin in pins: if pin is not None: pin = gpio_pin_schema( From 636cccc6a3413a5f3fe859c193d1642689114045 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Dec 2025 09:55:26 -1000 Subject: [PATCH 049/302] Bump aioesphomeapi from 43.9.0 to 43.9.1 (#12724) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 65ff74a4a6..a6262e0d10 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile esptool==5.1.0 click==8.1.7 esphome-dashboard==20251013.0 -aioesphomeapi==43.9.0 +aioesphomeapi==43.9.1 zeroconf==0.148.0 puremagic==1.30 ruamel.yaml==0.18.17 # dashboard_import From 2e7cdad532e55d27a25752c3fb2a416c841cc5bb Mon Sep 17 00:00:00 2001 From: hsand <14326961+hsand@users.noreply.github.com> Date: Mon, 29 Dec 2025 22:58:38 +0100 Subject: [PATCH 050/302] [pvvx_mithermometer] fix displaying negative numbers (#12735) --- .../components/pvvx_mithermometer/display/pvvx_display.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/pvvx_mithermometer/display/pvvx_display.h b/esphome/components/pvvx_mithermometer/display/pvvx_display.h index 8637506bae..06837b94ab 100644 --- a/esphome/components/pvvx_mithermometer/display/pvvx_display.h +++ b/esphome/components/pvvx_mithermometer/display/pvvx_display.h @@ -60,13 +60,13 @@ class PVVXDisplay : public ble_client::BLEClientNode, public PollingComponent { * Valid values are from -99.5 to 1999.5. Smaller values are displayed as Lo, higher as Hi. * It will printed as it fits in the screen. */ - void print_bignum(float bignum) { this->bignum_ = bignum * 10; } + void print_bignum(float bignum) { this->bignum_ = static_cast(bignum * 10); } /** * Print the small number * * Valid values are from -9 to 99. Smaller values are displayed as Lo, higher as Hi. */ - void print_smallnum(float smallnum) { this->smallnum_ = smallnum; } + void print_smallnum(float smallnum) { this->smallnum_ = static_cast(smallnum); } /** * Print a happy face * @@ -107,8 +107,8 @@ class PVVXDisplay : public ble_client::BLEClientNode, public PollingComponent { bool auto_clear_enabled_{true}; uint32_t disconnect_delay_ms_ = 5000; uint16_t validity_period_ = 300; - uint16_t bignum_ = 0; - uint16_t smallnum_ = 0; + int16_t bignum_ = 0; + int16_t smallnum_ = 0; uint8_t cfg_ = 0; void setcfgbit_(uint8_t bit, bool value); From 20e43398fa8849fddf1050948ae7852d4c4429f5 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Tue, 30 Dec 2025 12:21:30 +1000 Subject: [PATCH 051/302] [cli] Report program path on host (#12743) --- esphome/__main__.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/esphome/__main__.py b/esphome/__main__.py index 119ab957a3..3822af0330 100644 --- a/esphome/__main__.py +++ b/esphome/__main__.py @@ -789,7 +789,13 @@ def command_compile(args: ArgsProtocol, config: ConfigType) -> int | None: exit_code = compile_program(args, config) if exit_code != 0: return exit_code - _LOGGER.info("Successfully compiled program.") + if CORE.is_host: + from esphome.platformio_api import get_idedata + + program_path = str(get_idedata(config).firmware_elf_path) + _LOGGER.info("Successfully compiled program to path '%s'", program_path) + else: + _LOGGER.info("Successfully compiled program.") return 0 @@ -839,10 +845,8 @@ def command_run(args: ArgsProtocol, config: ConfigType) -> int | None: if CORE.is_host: from esphome.platformio_api import get_idedata - idedata = get_idedata(config) - if idedata is None: - return 1 - program_path = idedata.raw["prog_path"] + program_path = str(get_idedata(config).firmware_elf_path) + _LOGGER.info("Running program from path '%s'", program_path) return run_external_process(program_path) # Get devices, resolving special identifiers like OTA From 63464a13c31127885fe75b554f201a929dcbbaa2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 29 Dec 2025 16:57:22 -1000 Subject: [PATCH 052/302] [core] Fix incremental build failures when adding components on ESP32-Arduino (#12745) --- esphome/writer.py | 9 ++-- tests/unit_tests/test_writer.py | 88 +++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/esphome/writer.py b/esphome/writer.py index 9ae40e417a..cb9c921693 100644 --- a/esphome/writer.py +++ b/esphome/writer.py @@ -103,14 +103,11 @@ def storage_should_clean(old: StorageJSON | None, new: StorageJSON) -> bool: def storage_should_update_cmake_cache(old: StorageJSON, new: StorageJSON) -> bool: - if ( + # ESP32 uses CMake for both Arduino and ESP-IDF frameworks + return ( old.loaded_integrations != new.loaded_integrations or old.loaded_platforms != new.loaded_platforms - ) and new.core_platform == PLATFORM_ESP32: - from esphome.components.esp32 import FRAMEWORK_ESP_IDF - - return new.framework == FRAMEWORK_ESP_IDF - return False + ) and new.core_platform == PLATFORM_ESP32 def update_storage_json() -> None: diff --git a/tests/unit_tests/test_writer.py b/tests/unit_tests/test_writer.py index f354d71bb7..ac05e0d31b 100644 --- a/tests/unit_tests/test_writer.py +++ b/tests/unit_tests/test_writer.py @@ -13,6 +13,13 @@ from unittest.mock import MagicMock, patch import pytest +from esphome.const import ( + PLATFORM_BK72XX, + PLATFORM_ESP32, + PLATFORM_ESP8266, + PLATFORM_RP2040, + PLATFORM_RTL87XX, +) from esphome.core import EsphomeError from esphome.storage_json import StorageJSON from esphome.writer import ( @@ -28,6 +35,7 @@ from esphome.writer import ( generate_build_info_data_h, get_build_info, storage_should_clean, + storage_should_update_cmake_cache, update_storage_json, write_cpp, write_gitignore, @@ -171,6 +179,86 @@ def test_storage_edge_case_from_empty_integrations( assert storage_should_clean(old, new) is False +# Tests for storage_should_update_cmake_cache + + +@pytest.mark.parametrize("framework", ["arduino", "esp-idf"]) +def test_storage_should_update_cmake_cache_when_integration_added_esp32( + create_storage: Callable[..., StorageJSON], + framework: str, +) -> None: + """Test cmake cache update triggered when integration added on ESP32.""" + old = create_storage( + loaded_integrations=["api", "wifi"], + core_platform=PLATFORM_ESP32, + framework=framework, + ) + new = create_storage( + loaded_integrations=["api", "wifi", "restart"], + core_platform=PLATFORM_ESP32, + framework=framework, + ) + assert storage_should_update_cmake_cache(old, new) is True + + +def test_storage_should_update_cmake_cache_when_platform_changed_esp32( + create_storage: Callable[..., StorageJSON], +) -> None: + """Test cmake cache update triggered when platforms change on ESP32.""" + old = create_storage( + loaded_integrations=["api", "wifi"], + loaded_platforms={"sensor"}, + core_platform=PLATFORM_ESP32, + framework="arduino", + ) + new = create_storage( + loaded_integrations=["api", "wifi"], + loaded_platforms={"sensor", "binary_sensor"}, + core_platform=PLATFORM_ESP32, + framework="arduino", + ) + assert storage_should_update_cmake_cache(old, new) is True + + +def test_storage_should_not_update_cmake_cache_when_nothing_changes( + create_storage: Callable[..., StorageJSON], +) -> None: + """Test cmake cache not updated when nothing changes.""" + old = create_storage( + loaded_integrations=["api", "wifi"], + core_platform=PLATFORM_ESP32, + framework="arduino", + ) + new = create_storage( + loaded_integrations=["api", "wifi"], + core_platform=PLATFORM_ESP32, + framework="arduino", + ) + assert storage_should_update_cmake_cache(old, new) is False + + +@pytest.mark.parametrize( + "core_platform", + [PLATFORM_ESP8266, PLATFORM_RP2040, PLATFORM_BK72XX, PLATFORM_RTL87XX], +) +def test_storage_should_not_update_cmake_cache_for_non_esp32( + create_storage: Callable[..., StorageJSON], + core_platform: str, +) -> None: + """Test cmake cache not updated for non-ESP32 platforms.""" + old = create_storage( + loaded_integrations=["api", "wifi"], + core_platform=core_platform, + framework="arduino", + ) + new = create_storage( + loaded_integrations=["api", "wifi", "restart"], + core_platform=core_platform, + framework="arduino", + ) + assert storage_should_update_cmake_cache(old, new) is False + + @patch("esphome.writer.clean_build") @patch("esphome.writer.StorageJSON") @patch("esphome.writer.storage_path") From d86c05bfe65b7d2746356df435dcc998c60f2907 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 29 Dec 2025 17:23:41 -1000 Subject: [PATCH 053/302] [esp32] Breaking Change: Change default framework to ESP-IDF (#12746) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- esphome/components/esp32/__init__.py | 52 +++++++++++----------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index d307ae75c8..929ced6e3b 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -729,12 +729,14 @@ FRAMEWORK_SCHEMA = cv.Schema( ) +# Remove this class in 2026.7.0 class _FrameworkMigrationWarning: shown = False def _show_framework_migration_message(name: str, variant: str) -> None: - """Show a friendly message about framework migration when defaulting to Arduino.""" + """Show a message about the framework default change and how to switch back to Arduino.""" + # Remove this function in 2026.7.0 if _FrameworkMigrationWarning.shown: return _FrameworkMigrationWarning.shown = True @@ -744,41 +746,27 @@ def _show_framework_migration_message(name: str, variant: str) -> None: message = ( color( AnsiFore.BOLD_CYAN, - f"💡 IMPORTANT: {name} doesn't have a framework specified!", + f"💡 NOTICE: {name} does not have a framework specified.", ) + "\n\n" - + f"Currently, {variant} defaults to the Arduino framework.\n" - + color(AnsiFore.YELLOW, "This will change to ESP-IDF in ESPHome 2026.1.0.\n") + + f"Starting with ESPHome 2026.1.0, the default framework for {variant} is ESP-IDF.\n" + + "(We've been warning about this change since ESPHome 2025.8.0)\n" + "\n" - + "Note: Newer ESP32 variants (C6, H2, P4, etc.) already use ESP-IDF by default.\n" - + "\n" - + "Why change? ESP-IDF offers:\n" - + color(AnsiFore.GREEN, " ✨ Up to 40% smaller binaries\n") - + color(AnsiFore.GREEN, " 🚀 Better performance and optimization\n") + + "Why we made this change:\n" + + color(AnsiFore.GREEN, " ✨ Up to 40% smaller firmware binaries\n") + color(AnsiFore.GREEN, " ⚡ 2-3x faster compile times\n") - + color(AnsiFore.GREEN, " 📦 Custom-built firmware for your exact needs\n") - + color( - AnsiFore.GREEN, - " 🔧 Active development and testing by ESPHome developers\n", - ) + + color(AnsiFore.GREEN, " 🚀 Better performance and newer features\n") + + color(AnsiFore.GREEN, " 🔧 More actively maintained by ESPHome\n") + "\n" - + "Trade-offs:\n" - + color(AnsiFore.YELLOW, " 🔄 Some components need migration\n") + + "To continue using Arduino, add this to your YAML under 'esp32:':\n" + + color(AnsiFore.WHITE, " framework:\n") + + color(AnsiFore.WHITE, " type: arduino\n") + "\n" - + "What should I do?\n" - + color(AnsiFore.CYAN, " Option 1") - + ": Migrate to ESP-IDF (recommended)\n" - + " Add this to your YAML under 'esp32:':\n" - + color(AnsiFore.WHITE, " framework:\n") - + color(AnsiFore.WHITE, " type: esp-idf\n") + + "To silence this message with ESP-IDF, explicitly set:\n" + + color(AnsiFore.WHITE, " framework:\n") + + color(AnsiFore.WHITE, " type: esp-idf\n") + "\n" - + color(AnsiFore.CYAN, " Option 2") - + ": Keep using Arduino (still supported)\n" - + " Add this to your YAML under 'esp32:':\n" - + color(AnsiFore.WHITE, " framework:\n") - + color(AnsiFore.WHITE, " type: arduino\n") - + "\n" - + "Need help? Check out the migration guide:\n" + + "Migration guide: " + color( AnsiFore.BLUE, "https://esphome.io/guides/esp32_arduino_to_idf/", @@ -793,13 +781,13 @@ def _set_default_framework(config): config[CONF_FRAMEWORK] = FRAMEWORK_SCHEMA({}) if CONF_TYPE not in config[CONF_FRAMEWORK]: variant = config[CONF_VARIANT] + config[CONF_FRAMEWORK][CONF_TYPE] = FRAMEWORK_ESP_IDF + # Show migration message for variants that previously defaulted to Arduino + # Remove this message in 2026.7.0 if variant in ARDUINO_ALLOWED_VARIANTS: - config[CONF_FRAMEWORK][CONF_TYPE] = FRAMEWORK_ARDUINO _show_framework_migration_message( config.get(CONF_NAME, "This device"), variant ) - else: - config[CONF_FRAMEWORK][CONF_TYPE] = FRAMEWORK_ESP_IDF return config From 4c16afeacb059bbff720caae2e4524ad053ecc8a Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Mon, 29 Dec 2025 22:25:26 -0500 Subject: [PATCH 054/302] [esp32] Add IDF framework source for Arduino builds (#12731) Co-authored-by: Claude Opus 4.5 Co-authored-by: J. Nick Koston --- esphome/components/esp32/__init__.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index 929ced6e3b..d8397a87cc 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -375,6 +375,23 @@ ARDUINO_PLATFORM_VERSION_LOOKUP = { cv.Version(3, 1, 1): cv.Version(53, 3, 11), cv.Version(3, 1, 0): cv.Version(53, 3, 10), } +# Maps Arduino framework versions to a compatible ESP-IDF version +# These versions correspond to pioarduino/esp-idf releases +# See: https://github.com/pioarduino/esp-idf/releases +ARDUINO_IDF_VERSION_LOOKUP = { + cv.Version(3, 3, 5): cv.Version(5, 5, 2), + cv.Version(3, 3, 4): cv.Version(5, 5, 1), + cv.Version(3, 3, 3): cv.Version(5, 5, 1), + cv.Version(3, 3, 2): cv.Version(5, 5, 1), + cv.Version(3, 3, 1): cv.Version(5, 5, 1), + cv.Version(3, 3, 0): cv.Version(5, 5, 0), + cv.Version(3, 2, 1): cv.Version(5, 4, 2), + cv.Version(3, 2, 0): cv.Version(5, 4, 2), + cv.Version(3, 1, 3): cv.Version(5, 3, 2), + cv.Version(3, 1, 2): cv.Version(5, 3, 2), + cv.Version(3, 1, 1): cv.Version(5, 3, 1), + cv.Version(3, 1, 0): cv.Version(5, 3, 0), +} # The default/recommended esp-idf framework version # - https://github.com/espressif/esp-idf/releases @@ -981,6 +998,13 @@ async def to_code(config): add_idf_sdkconfig_option("CONFIG_MBEDTLS_PSK_MODES", True) add_idf_sdkconfig_option("CONFIG_MBEDTLS_CERTIFICATE_BUNDLE", True) + # Add IDF framework source for Arduino builds to ensure it uses the same version as + # the ESP-IDF framework + if (idf_ver := ARDUINO_IDF_VERSION_LOOKUP.get(framework_ver)) is not None: + cg.add_platformio_option( + "platform_packages", [_format_framework_espidf_version(idf_ver, None)] + ) + # ESP32-S2 Arduino: Disable USB Serial on boot to avoid TinyUSB dependency if get_esp32_variant() == VARIANT_ESP32S2: cg.add_build_unflag("-DARDUINO_USB_CDC_ON_BOOT=1") From 468bd7b04f4ff1f59ff0680064d1f253748109d0 Mon Sep 17 00:00:00 2001 From: bakroistvan Date: Tue, 30 Dec 2025 07:53:28 +0100 Subject: [PATCH 055/302] [dallas_temp] higher precision for logged temperature (#12695) --- esphome/components/dallas_temp/dallas_temp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/dallas_temp/dallas_temp.cpp b/esphome/components/dallas_temp/dallas_temp.cpp index a3969e081e..a1b684abbf 100644 --- a/esphome/components/dallas_temp/dallas_temp.cpp +++ b/esphome/components/dallas_temp/dallas_temp.cpp @@ -51,7 +51,7 @@ void DallasTemperatureSensor::update() { } float tempc = this->get_temp_c_(); - ESP_LOGD(TAG, "'%s': Got Temperature=%.1f°C", this->get_name().c_str(), tempc); + ESP_LOGD(TAG, "'%s': Got Temperature=%f°C", this->get_name().c_str(), tempc); this->publish_state(tempc); }); } From a615b28ecf05345a908f85e54ec6f4155241a8b7 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Tue, 30 Dec 2025 07:22:36 +0000 Subject: [PATCH 056/302] [bme68x_bsec2] add `id:` to allow extending (#12649) --- esphome/components/bme68x_bsec2/sensor.py | 1 + tests/components/bme68x_bsec2_i2c/common.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/esphome/components/bme68x_bsec2/sensor.py b/esphome/components/bme68x_bsec2/sensor.py index c7dca437d7..45a9e54c1e 100644 --- a/esphome/components/bme68x_bsec2/sensor.py +++ b/esphome/components/bme68x_bsec2/sensor.py @@ -50,6 +50,7 @@ TYPES = [ CONFIG_SCHEMA = cv.Schema( { + cv.GenerateID(): cv.declare_id(cg.Component), cv.GenerateID(CONF_BME68X_BSEC2_ID): cv.use_id(BME68xBSEC2Component), cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema( unit_of_measurement=UNIT_CELSIUS, diff --git a/tests/components/bme68x_bsec2_i2c/common.yaml b/tests/components/bme68x_bsec2_i2c/common.yaml index bee964f433..a462bdaf7f 100644 --- a/tests/components/bme68x_bsec2_i2c/common.yaml +++ b/tests/components/bme68x_bsec2_i2c/common.yaml @@ -9,6 +9,7 @@ bme68x_bsec2_i2c: sensor: - platform: bme68x_bsec2 + id: bme_sensor temperature: name: BME68X Temperature pressure: From 339399eb7084fdecc09d8e65cebda54759bd08a0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 27 Dec 2025 08:35:36 -1000 Subject: [PATCH 057/302] [lvgl] Fix lambdas in canvas actions called from outside LVGL context (#12671) --- esphome/components/lvgl/defines.py | 10 +++------- esphome/components/lvgl/lv_validation.py | 11 +++-------- esphome/components/lvgl/lvcode.py | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/esphome/components/lvgl/defines.py b/esphome/components/lvgl/defines.py index 1d528b2f73..91077a1ff4 100644 --- a/esphome/components/lvgl/defines.py +++ b/esphome/components/lvgl/defines.py @@ -5,7 +5,7 @@ Constants already defined in esphome.const are not duplicated here and must be i """ import logging -from typing import TYPE_CHECKING, Any +from typing import Any from esphome import codegen as cg, config_validation as cv from esphome.const import CONF_ITEMS @@ -96,13 +96,9 @@ class LValidator: return None if isinstance(value, Lambda): # Local import to avoid circular import - from .lvcode import CodeContext, LambdaContext + from .lvcode import get_lambda_context_args - if TYPE_CHECKING: - # CodeContext does not have get_automation_parameters - # so we need to assert the type here - assert isinstance(CodeContext.code_context, LambdaContext) - args = args or CodeContext.code_context.get_automation_parameters() + args = args or get_lambda_context_args() return cg.RawExpression( call_lambda( await cg.process_lambda(value, args, return_type=self.rtype) diff --git a/esphome/components/lvgl/lv_validation.py b/esphome/components/lvgl/lv_validation.py index 9c1dd22085..947e44b131 100644 --- a/esphome/components/lvgl/lv_validation.py +++ b/esphome/components/lvgl/lv_validation.py @@ -1,5 +1,5 @@ import re -from typing import TYPE_CHECKING, Any +from typing import Any import esphome.codegen as cg from esphome.components import image @@ -404,14 +404,9 @@ class TextValidator(LValidator): self, value: Any, args: list[tuple[SafeExpType, str]] | None = None ) -> Expression: # Local import to avoid circular import at module level + from .lvcode import get_lambda_context_args - from .lvcode import CodeContext, LambdaContext - - if TYPE_CHECKING: - # CodeContext does not have get_automation_parameters - # so we need to assert the type here - assert isinstance(CodeContext.code_context, LambdaContext) - args = args or CodeContext.code_context.get_automation_parameters() + args = args or get_lambda_context_args() if isinstance(value, dict): if format_str := value.get(CONF_FORMAT): diff --git a/esphome/components/lvgl/lvcode.py b/esphome/components/lvgl/lvcode.py index c11597131f..2a1da2383c 100644 --- a/esphome/components/lvgl/lvcode.py +++ b/esphome/components/lvgl/lvcode.py @@ -1,4 +1,5 @@ import abc +from typing import TYPE_CHECKING from esphome import codegen as cg from esphome.config import Config @@ -200,6 +201,21 @@ class LvContext(LambdaContext): return self.add(*args) +def get_lambda_context_args() -> list[tuple[SafeExpType, str]]: + """Get automation parameters from the current lambda context if available. + + When called from outside LVGL's context (e.g., from interval), + CodeContext.code_context will be None, so return empty args. + """ + if CodeContext.code_context is None: + return [] + if TYPE_CHECKING: + # CodeContext base class doesn't define get_automation_parameters(), + # but LambdaContext and LvContext (the concrete implementations) do. + assert isinstance(CodeContext.code_context, LambdaContext) + return CodeContext.code_context.get_automation_parameters() + + class LocalVariable(MockObj): """ Create a local variable and enclose the code using it within a block. From 0194bfd9ea8ef1ccd4eb1ef416dede9c522edb77 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 29 Dec 2025 16:57:22 -1000 Subject: [PATCH 058/302] [core] Fix incremental build failures when adding components on ESP32-Arduino (#12745) --- esphome/writer.py | 9 ++-- tests/unit_tests/test_writer.py | 88 +++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/esphome/writer.py b/esphome/writer.py index 721db07f96..684b3f9dc5 100644 --- a/esphome/writer.py +++ b/esphome/writer.py @@ -99,14 +99,11 @@ def storage_should_clean(old: StorageJSON | None, new: StorageJSON) -> bool: def storage_should_update_cmake_cache(old: StorageJSON, new: StorageJSON) -> bool: - if ( + # ESP32 uses CMake for both Arduino and ESP-IDF frameworks + return ( old.loaded_integrations != new.loaded_integrations or old.loaded_platforms != new.loaded_platforms - ) and new.core_platform == PLATFORM_ESP32: - from esphome.components.esp32 import FRAMEWORK_ESP_IDF - - return new.framework == FRAMEWORK_ESP_IDF - return False + ) and new.core_platform == PLATFORM_ESP32 def update_storage_json() -> None: diff --git a/tests/unit_tests/test_writer.py b/tests/unit_tests/test_writer.py index 9fa60c06ec..fa2ca0a696 100644 --- a/tests/unit_tests/test_writer.py +++ b/tests/unit_tests/test_writer.py @@ -9,6 +9,13 @@ from unittest.mock import MagicMock, patch import pytest +from esphome.const import ( + PLATFORM_BK72XX, + PLATFORM_ESP32, + PLATFORM_ESP8266, + PLATFORM_RP2040, + PLATFORM_RTL87XX, +) from esphome.core import EsphomeError from esphome.storage_json import StorageJSON from esphome.writer import ( @@ -21,6 +28,7 @@ from esphome.writer import ( clean_build, clean_cmake_cache, storage_should_clean, + storage_should_update_cmake_cache, update_storage_json, write_cpp, write_gitignore, @@ -164,6 +172,86 @@ def test_storage_edge_case_from_empty_integrations( assert storage_should_clean(old, new) is False +# Tests for storage_should_update_cmake_cache + + +@pytest.mark.parametrize("framework", ["arduino", "esp-idf"]) +def test_storage_should_update_cmake_cache_when_integration_added_esp32( + create_storage: Callable[..., StorageJSON], + framework: str, +) -> None: + """Test cmake cache update triggered when integration added on ESP32.""" + old = create_storage( + loaded_integrations=["api", "wifi"], + core_platform=PLATFORM_ESP32, + framework=framework, + ) + new = create_storage( + loaded_integrations=["api", "wifi", "restart"], + core_platform=PLATFORM_ESP32, + framework=framework, + ) + assert storage_should_update_cmake_cache(old, new) is True + + +def test_storage_should_update_cmake_cache_when_platform_changed_esp32( + create_storage: Callable[..., StorageJSON], +) -> None: + """Test cmake cache update triggered when platforms change on ESP32.""" + old = create_storage( + loaded_integrations=["api", "wifi"], + loaded_platforms={"sensor"}, + core_platform=PLATFORM_ESP32, + framework="arduino", + ) + new = create_storage( + loaded_integrations=["api", "wifi"], + loaded_platforms={"sensor", "binary_sensor"}, + core_platform=PLATFORM_ESP32, + framework="arduino", + ) + assert storage_should_update_cmake_cache(old, new) is True + + +def test_storage_should_not_update_cmake_cache_when_nothing_changes( + create_storage: Callable[..., StorageJSON], +) -> None: + """Test cmake cache not updated when nothing changes.""" + old = create_storage( + loaded_integrations=["api", "wifi"], + core_platform=PLATFORM_ESP32, + framework="arduino", + ) + new = create_storage( + loaded_integrations=["api", "wifi"], + core_platform=PLATFORM_ESP32, + framework="arduino", + ) + assert storage_should_update_cmake_cache(old, new) is False + + +@pytest.mark.parametrize( + "core_platform", + [PLATFORM_ESP8266, PLATFORM_RP2040, PLATFORM_BK72XX, PLATFORM_RTL87XX], +) +def test_storage_should_not_update_cmake_cache_for_non_esp32( + create_storage: Callable[..., StorageJSON], + core_platform: str, +) -> None: + """Test cmake cache not updated for non-ESP32 platforms.""" + old = create_storage( + loaded_integrations=["api", "wifi"], + core_platform=core_platform, + framework="arduino", + ) + new = create_storage( + loaded_integrations=["api", "wifi", "restart"], + core_platform=core_platform, + framework="arduino", + ) + assert storage_should_update_cmake_cache(old, new) is False + + @patch("esphome.writer.clean_build") @patch("esphome.writer.StorageJSON") @patch("esphome.writer.storage_path") From c737033cc42eda289648ce0b33a61f1d0ee7267f Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 30 Dec 2025 09:22:03 -0500 Subject: [PATCH 059/302] Bump version to 2025.12.3 --- Doxyfile | 2 +- esphome/const.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doxyfile b/Doxyfile index d41459ea46..fbd5ffa80e 100644 --- a/Doxyfile +++ b/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = ESPHome # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 2025.12.2 +PROJECT_NUMBER = 2025.12.3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/esphome/const.py b/esphome/const.py index 41bb419aaf..ab72bfcaac 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -4,7 +4,7 @@ from enum import Enum from esphome.enum import StrEnum -__version__ = "2025.12.2" +__version__ = "2025.12.3" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From dae7ba604a28285cb88e0cc1cd44daefe8f51163 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 30 Dec 2025 10:25:51 -1000 Subject: [PATCH 060/302] [ethernet_info] Eliminate heap allocations in DNS text sensor (#12756) --- .../ethernet_info_text_sensor.cpp | 6 ++-- .../ethernet_info/ethernet_info_text_sensor.h | 28 +++++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/esphome/components/ethernet_info/ethernet_info_text_sensor.cpp b/esphome/components/ethernet_info/ethernet_info_text_sensor.cpp index 329fb9113a..35e18c7de5 100644 --- a/esphome/components/ethernet_info/ethernet_info_text_sensor.cpp +++ b/esphome/components/ethernet_info/ethernet_info_text_sensor.cpp @@ -3,8 +3,7 @@ #ifdef USE_ESP32 -namespace esphome { -namespace ethernet_info { +namespace esphome::ethernet_info { static const char *const TAG = "ethernet_info"; @@ -12,7 +11,6 @@ void IPAddressEthernetInfo::dump_config() { LOG_TEXT_SENSOR("", "EthernetInfo IP void DNSAddressEthernetInfo::dump_config() { LOG_TEXT_SENSOR("", "EthernetInfo DNS Address", this); } void MACAddressEthernetInfo::dump_config() { LOG_TEXT_SENSOR("", "EthernetInfo MAC Address", this); } -} // namespace ethernet_info -} // namespace esphome +} // namespace esphome::ethernet_info #endif // USE_ESP32 diff --git a/esphome/components/ethernet_info/ethernet_info_text_sensor.h b/esphome/components/ethernet_info/ethernet_info_text_sensor.h index 2adc08e31e..b49ddc263d 100644 --- a/esphome/components/ethernet_info/ethernet_info_text_sensor.h +++ b/esphome/components/ethernet_info/ethernet_info_text_sensor.h @@ -6,8 +6,7 @@ #ifdef USE_ESP32 -namespace esphome { -namespace ethernet_info { +namespace esphome::ethernet_info { class IPAddressEthernetInfo : public PollingComponent, public text_sensor::TextSensor { public: @@ -40,21 +39,27 @@ class IPAddressEthernetInfo : public PollingComponent, public text_sensor::TextS class DNSAddressEthernetInfo : public PollingComponent, public text_sensor::TextSensor { public: void update() override { - auto dns_one = ethernet::global_eth_component->get_dns_address(0); - auto dns_two = ethernet::global_eth_component->get_dns_address(1); + auto dns1 = ethernet::global_eth_component->get_dns_address(0); + auto dns2 = ethernet::global_eth_component->get_dns_address(1); - std::string dns_results = dns_one.str() + " " + dns_two.str(); - - if (dns_results != this->last_results_) { - this->last_results_ = dns_results; - this->publish_state(dns_results); + if (dns1 != this->last_dns1_ || dns2 != this->last_dns2_) { + this->last_dns1_ = dns1; + this->last_dns2_ = dns2; + // IP_ADDRESS_BUFFER_SIZE (40) = max IP (39) + null; space reuses first null's slot + char buf[network::IP_ADDRESS_BUFFER_SIZE * 2]; + dns1.str_to(buf); + size_t len1 = strlen(buf); + buf[len1] = ' '; + dns2.str_to(buf + len1 + 1); + this->publish_state(buf); } } float get_setup_priority() const override { return setup_priority::ETHERNET; } void dump_config() override; protected: - std::string last_results_; + network::IPAddress last_dns1_; + network::IPAddress last_dns2_; }; class MACAddressEthernetInfo : public Component, public text_sensor::TextSensor { @@ -64,7 +69,6 @@ class MACAddressEthernetInfo : public Component, public text_sensor::TextSensor void dump_config() override; }; -} // namespace ethernet_info -} // namespace esphome +} // namespace esphome::ethernet_info #endif // USE_ESP32 From bd3ecad3a14e57c1bd4284578dd2e1da04a25dc6 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 30 Dec 2025 11:51:51 -1000 Subject: [PATCH 061/302] [core] Add format_hex_pretty_to buffer helper and reduce code duplication (#12687) --- esphome/components/hmac_md5/hmac_md5.h | 2 +- esphome/components/hmac_sha256/hmac_sha256.h | 2 +- .../components/zwave_proxy/zwave_proxy.cpp | 6 +- esphome/components/zwave_proxy/zwave_proxy.h | 5 +- esphome/core/hash_base.h | 10 +-- esphome/core/helpers.cpp | 63 +++++++++------ esphome/core/helpers.h | 76 +++++++++++-------- 7 files changed, 96 insertions(+), 68 deletions(-) diff --git a/esphome/components/hmac_md5/hmac_md5.h b/esphome/components/hmac_md5/hmac_md5.h index b83b9d5421..fb9479e3af 100644 --- a/esphome/components/hmac_md5/hmac_md5.h +++ b/esphome/components/hmac_md5/hmac_md5.h @@ -30,7 +30,7 @@ class HmacMD5 { void get_bytes(uint8_t *output); /// Retrieve the HMAC-MD5 digest as hex characters. - /// The output must be able to hold 32 bytes or more. + /// The output must be able to hold 33 bytes or more (32 hex chars + null terminator). void get_hex(char *output); /// Compare the digest against a provided byte-encoded digest (16 bytes). diff --git a/esphome/components/hmac_sha256/hmac_sha256.h b/esphome/components/hmac_sha256/hmac_sha256.h index fa6b64aa94..85622cac46 100644 --- a/esphome/components/hmac_sha256/hmac_sha256.h +++ b/esphome/components/hmac_sha256/hmac_sha256.h @@ -35,7 +35,7 @@ class HmacSHA256 { void get_bytes(uint8_t *output); /// Retrieve the HMAC-SHA256 digest as hex characters. - /// The output must be able to hold 64 bytes or more. + /// The output must be able to hold 65 bytes or more (64 hex chars + null terminator). void get_hex(char *output); /// Compare the digest against a provided byte-encoded digest (32 bytes). diff --git a/esphome/components/zwave_proxy/zwave_proxy.cpp b/esphome/components/zwave_proxy/zwave_proxy.cpp index bd3f85772b..e4efa55e25 100644 --- a/esphome/components/zwave_proxy/zwave_proxy.cpp +++ b/esphome/components/zwave_proxy/zwave_proxy.cpp @@ -123,10 +123,11 @@ void ZWaveProxy::process_uart_() { } void ZWaveProxy::dump_config() { + char hex_buf[format_hex_pretty_size(ZWAVE_HOME_ID_SIZE)]; ESP_LOGCONFIG(TAG, "Z-Wave Proxy:\n" " Home ID: %s", - format_hex_pretty(this->home_id_.data(), this->home_id_.size(), ':', false).c_str()); + format_hex_pretty_to(hex_buf, this->home_id_.data(), this->home_id_.size())); } void ZWaveProxy::api_connection_authenticated(api::APIConnection *conn) { @@ -167,7 +168,8 @@ bool ZWaveProxy::set_home_id(const uint8_t *new_home_id) { return false; // No change } std::memcpy(this->home_id_.data(), new_home_id, this->home_id_.size()); - ESP_LOGI(TAG, "Home ID: %s", format_hex_pretty(this->home_id_.data(), this->home_id_.size(), ':', false).c_str()); + char hex_buf[format_hex_pretty_size(ZWAVE_HOME_ID_SIZE)]; + ESP_LOGI(TAG, "Home ID: %s", format_hex_pretty_to(hex_buf, this->home_id_.data(), this->home_id_.size())); this->home_id_ready_ = true; return true; // Home ID was changed } diff --git a/esphome/components/zwave_proxy/zwave_proxy.h b/esphome/components/zwave_proxy/zwave_proxy.h index 137a1206e3..f36287d32a 100644 --- a/esphome/components/zwave_proxy/zwave_proxy.h +++ b/esphome/components/zwave_proxy/zwave_proxy.h @@ -14,6 +14,7 @@ namespace esphome::zwave_proxy { static constexpr size_t MAX_ZWAVE_FRAME_SIZE = 257; // Maximum Z-Wave frame size +static constexpr size_t ZWAVE_HOME_ID_SIZE = 4; // Z-Wave Home ID size in bytes enum ZWaveResponseTypes : uint8_t { ZWAVE_FRAME_TYPE_ACK = 0x06, @@ -73,8 +74,8 @@ class ZWaveProxy : public uart::UARTDevice, public Component { // Pre-allocated message - always ready to send api::ZWaveProxyFrame outgoing_proto_msg_; - std::array buffer_; // Fixed buffer for incoming data - std::array home_id_{0, 0, 0, 0}; // Fixed buffer for home ID + std::array buffer_; // Fixed buffer for incoming data + std::array home_id_{}; // Fixed buffer for home ID // Pointers and 32-bit values (aligned together) api::APIConnection *api_connection_{nullptr}; // Current subscribed client diff --git a/esphome/core/hash_base.h b/esphome/core/hash_base.h index c45c4df70b..0c1c2dce33 100644 --- a/esphome/core/hash_base.h +++ b/esphome/core/hash_base.h @@ -25,14 +25,8 @@ class HashBase { /// Retrieve the hash as bytes void get_bytes(uint8_t *output) { memcpy(output, this->digest_, this->get_size()); } - /// Retrieve the hash as hex characters - void get_hex(char *output) { - for (size_t i = 0; i < this->get_size(); i++) { - uint8_t byte = this->digest_[i]; - output[i * 2] = format_hex_char(byte >> 4); - output[i * 2 + 1] = format_hex_char(byte & 0x0F); - } - } + /// Retrieve the hash as hex characters. Output buffer must hold get_size() * 2 + 1 bytes. + void get_hex(char *output) { format_hex_to(output, this->get_size() * 2 + 1, this->digest_, this->get_size()); } /// Compare the hash against a provided byte-encoded hash bool equals_bytes(const uint8_t *expected) { return memcmp(this->digest_, expected, this->get_size()) == 0; } diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index 5e361ecce2..1c68f1a021 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -286,43 +286,60 @@ std::string format_mac_address_pretty(const uint8_t *mac) { return std::string(buf); } -std::string format_hex(const uint8_t *data, size_t length) { - std::string ret; - ret.resize(length * 2); - for (size_t i = 0; i < length; i++) { - ret[2 * i] = format_hex_char(data[i] >> 4); - ret[2 * i + 1] = format_hex_char(data[i] & 0x0F); +// Internal helper for hex formatting - base is 'a' for lowercase or 'A' for uppercase +static char *format_hex_internal(char *buffer, size_t buffer_size, const uint8_t *data, size_t length, char separator, + char base) { + if (length == 0) { + buffer[0] = '\0'; + return buffer; + } + // With separator: total length is 3*length (2*length hex chars, (length-1) separators, 1 null terminator) + // Without separator: total length is 2*length + 1 (2*length hex chars, 1 null terminator) + uint8_t stride = separator ? 3 : 2; + size_t max_bytes = separator ? (buffer_size / stride) : ((buffer_size - 1) / stride); + if (max_bytes == 0) { + buffer[0] = '\0'; + return buffer; } - return ret; -} -std::string format_hex(const std::vector &data) { return format_hex(data.data(), data.size()); } - -char *format_hex_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length) { - size_t max_bytes = (buffer_size - 1) / 2; if (length > max_bytes) { length = max_bytes; } for (size_t i = 0; i < length; i++) { - buffer[2 * i] = format_hex_char(data[i] >> 4); - buffer[2 * i + 1] = format_hex_char(data[i] & 0x0F); + size_t pos = i * stride; + buffer[pos] = format_hex_char(data[i] >> 4, base); + buffer[pos + 1] = format_hex_char(data[i] & 0x0F, base); + if (separator && i < length - 1) { + buffer[pos + 2] = separator; + } } - buffer[length * 2] = '\0'; + buffer[length * stride - (separator ? 1 : 0)] = '\0'; return buffer; } +char *format_hex_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length) { + return format_hex_internal(buffer, buffer_size, data, length, 0, 'a'); +} + +std::string format_hex(const uint8_t *data, size_t length) { + std::string ret; + ret.resize(length * 2); + format_hex_to(&ret[0], length * 2 + 1, data, length); + return ret; +} +std::string format_hex(const std::vector &data) { return format_hex(data.data(), data.size()); } + +char *format_hex_pretty_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length, char separator) { + return format_hex_internal(buffer, buffer_size, data, length, separator, 'A'); +} + // Shared implementation for uint8_t and string hex formatting static std::string format_hex_pretty_uint8(const uint8_t *data, size_t length, char separator, bool show_length) { if (data == nullptr || length == 0) return ""; std::string ret; - uint8_t multiple = separator ? 3 : 2; // 3 if separator is not \0, 2 otherwise - ret.resize(multiple * length - (separator ? 1 : 0)); - for (size_t i = 0; i < length; i++) { - ret[multiple * i] = format_hex_pretty_char(data[i] >> 4); - ret[multiple * i + 1] = format_hex_pretty_char(data[i] & 0x0F); - if (separator && i != length - 1) - ret[multiple * i + 2] = separator; - } + size_t hex_len = separator ? (length * 3 - 1) : (length * 2); + ret.resize(hex_len); + format_hex_pretty_to(&ret[0], hex_len + 1, data, length, separator); if (show_length && length > 4) return ret + " (" + std::to_string(length) + ")"; return ret; diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 4319e32510..37534849d0 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -677,12 +677,14 @@ constexpr uint8_t parse_hex_char(char c) { return 255; } +/// Convert a nibble (0-15) to hex char with specified base ('a' for lowercase, 'A' for uppercase) +inline char format_hex_char(uint8_t v, char base) { return v >= 10 ? base + (v - 10) : '0' + v; } + /// Convert a nibble (0-15) to lowercase hex char -inline char format_hex_char(uint8_t v) { return v >= 10 ? 'a' + (v - 10) : '0' + v; } +inline char format_hex_char(uint8_t v) { return format_hex_char(v, 'a'); } /// Convert a nibble (0-15) to uppercase hex char (used for pretty printing) -/// This always uses uppercase (A-F) for pretty/human-readable output -inline char format_hex_pretty_char(uint8_t v) { return v >= 10 ? 'A' + (v - 10) : '0' + v; } +inline char format_hex_pretty_char(uint8_t v) { return format_hex_char(v, 'A'); } /// Write int8 value to buffer without modulo operations. /// Buffer must have at least 4 bytes free. Returns pointer past last char written. @@ -708,28 +710,6 @@ inline char *int8_to_str(char *buf, int8_t val) { return buf; } -/// Format MAC address as XX:XX:XX:XX:XX:XX (uppercase) -inline void format_mac_addr_upper(const uint8_t *mac, char *output) { - for (size_t i = 0; i < 6; i++) { - uint8_t byte = mac[i]; - output[i * 3] = format_hex_pretty_char(byte >> 4); - output[i * 3 + 1] = format_hex_pretty_char(byte & 0x0F); - if (i < 5) - output[i * 3 + 2] = ':'; - } - output[17] = '\0'; -} - -/// Format MAC address as xxxxxxxxxxxxxx (lowercase, no separators) -inline void format_mac_addr_lower_no_sep(const uint8_t *mac, char *output) { - for (size_t i = 0; i < 6; i++) { - uint8_t byte = mac[i]; - output[i * 2] = format_hex_char(byte >> 4); - output[i * 2 + 1] = format_hex_char(byte & 0x0F); - } - output[12] = '\0'; -} - /// Format byte array as lowercase hex to buffer (base implementation). char *format_hex_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length); @@ -748,6 +728,46 @@ inline char *format_hex_to(char (&buffer)[N], T val) { return format_hex_to(buffer, reinterpret_cast(&val), sizeof(T)); } +/// Calculate buffer size needed for format_hex_pretty_to with separator: "XX:XX:...:XX\0" +constexpr size_t format_hex_pretty_size(size_t byte_count) { return byte_count * 3; } + +/** Format byte array as uppercase hex to buffer (base implementation). + * + * @param buffer Output buffer to write to. + * @param buffer_size Size of the output buffer. + * @param data Pointer to the byte array to format. + * @param length Number of bytes in the array. + * @param separator Character to use between hex bytes, or '\0' for no separator. + * @return Pointer to buffer. + * + * Buffer size needed: length * 3 with separator (for "XX:XX:XX\0"), length * 2 + 1 without. + */ +char *format_hex_pretty_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length, char separator = ':'); + +/// Format byte array as uppercase hex with separator to buffer. Automatically deduces buffer size. +template +inline char *format_hex_pretty_to(char (&buffer)[N], const uint8_t *data, size_t length, char separator = ':') { + static_assert(N >= 3, "Buffer must hold at least one hex byte"); + return format_hex_pretty_to(buffer, N, data, length, separator); +} + +/// MAC address size in bytes +static constexpr size_t MAC_ADDRESS_SIZE = 6; +/// Buffer size for MAC address with separators: "XX:XX:XX:XX:XX:XX\0" +static constexpr size_t MAC_ADDRESS_PRETTY_BUFFER_SIZE = format_hex_pretty_size(MAC_ADDRESS_SIZE); +/// Buffer size for MAC address without separators: "XXXXXXXXXXXX\0" +static constexpr size_t MAC_ADDRESS_BUFFER_SIZE = MAC_ADDRESS_SIZE * 2 + 1; + +/// Format MAC address as XX:XX:XX:XX:XX:XX (uppercase, colon separators) +inline void format_mac_addr_upper(const uint8_t *mac, char *output) { + format_hex_pretty_to(output, MAC_ADDRESS_PRETTY_BUFFER_SIZE, mac, MAC_ADDRESS_SIZE, ':'); +} + +/// Format MAC address as xxxxxxxxxxxxxx (lowercase, no separators) +inline void format_mac_addr_lower_no_sep(const uint8_t *mac, char *output) { + format_hex_to(output, MAC_ADDRESS_BUFFER_SIZE, mac, MAC_ADDRESS_SIZE); +} + /// Format the six-byte array \p mac into a MAC address. std::string format_mac_address_pretty(const uint8_t mac[6]); /// Format the byte array \p data of length \p len in lowercased hex. @@ -1203,12 +1223,6 @@ class HighFrequencyLoopRequester { /// Get the device MAC address as raw bytes, written into the provided byte array (6 bytes). void get_mac_address_raw(uint8_t *mac); // NOLINT(readability-non-const-parameter) -/// Buffer size for MAC address in lowercase hex notation (12 hex chars + null terminator) -constexpr size_t MAC_ADDRESS_BUFFER_SIZE = 13; - -/// Buffer size for MAC address in colon-separated uppercase hex notation (17 chars + null terminator) -constexpr size_t MAC_ADDRESS_PRETTY_BUFFER_SIZE = 18; - /// Get the device MAC address as a string, in lowercase hex notation. std::string get_mac_address(); From 98cdef25683c26b42617f1cf65b44c3fb42d8ee2 Mon Sep 17 00:00:00 2001 From: Stuart Parmenter Date: Wed, 31 Dec 2025 12:58:37 -0800 Subject: [PATCH 062/302] [hub75] Add clipping check (#12762) --- esphome/components/hub75/hub75.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/esphome/components/hub75/hub75.cpp b/esphome/components/hub75/hub75.cpp index 7317174831..e29f1a898c 100644 --- a/esphome/components/hub75/hub75.cpp +++ b/esphome/components/hub75/hub75.cpp @@ -111,6 +111,9 @@ void HOT HUB75Display::draw_pixel_at(int x, int y, Color color) { if (x >= this->get_width_internal() || x < 0 || y >= this->get_height_internal() || y < 0) [[unlikely]] return; + if (!this->get_clipping().inside(x, y)) + return; + driver_->set_pixel(x, y, color.r, color.g, color.b); App.feed_wdt(); } From 476d00d0e591e10a5ccb41183c649a66291acde9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 31 Dec 2025 10:59:28 -1000 Subject: [PATCH 063/302] [wifi] Fix ESP-IDF reporting connected before DHCP completes on reconnect (#12755) --- esphome/components/wifi/wifi_component_esp_idf.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index b26ac3d2e2..5d4d003d62 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -483,6 +483,12 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) { s_sta_connected = false; s_sta_connect_error = false; s_sta_connect_not_found = false; + // Reset IP address flags - ensures we don't report connected before DHCP completes + // (IP_EVENT_STA_LOST_IP doesn't always fire on disconnect) + this->got_ipv4_address_ = false; +#if USE_NETWORK_IPV6 + this->num_ipv6_addresses_ = 0; +#endif err = esp_wifi_connect(); if (err != ESP_OK) { From 4633803d5dae4d969f00b246d528aee84aab19a8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 31 Dec 2025 11:05:58 -1000 Subject: [PATCH 064/302] [docker] Add build-essential to fix ruamel.yaml 0.19.0 compilation (#12769) Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> --- docker/Dockerfile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docker/Dockerfile b/docker/Dockerfile index 64ce67e819..348a503bc8 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -11,6 +11,16 @@ FROM base-source-${BUILD_TYPE} AS base RUN git config --system --add safe.directory "*" +# Install build tools for Python packages that require compilation +# (e.g., ruamel.yaml.clibz used by ESP-IDF's idf-component-manager) +RUN if command -v apk > /dev/null; then \ + apk add --no-cache build-base; \ + else \ + apt-get update \ + && apt-get install -y --no-install-recommends build-essential \ + && rm -rf /var/lib/apt/lists/*; \ + fi + ENV PIP_DISABLE_PIP_VERSION_CHECK=1 RUN pip install --no-cache-dir -U pip uv==0.6.14 From dd855985bec15d235924b9e3bd4a3204a7137221 Mon Sep 17 00:00:00 2001 From: Stuart Parmenter Date: Wed, 31 Dec 2025 12:58:37 -0800 Subject: [PATCH 065/302] [hub75] Add clipping check (#12762) --- esphome/components/hub75/hub75.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/esphome/components/hub75/hub75.cpp b/esphome/components/hub75/hub75.cpp index e023e446c4..a09094b87c 100644 --- a/esphome/components/hub75/hub75.cpp +++ b/esphome/components/hub75/hub75.cpp @@ -111,6 +111,9 @@ void HOT HUB75Display::draw_pixel_at(int x, int y, Color color) { if (x >= this->get_width_internal() || x < 0 || y >= this->get_height_internal() || y < 0) [[unlikely]] return; + if (!this->get_clipping().inside(x, y)) + return; + driver_->set_pixel(x, y, color.r, color.g, color.b); App.feed_wdt(); } From f0f01c081ad5498533173b2ba532f3817787e6bb Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 31 Dec 2025 10:59:28 -1000 Subject: [PATCH 066/302] [wifi] Fix ESP-IDF reporting connected before DHCP completes on reconnect (#12755) --- esphome/components/wifi/wifi_component_esp_idf.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 380e4ea7fd..fb28018b07 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -483,6 +483,12 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) { s_sta_connected = false; s_sta_connect_error = false; s_sta_connect_not_found = false; + // Reset IP address flags - ensures we don't report connected before DHCP completes + // (IP_EVENT_STA_LOST_IP doesn't always fire on disconnect) + this->got_ipv4_address_ = false; +#if USE_NETWORK_IPV6 + this->num_ipv6_addresses_ = 0; +#endif err = esp_wifi_connect(); if (err != ESP_OK) { From 062840dd7bb7aa4e01d5c71b6b85406223cf8e7a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 31 Dec 2025 11:05:58 -1000 Subject: [PATCH 067/302] [docker] Add build-essential to fix ruamel.yaml 0.19.0 compilation (#12769) Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> --- docker/Dockerfile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docker/Dockerfile b/docker/Dockerfile index 64ce67e819..348a503bc8 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -11,6 +11,16 @@ FROM base-source-${BUILD_TYPE} AS base RUN git config --system --add safe.directory "*" +# Install build tools for Python packages that require compilation +# (e.g., ruamel.yaml.clibz used by ESP-IDF's idf-component-manager) +RUN if command -v apk > /dev/null; then \ + apk add --no-cache build-base; \ + else \ + apt-get update \ + && apt-get install -y --no-install-recommends build-essential \ + && rm -rf /var/lib/apt/lists/*; \ + fi + ENV PIP_DISABLE_PIP_VERSION_CHECK=1 RUN pip install --no-cache-dir -U pip uv==0.6.14 From e9e07129599394a2b42a6594bb1e4bf72f045236 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 31 Dec 2025 16:07:00 -0500 Subject: [PATCH 068/302] Bump version to 2025.12.4 --- Doxyfile | 2 +- esphome/const.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doxyfile b/Doxyfile index fbd5ffa80e..ff74757639 100644 --- a/Doxyfile +++ b/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = ESPHome # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 2025.12.3 +PROJECT_NUMBER = 2025.12.4 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/esphome/const.py b/esphome/const.py index ab72bfcaac..3fbdb69215 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -4,7 +4,7 @@ from enum import Enum from esphome.enum import StrEnum -__version__ = "2025.12.3" +__version__ = "2025.12.4" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From 1d96de986ec752c19aecbc81aa70f7413d3168fb Mon Sep 17 00:00:00 2001 From: Konstantin Tretyakov <220083+konstantint@users.noreply.github.com> Date: Wed, 31 Dec 2025 22:49:43 +0100 Subject: [PATCH 069/302] [sdist] Include yaml files in components in source distribution package Co-authored-by: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index 45d5e86672..ed65edc656 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,7 @@ include LICENSE include README.md include requirements.txt +recursive-include esphome *.yaml recursive-include esphome *.cpp *.h *.tcc *.c recursive-include esphome *.py.script recursive-include esphome LICENSE.txt From 4313130f2e3a87f8c1e35fa32db03c5085760415 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Thu, 1 Jan 2026 13:44:21 +1000 Subject: [PATCH 070/302] [lvgl] Fix arc background angles (#12773) --- esphome/components/lvgl/widgets/arc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/lvgl/widgets/arc.py b/esphome/components/lvgl/widgets/arc.py index 21530441f8..34ac9c51f7 100644 --- a/esphome/components/lvgl/widgets/arc.py +++ b/esphome/components/lvgl/widgets/arc.py @@ -85,11 +85,11 @@ class ArcType(NumberType): lv.arc_set_range(w.obj, min_value, max_value) await w.set_property( - CONF_START_ANGLE, + "bg_start_angle", await lv_angle_degrees.process(config.get(CONF_START_ANGLE)), ) await w.set_property( - CONF_END_ANGLE, await lv_angle_degrees.process(config.get(CONF_END_ANGLE)) + "bg_end_angle", await lv_angle_degrees.process(config.get(CONF_END_ANGLE)) ) await w.set_property( CONF_ROTATION, await lv_angle_degrees.process(config.get(CONF_ROTATION)) From 1945e85ddc55d7c7bd98be201dcd4f967ddb5989 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Thu, 1 Jan 2026 21:07:35 +1000 Subject: [PATCH 071/302] [core] Make LockFreeQueue more widely available (#12766) --- esphome/core/lock_free_queue.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/core/lock_free_queue.h b/esphome/core/lock_free_queue.h index 68e2825d09..e96b739b58 100644 --- a/esphome/core/lock_free_queue.h +++ b/esphome/core/lock_free_queue.h @@ -1,12 +1,12 @@ #pragma once -#if defined(USE_ESP32) - #include #include +#ifdef USE_ESP32 #include #include +#endif /* * Lock-free queue for single-producer single-consumer scenarios. @@ -95,7 +95,7 @@ template class LockFreeQueue { } protected: - T *buffer_[SIZE]; + T *buffer_[SIZE]{}; // Atomic: written by producer (push/increment), read+reset by consumer (get_and_reset) std::atomic dropped_count_; // 65535 max - more than enough for drop tracking // Atomic: written by consumer (pop), read by producer (push) to check if full @@ -106,6 +106,7 @@ template class LockFreeQueue { std::atomic tail_; }; +#ifdef USE_ESP32 // Extended queue with task notification support template class NotifyingLockFreeQueue : public LockFreeQueue { public: @@ -140,7 +141,6 @@ template class NotifyingLockFreeQueue : public LockFreeQu private: TaskHandle_t task_to_notify_; }; +#endif } // namespace esphome - -#endif // defined(USE_ESP32) From dc320f455a3c03dcd2b339148aa394d580dc67de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jan 2026 09:16:01 -1000 Subject: [PATCH 072/302] Bump bleak from 2.1.0 to 2.1.1 (#12804) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a6262e0d10..d457be9cd2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ pillow==11.3.0 cairosvg==2.8.2 freetype-py==2.5.1 jinja2==3.1.6 -bleak==2.1.0 +bleak==2.1.1 # esp-idf >= 5.0 requires this pyparsing >= 3.0 From 9847e51fbcd9f1ba9b46cbaecabdc915fdb059f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=2E=20=C3=81rkosi=20R=C3=B3bert?= Date: Thu, 1 Jan 2026 22:40:18 +0100 Subject: [PATCH 073/302] [bthome_mithermometer] Add BTHome parsing for Xiaomi Mijia BLE Sensors (#12635) --- CODEOWNERS | 1 + .../bthome_mithermometer/__init__.py | 36 +++ .../bthome_mithermometer/bthome_ble.cpp | 298 ++++++++++++++++++ .../bthome_mithermometer/bthome_ble.h | 44 +++ .../components/bthome_mithermometer/sensor.py | 88 ++++++ .../bthome_mithermometer/common.yaml | 15 + .../bthome_mithermometer/test.esp32-idf.yaml | 4 + 7 files changed, 486 insertions(+) create mode 100644 esphome/components/bthome_mithermometer/__init__.py create mode 100644 esphome/components/bthome_mithermometer/bthome_ble.cpp create mode 100644 esphome/components/bthome_mithermometer/bthome_ble.h create mode 100644 esphome/components/bthome_mithermometer/sensor.py create mode 100644 tests/components/bthome_mithermometer/common.yaml create mode 100644 tests/components/bthome_mithermometer/test.esp32-idf.yaml diff --git a/CODEOWNERS b/CODEOWNERS index f95d68a46d..0d9396aa6f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -91,6 +91,7 @@ esphome/components/bmp3xx_spi/* @latonita esphome/components/bmp581/* @kahrendt esphome/components/bp1658cj/* @Cossid esphome/components/bp5758d/* @Cossid +esphome/components/bthome_mithermometer/* @nagyrobi esphome/components/button/* @esphome/core esphome/components/bytebuffer/* @clydebarrow esphome/components/camera/* @bdraco @DT-art1 diff --git a/esphome/components/bthome_mithermometer/__init__.py b/esphome/components/bthome_mithermometer/__init__.py new file mode 100644 index 0000000000..0e84278afa --- /dev/null +++ b/esphome/components/bthome_mithermometer/__init__.py @@ -0,0 +1,36 @@ +import esphome.codegen as cg +from esphome.components import esp32_ble_tracker +import esphome.config_validation as cv +from esphome.const import CONF_ID, CONF_MAC_ADDRESS + +CODEOWNERS = ["@nagyrobi"] +DEPENDENCIES = ["esp32_ble_tracker"] + +BLE_DEVICE_SCHEMA = esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA + +bthome_mithermometer_ns = cg.esphome_ns.namespace("bthome_mithermometer") +BTHomeMiThermometer = bthome_mithermometer_ns.class_( + "BTHomeMiThermometer", esp32_ble_tracker.ESPBTDeviceListener, cg.Component +) + + +def bthome_mithermometer_base_schema(extra_schema=None): + if extra_schema is None: + extra_schema = {} + return ( + cv.Schema( + { + cv.GenerateID(CONF_ID): cv.declare_id(BTHomeMiThermometer), + cv.Required(CONF_MAC_ADDRESS): cv.mac_address, + } + ) + .extend(BLE_DEVICE_SCHEMA) + .extend(cv.COMPONENT_SCHEMA) + .extend(extra_schema) + ) + + +async def setup_bthome_mithermometer(var, config): + await cg.register_component(var, config) + await esp32_ble_tracker.register_ble_device(var, config) + cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex)) diff --git a/esphome/components/bthome_mithermometer/bthome_ble.cpp b/esphome/components/bthome_mithermometer/bthome_ble.cpp new file mode 100644 index 0000000000..b8da51a783 --- /dev/null +++ b/esphome/components/bthome_mithermometer/bthome_ble.cpp @@ -0,0 +1,298 @@ +#include "bthome_ble.h" + +#include "esphome/core/helpers.h" +#include "esphome/core/log.h" + +#include + +#ifdef USE_ESP32 + +namespace esphome { +namespace bthome_mithermometer { + +static const char *const TAG = "bthome_mithermometer"; + +static std::string format_mac_address(uint64_t address) { + std::array mac{}; + for (size_t i = 0; i < MAC_ADDRESS_SIZE; i++) { + mac[i] = (address >> ((MAC_ADDRESS_SIZE - 1 - i) * 8)) & 0xFF; + } + + char buffer[MAC_ADDRESS_SIZE * 3]; + format_mac_addr_upper(mac.data(), buffer); + return buffer; +} + +static bool get_bthome_value_length(uint8_t obj_type, size_t &value_length) { + switch (obj_type) { + case 0x00: // packet id + case 0x01: // battery + case 0x09: // count (uint8) + case 0x0F: // generic boolean + case 0x10: // power (bool) + case 0x11: // opening + case 0x15: // battery low + case 0x16: // battery charging + case 0x17: // carbon monoxide + case 0x18: // cold + case 0x19: // connectivity + case 0x1A: // door + case 0x1B: // garage door + case 0x1C: // gas + case 0x1D: // heat + case 0x1E: // light + case 0x1F: // lock + case 0x20: // moisture + case 0x21: // motion + case 0x22: // moving + case 0x23: // occupancy + case 0x24: // plug + case 0x25: // presence + case 0x26: // problem + case 0x27: // running + case 0x28: // safety + case 0x29: // smoke + case 0x2A: // sound + case 0x2B: // tamper + case 0x2C: // vibration + case 0x2D: // water leak + case 0x2E: // humidity (uint8) + case 0x2F: // moisture (uint8) + case 0x46: // UV index + case 0x57: // temperature (sint8) + case 0x58: // temperature (0.35C step) + case 0x59: // count (sint8) + case 0x60: // channel + value_length = 1; + return true; + case 0x02: // temperature (0.01C) + case 0x03: // humidity + case 0x06: // mass (kg) + case 0x07: // mass (lb) + case 0x08: // dewpoint + case 0x0C: // voltage (mV) + case 0x0D: // pm2.5 + case 0x0E: // pm10 + case 0x12: // CO2 + case 0x13: // TVOC + case 0x14: // moisture + case 0x3D: // count (uint16) + case 0x3F: // rotation + case 0x40: // distance (mm) + case 0x41: // distance (m) + case 0x43: // current (A) + case 0x44: // speed + case 0x45: // temperature (0.1C) + case 0x47: // volume (L) + case 0x48: // volume (mL) + case 0x49: // volume flow rate + case 0x4A: // voltage (0.1V) + case 0x51: // acceleration + case 0x52: // gyroscope + case 0x56: // conductivity + case 0x5A: // count (sint16) + case 0x5D: // current (sint16) + case 0x5E: // direction + case 0x5F: // precipitation + case 0x61: // rotational speed + case 0xF0: // button event + value_length = 2; + return true; + case 0x04: // pressure + case 0x05: // illuminance + case 0x0A: // energy + case 0x0B: // power + case 0x42: // duration + case 0x4B: // gas (uint24) + case 0xF2: // firmware version (uint24) + value_length = 3; + return true; + case 0x3E: // count (uint32) + case 0x4C: // gas (uint32) + case 0x4D: // energy (uint32) + case 0x4E: // volume (uint32) + case 0x4F: // water (uint32) + case 0x50: // timestamp + case 0x55: // volume storage + case 0x5B: // count (sint32) + case 0x5C: // power (sint32) + case 0x62: // speed (sint32) + case 0x63: // acceleration (sint32) + case 0xF1: // firmware version (uint32) + value_length = 4; + return true; + default: + return false; + } +} + +void BTHomeMiThermometer::dump_config() { + ESP_LOGCONFIG(TAG, "BTHome MiThermometer"); + ESP_LOGCONFIG(TAG, " MAC Address: %s", format_mac_address(this->address_).c_str()); + LOG_SENSOR(" ", "Temperature", this->temperature_); + LOG_SENSOR(" ", "Humidity", this->humidity_); + LOG_SENSOR(" ", "Battery Level", this->battery_level_); + LOG_SENSOR(" ", "Battery Voltage", this->battery_voltage_); + LOG_SENSOR(" ", "Signal Strength", this->signal_strength_); +} + +bool BTHomeMiThermometer::parse_device(const esp32_ble_tracker::ESPBTDevice &device) { + bool matched = false; + for (auto &service_data : device.get_service_datas()) { + if (this->handle_service_data_(service_data, device)) { + matched = true; + } + } + if (matched && this->signal_strength_ != nullptr) { + this->signal_strength_->publish_state(device.get_rssi()); + } + return matched; +} + +bool BTHomeMiThermometer::handle_service_data_(const esp32_ble_tracker::ServiceData &service_data, + const esp32_ble_tracker::ESPBTDevice &device) { + if (!service_data.uuid.contains(0xD2, 0xFC)) { + return false; + } + + const auto &data = service_data.data; + if (data.size() < 2) { + ESP_LOGVV(TAG, "BTHome data too short: %zu", data.size()); + return false; + } + + const uint8_t adv_info = data[0]; + const bool is_encrypted = adv_info & 0x01; + const bool mac_included = adv_info & 0x02; + const bool is_trigger_based = adv_info & 0x04; + const uint8_t version = (adv_info >> 5) & 0x07; + + if (version != 0x02) { + ESP_LOGVV(TAG, "Unsupported BTHome version %u", version); + return false; + } + + if (is_encrypted) { + ESP_LOGV(TAG, "Ignoring encrypted BTHome frame from %s", device.address_str().c_str()); + return false; + } + + size_t payload_index = 1; + uint64_t source_address = device.address_uint64(); + + if (mac_included) { + if (data.size() < 7) { + ESP_LOGVV(TAG, "BTHome payload missing MAC address"); + return false; + } + source_address = 0; + for (int i = 5; i >= 0; i--) { + source_address = (source_address << 8) | data[1 + i]; + } + payload_index = 7; + } + + if (source_address != this->address_) { + ESP_LOGVV(TAG, "BTHome frame from unexpected device %s", format_mac_address(source_address).c_str()); + return false; + } + + if (payload_index >= data.size()) { + ESP_LOGVV(TAG, "BTHome payload empty after header"); + return false; + } + + bool reported = false; + size_t offset = payload_index; + uint8_t last_type = 0; + + while (offset < data.size()) { + const uint8_t obj_type = data[offset++]; + size_t value_length = 0; + bool has_length_byte = obj_type == 0x53; // text objects include explicit length + + if (has_length_byte) { + if (offset >= data.size()) { + break; + } + value_length = data[offset++]; + } else { + if (!get_bthome_value_length(obj_type, value_length)) { + ESP_LOGVV(TAG, "Unknown BTHome object 0x%02X", obj_type); + break; + } + } + + if (value_length == 0) { + break; + } + + if (offset + value_length > data.size()) { + ESP_LOGVV(TAG, "BTHome object length exceeds payload"); + break; + } + + const uint8_t *value = &data[offset]; + offset += value_length; + + if (obj_type < last_type) { + ESP_LOGVV(TAG, "BTHome objects not in ascending order"); + } + last_type = obj_type; + + switch (obj_type) { + case 0x00: { // packet id + const uint8_t packet_id = value[0]; + if (this->last_packet_id_.has_value() && *this->last_packet_id_ == packet_id) { + return reported; + } + this->last_packet_id_ = packet_id; + break; + } + case 0x01: { // battery percentage + if (this->battery_level_ != nullptr) { + this->battery_level_->publish_state(value[0]); + reported = true; + } + break; + } + case 0x0C: { // battery voltage (mV) + if (this->battery_voltage_ != nullptr) { + const uint16_t raw = encode_uint16(value[1], value[0]); + this->battery_voltage_->publish_state(raw * 0.001f); + reported = true; + } + break; + } + case 0x02: { // temperature + if (this->temperature_ != nullptr) { + const int16_t raw = encode_uint16(value[1], value[0]); + this->temperature_->publish_state(raw * 0.01f); + reported = true; + } + break; + } + case 0x03: { // humidity + if (this->humidity_ != nullptr) { + const uint16_t raw = encode_uint16(value[1], value[0]); + this->humidity_->publish_state(raw * 0.01f); + reported = true; + } + break; + } + default: + break; + } + } + + if (reported) { + ESP_LOGD(TAG, "BTHome data%sfrom %s", is_trigger_based ? " (triggered) " : " ", device.address_str().c_str()); + } + + return reported; +} + +} // namespace bthome_mithermometer +} // namespace esphome + +#endif diff --git a/esphome/components/bthome_mithermometer/bthome_ble.h b/esphome/components/bthome_mithermometer/bthome_ble.h new file mode 100644 index 0000000000..3d2380b48d --- /dev/null +++ b/esphome/components/bthome_mithermometer/bthome_ble.h @@ -0,0 +1,44 @@ +#pragma once + +#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/core/component.h" + +#include + +#ifdef USE_ESP32 + +namespace esphome { +namespace bthome_mithermometer { + +class BTHomeMiThermometer : public esp32_ble_tracker::ESPBTDeviceListener, public Component { + public: + void set_address(uint64_t address) { this->address_ = address; } + + void set_temperature(sensor::Sensor *temperature) { this->temperature_ = temperature; } + void set_humidity(sensor::Sensor *humidity) { this->humidity_ = humidity; } + void set_battery_level(sensor::Sensor *battery_level) { this->battery_level_ = battery_level; } + void set_battery_voltage(sensor::Sensor *battery_voltage) { this->battery_voltage_ = battery_voltage; } + void set_signal_strength(sensor::Sensor *signal_strength) { this->signal_strength_ = signal_strength; } + + void dump_config() override; + bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override; + + protected: + bool handle_service_data_(const esp32_ble_tracker::ServiceData &service_data, + const esp32_ble_tracker::ESPBTDevice &device); + + uint64_t address_{0}; + optional last_packet_id_{}; + + sensor::Sensor *temperature_{nullptr}; + sensor::Sensor *humidity_{nullptr}; + sensor::Sensor *battery_level_{nullptr}; + sensor::Sensor *battery_voltage_{nullptr}; + sensor::Sensor *signal_strength_{nullptr}; +}; + +} // namespace bthome_mithermometer +} // namespace esphome + +#endif diff --git a/esphome/components/bthome_mithermometer/sensor.py b/esphome/components/bthome_mithermometer/sensor.py new file mode 100644 index 0000000000..9b50866db0 --- /dev/null +++ b/esphome/components/bthome_mithermometer/sensor.py @@ -0,0 +1,88 @@ +import esphome.codegen as cg +from esphome.components import sensor +import esphome.config_validation as cv +from esphome.const import ( + CONF_BATTERY_LEVEL, + CONF_BATTERY_VOLTAGE, + CONF_HUMIDITY, + CONF_ID, + CONF_SIGNAL_STRENGTH, + CONF_TEMPERATURE, + DEVICE_CLASS_BATTERY, + DEVICE_CLASS_HUMIDITY, + DEVICE_CLASS_SIGNAL_STRENGTH, + DEVICE_CLASS_TEMPERATURE, + DEVICE_CLASS_VOLTAGE, + ENTITY_CATEGORY_DIAGNOSTIC, + STATE_CLASS_MEASUREMENT, + UNIT_CELSIUS, + UNIT_DECIBEL_MILLIWATT, + UNIT_PERCENT, + UNIT_VOLT, +) + +from . import bthome_mithermometer_base_schema, setup_bthome_mithermometer + +CODEOWNERS = ["@nagyrobi"] + +DEPENDENCIES = ["esp32_ble_tracker"] + +CONFIG_SCHEMA = bthome_mithermometer_base_schema( + { + cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema( + unit_of_measurement=UNIT_CELSIUS, + accuracy_decimals=2, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_HUMIDITY): sensor.sensor_schema( + unit_of_measurement=UNIT_PERCENT, + accuracy_decimals=2, + device_class=DEVICE_CLASS_HUMIDITY, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema( + unit_of_measurement=UNIT_PERCENT, + accuracy_decimals=0, + device_class=DEVICE_CLASS_BATTERY, + state_class=STATE_CLASS_MEASUREMENT, + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, + ), + cv.Optional(CONF_BATTERY_VOLTAGE): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, + icon="mdi:battery-plus", + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, + ), + cv.Optional(CONF_SIGNAL_STRENGTH): sensor.sensor_schema( + unit_of_measurement=UNIT_DECIBEL_MILLIWATT, + accuracy_decimals=0, + device_class=DEVICE_CLASS_SIGNAL_STRENGTH, + state_class=STATE_CLASS_MEASUREMENT, + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, + ), + } +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await setup_bthome_mithermometer(var, config) + + if temp_sens := config.get(CONF_TEMPERATURE): + sens = await sensor.new_sensor(temp_sens) + cg.add(var.set_temperature(sens)) + if humi_sens := config.get(CONF_HUMIDITY): + sens = await sensor.new_sensor(humi_sens) + cg.add(var.set_humidity(sens)) + if batl_sens := config.get(CONF_BATTERY_LEVEL): + sens = await sensor.new_sensor(batl_sens) + cg.add(var.set_battery_level(sens)) + if batv_sens := config.get(CONF_BATTERY_VOLTAGE): + sens = await sensor.new_sensor(batv_sens) + cg.add(var.set_battery_voltage(sens)) + if sgnl_sens := config.get(CONF_SIGNAL_STRENGTH): + sens = await sensor.new_sensor(sgnl_sens) + cg.add(var.set_signal_strength(sens)) diff --git a/tests/components/bthome_mithermometer/common.yaml b/tests/components/bthome_mithermometer/common.yaml new file mode 100644 index 0000000000..ba94e46878 --- /dev/null +++ b/tests/components/bthome_mithermometer/common.yaml @@ -0,0 +1,15 @@ +esp32_ble_tracker: + +sensor: + - platform: bthome_mithermometer + mac_address: A4:C1:38:4E:16:78 + temperature: + name: "BTHome Temperature" + humidity: + name: "BTHome Humidity" + battery_level: + name: "BTHome Battery" + battery_voltage: + name: "BTHome Battery Voltage" + signal_strength: + name: "BTHome Signal" diff --git a/tests/components/bthome_mithermometer/test.esp32-idf.yaml b/tests/components/bthome_mithermometer/test.esp32-idf.yaml new file mode 100644 index 0000000000..7a6541ae76 --- /dev/null +++ b/tests/components/bthome_mithermometer/test.esp32-idf.yaml @@ -0,0 +1,4 @@ +packages: + ble: !include ../../test_build_components/common/ble/esp32-idf.yaml + +<<: !include common.yaml From ed435241b1e990a7f0067246e098a7c67a204704 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 11:48:37 -1000 Subject: [PATCH 074/302] [mipi_spi] Use stack buffer for hex formatting in verbose logging (#12778) --- esphome/components/mipi_spi/mipi_spi.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/esphome/components/mipi_spi/mipi_spi.h b/esphome/components/mipi_spi/mipi_spi.h index 1953aef035..7dfd5a9992 100644 --- a/esphome/components/mipi_spi/mipi_spi.h +++ b/esphome/components/mipi_spi/mipi_spi.h @@ -5,11 +5,15 @@ #include "esphome/components/spi/spi.h" #include "esphome/components/display/display.h" #include "esphome/components/display/display_color_utils.h" +#include "esphome/core/helpers.h" namespace esphome { namespace mipi_spi { constexpr static const char *const TAG = "display.mipi_spi"; + +// Maximum bytes to log for commands (truncated if larger) +static constexpr size_t MIPI_SPI_MAX_CMD_LOG_BYTES = 64; static constexpr uint8_t SW_RESET_CMD = 0x01; static constexpr uint8_t SLEEP_OUT = 0x11; static constexpr uint8_t NORON = 0x13; @@ -241,7 +245,10 @@ class MipiSpi : public display::Display, // Writes a command to the display, with the given bytes. void write_command_(uint8_t cmd, const uint8_t *bytes, size_t len) { - esph_log_v(TAG, "Command %02X, length %d, bytes %s", cmd, len, format_hex_pretty(bytes, len).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MIPI_SPI_MAX_CMD_LOG_BYTES)]; + esph_log_v(TAG, "Command %02X, length %d, bytes %s", cmd, len, format_hex_pretty_to(hex_buf, bytes, len)); +#endif if constexpr (BUS_TYPE == BUS_TYPE_QUAD) { this->enable(); this->write_cmd_addr_data(8, 0x02, 24, cmd << 8, bytes, len); From 2841b5fe44bf0aac569c140c0223e79b7271c07e Mon Sep 17 00:00:00 2001 From: Artur <130101347+aanikei@users.noreply.github.com> Date: Fri, 2 Jan 2026 04:28:10 +0000 Subject: [PATCH 075/302] [sn74hc595]: fix 'Attempted read from write-only channel' when using esp-idf framework (#12801) --- esphome/components/sn74hc595/sn74hc595.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/sn74hc595/sn74hc595.cpp b/esphome/components/sn74hc595/sn74hc595.cpp index fc47a6dc5e..a9ada432e4 100644 --- a/esphome/components/sn74hc595/sn74hc595.cpp +++ b/esphome/components/sn74hc595/sn74hc595.cpp @@ -70,7 +70,7 @@ void SN74HC595GPIOComponent::write_gpio() { void SN74HC595SPIComponent::write_gpio() { for (uint8_t &output_byte : std::ranges::reverse_view(this->output_bytes_)) { this->enable(); - this->transfer_byte(output_byte); + this->write_byte(output_byte); this->disable(); } SN74HC595Component::write_gpio(); From 7483bbd6ea67300b43302b7c05e027113dd089cd Mon Sep 17 00:00:00 2001 From: Stuart Parmenter Date: Thu, 1 Jan 2026 21:34:39 -0800 Subject: [PATCH 076/302] [display] Ensure drivers respect clipping during `fill()` (#12808) --- esphome/components/epaper_spi/epaper_spi.h | 6 ++++++ .../components/epaper_spi/epaper_spi_spectra_e6.cpp | 6 ++++++ esphome/components/ili9xxx/ili9xxx_display.cpp | 7 +++++++ esphome/components/inkplate/inkplate.cpp | 7 +++++++ esphome/components/mipi_dsi/mipi_dsi.cpp | 7 +++++++ esphome/components/mipi_rgb/mipi_rgb.cpp | 7 +++++++ esphome/components/mipi_spi/mipi_spi.h | 6 ++++++ esphome/components/pcd8544/pcd_8544.cpp | 6 ++++++ esphome/components/ssd1306_base/ssd1306_base.cpp | 6 ++++++ esphome/components/ssd1322_base/ssd1322_base.cpp | 6 ++++++ esphome/components/ssd1327_base/ssd1327_base.cpp | 6 ++++++ esphome/components/ssd1331_base/ssd1331_base.cpp | 6 ++++++ esphome/components/ssd1351_base/ssd1351_base.cpp | 6 ++++++ esphome/components/st7567_base/st7567_base.cpp | 11 ++++++++++- esphome/components/st7920/st7920.cpp | 11 ++++++++++- .../components/waveshare_epaper/waveshare_epaper.cpp | 12 ++++++++++++ 16 files changed, 114 insertions(+), 2 deletions(-) diff --git a/esphome/components/epaper_spi/epaper_spi.h b/esphome/components/epaper_spi/epaper_spi.h index 6852416cac..b587b07e8f 100644 --- a/esphome/components/epaper_spi/epaper_spi.h +++ b/esphome/components/epaper_spi/epaper_spi.h @@ -76,6 +76,12 @@ class EPaperBase : public Display, return 0; } void fill(Color color) override { + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + auto pixel_color = color_to_bit(color) ? 0xFF : 0x00; // We store 8 pixels per byte diff --git a/esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp b/esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp index d0e68595d0..be243145fc 100644 --- a/esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +++ b/esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp @@ -97,6 +97,12 @@ void EPaperSpectraE6::deep_sleep() { } void EPaperSpectraE6::fill(Color color) { + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + EPaperBase::fill(color); + return; + } + auto pixel_color = color_to_hex(color); // We store 2 pixels per byte diff --git a/esphome/components/ili9xxx/ili9xxx_display.cpp b/esphome/components/ili9xxx/ili9xxx_display.cpp index 2a3d0edca7..a3eff901d3 100644 --- a/esphome/components/ili9xxx/ili9xxx_display.cpp +++ b/esphome/components/ili9xxx/ili9xxx_display.cpp @@ -131,6 +131,13 @@ float ILI9XXXDisplay::get_setup_priority() const { return setup_priority::HARDWA void ILI9XXXDisplay::fill(Color color) { if (!this->check_buffer_()) return; + + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + uint16_t new_color = 0; this->x_low_ = 0; this->y_low_ = 0; diff --git a/esphome/components/inkplate/inkplate.cpp b/esphome/components/inkplate/inkplate.cpp index f96fb6905e..c921c643fa 100644 --- a/esphome/components/inkplate/inkplate.cpp +++ b/esphome/components/inkplate/inkplate.cpp @@ -293,6 +293,13 @@ void Inkplate::fill(Color color) { ESP_LOGV(TAG, "Fill called"); uint32_t start_time = millis(); + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + ESP_LOGV(TAG, "Fill finished (%ums)", millis() - start_time); + return; + } + if (this->greyscale_) { uint8_t fill = ((color.red * 2126 / 10000) + (color.green * 7152 / 10000) + (color.blue * 722 / 10000)) >> 5; memset(this->buffer_, (fill << 4) | fill, this->get_buffer_length_()); diff --git a/esphome/components/mipi_dsi/mipi_dsi.cpp b/esphome/components/mipi_dsi/mipi_dsi.cpp index cae8647398..7471aaa5c5 100644 --- a/esphome/components/mipi_dsi/mipi_dsi.cpp +++ b/esphome/components/mipi_dsi/mipi_dsi.cpp @@ -293,6 +293,13 @@ void MIPI_DSI::draw_pixel_at(int x, int y, Color color) { void MIPI_DSI::fill(Color color) { if (!this->check_buffer_()) return; + + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + switch (this->color_depth_) { case display::COLOR_BITNESS_565: { auto *ptr_16 = reinterpret_cast(this->buffer_); diff --git a/esphome/components/mipi_rgb/mipi_rgb.cpp b/esphome/components/mipi_rgb/mipi_rgb.cpp index d5d1caf6d2..c4485af8a7 100644 --- a/esphome/components/mipi_rgb/mipi_rgb.cpp +++ b/esphome/components/mipi_rgb/mipi_rgb.cpp @@ -300,6 +300,13 @@ void MipiRgb::draw_pixel_at(int x, int y, Color color) { void MipiRgb::fill(Color color) { if (!this->check_buffer_()) return; + + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + auto *ptr_16 = reinterpret_cast(this->buffer_); uint8_t hi_byte = static_cast(color.r & 0xF8) | (color.g >> 5); uint8_t lo_byte = static_cast((color.g & 0x1C) << 3) | (color.b >> 3); diff --git a/esphome/components/mipi_spi/mipi_spi.h b/esphome/components/mipi_spi/mipi_spi.h index 7dfd5a9992..a59cb8104b 100644 --- a/esphome/components/mipi_spi/mipi_spi.h +++ b/esphome/components/mipi_spi/mipi_spi.h @@ -569,6 +569,12 @@ class MipiSpiBuffer : public MipiSpiget_clipping().is_set()) { + display::Display::fill(color); + return; + } + this->x_low_ = 0; this->y_low_ = this->start_line_; this->x_high_ = WIDTH - 1; diff --git a/esphome/components/pcd8544/pcd_8544.cpp b/esphome/components/pcd8544/pcd_8544.cpp index f5b018b127..95d91ff18a 100644 --- a/esphome/components/pcd8544/pcd_8544.cpp +++ b/esphome/components/pcd8544/pcd_8544.cpp @@ -117,6 +117,12 @@ void PCD8544::update() { } void PCD8544::fill(Color color) { + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + uint8_t fill = color.is_on() ? 0xFF : 0x00; for (uint32_t i = 0; i < this->get_buffer_length_(); i++) this->buffer_[i] = fill; diff --git a/esphome/components/ssd1306_base/ssd1306_base.cpp b/esphome/components/ssd1306_base/ssd1306_base.cpp index 00425b853f..b0c39033e3 100644 --- a/esphome/components/ssd1306_base/ssd1306_base.cpp +++ b/esphome/components/ssd1306_base/ssd1306_base.cpp @@ -329,6 +329,12 @@ void HOT SSD1306::draw_absolute_pixel_internal(int x, int y, Color color) { } } void SSD1306::fill(Color color) { + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + uint8_t fill = color.is_on() ? 0xFF : 0x00; for (uint32_t i = 0; i < this->get_buffer_length_(); i++) this->buffer_[i] = fill; diff --git a/esphome/components/ssd1322_base/ssd1322_base.cpp b/esphome/components/ssd1322_base/ssd1322_base.cpp index eb8d87998f..23576e7b2c 100644 --- a/esphome/components/ssd1322_base/ssd1322_base.cpp +++ b/esphome/components/ssd1322_base/ssd1322_base.cpp @@ -174,6 +174,12 @@ void HOT SSD1322::draw_absolute_pixel_internal(int x, int y, Color color) { this->buffer_[pos] |= color4; } void SSD1322::fill(Color color) { + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + const uint32_t color4 = display::ColorUtil::color_to_grayscale4(color); uint8_t fill = (color4 & SSD1322_COLORMASK) | ((color4 & SSD1322_COLORMASK) << SSD1322_COLORSHIFT); for (uint32_t i = 0; i < this->get_buffer_length_(); i++) diff --git a/esphome/components/ssd1327_base/ssd1327_base.cpp b/esphome/components/ssd1327_base/ssd1327_base.cpp index 6b83ec5f9d..2498bfcd67 100644 --- a/esphome/components/ssd1327_base/ssd1327_base.cpp +++ b/esphome/components/ssd1327_base/ssd1327_base.cpp @@ -150,6 +150,12 @@ void HOT SSD1327::draw_absolute_pixel_internal(int x, int y, Color color) { this->buffer_[pos] |= color4; } void SSD1327::fill(Color color) { + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + const uint32_t color4 = display::ColorUtil::color_to_grayscale4(color); uint8_t fill = (color4 & SSD1327_COLORMASK) | ((color4 & SSD1327_COLORMASK) << SSD1327_COLORSHIFT); for (uint32_t i = 0; i < this->get_buffer_length_(); i++) diff --git a/esphome/components/ssd1331_base/ssd1331_base.cpp b/esphome/components/ssd1331_base/ssd1331_base.cpp index 8ee12387e4..a2993edef3 100644 --- a/esphome/components/ssd1331_base/ssd1331_base.cpp +++ b/esphome/components/ssd1331_base/ssd1331_base.cpp @@ -128,6 +128,12 @@ void HOT SSD1331::draw_absolute_pixel_internal(int x, int y, Color color) { this->buffer_[pos] = color565 & 0xff; } void SSD1331::fill(Color color) { + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + const uint32_t color565 = display::ColorUtil::color_to_565(color); for (uint32_t i = 0; i < this->get_buffer_length_(); i++) { if (i & 1) { diff --git a/esphome/components/ssd1351_base/ssd1351_base.cpp b/esphome/components/ssd1351_base/ssd1351_base.cpp index 09530e8a27..69bf67f476 100644 --- a/esphome/components/ssd1351_base/ssd1351_base.cpp +++ b/esphome/components/ssd1351_base/ssd1351_base.cpp @@ -160,6 +160,12 @@ void HOT SSD1351::draw_absolute_pixel_internal(int x, int y, Color color) { this->buffer_[pos] = color565 & 0xff; } void SSD1351::fill(Color color) { + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + const uint32_t color565 = display::ColorUtil::color_to_565(color); for (uint32_t i = 0; i < this->get_buffer_length_(); i++) { if (i & 1) { diff --git a/esphome/components/st7567_base/st7567_base.cpp b/esphome/components/st7567_base/st7567_base.cpp index 0afd2a70ba..8c47094b26 100644 --- a/esphome/components/st7567_base/st7567_base.cpp +++ b/esphome/components/st7567_base/st7567_base.cpp @@ -131,7 +131,16 @@ void HOT ST7567::draw_absolute_pixel_internal(int x, int y, Color color) { } } -void ST7567::fill(Color color) { memset(buffer_, color.is_on() ? 0xFF : 0x00, this->get_buffer_length_()); } +void ST7567::fill(Color color) { + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + + uint8_t fill = color.is_on() ? 0xFF : 0x00; + memset(buffer_, fill, this->get_buffer_length_()); +} void ST7567::init_reset_() { if (this->reset_pin_ != nullptr) { diff --git a/esphome/components/st7920/st7920.cpp b/esphome/components/st7920/st7920.cpp index c7ce7140e3..afd7cd61bd 100644 --- a/esphome/components/st7920/st7920.cpp +++ b/esphome/components/st7920/st7920.cpp @@ -89,7 +89,16 @@ void HOT ST7920::write_display_data() { } } -void ST7920::fill(Color color) { memset(this->buffer_, color.is_on() ? 0xFF : 0x00, this->get_buffer_length_()); } +void ST7920::fill(Color color) { + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + + uint8_t fill = color.is_on() ? 0xFF : 0x00; + memset(this->buffer_, fill, this->get_buffer_length_()); +} void ST7920::dump_config() { LOG_DISPLAY("", "ST7920", this); diff --git a/esphome/components/waveshare_epaper/waveshare_epaper.cpp b/esphome/components/waveshare_epaper/waveshare_epaper.cpp index 3510d157d6..9ab050395d 100644 --- a/esphome/components/waveshare_epaper/waveshare_epaper.cpp +++ b/esphome/components/waveshare_epaper/waveshare_epaper.cpp @@ -172,6 +172,12 @@ void WaveshareEPaperBase::update() { this->display(); } void WaveshareEPaper::fill(Color color) { + // If clipping is active, fall back to base implementation + if (this->get_clipping().is_set()) { + Display::fill(color); + return; + } + // flip logic const uint8_t fill = color.is_on() ? 0x00 : 0xFF; for (uint32_t i = 0; i < this->get_buffer_length_(); i++) @@ -234,6 +240,12 @@ uint8_t WaveshareEPaper7C::color_to_hex(Color color) { return hex_code; } void WaveshareEPaper7C::fill(Color color) { + // If clipping is active, use base class (3-bit packing is complex for partial fills) + if (this->get_clipping().is_set()) { + display::Display::fill(color); + return; + } + uint8_t pixel_color; if (color.is_on()) { pixel_color = this->color_to_hex(color); From 544aaeaa6676bb34751968dc3be63a84ebd62102 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:08:57 -1000 Subject: [PATCH 077/302] [mipi_dsi] Use stack buffer for hex formatting in very verbose logging (#12776) --- esphome/components/mipi_dsi/mipi_dsi.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/esphome/components/mipi_dsi/mipi_dsi.cpp b/esphome/components/mipi_dsi/mipi_dsi.cpp index 7471aaa5c5..18cafab684 100644 --- a/esphome/components/mipi_dsi/mipi_dsi.cpp +++ b/esphome/components/mipi_dsi/mipi_dsi.cpp @@ -1,10 +1,14 @@ #ifdef USE_ESP32_VARIANT_ESP32P4 #include #include "mipi_dsi.h" +#include "esphome/core/helpers.h" namespace esphome { namespace mipi_dsi { +// Maximum bytes to log for init commands (truncated if larger) +static constexpr size_t MIPI_DSI_MAX_CMD_LOG_BYTES = 64; + static bool notify_refresh_ready(esp_lcd_panel_handle_t panel, esp_lcd_dpi_panel_event_data_t *edata, void *user_ctx) { auto *sem = static_cast(user_ctx); BaseType_t need_yield = pdFALSE; @@ -121,8 +125,11 @@ void MIPI_DSI::setup() { } } const auto *ptr = vec.data() + index; +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + char hex_buf[format_hex_pretty_size(MIPI_DSI_MAX_CMD_LOG_BYTES)]; +#endif ESP_LOGVV(TAG, "Command %02X, length %d, byte(s) %s", cmd, num_args, - format_hex_pretty(ptr, num_args, '.', false).c_str()); + format_hex_pretty_to(hex_buf, ptr, num_args, '.')); err = esp_lcd_panel_io_tx_param(this->io_handle_, cmd, ptr, num_args); if (err != ESP_OK) { this->smark_failed(LOG_STR("lcd_panel_io_tx_param failed"), err); From 14e97642f77a71599459a2ffbbbdecdaef2ae7d7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:09:37 -1000 Subject: [PATCH 078/302] [mipi_rgb] Use stack buffer for hex formatting in init sequence logging (#12777) --- esphome/components/mipi_rgb/mipi_rgb.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/esphome/components/mipi_rgb/mipi_rgb.cpp b/esphome/components/mipi_rgb/mipi_rgb.cpp index c4485af8a7..ef96da8a1c 100644 --- a/esphome/components/mipi_rgb/mipi_rgb.cpp +++ b/esphome/components/mipi_rgb/mipi_rgb.cpp @@ -1,5 +1,6 @@ #ifdef USE_ESP32_VARIANT_ESP32S3 #include "mipi_rgb.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #include "esphome/core/hal.h" #include "esp_lcd_panel_rgb.h" @@ -8,6 +9,9 @@ namespace esphome { namespace mipi_rgb { static const uint8_t DELAY_FLAG = 0xFF; + +// Maximum bytes to log for init commands (truncated if larger) +static constexpr size_t MIPI_RGB_MAX_CMD_LOG_BYTES = 64; static constexpr uint8_t MADCTL_MY = 0x80; // Bit 7 Bottom to top static constexpr uint8_t MADCTL_MX = 0x40; // Bit 6 Right to left static constexpr uint8_t MADCTL_MV = 0x20; // Bit 5 Swap axes @@ -91,8 +95,9 @@ void MipiRgbSpi::write_init_sequence_() { delay(120); // NOLINT } const auto *ptr = vec.data() + index; + char hex_buf[format_hex_pretty_size(MIPI_RGB_MAX_CMD_LOG_BYTES)]; ESP_LOGD(TAG, "Write command %02X, length %d, byte(s) %s", cmd, num_args, - format_hex_pretty(ptr, num_args, '.', false).c_str()); + format_hex_pretty_to(hex_buf, ptr, num_args, '.')); index += num_args; this->write_command_(cmd); while (num_args-- != 0) From 09242815457f3035d69e68b59dd756f93fe6bfbd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:10:08 -1000 Subject: [PATCH 079/302] [mitsubishi] Use stack buffer for hex formatting in verbose logging (#12779) --- esphome/components/mitsubishi/mitsubishi.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/esphome/components/mitsubishi/mitsubishi.cpp b/esphome/components/mitsubishi/mitsubishi.cpp index 10ab4f3b5c..d80b7aeff5 100644 --- a/esphome/components/mitsubishi/mitsubishi.cpp +++ b/esphome/components/mitsubishi/mitsubishi.cpp @@ -1,4 +1,5 @@ #include "mitsubishi.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" namespace esphome { @@ -6,6 +7,9 @@ namespace mitsubishi { static const char *const TAG = "mitsubishi.climate"; +// IR frame size for Mitsubishi climate +static constexpr size_t MITSUBISHI_FRAME_SIZE = 18; + const uint8_t MITSUBISHI_OFF = 0x00; const uint8_t MITSUBISHI_MODE_AUTO = 0x20; @@ -388,7 +392,10 @@ bool MitsubishiClimate::on_receive(remote_base::RemoteReceiveData data) { break; } - ESP_LOGV(TAG, "Receiving: %s", format_hex_pretty(state_frame, 18).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MITSUBISHI_FRAME_SIZE)]; +#endif + ESP_LOGV(TAG, "Receiving: %s", format_hex_pretty_to(hex_buf, state_frame, MITSUBISHI_FRAME_SIZE)); this->publish_state(); return true; From b5188731f82b1000b2f385be3d37a46d7d8b2e42 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:10:45 -1000 Subject: [PATCH 080/302] [modbus] Use stack buffer for hex formatting in verbose logging (#12780) --- esphome/components/modbus/modbus.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/esphome/components/modbus/modbus.cpp b/esphome/components/modbus/modbus.cpp index 20271b4bdb..457dff4075 100644 --- a/esphome/components/modbus/modbus.cpp +++ b/esphome/components/modbus/modbus.cpp @@ -8,6 +8,9 @@ namespace modbus { static const char *const TAG = "modbus"; +// Maximum bytes to log for Modbus frames (truncated if larger) +static constexpr size_t MODBUS_MAX_LOG_BYTES = 64; + void Modbus::setup() { if (this->flow_control_pin_ != nullptr) { this->flow_control_pin_->setup(); @@ -255,7 +258,10 @@ void Modbus::send(uint8_t address, uint8_t function_code, uint16_t start_address this->flow_control_pin_->digital_write(false); waiting_for_response = address; last_send_ = millis(); - ESP_LOGV(TAG, "Modbus write: %s", format_hex_pretty(data).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MODBUS_MAX_LOG_BYTES)]; +#endif + ESP_LOGV(TAG, "Modbus write: %s", format_hex_pretty_to(hex_buf, data.data(), data.size())); } // Helper function for lambdas @@ -276,7 +282,10 @@ void Modbus::send_raw(const std::vector &payload) { if (this->flow_control_pin_ != nullptr) this->flow_control_pin_->digital_write(false); waiting_for_response = payload[0]; - ESP_LOGV(TAG, "Modbus write raw: %s", format_hex_pretty(payload).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MODBUS_MAX_LOG_BYTES)]; +#endif + ESP_LOGV(TAG, "Modbus write raw: %s", format_hex_pretty_to(hex_buf, payload.data(), payload.size())); last_send_ = millis(); } From 7df41124b287bbdf7d1791c425f3041228fa83b7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:11:53 -1000 Subject: [PATCH 081/302] [pn532_spi] Replace format_hex_pretty with stack-based format_hex_pretty_to (#12782) --- esphome/components/pn532_spi/pn532_spi.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/esphome/components/pn532_spi/pn532_spi.cpp b/esphome/components/pn532_spi/pn532_spi.cpp index 0871f7acab..118421c47f 100644 --- a/esphome/components/pn532_spi/pn532_spi.cpp +++ b/esphome/components/pn532_spi/pn532_spi.cpp @@ -1,4 +1,5 @@ #include "pn532_spi.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" // Based on: @@ -11,6 +12,9 @@ namespace pn532_spi { static const char *const TAG = "pn532_spi"; +// Maximum bytes to log in verbose hex output +static constexpr size_t PN532_MAX_LOG_BYTES = 64; + void PN532Spi::setup() { this->spi_setup(); @@ -32,7 +36,10 @@ bool PN532Spi::write_data(const std::vector &data) { delay(2); // First byte, communication mode: Write data this->write_byte(0x01); - ESP_LOGV(TAG, "Writing data: %s", format_hex_pretty(data).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(PN532_MAX_LOG_BYTES)]; +#endif + ESP_LOGV(TAG, "Writing data: %s", format_hex_pretty_to(hex_buf, sizeof(hex_buf), data.data(), data.size())); this->write_array(data.data(), data.size()); this->disable(); @@ -55,7 +62,10 @@ bool PN532Spi::read_data(std::vector &data, uint8_t len) { this->read_array(data.data(), len); this->disable(); data.insert(data.begin(), 0x01); - ESP_LOGV(TAG, "Read data: %s", format_hex_pretty(data).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(PN532_MAX_LOG_BYTES)]; +#endif + ESP_LOGV(TAG, "Read data: %s", format_hex_pretty_to(hex_buf, sizeof(hex_buf), data.data(), data.size())); return true; } @@ -73,7 +83,10 @@ bool PN532Spi::read_response(uint8_t command, std::vector &data) { std::vector header(7); this->read_array(header.data(), 7); - ESP_LOGV(TAG, "Header data: %s", format_hex_pretty(header).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(PN532_MAX_LOG_BYTES)]; +#endif + ESP_LOGV(TAG, "Header data: %s", format_hex_pretty_to(hex_buf, sizeof(hex_buf), header.data(), header.size())); if (header[0] != 0x00 && header[1] != 0x00 && header[2] != 0xFF) { // invalid packet @@ -103,7 +116,7 @@ bool PN532Spi::read_response(uint8_t command, std::vector &data) { this->read_array(data.data(), len + 1); this->disable(); - ESP_LOGV(TAG, "Response data: %s", format_hex_pretty(data).c_str()); + ESP_LOGV(TAG, "Response data: %s", format_hex_pretty_to(hex_buf, sizeof(hex_buf), data.data(), data.size())); uint8_t checksum = header[5] + header[6]; // TFI + Command response code for (int i = 0; i < len - 1; i++) { From c81ce243cc02881fbed9b553719de5554e3f8872 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:13:10 -1000 Subject: [PATCH 082/302] [qspi_dbi] Replace format_hex_pretty with stack-based format_hex_pretty_to (#12783) --- esphome/components/qspi_dbi/qspi_dbi.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/esphome/components/qspi_dbi/qspi_dbi.cpp b/esphome/components/qspi_dbi/qspi_dbi.cpp index 24b9a0ce0a..00a4a375eb 100644 --- a/esphome/components/qspi_dbi/qspi_dbi.cpp +++ b/esphome/components/qspi_dbi/qspi_dbi.cpp @@ -1,10 +1,14 @@ #if defined(USE_ESP32) && defined(USE_ESP32_VARIANT_ESP32S3) #include "qspi_dbi.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" namespace esphome { namespace qspi_dbi { +// Maximum bytes to log in verbose hex output +static constexpr size_t QSPI_DBI_MAX_LOG_BYTES = 64; + void QspiDbi::setup() { this->spi_setup(); if (this->enable_pin_ != nullptr) { @@ -174,7 +178,11 @@ void QspiDbi::write_to_display_(int x_start, int y_start, int w, int h, const ui this->disable(); } void QspiDbi::write_command_(uint8_t cmd, const uint8_t *bytes, size_t len) { - ESP_LOGV(TAG, "Command %02X, length %d, bytes %s", cmd, len, format_hex_pretty(bytes, len).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(QSPI_DBI_MAX_LOG_BYTES)]; +#endif + ESP_LOGV(TAG, "Command %02X, length %d, bytes %s", cmd, len, + format_hex_pretty_to(hex_buf, sizeof(hex_buf), bytes, len)); this->enable(); this->write_cmd_addr_data(8, 0x02, 24, cmd << 8, bytes, len); this->disable(); From 4fcd263ea85e9cade892b556f6cd00b1dbfe5597 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:16:40 -1000 Subject: [PATCH 083/302] [seeed_mr60bha2] Replace format_hex_pretty with stack-based format_hex_pretty_to (#12784) --- .../seeed_mr60bha2/seeed_mr60bha2.cpp | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp b/esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp index c815c98419..b9ce1f9151 100644 --- a/esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +++ b/esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp @@ -10,6 +10,9 @@ namespace seeed_mr60bha2 { static const char *const TAG = "seeed_mr60bha2"; +// Maximum bytes to log in verbose hex output +static constexpr size_t MR60BHA2_MAX_LOG_BYTES = 64; + // Prints the component's configuration data. dump_config() prints all of the component's configuration // items in an easy-to-read format, including the configuration key-value pairs. void MR60BHA2Component::dump_config() { @@ -110,7 +113,10 @@ bool MR60BHA2Component::validate_message_() { if (at == 7) { if (!validate_checksum(data, 7, header_checksum)) { ESP_LOGE(TAG, "HEAD_CKSUM_FRAME ERROR: 0x%02x", header_checksum); - ESP_LOGV(TAG, "GET FRAME: %s", format_hex_pretty(data, 8).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MR60BHA2_MAX_LOG_BYTES)]; +#endif + ESP_LOGV(TAG, "GET FRAME: %s", format_hex_pretty_to(hex_buf, sizeof(hex_buf), data, 8)); return false; } return true; @@ -125,14 +131,22 @@ bool MR60BHA2Component::validate_message_() { if (at == 8 + length) { if (!validate_checksum(data + 8, length, data_checksum)) { ESP_LOGE(TAG, "DATA_CKSUM_FRAME ERROR: 0x%02x", data_checksum); - ESP_LOGV(TAG, "GET FRAME: %s", format_hex_pretty(data, 8 + length).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MR60BHA2_MAX_LOG_BYTES)]; +#endif + ESP_LOGV(TAG, "GET FRAME: %s", format_hex_pretty_to(hex_buf, sizeof(hex_buf), data, 8 + length)); return false; } } const uint8_t *frame_data = data + 8; +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf1[format_hex_pretty_size(MR60BHA2_MAX_LOG_BYTES)]; + char hex_buf2[format_hex_pretty_size(MR60BHA2_MAX_LOG_BYTES)]; +#endif ESP_LOGV(TAG, "Received Frame: ID: 0x%04x, Type: 0x%04x, Data: [%s] Raw Data: [%s]", frame_id, frame_type, - format_hex_pretty(frame_data, length).c_str(), format_hex_pretty(this->rx_message_).c_str()); + format_hex_pretty_to(hex_buf1, sizeof(hex_buf1), frame_data, length), + format_hex_pretty_to(hex_buf2, sizeof(hex_buf2), this->rx_message_.data(), this->rx_message_.size())); this->process_frame_(frame_id, frame_type, data + 8, length); // Return false to reset rx buffer From e1788bba45304ba9af8e3a714cfb5cf354f70a4e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:17:22 -1000 Subject: [PATCH 084/302] [seeed_mr60fda2] Use stack-based format_hex_pretty_to for verbose logging (#12785) --- .../seeed_mr60fda2/seeed_mr60fda2.cpp | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp b/esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp index 7f8bd6a43c..b5b5b4d05a 100644 --- a/esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +++ b/esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp @@ -10,6 +10,9 @@ namespace seeed_mr60fda2 { static const char *const TAG = "seeed_mr60fda2"; +// Maximum bytes to log in verbose hex output +static constexpr size_t MR60FDA2_MAX_LOG_BYTES = 64; + // Prints the component's configuration data. dump_config() prints all of the component's configuration // items in an easy-to-read format, including the configuration key-value pairs. void MR60FDA2Component::dump_config() { @@ -202,9 +205,13 @@ void MR60FDA2Component::split_frame_(uint8_t buffer) { this->current_frame_locate_++; } else { ESP_LOGD(TAG, "HEAD_CKSUM_FRAME ERROR: 0x%02x", buffer); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char frame_buf[format_hex_pretty_size(MR60FDA2_MAX_LOG_BYTES)]; + char byte_buf[format_hex_pretty_size(1)]; +#endif ESP_LOGV(TAG, "CURRENT_FRAME: %s %s", - format_hex_pretty(this->current_frame_buf_, this->current_frame_len_).c_str(), - format_hex_pretty(&buffer, 1).c_str()); + format_hex_pretty_to(frame_buf, this->current_frame_buf_, this->current_frame_len_), + format_hex_pretty_to(byte_buf, &buffer, 1)); this->current_frame_locate_ = LOCATE_FRAME_HEADER; } break; @@ -228,9 +235,13 @@ void MR60FDA2Component::split_frame_(uint8_t buffer) { this->process_frame_(); } else { ESP_LOGD(TAG, "DATA_CKSUM_FRAME ERROR: 0x%02x", buffer); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char frame_buf[format_hex_pretty_size(MR60FDA2_MAX_LOG_BYTES)]; + char byte_buf[format_hex_pretty_size(1)]; +#endif ESP_LOGV(TAG, "GET CURRENT_FRAME: %s %s", - format_hex_pretty(this->current_frame_buf_, this->current_frame_len_).c_str(), - format_hex_pretty(&buffer, 1).c_str()); + format_hex_pretty_to(frame_buf, this->current_frame_buf_, this->current_frame_len_), + format_hex_pretty_to(byte_buf, &buffer, 1)); this->current_frame_locate_ = LOCATE_FRAME_HEADER; } @@ -328,7 +339,10 @@ void MR60FDA2Component::set_install_height(uint8_t index) { float_to_bytes(INSTALL_HEIGHT[index], &send_data[8]); send_data[12] = calculate_checksum(send_data + 8, 4); this->write_array(send_data, 13); - ESP_LOGV(TAG, "SEND INSTALL HEIGHT FRAME: %s", format_hex_pretty(send_data, 13).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(13)]; +#endif + ESP_LOGV(TAG, "SEND INSTALL HEIGHT FRAME: %s", format_hex_pretty_to(hex_buf, send_data, 13)); } void MR60FDA2Component::set_height_threshold(uint8_t index) { @@ -336,7 +350,10 @@ void MR60FDA2Component::set_height_threshold(uint8_t index) { float_to_bytes(HEIGHT_THRESHOLD[index], &send_data[8]); send_data[12] = calculate_checksum(send_data + 8, 4); this->write_array(send_data, 13); - ESP_LOGV(TAG, "SEND HEIGHT THRESHOLD: %s", format_hex_pretty(send_data, 13).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(13)]; +#endif + ESP_LOGV(TAG, "SEND HEIGHT THRESHOLD: %s", format_hex_pretty_to(hex_buf, send_data, 13)); } void MR60FDA2Component::set_sensitivity(uint8_t index) { @@ -346,19 +363,28 @@ void MR60FDA2Component::set_sensitivity(uint8_t index) { send_data[12] = calculate_checksum(send_data + 8, 4); this->write_array(send_data, 13); - ESP_LOGV(TAG, "SEND SET SENSITIVITY: %s", format_hex_pretty(send_data, 13).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(13)]; +#endif + ESP_LOGV(TAG, "SEND SET SENSITIVITY: %s", format_hex_pretty_to(hex_buf, send_data, 13)); } void MR60FDA2Component::get_radar_parameters() { uint8_t send_data[8] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x06, 0xF6}; this->write_array(send_data, 8); - ESP_LOGV(TAG, "SEND GET PARAMETERS: %s", format_hex_pretty(send_data, 8).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(8)]; +#endif + ESP_LOGV(TAG, "SEND GET PARAMETERS: %s", format_hex_pretty_to(hex_buf, send_data, 8)); } void MR60FDA2Component::factory_reset() { uint8_t send_data[8] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xCF}; this->write_array(send_data, 8); - ESP_LOGV(TAG, "SEND RESET: %s", format_hex_pretty(send_data, 8).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(8)]; +#endif + ESP_LOGV(TAG, "SEND RESET: %s", format_hex_pretty_to(hex_buf, send_data, 8)); this->get_radar_parameters(); } From 0049c8ad38be45e0b04459e7098effaa3fd92bc4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:17:51 -1000 Subject: [PATCH 085/302] [zwave_proxy] Use stack-based format_hex_pretty_to for very verbose logging (#12786) --- esphome/components/zwave_proxy/zwave_proxy.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/esphome/components/zwave_proxy/zwave_proxy.cpp b/esphome/components/zwave_proxy/zwave_proxy.cpp index e4efa55e25..c1fde4de6b 100644 --- a/esphome/components/zwave_proxy/zwave_proxy.cpp +++ b/esphome/components/zwave_proxy/zwave_proxy.cpp @@ -12,6 +12,9 @@ namespace esphome::zwave_proxy { static const char *const TAG = "zwave_proxy"; +// Maximum bytes to log in very verbose hex output (168 * 3 = 504, under TX buffer size of 512) +static constexpr size_t ZWAVE_MAX_LOG_BYTES = 168; + static constexpr uint8_t ZWAVE_COMMAND_GET_NETWORK_IDS = 0x20; // GET_NETWORK_IDS response: [SOF][LENGTH][TYPE][CMD][HOME_ID(4)][NODE_ID][...] static constexpr uint8_t ZWAVE_COMMAND_TYPE_RESPONSE = 0x01; // Response type field value @@ -179,7 +182,10 @@ void ZWaveProxy::send_frame(const uint8_t *data, size_t length) { ESP_LOGV(TAG, "Skipping sending duplicate response: 0x%02X", data[0]); return; } - ESP_LOGVV(TAG, "Sending: %s", format_hex_pretty(data, length).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + char hex_buf[format_hex_pretty_size(ZWAVE_MAX_LOG_BYTES)]; +#endif + ESP_LOGVV(TAG, "Sending: %s", format_hex_pretty_to(hex_buf, data, length)); this->write_array(data, length); } @@ -252,7 +258,10 @@ bool ZWaveProxy::parse_byte_(uint8_t byte) { this->parsing_state_ = ZWAVE_PARSING_STATE_SEND_NAK; } else { this->parsing_state_ = ZWAVE_PARSING_STATE_SEND_ACK; - ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(this->buffer_.data(), this->buffer_index_).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + char hex_buf[format_hex_pretty_size(ZWAVE_MAX_LOG_BYTES)]; +#endif + ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty_to(hex_buf, this->buffer_.data(), this->buffer_index_)); frame_completed = true; } this->response_handler_(); From c6f3860f90e655fbd1518b4a6cf558b8a4a62a57 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:18:23 -1000 Subject: [PATCH 086/302] [ee895] Use stack-based format_hex_to for verbose logging (#12789) --- esphome/components/ee895/ee895.cpp | 8 +++++++- esphome/core/helpers.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/esphome/components/ee895/ee895.cpp b/esphome/components/ee895/ee895.cpp index c6eaf4e728..602e31db14 100644 --- a/esphome/components/ee895/ee895.cpp +++ b/esphome/components/ee895/ee895.cpp @@ -7,6 +7,9 @@ namespace ee895 { static const char *const TAG = "ee895"; +// Serial number is 16 bytes +static constexpr size_t EE895_SERIAL_NUMBER_SIZE = 16; + static const uint16_t CRC16_ONEWIRE_START = 0xFFFF; static const uint8_t FUNCTION_CODE_READ = 0x03; static const uint16_t SERIAL_NUMBER = 0x0000; @@ -26,7 +29,10 @@ void EE895Component::setup() { this->mark_failed(); return; } - ESP_LOGV(TAG, " Serial Number: 0x%s", format_hex(serial_number + 2, 16).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char serial_hex[format_hex_size(EE895_SERIAL_NUMBER_SIZE)]; +#endif + ESP_LOGV(TAG, " Serial Number: 0x%s", format_hex_to(serial_hex, serial_number + 2, EE895_SERIAL_NUMBER_SIZE)); } void EE895Component::dump_config() { diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 37534849d0..ac7a96a8c8 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -728,6 +728,9 @@ inline char *format_hex_to(char (&buffer)[N], T val) { return format_hex_to(buffer, reinterpret_cast(&val), sizeof(T)); } +/// Calculate buffer size needed for format_hex_to: "XXXXXXXX...\0" = bytes * 2 + 1 +constexpr size_t format_hex_size(size_t byte_count) { return byte_count * 2 + 1; } + /// Calculate buffer size needed for format_hex_pretty_to with separator: "XX:XX:...:XX\0" constexpr size_t format_hex_pretty_size(size_t byte_count) { return byte_count * 3; } From 71c3d4ca27e00bffc9ce4349dd6b567b8c7f3186 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:19:20 -1000 Subject: [PATCH 087/302] [mopeka_std_check] Use stack-based format_hex_pretty_to for very verbose logging (#12790) --- esphome/components/mopeka_std_check/mopeka_std_check.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/esphome/components/mopeka_std_check/mopeka_std_check.cpp b/esphome/components/mopeka_std_check/mopeka_std_check.cpp index 0d8340f95f..986a9a9fdc 100644 --- a/esphome/components/mopeka_std_check/mopeka_std_check.cpp +++ b/esphome/components/mopeka_std_check/mopeka_std_check.cpp @@ -13,6 +13,9 @@ static const uint16_t SERVICE_UUID = 0xADA0; static const uint8_t MANUFACTURER_DATA_LENGTH = 23; static const uint16_t MANUFACTURER_ID = 0x000D; +// Maximum bytes to log in very verbose hex output +static constexpr size_t MOPEKA_MAX_LOG_BYTES = 32; + void MopekaStdCheck::dump_config() { ESP_LOGCONFIG(TAG, "Mopeka Std Check"); ESP_LOGCONFIG(TAG, " Propane Butane mix: %.0f%%", this->propane_butane_mix_ * 100); @@ -60,7 +63,11 @@ bool MopekaStdCheck::parse_device(const esp32_ble_tracker::ESPBTDevice &device) const auto &manu_data = manu_datas[0]; - ESP_LOGVV(TAG, "[%s] Manufacturer data: %s", device.address_str().c_str(), format_hex_pretty(manu_data.data).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + char hex_buf[format_hex_pretty_size(MOPEKA_MAX_LOG_BYTES)]; +#endif + ESP_LOGVV(TAG, "[%s] Manufacturer data: %s", device.address_str().c_str(), + format_hex_pretty_to(hex_buf, manu_data.data.data(), manu_data.data.size())); if (manu_data.data.size() != MANUFACTURER_DATA_LENGTH) { ESP_LOGE(TAG, "[%s] Unexpected manu_data size (%d)", device.address_str().c_str(), manu_data.data.size()); From bcc6bbbf5f0bc7671f36d62d98da3a199c08becd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:19:49 -1000 Subject: [PATCH 088/302] [espnow] Use stack buffer for hex formatting in verbose logging (#12738) --- esphome/components/espnow/espnow_component.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esphome/components/espnow/espnow_component.cpp b/esphome/components/espnow/espnow_component.cpp index bc05833709..16e2331937 100644 --- a/esphome/components/espnow/espnow_component.cpp +++ b/esphome/components/espnow/espnow_component.cpp @@ -6,6 +6,7 @@ #include "esphome/core/application.h" #include "esphome/core/defines.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #include @@ -299,9 +300,10 @@ void ESPNowComponent::loop() { // Intentionally left as if instead of else in case the peer is added above if (esp_now_is_peer_exist(info.src_addr)) { #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(ESP_NOW_MAX_DATA_LEN)]; ESP_LOGV(TAG, "<<< [%s -> %s] %s", format_mac_address_pretty(info.src_addr).c_str(), format_mac_address_pretty(info.des_addr).c_str(), - format_hex_pretty(packet->packet_.receive.data, packet->packet_.receive.size).c_str()); + format_hex_pretty_to(hex_buf, packet->packet_.receive.data, packet->packet_.receive.size)); #endif if (memcmp(info.des_addr, ESPNOW_BROADCAST_ADDR, ESP_NOW_ETH_ALEN) == 0) { for (auto *handler : this->broadcasted_handlers_) { From 1cc18055ef7903620933b9e3a18a4227fc3f697b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:20:24 -1000 Subject: [PATCH 089/302] [i2c] Use stack buffer for hex formatting in verbose logging (#12739) --- esphome/components/i2c/i2c_bus_arduino.cpp | 8 +++++++- esphome/components/i2c/i2c_bus_esp_idf.cpp | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/esphome/components/i2c/i2c_bus_arduino.cpp b/esphome/components/i2c/i2c_bus_arduino.cpp index 1579020c9b..e728830147 100644 --- a/esphome/components/i2c/i2c_bus_arduino.cpp +++ b/esphome/components/i2c/i2c_bus_arduino.cpp @@ -12,6 +12,9 @@ namespace i2c { static const char *const TAG = "i2c.arduino"; +// Maximum bytes to log in hex format (truncates larger transfers) +static constexpr size_t I2C_MAX_LOG_BYTES = 32; + void ArduinoI2CBus::setup() { recover_(); @@ -107,7 +110,10 @@ ErrorCode ArduinoI2CBus::write_readv(uint8_t address, const uint8_t *write_buffe return ERROR_NOT_INITIALIZED; } - ESP_LOGV(TAG, "0x%02X TX %s", address, format_hex_pretty(write_buffer, write_count).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(I2C_MAX_LOG_BYTES)]; + ESP_LOGV(TAG, "0x%02X TX %s", address, format_hex_pretty_to(hex_buf, write_buffer, write_count)); +#endif uint8_t status = 0; if (write_count != 0 || read_count == 0) { diff --git a/esphome/components/i2c/i2c_bus_esp_idf.cpp b/esphome/components/i2c/i2c_bus_esp_idf.cpp index 486dc0b7d8..191c849aa3 100644 --- a/esphome/components/i2c/i2c_bus_esp_idf.cpp +++ b/esphome/components/i2c/i2c_bus_esp_idf.cpp @@ -15,6 +15,9 @@ namespace i2c { static const char *const TAG = "i2c.idf"; +// Maximum bytes to log in hex format (truncates larger transfers) +static constexpr size_t I2C_MAX_LOG_BYTES = 32; + void IDFI2CBus::setup() { static i2c_port_t next_hp_port = I2C_NUM_0; #if SOC_LP_I2C_SUPPORTED @@ -147,7 +150,10 @@ ErrorCode IDFI2CBus::write_readv(uint8_t address, const uint8_t *write_buffer, s jobs[num_jobs++].write.total_bytes = 1; } else { if (write_count != 0) { - ESP_LOGV(TAG, "0x%02X TX %s", address, format_hex_pretty(write_buffer, write_count).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(I2C_MAX_LOG_BYTES)]; + ESP_LOGV(TAG, "0x%02X TX %s", address, format_hex_pretty_to(hex_buf, write_buffer, write_count)); +#endif jobs[num_jobs++].command = I2C_MASTER_CMD_START; jobs[num_jobs].command = I2C_MASTER_CMD_WRITE; jobs[num_jobs].write.ack_check = true; From 69ec311d212a6d19d654cb2a017385b3cdf8d74b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:20:58 -1000 Subject: [PATCH 090/302] [hlk_fm22x] Use stack buffer for hex formatting in verbose logging (#12740) --- esphome/components/hlk_fm22x/hlk_fm22x.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/esphome/components/hlk_fm22x/hlk_fm22x.cpp b/esphome/components/hlk_fm22x/hlk_fm22x.cpp index ab15a2340d..c0f14c7105 100644 --- a/esphome/components/hlk_fm22x/hlk_fm22x.cpp +++ b/esphome/components/hlk_fm22x/hlk_fm22x.cpp @@ -8,6 +8,9 @@ namespace esphome::hlk_fm22x { static const char *const TAG = "hlk_fm22x"; +// Maximum response size is 36 bytes (VERIFY reply: face_id + 32-byte name) +static constexpr size_t HLK_FM22X_MAX_RESPONSE_SIZE = 36; + void HlkFm22xComponent::setup() { ESP_LOGCONFIG(TAG, "Setting up HLK-FM22X..."); this->set_enrolling_(false); @@ -142,7 +145,10 @@ void HlkFm22xComponent::recv_command_() { data.push_back(byte); } - ESP_LOGV(TAG, "Recv type: 0x%.2X, data: %s", response_type, format_hex_pretty(data).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(HLK_FM22X_MAX_RESPONSE_SIZE)]; + ESP_LOGV(TAG, "Recv type: 0x%.2X, data: %s", response_type, format_hex_pretty_to(hex_buf, data.data(), data.size())); +#endif byte = this->read(); if (byte != checksum) { From 2e8baa04936cd08f6a963f6f254a0d8506618986 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:21:33 -1000 Subject: [PATCH 091/302] [esp32_ble_tracker] Use stack buffer for hex formatting in very verbose logging (#12741) --- .../esp32_ble_tracker/esp32_ble_tracker.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp index 47da2e3570..63675ec377 100644 --- a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +++ b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp @@ -37,6 +37,9 @@ namespace esphome::esp32_ble_tracker { static const char *const TAG = "esp32_ble_tracker"; +// BLE advertisement max: 31 bytes adv data + 31 bytes scan response +static constexpr size_t BLE_ADV_MAX_LOG_BYTES = 62; + ESP32BLETracker *global_esp32_ble_tracker = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) const char *client_state_to_string(ClientState state) { @@ -445,6 +448,7 @@ void ESPBTDevice::parse_scan_rst(const BLEScanResult &scan_result) { uuid.to_str(uuid_buf); ESP_LOGVV(TAG, " Service UUID: %s", uuid_buf); } + char hex_buf[format_hex_pretty_size(BLE_ADV_MAX_LOG_BYTES)]; for (auto &data : this->manufacturer_datas_) { auto ibeacon = ESPBLEiBeacon::from_manufacturer_data(data); if (ibeacon.has_value()) { @@ -458,7 +462,8 @@ void ESPBTDevice::parse_scan_rst(const BLEScanResult &scan_result) { } else { char uuid_buf[esp32_ble::UUID_STR_LEN]; data.uuid.to_str(uuid_buf); - ESP_LOGVV(TAG, " Manufacturer ID: %s, data: %s", uuid_buf, format_hex_pretty(data.data).c_str()); + ESP_LOGVV(TAG, " Manufacturer ID: %s, data: %s", uuid_buf, + format_hex_pretty_to(hex_buf, data.data.data(), data.data.size())); } } for (auto &data : this->service_datas_) { @@ -466,11 +471,11 @@ void ESPBTDevice::parse_scan_rst(const BLEScanResult &scan_result) { char uuid_buf[esp32_ble::UUID_STR_LEN]; data.uuid.to_str(uuid_buf); ESP_LOGVV(TAG, " UUID: %s", uuid_buf); - ESP_LOGVV(TAG, " Data: %s", format_hex_pretty(data.data).c_str()); + ESP_LOGVV(TAG, " Data: %s", format_hex_pretty_to(hex_buf, data.data.data(), data.data.size())); } ESP_LOGVV(TAG, " Adv data: %s", - format_hex_pretty(scan_result.ble_adv, scan_result.adv_data_len + scan_result.scan_rsp_len).c_str()); + format_hex_pretty_to(hex_buf, scan_result.ble_adv, scan_result.adv_data_len + scan_result.scan_rsp_len)); #endif } From 7702a9ae8552eb9bdfbbb00f6ba63a2c6e20a5d9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:22:19 -1000 Subject: [PATCH 092/302] [ethernet] Use stack buffer for hex formatting in very verbose logging (#12742) --- esphome/components/ethernet/ethernet_component.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/esphome/components/ethernet/ethernet_component.cpp b/esphome/components/ethernet/ethernet_component.cpp index 114000401f..af4f652d8b 100644 --- a/esphome/components/ethernet/ethernet_component.cpp +++ b/esphome/components/ethernet/ethernet_component.cpp @@ -1,5 +1,6 @@ #include "ethernet_component.h" #include "esphome/core/application.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #include "esphome/core/util.h" @@ -39,6 +40,9 @@ namespace ethernet { static const char *const TAG = "ethernet"; +// PHY register size for hex logging +static constexpr size_t PHY_REG_SIZE = 2; + EthernetComponent *global_eth_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) void EthernetComponent::log_error_and_mark_failed_(esp_err_t err, const char *message) { @@ -773,7 +777,10 @@ void EthernetComponent::ksz8081_set_clock_reference_(esp_eth_mac_t *mac) { uint32_t phy_control_2; err = mac->read_phy_reg(mac, this->phy_addr_, KSZ80XX_PC2R_REG_ADDR, &(phy_control_2)); ESPHL_ERROR_CHECK(err, "Read PHY Control 2 failed"); - ESP_LOGVV(TAG, "KSZ8081 PHY Control 2: %s", format_hex_pretty((u_int8_t *) &phy_control_2, 2).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + char hex_buf[format_hex_pretty_size(PHY_REG_SIZE)]; +#endif + ESP_LOGVV(TAG, "KSZ8081 PHY Control 2: %s", format_hex_pretty_to(hex_buf, (uint8_t *) &phy_control_2, PHY_REG_SIZE)); /* * Bit 7 is `RMII Reference Clock Select`. Default is `0`. @@ -790,7 +797,8 @@ void EthernetComponent::ksz8081_set_clock_reference_(esp_eth_mac_t *mac) { ESPHL_ERROR_CHECK(err, "Write PHY Control 2 failed"); err = mac->read_phy_reg(mac, this->phy_addr_, KSZ80XX_PC2R_REG_ADDR, &(phy_control_2)); ESPHL_ERROR_CHECK(err, "Read PHY Control 2 failed"); - ESP_LOGVV(TAG, "KSZ8081 PHY Control 2: %s", format_hex_pretty((u_int8_t *) &phy_control_2, 2).c_str()); + ESP_LOGVV(TAG, "KSZ8081 PHY Control 2: %s", + format_hex_pretty_to(hex_buf, (uint8_t *) &phy_control_2, PHY_REG_SIZE)); } } #endif // USE_ETHERNET_KSZ8081 From 3a4cca002735c75f38252b40ade21e464f71235d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:22:48 -1000 Subject: [PATCH 093/302] [ble_client] Use stack buffer for hex formatting in very verbose logging (#12744) --- esphome/components/ble_client/automation.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/esphome/components/ble_client/automation.h b/esphome/components/ble_client/automation.h index ccda894509..f9f613ae76 100644 --- a/esphome/components/ble_client/automation.h +++ b/esphome/components/ble_client/automation.h @@ -7,8 +7,12 @@ #include "esphome/core/automation.h" #include "esphome/components/ble_client/ble_client.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" +// Maximum bytes to log in hex format for BLE writes (many logging buffers are 256 chars) +static constexpr size_t BLE_WRITE_MAX_LOG_BYTES = 64; + namespace esphome::ble_client { // placeholder class for static TAG . @@ -151,7 +155,10 @@ template class BLEClientWriteAction : public Action, publ esph_log_w(Automation::TAG, "Cannot write to BLE characteristic - not connected"); return false; } - esph_log_vv(Automation::TAG, "Will write %d bytes: %s", len, format_hex_pretty(data, len).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + char hex_buf[format_hex_pretty_size(BLE_WRITE_MAX_LOG_BYTES)]; + esph_log_vv(Automation::TAG, "Will write %d bytes: %s", len, format_hex_pretty_to(hex_buf, data, len)); +#endif esp_err_t err = esp_ble_gattc_write_char(this->parent()->get_gattc_if(), this->parent()->get_conn_id(), this->char_handle_, len, const_cast(data), this->write_type_, ESP_GATT_AUTH_REQ_NONE); From ebfa0149cc343131c86fea0ffde11c3542fd3e72 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:23:37 -1000 Subject: [PATCH 094/302] [light] Use StringRef to avoid allocation in JSON effect name serialization (#12758) --- esphome/components/light/light_json_schema.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/light/light_json_schema.cpp b/esphome/components/light/light_json_schema.cpp index 3365d1f417..7679002e74 100644 --- a/esphome/components/light/light_json_schema.cpp +++ b/esphome/components/light/light_json_schema.cpp @@ -36,7 +36,7 @@ static const char *get_color_mode_json_str(ColorMode mode) { void LightJSONSchema::dump_json(LightState &state, JsonObject root) { // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson if (state.supports_effects()) { - root[ESPHOME_F("effect")] = state.get_effect_name(); + root[ESPHOME_F("effect")] = state.get_effect_name_ref(); root[ESPHOME_F("effect_index")] = state.get_current_effect_index(); root[ESPHOME_F("effect_count")] = state.get_effect_count(); } From a828abf53dcf5b731eecf776451c40f93e68e8e0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:24:31 -1000 Subject: [PATCH 095/302] [ota] Remove MD5 authentication support (#12707) --- esphome/components/esphome/ota/__init__.py | 19 +-- .../components/esphome/ota/ota_esphome.cpp | 150 +++--------------- esphome/components/esphome/ota/ota_esphome.h | 2 +- esphome/core/defines.h | 3 - 4 files changed, 24 insertions(+), 150 deletions(-) diff --git a/esphome/components/esphome/ota/__init__.py b/esphome/components/esphome/ota/__init__.py index e56e85b231..2f637d714d 100644 --- a/esphome/components/esphome/ota/__init__.py +++ b/esphome/components/esphome/ota/__init__.py @@ -16,7 +16,7 @@ from esphome.const import ( CONF_SAFE_MODE, CONF_VERSION, ) -from esphome.core import CORE, coroutine_with_priority +from esphome.core import coroutine_with_priority from esphome.coroutine import CoroPriority import esphome.final_validate as fv from esphome.types import ConfigType @@ -28,17 +28,7 @@ CODEOWNERS = ["@esphome/core"] DEPENDENCIES = ["network"] -def supports_sha256() -> bool: - """Check if the current platform supports SHA256 for OTA authentication.""" - return bool(CORE.is_esp32 or CORE.is_esp8266 or CORE.is_rp2040 or CORE.is_libretiny) - - -def AUTO_LOAD() -> list[str]: - """Conditionally auto-load sha256 only on platforms that support it.""" - base_components = ["md5", "socket"] - if supports_sha256(): - return base_components + ["sha256"] - return base_components +AUTO_LOAD = ["sha256", "socket"] esphome = cg.esphome_ns.namespace("esphome") @@ -155,11 +145,6 @@ async def to_code(config: ConfigType) -> None: if config.get(CONF_PASSWORD): cg.add(var.set_auth_password(config[CONF_PASSWORD])) cg.add_define("USE_OTA_PASSWORD") - # Only include hash algorithms when password is configured - cg.add_define("USE_OTA_MD5") - # Only include SHA256 support on platforms that have it - if supports_sha256(): - cg.add_define("USE_OTA_SHA256") cg.add_define("USE_OTA_VERSION", config[CONF_VERSION]) await cg.register_component(var, config) diff --git a/esphome/components/esphome/ota/ota_esphome.cpp b/esphome/components/esphome/ota/ota_esphome.cpp index 98569c96cb..16d7089f02 100644 --- a/esphome/components/esphome/ota/ota_esphome.cpp +++ b/esphome/components/esphome/ota/ota_esphome.cpp @@ -1,13 +1,8 @@ #include "ota_esphome.h" #ifdef USE_OTA #ifdef USE_OTA_PASSWORD -#ifdef USE_OTA_MD5 -#include "esphome/components/md5/md5.h" -#endif -#ifdef USE_OTA_SHA256 #include "esphome/components/sha256/sha256.h" #endif -#endif #include "esphome/components/network/util.h" #include "esphome/components/ota/ota_backend.h" #include "esphome/components/ota/ota_backend_esp8266.h" @@ -31,15 +26,6 @@ static constexpr size_t OTA_BUFFER_SIZE = 1024; // buffer size static constexpr uint32_t OTA_SOCKET_TIMEOUT_HANDSHAKE = 20000; // milliseconds for initial handshake static constexpr uint32_t OTA_SOCKET_TIMEOUT_DATA = 90000; // milliseconds for data transfer -#ifdef USE_OTA_PASSWORD -#ifdef USE_OTA_MD5 -static constexpr size_t MD5_HEX_SIZE = 32; // MD5 hash as hex string (16 bytes * 2) -#endif -#ifdef USE_OTA_SHA256 -static constexpr size_t SHA256_HEX_SIZE = 64; // SHA256 hash as hex string (32 bytes * 2) -#endif -#endif // USE_OTA_PASSWORD - void ESPHomeOTAComponent::setup() { this->server_ = socket::socket_ip_loop_monitored(SOCK_STREAM, 0); // monitored for incoming connections if (this->server_ == nullptr) { @@ -108,15 +94,7 @@ void ESPHomeOTAComponent::loop() { } static const uint8_t FEATURE_SUPPORTS_COMPRESSION = 0x01; -#ifdef USE_OTA_SHA256 static const uint8_t FEATURE_SUPPORTS_SHA256_AUTH = 0x02; -#endif - -// Temporary flag to allow MD5 downgrade for ~3 versions (until 2026.1.0) -// This allows users to downgrade via OTA if they encounter issues after updating. -// Without this, users would need to do a serial flash to downgrade. -// TODO: Remove this flag and all associated code in 2026.1.0 -#define ALLOW_OTA_DOWNGRADE_MD5 void ESPHomeOTAComponent::handle_handshake_() { /// Handle the OTA handshake and authentication. @@ -547,26 +525,8 @@ void ESPHomeOTAComponent::yield_and_feed_watchdog_() { void ESPHomeOTAComponent::log_auth_warning_(const LogString *msg) { ESP_LOGW(TAG, "Auth: %s", LOG_STR_ARG(msg)); } bool ESPHomeOTAComponent::select_auth_type_() { -#ifdef USE_OTA_SHA256 bool client_supports_sha256 = (this->ota_features_ & FEATURE_SUPPORTS_SHA256_AUTH) != 0; -#ifdef ALLOW_OTA_DOWNGRADE_MD5 - // Allow fallback to MD5 if client doesn't support SHA256 - if (client_supports_sha256) { - this->auth_type_ = ota::OTA_RESPONSE_REQUEST_SHA256_AUTH; - return true; - } -#ifdef USE_OTA_MD5 - this->log_auth_warning_(LOG_STR("Using deprecated MD5")); - this->auth_type_ = ota::OTA_RESPONSE_REQUEST_AUTH; - return true; -#else - this->log_auth_warning_(LOG_STR("SHA256 required")); - this->send_error_and_cleanup_(ota::OTA_RESPONSE_ERROR_AUTH_INVALID); - return false; -#endif // USE_OTA_MD5 - -#else // !ALLOW_OTA_DOWNGRADE_MD5 // Require SHA256 if (!client_supports_sha256) { this->log_auth_warning_(LOG_STR("SHA256 required")); @@ -575,20 +535,6 @@ bool ESPHomeOTAComponent::select_auth_type_() { } this->auth_type_ = ota::OTA_RESPONSE_REQUEST_SHA256_AUTH; return true; -#endif // ALLOW_OTA_DOWNGRADE_MD5 - -#else // !USE_OTA_SHA256 -#ifdef USE_OTA_MD5 - // Only MD5 available - this->auth_type_ = ota::OTA_RESPONSE_REQUEST_AUTH; - return true; -#else - // No auth methods available - this->log_auth_warning_(LOG_STR("No auth methods available")); - this->send_error_and_cleanup_(ota::OTA_RESPONSE_ERROR_AUTH_INVALID); - return false; -#endif // USE_OTA_MD5 -#endif // USE_OTA_SHA256 } bool ESPHomeOTAComponent::handle_auth_send_() { @@ -612,31 +558,12 @@ bool ESPHomeOTAComponent::handle_auth_send_() { // [1+hex_size...1+2*hex_size-1]: cnonce (hex_size bytes) - client's nonce // [1+2*hex_size...1+3*hex_size-1]: response (hex_size bytes) - client's hash - // Declare both hash objects in same stack frame, use pointer to select. - // NOTE: Both objects are declared here even though only one is used. This is REQUIRED for ESP32-S3 - // hardware SHA acceleration - the object must exist in this stack frame for all operations. - // Do NOT try to "optimize" by creating the object inside the if block, as it would go out of scope. -#ifdef USE_OTA_SHA256 - sha256::SHA256 sha_hasher; -#endif -#ifdef USE_OTA_MD5 - md5::MD5Digest md5_hasher; -#endif - HashBase *hasher = nullptr; + // CRITICAL ESP32-S3 HARDWARE SHA ACCELERATION: Hash object must stay in same stack frame + // (no passing to other functions). All hash operations must happen in this function. + sha256::SHA256 hasher; -#ifdef USE_OTA_SHA256 - if (this->auth_type_ == ota::OTA_RESPONSE_REQUEST_SHA256_AUTH) { - hasher = &sha_hasher; - } -#endif -#ifdef USE_OTA_MD5 - if (this->auth_type_ == ota::OTA_RESPONSE_REQUEST_AUTH) { - hasher = &md5_hasher; - } -#endif - - const size_t hex_size = hasher->get_size() * 2; - const size_t nonce_len = hasher->get_size() / 4; + const size_t hex_size = hasher.get_size() * 2; + const size_t nonce_len = hasher.get_size() / 4; const size_t auth_buf_size = 1 + 3 * hex_size; this->auth_buf_ = std::make_unique(auth_buf_size); this->auth_buf_pos_ = 0; @@ -648,17 +575,17 @@ bool ESPHomeOTAComponent::handle_auth_send_() { return false; } - hasher->init(); - hasher->add(buf, nonce_len); - hasher->calculate(); + hasher.init(); + hasher.add(buf, nonce_len); + hasher.calculate(); this->auth_buf_[0] = this->auth_type_; - hasher->get_hex(buf); + hasher.get_hex(buf); ESP_LOGV(TAG, "Auth: Nonce is %.*s", hex_size, buf); } // Try to write auth_type + nonce - size_t hex_size = this->get_auth_hex_size_(); + constexpr size_t hex_size = SHA256_HEX_SIZE; const size_t to_write = 1 + hex_size; size_t remaining = to_write - this->auth_buf_pos_; @@ -680,7 +607,7 @@ bool ESPHomeOTAComponent::handle_auth_send_() { } bool ESPHomeOTAComponent::handle_auth_read_() { - size_t hex_size = this->get_auth_hex_size_(); + constexpr size_t hex_size = SHA256_HEX_SIZE; const size_t to_read = hex_size * 2; // CNonce + Response // Try to read remaining bytes (CNonce + Response) @@ -705,45 +632,25 @@ bool ESPHomeOTAComponent::handle_auth_read_() { const char *cnonce = nonce + hex_size; const char *response = cnonce + hex_size; - // CRITICAL ESP32-S3: Hash objects must stay in same stack frame (no passing to other functions). - // Declare both hash objects in same stack frame, use pointer to select. - // NOTE: Both objects are declared here even though only one is used. This is REQUIRED for ESP32-S3 - // hardware SHA acceleration - the object must exist in this stack frame for all operations. - // Do NOT try to "optimize" by creating the object inside the if block, as it would go out of scope. -#ifdef USE_OTA_SHA256 - sha256::SHA256 sha_hasher; -#endif -#ifdef USE_OTA_MD5 - md5::MD5Digest md5_hasher; -#endif - HashBase *hasher = nullptr; + // CRITICAL ESP32-S3 HARDWARE SHA ACCELERATION: Hash object must stay in same stack frame + // (no passing to other functions). All hash operations must happen in this function. + sha256::SHA256 hasher; -#ifdef USE_OTA_SHA256 - if (this->auth_type_ == ota::OTA_RESPONSE_REQUEST_SHA256_AUTH) { - hasher = &sha_hasher; - } -#endif -#ifdef USE_OTA_MD5 - if (this->auth_type_ == ota::OTA_RESPONSE_REQUEST_AUTH) { - hasher = &md5_hasher; - } -#endif - - hasher->init(); - hasher->add(this->password_.c_str(), this->password_.length()); - hasher->add(nonce, hex_size * 2); // Add both nonce and cnonce (contiguous in buffer) - hasher->calculate(); + hasher.init(); + hasher.add(this->password_.c_str(), this->password_.length()); + hasher.add(nonce, hex_size * 2); // Add both nonce and cnonce (contiguous in buffer) + hasher.calculate(); ESP_LOGV(TAG, "Auth: CNonce is %.*s", hex_size, cnonce); #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE - char computed_hash[65]; // Buffer for hex-encoded hash (max expected length + null terminator) - hasher->get_hex(computed_hash); + char computed_hash[SHA256_HEX_SIZE + 1]; // Buffer for hex-encoded hash (max expected length + null terminator) + hasher.get_hex(computed_hash); ESP_LOGV(TAG, "Auth: Result is %.*s", hex_size, computed_hash); #endif ESP_LOGV(TAG, "Auth: Response is %.*s", hex_size, response); // Compare response - bool matches = hasher->equals_hex(response); + bool matches = hasher.equals_hex(response); if (!matches) { this->log_auth_warning_(LOG_STR("Password mismatch")); @@ -757,21 +664,6 @@ bool ESPHomeOTAComponent::handle_auth_read_() { return true; } -size_t ESPHomeOTAComponent::get_auth_hex_size_() const { -#ifdef USE_OTA_SHA256 - if (this->auth_type_ == ota::OTA_RESPONSE_REQUEST_SHA256_AUTH) { - return SHA256_HEX_SIZE; - } -#endif -#ifdef USE_OTA_MD5 - return MD5_HEX_SIZE; -#else -#ifndef USE_OTA_SHA256 -#error "Either USE_OTA_MD5 or USE_OTA_SHA256 must be defined when USE_OTA_PASSWORD is enabled" -#endif -#endif -} - void ESPHomeOTAComponent::cleanup_auth_() { this->auth_buf_ = nullptr; this->auth_buf_pos_ = 0; diff --git a/esphome/components/esphome/ota/ota_esphome.h b/esphome/components/esphome/ota/ota_esphome.h index 4412a65757..e199b7e406 100644 --- a/esphome/components/esphome/ota/ota_esphome.h +++ b/esphome/components/esphome/ota/ota_esphome.h @@ -44,10 +44,10 @@ class ESPHomeOTAComponent : public ota::OTAComponent { void handle_handshake_(); void handle_data_(); #ifdef USE_OTA_PASSWORD + static constexpr size_t SHA256_HEX_SIZE = 64; // SHA256 hash as hex string (32 bytes * 2) bool handle_auth_send_(); bool handle_auth_read_(); bool select_auth_type_(); - size_t get_auth_hex_size_() const; void cleanup_auth_(); void log_auth_warning_(const LogString *msg); #endif // USE_OTA_PASSWORD diff --git a/esphome/core/defines.h b/esphome/core/defines.h index be429a9784..579edc065a 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -144,10 +144,7 @@ #define USE_ONLINE_IMAGE_PNG_SUPPORT #define USE_ONLINE_IMAGE_JPEG_SUPPORT #define USE_OTA -#define USE_OTA_MD5 #define USE_OTA_PASSWORD -#define USE_OTA_SHA256 -#define ALLOW_OTA_DOWNGRADE_MD5 #define USE_OTA_STATE_LISTENER #define USE_OTA_VERSION 2 #define USE_TIME_TIMEZONE From 4e8c02b39673ae962d5f775ba773426abf6c9efc Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 20:25:12 -1000 Subject: [PATCH 096/302] [xiaomi_*] Use stack-based hex formatting for bindkey logging (#12798) --- esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp | 6 +++++- esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.cpp | 6 +++++- esphome/components/xiaomi_cgg1/xiaomi_cgg1.cpp | 6 +++++- esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp | 6 +++++- esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp | 6 +++++- esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.cpp | 6 +++++- esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.cpp | 6 +++++- .../components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp | 6 +++++- 8 files changed, 40 insertions(+), 8 deletions(-) diff --git a/esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp b/esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp index 4642768f90..d7f1ec3782 100644 --- a/esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp +++ b/esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp @@ -1,4 +1,5 @@ #include "xiaomi_cgd1.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #ifdef USE_ESP32 @@ -8,11 +9,14 @@ namespace xiaomi_cgd1 { static const char *const TAG = "xiaomi_cgd1"; +static constexpr size_t CGD1_BINDKEY_SIZE = 16; + void XiaomiCGD1::dump_config() { + char bindkey_hex[format_hex_pretty_size(CGD1_BINDKEY_SIZE)]; ESP_LOGCONFIG(TAG, "Xiaomi CGD1\n" " Bindkey: %s", - format_hex_pretty(this->bindkey_, 16).c_str()); + format_hex_pretty_to(bindkey_hex, this->bindkey_, CGD1_BINDKEY_SIZE, '.')); LOG_SENSOR(" ", "Temperature", this->temperature_); LOG_SENSOR(" ", "Humidity", this->humidity_); LOG_SENSOR(" ", "Battery Level", this->battery_level_); diff --git a/esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.cpp b/esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.cpp index 0dcbcbd05c..9151cbde41 100644 --- a/esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.cpp +++ b/esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.cpp @@ -1,4 +1,5 @@ #include "xiaomi_cgdk2.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #ifdef USE_ESP32 @@ -8,11 +9,14 @@ namespace xiaomi_cgdk2 { static const char *const TAG = "xiaomi_cgdk2"; +static constexpr size_t CGDK2_BINDKEY_SIZE = 16; + void XiaomiCGDK2::dump_config() { + char bindkey_hex[format_hex_pretty_size(CGDK2_BINDKEY_SIZE)]; ESP_LOGCONFIG(TAG, "Xiaomi CGDK2\n" " Bindkey: %s", - format_hex_pretty(this->bindkey_, 16).c_str()); + format_hex_pretty_to(bindkey_hex, this->bindkey_, CGDK2_BINDKEY_SIZE, '.')); LOG_SENSOR(" ", "Temperature", this->temperature_); LOG_SENSOR(" ", "Humidity", this->humidity_); LOG_SENSOR(" ", "Battery Level", this->battery_level_); diff --git a/esphome/components/xiaomi_cgg1/xiaomi_cgg1.cpp b/esphome/components/xiaomi_cgg1/xiaomi_cgg1.cpp index f9fffa3f20..54b50a2eee 100644 --- a/esphome/components/xiaomi_cgg1/xiaomi_cgg1.cpp +++ b/esphome/components/xiaomi_cgg1/xiaomi_cgg1.cpp @@ -1,4 +1,5 @@ #include "xiaomi_cgg1.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #ifdef USE_ESP32 @@ -8,11 +9,14 @@ namespace xiaomi_cgg1 { static const char *const TAG = "xiaomi_cgg1"; +static constexpr size_t CGG1_BINDKEY_SIZE = 16; + void XiaomiCGG1::dump_config() { + char bindkey_hex[format_hex_pretty_size(CGG1_BINDKEY_SIZE)]; ESP_LOGCONFIG(TAG, "Xiaomi CGG1\n" " Bindkey: %s", - format_hex_pretty(this->bindkey_, 16).c_str()); + format_hex_pretty_to(bindkey_hex, this->bindkey_, CGG1_BINDKEY_SIZE, '.')); LOG_SENSOR(" ", "Temperature", this->temperature_); LOG_SENSOR(" ", "Humidity", this->humidity_); LOG_SENSOR(" ", "Battery Level", this->battery_level_); diff --git a/esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp b/esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp index dff1228f64..da5229c100 100644 --- a/esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp +++ b/esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp @@ -1,4 +1,5 @@ #include "xiaomi_lywsd02mmc.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #ifdef USE_ESP32 @@ -8,11 +9,14 @@ namespace xiaomi_lywsd02mmc { static const char *const TAG = "xiaomi_lywsd02mmc"; +static constexpr size_t LYWSD02MMC_BINDKEY_SIZE = 16; + void XiaomiLYWSD02MMC::dump_config() { + char bindkey_hex[format_hex_pretty_size(LYWSD02MMC_BINDKEY_SIZE)]; ESP_LOGCONFIG(TAG, "Xiaomi LYWSD02MMC\n" " Bindkey: %s", - format_hex_pretty(this->bindkey_, 16).c_str()); + format_hex_pretty_to(bindkey_hex, this->bindkey_, LYWSD02MMC_BINDKEY_SIZE, '.')); LOG_SENSOR(" ", "Temperature", this->temperature_); LOG_SENSOR(" ", "Humidity", this->humidity_); LOG_SENSOR(" ", "Battery Level", this->battery_level_); diff --git a/esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp b/esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp index fb0165a21f..44fdb3b816 100644 --- a/esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp +++ b/esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp @@ -1,4 +1,5 @@ #include "xiaomi_lywsd03mmc.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #ifdef USE_ESP32 @@ -8,11 +9,14 @@ namespace xiaomi_lywsd03mmc { static const char *const TAG = "xiaomi_lywsd03mmc"; +static constexpr size_t LYWSD03MMC_BINDKEY_SIZE = 16; + void XiaomiLYWSD03MMC::dump_config() { + char bindkey_hex[format_hex_pretty_size(LYWSD03MMC_BINDKEY_SIZE)]; ESP_LOGCONFIG(TAG, "Xiaomi LYWSD03MMC\n" " Bindkey: %s", - format_hex_pretty(this->bindkey_, 16).c_str()); + format_hex_pretty_to(bindkey_hex, this->bindkey_, LYWSD03MMC_BINDKEY_SIZE, '.')); LOG_SENSOR(" ", "Temperature", this->temperature_); LOG_SENSOR(" ", "Humidity", this->humidity_); LOG_SENSOR(" ", "Battery Level", this->battery_level_); diff --git a/esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.cpp b/esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.cpp index 90b654873b..55b81b301e 100644 --- a/esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.cpp +++ b/esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.cpp @@ -1,4 +1,5 @@ #include "xiaomi_mhoc401.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #ifdef USE_ESP32 @@ -8,11 +9,14 @@ namespace xiaomi_mhoc401 { static const char *const TAG = "xiaomi_mhoc401"; +static constexpr size_t MHOC401_BINDKEY_SIZE = 16; + void XiaomiMHOC401::dump_config() { + char bindkey_hex[format_hex_pretty_size(MHOC401_BINDKEY_SIZE)]; ESP_LOGCONFIG(TAG, "Xiaomi MHOC401\n" " Bindkey: %s", - format_hex_pretty(this->bindkey_, 16).c_str()); + format_hex_pretty_to(bindkey_hex, this->bindkey_, MHOC401_BINDKEY_SIZE, '.')); LOG_SENSOR(" ", "Temperature", this->temperature_); LOG_SENSOR(" ", "Humidity", this->humidity_); LOG_SENSOR(" ", "Battery Level", this->battery_level_); diff --git a/esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.cpp b/esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.cpp index 498e724368..112bf442e0 100644 --- a/esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.cpp +++ b/esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.cpp @@ -1,4 +1,5 @@ #include "xiaomi_rtcgq02lm.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #ifdef USE_ESP32 @@ -8,9 +9,12 @@ namespace xiaomi_rtcgq02lm { static const char *const TAG = "xiaomi_rtcgq02lm"; +static constexpr size_t RTCGQ02LM_BINDKEY_SIZE = 16; + void XiaomiRTCGQ02LM::dump_config() { + char bindkey_hex[format_hex_pretty_size(RTCGQ02LM_BINDKEY_SIZE)]; ESP_LOGCONFIG(TAG, "Xiaomi RTCGQ02LM"); - ESP_LOGCONFIG(TAG, " Bindkey: %s", format_hex_pretty(this->bindkey_, 16).c_str()); + ESP_LOGCONFIG(TAG, " Bindkey: %s", format_hex_pretty_to(bindkey_hex, this->bindkey_, RTCGQ02LM_BINDKEY_SIZE, '.')); #ifdef USE_BINARY_SENSOR LOG_BINARY_SENSOR(" ", "Motion", this->motion_); LOG_BINARY_SENSOR(" ", "Light", this->light_); diff --git a/esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp b/esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp index f8712e7fd4..d3fec6cc9e 100644 --- a/esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +++ b/esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp @@ -1,4 +1,5 @@ #include "xiaomi_xmwsdj04mmc.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #ifdef USE_ESP32 @@ -8,9 +9,12 @@ namespace xiaomi_xmwsdj04mmc { static const char *const TAG = "xiaomi_xmwsdj04mmc"; +static constexpr size_t XMWSDJ04MMC_BINDKEY_SIZE = 16; + void XiaomiXMWSDJ04MMC::dump_config() { + char bindkey_hex[format_hex_pretty_size(XMWSDJ04MMC_BINDKEY_SIZE)]; ESP_LOGCONFIG(TAG, "Xiaomi XMWSDJ04MMC"); - ESP_LOGCONFIG(TAG, " Bindkey: %s", format_hex_pretty(this->bindkey_, 16).c_str()); + ESP_LOGCONFIG(TAG, " Bindkey: %s", format_hex_pretty_to(bindkey_hex, this->bindkey_, XMWSDJ04MMC_BINDKEY_SIZE, '.')); LOG_SENSOR(" ", "Temperature", this->temperature_); LOG_SENSOR(" ", "Humidity", this->humidity_); LOG_SENSOR(" ", "Battery Level", this->battery_level_); From 8acaa16987f50a6d65b71832dd559d1716d9f927 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 21:04:11 -1000 Subject: [PATCH 097/302] [usb_cdc_acm] Use stack-based hex formatting in verbose logging (#12792) --- esphome/components/usb_cdc_acm/usb_cdc_acm.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/esphome/components/usb_cdc_acm/usb_cdc_acm.cpp b/esphome/components/usb_cdc_acm/usb_cdc_acm.cpp index 1cf614286f..29120a3d0b 100644 --- a/esphome/components/usb_cdc_acm/usb_cdc_acm.cpp +++ b/esphome/components/usb_cdc_acm/usb_cdc_acm.cpp @@ -1,6 +1,7 @@ #if defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) #include "usb_cdc_acm.h" #include "esphome/core/application.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #include @@ -16,6 +17,9 @@ namespace esphome::usb_cdc_acm { static const char *TAG = "usb_cdc_acm"; +// Maximum bytes to log in very verbose hex output (168 * 3 = 504, under TX buffer size of 512) +static constexpr size_t USB_CDC_MAX_LOG_BYTES = 168; + static constexpr size_t USB_TX_TASK_STACK_SIZE = 4096; static constexpr size_t USB_TX_TASK_STACK_SIZE_VV = 8192; @@ -43,7 +47,10 @@ static void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event) { esp_err_t ret = tinyusb_cdcacm_read(static_cast(itf), rx_buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); ESP_LOGV(TAG, "tinyusb_cdc_rx_callback itf=%d (size: %u)", itf, rx_size); - ESP_LOGVV(TAG, "rx_buf = %s", format_hex_pretty(rx_buf, rx_size).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + char rx_hex_buf[format_hex_pretty_size(USB_CDC_MAX_LOG_BYTES)]; +#endif + ESP_LOGVV(TAG, "rx_buf = %s", format_hex_pretty_to(rx_hex_buf, rx_buf, rx_size)); if (ret == ESP_OK && rx_size > 0) { RingbufHandle_t rx_ringbuf = instance->get_rx_ringbuf(); @@ -306,7 +313,10 @@ void USBCDCACMInstance::usb_tx_task() { } ESP_LOGV(TAG, "USB TX itf=%d: Read %d bytes from buffer", this->itf_, tx_data_size); - ESP_LOGVV(TAG, "data = %s", format_hex_pretty(data, tx_data_size).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + char tx_hex_buf[format_hex_pretty_size(USB_CDC_MAX_LOG_BYTES)]; +#endif + ESP_LOGVV(TAG, "data = %s", format_hex_pretty_to(tx_hex_buf, data, tx_data_size)); // Serial data will be split up into 64 byte chunks to be sent over USB so this // usually will take multiple iterations From d7fd85e61009544bd08b06569fcbaf0cd8a4b1c4 Mon Sep 17 00:00:00 2001 From: Tobias Stanzel Date: Fri, 2 Jan 2026 08:10:30 +0100 Subject: [PATCH 098/302] [spi] Allow any achievable data rate (#12753) Co-authored-by: clydebarrow <2366188+clydebarrow@users.noreply.github.com> --- esphome/components/spi/__init__.py | 94 +++++++++++++------ .../components/animation/test.rp2040-ard.yaml | 1 + tests/components/chsc6x/test.rp2040-ard.yaml | 1 + tests/components/display/common.yaml | 1 + tests/components/ili9xxx/common.yaml | 2 + tests/components/image/test.rp2040-ard.yaml | 1 + .../online_image/common-rp2040.yaml | 1 + tests/components/qr_code/common.yaml | 1 + tests/components/xpt2046/common.yaml | 1 + 9 files changed, 76 insertions(+), 27 deletions(-) diff --git a/esphome/components/spi/__init__.py b/esphome/components/spi/__init__.py index 045cdd09d3..e890567abf 100644 --- a/esphome/components/spi/__init__.py +++ b/esphome/components/spi/__init__.py @@ -49,21 +49,60 @@ SPIDevice = spi_ns.class_("SPIDevice") SPIDataRate = spi_ns.enum("SPIDataRate") SPIMode = spi_ns.enum("SPIMode") -SPI_DATA_RATE_OPTIONS = { - 80e6: SPIDataRate.DATA_RATE_80MHZ, - 40e6: SPIDataRate.DATA_RATE_40MHZ, - 20e6: SPIDataRate.DATA_RATE_20MHZ, - 10e6: SPIDataRate.DATA_RATE_10MHZ, - 8e6: SPIDataRate.DATA_RATE_8MHZ, - 5e6: SPIDataRate.DATA_RATE_5MHZ, - 4e6: SPIDataRate.DATA_RATE_4MHZ, - 2e6: SPIDataRate.DATA_RATE_2MHZ, - 1e6: SPIDataRate.DATA_RATE_1MHZ, - 2e5: SPIDataRate.DATA_RATE_200KHZ, - 75e3: SPIDataRate.DATA_RATE_75KHZ, - 1e3: SPIDataRate.DATA_RATE_1KHZ, +PLATFORM_SPI_CLOCKS = { + PLATFORM_ESP8266: 40e6, + PLATFORM_ESP32: 80e6, + PLATFORM_RP2040: 62.5e6, } -SPI_DATA_RATE_SCHEMA = cv.All(cv.frequency, cv.enum(SPI_DATA_RATE_OPTIONS)) + +MAX_DATA_RATE_ERROR = 0.05 # Max allowable actual data rate difference from requested + + +def _render_hz(value: float) -> str: + """Render a frequency in Hz as a human-readable string using Hz, KHz or MHz. + + Examples: + 500 -> "500 Hz" + 1500 -> "1.5 kHz" + 2000000 -> "2 MHz" + """ + if value >= 1e6: + unit = "MHz" + num = value / 1e6 + elif value >= 1e3: + unit = "kHz" + num = value / 1e3 + else: + unit = "Hz" + num = value + + # Format with up to 2 decimal places, then strip unnecessary trailing zeros and dot + formatted = f"{int(num)}" if unit == "Hz" else f"{num:.2f}".rstrip("0").rstrip(".") + return formatted + unit + + +def _frequency_validator(value): + platform = get_target_platform() + frequency = PLATFORM_SPI_CLOCKS[platform] + value = cv.frequency(value) + if value > frequency: + raise cv.Invalid( + f"The configured SPI data rate ({_render_hz(value)}) exceeds the maximum for this platform ({_render_hz(frequency)})" + ) + if value < 1000: + raise cv.Invalid("The configured SPI data rate must be at least 1000Hz") + divisor = round(frequency / value) + actual = frequency / divisor + error = abs(actual - value) / value + if error > MAX_DATA_RATE_ERROR: + raise cv.Invalid( + f"The configured SPI data rate ({_render_hz(value)}) is not available for this chip - closest is {_render_hz(actual)}" + ) + return value + + +SPI_DATA_RATE_SCHEMA = _frequency_validator + SPI_MODE_OPTIONS = { "MODE0": SPIMode.MODE0, @@ -393,19 +432,20 @@ def spi_device_schema( :param mode Choose single, quad or octal mode. :return: The SPI device schema, `extend` this in your config schema. """ - schema = { - cv.GenerateID(CONF_SPI_ID): cv.use_id(TYPE_CLASS[mode]), - cv.Optional(CONF_DATA_RATE, default=default_data_rate): SPI_DATA_RATE_SCHEMA, - cv.Optional(CONF_SPI_MODE, default=default_mode): cv.enum( - SPI_MODE_OPTIONS, upper=True - ), - cv.Optional(CONF_RELEASE_DEVICE): cv.All(cv.boolean, cv.only_on_esp32), - } - if cs_pin_required: - schema[cv.Required(CONF_CS_PIN)] = pins.gpio_output_pin_schema - else: - schema[cv.Optional(CONF_CS_PIN)] = pins.gpio_output_pin_schema - return cv.Schema(schema) + cs_pin_option = cv.Required if cs_pin_required else cv.Optional + return cv.Schema( + { + cv.GenerateID(CONF_SPI_ID): cv.use_id(TYPE_CLASS[mode]), + cv.Optional( + CONF_DATA_RATE, default=default_data_rate + ): SPI_DATA_RATE_SCHEMA, + cv.Optional(CONF_SPI_MODE, default=default_mode): cv.enum( + SPI_MODE_OPTIONS, upper=True + ), + cv.Optional(CONF_RELEASE_DEVICE): cv.All(cv.boolean, cv.only_on_esp32), + cs_pin_option(CONF_CS_PIN): pins.gpio_output_pin_schema, + } + ) async def register_spi_device(var, config): diff --git a/tests/components/animation/test.rp2040-ard.yaml b/tests/components/animation/test.rp2040-ard.yaml index 32fb4efb04..2c99e937f3 100644 --- a/tests/components/animation/test.rp2040-ard.yaml +++ b/tests/components/animation/test.rp2040-ard.yaml @@ -11,3 +11,4 @@ display: dc_pin: 21 reset_pin: 22 invert_colors: false + data_rate: 10MHz diff --git a/tests/components/chsc6x/test.rp2040-ard.yaml b/tests/components/chsc6x/test.rp2040-ard.yaml index 2e3613a4a3..eb21b8ec4b 100644 --- a/tests/components/chsc6x/test.rp2040-ard.yaml +++ b/tests/components/chsc6x/test.rp2040-ard.yaml @@ -9,6 +9,7 @@ display: invert_colors: True cs_pin: 20 dc_pin: 21 + data_rate: 20MHz pages: - id: page1 lambda: |- diff --git a/tests/components/display/common.yaml b/tests/components/display/common.yaml index 27abb23e03..a722a5f7c2 100644 --- a/tests/components/display/common.yaml +++ b/tests/components/display/common.yaml @@ -6,6 +6,7 @@ display: dc_pin: 13 reset_pin: 21 invert_colors: false + data_rate: 20MHz lambda: |- // Draw an analog clock in the center of the screen int centerX = it.get_width() / 2; diff --git a/tests/components/ili9xxx/common.yaml b/tests/components/ili9xxx/common.yaml index 47384b1398..4665e55e4b 100644 --- a/tests/components/ili9xxx/common.yaml +++ b/tests/components/ili9xxx/common.yaml @@ -11,6 +11,7 @@ display: cs_pin: ${cs_pin1} dc_pin: ${dc_pin1} reset_pin: ${reset_pin1} + data_rate: 20MHz lambda: |- it.rectangle(0, 0, it.get_width(), it.get_height()); - platform: ili9xxx @@ -27,5 +28,6 @@ display: reset_pin: ${reset_pin2} auto_clear_enabled: false rotation: 90 + data_rate: 20MHz lambda: |- it.fill(Color::WHITE); diff --git a/tests/components/image/test.rp2040-ard.yaml b/tests/components/image/test.rp2040-ard.yaml index 40f17d57fe..03a9c42a38 100644 --- a/tests/components/image/test.rp2040-ard.yaml +++ b/tests/components/image/test.rp2040-ard.yaml @@ -9,6 +9,7 @@ display: cs_pin: 20 dc_pin: 21 reset_pin: 22 + data_rate: 20MHz invert_colors: true <<: !include common.yaml diff --git a/tests/components/online_image/common-rp2040.yaml b/tests/components/online_image/common-rp2040.yaml index 25891b94bc..bbb514bded 100644 --- a/tests/components/online_image/common-rp2040.yaml +++ b/tests/components/online_image/common-rp2040.yaml @@ -8,6 +8,7 @@ display: spi_id: spi_bus id: main_lcd model: ili9342 + data_rate: 20MHz cs_pin: 20 dc_pin: 17 reset_pin: 21 diff --git a/tests/components/qr_code/common.yaml b/tests/components/qr_code/common.yaml index 15b4e387c6..2ffba67763 100644 --- a/tests/components/qr_code/common.yaml +++ b/tests/components/qr_code/common.yaml @@ -5,6 +5,7 @@ display: cs_pin: ${cs_pin} dc_pin: ${dc_pin} reset_pin: ${reset_pin} + data_rate: 500kHz invert_colors: false lambda: |- // Draw a QR code in the center of the screen diff --git a/tests/components/xpt2046/common.yaml b/tests/components/xpt2046/common.yaml index 3a8e3286a6..eddbd24d6a 100644 --- a/tests/components/xpt2046/common.yaml +++ b/tests/components/xpt2046/common.yaml @@ -6,6 +6,7 @@ display: cs_pin: ${disp_cs_pin} dc_pin: ${dc_pin} reset_pin: ${reset_pin} + data_rate: 20MHz invert_colors: false lambda: |- it.rectangle(0, 0, it.get_width(), it.get_height()); From 6d4f4d8d23a8321704e315d64aacae9a8224966b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 08:17:05 -1000 Subject: [PATCH 099/302] [api] Auto-generate StringRef for incoming API string fields (#12648) --- esphome/components/api/api.proto | 22 +-- esphome/components/api/api_connection.cpp | 32 ++-- esphome/components/api/api_pb2.cpp | 149 ++++++++---------- esphome/components/api/api_pb2.h | 87 +++++----- esphome/components/api/api_pb2_dump.cpp | 98 ++++++++---- .../voice_assistant/voice_assistant.cpp | 26 +-- script/api_protobuf/api_protobuf.py | 103 +++++++----- 7 files changed, 280 insertions(+), 237 deletions(-) diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index c351bc8c9c..debea5808c 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -102,7 +102,7 @@ message HelloRequest { // For example "Home Assistant" // Not strictly necessary to send but nice for debugging // purposes. - string client_info = 1 [(pointer_to_buffer) = true]; + string client_info = 1; uint32 api_version_major = 2; uint32 api_version_minor = 3; } @@ -139,7 +139,7 @@ message AuthenticationRequest { option (ifdef) = "USE_API_PASSWORD"; // The password to log in with - string password = 1 [(pointer_to_buffer) = true]; + string password = 1; } // Confirmation of successful connection. After this the connection is available for all traffic. @@ -477,7 +477,7 @@ message FanCommandRequest { bool has_speed_level = 10; int32 speed_level = 11; bool has_preset_mode = 12; - string preset_mode = 13 [(pointer_to_buffer) = true]; + string preset_mode = 13; uint32 device_id = 14 [(field_ifdef) = "USE_DEVICES"]; } @@ -579,7 +579,7 @@ message LightCommandRequest { bool has_flash_length = 16; uint32 flash_length = 17; bool has_effect = 18; - string effect = 19 [(pointer_to_buffer) = true]; + string effect = 19; uint32 device_id = 28 [(field_ifdef) = "USE_DEVICES"]; } @@ -824,9 +824,9 @@ message HomeAssistantStateResponse { option (no_delay) = true; option (ifdef) = "USE_API_HOMEASSISTANT_STATES"; - string entity_id = 1 [(pointer_to_buffer) = true]; - string state = 2 [(pointer_to_buffer) = true]; - string attribute = 3 [(pointer_to_buffer) = true]; + string entity_id = 1; + string state = 2; + string attribute = 3; } // ==================== IMPORT TIME ==================== @@ -841,7 +841,7 @@ message GetTimeResponse { option (no_delay) = true; fixed32 epoch_seconds = 1; - string timezone = 2 [(pointer_to_buffer) = true]; + string timezone = 2; } // ==================== USER-DEFINES SERVICES ==================== @@ -1091,11 +1091,11 @@ message ClimateCommandRequest { bool has_swing_mode = 14; ClimateSwingMode swing_mode = 15; bool has_custom_fan_mode = 16; - string custom_fan_mode = 17 [(pointer_to_buffer) = true]; + string custom_fan_mode = 17; bool has_preset = 18; ClimatePreset preset = 19; bool has_custom_preset = 20; - string custom_preset = 21 [(pointer_to_buffer) = true]; + string custom_preset = 21; bool has_target_humidity = 22; float target_humidity = 23; uint32 device_id = 24 [(field_ifdef) = "USE_DEVICES"]; @@ -1274,7 +1274,7 @@ message SelectCommandRequest { option (base_class) = "CommandProtoMessage"; fixed32 key = 1; - string state = 2 [(pointer_to_buffer) = true]; + string state = 2; uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"]; } diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index b5628f654e..26ddb16e9a 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -473,7 +473,7 @@ void APIConnection::fan_command(const FanCommandRequest &msg) { if (msg.has_direction) call.set_direction(static_cast(msg.direction)); if (msg.has_preset_mode) - call.set_preset_mode(reinterpret_cast(msg.preset_mode), msg.preset_mode_len); + call.set_preset_mode(msg.preset_mode.c_str(), msg.preset_mode.size()); call.perform(); } #endif @@ -559,7 +559,7 @@ void APIConnection::light_command(const LightCommandRequest &msg) { if (msg.has_flash_length) call.set_flash_length(msg.flash_length); if (msg.has_effect) - call.set_effect(reinterpret_cast(msg.effect), msg.effect_len); + call.set_effect(msg.effect.c_str(), msg.effect.size()); call.perform(); } #endif @@ -738,11 +738,11 @@ void APIConnection::climate_command(const ClimateCommandRequest &msg) { if (msg.has_fan_mode) call.set_fan_mode(static_cast(msg.fan_mode)); if (msg.has_custom_fan_mode) - call.set_fan_mode(reinterpret_cast(msg.custom_fan_mode), msg.custom_fan_mode_len); + call.set_fan_mode(msg.custom_fan_mode.c_str(), msg.custom_fan_mode.size()); if (msg.has_preset) call.set_preset(static_cast(msg.preset)); if (msg.has_custom_preset) - call.set_preset(reinterpret_cast(msg.custom_preset), msg.custom_preset_len); + call.set_preset(msg.custom_preset.c_str(), msg.custom_preset.size()); if (msg.has_swing_mode) call.set_swing_mode(static_cast(msg.swing_mode)); call.perform(); @@ -931,7 +931,7 @@ uint16_t APIConnection::try_send_select_info(EntityBase *entity, APIConnection * } void APIConnection::select_command(const SelectCommandRequest &msg) { ENTITY_COMMAND_MAKE_CALL(select::Select, select, select) - call.set_option(reinterpret_cast(msg.state), msg.state_len); + call.set_option(msg.state.c_str(), msg.state.size()); call.perform(); } #endif @@ -1153,9 +1153,8 @@ void APIConnection::on_get_time_response(const GetTimeResponse &value) { if (homeassistant::global_homeassistant_time != nullptr) { homeassistant::global_homeassistant_time->set_epoch_time(value.epoch_seconds); #ifdef USE_TIME_TIMEZONE - if (value.timezone_len > 0) { - homeassistant::global_homeassistant_time->set_timezone(reinterpret_cast(value.timezone), - value.timezone_len); + if (!value.timezone.empty()) { + homeassistant::global_homeassistant_time->set_timezone(value.timezone.c_str(), value.timezone.size()); } #endif } @@ -1522,7 +1521,7 @@ void APIConnection::complete_authentication_() { } bool APIConnection::send_hello_response(const HelloRequest &msg) { - this->client_info_.name.assign(reinterpret_cast(msg.client_info), msg.client_info_len); + this->client_info_.name.assign(msg.client_info.c_str(), msg.client_info.size()); this->client_info_.peername = this->helper_->getpeername(); this->client_api_version_major_ = msg.api_version_major; this->client_api_version_minor_ = msg.api_version_minor; @@ -1550,7 +1549,7 @@ bool APIConnection::send_hello_response(const HelloRequest &msg) { bool APIConnection::send_authenticate_response(const AuthenticationRequest &msg) { AuthenticationResponse resp; // bool invalid_password = 1; - resp.invalid_password = !this->parent_->check_password(msg.password, msg.password_len); + resp.invalid_password = !this->parent_->check_password(msg.password.byte(), msg.password.size()); if (!resp.invalid_password) { this->complete_authentication_(); } @@ -1693,27 +1692,28 @@ bool APIConnection::send_device_info_response(const DeviceInfoRequest &msg) { #ifdef USE_API_HOMEASSISTANT_STATES void APIConnection::on_home_assistant_state_response(const HomeAssistantStateResponse &msg) { // Skip if entity_id is empty (invalid message) - if (msg.entity_id_len == 0) { + if (msg.entity_id.empty()) { return; } for (auto &it : this->parent_->get_state_subs()) { // Compare entity_id: check length matches and content matches size_t entity_id_len = strlen(it.entity_id); - if (entity_id_len != msg.entity_id_len || memcmp(it.entity_id, msg.entity_id, msg.entity_id_len) != 0) { + if (entity_id_len != msg.entity_id.size() || + memcmp(it.entity_id, msg.entity_id.c_str(), msg.entity_id.size()) != 0) { continue; } // Compare attribute: either both have matching attribute, or both have none size_t sub_attr_len = it.attribute != nullptr ? strlen(it.attribute) : 0; - if (sub_attr_len != msg.attribute_len || - (sub_attr_len > 0 && memcmp(it.attribute, msg.attribute, sub_attr_len) != 0)) { + if (sub_attr_len != msg.attribute.size() || + (sub_attr_len > 0 && memcmp(it.attribute, msg.attribute.c_str(), sub_attr_len) != 0)) { continue; } // Create temporary string for callback (callback takes const std::string &) - // Handle empty state (nullptr with len=0) - std::string state(msg.state_len > 0 ? reinterpret_cast(msg.state) : "", msg.state_len); + // Handle empty state + std::string state(!msg.state.empty() ? msg.state.c_str() : "", msg.state.size()); it.callback(state); } } diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index 3376b022c5..edd6dfc6a9 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -23,9 +23,7 @@ bool HelloRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { bool HelloRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 1: { - // Use raw data directly to avoid allocation - this->client_info = value.data(); - this->client_info_len = value.size(); + this->client_info = StringRef(reinterpret_cast(value.data()), value.size()); break; } default: @@ -49,9 +47,7 @@ void HelloResponse::calculate_size(ProtoSize &size) const { bool AuthenticationRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 1: { - // Use raw data directly to avoid allocation - this->password = value.data(); - this->password_len = value.size(); + this->password = StringRef(reinterpret_cast(value.data()), value.size()); break; } default: @@ -448,9 +444,7 @@ bool FanCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { bool FanCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 13: { - // Use raw data directly to avoid allocation - this->preset_mode = value.data(); - this->preset_mode_len = value.size(); + this->preset_mode = StringRef(reinterpret_cast(value.data()), value.size()); break; } default: @@ -615,9 +609,7 @@ bool LightCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { bool LightCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 19: { - // Use raw data directly to avoid allocation - this->effect = value.data(); - this->effect_len = value.size(); + this->effect = StringRef(reinterpret_cast(value.data()), value.size()); break; } default: @@ -859,7 +851,6 @@ void SubscribeLogsResponse::calculate_size(ProtoSize &size) const { bool NoiseEncryptionSetKeyRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 1: { - // Use raw data directly to avoid allocation this->key = value.data(); this->key_len = value.size(); break; @@ -936,12 +927,12 @@ bool HomeassistantActionResponse::decode_varint(uint32_t field_id, ProtoVarInt v } bool HomeassistantActionResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 3: - this->error_message = value.as_string(); + case 3: { + this->error_message = StringRef(reinterpret_cast(value.data()), value.size()); break; + } #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON case 4: { - // Use raw data directly to avoid allocation this->response_data = value.data(); this->response_data_len = value.size(); break; @@ -967,21 +958,15 @@ void SubscribeHomeAssistantStateResponse::calculate_size(ProtoSize &size) const bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 1: { - // Use raw data directly to avoid allocation - this->entity_id = value.data(); - this->entity_id_len = value.size(); + this->entity_id = StringRef(reinterpret_cast(value.data()), value.size()); break; } case 2: { - // Use raw data directly to avoid allocation - this->state = value.data(); - this->state_len = value.size(); + this->state = StringRef(reinterpret_cast(value.data()), value.size()); break; } case 3: { - // Use raw data directly to avoid allocation - this->attribute = value.data(); - this->attribute_len = value.size(); + this->attribute = StringRef(reinterpret_cast(value.data()), value.size()); break; } default: @@ -993,9 +978,7 @@ bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDel bool GetTimeResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 2: { - // Use raw data directly to avoid allocation - this->timezone = value.data(); - this->timezone_len = value.size(); + this->timezone = StringRef(reinterpret_cast(value.data()), value.size()); break; } default: @@ -1060,9 +1043,10 @@ bool ExecuteServiceArgument::decode_varint(uint32_t field_id, ProtoVarInt value) } bool ExecuteServiceArgument::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 4: - this->string_ = value.as_string(); + case 4: { + this->string_ = StringRef(reinterpret_cast(value.data()), value.size()); break; + } case 9: this->string_array.push_back(value.as_string()); break; @@ -1153,7 +1137,7 @@ void ExecuteServiceResponse::calculate_size(ProtoSize &size) const { size.add_bool(1, this->success); size.add_length(1, this->error_message_ref_.size()); #ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON - size.add_length(4, this->response_data_len); + size.add_length(1, this->response_data_len); #endif } #endif @@ -1408,15 +1392,11 @@ bool ClimateCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) bool ClimateCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 17: { - // Use raw data directly to avoid allocation - this->custom_fan_mode = value.data(); - this->custom_fan_mode_len = value.size(); + this->custom_fan_mode = StringRef(reinterpret_cast(value.data()), value.size()); break; } case 21: { - // Use raw data directly to avoid allocation - this->custom_preset = value.data(); - this->custom_preset_len = value.size(); + this->custom_preset = StringRef(reinterpret_cast(value.data()), value.size()); break; } default: @@ -1702,9 +1682,7 @@ bool SelectCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { bool SelectCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 2: { - // Use raw data directly to avoid allocation - this->state = value.data(); - this->state_len = value.size(); + this->state = StringRef(reinterpret_cast(value.data()), value.size()); break; } default: @@ -1808,9 +1786,10 @@ bool SirenCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { } bool SirenCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 5: - this->tone = value.as_string(); + case 5: { + this->tone = StringRef(reinterpret_cast(value.data()), value.size()); break; + } default: return false; } @@ -1899,9 +1878,10 @@ bool LockCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { } bool LockCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 4: - this->code = value.as_string(); + case 4: { + this->code = StringRef(reinterpret_cast(value.data()), value.size()); break; + } default: return false; } @@ -2069,9 +2049,10 @@ bool MediaPlayerCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt val } bool MediaPlayerCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 7: - this->media_url = value.as_string(); + case 7: { + this->media_url = StringRef(reinterpret_cast(value.data()), value.size()); break; + } default: return false; } @@ -2279,7 +2260,6 @@ bool BluetoothGATTWriteRequest::decode_varint(uint32_t field_id, ProtoVarInt val bool BluetoothGATTWriteRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 4: { - // Use raw data directly to avoid allocation this->data = value.data(); this->data_len = value.size(); break; @@ -2318,7 +2298,6 @@ bool BluetoothGATTWriteDescriptorRequest::decode_varint(uint32_t field_id, Proto bool BluetoothGATTWriteDescriptorRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 3: { - // Use raw data directly to avoid allocation this->data = value.data(); this->data_len = value.size(); break; @@ -2502,12 +2481,14 @@ bool VoiceAssistantResponse::decode_varint(uint32_t field_id, ProtoVarInt value) } bool VoiceAssistantEventData::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->name = value.as_string(); + case 1: { + this->name = StringRef(reinterpret_cast(value.data()), value.size()); break; - case 2: - this->value = value.as_string(); + } + case 2: { + this->value = StringRef(reinterpret_cast(value.data()), value.size()); break; + } default: return false; } @@ -2583,12 +2564,14 @@ bool VoiceAssistantTimerEventResponse::decode_varint(uint32_t field_id, ProtoVar } bool VoiceAssistantTimerEventResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 2: - this->timer_id = value.as_string(); + case 2: { + this->timer_id = StringRef(reinterpret_cast(value.data()), value.size()); break; - case 3: - this->name = value.as_string(); + } + case 3: { + this->name = StringRef(reinterpret_cast(value.data()), value.size()); break; + } default: return false; } @@ -2606,15 +2589,18 @@ bool VoiceAssistantAnnounceRequest::decode_varint(uint32_t field_id, ProtoVarInt } bool VoiceAssistantAnnounceRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->media_id = value.as_string(); + case 1: { + this->media_id = StringRef(reinterpret_cast(value.data()), value.size()); break; - case 2: - this->text = value.as_string(); + } + case 2: { + this->text = StringRef(reinterpret_cast(value.data()), value.size()); break; - case 3: - this->preannounce_media_id = value.as_string(); + } + case 3: { + this->preannounce_media_id = StringRef(reinterpret_cast(value.data()), value.size()); break; + } default: return false; } @@ -2650,24 +2636,29 @@ bool VoiceAssistantExternalWakeWord::decode_varint(uint32_t field_id, ProtoVarIn } bool VoiceAssistantExternalWakeWord::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->id = value.as_string(); + case 1: { + this->id = StringRef(reinterpret_cast(value.data()), value.size()); break; - case 2: - this->wake_word = value.as_string(); + } + case 2: { + this->wake_word = StringRef(reinterpret_cast(value.data()), value.size()); break; + } case 3: this->trained_languages.push_back(value.as_string()); break; - case 4: - this->model_type = value.as_string(); + case 4: { + this->model_type = StringRef(reinterpret_cast(value.data()), value.size()); break; - case 6: - this->model_hash = value.as_string(); + } + case 6: { + this->model_hash = StringRef(reinterpret_cast(value.data()), value.size()); break; - case 7: - this->url = value.as_string(); + } + case 7: { + this->url = StringRef(reinterpret_cast(value.data()), value.size()); break; + } default: return false; } @@ -2777,9 +2768,10 @@ bool AlarmControlPanelCommandRequest::decode_varint(uint32_t field_id, ProtoVarI } bool AlarmControlPanelCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 3: - this->code = value.as_string(); + case 3: { + this->code = StringRef(reinterpret_cast(value.data()), value.size()); break; + } default: return false; } @@ -2861,9 +2853,10 @@ bool TextCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { } bool TextCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 2: - this->state = value.as_string(); + case 2: { + this->state = StringRef(reinterpret_cast(value.data()), value.size()); break; + } default: return false; } @@ -3331,7 +3324,6 @@ bool UpdateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { bool ZWaveProxyFrame::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 1: { - // Use raw data directly to avoid allocation this->data = value.data(); this->data_len = value.size(); break; @@ -3356,7 +3348,6 @@ bool ZWaveProxyRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { bool ZWaveProxyRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 2: { - // Use raw data directly to avoid allocation this->data = value.data(); this->data_len = value.size(); break; @@ -3372,7 +3363,7 @@ void ZWaveProxyRequest::encode(ProtoWriteBuffer buffer) const { } void ZWaveProxyRequest::calculate_size(ProtoSize &size) const { size.add_uint32(1, static_cast(this->type)); - size.add_length(2, this->data_len); + size.add_length(1, this->data_len); } #endif diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index 2111c2a895..9d7a1eb9cb 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -357,12 +357,11 @@ class CommandProtoMessage : public ProtoDecodableMessage { class HelloRequest final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 1; - static constexpr uint8_t ESTIMATED_SIZE = 27; + static constexpr uint8_t ESTIMATED_SIZE = 17; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "hello_request"; } #endif - const uint8_t *client_info{nullptr}; - uint16_t client_info_len{0}; + StringRef client_info{}; uint32_t api_version_major{0}; uint32_t api_version_minor{0}; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -398,12 +397,11 @@ class HelloResponse final : public ProtoMessage { class AuthenticationRequest final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 3; - static constexpr uint8_t ESTIMATED_SIZE = 19; + static constexpr uint8_t ESTIMATED_SIZE = 9; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "authentication_request"; } #endif - const uint8_t *password{nullptr}; - uint16_t password_len{0}; + StringRef password{}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; #endif @@ -784,7 +782,7 @@ class FanStateResponse final : public StateResponseProtoMessage { class FanCommandRequest final : public CommandProtoMessage { public: static constexpr uint8_t MESSAGE_TYPE = 31; - static constexpr uint8_t ESTIMATED_SIZE = 48; + static constexpr uint8_t ESTIMATED_SIZE = 38; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "fan_command_request"; } #endif @@ -797,8 +795,7 @@ class FanCommandRequest final : public CommandProtoMessage { bool has_speed_level{false}; int32_t speed_level{0}; bool has_preset_mode{false}; - const uint8_t *preset_mode{nullptr}; - uint16_t preset_mode_len{0}; + StringRef preset_mode{}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; #endif @@ -860,7 +857,7 @@ class LightStateResponse final : public StateResponseProtoMessage { class LightCommandRequest final : public CommandProtoMessage { public: static constexpr uint8_t MESSAGE_TYPE = 32; - static constexpr uint8_t ESTIMATED_SIZE = 122; + static constexpr uint8_t ESTIMATED_SIZE = 112; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "light_command_request"; } #endif @@ -889,8 +886,7 @@ class LightCommandRequest final : public CommandProtoMessage { bool has_flash_length{false}; uint32_t flash_length{0}; bool has_effect{false}; - const uint8_t *effect{nullptr}; - uint16_t effect_len{0}; + StringRef effect{}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; #endif @@ -1171,7 +1167,7 @@ class HomeassistantActionResponse final : public ProtoDecodableMessage { #endif uint32_t call_id{0}; bool success{false}; - std::string error_message{}; + StringRef error_message{}; #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON const uint8_t *response_data{nullptr}; uint16_t response_data_len{0}; @@ -1222,16 +1218,13 @@ class SubscribeHomeAssistantStateResponse final : public ProtoMessage { class HomeAssistantStateResponse final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 40; - static constexpr uint8_t ESTIMATED_SIZE = 57; + static constexpr uint8_t ESTIMATED_SIZE = 27; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "home_assistant_state_response"; } #endif - const uint8_t *entity_id{nullptr}; - uint16_t entity_id_len{0}; - const uint8_t *state{nullptr}; - uint16_t state_len{0}; - const uint8_t *attribute{nullptr}; - uint16_t attribute_len{0}; + StringRef entity_id{}; + StringRef state{}; + StringRef attribute{}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; #endif @@ -1256,13 +1249,12 @@ class GetTimeRequest final : public ProtoMessage { class GetTimeResponse final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 37; - static constexpr uint8_t ESTIMATED_SIZE = 24; + static constexpr uint8_t ESTIMATED_SIZE = 14; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "get_time_response"; } #endif uint32_t epoch_seconds{0}; - const uint8_t *timezone{nullptr}; - uint16_t timezone_len{0}; + StringRef timezone{}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; #endif @@ -1310,7 +1302,7 @@ class ExecuteServiceArgument final : public ProtoDecodableMessage { bool bool_{false}; int32_t legacy_int{0}; float float_{0.0f}; - std::string string_{}; + StringRef string_{}; int32_t int_{0}; FixedVector bool_array{}; FixedVector int_array{}; @@ -1499,7 +1491,7 @@ class ClimateStateResponse final : public StateResponseProtoMessage { class ClimateCommandRequest final : public CommandProtoMessage { public: static constexpr uint8_t MESSAGE_TYPE = 48; - static constexpr uint8_t ESTIMATED_SIZE = 104; + static constexpr uint8_t ESTIMATED_SIZE = 84; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "climate_command_request"; } #endif @@ -1516,13 +1508,11 @@ class ClimateCommandRequest final : public CommandProtoMessage { bool has_swing_mode{false}; enums::ClimateSwingMode swing_mode{}; bool has_custom_fan_mode{false}; - const uint8_t *custom_fan_mode{nullptr}; - uint16_t custom_fan_mode_len{0}; + StringRef custom_fan_mode{}; bool has_preset{false}; enums::ClimatePreset preset{}; bool has_custom_preset{false}; - const uint8_t *custom_preset{nullptr}; - uint16_t custom_preset_len{0}; + StringRef custom_preset{}; bool has_target_humidity{false}; float target_humidity{0.0f}; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -1695,12 +1685,11 @@ class SelectStateResponse final : public StateResponseProtoMessage { class SelectCommandRequest final : public CommandProtoMessage { public: static constexpr uint8_t MESSAGE_TYPE = 54; - static constexpr uint8_t ESTIMATED_SIZE = 28; + static constexpr uint8_t ESTIMATED_SIZE = 18; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "select_command_request"; } #endif - const uint8_t *state{nullptr}; - uint16_t state_len{0}; + StringRef state{}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; #endif @@ -1756,7 +1745,7 @@ class SirenCommandRequest final : public CommandProtoMessage { bool has_state{false}; bool state{false}; bool has_tone{false}; - std::string tone{}; + StringRef tone{}; bool has_duration{false}; uint32_t duration{0}; bool has_volume{false}; @@ -1817,7 +1806,7 @@ class LockCommandRequest final : public CommandProtoMessage { #endif enums::LockCommand command{}; bool has_code{false}; - std::string code{}; + StringRef code{}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; #endif @@ -1927,7 +1916,7 @@ class MediaPlayerCommandRequest final : public CommandProtoMessage { bool has_volume{false}; float volume{0.0f}; bool has_media_url{false}; - std::string media_url{}; + StringRef media_url{}; bool has_announcement{false}; bool announcement{false}; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -2503,8 +2492,8 @@ class VoiceAssistantResponse final : public ProtoDecodableMessage { }; class VoiceAssistantEventData final : public ProtoDecodableMessage { public: - std::string name{}; - std::string value{}; + StringRef name{}; + StringRef value{}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; #endif @@ -2562,8 +2551,8 @@ class VoiceAssistantTimerEventResponse final : public ProtoDecodableMessage { const char *message_name() const override { return "voice_assistant_timer_event_response"; } #endif enums::VoiceAssistantTimerEvent event_type{}; - std::string timer_id{}; - std::string name{}; + StringRef timer_id{}; + StringRef name{}; uint32_t total_seconds{0}; uint32_t seconds_left{0}; bool is_active{false}; @@ -2582,9 +2571,9 @@ class VoiceAssistantAnnounceRequest final : public ProtoDecodableMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "voice_assistant_announce_request"; } #endif - std::string media_id{}; - std::string text{}; - std::string preannounce_media_id{}; + StringRef media_id{}; + StringRef text{}; + StringRef preannounce_media_id{}; bool start_conversation{false}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; @@ -2627,13 +2616,13 @@ class VoiceAssistantWakeWord final : public ProtoMessage { }; class VoiceAssistantExternalWakeWord final : public ProtoDecodableMessage { public: - std::string id{}; - std::string wake_word{}; + StringRef id{}; + StringRef wake_word{}; std::vector trained_languages{}; - std::string model_type{}; + StringRef model_type{}; uint32_t model_size{0}; - std::string model_hash{}; - std::string url{}; + StringRef model_hash{}; + StringRef url{}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; #endif @@ -2734,7 +2723,7 @@ class AlarmControlPanelCommandRequest final : public CommandProtoMessage { const char *message_name() const override { return "alarm_control_panel_command_request"; } #endif enums::AlarmControlPanelStateCommand command{}; - std::string code{}; + StringRef code{}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; #endif @@ -2791,7 +2780,7 @@ class TextCommandRequest final : public CommandProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "text_command_request"; } #endif - std::string state{}; + StringRef state{}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; #endif diff --git a/esphome/components/api/api_pb2_dump.cpp b/esphome/components/api/api_pb2_dump.cpp index 9faf39e29e..567f10fcc0 100644 --- a/esphome/components/api/api_pb2_dump.cpp +++ b/esphome/components/api/api_pb2_dump.cpp @@ -736,7 +736,7 @@ template<> const char *proto_enum_to_string(enums: void HelloRequest::dump_to(std::string &out) const { MessageDumpHelper helper(out, "HelloRequest"); out.append(" client_info: "); - out.append(format_hex_pretty(this->client_info, this->client_info_len)); + out.append("'").append(this->client_info.c_str(), this->client_info.size()).append("'"); out.append("\n"); dump_field(out, "api_version_major", this->api_version_major); dump_field(out, "api_version_minor", this->api_version_minor); @@ -752,7 +752,7 @@ void HelloResponse::dump_to(std::string &out) const { void AuthenticationRequest::dump_to(std::string &out) const { MessageDumpHelper helper(out, "AuthenticationRequest"); out.append(" password: "); - out.append(format_hex_pretty(this->password, this->password_len)); + out.append("'").append(this->password.c_str(), this->password.size()).append("'"); out.append("\n"); } void AuthenticationResponse::dump_to(std::string &out) const { @@ -965,7 +965,7 @@ void FanCommandRequest::dump_to(std::string &out) const { dump_field(out, "speed_level", this->speed_level); dump_field(out, "has_preset_mode", this->has_preset_mode); out.append(" preset_mode: "); - out.append(format_hex_pretty(this->preset_mode, this->preset_mode_len)); + out.append("'").append(this->preset_mode.c_str(), this->preset_mode.size()).append("'"); out.append("\n"); #ifdef USE_DEVICES dump_field(out, "device_id", this->device_id); @@ -1043,7 +1043,7 @@ void LightCommandRequest::dump_to(std::string &out) const { dump_field(out, "flash_length", this->flash_length); dump_field(out, "has_effect", this->has_effect); out.append(" effect: "); - out.append(format_hex_pretty(this->effect, this->effect_len)); + out.append("'").append(this->effect.c_str(), this->effect.size()).append("'"); out.append("\n"); #ifdef USE_DEVICES dump_field(out, "device_id", this->device_id); @@ -1205,7 +1205,9 @@ void HomeassistantActionResponse::dump_to(std::string &out) const { MessageDumpHelper helper(out, "HomeassistantActionResponse"); dump_field(out, "call_id", this->call_id); dump_field(out, "success", this->success); - dump_field(out, "error_message", this->error_message); + out.append(" error_message: "); + out.append("'").append(this->error_message.c_str(), this->error_message.size()).append("'"); + out.append("\n"); #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON out.append(" response_data: "); out.append(format_hex_pretty(this->response_data, this->response_data_len)); @@ -1226,13 +1228,13 @@ void SubscribeHomeAssistantStateResponse::dump_to(std::string &out) const { void HomeAssistantStateResponse::dump_to(std::string &out) const { MessageDumpHelper helper(out, "HomeAssistantStateResponse"); out.append(" entity_id: "); - out.append(format_hex_pretty(this->entity_id, this->entity_id_len)); + out.append("'").append(this->entity_id.c_str(), this->entity_id.size()).append("'"); out.append("\n"); out.append(" state: "); - out.append(format_hex_pretty(this->state, this->state_len)); + out.append("'").append(this->state.c_str(), this->state.size()).append("'"); out.append("\n"); out.append(" attribute: "); - out.append(format_hex_pretty(this->attribute, this->attribute_len)); + out.append("'").append(this->attribute.c_str(), this->attribute.size()).append("'"); out.append("\n"); } #endif @@ -1241,7 +1243,7 @@ void GetTimeResponse::dump_to(std::string &out) const { MessageDumpHelper helper(out, "GetTimeResponse"); dump_field(out, "epoch_seconds", this->epoch_seconds); out.append(" timezone: "); - out.append(format_hex_pretty(this->timezone, this->timezone_len)); + out.append("'").append(this->timezone.c_str(), this->timezone.size()).append("'"); out.append("\n"); } #ifdef USE_API_USER_DEFINED_ACTIONS @@ -1266,7 +1268,9 @@ void ExecuteServiceArgument::dump_to(std::string &out) const { dump_field(out, "bool_", this->bool_); dump_field(out, "legacy_int", this->legacy_int); dump_field(out, "float_", this->float_); - dump_field(out, "string_", this->string_); + out.append(" string_: "); + out.append("'").append(this->string_.c_str(), this->string_.size()).append("'"); + out.append("\n"); dump_field(out, "int_", this->int_); for (const auto it : this->bool_array) { dump_field(out, "bool_array", static_cast(it), 4); @@ -1424,13 +1428,13 @@ void ClimateCommandRequest::dump_to(std::string &out) const { dump_field(out, "swing_mode", static_cast(this->swing_mode)); dump_field(out, "has_custom_fan_mode", this->has_custom_fan_mode); out.append(" custom_fan_mode: "); - out.append(format_hex_pretty(this->custom_fan_mode, this->custom_fan_mode_len)); + out.append("'").append(this->custom_fan_mode.c_str(), this->custom_fan_mode.size()).append("'"); out.append("\n"); dump_field(out, "has_preset", this->has_preset); dump_field(out, "preset", static_cast(this->preset)); dump_field(out, "has_custom_preset", this->has_custom_preset); out.append(" custom_preset: "); - out.append(format_hex_pretty(this->custom_preset, this->custom_preset_len)); + out.append("'").append(this->custom_preset.c_str(), this->custom_preset.size()).append("'"); out.append("\n"); dump_field(out, "has_target_humidity", this->has_target_humidity); dump_field(out, "target_humidity", this->target_humidity); @@ -1558,7 +1562,7 @@ void SelectCommandRequest::dump_to(std::string &out) const { MessageDumpHelper helper(out, "SelectCommandRequest"); dump_field(out, "key", this->key); out.append(" state: "); - out.append(format_hex_pretty(this->state, this->state_len)); + out.append("'").append(this->state.c_str(), this->state.size()).append("'"); out.append("\n"); #ifdef USE_DEVICES dump_field(out, "device_id", this->device_id); @@ -1599,7 +1603,9 @@ void SirenCommandRequest::dump_to(std::string &out) const { dump_field(out, "has_state", this->has_state); dump_field(out, "state", this->state); dump_field(out, "has_tone", this->has_tone); - dump_field(out, "tone", this->tone); + out.append(" tone: "); + out.append("'").append(this->tone.c_str(), this->tone.size()).append("'"); + out.append("\n"); dump_field(out, "has_duration", this->has_duration); dump_field(out, "duration", this->duration); dump_field(out, "has_volume", this->has_volume); @@ -1641,7 +1647,9 @@ void LockCommandRequest::dump_to(std::string &out) const { dump_field(out, "key", this->key); dump_field(out, "command", static_cast(this->command)); dump_field(out, "has_code", this->has_code); - dump_field(out, "code", this->code); + out.append(" code: "); + out.append("'").append(this->code.c_str(), this->code.size()).append("'"); + out.append("\n"); #ifdef USE_DEVICES dump_field(out, "device_id", this->device_id); #endif @@ -1719,7 +1727,9 @@ void MediaPlayerCommandRequest::dump_to(std::string &out) const { dump_field(out, "has_volume", this->has_volume); dump_field(out, "volume", this->volume); dump_field(out, "has_media_url", this->has_media_url); - dump_field(out, "media_url", this->media_url); + out.append(" media_url: "); + out.append("'").append(this->media_url.c_str(), this->media_url.size()).append("'"); + out.append("\n"); dump_field(out, "has_announcement", this->has_announcement); dump_field(out, "announcement", this->announcement); #ifdef USE_DEVICES @@ -1949,8 +1959,12 @@ void VoiceAssistantResponse::dump_to(std::string &out) const { } void VoiceAssistantEventData::dump_to(std::string &out) const { MessageDumpHelper helper(out, "VoiceAssistantEventData"); - dump_field(out, "name", this->name); - dump_field(out, "value", this->value); + out.append(" name: "); + out.append("'").append(this->name.c_str(), this->name.size()).append("'"); + out.append("\n"); + out.append(" value: "); + out.append("'").append(this->value.c_str(), this->value.size()).append("'"); + out.append("\n"); } void VoiceAssistantEventResponse::dump_to(std::string &out) const { MessageDumpHelper helper(out, "VoiceAssistantEventResponse"); @@ -1975,17 +1989,27 @@ void VoiceAssistantAudio::dump_to(std::string &out) const { void VoiceAssistantTimerEventResponse::dump_to(std::string &out) const { MessageDumpHelper helper(out, "VoiceAssistantTimerEventResponse"); dump_field(out, "event_type", static_cast(this->event_type)); - dump_field(out, "timer_id", this->timer_id); - dump_field(out, "name", this->name); + out.append(" timer_id: "); + out.append("'").append(this->timer_id.c_str(), this->timer_id.size()).append("'"); + out.append("\n"); + out.append(" name: "); + out.append("'").append(this->name.c_str(), this->name.size()).append("'"); + out.append("\n"); dump_field(out, "total_seconds", this->total_seconds); dump_field(out, "seconds_left", this->seconds_left); dump_field(out, "is_active", this->is_active); } void VoiceAssistantAnnounceRequest::dump_to(std::string &out) const { MessageDumpHelper helper(out, "VoiceAssistantAnnounceRequest"); - dump_field(out, "media_id", this->media_id); - dump_field(out, "text", this->text); - dump_field(out, "preannounce_media_id", this->preannounce_media_id); + out.append(" media_id: "); + out.append("'").append(this->media_id.c_str(), this->media_id.size()).append("'"); + out.append("\n"); + out.append(" text: "); + out.append("'").append(this->text.c_str(), this->text.size()).append("'"); + out.append("\n"); + out.append(" preannounce_media_id: "); + out.append("'").append(this->preannounce_media_id.c_str(), this->preannounce_media_id.size()).append("'"); + out.append("\n"); dump_field(out, "start_conversation", this->start_conversation); } void VoiceAssistantAnnounceFinished::dump_to(std::string &out) const { dump_field(out, "success", this->success); } @@ -1999,15 +2023,25 @@ void VoiceAssistantWakeWord::dump_to(std::string &out) const { } void VoiceAssistantExternalWakeWord::dump_to(std::string &out) const { MessageDumpHelper helper(out, "VoiceAssistantExternalWakeWord"); - dump_field(out, "id", this->id); - dump_field(out, "wake_word", this->wake_word); + out.append(" id: "); + out.append("'").append(this->id.c_str(), this->id.size()).append("'"); + out.append("\n"); + out.append(" wake_word: "); + out.append("'").append(this->wake_word.c_str(), this->wake_word.size()).append("'"); + out.append("\n"); for (const auto &it : this->trained_languages) { dump_field(out, "trained_languages", it, 4); } - dump_field(out, "model_type", this->model_type); + out.append(" model_type: "); + out.append("'").append(this->model_type.c_str(), this->model_type.size()).append("'"); + out.append("\n"); dump_field(out, "model_size", this->model_size); - dump_field(out, "model_hash", this->model_hash); - dump_field(out, "url", this->url); + out.append(" model_hash: "); + out.append("'").append(this->model_hash.c_str(), this->model_hash.size()).append("'"); + out.append("\n"); + out.append(" url: "); + out.append("'").append(this->url.c_str(), this->url.size()).append("'"); + out.append("\n"); } void VoiceAssistantConfigurationRequest::dump_to(std::string &out) const { MessageDumpHelper helper(out, "VoiceAssistantConfigurationRequest"); @@ -2066,7 +2100,9 @@ void AlarmControlPanelCommandRequest::dump_to(std::string &out) const { MessageDumpHelper helper(out, "AlarmControlPanelCommandRequest"); dump_field(out, "key", this->key); dump_field(out, "command", static_cast(this->command)); - dump_field(out, "code", this->code); + out.append(" code: "); + out.append("'").append(this->code.c_str(), this->code.size()).append("'"); + out.append("\n"); #ifdef USE_DEVICES dump_field(out, "device_id", this->device_id); #endif @@ -2103,7 +2139,9 @@ void TextStateResponse::dump_to(std::string &out) const { void TextCommandRequest::dump_to(std::string &out) const { MessageDumpHelper helper(out, "TextCommandRequest"); dump_field(out, "key", this->key); - dump_field(out, "state", this->state); + out.append(" state: "); + out.append("'").append(this->state.c_str(), this->state.size()).append("'"); + out.append("\n"); #ifdef USE_DEVICES dump_field(out, "device_id", this->device_id); #endif diff --git a/esphome/components/voice_assistant/voice_assistant.cpp b/esphome/components/voice_assistant/voice_assistant.cpp index b946e3b38a..9bb5393be2 100644 --- a/esphome/components/voice_assistant/voice_assistant.cpp +++ b/esphome/components/voice_assistant/voice_assistant.cpp @@ -627,9 +627,9 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { ESP_LOGD(TAG, "Assist Pipeline running"); #ifdef USE_MEDIA_PLAYER this->started_streaming_tts_ = false; - for (auto arg : msg.data) { + for (const auto &arg : msg.data) { if (arg.name == "url") { - this->tts_response_url_ = std::move(arg.value); + this->tts_response_url_ = arg.value; } } #endif @@ -648,9 +648,9 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { break; case api::enums::VOICE_ASSISTANT_STT_END: { std::string text; - for (auto arg : msg.data) { + for (const auto &arg : msg.data) { if (arg.name == "text") { - text = std::move(arg.value); + text = arg.value; } } if (text.empty()) { @@ -693,9 +693,9 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { break; } case api::enums::VOICE_ASSISTANT_INTENT_END: { - for (auto arg : msg.data) { + for (const auto &arg : msg.data) { if (arg.name == "conversation_id") { - this->conversation_id_ = std::move(arg.value); + this->conversation_id_ = arg.value; } else if (arg.name == "continue_conversation") { this->continue_conversation_ = (arg.value == "1"); } @@ -705,9 +705,9 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { } case api::enums::VOICE_ASSISTANT_TTS_START: { std::string text; - for (auto arg : msg.data) { + for (const auto &arg : msg.data) { if (arg.name == "text") { - text = std::move(arg.value); + text = arg.value; } } if (text.empty()) { @@ -731,9 +731,9 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { } case api::enums::VOICE_ASSISTANT_TTS_END: { std::string url; - for (auto arg : msg.data) { + for (const auto &arg : msg.data) { if (arg.name == "url") { - url = std::move(arg.value); + url = arg.value; } } if (url.empty()) { @@ -778,11 +778,11 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { case api::enums::VOICE_ASSISTANT_ERROR: { std::string code = ""; std::string message = ""; - for (auto arg : msg.data) { + for (const auto &arg : msg.data) { if (arg.name == "code") { - code = std::move(arg.value); + code = arg.value; } else if (arg.name == "message") { - message = std::move(arg.value); + message = arg.value; } } if (code == "wake-word-timeout" || code == "wake_word_detection_aborted" || code == "no_wake_word") { diff --git a/script/api_protobuf/api_protobuf.py b/script/api_protobuf/api_protobuf.py index cb09ef7050..f22b248747 100755 --- a/script/api_protobuf/api_protobuf.py +++ b/script/api_protobuf/api_protobuf.py @@ -374,20 +374,16 @@ def create_field_type_info( # Traditional fixed array approach with copy return FixedArrayBytesType(field, fixed_size) - # Check for pointer_to_buffer option on string fields - if field.type == 9: - has_pointer_to_buffer = get_field_opt(field, pb.pointer_to_buffer, False) - - if has_pointer_to_buffer: - # Zero-copy pointer approach for strings - return PointerToBytesBufferType(field, None) - # Special handling for bytes fields if field.type == 12: return BytesType(field, needs_decode, needs_encode) # Special handling for string fields if field.type == 9: + # For SOURCE_CLIENT only messages (decode but no encode), use StringRef + # for zero-copy access to the receive buffer + if needs_decode and not needs_encode: + return PointerToStringBufferType(field, None) return StringType(field, needs_decode, needs_encode) validate_field_type(field.type, field.name) @@ -840,8 +836,8 @@ class BytesType(TypeInfo): return self.calculate_field_id_size() + 8 # field ID + 8 bytes typical bytes -class PointerToBytesBufferType(TypeInfo): - """Type for bytes fields that use pointer_to_buffer option for zero-copy.""" +class PointerToBufferTypeBase(TypeInfo): + """Base class for pointer_to_buffer types (bytes and strings) for zero-copy decoding.""" @classmethod def can_use_dump_field(cls) -> bool: @@ -851,29 +847,34 @@ class PointerToBytesBufferType(TypeInfo): self, field: descriptor.FieldDescriptorProto, size: int | None = None ) -> None: super().__init__(field) - # Size is not used for pointer_to_buffer - we always use size_t for length self.array_size = 0 @property - def cpp_type(self) -> str: - return "const uint8_t*" + def decode_length(self) -> str | None: + # This is handled in decode_length_content + return None @property - def default_value(self) -> str: - return "nullptr" + def wire_type(self) -> WireType: + """Get the wire type for this field.""" + return WireType.LENGTH_DELIMITED # Uses wire type 2 - @property - def reference_type(self) -> str: - return "const uint8_t*" + def get_estimated_size(self) -> int: + # field ID + length varint + typical data (assume small for pointer fields) + return self.calculate_field_id_size() + 2 + 16 - @property - def const_reference_type(self) -> str: - return "const uint8_t*" + +class PointerToBytesBufferType(PointerToBufferTypeBase): + """Type for bytes fields that use pointer_to_buffer option for zero-copy.""" + + cpp_type = "const uint8_t*" + default_value = "nullptr" + reference_type = "const uint8_t*" + const_reference_type = "const uint8_t*" @property def public_content(self) -> list[str]: # Use uint16_t for length - max packet size is well below 65535 - # Add pointer and length fields return [ f"const uint8_t* {self.field_name}{{nullptr}};", f"uint16_t {self.field_name}_len{{0}};", @@ -885,24 +886,12 @@ class PointerToBytesBufferType(TypeInfo): @property def decode_length_content(self) -> str | None: - # Decode directly stores the pointer to avoid allocation return f"""case {self.number}: {{ - // Use raw data directly to avoid allocation this->{self.field_name} = value.data(); this->{self.field_name}_len = value.size(); break; }}""" - @property - def decode_length(self) -> str | None: - # This is handled in decode_length_content - return None - - @property - def wire_type(self) -> WireType: - """Get the wire type for this bytes field.""" - return WireType.LENGTH_DELIMITED # Uses wire type 2 - def dump(self, name: str) -> str: return ( f"format_hex_pretty(this->{self.field_name}, this->{self.field_name}_len)" @@ -910,7 +899,6 @@ class PointerToBytesBufferType(TypeInfo): @property def dump_content(self) -> str: - # Custom dump that doesn't use dump_field template return ( f'out.append(" {self.name}: ");\n' + f"out.append({self.dump(self.field_name)});\n" @@ -918,11 +906,48 @@ class PointerToBytesBufferType(TypeInfo): ) def get_size_calculation(self, name: str, force: bool = False) -> str: - return f"size.add_length({self.number}, this->{self.field_name}_len);" + return f"size.add_length({self.calculate_field_id_size()}, this->{self.field_name}_len);" - def get_estimated_size(self) -> int: - # field ID + length varint + typical data (assume small for pointer fields) - return self.calculate_field_id_size() + 2 + 16 + +class PointerToStringBufferType(PointerToBufferTypeBase): + """Type for string fields that use pointer_to_buffer option for zero-copy. + + Uses StringRef instead of separate pointer and length fields. + """ + + cpp_type = "StringRef" + default_value = "" + reference_type = "StringRef &" + const_reference_type = "const StringRef &" + + @property + def public_content(self) -> list[str]: + return [f"StringRef {self.field_name}{{}};"] + + @property + def encode_content(self) -> str: + return f"buffer.encode_string({self.number}, this->{self.field_name});" + + @property + def decode_length_content(self) -> str | None: + return f"""case {self.number}: {{ + this->{self.field_name} = StringRef(reinterpret_cast(value.data()), value.size()); + break; + }}""" + + def dump(self, name: str) -> str: + return f'out.append("\'").append(this->{self.field_name}.c_str(), this->{self.field_name}.size()).append("\'");' + + @property + def dump_content(self) -> str: + return ( + f'out.append(" {self.name}: ");\n' + + f"{self.dump(self.field_name)}\n" + + 'out.append("\\n");' + ) + + def get_size_calculation(self, name: str, force: bool = False) -> str: + return f"size.add_length({self.calculate_field_id_size()}, this->{self.field_name}.size());" class FixedArrayBytesType(TypeInfo): From 763515d3a19561f76461f004a9631bab9493bcba Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Fri, 2 Jan 2026 14:47:14 -0500 Subject: [PATCH 100/302] [core] Remove unused USE_ESP32_FRAMEWORK_ARDUINO ifdefs (#12813) Co-authored-by: Claude --- esphome/components/wifi/wifi_component.h | 10 ---------- esphome/core/hal.h | 10 +--------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index ff2bfe12a4..5bf1f444e8 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -12,12 +12,6 @@ #include #include -#ifdef USE_ESP32_FRAMEWORK_ARDUINO -#include -#include -#include -#endif - #ifdef USE_LIBRETINY #include #endif @@ -578,10 +572,6 @@ class WiFiComponent : public Component { static void s_wifi_scan_done_callback(void *arg, STATUS status); #endif -#ifdef USE_ESP32_FRAMEWORK_ARDUINO - void wifi_event_callback_(arduino_event_id_t event, arduino_event_info_t info); - void wifi_scan_done_callback_(); -#endif #ifdef USE_ESP32 void wifi_process_event_(IDFWiFiEvent *data); #endif diff --git a/esphome/core/hal.h b/esphome/core/hal.h index 0ccf21ad83..1a4230e421 100644 --- a/esphome/core/hal.h +++ b/esphome/core/hal.h @@ -3,20 +3,12 @@ #include #include "gpio.h" -#if defined(USE_ESP32_FRAMEWORK_ESP_IDF) +#if defined(USE_ESP32) #include #ifndef PROGMEM #define PROGMEM #endif -#elif defined(USE_ESP32_FRAMEWORK_ARDUINO) - -#include - -#ifndef PROGMEM -#define PROGMEM -#endif - #elif defined(USE_ESP8266) #include From 087f521b198eb39ccb7b95f1106ab5b9a395d78a Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Fri, 2 Jan 2026 15:58:53 -0500 Subject: [PATCH 101/302] [ultrasonic] Use interrupt-based measurement for reliability (#12617) Co-authored-by: Claude --- esphome/components/ultrasonic/sensor.py | 2 +- .../ultrasonic/ultrasonic_sensor.cpp | 94 +++++++++++++------ .../components/ultrasonic/ultrasonic_sensor.h | 42 +++++---- 3 files changed, 89 insertions(+), 49 deletions(-) diff --git a/esphome/components/ultrasonic/sensor.py b/esphome/components/ultrasonic/sensor.py index 937d9a5261..d341acb9d1 100644 --- a/esphome/components/ultrasonic/sensor.py +++ b/esphome/components/ultrasonic/sensor.py @@ -28,7 +28,7 @@ CONFIG_SCHEMA = ( ) .extend( { - cv.Required(CONF_TRIGGER_PIN): pins.gpio_output_pin_schema, + cv.Required(CONF_TRIGGER_PIN): pins.internal_gpio_output_pin_schema, cv.Required(CONF_ECHO_PIN): pins.internal_gpio_input_pin_schema, cv.Optional(CONF_TIMEOUT, default="2m"): cv.distance, cv.Optional( diff --git a/esphome/components/ultrasonic/ultrasonic_sensor.cpp b/esphome/components/ultrasonic/ultrasonic_sensor.cpp index e864ea6419..184d93f189 100644 --- a/esphome/components/ultrasonic/ultrasonic_sensor.cpp +++ b/esphome/components/ultrasonic/ultrasonic_sensor.cpp @@ -1,64 +1,96 @@ #include "ultrasonic_sensor.h" -#include "esphome/core/log.h" #include "esphome/core/hal.h" +#include "esphome/core/log.h" -namespace esphome { -namespace ultrasonic { +namespace esphome::ultrasonic { static const char *const TAG = "ultrasonic.sensor"; +static constexpr uint32_t DEBOUNCE_US = 50; // Ignore edges within 50us (noise filtering) +static constexpr uint32_t TIMEOUT_MARGIN_US = 1000; // Extra margin for sensor processing time + +void IRAM_ATTR UltrasonicSensorStore::gpio_intr(UltrasonicSensorStore *arg) { + uint32_t now = micros(); + if (!arg->echo_start || (now - arg->echo_start_us) <= DEBOUNCE_US) { + arg->echo_start_us = now; + arg->echo_start = true; + } else { + arg->echo_end_us = now; + arg->echo_end = true; + } +} + +void IRAM_ATTR UltrasonicSensorComponent::send_trigger_pulse_() { + InterruptLock lock; + this->store_.echo_start_us = 0; + this->store_.echo_end_us = 0; + this->store_.echo_start = false; + this->store_.echo_end = false; + this->trigger_pin_isr_.digital_write(true); + delayMicroseconds(this->pulse_time_us_); + this->trigger_pin_isr_.digital_write(false); + this->measurement_pending_ = true; + this->measurement_start_us_ = micros(); +} + void UltrasonicSensorComponent::setup() { this->trigger_pin_->setup(); this->trigger_pin_->digital_write(false); + this->trigger_pin_isr_ = this->trigger_pin_->to_isr(); this->echo_pin_->setup(); - // isr is faster to access - echo_isr_ = echo_pin_->to_isr(); + this->echo_pin_->attach_interrupt(UltrasonicSensorStore::gpio_intr, &this->store_, gpio::INTERRUPT_ANY_EDGE); } + void UltrasonicSensorComponent::update() { - this->trigger_pin_->digital_write(true); - delayMicroseconds(this->pulse_time_us_); - this->trigger_pin_->digital_write(false); + if (this->measurement_pending_) { + return; + } + this->send_trigger_pulse_(); +} - const uint32_t start = micros(); - while (micros() - start < timeout_us_ && echo_isr_.digital_read()) - ; - while (micros() - start < timeout_us_ && !echo_isr_.digital_read()) - ; - const uint32_t pulse_start = micros(); - while (micros() - start < timeout_us_ && echo_isr_.digital_read()) - ; - const uint32_t pulse_end = micros(); +void UltrasonicSensorComponent::loop() { + if (!this->measurement_pending_) { + return; + } - ESP_LOGV(TAG, "Echo took %" PRIu32 "µs", pulse_end - pulse_start); - - if (pulse_end - start >= timeout_us_) { - ESP_LOGD(TAG, "'%s' - Distance measurement timed out!", this->name_.c_str()); - this->publish_state(NAN); - } else { - float result = UltrasonicSensorComponent::us_to_m(pulse_end - pulse_start); + if (this->store_.echo_end) { + uint32_t pulse_duration = this->store_.echo_end_us - this->store_.echo_start_us; + ESP_LOGV(TAG, "Echo took %" PRIu32 "us", pulse_duration); + float result = UltrasonicSensorComponent::us_to_m(pulse_duration); ESP_LOGD(TAG, "'%s' - Got distance: %.3f m", this->name_.c_str(), result); this->publish_state(result); + this->measurement_pending_ = false; + return; + } + + uint32_t elapsed = micros() - this->measurement_start_us_; + if (elapsed >= this->timeout_us_ + TIMEOUT_MARGIN_US) { + ESP_LOGD(TAG, + "'%s' - Timeout after %" PRIu32 "us (measurement_start=%" PRIu32 ", echo_start=%" PRIu32 + ", echo_end=%" PRIu32 ")", + this->name_.c_str(), elapsed, this->measurement_start_us_, this->store_.echo_start_us, + this->store_.echo_end_us); + this->publish_state(NAN); + this->measurement_pending_ = false; } } + void UltrasonicSensorComponent::dump_config() { LOG_SENSOR("", "Ultrasonic Sensor", this); LOG_PIN(" Echo Pin: ", this->echo_pin_); LOG_PIN(" Trigger Pin: ", this->trigger_pin_); ESP_LOGCONFIG(TAG, - " Pulse time: %" PRIu32 " µs\n" - " Timeout: %" PRIu32 " µs", + " Pulse time: %" PRIu32 " us\n" + " Timeout: %" PRIu32 " us", this->pulse_time_us_, this->timeout_us_); LOG_UPDATE_INTERVAL(this); } + float UltrasonicSensorComponent::us_to_m(uint32_t us) { const float speed_sound_m_per_s = 343.0f; const float time_s = us / 1e6f; const float total_dist = time_s * speed_sound_m_per_s; return total_dist / 2.0f; } -float UltrasonicSensorComponent::get_setup_priority() const { return setup_priority::DATA; } -void UltrasonicSensorComponent::set_pulse_time_us(uint32_t pulse_time_us) { this->pulse_time_us_ = pulse_time_us; } -void UltrasonicSensorComponent::set_timeout_us(uint32_t timeout_us) { this->timeout_us_ = timeout_us; } -} // namespace ultrasonic -} // namespace esphome +} // namespace esphome::ultrasonic diff --git a/esphome/components/ultrasonic/ultrasonic_sensor.h b/esphome/components/ultrasonic/ultrasonic_sensor.h index 1a255d6122..e2266543ce 100644 --- a/esphome/components/ultrasonic/ultrasonic_sensor.h +++ b/esphome/components/ultrasonic/ultrasonic_sensor.h @@ -6,41 +6,49 @@ #include -namespace esphome { -namespace ultrasonic { +namespace esphome::ultrasonic { + +struct UltrasonicSensorStore { + static void gpio_intr(UltrasonicSensorStore *arg); + + volatile uint32_t echo_start_us{0}; + volatile uint32_t echo_end_us{0}; + volatile bool echo_start{false}; + volatile bool echo_end{false}; +}; class UltrasonicSensorComponent : public sensor::Sensor, public PollingComponent { public: - void set_trigger_pin(GPIOPin *trigger_pin) { trigger_pin_ = trigger_pin; } - void set_echo_pin(InternalGPIOPin *echo_pin) { echo_pin_ = echo_pin; } + void set_trigger_pin(InternalGPIOPin *trigger_pin) { this->trigger_pin_ = trigger_pin; } + void set_echo_pin(InternalGPIOPin *echo_pin) { this->echo_pin_ = echo_pin; } /// Set the timeout for waiting for the echo in µs. - void set_timeout_us(uint32_t timeout_us); + void set_timeout_us(uint32_t timeout_us) { this->timeout_us_ = timeout_us; } - // ========== INTERNAL METHODS ========== - // (In most use cases you won't need these) - /// Set up pins and register interval. void setup() override; + void loop() override; void dump_config() override; - void update() override; - float get_setup_priority() const override; + float get_setup_priority() const override { return setup_priority::DATA; } /// Set the time in µs the trigger pin should be enabled for in µs, defaults to 10µs (for HC-SR04) - void set_pulse_time_us(uint32_t pulse_time_us); + void set_pulse_time_us(uint32_t pulse_time_us) { this->pulse_time_us_ = pulse_time_us; } protected: /// Helper function to convert the specified echo duration in µs to meters. static float us_to_m(uint32_t us); - /// Helper function to convert the specified distance in meters to the echo duration in µs. + void send_trigger_pulse_(); - GPIOPin *trigger_pin_; + InternalGPIOPin *trigger_pin_; + ISRInternalGPIOPin trigger_pin_isr_; InternalGPIOPin *echo_pin_; - ISRInternalGPIOPin echo_isr_; - uint32_t timeout_us_{}; /// 2 meters. + UltrasonicSensorStore store_; + uint32_t timeout_us_{}; uint32_t pulse_time_us_{}; + + uint32_t measurement_start_us_{0}; + bool measurement_pending_{false}; }; -} // namespace ultrasonic -} // namespace esphome +} // namespace esphome::ultrasonic From c6713eaccb76cb2ce485ad429df0c948ad1c88bd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 13:07:11 -1000 Subject: [PATCH 102/302] [web_server] Fix URL collisions with UTF-8 names and sub-devices (#12627) --- esphome/components/web_server/web_server.cpp | 315 +++++++++++++----- esphome/components/web_server/web_server.h | 40 +-- .../components/web_server/web_server_v1.cpp | 44 ++- esphome/components/web_server_idf/utils.cpp | 6 +- esphome/components/web_server_idf/utils.h | 4 + .../web_server_idf/web_server_idf.cpp | 17 +- esphome/config_validation.py | 39 +++ esphome/core/config.py | 8 +- esphome/core/entity_base.h | 2 + tests/unit_tests/test_config_validation.py | 57 ++++ 10 files changed, 413 insertions(+), 119 deletions(-) diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index f613d6bc36..7c015adcf7 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -45,62 +45,144 @@ static constexpr size_t PSTR_LOCAL_SIZE = 18; #define PSTR_LOCAL(mode_s) ESPHOME_strncpy_P(buf, (ESPHOME_PGM_P) ((mode_s)), PSTR_LOCAL_SIZE - 1) // Parse URL and return match info -static UrlMatch match_url(const char *url_ptr, size_t url_len, bool only_domain) { - UrlMatch match{}; +// URL formats (disambiguated by HTTP method for 3-segment case): +// GET /{domain}/{entity_name} - main device state +// POST /{domain}/{entity_name}/{action} - main device action +// GET /{domain}/{device_name}/{entity_name} - sub-device state (USE_DEVICES only) +// POST /{domain}/{device_name}/{entity_name}/{action} - sub-device action (USE_DEVICES only) +static UrlMatch match_url(const char *url_ptr, size_t url_len, bool only_domain, bool is_post = false) { + // URL must start with '/' and have content after it + if (url_len < 2 || url_ptr[0] != '/') + return UrlMatch{}; - // URL must start with '/' - if (url_len < 2 || url_ptr[0] != '/') { - return match; - } - - // Skip leading '/' - const char *start = url_ptr + 1; + const char *p = url_ptr + 1; const char *end = url_ptr + url_len; - // Find domain (everything up to next '/' or end) - const char *domain_end = (const char *) memchr(start, '/', end - start); - if (!domain_end) { - // No second slash found - original behavior returns invalid - return match; - } + // Helper to find next segment: returns pointer after '/' or nullptr if no more slashes + auto next_segment = [&end](const char *start) -> const char * { + const char *slash = (const char *) memchr(start, '/', end - start); + return slash ? slash + 1 : nullptr; + }; - // Set domain - match.domain = start; - match.domain_len = domain_end - start; + // Helper to make StringRef from segment start to next segment (or end) + auto make_ref = [&end](const char *start, const char *next_start) -> StringRef { + return StringRef(start, (next_start ? next_start - 1 : end) - start); + }; + + // Parse domain segment + const char *s1 = p; + const char *s2 = next_segment(s1); + + // Must have domain with trailing slash + if (!s2) + return UrlMatch{}; + + UrlMatch match{}; + match.domain = make_ref(s1, s2); match.valid = true; - if (only_domain) { + if (only_domain || s2 >= end) return match; - } - // Parse ID if present - if (domain_end + 1 >= end) { - return match; // Nothing after domain slash - } + // Parse remaining segments only when needed + const char *s3 = next_segment(s2); + const char *s4 = s3 ? next_segment(s3) : nullptr; - const char *id_start = domain_end + 1; - const char *id_end = (const char *) memchr(id_start, '/', end - id_start); + StringRef seg2 = make_ref(s2, s3); + StringRef seg3 = s3 ? make_ref(s3, s4) : StringRef(); + StringRef seg4 = s4 ? make_ref(s4, nullptr) : StringRef(); - if (!id_end) { - // No more slashes, entire remaining string is ID - match.id = id_start; - match.id_len = end - id_start; - return match; - } + // Reject empty segments + if (seg2.empty() || (s3 && seg3.empty()) || (s4 && seg4.empty())) + return UrlMatch{}; - // Set ID - match.id = id_start; - match.id_len = id_end - id_start; - - // Parse method if present - if (id_end + 1 < end) { - match.method = id_end + 1; - match.method_len = end - (id_end + 1); + // Interpret based on segment count + if (!s3) { + // 1 segment after domain: /{domain}/{entity} + match.id = seg2; + } else if (!s4) { + // 2 segments after domain: /{domain}/{X}/{Y} + // HTTP method disambiguates: GET = device/entity, POST = entity/action + if (is_post) { + match.id = seg2; + match.method = seg3; + return match; + } +#ifdef USE_DEVICES + match.device_name = seg2; + match.id = seg3; +#else + return UrlMatch{}; // 3-segment GET not supported without USE_DEVICES +#endif + } else { + // 3 segments after domain: /{domain}/{device}/{entity}/{action} +#ifdef USE_DEVICES + if (!is_post) { + return UrlMatch{}; // 4-segment GET not supported (action requires POST) + } + match.device_name = seg2; + match.id = seg3; + match.method = seg4; +#else + return UrlMatch{}; // Not supported without USE_DEVICES +#endif } return match; } +EntityMatchResult UrlMatch::match_entity(EntityBase *entity) const { + EntityMatchResult result{false, this->method.empty()}; + +#ifdef USE_DEVICES + Device *entity_device = entity->get_device(); + bool url_has_device = !this->device_name.empty(); + bool entity_has_device = (entity_device != nullptr); + + // Device matching: URL device segment must match entity's device + if (url_has_device != entity_has_device) { + return result; // Mismatch: one has device, other doesn't + } + if (url_has_device && this->device_name != entity_device->get_name()) { + return result; // Device name doesn't match + } +#endif + + // Try matching by entity name (new format) + if (this->id == entity->get_name()) { + result.matched = true; + return result; + } + + // Fall back to object_id (deprecated format) + char object_id_buf[OBJECT_ID_MAX_LEN]; + StringRef object_id = entity->get_object_id_to(object_id_buf); + if (this->id == object_id) { + result.matched = true; + // Log deprecation warning +#ifdef USE_DEVICES + Device *device = entity->get_device(); + if (device != nullptr) { + ESP_LOGW(TAG, + "Deprecated URL format: /%.*s/%.*s/%.*s - use entity name '/%.*s/%s/%s' instead. " + "Object ID URLs will be removed in 2026.7.0.", + (int) this->domain.size(), this->domain.c_str(), (int) this->device_name.size(), + this->device_name.c_str(), (int) this->id.size(), this->id.c_str(), (int) this->domain.size(), + this->domain.c_str(), device->get_name(), entity->get_name().c_str()); + } else +#endif + { + ESP_LOGW(TAG, + "Deprecated URL format: /%.*s/%.*s - use entity name '/%.*s/%s' instead. " + "Object ID URLs will be removed in 2026.7.0.", + (int) this->domain.size(), this->domain.c_str(), (int) this->id.size(), this->id.c_str(), + (int) this->domain.size(), this->domain.c_str(), entity->get_name().c_str()); + } + } + + return result; +} + #if !defined(USE_ESP32) && defined(USE_ARDUINO) // helper for allowing only unique entries in the queue void DeferredUpdateEventSource::deq_push_back_with_dedup_(void *source, message_generator_t *message_generator) { @@ -397,15 +479,53 @@ void WebServer::handle_js_request(AsyncWebServerRequest *request) { #endif // Helper functions to reduce code size by avoiding macro expansion +// Build unique id as: {domain}/{device_name}/{entity_name} or {domain}/{entity_name} +// Uses names (not object_id) to avoid UTF-8 collision issues static void set_json_id(JsonObject &root, EntityBase *obj, const char *prefix, JsonDetail start_config) { - char id_buf[160]; // prefix + dash + object_id (up to 128) + null - size_t len = strlen(prefix); - memcpy(id_buf, prefix, len); // NOLINT(bugprone-not-null-terminated-result) - null added by write_object_id_to - id_buf[len++] = '-'; - obj->write_object_id_to(id_buf + len, sizeof(id_buf) - len); + const StringRef &name = obj->get_name(); + size_t prefix_len = strlen(prefix); + size_t name_len = name.size(); + +#ifdef USE_DEVICES + Device *device = obj->get_device(); + const char *device_name = device ? device->get_name() : nullptr; + size_t device_len = device_name ? strlen(device_name) : 0; +#endif + + // Build id into stack buffer - ArduinoJson copies the string + // Format: {prefix}/{device?}/{name} + // Buffer size guaranteed by schema validation (NAME_MAX_LENGTH=120): + // With devices: domain(20) + "/" + device(120) + "/" + name(120) + null = 263, rounded up to 280 for safety margin + // Without devices: domain(20) + "/" + name(120) + null = 142, rounded up to 150 for safety margin +#ifdef USE_DEVICES + char id_buf[280]; +#else + char id_buf[150]; +#endif + char *p = id_buf; + memcpy(p, prefix, prefix_len); + p += prefix_len; + *p++ = '/'; +#ifdef USE_DEVICES + if (device_name) { + memcpy(p, device_name, device_len); + p += device_len; + *p++ = '/'; + } +#endif + memcpy(p, name.c_str(), name_len); + p[name_len] = '\0'; + root[ESPHOME_F("id")] = id_buf; + if (start_config == DETAIL_ALL) { - root[ESPHOME_F("name")] = obj->get_name(); + root[ESPHOME_F("domain")] = prefix; + root[ESPHOME_F("name")] = name; +#ifdef USE_DEVICES + if (device_name) { + root[ESPHOME_F("device")] = device_name; + } +#endif root[ESPHOME_F("icon")] = obj->get_icon_ref(); root[ESPHOME_F("entity_category")] = obj->get_entity_category(); bool is_disabled = obj->is_disabled_by_default(); @@ -444,10 +564,11 @@ void WebServer::on_sensor_update(sensor::Sensor *obj) { } void WebServer::handle_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (sensor::Sensor *obj : App.get_sensors()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; // Note: request->method() is always HTTP_GET here (canHandle ensures this) - if (match.method_empty()) { + if (entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->sensor_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); @@ -490,10 +611,11 @@ void WebServer::on_text_sensor_update(text_sensor::TextSensor *obj) { } void WebServer::handle_text_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (text_sensor::TextSensor *obj : App.get_text_sensors()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; // Note: request->method() is always HTTP_GET here (canHandle ensures this) - if (match.method_empty()) { + if (entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->text_sensor_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); @@ -532,10 +654,11 @@ void WebServer::on_switch_update(switch_::Switch *obj) { } void WebServer::handle_switch_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (switch_::Switch *obj : App.get_switches()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->switch_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); @@ -601,9 +724,10 @@ std::string WebServer::switch_json_(switch_::Switch *obj, bool value, JsonDetail #ifdef USE_BUTTON void WebServer::handle_button_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (button::Button *obj : App.get_buttons()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->button_json_(obj, detail); request->send(200, "application/json", data.c_str()); @@ -645,10 +769,11 @@ void WebServer::on_binary_sensor_update(binary_sensor::BinarySensor *obj) { } void WebServer::handle_binary_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (binary_sensor::BinarySensor *obj : App.get_binary_sensors()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; // Note: request->method() is always HTTP_GET here (canHandle ensures this) - if (match.method_empty()) { + if (entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->binary_sensor_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); @@ -686,10 +811,11 @@ void WebServer::on_fan_update(fan::Fan *obj) { } void WebServer::handle_fan_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (fan::Fan *obj : App.get_fans()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->fan_json_(obj, detail); request->send(200, "application/json", data.c_str()); @@ -766,10 +892,11 @@ void WebServer::on_light_update(light::LightState *obj) { } void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (light::LightState *obj : App.get_lights()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->light_json_(obj, detail); request->send(200, "application/json", data.c_str()); @@ -844,10 +971,11 @@ void WebServer::on_cover_update(cover::Cover *obj) { } void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (cover::Cover *obj : App.get_covers()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->cover_json_(obj, detail); request->send(200, "application/json", data.c_str()); @@ -932,10 +1060,11 @@ void WebServer::on_number_update(number::Number *obj) { } void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (auto *obj : App.get_numbers()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->number_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); @@ -999,9 +1128,10 @@ void WebServer::on_date_update(datetime::DateEntity *obj) { } void WebServer::handle_date_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (auto *obj : App.get_dates()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->date_json_(obj, detail); request->send(200, "application/json", data.c_str()); @@ -1062,9 +1192,10 @@ void WebServer::on_time_update(datetime::TimeEntity *obj) { } void WebServer::handle_time_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (auto *obj : App.get_times()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->time_json_(obj, detail); request->send(200, "application/json", data.c_str()); @@ -1124,9 +1255,10 @@ void WebServer::on_datetime_update(datetime::DateTimeEntity *obj) { } void WebServer::handle_datetime_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (auto *obj : App.get_datetimes()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->datetime_json_(obj, detail); request->send(200, "application/json", data.c_str()); @@ -1188,10 +1320,11 @@ void WebServer::on_text_update(text::Text *obj) { } void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (auto *obj : App.get_texts()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->text_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); @@ -1244,10 +1377,11 @@ void WebServer::on_select_update(select::Select *obj) { } void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (auto *obj : App.get_selects()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->select_json_(obj, obj->has_state() ? obj->current_option() : "", detail); request->send(200, "application/json", data.c_str()); @@ -1301,10 +1435,11 @@ void WebServer::on_climate_update(climate::Climate *obj) { } void WebServer::handle_climate_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (auto *obj : App.get_climates()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->climate_json_(obj, detail); request->send(200, "application/json", data.c_str()); @@ -1451,10 +1586,11 @@ void WebServer::on_lock_update(lock::Lock *obj) { } void WebServer::handle_lock_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (lock::Lock *obj : App.get_locks()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->lock_json_(obj, obj->state, detail); request->send(200, "application/json", data.c_str()); @@ -1525,10 +1661,11 @@ void WebServer::on_valve_update(valve::Valve *obj) { } void WebServer::handle_valve_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (valve::Valve *obj : App.get_valves()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->valve_json_(obj, detail); request->send(200, "application/json", data.c_str()); @@ -1609,10 +1746,11 @@ void WebServer::on_alarm_control_panel_update(alarm_control_panel::AlarmControlP } void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (alarm_control_panel::AlarmControlPanel *obj : App.get_alarm_control_panels()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->alarm_control_panel_json_(obj, obj->get_state(), detail); request->send(200, "application/json", data.c_str()); @@ -1690,11 +1828,12 @@ void WebServer::on_event(event::Event *obj) { void WebServer::handle_event_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (event::Event *obj : App.get_events()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; // Note: request->method() is always HTTP_GET here (canHandle ensures this) - if (match.method_empty()) { + if (entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->event_json_(obj, "", detail); request->send(200, "application/json", data.c_str()); @@ -1759,10 +1898,11 @@ void WebServer::on_update(update::UpdateEntity *obj) { } void WebServer::handle_update_request(AsyncWebServerRequest *request, const UrlMatch &match) { for (update::UpdateEntity *obj : App.get_updates()) { - if (!match.id_equals_entity(obj)) + auto entity_match = match.match_entity(obj); + if (!entity_match.matched) continue; - if (request->method() == HTTP_GET && match.method_empty()) { + if (request->method() == HTTP_GET && entity_match.action_is_empty) { auto detail = get_request_detail(request); std::string data = this->update_json_(obj, detail); request->send(200, "application/json", data.c_str()); @@ -1973,7 +2113,8 @@ void WebServer::handleRequest(AsyncWebServerRequest *request) { #endif // Parse URL for component routing - UrlMatch match = match_url(url.c_str(), url.length(), false); + // Pass HTTP method to disambiguate 3-segment URLs (GET=sub-device state, POST=main device action) + UrlMatch match = match_url(url.c_str(), url.length(), false, request->method() == HTTP_POST); // Route to appropriate handler based on domain // NOLINTNEXTLINE(readability-simplify-boolean-expr) diff --git a/esphome/components/web_server/web_server.h b/esphome/components/web_server/web_server.h index b9e852c745..3e1dd867c6 100644 --- a/esphome/components/web_server/web_server.h +++ b/esphome/components/web_server/web_server.h @@ -35,33 +35,29 @@ extern const size_t ESPHOME_WEBSERVER_JS_INCLUDE_SIZE; namespace esphome::web_server { +/// Result of matching a URL against an entity +struct EntityMatchResult { + bool matched; ///< True if entity matched the URL + bool action_is_empty; ///< True if no action/method segment in URL +}; + /// Internal helper struct that is used to parse incoming URLs struct UrlMatch { - const char *domain; ///< Pointer to domain within URL, for example "sensor" - const char *id; ///< Pointer to id within URL, for example "living_room_fan" - const char *method; ///< Pointer to method within URL, for example "turn_on" - uint8_t domain_len; ///< Length of domain string - uint8_t id_len; ///< Length of id string - uint8_t method_len; ///< Length of method string - bool valid; ///< Whether this match is valid + StringRef domain; ///< Domain within URL, for example "sensor" + StringRef id; ///< Entity name/id within URL, for example "Temperature" + StringRef method; ///< Method within URL, for example "turn_on" +#ifdef USE_DEVICES + StringRef device_name; ///< Device name within URL, empty for main device +#endif + bool valid{false}; ///< Whether this match is valid // Helper methods for string comparisons - bool domain_equals(const char *str) const { - return domain && domain_len == strlen(str) && memcmp(domain, str, domain_len) == 0; - } + bool domain_equals(const char *str) const { return this->domain == str; } + bool method_equals(const char *str) const { return this->method == str; } - bool id_equals_entity(EntityBase *entity) const { - // Get object_id with zero heap allocation - char object_id_buf[OBJECT_ID_MAX_LEN]; - StringRef object_id = entity->get_object_id_to(object_id_buf); - return id && id_len == object_id.size() && memcmp(id, object_id.c_str(), id_len) == 0; - } - - bool method_equals(const char *str) const { - return method && method_len == strlen(str) && memcmp(method, str, method_len) == 0; - } - - bool method_empty() const { return method_len == 0; } + /// Match entity by name first, then fall back to object_id with deprecation warning + /// Returns EntityMatchResult with match status and whether action segment is empty + EntityMatchResult match_entity(EntityBase *entity) const; }; #ifdef USE_WEBSERVER_SORTING diff --git a/esphome/components/web_server/web_server_v1.cpp b/esphome/components/web_server/web_server_v1.cpp index e27306ad78..a21e9cb9ff 100644 --- a/esphome/components/web_server/web_server_v1.cpp +++ b/esphome/components/web_server/web_server_v1.cpp @@ -5,6 +5,29 @@ namespace esphome::web_server { +// Write HTML-escaped text to stream (escapes ", &, <, >) +static void write_html_escaped(AsyncResponseStream *stream, const char *text) { + for (const char *p = text; *p; ++p) { + switch (*p) { + case '"': + stream->print("""); + break; + case '&': + stream->print("&"); + break; + case '<': + stream->print("<"); + break; + case '>': + stream->print(">"); + break; + default: + stream->write(*p); + break; + } + } +} + void write_row(AsyncResponseStream *stream, EntityBase *obj, const std::string &klass, const std::string &action, const std::function &action_func = nullptr) { stream->print("print("-"); char object_id_buf[OBJECT_ID_MAX_LEN]; stream->print(obj->get_object_id_to(object_id_buf).c_str()); + // Add data attributes for hierarchical URL support + stream->print("\" data-domain=\""); + stream->print(klass.c_str()); + stream->print("\" data-name=\""); + write_html_escaped(stream, obj->get_name().c_str()); +#ifdef USE_DEVICES + Device *device = obj->get_device(); + if (device != nullptr) { + stream->print("\" data-device=\""); + write_html_escaped(stream, device->get_name()); + } +#endif stream->print("\">"); - stream->print(obj->get_name().c_str()); +#ifdef USE_DEVICES + if (device != nullptr) { + stream->print("["); + write_html_escaped(stream, device->get_name()); + stream->print("] "); + } +#endif + write_html_escaped(stream, obj->get_name().c_str()); stream->print(""); stream->print(action.c_str()); if (action_func) { diff --git a/esphome/components/web_server_idf/utils.cpp b/esphome/components/web_server_idf/utils.cpp index d5d34b520b..f27814062c 100644 --- a/esphome/components/web_server_idf/utils.cpp +++ b/esphome/components/web_server_idf/utils.cpp @@ -13,7 +13,8 @@ namespace web_server_idf { static const char *const TAG = "web_server_idf_utils"; -void url_decode(char *str) { +size_t url_decode(char *str) { + char *start = str; char *ptr = str, buf; for (; *str; str++, ptr++) { if (*str == '%') { @@ -31,7 +32,8 @@ void url_decode(char *str) { *ptr = *str; } } - *ptr = *str; + *ptr = '\0'; + return ptr - start; } bool request_has_header(httpd_req_t *req, const char *name) { return httpd_req_get_hdr_value_len(req, name); } diff --git a/esphome/components/web_server_idf/utils.h b/esphome/components/web_server_idf/utils.h index f70a5f0760..3a86aec7ac 100644 --- a/esphome/components/web_server_idf/utils.h +++ b/esphome/components/web_server_idf/utils.h @@ -8,6 +8,10 @@ namespace esphome { namespace web_server_idf { +/// Decode URL-encoded string in-place (e.g., %20 -> space, + -> space) +/// Returns the new length of the decoded string +size_t url_decode(char *str); + bool request_has_header(httpd_req_t *req, const char *name); optional request_get_header(httpd_req_t *req, const char *name); optional request_get_url_query(httpd_req_t *req); diff --git a/esphome/components/web_server_idf/web_server_idf.cpp b/esphome/components/web_server_idf/web_server_idf.cpp index 3d76b86a14..5062aa1e6c 100644 --- a/esphome/components/web_server_idf/web_server_idf.cpp +++ b/esphome/components/web_server_idf/web_server_idf.cpp @@ -247,11 +247,20 @@ optional AsyncWebServerRequest::get_header(const char *name) const } std::string AsyncWebServerRequest::url() const { - auto *str = strchr(this->req_->uri, '?'); - if (str == nullptr) { - return this->req_->uri; + auto *query_start = strchr(this->req_->uri, '?'); + std::string result; + if (query_start == nullptr) { + result = this->req_->uri; + } else { + result = std::string(this->req_->uri, query_start - this->req_->uri); } - return std::string(this->req_->uri, str - this->req_->uri); + // Decode URL-encoded characters in-place (e.g., %20 -> space) + // This matches AsyncWebServer behavior on Arduino + if (!result.empty()) { + size_t new_len = url_decode(&result[0]); + result.resize(new_len); + } + return result; } std::string AsyncWebServerRequest::host() const { return this->get_header("Host").value(); } diff --git a/esphome/config_validation.py b/esphome/config_validation.py index d085206ee8..b0da88c50d 100644 --- a/esphome/config_validation.py +++ b/esphome/config_validation.py @@ -1981,6 +1981,26 @@ MQTT_COMMAND_COMPONENT_SCHEMA = MQTT_COMPONENT_SCHEMA.extend( ) +def _validate_no_slash(value): + """Validate that a name does not contain '/' characters. + + The '/' character is used as a path separator in web server URLs, + so it cannot be used in entity or device names. + """ + if "/" in value: + raise Invalid( + f"Name cannot contain '/' character (used as URL path separator): {value}" + ) + return value + + +# Maximum length for entity, device, and area names +# This ensures web server URL IDs fit in a 280-byte buffer: +# domain(20) + "/" + device(120) + "/" + name(120) + null = 263 bytes +# Note: Must be < 255 because web_server UrlMatch uses uint8_t for length fields +NAME_MAX_LENGTH = 120 + + def _validate_entity_name(value): value = string(value) try: @@ -1991,9 +2011,28 @@ def _validate_entity_name(value): requires_friendly_name( "Name cannot be None when esphome->friendly_name is not set!" )(value) + if value is not None: + # Validate length for web server URL compatibility + if len(value) > NAME_MAX_LENGTH: + raise Invalid( + f"Name is too long ({len(value)} chars). " + f"Maximum length is {NAME_MAX_LENGTH} characters." + ) + # Validate no '/' in name for web server URL compatibility + _validate_no_slash(value) return value +def string_no_slash(value): + """Validate a string that cannot contain '/' characters. + + Used for device and area names where '/' is reserved as a URL path separator. + Use with cv.Length() to also enforce maximum length. + """ + value = string(value) + return _validate_no_slash(value) + + ENTITY_BASE_SCHEMA = Schema( { Optional(CONF_NAME): _validate_entity_name, diff --git a/esphome/core/config.py b/esphome/core/config.py index 5e32b9380d..f9c3011507 100644 --- a/esphome/core/config.py +++ b/esphome/core/config.py @@ -186,14 +186,14 @@ else: AREA_SCHEMA = cv.Schema( { cv.GenerateID(CONF_ID): cv.declare_id(Area), - cv.Required(CONF_NAME): cv.string, + cv.Required(CONF_NAME): cv.All(cv.string_no_slash, cv.Length(max=120)), } ) DEVICE_SCHEMA = cv.Schema( { cv.GenerateID(CONF_ID): cv.declare_id(Device), - cv.Required(CONF_NAME): cv.string, + cv.Required(CONF_NAME): cv.All(cv.string_no_slash, cv.Length(max=120)), cv.Optional(CONF_AREA_ID): cv.use_id(Area), } ) @@ -207,7 +207,9 @@ CONFIG_SCHEMA = cv.All( cv.Schema( { cv.Required(CONF_NAME): cv.valid_name, - cv.Optional(CONF_FRIENDLY_NAME, ""): cv.All(cv.string, cv.Length(max=120)), + cv.Optional(CONF_FRIENDLY_NAME, ""): cv.All( + cv.string_no_slash, cv.Length(max=120) + ), cv.Optional(CONF_AREA): validate_area_config, cv.Optional(CONF_COMMENT): cv.All(cv.string, cv.Length(max=255)), cv.Required(CONF_BUILD_PATH): cv.string, diff --git a/esphome/core/entity_base.h b/esphome/core/entity_base.h index 93f989934a..a5c69f132c 100644 --- a/esphome/core/entity_base.h +++ b/esphome/core/entity_base.h @@ -100,6 +100,8 @@ class EntityBase { return this->device_->get_device_id(); } void set_device(Device *device) { this->device_ = device; } + // Get the device this entity belongs to (nullptr if main device) + Device *get_device() const { return this->device_; } #endif // Check if this entity has state diff --git a/tests/unit_tests/test_config_validation.py b/tests/unit_tests/test_config_validation.py index c9d7b7486e..94224f2364 100644 --- a/tests/unit_tests/test_config_validation.py +++ b/tests/unit_tests/test_config_validation.py @@ -502,3 +502,60 @@ def test_only_with_user_value_overrides_default() -> None: result = schema({"mqtt_id": "custom_id"}) assert result.get("mqtt_id") == "custom_id" + + +@pytest.mark.parametrize("value", ("hello", "Hello World", "test_name", "温度")) +def test_string_no_slash__valid(value: str) -> None: + actual = config_validation.string_no_slash(value) + assert actual == value + + +@pytest.mark.parametrize("value", ("has/slash", "a/b/c", "/leading", "trailing/")) +def test_string_no_slash__slash_rejected(value: str) -> None: + with pytest.raises(Invalid, match="cannot contain '/' character"): + config_validation.string_no_slash(value) + + +def test_string_no_slash__long_string_allowed() -> None: + # string_no_slash doesn't enforce length - use cv.Length() separately + long_value = "x" * 200 + assert config_validation.string_no_slash(long_value) == long_value + + +def test_string_no_slash__empty() -> None: + assert config_validation.string_no_slash("") == "" + + +@pytest.mark.parametrize("value", ("Temperature", "Living Room Light", "温度传感器")) +def test_validate_entity_name__valid(value: str) -> None: + actual = config_validation._validate_entity_name(value) + assert actual == value + + +def test_validate_entity_name__slash_rejected() -> None: + with pytest.raises(Invalid, match="cannot contain '/' character"): + config_validation._validate_entity_name("has/slash") + + +def test_validate_entity_name__max_length() -> None: + # 120 chars should pass + assert config_validation._validate_entity_name("x" * 120) == "x" * 120 + + # 121 chars should fail + with pytest.raises(Invalid, match="too long.*121 chars.*Maximum.*120"): + config_validation._validate_entity_name("x" * 121) + + +def test_validate_entity_name__none_without_friendly_name() -> None: + # When name is "None" and friendly_name is not set, it should fail + CORE.friendly_name = None + with pytest.raises(Invalid, match="friendly_name is not set"): + config_validation._validate_entity_name("None") + + +def test_validate_entity_name__none_with_friendly_name() -> None: + # When name is "None" but friendly_name is set, it should return None + CORE.friendly_name = "My Device" + result = config_validation._validate_entity_name("None") + assert result is None + CORE.friendly_name = None # Reset From 5bb9ffa0cbb28b3875b06df1913f8b6015e852c6 Mon Sep 17 00:00:00 2001 From: esphomebot Date: Sat, 3 Jan 2026 12:14:11 +1300 Subject: [PATCH 103/302] Update webserver local assets to 20260102-230255 (#12817) --- .../components/web_server/server_index_v2.h | 1276 +-- .../components/web_server/server_index_v3.h | 8086 +++++++++-------- 2 files changed, 4690 insertions(+), 4672 deletions(-) diff --git a/esphome/components/web_server/server_index_v2.h b/esphome/components/web_server/server_index_v2.h index b2d204c9e7..4f2ea8a6ab 100644 --- a/esphome/components/web_server/server_index_v2.h +++ b/esphome/components/web_server/server_index_v2.h @@ -6,644 +6,652 @@ #include "esphome/core/hal.h" -namespace esphome::web_server { +namespace esphome { +namespace web_server { const uint8_t INDEX_GZ[] PROGMEM = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xcd, 0x7d, 0xdb, 0x72, 0xdb, 0xc6, 0xb6, 0xe0, 0xf3, - 0xe4, 0x2b, 0x20, 0x44, 0x5b, 0x41, 0x6f, 0x36, 0x21, 0x92, 0x92, 0x6c, 0x19, 0x54, 0x93, 0x5b, 0x96, 0x9d, 0xed, - 0x64, 0xfb, 0x16, 0xcb, 0x4e, 0x76, 0xc2, 0x68, 0x4b, 0x10, 0xd1, 0x24, 0x3a, 0x06, 0xd1, 0x0c, 0xd0, 0xa4, 0xa4, - 0x90, 0x38, 0x35, 0x1f, 0x30, 0x55, 0x53, 0x35, 0x4f, 0xf3, 0x32, 0x35, 0xe7, 0x61, 0x3e, 0x62, 0x9e, 0xcf, 0xa7, - 0x9c, 0x1f, 0x98, 0xf9, 0x84, 0xa9, 0xd5, 0x17, 0xa0, 0xc1, 0x8b, 0xac, 0x5c, 0xce, 0x39, 0x53, 0x2e, 0xdb, 0x44, - 0xa3, 0x2f, 0xab, 0x57, 0xaf, 0x5e, 0xf7, 0x6e, 0x9c, 0xec, 0x44, 0x7c, 0x28, 0xee, 0xa6, 0xd4, 0x89, 0xc5, 0x24, - 0xe9, 0x9d, 0xe8, 0x7f, 0x69, 0x18, 0xf5, 0x4e, 0x12, 0x96, 0x7e, 0x74, 0x32, 0x9a, 0x10, 0x36, 0xe4, 0xa9, 0x13, - 0x67, 0x74, 0x44, 0xa2, 0x50, 0x84, 0x01, 0x9b, 0x84, 0x63, 0xea, 0xec, 0xf7, 0x4e, 0x26, 0x54, 0x84, 0xce, 0x30, - 0x0e, 0xb3, 0x9c, 0x0a, 0xf2, 0xe1, 0xfd, 0x97, 0xcd, 0xe3, 0xde, 0x49, 0x3e, 0xcc, 0xd8, 0x54, 0x38, 0xd0, 0x25, - 0x99, 0xf0, 0x68, 0x96, 0xd0, 0xde, 0xfe, 0xfe, 0xcd, 0xcd, 0x8d, 0xff, 0x53, 0xfe, 0xd9, 0x90, 0xa7, 0xb9, 0x70, - 0x5e, 0x92, 0x1b, 0x96, 0x46, 0xfc, 0x06, 0x33, 0x41, 0x5e, 0xfa, 0xe7, 0x71, 0x18, 0xf1, 0x9b, 0x77, 0x9c, 0x8b, - 0xbd, 0x3d, 0x4f, 0x3d, 0xde, 0x9d, 0x9d, 0x9f, 0x13, 0x42, 0xe6, 0x9c, 0x45, 0x4e, 0x6b, 0xb9, 0xac, 0x0a, 0xfd, - 0x34, 0x14, 0x6c, 0x4e, 0x55, 0x13, 0xb4, 0xb7, 0xe7, 0x86, 0x11, 0x9f, 0x0a, 0x1a, 0x9d, 0x8b, 0xbb, 0x84, 0x9e, - 0xc7, 0x94, 0x8a, 0xdc, 0x65, 0xa9, 0xf3, 0x8c, 0x0f, 0x67, 0x13, 0x9a, 0x0a, 0x7f, 0x9a, 0x71, 0xc1, 0x01, 0x92, - 0xbd, 0x3d, 0x37, 0xa3, 0xd3, 0x24, 0x1c, 0x52, 0x78, 0x7f, 0x76, 0x7e, 0x5e, 0xb5, 0xa8, 0x2a, 0xe1, 0x5c, 0x90, - 0xf3, 0xbb, 0xc9, 0x35, 0x4f, 0x3c, 0x84, 0x43, 0x41, 0x52, 0x7a, 0xe3, 0x7c, 0x47, 0xc3, 0x8f, 0xaf, 0xc2, 0x69, - 0x77, 0x98, 0x84, 0x79, 0xee, 0xdc, 0x88, 0x85, 0x9c, 0x42, 0x36, 0x1b, 0x0a, 0x9e, 0x79, 0x02, 0x53, 0xcc, 0xd0, - 0x82, 0x8d, 0x3c, 0x11, 0xb3, 0xdc, 0xbf, 0xdc, 0x1d, 0xe6, 0xf9, 0x3b, 0x9a, 0xcf, 0x12, 0xb1, 0x4b, 0x76, 0x5a, - 0x98, 0xed, 0x10, 0x92, 0x0b, 0x24, 0xe2, 0x8c, 0xdf, 0x38, 0xcf, 0xb3, 0x8c, 0x67, 0x9e, 0x7b, 0x76, 0x7e, 0xae, - 0x6a, 0x38, 0x2c, 0x77, 0x52, 0x2e, 0x9c, 0xb2, 0xbf, 0xf0, 0x3a, 0xa1, 0xbe, 0xf3, 0x21, 0xa7, 0xce, 0xd5, 0x2c, - 0xcd, 0xc3, 0x11, 0x3d, 0x3b, 0x3f, 0xbf, 0x72, 0x78, 0xe6, 0x5c, 0x0d, 0xf3, 0xfc, 0xca, 0x61, 0x69, 0x2e, 0x68, - 0x18, 0xf9, 0x2e, 0xea, 0xca, 0xc1, 0x86, 0x79, 0xfe, 0x9e, 0xde, 0x0a, 0x22, 0xb0, 0x7c, 0x14, 0x84, 0x16, 0x63, - 0x2a, 0x9c, 0xbc, 0x9c, 0x97, 0x87, 0x16, 0x09, 0x15, 0x8e, 0x20, 0xf2, 0x3d, 0xef, 0x2a, 0xdc, 0x53, 0xf5, 0x28, - 0xba, 0x6c, 0xe4, 0x31, 0xb1, 0xb7, 0x27, 0x4a, 0x3c, 0x23, 0x35, 0x35, 0x87, 0x11, 0xba, 0x63, 0xca, 0xf6, 0xf6, - 0xa8, 0x9f, 0xd0, 0x74, 0x2c, 0x62, 0x42, 0x48, 0xbb, 0xcb, 0xf6, 0xf6, 0x3c, 0x41, 0x42, 0xe1, 0x8f, 0xa9, 0xf0, - 0x28, 0x42, 0xb8, 0x6a, 0xbd, 0xb7, 0xe7, 0x29, 0x24, 0x70, 0xa2, 0x10, 0x57, 0xc3, 0x31, 0xf2, 0x35, 0xf6, 0xcf, - 0xef, 0xd2, 0xa1, 0x67, 0xc3, 0x8f, 0x30, 0xdb, 0xdb, 0x0b, 0x85, 0x9f, 0x43, 0x8f, 0x58, 0x20, 0x54, 0x64, 0x54, - 0xcc, 0xb2, 0xd4, 0x11, 0x85, 0xe0, 0xe7, 0x22, 0x63, 0xe9, 0xd8, 0x43, 0x0b, 0x53, 0x66, 0x35, 0x2c, 0x0a, 0x05, - 0xee, 0x07, 0x41, 0x52, 0xd2, 0x83, 0x11, 0x6f, 0x84, 0x07, 0xab, 0xc8, 0x47, 0x4e, 0x4a, 0x88, 0x9b, 0xcb, 0xb6, - 0x6e, 0x3f, 0x0d, 0xd2, 0x86, 0xeb, 0x62, 0x05, 0x25, 0xce, 0x05, 0xc2, 0x6f, 0x88, 0x97, 0x62, 0xdf, 0xf7, 0x05, - 0x22, 0xbd, 0x85, 0xc1, 0x4a, 0x6a, 0xcd, 0xb3, 0x9f, 0x0e, 0x5a, 0x17, 0x81, 0xf0, 0x33, 0x1a, 0xcd, 0x86, 0xd4, - 0xf3, 0x18, 0xce, 0x71, 0x86, 0x48, 0x8f, 0x35, 0x3c, 0x4e, 0x7a, 0xb0, 0xdc, 0xbc, 0xbe, 0xd6, 0x84, 0xec, 0xb4, - 0x90, 0x86, 0x91, 0x1b, 0x00, 0x01, 0xc3, 0x1a, 0x1e, 0x4e, 0x88, 0x9b, 0xce, 0x26, 0xd7, 0x34, 0x73, 0xcb, 0x6a, - 0xdd, 0x1a, 0x59, 0xcc, 0x72, 0xea, 0x0c, 0xf3, 0xdc, 0x19, 0xcd, 0xd2, 0xa1, 0x60, 0x3c, 0x75, 0xdc, 0x06, 0x6f, - 0xb8, 0x8a, 0x1c, 0x4a, 0x6a, 0x70, 0x51, 0x81, 0xbc, 0x1c, 0x35, 0xd2, 0x41, 0xd6, 0x68, 0x5f, 0x60, 0x80, 0x12, - 0x75, 0x75, 0x7f, 0x1a, 0x01, 0x14, 0xa7, 0x30, 0xc7, 0x02, 0xbf, 0x17, 0x30, 0x4b, 0x39, 0x45, 0x26, 0xfa, 0xa9, - 0xbf, 0xbe, 0x51, 0x88, 0xf0, 0x27, 0xe1, 0xd4, 0xa3, 0xa4, 0x47, 0x25, 0x71, 0x85, 0xe9, 0x10, 0x60, 0xad, 0xad, - 0x5b, 0x9f, 0x06, 0xd4, 0xaf, 0x48, 0x0a, 0x05, 0xc2, 0x1f, 0xf1, 0xec, 0x79, 0x38, 0x8c, 0xa1, 0x5d, 0x49, 0x30, - 0x91, 0xd9, 0x6f, 0xc3, 0x8c, 0x86, 0x82, 0x3e, 0x4f, 0x28, 0x3c, 0x79, 0xae, 0x6c, 0xe9, 0x22, 0x9c, 0x93, 0x97, - 0x7e, 0xc2, 0xc4, 0x6b, 0x9e, 0x0e, 0x69, 0x37, 0xb7, 0xa8, 0x8b, 0xc1, 0xba, 0x9f, 0x0a, 0x91, 0xb1, 0xeb, 0x99, - 0xa0, 0x9e, 0x9b, 0x42, 0x0d, 0x17, 0xe7, 0x08, 0x33, 0x5f, 0xd0, 0x5b, 0x71, 0xc6, 0x53, 0x41, 0x53, 0x41, 0xa8, - 0x41, 0x2a, 0x4e, 0xfd, 0x70, 0x3a, 0xa5, 0x69, 0x74, 0x16, 0xb3, 0x24, 0xf2, 0x18, 0x2a, 0x50, 0x81, 0x63, 0x41, - 0x60, 0x8e, 0xa4, 0x97, 0x06, 0xf0, 0xcf, 0xf6, 0xd9, 0x78, 0x82, 0xf4, 0xe4, 0xa6, 0xa0, 0xc4, 0x75, 0xbb, 0x23, - 0x9e, 0x79, 0x7a, 0x06, 0x0e, 0x1f, 0x39, 0x02, 0xc6, 0x78, 0x37, 0x4b, 0x68, 0x8e, 0x68, 0x83, 0xb0, 0x72, 0x19, - 0x35, 0x82, 0x3f, 0x00, 0xc5, 0x17, 0xc8, 0x4b, 0x51, 0x90, 0x76, 0xe7, 0x61, 0xe6, 0x7c, 0xa7, 0x77, 0xd4, 0x33, - 0xc3, 0xcd, 0x86, 0x82, 0x3c, 0xf3, 0x45, 0x36, 0xcb, 0x05, 0x8d, 0xde, 0xdf, 0x4d, 0x69, 0x8e, 0x5f, 0x0b, 0x32, - 0x14, 0xfd, 0xa1, 0xf0, 0xe9, 0x64, 0x2a, 0xee, 0xce, 0x25, 0x63, 0x0c, 0x5c, 0x17, 0x47, 0x50, 0x33, 0xa3, 0xe1, - 0x10, 0x98, 0x99, 0xc6, 0xd6, 0x5b, 0x9e, 0xdc, 0x8d, 0x58, 0x92, 0x9c, 0xcf, 0xa6, 0x53, 0x9e, 0x09, 0xfc, 0x77, - 0xb2, 0x10, 0xbc, 0x42, 0x0d, 0xac, 0xe5, 0x22, 0xbf, 0x61, 0x62, 0x18, 0x7b, 0x02, 0x2d, 0x86, 0x61, 0x4e, 0x9d, - 0xa7, 0x9c, 0x27, 0x34, 0x84, 0x49, 0xa7, 0xfd, 0xd7, 0x22, 0x48, 0x67, 0x49, 0xd2, 0xbd, 0xce, 0x68, 0xf8, 0xb1, - 0x2b, 0x5f, 0xbf, 0xb9, 0xfe, 0x89, 0x0e, 0x45, 0x20, 0x7f, 0x9f, 0x66, 0x59, 0x78, 0x07, 0x15, 0x09, 0x81, 0x6a, - 0xfd, 0x34, 0xf8, 0xfa, 0xfc, 0xcd, 0x6b, 0x5f, 0x6d, 0x12, 0x36, 0xba, 0xf3, 0xd2, 0x72, 0xe3, 0xa5, 0x05, 0x1e, - 0x65, 0x7c, 0xb2, 0x32, 0xb4, 0xc2, 0x5a, 0xda, 0xdd, 0x02, 0x02, 0x25, 0xe9, 0x8e, 0xea, 0xda, 0x86, 0xe0, 0xb5, - 0xa4, 0x79, 0x78, 0x49, 0xcc, 0xb8, 0xb3, 0x24, 0x09, 0x54, 0xb1, 0x97, 0xa2, 0xfb, 0xa1, 0x15, 0xd9, 0xdd, 0x82, - 0x12, 0x09, 0xe7, 0x14, 0x24, 0x0c, 0xc0, 0x38, 0x0c, 0xc5, 0x30, 0x5e, 0x50, 0xd9, 0x59, 0x61, 0x20, 0xa6, 0x45, - 0x81, 0x6f, 0x4b, 0x7a, 0x17, 0x00, 0x88, 0x64, 0x54, 0x44, 0x2c, 0x97, 0x30, 0x61, 0x84, 0x7f, 0x20, 0x8b, 0xd0, - 0xcc, 0x27, 0xd8, 0x69, 0x61, 0xd8, 0x97, 0x81, 0xe2, 0x2e, 0x78, 0xc8, 0xd3, 0x39, 0xcd, 0x04, 0xcd, 0x82, 0xbf, - 0xe3, 0x8c, 0x8e, 0x12, 0x80, 0x62, 0xa7, 0x8d, 0xe3, 0x30, 0x3f, 0x8b, 0xc3, 0x74, 0x4c, 0xa3, 0xe0, 0x56, 0x14, - 0x58, 0x08, 0xe2, 0x8e, 0x58, 0x1a, 0x26, 0xec, 0x17, 0x1a, 0xb9, 0x5a, 0x1c, 0x3c, 0x77, 0xe8, 0xad, 0xa0, 0x69, - 0x94, 0x3b, 0x2f, 0xde, 0xbf, 0x7a, 0xa9, 0x17, 0xb2, 0x26, 0x21, 0xd0, 0x22, 0x9f, 0x4d, 0x69, 0xe6, 0x21, 0xac, - 0x25, 0xc4, 0x73, 0x26, 0xb9, 0xe3, 0xab, 0x70, 0xaa, 0x4a, 0x58, 0xfe, 0x61, 0x1a, 0x85, 0x82, 0xbe, 0xa5, 0x69, - 0xc4, 0xd2, 0x31, 0xd9, 0x69, 0xab, 0xf2, 0x38, 0xd4, 0x2f, 0xa2, 0xb2, 0xe8, 0x72, 0xf7, 0x79, 0x22, 0x27, 0x5e, - 0x3e, 0xce, 0x3c, 0x54, 0xe4, 0x22, 0x14, 0x6c, 0xe8, 0x84, 0x51, 0xf4, 0x55, 0xca, 0x04, 0x93, 0x00, 0x66, 0xb0, - 0x3e, 0x40, 0xa3, 0x54, 0xc9, 0x0a, 0x03, 0xb8, 0x87, 0xb0, 0xe7, 0x69, 0x09, 0x10, 0x23, 0xbd, 0x60, 0x7b, 0x7b, - 0x15, 0xbf, 0xef, 0xd3, 0x40, 0xbd, 0x24, 0x83, 0x0b, 0xe4, 0x4f, 0x67, 0x39, 0xac, 0xb4, 0x19, 0x02, 0xc4, 0x0b, - 0xbf, 0xce, 0x69, 0x36, 0xa7, 0x51, 0x49, 0x1d, 0xb9, 0x87, 0x16, 0x2b, 0x63, 0xe8, 0x7d, 0x21, 0xc8, 0xe0, 0xa2, - 0x6b, 0x33, 0x6e, 0xaa, 0x09, 0x3d, 0xe3, 0x53, 0x9a, 0x09, 0x46, 0xf3, 0x92, 0x97, 0x78, 0x20, 0x46, 0x4b, 0x7e, - 0x92, 0x13, 0x33, 0xbf, 0xa9, 0xc7, 0x30, 0x45, 0x35, 0x8e, 0x61, 0x24, 0xed, 0xf3, 0xb9, 0x14, 0x19, 0x39, 0x66, - 0x08, 0x0b, 0x05, 0x69, 0x8e, 0x50, 0x81, 0xb0, 0x30, 0xe0, 0x2a, 0x5e, 0xa4, 0x47, 0xbb, 0x03, 0x59, 0x4d, 0x7e, - 0x90, 0xb2, 0x1a, 0x38, 0x5a, 0x28, 0xe8, 0xde, 0x9e, 0x47, 0xfd, 0x92, 0x2a, 0xc8, 0x4e, 0x5b, 0xaf, 0x91, 0x85, - 0xac, 0x2d, 0x60, 0xc3, 0xc0, 0x02, 0x53, 0x84, 0x77, 0xa8, 0x9f, 0xf2, 0xd3, 0xe1, 0x90, 0xe6, 0x39, 0xcf, 0xf6, - 0xf6, 0x76, 0x64, 0xfd, 0x52, 0x9d, 0x80, 0x35, 0x7c, 0x73, 0x93, 0x56, 0x10, 0xa0, 0x4a, 0xc4, 0x6a, 0xc1, 0x20, - 0x40, 0x50, 0x49, 0x8d, 0xc3, 0xed, 0x1b, 0xcd, 0x23, 0x70, 0x2f, 0x2f, 0xdd, 0x86, 0xc0, 0x1a, 0x0d, 0x63, 0x6a, - 0x86, 0xbe, 0x7b, 0x46, 0x95, 0x6e, 0x25, 0x35, 0x8f, 0x35, 0xcc, 0xa8, 0x0d, 0xe4, 0x47, 0x74, 0xc4, 0x52, 0x6b, - 0xda, 0x35, 0x90, 0xb0, 0xc0, 0x39, 0x2a, 0xac, 0x05, 0xdd, 0xd8, 0xb5, 0x54, 0x6a, 0xd4, 0xca, 0x2d, 0xc6, 0x52, - 0x91, 0xb0, 0x96, 0x71, 0x40, 0x2f, 0x0a, 0x2c, 0x51, 0x6f, 0x66, 0x93, 0x49, 0x40, 0x07, 0xe2, 0xa2, 0xab, 0xdf, - 0x93, 0x5c, 0x61, 0x2e, 0xa3, 0x3f, 0xcf, 0x68, 0x2e, 0x14, 0x1d, 0x7b, 0x02, 0x67, 0x98, 0xa1, 0x02, 0xf6, 0xdb, - 0x88, 0x8d, 0x67, 0x19, 0xe8, 0x3b, 0xb0, 0x17, 0x69, 0x3a, 0x9b, 0x50, 0xf3, 0xb4, 0x09, 0xb6, 0x37, 0x53, 0x90, - 0x88, 0x39, 0xd0, 0xf4, 0xfd, 0xe4, 0x04, 0xb0, 0x0a, 0xb4, 0x5c, 0xfe, 0x60, 0x3a, 0xa9, 0x96, 0xb2, 0xd4, 0xd1, - 0x56, 0xd7, 0x44, 0x20, 0x2d, 0x91, 0x77, 0xda, 0x0a, 0x7c, 0x21, 0x2e, 0xc8, 0x4e, 0xab, 0xa4, 0x61, 0x8d, 0x55, - 0x05, 0x8e, 0x42, 0xe2, 0x1b, 0xd5, 0x15, 0x92, 0x02, 0xbe, 0x46, 0x2e, 0x7e, 0xbc, 0x46, 0xa9, 0x31, 0x19, 0x80, - 0xaa, 0xe1, 0xc7, 0x17, 0xdb, 0xc8, 0xc9, 0xf0, 0x03, 0x4f, 0xac, 0xbf, 0xab, 0xd8, 0xc6, 0xbc, 0xce, 0x36, 0x56, - 0xa6, 0xe1, 0x4e, 0xcb, 0x26, 0x6e, 0x49, 0x65, 0x7a, 0xa3, 0x57, 0xaf, 0x30, 0x93, 0xc0, 0x54, 0x53, 0xb2, 0xba, - 0x78, 0x1d, 0x4e, 0x68, 0xee, 0x51, 0x84, 0xb7, 0x55, 0x50, 0xe4, 0x09, 0x55, 0x2e, 0x2c, 0xc9, 0x99, 0x83, 0xe4, - 0x64, 0x48, 0x29, 0x66, 0xf5, 0x0d, 0x97, 0x63, 0x3a, 0xc8, 0x2f, 0x2a, 0x7d, 0xce, 0x9a, 0xbc, 0x14, 0xc9, 0x9a, - 0xbe, 0x0d, 0xfe, 0x54, 0x99, 0x42, 0x9a, 0xd4, 0x1b, 0x72, 0x84, 0x77, 0x5a, 0xab, 0x2b, 0x69, 0x6a, 0x55, 0x73, - 0x1c, 0x5c, 0xc0, 0x3a, 0x48, 0x89, 0xe1, 0xb3, 0x5c, 0xfe, 0x5f, 0xdb, 0x69, 0x80, 0xb6, 0x73, 0x20, 0x0c, 0x7f, - 0x94, 0x84, 0xc2, 0x6b, 0xef, 0xb7, 0x40, 0x19, 0x9d, 0x53, 0x10, 0x28, 0x08, 0xad, 0x4f, 0x85, 0xfa, 0xb3, 0x34, - 0x8f, 0xd9, 0x48, 0x78, 0xb1, 0x90, 0x2c, 0x85, 0x26, 0x39, 0x75, 0x44, 0x4d, 0x25, 0x96, 0xec, 0x26, 0x06, 0x62, - 0x2b, 0xf5, 0x2f, 0x6a, 0x20, 0x95, 0x6c, 0x0b, 0xb8, 0x43, 0xa5, 0x4e, 0x57, 0x5c, 0xc6, 0xd4, 0x66, 0xa0, 0x32, - 0xb6, 0xfb, 0xaa, 0xc7, 0x40, 0x33, 0x03, 0x66, 0x69, 0xad, 0x2c, 0xb0, 0x39, 0x84, 0x2e, 0x14, 0xbe, 0xe0, 0x2f, - 0xf9, 0x0d, 0xcd, 0xce, 0x42, 0x00, 0x3e, 0x50, 0xcd, 0x0b, 0x25, 0x08, 0x24, 0xbf, 0x17, 0x5d, 0x43, 0x2f, 0x97, - 0x72, 0xe2, 0x6f, 0x33, 0x3e, 0x61, 0x39, 0x05, 0x65, 0x4d, 0xe1, 0x3f, 0x85, 0x7d, 0x26, 0x37, 0x24, 0x08, 0x1b, - 0x5a, 0xd2, 0xd7, 0xe9, 0xcb, 0x3a, 0x7d, 0x5d, 0xee, 0x3e, 0x1f, 0x1b, 0x06, 0x58, 0xdf, 0xc6, 0x08, 0x7b, 0xda, - 0xa4, 0xb0, 0xe4, 0x9c, 0x1f, 0x23, 0x2d, 0xe1, 0x97, 0x4b, 0x61, 0x59, 0x6e, 0x35, 0x75, 0x91, 0xaa, 0x6d, 0x83, - 0x8a, 0x30, 0x8a, 0x40, 0xb1, 0xcb, 0x78, 0x92, 0x58, 0xa2, 0x0a, 0xb3, 0x6e, 0x29, 0x9c, 0x2e, 0x77, 0x9f, 0x9f, - 0xdf, 0x27, 0x9f, 0xe0, 0xbd, 0x2d, 0xa2, 0x0c, 0xa0, 0x69, 0x44, 0x33, 0xb0, 0x24, 0xad, 0xd5, 0xd2, 0x52, 0xf6, - 0x8c, 0xa7, 0x29, 0x1d, 0x0a, 0x1a, 0x81, 0xa1, 0xc2, 0x88, 0xf0, 0x63, 0x9e, 0x8b, 0xb2, 0xb0, 0x82, 0x9e, 0x59, - 0xd0, 0x33, 0x7f, 0x18, 0x26, 0x89, 0xa7, 0x8c, 0x92, 0x09, 0x9f, 0xd3, 0x0d, 0x50, 0x77, 0x6b, 0x20, 0x97, 0xdd, - 0x50, 0xab, 0x1b, 0xea, 0xe7, 0xd3, 0x84, 0x0d, 0x69, 0x29, 0xba, 0xce, 0x7d, 0x96, 0x46, 0xf4, 0x16, 0xf8, 0x08, - 0xea, 0xf5, 0x7a, 0x2d, 0xdc, 0x46, 0x85, 0x42, 0xf8, 0x62, 0x0d, 0xb1, 0xf7, 0x08, 0x4d, 0x20, 0x32, 0xd2, 0x5b, - 0x6c, 0xe2, 0x07, 0x14, 0x59, 0x92, 0x92, 0x19, 0xe3, 0x4a, 0x71, 0x67, 0x84, 0x23, 0x9a, 0x50, 0x41, 0x0d, 0x37, - 0x07, 0x15, 0x5a, 0x6d, 0xdd, 0x77, 0x25, 0xfe, 0x4a, 0x72, 0x32, 0xbb, 0xcc, 0xac, 0x79, 0x5e, 0x1a, 0xeb, 0xd5, - 0xf2, 0x54, 0xd8, 0xee, 0x0b, 0xb5, 0x3c, 0xa1, 0x10, 0xe1, 0x30, 0x56, 0x56, 0xba, 0xb7, 0x36, 0xa5, 0xaa, 0x0f, - 0xcd, 0xd9, 0xcb, 0x4d, 0xf4, 0xde, 0x80, 0xb9, 0x09, 0x05, 0xe7, 0x9a, 0x29, 0x50, 0x30, 0xfc, 0xd4, 0xb2, 0x9d, - 0x85, 0x49, 0x72, 0x1d, 0x0e, 0x3f, 0xd6, 0xa9, 0xbf, 0x22, 0x03, 0xb2, 0xca, 0x8d, 0xad, 0x57, 0x16, 0xcb, 0xb2, - 0xe7, 0x6d, 0xb8, 0x74, 0x6d, 0xa3, 0x78, 0x3b, 0xad, 0x8a, 0xec, 0xeb, 0x0b, 0xbd, 0x95, 0xda, 0x25, 0x44, 0x4c, - 0xcf, 0xcc, 0x03, 0x2e, 0xf0, 0x49, 0x8a, 0x33, 0xfc, 0x40, 0xd3, 0x1d, 0x98, 0x1b, 0xc5, 0x0a, 0x20, 0x02, 0x2d, - 0x8a, 0x88, 0xe5, 0xdb, 0x31, 0xf0, 0x87, 0x40, 0xf9, 0xcc, 0x1a, 0xe1, 0xa1, 0x80, 0x96, 0x3c, 0x4e, 0x6b, 0xcd, - 0x25, 0x64, 0x5a, 0x9f, 0x30, 0x8c, 0xe6, 0x6f, 0xa0, 0xbb, 0x48, 0x7a, 0x7f, 0xa3, 0x5e, 0x81, 0x56, 0x06, 0x50, - 0xe4, 0x5d, 0x5b, 0x9d, 0xa8, 0x51, 0x80, 0xe6, 0xa9, 0x4c, 0x8a, 0xdc, 0xac, 0x66, 0x3f, 0x6a, 0x8d, 0x5d, 0x99, - 0xe0, 0x9a, 0xe5, 0x72, 0xe2, 0x79, 0x5e, 0x0e, 0x26, 0x9c, 0x51, 0xed, 0xab, 0x49, 0xe4, 0x6b, 0x93, 0xc8, 0x7d, - 0xcb, 0xce, 0x42, 0x15, 0x2d, 0x5b, 0xcd, 0x83, 0xbf, 0x23, 0xbb, 0x12, 0xa8, 0xab, 0x3e, 0xf0, 0x67, 0x54, 0xb2, - 0xdb, 0x84, 0x08, 0xcc, 0xb5, 0x8d, 0xa3, 0x29, 0x0d, 0x18, 0x46, 0xd5, 0x24, 0x43, 0x6a, 0x6b, 0xd4, 0xec, 0xdd, - 0x0c, 0x73, 0xb4, 0xa2, 0xdb, 0x17, 0x85, 0xc6, 0x11, 0x45, 0x7a, 0x6d, 0x6a, 0x4a, 0xb1, 0x85, 0x15, 0x9c, 0x11, - 0xad, 0x08, 0x2b, 0xbd, 0x67, 0x15, 0x37, 0x65, 0xbf, 0x3b, 0x84, 0x64, 0x15, 0x6a, 0x6a, 0x1a, 0xa5, 0x51, 0xad, - 0x32, 0x84, 0x63, 0xa3, 0x93, 0xf2, 0x6a, 0xde, 0x84, 0xb8, 0xc6, 0x21, 0xe1, 0xf6, 0x17, 0x35, 0xab, 0x30, 0xb0, - 0xaa, 0x15, 0x01, 0xb0, 0x54, 0xbe, 0x09, 0xdd, 0x9b, 0x68, 0xa6, 0xd6, 0x8f, 0x85, 0x70, 0x6e, 0x23, 0xdc, 0xc2, - 0x6c, 0xa6, 0x38, 0x57, 0x76, 0x41, 0xe2, 0x7a, 0x5b, 0x8f, 0x62, 0xae, 0xd6, 0x61, 0x0d, 0x89, 0xab, 0xaa, 0xa7, - 0x24, 0x41, 0xb0, 0x61, 0x73, 0x50, 0xee, 0x6c, 0xf9, 0xe0, 0x01, 0xec, 0x6c, 0xb9, 0x5c, 0x23, 0xba, 0x8d, 0x1a, - 0x28, 0xf2, 0x2b, 0xbb, 0x70, 0xb9, 0xbc, 0x15, 0xc8, 0xd3, 0xba, 0x2f, 0xa6, 0xa8, 0x6f, 0x38, 0xee, 0xe9, 0x4b, - 0xa8, 0x25, 0x55, 0xd1, 0xaa, 0xa4, 0x34, 0x1a, 0xea, 0x34, 0x5b, 0x5f, 0x27, 0x61, 0xb1, 0xed, 0xb3, 0x35, 0xee, - 0x25, 0x0b, 0xb5, 0x98, 0xae, 0xa6, 0x7c, 0xa6, 0xbb, 0x66, 0x08, 0xa1, 0x20, 0x97, 0x76, 0xcc, 0xce, 0x26, 0xd3, - 0x72, 0x6f, 0x2f, 0xb7, 0x3a, 0xba, 0x2c, 0xd9, 0xc4, 0x4f, 0x1e, 0x88, 0xe4, 0xfc, 0x2e, 0x95, 0xba, 0xcb, 0x4f, - 0x46, 0x08, 0xad, 0x19, 0xa6, 0xad, 0x2e, 0x18, 0xe4, 0xe1, 0x4d, 0xc8, 0x84, 0x53, 0xf6, 0xa2, 0x0c, 0x72, 0x8f, - 0xa2, 0x85, 0x56, 0x35, 0xfc, 0x8c, 0x82, 0xf2, 0x08, 0x3c, 0xc1, 0xa8, 0xd0, 0x8a, 0xee, 0x87, 0x31, 0x05, 0x5f, - 0xb0, 0xd1, 0x22, 0x4a, 0xcb, 0x70, 0x47, 0x4b, 0x11, 0xdd, 0xf1, 0x66, 0xd8, 0x8b, 0xd5, 0xe6, 0x35, 0x4b, 0x60, - 0x4a, 0xb3, 0x11, 0xcf, 0x26, 0xe6, 0x5d, 0xb1, 0xf2, 0xac, 0x39, 0x23, 0x1b, 0x79, 0x1b, 0xfb, 0xd6, 0xfa, 0x7f, - 0x77, 0xc5, 0xec, 0xae, 0x0c, 0xf6, 0x9a, 0x28, 0x2d, 0xa5, 0xaf, 0x72, 0x09, 0x1a, 0xca, 0xcc, 0x6d, 0x03, 0x5f, - 0xfb, 0x53, 0xbb, 0xca, 0x67, 0xb2, 0xd3, 0xee, 0x96, 0x56, 0x9f, 0xa1, 0x86, 0xae, 0xf2, 0x6d, 0x68, 0x91, 0xca, - 0x67, 0x49, 0xa4, 0x81, 0x65, 0x08, 0x53, 0x4d, 0x47, 0x37, 0x2c, 0x49, 0xaa, 0xd2, 0x5f, 0xc3, 0xd7, 0x73, 0xcd, - 0xd7, 0x33, 0xc3, 0xd7, 0x81, 0x53, 0x00, 0x5f, 0x57, 0xdd, 0x55, 0xcd, 0xb3, 0xb5, 0xdd, 0x99, 0x29, 0x8e, 0x9e, - 0x4b, 0x4b, 0x1a, 0xc6, 0x9b, 0x19, 0x08, 0x50, 0xa9, 0x79, 0x7d, 0xf4, 0xb4, 0x1f, 0x06, 0x4c, 0x40, 0xe5, 0xc5, - 0xa4, 0xb6, 0x93, 0xe2, 0xa3, 0x87, 0x70, 0x5e, 0xd0, 0x92, 0xb2, 0x4f, 0x9f, 0x83, 0x9f, 0xce, 0x9a, 0x0e, 0x08, - 0x31, 0x59, 0xfc, 0xab, 0x94, 0x28, 0x33, 0x3b, 0xa6, 0x67, 0x97, 0x9b, 0xd9, 0x01, 0xa7, 0xaf, 0x66, 0x17, 0xdd, - 0xcf, 0xeb, 0xe5, 0xf4, 0x58, 0x39, 0xbd, 0x6a, 0xbd, 0x97, 0x4b, 0x6f, 0xa5, 0x04, 0x5c, 0xf8, 0xda, 0x44, 0xc9, - 0xca, 0xde, 0x81, 0x07, 0xd8, 0x98, 0x81, 0x82, 0x42, 0x4d, 0xba, 0x14, 0x71, 0x2f, 0x3f, 0xe5, 0xe2, 0x91, 0x9e, - 0x7a, 0xd5, 0xfe, 0x8c, 0x4f, 0xa6, 0xa0, 0x8d, 0xad, 0x90, 0xf4, 0x98, 0xea, 0x01, 0xab, 0xf7, 0xc5, 0x86, 0xb2, - 0x5a, 0x1b, 0xb9, 0x1f, 0x6b, 0xd4, 0x54, 0x5a, 0xcc, 0x3b, 0xad, 0x62, 0x56, 0x16, 0x95, 0x8c, 0x63, 0x93, 0x5b, - 0xe5, 0x6c, 0xd5, 0x29, 0x63, 0x5e, 0xbc, 0xf1, 0x98, 0xe2, 0xc3, 0x0c, 0x78, 0x9d, 0xc5, 0x7e, 0x0c, 0xb9, 0xdb, - 0xeb, 0x5f, 0x54, 0xc8, 0x59, 0x14, 0x2b, 0xe8, 0x5b, 0x14, 0xc5, 0x73, 0x6d, 0x65, 0xe3, 0xe7, 0xdb, 0xcd, 0xe1, - 0xea, 0x9d, 0xb6, 0x16, 0x07, 0x17, 0xf8, 0xf9, 0xba, 0xee, 0x48, 0x16, 0x13, 0x1e, 0xd1, 0xc0, 0xe5, 0x53, 0x9a, - 0xba, 0x05, 0x78, 0x56, 0xf5, 0xe2, 0x47, 0xc2, 0x5b, 0xbc, 0xab, 0xbb, 0x58, 0x83, 0xe7, 0x05, 0x38, 0xc0, 0xbe, - 0x5b, 0x77, 0xbe, 0x7e, 0x4b, 0xb3, 0x5c, 0x6a, 0xa2, 0xa5, 0x52, 0xfb, 0x5d, 0x25, 0x97, 0xbe, 0x0b, 0xb6, 0xd6, - 0xaf, 0x6c, 0x10, 0xb7, 0xed, 0x3f, 0xf2, 0x0f, 0x5c, 0x24, 0x5d, 0xc3, 0x5f, 0xeb, 0x1d, 0xff, 0x93, 0x71, 0x0d, - 0x9f, 0x93, 0x9f, 0xea, 0x9e, 0xe1, 0x99, 0x20, 0xe7, 0xfd, 0x73, 0x63, 0x32, 0xf3, 0x84, 0x0d, 0xef, 0x3c, 0x37, - 0x61, 0xa2, 0x09, 0xe1, 0x37, 0x17, 0x2f, 0xd4, 0x0b, 0xf0, 0x2a, 0x4a, 0x97, 0x76, 0x61, 0x8c, 0x3d, 0x4c, 0x05, - 0x71, 0x77, 0x13, 0x26, 0x76, 0x5d, 0x3c, 0x21, 0x57, 0xf0, 0x63, 0x77, 0xe1, 0xbd, 0x0a, 0x45, 0xec, 0x67, 0x61, - 0x1a, 0xf1, 0x89, 0x87, 0x1a, 0xae, 0x8b, 0xfc, 0x5c, 0x1a, 0x1c, 0x4f, 0x50, 0xb1, 0x7b, 0x85, 0x4f, 0x05, 0x71, - 0xfb, 0x6e, 0x63, 0x82, 0xdf, 0x09, 0x72, 0x75, 0xb2, 0xbb, 0x38, 0x15, 0x45, 0xef, 0x0a, 0xdf, 0x96, 0x5e, 0x7b, - 0xfc, 0x81, 0x78, 0x88, 0xf4, 0x6e, 0x35, 0x34, 0x67, 0x7c, 0xa2, 0xbc, 0xf7, 0x2e, 0xc2, 0xef, 0x65, 0x6c, 0xa5, - 0x62, 0x37, 0x3a, 0xbc, 0xb2, 0x43, 0x5c, 0x2e, 0x7d, 0x04, 0xee, 0xde, 0x9e, 0x55, 0x56, 0xea, 0x0a, 0xf8, 0xb9, - 0x20, 0x35, 0x8b, 0x1c, 0xbf, 0x90, 0x51, 0x9a, 0xe7, 0xc2, 0x4b, 0x91, 0xe9, 0xc6, 0x33, 0xbe, 0x68, 0xbd, 0x37, - 0xd3, 0x81, 0x72, 0x31, 0xf8, 0x4c, 0xd0, 0x2c, 0x14, 0x3c, 0xbb, 0x40, 0xb6, 0xfe, 0x81, 0xff, 0x46, 0xae, 0x06, - 0xce, 0x7f, 0xfa, 0xec, 0xc7, 0xd1, 0x8f, 0xd9, 0xc5, 0x15, 0x7e, 0x4b, 0xf6, 0x4f, 0xbc, 0x7e, 0xe0, 0xed, 0x34, - 0x9b, 0xcb, 0x1f, 0xf7, 0x07, 0xff, 0x08, 0x9b, 0xbf, 0x9c, 0x36, 0x7f, 0xb8, 0x40, 0x4b, 0xef, 0xc7, 0xfd, 0xfe, - 0x40, 0x3f, 0x0d, 0xfe, 0xd1, 0xfb, 0x31, 0xbf, 0xf8, 0xb3, 0x2a, 0xdc, 0x45, 0x68, 0x7f, 0x8c, 0xa7, 0x82, 0xec, - 0x37, 0x9b, 0xbd, 0xfd, 0x31, 0x1e, 0x0b, 0xb2, 0x0f, 0xff, 0x5f, 0x93, 0x77, 0x74, 0xfc, 0xfc, 0x76, 0xea, 0x5d, - 0xf5, 0x96, 0xbb, 0x8b, 0xbf, 0x15, 0xd0, 0xeb, 0xe0, 0x1f, 0x3f, 0xfe, 0x98, 0xbb, 0x5f, 0xf4, 0xc8, 0xfe, 0x45, - 0x03, 0x79, 0x50, 0xfa, 0x67, 0x22, 0xff, 0xf5, 0xfa, 0xc1, 0xe0, 0x1f, 0x1a, 0x0a, 0xf7, 0x8b, 0x1f, 0xaf, 0x4e, - 0x7a, 0xe4, 0x62, 0xe9, 0xb9, 0xcb, 0x2f, 0xd0, 0x12, 0xa1, 0xe5, 0x2e, 0xba, 0xc2, 0xee, 0xd8, 0x45, 0x78, 0x2e, - 0xc8, 0xfe, 0x17, 0xfb, 0x63, 0x3c, 0x12, 0x64, 0xdf, 0xdd, 0x1f, 0xe3, 0x73, 0x41, 0xf6, 0xff, 0xe1, 0xf5, 0x03, - 0xe5, 0x64, 0x5b, 0x4a, 0xff, 0xc6, 0x12, 0x02, 0x1c, 0x61, 0x46, 0xc3, 0xa5, 0x60, 0x22, 0xa1, 0x68, 0x77, 0x9f, - 0xe1, 0x33, 0x89, 0x26, 0x4f, 0x80, 0x17, 0x06, 0x8c, 0x3b, 0x6f, 0x71, 0x09, 0x8b, 0x0d, 0x34, 0xb3, 0x1b, 0x40, - 0x64, 0x07, 0x1c, 0x01, 0x79, 0x20, 0xf0, 0x3c, 0x4c, 0x66, 0x34, 0x0f, 0x68, 0x81, 0xf0, 0x90, 0x9c, 0x09, 0xaf, - 0x8d, 0xf0, 0x53, 0x01, 0x3f, 0x3a, 0x08, 0x9f, 0xe9, 0x20, 0x26, 0xec, 0x64, 0x45, 0x54, 0x29, 0x57, 0x2a, 0x8b, - 0x8b, 0xf0, 0x74, 0xc3, 0x4b, 0x11, 0x83, 0x7b, 0x01, 0xe1, 0xdd, 0x5a, 0xc8, 0x13, 0xdf, 0x10, 0x43, 0x12, 0xef, - 0x33, 0x4a, 0xbf, 0x0b, 0x93, 0x8f, 0x34, 0xf3, 0x6e, 0x71, 0xbb, 0xf3, 0x04, 0x4b, 0x2f, 0xf4, 0x4e, 0x1b, 0x75, - 0xcb, 0x78, 0xd5, 0x47, 0xa1, 0xe2, 0x04, 0x20, 0x65, 0xeb, 0xce, 0x18, 0x58, 0xf1, 0x9d, 0x74, 0xcd, 0x63, 0x95, - 0x85, 0x37, 0x2e, 0xaa, 0xc7, 0x46, 0x59, 0x3a, 0x0f, 0x13, 0x16, 0x39, 0x82, 0x4e, 0xa6, 0x49, 0x28, 0xa8, 0xa3, - 0xe7, 0xeb, 0x84, 0xd0, 0x91, 0x5b, 0xea, 0x0c, 0x33, 0xcb, 0xe2, 0x9c, 0x99, 0xa0, 0x13, 0xec, 0x15, 0x0f, 0x22, - 0x54, 0x5a, 0xef, 0x78, 0x55, 0x05, 0xc0, 0x56, 0x63, 0x7c, 0xcd, 0x36, 0x78, 0xc2, 0x2e, 0xa4, 0x7c, 0xce, 0x71, - 0x46, 0x40, 0x8a, 0x76, 0xfa, 0xee, 0x49, 0x3e, 0x1f, 0xf7, 0x5c, 0x88, 0xcf, 0x70, 0xf2, 0x56, 0x3a, 0x86, 0xa0, - 0x42, 0x4c, 0x5a, 0xdd, 0xf8, 0x84, 0x76, 0xe3, 0x46, 0xc3, 0x28, 0xd1, 0x09, 0x49, 0x07, 0xb1, 0x6a, 0x1e, 0xe2, - 0x08, 0xcf, 0x48, 0xb3, 0x8d, 0xc7, 0xa4, 0x25, 0x9b, 0x74, 0xc7, 0x27, 0x89, 0x1e, 0x66, 0x6f, 0xcf, 0xe3, 0x7e, - 0x12, 0xe6, 0xe2, 0x2b, 0xb0, 0xf6, 0xc9, 0x18, 0x47, 0x84, 0xfb, 0xf4, 0x96, 0x0e, 0xbd, 0x04, 0xe1, 0x48, 0x73, - 0x1a, 0xd4, 0x45, 0x63, 0x62, 0x55, 0x03, 0x2b, 0x82, 0xbc, 0xed, 0x47, 0x83, 0xf6, 0x05, 0x21, 0xc4, 0xdd, 0x69, - 0x36, 0xdd, 0x3e, 0x27, 0x53, 0x11, 0x40, 0x89, 0xa5, 0x2b, 0x93, 0x31, 0x14, 0x75, 0xac, 0x22, 0xef, 0x5c, 0xf8, - 0x82, 0xe6, 0xc2, 0x83, 0x62, 0xb0, 0xff, 0x73, 0x43, 0xd8, 0xee, 0xc9, 0xbe, 0xdb, 0x80, 0x52, 0x49, 0x9c, 0x08, - 0x73, 0x72, 0x8d, 0x82, 0x68, 0x70, 0x70, 0x61, 0x0b, 0x00, 0x59, 0x08, 0x83, 0x5f, 0xf7, 0xa3, 0x41, 0x4b, 0x0e, - 0xde, 0x73, 0xfb, 0x1e, 0x27, 0xb9, 0xd2, 0xd0, 0xfa, 0x79, 0xf0, 0x56, 0x4e, 0x15, 0x05, 0x1a, 0x38, 0xb3, 0x02, - 0xa4, 0xd9, 0x09, 0xbc, 0x99, 0x3d, 0x89, 0x26, 0x0c, 0xa6, 0xb1, 0x80, 0x43, 0x02, 0xf5, 0x31, 0x27, 0x30, 0x62, - 0xd5, 0xec, 0x3a, 0xd0, 0xcf, 0x5f, 0xb8, 0x5f, 0xf4, 0x47, 0x22, 0x98, 0x0b, 0x35, 0xfc, 0x48, 0x2c, 0x97, 0xf0, - 0xff, 0x5c, 0xf4, 0x39, 0xb9, 0x96, 0x45, 0x53, 0x5d, 0x34, 0x86, 0xa2, 0xb7, 0x01, 0x80, 0x8a, 0xf3, 0x52, 0xcb, - 0x52, 0x6b, 0x32, 0x27, 0x12, 0xf6, 0xbd, 0xbd, 0x74, 0x10, 0x37, 0xda, 0x17, 0xe0, 0xe2, 0xcf, 0x44, 0xfe, 0x1d, - 0x13, 0xb1, 0xe7, 0xee, 0xf7, 0x5c, 0xd4, 0x77, 0x1d, 0x58, 0xda, 0x6e, 0xd6, 0x20, 0x0a, 0xc3, 0x49, 0xe3, 0x9d, - 0x08, 0x66, 0x3d, 0xd2, 0xea, 0x7b, 0x4c, 0xb1, 0xf0, 0x10, 0xe1, 0x44, 0x33, 0xce, 0x16, 0x9e, 0xa1, 0x06, 0x15, - 0x0d, 0xf3, 0x3c, 0x43, 0x8d, 0x49, 0x63, 0x8e, 0x82, 0xa4, 0x31, 0x69, 0x78, 0x33, 0x42, 0x48, 0xb3, 0x53, 0x36, - 0x33, 0xe2, 0x2f, 0x46, 0xc1, 0xdc, 0x78, 0x3b, 0x07, 0x72, 0x3b, 0x64, 0x0d, 0x2f, 0x1d, 0xd0, 0x8b, 0xe5, 0xd2, - 0x3d, 0xe9, 0xf7, 0x5c, 0xd4, 0xf0, 0x0c, 0xa1, 0xed, 0x1b, 0x4a, 0x43, 0x08, 0xb3, 0x8b, 0x42, 0x47, 0x93, 0x5e, - 0xd7, 0x22, 0x47, 0x8b, 0x6a, 0xb3, 0x5b, 0x3c, 0x80, 0x16, 0xa5, 0x21, 0xa3, 0x14, 0xd6, 0x29, 0x4c, 0xd3, 0x10, - 0x73, 0x46, 0x5a, 0x98, 0x13, 0xe3, 0xbc, 0x8e, 0x89, 0xa8, 0x08, 0x3e, 0x21, 0x55, 0x75, 0x3c, 0x08, 0x71, 0x74, - 0x41, 0x5e, 0x29, 0x83, 0xa4, 0x6b, 0x5c, 0xe3, 0x34, 0x21, 0xaf, 0x57, 0x22, 0xb8, 0x21, 0x84, 0x57, 0x6e, 0xfc, - 0xe1, 0x2c, 0xcb, 0x68, 0x2a, 0x5e, 0xf3, 0x48, 0xeb, 0x69, 0x34, 0x01, 0x53, 0x09, 0x42, 0xb3, 0x18, 0x94, 0xb4, - 0x8e, 0xd9, 0x19, 0xb3, 0xb5, 0xd7, 0x63, 0x32, 0x53, 0xfa, 0x93, 0x0c, 0xd8, 0x76, 0xc7, 0xda, 0x30, 0xf6, 0x10, - 0x9e, 0xe9, 0x48, 0xae, 0xe7, 0xfb, 0xfe, 0xd8, 0x1f, 0xc2, 0x6b, 0x18, 0x20, 0x47, 0x85, 0xdc, 0x47, 0x5e, 0x4e, - 0x6e, 0xfc, 0x94, 0xde, 0xca, 0x51, 0x3d, 0x54, 0x49, 0x66, 0xb3, 0xbd, 0x4e, 0xe2, 0xae, 0x64, 0x37, 0xb9, 0x9f, - 0xf2, 0x88, 0x02, 0x7a, 0x20, 0x76, 0xaf, 0x8b, 0xe2, 0x30, 0xb7, 0x43, 0x54, 0x15, 0x7c, 0x03, 0xdb, 0x7b, 0x3d, - 0x06, 0x97, 0xaf, 0x54, 0xb6, 0xca, 0xca, 0xca, 0x0f, 0x8e, 0x10, 0x1b, 0x79, 0x63, 0x1f, 0x42, 0x7b, 0x92, 0x84, - 0x28, 0xd8, 0x72, 0x63, 0x9b, 0xa8, 0x26, 0x65, 0x9f, 0x73, 0x12, 0x0d, 0x78, 0xa3, 0x21, 0xdd, 0xd0, 0x33, 0x45, - 0x12, 0x63, 0x84, 0xe7, 0xe5, 0xde, 0x32, 0xf5, 0xbe, 0x24, 0xf5, 0x91, 0xbc, 0x79, 0xdd, 0x9d, 0xdb, 0x80, 0x34, - 0x09, 0xf0, 0x14, 0x0a, 0x6f, 0x82, 0xf0, 0x29, 0xd9, 0xf7, 0x06, 0x7e, 0xff, 0x2f, 0x17, 0xa8, 0xef, 0xf9, 0x7f, - 0x46, 0xfb, 0x8a, 0x71, 0xcc, 0x51, 0x37, 0x51, 0x43, 0x2c, 0x64, 0x08, 0xb3, 0x8d, 0xa5, 0x27, 0x31, 0xc8, 0x70, - 0x1a, 0x4e, 0x68, 0x70, 0x0a, 0x7b, 0xdc, 0xd0, 0xcd, 0x97, 0x18, 0xe8, 0x28, 0x38, 0xd5, 0x9c, 0xc4, 0x77, 0xfb, - 0xcf, 0x44, 0xf9, 0xd4, 0x77, 0xfb, 0x5f, 0x55, 0x4f, 0x7f, 0x71, 0xfb, 0x3f, 0x8b, 0xe0, 0x97, 0x42, 0x3b, 0xbb, - 0x6b, 0x43, 0x3c, 0x32, 0x43, 0x14, 0x6a, 0x61, 0x2c, 0xcc, 0xcd, 0xd0, 0xba, 0x9f, 0x63, 0x8c, 0x0a, 0x36, 0x2a, - 0x59, 0x51, 0xee, 0x8b, 0x70, 0x0c, 0x28, 0xb5, 0x56, 0x20, 0xb7, 0x23, 0xfb, 0xd5, 0x84, 0x81, 0x50, 0x0c, 0xb5, - 0x02, 0x2a, 0xc7, 0xbd, 0x16, 0x5a, 0xd4, 0xea, 0x4a, 0x8d, 0xa9, 0x1e, 0x49, 0x2f, 0xb9, 0xf4, 0x9c, 0xb4, 0xba, - 0xf3, 0x93, 0x71, 0x77, 0xde, 0x68, 0xa0, 0xdc, 0x10, 0xd6, 0x6c, 0x30, 0xbf, 0xc0, 0x1f, 0xc0, 0xa7, 0x67, 0x53, - 0x12, 0xae, 0x4d, 0xaf, 0xa3, 0xa7, 0xd7, 0x68, 0x64, 0x05, 0xea, 0x5a, 0x4d, 0xc7, 0xaa, 0x69, 0x51, 0x28, 0x9c, - 0xac, 0x12, 0xda, 0x31, 0x92, 0x25, 0x90, 0x0e, 0x45, 0x08, 0x39, 0x15, 0x68, 0x63, 0xaf, 0xd0, 0x27, 0x34, 0x97, - 0x3b, 0x16, 0x98, 0xa7, 0x92, 0x11, 0x1e, 0x60, 0x01, 0x9a, 0x96, 0x8e, 0xe0, 0x09, 0x9e, 0x35, 0xda, 0x92, 0xc8, - 0x9b, 0xed, 0x6e, 0xbd, 0xaf, 0xc7, 0x55, 0x5f, 0x78, 0xd6, 0x20, 0x93, 0x12, 0x4b, 0x45, 0xd6, 0x68, 0x14, 0xf5, - 0x68, 0xa7, 0xd9, 0xb7, 0xb5, 0xf8, 0xc3, 0xed, 0x6a, 0x5a, 0x86, 0x91, 0xaf, 0x95, 0x44, 0x65, 0x3e, 0x4b, 0x53, - 0x9a, 0x81, 0x0c, 0x25, 0x02, 0xb3, 0xa2, 0xa8, 0xe4, 0x3a, 0x08, 0x51, 0x4c, 0x49, 0x0a, 0x7c, 0x47, 0x9a, 0x5d, - 0x38, 0xc3, 0x1c, 0xc7, 0x92, 0x6b, 0x10, 0x42, 0xce, 0x4c, 0x42, 0x8b, 0x90, 0x1c, 0x28, 0x21, 0xcc, 0x92, 0x48, - 0x39, 0xa1, 0xfe, 0xe5, 0xee, 0x19, 0xbf, 0xd7, 0x24, 0x1b, 0xb0, 0x8b, 0x40, 0x56, 0x4b, 0x34, 0xdf, 0x0a, 0xc9, - 0x7b, 0x4f, 0xa0, 0x32, 0x38, 0xe2, 0x4b, 0xf6, 0xf7, 0x8c, 0x65, 0x54, 0x6a, 0xe0, 0xbb, 0xc6, 0xec, 0x4b, 0xea, - 0xea, 0x63, 0x62, 0x3b, 0x6f, 0x00, 0x91, 0x21, 0xf8, 0x76, 0x32, 0xb2, 0x56, 0xed, 0x72, 0xf7, 0xf4, 0xcd, 0x26, - 0x13, 0x78, 0xb9, 0xd4, 0xc6, 0xaf, 0xd4, 0x6c, 0x70, 0x58, 0x41, 0x9a, 0xe8, 0x1f, 0x81, 0x97, 0x48, 0x05, 0x29, - 0xf4, 0x52, 0xa0, 0xa2, 0xcb, 0xdd, 0xd3, 0xf7, 0x5e, 0x2a, 0x5d, 0x4b, 0x08, 0xdb, 0xd3, 0xf6, 0x38, 0xf1, 0x62, - 0x42, 0x91, 0x9a, 0x7b, 0xc9, 0xb8, 0xb8, 0x25, 0xbe, 0x83, 0x58, 0xbe, 0x04, 0xfb, 0x61, 0xc0, 0x2e, 0x48, 0xa2, - 0x31, 0x40, 0x12, 0x84, 0x93, 0x9a, 0x59, 0x46, 0x60, 0x01, 0xe4, 0x58, 0xe7, 0xb0, 0x12, 0xbe, 0x52, 0xfc, 0x10, - 0x4e, 0xe4, 0xa8, 0xa2, 0x50, 0xa2, 0xe3, 0xe5, 0x5a, 0x5e, 0x5a, 0x65, 0x8d, 0x7e, 0x0b, 0x96, 0x93, 0x79, 0x78, - 0xad, 0xbb, 0x2e, 0x0b, 0x9e, 0x99, 0x04, 0xb2, 0xcb, 0xdd, 0xd3, 0x57, 0x3a, 0x87, 0x6c, 0x1a, 0x1a, 0x6e, 0xbf, - 0x66, 0x61, 0x9e, 0xbe, 0xf2, 0xab, 0xb7, 0xb2, 0xf2, 0xe5, 0xee, 0xe9, 0x87, 0x4d, 0xd5, 0xa0, 0xbc, 0x98, 0x55, - 0x26, 0xbe, 0x84, 0x6f, 0x41, 0x93, 0x60, 0xa1, 0x45, 0x43, 0xc0, 0x0a, 0x2c, 0xc5, 0x51, 0x90, 0x17, 0xa5, 0x67, - 0xe4, 0x19, 0xce, 0x88, 0x8c, 0x02, 0xd5, 0x57, 0x4d, 0x2b, 0x79, 0x8c, 0xa7, 0xe7, 0x43, 0x3e, 0xa5, 0x5b, 0x42, - 0x43, 0xb7, 0xc8, 0x67, 0x13, 0x48, 0x9e, 0x91, 0xa0, 0x33, 0xbc, 0xd3, 0x42, 0xdd, 0xba, 0xf0, 0xca, 0x24, 0x91, - 0xf2, 0x9a, 0x64, 0xc1, 0x31, 0x69, 0xe1, 0x84, 0xb4, 0x70, 0x48, 0xf2, 0x41, 0x4b, 0x89, 0x87, 0x6e, 0x58, 0xf6, - 0xab, 0x84, 0x0c, 0xe4, 0x85, 0xe9, 0xdd, 0xaa, 0xc4, 0x6f, 0xd4, 0x0d, 0xa5, 0xeb, 0x51, 0x4a, 0xf4, 0x48, 0x92, - 0xc5, 0x0b, 0x8f, 0x63, 0x2e, 0x3b, 0x3e, 0x67, 0xd7, 0x09, 0xa4, 0x96, 0xc0, 0xac, 0xb0, 0x40, 0x41, 0x59, 0xb5, - 0xad, 0xab, 0x86, 0xbe, 0x5c, 0x27, 0x8e, 0x43, 0x1f, 0x18, 0x37, 0x0e, 0x75, 0x26, 0x4e, 0xbe, 0xde, 0xe4, 0xd1, - 0xde, 0x9e, 0xa7, 0x1a, 0xfd, 0x22, 0x3c, 0x6e, 0xde, 0x57, 0x81, 0xbb, 0x6f, 0x15, 0xaf, 0x88, 0x90, 0x84, 0xbf, - 0xd1, 0x48, 0x2e, 0x0a, 0x88, 0x42, 0x7b, 0x61, 0x1d, 0x83, 0x06, 0x78, 0xa9, 0xe9, 0xd5, 0xa7, 0xdf, 0x68, 0x94, - 0x41, 0xda, 0x3a, 0xb6, 0x6e, 0x71, 0x56, 0xcc, 0xbd, 0x32, 0xf9, 0xa7, 0xb5, 0x96, 0x31, 0x65, 0x40, 0x40, 0xcc, - 0xa6, 0x59, 0x66, 0x26, 0x63, 0x6d, 0x09, 0x06, 0xf5, 0xbe, 0xd2, 0x69, 0x0b, 0x58, 0xe6, 0x57, 0xe9, 0x4a, 0x86, - 0x9d, 0x75, 0x50, 0x60, 0x2a, 0x41, 0x50, 0x0a, 0x2a, 0x35, 0x0a, 0x4d, 0xde, 0x2f, 0xd6, 0xb3, 0x2e, 0x71, 0x8e, - 0xb4, 0x8f, 0x4b, 0x42, 0x21, 0x91, 0xd5, 0x29, 0x91, 0xf2, 0x82, 0x4c, 0xb7, 0x93, 0xfc, 0xa9, 0x45, 0xf2, 0x4f, - 0x09, 0xb5, 0xc8, 0x5f, 0x79, 0x38, 0x7c, 0xae, 0x5d, 0x0b, 0xb9, 0x79, 0x75, 0x36, 0x25, 0xe0, 0x43, 0xab, 0x63, - 0xb4, 0x16, 0x55, 0xdc, 0xc2, 0x50, 0xec, 0x1d, 0x22, 0xbd, 0x90, 0xd8, 0x84, 0x80, 0xbd, 0x2a, 0xa6, 0x06, 0x43, - 0x6f, 0x72, 0xe9, 0xd9, 0x1c, 0xf0, 0xf4, 0xc3, 0xfd, 0xe1, 0xd0, 0xb3, 0xe9, 0xfa, 0xce, 0xb5, 0xb2, 0x3f, 0x61, - 0xd6, 0xd6, 0xc6, 0xad, 0xe7, 0x82, 0xc2, 0xf8, 0x65, 0x18, 0xbb, 0xce, 0x7c, 0x56, 0x36, 0xa1, 0x91, 0x7f, 0x00, - 0x6d, 0xbb, 0x2d, 0x6b, 0x50, 0xab, 0x5b, 0xe0, 0x47, 0x2a, 0x07, 0x35, 0xcc, 0xb6, 0xb0, 0x8f, 0x53, 0x59, 0x81, - 0xa6, 0xd1, 0xe6, 0xd7, 0x4f, 0x0b, 0x4d, 0x26, 0x0a, 0x34, 0xb4, 0x00, 0xfe, 0xa7, 0x48, 0x1e, 0xe8, 0x46, 0xca, - 0x05, 0x40, 0xd0, 0x54, 0xe2, 0xa9, 0x42, 0x98, 0xeb, 0x56, 0xce, 0xf7, 0x17, 0x3b, 0x84, 0x4c, 0x2b, 0xe7, 0xe3, - 0xbb, 0x2a, 0xf7, 0x0a, 0xc8, 0x02, 0x05, 0x60, 0x3c, 0x96, 0x05, 0x2a, 0x7a, 0x79, 0x66, 0xaa, 0x4b, 0x03, 0xd2, - 0xaf, 0xf4, 0x6d, 0x2b, 0xb2, 0x29, 0xbd, 0x72, 0xea, 0xbd, 0x41, 0xc3, 0xca, 0xdb, 0x5d, 0x78, 0xfb, 0x42, 0x48, - 0x18, 0xe1, 0xf9, 0xbd, 0xac, 0x6d, 0xfa, 0x2d, 0x3e, 0xae, 0x26, 0xb0, 0xac, 0x2c, 0x8a, 0xcf, 0xd2, 0x9c, 0x66, - 0xe2, 0x29, 0x1d, 0xf1, 0x0c, 0x42, 0x16, 0x25, 0x4e, 0x50, 0xb1, 0x6b, 0xb9, 0xed, 0xe4, 0xfc, 0xac, 0x38, 0xc1, - 0xca, 0x04, 0xe5, 0xaf, 0x8f, 0x32, 0x66, 0x7d, 0xb9, 0xda, 0x6a, 0xba, 0xb7, 0xf7, 0xbe, 0x42, 0x93, 0x86, 0x52, - 0x42, 0x61, 0x31, 0x2d, 0xa5, 0xd2, 0xe8, 0x40, 0xee, 0xae, 0x57, 0xba, 0x00, 0x0c, 0xc3, 0xb0, 0x79, 0xcf, 0x0b, - 0x22, 0x8a, 0xf1, 0x2a, 0x8b, 0xd7, 0xae, 0x09, 0x66, 0x9b, 0x2d, 0xc0, 0xe1, 0xc1, 0xd0, 0x56, 0xbe, 0xa2, 0xbc, - 0x4a, 0x87, 0x2d, 0x61, 0x38, 0x03, 0x64, 0x79, 0xd2, 0x08, 0xb1, 0x28, 0x70, 0xa3, 0x51, 0xf2, 0x11, 0xf4, 0xca, - 0x18, 0xe7, 0x7e, 0x0c, 0x09, 0xb0, 0xb5, 0x2d, 0x8b, 0x10, 0x56, 0x79, 0x39, 0x56, 0x26, 0xc1, 0xe9, 0x8b, 0x4d, - 0x1e, 0x65, 0x43, 0xd4, 0x54, 0x4a, 0x1d, 0xa8, 0x91, 0xa1, 0xb2, 0x81, 0x3f, 0xf7, 0x98, 0x56, 0xdc, 0x4c, 0xd8, - 0x0c, 0x18, 0xf0, 0x4b, 0xe1, 0xa9, 0x58, 0x14, 0xc8, 0x0c, 0xee, 0xcf, 0xbc, 0xda, 0xd0, 0x5d, 0x2e, 0x9b, 0x61, - 0x8d, 0xb8, 0xd8, 0x46, 0x13, 0x97, 0x61, 0xbd, 0xb3, 0x8a, 0x97, 0xee, 0xaa, 0x1c, 0x6a, 0x61, 0xb8, 0x60, 0x95, - 0x47, 0x62, 0x4d, 0x7f, 0x57, 0xa5, 0x45, 0x97, 0x95, 0x40, 0x0d, 0xa3, 0x37, 0xce, 0x6b, 0xb9, 0x06, 0xb4, 0x00, - 0xfa, 0x5a, 0x3c, 0x17, 0xd6, 0x8a, 0x1a, 0x1f, 0xb6, 0x1c, 0xd3, 0x92, 0xfa, 0xef, 0x20, 0xd3, 0x65, 0x75, 0xcf, - 0xbf, 0x90, 0xb2, 0x90, 0xe1, 0xbc, 0xc6, 0xd8, 0x33, 0xc9, 0xd8, 0x11, 0xe8, 0x69, 0x26, 0xf5, 0xbb, 0xaf, 0x13, - 0x5e, 0x98, 0x96, 0x72, 0x9a, 0xc4, 0x3e, 0x94, 0xc1, 0x72, 0xeb, 0xf7, 0xca, 0x6a, 0x04, 0x8c, 0x40, 0x12, 0x10, - 0xd6, 0x9c, 0x3d, 0x43, 0x38, 0x6f, 0x34, 0xba, 0xf9, 0x09, 0xad, 0x5c, 0x24, 0x15, 0x8c, 0x0c, 0xe2, 0xb9, 0x40, - 0xf0, 0x35, 0x19, 0x0a, 0x11, 0x7f, 0x93, 0x9b, 0x9d, 0x83, 0xab, 0xfd, 0xf4, 0x9d, 0x67, 0x73, 0x35, 0xbb, 0x6e, - 0x19, 0x33, 0x85, 0xf9, 0x78, 0x55, 0xbc, 0xe5, 0xed, 0xfd, 0xf9, 0x1d, 0x00, 0xf7, 0x4e, 0x1b, 0x43, 0x2e, 0x1a, - 0xea, 0x0a, 0xc5, 0x12, 0xca, 0xdd, 0xd7, 0x45, 0x55, 0x5a, 0xa2, 0x3d, 0x58, 0x57, 0x54, 0xa6, 0xac, 0x20, 0x79, - 0x51, 0xe4, 0xb4, 0x8a, 0xee, 0xaf, 0xe4, 0x5f, 0x4a, 0xe1, 0xb2, 0xee, 0x6c, 0x3f, 0x9b, 0x12, 0x81, 0x2d, 0x42, - 0x7d, 0xbb, 0x2d, 0xf4, 0x51, 0x81, 0x09, 0xfb, 0x5a, 0x0b, 0xc5, 0x5f, 0x36, 0x09, 0x45, 0x9c, 0xe9, 0x2d, 0x2f, - 0x05, 0x62, 0xfb, 0x01, 0x02, 0x51, 0x3b, 0xd9, 0x8d, 0x4c, 0x04, 0x75, 0xa4, 0x26, 0x13, 0xeb, 0x4b, 0x4a, 0x32, - 0xcc, 0xf4, 0x6a, 0xf4, 0x3a, 0xcb, 0x25, 0x1b, 0xb4, 0xc0, 0x89, 0xe4, 0xba, 0xf0, 0xb3, 0xad, 0x7e, 0x5a, 0x9c, - 0x58, 0x39, 0x81, 0x3d, 0x56, 0x9a, 0x2c, 0xc8, 0x87, 0x14, 0x67, 0x4f, 0xe6, 0x64, 0x49, 0x9a, 0xd6, 0x14, 0xa4, - 0x09, 0x9c, 0xb0, 0x32, 0xca, 0x04, 0x10, 0x4b, 0x59, 0xa1, 0x0d, 0x48, 0x6f, 0x63, 0xf2, 0x9f, 0x31, 0x2f, 0x3f, - 0xad, 0x89, 0xd6, 0xe4, 0x8a, 0x52, 0x1f, 0x6a, 0xe9, 0x06, 0x1a, 0x02, 0xad, 0x1f, 0xee, 0x48, 0x13, 0xb4, 0x12, - 0xe5, 0xc8, 0x96, 0x43, 0xb8, 0x05, 0x2e, 0xb4, 0x9d, 0xf7, 0x2a, 0xc0, 0xbb, 0x41, 0x9a, 0x60, 0x6e, 0xd1, 0xf5, - 0x0b, 0x22, 0x6a, 0xac, 0x24, 0x26, 0xda, 0x52, 0xc2, 0xa1, 0x24, 0x53, 0x41, 0xb2, 0x41, 0xeb, 0x02, 0x14, 0xd0, - 0x6e, 0x72, 0x92, 0x55, 0x26, 0x70, 0xd2, 0x68, 0xa0, 0xd0, 0x8c, 0x1a, 0x0f, 0x58, 0x23, 0xb9, 0xc0, 0x14, 0x27, - 0xca, 0x30, 0x39, 0xdb, 0xdb, 0xf3, 0xc2, 0x6a, 0xdc, 0x41, 0x72, 0x81, 0x30, 0x5f, 0x2e, 0x3d, 0x09, 0x56, 0x88, - 0x96, 0xcb, 0xd0, 0x06, 0x4b, 0xbe, 0x86, 0x66, 0xd3, 0xbe, 0x20, 0x53, 0x29, 0x00, 0xa7, 0x00, 0x61, 0x83, 0x78, - 0xa1, 0x76, 0xee, 0x85, 0xe0, 0x8c, 0x6a, 0x64, 0x83, 0xa4, 0xd1, 0xbe, 0xb0, 0x18, 0xd7, 0x20, 0xb9, 0x20, 0x61, - 0xc1, 0xf7, 0xf6, 0x76, 0x72, 0x2d, 0x22, 0x7f, 0x02, 0x51, 0xf6, 0x93, 0x94, 0x2c, 0xaa, 0x43, 0x7b, 0x35, 0x56, - 0x9d, 0x01, 0x25, 0x45, 0xe9, 0x65, 0x35, 0xf5, 0x6a, 0x49, 0x10, 0x65, 0x25, 0xac, 0x63, 0xc1, 0x7d, 0xb0, 0xec, - 0x4b, 0x32, 0x7f, 0x26, 0xca, 0x24, 0xeb, 0x5f, 0x36, 0xa6, 0x56, 0xfb, 0xbe, 0x1f, 0x66, 0x63, 0x19, 0xc9, 0x30, - 0x51, 0x58, 0x49, 0xfc, 0x07, 0x1a, 0x4c, 0x6b, 0xe0, 0x41, 0x39, 0xd6, 0x05, 0x51, 0xe0, 0x1b, 0xd5, 0xc6, 0x9c, - 0x26, 0xf9, 0x69, 0xa3, 0x97, 0x41, 0x41, 0xf2, 0xd5, 0x6f, 0x85, 0xe4, 0x50, 0x43, 0xa2, 0xc8, 0x63, 0x05, 0x67, - 0x5b, 0x70, 0xf1, 0x93, 0x58, 0xc1, 0xd9, 0x76, 0xdc, 0x1a, 0x4c, 0xfd, 0xbc, 0x0d, 0x3e, 0x8b, 0x37, 0x28, 0x40, - 0xab, 0x02, 0x0b, 0xca, 0xa3, 0x55, 0xdd, 0x4b, 0xb1, 0x52, 0x10, 0xa6, 0x82, 0x78, 0xac, 0xbe, 0x01, 0x2a, 0x6d, - 0xd4, 0x32, 0x7c, 0x59, 0x30, 0x45, 0x96, 0x4b, 0xa0, 0x9e, 0xb9, 0x02, 0xe4, 0xa4, 0x7d, 0xed, 0xd3, 0xbd, 0x3d, - 0xb0, 0x0d, 0x40, 0x89, 0xf3, 0x87, 0xe1, 0x54, 0xcc, 0x32, 0x50, 0xa5, 0x72, 0xf3, 0x1b, 0x8a, 0xe1, 0x1c, 0x88, - 0x2c, 0x83, 0x1f, 0x50, 0x30, 0x0d, 0xf3, 0x9c, 0xcd, 0x55, 0x99, 0xfe, 0x8d, 0x39, 0x31, 0xa4, 0x9c, 0x2b, 0x9d, - 0x30, 0x43, 0xdd, 0x4c, 0xd3, 0x69, 0x1d, 0x6d, 0xcf, 0xe7, 0x34, 0x15, 0x2f, 0x59, 0x2e, 0x68, 0x0a, 0xd3, 0xaf, - 0x28, 0x0e, 0x66, 0x94, 0x23, 0xd8, 0xb0, 0xb5, 0x56, 0x61, 0x14, 0xdd, 0xdb, 0x44, 0xd4, 0x75, 0xa0, 0x38, 0x4c, - 0xa3, 0x44, 0x0d, 0x62, 0xa7, 0x33, 0x9a, 0x14, 0xce, 0xb2, 0xa6, 0x9d, 0x4e, 0x53, 0x29, 0x1b, 0x92, 0xbb, 0x7b, - 0x8c, 0x18, 0x49, 0x60, 0xa4, 0xe7, 0xbd, 0x5a, 0x0b, 0x04, 0xbc, 0xb7, 0x2c, 0x82, 0x3d, 0x13, 0x2c, 0x2c, 0x8e, - 0xea, 0xd7, 0xe1, 0x2c, 0x05, 0xc9, 0xc6, 0x43, 0x6d, 0x9b, 0x84, 0x83, 0xa4, 0x93, 0x47, 0xdb, 0x2d, 0xab, 0x57, - 0x46, 0x72, 0x18, 0x69, 0xc1, 0x1e, 0xca, 0x98, 0xd1, 0xc2, 0x90, 0x17, 0x32, 0x5b, 0xf1, 0x52, 0x90, 0x9f, 0xe0, - 0xd4, 0xd0, 0x0b, 0x31, 0x49, 0x56, 0x0e, 0xc7, 0x74, 0x2f, 0x4b, 0xed, 0xff, 0x52, 0x78, 0xaf, 0xf1, 0x0b, 0x08, - 0xeb, 0x7e, 0x5d, 0x55, 0x5f, 0x0f, 0xe7, 0x7e, 0x5d, 0x21, 0xe8, 0xeb, 0x60, 0xad, 0x9e, 0x15, 0xc6, 0xed, 0xf8, - 0xc7, 0x7e, 0xcb, 0x35, 0xda, 0xd2, 0xb7, 0x2a, 0x88, 0xa4, 0x12, 0x2d, 0xe5, 0x7e, 0xc0, 0x55, 0x9a, 0x1a, 0xa4, - 0xcb, 0xd5, 0x2d, 0x24, 0xaa, 0x13, 0x0c, 0x95, 0x0e, 0xbf, 0x6d, 0x79, 0xb4, 0x8c, 0xc9, 0x94, 0x9d, 0xf1, 0x36, - 0xcc, 0xc4, 0x2e, 0xec, 0x32, 0xbe, 0x76, 0x12, 0x2f, 0x26, 0xe0, 0x41, 0x7b, 0xd8, 0x10, 0x96, 0xb1, 0x9d, 0xab, - 0x93, 0x40, 0x76, 0xff, 0x84, 0x1b, 0xdd, 0xad, 0x6e, 0x65, 0x7c, 0x00, 0xfb, 0x1f, 0xe1, 0xd8, 0x1c, 0x8f, 0xa3, - 0x9a, 0x03, 0xd3, 0x60, 0x51, 0x94, 0x4e, 0x01, 0xae, 0x94, 0xb7, 0x14, 0x61, 0x5e, 0xc8, 0xf0, 0xf6, 0x37, 0xf8, - 0x7b, 0xcd, 0x12, 0x47, 0x25, 0xc7, 0x79, 0xfe, 0x50, 0x8e, 0xa8, 0xc0, 0x2f, 0xa3, 0xf7, 0x40, 0xc7, 0x92, 0x42, - 0x0b, 0x43, 0x45, 0xcf, 0xb8, 0x9e, 0xc8, 0xd6, 0xac, 0x54, 0x4c, 0xcb, 0x8c, 0x1a, 0x39, 0xcc, 0x86, 0x34, 0x4e, - 0x63, 0x65, 0x8b, 0x72, 0x57, 0xd5, 0xc6, 0x45, 0x5b, 0xb0, 0x58, 0x05, 0x16, 0x97, 0x4b, 0xaf, 0x8e, 0x6a, 0xc2, - 0xac, 0x38, 0x06, 0xc2, 0xcc, 0x4a, 0xa8, 0xa8, 0x69, 0xd6, 0xaa, 0x8d, 0x87, 0x56, 0xf3, 0x89, 0x8c, 0x6e, 0x5e, - 0x83, 0xc3, 0x76, 0x21, 0xa8, 0xe6, 0xb6, 0x4f, 0x01, 0xab, 0xd9, 0x95, 0x03, 0x59, 0x18, 0xfa, 0xb6, 0xcc, 0x94, - 0xad, 0x52, 0x5a, 0x37, 0xe0, 0x17, 0xdd, 0x93, 0x2b, 0xab, 0x51, 0xb7, 0xfe, 0xde, 0xca, 0x35, 0x7a, 0xc6, 0xb7, - 0xe5, 0x1a, 0xd5, 0xb4, 0xdd, 0x9d, 0x16, 0xba, 0x3f, 0x2b, 0x55, 0x8d, 0xb5, 0xb9, 0xca, 0x6f, 0x18, 0xae, 0x0d, - 0xb4, 0xa9, 0xd0, 0x6c, 0xb8, 0xca, 0x59, 0x51, 0x8c, 0xca, 0xb3, 0x04, 0x32, 0x75, 0x67, 0xa4, 0xe8, 0x5f, 0x5b, - 0x8d, 0xf2, 0x40, 0xae, 0xf7, 0x0d, 0x19, 0x27, 0xfc, 0x3a, 0x4c, 0xde, 0xc3, 0x78, 0xd5, 0xcb, 0x17, 0x77, 0x51, - 0x16, 0x0a, 0xaa, 0xb9, 0x4b, 0x05, 0xc3, 0x37, 0x16, 0x0c, 0xdf, 0x28, 0x3e, 0x5d, 0xb5, 0xc7, 0x8b, 0x97, 0x65, - 0x07, 0xc1, 0xa8, 0x30, 0x2c, 0x63, 0x22, 0x36, 0x8f, 0xb1, 0xca, 0xc2, 0x26, 0x25, 0x0b, 0x9b, 0x08, 0x6f, 0xb5, - 0x2b, 0xcf, 0xfb, 0x7e, 0x73, 0x2f, 0xeb, 0x9c, 0xed, 0xfb, 0x6a, 0xe3, 0x7f, 0x1f, 0xdc, 0xdb, 0xc6, 0xe2, 0x72, - 0x07, 0xfe, 0x81, 0x4c, 0x56, 0x51, 0x20, 0x3f, 0x85, 0xa4, 0x03, 0x41, 0x7a, 0xd6, 0x91, 0x83, 0x4a, 0x4e, 0x99, - 0x3c, 0x20, 0x6f, 0x38, 0xcb, 0x05, 0x9f, 0xe8, 0x3e, 0x73, 0x7d, 0xce, 0x48, 0xbe, 0x04, 0x57, 0xb4, 0x8c, 0xb5, - 0x07, 0xf5, 0x93, 0x5c, 0x8b, 0x8f, 0x2c, 0x8d, 0x82, 0x1c, 0x6b, 0x29, 0x92, 0x07, 0x59, 0x41, 0x4c, 0xae, 0xf1, - 0xfa, 0x3b, 0x3c, 0x62, 0x29, 0xcb, 0x63, 0x9a, 0x79, 0x1c, 0x2d, 0xb6, 0x0d, 0xc6, 0x21, 0x20, 0xa3, 0x06, 0xc3, - 0x5f, 0x56, 0x47, 0xfe, 0x7c, 0xe8, 0x0d, 0xfc, 0x40, 0x13, 0x2a, 0x62, 0x1e, 0x41, 0x5a, 0x8a, 0x1f, 0x95, 0x47, - 0x9a, 0xf6, 0xf6, 0x76, 0x3c, 0x57, 0xba, 0x25, 0xe0, 0xf0, 0xb7, 0xfd, 0x06, 0xf5, 0x17, 0x70, 0x3a, 0xa7, 0x1a, - 0x9a, 0xa2, 0x05, 0x5d, 0x3d, 0xc8, 0x22, 0xfc, 0x8f, 0xf4, 0x0e, 0xa7, 0xa8, 0x28, 0x02, 0x05, 0xb5, 0x3b, 0x62, - 0x34, 0x89, 0x5c, 0xfc, 0x91, 0xde, 0x05, 0xe5, 0x79, 0x71, 0x79, 0xbc, 0x59, 0x2e, 0xa0, 0xcb, 0x6f, 0x52, 0x17, - 0x57, 0x83, 0x04, 0x8b, 0x02, 0xf3, 0x8c, 0x8d, 0x81, 0x38, 0xff, 0x46, 0xef, 0x02, 0xd5, 0x1f, 0xb3, 0x4e, 0xeb, - 0xa1, 0x85, 0x41, 0xbd, 0x6f, 0x15, 0xdb, 0xcb, 0xa0, 0x0d, 0x8a, 0x81, 0x6c, 0x7b, 0x41, 0x6a, 0xf5, 0x2a, 0xf3, - 0x10, 0xa1, 0xe2, 0xa1, 0x53, 0xc1, 0xdf, 0xd9, 0xa2, 0x4d, 0xd4, 0x32, 0x5f, 0x57, 0x1a, 0x51, 0x68, 0x50, 0x65, - 0x7a, 0x5c, 0x7a, 0xa9, 0xd9, 0x75, 0xfa, 0x08, 0x82, 0xe5, 0x08, 0xfb, 0x4e, 0xe8, 0x4e, 0x83, 0x2f, 0x55, 0x42, - 0x48, 0x15, 0x49, 0x7a, 0x55, 0xb5, 0x73, 0x2e, 0x3d, 0xc0, 0x3b, 0x24, 0xb4, 0x84, 0xf2, 0x40, 0x66, 0x61, 0xb2, - 0x45, 0x7f, 0x10, 0xc4, 0x5b, 0x98, 0x29, 0x04, 0xa9, 0x8d, 0x45, 0x51, 0x00, 0x15, 0x6a, 0xfa, 0x52, 0x09, 0x80, - 0x70, 0x86, 0x7d, 0x4d, 0x6a, 0x66, 0x52, 0x6a, 0xfa, 0x16, 0xc6, 0xb7, 0x48, 0x49, 0x2a, 0x91, 0x21, 0x95, 0x48, - 0x29, 0xf4, 0xf4, 0xe2, 0x6a, 0x12, 0xb2, 0x17, 0xb4, 0x3c, 0x3f, 0xa7, 0xd6, 0x3c, 0xab, 0x81, 0xe5, 0xc9, 0x7e, - 0x50, 0x11, 0xc0, 0x94, 0xa8, 0xaa, 0x50, 0x94, 0xc7, 0xb2, 0x4d, 0x7a, 0xab, 0xc7, 0x7d, 0x33, 0x2d, 0x62, 0x50, - 0xe2, 0xc5, 0x68, 0x91, 0x7a, 0x31, 0xce, 0x20, 0x1d, 0x91, 0x17, 0x25, 0xfc, 0xd4, 0x5e, 0x8d, 0x5a, 0xb2, 0xf2, - 0xe6, 0x33, 0x7e, 0xa0, 0xcc, 0x0b, 0x48, 0xd1, 0xc4, 0xa9, 0xe1, 0x29, 0xa9, 0x27, 0x0f, 0xdb, 0x59, 0xcb, 0xf6, - 0xb5, 0x4e, 0xd0, 0xd1, 0x80, 0xfd, 0x20, 0xbc, 0x85, 0x35, 0x0b, 0xfb, 0x34, 0xb7, 0x3e, 0xf3, 0xa7, 0x83, 0x7d, - 0x55, 0x0e, 0xa9, 0x97, 0x93, 0x15, 0x89, 0x73, 0x7f, 0xaa, 0xe5, 0xcf, 0x33, 0x9a, 0xdd, 0x9d, 0x53, 0x48, 0x75, - 0xe6, 0x70, 0xda, 0xb7, 0x5a, 0x86, 0x2a, 0x4d, 0xbd, 0x9f, 0x49, 0x65, 0xa5, 0xa8, 0x9f, 0x02, 0x5c, 0x3d, 0x23, - 0x58, 0xc8, 0x68, 0xa3, 0xe5, 0x88, 0x51, 0xbb, 0x85, 0x6e, 0x3d, 0x3d, 0x49, 0xbb, 0x0c, 0xfc, 0x6b, 0x15, 0xa6, - 0x75, 0xb0, 0x00, 0x73, 0xfb, 0x44, 0xea, 0x20, 0xbf, 0x58, 0xf5, 0xca, 0x40, 0x11, 0x84, 0xef, 0xb2, 0xed, 0x53, - 0xdd, 0x94, 0x34, 0xbb, 0x7d, 0xaa, 0xb5, 0xa0, 0x9f, 0x4c, 0xf8, 0xc1, 0x7a, 0x9c, 0xf2, 0xf8, 0x32, 0x2b, 0x0a, - 0x54, 0x00, 0x78, 0x7f, 0xed, 0x7a, 0xde, 0x5f, 0x75, 0xca, 0xa0, 0x0f, 0xb1, 0xd8, 0xf3, 0x84, 0x1b, 0x26, 0x5e, - 0x8d, 0xff, 0xd7, 0xb5, 0xf1, 0xff, 0x6a, 0x9d, 0x39, 0x05, 0xd3, 0x68, 0x9c, 0xd2, 0xc8, 0xb0, 0x4e, 0xa4, 0x08, - 0x50, 0xea, 0x6d, 0xa9, 0x20, 0x6f, 0xae, 0x02, 0xd0, 0xb8, 0x16, 0x23, 0x9e, 0x8a, 0xe6, 0x28, 0x9c, 0xb0, 0xe4, - 0x2e, 0x98, 0xb1, 0xe6, 0x84, 0xa7, 0x3c, 0x9f, 0x86, 0x43, 0x8a, 0xf3, 0xbb, 0x5c, 0xd0, 0x49, 0x73, 0xc6, 0xf0, - 0x0b, 0x9a, 0xcc, 0xa9, 0x60, 0xc3, 0x10, 0xbb, 0xa7, 0x19, 0x0b, 0x13, 0xe7, 0x75, 0x98, 0x65, 0xfc, 0xc6, 0xc5, - 0xef, 0xf8, 0x35, 0x17, 0x1c, 0xbf, 0xb9, 0xbd, 0x1b, 0xd3, 0x14, 0x7f, 0xb8, 0x9e, 0xa5, 0x62, 0x86, 0xf3, 0x30, - 0xcd, 0x9b, 0x39, 0xcd, 0xd8, 0xa8, 0x3b, 0xe4, 0x09, 0xcf, 0x9a, 0x90, 0xb1, 0x3d, 0xa1, 0x41, 0xc2, 0xc6, 0xb1, - 0x70, 0xa2, 0x30, 0xfb, 0xd8, 0x6d, 0x36, 0xa7, 0x19, 0x9b, 0x84, 0xd9, 0x5d, 0x53, 0xd6, 0x08, 0x3e, 0x6f, 0x1d, - 0x84, 0x4f, 0x46, 0x87, 0x5d, 0x91, 0x85, 0x69, 0xce, 0x60, 0x99, 0x82, 0x30, 0x49, 0x9c, 0x83, 0xa3, 0xd6, 0x24, - 0xdf, 0x51, 0x81, 0xbc, 0x30, 0x15, 0xc5, 0x15, 0x7e, 0x03, 0x70, 0xfb, 0xd7, 0x22, 0xc5, 0xd7, 0x33, 0x21, 0x78, - 0xba, 0x18, 0xce, 0xb2, 0x9c, 0x67, 0xc1, 0x94, 0xb3, 0x54, 0xd0, 0xac, 0x7b, 0xcd, 0xb3, 0x88, 0x66, 0xcd, 0x2c, - 0x8c, 0xd8, 0x2c, 0x0f, 0x0e, 0xa7, 0xb7, 0x5d, 0xd0, 0x2c, 0xc6, 0x19, 0x9f, 0xa5, 0x91, 0x1e, 0x8b, 0xa5, 0x31, - 0xcd, 0x98, 0xb0, 0x5f, 0xc8, 0x4b, 0x4c, 0x82, 0x84, 0xa5, 0x34, 0xcc, 0x9a, 0x63, 0x68, 0x0c, 0x66, 0x51, 0x2b, - 0xa2, 0x63, 0x9c, 0x8d, 0xaf, 0x43, 0xaf, 0xdd, 0x79, 0x8c, 0xcd, 0x5f, 0xff, 0x08, 0x39, 0xad, 0xcd, 0xc5, 0xed, - 0x56, 0xeb, 0x4f, 0xa8, 0xbb, 0x32, 0x8a, 0x04, 0x28, 0x68, 0x4f, 0x6f, 0x9d, 0x9c, 0x43, 0x46, 0xdb, 0xa6, 0x96, - 0xdd, 0x69, 0x18, 0x41, 0x3e, 0x70, 0xd0, 0x99, 0xde, 0x16, 0x30, 0xbb, 0x40, 0xa5, 0x98, 0xea, 0x49, 0xea, 0xa7, - 0xc5, 0x6f, 0x85, 0xf8, 0x78, 0x33, 0xc4, 0x1d, 0x03, 0x71, 0x85, 0xf5, 0x66, 0x34, 0xcb, 0x64, 0x6c, 0x35, 0x68, - 0xe7, 0x0a, 0x90, 0x98, 0xcf, 0x69, 0x66, 0xe0, 0x90, 0x0f, 0xbf, 0x19, 0x8c, 0xce, 0x66, 0x30, 0x8e, 0x3f, 0x05, - 0x46, 0x96, 0x46, 0x8b, 0xfa, 0xba, 0xb6, 0x33, 0x3a, 0xe9, 0xc6, 0x14, 0xe8, 0x29, 0xe8, 0xc0, 0xef, 0x1b, 0x16, - 0x89, 0x58, 0xfd, 0x94, 0xe4, 0x7c, 0xa3, 0xde, 0x1d, 0xb5, 0x5a, 0xea, 0x39, 0x67, 0xbf, 0xd0, 0xa0, 0xed, 0x43, - 0x85, 0xe2, 0x0a, 0xff, 0xad, 0x3c, 0xcb, 0x5b, 0xe7, 0x9e, 0xf8, 0x1b, 0xfb, 0x90, 0xaf, 0x95, 0xa2, 0x58, 0x1d, - 0x89, 0xc6, 0x99, 0x91, 0x95, 0x4a, 0xf8, 0x80, 0xdb, 0x4e, 0x72, 0x47, 0xc2, 0x7a, 0xe5, 0x21, 0x4e, 0xd6, 0xff, - 0x46, 0xe5, 0x5d, 0x04, 0x10, 0xe9, 0xb0, 0x52, 0x0d, 0x79, 0x37, 0xeb, 0x91, 0x56, 0x37, 0x6b, 0x36, 0x91, 0xc7, - 0x49, 0x3a, 0xc8, 0x74, 0x72, 0x9e, 0xc7, 0xfa, 0x5c, 0x1a, 0xdb, 0x39, 0x0a, 0x38, 0x9c, 0x34, 0x5d, 0x2e, 0xab, - 0x30, 0x00, 0x93, 0xa7, 0x35, 0xfe, 0x26, 0x74, 0x05, 0x9c, 0x5b, 0x9c, 0x9c, 0x9b, 0xab, 0x5d, 0x52, 0xc3, 0x2b, - 0x12, 0x3e, 0x94, 0x98, 0xf3, 0xa7, 0xa1, 0x88, 0xc1, 0x4b, 0x51, 0x8a, 0x9f, 0x2a, 0x85, 0xc9, 0xdd, 0x77, 0x51, - 0x3f, 0x2d, 0xf3, 0xdb, 0x20, 0x8f, 0x2f, 0x2d, 0xa0, 0x97, 0xef, 0x05, 0x81, 0x1e, 0xf1, 0x57, 0x44, 0xd9, 0x74, - 0xc6, 0xa2, 0x1b, 0x3d, 0xd4, 0xa2, 0xa3, 0xa9, 0x60, 0x32, 0x73, 0xdb, 0x44, 0x1c, 0xe2, 0x30, 0xbf, 0x1c, 0xaa, - 0xa3, 0x92, 0x79, 0x75, 0x30, 0x20, 0x94, 0xd0, 0x2b, 0x23, 0x8d, 0x66, 0xd2, 0x1e, 0xfd, 0xab, 0xd8, 0x6a, 0x9f, - 0xa4, 0xf7, 0xd9, 0x27, 0xe5, 0xc4, 0x73, 0x3e, 0xcb, 0x86, 0x10, 0x8e, 0xd4, 0x52, 0x6f, 0xdd, 0x71, 0xe3, 0x4a, - 0x15, 0xc3, 0xc5, 0xc2, 0xca, 0x03, 0x15, 0x98, 0xd9, 0xd7, 0x4a, 0x50, 0x19, 0xf2, 0x52, 0xc7, 0x35, 0xb4, 0x88, - 0x33, 0x53, 0x02, 0x99, 0x1d, 0xc9, 0x94, 0x46, 0x2f, 0x23, 0xbd, 0xcc, 0x9f, 0xa5, 0xec, 0xe7, 0x19, 0xbd, 0x64, - 0xa0, 0x6b, 0x32, 0x9f, 0x45, 0x32, 0xd6, 0x04, 0xb2, 0xaf, 0xd9, 0x86, 0xe0, 0x05, 0x8b, 0xd4, 0xc2, 0x64, 0xf2, - 0xa5, 0xce, 0x6d, 0x72, 0x9b, 0x2e, 0xf8, 0x8b, 0x41, 0x3b, 0x60, 0x38, 0xe2, 0x93, 0x90, 0xa5, 0x81, 0x74, 0xf9, - 0x96, 0x9d, 0x05, 0x50, 0x1b, 0xb3, 0x28, 0xc8, 0xf4, 0xf2, 0xb4, 0x91, 0xff, 0x13, 0x67, 0xa9, 0x6c, 0x5a, 0x74, - 0xb9, 0x44, 0xa8, 0x42, 0x1f, 0x31, 0x08, 0x3e, 0x55, 0x72, 0x8d, 0x23, 0x6c, 0xbf, 0x2e, 0x4f, 0x9d, 0xd7, 0x56, - 0xa0, 0xb5, 0xb2, 0x50, 0xca, 0x08, 0xe0, 0xab, 0xa5, 0x39, 0xcf, 0x84, 0xe7, 0xc5, 0x38, 0x41, 0xa4, 0x17, 0x4b, - 0x67, 0xd7, 0x49, 0x22, 0xff, 0xeb, 0x37, 0xdb, 0x41, 0xbb, 0x34, 0xdf, 0x6b, 0x87, 0x81, 0x55, 0x72, 0x94, 0x3e, - 0x50, 0x2a, 0xa7, 0x51, 0xfe, 0x56, 0x53, 0xad, 0x9e, 0xcb, 0xe9, 0x62, 0xbd, 0xdd, 0x94, 0xa8, 0xf2, 0x6a, 0x40, - 0xc8, 0x60, 0xd1, 0x96, 0xa1, 0x50, 0x51, 0xcd, 0xbb, 0x54, 0x25, 0xaf, 0x94, 0x88, 0xbe, 0xdc, 0x5d, 0xa4, 0x7a, - 0xc4, 0xe2, 0x8a, 0x19, 0x27, 0x53, 0x9d, 0xe4, 0x0a, 0x8d, 0x11, 0x4b, 0x0f, 0xdd, 0x54, 0x4d, 0xc1, 0x72, 0x47, - 0xd2, 0x8d, 0x74, 0xeb, 0xab, 0x47, 0xaa, 0x14, 0x84, 0xcd, 0x55, 0x64, 0xaa, 0xde, 0x26, 0xc0, 0xc0, 0x6c, 0xcd, - 0x85, 0x99, 0x02, 0x68, 0x63, 0x23, 0x0a, 0xe7, 0x68, 0xae, 0x76, 0x17, 0xdf, 0x8b, 0x62, 0xdf, 0xaa, 0x2a, 0x7f, - 0xb3, 0x08, 0xfe, 0x07, 0x09, 0xb8, 0x50, 0x4a, 0x69, 0xe0, 0xbe, 0x7d, 0x73, 0xfe, 0xde, 0xc5, 0x70, 0x3b, 0x17, - 0xcd, 0xf2, 0x60, 0xe1, 0xea, 0xd4, 0xb8, 0x26, 0x84, 0x59, 0xdd, 0xc0, 0x0d, 0xa7, 0x70, 0xd2, 0x58, 0xf2, 0x82, - 0xfd, 0xdb, 0xe6, 0xcd, 0xcd, 0x4d, 0x13, 0x0e, 0x42, 0x35, 0x67, 0x59, 0x42, 0xd3, 0x21, 0x8f, 0x68, 0xe4, 0x16, - 0x05, 0xf2, 0x45, 0x4c, 0xd3, 0xf2, 0xfe, 0x1e, 0x9e, 0x50, 0x3f, 0xe1, 0x63, 0x75, 0x88, 0x73, 0xd5, 0xaa, 0x1e, - 0x5e, 0x9d, 0xc8, 0x7b, 0xa9, 0x7a, 0x27, 0x42, 0xdd, 0x08, 0x26, 0x32, 0xf8, 0xd9, 0x83, 0x98, 0xcb, 0xc9, 0xbe, - 0x88, 0xe5, 0xc3, 0x39, 0xec, 0x30, 0xf9, 0xb4, 0xbb, 0x58, 0xa3, 0xbe, 0x3e, 0x74, 0x11, 0xf7, 0xd4, 0x9c, 0x73, - 0x59, 0xeb, 0x2a, 0x18, 0x5e, 0x5d, 0x15, 0x27, 0xfb, 0xd0, 0xd7, 0xbe, 0xe9, 0xf7, 0x9a, 0x47, 0x77, 0xa6, 0x7d, - 0x49, 0x91, 0x70, 0x3f, 0x51, 0x4a, 0x7a, 0xd0, 0x05, 0x8c, 0x1b, 0xf5, 0x00, 0x2b, 0x40, 0x91, 0xd0, 0x3a, 0x2a, - 0x4b, 0xe4, 0x16, 0x57, 0x45, 0xdb, 0x20, 0x50, 0x15, 0xab, 0x8d, 0xa2, 0xdc, 0xaf, 0x15, 0x41, 0x18, 0x90, 0x22, - 0x1b, 0xba, 0x2b, 0x04, 0xff, 0x4b, 0xc8, 0x4e, 0xf6, 0x15, 0x1e, 0xae, 0xec, 0xcb, 0x50, 0xd4, 0x35, 0x05, 0x25, - 0xb6, 0x06, 0xa9, 0xc0, 0x6f, 0x04, 0x7e, 0x73, 0x25, 0xab, 0x1a, 0xe9, 0x05, 0x6a, 0x15, 0x48, 0xf9, 0x96, 0x51, - 0x53, 0x86, 0x3c, 0x49, 0xc2, 0x69, 0x4e, 0x03, 0xf3, 0x43, 0x0b, 0x32, 0x90, 0x87, 0xeb, 0x9a, 0x83, 0xce, 0xc7, - 0x39, 0x03, 0xfd, 0x62, 0x5d, 0xad, 0x99, 0x87, 0x99, 0xd7, 0x6c, 0x0e, 0x9b, 0xd7, 0x63, 0x54, 0x88, 0x78, 0x61, - 0x8b, 0xc1, 0x47, 0xad, 0x56, 0x17, 0x92, 0x27, 0x9b, 0x61, 0xc2, 0xc6, 0x69, 0x90, 0xd0, 0x91, 0x28, 0x04, 0x9c, - 0x6a, 0x5b, 0x18, 0xbd, 0xc3, 0xef, 0x1c, 0x65, 0x74, 0xe2, 0xf8, 0xf0, 0xef, 0xfd, 0x03, 0x17, 0x22, 0x0a, 0x52, - 0x11, 0x37, 0x65, 0x92, 0x2e, 0x1c, 0x31, 0x10, 0x71, 0xed, 0x79, 0x61, 0x0d, 0x34, 0xa4, 0xa0, 0x93, 0x15, 0x22, - 0x73, 0x44, 0x8c, 0x45, 0x66, 0xd7, 0x4b, 0xd1, 0x62, 0x6d, 0x06, 0xeb, 0xaa, 0xc1, 0x01, 0x2a, 0x72, 0xa9, 0x49, - 0xaf, 0x57, 0x36, 0xfa, 0x55, 0xfd, 0x69, 0x0d, 0x7d, 0x96, 0x26, 0x58, 0x28, 0x4f, 0xf4, 0x42, 0xb5, 0x78, 0x08, - 0x32, 0x6b, 0x3a, 0x2a, 0xb6, 0x5b, 0xa0, 0x82, 0xa5, 0xd3, 0x99, 0x18, 0x48, 0x2f, 0x78, 0x06, 0xe7, 0x29, 0x2e, - 0xb0, 0x55, 0x02, 0x38, 0xb8, 0x58, 0x28, 0x60, 0x86, 0x61, 0x32, 0xf4, 0x00, 0x22, 0xa7, 0xe9, 0x1c, 0x67, 0x74, - 0x82, 0xba, 0x13, 0x96, 0x36, 0xd5, 0xbb, 0x23, 0x4b, 0x8f, 0xf1, 0x1f, 0xc3, 0x53, 0xe1, 0xcb, 0xde, 0xb0, 0x4c, - 0x76, 0xdd, 0x80, 0xcb, 0xab, 0x8b, 0xa2, 0xe8, 0x66, 0xc2, 0x1b, 0xbc, 0xf2, 0xd0, 0x05, 0xfe, 0xca, 0xba, 0xce, - 0xc5, 0x35, 0x5b, 0xc5, 0xc5, 0x1d, 0xb4, 0xa5, 0x8a, 0xbd, 0x17, 0x64, 0xb5, 0xaf, 0x08, 0x54, 0x7c, 0xea, 0xb9, - 0x34, 0x9f, 0x36, 0x15, 0xb3, 0x6b, 0x4a, 0x92, 0x75, 0xa1, 0x29, 0xd2, 0xae, 0xdd, 0xbf, 0x8a, 0x85, 0xe4, 0x63, - 0xfa, 0x4c, 0x87, 0xf2, 0x3e, 0x5c, 0x94, 0x67, 0x80, 0xf4, 0xb3, 0x7d, 0xea, 0x07, 0xd5, 0xf8, 0xc9, 0xd5, 0x69, - 0x9d, 0x29, 0x02, 0x23, 0x2b, 0xef, 0xbc, 0x0b, 0x93, 0x04, 0x06, 0xbc, 0x32, 0xfa, 0x8e, 0x7d, 0x49, 0xc8, 0x40, - 0x5c, 0x78, 0xa8, 0xd0, 0xfb, 0xf4, 0xa9, 0xd4, 0x41, 0xad, 0x8b, 0xf6, 0x76, 0x84, 0x89, 0x2e, 0x29, 0x71, 0xcd, - 0x20, 0x3e, 0x5e, 0xcb, 0xa3, 0xee, 0x56, 0xbc, 0x4b, 0x69, 0xb0, 0x8e, 0x9c, 0x10, 0x71, 0xb3, 0x34, 0x72, 0x9d, - 0xbf, 0x0c, 0x13, 0x36, 0xfc, 0x48, 0xdc, 0xdd, 0x85, 0x87, 0xd6, 0x8f, 0x49, 0x4a, 0xae, 0x60, 0x38, 0x3c, 0xaa, - 0x7b, 0xde, 0x33, 0xdf, 0x62, 0xde, 0xea, 0x1e, 0x1d, 0xb7, 0xb7, 0xbb, 0x00, 0xc6, 0xa3, 0xc6, 0xe9, 0x5d, 0x15, - 0x97, 0xd5, 0xf5, 0x58, 0x15, 0x14, 0x80, 0x66, 0x55, 0xee, 0x48, 0xa2, 0x22, 0xee, 0x27, 0x29, 0xcd, 0x75, 0x14, - 0x53, 0x03, 0x38, 0x85, 0xe6, 0x6f, 0xae, 0xf3, 0x97, 0xb2, 0x8c, 0x96, 0x2e, 0x10, 0x99, 0xc3, 0x41, 0x5c, 0x18, - 0x0b, 0xec, 0x5e, 0x3f, 0xa2, 0x22, 0x64, 0x89, 0x6a, 0xd2, 0x35, 0x16, 0xfb, 0xca, 0x8c, 0x96, 0xcb, 0xbc, 0x3e, - 0x17, 0x56, 0xc7, 0xa0, 0x9c, 0xd9, 0xc9, 0x7e, 0x05, 0xb7, 0x9c, 0x99, 0xdc, 0x93, 0x76, 0x2c, 0xb1, 0x9a, 0xa1, - 0x7a, 0xe7, 0xfc, 0x65, 0x28, 0x4f, 0x19, 0x01, 0x80, 0x5c, 0x03, 0x08, 0x51, 0x6e, 0x75, 0x8a, 0xc6, 0x4b, 0x08, - 0xf7, 0x45, 0x98, 0x8d, 0xa9, 0x58, 0x41, 0x6c, 0xa2, 0x92, 0x5a, 0xbb, 0x26, 0xa2, 0xbd, 0x06, 0x6d, 0x58, 0x87, - 0xf6, 0x0a, 0x90, 0xde, 0xdf, 0x5d, 0xb0, 0x82, 0xec, 0x2e, 0x94, 0x5c, 0xfb, 0xf0, 0xee, 0x2b, 0x38, 0x14, 0xc9, - 0x53, 0xb0, 0x44, 0x62, 0x04, 0x92, 0x56, 0x2e, 0x8e, 0x12, 0x21, 0x5c, 0x8a, 0x10, 0xc5, 0x09, 0x1c, 0x39, 0x96, - 0x04, 0xb1, 0x70, 0x9d, 0xbe, 0x82, 0x9c, 0x46, 0x0a, 0x66, 0x92, 0xc9, 0x56, 0xbc, 0x38, 0xd9, 0x57, 0xb5, 0x95, - 0x08, 0x50, 0x95, 0x00, 0x09, 0x72, 0x9f, 0x56, 0x38, 0x80, 0x44, 0x68, 0x1b, 0x0f, 0x11, 0x9b, 0x97, 0xc4, 0x26, - 0xcf, 0x5b, 0xf5, 0x4e, 0x92, 0xf0, 0x9a, 0x26, 0xbd, 0xdd, 0x45, 0xb6, 0x5c, 0xb6, 0x8a, 0x93, 0x7d, 0xf5, 0xe8, - 0x9c, 0x48, 0xbe, 0xa1, 0xee, 0xc8, 0x94, 0x4b, 0x0c, 0x87, 0x18, 0x21, 0x3d, 0xd4, 0xe4, 0x45, 0x05, 0xba, 0x83, - 0xc2, 0x75, 0x64, 0x46, 0x86, 0xac, 0x54, 0x6a, 0x50, 0x85, 0xeb, 0xb0, 0x68, 0xbd, 0x2c, 0x17, 0x74, 0x0a, 0xa5, - 0xf1, 0x72, 0xd9, 0x2e, 0x5c, 0x67, 0xc2, 0x52, 0x78, 0xca, 0x96, 0x4b, 0x79, 0x3e, 0x70, 0xc2, 0x52, 0xaf, 0x05, - 0x64, 0xeb, 0x3a, 0x93, 0xf0, 0x56, 0x4e, 0xd8, 0xbc, 0x09, 0x6f, 0xbd, 0xb6, 0x7e, 0xe5, 0x97, 0xf8, 0xc9, 0x81, - 0xe2, 0xaa, 0x15, 0x4d, 0xf4, 0x8a, 0x46, 0x78, 0xa6, 0x4e, 0x3e, 0x11, 0x2f, 0x22, 0xc9, 0xe6, 0x15, 0x8d, 0xcc, - 0x8a, 0xce, 0xb6, 0xac, 0xe8, 0xec, 0x9e, 0x15, 0x0d, 0xf5, 0xea, 0x39, 0x25, 0xee, 0xf8, 0x72, 0xd9, 0x6e, 0x55, - 0xd8, 0x3b, 0xd9, 0x8f, 0xd8, 0x1c, 0x56, 0x03, 0xf4, 0x42, 0xc1, 0x26, 0x74, 0x33, 0x51, 0xd6, 0x51, 0x4c, 0x7f, - 0x15, 0x26, 0x2b, 0x2c, 0x64, 0x75, 0x2c, 0xd8, 0x74, 0x5d, 0x06, 0xe9, 0xfe, 0x48, 0xca, 0x66, 0x80, 0x87, 0x1c, - 0xf0, 0x10, 0x9b, 0x3b, 0x33, 0x3d, 0xf7, 0xbd, 0x8b, 0x5d, 0xc7, 0x35, 0x64, 0x7d, 0x55, 0x5c, 0x82, 0x8c, 0x90, - 0xf3, 0x7b, 0x10, 0x2d, 0x42, 0x6d, 0xb7, 0xb7, 0x9d, 0xe6, 0x20, 0x9e, 0x7e, 0xc3, 0xb3, 0xc8, 0x0d, 0x54, 0xd5, - 0x5f, 0x85, 0xaa, 0x09, 0x4b, 0x75, 0x76, 0xd6, 0x56, 0x5a, 0xab, 0xde, 0xdb, 0x14, 0xd7, 0x39, 0x3a, 0x52, 0x35, - 0xa6, 0xa1, 0x10, 0x34, 0x4b, 0x35, 0xe5, 0xba, 0xee, 0xff, 0x17, 0x54, 0xb8, 0x81, 0xaf, 0x84, 0x66, 0x01, 0x0c, - 0x01, 0x6a, 0x0d, 0x5f, 0xf3, 0x7c, 0x25, 0x9e, 0x76, 0x2a, 0x0d, 0xf6, 0x0e, 0xd9, 0x56, 0x86, 0x2a, 0x02, 0xa3, - 0x67, 0x36, 0xa1, 0xd1, 0xa5, 0x64, 0xd0, 0xfd, 0xe1, 0x95, 0x56, 0x58, 0x57, 0xc4, 0x5d, 0xd5, 0x00, 0xbb, 0x3f, - 0xce, 0x3a, 0x8f, 0x0f, 0xcf, 0x5c, 0xac, 0x78, 0x3c, 0x1f, 0x8d, 0x5c, 0x54, 0x38, 0x0f, 0x6b, 0xd6, 0x3e, 0xfc, - 0x71, 0xf6, 0xe5, 0xf3, 0xd6, 0x97, 0x65, 0xe3, 0x14, 0x88, 0x48, 0x27, 0x04, 0x18, 0x51, 0x65, 0xc1, 0x6b, 0x66, - 0x34, 0x0a, 0xd3, 0xed, 0xd3, 0x19, 0xd8, 0xd3, 0xc9, 0xa7, 0x94, 0x46, 0x40, 0x9c, 0x78, 0xad, 0xf4, 0x32, 0xa1, - 0x73, 0x6a, 0xee, 0x2a, 0xdc, 0x30, 0xd8, 0x86, 0x16, 0x43, 0x3e, 0x4b, 0x85, 0xce, 0x8c, 0xd0, 0xac, 0xd6, 0x9a, - 0xd2, 0x95, 0x9c, 0x83, 0x6d, 0x23, 0xdc, 0x29, 0x39, 0x57, 0x97, 0x5e, 0xc5, 0x15, 0x76, 0x2d, 0x00, 0xb6, 0x42, - 0xd6, 0xdf, 0x52, 0x1e, 0xb4, 0x70, 0x6b, 0x1b, 0x6c, 0xb8, 0x8d, 0x02, 0xd7, 0xbd, 0x30, 0x78, 0x92, 0xce, 0xcd, - 0xda, 0x05, 0x13, 0x5b, 0xf1, 0xf5, 0x49, 0x0c, 0x5c, 0x67, 0xd0, 0x59, 0x4a, 0xf3, 0x7c, 0x2b, 0x02, 0xca, 0x45, - 0xc4, 0x6e, 0x55, 0xdb, 0xdd, 0xd2, 0x0b, 0x6e, 0x61, 0xd8, 0x61, 0x12, 0xe0, 0x32, 0xc4, 0xaa, 0x6b, 0xd1, 0xd1, - 0x88, 0x0e, 0x4b, 0xdf, 0x30, 0x04, 0xcb, 0x46, 0x2c, 0x11, 0x10, 0x33, 0x92, 0xc1, 0x1c, 0xf7, 0x35, 0x4f, 0xa9, - 0x8b, 0x4c, 0xfa, 0xa7, 0x86, 0x5f, 0xcb, 0xff, 0xcd, 0xf0, 0xa8, 0x1e, 0xeb, 0xb0, 0xe8, 0x51, 0x96, 0x4b, 0xe3, - 0x17, 0xaa, 0x95, 0xd7, 0x11, 0xc9, 0xa5, 0xe3, 0x67, 0xdb, 0x06, 0x7a, 0xd8, 0x36, 0x59, 0xb4, 0xbf, 0x3c, 0x6a, - 0xb7, 0x0a, 0x17, 0xbb, 0xd0, 0xdd, 0x43, 0x77, 0x89, 0x6c, 0x75, 0x00, 0xad, 0x66, 0xe9, 0xaf, 0x69, 0xd7, 0x69, - 0x3f, 0x69, 0xbb, 0x58, 0xdd, 0x3b, 0x80, 0x8a, 0x92, 0x19, 0x0c, 0xc1, 0x5b, 0xfa, 0xbb, 0xa7, 0x52, 0xef, 0xfc, - 0x61, 0xf0, 0x3c, 0x6a, 0xb7, 0x5c, 0xec, 0xe6, 0x82, 0x4f, 0x7f, 0xc5, 0x14, 0x0e, 0x5c, 0xec, 0x0e, 0x13, 0x9e, - 0x53, 0x7b, 0x0e, 0x4a, 0x9d, 0xfd, 0xfd, 0x93, 0x50, 0x10, 0x4d, 0x33, 0x9a, 0xe7, 0x8e, 0xdd, 0xbf, 0x26, 0xa5, - 0x4f, 0x30, 0xcc, 0x8d, 0x14, 0x97, 0x53, 0x21, 0xf1, 0xa2, 0xae, 0x04, 0xb0, 0xa9, 0x4a, 0x95, 0xad, 0x11, 0x9b, - 0x14, 0x01, 0x25, 0x63, 0x53, 0xda, 0xd5, 0x27, 0x47, 0xde, 0xb0, 0xf5, 0xd4, 0xc0, 0x2a, 0x88, 0xbc, 0x3e, 0x40, - 0xad, 0x64, 0xc2, 0xd2, 0xcb, 0x0d, 0xa5, 0xe1, 0xed, 0x86, 0x52, 0x50, 0xd9, 0x4a, 0xe8, 0xf4, 0x75, 0x35, 0x9f, - 0xc6, 0x7a, 0xa5, 0xf8, 0xd8, 0x20, 0x46, 0xd2, 0xd1, 0xf9, 0x09, 0x48, 0xad, 0x65, 0x90, 0x3d, 0xfc, 0xf6, 0xe1, - 0xa0, 0xe4, 0xd7, 0x0c, 0x57, 0xf6, 0xf2, 0xfb, 0x66, 0x08, 0xa5, 0x4d, 0x70, 0x78, 0x27, 0xbf, 0x6a, 0xae, 0xf4, - 0xf6, 0xd3, 0x04, 0x67, 0x69, 0x55, 0xbf, 0x63, 0xe9, 0xf5, 0xb1, 0xf7, 0xd5, 0xb5, 0xdf, 0x50, 0xac, 0x15, 0x9f, - 0x72, 0xfd, 0x87, 0x09, 0x9b, 0x54, 0x24, 0xb0, 0x0e, 0xa6, 0xd4, 0x78, 0x20, 0xfb, 0xc9, 0xee, 0x44, 0xa9, 0x3e, - 0x97, 0x70, 0xa6, 0x13, 0xae, 0xcd, 0x98, 0x65, 0xf4, 0x32, 0xe1, 0x37, 0xab, 0xf7, 0x80, 0x6d, 0xaf, 0x1c, 0xb3, - 0x71, 0x6c, 0x1d, 0xd4, 0xa2, 0xa4, 0x5c, 0x84, 0x7b, 0x07, 0x28, 0xfe, 0xe5, 0x9f, 0x7d, 0xff, 0x5f, 0xfe, 0xf9, - 0x93, 0x55, 0xa1, 0xfb, 0xe2, 0x0a, 0x8b, 0xaa, 0xdb, 0xed, 0xbb, 0x6b, 0xf3, 0x48, 0x75, 0x9c, 0x6f, 0xae, 0xb3, - 0xb6, 0x08, 0xf0, 0x7e, 0x6d, 0x09, 0xd6, 0x0a, 0xd5, 0xee, 0x73, 0x7e, 0x0b, 0x60, 0x30, 0xaf, 0x4f, 0x42, 0x06, - 0x95, 0x7e, 0x17, 0x68, 0x57, 0x28, 0x78, 0xd0, 0x8a, 0xfc, 0x76, 0x0c, 0x7f, 0x6a, 0x0e, 0xbf, 0x13, 0x7c, 0xed, - 0x9f, 0x18, 0x5e, 0x5d, 0x95, 0x19, 0x79, 0x76, 0x53, 0x38, 0xef, 0xdf, 0x5f, 0x2b, 0xd1, 0x8a, 0x47, 0xd0, 0x42, - 0x3d, 0x79, 0x9e, 0x90, 0x0c, 0xaf, 0x5e, 0xc1, 0x25, 0x3f, 0x27, 0xd7, 0x99, 0x71, 0xf0, 0xde, 0x23, 0x1c, 0xa0, - 0x8b, 0xfa, 0xac, 0x64, 0xa7, 0x6b, 0x92, 0x01, 0x4a, 0xc1, 0xdc, 0x00, 0x30, 0xf1, 0xf0, 0x4a, 0x5b, 0x9b, 0x67, - 0xca, 0x0d, 0x13, 0xac, 0x92, 0xb6, 0x76, 0xcf, 0xd4, 0x90, 0x8e, 0x9d, 0xf7, 0x12, 0x5f, 0xb2, 0x32, 0xad, 0xac, - 0x7b, 0xe9, 0xea, 0x02, 0x3b, 0xa2, 0x64, 0x3f, 0xf3, 0x30, 0x99, 0x3f, 0x8c, 0xf1, 0x6d, 0x17, 0xa8, 0x4b, 0x67, - 0xf9, 0x6f, 0xad, 0x12, 0x2c, 0x9b, 0xcb, 0x9a, 0x3e, 0x20, 0xb3, 0x12, 0xfe, 0xbe, 0x2d, 0x70, 0x2a, 0xe8, 0x27, - 0x03, 0xa7, 0xc9, 0x83, 0x02, 0xa7, 0xea, 0x86, 0xbe, 0x3f, 0x32, 0x70, 0xfa, 0x77, 0x3b, 0x70, 0x0a, 0x24, 0xf8, - 0xf3, 0x83, 0x82, 0x9b, 0x26, 0xf0, 0xc4, 0x6f, 0x72, 0xd2, 0xd6, 0x46, 0x40, 0xc2, 0xc7, 0x10, 0xd9, 0xfc, 0xb7, - 0x0f, 0x54, 0x26, 0x7c, 0x6c, 0x87, 0x29, 0xe1, 0x8e, 0x5a, 0x88, 0x4b, 0xe2, 0x8c, 0x2c, 0xdc, 0x1f, 0x6f, 0xdb, - 0x4f, 0x07, 0xed, 0xee, 0x41, 0x7b, 0xe2, 0x06, 0x2e, 0x48, 0x5d, 0x59, 0xd0, 0xea, 0x1e, 0x1c, 0x40, 0xc1, 0x8d, - 0x55, 0xd0, 0x81, 0x02, 0x66, 0x15, 0x1c, 0x41, 0xc1, 0xd0, 0x2a, 0x78, 0x04, 0x05, 0x91, 0x55, 0xf0, 0x18, 0x0a, - 0xe6, 0x6e, 0x31, 0x60, 0x65, 0x74, 0xf8, 0x31, 0x92, 0xd7, 0x59, 0xec, 0x64, 0xf5, 0x54, 0xfe, 0x98, 0x98, 0x2a, - 0x8f, 0xcb, 0x63, 0x40, 0xcd, 0x43, 0x73, 0x6b, 0xc5, 0xd5, 0x67, 0x57, 0x08, 0x27, 0x04, 0x4e, 0xe5, 0x61, 0x30, - 0xca, 0x55, 0xcd, 0x03, 0xf3, 0xda, 0x0d, 0xca, 0x7b, 0xa9, 0x5a, 0xb8, 0x63, 0x22, 0x9c, 0x81, 0x8b, 0xf0, 0xac, - 0xac, 0x7c, 0xd4, 0x88, 0x74, 0xb7, 0x70, 0x21, 0x44, 0x75, 0x1b, 0xcb, 0x01, 0xc2, 0xea, 0x02, 0xec, 0x67, 0x52, - 0x3e, 0xfa, 0x82, 0xbf, 0x67, 0x13, 0x6a, 0x3e, 0x0f, 0x62, 0x06, 0x70, 0x5c, 0x04, 0x07, 0xb8, 0xe3, 0xea, 0x0a, - 0xb3, 0x2f, 0xf1, 0x69, 0x75, 0x01, 0xd0, 0x5b, 0x41, 0xd4, 0x8d, 0x0a, 0x19, 0x56, 0x86, 0xde, 0x18, 0x8b, 0x70, - 0x1c, 0x40, 0xc8, 0x12, 0x7c, 0xa6, 0xc1, 0x29, 0x21, 0xa4, 0xd5, 0x9f, 0x05, 0x5f, 0xe2, 0x9b, 0x98, 0xa6, 0xc1, - 0xbc, 0xe8, 0x96, 0x04, 0xa0, 0x22, 0xa6, 0x6f, 0x45, 0x79, 0x6f, 0x9c, 0xa4, 0x8a, 0xea, 0xb5, 0x82, 0xb3, 0x59, - 0x52, 0xcf, 0x96, 0x58, 0x9a, 0xe5, 0x93, 0x19, 0x25, 0xfc, 0xa6, 0x79, 0xeb, 0xf6, 0x36, 0xc7, 0xd7, 0x60, 0x76, - 0x65, 0x7c, 0xed, 0x25, 0x00, 0x5b, 0x3e, 0xbd, 0x0f, 0xc7, 0xe5, 0xef, 0x57, 0x34, 0xcf, 0xc3, 0xb1, 0xae, 0xb9, - 0x3d, 0x9e, 0x26, 0x41, 0xb4, 0x63, 0x69, 0x06, 0x08, 0x88, 0x89, 0x01, 0x46, 0xc0, 0xa7, 0xa1, 0x43, 0x64, 0x30, - 0xf5, 0x7a, 0x74, 0x4d, 0xe2, 0xaa, 0x5e, 0x24, 0xc2, 0x71, 0x55, 0x70, 0x32, 0xcd, 0xa8, 0x2c, 0x55, 0x68, 0x2c, - 0x4e, 0xf6, 0xa1, 0x40, 0xbd, 0xde, 0x12, 0x45, 0x33, 0x0e, 0x94, 0xed, 0xb1, 0x34, 0xc7, 0x44, 0xd1, 0xec, 0x44, - 0xa5, 0x32, 0x4b, 0x69, 0x3d, 0x76, 0xf3, 0x79, 0x7b, 0x08, 0x7f, 0x74, 0x64, 0xe8, 0xf3, 0xd1, 0x68, 0x74, 0x6f, - 0x54, 0xed, 0xf3, 0x68, 0x44, 0x3b, 0xf4, 0xa8, 0x0b, 0x49, 0x2c, 0x4d, 0x1d, 0x8b, 0x69, 0x17, 0x12, 0x77, 0x8b, - 0x87, 0x55, 0x86, 0xb0, 0x8d, 0x88, 0x17, 0x0f, 0x8f, 0xb0, 0x15, 0xd3, 0x8c, 0x2e, 0x26, 0x61, 0x36, 0x66, 0x69, - 0xd0, 0x2a, 0xfc, 0xb9, 0x0e, 0x49, 0x7d, 0x7e, 0x7c, 0x7c, 0x5c, 0xf8, 0x91, 0x79, 0x6a, 0x45, 0x51, 0xe1, 0x0f, - 0x17, 0xe5, 0x34, 0x5a, 0xad, 0xd1, 0xa8, 0xf0, 0x99, 0x29, 0x38, 0xe8, 0x0c, 0xa3, 0x83, 0x4e, 0xe1, 0xdf, 0x58, - 0x35, 0x0a, 0x9f, 0xea, 0xa7, 0x8c, 0x46, 0xb5, 0x4c, 0x98, 0xc7, 0xad, 0x56, 0xe1, 0x2b, 0x42, 0x5b, 0x80, 0x59, - 0xaa, 0x7e, 0x06, 0xe1, 0x4c, 0x70, 0x60, 0xee, 0xdd, 0x44, 0x78, 0x83, 0x4b, 0x7d, 0xcb, 0x88, 0xfa, 0x26, 0x47, - 0x81, 0x2e, 0xf0, 0xcf, 0x76, 0xf0, 0x08, 0x88, 0x59, 0x06, 0x8d, 0x12, 0x13, 0x5b, 0xaa, 0xbd, 0x06, 0xca, 0x92, - 0xaf, 0x7f, 0x26, 0x49, 0x15, 0x53, 0x02, 0x4e, 0x06, 0x35, 0xd5, 0x65, 0x78, 0x94, 0x6e, 0x91, 0x1f, 0xec, 0xd3, - 0xf2, 0xe3, 0xee, 0x21, 0xe2, 0x83, 0xfd, 0xe1, 0xe2, 0x83, 0x52, 0x4b, 0x7c, 0x28, 0xe6, 0x71, 0x27, 0x88, 0x3b, - 0x8c, 0xe9, 0xf0, 0xe3, 0x35, 0xbf, 0x6d, 0xc2, 0x96, 0xc8, 0x5c, 0x29, 0x58, 0x76, 0x7f, 0x6b, 0xd6, 0x8c, 0xe9, - 0xcc, 0xfa, 0xa2, 0x87, 0x54, 0x1f, 0xde, 0xa4, 0xc4, 0x7d, 0x63, 0x6c, 0x5b, 0x55, 0x32, 0x1a, 0x11, 0xf7, 0xcd, - 0x68, 0xe4, 0x9a, 0xb3, 0x92, 0xa1, 0xa0, 0xb2, 0xd6, 0xeb, 0x5a, 0x89, 0xac, 0xf5, 0xe5, 0x97, 0x76, 0x99, 0x5d, - 0xa0, 0x43, 0x4f, 0x76, 0x98, 0x49, 0xbf, 0x89, 0x58, 0x0e, 0x5b, 0x0d, 0x3e, 0x34, 0x52, 0xbf, 0xab, 0x31, 0xad, - 0x5d, 0xab, 0x5d, 0x02, 0xbc, 0xe1, 0x2e, 0xf0, 0xd5, 0x8b, 0x02, 0xc6, 0xd4, 0xe4, 0x2d, 0x3e, 0xbd, 0xfb, 0x2a, - 0xf2, 0xee, 0x04, 0x2a, 0x58, 0xfe, 0x26, 0x5d, 0x39, 0x04, 0xa4, 0x60, 0x24, 0xc4, 0x9e, 0x56, 0x21, 0xf8, 0x78, - 0x9c, 0xc0, 0xb7, 0x5e, 0x16, 0xb5, 0xfb, 0x63, 0x55, 0xf3, 0x7e, 0x6d, 0xbe, 0x81, 0xdd, 0x50, 0xdf, 0xb6, 0x2a, - 0x3f, 0x3d, 0xa5, 0x92, 0xc7, 0xe7, 0xfa, 0x1b, 0x44, 0xd2, 0x2c, 0x5e, 0x68, 0x26, 0xbf, 0x50, 0x29, 0xc7, 0x02, - 0xd2, 0x6d, 0x54, 0xc7, 0x51, 0x51, 0xe8, 0xc3, 0x1a, 0x11, 0xcb, 0xa7, 0x70, 0xaf, 0xa9, 0x6a, 0x49, 0x3f, 0xc5, - 0xc2, 0xf3, 0x1b, 0x2b, 0xbe, 0x53, 0x5b, 0xae, 0xc2, 0x04, 0x78, 0x94, 0xc3, 0xfc, 0x4e, 0x14, 0xae, 0xf6, 0xbb, - 0x1b, 0x24, 0xba, 0x8e, 0xc2, 0xa7, 0x8a, 0x3c, 0x59, 0x33, 0x04, 0xe7, 0x77, 0xb9, 0x20, 0xe6, 0x95, 0x29, 0x28, - 0xec, 0xf8, 0xa5, 0x7c, 0xa3, 0xb0, 0x25, 0xa3, 0x25, 0xf9, 0x34, 0x4c, 0x15, 0x1b, 0x25, 0xae, 0xe2, 0x07, 0xbb, - 0x8b, 0x6a, 0xe5, 0x0b, 0xd7, 0x80, 0xad, 0x88, 0xb7, 0x77, 0xb2, 0x0f, 0x0d, 0x7a, 0x4e, 0x0d, 0xf4, 0x74, 0x2d, - 0xc8, 0xf2, 0x89, 0x74, 0x87, 0x2b, 0x3f, 0xbf, 0xc1, 0x7e, 0x7e, 0xe3, 0xfc, 0x79, 0xd1, 0xbc, 0xa1, 0xd7, 0x1f, - 0x99, 0x68, 0x8a, 0x70, 0xda, 0x04, 0xc3, 0x47, 0x3a, 0x47, 0x35, 0x7b, 0x96, 0x59, 0x7e, 0xea, 0xaa, 0x83, 0xee, - 0x2c, 0x87, 0xac, 0x08, 0xa9, 0xbe, 0x07, 0x29, 0x4f, 0x69, 0xb7, 0x9e, 0xcd, 0x69, 0x07, 0xd9, 0x0d, 0xb6, 0x2e, - 0x16, 0x1c, 0xb2, 0x28, 0xc4, 0x5d, 0xd0, 0xd2, 0x6c, 0xbd, 0x65, 0x22, 0xe8, 0xad, 0x8d, 0xf5, 0x03, 0x8d, 0xdc, - 0x86, 0x94, 0x5e, 0xd9, 0x7a, 0x26, 0xc1, 0xb6, 0x4c, 0x80, 0x4f, 0xe5, 0x36, 0x82, 0x4b, 0xd5, 0xfc, 0xb5, 0x92, - 0x42, 0x57, 0x8b, 0x65, 0x6e, 0xe3, 0x43, 0x20, 0x0b, 0xc2, 0x91, 0xa0, 0x19, 0x7e, 0x48, 0xcd, 0x6b, 0x79, 0x0c, - 0x69, 0x01, 0x62, 0x26, 0x68, 0x1f, 0x4f, 0x6f, 0x1f, 0xde, 0xfd, 0xfd, 0xd3, 0x2f, 0x34, 0x8e, 0xcc, 0xb5, 0x3c, - 0xae, 0xdb, 0x85, 0x8d, 0x90, 0x84, 0x77, 0x01, 0x4b, 0xa5, 0xcc, 0xbb, 0x06, 0xbf, 0x68, 0x77, 0xca, 0x75, 0x92, - 0x6e, 0x46, 0x13, 0xf9, 0x15, 0x3e, 0xbd, 0x14, 0x07, 0x8f, 0xa6, 0xb7, 0x66, 0x35, 0xda, 0x2b, 0xc9, 0xb7, 0x7f, - 0x68, 0x8e, 0xed, 0xf6, 0xa4, 0xde, 0x7a, 0x9e, 0xe8, 0xd1, 0xf4, 0xb6, 0xab, 0x04, 0x6d, 0x33, 0x53, 0x50, 0xb5, - 0xa6, 0xb7, 0x76, 0x96, 0x71, 0xd5, 0x91, 0xe3, 0x1f, 0xe4, 0x0e, 0x0d, 0x73, 0xda, 0x85, 0x7b, 0xc7, 0xd9, 0x30, - 0x4c, 0xb4, 0x30, 0x9f, 0xb0, 0x28, 0x4a, 0x68, 0xd7, 0xc8, 0x6b, 0xa7, 0xfd, 0x08, 0x92, 0x74, 0xed, 0x25, 0xab, - 0xaf, 0x8a, 0x85, 0xbc, 0x12, 0x4f, 0xe1, 0x75, 0xce, 0x13, 0xf8, 0xe8, 0xc7, 0x46, 0x74, 0xea, 0xec, 0xd5, 0x56, - 0x85, 0x3c, 0xf9, 0xbb, 0x3e, 0x97, 0xa3, 0xd6, 0x9f, 0xba, 0x72, 0xc1, 0x5b, 0x5d, 0xc1, 0xa7, 0x41, 0xf3, 0xa0, - 0x3e, 0x11, 0x78, 0x55, 0x4e, 0x01, 0x6f, 0x98, 0x16, 0x06, 0x69, 0xa5, 0xf8, 0xb4, 0xe3, 0xb7, 0x75, 0x99, 0xec, - 0x00, 0xf2, 0xc2, 0xca, 0xa2, 0xa2, 0x3e, 0x99, 0x7f, 0x9b, 0xdd, 0xf2, 0x64, 0xf3, 0x6e, 0x79, 0x62, 0x76, 0xcb, - 0xfd, 0x14, 0xfb, 0xf9, 0xa8, 0x0d, 0x7f, 0xba, 0xd5, 0x84, 0x82, 0x96, 0x73, 0x30, 0xbd, 0x75, 0x40, 0x4f, 0x6b, - 0x76, 0xa6, 0xb7, 0x2a, 0xc7, 0x1a, 0x62, 0x37, 0x2d, 0xc8, 0x3a, 0xc6, 0x2d, 0x07, 0x0a, 0xe1, 0x6f, 0xab, 0xf6, - 0xaa, 0x7d, 0x08, 0xef, 0xa0, 0xd5, 0xd1, 0xfa, 0xbb, 0xce, 0xfd, 0x9b, 0x36, 0x48, 0xb9, 0xf0, 0x02, 0xc3, 0x8d, - 0x91, 0x2f, 0xc2, 0xeb, 0x6b, 0x1a, 0x05, 0x23, 0x3e, 0x9c, 0xe5, 0xff, 0xa4, 0xe1, 0xd7, 0x48, 0xbc, 0x77, 0x4b, - 0xaf, 0xf4, 0x63, 0x9a, 0xaa, 0x8c, 0x6f, 0xd3, 0xc3, 0xa2, 0x5c, 0xa7, 0x20, 0x1f, 0x86, 0x09, 0xf5, 0x3a, 0xfe, - 0xe1, 0x86, 0x4d, 0xf0, 0xef, 0xb2, 0x36, 0x1b, 0x27, 0xf3, 0x7b, 0x91, 0x71, 0x2f, 0x12, 0x7e, 0x15, 0x0e, 0xec, - 0x35, 0x6c, 0x1d, 0x6f, 0x06, 0x77, 0x60, 0x46, 0xba, 0x30, 0x42, 0x41, 0xcb, 0x9d, 0x88, 0x8e, 0xc2, 0x59, 0x22, - 0xee, 0xef, 0x75, 0x1b, 0x65, 0xac, 0xf5, 0x7a, 0x0f, 0x43, 0xaf, 0xea, 0x3e, 0x90, 0x4b, 0x7f, 0xfe, 0xe4, 0x10, - 0xfe, 0xa8, 0xfc, 0xaf, 0xbb, 0x4a, 0x57, 0x57, 0x76, 0x2f, 0xe8, 0xea, 0xbb, 0x35, 0x65, 0x5c, 0x89, 0x70, 0xa9, - 0x8f, 0x3f, 0xb4, 0x36, 0x68, 0x95, 0x0f, 0xaa, 0xae, 0xb5, 0xac, 0x5f, 0x55, 0xfb, 0xd7, 0x75, 0xfe, 0xc0, 0xba, - 0x43, 0xa5, 0xb9, 0xd6, 0xeb, 0xea, 0xcf, 0x10, 0xae, 0x55, 0x36, 0x18, 0x97, 0xf5, 0x77, 0xc9, 0x5d, 0x69, 0xa2, - 0xa8, 0x68, 0x2c, 0x58, 0x29, 0xbb, 0xca, 0x4a, 0xc9, 0x29, 0xb9, 0x3a, 0xe9, 0xdf, 0x4e, 0x12, 0x67, 0xae, 0x8e, - 0x4b, 0x12, 0xb7, 0xed, 0xb7, 0x5c, 0x47, 0xe6, 0x01, 0xc0, 0xad, 0xed, 0xae, 0xfc, 0xbc, 0xad, 0xdb, 0x07, 0x4d, - 0x6b, 0x3e, 0x96, 0x9a, 0xdd, 0xcb, 0xf0, 0x8e, 0x66, 0x97, 0x1d, 0xd7, 0x01, 0x3f, 0x4d, 0x53, 0xa5, 0x4c, 0xc8, - 0x32, 0xa7, 0xe3, 0x3a, 0xb7, 0x93, 0x24, 0xcd, 0x89, 0x1b, 0x0b, 0x31, 0x0d, 0xd4, 0xf7, 0x6f, 0x6f, 0x0e, 0x7c, - 0x9e, 0x8d, 0xf7, 0x3b, 0xad, 0x56, 0x0b, 0x2e, 0x80, 0x75, 0x9d, 0x39, 0xa3, 0x37, 0x4f, 0xf9, 0x2d, 0x71, 0x5b, - 0x4e, 0xcb, 0x69, 0x77, 0x8e, 0x9d, 0x76, 0xe7, 0xd0, 0x7f, 0x74, 0xec, 0xf6, 0x3e, 0x73, 0x9c, 0x93, 0x88, 0x8e, - 0x72, 0xf8, 0xe1, 0x38, 0x27, 0x52, 0xf1, 0x52, 0xbf, 0x1d, 0xc7, 0x1f, 0x26, 0x79, 0xb3, 0xed, 0x2c, 0xf4, 0xa3, - 0xe3, 0xc0, 0xa1, 0xd2, 0xc0, 0xf9, 0x7c, 0xd4, 0x19, 0x1d, 0x8e, 0x9e, 0x74, 0x75, 0x71, 0xf1, 0x59, 0xad, 0x3a, - 0x56, 0xff, 0x77, 0xac, 0x66, 0xb9, 0xc8, 0xf8, 0x47, 0xaa, 0x73, 0x12, 0x1d, 0x10, 0x3d, 0x1b, 0x9b, 0x76, 0xd6, - 0x47, 0x6a, 0x1f, 0x5f, 0x0f, 0x47, 0x9d, 0xaa, 0xba, 0x84, 0x71, 0xbf, 0x04, 0xf2, 0x64, 0xdf, 0x80, 0x7e, 0x62, - 0xa3, 0xa9, 0xdd, 0xdc, 0x84, 0xa8, 0xb6, 0xab, 0xe7, 0x38, 0x36, 0xf3, 0x3b, 0x81, 0x33, 0x0c, 0x46, 0x57, 0x95, - 0x10, 0xb8, 0x4e, 0x44, 0xdc, 0x57, 0xed, 0xce, 0x31, 0x6e, 0xb7, 0x1f, 0xf9, 0x8f, 0x8e, 0x87, 0x2d, 0x7c, 0xe8, - 0x1f, 0x36, 0x0f, 0xfc, 0x47, 0xf8, 0xb8, 0x79, 0x8c, 0x8f, 0x5f, 0x1c, 0x0f, 0x9b, 0x87, 0xfe, 0x21, 0x6e, 0x35, - 0x8f, 0xa1, 0xb0, 0x79, 0xdc, 0x3c, 0x9e, 0x37, 0x0f, 0x8f, 0x87, 0x2d, 0x59, 0xda, 0xf1, 0x8f, 0x8e, 0x9a, 0xed, - 0x96, 0x7f, 0x74, 0x84, 0x8f, 0xfc, 0x47, 0x8f, 0x9a, 0xed, 0x03, 0xff, 0xd1, 0xa3, 0x97, 0x47, 0xc7, 0xfe, 0x01, - 0xbc, 0x3b, 0x38, 0x18, 0x1e, 0xf8, 0xed, 0x76, 0x13, 0xfe, 0xc1, 0xc7, 0x7e, 0x47, 0xfd, 0x68, 0xb7, 0xfd, 0x83, - 0x36, 0x6e, 0x25, 0x47, 0x1d, 0xff, 0xd1, 0x13, 0x2c, 0xff, 0x95, 0xd5, 0xb0, 0xfc, 0x07, 0xba, 0xc1, 0x4f, 0xfc, - 0xce, 0x23, 0xf5, 0x4b, 0x76, 0x38, 0x3f, 0x3c, 0xfe, 0xc1, 0xdd, 0xdf, 0x3a, 0x87, 0xb6, 0x9a, 0xc3, 0xf1, 0x91, - 0x7f, 0x70, 0x80, 0x0f, 0xdb, 0xfe, 0xf1, 0x41, 0xdc, 0x3c, 0xec, 0xf8, 0x8f, 0x1e, 0x0f, 0x9b, 0x6d, 0xff, 0xf1, - 0x63, 0xdc, 0x6a, 0x1e, 0xf8, 0x1d, 0xdc, 0xf6, 0x0f, 0x0f, 0xe4, 0x8f, 0x03, 0xbf, 0x33, 0x7f, 0xfc, 0xc4, 0x7f, - 0x74, 0x14, 0x3f, 0xf2, 0x0f, 0xbf, 0x3d, 0x3c, 0xf6, 0x3b, 0x07, 0xf1, 0xc1, 0x23, 0xbf, 0xf3, 0x78, 0xfe, 0xc8, - 0x3f, 0x8c, 0x9b, 0x9d, 0x47, 0xf7, 0xb6, 0x6c, 0x77, 0x7c, 0xc0, 0x91, 0x7c, 0x0d, 0x2f, 0xb0, 0x7e, 0x01, 0x7f, - 0x63, 0xd9, 0xf6, 0xdf, 0xb1, 0x9b, 0x7c, 0xbd, 0xe9, 0x13, 0xff, 0xf8, 0xf1, 0x50, 0x55, 0x87, 0x82, 0xa6, 0xa9, - 0x01, 0x4d, 0xe6, 0x4d, 0x35, 0xac, 0xec, 0xae, 0x69, 0x3a, 0x32, 0x7f, 0xf5, 0x60, 0xf3, 0x26, 0x0c, 0xac, 0xc6, - 0xfd, 0x0f, 0xed, 0xa7, 0x5c, 0xf2, 0x93, 0xfd, 0xb1, 0x22, 0xfd, 0x71, 0xef, 0x33, 0x75, 0xbb, 0xf3, 0x67, 0x57, - 0x38, 0xdd, 0xe6, 0xf8, 0xc8, 0x3e, 0xed, 0xf8, 0xe0, 0xf4, 0x21, 0x9e, 0x8f, 0xec, 0x0f, 0xf7, 0x7c, 0xa4, 0x74, - 0xc5, 0x71, 0x7e, 0x2d, 0xd6, 0x1c, 0x1c, 0xab, 0x56, 0xf1, 0x53, 0xe1, 0x0d, 0x72, 0xf8, 0x8e, 0x58, 0xd1, 0xbd, - 0x16, 0x84, 0x53, 0xdb, 0x0f, 0xc4, 0x81, 0xc5, 0x5e, 0x0b, 0xc5, 0x63, 0x93, 0x6d, 0x08, 0x09, 0x3f, 0x8d, 0x90, - 0x6f, 0x1f, 0x82, 0x8f, 0xf0, 0x0f, 0xc7, 0x47, 0x62, 0xe3, 0xa3, 0xe6, 0xcb, 0x97, 0x9e, 0x06, 0xe9, 0x29, 0x38, - 0x97, 0xcf, 0x1e, 0x1c, 0xa2, 0x6a, 0xb8, 0xfb, 0x14, 0x8a, 0x72, 0x57, 0x45, 0xbe, 0xde, 0xfd, 0x9a, 0xb0, 0x83, - 0x3a, 0x31, 0x49, 0x5c, 0xed, 0x96, 0x99, 0x4a, 0xa9, 0xa3, 0x1f, 0x4a, 0xa1, 0xd4, 0xf1, 0x5b, 0x7e, 0xab, 0x74, - 0xe9, 0xc0, 0x29, 0x59, 0xb2, 0xe0, 0x22, 0x84, 0x2f, 0xd6, 0x26, 0x7c, 0x2c, 0xbf, 0x6d, 0x0b, 0x5f, 0x13, 0x80, - 0xa4, 0x9f, 0xa1, 0xfa, 0x90, 0x43, 0xe0, 0xba, 0xfa, 0x6e, 0x0d, 0x38, 0x85, 0xf9, 0x0d, 0x9c, 0x54, 0x35, 0x51, - 0x89, 0x09, 0x78, 0x3b, 0x5e, 0xd1, 0x88, 0x85, 0x9e, 0xeb, 0x4d, 0x33, 0x3a, 0xa2, 0x59, 0xde, 0xac, 0x1d, 0xdf, - 0x94, 0x27, 0x37, 0x91, 0x6b, 0x3e, 0x8d, 0x9a, 0xc1, 0xed, 0xd8, 0x64, 0xa0, 0xfd, 0x8d, 0xae, 0x36, 0xc0, 0xdc, - 0x02, 0x9b, 0x92, 0x0c, 0x64, 0x6d, 0xa5, 0xb4, 0xb9, 0x4a, 0x6b, 0x6b, 0xfb, 0x9d, 0x23, 0xe4, 0xc8, 0x62, 0xb8, - 0x77, 0xf8, 0x7b, 0xaf, 0x79, 0xd0, 0xfa, 0x13, 0xb2, 0x9a, 0x95, 0x1d, 0x5d, 0x68, 0x77, 0x5b, 0x5a, 0x7d, 0x53, - 0xba, 0x7e, 0xb6, 0xd6, 0x55, 0x14, 0xf1, 0xb9, 0x9a, 0xbb, 0x8b, 0xba, 0xa9, 0x8e, 0x70, 0xab, 0x1b, 0x22, 0x46, - 0x6c, 0xec, 0xd9, 0x5f, 0x0c, 0x56, 0xf7, 0x1a, 0xcb, 0x0f, 0x8d, 0xa3, 0xa2, 0xaa, 0x92, 0xa2, 0x85, 0x8c, 0xb7, - 0xb0, 0xd4, 0x49, 0x97, 0x4b, 0x2f, 0x05, 0x17, 0x39, 0xb1, 0x70, 0x0a, 0xcf, 0xa8, 0x86, 0xe4, 0x14, 0x97, 0x00, - 0x49, 0x04, 0x93, 0x54, 0xfd, 0x5f, 0x15, 0x9b, 0x1f, 0xda, 0xf1, 0xe5, 0x27, 0x61, 0x3a, 0x06, 0x2a, 0x0c, 0xd3, - 0xf1, 0x9a, 0x5b, 0x4d, 0x85, 0x8c, 0x56, 0x4a, 0xab, 0xae, 0x2a, 0xf7, 0x59, 0xfe, 0xf4, 0xee, 0xbd, 0xbe, 0x00, - 0xcd, 0x05, 0xef, 0xb4, 0x8c, 0x70, 0x54, 0x97, 0x35, 0x37, 0xc8, 0x17, 0x27, 0x13, 0x2a, 0x42, 0x95, 0xaf, 0x09, - 0xfa, 0x04, 0x9c, 0x9a, 0x75, 0xb4, 0x35, 0x4a, 0x5c, 0x29, 0xdd, 0x49, 0x44, 0xe7, 0x6c, 0xa8, 0x45, 0x3d, 0x76, - 0xf4, 0xcd, 0x01, 0x4d, 0xb9, 0x34, 0xa4, 0x8d, 0x95, 0x3f, 0x66, 0x18, 0xca, 0x8c, 0x7c, 0x92, 0x72, 0xb7, 0xf7, - 0x45, 0xf9, 0xf5, 0xd3, 0x6d, 0x8b, 0x90, 0xb0, 0xf4, 0xe3, 0x20, 0xa3, 0xc9, 0x3f, 0x91, 0x2f, 0xd8, 0x90, 0xa7, - 0x5f, 0x5c, 0xc0, 0x57, 0xe9, 0xfd, 0x38, 0xa3, 0x23, 0xf2, 0x05, 0xc8, 0xf8, 0x40, 0x5a, 0x1f, 0xc0, 0x08, 0x1b, - 0xb7, 0x93, 0x04, 0x4b, 0x8d, 0xe9, 0x01, 0x0a, 0x91, 0x02, 0xd7, 0xed, 0x1c, 0xb9, 0x8e, 0xb2, 0x89, 0xe5, 0xef, - 0x9e, 0x12, 0xa7, 0x52, 0x09, 0x70, 0xda, 0x1d, 0xff, 0x28, 0xee, 0xf8, 0x4f, 0xe6, 0x8f, 0xfd, 0xe3, 0xb8, 0xfd, - 0x78, 0xde, 0x84, 0xff, 0x3b, 0xfe, 0x93, 0xa4, 0xd9, 0xf1, 0x9f, 0xc0, 0xdf, 0x6f, 0x0f, 0xfd, 0xa3, 0xb8, 0xd9, - 0xf6, 0x8f, 0xe7, 0x07, 0xfe, 0xc1, 0xcb, 0x76, 0xc7, 0x3f, 0x70, 0xda, 0x8e, 0x6a, 0x07, 0xec, 0x5a, 0x71, 0xe7, - 0x2f, 0x56, 0x36, 0xc4, 0x86, 0x70, 0x9c, 0xca, 0x39, 0x75, 0xb1, 0x57, 0x7e, 0x63, 0x51, 0xef, 0x4f, 0xed, 0xac, - 0x7b, 0x16, 0x66, 0xf0, 0xa1, 0x9b, 0xfa, 0xde, 0xad, 0xbd, 0xc3, 0x35, 0x7e, 0xb1, 0x61, 0x08, 0xd8, 0xe1, 0x2e, - 0xb6, 0x8f, 0xde, 0xc3, 0xb9, 0x75, 0x79, 0x2f, 0xb8, 0xb9, 0x1e, 0x71, 0x3b, 0x69, 0xab, 0x8a, 0xe6, 0x0a, 0x46, - 0xc9, 0x2c, 0x98, 0xfc, 0x02, 0x83, 0x1c, 0xe4, 0xab, 0xa8, 0x58, 0x1d, 0x1f, 0x52, 0x5f, 0x33, 0x6e, 0xdd, 0x3e, - 0x40, 0xab, 0x03, 0x1b, 0x11, 0x83, 0xfb, 0x22, 0x8a, 0xc2, 0x80, 0x5e, 0x73, 0xd3, 0x56, 0x58, 0x92, 0xfc, 0x82, - 0xe6, 0x7d, 0x17, 0x8a, 0xdc, 0xc0, 0x95, 0x2e, 0x3e, 0xb7, 0xfc, 0xd8, 0x4f, 0x49, 0xd8, 0x55, 0x01, 0x96, 0x87, - 0xae, 0x60, 0xd7, 0x02, 0x7e, 0x5c, 0xb4, 0xb7, 0xb7, 0x75, 0xbf, 0x48, 0x05, 0x12, 0xe6, 0x5a, 0x7d, 0x23, 0xc4, - 0x66, 0x45, 0xae, 0x8d, 0xe8, 0xb2, 0x5f, 0x89, 0x42, 0xa4, 0xf1, 0x74, 0x4d, 0x43, 0xe1, 0x87, 0xa9, 0x4a, 0xa2, - 0xb1, 0x18, 0x16, 0x6e, 0xd3, 0x03, 0x54, 0x70, 0x11, 0x5a, 0xdf, 0x01, 0xd6, 0xfb, 0x9c, 0x8b, 0xd0, 0x9c, 0xa5, - 0xb5, 0xae, 0x0d, 0x02, 0x47, 0x6f, 0xdc, 0xe9, 0xbd, 0x79, 0x7f, 0xea, 0xa8, 0xed, 0x79, 0xb2, 0x1f, 0x77, 0x7a, - 0x27, 0xd2, 0x67, 0xa2, 0x4e, 0xe2, 0x11, 0x75, 0x12, 0xcf, 0xd1, 0xa7, 0x32, 0x21, 0x92, 0x56, 0xec, 0xab, 0x69, - 0x4b, 0x9b, 0x41, 0x79, 0x7b, 0x27, 0xb3, 0x44, 0x30, 0xb8, 0xe3, 0x7a, 0x5f, 0x1e, 0xc3, 0x83, 0x05, 0x2b, 0xf3, - 0xb0, 0xb5, 0x76, 0x78, 0x2d, 0x52, 0xe3, 0x1b, 0x1e, 0xb1, 0x84, 0x9a, 0xcc, 0x6b, 0xdd, 0x55, 0x79, 0x52, 0x60, - 0xbd, 0x76, 0x3e, 0xbb, 0x9e, 0x30, 0xe1, 0x9a, 0xf3, 0x0c, 0x1f, 0x74, 0x83, 0x13, 0x39, 0x54, 0xef, 0xaa, 0xd0, - 0xce, 0x6b, 0xf3, 0x35, 0x9f, 0xfa, 0x92, 0xea, 0xd9, 0x6b, 0x09, 0x01, 0x27, 0xe4, 0xe2, 0x83, 0x5e, 0xe9, 0x2e, - 0xb6, 0xdf, 0x15, 0x27, 0xfb, 0xf1, 0x41, 0xef, 0x2a, 0x98, 0xea, 0xfe, 0x5e, 0xf2, 0xf1, 0xe6, 0xbe, 0x12, 0x3e, - 0xee, 0xcb, 0xa3, 0x20, 0xea, 0x90, 0xb2, 0x51, 0x7e, 0x79, 0xe2, 0xf6, 0x4e, 0xb4, 0x32, 0xe0, 0xc8, 0xc0, 0xba, - 0x7b, 0xd4, 0x32, 0xa7, 0x4b, 0x12, 0x3e, 0x86, 0x0d, 0xa9, 0x9a, 0x58, 0x83, 0xd4, 0x3c, 0xee, 0x71, 0xbb, 0x77, - 0x12, 0x3a, 0x92, 0xb7, 0x48, 0xe6, 0x91, 0x07, 0xfb, 0xd0, 0x38, 0xe6, 0x13, 0xea, 0x33, 0xbe, 0x7f, 0x43, 0xaf, - 0x9b, 0xe1, 0x94, 0x55, 0xee, 0x6d, 0x50, 0x3a, 0xca, 0x21, 0xb9, 0xf1, 0x88, 0xeb, 0xb3, 0x57, 0x9d, 0xca, 0xdd, - 0x76, 0x08, 0x36, 0x8f, 0x71, 0xcd, 0x49, 0x9f, 0x9c, 0x05, 0x16, 0xef, 0x9d, 0xec, 0x87, 0x2b, 0x18, 0x91, 0xfc, - 0xbe, 0xd0, 0x8e, 0x76, 0x30, 0x6c, 0x80, 0xde, 0x5c, 0x47, 0x89, 0x03, 0xe3, 0x90, 0xd7, 0x82, 0xba, 0x70, 0x7b, - 0xff, 0xfa, 0x3f, 0xfe, 0x97, 0xf6, 0xb1, 0x9f, 0xec, 0xc7, 0x6d, 0xd3, 0xd7, 0xca, 0xaa, 0x14, 0x27, 0x70, 0xdc, - 0xb3, 0x0a, 0x0a, 0xd3, 0xdb, 0xe6, 0x38, 0x63, 0x51, 0x33, 0x0e, 0x93, 0x91, 0xdb, 0xdb, 0x8e, 0x4d, 0xfb, 0xd8, - 0x96, 0x86, 0xba, 0x5e, 0x04, 0xf4, 0xfa, 0x9b, 0x0e, 0x1e, 0x99, 0xf3, 0x2b, 0x72, 0x6b, 0xdb, 0xc7, 0x90, 0xaa, - 0xdd, 0x57, 0x3b, 0x8a, 0x94, 0xea, 0x4f, 0x84, 0x69, 0x0e, 0x98, 0xd6, 0x4e, 0x20, 0x15, 0xae, 0x53, 0x06, 0xb5, - 0xfe, 0xef, 0xff, 0xfc, 0x2f, 0xff, 0xcd, 0x3c, 0x42, 0xac, 0xea, 0x5f, 0xff, 0xfb, 0x7f, 0xfe, 0x3f, 0xff, 0xfb, - 0xbf, 0xc2, 0xa9, 0x15, 0x1d, 0xcf, 0x92, 0x4c, 0xc5, 0xa9, 0x82, 0x59, 0x8a, 0xbb, 0x38, 0x90, 0xd8, 0x39, 0x61, - 0xb9, 0x60, 0xc3, 0xfa, 0x99, 0xa4, 0x73, 0x39, 0xa0, 0xdc, 0x99, 0x1a, 0x3a, 0xb9, 0xc3, 0x8b, 0x8a, 0xa0, 0x6a, - 0x28, 0x97, 0x84, 0x5b, 0x9c, 0xec, 0x03, 0xbe, 0x1f, 0x76, 0x8c, 0xd3, 0x2f, 0x97, 0x63, 0x61, 0xc8, 0x04, 0x4a, - 0x8a, 0xaa, 0xdc, 0x81, 0xd8, 0xca, 0x02, 0x1e, 0x83, 0x8e, 0x55, 0x2c, 0x57, 0xaf, 0xd6, 0xa6, 0xfb, 0xd3, 0x2c, - 0x17, 0x6c, 0x04, 0x28, 0x57, 0x7e, 0x62, 0x19, 0xc6, 0x6e, 0x82, 0xae, 0x98, 0xdc, 0x15, 0xb2, 0x17, 0x45, 0xa0, - 0x87, 0xc7, 0x7f, 0x2a, 0xfe, 0x32, 0x01, 0x8d, 0xcc, 0xf1, 0x26, 0xe1, 0xad, 0x36, 0xcf, 0x1f, 0xb5, 0x5a, 0xd3, - 0x5b, 0xb4, 0xa8, 0x46, 0xc0, 0xdb, 0x06, 0x93, 0x74, 0x6c, 0x77, 0x28, 0xe3, 0xdf, 0xa5, 0x1b, 0xbb, 0xe5, 0x80, - 0x2f, 0xdc, 0x69, 0x15, 0xc5, 0x9f, 0x17, 0xd2, 0x93, 0xca, 0x7e, 0x81, 0x38, 0xb5, 0x76, 0x3a, 0x5f, 0x73, 0x7b, - 0x72, 0x0b, 0xab, 0x55, 0x47, 0xb5, 0x8a, 0xdb, 0xeb, 0xa7, 0x13, 0xed, 0x38, 0xbb, 0x1d, 0x21, 0x3f, 0x84, 0x98, - 0x77, 0xdc, 0xc6, 0x71, 0x67, 0x51, 0x76, 0x2f, 0x04, 0x9f, 0xd8, 0x81, 0x75, 0x1a, 0xd2, 0x21, 0x1d, 0x19, 0x67, - 0xbd, 0x7e, 0xaf, 0x82, 0xe6, 0x45, 0x7c, 0xb0, 0x61, 0x2c, 0x0d, 0x92, 0x0c, 0xa8, 0x3b, 0xad, 0xe2, 0x73, 0xd8, - 0x81, 0x8b, 0x51, 0xc2, 0x43, 0x11, 0x48, 0x82, 0xed, 0xda, 0xe1, 0xf9, 0x10, 0x78, 0x12, 0x5f, 0x58, 0xf0, 0x74, - 0x55, 0x55, 0x70, 0x9b, 0xd7, 0xcf, 0x90, 0x16, 0xbe, 0x6c, 0x6e, 0x77, 0xa5, 0xbc, 0x6e, 0xdf, 0xea, 0xa8, 0xf7, - 0xbb, 0x9a, 0xbb, 0x4a, 0x0b, 0xa4, 0x0e, 0xda, 0xfc, 0x5e, 0xc9, 0x75, 0xf5, 0xf6, 0x6b, 0xe1, 0xb9, 0x12, 0x4c, - 0x77, 0xb5, 0x96, 0x2c, 0x84, 0x5a, 0xef, 0xc8, 0xb7, 0xa5, 0xc9, 0x14, 0x4e, 0xa7, 0xb2, 0x22, 0xea, 0x9e, 0xec, - 0x2b, 0x4d, 0x17, 0xb8, 0x87, 0x4c, 0xe9, 0x50, 0x19, 0x14, 0xba, 0x92, 0xde, 0x0a, 0xea, 0x97, 0xce, 0xad, 0x80, - 0x4f, 0xc7, 0xf5, 0xfe, 0x1f, 0xe7, 0xe0, 0x1c, 0x12, 0xcf, 0x89, 0x00, 0x00}; + 0xe4, 0x2b, 0x20, 0x44, 0x5b, 0x41, 0x6f, 0x36, 0xc1, 0x8b, 0x2e, 0x96, 0x41, 0x36, 0x19, 0x59, 0x76, 0xe2, 0x64, + 0xfb, 0x16, 0xcb, 0x4e, 0x76, 0xc2, 0x70, 0x4b, 0x10, 0xd1, 0x24, 0xda, 0x06, 0x01, 0x06, 0x68, 0x52, 0x52, 0x48, + 0x9c, 0x9a, 0x0f, 0x98, 0xaa, 0xa9, 0x9a, 0xa7, 0x79, 0x99, 0x9a, 0xf3, 0x30, 0x1f, 0x31, 0xcf, 0xe7, 0x53, 0xce, + 0x0f, 0xcc, 0x7c, 0xc2, 0xd4, 0xea, 0x0b, 0xd0, 0xe0, 0x45, 0x56, 0x2e, 0xe7, 0x9c, 0x29, 0x97, 0x6d, 0xa2, 0xd1, + 0x97, 0xd5, 0xab, 0x57, 0xaf, 0x7b, 0x37, 0xba, 0x7b, 0x41, 0x32, 0xe2, 0x77, 0x33, 0x6a, 0x85, 0x7c, 0x1a, 0xf5, + 0xba, 0xea, 0x5f, 0xea, 0x07, 0xbd, 0x6e, 0xc4, 0xe2, 0x8f, 0x56, 0x4a, 0x23, 0xc2, 0x46, 0x49, 0x6c, 0x85, 0x29, + 0x1d, 0x93, 0xc0, 0xe7, 0xbe, 0xc7, 0xa6, 0xfe, 0x84, 0x5a, 0x8d, 0x5e, 0x77, 0x4a, 0xb9, 0x6f, 0x8d, 0x42, 0x3f, + 0xcd, 0x28, 0x27, 0xef, 0xdf, 0x7d, 0x55, 0x3f, 0xed, 0x75, 0xb3, 0x51, 0xca, 0x66, 0xdc, 0x82, 0x2e, 0xc9, 0x34, + 0x09, 0xe6, 0x11, 0xed, 0x35, 0x1a, 0x37, 0x37, 0x37, 0xee, 0x87, 0xec, 0xb3, 0x51, 0x12, 0x67, 0xdc, 0x7a, 0x41, + 0x6e, 0x58, 0x1c, 0x24, 0x37, 0x98, 0x71, 0xf2, 0xc2, 0xbd, 0x08, 0xfd, 0x20, 0xb9, 0x79, 0x9b, 0x24, 0xfc, 0xe0, + 0xc0, 0x91, 0x8f, 0x77, 0xe7, 0x17, 0x17, 0x84, 0x90, 0x45, 0xc2, 0x02, 0xab, 0xb9, 0x5a, 0x95, 0x85, 0x6e, 0xec, + 0x73, 0xb6, 0xa0, 0xb2, 0x09, 0x3a, 0x38, 0xb0, 0xfd, 0x20, 0x99, 0x71, 0x1a, 0x5c, 0xf0, 0xbb, 0x88, 0x5e, 0x84, + 0x94, 0xf2, 0xcc, 0x66, 0xb1, 0xf5, 0x34, 0x19, 0xcd, 0xa7, 0x34, 0xe6, 0xee, 0x2c, 0x4d, 0x78, 0x02, 0x90, 0x1c, + 0x1c, 0xd8, 0x29, 0x9d, 0x45, 0xfe, 0x88, 0xc2, 0xfb, 0xf3, 0x8b, 0x8b, 0xb2, 0x45, 0x59, 0x09, 0x67, 0x9c, 0x5c, + 0xdc, 0x4d, 0xaf, 0x93, 0xc8, 0x41, 0xd8, 0xe7, 0x24, 0xa6, 0x37, 0xd6, 0x0f, 0xd4, 0xff, 0xf8, 0xd2, 0x9f, 0x75, + 0x46, 0x91, 0x9f, 0x65, 0xd6, 0x2d, 0x5f, 0x8a, 0x29, 0xa4, 0xf3, 0x11, 0x4f, 0x52, 0x87, 0x63, 0x8a, 0x19, 0x5a, + 0xb2, 0xb1, 0xc3, 0x43, 0x96, 0xb9, 0x97, 0xfb, 0xa3, 0x2c, 0x7b, 0x4b, 0xb3, 0x79, 0xc4, 0xf7, 0xc9, 0x5e, 0x13, + 0xb3, 0x3d, 0x42, 0x32, 0x8e, 0x78, 0x98, 0x26, 0x37, 0xd6, 0xb3, 0x34, 0x4d, 0x52, 0xc7, 0x3e, 0xbf, 0xb8, 0x90, + 0x35, 0x2c, 0x96, 0x59, 0x71, 0xc2, 0xad, 0xa2, 0x3f, 0xff, 0x3a, 0xa2, 0xae, 0xf5, 0x3e, 0xa3, 0xd6, 0xd5, 0x3c, + 0xce, 0xfc, 0x31, 0x3d, 0xbf, 0xb8, 0xb8, 0xb2, 0x92, 0xd4, 0xba, 0x1a, 0x65, 0xd9, 0x95, 0xc5, 0xe2, 0x8c, 0x53, + 0x3f, 0x70, 0x6d, 0xd4, 0x11, 0x83, 0x8d, 0xb2, 0xec, 0x1d, 0xbd, 0xe5, 0x84, 0x63, 0xf1, 0xc8, 0x09, 0xcd, 0x27, + 0x94, 0x5b, 0x59, 0x31, 0x2f, 0x07, 0x2d, 0x23, 0xca, 0x2d, 0x4e, 0xc4, 0xfb, 0xa4, 0x23, 0x71, 0x4f, 0xe5, 0x23, + 0xef, 0xb0, 0xb1, 0xc3, 0xf8, 0xc1, 0x01, 0x2f, 0xf0, 0x8c, 0xe4, 0xd4, 0x2c, 0x46, 0xe8, 0x9e, 0x2e, 0x3b, 0x38, + 0xa0, 0x6e, 0x44, 0xe3, 0x09, 0x0f, 0x09, 0x21, 0xad, 0x0e, 0x3b, 0x38, 0x70, 0x38, 0xf1, 0xb9, 0x3b, 0xa1, 0xdc, + 0xa1, 0x08, 0xe1, 0xb2, 0xf5, 0xc1, 0x81, 0x23, 0x91, 0x90, 0x10, 0x89, 0xb8, 0x0a, 0x8e, 0x91, 0xab, 0xb0, 0x7f, + 0x71, 0x17, 0x8f, 0x1c, 0x13, 0x7e, 0x84, 0xd9, 0xc1, 0x81, 0xcf, 0xdd, 0x0c, 0x7a, 0xc4, 0x1c, 0xa1, 0x3c, 0xa5, + 0x7c, 0x9e, 0xc6, 0x16, 0xcf, 0x79, 0x72, 0xc1, 0x53, 0x16, 0x4f, 0x1c, 0xb4, 0xd4, 0x65, 0x46, 0xc3, 0x3c, 0x97, + 0xe0, 0xbe, 0xe2, 0x24, 0x26, 0x3d, 0x18, 0xf1, 0x96, 0x3b, 0xb0, 0x8a, 0xc9, 0xd8, 0x8a, 0x09, 0xb1, 0x33, 0xd1, + 0xd6, 0xee, 0xc7, 0x5e, 0x5c, 0xb3, 0x6d, 0x2c, 0xa1, 0xc4, 0x19, 0x47, 0xf8, 0x35, 0x71, 0x62, 0xec, 0xba, 0x2e, + 0x47, 0xa4, 0xb7, 0xd4, 0x58, 0x89, 0x8d, 0x79, 0xf6, 0xe3, 0x41, 0x73, 0xe8, 0x71, 0x37, 0xa5, 0xc1, 0x7c, 0x44, + 0x1d, 0x87, 0xe1, 0x0c, 0xa7, 0x88, 0xf4, 0x58, 0xcd, 0x49, 0x48, 0x0f, 0x96, 0x3b, 0xa9, 0xae, 0x35, 0x21, 0x7b, + 0x4d, 0xa4, 0x60, 0x4c, 0x34, 0x80, 0x80, 0x61, 0x05, 0x4f, 0x42, 0x88, 0x1d, 0xcf, 0xa7, 0xd7, 0x34, 0xb5, 0x8b, + 0x6a, 0x9d, 0x0a, 0x59, 0xcc, 0x33, 0x6a, 0x8d, 0xb2, 0xcc, 0x1a, 0xcf, 0xe3, 0x11, 0x67, 0x49, 0x6c, 0xd9, 0xb5, + 0xa4, 0x66, 0x4b, 0x72, 0x28, 0xa8, 0xc1, 0x46, 0x39, 0x72, 0x32, 0x54, 0x8b, 0x07, 0x69, 0xad, 0x35, 0xc4, 0x00, + 0x25, 0xea, 0xa8, 0xfe, 0x14, 0x02, 0x28, 0x8e, 0x61, 0x8e, 0x39, 0x7e, 0xcb, 0x61, 0x96, 0x62, 0x8a, 0x8c, 0xf7, + 0x63, 0x77, 0x73, 0xa3, 0x10, 0xee, 0x4e, 0xfd, 0x99, 0x43, 0x49, 0x8f, 0x0a, 0xe2, 0xf2, 0xe3, 0x11, 0xc0, 0x5a, + 0x59, 0xb7, 0x3e, 0xf5, 0xa8, 0x5b, 0x92, 0x14, 0xf2, 0xb8, 0x3b, 0x4e, 0xd2, 0x67, 0xfe, 0x28, 0x84, 0x76, 0x05, + 0xc1, 0x04, 0x7a, 0xbf, 0x8d, 0x52, 0xea, 0x73, 0xfa, 0x2c, 0xa2, 0xf0, 0xe4, 0xd8, 0xa2, 0xa5, 0x8d, 0x70, 0x46, + 0x5e, 0xb8, 0x11, 0xe3, 0xaf, 0x92, 0x78, 0x44, 0x3b, 0x99, 0x41, 0x5d, 0x0c, 0xd6, 0xfd, 0x8c, 0xf3, 0x94, 0x5d, + 0xcf, 0x39, 0x75, 0xec, 0x18, 0x6a, 0xd8, 0x38, 0x43, 0x98, 0xb9, 0x9c, 0xde, 0xf2, 0xf3, 0x24, 0xe6, 0x34, 0xe6, + 0x84, 0x6a, 0xa4, 0xe2, 0xd8, 0xf5, 0x67, 0x33, 0x1a, 0x07, 0xe7, 0x21, 0x8b, 0x02, 0x87, 0xa1, 0x1c, 0xe5, 0x38, + 0xe4, 0x04, 0xe6, 0x48, 0x7a, 0xb1, 0x07, 0xff, 0xec, 0x9e, 0x8d, 0xc3, 0x49, 0x4f, 0x6c, 0x0a, 0x4a, 0x6c, 0xbb, + 0x33, 0x4e, 0x52, 0x47, 0xcd, 0xc0, 0x4a, 0xc6, 0x16, 0x87, 0x31, 0xde, 0xce, 0x23, 0x9a, 0x21, 0x5a, 0x23, 0xac, + 0x58, 0x46, 0x85, 0xe0, 0x57, 0x40, 0xf1, 0x39, 0x72, 0x62, 0xe4, 0xc5, 0x9d, 0x85, 0x9f, 0x5a, 0x3f, 0xa8, 0x1d, + 0xf5, 0x54, 0x73, 0xb3, 0x11, 0x27, 0x4f, 0x5d, 0x9e, 0xce, 0x33, 0x4e, 0x83, 0x77, 0x77, 0x33, 0x9a, 0xe1, 0xe7, + 0x9c, 0x8c, 0x78, 0x7f, 0xc4, 0x5d, 0x3a, 0x9d, 0xf1, 0xbb, 0x0b, 0xc1, 0x18, 0x3d, 0xdb, 0xc6, 0x01, 0xd4, 0x4c, + 0xa9, 0x3f, 0x02, 0x66, 0xa6, 0xb0, 0xf5, 0x26, 0x89, 0xee, 0xc6, 0x2c, 0x8a, 0x2e, 0xe6, 0xb3, 0x59, 0x92, 0x72, + 0xfc, 0x77, 0xb2, 0xe4, 0x49, 0x89, 0x1a, 0x58, 0xcb, 0x65, 0x76, 0xc3, 0xf8, 0x28, 0x74, 0x38, 0x5a, 0x8e, 0xfc, + 0x8c, 0x5a, 0x4f, 0x92, 0x24, 0xa2, 0x3e, 0x4c, 0x3a, 0xee, 0x3f, 0xe7, 0x5e, 0x3c, 0x8f, 0xa2, 0xce, 0x75, 0x4a, + 0xfd, 0x8f, 0x1d, 0xf1, 0xfa, 0xf5, 0xf5, 0x07, 0x3a, 0xe2, 0x9e, 0xf8, 0x7d, 0x96, 0xa6, 0xfe, 0x1d, 0x54, 0x24, + 0x04, 0xaa, 0xf5, 0x63, 0xef, 0xdb, 0x8b, 0xd7, 0xaf, 0x5c, 0xb9, 0x49, 0xd8, 0xf8, 0xce, 0x89, 0x8b, 0x8d, 0x17, + 0xe7, 0x78, 0x9c, 0x26, 0xd3, 0xb5, 0xa1, 0x25, 0xd6, 0xe2, 0xce, 0x0e, 0x10, 0x28, 0x89, 0xf7, 0x64, 0xd7, 0x26, + 0x04, 0xaf, 0x04, 0xcd, 0xc3, 0x4b, 0xa2, 0xc7, 0x9d, 0x47, 0x91, 0x27, 0x8b, 0x9d, 0x18, 0xdd, 0x0f, 0x2d, 0x4f, + 0xef, 0x96, 0x94, 0x08, 0x38, 0x67, 0x20, 0x61, 0x00, 0xc6, 0x91, 0xcf, 0x47, 0xe1, 0x92, 0x8a, 0xce, 0x72, 0x0d, + 0x31, 0xcd, 0x73, 0x7c, 0x56, 0xd0, 0x3b, 0x07, 0x40, 0x04, 0xa3, 0x22, 0x7c, 0xb5, 0x82, 0x09, 0x23, 0xfc, 0x13, + 0x59, 0xfa, 0x7a, 0x3e, 0xde, 0x5e, 0x13, 0xc3, 0xbe, 0xf4, 0x24, 0x77, 0xc1, 0xa3, 0x24, 0x5e, 0xd0, 0x94, 0xd3, + 0xd4, 0xfb, 0x3b, 0x4e, 0xe9, 0x38, 0x02, 0x28, 0xf6, 0x5a, 0x38, 0xf4, 0xb3, 0xf3, 0xd0, 0x8f, 0x27, 0x34, 0xf0, + 0xce, 0x78, 0x8e, 0x39, 0x27, 0xf6, 0x98, 0xc5, 0x7e, 0xc4, 0x7e, 0xa5, 0x81, 0xad, 0xc4, 0xc1, 0x33, 0x8b, 0xde, + 0x72, 0x1a, 0x07, 0x99, 0xf5, 0xfc, 0xdd, 0xcb, 0x17, 0x6a, 0x21, 0x2b, 0x12, 0x02, 0x2d, 0xb3, 0xf9, 0x8c, 0xa6, + 0x0e, 0xc2, 0x4a, 0x42, 0x3c, 0x63, 0x82, 0x3b, 0xbe, 0xf4, 0x67, 0xb2, 0x84, 0x65, 0xef, 0x67, 0x81, 0xcf, 0xe9, + 0x1b, 0x1a, 0x07, 0x2c, 0x9e, 0x90, 0xbd, 0x96, 0x2c, 0x0f, 0x7d, 0xf5, 0x22, 0x28, 0x8a, 0x2e, 0xf7, 0x9f, 0x45, + 0x62, 0xe2, 0xc5, 0xe3, 0xdc, 0x41, 0x79, 0xc6, 0x7d, 0xce, 0x46, 0x96, 0x1f, 0x04, 0xdf, 0xc4, 0x8c, 0x33, 0x01, + 0x60, 0x0a, 0xeb, 0x03, 0x34, 0x4a, 0xa5, 0xac, 0xd0, 0x80, 0x3b, 0x08, 0x3b, 0x8e, 0x92, 0x00, 0x21, 0x52, 0x0b, + 0x76, 0x70, 0x50, 0xf2, 0xfb, 0x3e, 0xf5, 0xe4, 0x4b, 0x32, 0x18, 0x22, 0x77, 0x36, 0xcf, 0x60, 0xa5, 0xf5, 0x10, + 0x20, 0x5e, 0x92, 0xeb, 0x8c, 0xa6, 0x0b, 0x1a, 0x14, 0xd4, 0x91, 0x39, 0x68, 0xb9, 0x36, 0x86, 0xda, 0x17, 0x9c, + 0x0c, 0x86, 0x1d, 0x93, 0x71, 0x53, 0x45, 0xe8, 0x69, 0x32, 0xa3, 0x29, 0x67, 0x34, 0x2b, 0x78, 0x89, 0x03, 0x62, + 0xb4, 0xe0, 0x27, 0x19, 0xd1, 0xf3, 0x9b, 0x39, 0x0c, 0x53, 0x54, 0xe1, 0x18, 0x5a, 0xd2, 0x3e, 0x5b, 0x08, 0x91, + 0x91, 0x61, 0x86, 0x30, 0x97, 0x90, 0x66, 0x08, 0xe5, 0x08, 0x73, 0x0d, 0xae, 0xe4, 0x45, 0x6a, 0xb4, 0x3b, 0x90, + 0xd5, 0xe4, 0x27, 0x21, 0xab, 0x81, 0xa3, 0xf9, 0x9c, 0x1e, 0x1c, 0x38, 0xd4, 0x2d, 0xa8, 0x82, 0xec, 0xb5, 0xd4, + 0x1a, 0x19, 0xc8, 0xda, 0x01, 0x36, 0x0c, 0xcc, 0x31, 0x45, 0x78, 0x8f, 0xba, 0x71, 0x72, 0x36, 0x1a, 0xd1, 0x2c, + 0x4b, 0xd2, 0x83, 0x83, 0x3d, 0x51, 0xbf, 0x50, 0x27, 0x60, 0x0d, 0x5f, 0xdf, 0xc4, 0x25, 0x04, 0xa8, 0x14, 0xb1, + 0x4a, 0x30, 0x70, 0x10, 0x54, 0x42, 0xe3, 0xb0, 0xfb, 0x5a, 0xf3, 0xf0, 0xec, 0xcb, 0x4b, 0xbb, 0xc6, 0xb1, 0x42, + 0xc3, 0x84, 0xea, 0xa1, 0xef, 0x9e, 0x52, 0xa9, 0x5b, 0x09, 0xcd, 0x63, 0x03, 0x33, 0x72, 0x03, 0xb9, 0x01, 0x1d, + 0xb3, 0xd8, 0x98, 0x76, 0x05, 0x24, 0xcc, 0x71, 0x86, 0x72, 0x63, 0x41, 0xb7, 0x76, 0x2d, 0x94, 0x1a, 0xb9, 0x72, + 0xcb, 0x89, 0x50, 0x24, 0x8c, 0x65, 0x1c, 0xd0, 0x61, 0x8e, 0x05, 0xea, 0xf5, 0x6c, 0x52, 0x01, 0xe8, 0x80, 0x0f, + 0x3b, 0xea, 0x3d, 0xc9, 0x24, 0xe6, 0x52, 0xfa, 0xcb, 0x9c, 0x66, 0x5c, 0xd2, 0xb1, 0xc3, 0x71, 0x8a, 0x19, 0xca, + 0x61, 0xbf, 0x8d, 0xd9, 0x64, 0x9e, 0x82, 0xbe, 0x03, 0x7b, 0x91, 0xc6, 0xf3, 0x29, 0xd5, 0x4f, 0xdb, 0x60, 0x7b, + 0x3d, 0x03, 0x89, 0x98, 0x01, 0x4d, 0xdf, 0x4f, 0x4e, 0x00, 0x2b, 0x47, 0xab, 0xd5, 0x4f, 0xba, 0x93, 0x72, 0x29, + 0x0b, 0x1d, 0x6d, 0x7d, 0x4d, 0x38, 0x52, 0x12, 0x79, 0xaf, 0x25, 0xc1, 0xe7, 0x7c, 0x48, 0xf6, 0x9a, 0x05, 0x0d, + 0x2b, 0xac, 0x4a, 0x70, 0x24, 0x12, 0x5f, 0xcb, 0xae, 0x90, 0x10, 0xf0, 0x15, 0x72, 0x71, 0xc3, 0x0d, 0x4a, 0x0d, + 0xc9, 0x00, 0x54, 0x0d, 0x37, 0x1c, 0xee, 0x22, 0x27, 0xcd, 0x0f, 0x1c, 0xbe, 0xf9, 0xae, 0x64, 0x1b, 0x8b, 0x2a, + 0xdb, 0x58, 0x9b, 0x86, 0x3d, 0x2b, 0x9a, 0xd8, 0x05, 0x95, 0xa9, 0x8d, 0x5e, 0xbe, 0xc2, 0x4c, 0x00, 0x53, 0x4e, + 0xc9, 0xe8, 0xe2, 0x95, 0x3f, 0xa5, 0x99, 0x43, 0x11, 0xde, 0x55, 0x41, 0x92, 0x27, 0x54, 0x19, 0x1a, 0x92, 0x33, + 0x03, 0xc9, 0xc9, 0x90, 0x54, 0xcc, 0xaa, 0x1b, 0x2e, 0xc3, 0x74, 0x90, 0x0d, 0x4b, 0x7d, 0xce, 0x98, 0xbc, 0x10, + 0xc9, 0x8a, 0xbe, 0x35, 0xfe, 0x64, 0x99, 0x44, 0x9a, 0xd0, 0x1b, 0x32, 0x84, 0xf7, 0x9a, 0xeb, 0x2b, 0xa9, 0x6b, + 0x95, 0x73, 0x1c, 0x0c, 0x61, 0x1d, 0x84, 0xc4, 0x70, 0x59, 0x26, 0xfe, 0xaf, 0xec, 0x34, 0x40, 0xdb, 0x05, 0x10, + 0x86, 0x3b, 0x8e, 0x7c, 0xee, 0xb4, 0x1a, 0x4d, 0x50, 0x46, 0x17, 0x14, 0x04, 0x0a, 0x42, 0x9b, 0x53, 0xa1, 0xee, + 0x3c, 0xce, 0x42, 0x36, 0xe6, 0x4e, 0xc8, 0x05, 0x4b, 0xa1, 0x51, 0x46, 0x2d, 0x5e, 0x51, 0x89, 0x05, 0xbb, 0x09, + 0x81, 0xd8, 0x0a, 0xfd, 0x8b, 0x6a, 0x48, 0x05, 0xdb, 0x02, 0xee, 0x50, 0xaa, 0xd3, 0x25, 0x97, 0xd1, 0xb5, 0x19, + 0xa8, 0x8c, 0xad, 0xbe, 0xec, 0xd1, 0x53, 0xcc, 0x80, 0x19, 0x5a, 0x2b, 0xf3, 0x4c, 0x0e, 0xa1, 0x0a, 0xb9, 0xcb, + 0x93, 0x17, 0xc9, 0x0d, 0x4d, 0xcf, 0x7d, 0x00, 0xde, 0x93, 0xcd, 0x73, 0x29, 0x08, 0x04, 0xbf, 0xe7, 0x1d, 0x4d, + 0x2f, 0x97, 0x62, 0xe2, 0x6f, 0xd2, 0x64, 0xca, 0x32, 0x0a, 0xca, 0x9a, 0xc4, 0x7f, 0x0c, 0xfb, 0x4c, 0x6c, 0x48, + 0x10, 0x36, 0xb4, 0xa0, 0xaf, 0xb3, 0x17, 0x55, 0xfa, 0xba, 0xdc, 0x7f, 0x36, 0xd1, 0x0c, 0xb0, 0xba, 0x8d, 0x11, + 0x76, 0x94, 0x49, 0x61, 0xc8, 0x39, 0x37, 0x44, 0x4a, 0xc2, 0xaf, 0x56, 0xdc, 0xb0, 0xdc, 0x2a, 0xea, 0x22, 0x95, + 0xdb, 0x06, 0xe5, 0x7e, 0x10, 0x80, 0x62, 0x97, 0x26, 0x51, 0x64, 0x88, 0x2a, 0xcc, 0x3a, 0x85, 0x70, 0xba, 0xdc, + 0x7f, 0x76, 0x71, 0x9f, 0x7c, 0x82, 0xf7, 0xa6, 0x88, 0xd2, 0x80, 0xc6, 0x01, 0x4d, 0xc1, 0x92, 0x34, 0x56, 0x4b, + 0x49, 0xd9, 0xf3, 0x24, 0x8e, 0xe9, 0x88, 0xd3, 0x00, 0x0c, 0x15, 0x46, 0xb8, 0x1b, 0x26, 0x19, 0x2f, 0x0a, 0x4b, + 0xe8, 0x99, 0x01, 0x3d, 0x73, 0x47, 0x7e, 0x14, 0x39, 0xd2, 0x28, 0x99, 0x26, 0x0b, 0xba, 0x05, 0xea, 0x4e, 0x05, + 0xe4, 0xa2, 0x1b, 0x6a, 0x74, 0x43, 0xdd, 0x6c, 0x16, 0xb1, 0x11, 0x2d, 0x44, 0xd7, 0x85, 0xcb, 0xe2, 0x80, 0xde, + 0x02, 0x1f, 0x41, 0xbd, 0x5e, 0xaf, 0x89, 0x5b, 0x28, 0x97, 0x08, 0x5f, 0x6e, 0x20, 0xf6, 0x1e, 0xa1, 0x09, 0x44, + 0x46, 0x7a, 0xcb, 0x6d, 0xfc, 0x80, 0x22, 0x43, 0x52, 0x32, 0x6d, 0x5c, 0x49, 0xee, 0x8c, 0x70, 0x40, 0x23, 0xca, + 0xa9, 0xe6, 0xe6, 0xa0, 0x42, 0xcb, 0xad, 0xfb, 0xb6, 0xc0, 0x5f, 0x41, 0x4e, 0x7a, 0x97, 0xe9, 0x35, 0xcf, 0x0a, + 0x63, 0xbd, 0x5c, 0x9e, 0x12, 0xdb, 0x7d, 0x2e, 0x97, 0xc7, 0xe7, 0xdc, 0x1f, 0x85, 0xd2, 0x4a, 0x77, 0x36, 0xa6, + 0x54, 0xf6, 0xa1, 0x38, 0x7b, 0xb1, 0x89, 0xde, 0x6a, 0x30, 0xb7, 0xa1, 0xe0, 0x42, 0x31, 0x05, 0x0a, 0x86, 0x9f, + 0x5c, 0xb6, 0x73, 0x3f, 0x8a, 0xae, 0xfd, 0xd1, 0xc7, 0x2a, 0xf5, 0x97, 0x64, 0x40, 0xd6, 0xb9, 0xb1, 0xf1, 0xca, + 0x60, 0x59, 0xe6, 0xbc, 0x35, 0x97, 0xae, 0x6c, 0x14, 0x67, 0xaf, 0x59, 0x92, 0x7d, 0x75, 0xa1, 0x77, 0x52, 0xbb, + 0x80, 0x88, 0xa9, 0x99, 0x39, 0xc0, 0x05, 0x3e, 0x49, 0x71, 0x9a, 0x1f, 0x28, 0xba, 0x03, 0x73, 0x23, 0x5f, 0x03, + 0x84, 0xa3, 0x65, 0x1e, 0xb0, 0x6c, 0x37, 0x06, 0xfe, 0x14, 0x28, 0x9f, 0x1a, 0x23, 0x3c, 0x14, 0xd0, 0x82, 0xc7, + 0x29, 0xad, 0xb9, 0x80, 0x4c, 0xe9, 0x13, 0x9a, 0xd1, 0xfc, 0x0d, 0x74, 0x17, 0x41, 0xef, 0xaf, 0xe5, 0x2b, 0xd0, + 0xca, 0x00, 0x8a, 0xac, 0x63, 0xaa, 0x13, 0x15, 0x0a, 0x50, 0x3c, 0x95, 0x09, 0x91, 0x9b, 0x56, 0xec, 0x47, 0xa5, + 0xb1, 0x4b, 0x13, 0x5c, 0xb1, 0xdc, 0x84, 0x38, 0x8e, 0x93, 0x81, 0x09, 0xa7, 0x55, 0xfb, 0x72, 0x12, 0xd9, 0xc6, + 0x24, 0x32, 0xd7, 0xb0, 0xb3, 0x50, 0x49, 0xcb, 0x46, 0x73, 0xef, 0xef, 0xc8, 0xac, 0x04, 0xea, 0xaa, 0x0b, 0xfc, + 0x19, 0x15, 0xec, 0x36, 0x22, 0x1c, 0x27, 0xca, 0xc6, 0x51, 0x94, 0x06, 0x0c, 0xa3, 0x6c, 0x92, 0x22, 0xb9, 0x35, + 0x2a, 0xf6, 0x6e, 0x8a, 0x13, 0xb4, 0xa6, 0xdb, 0xe7, 0xb9, 0xc2, 0x11, 0x45, 0x6a, 0x6d, 0x2a, 0x4a, 0xb1, 0x81, + 0x15, 0x9c, 0x12, 0xa5, 0x08, 0x4b, 0xbd, 0x67, 0x1d, 0x37, 0x45, 0xbf, 0x7b, 0x84, 0xa4, 0x25, 0x6a, 0x2a, 0x1a, + 0xa5, 0x56, 0xad, 0x52, 0x84, 0x43, 0xad, 0x93, 0x26, 0xe5, 0xbc, 0x09, 0xb1, 0xb5, 0x43, 0xc2, 0xee, 0x2f, 0x2b, + 0x56, 0xa1, 0x67, 0x54, 0xcb, 0x3d, 0x60, 0xa9, 0xc9, 0x36, 0x74, 0x6f, 0xa3, 0x99, 0x4a, 0x3f, 0x06, 0xc2, 0x13, + 0x13, 0xe1, 0x06, 0x66, 0x53, 0xc9, 0xb9, 0xd2, 0x21, 0x09, 0xab, 0x6d, 0x1d, 0x8a, 0x13, 0xb9, 0x0e, 0x1b, 0x48, + 0x5c, 0x57, 0x3d, 0x05, 0x09, 0x82, 0x0d, 0x9b, 0x81, 0x72, 0x67, 0xca, 0x07, 0x07, 0x60, 0x67, 0xab, 0xd5, 0x06, + 0xd1, 0x6d, 0xd5, 0x40, 0x91, 0x5b, 0xda, 0x85, 0xab, 0xd5, 0x19, 0x47, 0x8e, 0xd2, 0x7d, 0x31, 0x45, 0x7d, 0xcd, + 0x71, 0xcf, 0x5e, 0x40, 0x2d, 0xa1, 0x8a, 0x96, 0x25, 0x85, 0xd1, 0x50, 0xa5, 0xd9, 0xea, 0x3a, 0x71, 0x83, 0x6d, + 0x9f, 0x6f, 0x70, 0x2f, 0x51, 0xa8, 0xc4, 0x74, 0x39, 0xe5, 0x73, 0xd5, 0x35, 0x43, 0x08, 0x79, 0x99, 0xb0, 0x63, + 0xf6, 0xb6, 0x99, 0x96, 0x07, 0x07, 0x99, 0xd1, 0xd1, 0x65, 0xc1, 0x26, 0x3e, 0x38, 0x20, 0x92, 0xb3, 0xbb, 0x58, + 0xe8, 0x2e, 0x1f, 0xb4, 0x10, 0xda, 0x30, 0x4c, 0x9b, 0x1d, 0x30, 0xc8, 0xfd, 0x1b, 0x9f, 0x71, 0xab, 0xe8, 0x45, + 0x1a, 0xe4, 0x0e, 0x45, 0x4b, 0xa5, 0x6a, 0xb8, 0x29, 0x05, 0xe5, 0x11, 0x78, 0x82, 0x56, 0xa1, 0x25, 0xdd, 0x8f, + 0x42, 0x0a, 0xbe, 0x60, 0xad, 0x45, 0x14, 0x96, 0xe1, 0x9e, 0x92, 0x22, 0xaa, 0xe3, 0xed, 0xb0, 0xe7, 0xeb, 0xcd, + 0x2b, 0x96, 0xc0, 0x8c, 0xa6, 0xe3, 0x24, 0x9d, 0xea, 0x77, 0xf9, 0xda, 0xb3, 0xe2, 0x8c, 0x6c, 0xec, 0x6c, 0xed, + 0x5b, 0xe9, 0xff, 0x9d, 0x35, 0xb3, 0xbb, 0x34, 0xd8, 0x2b, 0xa2, 0xb4, 0x90, 0xbe, 0xd2, 0x25, 0xa8, 0x29, 0x33, + 0x33, 0x0d, 0x7c, 0xe5, 0x4f, 0xed, 0x48, 0x9f, 0xc9, 0x5e, 0xab, 0x53, 0x58, 0x7d, 0x9a, 0x1a, 0x3a, 0xd2, 0xb7, + 0xa1, 0x44, 0x6a, 0x32, 0x8f, 0x02, 0x05, 0x2c, 0x43, 0x98, 0x2a, 0x3a, 0xba, 0x61, 0x51, 0x54, 0x96, 0xfe, 0x16, + 0xbe, 0x9e, 0x29, 0xbe, 0x9e, 0x6a, 0xbe, 0x0e, 0x9c, 0x02, 0xf8, 0xba, 0xec, 0xae, 0x6c, 0x9e, 0x6e, 0xec, 0xce, + 0x54, 0x72, 0xf4, 0x4c, 0x58, 0xd2, 0x30, 0xde, 0x5c, 0x43, 0x80, 0x0a, 0xcd, 0xeb, 0xa3, 0xa3, 0xfc, 0x30, 0x60, + 0x02, 0x4a, 0x2f, 0x26, 0x35, 0x9d, 0x14, 0x1f, 0x1d, 0x84, 0xb3, 0x9c, 0x16, 0x94, 0x7d, 0xf6, 0x0c, 0xfc, 0x74, + 0xc6, 0x74, 0x40, 0x88, 0x89, 0xe2, 0xdf, 0xa4, 0x44, 0xe9, 0xd9, 0x31, 0x35, 0xbb, 0x4c, 0xcf, 0x0e, 0x38, 0x7d, + 0x39, 0xbb, 0xe0, 0x7e, 0x5e, 0x2f, 0xa6, 0xc7, 0x8a, 0xe9, 0x95, 0xeb, 0xbd, 0x5a, 0x39, 0x6b, 0x25, 0xe0, 0xc2, + 0x57, 0x26, 0x4a, 0x5a, 0xf4, 0x0e, 0x3c, 0xc0, 0xc4, 0x0c, 0x14, 0xe4, 0x72, 0xd2, 0x85, 0x88, 0x7b, 0xf1, 0x29, + 0x17, 0x8f, 0xf0, 0xd4, 0xcb, 0xf6, 0xe7, 0xc9, 0x74, 0x06, 0xda, 0xd8, 0x1a, 0x49, 0x4f, 0xa8, 0x1a, 0xb0, 0x7c, + 0x9f, 0x6f, 0x29, 0xab, 0xb4, 0x11, 0xfb, 0xb1, 0x42, 0x4d, 0x85, 0xc5, 0xbc, 0xd7, 0xcc, 0xe7, 0x45, 0x51, 0xc1, + 0x38, 0xb6, 0xb9, 0x55, 0xce, 0xd7, 0x9d, 0x32, 0xfa, 0xc5, 0x6b, 0x87, 0x49, 0x3e, 0xcc, 0x80, 0xd7, 0x19, 0xec, + 0x47, 0x93, 0xbb, 0xb9, 0xfe, 0x79, 0x89, 0x9c, 0x65, 0xbe, 0x86, 0xbe, 0x65, 0x9e, 0x3f, 0x53, 0x56, 0x36, 0x7e, + 0xb6, 0xdb, 0x1c, 0x2e, 0xdf, 0x29, 0x6b, 0x71, 0x30, 0xc4, 0xcf, 0x36, 0x75, 0x47, 0xb2, 0x9c, 0x26, 0x01, 0xf5, + 0xec, 0x64, 0x46, 0x63, 0x3b, 0x07, 0xcf, 0xaa, 0x5a, 0xfc, 0x80, 0x3b, 0xcb, 0xb7, 0x55, 0x17, 0xab, 0xf7, 0x2c, + 0x07, 0x07, 0xd8, 0x0f, 0x9b, 0xce, 0xd7, 0xef, 0x69, 0x9a, 0x09, 0x4d, 0xb4, 0x50, 0x6a, 0x7f, 0x28, 0xe5, 0xd2, + 0x0f, 0xde, 0xce, 0xfa, 0xa5, 0x0d, 0x62, 0xb7, 0xdc, 0x13, 0xf7, 0xd0, 0x46, 0xc2, 0x35, 0xfc, 0xad, 0xda, 0xf1, + 0x1f, 0xb4, 0x6b, 0xf8, 0x82, 0x7c, 0xa8, 0x7a, 0x86, 0xe7, 0x9c, 0x5c, 0xf4, 0x2f, 0xb4, 0xc9, 0x9c, 0x44, 0x6c, + 0x74, 0xe7, 0xd8, 0x11, 0xe3, 0x75, 0x08, 0xbf, 0xd9, 0x78, 0x29, 0x5f, 0x80, 0x57, 0x51, 0xb8, 0xb4, 0x73, 0x6d, + 0xec, 0x61, 0xca, 0x89, 0xbd, 0x1f, 0x31, 0xbe, 0x6f, 0xe3, 0x29, 0xb9, 0x82, 0x1f, 0xfb, 0x4b, 0xe7, 0xa5, 0xcf, + 0x43, 0x37, 0xf5, 0xe3, 0x20, 0x99, 0x3a, 0xa8, 0x66, 0xdb, 0xc8, 0xcd, 0x84, 0xc1, 0xf1, 0x18, 0xe5, 0xfb, 0x57, + 0xf8, 0x19, 0x27, 0x76, 0xdf, 0xae, 0x4d, 0xf1, 0x13, 0x4e, 0xae, 0xba, 0xfb, 0xcb, 0x67, 0x3c, 0xef, 0x5d, 0xe1, + 0xdb, 0xc2, 0x6b, 0x8f, 0xdf, 0x13, 0x07, 0x91, 0xde, 0xad, 0x82, 0xe6, 0x3c, 0x99, 0x4a, 0xef, 0xbd, 0x8d, 0xf0, + 0x3b, 0x11, 0x5b, 0x29, 0xd9, 0x8d, 0x0a, 0xaf, 0xec, 0x11, 0x3b, 0x11, 0x3e, 0x02, 0xfb, 0xe0, 0xc0, 0x28, 0x2b, + 0x74, 0x05, 0x7c, 0xc1, 0x49, 0xc5, 0x22, 0xc7, 0x2f, 0x45, 0x94, 0xe6, 0x82, 0x3b, 0x31, 0xd2, 0xdd, 0x38, 0xda, + 0x17, 0xad, 0xf6, 0x66, 0x3c, 0x90, 0x2e, 0x06, 0x97, 0x71, 0x9a, 0xfa, 0x3c, 0x49, 0x87, 0xc8, 0xd4, 0x3f, 0xf0, + 0xdf, 0xc8, 0xd5, 0xc0, 0xfa, 0x4f, 0x9f, 0xfd, 0x3c, 0xfe, 0x39, 0x1d, 0x5e, 0xe1, 0x37, 0xa4, 0xd1, 0x75, 0xfa, + 0x9e, 0xb3, 0x57, 0xaf, 0xaf, 0x7e, 0x6e, 0x0c, 0xfe, 0xe1, 0xd7, 0x7f, 0x3d, 0xab, 0xff, 0x34, 0x44, 0x2b, 0xe7, + 0xe7, 0x46, 0x7f, 0xa0, 0x9e, 0x06, 0xff, 0xe8, 0xfd, 0x9c, 0x0d, 0xff, 0x2a, 0x0b, 0xf7, 0x11, 0x6a, 0x4c, 0xf0, + 0x8c, 0x93, 0x46, 0xbd, 0xde, 0x6b, 0x4c, 0xf0, 0x84, 0x93, 0x06, 0xfc, 0x7f, 0x4d, 0xde, 0xd2, 0xc9, 0xb3, 0xdb, + 0x99, 0x73, 0xd5, 0x5b, 0xed, 0x2f, 0xff, 0x96, 0x43, 0xaf, 0x83, 0x7f, 0xfc, 0xfc, 0x73, 0x66, 0x7f, 0xd1, 0x23, + 0x8d, 0x61, 0x0d, 0x39, 0x50, 0xfa, 0x57, 0x22, 0xfe, 0x75, 0xfa, 0xde, 0xe0, 0x1f, 0x0a, 0x0a, 0xfb, 0x8b, 0x9f, + 0xaf, 0xba, 0x3d, 0x32, 0x5c, 0x39, 0xf6, 0xea, 0x0b, 0xb4, 0x42, 0x68, 0xb5, 0x8f, 0xae, 0xb0, 0x3d, 0xb1, 0x11, + 0x5e, 0x70, 0xd2, 0xf8, 0xa2, 0x31, 0xc1, 0x63, 0x4e, 0x1a, 0x76, 0x63, 0x82, 0xcf, 0x39, 0x69, 0xfc, 0xc3, 0xe9, + 0x7b, 0xd2, 0xc9, 0xb6, 0x12, 0xfe, 0x8d, 0x15, 0x04, 0x38, 0xfc, 0x94, 0xfa, 0x2b, 0xce, 0x78, 0x44, 0xd1, 0x7e, + 0x83, 0xe1, 0x8f, 0x02, 0x4d, 0x0e, 0x07, 0x2f, 0x0c, 0x18, 0x77, 0xce, 0xf2, 0x12, 0x16, 0x1b, 0x68, 0x66, 0xdf, + 0x83, 0xc8, 0x0e, 0x38, 0x02, 0x32, 0x8f, 0xe3, 0x85, 0x1f, 0xcd, 0x69, 0xe6, 0xd1, 0x1c, 0xe1, 0x11, 0xf9, 0xc8, + 0x9d, 0x16, 0xc2, 0x2f, 0x38, 0xfc, 0x68, 0x23, 0x7c, 0xae, 0x82, 0x98, 0xb0, 0x93, 0x25, 0x51, 0xc5, 0x89, 0x54, + 0x59, 0x6c, 0x84, 0x67, 0x5b, 0x5e, 0xf2, 0x10, 0xdc, 0x0b, 0x08, 0xef, 0x57, 0x42, 0x9e, 0xf8, 0x86, 0x68, 0x92, + 0x78, 0x97, 0x52, 0xfa, 0x83, 0x1f, 0x7d, 0xa4, 0xa9, 0x73, 0x8b, 0x5b, 0xed, 0xc7, 0x58, 0x78, 0xa1, 0xf7, 0x5a, + 0xa8, 0x53, 0xc4, 0xab, 0x5e, 0x73, 0x19, 0x27, 0x00, 0x29, 0x5b, 0x75, 0xc6, 0xc0, 0x8a, 0xef, 0xc5, 0x1b, 0x1e, + 0xab, 0xd4, 0xbf, 0xb1, 0x51, 0x35, 0x36, 0xca, 0xe2, 0x85, 0x1f, 0xb1, 0xc0, 0xe2, 0x74, 0x3a, 0x8b, 0x7c, 0x4e, + 0x2d, 0x35, 0x5f, 0xcb, 0x87, 0x8e, 0xec, 0x42, 0x67, 0x98, 0x1b, 0x16, 0xe7, 0x5c, 0x07, 0x9d, 0x60, 0xaf, 0x38, + 0x10, 0xa1, 0x52, 0x7a, 0xc7, 0xd3, 0x32, 0x00, 0xb6, 0x1e, 0xe3, 0xab, 0xb7, 0xc0, 0x13, 0x36, 0x14, 0xf2, 0x39, + 0xc3, 0x29, 0x01, 0x29, 0xda, 0xee, 0xdb, 0xdd, 0x6c, 0x31, 0xe9, 0xd9, 0x10, 0x9f, 0x49, 0xc8, 0x1b, 0xe1, 0x18, + 0x82, 0x0a, 0x21, 0x69, 0x76, 0xc2, 0x2e, 0xed, 0x84, 0xb5, 0x9a, 0x56, 0xa2, 0x23, 0x12, 0x0f, 0x42, 0xd9, 0xdc, + 0xc7, 0x01, 0x9e, 0x93, 0x7a, 0x0b, 0x4f, 0x48, 0x53, 0x34, 0xe9, 0x4c, 0xba, 0x91, 0x1a, 0xe6, 0xe0, 0xc0, 0x49, + 0xdc, 0xc8, 0xcf, 0xf8, 0x37, 0x60, 0xed, 0x93, 0x09, 0x0e, 0x48, 0xe2, 0xd2, 0x5b, 0x3a, 0x72, 0x22, 0x84, 0x03, + 0xc5, 0x69, 0x50, 0x07, 0x4d, 0x88, 0x51, 0x0d, 0xac, 0x08, 0xf2, 0xa6, 0x1f, 0x0c, 0x5a, 0x43, 0x42, 0x88, 0xbd, + 0x57, 0xaf, 0xdb, 0xfd, 0x84, 0xcc, 0xb8, 0x07, 0x25, 0x86, 0xae, 0x4c, 0x26, 0x50, 0xd4, 0x36, 0x8a, 0x9c, 0x73, + 0xee, 0x72, 0x9a, 0x71, 0x07, 0x8a, 0xc1, 0xfe, 0xcf, 0x34, 0x61, 0xdb, 0xdd, 0x86, 0x5d, 0x83, 0x52, 0x41, 0x9c, + 0x08, 0x27, 0xe4, 0x1a, 0x79, 0xc1, 0xe0, 0x70, 0x68, 0x0a, 0x00, 0x51, 0x08, 0x83, 0x5f, 0xf7, 0x83, 0x41, 0x53, + 0x0c, 0xde, 0xb3, 0xfb, 0x4e, 0x42, 0x32, 0xa9, 0xa1, 0xf5, 0x33, 0xef, 0x8d, 0x98, 0x2a, 0xf2, 0x14, 0x70, 0x7a, + 0x05, 0x48, 0xbd, 0xed, 0x39, 0x73, 0x73, 0x12, 0x75, 0x18, 0x4c, 0x61, 0x01, 0xfb, 0x04, 0xea, 0xe3, 0x84, 0xc0, + 0x88, 0x65, 0xb3, 0x6b, 0x4f, 0x3d, 0x7f, 0x61, 0x7f, 0xd1, 0x1f, 0x73, 0x6f, 0xc1, 0xe5, 0xf0, 0x63, 0xbe, 0x5a, + 0xc1, 0xff, 0x0b, 0xde, 0x4f, 0xc8, 0xb5, 0x28, 0x9a, 0xa9, 0xa2, 0x09, 0x14, 0xbd, 0xf1, 0x00, 0x54, 0x9c, 0x15, + 0x5a, 0x96, 0x5c, 0x93, 0x05, 0x11, 0xb0, 0x1f, 0x1c, 0xc4, 0x83, 0xb0, 0xd6, 0x1a, 0x82, 0x8b, 0x3f, 0xe5, 0xd9, + 0x0f, 0x8c, 0x87, 0x8e, 0xdd, 0xe8, 0xd9, 0xa8, 0x6f, 0x5b, 0xb0, 0xb4, 0x9d, 0xb4, 0x46, 0x24, 0x86, 0xa3, 0xda, + 0x13, 0xee, 0xcd, 0x7b, 0xa4, 0xd9, 0x77, 0x98, 0x64, 0xe1, 0x3e, 0xc2, 0x91, 0x62, 0x9c, 0x4d, 0x3c, 0x47, 0x35, + 0xca, 0x6b, 0xfa, 0x79, 0x8e, 0x6a, 0xd3, 0xda, 0x02, 0x79, 0x51, 0x6d, 0x5a, 0x73, 0xe6, 0x84, 0x90, 0x7a, 0xbb, + 0x68, 0xa6, 0xc5, 0x5f, 0x88, 0xbc, 0x85, 0xf6, 0x76, 0x0e, 0xc4, 0x76, 0x48, 0x6b, 0x4e, 0x3c, 0xa0, 0xc3, 0xd5, + 0xca, 0xee, 0xf6, 0x7b, 0x36, 0xaa, 0x39, 0x9a, 0xd0, 0x1a, 0x9a, 0xd2, 0x10, 0xc2, 0x6c, 0x98, 0xab, 0x68, 0xd2, + 0xab, 0x4a, 0xe4, 0x68, 0x59, 0x6e, 0x76, 0x83, 0x07, 0xd0, 0xbc, 0x30, 0x64, 0xa4, 0xc2, 0x3a, 0x83, 0x69, 0x6a, + 0x62, 0x4e, 0x49, 0x13, 0x27, 0x44, 0x3b, 0xaf, 0x43, 0xc2, 0x4b, 0x82, 0x8f, 0x48, 0x59, 0x1d, 0x0f, 0x7c, 0x1c, + 0x0c, 0xc9, 0x53, 0x69, 0x90, 0x74, 0xb4, 0x6b, 0x9c, 0x46, 0xe4, 0xd5, 0x5a, 0x04, 0xd7, 0x87, 0xf0, 0xca, 0x8d, + 0x3b, 0x9a, 0xa7, 0x29, 0x8d, 0xf9, 0xab, 0x24, 0x50, 0x7a, 0x1a, 0x8d, 0xc0, 0x54, 0x82, 0xd0, 0x2c, 0x06, 0x25, + 0xad, 0xad, 0x77, 0xc6, 0x7c, 0xe3, 0xf5, 0x84, 0xcc, 0xa5, 0xfe, 0x24, 0x02, 0xb6, 0x9d, 0x89, 0x32, 0x8c, 0x1d, + 0x84, 0xe7, 0x2a, 0x92, 0xeb, 0xb8, 0xae, 0x3b, 0x71, 0x47, 0xf0, 0x1a, 0x06, 0xc8, 0x50, 0x2e, 0xf6, 0x91, 0x93, + 0x91, 0x1b, 0x37, 0xa6, 0xb7, 0x62, 0x54, 0x07, 0x95, 0x92, 0x59, 0x6f, 0xaf, 0x6e, 0xd8, 0x11, 0xec, 0x26, 0x73, + 0xe3, 0x24, 0xa0, 0x80, 0x1e, 0x88, 0xdd, 0xab, 0xa2, 0xd0, 0xcf, 0xcc, 0x10, 0x55, 0x09, 0xdf, 0xc0, 0xf4, 0x5e, + 0x4f, 0xc0, 0xe5, 0x2b, 0x94, 0xad, 0xa2, 0xb2, 0xf4, 0x83, 0x23, 0xc4, 0xc6, 0xce, 0xc4, 0x85, 0xd0, 0x9e, 0x20, + 0x21, 0x0a, 0xb6, 0xdc, 0xc4, 0x24, 0xaa, 0x69, 0xd1, 0xe7, 0x82, 0x04, 0x83, 0xa4, 0x56, 0x13, 0x6e, 0xe8, 0xb9, + 0x24, 0x89, 0x09, 0xc2, 0x8b, 0x62, 0x6f, 0xe9, 0x7a, 0x5f, 0x91, 0xea, 0x48, 0xce, 0xa2, 0xea, 0xce, 0xad, 0x41, + 0x9a, 0x04, 0x78, 0x0a, 0xb9, 0x33, 0x45, 0xf8, 0x8c, 0x34, 0x9c, 0x81, 0xdb, 0xff, 0x72, 0x88, 0xfa, 0x8e, 0xfb, + 0x57, 0xd4, 0x90, 0x8c, 0x63, 0x81, 0x3a, 0x91, 0x1c, 0x62, 0x29, 0x42, 0x98, 0x2d, 0x2c, 0x3c, 0x89, 0x5e, 0x8a, + 0x63, 0x7f, 0x4a, 0xbd, 0x33, 0xd8, 0xe3, 0x9a, 0x6e, 0xbe, 0xc2, 0x40, 0x47, 0xde, 0x99, 0xe2, 0x24, 0xae, 0xdd, + 0xff, 0x86, 0x17, 0x4f, 0x7d, 0xbb, 0xff, 0x6b, 0xf9, 0xf4, 0xa5, 0xdd, 0xff, 0x9e, 0x7b, 0xbf, 0xe6, 0xca, 0xd9, + 0x5d, 0x19, 0xe2, 0x44, 0x0f, 0x91, 0xcb, 0x85, 0x31, 0x30, 0x37, 0x47, 0x9b, 0x7e, 0x8e, 0x09, 0xca, 0xd9, 0xb8, + 0x60, 0x45, 0x99, 0xcb, 0xfd, 0x09, 0xa0, 0xd4, 0x58, 0x81, 0xcc, 0x8c, 0xec, 0x97, 0x13, 0x06, 0x42, 0xd1, 0xd4, + 0x0a, 0xa8, 0x9c, 0xf4, 0x9a, 0x68, 0x59, 0xa9, 0x2b, 0x34, 0xa6, 0x6a, 0x24, 0xbd, 0xe0, 0xd2, 0x0b, 0xd2, 0xec, + 0x2c, 0xba, 0x93, 0xce, 0xa2, 0x56, 0x43, 0x99, 0x26, 0xac, 0xf9, 0x60, 0x31, 0xc4, 0xef, 0xc1, 0xa7, 0x67, 0x52, + 0x12, 0xae, 0x4c, 0xaf, 0xad, 0xa6, 0x57, 0xab, 0xa5, 0x39, 0xea, 0x18, 0x4d, 0x27, 0xb2, 0x69, 0x9e, 0x4b, 0x9c, + 0xac, 0x13, 0xda, 0x29, 0x12, 0x25, 0x90, 0x0e, 0x45, 0x08, 0x79, 0xc6, 0xd1, 0xd6, 0x5e, 0xa1, 0x4f, 0x68, 0x2e, + 0x76, 0x2c, 0x30, 0x4f, 0x29, 0x23, 0x1c, 0xc0, 0x02, 0x34, 0x2d, 0x1c, 0xc1, 0x53, 0x3c, 0xaf, 0xb5, 0x04, 0x91, + 0xd7, 0x5b, 0x9d, 0x6a, 0x5f, 0x8f, 0xca, 0xbe, 0xf0, 0xbc, 0x46, 0xa6, 0x05, 0x96, 0xf2, 0xb4, 0x56, 0xcb, 0xab, + 0xd1, 0x4e, 0xbd, 0x6f, 0x2b, 0xf1, 0x87, 0xdb, 0xf5, 0xb4, 0x0c, 0x2d, 0x5f, 0x4b, 0x89, 0xca, 0x5c, 0x16, 0xc7, + 0x34, 0x05, 0x19, 0x4a, 0x38, 0x66, 0x79, 0x5e, 0xc8, 0xf5, 0x8f, 0x20, 0x44, 0x31, 0x25, 0x31, 0xf0, 0x1d, 0x61, + 0x76, 0xe1, 0x14, 0x27, 0x38, 0x14, 0x5c, 0x83, 0x10, 0x72, 0xae, 0x13, 0x5a, 0xb8, 0xe0, 0x40, 0x11, 0x61, 0x86, + 0x44, 0xca, 0x08, 0x75, 0x2f, 0xf7, 0xcf, 0x93, 0x7b, 0x4d, 0xb2, 0x01, 0x1b, 0x7a, 0xa2, 0x5a, 0xa4, 0xf8, 0x96, + 0x4f, 0xde, 0x39, 0x1c, 0x15, 0xc1, 0x11, 0x57, 0xb0, 0xbf, 0xa7, 0x2c, 0xa5, 0x42, 0x03, 0xdf, 0xd7, 0x66, 0x5f, + 0x54, 0x55, 0x1f, 0x23, 0xd3, 0x79, 0x03, 0x88, 0xf4, 0xc1, 0xb7, 0x93, 0x92, 0x8d, 0x6a, 0x97, 0xfb, 0x67, 0xaf, + 0xb7, 0x99, 0xc0, 0xab, 0x95, 0x32, 0x7e, 0x85, 0x66, 0x83, 0xfd, 0x12, 0xd2, 0x48, 0xfd, 0xf0, 0x9c, 0x48, 0x28, + 0x48, 0xbe, 0x13, 0x03, 0x15, 0x5d, 0xee, 0x9f, 0xbd, 0x73, 0x62, 0xe1, 0x5a, 0x42, 0xd8, 0x9c, 0xb6, 0x93, 0x10, + 0x27, 0x24, 0x14, 0xc9, 0xb9, 0x17, 0x8c, 0x2b, 0x31, 0xc4, 0xb7, 0x17, 0x8a, 0x97, 0x60, 0x3f, 0x0c, 0xd8, 0x90, + 0x44, 0x0a, 0x03, 0x24, 0x42, 0x38, 0xaa, 0x98, 0x65, 0x04, 0x16, 0x40, 0x8c, 0x75, 0x01, 0x2b, 0xe1, 0x4a, 0xc5, + 0x0f, 0xe1, 0x48, 0x8c, 0xca, 0x73, 0x29, 0x3a, 0x3e, 0x6c, 0xe4, 0xa5, 0x95, 0xd6, 0xe8, 0xf7, 0x60, 0x39, 0xe9, + 0x87, 0x57, 0xaa, 0xeb, 0xa2, 0xe0, 0xa9, 0x4e, 0x20, 0xbb, 0xdc, 0x3f, 0x7b, 0xa9, 0x72, 0xc8, 0x66, 0xbe, 0xe6, + 0xf6, 0x1b, 0x16, 0xe6, 0xd9, 0x4b, 0xb7, 0x7c, 0x2b, 0x2a, 0x5f, 0xee, 0x9f, 0xbd, 0xdf, 0x56, 0x0d, 0xca, 0xf3, + 0x79, 0x69, 0xe2, 0x0b, 0xf8, 0x96, 0x34, 0xf2, 0x96, 0x4a, 0x34, 0x78, 0x2c, 0xc7, 0x42, 0x1c, 0x79, 0x59, 0x5e, + 0x78, 0x46, 0x9e, 0xe2, 0x94, 0x88, 0x28, 0x50, 0x75, 0xd5, 0x94, 0x92, 0xc7, 0x92, 0xf8, 0x62, 0x94, 0xcc, 0xe8, + 0x8e, 0xd0, 0xd0, 0x2d, 0x72, 0xd9, 0x14, 0x92, 0x67, 0x04, 0xe8, 0x0c, 0xef, 0x35, 0x51, 0xa7, 0x2a, 0xbc, 0x52, + 0x41, 0xa4, 0x49, 0x45, 0xb2, 0xe0, 0x90, 0x34, 0x71, 0x44, 0x9a, 0xd8, 0x27, 0xd9, 0xa0, 0x29, 0xc5, 0x43, 0xc7, + 0x2f, 0xfa, 0x95, 0x42, 0x06, 0xf2, 0xc2, 0xd4, 0x6e, 0x95, 0xe2, 0x37, 0xe8, 0xf8, 0xc2, 0xf5, 0x28, 0x24, 0x7a, + 0x20, 0xc8, 0xe2, 0xb9, 0x93, 0xe0, 0x44, 0x74, 0x7c, 0xc1, 0xae, 0x23, 0x48, 0x2d, 0x81, 0x59, 0x61, 0x8e, 0xbc, + 0xa2, 0x6a, 0x4b, 0x55, 0xf5, 0x5d, 0xb1, 0x4e, 0x09, 0xf6, 0x5d, 0x60, 0xdc, 0xd8, 0x57, 0x99, 0x38, 0xd9, 0x66, + 0x93, 0x93, 0x83, 0x03, 0x47, 0x36, 0xfa, 0x8a, 0x3b, 0x89, 0x7e, 0x5f, 0x06, 0xee, 0xbe, 0x97, 0xbc, 0x22, 0x40, + 0x02, 0xfe, 0x5a, 0x2d, 0x1a, 0xe6, 0x10, 0x85, 0x76, 0xfc, 0x2a, 0x06, 0x35, 0xf0, 0x42, 0xd3, 0xab, 0x4e, 0xbf, + 0x56, 0x2b, 0x82, 0xb4, 0x55, 0x6c, 0xdd, 0xe2, 0x34, 0x5f, 0x38, 0x45, 0xf2, 0x4f, 0x73, 0x23, 0x63, 0x4a, 0x83, + 0x80, 0x98, 0x49, 0xb3, 0x4c, 0x4f, 0xc6, 0xd8, 0x12, 0x0c, 0xea, 0x7d, 0xa3, 0xd2, 0x16, 0xb0, 0xc8, 0xaf, 0x52, + 0x95, 0x34, 0x3b, 0x6b, 0x23, 0x4f, 0x57, 0x82, 0xa0, 0x14, 0x54, 0xaa, 0xe5, 0x8a, 0xbc, 0x9f, 0x6f, 0x66, 0x5d, + 0xe2, 0x0c, 0x29, 0x1f, 0x97, 0x80, 0x42, 0x20, 0xab, 0x5d, 0x20, 0xe5, 0x39, 0x99, 0xed, 0x26, 0xf9, 0x33, 0x83, + 0xe4, 0x9f, 0x10, 0x6a, 0x90, 0xbf, 0xf4, 0x70, 0xb8, 0x89, 0x72, 0x2d, 0x64, 0xfa, 0xd5, 0xf9, 0x8c, 0x80, 0x0f, + 0xad, 0x8a, 0xd1, 0x4a, 0x54, 0x71, 0x07, 0x43, 0x31, 0x77, 0x88, 0xf0, 0x42, 0x62, 0x1d, 0x02, 0x76, 0xca, 0x98, + 0x1a, 0x0c, 0xbd, 0xcd, 0xa5, 0x67, 0x72, 0xc0, 0xb3, 0xf7, 0xf7, 0x87, 0x43, 0xcf, 0x67, 0x9b, 0x3b, 0xd7, 0xc8, + 0xfe, 0x84, 0x59, 0x1b, 0x1b, 0xb7, 0x9a, 0x0b, 0x0a, 0xe3, 0x17, 0x61, 0xec, 0x2a, 0xf3, 0x59, 0xdb, 0x84, 0x5a, + 0xfe, 0x01, 0xb4, 0xad, 0x96, 0xa8, 0x41, 0x8d, 0x6e, 0x81, 0x1f, 0xc9, 0x1c, 0x54, 0x3f, 0xdd, 0xc1, 0x3e, 0xce, + 0x44, 0x05, 0x1a, 0x07, 0xdb, 0x5f, 0x3f, 0xc9, 0x15, 0x99, 0x48, 0xd0, 0xd0, 0x12, 0xf8, 0x9f, 0x24, 0x79, 0xa0, + 0x1b, 0x21, 0x17, 0x00, 0x41, 0x33, 0x81, 0xa7, 0x12, 0x61, 0xb6, 0x5d, 0x3a, 0xdf, 0x9f, 0xef, 0x11, 0x32, 0x2b, + 0x9d, 0x8f, 0x6f, 0xcb, 0xdc, 0x2b, 0x20, 0x0b, 0xe4, 0x81, 0xf1, 0x58, 0x14, 0xc8, 0xe8, 0xe5, 0xb9, 0xae, 0x2e, + 0x0c, 0x48, 0xb7, 0xd4, 0xb7, 0x8d, 0xc8, 0xa6, 0xf0, 0xca, 0xc9, 0xf7, 0x1a, 0x0d, 0x6b, 0x6f, 0xf7, 0xe1, 0xed, + 0x4b, 0x2e, 0x60, 0x84, 0xe7, 0x77, 0xa2, 0xb6, 0xee, 0x37, 0xff, 0xb8, 0x9e, 0xc0, 0xb2, 0xb6, 0x28, 0x2e, 0x8b, + 0x33, 0x9a, 0xf2, 0x27, 0x74, 0x9c, 0xa4, 0x10, 0xb2, 0x28, 0x70, 0x82, 0xf2, 0x7d, 0xc3, 0x6d, 0x27, 0xe6, 0x67, + 0xc4, 0x09, 0xd6, 0x26, 0x28, 0x7e, 0x7d, 0x14, 0x31, 0xeb, 0xcb, 0xf5, 0x56, 0xb3, 0x83, 0x83, 0x77, 0x25, 0x9a, + 0x14, 0x94, 0x02, 0x0a, 0x83, 0x69, 0x49, 0x95, 0x46, 0x05, 0x72, 0xf7, 0x9d, 0xc2, 0x05, 0xa0, 0x19, 0x86, 0xc9, + 0x7b, 0x9e, 0x13, 0x9e, 0x4f, 0xd6, 0x59, 0xbc, 0x72, 0x4d, 0x30, 0xd3, 0x6c, 0x01, 0x0e, 0x0f, 0x86, 0xb6, 0xf4, + 0x15, 0x65, 0x65, 0x3a, 0x6c, 0x01, 0xc3, 0x39, 0x20, 0xcb, 0x11, 0x46, 0x88, 0x41, 0x81, 0x5b, 0x8d, 0x92, 0xd7, + 0xa0, 0x57, 0x86, 0x38, 0x73, 0x43, 0x48, 0x80, 0xad, 0x6c, 0x59, 0x84, 0xb0, 0xcc, 0xcb, 0x31, 0x32, 0x09, 0xce, + 0x9e, 0x6f, 0xf3, 0x28, 0x6b, 0xa2, 0xa6, 0x42, 0xea, 0x40, 0x8d, 0x14, 0x15, 0x0d, 0xdc, 0x85, 0xc3, 0x94, 0xe2, + 0xa6, 0xc3, 0x66, 0xc0, 0x80, 0x3f, 0x70, 0x47, 0xc6, 0xa2, 0x40, 0x66, 0x24, 0xee, 0xdc, 0xa9, 0x0c, 0xdd, 0x49, + 0x44, 0x33, 0xac, 0x10, 0x17, 0x9a, 0x68, 0x4a, 0x44, 0x58, 0xef, 0xbc, 0xe4, 0xa5, 0xfb, 0x32, 0x87, 0x9a, 0x6b, + 0x2e, 0x58, 0xe6, 0x91, 0x18, 0xd3, 0xdf, 0x97, 0x69, 0xd1, 0x45, 0x25, 0x50, 0xc3, 0xe8, 0x8d, 0xf5, 0x4a, 0xac, + 0x01, 0xcd, 0x81, 0xbe, 0x96, 0x17, 0xdc, 0x58, 0x51, 0xed, 0xc3, 0x16, 0x63, 0x1a, 0x52, 0xff, 0x2d, 0x64, 0xba, + 0xac, 0xef, 0xf9, 0xe7, 0x42, 0x16, 0x32, 0x9c, 0x55, 0x18, 0x7b, 0x2a, 0x18, 0x3b, 0x02, 0x3d, 0x4d, 0xa7, 0x7e, + 0xf7, 0x55, 0xc2, 0x0b, 0x53, 0x52, 0x4e, 0x91, 0xd8, 0xfb, 0x22, 0x58, 0x6e, 0xfc, 0x5e, 0x5b, 0x0d, 0x8f, 0x11, + 0x48, 0x02, 0xc2, 0x8a, 0xb3, 0xa7, 0x08, 0x67, 0xb5, 0x5a, 0x27, 0xeb, 0xd2, 0xd2, 0x45, 0x52, 0xc2, 0xc8, 0x20, + 0x9e, 0x0b, 0x04, 0x5f, 0x91, 0xa1, 0x10, 0xf1, 0xd7, 0xb9, 0xd9, 0x19, 0xb8, 0xda, 0xcf, 0xde, 0x3a, 0x26, 0x57, + 0x33, 0xeb, 0x16, 0x31, 0x53, 0x98, 0x8f, 0x53, 0xc6, 0x5b, 0xde, 0xdc, 0x9f, 0xdf, 0x01, 0x70, 0xef, 0xb5, 0x30, + 0xe4, 0xa2, 0xa1, 0x0e, 0x97, 0x2c, 0xa1, 0xd8, 0x7d, 0x1d, 0x54, 0xa6, 0x25, 0x9a, 0x83, 0x75, 0x78, 0x69, 0xca, + 0x72, 0x92, 0xe5, 0x79, 0x46, 0xcb, 0xe8, 0xfe, 0x5a, 0xfe, 0xa5, 0x10, 0x2e, 0x9b, 0xce, 0xf6, 0xf3, 0x19, 0xe1, + 0xd8, 0x20, 0xd4, 0x37, 0xbb, 0x42, 0x1f, 0x25, 0x98, 0xb0, 0xaf, 0x95, 0x50, 0xfc, 0x75, 0x9b, 0x50, 0xc4, 0xa9, + 0xda, 0xf2, 0x42, 0x20, 0xb6, 0x1e, 0x20, 0x10, 0x95, 0x93, 0x5d, 0xcb, 0x44, 0x50, 0x47, 0x2a, 0x32, 0xb1, 0xba, + 0xa4, 0x24, 0xc5, 0x4c, 0xad, 0x46, 0xaf, 0xbd, 0x5a, 0xb1, 0x41, 0x13, 0x9c, 0x48, 0xb6, 0x0d, 0x3f, 0x5b, 0xf2, + 0xa7, 0xc1, 0x89, 0xa5, 0x13, 0xd8, 0x61, 0x85, 0xc9, 0x82, 0x5c, 0x48, 0x71, 0x76, 0x44, 0x4e, 0x96, 0xa0, 0x69, + 0x45, 0x41, 0x8a, 0xc0, 0x09, 0x2b, 0xa2, 0x4c, 0x00, 0xb1, 0x90, 0x15, 0xca, 0x80, 0x74, 0xb6, 0x26, 0xff, 0x69, + 0xf3, 0xf2, 0xd3, 0x9a, 0x68, 0x45, 0xae, 0x48, 0xf5, 0xa1, 0x92, 0x6e, 0xa0, 0x20, 0x50, 0xfa, 0xe1, 0x9e, 0x30, + 0x41, 0x4b, 0x51, 0x8e, 0x4c, 0x39, 0x84, 0x9b, 0xe0, 0x42, 0xdb, 0x7b, 0x27, 0x03, 0xbc, 0x5b, 0xa4, 0x09, 0x4e, + 0x0c, 0xba, 0x7e, 0x4e, 0x78, 0x85, 0x95, 0x84, 0x44, 0x59, 0x4a, 0xd8, 0x17, 0x64, 0xca, 0x49, 0x3a, 0x68, 0x0e, + 0x41, 0x01, 0xed, 0x44, 0xdd, 0xb4, 0x34, 0x81, 0xa3, 0x5a, 0x0d, 0xf9, 0x7a, 0xd4, 0x70, 0xc0, 0x6a, 0xd1, 0x10, + 0x53, 0x1c, 0x49, 0xc3, 0xe4, 0xfc, 0xe0, 0xc0, 0xf1, 0xcb, 0x71, 0x07, 0xd1, 0x10, 0xe1, 0x64, 0xb5, 0x72, 0x04, + 0x58, 0x3e, 0x5a, 0xad, 0x7c, 0x13, 0x2c, 0xf1, 0x1a, 0x9a, 0xcd, 0xfa, 0x9c, 0xcc, 0x84, 0x00, 0x9c, 0x01, 0x84, + 0x35, 0xe2, 0xf8, 0xca, 0xb9, 0xe7, 0x83, 0x33, 0xaa, 0x96, 0x0e, 0xa2, 0x5a, 0x6b, 0x68, 0x30, 0xae, 0x41, 0x34, + 0x24, 0x7e, 0x9e, 0x1c, 0x1c, 0xec, 0x65, 0x4a, 0x44, 0x7e, 0x00, 0x51, 0xf6, 0x41, 0x48, 0x16, 0xd9, 0xa1, 0xb9, + 0x1a, 0xeb, 0xce, 0x80, 0x82, 0xa2, 0xd4, 0xb2, 0xea, 0x7a, 0x95, 0x24, 0x88, 0xa2, 0x12, 0x56, 0xb1, 0xe0, 0x3e, + 0x58, 0xf6, 0x05, 0x99, 0x7f, 0xc3, 0x8b, 0x24, 0xeb, 0x5f, 0xb7, 0xa6, 0x56, 0xbb, 0xae, 0xeb, 0xa7, 0x13, 0x11, + 0xc9, 0xd0, 0x51, 0x58, 0x41, 0xfc, 0x87, 0x0a, 0x4c, 0x63, 0xe0, 0x41, 0x31, 0xd6, 0x90, 0x48, 0xf0, 0xb5, 0x6a, + 0xa3, 0x4f, 0x93, 0xfc, 0xb2, 0xd5, 0xcb, 0xa0, 0x36, 0xdc, 0xef, 0x85, 0xe4, 0x48, 0x41, 0x22, 0xc9, 0x63, 0x0d, + 0x67, 0x3b, 0x70, 0xf1, 0x0b, 0x5f, 0xc3, 0xd9, 0x6e, 0xdc, 0x6a, 0x4c, 0x7d, 0xbf, 0x0b, 0x3e, 0x83, 0x37, 0x48, + 0x40, 0xcb, 0x02, 0x03, 0xca, 0xe3, 0x75, 0xdd, 0x4b, 0xb2, 0x52, 0x10, 0xa6, 0x9c, 0x38, 0xac, 0xba, 0x01, 0x4a, + 0x6d, 0xd4, 0x30, 0x7c, 0x99, 0x37, 0x43, 0x86, 0x4b, 0xa0, 0x9a, 0xb9, 0x02, 0xe4, 0xa4, 0x7c, 0xed, 0xb3, 0x83, + 0x03, 0xb0, 0x0d, 0x40, 0x89, 0x73, 0x47, 0xfe, 0x8c, 0xcf, 0x53, 0x50, 0xa5, 0x32, 0xfd, 0x1b, 0x8a, 0xe1, 0x1c, + 0x88, 0x28, 0x83, 0x1f, 0x50, 0x30, 0xf3, 0xb3, 0x8c, 0x2d, 0x64, 0x99, 0xfa, 0x8d, 0x13, 0xa2, 0x49, 0x39, 0x93, + 0x3a, 0x61, 0x8a, 0x3a, 0xa9, 0xa2, 0xd3, 0x2a, 0xda, 0x9e, 0x2d, 0x68, 0xcc, 0x5f, 0xb0, 0x8c, 0xd3, 0x18, 0xa6, + 0x5f, 0x52, 0x1c, 0xcc, 0x28, 0x43, 0xb0, 0x61, 0x2b, 0xad, 0xfc, 0x20, 0xb8, 0xb7, 0x09, 0xaf, 0xea, 0x40, 0xa1, + 0x1f, 0x07, 0x91, 0x1c, 0xc4, 0x4c, 0x67, 0xd4, 0x29, 0x9c, 0x45, 0x4d, 0x33, 0x9d, 0xa6, 0x54, 0x36, 0x04, 0x77, + 0x77, 0x18, 0xd1, 0x92, 0x40, 0x4b, 0xcf, 0x7b, 0xb5, 0x16, 0x08, 0x78, 0xef, 0x58, 0x04, 0x73, 0x26, 0x98, 0x1b, + 0x1c, 0xd5, 0xad, 0xc2, 0xa9, 0xe9, 0xe6, 0xab, 0xad, 0x87, 0xda, 0xb6, 0x09, 0x07, 0x41, 0x27, 0x27, 0xbb, 0x2d, + 0xab, 0x97, 0x5a, 0x72, 0x68, 0x69, 0xc1, 0x1e, 0xca, 0x98, 0xd1, 0x52, 0x93, 0x17, 0xd2, 0x5b, 0xf1, 0x92, 0x93, + 0x0f, 0x70, 0x6a, 0xe8, 0x39, 0x9f, 0x46, 0x6b, 0x87, 0x63, 0x3a, 0x97, 0x85, 0xf6, 0x7f, 0xc9, 0x9d, 0x57, 0xf8, + 0x39, 0x84, 0x75, 0xbf, 0x2d, 0xab, 0x6f, 0x86, 0x73, 0xbf, 0x2d, 0x11, 0xf4, 0xad, 0xb7, 0x51, 0xcf, 0x08, 0xe3, + 0xb6, 0xdd, 0x53, 0xb7, 0x69, 0x6b, 0x6d, 0xe9, 0x07, 0x19, 0x44, 0x92, 0x89, 0x96, 0x62, 0x3f, 0xe0, 0x32, 0x4d, + 0x0d, 0xd2, 0xe5, 0xaa, 0x16, 0x12, 0x55, 0x09, 0x86, 0x52, 0x87, 0xdf, 0xb5, 0x3c, 0x4a, 0xc6, 0xa4, 0xd2, 0xce, + 0x78, 0xe3, 0xa7, 0x7c, 0x1f, 0x76, 0x59, 0xb2, 0x71, 0x12, 0x2f, 0x24, 0xe0, 0x41, 0x7b, 0xd8, 0x10, 0x86, 0xb1, + 0x9d, 0xc9, 0x93, 0x40, 0x66, 0xff, 0x24, 0xd1, 0xba, 0x5b, 0xd5, 0xca, 0x78, 0x0f, 0xf6, 0x3f, 0xc2, 0xa1, 0x3e, + 0x1e, 0x47, 0x15, 0x07, 0xa6, 0xde, 0x32, 0x2f, 0x9c, 0x02, 0x89, 0x54, 0xde, 0x62, 0x84, 0x93, 0x5c, 0x84, 0xb7, + 0xbf, 0xc3, 0x3f, 0x2a, 0x96, 0x38, 0x2e, 0x38, 0xce, 0xb3, 0x87, 0x72, 0x44, 0x09, 0x7e, 0x11, 0xbd, 0x07, 0x3a, + 0x16, 0x14, 0x9a, 0x6b, 0x2a, 0x7a, 0x9a, 0xa8, 0x89, 0xec, 0xcc, 0x4a, 0xc5, 0xb4, 0xc8, 0xa8, 0x11, 0xc3, 0x6c, + 0x49, 0xe3, 0xd4, 0x56, 0x36, 0x2f, 0x76, 0x55, 0x65, 0x5c, 0xb4, 0x03, 0x8b, 0x65, 0x60, 0x71, 0xb5, 0x72, 0xaa, + 0xa8, 0x26, 0xcc, 0x88, 0x63, 0x20, 0xcc, 0x8c, 0x84, 0x8a, 0x8a, 0x66, 0x2d, 0xdb, 0x38, 0x68, 0x3d, 0x9f, 0x48, + 0xeb, 0xe6, 0x15, 0x38, 0x4c, 0x17, 0x82, 0x6c, 0x6e, 0xfa, 0x14, 0xb0, 0x9c, 0x5d, 0x31, 0x90, 0x81, 0xa1, 0x1f, + 0x8a, 0x4c, 0xd9, 0x32, 0xa5, 0x75, 0x0b, 0x7e, 0xd1, 0x3d, 0xb9, 0xb2, 0x0a, 0x75, 0x9b, 0xef, 0x8d, 0x5c, 0xa3, + 0xa7, 0xc9, 0xae, 0x5c, 0xa3, 0x8a, 0xb6, 0xbb, 0xd7, 0x44, 0xf7, 0x67, 0xa5, 0xca, 0xb1, 0xb6, 0x57, 0xf9, 0x1d, + 0xc3, 0xb5, 0x80, 0x36, 0x25, 0x9a, 0x35, 0x57, 0x39, 0xcf, 0xf3, 0x71, 0x71, 0x96, 0x40, 0xa4, 0xee, 0x8c, 0x25, + 0xfd, 0x2b, 0xab, 0x51, 0x1c, 0xc8, 0x75, 0xbe, 0x23, 0x93, 0x28, 0xb9, 0xf6, 0xa3, 0x77, 0x30, 0x5e, 0xf9, 0xf2, + 0xf9, 0x5d, 0x90, 0xfa, 0x9c, 0x2a, 0xee, 0x52, 0xc2, 0xf0, 0x9d, 0x01, 0xc3, 0x77, 0x92, 0x4f, 0x97, 0xed, 0xf1, + 0xf2, 0x45, 0xd1, 0x81, 0x37, 0xce, 0x35, 0xcb, 0x98, 0xf2, 0xed, 0x63, 0xac, 0xb3, 0xb0, 0x69, 0xc1, 0xc2, 0xa6, + 0xdc, 0x59, 0xef, 0xca, 0x71, 0x7e, 0xdc, 0xde, 0xcb, 0x26, 0x67, 0xfb, 0xb1, 0xdc, 0xf8, 0x3f, 0x7a, 0xf7, 0xb6, + 0x31, 0xb8, 0xdc, 0xa1, 0x7b, 0x28, 0x92, 0x55, 0x24, 0xc8, 0x4f, 0x20, 0xe9, 0x80, 0x93, 0x9e, 0x71, 0xe4, 0xa0, + 0x94, 0x53, 0x3a, 0x0f, 0xc8, 0x19, 0xcd, 0x33, 0x9e, 0x4c, 0x55, 0x9f, 0x99, 0x3a, 0x67, 0x24, 0x5e, 0x82, 0x2b, + 0x5a, 0xc4, 0xda, 0xbd, 0xea, 0x49, 0xae, 0xe5, 0x47, 0x16, 0x07, 0x5e, 0x86, 0x95, 0x14, 0xc9, 0xbc, 0x34, 0x27, + 0x3a, 0xd7, 0x78, 0xf3, 0x1d, 0x1e, 0xb3, 0x98, 0x65, 0x21, 0x4d, 0x9d, 0x04, 0x2d, 0x77, 0x0d, 0x96, 0x40, 0x40, + 0x46, 0x0e, 0x86, 0x7f, 0x2a, 0x8f, 0xfc, 0xb9, 0xd0, 0x1b, 0xf8, 0x81, 0xa6, 0x94, 0x87, 0x49, 0x00, 0x69, 0x29, + 0x6e, 0x50, 0x1c, 0x69, 0x3a, 0x38, 0xd8, 0x73, 0x6c, 0xe1, 0x96, 0x80, 0xc3, 0xdf, 0xe6, 0x1b, 0xd4, 0x5f, 0xc2, + 0xe9, 0x9c, 0x72, 0x68, 0x8a, 0x96, 0x74, 0xfd, 0x20, 0x0b, 0x77, 0x3f, 0xd2, 0x3b, 0x1c, 0xa3, 0x3c, 0xf7, 0x24, + 0xd4, 0xf6, 0x98, 0xd1, 0x28, 0xb0, 0xf1, 0x47, 0x7a, 0xe7, 0x15, 0xe7, 0xc5, 0xc5, 0xf1, 0x66, 0xb1, 0x80, 0x76, + 0x72, 0x13, 0xdb, 0xb8, 0x1c, 0xc4, 0x5b, 0xe6, 0x38, 0x49, 0xd9, 0x04, 0x88, 0xf3, 0x6f, 0xf4, 0xce, 0x93, 0xfd, + 0x31, 0xe3, 0xb4, 0x1e, 0x5a, 0x6a, 0xd4, 0xbb, 0x46, 0xb1, 0xb9, 0x0c, 0xca, 0xa0, 0x18, 0x88, 0xb6, 0x43, 0x52, + 0xa9, 0x57, 0x9a, 0x87, 0x08, 0xe5, 0x0f, 0x9d, 0x0a, 0xfe, 0xd6, 0x14, 0x6d, 0xbc, 0x92, 0xf9, 0xba, 0xd6, 0x88, + 0x42, 0x83, 0x32, 0xd3, 0xe3, 0xd2, 0x89, 0xf5, 0xae, 0x53, 0x47, 0x10, 0x0c, 0x47, 0xd8, 0xb7, 0x5c, 0x75, 0xea, + 0xfd, 0x24, 0x13, 0x42, 0xca, 0x48, 0xd2, 0xcb, 0xb2, 0x9d, 0x75, 0xe9, 0x00, 0xde, 0x21, 0xa1, 0xc5, 0x17, 0x07, + 0x32, 0x73, 0x9d, 0x2d, 0xfa, 0x37, 0x4e, 0x9c, 0xa5, 0x9e, 0x82, 0x17, 0x9b, 0x58, 0xe4, 0x39, 0x50, 0xa1, 0xa2, + 0x2f, 0x99, 0x00, 0x08, 0x67, 0xd8, 0x37, 0xa4, 0x66, 0x2a, 0xa4, 0xa6, 0x6b, 0x60, 0x7c, 0x87, 0x94, 0xa4, 0x02, + 0x19, 0x42, 0x89, 0x14, 0x42, 0x4f, 0x2d, 0xae, 0x22, 0x21, 0x73, 0x41, 0x8b, 0xf3, 0x73, 0x72, 0xcd, 0xd3, 0x0a, + 0x58, 0x8e, 0xe8, 0x07, 0xe5, 0x1e, 0x4c, 0x89, 0xca, 0x0a, 0x79, 0x71, 0x2c, 0x5b, 0xa7, 0xb7, 0x3a, 0x89, 0xab, + 0xa7, 0x45, 0x34, 0x4a, 0x9c, 0x10, 0x2d, 0x63, 0x27, 0xc4, 0x29, 0xa4, 0x23, 0x26, 0x79, 0x01, 0x3f, 0x35, 0x57, + 0xa3, 0x92, 0xac, 0xbc, 0xfd, 0x8c, 0x1f, 0x28, 0xf3, 0x1c, 0x52, 0x34, 0x71, 0xac, 0x79, 0x4a, 0xec, 0x88, 0xc3, + 0x76, 0xc6, 0xb2, 0x7d, 0xa7, 0x12, 0x74, 0x14, 0x60, 0x7f, 0xe3, 0xce, 0xd2, 0x98, 0x85, 0x79, 0x9a, 0x5b, 0x9d, + 0xf9, 0x53, 0xc1, 0xbe, 0x32, 0x87, 0xd4, 0xc9, 0xc8, 0x9a, 0xc4, 0xb9, 0x3f, 0xd5, 0xf2, 0x97, 0x39, 0x4d, 0xef, + 0x2e, 0x28, 0xa4, 0x3a, 0x27, 0x70, 0xda, 0xb7, 0x5c, 0x86, 0x32, 0x4d, 0xbd, 0x9f, 0x0a, 0x65, 0x25, 0xaf, 0x9e, + 0x02, 0x5c, 0x3f, 0x23, 0x98, 0x8b, 0x68, 0xa3, 0xe1, 0x88, 0x91, 0xbb, 0x85, 0xee, 0x3c, 0x3d, 0x49, 0x3b, 0x0c, + 0xfc, 0x6b, 0x25, 0xa6, 0x55, 0xb0, 0x00, 0x27, 0xe6, 0x89, 0xd4, 0x41, 0x36, 0x5c, 0xf7, 0xca, 0x40, 0x11, 0x84, + 0xef, 0xd2, 0xdd, 0x53, 0xdd, 0x96, 0x34, 0xbb, 0x7b, 0xaa, 0x95, 0xa0, 0x9f, 0x48, 0xf8, 0xc1, 0x6a, 0x9c, 0xe2, + 0xf8, 0x32, 0xcb, 0x73, 0x94, 0x03, 0x78, 0x5f, 0x77, 0x1c, 0xe7, 0x6b, 0x95, 0x32, 0xe8, 0x42, 0x2c, 0xf6, 0x22, + 0x4a, 0x34, 0x13, 0x2f, 0xc7, 0xff, 0x7a, 0x63, 0xfc, 0xaf, 0x8d, 0x33, 0xa7, 0x60, 0x1a, 0x4d, 0x62, 0x1a, 0x68, + 0xd6, 0x89, 0x24, 0x01, 0x0a, 0xbd, 0x2d, 0xe6, 0xe4, 0xf5, 0x95, 0x07, 0x1a, 0xd7, 0x72, 0x9c, 0xc4, 0xbc, 0x3e, + 0xf6, 0xa7, 0x2c, 0xba, 0xf3, 0xe6, 0xac, 0x3e, 0x4d, 0xe2, 0x24, 0x9b, 0xf9, 0x23, 0x8a, 0xb3, 0xbb, 0x8c, 0xd3, + 0x69, 0x7d, 0xce, 0xf0, 0x73, 0x1a, 0x2d, 0x28, 0x67, 0x23, 0x1f, 0xdb, 0x67, 0x29, 0xf3, 0x23, 0xeb, 0x95, 0x9f, + 0xa6, 0xc9, 0x8d, 0x8d, 0xdf, 0x26, 0xd7, 0x09, 0x4f, 0xf0, 0xeb, 0xdb, 0xbb, 0x09, 0x8d, 0xf1, 0xfb, 0xeb, 0x79, + 0xcc, 0xe7, 0x38, 0xf3, 0xe3, 0xac, 0x9e, 0xd1, 0x94, 0x8d, 0x3b, 0xa3, 0x24, 0x4a, 0xd2, 0x3a, 0x64, 0x6c, 0x4f, + 0xa9, 0x17, 0xb1, 0x49, 0xc8, 0xad, 0xc0, 0x4f, 0x3f, 0x76, 0xea, 0xf5, 0x59, 0xca, 0xa6, 0x7e, 0x7a, 0x57, 0x17, + 0x35, 0xbc, 0xcf, 0x9b, 0x87, 0xfe, 0xe3, 0xf1, 0x51, 0x87, 0xa7, 0x7e, 0x9c, 0x31, 0x58, 0x26, 0xcf, 0x8f, 0x22, + 0xeb, 0xf0, 0xb8, 0x39, 0xcd, 0xf6, 0x64, 0x20, 0xcf, 0x8f, 0x79, 0x7e, 0x85, 0xdf, 0x00, 0xdc, 0xee, 0x35, 0x8f, + 0xf1, 0xf5, 0x9c, 0xf3, 0x24, 0x5e, 0x8e, 0xe6, 0x69, 0x96, 0xa4, 0xde, 0x2c, 0x61, 0x31, 0xa7, 0x69, 0xe7, 0x3a, + 0x49, 0x03, 0x9a, 0xd6, 0x53, 0x3f, 0x60, 0xf3, 0xcc, 0x3b, 0x9a, 0xdd, 0x76, 0x40, 0xb3, 0x98, 0xa4, 0xc9, 0x3c, + 0x0e, 0xd4, 0x58, 0x2c, 0x0e, 0x69, 0xca, 0xb8, 0xf9, 0x42, 0x5c, 0x62, 0xe2, 0x45, 0x2c, 0xa6, 0x7e, 0x5a, 0x9f, + 0x40, 0x63, 0x30, 0x8b, 0x9a, 0x01, 0x9d, 0xe0, 0x74, 0x72, 0xed, 0x3b, 0xad, 0xf6, 0x23, 0xac, 0xff, 0xba, 0xc7, + 0xc8, 0x6a, 0x6e, 0x2f, 0x6e, 0x35, 0x9b, 0x7f, 0x41, 0x9d, 0xb5, 0x51, 0x04, 0x40, 0x5e, 0x6b, 0x76, 0x6b, 0x65, + 0x09, 0x64, 0xb4, 0x6d, 0x6b, 0xd9, 0x99, 0xf9, 0x01, 0xe4, 0x03, 0x7b, 0xed, 0xd9, 0x6d, 0x0e, 0xb3, 0xf3, 0x64, + 0x8a, 0xa9, 0x9a, 0xa4, 0x7a, 0x5a, 0xfe, 0x5e, 0x88, 0x4f, 0xb7, 0x43, 0xdc, 0xd6, 0x10, 0x97, 0x58, 0xaf, 0x07, + 0xf3, 0x54, 0xc4, 0x56, 0xbd, 0x56, 0x26, 0x01, 0x09, 0x93, 0x05, 0x4d, 0x35, 0x1c, 0xe2, 0xe1, 0x77, 0x83, 0xd1, + 0xde, 0x0e, 0xc6, 0xe9, 0xa7, 0xc0, 0x48, 0xe3, 0x60, 0x59, 0x5d, 0xd7, 0x56, 0x4a, 0xa7, 0x9d, 0x90, 0x02, 0x3d, + 0x79, 0x6d, 0xf8, 0x7d, 0xc3, 0x02, 0x1e, 0xca, 0x9f, 0x82, 0x9c, 0x6f, 0xe4, 0xbb, 0xe3, 0x66, 0x53, 0x3e, 0x67, + 0xec, 0x57, 0xea, 0xb5, 0x5c, 0xa8, 0x90, 0x5f, 0xe1, 0x1f, 0x8b, 0xb3, 0xbc, 0x55, 0xee, 0x89, 0xbf, 0x36, 0x0f, + 0xf9, 0x1a, 0x29, 0x8a, 0xe5, 0x91, 0x68, 0x9c, 0x6a, 0x59, 0x29, 0x85, 0x0f, 0xb8, 0xed, 0x04, 0x77, 0x24, 0xac, + 0x57, 0x1c, 0xe2, 0x64, 0xfd, 0xaf, 0x65, 0xde, 0x85, 0x07, 0x91, 0x0e, 0x23, 0xd5, 0x30, 0xe9, 0xa4, 0x3d, 0xd2, + 0xec, 0xa4, 0xf5, 0x3a, 0x72, 0x12, 0x12, 0x0f, 0x52, 0x95, 0x9c, 0xe7, 0xb0, 0x7e, 0x22, 0x8c, 0xed, 0x0c, 0x79, + 0x09, 0x9c, 0x34, 0x5d, 0xad, 0xca, 0x30, 0x00, 0x13, 0xa7, 0x35, 0x7e, 0xe4, 0xaa, 0x02, 0xce, 0x0c, 0x4e, 0x9e, + 0xe8, 0xab, 0x5d, 0x62, 0xcd, 0x2b, 0xa2, 0x64, 0x24, 0x30, 0xe7, 0xce, 0x7c, 0x1e, 0x82, 0x97, 0xa2, 0x10, 0x3f, + 0x65, 0x0a, 0x93, 0xdd, 0xb0, 0x51, 0x3f, 0x2e, 0xf2, 0xdb, 0x20, 0x8f, 0x2f, 0xce, 0xa1, 0x97, 0x3b, 0x4e, 0x84, + 0xc5, 0x54, 0xf4, 0xff, 0x9e, 0x1b, 0x92, 0x3a, 0x76, 0x59, 0x3c, 0x8a, 0xe6, 0x01, 0xcd, 0x44, 0x0f, 0xa5, 0x38, + 0xff, 0xbb, 0x59, 0x4b, 0x34, 0x81, 0xde, 0x45, 0x36, 0x0f, 0x54, 0x84, 0x1b, 0x54, 0x8a, 0xe7, 0xba, 0x78, 0x2e, + 0xdb, 0xea, 0x4b, 0x25, 0xd8, 0xd8, 0x81, 0x96, 0xee, 0x3c, 0x66, 0xbf, 0xcc, 0xe9, 0x25, 0x0b, 0x8c, 0x73, 0xbb, + 0x34, 0x1e, 0x25, 0x01, 0x7d, 0xff, 0xf6, 0x1b, 0xc8, 0x76, 0x4f, 0x62, 0x20, 0xb1, 0x58, 0xfa, 0xbb, 0x70, 0x46, + 0x62, 0x37, 0xa0, 0x0b, 0x36, 0xa2, 0xfd, 0xab, 0xfd, 0xe5, 0xd6, 0x8a, 0xf2, 0x35, 0xca, 0x1b, 0x57, 0x22, 0xe9, + 0x4f, 0x40, 0x79, 0xb5, 0xbf, 0xbc, 0xe3, 0x79, 0x63, 0x7f, 0x19, 0xbb, 0x41, 0x32, 0xf5, 0x59, 0x0c, 0xbf, 0xb3, + 0x7c, 0x7f, 0xc9, 0xe0, 0x07, 0xcf, 0xaf, 0xf2, 0x32, 0x51, 0xb4, 0x80, 0xc8, 0x98, 0x82, 0xc2, 0x5d, 0x0b, 0xb9, + 0x1f, 0x12, 0x16, 0x8b, 0xa2, 0xfb, 0x7a, 0xa6, 0xba, 0x57, 0x40, 0xf2, 0x37, 0x44, 0x1a, 0xcc, 0xda, 0x5c, 0x1e, + 0x3f, 0xd4, 0x5c, 0xa6, 0x31, 0x67, 0x22, 0x2d, 0x5e, 0x87, 0x73, 0x42, 0x3f, 0xbb, 0x1c, 0xc9, 0x73, 0xa8, 0x59, + 0x79, 0xea, 0xc2, 0x17, 0x88, 0x95, 0x16, 0x30, 0x4d, 0x85, 0xb1, 0x4f, 0x77, 0x1f, 0x94, 0x8c, 0xef, 0x33, 0xfe, + 0x0a, 0xaa, 0xca, 0x92, 0x79, 0x3a, 0x82, 0x58, 0xaf, 0x52, 0x29, 0x36, 0xbd, 0x62, 0xb6, 0xd0, 0xdf, 0x6c, 0xcc, + 0x8d, 0x24, 0x5b, 0x8e, 0x99, 0x79, 0x67, 0x07, 0x15, 0xf1, 0x44, 0x79, 0x16, 0x46, 0xe9, 0x0f, 0x7a, 0x4a, 0xa0, + 0x10, 0x05, 0x22, 0x5f, 0xd4, 0x49, 0x49, 0x2f, 0x2d, 0x71, 0x4e, 0x08, 0x61, 0x2e, 0x0b, 0x44, 0x20, 0x0f, 0x14, + 0x8b, 0x7a, 0x0b, 0x22, 0x43, 0x2c, 0x28, 0x35, 0x3c, 0xa6, 0xf0, 0xbc, 0x5a, 0xfd, 0x9d, 0x3b, 0xb2, 0xae, 0x74, + 0xaa, 0x80, 0x0e, 0xc6, 0xb0, 0x7c, 0xe9, 0xa5, 0xb8, 0xe8, 0xd2, 0x83, 0x4a, 0x79, 0x27, 0x11, 0xe8, 0x93, 0xc8, + 0x22, 0x1a, 0x9d, 0x67, 0x52, 0x45, 0x48, 0x10, 0x36, 0x5f, 0x17, 0x07, 0xf8, 0x2b, 0xf8, 0x6e, 0xae, 0x2d, 0x8b, + 0xb4, 0xa7, 0x92, 0xf5, 0xd2, 0x2c, 0x49, 0xb9, 0xe3, 0x84, 0x38, 0x42, 0xa4, 0x17, 0x0a, 0xaa, 0xed, 0x46, 0xe2, + 0xbf, 0x7e, 0xbd, 0xe5, 0xb5, 0x0a, 0x4f, 0x48, 0xe5, 0x5c, 0xb5, 0xcc, 0x33, 0x53, 0x67, 0x73, 0x01, 0x5c, 0x5c, + 0xfc, 0x96, 0xf3, 0x29, 0x9f, 0x8b, 0x69, 0x61, 0xc5, 0xb9, 0xa4, 0xd4, 0x77, 0x2a, 0x40, 0x88, 0xb8, 0xdb, 0x8e, + 0xa1, 0x50, 0x5e, 0xce, 0xbb, 0xd8, 0xc5, 0x57, 0x52, 0xdb, 0xb9, 0x34, 0xc8, 0xf8, 0x8a, 0x69, 0x7f, 0x5d, 0x95, + 0xc0, 0x72, 0x85, 0x11, 0x83, 0x05, 0x6c, 0xab, 0x26, 0x61, 0xb9, 0x23, 0xf1, 0x56, 0x2a, 0x75, 0xe5, 0x23, 0x95, + 0xba, 0xd6, 0xf6, 0x2a, 0x22, 0xeb, 0x71, 0x1b, 0x60, 0xe0, 0x01, 0xc8, 0xb8, 0x9e, 0x02, 0x30, 0x93, 0x31, 0x15, + 0x17, 0xd3, 0x48, 0xd6, 0x82, 0x97, 0x52, 0x8d, 0xf7, 0xec, 0x37, 0xaf, 0x2f, 0xde, 0xd9, 0x18, 0xee, 0x33, 0xa3, + 0x69, 0xe6, 0x2d, 0x6d, 0x95, 0x4c, 0x58, 0x87, 0xc0, 0xb4, 0xed, 0xd9, 0xfe, 0x0c, 0xce, 0x66, 0x0b, 0xee, 0xd9, + 0xb8, 0xad, 0xdf, 0xdc, 0xdc, 0xd4, 0xe1, 0xe8, 0x58, 0x7d, 0x9e, 0x46, 0x92, 0xaf, 0x04, 0x76, 0x9e, 0x23, 0x97, + 0x87, 0x34, 0x2e, 0x6e, 0x3c, 0x4a, 0x22, 0xea, 0x46, 0xc9, 0x44, 0x1e, 0x7b, 0x5d, 0xf7, 0x43, 0x8c, 0xae, 0xba, + 0xe2, 0x26, 0xaf, 0x5e, 0x97, 0xcb, 0x3b, 0xd4, 0x78, 0x0a, 0x3f, 0x7b, 0x10, 0xa5, 0xea, 0x36, 0x78, 0x28, 0x1e, + 0x2e, 0x60, 0xdb, 0x88, 0xa7, 0xfd, 0xe5, 0x06, 0x91, 0xf5, 0xa1, 0x8b, 0xb0, 0x27, 0xa7, 0x96, 0x89, 0x5a, 0x57, + 0xde, 0xe8, 0xea, 0x2a, 0xef, 0x36, 0xa0, 0xaf, 0x86, 0xee, 0xf7, 0x3a, 0x09, 0xee, 0x74, 0xfb, 0x82, 0xf0, 0xe0, + 0x46, 0xa7, 0x98, 0xf4, 0xa0, 0x0b, 0x18, 0x37, 0xe8, 0x09, 0x9c, 0x29, 0x5e, 0x39, 0x28, 0x1f, 0xf2, 0xa1, 0x05, + 0x9c, 0x31, 0x87, 0x12, 0xa0, 0x4b, 0xe8, 0x3c, 0x28, 0x1a, 0x88, 0x6d, 0x2d, 0x8b, 0x76, 0x01, 0x28, 0x2b, 0x96, + 0xdb, 0x45, 0xfa, 0xb3, 0x4b, 0xb2, 0xd0, 0x10, 0x07, 0x26, 0xf0, 0x57, 0x08, 0xfe, 0x17, 0x80, 0x77, 0x1b, 0x12, + 0x4d, 0x57, 0xe6, 0xed, 0x32, 0xf2, 0xde, 0x87, 0x02, 0x99, 0x83, 0x98, 0xe3, 0x37, 0x1c, 0xbf, 0xbe, 0x12, 0x55, + 0xb5, 0x3a, 0x00, 0x7a, 0x2a, 0xa8, 0x4d, 0x4d, 0xad, 0xf7, 0x8d, 0x92, 0x28, 0xf2, 0x67, 0x19, 0xf5, 0xf4, 0x0f, + 0xa5, 0x19, 0x80, 0x82, 0xb1, 0xa9, 0x8a, 0xa9, 0x04, 0xa7, 0x73, 0x50, 0xd8, 0x36, 0xf5, 0xc4, 0x85, 0x9f, 0x3a, + 0xf5, 0xfa, 0xa8, 0x7e, 0x3d, 0x41, 0x39, 0x0f, 0x97, 0xa6, 0x5e, 0x71, 0xd2, 0x6c, 0x76, 0x20, 0x1b, 0xb5, 0xee, + 0x47, 0x6c, 0x12, 0x7b, 0x11, 0x1d, 0xf3, 0x9c, 0xc3, 0x31, 0xc1, 0xa5, 0x56, 0xe4, 0xdc, 0xf6, 0x71, 0x4a, 0xa7, + 0x96, 0x0b, 0xff, 0xde, 0x3f, 0x70, 0xce, 0x03, 0x2f, 0xe6, 0x61, 0x5d, 0x64, 0x3d, 0xc3, 0x99, 0x0d, 0x1e, 0x56, + 0x9e, 0x97, 0xc6, 0x40, 0x23, 0x0a, 0x4a, 0x6e, 0xce, 0x53, 0x8b, 0x87, 0x98, 0xa7, 0x66, 0xbd, 0x18, 0x2d, 0x37, + 0x66, 0xb0, 0xa9, 0x6b, 0x1d, 0xa2, 0x3c, 0x13, 0xa6, 0xc9, 0x66, 0x65, 0xad, 0xb0, 0x56, 0x9f, 0x36, 0xd0, 0x67, + 0xa8, 0xd6, 0xb9, 0x74, 0xed, 0x2f, 0x65, 0x8b, 0x87, 0x20, 0xb3, 0xa2, 0xf4, 0x63, 0xb3, 0x05, 0xca, 0x59, 0x3c, + 0x9b, 0xf3, 0x81, 0x08, 0x2b, 0xa4, 0x70, 0x40, 0x65, 0x88, 0x8d, 0x12, 0xc0, 0xc1, 0x70, 0x29, 0x81, 0x19, 0xf9, + 0xd1, 0xc8, 0x01, 0x88, 0xac, 0xba, 0x75, 0x9a, 0xd2, 0x29, 0xea, 0x4c, 0x59, 0x5c, 0x97, 0xef, 0x8e, 0x0d, 0xc5, + 0xd0, 0x7d, 0x04, 0x4f, 0xb9, 0x2b, 0x7a, 0xc3, 0x22, 0x7b, 0x78, 0x0b, 0x2e, 0xaf, 0x86, 0x79, 0xde, 0x49, 0xb9, + 0x33, 0x78, 0xe9, 0xa0, 0x21, 0xfe, 0xc6, 0xb8, 0x1f, 0xc7, 0xd6, 0x3b, 0xc9, 0xc6, 0x6d, 0xb4, 0xa3, 0x8a, 0xb9, + 0x17, 0x44, 0xb5, 0x6f, 0x08, 0x54, 0x7c, 0xe2, 0xd8, 0x34, 0x9b, 0xd5, 0x25, 0xcb, 0xab, 0x0b, 0x92, 0xb5, 0xa1, + 0x29, 0x52, 0xbe, 0x72, 0x4a, 0x97, 0x82, 0x9b, 0xa9, 0x43, 0x32, 0xd2, 0x9d, 0x33, 0x2c, 0x0e, 0x55, 0xa9, 0x67, + 0xf3, 0x18, 0x15, 0xaa, 0xb0, 0x9b, 0xab, 0xb3, 0x2a, 0x6b, 0x04, 0xe5, 0xa2, 0xb8, 0x44, 0xd0, 0x8f, 0x22, 0x18, + 0xf0, 0x4a, 0x6b, 0x24, 0xe6, 0xad, 0x2b, 0x03, 0x3e, 0x74, 0x50, 0xae, 0xf6, 0xe9, 0x13, 0xa1, 0xd4, 0x1b, 0x37, + 0x17, 0xee, 0x71, 0x1d, 0xae, 0x93, 0x22, 0x9a, 0x41, 0xc2, 0x41, 0x25, 0x31, 0xbd, 0x53, 0xb2, 0x36, 0x69, 0x12, + 0x58, 0x62, 0x42, 0xc4, 0x4e, 0xe3, 0xc0, 0xb6, 0xbe, 0x1c, 0x45, 0x6c, 0xf4, 0x91, 0xd8, 0xfb, 0x4b, 0x07, 0x6d, + 0x9e, 0x3b, 0x15, 0x5c, 0x41, 0xf3, 0x79, 0x54, 0x0d, 0x65, 0xa4, 0xae, 0xc1, 0xc2, 0xe5, 0xc5, 0x44, 0x76, 0x0f, + 0xf4, 0xa6, 0x6e, 0x43, 0x8e, 0xd3, 0xbb, 0xca, 0x2f, 0xcb, 0xfb, 0xc6, 0x4a, 0x28, 0x00, 0xcd, 0xb2, 0xdc, 0x12, + 0x44, 0x45, 0xec, 0x4f, 0x52, 0x9a, 0x6d, 0x49, 0xa6, 0x06, 0x70, 0x72, 0xc5, 0xdf, 0x6c, 0xeb, 0xcb, 0xa2, 0x8c, + 0x16, 0x3e, 0x25, 0x91, 0x14, 0x43, 0x6c, 0x18, 0x0b, 0x1c, 0x09, 0x6e, 0x40, 0xb9, 0xcf, 0x22, 0xd9, 0xa4, 0xa3, + 0x5d, 0x20, 0x6b, 0x33, 0x5a, 0xad, 0xb2, 0xea, 0x5c, 0x58, 0x15, 0x83, 0x62, 0x66, 0xdd, 0x46, 0x09, 0xb7, 0x98, + 0x99, 0xd8, 0x93, 0x66, 0x70, 0xb6, 0x9c, 0xa1, 0x7c, 0x67, 0x7d, 0x39, 0x12, 0xc7, 0xb6, 0x00, 0xc0, 0x44, 0x01, + 0x08, 0x69, 0x03, 0xf2, 0x58, 0x92, 0x13, 0x91, 0xc4, 0xe5, 0x7e, 0x3a, 0xa1, 0x7c, 0x0d, 0xb1, 0x91, 0xcc, 0x12, + 0xee, 0xe8, 0x14, 0x81, 0x0d, 0x68, 0xfd, 0x2a, 0xb4, 0xa0, 0x44, 0xe7, 0x7d, 0xd0, 0x83, 0xc9, 0x56, 0x75, 0x3a, + 0x44, 0x20, 0x6f, 0xc5, 0xe2, 0x48, 0x09, 0x93, 0x08, 0x09, 0x23, 0x39, 0x81, 0x25, 0xc6, 0x12, 0x20, 0xe6, 0xb6, + 0xd5, 0x97, 0x90, 0xd3, 0x40, 0xc2, 0x4c, 0x52, 0xd1, 0x2a, 0xc9, 0xbb, 0x0d, 0x59, 0x5b, 0x8a, 0x00, 0x59, 0x09, + 0x90, 0x20, 0xf6, 0x69, 0x89, 0x03, 0xc8, 0x2c, 0x37, 0xf1, 0x10, 0xb0, 0x45, 0x41, 0x6c, 0xe2, 0x00, 0x5b, 0xaf, + 0x1b, 0xf9, 0xd7, 0x34, 0xea, 0xed, 0x2f, 0xd3, 0xd5, 0xaa, 0x99, 0x77, 0x1b, 0xf2, 0xd1, 0xea, 0x0a, 0xbe, 0x21, + 0x2f, 0x1d, 0x15, 0x4b, 0x0c, 0xa7, 0x42, 0x21, 0xdf, 0x56, 0x27, 0x9a, 0x79, 0xaa, 0x83, 0xdc, 0xb6, 0x44, 0x8a, + 0x8b, 0xa8, 0x54, 0xe8, 0x51, 0xb9, 0x6d, 0xb1, 0x60, 0xb3, 0x2c, 0xe3, 0x74, 0x06, 0xa5, 0xe1, 0x6a, 0xd5, 0xca, + 0x6d, 0x6b, 0xca, 0x62, 0x78, 0x4a, 0x57, 0x2b, 0x71, 0xe0, 0x72, 0xca, 0x62, 0xa7, 0x09, 0x64, 0x6b, 0x5b, 0x53, + 0xff, 0x56, 0x4c, 0x58, 0xbf, 0xf1, 0x6f, 0x9d, 0x96, 0x7a, 0xe5, 0x16, 0xf8, 0xc9, 0x80, 0xe2, 0xca, 0x15, 0x8d, + 0xd4, 0x8a, 0x06, 0x78, 0x2e, 0x8f, 0x92, 0x11, 0x27, 0x20, 0xd1, 0xf6, 0x15, 0x0d, 0xf4, 0x8a, 0xce, 0x77, 0xac, + 0xe8, 0xfc, 0x9e, 0x15, 0xf5, 0xd5, 0xea, 0x59, 0x05, 0xee, 0x92, 0xd5, 0xaa, 0xd5, 0x2c, 0xb1, 0xd7, 0x6d, 0x04, + 0x6c, 0x01, 0xab, 0x01, 0xda, 0x21, 0x67, 0x53, 0xba, 0x9d, 0x28, 0xab, 0x28, 0xa6, 0xbf, 0x09, 0x93, 0x25, 0x16, + 0xd2, 0x2a, 0x16, 0x4c, 0xba, 0x2e, 0xa2, 0x9e, 0x7f, 0x26, 0x65, 0x33, 0xc0, 0x43, 0x06, 0x78, 0x08, 0xf5, 0x25, + 0xa4, 0x8e, 0xfd, 0xce, 0xc6, 0xb6, 0x65, 0x6b, 0xb2, 0xbe, 0xca, 0x2f, 0x41, 0x46, 0x88, 0xf9, 0x3d, 0x88, 0x16, + 0xa1, 0xb6, 0xdd, 0xdb, 0x4d, 0x73, 0x90, 0xa0, 0x70, 0x93, 0xa4, 0x81, 0xed, 0xc9, 0xaa, 0xbf, 0x09, 0x55, 0x53, + 0x16, 0xab, 0x74, 0xb7, 0x9d, 0xb4, 0x56, 0xbe, 0x37, 0x29, 0xae, 0x7d, 0x7c, 0x2c, 0x6b, 0xcc, 0x7c, 0xce, 0x69, + 0x1a, 0x2b, 0xca, 0xb5, 0xed, 0xff, 0x2f, 0xa8, 0x70, 0x0b, 0x5f, 0xf1, 0xf5, 0x02, 0x68, 0x02, 0x54, 0x7a, 0xbe, + 0xe2, 0xf9, 0x52, 0x3c, 0xed, 0x95, 0x0a, 0xee, 0x1d, 0x32, 0x6d, 0x0d, 0x59, 0x04, 0xa6, 0xcf, 0x7c, 0x4a, 0x83, + 0x4b, 0xc1, 0xa0, 0xfb, 0xa3, 0x2b, 0xa5, 0xb0, 0xae, 0x89, 0xbb, 0xb2, 0x01, 0xb6, 0x7f, 0x9e, 0xb7, 0x1f, 0x1d, + 0x9d, 0xdb, 0x58, 0xf2, 0xf8, 0x64, 0x3c, 0xb6, 0x51, 0x6e, 0x3d, 0xac, 0x59, 0xeb, 0xe8, 0xe7, 0xf9, 0x57, 0xcf, + 0x9a, 0x5f, 0x15, 0x8d, 0x63, 0x20, 0x22, 0x95, 0x61, 0xa1, 0x45, 0x95, 0x01, 0xaf, 0x9e, 0xd1, 0xd8, 0x8f, 0x77, + 0x4f, 0x67, 0x60, 0x4e, 0x27, 0x9b, 0x51, 0x1a, 0x00, 0x71, 0xe2, 0x8d, 0xd2, 0xcb, 0x88, 0x2e, 0xa8, 0xbe, 0xfc, + 0x71, 0xcb, 0x60, 0x5b, 0x5a, 0x8c, 0x92, 0x79, 0xcc, 0x55, 0xaa, 0x89, 0x62, 0xb5, 0xc6, 0x94, 0xae, 0xc4, 0x1c, + 0x4c, 0x13, 0xe2, 0x4e, 0xca, 0xb9, 0xaa, 0xf4, 0xca, 0xaf, 0xb0, 0x6d, 0x00, 0xb0, 0x13, 0xb2, 0xfe, 0x8e, 0x72, + 0xaf, 0x89, 0x9b, 0xbb, 0x60, 0xc3, 0x2d, 0xe4, 0xd9, 0xf6, 0x50, 0xe3, 0x49, 0x78, 0x8b, 0x2b, 0x37, 0x76, 0xec, + 0xc4, 0xd7, 0x27, 0x31, 0x70, 0x9d, 0x42, 0x67, 0x31, 0xcd, 0xb2, 0x9d, 0x08, 0x28, 0x16, 0x11, 0xdb, 0x65, 0x6d, + 0x7b, 0x47, 0x2f, 0xb8, 0x89, 0x61, 0x87, 0x09, 0x80, 0x8b, 0x98, 0xb5, 0xaa, 0x45, 0xc7, 0x63, 0x3a, 0x2a, 0x9c, + 0xed, 0x10, 0x7d, 0x1c, 0xb3, 0x88, 0x43, 0x10, 0x4e, 0x44, 0xc7, 0xec, 0x57, 0x49, 0x4c, 0x6d, 0xa4, 0xf3, 0x69, + 0x15, 0xfc, 0x4a, 0xfe, 0x6f, 0x87, 0x47, 0xf6, 0x58, 0x85, 0x45, 0x8d, 0xb2, 0x5a, 0x69, 0x5f, 0x50, 0xa5, 0xbc, + 0x8a, 0xc8, 0x44, 0x38, 0x7b, 0x76, 0x6d, 0xa0, 0x87, 0x6d, 0x93, 0x65, 0xeb, 0xab, 0xe3, 0x56, 0x33, 0xb7, 0xb1, + 0x0d, 0xdd, 0x3d, 0x74, 0x97, 0x88, 0x56, 0x87, 0xd0, 0x6a, 0x1e, 0xff, 0x96, 0x76, 0xed, 0xd6, 0xe3, 0x96, 0x8d, + 0xe5, 0x45, 0x0e, 0x28, 0x2f, 0x98, 0xc1, 0x08, 0xdc, 0xcf, 0x7f, 0x78, 0x2a, 0xd5, 0xce, 0x1f, 0x06, 0xcf, 0x49, + 0xab, 0x69, 0x63, 0x3b, 0xe3, 0xc9, 0xec, 0x37, 0x4c, 0xe1, 0xd0, 0xc6, 0xf6, 0x28, 0x4a, 0x32, 0x6a, 0xce, 0x41, + 0xaa, 0xb3, 0x7f, 0x7c, 0x12, 0x12, 0xa2, 0x59, 0x4a, 0xb3, 0xcc, 0x32, 0xfb, 0x57, 0xa4, 0xf4, 0x09, 0x86, 0xb9, + 0x95, 0xe2, 0x32, 0xca, 0x05, 0x5e, 0xe4, 0x1d, 0x0b, 0x26, 0x55, 0xc9, 0xb2, 0x0d, 0x62, 0x13, 0x22, 0xa0, 0x60, + 0x6c, 0x52, 0xbb, 0xfa, 0xe4, 0xc8, 0x5b, 0xb6, 0x9e, 0x1c, 0x58, 0x46, 0xe5, 0x37, 0x07, 0xa8, 0x94, 0x4c, 0x59, + 0x7c, 0xb9, 0xa5, 0xd4, 0xbf, 0xdd, 0x52, 0x0a, 0x2a, 0x5b, 0x01, 0x9d, 0xba, 0xff, 0xe7, 0xd3, 0x58, 0x2f, 0x15, + 0x1f, 0x13, 0xc4, 0x40, 0x38, 0x37, 0x3f, 0x01, 0xa9, 0xb1, 0x0c, 0xa2, 0x87, 0xdf, 0x3f, 0x1c, 0x94, 0xfc, 0x96, + 0xe1, 0x8a, 0x5e, 0xfe, 0xd8, 0x0c, 0xa1, 0xb4, 0x0e, 0x11, 0x84, 0xe8, 0x37, 0xcd, 0x95, 0xde, 0x7e, 0x9a, 0xe0, + 0x0c, 0xad, 0xea, 0x0f, 0x2c, 0xbd, 0xba, 0x47, 0x60, 0x7d, 0xed, 0xb7, 0x14, 0x2b, 0xc5, 0xa7, 0x58, 0xff, 0x51, + 0xc4, 0xa6, 0x25, 0x09, 0x6c, 0x82, 0x29, 0x34, 0x1e, 0x48, 0x27, 0x33, 0x3b, 0x91, 0xaa, 0xcf, 0x25, 0x1c, 0x92, + 0x85, 0x7b, 0x48, 0xe6, 0x29, 0xbd, 0x8c, 0x92, 0x9b, 0xf5, 0x8b, 0xd5, 0x76, 0x57, 0x0e, 0xd9, 0x24, 0x34, 0x4e, + 0xbe, 0x51, 0x52, 0x2c, 0xc2, 0xbd, 0x03, 0xe4, 0xff, 0xf2, 0xcf, 0xae, 0xfb, 0x2f, 0xff, 0xfc, 0xc9, 0xaa, 0xd0, + 0x7d, 0x7e, 0x85, 0x79, 0xd9, 0xed, 0xee, 0xdd, 0xb5, 0x7d, 0xa4, 0x2a, 0xce, 0xb7, 0xd7, 0xd9, 0x58, 0x04, 0x78, + 0xbf, 0xb1, 0x04, 0x1b, 0x85, 0x72, 0xf7, 0x59, 0xbf, 0x07, 0x30, 0x98, 0xd7, 0x27, 0x21, 0x83, 0x4a, 0x7f, 0x08, + 0xb4, 0x2b, 0xe4, 0x3d, 0x68, 0x45, 0x7e, 0x3f, 0x86, 0x3f, 0x35, 0x87, 0x3f, 0x08, 0xbe, 0xf2, 0x4f, 0x8c, 0xae, + 0xae, 0x8a, 0x14, 0x47, 0xb3, 0x29, 0x5c, 0xa0, 0xd0, 0xdf, 0x28, 0x51, 0x8a, 0x87, 0xd7, 0x44, 0x3d, 0x71, 0x40, + 0x93, 0x8c, 0xae, 0x5e, 0xc2, 0xad, 0x49, 0xdd, 0xeb, 0x54, 0x3b, 0x78, 0xef, 0x11, 0x0e, 0xd0, 0x45, 0x75, 0x56, + 0xa2, 0xd3, 0x0d, 0xc9, 0x00, 0xa5, 0x60, 0x6e, 0x00, 0x98, 0x78, 0x74, 0xa5, 0xac, 0xcd, 0x73, 0xe9, 0x86, 0xf1, + 0xd6, 0x49, 0x5b, 0xb9, 0x67, 0x2a, 0x48, 0xc7, 0xd6, 0x3b, 0x81, 0x2f, 0x51, 0x99, 0x96, 0xd6, 0xbd, 0x70, 0x75, + 0x81, 0x1d, 0x51, 0xb0, 0x9f, 0x85, 0x1f, 0x2d, 0x1e, 0xc6, 0xf8, 0x76, 0x0b, 0xd4, 0x95, 0xb5, 0xfa, 0xb7, 0x56, + 0x09, 0x56, 0xf5, 0x55, 0x45, 0x1f, 0x10, 0x69, 0x1e, 0x8c, 0xee, 0x88, 0x44, 0x67, 0xf4, 0x93, 0x91, 0xe8, 0xe8, + 0x41, 0x91, 0xe8, 0x8c, 0xfe, 0xd9, 0x91, 0x68, 0x46, 0x8d, 0x48, 0x34, 0x90, 0xe0, 0x2f, 0x0f, 0x0a, 0x68, 0xea, + 0xf0, 0x53, 0x72, 0x93, 0x91, 0x96, 0x32, 0x02, 0xa2, 0x64, 0x02, 0xd1, 0xcc, 0x7f, 0xfb, 0xe0, 0x64, 0x94, 0x4c, + 0xcc, 0xd0, 0x24, 0x5c, 0xfa, 0x0b, 0xb1, 0x48, 0x9c, 0x92, 0xa5, 0xfd, 0xf3, 0x6d, 0xeb, 0xc9, 0xa0, 0xd5, 0x39, + 0x6c, 0x4d, 0x6d, 0xcf, 0x06, 0xa9, 0x2b, 0x0a, 0x9a, 0x9d, 0xc3, 0x43, 0x28, 0xb8, 0x31, 0x0a, 0xda, 0x50, 0xc0, + 0x8c, 0x82, 0x63, 0x28, 0x18, 0x19, 0x05, 0x27, 0x50, 0x10, 0x18, 0x05, 0x8f, 0xa0, 0x60, 0x61, 0xe7, 0x03, 0x56, + 0x84, 0xdb, 0x1f, 0x21, 0x71, 0x3f, 0xc8, 0x5e, 0x5a, 0x3d, 0x1b, 0x11, 0x12, 0x5d, 0xe5, 0x51, 0x71, 0xae, 0xaa, + 0x7e, 0xa4, 0xaf, 0x01, 0xb9, 0xfa, 0xec, 0x0a, 0xe1, 0x88, 0xc0, 0x31, 0x47, 0x0c, 0x46, 0xb9, 0xac, 0x79, 0xa8, + 0x5f, 0xdb, 0x5e, 0x11, 0x93, 0x6e, 0xe2, 0xb6, 0x8e, 0x4a, 0x7b, 0x36, 0xc2, 0xf3, 0xa2, 0xf2, 0x71, 0x2d, 0x50, + 0xdd, 0xc2, 0x0d, 0x1b, 0xe5, 0xf5, 0x36, 0x87, 0x08, 0xcb, 0x1b, 0xc5, 0x9f, 0x0a, 0xf9, 0xe8, 0xf2, 0xe4, 0x1d, + 0x9b, 0x52, 0xfd, 0xbd, 0x15, 0x3d, 0x80, 0x25, 0xe2, 0xf6, 0x9d, 0xb0, 0xbc, 0x13, 0xee, 0x2b, 0x7c, 0x56, 0xde, + 0xa8, 0xf4, 0x8e, 0x13, 0x79, 0x45, 0x45, 0x8a, 0xa5, 0xa1, 0x37, 0xc1, 0xdc, 0x9f, 0x78, 0x10, 0xb8, 0x04, 0x9f, + 0xa9, 0x77, 0x46, 0x08, 0x69, 0xf6, 0xe7, 0xde, 0x57, 0xf8, 0x26, 0xa4, 0xb1, 0xb7, 0xc8, 0x3b, 0x05, 0x01, 0xc8, + 0xb8, 0xe9, 0x3b, 0x5e, 0x5c, 0xc4, 0x27, 0xa8, 0xa2, 0x7c, 0x2d, 0xe1, 0xac, 0x17, 0xd4, 0xb3, 0x23, 0xd4, 0x66, + 0xf8, 0x64, 0xc6, 0x51, 0x72, 0x53, 0xbf, 0xb5, 0x7b, 0xdb, 0xc3, 0x6f, 0x30, 0xbb, 0x22, 0xfc, 0xf6, 0x02, 0x80, + 0x2d, 0x9e, 0xde, 0xf9, 0x93, 0xe2, 0xf7, 0x4b, 0x9a, 0x65, 0xfe, 0x44, 0xd5, 0xdc, 0x1d, 0x6e, 0x13, 0x20, 0x9a, + 0xa1, 0x36, 0x0d, 0x04, 0xc4, 0xc4, 0x00, 0x23, 0xe0, 0xd3, 0x50, 0x21, 0x32, 0x98, 0x7a, 0x35, 0xba, 0x26, 0x70, + 0x55, 0x2d, 0xe2, 0xfe, 0xa4, 0x2c, 0xe8, 0xce, 0x52, 0xaa, 0xe2, 0x76, 0x80, 0xc6, 0xbc, 0xdb, 0x80, 0x02, 0xf9, + 0x7a, 0x47, 0x14, 0x4d, 0x3b, 0x50, 0x76, 0xc7, 0xd2, 0x2c, 0x1d, 0x45, 0x33, 0x33, 0xbf, 0x8a, 0xb4, 0xaf, 0xcd, + 0xd8, 0xcd, 0xe7, 0xad, 0x11, 0xfc, 0x51, 0x91, 0xa1, 0xcf, 0xc7, 0xe3, 0xf1, 0xbd, 0x51, 0xb5, 0xcf, 0x83, 0x31, + 0x6d, 0xd3, 0xe3, 0x0e, 0x64, 0x05, 0xd5, 0x55, 0x2c, 0xa6, 0x95, 0x0b, 0xdc, 0x2d, 0x1f, 0x56, 0x19, 0xc2, 0x36, + 0x3c, 0x5c, 0x3e, 0x3c, 0xc2, 0x96, 0xcf, 0x52, 0xba, 0x9c, 0xfa, 0xe9, 0x84, 0xc5, 0x5e, 0x33, 0x77, 0x17, 0x2a, + 0x24, 0xf5, 0xf9, 0xe9, 0xe9, 0x69, 0xee, 0x06, 0xfa, 0xa9, 0x19, 0x04, 0xb9, 0x3b, 0x5a, 0x16, 0xd3, 0x68, 0x36, + 0xc7, 0xe3, 0xdc, 0x65, 0xba, 0xe0, 0xb0, 0x3d, 0x0a, 0x0e, 0xdb, 0xb9, 0x7b, 0x63, 0xd4, 0xc8, 0x5d, 0xaa, 0x9e, + 0x52, 0x1a, 0x54, 0x52, 0x8b, 0x1e, 0x35, 0x9b, 0xb9, 0x2b, 0x09, 0x6d, 0x09, 0x66, 0xa9, 0xfc, 0xe9, 0xf9, 0x73, + 0x9e, 0x00, 0x73, 0xef, 0x44, 0xdc, 0x19, 0x5c, 0xaa, 0x6b, 0x5b, 0xe4, 0x47, 0x4e, 0x72, 0x34, 0xc4, 0xbf, 0x98, + 0xc1, 0x23, 0x20, 0x66, 0x11, 0x34, 0x8a, 0x74, 0x6c, 0xa9, 0xf2, 0x1a, 0x28, 0x4b, 0xbc, 0xfe, 0x85, 0x44, 0x65, + 0x4c, 0x09, 0x38, 0x19, 0xd4, 0x94, 0xb7, 0x0b, 0xc6, 0xbb, 0xe4, 0x47, 0xfa, 0x69, 0xf9, 0x71, 0xf7, 0x10, 0xf1, + 0x91, 0xfe, 0xe9, 0xe2, 0x23, 0x36, 0xc5, 0x87, 0x64, 0x1e, 0xd7, 0x9c, 0xd8, 0xa3, 0x90, 0x8e, 0x3e, 0x5e, 0x27, + 0xb7, 0x75, 0xd8, 0x12, 0xa9, 0x2d, 0x04, 0xcb, 0xfe, 0xef, 0xcd, 0x94, 0xd1, 0x9d, 0x19, 0x9f, 0x48, 0x11, 0xea, + 0xc3, 0xeb, 0x98, 0xd8, 0xaf, 0xb5, 0x6d, 0x2b, 0x4b, 0xc6, 0x63, 0x62, 0xbf, 0x1e, 0x8f, 0x6d, 0x7d, 0xf8, 0xd4, + 0xe7, 0x54, 0xd4, 0x7a, 0x55, 0x29, 0x11, 0xb5, 0xbe, 0xfa, 0xca, 0x2c, 0x33, 0x0b, 0x54, 0xe8, 0xc9, 0x0c, 0x33, + 0xa9, 0x37, 0x01, 0xcb, 0x60, 0xab, 0xc1, 0x97, 0x5b, 0xaa, 0x97, 0x5f, 0xc6, 0x95, 0x7b, 0xca, 0x0b, 0x80, 0xb7, + 0x5c, 0xae, 0xbe, 0x7e, 0xf3, 0xc2, 0x84, 0xea, 0x44, 0xd0, 0x27, 0x77, 0xdf, 0x04, 0xce, 0x35, 0x47, 0x39, 0xcb, + 0x5e, 0xc7, 0x6b, 0xa7, 0xaa, 0x24, 0x8c, 0x84, 0x98, 0xd3, 0xca, 0x79, 0x32, 0x99, 0x44, 0xf0, 0xf1, 0x9c, 0x65, + 0xe5, 0x42, 0x5e, 0xd9, 0xbc, 0x5f, 0x99, 0xaf, 0x67, 0x36, 0x54, 0xd7, 0xd7, 0x8a, 0x6f, 0x79, 0xc9, 0x6c, 0xfc, + 0x85, 0xfa, 0xa8, 0x93, 0x30, 0x8b, 0x97, 0x8a, 0xc9, 0x2f, 0x65, 0x0e, 0x37, 0xc7, 0x2c, 0x90, 0xcd, 0x59, 0x90, + 0xe7, 0xea, 0xf4, 0x4b, 0xc0, 0xb2, 0x19, 0x5c, 0x14, 0x2b, 0x5b, 0xd2, 0x4f, 0xb1, 0xf0, 0xec, 0xc6, 0x88, 0xef, + 0x54, 0x96, 0x2b, 0xd7, 0x01, 0x1e, 0xe9, 0x30, 0xbf, 0xe6, 0xb9, 0xad, 0xfc, 0xee, 0x1a, 0x89, 0xb6, 0x25, 0xf1, + 0x29, 0x23, 0x4f, 0xc6, 0x0c, 0xc1, 0xf9, 0x5d, 0x2c, 0x88, 0x7e, 0xa5, 0x0b, 0x72, 0x33, 0x7e, 0x29, 0xde, 0x48, + 0x6c, 0x89, 0x68, 0x49, 0x36, 0xf3, 0x63, 0xc9, 0x46, 0x89, 0x2d, 0xf9, 0xc1, 0xfe, 0xb2, 0x5c, 0xf9, 0xdc, 0xd6, + 0x60, 0x4b, 0xe2, 0xed, 0x75, 0x1b, 0xd0, 0xa0, 0x67, 0x55, 0x40, 0x8f, 0x37, 0x82, 0x2c, 0xf7, 0xa7, 0x3b, 0xbc, + 0xbe, 0x72, 0xb3, 0x1b, 0xec, 0x66, 0x37, 0xd6, 0x5f, 0x97, 0xf5, 0x1b, 0x7a, 0xfd, 0x91, 0xf1, 0x3a, 0xf7, 0x67, + 0x75, 0x30, 0x7c, 0x84, 0x73, 0x54, 0xb1, 0x67, 0x91, 0x36, 0x29, 0xef, 0x8e, 0xe8, 0xcc, 0x33, 0xc8, 0x8a, 0x10, + 0xea, 0xbb, 0x17, 0x27, 0x31, 0xed, 0x54, 0xd3, 0x63, 0xcd, 0x20, 0xbb, 0xc6, 0xd6, 0x70, 0x99, 0x40, 0x16, 0x05, + 0xbf, 0xf3, 0x9a, 0x8a, 0xad, 0x37, 0x75, 0x04, 0xbd, 0xb9, 0xb5, 0xbe, 0xa7, 0x90, 0x5b, 0x13, 0xd2, 0x2b, 0xdd, + 0xcc, 0x24, 0xd8, 0x95, 0x09, 0xf0, 0xa9, 0x64, 0x51, 0x70, 0xa9, 0xea, 0xbf, 0x46, 0x96, 0xed, 0x7a, 0xb1, 0x48, + 0x16, 0x7d, 0x08, 0x64, 0x9e, 0x3f, 0xe6, 0x34, 0xc5, 0x0f, 0xa9, 0x79, 0x2d, 0xce, 0x75, 0x2d, 0x41, 0xcc, 0x78, + 0xad, 0xd3, 0xd9, 0xed, 0xc3, 0xbb, 0xbf, 0x7f, 0xfa, 0xb9, 0xc2, 0x91, 0xbe, 0xe7, 0xc8, 0xb6, 0x3b, 0xb0, 0x11, + 0x22, 0xff, 0xce, 0x63, 0xb1, 0x90, 0x79, 0xd7, 0xe0, 0x17, 0xed, 0xcc, 0x12, 0x95, 0xf5, 0x9c, 0xd2, 0x48, 0x7c, + 0xd6, 0x50, 0x2d, 0xc5, 0xe1, 0xc9, 0xec, 0x56, 0xaf, 0x46, 0x6b, 0x2d, 0x9b, 0xf9, 0x4f, 0x4d, 0x5a, 0xde, 0x9d, + 0x25, 0x5d, 0x4d, 0xbc, 0x3d, 0x9e, 0xdd, 0x76, 0xa4, 0xa0, 0xad, 0xa7, 0x12, 0xaa, 0xe6, 0xec, 0xd6, 0x4c, 0xdb, + 0x2e, 0x3b, 0xb2, 0xdc, 0xc3, 0xcc, 0xa2, 0x7e, 0x46, 0x3b, 0x70, 0x91, 0x3b, 0x1b, 0xf9, 0x91, 0x12, 0xe6, 0x53, + 0x16, 0x04, 0x11, 0xed, 0x68, 0x79, 0x6d, 0xb5, 0x4e, 0x20, 0xeb, 0xd9, 0x5c, 0xb2, 0xea, 0xaa, 0x18, 0xc8, 0x2b, + 0xf0, 0xe4, 0x5f, 0x67, 0x49, 0x04, 0x5f, 0x51, 0xd9, 0x8a, 0x4e, 0x95, 0x0e, 0xdc, 0x2c, 0x91, 0x27, 0x7e, 0x57, + 0xe7, 0x72, 0xdc, 0xfc, 0x4b, 0x47, 0x2c, 0x78, 0xb3, 0xc3, 0x93, 0x99, 0x57, 0x3f, 0xac, 0x4e, 0x04, 0x5e, 0x15, + 0x53, 0xc0, 0x5b, 0xa6, 0x85, 0x41, 0x5a, 0x49, 0x3e, 0x6d, 0xb9, 0x2d, 0x55, 0x26, 0x3a, 0x80, 0xb4, 0xb1, 0xa2, + 0x28, 0xaf, 0x4e, 0xe6, 0xdf, 0x66, 0xb7, 0x3c, 0xde, 0xbe, 0x5b, 0x1e, 0xeb, 0xdd, 0x72, 0x3f, 0xc5, 0x7e, 0x3e, + 0x6e, 0xc1, 0x9f, 0x4e, 0x39, 0x21, 0xaf, 0x69, 0x1d, 0xce, 0x6e, 0x2d, 0xd0, 0xd3, 0xea, 0xed, 0xd9, 0xad, 0x4c, + 0x5a, 0x87, 0xd8, 0x4d, 0x13, 0xd2, 0xb8, 0x71, 0xd3, 0x82, 0x42, 0xf8, 0xdb, 0xac, 0xbc, 0x6a, 0x1d, 0xc1, 0x3b, + 0x68, 0x75, 0xbc, 0xf9, 0xae, 0x7d, 0xff, 0xa6, 0xf5, 0xe2, 0x84, 0x3b, 0x9e, 0xe6, 0xc6, 0xc8, 0xe5, 0xfe, 0xf5, + 0x35, 0x0d, 0xbc, 0x71, 0x32, 0x9a, 0x67, 0xff, 0xa4, 0xe0, 0x57, 0x48, 0xbc, 0x77, 0x4b, 0xaf, 0xf5, 0xa3, 0x9b, + 0xca, 0x14, 0x7a, 0xdd, 0xc3, 0xb2, 0x58, 0x27, 0x2f, 0x1b, 0xf9, 0x11, 0x75, 0xda, 0xee, 0xd1, 0x96, 0x4d, 0xf0, + 0xef, 0xb2, 0x36, 0x5b, 0x27, 0xf3, 0x47, 0x91, 0x71, 0x2f, 0x12, 0x7e, 0x13, 0x0e, 0xcc, 0x35, 0x6c, 0x9e, 0x6e, + 0x07, 0x77, 0xa0, 0x47, 0x1a, 0x6a, 0xa1, 0xa0, 0xe4, 0x4e, 0x40, 0xc7, 0xfe, 0x3c, 0xe2, 0xf7, 0xf7, 0xba, 0x8b, + 0x32, 0x36, 0x7a, 0xbd, 0x87, 0xa1, 0x97, 0x75, 0x1f, 0xc8, 0xa5, 0x3f, 0x7f, 0x7c, 0x04, 0x7f, 0x64, 0xfe, 0xd7, + 0x5d, 0xa9, 0xab, 0x4b, 0xbb, 0x17, 0x74, 0xf5, 0xfd, 0x8a, 0x32, 0x2e, 0x45, 0xb8, 0xd0, 0xc7, 0x1f, 0x5a, 0x1b, + 0xb4, 0xca, 0x07, 0x55, 0x57, 0x5a, 0xd6, 0x6f, 0xaa, 0xfd, 0xdb, 0x3a, 0x7f, 0x60, 0xdd, 0x91, 0xd4, 0x5c, 0xab, + 0x75, 0xd5, 0x77, 0x1d, 0x37, 0x2a, 0x6b, 0x8c, 0x8b, 0xfa, 0xfb, 0xe4, 0xae, 0x30, 0x51, 0x64, 0x34, 0x16, 0xac, + 0x94, 0x7d, 0x69, 0xa5, 0x24, 0x94, 0x5c, 0x75, 0xfb, 0xb7, 0xd3, 0xc8, 0x5a, 0xc8, 0xf3, 0xa7, 0xc4, 0x6e, 0xb9, + 0x4d, 0xdb, 0x12, 0x79, 0x00, 0x70, 0x0d, 0xbe, 0x2d, 0xbe, 0x17, 0x6c, 0xf7, 0x41, 0xd3, 0x5a, 0x4c, 0x84, 0x66, + 0xf7, 0xc2, 0xbf, 0xa3, 0xe9, 0x65, 0xdb, 0xb6, 0xc0, 0x4f, 0x53, 0x97, 0x29, 0x13, 0xa2, 0xcc, 0x6a, 0xdb, 0xd6, + 0xed, 0x34, 0x8a, 0x33, 0x62, 0x87, 0x9c, 0xcf, 0x3c, 0xf9, 0x41, 0xe1, 0x9b, 0x43, 0x37, 0x49, 0x27, 0x8d, 0x76, + 0xb3, 0xd9, 0x84, 0x1b, 0x75, 0x6d, 0x6b, 0xc1, 0xe8, 0xcd, 0x93, 0xe4, 0x96, 0xd8, 0x4d, 0xab, 0x69, 0xb5, 0xda, + 0xa7, 0x56, 0xab, 0x7d, 0xe4, 0x9e, 0x9c, 0xda, 0xbd, 0xcf, 0x2c, 0xab, 0x1b, 0xd0, 0x71, 0x06, 0x3f, 0x2c, 0xab, + 0x2b, 0x14, 0x2f, 0xf9, 0xdb, 0xb2, 0xdc, 0x51, 0x94, 0xd5, 0x5b, 0xd6, 0x52, 0x3d, 0x5a, 0x16, 0x9c, 0xd2, 0xf5, + 0xac, 0xcf, 0xc7, 0xed, 0xf1, 0xd1, 0xf8, 0x71, 0x47, 0x15, 0xe7, 0x9f, 0x55, 0xaa, 0x63, 0xf9, 0x7f, 0xdb, 0x68, + 0x96, 0xf1, 0x34, 0xf9, 0x48, 0x55, 0x4e, 0xa2, 0x05, 0xa2, 0x67, 0x6b, 0xd3, 0xf6, 0xe6, 0x48, 0xad, 0xd3, 0xeb, + 0xd1, 0xb8, 0x5d, 0x56, 0x17, 0x30, 0x36, 0x0a, 0x20, 0xbb, 0x0d, 0x0d, 0x7a, 0xd7, 0x44, 0x53, 0xab, 0xbe, 0x0d, + 0x51, 0x2d, 0x5b, 0xcd, 0x71, 0xa2, 0xe7, 0xd7, 0x85, 0x43, 0x21, 0x5a, 0x57, 0x15, 0x10, 0xd8, 0x56, 0x40, 0xec, + 0x97, 0xad, 0xf6, 0x29, 0x6e, 0xb5, 0x4e, 0xdc, 0x93, 0xd3, 0x51, 0x13, 0x1f, 0xb9, 0x47, 0xf5, 0x43, 0xf7, 0x04, + 0x9f, 0xd6, 0x4f, 0xf1, 0xe9, 0xf3, 0xd3, 0x51, 0xfd, 0xc8, 0x3d, 0xc2, 0xcd, 0xfa, 0x29, 0x14, 0xd6, 0x4f, 0xeb, + 0xa7, 0x8b, 0xfa, 0xd1, 0xe9, 0xa8, 0x29, 0x4a, 0xdb, 0xee, 0xf1, 0x71, 0xbd, 0xd5, 0x74, 0x8f, 0x8f, 0xf1, 0xb1, + 0x7b, 0x72, 0x52, 0x6f, 0x1d, 0xba, 0x27, 0x27, 0x2f, 0x8e, 0x4f, 0xdd, 0x43, 0x78, 0x77, 0x78, 0x38, 0x3a, 0x74, + 0x5b, 0xad, 0x3a, 0xfc, 0x83, 0x4f, 0xdd, 0xb6, 0xfc, 0xd1, 0x6a, 0xb9, 0x87, 0x2d, 0xdc, 0x8c, 0x8e, 0xdb, 0xee, + 0xc9, 0x63, 0x2c, 0xfe, 0x15, 0xd5, 0xb0, 0xf8, 0x07, 0xba, 0xc1, 0x8f, 0xdd, 0xf6, 0x89, 0xfc, 0x25, 0x3a, 0x5c, + 0x1c, 0x9d, 0xfe, 0x64, 0x37, 0x76, 0xce, 0xa1, 0x25, 0xe7, 0x70, 0x7a, 0xec, 0x1e, 0x1e, 0xe2, 0xa3, 0x96, 0x7b, + 0x7a, 0x18, 0xd6, 0x8f, 0xda, 0xee, 0xc9, 0xa3, 0x51, 0xbd, 0xe5, 0x3e, 0x7a, 0x84, 0x9b, 0xf5, 0x43, 0xb7, 0x8d, + 0x5b, 0xee, 0xd1, 0xa1, 0xf8, 0x71, 0xe8, 0xb6, 0x17, 0x8f, 0x1e, 0xbb, 0x27, 0xc7, 0xe1, 0x89, 0x7b, 0xf4, 0xfd, + 0xd1, 0xa9, 0xdb, 0x3e, 0x0c, 0x0f, 0x4f, 0xdc, 0xf6, 0xa3, 0xc5, 0x89, 0x7b, 0x14, 0xd6, 0xdb, 0x27, 0xf7, 0xb6, + 0x6c, 0xb5, 0x5d, 0xc0, 0x91, 0x78, 0x0d, 0x2f, 0xb0, 0x7a, 0x01, 0x7f, 0x43, 0xd1, 0xf6, 0xdf, 0xb1, 0x9b, 0x6c, + 0xb3, 0xe9, 0x63, 0xf7, 0xf4, 0xd1, 0x48, 0x56, 0x87, 0x82, 0xba, 0xae, 0x01, 0x4d, 0x16, 0x75, 0x39, 0xac, 0xe8, + 0xae, 0xae, 0x3b, 0xd2, 0x7f, 0xd5, 0x60, 0x8b, 0x3a, 0x0c, 0x2c, 0xc7, 0xfd, 0x0f, 0xed, 0xa7, 0x58, 0xf2, 0x6e, + 0x63, 0x22, 0x49, 0x7f, 0xd2, 0xfb, 0x4c, 0x5e, 0x97, 0xfd, 0xd9, 0x15, 0x8e, 0x76, 0x39, 0x3e, 0xfc, 0x4f, 0x3b, + 0x3e, 0x42, 0xfa, 0x10, 0xcf, 0x87, 0xff, 0xa7, 0x7b, 0x3e, 0xa2, 0x75, 0xc7, 0xf9, 0x0d, 0xdf, 0x70, 0x70, 0xac, + 0x5b, 0xc5, 0x2f, 0xb8, 0x33, 0x48, 0xe0, 0xc3, 0x6c, 0x79, 0xe7, 0x86, 0x93, 0x90, 0x9a, 0x7e, 0xa0, 0x04, 0x58, + 0xec, 0x0d, 0x97, 0x3c, 0x76, 0xb4, 0x0b, 0x21, 0xc1, 0xa7, 0x11, 0xf2, 0xfd, 0x43, 0xf0, 0x11, 0xfc, 0xe9, 0xf8, + 0x18, 0x99, 0xf8, 0xa8, 0xf8, 0xf2, 0x85, 0xa7, 0x41, 0x78, 0x0a, 0x2e, 0xc4, 0xb3, 0x03, 0xa7, 0xd2, 0x6a, 0x76, + 0x83, 0x42, 0x51, 0x66, 0xcb, 0xc8, 0xd7, 0xdb, 0xdf, 0x12, 0x76, 0x90, 0x47, 0x50, 0x89, 0xad, 0xdc, 0x32, 0x33, + 0x21, 0x75, 0xd4, 0x43, 0x21, 0x94, 0xda, 0x6e, 0xd3, 0x6d, 0x16, 0x2e, 0x1d, 0x38, 0x76, 0x4c, 0x96, 0x09, 0xf7, + 0xe1, 0x13, 0xc0, 0x51, 0x32, 0x11, 0x1f, 0x0b, 0x86, 0xcf, 0x33, 0x40, 0xd2, 0xcf, 0x48, 0x7e, 0x19, 0x03, 0xce, + 0x4d, 0x28, 0x47, 0x8f, 0x9f, 0x7e, 0xfc, 0x0e, 0x8e, 0xfe, 0xea, 0xa8, 0xc4, 0x14, 0xbc, 0x1d, 0x2f, 0x69, 0xc0, + 0x7c, 0xc7, 0x76, 0x66, 0x29, 0x1d, 0xd3, 0x34, 0xab, 0x57, 0xce, 0xc3, 0x8a, 0xa3, 0xb0, 0xc8, 0xd6, 0xdf, 0x9a, + 0x4d, 0xe1, 0xba, 0x71, 0x32, 0x50, 0xfe, 0x46, 0x5b, 0x19, 0x60, 0x76, 0x8e, 0x75, 0x49, 0x0a, 0xb2, 0xb6, 0x54, + 0xda, 0x6c, 0xa9, 0xb5, 0xb5, 0xdc, 0xf6, 0x31, 0xb2, 0x44, 0x31, 0x5c, 0xe4, 0xfc, 0xa3, 0x53, 0x3f, 0x6c, 0xfe, + 0x05, 0x19, 0xcd, 0x8a, 0x8e, 0x86, 0xca, 0xdd, 0x16, 0x97, 0x1f, 0xe9, 0xae, 0x1e, 0x56, 0xb6, 0x25, 0x45, 0x7c, + 0x2e, 0xe7, 0x6e, 0xa3, 0x4e, 0xac, 0x22, 0xdc, 0xf2, 0xca, 0x8d, 0x31, 0x9b, 0x38, 0xe6, 0x27, 0x98, 0xe5, 0x45, + 0xd1, 0xe2, 0xcb, 0xed, 0x28, 0x2f, 0xab, 0xc4, 0x68, 0x29, 0xe2, 0x2d, 0x2c, 0xb6, 0xe2, 0xd5, 0xca, 0x89, 0xc1, + 0x45, 0x4e, 0x0c, 0x9c, 0xc2, 0x33, 0xaa, 0x20, 0x39, 0xc6, 0x05, 0x40, 0x02, 0xc1, 0x24, 0x96, 0xff, 0x97, 0xc5, + 0xfa, 0x87, 0x72, 0x7c, 0xb9, 0x91, 0x1f, 0x4f, 0x80, 0x0a, 0xfd, 0x78, 0xb2, 0xe1, 0x56, 0x93, 0x21, 0xa3, 0xb5, + 0xd2, 0xb2, 0xab, 0xd2, 0x7d, 0x96, 0x3d, 0xb9, 0x7b, 0xa7, 0x6e, 0x94, 0xb3, 0xc1, 0x3b, 0x2d, 0x22, 0x1c, 0xe5, + 0xed, 0xd7, 0x35, 0xf2, 0x45, 0x77, 0x4a, 0xb9, 0x2f, 0xf3, 0x35, 0x41, 0x9f, 0x80, 0x63, 0xc8, 0x96, 0xb2, 0x46, + 0x89, 0x2d, 0xa4, 0x3b, 0x91, 0x67, 0x68, 0xa4, 0xa8, 0xc7, 0x96, 0xba, 0x8a, 0xa1, 0x2e, 0x96, 0x86, 0xb4, 0xb0, + 0xf4, 0xc7, 0x8c, 0x7c, 0x91, 0x91, 0x4f, 0xe2, 0xc4, 0xee, 0x7d, 0x51, 0x7c, 0x4e, 0x76, 0xd7, 0x22, 0x44, 0x2c, + 0xfe, 0x38, 0x48, 0x69, 0xf4, 0x4f, 0xe4, 0x0b, 0x36, 0x4a, 0xe2, 0x2f, 0x86, 0x36, 0xea, 0x70, 0x37, 0x4c, 0xe9, + 0x98, 0x7c, 0x01, 0x32, 0xde, 0x13, 0xd6, 0x07, 0x30, 0xc2, 0xda, 0xed, 0x34, 0xc2, 0x42, 0x63, 0x7a, 0x80, 0x42, + 0x24, 0xc1, 0xb5, 0xdb, 0xc7, 0xb6, 0x25, 0x6d, 0x62, 0xf1, 0xbb, 0x27, 0xc5, 0xa9, 0x50, 0x02, 0xac, 0x56, 0xdb, + 0x3d, 0x0e, 0xdb, 0xee, 0xe3, 0xc5, 0x23, 0xf7, 0x34, 0x6c, 0x3d, 0x5a, 0xd4, 0xe1, 0xff, 0xb6, 0xfb, 0x38, 0xaa, + 0xb7, 0xdd, 0xc7, 0xf0, 0xf7, 0xfb, 0x23, 0xf7, 0x38, 0xac, 0xb7, 0xdc, 0xd3, 0xc5, 0xa1, 0x7b, 0xf8, 0xa2, 0xd5, + 0x76, 0x0f, 0xad, 0x96, 0x25, 0xdb, 0x01, 0xbb, 0x96, 0xdc, 0xf9, 0x8b, 0xb5, 0x0d, 0xb1, 0x25, 0x1c, 0x27, 0x73, + 0x4e, 0x6d, 0xec, 0x14, 0x1f, 0xad, 0x54, 0xfb, 0x53, 0x39, 0xeb, 0x9e, 0xfa, 0x29, 0x7c, 0x39, 0xa8, 0xba, 0x77, + 0x2b, 0xef, 0x70, 0x85, 0x5f, 0x6c, 0x19, 0x02, 0x76, 0xb8, 0x8d, 0xcd, 0xbb, 0x0c, 0xe0, 0x22, 0x00, 0x71, 0xd1, + 0xba, 0xbe, 0x6f, 0x72, 0x37, 0x69, 0xcb, 0x8a, 0xfa, 0x4e, 0x4b, 0xc1, 0x2c, 0x98, 0xf8, 0xa4, 0x85, 0x18, 0xe4, + 0x9b, 0x20, 0x5f, 0x1f, 0x1f, 0x52, 0x5f, 0xd3, 0xc4, 0xb8, 0xce, 0x81, 0x96, 0x07, 0x36, 0x02, 0x06, 0x17, 0x70, + 0xe4, 0xb9, 0x06, 0xbd, 0xe2, 0xa6, 0x2d, 0xb1, 0x24, 0xf8, 0x05, 0xcd, 0xfa, 0x36, 0x14, 0xd9, 0x9e, 0x2d, 0x5c, + 0x7c, 0x76, 0xf1, 0xf5, 0xa4, 0x82, 0xb0, 0xcb, 0x02, 0x2c, 0x0e, 0x5d, 0xc1, 0xae, 0x05, 0xfc, 0xd8, 0xe8, 0xe0, + 0x60, 0xe7, 0x7e, 0x11, 0x0a, 0x24, 0xcc, 0xb5, 0xfc, 0xe8, 0x8a, 0xc9, 0x8a, 0x6c, 0x13, 0xd1, 0x45, 0xbf, 0x02, + 0x85, 0x48, 0xe1, 0xe9, 0x9a, 0xfa, 0xdc, 0xf5, 0x63, 0x99, 0x44, 0x63, 0x30, 0x2c, 0xdc, 0xa2, 0x87, 0x28, 0x4f, + 0xb8, 0x6f, 0x7c, 0x58, 0x59, 0xed, 0xf3, 0x84, 0xfb, 0xfa, 0x70, 0xb2, 0x71, 0x0f, 0x13, 0x38, 0x7a, 0xc3, 0x76, + 0xef, 0xf5, 0xbb, 0x33, 0x4b, 0x6e, 0xcf, 0x6e, 0x23, 0x6c, 0xf7, 0xba, 0xc2, 0x67, 0x22, 0x0f, 0xea, 0x11, 0x79, + 0x50, 0xcf, 0x52, 0x67, 0x33, 0x21, 0x92, 0x96, 0x37, 0xe4, 0xb4, 0x85, 0xcd, 0x20, 0xbd, 0xbd, 0xd3, 0x79, 0xc4, + 0x19, 0x5c, 0x1a, 0xde, 0x10, 0xa7, 0xf4, 0x60, 0xc1, 0x8a, 0x3c, 0x6c, 0xa5, 0x1d, 0x5e, 0xf3, 0x58, 0xfb, 0x86, + 0xc7, 0x2c, 0xa2, 0x3a, 0xf3, 0x5a, 0x75, 0x55, 0x9c, 0x14, 0xd8, 0xac, 0x9d, 0xcd, 0xaf, 0xa7, 0x8c, 0xdb, 0xfa, + 0x3c, 0xc3, 0x7b, 0xd5, 0xa0, 0x2b, 0x86, 0xea, 0x5d, 0xe5, 0xca, 0x79, 0xad, 0x3f, 0x8f, 0x54, 0x5d, 0x52, 0x35, + 0x7b, 0x25, 0x21, 0xe0, 0x84, 0x5c, 0x78, 0xd8, 0x2b, 0xdc, 0xc5, 0xe6, 0xbb, 0xbc, 0xdb, 0x08, 0x0f, 0x7b, 0x57, + 0xde, 0x4c, 0xf5, 0xf7, 0x22, 0x99, 0x6c, 0xef, 0x2b, 0x4a, 0x26, 0x7d, 0x71, 0x14, 0x44, 0x9e, 0x99, 0xd6, 0xca, + 0x6f, 0x12, 0xd9, 0xbd, 0xae, 0x52, 0x06, 0x2c, 0x11, 0x58, 0xb7, 0x8f, 0x9b, 0xfa, 0x74, 0x49, 0x94, 0x4c, 0x60, + 0x43, 0xca, 0x26, 0xc6, 0x20, 0x15, 0x8f, 0x7b, 0xd8, 0xea, 0x75, 0x7d, 0x4b, 0xf0, 0x16, 0xc1, 0x3c, 0x32, 0xaf, + 0x01, 0x8d, 0xc3, 0x64, 0x4a, 0x5d, 0x96, 0x34, 0x6e, 0xe8, 0x75, 0xdd, 0x9f, 0xb1, 0xd2, 0xbd, 0x0d, 0x4a, 0x47, + 0x31, 0x64, 0xa2, 0x3d, 0xe2, 0xea, 0xec, 0x55, 0xbb, 0x74, 0xb7, 0x1d, 0x81, 0xcd, 0xa3, 0x5d, 0x73, 0xc2, 0x27, + 0x67, 0x80, 0x95, 0xf4, 0xba, 0x0d, 0x7f, 0x0d, 0x23, 0x82, 0xdf, 0xe7, 0xca, 0xd1, 0x0e, 0x86, 0x0d, 0xd0, 0x9b, + 0x6d, 0x49, 0x71, 0xa0, 0x1d, 0xf2, 0x4a, 0x50, 0xe7, 0x76, 0xef, 0x5f, 0xff, 0xc7, 0xff, 0x52, 0x3e, 0xf6, 0x6e, + 0x23, 0x6c, 0xe9, 0xbe, 0xd6, 0x56, 0x25, 0xef, 0xc2, 0xf9, 0xd0, 0x32, 0x28, 0x4c, 0x6f, 0xeb, 0x93, 0x94, 0x05, + 0xf5, 0xd0, 0x8f, 0xc6, 0x76, 0x6f, 0x37, 0x36, 0xcd, 0x63, 0x5b, 0x0a, 0xea, 0x6a, 0x11, 0xd0, 0xeb, 0xef, 0x3a, + 0x78, 0xa4, 0xcf, 0xaf, 0x88, 0xad, 0x6d, 0x1e, 0x43, 0x2a, 0x77, 0x5f, 0xe5, 0x28, 0x52, 0xac, 0xbe, 0xb9, 0xa6, + 0x38, 0x60, 0x5c, 0x39, 0x81, 0x94, 0xdb, 0x56, 0x11, 0xd4, 0xfa, 0xbf, 0xff, 0xf3, 0xbf, 0xfc, 0x37, 0xfd, 0x08, + 0xb1, 0xaa, 0x7f, 0xfd, 0xef, 0xff, 0xf9, 0xff, 0xfc, 0xef, 0xff, 0x0a, 0xa7, 0x56, 0x54, 0x3c, 0x4b, 0x30, 0x15, + 0xab, 0x0c, 0x66, 0x49, 0xee, 0x62, 0x41, 0x62, 0xe7, 0x94, 0x65, 0x9c, 0x8d, 0xaa, 0x67, 0x92, 0x2e, 0xc4, 0x80, + 0x62, 0x67, 0x2a, 0xe8, 0xc4, 0x0e, 0xcf, 0x4b, 0x82, 0xaa, 0xa0, 0x5c, 0x10, 0x6e, 0xde, 0x6d, 0x00, 0xbe, 0x1f, + 0x76, 0x8c, 0xd3, 0x2d, 0x96, 0x63, 0xa9, 0xc9, 0x04, 0x4a, 0xf2, 0xb2, 0xdc, 0x82, 0xd8, 0xca, 0x12, 0x1e, 0xbd, + 0xb6, 0x51, 0x2c, 0x56, 0xaf, 0xd2, 0xa6, 0xf3, 0x61, 0x9e, 0x71, 0x36, 0x06, 0x94, 0x4b, 0x3f, 0xb1, 0x08, 0x63, + 0xd7, 0x41, 0x57, 0x8c, 0xee, 0x72, 0xd1, 0x8b, 0x24, 0xd0, 0xa3, 0xd3, 0xbf, 0xe4, 0x5f, 0x4e, 0x41, 0x23, 0xb3, + 0x9c, 0xa9, 0x7f, 0xab, 0xcc, 0xf3, 0x93, 0x66, 0x73, 0x76, 0x8b, 0x96, 0xe5, 0x08, 0x78, 0xd7, 0x60, 0x82, 0x8e, + 0xcd, 0x0e, 0x45, 0xfc, 0xbb, 0x70, 0x63, 0x37, 0x2d, 0xf0, 0x85, 0x5b, 0xcd, 0x3c, 0xff, 0xeb, 0x52, 0x78, 0x52, + 0xd9, 0xaf, 0x10, 0xa7, 0x56, 0x4e, 0xe7, 0xeb, 0xc4, 0x9c, 0xdc, 0xd2, 0x68, 0xd5, 0x96, 0xad, 0xc2, 0xd6, 0xe6, + 0xe9, 0x44, 0x33, 0xce, 0x6e, 0x46, 0xc8, 0x8f, 0x20, 0xe6, 0x1d, 0xb6, 0x70, 0xd8, 0x5e, 0x16, 0xdd, 0x73, 0x9e, + 0x4c, 0xcd, 0xc0, 0x3a, 0xf5, 0xe9, 0x88, 0x8e, 0xb5, 0xb3, 0x5e, 0xbd, 0x97, 0x41, 0xf3, 0x3c, 0x3c, 0xdc, 0x32, + 0x96, 0x02, 0x49, 0x04, 0xd4, 0xad, 0x66, 0xfe, 0x39, 0xec, 0xc0, 0xe5, 0x38, 0x4a, 0x7c, 0xee, 0x09, 0x82, 0xed, + 0x98, 0xe1, 0x79, 0x1f, 0x78, 0x52, 0xb2, 0x34, 0xe0, 0xe9, 0xc8, 0xaa, 0xe0, 0x36, 0xaf, 0x9e, 0x21, 0xcd, 0x5d, + 0xd1, 0xdc, 0xec, 0x4a, 0x7a, 0xdd, 0xbe, 0x57, 0x51, 0xef, 0xb7, 0x15, 0x77, 0x95, 0x12, 0x48, 0x6d, 0xb4, 0xfd, + 0xbd, 0x94, 0xeb, 0xf2, 0xed, 0x77, 0xdc, 0xb1, 0x05, 0x98, 0xf6, 0x7a, 0x2d, 0x51, 0x08, 0xb5, 0xde, 0x92, 0xef, + 0x0b, 0x93, 0xc9, 0x9f, 0xcd, 0x44, 0x45, 0xd4, 0xe9, 0x36, 0xa4, 0xa6, 0x0b, 0xdc, 0x43, 0xa4, 0x74, 0xc8, 0x0c, + 0x0a, 0x55, 0x49, 0x6d, 0x05, 0xf9, 0x4b, 0xe5, 0x56, 0xc0, 0xb7, 0xf8, 0x7a, 0xff, 0x0f, 0x85, 0xa3, 0x0b, 0x12, + 0x20, 0x8b, 0x00, 0x00}; -} // namespace esphome::web_server +} // namespace web_server +} // namespace esphome #endif #endif diff --git a/esphome/components/web_server/server_index_v3.h b/esphome/components/web_server/server_index_v3.h index 8a8ced9153..725bdc34e3 100644 --- a/esphome/components/web_server/server_index_v3.h +++ b/esphome/components/web_server/server_index_v3.h @@ -6,4048 +6,4058 @@ #include "esphome/core/hal.h" -namespace esphome::web_server { +namespace esphome { +namespace web_server { const uint8_t INDEX_GZ[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xcc, 0xbd, 0xeb, 0x7a, 0x1b, 0xb7, 0xb2, 0x20, 0xfa, - 0xfb, 0xcc, 0x53, 0x48, 0xbd, 0x1d, 0xa5, 0x21, 0x82, 0x2d, 0x92, 0xba, 0x58, 0x6e, 0x0a, 0xe2, 0xf8, 0x1a, 0x3b, - 0x71, 0x6c, 0xc7, 0x72, 0xec, 0x38, 0x0c, 0xb7, 0x0c, 0x36, 0x41, 0x12, 0x76, 0x13, 0x60, 0x1a, 0xa0, 0x25, 0x85, - 0xe4, 0xbb, 0x9f, 0xaf, 0x70, 0xe9, 0x46, 0x93, 0xb4, 0xd7, 0x5a, 0x73, 0x66, 0xce, 0x37, 0x3b, 0x7b, 0x59, 0x6c, - 0xdc, 0x51, 0x28, 0x14, 0xaa, 0x0a, 0x55, 0x85, 0x8b, 0xfd, 0x91, 0xcc, 0xf4, 0xdd, 0x9c, 0xed, 0x4d, 0xf5, 0x2c, - 0xbf, 0xbc, 0x70, 0xff, 0x32, 0x3a, 0xba, 0xbc, 0xc8, 0xb9, 0xf8, 0xb2, 0x57, 0xb0, 0x9c, 0xf0, 0x4c, 0x8a, 0xbd, - 0x69, 0xc1, 0xc6, 0x64, 0x44, 0x35, 0x4d, 0xf9, 0x8c, 0x4e, 0xd8, 0xde, 0xd1, 0xe5, 0xc5, 0x8c, 0x69, 0xba, 0x97, - 0x4d, 0x69, 0xa1, 0x98, 0x26, 0xbf, 0xbf, 0x7b, 0xd6, 0x3c, 0xbf, 0xbc, 0x50, 0x59, 0xc1, 0xe7, 0x7a, 0x0f, 0x9a, - 0x24, 0x33, 0x39, 0x5a, 0xe4, 0xec, 0xf2, 0xe8, 0xe8, 0xe6, 0xe6, 0x26, 0xf9, 0xac, 0xfe, 0xc7, 0x57, 0x5a, 0xec, - 0xfd, 0x52, 0x90, 0xd7, 0xc3, 0xcf, 0x2c, 0xd3, 0xc9, 0x88, 0x8d, 0xb9, 0x60, 0x6f, 0x0a, 0x39, 0x67, 0x85, 0xbe, - 0xeb, 0x42, 0xe6, 0x4f, 0x05, 0x89, 0x39, 0xd6, 0x98, 0x21, 0x72, 0xa9, 0xf7, 0xb8, 0xd8, 0xe3, 0xbd, 0x5f, 0x0a, - 0x93, 0xb2, 0x64, 0x62, 0x31, 0x63, 0x05, 0x1d, 0xe6, 0x2c, 0xdd, 0x6f, 0xe1, 0x4c, 0x8a, 0x31, 0x9f, 0x2c, 0xca, - 0xef, 0x9b, 0x82, 0x6b, 0xff, 0xfb, 0x2b, 0xcd, 0x17, 0x2c, 0x65, 0x6b, 0x94, 0xf2, 0xbe, 0x1e, 0x10, 0x66, 0x5a, - 0xfe, 0x52, 0x35, 0x1c, 0xff, 0x64, 0x9a, 0xbc, 0x9b, 0x33, 0x39, 0xde, 0xd3, 0xfb, 0x24, 0x52, 0x77, 0xb3, 0xa1, - 0xcc, 0xa3, 0x9e, 0x6e, 0x44, 0x51, 0x0a, 0x65, 0x30, 0x43, 0xdd, 0x4c, 0x0a, 0xa5, 0xf7, 0x04, 0x27, 0x37, 0x5c, - 0x8c, 0xe4, 0x0d, 0xbe, 0x11, 0x44, 0xf0, 0xe4, 0x6a, 0x4a, 0x47, 0xf2, 0xe6, 0xad, 0x94, 0xfa, 0xe0, 0x20, 0x76, - 0xdf, 0x77, 0x8f, 0xaf, 0xae, 0x08, 0x21, 0x5f, 0x25, 0x1f, 0xed, 0xb5, 0x56, 0xab, 0x20, 0x35, 0x11, 0x54, 0xf3, - 0xaf, 0xcc, 0x56, 0x42, 0x07, 0x07, 0x11, 0x1d, 0xc9, 0xb9, 0x66, 0xa3, 0x2b, 0x7d, 0x97, 0xb3, 0xab, 0x29, 0x63, - 0x5a, 0x45, 0x5c, 0xec, 0x3d, 0x91, 0xd9, 0x62, 0xc6, 0x84, 0x4e, 0xe6, 0x85, 0xd4, 0x12, 0x06, 0x76, 0x70, 0x10, - 0x15, 0x6c, 0x9e, 0xd3, 0x8c, 0x41, 0xfe, 0xe3, 0xab, 0xab, 0xaa, 0x46, 0x55, 0x08, 0x7f, 0x11, 0xe4, 0xca, 0x0c, - 0x3d, 0x46, 0xf8, 0x83, 0x20, 0x82, 0xdd, 0xec, 0x7d, 0x60, 0xf4, 0xcb, 0xaf, 0x74, 0xde, 0xcd, 0x72, 0xaa, 0xd4, - 0xde, 0x33, 0xb9, 0x34, 0xd3, 0x28, 0x16, 0x99, 0x96, 0x45, 0xac, 0x31, 0xc3, 0x02, 0x2d, 0xf9, 0x38, 0xd6, 0x53, - 0xae, 0x92, 0xeb, 0x7b, 0x99, 0x52, 0x6f, 0x99, 0x5a, 0xe4, 0xfa, 0x1e, 0xd9, 0x6f, 0x61, 0xb1, 0x4f, 0xc8, 0x17, - 0x81, 0xf4, 0xb4, 0x90, 0x37, 0x7b, 0x4f, 0x8b, 0x42, 0x16, 0x71, 0xf4, 0xf8, 0xea, 0xca, 0x96, 0xd8, 0xe3, 0x6a, - 0x4f, 0x48, 0xbd, 0x57, 0xb6, 0x07, 0xd0, 0x4e, 0xf6, 0x7e, 0x57, 0x6c, 0xef, 0xd3, 0x42, 0x28, 0x3a, 0x66, 0x8f, - 0xaf, 0xae, 0x3e, 0xed, 0xc9, 0x62, 0xef, 0x53, 0xa6, 0xd4, 0xa7, 0x3d, 0x2e, 0x94, 0x66, 0x74, 0x94, 0x44, 0xa8, - 0x6b, 0x3a, 0xcb, 0x94, 0x7a, 0xc7, 0x6e, 0x35, 0xd1, 0xd8, 0x7c, 0x6a, 0xc2, 0xd6, 0x13, 0xa6, 0xf7, 0x54, 0x39, - 0xaf, 0x18, 0x2d, 0x73, 0xa6, 0xf7, 0x34, 0x31, 0xf9, 0xd2, 0xc1, 0x9f, 0xd9, 0x4f, 0xdd, 0xe5, 0xe3, 0xf8, 0x46, - 0x1c, 0x1c, 0xe8, 0x12, 0xd0, 0x68, 0xe9, 0x56, 0x88, 0xb0, 0x7d, 0x9f, 0x76, 0x70, 0xc0, 0x92, 0x9c, 0x89, 0x89, - 0x9e, 0x12, 0x42, 0xda, 0x5d, 0x71, 0x70, 0x10, 0x6b, 0xf2, 0x41, 0x24, 0x13, 0xa6, 0x63, 0x86, 0x10, 0xae, 0x6a, - 0x1f, 0x1c, 0xc4, 0x16, 0x08, 0x92, 0x68, 0x03, 0xb8, 0x1a, 0x8c, 0x51, 0xe2, 0xa0, 0x7f, 0x75, 0x27, 0xb2, 0x38, - 0x1c, 0x3f, 0xc2, 0xe2, 0xe0, 0xe0, 0x83, 0x48, 0x14, 0xb4, 0x88, 0x35, 0x42, 0xeb, 0x82, 0xe9, 0x45, 0x21, 0xf6, - 0xf4, 0x5a, 0xcb, 0x2b, 0x5d, 0x70, 0x31, 0x89, 0xd1, 0xd2, 0xa7, 0x05, 0x15, 0xd7, 0x6b, 0x3b, 0xdc, 0xdf, 0x0a, - 0xc2, 0xc9, 0x25, 0xf4, 0xf8, 0x4c, 0xc6, 0x0e, 0x07, 0x39, 0x21, 0x91, 0x32, 0x75, 0xa3, 0x1e, 0x4f, 0x79, 0x23, - 0x8a, 0xb0, 0x1d, 0x25, 0xfe, 0x22, 0x10, 0x16, 0x1a, 0x50, 0x37, 0x49, 0x12, 0x8d, 0xc8, 0xe5, 0xd2, 0x83, 0x85, - 0x07, 0x13, 0xed, 0xf1, 0x7e, 0x6b, 0x90, 0xea, 0xa4, 0x60, 0xa3, 0x45, 0xc6, 0xe2, 0x58, 0x60, 0x85, 0x25, 0x22, - 0x97, 0xa2, 0x11, 0x17, 0xe4, 0x12, 0xd6, 0xbb, 0xa8, 0x2f, 0x36, 0x21, 0xfb, 0x2d, 0xe4, 0x06, 0x59, 0xf8, 0x11, - 0x02, 0x88, 0xdd, 0x80, 0x0a, 0x42, 0x22, 0xb1, 0x98, 0x0d, 0x59, 0x11, 0x95, 0xc5, 0xba, 0x35, 0xbc, 0x58, 0x28, - 0xb6, 0x97, 0x29, 0xb5, 0x37, 0x5e, 0x88, 0x4c, 0x73, 0x29, 0xf6, 0xa2, 0x46, 0xd1, 0x88, 0x2c, 0x3e, 0x94, 0xe8, - 0x10, 0xa1, 0x35, 0x8a, 0x15, 0x6a, 0xf0, 0xbe, 0x6c, 0xb4, 0x07, 0x18, 0x46, 0x89, 0xba, 0xae, 0x3d, 0x07, 0x01, - 0x86, 0x39, 0x4c, 0x72, 0x8d, 0xff, 0xb4, 0x3b, 0x1f, 0xa6, 0x78, 0x23, 0x7a, 0x3c, 0xd9, 0xde, 0x29, 0x44, 0x27, - 0x33, 0x3a, 0x8f, 0x19, 0xb9, 0x64, 0x06, 0xbb, 0xa8, 0xc8, 0x60, 0xac, 0xb5, 0x85, 0xeb, 0xb1, 0x94, 0x25, 0x15, - 0x4e, 0xa1, 0x54, 0x27, 0x63, 0x59, 0x3c, 0xa5, 0xd9, 0x14, 0xea, 0x95, 0x18, 0x33, 0xf2, 0x1b, 0x2e, 0x2b, 0x18, - 0xd5, 0xec, 0x69, 0xce, 0xe0, 0x2b, 0x8e, 0x4c, 0xcd, 0x08, 0x61, 0x05, 0x5b, 0x3d, 0xe7, 0xfa, 0x95, 0x14, 0x19, - 0xeb, 0xaa, 0x00, 0xbf, 0xcc, 0xca, 0x3f, 0xd4, 0xba, 0xe0, 0xc3, 0x85, 0x66, 0x71, 0x24, 0xa0, 0x44, 0x84, 0x15, - 0xc2, 0x22, 0xd1, 0xec, 0x56, 0x3f, 0x96, 0x42, 0x33, 0xa1, 0x09, 0xf3, 0x50, 0xc5, 0x3c, 0xa1, 0xf3, 0x39, 0x13, - 0xa3, 0xc7, 0x53, 0x9e, 0x8f, 0x62, 0x81, 0xd6, 0x68, 0x8d, 0x7f, 0x17, 0x04, 0x26, 0x49, 0x2e, 0x79, 0x0a, 0xff, - 0x7c, 0x7b, 0x3a, 0xb1, 0x26, 0x97, 0x66, 0x5b, 0x30, 0x12, 0x45, 0xdd, 0xb1, 0x2c, 0x62, 0x37, 0x85, 0x3d, 0x20, - 0x5d, 0xd0, 0xc7, 0xdb, 0x45, 0xce, 0x14, 0x62, 0x0d, 0x22, 0xca, 0x75, 0x74, 0x10, 0xfe, 0xad, 0x88, 0x19, 0x2c, - 0x00, 0x47, 0x29, 0x37, 0x24, 0xf0, 0x25, 0x77, 0x9b, 0x6a, 0x54, 0x12, 0xb5, 0x8f, 0x82, 0x8c, 0x78, 0xa2, 0x8b, - 0x85, 0xd2, 0x6c, 0xf4, 0xee, 0x6e, 0xce, 0x14, 0xfe, 0xb9, 0x20, 0x1f, 0x45, 0xef, 0xa3, 0x48, 0xd8, 0x6c, 0xae, - 0xef, 0xae, 0x0c, 0x35, 0x4f, 0xa3, 0x08, 0xff, 0x6d, 0x8a, 0x16, 0x8c, 0x66, 0x40, 0xd2, 0x1c, 0xc8, 0xde, 0xc8, - 0xfc, 0x6e, 0xcc, 0xf3, 0xfc, 0x6a, 0x31, 0x9f, 0xcb, 0x42, 0x63, 0x2d, 0xc8, 0x52, 0xcb, 0x0a, 0x3e, 0xb0, 0xa2, - 0x4b, 0x75, 0xc3, 0x75, 0x36, 0x8d, 0x35, 0x5a, 0x66, 0x54, 0xb1, 0xbd, 0x47, 0x52, 0xe6, 0x8c, 0x8a, 0x94, 0x13, - 0xde, 0xfb, 0xb9, 0x48, 0xc5, 0x22, 0xcf, 0xbb, 0xc3, 0x82, 0xd1, 0x2f, 0x5d, 0x93, 0x6d, 0x0f, 0x87, 0xd4, 0xfc, - 0x7e, 0x58, 0x14, 0xf4, 0x0e, 0x0a, 0x12, 0x02, 0xc5, 0x7a, 0x3c, 0xfd, 0xf9, 0xea, 0xf5, 0xab, 0xc4, 0xee, 0x15, - 0x3e, 0xbe, 0x8b, 0x79, 0xb9, 0xff, 0xf8, 0x1a, 0x8f, 0x0b, 0x39, 0xdb, 0xe8, 0xda, 0x82, 0x8e, 0x77, 0xbf, 0x31, - 0x04, 0x46, 0xf8, 0xbe, 0x6d, 0x3a, 0x1c, 0xc1, 0x2b, 0x83, 0xf9, 0x90, 0x49, 0x5c, 0xbf, 0xf0, 0x4f, 0x6a, 0x93, - 0x63, 0x8e, 0xbe, 0x3f, 0x5a, 0x5d, 0xdc, 0x2d, 0x19, 0x31, 0xe3, 0x9c, 0xc3, 0xc1, 0x08, 0x63, 0xcc, 0xa8, 0xce, - 0xa6, 0x4b, 0x66, 0x1a, 0x5b, 0xfb, 0x11, 0xb3, 0xf5, 0x1a, 0xbf, 0x92, 0x1e, 0xeb, 0xf5, 0x3e, 0x21, 0xdc, 0xd0, - 0x2b, 0xa2, 0x57, 0x2b, 0x4e, 0x08, 0x47, 0xf8, 0x2d, 0x27, 0x4b, 0xea, 0x27, 0x04, 0x27, 0x1b, 0x6c, 0xcf, 0xd4, - 0x52, 0x19, 0x38, 0x01, 0xbf, 0xb2, 0x42, 0xb3, 0x22, 0xd5, 0x02, 0x17, 0x6c, 0x9c, 0xc3, 0x38, 0xf6, 0xdb, 0x78, - 0x4a, 0xd5, 0xe3, 0x29, 0x15, 0x13, 0x36, 0x4a, 0x5f, 0xc9, 0x35, 0x66, 0x82, 0x44, 0x63, 0x2e, 0x68, 0xce, 0xff, - 0x61, 0xa3, 0xc8, 0x9d, 0x0b, 0xef, 0xf5, 0x1e, 0xbb, 0xd5, 0x4c, 0x8c, 0xd4, 0xde, 0xf3, 0x77, 0xbf, 0xbe, 0x74, - 0x8b, 0x59, 0x3b, 0x2b, 0xd0, 0x52, 0x2d, 0xe6, 0xac, 0x88, 0x11, 0x76, 0x67, 0xc5, 0x53, 0x6e, 0xe8, 0xe4, 0xaf, - 0x74, 0x6e, 0x53, 0xb8, 0xfa, 0x7d, 0x3e, 0xa2, 0x9a, 0xbd, 0x61, 0x62, 0xc4, 0xc5, 0x84, 0xec, 0xb7, 0x6d, 0xfa, - 0x94, 0xba, 0x8c, 0x51, 0x99, 0x74, 0x7d, 0xef, 0x69, 0x6e, 0xe6, 0x5e, 0x7e, 0x2e, 0x62, 0xb4, 0x56, 0x9a, 0x6a, - 0x9e, 0xed, 0xd1, 0xd1, 0xe8, 0x85, 0xe0, 0x9a, 0x9b, 0x11, 0x16, 0xb0, 0x44, 0x80, 0xab, 0xcc, 0x9e, 0x1a, 0x7e, - 0xe4, 0x31, 0xc2, 0x71, 0xec, 0xce, 0x82, 0x29, 0x72, 0x6b, 0x76, 0x70, 0x50, 0x51, 0xfe, 0x1e, 0x4b, 0x6d, 0x26, - 0xe9, 0x0f, 0x50, 0x32, 0x5f, 0x28, 0x58, 0x6c, 0xdf, 0x05, 0x1c, 0x34, 0x72, 0xa8, 0x58, 0xf1, 0x95, 0x8d, 0x4a, - 0x04, 0x51, 0x31, 0x5a, 0x6e, 0xf4, 0xe1, 0xb6, 0x87, 0x26, 0xfd, 0x41, 0x37, 0x24, 0xe1, 0xcc, 0x21, 0xbb, 0xe5, - 0x54, 0x38, 0x53, 0x25, 0x51, 0x89, 0xe1, 0x40, 0x2d, 0x09, 0x8b, 0x22, 0x7e, 0x7e, 0xf3, 0x58, 0x00, 0x0f, 0x11, - 0x52, 0x0e, 0x7f, 0xe6, 0x3e, 0xfd, 0x6a, 0x0e, 0x0f, 0x85, 0x05, 0xc2, 0xda, 0x8e, 0x54, 0x21, 0xb4, 0x46, 0x58, - 0xfb, 0xe1, 0x5a, 0xa2, 0xe4, 0xf9, 0x22, 0x38, 0xb5, 0xc9, 0x5b, 0x6e, 0x8e, 0x6d, 0xa0, 0x6d, 0x54, 0xb3, 0x83, - 0x83, 0x98, 0x25, 0x25, 0x62, 0x90, 0xfd, 0xb6, 0x5b, 0xa4, 0x00, 0x5a, 0xdf, 0x18, 0x37, 0xf4, 0x6c, 0x18, 0x9c, - 0x7d, 0x96, 0x08, 0xf9, 0x30, 0xcb, 0x98, 0x52, 0xb2, 0x38, 0x38, 0xd8, 0x37, 0xe5, 0x4b, 0xce, 0x02, 0x16, 0xf1, - 0xf5, 0x8d, 0xa8, 0x86, 0x80, 0xaa, 0xd3, 0xd6, 0xf3, 0x4d, 0xa4, 0xe2, 0x9b, 0x3c, 0x13, 0x92, 0x46, 0xd7, 0xd7, - 0x51, 0x43, 0x63, 0x07, 0x87, 0x09, 0xf3, 0x5d, 0xdf, 0x3d, 0x61, 0x96, 0x2d, 0x34, 0x4c, 0xc8, 0x16, 0x68, 0x76, - 0xf2, 0x83, 0x71, 0x7d, 0x48, 0x58, 0x63, 0x85, 0xd6, 0xc1, 0x8a, 0xee, 0x6c, 0xda, 0xf0, 0x37, 0x76, 0xe9, 0x96, - 0x13, 0xc3, 0x53, 0x04, 0xeb, 0xd8, 0x67, 0x83, 0x35, 0x36, 0xb0, 0xf7, 0xb3, 0x91, 0x66, 0xa0, 0x7d, 0x3d, 0xe8, - 0xba, 0x7c, 0xa2, 0x2c, 0xe4, 0x0a, 0xf6, 0xf7, 0x82, 0x29, 0x6d, 0x11, 0x39, 0xd6, 0x58, 0x62, 0x38, 0xa3, 0x36, - 0x99, 0xce, 0x1a, 0x4b, 0xba, 0x6b, 0x6c, 0xaf, 0xe7, 0x70, 0x36, 0x2a, 0x40, 0xea, 0xef, 0xe3, 0x13, 0x8c, 0x55, - 0xa3, 0xd5, 0xea, 0x2d, 0xf7, 0xad, 0x54, 0x6b, 0x59, 0xf2, 0x6b, 0x1b, 0x8b, 0xc2, 0x04, 0x72, 0x87, 0xf3, 0x7e, - 0xdb, 0x8d, 0x5f, 0x0c, 0xc8, 0x7e, 0xab, 0xc4, 0x62, 0x07, 0x56, 0x3b, 0x1e, 0x0b, 0xc5, 0xd7, 0xb6, 0x29, 0x64, - 0xce, 0xfa, 0x1a, 0xbe, 0x24, 0xd3, 0x2d, 0x5c, 0x9d, 0x92, 0x3e, 0x70, 0x1d, 0xc9, 0x74, 0xf0, 0x2d, 0x7c, 0xf2, - 0x14, 0x21, 0xd6, 0xdb, 0x79, 0x15, 0xe1, 0xf8, 0x5a, 0x27, 0x1c, 0x1b, 0xd3, 0x88, 0xe6, 0x65, 0x95, 0xa8, 0x44, - 0x33, 0xb7, 0xd5, 0xab, 0x2c, 0x2c, 0xcc, 0x60, 0xaa, 0x29, 0x05, 0x4d, 0xbc, 0xa2, 0x33, 0xa6, 0x62, 0x86, 0xf0, - 0xb7, 0x0a, 0x58, 0xfc, 0x84, 0x22, 0x83, 0xe0, 0x0c, 0x55, 0x70, 0x86, 0x02, 0xbb, 0x0b, 0x4c, 0x5a, 0x7d, 0xcb, - 0x29, 0xcc, 0xfa, 0x6a, 0x50, 0xf1, 0x76, 0xc1, 0xe4, 0xcd, 0xe1, 0xec, 0x10, 0xdc, 0xc3, 0xcf, 0xa6, 0x59, 0xa0, - 0x19, 0x16, 0x42, 0x21, 0xbc, 0xdf, 0xda, 0x5c, 0x49, 0x5f, 0xaa, 0x9a, 0x63, 0x7f, 0x00, 0xeb, 0x60, 0x8e, 0x8d, - 0x84, 0x2b, 0xf3, 0xb7, 0xb6, 0xd5, 0x00, 0x6c, 0x57, 0x80, 0x19, 0xc9, 0x38, 0xa7, 0x3a, 0x6e, 0x1f, 0xb5, 0x80, - 0x31, 0xfd, 0xca, 0xe0, 0x54, 0x41, 0x68, 0x7b, 0x2a, 0x2c, 0x59, 0x08, 0x35, 0xe5, 0x63, 0x1d, 0xff, 0x2e, 0x0c, - 0x51, 0x61, 0xb9, 0x62, 0x20, 0xe1, 0x04, 0xec, 0xb1, 0x21, 0x38, 0xbf, 0x0b, 0xe8, 0xa7, 0x5b, 0x1e, 0x44, 0x6e, - 0xa4, 0x86, 0x70, 0x01, 0x79, 0xa8, 0x58, 0xeb, 0x8a, 0xcc, 0x94, 0x8c, 0x1b, 0x70, 0x8f, 0xed, 0x9e, 0x6d, 0x31, - 0x75, 0xd4, 0x40, 0x04, 0x1c, 0xac, 0x48, 0x43, 0x12, 0xe1, 0x12, 0x75, 0xa2, 0xe5, 0x4b, 0x79, 0xc3, 0x8a, 0xc7, - 0x14, 0x06, 0x9f, 0xda, 0xea, 0x6b, 0x7b, 0x14, 0x18, 0x8a, 0xaf, 0xbb, 0x1e, 0x5f, 0xae, 0xcd, 0xc4, 0xdf, 0x14, - 0x72, 0xc6, 0x15, 0x03, 0xbe, 0xcd, 0xc2, 0x5f, 0xc0, 0x46, 0x33, 0x3b, 0x12, 0x8e, 0x1b, 0x56, 0xe2, 0xd7, 0xc3, - 0x97, 0x75, 0xfc, 0xba, 0xbe, 0xf7, 0x74, 0xe2, 0x29, 0x60, 0x7d, 0x1f, 0x23, 0x1c, 0x3b, 0xf1, 0x22, 0x38, 0xe9, - 0x92, 0x29, 0x72, 0xc7, 0xfc, 0x6a, 0xa5, 0x03, 0x31, 0xae, 0xc6, 0x39, 0x32, 0xbb, 0x6d, 0xd0, 0x9a, 0x8e, 0x46, - 0xc0, 0xe2, 0x15, 0x32, 0xcf, 0x83, 0xc3, 0x0a, 0x8b, 0x6e, 0x79, 0x3c, 0x5d, 0xdf, 0x7b, 0x7a, 0xf5, 0xbd, 0x13, - 0x0a, 0xf2, 0xc3, 0x43, 0xca, 0x0f, 0x54, 0x8c, 0x58, 0x01, 0x72, 0x65, 0xb0, 0x5a, 0xee, 0x9c, 0x7d, 0x2c, 0x85, - 0x60, 0x99, 0x66, 0x23, 0x10, 0x5a, 0x04, 0xd1, 0xc9, 0x54, 0x2a, 0x5d, 0x26, 0x56, 0xa3, 0x17, 0xa1, 0x10, 0x9a, - 0x64, 0x34, 0xcf, 0x63, 0x2b, 0xa0, 0xcc, 0xe4, 0x57, 0xb6, 0x63, 0xd4, 0xdd, 0xda, 0x90, 0xcb, 0x66, 0x58, 0xd0, - 0x0c, 0x4b, 0xd4, 0x3c, 0xe7, 0x19, 0x2b, 0x0f, 0xaf, 0xab, 0x84, 0x8b, 0x11, 0xbb, 0x05, 0x3a, 0x82, 0x2e, 0x2f, - 0x2f, 0x5b, 0xb8, 0x8d, 0xd6, 0x16, 0xe0, 0xcb, 0x2d, 0xc0, 0x7e, 0xe7, 0xd8, 0xb4, 0x82, 0xf8, 0x72, 0x27, 0x59, - 0x43, 0xc1, 0x59, 0xc9, 0xbd, 0xa0, 0x65, 0xc9, 0x33, 0xc2, 0x23, 0x96, 0x33, 0xcd, 0x3c, 0x39, 0x07, 0x66, 0xda, - 0x6e, 0xdd, 0xb7, 0x25, 0xfc, 0x4a, 0x74, 0xf2, 0xbb, 0xcc, 0xaf, 0xb9, 0x2a, 0x45, 0xf7, 0x6a, 0x79, 0x2a, 0x68, - 0xf7, 0xb4, 0x5d, 0x1e, 0xaa, 0x35, 0xcd, 0xa6, 0x56, 0x62, 0x8f, 0xb7, 0xa6, 0x54, 0xb5, 0xe1, 0x48, 0x7b, 0xb9, - 0x89, 0xfe, 0x2c, 0xdc, 0x30, 0x77, 0x81, 0xe0, 0xca, 0x11, 0x05, 0x06, 0x42, 0xa0, 0x5d, 0xb6, 0xc7, 0x34, 0xcf, - 0x87, 0x34, 0xfb, 0x52, 0xc7, 0xfe, 0x0a, 0x0d, 0xc8, 0x26, 0x35, 0x0e, 0xb2, 0x02, 0x92, 0x15, 0xce, 0xdb, 0x53, - 0xe9, 0xda, 0x46, 0x89, 0xf7, 0x5b, 0x15, 0xda, 0xd7, 0x17, 0xfa, 0x9b, 0xd8, 0x6e, 0x46, 0x24, 0xdc, 0xcc, 0x62, - 0xa0, 0x02, 0xff, 0x12, 0xe3, 0x3c, 0x3d, 0x70, 0x78, 0x07, 0x82, 0xc7, 0x7a, 0x63, 0x20, 0x1a, 0x2d, 0xd7, 0x23, - 0xae, 0xbe, 0x0d, 0x81, 0xff, 0x2d, 0xa3, 0x7c, 0x12, 0xf4, 0xf0, 0xef, 0x0e, 0xb4, 0xa4, 0x71, 0x8e, 0x71, 0x2e, - 0x47, 0xe6, 0x18, 0x0a, 0x4f, 0x68, 0x7e, 0x01, 0xe6, 0xc5, 0xe0, 0xfb, 0x6b, 0x9b, 0x65, 0xf8, 0x32, 0x18, 0x86, - 0xea, 0x86, 0x0c, 0x45, 0x0d, 0x05, 0x1c, 0x51, 0x15, 0xe6, 0xcc, 0x95, 0x35, 0x51, 0xd2, 0x71, 0xed, 0x56, 0x1c, - 0x77, 0x34, 0xb7, 0x20, 0x71, 0x1c, 0x2b, 0x90, 0xe6, 0x3c, 0x7f, 0x5f, 0xcd, 0x42, 0x6d, 0xcd, 0x42, 0x25, 0x81, - 0xb4, 0x85, 0x2a, 0x64, 0x0e, 0xaa, 0xa7, 0x5a, 0xa0, 0xb0, 0x14, 0xb0, 0xac, 0x09, 0x50, 0x68, 0x54, 0x12, 0xdc, - 0x9c, 0x68, 0x5c, 0x38, 0x51, 0xc7, 0xe1, 0x1a, 0x90, 0x8c, 0xaa, 0x8a, 0x44, 0x76, 0x73, 0xd4, 0x64, 0x5f, 0x89, - 0x0b, 0xb4, 0xc1, 0xdf, 0xaf, 0xd7, 0x0e, 0x4a, 0x0c, 0xb9, 0xd5, 0xa9, 0x31, 0xc6, 0x01, 0x58, 0xb0, 0x24, 0x8e, - 0x19, 0xb6, 0xac, 0xcf, 0x26, 0x70, 0xca, 0x76, 0xf7, 0x09, 0x91, 0x15, 0x6c, 0x6a, 0x4c, 0xa5, 0xe7, 0xae, 0x24, - 0xc2, 0xd4, 0xb3, 0xa5, 0x45, 0x35, 0x71, 0x42, 0x22, 0xaf, 0x9d, 0x88, 0x7a, 0xcb, 0x9a, 0x70, 0x98, 0x06, 0xc5, - 0xd6, 0x29, 0x10, 0xd5, 0x62, 0x17, 0xbc, 0x77, 0x61, 0x4d, 0xad, 0x9d, 0x00, 0xe2, 0x45, 0x0d, 0xe2, 0x01, 0x68, - 0xa5, 0x25, 0x5e, 0x72, 0x40, 0x68, 0xbd, 0x72, 0xcc, 0x70, 0x61, 0x17, 0x62, 0x0b, 0x8a, 0x9b, 0xec, 0xa7, 0xc1, - 0x42, 0x90, 0x65, 0x15, 0xf0, 0x77, 0xe1, 0x11, 0x11, 0xc3, 0xe0, 0xc5, 0x6a, 0xb5, 0x85, 0x76, 0x3b, 0xb9, 0x50, - 0x94, 0x54, 0xd2, 0xe1, 0x6a, 0xf5, 0x4a, 0xa2, 0xd8, 0xf1, 0xbf, 0x98, 0xa1, 0x9e, 0x27, 0xba, 0x0f, 0x5f, 0x42, - 0x29, 0xc3, 0x8e, 0x56, 0x29, 0xa5, 0xe0, 0x50, 0xc7, 0xda, 0xfa, 0x42, 0xe9, 0x80, 0x72, 0x3f, 0xde, 0x22, 0x60, - 0x26, 0xd1, 0x9d, 0xd4, 0xd5, 0x94, 0x1f, 0xbb, 0xa6, 0x05, 0x42, 0x28, 0x55, 0x46, 0x96, 0xd9, 0xdf, 0x25, 0x5f, - 0x1e, 0x1c, 0xa8, 0xa0, 0xa1, 0xeb, 0x92, 0x52, 0x7c, 0x8e, 0xe1, 0x54, 0x56, 0x77, 0xc2, 0xb0, 0x2f, 0x9f, 0xfd, - 0x39, 0xb4, 0x25, 0x9d, 0xb6, 0xba, 0x20, 0x98, 0xd3, 0x1b, 0xca, 0xf5, 0x5e, 0xd9, 0x8a, 0x15, 0xcc, 0x63, 0x86, - 0x96, 0x8e, 0xdb, 0x48, 0x0a, 0x06, 0xfc, 0x23, 0x90, 0x05, 0xcf, 0x45, 0x5b, 0xc4, 0xcf, 0xa6, 0x0c, 0x54, 0xd9, - 0x9e, 0x91, 0x28, 0xc5, 0xc3, 0x7d, 0x77, 0x90, 0xb8, 0x86, 0x77, 0x8f, 0x7d, 0xbd, 0x59, 0xbd, 0x26, 0x0d, 0xcc, - 0x59, 0x31, 0x96, 0xc5, 0xcc, 0xe7, 0xad, 0x37, 0xbe, 0x1d, 0x71, 0xe4, 0xe3, 0x78, 0x67, 0xdb, 0x4e, 0x04, 0xe8, - 0x6e, 0xc8, 0xde, 0x95, 0xd4, 0x5e, 0x3b, 0x4d, 0xcb, 0x03, 0xd8, 0x2a, 0x08, 0x3d, 0x66, 0xaa, 0x50, 0xca, 0x77, - 0xea, 0xd5, 0xae, 0xd5, 0x9d, 0xec, 0xb7, 0xbb, 0xa5, 0xe4, 0xe7, 0xb1, 0xa1, 0x6b, 0x75, 0x1c, 0xee, 0x54, 0x95, - 0x8b, 0x7c, 0xe4, 0x06, 0x2b, 0x10, 0x66, 0x0e, 0x8f, 0x6e, 0x78, 0x9e, 0x57, 0xa9, 0xff, 0x09, 0x69, 0x57, 0x8e, - 0xb4, 0x4b, 0x4f, 0xda, 0x81, 0x54, 0x00, 0x69, 0xb7, 0xcd, 0x55, 0xd5, 0xe5, 0xd6, 0xf6, 0x94, 0x96, 0xa8, 0x2b, - 0x23, 0x4e, 0x43, 0x7f, 0x0b, 0x3f, 0x02, 0x54, 0x32, 0x5f, 0x5f, 0x62, 0xa7, 0x8f, 0x01, 0x31, 0xd0, 0xea, 0x34, - 0x59, 0xa8, 0xa9, 0xf8, 0x12, 0x23, 0xac, 0xd6, 0xac, 0xc4, 0xec, 0x87, 0x4f, 0x41, 0x69, 0x17, 0x4c, 0x07, 0xce, - 0x31, 0x93, 0xfc, 0x1f, 0xf1, 0x51, 0x7e, 0x76, 0xc2, 0xcd, 0x4e, 0xf9, 0xd9, 0x01, 0xad, 0xaf, 0x66, 0x37, 0xfa, - 0x3e, 0xb5, 0x37, 0xd3, 0x13, 0xe5, 0xf4, 0xaa, 0xf5, 0x5e, 0xad, 0xe2, 0x8d, 0x14, 0xd0, 0xe8, 0x3b, 0x29, 0xa5, - 0x28, 0x5b, 0x07, 0x1a, 0x10, 0x42, 0x06, 0x12, 0xd6, 0x76, 0xd2, 0xe5, 0x29, 0xf7, 0xf2, 0x5f, 0xe9, 0x79, 0x8c, - 0xe2, 0xde, 0xd6, 0x7f, 0x2c, 0x67, 0x73, 0x60, 0xc8, 0x36, 0x50, 0x7a, 0xc2, 0x5c, 0x87, 0x55, 0xfe, 0x7a, 0x47, - 0x5a, 0xad, 0x8e, 0xd9, 0x8f, 0x35, 0x6c, 0x2a, 0xa5, 0xe6, 0xfd, 0xd6, 0x7a, 0x51, 0x26, 0x95, 0x84, 0x63, 0x97, - 0x6e, 0xe5, 0xf1, 0xa6, 0x66, 0xc6, 0x67, 0xbc, 0x8e, 0x85, 0xa5, 0xc3, 0x02, 0x68, 0x5d, 0x40, 0x7e, 0x3c, 0xba, - 0x87, 0xeb, 0xbf, 0xae, 0x80, 0xb3, 0x5c, 0x6f, 0x80, 0x6f, 0xb9, 0x5e, 0xbf, 0xd7, 0x4e, 0xd2, 0xc6, 0xef, 0x77, - 0xc8, 0xbd, 0x25, 0xf4, 0xaa, 0x4c, 0x27, 0x33, 0xf6, 0x07, 0x90, 0xb6, 0xc5, 0x42, 0x92, 0xe5, 0x4c, 0x8e, 0x58, - 0x1a, 0xc9, 0x39, 0x13, 0xd1, 0x1a, 0xf4, 0xac, 0x0e, 0x01, 0xfe, 0x16, 0xf1, 0xf2, 0x6d, 0x5d, 0xdf, 0x9a, 0xbe, - 0xd7, 0x6b, 0x50, 0x85, 0xbd, 0xe4, 0x3b, 0x94, 0xb1, 0xef, 0x59, 0xa1, 0x0c, 0x4f, 0x5a, 0xb2, 0xb7, 0x2f, 0x79, - 0x75, 0x40, 0xbd, 0xe4, 0xe9, 0xb7, 0xab, 0x54, 0x02, 0x49, 0xd4, 0x4e, 0xce, 0x92, 0xe3, 0x08, 0x19, 0x8d, 0xf1, - 0x33, 0xaf, 0x31, 0x5e, 0x94, 0x1a, 0xe3, 0xe7, 0x9a, 0x2c, 0x36, 0x34, 0xc6, 0x7f, 0x08, 0xf2, 0x5c, 0xf7, 0x9e, - 0x7b, 0x6d, 0xfa, 0x1b, 0x99, 0xf3, 0xec, 0x2e, 0x8e, 0x72, 0xae, 0x9b, 0x70, 0x9b, 0x18, 0xe1, 0xa5, 0xcd, 0x00, - 0x55, 0xa3, 0xd1, 0x77, 0xaf, 0xbd, 0xfc, 0x87, 0x85, 0x20, 0xd1, 0xbd, 0x9c, 0xeb, 0x7b, 0x11, 0x9e, 0x6a, 0xf2, - 0x09, 0x7e, 0xdd, 0x5b, 0xc6, 0xbf, 0x52, 0x3d, 0x4d, 0x0a, 0x2a, 0x46, 0x72, 0x16, 0xa3, 0x46, 0x14, 0xa1, 0x44, - 0x19, 0x21, 0xe4, 0x01, 0x5a, 0xdf, 0xfb, 0x84, 0xff, 0x91, 0x24, 0xea, 0x45, 0x8d, 0xa9, 0xc6, 0x9a, 0x92, 0x4f, - 0x17, 0xf7, 0x96, 0xff, 0xc8, 0xf5, 0xe5, 0x27, 0xfc, 0x54, 0x97, 0x6a, 0x7d, 0x7c, 0xcb, 0x48, 0x8c, 0xc8, 0xe5, - 0x53, 0x3f, 0xa4, 0xc7, 0x72, 0x66, 0x15, 0xfc, 0x11, 0xc2, 0x5f, 0x41, 0xaf, 0x7b, 0xc9, 0x2b, 0x22, 0xe4, 0xee, - 0x60, 0xf6, 0x49, 0x24, 0x8d, 0xf2, 0x20, 0x3a, 0x38, 0x08, 0xd2, 0x4a, 0x16, 0x02, 0x7f, 0x96, 0xa4, 0x26, 0xaa, - 0x63, 0x46, 0xa1, 0xa5, 0xcf, 0x32, 0xe6, 0xc8, 0x37, 0x13, 0x7b, 0x4d, 0xb5, 0xdb, 0xb1, 0xbc, 0x6f, 0x75, 0x0f, - 0x09, 0xd7, 0xac, 0xa0, 0x5a, 0x16, 0x03, 0x14, 0xb2, 0x25, 0xf8, 0x15, 0x27, 0x9f, 0xfa, 0x7b, 0xff, 0xcf, 0xff, - 0xf8, 0x6b, 0xfc, 0x57, 0x31, 0xf8, 0x84, 0x05, 0x23, 0x47, 0x17, 0x71, 0x2f, 0x8d, 0xf7, 0x9b, 0xcd, 0xd5, 0x5f, - 0x47, 0xfd, 0xff, 0xa6, 0xcd, 0x7f, 0x1e, 0x36, 0xff, 0x1c, 0xa0, 0x55, 0xfc, 0xd7, 0x51, 0xaf, 0xef, 0xbe, 0xfa, - 0xff, 0x7d, 0xf9, 0x97, 0x1a, 0x1c, 0xda, 0xc4, 0x7b, 0x08, 0x1d, 0x4d, 0xf0, 0x2f, 0x82, 0x1c, 0x35, 0x9b, 0x97, - 0x47, 0x13, 0xfc, 0x93, 0x20, 0x47, 0xf0, 0xf7, 0x4e, 0x93, 0xb7, 0x6c, 0xf2, 0xf4, 0x76, 0x1e, 0x7f, 0xba, 0x5c, - 0xdd, 0x5b, 0xbe, 0xe2, 0x6b, 0x68, 0xb7, 0xff, 0xdf, 0x7f, 0xfd, 0xa5, 0xa2, 0x1f, 0x2f, 0xc9, 0xd1, 0xa0, 0x81, - 0x62, 0x93, 0x7c, 0x48, 0xec, 0x9f, 0xb8, 0x97, 0xf6, 0xff, 0xdb, 0x0d, 0x25, 0xfa, 0xf1, 0xaf, 0x4f, 0x17, 0x97, - 0x64, 0xb0, 0x8a, 0xa3, 0xd5, 0x8f, 0x68, 0x85, 0xd0, 0xea, 0x1e, 0xfa, 0x84, 0xa3, 0x49, 0x84, 0xf0, 0x6f, 0x82, - 0x1c, 0xfd, 0x78, 0x34, 0xc1, 0x7f, 0x0a, 0x72, 0x14, 0x1d, 0x4d, 0xf0, 0x23, 0x49, 0x8e, 0xfe, 0x3b, 0xee, 0xa5, - 0x56, 0x09, 0xb7, 0x32, 0xea, 0x8f, 0x15, 0xdc, 0x84, 0xd0, 0x82, 0xd1, 0x95, 0xe6, 0x3a, 0x67, 0xe8, 0xde, 0x11, - 0xc7, 0xef, 0x25, 0x00, 0x2b, 0xd6, 0xa0, 0xa4, 0x31, 0x97, 0xb0, 0xcb, 0x6b, 0x58, 0x78, 0xc0, 0xa0, 0x7b, 0x29, - 0xc7, 0x56, 0x4f, 0xa0, 0x52, 0x6d, 0x6f, 0x6f, 0x15, 0x5c, 0xdf, 0xe2, 0xc7, 0xe4, 0xbd, 0x8c, 0xdb, 0x08, 0x73, - 0x0a, 0x3f, 0x3a, 0x08, 0x7f, 0xd0, 0xee, 0xc2, 0x13, 0xb6, 0xb9, 0xc5, 0x30, 0x21, 0x2d, 0x3f, 0x13, 0x21, 0xfc, - 0x72, 0x47, 0xa6, 0x9e, 0x82, 0xfa, 0x01, 0xe1, 0x9f, 0x6b, 0xd7, 0xa3, 0xf8, 0xb1, 0x26, 0x25, 0x72, 0xbc, 0x2b, - 0x18, 0xfb, 0x40, 0xf3, 0x2f, 0xac, 0x88, 0x9f, 0x6a, 0xdc, 0xee, 0x3c, 0xc0, 0x46, 0x55, 0xbd, 0xdf, 0x46, 0xdd, - 0xf2, 0x76, 0xeb, 0xb9, 0xb4, 0xf7, 0x09, 0x70, 0x0a, 0xd7, 0xf5, 0x35, 0xb0, 0xf6, 0xfb, 0x7c, 0x4b, 0xa9, 0x55, - 0xd0, 0x9b, 0x08, 0xd5, 0xaf, 0x52, 0xb9, 0xf8, 0x4a, 0x73, 0x3e, 0xda, 0xd3, 0x6c, 0x36, 0xcf, 0xa9, 0x66, 0x7b, - 0x6e, 0xce, 0x7b, 0x14, 0x1a, 0x8a, 0x4a, 0x9e, 0xe2, 0x0f, 0x51, 0x6d, 0xda, 0x3f, 0x44, 0x52, 0xed, 0x9d, 0x18, - 0xee, 0xb3, 0x1c, 0x5f, 0x22, 0x68, 0x79, 0x5d, 0xb6, 0x79, 0x23, 0xd8, 0x6c, 0x83, 0xb2, 0x6c, 0x60, 0xce, 0x6f, - 0x85, 0xe1, 0x7e, 0x93, 0x90, 0x4e, 0x2f, 0xba, 0x50, 0x5f, 0x27, 0x97, 0x11, 0xdc, 0xe4, 0x14, 0x44, 0x30, 0xa3, - 0x3c, 0x82, 0x12, 0x94, 0xb4, 0xba, 0xf4, 0x82, 0x75, 0x69, 0xa3, 0xe1, 0xd9, 0xec, 0x8c, 0xf0, 0x3e, 0xb5, 0xf5, - 0x73, 0x3c, 0xc5, 0x23, 0xd2, 0x6c, 0xe3, 0x05, 0x69, 0x99, 0x2a, 0xdd, 0xc5, 0x45, 0xe6, 0xfa, 0x39, 0x38, 0x88, - 0x8b, 0x24, 0xa7, 0x4a, 0xbf, 0x00, 0x8d, 0x00, 0x59, 0xe0, 0x29, 0x29, 0x12, 0x76, 0xcb, 0xb2, 0x38, 0x43, 0x78, - 0xea, 0x68, 0x10, 0xea, 0xa2, 0x05, 0x09, 0x8a, 0x81, 0x9c, 0x41, 0x04, 0xeb, 0x4d, 0xfb, 0xed, 0x01, 0x21, 0x24, - 0xda, 0x6f, 0x36, 0xa3, 0x5e, 0x41, 0x7e, 0x11, 0x29, 0xa4, 0x04, 0xec, 0x34, 0xf9, 0x09, 0x92, 0x3a, 0x41, 0x52, - 0xfc, 0x48, 0x26, 0x9a, 0x29, 0x1d, 0x43, 0x32, 0x28, 0x09, 0x94, 0xc7, 0xf0, 0xe8, 0xe2, 0x28, 0x6a, 0x40, 0xaa, - 0x41, 0x51, 0x84, 0x0b, 0x72, 0xa7, 0x51, 0x3a, 0xed, 0x1f, 0x0f, 0xc2, 0x33, 0xc2, 0xa6, 0x42, 0xff, 0x77, 0xba, - 0x37, 0xed, 0xb7, 0x4c, 0xff, 0x97, 0x51, 0x2f, 0x2e, 0x88, 0xb2, 0x6c, 0x5c, 0x4f, 0xa5, 0x82, 0x99, 0xf9, 0xa2, - 0xd4, 0x0d, 0xd0, 0xf5, 0x3d, 0x22, 0xcd, 0x4e, 0x1a, 0x8f, 0xc2, 0x99, 0x34, 0xa1, 0x43, 0x07, 0x0a, 0x9c, 0x13, - 0x28, 0x8f, 0x0b, 0x02, 0x9d, 0x56, 0xd5, 0xee, 0x74, 0xea, 0x12, 0x7e, 0x8c, 0x7e, 0xec, 0xfd, 0x29, 0xd2, 0xdf, - 0x84, 0x1d, 0xc1, 0x9f, 0x62, 0xb5, 0x82, 0xbf, 0xbf, 0x89, 0x1e, 0x0c, 0xcb, 0xa4, 0xfd, 0xe2, 0xd2, 0x7e, 0x82, - 0x34, 0xc1, 0x52, 0x33, 0x60, 0xac, 0x4a, 0x7e, 0xcc, 0x2e, 0xce, 0x98, 0xd8, 0x19, 0x1c, 0x1c, 0xf0, 0x3e, 0x6d, - 0xb4, 0x07, 0x70, 0x23, 0x50, 0x68, 0xf5, 0x81, 0xeb, 0x69, 0x1c, 0x1d, 0x5d, 0x46, 0xa8, 0x17, 0xed, 0xc1, 0x2a, - 0x77, 0x65, 0x83, 0x38, 0x58, 0x67, 0x0d, 0x4d, 0xd3, 0xd1, 0x25, 0x69, 0xf5, 0x62, 0x61, 0x89, 0x7c, 0x8e, 0x70, - 0xe6, 0x68, 0x6a, 0x0b, 0x8f, 0x50, 0x43, 0x88, 0x86, 0xff, 0x1e, 0xa1, 0xc6, 0x54, 0x37, 0xc6, 0x28, 0xcd, 0xe0, - 0x6f, 0x3c, 0x22, 0x84, 0x34, 0x3b, 0x65, 0x45, 0x7f, 0x58, 0x52, 0x94, 0x8e, 0xbd, 0x7a, 0xb4, 0x6f, 0x36, 0x87, - 0x6c, 0xc4, 0xbc, 0xcf, 0x06, 0xab, 0x55, 0x74, 0xd1, 0xbb, 0x8c, 0x50, 0x23, 0xf6, 0x68, 0x77, 0xe4, 0xf1, 0x0e, - 0x21, 0x2c, 0x06, 0x6b, 0x77, 0x03, 0x75, 0xc3, 0x6a, 0xb7, 0x4d, 0xcb, 0x6a, 0xff, 0x07, 0x64, 0x81, 0xad, 0x4b, - 0xb9, 0xc7, 0xf2, 0xb7, 0x73, 0x98, 0xaa, 0xc7, 0x6d, 0x49, 0x5a, 0xb8, 0x20, 0x5e, 0xdd, 0x4d, 0x89, 0xae, 0xf0, - 0x3f, 0x23, 0x55, 0x71, 0xdc, 0xcf, 0xf1, 0x74, 0x40, 0x04, 0x35, 0xf2, 0x4b, 0xd7, 0x2b, 0xd3, 0x59, 0x4e, 0x6e, - 0xd8, 0xc6, 0xfd, 0x6f, 0x0e, 0x77, 0x32, 0x8f, 0x75, 0x92, 0x2d, 0x8a, 0x82, 0x09, 0xfd, 0x4a, 0x8e, 0x1c, 0x63, - 0xc7, 0x72, 0x90, 0xad, 0xe0, 0x62, 0x17, 0x03, 0x57, 0xd7, 0xf1, 0x3b, 0x65, 0xb4, 0x95, 0xbd, 0x20, 0x23, 0xcb, - 0x70, 0x99, 0xeb, 0xde, 0xee, 0xc2, 0x89, 0xd2, 0x31, 0xc2, 0x23, 0x77, 0x0f, 0x1c, 0x27, 0x49, 0xb2, 0x48, 0x32, - 0xc8, 0x86, 0x0e, 0x14, 0x5a, 0x9b, 0x7d, 0x15, 0x2b, 0xf2, 0x58, 0x27, 0x82, 0xdd, 0x9a, 0x6e, 0x63, 0x54, 0x1d, - 0xe2, 0x7e, 0xbf, 0x5d, 0xd0, 0xae, 0x21, 0x40, 0x2a, 0x11, 0x72, 0xc4, 0x00, 0x42, 0x70, 0xf7, 0xef, 0x92, 0xa6, - 0x54, 0x85, 0x37, 0x5b, 0xd5, 0x00, 0xfb, 0xa1, 0xca, 0x7b, 0x01, 0x7a, 0x62, 0xc3, 0x9e, 0x95, 0x85, 0xad, 0xf2, - 0x1c, 0x21, 0x3e, 0x8e, 0x17, 0x09, 0xdc, 0x08, 0x1a, 0x4c, 0x12, 0x02, 0xad, 0x56, 0x8b, 0x10, 0xb7, 0xa6, 0x95, - 0x62, 0x7a, 0x4c, 0xa6, 0xfd, 0xa2, 0xd1, 0x30, 0xca, 0xeb, 0x91, 0xc5, 0x8b, 0x05, 0xc2, 0xe3, 0x72, 0xaf, 0xf9, - 0x72, 0x73, 0x52, 0xef, 0x2a, 0x1e, 0xd7, 0x95, 0xc0, 0x0d, 0x21, 0x90, 0xd1, 0x2f, 0x6a, 0x68, 0x1d, 0x4f, 0xc8, - 0x51, 0xdc, 0x4f, 0x7a, 0xff, 0x73, 0x80, 0x7a, 0x71, 0x72, 0x88, 0x8e, 0x2c, 0x2d, 0x19, 0xa3, 0x6e, 0x66, 0xfb, - 0x58, 0x9a, 0xdb, 0xcf, 0x36, 0x36, 0x0a, 0xc8, 0x54, 0x62, 0x41, 0x67, 0x2c, 0x9d, 0xc0, 0xae, 0xf7, 0xc8, 0x33, - 0xc7, 0x80, 0x4c, 0xe9, 0xc4, 0xd1, 0x96, 0x24, 0xea, 0x49, 0x5a, 0x7e, 0xf5, 0xa2, 0x1e, 0xad, 0xbe, 0xfe, 0x67, - 0xd4, 0xcb, 0x68, 0xfa, 0x98, 0xaf, 0x9d, 0x92, 0xbc, 0xd6, 0xc7, 0x99, 0xef, 0x63, 0x6d, 0x17, 0x27, 0x00, 0xde, - 0x08, 0x6d, 0x6b, 0x47, 0x16, 0x68, 0xcd, 0xc7, 0x25, 0x75, 0x52, 0x89, 0xa6, 0x13, 0x80, 0x6a, 0xb0, 0x08, 0x2a, - 0xb4, 0x0d, 0x08, 0xa6, 0x0c, 0xd8, 0xe2, 0x91, 0x16, 0xa0, 0xb9, 0xb8, 0x6c, 0xa1, 0x65, 0xad, 0xb0, 0xe3, 0xac, - 0xea, 0x77, 0xf1, 0x25, 0xf1, 0x1e, 0x03, 0x55, 0xbe, 0x58, 0x74, 0xc7, 0x8d, 0x06, 0x52, 0x1e, 0xbf, 0x46, 0xfd, - 0xf1, 0x00, 0xdf, 0x02, 0x0a, 0xe1, 0x1a, 0x46, 0xe1, 0xda, 0x1c, 0x3b, 0x6e, 0x8e, 0x8d, 0x86, 0x5c, 0xa3, 0x6e, - 0x50, 0x79, 0xe1, 0x2a, 0xaf, 0xd7, 0x16, 0x32, 0x9b, 0x18, 0x77, 0x8e, 0x4c, 0x0a, 0x18, 0x82, 0x11, 0x42, 0xfe, - 0x91, 0x68, 0x67, 0xb3, 0xd0, 0x28, 0x54, 0x37, 0xbb, 0x17, 0x28, 0xaa, 0x3d, 0x3d, 0x62, 0x80, 0x05, 0x54, 0x2d, - 0xd5, 0xc8, 0x53, 0x8d, 0x47, 0x8d, 0xb6, 0x41, 0xf7, 0x66, 0xbb, 0x5b, 0x6f, 0xec, 0x7e, 0xd5, 0x18, 0x1e, 0x35, - 0xc8, 0xb4, 0xda, 0xe1, 0x6b, 0xd9, 0x68, 0xac, 0xeb, 0xf7, 0xa5, 0x7e, 0x13, 0xd7, 0xee, 0x2f, 0x9e, 0x6e, 0x99, - 0x78, 0xf8, 0xd3, 0xb7, 0x3a, 0x6f, 0x45, 0xc2, 0x85, 0x60, 0x05, 0x9c, 0xb0, 0x44, 0x63, 0xb1, 0x5e, 0x97, 0xa7, - 0xfe, 0xef, 0xda, 0xda, 0x8c, 0x11, 0x0e, 0x74, 0xc8, 0x48, 0x6d, 0x58, 0xe2, 0x02, 0x53, 0x43, 0x45, 0x08, 0x21, - 0x1f, 0xb4, 0x37, 0x8f, 0xd1, 0x86, 0x24, 0x65, 0x24, 0x38, 0xbb, 0x63, 0x45, 0x58, 0x72, 0x7d, 0xef, 0xb1, 0xfc, - 0xae, 0x48, 0xd7, 0x17, 0x83, 0xd4, 0x14, 0xcb, 0x1d, 0x21, 0xcb, 0xc9, 0x57, 0x90, 0x73, 0xca, 0x0b, 0x96, 0xc4, - 0x10, 0xc4, 0x27, 0xbc, 0x60, 0x86, 0x71, 0xbf, 0xe7, 0xe5, 0xc6, 0xac, 0xce, 0x69, 0x66, 0xa1, 0xf6, 0x07, 0xa0, - 0x99, 0x83, 0x72, 0x48, 0x92, 0xad, 0x62, 0xd7, 0xf7, 0x1e, 0xbe, 0xde, 0x25, 0x43, 0xaf, 0x56, 0x4e, 0x7a, 0xce, - 0x80, 0xf5, 0xc1, 0x79, 0x35, 0xd4, 0xcc, 0xfd, 0x48, 0xe3, 0xcc, 0x30, 0x51, 0x79, 0xcc, 0x01, 0x99, 0xae, 0xef, - 0x3d, 0x7c, 0x17, 0x73, 0xa3, 0x9b, 0x42, 0x38, 0x9c, 0x77, 0x5c, 0x90, 0x98, 0x12, 0x86, 0xec, 0xe4, 0x4b, 0x3a, - 0x56, 0x04, 0xa7, 0x7b, 0x4a, 0x4d, 0x26, 0x88, 0x1d, 0x7d, 0x31, 0x20, 0x99, 0x03, 0x01, 0xc9, 0x10, 0xce, 0x6a, - 0x72, 0x1d, 0x31, 0x6b, 0x60, 0x3a, 0xbb, 0x82, 0xc5, 0x48, 0x2c, 0x7b, 0x88, 0x70, 0x66, 0xba, 0xd5, 0x6b, 0x7b, - 0x9c, 0x28, 0xba, 0x69, 0xe8, 0x56, 0xc9, 0xb3, 0xef, 0x41, 0xf0, 0xf2, 0x1f, 0xaf, 0x5c, 0xdb, 0x65, 0xc2, 0x13, - 0x6f, 0x91, 0x76, 0x7d, 0xef, 0xe1, 0xaf, 0xce, 0x28, 0x6d, 0x4e, 0x3d, 0xf9, 0xdf, 0x92, 0x51, 0x1f, 0xfe, 0x9a, - 0x54, 0xb9, 0xa6, 0xf0, 0xf5, 0xbd, 0x87, 0xbf, 0xef, 0x2a, 0x06, 0xe9, 0xeb, 0x45, 0xa5, 0x24, 0x30, 0xe3, 0x5b, - 0xb2, 0x3c, 0x5d, 0xba, 0xb3, 0x22, 0x15, 0x6b, 0x6c, 0x4e, 0xa8, 0x54, 0xad, 0x4b, 0xdd, 0xca, 0x13, 0x2c, 0x89, - 0xb9, 0x4a, 0xaa, 0x2f, 0x9b, 0x43, 0x63, 0x2e, 0xc5, 0x55, 0x26, 0xe7, 0xec, 0x1b, 0xf7, 0x4b, 0x4f, 0x35, 0x4a, - 0xf8, 0x0c, 0x0c, 0x71, 0xcc, 0xd8, 0x05, 0xde, 0x6f, 0xa1, 0xee, 0xc6, 0x79, 0x26, 0x0d, 0xa2, 0x16, 0xf5, 0xc3, - 0x06, 0x53, 0xd2, 0xc2, 0x19, 0x69, 0xe1, 0x9c, 0xa8, 0x7e, 0xcb, 0x9e, 0x18, 0xdd, 0xbc, 0x6c, 0xda, 0x9e, 0x3b, - 0xb0, 0xdd, 0x73, 0xbb, 0x6f, 0xed, 0xa1, 0x3c, 0xed, 0xe6, 0x46, 0x7f, 0x69, 0x0e, 0xfa, 0xa9, 0x41, 0x8d, 0x27, - 0x2c, 0x2e, 0x70, 0x61, 0x5a, 0xbe, 0xe2, 0xc3, 0x1c, 0xec, 0x54, 0x60, 0x66, 0x58, 0xa3, 0xb4, 0x2c, 0xdb, 0x76, - 0x65, 0xf3, 0xc4, 0xac, 0x55, 0x81, 0xf3, 0x04, 0x48, 0x39, 0xce, 0x9d, 0x5d, 0x8f, 0xda, 0xae, 0x72, 0x76, 0x70, - 0x10, 0xbb, 0x4a, 0x34, 0x2e, 0x7c, 0x7e, 0x75, 0x03, 0xf8, 0xde, 0x52, 0x8d, 0x29, 0x32, 0x13, 0x68, 0x34, 0xb2, - 0xc1, 0x9a, 0xee, 0x13, 0x12, 0xe7, 0x75, 0x28, 0xfa, 0xd1, 0x1b, 0x66, 0x70, 0x03, 0x00, 0x8d, 0x46, 0x79, 0xdd, - 0xbb, 0x01, 0xb1, 0xa7, 0x1a, 0xcb, 0xf5, 0xd7, 0xb8, 0xb4, 0x26, 0x6a, 0x6d, 0xd9, 0x61, 0xf9, 0x51, 0x20, 0x11, - 0xe2, 0xae, 0xf0, 0xf3, 0x09, 0xb6, 0x86, 0x80, 0x72, 0x2f, 0x9c, 0x0d, 0x04, 0x36, 0x56, 0x5b, 0xae, 0x90, 0x27, - 0x6d, 0x1d, 0x94, 0xfa, 0x42, 0x70, 0xc1, 0x05, 0x85, 0x1a, 0x6b, 0x87, 0xe5, 0x4f, 0xd8, 0xb6, 0x39, 0x27, 0x56, - 0xc8, 0x69, 0xcb, 0xcc, 0x30, 0x0c, 0xc0, 0x3a, 0x25, 0x60, 0x9e, 0x93, 0x97, 0xdf, 0x46, 0xfd, 0x87, 0x01, 0xea, - 0x3f, 0x22, 0x2c, 0xd8, 0x06, 0x56, 0x57, 0x92, 0x48, 0xa7, 0xa0, 0x50, 0x3e, 0xeb, 0xf1, 0x9c, 0x80, 0x36, 0xae, - 0x0e, 0xd5, 0xda, 0x15, 0xe5, 0x37, 0x28, 0x4b, 0xb8, 0x53, 0x8c, 0x3e, 0x13, 0xfb, 0xfb, 0xe4, 0xb8, 0xba, 0xa0, - 0x83, 0xae, 0x77, 0x29, 0x07, 0x43, 0x52, 0xf8, 0xf0, 0xf7, 0xef, 0xdf, 0xad, 0x3e, 0x9e, 0x6f, 0xef, 0xe0, 0xc0, - 0xac, 0x14, 0x66, 0x1d, 0x6c, 0xe0, 0xba, 0x91, 0x29, 0xf4, 0x5f, 0xde, 0x89, 0xd7, 0xa9, 0xd0, 0xc6, 0x66, 0xf4, - 0xc7, 0x21, 0x8c, 0xb6, 0xdd, 0x36, 0x25, 0x58, 0xd0, 0x2c, 0xd0, 0x25, 0x6b, 0xdc, 0x4a, 0x8b, 0x6f, 0x90, 0x91, - 0x87, 0xa6, 0x00, 0x13, 0xa3, 0xdd, 0xd9, 0x8f, 0xd6, 0x0e, 0x4f, 0xec, 0xd0, 0xd0, 0xd2, 0x10, 0x42, 0x8b, 0xf7, - 0x80, 0x39, 0xf6, 0x88, 0x00, 0x10, 0xbd, 0x34, 0x90, 0xaa, 0x40, 0x16, 0x45, 0x95, 0x22, 0xff, 0xf9, 0x3e, 0x21, - 0x2f, 0x2b, 0x45, 0xe6, 0xdb, 0xca, 0x98, 0x0b, 0x10, 0x03, 0xa5, 0x70, 0x91, 0x50, 0x26, 0xd8, 0xcb, 0xd0, 0x0f, - 0xda, 0x97, 0x37, 0xd2, 0x66, 0x52, 0x71, 0xe3, 0xc1, 0x4d, 0xa9, 0x51, 0xf1, 0xd9, 0x7c, 0x0f, 0x89, 0x8d, 0xdc, - 0x7b, 0x90, 0xcb, 0xa8, 0x19, 0x24, 0x7c, 0xbf, 0x33, 0xa5, 0x7d, 0xbb, 0xeb, 0x2f, 0x9b, 0x16, 0x31, 0x1b, 0xeb, - 0x92, 0x70, 0xa1, 0x58, 0xa1, 0x1f, 0xb1, 0xb1, 0x2c, 0xe0, 0xfe, 0xa3, 0x04, 0x0b, 0x5a, 0xdf, 0x0b, 0x74, 0x80, - 0x66, 0x82, 0xc1, 0xa5, 0xc3, 0xc6, 0x0c, 0xcd, 0xaf, 0x2f, 0xe6, 0x0e, 0xfc, 0x7a, 0xb3, 0xd6, 0xcb, 0x83, 0x83, - 0xaf, 0xac, 0x02, 0x94, 0x1b, 0xa6, 0x19, 0x46, 0x40, 0xbc, 0x2c, 0x97, 0xe3, 0x6e, 0x86, 0xef, 0xc5, 0x95, 0xca, - 0xc0, 0x13, 0x8e, 0x90, 0x08, 0x3d, 0x27, 0x7a, 0x3d, 0xd9, 0xa4, 0xf7, 0x4e, 0x9b, 0x21, 0x42, 0xb1, 0x06, 0xc8, - 0x3d, 0xc8, 0xe5, 0x56, 0xc9, 0xa4, 0x2a, 0x5b, 0xdb, 0x72, 0x10, 0x8f, 0x01, 0x5c, 0xb1, 0x11, 0x52, 0x02, 0x34, - 0xdc, 0x2d, 0xb4, 0x3c, 0x97, 0xc0, 0xfe, 0x63, 0x95, 0x80, 0x48, 0x8b, 0x6a, 0x1b, 0x17, 0x21, 0x6c, 0x4d, 0x7d, - 0x02, 0xe3, 0x84, 0x87, 0xcf, 0x77, 0x69, 0xa8, 0x3d, 0x6a, 0x33, 0x73, 0x06, 0x41, 0x09, 0x89, 0xca, 0x0a, 0xc9, - 0xd7, 0x58, 0x38, 0x6e, 0xce, 0xdf, 0xc3, 0x01, 0x29, 0x56, 0x34, 0xb6, 0x77, 0x5b, 0x70, 0x7c, 0x14, 0xc9, 0x22, - 0xae, 0x75, 0xdd, 0x2d, 0x4c, 0x35, 0xec, 0x40, 0x47, 0x43, 0x38, 0x15, 0xe6, 0x9e, 0xf0, 0x71, 0x45, 0x52, 0x7f, - 0xb6, 0x26, 0xda, 0xda, 0x13, 0xc3, 0xca, 0x34, 0x25, 0x98, 0xff, 0xcf, 0xd6, 0xea, 0xba, 0x2c, 0x84, 0x99, 0x19, - 0xc6, 0x8d, 0x5d, 0x05, 0xb6, 0x06, 0x1c, 0x5b, 0x7e, 0x96, 0xc1, 0xa2, 0x7a, 0xa5, 0xb8, 0xe9, 0x34, 0x60, 0x02, - 0xde, 0x82, 0xf5, 0xcc, 0xe6, 0xd6, 0x7f, 0x6e, 0x0e, 0x46, 0x81, 0x55, 0x8d, 0xc0, 0x4b, 0x43, 0xe0, 0x11, 0x30, - 0x6e, 0xde, 0xb4, 0xbc, 0xe7, 0x8c, 0x68, 0x84, 0x3f, 0xf1, 0x1c, 0x9e, 0x59, 0x96, 0x7b, 0xeb, 0x63, 0x63, 0x45, - 0x52, 0x41, 0xc0, 0xb6, 0x08, 0x3b, 0x22, 0x2f, 0x11, 0x56, 0x8d, 0x46, 0x57, 0x5d, 0xb0, 0x4a, 0xab, 0x52, 0x0d, - 0x53, 0xc0, 0x2d, 0x31, 0xe0, 0x7d, 0xed, 0x44, 0x05, 0x43, 0x02, 0x6f, 0xfd, 0xad, 0x40, 0x7d, 0xff, 0xf0, 0x6d, - 0x1c, 0xd2, 0xb7, 0xb0, 0x6c, 0x79, 0x11, 0x0b, 0x53, 0x8a, 0xab, 0x3b, 0x9c, 0x37, 0xdf, 0x37, 0x1b, 0x81, 0x71, - 0xef, 0xb7, 0x31, 0xd8, 0xb8, 0xa1, 0xae, 0xb6, 0xa4, 0xa1, 0xdc, 0x84, 0x5d, 0x54, 0xd9, 0x3b, 0x86, 0x9d, 0x75, - 0x75, 0x25, 0xed, 0x6a, 0xa2, 0xd6, 0x6b, 0xc5, 0x2a, 0xa3, 0x81, 0x0d, 0xc3, 0x4e, 0x73, 0xcc, 0x6c, 0x2b, 0xf0, - 0x1f, 0xcf, 0x89, 0xc6, 0x01, 0xb2, 0xbe, 0xf9, 0xd6, 0x75, 0x4a, 0x35, 0x4c, 0xd8, 0xde, 0xee, 0x7c, 0x7c, 0xcc, - 0x77, 0x9d, 0x8f, 0x58, 0xba, 0xad, 0x6f, 0xce, 0xc6, 0xf6, 0xbf, 0x71, 0x36, 0x3a, 0xb5, 0xbd, 0x3f, 0x1e, 0x81, - 0x3b, 0xa9, 0x1d, 0x8f, 0xf5, 0x35, 0x25, 0x12, 0x0b, 0xb7, 0x1c, 0x97, 0x9d, 0xd5, 0x4a, 0xf4, 0x5b, 0xa0, 0x76, - 0x8a, 0x22, 0xf8, 0xd9, 0xb6, 0x3f, 0x03, 0x92, 0x6c, 0x75, 0xc8, 0xb1, 0x28, 0x45, 0x19, 0x94, 0x80, 0x01, 0x75, - 0x6c, 0x6c, 0xbd, 0x0c, 0x62, 0x3b, 0x1c, 0x72, 0x58, 0x4e, 0x44, 0x79, 0x75, 0x05, 0x23, 0x36, 0xc7, 0x86, 0x13, - 0x30, 0xe3, 0x9d, 0x56, 0x85, 0x5e, 0xfc, 0xfc, 0xd7, 0xcc, 0x69, 0xed, 0x88, 0xb1, 0x9c, 0x44, 0xcd, 0x8a, 0xc1, - 0x8d, 0xc0, 0x31, 0x8c, 0xfb, 0x46, 0x42, 0xad, 0x4e, 0x75, 0x54, 0x3b, 0x92, 0x70, 0x0b, 0xd4, 0x6e, 0xfb, 0xe6, - 0x5c, 0x5a, 0xad, 0x76, 0x1e, 0x2c, 0xb8, 0x08, 0x70, 0xfb, 0x39, 0xd1, 0x35, 0x92, 0x42, 0x89, 0x93, 0xa0, 0x70, - 0x6e, 0x50, 0x55, 0x13, 0xd9, 0x6f, 0x0d, 0x80, 0x27, 0xed, 0x66, 0x17, 0xb2, 0x12, 0x92, 0xb3, 0x46, 0x03, 0xe5, - 0x65, 0xc7, 0xb4, 0x2f, 0x1a, 0xd9, 0x00, 0x33, 0x9c, 0x59, 0x81, 0x05, 0x4e, 0xaf, 0x38, 0xaf, 0xba, 0xee, 0x67, - 0x03, 0x84, 0x8b, 0xd5, 0x2a, 0xb6, 0x43, 0xcb, 0xd1, 0x6a, 0x95, 0x87, 0x43, 0x33, 0xf9, 0x50, 0xf1, 0x65, 0x4f, - 0x93, 0x97, 0xe6, 0x3c, 0x7c, 0x09, 0x83, 0x6c, 0x90, 0x38, 0x77, 0x2a, 0xc1, 0x1c, 0x34, 0x57, 0x0d, 0xd9, 0xcf, - 0x1a, 0xed, 0x41, 0x40, 0xc3, 0xfa, 0xd9, 0x80, 0xe4, 0x6b, 0xb0, 0x9c, 0x55, 0xee, 0xc0, 0xfc, 0x0c, 0x07, 0xdb, - 0x67, 0x73, 0xce, 0xd8, 0x06, 0xc3, 0x35, 0xd9, 0x54, 0x19, 0x94, 0x78, 0xe5, 0x16, 0xd7, 0x97, 0xab, 0x19, 0x58, - 0x94, 0x85, 0xb0, 0xbb, 0x66, 0xee, 0x81, 0xf0, 0x5f, 0x62, 0xbb, 0xa4, 0xa5, 0x11, 0xf7, 0x06, 0xe2, 0x7b, 0xdb, - 0xed, 0x24, 0x49, 0x68, 0x31, 0x31, 0x57, 0x22, 0xfe, 0x86, 0xd7, 0xec, 0x81, 0x63, 0x37, 0xce, 0xa0, 0xe7, 0x7e, - 0xd9, 0xd9, 0x80, 0xd8, 0xf1, 0x7b, 0x66, 0xc7, 0x3b, 0xae, 0x14, 0x74, 0xb7, 0x2e, 0xc2, 0x0e, 0x86, 0xfe, 0x2f, - 0x0f, 0xe6, 0xc4, 0x0d, 0xc6, 0xa2, 0xc9, 0x06, 0xdc, 0xbe, 0x01, 0x8f, 0x82, 0x6e, 0xc0, 0xed, 0xdb, 0xf0, 0xf5, - 0xd0, 0xca, 0xbe, 0x39, 0xc0, 0x80, 0x4c, 0xd8, 0x91, 0x56, 0x09, 0xc1, 0x30, 0x4f, 0x37, 0x39, 0x32, 0x4b, 0x56, - 0xe1, 0x70, 0xd5, 0x24, 0x16, 0x1b, 0x7b, 0xa1, 0x62, 0x52, 0x03, 0xc1, 0x58, 0xa4, 0x2f, 0x51, 0xa8, 0x34, 0xa8, - 0x1b, 0xc7, 0x00, 0x56, 0x39, 0x6d, 0xfd, 0xcb, 0x83, 0x03, 0x10, 0x1a, 0x80, 0xb5, 0x4b, 0x32, 0x3a, 0xd7, 0x8b, - 0x02, 0xf8, 0x2b, 0xe5, 0x7f, 0x43, 0x32, 0xb8, 0x9d, 0x98, 0x34, 0xf8, 0x01, 0x09, 0x73, 0xaa, 0x14, 0xff, 0x6a, - 0xd3, 0xdc, 0x6f, 0x5c, 0x10, 0x8f, 0xd1, 0xca, 0x72, 0x8a, 0x12, 0x75, 0xa5, 0x43, 0xd7, 0x3a, 0xe4, 0x9e, 0x7e, - 0x65, 0x42, 0xbf, 0xe4, 0x4a, 0x33, 0x01, 0x00, 0xa8, 0x10, 0x0f, 0xa6, 0xa4, 0x10, 0x6c, 0xdd, 0x5a, 0x2d, 0x3a, - 0x1a, 0x7d, 0xb7, 0x8a, 0xae, 0xb3, 0x45, 0x53, 0x2a, 0x46, 0xb9, 0xed, 0x24, 0xb4, 0x99, 0xf4, 0x76, 0xa2, 0x65, - 0xc9, 0xd0, 0x62, 0xa7, 0x62, 0x3f, 0x0c, 0xad, 0x8f, 0x05, 0xf1, 0xe7, 0x82, 0x3f, 0x4b, 0xbf, 0xcb, 0xc7, 0xc0, - 0x95, 0xfa, 0x37, 0x56, 0x21, 0x9c, 0x09, 0xd6, 0x01, 0x79, 0x4d, 0xea, 0xe3, 0xf4, 0xa8, 0x93, 0x6f, 0x29, 0x17, - 0x4a, 0xa3, 0xb0, 0x8d, 0x93, 0xc2, 0x60, 0xca, 0xd9, 0xb7, 0x25, 0xae, 0x5f, 0xfd, 0x31, 0xe2, 0x8f, 0x0e, 0xf1, - 0xef, 0x52, 0x69, 0xb4, 0x2c, 0x11, 0x0c, 0xf9, 0x1d, 0xa9, 0x15, 0x5c, 0xc5, 0xe6, 0x5c, 0x3f, 0xd7, 0xb3, 0x7c, - 0xc3, 0x13, 0xa7, 0xab, 0x55, 0x29, 0x15, 0xa8, 0xf8, 0x86, 0xe1, 0x27, 0x0c, 0xee, 0x8d, 0x9f, 0xf1, 0xa0, 0xca, - 0xf6, 0x7d, 0xf1, 0xb3, 0xe0, 0xbe, 0xf8, 0x19, 0x4f, 0xb7, 0x8b, 0x06, 0xf7, 0xc4, 0x9d, 0xe4, 0x3c, 0x69, 0x45, - 0x9e, 0x8f, 0x9a, 0xd2, 0xca, 0xbf, 0xd2, 0x6e, 0x0d, 0x5c, 0xd9, 0xc4, 0x81, 0x71, 0x5e, 0x5d, 0x84, 0x62, 0xce, - 0x9c, 0xd1, 0x72, 0xf8, 0xdf, 0x5a, 0x27, 0x77, 0xf2, 0x48, 0x2b, 0x85, 0xbc, 0xa1, 0x85, 0xbe, 0x07, 0x1b, 0xae, - 0xd8, 0xf2, 0x01, 0xa4, 0x04, 0x94, 0x6d, 0xff, 0x5e, 0x17, 0x81, 0x38, 0xae, 0xac, 0xf3, 0x51, 0xd8, 0x3e, 0x29, - 0x4a, 0xae, 0xae, 0x2e, 0x84, 0xdc, 0x1a, 0x2d, 0x01, 0xc2, 0xd4, 0xbb, 0xe6, 0x31, 0x47, 0x93, 0x59, 0xba, 0x5c, - 0x97, 0xaa, 0x83, 0xc2, 0x72, 0x75, 0x1c, 0xe1, 0x62, 0x6d, 0x6e, 0xd0, 0xff, 0xe1, 0xf8, 0x33, 0x77, 0x34, 0xf2, - 0xe7, 0x92, 0x02, 0xbd, 0xdf, 0xed, 0x6b, 0xb3, 0x83, 0x44, 0xda, 0x39, 0x94, 0x96, 0x02, 0x80, 0xd5, 0x06, 0x5f, - 0xd7, 0x1e, 0xa7, 0x9e, 0x48, 0x37, 0x9b, 0x6f, 0x1a, 0xc2, 0x62, 0x56, 0x5a, 0xf0, 0x98, 0x6e, 0x76, 0x58, 0x8e, - 0x7a, 0x59, 0x5c, 0x97, 0x7b, 0xac, 0xd6, 0x2f, 0xfa, 0x06, 0x28, 0x2b, 0x43, 0xb4, 0xd5, 0x2a, 0xae, 0xc3, 0x9b, - 0x88, 0xe0, 0x1a, 0x04, 0x61, 0x11, 0x18, 0x70, 0xd4, 0x18, 0x6f, 0x5b, 0x27, 0x46, 0x9b, 0xf6, 0x4b, 0x9e, 0x75, - 0xaf, 0x8d, 0x23, 0x54, 0x34, 0xd8, 0xea, 0xa1, 0xe6, 0x01, 0xdb, 0xd9, 0x95, 0x1d, 0x05, 0x10, 0x9a, 0x52, 0x6f, - 0x9c, 0x5b, 0x59, 0xd1, 0xee, 0x80, 0x2f, 0xfa, 0x8e, 0x79, 0xae, 0x03, 0xdd, 0x76, 0x7e, 0x60, 0xdb, 0xf4, 0x44, - 0x7e, 0xcb, 0xb6, 0xa9, 0xc6, 0x09, 0xef, 0xb7, 0xd0, 0xf7, 0x0d, 0x61, 0x6d, 0x5f, 0xbb, 0x8b, 0xfc, 0x2f, 0x74, - 0xd7, 0x06, 0xf4, 0xb4, 0x60, 0xf6, 0x34, 0xe6, 0x83, 0x5e, 0xaf, 0x7f, 0x2e, 0xfd, 0x17, 0x8c, 0xad, 0xd0, 0xcf, - 0x76, 0x17, 0x38, 0xb1, 0xd2, 0x38, 0x04, 0xc7, 0xff, 0x70, 0x32, 0xc9, 0xe5, 0x90, 0xe6, 0xef, 0xa0, 0xc7, 0x2a, - 0xf7, 0xf9, 0xdd, 0xa8, 0xa0, 0x9a, 0x39, 0x5a, 0x53, 0x8d, 0xe2, 0x1f, 0x1e, 0x0c, 0xe3, 0x1f, 0x6e, 0x29, 0x77, - 0xd5, 0x02, 0x5e, 0xbe, 0x2c, 0x9b, 0x48, 0x7f, 0x5e, 0x97, 0x32, 0x98, 0xda, 0xdd, 0xcb, 0x26, 0x49, 0x63, 0x25, - 0x49, 0x63, 0x2a, 0xde, 0x6c, 0x2a, 0x8e, 0x3f, 0x7f, 0x63, 0xb0, 0xdb, 0x64, 0xee, 0x73, 0x40, 0xe6, 0x3e, 0xf3, - 0xf4, 0xbb, 0xb5, 0x02, 0x8a, 0x77, 0x9c, 0x1c, 0x1b, 0xcb, 0x18, 0x3b, 0xea, 0xb7, 0x1a, 0x0c, 0x1a, 0x34, 0xb9, - 0x0c, 0xbc, 0x1d, 0xaa, 0xd3, 0xcb, 0xdb, 0x1f, 0xc5, 0xd9, 0x42, 0x69, 0x39, 0x73, 0x8d, 0x2a, 0xe7, 0xe3, 0x64, - 0x32, 0x41, 0x81, 0x6d, 0xee, 0xf0, 0xd3, 0xba, 0x1b, 0xd9, 0xf2, 0x0b, 0x17, 0xa3, 0x54, 0x61, 0x77, 0xb6, 0xa8, - 0x54, 0xae, 0x89, 0x37, 0x73, 0xde, 0xce, 0xc3, 0x63, 0x2e, 0xb8, 0x9a, 0xb2, 0x22, 0x2e, 0xd0, 0xf2, 0x5b, 0x9d, - 0x15, 0x70, 0x9b, 0x63, 0x3b, 0xc3, 0xa3, 0xd2, 0x72, 0x40, 0x27, 0xd0, 0x1a, 0xe8, 0x8c, 0x66, 0x4c, 0x4f, 0xe5, - 0x08, 0x0c, 0x5f, 0x92, 0x51, 0xe9, 0x4e, 0x75, 0x70, 0xb0, 0x1f, 0x47, 0x46, 0x7f, 0x01, 0x3e, 0xe8, 0x61, 0x0e, - 0xea, 0x2d, 0xc1, 0x31, 0xa8, 0xea, 0x9a, 0xa1, 0x25, 0xdb, 0xf4, 0xa1, 0xd1, 0xc9, 0x17, 0x76, 0x87, 0x39, 0x5a, - 0xaf, 0x53, 0x3b, 0xea, 0x68, 0xcc, 0x59, 0x3e, 0x8a, 0xf0, 0x17, 0x76, 0x97, 0x96, 0x6e, 0xeb, 0xc6, 0xcb, 0xda, - 0x2c, 0x62, 0x24, 0x6f, 0x44, 0x84, 0xab, 0x4e, 0xd2, 0xe5, 0x1a, 0xcb, 0x82, 0x4f, 0x00, 0x47, 0x7f, 0x61, 0x77, - 0xa9, 0x6b, 0x2f, 0x70, 0x15, 0x44, 0x4b, 0x0f, 0xfa, 0x24, 0x48, 0x0e, 0x97, 0xc1, 0x09, 0x1c, 0x7d, 0x53, 0x77, - 0x40, 0x6a, 0xe5, 0x2a, 0x11, 0x12, 0xa1, 0xf5, 0xbf, 0x3b, 0x15, 0xbc, 0x08, 0xcf, 0x39, 0x5d, 0xb3, 0xb8, 0xdd, - 0xa8, 0xc4, 0xa0, 0x42, 0x65, 0x41, 0xf2, 0x31, 0xe6, 0x7e, 0xf7, 0x39, 0xef, 0x87, 0x40, 0x67, 0xb6, 0xa0, 0xae, - 0xd1, 0x74, 0x64, 0x7e, 0xa1, 0xea, 0x0e, 0x6a, 0xa6, 0xab, 0x8a, 0x7b, 0x1f, 0x63, 0x00, 0x3c, 0x58, 0xcb, 0x50, - 0xe3, 0x10, 0xba, 0xf6, 0x66, 0xaa, 0x63, 0x4a, 0xe2, 0xa5, 0x9f, 0x43, 0xca, 0x43, 0x30, 0xea, 0x35, 0xa0, 0xa1, - 0x43, 0x30, 0x6b, 0x79, 0xc8, 0xc7, 0xb1, 0xd8, 0x3a, 0x43, 0xa5, 0x39, 0x43, 0x93, 0x00, 0xe4, 0xdf, 0x38, 0x33, - 0x99, 0x81, 0x86, 0xe1, 0x2d, 0xcd, 0x01, 0xe8, 0x56, 0xd7, 0xe1, 0x50, 0xb8, 0xa2, 0xa5, 0xf3, 0x9e, 0x5d, 0x74, - 0x59, 0x1b, 0x56, 0x6c, 0xda, 0x41, 0xeb, 0x14, 0xa6, 0xc4, 0x6c, 0x81, 0xb5, 0xd7, 0xfb, 0x70, 0x6f, 0x57, 0x1b, - 0x17, 0x89, 0x9f, 0x16, 0xf1, 0x30, 0x89, 0x29, 0x5a, 0xf2, 0x98, 0x62, 0x09, 0x76, 0x90, 0xc5, 0xba, 0x1c, 0x3f, - 0x0b, 0x97, 0xa3, 0x66, 0x25, 0xbd, 0xdb, 0xc1, 0x10, 0xb8, 0x7c, 0x0d, 0xb6, 0xa1, 0x98, 0x7b, 0xc2, 0xc2, 0x63, - 0xe3, 0xe9, 0x17, 0xac, 0xdb, 0xdc, 0x2e, 0x88, 0x5f, 0x81, 0x31, 0x8d, 0x97, 0xc1, 0x2c, 0x42, 0xa7, 0x72, 0xe7, - 0x70, 0xe8, 0xae, 0x09, 0x2b, 0xe3, 0xd5, 0x58, 0x91, 0x8d, 0xa3, 0xe7, 0xfb, 0x36, 0x9e, 0x7f, 0x2f, 0x58, 0x71, - 0x77, 0xc5, 0xc0, 0xc6, 0x5a, 0x82, 0xbb, 0x71, 0xb5, 0x0c, 0x95, 0x81, 0x7c, 0x4f, 0x1a, 0xd6, 0x65, 0x8d, 0xbf, - 0x1b, 0x15, 0x63, 0x6d, 0xee, 0x29, 0x03, 0x6d, 0x8d, 0xdd, 0x2e, 0xec, 0x9b, 0xae, 0x9b, 0xac, 0x6b, 0x14, 0x71, - 0x15, 0xa4, 0xdd, 0xdd, 0x02, 0x2e, 0x42, 0x7f, 0xd8, 0xbe, 0x1a, 0x6c, 0xaa, 0x6e, 0x20, 0x09, 0xae, 0xfd, 0xe4, - 0xb7, 0xa7, 0xba, 0xcb, 0x5a, 0xf7, 0xdb, 0x53, 0xad, 0x5d, 0x16, 0x1a, 0x43, 0x22, 0xec, 0xfa, 0x29, 0xfd, 0xa7, - 0xc5, 0x7a, 0x8d, 0xd6, 0x30, 0xbc, 0x47, 0xbc, 0x1b, 0xc7, 0x8f, 0xbc, 0x85, 0x62, 0x02, 0x17, 0xb9, 0x57, 0xb9, - 0xf4, 0x84, 0xbc, 0x1a, 0xc1, 0x23, 0xbe, 0x35, 0x84, 0x47, 0x3c, 0x70, 0x7a, 0x05, 0xa9, 0x69, 0x22, 0xd8, 0xc8, - 0xd3, 0x4f, 0x64, 0x91, 0xd0, 0xf0, 0x71, 0xaf, 0x39, 0x11, 0xfa, 0x53, 0x0a, 0xfc, 0x17, 0x1e, 0x2e, 0xb4, 0x96, - 0x02, 0x73, 0x31, 0x5f, 0x68, 0xac, 0xcc, 0xe8, 0x97, 0x63, 0x29, 0x74, 0x73, 0x4c, 0x67, 0x3c, 0xbf, 0x4b, 0x17, - 0xbc, 0x39, 0x93, 0x42, 0xaa, 0x39, 0xcd, 0x18, 0x56, 0x77, 0x4a, 0xb3, 0x59, 0x73, 0xc1, 0xf1, 0x73, 0x96, 0x7f, - 0x65, 0x9a, 0x67, 0x14, 0xbf, 0x95, 0x43, 0xa9, 0x25, 0x7e, 0x7d, 0x7b, 0x37, 0x61, 0x02, 0xff, 0x3e, 0x5c, 0x08, - 0xbd, 0xc0, 0x8a, 0x0a, 0xd5, 0x54, 0xac, 0xe0, 0xe3, 0x6e, 0xb3, 0x39, 0x2f, 0xf8, 0x8c, 0x16, 0x77, 0xcd, 0x4c, - 0xe6, 0xb2, 0x48, 0xff, 0xab, 0x75, 0x4c, 0x1f, 0x8c, 0x4f, 0xba, 0xba, 0xa0, 0x42, 0x71, 0x58, 0x98, 0x94, 0xe6, - 0xf9, 0xde, 0xf1, 0x69, 0x6b, 0xa6, 0xf6, 0xed, 0x85, 0x1f, 0x15, 0x7a, 0xfd, 0x09, 0x7f, 0x90, 0x30, 0xca, 0x64, - 0xa8, 0x85, 0x1b, 0xe4, 0x32, 0x5b, 0x14, 0x4a, 0x16, 0xe9, 0x5c, 0x72, 0xa1, 0x59, 0xd1, 0x1d, 0xca, 0x62, 0xc4, - 0x8a, 0x66, 0x41, 0x47, 0x7c, 0xa1, 0xd2, 0x93, 0xf9, 0x6d, 0xb7, 0xde, 0x83, 0xcd, 0x4f, 0x85, 0x14, 0xac, 0x0b, - 0xfc, 0xc6, 0xa4, 0x90, 0x0b, 0x31, 0x72, 0xc3, 0x58, 0x08, 0xc5, 0x74, 0x77, 0x4e, 0x47, 0x60, 0x07, 0x9c, 0x9e, - 0xcf, 0x6f, 0xbb, 0x66, 0xd6, 0x37, 0x8c, 0x4f, 0xa6, 0x3a, 0x3d, 0x6d, 0xb5, 0xec, 0xb7, 0xe2, 0xff, 0xb0, 0xb4, - 0xdd, 0x49, 0x3a, 0xa7, 0xf3, 0x5b, 0xe0, 0xe0, 0x35, 0x2b, 0x9a, 0x00, 0x0b, 0xa8, 0xd4, 0x4e, 0x5a, 0x0f, 0x8e, - 0xef, 0x43, 0x06, 0xd8, 0x38, 0x34, 0xcd, 0x84, 0xc0, 0xd8, 0x3d, 0x5d, 0xcc, 0xe7, 0xac, 0x00, 0x2f, 0xfa, 0xee, - 0x8c, 0x16, 0x13, 0x2e, 0x9a, 0x85, 0x69, 0xb4, 0x79, 0x3e, 0xbf, 0x5d, 0xc3, 0x7c, 0x52, 0x6b, 0xb6, 0xea, 0xa6, - 0xe5, 0xbe, 0x96, 0xc1, 0x10, 0x4d, 0x4c, 0x9a, 0xb4, 0x98, 0x0c, 0x69, 0xdc, 0xee, 0xdc, 0xc7, 0xfe, 0x7f, 0x49, - 0x07, 0x05, 0x60, 0x6b, 0x8e, 0x16, 0x85, 0xb9, 0x45, 0x4d, 0xdb, 0xca, 0x36, 0x3b, 0x95, 0x5f, 0x59, 0xe1, 0x5b, - 0x35, 0x1f, 0xcb, 0xad, 0x79, 0xff, 0x47, 0x8d, 0x52, 0xdb, 0xd6, 0x0b, 0x75, 0x05, 0x34, 0x7a, 0xbb, 0xb1, 0xff, - 0xea, 0x9c, 0xd3, 0xfb, 0x27, 0xa7, 0x1e, 0xee, 0xe3, 0xf1, 0xb8, 0x06, 0x74, 0x0f, 0xdd, 0x76, 0x6b, 0x7e, 0xbb, - 0xd7, 0x69, 0x79, 0x18, 0x5b, 0x98, 0x9e, 0xcd, 0x6f, 0x77, 0xac, 0x60, 0x80, 0x15, 0x9b, 0xbd, 0xed, 0x25, 0xc7, - 0x6a, 0x8f, 0x51, 0xc5, 0xd6, 0x9f, 0xf0, 0x84, 0x02, 0x6e, 0x18, 0xa4, 0xed, 0x1b, 0x39, 0x15, 0x56, 0x60, 0xb0, - 0xbc, 0xe1, 0x23, 0x3d, 0x4d, 0xdb, 0xad, 0xd6, 0x0f, 0x15, 0x26, 0x75, 0xa7, 0x76, 0x49, 0xdb, 0x05, 0x9b, 0xd5, - 0xf0, 0x6b, 0x46, 0xcb, 0x5d, 0xb0, 0x9c, 0x4b, 0xd7, 0x69, 0xc1, 0x72, 0x13, 0xe5, 0x66, 0xed, 0xb6, 0xc2, 0xd6, - 0x94, 0xb9, 0x98, 0xb2, 0x82, 0xeb, 0x6e, 0xfd, 0xab, 0xea, 0x78, 0x7b, 0x4e, 0x6b, 0x2b, 0x1f, 0x2f, 0x6d, 0x0d, - 0x77, 0x19, 0xfb, 0x18, 0x3e, 0xb6, 0xb1, 0xf2, 0x2b, 0x2d, 0xe2, 0x8d, 0x0d, 0x83, 0xc3, 0x1a, 0x68, 0x1d, 0xcc, - 0xb9, 0x00, 0x53, 0xd1, 0x01, 0xfe, 0x06, 0x14, 0x32, 0x9a, 0x67, 0x31, 0x8c, 0x68, 0xaf, 0xb9, 0x77, 0x5c, 0xb0, - 0x19, 0xf2, 0x80, 0x48, 0xee, 0x9f, 0x16, 0x6c, 0xb6, 0x4e, 0x4c, 0xf5, 0xa5, 0x41, 0x5d, 0x9a, 0xf3, 0x89, 0x48, - 0x33, 0x06, 0xdb, 0x6a, 0x9d, 0x30, 0xa1, 0xb9, 0xbe, 0x6b, 0x16, 0xf2, 0x66, 0x39, 0xe2, 0x6a, 0x9e, 0xd3, 0xbb, - 0x74, 0x9c, 0xb3, 0xdb, 0xae, 0x29, 0xd5, 0xe4, 0x9a, 0xcd, 0x94, 0x2b, 0xdb, 0x85, 0xf4, 0xe6, 0xc8, 0x9a, 0x73, - 0x00, 0xf4, 0xe4, 0xcd, 0xe6, 0xbe, 0xf6, 0x8b, 0xd6, 0x94, 0x0b, 0xbd, 0xd7, 0x52, 0xdd, 0x19, 0x17, 0x4d, 0x37, - 0x90, 0x13, 0xc0, 0x88, 0x6d, 0xc8, 0x07, 0xfd, 0x27, 0xec, 0x76, 0x4e, 0xc5, 0x88, 0x8d, 0x96, 0x41, 0xb5, 0x0e, - 0xd4, 0x0b, 0x4b, 0xa5, 0x42, 0x4f, 0x9b, 0xc6, 0x06, 0x2d, 0xee, 0x08, 0xf4, 0x0d, 0x94, 0x7f, 0xd0, 0xc2, 0xf6, - 0xff, 0x93, 0x36, 0x0a, 0x2b, 0xef, 0x41, 0x38, 0x28, 0x3e, 0xbe, 0x6b, 0xc2, 0xdf, 0x25, 0xf8, 0x3c, 0xf1, 0x8c, - 0xe6, 0x0e, 0x22, 0x33, 0x3e, 0x1a, 0xe5, 0xb5, 0x11, 0x5d, 0x06, 0x9d, 0xb5, 0xd1, 0x12, 0xe6, 0x9f, 0xb6, 0xf6, - 0x5a, 0x7b, 0x66, 0x2e, 0x6e, 0x1b, 0x9c, 0x9c, 0xdc, 0x3f, 0x7e, 0xc0, 0xba, 0x39, 0x17, 0xac, 0x36, 0xd5, 0xef, - 0x82, 0x3a, 0x6c, 0xb8, 0xe3, 0x1a, 0x6e, 0xef, 0xb5, 0xf7, 0x4e, 0x5a, 0x3f, 0x78, 0x2a, 0x92, 0xb3, 0xb1, 0xb6, - 0xfb, 0xa6, 0x46, 0x56, 0xce, 0x7d, 0xd3, 0x37, 0x05, 0x9d, 0xa7, 0x42, 0xc2, 0x9f, 0x2e, 0x6c, 0xfe, 0x71, 0x2e, - 0x6f, 0xd2, 0x29, 0x1f, 0x8d, 0x98, 0xb0, 0x05, 0xca, 0x44, 0x96, 0xe7, 0x7c, 0xae, 0xb8, 0x5d, 0x0d, 0x87, 0xbb, - 0xa7, 0x1b, 0x50, 0x0d, 0x07, 0x74, 0x1c, 0x0c, 0xe8, 0xb4, 0x1a, 0x50, 0xd5, 0x7f, 0x38, 0xc2, 0xce, 0xc6, 0x5c, - 0x4d, 0xa9, 0x6e, 0x0d, 0x93, 0x3e, 0x2f, 0x94, 0x06, 0x98, 0x7b, 0xe3, 0x11, 0x73, 0xba, 0x34, 0x87, 0x4c, 0xdf, - 0x30, 0x26, 0xbe, 0x3d, 0x88, 0xcb, 0x54, 0x8a, 0xfc, 0xce, 0x7e, 0x2e, 0xc3, 0x2e, 0xe9, 0x42, 0xcb, 0x75, 0x32, - 0xe4, 0x82, 0x16, 0x77, 0xd7, 0x8a, 0x09, 0x25, 0x8b, 0x6b, 0x39, 0x1e, 0x2f, 0xbf, 0x45, 0xf2, 0xee, 0xa3, 0x75, - 0xa2, 0xb8, 0x98, 0xe4, 0xcc, 0x12, 0x38, 0x83, 0x08, 0xee, 0x90, 0xb1, 0xed, 0x9a, 0x26, 0x6b, 0x83, 0x5e, 0x27, - 0x59, 0xce, 0x67, 0x54, 0x33, 0x03, 0xe7, 0x80, 0xd4, 0xb8, 0xc9, 0x5b, 0x2a, 0xd7, 0xda, 0xb3, 0x7f, 0xaa, 0xd2, - 0xb0, 0x8d, 0x82, 0xc2, 0xbe, 0x49, 0x2e, 0x0c, 0x7e, 0x18, 0x70, 0x98, 0x5d, 0x64, 0x56, 0xcf, 0xac, 0x5d, 0x00, - 0x3b, 0x98, 0x5d, 0xad, 0xa9, 0x4b, 0x47, 0x97, 0x6c, 0x8b, 0xa7, 0xad, 0x1f, 0xea, 0xb9, 0x39, 0x1d, 0xb2, 0x7c, - 0x69, 0x37, 0xaa, 0x07, 0xae, 0xdb, 0xaa, 0xe1, 0x32, 0x07, 0x24, 0xc3, 0x80, 0x68, 0x90, 0xa6, 0xcd, 0x1b, 0x36, - 0xfc, 0xc2, 0xb5, 0xdd, 0x32, 0x4d, 0x75, 0x03, 0x4e, 0x45, 0x66, 0x4c, 0x73, 0x56, 0x2c, 0x3d, 0x21, 0x6f, 0xd5, - 0x08, 0xe8, 0x95, 0x30, 0x07, 0xb4, 0xa6, 0xc3, 0x26, 0x84, 0x58, 0x63, 0xc5, 0x72, 0xd7, 0xe4, 0x66, 0xf4, 0xd6, - 0xa1, 0xd8, 0x83, 0xd6, 0x0f, 0xb5, 0x43, 0xf6, 0xa4, 0xd5, 0xf2, 0x47, 0x44, 0xd3, 0xd6, 0x48, 0xdb, 0xc9, 0x29, - 0x9b, 0x95, 0x89, 0x5a, 0xce, 0xd3, 0x5a, 0xc2, 0x50, 0x6a, 0x2d, 0x67, 0x36, 0x6d, 0x07, 0x35, 0xaa, 0x93, 0xde, - 0x76, 0x67, 0x7e, 0xbb, 0x67, 0xfe, 0x69, 0xed, 0xb5, 0xb6, 0x49, 0xed, 0x36, 0x56, 0x1c, 0x23, 0x8f, 0xc7, 0xd0, - 0x71, 0x9b, 0xcd, 0xba, 0x0b, 0x05, 0xc7, 0xbd, 0x81, 0xb8, 0x39, 0xd1, 0xd6, 0x66, 0xb2, 0x00, 0x58, 0xca, 0x05, - 0x9c, 0xae, 0xf6, 0xb0, 0x83, 0x3e, 0x94, 0x04, 0x73, 0xf8, 0x9d, 0x8d, 0xd6, 0x87, 0xd5, 0xda, 0xab, 0x06, 0x06, - 0xff, 0xac, 0x3f, 0x55, 0xfc, 0xf9, 0x0b, 0x16, 0xc8, 0x47, 0xbc, 0x91, 0x9c, 0xae, 0x5a, 0x4e, 0x26, 0x1a, 0xe9, - 0x4a, 0x54, 0x33, 0x1e, 0x25, 0x33, 0x7a, 0x6b, 0x5d, 0x4b, 0x66, 0x5c, 0x80, 0xe1, 0x1a, 0xc2, 0x3a, 0x30, 0xf1, - 0x9f, 0x86, 0x0d, 0x8d, 0x74, 0x0c, 0x0d, 0x1f, 0x76, 0x92, 0xd3, 0x53, 0x84, 0x5b, 0xb8, 0x73, 0x7a, 0x1a, 0xc8, - 0x64, 0x63, 0xbd, 0xab, 0xe8, 0xae, 0x92, 0x72, 0x47, 0xc9, 0x23, 0xd3, 0xe8, 0x51, 0xbb, 0xd5, 0xc2, 0xc6, 0x7d, - 0xbe, 0x2c, 0xcc, 0xd5, 0x8e, 0x66, 0xdb, 0xad, 0x16, 0x34, 0x0b, 0x7f, 0xdc, 0xbc, 0x7e, 0x21, 0xcb, 0x56, 0xda, - 0xc2, 0xed, 0xb4, 0x8d, 0x3b, 0x69, 0x07, 0x1f, 0xa7, 0xc7, 0xf8, 0x24, 0x3d, 0xc1, 0xa7, 0xe9, 0x29, 0x3e, 0x4b, - 0xcf, 0xf0, 0xfd, 0xf4, 0x3e, 0x3e, 0x4f, 0xcf, 0xf1, 0x83, 0xf4, 0x01, 0x7e, 0x98, 0xb6, 0x5b, 0xf8, 0x51, 0xda, - 0x6e, 0xe3, 0xc7, 0x69, 0xbb, 0x83, 0x9f, 0xa4, 0xed, 0x63, 0xfc, 0x34, 0x6d, 0x9f, 0xe0, 0x67, 0x69, 0xfb, 0x14, - 0x53, 0xc8, 0x1d, 0x42, 0x6e, 0x06, 0xb9, 0x23, 0xc8, 0x65, 0x90, 0x3b, 0x4e, 0xdb, 0xa7, 0x6b, 0xac, 0x6c, 0xc8, - 0x8d, 0xa8, 0xd5, 0xee, 0x1c, 0x9f, 0x9c, 0x9e, 0xdd, 0x3f, 0x7f, 0xf0, 0xf0, 0xd1, 0xe3, 0x27, 0x4f, 0x9f, 0x45, - 0x03, 0x3c, 0x34, 0x9e, 0x2f, 0x4a, 0xf4, 0xf9, 0x41, 0xfb, 0x74, 0x80, 0xaf, 0xfd, 0x67, 0xcc, 0x0f, 0x3a, 0x27, - 0x2d, 0x74, 0x79, 0x79, 0x32, 0x68, 0x94, 0xb9, 0x8f, 0x8c, 0xc3, 0x4d, 0x95, 0x45, 0x08, 0x89, 0x21, 0x07, 0xe1, - 0x3b, 0x53, 0xef, 0x11, 0x8b, 0x79, 0x52, 0xa0, 0x83, 0x03, 0xf3, 0x63, 0xe2, 0x7f, 0x0c, 0xfd, 0x0f, 0x1a, 0x2c, - 0xd2, 0x2d, 0x8d, 0x9d, 0xc7, 0xb5, 0x2e, 0xfd, 0x1d, 0x4a, 0x53, 0xa2, 0x3d, 0xee, 0x8c, 0xfa, 0xff, 0x2b, 0xb2, - 0x46, 0x3b, 0xe4, 0xc4, 0x2a, 0xc6, 0x4e, 0x7b, 0x8c, 0x2c, 0x8b, 0xb4, 0x73, 0x7a, 0x7a, 0xf0, 0x4b, 0x9f, 0xf7, - 0xdb, 0x83, 0xc1, 0x61, 0xfb, 0x3e, 0x9e, 0x94, 0x09, 0x1d, 0x9b, 0x30, 0x2c, 0x13, 0x8e, 0x6d, 0x02, 0x4d, 0x6d, - 0x6d, 0x48, 0x3a, 0x31, 0x49, 0x50, 0x62, 0x9d, 0x9a, 0xb6, 0xef, 0xdb, 0xb6, 0x1f, 0x80, 0x35, 0x99, 0x69, 0xde, - 0x35, 0x7d, 0x71, 0x71, 0xb2, 0x72, 0x8d, 0xe2, 0x49, 0xea, 0x5a, 0xf3, 0x89, 0x27, 0x83, 0x01, 0x1e, 0x9a, 0xc4, - 0xd3, 0x2a, 0xf1, 0x6c, 0x30, 0x70, 0x5d, 0x3d, 0x30, 0x5d, 0xdd, 0xaf, 0xb2, 0xce, 0x07, 0x03, 0xd3, 0x25, 0x72, - 0xb1, 0x03, 0x94, 0xde, 0xfb, 0x5a, 0xea, 0x6f, 0xf8, 0x45, 0xe7, 0xf4, 0xb4, 0x07, 0x18, 0x66, 0x6c, 0x82, 0x3d, - 0x8c, 0x6e, 0x02, 0x18, 0xdd, 0xc1, 0xef, 0xde, 0x90, 0xa6, 0xd7, 0xb4, 0x04, 0x52, 0x2f, 0xfa, 0xaf, 0xa8, 0xa1, - 0x0d, 0xcc, 0xcd, 0x9f, 0x89, 0xfd, 0x33, 0x44, 0x8d, 0xaf, 0x14, 0xc0, 0x0d, 0x1a, 0x29, 0xaf, 0x52, 0x36, 0x3d, - 0x7e, 0xa1, 0xe0, 0xe2, 0x33, 0x55, 0x39, 0xed, 0xad, 0xa6, 0x37, 0xc3, 0xd5, 0x54, 0x7d, 0x45, 0x7f, 0xc5, 0x7f, - 0xa9, 0xc3, 0xb8, 0xdf, 0x6c, 0x24, 0xec, 0xaf, 0x11, 0xf8, 0x12, 0xf5, 0xd2, 0x11, 0x9b, 0xa0, 0x5e, 0xff, 0x2f, - 0x85, 0x07, 0x8d, 0x20, 0xe3, 0x87, 0xed, 0x14, 0xf0, 0x34, 0xda, 0x4c, 0x8c, 0x7f, 0x40, 0x3d, 0xd4, 0xfb, 0x4b, - 0x1d, 0xfe, 0x85, 0xee, 0x1d, 0x55, 0x73, 0xf9, 0x5d, 0xba, 0x2d, 0x5c, 0x85, 0x1f, 0x3a, 0x2c, 0xb7, 0x30, 0xc3, - 0xed, 0x26, 0x83, 0x60, 0x6d, 0xe0, 0x8a, 0x4e, 0x62, 0xd9, 0xe0, 0x47, 0xc7, 0x2d, 0xf4, 0x43, 0xbb, 0x03, 0xca, - 0x95, 0xa6, 0x38, 0xdc, 0xde, 0xf4, 0x45, 0xf3, 0x18, 0x3f, 0x68, 0x16, 0xb8, 0x8d, 0x70, 0xb3, 0xed, 0xb5, 0xde, - 0x7d, 0x15, 0xb7, 0x10, 0x56, 0xf1, 0x39, 0xfc, 0x73, 0x82, 0x06, 0xd5, 0x86, 0xbc, 0xa2, 0x9b, 0xbd, 0x83, 0xdf, - 0x2c, 0x89, 0x55, 0x83, 0x1f, 0x9d, 0xb5, 0xd0, 0x0f, 0x67, 0xa6, 0x23, 0x76, 0xa8, 0x77, 0x74, 0x25, 0xf1, 0x49, - 0x53, 0x42, 0x47, 0xad, 0xb2, 0x1f, 0x11, 0x9f, 0x22, 0x2c, 0xe2, 0x63, 0xf8, 0xa7, 0x1d, 0xf6, 0xf3, 0xeb, 0x56, - 0x3f, 0x66, 0xde, 0x6d, 0x9c, 0x9c, 0x5a, 0x37, 0x5c, 0x65, 0xef, 0xc4, 0x1b, 0xec, 0xb2, 0x6d, 0x2e, 0xf3, 0xda, - 0x47, 0xf0, 0x81, 0xb0, 0x3e, 0x24, 0x0a, 0xb3, 0x43, 0xf0, 0xdf, 0x05, 0xb3, 0x15, 0x75, 0x71, 0xdc, 0x55, 0x8d, - 0x06, 0x12, 0x7d, 0x35, 0x38, 0x24, 0xed, 0xa6, 0x6e, 0x32, 0x0c, 0xbf, 0x1b, 0xa4, 0x0c, 0x0a, 0x27, 0xaa, 0x5e, - 0x1f, 0xbb, 0x5e, 0xed, 0xcd, 0xbf, 0xc7, 0x0e, 0x42, 0x88, 0xea, 0xc5, 0xba, 0xc9, 0xd0, 0x91, 0x68, 0xc4, 0xfa, - 0x82, 0xf5, 0xce, 0xd2, 0x16, 0x32, 0xd8, 0xa9, 0x7a, 0x31, 0x6b, 0x72, 0x48, 0xef, 0xa4, 0x31, 0x6f, 0x6a, 0xf8, - 0x75, 0x12, 0xcc, 0x42, 0x00, 0xde, 0x55, 0xde, 0x48, 0xc5, 0x51, 0xe7, 0xf4, 0x14, 0x0b, 0xc2, 0x93, 0x89, 0xf9, - 0xa5, 0x08, 0x4f, 0x86, 0xe6, 0x97, 0x24, 0x25, 0xbc, 0x6c, 0xef, 0xb8, 0x20, 0xc1, 0xaa, 0x9a, 0x14, 0x0a, 0x0b, - 0x5a, 0xa0, 0xa3, 0x8e, 0x37, 0x0b, 0xc0, 0x53, 0x3f, 0x07, 0x50, 0x83, 0x14, 0xc6, 0x22, 0x54, 0x36, 0x0b, 0x9c, - 0x13, 0x7a, 0x99, 0x9c, 0xf6, 0xa6, 0x47, 0x71, 0xa7, 0x29, 0x9b, 0x05, 0x4a, 0xa7, 0x47, 0xa6, 0x26, 0xce, 0xc8, - 0x63, 0x6a, 0x5b, 0xc3, 0x53, 0xb8, 0xcb, 0xcd, 0x48, 0x76, 0x78, 0xd6, 0x6a, 0x24, 0xa7, 0x08, 0xf7, 0xb3, 0x55, - 0x0b, 0xe7, 0xab, 0x55, 0x0b, 0xd3, 0x60, 0x19, 0x1e, 0x0b, 0x0f, 0x90, 0x52, 0x53, 0xb7, 0x19, 0x9b, 0xa7, 0xc7, - 0x63, 0x0d, 0x76, 0x09, 0x1a, 0xbc, 0x7d, 0x34, 0xf8, 0x21, 0xa5, 0xdc, 0x5d, 0x08, 0x22, 0x13, 0x9d, 0x70, 0x1c, - 0xea, 0xee, 0x5e, 0x0b, 0xbf, 0xae, 0xde, 0xb2, 0x54, 0xc4, 0xbf, 0x4b, 0x6c, 0xd3, 0x82, 0x62, 0x74, 0xbb, 0xd8, - 0xaf, 0x74, 0xab, 0xd8, 0x9b, 0x1d, 0xc5, 0xae, 0xb6, 0x8b, 0x7d, 0x94, 0x81, 0xa6, 0x91, 0xff, 0x70, 0x7c, 0xd6, - 0x6a, 0x1c, 0x03, 0xb2, 0x1e, 0x9f, 0xb5, 0xaa, 0x42, 0xf7, 0x68, 0xb5, 0x56, 0x9a, 0x7c, 0xa1, 0xd6, 0xd7, 0x82, - 0x7b, 0xa7, 0x6f, 0xb3, 0x70, 0xd6, 0xe5, 0xbc, 0xf4, 0x2f, 0xef, 0x9f, 0x82, 0x2d, 0x8b, 0x30, 0xd4, 0x4e, 0xf7, - 0xcf, 0x06, 0xbd, 0x29, 0x8b, 0x1b, 0x90, 0x8a, 0xd2, 0xb1, 0x76, 0xbf, 0x50, 0x79, 0xa5, 0xfd, 0x51, 0x42, 0x52, - 0x67, 0x80, 0xb0, 0x24, 0x0d, 0xdd, 0x3f, 0x1e, 0x98, 0xf3, 0xae, 0x80, 0xdf, 0x27, 0xe6, 0x77, 0xa9, 0x50, 0x72, - 0x0e, 0x19, 0xd3, 0x9b, 0x61, 0xd4, 0x13, 0xe4, 0x35, 0x8d, 0x8d, 0x8d, 0x3d, 0x4a, 0xcb, 0x0c, 0xf5, 0x15, 0x32, - 0xde, 0x94, 0x19, 0x82, 0xbc, 0x16, 0xee, 0x37, 0x5e, 0x16, 0x29, 0xd8, 0xdb, 0xe0, 0x49, 0x0a, 0xb6, 0x36, 0x78, - 0x98, 0x0a, 0xf0, 0x07, 0xa1, 0x29, 0x0b, 0xac, 0xf8, 0x1f, 0x3a, 0x0d, 0x9e, 0xb9, 0x75, 0x26, 0x06, 0x4b, 0xbb, - 0x0c, 0x4e, 0x8a, 0x8f, 0x32, 0x86, 0xbf, 0x0d, 0x8d, 0x30, 0x83, 0x36, 0x19, 0xc2, 0x3c, 0x29, 0x08, 0xa4, 0x61, - 0x9e, 0x4c, 0x08, 0x83, 0x26, 0x79, 0x32, 0x24, 0xac, 0xdf, 0x09, 0xd0, 0xe4, 0xa9, 0x81, 0x1d, 0x00, 0x87, 0xd7, - 0x2f, 0xf2, 0xb5, 0x6d, 0x1c, 0x2c, 0x04, 0xa0, 0x09, 0x41, 0xb8, 0x8a, 0x61, 0x16, 0xb0, 0x39, 0xcd, 0xcf, 0x4e, - 0x15, 0xfe, 0x92, 0x27, 0xd4, 0x50, 0xef, 0x4f, 0x40, 0x56, 0xe3, 0x7b, 0x4b, 0xb6, 0xc6, 0x7b, 0xf7, 0x96, 0x62, - 0xfd, 0x03, 0xfc, 0x51, 0xf6, 0x0f, 0x30, 0x0f, 0x09, 0x45, 0x6b, 0xf4, 0x29, 0x85, 0x62, 0x3b, 0x4a, 0xa1, 0x4f, - 0xde, 0x1d, 0x50, 0x91, 0xe5, 0x6d, 0x1a, 0x8d, 0x68, 0xf1, 0x25, 0xc2, 0x7f, 0xa6, 0x51, 0x0e, 0xdc, 0x62, 0x84, - 0x3f, 0xa6, 0x51, 0xc1, 0x22, 0xfc, 0x47, 0x1a, 0x0d, 0xf3, 0x45, 0x84, 0x3f, 0xa4, 0xd1, 0xa4, 0x88, 0xf0, 0x7b, - 0x50, 0xd6, 0x8e, 0xf8, 0x62, 0x16, 0xe1, 0xdf, 0xd3, 0x48, 0x19, 0x6f, 0x08, 0xfc, 0x30, 0x8d, 0x18, 0x8b, 0xf0, - 0xbb, 0x34, 0x92, 0x79, 0x84, 0xaf, 0xd2, 0x48, 0x16, 0x11, 0x7e, 0x94, 0x46, 0x05, 0x8d, 0xf0, 0xe3, 0x34, 0x82, - 0x42, 0x93, 0x08, 0x3f, 0x49, 0x23, 0x68, 0x59, 0x45, 0xf8, 0x6d, 0x1a, 0x71, 0x11, 0xe1, 0xdf, 0xd2, 0x48, 0x2f, - 0x8a, 0xbf, 0x17, 0x92, 0xab, 0x08, 0x3f, 0x4d, 0xa3, 0x29, 0x8f, 0xf0, 0x9b, 0x34, 0x2a, 0x64, 0x84, 0x5f, 0xa7, - 0x11, 0xcd, 0x23, 0xfc, 0x2a, 0x8d, 0x72, 0x16, 0xe1, 0x5f, 0xd3, 0x68, 0xc4, 0x22, 0xfc, 0x32, 0x8d, 0xee, 0x58, - 0x9e, 0xcb, 0x08, 0x3f, 0x4b, 0x23, 0x26, 0x22, 0xfc, 0x4b, 0x1a, 0x65, 0xd3, 0x08, 0xff, 0x94, 0x46, 0xb4, 0xf8, - 0xa2, 0x22, 0xfc, 0x3c, 0x8d, 0x18, 0x8d, 0xf0, 0x0b, 0xdb, 0xd1, 0x24, 0xc2, 0x3f, 0xa7, 0xd1, 0xcd, 0x34, 0x5a, - 0x63, 0xa5, 0xc8, 0xf2, 0x35, 0xcf, 0xd8, 0x1f, 0x2c, 0x8d, 0xc6, 0xad, 0xf1, 0xf9, 0x78, 0x1c, 0x61, 0x2a, 0x34, - 0xff, 0x7b, 0xc1, 0x6e, 0x9e, 0x6a, 0x48, 0xa4, 0x6c, 0x38, 0xba, 0x1f, 0x61, 0xfa, 0xf7, 0x82, 0xa6, 0xd1, 0x78, - 0x6c, 0x0a, 0xfc, 0xbd, 0xa0, 0x33, 0x5a, 0xbc, 0x65, 0x69, 0x74, 0x7f, 0x3c, 0x1e, 0x8f, 0x4e, 0x22, 0x4c, 0xff, - 0x59, 0x7c, 0x34, 0x2d, 0x98, 0x02, 0x43, 0xc6, 0x27, 0x50, 0xf7, 0x74, 0x7c, 0x3a, 0xca, 0x22, 0x3c, 0xe4, 0xea, - 0xef, 0x05, 0x7c, 0x8f, 0xd9, 0x49, 0x76, 0x12, 0xe1, 0x61, 0x4e, 0xb3, 0x2f, 0x69, 0xd4, 0x32, 0xbf, 0xc4, 0x2f, - 0x6c, 0xf4, 0x7a, 0x26, 0xcd, 0x55, 0xc6, 0x98, 0x0d, 0xb3, 0x51, 0x84, 0xcd, 0x60, 0xc6, 0xf0, 0xf7, 0x2b, 0x7f, - 0xc7, 0x74, 0x1a, 0x9d, 0xd3, 0xce, 0x90, 0x75, 0x22, 0x3c, 0x7c, 0x73, 0x23, 0xd2, 0x88, 0x9e, 0x76, 0x68, 0x87, - 0x46, 0x78, 0xb8, 0x28, 0xf2, 0xbb, 0x1b, 0x29, 0x47, 0x00, 0x84, 0xe1, 0xf9, 0xf9, 0xfd, 0x08, 0x67, 0xf4, 0x57, - 0x0d, 0xb5, 0x4f, 0xc7, 0x0f, 0x18, 0x6d, 0x45, 0xf8, 0x17, 0x5a, 0xe8, 0x8f, 0x0b, 0xe5, 0x06, 0xda, 0x82, 0x14, - 0x99, 0xbd, 0x03, 0x35, 0x7f, 0x34, 0xea, 0x9c, 0x3d, 0x68, 0xb3, 0x08, 0x67, 0x57, 0xaf, 0xa1, 0xb7, 0xfb, 0xe3, - 0xd3, 0x16, 0x7c, 0x08, 0x90, 0x4b, 0x59, 0x01, 0x8d, 0x9c, 0x9d, 0x3c, 0x38, 0x65, 0x23, 0x93, 0xa8, 0x78, 0xfe, - 0xc5, 0xcc, 0xfe, 0x1c, 0xe6, 0x93, 0x15, 0x7c, 0xa6, 0xa4, 0x48, 0xa3, 0x51, 0xd6, 0x3e, 0x39, 0x86, 0x84, 0x3b, - 0x2a, 0x3c, 0x70, 0x6e, 0xa1, 0xea, 0xf9, 0x30, 0xc2, 0xb7, 0x36, 0xf5, 0x7c, 0x68, 0x3e, 0x26, 0xef, 0x7e, 0x15, - 0x6f, 0x46, 0x69, 0x34, 0x3c, 0x3f, 0x3f, 0x6b, 0x41, 0xc2, 0x07, 0x7a, 0x97, 0x46, 0xf4, 0x01, 0xfc, 0x07, 0xd9, - 0x1f, 0x9f, 0x41, 0x87, 0x30, 0xc2, 0xdb, 0xc9, 0xc7, 0x30, 0xe7, 0xcb, 0x94, 0x7e, 0xe1, 0x69, 0x34, 0x1c, 0x0d, - 0xef, 0x9f, 0x41, 0xbd, 0x19, 0x9d, 0x3c, 0xd3, 0x14, 0xda, 0x6d, 0xb5, 0x4c, 0xcb, 0xef, 0xf8, 0x57, 0x66, 0xaa, - 0x9f, 0x9e, 0x9e, 0x0d, 0x3b, 0x30, 0x82, 0x2b, 0x50, 0xa8, 0xc0, 0x78, 0xce, 0x33, 0xd3, 0xe0, 0x55, 0xf6, 0x74, - 0x94, 0x46, 0x0f, 0x1e, 0x1c, 0x77, 0xb2, 0x2c, 0xc2, 0xb7, 0x1f, 0x47, 0xb6, 0xb6, 0xc9, 0x53, 0x00, 0xfb, 0x34, - 0x62, 0x0f, 0x1e, 0x9c, 0xdd, 0xa7, 0xf0, 0xfd, 0xdc, 0xb4, 0x75, 0x3e, 0x1e, 0x66, 0xe7, 0xd0, 0xd6, 0xef, 0x30, - 0x9d, 0x93, 0xf3, 0xe3, 0x91, 0xe9, 0xeb, 0x77, 0x33, 0xea, 0xce, 0xf8, 0x64, 0x7c, 0x62, 0x32, 0xcd, 0x50, 0xcb, - 0xcf, 0xdf, 0x58, 0x1a, 0x65, 0x6c, 0xd4, 0x8e, 0xf0, 0xad, 0x5b, 0xb8, 0x07, 0x27, 0xad, 0xd6, 0xe8, 0x38, 0xc2, - 0xa3, 0x87, 0xf3, 0xf9, 0x5b, 0x03, 0xc1, 0xf6, 0xc9, 0x03, 0xfb, 0xad, 0xbe, 0xdc, 0x41, 0xd3, 0x43, 0x03, 0xb4, - 0x11, 0x9f, 0x99, 0x96, 0xcf, 0x1e, 0xc0, 0x7f, 0xe6, 0xdb, 0x34, 0x5d, 0x7e, 0xcb, 0xd1, 0xc4, 0x2e, 0x4a, 0x9b, - 0x3d, 0x68, 0x41, 0x8d, 0x31, 0xff, 0x38, 0x2c, 0x38, 0xa0, 0xd1, 0xb0, 0x03, 0xff, 0x17, 0xe1, 0x71, 0x7e, 0xf5, - 0xda, 0xe1, 0xec, 0x78, 0x4c, 0xc7, 0xad, 0x08, 0x8f, 0xe5, 0x47, 0xa5, 0x3f, 0x3c, 0x14, 0x69, 0xd4, 0xe9, 0x9c, - 0x0f, 0x4d, 0x99, 0xc5, 0x2f, 0x8a, 0x1b, 0x3c, 0x6e, 0x99, 0x56, 0x26, 0xf4, 0xad, 0x1a, 0x5e, 0x49, 0x58, 0x49, - 0xf8, 0x2f, 0xc2, 0x13, 0xd0, 0xc2, 0xb9, 0x56, 0xce, 0xed, 0x76, 0x98, 0xbc, 0x33, 0xa8, 0x39, 0xba, 0x0f, 0xf0, - 0xf2, 0xcb, 0x38, 0xa2, 0xf4, 0xb4, 0xd3, 0x8a, 0xb0, 0x19, 0xf5, 0x79, 0x0b, 0xfe, 0x8b, 0xb0, 0x85, 0x9c, 0x81, - 0xeb, 0xe4, 0xe3, 0xb3, 0x97, 0x37, 0x69, 0x44, 0x47, 0xe3, 0x31, 0x2c, 0x89, 0x99, 0x8c, 0x2f, 0x36, 0x95, 0x82, - 0xdd, 0xfd, 0x7a, 0xe3, 0xb6, 0x8b, 0x49, 0xd0, 0x0e, 0x3a, 0x67, 0x0f, 0x86, 0x27, 0x11, 0x7e, 0x3b, 0xe2, 0x54, - 0xc0, 0x2a, 0x65, 0xa3, 0xd3, 0xec, 0x34, 0x33, 0x09, 0x13, 0x99, 0x46, 0x27, 0xb0, 0xe4, 0x9d, 0x08, 0xf3, 0xaf, - 0x57, 0x77, 0x16, 0xdd, 0xa0, 0xb6, 0x43, 0x90, 0x71, 0x8b, 0x9d, 0x9d, 0x67, 0x11, 0xce, 0xe9, 0xd7, 0x67, 0xbf, - 0x16, 0x69, 0xc4, 0xce, 0xd8, 0xd9, 0x98, 0xfa, 0xef, 0x3f, 0xd4, 0xd4, 0xd4, 0x68, 0x8d, 0x4f, 0x21, 0xe9, 0x46, - 0x98, 0xb1, 0xde, 0xcf, 0xc6, 0x06, 0x43, 0x5e, 0xcd, 0xa4, 0xc8, 0x9e, 0x8e, 0xc7, 0xd2, 0x62, 0x31, 0x85, 0x4d, - 0xf8, 0x27, 0x40, 0x9b, 0x8e, 0x46, 0xe7, 0xec, 0x2c, 0xc2, 0x7f, 0xda, 0x5d, 0xe2, 0x26, 0xf0, 0xa7, 0xc5, 0x6c, - 0xe6, 0x76, 0xfb, 0x9f, 0x16, 0x28, 0x30, 0xdf, 0x31, 0x1d, 0xd3, 0x51, 0x27, 0xc2, 0x7f, 0x1a, 0xb8, 0x8c, 0x8e, - 0xe1, 0x3f, 0x28, 0x00, 0x9d, 0x3d, 0x68, 0x31, 0xf6, 0xa0, 0x65, 0xbe, 0xc2, 0x3c, 0x37, 0xf3, 0xe1, 0x59, 0xd6, - 0x8e, 0xf0, 0x9f, 0x0e, 0x1d, 0xc7, 0x63, 0xda, 0x02, 0x74, 0xfc, 0xd3, 0xa1, 0x63, 0xa7, 0x35, 0xec, 0x50, 0xf3, - 0x6d, 0xb1, 0xe6, 0xfc, 0x7e, 0xc6, 0x60, 0x72, 0x7f, 0x5a, 0x84, 0xbc, 0x7f, 0xff, 0xfc, 0xfc, 0xc1, 0x03, 0xf8, - 0x34, 0x6d, 0x97, 0x9f, 0x4a, 0x3f, 0xcc, 0x0d, 0x92, 0xb5, 0xb2, 0x13, 0xa0, 0x93, 0x7f, 0x9a, 0x31, 0x8e, 0xc7, - 0x63, 0xd6, 0x8a, 0x70, 0xce, 0x67, 0xcc, 0x62, 0x82, 0xfd, 0x6d, 0x3a, 0x3a, 0xee, 0x64, 0xa3, 0xe3, 0x4e, 0x84, - 0xf3, 0xb7, 0xcf, 0xcc, 0x6c, 0x5a, 0x30, 0x7b, 0xbf, 0xe5, 0x3c, 0xd6, 0xcc, 0xe8, 0x1b, 0x18, 0x24, 0xac, 0x34, - 0x54, 0x7e, 0x1f, 0xd0, 0xc3, 0xb3, 0xb3, 0x6c, 0x04, 0x03, 0x7d, 0x0f, 0xdd, 0x02, 0x18, 0xdf, 0xdb, 0xcd, 0x37, - 0xa4, 0xa7, 0xa7, 0x30, 0xdd, 0xf7, 0xf3, 0x45, 0x31, 0x7f, 0x95, 0x46, 0x0f, 0x8e, 0xef, 0xb7, 0x46, 0xc3, 0x08, - 0xbf, 0x77, 0x13, 0x3c, 0xce, 0x86, 0xc7, 0xf7, 0xdb, 0x11, 0x7e, 0x6f, 0xf6, 0xdb, 0xfd, 0xe1, 0xd9, 0x39, 0x9c, - 0x1b, 0xef, 0xd5, 0xbc, 0x78, 0x3b, 0x31, 0x05, 0xc6, 0xf4, 0x01, 0x34, 0xfb, 0x9b, 0xd9, 0x8d, 0xa3, 0x36, 0x6c, - 0xe4, 0xf7, 0x66, 0x93, 0x19, 0x3c, 0xb9, 0xdf, 0x3e, 0x3d, 0x3f, 0x8d, 0xf0, 0x8c, 0x8f, 0x04, 0x10, 0x78, 0xb3, - 0x51, 0x1e, 0xb4, 0x1f, 0xdc, 0x6f, 0x45, 0x78, 0xf6, 0x56, 0x67, 0x1f, 0xe9, 0xcc, 0x50, 0xe3, 0x31, 0xc0, 0x6c, - 0xc6, 0x95, 0xbe, 0x7b, 0xa3, 0x1c, 0x3d, 0x66, 0xed, 0x08, 0xcf, 0x64, 0x96, 0x51, 0xf5, 0xd6, 0x26, 0x0c, 0x4f, - 0x23, 0x2c, 0xe8, 0x57, 0xfa, 0x59, 0xfa, 0xcd, 0x34, 0x62, 0x74, 0x64, 0xd2, 0x0c, 0x0e, 0x47, 0xf8, 0xdd, 0x08, - 0x2e, 0x23, 0xd3, 0x68, 0x3c, 0x1a, 0x9f, 0x02, 0x78, 0x80, 0x00, 0x59, 0xec, 0x06, 0x68, 0xc0, 0xd7, 0xe8, 0xd1, - 0x30, 0x8d, 0xce, 0x86, 0xe7, 0xac, 0x73, 0x1c, 0xe1, 0x92, 0x1a, 0xd1, 0x53, 0xc8, 0x37, 0x9f, 0x1f, 0xcd, 0x96, - 0x3a, 0xb1, 0x09, 0x06, 0x40, 0x23, 0x7a, 0xbf, 0x35, 0x3a, 0x8b, 0xf0, 0xfc, 0x35, 0xf3, 0x7b, 0x8c, 0x31, 0x76, - 0x0e, 0xb0, 0x84, 0x24, 0x83, 0x40, 0xe7, 0xe3, 0xe1, 0x83, 0x73, 0xf3, 0x0d, 0x60, 0xa0, 0x63, 0xc6, 0x00, 0x48, - 0xf3, 0xd7, 0xac, 0x04, 0xc4, 0x68, 0x78, 0xbf, 0x05, 0xf4, 0x65, 0x4e, 0xe7, 0xf4, 0x8e, 0xde, 0x3c, 0x9d, 0x9b, - 0x39, 0x8d, 0x47, 0xa7, 0x11, 0x9e, 0x3f, 0xff, 0x65, 0xbe, 0x18, 0x8f, 0xcd, 0x84, 0xe8, 0xf0, 0x41, 0x84, 0xe7, - 0xac, 0x58, 0xc0, 0x1a, 0x9d, 0x9f, 0x1e, 0x8f, 0x23, 0xec, 0xd0, 0x30, 0x6b, 0x65, 0x43, 0xb8, 0x6d, 0x5d, 0xcc, - 0xd2, 0x68, 0x34, 0xa2, 0xad, 0x11, 0xdc, 0xbd, 0xca, 0x9b, 0x5f, 0x0b, 0x8b, 0x46, 0xcc, 0xe0, 0x83, 0x5b, 0x43, - 0x98, 0x2f, 0xc0, 0xe3, 0xe3, 0x90, 0x65, 0x19, 0x75, 0x89, 0x67, 0x67, 0xc7, 0xc7, 0x80, 0x7b, 0x76, 0x86, 0x16, - 0x41, 0xde, 0xa8, 0xbb, 0x61, 0x21, 0xe1, 0xe8, 0x02, 0xa2, 0x0a, 0x64, 0xf5, 0xcd, 0xdd, 0x6b, 0x43, 0x57, 0xdb, - 0x67, 0x0f, 0x60, 0x01, 0x14, 0x1d, 0x8d, 0x5e, 0xd9, 0xc3, 0xed, 0x7c, 0x78, 0x72, 0xda, 0x3e, 0x8e, 0xb0, 0xdf, - 0x08, 0xf4, 0xbc, 0x75, 0xbf, 0x03, 0x25, 0xc4, 0xe8, 0xce, 0x96, 0x18, 0x9f, 0xd0, 0x93, 0xb3, 0x56, 0x84, 0xfd, - 0xd6, 0x60, 0xe7, 0xc3, 0xd3, 0xfb, 0xf0, 0xa9, 0xa6, 0x2c, 0xcf, 0x0d, 0x7e, 0x9f, 0x02, 0x5c, 0x14, 0x7f, 0x26, - 0x68, 0x1a, 0xd1, 0xd6, 0x69, 0xa7, 0x33, 0x82, 0xcf, 0xfc, 0x2b, 0x2b, 0xd2, 0x28, 0x6b, 0xc1, 0x7f, 0x11, 0x0e, - 0x76, 0x12, 0x1b, 0x46, 0xd8, 0xe0, 0xdd, 0x19, 0x3d, 0x35, 0x7b, 0xdf, 0xed, 0xaa, 0xd6, 0x79, 0x0b, 0x36, 0xac, - 0xdb, 0x54, 0xee, 0x4b, 0x09, 0x79, 0xe3, 0x48, 0x2c, 0x8d, 0x70, 0x80, 0xa0, 0xe3, 0xfb, 0xe3, 0x08, 0xfb, 0x1d, - 0x77, 0x72, 0x76, 0xde, 0x01, 0x52, 0xa6, 0x81, 0x50, 0x8c, 0x3a, 0xc3, 0x13, 0x20, 0x4d, 0x9a, 0xbd, 0xb6, 0x78, - 0x12, 0x61, 0xfd, 0x54, 0xe9, 0x57, 0x69, 0x34, 0x3a, 0x1f, 0x8e, 0x47, 0xe7, 0x11, 0xd6, 0x72, 0x46, 0xb5, 0x34, - 0x14, 0xf0, 0xf8, 0xe4, 0x7e, 0x84, 0x0d, 0x9a, 0xb7, 0x58, 0x6b, 0xd4, 0x8a, 0xb0, 0x3b, 0x4a, 0x18, 0x3b, 0xef, - 0xc0, 0xb4, 0x7e, 0x7e, 0xae, 0x01, 0x97, 0x47, 0x6c, 0x78, 0x1c, 0xe1, 0x92, 0xde, 0x1b, 0x42, 0x04, 0x5f, 0x6a, - 0x26, 0xbf, 0x38, 0xd6, 0x03, 0x48, 0x9d, 0xdf, 0xf0, 0xb0, 0x0c, 0x2f, 0x6f, 0x2c, 0x1a, 0x51, 0xb3, 0xc5, 0x83, - 0xdb, 0xe8, 0x27, 0x34, 0xf6, 0x6c, 0x3b, 0x27, 0xcb, 0x35, 0x2e, 0x83, 0xbc, 0x7e, 0x61, 0x77, 0x2a, 0x56, 0xca, - 0x70, 0xb2, 0x41, 0x0a, 0x38, 0x62, 0x38, 0xb7, 0x06, 0xe7, 0xb9, 0x0a, 0x82, 0xa4, 0x20, 0xad, 0xae, 0xb8, 0xf0, - 0xde, 0xb4, 0x5d, 0x01, 0xa1, 0x1f, 0x20, 0xbd, 0x20, 0x94, 0x68, 0x88, 0x90, 0x63, 0x85, 0x49, 0xef, 0x64, 0x60, - 0x64, 0x4a, 0x69, 0xdd, 0x16, 0x28, 0xa1, 0x3e, 0x36, 0x3e, 0x5c, 0x95, 0x43, 0xf4, 0x28, 0xd4, 0x95, 0xc4, 0x44, - 0xba, 0x7e, 0x21, 0x74, 0xac, 0x54, 0xbf, 0x18, 0xe0, 0xf6, 0x19, 0xc2, 0x10, 0x43, 0x82, 0xf4, 0xe5, 0xe5, 0x65, - 0xfb, 0xec, 0xc0, 0x08, 0x7d, 0x97, 0x97, 0xe7, 0xf6, 0x07, 0xfc, 0x3b, 0xa8, 0xe2, 0x76, 0xc3, 0xf8, 0xde, 0xb3, - 0x40, 0xa3, 0x67, 0xf8, 0xeb, 0xf7, 0x6c, 0xb5, 0x8a, 0xdf, 0x33, 0x02, 0x33, 0xc6, 0xef, 0x59, 0x62, 0xee, 0x48, - 0xac, 0x87, 0x10, 0xe9, 0x83, 0xe6, 0xac, 0x85, 0x21, 0x9a, 0xbc, 0xe7, 0xbc, 0xdf, 0xb3, 0x3e, 0xaf, 0x7b, 0x97, - 0x57, 0x21, 0x9c, 0x0f, 0x0e, 0x96, 0x45, 0xaa, 0xad, 0x98, 0xa0, 0xad, 0x98, 0xa0, 0xad, 0x98, 0xa0, 0xab, 0x20, - 0xfa, 0x27, 0x3d, 0x90, 0x52, 0x8c, 0xb2, 0xc5, 0xf1, 0xd4, 0xef, 0x40, 0xed, 0x01, 0xda, 0xc9, 0x5e, 0xa5, 0xec, - 0x28, 0x75, 0x15, 0x3b, 0x15, 0x18, 0x3b, 0x13, 0x9d, 0xb6, 0xe3, 0xe8, 0xdf, 0x51, 0x77, 0xbc, 0xac, 0x89, 0x65, - 0xef, 0x76, 0x8a, 0x65, 0xb0, 0x92, 0x46, 0x34, 0xdb, 0xb7, 0xf1, 0x48, 0x74, 0xff, 0xbe, 0x11, 0xcc, 0xaa, 0x20, - 0x79, 0x0d, 0x48, 0xea, 0x82, 0x14, 0x72, 0x6e, 0xa4, 0xb4, 0x02, 0xa5, 0x23, 0x1d, 0x17, 0xa0, 0xa1, 0xf4, 0x0a, - 0xca, 0x32, 0x96, 0x6b, 0xc3, 0x00, 0x44, 0x59, 0x19, 0xcd, 0xca, 0x6a, 0xa7, 0x20, 0xba, 0x80, 0x26, 0xcc, 0x48, - 0x2c, 0xd0, 0x80, 0x30, 0x0d, 0x08, 0x57, 0x19, 0xc4, 0x19, 0x97, 0x7d, 0x62, 0xb2, 0x95, 0xc9, 0x56, 0x65, 0xb6, - 0xf4, 0xd9, 0x56, 0x48, 0x94, 0x26, 0x5b, 0x96, 0xd9, 0x20, 0xb3, 0xe1, 0x49, 0xaa, 0xf0, 0x30, 0x95, 0x56, 0x54, - 0xab, 0x64, 0xab, 0xb7, 0x34, 0xd4, 0xe6, 0x1e, 0x1c, 0xc4, 0xa5, 0x9c, 0x64, 0xd4, 0xc4, 0xf7, 0x96, 0x3c, 0x29, - 0x8c, 0x0c, 0xc4, 0x93, 0x89, 0xfb, 0x3b, 0x5c, 0x6f, 0xca, 0x4a, 0xc5, 0x64, 0xf8, 0x8d, 0x92, 0xe8, 0x93, 0x57, - 0xa2, 0xbe, 0xe7, 0x26, 0x0a, 0xd0, 0x05, 0x49, 0x5a, 0xad, 0xe3, 0xf6, 0x71, 0xeb, 0xbc, 0xc7, 0x0f, 0xdb, 0x9d, - 0xe4, 0x41, 0x27, 0x35, 0x8a, 0x88, 0xb9, 0xbc, 0x01, 0x05, 0xcc, 0x51, 0x27, 0x39, 0x41, 0x87, 0xed, 0xa4, 0x75, - 0x7a, 0xda, 0x84, 0x7f, 0xf0, 0x23, 0x5d, 0x56, 0x3b, 0x69, 0x9d, 0x9c, 0xf6, 0xf8, 0xd1, 0x46, 0xa5, 0x98, 0x37, - 0xa0, 0x20, 0x3a, 0x32, 0x95, 0x30, 0xd4, 0xaf, 0x96, 0xf7, 0xd9, 0x96, 0x9e, 0xe7, 0x91, 0x8e, 0xa5, 0x55, 0xc5, - 0x01, 0x54, 0xfd, 0xd7, 0xc4, 0x00, 0xd1, 0x7f, 0x0d, 0xcb, 0x48, 0xbd, 0xcb, 0x02, 0x44, 0xed, 0xf7, 0x3c, 0x16, - 0x0d, 0x76, 0x18, 0xdb, 0x7c, 0x0d, 0x75, 0x9b, 0x10, 0x3d, 0x0f, 0x4f, 0x5c, 0xae, 0x0a, 0x73, 0x27, 0x08, 0x35, - 0x15, 0xe4, 0x0e, 0x5d, 0xae, 0x0c, 0x73, 0x87, 0x08, 0x35, 0x25, 0xe4, 0xd2, 0x94, 0x27, 0x14, 0x72, 0x74, 0x42, - 0x9b, 0x06, 0x92, 0xd5, 0xa2, 0x3c, 0x67, 0x7e, 0xd8, 0x7c, 0x0c, 0xcb, 0x63, 0x08, 0x8a, 0x13, 0xa4, 0x05, 0xbc, - 0xb0, 0x52, 0x6a, 0x73, 0x5a, 0xb8, 0x54, 0xe3, 0x40, 0x46, 0x03, 0xfe, 0x39, 0x64, 0xe6, 0xd9, 0x8d, 0x56, 0xef, - 0xf8, 0xac, 0x95, 0xb6, 0xc1, 0x55, 0x1c, 0x64, 0x6d, 0x61, 0x65, 0x6d, 0xe1, 0x65, 0x6d, 0xe1, 0x65, 0x6d, 0x10, - 0xe0, 0x83, 0xbe, 0xff, 0x96, 0x35, 0xf3, 0x1b, 0x5e, 0xda, 0xf2, 0x58, 0x63, 0x8d, 0x58, 0xaf, 0x56, 0xcb, 0x35, - 0x58, 0x5a, 0x55, 0x2a, 0x77, 0x55, 0xa9, 0x3f, 0x97, 0x45, 0xda, 0xc2, 0x93, 0x14, 0xb4, 0xdc, 0x2d, 0x4c, 0xcd, - 0xe6, 0xf6, 0x54, 0x61, 0x33, 0x8a, 0x4f, 0xcf, 0xab, 0x93, 0x2f, 0xc9, 0xb1, 0xd1, 0x1e, 0x2f, 0x8b, 0x94, 0x5b, - 0x9a, 0xc1, 0x2d, 0xcd, 0xe0, 0x96, 0x66, 0x40, 0x23, 0xb8, 0x2c, 0x6c, 0xca, 0x26, 0x94, 0xc0, 0x95, 0x40, 0xff, - 0x78, 0x00, 0x41, 0x0c, 0x63, 0x4d, 0xcc, 0xa8, 0x37, 0x3a, 0x6f, 0x43, 0xd0, 0x36, 0x5b, 0x52, 0x27, 0xd4, 0xf8, - 0xae, 0x97, 0x63, 0x7e, 0x55, 0x43, 0xfb, 0x04, 0x5e, 0xd4, 0x79, 0xa8, 0xe3, 0x16, 0x98, 0xae, 0x44, 0x45, 0xd4, - 0x33, 0x64, 0x21, 0x35, 0x3a, 0x1b, 0x67, 0x92, 0xfe, 0x65, 0xc3, 0x13, 0xd8, 0x52, 0x82, 0xf0, 0x1d, 0x89, 0x2f, - 0xac, 0x0a, 0x4d, 0x50, 0x5a, 0xdc, 0x3a, 0x73, 0x39, 0x7b, 0x24, 0x74, 0xc1, 0x6c, 0xde, 0xc7, 0xbc, 0xea, 0x09, - 0x22, 0x95, 0x71, 0xda, 0x24, 0x55, 0xd4, 0x66, 0x70, 0x62, 0x26, 0xb7, 0xd4, 0xb8, 0xf4, 0xbc, 0xb0, 0x7f, 0x5e, - 0xd1, 0xc0, 0xe7, 0xb1, 0x98, 0x0c, 0xbd, 0xab, 0xf0, 0xb5, 0x89, 0x6d, 0x44, 0xf6, 0xf7, 0xad, 0x45, 0xbb, 0xf9, - 0xda, 0x34, 0x69, 0x37, 0x89, 0x26, 0x1b, 0x76, 0xa8, 0x5f, 0xa3, 0xbf, 0xbd, 0xc7, 0x5e, 0x31, 0x19, 0xa2, 0x80, - 0x66, 0x1b, 0xb0, 0xca, 0x0a, 0x58, 0xca, 0xd5, 0x2b, 0x1d, 0x39, 0xa1, 0x77, 0x33, 0xe6, 0x75, 0x31, 0x19, 0xee, - 0x7c, 0x7a, 0xc5, 0xf6, 0xd8, 0x7b, 0x4b, 0x83, 0x1e, 0xbc, 0x6a, 0x7b, 0xca, 0x6e, 0xbf, 0x57, 0xe7, 0x66, 0x67, - 0x1d, 0x95, 0x7f, 0xaf, 0xce, 0xd3, 0x5d, 0x75, 0x66, 0xfc, 0x36, 0xf6, 0x7b, 0x47, 0x07, 0x6a, 0x6c, 0x63, 0x26, - 0x35, 0x19, 0x42, 0xac, 0x7c, 0xf8, 0x6b, 0x23, 0xda, 0x74, 0x3d, 0x09, 0x87, 0x55, 0x90, 0xbd, 0xe4, 0x34, 0x65, - 0x98, 0x92, 0xce, 0x61, 0x61, 0x62, 0xda, 0x88, 0x84, 0x36, 0x55, 0x42, 0x71, 0x4e, 0xe2, 0x98, 0x1e, 0x66, 0x10, - 0x99, 0xa7, 0xdd, 0xa3, 0x69, 0x4c, 0x1b, 0x19, 0x3a, 0x8a, 0xdb, 0x0d, 0x7a, 0x98, 0x21, 0xd4, 0x68, 0x83, 0xce, - 0x54, 0x92, 0x76, 0x33, 0x87, 0x58, 0x9d, 0x86, 0x14, 0xe7, 0x87, 0x22, 0x29, 0x1a, 0xf2, 0x50, 0x25, 0x45, 0x23, - 0x39, 0xc5, 0x22, 0x99, 0x94, 0xc9, 0x13, 0x93, 0x3c, 0xb1, 0xc9, 0xc3, 0x32, 0x79, 0x68, 0x92, 0x87, 0x36, 0x99, - 0x92, 0xe2, 0x50, 0x24, 0xb4, 0x11, 0xb7, 0x9b, 0x05, 0x3a, 0x84, 0x11, 0xf8, 0xd1, 0x13, 0x11, 0x86, 0x48, 0x5f, - 0x1b, 0x1b, 0xa3, 0xb9, 0xcc, 0x5d, 0xd0, 0xd2, 0x0a, 0x48, 0xa5, 0xe3, 0x17, 0xd4, 0x79, 0x16, 0x80, 0x09, 0x6b, - 0xfb, 0xc7, 0x87, 0xe4, 0x5b, 0x67, 0xb9, 0x14, 0x81, 0x63, 0x1b, 0xd8, 0xe2, 0x7f, 0x71, 0xee, 0x3c, 0x00, 0xd5, - 0x35, 0xcd, 0xe7, 0x53, 0xba, 0xe5, 0x3d, 0x5c, 0x4c, 0x86, 0x6e, 0x67, 0x95, 0xcd, 0x30, 0x5a, 0xd8, 0x50, 0xd7, - 0x75, 0x3f, 0x4f, 0x00, 0xb5, 0xf7, 0x2d, 0x4d, 0xa8, 0x51, 0x92, 0xdb, 0x1a, 0x93, 0x82, 0xdd, 0xa9, 0x8c, 0xe6, - 0x2c, 0xae, 0x0e, 0xe0, 0x6a, 0x98, 0x8c, 0xbc, 0x00, 0x8f, 0x80, 0xe2, 0x30, 0x39, 0x6e, 0xe8, 0x64, 0x72, 0x98, - 0x9c, 0x3e, 0x68, 0xe8, 0x64, 0x78, 0x98, 0xb4, 0xdb, 0x15, 0xce, 0x26, 0x05, 0xd1, 0xc9, 0x84, 0x68, 0xd0, 0x18, - 0xda, 0x46, 0xe5, 0x9c, 0x82, 0x89, 0xdb, 0xbf, 0x31, 0x8c, 0x86, 0x1b, 0x86, 0x60, 0x13, 0x1b, 0xf5, 0x73, 0x6b, - 0x0c, 0x61, 0x37, 0x9d, 0xd3, 0xd3, 0xa6, 0x4e, 0x0a, 0xac, 0xed, 0x4a, 0x36, 0x75, 0x32, 0xc1, 0xda, 0x2e, 0x5f, - 0x53, 0x27, 0x43, 0xdb, 0x94, 0xd1, 0x01, 0x32, 0x11, 0x00, 0xeb, 0x39, 0x0b, 0x20, 0xdf, 0xf1, 0x4e, 0x3a, 0x6b, - 0xd0, 0x1a, 0x7e, 0xaf, 0x5c, 0xd3, 0x17, 0x54, 0x54, 0x83, 0xa9, 0x13, 0xfb, 0x56, 0xd1, 0x76, 0xd5, 0x24, 0xfb, - 0xd7, 0x65, 0xcb, 0x66, 0x0b, 0xa9, 0xeb, 0x05, 0x1f, 0xd6, 0x30, 0xc4, 0x95, 0x72, 0x07, 0xf7, 0x3f, 0x94, 0xc4, - 0x10, 0xdb, 0xcf, 0x9c, 0x42, 0x9c, 0x78, 0x3d, 0x32, 0x24, 0xf1, 0x46, 0x63, 0x8d, 0xe2, 0xe0, 0xbc, 0x7d, 0x1a, - 0x52, 0xd5, 0xad, 0x80, 0x7f, 0x84, 0x44, 0x0b, 0x61, 0x4d, 0x42, 0x47, 0x51, 0xc0, 0x82, 0x38, 0xed, 0x6e, 0xed, - 0x80, 0x38, 0x38, 0xd8, 0x3c, 0x2f, 0xfc, 0xd3, 0x0b, 0x5b, 0xcf, 0x2d, 0x54, 0xf6, 0x84, 0xfe, 0x41, 0x28, 0x6b, - 0x69, 0xcc, 0x03, 0x44, 0xf1, 0xa1, 0xb7, 0xee, 0x1b, 0x0a, 0xdf, 0xaf, 0xe2, 0x0e, 0xba, 0x9c, 0xe6, 0x99, 0xc9, - 0x30, 0x7d, 0x0d, 0x82, 0xb1, 0xbd, 0x09, 0x27, 0x54, 0xda, 0x4a, 0xfe, 0xcb, 0x8e, 0x83, 0x4e, 0xdc, 0x83, 0x35, - 0x61, 0xa3, 0x9f, 0x43, 0xcb, 0xe4, 0x0a, 0x36, 0xce, 0x27, 0x7d, 0xb5, 0xaa, 0x3d, 0x4f, 0x64, 0x1f, 0xc1, 0x41, - 0x07, 0x07, 0x5c, 0x3d, 0x03, 0x63, 0x6a, 0x16, 0x37, 0xc2, 0xc3, 0xf7, 0xef, 0xda, 0x69, 0xfd, 0xd9, 0x9c, 0xab, - 0x69, 0x70, 0xd0, 0x3d, 0xac, 0xe5, 0xef, 0x5c, 0x89, 0x9e, 0x4e, 0xb9, 0x5b, 0xeb, 0xcf, 0x95, 0xa9, 0xfa, 0xd6, - 0x43, 0x59, 0x07, 0x07, 0xbc, 0x0a, 0x57, 0x15, 0xfd, 0x10, 0xa1, 0x9e, 0x91, 0x41, 0x9e, 0xe5, 0x92, 0xc2, 0x8d, - 0x28, 0x5c, 0x31, 0xa4, 0x0d, 0x7e, 0xa4, 0xf1, 0x1f, 0xf2, 0xff, 0x53, 0x23, 0x87, 0x3a, 0x6d, 0xf0, 0x40, 0x00, - 0x0b, 0x59, 0xa1, 0x2a, 0x50, 0xa4, 0x81, 0x74, 0x68, 0x79, 0x8e, 0xca, 0xc3, 0x9c, 0xce, 0xe7, 0xf9, 0x9d, 0x79, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xcc, 0xbd, 0x6d, 0x7b, 0x1b, 0x37, 0xb2, 0x20, 0xfa, + 0xf9, 0xee, 0xaf, 0x90, 0xfa, 0x38, 0x4a, 0x43, 0x04, 0x5b, 0x24, 0x25, 0xca, 0x72, 0x53, 0x10, 0xd7, 0xaf, 0x63, + 0x27, 0x8e, 0xed, 0x58, 0xb6, 0x33, 0x0e, 0xc3, 0xe3, 0x80, 0x4d, 0x90, 0x84, 0xdd, 0x04, 0x98, 0x06, 0x68, 0x49, + 0x21, 0xf9, 0xdf, 0xef, 0x53, 0x78, 0xe9, 0x46, 0x93, 0xb4, 0x67, 0x66, 0xef, 0xee, 0x7d, 0xf6, 0xe4, 0x8c, 0xc5, + 0xc6, 0x3b, 0x0a, 0x85, 0x42, 0x55, 0xa1, 0xaa, 0x70, 0x79, 0x38, 0x96, 0x99, 0xbe, 0x5b, 0xb0, 0x83, 0x99, 0x9e, + 0xe7, 0x57, 0x97, 0xee, 0x5f, 0x46, 0xc7, 0x57, 0x97, 0x39, 0x17, 0x5f, 0x0e, 0x0a, 0x96, 0x13, 0x9e, 0x49, 0x71, + 0x30, 0x2b, 0xd8, 0x84, 0x8c, 0xa9, 0xa6, 0x29, 0x9f, 0xd3, 0x29, 0x3b, 0x38, 0xb9, 0xba, 0x9c, 0x33, 0x4d, 0x0f, + 0xb2, 0x19, 0x2d, 0x14, 0xd3, 0xe4, 0xfd, 0xbb, 0x67, 0xcd, 0x8b, 0xab, 0x4b, 0x95, 0x15, 0x7c, 0xa1, 0x0f, 0xa0, + 0x49, 0x32, 0x97, 0xe3, 0x65, 0xce, 0xae, 0x4e, 0x4e, 0x6e, 0x6e, 0x6e, 0x92, 0xcf, 0xea, 0x7f, 0x7c, 0xa5, 0xc5, + 0xc1, 0x3f, 0x0a, 0xf2, 0x7a, 0xf4, 0x99, 0x65, 0x3a, 0x19, 0xb3, 0x09, 0x17, 0xec, 0x4d, 0x21, 0x17, 0xac, 0xd0, + 0x77, 0x3d, 0xc8, 0xfc, 0xb5, 0x20, 0x31, 0xc7, 0x1a, 0x33, 0x44, 0xae, 0xf4, 0x01, 0x17, 0x07, 0xbc, 0xff, 0x8f, + 0xc2, 0xa4, 0xac, 0x98, 0x58, 0xce, 0x59, 0x41, 0x47, 0x39, 0x4b, 0x0f, 0x5b, 0x38, 0x93, 0x62, 0xc2, 0xa7, 0xcb, + 0xf2, 0xfb, 0xa6, 0xe0, 0xda, 0xff, 0xfe, 0x4a, 0xf3, 0x25, 0x4b, 0xd9, 0x06, 0xa5, 0x7c, 0xa0, 0x87, 0x84, 0x99, + 0x96, 0xbf, 0x54, 0x0d, 0xc7, 0xbf, 0x9a, 0x26, 0xef, 0x16, 0x4c, 0x4e, 0x0e, 0xf4, 0x21, 0x89, 0xd4, 0xdd, 0x7c, + 0x24, 0xf3, 0xa8, 0xaf, 0x1b, 0x51, 0x94, 0x42, 0x19, 0xcc, 0x50, 0x2f, 0x93, 0x42, 0xe9, 0x03, 0xc1, 0xc9, 0x0d, + 0x17, 0x63, 0x79, 0x83, 0x6f, 0x04, 0x11, 0x3c, 0xb9, 0x9e, 0xd1, 0xb1, 0xbc, 0x79, 0x2b, 0xa5, 0x3e, 0x3a, 0x8a, + 0xdd, 0xf7, 0xdd, 0xe3, 0xeb, 0x6b, 0x42, 0xc8, 0x57, 0xc9, 0xc7, 0x07, 0xad, 0xf5, 0x3a, 0x48, 0x4d, 0x04, 0xd5, + 0xfc, 0x2b, 0xb3, 0x95, 0xd0, 0xd1, 0x51, 0x44, 0xc7, 0x72, 0xa1, 0xd9, 0xf8, 0x5a, 0xdf, 0xe5, 0xec, 0x7a, 0xc6, + 0x98, 0x56, 0x11, 0x17, 0x07, 0x4f, 0x64, 0xb6, 0x9c, 0x33, 0xa1, 0x93, 0x45, 0x21, 0xb5, 0x84, 0x81, 0x1d, 0x1d, + 0x45, 0x05, 0x5b, 0xe4, 0x34, 0x63, 0x90, 0xff, 0xf8, 0xfa, 0xba, 0xaa, 0x51, 0x15, 0xc2, 0x5f, 0x04, 0xb9, 0x36, + 0x43, 0x8f, 0x11, 0xfe, 0x4d, 0x10, 0xc1, 0x6e, 0x0e, 0x7e, 0x63, 0xf4, 0xcb, 0x2f, 0x74, 0xd1, 0xcb, 0x72, 0xaa, + 0xd4, 0xc1, 0x2b, 0xb9, 0x32, 0xd3, 0x28, 0x96, 0x99, 0x96, 0x45, 0xac, 0x31, 0xc3, 0x02, 0xad, 0xf8, 0x24, 0xd6, + 0x33, 0xae, 0x92, 0x4f, 0xf7, 0x32, 0xa5, 0xde, 0x32, 0xb5, 0xcc, 0xf5, 0x3d, 0x72, 0xd8, 0xc2, 0xe2, 0x90, 0x90, + 0x2f, 0x02, 0xe9, 0x59, 0x21, 0x6f, 0x0e, 0x9e, 0x16, 0x85, 0x2c, 0xe2, 0xe8, 0xf1, 0xf5, 0xb5, 0x2d, 0x71, 0xc0, + 0xd5, 0x81, 0x90, 0xfa, 0xa0, 0x6c, 0x0f, 0xa0, 0x9d, 0x1c, 0xbc, 0x57, 0xec, 0xe0, 0xcf, 0xa5, 0x50, 0x74, 0xc2, + 0x1e, 0x5f, 0x5f, 0xff, 0x79, 0x20, 0x8b, 0x83, 0x3f, 0x33, 0xa5, 0xfe, 0x3c, 0xe0, 0x42, 0x69, 0x46, 0xc7, 0x49, + 0x84, 0x7a, 0xa6, 0xb3, 0x4c, 0xa9, 0x77, 0xec, 0x56, 0x13, 0x8d, 0xcd, 0xa7, 0x26, 0x6c, 0x33, 0x65, 0xfa, 0x40, + 0x95, 0xf3, 0x8a, 0xd1, 0x2a, 0x67, 0xfa, 0x40, 0x13, 0x93, 0x2f, 0x1d, 0xfc, 0x99, 0xfd, 0xd4, 0x3d, 0x3e, 0x89, + 0x6f, 0xc4, 0xd1, 0x91, 0x2e, 0x01, 0x8d, 0x56, 0x6e, 0x85, 0x08, 0x3b, 0xf4, 0x69, 0x47, 0x47, 0x2c, 0xc9, 0x99, + 0x98, 0xea, 0x19, 0x21, 0xa4, 0xdd, 0x13, 0x47, 0x47, 0xb1, 0x26, 0xbf, 0x89, 0x64, 0xca, 0x74, 0xcc, 0x10, 0xc2, + 0x55, 0xed, 0xa3, 0xa3, 0xd8, 0x02, 0x41, 0x12, 0x6d, 0x00, 0x57, 0x83, 0x31, 0x4a, 0x1c, 0xf4, 0xaf, 0xef, 0x44, + 0x16, 0x87, 0xe3, 0x47, 0x58, 0x1c, 0x1d, 0xfd, 0x26, 0x12, 0x05, 0x2d, 0x62, 0x8d, 0xd0, 0xa6, 0x60, 0x7a, 0x59, + 0x88, 0x03, 0xbd, 0xd1, 0xf2, 0x5a, 0x17, 0x5c, 0x4c, 0x63, 0xb4, 0xf2, 0x69, 0x41, 0xc5, 0xcd, 0xc6, 0x0e, 0xf7, + 0xf7, 0x82, 0x70, 0x72, 0x05, 0x3d, 0xbe, 0x92, 0xb1, 0xc3, 0x41, 0x4e, 0x48, 0xa4, 0x4c, 0xdd, 0xa8, 0xcf, 0x53, + 0xde, 0x88, 0x22, 0x6c, 0x47, 0x89, 0xbf, 0x08, 0x84, 0x85, 0x06, 0xd4, 0x4d, 0x92, 0x44, 0x23, 0x72, 0xb5, 0xf2, + 0x60, 0xe1, 0xc1, 0x44, 0xfb, 0x7c, 0xd0, 0x1a, 0xa6, 0x3a, 0x29, 0xd8, 0x78, 0x99, 0xb1, 0x38, 0x16, 0x58, 0x61, + 0x89, 0xc8, 0x95, 0x68, 0xc4, 0x05, 0xb9, 0x82, 0xf5, 0x2e, 0xea, 0x8b, 0x4d, 0xc8, 0x61, 0x0b, 0xb9, 0x41, 0x16, + 0x7e, 0x84, 0x00, 0x62, 0x37, 0xa0, 0x82, 0x90, 0x48, 0x2c, 0xe7, 0x23, 0x56, 0x44, 0x65, 0xb1, 0x5e, 0x0d, 0x2f, + 0x96, 0x8a, 0x1d, 0x64, 0x4a, 0x1d, 0x4c, 0x96, 0x22, 0xd3, 0x5c, 0x8a, 0x83, 0xa8, 0x51, 0x34, 0x22, 0x8b, 0x0f, + 0x25, 0x3a, 0x44, 0x68, 0x83, 0x62, 0x85, 0x1a, 0x7c, 0x20, 0x1b, 0xed, 0x21, 0x86, 0x51, 0xa2, 0x9e, 0x6b, 0xcf, + 0x41, 0x80, 0x61, 0x0e, 0x93, 0xdc, 0xe0, 0x9f, 0xec, 0xce, 0x87, 0x29, 0xde, 0x88, 0x3e, 0x4f, 0x76, 0x77, 0x0a, + 0xd1, 0xc9, 0x9c, 0x2e, 0x62, 0x46, 0xae, 0x98, 0xc1, 0x2e, 0x2a, 0x32, 0x18, 0x6b, 0x6d, 0xe1, 0xfa, 0x2c, 0x65, + 0x49, 0x85, 0x53, 0x28, 0xd5, 0xc9, 0x44, 0x16, 0x4f, 0x69, 0x36, 0x83, 0x7a, 0x25, 0xc6, 0x8c, 0xfd, 0x86, 0xcb, + 0x0a, 0x46, 0x35, 0x7b, 0x9a, 0x33, 0xf8, 0x8a, 0x23, 0x53, 0x33, 0x42, 0x58, 0xc1, 0x56, 0xcf, 0xb9, 0x7e, 0x25, + 0x45, 0xc6, 0x7a, 0x2a, 0xc0, 0x2f, 0xb3, 0xf2, 0x0f, 0xb5, 0x2e, 0xf8, 0x68, 0xa9, 0x59, 0x1c, 0x09, 0x28, 0x11, + 0x61, 0x85, 0xb0, 0x48, 0x34, 0xbb, 0xd5, 0x8f, 0xa5, 0xd0, 0x4c, 0x68, 0xc2, 0x3c, 0x54, 0x31, 0x4f, 0xe8, 0x62, + 0xc1, 0xc4, 0xf8, 0xf1, 0x8c, 0xe7, 0xe3, 0x58, 0xa0, 0x0d, 0xda, 0xe0, 0x8f, 0x82, 0xc0, 0x24, 0xc9, 0x15, 0x4f, + 0xe1, 0x9f, 0x6f, 0x4f, 0x27, 0xd6, 0xe4, 0xca, 0x6c, 0x0b, 0x46, 0xa2, 0xa8, 0x37, 0x91, 0x45, 0xec, 0xa6, 0x70, + 0x00, 0xa4, 0x0b, 0xfa, 0x78, 0xbb, 0xcc, 0x99, 0x42, 0xac, 0x41, 0x44, 0xb9, 0x8e, 0x0e, 0xc2, 0xbf, 0x17, 0x31, + 0x83, 0x05, 0xe0, 0x28, 0xe5, 0x86, 0x04, 0xbe, 0xe4, 0x6e, 0x53, 0x8d, 0x4b, 0xa2, 0xf6, 0x97, 0x20, 0x63, 0x9e, + 0xe8, 0x62, 0xa9, 0x34, 0x1b, 0xbf, 0xbb, 0x5b, 0x30, 0x85, 0x35, 0x25, 0x7f, 0x89, 0xfe, 0x5f, 0x22, 0x61, 0xf3, + 0x85, 0xbe, 0xbb, 0x36, 0xd4, 0x3c, 0x8d, 0x22, 0xfc, 0x4f, 0x53, 0xb4, 0x60, 0x34, 0x03, 0x92, 0xe6, 0x40, 0xf6, + 0x46, 0xe6, 0x77, 0x13, 0x9e, 0xe7, 0xd7, 0xcb, 0xc5, 0x42, 0x16, 0x1a, 0x6b, 0x41, 0x56, 0x5a, 0x56, 0xf0, 0x81, + 0x15, 0x5d, 0xa9, 0x1b, 0xae, 0xb3, 0x59, 0xac, 0xd1, 0x2a, 0xa3, 0x8a, 0x1d, 0x3c, 0x92, 0x32, 0x67, 0x54, 0xa4, + 0x9c, 0xf0, 0xbe, 0xa6, 0xa9, 0x58, 0xe6, 0x79, 0x6f, 0x54, 0x30, 0xfa, 0xa5, 0x67, 0xb2, 0xed, 0xe1, 0x90, 0x9a, + 0xdf, 0x0f, 0x8b, 0x82, 0xde, 0x41, 0x41, 0x42, 0xa0, 0x58, 0x9f, 0xa7, 0x3f, 0x5d, 0xbf, 0x7e, 0x95, 0xd8, 0xbd, + 0xc2, 0x27, 0x77, 0x31, 0x2f, 0xf7, 0x1f, 0xdf, 0xe0, 0x49, 0x21, 0xe7, 0x5b, 0x5d, 0x5b, 0xd0, 0xf1, 0xde, 0x37, + 0x86, 0xc0, 0x08, 0x3f, 0xb4, 0x4d, 0x87, 0x23, 0x78, 0x65, 0x30, 0x1f, 0x32, 0x89, 0xeb, 0x17, 0xfe, 0x49, 0x6d, + 0x72, 0xcc, 0xd1, 0xf7, 0x47, 0xab, 0x8b, 0xbb, 0x15, 0x23, 0x66, 0x9c, 0x0b, 0x38, 0x18, 0x61, 0x8c, 0x19, 0xd5, + 0xd9, 0x6c, 0xc5, 0x4c, 0x63, 0x1b, 0x3f, 0x62, 0xb6, 0xd9, 0xe0, 0xbf, 0xa5, 0xc7, 0x7a, 0x7d, 0x48, 0x08, 0x37, + 0xf4, 0x8a, 0xe8, 0xf5, 0x9a, 0x13, 0xc2, 0x11, 0x7e, 0xcb, 0xc9, 0x8a, 0xfa, 0x09, 0xc1, 0xc9, 0x06, 0xdb, 0x33, + 0xb5, 0x54, 0x06, 0x4e, 0xc0, 0xaf, 0xac, 0xd0, 0xac, 0x48, 0xb5, 0xc0, 0x05, 0x9b, 0xe4, 0x30, 0x8e, 0xc3, 0x36, + 0x9e, 0x51, 0xf5, 0x78, 0x46, 0xc5, 0x94, 0x8d, 0xd3, 0xbf, 0xe5, 0x06, 0x33, 0x41, 0xa2, 0x09, 0x17, 0x34, 0xe7, + 0x7f, 0xb3, 0x71, 0xe4, 0xce, 0x85, 0x0f, 0xfa, 0x80, 0xdd, 0x6a, 0x26, 0xc6, 0xea, 0xe0, 0xf9, 0xbb, 0x5f, 0x5e, + 0xba, 0xc5, 0xac, 0x9d, 0x15, 0x68, 0xa5, 0x96, 0x0b, 0x56, 0xc4, 0x08, 0xbb, 0xb3, 0xe2, 0x29, 0x37, 0x74, 0xf2, + 0x17, 0xba, 0xb0, 0x29, 0x5c, 0xbd, 0x5f, 0x8c, 0xa9, 0x66, 0x6f, 0x98, 0x18, 0x73, 0x31, 0x25, 0x87, 0x6d, 0x9b, + 0x3e, 0xa3, 0x2e, 0x63, 0x5c, 0x26, 0x7d, 0xba, 0xf7, 0x34, 0x37, 0x73, 0x2f, 0x3f, 0x97, 0x31, 0xda, 0x28, 0x4d, + 0x35, 0xcf, 0x0e, 0xe8, 0x78, 0xfc, 0x42, 0x70, 0xcd, 0xcd, 0x08, 0x0b, 0x58, 0x22, 0xc0, 0x55, 0x66, 0x4f, 0x0d, + 0x3f, 0xf2, 0x18, 0xe1, 0x38, 0x76, 0x67, 0xc1, 0x0c, 0xb9, 0x35, 0x3b, 0x3a, 0xaa, 0x28, 0x7f, 0x9f, 0xa5, 0x36, + 0x93, 0x0c, 0x86, 0x28, 0x59, 0x2c, 0x15, 0x2c, 0xb6, 0xef, 0x02, 0x0e, 0x1a, 0x39, 0x52, 0xac, 0xf8, 0xca, 0xc6, + 0x25, 0x82, 0xa8, 0x18, 0xad, 0xb6, 0xfa, 0x70, 0xdb, 0x43, 0x93, 0xc1, 0xb0, 0x17, 0x92, 0x70, 0xe6, 0x90, 0xdd, + 0x72, 0x2a, 0x9c, 0xa9, 0x92, 0xa8, 0xc4, 0x70, 0xa0, 0x96, 0x84, 0x45, 0x11, 0x3f, 0xbf, 0x45, 0x2c, 0x80, 0x87, + 0x08, 0x29, 0x87, 0x3f, 0x73, 0x9f, 0x7e, 0x35, 0x87, 0x87, 0xc2, 0x02, 0x61, 0x6d, 0x47, 0xaa, 0x10, 0xda, 0x20, + 0xac, 0xfd, 0x70, 0x2d, 0x51, 0xf2, 0x7c, 0x11, 0x9c, 0xda, 0xe4, 0x2d, 0x37, 0xc7, 0x36, 0xd0, 0x36, 0xaa, 0xd9, + 0xd1, 0x51, 0xcc, 0x92, 0x12, 0x31, 0xc8, 0x61, 0xdb, 0x2d, 0x52, 0x00, 0xad, 0x6f, 0x8c, 0x1b, 0x7a, 0x36, 0x0c, + 0xce, 0x21, 0x4b, 0x84, 0x7c, 0x98, 0x65, 0x4c, 0x29, 0x59, 0x1c, 0x1d, 0x1d, 0x9a, 0xf2, 0x25, 0x67, 0x01, 0x8b, + 0xf8, 0xfa, 0x46, 0x54, 0x43, 0x40, 0xd5, 0x69, 0xeb, 0xf9, 0x26, 0x52, 0xf1, 0x4d, 0x9e, 0x09, 0x49, 0xa3, 0x4f, + 0x9f, 0xa2, 0x86, 0xc6, 0x0e, 0x0e, 0x53, 0xe6, 0xbb, 0xbe, 0x7b, 0xc2, 0x2c, 0x5b, 0x68, 0x98, 0x90, 0x1d, 0xd0, + 0xec, 0xe5, 0x07, 0xe3, 0xfa, 0x90, 0xb0, 0xc6, 0x0a, 0x6d, 0x82, 0x15, 0xdd, 0xdb, 0xb4, 0xe1, 0x6f, 0xec, 0xd2, + 0xad, 0xa6, 0x86, 0xa7, 0x08, 0xd6, 0x71, 0xc0, 0x86, 0x1b, 0x6c, 0x60, 0xef, 0x67, 0x23, 0xcd, 0x40, 0x07, 0x7a, + 0xd8, 0x73, 0xf9, 0x44, 0x59, 0xc8, 0x15, 0xec, 0xaf, 0x25, 0x53, 0xda, 0x22, 0x72, 0xac, 0xb1, 0xc4, 0x70, 0x46, + 0x6d, 0x33, 0x9d, 0x35, 0x96, 0x74, 0xdf, 0xd8, 0x5e, 0x2f, 0xe0, 0x6c, 0x54, 0x80, 0xd4, 0xdf, 0xc7, 0x27, 0x18, + 0xab, 0x46, 0xeb, 0xf5, 0x5b, 0xee, 0x5b, 0xa9, 0xd6, 0xb2, 0xe4, 0xd7, 0xb6, 0x16, 0x85, 0x09, 0xe4, 0x0e, 0xe7, + 0xc3, 0xb6, 0x1b, 0xbf, 0x18, 0x92, 0xc3, 0x56, 0x89, 0xc5, 0x0e, 0xac, 0x76, 0x3c, 0x16, 0x8a, 0xaf, 0x6d, 0x53, + 0xc8, 0x9c, 0xf5, 0x35, 0x7c, 0x49, 0x66, 0x3b, 0xb8, 0x3a, 0x23, 0x03, 0xe0, 0x3a, 0x92, 0xd9, 0xf0, 0x5b, 0xf8, + 0xe4, 0x29, 0x42, 0xac, 0x77, 0xf3, 0x2a, 0xc2, 0xf1, 0xb5, 0x4e, 0x38, 0xb6, 0xa6, 0x11, 0x2d, 0xca, 0x2a, 0x51, + 0x89, 0x66, 0x6e, 0xab, 0x57, 0x59, 0x58, 0x98, 0xc1, 0x54, 0x53, 0x0a, 0x9a, 0x78, 0x45, 0xe7, 0x4c, 0xc5, 0x0c, + 0xe1, 0x6f, 0x15, 0xb0, 0xf8, 0x09, 0x45, 0x86, 0xc1, 0x19, 0xaa, 0xe0, 0x0c, 0x05, 0x76, 0x17, 0x98, 0xb4, 0xfa, + 0x96, 0x53, 0x98, 0x0d, 0xd4, 0xb0, 0xe2, 0xed, 0x82, 0xc9, 0x9b, 0xc3, 0xd9, 0x21, 0xb8, 0x87, 0x9f, 0x4d, 0xb3, + 0x40, 0x33, 0x2c, 0x84, 0x42, 0xf8, 0xb0, 0xb5, 0xbd, 0x92, 0xbe, 0x54, 0x35, 0xc7, 0xc1, 0x10, 0xd6, 0xc1, 0x1c, + 0x1b, 0x09, 0x57, 0xe6, 0x6f, 0x6d, 0xab, 0x01, 0xd8, 0xae, 0x01, 0x33, 0x92, 0x49, 0x4e, 0x75, 0xdc, 0x3e, 0x69, + 0x01, 0x63, 0xfa, 0x95, 0xc1, 0xa9, 0x82, 0xd0, 0xee, 0x54, 0x58, 0xb2, 0x14, 0x6a, 0xc6, 0x27, 0x3a, 0xfe, 0x28, + 0x0c, 0x51, 0x61, 0xb9, 0x62, 0x20, 0xe1, 0x04, 0xec, 0xb1, 0x21, 0x38, 0x1f, 0x05, 0xf4, 0xd3, 0x2b, 0x0f, 0x22, + 0x37, 0x52, 0x43, 0xb8, 0x80, 0x3c, 0x54, 0xac, 0x75, 0x45, 0x66, 0x4a, 0xc6, 0x0d, 0xb8, 0xc7, 0x76, 0xdf, 0xb6, + 0x98, 0x3a, 0x6a, 0x20, 0x02, 0x0e, 0x56, 0xa4, 0x21, 0x89, 0x70, 0x89, 0x3a, 0xd1, 0xf2, 0xa5, 0xbc, 0x61, 0xc5, + 0x63, 0x0a, 0x83, 0x4f, 0x6d, 0xf5, 0x8d, 0x3d, 0x0a, 0x0c, 0xc5, 0xd7, 0x3d, 0x8f, 0x2f, 0x9f, 0xcc, 0xc4, 0xdf, + 0x14, 0x72, 0xce, 0x15, 0x03, 0xbe, 0xcd, 0xc2, 0x5f, 0xc0, 0x46, 0x33, 0x3b, 0x12, 0x8e, 0x1b, 0x56, 0xe2, 0xd7, + 0xc3, 0x97, 0x75, 0xfc, 0xfa, 0x74, 0xef, 0xe9, 0xd4, 0x53, 0xc0, 0xfa, 0x3e, 0x46, 0x38, 0x76, 0xe2, 0x45, 0x70, + 0xd2, 0x25, 0x33, 0xe4, 0x8e, 0xf9, 0xf5, 0x5a, 0x07, 0x62, 0x5c, 0x8d, 0x73, 0x64, 0x76, 0xdb, 0xa0, 0x0d, 0x1d, + 0x8f, 0x81, 0xc5, 0x2b, 0x64, 0x9e, 0x07, 0x87, 0x15, 0x16, 0xbd, 0xf2, 0x78, 0xfa, 0x74, 0xef, 0xe9, 0xf5, 0xf7, + 0x4e, 0x28, 0xc8, 0x0f, 0x0f, 0x29, 0x3f, 0x50, 0x31, 0x66, 0x05, 0xc8, 0x95, 0xc1, 0x6a, 0xb9, 0x73, 0xf6, 0xb1, + 0x14, 0x82, 0x65, 0x9a, 0x8d, 0x41, 0x68, 0x11, 0x44, 0x27, 0x33, 0xa9, 0x74, 0x99, 0x58, 0x8d, 0x5e, 0x84, 0x42, + 0x68, 0x92, 0xd1, 0x3c, 0x8f, 0xad, 0x80, 0x32, 0x97, 0x5f, 0xd9, 0x9e, 0x51, 0xf7, 0x6a, 0x43, 0x2e, 0x9b, 0x61, + 0x41, 0x33, 0x2c, 0x51, 0x8b, 0x9c, 0x67, 0xac, 0x3c, 0xbc, 0xae, 0x13, 0x2e, 0xc6, 0xec, 0x16, 0xe8, 0x08, 0xba, + 0xba, 0xba, 0x6a, 0xe1, 0x36, 0xda, 0x58, 0x80, 0xaf, 0x76, 0x00, 0xfb, 0x9d, 0x63, 0xd3, 0x0a, 0xe2, 0xab, 0xbd, + 0x64, 0x0d, 0x05, 0x67, 0x25, 0xf7, 0x82, 0x96, 0x25, 0xcf, 0x08, 0x8f, 0x59, 0xce, 0x34, 0xf3, 0xe4, 0x1c, 0x98, + 0x69, 0xbb, 0x75, 0xdf, 0x96, 0xf0, 0x2b, 0xd1, 0xc9, 0xef, 0x32, 0xbf, 0xe6, 0xaa, 0x14, 0xdd, 0xab, 0xe5, 0xa9, + 0xa0, 0xdd, 0xd7, 0x76, 0x79, 0xa8, 0xd6, 0x34, 0x9b, 0x59, 0x89, 0x3d, 0xde, 0x99, 0x52, 0xd5, 0x86, 0x23, 0xed, + 0xe5, 0x26, 0xfa, 0xa9, 0x70, 0xc3, 0xdc, 0x07, 0x82, 0x6b, 0x47, 0x14, 0x18, 0x08, 0x81, 0x76, 0xd9, 0x1e, 0xd3, + 0x3c, 0x1f, 0xd1, 0xec, 0x4b, 0x1d, 0xfb, 0x2b, 0x34, 0x20, 0xdb, 0xd4, 0x38, 0xc8, 0x0a, 0x48, 0x56, 0x38, 0x6f, + 0x4f, 0xa5, 0x6b, 0x1b, 0x25, 0x3e, 0x6c, 0x55, 0x68, 0x5f, 0x5f, 0xe8, 0x6f, 0x62, 0xbb, 0x19, 0x91, 0x70, 0x33, + 0x8b, 0x81, 0x0a, 0xfc, 0x4b, 0x8c, 0xf3, 0xf4, 0xc0, 0xe1, 0x1d, 0x08, 0x1e, 0x9b, 0xad, 0x81, 0x68, 0xb4, 0xda, + 0x8c, 0xb9, 0xfa, 0x36, 0x04, 0xfe, 0xb7, 0x8c, 0xf2, 0x49, 0xd0, 0xc3, 0xbf, 0x3b, 0xd0, 0x92, 0xc6, 0x39, 0xc6, + 0xb9, 0x1c, 0x99, 0x63, 0x28, 0x3c, 0xa1, 0xf9, 0x19, 0x98, 0x17, 0x83, 0xef, 0xaf, 0x6d, 0x96, 0xe1, 0xcb, 0x60, + 0x18, 0xaa, 0x17, 0x32, 0x14, 0x35, 0x14, 0x70, 0x44, 0x55, 0x98, 0x33, 0x57, 0xd6, 0x44, 0x49, 0xc7, 0xb5, 0x5b, + 0x71, 0xdc, 0xd1, 0xdc, 0x82, 0xc4, 0x71, 0xac, 0x40, 0x9a, 0xf3, 0xfc, 0x7d, 0x35, 0x0b, 0xb5, 0x33, 0x0b, 0x95, + 0x04, 0xd2, 0x16, 0xaa, 0x90, 0x39, 0xa8, 0x9e, 0x6a, 0x81, 0xc2, 0x52, 0xc0, 0xb2, 0x26, 0x40, 0xa1, 0x51, 0x49, + 0x70, 0x73, 0xa2, 0x71, 0xe1, 0x44, 0x1d, 0x87, 0x6b, 0x40, 0x32, 0xaa, 0x2a, 0x12, 0xd9, 0xcd, 0x51, 0x93, 0x7d, + 0x25, 0x2e, 0xd0, 0x16, 0x7f, 0xbf, 0xd9, 0x38, 0x28, 0x31, 0xe4, 0x56, 0xa7, 0xc6, 0x18, 0x07, 0x60, 0xc1, 0x92, + 0x38, 0x66, 0xd8, 0xb2, 0x3e, 0xdb, 0xc0, 0x29, 0xdb, 0x3d, 0x24, 0x44, 0x56, 0xb0, 0xa9, 0x31, 0x95, 0x9e, 0xbb, + 0x92, 0x08, 0x53, 0xcf, 0x96, 0x16, 0xd5, 0xc4, 0x09, 0x89, 0xbc, 0x76, 0x22, 0xea, 0xaf, 0x6a, 0xc2, 0x61, 0x1a, + 0x14, 0xdb, 0xa4, 0x40, 0x54, 0x8b, 0x7d, 0xf0, 0xde, 0x87, 0x35, 0xb5, 0x76, 0x02, 0x88, 0x17, 0x35, 0x88, 0x07, + 0xa0, 0x95, 0x96, 0x78, 0xc9, 0x21, 0xa1, 0xf5, 0xca, 0x31, 0xc3, 0x85, 0x5d, 0x88, 0x1d, 0x28, 0x6e, 0xb3, 0x9f, + 0x06, 0x0b, 0x41, 0x96, 0x55, 0xc0, 0xdf, 0x85, 0x47, 0x44, 0x0c, 0x83, 0x17, 0xeb, 0xf5, 0x0e, 0xda, 0xed, 0xe5, + 0x42, 0x51, 0x52, 0x49, 0x87, 0xeb, 0xf5, 0xdf, 0x12, 0xc5, 0x8e, 0xff, 0xc5, 0x0c, 0xf5, 0x3d, 0xd1, 0x7d, 0xf8, + 0x12, 0x4a, 0x19, 0x76, 0xb4, 0x4a, 0x29, 0x05, 0x87, 0x3a, 0xd6, 0xd6, 0x17, 0x4a, 0x07, 0x94, 0xfb, 0xf1, 0x0e, + 0x01, 0x33, 0x89, 0xee, 0xa4, 0xae, 0xa6, 0xfc, 0xd8, 0x35, 0x2d, 0x10, 0x42, 0xa9, 0x32, 0xb2, 0xcc, 0xe1, 0x3e, + 0xf9, 0xf2, 0xe8, 0x48, 0x05, 0x0d, 0x7d, 0x2a, 0x29, 0xc5, 0xe7, 0x18, 0x4e, 0x65, 0x75, 0x27, 0x0c, 0xfb, 0xf2, + 0xd9, 0x9f, 0x43, 0x3b, 0xd2, 0x69, 0xab, 0x07, 0x82, 0x39, 0xbd, 0xa1, 0x5c, 0x1f, 0x94, 0xad, 0x58, 0xc1, 0x3c, + 0x66, 0x68, 0xe5, 0xb8, 0x8d, 0xa4, 0x60, 0xc0, 0x3f, 0x02, 0x59, 0xf0, 0x5c, 0xb4, 0x45, 0xfc, 0x6c, 0xc6, 0x40, + 0x95, 0xed, 0x19, 0x89, 0x52, 0x3c, 0x3c, 0x74, 0x07, 0x89, 0x6b, 0x78, 0xff, 0xd8, 0x37, 0xdb, 0xd5, 0x6b, 0xd2, + 0xc0, 0x82, 0x15, 0x13, 0x59, 0xcc, 0x7d, 0xde, 0x66, 0xeb, 0xdb, 0x11, 0x47, 0x3e, 0x89, 0xf7, 0xb6, 0xed, 0x44, + 0x80, 0xde, 0x96, 0xec, 0x5d, 0x49, 0xed, 0xb5, 0xd3, 0xb4, 0x3c, 0x80, 0xad, 0x82, 0xd0, 0x63, 0xa6, 0x0a, 0xa5, + 0x7c, 0xa7, 0x5e, 0xed, 0x59, 0xdd, 0xc9, 0x61, 0xbb, 0x57, 0x4a, 0x7e, 0x1e, 0x1b, 0x7a, 0x56, 0xc7, 0xe1, 0x4e, + 0x55, 0xb9, 0xcc, 0xc7, 0x6e, 0xb0, 0x02, 0x61, 0xe6, 0xf0, 0xe8, 0x86, 0xe7, 0x79, 0x95, 0xfa, 0x9f, 0x90, 0x76, + 0xe5, 0x48, 0xbb, 0xf4, 0xa4, 0x1d, 0x48, 0x05, 0x90, 0x76, 0xdb, 0x5c, 0x55, 0x5d, 0xee, 0x6c, 0x4f, 0x69, 0x89, + 0xba, 0x32, 0xe2, 0x34, 0xf4, 0xb7, 0xf4, 0x23, 0x40, 0x25, 0xf3, 0xf5, 0x25, 0x76, 0xfa, 0x18, 0x10, 0x03, 0xad, + 0x4e, 0x93, 0x85, 0x9a, 0x8a, 0x2f, 0x31, 0xc2, 0x6a, 0xc3, 0x4a, 0xcc, 0x7e, 0xf8, 0x14, 0x94, 0x76, 0xc1, 0x74, + 0xe0, 0x1c, 0x33, 0xc9, 0xff, 0x11, 0x1f, 0xe5, 0x67, 0x27, 0xdc, 0xec, 0x94, 0x9f, 0x1d, 0xd0, 0xfa, 0x6a, 0x76, + 0xe3, 0xef, 0x53, 0x7b, 0x33, 0x3d, 0x51, 0x4e, 0xaf, 0x5a, 0xef, 0xf5, 0x3a, 0xde, 0x4a, 0x01, 0x8d, 0xbe, 0x93, + 0x52, 0x8a, 0xb2, 0x75, 0xa0, 0x01, 0x21, 0x64, 0x20, 0x61, 0x63, 0x27, 0x5d, 0x9e, 0x72, 0x2f, 0xff, 0x95, 0x9e, + 0xc7, 0x28, 0xee, 0x6d, 0xfd, 0xc7, 0x72, 0xbe, 0x00, 0x86, 0x6c, 0x0b, 0xa5, 0xa7, 0xcc, 0x75, 0x58, 0xe5, 0x6f, + 0xf6, 0xa4, 0xd5, 0xea, 0x98, 0xfd, 0x58, 0xc3, 0xa6, 0x52, 0x6a, 0x3e, 0x6c, 0x6d, 0x96, 0x65, 0x52, 0x49, 0x38, + 0xf6, 0xe9, 0x56, 0x1e, 0x6f, 0x6b, 0x66, 0x7c, 0xc6, 0xeb, 0x58, 0x58, 0x3a, 0x2c, 0x80, 0xd6, 0x05, 0xe4, 0xc7, + 0xa3, 0x7b, 0xb8, 0xfe, 0x9b, 0x0a, 0x38, 0xab, 0xcd, 0x16, 0xf8, 0x56, 0x9b, 0xcd, 0x07, 0xed, 0x24, 0x6d, 0xfc, + 0x61, 0x8f, 0xdc, 0x5b, 0x42, 0xaf, 0xca, 0x74, 0x32, 0xe3, 0x60, 0x08, 0x69, 0x3b, 0x2c, 0x24, 0x59, 0xcd, 0xe5, + 0x98, 0xa5, 0x91, 0x5c, 0x30, 0x11, 0x6d, 0x40, 0xcf, 0xea, 0x10, 0xe0, 0x9f, 0x22, 0x5e, 0xbd, 0xad, 0xeb, 0x5b, + 0xd3, 0x0f, 0x7a, 0x03, 0xaa, 0xb0, 0x97, 0x7c, 0x8f, 0x32, 0xf6, 0x03, 0x2b, 0x94, 0xe1, 0x49, 0x4b, 0xf6, 0xf6, + 0x25, 0xaf, 0x0e, 0xa8, 0x97, 0x3c, 0xfd, 0x76, 0x95, 0x4a, 0x20, 0x89, 0xda, 0xc9, 0x79, 0x72, 0x1a, 0x21, 0xa3, + 0x31, 0x7e, 0xe6, 0x35, 0xc6, 0xcb, 0x52, 0x63, 0xfc, 0x5c, 0x93, 0xe5, 0x96, 0xc6, 0xf8, 0x67, 0x41, 0x9e, 0xeb, + 0xfe, 0x73, 0xaf, 0x4d, 0x7f, 0x23, 0x73, 0x9e, 0xdd, 0xc5, 0x51, 0xce, 0x75, 0x13, 0x6e, 0x13, 0x23, 0xbc, 0xb2, + 0x19, 0xa0, 0x6a, 0x34, 0xfa, 0xee, 0x8d, 0x97, 0xff, 0xb0, 0x10, 0x24, 0xba, 0x97, 0x73, 0x7d, 0x2f, 0xc2, 0x33, + 0x4d, 0xfe, 0x84, 0x5f, 0xf7, 0x56, 0xf1, 0x2f, 0x54, 0xcf, 0x92, 0x82, 0x8a, 0xb1, 0x9c, 0xc7, 0xa8, 0x11, 0x45, + 0x28, 0x51, 0x46, 0x08, 0x79, 0x80, 0x36, 0xf7, 0xfe, 0xc4, 0x9f, 0x25, 0x89, 0xfa, 0x51, 0x63, 0xa6, 0x31, 0xa3, + 0xe4, 0xcf, 0xcb, 0x7b, 0xab, 0xcf, 0x72, 0x73, 0xf5, 0x27, 0x7e, 0xaa, 0x4b, 0xb5, 0x3e, 0xbe, 0x65, 0x24, 0x46, + 0xe4, 0xea, 0xa9, 0x1f, 0xd2, 0x63, 0x39, 0xb7, 0x0a, 0xfe, 0x08, 0xe1, 0xaf, 0xa0, 0xd7, 0xbd, 0xe2, 0x15, 0x11, + 0x72, 0x77, 0x30, 0x87, 0x24, 0x92, 0x46, 0x79, 0x10, 0x1d, 0x1d, 0x05, 0x69, 0x25, 0x0b, 0x81, 0x1f, 0x49, 0x52, + 0x13, 0xd5, 0x31, 0xa7, 0xd0, 0xd2, 0x23, 0x19, 0x73, 0xe4, 0x9b, 0x89, 0xbd, 0xa6, 0xda, 0xed, 0x58, 0x3e, 0xb0, + 0xba, 0x87, 0x84, 0x6b, 0x56, 0x50, 0x2d, 0x8b, 0x21, 0x0a, 0xd9, 0x12, 0xfc, 0x8a, 0x93, 0x3f, 0x07, 0x07, 0xff, + 0xcf, 0xff, 0xf8, 0x63, 0xf2, 0x47, 0x31, 0xfc, 0x13, 0x0b, 0x46, 0x4e, 0x2e, 0xe3, 0x7e, 0x1a, 0x1f, 0x36, 0x9b, + 0xeb, 0x3f, 0x4e, 0x06, 0xff, 0x4d, 0x9b, 0x7f, 0x3f, 0x6c, 0xfe, 0x3e, 0x44, 0xeb, 0xf8, 0x8f, 0x93, 0xfe, 0xc0, + 0x7d, 0x0d, 0xfe, 0xfb, 0xea, 0x0f, 0x35, 0x3c, 0xb6, 0x89, 0xf7, 0x10, 0x3a, 0x99, 0xe2, 0x7f, 0x08, 0x72, 0xd2, + 0x6c, 0x5e, 0x9d, 0x4c, 0xf1, 0xaf, 0x82, 0x9c, 0xc0, 0xdf, 0x3b, 0x4d, 0xde, 0xb2, 0xe9, 0xd3, 0xdb, 0x45, 0xfc, + 0xe7, 0xd5, 0xfa, 0xde, 0xea, 0x15, 0xdf, 0x40, 0xbb, 0x83, 0xff, 0xfe, 0xe3, 0x0f, 0x15, 0xfd, 0x78, 0x45, 0x4e, + 0x86, 0x0d, 0x14, 0x9b, 0xe4, 0x63, 0x62, 0xff, 0xc4, 0xfd, 0x74, 0xf0, 0xdf, 0x6e, 0x28, 0xd1, 0x8f, 0x7f, 0xfc, + 0x79, 0x79, 0x45, 0x86, 0xeb, 0x38, 0x5a, 0xff, 0x88, 0xd6, 0x08, 0xad, 0xef, 0xa1, 0x3f, 0x71, 0x34, 0x8d, 0x10, + 0xfe, 0x5d, 0x90, 0x93, 0x1f, 0x4f, 0xa6, 0xf8, 0x27, 0x41, 0x4e, 0xa2, 0x93, 0x29, 0xfe, 0x20, 0xc9, 0xc9, 0x7f, + 0xc7, 0xfd, 0xd4, 0x2a, 0xe1, 0xd6, 0x46, 0xfd, 0xb1, 0x86, 0x9b, 0x10, 0x5a, 0x30, 0xba, 0xd6, 0x5c, 0xe7, 0x0c, + 0xdd, 0x3b, 0xe1, 0xf8, 0xb9, 0x04, 0x60, 0xc5, 0x1a, 0x94, 0x34, 0xe6, 0x12, 0x76, 0xf5, 0x09, 0x16, 0x1e, 0x30, + 0xe8, 0x5e, 0xca, 0xb1, 0xd5, 0x13, 0xa8, 0x54, 0xdb, 0xdb, 0x5b, 0x05, 0xd7, 0xb7, 0xf8, 0x31, 0x79, 0x2e, 0xe3, + 0x36, 0xc2, 0x82, 0xc2, 0x8f, 0x0e, 0xc2, 0xef, 0xb5, 0xbb, 0xf0, 0x84, 0x6d, 0x6e, 0x31, 0x4c, 0x48, 0xcb, 0xcf, + 0x44, 0x08, 0xbf, 0xdc, 0x93, 0xa9, 0x67, 0xa0, 0x7e, 0x40, 0x58, 0xab, 0xf0, 0x7a, 0x14, 0x3f, 0xd6, 0xa4, 0x44, + 0x8e, 0x77, 0x05, 0x63, 0xbf, 0xd1, 0xfc, 0x0b, 0x2b, 0xe2, 0xa7, 0x1a, 0xb7, 0x3b, 0x0f, 0xb0, 0x51, 0x55, 0x1f, + 0xb6, 0x51, 0xaf, 0xbc, 0xdd, 0x7a, 0x2f, 0xed, 0x7d, 0x02, 0x9c, 0xc2, 0x75, 0x7d, 0x0d, 0xac, 0xfd, 0x21, 0xdf, + 0x51, 0x6a, 0x15, 0xf4, 0x26, 0x42, 0xf5, 0xab, 0x54, 0x2e, 0xbe, 0xd2, 0x9c, 0x8f, 0x0f, 0x34, 0x9b, 0x2f, 0x72, + 0xaa, 0xd9, 0x81, 0x9b, 0xf3, 0x01, 0x85, 0x86, 0xa2, 0x92, 0xa7, 0xf8, 0x59, 0x54, 0x9b, 0xf6, 0x67, 0x91, 0x54, + 0x7b, 0x27, 0x86, 0xfb, 0x2c, 0xc7, 0x97, 0x28, 0x5a, 0x5e, 0x97, 0x6d, 0xdf, 0x08, 0x36, 0xdb, 0xa0, 0x2c, 0x1b, + 0x9a, 0xf3, 0x5b, 0x61, 0xb8, 0xdf, 0x24, 0xa4, 0xd3, 0x8f, 0x2e, 0xd5, 0xd7, 0xe9, 0x55, 0x04, 0x37, 0x39, 0x05, + 0x11, 0xcc, 0x28, 0x8f, 0xa0, 0x04, 0x25, 0xad, 0x1e, 0xbd, 0x64, 0x3d, 0xda, 0x68, 0x78, 0x36, 0x3b, 0x23, 0x7c, + 0x40, 0x6d, 0xfd, 0x1c, 0xcf, 0xf0, 0x98, 0x34, 0xdb, 0x78, 0x49, 0x5a, 0xa6, 0x4a, 0x6f, 0x79, 0x99, 0xb9, 0x7e, + 0x8e, 0x8e, 0xe2, 0x22, 0xc9, 0xa9, 0xd2, 0x2f, 0x40, 0x23, 0x40, 0x96, 0x78, 0x46, 0x8a, 0x84, 0xdd, 0xb2, 0x2c, + 0xce, 0x10, 0x9e, 0x39, 0x1a, 0x84, 0x7a, 0x68, 0x49, 0x82, 0x62, 0x20, 0x67, 0x10, 0xc1, 0xfa, 0xb3, 0x41, 0x7b, + 0x48, 0x08, 0x89, 0x0e, 0x9b, 0xcd, 0xa8, 0x5f, 0x90, 0x7f, 0x88, 0x14, 0x52, 0x02, 0x76, 0x9a, 0xfc, 0x0a, 0x49, + 0x9d, 0x20, 0x29, 0xfe, 0x20, 0x13, 0xcd, 0x94, 0x8e, 0x21, 0x19, 0x94, 0x04, 0xca, 0x63, 0x78, 0x74, 0x79, 0x12, + 0x35, 0x20, 0xd5, 0xa0, 0x28, 0xc2, 0x05, 0xb9, 0xd3, 0x28, 0x9d, 0x0d, 0x4e, 0x87, 0xe1, 0x19, 0x61, 0x53, 0xa1, + 0xff, 0x3b, 0xdd, 0x9f, 0x0d, 0x5a, 0xa6, 0xff, 0xab, 0xa8, 0x1f, 0x17, 0x44, 0x59, 0x36, 0xae, 0xaf, 0x52, 0xc1, + 0xcc, 0x7c, 0x51, 0xea, 0x06, 0xe8, 0xfa, 0x1e, 0x93, 0x66, 0x27, 0x8d, 0xc7, 0xe1, 0x4c, 0x9a, 0xd0, 0xa1, 0x03, + 0x05, 0xce, 0x09, 0x94, 0xc7, 0x05, 0x81, 0x4e, 0xab, 0x6a, 0x77, 0x3a, 0x75, 0x09, 0x3f, 0x46, 0x3f, 0xf6, 0x7f, + 0x12, 0xe9, 0xef, 0xc2, 0x8e, 0xe0, 0x27, 0xb1, 0x5e, 0xc3, 0xdf, 0xdf, 0x45, 0x1f, 0x86, 0x65, 0xd2, 0xfe, 0xe1, + 0xd2, 0x7e, 0x85, 0x34, 0xc1, 0x52, 0x33, 0x60, 0xac, 0x4a, 0x7e, 0xcc, 0x2e, 0xce, 0x84, 0xd8, 0x19, 0x1c, 0x1d, + 0xf1, 0x01, 0x6d, 0xb4, 0x87, 0x70, 0x23, 0x50, 0x68, 0xf5, 0x1b, 0xd7, 0xb3, 0x38, 0x3a, 0xb9, 0x8a, 0x50, 0x3f, + 0x3a, 0x80, 0x55, 0xee, 0xc9, 0x06, 0x71, 0xb0, 0xce, 0x1a, 0x8c, 0xa6, 0xe3, 0x2b, 0xd2, 0xea, 0xc7, 0xc2, 0x12, + 0xf9, 0x1c, 0xe1, 0xcc, 0xd1, 0xd4, 0x16, 0x1e, 0xa3, 0x86, 0x10, 0x0d, 0xff, 0x3d, 0x46, 0x8d, 0x99, 0x6e, 0x4c, + 0x50, 0x9a, 0xc1, 0xdf, 0x78, 0x4c, 0x08, 0x69, 0x76, 0xca, 0x8a, 0xfe, 0xb0, 0xa4, 0x28, 0x9d, 0x78, 0xf5, 0xe8, + 0xc0, 0x6c, 0x0e, 0xd9, 0x88, 0xf9, 0x80, 0x0d, 0xd7, 0xeb, 0xe8, 0xb2, 0x7f, 0x15, 0xa1, 0x46, 0xec, 0xd1, 0xee, + 0xc4, 0xe3, 0x1d, 0x42, 0x58, 0x0c, 0x37, 0xee, 0x06, 0xea, 0x86, 0xd5, 0x6e, 0x9b, 0x56, 0xd5, 0xfe, 0x0f, 0xc8, + 0x02, 0xdb, 0x94, 0x72, 0x8f, 0xe5, 0x6f, 0x17, 0x30, 0x55, 0x8f, 0xdb, 0x92, 0xb4, 0x70, 0x41, 0xbc, 0xba, 0x9b, + 0x12, 0x5d, 0xe1, 0x7f, 0x46, 0xaa, 0xe2, 0x78, 0x90, 0xe3, 0xd9, 0x90, 0x28, 0x6a, 0xe4, 0x97, 0x9e, 0x57, 0xa6, + 0xb3, 0x9c, 0xdc, 0xb0, 0xad, 0xfb, 0xdf, 0x1c, 0xee, 0x64, 0x1e, 0xeb, 0x24, 0x5b, 0x16, 0x05, 0x13, 0xfa, 0x95, + 0x1c, 0x3b, 0xc6, 0x8e, 0xe5, 0x20, 0x5b, 0xc1, 0xc5, 0x2e, 0x06, 0xae, 0xae, 0xe3, 0x77, 0xca, 0x78, 0x27, 0x7b, + 0x49, 0xc6, 0x96, 0xe1, 0x32, 0xd7, 0xbd, 0xbd, 0xa5, 0x13, 0xa5, 0x63, 0x84, 0xc7, 0xee, 0x1e, 0x38, 0x4e, 0x92, + 0x64, 0x99, 0x64, 0x90, 0x0d, 0x1d, 0x28, 0xb4, 0x31, 0xfb, 0x2a, 0x56, 0xe4, 0xb1, 0x4e, 0x04, 0xbb, 0x35, 0xdd, + 0xc6, 0xa8, 0x3a, 0xc4, 0xfd, 0x7e, 0xbb, 0xa4, 0x3d, 0x43, 0x80, 0x54, 0x22, 0xe4, 0x98, 0x01, 0x84, 0xe0, 0xee, + 0xdf, 0x25, 0xcd, 0xa8, 0x0a, 0x6f, 0xb6, 0xaa, 0x01, 0x0e, 0x42, 0x95, 0xf7, 0x12, 0xf4, 0xc4, 0x86, 0x3d, 0x2b, + 0x0b, 0x5b, 0xe5, 0x39, 0x42, 0x7c, 0x12, 0x2f, 0x13, 0xb8, 0x11, 0x34, 0x98, 0x24, 0x04, 0x5a, 0xaf, 0x97, 0x21, + 0x6e, 0xcd, 0x2a, 0xc5, 0xf4, 0x84, 0xcc, 0x06, 0x45, 0xa3, 0x61, 0x94, 0xd7, 0x63, 0x8b, 0x17, 0x4b, 0x84, 0x27, + 0xe5, 0x5e, 0xf3, 0xe5, 0x16, 0xa4, 0xde, 0x55, 0x3c, 0xa9, 0x2b, 0x81, 0x1b, 0x42, 0x20, 0xa3, 0x5f, 0xd4, 0xd0, + 0x3a, 0x9e, 0x92, 0x93, 0x78, 0x90, 0xf4, 0xff, 0xe7, 0x10, 0xf5, 0xe3, 0xe4, 0x18, 0x9d, 0x58, 0x5a, 0x32, 0x41, + 0xbd, 0xcc, 0xf6, 0xb1, 0x32, 0xb7, 0x9f, 0x6d, 0x6c, 0x14, 0x90, 0xa9, 0xc4, 0x82, 0xce, 0x59, 0x3a, 0x85, 0x5d, + 0xef, 0x91, 0x67, 0x81, 0x01, 0x99, 0xd2, 0xa9, 0xa3, 0x2d, 0x49, 0xd4, 0x2f, 0x68, 0xf9, 0xd5, 0x8f, 0xfa, 0x59, + 0xf5, 0xf5, 0x3f, 0xa3, 0x7e, 0x4e, 0xd3, 0xc7, 0x7c, 0xe3, 0x94, 0xe4, 0xb5, 0x3e, 0xce, 0x7d, 0x1f, 0x1b, 0xbb, + 0x38, 0x01, 0xf0, 0xc6, 0x68, 0x57, 0x3b, 0xb2, 0x44, 0x1b, 0x3e, 0x29, 0xa9, 0x93, 0x4a, 0x34, 0x9d, 0x02, 0x54, + 0x83, 0x45, 0x50, 0xa1, 0x6d, 0x40, 0x30, 0x65, 0xc0, 0x16, 0x8f, 0xb4, 0x00, 0xcd, 0xe5, 0x55, 0x0b, 0xad, 0x6a, + 0x85, 0x1d, 0x67, 0x55, 0xbf, 0x8b, 0x2f, 0x89, 0xf7, 0x04, 0xa8, 0xf2, 0xe5, 0xb2, 0x37, 0x69, 0x34, 0x90, 0xf2, + 0xf8, 0x35, 0x1e, 0x4c, 0x86, 0xf8, 0x16, 0x50, 0x08, 0xd7, 0x30, 0x0a, 0xd7, 0xe6, 0xd8, 0x71, 0x73, 0x6c, 0x34, + 0xe4, 0x06, 0xf5, 0x82, 0xca, 0x4b, 0x57, 0x79, 0xb3, 0xb1, 0x90, 0xd9, 0xc6, 0xb8, 0x0b, 0x64, 0x52, 0xc0, 0x10, + 0x8c, 0x10, 0xf2, 0x59, 0xa2, 0xbd, 0xcd, 0x42, 0xa3, 0x50, 0xdd, 0xec, 0x5e, 0xa0, 0xa8, 0xf6, 0xf4, 0x88, 0x01, + 0x16, 0x50, 0xb5, 0x54, 0x23, 0xcf, 0x34, 0x1e, 0x37, 0xda, 0x06, 0xdd, 0x9b, 0xed, 0x5e, 0xbd, 0xb1, 0xfb, 0x55, + 0x63, 0x78, 0xdc, 0x20, 0xb3, 0x6a, 0x87, 0x6f, 0x64, 0xa3, 0xb1, 0xa9, 0xdf, 0x97, 0xfa, 0x4d, 0x5c, 0xbb, 0xbf, + 0x78, 0xba, 0x63, 0xe2, 0xe1, 0x4f, 0xdf, 0xea, 0xbc, 0x15, 0x09, 0x17, 0x82, 0x15, 0x70, 0xc2, 0x12, 0x8d, 0xc5, + 0x66, 0x53, 0x9e, 0xfa, 0xbf, 0x69, 0x6b, 0x33, 0x46, 0x38, 0xd0, 0x21, 0x23, 0xb5, 0x61, 0x89, 0x0b, 0x4c, 0x0d, + 0x15, 0x21, 0x84, 0xbc, 0xd7, 0xde, 0x3c, 0x46, 0x1b, 0x92, 0x94, 0x91, 0xe0, 0xec, 0x8e, 0x15, 0x61, 0xc9, 0xa7, + 0x7b, 0x8f, 0xe5, 0x77, 0x45, 0xba, 0x81, 0x18, 0xa6, 0xa6, 0x58, 0xee, 0x08, 0x59, 0x4e, 0xbe, 0x82, 0x9c, 0x53, + 0x5e, 0xb0, 0x24, 0x86, 0x20, 0x3e, 0xe1, 0x05, 0x33, 0x8c, 0xfb, 0x3d, 0x2f, 0x37, 0x66, 0x75, 0x4e, 0x33, 0x0b, + 0xb5, 0x3f, 0x00, 0xcd, 0x1c, 0x94, 0x43, 0x92, 0xec, 0x14, 0xfb, 0x74, 0xef, 0xe1, 0xeb, 0x7d, 0x32, 0xf4, 0x7a, + 0xed, 0xa4, 0xe7, 0x0c, 0x58, 0x1f, 0x9c, 0x57, 0x43, 0xcd, 0xdc, 0x8f, 0x34, 0xce, 0x0c, 0x13, 0x95, 0xc7, 0x1c, + 0x90, 0xe9, 0xd3, 0xbd, 0x87, 0xef, 0x62, 0x6e, 0x74, 0x53, 0x08, 0x87, 0xf3, 0x8e, 0x0b, 0x12, 0x53, 0xc2, 0x90, + 0x9d, 0x7c, 0x49, 0xc7, 0x8a, 0xe0, 0x74, 0x4f, 0xa9, 0xc9, 0x04, 0xb1, 0x63, 0x20, 0x86, 0x24, 0x73, 0x20, 0x20, + 0x19, 0xc2, 0x59, 0x4d, 0xae, 0x23, 0x66, 0x0d, 0x4c, 0x67, 0xd7, 0xb0, 0x18, 0x89, 0x65, 0x0f, 0x11, 0xce, 0x4c, + 0xb7, 0x7a, 0x63, 0x8f, 0x13, 0x49, 0xb7, 0x0d, 0xdd, 0x2a, 0x79, 0xf6, 0x03, 0x08, 0x5e, 0xfe, 0xe3, 0x95, 0x6b, + 0xbb, 0x4c, 0x78, 0xe2, 0x2d, 0xd2, 0x3e, 0xdd, 0x7b, 0xf8, 0x8b, 0x33, 0x4a, 0x5b, 0x50, 0x4f, 0xfe, 0x77, 0x64, + 0xd4, 0x87, 0xbf, 0x24, 0x55, 0xae, 0x29, 0xfc, 0xe9, 0xde, 0xc3, 0xf7, 0xfb, 0x8a, 0x41, 0xfa, 0x66, 0x59, 0x29, + 0x09, 0xcc, 0xf8, 0x56, 0x2c, 0x4f, 0x57, 0xee, 0xac, 0x48, 0xc5, 0x06, 0x9b, 0x13, 0x2a, 0x55, 0x9b, 0x52, 0xb7, + 0xf2, 0x04, 0x4b, 0x62, 0xae, 0x92, 0xea, 0xcb, 0xe6, 0xd0, 0x98, 0x4b, 0x71, 0x9d, 0xc9, 0x05, 0xfb, 0xc6, 0xfd, + 0xd2, 0x53, 0x8d, 0x12, 0x3e, 0x07, 0x43, 0x1c, 0x33, 0x76, 0x81, 0x0f, 0x5b, 0xa8, 0xb7, 0x75, 0x9e, 0x49, 0x83, + 0xa8, 0x45, 0xfd, 0xb0, 0xc1, 0x94, 0xb4, 0x70, 0x46, 0x5a, 0x38, 0x27, 0x6a, 0xd0, 0xb2, 0x27, 0x46, 0x2f, 0x2f, + 0x9b, 0xb6, 0xe7, 0x0e, 0x6c, 0xf7, 0xdc, 0xee, 0x5b, 0x7b, 0x28, 0xcf, 0x7a, 0xb9, 0xd1, 0x5f, 0x9a, 0x83, 0x7e, + 0x66, 0x50, 0xe3, 0x05, 0x8b, 0x0b, 0x5c, 0x98, 0x96, 0xaf, 0xf9, 0x28, 0x07, 0x3b, 0x15, 0x98, 0x19, 0xd6, 0x28, + 0x2d, 0xcb, 0xb6, 0x5d, 0xd9, 0x3c, 0x31, 0x6b, 0x55, 0xe0, 0x3c, 0x01, 0x52, 0x8e, 0x73, 0x67, 0xd7, 0xa3, 0x76, + 0xab, 0x9c, 0x1f, 0x1d, 0xc5, 0xb6, 0xd2, 0x8c, 0xc6, 0x85, 0xcf, 0xaf, 0x6e, 0x00, 0x3f, 0x58, 0xaa, 0x31, 0x43, + 0x66, 0x02, 0x8d, 0x46, 0x36, 0xdc, 0xd0, 0x43, 0x42, 0xe2, 0xbc, 0x0e, 0x45, 0x3f, 0x7a, 0xc3, 0x0c, 0x6e, 0x01, + 0xa0, 0xd1, 0x28, 0xaf, 0x7b, 0xb7, 0x20, 0xf6, 0x54, 0x63, 0xb9, 0xf9, 0x1a, 0x97, 0xd6, 0x44, 0xad, 0x1d, 0x3b, + 0x2c, 0x3f, 0x0a, 0x24, 0x42, 0xdc, 0x15, 0x7e, 0x3e, 0xc1, 0xd6, 0x10, 0x50, 0xee, 0x85, 0xb3, 0x81, 0xc0, 0xc6, + 0x6a, 0xcb, 0x15, 0xf2, 0xa4, 0xad, 0x83, 0x52, 0x5f, 0x08, 0x2e, 0xb8, 0xa0, 0x50, 0x63, 0xe3, 0xb0, 0xfc, 0x05, + 0xdb, 0x35, 0xe7, 0xc4, 0x0a, 0x39, 0x6d, 0x99, 0x19, 0x86, 0x01, 0x58, 0xa7, 0x04, 0xcc, 0x73, 0xf2, 0xf2, 0xdb, + 0xa8, 0xff, 0x30, 0x40, 0xfd, 0x47, 0x84, 0x05, 0xdb, 0xc0, 0xea, 0x4a, 0x12, 0xe9, 0x14, 0x14, 0xca, 0x67, 0x3d, + 0x5e, 0x10, 0xd0, 0xc6, 0xd5, 0xa1, 0x5a, 0xbb, 0xa2, 0xfc, 0x06, 0x65, 0x09, 0x77, 0x8a, 0xd1, 0x67, 0x62, 0x7f, + 0x9f, 0x1c, 0x57, 0x17, 0x74, 0xd0, 0xf5, 0x3e, 0xe5, 0x60, 0x48, 0x0a, 0x1f, 0xbe, 0xff, 0xfe, 0xdd, 0xea, 0xe3, + 0xc5, 0xee, 0x0e, 0x0e, 0xcc, 0x4a, 0x61, 0xd6, 0xc1, 0x06, 0xae, 0x1b, 0x99, 0x42, 0xff, 0xe5, 0x9d, 0x78, 0x9d, + 0x0a, 0x6d, 0x6d, 0x46, 0x7f, 0x1c, 0xc2, 0x68, 0xdb, 0x6d, 0x53, 0x82, 0x05, 0xcd, 0x02, 0x5d, 0xb2, 0xc6, 0xad, + 0xb4, 0xf8, 0x06, 0x19, 0x79, 0x68, 0x0a, 0x30, 0x31, 0xde, 0x9f, 0xfd, 0x68, 0xe3, 0xf0, 0xc4, 0x0e, 0x0d, 0xad, + 0x0c, 0x21, 0xb4, 0x78, 0x0f, 0x98, 0x63, 0x8f, 0x08, 0x00, 0xd1, 0x4b, 0x03, 0xa9, 0x0a, 0x64, 0x51, 0x54, 0x29, + 0xf2, 0x9f, 0x1f, 0x12, 0xf2, 0xb2, 0x52, 0x64, 0xbe, 0xad, 0x8c, 0xb9, 0x00, 0x31, 0x50, 0x0a, 0x17, 0x09, 0x65, + 0x82, 0xbd, 0x0c, 0x7d, 0xaf, 0x7d, 0x79, 0x23, 0x6d, 0x26, 0x15, 0x37, 0x1e, 0xdc, 0x94, 0x1a, 0x15, 0x9f, 0xcd, + 0xf7, 0x90, 0xd8, 0xca, 0xbd, 0x07, 0xb9, 0x9c, 0x9a, 0x41, 0xc2, 0xf7, 0x3b, 0x53, 0xda, 0xb7, 0xbb, 0xf9, 0xb2, + 0x6d, 0x11, 0xb3, 0xb5, 0x2e, 0x09, 0x17, 0x8a, 0x15, 0xfa, 0x11, 0x9b, 0xc8, 0x02, 0xee, 0x3f, 0x4a, 0xb0, 0xa0, + 0xcd, 0xbd, 0x40, 0x07, 0x68, 0x26, 0x18, 0x5c, 0x3a, 0x6c, 0xcd, 0xd0, 0xfc, 0xfa, 0x62, 0xee, 0xc0, 0x3f, 0x6d, + 0xd7, 0x7a, 0x79, 0x74, 0xf4, 0x95, 0x55, 0x80, 0x72, 0xc3, 0x34, 0xc3, 0x08, 0x88, 0x97, 0xe5, 0x72, 0xdc, 0xcd, + 0xf0, 0xbd, 0xb8, 0x52, 0x19, 0x78, 0xc2, 0x11, 0x12, 0xa1, 0xe7, 0x44, 0x6f, 0xa6, 0xdb, 0xf4, 0xde, 0x69, 0x33, + 0x44, 0x28, 0xd6, 0x00, 0xb9, 0x07, 0xb9, 0xdc, 0x2a, 0x99, 0x54, 0x65, 0x6b, 0x5b, 0x0e, 0xe2, 0x31, 0x80, 0x2b, + 0x36, 0x42, 0x4a, 0x80, 0x86, 0xfb, 0x85, 0x96, 0xf7, 0x12, 0xd8, 0x7f, 0xac, 0x12, 0x10, 0x69, 0x51, 0x6d, 0xe3, + 0x22, 0x84, 0xad, 0xa9, 0x4f, 0x60, 0x9c, 0xf0, 0xf0, 0xf9, 0x3e, 0x0d, 0xb5, 0x47, 0x6d, 0x66, 0xce, 0x20, 0x28, + 0x21, 0x51, 0x59, 0x21, 0xf9, 0x1a, 0x0b, 0xc7, 0xcd, 0xf9, 0x7b, 0x38, 0x20, 0xc5, 0x92, 0xc6, 0xf6, 0x6e, 0x0b, + 0x8e, 0x8f, 0x22, 0x59, 0xc6, 0xb5, 0xae, 0x7b, 0x85, 0xa9, 0x86, 0x1d, 0xe8, 0x68, 0x08, 0xa7, 0xc2, 0xdc, 0x13, + 0x3e, 0xae, 0x48, 0xaa, 0x76, 0x16, 0x50, 0x9e, 0x18, 0x56, 0xa6, 0x29, 0xc1, 0xfc, 0xb5, 0x33, 0x5f, 0x2b, 0x8f, + 0x09, 0x66, 0x86, 0x71, 0x63, 0x57, 0x81, 0x6d, 0x00, 0xc7, 0x56, 0x8f, 0x64, 0xb0, 0xa8, 0x5e, 0x29, 0x6e, 0x3a, + 0x0d, 0x98, 0x80, 0xb7, 0x60, 0x3d, 0xb3, 0xbd, 0xf5, 0x9f, 0x9b, 0x83, 0x51, 0x60, 0x55, 0x23, 0xf0, 0xd2, 0x10, + 0x78, 0x04, 0x8c, 0x9b, 0x37, 0x2d, 0xef, 0x3b, 0x23, 0x1a, 0xe1, 0x4f, 0x3c, 0x87, 0x67, 0x96, 0xe5, 0xde, 0xf9, + 0xd8, 0x5a, 0x91, 0x54, 0x10, 0xb0, 0x2d, 0xc2, 0x8e, 0xc8, 0x4b, 0x84, 0x55, 0xa3, 0xd1, 0x53, 0x97, 0xac, 0xd2, + 0xaa, 0x54, 0xc3, 0x14, 0x70, 0x4b, 0x0c, 0x78, 0x5f, 0x3b, 0x51, 0xc1, 0x90, 0xc0, 0x5b, 0x7f, 0x2b, 0x50, 0xdf, + 0x3f, 0x7c, 0x1b, 0x87, 0xf4, 0x2d, 0x2c, 0x5b, 0x5e, 0xc4, 0xc2, 0x94, 0xe2, 0xea, 0x0e, 0xe7, 0xcd, 0xf7, 0xcd, + 0x46, 0x60, 0xdc, 0x87, 0x6d, 0x0c, 0x36, 0x6e, 0xa8, 0xa7, 0x2d, 0x69, 0x28, 0x37, 0x61, 0x0f, 0x55, 0xf6, 0x8e, + 0x61, 0x67, 0x3d, 0x5d, 0x49, 0xbb, 0x9a, 0xa8, 0xcd, 0x46, 0xb1, 0xca, 0x68, 0x60, 0xcb, 0xb0, 0xd3, 0x1c, 0x33, + 0xbb, 0x0a, 0xfc, 0xc7, 0x0b, 0xa2, 0x71, 0x80, 0xac, 0x6f, 0xbe, 0x75, 0x9d, 0x52, 0x0d, 0x13, 0xb6, 0xb7, 0x3b, + 0x1f, 0x1f, 0xf3, 0x7d, 0xe7, 0x23, 0x96, 0x6e, 0xeb, 0x9b, 0xb3, 0xb1, 0xfd, 0x6f, 0x9c, 0x8d, 0x4e, 0x6d, 0xef, + 0x8f, 0x47, 0xe0, 0x4e, 0x6a, 0xc7, 0x63, 0x7d, 0x4d, 0x89, 0xc4, 0xc2, 0x2d, 0xc7, 0x55, 0x67, 0xbd, 0x16, 0x83, + 0x16, 0xa8, 0x9d, 0xa2, 0x08, 0x7e, 0xb6, 0xed, 0xcf, 0x80, 0x24, 0x5b, 0x1d, 0x72, 0x2c, 0x4a, 0x51, 0x06, 0x25, + 0x60, 0x40, 0x1d, 0x1b, 0x5b, 0x2f, 0x83, 0xd8, 0x0e, 0x87, 0x1c, 0x96, 0x13, 0x51, 0x5e, 0x5d, 0xc1, 0x88, 0xcd, + 0xb1, 0xe1, 0x04, 0xcc, 0x78, 0xaf, 0x55, 0xa1, 0x17, 0x3f, 0xff, 0x35, 0x73, 0x5a, 0x3b, 0x62, 0x2c, 0x27, 0x51, + 0xb3, 0x62, 0x70, 0x23, 0x70, 0x0c, 0xe3, 0xa1, 0x91, 0x50, 0xab, 0x53, 0x1d, 0xd5, 0x8e, 0x24, 0xdc, 0x02, 0xb5, + 0xdb, 0xa1, 0x39, 0x97, 0xd6, 0xeb, 0xbd, 0x07, 0x0b, 0x2e, 0x02, 0xdc, 0x7e, 0x4e, 0x74, 0x8d, 0xa4, 0x50, 0xe2, + 0x24, 0x28, 0x9c, 0x1b, 0x54, 0xd5, 0x44, 0x0e, 0x5a, 0x43, 0xe0, 0x49, 0x7b, 0xd9, 0xa5, 0xac, 0x84, 0xe4, 0xac, + 0xd1, 0x40, 0x79, 0xd9, 0x31, 0x1d, 0x88, 0x46, 0x36, 0xc4, 0x0c, 0x67, 0x56, 0x60, 0x81, 0xd3, 0x2b, 0xce, 0xab, + 0xae, 0x07, 0xd9, 0x10, 0xe1, 0x62, 0xbd, 0x8e, 0xed, 0xd0, 0x72, 0xb4, 0x5e, 0xe7, 0xe1, 0xd0, 0x4c, 0x3e, 0x54, + 0x7c, 0xd9, 0xd7, 0xe4, 0xa5, 0x39, 0x0f, 0x5f, 0xc2, 0x20, 0x1b, 0x24, 0xce, 0x9d, 0x4a, 0x30, 0x07, 0xcd, 0x55, + 0x43, 0x0e, 0xb2, 0x46, 0x7b, 0x18, 0xd0, 0xb0, 0x41, 0x36, 0x24, 0xf9, 0x06, 0x2c, 0x67, 0x95, 0x3b, 0x30, 0x3f, + 0xc3, 0xc1, 0xf6, 0xd9, 0x9c, 0x33, 0xb6, 0xc1, 0x70, 0x4d, 0xb6, 0x55, 0x06, 0x25, 0x5e, 0xb9, 0xc5, 0xf5, 0xe5, + 0x6a, 0x06, 0x16, 0x65, 0x21, 0xec, 0xae, 0x99, 0xfb, 0x20, 0xfc, 0x97, 0xd8, 0x5e, 0xd0, 0xd2, 0x88, 0x7b, 0x0b, + 0xf1, 0xbd, 0xed, 0x76, 0x92, 0x24, 0xb4, 0x98, 0x9a, 0x2b, 0x11, 0x7f, 0xc3, 0x6b, 0xf6, 0xc0, 0xa9, 0x1b, 0x67, + 0xd0, 0xf3, 0xa0, 0xec, 0x6c, 0x48, 0xec, 0xf8, 0x3d, 0xb3, 0xe3, 0x1d, 0x57, 0x28, 0xdd, 0xaf, 0x8b, 0xb0, 0x83, + 0xc9, 0xfe, 0x97, 0x07, 0x73, 0xe6, 0x06, 0x63, 0xd1, 0x64, 0x0b, 0x6e, 0xdf, 0x80, 0x07, 0xa5, 0x5b, 0x70, 0xfb, + 0x36, 0x7c, 0x3d, 0xb4, 0xf2, 0x6f, 0x0e, 0x30, 0x20, 0x13, 0x76, 0xa4, 0x55, 0x42, 0x30, 0xcc, 0xee, 0x36, 0x47, + 0x66, 0xc9, 0x2a, 0x1c, 0xae, 0x9a, 0xc4, 0x62, 0x6b, 0x2f, 0x54, 0x4c, 0x6a, 0x20, 0x18, 0x8b, 0xf4, 0x25, 0x0a, + 0x95, 0x06, 0x75, 0xe3, 0x18, 0xc0, 0x2a, 0xa7, 0xad, 0x7f, 0x79, 0x74, 0x04, 0x42, 0x03, 0xb0, 0x76, 0x49, 0x46, + 0x17, 0x7a, 0x59, 0x00, 0x7f, 0xa5, 0xfc, 0x6f, 0x48, 0x06, 0xb7, 0x13, 0x93, 0x06, 0x3f, 0x20, 0x61, 0x41, 0x95, + 0xe2, 0x5f, 0x6d, 0x9a, 0xfb, 0x8d, 0x0b, 0xe2, 0x31, 0x5a, 0x59, 0x4e, 0x51, 0xa2, 0x9e, 0x74, 0xe8, 0x5a, 0x87, + 0xdc, 0xd3, 0xaf, 0x4c, 0xe8, 0x97, 0x5c, 0x69, 0x26, 0x00, 0x00, 0x15, 0xe2, 0xc1, 0x94, 0x14, 0x82, 0xad, 0x5b, + 0xab, 0x45, 0xc7, 0xe3, 0xef, 0x56, 0xd1, 0x75, 0xb6, 0x68, 0x46, 0xc5, 0x38, 0xb7, 0x9d, 0x84, 0x36, 0x93, 0xde, + 0x4e, 0xb4, 0x2c, 0x19, 0x5a, 0xec, 0x54, 0xec, 0x87, 0xa1, 0xf5, 0xb1, 0x20, 0xfe, 0x5c, 0xf0, 0x67, 0xe9, 0x77, + 0xf9, 0x18, 0xb8, 0x52, 0xff, 0xc6, 0x2a, 0x84, 0x33, 0xc1, 0x3a, 0x20, 0xaf, 0x49, 0x7d, 0x9c, 0x1e, 0x75, 0x66, + 0x3b, 0xca, 0x85, 0xd2, 0x28, 0x6c, 0xeb, 0xa4, 0x30, 0x98, 0x72, 0xfe, 0x6d, 0x89, 0xeb, 0x17, 0x7f, 0x8c, 0xf8, + 0xa3, 0x43, 0xfc, 0xbb, 0x54, 0x1a, 0xad, 0x4a, 0x04, 0x43, 0x7e, 0x47, 0x32, 0x05, 0x57, 0xb1, 0x39, 0xd7, 0xcf, + 0xf5, 0x3c, 0xdf, 0xf2, 0xc4, 0xe9, 0x31, 0x55, 0x42, 0x47, 0xc5, 0x37, 0x0c, 0xbf, 0x60, 0x70, 0x6f, 0xfc, 0x8c, + 0x07, 0x55, 0x76, 0xef, 0x8b, 0x9f, 0x05, 0xf7, 0xc5, 0xcf, 0x78, 0xba, 0x5b, 0x34, 0xb8, 0x27, 0xee, 0x24, 0x17, + 0x49, 0x2b, 0xf2, 0x7c, 0xd4, 0x98, 0x56, 0xfe, 0x95, 0x76, 0x6b, 0xe0, 0xca, 0x26, 0x0e, 0x8c, 0xf3, 0xea, 0x22, + 0x14, 0x73, 0xe6, 0x8c, 0x96, 0xc3, 0xff, 0xd6, 0x3a, 0xb9, 0x93, 0x47, 0x5a, 0x29, 0xe4, 0x0d, 0x2d, 0xf4, 0x3d, + 0xd8, 0x70, 0xc5, 0x8e, 0x0f, 0x20, 0x25, 0xa0, 0x6c, 0xfb, 0xf7, 0xba, 0x08, 0xc4, 0x71, 0x65, 0x9d, 0x8f, 0xc2, + 0xf6, 0x49, 0x51, 0x72, 0x75, 0x75, 0x21, 0xe4, 0xd6, 0x68, 0x09, 0x10, 0xa6, 0xde, 0x35, 0x8f, 0x39, 0x9a, 0xcc, + 0xd2, 0xd5, 0xa6, 0x54, 0x1d, 0x14, 0x96, 0xab, 0xe3, 0x08, 0x17, 0x1b, 0x73, 0x83, 0xfe, 0x37, 0xc7, 0x9f, 0xb9, + 0xa3, 0x91, 0x3f, 0x95, 0x14, 0xe8, 0xc3, 0x7e, 0x5f, 0x9b, 0x3d, 0x24, 0xd2, 0xce, 0xa1, 0xb4, 0x14, 0x00, 0xac, + 0x36, 0xf8, 0xba, 0xf1, 0x38, 0xf5, 0x44, 0xba, 0xd9, 0x7c, 0xd3, 0x10, 0x16, 0xb3, 0xd2, 0x82, 0xc7, 0x74, 0xb3, + 0xc7, 0x72, 0xd4, 0xcb, 0xe2, 0xba, 0xdc, 0x63, 0xb5, 0x7e, 0xd1, 0x37, 0x40, 0x59, 0x19, 0xa2, 0xad, 0xd7, 0x71, + 0x1d, 0xde, 0x44, 0x04, 0xd7, 0x20, 0x08, 0x8b, 0xc0, 0x80, 0xa3, 0xc6, 0x78, 0xdb, 0x3a, 0x31, 0xda, 0xb6, 0x5f, + 0xf2, 0xac, 0x7b, 0x6d, 0x1c, 0xa1, 0xa2, 0xc1, 0x56, 0x0f, 0x35, 0x0f, 0xd8, 0xce, 0xae, 0xec, 0x28, 0x80, 0xd0, + 0x98, 0x7a, 0xe3, 0xdc, 0xca, 0x8a, 0x76, 0x0f, 0x7c, 0xd1, 0x77, 0xcc, 0x73, 0x1d, 0xe8, 0x76, 0xf3, 0x03, 0xdb, + 0xa6, 0x27, 0xf2, 0x5b, 0xb6, 0x4d, 0x35, 0x4e, 0xf8, 0xb0, 0x85, 0xbe, 0x6f, 0x08, 0x6b, 0xfb, 0xda, 0x5f, 0xe4, + 0x7f, 0xa1, 0xbb, 0x36, 0xa0, 0xa7, 0x05, 0xb3, 0xa7, 0x31, 0xef, 0xf5, 0x66, 0xf3, 0x53, 0xe9, 0xbf, 0x60, 0x6c, + 0x85, 0x7e, 0xb2, 0xbb, 0xc0, 0x89, 0x95, 0xc6, 0x21, 0x38, 0xfe, 0x9b, 0x93, 0x69, 0x2e, 0x47, 0x34, 0x7f, 0x07, + 0x3d, 0x56, 0xb9, 0xcf, 0xef, 0xc6, 0x05, 0xd5, 0xcc, 0xd1, 0x9a, 0x6a, 0x14, 0x7f, 0xf3, 0x60, 0x18, 0x7f, 0x73, + 0x4b, 0xb9, 0xab, 0x16, 0xf0, 0xea, 0x65, 0xd9, 0x44, 0xfa, 0xd3, 0xc6, 0xd3, 0x0e, 0xae, 0xf6, 0xf7, 0xb2, 0x4d, + 0xd2, 0x78, 0x49, 0xd2, 0xb8, 0x8a, 0xb7, 0x9b, 0x8a, 0xe3, 0xcf, 0xdf, 0x18, 0xec, 0x2e, 0x99, 0xfb, 0x1c, 0x90, + 0xb9, 0xcf, 0x3c, 0xfd, 0x6e, 0xad, 0x80, 0xe2, 0x9d, 0x26, 0xa7, 0xc6, 0x32, 0xc6, 0x8e, 0xfa, 0xad, 0x06, 0x83, + 0x06, 0x4d, 0xae, 0x02, 0x6f, 0x87, 0xea, 0xf4, 0xf2, 0xf6, 0x47, 0x71, 0xb6, 0x54, 0x5a, 0xce, 0x5d, 0xa3, 0xca, + 0xf9, 0x38, 0x99, 0x4c, 0x50, 0x60, 0x9b, 0x3b, 0xfc, 0xb4, 0xee, 0x46, 0xb6, 0xfa, 0xc2, 0xc5, 0x38, 0x55, 0xd8, + 0x9d, 0x2d, 0x2a, 0x95, 0x1b, 0xe2, 0xcd, 0x9c, 0x77, 0xf3, 0xf0, 0x84, 0x0b, 0xae, 0x66, 0xac, 0x88, 0x0b, 0xb4, + 0xfa, 0x56, 0x67, 0x05, 0xdc, 0xe6, 0xd8, 0xce, 0xf0, 0xb2, 0xb4, 0x1c, 0xd0, 0x09, 0xb4, 0x06, 0x3a, 0xa3, 0x39, + 0xd3, 0x33, 0x39, 0x06, 0xc3, 0x97, 0x64, 0x5c, 0xba, 0x53, 0x1d, 0x1d, 0x1d, 0xc6, 0x91, 0xd1, 0x5f, 0x80, 0x0f, + 0x7a, 0x98, 0x83, 0xfa, 0x2b, 0x70, 0x0c, 0xaa, 0xba, 0x66, 0x68, 0xc5, 0xb6, 0x7d, 0x68, 0x74, 0xf2, 0x85, 0xdd, + 0x61, 0x8e, 0x36, 0x9b, 0xd4, 0x8e, 0x3a, 0x9a, 0x70, 0x96, 0x8f, 0x23, 0xfc, 0x85, 0xdd, 0xa5, 0xa5, 0xdb, 0xba, + 0xf1, 0xb2, 0x36, 0x8b, 0x18, 0xc9, 0x1b, 0x11, 0xe1, 0xaa, 0x93, 0x74, 0xb5, 0xc1, 0xb2, 0xe0, 0x53, 0xc0, 0xd1, + 0x9f, 0xd9, 0x5d, 0xea, 0xda, 0x0b, 0x5c, 0x05, 0xd1, 0xca, 0x83, 0x3e, 0x09, 0x92, 0xc3, 0x65, 0x70, 0x02, 0xc7, + 0xc0, 0xd4, 0x1d, 0x92, 0x5a, 0xb9, 0x4a, 0x84, 0x44, 0x68, 0xf3, 0xef, 0x4e, 0x05, 0x4f, 0xc2, 0x73, 0x4e, 0xd7, + 0x2c, 0x6e, 0xb7, 0x2a, 0x31, 0xa8, 0x50, 0x59, 0x90, 0x7c, 0x8c, 0xb9, 0xdf, 0x7d, 0xce, 0xfb, 0x21, 0xd0, 0x99, + 0x4d, 0xa8, 0x6b, 0x34, 0x5d, 0x9a, 0x5f, 0xa8, 0xba, 0x83, 0x9a, 0xeb, 0xaa, 0xe2, 0xc1, 0xc7, 0x18, 0x00, 0x0f, + 0xd6, 0x32, 0xd4, 0x38, 0x84, 0x6e, 0xbc, 0x99, 0xea, 0x82, 0x92, 0x78, 0xe5, 0xe7, 0x90, 0xf2, 0x10, 0x8c, 0x7a, + 0x03, 0x68, 0xe8, 0x10, 0xcc, 0x5a, 0x1e, 0xf2, 0x49, 0x2c, 0x76, 0xce, 0x50, 0x69, 0xce, 0xd0, 0x24, 0x00, 0xf9, + 0x37, 0xce, 0x4c, 0x66, 0xa0, 0x61, 0x78, 0x4b, 0x73, 0x00, 0xba, 0xd5, 0x75, 0x38, 0x14, 0xae, 0x68, 0xe9, 0xbc, + 0x67, 0x17, 0x5d, 0xd6, 0x86, 0x15, 0x9b, 0x76, 0xd0, 0x26, 0x85, 0x29, 0x31, 0x5b, 0x60, 0xe3, 0xf5, 0x3e, 0xdc, + 0xdb, 0xd5, 0xc6, 0x45, 0xe2, 0xa7, 0x45, 0x3c, 0x4c, 0x62, 0x8a, 0x56, 0x3c, 0xa6, 0x58, 0x82, 0x1d, 0x64, 0xb1, + 0x29, 0xc7, 0xcf, 0xc2, 0xe5, 0xa8, 0x59, 0x49, 0xef, 0x77, 0x30, 0x04, 0x2e, 0x5f, 0x83, 0x6d, 0x28, 0xe6, 0x25, + 0x61, 0x89, 0x8d, 0xa7, 0x5f, 0xb0, 0x6e, 0x53, 0xbb, 0x20, 0x7e, 0x05, 0x16, 0x34, 0x5e, 0x05, 0xb3, 0x08, 0x9d, + 0xca, 0x9d, 0xc3, 0xa1, 0xbb, 0x26, 0xac, 0x8c, 0x57, 0x63, 0x45, 0xb6, 0x8e, 0x9e, 0xef, 0xdb, 0x78, 0xfe, 0xb5, + 0x64, 0xc5, 0xdd, 0x35, 0x03, 0x1b, 0x6b, 0x09, 0xee, 0xc6, 0xd5, 0x32, 0x54, 0x06, 0xf2, 0x7d, 0x69, 0x58, 0x97, + 0x0d, 0xfe, 0x6e, 0x54, 0x8c, 0x8d, 0xb9, 0xa7, 0x0c, 0xb4, 0x35, 0x76, 0xbb, 0xb0, 0x6f, 0xba, 0x6e, 0xb2, 0x9e, + 0x89, 0x95, 0x50, 0x41, 0xda, 0xdd, 0x2d, 0xe0, 0x22, 0xf4, 0x87, 0x1d, 0xa8, 0xe1, 0xb6, 0xea, 0x06, 0x92, 0xe0, + 0xda, 0x4f, 0x7e, 0x7b, 0xaa, 0xfb, 0xac, 0x75, 0xbf, 0x3d, 0xd5, 0xda, 0x65, 0xa1, 0x31, 0x24, 0xc2, 0xae, 0x9f, + 0xd2, 0x7f, 0x5a, 0x6c, 0x36, 0x68, 0x03, 0xc3, 0x7b, 0xc4, 0x7b, 0x71, 0xfc, 0xc8, 0x5b, 0x28, 0x26, 0x70, 0x91, + 0x7b, 0x9d, 0x4b, 0x4f, 0xc8, 0xab, 0x11, 0x3c, 0xe2, 0x3b, 0x43, 0x78, 0xc4, 0x03, 0xa7, 0x57, 0x90, 0x9a, 0xa6, + 0x82, 0x8d, 0x3d, 0xfd, 0x44, 0x16, 0x09, 0x0d, 0x1f, 0xf7, 0x9a, 0x13, 0xa1, 0xff, 0x4c, 0x81, 0xff, 0xc2, 0xa3, + 0xa5, 0xd6, 0x52, 0x60, 0x2e, 0x16, 0x4b, 0x8d, 0x95, 0x19, 0xfd, 0x6a, 0x22, 0x85, 0x6e, 0x4e, 0xe8, 0x9c, 0xe7, + 0x77, 0xe9, 0x92, 0x37, 0xe7, 0x52, 0x48, 0xb5, 0xa0, 0x19, 0xc3, 0xea, 0x4e, 0x69, 0x36, 0x6f, 0x2e, 0x39, 0x7e, + 0xce, 0xf2, 0xaf, 0x4c, 0xf3, 0x8c, 0xe2, 0xb7, 0x72, 0x24, 0xb5, 0xc4, 0xaf, 0x6f, 0xef, 0xa6, 0x4c, 0xe0, 0xf7, + 0xa3, 0xa5, 0xd0, 0x4b, 0xac, 0xa8, 0x50, 0x4d, 0xc5, 0x0a, 0x3e, 0xe9, 0x35, 0x9b, 0x8b, 0x82, 0xcf, 0x69, 0x71, + 0xd7, 0xcc, 0x64, 0x2e, 0x8b, 0xf4, 0xbf, 0x5a, 0xa7, 0xf4, 0xc1, 0xe4, 0xac, 0xa7, 0x0b, 0x2a, 0x14, 0x87, 0x85, + 0x49, 0x69, 0x9e, 0x1f, 0x9c, 0x76, 0x5b, 0x73, 0x75, 0x68, 0x2f, 0xfc, 0xa8, 0xd0, 0x9b, 0x3f, 0xf1, 0x6f, 0x12, + 0x46, 0x99, 0x8c, 0xb4, 0x70, 0x83, 0x5c, 0x65, 0xcb, 0x42, 0xc9, 0x22, 0x5d, 0x48, 0x2e, 0x34, 0x2b, 0x7a, 0x23, + 0x59, 0x8c, 0x59, 0xd1, 0x2c, 0xe8, 0x98, 0x2f, 0x55, 0x7a, 0xb6, 0xb8, 0xed, 0xd5, 0x7b, 0xb0, 0xf9, 0xa9, 0x90, + 0x82, 0xf5, 0x80, 0xdf, 0x98, 0x16, 0x72, 0x29, 0xc6, 0x6e, 0x18, 0x4b, 0xa1, 0x98, 0xee, 0x2d, 0xe8, 0x18, 0xec, + 0x80, 0xd3, 0x8b, 0xc5, 0x6d, 0xcf, 0xcc, 0xfa, 0x86, 0xf1, 0xe9, 0x4c, 0xa7, 0xdd, 0x56, 0xcb, 0x7e, 0x2b, 0xfe, + 0x37, 0x4b, 0xdb, 0x9d, 0xa4, 0xd3, 0x5d, 0xdc, 0x02, 0x07, 0xaf, 0x59, 0xd1, 0x04, 0x58, 0x40, 0xa5, 0x76, 0xd2, + 0x7a, 0x70, 0x7a, 0x1f, 0x32, 0xc0, 0xc6, 0xa1, 0x69, 0x26, 0x04, 0xc6, 0xee, 0xe9, 0x72, 0xb1, 0x60, 0x05, 0x78, + 0xd1, 0xf7, 0xe6, 0xb4, 0x98, 0x72, 0xd1, 0x2c, 0x4c, 0xa3, 0xcd, 0x8b, 0xc5, 0xed, 0x06, 0xe6, 0x93, 0x5a, 0xb3, + 0x55, 0x37, 0x2d, 0xf7, 0xb5, 0x0a, 0x86, 0x68, 0x62, 0xd2, 0xa4, 0xc5, 0x74, 0x44, 0xe3, 0x76, 0xe7, 0x3e, 0xf6, + 0xff, 0x4b, 0x3a, 0x28, 0x00, 0x5b, 0x73, 0xbc, 0x2c, 0xcc, 0x2d, 0x6a, 0xda, 0x56, 0xb6, 0xd9, 0x99, 0xfc, 0xca, + 0x0a, 0xdf, 0xaa, 0xf9, 0x58, 0xed, 0xcc, 0xfb, 0x3f, 0x6a, 0x94, 0xda, 0xb6, 0x5e, 0xa8, 0x6b, 0xa0, 0xd1, 0xbb, + 0x8d, 0xfd, 0x57, 0xe7, 0x82, 0xde, 0x3f, 0xeb, 0x7a, 0xb8, 0x4f, 0x26, 0x93, 0x1a, 0xd0, 0x3d, 0x74, 0xdb, 0xad, + 0xc5, 0xed, 0x41, 0xa7, 0xe5, 0x61, 0x6c, 0x61, 0x7a, 0xbe, 0xb8, 0xdd, 0xb3, 0x82, 0x01, 0x56, 0x6c, 0xf7, 0x76, + 0x90, 0x9c, 0xaa, 0x03, 0x46, 0x15, 0xdb, 0xfc, 0x89, 0xe7, 0x14, 0x70, 0xc3, 0x20, 0xed, 0xc0, 0xc8, 0xa9, 0xb0, + 0x02, 0xc3, 0xd5, 0x0d, 0x1f, 0xeb, 0x59, 0xda, 0x6e, 0xb5, 0x7e, 0xa8, 0x30, 0xa9, 0x37, 0xb3, 0x4b, 0xda, 0x2e, + 0xd8, 0xbc, 0x86, 0x5f, 0x23, 0x5a, 0xee, 0x82, 0xd5, 0x42, 0xba, 0x4e, 0x0b, 0x96, 0x9b, 0x28, 0x37, 0x1b, 0xb7, + 0x15, 0x76, 0xa6, 0xcc, 0xc5, 0x8c, 0x15, 0x5c, 0xf7, 0xea, 0x5f, 0x55, 0xc7, 0xbb, 0x73, 0xda, 0x58, 0xf9, 0x78, + 0x65, 0x6b, 0xb8, 0xcb, 0xd8, 0xc7, 0xf0, 0xb1, 0x8b, 0x95, 0x5f, 0x69, 0x11, 0x6f, 0x6d, 0x18, 0x1c, 0xd6, 0x40, + 0x9b, 0x60, 0xce, 0x05, 0x98, 0x8a, 0x0e, 0xf1, 0x37, 0xa0, 0x90, 0xd1, 0x3c, 0x8b, 0x61, 0x44, 0x07, 0xcd, 0x83, + 0xd3, 0x82, 0xcd, 0x91, 0x07, 0x44, 0x72, 0xbf, 0x5b, 0xb0, 0xf9, 0x26, 0x31, 0xd5, 0x57, 0x06, 0x75, 0x69, 0xce, + 0xa7, 0x22, 0xcd, 0x18, 0x6c, 0xab, 0x4d, 0xc2, 0x84, 0xe6, 0xfa, 0xae, 0x59, 0xc8, 0x9b, 0xd5, 0x98, 0xab, 0x45, + 0x4e, 0xef, 0xd2, 0x49, 0xce, 0x6e, 0x7b, 0xa6, 0x54, 0x93, 0x6b, 0x36, 0x57, 0xae, 0x6c, 0x0f, 0xd2, 0x9b, 0x63, + 0x6b, 0xce, 0x01, 0xd0, 0x93, 0x37, 0xdb, 0xfb, 0xda, 0x2f, 0x5a, 0x53, 0x2e, 0xf5, 0x41, 0x4b, 0xf5, 0xe6, 0x5c, + 0x34, 0xdd, 0x40, 0xce, 0x00, 0x23, 0x76, 0x21, 0x1f, 0xf4, 0x9f, 0xb0, 0xdb, 0x05, 0x15, 0x63, 0x36, 0x5e, 0x05, + 0xd5, 0x3a, 0x50, 0x2f, 0x2c, 0x95, 0x0a, 0x3d, 0x6b, 0x1a, 0x1b, 0xb4, 0xb8, 0x23, 0xd0, 0x37, 0x50, 0xfe, 0x41, + 0x0b, 0xdb, 0xff, 0x4f, 0xda, 0x28, 0xac, 0x7c, 0x00, 0xe1, 0xa0, 0xf8, 0xe4, 0xae, 0x09, 0x7f, 0x57, 0xe0, 0xf3, + 0xc4, 0x33, 0x9a, 0x3b, 0x88, 0xcc, 0xf9, 0x78, 0x9c, 0xd7, 0x46, 0x74, 0x15, 0x74, 0xd6, 0x46, 0x2b, 0x98, 0x7f, + 0xda, 0x3a, 0x68, 0x1d, 0x98, 0xb9, 0xb8, 0x6d, 0x70, 0x76, 0x76, 0xff, 0xf4, 0x01, 0xeb, 0xe5, 0x5c, 0xb0, 0xda, + 0x54, 0xbf, 0x0b, 0xea, 0xb0, 0xe1, 0x8e, 0x6b, 0xb8, 0x7d, 0xd0, 0x3e, 0x38, 0x6b, 0xfd, 0xe0, 0xa9, 0x48, 0xce, + 0x26, 0xda, 0xee, 0x9b, 0x1a, 0x59, 0xb9, 0xf0, 0x4d, 0xdf, 0x14, 0x74, 0x91, 0x0a, 0x09, 0x7f, 0x7a, 0xb0, 0xf9, + 0x27, 0xb9, 0xbc, 0x49, 0x67, 0x7c, 0x3c, 0x66, 0xc2, 0x16, 0x28, 0x13, 0x59, 0x9e, 0xf3, 0x85, 0xe2, 0x76, 0x35, + 0x1c, 0xee, 0x76, 0xb7, 0xa0, 0x1a, 0x0e, 0xe8, 0x34, 0x18, 0x50, 0xb7, 0x1a, 0x50, 0xd5, 0x7f, 0x38, 0xc2, 0xce, + 0xd6, 0x5c, 0x4d, 0xa9, 0x5e, 0x0d, 0x93, 0x3e, 0x2f, 0x95, 0x06, 0x98, 0x7b, 0xe3, 0x11, 0x73, 0xba, 0x34, 0x47, + 0x4c, 0xdf, 0x30, 0x26, 0xbe, 0x3d, 0x88, 0xab, 0x54, 0x8a, 0xfc, 0xce, 0x7e, 0xae, 0xc2, 0x2e, 0xe9, 0x52, 0xcb, + 0x4d, 0x32, 0xe2, 0x82, 0x16, 0x77, 0x9f, 0x14, 0x13, 0x4a, 0x16, 0x9f, 0xe4, 0x64, 0xb2, 0xfa, 0x16, 0xc9, 0xbb, + 0x8f, 0x36, 0x89, 0xe2, 0x62, 0x9a, 0x33, 0x4b, 0xe0, 0x0c, 0x22, 0xb8, 0x43, 0xc6, 0xb6, 0x6b, 0x9a, 0xac, 0x0d, + 0x7a, 0x93, 0x64, 0x39, 0x9f, 0x53, 0xcd, 0x0c, 0x9c, 0x03, 0x52, 0xe3, 0x26, 0x6f, 0xa9, 0x5c, 0xeb, 0xc0, 0xfe, + 0xa9, 0x4a, 0xc3, 0x36, 0x0a, 0x0a, 0xfb, 0x26, 0xb9, 0x30, 0xf8, 0x61, 0xc0, 0x61, 0x76, 0x91, 0x59, 0x3d, 0xb3, + 0x76, 0x01, 0xec, 0x60, 0x76, 0xb5, 0xa6, 0xae, 0x1c, 0x5d, 0xb2, 0x2d, 0x76, 0x5b, 0x3f, 0xd4, 0x73, 0x73, 0x3a, + 0x62, 0xf9, 0xca, 0x6e, 0x54, 0x0f, 0x5c, 0xb7, 0x55, 0xc3, 0x65, 0x0e, 0x48, 0x86, 0x01, 0xd1, 0x30, 0x4d, 0x9b, + 0x37, 0x6c, 0xf4, 0x85, 0x6b, 0xbb, 0x65, 0x9a, 0xea, 0x06, 0x9c, 0x8a, 0xcc, 0x98, 0x16, 0xac, 0x58, 0x79, 0x42, + 0xde, 0xaa, 0x11, 0xd0, 0x6b, 0x61, 0x0e, 0x68, 0x4d, 0x47, 0x4d, 0x08, 0xb1, 0xc6, 0x8a, 0xd5, 0xbe, 0xc9, 0xcd, + 0xe9, 0xad, 0x43, 0xb1, 0x07, 0xad, 0x1f, 0x6a, 0x87, 0xec, 0x59, 0xab, 0xe5, 0x8f, 0x88, 0xa6, 0xad, 0x91, 0xb6, + 0x93, 0x2e, 0x9b, 0x97, 0x89, 0x5a, 0x2e, 0xd2, 0x5a, 0xc2, 0x48, 0x6a, 0x2d, 0xe7, 0x36, 0x6d, 0x0f, 0x35, 0xaa, + 0x93, 0xde, 0x76, 0x67, 0x71, 0x7b, 0x60, 0xfe, 0x69, 0x1d, 0xb4, 0x76, 0x49, 0xed, 0x2e, 0x56, 0x9c, 0x22, 0x8f, + 0xc7, 0xd0, 0x71, 0x9b, 0xcd, 0x7b, 0x4b, 0x05, 0xc7, 0xbd, 0x81, 0xb8, 0x39, 0xd1, 0x36, 0x66, 0xb2, 0x00, 0x58, + 0xca, 0x05, 0x9c, 0xae, 0xf6, 0xb0, 0x83, 0x3e, 0x94, 0x04, 0x73, 0xf8, 0xbd, 0x8d, 0xd6, 0x87, 0xd5, 0x3a, 0xa8, + 0x06, 0x06, 0xff, 0x6c, 0xfe, 0xac, 0xf8, 0xf3, 0x27, 0x2c, 0x90, 0x8f, 0x78, 0x23, 0xe9, 0xae, 0x5b, 0x4e, 0x26, + 0x1a, 0xeb, 0x4a, 0x54, 0x33, 0x1e, 0x25, 0x73, 0x7a, 0x6b, 0x5d, 0x4b, 0xe6, 0x5c, 0x80, 0xe1, 0x1a, 0xc2, 0x3a, + 0x30, 0xf1, 0x9f, 0x85, 0x0d, 0x8d, 0x75, 0x0c, 0x0d, 0x1f, 0x77, 0x92, 0x6e, 0x17, 0xe1, 0x16, 0xee, 0x74, 0xbb, + 0x81, 0x4c, 0x36, 0xd1, 0xfb, 0x8a, 0xee, 0x2b, 0x29, 0xf7, 0x94, 0x3c, 0x31, 0x8d, 0x9e, 0xb4, 0x5b, 0x2d, 0x6c, + 0xdc, 0xe7, 0xcb, 0xc2, 0x42, 0xed, 0x69, 0xb6, 0xdd, 0x6a, 0x41, 0xb3, 0xf0, 0xc7, 0xcd, 0xeb, 0x67, 0xb2, 0x6a, + 0xa5, 0x2d, 0xdc, 0x4e, 0xdb, 0xb8, 0x93, 0x76, 0xf0, 0x69, 0x7a, 0x8a, 0xcf, 0xd2, 0x33, 0xdc, 0x4d, 0xbb, 0xf8, + 0x3c, 0x3d, 0xc7, 0xf7, 0xd3, 0xfb, 0xf8, 0x22, 0xbd, 0xc0, 0x0f, 0xd2, 0x07, 0xf8, 0x61, 0xda, 0x6e, 0xe1, 0x47, + 0x69, 0xbb, 0x8d, 0x1f, 0xa7, 0xed, 0x0e, 0x7e, 0x92, 0xb6, 0x4f, 0xf1, 0xd3, 0xb4, 0x7d, 0x86, 0x9f, 0xa5, 0xed, + 0x2e, 0xa6, 0x90, 0x3b, 0x82, 0xdc, 0x0c, 0x72, 0xc7, 0x90, 0xcb, 0x20, 0x77, 0x92, 0xb6, 0xbb, 0x1b, 0xac, 0x6c, + 0xc8, 0x8d, 0xa8, 0xd5, 0xee, 0x9c, 0x9e, 0x75, 0xcf, 0xef, 0x5f, 0x3c, 0x78, 0xf8, 0xe8, 0xf1, 0x93, 0xa7, 0xcf, + 0xa2, 0x21, 0xfe, 0x64, 0x3c, 0x5f, 0x94, 0x18, 0xf0, 0xa3, 0x76, 0x77, 0x88, 0xef, 0xfc, 0x67, 0xcc, 0x8f, 0x3a, + 0x67, 0x2d, 0x74, 0x75, 0x75, 0x36, 0x6c, 0x94, 0xb9, 0x8f, 0x8c, 0xc3, 0x4d, 0x95, 0x45, 0x08, 0x89, 0x21, 0x07, + 0xe1, 0x5b, 0xeb, 0x40, 0xc3, 0x62, 0x9e, 0x14, 0xe8, 0xe8, 0xc8, 0xfc, 0x98, 0xfa, 0x1f, 0x23, 0xff, 0x83, 0x06, + 0x8b, 0xf4, 0x95, 0xc6, 0xce, 0xe3, 0x5a, 0x97, 0xfe, 0x0e, 0xa5, 0x29, 0xd1, 0x01, 0x77, 0x46, 0xfd, 0xff, 0x15, + 0x59, 0xa3, 0x1d, 0x72, 0x66, 0x15, 0x63, 0xdd, 0x3e, 0x23, 0xab, 0x22, 0xed, 0x74, 0xbb, 0x47, 0x3f, 0x0f, 0xf8, + 0xa0, 0x3d, 0x1c, 0x1e, 0xb7, 0xef, 0xe3, 0x69, 0x99, 0xd0, 0xb1, 0x09, 0xa3, 0x32, 0xe1, 0xd4, 0x26, 0xd0, 0xd4, + 0xd6, 0x86, 0xa4, 0x33, 0x93, 0x04, 0x25, 0x36, 0xa9, 0x69, 0xfb, 0xbe, 0x6d, 0xfb, 0x01, 0x58, 0x93, 0x99, 0xe6, + 0x5d, 0xd3, 0x97, 0x97, 0x67, 0x6b, 0xd7, 0x28, 0x9e, 0xa6, 0xae, 0x35, 0x9f, 0x78, 0x36, 0x1c, 0xe2, 0x91, 0x49, + 0xec, 0x56, 0x89, 0xe7, 0xc3, 0xa1, 0xeb, 0xea, 0x81, 0xe9, 0xea, 0x7e, 0x95, 0x75, 0x31, 0x1c, 0x9a, 0x2e, 0x91, + 0x8b, 0x1d, 0xa0, 0xf4, 0xc1, 0x4d, 0xa9, 0xbf, 0xe1, 0x97, 0x9d, 0x6e, 0xb7, 0x0f, 0x18, 0x66, 0x6c, 0x82, 0x3d, + 0x8c, 0xbe, 0x04, 0x30, 0xba, 0x85, 0xdf, 0xfd, 0x4f, 0x34, 0xbd, 0xa3, 0x25, 0x90, 0xfa, 0xd1, 0x7f, 0x45, 0x0d, + 0x6d, 0x60, 0x6e, 0xfe, 0x4c, 0xed, 0x9f, 0x11, 0x6a, 0xdc, 0x50, 0x00, 0x37, 0x68, 0xa4, 0xbc, 0x4a, 0xd9, 0xf4, + 0x78, 0x4d, 0xc1, 0xc5, 0x67, 0xa6, 0x72, 0xda, 0x5f, 0xcf, 0x6e, 0x46, 0xeb, 0x99, 0xfa, 0x8a, 0xfe, 0x88, 0xff, + 0x50, 0xc7, 0xf1, 0xa0, 0xd9, 0x48, 0xd8, 0x1f, 0x63, 0xf0, 0x25, 0xea, 0xa7, 0x63, 0x36, 0x45, 0xfd, 0xc1, 0x1f, + 0x0a, 0x0f, 0x1b, 0x41, 0xc6, 0x0f, 0xbb, 0x29, 0xe0, 0x69, 0xb4, 0x9d, 0x18, 0xff, 0x80, 0xfa, 0xa8, 0xff, 0x87, + 0x3a, 0xfe, 0x03, 0xdd, 0x3b, 0x09, 0xb4, 0x26, 0xd2, 0x6d, 0xe1, 0x2a, 0xfc, 0xd0, 0x71, 0xb9, 0x85, 0x19, 0x6e, + 0x37, 0x19, 0x04, 0x6b, 0x03, 0x57, 0x74, 0x12, 0xcb, 0x06, 0x3f, 0x39, 0x6d, 0xa1, 0x1f, 0xda, 0x1d, 0x50, 0xae, + 0x34, 0xc5, 0xf1, 0xee, 0xa6, 0x2f, 0x9a, 0xa7, 0xf8, 0x41, 0xb3, 0xc0, 0x6d, 0x84, 0x9b, 0x6d, 0xaf, 0xf5, 0x1e, + 0xa8, 0xb8, 0x85, 0xb0, 0x8a, 0x2f, 0xe0, 0x9f, 0x33, 0x34, 0xac, 0x36, 0xe4, 0x2f, 0x74, 0xbb, 0x77, 0xf0, 0x9b, + 0x25, 0xb1, 0x6a, 0xf0, 0x93, 0xf3, 0x16, 0xfa, 0xe1, 0xdc, 0x74, 0xc4, 0x8e, 0xf5, 0x9e, 0xae, 0x24, 0x3e, 0x6b, + 0x4a, 0xe8, 0xa8, 0x55, 0xf6, 0x23, 0xe2, 0x2e, 0xc2, 0x22, 0x3e, 0x85, 0x7f, 0xda, 0x61, 0x3f, 0x8f, 0x77, 0xfa, + 0x31, 0xf3, 0x6e, 0xe3, 0xa4, 0x6b, 0xdd, 0x70, 0x95, 0xbd, 0x13, 0x6f, 0xb0, 0xab, 0xb6, 0xb9, 0xcc, 0x6b, 0x9f, + 0xc0, 0x07, 0xc2, 0xfa, 0x98, 0x28, 0xcc, 0x8e, 0xc1, 0x7f, 0x17, 0xcc, 0x56, 0xd4, 0xe5, 0x69, 0x4f, 0x35, 0x1a, + 0x48, 0x0c, 0xd4, 0xf0, 0x98, 0xb4, 0x9b, 0xba, 0xc9, 0x30, 0xfc, 0x6e, 0x90, 0x32, 0x28, 0x9c, 0xa8, 0x7a, 0x7d, + 0xed, 0x7a, 0xb5, 0x37, 0xff, 0x1e, 0x3b, 0x08, 0x21, 0xaa, 0x1f, 0xeb, 0x26, 0x43, 0x27, 0xa2, 0x11, 0xeb, 0x4b, + 0xd6, 0x3f, 0x4f, 0x5b, 0xc8, 0x60, 0xa7, 0xea, 0xc7, 0xac, 0xc9, 0x21, 0xbd, 0x93, 0xc6, 0xbc, 0xa9, 0xe1, 0xd7, + 0x59, 0x00, 0x2d, 0x01, 0x78, 0x57, 0x79, 0x23, 0x15, 0x27, 0x9d, 0x6e, 0x17, 0x0b, 0xc2, 0x93, 0xa9, 0xf9, 0xa5, + 0x08, 0x4f, 0x46, 0xe6, 0x97, 0x24, 0x25, 0xbc, 0x6c, 0xef, 0xb8, 0x20, 0xc1, 0xaa, 0x9a, 0x14, 0x0a, 0x0b, 0x5a, + 0xa0, 0x93, 0x8e, 0x37, 0x0b, 0xc0, 0x33, 0x3f, 0x07, 0x50, 0x83, 0x14, 0xc6, 0x22, 0x54, 0x36, 0x0b, 0x9c, 0x13, + 0x7a, 0x95, 0x74, 0xfb, 0xb3, 0x93, 0xb8, 0xd3, 0x94, 0xcd, 0x02, 0xa5, 0xb3, 0x13, 0x53, 0x13, 0x67, 0xe4, 0x35, + 0xb5, 0xad, 0xe1, 0x19, 0xdc, 0xe5, 0x66, 0x24, 0x3b, 0x3e, 0x6f, 0x35, 0x92, 0x2e, 0xc2, 0x83, 0x6c, 0xdd, 0xc2, + 0xf9, 0x7a, 0xdd, 0xc2, 0x34, 0x5c, 0x06, 0xe1, 0x01, 0x52, 0x6a, 0xea, 0xb6, 0x63, 0xf3, 0xf4, 0x79, 0xac, 0xc1, + 0x2e, 0x41, 0x83, 0xb7, 0x8f, 0x06, 0x3f, 0xa4, 0x94, 0xbb, 0x0b, 0x41, 0x64, 0xa2, 0x13, 0x4e, 0x42, 0xdd, 0xdd, + 0x6b, 0xe1, 0xd7, 0xd5, 0x5b, 0x96, 0x8a, 0xf8, 0xa3, 0xc4, 0x36, 0xad, 0x2a, 0xf6, 0x86, 0xee, 0x16, 0x7b, 0x4c, + 0x77, 0x8a, 0xdd, 0xdb, 0x53, 0xec, 0x97, 0xdd, 0x62, 0x7f, 0xc9, 0x40, 0xd3, 0xc8, 0x7f, 0x38, 0x3d, 0x6f, 0x35, + 0x4e, 0x01, 0x59, 0x4f, 0xcf, 0x5b, 0x55, 0xa1, 0x87, 0xb4, 0x5a, 0x2b, 0x4d, 0xae, 0xa9, 0xf5, 0xb5, 0xe0, 0xde, + 0xe9, 0xdb, 0x2c, 0x9c, 0x75, 0x39, 0x2f, 0xfd, 0xcb, 0x07, 0x5d, 0xb0, 0x65, 0x11, 0x86, 0xda, 0xe9, 0xc1, 0xf9, + 0xb0, 0x3f, 0x63, 0x71, 0x03, 0x52, 0x51, 0x3a, 0xd1, 0xee, 0x17, 0x2a, 0xaf, 0xb4, 0xff, 0x92, 0x90, 0xd4, 0x19, + 0x22, 0x2c, 0x49, 0x43, 0x0f, 0x4e, 0x87, 0xe6, 0xbc, 0x2b, 0xe0, 0xf7, 0x99, 0xf9, 0x5d, 0x2a, 0x94, 0x9c, 0x43, + 0xc6, 0xec, 0x66, 0x14, 0xf5, 0x05, 0x79, 0x43, 0x63, 0x63, 0x63, 0x8f, 0xd2, 0x32, 0x43, 0x7d, 0x85, 0x8c, 0x7b, + 0x65, 0x86, 0x20, 0xaf, 0x85, 0xfb, 0x8d, 0x57, 0x45, 0x0a, 0xf6, 0x36, 0x78, 0x9a, 0x82, 0xad, 0x0d, 0x1e, 0xa5, + 0x02, 0xfc, 0x41, 0x68, 0xca, 0x02, 0x2b, 0xfe, 0xa7, 0x4e, 0x83, 0x67, 0x6e, 0x9d, 0x89, 0xc1, 0xd2, 0x1e, 0x83, + 0x93, 0xe2, 0x2f, 0x19, 0xc3, 0xdf, 0x86, 0x46, 0x98, 0x41, 0x9b, 0x0c, 0x61, 0x9e, 0x14, 0x04, 0xd2, 0x30, 0x4f, + 0xa6, 0x84, 0x41, 0x93, 0x3c, 0x19, 0x11, 0x36, 0xe8, 0x04, 0x68, 0xf2, 0xc2, 0xc0, 0x0e, 0x80, 0xc3, 0xeb, 0x17, + 0xf9, 0xda, 0x36, 0x0e, 0x16, 0x02, 0xd0, 0x84, 0x20, 0x10, 0x73, 0x61, 0x00, 0x66, 0x23, 0xca, 0xfe, 0xec, 0x54, + 0xe1, 0x2f, 0x79, 0x42, 0x0d, 0xf5, 0xfe, 0x13, 0xc8, 0x6a, 0x7c, 0x6f, 0xc5, 0x36, 0xf8, 0xe0, 0xde, 0x4a, 0x6c, + 0x7e, 0x80, 0x3f, 0xca, 0xfe, 0x01, 0xe6, 0x21, 0xa1, 0x68, 0x83, 0xfe, 0x4c, 0xa1, 0xd8, 0x9e, 0x52, 0xe8, 0x4f, + 0xef, 0x0e, 0xa8, 0xc8, 0xea, 0x36, 0x8d, 0xc6, 0xb4, 0xf8, 0x12, 0xe1, 0xdf, 0xd3, 0x28, 0x07, 0x6e, 0x31, 0xc2, + 0x1f, 0xd3, 0xa8, 0x60, 0x11, 0xfe, 0x67, 0x1a, 0x8d, 0xf2, 0x65, 0x84, 0x7f, 0x4b, 0xa3, 0x69, 0x11, 0xe1, 0x0f, + 0xa0, 0xac, 0x1d, 0xf3, 0xe5, 0x3c, 0xc2, 0xef, 0xd3, 0x48, 0x19, 0x6f, 0x08, 0xfc, 0x30, 0x8d, 0x18, 0x8b, 0xf0, + 0xbb, 0x34, 0x92, 0x79, 0x84, 0xaf, 0xd3, 0x48, 0x16, 0x11, 0x7e, 0x94, 0x46, 0x05, 0x8d, 0xf0, 0xe3, 0x34, 0x82, + 0x42, 0xd3, 0x08, 0x3f, 0x49, 0x23, 0x68, 0x59, 0x45, 0xf8, 0x6d, 0x1a, 0x71, 0x11, 0xe1, 0x5f, 0xd3, 0x48, 0x2f, + 0x8b, 0xbf, 0x96, 0x92, 0xab, 0x08, 0x3f, 0x4d, 0xa3, 0x19, 0x8f, 0xf0, 0x9b, 0x34, 0x2a, 0x64, 0x84, 0x5f, 0xa7, + 0x11, 0xcd, 0x23, 0xfc, 0x2a, 0x8d, 0x72, 0x16, 0xe1, 0x5f, 0xd2, 0x68, 0xcc, 0x22, 0xfc, 0x32, 0x8d, 0xee, 0x58, + 0x9e, 0xcb, 0x08, 0x3f, 0x4b, 0x23, 0x26, 0x22, 0xfc, 0x73, 0x1a, 0x65, 0xb3, 0x08, 0xff, 0x23, 0x8d, 0x68, 0xf1, + 0x45, 0x45, 0xf8, 0x79, 0x1a, 0x31, 0x1a, 0xe1, 0x17, 0xb6, 0xa3, 0x69, 0x84, 0x7f, 0x4a, 0xa3, 0x9b, 0x59, 0xb4, + 0xc1, 0x52, 0x91, 0xd5, 0x6b, 0x9e, 0xb1, 0x7f, 0xb2, 0x34, 0x9a, 0xb4, 0x26, 0x17, 0x93, 0x49, 0x84, 0xa9, 0xd0, + 0xfc, 0xaf, 0x25, 0xbb, 0x79, 0xaa, 0x21, 0x91, 0xb2, 0xd1, 0xf8, 0x7e, 0x84, 0xe9, 0x5f, 0x4b, 0x9a, 0x46, 0x93, + 0x89, 0x29, 0xf0, 0xd7, 0x92, 0xce, 0x69, 0xf1, 0x96, 0xa5, 0xd1, 0xfd, 0xc9, 0x64, 0x32, 0x3e, 0x8b, 0x30, 0xfd, + 0x7b, 0xf9, 0xd1, 0xb4, 0x60, 0x0a, 0x8c, 0x18, 0x9f, 0x42, 0xdd, 0xee, 0xa4, 0x3b, 0xce, 0x22, 0x3c, 0xe2, 0xea, + 0xaf, 0x25, 0x7c, 0x4f, 0xd8, 0x59, 0x76, 0x16, 0xe1, 0x51, 0x4e, 0xb3, 0x2f, 0x69, 0xd4, 0x32, 0xbf, 0xc4, 0xcf, + 0x6c, 0xfc, 0x7a, 0x2e, 0xcd, 0x55, 0xc6, 0x84, 0x8d, 0xb2, 0x71, 0x84, 0xcd, 0x60, 0x26, 0xf0, 0xf7, 0x2b, 0x7f, + 0xc7, 0x74, 0x1a, 0x5d, 0xd0, 0xce, 0x88, 0x75, 0x22, 0x3c, 0x7a, 0x73, 0x23, 0xd2, 0x88, 0x76, 0x3b, 0xb4, 0x43, + 0x23, 0x3c, 0x5a, 0x16, 0xf9, 0xdd, 0x8d, 0x94, 0x63, 0x00, 0xc2, 0xe8, 0xe2, 0xe2, 0x7e, 0x84, 0x33, 0xfa, 0x8b, + 0x86, 0xda, 0xdd, 0xc9, 0x03, 0x46, 0x5b, 0x11, 0xfe, 0x99, 0x16, 0xfa, 0xe3, 0x52, 0xb9, 0x81, 0xb6, 0x20, 0x45, + 0x66, 0xef, 0x40, 0xcd, 0x1f, 0x8d, 0x3b, 0xe7, 0x0f, 0xda, 0x2c, 0xc2, 0xd9, 0xf5, 0x6b, 0xe8, 0xed, 0xfe, 0xa4, + 0xdb, 0x82, 0x0f, 0x01, 0x72, 0x29, 0x2b, 0xa0, 0x91, 0xf3, 0xb3, 0x07, 0x5d, 0x36, 0x36, 0x89, 0x8a, 0xe7, 0x5f, + 0xcc, 0xec, 0x2f, 0x60, 0x3e, 0x59, 0xc1, 0xe7, 0x4a, 0x8a, 0x34, 0x1a, 0x67, 0xed, 0xb3, 0x53, 0x48, 0xb8, 0xa3, + 0xc2, 0x03, 0xe7, 0x16, 0xaa, 0x5e, 0x8c, 0x22, 0x7c, 0x6b, 0x53, 0x2f, 0x46, 0xe6, 0x63, 0xfa, 0xee, 0x17, 0xf1, + 0x66, 0x9c, 0x46, 0xa3, 0x8b, 0x8b, 0xf3, 0x16, 0x24, 0xfc, 0x46, 0xef, 0xd2, 0x88, 0x3e, 0x80, 0xff, 0x20, 0xfb, + 0xe3, 0x33, 0xe8, 0x10, 0x46, 0x78, 0x3b, 0xfd, 0x18, 0xe6, 0x7c, 0x99, 0xd1, 0x2f, 0x3c, 0x8d, 0x46, 0xe3, 0xd1, + 0xfd, 0x73, 0xa8, 0x37, 0xa7, 0xd3, 0x67, 0x9a, 0x42, 0xbb, 0xad, 0x96, 0x69, 0xf9, 0x1d, 0xff, 0xca, 0x4c, 0xf5, + 0x6e, 0xf7, 0x7c, 0xd4, 0x81, 0x11, 0x5c, 0x83, 0x42, 0x05, 0xc6, 0x73, 0x91, 0x99, 0x06, 0xaf, 0xb3, 0xa7, 0xe3, + 0x34, 0x7a, 0xf0, 0xe0, 0xb4, 0x93, 0x65, 0x11, 0xbe, 0xfd, 0x38, 0xb6, 0xb5, 0x4d, 0x9e, 0x02, 0xd8, 0xa7, 0x11, + 0x7b, 0xf0, 0xe0, 0xfc, 0x3e, 0x85, 0xef, 0xe7, 0xa6, 0xad, 0x8b, 0xc9, 0x28, 0xbb, 0x80, 0xb6, 0xde, 0xc3, 0x74, + 0xce, 0x2e, 0x4e, 0xc7, 0xa6, 0xaf, 0xf7, 0x66, 0xd4, 0x9d, 0xc9, 0xd9, 0xe4, 0xcc, 0x64, 0x9a, 0xa1, 0x96, 0x9f, + 0xbf, 0xb2, 0x34, 0xca, 0xd8, 0xb8, 0x1d, 0xe1, 0x5b, 0xb7, 0x70, 0x0f, 0xce, 0x5a, 0xad, 0xf1, 0x69, 0x84, 0xc7, + 0x0f, 0x17, 0x8b, 0xb7, 0x06, 0x82, 0xed, 0xb3, 0x07, 0xf6, 0x5b, 0x7d, 0xb9, 0x83, 0xa6, 0x47, 0x06, 0x68, 0x63, + 0x3e, 0x37, 0x2d, 0x9f, 0x3f, 0x80, 0xff, 0xcc, 0xb7, 0x69, 0xba, 0xfc, 0x96, 0xe3, 0xa9, 0x5d, 0x94, 0x36, 0x7b, + 0xd0, 0x82, 0x1a, 0x13, 0xfe, 0x71, 0x54, 0x70, 0x40, 0xa3, 0x51, 0x07, 0xfe, 0x2f, 0xc2, 0x93, 0xfc, 0xfa, 0xb5, + 0xc3, 0xd9, 0xc9, 0x84, 0x4e, 0x5a, 0x11, 0x9e, 0xc8, 0x8f, 0x4a, 0xff, 0xf6, 0x50, 0xa4, 0x51, 0xa7, 0x73, 0x31, + 0x32, 0x65, 0x96, 0x3f, 0x2b, 0x6e, 0xf0, 0xb8, 0x65, 0x5a, 0x99, 0xd2, 0xb7, 0x6a, 0x74, 0x2d, 0x61, 0x25, 0xe1, + 0xbf, 0x08, 0x4f, 0x41, 0x0b, 0xe7, 0x5a, 0xb9, 0xb0, 0xdb, 0x61, 0xfa, 0xce, 0xa0, 0xe6, 0xf8, 0x3e, 0xc0, 0xcb, + 0x2f, 0xe3, 0x98, 0xd2, 0x6e, 0xa7, 0x15, 0x61, 0x33, 0xea, 0x8b, 0x16, 0xfc, 0x17, 0x61, 0x0b, 0x39, 0x03, 0xd7, + 0xe9, 0xc7, 0x67, 0x2f, 0x6f, 0xd2, 0x88, 0x8e, 0x27, 0x13, 0x58, 0x12, 0x33, 0x19, 0x5f, 0x6c, 0x26, 0x05, 0xbb, + 0xfb, 0xe5, 0xc6, 0x6d, 0x17, 0x93, 0xa0, 0x1d, 0x74, 0xce, 0x1f, 0x8c, 0xce, 0x22, 0xfc, 0x76, 0xcc, 0xa9, 0x80, + 0x55, 0xca, 0xc6, 0xdd, 0xac, 0x9b, 0x99, 0x84, 0xa9, 0x4c, 0xa3, 0x33, 0x58, 0xf2, 0x4e, 0x84, 0xf9, 0xd7, 0xeb, + 0x3b, 0x8b, 0x6e, 0x50, 0xdb, 0x21, 0xc8, 0xa4, 0xc5, 0xce, 0x2f, 0xb2, 0x08, 0xe7, 0xf4, 0xeb, 0xb3, 0x5f, 0x8a, + 0x34, 0x62, 0xe7, 0xec, 0x7c, 0x42, 0xfd, 0xf7, 0x3f, 0xd5, 0xcc, 0xd4, 0x68, 0x4d, 0xba, 0x90, 0x74, 0x23, 0xcc, + 0x58, 0xef, 0x67, 0x13, 0x83, 0x21, 0xaf, 0xe6, 0x52, 0x64, 0x4f, 0x27, 0x13, 0x69, 0xb1, 0x98, 0xc2, 0x26, 0xfc, + 0x1d, 0xa0, 0x4d, 0xc7, 0xe3, 0x0b, 0x76, 0x1e, 0xe1, 0xdf, 0xed, 0x2e, 0x71, 0x13, 0xf8, 0xdd, 0x62, 0x36, 0x73, + 0xbb, 0xfd, 0x77, 0x0b, 0x14, 0x98, 0xef, 0x84, 0x4e, 0xe8, 0xb8, 0x13, 0xe1, 0xdf, 0x0d, 0x5c, 0xc6, 0xa7, 0xf0, + 0x1f, 0x14, 0x80, 0xce, 0x1e, 0xb4, 0x18, 0x7b, 0xd0, 0x32, 0x5f, 0x61, 0x9e, 0x9b, 0xf9, 0xe8, 0x3c, 0x6b, 0x47, + 0xf8, 0x77, 0x87, 0x8e, 0x93, 0x09, 0x6d, 0x01, 0x3a, 0xfe, 0xee, 0xd0, 0xb1, 0xd3, 0x1a, 0x75, 0xa8, 0xf9, 0xb6, + 0x58, 0x73, 0x71, 0x3f, 0x63, 0x30, 0xb9, 0xdf, 0x2d, 0x42, 0xde, 0xbf, 0x7f, 0x71, 0xf1, 0xe0, 0x01, 0x7c, 0x9a, + 0xb6, 0xcb, 0x4f, 0xa5, 0x1f, 0xe6, 0x06, 0xc9, 0x5a, 0xd9, 0x19, 0xd0, 0xc9, 0xdf, 0xcd, 0x18, 0x27, 0x93, 0x09, + 0x6b, 0x45, 0x38, 0xe7, 0x73, 0x66, 0x31, 0xc1, 0xfe, 0x36, 0x1d, 0x9d, 0x76, 0xb2, 0xf1, 0x69, 0x27, 0xc2, 0xf9, + 0xdb, 0x67, 0x66, 0x36, 0x2d, 0x98, 0xbd, 0xdf, 0x72, 0x1e, 0x6b, 0xe6, 0xf4, 0x0d, 0x0c, 0x12, 0x56, 0x1a, 0x2a, + 0x7f, 0x08, 0xe8, 0xe1, 0xf9, 0x79, 0x36, 0x86, 0x81, 0x7e, 0x80, 0x6e, 0x01, 0x8c, 0x1f, 0xec, 0xe6, 0x1b, 0xd1, + 0x6e, 0x17, 0xa6, 0xfb, 0x61, 0xb1, 0x2c, 0x16, 0xaf, 0xd2, 0xe8, 0xc1, 0xe9, 0xfd, 0xd6, 0x78, 0x14, 0xe1, 0x0f, + 0x6e, 0x82, 0xa7, 0xd9, 0xe8, 0xf4, 0x7e, 0x3b, 0xc2, 0x1f, 0xcc, 0x7e, 0xbb, 0x3f, 0x3a, 0xbf, 0x80, 0x73, 0xe3, + 0x83, 0x5a, 0x14, 0x6f, 0xa7, 0xa6, 0xc0, 0x84, 0x3e, 0x80, 0x66, 0x7f, 0x35, 0xbb, 0x71, 0xdc, 0x86, 0x8d, 0xfc, + 0xc1, 0x6c, 0x32, 0x83, 0x27, 0xf7, 0xdb, 0xdd, 0x8b, 0x6e, 0x84, 0xe7, 0x7c, 0x2c, 0x80, 0xc0, 0x9b, 0x8d, 0xf2, + 0xa0, 0xfd, 0xe0, 0x7e, 0x2b, 0xc2, 0xf3, 0xb7, 0x3a, 0xfb, 0x48, 0xe7, 0x86, 0x1a, 0x4f, 0x00, 0x66, 0x73, 0xae, + 0xf4, 0xdd, 0x1b, 0xe5, 0xe8, 0x31, 0x6b, 0x47, 0x78, 0x2e, 0xb3, 0x8c, 0xaa, 0xb7, 0x36, 0x61, 0xd4, 0x8d, 0xb0, + 0xa0, 0x5f, 0xe9, 0x67, 0xe9, 0x37, 0xd3, 0x98, 0xd1, 0xb1, 0x49, 0x33, 0x38, 0x1c, 0xe1, 0x77, 0x63, 0xb8, 0x8c, + 0x4c, 0xa3, 0xc9, 0x78, 0xd2, 0x05, 0xf0, 0x00, 0x01, 0xb2, 0xd8, 0x0d, 0xd0, 0x80, 0xaf, 0xf1, 0xa3, 0x51, 0x1a, + 0x9d, 0x8f, 0x2e, 0x58, 0xe7, 0x34, 0xc2, 0x25, 0x35, 0xa2, 0x5d, 0xc8, 0x37, 0x9f, 0x1f, 0xcd, 0x96, 0x3a, 0xb3, + 0x09, 0x06, 0x40, 0x63, 0x7a, 0xbf, 0x35, 0x3e, 0x8f, 0xf0, 0xe2, 0x35, 0xf3, 0x7b, 0x8c, 0x31, 0x76, 0x01, 0xb0, + 0x84, 0x24, 0x83, 0x40, 0x17, 0x93, 0xd1, 0x83, 0x0b, 0xf3, 0x0d, 0x60, 0xa0, 0x13, 0xc6, 0x00, 0x48, 0x8b, 0xd7, + 0xac, 0x04, 0xc4, 0x78, 0x74, 0xbf, 0x05, 0xf4, 0x65, 0x41, 0x17, 0xf4, 0x8e, 0xde, 0x3c, 0x5d, 0x98, 0x39, 0x4d, + 0xc6, 0xdd, 0x08, 0x2f, 0x9e, 0xff, 0xbc, 0x58, 0x4e, 0x26, 0x66, 0x42, 0x74, 0xf4, 0x20, 0xc2, 0x0b, 0x56, 0x2c, + 0x61, 0x8d, 0x2e, 0xba, 0xa7, 0x93, 0x08, 0x3b, 0x34, 0xcc, 0x5a, 0xd9, 0x08, 0x6e, 0x5b, 0x97, 0xf3, 0x34, 0x1a, + 0x8f, 0x69, 0x6b, 0x0c, 0x77, 0xaf, 0xf2, 0xe6, 0x97, 0xc2, 0xa2, 0x11, 0x33, 0xf8, 0xe0, 0xd6, 0x10, 0xe6, 0x0b, + 0xf0, 0xf8, 0x38, 0x62, 0x59, 0x46, 0x5d, 0xe2, 0xf9, 0xf9, 0xe9, 0x29, 0xe0, 0x9e, 0x9d, 0xa1, 0x45, 0x90, 0x37, + 0xea, 0x6e, 0x54, 0x48, 0x38, 0xba, 0x80, 0xa8, 0x02, 0x59, 0x7d, 0x73, 0xf7, 0xda, 0xd0, 0xd5, 0xf6, 0xf9, 0x03, + 0x58, 0x00, 0x45, 0xc7, 0xe3, 0x57, 0xf6, 0x70, 0xbb, 0x18, 0x9d, 0x75, 0xdb, 0xa7, 0x11, 0xf6, 0x1b, 0x81, 0x5e, + 0xb4, 0xee, 0x77, 0xa0, 0x84, 0x18, 0xdf, 0xd9, 0x12, 0x93, 0x33, 0x7a, 0x76, 0xde, 0x8a, 0xb0, 0xdf, 0x1a, 0xec, + 0x62, 0xd4, 0xbd, 0x0f, 0x9f, 0x6a, 0xc6, 0xf2, 0xdc, 0xe0, 0x77, 0x17, 0xe0, 0xa2, 0xf8, 0x33, 0x41, 0xd3, 0x88, + 0xb6, 0xba, 0x9d, 0xce, 0x18, 0x3e, 0xf3, 0xaf, 0xac, 0x48, 0xa3, 0xac, 0x05, 0xff, 0x45, 0x38, 0xd8, 0x49, 0x6c, + 0x14, 0x61, 0x83, 0x77, 0xe7, 0xb4, 0x6b, 0xf6, 0xbe, 0xdb, 0x55, 0xad, 0x8b, 0x16, 0x6c, 0x58, 0xb7, 0xa9, 0xdc, + 0x97, 0x12, 0xf2, 0xc6, 0x91, 0x58, 0x1a, 0xe1, 0x00, 0x41, 0x27, 0xf7, 0x27, 0x11, 0xf6, 0x3b, 0xee, 0xec, 0xfc, + 0xa2, 0x03, 0xa4, 0x4c, 0x03, 0xa1, 0x18, 0x77, 0x46, 0x67, 0x40, 0x9a, 0x34, 0x7b, 0x6d, 0xf1, 0x24, 0xc2, 0xfa, + 0xa9, 0xd2, 0xaf, 0xd2, 0x68, 0x7c, 0x31, 0x9a, 0x8c, 0x2f, 0x22, 0xac, 0xe5, 0x9c, 0x6a, 0x69, 0x28, 0xe0, 0xe9, + 0xd9, 0xfd, 0x08, 0x1b, 0x34, 0x6f, 0xb1, 0xd6, 0xb8, 0x15, 0x61, 0x77, 0x94, 0x30, 0x76, 0xd1, 0x81, 0x69, 0xfd, + 0xf4, 0x5c, 0x03, 0x2e, 0x8f, 0xd9, 0xe8, 0x34, 0xc2, 0x25, 0xbd, 0x37, 0x84, 0x08, 0xbe, 0xd4, 0x5c, 0x7e, 0x71, + 0xac, 0x07, 0x90, 0x3a, 0xbf, 0xe1, 0x61, 0x19, 0x5e, 0xde, 0x58, 0x34, 0xa2, 0x66, 0x8b, 0x07, 0xb7, 0xd1, 0x4f, + 0x68, 0xec, 0xd9, 0x76, 0x4e, 0x56, 0x1b, 0x5c, 0x06, 0x79, 0xfd, 0xc2, 0xee, 0x54, 0x2c, 0x95, 0xe1, 0x64, 0x83, + 0x14, 0xa5, 0x90, 0x77, 0x6b, 0x70, 0x9e, 0xab, 0x20, 0x48, 0x0a, 0xd2, 0xea, 0x89, 0x4b, 0xef, 0x4d, 0xdb, 0x13, + 0x10, 0xfa, 0x01, 0xd2, 0x0b, 0x42, 0x89, 0x86, 0x08, 0x39, 0x56, 0x98, 0xf4, 0x4e, 0x06, 0x46, 0xa6, 0x94, 0xd6, + 0x6d, 0x81, 0x12, 0xea, 0x63, 0xe3, 0xc7, 0x12, 0x2b, 0x88, 0x1e, 0x85, 0x7a, 0x92, 0x98, 0x48, 0xd7, 0x2f, 0x84, + 0x8e, 0xa5, 0x1a, 0x14, 0x43, 0xdc, 0x3e, 0x47, 0x18, 0x62, 0x48, 0x90, 0x81, 0xbc, 0xba, 0x6a, 0x9f, 0x1f, 0x19, + 0xa1, 0xef, 0xea, 0xea, 0xc2, 0xfe, 0x80, 0x7f, 0x87, 0x55, 0xdc, 0x6e, 0x18, 0xdf, 0x07, 0x56, 0xcd, 0xf1, 0x9d, + 0xe1, 0xaf, 0x3f, 0xb0, 0xf5, 0x3a, 0xfe, 0xc0, 0x08, 0xcc, 0x18, 0x7f, 0x60, 0x89, 0xb9, 0x23, 0xb1, 0x1e, 0x42, + 0x64, 0x00, 0x9a, 0xb3, 0x16, 0x86, 0x68, 0xf2, 0x9e, 0xf3, 0xfe, 0xc0, 0x06, 0xbc, 0xee, 0x5d, 0x5e, 0x85, 0x70, + 0x3e, 0x3a, 0x5a, 0x15, 0xa9, 0xb6, 0x62, 0x82, 0xb6, 0x62, 0x82, 0xb6, 0x62, 0x82, 0xae, 0x82, 0xe8, 0x9f, 0xf5, + 0x41, 0x4a, 0x31, 0xca, 0x16, 0xc7, 0x53, 0xbf, 0x04, 0xb5, 0x07, 0x68, 0x27, 0xfb, 0x95, 0xb2, 0xa3, 0xd4, 0x55, + 0xec, 0x55, 0x60, 0xec, 0x4d, 0x74, 0xda, 0x8e, 0x93, 0x7f, 0x47, 0xdd, 0xf1, 0xb6, 0x26, 0x96, 0xbd, 0xdc, 0x2b, + 0x96, 0xc1, 0x4a, 0x1a, 0xd1, 0xec, 0xd0, 0xc6, 0x23, 0xd1, 0x83, 0xfb, 0x46, 0x30, 0xab, 0x82, 0xe4, 0x35, 0x20, + 0xa9, 0x07, 0x52, 0xc8, 0x85, 0x91, 0xd2, 0x0a, 0x94, 0x8e, 0x75, 0x5c, 0x80, 0x86, 0xd2, 0x2b, 0x28, 0xcb, 0x58, + 0xae, 0x0d, 0x03, 0x10, 0x65, 0x65, 0x34, 0x2b, 0xab, 0x75, 0x41, 0x74, 0x01, 0x4d, 0x98, 0x91, 0x58, 0xa0, 0x01, + 0x61, 0x1a, 0x10, 0xae, 0x32, 0x88, 0x33, 0x2e, 0xfb, 0xcc, 0x64, 0x2b, 0x93, 0xad, 0xca, 0x6c, 0xe9, 0xb3, 0xad, + 0x90, 0x28, 0x4d, 0xb6, 0x2c, 0xb3, 0x41, 0x66, 0xc3, 0xd3, 0x54, 0xe1, 0x51, 0x2a, 0xad, 0xa8, 0x56, 0xc9, 0x56, + 0xcf, 0x68, 0xa8, 0xcd, 0x3d, 0x3a, 0x8a, 0x4b, 0x39, 0xc9, 0xa8, 0x89, 0xef, 0xad, 0x78, 0x52, 0x18, 0x19, 0x88, + 0x27, 0x53, 0xf7, 0x77, 0xb4, 0xd9, 0x96, 0x95, 0x8a, 0xe9, 0xe8, 0x1b, 0x25, 0xd1, 0x9f, 0x5e, 0x89, 0xfa, 0x81, + 0x9b, 0x28, 0x40, 0x97, 0x24, 0x69, 0xb5, 0x4e, 0xdb, 0xa7, 0xad, 0x8b, 0x3e, 0x3f, 0x6e, 0x77, 0x92, 0x07, 0x9d, + 0xd4, 0x28, 0x22, 0x16, 0xf2, 0x06, 0x14, 0x30, 0x27, 0x9d, 0xe4, 0x0c, 0x1d, 0xb7, 0x93, 0x56, 0xb7, 0xdb, 0x84, + 0x7f, 0xf0, 0x23, 0x5d, 0x56, 0x3b, 0x6b, 0x9d, 0x75, 0xfb, 0xfc, 0x64, 0xab, 0x52, 0xcc, 0x1b, 0x50, 0x10, 0x9d, + 0x98, 0x4a, 0x18, 0xea, 0x57, 0xcb, 0xfb, 0x6a, 0x47, 0xcf, 0xf3, 0x48, 0xc7, 0xd2, 0xaa, 0xe2, 0x00, 0xaa, 0xfe, + 0x6b, 0x6a, 0x80, 0xe8, 0xbf, 0x46, 0x65, 0xa4, 0xde, 0x55, 0x01, 0xa2, 0xf6, 0x07, 0x1e, 0x8b, 0x06, 0x3b, 0x8e, + 0x6d, 0xbe, 0x86, 0xba, 0x4d, 0x88, 0x9e, 0x87, 0xa7, 0x2e, 0x57, 0x85, 0xb9, 0x53, 0x84, 0x9a, 0x0a, 0x72, 0x47, + 0x2e, 0x57, 0x86, 0xb9, 0x23, 0x84, 0x9a, 0x12, 0x72, 0x69, 0xca, 0x13, 0x0a, 0x39, 0x3a, 0xa1, 0x4d, 0x03, 0xc9, + 0x6a, 0x51, 0x9e, 0x33, 0x3f, 0x6c, 0x3e, 0x81, 0xe5, 0x31, 0x04, 0xc5, 0x09, 0xd2, 0x02, 0x5e, 0x58, 0x29, 0xb5, + 0x39, 0x2d, 0x5c, 0xaa, 0x71, 0x20, 0xa3, 0x01, 0xff, 0x1c, 0x33, 0xf3, 0xec, 0x46, 0xab, 0x7f, 0x7a, 0xde, 0x4a, + 0xdb, 0xe0, 0x2a, 0x0e, 0xb2, 0xb6, 0xb0, 0xb2, 0xb6, 0xf0, 0xb2, 0xb6, 0xf0, 0xb2, 0x36, 0x08, 0xf0, 0x41, 0xdf, + 0xff, 0x94, 0x35, 0xf3, 0x1b, 0x5e, 0xda, 0xf2, 0x58, 0x63, 0x8d, 0x58, 0xaf, 0xd7, 0xab, 0x0d, 0x58, 0x5a, 0x95, + 0x35, 0x0a, 0x55, 0xa9, 0x3f, 0x57, 0x45, 0xda, 0xc2, 0xd3, 0x14, 0xb4, 0xdc, 0x2d, 0x4c, 0xcd, 0xe6, 0xf6, 0x54, + 0x61, 0x3b, 0x8a, 0x4f, 0xdf, 0xab, 0x93, 0xaf, 0xc8, 0xa9, 0xd1, 0x1e, 0xaf, 0x8a, 0x94, 0x5b, 0x9a, 0xc1, 0x2d, + 0xcd, 0xe0, 0x96, 0x66, 0x40, 0x23, 0xb8, 0x2c, 0x6c, 0xca, 0x26, 0x94, 0xc0, 0x95, 0xc0, 0xe0, 0x74, 0x08, 0x41, + 0x0c, 0x63, 0x4d, 0xcc, 0xa8, 0xb7, 0x3a, 0x6f, 0x43, 0xd0, 0x36, 0x5b, 0x52, 0x27, 0xd4, 0xf8, 0xae, 0x97, 0x63, + 0xfe, 0xbb, 0x86, 0xf6, 0x09, 0xbc, 0xa8, 0xf3, 0x50, 0xc7, 0x2d, 0x30, 0x5d, 0x89, 0x8a, 0xa8, 0x6f, 0xc8, 0x42, + 0x6a, 0x74, 0x36, 0xce, 0x24, 0xfd, 0xcb, 0x96, 0x27, 0xb0, 0xa5, 0x04, 0xe1, 0x3b, 0x12, 0x5f, 0x58, 0x15, 0x9a, + 0xa0, 0xb4, 0xb8, 0x75, 0xe6, 0x72, 0xf6, 0x48, 0xe8, 0x81, 0xd9, 0xbc, 0x8f, 0x79, 0xd5, 0x17, 0xa4, 0x80, 0x98, + 0x8f, 0xa9, 0x49, 0x74, 0x51, 0x9b, 0xc1, 0x89, 0x99, 0x7c, 0xa5, 0xc6, 0xa5, 0xe7, 0x9d, 0xfd, 0xf3, 0x37, 0x0d, + 0x7c, 0x1e, 0x8b, 0xe9, 0xc8, 0xbb, 0x0a, 0x7f, 0x32, 0xb1, 0x8d, 0xc8, 0xe1, 0xa1, 0xb5, 0x68, 0x37, 0x5f, 0xdb, + 0x26, 0xed, 0x26, 0xd1, 0x64, 0xc3, 0x0e, 0xf5, 0x6b, 0xf4, 0x4f, 0xef, 0xb1, 0x57, 0x4c, 0x47, 0x28, 0xa0, 0xd9, + 0x06, 0xac, 0xb2, 0x02, 0x96, 0x72, 0xf5, 0x4a, 0x47, 0x4e, 0xe8, 0xdd, 0x8c, 0x79, 0x53, 0x4c, 0x47, 0x7b, 0x9f, + 0x5e, 0xb1, 0x3d, 0xf6, 0x9f, 0xd1, 0xa0, 0x07, 0xaf, 0xda, 0x9e, 0xb1, 0xdb, 0xef, 0xd5, 0xf9, 0xb2, 0xb7, 0x8e, + 0xca, 0xbf, 0x57, 0xe7, 0xc5, 0xbe, 0x3a, 0x73, 0x7e, 0x1b, 0xfb, 0xbd, 0xa3, 0x03, 0x35, 0xb6, 0x31, 0x93, 0x9a, + 0x8e, 0x20, 0x56, 0x3e, 0xfc, 0xb5, 0x11, 0x6d, 0x7a, 0x9e, 0x84, 0xc3, 0x2a, 0xc8, 0x7e, 0xd2, 0x4d, 0x19, 0xa6, + 0xa4, 0x73, 0x5c, 0x98, 0x98, 0x36, 0x22, 0xa1, 0x4d, 0x95, 0x50, 0x9c, 0x93, 0x38, 0xa6, 0xc7, 0x19, 0x44, 0xe6, + 0x69, 0xf7, 0x69, 0x1a, 0xd3, 0x46, 0x86, 0x4e, 0xe2, 0x76, 0x83, 0x1e, 0x67, 0x08, 0x35, 0xda, 0xa0, 0x33, 0x95, + 0xa4, 0xdd, 0xcc, 0x21, 0x56, 0xa7, 0x21, 0xc5, 0xf9, 0xb1, 0x48, 0x8a, 0x86, 0x3c, 0x56, 0x49, 0xd1, 0x48, 0xba, + 0x58, 0x24, 0xd3, 0x32, 0x79, 0x6a, 0x92, 0xa7, 0x36, 0x79, 0x54, 0x26, 0x8f, 0x4c, 0xf2, 0xc8, 0x26, 0x53, 0x52, + 0x1c, 0x8b, 0x84, 0x36, 0xe2, 0x76, 0xb3, 0x40, 0xc7, 0x30, 0x02, 0x3f, 0x7a, 0x22, 0xc2, 0x10, 0xe9, 0x1b, 0x63, + 0x63, 0xb4, 0x90, 0xb9, 0x0b, 0x5a, 0x5a, 0x01, 0xa9, 0x74, 0xfc, 0x82, 0x3a, 0xaf, 0x02, 0x30, 0x61, 0x6d, 0xff, + 0xf8, 0x90, 0x7c, 0x9b, 0x2c, 0x97, 0x22, 0x70, 0x6c, 0x03, 0x5b, 0xfc, 0x2f, 0xce, 0x9d, 0x07, 0xa0, 0xba, 0xa1, + 0xf9, 0x62, 0x46, 0x77, 0xbc, 0x87, 0x8b, 0xe9, 0xc8, 0xed, 0xac, 0xb2, 0x19, 0x46, 0x0b, 0x1b, 0xea, 0xba, 0xee, + 0xe7, 0x09, 0xa0, 0xf6, 0xbe, 0xa5, 0x09, 0x35, 0x4a, 0x72, 0x5b, 0x63, 0x5a, 0xb0, 0x3b, 0x95, 0xd1, 0x9c, 0xc5, + 0xd5, 0x01, 0x5c, 0x0d, 0x93, 0x91, 0x27, 0xe0, 0x11, 0x50, 0x1c, 0x27, 0xa7, 0x0d, 0x9d, 0x4c, 0x8f, 0x93, 0xee, + 0x83, 0x86, 0x4e, 0x46, 0xc7, 0x49, 0xbb, 0x5d, 0xe1, 0x6c, 0x52, 0x10, 0x9d, 0x4c, 0x89, 0x06, 0x8d, 0xa1, 0x6d, + 0x54, 0x2e, 0x28, 0x98, 0xb8, 0xfd, 0x1b, 0xc3, 0x68, 0xb8, 0x61, 0x08, 0x36, 0xb5, 0x51, 0x3f, 0x77, 0xc6, 0x10, + 0x76, 0xd3, 0xe9, 0x76, 0x9b, 0x3a, 0x29, 0xb0, 0xb6, 0x2b, 0xd9, 0xd4, 0xc9, 0x14, 0x6b, 0xbb, 0x7c, 0x4d, 0x9d, + 0x8c, 0x6c, 0x53, 0x46, 0x07, 0xc8, 0x44, 0x00, 0xac, 0xe7, 0x2c, 0x80, 0x7c, 0xc7, 0x3b, 0xe9, 0x6c, 0x40, 0x6b, + 0xf8, 0xbd, 0x72, 0x4d, 0x5f, 0x50, 0x51, 0x0d, 0xa6, 0x4e, 0xec, 0x5b, 0x45, 0xdb, 0x55, 0x93, 0xec, 0x5f, 0x97, + 0x2d, 0x9b, 0x2d, 0xa4, 0xae, 0x17, 0x7c, 0x5a, 0xc3, 0x10, 0x57, 0xca, 0x1d, 0xdc, 0x9f, 0x29, 0x89, 0x21, 0xb6, + 0x9f, 0x39, 0x85, 0x38, 0xf1, 0x7a, 0x64, 0x48, 0xe2, 0x8d, 0xc6, 0x06, 0xc5, 0xc1, 0x79, 0xfb, 0x34, 0xa4, 0xaa, + 0x3b, 0x01, 0xff, 0x08, 0x89, 0x96, 0xc2, 0x9a, 0x84, 0x8e, 0xa3, 0x8a, 0x16, 0xbf, 0x75, 0xda, 0xdd, 0xda, 0x01, + 0x71, 0x74, 0xb4, 0x7d, 0x5e, 0xf8, 0xa7, 0x17, 0x76, 0x9e, 0x5b, 0xa8, 0xec, 0x09, 0xfd, 0x83, 0x50, 0xd6, 0xd2, + 0x98, 0x07, 0x88, 0xe2, 0x43, 0x6f, 0xdd, 0x37, 0x14, 0x7e, 0x50, 0xc5, 0x1d, 0x74, 0x39, 0xcd, 0x73, 0x93, 0x61, + 0xfa, 0x1a, 0x06, 0x63, 0x7b, 0x13, 0x4e, 0xa8, 0xb4, 0x95, 0xfc, 0x97, 0x1d, 0x07, 0x9d, 0xb8, 0x07, 0x6b, 0xc2, + 0x46, 0x3f, 0x87, 0x96, 0xc9, 0x15, 0x6c, 0x9c, 0x4f, 0xfa, 0x7a, 0x5d, 0x7b, 0x9e, 0xc8, 0x3e, 0x82, 0x83, 0x8e, + 0x8e, 0xb8, 0x7a, 0x06, 0xc6, 0xd4, 0x2c, 0x6e, 0x84, 0x87, 0xef, 0x5f, 0xb5, 0xd3, 0xfa, 0xb3, 0x39, 0x57, 0xd3, + 0xe0, 0xa0, 0x7b, 0x58, 0xcb, 0xdf, 0xbb, 0x12, 0x7d, 0x9d, 0x72, 0xb7, 0xd6, 0x8f, 0x2a, 0x53, 0xf5, 0x9d, 0x87, + 0xb2, 0x8e, 0x8e, 0x78, 0x15, 0xae, 0x2a, 0xfa, 0x21, 0x42, 0x7d, 0x23, 0x83, 0x3c, 0xcb, 0x25, 0x85, 0x1b, 0x51, + 0xb8, 0x62, 0x48, 0x1b, 0xfc, 0x44, 0xe3, 0x9f, 0xe5, 0xff, 0xa7, 0x46, 0x8e, 0x75, 0xda, 0xe0, 0x15, 0x4a, 0xbd, + 0x08, 0x59, 0xa1, 0x2a, 0x50, 0xa4, 0x81, 0x74, 0x68, 0x79, 0x8e, 0xca, 0xc3, 0x9c, 0x2e, 0x16, 0xf9, 0x9d, 0x79, 0x2b, 0x2c, 0xe0, 0xa8, 0xaa, 0x8b, 0x26, 0x17, 0xa5, 0x0f, 0x17, 0xc0, 0xd3, 0x03, 0xee, 0x21, 0xe3, 0x65, 0x5b, - 0x5e, 0x6e, 0x0b, 0x04, 0x92, 0x99, 0x22, 0xb2, 0xd9, 0xee, 0xaa, 0x4b, 0x90, 0xcb, 0x9a, 0x4d, 0xa4, 0x5d, 0xf0, - 0x72, 0xcc, 0x41, 0x26, 0x53, 0xd6, 0x93, 0x76, 0xcf, 0x16, 0x04, 0xc9, 0x4d, 0x1a, 0x91, 0x6d, 0x77, 0x29, 0x3e, - 0x8e, 0x01, 0x8d, 0x90, 0x15, 0xf8, 0x42, 0x61, 0x91, 0x03, 0xd7, 0x59, 0xf8, 0x8e, 0xbf, 0xd1, 0x52, 0xd1, 0x57, - 0x83, 0x01, 0x2e, 0xcc, 0xf3, 0x18, 0xe5, 0x7c, 0x0a, 0x15, 0x3c, 0xb7, 0x14, 0x88, 0x28, 0x7c, 0xb5, 0xda, 0x87, - 0xd7, 0x8c, 0x5c, 0x9b, 0xe0, 0x7a, 0xeb, 0x7e, 0x56, 0x2f, 0x97, 0xc0, 0x38, 0x18, 0x69, 0x99, 0x8b, 0x42, 0x27, - 0x6f, 0xb2, 0x0b, 0xd1, 0x6d, 0x34, 0x98, 0x09, 0x34, 0x45, 0x20, 0xaa, 0x1c, 0xf8, 0x45, 0xc2, 0x1f, 0x1b, 0x3b, - 0x4a, 0x31, 0x1b, 0x81, 0x0f, 0x42, 0x83, 0xd7, 0x12, 0x56, 0x2b, 0x65, 0x23, 0xbc, 0x98, 0x1c, 0x1b, 0xeb, 0xa5, - 0xec, 0xa7, 0x0c, 0x25, 0x5b, 0x99, 0x71, 0x70, 0xb7, 0xd5, 0xdf, 0x56, 0xfb, 0x79, 0x8f, 0xdb, 0x6b, 0x3c, 0x6e, - 0xe2, 0x26, 0x18, 0x40, 0x2d, 0x37, 0x36, 0xb8, 0xb5, 0xf3, 0x8f, 0xad, 0x51, 0x32, 0xdb, 0x84, 0xa0, 0x28, 0xe3, - 0x04, 0xd8, 0x9b, 0x5b, 0x1f, 0x37, 0x51, 0x99, 0x39, 0x29, 0xa4, 0xfb, 0x20, 0x47, 0x0f, 0x08, 0x74, 0x6e, 0x7f, - 0x56, 0x74, 0xa1, 0x92, 0x89, 0xcb, 0x31, 0xfe, 0x12, 0xdc, 0xe6, 0xf5, 0xa3, 0xeb, 0x6b, 0xb3, 0xc9, 0xaf, 0xaf, - 0x23, 0x1c, 0x1a, 0xd7, 0x47, 0x01, 0x2f, 0x18, 0x0d, 0xca, 0xd0, 0x5a, 0x66, 0xe3, 0x37, 0xdb, 0x55, 0x63, 0x8f, - 0x68, 0x85, 0x77, 0xb0, 0x3c, 0xa6, 0xf1, 0x2d, 0x67, 0xd4, 0x3e, 0x07, 0x78, 0xb3, 0x3e, 0x1f, 0x74, 0xdf, 0xc4, - 0x0a, 0x1d, 0x1c, 0xbc, 0x89, 0x25, 0xea, 0x5d, 0x31, 0x73, 0xe7, 0x06, 0xde, 0xe8, 0x7d, 0x6e, 0x86, 0x2f, 0x03, - 0x04, 0xb8, 0x62, 0x9b, 0x92, 0xcd, 0x5b, 0x13, 0xfb, 0x23, 0x85, 0xd8, 0xe2, 0x10, 0xe1, 0xd8, 0x81, 0x04, 0x7a, - 0x7d, 0x13, 0x42, 0xbb, 0xcb, 0x08, 0x03, 0x16, 0xbe, 0xf4, 0x15, 0x64, 0xc9, 0x8c, 0x15, 0x13, 0x56, 0xac, 0x56, - 0x8f, 0xa8, 0xf5, 0xff, 0xdb, 0x08, 0x55, 0xa9, 0xba, 0x8d, 0x06, 0x35, 0xe3, 0x07, 0xf1, 0x81, 0x0e, 0xf0, 0xfe, - 0x9b, 0xb8, 0x40, 0x08, 0x2c, 0x8c, 0xb8, 0x58, 0x78, 0x5f, 0xb7, 0xac, 0xb6, 0x2e, 0x05, 0x2a, 0x1b, 0xc9, 0x49, - 0x0b, 0x4f, 0x49, 0x56, 0xae, 0xd1, 0xc5, 0xb4, 0xdb, 0x68, 0xe4, 0x48, 0xc6, 0x59, 0x3f, 0x1f, 0x60, 0x8e, 0x0b, - 0xb8, 0x4c, 0xdd, 0x5e, 0x87, 0x39, 0xab, 0x51, 0x2e, 0x37, 0xdf, 0xa5, 0x1d, 0x6b, 0xfa, 0x9e, 0xae, 0x03, 0x60, - 0xbc, 0xa7, 0x01, 0x91, 0xd8, 0x05, 0x64, 0x61, 0x81, 0xac, 0x3c, 0x90, 0x85, 0x01, 0xb2, 0x42, 0xbd, 0x39, 0x04, - 0x6d, 0x52, 0x28, 0xdd, 0xa2, 0xe8, 0xf5, 0xf0, 0xa2, 0xce, 0x75, 0x05, 0x73, 0x13, 0xe1, 0xc2, 0x2d, 0x07, 0xb8, - 0xb1, 0x38, 0x6f, 0x48, 0x45, 0x96, 0x51, 0x64, 0x22, 0xed, 0xe2, 0x5b, 0xf3, 0x27, 0xb9, 0xc5, 0x77, 0xf6, 0xc7, - 0x5d, 0xa0, 0x4c, 0x7a, 0x5e, 0xd3, 0x36, 0x70, 0x17, 0x97, 0x2e, 0x4a, 0x22, 0x40, 0x6b, 0x17, 0x64, 0x51, 0xd4, - 0xdf, 0x9d, 0x53, 0x36, 0x1c, 0x86, 0x68, 0x10, 0x85, 0x45, 0x40, 0x3a, 0xff, 0xfa, 0x2b, 0x42, 0x3d, 0x01, 0xd1, - 0x8c, 0xdc, 0xc9, 0xd6, 0x6c, 0xa3, 0x46, 0x94, 0x44, 0x69, 0xec, 0x83, 0x65, 0xc0, 0xce, 0x88, 0xa2, 0xe0, 0xcd, - 0x99, 0x72, 0x18, 0x1f, 0x6a, 0xc3, 0x30, 0x83, 0xaa, 0xc2, 0x7f, 0x5c, 0x2e, 0x37, 0x83, 0x2d, 0x19, 0xa8, 0x0a, - 0x13, 0xe9, 0x06, 0xd9, 0x87, 0xd8, 0x18, 0x61, 0x07, 0x07, 0xac, 0x2f, 0x06, 0xc1, 0xcb, 0x6a, 0xd5, 0x75, 0xb8, - 0x0e, 0x17, 0x2e, 0xa6, 0x10, 0xed, 0x7e, 0xb5, 0xb2, 0x7f, 0xc9, 0x07, 0x23, 0xcd, 0xc0, 0x13, 0x79, 0xc1, 0x19, - 0x2b, 0x76, 0xcb, 0x62, 0x89, 0x96, 0xbf, 0x83, 0x65, 0x9f, 0x8b, 0x5d, 0xc8, 0xdd, 0x54, 0xdb, 0x1e, 0xea, 0x73, - 0xa3, 0x51, 0x08, 0x22, 0x07, 0x57, 0x47, 0x1a, 0x9e, 0xeb, 0x30, 0xaf, 0x16, 0x01, 0x38, 0x53, 0x65, 0x20, 0x57, - 0x38, 0x52, 0x12, 0xb0, 0xf4, 0x36, 0x74, 0x12, 0x7e, 0xd4, 0xa9, 0xa4, 0x63, 0x21, 0x01, 0x0a, 0x1c, 0x99, 0xcb, - 0x79, 0x13, 0xa8, 0x9f, 0xa1, 0x1d, 0x44, 0x2e, 0x30, 0xa1, 0xa9, 0xcb, 0x96, 0x2e, 0xa2, 0x56, 0x34, 0x93, 0x0b, - 0xc5, 0x16, 0x73, 0x38, 0xdf, 0xcb, 0xb4, 0x2c, 0xe7, 0xd9, 0x97, 0x7a, 0x0a, 0x18, 0x44, 0xde, 0xea, 0x19, 0x13, - 0x8b, 0xc8, 0xcd, 0xf3, 0x95, 0x15, 0xf7, 0xdf, 0xbc, 0xc0, 0xef, 0x49, 0xe7, 0xf0, 0x15, 0xfe, 0x48, 0xc9, 0xfb, - 0xc6, 0x2b, 0x3c, 0xe1, 0xc4, 0xf2, 0x06, 0xc9, 0x9b, 0xd7, 0x57, 0x2f, 0xde, 0xbd, 0x78, 0xff, 0xf4, 0xfa, 0xc5, - 0xab, 0x67, 0x2f, 0x5e, 0xbd, 0x78, 0xf7, 0x11, 0xff, 0x4d, 0xc9, 0xab, 0xa3, 0xf6, 0x79, 0x0b, 0x7f, 0x20, 0xaf, - 0x8e, 0x3a, 0xf8, 0x56, 0x93, 0x57, 0x47, 0x27, 0x38, 0x57, 0xe4, 0xd5, 0x61, 0xe7, 0xe8, 0x18, 0x2f, 0xb4, 0x6d, - 0x32, 0x97, 0x93, 0x76, 0x0b, 0xff, 0xed, 0xbe, 0x40, 0xbc, 0xaf, 0x66, 0x31, 0x61, 0x1b, 0xc6, 0x0f, 0xa6, 0x0c, - 0x1d, 0x2a, 0x63, 0x88, 0x72, 0x11, 0xa0, 0xd3, 0x54, 0x85, 0xe8, 0x64, 0x43, 0x49, 0x83, 0x0d, 0x23, 0xa0, 0x15, - 0x27, 0xae, 0x1d, 0x7e, 0xd4, 0x66, 0xc7, 0x40, 0x9f, 0x78, 0x29, 0x1c, 0x97, 0x2a, 0x9c, 0xb6, 0xd3, 0x62, 0x8c, - 0x73, 0x29, 0x8b, 0x78, 0x01, 0x8c, 0x80, 0xd1, 0x5a, 0xf0, 0xa3, 0x32, 0x66, 0x95, 0xb8, 0x20, 0xed, 0x5e, 0x3b, - 0x15, 0x17, 0xa4, 0xd3, 0xeb, 0xc0, 0x9f, 0xd3, 0xde, 0x69, 0xda, 0x6e, 0xa1, 0xc3, 0x60, 0x1c, 0x7f, 0xd4, 0xd0, - 0xba, 0x3f, 0xc0, 0xae, 0x0b, 0xf5, 0x77, 0xa1, 0xbd, 0x4a, 0x4f, 0x38, 0x75, 0x6c, 0xbb, 0x2b, 0x2e, 0x98, 0xd1, - 0xc3, 0xf2, 0x1f, 0x00, 0xb5, 0x8d, 0x5b, 0x4d, 0xb9, 0x71, 0xdc, 0x2f, 0x7e, 0x24, 0x50, 0x2d, 0x30, 0x4e, 0xcc, - 0x56, 0x2d, 0x04, 0x4c, 0xa3, 0xc9, 0x06, 0x73, 0xa0, 0x44, 0xc9, 0x42, 0xfb, 0xe0, 0xfe, 0xaa, 0x29, 0x51, 0x32, - 0x97, 0xf3, 0xb8, 0xa6, 0x6a, 0xf8, 0x35, 0x30, 0x73, 0xdc, 0xe7, 0xea, 0x15, 0x7d, 0x15, 0xd7, 0x78, 0x9e, 0x90, - 0xb5, 0x0b, 0xb7, 0xc5, 0x2f, 0xce, 0x8a, 0xa2, 0x06, 0xae, 0x12, 0xb0, 0x7e, 0x54, 0x4d, 0x7d, 0x01, 0xaf, 0x18, - 0xb2, 0x86, 0xbe, 0x24, 0x01, 0xf5, 0xfc, 0xa9, 0x34, 0xe3, 0x2a, 0x95, 0xd1, 0x5e, 0x11, 0x6d, 0xcc, 0x82, 0xbc, - 0x22, 0xfa, 0x42, 0x19, 0x20, 0x48, 0xc2, 0xfb, 0x62, 0x00, 0x07, 0xbe, 0x1d, 0xa0, 0x34, 0x74, 0x0e, 0xd4, 0x4a, - 0x95, 0x99, 0x90, 0xf9, 0x34, 0x21, 0x1a, 0x40, 0xf3, 0x54, 0xa9, 0xa0, 0xcc, 0x27, 0x96, 0x28, 0x18, 0xfa, 0x9f, - 0xe1, 0x06, 0x38, 0x8c, 0x0d, 0x2a, 0x06, 0xd9, 0xf7, 0x44, 0x3d, 0xbf, 0x7d, 0xde, 0x3a, 0x7a, 0x15, 0xe4, 0x8f, - 0x94, 0xb7, 0xf7, 0xf8, 0x1c, 0x50, 0x72, 0x1b, 0x54, 0xac, 0x8d, 0x7d, 0x3c, 0xb8, 0x6e, 0x08, 0x90, 0x43, 0x8d, - 0x8e, 0xcc, 0x83, 0x8e, 0x5d, 0xa4, 0x0f, 0x49, 0xbb, 0x05, 0x41, 0xdc, 0x76, 0x50, 0xbe, 0x9f, 0x36, 0x60, 0xaa, - 0x93, 0xdb, 0x26, 0xd0, 0x6a, 0x78, 0xe3, 0xe9, 0xae, 0xc9, 0x93, 0x3b, 0xac, 0x02, 0x9c, 0x61, 0x87, 0xac, 0x21, - 0x0e, 0x05, 0x72, 0xc1, 0x6f, 0xed, 0x06, 0xd0, 0x54, 0x74, 0xec, 0x5b, 0x83, 0xde, 0x38, 0xea, 0xa2, 0x99, 0x9c, - 0x1e, 0xbe, 0x3a, 0x38, 0x88, 0x65, 0x83, 0xbc, 0x47, 0x78, 0x49, 0xc1, 0x66, 0x1b, 0x7c, 0xef, 0xb8, 0x65, 0xe2, - 0x53, 0x15, 0x50, 0xc7, 0x85, 0xaa, 0x1d, 0x6b, 0x55, 0x67, 0xe5, 0x6e, 0xf0, 0x63, 0xea, 0xa0, 0x46, 0x90, 0x66, - 0x47, 0xd7, 0x09, 0xa1, 0xfc, 0x5b, 0xcd, 0x51, 0x0e, 0xb6, 0x65, 0xe3, 0x23, 0x45, 0x3f, 0xbc, 0x6f, 0xbe, 0x0a, - 0xca, 0xd4, 0x4c, 0x93, 0xde, 0x37, 0xde, 0xa3, 0x1f, 0xde, 0x07, 0xae, 0x8e, 0xbc, 0x62, 0x4f, 0x3c, 0x37, 0xf2, - 0x9b, 0xe5, 0x4a, 0x7f, 0x03, 0xc9, 0xbe, 0x20, 0xbf, 0x01, 0x96, 0x53, 0xf2, 0x5b, 0x2c, 0x9b, 0x10, 0x02, 0x92, - 0xfc, 0x16, 0x17, 0xf0, 0x23, 0x27, 0xbf, 0xc5, 0x80, 0xed, 0x78, 0x6a, 0x7e, 0x14, 0x25, 0x30, 0xc0, 0xbd, 0x4e, - 0x5a, 0x2f, 0xbb, 0x62, 0xb5, 0x12, 0x07, 0x07, 0xd2, 0xfe, 0xa2, 0x97, 0xd9, 0xc1, 0x41, 0x7e, 0x31, 0x0d, 0x6c, - 0x6f, 0xf5, 0x2e, 0xfa, 0x62, 0x10, 0x0a, 0x07, 0xa6, 0x69, 0xbc, 0x86, 0x57, 0x35, 0xca, 0x0a, 0x0d, 0x34, 0x8f, - 0x3b, 0xf7, 0xcf, 0xce, 0x31, 0xfc, 0x7b, 0x3f, 0x28, 0xf8, 0x73, 0xc9, 0x77, 0x91, 0x36, 0x6b, 0x9e, 0x55, 0x75, - 0x2e, 0x03, 0x7c, 0xc6, 0x0c, 0x35, 0xc5, 0xc1, 0x01, 0xbf, 0x08, 0x70, 0x19, 0x33, 0xd4, 0x08, 0x2c, 0xf6, 0x1e, - 0x96, 0xf6, 0x64, 0x86, 0x6b, 0x82, 0xc7, 0x7d, 0x79, 0xbf, 0x18, 0x5c, 0x68, 0x47, 0x4d, 0xc2, 0x10, 0xe0, 0x8a, - 0xb4, 0xdc, 0x26, 0xeb, 0x8a, 0xa6, 0xba, 0x6c, 0x77, 0x91, 0x24, 0xaa, 0x21, 0x2e, 0x2f, 0xdb, 0x18, 0x54, 0xf2, - 0x3d, 0x45, 0x64, 0x2a, 0x88, 0x77, 0x53, 0x5c, 0xe6, 0x32, 0x55, 0x78, 0xca, 0x53, 0xe1, 0xe5, 0xec, 0xd7, 0xde, - 0x7a, 0xda, 0x38, 0x8e, 0x9a, 0x9e, 0x19, 0x16, 0x3d, 0x55, 0x3a, 0x3c, 0xc2, 0x26, 0x55, 0x03, 0x78, 0x3b, 0xb1, - 0xc4, 0x3c, 0x66, 0xbd, 0xfc, 0x18, 0xc4, 0xa6, 0x56, 0x8d, 0x36, 0x64, 0xc2, 0xe7, 0x3a, 0x55, 0x30, 0x50, 0x53, - 0xf8, 0x02, 0xc8, 0x54, 0x56, 0x19, 0x66, 0xfb, 0x86, 0xa1, 0x80, 0x80, 0x02, 0x97, 0x84, 0x05, 0x12, 0x3c, 0xdc, - 0x7e, 0x04, 0x84, 0xa3, 0x4e, 0x2e, 0xec, 0xe4, 0x2e, 0x14, 0x74, 0x27, 0x06, 0x17, 0xba, 0x8b, 0x44, 0xa3, 0xe1, - 0xb8, 0xed, 0x4b, 0x61, 0x06, 0xd1, 0x6c, 0x0f, 0x2e, 0x59, 0x17, 0xa9, 0x66, 0xb3, 0x34, 0x80, 0xbc, 0x6c, 0xad, - 0x56, 0xea, 0xc2, 0x37, 0xd2, 0xf3, 0xe7, 0xb8, 0xe1, 0xbb, 0xbc, 0xe0, 0xf9, 0x9b, 0x24, 0xfd, 0x08, 0xa8, 0x2a, - 0xf0, 0xd9, 0x72, 0x1e, 0xe1, 0xc8, 0x3c, 0xab, 0x07, 0x7f, 0xcd, 0x73, 0x68, 0x11, 0x8e, 0xdc, 0x4b, 0x7b, 0xd1, - 0xa0, 0x1a, 0x2c, 0xcf, 0xca, 0x20, 0xf1, 0x3c, 0xb9, 0x06, 0xc6, 0x41, 0x7f, 0x56, 0x68, 0x59, 0xfd, 0x4e, 0x72, - 0x17, 0x2e, 0x45, 0xf9, 0xc7, 0xdf, 0xdc, 0xa8, 0xd6, 0xbb, 0x1d, 0x54, 0x39, 0x8e, 0x7c, 0x55, 0x78, 0x44, 0xe1, - 0x3b, 0xaf, 0x4f, 0xb6, 0xdd, 0xa3, 0xe7, 0xcb, 0xb2, 0x07, 0xe0, 0xbc, 0xd7, 0x6b, 0x84, 0x7f, 0x93, 0x3b, 0x5f, - 0x40, 0x8e, 0xae, 0xa5, 0x78, 0x42, 0x35, 0x8d, 0x1a, 0x6f, 0x8c, 0xe1, 0x9b, 0x95, 0xb3, 0xba, 0xdf, 0x1a, 0x07, - 0xfb, 0xb7, 0xba, 0x87, 0x00, 0x16, 0xb5, 0xc7, 0x9a, 0xac, 0xec, 0x6b, 0xc2, 0x96, 0xc8, 0xc0, 0xf4, 0x6d, 0x07, - 0x3c, 0xfc, 0x18, 0x29, 0xb8, 0x55, 0x5b, 0x3e, 0x89, 0x42, 0x64, 0xd8, 0x9a, 0x33, 0x37, 0xa4, 0xd8, 0x3e, 0x8c, - 0xe3, 0xef, 0x1a, 0x85, 0x5c, 0xf7, 0x58, 0xd5, 0x89, 0x69, 0xd5, 0x8d, 0x91, 0x3a, 0xd8, 0x26, 0x0b, 0xce, 0xaa, - 0xde, 0x8d, 0x84, 0x52, 0xbd, 0x6b, 0x67, 0xde, 0x26, 0x6d, 0xb6, 0xcd, 0x63, 0xcf, 0xf6, 0xf5, 0x3b, 0x05, 0x86, - 0xbc, 0xfb, 0x65, 0xd0, 0xae, 0x4b, 0x38, 0x76, 0xe3, 0x00, 0xb2, 0x92, 0x5c, 0x2e, 0xdd, 0xcb, 0x74, 0xbc, 0x2f, - 0x07, 0xeb, 0xf2, 0x9d, 0xba, 0x00, 0x0f, 0xaa, 0x91, 0x8a, 0x2c, 0xe4, 0x0c, 0xfc, 0x23, 0x8f, 0x35, 0xfd, 0x10, - 0xff, 0x07, 0x0e, 0xf8, 0x0a, 0x49, 0x53, 0xab, 0x7e, 0x82, 0xf7, 0xa3, 0x40, 0xe1, 0x6d, 0xeb, 0xfe, 0x29, 0x43, - 0x47, 0xdd, 0xba, 0x4e, 0xc5, 0xfa, 0xc2, 0xd6, 0x15, 0x2b, 0x65, 0xe1, 0x80, 0x6a, 0xc5, 0x68, 0x9d, 0x3a, 0xbf, - 0x59, 0xf7, 0xe8, 0xd4, 0x43, 0x01, 0xbe, 0x31, 0x5c, 0x8a, 0x67, 0x05, 0x44, 0x11, 0x0b, 0xf5, 0x69, 0x3f, 0xcb, - 0xf0, 0x55, 0xe5, 0x3e, 0xdc, 0x13, 0x96, 0x3c, 0x67, 0xf9, 0x12, 0x38, 0x2c, 0x90, 0x02, 0x0a, 0xa5, 0xb0, 0x58, - 0xad, 0x62, 0x01, 0x81, 0x24, 0xfe, 0x74, 0xa1, 0x85, 0xdd, 0x1b, 0x22, 0x46, 0x7f, 0x07, 0x75, 0xb1, 0x57, 0x8f, - 0x18, 0x13, 0x56, 0x14, 0x5e, 0x3a, 0xa9, 0x2c, 0xe8, 0x6b, 0x57, 0x1f, 0xa2, 0x9a, 0x72, 0x2f, 0x36, 0xfa, 0xde, - 0x77, 0x7c, 0xc6, 0xe4, 0x02, 0x1e, 0x6f, 0xc2, 0x8c, 0x28, 0xa6, 0xfd, 0x37, 0x50, 0x10, 0x78, 0x01, 0x88, 0x87, - 0xf8, 0x08, 0x7c, 0x95, 0xa7, 0x75, 0x32, 0xf3, 0x4f, 0x82, 0x44, 0x26, 0x64, 0x67, 0xd4, 0x8b, 0xc0, 0x8b, 0x08, - 0x44, 0x28, 0x42, 0x22, 0x26, 0x46, 0x51, 0x2f, 0x32, 0x2e, 0x59, 0x11, 0x58, 0x8d, 0x81, 0x92, 0x3b, 0xc2, 0x73, - 0x55, 0x11, 0xb1, 0xb0, 0xa6, 0x0e, 0x2a, 0xb1, 0xd4, 0x98, 0x69, 0x1f, 0x75, 0x2a, 0x10, 0x16, 0xd9, 0xa6, 0xa0, - 0xac, 0x37, 0xd4, 0x05, 0x58, 0x12, 0x63, 0x7a, 0xcb, 0x93, 0x6b, 0xe0, 0xe6, 0xd8, 0xc8, 0x15, 0x5d, 0xf2, 0x2b, - 0x50, 0x4f, 0xa7, 0x05, 0xbe, 0x36, 0x0c, 0xdb, 0x28, 0xa5, 0x6b, 0xc2, 0x71, 0x46, 0x8a, 0x84, 0xde, 0x42, 0x6c, - 0x8d, 0x19, 0x17, 0x69, 0x8e, 0x67, 0xf4, 0x36, 0x9d, 0xe2, 0x19, 0x17, 0x4f, 0xec, 0xb2, 0xa7, 0x23, 0x48, 0xf2, - 0x1f, 0x8b, 0x35, 0x31, 0x4f, 0x83, 0xfd, 0xae, 0x58, 0xf1, 0x08, 0x78, 0x15, 0x15, 0xa3, 0xee, 0xc8, 0xd8, 0x94, - 0x73, 0x5d, 0x19, 0xaf, 0xbf, 0xd6, 0x31, 0xc5, 0x19, 0xce, 0x51, 0x92, 0x4b, 0xcc, 0x7a, 0x22, 0x7d, 0x0d, 0x71, - 0xb5, 0x33, 0x6c, 0x9f, 0x15, 0xe3, 0xb7, 0x2c, 0x7f, 0x26, 0x8b, 0xf7, 0x66, 0xcb, 0xe7, 0x08, 0x0a, 0x81, 0x8b, - 0x8a, 0x68, 0xc2, 0xed, 0xde, 0xa2, 0x27, 0xab, 0xa6, 0xe8, 0xad, 0x6d, 0xca, 0x0d, 0x71, 0x0a, 0x01, 0x89, 0x93, - 0x29, 0x6f, 0xb4, 0x31, 0xeb, 0xb5, 0xbe, 0xd3, 0xe8, 0x14, 0x95, 0x25, 0x11, 0x86, 0xb5, 0x6a, 0xaa, 0x54, 0x12, - 0xd1, 0x54, 0x4e, 0xc2, 0x5b, 0x1a, 0x60, 0xa7, 0x0a, 0x67, 0x72, 0x21, 0x74, 0x2a, 0x03, 0xbc, 0xa1, 0xd5, 0xe6, - 0x5a, 0xde, 0x5a, 0x88, 0x69, 0x7c, 0x67, 0x7f, 0x30, 0x7c, 0x6d, 0x54, 0xfc, 0x6f, 0xc1, 0xb0, 0x47, 0xa5, 0x02, - 0xe0, 0x07, 0x86, 0xb3, 0x00, 0x39, 0xcb, 0x4f, 0xde, 0x02, 0xf8, 0x2c, 0x0b, 0x79, 0x07, 0xa9, 0xcc, 0xa4, 0xde, - 0x41, 0x2a, 0x83, 0x54, 0xe3, 0x51, 0xbf, 0x2f, 0x2a, 0x65, 0x51, 0xd8, 0x20, 0x51, 0xb8, 0x54, 0x07, 0x4b, 0x22, - 0x12, 0x68, 0xd7, 0x88, 0x72, 0x33, 0x2e, 0x20, 0xb4, 0x22, 0x34, 0x6e, 0xbf, 0xe9, 0x2d, 0x7c, 0xdf, 0xd9, 0x7c, - 0xe6, 0xf3, 0xef, 0x6c, 0xbe, 0xe9, 0xc8, 0x63, 0x7c, 0xfd, 0xb6, 0xd3, 0x58, 0xc6, 0x4b, 0x87, 0xb5, 0x1f, 0xca, - 0x87, 0x6c, 0x5a, 0xe6, 0xc1, 0x70, 0xd2, 0xc6, 0x93, 0x00, 0x29, 0x9b, 0x15, 0x0f, 0xd7, 0xc1, 0xed, 0xd6, 0x61, - 0xcc, 0x9b, 0xa4, 0x8d, 0xd0, 0xa1, 0x13, 0xae, 0x44, 0x6c, 0x24, 0xa7, 0xc3, 0xf7, 0x47, 0x70, 0xf7, 0x32, 0x53, - 0x1b, 0xbe, 0x52, 0xb6, 0x5a, 0xb3, 0xdd, 0x3a, 0xe4, 0x3b, 0xab, 0x34, 0xda, 0x78, 0xc6, 0xc8, 0x12, 0x3c, 0xd0, - 0x68, 0x61, 0x55, 0x0d, 0xe0, 0xb2, 0xfa, 0x42, 0xfc, 0xb6, 0xa0, 0x23, 0xf3, 0x7d, 0x68, 0x53, 0x5e, 0x2f, 0xb4, - 0x4f, 0x6a, 0x72, 0x18, 0x44, 0x07, 0xb9, 0x92, 0x41, 0x4e, 0xcc, 0x8f, 0x48, 0x72, 0x8a, 0x2e, 0xda, 0xbd, 0xe4, - 0xf4, 0x90, 0x1f, 0xf2, 0x14, 0x78, 0xd8, 0xb8, 0xe9, 0x2b, 0x34, 0xdb, 0xbe, 0xce, 0xe3, 0xc5, 0x90, 0x67, 0xae, - 0xf9, 0xaa, 0x83, 0x32, 0xd5, 0xce, 0x11, 0xb2, 0x00, 0xc5, 0x7c, 0x2f, 0x41, 0x76, 0xbd, 0x9b, 0x43, 0x9e, 0x42, - 0x3f, 0x50, 0xab, 0x63, 0x6b, 0x95, 0x83, 0xfb, 0x6d, 0x01, 0x08, 0xe6, 0x3b, 0xaa, 0xcd, 0xc5, 0xa6, 0x37, 0xe3, - 0xaa, 0xb3, 0x43, 0x5e, 0x8d, 0x30, 0x2c, 0xb3, 0xdd, 0x9f, 0x9f, 0x5a, 0xd5, 0xe5, 0x61, 0x00, 0x91, 0xdf, 0x16, - 0x5c, 0x84, 0x9d, 0x86, 0xdd, 0xba, 0x9c, 0xb0, 0xd3, 0xfa, 0x2c, 0x83, 0x22, 0xdb, 0xbd, 0x6e, 0xcd, 0xb4, 0x3e, - 0xdb, 0x2b, 0x70, 0x24, 0x84, 0x49, 0x99, 0x95, 0xce, 0xe0, 0x0a, 0xfd, 0xf0, 0x03, 0x72, 0xad, 0xbf, 0x5e, 0x68, - 0x9f, 0x5f, 0x22, 0x02, 0x64, 0x57, 0x5d, 0x97, 0xd5, 0xa1, 0x8f, 0xb2, 0x89, 0x57, 0x87, 0x3c, 0x58, 0xb9, 0xa7, - 0xb7, 0x73, 0x99, 0x7a, 0x7c, 0xed, 0xb5, 0xd2, 0x2d, 0xe4, 0x04, 0xe2, 0xe1, 0xba, 0x0b, 0xcb, 0x82, 0x9c, 0xdd, - 0xdc, 0x42, 0xc9, 0x70, 0xe2, 0xbe, 0xf4, 0x07, 0x66, 0xaf, 0x1b, 0xf8, 0x45, 0x72, 0x0a, 0x53, 0xdf, 0xec, 0xe1, - 0xb0, 0x03, 0x7d, 0x18, 0x38, 0x6c, 0x36, 0xe8, 0x33, 0x2b, 0x88, 0x3c, 0xe6, 0x85, 0xc5, 0xb3, 0x4b, 0xd2, 0xee, - 0xf1, 0xd4, 0x6d, 0x26, 0x23, 0x1a, 0xb5, 0x9b, 0x3c, 0x98, 0x19, 0xe0, 0x97, 0x2b, 0x1b, 0x16, 0xf1, 0xeb, 0x14, - 0x40, 0xc9, 0x17, 0xab, 0xd6, 0xa7, 0x82, 0x57, 0xbd, 0xe1, 0x74, 0x33, 0xdd, 0xaf, 0x1b, 0xdc, 0xee, 0x7a, 0x78, - 0xc2, 0x43, 0x34, 0x16, 0xad, 0xfd, 0xc4, 0x27, 0xc0, 0x01, 0x25, 0xad, 0xfb, 0xa7, 0xe0, 0x42, 0x59, 0xc2, 0x72, - 0xbb, 0xdc, 0x6c, 0xab, 0x9c, 0x85, 0xa3, 0x2d, 0x19, 0x70, 0x07, 0x9b, 0x10, 0x85, 0x0e, 0x0e, 0x3b, 0x38, 0x69, - 0xb7, 0x3b, 0xa7, 0x38, 0x39, 0x39, 0x85, 0x81, 0x36, 0x92, 0xd3, 0xc3, 0x99, 0xb2, 0x00, 0x0c, 0x72, 0xd6, 0xae, - 0xdd, 0x47, 0x10, 0xb4, 0x2a, 0x14, 0xaf, 0xf9, 0x61, 0x1c, 0xb7, 0x93, 0xfb, 0xad, 0xf6, 0xe9, 0x79, 0x03, 0x00, - 0xd4, 0x74, 0x1f, 0xae, 0xc6, 0xeb, 0x85, 0xae, 0x57, 0x29, 0x11, 0xbe, 0x5e, 0xad, 0xe1, 0xab, 0x35, 0xda, 0xeb, - 0x6a, 0x0a, 0xbe, 0xaa, 0x13, 0xce, 0x6d, 0x11, 0xaf, 0xb4, 0x09, 0xb7, 0x45, 0x6c, 0x07, 0x12, 0x83, 0x74, 0x9e, - 0x9c, 0x76, 0x4e, 0x91, 0x1d, 0x8b, 0x76, 0xf8, 0x51, 0xee, 0x93, 0xad, 0x22, 0x0d, 0x0d, 0x48, 0x52, 0xce, 0x4e, - 0x2e, 0x40, 0xa2, 0xe6, 0xe4, 0xb2, 0xdd, 0x9c, 0xb1, 0xc4, 0x4f, 0xc0, 0xa4, 0xc2, 0x72, 0x96, 0xab, 0xe0, 0x92, - 0x02, 0x40, 0x5c, 0x80, 0x71, 0xd1, 0xfd, 0xd3, 0xde, 0xfd, 0xe4, 0xf4, 0xac, 0x63, 0x89, 0x1e, 0xbf, 0xe8, 0xd4, - 0xd2, 0xcc, 0xd4, 0x93, 0x53, 0x93, 0x06, 0x5d, 0x27, 0xf7, 0x4f, 0xa1, 0x8c, 0x4b, 0x09, 0x4b, 0x41, 0xb0, 0x8d, - 0xaa, 0x18, 0x44, 0xd8, 0x48, 0x6b, 0xb9, 0x67, 0xb5, 0xec, 0xf3, 0x93, 0xe3, 0xfb, 0xa7, 0x21, 0xd4, 0xca, 0x59, - 0x98, 0x85, 0x76, 0x13, 0xf1, 0xb3, 0x83, 0xa5, 0x45, 0x87, 0xc9, 0x69, 0xba, 0x35, 0x41, 0xbb, 0x69, 0x0e, 0x0d, - 0x0e, 0x04, 0x0a, 0xc7, 0xa7, 0xc2, 0xe9, 0x4b, 0x82, 0xfb, 0xb1, 0xca, 0xd0, 0x24, 0x54, 0x38, 0xfb, 0x7b, 0xca, - 0xe0, 0x3d, 0xcd, 0xf0, 0xaa, 0xf2, 0x31, 0x15, 0x5f, 0xa9, 0x7a, 0x43, 0x21, 0x82, 0x88, 0x18, 0x44, 0x2e, 0xbe, - 0x79, 0x3d, 0xf7, 0x27, 0x70, 0x11, 0x66, 0x02, 0x2e, 0x34, 0xbd, 0x12, 0xb4, 0xe2, 0x05, 0x86, 0xa1, 0x43, 0xad, - 0x19, 0x56, 0x8f, 0xa7, 0xce, 0xa4, 0x20, 0xd4, 0x6d, 0x3d, 0xe7, 0xdf, 0x2b, 0x97, 0x94, 0x57, 0xd9, 0xc9, 0x29, - 0x4a, 0xdc, 0x65, 0x79, 0xd2, 0x46, 0x49, 0x60, 0x42, 0xe2, 0x8e, 0xe4, 0x2c, 0x23, 0xfd, 0xe8, 0x36, 0xc2, 0xd1, - 0x5d, 0x84, 0x23, 0xeb, 0xc3, 0xfc, 0x01, 0xfc, 0xb8, 0x23, 0x1c, 0x59, 0x57, 0xe6, 0x08, 0x47, 0x9a, 0x09, 0x08, - 0x2c, 0x16, 0x0d, 0x70, 0x0e, 0xa5, 0x8d, 0x67, 0x75, 0x59, 0xfa, 0xb1, 0xff, 0x2a, 0x5d, 0xaf, 0x6d, 0x4a, 0x20, - 0x65, 0x4e, 0xcd, 0x0e, 0xb5, 0x0f, 0x63, 0x47, 0xd4, 0x33, 0xeb, 0x11, 0x06, 0x01, 0x84, 0xde, 0xf9, 0x87, 0xf5, - 0xaa, 0x98, 0x24, 0xec, 0x18, 0x56, 0x1a, 0x5c, 0xd1, 0xa3, 0xf0, 0x0c, 0x8b, 0xf0, 0x58, 0xf8, 0xc2, 0x20, 0x56, - 0xf8, 0xdf, 0xb9, 0x94, 0x73, 0xff, 0x5b, 0xcb, 0xf2, 0x17, 0x3c, 0xc7, 0xe2, 0x2c, 0x5a, 0xc0, 0x72, 0xcb, 0x86, - 0x40, 0x1a, 0xb2, 0xfa, 0x08, 0xae, 0xc7, 0x2e, 0x4c, 0x1d, 0x48, 0x84, 0xd7, 0x46, 0xa0, 0xf2, 0xf2, 0xe1, 0xb5, - 0x0d, 0x99, 0x64, 0x3e, 0x21, 0x66, 0x1a, 0x84, 0x45, 0x96, 0x70, 0xa1, 0x31, 0x29, 0x98, 0x52, 0x91, 0x8d, 0x25, - 0x18, 0x49, 0xe1, 0x1f, 0x87, 0xf4, 0x29, 0x63, 0x11, 0x99, 0x0e, 0xeb, 0xb3, 0xb5, 0xe2, 0x70, 0x2e, 0x0b, 0x95, - 0xda, 0x97, 0x62, 0x3c, 0x18, 0xe7, 0xe5, 0x33, 0x8c, 0x69, 0x9e, 0xad, 0xb1, 0xbd, 0xc3, 0x2e, 0x0b, 0xb9, 0x2b, - 0xed, 0xb0, 0x54, 0x96, 0xad, 0xbf, 0x35, 0x21, 0x55, 0x9b, 0x51, 0x30, 0xd1, 0x6a, 0x40, 0x55, 0xe0, 0x0e, 0x28, - 0x6c, 0x83, 0xd2, 0xa4, 0xcb, 0xb2, 0x64, 0xba, 0x2c, 0x97, 0xe1, 0xa4, 0xd5, 0x5a, 0xaf, 0x71, 0xc1, 0x4c, 0x20, - 0x97, 0x9d, 0x25, 0x20, 0x5f, 0x4d, 0xe5, 0x4d, 0x90, 0xab, 0xd2, 0x72, 0x96, 0x66, 0x89, 0xa2, 0xc0, 0x08, 0x36, - 0x5a, 0xe3, 0xaf, 0x5c, 0x71, 0x80, 0xa7, 0x9b, 0xdd, 0x50, 0xca, 0x9c, 0x51, 0x88, 0xa1, 0x16, 0x34, 0xb9, 0xc6, - 0x53, 0x3e, 0x62, 0xbb, 0xdb, 0x04, 0x33, 0xe6, 0x7f, 0xaf, 0x45, 0x8f, 0x40, 0x96, 0xdd, 0x33, 0xa8, 0x03, 0x8b, - 0xb8, 0x82, 0x0e, 0x42, 0x19, 0x7c, 0x14, 0xe2, 0x66, 0x4e, 0xef, 0xe4, 0x42, 0x03, 0x5c, 0x16, 0x5a, 0xbe, 0x71, - 0xe1, 0x10, 0xf6, 0x5b, 0xd8, 0x47, 0x46, 0x58, 0x42, 0xc8, 0x80, 0x16, 0xb6, 0x11, 0x31, 0x5a, 0xd8, 0x05, 0x2a, - 0x68, 0x61, 0x13, 0x9e, 0xa2, 0xb5, 0x2e, 0x63, 0x9b, 0x5d, 0x97, 0x4f, 0x6a, 0x56, 0x9b, 0x60, 0xe1, 0xa4, 0x43, - 0x4d, 0x74, 0x70, 0x7b, 0xc8, 0x08, 0x6f, 0xfc, 0x7c, 0xf5, 0xfa, 0x95, 0x8b, 0x5c, 0xcd, 0xc7, 0xe0, 0xb2, 0xe9, - 0x54, 0x63, 0xd7, 0xe6, 0x2d, 0xaa, 0xb8, 0x52, 0x94, 0x5a, 0xe1, 0x14, 0x5a, 0x7e, 0x21, 0x74, 0x9e, 0xd8, 0xcb, - 0x8b, 0x67, 0xb2, 0x98, 0x51, 0x7b, 0x63, 0x84, 0xaf, 0x95, 0x7b, 0x7c, 0xde, 0xbc, 0x6f, 0x53, 0x4d, 0xf2, 0xdd, - 0xe6, 0x55, 0xc4, 0x22, 0x33, 0xf2, 0x2b, 0x68, 0x03, 0x4c, 0xe5, 0xf2, 0xed, 0xe0, 0x82, 0xb8, 0xf8, 0xff, 0x01, - 0x79, 0x79, 0x6b, 0xa9, 0x4b, 0x14, 0x35, 0xb8, 0xc1, 0x4f, 0x56, 0xf0, 0x2c, 0xb8, 0x2e, 0x34, 0xec, 0x91, 0x13, - 0x2f, 0xa2, 0x56, 0x54, 0x7f, 0x7b, 0xd7, 0xa8, 0x12, 0x7c, 0xec, 0xd8, 0x24, 0x97, 0x20, 0x7a, 0x94, 0xcf, 0xfc, - 0x71, 0x10, 0x4d, 0xfc, 0xdd, 0xf3, 0x65, 0xdb, 0xd3, 0xd9, 0xbc, 0x52, 0x27, 0x96, 0x57, 0x26, 0xe0, 0xe1, 0x68, - 0x1f, 0xd2, 0x41, 0x38, 0x48, 0x64, 0xa5, 0xf6, 0xd0, 0xe7, 0xa2, 0x6e, 0x9c, 0x5f, 0xb4, 0x59, 0xf3, 0x64, 0xb5, - 0xca, 0x2f, 0xdb, 0xac, 0x7d, 0x6a, 0x9f, 0xdd, 0x8b, 0x54, 0x06, 0x34, 0x97, 0x8f, 0x79, 0x16, 0x81, 0x76, 0x76, - 0x9c, 0x99, 0x70, 0x0a, 0x3e, 0x50, 0x34, 0x59, 0xe8, 0xaa, 0x2f, 0x09, 0xc6, 0xa5, 0xc4, 0xea, 0xf1, 0x0b, 0xd4, - 0x6b, 0xa7, 0xdb, 0xae, 0xd2, 0xcd, 0xf6, 0x61, 0x70, 0xe1, 0x52, 0x20, 0xdc, 0x81, 0x90, 0x07, 0xa0, 0xdf, 0x5d, - 0x0a, 0x30, 0x0d, 0x02, 0x54, 0x56, 0x20, 0xd2, 0xf2, 0xd9, 0x62, 0xf6, 0xac, 0xa0, 0x66, 0x19, 0x9e, 0xf0, 0x09, - 0xd7, 0x2a, 0xa5, 0x20, 0xdd, 0xee, 0x4a, 0x5f, 0xef, 0x96, 0xa0, 0xb2, 0x5a, 0xfc, 0xdd, 0x44, 0xf3, 0xec, 0x8b, - 0x72, 0x0b, 0x87, 0xb0, 0x59, 0x59, 0x81, 0x33, 0xb4, 0xc6, 0xb9, 0x9c, 0xd0, 0x82, 0xeb, 0xe9, 0xec, 0xdf, 0x5a, - 0x1d, 0xd6, 0xd7, 0x03, 0x73, 0x61, 0x05, 0x20, 0xa1, 0x62, 0xb4, 0x5a, 0xf1, 0xa3, 0xef, 0xdf, 0x27, 0x79, 0x9f, - 0xf0, 0x36, 0xee, 0xe0, 0x63, 0x7c, 0x8a, 0xdb, 0x2d, 0xdc, 0x3e, 0x85, 0xab, 0xfb, 0x2c, 0x5f, 0x8c, 0x98, 0x8a, - 0xe1, 0xfd, 0x35, 0x7d, 0x99, 0x9c, 0x1f, 0x96, 0xaf, 0x0e, 0xe8, 0x22, 0x71, 0xe8, 0x12, 0x04, 0xbf, 0x77, 0x51, - 0x03, 0xa3, 0x28, 0x0c, 0x59, 0x37, 0x0e, 0x55, 0x27, 0xa5, 0x7e, 0xe1, 0xf2, 0xb8, 0x07, 0xf6, 0xdc, 0x76, 0x65, - 0x9b, 0x60, 0xf6, 0x6d, 0x7f, 0xa6, 0xd5, 0xcf, 0xa6, 0x2e, 0x11, 0xc3, 0x43, 0xaf, 0x42, 0x0f, 0x74, 0x49, 0xda, - 0x07, 0x07, 0x60, 0x75, 0x14, 0xcc, 0x86, 0xdb, 0xe8, 0x07, 0xbc, 0x59, 0x4b, 0x83, 0x60, 0x05, 0x60, 0xdc, 0xf9, - 0x86, 0x93, 0xa5, 0x85, 0xad, 0x06, 0x2a, 0xac, 0x8b, 0x30, 0xae, 0x5e, 0x48, 0x2a, 0x8c, 0x10, 0x0d, 0x47, 0x98, - 0x0b, 0x86, 0xb2, 0xdf, 0xc2, 0x72, 0x3c, 0x56, 0x4c, 0xc3, 0xd1, 0x51, 0xb0, 0xaf, 0xac, 0x50, 0xe6, 0x14, 0x19, - 0xb2, 0x09, 0x17, 0x0f, 0xf5, 0x9f, 0xac, 0x90, 0xe6, 0xd3, 0x68, 0x30, 0xd2, 0xc8, 0xac, 0x62, 0x84, 0xb3, 0x9c, - 0xcf, 0xa1, 0xea, 0xa4, 0x00, 0xa7, 0x1f, 0xf8, 0xcb, 0x47, 0x69, 0xd8, 0x26, 0x90, 0xaf, 0x0f, 0x36, 0xa6, 0x0b, - 0x1e, 0x15, 0xf4, 0xe6, 0xb5, 0x78, 0x0c, 0x3b, 0xea, 0x61, 0xc1, 0x28, 0x64, 0x43, 0xd2, 0x3b, 0x68, 0x0a, 0x3e, - 0xa0, 0xcd, 0x97, 0x06, 0x70, 0xe9, 0xb9, 0xf9, 0xb0, 0x15, 0x7d, 0xec, 0xc6, 0xa4, 0x6c, 0xcb, 0x64, 0x9a, 0x53, - 0xba, 0xca, 0xb4, 0x51, 0xa8, 0xca, 0x29, 0xac, 0xb1, 0x8b, 0x7a, 0x12, 0x0e, 0x66, 0x44, 0xd5, 0x34, 0xed, 0x0f, - 0xcc, 0xdf, 0xd7, 0xb6, 0x64, 0x0b, 0xbb, 0x88, 0x33, 0x6b, 0x6c, 0x1e, 0x4e, 0x0d, 0xca, 0xb7, 0x31, 0xdc, 0xc3, - 0xc2, 0xeb, 0x9d, 0x35, 0xf2, 0x79, 0xe2, 0xc9, 0xe6, 0xc9, 0x7a, 0x6d, 0x06, 0xa2, 0x52, 0xd0, 0x03, 0xbd, 0xf5, - 0xdb, 0xa6, 0x05, 0xdb, 0xa3, 0xfc, 0x3a, 0x6d, 0xe1, 0x19, 0x87, 0xc7, 0x48, 0x7d, 0x7b, 0x57, 0xba, 0x90, 0x5f, - 0x1c, 0x48, 0x5a, 0x41, 0x8a, 0x9d, 0x4e, 0xd0, 0xd9, 0x31, 0x0e, 0x46, 0x0e, 0xf4, 0xfc, 0xea, 0x8b, 0x85, 0xb5, - 0xff, 0xfd, 0xa6, 0x2c, 0x68, 0xe2, 0xe9, 0x94, 0x13, 0xca, 0xfc, 0xf9, 0xf9, 0x86, 0x27, 0x15, 0x2a, 0xb8, 0x57, - 0xbc, 0x60, 0x4f, 0xdb, 0x40, 0x9f, 0x33, 0xfa, 0xd9, 0xfe, 0xb0, 0x31, 0x7c, 0x4a, 0x2d, 0x5b, 0x56, 0x48, 0xa5, - 0x1e, 0xda, 0x34, 0x7b, 0xf4, 0xc0, 0x11, 0xf9, 0x12, 0xba, 0x00, 0x5e, 0x7f, 0x54, 0xc8, 0xb9, 0x41, 0x04, 0xf7, - 0xdb, 0x8d, 0xdb, 0xf8, 0x0a, 0x80, 0xb7, 0xc3, 0x5e, 0xf5, 0x4f, 0x0b, 0xd8, 0xdf, 0xa8, 0x2c, 0xe9, 0xc7, 0xdb, - 0xb1, 0xc7, 0x7f, 0x21, 0x21, 0x6a, 0xbc, 0xc5, 0xc3, 0xc4, 0xa1, 0x53, 0xc9, 0x9a, 0x95, 0x3f, 0xb7, 0x4a, 0x02, - 0x86, 0xd5, 0x0b, 0x86, 0x6c, 0xdc, 0x56, 0x71, 0x9b, 0xf9, 0x1f, 0x54, 0x30, 0x58, 0xf0, 0xad, 0x91, 0x54, 0x2c, - 0x8b, 0xdf, 0x3e, 0x75, 0xfe, 0xab, 0xce, 0x71, 0xed, 0xeb, 0xda, 0x4b, 0xa1, 0x43, 0x13, 0xa5, 0x39, 0x42, 0x07, - 0x07, 0x1b, 0x19, 0x74, 0x0c, 0x80, 0x47, 0x8e, 0xfd, 0xf2, 0xcb, 0xe7, 0xd9, 0x31, 0xa3, 0x79, 0x2c, 0xa2, 0x90, - 0xb9, 0xf3, 0xdc, 0x9c, 0x9d, 0xc8, 0x13, 0xaa, 0xa6, 0xbe, 0x30, 0xc0, 0xf1, 0xd1, 0x56, 0x2a, 0xe0, 0x7b, 0xb4, - 0xde, 0x31, 0x81, 0x0d, 0x7e, 0xcb, 0x4e, 0x6a, 0x57, 0x41, 0xbf, 0x40, 0xcb, 0x5d, 0x4c, 0xe5, 0xc6, 0x02, 0x47, - 0x9b, 0x13, 0xd9, 0x39, 0xf4, 0x8d, 0x3a, 0x25, 0xeb, 0xf1, 0x64, 0xb7, 0xd1, 0x97, 0x14, 0xbb, 0x92, 0x2b, 0xda, - 0x36, 0x64, 0xd5, 0x6b, 0xc1, 0xba, 0x32, 0x75, 0xaa, 0xae, 0x79, 0x2b, 0x4b, 0x9b, 0xd2, 0x2e, 0xc9, 0xde, 0x6d, - 0xb1, 0xf0, 0x2a, 0xbc, 0xd1, 0x28, 0x2f, 0x42, 0xc1, 0x1e, 0x4b, 0x0c, 0xba, 0x9c, 0xc0, 0xf5, 0xc2, 0x6a, 0x15, - 0xc3, 0x9f, 0x5d, 0x63, 0xd8, 0x65, 0xba, 0xf4, 0x81, 0x6f, 0xf0, 0x2b, 0x41, 0xc0, 0x62, 0x67, 0x07, 0x09, 0xd6, - 0x5d, 0x6e, 0xd0, 0x70, 0x9c, 0xf8, 0x2f, 0x78, 0x2e, 0x5b, 0x7b, 0x97, 0x83, 0x49, 0xf6, 0x8d, 0x27, 0xf6, 0x4a, - 0xd6, 0xb2, 0x16, 0xed, 0x7e, 0x43, 0x82, 0x21, 0x76, 0x53, 0x3a, 0xc7, 0xad, 0xa4, 0x8d, 0x22, 0x57, 0xac, 0x42, - 0xff, 0x6f, 0x15, 0xc9, 0x6c, 0xe6, 0x7f, 0x9d, 0x9d, 0x9d, 0xb9, 0x14, 0x67, 0xf3, 0xa7, 0x8c, 0x07, 0x9c, 0x49, - 0x60, 0x5f, 0x79, 0xc6, 0x8c, 0x0e, 0xf9, 0x2d, 0x0c, 0x85, 0x08, 0x72, 0x29, 0x1c, 0xbb, 0x04, 0xaf, 0x3d, 0x02, - 0xe5, 0x01, 0xf6, 0xef, 0xc9, 0x46, 0x39, 0xff, 0x5c, 0x94, 0x0f, 0xa7, 0x5c, 0x36, 0xc8, 0xbe, 0x9a, 0xcf, 0xbe, - 0x35, 0x93, 0x81, 0x17, 0x12, 0x22, 0x6c, 0x7f, 0x1b, 0x96, 0xd6, 0x59, 0xca, 0xe0, 0x48, 0xcb, 0x45, 0x36, 0xb5, - 0x9a, 0x7f, 0xf7, 0x61, 0xca, 0xba, 0xa7, 0x86, 0x20, 0x72, 0x17, 0x59, 0xba, 0xa8, 0xa0, 0xd1, 0x8f, 0x65, 0x00, - 0xd0, 0xbd, 0x57, 0x6c, 0xc1, 0x7e, 0xc4, 0x7b, 0x55, 0x0a, 0x7c, 0x3c, 0x2c, 0x38, 0xcd, 0x7f, 0xc4, 0x7b, 0x55, - 0x20, 0x50, 0x70, 0x85, 0x34, 0xb1, 0x34, 0xb1, 0x79, 0x56, 0x3b, 0x8d, 0x04, 0x50, 0xd0, 0x3c, 0x32, 0x07, 0xd9, - 0x73, 0x17, 0xa3, 0x31, 0xe9, 0x60, 0x17, 0x1c, 0xcc, 0x46, 0x84, 0xb5, 0x81, 0xd4, 0x21, 0x6e, 0x5d, 0x39, 0x1b, - 0xf3, 0xf5, 0x68, 0x63, 0x41, 0x8c, 0x32, 0x99, 0x5c, 0x3e, 0xe7, 0xf1, 0xd6, 0x62, 0xa1, 0xb0, 0x5a, 0xb0, 0x40, - 0xb5, 0x2a, 0x55, 0x7a, 0x58, 0x7c, 0xbb, 0x60, 0x16, 0x14, 0x31, 0x5b, 0xef, 0xe1, 0x2d, 0x57, 0x04, 0xa4, 0x64, - 0x97, 0x04, 0x2f, 0xa3, 0x1b, 0x4c, 0x25, 0xcb, 0x99, 0x1c, 0x31, 0x4b, 0xe8, 0x99, 0xd2, 0x11, 0x36, 0x79, 0x0a, - 0x22, 0x89, 0xed, 0xb7, 0xb0, 0x63, 0x8d, 0x5e, 0x08, 0x2f, 0xa4, 0xc0, 0xb9, 0x6a, 0x9a, 0x98, 0x51, 0x6e, 0xa2, - 0x8b, 0x3d, 0x54, 0x73, 0x96, 0x69, 0x8b, 0x00, 0xfb, 0x0e, 0x0d, 0xa5, 0x78, 0x6e, 0x40, 0x61, 0x9e, 0xf4, 0x76, - 0x29, 0x8f, 0x61, 0xf1, 0x82, 0x14, 0x20, 0x6a, 0x5c, 0x4c, 0xca, 0x3a, 0xf3, 0x7c, 0x31, 0xe1, 0xa2, 0x42, 0x86, - 0x82, 0xa9, 0xb9, 0x14, 0xf0, 0xa2, 0x46, 0x59, 0xc4, 0xd0, 0xa1, 0x1a, 0xbe, 0x5b, 0x12, 0x56, 0xd6, 0x31, 0xc7, - 0x14, 0x17, 0x55, 0x0d, 0x60, 0x2e, 0x1e, 0x1a, 0x01, 0xd1, 0x87, 0x97, 0x7d, 0x2d, 0xde, 0xc9, 0x79, 0x95, 0xef, - 0x69, 0x9c, 0x0f, 0x5c, 0xef, 0xec, 0x86, 0xd1, 0xda, 0x3c, 0x7a, 0x15, 0x6c, 0xdf, 0x0f, 0xbc, 0x7a, 0x08, 0x6e, - 0x6d, 0x9e, 0xcd, 0x2a, 0xb3, 0x86, 0xac, 0x7c, 0x23, 0xa2, 0x6a, 0xaf, 0x5e, 0x55, 0x0a, 0x5b, 0x11, 0xa0, 0x52, - 0xf0, 0xd1, 0x56, 0xfe, 0x13, 0x6d, 0xf3, 0xed, 0x39, 0x54, 0x86, 0x07, 0xf2, 0x64, 0xa8, 0xea, 0x01, 0x17, 0xe5, - 0x87, 0x00, 0x16, 0x3f, 0x32, 0xf1, 0x83, 0x77, 0x5d, 0x20, 0x73, 0xa6, 0x62, 0x89, 0x97, 0x7d, 0x3a, 0x48, 0xad, - 0x3c, 0x94, 0x4a, 0xb0, 0xed, 0xb9, 0x29, 0xb8, 0xf6, 0x81, 0x8a, 0x71, 0x9f, 0x0d, 0xd2, 0x65, 0x3d, 0x98, 0xb1, - 0x0d, 0xa7, 0xec, 0xcd, 0x39, 0x4d, 0xf4, 0x5f, 0x3a, 0xc0, 0x39, 0x01, 0xdb, 0x63, 0xcf, 0x9e, 0xbe, 0x89, 0x33, - 0xd4, 0xab, 0x73, 0xf8, 0xcb, 0x35, 0xce, 0x71, 0x86, 0xd2, 0x87, 0x31, 0x5c, 0x60, 0xad, 0x31, 0x80, 0x2f, 0xb3, - 0xa4, 0x0a, 0x3c, 0x52, 0x33, 0x23, 0xb1, 0xba, 0x8b, 0x40, 0xb4, 0xd4, 0xe1, 0xed, 0x38, 0xf3, 0xe1, 0xc0, 0x0d, - 0xf7, 0xfa, 0xcc, 0x08, 0x87, 0x93, 0x2c, 0xae, 0x9d, 0x33, 0x9c, 0x5c, 0xee, 0xf3, 0xda, 0x89, 0x09, 0xd6, 0xde, - 0xe1, 0xa9, 0x02, 0x7a, 0x34, 0x38, 0x55, 0x2c, 0x0d, 0x81, 0x98, 0x09, 0xe0, 0xcd, 0x1c, 0x1e, 0x6d, 0x01, 0xce, - 0x47, 0x6b, 0x1c, 0x7c, 0xa5, 0xb5, 0xae, 0x36, 0x95, 0x28, 0xeb, 0x35, 0xee, 0x4f, 0x33, 0x3c, 0xca, 0xf0, 0x3c, - 0x1b, 0x04, 0xc7, 0xcd, 0x2c, 0x0b, 0x4d, 0xba, 0x56, 0xab, 0xa7, 0xce, 0x8c, 0x10, 0xd9, 0x9f, 0x96, 0xfe, 0xa0, - 0x1e, 0x20, 0x7c, 0x0a, 0x59, 0x40, 0x4b, 0x7a, 0xee, 0x6f, 0xc3, 0xbe, 0x16, 0x8e, 0x1a, 0x31, 0x4f, 0x2c, 0x19, - 0xe9, 0xf9, 0x1f, 0x65, 0x96, 0x6d, 0xad, 0x11, 0xcd, 0x6f, 0xf7, 0xa2, 0x86, 0x6f, 0x2f, 0xd0, 0xb2, 0x95, 0x66, - 0x3b, 0x80, 0x28, 0xd6, 0x38, 0x49, 0x07, 0x6b, 0x24, 0x57, 0xab, 0xd8, 0xa6, 0x10, 0x9e, 0xcc, 0x18, 0x55, 0x8b, - 0xc2, 0x3c, 0xa0, 0x17, 0x2b, 0x94, 0x18, 0x7e, 0x17, 0x3b, 0x1b, 0x51, 0x78, 0xaf, 0x4e, 0x82, 0xe1, 0x46, 0x2c, - 0x88, 0xac, 0x89, 0xdc, 0xc3, 0xac, 0xb2, 0x0c, 0x12, 0x44, 0x18, 0x91, 0xdf, 0x5e, 0x97, 0x0a, 0xfb, 0x44, 0x9f, - 0xfd, 0x63, 0x7c, 0x01, 0xe1, 0xe6, 0x6d, 0x42, 0x8b, 0x21, 0x9d, 0x00, 0x1b, 0x0b, 0x71, 0x08, 0xb7, 0x12, 0x56, - 0xab, 0xfe, 0xa0, 0x2b, 0x0c, 0x79, 0x76, 0x0f, 0x08, 0x96, 0x0d, 0xed, 0x6e, 0x00, 0xae, 0xba, 0x2d, 0x35, 0xd7, - 0x46, 0xf7, 0x43, 0xcd, 0x1b, 0x67, 0xdc, 0x25, 0xb9, 0x67, 0x4a, 0xaa, 0x97, 0xc8, 0x6b, 0x16, 0xe0, 0x26, 0x74, - 0x15, 0x1e, 0xe1, 0x85, 0xb5, 0xe1, 0x34, 0x0f, 0x5a, 0x51, 0xf3, 0x8e, 0x15, 0x3c, 0x9f, 0x4d, 0x58, 0x3f, 0x1b, - 0xe0, 0x91, 0x0f, 0x77, 0xbe, 0xff, 0x36, 0x1e, 0x21, 0x54, 0x10, 0x03, 0x53, 0xeb, 0xb2, 0x3d, 0xaa, 0xec, 0xf6, - 0x4d, 0xa6, 0x61, 0x18, 0x8c, 0x11, 0xf3, 0x28, 0x34, 0x62, 0xce, 0x1b, 0x0d, 0xb4, 0x20, 0x23, 0x30, 0x62, 0x5e, - 0x04, 0xad, 0x2d, 0xec, 0x63, 0xa7, 0x41, 0x7b, 0x0b, 0x84, 0xba, 0x1c, 0x68, 0x9a, 0x86, 0x67, 0x4d, 0xaa, 0x67, - 0xe5, 0xfd, 0x23, 0x5b, 0x47, 0x1d, 0x50, 0x24, 0x8c, 0x2f, 0xfd, 0x24, 0xac, 0x6b, 0xb8, 0x1d, 0xf7, 0xd8, 0x8c, - 0xdb, 0xd9, 0x36, 0xa8, 0xbe, 0xec, 0x67, 0x83, 0x41, 0x57, 0x7a, 0x2b, 0x89, 0x16, 0x1e, 0x57, 0x0f, 0xa1, 0x54, - 0x8b, 0xf7, 0x55, 0x6f, 0x5e, 0x79, 0x73, 0xff, 0xbe, 0xea, 0xe6, 0x79, 0x0c, 0x1c, 0xd0, 0x3e, 0xdc, 0x0f, 0x55, - 0xf1, 0xc1, 0x8e, 0x3a, 0x10, 0x05, 0x2d, 0x6d, 0xd5, 0x04, 0x52, 0x6b, 0x66, 0x17, 0xeb, 0xa6, 0x42, 0x87, 0x02, - 0xc2, 0x90, 0xa9, 0xaa, 0xbb, 0x3b, 0x15, 0xa8, 0x86, 0x38, 0x9c, 0xfa, 0x8f, 0xad, 0x11, 0x6b, 0x1c, 0x75, 0x46, - 0x91, 0x31, 0x92, 0xb4, 0xcb, 0x07, 0x6f, 0x1f, 0x81, 0x95, 0x80, 0x8f, 0x41, 0x6d, 0x92, 0x8c, 0x21, 0xc1, 0x5b, - 0x96, 0x69, 0xc3, 0x87, 0x70, 0x87, 0xa0, 0x3c, 0xb1, 0x41, 0x69, 0x5d, 0x25, 0x0b, 0xb9, 0xaa, 0xcb, 0xeb, 0x00, - 0x3d, 0xef, 0xca, 0xdf, 0xd8, 0x70, 0x64, 0xc1, 0xc0, 0xb2, 0xad, 0x7d, 0x02, 0x1e, 0xf9, 0xb8, 0x42, 0x10, 0xbf, - 0x14, 0x3a, 0x31, 0xf1, 0xba, 0xaf, 0x60, 0x83, 0xe2, 0x39, 0x38, 0x08, 0x3a, 0x09, 0x0e, 0x83, 0x77, 0x99, 0xd5, - 0x24, 0x1b, 0xdc, 0x9a, 0x91, 0x78, 0xbe, 0x5a, 0xb5, 0xd0, 0xe1, 0xdf, 0xe6, 0x49, 0xea, 0x71, 0xa9, 0x70, 0x1f, - 0x57, 0x0a, 0x77, 0xb0, 0x04, 0x24, 0xe3, 0x40, 0xd7, 0x8e, 0x65, 0xa8, 0x46, 0x87, 0x68, 0xe9, 0x2f, 0x20, 0x76, - 0xb6, 0x3b, 0x96, 0x40, 0xcf, 0xbe, 0x55, 0xc0, 0xea, 0xda, 0xcb, 0x12, 0xc8, 0x08, 0xee, 0x7e, 0x13, 0x18, 0x15, - 0xa2, 0xf1, 0xf9, 0x33, 0xaf, 0x5a, 0xf0, 0xc4, 0xf9, 0x73, 0xcd, 0x0c, 0xeb, 0x5e, 0xd0, 0x1b, 0xd3, 0x7c, 0x3c, - 0xc6, 0xcd, 0xb1, 0x05, 0xe7, 0x51, 0x07, 0x7e, 0x5a, 0x88, 0x1e, 0x75, 0xb0, 0x4b, 0xc5, 0xe3, 0x12, 0xc8, 0x21, - 0x7a, 0x3a, 0x03, 0x29, 0x60, 0xa5, 0x63, 0xab, 0x45, 0x9a, 0xa0, 0xd5, 0x6a, 0x72, 0x41, 0x5a, 0x08, 0x2d, 0xd5, - 0x0d, 0xd7, 0xd9, 0x14, 0x7c, 0xa4, 0x41, 0x31, 0xf0, 0x86, 0xea, 0x69, 0x8c, 0xf0, 0x18, 0x2d, 0x47, 0x6c, 0x4c, - 0x17, 0xb9, 0x4e, 0x55, 0x8f, 0x27, 0x36, 0x70, 0x2f, 0xb3, 0x91, 0xe0, 0x8e, 0x3a, 0x78, 0x62, 0xf8, 0xcb, 0xf7, - 0xc6, 0x1c, 0xa4, 0xc8, 0x4c, 0xf2, 0xc4, 0x24, 0x60, 0x9e, 0x64, 0xb9, 0x54, 0xcc, 0x36, 0xd3, 0xb5, 0xb6, 0xe5, - 0x10, 0x92, 0x3c, 0xd2, 0x05, 0x37, 0x56, 0x94, 0x51, 0x3a, 0x25, 0xaa, 0xa7, 0x8e, 0x3a, 0xe9, 0x04, 0xf3, 0x04, - 0x38, 0xbd, 0x77, 0x32, 0x66, 0x8d, 0xf2, 0x56, 0x74, 0x86, 0x0e, 0xa7, 0x58, 0x54, 0x97, 0xa8, 0x33, 0x74, 0x38, - 0x41, 0x78, 0xd6, 0x20, 0xb9, 0x02, 0x8f, 0x61, 0x2e, 0xfe, 0x8f, 0x94, 0xff, 0xe6, 0xb0, 0x21, 0xc4, 0xf4, 0x5b, - 0xd8, 0x29, 0x6c, 0x14, 0xa5, 0x39, 0x01, 0xaf, 0xc5, 0xf6, 0x19, 0xce, 0xc8, 0xa4, 0x99, 0xfb, 0x80, 0x7b, 0xa6, - 0x95, 0xc6, 0xad, 0x46, 0x87, 0x19, 0x1e, 0x6d, 0x26, 0xc5, 0x66, 0xae, 0xcd, 0x3c, 0xcd, 0xe0, 0x7c, 0xaf, 0x46, - 0xe1, 0xca, 0x2f, 0x36, 0x93, 0xc2, 0xf2, 0x0e, 0xb8, 0xcd, 0x11, 0x16, 0x4d, 0x8a, 0x73, 0x3c, 0x6b, 0xbe, 0xc2, - 0xb3, 0xe6, 0x87, 0x32, 0xa3, 0xb1, 0xc0, 0x02, 0x82, 0xf7, 0x41, 0x22, 0x9e, 0x55, 0xc9, 0x23, 0x2c, 0x1a, 0xa6, - 0x3c, 0x9e, 0x35, 0xaa, 0xd2, 0xcd, 0x05, 0x16, 0x0d, 0x53, 0xba, 0xf1, 0x01, 0xcf, 0x1a, 0xaf, 0xfe, 0xc5, 0xa4, - 0xa3, 0x14, 0xd0, 0x65, 0x8e, 0x96, 0x99, 0x1d, 0xe2, 0xd5, 0x6f, 0x6f, 0xdf, 0xb5, 0xaf, 0x3b, 0x87, 0x13, 0xec, - 0xd7, 0x2f, 0x33, 0x38, 0x96, 0xe9, 0x98, 0x35, 0x01, 0xa2, 0x19, 0xee, 0x1c, 0x4e, 0x71, 0xe7, 0x30, 0x73, 0x4d, - 0xad, 0x67, 0x0d, 0x72, 0xab, 0x43, 0x28, 0xea, 0x28, 0x0d, 0xe1, 0xe3, 0x27, 0x9b, 0x4e, 0x50, 0x0d, 0x94, 0xe8, - 0x70, 0x52, 0x03, 0x15, 0x7c, 0x2f, 0x6a, 0xdf, 0x55, 0xbd, 0x0a, 0x83, 0x2c, 0x94, 0x50, 0xb8, 0xe6, 0x06, 0x3c, - 0xb5, 0x14, 0x03, 0x99, 0x30, 0xc5, 0x02, 0xe5, 0x3b, 0xa0, 0x30, 0xca, 0x13, 0x33, 0xf4, 0x60, 0x3a, 0x26, 0xf1, - 0xff, 0xe7, 0xc9, 0x94, 0x43, 0x2f, 0xb7, 0xcc, 0xd6, 0xf4, 0xdc, 0x64, 0xc2, 0xe1, 0x03, 0x8f, 0xf5, 0x7f, 0xed, - 0x40, 0xb1, 0x01, 0x29, 0xfe, 0xbf, 0x74, 0x74, 0x21, 0x18, 0x21, 0x2b, 0x4a, 0x0b, 0x87, 0xf8, 0xdf, 0x1f, 0x56, - 0xd0, 0x7d, 0xb1, 0xd5, 0x7d, 0x61, 0xba, 0x0f, 0x9b, 0x36, 0xaa, 0x9c, 0xb4, 0xaa, 0x64, 0xc9, 0x7f, 0x9d, 0x6e, - 0x6d, 0x81, 0x46, 0xd4, 0xe8, 0xd9, 0x24, 0x6c, 0x70, 0xbf, 0x9d, 0xee, 0x40, 0xe6, 0x35, 0xb7, 0x2f, 0xa4, 0xc2, - 0xe1, 0x1b, 0xdc, 0xa9, 0x5e, 0xb6, 0xc0, 0x7b, 0x53, 0x19, 0x7d, 0x65, 0x1c, 0x5a, 0x0e, 0xd2, 0x4d, 0x53, 0x6e, - 0x63, 0x2c, 0x9d, 0x9c, 0x62, 0xe3, 0x8a, 0x08, 0x95, 0x6e, 0x2f, 0x41, 0x29, 0x3e, 0xd6, 0x4d, 0x66, 0xbe, 0x2e, - 0x74, 0x62, 0x2e, 0xa1, 0x1a, 0xe6, 0xf3, 0xee, 0x52, 0x27, 0x5a, 0xce, 0x6d, 0xde, 0xdd, 0x05, 0xf4, 0x09, 0x1a, - 0xd6, 0x46, 0x60, 0xb7, 0xcf, 0x0a, 0xa7, 0xdf, 0xa9, 0x0e, 0xc1, 0xf0, 0x00, 0x72, 0xa4, 0xc5, 0xf6, 0x81, 0x4d, - 0x6b, 0xd8, 0x75, 0xd1, 0x2c, 0x13, 0x6d, 0xab, 0x4d, 0x93, 0x6b, 0xf7, 0x30, 0x9f, 0x87, 0x3c, 0x05, 0x2f, 0xac, - 0x7e, 0x7c, 0x07, 0xbb, 0x71, 0x5b, 0x63, 0x24, 0xea, 0x4a, 0xa6, 0x12, 0xfa, 0xc9, 0x2d, 0x66, 0xc9, 0x9d, 0xf1, - 0x62, 0x54, 0xc6, 0xdf, 0xc7, 0xc4, 0xe5, 0x8f, 0x2a, 0x49, 0x0e, 0x2c, 0xfb, 0x1b, 0x2c, 0xb9, 0x05, 0xf3, 0xc4, - 0xb2, 0x9a, 0xc4, 0x3a, 0xb9, 0x0b, 0x16, 0x51, 0x9a, 0x46, 0xd6, 0x86, 0x01, 0x35, 0xcd, 0x58, 0xf5, 0xe0, 0x3e, - 0x04, 0x7a, 0xe8, 0x95, 0xa5, 0xb4, 0xeb, 0x2c, 0xad, 0x75, 0xaf, 0x4d, 0xf7, 0x9b, 0x03, 0x0a, 0xf8, 0xc2, 0x80, - 0x6b, 0xfa, 0x57, 0x93, 0x48, 0x86, 0xec, 0x1f, 0xce, 0x8a, 0xc7, 0x8b, 0xc2, 0x60, 0x9a, 0xe8, 0xe9, 0x24, 0x9b, - 0xb7, 0xc1, 0x54, 0x2f, 0x9b, 0x77, 0x6e, 0xb1, 0xfb, 0xbe, 0xb3, 0xdf, 0x77, 0x58, 0xf4, 0x98, 0xc9, 0x48, 0x99, - 0x29, 0xe6, 0xbf, 0xef, 0xec, 0xf7, 0x1d, 0xde, 0x1e, 0xcc, 0x8d, 0xbf, 0x50, 0x2c, 0xd9, 0x19, 0x2e, 0xc1, 0x84, - 0x3c, 0xe0, 0x6e, 0x6a, 0x59, 0x26, 0x08, 0x6c, 0x2d, 0x01, 0xe2, 0x7c, 0x3e, 0x8d, 0x2b, 0x5e, 0x0d, 0x01, 0xf7, - 0xe9, 0x5d, 0xdb, 0xab, 0x54, 0xe0, 0x31, 0x41, 0x23, 0x62, 0x62, 0xdb, 0x98, 0xd7, 0xcd, 0x80, 0xcb, 0x23, 0xba, - 0xd4, 0x93, 0x24, 0xc0, 0xab, 0x1a, 0x95, 0xb7, 0x29, 0x52, 0x7e, 0x91, 0x20, 0xc7, 0x17, 0x7b, 0x44, 0x15, 0x03, - 0x58, 0x95, 0x25, 0x7d, 0x02, 0xa9, 0xe7, 0x07, 0x13, 0xfd, 0xb2, 0x89, 0x3c, 0xf6, 0x9d, 0xdf, 0x2f, 0x4c, 0x4f, - 0x0b, 0xb9, 0x98, 0x4c, 0xc1, 0x87, 0x16, 0x58, 0x86, 0xc2, 0xd4, 0xab, 0x6c, 0xfd, 0x6b, 0x92, 0x9b, 0x00, 0x0a, - 0xa7, 0x9b, 0x32, 0xa1, 0x99, 0x5e, 0xd0, 0xdc, 0x58, 0x92, 0x72, 0x31, 0x79, 0x24, 0x6f, 0x5f, 0x02, 0x76, 0x53, - 0xa2, 0x1b, 0x3b, 0xf2, 0xde, 0xc2, 0x0e, 0xc0, 0x19, 0x61, 0xbb, 0x2a, 0x3e, 0x54, 0xa0, 0xf3, 0xc7, 0x39, 0x61, - 0xbb, 0xaa, 0x3e, 0x61, 0x36, 0x7b, 0x4a, 0x36, 0x86, 0xdb, 0x8b, 0xb3, 0x46, 0x8e, 0x8e, 0x3a, 0x69, 0xde, 0xf5, - 0xc4, 0xc0, 0x02, 0x34, 0x00, 0xee, 0xd6, 0xf6, 0x2c, 0xef, 0x6e, 0x08, 0xe8, 0x5d, 0x32, 0x69, 0xaf, 0xcb, 0x4d, - 0xca, 0x6a, 0xd5, 0xa9, 0xa8, 0x60, 0x81, 0xa7, 0xc1, 0x5e, 0xa0, 0xf6, 0x6b, 0x07, 0xc5, 0xb9, 0xca, 0x36, 0x4d, - 0xcf, 0xcb, 0xbe, 0xbb, 0x3b, 0x16, 0x19, 0xdb, 0xb4, 0xb7, 0x3b, 0x88, 0x84, 0xe5, 0x84, 0x75, 0xc0, 0x09, 0x57, - 0xb5, 0x03, 0x02, 0x74, 0x1d, 0x88, 0xdc, 0x58, 0x92, 0xe5, 0xba, 0x32, 0xba, 0x0f, 0xfc, 0x6e, 0x29, 0x91, 0x6e, - 0xb4, 0x25, 0xc1, 0xf4, 0x09, 0x46, 0x4d, 0x67, 0x9e, 0xa6, 0xae, 0xbd, 0xba, 0xbc, 0x29, 0xda, 0xfa, 0x37, 0xa0, - 0xb1, 0xd9, 0x1e, 0x26, 0x86, 0x32, 0x88, 0x81, 0xde, 0x47, 0xbc, 0xdb, 0x68, 0x64, 0x08, 0x14, 0x32, 0xd9, 0x00, - 0xcb, 0xc4, 0x6b, 0xd1, 0x0f, 0x0e, 0x0c, 0x3c, 0xaa, 0x04, 0x84, 0x29, 0x08, 0x21, 0x61, 0xd7, 0x06, 0x61, 0xc3, - 0xe5, 0xaa, 0xe5, 0xc2, 0x46, 0xaa, 0x0d, 0x1d, 0xfc, 0xbf, 0xc2, 0x65, 0xab, 0x67, 0x96, 0x8b, 0x62, 0x70, 0x33, - 0x37, 0x60, 0x91, 0x20, 0x3d, 0xda, 0x6c, 0x0f, 0xc5, 0xdd, 0xb9, 0xd8, 0x6c, 0x08, 0x48, 0xcc, 0x61, 0x82, 0xa2, - 0xe1, 0xdc, 0x18, 0x63, 0x95, 0x54, 0x5a, 0xd6, 0x9a, 0xc4, 0x1c, 0xf8, 0xd2, 0x85, 0xeb, 0xbe, 0xbc, 0x4d, 0x19, - 0xbe, 0x4b, 0x05, 0xbe, 0x01, 0x4f, 0x9a, 0x54, 0x62, 0xf7, 0x78, 0x41, 0xb1, 0x26, 0xba, 0xeb, 0xd9, 0xdb, 0x02, - 0xd6, 0xd9, 0xec, 0x11, 0x11, 0xfc, 0xae, 0x7e, 0xb5, 0xc1, 0x77, 0x0b, 0xbf, 0x02, 0xeb, 0xe7, 0xe0, 0x24, 0xc5, - 0xa2, 0x21, 0x9b, 0x85, 0x3b, 0x32, 0xa0, 0x5c, 0xc5, 0x2f, 0x87, 0xa9, 0x5b, 0xc5, 0x70, 0xed, 0xe3, 0x15, 0xfe, - 0xb0, 0xd1, 0x6e, 0x43, 0x95, 0xc5, 0xed, 0xde, 0x14, 0x0d, 0x59, 0x35, 0xbd, 0x23, 0x73, 0x23, 0xa5, 0xfe, 0xf5, - 0x01, 0xb7, 0xb6, 0xda, 0xf7, 0xd3, 0x7c, 0xeb, 0xd1, 0xb9, 0x6a, 0xda, 0xa7, 0xd6, 0x8a, 0xe0, 0xe0, 0x67, 0x0b, - 0x37, 0xb7, 0x06, 0x1c, 0xc0, 0xcf, 0xdf, 0xd1, 0x3c, 0xce, 0x20, 0x3a, 0xbd, 0xd5, 0x8c, 0xaf, 0xe2, 0xbf, 0x46, - 0x8d, 0xb8, 0x97, 0xfe, 0x95, 0xfc, 0x35, 0x6a, 0xa0, 0x1e, 0x8a, 0xe7, 0xb7, 0x2b, 0x36, 0x5b, 0x41, 0xb0, 0xb5, - 0x7b, 0x47, 0xf8, 0x75, 0x58, 0x92, 0x6b, 0x9a, 0xf3, 0x6c, 0xe5, 0x1e, 0x04, 0x5c, 0xb9, 0x57, 0x89, 0x56, 0xe6, - 0x8d, 0xab, 0x55, 0x2c, 0x87, 0x39, 0x04, 0x16, 0x8e, 0xf7, 0x9a, 0xbd, 0x7e, 0xab, 0xf9, 0x60, 0x60, 0xff, 0x35, - 0x11, 0xee, 0x51, 0x2d, 0x62, 0xdb, 0x9b, 0x8d, 0xad, 0x1f, 0x83, 0x61, 0x07, 0x84, 0x02, 0x07, 0xb9, 0xf4, 0x71, - 0x86, 0xac, 0xef, 0xc9, 0x6a, 0xc5, 0x5c, 0x34, 0x6b, 0xa7, 0xc1, 0x2f, 0x63, 0x33, 0x1d, 0xb6, 0x93, 0x4e, 0xd7, - 0x8b, 0xb1, 0xa4, 0x01, 0x91, 0xa6, 0x31, 0x83, 0x40, 0x52, 0x4b, 0xc3, 0x61, 0xcd, 0x6f, 0xa3, 0xb4, 0xba, 0x3f, - 0x82, 0x94, 0x1f, 0xa2, 0x94, 0x1f, 0x11, 0x08, 0xa0, 0x6d, 0x99, 0xa3, 0xb2, 0x21, 0xef, 0xbb, 0x74, 0xcf, 0x38, - 0x33, 0x34, 0xf8, 0x6a, 0xd5, 0xaa, 0x86, 0x29, 0x8a, 0xfa, 0x30, 0x97, 0x6b, 0x2c, 0xc8, 0x1b, 0xd0, 0x35, 0x2b, - 0x22, 0x7a, 0xa1, 0xab, 0x3c, 0xbc, 0x87, 0x8c, 0x25, 0x01, 0x27, 0xfd, 0x9e, 0xe8, 0x15, 0xe4, 0xf2, 0x61, 0x0c, - 0x3e, 0x66, 0x98, 0xf7, 0x75, 0xbf, 0x18, 0x0c, 0x50, 0xea, 0x9c, 0xce, 0x52, 0x13, 0x71, 0x25, 0xf0, 0x4b, 0x2e, - 0xc0, 0x2f, 0x59, 0x21, 0xd6, 0x2f, 0x06, 0xe4, 0x5e, 0x16, 0x4b, 0x70, 0xca, 0xdf, 0xe1, 0xf3, 0xf8, 0x30, 0x34, - 0x30, 0x35, 0xc3, 0x32, 0x17, 0xd9, 0x60, 0x31, 0x67, 0x2d, 0x81, 0xe0, 0x66, 0xc0, 0x5d, 0x6a, 0x43, 0xa2, 0xb1, - 0x06, 0x8a, 0x6e, 0xa3, 0xd0, 0xcc, 0xe8, 0xe9, 0x56, 0x1b, 0xfd, 0xc8, 0xe1, 0x85, 0xb9, 0x86, 0xb1, 0x08, 0x64, - 0x2e, 0x57, 0x3d, 0xf6, 0x97, 0x1f, 0x36, 0x2b, 0x0c, 0x5e, 0x91, 0xe9, 0xd0, 0x1d, 0xc7, 0x8c, 0xaf, 0xf2, 0xc4, - 0x31, 0x04, 0x99, 0x58, 0x2a, 0xdd, 0x70, 0x4c, 0x5c, 0x49, 0x9f, 0x89, 0x21, 0xdb, 0x0d, 0xcf, 0xcc, 0x85, 0x6e, - 0xb6, 0x7f, 0x38, 0xb7, 0x73, 0x4e, 0xb8, 0xd1, 0x4a, 0x1a, 0x6d, 0xd4, 0x33, 0x43, 0x55, 0x5d, 0x30, 0xbf, 0x87, - 0x4e, 0x4b, 0x8b, 0x9d, 0xab, 0x77, 0x37, 0x7c, 0x9d, 0xaf, 0x8c, 0xbf, 0xc5, 0xaa, 0xd0, 0x8a, 0x0c, 0xb7, 0x5b, - 0xc8, 0x9b, 0x33, 0x3d, 0xf4, 0x8a, 0x5c, 0xa8, 0x0e, 0x7f, 0x51, 0x57, 0x98, 0x07, 0x3b, 0xa3, 0x86, 0xf0, 0xe8, - 0xf7, 0x3a, 0x03, 0xe5, 0x1f, 0x4c, 0x4c, 0xe6, 0x2c, 0xb9, 0xa1, 0x85, 0x88, 0x7f, 0x7c, 0x21, 0x4c, 0xac, 0xaa, - 0x3d, 0x18, 0xc8, 0x9e, 0xa9, 0xb8, 0x07, 0xb7, 0x26, 0x7c, 0xcc, 0xd9, 0x28, 0xdd, 0x8b, 0x7e, 0x6c, 0x88, 0xc6, - 0x8f, 0xd1, 0x8f, 0xe0, 0xee, 0xec, 0x5e, 0x87, 0x2c, 0xe3, 0x42, 0xf8, 0x7b, 0xac, 0x87, 0xa5, 0x4a, 0x19, 0x6b, - 0xaf, 0x5b, 0x0e, 0x2f, 0xa4, 0xde, 0x64, 0xf1, 0x43, 0x47, 0xac, 0x6d, 0x0a, 0xd6, 0x21, 0x25, 0x85, 0x67, 0x57, - 0xcc, 0xad, 0x16, 0x73, 0x97, 0x5a, 0xc2, 0x5f, 0x5f, 0x3d, 0x2c, 0x55, 0xd0, 0x70, 0x10, 0xba, 0xd2, 0x16, 0x12, - 0x60, 0xe0, 0x52, 0xfa, 0x74, 0xba, 0x33, 0x89, 0xcc, 0xb2, 0x18, 0xde, 0x3d, 0xa8, 0x60, 0xfe, 0x3b, 0xdb, 0x08, - 0xab, 0x02, 0x97, 0x2b, 0x55, 0xd4, 0x4b, 0x49, 0x20, 0x00, 0x7d, 0xe9, 0x3d, 0x28, 0x2f, 0x8a, 0x6e, 0xa3, 0x21, - 0x41, 0x0b, 0x4b, 0xcd, 0xb5, 0x2a, 0xa6, 0xfb, 0xe1, 0xab, 0x86, 0xc1, 0x87, 0x77, 0x48, 0xdb, 0x78, 0x5a, 0x94, - 0x12, 0x6a, 0x77, 0xd0, 0x3e, 0x58, 0x65, 0x07, 0xe5, 0xdf, 0xc6, 0x14, 0xd9, 0xfc, 0x3e, 0xfb, 0x81, 0xba, 0x0e, - 0x07, 0xae, 0x60, 0xd5, 0x4b, 0x19, 0x05, 0x03, 0x56, 0x4e, 0x81, 0xda, 0x3b, 0xc9, 0x68, 0x36, 0x65, 0xa0, 0xee, - 0xb7, 0x45, 0xab, 0xb9, 0x3d, 0xa9, 0xfb, 0x0d, 0x19, 0x67, 0x1f, 0x61, 0x9c, 0x7d, 0x14, 0x78, 0xb1, 0x48, 0xf2, - 0x87, 0x8c, 0x35, 0x8e, 0x55, 0x53, 0xa0, 0xa3, 0x0e, 0x70, 0x67, 0xe0, 0xc0, 0x03, 0xb6, 0x28, 0x07, 0x07, 0xd4, - 0x59, 0xdc, 0xd3, 0x46, 0xe6, 0xbd, 0x3d, 0xa1, 0x76, 0x11, 0x0b, 0xdc, 0xac, 0x99, 0x69, 0x41, 0x6b, 0x85, 0x71, - 0x1e, 0x0f, 0x78, 0x9b, 0x67, 0xb5, 0xf8, 0x09, 0x1b, 0xd6, 0x54, 0xf5, 0x1b, 0x68, 0x8e, 0x6a, 0x41, 0x6e, 0x9e, - 0x18, 0x6f, 0x55, 0xd2, 0x8f, 0xa2, 0x81, 0xe5, 0x54, 0x88, 0x21, 0x19, 0xfd, 0xd6, 0x20, 0xb8, 0xd5, 0x5e, 0xad, - 0xb8, 0x47, 0x7c, 0x51, 0xf3, 0x56, 0x33, 0xb7, 0x00, 0xb4, 0x88, 0xa3, 0xf2, 0xde, 0x24, 0x02, 0xef, 0xdb, 0x32, - 0x42, 0xda, 0xb2, 0x6f, 0x9f, 0xae, 0x2c, 0x15, 0x9b, 0xef, 0xe8, 0x64, 0x90, 0x46, 0x76, 0x44, 0x11, 0xbe, 0x2e, - 0x21, 0x09, 0x57, 0x49, 0xd7, 0x2a, 0x93, 0x73, 0xa6, 0x52, 0x8e, 0xaf, 0x0b, 0x29, 0xf5, 0x95, 0xfd, 0x92, 0xb8, - 0xba, 0x93, 0x11, 0xf8, 0x7a, 0xc2, 0xf4, 0x3b, 0x5a, 0x4c, 0x18, 0xf8, 0x15, 0xf9, 0xdb, 0xb1, 0x94, 0x92, 0xcb, - 0x27, 0x22, 0xee, 0x53, 0x0c, 0xef, 0xae, 0x0e, 0xb0, 0x36, 0x21, 0x50, 0x4a, 0x5c, 0x84, 0x0b, 0xa2, 0x37, 0x85, - 0xbc, 0xbd, 0x8b, 0x0b, 0xec, 0x1c, 0x00, 0x4b, 0xa7, 0x49, 0x80, 0x7f, 0xf9, 0x98, 0x8f, 0xd5, 0x98, 0x53, 0xa3, - 0xeb, 0x77, 0xbf, 0x93, 0x6b, 0xa0, 0xb7, 0xa5, 0xa3, 0x60, 0xbf, 0x35, 0x80, 0x5c, 0xb8, 0x0b, 0x83, 0x8b, 0xaf, - 0xb0, 0xb6, 0x2c, 0x8c, 0x37, 0x16, 0x40, 0xef, 0x73, 0x06, 0x16, 0x6c, 0x98, 0x63, 0x0a, 0x8f, 0xd6, 0x4e, 0x98, - 0x0e, 0xa2, 0x82, 0x3c, 0x29, 0x9f, 0x25, 0xad, 0xd5, 0x7e, 0xcb, 0xc6, 0x70, 0x87, 0x91, 0x7c, 0xbb, 0x70, 0xe2, - 0xc0, 0x03, 0x32, 0x4d, 0x66, 0x9b, 0x7d, 0xe3, 0x23, 0x8f, 0xbc, 0x1e, 0xc7, 0xbb, 0x5a, 0x0a, 0xf3, 0xcd, 0x8a, - 0xae, 0x31, 0x84, 0xa2, 0x08, 0xfb, 0xfd, 0xaa, 0x62, 0x8a, 0x2a, 0x83, 0x36, 0x68, 0x58, 0xde, 0x88, 0x5f, 0xe0, - 0x8c, 0xa1, 0xf5, 0x42, 0xf6, 0x8e, 0xce, 0x3a, 0x9c, 0x39, 0xcc, 0x98, 0x12, 0x18, 0x95, 0x96, 0x05, 0x9d, 0x80, - 0xa3, 0x73, 0xf5, 0x41, 0x54, 0x5c, 0x1d, 0x2b, 0x00, 0x4f, 0x32, 0x85, 0x7f, 0xf2, 0x4d, 0xb0, 0xee, 0xb7, 0x6a, - 0x86, 0xa9, 0xbf, 0xe8, 0x6d, 0xd7, 0xf2, 0x65, 0x88, 0x23, 0x6d, 0x0c, 0xa1, 0x75, 0x6e, 0xef, 0x00, 0x45, 0x5c, - 0xd0, 0x8b, 0x54, 0xe3, 0x6b, 0xb5, 0x18, 0x9a, 0xf5, 0x35, 0xae, 0x63, 0xda, 0x20, 0x8a, 0x75, 0xd7, 0xc4, 0xd7, - 0xd5, 0x2b, 0xb0, 0x2a, 0x55, 0x70, 0x06, 0x09, 0x84, 0x55, 0x79, 0xd9, 0x90, 0x4a, 0x72, 0x69, 0x3a, 0x95, 0xa6, - 0xd3, 0x0a, 0xa1, 0x5c, 0x7a, 0x52, 0xde, 0xbf, 0x42, 0x08, 0x03, 0x53, 0x66, 0x07, 0x56, 0xa9, 0x2d, 0xac, 0x82, - 0x57, 0x2f, 0x36, 0xb0, 0x4a, 0xc2, 0xf1, 0x5c, 0xa2, 0x51, 0x51, 0xe1, 0x90, 0x21, 0x7d, 0x21, 0x16, 0x41, 0x02, - 0x60, 0xd1, 0xbb, 0xcc, 0xe5, 0x7d, 0x0f, 0x87, 0xc2, 0x9e, 0x64, 0x12, 0x4e, 0x37, 0xa1, 0x39, 0x3c, 0x0f, 0xac, - 0x7a, 0x1e, 0x21, 0x60, 0xe9, 0x39, 0x86, 0x67, 0xa1, 0xbf, 0xff, 0x1c, 0xad, 0xb3, 0x20, 0x4f, 0xff, 0x25, 0x4a, - 0x42, 0x63, 0xff, 0x39, 0x1e, 0x3a, 0x24, 0x0c, 0x07, 0xbe, 0x39, 0xc2, 0x0a, 0x07, 0xb7, 0x8a, 0xf8, 0x0c, 0xee, - 0xf0, 0xb1, 0x0e, 0x3d, 0x00, 0x2c, 0xa1, 0x38, 0x04, 0xf9, 0x06, 0x8a, 0x19, 0x1c, 0xd0, 0x64, 0x19, 0x5e, 0xe0, - 0x82, 0xd5, 0x42, 0x79, 0x7f, 0xdb, 0xf2, 0x52, 0x5a, 0xed, 0x92, 0xd7, 0x98, 0x03, 0x95, 0x9f, 0xe1, 0x85, 0xaf, - 0x30, 0xef, 0x55, 0xbb, 0x2f, 0x7c, 0xed, 0x80, 0x9e, 0x42, 0xc0, 0x48, 0xf7, 0x7b, 0x4d, 0xb8, 0xa7, 0xe8, 0x65, - 0x2e, 0x0e, 0xdb, 0x0e, 0xba, 0x17, 0x98, 0xab, 0xab, 0x2a, 0x6b, 0x0e, 0xa6, 0xd0, 0xe0, 0xa0, 0x0a, 0x67, 0x04, - 0xe6, 0xea, 0x45, 0x59, 0x70, 0x0e, 0xe2, 0x7d, 0x4f, 0x98, 0x9c, 0x32, 0x1a, 0xc0, 0x8b, 0xac, 0x7c, 0x74, 0xaa, - 0xc7, 0xc1, 0x65, 0xdc, 0xb0, 0x89, 0x2f, 0x84, 0x4f, 0x05, 0x56, 0xd2, 0x1a, 0x87, 0x46, 0x74, 0x44, 0xe7, 0x60, - 0xb6, 0x01, 0x14, 0xdc, 0x9d, 0x0f, 0x1b, 0x0b, 0x15, 0x3c, 0xc9, 0x5b, 0x7b, 0x41, 0x9b, 0x10, 0x67, 0xd2, 0x14, - 0xdc, 0x6d, 0x1b, 0x64, 0xf0, 0xe6, 0xb7, 0xff, 0x56, 0x58, 0x24, 0x18, 0x50, 0xa9, 0x49, 0x82, 0xf0, 0x04, 0xa5, - 0x91, 0x6e, 0xe5, 0x66, 0x02, 0xe9, 0x44, 0xd4, 0x8c, 0xba, 0x37, 0xce, 0x57, 0x47, 0x0d, 0x44, 0x45, 0x0d, 0x54, - 0x40, 0x0d, 0x64, 0x7d, 0xfb, 0x17, 0xb0, 0x10, 0x36, 0x42, 0x95, 0x08, 0x02, 0x22, 0xcc, 0xb5, 0xe1, 0x03, 0x8a, - 0x24, 0x84, 0xbc, 0x01, 0x54, 0x4c, 0xc9, 0x4b, 0x30, 0x1a, 0x87, 0xd7, 0x7b, 0xc0, 0xfd, 0xd2, 0x32, 0x0c, 0x9e, - 0x53, 0x30, 0xf9, 0x6f, 0x7d, 0x3e, 0x54, 0x2f, 0x57, 0x07, 0x21, 0xfc, 0x02, 0x62, 0x45, 0x38, 0xfe, 0xe2, 0x17, - 0x20, 0x9b, 0x0a, 0xcb, 0x83, 0x03, 0x09, 0x02, 0x3f, 0x44, 0x11, 0x0e, 0x78, 0x86, 0x97, 0xd9, 0x06, 0xd1, 0xf3, - 0xb3, 0x52, 0xd5, 0xac, 0x64, 0x30, 0xab, 0xc2, 0xd3, 0x38, 0xba, 0x26, 0x0c, 0x04, 0x17, 0x6a, 0xf7, 0x0d, 0x42, - 0xa0, 0x6c, 0xb9, 0x31, 0x74, 0xe9, 0x29, 0x98, 0x8f, 0xc6, 0xd1, 0x5b, 0x06, 0x0f, 0x0b, 0x1b, 0x93, 0x7f, 0xa6, - 0x59, 0xa6, 0x0d, 0xf3, 0xd8, 0x08, 0x9c, 0xd4, 0x29, 0x4a, 0x3e, 0x4b, 0x2e, 0xe2, 0xa8, 0x79, 0x19, 0xa1, 0x06, - 0xfc, 0xdb, 0xe0, 0xa8, 0x4b, 0x13, 0x3a, 0x1a, 0xf9, 0xe0, 0x37, 0x19, 0x31, 0x9b, 0x6c, 0xb5, 0x12, 0x15, 0x41, - 0x4f, 0xec, 0x06, 0x03, 0x56, 0xe2, 0x05, 0xb0, 0x0f, 0x96, 0x83, 0x25, 0xef, 0x44, 0xac, 0xfc, 0x29, 0x85, 0xc1, - 0xea, 0x39, 0x43, 0x08, 0x67, 0x41, 0xcc, 0xc6, 0xff, 0x7c, 0xa6, 0xe1, 0xfa, 0xf9, 0xf9, 0x3a, 0x46, 0x44, 0xfa, - 0x20, 0x72, 0x35, 0x76, 0x44, 0x04, 0x61, 0xcb, 0x74, 0xdf, 0x95, 0xf9, 0xc1, 0x5b, 0x57, 0x0f, 0x6c, 0xb8, 0x38, - 0x30, 0xa0, 0x46, 0x81, 0xd1, 0x0a, 0xce, 0x49, 0x39, 0x70, 0x50, 0x42, 0x68, 0x56, 0xc4, 0x53, 0x72, 0x09, 0x91, - 0xf0, 0x32, 0xd4, 0x05, 0xc3, 0x82, 0x40, 0x82, 0x9a, 0x82, 0x04, 0x95, 0xf9, 0xda, 0x23, 0x98, 0x75, 0x6e, 0x66, - 0x3b, 0x45, 0x5d, 0x17, 0xe4, 0xe7, 0x17, 0x1d, 0x8f, 0x80, 0xa5, 0x3d, 0x38, 0x28, 0x20, 0x82, 0x18, 0x50, 0xf0, - 0x52, 0x02, 0x0c, 0xc2, 0xf1, 0x15, 0x1b, 0x1a, 0xf0, 0xb9, 0x36, 0x5e, 0x07, 0xc6, 0xd6, 0xa7, 0x0c, 0x72, 0xf1, - 0xac, 0xda, 0xd3, 0x84, 0x90, 0xfd, 0x56, 0x4f, 0xa7, 0xdb, 0x11, 0x12, 0x7b, 0x1f, 0xb5, 0x09, 0x34, 0xe6, 0x48, - 0x77, 0xb5, 0x31, 0x5f, 0xd5, 0xf4, 0x88, 0xd5, 0x24, 0xa4, 0x0b, 0xd2, 0xe5, 0xf9, 0xb4, 0x67, 0x70, 0xc5, 0x2a, - 0x8d, 0x1c, 0x5c, 0x80, 0x3e, 0x1b, 0x10, 0xa0, 0x40, 0xa5, 0xa9, 0x44, 0x51, 0xc4, 0x45, 0x52, 0xb2, 0x61, 0x98, - 0x41, 0x98, 0xc2, 0x6a, 0x25, 0xe8, 0xc6, 0x1a, 0x00, 0xef, 0xcc, 0xec, 0x9f, 0xd2, 0x07, 0x9b, 0xae, 0xbd, 0x79, - 0x04, 0x10, 0x90, 0xfd, 0x76, 0xc9, 0xae, 0x8b, 0x8d, 0xca, 0x2c, 0xac, 0x65, 0x6c, 0xe5, 0xb6, 0x3d, 0xc6, 0xde, - 0x89, 0x6d, 0x3e, 0x01, 0x42, 0xd4, 0x96, 0x4c, 0x23, 0x44, 0x48, 0x2c, 0x62, 0x5d, 0x1b, 0xb2, 0xd1, 0x86, 0xc2, - 0x53, 0x89, 0x1c, 0xb8, 0x44, 0x13, 0x24, 0xdf, 0x71, 0x09, 0x0e, 0xe1, 0x85, 0x47, 0xf8, 0x5b, 0x60, 0x91, 0x0a, - 0xcc, 0xb0, 0x5c, 0xad, 0xa0, 0x9e, 0xc7, 0xfb, 0x6c, 0x33, 0x38, 0xa9, 0xdc, 0x18, 0xbb, 0xb4, 0x13, 0x8f, 0xcb, - 0x26, 0x24, 0xce, 0xa0, 0x5f, 0x5f, 0x11, 0xf5, 0xf6, 0xdb, 0xe9, 0x13, 0xff, 0x5e, 0x99, 0xdb, 0x81, 0xd8, 0xb0, - 0xde, 0x60, 0xf5, 0x01, 0xb4, 0xfc, 0x9f, 0xcc, 0x3f, 0x54, 0x16, 0xdc, 0x24, 0xa8, 0xcd, 0x45, 0xec, 0xb2, 0x2e, - 0x62, 0xa4, 0xb6, 0xb8, 0x3b, 0x84, 0xf8, 0x7f, 0xb6, 0xa2, 0x18, 0xf0, 0xa4, 0xe2, 0x9f, 0x63, 0xd4, 0x85, 0x50, - 0xd4, 0xd6, 0xc3, 0x06, 0x28, 0xed, 0x72, 0x5d, 0x89, 0x91, 0x21, 0x81, 0x7c, 0xeb, 0xc2, 0x0b, 0x9a, 0x93, 0x48, - 0x81, 0x9c, 0x1c, 0x44, 0x25, 0xcd, 0x36, 0x84, 0xb9, 0xee, 0x16, 0x8e, 0x99, 0xab, 0x0d, 0x5a, 0xc4, 0x2f, 0x80, - 0x9d, 0xe1, 0x46, 0xb2, 0x74, 0xe0, 0x53, 0x35, 0xf0, 0xf9, 0x35, 0x37, 0x14, 0x45, 0xa1, 0xde, 0x3b, 0xfb, 0xc8, - 0x1c, 0xfc, 0x4e, 0x03, 0xf1, 0x91, 0x3a, 0x1d, 0xc9, 0x46, 0xa8, 0x35, 0x67, 0xc7, 0xcb, 0x36, 0x23, 0x0c, 0x0a, - 0x1b, 0xbd, 0xaf, 0x42, 0x56, 0xb1, 0xb3, 0x53, 0x11, 0xcc, 0xe9, 0xab, 0xaa, 0x9c, 0x53, 0xb9, 0x65, 0x54, 0x4b, - 0x4d, 0x03, 0x44, 0xb8, 0xf2, 0x89, 0xe4, 0x51, 0x66, 0xc2, 0x3f, 0x18, 0x8c, 0xab, 0x47, 0x0a, 0x7f, 0xb4, 0x2b, - 0x76, 0xc8, 0x76, 0x74, 0xb8, 0x8d, 0xa0, 0x79, 0xa1, 0x82, 0x07, 0x1c, 0x95, 0x2c, 0x21, 0x52, 0xe4, 0x72, 0x5f, - 0xd5, 0x4c, 0xd9, 0xae, 0x23, 0x84, 0x90, 0xf6, 0x38, 0xeb, 0x86, 0x56, 0x0f, 0x3d, 0x52, 0x45, 0x39, 0xdc, 0xa2, - 0xb9, 0x2e, 0x40, 0x85, 0x11, 0x48, 0x97, 0x5f, 0xd8, 0x5d, 0x2a, 0x21, 0x7a, 0xf9, 0xda, 0x85, 0x30, 0x76, 0x56, - 0x96, 0xb8, 0x30, 0xa3, 0xb6, 0x61, 0x74, 0xdd, 0xc6, 0x70, 0x36, 0x30, 0x66, 0x1a, 0x94, 0xb4, 0x20, 0xd4, 0x75, - 0x97, 0x5e, 0x64, 0x26, 0xd0, 0x63, 0x4e, 0x68, 0x83, 0xe1, 0x29, 0xd1, 0x60, 0xd9, 0x54, 0x80, 0x05, 0xdf, 0xb2, - 0x48, 0xad, 0xcd, 0x26, 0x8b, 0x3f, 0xea, 0xd8, 0x3c, 0xed, 0x97, 0x57, 0xcc, 0x73, 0xe1, 0xa8, 0xdb, 0xf3, 0xcc, - 0xc7, 0xa3, 0x7b, 0xfa, 0xe6, 0xea, 0xc5, 0xcb, 0xd7, 0xaf, 0x56, 0xab, 0x36, 0x6b, 0xb6, 0x4f, 0xf0, 0x4f, 0xba, - 0x8c, 0x07, 0x5b, 0x46, 0x01, 0x3a, 0x38, 0xd8, 0xe7, 0xc6, 0x85, 0xe7, 0x0b, 0x9f, 0x43, 0xdc, 0x20, 0x3d, 0xc0, - 0x59, 0x51, 0xc6, 0x04, 0xb9, 0x8d, 0x7a, 0xd1, 0x5d, 0x04, 0x4a, 0xa8, 0x8a, 0xfc, 0x7d, 0xd8, 0x9c, 0xfd, 0x1e, - 0x04, 0x26, 0x82, 0xfa, 0x10, 0x01, 0x04, 0xe2, 0x95, 0xe2, 0x82, 0x30, 0x9f, 0x00, 0x51, 0xbc, 0x17, 0xc0, 0x99, - 0x9a, 0xa8, 0x55, 0x0b, 0x15, 0x17, 0x40, 0x12, 0x6d, 0x38, 0x4a, 0x7a, 0x64, 0x02, 0x78, 0x43, 0x50, 0x4a, 0xfb, - 0xab, 0x9b, 0x3b, 0x77, 0xa9, 0x1c, 0xf5, 0x5a, 0x69, 0x8e, 0xa7, 0xee, 0x73, 0x0a, 0x9f, 0xd3, 0xae, 0x3f, 0x1d, - 0xc4, 0x61, 0x8e, 0x17, 0x44, 0x1c, 0xfa, 0x67, 0x11, 0x97, 0xf3, 0x82, 0x7d, 0xe5, 0x72, 0xa1, 0xd2, 0xe5, 0x6d, - 0x2a, 0x93, 0xdb, 0xe6, 0xe8, 0x30, 0x2e, 0x92, 0xdb, 0xa6, 0x4a, 0x6e, 0x11, 0xbe, 0x4b, 0x65, 0x72, 0x67, 0x53, - 0xee, 0x9a, 0x0a, 0x6e, 0xbe, 0xb0, 0x80, 0x43, 0xd1, 0x16, 0x6d, 0x2c, 0x36, 0x8b, 0xda, 0x14, 0x57, 0x34, 0xc0, - 0xe0, 0xdf, 0x77, 0x6c, 0xfc, 0x30, 0x7c, 0x09, 0x2e, 0x4d, 0x9a, 0xc8, 0x4f, 0x20, 0xfd, 0xb4, 0x2a, 0x03, 0xf7, - 0x29, 0x69, 0x75, 0xa7, 0x17, 0xa2, 0xd9, 0xee, 0x36, 0x1a, 0x53, 0xd8, 0xbb, 0x19, 0xc9, 0x7d, 0xb1, 0x69, 0xc3, - 0xc4, 0xd7, 0xd9, 0xcf, 0x56, 0xab, 0xfd, 0x1c, 0x99, 0x0d, 0x37, 0x61, 0xb1, 0xee, 0x4f, 0x07, 0xb8, 0x85, 0x9f, - 0x67, 0x08, 0x2d, 0x59, 0x7f, 0x3a, 0x20, 0xac, 0x3f, 0x6d, 0xb4, 0x07, 0xd6, 0xd0, 0xce, 0x6c, 0xc5, 0x35, 0x84, - 0xd0, 0x9c, 0x0e, 0x8e, 0x4c, 0x49, 0xe9, 0xf2, 0xed, 0x17, 0xad, 0x02, 0xfa, 0xa9, 0x5a, 0xf0, 0x32, 0x89, 0x3b, - 0xd0, 0x17, 0xbd, 0xb0, 0x4f, 0xb7, 0x16, 0xe4, 0xf8, 0xa8, 0x72, 0xb5, 0xa7, 0x08, 0x9b, 0x9e, 0xd4, 0x61, 0x71, - 0x68, 0x9a, 0x71, 0x5d, 0x4a, 0xf7, 0x1d, 0x6a, 0x46, 0x3e, 0x3a, 0x58, 0x00, 0x82, 0x54, 0xf0, 0xc8, 0x0a, 0x17, - 0x4e, 0x29, 0x84, 0x8b, 0x83, 0xca, 0x16, 0x4c, 0x72, 0xd2, 0xea, 0xe6, 0xc6, 0xd2, 0x3f, 0x77, 0x11, 0x4d, 0x29, - 0xa6, 0x24, 0xf3, 0x25, 0x73, 0x03, 0x16, 0xba, 0x49, 0x79, 0xa6, 0xa0, 0x57, 0x1a, 0xe0, 0x11, 0x81, 0x78, 0x48, - 0xdd, 0xc2, 0x18, 0x78, 0xc5, 0xd3, 0x66, 0xd1, 0x67, 0x03, 0x74, 0x74, 0x8c, 0x69, 0xff, 0x53, 0x36, 0x6f, 0xc3, - 0x63, 0x81, 0x9f, 0x06, 0x64, 0xda, 0x94, 0x65, 0x82, 0x80, 0x84, 0x51, 0x53, 0x1e, 0xc2, 0x5e, 0x42, 0x38, 0xb3, - 0x15, 0xb3, 0x3e, 0x1b, 0x34, 0xa7, 0x65, 0xc5, 0x8e, 0xaf, 0xd8, 0x90, 0x65, 0x82, 0xad, 0xd8, 0x70, 0x15, 0xc3, - 0xd7, 0x19, 0x0c, 0x08, 0x42, 0x00, 0x30, 0x00, 0x80, 0x46, 0x41, 0x34, 0x5f, 0xac, 0x88, 0xdf, 0xec, 0xf6, 0x1e, - 0xbf, 0x05, 0x16, 0x68, 0xb5, 0xfd, 0xbf, 0x0b, 0x65, 0xc0, 0x9e, 0xb2, 0x30, 0x31, 0x73, 0x0b, 0xab, 0xa2, 0x03, - 0xa8, 0x94, 0x08, 0x53, 0x18, 0xc8, 0xec, 0x67, 0x06, 0x6a, 0x81, 0xd6, 0x20, 0xef, 0xeb, 0x41, 0x33, 0x83, 0x23, - 0x06, 0xde, 0xa1, 0x21, 0x53, 0x63, 0x4c, 0x18, 0xe7, 0x30, 0xc5, 0xcc, 0x80, 0x67, 0x9a, 0xb6, 0xd6, 0xd2, 0xc8, - 0x72, 0xbd, 0xbc, 0xf7, 0xb7, 0x8e, 0x55, 0xbf, 0x68, 0xb6, 0x07, 0x68, 0x9f, 0x10, 0xfb, 0x31, 0x80, 0x4d, 0xe6, - 0x52, 0x1b, 0xe6, 0xfb, 0xa8, 0x93, 0xda, 0x4f, 0xf8, 0x33, 0x58, 0x9b, 0x1d, 0x00, 0x3a, 0x32, 0x6c, 0xd6, 0x5f, - 0xd6, 0x54, 0x5e, 0x1f, 0x77, 0x46, 0xa9, 0xdc, 0xf5, 0xee, 0x74, 0xa0, 0x29, 0x0e, 0xbd, 0xf5, 0x70, 0xf9, 0x50, - 0x0f, 0x01, 0x33, 0x06, 0x73, 0xcb, 0x8c, 0xbe, 0x17, 0x22, 0xb9, 0x20, 0x12, 0x4b, 0x83, 0x35, 0x0c, 0xf6, 0xd6, - 0xc1, 0x81, 0xa9, 0xc6, 0x1a, 0xf0, 0x3c, 0x29, 0x02, 0xc1, 0xc0, 0x47, 0x50, 0x06, 0x34, 0x51, 0xe6, 0x36, 0x9c, - 0x7c, 0x64, 0xee, 0x17, 0x2e, 0x6f, 0x1f, 0x0b, 0xa7, 0x6d, 0x35, 0xd7, 0xe3, 0x65, 0x81, 0xbb, 0xf2, 0x5e, 0xd2, - 0x2a, 0xb8, 0x91, 0xbd, 0xc9, 0x53, 0xe6, 0x6e, 0xdd, 0x97, 0xea, 0xec, 0x6e, 0xa6, 0x53, 0x36, 0xd3, 0xd9, 0x6e, - 0x26, 0xd4, 0xcc, 0x7c, 0xcb, 0x2a, 0xd2, 0x9c, 0xac, 0x89, 0x9a, 0x53, 0xf1, 0x13, 0x9d, 0x83, 0x76, 0x94, 0xdb, - 0x7b, 0x55, 0x38, 0xb9, 0x72, 0x72, 0xb9, 0x9f, 0x1b, 0xe2, 0x8a, 0xcc, 0x85, 0x3a, 0x04, 0x78, 0x79, 0x51, 0x3e, - 0x3e, 0xc0, 0xa5, 0xf8, 0x55, 0x8e, 0x5c, 0x94, 0x53, 0x21, 0xb5, 0x14, 0x2c, 0x42, 0x06, 0x55, 0x5d, 0x0c, 0xec, - 0xa5, 0xdd, 0x7b, 0xa2, 0xc7, 0xfb, 0x55, 0xc4, 0xbc, 0x81, 0x79, 0xee, 0xe3, 0x7b, 0x9a, 0x62, 0xa7, 0x26, 0xce, - 0xc8, 0x87, 0x2c, 0xce, 0x41, 0x36, 0xeb, 0x57, 0xaf, 0xfd, 0x36, 0xda, 0xb8, 0x68, 0xc6, 0xa2, 0x67, 0x9e, 0x38, - 0xf9, 0xa1, 0x30, 0xc6, 0x01, 0xd6, 0xd1, 0x1f, 0x61, 0x6a, 0xc1, 0x9e, 0x25, 0x9e, 0x42, 0x27, 0xb7, 0x36, 0xed, - 0x2e, 0x4c, 0xbb, 0x33, 0x69, 0x1d, 0x28, 0x07, 0xa4, 0xd9, 0x95, 0xe9, 0xdc, 0xf9, 0xef, 0x3b, 0x78, 0xe9, 0x76, - 0x0d, 0x91, 0xb8, 0xe7, 0x8f, 0x8c, 0x31, 0xc4, 0x1b, 0xb0, 0x11, 0x55, 0x07, 0x07, 0x7f, 0x38, 0xef, 0xdb, 0x4a, - 0xee, 0xfb, 0x56, 0x38, 0xb0, 0x0d, 0xa6, 0xd2, 0xe5, 0x8d, 0x64, 0xb6, 0x00, 0xbb, 0xce, 0xfd, 0x6f, 0xc4, 0xc3, - 0x17, 0x21, 0xd3, 0x62, 0x5d, 0xc5, 0x5f, 0xc9, 0x51, 0xe9, 0x21, 0xaa, 0x21, 0x02, 0x69, 0x65, 0x5d, 0x1a, 0x9a, - 0x8e, 0x5e, 0x4d, 0xe9, 0x48, 0xde, 0xbc, 0x95, 0x52, 0x0f, 0xec, 0x8b, 0xdc, 0x3a, 0x81, 0x47, 0x0b, 0x6b, 0x0c, - 0xcd, 0x5d, 0xe9, 0x9d, 0x64, 0x03, 0xa2, 0xd6, 0xc7, 0x1d, 0x4a, 0x22, 0xb1, 0xa8, 0xee, 0x42, 0x38, 0xdc, 0x85, - 0x60, 0x5e, 0x06, 0x6d, 0x83, 0xd8, 0xed, 0x2e, 0x68, 0x1b, 0x38, 0x75, 0xdb, 0xc0, 0xed, 0xc1, 0x60, 0x61, 0xef, - 0xc3, 0xcb, 0xb1, 0x1c, 0x0b, 0x7f, 0x4d, 0x66, 0x1f, 0x00, 0x02, 0xb5, 0x0f, 0x2b, 0x9e, 0x38, 0x10, 0x24, 0xce, - 0x70, 0xf4, 0x3d, 0x67, 0x37, 0xd6, 0x72, 0x78, 0x36, 0x5f, 0x68, 0x36, 0x32, 0x77, 0xd4, 0xa0, 0xe2, 0xab, 0xfb, - 0x79, 0xfd, 0x94, 0xd5, 0x74, 0xe3, 0xf7, 0x20, 0x8c, 0x84, 0x53, 0x76, 0x18, 0x85, 0x84, 0x0d, 0x66, 0x55, 0xc6, - 0x6b, 0xfb, 0x0d, 0xe2, 0x3d, 0x68, 0x13, 0x4e, 0xb0, 0xa8, 0x5d, 0x50, 0x45, 0xd8, 0xc6, 0x1b, 0x0b, 0xa2, 0x3c, - 0xbc, 0xd9, 0x32, 0x9a, 0x5e, 0xae, 0x21, 0xd0, 0x71, 0x2f, 0x6a, 0x46, 0x0d, 0x96, 0xba, 0xa0, 0xcc, 0x3e, 0xc2, - 0xb8, 0xba, 0x38, 0x31, 0x71, 0xda, 0x4b, 0xbd, 0xfa, 0x6f, 0x19, 0x18, 0xe0, 0x0b, 0xf0, 0x12, 0x0b, 0xa3, 0xbb, - 0xf6, 0x75, 0x03, 0xea, 0xcb, 0x06, 0x1b, 0xa0, 0xd5, 0xaa, 0x55, 0x3e, 0x03, 0xe5, 0xae, 0xb9, 0x84, 0xbd, 0xe6, - 0x12, 0xee, 0x9a, 0x4b, 0xf8, 0x6b, 0x2e, 0x61, 0xae, 0xb9, 0x84, 0xbf, 0xe6, 0xf2, 0x20, 0xfc, 0x33, 0x88, 0xe3, - 0x18, 0x73, 0x88, 0xab, 0xa8, 0x6d, 0x64, 0x3c, 0xb8, 0xf0, 0xdc, 0x67, 0x89, 0x2a, 0x97, 0x3f, 0x8c, 0x21, 0xb7, - 0x65, 0x2b, 0x61, 0xdc, 0xa6, 0x98, 0x82, 0xc8, 0xe9, 0x07, 0x07, 0xa5, 0xbb, 0x33, 0xf8, 0xa8, 0xa7, 0x1c, 0x2f, - 0xad, 0x13, 0xed, 0x1f, 0xa0, 0x93, 0x37, 0xbf, 0x3e, 0xa6, 0x72, 0x4d, 0x84, 0x33, 0xb9, 0xdf, 0x6f, 0x7b, 0x4a, - 0xf1, 0x67, 0x66, 0xc2, 0x93, 0xf3, 0x44, 0x1b, 0x11, 0x04, 0x21, 0x4a, 0x14, 0xce, 0x88, 0xfc, 0x7f, 0xd9, 0x7b, - 0xd7, 0xe5, 0xb6, 0x91, 0x2c, 0x5d, 0xf4, 0x55, 0x24, 0x86, 0xcd, 0x02, 0xcc, 0x24, 0x45, 0x79, 0xef, 0x99, 0x88, - 0x03, 0x2a, 0xc5, 0xf0, 0xa5, 0xdc, 0xe5, 0xee, 0xf2, 0xa5, 0x2d, 0x77, 0x75, 0x55, 0x33, 0x78, 0x58, 0x10, 0x90, - 0x14, 0xe0, 0x02, 0x01, 0x16, 0x00, 0x4a, 0xa4, 0x49, 0xbc, 0xfb, 0x8e, 0xb5, 0x56, 0x5e, 0x41, 0x50, 0x76, 0xcf, - 0xec, 0xf9, 0x75, 0xce, 0x1f, 0x5b, 0x4c, 0x24, 0x12, 0x79, 0xcf, 0x95, 0xeb, 0xf2, 0x7d, 0xb4, 0xde, 0x55, 0x28, - 0x3c, 0xaa, 0xa2, 0x94, 0x5b, 0xc9, 0xab, 0x0c, 0x82, 0xd8, 0xd1, 0x0b, 0xc3, 0x9f, 0x40, 0x08, 0x41, 0x84, 0x09, - 0xbf, 0x0e, 0x33, 0xda, 0xce, 0x22, 0x9d, 0xf4, 0xdb, 0x30, 0xc3, 0x0d, 0xac, 0xe4, 0xe7, 0xaa, 0xcf, 0xf6, 0xdb, - 0x20, 0x64, 0xbb, 0x20, 0x62, 0xb7, 0xc5, 0x36, 0x28, 0x6d, 0x5f, 0x10, 0x65, 0xf8, 0x5b, 0x7a, 0xbd, 0x3c, 0x84, - 0x78, 0x9f, 0x5e, 0x9a, 0x9f, 0xa5, 0xad, 0x28, 0xc0, 0x7d, 0x84, 0x1e, 0xd5, 0x81, 0x60, 0x27, 0x3c, 0xe1, 0x01, - 0x9c, 0xac, 0x66, 0x15, 0x7f, 0x92, 0x82, 0x38, 0x51, 0x70, 0x08, 0xb8, 0xda, 0xde, 0xa4, 0x5f, 0xc1, 0xf0, 0xa5, - 0x83, 0x2d, 0x87, 0xb7, 0xc5, 0xb6, 0xc7, 0x4a, 0xfe, 0x11, 0xd8, 0xb7, 0x7a, 0x32, 0x56, 0xb7, 0x07, 0xce, 0xba, - 0x94, 0xa2, 0xe3, 0x4d, 0x71, 0x78, 0x7b, 0x3e, 0xdb, 0x6f, 0x83, 0x88, 0xed, 0x82, 0x0c, 0x6b, 0x9d, 0x34, 0xfc, - 0xaf, 0xb4, 0x75, 0xb0, 0x18, 0x61, 0xff, 0x97, 0xf5, 0xc0, 0x4b, 0x48, 0x0d, 0x05, 0x2e, 0x06, 0x1b, 0x8e, 0xd6, - 0x76, 0x99, 0x06, 0x6e, 0x6a, 0xd0, 0xeb, 0x7b, 0x0a, 0x51, 0x5e, 0x32, 0x9a, 0x1b, 0xc1, 0xba, 0x31, 0xe4, 0xe2, - 0x70, 0xdc, 0x2c, 0x87, 0xbc, 0xa4, 0xe9, 0x34, 0x08, 0xa5, 0x3b, 0xcb, 0x1a, 0x92, 0x28, 0xfb, 0x20, 0xd4, 0xae, - 0x2d, 0xfb, 0x6d, 0x60, 0xfb, 0xf2, 0x47, 0xc3, 0xd8, 0xbf, 0x58, 0x3e, 0x13, 0xd2, 0x45, 0x3c, 0x07, 0x41, 0xd4, - 0x7e, 0x9e, 0x0d, 0x37, 0xfe, 0xc5, 0xfa, 0x99, 0x50, 0x7e, 0xe3, 0xb9, 0x2d, 0x87, 0xd4, 0x59, 0x0b, 0x5f, 0x18, - 0x0f, 0x0f, 0xae, 0x0c, 0x6d, 0x87, 0x83, 0xd0, 0x7f, 0x9b, 0x35, 0x82, 0x1b, 0x1b, 0xda, 0xe7, 0x0b, 0x1f, 0xb6, - 0x36, 0x1a, 0x6b, 0x8a, 0xe9, 0x16, 0xfa, 0x37, 0x99, 0x2d, 0xed, 0x69, 0x54, 0xf2, 0xe2, 0xd4, 0x34, 0x62, 0x21, - 0x0c, 0x18, 0xfa, 0xc9, 0x7c, 0x04, 0xd5, 0xdc, 0xf1, 0x08, 0x64, 0xf2, 0x81, 0x1e, 0xac, 0x49, 0xad, 0xfa, 0x6b, - 0x98, 0xc9, 0xff, 0x23, 0x15, 0x16, 0xa3, 0xbb, 0x6d, 0x98, 0xa9, 0x3f, 0x22, 0xf9, 0x07, 0xcb, 0xf9, 0x2e, 0xf5, - 0x42, 0xed, 0xc7, 0xc2, 0x0a, 0x0c, 0x4a, 0x54, 0x0d, 0xe8, 0x81, 0x08, 0xaa, 0x32, 0x48, 0x33, 0xac, 0xce, 0x41, - 0xbf, 0x7b, 0x5a, 0x75, 0x24, 0x87, 0xb4, 0x56, 0x43, 0x2a, 0x98, 0x2a, 0x35, 0xc8, 0x0f, 0x87, 0xbb, 0x94, 0xe9, - 0x32, 0xe0, 0x92, 0x7e, 0x97, 0x2a, 0xa5, 0xf0, 0x9f, 0x08, 0x40, 0xe7, 0xe0, 0x1e, 0x5f, 0x8e, 0x81, 0x34, 0xc3, - 0xc2, 0x6f, 0xcd, 0x8e, 0xaf, 0x49, 0xb8, 0x4d, 0x82, 0x8b, 0x01, 0xce, 0xd1, 0x55, 0x58, 0xde, 0xa5, 0x10, 0x41, - 0x55, 0x42, 0x7d, 0x2b, 0xd3, 0xa0, 0xb4, 0xd5, 0x20, 0xac, 0x49, 0xa8, 0x33, 0xc9, 0x46, 0xa5, 0xed, 0x46, 0x61, - 0xb6, 0x88, 0xeb, 0x19, 0x61, 0xcd, 0xd9, 0x4c, 0x35, 0x30, 0x69, 0x38, 0x6e, 0x1a, 0xad, 0x45, 0x85, 0x9a, 0xc2, - 0xbc, 0xc6, 0x55, 0xa5, 0xaa, 0xbb, 0x39, 0xb5, 0x94, 0x96, 0xed, 0x55, 0x37, 0xc9, 0x86, 0x5c, 0x86, 0x32, 0x0c, - 0x36, 0x72, 0x04, 0x13, 0x48, 0x92, 0x33, 0x7f, 0x23, 0xff, 0x50, 0x9b, 0xae, 0x05, 0xcc, 0x31, 0x66, 0xd9, 0xb0, - 0xa0, 0x57, 0xe0, 0x1e, 0x68, 0xa5, 0xe7, 0xd3, 0xec, 0x22, 0x0f, 0x92, 0x61, 0xa1, 0x97, 0x4d, 0xc6, 0xff, 0x14, - 0x46, 0x9a, 0xcc, 0x58, 0xc9, 0x22, 0xdb, 0xd5, 0x29, 0x71, 0x1e, 0x27, 0xb0, 0x3d, 0x9a, 0xde, 0xf2, 0x7d, 0x06, - 0x51, 0x41, 0xa0, 0x60, 0xc6, 0x7c, 0xd9, 0xc5, 0x73, 0xdf, 0x67, 0x96, 0xa9, 0xfb, 0x70, 0x30, 0x66, 0x6c, 0xbf, - 0xdf, 0xcf, 0xfb, 0x7d, 0x35, 0xdf, 0xfa, 0xfd, 0xe4, 0xda, 0xfc, 0xed, 0x01, 0x83, 0x82, 0x9c, 0x88, 0xa6, 0x42, - 0x04, 0xff, 0x90, 0x3c, 0x43, 0x32, 0xba, 0xe3, 0x3e, 0xb7, 0x9c, 0x2d, 0xab, 0x23, 0x10, 0xcc, 0xc3, 0xe1, 0x52, - 0x81, 0x5d, 0x4b, 0x14, 0x09, 0x59, 0xfe, 0x33, 0x30, 0x9e, 0xb9, 0x0f, 0xb0, 0x64, 0x00, 0xc2, 0x56, 0x79, 0xba, - 0xde, 0xf3, 0x55, 0xf0, 0x4e, 0xc7, 0xbb, 0xc6, 0x8a, 0x0c, 0xc4, 0x2d, 0xb0, 0x11, 0x6b, 0xed, 0x01, 0x39, 0x53, - 0x80, 0xe3, 0xc5, 0xe1, 0x70, 0x2e, 0x7f, 0xe9, 0x66, 0xeb, 0x04, 0x2a, 0x05, 0x6e, 0x8f, 0x4e, 0x0e, 0xfe, 0x3b, - 0xd0, 0x0c, 0xca, 0x61, 0x5e, 0x6f, 0x7f, 0x67, 0x4e, 0x7e, 0x7a, 0x8a, 0x7f, 0xc2, 0x43, 0x74, 0xfa, 0xed, 0xde, - 0xfc, 0x41, 0x51, 0x79, 0x38, 0xa8, 0xc5, 0x7f, 0xce, 0x79, 0x05, 0xbf, 0xf0, 0x4d, 0x60, 0x36, 0x99, 0x7a, 0x27, - 0xdf, 0xe4, 0x39, 0x53, 0xaf, 0xf1, 0x8a, 0xc9, 0x77, 0x38, 0x9c, 0x8b, 0x51, 0xbd, 0x1d, 0x39, 0xd1, 0x4e, 0x39, - 0xc6, 0xc1, 0xe0, 0xbf, 0x88, 0xb6, 0x09, 0x01, 0x86, 0xd4, 0x2d, 0x69, 0x66, 0xe3, 0xca, 0x12, 0xcf, 0xd2, 0xf9, - 0xe5, 0xa4, 0x2e, 0x77, 0x5a, 0xf1, 0xb4, 0x07, 0x16, 0xb7, 0x35, 0x78, 0x01, 0xdc, 0x5b, 0x6c, 0x5d, 0x29, 0x38, - 0x5c, 0x40, 0x9c, 0xe2, 0x04, 0x44, 0xd0, 0x7e, 0x5f, 0xe2, 0xbd, 0x82, 0x3e, 0xe9, 0x47, 0x08, 0x86, 0xfc, 0x59, - 0x02, 0xee, 0x7a, 0xbd, 0x1a, 0xe3, 0x7b, 0x29, 0x04, 0xd7, 0x67, 0x1a, 0x80, 0x16, 0xfc, 0x2e, 0x1f, 0xcb, 0xe9, - 0x37, 0x11, 0x78, 0xb6, 0xec, 0x4d, 0x94, 0xbb, 0x0d, 0x4f, 0xfb, 0x47, 0x0b, 0x01, 0x58, 0x8a, 0x67, 0x4a, 0xb0, - 0x20, 0xa7, 0x98, 0x8b, 0xff, 0x17, 0x7c, 0xc4, 0x7c, 0x4f, 0xba, 0x88, 0xad, 0xb7, 0x4f, 0x2e, 0x0c, 0x24, 0xd0, - 0x74, 0x00, 0x7e, 0xbc, 0x0a, 0xe8, 0xca, 0xf8, 0xf9, 0x59, 0xd6, 0x63, 0x7d, 0xfc, 0xa7, 0xe0, 0x3e, 0xfd, 0x4c, - 0xe1, 0xa3, 0xc3, 0x71, 0x95, 0x8e, 0x76, 0x94, 0x82, 0xe8, 0xe8, 0xf6, 0xf9, 0x94, 0x67, 0xdf, 0x55, 0x40, 0x6e, - 0x39, 0x6a, 0x4f, 0x05, 0x60, 0xb1, 0xa5, 0x23, 0xf0, 0x69, 0x96, 0x4f, 0xc8, 0xf7, 0x7a, 0x2a, 0xae, 0x2e, 0x75, - 0xba, 0xb8, 0x1e, 0x4f, 0xe1, 0x7f, 0x20, 0xf6, 0xb0, 0x4c, 0x91, 0x1d, 0xbb, 0x2e, 0x7e, 0x10, 0x6f, 0x6b, 0x3b, - 0xfa, 0x63, 0x07, 0x91, 0x8e, 0x7b, 0x72, 0xa1, 0xbe, 0x84, 0x54, 0x72, 0xa1, 0x6e, 0x20, 0x76, 0xa1, 0xc6, 0x3b, - 0x2e, 0x62, 0xad, 0xbf, 0xab, 0x51, 0xb0, 0x12, 0x70, 0xa6, 0xbd, 0x03, 0x83, 0x0d, 0xac, 0x5b, 0x96, 0xc1, 0xdf, - 0x70, 0x4d, 0x13, 0xb8, 0x61, 0x91, 0xf5, 0xde, 0x60, 0x2b, 0xbd, 0x03, 0x47, 0xcb, 0xc4, 0xb9, 0x94, 0x64, 0x65, - 0x8b, 0x8c, 0xab, 0x47, 0x21, 0x55, 0xd3, 0xfd, 0xad, 0xa8, 0x1f, 0x84, 0xc8, 0x83, 0x55, 0xca, 0xa2, 0x62, 0x05, - 0x32, 0x7b, 0xf0, 0xf7, 0x90, 0x91, 0xa3, 0x1c, 0x38, 0x0a, 0xfd, 0xbd, 0x09, 0x74, 0x9e, 0xbf, 0x86, 0x3a, 0x8f, - 0x04, 0x5b, 0xa9, 0x87, 0xc2, 0xca, 0x0b, 0x88, 0x0e, 0xb6, 0x30, 0x56, 0x79, 0x12, 0x2a, 0x36, 0x65, 0x22, 0x8f, - 0x83, 0x5a, 0x02, 0xc6, 0x0a, 0x82, 0x39, 0xcb, 0xa5, 0x0b, 0x52, 0xd5, 0xe8, 0x61, 0x91, 0xb9, 0x9f, 0x0a, 0xca, - 0xff, 0x54, 0xe5, 0x84, 0xeb, 0xcb, 0x10, 0xe0, 0x68, 0x9f, 0x82, 0x28, 0x31, 0xd6, 0x2f, 0x5a, 0xbc, 0x93, 0x99, - 0xb3, 0xa9, 0xed, 0x25, 0xc8, 0xd8, 0x0e, 0xbf, 0x42, 0x68, 0xb5, 0x50, 0x64, 0xd1, 0x70, 0xc1, 0x74, 0x7b, 0x4a, - 0xab, 0xee, 0x61, 0xc3, 0xb3, 0xd2, 0x43, 0xa5, 0xbe, 0x8d, 0x09, 0x2c, 0xab, 0x94, 0xe1, 0xdb, 0x09, 0x55, 0x27, - 0x06, 0x15, 0xeb, 0x86, 0x2d, 0xe1, 0x10, 0x8b, 0x49, 0x63, 0x9d, 0x0d, 0x78, 0xc4, 0x12, 0xf8, 0x67, 0xc3, 0xc7, - 0x6c, 0xc9, 0xa3, 0xc9, 0xe6, 0x6a, 0xd9, 0xef, 0x97, 0x5e, 0xe8, 0xd5, 0xb3, 0xec, 0x69, 0x34, 0x9f, 0xe5, 0x73, - 0x1f, 0x15, 0x17, 0x93, 0xc1, 0x60, 0xe3, 0x67, 0xc3, 0x21, 0x4b, 0x86, 0xc3, 0x49, 0xf6, 0x14, 0x5e, 0x7b, 0xca, - 0x23, 0xb5, 0xa4, 0x92, 0xab, 0x0c, 0xf6, 0xf7, 0x01, 0x8f, 0x7c, 0xd6, 0xf9, 0x69, 0xd9, 0x74, 0xe9, 0x7e, 0x66, - 0x75, 0x40, 0xa9, 0x3b, 0xc0, 0xc6, 0xdb, 0x06, 0x1d, 0xf9, 0xb7, 0x3b, 0xa4, 0xd4, 0x4d, 0x06, 0x60, 0x37, 0x1a, - 0xe0, 0x90, 0xa9, 0x5e, 0x8a, 0xac, 0x5e, 0xca, 0x54, 0x2f, 0xc9, 0xca, 0x25, 0x58, 0x48, 0x4c, 0x95, 0xdb, 0xc8, - 0xca, 0x2d, 0x1b, 0xae, 0x87, 0x83, 0xad, 0x15, 0x97, 0xcd, 0x1d, 0xdc, 0x17, 0x56, 0x14, 0xf8, 0x7f, 0xcb, 0x16, - 0xec, 0x5e, 0x1e, 0x03, 0xef, 0xd0, 0x31, 0x09, 0x2e, 0x10, 0xf7, 0xec, 0x16, 0xec, 0xb0, 0xf0, 0x17, 0x5c, 0x27, - 0xc7, 0x6c, 0x87, 0x8f, 0x42, 0xaf, 0x60, 0xb7, 0x3e, 0x01, 0xed, 0x82, 0xad, 0x01, 0xb2, 0xb1, 0x2d, 0x3e, 0xba, - 0x3b, 0x1c, 0xde, 0x79, 0x3e, 0x7b, 0xc0, 0x1f, 0xe7, 0x77, 0x87, 0xc3, 0xce, 0x33, 0xea, 0xbd, 0x1b, 0x9e, 0xb0, - 0x0f, 0x3c, 0x99, 0xdc, 0x5c, 0xf1, 0x78, 0x32, 0x18, 0xdc, 0xf8, 0x0b, 0x5e, 0xcf, 0x6e, 0x40, 0x3b, 0x70, 0xbe, - 0x90, 0xba, 0x66, 0xef, 0x96, 0x67, 0xde, 0x02, 0xc7, 0xe6, 0x16, 0x8e, 0xde, 0x7e, 0xdf, 0xbb, 0xe3, 0x91, 0x77, - 0x4b, 0x2a, 0xa6, 0x15, 0x57, 0x1c, 0x6f, 0x5b, 0xdc, 0x4f, 0x57, 0x3c, 0x84, 0x47, 0x58, 0x95, 0xe9, 0x4d, 0xf0, - 0xc1, 0x67, 0x2b, 0xcd, 0x02, 0xf7, 0x80, 0x39, 0xd6, 0x64, 0x27, 0x34, 0x13, 0x7f, 0x85, 0xfd, 0x73, 0xa3, 0xfa, - 0x87, 0xe6, 0x7f, 0xa9, 0xfb, 0x09, 0xdc, 0xbe, 0xc8, 0x82, 0xc4, 0x3e, 0xf0, 0x1b, 0x76, 0xcf, 0x0d, 0xdb, 0xec, - 0x99, 0x29, 0xfb, 0x44, 0xa9, 0xf1, 0x23, 0xa5, 0xae, 0x2d, 0xc3, 0x4a, 0xe6, 0xee, 0xcb, 0x08, 0x1c, 0x0e, 0xc8, - 0x4f, 0x77, 0x88, 0x83, 0xd0, 0xba, 0xc9, 0x6a, 0xae, 0x28, 0xe7, 0x42, 0x5b, 0x66, 0x5e, 0x0e, 0x2c, 0x66, 0x29, - 0x85, 0xc6, 0x02, 0x00, 0xc1, 0xa4, 0xd0, 0xda, 0x7b, 0x19, 0x40, 0x4e, 0xd0, 0xf0, 0xc7, 0xe6, 0xaa, 0x28, 0x6b, - 0xd9, 0x92, 0x10, 0x65, 0xbb, 0x1e, 0x5e, 0x22, 0x64, 0x5a, 0xbf, 0x7f, 0x4e, 0x24, 0x6b, 0x93, 0xea, 0xaa, 0x46, - 0x4b, 0x40, 0x45, 0x96, 0x80, 0x89, 0x5f, 0x69, 0x3e, 0x01, 0x78, 0xd2, 0xf1, 0xa0, 0x7a, 0xca, 0x6b, 0x26, 0x88, - 0x6c, 0xa3, 0xf2, 0x27, 0xc5, 0x35, 0x92, 0x11, 0x14, 0x4f, 0x6b, 0x95, 0xb1, 0x30, 0xcc, 0x03, 0x05, 0xe4, 0xdd, - 0xbb, 0x53, 0xdf, 0xda, 0x1f, 0x3b, 0xf6, 0x6c, 0xad, 0x42, 0x2d, 0xd4, 0x14, 0x2e, 0x39, 0x44, 0x57, 0x90, 0x81, - 0x42, 0xc6, 0x93, 0xd7, 0x83, 0xcb, 0x49, 0x74, 0xc5, 0x05, 0x3a, 0xe3, 0xeb, 0x9b, 0x6e, 0x3a, 0x8b, 0x9e, 0x56, - 0xf3, 0x09, 0x29, 0xc9, 0x0e, 0x87, 0x6c, 0x54, 0xd5, 0xc5, 0x7a, 0x1a, 0xca, 0x9f, 0x1e, 0x82, 0xaf, 0x17, 0xd4, - 0x6b, 0xb2, 0x4a, 0xf5, 0x53, 0xaa, 0x94, 0x17, 0x0d, 0x2f, 0xfd, 0xa7, 0x95, 0xdc, 0xf7, 0x80, 0xb4, 0x96, 0x97, - 0x5c, 0xbe, 0x1f, 0x21, 0xc6, 0x88, 0x1f, 0x78, 0x25, 0x8f, 0x58, 0xa8, 0xa6, 0x70, 0xcd, 0x23, 0x04, 0x79, 0xcb, - 0x74, 0xf0, 0xb7, 0x9e, 0x38, 0xdd, 0x9f, 0x28, 0xed, 0xe2, 0x0b, 0x8b, 0xba, 0x27, 0x6b, 0xeb, 0x06, 0xe4, 0x60, - 0xc3, 0x74, 0x51, 0x90, 0x6d, 0x4a, 0x23, 0x68, 0xa3, 0xe5, 0xc0, 0x86, 0x53, 0xa9, 0x0d, 0x67, 0xae, 0x21, 0xb8, - 0xcf, 0xcf, 0xd3, 0xd1, 0x02, 0x3e, 0xa4, 0xba, 0xbd, 0xc4, 0xcf, 0x87, 0x0d, 0x8f, 0x80, 0xcc, 0x8e, 0xf8, 0xcc, - 0x26, 0x92, 0x4e, 0xea, 0x5c, 0x01, 0xbb, 0x9d, 0xbd, 0x03, 0x39, 0x62, 0xe6, 0xbe, 0x42, 0xf5, 0x2d, 0x1a, 0x70, - 0x65, 0xac, 0x7d, 0x4d, 0x32, 0x16, 0x5e, 0x95, 0xd3, 0x70, 0x00, 0x30, 0x74, 0x19, 0x7d, 0x6d, 0xb9, 0xc9, 0xb2, - 0x9f, 0x0b, 0x08, 0x82, 0x28, 0x89, 0xc7, 0x07, 0xbc, 0x2f, 0xab, 0xa1, 0x46, 0xc9, 0xc7, 0xb2, 0x91, 0x4a, 0xaf, - 0x44, 0x7f, 0x37, 0xe6, 0x12, 0x03, 0xbe, 0xab, 0xda, 0x82, 0xc2, 0x79, 0x7e, 0x38, 0x9c, 0xe7, 0x23, 0xe3, 0x59, - 0x06, 0xaa, 0x95, 0x69, 0x1d, 0xc4, 0x66, 0xbe, 0x58, 0xf8, 0x8b, 0x9d, 0x93, 0x88, 0x28, 0x08, 0xec, 0x48, 0x78, - 0x10, 0xa9, 0x5f, 0x55, 0x9e, 0xee, 0x54, 0x9f, 0xed, 0x17, 0x36, 0x91, 0x5e, 0x50, 0x32, 0xf9, 0x24, 0xd8, 0xab, - 0xfe, 0x0e, 0xc2, 0x86, 0xf0, 0xe6, 0x55, 0xaf, 0xb3, 0x4c, 0xcd, 0x4a, 0x90, 0x30, 0x63, 0x8e, 0xe0, 0x71, 0xd8, - 0x69, 0x6c, 0xc3, 0x63, 0x0b, 0x8e, 0xce, 0x5b, 0xb3, 0x3b, 0xb6, 0x62, 0xb7, 0xaa, 0x4e, 0x0b, 0x1e, 0x4e, 0x87, - 0x97, 0x01, 0xae, 0xbe, 0xf5, 0x39, 0xe7, 0x77, 0x74, 0x82, 0xad, 0x07, 0x3c, 0x9a, 0x88, 0xd9, 0xfa, 0x69, 0xa4, - 0x16, 0xcf, 0x7a, 0xc8, 0x17, 0xb4, 0xfe, 0xc4, 0xec, 0xce, 0x24, 0xdf, 0x0d, 0xf8, 0x62, 0xb2, 0x7e, 0x1a, 0xc1, - 0xab, 0x4f, 0xc1, 0x8a, 0x91, 0x39, 0xb3, 0x6c, 0xfd, 0x34, 0xc2, 0x31, 0xbb, 0x7b, 0x1a, 0xd1, 0xa8, 0xad, 0xe4, - 0xbe, 0x74, 0xdb, 0x80, 0xb0, 0x72, 0xcb, 0x62, 0x78, 0x0d, 0xc4, 0x33, 0x6d, 0x24, 0x5d, 0x4b, 0x43, 0x6f, 0xcc, - 0xc3, 0x69, 0x1c, 0xac, 0xa9, 0x15, 0xf2, 0xcc, 0x10, 0xb3, 0xf8, 0x69, 0x34, 0x67, 0x2b, 0xac, 0xc8, 0x86, 0xc7, - 0x83, 0xcb, 0xc9, 0xe6, 0x8a, 0xaf, 0x81, 0xfc, 0x6c, 0xb2, 0x31, 0x5b, 0xd4, 0x2d, 0x17, 0xb3, 0xcd, 0xd3, 0x68, - 0x3e, 0x59, 0x41, 0xcf, 0xda, 0x03, 0xe6, 0xbd, 0x01, 0x11, 0x4a, 0x42, 0x6a, 0xca, 0x4d, 0xaf, 0xc7, 0xd6, 0xe3, - 0xe0, 0x8e, 0xad, 0x2f, 0x83, 0x5b, 0xb6, 0x1e, 0x03, 0x11, 0x07, 0xf5, 0xbb, 0xb7, 0x81, 0xc5, 0x17, 0xb1, 0xf5, - 0xa5, 0x49, 0xdb, 0x3c, 0x8d, 0x98, 0x3b, 0x38, 0x0d, 0x5c, 0xb0, 0x36, 0x99, 0xb7, 0x62, 0x70, 0x09, 0x59, 0x7a, - 0x31, 0xdb, 0x0c, 0x2f, 0xd9, 0x7a, 0x84, 0x53, 0x3d, 0xf1, 0xd9, 0x1d, 0xbf, 0x65, 0x09, 0x5f, 0x35, 0xf1, 0xd5, - 0x06, 0x34, 0xa2, 0x47, 0x19, 0xf4, 0x15, 0xd4, 0xcc, 0x9c, 0x57, 0x16, 0x46, 0xe5, 0xbe, 0x05, 0x07, 0x14, 0xa4, - 0x6d, 0x80, 0x20, 0x89, 0x67, 0xf7, 0x2a, 0x5c, 0xdf, 0x48, 0x61, 0xc0, 0x4d, 0x60, 0x06, 0x0c, 0x4c, 0x3f, 0x83, - 0x1f, 0x56, 0xba, 0x44, 0x88, 0xb3, 0x9f, 0x52, 0x92, 0xcc, 0xf3, 0xd7, 0x22, 0xcd, 0xdd, 0xc2, 0x75, 0x0a, 0xb3, - 0xa2, 0x40, 0xf5, 0x53, 0x52, 0x1a, 0x58, 0xa8, 0x44, 0xa6, 0x52, 0xf0, 0xcb, 0xe6, 0x3c, 0xca, 0x8e, 0xd1, 0xb9, - 0xce, 0x2f, 0x27, 0xce, 0xe9, 0xa4, 0xef, 0x3f, 0x70, 0x0c, 0x5b, 0xc8, 0xc0, 0x85, 0x3f, 0xf5, 0x84, 0x71, 0x6a, - 0x05, 0x62, 0x2a, 0x79, 0xf6, 0x14, 0x3e, 0x13, 0x5a, 0x1d, 0x5d, 0xf8, 0x7e, 0x50, 0x68, 0x93, 0x74, 0x0b, 0x92, - 0x14, 0x3c, 0x45, 0xcf, 0x39, 0x6f, 0x03, 0x95, 0x62, 0x44, 0x0b, 0x22, 0x6d, 0x2d, 0x33, 0x07, 0x69, 0x4b, 0xf3, - 0x5d, 0x13, 0x3f, 0x87, 0x05, 0x5c, 0x44, 0x0b, 0x5b, 0xc3, 0xa3, 0x2a, 0x56, 0xee, 0x4d, 0x9e, 0x23, 0x9c, 0xd1, - 0xa5, 0x4c, 0x00, 0x5c, 0xef, 0xd7, 0x61, 0xad, 0xf0, 0x8a, 0x9a, 0x45, 0x5e, 0xd4, 0xf4, 0xc9, 0x16, 0xb8, 0x8f, - 0x45, 0x89, 0x02, 0x67, 0x2d, 0x18, 0xb0, 0x15, 0x96, 0xec, 0xa4, 0xb0, 0x29, 0x5a, 0x42, 0x6f, 0x8f, 0x9f, 0x0e, - 0x6a, 0x26, 0x03, 0x68, 0x02, 0x68, 0x3c, 0xfe, 0x05, 0xa0, 0xa6, 0x37, 0xb5, 0x58, 0x57, 0x41, 0xa9, 0x94, 0x9b, - 0xf0, 0x33, 0x30, 0xcc, 0xf0, 0x43, 0x21, 0xb7, 0x89, 0x12, 0x39, 0x3f, 0x16, 0xa5, 0x58, 0x96, 0xa2, 0x4a, 0xda, - 0x0d, 0x05, 0x8f, 0x08, 0xb7, 0x41, 0x63, 0xe6, 0xf6, 0x44, 0x17, 0xad, 0x08, 0xe5, 0xd8, 0xac, 0x63, 0xa4, 0x51, - 0x66, 0x27, 0xbb, 0x4e, 0x16, 0xda, 0xef, 0xab, 0x1c, 0xb2, 0x0e, 0x58, 0x23, 0xf9, 0x7a, 0xcd, 0xa1, 0xdb, 0x46, - 0x79, 0xf1, 0xe0, 0xf9, 0x0a, 0x4e, 0x73, 0x3c, 0xb1, 0xbb, 0x5e, 0x77, 0x8a, 0x44, 0xbc, 0xc2, 0x49, 0x95, 0x8f, - 0x64, 0xe1, 0xb8, 0x73, 0xa7, 0xb5, 0x58, 0x55, 0x2e, 0xeb, 0xa9, 0xc5, 0x11, 0x81, 0x4f, 0xe5, 0xd1, 0x5e, 0x68, - 0x5b, 0x14, 0x0b, 0x61, 0xf4, 0xe8, 0x84, 0x9f, 0x94, 0xc0, 0xfa, 0x3a, 0x1c, 0x96, 0x7e, 0xc4, 0xd1, 0xef, 0x34, - 0x1a, 0x2d, 0x08, 0x69, 0x78, 0xea, 0x45, 0xa3, 0x45, 0x5d, 0xd4, 0x61, 0x76, 0x9d, 0xeb, 0x81, 0xc2, 0x30, 0x02, - 0xf5, 0x83, 0xab, 0x0c, 0x3e, 0x8b, 0x10, 0x35, 0x0f, 0x4c, 0xb3, 0x21, 0x1c, 0x75, 0x81, 0x87, 0x56, 0xd0, 0x62, - 0x66, 0x3e, 0x0a, 0x31, 0x7c, 0x48, 0x17, 0xe7, 0x4f, 0xc8, 0xca, 0x07, 0xd8, 0x1d, 0xba, 0x0b, 0xe5, 0x9c, 0xa9, - 0x18, 0xe0, 0x47, 0x01, 0xf9, 0x28, 0x01, 0x37, 0x03, 0x64, 0x8f, 0x2c, 0x01, 0xc4, 0x8a, 0xd1, 0xd1, 0xe4, 0x73, - 0xdf, 0x8b, 0x14, 0xbc, 0xb3, 0xcf, 0x72, 0x35, 0x61, 0x28, 0x7c, 0x62, 0xa0, 0x9b, 0xdf, 0xf8, 0xed, 0x79, 0x0b, - 0x46, 0x76, 0x49, 0x8a, 0xd7, 0x9a, 0xe1, 0x7e, 0x03, 0x6e, 0x47, 0x40, 0x59, 0x53, 0x1d, 0x93, 0x6c, 0xd3, 0x10, - 0xc9, 0x80, 0x19, 0x31, 0x22, 0xa8, 0x2c, 0x17, 0xfe, 0x77, 0x2f, 0x8b, 0x02, 0x07, 0x70, 0x35, 0x93, 0xc1, 0x6b, - 0x17, 0x46, 0x05, 0xc0, 0x39, 0x0d, 0x9d, 0xd2, 0x5e, 0x55, 0x1d, 0x92, 0x55, 0xf3, 0x83, 0xd9, 0xbc, 0x69, 0x98, - 0x18, 0x11, 0x44, 0x17, 0xe1, 0x04, 0xd3, 0x2b, 0xd2, 0xd7, 0x4a, 0x4e, 0x47, 0xab, 0x8e, 0xd6, 0x12, 0x13, 0x73, - 0x45, 0xf1, 0xd7, 0x80, 0xc7, 0x0d, 0x5e, 0x9d, 0xa4, 0xe9, 0x44, 0xf5, 0xe8, 0xf1, 0xeb, 0x34, 0x9d, 0x94, 0xb8, - 0x2b, 0xfc, 0x06, 0x5c, 0x34, 0xdb, 0x7c, 0xe8, 0xc7, 0x2f, 0x28, 0xe2, 0xa2, 0x06, 0x57, 0xde, 0xa9, 0xbe, 0x52, - 0x7d, 0x04, 0xb5, 0xf0, 0xc4, 0xc8, 0x5a, 0x78, 0x72, 0xc9, 0x5a, 0x0b, 0x82, 0x99, 0xcd, 0x81, 0x0b, 0xf9, 0x95, - 0x52, 0xc4, 0x9b, 0x48, 0xa8, 0xc5, 0xa0, 0xf5, 0x98, 0x39, 0xab, 0x46, 0x0b, 0x95, 0x19, 0xa1, 0x7d, 0x5b, 0x8b, - 0xce, 0x6f, 0xe4, 0xa7, 0x3c, 0xb5, 0x2f, 0xdb, 0xe3, 0x7c, 0xbc, 0x47, 0x77, 0xd5, 0x59, 0x66, 0x52, 0xc6, 0x27, - 0xb3, 0x04, 0x85, 0xbb, 0x04, 0x1b, 0x90, 0x64, 0xbf, 0xd5, 0x01, 0x32, 0x6a, 0xaf, 0xfd, 0xae, 0xb3, 0x7c, 0x75, - 0xb3, 0x35, 0x14, 0x95, 0x5a, 0x49, 0x8a, 0x83, 0x0c, 0xd7, 0x6d, 0xe5, 0xc3, 0xc5, 0x05, 0xf4, 0x8c, 0x91, 0xc8, - 0x3c, 0x7f, 0x22, 0x5f, 0x82, 0x73, 0xc6, 0x59, 0x21, 0x30, 0x61, 0xac, 0xde, 0xb5, 0x96, 0x4a, 0x43, 0x8a, 0xb1, - 0xa3, 0x51, 0x96, 0x55, 0x96, 0x2e, 0xb3, 0xb5, 0x84, 0x2d, 0xab, 0xc8, 0x2d, 0x6c, 0x99, 0xc9, 0x6a, 0x7e, 0xa8, - 0xb8, 0x83, 0xf2, 0xcd, 0xd6, 0x19, 0xdf, 0x4b, 0x64, 0xef, 0x36, 0x50, 0xc2, 0xf5, 0xe8, 0x3f, 0x90, 0x7e, 0x9b, - 0x61, 0x9c, 0x72, 0x5b, 0x49, 0x0b, 0x70, 0xfa, 0x87, 0xc3, 0x87, 0x0a, 0x83, 0x06, 0x47, 0x18, 0x47, 0xd6, 0xef, - 0xdf, 0x56, 0x5e, 0x8d, 0x89, 0x3a, 0x3e, 0xab, 0xdf, 0xaf, 0xe8, 0xe1, 0xb4, 0x1a, 0xad, 0xd2, 0x2d, 0xb2, 0x13, - 0xda, 0x58, 0xf9, 0x41, 0xad, 0x80, 0xd9, 0x5b, 0x9f, 0x4f, 0x07, 0xa0, 0x63, 0x01, 0x12, 0xcd, 0x66, 0x22, 0x31, - 0x27, 0xdd, 0x93, 0xf0, 0xf8, 0xc0, 0x02, 0x07, 0x98, 0x8a, 0xff, 0x43, 0x78, 0x33, 0xb0, 0x41, 0xa3, 0x44, 0x5f, - 0xa3, 0xab, 0xda, 0xdc, 0xe8, 0x78, 0xe9, 0x29, 0x24, 0xb2, 0x82, 0x55, 0x73, 0x5f, 0x6e, 0xe0, 0xb4, 0x87, 0x9a, - 0x43, 0x65, 0x09, 0xfe, 0xf6, 0xcb, 0xfc, 0x70, 0x58, 0x67, 0x50, 0xd8, 0x6e, 0x2d, 0xb4, 0x37, 0x66, 0xa9, 0x86, - 0x8a, 0x70, 0xd0, 0xf9, 0x4a, 0xcc, 0xea, 0x11, 0xfd, 0x3d, 0x3f, 0x1c, 0x56, 0x04, 0x06, 0x1c, 0x96, 0x32, 0x13, - 0x2d, 0x14, 0x4b, 0xeb, 0x6c, 0x46, 0x75, 0xe0, 0x81, 0x89, 0x39, 0x0b, 0x77, 0x00, 0xda, 0xa4, 0x56, 0x81, 0x5e, - 0x45, 0xf4, 0x13, 0xf7, 0x6b, 0xfb, 0xf5, 0x7a, 0x64, 0x96, 0x8e, 0xdc, 0x18, 0x0b, 0x00, 0x0e, 0x3c, 0xaf, 0x49, - 0x9e, 0x93, 0xaf, 0xa1, 0xdd, 0x93, 0x0b, 0xf9, 0x13, 0x94, 0x2d, 0x3c, 0x57, 0x4d, 0x2b, 0x8b, 0x15, 0x57, 0xd5, - 0xab, 0x0b, 0x5e, 0x99, 0x4c, 0xab, 0xb4, 0x12, 0x95, 0x12, 0x0c, 0xa8, 0x4b, 0xbc, 0xd6, 0x34, 0xa3, 0xd4, 0x46, - 0x9d, 0x89, 0x1a, 0xb0, 0xc1, 0x7e, 0xaa, 0x36, 0x3a, 0x39, 0x97, 0xcf, 0x2f, 0x8d, 0xc3, 0xa7, 0x5d, 0xbd, 0x99, - 0xa9, 0x1c, 0xf8, 0x6b, 0xe5, 0x43, 0xab, 0xc7, 0x40, 0x07, 0xe4, 0xf4, 0xc7, 0xb0, 0x98, 0xd8, 0x1d, 0x9a, 0xb7, - 0xbb, 0xcb, 0xea, 0x22, 0xbd, 0xd3, 0x94, 0xcc, 0xea, 0x2d, 0x9f, 0x59, 0x3d, 0x3a, 0xe0, 0xc5, 0x63, 0xbd, 0x57, - 0x98, 0x49, 0x04, 0x17, 0x43, 0x35, 0x89, 0xec, 0x0e, 0xb4, 0xe6, 0x51, 0xc5, 0x04, 0xf8, 0x41, 0xa9, 0x35, 0xbd, - 0xb7, 0xbb, 0x42, 0x9d, 0x52, 0x78, 0xdc, 0x5a, 0xf2, 0x03, 0x73, 0xa7, 0x5d, 0xeb, 0x7c, 0x3c, 0xbf, 0xf4, 0xfd, - 0x46, 0x9e, 0xd0, 0x66, 0x67, 0x72, 0xfa, 0x27, 0x6f, 0xf5, 0x0f, 0x53, 0x7d, 0x0b, 0xdd, 0x09, 0xfa, 0x0c, 0x5d, - 0x55, 0xdd, 0x95, 0xd8, 0xc2, 0x50, 0x4f, 0x2c, 0xf2, 0x42, 0x9e, 0xb4, 0xc6, 0x8e, 0x83, 0xbd, 0x01, 0x4e, 0xfc, - 0xf2, 0x70, 0x10, 0x57, 0xb9, 0xcf, 0xce, 0xbb, 0x46, 0x56, 0x0e, 0x60, 0x05, 0x51, 0x30, 0x6e, 0xcd, 0xc7, 0x36, - 0x48, 0x97, 0xb8, 0x1a, 0x1f, 0xbf, 0xa1, 0x58, 0x26, 0x9b, 0x88, 0x8b, 0x8b, 0xfc, 0xe9, 0x73, 0x20, 0x2d, 0xeb, - 0xf7, 0xa3, 0xeb, 0xcb, 0xe9, 0xf3, 0x61, 0x14, 0x80, 0x63, 0x97, 0xbd, 0xbc, 0x8c, 0xf9, 0xea, 0x92, 0x59, 0xa6, - 0xb0, 0xc8, 0x37, 0x03, 0xaa, 0x4b, 0x56, 0x4b, 0xd7, 0x2b, 0xc0, 0xd2, 0xe5, 0x37, 0x0f, 0x61, 0x6a, 0x40, 0x23, - 0x6b, 0xee, 0x4e, 0x73, 0x2d, 0x50, 0xea, 0x79, 0x3f, 0x33, 0xe4, 0xeb, 0x32, 0xe8, 0x0a, 0xd2, 0x3d, 0x8f, 0x48, - 0x2f, 0xf7, 0xd2, 0xe9, 0x7e, 0x5f, 0x0a, 0xb0, 0xd4, 0x97, 0xe2, 0x0b, 0x28, 0x2c, 0x1a, 0xdf, 0x08, 0xd0, 0xd6, - 0x50, 0x4d, 0x7b, 0xa5, 0xa8, 0x7a, 0x41, 0xaf, 0x14, 0x5f, 0x7a, 0x7a, 0xa8, 0xcc, 0x97, 0xa5, 0xa3, 0xff, 0x09, - 0x35, 0x17, 0x9c, 0x10, 0x33, 0x31, 0x07, 0x50, 0x09, 0xda, 0xf8, 0x56, 0x47, 0x1b, 0x9f, 0xea, 0x55, 0xdc, 0xf4, - 0x79, 0x6d, 0x2d, 0x73, 0x42, 0xd8, 0x74, 0x2f, 0x01, 0x2a, 0xf2, 0x4a, 0x78, 0x04, 0xcb, 0x2f, 0x7f, 0xc8, 0xd3, - 0x15, 0xa2, 0x75, 0xdc, 0xb3, 0xcc, 0xa5, 0xb1, 0x7f, 0x63, 0x30, 0x7d, 0x7d, 0xbb, 0x2d, 0xf2, 0x53, 0x13, 0x13, - 0xd6, 0x63, 0x45, 0xdf, 0xbc, 0x0f, 0x57, 0x02, 0x05, 0x0e, 0x25, 0x12, 0xdb, 0x54, 0xa1, 0x88, 0x07, 0x49, 0x9f, - 0x2e, 0x5a, 0x9f, 0x06, 0x98, 0x5a, 0xcb, 0x81, 0x39, 0x84, 0xab, 0xb8, 0xf0, 0xd1, 0xd3, 0xb7, 0x98, 0x85, 0xf3, - 0x89, 0xf7, 0xc9, 0x2b, 0x46, 0xe6, 0xe3, 0x3e, 0x2a, 0x95, 0xf4, 0xcf, 0xc3, 0x61, 0x56, 0xcd, 0x7d, 0x87, 0x3e, - 0xd2, 0x43, 0x95, 0x0b, 0xca, 0xde, 0x18, 0x93, 0x08, 0x94, 0xc6, 0x78, 0x1f, 0x07, 0xc7, 0x79, 0x9f, 0x06, 0x90, - 0xda, 0x27, 0x3e, 0x90, 0x92, 0xc3, 0x73, 0x8e, 0x39, 0xa1, 0xb4, 0x22, 0xac, 0xe2, 0x8b, 0x0c, 0xe5, 0xba, 0x53, - 0x0a, 0x26, 0x39, 0x24, 0x18, 0xfe, 0xaa, 0x79, 0x13, 0x2b, 0x10, 0x76, 0xcd, 0xbc, 0x1a, 0x3d, 0xa9, 0x92, 0xb0, - 0x14, 0x70, 0x54, 0x66, 0x9e, 0x61, 0x6f, 0x78, 0x62, 0x18, 0x39, 0x58, 0xee, 0x8f, 0xea, 0x44, 0xe4, 0x1e, 0x5d, - 0x60, 0x54, 0x16, 0x9e, 0x37, 0x74, 0xa5, 0x41, 0x25, 0xd9, 0xf1, 0x57, 0x5c, 0x03, 0x6a, 0x6b, 0x8c, 0x18, 0x0a, - 0x18, 0x05, 0xaf, 0xed, 0x0f, 0x21, 0x8b, 0xb2, 0xf5, 0x1b, 0x1c, 0xf3, 0x59, 0xc9, 0x5d, 0xef, 0x70, 0x16, 0x5a, - 0x42, 0x9e, 0xdc, 0x31, 0x48, 0xd3, 0x58, 0x1a, 0x01, 0x27, 0x22, 0xd9, 0xc6, 0x52, 0x38, 0x02, 0x08, 0x08, 0x74, - 0x53, 0x66, 0x18, 0xd3, 0xc1, 0xc8, 0xf3, 0xa4, 0x67, 0xbc, 0x57, 0xe1, 0x29, 0xa4, 0xc9, 0xf6, 0xf5, 0xfc, 0xbd, - 0x11, 0x64, 0xe5, 0x96, 0x73, 0x3c, 0x2c, 0xbe, 0x71, 0xf6, 0x55, 0x4e, 0x9e, 0x62, 0x96, 0x91, 0xde, 0x29, 0xe6, - 0x05, 0xfc, 0xa9, 0x2c, 0xf5, 0x39, 0x4a, 0x6f, 0x99, 0x4f, 0x56, 0x91, 0x74, 0xe9, 0x6d, 0xfa, 0xfd, 0x78, 0xa4, - 0x0e, 0x35, 0x7f, 0x1f, 0x8f, 0xe4, 0x19, 0xb6, 0x61, 0x09, 0x0b, 0xad, 0x82, 0x31, 0x80, 0x24, 0x36, 0x22, 0x1a, - 0x8c, 0xf6, 0xe6, 0x70, 0x38, 0xdf, 0x98, 0xb3, 0x64, 0x0f, 0xae, 0xaf, 0x3c, 0x31, 0xef, 0xc0, 0x97, 0x79, 0x4c, - 0x10, 0xb1, 0x99, 0xb7, 0x61, 0x35, 0x78, 0xb0, 0x83, 0xeb, 0x23, 0xb6, 0x28, 0xd6, 0x3a, 0x96, 0xca, 0x3a, 0x38, - 0xad, 0x63, 0xd3, 0x8c, 0x94, 0x22, 0xfb, 0x1c, 0xfb, 0x7b, 0x37, 0xb8, 0xba, 0x36, 0x06, 0xb5, 0xc6, 0x1d, 0xe6, - 0xce, 0xa9, 0x80, 0x7a, 0x4c, 0x57, 0x50, 0x3d, 0xab, 0xc8, 0x97, 0xdf, 0xda, 0x39, 0x20, 0x68, 0x04, 0x02, 0x17, - 0x0d, 0xb4, 0x6a, 0x97, 0x72, 0xde, 0x05, 0x84, 0xf8, 0x2e, 0x05, 0x7d, 0x3a, 0x83, 0x4d, 0x6c, 0x3e, 0x81, 0x58, - 0x34, 0xdd, 0xe7, 0x5a, 0x33, 0x5f, 0x8c, 0x68, 0x67, 0xd6, 0xdd, 0x22, 0xb7, 0x5a, 0x88, 0x64, 0xf4, 0x6c, 0x33, - 0xe1, 0xa2, 0x43, 0x39, 0x23, 0x01, 0x13, 0xb4, 0xb6, 0x52, 0xf2, 0xb9, 0xee, 0x75, 0x82, 0xf6, 0x40, 0xd2, 0xba, - 0x7f, 0xb3, 0xe8, 0x8c, 0x92, 0x93, 0xeb, 0x4d, 0xce, 0x20, 0x05, 0x0b, 0xb6, 0x97, 0x39, 0xe1, 0x06, 0xf8, 0xc4, - 0x66, 0xc9, 0x69, 0x1a, 0xe4, 0xb1, 0x30, 0x1e, 0x79, 0x6d, 0x7e, 0x59, 0x40, 0x87, 0x92, 0x45, 0x23, 0xc4, 0x03, - 0xec, 0x1c, 0x92, 0xab, 0x02, 0x75, 0xd3, 0x40, 0x57, 0xae, 0x9c, 0x29, 0xa6, 0xc0, 0x85, 0x50, 0x10, 0xb5, 0xa3, - 0x93, 0xa8, 0x9c, 0xf7, 0x49, 0x75, 0x99, 0x4f, 0x0b, 0x69, 0x1a, 0xc8, 0xa7, 0x95, 0x63, 0x1e, 0xd8, 0xd9, 0xc6, - 0x35, 0x81, 0x81, 0x4e, 0xed, 0x6b, 0x51, 0xce, 0xb1, 0x8a, 0xe8, 0x7d, 0xfe, 0xb1, 0xb2, 0xa7, 0x0f, 0x22, 0x6c, - 0x54, 0xa0, 0xb1, 0x94, 0x18, 0x1b, 0x39, 0xfe, 0x2d, 0x51, 0x36, 0x64, 0x08, 0x08, 0x21, 0x6d, 0xe4, 0xf4, 0xc3, - 0xfa, 0xf2, 0x36, 0xd3, 0xfe, 0x9f, 0x24, 0x7e, 0x1b, 0xec, 0xe5, 0xd4, 0x9f, 0x7a, 0xc4, 0xe3, 0xb5, 0x46, 0x8f, - 0x29, 0xe9, 0x36, 0xc8, 0x53, 0xe5, 0x29, 0x48, 0x26, 0x8c, 0x25, 0x04, 0x8b, 0x72, 0xc1, 0x73, 0x5e, 0x71, 0x09, - 0xf7, 0x51, 0xcb, 0x8a, 0x08, 0x55, 0x89, 0x9c, 0x3e, 0x5f, 0x01, 0xcf, 0x04, 0x04, 0x3a, 0xc6, 0x48, 0xa3, 0x0a, - 0xbe, 0x04, 0xc6, 0x3a, 0x50, 0x76, 0x9a, 0x91, 0xe0, 0xb2, 0x7b, 0x83, 0x44, 0xa9, 0xaf, 0x49, 0x49, 0xfa, 0x4e, - 0xd4, 0x78, 0x25, 0x56, 0x11, 0x09, 0x64, 0xa8, 0x21, 0x62, 0x55, 0x3d, 0x75, 0xaf, 0x8a, 0xc9, 0x60, 0x50, 0xf9, - 0x72, 0x7a, 0xe2, 0x0d, 0x0d, 0x95, 0x77, 0x5d, 0xd1, 0x4e, 0x4f, 0xb4, 0x52, 0xde, 0x42, 0x5a, 0x82, 0xa6, 0x61, - 0xa4, 0x39, 0x94, 0xba, 0x92, 0xee, 0xc6, 0x20, 0xbe, 0x64, 0xa2, 0x67, 0x3b, 0xb5, 0xa3, 0xb4, 0x25, 0xed, 0x21, - 0xa4, 0xe7, 0x2e, 0xf9, 0x98, 0x85, 0x5c, 0xdd, 0x29, 0x27, 0xe5, 0x55, 0x88, 0x4e, 0xee, 0x7b, 0x0c, 0x89, 0x40, - 0x9f, 0x73, 0x0c, 0xeb, 0xa2, 0xa1, 0xce, 0x61, 0x85, 0x98, 0x2d, 0x94, 0x30, 0x5f, 0x32, 0x9e, 0x4a, 0x06, 0x0d, - 0x80, 0x0c, 0xf8, 0xe2, 0x65, 0x60, 0xf9, 0x2b, 0x88, 0x1f, 0x6d, 0x7c, 0x38, 0xfc, 0x59, 0x53, 0x88, 0xed, 0x9f, - 0xb0, 0x19, 0xc2, 0xa3, 0x7a, 0xc0, 0x33, 0xdf, 0xc4, 0x09, 0x5a, 0x01, 0x49, 0x99, 0x1d, 0x4d, 0x64, 0xaf, 0x7a, - 0x08, 0xa7, 0xb2, 0x02, 0x75, 0x94, 0x75, 0x56, 0xc2, 0x8f, 0x30, 0xd5, 0xad, 0xc4, 0x5a, 0xa0, 0xcd, 0xd5, 0x8a, - 0xb5, 0x00, 0x0e, 0xfc, 0x1c, 0x82, 0x27, 0xf2, 0x39, 0xb8, 0x18, 0x14, 0xe0, 0x73, 0x00, 0xbc, 0xc8, 0x5d, 0x78, - 0x30, 0x8f, 0x2c, 0xab, 0x11, 0x86, 0xa3, 0x8a, 0x58, 0xbf, 0x66, 0x3b, 0xf2, 0x81, 0xdb, 0x31, 0x3e, 0xd7, 0x1e, - 0x4b, 0x96, 0x83, 0x51, 0xe6, 0x5e, 0x2d, 0xd1, 0xf3, 0x26, 0x8d, 0x9b, 0xd1, 0x93, 0x7d, 0x2d, 0xff, 0x17, 0xf4, - 0x32, 0xe8, 0x6f, 0xe1, 0x96, 0xd7, 0xfc, 0x6e, 0x41, 0xa4, 0x99, 0x5e, 0x41, 0xa4, 0x8c, 0x1a, 0x91, 0x31, 0x84, - 0x4d, 0xaa, 0x9b, 0xdb, 0xa4, 0xba, 0x10, 0xf0, 0x74, 0x44, 0xaa, 0x6b, 0x21, 0x6d, 0xe4, 0xd3, 0x3a, 0x90, 0xb1, - 0x48, 0xef, 0x7f, 0xfc, 0xcb, 0x8b, 0xcf, 0x6f, 0x7f, 0xf9, 0x71, 0xf1, 0xf6, 0xfd, 0x9b, 0xb7, 0xef, 0xdf, 0x7e, - 0xfe, 0x8d, 0x20, 0x3c, 0xa6, 0x42, 0x65, 0xf8, 0xf8, 0xe1, 0xe6, 0xad, 0x93, 0xc1, 0xf6, 0x66, 0xc8, 0xda, 0x37, - 0x72, 0x30, 0x04, 0x22, 0x1b, 0x84, 0x0c, 0xb2, 0x53, 0x32, 0xc7, 0x4c, 0xcc, 0x31, 0xf6, 0x4e, 0x60, 0xb2, 0x05, - 0x9c, 0x63, 0x99, 0x97, 0x8c, 0xc8, 0x55, 0xa1, 0xf5, 0x03, 0x5a, 0xf0, 0x0e, 0x5c, 0x64, 0xd2, 0xfc, 0xee, 0x17, - 0x82, 0xd8, 0xa7, 0x95, 0x94, 0xfb, 0x6a, 0x5b, 0xf3, 0x7c, 0x7b, 0xbf, 0x97, 0x70, 0xfe, 0x73, 0x69, 0x44, 0x2d, - 0xc0, 0x01, 0xf8, 0x1c, 0xfe, 0xb8, 0xd2, 0x96, 0x34, 0x99, 0x45, 0xfb, 0x19, 0x43, 0xd0, 0xa5, 0xc1, 0x07, 0xb1, - 0x47, 0x5e, 0xea, 0x93, 0x85, 0x04, 0xee, 0x88, 0xe1, 0xd3, 0x8a, 0xa0, 0x57, 0x8c, 0x28, 0x2e, 0xb9, 0x42, 0xa5, - 0x94, 0xfc, 0x1b, 0x65, 0x17, 0x15, 0x72, 0x56, 0xb0, 0x7b, 0x45, 0x8e, 0x8c, 0x1f, 0x04, 0x13, 0x5f, 0x0e, 0xee, - 0xbf, 0xc4, 0x3b, 0x9c, 0x29, 0x8e, 0xe4, 0x84, 0x3f, 0x64, 0x18, 0xd8, 0x9f, 0x83, 0xcf, 0xab, 0xc3, 0xbc, 0xbc, - 0xd1, 0xa7, 0xdc, 0x92, 0x8f, 0x27, 0xcb, 0x2b, 0x30, 0xd8, 0x2f, 0x55, 0x73, 0xd7, 0xbc, 0x9e, 0x2d, 0xe7, 0x6c, - 0x3f, 0x8b, 0xe6, 0xc1, 0x1d, 0x9b, 0x65, 0xf3, 0x60, 0xd5, 0xf0, 0x35, 0xbb, 0xe5, 0x6b, 0xab, 0x6a, 0x6b, 0xbb, - 0x6a, 0x93, 0x0d, 0xbf, 0x05, 0x09, 0xe1, 0x26, 0xf3, 0x80, 0xf7, 0xf8, 0xce, 0x67, 0x1b, 0x90, 0x68, 0x57, 0x6c, - 0x03, 0x17, 0xb1, 0x35, 0xff, 0xb1, 0xf2, 0x36, 0xac, 0x64, 0xe7, 0x63, 0x96, 0xe3, 0xfc, 0xf3, 0xe1, 0x01, 0xed, - 0x85, 0xfa, 0xd9, 0xa5, 0x7a, 0x36, 0x51, 0x76, 0xb3, 0xcd, 0x68, 0x71, 0x9f, 0x56, 0x9b, 0x30, 0x43, 0xcf, 0x72, - 0xf8, 0x68, 0x2b, 0x05, 0x3f, 0xbd, 0xc0, 0x2f, 0xd9, 0x51, 0x5b, 0x69, 0xdb, 0xae, 0x4a, 0x6c, 0x05, 0x2d, 0x8a, - 0xac, 0x56, 0x78, 0x60, 0xce, 0xaf, 0x61, 0x01, 0x63, 0xcf, 0x71, 0xce, 0x6b, 0x7f, 0x84, 0x8c, 0xf7, 0x0e, 0x00, - 0x5a, 0xe6, 0x38, 0xc0, 0x23, 0x56, 0x8c, 0xa2, 0xc1, 0x3b, 0xbf, 0x54, 0x56, 0x2b, 0xcd, 0x49, 0x68, 0x1b, 0xb1, - 0x6a, 0x39, 0x52, 0x35, 0x23, 0xd2, 0x07, 0xe9, 0x79, 0xdf, 0x23, 0xaa, 0xc1, 0x9e, 0xcc, 0xeb, 0xc0, 0x3e, 0xbd, - 0x6a, 0xad, 0xea, 0xce, 0xef, 0xa9, 0xd2, 0x25, 0x47, 0xb6, 0xfc, 0x74, 0x19, 0x3e, 0xa8, 0x3f, 0x25, 0xd7, 0x87, - 0x02, 0x47, 0x78, 0xac, 0x02, 0xce, 0xd7, 0x2b, 0xd1, 0xee, 0x44, 0xd8, 0x95, 0x4b, 0x40, 0x88, 0x2f, 0x69, 0x9a, - 0xe3, 0x71, 0x44, 0x13, 0x11, 0x36, 0x31, 0xfa, 0x0b, 0xbb, 0x0f, 0x25, 0x96, 0xf3, 0x5c, 0x83, 0x92, 0x4b, 0x06, - 0xef, 0x49, 0x7b, 0x0d, 0x9a, 0xe5, 0x55, 0xa9, 0xc9, 0x44, 0x0e, 0xca, 0x87, 0x43, 0x01, 0x7b, 0xa9, 0xf1, 0xd3, - 0x84, 0x9f, 0xb0, 0xbc, 0xb5, 0xb7, 0xa6, 0x14, 0x95, 0x34, 0x40, 0x05, 0x3e, 0x66, 0xf0, 0xbf, 0x3b, 0x43, 0x2c, - 0x98, 0xa2, 0xe3, 0x87, 0x33, 0x31, 0xb7, 0x9e, 0x5b, 0x65, 0x1d, 0x65, 0x6b, 0x94, 0x13, 0xf0, 0x6f, 0xa9, 0x8e, - 0x93, 0x44, 0x38, 0xf5, 0x1e, 0x71, 0x51, 0xf7, 0x72, 0x88, 0xba, 0x61, 0x6f, 0x2b, 0x1d, 0x6c, 0x39, 0x4d, 0x83, - 0x23, 0xf1, 0x2b, 0xf5, 0xd9, 0x87, 0xcc, 0xe2, 0x51, 0x47, 0x36, 0xa2, 0x24, 0x8d, 0x63, 0x91, 0xc3, 0xf6, 0xbe, - 0x90, 0xfb, 0x7f, 0xbf, 0x0f, 0xe1, 0xa4, 0x55, 0x90, 0x94, 0x9e, 0x40, 0x44, 0x38, 0x3a, 0xfc, 0x88, 0xf0, 0x44, - 0xaa, 0x0a, 0x9f, 0xd4, 0x27, 0x6e, 0xcc, 0xee, 0x85, 0x39, 0xaa, 0xb7, 0x00, 0xc3, 0x58, 0x6f, 0x2d, 0x42, 0x12, - 0xad, 0x34, 0xa3, 0xad, 0x07, 0xc4, 0x88, 0x0f, 0x6b, 0x8b, 0x0c, 0xc6, 0xda, 0x92, 0x48, 0x00, 0xbf, 0x23, 0x21, - 0x43, 0xdb, 0x46, 0x60, 0xc6, 0xf0, 0x76, 0x56, 0x5c, 0xba, 0x0e, 0xdb, 0x9c, 0xc3, 0x17, 0xb2, 0xd0, 0xac, 0x23, - 0x4a, 0x13, 0x84, 0xfc, 0x03, 0x4e, 0x16, 0x0a, 0xa3, 0x79, 0x7d, 0x94, 0x4e, 0x12, 0xeb, 0x87, 0xae, 0x52, 0xc1, - 0x66, 0x73, 0x83, 0xfa, 0xb2, 0xa3, 0xe4, 0x57, 0xe0, 0xa4, 0xe3, 0x24, 0x8b, 0x1c, 0x44, 0x2d, 0x2a, 0xe7, 0x26, - 0x09, 0x4b, 0xbb, 0x3a, 0xd5, 0x66, 0xbd, 0x2e, 0xca, 0xba, 0x7a, 0x2d, 0x22, 0x45, 0xef, 0xa3, 0x1e, 0x3d, 0x91, - 0x90, 0x0a, 0xad, 0x4a, 0xed, 0xf2, 0x08, 0xdc, 0x36, 0xb5, 0x62, 0x5b, 0x2e, 0x61, 0x89, 0x1a, 0xff, 0x19, 0xfa, - 0x28, 0x17, 0x0f, 0x32, 0x40, 0xa3, 0xe3, 0xa9, 0x79, 0xeb, 0x91, 0x57, 0x8e, 0xf2, 0x4b, 0xab, 0x4d, 0xfa, 0x15, - 0x90, 0x19, 0xed, 0x1f, 0x2d, 0x25, 0x90, 0x19, 0x98, 0x49, 0x4b, 0x43, 0x22, 0x47, 0x31, 0x4b, 0xf3, 0x3f, 0x70, - 0xc5, 0x56, 0x88, 0x34, 0xac, 0xe6, 0x1e, 0x7f, 0x51, 0x79, 0xb5, 0x5c, 0xcb, 0x4c, 0x73, 0xb3, 0xc4, 0xb1, 0x62, - 0x71, 0x51, 0xaf, 0x2b, 0x91, 0x05, 0x42, 0x1c, 0x61, 0x1a, 0xeb, 0xa9, 0x37, 0x4a, 0xab, 0x8f, 0x48, 0x28, 0xf3, - 0x23, 0xf6, 0x76, 0xec, 0xf5, 0x20, 0x0b, 0x71, 0x6c, 0x39, 0xd8, 0x6c, 0xbd, 0xcf, 0x65, 0x2a, 0xe2, 0xb3, 0xba, - 0x38, 0xdb, 0x54, 0xe2, 0xac, 0x4e, 0xc4, 0xd9, 0x0f, 0x90, 0xf3, 0x87, 0x33, 0x2a, 0xfa, 0xec, 0x21, 0xad, 0x93, - 0x62, 0x53, 0xd3, 0x93, 0x37, 0x58, 0xc6, 0x0f, 0x67, 0xc4, 0x55, 0x73, 0x46, 0x23, 0x19, 0x8f, 0xce, 0x3e, 0x66, - 0x40, 0xf2, 0x7a, 0x96, 0xae, 0x60, 0xf0, 0xce, 0xc2, 0x3c, 0x3e, 0x2b, 0xc5, 0x1d, 0x58, 0x9c, 0xca, 0xce, 0xf7, - 0x20, 0xc3, 0x2a, 0xfc, 0x43, 0x9c, 0x01, 0xb4, 0xeb, 0x59, 0x5a, 0x9f, 0xa5, 0xd5, 0x59, 0x5e, 0xd4, 0x67, 0x4a, - 0x0a, 0x87, 0x30, 0x7e, 0x78, 0x4f, 0x5f, 0xd9, 0xe5, 0x6d, 0x16, 0x77, 0x59, 0xe4, 0x4f, 0xd1, 0xab, 0x88, 0x98, - 0x34, 0x2a, 0xe1, 0xb5, 0xfb, 0xdb, 0xe6, 0xfe, 0xe1, 0x75, 0x63, 0xf7, 0xb3, 0x3b, 0x46, 0x74, 0x41, 0x3d, 0x5e, - 0x49, 0x4a, 0x05, 0x05, 0x04, 0x4e, 0x34, 0x6b, 0x3c, 0xb8, 0xe3, 0x80, 0x57, 0x03, 0x5b, 0xb2, 0xb5, 0xcf, 0xaf, - 0x63, 0x19, 0xa6, 0xbd, 0x09, 0xf0, 0xaf, 0xb2, 0x37, 0x5d, 0x07, 0x4b, 0xbc, 0x6f, 0x21, 0xdb, 0xd0, 0xdb, 0xd7, - 0xfc, 0x85, 0x97, 0xab, 0xbf, 0xd9, 0x3f, 0x00, 0x08, 0x03, 0x62, 0x56, 0x7d, 0x34, 0x71, 0xef, 0xac, 0x2c, 0x3b, - 0x27, 0xcb, 0xae, 0x87, 0x7e, 0x4d, 0x62, 0x54, 0x5a, 0x59, 0x4a, 0x27, 0x4b, 0x09, 0x59, 0xc0, 0x27, 0x46, 0x53, - 0x1b, 0x01, 0x84, 0xed, 0x28, 0x95, 0x2f, 0x54, 0x5e, 0x44, 0xe1, 0x9c, 0xe0, 0x79, 0x22, 0x46, 0xf7, 0x56, 0x32, - 0x60, 0x38, 0x84, 0x60, 0x0e, 0xda, 0x62, 0x6f, 0xe8, 0x26, 0xe2, 0xaf, 0x37, 0x45, 0xf9, 0x36, 0x26, 0x9f, 0x82, - 0xdd, 0xc9, 0xc7, 0x25, 0x3c, 0x2e, 0x4f, 0x3e, 0x0e, 0xd1, 0x23, 0xe1, 0xe4, 0x63, 0xf0, 0x3d, 0x92, 0xf3, 0xba, - 0xeb, 0x71, 0x82, 0xdc, 0x42, 0xba, 0xbf, 0x1d, 0x93, 0x00, 0xcd, 0x6b, 0x58, 0x8e, 0x9a, 0x8a, 0x6b, 0x66, 0xc6, - 0x78, 0xde, 0xe8, 0xfd, 0xb1, 0xe3, 0x2d, 0x53, 0x28, 0x66, 0x31, 0xaf, 0xe1, 0xf7, 0xac, 0x0a, 0xd4, 0x5d, 0x6f, - 0x93, 0xdc, 0x32, 0xab, 0xe7, 0x68, 0xf7, 0xfd, 0x50, 0x27, 0x82, 0xda, 0xdf, 0x61, 0xcf, 0x33, 0xeb, 0x5d, 0x15, - 0x03, 0x97, 0x2a, 0xd9, 0x21, 0x53, 0xd5, 0xf4, 0x40, 0xa5, 0x34, 0x78, 0x7a, 0x69, 0x5d, 0xbe, 0x54, 0xda, 0xc8, - 0x33, 0xcd, 0x6f, 0x00, 0x2f, 0xa6, 0x2e, 0x8b, 0xdd, 0x37, 0xf7, 0x15, 0xdc, 0xc6, 0xfb, 0xfd, 0x65, 0xe5, 0x99, - 0x9f, 0xb8, 0x00, 0xec, 0x4d, 0x85, 0xd6, 0x09, 0x94, 0x1a, 0xd6, 0xe1, 0xab, 0x44, 0x44, 0x7f, 0xb4, 0xcb, 0x75, - 0xe6, 0x3a, 0x60, 0x44, 0x11, 0xbf, 0x8d, 0x47, 0x7f, 0x80, 0xe2, 0xda, 0xd8, 0x03, 0xc2, 0x3a, 0x24, 0xf4, 0x19, - 0x01, 0x48, 0x3d, 0xe6, 0x28, 0x01, 0xcd, 0x8a, 0xe6, 0x8e, 0xc9, 0xcf, 0xf5, 0x95, 0xd2, 0xdf, 0x2f, 0x2b, 0x8f, - 0xcc, 0x29, 0x6d, 0x33, 0x8d, 0xd5, 0x9a, 0x4a, 0x20, 0xbc, 0xa2, 0x92, 0x55, 0xf8, 0x6c, 0xde, 0x88, 0x7e, 0x5f, - 0x1e, 0xe1, 0x69, 0xf5, 0xe3, 0x16, 0xe3, 0x5b, 0x01, 0xd1, 0x48, 0x00, 0xf4, 0x13, 0xc0, 0xbc, 0xc8, 0x66, 0x76, - 0x1f, 0x07, 0x54, 0x29, 0xd1, 0x34, 0xce, 0xe6, 0xf9, 0x3d, 0xbd, 0x29, 0x3b, 0xe8, 0xd4, 0xa9, 0x02, 0x17, 0x5c, - 0x95, 0x8c, 0x57, 0xd6, 0x13, 0xf9, 0xfc, 0xe6, 0x76, 0x93, 0x66, 0xf1, 0x87, 0xf2, 0x1f, 0x38, 0xb6, 0xba, 0x0e, - 0x8f, 0x4c, 0x9d, 0xae, 0x9d, 0x47, 0x5a, 0x7b, 0x21, 0x20, 0xa2, 0x5d, 0x43, 0xad, 0x17, 0x16, 0x7a, 0xa4, 0x27, - 0xc2, 0x39, 0x49, 0xd4, 0xb4, 0x03, 0x2d, 0x8d, 0xd0, 0xd7, 0xd7, 0x9c, 0xfe, 0xc2, 0x60, 0xed, 0xf3, 0x31, 0x03, - 0xb2, 0x12, 0xfd, 0x58, 0x3d, 0x34, 0x36, 0x73, 0xe8, 0x59, 0xab, 0xf2, 0xcc, 0xab, 0x0e, 0x07, 0xc4, 0x87, 0xd1, - 0x5f, 0xf2, 0xfb, 0xfd, 0xd7, 0x34, 0xff, 0x98, 0x50, 0xe3, 0x67, 0x9b, 0x01, 0xba, 0xf6, 0x5d, 0x79, 0x20, 0xea, - 0xb9, 0x56, 0x09, 0x42, 0xbc, 0x41, 0x4c, 0x34, 0x23, 0xe6, 0xe0, 0xb4, 0x43, 0xcd, 0x3f, 0x49, 0x0d, 0x08, 0x51, - 0xe2, 0x75, 0x4c, 0x59, 0x90, 0xd3, 0x26, 0x8e, 0xf4, 0xa3, 0x70, 0x22, 0x3f, 0x89, 0xaa, 0xc8, 0xee, 0xe1, 0x82, - 0xc1, 0xd4, 0x7b, 0xda, 0x2f, 0xd1, 0x6f, 0x09, 0x47, 0xce, 0xd1, 0xaa, 0x10, 0x44, 0x4e, 0x08, 0x6b, 0x0d, 0x61, - 0x82, 0xd8, 0x20, 0x5e, 0xf6, 0x5d, 0x92, 0xe1, 0x48, 0xc1, 0x65, 0x1d, 0x3b, 0xc6, 0x5c, 0x1d, 0x55, 0xaf, 0x01, - 0x8c, 0x57, 0x8e, 0xa0, 0xd9, 0x28, 0xb2, 0x4b, 0x88, 0x2a, 0x72, 0x3c, 0x01, 0xb5, 0x83, 0xd2, 0xd8, 0x4c, 0xcf, - 0xc7, 0x41, 0x3e, 0x5a, 0x54, 0xa8, 0x73, 0x62, 0x19, 0xaf, 0x01, 0x58, 0x3b, 0x57, 0xfd, 0x3c, 0xab, 0xc1, 0x93, - 0x86, 0xf8, 0x7c, 0x8c, 0xb6, 0x57, 0x36, 0x07, 0xd5, 0x76, 0x3a, 0x2b, 0xaf, 0x98, 0x2e, 0x07, 0xc6, 0x7d, 0xc3, - 0x2b, 0x8a, 0x33, 0xfc, 0xe4, 0xc1, 0x16, 0xe7, 0x4f, 0x37, 0xd4, 0x7e, 0xcc, 0x8d, 0x7a, 0x18, 0x68, 0x2d, 0x78, - 0x53, 0x10, 0xeb, 0xef, 0xc7, 0x8e, 0x6c, 0x1f, 0xb4, 0xc8, 0x68, 0xf2, 0xd9, 0xcf, 0x3f, 0x96, 0xe9, 0x2a, 0x85, - 0xfb, 0x92, 0x93, 0x45, 0x33, 0x0f, 0x81, 0xbd, 0x21, 0x86, 0xeb, 0xa3, 0xc2, 0x23, 0xca, 0xfa, 0x7d, 0xf8, 0x7d, - 0x95, 0x81, 0x29, 0x06, 0xae, 0x2b, 0x04, 0xe3, 0x21, 0x10, 0xc4, 0xc3, 0x34, 0x3a, 0x19, 0xd4, 0xa0, 0x0d, 0xdf, - 0x00, 0x64, 0x06, 0x78, 0x64, 0x2e, 0x3d, 0x02, 0xee, 0x02, 0xd7, 0x9e, 0x8c, 0xc7, 0xfe, 0xc4, 0x34, 0x34, 0x6a, - 0x4a, 0x33, 0x3d, 0x37, 0x7e, 0xd3, 0x51, 0x2d, 0xd7, 0xce, 0x7f, 0x7c, 0xc9, 0x6f, 0xd0, 0x0b, 0x5a, 0x5e, 0xee, - 0x23, 0x75, 0xb9, 0xcf, 0x28, 0x2e, 0x13, 0xc9, 0x61, 0x41, 0x2c, 0x4b, 0x38, 0xf0, 0x18, 0x95, 0x2c, 0xb6, 0xf4, - 0x58, 0x15, 0x2d, 0x5f, 0x94, 0x1b, 0xa4, 0x43, 0x27, 0x04, 0x4b, 0x54, 0x10, 0x2c, 0x81, 0x71, 0x11, 0x6b, 0xbe, - 0x19, 0xe4, 0x2c, 0x9e, 0x6d, 0xe6, 0x1c, 0x09, 0xeb, 0x92, 0xc3, 0xa1, 0x90, 0x60, 0x33, 0xd9, 0x6c, 0x3d, 0x67, - 0x6b, 0x9f, 0x81, 0x12, 0xa0, 0x94, 0x69, 0x82, 0xd2, 0xb4, 0x62, 0x2b, 0x6e, 0x5a, 0x83, 0xd5, 0x6a, 0xca, 0x56, - 0x35, 0x65, 0xe7, 0x34, 0xe5, 0xa8, 0x82, 0x92, 0x13, 0x4a, 0x51, 0x86, 0x01, 0x8c, 0xd8, 0x24, 0xba, 0xca, 0xd0, - 0xc7, 0x3b, 0xe1, 0x11, 0x54, 0x11, 0x91, 0x4f, 0x18, 0x42, 0x60, 0x22, 0x8a, 0x0b, 0x55, 0x28, 0x06, 0xc8, 0x88, - 0x04, 0x82, 0x89, 0x4a, 0x9d, 0x02, 0xf3, 0xd1, 0x54, 0x31, 0x6c, 0xda, 0x13, 0xe5, 0x7b, 0xea, 0xb8, 0x47, 0xd9, - 0xe6, 0x6f, 0x62, 0x17, 0x84, 0xc8, 0xdd, 0xb8, 0x53, 0x3f, 0x23, 0xde, 0xdb, 0x1d, 0x61, 0xfc, 0x64, 0xc7, 0x2d, - 0xc2, 0x15, 0xc1, 0x96, 0x6a, 0x0e, 0xb1, 0x98, 0x57, 0x93, 0x04, 0xb5, 0x2c, 0x89, 0xbf, 0xe1, 0xc9, 0x20, 0x67, - 0x4b, 0xf0, 0xa0, 0x9d, 0xb3, 0x0c, 0xf0, 0x57, 0xac, 0x16, 0xfd, 0x56, 0x7b, 0x4b, 0x90, 0x9f, 0x36, 0x76, 0xa3, - 0x30, 0x31, 0x82, 0x44, 0xdd, 0xae, 0x0c, 0xe4, 0x87, 0x8f, 0x38, 0x1d, 0x8f, 0x3d, 0x65, 0xcc, 0xad, 0x4c, 0x2f, - 0xd3, 0xb9, 0x92, 0x6f, 0xe4, 0x5e, 0xfa, 0xd8, 0x4b, 0xb0, 0x73, 0xc0, 0x1b, 0x48, 0x1b, 0x78, 0x03, 0xdb, 0x85, - 0xd7, 0x06, 0x09, 0x33, 0x02, 0x6c, 0x71, 0x7c, 0x8c, 0x94, 0xc0, 0x10, 0x8e, 0xb3, 0x14, 0x80, 0x69, 0xf4, 0x65, - 0xb6, 0xb2, 0x2f, 0xb3, 0x5a, 0xb3, 0xa5, 0x72, 0xba, 0x77, 0x6e, 0xdd, 0xce, 0x27, 0x12, 0x00, 0x4c, 0xea, 0x1c, - 0x88, 0x33, 0x13, 0xec, 0xd2, 0x24, 0xb2, 0x7c, 0x0a, 0xf3, 0x3b, 0xf1, 0xa6, 0x2c, 0x56, 0xaa, 0x2b, 0xda, 0x3e, - 0x33, 0xf9, 0x8c, 0x74, 0x12, 0x2a, 0xa0, 0xa0, 0x90, 0x6b, 0x7d, 0xfa, 0x3e, 0x7c, 0x1f, 0x14, 0x1a, 0x98, 0xad, - 0xc2, 0x3d, 0x4d, 0xd6, 0x48, 0xbd, 0x51, 0xf5, 0xfb, 0xe4, 0x1a, 0x48, 0x75, 0xe6, 0xd0, 0xb2, 0x27, 0x15, 0x06, - 0x88, 0x1d, 0xf5, 0x19, 0x09, 0x75, 0x20, 0xf5, 0x80, 0x21, 0x44, 0xdb, 0xf4, 0xf1, 0x27, 0x43, 0xa2, 0x0b, 0xb0, - 0x85, 0x68, 0x03, 0x3f, 0xfe, 0x04, 0xfb, 0x2c, 0x08, 0x8f, 0x69, 0xfe, 0x0e, 0x92, 0x8e, 0x0d, 0x9c, 0x56, 0x9f, - 0x82, 0x0f, 0x92, 0x1c, 0x4c, 0xd4, 0xc1, 0xcb, 0xfd, 0xa5, 0xdf, 0x87, 0x2d, 0x3b, 0x97, 0x52, 0x1d, 0x2b, 0xf5, - 0xb6, 0xad, 0xfd, 0x20, 0xda, 0x82, 0x23, 0x8b, 0xf8, 0x87, 0x0c, 0x11, 0xc1, 0xcc, 0x20, 0xc2, 0xae, 0x85, 0xba, - 0xdb, 0x53, 0x6a, 0x59, 0xd4, 0xdb, 0x9e, 0x52, 0xea, 0x36, 0x0c, 0xdf, 0x4d, 0x30, 0x53, 0xdc, 0xf0, 0x3f, 0x32, - 0x2f, 0xd4, 0x1b, 0x8f, 0x45, 0x81, 0xee, 0xf9, 0xfb, 0x25, 0xaf, 0x66, 0x1b, 0x65, 0xc2, 0xbc, 0xe3, 0xcb, 0x59, - 0x28, 0xbb, 0x5a, 0x1a, 0x77, 0xbe, 0x78, 0x4b, 0x35, 0x1f, 0xfc, 0xc3, 0x21, 0x81, 0x78, 0xa3, 0xf8, 0xea, 0xae, - 0x91, 0x5b, 0xd7, 0x64, 0x73, 0x55, 0x02, 0xea, 0xf7, 0xf9, 0x1a, 0xf7, 0x5b, 0xac, 0x7f, 0xf7, 0x34, 0xc8, 0x58, - 0xcd, 0x70, 0xc5, 0x14, 0x3e, 0x05, 0x80, 0xc1, 0xe1, 0x54, 0x90, 0x16, 0x78, 0xc3, 0xcb, 0xe1, 0xe5, 0x64, 0x43, - 0x26, 0xdd, 0x8d, 0x8f, 0xdc, 0x59, 0xa0, 0xea, 0xfd, 0x8e, 0xe2, 0xa4, 0x41, 0xa2, 0xb1, 0xd7, 0xe0, 0x8b, 0x2c, - 0xa3, 0x5c, 0x34, 0x71, 0x1f, 0x93, 0xaf, 0xf4, 0x00, 0xe6, 0x2a, 0x94, 0x00, 0xd1, 0x6f, 0x2c, 0x8b, 0x8d, 0x68, - 0x5b, 0x6c, 0x60, 0x29, 0x55, 0x73, 0xbd, 0x9a, 0xbe, 0x78, 0x25, 0x9a, 0xf7, 0xd1, 0x8c, 0x53, 0x1a, 0x0d, 0x38, - 0x4e, 0xa3, 0x70, 0xfb, 0xe1, 0x5e, 0x94, 0xcb, 0x0c, 0x2c, 0xd9, 0x2a, 0x9c, 0xe2, 0xb2, 0x51, 0x67, 0xc4, 0x8b, - 0x3c, 0x56, 0x00, 0x1d, 0x8f, 0x09, 0x80, 0xea, 0x82, 0x80, 0x8a, 0x68, 0x29, 0xbd, 0x15, 0x5a, 0x2c, 0xd4, 0x1b, - 0x8e, 0x52, 0xf8, 0x23, 0xfd, 0x79, 0x90, 0x4f, 0x01, 0x88, 0x5d, 0x1f, 0x47, 0x6f, 0x8a, 0x92, 0x3e, 0x55, 0xcc, - 0x72, 0x39, 0x98, 0xc0, 0xae, 0x4e, 0x64, 0xa8, 0x15, 0xe4, 0xad, 0xba, 0xf2, 0x56, 0x26, 0x6f, 0x63, 0x9c, 0x92, - 0x1f, 0xb9, 0xe9, 0x58, 0x23, 0x06, 0x5e, 0x79, 0x5a, 0xa7, 0x09, 0xd2, 0xe4, 0x02, 0x18, 0x86, 0xf8, 0x36, 0xf3, - 0x5e, 0x78, 0x8e, 0x54, 0x05, 0xc9, 0x6c, 0x97, 0x79, 0xea, 0x22, 0xaa, 0xaf, 0x9c, 0x5a, 0x3a, 0x73, 0xfa, 0x11, - 0xc0, 0x7b, 0x4c, 0x4d, 0x1a, 0xf2, 0x11, 0x6e, 0x4b, 0xf1, 0xf5, 0x56, 0x5d, 0xe3, 0xa5, 0xd1, 0xb9, 0x7b, 0xf9, - 0xd2, 0x9d, 0x06, 0xfd, 0x14, 0x04, 0xe5, 0x7c, 0x51, 0x0a, 0xd8, 0x53, 0x66, 0x73, 0xbd, 0x5a, 0xb5, 0x42, 0xeb, - 0x70, 0x18, 0x6b, 0x47, 0x21, 0xad, 0xce, 0x02, 0xb6, 0x1a, 0xe9, 0x94, 0x00, 0x21, 0x38, 0x4e, 0xc3, 0x4e, 0x30, - 0xee, 0xd2, 0x69, 0x44, 0xd6, 0x2b, 0x25, 0xe9, 0xc2, 0x0c, 0x92, 0x7f, 0x92, 0xd7, 0x33, 0xa0, 0x25, 0x80, 0x43, - 0x11, 0x4b, 0x78, 0x38, 0x49, 0xae, 0x00, 0x3a, 0x1d, 0x0e, 0x2a, 0x0d, 0xcd, 0x59, 0xcd, 0x92, 0xf9, 0x24, 0x96, - 0xaa, 0xca, 0xc3, 0xc1, 0x53, 0x6e, 0x06, 0xfd, 0x7e, 0x36, 0x2d, 0x95, 0x0b, 0x40, 0x10, 0xeb, 0xc2, 0x00, 0xf1, - 0x48, 0x0b, 0x4f, 0x16, 0x7d, 0x4a, 0xe2, 0x97, 0xb3, 0x64, 0x6e, 0xb2, 0xe1, 0x1d, 0x18, 0xc1, 0x66, 0x5c, 0x97, - 0x94, 0x69, 0x8f, 0xca, 0xef, 0x19, 0x3d, 0xb5, 0x7d, 0xad, 0xd5, 0x16, 0xb1, 0xae, 0x83, 0xab, 0x12, 0xf5, 0x14, - 0x1f, 0x94, 0x24, 0x78, 0xbf, 0x76, 0x6e, 0x46, 0xca, 0xd7, 0x22, 0xf7, 0x83, 0x76, 0xa6, 0x56, 0x0e, 0x1c, 0x81, - 0x1c, 0xab, 0xa8, 0xe4, 0xf5, 0xae, 0x43, 0xf0, 0xe8, 0xae, 0x54, 0xa0, 0x1c, 0x7c, 0x0d, 0x62, 0x74, 0x7d, 0xd5, - 0x59, 0x43, 0xcd, 0x34, 0xaa, 0x3c, 0x82, 0x4e, 0x1d, 0xc0, 0x93, 0x82, 0x97, 0x5a, 0xfd, 0x78, 0x38, 0x78, 0xe6, - 0x07, 0x7f, 0x95, 0xe9, 0x5b, 0x88, 0x89, 0x72, 0xaa, 0x11, 0x12, 0x57, 0x4a, 0x12, 0xf1, 0xf1, 0xa2, 0x65, 0xc5, - 0xa8, 0x0c, 0x1f, 0x78, 0xa5, 0xca, 0x57, 0xa7, 0x2a, 0x2f, 0x46, 0xda, 0x96, 0xc0, 0x6b, 0xf2, 0x0f, 0x91, 0x6b, - 0xde, 0xfa, 0xba, 0xab, 0x0c, 0x7d, 0x27, 0x2b, 0xd0, 0x11, 0x6c, 0x65, 0x29, 0x39, 0xe0, 0x93, 0xea, 0xae, 0x5a, - 0xb5, 0x3e, 0xa7, 0x6c, 0x23, 0xdc, 0xe4, 0xd7, 0xb1, 0x83, 0x23, 0xe5, 0x37, 0x78, 0x2e, 0x80, 0xbd, 0x06, 0xec, - 0xcd, 0x39, 0x2b, 0x9a, 0x47, 0x87, 0xb4, 0x2d, 0xd0, 0xc8, 0xcc, 0xed, 0x5c, 0xdd, 0xb7, 0xe5, 0x51, 0x1a, 0x43, - 0x64, 0xda, 0x23, 0xd3, 0xc1, 0x66, 0x94, 0xff, 0x9e, 0xf2, 0x5b, 0x85, 0x63, 0xe0, 0xdb, 0xa9, 0x77, 0x00, 0x55, - 0x4f, 0x1b, 0x64, 0xac, 0x19, 0x86, 0x56, 0x76, 0xb9, 0x14, 0x5a, 0x82, 0x96, 0xba, 0x09, 0x82, 0xf3, 0x23, 0xa2, - 0x1c, 0x01, 0xe8, 0x22, 0x05, 0x4c, 0xf0, 0x53, 0xda, 0xee, 0x7e, 0x7f, 0x9d, 0x7a, 0xe4, 0xde, 0x15, 0x6a, 0x94, - 0x50, 0x82, 0xb1, 0x9f, 0x68, 0xcc, 0xa0, 0xa3, 0x2b, 0x72, 0xc2, 0xb3, 0x56, 0x87, 0x75, 0xdd, 0x94, 0x41, 0x59, - 0x1c, 0xf3, 0x6a, 0x3a, 0xfb, 0xfd, 0xc9, 0xbe, 0x6e, 0x90, 0x85, 0xfc, 0x77, 0xd6, 0x43, 0x32, 0xe8, 0x1e, 0x84, - 0x42, 0xf4, 0xe6, 0xc1, 0x0c, 0xff, 0x63, 0x1b, 0x9e, 0x7d, 0xc7, 0x8d, 0x3a, 0x01, 0xcc, 0x11, 0xd7, 0x4b, 0x4f, - 0xd1, 0xd6, 0xc3, 0x2d, 0x90, 0xad, 0xf1, 0xf2, 0xd6, 0x5e, 0x03, 0x39, 0xc5, 0xf1, 0xdf, 0xf1, 0x4c, 0xad, 0x6c, - 0xf0, 0xd3, 0x53, 0xb6, 0x03, 0x0f, 0x2f, 0x42, 0x40, 0x31, 0x2c, 0x1b, 0x7f, 0x67, 0x39, 0xce, 0xe8, 0xbf, 0x79, - 0xc4, 0x30, 0x58, 0x44, 0x7e, 0x7c, 0x59, 0x0a, 0xf1, 0x55, 0x78, 0x6f, 0x2b, 0xef, 0x8e, 0x9c, 0x32, 0xef, 0xf4, - 0x30, 0xba, 0x2e, 0x49, 0xdf, 0x25, 0x1f, 0x5b, 0xc3, 0xf6, 0xbb, 0x76, 0xbf, 0x19, 0x22, 0x08, 0xa1, 0x1c, 0x3f, - 0x67, 0x74, 0x42, 0xe3, 0xc3, 0x6a, 0x76, 0x7a, 0xfd, 0xde, 0x39, 0x5e, 0xb0, 0x35, 0x1a, 0xe0, 0xf1, 0xd0, 0xc5, - 0x3c, 0x51, 0x43, 0xa7, 0xeb, 0xda, 0x39, 0x78, 0x60, 0x90, 0xe5, 0xc9, 0x77, 0x0c, 0x4b, 0xec, 0x4f, 0x22, 0x9e, - 0xb4, 0x55, 0x1b, 0x9b, 0x23, 0xd5, 0x46, 0xcd, 0xc0, 0x0f, 0x5e, 0x41, 0x81, 0xd1, 0x05, 0x69, 0x05, 0xc6, 0xe1, - 0x08, 0x40, 0x56, 0x8c, 0xe3, 0x91, 0xc1, 0x04, 0x86, 0x74, 0x43, 0x51, 0x00, 0x1e, 0x1e, 0xc7, 0x83, 0x90, 0x01, - 0xa4, 0x0b, 0x1e, 0x1a, 0xb6, 0x49, 0x48, 0xf9, 0x79, 0x9e, 0xd7, 0x6a, 0x08, 0x7d, 0x67, 0xa1, 0x3a, 0xf6, 0x23, - 0xed, 0x15, 0xeb, 0x5a, 0x95, 0x8e, 0x6c, 0x75, 0x80, 0xbe, 0x21, 0x03, 0xdf, 0x3a, 0xb6, 0x00, 0x88, 0x96, 0xf8, - 0x2d, 0xf5, 0x6a, 0x5f, 0xc6, 0xac, 0x50, 0xaf, 0x2f, 0x4c, 0xbb, 0x5e, 0x4b, 0x8b, 0x02, 0x2a, 0x6e, 0x5b, 0xb5, - 0x3d, 0x92, 0xf3, 0x1f, 0xdf, 0x75, 0xb4, 0xe3, 0xb3, 0x53, 0x63, 0x4b, 0x28, 0x73, 0x8b, 0x27, 0xb2, 0x3a, 0xda, - 0x52, 0x9d, 0xea, 0x03, 0x2e, 0x35, 0xa9, 0xce, 0x0c, 0x0c, 0xaf, 0x11, 0xa0, 0xdc, 0x42, 0x24, 0x8d, 0xc3, 0xde, - 0xf9, 0x64, 0x50, 0x30, 0xb7, 0x48, 0x40, 0x02, 0xdb, 0xd8, 0xda, 0x45, 0x73, 0xfd, 0xfa, 0x2d, 0xf5, 0xaa, 0x36, - 0x55, 0x3d, 0x78, 0xe3, 0x05, 0xce, 0xde, 0x69, 0x2d, 0x20, 0x80, 0xc2, 0xd6, 0xb2, 0x1c, 0x9c, 0xbb, 0x5d, 0xd5, - 0x52, 0x51, 0x46, 0xfd, 0xfe, 0xf9, 0x6f, 0x29, 0x2a, 0x62, 0x4f, 0x15, 0xa7, 0xac, 0xdf, 0x6e, 0x99, 0x8b, 0xca, - 0x92, 0x37, 0xa8, 0xa2, 0xb5, 0x3a, 0x6a, 0x2a, 0xd7, 0xcd, 0x55, 0x4b, 0x26, 0x88, 0xd1, 0x7d, 0xba, 0xd6, 0xb9, - 0x53, 0xef, 0xbd, 0x8a, 0x23, 0x06, 0x82, 0x9b, 0xee, 0xf1, 0xc1, 0x41, 0x68, 0x54, 0x94, 0x0b, 0x6e, 0x94, 0x56, - 0x95, 0x94, 0x42, 0xde, 0xaa, 0x68, 0xce, 0xf4, 0x11, 0x00, 0x11, 0x60, 0x95, 0xa8, 0xff, 0xcd, 0x97, 0xc6, 0x78, - 0xf0, 0xc0, 0xd7, 0xe4, 0x3a, 0xb6, 0xde, 0x3f, 0xad, 0x91, 0x56, 0x1b, 0xc7, 0xa4, 0x56, 0xbd, 0x6c, 0x15, 0x2f, - 0xbb, 0xd7, 0xa9, 0x18, 0x3c, 0xff, 0x9f, 0xfb, 0x00, 0x35, 0xa2, 0xa5, 0x0c, 0x6e, 0x5d, 0x0d, 0xd0, 0xf8, 0x70, - 0x2c, 0x7c, 0xe3, 0x87, 0x8c, 0xf3, 0xc1, 0x0c, 0x1d, 0xd5, 0xe6, 0xe0, 0x80, 0xe0, 0xa8, 0xee, 0xd1, 0x98, 0x30, - 0x0b, 0xe7, 0x1e, 0x04, 0xaa, 0x4f, 0xdc, 0x67, 0x5c, 0x7b, 0x41, 0x9b, 0xc0, 0x27, 0xeb, 0xba, 0xa6, 0x08, 0x70, - 0x11, 0x1b, 0x13, 0x31, 0xc4, 0x65, 0x93, 0x48, 0x7d, 0x33, 0x06, 0x05, 0x40, 0x71, 0x5d, 0x91, 0x5c, 0xba, 0x48, - 0xf3, 0x4a, 0x94, 0xb5, 0x6e, 0x46, 0xc5, 0x8a, 0x21, 0x00, 0x3c, 0x04, 0xc5, 0x55, 0x65, 0x26, 0x34, 0x62, 0x03, - 0xa9, 0x2c, 0x05, 0xab, 0x86, 0x85, 0xdf, 0xb4, 0xdf, 0x24, 0x27, 0xbd, 0xf3, 0x71, 0xeb, 0xdc, 0xb1, 0xef, 0x1d, - 0x85, 0x94, 0xf6, 0x50, 0x4c, 0x10, 0x04, 0x3f, 0xad, 0xc3, 0xf9, 0x33, 0x7e, 0x4d, 0x60, 0x2a, 0xb2, 0x19, 0x03, - 0x0e, 0x42, 0x44, 0x66, 0xfc, 0x9e, 0xc3, 0x6b, 0x5e, 0x4e, 0xc2, 0xe1, 0xd0, 0x07, 0x7d, 0x28, 0xcf, 0x66, 0xe1, - 0x50, 0xcc, 0xa5, 0xf7, 0x3a, 0x58, 0xeb, 0x42, 0x5e, 0x4f, 0x42, 0x44, 0x0b, 0x0d, 0x7d, 0x70, 0x5e, 0x77, 0xcd, - 0x11, 0x96, 0x00, 0x34, 0x71, 0xf4, 0x65, 0xfd, 0x7e, 0xe4, 0x69, 0x43, 0x8b, 0x14, 0x17, 0x8d, 0x32, 0x9b, 0xe5, - 0xb2, 0x13, 0x36, 0xae, 0xdd, 0x02, 0xa1, 0x78, 0x98, 0xb6, 0x50, 0xb5, 0x9e, 0xea, 0xf5, 0xdc, 0xb4, 0xfb, 0xee, - 0x51, 0xb5, 0xca, 0x91, 0xce, 0xda, 0x74, 0xa5, 0x56, 0xb7, 0x8c, 0xaa, 0x75, 0x96, 0x46, 0x54, 0xb9, 0x49, 0xee, - 0x1a, 0xb5, 0xe0, 0x93, 0x0d, 0x5d, 0xa6, 0xec, 0x6c, 0x0d, 0x4e, 0x1c, 0x79, 0x2e, 0xb9, 0xe5, 0xbb, 0xf3, 0x8a, - 0xee, 0x4e, 0xb5, 0x6f, 0x01, 0xee, 0xcd, 0xb0, 0x21, 0x73, 0x5e, 0x63, 0xa7, 0x41, 0x98, 0x04, 0x7e, 0xc4, 0x3e, - 0x66, 0xc8, 0x06, 0x03, 0x3a, 0x0a, 0xe9, 0x7f, 0x6d, 0x99, 0x23, 0x01, 0x93, 0xbf, 0x9e, 0xfb, 0xcd, 0xa2, 0xc8, - 0x61, 0x31, 0x7e, 0xdc, 0x60, 0xa4, 0xb1, 0x5a, 0x83, 0x61, 0x79, 0x87, 0xc8, 0x9f, 0xda, 0x1d, 0xd3, 0x54, 0xc7, - 0x9b, 0xf5, 0x5a, 0xf3, 0xab, 0xa7, 0x4f, 0x75, 0x7d, 0xfe, 0xdb, 0xf7, 0x97, 0x61, 0xcd, 0xec, 0x0f, 0x41, 0x28, - 0xed, 0xde, 0x2d, 0xce, 0x1d, 0x89, 0xde, 0xb1, 0xd2, 0xcc, 0x2e, 0xed, 0x92, 0x5d, 0x9a, 0xd2, 0x6e, 0xc8, 0xf5, - 0xea, 0x1b, 0xe5, 0x8d, 0x9d, 0x57, 0x4c, 0xf7, 0xef, 0x85, 0xde, 0x51, 0x4e, 0xd5, 0x04, 0x22, 0x9a, 0xb4, 0x23, - 0x71, 0xbb, 0x57, 0x86, 0xcf, 0x27, 0x79, 0xbb, 0x84, 0xa3, 0xae, 0x61, 0xb9, 0xf9, 0xf6, 0x3f, 0xf2, 0xaa, 0xb3, - 0xc2, 0xed, 0x97, 0xc6, 0xac, 0xfd, 0x29, 0x88, 0xab, 0xfa, 0xc3, 0x7b, 0x52, 0x33, 0x25, 0xff, 0x57, 0x3d, 0x06, - 0xae, 0x7e, 0x32, 0xed, 0xe8, 0x9e, 0x42, 0xd8, 0x60, 0xf6, 0xf3, 0xe3, 0x87, 0x16, 0xac, 0xaa, 0x0b, 0x14, 0xc9, - 0x01, 0x74, 0xee, 0x92, 0x11, 0xde, 0xef, 0x18, 0xe7, 0xfe, 0xd5, 0x2f, 0x6a, 0x72, 0x84, 0x88, 0x76, 0x11, 0x0e, - 0x00, 0xe2, 0x4e, 0x53, 0x59, 0x87, 0x1a, 0xa0, 0x0f, 0x08, 0xac, 0x43, 0xdf, 0x66, 0x00, 0x07, 0x7d, 0xb4, 0x79, - 0x16, 0x81, 0xbc, 0xee, 0xdd, 0xb3, 0x77, 0x6c, 0xe7, 0xf3, 0xeb, 0x55, 0xea, 0xdd, 0xa3, 0x43, 0xf0, 0xf9, 0xd8, - 0x9f, 0x5e, 0x06, 0x06, 0x17, 0x9a, 0xbd, 0x7b, 0x26, 0xd8, 0x8e, 0xed, 0x9e, 0x21, 0x52, 0x51, 0x77, 0xfe, 0xe1, - 0xa5, 0x89, 0x9e, 0x77, 0x5e, 0xb8, 0xe3, 0x4b, 0x00, 0x0f, 0x64, 0x31, 0xa0, 0xf8, 0x2c, 0xbd, 0x7f, 0xb2, 0x04, - 0xd4, 0xe4, 0xb7, 0x7c, 0xed, 0xbd, 0xa7, 0xd4, 0x05, 0xfc, 0x39, 0xa0, 0xf4, 0x49, 0xce, 0xbd, 0xbb, 0xe1, 0xad, - 0x7f, 0xf1, 0x1c, 0x9c, 0x27, 0x56, 0xc3, 0x05, 0xfc, 0x55, 0xf0, 0xa1, 0x77, 0x37, 0xc0, 0xc4, 0x92, 0x0f, 0xbd, - 0xd5, 0x00, 0x52, 0x15, 0x2e, 0x24, 0xc6, 0x3e, 0xfc, 0x1a, 0xe4, 0x0c, 0xff, 0xf8, 0x4d, 0x63, 0xb0, 0xfe, 0x1a, - 0x14, 0x1a, 0x8d, 0xb5, 0x54, 0x21, 0x4b, 0xb1, 0x38, 0x13, 0x60, 0x13, 0x8e, 0xbb, 0x7d, 0xb1, 0xaa, 0xcd, 0x5a, - 0xd0, 0x9f, 0x8f, 0xf8, 0x1e, 0x8d, 0xd5, 0x55, 0x39, 0x17, 0xe5, 0x27, 0xa4, 0x4f, 0x75, 0x7c, 0x8c, 0x8a, 0x4d, - 0xdd, 0x9d, 0x4e, 0xb5, 0xea, 0x48, 0xfb, 0x4d, 0xb9, 0x06, 0x3b, 0x5e, 0x27, 0x47, 0x96, 0xc2, 0xb3, 0x0e, 0x3b, - 0x2f, 0x9d, 0x12, 0x1d, 0x86, 0xf1, 0x6e, 0xab, 0x9e, 0x31, 0x94, 0xe7, 0x06, 0x63, 0xba, 0xe0, 0x11, 0xbf, 0x1e, - 0xe4, 0x32, 0x34, 0xe6, 0x23, 0xb2, 0x61, 0x28, 0x1f, 0x5a, 0x64, 0x48, 0x88, 0x78, 0x0f, 0x95, 0x80, 0x6d, 0x0b, - 0xca, 0xa4, 0x80, 0xb3, 0x68, 0xf0, 0x5b, 0xed, 0xe5, 0xc0, 0x7b, 0x10, 0xf9, 0x8d, 0x74, 0x29, 0x97, 0xd8, 0xe8, - 0xc4, 0xb1, 0x2c, 0xb4, 0xf3, 0xb8, 0xfe, 0x3a, 0x06, 0xf5, 0x7b, 0xa5, 0xdf, 0xa0, 0x9c, 0xfd, 0x49, 0xb2, 0x4e, - 0x1b, 0x4f, 0x8c, 0x7f, 0xb9, 0xca, 0x3f, 0x45, 0x4b, 0x3d, 0xfc, 0x7f, 0xc6, 0x14, 0x4a, 0xff, 0x2a, 0x2d, 0xa3, - 0xcd, 0x6a, 0x29, 0x4a, 0x91, 0x47, 0xe2, 0xe4, 0x6b, 0x91, 0x9d, 0xcb, 0x77, 0x3e, 0x85, 0x7e, 0x01, 0x68, 0xd9, - 0x27, 0xc8, 0xe8, 0x5f, 0x98, 0xe0, 0xc3, 0x5f, 0xb4, 0x73, 0x6d, 0xce, 0xc7, 0x93, 0xfc, 0xca, 0xda, 0xbb, 0x1d, - 0x2f, 0x12, 0xa3, 0x18, 0xcb, 0x7d, 0xd5, 0xcd, 0xca, 0x89, 0x4a, 0x0e, 0x8c, 0x74, 0x4d, 0xf6, 0x72, 0x25, 0xeb, - 0x76, 0xba, 0x95, 0x40, 0x44, 0x15, 0x78, 0x8f, 0x71, 0x15, 0xfb, 0x08, 0xa6, 0xeb, 0x8e, 0xcb, 0x68, 0xc7, 0x7b, - 0xc6, 0xab, 0x13, 0x65, 0x05, 0xb7, 0x1b, 0xd1, 0x9e, 0xd0, 0xd1, 0x4f, 0x93, 0xda, 0xb2, 0x70, 0x00, 0x72, 0x97, - 0x30, 0x96, 0x0d, 0xc1, 0x8a, 0x41, 0xe9, 0xeb, 0x35, 0x25, 0xcb, 0x02, 0x2c, 0x3a, 0xbb, 0x8c, 0x40, 0x0c, 0xeb, - 0xa6, 0x39, 0xa1, 0xe3, 0xa5, 0x8b, 0xf3, 0x5e, 0xab, 0x48, 0xc1, 0x33, 0x5a, 0x74, 0xcc, 0x4d, 0x47, 0xba, 0x31, - 0xda, 0xdb, 0x97, 0x06, 0x21, 0xc5, 0xf3, 0x07, 0xb6, 0x5a, 0x17, 0x17, 0x89, 0x57, 0xc8, 0x44, 0x0b, 0x62, 0x29, - 0x02, 0x33, 0x5e, 0x68, 0x1a, 0x61, 0x82, 0x32, 0x25, 0x58, 0xb4, 0x46, 0x87, 0xf6, 0x87, 0x25, 0xec, 0x1e, 0x63, - 0x04, 0x08, 0x54, 0x99, 0xbe, 0x84, 0xad, 0x09, 0xb3, 0xa9, 0x8b, 0x0d, 0xd0, 0x56, 0x31, 0x34, 0x08, 0x6b, 0x43, - 0xcc, 0xa7, 0x34, 0xbf, 0xfb, 0x27, 0x16, 0x63, 0x7b, 0x02, 0xb1, 0xbd, 0xdb, 0x35, 0x09, 0xd3, 0xbd, 0x16, 0x37, - 0xd6, 0xcb, 0xed, 0x29, 0xc7, 0xd4, 0x8e, 0xb5, 0x51, 0x3b, 0xd6, 0x52, 0xef, 0x58, 0x6b, 0xbd, 0x63, 0xdd, 0x35, - 0xfc, 0x63, 0xe6, 0xc5, 0x2c, 0x01, 0xfd, 0xee, 0x8a, 0xab, 0x06, 0x41, 0x33, 0x36, 0xec, 0x16, 0x7e, 0x4b, 0xac, - 0xdd, 0xd2, 0xbf, 0x58, 0xb2, 0x85, 0xe9, 0x03, 0xdd, 0x3a, 0xc0, 0x32, 0xa2, 0x26, 0xdf, 0x23, 0xef, 0xa6, 0xb3, - 0xa2, 0x70, 0x7b, 0x62, 0x0b, 0x9f, 0xbd, 0x33, 0x6f, 0xde, 0x3f, 0x8b, 0x20, 0xf7, 0x8e, 0x7b, 0xf7, 0xc3, 0x77, - 0xfe, 0x85, 0x6e, 0x81, 0x9c, 0xcc, 0x72, 0x06, 0x52, 0x47, 0x7c, 0x86, 0x68, 0x65, 0x4f, 0xf9, 0x4e, 0xc8, 0x9d, - 0x6d, 0xfd, 0xec, 0xde, 0xdd, 0xd6, 0xee, 0x9e, 0xdd, 0xb3, 0x6a, 0x44, 0xb1, 0xe2, 0x34, 0x45, 0xc2, 0x2c, 0xda, - 0x00, 0x4f, 0xbd, 0x7c, 0xbf, 0x63, 0xc7, 0x1c, 0xee, 0x9e, 0x75, 0x74, 0xbc, 0x9c, 0x03, 0x76, 0xf7, 0x1f, 0x6d, - 0xc2, 0xc6, 0x4a, 0xd7, 0x2a, 0x74, 0xb8, 0x7b, 0x96, 0x69, 0x3c, 0x87, 0x23, 0xf9, 0x74, 0xac, 0xb1, 0x41, 0x50, - 0xd7, 0xe7, 0x0c, 0x6a, 0xc7, 0xee, 0x6b, 0xc2, 0x2e, 0x3b, 0xe6, 0xb5, 0xae, 0x79, 0x7b, 0xe5, 0xa9, 0xd8, 0x10, - 0xd0, 0xe1, 0x6b, 0x75, 0x83, 0xfc, 0x4b, 0xe0, 0x14, 0x01, 0x20, 0x87, 0xe3, 0x25, 0x8f, 0x7d, 0x9f, 0x66, 0x69, - 0xbd, 0x43, 0xad, 0x45, 0x65, 0x59, 0x86, 0xb5, 0xf7, 0x83, 0x56, 0x0c, 0x4b, 0x4d, 0xff, 0x74, 0x1c, 0xb8, 0x9d, - 0xed, 0x56, 0xc6, 0x2e, 0xe3, 0x59, 0x71, 0xf1, 0xcb, 0x69, 0xa1, 0x5c, 0xbb, 0x79, 0x1b, 0xbf, 0x69, 0xb5, 0x64, - 0x69, 0xad, 0x87, 0xbc, 0xb4, 0x2c, 0x22, 0x10, 0xc0, 0x70, 0xa4, 0xec, 0x62, 0x09, 0xf7, 0x08, 0xab, 0x7b, 0x10, - 0x4a, 0xe6, 0x85, 0x8b, 0xe7, 0x2c, 0x86, 0x44, 0x80, 0xed, 0x0e, 0x15, 0xdb, 0xc2, 0xc5, 0x73, 0xb6, 0xe1, 0x45, - 0xbf, 0x9f, 0xa9, 0x4e, 0x21, 0xeb, 0xce, 0x92, 0x6f, 0x54, 0x73, 0xac, 0xa1, 0x66, 0x6b, 0x93, 0x6c, 0x8d, 0x73, - 0x5b, 0xf1, 0x71, 0xd7, 0x56, 0x7c, 0xac, 0xac, 0x75, 0xe9, 0x5e, 0xef, 0x51, 0x5d, 0x00, 0x5b, 0xff, 0xed, 0xf1, - 0xca, 0xf5, 0x7c, 0x46, 0x00, 0x5f, 0x0b, 0x3e, 0x9e, 0x2c, 0xd0, 0xab, 0x64, 0xe1, 0xdf, 0x0e, 0xd4, 0xf8, 0x3b, - 0x9d, 0xbb, 0x00, 0xe8, 0x4a, 0xca, 0x2b, 0x20, 0xef, 0x20, 0xc7, 0xdc, 0xb2, 0x2b, 0xef, 0x4f, 0xbe, 0xc3, 0xde, - 0xf1, 0x7a, 0xb6, 0x98, 0xb3, 0x1d, 0x38, 0x15, 0x24, 0x03, 0x7b, 0x59, 0xb1, 0x5d, 0x10, 0xdb, 0x09, 0xbf, 0x11, - 0x30, 0xe5, 0x0b, 0x08, 0xe2, 0x0a, 0x6e, 0x21, 0x0e, 0x4f, 0xfe, 0x39, 0xb8, 0x6f, 0x6d, 0xd6, 0xf7, 0xcc, 0xea, - 0x9c, 0x60, 0xcd, 0xac, 0x1e, 0x0c, 0x96, 0xcd, 0x64, 0xd5, 0xef, 0x7b, 0x3b, 0xed, 0xf8, 0x74, 0x27, 0x75, 0x62, - 0xa7, 0xb5, 0x5a, 0x0b, 0xf6, 0x4e, 0x6a, 0x5d, 0x8c, 0xa1, 0x07, 0x88, 0x9f, 0x6e, 0x07, 0xfc, 0xbe, 0x63, 0x6d, - 0x79, 0xef, 0xd8, 0x82, 0xed, 0xe0, 0x12, 0xd4, 0xb4, 0x97, 0xfd, 0x49, 0xe5, 0x82, 0x76, 0xec, 0x92, 0x78, 0x38, - 0x63, 0x56, 0x29, 0x33, 0xeb, 0xa4, 0xba, 0x12, 0x9d, 0x31, 0x9d, 0xb5, 0x9e, 0xcf, 0xd5, 0x7c, 0x52, 0x68, 0x50, - 0xbf, 0x73, 0xe2, 0x23, 0x2a, 0x3a, 0x4f, 0x60, 0x6b, 0x59, 0x41, 0xac, 0xf6, 0x39, 0x58, 0x6b, 0xb5, 0x4b, 0xbf, - 0x97, 0x0f, 0xb8, 0x4d, 0x39, 0xac, 0x03, 0x83, 0x9a, 0x13, 0x2b, 0xea, 0x31, 0xdb, 0x31, 0x6e, 0x7e, 0x7a, 0xf9, - 0x83, 0x13, 0x96, 0xac, 0x58, 0xed, 0x4f, 0x7f, 0x79, 0xe6, 0xe9, 0xef, 0xd4, 0xfe, 0x85, 0xf0, 0x83, 0xf1, 0xbf, - 0x6b, 0xf7, 0xb5, 0x16, 0xa3, 0xb2, 0x55, 0x8e, 0xd0, 0xb8, 0x5b, 0x49, 0x93, 0xe5, 0x67, 0xe1, 0x09, 0x6b, 0xc1, - 0xb3, 0x5c, 0x2f, 0xd1, 0xac, 0x80, 0x15, 0xd6, 0x32, 0x09, 0x57, 0x18, 0xab, 0xa5, 0xad, 0xbe, 0x45, 0xd3, 0x1c, - 0x1f, 0xce, 0xb5, 0x41, 0x99, 0x72, 0x76, 0x46, 0xac, 0x86, 0xcb, 0xb0, 0x34, 0xa1, 0x08, 0xd9, 0xbd, 0x1d, 0xdc, - 0xd8, 0x29, 0x4b, 0x29, 0xc3, 0x39, 0x06, 0x13, 0x1e, 0x89, 0x51, 0x95, 0xef, 0xef, 0x4b, 0x8a, 0x9c, 0xb6, 0xe5, - 0xa0, 0x0a, 0x61, 0x1f, 0x49, 0x94, 0xc0, 0xad, 0x48, 0x0b, 0x45, 0xca, 0xe2, 0x6f, 0x07, 0xe8, 0x02, 0x2f, 0xa0, - 0xae, 0x46, 0xdd, 0xfe, 0x70, 0xc4, 0xc3, 0x47, 0xa6, 0x3e, 0x30, 0x62, 0x49, 0xa0, 0xb6, 0x17, 0x59, 0x7a, 0x07, - 0x2a, 0xfc, 0x1e, 0xae, 0x26, 0x62, 0x3f, 0xb7, 0xa4, 0xa8, 0xc8, 0x46, 0x7a, 0x43, 0x6b, 0xf0, 0x08, 0xad, 0x29, - 0x2f, 0x9d, 0x54, 0x9b, 0x74, 0xde, 0x11, 0x72, 0xac, 0xbe, 0xb5, 0x84, 0xd1, 0xae, 0xe8, 0xc5, 0xbd, 0xa3, 0xf7, - 0x3c, 0x5d, 0xf5, 0xdc, 0x9f, 0xb8, 0x62, 0x9e, 0xdc, 0x46, 0xa0, 0x6e, 0x05, 0xd5, 0xed, 0x83, 0x4a, 0xb0, 0x60, - 0x49, 0xbb, 0x8f, 0xdf, 0xce, 0xda, 0x81, 0xa8, 0x8c, 0x55, 0xfa, 0x96, 0x24, 0xec, 0x89, 0x41, 0xa7, 0x50, 0x95, - 0xdb, 0xdd, 0xd1, 0x16, 0xb8, 0x8e, 0x59, 0x8a, 0x5e, 0xd8, 0x22, 0x77, 0xcb, 0xbf, 0x7b, 0xae, 0xc8, 0xd9, 0x2f, - 0x01, 0xc1, 0xa9, 0xf9, 0x86, 0xf8, 0x72, 0x84, 0x47, 0xd5, 0x2d, 0x70, 0x9c, 0xbe, 0x03, 0xf8, 0x87, 0xc3, 0x25, - 0x68, 0x02, 0x62, 0xc1, 0x7a, 0x69, 0xdc, 0x63, 0xbd, 0xb8, 0xd8, 0xdc, 0x25, 0xf9, 0x06, 0x9c, 0x19, 0x28, 0xd5, - 0xd2, 0x0f, 0x1c, 0xab, 0x05, 0x54, 0x38, 0x98, 0x9d, 0xd4, 0x0b, 0xcb, 0xa8, 0xc7, 0xf4, 0xf9, 0x19, 0xec, 0x1d, - 0x21, 0x01, 0x70, 0xbf, 0xec, 0x03, 0x12, 0xf0, 0xd0, 0x99, 0x1d, 0x10, 0x4e, 0x98, 0x45, 0x55, 0x20, 0x91, 0x1c, - 0xe9, 0x67, 0x8f, 0x99, 0x48, 0xfe, 0x60, 0xd6, 0x73, 0x4e, 0x89, 0x1e, 0xeb, 0xa9, 0x23, 0xa4, 0xc7, 0x7a, 0xd6, - 0x11, 0xd1, 0x63, 0x3d, 0xeb, 0xf8, 0xe8, 0xb1, 0x9e, 0x39, 0x76, 0x7a, 0x10, 0x98, 0x00, 0x91, 0x07, 0xac, 0x47, - 0x93, 0xa9, 0xa7, 0xb8, 0x07, 0x88, 0x06, 0x81, 0xf5, 0xa4, 0x70, 0xde, 0x03, 0xe4, 0x31, 0x12, 0xab, 0x83, 0xde, - 0x7f, 0x8c, 0x9f, 0xf6, 0x8c, 0x8c, 0x3c, 0x6e, 0x1d, 0x56, 0xff, 0xeb, 0x3f, 0x21, 0x00, 0x0e, 0xcf, 0xa6, 0xde, - 0xe5, 0x18, 0xb2, 0xca, 0x32, 0x02, 0xc9, 0x4f, 0x0c, 0xbe, 0x7c, 0x01, 0x50, 0xf5, 0x99, 0xae, 0xd5, 0xe4, 0xa8, - 0x3d, 0xe6, 0xd0, 0x15, 0x03, 0xc0, 0x36, 0x2c, 0x51, 0x55, 0x0b, 0x9b, 0xb0, 0xb8, 0xfd, 0x0c, 0xa3, 0xb9, 0x6c, - 0x7a, 0x41, 0x03, 0xf5, 0x08, 0xc1, 0x2f, 0xad, 0x87, 0xd6, 0x5a, 0xa6, 0x1c, 0xba, 0x36, 0x8a, 0x2a, 0x1b, 0xea, - 0x12, 0x56, 0x6b, 0x11, 0xd5, 0x44, 0x91, 0x72, 0xc9, 0x28, 0x8a, 0xa5, 0x0a, 0xf6, 0x99, 0xb8, 0x83, 0xa8, 0x79, - 0xda, 0x6a, 0xab, 0x60, 0x7f, 0x07, 0x08, 0x6b, 0x61, 0x2d, 0xa4, 0x33, 0xa8, 0xbd, 0xd3, 0x8f, 0x94, 0xbf, 0xbc, - 0x90, 0xdb, 0xb9, 0x85, 0x22, 0xdc, 0x9e, 0x83, 0xf2, 0xa6, 0xae, 0x4a, 0x45, 0x34, 0x5a, 0x02, 0xa5, 0xcc, 0x09, - 0x22, 0x0b, 0x10, 0xc0, 0x71, 0x03, 0x81, 0xcf, 0x6b, 0x7c, 0x02, 0x8d, 0x42, 0x20, 0x3f, 0xb0, 0x0a, 0xd7, 0x1e, - 0xd2, 0x52, 0x6b, 0x44, 0x94, 0x88, 0x1f, 0x5d, 0x3d, 0xc7, 0xf6, 0xd5, 0xd3, 0x58, 0x5b, 0x4a, 0x13, 0xc4, 0x4f, - 0x2c, 0xb6, 0x10, 0x13, 0x44, 0x75, 0x88, 0x8e, 0x60, 0x39, 0x21, 0x44, 0xe1, 0x0f, 0xa1, 0x9f, 0x1a, 0xf8, 0x4b, - 0xb6, 0x2c, 0xf2, 0x9a, 0x60, 0x31, 0x2b, 0x06, 0x68, 0x55, 0x04, 0x9e, 0xe9, 0x6c, 0xa9, 0xcc, 0x69, 0x1e, 0x1d, - 0xd9, 0xc1, 0x79, 0xd7, 0xc1, 0x5e, 0xfa, 0x32, 0x76, 0xb2, 0x6c, 0x1a, 0xb5, 0xb1, 0x21, 0x12, 0x5e, 0x91, 0xbf, - 0xca, 0x52, 0xe3, 0x1c, 0x99, 0xcb, 0xf5, 0x5d, 0x17, 0x77, 0x77, 0xb4, 0x4d, 0x58, 0x85, 0x08, 0x75, 0xdb, 0x50, - 0xb9, 0x14, 0x66, 0x63, 0xd3, 0x34, 0xc0, 0x17, 0x8a, 0x4a, 0xa5, 0x2a, 0xb5, 0x95, 0x4a, 0x4e, 0x78, 0xd7, 0x37, - 0xb5, 0x48, 0x5d, 0x11, 0x6c, 0x63, 0x86, 0x7a, 0x28, 0x37, 0x6a, 0xec, 0xdb, 0x8e, 0x55, 0x7a, 0x87, 0x09, 0x72, - 0x46, 0x5e, 0xe4, 0xe0, 0xa2, 0xa4, 0x20, 0x73, 0x35, 0x84, 0xf9, 0xa3, 0x86, 0x4f, 0x0b, 0xcb, 0x3d, 0x94, 0x80, - 0xd9, 0x51, 0xc3, 0xcb, 0x08, 0x81, 0x88, 0x4b, 0x65, 0x5f, 0x31, 0xf1, 0x7b, 0x0a, 0x66, 0xc9, 0x84, 0xee, 0x45, - 0x2c, 0x8c, 0xd0, 0xc6, 0x27, 0x49, 0x32, 0xf5, 0x34, 0x05, 0x37, 0x72, 0x19, 0xe6, 0x68, 0x84, 0x96, 0x7c, 0xe4, - 0x40, 0xfa, 0x5a, 0x4e, 0x25, 0xf8, 0x88, 0x3a, 0x05, 0x1c, 0xcf, 0xcf, 0x0b, 0xeb, 0x27, 0xcb, 0x25, 0xe6, 0xb2, - 0x36, 0xff, 0x65, 0x47, 0xc7, 0x60, 0x97, 0xa7, 0x89, 0xe3, 0xea, 0x3f, 0xaa, 0x92, 0xe2, 0xe1, 0xe7, 0x34, 0x07, - 0x14, 0xc1, 0xcc, 0x9e, 0x62, 0x7c, 0xec, 0xb3, 0x4c, 0x01, 0x7f, 0xbb, 0xde, 0x5a, 0x32, 0xb1, 0x4b, 0xda, 0xcd, - 0x95, 0xf1, 0x4b, 0x6d, 0xd8, 0x71, 0x70, 0x6e, 0x00, 0x8a, 0xb3, 0x46, 0x87, 0xe5, 0xb5, 0x6e, 0x5b, 0x15, 0x2a, - 0x50, 0xeb, 0x7f, 0xef, 0x16, 0xa6, 0xbc, 0xcd, 0x4b, 0xe5, 0x6d, 0x1e, 0x9a, 0x00, 0x81, 0xc8, 0x0c, 0x79, 0xd6, - 0x74, 0x4c, 0x12, 0xf7, 0x8e, 0x94, 0xb4, 0xef, 0x48, 0xf1, 0xa3, 0x77, 0x24, 0xe4, 0x5b, 0x42, 0x47, 0xf6, 0x25, - 0x27, 0x27, 0x50, 0x66, 0xb0, 0x97, 0xd7, 0x4c, 0xf6, 0x0f, 0x68, 0x2f, 0x9c, 0xcb, 0xf2, 0x8a, 0xbf, 0x13, 0xde, - 0xda, 0x9f, 0xae, 0x4f, 0xbb, 0xaa, 0xde, 0x7e, 0x63, 0x66, 0x1e, 0x0e, 0xc5, 0xe1, 0x50, 0x99, 0xa0, 0xdd, 0x05, - 0x17, 0x83, 0x9c, 0xdd, 0xbb, 0xf1, 0xf1, 0xef, 0x38, 0x8a, 0xd8, 0x4a, 0x79, 0x24, 0x5d, 0xa8, 0xc4, 0xf0, 0xd2, - 0xc0, 0xc3, 0xec, 0xf8, 0x78, 0xb2, 0xbb, 0xba, 0x9f, 0x0c, 0x06, 0x3b, 0xd5, 0xb7, 0x5b, 0x5e, 0xcf, 0x76, 0x73, - 0xf6, 0xc0, 0x6f, 0xa7, 0xdb, 0x60, 0xdf, 0xc0, 0xb6, 0xbb, 0xbb, 0x12, 0x87, 0xc3, 0xee, 0x9a, 0x2f, 0xfc, 0xfd, - 0x03, 0x02, 0x3a, 0xf3, 0xf3, 0x71, 0x1b, 0xe3, 0xe7, 0xa6, 0xed, 0xaa, 0xb5, 0x03, 0x78, 0xfa, 0x1f, 0xbd, 0x9b, - 0xd9, 0x72, 0xee, 0xb3, 0x27, 0xfc, 0x01, 0xfc, 0xf3, 0x71, 0x93, 0x44, 0xea, 0x13, 0xed, 0x32, 0x79, 0x03, 0x0e, - 0xe4, 0x3b, 0x9f, 0xbd, 0xe5, 0x0f, 0xb3, 0xe5, 0x9c, 0x17, 0x87, 0xc3, 0x87, 0x69, 0x88, 0x64, 0x4d, 0x61, 0x45, - 0x2c, 0x29, 0x9e, 0x1f, 0x84, 0xc7, 0xef, 0x45, 0x64, 0x88, 0xb4, 0xdc, 0xbb, 0x43, 0x76, 0xc3, 0x22, 0x3f, 0x80, - 0x0f, 0xb2, 0x9d, 0x3f, 0x91, 0x35, 0xa5, 0xfb, 0xc5, 0x13, 0xff, 0x70, 0xa0, 0xbf, 0xde, 0xfa, 0x87, 0xc3, 0x07, - 0xf6, 0x80, 0xe0, 0xe8, 0x7c, 0x07, 0xfd, 0xa3, 0x6f, 0x1d, 0x50, 0x95, 0xe1, 0xbb, 0xd9, 0x66, 0xee, 0x5f, 0xaf, - 0xd8, 0x1d, 0x70, 0xa1, 0x28, 0x2f, 0xb4, 0x1b, 0xf6, 0x80, 0x5e, 0x67, 0xe4, 0x44, 0x34, 0xdb, 0xcd, 0x7d, 0x16, - 0xe3, 0x73, 0x75, 0x5f, 0x4c, 0xbe, 0x79, 0x5f, 0xdc, 0xb1, 0x6d, 0xf7, 0x7d, 0x51, 0xbe, 0xe9, 0xae, 0x9f, 0x2d, - 0xdb, 0xb1, 0x07, 0x98, 0x61, 0xef, 0xf8, 0x4d, 0x73, 0xec, 0x18, 0xfb, 0xcd, 0x1b, 0x23, 0x80, 0x32, 0x5b, 0xb0, - 0x58, 0x70, 0x50, 0xaa, 0x55, 0xdb, 0x92, 0xc8, 0x2b, 0x1d, 0xa8, 0x36, 0x23, 0xb8, 0xaf, 0x16, 0x72, 0xe6, 0x99, - 0x81, 0xbe, 0xad, 0x10, 0x2d, 0x1c, 0x36, 0xe0, 0x6f, 0xb4, 0x75, 0x8c, 0x61, 0x9a, 0xd5, 0x4c, 0xdb, 0xa2, 0x2e, - 0xbf, 0xef, 0x3d, 0x93, 0xdf, 0xc8, 0xc0, 0x16, 0x22, 0x29, 0x1c, 0xc7, 0x17, 0xcf, 0x4f, 0xf8, 0xaf, 0x5a, 0x1e, - 0xb5, 0xda, 0x2f, 0x94, 0xfa, 0xf4, 0x15, 0x1d, 0xd1, 0xc4, 0xbd, 0x68, 0xcb, 0xb0, 0x46, 0x59, 0x53, 0x4b, 0x87, - 0x61, 0x5c, 0xc3, 0xbe, 0x3c, 0x70, 0xe8, 0x3b, 0x20, 0xd0, 0x56, 0xa9, 0x14, 0x68, 0xe1, 0x18, 0x46, 0x61, 0x16, - 0x52, 0x1e, 0x17, 0x66, 0x29, 0xef, 0xb1, 0x40, 0x8b, 0x5b, 0x75, 0x8f, 0xa9, 0xed, 0x16, 0x44, 0x58, 0xbd, 0x65, - 0x9c, 0x5f, 0x36, 0xaa, 0x70, 0x5b, 0x80, 0xa2, 0x08, 0xca, 0x60, 0x4f, 0x72, 0xdb, 0x42, 0x49, 0xb3, 0x51, 0x58, - 0x8b, 0xbb, 0xa2, 0xdc, 0xf5, 0x1a, 0xb6, 0xc0, 0x0b, 0xaa, 0x7e, 0x42, 0xd8, 0x96, 0x3d, 0xeb, 0x50, 0x2e, 0xd2, - 0x7f, 0xcb, 0xd2, 0xf3, 0xfd, 0xd6, 0x9c, 0xff, 0xe9, 0x2b, 0xfa, 0xa8, 0xfc, 0xf7, 0x2f, 0xe9, 0x27, 0x83, 0x65, - 0xe4, 0x94, 0xfa, 0x25, 0x1a, 0xdd, 0xa6, 0x39, 0x61, 0x6c, 0xf9, 0xfa, 0xe9, 0x77, 0xc8, 0x14, 0x24, 0x87, 0x52, - 0xaa, 0x72, 0xb2, 0x87, 0xbe, 0xf0, 0xba, 0x0f, 0x33, 0xc1, 0x00, 0x84, 0xd7, 0x68, 0x53, 0x4d, 0x98, 0xc4, 0xa3, - 0x2b, 0xf8, 0xbf, 0x11, 0xc4, 0xa0, 0x7d, 0xa2, 0xa8, 0x63, 0xdb, 0x48, 0xd7, 0x6d, 0xe7, 0x20, 0xb9, 0x53, 0x57, - 0xfe, 0xa8, 0x9c, 0xfc, 0x3b, 0x1a, 0x22, 0xaf, 0xb8, 0x42, 0xac, 0x2c, 0xb8, 0xc4, 0x62, 0xa8, 0x48, 0x01, 0xae, - 0x21, 0x88, 0x94, 0x45, 0x49, 0xe1, 0x96, 0x83, 0xaa, 0x08, 0xc0, 0xb8, 0x5a, 0x1d, 0x75, 0x22, 0x7c, 0xdc, 0x5a, - 0x8b, 0x10, 0xac, 0x68, 0xd4, 0xca, 0x5a, 0x81, 0x2f, 0x48, 0x5f, 0x3a, 0x14, 0xc4, 0xf4, 0x28, 0xa4, 0xaa, 0x74, - 0x28, 0x90, 0xe6, 0x50, 0xf1, 0x8d, 0xc1, 0x46, 0x51, 0x91, 0x9e, 0xbf, 0x34, 0x29, 0xb9, 0x34, 0x66, 0x7c, 0x14, - 0x65, 0x24, 0xf2, 0x3a, 0xbc, 0x13, 0xd3, 0x02, 0xf9, 0x46, 0x8f, 0x1f, 0x04, 0x97, 0xf0, 0x6e, 0xc8, 0xbd, 0x02, - 0x6c, 0x09, 0xd8, 0x01, 0xee, 0x95, 0x19, 0xe5, 0x3a, 0xad, 0xeb, 0xb7, 0xd6, 0x43, 0x31, 0x0c, 0x9f, 0x59, 0x02, - 0xdb, 0xd1, 0x3a, 0x3a, 0xd2, 0xc3, 0x87, 0xff, 0x75, 0x55, 0x73, 0xd4, 0xa9, 0x5c, 0xce, 0x8e, 0x27, 0x2c, 0x45, - 0xcc, 0xa0, 0xfb, 0xeb, 0xf6, 0x95, 0x00, 0xba, 0x5d, 0x16, 0xf3, 0x6c, 0xb4, 0x93, 0x7f, 0x4b, 0x37, 0x56, 0x94, - 0x36, 0xf1, 0x2e, 0xeb, 0x8d, 0xfd, 0xe1, 0xe8, 0x3f, 0x9e, 0xbd, 0x9f, 0x10, 0xaa, 0xce, 0x86, 0xad, 0x75, 0x9c, - 0xcb, 0xff, 0xfa, 0xcf, 0x31, 0x59, 0x41, 0x50, 0x10, 0x96, 0x9d, 0x62, 0xa2, 0x82, 0x51, 0xa4, 0x58, 0xf3, 0xf1, - 0x64, 0x8d, 0x3a, 0xe1, 0xb5, 0xbf, 0xd4, 0x3a, 0x61, 0x62, 0x64, 0xa5, 0xf2, 0xd7, 0xac, 0x62, 0x77, 0x2a, 0xb3, - 0x80, 0xcc, 0x83, 0x7c, 0xb2, 0x36, 0x1a, 0xcc, 0x15, 0xaf, 0x67, 0xeb, 0xb9, 0x54, 0x3e, 0x83, 0x29, 0x67, 0x39, - 0x38, 0x59, 0x0a, 0xbb, 0x27, 0x81, 0xa2, 0x35, 0x43, 0xd7, 0xfe, 0x14, 0x5b, 0xf5, 0x3a, 0xad, 0x6a, 0x80, 0x07, - 0x84, 0x18, 0x18, 0x6a, 0xaf, 0x16, 0x1e, 0x5a, 0x0b, 0x60, 0xed, 0x8f, 0x4a, 0x3f, 0x18, 0x4f, 0x96, 0x7c, 0x81, - 0xfc, 0xcb, 0x91, 0xa3, 0x76, 0xef, 0xf7, 0xbd, 0x7b, 0x90, 0x82, 0x23, 0xd7, 0x42, 0x81, 0x44, 0x40, 0x0b, 0xbe, - 0xf1, 0x95, 0x0f, 0xc6, 0x3b, 0xd4, 0x56, 0x83, 0x82, 0xda, 0xd1, 0x2d, 0x8f, 0x1d, 0xbd, 0xf3, 0xfd, 0x09, 0x7d, - 0xf5, 0x42, 0x0b, 0xc7, 0xdf, 0x38, 0x23, 0xd7, 0x6c, 0xd5, 0x21, 0x47, 0x34, 0x93, 0x0e, 0x21, 0x62, 0xc5, 0xd6, - 0xec, 0x1d, 0xa9, 0x9c, 0x3b, 0x87, 0xec, 0xf4, 0x11, 0xaa, 0xf4, 0x5a, 0x8f, 0x6f, 0x27, 0x4a, 0x77, 0x7b, 0xbc, - 0x9b, 0x7c, 0xcf, 0x26, 0x22, 0x06, 0x03, 0xda, 0x20, 0x9c, 0x91, 0x75, 0x88, 0x54, 0x3a, 0x40, 0x08, 0x1c, 0x13, - 0xd0, 0xf4, 0x5f, 0xdf, 0x92, 0x28, 0xe0, 0x48, 0x1b, 0x21, 0x6b, 0xd9, 0xe1, 0x90, 0x83, 0x46, 0xb9, 0xf9, 0xc3, - 0x2b, 0xd4, 0x69, 0x0e, 0xcc, 0xd3, 0x25, 0xec, 0x39, 0x78, 0xa4, 0x17, 0xc7, 0x47, 0xfa, 0x7f, 0x47, 0x13, 0x35, - 0xfe, 0xf7, 0x35, 0x51, 0x4a, 0x8b, 0xe4, 0xa8, 0x96, 0xbe, 0x4b, 0x1d, 0x05, 0x17, 0x79, 0x47, 0x2d, 0x64, 0xcf, - 0xb2, 0x71, 0xa3, 0x9a, 0xf7, 0xff, 0x6b, 0x65, 0xfe, 0xbf, 0xa6, 0x95, 0x61, 0x4a, 0x76, 0x2c, 0xd5, 0xcc, 0x03, - 0xad, 0x62, 0x98, 0xfd, 0x4c, 0x12, 0x22, 0xc3, 0xa5, 0x01, 0x3f, 0xaa, 0x60, 0x1f, 0xa7, 0xd5, 0x3a, 0x0b, 0x77, - 0xa8, 0x44, 0xbd, 0x15, 0x77, 0x69, 0xfe, 0xa2, 0xfe, 0x97, 0x28, 0x0b, 0x98, 0xda, 0x77, 0x65, 0x1a, 0x07, 0x64, - 0xe1, 0xcf, 0xc2, 0x12, 0x27, 0x37, 0xb6, 0xf1, 0x67, 0x39, 0x9e, 0xf6, 0xab, 0xce, 0xcc, 0x03, 0x09, 0xd4, 0x40, - 0xfc, 0x91, 0x73, 0x59, 0x59, 0x3c, 0x20, 0x74, 0xf3, 0x8f, 0x65, 0x59, 0x94, 0x5e, 0xef, 0x73, 0x92, 0x56, 0x67, - 0x2b, 0x51, 0x27, 0x45, 0xac, 0xa0, 0x6c, 0x52, 0x80, 0xd1, 0x87, 0x95, 0x27, 0xe2, 0xe0, 0x0c, 0x81, 0x1a, 0xce, - 0xea, 0x24, 0x04, 0xa0, 0x61, 0x85, 0xb0, 0x7f, 0x06, 0x2d, 0x3c, 0x0b, 0xe3, 0x70, 0x0d, 0x30, 0x39, 0x69, 0x75, - 0xb6, 0x2e, 0x8b, 0xfb, 0x34, 0x16, 0xf1, 0xa8, 0xa7, 0x28, 0x59, 0xde, 0xe4, 0xae, 0x9c, 0xeb, 0xef, 0xff, 0xa0, - 0x00, 0x76, 0x03, 0x66, 0xdb, 0x02, 0x3b, 0x00, 0x48, 0x50, 0x20, 0x5b, 0xa8, 0xd3, 0xe8, 0x4c, 0x2d, 0x15, 0x78, - 0xcf, 0xf5, 0x00, 0x7f, 0x93, 0x03, 0x96, 0x71, 0x5d, 0xc8, 0x80, 0x11, 0x04, 0x30, 0x02, 0x07, 0x25, 0x60, 0xe8, - 0x0c, 0x71, 0x5b, 0x95, 0xb3, 0x16, 0x9a, 0x2b, 0xdd, 0x96, 0xdc, 0x34, 0xca, 0xd9, 0x4a, 0x04, 0xd0, 0x57, 0x37, - 0x25, 0x4e, 0x97, 0xcb, 0x56, 0x12, 0xf6, 0xed, 0x87, 0x76, 0xaa, 0xc8, 0xe3, 0xa3, 0x34, 0xe4, 0x15, 0x78, 0x92, - 0x71, 0x24, 0x89, 0x12, 0xc1, 0x9b, 0xbc, 0x31, 0xe3, 0xf0, 0xa2, 0x4d, 0x39, 0xb5, 0x37, 0xeb, 0x05, 0xe0, 0x3c, - 0x41, 0x5b, 0x06, 0x18, 0x0b, 0x18, 0x9c, 0x0b, 0xb1, 0xe4, 0x29, 0x82, 0x5f, 0x3a, 0x91, 0xc2, 0xb8, 0xcb, 0x61, - 0x98, 0x07, 0x45, 0xef, 0x92, 0xfa, 0xa3, 0xdf, 0x47, 0x6d, 0x32, 0x18, 0x82, 0x4a, 0x00, 0x95, 0x75, 0x83, 0xc4, - 0xc0, 0xaa, 0xb4, 0x90, 0xb8, 0x84, 0x78, 0x99, 0xaf, 0xa6, 0x75, 0x14, 0x7c, 0xa8, 0x27, 0x84, 0x70, 0x82, 0xf1, - 0x21, 0x6e, 0x80, 0x80, 0xc1, 0x2a, 0x2e, 0x30, 0x48, 0x9e, 0x4b, 0x74, 0x7f, 0x3c, 0xdf, 0x31, 0xc0, 0x95, 0xf3, - 0x9e, 0x6a, 0x57, 0x0f, 0xec, 0xe5, 0x2a, 0x5d, 0x32, 0x42, 0x58, 0xf1, 0x7f, 0x11, 0x79, 0xdf, 0x0e, 0x13, 0x50, - 0xdb, 0xc8, 0x1f, 0x83, 0xc4, 0x5c, 0x26, 0x8a, 0x20, 0x1e, 0x65, 0x05, 0x4b, 0xd2, 0x60, 0x33, 0x4a, 0x52, 0xd0, - 0x68, 0x62, 0x0c, 0x99, 0x0a, 0xed, 0x90, 0x34, 0x9a, 0x8d, 0xc9, 0x3e, 0x86, 0xbc, 0x86, 0x8b, 0xc5, 0x02, 0xef, - 0xfb, 0x59, 0xa8, 0x0e, 0xb6, 0xa5, 0x39, 0x04, 0x9c, 0x24, 0xd8, 0x53, 0x57, 0xa4, 0x24, 0xcc, 0x46, 0x9f, 0x42, - 0xce, 0x0d, 0xe8, 0x38, 0x69, 0x0c, 0xd5, 0x07, 0x26, 0xe1, 0x55, 0x84, 0x4e, 0xca, 0x0a, 0x61, 0x01, 0xf7, 0x8d, - 0x8c, 0x46, 0x2b, 0x69, 0x10, 0x78, 0x9b, 0x61, 0x2b, 0xb0, 0x09, 0x0d, 0x7f, 0x91, 0x79, 0x98, 0x56, 0xb3, 0x12, - 0xcc, 0xf9, 0x06, 0x2a, 0x31, 0x9e, 0x2c, 0xaf, 0xf8, 0xc6, 0xc5, 0x4a, 0x4c, 0x66, 0xcb, 0xf9, 0x64, 0x2d, 0xa9, - 0xe6, 0x72, 0x6f, 0xcd, 0x32, 0xb6, 0x84, 0xfd, 0xc3, 0xc0, 0x50, 0x3a, 0xb0, 0xa3, 0xa9, 0xa6, 0x4d, 0x02, 0x4c, - 0xa6, 0x73, 0xce, 0x87, 0x97, 0x88, 0x26, 0xab, 0x53, 0x77, 0x32, 0x55, 0xed, 0xe0, 0x9a, 0x9c, 0xc9, 0xe9, 0x91, - 0x7a, 0xaa, 0x75, 0x2f, 0xf9, 0x68, 0x3b, 0xac, 0x46, 0x5b, 0x3f, 0x00, 0xb7, 0x4e, 0x61, 0xa7, 0xef, 0x86, 0xd5, - 0x68, 0xe7, 0x6b, 0xd8, 0x5d, 0x52, 0x08, 0x54, 0x7f, 0x96, 0x35, 0x99, 0x8b, 0xd7, 0xc5, 0x83, 0x57, 0xb0, 0xe7, - 0xfe, 0x40, 0xff, 0x2a, 0xd9, 0x73, 0xdf, 0x66, 0x72, 0xfd, 0x33, 0xed, 0x1a, 0x8d, 0x99, 0x8e, 0xd7, 0xae, 0xc0, - 0x0a, 0x0d, 0x90, 0x5f, 0xb0, 0xa3, 0xbd, 0xcd, 0x41, 0x20, 0x40, 0xf7, 0x12, 0x1c, 0x45, 0x01, 0x51, 0xd3, 0xaa, - 0xf2, 0xe8, 0x74, 0xef, 0xef, 0xf1, 0x8d, 0x10, 0xb0, 0xc9, 0x53, 0xeb, 0xde, 0x32, 0xf6, 0x0f, 0x07, 0x08, 0xa1, - 0x97, 0xd3, 0x6f, 0xb4, 0x65, 0xf5, 0x68, 0xc7, 0x72, 0xdf, 0x30, 0xea, 0x29, 0x18, 0xc3, 0xd0, 0x85, 0x55, 0x8c, - 0xe4, 0x19, 0x90, 0x35, 0x7e, 0x83, 0xe8, 0x02, 0x16, 0xbd, 0xde, 0xeb, 0x23, 0x1a, 0x44, 0x40, 0xa5, 0xd7, 0xfc, - 0xa5, 0xc8, 0xe7, 0xaa, 0x10, 0xbd, 0xf7, 0xd6, 0xce, 0x9b, 0x19, 0xc9, 0x32, 0x69, 0xa4, 0xda, 0xad, 0x2c, 0xd6, - 0x95, 0x37, 0x3b, 0x21, 0x5d, 0xcc, 0x31, 0x54, 0x06, 0x8f, 0x03, 0x50, 0x7a, 0xfe, 0x25, 0xf4, 0x4a, 0x86, 0x4c, - 0xb3, 0x44, 0x33, 0xbb, 0x6b, 0xfc, 0xc9, 0x2a, 0xf5, 0x62, 0x44, 0xcc, 0x06, 0xb6, 0x10, 0xb7, 0x45, 0xa5, 0xdb, - 0xa2, 0x50, 0xb6, 0x28, 0xd2, 0x87, 0xda, 0x99, 0xee, 0xcc, 0xc2, 0x67, 0x95, 0x69, 0xdf, 0xdb, 0xcc, 0x8c, 0x0d, - 0xd0, 0x76, 0x11, 0xbe, 0x81, 0x0e, 0x54, 0x08, 0xf9, 0x8f, 0x88, 0x88, 0x44, 0xc0, 0x2e, 0xa7, 0xee, 0xc4, 0xa6, - 0x43, 0x32, 0x0f, 0x31, 0x2b, 0xd4, 0x28, 0x2f, 0x79, 0x72, 0x34, 0x20, 0x15, 0xa1, 0x6e, 0xf7, 0xfb, 0xe7, 0x4b, - 0x17, 0xd4, 0x7e, 0x4d, 0xb1, 0x63, 0x74, 0x53, 0xc0, 0xb9, 0xe0, 0x51, 0xde, 0x73, 0xef, 0x1c, 0xd0, 0x1c, 0xdb, - 0x53, 0x64, 0x0d, 0x38, 0xbd, 0xed, 0x42, 0x80, 0xed, 0xb3, 0x66, 0x6b, 0x7f, 0xb2, 0xba, 0x8a, 0xa6, 0x5e, 0xc9, - 0x67, 0xba, 0x8b, 0x12, 0xb7, 0x8b, 0x62, 0xd9, 0x45, 0x9b, 0x06, 0x82, 0x1d, 0x57, 0x7e, 0x00, 0xbc, 0xa1, 0x51, - 0xbf, 0x5f, 0xb6, 0x7a, 0xf6, 0xe4, 0x6b, 0xc7, 0x3d, 0x9b, 0xf9, 0xac, 0x34, 0x3d, 0xfb, 0x6b, 0xea, 0xf6, 0xac, - 0x9c, 0xec, 0x45, 0xe7, 0x64, 0x9f, 0xce, 0xe6, 0x81, 0xe0, 0x72, 0xe7, 0x3e, 0xcf, 0xa7, 0x7a, 0xda, 0x55, 0x7e, - 0xd0, 0x1a, 0x22, 0xf3, 0x85, 0xcf, 0x55, 0xf7, 0xba, 0x82, 0x05, 0x2c, 0xc1, 0xdd, 0x7a, 0x69, 0xfe, 0x2b, 0x76, - 0x7f, 0x2f, 0xe8, 0xa5, 0xf9, 0x6f, 0xf4, 0x27, 0x05, 0x70, 0x00, 0x1a, 0x53, 0xbb, 0x05, 0x1e, 0x62, 0xa8, 0xa0, - 0x70, 0x37, 0x2b, 0xe7, 0x5e, 0x0d, 0x70, 0x98, 0xa4, 0x6f, 0x68, 0xf5, 0x4a, 0x8b, 0x5d, 0x2f, 0x93, 0xbd, 0x02, - 0x3c, 0x54, 0x21, 0x0f, 0x0f, 0x87, 0xa8, 0x63, 0xd8, 0x41, 0x1d, 0x01, 0xc3, 0x1e, 0x42, 0x63, 0x0b, 0x3c, 0x1f, - 0x3f, 0x67, 0x7c, 0x2f, 0x40, 0x6d, 0x84, 0xf0, 0x78, 0xb5, 0x28, 0x43, 0x6c, 0xd9, 0x5b, 0xa4, 0x92, 0xfa, 0x59, - 0x20, 0xca, 0x68, 0x15, 0xd0, 0x56, 0x7b, 0xcc, 0xd2, 0x78, 0x03, 0xa1, 0x62, 0xa9, 0x8f, 0x21, 0x34, 0x70, 0xf8, - 0x1d, 0x0e, 0x20, 0xc1, 0x97, 0x5c, 0x93, 0xcd, 0xbd, 0xcd, 0xef, 0x69, 0x9f, 0x3f, 0x1c, 0xce, 0x2f, 0x11, 0x94, - 0x2e, 0x85, 0x8f, 0x54, 0x22, 0xaa, 0xa7, 0xb8, 0x29, 0x21, 0x9b, 0x25, 0x2b, 0xfd, 0xe0, 0x57, 0xf5, 0x0b, 0x00, - 0x64, 0x21, 0xd0, 0x26, 0x32, 0xfb, 0xd3, 0x99, 0x8a, 0x2e, 0x00, 0x0e, 0xf1, 0xc7, 0x4f, 0x10, 0x7d, 0x43, 0xcb, - 0xb4, 0x7c, 0x9c, 0xf0, 0x10, 0xb4, 0xb6, 0xa4, 0x93, 0x88, 0x95, 0x02, 0x1b, 0x22, 0xe1, 0xfb, 0xfd, 0xf3, 0x58, - 0xd2, 0x81, 0x46, 0xad, 0xee, 0x8d, 0x5b, 0xdd, 0x2b, 0x5f, 0xd7, 0x9d, 0xdc, 0xf8, 0xa0, 0x68, 0x9f, 0xcd, 0x1b, - 0x95, 0xef, 0xfb, 0x3a, 0x67, 0x77, 0xba, 0x77, 0xe4, 0x9c, 0xf8, 0xfe, 0x1e, 0x42, 0xd1, 0x43, 0x53, 0x64, 0x59, - 0x12, 0x06, 0xb4, 0xd6, 0xae, 0x3d, 0xcb, 0xe8, 0xe0, 0xb5, 0x6f, 0x08, 0x11, 0x79, 0x8a, 0x4f, 0x42, 0x6e, 0x71, - 0x7c, 0x50, 0xa0, 0x7f, 0x66, 0xfc, 0x99, 0x13, 0x3f, 0x6c, 0xf5, 0x0b, 0xe0, 0xdc, 0x74, 0xef, 0xdd, 0x89, 0x59, - 0x8f, 0xa1, 0x94, 0x8d, 0xff, 0xfb, 0x7d, 0x22, 0x0b, 0x74, 0x3a, 0xa2, 0x61, 0x20, 0xb8, 0x8b, 0xea, 0xff, 0x5e, - 0xf1, 0xba, 0x67, 0xad, 0xce, 0x97, 0x9f, 0x3a, 0x3d, 0xe9, 0xd5, 0xcb, 0xb8, 0x07, 0x54, 0xe8, 0x00, 0xe1, 0xbc, - 0xee, 0x37, 0x6c, 0xf7, 0xdd, 0x2f, 0xef, 0x8e, 0x5e, 0x06, 0x36, 0x29, 0x12, 0xdb, 0x4a, 0x3e, 0xeb, 0x81, 0xc2, - 0xaf, 0xc7, 0x7a, 0x75, 0xb1, 0xee, 0xb1, 0x1e, 0x6a, 0x01, 0xd1, 0xc3, 0x02, 0xd4, 0x7f, 0x3d, 0xfb, 0x34, 0x14, - 0x0e, 0xb2, 0x71, 0xaa, 0x40, 0x91, 0x05, 0xbf, 0x16, 0xa3, 0x75, 0x41, 0x80, 0xc8, 0x96, 0x90, 0x56, 0x9d, 0xcc, - 0x1e, 0x97, 0x5a, 0x92, 0xc1, 0x37, 0x01, 0x99, 0x1d, 0x58, 0x39, 0x41, 0xe9, 0xb8, 0x35, 0xe0, 0xca, 0x16, 0x8f, - 0x76, 0xfb, 0xd3, 0x20, 0x3b, 0x6b, 0x4e, 0x1a, 0xed, 0xc3, 0x3e, 0xcd, 0x03, 0x04, 0x22, 0x99, 0x8a, 0x20, 0xd7, - 0xdc, 0x5b, 0xd2, 0x47, 0x87, 0x73, 0x5e, 0xc8, 0x3f, 0xa7, 0x52, 0x87, 0x38, 0x94, 0x58, 0x03, 0x81, 0xca, 0x33, - 0x54, 0x39, 0x6c, 0x90, 0xe3, 0x9f, 0x1d, 0xc9, 0x4c, 0x62, 0xb2, 0xc8, 0xdd, 0x9a, 0xa9, 0xf0, 0x03, 0xc1, 0xc7, - 0x2c, 0xe7, 0xc0, 0x05, 0x36, 0x9b, 0xfb, 0x6a, 0x8a, 0x8b, 0x2b, 0xf0, 0xc7, 0x14, 0x7e, 0xc5, 0x53, 0xd8, 0x69, - 0xf7, 0xeb, 0xa2, 0x4a, 0x51, 0xb7, 0x51, 0x58, 0x54, 0xb2, 0x60, 0x5a, 0x43, 0x9a, 0xe8, 0x30, 0xfa, 0x83, 0x9c, - 0x81, 0x82, 0x90, 0x5f, 0x36, 0x0d, 0x30, 0x52, 0xc9, 0xe5, 0x41, 0x95, 0x04, 0x5e, 0x80, 0x6d, 0x50, 0xb1, 0x75, - 0x01, 0x41, 0xb6, 0x49, 0x51, 0xa6, 0x5f, 0x8b, 0xbc, 0x0e, 0xb3, 0xa0, 0x1a, 0xa5, 0xd5, 0x4f, 0xfa, 0x27, 0x30, - 0x6f, 0x53, 0x31, 0xaa, 0x55, 0x4c, 0x7e, 0xa3, 0xdf, 0x2f, 0x06, 0xad, 0x0f, 0x19, 0x7c, 0xf4, 0xda, 0x34, 0xf8, - 0x93, 0xd3, 0x60, 0x87, 0x89, 0x46, 0x00, 0x24, 0x73, 0x6a, 0xc9, 0x43, 0xd1, 0x1f, 0x41, 0x8e, 0x35, 0xaa, 0x9c, - 0x82, 0xc1, 0xfa, 0x8f, 0x47, 0x3b, 0x30, 0xf5, 0xe2, 0x68, 0x4b, 0x76, 0xd0, 0xca, 0x37, 0xc0, 0xfd, 0x1a, 0xd9, - 0x62, 0x96, 0x03, 0x34, 0x7b, 0x8d, 0xc8, 0xf8, 0xe4, 0x05, 0x30, 0x66, 0xeb, 0x2c, 0x8c, 0x44, 0x1c, 0x8c, 0x55, - 0x63, 0xc6, 0x0c, 0x0c, 0x5c, 0xa0, 0x6b, 0x99, 0x94, 0xa4, 0x21, 0x1d, 0x0c, 0x58, 0x29, 0x5b, 0x38, 0xe0, 0x45, - 0x73, 0xdc, 0x8e, 0x37, 0x2d, 0x1a, 0x0f, 0x6c, 0x17, 0xdb, 0xdf, 0xbf, 0x2c, 0xb6, 0xef, 0xc2, 0x2d, 0xe9, 0x15, - 0x72, 0x96, 0xd0, 0xcf, 0x9f, 0x64, 0x9f, 0x35, 0x9c, 0x9c, 0x0a, 0xcd, 0xd0, 0x52, 0x24, 0x94, 0xe2, 0x9d, 0x9e, - 0x14, 0x18, 0xcb, 0x58, 0xf8, 0x7b, 0xe0, 0x9c, 0x2e, 0x14, 0x91, 0x3b, 0x70, 0x1c, 0xdf, 0x40, 0x05, 0xa3, 0x86, - 0x83, 0x97, 0x31, 0x6c, 0x8b, 0x62, 0x16, 0x12, 0x4e, 0x21, 0x5c, 0xac, 0xb2, 0x7e, 0x5f, 0xfe, 0xa2, 0x2e, 0xba, - 0xc8, 0x64, 0xdd, 0x27, 0xe1, 0xc8, 0x8c, 0xe5, 0xd4, 0x0b, 0xc9, 0xf3, 0x9e, 0x27, 0xd3, 0xe4, 0x59, 0x1e, 0x44, - 0x00, 0xf9, 0x1c, 0xde, 0x87, 0x69, 0x06, 0x56, 0x69, 0x52, 0x7e, 0x84, 0xd2, 0x17, 0x9f, 0x57, 0x7e, 0xa0, 0xb3, - 0xe7, 0x26, 0x19, 0xde, 0xac, 0x5a, 0x6f, 0x52, 0xeb, 0xba, 0x78, 0xc0, 0xdf, 0x3b, 0x83, 0x8d, 0x73, 0x9d, 0x09, - 0x0e, 0xbc, 0x48, 0x6a, 0xbd, 0x66, 0xfc, 0x3a, 0xc3, 0x75, 0xa9, 0xda, 0xe8, 0xa3, 0x10, 0x9d, 0x43, 0xa6, 0x02, - 0x14, 0x8a, 0xb4, 0x7f, 0x50, 0x6a, 0x65, 0x52, 0x69, 0x23, 0x01, 0x74, 0x0f, 0x93, 0x06, 0x5b, 0x0c, 0x65, 0x2c, - 0x4d, 0xa2, 0xdc, 0x69, 0x10, 0x57, 0xf6, 0xe7, 0x4a, 0xe2, 0xd0, 0xb2, 0x48, 0xfe, 0xbd, 0xeb, 0xe9, 0x2b, 0xa4, - 0xee, 0x64, 0x81, 0xcc, 0x18, 0x2f, 0xf2, 0xf8, 0x33, 0x10, 0x66, 0x83, 0x36, 0x2a, 0x0a, 0x21, 0x64, 0x83, 0x18, - 0x34, 0x5e, 0xe4, 0xf1, 0x4b, 0x45, 0xe3, 0x21, 0x1f, 0x45, 0xbe, 0xfa, 0xab, 0xd4, 0x7f, 0x85, 0x3e, 0x33, 0xc1, - 0x23, 0x54, 0x13, 0xfd, 0xbb, 0xe7, 0xb3, 0x7b, 0x50, 0x1b, 0x46, 0x61, 0x66, 0xca, 0xaf, 0x7c, 0x53, 0x9c, 0xbd, - 0xfe, 0x8a, 0xae, 0xb2, 0xad, 0xfb, 0xd1, 0xa7, 0x23, 0x02, 0x6b, 0x63, 0x74, 0xc5, 0x8d, 0x01, 0xe4, 0x30, 0x79, - 0xbf, 0xa2, 0xb4, 0x1c, 0xd2, 0x20, 0x74, 0xd0, 0x10, 0xf4, 0x4a, 0xa2, 0x0f, 0x24, 0x16, 0x31, 0x86, 0x17, 0xe2, - 0x19, 0xa9, 0xc9, 0x44, 0x43, 0xbc, 0x22, 0xf6, 0x43, 0xb4, 0xe4, 0xd4, 0x44, 0x37, 0xc2, 0x14, 0x03, 0x89, 0x9d, - 0x41, 0x72, 0x92, 0xd4, 0xca, 0x2f, 0x9e, 0x49, 0xc2, 0x12, 0x3b, 0x0f, 0x31, 0x98, 0xd4, 0xd2, 0x9d, 0xde, 0x54, - 0xe9, 0xeb, 0x91, 0x96, 0x83, 0xf6, 0x01, 0xd8, 0xa5, 0xa4, 0xf7, 0x4f, 0x0a, 0x45, 0x7c, 0x0c, 0xe3, 0x18, 0xc2, - 0xb7, 0x88, 0xea, 0x0a, 0x9c, 0x6b, 0x05, 0x1a, 0xab, 0x81, 0x87, 0x66, 0x56, 0xcd, 0x87, 0x9c, 0x7e, 0x2a, 0x2d, - 0x7f, 0x8c, 0x68, 0x6c, 0xb4, 0x6e, 0x0e, 0x87, 0x3d, 0xad, 0x7a, 0xe9, 0x1c, 0x74, 0xd9, 0x4c, 0x62, 0xe2, 0x06, - 0xd2, 0xf5, 0xa3, 0xdf, 0x4c, 0xd8, 0x8b, 0xa8, 0x90, 0x4b, 0x21, 0x28, 0x68, 0x75, 0x20, 0x70, 0x28, 0xbc, 0x45, - 0x99, 0x2f, 0x62, 0xda, 0x40, 0x18, 0x7c, 0x7e, 0x20, 0x3f, 0xdf, 0x14, 0xa4, 0x62, 0xc7, 0xba, 0xf6, 0xfb, 0x9b, - 0xd2, 0x03, 0x3c, 0x39, 0x93, 0xe4, 0x69, 0x33, 0x84, 0x15, 0x01, 0x34, 0x66, 0x35, 0x59, 0x9c, 0x70, 0x65, 0x0e, - 0x3f, 0x55, 0x5e, 0xc9, 0x52, 0xa6, 0xce, 0x53, 0xbd, 0x00, 0xa2, 0x8e, 0x37, 0x68, 0x45, 0xea, 0x57, 0xe8, 0xec, - 0x35, 0x2b, 0x21, 0xe3, 0xe1, 0x39, 0xe7, 0xe9, 0xe8, 0x81, 0x25, 0x3c, 0xc2, 0xbf, 0x92, 0x89, 0x3e, 0xfc, 0x1e, - 0x38, 0xdc, 0x8c, 0x13, 0x1e, 0xb9, 0xcd, 0xde, 0x57, 0xe1, 0x0a, 0x6e, 0xa6, 0x05, 0x20, 0xb9, 0x05, 0x49, 0x13, - 0x50, 0x42, 0x22, 0x13, 0x32, 0x6b, 0x4a, 0x7e, 0x69, 0x69, 0x1b, 0xac, 0x61, 0xd2, 0x79, 0xc0, 0x8b, 0x56, 0x1f, - 0xad, 0x26, 0xda, 0x65, 0x96, 0xcf, 0x87, 0x38, 0x43, 0x35, 0xc7, 0xdd, 0x19, 0xfc, 0x1c, 0xf0, 0x8a, 0x55, 0x4d, - 0x3a, 0xda, 0x0d, 0xb8, 0xf0, 0xe4, 0x3a, 0x4f, 0x47, 0x5b, 0xfc, 0x25, 0xf7, 0x07, 0x80, 0x0e, 0xa6, 0x2e, 0x81, - 0x3f, 0x55, 0x5b, 0x4d, 0xa5, 0x5e, 0xb6, 0xf6, 0xeb, 0xba, 0xb3, 0x5a, 0xb9, 0x67, 0x5d, 0x86, 0xf6, 0xc8, 0x90, - 0x33, 0x66, 0xc0, 0x9f, 0x33, 0x96, 0xfc, 0x39, 0x63, 0xc5, 0x9f, 0x33, 0x6e, 0x8c, 0x0c, 0xa0, 0x04, 0xf7, 0x92, - 0x5f, 0xef, 0x11, 0x33, 0xc4, 0x6a, 0x50, 0x09, 0xac, 0x2c, 0xe5, 0xdc, 0x47, 0x4e, 0x31, 0xe5, 0x94, 0xe1, 0xa5, - 0xd3, 0x99, 0x3b, 0x90, 0xf3, 0x60, 0xe6, 0x0e, 0x93, 0xb3, 0x3e, 0xc5, 0xb1, 0x34, 0x26, 0x45, 0x05, 0xe9, 0x9c, - 0x0e, 0x37, 0xaf, 0x8e, 0xf3, 0x84, 0x65, 0x7c, 0xdc, 0x3e, 0x53, 0x20, 0xc4, 0x16, 0xcf, 0x90, 0x48, 0xa9, 0x9a, - 0xe5, 0x36, 0x7f, 0x38, 0xd4, 0xa3, 0x07, 0xbd, 0xd3, 0xc3, 0xaf, 0x84, 0xbd, 0xcc, 0x3c, 0xfb, 0x04, 0x01, 0x4c, - 0x12, 0x79, 0x26, 0xe1, 0xe8, 0xc7, 0x72, 0xf4, 0x37, 0x0d, 0xff, 0x9a, 0xa1, 0xba, 0x3b, 0x04, 0x26, 0xb6, 0xec, - 0xc0, 0x21, 0x38, 0x5d, 0x55, 0x22, 0x01, 0x07, 0x9b, 0x0d, 0x8b, 0xf4, 0x1e, 0x0f, 0x71, 0x3e, 0x28, 0x7c, 0x84, - 0x86, 0x19, 0xbd, 0xdf, 0xdf, 0x08, 0xaf, 0x92, 0xad, 0x3c, 0x1c, 0x12, 0xeb, 0x2e, 0xec, 0xe8, 0xe3, 0x68, 0x8f, - 0x12, 0x6a, 0x3f, 0xaa, 0xf5, 0xa6, 0x52, 0x0f, 0x72, 0xb3, 0x0b, 0x89, 0x41, 0xc5, 0x52, 0x7d, 0x7a, 0xa5, 0xfa, - 0x50, 0xb3, 0xce, 0xef, 0xea, 0xb8, 0x4f, 0xc5, 0x68, 0x2d, 0x27, 0x04, 0xb8, 0x0e, 0x12, 0x8d, 0x0e, 0x80, 0x71, - 0xb6, 0xd9, 0xf2, 0x52, 0x5b, 0x27, 0x4a, 0xc7, 0x71, 0xae, 0x8f, 0xe3, 0xc3, 0x41, 0x8a, 0x19, 0x97, 0x47, 0x62, - 0xc6, 0x65, 0x03, 0xf0, 0x66, 0x9d, 0x07, 0xf5, 0xe1, 0x70, 0x49, 0x97, 0x22, 0xd3, 0xd9, 0x46, 0xf9, 0x59, 0x8f, - 0x1e, 0x9e, 0x25, 0x68, 0xee, 0xad, 0xb0, 0xf7, 0x22, 0xd9, 0x9e, 0xc9, 0x3a, 0xf5, 0x32, 0xf2, 0xe9, 0x85, 0x7b, - 0x76, 0xc9, 0xd5, 0x0f, 0xab, 0xaf, 0xa7, 0xbf, 0x0a, 0x2f, 0x62, 0x15, 0xed, 0xd6, 0x25, 0x13, 0xf6, 0x96, 0x52, - 0x49, 0xab, 0xbc, 0x7c, 0xba, 0xf1, 0x03, 0xcc, 0x4c, 0x7b, 0xfa, 0x20, 0x1b, 0x51, 0xfd, 0x59, 0x89, 0x5a, 0x19, - 0x26, 0x0b, 0xe7, 0x25, 0x53, 0x4f, 0x06, 0x3c, 0x66, 0x25, 0x8f, 0x64, 0xa7, 0x37, 0x06, 0x41, 0x00, 0xeb, 0x9c, - 0xb4, 0xea, 0x8c, 0xa3, 0xd1, 0xaa, 0x72, 0x71, 0xba, 0xca, 0x05, 0x86, 0xdb, 0xad, 0xd9, 0x46, 0xd5, 0x59, 0x6e, - 0x6a, 0x95, 0xf2, 0x1d, 0xc0, 0xc7, 0xb2, 0xca, 0x05, 0x1d, 0x53, 0xa6, 0xce, 0x1b, 0x08, 0xc6, 0x56, 0x35, 0x2e, - 0x9c, 0x1a, 0x17, 0x3c, 0xa2, 0x76, 0x37, 0x4d, 0x3d, 0xda, 0x02, 0x4b, 0xe9, 0x68, 0xc7, 0x4b, 0x54, 0x29, 0xfc, - 0x4d, 0xf0, 0x7d, 0x18, 0xc7, 0x2f, 0x8b, 0xad, 0x3a, 0x10, 0x6f, 0x8b, 0x2d, 0xd2, 0xbe, 0xc8, 0xbf, 0x10, 0x07, - 0xbc, 0xd6, 0x35, 0xe5, 0xb5, 0x35, 0xa7, 0x81, 0xad, 0x61, 0xa4, 0xa4, 0x70, 0x6e, 0xfe, 0x3c, 0x1c, 0x68, 0x65, - 0xd7, 0xea, 0xae, 0x50, 0xeb, 0x31, 0x87, 0x0d, 0x7b, 0x91, 0x85, 0x3b, 0x51, 0x82, 0x23, 0x97, 0xfc, 0xeb, 0x70, - 0xd0, 0x2a, 0x4b, 0x75, 0xa4, 0xcf, 0xf6, 0x5f, 0x83, 0x31, 0x43, 0x97, 0x26, 0x60, 0xd9, 0x18, 0xc9, 0xbf, 0x9a, - 0x66, 0xde, 0x30, 0x59, 0x33, 0x85, 0xe3, 0xd0, 0x30, 0x42, 0x1a, 0xd0, 0x6d, 0x50, 0x1b, 0x9e, 0xcc, 0x37, 0x55, - 0xf9, 0xd5, 0x1d, 0xa9, 0xf6, 0x83, 0xe1, 0xe5, 0x44, 0x9c, 0xd3, 0x25, 0x49, 0x3d, 0x95, 0x50, 0x12, 0x82, 0x5d, - 0xfa, 0x40, 0x4e, 0xac, 0x80, 0xac, 0x65, 0x2c, 0xbf, 0xd5, 0x03, 0x42, 0xff, 0x69, 0xb7, 0x5e, 0xe8, 0x3f, 0x4d, - 0xb3, 0x85, 0xba, 0xfe, 0x30, 0xb9, 0xef, 0xe8, 0xf5, 0x07, 0x87, 0x77, 0xea, 0xaa, 0xe2, 0x2a, 0x1e, 0xd5, 0x86, - 0x49, 0x6e, 0x94, 0x85, 0xbb, 0x62, 0x53, 0xab, 0xe5, 0xe9, 0x38, 0x8c, 0xc0, 0x8c, 0xa0, 0x00, 0x59, 0xd7, 0x6d, - 0x44, 0x0c, 0x2b, 0xb9, 0x4c, 0xc8, 0x27, 0x04, 0x64, 0x51, 0x6a, 0x9c, 0x8f, 0x5b, 0xa0, 0x12, 0xc1, 0xe0, 0x34, - 0xb4, 0x56, 0xdd, 0xe4, 0x27, 0x95, 0x8d, 0xdd, 0x01, 0x39, 0x24, 0x99, 0x2c, 0xee, 0x46, 0xb7, 0x62, 0x59, 0x94, - 0xe2, 0x67, 0xac, 0x87, 0x6b, 0xb6, 0x70, 0x9f, 0x01, 0xa1, 0xfd, 0x44, 0x69, 0x6f, 0x22, 0x4d, 0xd0, 0x7d, 0xc7, - 0x56, 0x00, 0x32, 0x80, 0xa2, 0xae, 0x76, 0xeb, 0x73, 0x7e, 0x8e, 0xa4, 0x19, 0x0e, 0xa3, 0xdb, 0xa7, 0x77, 0xc1, - 0xdd, 0xe0, 0x12, 0xb5, 0xd2, 0x97, 0x2c, 0x6e, 0x61, 0x50, 0xed, 0xcd, 0x12, 0x0e, 0x6a, 0x66, 0xad, 0x8d, 0x40, - 0x30, 0xd9, 0x43, 0x41, 0xc5, 0x5c, 0xc1, 0x3e, 0x28, 0x58, 0x4b, 0x5e, 0x07, 0x87, 0x5b, 0xfb, 0xb2, 0x52, 0x5c, - 0x3c, 0xbf, 0x48, 0x5a, 0x17, 0x96, 0xf2, 0xe2, 0x79, 0x03, 0x06, 0x97, 0x23, 0x6c, 0xaa, 0xca, 0x9f, 0x6c, 0x00, - 0x74, 0x2b, 0xa2, 0x88, 0x17, 0xa5, 0xb0, 0x6d, 0xe5, 0x33, 0x27, 0x6c, 0xb0, 0x61, 0x0f, 0x70, 0xaf, 0x0c, 0x4a, - 0x06, 0x17, 0x62, 0xdc, 0x6e, 0x76, 0x01, 0xae, 0x60, 0x28, 0x8c, 0xad, 0xf9, 0x9b, 0xcc, 0x8b, 0x94, 0x80, 0x9b, - 0x21, 0xca, 0xd7, 0x06, 0x4e, 0x26, 0x3d, 0xb9, 0x96, 0x2c, 0x06, 0x2c, 0x68, 0xf0, 0x1d, 0xb5, 0xfe, 0xce, 0xe4, - 0xdf, 0x78, 0x7a, 0xe8, 0x07, 0x5f, 0x32, 0x6f, 0xe9, 0xb3, 0x37, 0x95, 0x8c, 0xd6, 0x24, 0x51, 0x5e, 0x3d, 0x5c, - 0x82, 0xdc, 0xb0, 0x1c, 0x3d, 0xb0, 0x25, 0x88, 0x13, 0xcb, 0x51, 0x42, 0x19, 0x5d, 0xe1, 0x5e, 0x65, 0xb6, 0x4c, - 0x04, 0x52, 0x1c, 0x58, 0x4a, 0xb9, 0xb7, 0x58, 0x07, 0x4b, 0xdc, 0x9f, 0x48, 0x2e, 0xa0, 0xe4, 0x01, 0x94, 0x2b, - 0x05, 0x04, 0x7c, 0x3a, 0x80, 0xf2, 0xa5, 0xbc, 0x08, 0x7f, 0xe2, 0x44, 0x0d, 0x96, 0xa3, 0x87, 0x86, 0xfd, 0xe4, - 0x85, 0x96, 0xfd, 0xe1, 0x4e, 0x6b, 0x1a, 0x56, 0xfc, 0x0e, 0xa6, 0xc5, 0xc4, 0xed, 0xcb, 0x95, 0x5d, 0x15, 0x9f, - 0xad, 0xd4, 0xd9, 0x4d, 0x0d, 0x49, 0xd8, 0x37, 0x64, 0x15, 0xe0, 0x60, 0x55, 0xc4, 0x3d, 0xcb, 0x72, 0x1f, 0x46, - 0x7f, 0x6e, 0xd2, 0x52, 0x58, 0xa8, 0x92, 0xfe, 0xbe, 0x29, 0x05, 0x52, 0x99, 0xe8, 0x44, 0x0b, 0xc1, 0x15, 0x18, - 0x04, 0xee, 0x45, 0x5e, 0x03, 0x60, 0x0c, 0xb8, 0x14, 0x28, 0xcb, 0xb6, 0x84, 0x90, 0xea, 0x7e, 0x06, 0x6a, 0x3b, - 0x71, 0x9f, 0x46, 0x64, 0x2d, 0x44, 0x5f, 0x05, 0x63, 0xe6, 0xbc, 0x94, 0x6e, 0xb1, 0xe9, 0x6a, 0xb3, 0xba, 0x41, - 0xe7, 0xd2, 0x96, 0x9b, 0x9f, 0xb0, 0xc5, 0x5a, 0x81, 0xb2, 0x09, 0x49, 0xdb, 0x39, 0xcf, 0x51, 0x36, 0xa1, 0xa5, - 0xbd, 0xa7, 0x1e, 0x15, 0xaa, 0x93, 0xad, 0x97, 0xaa, 0xa9, 0x45, 0x58, 0x2d, 0x2e, 0x2a, 0x3f, 0x00, 0xdd, 0x54, - 0x5a, 0xbd, 0xa8, 0x6b, 0x34, 0x85, 0x5a, 0x2d, 0x1c, 0x37, 0xda, 0xd9, 0x74, 0x99, 0xde, 0x21, 0xce, 0xaa, 0xb4, - 0x43, 0xff, 0x92, 0x69, 0xd7, 0xcb, 0x8e, 0x7e, 0x33, 0xae, 0x2e, 0x70, 0x21, 0x36, 0xe0, 0x73, 0xee, 0x2f, 0xaf, - 0xf7, 0x3c, 0xee, 0xf9, 0x87, 0x03, 0xb2, 0x27, 0xb5, 0x3f, 0x54, 0x1f, 0xbb, 0x82, 0x21, 0x0b, 0xa3, 0xd4, 0x5f, - 0xa4, 0xbc, 0xf7, 0x04, 0xc7, 0xfd, 0x4b, 0xd5, 0x63, 0x3f, 0x65, 0x7c, 0x5f, 0x17, 0x9b, 0x28, 0xa1, 0xa8, 0x86, - 0xde, 0xaa, 0xd8, 0x54, 0x22, 0x2e, 0x1e, 0xf2, 0x1e, 0xc3, 0x64, 0x18, 0x0b, 0x99, 0x0a, 0x7f, 0xca, 0x54, 0xf0, - 0x08, 0xa1, 0xc4, 0xcd, 0xba, 0x47, 0xda, 0x4d, 0x88, 0x53, 0xaa, 0x45, 0x29, 0x93, 0xf1, 0x6f, 0xfd, 0x04, 0xca, - 0x73, 0x8a, 0x96, 0xe9, 0x47, 0x85, 0xcb, 0xf4, 0xcd, 0xfa, 0xb8, 0xf4, 0x4c, 0x84, 0x3a, 0x73, 0xb1, 0xa9, 0x75, - 0x3a, 0xc6, 0x4e, 0xe9, 0xd4, 0x86, 0xbd, 0xaf, 0x14, 0x97, 0x15, 0x85, 0x7f, 0x23, 0x91, 0x55, 0xcf, 0x88, 0xe3, - 0xff, 0xcc, 0xda, 0x67, 0x58, 0x05, 0x7e, 0x19, 0xc8, 0xfb, 0x05, 0xc0, 0xc7, 0x75, 0x5d, 0xa6, 0xb7, 0x1b, 0xa0, - 0x0d, 0xa1, 0xe1, 0xef, 0xf9, 0xc8, 0x80, 0xe9, 0x3e, 0xc2, 0x19, 0xd2, 0x43, 0x9d, 0x73, 0x3a, 0x2b, 0xd3, 0x39, - 0x57, 0x61, 0x2d, 0xc1, 0x5e, 0x4e, 0x9a, 0x5c, 0xae, 0x4b, 0x50, 0x33, 0x81, 0xdb, 0x87, 0xf6, 0x88, 0x10, 0x6a, - 0x53, 0x56, 0xd3, 0x4b, 0xa8, 0x79, 0x27, 0xa7, 0x1d, 0x4d, 0x4a, 0x70, 0xd5, 0xd0, 0x59, 0xb9, 0xfe, 0xeb, 0x70, - 0xe8, 0xdd, 0x66, 0x45, 0xf4, 0x47, 0x0f, 0xfd, 0x1d, 0xb7, 0x37, 0xe9, 0x57, 0x88, 0x96, 0xb1, 0xfe, 0x86, 0x0c, - 0xe8, 0x78, 0x32, 0xbc, 0x2d, 0xb6, 0x3d, 0xf6, 0x1e, 0x35, 0x58, 0xfa, 0xfa, 0xf1, 0x07, 0x48, 0xa8, 0xba, 0xf6, - 0x85, 0xc5, 0x13, 0xe6, 0x29, 0xd1, 0xb6, 0xf0, 0x21, 0x2c, 0xf4, 0x3d, 0x44, 0x46, 0x42, 0xb8, 0xa9, 0xec, 0x1e, - 0x25, 0xed, 0x42, 0x5f, 0xfa, 0x5a, 0xf6, 0x95, 0xef, 0x5c, 0x00, 0xac, 0xec, 0x73, 0x1b, 0xee, 0x49, 0x7f, 0x4a, - 0xf5, 0x61, 0xfb, 0x5b, 0xb2, 0x80, 0x42, 0x0b, 0xeb, 0xa9, 0x9c, 0x9d, 0xeb, 0x92, 0xa7, 0xd9, 0x74, 0xbf, 0x86, - 0x3d, 0xea, 0x1e, 0xbd, 0xa6, 0x82, 0xf3, 0x4b, 0x33, 0x7a, 0xff, 0x30, 0x14, 0xaa, 0xa3, 0xce, 0x1d, 0x64, 0x5d, - 0x5a, 0x97, 0x9c, 0xdf, 0xac, 0xdc, 0x51, 0x98, 0xdf, 0x87, 0xe0, 0x19, 0xd6, 0xbd, 0xbb, 0x38, 0xef, 0xfd, 0xd9, - 0x9a, 0x23, 0x3f, 0x65, 0xb3, 0x14, 0xb1, 0x48, 0xe6, 0x60, 0xf5, 0x43, 0x3f, 0x8f, 0xfd, 0x36, 0xc8, 0xe1, 0xb8, - 0x69, 0x40, 0x87, 0x0d, 0x99, 0xb5, 0x2f, 0x11, 0x38, 0xd5, 0x08, 0xd2, 0xd4, 0x04, 0x35, 0xcb, 0x43, 0x24, 0xb6, - 0x4b, 0xd9, 0x36, 0xc8, 0x75, 0x17, 0x4c, 0x73, 0xa4, 0x3d, 0x83, 0xf7, 0x4d, 0x9a, 0xa4, 0x42, 0xb3, 0x48, 0x5b, - 0x25, 0xe3, 0xdf, 0x91, 0x36, 0x53, 0xb2, 0xc7, 0xd6, 0xc0, 0x7b, 0x09, 0xca, 0xc9, 0x30, 0xc5, 0xf0, 0x1d, 0x5f, - 0xef, 0x3c, 0xe6, 0x9e, 0x73, 0xcc, 0x36, 0x29, 0x3b, 0x82, 0x49, 0xb2, 0xf1, 0x0d, 0xc5, 0x1b, 0x7e, 0xb8, 0xad, - 0x44, 0x09, 0xa0, 0x97, 0x05, 0xbf, 0x96, 0x36, 0x57, 0xe8, 0x76, 0xf7, 0x8e, 0x52, 0xf8, 0x25, 0x2f, 0x0f, 0x87, - 0x6d, 0xea, 0x85, 0xd0, 0xf9, 0x22, 0x7e, 0x0f, 0xe6, 0x30, 0x86, 0xd8, 0x8c, 0x00, 0x61, 0x8e, 0x0f, 0xa8, 0x83, - 0xf5, 0x23, 0x00, 0x8d, 0x13, 0x28, 0xc0, 0xe8, 0xab, 0x6d, 0x41, 0xdf, 0xf2, 0xe2, 0x22, 0x42, 0xd4, 0x28, 0xc0, - 0x44, 0x49, 0xb3, 0x18, 0x86, 0x03, 0x9d, 0xdf, 0x37, 0xb7, 0x75, 0x29, 0x70, 0xe8, 0x1d, 0xcb, 0xf0, 0xdf, 0xfe, - 0xc7, 0xda, 0xd2, 0xaa, 0xb2, 0xdd, 0x1a, 0xa7, 0x99, 0xff, 0xed, 0xb6, 0xd0, 0xf7, 0x5f, 0x09, 0xc5, 0xf3, 0x8e, - 0xd7, 0xed, 0xaf, 0x10, 0xbd, 0xaf, 0x5b, 0x79, 0x57, 0x6a, 0x37, 0xcc, 0x94, 0x3f, 0xa4, 0x79, 0x5c, 0x3c, 0x8c, - 0xe2, 0xd6, 0x91, 0x37, 0x49, 0xcf, 0x39, 0xff, 0x5a, 0xf5, 0xfb, 0xde, 0x57, 0x20, 0xe3, 0x7d, 0x25, 0x8c, 0x23, - 0x26, 0x71, 0xf0, 0xed, 0xc5, 0x28, 0xda, 0x94, 0xb0, 0x21, 0xb7, 0x4f, 0x4b, 0xd0, 0xcc, 0xf4, 0xfb, 0x28, 0x51, - 0x5a, 0xf3, 0xfd, 0x2f, 0x72, 0xbe, 0xbf, 0x12, 0xf2, 0x66, 0x25, 0x3f, 0x7c, 0xb4, 0xc2, 0xc0, 0xf7, 0x38, 0xfd, - 0x2a, 0x7a, 0xec, 0xae, 0xf4, 0xe1, 0xbb, 0xd2, 0xd2, 0x67, 0x15, 0xf5, 0x77, 0x54, 0xd4, 0xbc, 0x12, 0x23, 0x22, - 0x1e, 0x04, 0xed, 0x6c, 0xbb, 0xd4, 0xae, 0x25, 0x68, 0x17, 0x6c, 0x0a, 0xfb, 0xd7, 0xa3, 0x43, 0xde, 0xef, 0x7f, - 0xca, 0xbd, 0x16, 0xaf, 0xbb, 0x0e, 0x4d, 0xf9, 0x6b, 0xe1, 0x21, 0x04, 0xb0, 0x96, 0x81, 0x32, 0x8e, 0x30, 0xe9, - 0x22, 0xaf, 0x51, 0x36, 0x9d, 0x08, 0x7c, 0xcc, 0xb2, 0x2b, 0x27, 0x99, 0x06, 0x98, 0x51, 0x4d, 0x61, 0x26, 0xc0, - 0x48, 0x7d, 0xc2, 0xba, 0xe9, 0x69, 0x15, 0x5a, 0xbe, 0x86, 0x60, 0x5d, 0x64, 0x19, 0x47, 0x31, 0x13, 0x00, 0x6c, - 0x3e, 0x81, 0x7c, 0x45, 0x57, 0x87, 0xa4, 0x95, 0x2a, 0xef, 0xd7, 0x19, 0x91, 0xd1, 0x24, 0x44, 0xf3, 0x5b, 0x78, - 0x60, 0xdf, 0x36, 0x33, 0xaa, 0xd4, 0x33, 0xaa, 0xf2, 0x19, 0x0e, 0x4b, 0xe1, 0x18, 0xf1, 0xff, 0x96, 0xaa, 0x1e, - 0x11, 0xe8, 0x55, 0x99, 0x56, 0x51, 0x91, 0xe7, 0x22, 0x42, 0x84, 0x6a, 0xe9, 0x1c, 0x0e, 0xfd, 0xd8, 0xef, 0xe3, - 0x40, 0x98, 0x17, 0xff, 0xfa, 0x58, 0x57, 0xfe, 0xb5, 0xc0, 0xb5, 0x92, 0x02, 0xa7, 0xa2, 0x46, 0x88, 0x10, 0xde, - 0x9f, 0xc0, 0xb3, 0x9a, 0xfa, 0x7e, 0x63, 0x99, 0xe8, 0xfe, 0x91, 0x01, 0xe5, 0x0f, 0xc8, 0xd7, 0x95, 0x14, 0x67, - 0xea, 0xe4, 0x31, 0x71, 0xc6, 0x01, 0x88, 0xf9, 0xb6, 0x44, 0xa3, 0xb1, 0xff, 0x01, 0x09, 0x86, 0xea, 0x07, 0x3b, - 0xdd, 0xd4, 0xfb, 0x67, 0x26, 0x71, 0x14, 0x7d, 0xda, 0x26, 0x8f, 0x25, 0x4b, 0xa3, 0x85, 0xa3, 0xf7, 0x88, 0x61, - 0x1c, 0x4e, 0xe7, 0x63, 0x92, 0x6d, 0x4c, 0x56, 0x01, 0xa4, 0x93, 0x99, 0x3a, 0xa6, 0xd4, 0xd1, 0x38, 0xd7, 0x0b, - 0xaa, 0xd0, 0x63, 0x5d, 0xf2, 0x1c, 0xac, 0x27, 0x3f, 0x7a, 0xa5, 0x3f, 0x15, 0x72, 0x0e, 0x1b, 0x89, 0xa0, 0xf0, - 0x03, 0x5c, 0x0d, 0x56, 0x0a, 0x18, 0x4c, 0x7d, 0x0b, 0x5f, 0x13, 0xcf, 0x51, 0xf0, 0x28, 0xec, 0x62, 0x6c, 0xad, - 0x7c, 0xe7, 0x93, 0x82, 0x72, 0xcf, 0x8a, 0x39, 0xaf, 0x80, 0x73, 0x19, 0x14, 0xc2, 0x74, 0x3c, 0xcb, 0xff, 0x99, - 0xe4, 0xf5, 0xc4, 0x86, 0x00, 0x19, 0xfc, 0x29, 0x71, 0x5a, 0xba, 0x43, 0x77, 0x1e, 0x7a, 0x16, 0x71, 0xd8, 0xe8, - 0xc9, 0xba, 0x2c, 0xb6, 0x29, 0xea, 0x25, 0xcc, 0x0f, 0xe4, 0xe7, 0x2d, 0xf9, 0x3e, 0x44, 0xf1, 0x36, 0xf8, 0x35, - 0x63, 0xb1, 0xc0, 0xbf, 0xfe, 0x96, 0x31, 0x9a, 0x68, 0xc1, 0xbf, 0xb2, 0x06, 0x89, 0x8a, 0xff, 0x9a, 0x4d, 0x00, - 0xd6, 0x91, 0xab, 0x0f, 0x9f, 0x12, 0xe3, 0xad, 0xd9, 0xf0, 0xc8, 0x37, 0x2b, 0xd0, 0xa9, 0xcf, 0xdd, 0x95, 0xed, - 0xa9, 0x6a, 0xfc, 0x2d, 0xd5, 0xd5, 0x48, 0x55, 0x35, 0xfe, 0x96, 0x52, 0x35, 0x7e, 0xcb, 0x28, 0x7e, 0xa7, 0xf2, - 0x19, 0x32, 0x27, 0x9b, 0x98, 0xa4, 0xd3, 0xf7, 0x86, 0x13, 0xbb, 0xec, 0x37, 0x6f, 0x13, 0x99, 0x89, 0x14, 0x72, - 0x6f, 0x00, 0xda, 0x7e, 0x97, 0x1b, 0x4e, 0x89, 0xf3, 0x73, 0x0f, 0x57, 0x6c, 0x5a, 0xbd, 0xa2, 0x05, 0x0b, 0x6c, - 0x5e, 0x66, 0x79, 0x8a, 0x04, 0xb6, 0x4d, 0x99, 0xf5, 0xe7, 0xdc, 0x03, 0x08, 0x66, 0x52, 0x13, 0x00, 0xd2, 0x42, - 0x54, 0x0a, 0x91, 0xbf, 0xc2, 0x59, 0x7d, 0xce, 0x7b, 0x9b, 0x3c, 0x26, 0xd2, 0xea, 0x5e, 0xbf, 0x9f, 0x9e, 0xa5, - 0x39, 0x05, 0x35, 0x1c, 0x67, 0x9d, 0xfe, 0x92, 0x05, 0x75, 0x22, 0x57, 0xe9, 0xdf, 0xdd, 0x20, 0x2f, 0xe3, 0xfb, - 0xba, 0xed, 0xf9, 0x13, 0xf5, 0xf7, 0xce, 0xfa, 0xdb, 0x02, 0xc1, 0x9d, 0x1c, 0xfb, 0xc9, 0xaa, 0x94, 0x27, 0xc6, - 0xa5, 0xbd, 0xe7, 0x37, 0x75, 0x51, 0x64, 0x75, 0xba, 0xfe, 0x28, 0xf5, 0x34, 0xba, 0x2f, 0xf6, 0x60, 0x0c, 0xde, - 0x01, 0xe0, 0x99, 0x0e, 0x0d, 0x90, 0xbe, 0x67, 0xe4, 0xe1, 0x3e, 0xb7, 0xe4, 0x27, 0x95, 0xb5, 0x49, 0xc2, 0x8a, - 0x62, 0x33, 0x8c, 0x11, 0x4a, 0xc6, 0x69, 0x6c, 0xfd, 0x7e, 0x5f, 0xfd, 0xbd, 0xc3, 0x28, 0x2a, 0x2a, 0xee, 0x18, - 0x8d, 0xca, 0xaa, 0x1e, 0x6d, 0x07, 0x87, 0xc3, 0x79, 0x6e, 0xe3, 0x68, 0xeb, 0x15, 0xb0, 0xb7, 0x42, 0xa5, 0xec, - 0x95, 0x08, 0xcb, 0x0f, 0x57, 0x7e, 0xbf, 0x0f, 0xff, 0xca, 0x48, 0x0b, 0xcf, 0x9f, 0xe2, 0xaf, 0x45, 0x5d, 0x60, - 0x78, 0x06, 0xad, 0xd1, 0x0a, 0x82, 0x09, 0xfe, 0xde, 0x81, 0x7a, 0x69, 0xa5, 0x7d, 0x02, 0xdd, 0x0a, 0xf4, 0xa0, - 0x1e, 0xfa, 0x34, 0x69, 0x5f, 0x48, 0xd4, 0xed, 0xad, 0x4e, 0xa3, 0x3f, 0x2a, 0xb8, 0x9c, 0xc2, 0xe4, 0x70, 0x43, - 0x9f, 0x56, 0xe1, 0xf6, 0x33, 0x3c, 0xfd, 0x19, 0x28, 0xb7, 0x0e, 0x87, 0x1c, 0xc4, 0x16, 0x70, 0xf3, 0x58, 0x85, - 0x5f, 0x8a, 0x52, 0x46, 0xd4, 0xc7, 0xd3, 0x02, 0xb4, 0x77, 0x01, 0x3a, 0x60, 0x69, 0x10, 0xaf, 0x90, 0x3c, 0x67, - 0x23, 0x80, 0x65, 0x07, 0x96, 0xb3, 0x8c, 0x53, 0x98, 0x67, 0x79, 0xad, 0x56, 0xda, 0x59, 0x99, 0x78, 0x35, 0xcb, - 0xc0, 0x59, 0xe0, 0xa2, 0xf2, 0x59, 0xa6, 0x55, 0x4f, 0x55, 0x82, 0x3e, 0xaf, 0xe4, 0x04, 0x57, 0x82, 0x93, 0x0d, - 0xc8, 0x2f, 0x40, 0x92, 0xa6, 0x94, 0x35, 0xe5, 0xf5, 0x25, 0xdd, 0x90, 0xd1, 0x73, 0xde, 0xf3, 0xa2, 0x61, 0xe8, - 0x5f, 0x78, 0x25, 0x84, 0x6f, 0xe2, 0xb6, 0x8d, 0x52, 0xd8, 0x5f, 0x04, 0x16, 0x9f, 0xb0, 0x1f, 0xbd, 0xa5, 0x3f, - 0x1d, 0x07, 0xe1, 0x10, 0xb9, 0xa1, 0x62, 0x0e, 0xec, 0x69, 0xc0, 0x62, 0x13, 0x5f, 0x6d, 0x26, 0xf1, 0x60, 0xe0, - 0xeb, 0x8c, 0xc5, 0x2c, 0x06, 0x1a, 0xe4, 0x78, 0x70, 0x39, 0xd7, 0x27, 0x84, 0x7e, 0x18, 0x51, 0x39, 0x2a, 0xd0, - 0x39, 0x88, 0x06, 0x4b, 0xc0, 0x53, 0x6f, 0x65, 0x83, 0x24, 0x63, 0x92, 0x49, 0x5c, 0x6b, 0x92, 0xea, 0x70, 0x42, - 0xeb, 0x40, 0xc7, 0xd5, 0x05, 0x74, 0x3e, 0xae, 0x7b, 0x1f, 0xaf, 0x86, 0x0b, 0x2a, 0xfd, 0x42, 0x0c, 0xbc, 0x7a, - 0x3a, 0x0e, 0x2e, 0xe9, 0x56, 0xb8, 0x58, 0x85, 0xdb, 0x9f, 0xe5, 0x03, 0xc7, 0x1d, 0x95, 0x34, 0x04, 0x06, 0x6f, - 0x0f, 0xdd, 0xcd, 0x0c, 0x0d, 0x75, 0xd2, 0x3e, 0x8c, 0x43, 0x39, 0xc4, 0xaa, 0x15, 0x17, 0xd2, 0x1b, 0xc1, 0xb7, - 0x0b, 0xc5, 0x58, 0x36, 0x76, 0x69, 0x28, 0x0a, 0x7f, 0x05, 0xb0, 0x43, 0xed, 0xaf, 0x54, 0xf2, 0x31, 0x32, 0xaa, - 0x69, 0xa0, 0x63, 0x00, 0x96, 0x2c, 0x4d, 0x24, 0x55, 0xa4, 0x91, 0xf8, 0x23, 0x33, 0xd6, 0x51, 0xd3, 0xf5, 0x05, - 0x53, 0xd5, 0x22, 0xe9, 0x76, 0x26, 0xb1, 0x9c, 0x48, 0x52, 0xdb, 0x7d, 0x44, 0x0c, 0x06, 0x3e, 0xd8, 0x88, 0x69, - 0x26, 0xc2, 0x11, 0x8f, 0x4a, 0x64, 0xd1, 0xe5, 0xb7, 0x51, 0x26, 0x6d, 0x5f, 0x56, 0x64, 0x0b, 0x82, 0xe9, 0x49, - 0xf4, 0x41, 0x92, 0x72, 0x2a, 0x12, 0x69, 0x46, 0x08, 0xf0, 0xe3, 0x49, 0x79, 0xa5, 0x3f, 0x07, 0x4d, 0x2b, 0xc1, - 0x4b, 0x06, 0xc9, 0x23, 0xf1, 0x33, 0x29, 0x98, 0xc5, 0x58, 0x35, 0x18, 0x60, 0x39, 0xd5, 0x33, 0xc7, 0x24, 0xfd, - 0x97, 0x4e, 0x27, 0xec, 0x17, 0x5e, 0x6e, 0x6b, 0x79, 0xd3, 0xdc, 0x7b, 0xe1, 0x55, 0x2c, 0xd5, 0xb0, 0x0c, 0xfa, - 0xaf, 0x89, 0x76, 0xc1, 0xd6, 0x96, 0x31, 0x61, 0xd5, 0x0f, 0x20, 0xed, 0x91, 0x2e, 0xaf, 0x1a, 0xe6, 0x4c, 0xf0, - 0xe8, 0xc2, 0x9a, 0x07, 0xd1, 0x85, 0xf0, 0x91, 0xcb, 0x6e, 0x92, 0x5c, 0x8d, 0x27, 0x7e, 0x38, 0x18, 0x28, 0x00, - 0x5a, 0x5a, 0x27, 0xc5, 0x20, 0x7c, 0x26, 0xe4, 0x40, 0x1a, 0x1d, 0x55, 0x01, 0x16, 0xcb, 0xec, 0xaa, 0x9c, 0x64, - 0x83, 0x81, 0x0f, 0x62, 0x63, 0x62, 0x37, 0x34, 0x9b, 0xfb, 0xec, 0x44, 0x41, 0x56, 0x9b, 0xc3, 0xd6, 0x4c, 0xb7, - 0xc0, 0x00, 0x60, 0x10, 0x11, 0x2c, 0xf7, 0xb9, 0x91, 0x8f, 0xa8, 0xd3, 0x53, 0x18, 0x01, 0xc1, 0x2f, 0x27, 0x02, - 0x91, 0x8b, 0x04, 0xea, 0x01, 0x66, 0x02, 0xcc, 0xa8, 0x62, 0x78, 0x09, 0xec, 0xe2, 0xb9, 0x79, 0xc5, 0xa0, 0x7f, - 0xd1, 0x24, 0x4b, 0x34, 0x95, 0x38, 0x1a, 0x23, 0xa7, 0xd2, 0x18, 0x19, 0x10, 0xbb, 0x38, 0xfe, 0x3d, 0xa5, 0x47, - 0x41, 0xca, 0xbe, 0x54, 0x86, 0x38, 0x1c, 0xc5, 0x57, 0xb0, 0x6a, 0x1c, 0x0e, 0xb5, 0x79, 0x3d, 0x9d, 0xd5, 0xf3, - 0x81, 0x08, 0xe0, 0xbf, 0xa1, 0x60, 0x2f, 0x35, 0x15, 0xb9, 0x41, 0xea, 0x3c, 0x1c, 0x52, 0x90, 0x4f, 0x75, 0x93, - 0x7f, 0xa9, 0xdc, 0xfd, 0x74, 0x36, 0xb7, 0xe6, 0xe8, 0x45, 0x8d, 0xeb, 0xd6, 0xea, 0x86, 0x42, 0xa2, 0x35, 0x4d, - 0x8a, 0xab, 0x6a, 0x52, 0x0c, 0x78, 0xee, 0x0b, 0xd5, 0xc5, 0xd6, 0x08, 0x16, 0xfe, 0xdc, 0x02, 0x61, 0x32, 0xee, - 0xc5, 0x47, 0x0b, 0x39, 0xa5, 0x5d, 0x5b, 0xed, 0xb6, 0x95, 0x0d, 0x29, 0x9a, 0x0f, 0x2f, 0x61, 0x97, 0x4e, 0x11, - 0x6d, 0xbb, 0x24, 0xf8, 0x02, 0xb4, 0xac, 0x2e, 0x44, 0x1e, 0xd3, 0xaf, 0x90, 0x5f, 0x8a, 0xe1, 0x7f, 0x4a, 0xf7, - 0xe6, 0xd4, 0x06, 0x39, 0x80, 0xed, 0xde, 0xc3, 0xed, 0x18, 0x3d, 0x90, 0xc1, 0x1b, 0x21, 0xe7, 0x9c, 0x5f, 0x4e, - 0xad, 0x19, 0x13, 0x0d, 0x0b, 0x56, 0x0e, 0x23, 0x3f, 0x40, 0xc6, 0xcb, 0x29, 0xb0, 0xb2, 0x1f, 0x15, 0x71, 0xe9, - 0x0f, 0x23, 0xff, 0xe2, 0x79, 0x90, 0x71, 0x2f, 0x1a, 0x76, 0x7c, 0x01, 0xf6, 0xea, 0x8b, 0xe7, 0x2c, 0x1a, 0xf0, - 0xea, 0xaa, 0x9e, 0x66, 0xc1, 0x30, 0x63, 0xd1, 0x55, 0x31, 0x04, 0x1f, 0xda, 0xeb, 0x72, 0x10, 0xfa, 0xbe, 0xd9, - 0x39, 0x74, 0x37, 0x24, 0xf2, 0x08, 0xfb, 0x09, 0xdc, 0x76, 0xb5, 0xc4, 0x0c, 0x26, 0x9b, 0xbb, 0x88, 0x19, 0x6c, - 0xf9, 0x8b, 0xe7, 0x86, 0x4b, 0xa8, 0xba, 0x96, 0x9a, 0x8d, 0x02, 0xcd, 0xc9, 0x15, 0x9a, 0x93, 0x95, 0x50, 0x4b, - 0x3e, 0xa9, 0x70, 0xc2, 0xce, 0x27, 0xb9, 0xb2, 0x1b, 0x8d, 0x31, 0x70, 0xd1, 0x9e, 0xdb, 0xc2, 0xc8, 0x4c, 0x67, - 0x29, 0x1a, 0xb0, 0xf0, 0x4c, 0x9c, 0xd2, 0x18, 0xd0, 0xbe, 0x1c, 0x58, 0xda, 0x90, 0x9f, 0xe4, 0xcc, 0x40, 0xdb, - 0x90, 0xd2, 0xa8, 0x19, 0xf8, 0x33, 0x35, 0x61, 0x7e, 0x05, 0x2b, 0x11, 0x44, 0x75, 0x01, 0x26, 0x49, 0x4e, 0x46, - 0x23, 0x65, 0x25, 0x92, 0x73, 0xc0, 0xfb, 0x04, 0x9e, 0x2c, 0x62, 0x5b, 0xfb, 0x53, 0xfa, 0x5f, 0x1d, 0x3e, 0x97, - 0xfe, 0x33, 0x01, 0x2c, 0xe4, 0xd2, 0x20, 0x32, 0x50, 0x38, 0xa4, 0xa6, 0x12, 0x71, 0xe2, 0x78, 0x06, 0xbe, 0x81, - 0x0b, 0x34, 0x05, 0xf4, 0x07, 0x35, 0xa3, 0x88, 0x2c, 0xfc, 0xd5, 0xb3, 0x9b, 0xba, 0xd1, 0xf3, 0xcc, 0x79, 0x0d, - 0x9a, 0x19, 0x08, 0xe9, 0x71, 0xaa, 0xde, 0x86, 0x44, 0xe7, 0xe5, 0xa5, 0x7e, 0x99, 0x10, 0xc9, 0x8a, 0xc8, 0xd3, - 0xf7, 0x39, 0x98, 0x47, 0x14, 0xa1, 0x83, 0x2b, 0xf3, 0x70, 0x38, 0x17, 0x14, 0xbe, 0xa3, 0x3c, 0x1f, 0x70, 0x9a, - 0x45, 0x09, 0x68, 0x03, 0x59, 0x6e, 0xca, 0x5c, 0x27, 0x2d, 0x53, 0xf7, 0x1e, 0xac, 0x04, 0x15, 0xba, 0x39, 0x05, - 0x85, 0x32, 0x12, 0x94, 0xd2, 0x6a, 0x10, 0x4a, 0x75, 0x58, 0x04, 0x91, 0x43, 0x16, 0x02, 0x6e, 0xa6, 0xa2, 0xd1, - 0x92, 0x86, 0x47, 0x38, 0x37, 0x50, 0x08, 0x40, 0x62, 0x4f, 0x15, 0x65, 0x5c, 0x0e, 0x01, 0x1f, 0x25, 0x1c, 0xe2, - 0xac, 0x49, 0x5b, 0x9e, 0x83, 0x38, 0x96, 0x4b, 0xbe, 0xae, 0x10, 0x0c, 0x22, 0xf4, 0x19, 0xf2, 0x27, 0xcb, 0xf9, - 0x77, 0xeb, 0x30, 0xed, 0x08, 0x1f, 0x76, 0xb5, 0x05, 0x17, 0xb3, 0xdb, 0xf9, 0x04, 0xe2, 0x5b, 0x6e, 0xe7, 0xc7, - 0x18, 0x22, 0x0b, 0x7f, 0x70, 0x37, 0x94, 0x5c, 0x51, 0xe8, 0xb2, 0x1e, 0x91, 0x22, 0x7b, 0xba, 0xe6, 0x08, 0x82, - 0x03, 0xad, 0x1a, 0x64, 0x68, 0x24, 0xbe, 0x78, 0x0e, 0x59, 0x83, 0x35, 0xff, 0x52, 0x91, 0xb3, 0xba, 0x3f, 0xd9, - 0x40, 0x35, 0xc9, 0x64, 0xad, 0xa8, 0x9c, 0xbf, 0x5d, 0x95, 0xe5, 0xc9, 0xaa, 0x0c, 0x57, 0x83, 0xae, 0xaa, 0x2c, - 0x39, 0x52, 0x1b, 0xa0, 0x35, 0x5d, 0x21, 0x86, 0x42, 0xd6, 0x60, 0x69, 0x55, 0x65, 0x4d, 0x7d, 0x02, 0x81, 0x3e, - 0xc0, 0x32, 0x6a, 0xf6, 0xd3, 0xe1, 0x3f, 0x83, 0x7f, 0xaa, 0x90, 0xa5, 0x3a, 0xad, 0x33, 0xf1, 0x6b, 0xb0, 0x64, - 0xf8, 0xc7, 0x6f, 0xc1, 0x1a, 0xb0, 0x04, 0xc8, 0x72, 0xb7, 0xb1, 0xd1, 0x7a, 0xe5, 0x15, 0xe2, 0x7d, 0xad, 0x2f, - 0xfa, 0xad, 0xdb, 0x44, 0xad, 0x00, 0x23, 0x14, 0x5a, 0x04, 0xd8, 0xea, 0x81, 0x7b, 0x0a, 0x7e, 0x20, 0x86, 0x73, - 0x4d, 0x5a, 0x53, 0x27, 0xbc, 0xce, 0xc6, 0x91, 0x88, 0xea, 0x2d, 0x5c, 0xdc, 0xeb, 0xad, 0xc5, 0xdf, 0xa8, 0x40, - 0x00, 0x64, 0x31, 0xc5, 0xda, 0x79, 0x43, 0x7a, 0x65, 0xd8, 0x49, 0xe8, 0xbd, 0x61, 0x27, 0x90, 0x17, 0x87, 0x9d, - 0x42, 0x97, 0x68, 0x3b, 0x45, 0x6a, 0xa2, 0xed, 0xa4, 0xc5, 0x2a, 0x2c, 0x21, 0xf8, 0x55, 0x7b, 0xeb, 0x28, 0xdb, - 0x17, 0x59, 0xc2, 0xb4, 0x05, 0x8c, 0x72, 0xab, 0x3e, 0x73, 0x8a, 0x58, 0x29, 0x7b, 0xa7, 0x93, 0x2a, 0x77, 0x91, - 0xcf, 0xad, 0xa6, 0xc8, 0xe4, 0x97, 0xc7, 0x2d, 0x92, 0x4f, 0x7e, 0x6e, 0x37, 0x4c, 0xa6, 0x7f, 0x3a, 0xfa, 0x02, - 0xba, 0x22, 0x3b, 0x7d, 0x02, 0x01, 0x99, 0x0a, 0xaa, 0xd5, 0xad, 0x62, 0x9a, 0xb7, 0xab, 0xec, 0xf6, 0x42, 0x89, - 0xe1, 0x74, 0x76, 0x12, 0x1e, 0x6d, 0x86, 0x0c, 0x1c, 0x82, 0x40, 0x21, 0x54, 0x14, 0xc3, 0x23, 0x50, 0x6b, 0x24, - 0x1f, 0xe0, 0x47, 0xbb, 0x53, 0x41, 0xa4, 0x76, 0x53, 0x71, 0xe3, 0xe4, 0xa6, 0xeb, 0xa5, 0x40, 0xad, 0x53, 0xb2, - 0x02, 0x28, 0x21, 0xea, 0xcf, 0x62, 0x5b, 0xbf, 0x82, 0x2b, 0x36, 0xdf, 0x37, 0x8a, 0x9e, 0x5c, 0x9f, 0xa2, 0x6e, - 0xc5, 0xd5, 0x69, 0xda, 0x6a, 0x8e, 0x1d, 0x67, 0xc8, 0xc1, 0xb3, 0x82, 0x60, 0x3b, 0x2a, 0x51, 0xbe, 0x6b, 0x37, - 0x1d, 0x13, 0x5b, 0xfd, 0xb3, 0xa8, 0x36, 0x77, 0x50, 0x11, 0x11, 0x1f, 0x65, 0x37, 0x4f, 0xda, 0xef, 0x60, 0x8f, - 0xb5, 0x1a, 0x44, 0xf6, 0x19, 0x5c, 0xe5, 0x3a, 0x2d, 0x72, 0x5b, 0x06, 0xe7, 0x1f, 0x5e, 0xed, 0x2a, 0x6c, 0x72, - 0xac, 0xab, 0xab, 0x99, 0xea, 0xa4, 0x62, 0x03, 0x63, 0x4d, 0x6b, 0xa9, 0xe6, 0x31, 0x24, 0xdd, 0x95, 0xc5, 0x59, - 0x95, 0x74, 0xd3, 0x73, 0xe3, 0x4c, 0x21, 0x06, 0xce, 0x56, 0xa3, 0xe5, 0x0c, 0x43, 0x74, 0x7d, 0x98, 0x25, 0x7e, - 0xab, 0xa7, 0xdc, 0xe7, 0xe1, 0xd6, 0xef, 0xea, 0x05, 0x27, 0x93, 0xfd, 0xe4, 0x38, 0x77, 0xbb, 0x48, 0xfb, 0x89, - 0x6f, 0xc3, 0xfc, 0xeb, 0x1b, 0xc4, 0x9d, 0xa8, 0xff, 0x51, 0x01, 0xd0, 0xe0, 0x26, 0x8f, 0x25, 0x4a, 0xfd, 0x5e, - 0x55, 0x3f, 0xa8, 0x99, 0xaa, 0x69, 0x20, 0x98, 0x53, 0x29, 0xe0, 0x0f, 0xb7, 0x0b, 0x57, 0x3c, 0xe2, 0x86, 0x85, - 0xf1, 0x4f, 0xaf, 0x66, 0xa7, 0x82, 0xca, 0xc0, 0xcd, 0xf8, 0x4f, 0x4f, 0xb0, 0x53, 0x58, 0x2b, 0x20, 0x2b, 0xfc, - 0xe9, 0xe5, 0x8f, 0xbc, 0x5f, 0xf1, 0x3f, 0xbd, 0xea, 0x91, 0xf7, 0x11, 0xe7, 0xe5, 0x4f, 0x24, 0x75, 0x42, 0x54, - 0x97, 0x3f, 0x09, 0x53, 0x6c, 0x95, 0xe6, 0xaf, 0x49, 0xe1, 0x13, 0x7c, 0x01, 0xbe, 0xc3, 0x55, 0xb8, 0x35, 0xbf, - 0xc1, 0x63, 0xc7, 0x62, 0xdb, 0xa5, 0xbe, 0x80, 0x72, 0x04, 0x16, 0x91, 0xdb, 0x6f, 0x57, 0xf6, 0xab, 0x85, 0x51, - 0xc6, 0xd8, 0x7d, 0xc9, 0x4a, 0x94, 0xce, 0xfa, 0xfd, 0x42, 0x0a, 0x46, 0x76, 0x61, 0x8d, 0xf6, 0x28, 0x55, 0xaf, - 0xbe, 0x0b, 0xeb, 0x28, 0x49, 0xf3, 0x3b, 0x19, 0x7d, 0x24, 0xc3, 0x8e, 0xf4, 0x95, 0x94, 0x68, 0xaf, 0x55, 0x58, - 0x8e, 0x66, 0xbf, 0x2e, 0x39, 0x50, 0x5e, 0xb7, 0x82, 0xf2, 0x55, 0x13, 0x40, 0xaf, 0x54, 0xfb, 0x0c, 0xb4, 0x82, - 0xc2, 0x52, 0x79, 0xb0, 0x12, 0xe7, 0xa2, 0xcf, 0x8a, 0xc3, 0x41, 0x5d, 0x0c, 0x09, 0x05, 0xaa, 0xc4, 0x49, 0x68, - 0xc4, 0x73, 0xb8, 0x10, 0x8a, 0xeb, 0x1c, 0x63, 0x2b, 0x72, 0xe0, 0x40, 0x86, 0x1f, 0x10, 0x78, 0x2f, 0xfb, 0x57, - 0x30, 0x18, 0x26, 0xb8, 0x91, 0x51, 0x27, 0xe7, 0xec, 0x4f, 0x0c, 0xcc, 0xa0, 0x9e, 0xd4, 0xee, 0xb3, 0x7b, 0x15, - 0xd8, 0x0b, 0x67, 0x40, 0x7b, 0x37, 0x46, 0x3f, 0xab, 0x62, 0xed, 0xa4, 0x7f, 0x2e, 0xd6, 0x90, 0x4c, 0x87, 0xc5, - 0xd1, 0x36, 0x0d, 0x8f, 0xe4, 0xc9, 0x71, 0xbc, 0xe9, 0x1f, 0x0e, 0x63, 0xfc, 0x38, 0xca, 0xaf, 0x2d, 0xe0, 0x55, - 0xdc, 0x42, 0x1a, 0x8b, 0x14, 0xbd, 0x03, 0x31, 0x87, 0xa2, 0x97, 0xec, 0xb7, 0x8c, 0x97, 0x13, 0x41, 0x29, 0x49, - 0x6c, 0x78, 0x47, 0x7a, 0x9a, 0xd6, 0xa3, 0xad, 0x0c, 0xd8, 0xaf, 0x47, 0x3b, 0xfa, 0x0b, 0x14, 0x8f, 0x16, 0xfe, - 0x92, 0xfe, 0x2e, 0xee, 0xe6, 0x9e, 0xf3, 0x4d, 0xe3, 0x3b, 0xe2, 0x02, 0xc5, 0x9a, 0xdd, 0x5f, 0xd3, 0xd2, 0x59, - 0x07, 0x82, 0x03, 0xde, 0x62, 0x17, 0xed, 0xfb, 0x8d, 0xeb, 0xf4, 0xb4, 0xff, 0xde, 0xad, 0x51, 0xbe, 0xf7, 0x0f, - 0x89, 0x72, 0xb0, 0x7f, 0xed, 0xa2, 0xf9, 0xdb, 0x4f, 0x19, 0x92, 0x0a, 0xcd, 0x0d, 0xb6, 0x93, 0x2d, 0xc2, 0xda, - 0x18, 0x07, 0x15, 0xbb, 0x2b, 0xc3, 0x08, 0x18, 0xd4, 0xb1, 0xff, 0xd1, 0x67, 0xd3, 0x86, 0xec, 0x03, 0x40, 0xe5, - 0x2a, 0x04, 0xec, 0x01, 0x38, 0xd1, 0x08, 0x37, 0xc0, 0xad, 0x46, 0x4b, 0x3a, 0xa8, 0xdb, 0x82, 0x81, 0x68, 0x09, - 0x1b, 0x79, 0xdb, 0xd5, 0xe9, 0x1b, 0xc2, 0x87, 0xda, 0x49, 0xe9, 0x50, 0xfe, 0xe6, 0x39, 0xfb, 0xef, 0x1d, 0xd6, - 0xd4, 0x94, 0x1b, 0xc0, 0xcc, 0x59, 0x89, 0xbc, 0x42, 0xe8, 0x14, 0xf9, 0xbd, 0xaa, 0x2b, 0x31, 0x5c, 0xd6, 0xa2, - 0xec, 0xcc, 0x6e, 0x9d, 0xe8, 0x9d, 0x53, 0x50, 0x4b, 0x65, 0x83, 0x9c, 0xa4, 0xda, 0x7c, 0x64, 0xad, 0xa0, 0x44, - 0x5d, 0xa3, 0xc0, 0xf1, 0x29, 0xd7, 0xee, 0xff, 0x9d, 0x33, 0x41, 0xcd, 0x36, 0xaa, 0xfb, 0x6b, 0xfd, 0x54, 0xd5, - 0x24, 0x16, 0xe0, 0x72, 0x92, 0xe6, 0x1d, 0x8f, 0xb0, 0xfa, 0xc7, 0xc9, 0x52, 0x04, 0x7a, 0x1d, 0xd1, 0xae, 0x04, - 0x24, 0x68, 0x27, 0x67, 0xa1, 0x22, 0x50, 0xa0, 0xaf, 0xbf, 0xdc, 0xa4, 0x59, 0x2c, 0x57, 0xb3, 0x3d, 0x4c, 0x94, - 0xc5, 0x7a, 0x88, 0x20, 0x67, 0xa6, 0x0e, 0xf6, 0x7b, 0x9a, 0xd1, 0x2c, 0xbc, 0x32, 0x25, 0xb8, 0x14, 0x57, 0x51, - 0x91, 0x83, 0xcf, 0x21, 0xbe, 0xf0, 0xb9, 0x90, 0x1b, 0x44, 0x34, 0xfd, 0x45, 0xa2, 0xda, 0x91, 0x02, 0x39, 0x94, - 0xfc, 0x84, 0xf8, 0x4b, 0xd6, 0xc6, 0xb8, 0x5f, 0x3a, 0xd5, 0x7e, 0xa5, 0x10, 0xdc, 0x7f, 0xb6, 0xc5, 0x46, 0x95, - 0x27, 0x7a, 0xf4, 0x29, 0xd6, 0xff, 0x64, 0x01, 0xa5, 0xba, 0x6f, 0x83, 0x53, 0xf1, 0x28, 0xdc, 0xd4, 0xc5, 0x0d, - 0x42, 0x0b, 0x94, 0xa3, 0xaa, 0xd8, 0x94, 0x11, 0x71, 0xc2, 0x6e, 0xea, 0xa2, 0xa7, 0x39, 0xd0, 0xa9, 0xc3, 0xd2, - 0x44, 0x9e, 0x08, 0xed, 0x16, 0x74, 0x4f, 0x73, 0xac, 0xc4, 0x0b, 0x59, 0x3a, 0xc8, 0x3a, 0x91, 0x26, 0x54, 0xee, - 0xea, 0xaa, 0xa3, 0x52, 0xa9, 0x1b, 0xde, 0xa4, 0x9a, 0xf1, 0x77, 0x69, 0xfe, 0xc4, 0xb2, 0xdf, 0xb4, 0x7e, 0xab, - 0xd5, 0xde, 0x58, 0x3d, 0x2a, 0x59, 0x73, 0x9c, 0x4d, 0x48, 0x4a, 0x9f, 0xb0, 0xdd, 0x4c, 0xba, 0xd6, 0x81, 0x27, - 0xc1, 0xe5, 0xd0, 0x13, 0x50, 0x31, 0x68, 0xe2, 0xed, 0x2e, 0x50, 0x8f, 0xc0, 0x33, 0x50, 0x3e, 0x51, 0xeb, 0x80, - 0x9f, 0xd7, 0x5a, 0x9e, 0x32, 0xc2, 0xb0, 0xda, 0x59, 0xb4, 0x1c, 0x9c, 0x77, 0x8a, 0xc0, 0xb5, 0x2b, 0x81, 0xe7, - 0x43, 0xf5, 0x5e, 0x08, 0x18, 0xee, 0x9f, 0x0b, 0x95, 0xcd, 0x6e, 0x86, 0xf3, 0xa8, 0x71, 0x7a, 0xa0, 0xbd, 0xed, - 0x5a, 0x0f, 0xf5, 0xae, 0xdb, 0xb9, 0xad, 0x74, 0xef, 0xd7, 0x4e, 0x26, 0x5d, 0x40, 0x6b, 0xf3, 0xd9, 0x77, 0x76, - 0xa5, 0x75, 0xd3, 0x73, 0xf6, 0x60, 0xeb, 0x96, 0xe8, 0x5c, 0x10, 0x4d, 0x7e, 0x3f, 0xf0, 0xac, 0x6d, 0x47, 0xbf, - 0x4d, 0x3b, 0xb6, 0xb9, 0x87, 0xba, 0x57, 0x50, 0xeb, 0x0d, 0xcd, 0xfb, 0x67, 0xae, 0x6d, 0xc7, 0x57, 0xbf, 0xae, - 0x3b, 0x5c, 0xe7, 0x4d, 0x70, 0xdc, 0x74, 0x6d, 0xab, 0x9d, 0xfd, 0xdc, 0xdd, 0x5b, 0x8b, 0x28, 0xcc, 0xb2, 0x9f, - 0x8a, 0xe2, 0x8f, 0x4a, 0xdf, 0x11, 0xe8, 0xe8, 0xce, 0x8b, 0x3a, 0x5d, 0xee, 0x3e, 0x12, 0xc6, 0x93, 0x57, 0x1f, - 0x11, 0xdd, 0xfa, 0x3e, 0x73, 0xbf, 0x02, 0xdc, 0x08, 0xee, 0x20, 0xda, 0xbb, 0xa5, 0x3e, 0xa9, 0xd5, 0xd7, 0x7a, - 0xed, 0x3c, 0x3d, 0xbf, 0xe9, 0xdc, 0x7e, 0xf7, 0xcd, 0xd1, 0xd6, 0x7b, 0x5c, 0x58, 0x2b, 0x4b, 0x4f, 0x55, 0xc1, - 0xde, 0x2c, 0x4f, 0x55, 0xc1, 0xe4, 0x81, 0xd7, 0xec, 0x17, 0x34, 0xb8, 0xd2, 0xd1, 0xc6, 0x7b, 0xa2, 0x06, 0x6e, - 0x51, 0x58, 0x3a, 0xfc, 0x92, 0x9b, 0xc9, 0x2b, 0xdc, 0x5f, 0x2a, 0x72, 0xb1, 0xef, 0x9c, 0xd1, 0x9d, 0x99, 0x75, - 0xaf, 0x2a, 0x5c, 0x2d, 0xc8, 0xd5, 0x81, 0xad, 0x65, 0x17, 0x87, 0x1b, 0x16, 0x51, 0x80, 0x40, 0x4c, 0xaf, 0xd4, - 0xda, 0x1f, 0xd1, 0x20, 0xe4, 0x83, 0x81, 0x5f, 0x60, 0xb0, 0x2a, 0x50, 0xf8, 0x40, 0x91, 0xfc, 0xb5, 0x27, 0x60, - 0x17, 0xcf, 0x00, 0xdd, 0x8a, 0xcd, 0x8a, 0x11, 0x22, 0x64, 0xb2, 0x9c, 0xd5, 0x74, 0x06, 0xf9, 0xd4, 0x17, 0xdf, - 0xd9, 0xaa, 0xd3, 0x79, 0x5b, 0x53, 0xe5, 0xd4, 0xa1, 0xd0, 0xdd, 0x4d, 0xdd, 0xb9, 0x75, 0x91, 0xa7, 0x0e, 0x21, - 0x57, 0x2a, 0x56, 0x62, 0x1a, 0x6a, 0x9e, 0xa4, 0x19, 0xf5, 0xa5, 0xbd, 0xdf, 0x6b, 0x14, 0x4e, 0xf9, 0xd3, 0x31, - 0xa8, 0xc2, 0x55, 0x0d, 0x71, 0x2c, 0x55, 0xf1, 0xc8, 0x06, 0x81, 0xe6, 0xd5, 0xad, 0x4a, 0x9a, 0x90, 0xc9, 0x8d, - 0xf0, 0xa9, 0x49, 0x29, 0x4f, 0xd3, 0x26, 0xad, 0x14, 0xa9, 0x83, 0x0f, 0xea, 0x54, 0xe3, 0xb9, 0x59, 0x5d, 0x03, - 0x98, 0x71, 0x7e, 0xc5, 0x2f, 0x15, 0x97, 0x51, 0x5b, 0x99, 0x49, 0xfb, 0x93, 0xa3, 0xb1, 0x51, 0x97, 0xd3, 0x46, - 0x19, 0x61, 0xa5, 0x34, 0x27, 0xc5, 0x72, 0x3c, 0xff, 0x80, 0xc1, 0x9a, 0x27, 0xb0, 0x83, 0x89, 0x4a, 0x79, 0x1f, - 0x01, 0xf1, 0x75, 0x92, 0xde, 0x25, 0x90, 0x22, 0xfd, 0x4b, 0x97, 0x3c, 0x75, 0x18, 0x1b, 0x88, 0x31, 0x2b, 0x66, - 0x46, 0xff, 0x83, 0xbb, 0xa4, 0x3f, 0x09, 0x01, 0x70, 0x13, 0x4d, 0xa1, 0x53, 0xe7, 0xc9, 0x45, 0x1e, 0x2c, 0x2f, - 0x3c, 0xb4, 0x62, 0xc4, 0x83, 0xff, 0xbc, 0x0e, 0x11, 0xc4, 0x1c, 0x53, 0x3c, 0xfd, 0xc2, 0xe8, 0x3f, 0x82, 0x4b, - 0x8c, 0x20, 0x74, 0xf7, 0xce, 0x61, 0x08, 0x37, 0x7b, 0x90, 0x41, 0xfd, 0xa1, 0x0e, 0x89, 0x1a, 0xfe, 0x54, 0x79, - 0xd0, 0xff, 0x75, 0x26, 0x2c, 0xb5, 0x9f, 0x9e, 0x0e, 0xa0, 0x82, 0xf7, 0x15, 0x6f, 0x23, 0xe2, 0xfb, 0xc4, 0xcf, - 0xe2, 0xc1, 0xe6, 0xd9, 0x06, 0xac, 0x75, 0x4f, 0x72, 0x63, 0x5d, 0x25, 0x6c, 0x20, 0xe0, 0x6b, 0x4c, 0x6b, 0xcf, - 0x6b, 0xb7, 0x7b, 0xf0, 0x9f, 0xfe, 0x45, 0xc8, 0x80, 0x89, 0xd3, 0xf7, 0x99, 0x93, 0x35, 0xba, 0xc8, 0x64, 0xfa, - 0xd0, 0x49, 0xdf, 0xe8, 0x74, 0xdf, 0x09, 0xff, 0xa8, 0x98, 0xc5, 0x87, 0x5b, 0xfa, 0x4a, 0x93, 0xe2, 0x0e, 0x58, - 0xd9, 0x3c, 0x2a, 0x08, 0x75, 0x2e, 0xa2, 0x6f, 0x4c, 0xf9, 0x96, 0x50, 0xb3, 0x6f, 0x2c, 0x29, 0xa5, 0x7b, 0x0d, - 0xbd, 0x49, 0x6b, 0xfd, 0x36, 0x4a, 0x30, 0x26, 0x3a, 0x9e, 0xbc, 0x8c, 0xc7, 0xca, 0xfb, 0x78, 0xdc, 0x48, 0x85, - 0x3c, 0x00, 0x11, 0xa8, 0x18, 0x7f, 0xba, 0xf2, 0xe4, 0xa4, 0x17, 0xc6, 0xab, 0x50, 0x0a, 0x0a, 0x03, 0xba, 0x02, - 0x29, 0xe0, 0x51, 0x7b, 0xa2, 0xb3, 0xb0, 0x4b, 0xb8, 0x47, 0x37, 0x01, 0x63, 0x7d, 0xfe, 0x09, 0xd0, 0xdc, 0x85, - 0x3b, 0xbc, 0x18, 0xa0, 0x36, 0xf5, 0xea, 0xee, 0xe3, 0x5a, 0x9d, 0xc3, 0x21, 0x38, 0x58, 0x0d, 0x22, 0x38, 0x9d, - 0x4f, 0x1d, 0xcd, 0xb2, 0x00, 0x95, 0x93, 0xe5, 0x46, 0xde, 0x3c, 0x5a, 0xf4, 0xea, 0xbe, 0xb7, 0x4c, 0xcb, 0xaa, - 0x0e, 0x32, 0x96, 0x85, 0x15, 0xe0, 0xea, 0xd0, 0xfa, 0x41, 0xb8, 0x2c, 0x9c, 0x3f, 0x10, 0x82, 0xd8, 0xbd, 0xda, - 0x96, 0x3c, 0x57, 0x73, 0xf8, 0xd9, 0x73, 0xb6, 0xe6, 0x12, 0x75, 0xd2, 0x99, 0x08, 0x40, 0xec, 0xa9, 0x59, 0x45, - 0xd7, 0x40, 0x52, 0xa7, 0x59, 0x45, 0xd7, 0xd4, 0x6c, 0x63, 0x1c, 0xc8, 0x47, 0xab, 0x14, 0xb0, 0xef, 0xa6, 0xe3, - 0x60, 0xf5, 0x2c, 0x96, 0xd7, 0xa1, 0xbb, 0x67, 0x1b, 0xe5, 0x33, 0xa8, 0x5b, 0x6d, 0x8c, 0x89, 0xed, 0xe6, 0xcb, - 0xb9, 0x7e, 0x3b, 0x58, 0xfa, 0x76, 0xd0, 0x9c, 0x53, 0xf6, 0x9d, 0x2e, 0x7b, 0x65, 0x97, 0x4d, 0x3d, 0x77, 0x54, - 0xb4, 0x1a, 0x03, 0x7a, 0x03, 0x0b, 0xd6, 0xe7, 0x22, 0xcd, 0x56, 0xa5, 0x2a, 0x01, 0x2f, 0x8c, 0x15, 0xbb, 0xf3, - 0x1b, 0x99, 0x21, 0x09, 0xf3, 0x38, 0x13, 0xef, 0xe8, 0x5e, 0x0b, 0x93, 0xe3, 0x58, 0x24, 0x53, 0x42, 0xa7, 0x74, - 0x67, 0x1b, 0x3a, 0x57, 0x61, 0x14, 0xd1, 0x5a, 0x49, 0xa5, 0x91, 0xc0, 0xd4, 0x0c, 0x50, 0x32, 0x57, 0xe0, 0x94, - 0x2e, 0xf7, 0xbf, 0x23, 0x31, 0xce, 0x7c, 0x51, 0x32, 0x03, 0xba, 0xe5, 0xd7, 0xc5, 0xba, 0x95, 0x22, 0x23, 0xcc, - 0x9b, 0xe3, 0xf6, 0xba, 0x3e, 0x04, 0x72, 0xb5, 0xec, 0x51, 0x34, 0x0e, 0x0a, 0x1d, 0x2e, 0x55, 0x02, 0xec, 0x8b, - 0xc4, 0xcf, 0x08, 0x5b, 0xda, 0x03, 0xb9, 0x3d, 0x3a, 0x13, 0xe6, 0x9c, 0x93, 0xb2, 0xec, 0x5c, 0x9a, 0xc1, 0xe5, - 0xc4, 0x95, 0xe0, 0x22, 0xbd, 0x6d, 0x4f, 0x93, 0x96, 0xb6, 0x8f, 0x0d, 0xe7, 0x68, 0x68, 0x1b, 0x74, 0xc7, 0xfe, - 0xd0, 0x5c, 0x2c, 0x62, 0xeb, 0x62, 0x31, 0xec, 0xcc, 0x7e, 0xb4, 0x58, 0x80, 0x1c, 0x00, 0x8e, 0xba, 0x0d, 0x1f, - 0xb3, 0x25, 0x70, 0x5a, 0x4d, 0xb3, 0xa9, 0xb7, 0xe1, 0xd5, 0x33, 0xd5, 0xd3, 0x4b, 0x9e, 0x3f, 0x13, 0x66, 0x2c, - 0x36, 0x3c, 0x7f, 0x66, 0x1d, 0x39, 0xd5, 0x33, 0xa1, 0x44, 0xeb, 0x02, 0x9a, 0x81, 0xd7, 0x14, 0x30, 0x62, 0xc9, - 0x64, 0x4a, 0x15, 0x79, 0xdc, 0x9b, 0x6e, 0xd4, 0xe0, 0x05, 0x85, 0x43, 0x20, 0xa5, 0xd3, 0x2f, 0x9e, 0x33, 0xfd, - 0xde, 0xc5, 0xf3, 0x0e, 0x59, 0xdb, 0x30, 0x5d, 0x6e, 0x86, 0xc9, 0xa0, 0xf4, 0x9f, 0x99, 0x89, 0x71, 0x61, 0x4d, - 0x12, 0x40, 0xfc, 0x1b, 0xfb, 0x1d, 0x52, 0xb8, 0x79, 0x7f, 0x39, 0x8c, 0x1f, 0x79, 0x3f, 0x46, 0xf6, 0x24, 0xcd, - 0x10, 0x6b, 0x26, 0x15, 0x72, 0xf7, 0xd5, 0xfa, 0xc7, 0xc4, 0x6e, 0xb2, 0x07, 0x16, 0x80, 0xd8, 0x9a, 0xb6, 0xba, - 0xe5, 0xfd, 0xbe, 0x67, 0x8a, 0x00, 0x3f, 0x28, 0xff, 0xe8, 0xce, 0x90, 0x0c, 0xca, 0xae, 0x1b, 0x42, 0x3c, 0x28, - 0x9b, 0xa6, 0xbd, 0xde, 0xf6, 0xce, 0x3c, 0x56, 0xd7, 0x69, 0x67, 0x71, 0xb5, 0xc8, 0x20, 0xad, 0x3e, 0x64, 0xc7, - 0x99, 0x7d, 0x76, 0xb4, 0x54, 0xba, 0xdf, 0x87, 0x88, 0xb8, 0xa3, 0xac, 0xed, 0xb7, 0x5b, 0x70, 0x0d, 0x47, 0x83, - 0xd0, 0x95, 0xbd, 0x5d, 0x46, 0x1b, 0x17, 0xe2, 0xb8, 0x67, 0x3a, 0x5f, 0xf0, 0xe5, 0x51, 0xda, 0x79, 0x70, 0xaa, - 0x27, 0xfa, 0xdc, 0x74, 0x57, 0x99, 0x5c, 0xeb, 0xb0, 0x1a, 0x83, 0xda, 0x2c, 0x6c, 0xe1, 0x2e, 0x6c, 0xa3, 0x83, - 0xd6, 0xbe, 0x2c, 0xf8, 0xa7, 0x0c, 0xc0, 0x97, 0x9e, 0x2d, 0xdb, 0x5e, 0x93, 0x56, 0x6f, 0x64, 0x14, 0x62, 0x4b, - 0xdb, 0xab, 0x4f, 0x47, 0xf9, 0xb8, 0x39, 0xa1, 0xb8, 0x90, 0xa3, 0xfc, 0xe8, 0x35, 0x44, 0x5d, 0xeb, 0x3a, 0x2e, - 0x16, 0x1d, 0x6e, 0x5c, 0x75, 0xdb, 0x8d, 0xeb, 0x47, 0xc4, 0x5b, 0xa3, 0x4d, 0x0a, 0xb5, 0x32, 0x76, 0x04, 0x2f, - 0xcb, 0x87, 0x43, 0x26, 0x86, 0x43, 0x09, 0x99, 0xfa, 0xd8, 0xbd, 0xa1, 0x69, 0x9f, 0x9f, 0xb6, 0x7e, 0xc4, 0x52, - 0xe3, 0x28, 0x36, 0xbc, 0xd3, 0x77, 0x1e, 0x5b, 0xe3, 0x4a, 0xbe, 0x0c, 0x66, 0xbb, 0x82, 0x6a, 0x6b, 0xbc, 0x61, - 0x2f, 0xe7, 0xbf, 0x54, 0x52, 0xc9, 0xdf, 0xfe, 0x0c, 0xd7, 0xf0, 0xd6, 0x96, 0x0e, 0x9a, 0x6a, 0x96, 0xb3, 0x5c, - 0xdf, 0x0b, 0x8e, 0x3f, 0xee, 0x5e, 0x11, 0x0c, 0x7e, 0x4f, 0x47, 0x41, 0x2e, 0x96, 0x6a, 0x0d, 0x28, 0x48, 0x47, - 0x76, 0x4c, 0x65, 0x81, 0x61, 0x00, 0x6f, 0xc8, 0x00, 0x79, 0x4c, 0xe1, 0x6e, 0xa8, 0xf0, 0xc2, 0x97, 0x15, 0xd9, - 0x25, 0xb0, 0xad, 0x19, 0x1f, 0x33, 0xdc, 0x41, 0xc8, 0x3f, 0x82, 0xdd, 0xb1, 0x15, 0xbb, 0x65, 0x0b, 0x86, 0x64, - 0xe3, 0x38, 0x8c, 0x31, 0x1f, 0x4f, 0xe2, 0x2b, 0x31, 0x89, 0x07, 0x3c, 0x42, 0xc7, 0x88, 0x35, 0xaf, 0x67, 0xb1, - 0x1c, 0x40, 0x76, 0xc7, 0x95, 0x0e, 0x08, 0xa1, 0xb1, 0xa1, 0x25, 0x6f, 0x0a, 0x83, 0x8b, 0x1d, 0xfb, 0x8c, 0x44, - 0x32, 0x0e, 0xc1, 0xa2, 0x55, 0x0d, 0x2c, 0x4c, 0xec, 0x96, 0x17, 0xb3, 0xd5, 0x1c, 0xff, 0x39, 0x1c, 0x10, 0x00, - 0x3b, 0xd8, 0x37, 0xec, 0x2e, 0x42, 0xa4, 0xb7, 0x05, 0xbf, 0xb3, 0x3c, 0x5d, 0xd8, 0x3d, 0x7f, 0xc7, 0xc7, 0xec, - 0xfc, 0x47, 0x0f, 0x22, 0x67, 0xcf, 0x3f, 0x01, 0x1a, 0xe2, 0x3d, 0xbf, 0x4d, 0xbd, 0x8a, 0xdd, 0x12, 0x05, 0xe1, - 0x2d, 0x38, 0x03, 0xdd, 0x43, 0x04, 0xec, 0x3b, 0xbe, 0xc0, 0x58, 0xb1, 0xb3, 0x74, 0xe9, 0x61, 0x46, 0xa8, 0x3d, - 0x9d, 0x2f, 0x6b, 0x35, 0x09, 0x37, 0x57, 0xcb, 0xc9, 0x60, 0xb0, 0xf1, 0x77, 0x7c, 0x0d, 0x7c, 0x30, 0xe7, 0x3f, - 0x7a, 0x3b, 0x2a, 0x17, 0xfe, 0xf3, 0x3a, 0x4b, 0xde, 0xf9, 0xec, 0xdd, 0x80, 0x2f, 0x00, 0x6f, 0x09, 0x1d, 0xb8, - 0xee, 0x7d, 0x26, 0xf1, 0xda, 0xde, 0xe9, 0x6b, 0x04, 0x12, 0xf9, 0x02, 0x30, 0x62, 0x62, 0x7e, 0xbf, 0x83, 0x08, - 0x8c, 0x04, 0x7c, 0x5b, 0xb5, 0x47, 0xfc, 0x96, 0x1b, 0xc0, 0xaf, 0xcc, 0x67, 0x0f, 0x3c, 0xd4, 0x3f, 0x13, 0x9f, - 0xdd, 0xf0, 0x0f, 0xfc, 0xda, 0x93, 0x92, 0x74, 0x39, 0xfb, 0x30, 0x87, 0xeb, 0xa1, 0x94, 0xa7, 0x43, 0xfa, 0xd9, - 0x18, 0x0c, 0x20, 0x14, 0x32, 0x6f, 0x3c, 0x60, 0x4d, 0x0a, 0xf1, 0x2f, 0xe0, 0xdb, 0x51, 0xc2, 0xe6, 0x8d, 0xb7, - 0xf5, 0xb5, 0xbc, 0x79, 0xe3, 0x3d, 0xf8, 0x14, 0x05, 0x58, 0x05, 0xa5, 0x2c, 0xb0, 0x0a, 0xc2, 0x46, 0x1b, 0x61, - 0x0c, 0x5c, 0xbd, 0x6b, 0x0c, 0x75, 0x3d, 0x47, 0x6c, 0x5b, 0xe9, 0xfb, 0xf0, 0x3d, 0x64, 0xc0, 0x07, 0x6f, 0x8a, - 0x92, 0xe8, 0x73, 0x6a, 0x8a, 0xa4, 0x75, 0xcf, 0xfd, 0xd6, 0xba, 0xa3, 0x35, 0xa5, 0x3e, 0x72, 0x35, 0x3e, 0x1c, - 0xea, 0x6b, 0xa1, 0x45, 0x82, 0x29, 0x68, 0x5c, 0x83, 0xb6, 0x00, 0x41, 0x9f, 0x07, 0xc8, 0x5a, 0x52, 0x2c, 0xf8, - 0xf6, 0x57, 0x88, 0xc1, 0x2b, 0xd3, 0x3b, 0x97, 0xab, 0x8c, 0x84, 0xed, 0x85, 0x5f, 0x0e, 0x6b, 0x7f, 0xe2, 0xd4, - 0xc2, 0xd2, 0x6a, 0x0e, 0xea, 0x67, 0xb6, 0x1c, 0xa7, 0xaa, 0xf6, 0x2f, 0x49, 0x52, 0xed, 0x2a, 0x2d, 0xa7, 0xf7, - 0xf6, 0x4d, 0x97, 0x09, 0x36, 0xf6, 0x03, 0xaa, 0x8e, 0xac, 0x86, 0xdd, 0x17, 0xea, 0x8b, 0x9e, 0x92, 0x09, 0xcd, - 0x47, 0x15, 0xcd, 0xb3, 0xfb, 0xcd, 0x8e, 0xfa, 0x4f, 0x2f, 0x87, 0x22, 0x40, 0xb2, 0x4a, 0x8b, 0xa5, 0xc8, 0xd9, - 0xd8, 0x8f, 0x87, 0x49, 0xa6, 0xc2, 0x0b, 0xd2, 0xd1, 0xdd, 0x6f, 0xdc, 0xdf, 0x72, 0x03, 0x59, 0xa1, 0x55, 0x1b, - 0x8c, 0x95, 0xa2, 0x65, 0xb0, 0xbe, 0x1a, 0xf7, 0xfb, 0xe2, 0x6a, 0x3c, 0x15, 0x41, 0x0d, 0xc4, 0x45, 0xe2, 0x7a, - 0x3c, 0xad, 0x89, 0x25, 0xb5, 0x2b, 0x30, 0x46, 0x8f, 0xab, 0xa2, 0xf6, 0xa9, 0xaf, 0x21, 0x14, 0xa9, 0xd6, 0xcc, - 0xb1, 0xc6, 0x8d, 0x11, 0x71, 0x87, 0x95, 0x6b, 0xa7, 0xf6, 0x3a, 0x00, 0xcb, 0xab, 0x71, 0x41, 0xd8, 0x24, 0xc7, - 0xce, 0x05, 0xac, 0x46, 0x43, 0xaa, 0xdd, 0x70, 0xeb, 0x65, 0xe7, 0x37, 0x8f, 0x13, 0x5b, 0x1b, 0xe1, 0x96, 0x02, - 0xca, 0x28, 0xbf, 0xb1, 0x9c, 0xb0, 0x3b, 0xd5, 0x3b, 0x52, 0xb5, 0x23, 0x4e, 0x5c, 0xc0, 0x72, 0xc3, 0x53, 0xab, - 0x6f, 0x62, 0x70, 0x22, 0x54, 0xad, 0x74, 0xb8, 0x93, 0x09, 0xc4, 0xfd, 0xea, 0xbe, 0xee, 0x95, 0xe0, 0x27, 0x21, - 0xaf, 0xdf, 0xf2, 0x0e, 0x00, 0x2b, 0x3e, 0xe4, 0xc5, 0xb4, 0x70, 0xb4, 0x2e, 0x83, 0x32, 0x40, 0x84, 0x66, 0x00, - 0x74, 0x72, 0x75, 0x10, 0xa5, 0x81, 0x2b, 0xee, 0x10, 0xe1, 0xa7, 0xd1, 0xb3, 0xfc, 0x3a, 0x7c, 0x56, 0x4d, 0xc3, - 0x8b, 0x3c, 0x88, 0x2e, 0xaa, 0x20, 0x7a, 0x56, 0x5d, 0x85, 0xcf, 0xf2, 0x69, 0x74, 0x91, 0x07, 0xe1, 0x45, 0xd5, - 0xd8, 0x77, 0xed, 0xee, 0x9e, 0x90, 0xb7, 0x5d, 0xfd, 0x91, 0x73, 0x65, 0x4f, 0x99, 0x9e, 0x9f, 0xd7, 0x7a, 0xa5, - 0x76, 0x9b, 0xeb, 0x35, 0x6a, 0xa6, 0x3e, 0xca, 0xfe, 0x62, 0x1b, 0x0b, 0x8f, 0xe6, 0x10, 0xfa, 0x8c, 0xb4, 0x98, - 0x7b, 0x9c, 0xeb, 0xcd, 0x9e, 0x14, 0x06, 0x46, 0x4c, 0x2a, 0x19, 0x39, 0xbd, 0xc0, 0x45, 0xa8, 0x42, 0x0c, 0x6b, - 0xe9, 0x6a, 0x9f, 0x75, 0xe9, 0x0d, 0xd4, 0x35, 0xc5, 0xbe, 0x86, 0x0c, 0xbc, 0x68, 0x7a, 0x19, 0x8c, 0x01, 0x39, - 0x02, 0xef, 0xf8, 0x6c, 0x09, 0x07, 0xe6, 0x1a, 0xa0, 0x6f, 0x1e, 0xf5, 0x75, 0xb9, 0xe3, 0x6b, 0xd5, 0x37, 0xd3, - 0xf5, 0x48, 0x29, 0x3f, 0x56, 0xfc, 0xee, 0xe2, 0x39, 0xbb, 0xe5, 0x1a, 0x15, 0xe5, 0xa5, 0x5e, 0xac, 0xf7, 0xc0, - 0x55, 0xf7, 0x12, 0x6e, 0xb3, 0x78, 0xec, 0xca, 0x03, 0x96, 0x6d, 0xd9, 0x03, 0xbb, 0x61, 0x1f, 0xd8, 0x13, 0xf6, - 0x96, 0x7d, 0x65, 0x35, 0x42, 0x94, 0x97, 0x4a, 0xca, 0xf3, 0x17, 0xfc, 0x56, 0xda, 0x1e, 0x25, 0x2c, 0xd9, 0x83, - 0x6d, 0xa7, 0x19, 0x6e, 0xd8, 0x07, 0xbe, 0x18, 0xae, 0xd8, 0x5b, 0xc8, 0x86, 0x42, 0xf1, 0x60, 0xc5, 0x6a, 0xb8, - 0xc2, 0x52, 0x06, 0x7d, 0x1a, 0x96, 0x96, 0xb0, 0x68, 0x0a, 0x45, 0x29, 0xfa, 0x2d, 0xaf, 0x09, 0x3b, 0xad, 0xc6, - 0x42, 0xe4, 0x87, 0x86, 0x2b, 0xf6, 0xc0, 0x17, 0x83, 0x15, 0xfb, 0xa0, 0x6d, 0x44, 0x83, 0x8d, 0x5b, 0x1c, 0x81, - 0x59, 0xe9, 0xc2, 0xa4, 0x40, 0xbd, 0xb5, 0x6f, 0x82, 0x1b, 0x76, 0x83, 0xf5, 0x7b, 0x82, 0x45, 0xa3, 0xcc, 0x3f, - 0x58, 0xb1, 0xaf, 0x5c, 0x62, 0xa8, 0xb9, 0xe5, 0x49, 0xc7, 0x50, 0x5d, 0x20, 0x5d, 0x11, 0x9e, 0x70, 0x7a, 0x91, - 0x7d, 0xc5, 0x32, 0xe8, 0x2b, 0xc3, 0x15, 0xdb, 0x62, 0xed, 0x6e, 0x8c, 0x71, 0xcb, 0xaa, 0x9e, 0x04, 0x05, 0x46, - 0x59, 0xa5, 0xb4, 0x5c, 0x1c, 0xb1, 0x6c, 0xea, 0xa8, 0x41, 0x6d, 0x18, 0xd0, 0x07, 0xa3, 0xff, 0xf0, 0xf5, 0xbb, - 0x1f, 0xbd, 0x52, 0xdf, 0x7c, 0x5f, 0x3a, 0xde, 0x95, 0x25, 0x7a, 0x57, 0xfe, 0xca, 0xcb, 0xd9, 0xcb, 0xf9, 0x44, - 0xd7, 0x92, 0x36, 0x19, 0x72, 0x37, 0x9d, 0xbd, 0xec, 0xf0, 0xb7, 0xfc, 0xd5, 0xf7, 0x1b, 0xab, 0x8f, 0xd5, 0x77, - 0x75, 0xf7, 0x3e, 0x0c, 0x36, 0x8d, 0x53, 0xf1, 0xdd, 0xe9, 0x8a, 0x63, 0x3b, 0x6b, 0xed, 0x9d, 0xf9, 0x3f, 0x5c, - 0xeb, 0x2d, 0x8e, 0xdd, 0x0d, 0xdf, 0x0e, 0x37, 0xf6, 0x30, 0xc8, 0xef, 0x4b, 0xc5, 0x71, 0x56, 0xf3, 0x17, 0x5e, - 0xa7, 0x24, 0x0b, 0xa8, 0x46, 0x9f, 0x8d, 0x34, 0x74, 0xc9, 0x4c, 0x4c, 0x43, 0x7c, 0x91, 0x01, 0x3a, 0x17, 0x88, - 0x67, 0xf7, 0x7c, 0x3c, 0xb9, 0xbf, 0x8a, 0x27, 0xf7, 0x03, 0xfe, 0xd9, 0xb4, 0xa0, 0xbd, 0xe0, 0xee, 0x7d, 0xf6, - 0x2b, 0x2f, 0xec, 0x25, 0xf9, 0xd2, 0x67, 0xef, 0x85, 0xbb, 0x4a, 0x5f, 0xfa, 0xec, 0xab, 0xe0, 0xbf, 0x8e, 0x34, - 0x59, 0x06, 0xfb, 0x5a, 0xf3, 0x5f, 0x47, 0xc8, 0xfa, 0xc1, 0xbe, 0x08, 0xfe, 0x1e, 0xfc, 0xbf, 0xab, 0x04, 0x2d, - 0xe3, 0x5f, 0x6a, 0xf5, 0xf3, 0x83, 0x8c, 0xcd, 0x81, 0x37, 0xa1, 0x15, 0xf4, 0xe6, 0x6d, 0x2d, 0x7f, 0x12, 0x17, - 0x47, 0xaa, 0x9e, 0x1a, 0x0e, 0x5a, 0x2c, 0x66, 0x51, 0x1f, 0xa5, 0x53, 0x79, 0x93, 0x77, 0x3c, 0x93, 0x16, 0xe6, - 0x7b, 0x08, 0x07, 0x7e, 0x67, 0xc3, 0x14, 0xec, 0x38, 0x6e, 0x06, 0xef, 0x18, 0x40, 0x48, 0x66, 0xd3, 0x2d, 0xbf, - 0xe1, 0x4f, 0xf8, 0x57, 0xbe, 0x0b, 0x1e, 0xf8, 0x07, 0xfe, 0x96, 0xd7, 0x35, 0xdf, 0xb1, 0xa5, 0x84, 0x3c, 0xad, - 0xb7, 0x97, 0xc1, 0x96, 0xd5, 0xbb, 0xcb, 0xe0, 0x81, 0xd5, 0xdb, 0xe7, 0xc1, 0x0d, 0xab, 0x77, 0xcf, 0x83, 0x0f, - 0x6c, 0x7b, 0x19, 0x3c, 0x61, 0xbb, 0xcb, 0xe0, 0x2d, 0xdb, 0x3e, 0x0f, 0xbe, 0xb2, 0xdd, 0xf3, 0xa0, 0x56, 0x48, - 0x0f, 0x5f, 0x85, 0x64, 0x3a, 0xf9, 0x5a, 0x33, 0xc3, 0xaa, 0x1b, 0x7c, 0x11, 0xd6, 0x2f, 0xaa, 0x65, 0xf0, 0xa5, - 0x66, 0xba, 0xcd, 0x81, 0x10, 0x4c, 0xb7, 0x38, 0xb8, 0xa5, 0x27, 0xa6, 0x5d, 0x41, 0x2a, 0x58, 0x57, 0x4b, 0x83, - 0x45, 0xdd, 0xb4, 0x4e, 0x66, 0xc7, 0x3b, 0x31, 0xee, 0xf0, 0x4e, 0x5c, 0xb0, 0x65, 0xd3, 0xe9, 0xaa, 0x73, 0xfa, - 0x3c, 0xd0, 0x47, 0x80, 0xde, 0xfb, 0x2b, 0xe9, 0x41, 0x53, 0x34, 0x3c, 0x57, 0xba, 0xe3, 0xd6, 0x7e, 0x1f, 0x5a, - 0xfb, 0x3d, 0x93, 0x8a, 0xb4, 0x88, 0x45, 0x65, 0x51, 0x55, 0xc8, 0x27, 0x1e, 0x64, 0x5a, 0xab, 0x96, 0x30, 0x52, - 0x67, 0x02, 0x26, 0x7d, 0x41, 0x87, 0x41, 0x4e, 0x76, 0x05, 0xb6, 0xe4, 0x9b, 0x41, 0xc2, 0xd6, 0x3c, 0x9e, 0x0e, - 0x93, 0x60, 0xc9, 0xee, 0xf8, 0xb0, 0x5b, 0x2c, 0x58, 0xa9, 0x30, 0x26, 0x7d, 0x7d, 0x3a, 0xda, 0xdd, 0x79, 0x6f, - 0x95, 0xc6, 0x71, 0x26, 0x50, 0xe7, 0x56, 0xe9, 0x6d, 0x7e, 0xeb, 0xec, 0xea, 0x6b, 0xb5, 0xcb, 0x83, 0xc0, 0xf0, - 0x2b, 0x10, 0xed, 0x10, 0xef, 0x1d, 0xd4, 0x18, 0xe9, 0x96, 0xcc, 0xba, 0xaf, 0xec, 0x7d, 0x7d, 0x6b, 0xb6, 0xea, - 0x7f, 0xb7, 0x08, 0xda, 0xcb, 0x65, 0xef, 0x7f, 0x36, 0xaf, 0xfe, 0xd6, 0xf1, 0xea, 0xc6, 0x9f, 0x3c, 0xf0, 0xcf, - 0x18, 0x9d, 0x80, 0x89, 0x6c, 0xc7, 0x3f, 0x8f, 0xb6, 0x8d, 0x53, 0x9e, 0xdc, 0xcb, 0xff, 0xaf, 0x14, 0x68, 0xef, - 0xe6, 0x95, 0xbd, 0x29, 0x6e, 0x79, 0xc7, 0x5e, 0xbe, 0xb4, 0xf6, 0x44, 0x83, 0x50, 0xf2, 0x99, 0xbb, 0x41, 0xd1, - 0xb0, 0x27, 0xbe, 0xe4, 0xd5, 0xec, 0xf3, 0x7c, 0xb2, 0xe5, 0xc7, 0x3b, 0xe2, 0xe7, 0x8e, 0x1d, 0xf1, 0xa5, 0x3f, - 0x58, 0x36, 0xdf, 0xea, 0xd5, 0xce, 0x9d, 0xdc, 0xa9, 0xf4, 0x8e, 0x1f, 0xef, 0xe3, 0xc3, 0x7f, 0xbb, 0xd2, 0xbb, - 0xef, 0xae, 0xb4, 0x5d, 0xe5, 0xee, 0xce, 0x37, 0x1d, 0xdf, 0xc8, 0x5a, 0x63, 0xb8, 0x99, 0x51, 0x30, 0xc2, 0xb4, - 0x85, 0x69, 0x1a, 0x44, 0x96, 0x62, 0x11, 0x12, 0x35, 0x4a, 0xe7, 0x44, 0x9f, 0x05, 0x9d, 0x82, 0x2e, 0x6e, 0xf4, - 0xb7, 0x7c, 0xcc, 0x16, 0xc6, 0x65, 0xf3, 0xf6, 0x6a, 0x31, 0x19, 0x0c, 0x6e, 0xfd, 0xfd, 0x3d, 0x0f, 0x67, 0xb7, - 0x73, 0xf6, 0x8e, 0xdf, 0xd3, 0x7a, 0x9a, 0xa8, 0xc6, 0x17, 0x8f, 0x49, 0x60, 0xb7, 0xbe, 0x3f, 0xb1, 0x88, 0x60, - 0xed, 0x1b, 0xe7, 0xad, 0x3f, 0x90, 0x66, 0x69, 0xb9, 0xb5, 0x7f, 0x78, 0x5c, 0x43, 0x71, 0x0b, 0x42, 0xc6, 0x07, - 0x5b, 0xe5, 0xf0, 0x96, 0x7f, 0xf2, 0xde, 0xf9, 0xd3, 0x77, 0x3a, 0xf8, 0x66, 0xa2, 0xce, 0xa5, 0xb7, 0x17, 0xcf, - 0xd9, 0xaf, 0xfc, 0xb3, 0x3c, 0x53, 0xde, 0x0b, 0x39, 0x6d, 0x6f, 0x90, 0xc4, 0x89, 0x8e, 0x8a, 0xaf, 0x6e, 0x22, - 0x81, 0x42, 0x20, 0x1e, 0x47, 0xcd, 0x1f, 0x26, 0xe5, 0xd4, 0xdb, 0x01, 0xc9, 0x2b, 0xb7, 0x15, 0xd1, 0xb7, 0x9c, - 0xf3, 0xc5, 0xf0, 0x72, 0xfa, 0xb5, 0xdb, 0xb7, 0x47, 0x85, 0xb5, 0xa9, 0x88, 0xb7, 0x5b, 0x0c, 0xc2, 0x3a, 0x99, - 0x59, 0xe6, 0x92, 0x2f, 0x7d, 0xad, 0xcd, 0xdc, 0x63, 0x7a, 0xc7, 0x99, 0x66, 0xc8, 0xe8, 0x0b, 0xcc, 0x4c, 0x87, - 0xc3, 0xdd, 0x39, 0x96, 0xc7, 0x87, 0x6f, 0x9f, 0x3d, 0x19, 0x3c, 0xc1, 0x10, 0x2e, 0x2b, 0x2c, 0xe4, 0x2b, 0x1f, - 0x66, 0x75, 0xeb, 0xda, 0x71, 0xf1, 0x7c, 0xf8, 0x12, 0xf2, 0x06, 0x5d, 0x0f, 0x4d, 0x11, 0xad, 0xf2, 0x3b, 0x8a, - 0x3e, 0x51, 0x72, 0xd0, 0xf1, 0x04, 0x6a, 0x87, 0x5c, 0xb8, 0x5f, 0x9f, 0x71, 0x50, 0x74, 0x60, 0xa9, 0xfd, 0xfe, - 0xf9, 0x67, 0x22, 0x94, 0x86, 0xf1, 0x7e, 0x19, 0x46, 0x7f, 0xc4, 0x65, 0xb1, 0x86, 0x23, 0x76, 0x00, 0x9f, 0x7b, - 0xa6, 0xaf, 0x61, 0x77, 0xbe, 0xef, 0x07, 0xde, 0x96, 0xdf, 0xb0, 0xaf, 0xdc, 0xbb, 0x1c, 0xbe, 0xf5, 0x9f, 0x3d, - 0x01, 0xf9, 0x09, 0xc6, 0xe5, 0x0b, 0x86, 0xc4, 0x76, 0x14, 0xa3, 0xd6, 0xe1, 0x97, 0x1a, 0x62, 0xb5, 0x3e, 0x23, - 0x75, 0x17, 0xa4, 0x7f, 0x54, 0xc8, 0x7e, 0x42, 0x60, 0x35, 0x49, 0x9f, 0x02, 0x93, 0xf8, 0xb6, 0x86, 0x04, 0xd2, - 0xb4, 0x40, 0x0c, 0x0e, 0x14, 0x9f, 0x0a, 0xfe, 0x75, 0xf8, 0x85, 0xe4, 0xbf, 0x45, 0xcd, 0xc7, 0xf0, 0x37, 0x0c, - 0xcd, 0xa4, 0x7a, 0x48, 0xeb, 0x28, 0xf1, 0x6a, 0x38, 0xf5, 0xc2, 0x4a, 0xa8, 0x93, 0x21, 0x48, 0xc5, 0x90, 0x0b, - 0x71, 0xf1, 0x7c, 0x72, 0x5b, 0x8a, 0xf0, 0x8f, 0x09, 0x3e, 0x93, 0x2b, 0x4d, 0x3e, 0xa3, 0x27, 0x8d, 0x2c, 0xe0, - 0x41, 0xbe, 0x2f, 0x7b, 0x35, 0x58, 0xd4, 0x43, 0x7e, 0x5b, 0xbb, 0xef, 0xcb, 0x39, 0x41, 0x8f, 0xec, 0x07, 0x34, - 0x07, 0x03, 0x35, 0x03, 0x29, 0x43, 0x70, 0x0b, 0x97, 0x7e, 0x4f, 0x15, 0xe4, 0xcb, 0xef, 0x7d, 0x11, 0x32, 0x70, - 0x65, 0x41, 0x98, 0x72, 0xa9, 0x90, 0x02, 0xc7, 0x6d, 0x3d, 0xf8, 0xa2, 0xd1, 0x49, 0x24, 0xf8, 0x94, 0x80, 0x24, - 0x69, 0x79, 0x20, 0x69, 0xc4, 0x74, 0x20, 0x2e, 0x94, 0xa6, 0x59, 0x49, 0x11, 0x87, 0xd8, 0x55, 0xdf, 0x21, 0xe1, - 0x59, 0xf0, 0x81, 0xc1, 0xda, 0x91, 0xa2, 0xc5, 0x57, 0x63, 0x3a, 0xd6, 0x61, 0x43, 0x77, 0xb2, 0xb8, 0x5f, 0x25, - 0x75, 0x1a, 0x89, 0x2b, 0xef, 0x85, 0xfc, 0xf9, 0x4f, 0x25, 0x02, 0xe9, 0x5d, 0x0d, 0xc4, 0x20, 0xf8, 0x01, 0xfa, - 0x0f, 0x58, 0xe4, 0x20, 0x28, 0xd5, 0x65, 0x98, 0x57, 0x19, 0x15, 0x38, 0xdb, 0xb1, 0xed, 0x9c, 0xa9, 0xba, 0x05, - 0x5f, 0x84, 0x61, 0x48, 0x3b, 0x5b, 0x35, 0x27, 0xb7, 0x7a, 0x03, 0xf5, 0x4c, 0xe2, 0x48, 0x2d, 0xc5, 0x91, 0xb6, - 0xe6, 0x3e, 0x5d, 0x7a, 0xdd, 0xf2, 0x82, 0x86, 0x0b, 0xd0, 0x8b, 0xd2, 0x5d, 0xe7, 0x13, 0x0a, 0x5d, 0x56, 0xe3, - 0x6a, 0x28, 0xea, 0x50, 0x8e, 0xb1, 0xf6, 0xe7, 0x4a, 0x9e, 0xdf, 0x81, 0xf5, 0x08, 0x0d, 0x5f, 0x95, 0x3a, 0x88, - 0xed, 0x27, 0x7a, 0xd7, 0xa9, 0xd4, 0xdf, 0x00, 0x30, 0x70, 0xea, 0x78, 0xa8, 0x8f, 0xda, 0x29, 0x64, 0x3b, 0xf7, - 0x96, 0x18, 0x95, 0x2b, 0xe1, 0xa9, 0xd2, 0xf2, 0x94, 0xb2, 0xea, 0x6b, 0xc1, 0xad, 0xec, 0x3e, 0x1b, 0x40, 0x46, - 0x1b, 0x14, 0xc8, 0x33, 0x6a, 0x6b, 0x3c, 0x48, 0x35, 0xcd, 0x12, 0xc7, 0xf0, 0x41, 0x91, 0x66, 0x15, 0x58, 0xbc, - 0xcc, 0x25, 0x73, 0x50, 0xb0, 0x5c, 0x6f, 0x36, 0xd3, 0x4c, 0xf5, 0x45, 0x6e, 0x6f, 0x34, 0x5e, 0xa6, 0xff, 0x66, - 0xc9, 0x80, 0x47, 0x17, 0xcf, 0xfd, 0x00, 0xd2, 0x24, 0xc5, 0x03, 0x24, 0xc1, 0xf6, 0x60, 0x17, 0x3b, 0x0c, 0x5b, - 0xc5, 0xca, 0x9e, 0x3c, 0x5d, 0xee, 0xd0, 0x94, 0x4b, 0x70, 0xc9, 0x89, 0xb9, 0x9c, 0xfa, 0xbe, 0x64, 0xbd, 0xa1, - 0x38, 0x65, 0xd3, 0x04, 0x94, 0x04, 0xda, 0x2d, 0xf8, 0x2f, 0x7c, 0x6a, 0xe8, 0xb4, 0x00, 0x4b, 0x6d, 0x37, 0xe0, - 0xbf, 0xd0, 0x2f, 0xb6, 0xbb, 0xa8, 0x1f, 0x98, 0x07, 0x7b, 0xb3, 0xb8, 0x32, 0x06, 0x9c, 0x24, 0xae, 0x34, 0x8f, - 0x5c, 0x3f, 0x28, 0xfa, 0x74, 0x59, 0x3b, 0x70, 0xa6, 0xb8, 0xb0, 0x4a, 0x6d, 0x92, 0x5e, 0xfb, 0x2d, 0x35, 0xf1, - 0x26, 0x4a, 0xaa, 0xc2, 0x76, 0x48, 0xfb, 0x97, 0x94, 0x33, 0x55, 0xdc, 0x21, 0x7a, 0xb2, 0x9b, 0xb8, 0x0a, 0xbc, - 0xb0, 0xaa, 0xd8, 0x08, 0xb5, 0x19, 0x59, 0x4e, 0xe0, 0x74, 0x8f, 0xd5, 0x05, 0x1f, 0xdb, 0xd5, 0xec, 0x82, 0x95, - 0x6c, 0xcd, 0xa4, 0xfb, 0xbc, 0x1d, 0x73, 0x21, 0xaf, 0xf4, 0xb2, 0x68, 0x05, 0xb4, 0x07, 0x81, 0xc3, 0x2f, 0x35, - 0xdd, 0xa3, 0x67, 0x9b, 0x6d, 0x6a, 0xb3, 0xb1, 0xb5, 0x08, 0x21, 0x03, 0xd1, 0xd0, 0x17, 0x72, 0x46, 0x91, 0xaf, - 0xd2, 0x72, 0xad, 0x36, 0x56, 0x19, 0x2f, 0x30, 0x11, 0x64, 0x38, 0x0b, 0xef, 0xd1, 0xd3, 0x7a, 0xa4, 0x29, 0x26, - 0xc1, 0x49, 0x17, 0x7f, 0x01, 0x36, 0x94, 0x27, 0xb9, 0x39, 0x20, 0x07, 0x50, 0xb9, 0x14, 0xa5, 0x52, 0x06, 0xff, - 0xac, 0xee, 0xc8, 0xb6, 0xea, 0xbf, 0xd3, 0x40, 0x06, 0x77, 0xa0, 0x6f, 0x7b, 0xa1, 0xb5, 0xa3, 0x9d, 0x2b, 0x5b, - 0xd3, 0xb6, 0x4c, 0xf3, 0x18, 0x59, 0x6c, 0x00, 0xf9, 0x44, 0x3a, 0x07, 0x22, 0xaf, 0x89, 0xc6, 0x3b, 0xbb, 0xe6, - 0xe3, 0xa9, 0x78, 0x4c, 0xde, 0xab, 0x7c, 0xdf, 0xdc, 0xeb, 0x83, 0x31, 0xf6, 0x2d, 0x28, 0x13, 0x1f, 0xad, 0xb6, - 0xd6, 0x25, 0xd6, 0x5b, 0xa5, 0x49, 0x74, 0xc3, 0x15, 0x74, 0x1c, 0x89, 0x1b, 0xc4, 0xe0, 0x98, 0xf1, 0xda, 0x2a, - 0x4b, 0x5f, 0x61, 0x99, 0xeb, 0x98, 0x25, 0x43, 0x26, 0x75, 0x9e, 0x28, 0x78, 0xf2, 0xf3, 0x84, 0x64, 0x44, 0xd4, - 0x6c, 0xcb, 0x51, 0xca, 0x4d, 0x0b, 0xb8, 0xcc, 0xc8, 0x00, 0xbe, 0x49, 0x13, 0x80, 0x72, 0xf9, 0x12, 0xa4, 0xd2, - 0x10, 0xc1, 0x35, 0xdb, 0x4b, 0x46, 0xb7, 0x8e, 0xd6, 0x41, 0x95, 0x64, 0xee, 0xe0, 0xdc, 0xce, 0x22, 0xa5, 0xde, - 0x7c, 0x84, 0x61, 0x27, 0x1f, 0xc3, 0x3a, 0xc1, 0x6f, 0x03, 0x6a, 0xd2, 0xe7, 0xc2, 0x8b, 0x46, 0x80, 0xa6, 0xbe, - 0x53, 0x65, 0x7c, 0x2e, 0xbc, 0x6c, 0xb4, 0x65, 0x19, 0xa5, 0x50, 0x5d, 0x30, 0xbb, 0x35, 0x5d, 0x88, 0x79, 0x55, - 0x0d, 0xb4, 0x41, 0x6e, 0xd7, 0x31, 0x03, 0x1a, 0xb5, 0x5d, 0x79, 0x64, 0x01, 0x6e, 0xcd, 0x44, 0x60, 0xe4, 0xfc, - 0x87, 0xfc, 0x95, 0x0a, 0xe7, 0xe9, 0xf7, 0x43, 0x6f, 0xbf, 0x0d, 0xa2, 0xd1, 0xf6, 0x92, 0xed, 0x82, 0x68, 0xb4, - 0xbb, 0x6c, 0x18, 0xfd, 0x7e, 0x4e, 0xbf, 0x9f, 0x37, 0xa0, 0x2a, 0x11, 0x26, 0xe2, 0x5e, 0xbf, 0x51, 0xcb, 0x57, - 0x6a, 0xfd, 0x4e, 0x2d, 0x5f, 0xaa, 0xe1, 0xad, 0x3d, 0x89, 0x04, 0x91, 0xa5, 0xb1, 0x79, 0x90, 0x6c, 0xa9, 0x96, - 0x4a, 0xc7, 0xa8, 0x32, 0xa2, 0x96, 0xce, 0xe6, 0x58, 0x31, 0xd2, 0xce, 0x41, 0xc9, 0x80, 0x4c, 0x8b, 0xab, 0x1a, - 0xd3, 0xcd, 0x8a, 0x96, 0x98, 0x8c, 0xb0, 0xb2, 0x2d, 0x6f, 0x37, 0xa9, 0x9a, 0xce, 0xc9, 0xcd, 0xad, 0x52, 0x6e, - 0x6e, 0x05, 0xcf, 0xbf, 0xa1, 0x5b, 0x2e, 0xb9, 0xf6, 0x32, 0x9b, 0x16, 0x4a, 0xb7, 0x8c, 0x6b, 0xb0, 0xb5, 0x6f, - 0x02, 0x59, 0xe6, 0x23, 0x45, 0x8d, 0xed, 0x45, 0xa3, 0x7c, 0x83, 0x6c, 0x45, 0x8c, 0x3a, 0x65, 0xc1, 0xf8, 0xdb, - 0x1d, 0x3d, 0x90, 0x81, 0xaa, 0xaa, 0x36, 0x0e, 0xee, 0xac, 0xf4, 0x87, 0xe5, 0xc5, 0x73, 0x96, 0x58, 0xe9, 0xe4, - 0x42, 0x15, 0xfa, 0x83, 0x10, 0xdd, 0x54, 0x36, 0x1c, 0x1c, 0xea, 0x62, 0x2b, 0x03, 0x42, 0x0f, 0xd3, 0x7b, 0x1b, - 0x2b, 0x59, 0xee, 0x9a, 0xf2, 0xc5, 0x8c, 0x27, 0x1c, 0x47, 0x5f, 0xae, 0x16, 0x61, 0xad, 0x16, 0xd9, 0x09, 0xf0, - 0xd0, 0x5a, 0x2d, 0x85, 0x5c, 0x2d, 0xc2, 0x99, 0xe9, 0x42, 0xcd, 0xf4, 0x0c, 0x14, 0x90, 0x42, 0xcd, 0xf2, 0x04, - 0x60, 0xe1, 0x85, 0x99, 0xe1, 0xc2, 0xcc, 0x70, 0x1c, 0x52, 0xe3, 0xff, 0xa0, 0xf7, 0x3a, 0xf7, 0xdc, 0x72, 0x37, - 0x3a, 0x8d, 0xf8, 0x76, 0xb4, 0xc1, 0x1c, 0x1f, 0x84, 0x13, 0x08, 0x15, 0x2c, 0x11, 0xab, 0x47, 0x23, 0xec, 0xa8, - 0xa1, 0x72, 0xb4, 0x5f, 0x16, 0x96, 0x64, 0x49, 0x58, 0x92, 0x7b, 0x35, 0xce, 0xa5, 0xe5, 0xe2, 0x55, 0x12, 0x88, - 0x44, 0xc6, 0x4b, 0x69, 0x82, 0x4f, 0x78, 0x39, 0x32, 0x52, 0xf3, 0x64, 0x91, 0x7a, 0x39, 0xcb, 0xd8, 0x18, 0x31, - 0x8c, 0x42, 0xbf, 0xa9, 0xfa, 0xfd, 0xb4, 0xf4, 0x72, 0x6a, 0xe7, 0x67, 0x70, 0xbd, 0x3c, 0x75, 0x16, 0x39, 0x42, - 0x5e, 0x8d, 0xa4, 0xc2, 0xf2, 0x5a, 0xa9, 0xa7, 0x2f, 0xc1, 0x07, 0x75, 0xf7, 0x46, 0x01, 0x10, 0x17, 0xb9, 0xf4, - 0xaf, 0x2d, 0xe1, 0xd2, 0x94, 0x1b, 0x18, 0xf4, 0x90, 0xe7, 0x24, 0x84, 0x4a, 0x10, 0x92, 0xc2, 0xba, 0x71, 0x5f, - 0x3c, 0x9f, 0xb8, 0xee, 0x2c, 0x36, 0x30, 0xc1, 0xe1, 0x00, 0x88, 0x07, 0x53, 0x2f, 0x1a, 0xf0, 0x52, 0xcd, 0x99, - 0x4f, 0x5e, 0x4e, 0x30, 0x19, 0xa0, 0xaa, 0x18, 0x38, 0x65, 0x3d, 0x93, 0x8f, 0x8c, 0x9b, 0x99, 0xef, 0x07, 0xf8, - 0x6e, 0x5d, 0x48, 0xf4, 0x07, 0x05, 0x50, 0x90, 0x29, 0x80, 0x82, 0xc4, 0x00, 0x14, 0xc4, 0x06, 0xa0, 0x60, 0xd3, - 0xf0, 0xb5, 0xd4, 0xe1, 0x46, 0x40, 0x17, 0xe1, 0x43, 0xcf, 0xc2, 0xc6, 0x0a, 0xc5, 0xb3, 0x31, 0x1b, 0xb3, 0x42, - 0xed, 0x3c, 0xb9, 0x9c, 0x8a, 0x9d, 0xc5, 0x58, 0x57, 0x91, 0x65, 0xe2, 0x85, 0x84, 0x22, 0xe7, 0xdc, 0x48, 0xd4, - 0xdd, 0xcf, 0xbd, 0x97, 0x64, 0x2c, 0x99, 0x37, 0x34, 0x6a, 0x30, 0x2f, 0xbb, 0x0e, 0x60, 0x5a, 0xf2, 0x6d, 0x41, - 0x83, 0xe9, 0x54, 0x79, 0x44, 0x9a, 0x04, 0xb5, 0x73, 0x99, 0x14, 0x39, 0x21, 0x4c, 0x82, 0x5e, 0x09, 0x7e, 0x23, - 0x51, 0xfe, 0xbf, 0xe9, 0x04, 0x0f, 0x70, 0x4c, 0xb4, 0x4a, 0xbe, 0x82, 0x01, 0x33, 0xe7, 0x2f, 0xa4, 0x53, 0x36, - 0x42, 0x31, 0x96, 0x69, 0x3c, 0xfa, 0xca, 0x86, 0x08, 0x6d, 0xf5, 0x02, 0x4d, 0x4c, 0x50, 0x07, 0x78, 0x44, 0x7f, - 0x8d, 0xbe, 0x1a, 0x0a, 0x95, 0xae, 0x46, 0xea, 0x9a, 0x9d, 0x73, 0xfe, 0xbe, 0x36, 0x9c, 0xc8, 0x98, 0x36, 0x05, - 0xbe, 0x01, 0x81, 0x7c, 0x03, 0x01, 0xe0, 0xaa, 0xe9, 0xcc, 0x5e, 0x01, 0x9c, 0x03, 0x01, 0x3c, 0xce, 0x3b, 0x1e, - 0x3f, 0xd2, 0x5f, 0xc5, 0x71, 0xef, 0x34, 0x0d, 0xdb, 0x7f, 0x05, 0xc6, 0x62, 0x28, 0xc7, 0xf3, 0x9d, 0x82, 0x64, - 0x8f, 0x52, 0x96, 0xae, 0x9a, 0xc8, 0x0e, 0xc5, 0xfa, 0x34, 0xa7, 0x8c, 0xa5, 0x6d, 0x39, 0x46, 0x1b, 0xaf, 0x1f, - 0xe3, 0xf1, 0xcd, 0x8d, 0x9e, 0x7c, 0xd0, 0x83, 0xdb, 0xdb, 0xdb, 0xd7, 0x3d, 0x66, 0xf3, 0xad, 0x58, 0x3c, 0x2b, - 0xe2, 0xc4, 0x69, 0x1d, 0x72, 0x80, 0x83, 0x9c, 0x84, 0x40, 0x3a, 0xc6, 0xa5, 0x16, 0x1d, 0xd4, 0x2c, 0xe7, 0x35, - 0xb0, 0xcc, 0x22, 0xc8, 0x06, 0x88, 0x6a, 0x9a, 0x8a, 0xd5, 0xf0, 0xa0, 0x54, 0xcd, 0x29, 0x95, 0xda, 0x37, 0x9c, - 0xad, 0x4e, 0x9f, 0x58, 0xb5, 0x09, 0xb7, 0xfe, 0xb5, 0xf6, 0x04, 0x6d, 0x25, 0x0d, 0x84, 0x7a, 0xbe, 0x4e, 0xef, - 0x28, 0x8a, 0xc7, 0x99, 0x89, 0xa7, 0x2a, 0x30, 0xf6, 0xad, 0x1d, 0x41, 0x41, 0xd2, 0x74, 0x1d, 0x70, 0x98, 0x46, - 0x27, 0x2c, 0xfe, 0x29, 0x7d, 0x28, 0x2f, 0x6a, 0x05, 0x4e, 0xf2, 0x77, 0xe1, 0x22, 0x92, 0x58, 0xe8, 0x97, 0x04, - 0x40, 0x22, 0x83, 0x57, 0xa3, 0x62, 0x2d, 0x54, 0x80, 0x9c, 0xa2, 0xf4, 0x56, 0xf1, 0x71, 0x29, 0x4a, 0x95, 0x52, - 0x99, 0x1b, 0x95, 0x02, 0xc2, 0xda, 0xc0, 0xd1, 0x05, 0x7c, 0x01, 0x41, 0x6b, 0xb9, 0x5b, 0xdb, 0x9e, 0x37, 0x32, - 0x9f, 0x99, 0xe6, 0x69, 0xf5, 0x51, 0xfd, 0xfd, 0x61, 0x89, 0x61, 0x36, 0x9e, 0xfe, 0xbe, 0xcd, 0x10, 0x6e, 0xfe, - 0x86, 0x21, 0xba, 0x03, 0x70, 0xcc, 0xd2, 0x1e, 0x0a, 0x59, 0x30, 0xc1, 0x1a, 0xaa, 0xf2, 0x94, 0xcf, 0x5e, 0x3e, - 0xb9, 0x05, 0x34, 0x35, 0x74, 0x71, 0xa3, 0x53, 0x5d, 0x95, 0x20, 0x7c, 0xdf, 0x15, 0xea, 0xb1, 0x39, 0xe0, 0xd4, - 0x00, 0x50, 0x2c, 0xf2, 0x5a, 0x8f, 0xed, 0x1f, 0xf4, 0x46, 0xbd, 0x01, 0xe2, 0xe9, 0x9c, 0x17, 0xfe, 0x11, 0xfd, - 0x3a, 0xf5, 0x67, 0x5c, 0x08, 0xa2, 0x5e, 0x4f, 0xc2, 0x7b, 0x71, 0x96, 0xc6, 0xc1, 0x59, 0x6f, 0x60, 0x2e, 0x02, - 0xc5, 0x59, 0x9a, 0x9f, 0x81, 0x58, 0x8e, 0xf0, 0x88, 0x35, 0xbb, 0x03, 0xc4, 0xc0, 0x52, 0x87, 0x24, 0xab, 0x8e, - 0xed, 0xf7, 0xdf, 0x8c, 0x0c, 0x6f, 0x3a, 0x22, 0xc2, 0xe8, 0xdf, 0x15, 0x08, 0x50, 0xb0, 0xcc, 0x6c, 0x67, 0x26, - 0x5d, 0xed, 0x59, 0x3d, 0x6f, 0x36, 0x79, 0x57, 0xef, 0x58, 0x4d, 0xcb, 0xa9, 0x69, 0x95, 0xd5, 0xb4, 0x49, 0x0e, - 0x35, 0x13, 0xfd, 0xbe, 0xc6, 0x47, 0xcd, 0xe7, 0x80, 0xcb, 0x86, 0xc9, 0x6f, 0x66, 0xd5, 0xbc, 0xdf, 0xf7, 0xe4, - 0x23, 0xf8, 0x85, 0xc4, 0x65, 0x6e, 0x8d, 0xe5, 0xd3, 0xd7, 0xc4, 0x67, 0x66, 0x10, 0x8f, 0xee, 0x8e, 0xa0, 0xbe, - 0x6e, 0x84, 0xd7, 0x31, 0x57, 0xd8, 0x4c, 0x4c, 0xdf, 0xc0, 0xe0, 0x79, 0xc2, 0x07, 0x6f, 0x39, 0xfa, 0x1b, 0xe9, - 0xcc, 0x14, 0x2c, 0xe4, 0xdc, 0x9f, 0xbc, 0x41, 0xe8, 0x64, 0x44, 0x7a, 0xd0, 0xe9, 0x04, 0x0d, 0xd9, 0xef, 0xaf, - 0xa0, 0x33, 0x5b, 0xa9, 0x94, 0xad, 0x8a, 0xca, 0x74, 0x5d, 0x17, 0x65, 0x05, 0x1d, 0x4b, 0x3f, 0x6f, 0x85, 0xcc, - 0xac, 0x9f, 0x59, 0xc8, 0x4f, 0x2b, 0x89, 0x35, 0x65, 0xdb, 0x27, 0x6a, 0x83, 0x34, 0xeb, 0x42, 0x75, 0x81, 0x73, - 0x67, 0xed, 0xf5, 0x46, 0xa8, 0x7f, 0xce, 0x47, 0xeb, 0x62, 0xed, 0x81, 0x4b, 0xcc, 0x2c, 0x9d, 0x2b, 0x0e, 0x8d, - 0xdc, 0x1f, 0x7d, 0x29, 0xd2, 0x9c, 0xf2, 0x00, 0x0d, 0xa2, 0x98, 0xdb, 0x6f, 0x81, 0xf4, 0x43, 0x6f, 0x81, 0xec, - 0xa3, 0x73, 0x4e, 0xde, 0x00, 0x38, 0x1d, 0x22, 0xe2, 0x56, 0x24, 0xe8, 0x58, 0x35, 0xbc, 0xb5, 0x70, 0x4f, 0x7b, - 0x69, 0xdc, 0x4b, 0xf3, 0xb3, 0xb4, 0xdf, 0x37, 0x00, 0x9a, 0x29, 0x22, 0xc3, 0xe3, 0x8c, 0x5c, 0x24, 0x2d, 0x04, - 0x53, 0xda, 0x7f, 0x35, 0x86, 0x04, 0x81, 0x80, 0xff, 0x5d, 0x78, 0x4f, 0x00, 0x6d, 0x93, 0x36, 0xe0, 0xaa, 0xc7, - 0x74, 0x60, 0xb6, 0xe4, 0x6c, 0xd5, 0xd9, 0x00, 0x94, 0x53, 0xa5, 0xf5, 0x94, 0xc7, 0x35, 0x45, 0x44, 0xaa, 0x2c, - 0xd4, 0x6f, 0xac, 0x27, 0x93, 0x55, 0x2e, 0x32, 0xe4, 0xa8, 0x4c, 0xef, 0x6b, 0x46, 0x88, 0x5d, 0xfa, 0xf9, 0x02, - 0x96, 0x6c, 0xfc, 0x09, 0x27, 0x6f, 0x09, 0x90, 0xb6, 0xb3, 0x76, 0x55, 0xed, 0x72, 0xdc, 0xda, 0xcd, 0x01, 0xc9, - 0xd7, 0x1b, 0x8d, 0x46, 0xda, 0x4f, 0x4e, 0xc0, 0x50, 0xf5, 0xd4, 0x52, 0xe8, 0xb1, 0x5a, 0x61, 0xeb, 0x76, 0xe4, - 0x32, 0x4b, 0x06, 0xf3, 0x85, 0x71, 0xfc, 0xca, 0x7c, 0xf4, 0xf1, 0x52, 0x59, 0xbb, 0x8e, 0xf8, 0xfa, 0x8f, 0xb2, - 0x5a, 0xdf, 0xf3, 0xae, 0x6a, 0x02, 0xbe, 0xa8, 0x62, 0x4b, 0xbf, 0xe3, 0x3d, 0xd9, 0xbb, 0xf8, 0xda, 0x0d, 0x76, - 0xc9, 0xf7, 0xbc, 0x45, 0x9d, 0xe7, 0x2b, 0x5f, 0x37, 0xaa, 0x74, 0x7b, 0x2f, 0x59, 0xe0, 0xda, 0x3b, 0x6a, 0x1a, - 0xeb, 0x99, 0x1f, 0x3d, 0x2c, 0x42, 0xb6, 0xf3, 0xb1, 0xf7, 0x55, 0xf3, 0xf4, 0xac, 0xa1, 0x37, 0xa9, 0xa1, 0x8f, - 0xbd, 0x28, 0xdb, 0xa7, 0xa6, 0x11, 0xbd, 0x86, 0x0d, 0x7d, 0xec, 0x2d, 0x39, 0x39, 0x24, 0x18, 0x9c, 0x1a, 0xf3, - 0xc7, 0x87, 0xd3, 0x19, 0xfe, 0x8e, 0x01, 0x95, 0x98, 0xcc, 0xa7, 0xc7, 0xb4, 0xa3, 0x00, 0x33, 0xaa, 0xf4, 0xf6, - 0xe9, 0x81, 0xed, 0x78, 0x59, 0x0f, 0x2d, 0xbd, 0x7b, 0x72, 0x74, 0x3b, 0x5e, 0x55, 0xe3, 0x4b, 0x39, 0xe4, 0x79, - 0x3e, 0x1b, 0x8d, 0x46, 0xc2, 0xa0, 0x73, 0x57, 0x7a, 0x03, 0x2b, 0x90, 0xc1, 0x45, 0xf5, 0xa1, 0x5c, 0x7a, 0x3b, - 0x75, 0x68, 0x57, 0xfe, 0x24, 0x3f, 0x1c, 0x8a, 0x91, 0x39, 0xc6, 0x01, 0xe7, 0xa4, 0x50, 0x72, 0x94, 0xac, 0x25, - 0x88, 0x4e, 0x69, 0x3c, 0x95, 0xf5, 0xda, 0x8a, 0xc8, 0xab, 0x11, 0xf2, 0x21, 0xf8, 0xc9, 0x03, 0xb5, 0xf8, 0xb5, - 0x16, 0xc4, 0x1e, 0xfb, 0x54, 0x29, 0x1d, 0xe2, 0x55, 0x01, 0x21, 0xc2, 0x80, 0x37, 0xd0, 0x0e, 0x4a, 0x70, 0xd8, - 0xe1, 0x3e, 0x22, 0x42, 0xf4, 0x6b, 0x2f, 0x9f, 0xc9, 0x70, 0xe5, 0xde, 0xa0, 0x9a, 0x33, 0x40, 0xac, 0xf4, 0x19, - 0xb8, 0x60, 0x02, 0xea, 0x29, 0x3e, 0x45, 0xff, 0x7a, 0xf3, 0xb0, 0xe9, 0xfa, 0xb4, 0x04, 0x54, 0x44, 0xcf, 0x7e, - 0x3e, 0x06, 0xf0, 0xce, 0xae, 0xcd, 0x48, 0x7b, 0xf9, 0x1b, 0x60, 0x58, 0x29, 0x49, 0xb4, 0x73, 0x4a, 0x04, 0xee, - 0x7c, 0x64, 0x4b, 0x3f, 0x4a, 0x81, 0x98, 0x3b, 0x9e, 0x24, 0xb2, 0x07, 0x1b, 0x39, 0x81, 0x5b, 0x0c, 0x78, 0x74, - 0x00, 0x2a, 0x57, 0x0a, 0x72, 0xaf, 0x39, 0x92, 0x3b, 0x7e, 0xe8, 0xfd, 0x30, 0xa8, 0x07, 0x3f, 0xf4, 0xce, 0x52, - 0x92, 0x3b, 0xc2, 0x33, 0x35, 0x25, 0x44, 0x7c, 0xf6, 0xc3, 0x20, 0x1f, 0xe0, 0x59, 0xa2, 0x45, 0x5a, 0xe4, 0x56, - 0x13, 0x35, 0x6e, 0xc2, 0x8b, 0x44, 0xd2, 0x10, 0xed, 0x3a, 0x8f, 0x88, 0x05, 0x80, 0x64, 0xf1, 0xd9, 0xbc, 0xa1, - 0xa8, 0x77, 0x13, 0xbe, 0x45, 0x77, 0x59, 0xec, 0xf7, 0xb7, 0x79, 0x5a, 0xf7, 0x74, 0xa8, 0x0c, 0xbe, 0x20, 0xd5, - 0x04, 0x78, 0xb4, 0xbf, 0x36, 0xc7, 0xab, 0x57, 0x9b, 0x23, 0x65, 0xa1, 0x4a, 0xd4, 0x6f, 0xb1, 0x9a, 0xf5, 0x10, - 0x91, 0x3b, 0xcb, 0x8c, 0xbd, 0xbd, 0xe0, 0x95, 0x9c, 0x55, 0xb1, 0x5d, 0x8e, 0xaf, 0x08, 0x6b, 0x2b, 0x09, 0xd0, - 0xd1, 0x7a, 0xac, 0x4d, 0x31, 0xf2, 0x2b, 0x85, 0x04, 0x5c, 0x74, 0x6c, 0x2d, 0x14, 0x1b, 0x2f, 0x40, 0x5f, 0xb2, - 0x33, 0x0d, 0xb0, 0xde, 0xe8, 0x55, 0xc4, 0x6d, 0xf9, 0x48, 0x85, 0x37, 0xb9, 0xa9, 0x32, 0x2b, 0x9b, 0x45, 0xbb, - 0x9f, 0x2a, 0x5e, 0x21, 0x6e, 0xbd, 0x51, 0x7b, 0x14, 0xa0, 0xf6, 0xd0, 0x42, 0x19, 0xa0, 0x4b, 0xd3, 0x0c, 0x00, - 0x19, 0x00, 0x64, 0xaa, 0x88, 0xcf, 0x04, 0xa8, 0xb4, 0xd5, 0x8d, 0x02, 0x27, 0xd2, 0x6b, 0x60, 0x5c, 0x60, 0xa5, - 0x8f, 0x6c, 0x64, 0xb0, 0xd8, 0x22, 0xc0, 0x2d, 0x47, 0xfa, 0x30, 0x0d, 0x27, 0xdb, 0x68, 0x0e, 0x93, 0x34, 0xbf, - 0x0f, 0xb3, 0x54, 0x42, 0x4b, 0xfc, 0x28, 0x6b, 0x8c, 0x58, 0x40, 0xfa, 0x3e, 0xbd, 0x28, 0xb2, 0x98, 0x20, 0xe1, - 0xac, 0xa7, 0x0e, 0xa0, 0x9a, 0x9c, 0x6b, 0x4d, 0xab, 0x67, 0xb5, 0xc9, 0x43, 0x16, 0xe8, 0xec, 0xc1, 0x98, 0xd4, - 0x72, 0x43, 0x8f, 0xec, 0xaf, 0x1c, 0xcf, 0x08, 0xdf, 0xf5, 0x0c, 0xa7, 0xfe, 0xbb, 0xa9, 0x81, 0x94, 0x29, 0x01, - 0x04, 0x19, 0x1c, 0x4d, 0x08, 0xe5, 0xe9, 0x98, 0x4c, 0x6d, 0x7e, 0x04, 0xc2, 0x11, 0xc1, 0x2b, 0x78, 0x6e, 0x68, - 0xdd, 0x72, 0x63, 0x67, 0x91, 0xa7, 0x09, 0x20, 0x8b, 0x17, 0x7c, 0x0b, 0xc8, 0x9c, 0x7a, 0x55, 0xc8, 0x9e, 0x3d, - 0x17, 0xd3, 0xd9, 0x3c, 0x78, 0x48, 0x68, 0xff, 0x62, 0xc2, 0x6f, 0xba, 0xab, 0xe4, 0xca, 0xd4, 0xba, 0x37, 0xd1, - 0x63, 0x2e, 0x77, 0xfa, 0xb4, 0xe2, 0x18, 0xf1, 0x0c, 0x56, 0x01, 0x39, 0x67, 0x43, 0x7e, 0x7d, 0x0e, 0xd8, 0x2d, - 0x2b, 0xe1, 0x45, 0xfc, 0x3a, 0x94, 0xd5, 0x02, 0xe4, 0x47, 0xce, 0x23, 0xf3, 0xcb, 0x57, 0xdb, 0xa1, 0x9c, 0x53, - 0x14, 0xd1, 0x72, 0x6a, 0x5a, 0x52, 0xc8, 0x0e, 0x3d, 0x05, 0x93, 0xa9, 0x2d, 0x7f, 0x6f, 0x13, 0x97, 0xe4, 0x9b, - 0x49, 0x64, 0x5f, 0x07, 0x58, 0xb3, 0x56, 0xdd, 0x43, 0x37, 0x04, 0x03, 0x44, 0x46, 0x28, 0xb3, 0xb9, 0xbe, 0x5b, - 0x0f, 0x06, 0x0a, 0xe6, 0x57, 0xd0, 0x4d, 0x8b, 0x4e, 0x71, 0x80, 0x9c, 0xb5, 0xae, 0x51, 0xa9, 0x2a, 0x0e, 0x1d, - 0xe6, 0xdd, 0xb2, 0x2a, 0xbb, 0x2c, 0xbd, 0x10, 0xa4, 0x46, 0x5d, 0x05, 0x8b, 0x94, 0x8a, 0x28, 0xde, 0x93, 0x5f, - 0x03, 0x13, 0xcf, 0xac, 0x1c, 0xa5, 0xf1, 0x1c, 0x10, 0x83, 0x14, 0x10, 0xa7, 0xfc, 0x0a, 0xd0, 0x44, 0x17, 0x51, - 0x98, 0xbd, 0x8d, 0xab, 0xa0, 0xb6, 0x9a, 0x7e, 0xef, 0x40, 0xc6, 0x9e, 0xd7, 0xfd, 0x7e, 0x4a, 0x8c, 0x7e, 0x18, - 0x85, 0x81, 0x7f, 0x8f, 0xa7, 0xfb, 0x26, 0x48, 0xcd, 0x2b, 0x0f, 0xf0, 0x8a, 0x2e, 0xb7, 0x36, 0xe5, 0x8a, 0xc6, - 0x85, 0xbf, 0x46, 0x70, 0xf8, 0xd4, 0x51, 0x6c, 0xb7, 0xa9, 0x72, 0x6a, 0x63, 0x30, 0x08, 0xe1, 0xbe, 0x95, 0xf1, - 0xfb, 0xc4, 0xcb, 0x67, 0xd1, 0x1c, 0x14, 0xa5, 0x99, 0xe6, 0x0b, 0x29, 0xa4, 0x9b, 0x00, 0x7d, 0x34, 0x08, 0xb5, - 0xba, 0xf2, 0x8f, 0xc4, 0x4b, 0xd5, 0xb4, 0x36, 0x4f, 0xb1, 0x46, 0x81, 0x98, 0x45, 0xf3, 0x86, 0x65, 0x74, 0x48, - 0xaa, 0xcb, 0xa5, 0x69, 0xc6, 0x1f, 0x56, 0x33, 0x54, 0x2b, 0x8e, 0x9a, 0xa0, 0x46, 0xe9, 0x06, 0x2e, 0x80, 0x7f, - 0xa3, 0x3b, 0x8e, 0x6a, 0x14, 0x29, 0x1a, 0xf0, 0x09, 0x62, 0xc4, 0x9a, 0xcd, 0x13, 0xd6, 0x9a, 0xba, 0x66, 0xf4, - 0xfb, 0x32, 0x64, 0xc8, 0x24, 0x21, 0x4f, 0x1f, 0x2e, 0xd7, 0x4f, 0xa4, 0xba, 0x00, 0x7e, 0xe5, 0x8a, 0xcd, 0x7a, - 0xbd, 0x39, 0xc0, 0xf5, 0xc2, 0xfa, 0x85, 0x8d, 0x2b, 0x38, 0xbf, 0x24, 0xf8, 0x5d, 0xf5, 0x23, 0xcc, 0x32, 0xa8, - 0x02, 0x32, 0xfe, 0x58, 0x48, 0xe7, 0xb9, 0x8b, 0x49, 0xfd, 0x66, 0xa4, 0x2e, 0x28, 0xb3, 0x74, 0x6e, 0x71, 0x82, - 0x80, 0xf3, 0xb0, 0x7a, 0x02, 0xc9, 0xbe, 0x7c, 0xec, 0xd3, 0x8c, 0x02, 0xd5, 0x11, 0xe0, 0xb3, 0x59, 0x3f, 0x84, - 0xfd, 0x03, 0x22, 0x0b, 0xf5, 0x37, 0x6f, 0xe4, 0xac, 0x21, 0x79, 0x20, 0xd5, 0xdc, 0xc7, 0x70, 0x6a, 0x2c, 0xf0, - 0xa5, 0x45, 0x6f, 0x2a, 0x78, 0x4d, 0xc8, 0xdc, 0x0b, 0xb4, 0xf6, 0x2d, 0xe0, 0x08, 0x11, 0x5c, 0x46, 0x29, 0x4e, - 0x7b, 0xbb, 0x5e, 0x80, 0xdc, 0xe6, 0x16, 0xe4, 0xf5, 0x3b, 0x17, 0xbf, 0x38, 0x45, 0x7a, 0x16, 0x5d, 0x60, 0xa0, - 0x0b, 0x32, 0x6f, 0xfc, 0xb3, 0x82, 0x95, 0x0b, 0xe8, 0xbd, 0x54, 0xac, 0xe4, 0x64, 0xdb, 0xa9, 0x3f, 0x4a, 0x65, - 0xbf, 0x3d, 0xb3, 0x26, 0xf0, 0xab, 0xc4, 0x7e, 0x89, 0x4c, 0xbe, 0xe9, 0xb1, 0xc9, 0x57, 0x86, 0x45, 0xa7, 0x96, - 0xc1, 0x39, 0x3d, 0x32, 0x38, 0xf7, 0x76, 0x56, 0x6d, 0x42, 0x18, 0x0a, 0x92, 0x40, 0xd3, 0xa5, 0x87, 0x75, 0xd3, - 0x9f, 0x9f, 0xb4, 0xa8, 0xb6, 0x6a, 0xdf, 0xba, 0x1f, 0x87, 0xd8, 0xc5, 0xaf, 0x12, 0xcf, 0x10, 0x91, 0xfa, 0x40, - 0x07, 0x26, 0x83, 0x27, 0x2e, 0xfb, 0x7d, 0x28, 0x6c, 0x36, 0x9e, 0x8f, 0xea, 0xe2, 0xe7, 0xe2, 0x01, 0x50, 0x1d, - 0x2a, 0xb0, 0xcb, 0xa1, 0x0c, 0x65, 0xc4, 0xa6, 0xb6, 0xdc, 0xf3, 0xfb, 0xab, 0x30, 0x07, 0x79, 0x47, 0xc3, 0xe3, - 0x9c, 0x81, 0x18, 0x06, 0x5f, 0xff, 0xe1, 0xc9, 0x3e, 0x6d, 0x7e, 0x38, 0x83, 0xef, 0x8e, 0xce, 0x3e, 0x22, 0xdd, - 0xcd, 0xd9, 0xba, 0x2c, 0xee, 0xd3, 0x58, 0x9c, 0xfd, 0x00, 0xa9, 0x3f, 0x9c, 0x15, 0xe5, 0xd9, 0x0f, 0xaa, 0x32, - 0x3f, 0x9c, 0xd1, 0x82, 0x1b, 0xfd, 0x6e, 0x4d, 0xbc, 0x7f, 0x54, 0x9a, 0x01, 0x6d, 0x09, 0x91, 0x59, 0x5a, 0xfd, - 0x08, 0x4a, 0x44, 0xc5, 0x8f, 0x2a, 0xa3, 0x5a, 0xad, 0x1d, 0xe7, 0x43, 0xa2, 0x91, 0xb2, 0x69, 0x42, 0xe2, 0x6a, - 0x09, 0xeb, 0x50, 0xcf, 0x4e, 0x9b, 0x6f, 0xc7, 0x79, 0xa0, 0x0e, 0x88, 0x9c, 0x5f, 0xe7, 0xa3, 0x2d, 0x7d, 0x0d, - 0xbe, 0x75, 0x38, 0xe4, 0xa3, 0x9d, 0xf9, 0xe9, 0x93, 0xb5, 0x52, 0xc6, 0x1d, 0x29, 0x72, 0x21, 0xe4, 0x8c, 0xdb, - 0xf6, 0x18, 0x70, 0x00, 0xf8, 0x87, 0x03, 0xfd, 0xde, 0xc9, 0xdf, 0x6a, 0xb7, 0xb4, 0xea, 0xf9, 0xb1, 0xc5, 0x9d, - 0xf1, 0xba, 0x36, 0x44, 0x6d, 0x7b, 0x89, 0x2d, 0xbd, 0x6f, 0x1a, 0xd4, 0x14, 0xd1, 0x4f, 0x58, 0x4d, 0xac, 0xe2, - 0xb0, 0x20, 0x25, 0x24, 0x31, 0x1c, 0xa3, 0x1d, 0x7a, 0x9c, 0x2e, 0x96, 0x9e, 0xdc, 0x77, 0x78, 0xb9, 0xf5, 0x7d, - 0x40, 0xd2, 0x2a, 0x9c, 0x7f, 0xf4, 0x42, 0x03, 0x8f, 0x5e, 0xe4, 0x55, 0x91, 0x89, 0x91, 0xa0, 0x51, 0x7e, 0x4b, - 0xe2, 0xcc, 0x19, 0xd6, 0xe2, 0x4c, 0x81, 0x85, 0x85, 0x04, 0xd0, 0x5d, 0x94, 0x94, 0x1e, 0x9c, 0x3d, 0xd9, 0x97, - 0xcd, 0xef, 0x04, 0x0f, 0x31, 0x5a, 0x00, 0x23, 0xce, 0xae, 0x5d, 0xde, 0x43, 0x58, 0xe6, 0xde, 0xef, 0x6f, 0xef, - 0xf2, 0x02, 0x42, 0x34, 0xcf, 0xa4, 0x62, 0xb5, 0x3c, 0x03, 0xc6, 0x3c, 0x11, 0x9f, 0x85, 0x95, 0x9c, 0x06, 0x55, - 0x47, 0xb1, 0x7a, 0x1b, 0xcf, 0x3d, 0xa0, 0xf8, 0xfe, 0x90, 0x00, 0x97, 0xbb, 0xcf, 0xde, 0x28, 0xd7, 0x54, 0xd2, - 0x23, 0xcf, 0x31, 0x5a, 0x32, 0x01, 0x8a, 0x67, 0x88, 0x93, 0x14, 0x56, 0xcf, 0x4d, 0x90, 0x8a, 0x7c, 0x7d, 0x42, - 0xf1, 0x45, 0xf3, 0x28, 0x6a, 0x58, 0xc8, 0x12, 0x38, 0x1e, 0x92, 0x59, 0x36, 0x47, 0x96, 0xf2, 0xb4, 0x3d, 0x45, - 0x3a, 0x3a, 0xb1, 0xc4, 0x6f, 0x6b, 0x7e, 0xbd, 0x48, 0x45, 0x60, 0xd2, 0xce, 0x56, 0xe6, 0x5e, 0x08, 0x43, 0x95, - 0x70, 0xef, 0x75, 0x3d, 0x0b, 0xe5, 0xa6, 0x68, 0x55, 0xcc, 0x1e, 0xa6, 0xc4, 0x0c, 0x53, 0xac, 0xbf, 0xb0, 0xe1, - 0x37, 0x89, 0x17, 0x83, 0xe1, 0x7a, 0xc9, 0xcb, 0xd9, 0xc6, 0x2c, 0x84, 0xc3, 0x61, 0x33, 0x29, 0x66, 0x4b, 0x08, - 0x73, 0x5d, 0xce, 0x0f, 0x87, 0xae, 0x96, 0xad, 0x85, 0x07, 0x0f, 0x55, 0x0b, 0x37, 0x0d, 0xcb, 0xe1, 0x67, 0x32, - 0x8b, 0xb1, 0x7d, 0x8d, 0xcf, 0xec, 0xcf, 0x17, 0xdd, 0xb3, 0x04, 0xc9, 0x37, 0xd6, 0x40, 0x3b, 0x36, 0x6b, 0x77, - 0xb8, 0x1a, 0x01, 0x49, 0xe9, 0x6e, 0xf4, 0x77, 0x65, 0x27, 0x4f, 0x09, 0x72, 0x47, 0x2b, 0xb0, 0xdf, 0x7d, 0xe3, - 0x4f, 0xb4, 0xd8, 0x83, 0x76, 0x1b, 0x5b, 0x42, 0x54, 0xd3, 0x9e, 0xcb, 0x95, 0x62, 0x69, 0xde, 0x4a, 0x1b, 0x3d, - 0x1f, 0xd6, 0xe7, 0xbe, 0x91, 0x03, 0x05, 0x63, 0xc4, 0x53, 0xeb, 0x20, 0x9a, 0xcd, 0x81, 0x06, 0x03, 0xcd, 0x23, - 0x3c, 0xb5, 0xd0, 0x41, 0x99, 0xb5, 0x61, 0x3f, 0x49, 0x4e, 0x96, 0xc7, 0xe1, 0x5b, 0xf8, 0x97, 0xcf, 0xb0, 0x49, - 0x4c, 0xb1, 0x3d, 0xfe, 0x56, 0x29, 0x2a, 0x3c, 0xb6, 0x20, 0xae, 0xb5, 0x1b, 0x51, 0x1b, 0x2a, 0x87, 0x7f, 0x09, - 0xfb, 0x08, 0xfb, 0x0d, 0x4d, 0x10, 0x06, 0xbb, 0xfe, 0x4c, 0x20, 0x44, 0x2c, 0xc4, 0x0b, 0xfe, 0x56, 0x49, 0x2a, - 0x3a, 0xe1, 0xb3, 0x45, 0x09, 0xbc, 0x75, 0x18, 0xd0, 0x27, 0x14, 0x29, 0x85, 0x30, 0x34, 0x13, 0x7a, 0x47, 0xff, - 0x8d, 0xd8, 0xc9, 0x26, 0xb9, 0x15, 0xf2, 0x81, 0xa4, 0x92, 0x60, 0x82, 0x95, 0x17, 0xca, 0x17, 0xee, 0x85, 0x52, - 0x6b, 0x2d, 0x68, 0xfd, 0xf2, 0x27, 0x89, 0x67, 0xf0, 0xf7, 0x40, 0xc6, 0xa0, 0xdb, 0x88, 0x6a, 0x92, 0x63, 0xfa, - 0x28, 0x9d, 0x67, 0xa0, 0x02, 0x3a, 0x5b, 0x67, 0x61, 0xbd, 0x2c, 0xca, 0x55, 0x2b, 0x52, 0x54, 0x96, 0x3e, 0x52, - 0x8f, 0x31, 0x2f, 0xcc, 0x93, 0x13, 0xf9, 0xe0, 0x11, 0x00, 0xe3, 0x51, 0x9e, 0x56, 0x1d, 0xa5, 0xf5, 0x03, 0xcb, - 0x80, 0x11, 0x38, 0x51, 0x06, 0x3c, 0xc2, 0x32, 0x30, 0x4f, 0xbb, 0x0c, 0x35, 0x88, 0x35, 0xaa, 0xae, 0xd4, 0x06, - 0x73, 0xa2, 0x28, 0xf9, 0x14, 0x4b, 0x2b, 0x8c, 0xa1, 0xa9, 0x2b, 0x8f, 0xac, 0x97, 0x9c, 0xb0, 0x27, 0xbb, 0x81, - 0x74, 0x0b, 0x1b, 0x85, 0x33, 0xe8, 0x5a, 0x96, 0x28, 0x17, 0xdd, 0x32, 0xa2, 0x4c, 0x84, 0xd4, 0xcf, 0x1e, 0xce, - 0xb4, 0xda, 0x6f, 0xec, 0xa4, 0x7d, 0x7b, 0xa4, 0xe8, 0x05, 0x83, 0xf6, 0x69, 0x8f, 0x94, 0x7a, 0xd6, 0xc8, 0x65, - 0x60, 0x4b, 0x97, 0xaa, 0x9e, 0xff, 0x02, 0xe5, 0x3b, 0x98, 0x19, 0x67, 0xb3, 0xdf, 0xf5, 0xe6, 0xf6, 0x64, 0x5f, - 0x37, 0xbf, 0xb3, 0x5e, 0x0f, 0xb6, 0x06, 0x99, 0xf8, 0x42, 0xb1, 0x50, 0x59, 0x85, 0x58, 0x41, 0xda, 0xff, 0x12, - 0xde, 0xef, 0xf0, 0xd6, 0x08, 0xcd, 0xca, 0x78, 0x98, 0x8f, 0x9e, 0xec, 0x45, 0xf3, 0x7b, 0x67, 0xd9, 0x56, 0xae, - 0x4a, 0x66, 0xfb, 0xfd, 0x28, 0x69, 0xce, 0x1e, 0xaf, 0x91, 0xd4, 0x01, 0x3e, 0x5e, 0x9f, 0xe1, 0x23, 0x95, 0x50, - 0x6a, 0x41, 0x55, 0x83, 0xd6, 0xc7, 0x7e, 0x6f, 0x3d, 0xa7, 0x8f, 0x1f, 0xcb, 0xe9, 0x96, 0x14, 0x61, 0xfc, 0xc0, - 0x60, 0xca, 0x4e, 0x9c, 0xba, 0xe4, 0xcd, 0x90, 0xde, 0x75, 0xab, 0xa4, 0x2e, 0x7b, 0x94, 0x08, 0x42, 0x1d, 0xac, - 0x5f, 0xec, 0x87, 0x30, 0xb3, 0x45, 0x7f, 0xd8, 0xac, 0xe6, 0x04, 0x88, 0x08, 0x68, 0xad, 0xf2, 0x3e, 0x70, 0xcc, - 0x17, 0x66, 0xcd, 0x0d, 0xe9, 0xd6, 0x9b, 0x2b, 0xed, 0x95, 0x14, 0xd0, 0xcf, 0x41, 0xe6, 0xf6, 0xd1, 0x2d, 0x57, - 0x2d, 0xf3, 0x5c, 0xda, 0x72, 0xc0, 0xa2, 0x85, 0x40, 0xcd, 0xce, 0xa5, 0xc3, 0x81, 0x82, 0x50, 0x57, 0xa2, 0x8a, - 0xb8, 0x3a, 0x8a, 0x16, 0xa2, 0x56, 0xab, 0x76, 0x39, 0xd9, 0x54, 0xc8, 0x96, 0x44, 0x90, 0x51, 0xb2, 0x57, 0x42, - 0x7d, 0x94, 0xab, 0x3d, 0xd3, 0x70, 0x80, 0x26, 0x60, 0xd3, 0x06, 0x7f, 0x0b, 0xdc, 0xcb, 0xe0, 0xcc, 0xb4, 0x4f, - 0xc3, 0x08, 0x38, 0xcd, 0x21, 0xe6, 0xcf, 0xef, 0x7a, 0x50, 0xc1, 0x83, 0x8e, 0xf4, 0xd7, 0xf5, 0xac, 0xc0, 0x33, - 0xf7, 0xc4, 0xf3, 0x37, 0x27, 0xd2, 0x8b, 0x1c, 0x1e, 0x68, 0x1a, 0xc4, 0x8c, 0xbf, 0x28, 0xcb, 0x70, 0x37, 0x5a, - 0x96, 0xc5, 0xca, 0x8b, 0xf4, 0x3e, 0x9e, 0x49, 0x31, 0x90, 0x98, 0x31, 0x33, 0xba, 0x8a, 0x75, 0x9c, 0xc3, 0xb8, - 0xb7, 0x27, 0x61, 0x85, 0xf6, 0xcf, 0x12, 0x7b, 0x5d, 0x00, 0x96, 0x43, 0xd6, 0xa0, 0x15, 0xde, 0xe9, 0xf6, 0x76, - 0x8f, 0x4b, 0x76, 0x14, 0x37, 0x80, 0x7e, 0x56, 0x43, 0xcb, 0x04, 0xb5, 0xcc, 0xba, 0x93, 0xc9, 0x14, 0xc9, 0xe5, - 0xdb, 0xb0, 0x37, 0xac, 0xc8, 0xe7, 0x8d, 0xdc, 0x1e, 0xde, 0x87, 0x2b, 0x11, 0x6b, 0x0b, 0x3a, 0xe9, 0xc8, 0x38, - 0xdc, 0x0b, 0xcd, 0x8d, 0x74, 0xff, 0xa4, 0x4a, 0xc2, 0x52, 0xc4, 0x70, 0x0b, 0x64, 0x7b, 0xb5, 0xad, 0x04, 0x25, - 0xf0, 0xc1, 0x7e, 0x2c, 0xc5, 0x32, 0xdd, 0x0a, 0xc0, 0x75, 0xe0, 0x7f, 0x4a, 0x44, 0x42, 0x77, 0xe7, 0x21, 0x8a, - 0x35, 0xf2, 0xbe, 0x41, 0x34, 0xf6, 0xd7, 0x20, 0xa7, 0x01, 0x99, 0x48, 0x31, 0x92, 0x05, 0x03, 0x1f, 0x40, 0xce, - 0xd7, 0x60, 0x92, 0x9b, 0xe6, 0x9e, 0x1f, 0xe4, 0xba, 0x83, 0x69, 0x1f, 0x74, 0x2f, 0xae, 0x35, 0xcb, 0xc1, 0x2b, - 0x26, 0xe2, 0x7f, 0xab, 0xbd, 0x92, 0xe5, 0x2c, 0xf3, 0x1b, 0x73, 0xd1, 0xc9, 0xe0, 0xaa, 0x21, 0xfc, 0x62, 0x96, - 0xcd, 0x79, 0x34, 0xcb, 0x74, 0xd4, 0x7f, 0xd1, 0x1c, 0x95, 0x02, 0x70, 0xea, 0x78, 0x01, 0xd6, 0xd0, 0x57, 0xba, - 0x69, 0xc5, 0x23, 0x8d, 0x31, 0x0a, 0x2a, 0x74, 0x10, 0xfa, 0x5b, 0x0d, 0x48, 0x1b, 0x4c, 0xd2, 0x24, 0x54, 0x3e, - 0xb8, 0xa0, 0x1b, 0xe6, 0xe5, 0xca, 0xe5, 0xaa, 0x49, 0xd5, 0xf2, 0xcb, 0x11, 0xf5, 0x5d, 0x2d, 0xb9, 0x54, 0x9b, - 0x4f, 0x8d, 0xb2, 0x46, 0x90, 0xc9, 0x51, 0xfa, 0x7d, 0xca, 0x85, 0x5b, 0x19, 0x93, 0xf5, 0xe1, 0xe0, 0x15, 0xdc, - 0xd4, 0xf8, 0x75, 0x4e, 0x84, 0xa2, 0xf6, 0x90, 0x08, 0x5b, 0xbb, 0x15, 0xba, 0xf7, 0xb8, 0x51, 0x9a, 0x47, 0xd9, - 0x26, 0x16, 0x95, 0xd7, 0x4b, 0xc0, 0x5a, 0xdc, 0x03, 0x5e, 0x54, 0x5a, 0xfa, 0x15, 0x2b, 0x00, 0x3d, 0x40, 0x0a, - 0x1b, 0x3f, 0x22, 0x03, 0xd6, 0x47, 0x2f, 0xf5, 0xfb, 0x7d, 0x63, 0xca, 0xff, 0xf0, 0x90, 0x03, 0x49, 0xa1, 0x28, - 0xeb, 0x1d, 0x4c, 0x20, 0xb8, 0x76, 0x92, 0xf6, 0xac, 0xe6, 0xd7, 0xeb, 0xda, 0x03, 0x7e, 0x2b, 0xdf, 0x22, 0xb1, - 0x7a, 0x6d, 0x5f, 0x6c, 0xf6, 0x69, 0x75, 0x63, 0x34, 0x0e, 0x82, 0xa5, 0xd5, 0x5b, 0xad, 0x72, 0xc8, 0x1b, 0x5e, - 0x81, 0x48, 0x65, 0x5d, 0x5d, 0x2b, 0xe7, 0xea, 0x5a, 0x70, 0xe4, 0x92, 0x2d, 0x79, 0x0e, 0xff, 0x85, 0xdc, 0x2b, - 0x0f, 0x87, 0xc2, 0xef, 0xf7, 0xd3, 0x19, 0x69, 0x65, 0x81, 0x3d, 0x6d, 0x5d, 0x7b, 0xa1, 0x7f, 0x38, 0xfc, 0x08, - 0x5e, 0x23, 0xfe, 0xe1, 0x50, 0xf6, 0xfb, 0x9f, 0xcc, 0x4d, 0xe6, 0x7c, 0xac, 0x94, 0xb2, 0x97, 0xa8, 0x74, 0x7f, - 0x9b, 0xf0, 0xde, 0xff, 0x1e, 0xfd, 0xef, 0xd1, 0x65, 0x4f, 0x85, 0x80, 0x25, 0x7c, 0x86, 0x37, 0x74, 0xa6, 0x2e, - 0xe7, 0x4c, 0xba, 0xbb, 0x2b, 0x3f, 0xf4, 0x9e, 0x86, 0x8a, 0xef, 0xcd, 0x4d, 0x1b, 0x7f, 0xad, 0x8e, 0x34, 0x09, - 0x1d, 0x17, 0xfd, 0xc3, 0xe1, 0x73, 0xa2, 0xf5, 0x69, 0xa9, 0xd2, 0xa7, 0x29, 0x1c, 0x25, 0x43, 0x8c, 0xeb, 0x16, - 0xa6, 0x03, 0xfb, 0x71, 0xf3, 0x55, 0xf2, 0xe2, 0x2c, 0x85, 0x6b, 0x6f, 0x3e, 0x4b, 0xe7, 0x53, 0xb0, 0xae, 0x0c, - 0xf3, 0x59, 0x3d, 0x0f, 0x20, 0x75, 0x08, 0x69, 0xd6, 0x34, 0xfc, 0x4b, 0xe5, 0x0a, 0xde, 0xda, 0xe3, 0xdd, 0xc0, - 0x45, 0xa9, 0x23, 0x7d, 0xd2, 0x46, 0xd3, 0x25, 0x95, 0xfc, 0x27, 0x91, 0xc7, 0x18, 0xb3, 0xf1, 0x9a, 0x78, 0x3f, - 0x8b, 0xfc, 0x55, 0x01, 0xd8, 0x45, 0x00, 0x86, 0x9c, 0xce, 0x1d, 0x49, 0xfc, 0xe7, 0xe4, 0xfb, 0x3f, 0xa6, 0x4b, - 0xfb, 0x58, 0x16, 0x77, 0xa5, 0xa8, 0xaa, 0xa3, 0xd2, 0x76, 0xb6, 0x5c, 0x0f, 0x4c, 0xa2, 0xfd, 0xbe, 0x64, 0x12, - 0x4d, 0x31, 0x14, 0x05, 0x6e, 0x8d, 0xbd, 0x69, 0xca, 0x15, 0x63, 0xf5, 0xc8, 0x58, 0x3f, 0x5f, 0xee, 0xde, 0xc6, - 0x5e, 0xea, 0x07, 0x29, 0x08, 0xc2, 0x1a, 0x4a, 0x29, 0x45, 0x3e, 0x38, 0x9f, 0x61, 0x2a, 0x51, 0xeb, 0x52, 0xaa, - 0xfc, 0x61, 0xa4, 0xf9, 0x30, 0x05, 0xbd, 0xec, 0xdf, 0x2b, 0x98, 0xff, 0xba, 0x3d, 0x58, 0x9f, 0xd6, 0x65, 0x1a, - 0x55, 0x44, 0x95, 0x17, 0xa6, 0xda, 0x04, 0x22, 0xf8, 0xb5, 0xb0, 0xf8, 0x7e, 0x7d, 0x72, 0x24, 0x68, 0xcc, 0x64, - 0xf9, 0x74, 0xe4, 0x7e, 0x61, 0x5f, 0xb9, 0x8e, 0xe7, 0x7f, 0x6e, 0xe6, 0xff, 0x00, 0x9d, 0x21, 0x8b, 0x6b, 0x6e, - 0x19, 0x2c, 0x70, 0xf6, 0x4b, 0x57, 0x0f, 0xf8, 0x9b, 0x79, 0xe2, 0x1a, 0xe8, 0x98, 0xaf, 0xd1, 0x55, 0x31, 0x9d, - 0x15, 0x03, 0xe0, 0xb2, 0xf5, 0x1b, 0x6b, 0x4e, 0xbc, 0xb1, 0x28, 0xaf, 0xe4, 0x82, 0xd0, 0xd7, 0x55, 0x98, 0x8d, - 0xab, 0x62, 0x53, 0x89, 0x62, 0x53, 0xf7, 0x48, 0x2d, 0x9b, 0x4f, 0x6b, 0x5b, 0x21, 0xfb, 0x57, 0xd1, 0x62, 0xf0, - 0x32, 0xac, 0x93, 0x51, 0x96, 0xae, 0xa7, 0xc0, 0xaf, 0x17, 0xc0, 0x59, 0x64, 0x5e, 0x79, 0xef, 0xec, 0x01, 0x5b, - 0x34, 0x9e, 0x02, 0x39, 0x2a, 0xfd, 0x91, 0x37, 0x46, 0xa7, 0x27, 0xfa, 0xfd, 0x7c, 0x4a, 0x31, 0x5f, 0x7f, 0x05, - 0x78, 0xae, 0x5a, 0x2e, 0x40, 0x5f, 0x86, 0x3a, 0xa8, 0x44, 0xa9, 0x15, 0xc3, 0x88, 0x85, 0xbf, 0x0a, 0x24, 0x72, - 0xa6, 0xc0, 0x66, 0x15, 0x25, 0xa1, 0x12, 0x95, 0x92, 0xad, 0x09, 0x6a, 0xe9, 0x7d, 0x51, 0xd6, 0xfb, 0x0a, 0x1c, - 0x25, 0x23, 0x6d, 0x96, 0x93, 0x66, 0x5c, 0x81, 0x32, 0x17, 0xfd, 0x60, 0xff, 0xaa, 0x3c, 0xbf, 0x91, 0xf9, 0x2c, - 0xf7, 0x1d, 0x9d, 0xd3, 0x76, 0x5c, 0xa0, 0xcc, 0x2d, 0xa7, 0xad, 0x96, 0x3c, 0x26, 0xef, 0x59, 0xb0, 0xed, 0xbf, - 0x48, 0x90, 0x62, 0x11, 0xe6, 0x13, 0xaa, 0x6c, 0xfe, 0x0e, 0xa1, 0xb6, 0x38, 0xb0, 0xc7, 0x2e, 0x4c, 0xc4, 0x7f, - 0x0b, 0x96, 0xc4, 0x30, 0x2b, 0x45, 0x18, 0xef, 0xc0, 0xfb, 0x67, 0x53, 0x89, 0xd1, 0x19, 0x3a, 0xb9, 0x9f, 0x3d, - 0xa4, 0x75, 0x72, 0xf6, 0xf6, 0xf5, 0xd9, 0x0f, 0xbd, 0x41, 0x31, 0x4a, 0xe3, 0x41, 0xef, 0x87, 0xb3, 0xd5, 0x06, - 0xd0, 0x32, 0xc5, 0x59, 0x4c, 0xa6, 0x34, 0x11, 0x9f, 0x91, 0x61, 0xf0, 0xac, 0x4e, 0xc4, 0x19, 0x4d, 0x4c, 0xf7, - 0x35, 0x4a, 0x93, 0x6f, 0x47, 0x61, 0x0e, 0x2f, 0x97, 0x62, 0x53, 0x89, 0x18, 0xec, 0x94, 0x6a, 0x9e, 0xe5, 0xed, - 0xb3, 0x38, 0x1f, 0x75, 0xc8, 0x2a, 0x1d, 0xf8, 0xdb, 0x13, 0x69, 0x57, 0xa5, 0x2b, 0x20, 0xf4, 0x00, 0x38, 0xe9, - 0xca, 0x9f, 0x87, 0x83, 0x48, 0x20, 0xd4, 0x82, 0x39, 0x99, 0x46, 0x74, 0x43, 0x7a, 0x85, 0x7d, 0x06, 0x66, 0x21, - 0xa5, 0x79, 0x70, 0x73, 0xb5, 0x18, 0xba, 0x2b, 0x56, 0x8e, 0xc2, 0x6a, 0x2d, 0xa2, 0x1a, 0x59, 0x8f, 0xc1, 0x79, - 0x07, 0x22, 0x00, 0x14, 0x39, 0x78, 0xc6, 0xa3, 0x7e, 0x3f, 0x52, 0x41, 0x39, 0x09, 0xfd, 0xa2, 0xd0, 0x2f, 0x0d, - 0x47, 0x19, 0xf3, 0xaf, 0xa1, 0xe6, 0x08, 0xa8, 0xff, 0x0f, 0x6f, 0xdf, 0xc2, 0xdd, 0xb6, 0x8d, 0xad, 0xfb, 0x57, - 0x2c, 0xde, 0x54, 0x25, 0x22, 0x48, 0x96, 0xdc, 0xa4, 0x33, 0xa5, 0x0c, 0xeb, 0xb8, 0x79, 0xb4, 0xe9, 0x34, 0x8f, - 0xc6, 0x69, 0xa7, 0x53, 0x5d, 0x1d, 0x97, 0x26, 0x61, 0x8b, 0x0d, 0x0d, 0xa8, 0x24, 0xe5, 0x47, 0x25, 0xfe, 0xf7, - 0xbb, 0xf6, 0xc6, 0x93, 0x14, 0xe5, 0x64, 0xe6, 0x9e, 0x7b, 0x57, 0xd6, 0x8a, 0x45, 0x10, 0xc4, 0x1b, 0x1b, 0x1b, - 0xfb, 0xf1, 0xed, 0x3b, 0x16, 0x9b, 0x70, 0x01, 0xb8, 0x9d, 0x13, 0xea, 0x8c, 0xf7, 0x58, 0x13, 0x98, 0xd3, 0x84, - 0xa0, 0x30, 0xd7, 0xc1, 0xc2, 0x00, 0xd0, 0xbb, 0xf6, 0x68, 0xcb, 0x49, 0x97, 0x60, 0xf1, 0xdc, 0xc0, 0xe2, 0xd5, - 0xc5, 0xa2, 0xba, 0xe6, 0x5a, 0x6e, 0x61, 0x53, 0xca, 0x2a, 0x86, 0x00, 0x02, 0xcd, 0x98, 0x61, 0x77, 0xdc, 0xe5, - 0x48, 0xd6, 0x45, 0xc1, 0xc5, 0x4e, 0x60, 0xe8, 0x66, 0x5c, 0x32, 0x73, 0x70, 0x35, 0xc3, 0x3a, 0xa9, 0x28, 0xc0, - 0xae, 0x2e, 0x40, 0xf6, 0xc2, 0x50, 0xd7, 0xcd, 0x6c, 0xb9, 0x0e, 0x7c, 0x5d, 0xba, 0xf0, 0x25, 0x05, 0x2f, 0x57, - 0x52, 0x94, 0xd9, 0x0d, 0xff, 0xd1, 0xbe, 0x6c, 0xc6, 0x92, 0x42, 0x3b, 0xd2, 0xd7, 0xed, 0xee, 0x68, 0x31, 0x8e, - 0x2d, 0xc7, 0xb7, 0x54, 0xba, 0xd7, 0xa3, 0xea, 0x85, 0xd0, 0xd6, 0xb9, 0x96, 0x59, 0x9a, 0x72, 0xf1, 0x4a, 0xa4, - 0x59, 0xe2, 0x25, 0xc7, 0x3a, 0x56, 0xb5, 0x0b, 0x82, 0xe5, 0xc2, 0x24, 0x3f, 0xcf, 0x4a, 0x8c, 0x1d, 0xdc, 0x68, - 0x54, 0x2b, 0xea, 0x94, 0x89, 0x81, 0x21, 0xdf, 0x63, 0xf0, 0x6d, 0x56, 0x26, 0xc0, 0xf0, 0x63, 0xa2, 0xbe, 0xa4, - 0xa7, 0x10, 0xf0, 0x41, 0x85, 0xe6, 0x7e, 0xce, 0x11, 0xfc, 0xda, 0xaa, 0xcc, 0x81, 0xc9, 0xd6, 0x2a, 0x48, 0xc4, - 0xbd, 0xcb, 0xe6, 0x7a, 0x11, 0x2d, 0xd4, 0x5d, 0xa8, 0x17, 0x6f, 0xb7, 0xbd, 0x44, 0xd1, 0x01, 0x27, 0x3f, 0x0d, - 0x5e, 0xc6, 0x59, 0xce, 0xd3, 0x83, 0x4a, 0x1e, 0xa8, 0x0d, 0x75, 0xa0, 0x9c, 0x39, 0x60, 0xe7, 0x7d, 0x59, 0x1d, - 0xe8, 0x35, 0x7d, 0xa0, 0xdb, 0x79, 0x00, 0x17, 0x0c, 0xdc, 0xb9, 0x57, 0xd9, 0x0d, 0x17, 0x07, 0xa0, 0x0c, 0xb4, - 0xc6, 0x03, 0x75, 0x59, 0x8d, 0xd4, 0xc4, 0xe8, 0x18, 0xd6, 0x89, 0x3e, 0x98, 0x03, 0xfa, 0x1d, 0x84, 0xb5, 0x6f, - 0xbd, 0x5d, 0xe9, 0x83, 0x36, 0xa0, 0x3f, 0x2e, 0x4d, 0x1f, 0x74, 0xe0, 0x78, 0x15, 0x1d, 0xb8, 0x31, 0xa4, 0x1a, - 0xb4, 0xd5, 0xc8, 0x2a, 0x50, 0xbc, 0xe1, 0x2d, 0xde, 0x9d, 0x6b, 0xc9, 0xc6, 0x7b, 0x89, 0x18, 0x5f, 0x99, 0xa8, - 0xe2, 0x4c, 0x9c, 0x7a, 0xa9, 0xbc, 0xd6, 0x4e, 0x32, 0xc2, 0xf8, 0x96, 0x95, 0xd4, 0xdf, 0x21, 0xe6, 0x16, 0x69, - 0x0e, 0x83, 0x17, 0x61, 0x45, 0x66, 0xbc, 0xdf, 0x97, 0x33, 0x19, 0x95, 0x33, 0x71, 0x58, 0x46, 0x0a, 0xac, 0x6d, - 0x9f, 0x08, 0xe8, 0x41, 0x09, 0x90, 0x2f, 0x00, 0xaa, 0x1e, 0x12, 0xfe, 0x3c, 0x24, 0xf5, 0xe9, 0x14, 0xfa, 0x14, - 0xda, 0x7a, 0xc5, 0x15, 0xc4, 0xab, 0xba, 0x31, 0xb2, 0x8d, 0x0a, 0x5a, 0x3c, 0x96, 0x67, 0xb5, 0x61, 0x6c, 0x4e, - 0xad, 0x7f, 0xbd, 0xd9, 0x60, 0xca, 0xe6, 0x42, 0xad, 0xc2, 0x90, 0x44, 0xb7, 0xa5, 0x17, 0x49, 0xc4, 0xc2, 0x66, - 0xb5, 0x36, 0xbf, 0x09, 0x03, 0x92, 0x89, 0x14, 0xf7, 0xb3, 0x25, 0xce, 0x5d, 0x3c, 0x9e, 0x57, 0x7d, 0xad, 0xa5, - 0x45, 0xa6, 0xcd, 0xf7, 0xfa, 0x32, 0xa4, 0xa9, 0xa8, 0x21, 0x8d, 0x3a, 0x33, 0xe8, 0xbe, 0x5d, 0xde, 0xb2, 0x1a, - 0x61, 0x02, 0xbc, 0xd2, 0x19, 0x74, 0xa3, 0xf1, 0x40, 0x2c, 0xab, 0x51, 0xb1, 0x16, 0x02, 0x81, 0x87, 0x21, 0xc7, - 0xcc, 0x12, 0x92, 0xec, 0x2f, 0xfe, 0xad, 0x8a, 0xb3, 0x50, 0xc4, 0xb7, 0x06, 0xd9, 0xbb, 0xb2, 0xae, 0xdd, 0x75, - 0xe4, 0xe7, 0xc4, 0xc2, 0x6a, 0xff, 0xa1, 0x79, 0xd4, 0x1a, 0x67, 0x01, 0x6d, 0x4d, 0xab, 0x1b, 0x0e, 0xf7, 0xa8, - 0x8e, 0x45, 0x69, 0xb0, 0x89, 0x3d, 0xb2, 0x5c, 0xb4, 0x8e, 0x19, 0x34, 0xa0, 0xbf, 0xcb, 0xae, 0xd7, 0xd7, 0x08, - 0xe0, 0x56, 0x22, 0xeb, 0x24, 0x95, 0x7f, 0x49, 0x7b, 0xd4, 0xb5, 0x3d, 0x95, 0xff, 0x6d, 0x9b, 0x2a, 0x87, 0x16, - 0x53, 0x1e, 0xbb, 0x39, 0x0b, 0x54, 0x47, 0x82, 0x28, 0x50, 0x5b, 0x2f, 0x98, 0x7a, 0xa7, 0x4c, 0xd1, 0x01, 0x02, - 0x5d, 0x98, 0x33, 0xec, 0x33, 0x8e, 0x18, 0xb3, 0x54, 0x62, 0x30, 0xf5, 0x31, 0x46, 0x35, 0xad, 0x15, 0xa0, 0xeb, - 0xa7, 0x1b, 0xf8, 0x13, 0x15, 0x35, 0x1a, 0x6a, 0x8d, 0xa4, 0x50, 0x34, 0x51, 0xa1, 0xc8, 0xd2, 0x42, 0xc7, 0x55, - 0xe8, 0x24, 0x12, 0x96, 0x80, 0x86, 0x09, 0xd1, 0x49, 0x05, 0xde, 0x1a, 0xc0, 0x99, 0x8f, 0x8b, 0x72, 0x5d, 0x68, - 0x83, 0xb9, 0xef, 0xe3, 0x1b, 0xfe, 0xea, 0xb9, 0x33, 0xaa, 0x6f, 0x59, 0xeb, 0x7b, 0x5a, 0x90, 0xef, 0x43, 0x4e, - 0xd1, 0x81, 0x89, 0x9d, 0x6c, 0xd0, 0x18, 0xa3, 0xac, 0x75, 0xd4, 0x8b, 0xb7, 0x3a, 0x14, 0x8b, 0x36, 0xc1, 0x7b, - 0xc0, 0x53, 0x44, 0x1b, 0x1e, 0x0a, 0x63, 0x55, 0x8d, 0x4f, 0x25, 0x6b, 0xe9, 0xc1, 0x0a, 0x9e, 0xae, 0x13, 0x1e, - 0x82, 0x1e, 0x89, 0xb0, 0x93, 0xb0, 0x98, 0xc7, 0x0b, 0x38, 0x4e, 0x0a, 0x02, 0x6a, 0x07, 0x7d, 0x05, 0x9f, 0x2f, - 0xd0, 0xfd, 0x55, 0xa2, 0x07, 0x18, 0x5a, 0x10, 0x37, 0xa3, 0xa0, 0x8e, 0xae, 0xe3, 0x55, 0x43, 0x45, 0xc2, 0xe7, - 0x05, 0xd8, 0x0e, 0x29, 0xf5, 0x14, 0x68, 0xa1, 0x12, 0xa5, 0x1f, 0x06, 0xbe, 0x43, 0x63, 0x60, 0x6b, 0x1d, 0xa0, - 0xa1, 0x9f, 0x31, 0x4d, 0xad, 0x33, 0x54, 0x3e, 0xf3, 0xee, 0x99, 0xd1, 0x72, 0x66, 0xd1, 0x18, 0xf4, 0x6d, 0x34, - 0x45, 0x71, 0x4e, 0x3e, 0x0b, 0x8a, 0x38, 0xcd, 0xe2, 0x1c, 0xfc, 0x36, 0xe3, 0x02, 0x33, 0x26, 0x71, 0xc5, 0xaf, - 0x64, 0x01, 0xda, 0xee, 0x5c, 0xa5, 0xd6, 0x35, 0x08, 0xc8, 0xbe, 0x07, 0xab, 0x97, 0x86, 0x8e, 0xca, 0x79, 0x77, - 0x69, 0x53, 0x88, 0x58, 0x84, 0x60, 0xd3, 0x4c, 0x97, 0xec, 0x34, 0x54, 0xda, 0x1c, 0x08, 0x75, 0x84, 0xc6, 0xfd, - 0xd3, 0x30, 0xb6, 0x9a, 0x62, 0x6b, 0xf7, 0xb6, 0xdd, 0xfe, 0x5a, 0x7a, 0xe9, 0x34, 0x27, 0x3d, 0xc6, 0x7e, 0x2d, - 0xc3, 0x62, 0x64, 0x3b, 0x42, 0x60, 0xc9, 0x79, 0x9f, 0xfa, 0xaf, 0x68, 0x39, 0x4f, 0xc0, 0x74, 0x44, 0x07, 0xcb, - 0x05, 0xca, 0x8e, 0x01, 0xdd, 0x81, 0xc1, 0x15, 0xfd, 0x3e, 0x58, 0x65, 0x98, 0x0b, 0xc9, 0x92, 0xa4, 0x0c, 0x9e, - 0xa7, 0x1e, 0x1c, 0xfc, 0x9a, 0x29, 0x73, 0x17, 0x65, 0x7d, 0xba, 0x24, 0xd3, 0x14, 0x19, 0x88, 0x75, 0xb8, 0xc9, - 0xd2, 0x28, 0x51, 0x22, 0xb2, 0x25, 0xfa, 0x47, 0x1a, 0x8a, 0xa5, 0x23, 0xf7, 0x22, 0x55, 0x22, 0x54, 0xcc, 0x53, - 0x3c, 0xa9, 0xd3, 0x3a, 0x1d, 0x61, 0xe8, 0x49, 0x50, 0xca, 0xd5, 0x30, 0x50, 0x25, 0xd5, 0x4b, 0x61, 0x53, 0x6c, - 0xb7, 0xfa, 0x62, 0x25, 0xe6, 0xf1, 0x02, 0x5f, 0x0a, 0x1c, 0xc5, 0x7f, 0x70, 0x2f, 0xec, 0x94, 0xda, 0x1e, 0xd4, - 0x8e, 0x28, 0xa1, 0xff, 0xe0, 0x70, 0x91, 0xf8, 0x56, 0xea, 0x10, 0x80, 0x68, 0x11, 0x72, 0xae, 0x0e, 0x52, 0xc3, - 0x0d, 0xed, 0x08, 0xff, 0x0d, 0xd7, 0x67, 0x9c, 0xd1, 0x9b, 0x6a, 0x46, 0x0d, 0xe5, 0xeb, 0x41, 0x1b, 0xa3, 0x3e, - 0x1b, 0x38, 0xac, 0x10, 0x85, 0x36, 0xec, 0xa4, 0x54, 0xa2, 0x85, 0xa1, 0x54, 0x7f, 0x09, 0x15, 0x27, 0xdc, 0x99, - 0x51, 0x96, 0x8c, 0x4f, 0xcb, 0x63, 0x31, 0x1d, 0x0c, 0x4a, 0x52, 0x19, 0x0b, 0x3d, 0xb8, 0x1e, 0x78, 0xfe, 0x3d, - 0x70, 0x0b, 0xf1, 0x90, 0x91, 0xc5, 0x90, 0x1b, 0x9c, 0xfc, 0x16, 0x27, 0x57, 0x8d, 0x4a, 0x15, 0xc7, 0x9a, 0xa8, - 0x16, 0xfc, 0xa3, 0x0c, 0x03, 0xf4, 0x49, 0x0a, 0xc0, 0x64, 0x30, 0xe5, 0x77, 0x20, 0x51, 0x3a, 0x57, 0x37, 0xa4, - 0x9f, 0x45, 0xc1, 0x2f, 0x79, 0xc1, 0x45, 0xe2, 0x0a, 0xb0, 0xbc, 0x83, 0xed, 0x75, 0x54, 0x51, 0x85, 0xc9, 0x6b, - 0x7a, 0x1c, 0x71, 0xe3, 0xfd, 0x67, 0x7a, 0x6c, 0x31, 0x5b, 0xad, 0x63, 0x83, 0xcf, 0x1c, 0x83, 0x0b, 0xba, 0x96, - 0xd8, 0x1a, 0xaa, 0x61, 0x45, 0x60, 0xe0, 0x02, 0x0e, 0xc2, 0x12, 0xc5, 0xb1, 0x95, 0xbc, 0x22, 0x0d, 0x29, 0xed, - 0x03, 0xc3, 0xd1, 0x26, 0x39, 0xbe, 0xcd, 0xb2, 0x9b, 0xc0, 0xf9, 0xa2, 0x73, 0xd2, 0x4c, 0x58, 0x1b, 0xbc, 0xcf, - 0x9b, 0xf3, 0x6b, 0xff, 0x90, 0x50, 0x15, 0xf7, 0x86, 0xb7, 0xe3, 0xde, 0x38, 0xe1, 0xd7, 0x5c, 0x2c, 0x74, 0xa8, - 0x16, 0x73, 0xc9, 0xf2, 0x5b, 0xeb, 0xdd, 0x92, 0xa4, 0x56, 0x40, 0xfb, 0x2c, 0x0b, 0x6a, 0x22, 0x00, 0xe4, 0x0f, - 0x7f, 0x81, 0xd0, 0x19, 0xfe, 0xf6, 0x18, 0x5c, 0x91, 0xc2, 0xbd, 0x43, 0x20, 0xac, 0xe9, 0xe6, 0x4e, 0x6d, 0xc0, - 0x17, 0xe3, 0xfe, 0x8c, 0xa9, 0xa7, 0xdf, 0x66, 0x72, 0x57, 0xd7, 0xed, 0x91, 0x65, 0xf8, 0x08, 0x57, 0x0a, 0xe0, - 0x66, 0xc2, 0x5f, 0x0c, 0x33, 0xa9, 0x3e, 0x01, 0x4c, 0x35, 0x1d, 0xdc, 0x27, 0x08, 0x0c, 0xa0, 0x12, 0x2d, 0x46, - 0x37, 0xca, 0x11, 0xcd, 0xc0, 0xad, 0xe9, 0x56, 0x18, 0x6f, 0x3d, 0x68, 0xa1, 0x67, 0x1a, 0x4e, 0xfc, 0x07, 0xcd, - 0xbc, 0x2a, 0x20, 0x80, 0x56, 0x46, 0xf0, 0xd6, 0xfa, 0x68, 0x8e, 0x10, 0x9f, 0xb0, 0x24, 0x9a, 0xb0, 0x78, 0xa6, - 0xf8, 0x31, 0xa1, 0x9b, 0xa6, 0xb6, 0xe9, 0x03, 0xd2, 0x5f, 0x5c, 0xb3, 0x7e, 0xca, 0xb2, 0xf6, 0xed, 0xa1, 0xe2, - 0xc5, 0xb4, 0x19, 0x07, 0x31, 0x51, 0xc5, 0xf8, 0x5f, 0x70, 0x5f, 0x6a, 0x05, 0x88, 0xcc, 0x5d, 0xf5, 0xf4, 0xfb, - 0xcd, 0x6c, 0x39, 0x10, 0x2a, 0xbf, 0x33, 0x48, 0xfa, 0x74, 0x68, 0x3f, 0xb0, 0x49, 0xd4, 0x16, 0x7a, 0xfe, 0xb8, - 0xd4, 0x4d, 0xbc, 0xbc, 0x36, 0x35, 0xa2, 0x15, 0x32, 0x54, 0xb6, 0x0e, 0x58, 0xdf, 0xdf, 0x87, 0xbb, 0x8b, 0x9a, - 0x86, 0x5a, 0xf7, 0xdc, 0xb5, 0x28, 0x38, 0xf1, 0x07, 0x18, 0x8b, 0x0b, 0x49, 0xad, 0xe3, 0x31, 0xe9, 0x47, 0x0b, - 0x99, 0xdc, 0xa8, 0xab, 0x93, 0x33, 0xc5, 0x3c, 0x81, 0x0b, 0x70, 0xd9, 0xf6, 0x57, 0x54, 0xea, 0x52, 0x6e, 0xaf, - 0x28, 0x4d, 0x0f, 0x69, 0x7b, 0x15, 0xe7, 0x6d, 0xc1, 0x05, 0xff, 0x4c, 0xc1, 0x85, 0x75, 0xb0, 0xee, 0xb8, 0x53, - 0xf6, 0x84, 0x27, 0xca, 0xb4, 0x36, 0xb8, 0xeb, 0x06, 0x63, 0x62, 0xec, 0x77, 0x97, 0x3c, 0xf9, 0x88, 0x2c, 0xf8, - 0xb7, 0x99, 0x00, 0xcf, 0x64, 0xf7, 0x4a, 0xe5, 0xff, 0xde, 0xbf, 0xda, 0xda, 0x77, 0xd6, 0xfc, 0xd3, 0xb3, 0x1e, - 0xee, 0x1c, 0x26, 0x3f, 0x56, 0x67, 0x40, 0x37, 0xd7, 0x32, 0xe5, 0x80, 0x0c, 0x60, 0x2d, 0x92, 0xd1, 0x80, 0x0f, - 0xad, 0x2c, 0xdb, 0xbe, 0xd3, 0xea, 0x82, 0xb0, 0x97, 0xc0, 0x4d, 0xf7, 0xd7, 0x66, 0x66, 0x4e, 0xd7, 0x4a, 0x34, - 0x5d, 0x1a, 0x5b, 0xcb, 0x52, 0x85, 0xf1, 0xbe, 0xf7, 0x24, 0x9b, 0xe6, 0xc7, 0xcb, 0x69, 0x6e, 0xa9, 0xdb, 0xc6, - 0x2d, 0x1b, 0x40, 0x43, 0xec, 0x5a, 0x5b, 0x39, 0xe0, 0xe5, 0xf6, 0x20, 0x9a, 0xaf, 0x15, 0xa1, 0xa7, 0x4a, 0x84, - 0x3e, 0x4d, 0x9b, 0x7d, 0xb0, 0xab, 0x6a, 0xdd, 0x08, 0x79, 0x34, 0x48, 0x35, 0x23, 0xff, 0xf6, 0x86, 0x17, 0x97, - 0xb9, 0xbc, 0x05, 0x38, 0x64, 0x52, 0x1b, 0x85, 0xe5, 0x35, 0xb8, 0xf3, 0xa3, 0xe3, 0x38, 0x13, 0xa3, 0x1c, 0xe3, - 0xb6, 0x22, 0x52, 0xb2, 0x4e, 0x9c, 0x01, 0x1e, 0xb2, 0x3f, 0x69, 0x3a, 0xb4, 0x6b, 0x81, 0xe1, 0x7d, 0x81, 0xbb, - 0xca, 0xd9, 0xc9, 0x26, 0xb7, 0x8b, 0xbe, 0x39, 0xc3, 0xba, 0x23, 0xa5, 0xb5, 0xb1, 0xe8, 0xba, 0x83, 0xb5, 0x66, - 0xd0, 0x16, 0xa1, 0xe4, 0x43, 0xee, 0xa4, 0xfd, 0x2b, 0xa0, 0xc1, 0x79, 0x96, 0xde, 0x59, 0xab, 0xfc, 0x8d, 0x16, - 0xe2, 0x44, 0x31, 0x75, 0xe2, 0x9b, 0x28, 0xd1, 0xe7, 0x67, 0x62, 0xdc, 0x40, 0x20, 0xf5, 0x7b, 0x8c, 0xaf, 0x51, - 0x84, 0x09, 0x5c, 0x07, 0xa2, 0xd8, 0x9e, 0xa8, 0x8d, 0xe5, 0x08, 0x3a, 0x21, 0xc4, 0x3b, 0x28, 0xc3, 0x58, 0x5d, - 0x1c, 0x68, 0x83, 0xa5, 0xaf, 0x5b, 0xeb, 0xdc, 0x10, 0x0a, 0xe3, 0x04, 0xa6, 0x18, 0x24, 0x75, 0xd6, 0x59, 0x26, - 0xa8, 0xb2, 0x63, 0xd2, 0x79, 0x1f, 0xa0, 0xbb, 0x6b, 0xd1, 0x14, 0x5f, 0x77, 0xee, 0xa0, 0x7d, 0x5c, 0xbf, 0xd6, - 0x22, 0x37, 0xf8, 0xf3, 0x96, 0x08, 0x8b, 0xc0, 0x59, 0x6b, 0xf2, 0x55, 0x23, 0x1c, 0x98, 0x92, 0x4c, 0xc3, 0x5e, - 0xa2, 0x6c, 0xba, 0xb7, 0xdb, 0x5e, 0x6f, 0xaf, 0x88, 0xab, 0xc7, 0x58, 0xe5, 0xdd, 0xcc, 0xed, 0x9d, 0x6a, 0x2d, - 0x76, 0x6f, 0xda, 0x7e, 0x8a, 0x1d, 0xb5, 0xd6, 0x6e, 0x37, 0x9c, 0x50, 0x43, 0xbe, 0x15, 0x55, 0x5a, 0x9d, 0x6e, - 0x0c, 0xda, 0x21, 0xb4, 0xb5, 0xc8, 0xe0, 0x46, 0xf9, 0xdc, 0x09, 0x9d, 0x54, 0xc8, 0x55, 0xa7, 0x2e, 0xd8, 0x5c, - 0xf3, 0x6a, 0x29, 0xd3, 0x48, 0x50, 0xb4, 0x39, 0x8f, 0x4a, 0x9a, 0xc8, 0xb5, 0xa8, 0x22, 0x59, 0xa3, 0x5e, 0xd4, - 0x6a, 0x0c, 0x10, 0x90, 0xe9, 0xbc, 0xe9, 0x41, 0x15, 0xcc, 0x86, 0x32, 0x92, 0xd3, 0xf7, 0x60, 0x69, 0x8f, 0x1c, - 0x6b, 0xbd, 0xaf, 0xce, 0x16, 0xdf, 0xea, 0x09, 0xc1, 0x14, 0x66, 0x0f, 0x44, 0x84, 0x6b, 0x1a, 0x43, 0x4e, 0xbb, - 0xc4, 0x65, 0x4d, 0xb7, 0x84, 0x3d, 0xdc, 0xae, 0x64, 0x27, 0x6e, 0x9e, 0x34, 0x37, 0x57, 0xb0, 0x93, 0x62, 0x3e, - 0x06, 0xed, 0x97, 0x54, 0xd7, 0x2e, 0xcd, 0xad, 0xc7, 0x83, 0x80, 0x06, 0x83, 0xc2, 0xf0, 0xaf, 0x13, 0xe3, 0xe1, - 0x49, 0x03, 0x82, 0xa4, 0x5c, 0x84, 0x63, 0xdf, 0x88, 0x7e, 0x32, 0x95, 0xc7, 0x1c, 0x2d, 0xde, 0xa1, 0xd5, 0x09, - 0x04, 0xf4, 0x12, 0xa1, 0x24, 0x46, 0x55, 0x68, 0x44, 0x50, 0x9e, 0x96, 0xbf, 0x54, 0xd5, 0x21, 0xa0, 0x90, 0xf6, - 0x15, 0x85, 0xb2, 0x4d, 0x62, 0x68, 0x86, 0x5f, 0xce, 0x27, 0x0b, 0x3d, 0x03, 0x03, 0x39, 0x3f, 0x5a, 0xe8, 0x59, - 0x18, 0xc8, 0xf9, 0x57, 0x8b, 0xda, 0xad, 0x03, 0x4d, 0x40, 0x3c, 0x17, 0x8e, 0x4e, 0x4a, 0xab, 0xb2, 0x05, 0x74, - 0xf3, 0x10, 0x41, 0xff, 0x87, 0x3d, 0x04, 0x9d, 0x5c, 0x68, 0x47, 0x6e, 0x40, 0xdb, 0x21, 0x09, 0xec, 0x15, 0x93, - 0x0a, 0x13, 0x8b, 0xe8, 0x98, 0x8d, 0xc1, 0x10, 0x5b, 0x7d, 0x70, 0xcc, 0xc6, 0x53, 0x9f, 0x04, 0x01, 0xa3, 0xfb, - 0xbd, 0x01, 0x07, 0xbf, 0xc3, 0xab, 0xf4, 0xc9, 0x46, 0xa0, 0x9b, 0xbe, 0xbb, 0x1b, 0x7a, 0x17, 0x57, 0x70, 0xaa, - 0x76, 0xf7, 0x24, 0x74, 0x93, 0x69, 0xc7, 0xea, 0x35, 0xc4, 0x0d, 0xf9, 0x95, 0xd1, 0x68, 0x64, 0x53, 0x42, 0x42, - 0x0c, 0xe7, 0xd0, 0xcc, 0x69, 0xb9, 0x7c, 0x75, 0xeb, 0xd9, 0x80, 0x0c, 0x33, 0xbd, 0x63, 0xb2, 0x7e, 0x80, 0xb2, - 0xea, 0x31, 0xb4, 0x43, 0xef, 0x91, 0xe3, 0x87, 0x07, 0xdf, 0x64, 0xfc, 0xc4, 0xe1, 0xda, 0xc3, 0xb9, 0xf0, 0x5d, - 0xd6, 0x8c, 0xcc, 0xa1, 0xf3, 0xec, 0xe3, 0x78, 0x0f, 0xe3, 0xe4, 0xd3, 0x2c, 0x94, 0x37, 0x5e, 0xd3, 0xff, 0xa8, - 0xf4, 0x66, 0x87, 0x43, 0x4e, 0x57, 0xb0, 0xe2, 0x66, 0x55, 0x68, 0xf8, 0x59, 0xe4, 0x8d, 0x23, 0x5e, 0x93, 0xa8, - 0xea, 0x3e, 0xef, 0x6d, 0xc4, 0xd2, 0x8e, 0x71, 0x00, 0x70, 0xa2, 0x56, 0x0d, 0xbb, 0xd2, 0xb8, 0x56, 0x07, 0x31, - 0x22, 0x25, 0x6c, 0x95, 0x38, 0x12, 0xca, 0xdf, 0x00, 0x84, 0xc5, 0x50, 0x1c, 0x6f, 0x0d, 0xeb, 0x03, 0xec, 0x87, - 0x2e, 0xd0, 0x34, 0xa7, 0x54, 0x33, 0x00, 0x48, 0x02, 0xfe, 0xe8, 0xe9, 0xa6, 0xa1, 0xb2, 0xcd, 0xf3, 0xd0, 0xb2, - 0xba, 0x82, 0x07, 0x7a, 0xea, 0x4a, 0x06, 0xc6, 0x55, 0x1d, 0x7b, 0x9b, 0xfd, 0xed, 0xd1, 0x2a, 0xf2, 0x9d, 0x4d, - 0x6a, 0x9a, 0x05, 0x90, 0xa2, 0x71, 0xe9, 0x0b, 0x3d, 0x9d, 0x00, 0xad, 0xd7, 0x96, 0x8a, 0xf6, 0xfb, 0x28, 0x46, - 0x8d, 0x0b, 0x05, 0x56, 0x61, 0x82, 0xc2, 0x21, 0xc2, 0x08, 0xa1, 0xdf, 0x95, 0xe1, 0xc6, 0x17, 0x64, 0x10, 0x0d, - 0xd7, 0xa2, 0x43, 0x11, 0x39, 0x5e, 0xb4, 0x2d, 0x55, 0x35, 0x27, 0x4d, 0x5b, 0x02, 0x6f, 0x22, 0x03, 0xb6, 0xf3, - 0x4f, 0x1b, 0x22, 0x57, 0xe1, 0x02, 0x86, 0xef, 0x88, 0x6b, 0x41, 0x74, 0x53, 0x9b, 0x7a, 0x1b, 0x76, 0x88, 0x8e, - 0xa6, 0x78, 0x74, 0xc8, 0x3d, 0x77, 0xcf, 0x6d, 0x11, 0xdf, 0x7e, 0x82, 0xdc, 0x35, 0x9d, 0xbd, 0x14, 0x61, 0x50, - 0xb7, 0x6c, 0xa0, 0x58, 0xc7, 0x4e, 0x50, 0x80, 0x01, 0x5c, 0xfe, 0x02, 0x3a, 0x36, 0x18, 0x54, 0x04, 0x9f, 0x14, - 0xb6, 0x4d, 0x83, 0xfc, 0x11, 0xef, 0x86, 0x0e, 0xaf, 0x2d, 0x79, 0x20, 0x5e, 0x61, 0x9f, 0x28, 0x61, 0xff, 0x82, - 0x82, 0xee, 0x28, 0x2f, 0x57, 0x85, 0xab, 0xd2, 0x00, 0x54, 0xd9, 0xf1, 0x5c, 0x6b, 0x4a, 0x5a, 0xc0, 0x4a, 0x49, - 0xdd, 0xf9, 0x4d, 0x70, 0xdc, 0x92, 0xa9, 0xf0, 0xad, 0xba, 0x51, 0xe5, 0xb1, 0x44, 0x91, 0x8e, 0x3d, 0xdb, 0x39, - 0x58, 0x03, 0xe0, 0x29, 0x6c, 0x2f, 0xce, 0x04, 0x7c, 0xee, 0xb4, 0xcb, 0x96, 0xb9, 0x04, 0x8a, 0xfa, 0x61, 0x9c, - 0x97, 0x1d, 0x5f, 0xee, 0x8e, 0xb6, 0xf7, 0xd0, 0x1b, 0xb1, 0x31, 0x5e, 0x9f, 0x47, 0x4d, 0x3f, 0x7b, 0x86, 0x2b, - 0x4b, 0x41, 0x1e, 0x68, 0xaa, 0x47, 0x18, 0x1d, 0x02, 0xd3, 0x94, 0x9f, 0xb0, 0xf1, 0x74, 0x38, 0x34, 0x64, 0xd0, - 0x6b, 0x26, 0x86, 0x02, 0xfb, 0x0c, 0x5a, 0x67, 0x26, 0xae, 0xf1, 0x69, 0xfb, 0x0a, 0x5a, 0xdd, 0xa1, 0x4c, 0xee, - 0x1c, 0x0c, 0x1f, 0x68, 0xc9, 0x14, 0x4c, 0x15, 0xde, 0x10, 0xa9, 0x64, 0x6f, 0x96, 0xd6, 0x61, 0xdf, 0x2e, 0x14, - 0x5a, 0x68, 0xe2, 0x57, 0x19, 0xe2, 0xa7, 0xae, 0x33, 0xff, 0x36, 0xed, 0x53, 0x83, 0x58, 0x38, 0x12, 0x83, 0x88, - 0x5f, 0x9c, 0x2a, 0xdb, 0x09, 0xa1, 0x62, 0xe3, 0xa1, 0x6b, 0xdd, 0x38, 0x92, 0x2a, 0x0c, 0xa5, 0xd0, 0x78, 0x6a, - 0xb8, 0xef, 0x85, 0x0e, 0x5f, 0x87, 0x59, 0xdc, 0x66, 0x8d, 0xa4, 0xc6, 0x38, 0x15, 0x26, 0x4e, 0xa5, 0x5c, 0x45, - 0x02, 0x03, 0xe5, 0xd9, 0xc2, 0x20, 0xc0, 0x24, 0x26, 0x19, 0x5b, 0x0b, 0x61, 0xc2, 0xd8, 0xb9, 0xc2, 0x34, 0x75, - 0x91, 0xfa, 0xcd, 0xc0, 0x64, 0x41, 0x43, 0x7e, 0x8f, 0x46, 0x6b, 0xaa, 0xa6, 0x00, 0xc3, 0x38, 0x4a, 0x35, 0xfe, - 0x2d, 0x42, 0x6d, 0x86, 0x01, 0x80, 0x6d, 0xde, 0xc9, 0x4c, 0x54, 0xaf, 0x04, 0x42, 0xa0, 0x39, 0xfb, 0xa9, 0xb8, - 0xda, 0x99, 0x05, 0xa3, 0x68, 0xb7, 0x57, 0x3e, 0x1f, 0x38, 0xa1, 0x3c, 0x55, 0x17, 0xa8, 0x97, 0xb2, 0x78, 0x2d, - 0x53, 0xde, 0x0a, 0x91, 0x79, 0x20, 0xd9, 0x87, 0x7c, 0x04, 0xe7, 0x15, 0x3a, 0x95, 0x9b, 0x6d, 0xa2, 0xcc, 0x92, - 0x24, 0x63, 0x81, 0xb1, 0x79, 0x09, 0x66, 0x52, 0x33, 0x63, 0xf8, 0x35, 0xc4, 0x19, 0xdb, 0x39, 0x09, 0x37, 0xfb, - 0x79, 0x60, 0x88, 0x52, 0x2e, 0x5a, 0xa2, 0x61, 0x6b, 0xc7, 0xeb, 0xc9, 0x35, 0xe1, 0x3e, 0x6c, 0xc4, 0x9a, 0x8c, - 0x31, 0xae, 0xcd, 0x8d, 0xac, 0x1f, 0x2d, 0xf0, 0x60, 0x4c, 0x59, 0x7f, 0x02, 0x99, 0x56, 0x52, 0xd6, 0xf9, 0xc2, - 0x88, 0x99, 0x54, 0xa2, 0x77, 0xfb, 0xc6, 0x67, 0x75, 0x17, 0x51, 0xbf, 0xb5, 0xdf, 0x93, 0x7a, 0xb8, 0xf7, 0x1f, - 0x14, 0xd6, 0xa0, 0x32, 0xe2, 0x32, 0xa2, 0x3c, 0x73, 0xa0, 0x9b, 0x26, 0x45, 0x9c, 0x9e, 0xaf, 0xe2, 0xa2, 0xe4, - 0x29, 0x54, 0xaa, 0xa9, 0x5b, 0xd4, 0x9b, 0x80, 0xbd, 0x21, 0x92, 0x24, 0x6b, 0x69, 0x6c, 0xc5, 0x2e, 0x0d, 0xd2, - 0xb3, 0x37, 0xe2, 0xd2, 0xcb, 0x0a, 0x0d, 0x69, 0xa9, 0x77, 0x16, 0x2a, 0x99, 0xbf, 0xe2, 0x3f, 0x83, 0x5a, 0x81, - 0x8e, 0x36, 0x29, 0xc6, 0x33, 0x60, 0xc4, 0x77, 0x83, 0x59, 0x3d, 0x40, 0x5c, 0x34, 0x41, 0xa9, 0x77, 0xc4, 0x8e, - 0x9f, 0x9a, 0x3c, 0xbc, 0x0b, 0x39, 0x67, 0xf0, 0xe9, 0xc3, 0x2c, 0x51, 0x6b, 0x1d, 0x89, 0x91, 0x9a, 0x01, 0x34, - 0x1d, 0x94, 0x39, 0x8f, 0x45, 0x30, 0xeb, 0x99, 0xc4, 0xa8, 0xc7, 0xf5, 0x2f, 0xd0, 0x50, 0xfb, 0xcd, 0xca, 0xf2, - 0xac, 0xba, 0xff, 0x1c, 0x0e, 0x6c, 0x6a, 0x2b, 0xe8, 0xf1, 0xba, 0x92, 0x57, 0x57, 0xaa, 0xdb, 0x7e, 0x21, 0x46, - 0x4e, 0xd7, 0xb8, 0x96, 0xce, 0xab, 0x05, 0xeb, 0x75, 0xa7, 0x9b, 0xc5, 0xdd, 0x2c, 0xa3, 0x81, 0xb0, 0xb6, 0xf3, - 0x89, 0xe6, 0xcf, 0x9a, 0x6d, 0xf7, 0xf1, 0x16, 0xc4, 0x2c, 0x00, 0x88, 0xf4, 0x20, 0x0a, 0x96, 0x59, 0xca, 0x03, - 0x2a, 0xf7, 0x71, 0x94, 0x85, 0xd2, 0xcb, 0x59, 0xc6, 0x4f, 0x9b, 0xc6, 0x5a, 0x67, 0x85, 0x32, 0xb4, 0x36, 0xba, - 0xd3, 0x55, 0x86, 0xd8, 0x7e, 0x12, 0x67, 0x0b, 0x70, 0x7f, 0xcc, 0x50, 0x68, 0xe8, 0x2c, 0x23, 0x4d, 0x34, 0x7c, - 0xd7, 0x9e, 0x41, 0x46, 0x71, 0xb2, 0xce, 0x2b, 0xe9, 0x46, 0x9f, 0xb5, 0x91, 0x30, 0xf7, 0x10, 0xfd, 0x2a, 0x06, - 0x8f, 0x72, 0x9f, 0xd7, 0x46, 0x27, 0xd3, 0x32, 0xd2, 0xee, 0xfc, 0xa4, 0x5e, 0x66, 0xa9, 0xd6, 0x61, 0xfb, 0x0c, - 0x7b, 0x6b, 0x4c, 0x7a, 0x13, 0x52, 0xc3, 0x48, 0x7c, 0x3a, 0xa3, 0x46, 0x08, 0x68, 0xcb, 0xf1, 0x77, 0xf8, 0x0c, - 0x43, 0x53, 0x60, 0xa9, 0xe2, 0x16, 0x76, 0xc3, 0xd7, 0x7c, 0xb2, 0x6a, 0x01, 0x08, 0x66, 0xe5, 0xeb, 0x5d, 0xbc, - 0x12, 0xea, 0x73, 0x6d, 0x06, 0x80, 0x2c, 0x28, 0xe5, 0x8e, 0x9f, 0x52, 0xe9, 0x60, 0x89, 0xa2, 0xed, 0xe5, 0xf4, - 0x8d, 0x8e, 0x8d, 0x1f, 0xd2, 0x73, 0x01, 0xdb, 0x85, 0xfc, 0xd6, 0x5e, 0xbd, 0x44, 0x45, 0x6a, 0xdb, 0xac, 0x07, - 0xf8, 0x72, 0x83, 0x26, 0x61, 0x04, 0x65, 0xca, 0x14, 0xc0, 0xe0, 0xa6, 0x1a, 0x05, 0x93, 0x56, 0x23, 0x61, 0x4b, - 0x3d, 0xc9, 0x72, 0xd3, 0x07, 0xa7, 0xda, 0x23, 0xe8, 0xd1, 0x0e, 0x27, 0x2d, 0xfb, 0xb5, 0x82, 0xa3, 0x93, 0xab, - 0x21, 0x6a, 0xe6, 0xbd, 0xb6, 0x23, 0x43, 0xca, 0x65, 0x18, 0x08, 0xa6, 0x1c, 0xf3, 0xf4, 0xd8, 0x7a, 0x46, 0x44, - 0x0f, 0x9c, 0x7d, 0xa6, 0x5b, 0x75, 0x25, 0x01, 0xd1, 0xf1, 0xeb, 0x27, 0xaf, 0xae, 0xe3, 0x2b, 0x83, 0xa2, 0xd4, - 0xb0, 0x88, 0x51, 0xa6, 0x7d, 0x95, 0x84, 0xc1, 0xfb, 0xf9, 0xfd, 0x8f, 0x2a, 0x4b, 0xed, 0xf7, 0x60, 0x63, 0x45, - 0x55, 0x3f, 0x97, 0xbc, 0x68, 0x0a, 0xb0, 0xf6, 0x59, 0xa2, 0x40, 0xee, 0xf7, 0x36, 0xcd, 0x7c, 0x13, 0x35, 0x6e, - 0x36, 0xac, 0x37, 0xae, 0xdb, 0xa5, 0xb6, 0x64, 0x47, 0x56, 0x22, 0x67, 0x16, 0x83, 0x19, 0x3f, 0x2a, 0x0c, 0x4a, - 0xc3, 0x06, 0x55, 0xa9, 0xf8, 0xbd, 0x11, 0xc1, 0xa9, 0x63, 0x55, 0x61, 0x4c, 0x03, 0x66, 0x5b, 0x51, 0x6b, 0x50, - 0x07, 0xa5, 0xb4, 0x35, 0x01, 0xd9, 0x7e, 0x65, 0x05, 0x35, 0xbf, 0xff, 0x65, 0x0c, 0xf9, 0x9a, 0x52, 0x50, 0x49, - 0xc0, 0xce, 0xa0, 0xd1, 0x53, 0x25, 0x0c, 0xa4, 0x20, 0x78, 0x02, 0x94, 0x2f, 0xa2, 0xc6, 0x6a, 0xb7, 0xaf, 0x4e, - 0x8d, 0xd1, 0x16, 0x10, 0x5a, 0x48, 0x8f, 0x2e, 0xfb, 0xb8, 0x8d, 0x75, 0x20, 0xf1, 0xe0, 0x04, 0xdb, 0xb9, 0xba, - 0x46, 0x23, 0xa1, 0xf9, 0x43, 0xa3, 0x01, 0xaf, 0x69, 0x05, 0x0a, 0xf5, 0x1c, 0x47, 0x43, 0x67, 0x87, 0x14, 0x44, - 0x6c, 0xd0, 0xc2, 0xbe, 0x3d, 0x1f, 0x9a, 0x7d, 0x3d, 0x4f, 0x16, 0xa4, 0xa6, 0xd2, 0x7d, 0xee, 0x96, 0x90, 0xb5, - 0xea, 0x50, 0x56, 0x1e, 0xe0, 0x78, 0xa1, 0x64, 0xfe, 0x0e, 0x93, 0x1a, 0xa5, 0x31, 0xa1, 0x31, 0x62, 0x01, 0x4b, - 0x82, 0xf6, 0x7a, 0xa0, 0x7e, 0x19, 0x84, 0x0a, 0x67, 0x7a, 0x22, 0xf1, 0x29, 0xe5, 0xea, 0xd3, 0x82, 0xd4, 0xd3, - 0x82, 0x39, 0xd0, 0x4b, 0xdf, 0xca, 0xaf, 0x6c, 0x7c, 0xb4, 0xbb, 0x77, 0xcd, 0x85, 0x75, 0x0c, 0x71, 0xb1, 0x85, - 0xdf, 0x9c, 0x9a, 0x02, 0xb0, 0xe1, 0xa9, 0x2e, 0xcb, 0x37, 0x6a, 0x22, 0xb3, 0x38, 0x24, 0x11, 0x48, 0xb6, 0x9b, - 0x9b, 0xdb, 0x08, 0xb6, 0xbd, 0x85, 0xda, 0x50, 0x7f, 0x79, 0xdb, 0x7d, 0xcf, 0xf0, 0x72, 0x4f, 0xee, 0xdd, 0xb4, - 0xa1, 0xfc, 0x7e, 0xff, 0x2a, 0xf9, 0xbf, 0xaa, 0x64, 0xbf, 0x55, 0x66, 0xdd, 0x16, 0xef, 0x77, 0x1d, 0xb7, 0x1c, - 0xa3, 0x41, 0x60, 0x4d, 0x81, 0x81, 0xf4, 0xa4, 0x31, 0x4d, 0x74, 0x74, 0x65, 0xc6, 0x0c, 0x1e, 0x5d, 0x80, 0xe6, - 0x30, 0x9d, 0xe7, 0x31, 0x00, 0x07, 0xf8, 0x47, 0x1e, 0xa1, 0xfe, 0xe9, 0x3c, 0x0f, 0xce, 0x83, 0x41, 0x39, 0x08, - 0xf4, 0x27, 0xae, 0x39, 0xc1, 0x02, 0x74, 0x6e, 0x31, 0x83, 0xb8, 0x93, 0xd6, 0xcc, 0x21, 0x3e, 0x4e, 0xa6, 0x83, - 0x41, 0x4c, 0x36, 0x00, 0xd2, 0x17, 0x2f, 0xac, 0x73, 0x50, 0xa1, 0x17, 0x64, 0xab, 0xee, 0xa2, 0x59, 0xb1, 0x57, - 0xed, 0x34, 0xef, 0xf7, 0xf3, 0x79, 0x39, 0x08, 0x1a, 0x15, 0x16, 0xc6, 0xfb, 0x8f, 0x36, 0xbf, 0x34, 0x3a, 0x69, - 0x82, 0x11, 0x6b, 0x4f, 0x51, 0xbd, 0xe2, 0x69, 0x46, 0x1b, 0xb7, 0x63, 0xa5, 0x7c, 0x01, 0x51, 0x3c, 0x30, 0x64, - 0xad, 0xbc, 0x3b, 0x07, 0xaf, 0xcb, 0x8d, 0x37, 0x47, 0x14, 0x60, 0x37, 0x85, 0x71, 0x52, 0x73, 0xd1, 0x45, 0x4d, - 0x3c, 0x83, 0x9d, 0xae, 0xde, 0x4a, 0xb4, 0x1a, 0xef, 0xc5, 0xbb, 0x66, 0xe3, 0x6f, 0xe4, 0x81, 0x2e, 0xf3, 0xe0, - 0x12, 0x10, 0x67, 0x0f, 0xe2, 0xea, 0x00, 0x4b, 0x3d, 0x08, 0x06, 0x16, 0x39, 0xa4, 0x5d, 0xad, 0x1e, 0x8a, 0x48, - 0x9d, 0xc7, 0x60, 0xc0, 0x64, 0x1a, 0x52, 0x93, 0x69, 0xaf, 0x50, 0x90, 0x36, 0xd6, 0x5a, 0x40, 0x1b, 0x0e, 0x8b, - 0x1d, 0xbb, 0x61, 0x77, 0xba, 0x75, 0x28, 0x94, 0x30, 0x90, 0x75, 0xdd, 0x3c, 0xd4, 0x1a, 0x9e, 0x08, 0x7a, 0x50, - 0x8d, 0xf6, 0xd3, 0x43, 0x79, 0xd2, 0x1e, 0x0b, 0x70, 0xd1, 0xc3, 0x97, 0x2f, 0x04, 0x5e, 0xb4, 0x77, 0x90, 0xe7, - 0xcc, 0xa7, 0xca, 0x07, 0xb1, 0xe1, 0x96, 0xe1, 0x43, 0xfb, 0xf8, 0x56, 0x20, 0x93, 0xba, 0xa3, 0xa9, 0xad, 0xdd, - 0xd1, 0x38, 0x26, 0xd0, 0x6f, 0xca, 0x51, 0xca, 0xc4, 0xd4, 0xb2, 0x64, 0x27, 0xbd, 0x5c, 0x79, 0x43, 0xa5, 0xec, - 0x64, 0xd9, 0xe6, 0xfc, 0xd2, 0x46, 0x42, 0xbf, 0xaf, 0xdd, 0x81, 0xf0, 0x8d, 0x5a, 0x6f, 0xc8, 0xcb, 0x86, 0x88, - 0xe5, 0x10, 0x33, 0x70, 0xbc, 0x90, 0xca, 0xb5, 0xbb, 0x68, 0xaa, 0xea, 0x76, 0xb6, 0x72, 0x41, 0x4b, 0xbc, 0x95, - 0x02, 0xab, 0x48, 0x9d, 0x5e, 0x4f, 0x25, 0xee, 0xfb, 0x28, 0xb6, 0x1f, 0x01, 0xdb, 0xd8, 0x38, 0x1a, 0x1b, 0xb7, - 0x88, 0x0d, 0xbe, 0x8a, 0x2a, 0x5a, 0x70, 0x80, 0xe0, 0x6e, 0x4b, 0x6a, 0x69, 0xe6, 0x10, 0xf7, 0x15, 0x0f, 0xd0, - 0xbe, 0x8b, 0x23, 0x4e, 0x05, 0xd8, 0xd6, 0xb5, 0xce, 0x59, 0x2d, 0x07, 0x6c, 0x26, 0x7a, 0xfe, 0x69, 0xd5, 0x48, - 0xc4, 0xb0, 0xca, 0x46, 0xca, 0x0a, 0xed, 0x41, 0xe9, 0x12, 0x2e, 0xbe, 0x00, 0x2f, 0xdb, 0xfb, 0x95, 0xdd, 0xe7, - 0x4b, 0xec, 0x1f, 0xe6, 0x55, 0x13, 0x3c, 0xf2, 0x1a, 0x6f, 0xef, 0x61, 0xe2, 0x73, 0xa5, 0x10, 0x5e, 0xa5, 0x34, - 0x94, 0x00, 0x0c, 0x92, 0xa0, 0x86, 0x2b, 0x6d, 0x9b, 0x41, 0x2a, 0x63, 0xd8, 0xdd, 0xea, 0xad, 0xfe, 0x4f, 0xab, - 0x70, 0x51, 0xc9, 0x62, 0x4c, 0x02, 0x9d, 0x53, 0x2d, 0x37, 0x81, 0x05, 0xcf, 0x77, 0xc9, 0x11, 0x28, 0xec, 0x04, - 0x70, 0x43, 0x09, 0xfb, 0x19, 0x6f, 0x43, 0x39, 0x7b, 0x69, 0x25, 0x4f, 0x6e, 0x5f, 0x52, 0x41, 0x13, 0x32, 0x15, - 0x76, 0xff, 0xb6, 0x36, 0xec, 0xf3, 0x50, 0x8e, 0xa4, 0xc0, 0xc5, 0x41, 0xe7, 0x00, 0xf6, 0x07, 0xb9, 0x8c, 0xcd, - 0x67, 0xd2, 0xef, 0xab, 0xf7, 0xcf, 0xf2, 0x2c, 0xf9, 0xb8, 0xf3, 0xde, 0xf0, 0x34, 0x4b, 0x06, 0x54, 0x22, 0xa6, - 0xd6, 0x55, 0x31, 0x5c, 0x6a, 0x17, 0xe3, 0x06, 0xc9, 0x88, 0xf7, 0x52, 0x87, 0x18, 0x31, 0xbe, 0xc8, 0x0e, 0x49, - 0xc9, 0xe9, 0xb2, 0xee, 0xec, 0xb9, 0x16, 0xcd, 0xa0, 0x31, 0xdc, 0x8e, 0xf7, 0x92, 0x5e, 0x01, 0x2a, 0x40, 0x74, - 0xcf, 0x02, 0xd7, 0xf0, 0xe6, 0x92, 0x68, 0x6c, 0xe9, 0x69, 0x4b, 0x34, 0xb0, 0x57, 0x26, 0x24, 0xd5, 0xc6, 0x01, - 0x16, 0xb1, 0xae, 0x3f, 0x86, 0x05, 0x00, 0xb5, 0x1a, 0xa4, 0x57, 0xfa, 0x92, 0x50, 0x95, 0x84, 0x60, 0x74, 0x22, - 0xe1, 0x65, 0x40, 0xe3, 0xcc, 0x24, 0x5a, 0xd8, 0xe0, 0x80, 0x3e, 0xaf, 0x4c, 0xa2, 0xb1, 0x21, 0x0f, 0x28, 0xb7, - 0x69, 0x00, 0x83, 0x0f, 0x92, 0x24, 0xfa, 0x6a, 0x69, 0x92, 0x40, 0x50, 0x82, 0xf2, 0x0d, 0xfa, 0x53, 0xe9, 0xf9, - 0x58, 0xfe, 0xe6, 0x1d, 0x4a, 0xdf, 0x87, 0x05, 0xc8, 0x14, 0x75, 0xc5, 0x34, 0x63, 0x27, 0x59, 0xb7, 0x31, 0x89, - 0xe7, 0x69, 0x77, 0x57, 0x28, 0x97, 0x2e, 0xf0, 0x2b, 0xcb, 0x10, 0xc7, 0xfa, 0x59, 0xbc, 0x62, 0xa7, 0x21, 0xd7, - 0x78, 0xe9, 0xcf, 0xe2, 0x15, 0xce, 0x10, 0xad, 0x5a, 0x09, 0x44, 0xf9, 0xaf, 0xda, 0xc0, 0x21, 0xee, 0x13, 0x0c, - 0x72, 0x51, 0x79, 0x0f, 0x04, 0xf2, 0xb6, 0x82, 0x88, 0x34, 0xb3, 0xeb, 0x30, 0x22, 0xd5, 0x4e, 0x92, 0xf9, 0xf2, - 0x07, 0x99, 0x09, 0xef, 0x1b, 0x78, 0x6c, 0x36, 0xcb, 0xa6, 0x98, 0x2f, 0x54, 0x30, 0x07, 0xf7, 0x89, 0x8a, 0x4b, - 0x51, 0xf9, 0x4f, 0xd8, 0x05, 0x2f, 0xc6, 0x83, 0xd7, 0x6b, 0x04, 0xd8, 0xaf, 0xfc, 0x27, 0x6f, 0xcc, 0xfe, 0xb2, - 0x6e, 0x7c, 0x99, 0x89, 0xf8, 0xc0, 0x47, 0x77, 0x94, 0x8f, 0xee, 0xbd, 0x4c, 0x7f, 0x34, 0xa0, 0x44, 0x46, 0x65, - 0xc5, 0x57, 0x2b, 0x9e, 0xce, 0xee, 0x92, 0x28, 0x1b, 0x55, 0x5c, 0xc0, 0xf4, 0x82, 0xe3, 0x5d, 0xb2, 0xbe, 0xc8, - 0x92, 0x57, 0x10, 0x7b, 0x60, 0x25, 0x15, 0x16, 0x3f, 0x2c, 0x33, 0xb5, 0x98, 0x85, 0xac, 0xa4, 0xe0, 0xc1, 0xec, - 0x26, 0x89, 0xfe, 0x5a, 0x7a, 0x48, 0x6a, 0x66, 0xca, 0x36, 0xb5, 0x23, 0xd4, 0xc6, 0xd7, 0x91, 0x6e, 0xb4, 0x05, - 0x00, 0xdc, 0xb3, 0x45, 0x1a, 0x49, 0x26, 0x86, 0x93, 0x9a, 0x71, 0x93, 0x5e, 0x60, 0x6a, 0x5c, 0xb3, 0x8a, 0x26, - 0xce, 0x42, 0x06, 0xf4, 0xfe, 0x80, 0x97, 0x83, 0xcf, 0x19, 0xdc, 0x7f, 0xd0, 0x1a, 0xb8, 0x3c, 0x2e, 0xfa, 0x7d, - 0x79, 0x5c, 0x6c, 0xb7, 0xe5, 0x49, 0xdc, 0xef, 0xcb, 0x93, 0xd8, 0xf0, 0x0f, 0x4a, 0xb1, 0x6d, 0xcc, 0x0d, 0x12, - 0x9a, 0x4b, 0x88, 0x5a, 0x34, 0x82, 0x3f, 0x34, 0xcb, 0xb9, 0x88, 0xf2, 0xe3, 0xa4, 0xdf, 0xef, 0x2d, 0x67, 0x62, - 0x90, 0x0f, 0x93, 0x28, 0x1f, 0x26, 0x9e, 0x13, 0xe2, 0xb7, 0x9e, 0x13, 0xa2, 0xa2, 0x81, 0x2b, 0x38, 0x33, 0x00, - 0x51, 0xc0, 0xa7, 0x7f, 0x54, 0xd7, 0x52, 0xe8, 0x5a, 0x62, 0x55, 0x4b, 0xa2, 0x2b, 0xa8, 0xd9, 0x4d, 0x11, 0x96, - 0x58, 0x0a, 0x5d, 0xb2, 0x3f, 0x96, 0xc0, 0x13, 0xe5, 0xbc, 0xda, 0x00, 0x03, 0x1b, 0xe1, 0x9d, 0xc3, 0x84, 0x93, - 0x58, 0xd7, 0x80, 0x76, 0xba, 0xa9, 0xe9, 0x25, 0x5d, 0xd1, 0x2b, 0xe4, 0x67, 0x2f, 0xc1, 0x60, 0xe9, 0x98, 0xe5, - 0xd3, 0xc1, 0xe0, 0x92, 0xac, 0x58, 0x39, 0x0f, 0xe3, 0x41, 0xb8, 0x9e, 0xe5, 0xc3, 0xcb, 0xe8, 0x92, 0x90, 0x2f, - 0x8a, 0x05, 0xed, 0xad, 0x46, 0xe5, 0xc7, 0x0c, 0xc2, 0xfb, 0xa5, 0xb3, 0x30, 0x33, 0x71, 0x3e, 0x56, 0xa3, 0x3b, - 0xba, 0x82, 0xf8, 0x35, 0x70, 0x23, 0x21, 0x11, 0x74, 0xe4, 0x8a, 0xae, 0xe8, 0x9a, 0x4a, 0x33, 0xc3, 0x18, 0xad, - 0xdb, 0x1e, 0x27, 0x09, 0x38, 0x26, 0xbb, 0xe2, 0xa3, 0xb1, 0x2a, 0xbc, 0xeb, 0x3b, 0x42, 0x7b, 0xbd, 0xc4, 0x0d, - 0xd2, 0x2f, 0xed, 0x41, 0x02, 0x46, 0x64, 0xa4, 0x06, 0xca, 0x8c, 0x8c, 0xa4, 0x66, 0x52, 0x71, 0x48, 0x62, 0x7f, - 0x48, 0xd4, 0x38, 0x24, 0xfe, 0x38, 0xe4, 0x7a, 0x1c, 0x90, 0xbb, 0x5f, 0xb2, 0x31, 0x4d, 0xd9, 0x98, 0xae, 0xd5, - 0xa8, 0xd0, 0x6b, 0x7a, 0xa1, 0xa9, 0xe3, 0x39, 0x7b, 0x0d, 0x07, 0xf6, 0x20, 0xcc, 0x67, 0xf1, 0xf0, 0x75, 0xf4, - 0x9a, 0x90, 0x2f, 0x24, 0xbd, 0x51, 0x97, 0x32, 0x08, 0x84, 0x78, 0x0d, 0xce, 0xa5, 0x2e, 0xd4, 0xc9, 0xb5, 0xd9, - 0x71, 0xf8, 0x74, 0xd5, 0x78, 0xba, 0x80, 0x88, 0x3e, 0x68, 0xa5, 0xd2, 0xef, 0x87, 0x97, 0xac, 0x9c, 0x9f, 0x87, - 0x63, 0x02, 0x38, 0x3c, 0x7a, 0x38, 0x2f, 0x47, 0x77, 0xf4, 0x72, 0x74, 0x4f, 0xc0, 0xc2, 0x6b, 0x3c, 0x5d, 0x1f, - 0xb3, 0x78, 0x3a, 0x18, 0xac, 0x91, 0xaa, 0xab, 0xdc, 0x6b, 0xb2, 0xa0, 0x97, 0x38, 0x11, 0x04, 0x18, 0xfa, 0x4c, - 0xac, 0x0d, 0x0d, 0x7f, 0xcd, 0xe0, 0xe3, 0x7b, 0x76, 0x39, 0xba, 0xa7, 0x77, 0xec, 0xf5, 0x76, 0x3c, 0x05, 0x66, - 0x6a, 0x35, 0x0b, 0xef, 0x8f, 0xaf, 0x66, 0x57, 0xec, 0x3e, 0xba, 0x3f, 0x81, 0x86, 0x5e, 0xb3, 0x7b, 0x04, 0x5c, - 0x4a, 0x1f, 0x2f, 0x07, 0xaf, 0xc9, 0xe1, 0x60, 0x90, 0x92, 0x28, 0xbc, 0x09, 0xbd, 0x56, 0xbe, 0xa6, 0xf7, 0x84, - 0xae, 0xd8, 0x1d, 0x8e, 0xc6, 0x15, 0xc3, 0x0f, 0x2e, 0xd8, 0x7d, 0x7d, 0x13, 0x7a, 0xbb, 0x39, 0x11, 0x9d, 0x20, - 0x46, 0xe8, 0x6b, 0xe0, 0x68, 0x96, 0x0b, 0x33, 0x01, 0x4f, 0xe6, 0x22, 0xa3, 0x45, 0xa1, 0x19, 0x88, 0xb3, 0x12, - 0x10, 0x4b, 0xa2, 0xee, 0x37, 0x1b, 0x9d, 0xc3, 0x72, 0xee, 0xf7, 0x7b, 0x95, 0xa1, 0x07, 0x88, 0x9c, 0xd9, 0x49, - 0x0f, 0x7a, 0x3e, 0x3d, 0xc0, 0x4f, 0xf4, 0xaa, 0x41, 0x9c, 0xcc, 0x5f, 0x96, 0xd1, 0xb7, 0x1e, 0x7d, 0xf8, 0xbe, - 0x9b, 0xf2, 0x88, 0xfc, 0xdf, 0xa7, 0x3c, 0x65, 0x1e, 0xbd, 0xae, 0x3c, 0x10, 0x3c, 0x6f, 0x4d, 0x2a, 0x8d, 0x44, - 0x35, 0x3a, 0x5f, 0xc5, 0xa0, 0x8d, 0x44, 0x6d, 0x83, 0x7e, 0x42, 0x0b, 0x2b, 0x88, 0x90, 0x73, 0xf4, 0x1c, 0x0c, - 0x52, 0x21, 0x54, 0x8e, 0x5a, 0x94, 0x68, 0x08, 0x92, 0xcb, 0x92, 0xab, 0xf0, 0x39, 0x84, 0xaa, 0xd3, 0xc7, 0x99, - 0x08, 0x1b, 0x7a, 0x1c, 0xfa, 0x00, 0xf0, 0x3f, 0xef, 0x90, 0x8b, 0x92, 0x5f, 0xe1, 0xd9, 0xdc, 0x26, 0x18, 0x05, - 0x4b, 0x44, 0x33, 0xb4, 0x0d, 0x62, 0x3f, 0x96, 0x04, 0xeb, 0x91, 0x34, 0x1e, 0x95, 0xe6, 0x88, 0xf0, 0xa3, 0xf8, - 0x28, 0x7a, 0x1a, 0x1b, 0x12, 0xc9, 0x91, 0x44, 0xf2, 0x01, 0x10, 0x4e, 0x82, 0xfe, 0xe2, 0xae, 0xc9, 0xae, 0x85, - 0xc4, 0xa0, 0x3f, 0x2d, 0x99, 0x96, 0xdd, 0xab, 0x1e, 0xfb, 0x8a, 0x20, 0x77, 0x4c, 0xff, 0xe9, 0xf5, 0xe1, 0x5f, - 0x4b, 0x9c, 0x41, 0xeb, 0xf9, 0xa2, 0x3a, 0x33, 0xf3, 0x06, 0x37, 0xf2, 0xba, 0xac, 0x5d, 0x97, 0x2f, 0xf9, 0x01, - 0xbf, 0xab, 0xb8, 0x48, 0xcb, 0x83, 0x9f, 0xaa, 0x36, 0x9e, 0x53, 0xb9, 0x5e, 0xb9, 0x38, 0x2b, 0xca, 0x38, 0xd5, - 0x93, 0xba, 0x18, 0x6b, 0xd8, 0x86, 0xdf, 0x23, 0xea, 0x4a, 0x5a, 0x8e, 0x9e, 0x52, 0xae, 0x9a, 0x29, 0x97, 0xeb, - 0x3c, 0xff, 0x71, 0x27, 0x15, 0xa7, 0xb8, 0x99, 0x82, 0x54, 0xa9, 0xe5, 0x02, 0xaa, 0xe7, 0xa8, 0xe5, 0x6e, 0x69, - 0x76, 0x80, 0x73, 0xdb, 0x54, 0x1f, 0x2b, 0xb3, 0x0b, 0x2f, 0xb9, 0x71, 0x7f, 0x32, 0x65, 0x58, 0x30, 0x0a, 0x6d, - 0x56, 0x5d, 0x69, 0xfb, 0x42, 0xeb, 0x34, 0x0c, 0x57, 0x7e, 0xbc, 0x80, 0x74, 0x01, 0xe3, 0x78, 0x51, 0x32, 0x31, - 0x6e, 0x8f, 0xde, 0x0a, 0xe2, 0x73, 0xb6, 0x02, 0xe9, 0xf7, 0x7b, 0xc2, 0xdb, 0x75, 0x1d, 0x6d, 0xf7, 0xc4, 0x29, - 0xa3, 0x72, 0x15, 0x8b, 0xef, 0xe2, 0x95, 0x81, 0x4c, 0x56, 0xc7, 0x63, 0x63, 0x4c, 0xa7, 0xff, 0x48, 0x42, 0xbf, - 0x10, 0x0a, 0x3e, 0xeb, 0xa5, 0x95, 0x27, 0xb7, 0x87, 0x65, 0x5c, 0xa3, 0x57, 0xe2, 0x4a, 0xf7, 0xcd, 0x48, 0x21, - 0xf5, 0xc8, 0x57, 0x4d, 0x01, 0xbd, 0x19, 0xfb, 0x66, 0x2a, 0xcc, 0xdb, 0x9e, 0x31, 0x57, 0x08, 0x56, 0xaa, 0xec, - 0xf6, 0x9d, 0x1a, 0x53, 0x31, 0x83, 0x29, 0xb6, 0x9d, 0xc5, 0xa4, 0x5b, 0xf9, 0xa7, 0x9d, 0xfb, 0x65, 0xde, 0xe1, - 0xae, 0xa8, 0xdf, 0x02, 0x17, 0x9a, 0x15, 0x65, 0xd5, 0x96, 0x0d, 0xdb, 0xc6, 0x1b, 0x59, 0x28, 0x36, 0xc0, 0xb2, - 0xe7, 0xbe, 0x85, 0x07, 0x88, 0x9b, 0x70, 0xcf, 0x2e, 0x6a, 0xb8, 0x31, 0x7c, 0x5e, 0x49, 0xbe, 0x2b, 0x8d, 0xb9, - 0xf4, 0xa9, 0xd2, 0xc4, 0x70, 0xb2, 0x18, 0x71, 0x91, 0x2e, 0xea, 0xcc, 0xae, 0x85, 0x4f, 0x78, 0x19, 0xce, 0xf9, - 0xc2, 0xe8, 0xa6, 0x74, 0xe9, 0x05, 0x8b, 0x75, 0xa7, 0x37, 0x2b, 0x8d, 0x95, 0x12, 0x71, 0x6b, 0x96, 0x09, 0x94, - 0xa5, 0xac, 0x95, 0xf0, 0xa6, 0x68, 0xd9, 0x4a, 0x1a, 0x79, 0xcf, 0x1c, 0xdc, 0xc7, 0xbe, 0x47, 0x4c, 0x64, 0x13, - 0x98, 0x14, 0x0d, 0x1d, 0xd0, 0xae, 0xba, 0xf0, 0xcd, 0xa8, 0x07, 0x83, 0xdc, 0x92, 0x44, 0xac, 0x20, 0xc5, 0x0a, - 0xd6, 0x35, 0x2b, 0xe6, 0xf9, 0x82, 0x5e, 0x32, 0x39, 0x4f, 0x17, 0x74, 0xc5, 0xe4, 0x7c, 0x8d, 0x37, 0xa1, 0x4b, - 0x38, 0x21, 0xc9, 0x26, 0x56, 0x0a, 0xd8, 0x4b, 0xbc, 0xbc, 0xe1, 0x99, 0xaa, 0x69, 0xd9, 0x95, 0xe2, 0x00, 0xe3, - 0x8b, 0x32, 0x0c, 0xcb, 0xe1, 0x25, 0x58, 0x4b, 0x1c, 0x86, 0xab, 0x39, 0x5f, 0xa8, 0xdf, 0x10, 0x75, 0x3e, 0x09, - 0x15, 0xbb, 0x60, 0xf7, 0x02, 0x99, 0x5e, 0xcf, 0xf9, 0x42, 0x8d, 0x84, 0x2e, 0xf8, 0xda, 0x1a, 0x9b, 0xc4, 0x9e, - 0xa0, 0x65, 0x16, 0xcf, 0xc7, 0x8b, 0x28, 0xae, 0x61, 0x19, 0x9e, 0xa9, 0x99, 0x69, 0xc9, 0x7f, 0x12, 0xb5, 0xa1, - 0x89, 0xbe, 0xc1, 0x2a, 0xf2, 0x87, 0xc7, 0x47, 0x97, 0x40, 0xc6, 0xce, 0xae, 0x64, 0xe6, 0x43, 0xdf, 0x47, 0x06, - 0xf7, 0xdc, 0x94, 0x33, 0xae, 0x82, 0x44, 0x19, 0xb8, 0x7b, 0x35, 0x4b, 0xc6, 0x5a, 0x84, 0xef, 0x1e, 0x15, 0x45, - 0x9f, 0x49, 0xd3, 0x80, 0xee, 0x23, 0xc1, 0x1c, 0xe8, 0xbd, 0x42, 0x87, 0xcb, 0x6a, 0x9b, 0x09, 0xf8, 0x8b, 0x04, - 0xf9, 0xad, 0xd0, 0xab, 0x1a, 0x83, 0x2a, 0xda, 0x45, 0x2c, 0xfd, 0xfb, 0x88, 0x1f, 0x65, 0xf3, 0x4f, 0x73, 0x8f, - 0x57, 0x12, 0x06, 0x3f, 0xa4, 0x66, 0x93, 0xcc, 0xdb, 0x2b, 0xf6, 0x1e, 0x3a, 0xea, 0x51, 0x6b, 0xbc, 0xaf, 0x5e, - 0x72, 0x0a, 0x31, 0x4a, 0x28, 0x3a, 0x09, 0x06, 0x70, 0xbb, 0x84, 0x14, 0x77, 0x83, 0xdd, 0x34, 0xaf, 0x79, 0x51, - 0x70, 0xb1, 0xae, 0xaa, 0xc0, 0x0f, 0x68, 0x38, 0x5f, 0xec, 0x86, 0x30, 0x1c, 0xd3, 0xd6, 0x35, 0x0c, 0xc2, 0x8c, - 0x61, 0x24, 0x04, 0xaf, 0x7f, 0xd1, 0x57, 0x34, 0x89, 0x57, 0xdf, 0xf2, 0xbf, 0x32, 0x5e, 0x28, 0x22, 0x0d, 0x22, - 0xa4, 0x6e, 0xe2, 0x1b, 0x99, 0x26, 0x05, 0x14, 0x02, 0x8c, 0x02, 0x2a, 0xb1, 0xa1, 0xa9, 0xf8, 0x5b, 0x2d, 0x3e, - 0xf8, 0xa9, 0xe9, 0x78, 0x34, 0xae, 0x5b, 0x9d, 0x51, 0x41, 0x67, 0xa0, 0x47, 0xad, 0xa8, 0xa7, 0x41, 0x2b, 0xc1, - 0x34, 0xd2, 0xbc, 0x75, 0x0f, 0x81, 0x57, 0xa6, 0xc5, 0x3b, 0x0f, 0xe8, 0xe6, 0xdc, 0x07, 0x4f, 0x1e, 0xd3, 0x73, - 0x87, 0x9e, 0x5c, 0xb1, 0x93, 0xaa, 0x87, 0xda, 0x7b, 0x33, 0x42, 0x41, 0xbf, 0x8f, 0x29, 0xd0, 0x8d, 0xa0, 0xf6, - 0xae, 0xee, 0x3f, 0x94, 0xbb, 0x1c, 0xbe, 0xe3, 0x2c, 0x37, 0x80, 0xa5, 0x22, 0x6b, 0x05, 0x1e, 0x05, 0xa8, 0x4b, - 0x65, 0x08, 0x5b, 0xcc, 0xe1, 0x50, 0xd9, 0xad, 0x5a, 0x0d, 0x25, 0x39, 0x2e, 0x47, 0xe0, 0x10, 0xba, 0x2e, 0x07, - 0xe5, 0x68, 0x99, 0x55, 0xef, 0xf1, 0xb7, 0x66, 0x1d, 0x92, 0x6c, 0x1f, 0xeb, 0xc0, 0x2d, 0xeb, 0x30, 0xfd, 0x68, - 0x90, 0x02, 0xd0, 0x64, 0x23, 0x70, 0x09, 0xc0, 0x7b, 0xfb, 0x8f, 0x08, 0xb5, 0x32, 0xdd, 0xcb, 0x58, 0xa8, 0xef, - 0x1b, 0x49, 0x50, 0x42, 0x33, 0xa1, 0x72, 0x2c, 0x05, 0xef, 0x3c, 0xd2, 0x39, 0xa9, 0x33, 0xf1, 0x1e, 0xc4, 0x69, - 0xe1, 0x03, 0x7b, 0x0b, 0x82, 0x73, 0x16, 0xf4, 0x1e, 0x6f, 0xb3, 0x5a, 0x6a, 0xa3, 0x07, 0x0a, 0xe0, 0x77, 0x83, - 0x7b, 0x04, 0xf9, 0x6a, 0x0c, 0xd7, 0x4a, 0xde, 0x86, 0x7c, 0x58, 0xd0, 0x23, 0x32, 0xb0, 0xcf, 0x62, 0x18, 0xd3, - 0x23, 0x72, 0x6c, 0x9f, 0xa5, 0x1b, 0xc0, 0x81, 0xd4, 0xa3, 0x4a, 0x8f, 0xa0, 0x41, 0xbf, 0xda, 0x16, 0x59, 0x92, - 0xf5, 0x43, 0x69, 0x14, 0x31, 0x50, 0x25, 0x88, 0xa8, 0xc5, 0xbf, 0x1e, 0xcc, 0x75, 0x8f, 0xb9, 0x40, 0x98, 0x83, - 0x01, 0x07, 0x71, 0x1b, 0x84, 0xe6, 0x80, 0xd9, 0xdc, 0x45, 0x82, 0xde, 0x5b, 0xc3, 0xcc, 0x8e, 0xfe, 0x70, 0x2b, - 0xc1, 0x37, 0x59, 0x6b, 0xd4, 0x79, 0x71, 0x08, 0x04, 0xc1, 0x9b, 0x42, 0x55, 0x7b, 0xd5, 0x03, 0x1b, 0x6f, 0xd5, - 0x8f, 0xed, 0x76, 0x3c, 0x15, 0xee, 0xda, 0x2f, 0x28, 0x9c, 0x7c, 0x4a, 0xfe, 0xf5, 0xde, 0x64, 0x70, 0x60, 0x64, - 0xf8, 0xd2, 0xdb, 0xbf, 0xf0, 0xb5, 0x96, 0xee, 0x89, 0x41, 0x49, 0x1e, 0x1f, 0x29, 0xfa, 0xb7, 0x57, 0x56, 0x3e, - 0xb5, 0xd3, 0xbf, 0xdd, 0x9a, 0xf5, 0x79, 0x3c, 0x9a, 0x6c, 0xb7, 0xbd, 0xb8, 0xd2, 0x1e, 0x6b, 0x7a, 0x41, 0xa0, - 0x73, 0x3d, 0x39, 0x3c, 0x82, 0xa8, 0x08, 0xcd, 0xb8, 0x9b, 0x65, 0x43, 0x22, 0xe3, 0xc7, 0xe9, 0x2c, 0x1b, 0x82, - 0x1d, 0xee, 0x45, 0x25, 0x2e, 0x47, 0xad, 0x0d, 0x4e, 0xcf, 0x93, 0x10, 0x42, 0x39, 0x60, 0x65, 0x77, 0xea, 0xcf, - 0xbd, 0x32, 0x13, 0x52, 0x93, 0xd5, 0xed, 0x94, 0xee, 0x61, 0x9a, 0x1f, 0x98, 0x11, 0x1c, 0x70, 0x6f, 0x7f, 0xd5, - 0x1f, 0xc3, 0x24, 0xd3, 0xe4, 0x14, 0xc9, 0x2f, 0xd2, 0x53, 0x48, 0xda, 0xa1, 0xa7, 0x8a, 0x00, 0x4e, 0xa8, 0xfd, - 0x18, 0x7e, 0xc3, 0xb8, 0x7f, 0xdb, 0x7c, 0xed, 0xa6, 0x22, 0x7a, 0x42, 0xb1, 0x4c, 0x4d, 0x4e, 0x93, 0xac, 0x48, - 0x20, 0x6a, 0xa3, 0x6a, 0x46, 0xf4, 0x95, 0x8b, 0xf9, 0xa8, 0x08, 0x9f, 0x57, 0xeb, 0xff, 0x0c, 0xe1, 0x33, 0x0a, - 0x37, 0x80, 0xcb, 0x2b, 0xae, 0x2e, 0xc2, 0xa7, 0x4f, 0xe8, 0xc1, 0xe4, 0xeb, 0x23, 0x7a, 0x70, 0xf4, 0xd5, 0x53, - 0x02, 0xb0, 0x68, 0x57, 0x17, 0xe1, 0xd1, 0xd3, 0xa7, 0xf4, 0xe0, 0x9b, 0x6f, 0xe8, 0xc1, 0xe4, 0xab, 0xa3, 0x46, - 0xda, 0xe4, 0xe9, 0x37, 0xf4, 0xe0, 0xeb, 0x27, 0x8d, 0xb4, 0xa3, 0xf1, 0x53, 0x7a, 0xf0, 0xf7, 0xaf, 0x4d, 0xda, - 0xdf, 0x20, 0xdb, 0x37, 0x47, 0xf8, 0x9f, 0x49, 0x9b, 0x3c, 0xfd, 0x8a, 0x1e, 0x4c, 0xc6, 0x50, 0xc9, 0x53, 0x57, - 0xc9, 0x78, 0x02, 0x1f, 0x7f, 0x05, 0xff, 0xfd, 0x8d, 0x04, 0x0b, 0x5a, 0x49, 0x96, 0x0b, 0xd4, 0x9f, 0xa1, 0x88, - 0x13, 0x55, 0x13, 0x09, 0x0f, 0x31, 0xb3, 0xfa, 0x26, 0x0e, 0x03, 0xe2, 0xd2, 0xa1, 0x20, 0x7a, 0x30, 0x1e, 0x3d, - 0x25, 0x81, 0x0f, 0x4f, 0x77, 0xeb, 0x83, 0x8c, 0xe5, 0x62, 0x9e, 0x7d, 0x91, 0x9b, 0xd8, 0x0a, 0x1e, 0x80, 0xd5, - 0x47, 0x3f, 0x57, 0x25, 0xe7, 0xd9, 0x17, 0x95, 0xdc, 0xcd, 0xf5, 0x6b, 0x0b, 0x50, 0xde, 0x5f, 0xb5, 0xec, 0xb6, - 0x50, 0xa1, 0xd3, 0x5a, 0xa3, 0xcf, 0x3e, 0x62, 0xfa, 0x60, 0xe0, 0xdd, 0xb0, 0xff, 0xb1, 0x53, 0x4e, 0xeb, 0x1b, - 0x8d, 0x42, 0x8d, 0xca, 0x43, 0xc2, 0x4e, 0xa0, 0xe8, 0xc1, 0x00, 0x78, 0x02, 0x0f, 0xf7, 0xed, 0xdf, 0x2c, 0xe3, - 0x63, 0x47, 0x19, 0x3f, 0xa1, 0x0c, 0x01, 0x8d, 0x7a, 0x98, 0xdd, 0xf4, 0xb0, 0xd1, 0xad, 0x5e, 0xb2, 0x54, 0x27, - 0x53, 0xd3, 0x33, 0xd8, 0xd7, 0xba, 0x96, 0x07, 0x46, 0x14, 0x2d, 0x2f, 0x0f, 0x52, 0x3e, 0xab, 0xd8, 0x3f, 0x96, - 0xa8, 0xde, 0x8a, 0x1a, 0x6f, 0x64, 0x36, 0xab, 0xd8, 0x77, 0xe6, 0x0d, 0x70, 0x33, 0xec, 0x57, 0xf5, 0xe4, 0x07, - 0xce, 0xe0, 0xd2, 0xb6, 0x47, 0x99, 0x18, 0x01, 0x56, 0x40, 0x06, 0x0e, 0x3c, 0x00, 0x3a, 0xe8, 0x8f, 0xf6, 0x76, - 0xab, 0x52, 0x9a, 0x7d, 0xb6, 0x30, 0x80, 0x86, 0x79, 0x9b, 0xb8, 0xb2, 0x7f, 0x6b, 0xc8, 0x4b, 0x50, 0xb8, 0xd5, - 0x2c, 0x6f, 0xa7, 0x30, 0x84, 0x10, 0xfc, 0x61, 0xc9, 0x00, 0x70, 0x20, 0xc0, 0x60, 0xac, 0x65, 0x40, 0xcd, 0x96, - 0x8f, 0x36, 0x5c, 0xa9, 0x27, 0x81, 0x33, 0xb8, 0x94, 0x45, 0xc2, 0xdf, 0x6a, 0xb1, 0x3f, 0x5a, 0x3f, 0xfa, 0xbe, - 0x3d, 0x1e, 0xac, 0x7d, 0x8f, 0x8f, 0xf4, 0x67, 0x8d, 0xeb, 0xc0, 0xa6, 0xe5, 0x1b, 0x2f, 0x6a, 0x2b, 0xf1, 0x28, - 0x81, 0x37, 0x30, 0x11, 0x29, 0x0c, 0x52, 0x2d, 0x70, 0x0c, 0xca, 0x1b, 0x0b, 0xb1, 0x54, 0x5d, 0xdd, 0x60, 0x0b, - 0x22, 0x43, 0xf0, 0x70, 0xfb, 0x6d, 0xa9, 0x02, 0x47, 0xf5, 0xfb, 0x5c, 0xfa, 0x6e, 0x4f, 0xc6, 0x8e, 0x1c, 0xa7, - 0x7e, 0x2a, 0x1c, 0xfc, 0x37, 0xa9, 0x6b, 0x63, 0xb9, 0x92, 0x32, 0xcb, 0xb2, 0xb0, 0x93, 0x50, 0xcb, 0x3d, 0x2a, - 0x0f, 0x92, 0x2f, 0xe4, 0x10, 0xc9, 0x02, 0xa3, 0x50, 0x90, 0xe1, 0x84, 0x8a, 0xd1, 0x5a, 0x94, 0xcb, 0xec, 0xb2, - 0x0a, 0x37, 0x4a, 0xa1, 0xcc, 0x29, 0xfa, 0x76, 0x83, 0x03, 0x09, 0x89, 0xb2, 0xf2, 0x4d, 0xfc, 0x26, 0x44, 0xb0, - 0x3a, 0xae, 0x6d, 0xa1, 0xb8, 0xb7, 0x3f, 0x79, 0xda, 0xc5, 0x1f, 0x19, 0x17, 0x50, 0x17, 0x8b, 0x69, 0x38, 0xb1, - 0xb1, 0x6f, 0xdc, 0x17, 0x56, 0xd3, 0x03, 0x50, 0xdf, 0xa5, 0x12, 0x23, 0xa8, 0xaf, 0x8c, 0x7d, 0x6c, 0x8f, 0x31, - 0x39, 0x83, 0x58, 0xc3, 0x2a, 0x67, 0xa6, 0xfa, 0x46, 0xd8, 0x09, 0x00, 0x37, 0x42, 0x6b, 0x74, 0x64, 0x92, 0x2a, - 0xc4, 0xf3, 0x52, 0x85, 0x6f, 0xcd, 0x08, 0x1d, 0x83, 0x37, 0x95, 0x6d, 0x64, 0x26, 0x7d, 0xc1, 0xa0, 0x39, 0xb6, - 0x75, 0x14, 0x56, 0x5b, 0x59, 0x76, 0x02, 0x70, 0x03, 0xd9, 0xb1, 0xb9, 0x78, 0xce, 0xaa, 0x79, 0xb6, 0x88, 0x4c, - 0x50, 0xc0, 0xa5, 0xb0, 0x0c, 0xda, 0x9b, 0x3d, 0xb2, 0x1d, 0x87, 0xd0, 0x0d, 0xf7, 0x11, 0x8c, 0xa7, 0xdd, 0x14, - 0xac, 0x20, 0x1a, 0x21, 0x1e, 0x66, 0xcc, 0xe2, 0x7b, 0xa5, 0x29, 0x4f, 0x55, 0x4b, 0x20, 0x70, 0x14, 0x42, 0x5d, - 0xec, 0x1a, 0x25, 0xb8, 0x4c, 0x8d, 0x60, 0x06, 0x3b, 0x76, 0xa4, 0xb6, 0x4b, 0xce, 0xe9, 0x50, 0x4d, 0x69, 0xa9, - 0xa7, 0x54, 0xfb, 0x1a, 0x8a, 0x79, 0x89, 0x1e, 0x7a, 0xe0, 0x7a, 0xa0, 0x1d, 0xf2, 0x4a, 0x3a, 0x31, 0x11, 0x74, - 0x5a, 0x6d, 0xc2, 0xce, 0x8d, 0x74, 0xcb, 0x6a, 0xe4, 0x1d, 0x43, 0xb3, 0x23, 0x5e, 0xf8, 0x81, 0xba, 0x00, 0x22, - 0x64, 0x6f, 0x8b, 0xcc, 0x11, 0xcd, 0xb2, 0xf2, 0x25, 0x94, 0xc5, 0x11, 0x5b, 0x57, 0xc0, 0xb5, 0x14, 0x4c, 0x2e, - 0x79, 0xc4, 0x53, 0x44, 0x04, 0x3c, 0x55, 0xda, 0xf5, 0x9d, 0x96, 0x10, 0x9a, 0xa5, 0x40, 0xdc, 0x5c, 0x14, 0xe7, - 0xda, 0x06, 0xb2, 0x00, 0xfa, 0xf6, 0x63, 0x76, 0xed, 0x85, 0x83, 0xdd, 0x5c, 0x67, 0xe2, 0x39, 0xbf, 0xcc, 0x04, - 0x4f, 0x11, 0xec, 0xea, 0xce, 0x3c, 0x70, 0xc7, 0xb6, 0x81, 0xe5, 0xdb, 0xb7, 0xb0, 0x60, 0xca, 0x50, 0x2b, 0x25, - 0x32, 0x11, 0x09, 0xc8, 0xec, 0x33, 0x77, 0xaf, 0x33, 0xf1, 0x3a, 0xbe, 0x03, 0x6f, 0x8a, 0x06, 0x3f, 0x3d, 0xba, - 0xc0, 0x2f, 0x11, 0x49, 0x14, 0x62, 0xd8, 0x62, 0x44, 0x2c, 0x44, 0x8e, 0x1d, 0x13, 0xca, 0x95, 0xa0, 0xb5, 0x35, - 0x04, 0x5e, 0xfc, 0x69, 0xd5, 0xbd, 0xeb, 0x4c, 0x18, 0xfb, 0x8c, 0xeb, 0xf8, 0x8e, 0x95, 0x0a, 0xcc, 0x02, 0xe3, - 0xdc, 0xb7, 0xa5, 0x24, 0xd7, 0x99, 0x30, 0x02, 0x92, 0xeb, 0xf8, 0x8e, 0x36, 0x65, 0x1c, 0xda, 0x8a, 0xce, 0x8b, - 0xf3, 0xbb, 0x3b, 0xfc, 0x12, 0x43, 0xad, 0x8c, 0xfb, 0x7d, 0x90, 0x98, 0x49, 0xdb, 0x94, 0x99, 0x8c, 0xa4, 0x46, - 0x0b, 0xa9, 0x28, 0x1f, 0x4c, 0xc8, 0xee, 0x4a, 0xb5, 0x8c, 0xa8, 0xfd, 0x2a, 0x14, 0xb3, 0x71, 0x34, 0x21, 0x74, - 0xd2, 0xb1, 0xde, 0x4d, 0x6b, 0x21, 0xd3, 0xe8, 0x69, 0xe4, 0xf9, 0x74, 0x16, 0xac, 0x9a, 0x16, 0xc7, 0x8c, 0x4f, - 0x8b, 0xc1, 0x80, 0x68, 0x97, 0xc2, 0x0d, 0xd6, 0x03, 0xa6, 0x34, 0x2e, 0xde, 0x9a, 0x69, 0xf5, 0x4b, 0xa9, 0x42, - 0xd2, 0x7b, 0x06, 0x24, 0x99, 0x74, 0xc1, 0x6e, 0x41, 0xa2, 0xe8, 0xf9, 0xdf, 0xa9, 0x2d, 0xb8, 0xeb, 0xc1, 0xd8, - 0x8c, 0xee, 0xeb, 0x19, 0xff, 0xa1, 0xb6, 0x05, 0x51, 0x9f, 0x4a, 0xd6, 0xeb, 0x48, 0x54, 0x21, 0x17, 0xe1, 0x67, - 0x47, 0x43, 0x0c, 0x51, 0xed, 0xb1, 0x40, 0xac, 0xaf, 0x2f, 0x78, 0x81, 0xd3, 0xcf, 0xdc, 0xe5, 0x0a, 0xb6, 0x05, - 0xad, 0x0c, 0x8d, 0x7a, 0x13, 0xbf, 0x89, 0xec, 0x65, 0x41, 0x17, 0xf9, 0x1c, 0x85, 0xac, 0x79, 0x18, 0x56, 0xc3, - 0xf6, 0x20, 0x92, 0xc3, 0xf6, 0x24, 0x34, 0x1a, 0x03, 0x0b, 0x64, 0x87, 0x46, 0xe0, 0x22, 0xb4, 0xf2, 0xb7, 0x63, - 0x70, 0xe1, 0xb2, 0x88, 0x2c, 0x43, 0x1d, 0xbf, 0xa9, 0xdd, 0x04, 0xd5, 0x2b, 0x74, 0x9a, 0xc2, 0xaa, 0x94, 0x49, - 0x3e, 0xfc, 0x7a, 0x29, 0x0b, 0xcc, 0xe4, 0x75, 0xd9, 0xa3, 0xaf, 0xed, 0xf6, 0x0e, 0x4c, 0xc1, 0xba, 0x4f, 0xde, - 0xd7, 0x8f, 0x3b, 0x7b, 0x02, 0x46, 0xb1, 0x2a, 0x47, 0x53, 0x48, 0xa9, 0x7d, 0x50, 0xea, 0x8f, 0xe1, 0x52, 0x68, - 0x8e, 0xdd, 0x02, 0x26, 0x01, 0xfb, 0x0c, 0xa9, 0x1e, 0xd3, 0x8e, 0x7d, 0x8e, 0x36, 0xb0, 0x24, 0xe0, 0xf0, 0x8f, - 0x32, 0x59, 0xfb, 0x57, 0x77, 0x91, 0x36, 0x43, 0xb6, 0xcc, 0x17, 0xc0, 0xe7, 0xc3, 0xae, 0x8d, 0x4a, 0x94, 0x4d, - 0x44, 0x92, 0xc2, 0x96, 0xc7, 0x20, 0xed, 0x51, 0x4c, 0x57, 0x05, 0x4f, 0x32, 0x94, 0x52, 0x24, 0xda, 0x27, 0x38, - 0x87, 0x37, 0xb8, 0x1f, 0x55, 0x40, 0x78, 0x15, 0x72, 0x3a, 0x4a, 0xa9, 0xb6, 0x80, 0x51, 0xd4, 0x03, 0x44, 0x79, - 0x19, 0xc8, 0xf1, 0xb6, 0xdb, 0x09, 0x5d, 0xb1, 0xe5, 0x70, 0x42, 0x91, 0x94, 0x5c, 0x61, 0xb9, 0xd7, 0xa0, 0xf3, - 0xb8, 0x60, 0xbd, 0x17, 0x80, 0x45, 0x70, 0x0e, 0x7f, 0x63, 0x42, 0x6f, 0xe0, 0x6f, 0x4e, 0xe8, 0x6b, 0x16, 0x5e, - 0x0f, 0xaf, 0xc8, 0x61, 0x98, 0x0e, 0x26, 0x4a, 0x30, 0x76, 0xcf, 0x96, 0x65, 0xa8, 0x12, 0x57, 0x87, 0x97, 0xe4, - 0xf1, 0x25, 0xbd, 0xa3, 0xb7, 0xf4, 0x8c, 0xbe, 0x05, 0xc2, 0x7f, 0x7f, 0x3c, 0xe1, 0xc3, 0xc9, 0x93, 0x7e, 0xbf, - 0x77, 0xd1, 0xef, 0xf7, 0xce, 0x8d, 0x01, 0x85, 0xde, 0x45, 0x57, 0x35, 0xd5, 0xbf, 0xae, 0xeb, 0xc5, 0xf4, 0xad, - 0xda, 0xb8, 0x09, 0xcf, 0xf2, 0xf0, 0xfa, 0xf0, 0x9e, 0x0c, 0xf1, 0xf1, 0x32, 0x97, 0xb2, 0x08, 0xaf, 0x0e, 0xef, - 0x09, 0x7d, 0x7b, 0x02, 0x7a, 0x53, 0xac, 0xef, 0xed, 0xe3, 0x7b, 0x5d, 0x1b, 0xa1, 0x2f, 0xc2, 0x04, 0xb6, 0xc9, - 0x1d, 0xb3, 0x77, 0xed, 0xc9, 0x18, 0x62, 0x99, 0xdc, 0x7b, 0xe5, 0xdd, 0x3f, 0xbe, 0x23, 0x87, 0x77, 0xe0, 0x29, - 0x6a, 0xc9, 0xdf, 0x2c, 0xbc, 0x65, 0xad, 0x1a, 0x1e, 0xdf, 0xd3, 0xb3, 0x56, 0x23, 0x1e, 0xdf, 0x93, 0x28, 0xbc, - 0x65, 0x57, 0xf4, 0x8c, 0x5d, 0x13, 0x7a, 0xd1, 0xef, 0x9f, 0xf7, 0xfb, 0xb2, 0xdf, 0xff, 0x47, 0x1c, 0x86, 0xf1, - 0xb0, 0x20, 0x87, 0x92, 0xde, 0x1f, 0x4e, 0xf8, 0x57, 0x64, 0x16, 0xea, 0xe6, 0xab, 0x05, 0x67, 0x55, 0xde, 0x2a, - 0xd7, 0x3d, 0x05, 0x6b, 0x85, 0x7b, 0xa6, 0x9e, 0xde, 0xd2, 0x5b, 0x56, 0xd0, 0x33, 0x16, 0x93, 0xe8, 0x06, 0x5a, - 0x71, 0x31, 0x2b, 0xa2, 0x5b, 0x7a, 0xc6, 0xce, 0x67, 0x71, 0x74, 0x46, 0xdf, 0xb2, 0x7c, 0x38, 0x81, 0xbc, 0x67, - 0xc3, 0x5b, 0x72, 0xf8, 0x96, 0x44, 0xe1, 0x5b, 0xfd, 0xfb, 0x9e, 0x5e, 0xf1, 0xf0, 0x2d, 0xf5, 0xaa, 0x79, 0x4b, - 0x4c, 0xf5, 0x8d, 0xda, 0xdf, 0x92, 0xc8, 0x1f, 0xcc, 0xb7, 0xd6, 0x9e, 0xe6, 0x91, 0xa3, 0x8d, 0x69, 0x19, 0x82, - 0xbe, 0xb9, 0x0c, 0x6f, 0x09, 0x99, 0x36, 0xc7, 0x0e, 0x06, 0x74, 0xf6, 0x28, 0x4a, 0x08, 0xbd, 0xf5, 0x4b, 0xbd, - 0xc5, 0x31, 0x34, 0x23, 0xa4, 0xd2, 0xce, 0x30, 0x0d, 0xd7, 0xc1, 0x2b, 0x0d, 0xd6, 0x71, 0xd1, 0xef, 0x87, 0xeb, - 0x7e, 0x1f, 0x22, 0xdd, 0x17, 0x33, 0x13, 0xdb, 0xcd, 0x91, 0x4d, 0x7a, 0x0b, 0xda, 0xff, 0x57, 0x83, 0x01, 0x74, - 0xc6, 0x2b, 0x29, 0xbc, 0x1d, 0xbc, 0x7a, 0x7c, 0x4f, 0x54, 0x1d, 0x05, 0x15, 0x32, 0x2c, 0xe8, 0x6b, 0x9a, 0x01, - 0xe0, 0xd7, 0xab, 0xc1, 0x80, 0x44, 0xe6, 0x33, 0x32, 0x7d, 0x75, 0xfc, 0x76, 0x3a, 0x18, 0xbc, 0x32, 0xdb, 0xe4, - 0x2f, 0xb6, 0xa7, 0x14, 0x58, 0x7f, 0xe7, 0xfd, 0xfe, 0x5f, 0x27, 0x31, 0xb9, 0x28, 0x78, 0xfc, 0x71, 0xda, 0x6c, - 0xcb, 0x5f, 0x2e, 0xaa, 0xda, 0x79, 0xbf, 0xbf, 0xee, 0xf7, 0xcf, 0x00, 0xbb, 0x68, 0xe6, 0x7c, 0x3d, 0x41, 0xda, - 0x32, 0x77, 0x14, 0x49, 0x93, 0x1c, 0x1a, 0x43, 0xdb, 0x62, 0xd5, 0xb6, 0x59, 0x47, 0x06, 0x16, 0x47, 0xcd, 0x8a, - 0xe2, 0x9a, 0x44, 0x61, 0xef, 0x7c, 0xbb, 0x3d, 0x63, 0x8c, 0xc5, 0x04, 0xa4, 0x1f, 0xfe, 0xeb, 0xb3, 0xba, 0x11, - 0x43, 0x4c, 0x48, 0x64, 0x36, 0x37, 0x4b, 0x7b, 0x08, 0x44, 0x1c, 0x36, 0xfd, 0x7b, 0x73, 0x2f, 0x17, 0xb5, 0xe3, - 0x5b, 0x7f, 0x03, 0x10, 0x22, 0xc9, 0x42, 0x3e, 0xc3, 0x31, 0x28, 0x33, 0x00, 0x32, 0x8f, 0xd4, 0xcc, 0x4b, 0x00, - 0x01, 0x26, 0xdb, 0xed, 0x68, 0x3c, 0x9e, 0xd0, 0x82, 0x8d, 0xfe, 0xf6, 0xf4, 0x71, 0xf5, 0x38, 0x0c, 0x82, 0x41, - 0x46, 0x5a, 0x7a, 0x0a, 0xbb, 0x58, 0xab, 0x43, 0x30, 0x82, 0xd7, 0xec, 0xe3, 0x4d, 0xf6, 0xd9, 0xec, 0x23, 0x12, - 0xd6, 0x06, 0xe3, 0xc8, 0x45, 0xda, 0xd2, 0xdb, 0xed, 0x61, 0x30, 0xb9, 0x48, 0x3f, 0xc1, 0x76, 0xfa, 0xfc, 0x9b, - 0x07, 0xe3, 0x09, 0x07, 0xa3, 0xbb, 0x28, 0xe8, 0x33, 0x6d, 0xbb, 0xad, 0xfc, 0x4b, 0xe0, 0x1b, 0x4c, 0x05, 0x1d, - 0x9b, 0x65, 0xe1, 0x06, 0x15, 0x51, 0x47, 0xcb, 0xa0, 0xaa, 0x95, 0xed, 0x1c, 0x50, 0x4b, 0xac, 0xca, 0xc4, 0x2d, - 0x30, 0x0c, 0x19, 0xea, 0x72, 0x4f, 0xab, 0xdf, 0x78, 0x21, 0x0d, 0x7c, 0x86, 0x13, 0x11, 0x7a, 0xdc, 0x1a, 0xf7, - 0xb9, 0x35, 0xf1, 0x09, 0x6e, 0xad, 0x44, 0x12, 0x6b, 0x60, 0x49, 0xcd, 0xe5, 0x28, 0x61, 0x27, 0x25, 0xe3, 0xb3, - 0x32, 0x4a, 0x68, 0x0c, 0x0f, 0x92, 0x89, 0x99, 0x8c, 0x12, 0xb4, 0x4f, 0x74, 0x11, 0x06, 0xff, 0x04, 0xcc, 0x7e, - 0x9a, 0xc3, 0x5f, 0x49, 0xa6, 0xc9, 0x31, 0x04, 0x84, 0x38, 0x1e, 0xcf, 0xe2, 0x70, 0x4c, 0xa2, 0xe4, 0x04, 0x9e, - 0xe0, 0xbf, 0x22, 0x1c, 0x93, 0x5a, 0xdf, 0x61, 0xa4, 0xba, 0xdc, 0x26, 0x0c, 0xe0, 0xca, 0xc6, 0xb3, 0x49, 0x64, - 0xa5, 0xbb, 0xf2, 0xf1, 0x68, 0xfc, 0x94, 0x4c, 0xe3, 0x50, 0x0e, 0x12, 0x42, 0xc1, 0xbb, 0x37, 0x2c, 0x87, 0x89, - 0x86, 0x67, 0x03, 0x36, 0xaf, 0x74, 0x6c, 0x9e, 0x84, 0x13, 0x10, 0x86, 0x09, 0x39, 0xd6, 0x3d, 0x48, 0x29, 0xfa, - 0x3c, 0xc7, 0x7e, 0xea, 0x23, 0x08, 0xb3, 0xa3, 0x96, 0x8a, 0xaf, 0x00, 0xe8, 0x12, 0x07, 0x87, 0xda, 0x33, 0x5f, - 0xcc, 0xc2, 0xd2, 0xa3, 0x52, 0xa6, 0xba, 0x43, 0xd1, 0xa0, 0xfc, 0xa6, 0x41, 0x87, 0x82, 0x0c, 0x26, 0xb4, 0x3c, - 0x99, 0xf0, 0xaf, 0x20, 0x80, 0x47, 0x23, 0xe2, 0x97, 0xc2, 0x89, 0x81, 0xf0, 0x2a, 0xc8, 0x40, 0xa5, 0xb5, 0x6a, - 0xcc, 0xc8, 0x56, 0x7c, 0x00, 0x61, 0x52, 0x0e, 0x6e, 0xe5, 0x3a, 0x4f, 0x21, 0x2a, 0xd8, 0x3a, 0xaf, 0x0e, 0xae, - 0xc0, 0x92, 0x3d, 0xae, 0x20, 0x4e, 0xd8, 0x7a, 0x05, 0xd8, 0xb9, 0x8f, 0x36, 0x65, 0x7d, 0xa0, 0xbe, 0x3b, 0xc0, - 0x96, 0xc3, 0xab, 0x4a, 0x1e, 0x4c, 0xc6, 0xe3, 0xf1, 0xe8, 0x77, 0x38, 0x3a, 0x80, 0xd0, 0x92, 0xc8, 0xf0, 0xc9, - 0x00, 0x8d, 0xbb, 0xae, 0xb8, 0x37, 0x2e, 0x14, 0x65, 0xa5, 0x93, 0x09, 0x01, 0xf1, 0xb3, 0xe9, 0x1b, 0xec, 0x2b, - 0xae, 0xe3, 0x9f, 0xec, 0x7e, 0x62, 0x56, 0xb4, 0x5a, 0xa9, 0xa3, 0x77, 0x6f, 0xcf, 0x5e, 0x7d, 0x78, 0xf5, 0xcb, - 0x8b, 0xf3, 0x57, 0x6f, 0x5e, 0xbe, 0x7a, 0xf3, 0xea, 0xc3, 0xbf, 0x1e, 0x60, 0xb0, 0x7d, 0x5b, 0x11, 0x3b, 0xf6, - 0xde, 0x3d, 0xc6, 0xab, 0xc5, 0x17, 0xce, 0x1e, 0xb9, 0x5b, 0x2c, 0xc0, 0x26, 0x18, 0x6e, 0x41, 0x50, 0xcd, 0x68, - 0x54, 0xfa, 0x9e, 0x80, 0x8c, 0x46, 0x85, 0x6c, 0x3c, 0xac, 0xd8, 0x0a, 0xb9, 0x78, 0xc7, 0x70, 0xf0, 0x91, 0xfd, - 0xad, 0x38, 0x13, 0x6e, 0x47, 0x5b, 0xb3, 0x22, 0xe0, 0xf3, 0xb5, 0x16, 0x95, 0xc7, 0x85, 0xa8, 0xbd, 0x6d, 0x9f, - 0x43, 0x42, 0x3d, 0x22, 0xd7, 0xc1, 0xfb, 0x36, 0xc8, 0x1e, 0x1f, 0x79, 0x4f, 0xca, 0x33, 0xd4, 0xe7, 0x68, 0xf8, - 0xa8, 0xf1, 0x8c, 0x4e, 0xcc, 0xb5, 0xd1, 0xa1, 0x9e, 0x17, 0xb0, 0xbf, 0x95, 0x18, 0x1b, 0xa2, 0x3d, 0xa4, 0x88, - 0xf5, 0xe1, 0x74, 0xbf, 0xbb, 0x37, 0xa3, 0xef, 0xe0, 0xf8, 0x51, 0xaa, 0x09, 0xa4, 0x45, 0x81, 0xd2, 0x95, 0x21, - 0xb7, 0x3d, 0x0b, 0x0b, 0xf3, 0x33, 0x6c, 0x10, 0x40, 0x7b, 0xd9, 0xb1, 0x24, 0xd0, 0x2c, 0x5e, 0xeb, 0xfa, 0xe7, - 0xe5, 0xcb, 0x44, 0x3b, 0x5f, 0x7c, 0x07, 0x21, 0x86, 0xfd, 0x2b, 0x42, 0x63, 0xc2, 0xdd, 0x24, 0xbb, 0x4b, 0x8b, - 0xb9, 0x57, 0x5d, 0xc7, 0x78, 0xdc, 0xed, 0xb9, 0x52, 0x34, 0x6f, 0x5d, 0x60, 0x0f, 0xd4, 0xbc, 0x8e, 0x97, 0x2c, - 0x04, 0x6c, 0xc6, 0x43, 0xbb, 0x48, 0x9c, 0xdf, 0x3b, 0x9d, 0x90, 0xc3, 0xa3, 0x29, 0x1f, 0xb2, 0x92, 0x8a, 0x01, - 0x2b, 0xeb, 0x1d, 0x6a, 0xce, 0xdb, 0x84, 0x5c, 0xec, 0xd2, 0x70, 0x31, 0xe4, 0x0f, 0x5d, 0x92, 0x3e, 0xf0, 0x86, - 0x43, 0xb5, 0x6d, 0x2e, 0x86, 0x34, 0xe5, 0x74, 0x97, 0xca, 0x80, 0x10, 0xe9, 0x3a, 0xae, 0x48, 0xad, 0x8f, 0xaa, - 0xd4, 0x49, 0x3a, 0x6e, 0xb2, 0xcd, 0x27, 0x2e, 0xd9, 0xea, 0x76, 0xed, 0x5f, 0xab, 0xdb, 0x17, 0x66, 0x20, 0x7f, - 0x7f, 0x20, 0xaa, 0x89, 0x81, 0xe8, 0x02, 0x2a, 0xf8, 0x07, 0x78, 0x79, 0xf2, 0x48, 0x2b, 0x40, 0xf7, 0x9d, 0x1d, - 0x5d, 0x7b, 0xbc, 0x31, 0x8b, 0xad, 0x25, 0xce, 0x59, 0xe5, 0x3b, 0xcb, 0xab, 0xb2, 0x15, 0xba, 0x8e, 0x60, 0xbf, - 0x85, 0x1d, 0x7d, 0xf7, 0xb6, 0x01, 0x10, 0xa5, 0xb0, 0x72, 0x67, 0xbf, 0xf0, 0xce, 0x7e, 0x61, 0xcf, 0x7e, 0xbb, - 0x09, 0x94, 0x0f, 0x2b, 0xb4, 0xec, 0xa5, 0x14, 0x95, 0x69, 0xf2, 0xb8, 0xa9, 0xcb, 0x42, 0x5a, 0xcc, 0x0f, 0x2d, - 0xed, 0x7a, 0x32, 0xa6, 0x12, 0xd5, 0x23, 0xdf, 0x63, 0xab, 0x0e, 0x4b, 0xf2, 0xf0, 0x3d, 0xf3, 0x7f, 0xf6, 0x06, - 0xb9, 0xef, 0x6e, 0xf7, 0x7f, 0x73, 0xa1, 0x83, 0xdb, 0x5a, 0x2a, 0x3c, 0x75, 0x75, 0x5c, 0xe0, 0x5d, 0x2d, 0x7d, - 0xf8, 0xae, 0xf6, 0x2e, 0xd3, 0xcb, 0xae, 0x02, 0xd4, 0x20, 0xb1, 0xbe, 0xe6, 0x45, 0x96, 0xd4, 0x56, 0xa1, 0xf1, - 0x96, 0x43, 0x68, 0x0f, 0xef, 0xe0, 0x02, 0x39, 0x2c, 0x21, 0xf4, 0x63, 0x65, 0x04, 0x80, 0x3e, 0x8b, 0xfd, 0x96, - 0x87, 0x19, 0x19, 0xf8, 0x12, 0xbf, 0x52, 0xfa, 0xe2, 0xe2, 0xc3, 0x9d, 0xcc, 0x04, 0xbd, 0x4a, 0x6c, 0x76, 0x29, - 0xdb, 0x31, 0x3f, 0xfc, 0x2f, 0x30, 0x1a, 0x84, 0xd7, 0x96, 0xec, 0x50, 0x74, 0xcc, 0x72, 0x05, 0x47, 0x6d, 0xe9, - 0xca, 0x2c, 0x5b, 0xd7, 0xcf, 0x6a, 0x98, 0xe9, 0x33, 0xe5, 0x2d, 0xc8, 0xbe, 0x90, 0xbb, 0x9f, 0xea, 0x8a, 0x05, - 0x39, 0x99, 0x8c, 0xa7, 0x44, 0x0c, 0x06, 0xad, 0xe4, 0x63, 0x4c, 0x1e, 0x0e, 0x77, 0x98, 0x4b, 0xa1, 0xfb, 0xe1, - 0xf5, 0x01, 0xea, 0x6b, 0x6c, 0x49, 0xb2, 0xa9, 0xd8, 0x9f, 0x60, 0x16, 0x0b, 0xc4, 0xd1, 0xc1, 0x2f, 0xce, 0x17, - 0x00, 0xb2, 0x0c, 0xcb, 0x4c, 0x0b, 0x8b, 0xca, 0x54, 0xf9, 0xc8, 0x16, 0x4c, 0x1e, 0x8f, 0x67, 0x7e, 0xcf, 0x1d, - 0x83, 0x43, 0x48, 0x34, 0xb1, 0xc6, 0x2f, 0x7e, 0x16, 0x8c, 0xe3, 0x50, 0x9e, 0xc8, 0xc6, 0x77, 0x25, 0x89, 0xc6, - 0xc6, 0x54, 0x59, 0x5f, 0x25, 0xaa, 0x61, 0x42, 0x1e, 0x17, 0xe4, 0xb0, 0xa0, 0x4b, 0x7f, 0x2c, 0x31, 0xfd, 0x30, - 0x3e, 0x9c, 0x8c, 0xc9, 0xe3, 0xf8, 0xf1, 0xc4, 0xc0, 0x0d, 0xfb, 0x39, 0xf2, 0xe1, 0x92, 0x1c, 0x36, 0xab, 0x04, - 0x53, 0x54, 0xd3, 0x33, 0xbf, 0x92, 0x64, 0xb0, 0x1c, 0xa4, 0x8f, 0x5b, 0x79, 0xb1, 0x56, 0x3d, 0xde, 0xeb, 0x63, - 0x3e, 0x25, 0xa2, 0x71, 0x63, 0x58, 0xd3, 0xeb, 0xf8, 0x0f, 0x59, 0x44, 0xa5, 0x04, 0x44, 0x42, 0x50, 0x6f, 0x67, - 0x97, 0x59, 0x12, 0x8b, 0x34, 0x4a, 0x6b, 0x42, 0xd3, 0x13, 0x36, 0x19, 0xcf, 0x52, 0x96, 0x1e, 0x4f, 0x9e, 0xce, - 0x26, 0x4f, 0xa3, 0xa3, 0x71, 0x94, 0x0e, 0x06, 0x90, 0x7c, 0x34, 0x06, 0x17, 0x3b, 0xf8, 0xcd, 0x8e, 0x60, 0xe8, - 0x4e, 0x90, 0x25, 0x2c, 0xa0, 0x69, 0x9f, 0xd7, 0x24, 0x3d, 0x9c, 0x97, 0xaa, 0x27, 0xf1, 0x1d, 0x5d, 0x7b, 0x0e, - 0x2e, 0x7e, 0x0b, 0x2f, 0x5d, 0x0b, 0x2f, 0x77, 0x5b, 0x28, 0x4c, 0xdc, 0x14, 0xf9, 0xff, 0xe3, 0x86, 0xb1, 0xef, - 0x2e, 0x61, 0x16, 0xd7, 0x4d, 0x36, 0x5a, 0x15, 0xb2, 0x92, 0x70, 0x9b, 0x50, 0xa2, 0xb0, 0x51, 0xbc, 0x5a, 0xe5, - 0xda, 0x45, 0x6c, 0x5e, 0x51, 0x00, 0x77, 0x81, 0x38, 0xc5, 0xc0, 0x42, 0x1b, 0x03, 0xb9, 0xbf, 0x78, 0x21, 0x99, - 0x55, 0xfb, 0x98, 0x7b, 0xe4, 0x1f, 0x21, 0x18, 0xa3, 0x8a, 0x93, 0xf1, 0x4c, 0x61, 0x5d, 0x7c, 0x4a, 0xde, 0xfb, - 0x6f, 0x1c, 0x45, 0xf6, 0x68, 0x06, 0x3d, 0x41, 0xe4, 0x3c, 0xe2, 0xec, 0xc9, 0xe4, 0x65, 0xe0, 0x7e, 0x06, 0x2b, - 0xfd, 0x75, 0xb7, 0x19, 0x6b, 0xdb, 0xa3, 0x7b, 0x61, 0x84, 0xa2, 0x7f, 0xe1, 0x3b, 0x53, 0x2f, 0xe0, 0x12, 0xaa, - 0x81, 0x5d, 0x5f, 0x5d, 0xf1, 0x12, 0x40, 0x84, 0x32, 0xd1, 0xef, 0xf7, 0xfe, 0x30, 0xd0, 0xa4, 0x25, 0x2f, 0x5e, - 0x67, 0xc2, 0x3a, 0xe3, 0x40, 0x53, 0x81, 0xfa, 0x7f, 0xac, 0xec, 0x33, 0x1d, 0x93, 0x99, 0xff, 0x38, 0x9c, 0x90, - 0xa8, 0xf9, 0x9a, 0x7c, 0xe2, 0x34, 0xfd, 0xc4, 0x15, 0xed, 0x3f, 0x90, 0x99, 0x1b, 0x0e, 0x19, 0xea, 0x2f, 0x1d, - 0xf3, 0x64, 0xf4, 0x3a, 0x31, 0x3b, 0x11, 0xac, 0x9a, 0x41, 0x14, 0xf6, 0x02, 0x1e, 0xd4, 0xb5, 0x2c, 0x9e, 0xc2, - 0xec, 0x83, 0x1a, 0x51, 0x1c, 0xb3, 0xf1, 0x2c, 0x94, 0xe1, 0x04, 0xec, 0x7b, 0x27, 0x63, 0xb8, 0x0f, 0xc8, 0xf0, - 0x63, 0x15, 0x62, 0xe7, 0x20, 0xed, 0x63, 0x85, 0x8a, 0x09, 0x80, 0x08, 0x84, 0xbc, 0xfd, 0xbe, 0x54, 0x49, 0xf8, - 0xba, 0xc4, 0x94, 0x42, 0x7d, 0xf0, 0x9f, 0x48, 0xd5, 0x1d, 0xd3, 0xaf, 0xd6, 0x8f, 0x3f, 0x13, 0x8a, 0x4f, 0x77, - 0x29, 0xf1, 0x1d, 0x04, 0x77, 0x96, 0xa0, 0x83, 0xa8, 0xd0, 0x8c, 0xed, 0x61, 0x7e, 0x57, 0xec, 0xe7, 0x77, 0xc5, - 0xff, 0x3b, 0x7e, 0x57, 0x3c, 0xc4, 0x18, 0x56, 0x16, 0x1a, 0x7e, 0x16, 0x8c, 0x83, 0xe8, 0x3f, 0xe7, 0x13, 0xf7, - 0xf2, 0xd4, 0xd7, 0x99, 0x98, 0xee, 0x61, 0x9a, 0x7d, 0x82, 0x82, 0xb0, 0x8a, 0xbb, 0xf4, 0x64, 0x5d, 0xd9, 0x5b, - 0x2b, 0x19, 0x62, 0x9e, 0x07, 0x58, 0xa3, 0xb0, 0xf2, 0x80, 0xee, 0x51, 0xb5, 0x41, 0x9c, 0x08, 0x1e, 0xc6, 0xcc, - 0x4a, 0xdf, 0xb7, 0x5b, 0xa3, 0xc2, 0x7c, 0x90, 0x8b, 0x82, 0xec, 0xe6, 0xe3, 0xd9, 0x38, 0x0a, 0xb1, 0x01, 0xff, - 0x31, 0x63, 0xd5, 0x90, 0xcd, 0x77, 0x32, 0x52, 0x3b, 0x26, 0x4f, 0x93, 0x5d, 0xd2, 0x3b, 0xe0, 0x1d, 0xf2, 0x73, - 0x70, 0x67, 0x93, 0x86, 0xdf, 0x92, 0x57, 0x71, 0x91, 0x55, 0xcb, 0xeb, 0x2c, 0x41, 0xa6, 0x0b, 0x5e, 0x7c, 0x36, - 0xd3, 0xe5, 0x7d, 0xac, 0x0f, 0x18, 0x4f, 0x29, 0x5e, 0x37, 0x44, 0xe9, 0xeb, 0x96, 0x67, 0x85, 0xba, 0x3c, 0xa9, - 0x98, 0xed, 0x59, 0x09, 0x4e, 0xa7, 0x60, 0x82, 0xaf, 0x7f, 0xba, 0xde, 0x27, 0x80, 0x0b, 0x0a, 0x35, 0xa7, 0x85, - 0x5c, 0x19, 0x2c, 0x27, 0x0b, 0xdd, 0x09, 0x98, 0xa1, 0x52, 0xe0, 0x05, 0x0a, 0xfe, 0xa2, 0x81, 0x11, 0x7d, 0xe9, - 0x7e, 0x93, 0x81, 0x41, 0xba, 0x34, 0x27, 0xc2, 0xd8, 0x71, 0x3b, 0x45, 0xda, 0x8a, 0x72, 0xc6, 0xd9, 0x7b, 0x75, - 0xa5, 0x00, 0x03, 0xbc, 0xcd, 0x6d, 0x74, 0x91, 0xa0, 0xd7, 0x82, 0xd2, 0x79, 0x03, 0x77, 0xb3, 0x8c, 0x8c, 0x70, - 0xf1, 0x71, 0xe5, 0xb1, 0xe0, 0x9e, 0xfd, 0x42, 0x2c, 0x8d, 0x66, 0x1a, 0x8c, 0xd9, 0xbc, 0x60, 0x81, 0x42, 0x05, - 0x0a, 0x2c, 0x67, 0xda, 0xd2, 0xb4, 0x1a, 0xf2, 0xc3, 0x23, 0xb4, 0x36, 0xad, 0x06, 0xfc, 0xf0, 0xa8, 0x8e, 0xb2, - 0x63, 0xc8, 0x72, 0xe2, 0x67, 0x50, 0xaf, 0xeb, 0xc8, 0xa4, 0x98, 0xec, 0x7e, 0x7d, 0xa9, 0x3f, 0xaa, 0x1b, 0x70, - 0xfd, 0x00, 0x04, 0xb0, 0x01, 0x38, 0x04, 0xaa, 0xc1, 0xd2, 0x88, 0x60, 0x51, 0xa6, 0xd0, 0xbe, 0x86, 0xde, 0x1b, - 0x0d, 0xff, 0x05, 0xee, 0x22, 0x72, 0xe5, 0x7f, 0x82, 0xc0, 0x5f, 0x51, 0xa6, 0x95, 0x29, 0xfe, 0x27, 0x5a, 0xbd, - 0x42, 0x39, 0x6b, 0x5a, 0xf3, 0x41, 0xb4, 0x26, 0x42, 0x35, 0x63, 0x08, 0xfe, 0xad, 0x2c, 0xd3, 0x96, 0xaa, 0x4a, - 0x7d, 0x68, 0xbc, 0xd6, 0x0a, 0x67, 0xf9, 0x38, 0xf2, 0x5e, 0x63, 0xe8, 0xd8, 0xc4, 0x59, 0xca, 0xa9, 0xd4, 0xd9, - 0x9b, 0x43, 0x19, 0x39, 0xc0, 0xe9, 0x84, 0x8d, 0xa7, 0xc9, 0xb1, 0x9c, 0x26, 0x0e, 0x32, 0x3f, 0x67, 0x18, 0x59, - 0xd5, 0x80, 0xb0, 0x28, 0x1b, 0x4a, 0x5b, 0x80, 0x49, 0x4e, 0x08, 0x99, 0x62, 0x28, 0x8a, 0x7c, 0xa4, 0xfb, 0x61, - 0xbd, 0x59, 0xdd, 0x17, 0xef, 0x34, 0xc0, 0x69, 0x98, 0x40, 0x20, 0xf0, 0x22, 0xbe, 0xcd, 0xc4, 0x15, 0x78, 0x0c, - 0x0f, 0xe0, 0x4b, 0x70, 0x93, 0x4b, 0xd9, 0xaf, 0x55, 0x98, 0xe3, 0xda, 0x02, 0x06, 0x0d, 0x56, 0x0f, 0xa2, 0xc3, - 0xa5, 0xb4, 0xd9, 0x55, 0x80, 0xd8, 0x98, 0x42, 0x2c, 0x0b, 0xb6, 0xb6, 0xec, 0xd9, 0x4f, 0xaa, 0x69, 0x68, 0x9d, - 0x70, 0x2a, 0xae, 0x72, 0x88, 0xa2, 0x32, 0x88, 0xc1, 0x1d, 0xc9, 0xe3, 0xf3, 0x1e, 0x89, 0xf0, 0x92, 0x80, 0x5b, - 0x59, 0x2c, 0xc3, 0x15, 0x5d, 0x8e, 0xee, 0xe8, 0x7a, 0x74, 0x4b, 0xc7, 0x74, 0xf2, 0xf7, 0x31, 0x58, 0x64, 0xeb, - 0xd4, 0x7b, 0xba, 0x1e, 0x2d, 0xe9, 0x37, 0x63, 0x7a, 0xf4, 0x37, 0x30, 0xe1, 0xc3, 0xc3, 0x84, 0x5e, 0x82, 0x63, - 0x17, 0xa9, 0xd1, 0x53, 0xd3, 0x37, 0x38, 0xac, 0x46, 0xf9, 0x90, 0x8f, 0x72, 0xca, 0x47, 0xc5, 0xb0, 0x1a, 0x81, - 0xa7, 0x63, 0x35, 0xe4, 0xa3, 0x8a, 0xf2, 0xd1, 0xc5, 0xb0, 0x1a, 0x5d, 0x90, 0x66, 0xd3, 0x5f, 0x55, 0xfc, 0xba, - 0x64, 0x29, 0x6c, 0x0b, 0x58, 0xbe, 0x9e, 0x57, 0x54, 0xea, 0xaf, 0x6a, 0x73, 0x32, 0x5b, 0xce, 0xde, 0x5e, 0x77, - 0x39, 0xb1, 0x78, 0xdc, 0x36, 0x1d, 0xae, 0xbe, 0x9c, 0xa8, 0x93, 0x5e, 0x21, 0x3f, 0x8c, 0xa7, 0x42, 0x9d, 0x43, - 0x60, 0x26, 0x31, 0x0b, 0x63, 0x86, 0xcd, 0xd4, 0x69, 0xa0, 0xc0, 0xc9, 0x46, 0x9e, 0x8b, 0x62, 0x36, 0xca, 0x29, - 0xbc, 0x8f, 0x09, 0x89, 0x04, 0x9c, 0x55, 0x27, 0xd5, 0xa8, 0x80, 0x98, 0x23, 0x2c, 0xc4, 0x47, 0xe8, 0x97, 0xfa, - 0xc8, 0x43, 0x02, 0xcf, 0xb0, 0xaf, 0xc5, 0x20, 0x86, 0x23, 0xde, 0x56, 0x56, 0xcd, 0xc2, 0x04, 0x2a, 0xab, 0x86, - 0xa5, 0xa9, 0xac, 0xa0, 0xd9, 0xa8, 0xf2, 0x2b, 0xab, 0x70, 0x8c, 0x12, 0x42, 0xa2, 0x52, 0x57, 0x06, 0xea, 0x93, - 0x84, 0x85, 0xa5, 0xae, 0xec, 0x42, 0x7d, 0x74, 0xe1, 0x57, 0x76, 0x01, 0x2e, 0xa4, 0x83, 0xc4, 0xbf, 0x4a, 0xe5, - 0x69, 0xfb, 0x3a, 0xd8, 0x58, 0x55, 0x74, 0xc3, 0xef, 0xaa, 0x22, 0x8e, 0x4a, 0xea, 0x62, 0x40, 0xe3, 0xc2, 0x88, - 0x24, 0xd5, 0x6b, 0x14, 0xfc, 0x21, 0x41, 0x54, 0x1a, 0x83, 0x57, 0x67, 0xd2, 0xb5, 0x52, 0x2b, 0x2a, 0x06, 0xe5, - 0xa0, 0x80, 0xfb, 0x53, 0xde, 0x5a, 0x48, 0x3f, 0x41, 0x44, 0x65, 0x28, 0x6f, 0xf0, 0x4f, 0x0c, 0x9e, 0xcc, 0x56, - 0x69, 0x98, 0x8c, 0xee, 0x69, 0x3c, 0x5a, 0x22, 0x1c, 0x0c, 0x5b, 0xa7, 0x0a, 0x6f, 0xfd, 0x12, 0xd2, 0xef, 0x68, - 0x3c, 0xba, 0xa5, 0xa9, 0xb5, 0x39, 0x35, 0x50, 0x57, 0xbd, 0x31, 0xbd, 0x8b, 0xe0, 0xf5, 0x7d, 0xb4, 0xa4, 0xb0, - 0x95, 0x4e, 0xf3, 0xec, 0x4a, 0x44, 0x29, 0x45, 0x04, 0xc2, 0x35, 0x22, 0x07, 0x2e, 0x35, 0xda, 0xe0, 0x7a, 0x00, - 0x65, 0x68, 0xb8, 0xc0, 0xe5, 0x20, 0x1e, 0x2d, 0x3d, 0x32, 0xb5, 0xd4, 0x17, 0x59, 0x84, 0x8f, 0x76, 0x36, 0x5a, - 0x8a, 0x67, 0xc4, 0xc2, 0xb8, 0x82, 0x21, 0xd4, 0x85, 0x95, 0xa6, 0x20, 0xe9, 0x02, 0x47, 0xf6, 0xc2, 0xb8, 0x0a, - 0x37, 0x60, 0x5a, 0x74, 0x0f, 0xe6, 0x51, 0xa0, 0x70, 0x70, 0x09, 0xd2, 0x4f, 0x28, 0xdb, 0x39, 0x4a, 0x93, 0xc3, - 0x9b, 0xa0, 0x74, 0x67, 0x82, 0x90, 0x76, 0x75, 0x93, 0x2d, 0xe9, 0x1b, 0x6c, 0xef, 0xd0, 0xa9, 0xa8, 0xa0, 0xfa, - 0xdc, 0x82, 0xc9, 0x92, 0x0d, 0xc2, 0x96, 0x30, 0x3d, 0xd3, 0x6b, 0xc0, 0x9e, 0x3e, 0x3c, 0xda, 0x99, 0xef, 0x62, - 0xf6, 0xe6, 0xb0, 0x8c, 0xc6, 0xca, 0x82, 0x37, 0xb7, 0xc4, 0x6e, 0xc9, 0xc6, 0xd3, 0xe5, 0x71, 0x39, 0x5d, 0x22, - 0xb1, 0x33, 0x74, 0x8b, 0xf1, 0xf9, 0x72, 0x41, 0x13, 0x3c, 0xdb, 0x58, 0x35, 0x5f, 0x1a, 0xb4, 0x94, 0x94, 0xe1, - 0x7a, 0x5b, 0xa2, 0xff, 0xbf, 0xba, 0xf8, 0xa5, 0x00, 0x2f, 0xc1, 0x58, 0x00, 0x08, 0xf7, 0x60, 0x5a, 0x90, 0xda, - 0x28, 0x1b, 0xcb, 0x34, 0x4c, 0x71, 0x11, 0x98, 0x94, 0x7e, 0x3f, 0xcc, 0x59, 0x4a, 0x3c, 0xe8, 0x50, 0x77, 0x6a, - 0xa7, 0xbe, 0x10, 0x04, 0x78, 0x24, 0x75, 0x8e, 0x4d, 0xfe, 0x3e, 0x9e, 0x05, 0x6a, 0x20, 0x82, 0x28, 0x3b, 0xc6, - 0x47, 0x0c, 0x5c, 0x14, 0xe9, 0xb8, 0x9d, 0xae, 0x88, 0xcb, 0xdd, 0x63, 0x16, 0xe2, 0x24, 0x61, 0xae, 0x59, 0x36, - 0x64, 0x55, 0x84, 0x09, 0xba, 0x30, 0x30, 0xcb, 0x1b, 0xb2, 0xea, 0xf0, 0x08, 0x22, 0xb5, 0xda, 0x32, 0x56, 0x5d, - 0x65, 0x7c, 0x03, 0x40, 0xd6, 0x8c, 0xb1, 0xa3, 0xbf, 0x8d, 0x67, 0xea, 0x9b, 0x28, 0xe4, 0x27, 0x47, 0x7f, 0x83, - 0xe4, 0xe3, 0x6f, 0x90, 0x99, 0x83, 0xe4, 0x46, 0x41, 0x57, 0xcd, 0x59, 0xd7, 0x50, 0x9a, 0xb8, 0xf6, 0x4a, 0xbd, - 0xf6, 0xa4, 0x59, 0x7b, 0x05, 0xba, 0x53, 0x1b, 0xde, 0x43, 0xd9, 0xce, 0x82, 0x09, 0x3a, 0x9a, 0xdd, 0x81, 0x0e, - 0xde, 0x29, 0x82, 0x5e, 0x24, 0xa1, 0xf1, 0x08, 0x55, 0x46, 0xbd, 0x18, 0x0f, 0xaa, 0x93, 0x75, 0xc9, 0x3c, 0x03, - 0xe6, 0xd8, 0x9e, 0x43, 0x62, 0x98, 0xab, 0x83, 0x3a, 0x65, 0xe5, 0x30, 0xc7, 0x03, 0x78, 0xcd, 0xe4, 0x50, 0x0c, - 0x72, 0x8d, 0xf2, 0x7d, 0xc9, 0x8a, 0x61, 0x39, 0xc8, 0x35, 0x37, 0x33, 0x6d, 0xc6, 0xa6, 0x4d, 0x74, 0x78, 0xe6, - 0x15, 0x3b, 0x59, 0xf5, 0x80, 0x8f, 0x05, 0x4f, 0x66, 0xdf, 0xf3, 0xf1, 0x35, 0x70, 0x32, 0x9b, 0xbb, 0x68, 0x49, - 0xef, 0xa3, 0x94, 0xde, 0x46, 0x6b, 0xba, 0x8c, 0x2e, 0x8d, 0x89, 0x71, 0x52, 0xc3, 0x39, 0x00, 0xad, 0x02, 0x48, - 0x3c, 0xf5, 0xeb, 0x3d, 0x4f, 0xaa, 0x70, 0x49, 0x53, 0x70, 0x1b, 0xf6, 0xed, 0x33, 0xaf, 0x7d, 0x89, 0xd4, 0x06, - 0x31, 0xd6, 0xac, 0xa1, 0xe2, 0xc6, 0x5b, 0xf7, 0x91, 0xa8, 0x61, 0xe7, 0xba, 0xd8, 0x44, 0xd5, 0x70, 0x32, 0x2d, - 0x01, 0xb1, 0xb5, 0x1c, 0x0e, 0xdd, 0x11, 0xb2, 0x7b, 0xfc, 0xe8, 0x40, 0xcf, 0x3d, 0x69, 0xb1, 0x6d, 0x5b, 0xfe, - 0xc0, 0x10, 0xa6, 0xf4, 0xd3, 0x47, 0x3e, 0x20, 0x56, 0x5c, 0xc1, 0xd9, 0x08, 0xd4, 0xd1, 0x0a, 0x9d, 0x7e, 0xad, - 0xc2, 0x42, 0x1f, 0xe0, 0x9b, 0xbb, 0x28, 0xa1, 0xf7, 0x51, 0xee, 0x91, 0xb5, 0x65, 0xcd, 0xe4, 0xf4, 0x3c, 0x0b, - 0x79, 0xfb, 0x40, 0x2f, 0x17, 0x00, 0xa2, 0x35, 0x88, 0x7d, 0xa9, 0xeb, 0x11, 0x38, 0x0d, 0xa1, 0x49, 0x68, 0x04, - 0x57, 0x15, 0x84, 0x11, 0x70, 0x25, 0xe1, 0x6f, 0x30, 0x51, 0x81, 0x2f, 0xc0, 0x45, 0x26, 0x4d, 0x73, 0x1e, 0xd4, - 0xfe, 0x48, 0x9e, 0x15, 0x6d, 0x6f, 0x57, 0x18, 0x4d, 0x30, 0xf6, 0x44, 0xfb, 0x3c, 0x52, 0x8e, 0xe2, 0x22, 0x09, - 0xb3, 0xd1, 0x9d, 0x3a, 0xcf, 0x69, 0x36, 0xba, 0xd7, 0xbf, 0x2a, 0x3a, 0xa6, 0xbf, 0xe8, 0x80, 0x36, 0x4a, 0xfa, - 0xd6, 0x71, 0x36, 0xa0, 0xf5, 0x62, 0x69, 0xfc, 0xaf, 0xe5, 0xe8, 0x8e, 0xca, 0xd1, 0xbd, 0x6f, 0x49, 0x35, 0x99, - 0x16, 0xc7, 0x02, 0x0d, 0xa9, 0x3a, 0xbf, 0x2f, 0x80, 0x9f, 0x2b, 0x8d, 0xef, 0xb4, 0xf9, 0xde, 0x6b, 0xff, 0x45, - 0x27, 0x4f, 0xa0, 0x58, 0xa2, 0x82, 0x55, 0x23, 0xb0, 0x63, 0x5f, 0xe7, 0x71, 0x61, 0x46, 0x29, 0xa6, 0xd6, 0xa4, - 0x1f, 0x03, 0x57, 0x4c, 0x7b, 0x05, 0xb8, 0x5a, 0x82, 0x93, 0x00, 0xc4, 0xd0, 0x84, 0x3d, 0x3b, 0x86, 0xa8, 0xe7, - 0xc6, 0x31, 0x4a, 0x36, 0xdc, 0x03, 0x62, 0x2d, 0xf3, 0x56, 0x2e, 0x01, 0x09, 0xbc, 0xf5, 0x30, 0x29, 0x00, 0x63, - 0xb0, 0x5c, 0x12, 0x9d, 0xc7, 0x43, 0x9f, 0x50, 0x2f, 0x34, 0xea, 0x84, 0x6c, 0x6c, 0x09, 0x1c, 0x7f, 0x58, 0x1f, - 0x02, 0xc1, 0xab, 0x3c, 0xd7, 0x5f, 0x69, 0x5d, 0x7f, 0xa9, 0xf4, 0xdc, 0xb1, 0x5c, 0xd7, 0xcf, 0xdb, 0xd4, 0xe8, - 0x25, 0x58, 0xf8, 0x6e, 0x94, 0x79, 0x24, 0xb7, 0x08, 0xa9, 0x0a, 0xac, 0xd4, 0x2d, 0x24, 0x98, 0x7f, 0x25, 0x67, - 0xab, 0x32, 0x5f, 0x3d, 0xf2, 0xa0, 0x9c, 0x4d, 0x4f, 0x7f, 0x43, 0x82, 0x76, 0xdf, 0x91, 0xe6, 0xf1, 0x16, 0x1d, - 0x3e, 0xbb, 0xd6, 0x12, 0x73, 0x27, 0x51, 0xf1, 0x7c, 0x0a, 0xd8, 0xea, 0x79, 0x76, 0xad, 0x7c, 0xac, 0x76, 0x71, - 0xfc, 0xcc, 0xf9, 0x93, 0x54, 0xe1, 0x5a, 0x34, 0x94, 0x20, 0xe0, 0xcd, 0x61, 0xec, 0x0a, 0x55, 0x40, 0x43, 0x73, - 0x03, 0xc7, 0xb9, 0x1a, 0x56, 0x9a, 0x80, 0x69, 0x29, 0x8f, 0x0e, 0x70, 0x68, 0xf2, 0xa8, 0xdd, 0x34, 0xac, 0x0c, - 0x5d, 0x6b, 0xf4, 0xb9, 0xad, 0x74, 0xc6, 0x9b, 0x0d, 0x3f, 0x3c, 0x1a, 0x54, 0xf8, 0x93, 0x34, 0x47, 0xa3, 0x9d, - 0x1b, 0xee, 0x34, 0x02, 0x33, 0x57, 0x72, 0x45, 0x76, 0x47, 0xc9, 0xcb, 0xef, 0xe9, 0x85, 0x05, 0xf4, 0xe7, 0x3f, - 0x17, 0x13, 0x4e, 0x5a, 0x62, 0x42, 0xb4, 0x74, 0xd0, 0xa2, 0x83, 0x1d, 0xe5, 0x95, 0x7d, 0x89, 0x97, 0xce, 0xf1, - 0xbf, 0xaf, 0xc7, 0xda, 0x55, 0x20, 0xb4, 0x3a, 0x79, 0xd8, 0x9e, 0x2c, 0x10, 0x35, 0xa0, 0x9a, 0x5d, 0x95, 0xa3, - 0x4c, 0x3b, 0x2b, 0xb2, 0x69, 0xc8, 0x5c, 0x77, 0xb3, 0x34, 0x6c, 0x26, 0x3b, 0x16, 0x96, 0x19, 0x06, 0x6b, 0xa7, - 0x8a, 0x3e, 0x07, 0x2d, 0x3f, 0x82, 0xe7, 0x4d, 0xe5, 0x99, 0xcf, 0x66, 0x19, 0xf1, 0x02, 0x9d, 0x73, 0x2a, 0x16, - 0x4d, 0xe9, 0x58, 0xb9, 0xdd, 0x96, 0x68, 0x2c, 0x51, 0x46, 0x41, 0x50, 0xdb, 0x20, 0xec, 0xba, 0x74, 0x4f, 0xfa, - 0xb4, 0x8b, 0x4f, 0x2b, 0xd0, 0xf7, 0x78, 0x9f, 0x81, 0xc4, 0xd4, 0x93, 0x3c, 0x54, 0x8d, 0xe6, 0xe8, 0xe4, 0x59, - 0x9c, 0x6a, 0x7c, 0x7e, 0x25, 0x3b, 0x6b, 0xde, 0xad, 0xc6, 0x14, 0xff, 0x91, 0xba, 0x7d, 0xe7, 0x32, 0x34, 0xd1, - 0x5f, 0xcb, 0x83, 0x96, 0xc2, 0x82, 0xe3, 0xb6, 0xf1, 0xd7, 0x6f, 0x33, 0x87, 0x18, 0x96, 0x2e, 0x87, 0x37, 0xa1, - 0x43, 0x77, 0x57, 0xd9, 0x99, 0xeb, 0x23, 0xea, 0xd4, 0xc5, 0xba, 0x0d, 0x28, 0x59, 0xf2, 0x6e, 0x9d, 0x9e, 0x58, - 0xe9, 0x97, 0xc3, 0x70, 0x67, 0x1e, 0x35, 0xbb, 0xbb, 0xdd, 0x4e, 0x48, 0xdb, 0x3e, 0x18, 0xef, 0x4b, 0x58, 0x88, - 0xf3, 0x0e, 0x3b, 0xf8, 0x29, 0xac, 0x1e, 0xf3, 0xc1, 0x6f, 0x38, 0xce, 0x30, 0xfa, 0x99, 0x32, 0xf4, 0x79, 0x59, - 0xc8, 0x6b, 0xd5, 0x29, 0x5f, 0xe8, 0xd6, 0x32, 0xf5, 0x7e, 0x13, 0xbf, 0x69, 0x05, 0x88, 0xf1, 0xba, 0x62, 0xa5, - 0x78, 0x43, 0x2b, 0x8c, 0x6b, 0xe0, 0x36, 0x39, 0xd4, 0x52, 0x2d, 0x10, 0x75, 0xf9, 0xc9, 0x63, 0x1e, 0x19, 0x75, - 0x26, 0x7c, 0xf7, 0x98, 0xfb, 0xd2, 0xb5, 0xdd, 0x26, 0x7e, 0xaa, 0x69, 0x87, 0xbb, 0x03, 0xdd, 0xd1, 0xba, 0x87, - 0x9b, 0x67, 0xf3, 0xf3, 0xc8, 0x7c, 0x31, 0xc0, 0x66, 0xed, 0x32, 0x2e, 0x3b, 0x86, 0xfb, 0xde, 0xf4, 0x60, 0x2c, - 0x20, 0x90, 0x98, 0xa1, 0x97, 0x81, 0x0b, 0x5c, 0xe0, 0xae, 0x30, 0x60, 0x88, 0x6b, 0x5a, 0x72, 0xae, 0xad, 0x6c, - 0x7d, 0xe4, 0x6d, 0x54, 0x08, 0xd6, 0x75, 0xc7, 0x4d, 0x92, 0x43, 0x70, 0xc2, 0x96, 0x7b, 0x5f, 0x7b, 0xed, 0x0c, - 0xff, 0x39, 0x10, 0xce, 0x2d, 0xd1, 0x33, 0x6a, 0x7b, 0xac, 0xd5, 0xbd, 0x86, 0x57, 0xb9, 0x8f, 0x3c, 0xeb, 0x37, - 0xf3, 0xd2, 0xb0, 0x2f, 0x78, 0x2d, 0x05, 0x87, 0xc6, 0x76, 0x2b, 0xdc, 0x62, 0xf1, 0x8e, 0x56, 0x2b, 0x6b, 0x6d, - 0xb5, 0xd7, 0x4a, 0x45, 0xf7, 0xaf, 0x39, 0x4e, 0x9c, 0xa5, 0xb0, 0xfd, 0xf0, 0xe1, 0x82, 0x5d, 0x13, 0xc0, 0xa0, - 0xc5, 0x64, 0x81, 0x12, 0x54, 0xb2, 0x56, 0xb5, 0xdb, 0x29, 0xf1, 0xcb, 0xfd, 0xac, 0xcb, 0x6c, 0xe7, 0xf1, 0xeb, - 0x26, 0xed, 0x13, 0x9f, 0xa3, 0x1f, 0xe6, 0xb7, 0xd6, 0x49, 0xc9, 0x19, 0xc6, 0xb5, 0xfc, 0xff, 0x2a, 0x7a, 0x55, - 0x64, 0x69, 0xb4, 0x31, 0x3c, 0x98, 0x0d, 0xb5, 0xe9, 0x43, 0x63, 0x54, 0x6e, 0xd9, 0x28, 0x22, 0x5a, 0xdd, 0x81, - 0x60, 0x46, 0x71, 0x5f, 0xa2, 0xcd, 0x2b, 0x55, 0x16, 0xde, 0xe1, 0x13, 0x1b, 0xbd, 0x61, 0x7b, 0x42, 0x28, 0xdf, - 0x3d, 0x2d, 0xcc, 0xaa, 0xa5, 0xa2, 0xc1, 0x76, 0x09, 0xef, 0x62, 0x54, 0xe9, 0x27, 0x4c, 0xb6, 0x2c, 0x98, 0xea, - 0xff, 0x77, 0x45, 0x96, 0xb6, 0x29, 0x3a, 0x30, 0x9d, 0x4d, 0x9f, 0x4e, 0xba, 0xc1, 0x75, 0x06, 0x2c, 0x22, 0xd8, - 0x52, 0xe1, 0x78, 0x94, 0xda, 0x0d, 0x12, 0x26, 0x82, 0x9b, 0xa8, 0x97, 0x1d, 0x2d, 0x53, 0xb2, 0x2a, 0xe0, 0xf9, - 0x95, 0xab, 0x4c, 0xc7, 0xd1, 0xd0, 0xef, 0x5f, 0xa7, 0x26, 0xf4, 0x2b, 0xf5, 0x52, 0x15, 0xe7, 0x61, 0x54, 0x1d, - 0x2a, 0x8c, 0xd1, 0x92, 0xa6, 0x70, 0x0c, 0x66, 0x97, 0x61, 0x8a, 0x97, 0xb3, 0x4d, 0xc2, 0x3e, 0x63, 0x20, 0x97, - 0xda, 0xa0, 0x5e, 0x53, 0xa2, 0x35, 0x6b, 0x6f, 0xe6, 0x94, 0xd0, 0x4b, 0x56, 0xfa, 0x77, 0xa1, 0x35, 0x08, 0x14, - 0x65, 0x33, 0x65, 0x7a, 0xa1, 0xdb, 0x79, 0x49, 0x13, 0x5a, 0xd0, 0x15, 0xa9, 0x41, 0xdf, 0xeb, 0xe4, 0xec, 0xe8, - 0x64, 0x67, 0x66, 0x3d, 0x66, 0xc5, 0x70, 0x32, 0x8d, 0xe1, 0x9a, 0x16, 0xbb, 0x6b, 0xda, 0xb2, 0x79, 0xe3, 0x6a, - 0x6c, 0x9c, 0x06, 0xed, 0x02, 0x69, 0x9b, 0xe6, 0xf6, 0x53, 0x8f, 0xdb, 0x5f, 0xd7, 0x6c, 0x39, 0xed, 0xad, 0xb7, - 0xdb, 0x5e, 0x0a, 0x36, 0xa2, 0x1e, 0x1f, 0xbf, 0x56, 0xd2, 0x75, 0xcb, 0xe5, 0xa7, 0xf0, 0xec, 0xf1, 0xf5, 0x4b, - 0x1f, 0x5c, 0x8e, 0x56, 0x6d, 0xee, 0x7e, 0xb9, 0x8b, 0x2c, 0xf7, 0x59, 0x43, 0xcb, 0xf5, 0x0c, 0x35, 0xc9, 0xb3, - 0xd1, 0xde, 0xa1, 0x16, 0x2c, 0x67, 0xdd, 0x84, 0x27, 0x06, 0x3b, 0xf6, 0xaa, 0xb1, 0x39, 0x2a, 0x73, 0xc9, 0x6a, - 0x90, 0x40, 0x9f, 0xe4, 0x99, 0xa6, 0x7f, 0x90, 0x61, 0x3e, 0xba, 0xa3, 0x39, 0xe0, 0x8a, 0x55, 0xf6, 0x92, 0x41, - 0xea, 0xaa, 0xbd, 0xc4, 0x95, 0xaf, 0x70, 0x48, 0x36, 0xf8, 0x64, 0x98, 0xaa, 0x4f, 0x2e, 0x79, 0xf0, 0xff, 0xb6, - 0x6a, 0x95, 0x9e, 0x9b, 0xe4, 0x86, 0xe3, 0x5f, 0x27, 0x6d, 0x1f, 0x13, 0x83, 0x04, 0x3c, 0xb5, 0x8b, 0xa1, 0x1a, - 0x55, 0x45, 0x2c, 0xca, 0xdc, 0xc4, 0x1c, 0xdb, 0xdb, 0x35, 0x74, 0x50, 0x06, 0xbf, 0x6e, 0xf8, 0xc4, 0xdc, 0x81, - 0xad, 0x40, 0x47, 0x27, 0x9a, 0xcb, 0x30, 0x33, 0x97, 0x61, 0xda, 0xb5, 0x55, 0x60, 0x78, 0xd5, 0x56, 0x49, 0x94, - 0xab, 0x51, 0x8f, 0x9b, 0x59, 0x6a, 0xf6, 0x22, 0xef, 0x5e, 0x93, 0x9e, 0xc4, 0x9f, 0x2e, 0x3d, 0x79, 0x3d, 0x0c, - 0x88, 0xfc, 0x9c, 0xa5, 0xe1, 0x1a, 0x05, 0xc1, 0xa9, 0xd5, 0x0e, 0xa4, 0xf9, 0x08, 0x90, 0xf9, 0x71, 0x1a, 0xbe, - 0xd5, 0xe2, 0x1c, 0xb2, 0x51, 0x1a, 0x27, 0xb6, 0x34, 0xea, 0x21, 0xb8, 0xf3, 0x5e, 0xf3, 0x18, 0x02, 0x1f, 0x7e, - 0xc0, 0xcd, 0xa0, 0xa2, 0xdb, 0x12, 0x13, 0xa5, 0xcd, 0xa3, 0x6e, 0xf9, 0xa8, 0x21, 0x54, 0xb2, 0x32, 0xbc, 0x04, - 0xda, 0xbb, 0x23, 0x30, 0xaa, 0x9c, 0x40, 0x66, 0x58, 0x1c, 0x1e, 0x0d, 0x53, 0x25, 0x28, 0x1a, 0xca, 0xe1, 0x12, - 0xe5, 0x80, 0x98, 0x04, 0x02, 0xa3, 0x62, 0x90, 0xea, 0xca, 0xd4, 0x8b, 0x41, 0xaa, 0x6f, 0x55, 0xa4, 0x3e, 0xcf, - 0xc2, 0x8a, 0xea, 0x16, 0xd1, 0x31, 0x1d, 0x4a, 0xba, 0x34, 0x3b, 0x35, 0xd7, 0xd2, 0x0b, 0xb5, 0x1c, 0x9f, 0xe9, - 0x34, 0x18, 0xc5, 0x33, 0x97, 0xa2, 0xdf, 0xaa, 0xfd, 0xec, 0xbf, 0xc5, 0x94, 0x1a, 0xb1, 0xa9, 0xbd, 0x45, 0x0c, - 0xab, 0xf6, 0x43, 0x56, 0xe5, 0xa0, 0xdd, 0x05, 0x65, 0x63, 0x65, 0x9c, 0xe7, 0x1b, 0xc1, 0xcc, 0x41, 0xdb, 0x58, - 0x35, 0x7d, 0xe8, 0x8d, 0x18, 0xb5, 0x37, 0xa6, 0x1a, 0xf7, 0x04, 0x7e, 0xda, 0xa0, 0xe9, 0x5e, 0xe4, 0x39, 0xea, - 0x91, 0x77, 0xff, 0x33, 0x47, 0x76, 0x26, 0x9f, 0xc4, 0x32, 0xa9, 0xdb, 0xc7, 0x24, 0x58, 0xa8, 0x3a, 0x46, 0x17, - 0x6e, 0x64, 0x4a, 0xfb, 0xb9, 0x33, 0xfd, 0x88, 0x67, 0xf2, 0xb0, 0x1d, 0x1a, 0xf5, 0xa5, 0x61, 0x2d, 0x29, 0xa2, - 0xbe, 0xa0, 0xb7, 0xa6, 0x3a, 0x3a, 0xa2, 0x5e, 0x47, 0x60, 0x75, 0x45, 0x1b, 0xd4, 0x00, 0x4c, 0xc6, 0xb5, 0xad, - 0xcd, 0xe7, 0x60, 0x6a, 0xab, 0x2a, 0x78, 0x4a, 0x77, 0x85, 0xd2, 0xbd, 0x49, 0x5d, 0xb7, 0x86, 0xd8, 0x02, 0x06, - 0x04, 0x6e, 0xf4, 0xd4, 0xf4, 0x07, 0x4d, 0x54, 0x00, 0x1a, 0x34, 0x6e, 0x67, 0x3a, 0x47, 0xa2, 0xdf, 0xa9, 0x4d, - 0xdb, 0x4c, 0xf5, 0xaa, 0xf2, 0x01, 0x54, 0xfc, 0x59, 0x3a, 0xbf, 0x34, 0x23, 0x16, 0xc0, 0xb8, 0x07, 0xce, 0x54, - 0xef, 0x34, 0x03, 0xeb, 0x89, 0x3c, 0xcf, 0x4a, 0x9e, 0x48, 0x01, 0x33, 0x22, 0xaf, 0xaf, 0xa5, 0x80, 0x61, 0x50, - 0x03, 0x80, 0x16, 0xcd, 0x65, 0x34, 0xe1, 0x5f, 0xd5, 0x74, 0x5f, 0x1e, 0xfe, 0x95, 0xce, 0xf5, 0xf5, 0xb8, 0x06, - 0x43, 0xe5, 0x75, 0xc5, 0x77, 0x32, 0x7d, 0xcd, 0x9f, 0x78, 0x99, 0x96, 0x72, 0x5d, 0xec, 0x64, 0xf9, 0xea, 0x6b, - 0xfe, 0x54, 0xe7, 0x39, 0x7a, 0x52, 0xd3, 0x34, 0xbe, 0xdf, 0xc9, 0xf2, 0xf7, 0xaf, 0x9f, 0xd8, 0x3c, 0x5f, 0x8d, - 0x6b, 0x7a, 0xcb, 0xf9, 0x47, 0x97, 0x69, 0xa2, 0xab, 0x1a, 0x3f, 0xf9, 0xbb, 0xcd, 0xf5, 0xa4, 0xa6, 0xd7, 0x52, - 0x54, 0xcb, 0x9d, 0xa2, 0x8e, 0xbe, 0x3e, 0xfa, 0x3b, 0xff, 0xda, 0x74, 0xef, 0xa8, 0xa6, 0x7f, 0xae, 0xe3, 0xa2, - 0xe2, 0xc5, 0x4e, 0x71, 0x7f, 0xfb, 0xfb, 0xdf, 0x9f, 0xd8, 0x8c, 0x4f, 0x6a, 0x7a, 0xcf, 0xe3, 0x8e, 0xb6, 0x4f, - 0x9e, 0x3e, 0xe1, 0x7f, 0xab, 0x6b, 0xfa, 0x33, 0xf3, 0x83, 0xa3, 0x9e, 0x66, 0x9e, 0x1e, 0x3e, 0x91, 0x4d, 0xd4, - 0x80, 0xa1, 0x87, 0x06, 0x90, 0x4b, 0xab, 0xa6, 0xd9, 0xe3, 0x95, 0x0b, 0x6e, 0xdf, 0xe7, 0x71, 0x1a, 0xaf, 0xe0, - 0x20, 0xd8, 0xa0, 0x71, 0x56, 0x01, 0x9c, 0x2a, 0xf0, 0x9e, 0x51, 0x49, 0xb3, 0x52, 0xfe, 0x93, 0xf3, 0x8f, 0x30, - 0x68, 0x08, 0x69, 0xa3, 0x22, 0x03, 0xbd, 0x5d, 0xe9, 0xc8, 0x46, 0xe8, 0xbf, 0xd9, 0x8c, 0x83, 0xe3, 0xc3, 0xe8, - 0xf5, 0xfb, 0x61, 0xc1, 0x44, 0x58, 0x10, 0x42, 0xff, 0x08, 0x0b, 0x70, 0x28, 0x29, 0x98, 0x97, 0xcf, 0xf8, 0x9e, - 0x6b, 0xa3, 0xb0, 0x10, 0x44, 0x77, 0x91, 0x7d, 0x40, 0xd5, 0xa3, 0xef, 0xd0, 0x0d, 0xf1, 0xb2, 0xc2, 0x82, 0xa1, - 0x55, 0x0d, 0xcc, 0x10, 0x14, 0xff, 0x9a, 0x87, 0x12, 0x7c, 0xe2, 0x01, 0x3e, 0x7a, 0x4c, 0x66, 0x5c, 0x5d, 0x6b, - 0xdf, 0x5e, 0x86, 0x05, 0x0d, 0x74, 0xdb, 0x21, 0xe8, 0x40, 0xe4, 0xbf, 0x00, 0x4f, 0x81, 0x81, 0x0f, 0x0b, 0xbb, - 0x94, 0xbb, 0xfe, 0xea, 0x3f, 0x1b, 0xd6, 0xd1, 0x85, 0x1f, 0xfd, 0xd9, 0xba, 0xb0, 0x67, 0x64, 0x2a, 0x8f, 0xcb, - 0xe1, 0x64, 0x3a, 0x18, 0x48, 0x17, 0xc7, 0xed, 0x34, 0x9b, 0xff, 0x3c, 0x97, 0x8b, 0x05, 0xea, 0xbe, 0x71, 0x5e, - 0x67, 0xfa, 0x6f, 0xa4, 0x9d, 0x0f, 0x5e, 0x9f, 0xfe, 0x7a, 0x7e, 0x76, 0xfa, 0x12, 0x9c, 0x0f, 0x3e, 0xbc, 0xf8, - 0xee, 0xc5, 0x7b, 0x15, 0xdc, 0x5d, 0xcd, 0x79, 0xbf, 0xef, 0xa4, 0x3e, 0x21, 0x1f, 0x56, 0xe4, 0x30, 0x8c, 0x1f, - 0x17, 0xca, 0xe8, 0x81, 0x1c, 0x33, 0x0b, 0x85, 0x0c, 0x55, 0xd4, 0xf6, 0x77, 0x39, 0x9c, 0x78, 0x60, 0x16, 0xf7, - 0x0d, 0x11, 0xae, 0xdf, 0x72, 0x1b, 0x64, 0x4d, 0x9e, 0x78, 0xfd, 0xe0, 0x64, 0x2a, 0x1d, 0x5b, 0x58, 0x30, 0x28, - 0x1b, 0xda, 0x74, 0x9a, 0xcd, 0x8b, 0x85, 0x6d, 0x97, 0x5b, 0x20, 0xa3, 0x34, 0xbb, 0xbc, 0x0c, 0x15, 0x74, 0xf5, - 0x09, 0x68, 0x00, 0x4c, 0xa3, 0x0a, 0xd7, 0x22, 0x3e, 0xf3, 0xcb, 0x8f, 0xc6, 0x5e, 0xf3, 0xee, 0x50, 0xf7, 0x64, - 0x9a, 0x55, 0x35, 0x06, 0x74, 0x30, 0xa1, 0xdc, 0x0d, 0xba, 0x09, 0x26, 0xa3, 0xda, 0xf2, 0xf3, 0xbc, 0x5a, 0x98, - 0xe6, 0xb8, 0x61, 0xa8, 0xbc, 0x92, 0xd7, 0xb2, 0x81, 0xc8, 0x40, 0x32, 0x0c, 0x7b, 0x34, 0x46, 0x91, 0xfa, 0xc1, - 0xae, 0x77, 0xfc, 0x26, 0x97, 0x10, 0x4d, 0x31, 0x03, 0xe9, 0xfc, 0xa9, 0x50, 0xce, 0xe5, 0x92, 0xf1, 0xb9, 0x58, - 0x9c, 0x80, 0xdb, 0xf9, 0x5c, 0x2c, 0x22, 0x0c, 0xca, 0x97, 0x41, 0xac, 0x12, 0xb0, 0x7b, 0x71, 0x10, 0xbe, 0x9d, - 0xd0, 0x06, 0x76, 0x03, 0x49, 0x36, 0x28, 0xed, 0x4a, 0x43, 0x94, 0x3b, 0xe5, 0xd1, 0x06, 0x91, 0x87, 0x58, 0x35, - 0xaf, 0xda, 0x9e, 0x6c, 0xe6, 0x62, 0x82, 0xab, 0x2c, 0x66, 0x72, 0x1a, 0x1f, 0xb3, 0x62, 0x1a, 0x43, 0x29, 0x71, - 0x9a, 0x86, 0x31, 0x9d, 0x50, 0x41, 0x48, 0xc2, 0xf8, 0x3c, 0x5e, 0xd0, 0x04, 0xa5, 0x04, 0x21, 0x84, 0xfc, 0x18, - 0xa1, 0x6d, 0x0e, 0x2c, 0x79, 0xbb, 0xfd, 0x3c, 0xfd, 0xdc, 0x8e, 0xe1, 0x32, 0x2a, 0x42, 0x37, 0xe8, 0xac, 0xe1, - 0xdf, 0x88, 0x0a, 0x1a, 0x63, 0xc5, 0x10, 0x04, 0xbc, 0xc0, 0xa8, 0x84, 0x05, 0x89, 0x59, 0x05, 0x51, 0x04, 0xca, - 0x79, 0xbc, 0x60, 0x05, 0x6d, 0xda, 0x9c, 0xc6, 0xda, 0x24, 0xa8, 0xe7, 0xb0, 0xd4, 0x0e, 0xa4, 0x52, 0x21, 0xf6, - 0xf8, 0x4c, 0x44, 0x37, 0xda, 0xd0, 0x00, 0x50, 0xa0, 0x94, 0x5c, 0xfc, 0xf6, 0xf3, 0x3d, 0xdc, 0x14, 0xf4, 0x3f, - 0xdb, 0x98, 0x68, 0x67, 0xb9, 0x3a, 0xf4, 0xe6, 0x0b, 0x1a, 0xe7, 0x39, 0x84, 0x62, 0x33, 0x08, 0xe4, 0x22, 0xab, - 0x20, 0xa2, 0xc5, 0x7d, 0x60, 0x42, 0xc2, 0x41, 0x9b, 0x7e, 0x86, 0xd4, 0x86, 0x98, 0x5c, 0x79, 0x62, 0x60, 0xb7, - 0x55, 0x82, 0x80, 0x23, 0x3d, 0xcf, 0xfe, 0x6a, 0x62, 0xac, 0x69, 0x6a, 0x66, 0xe2, 0x6d, 0x28, 0x44, 0x83, 0x16, - 0x44, 0x33, 0x78, 0xff, 0x5c, 0x73, 0xbc, 0xea, 0xc0, 0x0f, 0x78, 0xe7, 0xe2, 0xcc, 0xab, 0x99, 0x47, 0xe4, 0xd4, - 0x47, 0x39, 0xa2, 0x5f, 0xf2, 0xb0, 0x1a, 0xe9, 0x64, 0x8c, 0x95, 0xc4, 0x41, 0x6f, 0x83, 0x05, 0x73, 0x42, 0x57, - 0x3c, 0xb4, 0x7c, 0xfc, 0x4b, 0x64, 0x32, 0x4a, 0x6a, 0xac, 0xe8, 0x4a, 0x8b, 0x11, 0xe7, 0x35, 0xcc, 0xd2, 0x64, - 0x45, 0x17, 0x0b, 0x4d, 0x9a, 0x85, 0x32, 0x0d, 0xf0, 0x09, 0xb4, 0x18, 0xb9, 0x87, 0x9a, 0x36, 0x10, 0x1a, 0x76, - 0x87, 0x80, 0x8f, 0xdc, 0x43, 0x87, 0xff, 0x9f, 0x67, 0x17, 0x88, 0xb4, 0x37, 0x37, 0x91, 0xf1, 0x48, 0xdd, 0xc0, - 0x41, 0x31, 0x3e, 0xf6, 0xcd, 0xc4, 0xcf, 0x9c, 0xd1, 0x87, 0xa4, 0xf2, 0x1d, 0x3e, 0x58, 0xfe, 0x78, 0x53, 0x33, - 0x2b, 0x23, 0x58, 0x0f, 0xdb, 0x2d, 0x2e, 0x88, 0xb6, 0x0b, 0x20, 0xf5, 0x8c, 0x57, 0x0b, 0xdf, 0x78, 0x35, 0xde, - 0x63, 0xbc, 0xea, 0xce, 0xd4, 0x30, 0x27, 0x1b, 0xd4, 0x67, 0x29, 0x79, 0x7e, 0x8e, 0x32, 0xc1, 0xa6, 0xcb, 0x59, - 0x49, 0x55, 0x2a, 0xa1, 0xbd, 0xd8, 0xcf, 0x18, 0xdf, 0x11, 0x8c, 0xb3, 0xe2, 0x30, 0x12, 0xa8, 0x4a, 0x25, 0x75, - 0xd8, 0x2b, 0x40, 0x3d, 0x06, 0xef, 0x0d, 0x86, 0xa8, 0x91, 0xb1, 0x9b, 0x36, 0x10, 0x1a, 0x1a, 0xeb, 0xd1, 0x9e, - 0xb5, 0x1e, 0xdd, 0x6e, 0x2b, 0xe3, 0x6f, 0x27, 0xd7, 0x45, 0x82, 0xa8, 0xc2, 0x6a, 0x34, 0x01, 0xde, 0x34, 0xb1, - 0xb7, 0x25, 0xa7, 0xb4, 0xc0, 0xf0, 0xd9, 0x7f, 0x84, 0xa5, 0x53, 0x49, 0x94, 0x64, 0x56, 0x46, 0x03, 0x77, 0x0e, - 0x3e, 0x8f, 0x2b, 0x58, 0x03, 0x10, 0xc9, 0x11, 0x3d, 0x5c, 0xff, 0x08, 0xa5, 0xcb, 0x2c, 0xc9, 0x4c, 0x42, 0x66, - 0x2e, 0xd2, 0x76, 0xd6, 0xc1, 0xc4, 0x99, 0xd4, 0x7a, 0x63, 0x21, 0x87, 0x06, 0xf9, 0x01, 0x94, 0x21, 0x0e, 0x9f, - 0x7c, 0x30, 0xa1, 0x52, 0x85, 0x52, 0x6d, 0x74, 0xb3, 0x1b, 0x78, 0xe5, 0x43, 0x76, 0xcd, 0xcb, 0x2a, 0xbe, 0x5e, - 0x19, 0x4b, 0x62, 0xce, 0xf6, 0xb9, 0xed, 0x51, 0x61, 0x5e, 0xbd, 0x79, 0xf1, 0xdd, 0x69, 0xe3, 0xd5, 0x2e, 0xe2, - 0x68, 0x08, 0xb6, 0x15, 0x63, 0x8c, 0xde, 0xe2, 0xd3, 0x60, 0xa2, 0x5c, 0x23, 0xd0, 0xbb, 0x14, 0xf4, 0xdb, 0x9f, - 0xeb, 0x09, 0x78, 0xcd, 0xf5, 0xf2, 0x4b, 0x3e, 0x02, 0x96, 0xa8, 0xd0, 0xb3, 0xc2, 0xdc, 0xac, 0xcc, 0xf6, 0x76, - 0x2b, 0x32, 0xd3, 0xae, 0x34, 0x32, 0x10, 0xaf, 0xb6, 0xc3, 0x58, 0xb8, 0x74, 0x4d, 0xb7, 0x83, 0x5d, 0x2d, 0x3d, - 0x4b, 0xe4, 0xed, 0xb6, 0x84, 0x0e, 0xd9, 0x01, 0xf7, 0x5e, 0xc6, 0x77, 0xf0, 0xb2, 0xf4, 0xba, 0xd9, 0x0c, 0x9e, - 0x00, 0x66, 0xc2, 0x85, 0xb3, 0x2c, 0x8e, 0x19, 0x4f, 0x42, 0x15, 0x9b, 0xab, 0x21, 0xf2, 0x56, 0x84, 0xd6, 0xec, - 0xaf, 0x50, 0x8c, 0xc0, 0xee, 0xe4, 0xec, 0x63, 0xb6, 0x9a, 0x2d, 0x01, 0x35, 0xff, 0x3a, 0x13, 0x40, 0x73, 0xed, - 0x5a, 0xb0, 0x4d, 0xa1, 0xcd, 0x75, 0xfd, 0x2c, 0x5e, 0xc5, 0x09, 0xa8, 0x6e, 0xc0, 0x5b, 0xe4, 0x5e, 0x8b, 0xae, - 0x0c, 0xba, 0x28, 0x7d, 0xa0, 0x1c, 0x4b, 0x0a, 0x1d, 0x7d, 0xef, 0x09, 0x75, 0xee, 0x19, 0xc0, 0x25, 0x8d, 0x9a, - 0xa7, 0x5a, 0xca, 0x58, 0x00, 0x2c, 0x74, 0x30, 0x53, 0x64, 0x2b, 0xba, 0x33, 0x98, 0x14, 0xf0, 0xd6, 0x00, 0x7f, - 0x88, 0xac, 0x52, 0x77, 0xc5, 0x32, 0x2c, 0x3d, 0xfb, 0xeb, 0x7e, 0x3f, 0xf6, 0xec, 0xaf, 0x2f, 0x35, 0xad, 0x8b, - 0xdb, 0x0d, 0x20, 0x35, 0x06, 0x10, 0x39, 0xd5, 0x03, 0x61, 0x22, 0x8a, 0x35, 0x7d, 0xff, 0x4e, 0x4d, 0x16, 0x05, - 0x42, 0xbf, 0x53, 0xaf, 0x27, 0x25, 0x01, 0x9d, 0x5a, 0xc5, 0x4e, 0x06, 0xda, 0xec, 0x03, 0x02, 0xa2, 0xfa, 0x19, - 0xd9, 0x7c, 0xa1, 0x9c, 0x8b, 0x55, 0xf8, 0xf0, 0x31, 0x85, 0x80, 0xc2, 0x1d, 0x35, 0x3a, 0x6f, 0x43, 0x24, 0x50, - 0x56, 0x28, 0x62, 0xcd, 0x8b, 0xb5, 0x24, 0x64, 0x3e, 0x5e, 0xa0, 0xe0, 0xca, 0x01, 0xbb, 0x72, 0x36, 0x19, 0x96, - 0x11, 0x67, 0xe1, 0xfe, 0x6f, 0x26, 0x0b, 0x82, 0x9a, 0x2b, 0x3f, 0x90, 0xe3, 0x4e, 0xa6, 0xc6, 0x9e, 0x6a, 0xd4, - 0x20, 0x98, 0x8c, 0x20, 0x30, 0xdc, 0xf0, 0x33, 0x3e, 0x3e, 0x5a, 0x10, 0x50, 0x91, 0x59, 0xb3, 0x10, 0xf3, 0xe2, - 0xf8, 0x2b, 0x40, 0x8d, 0x19, 0x1d, 0x3d, 0x9d, 0x72, 0x06, 0x87, 0x28, 0x1d, 0x83, 0x8c, 0x56, 0xc0, 0x6f, 0xa1, - 0x7e, 0xb7, 0x4e, 0x7c, 0x1f, 0xfa, 0x55, 0xd0, 0xcb, 0x18, 0x18, 0x8e, 0x68, 0x72, 0x18, 0xf2, 0xc1, 0x64, 0x00, - 0xda, 0x12, 0x6f, 0xf7, 0xb5, 0xb4, 0xe2, 0xe6, 0x74, 0xe9, 0x74, 0xff, 0xa4, 0x4d, 0x90, 0x44, 0x2a, 0x59, 0xa9, - 0x88, 0x01, 0x84, 0xb2, 0x54, 0xdb, 0x64, 0x09, 0x96, 0x15, 0x66, 0x49, 0x73, 0x83, 0x92, 0xb8, 0xbb, 0x19, 0x38, - 0x46, 0xcd, 0x3a, 0x0d, 0xcb, 0x96, 0x1b, 0x35, 0xc0, 0xe7, 0x24, 0xac, 0xb0, 0x37, 0x9c, 0x99, 0xf4, 0xce, 0x74, - 0xb8, 0x3a, 0xe6, 0xec, 0x35, 0x47, 0x30, 0x8e, 0x04, 0x6f, 0x3c, 0x74, 0xc9, 0x34, 0x54, 0x64, 0xca, 0x38, 0x98, - 0xf6, 0x00, 0xf7, 0x9e, 0x83, 0x71, 0x18, 0x1b, 0x54, 0x96, 0xd4, 0xa7, 0xde, 0x5d, 0x08, 0x04, 0x69, 0xad, 0x97, - 0xf9, 0x0c, 0x4f, 0xcf, 0x08, 0x65, 0x7f, 0xc8, 0xe1, 0x0b, 0xb0, 0xa3, 0x20, 0x27, 0x13, 0xfe, 0xf4, 0xf1, 0x6e, - 0xa0, 0x2a, 0x3e, 0x08, 0x0e, 0x62, 0x91, 0x1e, 0x04, 0x03, 0x01, 0xbf, 0x0a, 0x7e, 0x50, 0x49, 0x79, 0x70, 0x19, - 0x17, 0x07, 0xf1, 0x2a, 0x2e, 0xaa, 0x83, 0xdb, 0xac, 0x5a, 0x1e, 0x98, 0x0e, 0x01, 0x34, 0x6f, 0x30, 0x88, 0x07, - 0xc1, 0x41, 0x30, 0x28, 0xcc, 0xd4, 0xae, 0x58, 0xd9, 0x38, 0xce, 0x4c, 0x88, 0xb2, 0xa0, 0x19, 0x20, 0xac, 0x71, - 0x1a, 0x00, 0x9f, 0xba, 0x66, 0x29, 0xbd, 0xc4, 0x70, 0x03, 0x62, 0xba, 0x86, 0x3e, 0x00, 0x8f, 0xbc, 0xa6, 0x31, - 0x2c, 0x81, 0xcb, 0xc1, 0x80, 0xac, 0x21, 0x72, 0xc1, 0x9a, 0xda, 0x20, 0x0e, 0xe1, 0x5a, 0xd9, 0x69, 0xef, 0x02, - 0x33, 0x6d, 0xb7, 0x80, 0xa8, 0x3c, 0x21, 0xfd, 0xbe, 0xfd, 0x86, 0xfa, 0x17, 0xec, 0x25, 0xd8, 0x5f, 0x15, 0x55, - 0x98, 0x48, 0xa5, 0xf9, 0xbe, 0x62, 0x27, 0x03, 0x15, 0x71, 0x78, 0xc7, 0x91, 0xa2, 0x8d, 0xca, 0x65, 0xd9, 0x93, - 0x65, 0xc3, 0x57, 0xe2, 0x9a, 0x3b, 0x3f, 0xae, 0x4a, 0xca, 0xbc, 0xca, 0x56, 0x8a, 0xfd, 0x9b, 0x71, 0xcd, 0xfd, - 0x81, 0xf5, 0x67, 0xf3, 0x15, 0x5c, 0x5b, 0xbd, 0x77, 0x4d, 0xae, 0x11, 0x39, 0x4b, 0x28, 0x97, 0xd4, 0x36, 0x0f, - 0x6f, 0xe9, 0xfb, 0xfc, 0xea, 0xdb, 0x4c, 0xa7, 0xf1, 0x59, 0x85, 0x85, 0x0b, 0xd1, 0x8a, 0xe0, 0xd0, 0x90, 0x8b, - 0xe6, 0x11, 0x60, 0xae, 0x7d, 0xb6, 0x82, 0x82, 0xd4, 0xe7, 0x15, 0x7a, 0xb7, 0x42, 0xc2, 0x4b, 0xcd, 0x2e, 0x3d, - 0x0c, 0xa4, 0x8c, 0xdb, 0x43, 0x4b, 0x98, 0xb4, 0xbc, 0x08, 0xef, 0xbd, 0xe6, 0x26, 0xf7, 0x3c, 0xc4, 0xe8, 0x45, - 0x9e, 0x9d, 0x80, 0xb1, 0xee, 0x92, 0x9d, 0x0d, 0x4f, 0xfc, 0x86, 0xe7, 0xac, 0x45, 0xa3, 0xe9, 0x92, 0x25, 0xfd, - 0x7e, 0x0c, 0x26, 0xde, 0x29, 0xcb, 0xe1, 0x57, 0xbe, 0xa0, 0x6b, 0x06, 0x98, 0x62, 0xf4, 0x12, 0x12, 0x52, 0x44, - 0x22, 0x59, 0xab, 0x93, 0xe4, 0x13, 0xdd, 0x05, 0x60, 0xf4, 0xcb, 0x59, 0x1a, 0x2d, 0xf7, 0x9a, 0x59, 0x20, 0x79, - 0x86, 0xbe, 0xeb, 0x60, 0x7b, 0x63, 0x1f, 0xa4, 0x9c, 0x1f, 0x8b, 0xe9, 0x60, 0xc0, 0x89, 0x86, 0x1b, 0x2f, 0x95, - 0xb8, 0x56, 0xb7, 0xb8, 0x63, 0x18, 0x4b, 0x7d, 0x5b, 0xc4, 0xe0, 0x80, 0x5d, 0xb4, 0xb2, 0xdb, 0x07, 0xd8, 0x57, - 0x8e, 0x77, 0xa9, 0xb2, 0x3b, 0x3d, 0x66, 0x9a, 0xcb, 0x56, 0x93, 0x4e, 0x2a, 0xf6, 0x13, 0xf9, 0x26, 0x77, 0xd0, - 0xe5, 0x72, 0xac, 0x79, 0xcb, 0x01, 0xa8, 0xe8, 0x47, 0x8a, 0xea, 0x7e, 0x86, 0x23, 0xcc, 0x83, 0x75, 0x9b, 0x4f, - 0x0e, 0x4d, 0x81, 0x43, 0xe4, 0x49, 0x1b, 0x4d, 0x01, 0xdd, 0xbb, 0x78, 0xdc, 0xd5, 0x6f, 0x4b, 0x77, 0x81, 0x12, - 0xed, 0x54, 0xdc, 0xf0, 0x63, 0xa2, 0x4e, 0x67, 0xda, 0x10, 0xfa, 0x57, 0x46, 0xdc, 0x5f, 0x1a, 0x57, 0xf1, 0xa6, - 0x77, 0xf9, 0x8c, 0x43, 0x9d, 0xdd, 0x10, 0x0a, 0xc0, 0x55, 0x7b, 0x3a, 0x75, 0x63, 0x48, 0xaf, 0x94, 0xe8, 0x36, - 0x38, 0xd8, 0x5e, 0x9f, 0x71, 0x14, 0xfd, 0x18, 0x35, 0xf2, 0x6d, 0x24, 0x1e, 0xcb, 0x41, 0xfc, 0xb8, 0xa0, 0xcb, - 0x48, 0x3c, 0x2e, 0x06, 0xf1, 0x63, 0x59, 0xd7, 0xbb, 0xe7, 0xca, 0xfe, 0x3e, 0x22, 0xcf, 0xba, 0xb3, 0x97, 0x4a, - 0xd8, 0x18, 0x78, 0x76, 0x2d, 0x20, 0x9c, 0x82, 0x27, 0xb2, 0xb5, 0xf4, 0xa1, 0x73, 0xbb, 0x8f, 0x2d, 0x93, 0x04, - 0x41, 0xcf, 0xdb, 0x6c, 0x12, 0xc5, 0xce, 0x36, 0x8f, 0x3e, 0x9c, 0x02, 0x09, 0xdd, 0x6e, 0x9b, 0x75, 0xb5, 0x06, - 0x14, 0xd3, 0x70, 0xcc, 0x0f, 0x8b, 0xd1, 0xad, 0xef, 0xae, 0x7f, 0x58, 0x8c, 0x96, 0x64, 0x38, 0x31, 0x93, 0x1f, - 0x9f, 0x8c, 0x67, 0x71, 0x34, 0xa9, 0x3b, 0x4e, 0x0b, 0x8d, 0x7f, 0xea, 0xdd, 0x42, 0x11, 0x38, 0x15, 0x23, 0x38, - 0x72, 0x2a, 0x94, 0x93, 0x52, 0x03, 0xc3, 0xff, 0xa0, 0xda, 0xd1, 0xa6, 0xbd, 0x8e, 0xab, 0x64, 0x99, 0x89, 0x2b, - 0x1d, 0x3e, 0x5c, 0x47, 0x17, 0xb7, 0x01, 0xed, 0xbc, 0xcb, 0xb4, 0xe3, 0xd7, 0x49, 0x83, 0x9e, 0xb8, 0x9a, 0x19, - 0x70, 0xeb, 0x7e, 0x84, 0x66, 0x08, 0x8c, 0x96, 0xe7, 0xef, 0x10, 0x73, 0xfb, 0x17, 0x65, 0xf3, 0xab, 0x68, 0x9f, - 0x23, 0x23, 0x65, 0x9b, 0x8c, 0x54, 0x60, 0x84, 0x29, 0x45, 0x12, 0x57, 0x21, 0x04, 0xb2, 0xff, 0x9c, 0xe2, 0x5a, - 0x2c, 0xbd, 0xd7, 0x20, 0x4c, 0xb0, 0x5d, 0xd0, 0x7e, 0x75, 0x3b, 0xb7, 0x95, 0x16, 0x7b, 0xa4, 0xbe, 0xcf, 0x9d, - 0xed, 0x8a, 0x26, 0x7f, 0x9f, 0x37, 0xa0, 0x0d, 0x20, 0xca, 0x7d, 0x7d, 0x54, 0x02, 0x27, 0x23, 0x6e, 0x28, 0x31, - 0x7a, 0x41, 0x57, 0x27, 0x72, 0xcf, 0x4e, 0xcd, 0x9b, 0x8a, 0x99, 0x8a, 0x2b, 0xdf, 0xec, 0x99, 0xff, 0x60, 0x28, - 0xa8, 0x00, 0x03, 0x6f, 0x73, 0xc6, 0xa3, 0x03, 0xdd, 0xad, 0xd1, 0x69, 0xc1, 0x66, 0x41, 0x5d, 0xd6, 0x6d, 0x1b, - 0x0f, 0x1a, 0x71, 0x50, 0x14, 0xab, 0x42, 0x8d, 0x84, 0x27, 0x02, 0x01, 0x53, 0x76, 0xcd, 0x23, 0x23, 0xa8, 0xe9, - 0x4d, 0x28, 0x6c, 0x28, 0xf8, 0xab, 0x44, 0x35, 0xbd, 0x09, 0x6d, 0x32, 0x71, 0x9a, 0x41, 0x04, 0x33, 0x62, 0xbb, - 0xdf, 0x02, 0xda, 0xdc, 0x9a, 0xd1, 0xa6, 0xae, 0xad, 0xb6, 0x0a, 0xb9, 0xa4, 0x48, 0x59, 0xfe, 0x3b, 0x35, 0x15, - 0x94, 0xd4, 0x72, 0xd1, 0x9b, 0x34, 0x5d, 0xf4, 0x78, 0x66, 0x24, 0x81, 0xca, 0x2d, 0x77, 0x8c, 0xfe, 0x10, 0x16, - 0x78, 0xc4, 0xc4, 0x89, 0x05, 0x73, 0xab, 0x13, 0x96, 0xcd, 0xc5, 0x62, 0xb4, 0x92, 0x10, 0x36, 0xf8, 0x98, 0x65, - 0xf3, 0x52, 0x3f, 0x84, 0xbe, 0xb0, 0xf4, 0x2d, 0xd8, 0xc5, 0x06, 0x2b, 0x59, 0x06, 0xe0, 0x7b, 0x41, 0x37, 0x2b, - 0x59, 0x46, 0x52, 0x75, 0x3f, 0xae, 0xb1, 0x04, 0x95, 0x56, 0xa8, 0xb4, 0xa4, 0xc6, 0x82, 0xc0, 0x57, 0x55, 0x97, - 0x0f, 0xc9, 0xae, 0x02, 0xf5, 0xd4, 0x51, 0x03, 0x4e, 0x81, 0xaa, 0x02, 0x0b, 0x92, 0xa0, 0x32, 0x74, 0x55, 0x60, - 0x5a, 0x81, 0x69, 0xa6, 0x0a, 0x17, 0x65, 0x76, 0x28, 0xcd, 0x7a, 0xc9, 0x67, 0xf1, 0x20, 0x4c, 0x86, 0x31, 0x79, - 0x8c, 0x50, 0xfb, 0x87, 0x79, 0x14, 0x6b, 0xb9, 0xe4, 0xca, 0xf9, 0xc5, 0xdf, 0x7e, 0xc2, 0x5e, 0xf7, 0x1c, 0x83, - 0x05, 0x38, 0x4b, 0xdb, 0xeb, 0x4c, 0xbc, 0x93, 0xad, 0xe0, 0x38, 0x98, 0x45, 0x39, 0xac, 0x7a, 0x72, 0x44, 0x73, - 0x91, 0x6b, 0xef, 0x22, 0x44, 0x0e, 0x32, 0x7b, 0x0c, 0xb0, 0x1b, 0xe1, 0xeb, 0xd0, 0xda, 0xdc, 0xea, 0x0a, 0xf1, - 0x37, 0x4a, 0x24, 0x7e, 0x94, 0xf2, 0xe3, 0x7a, 0xa5, 0x72, 0x55, 0x06, 0x8f, 0x55, 0x37, 0x83, 0x67, 0xda, 0xf7, - 0x58, 0xfb, 0xb7, 0xb6, 0x9b, 0xe3, 0xbd, 0x07, 0x0f, 0x5a, 0xff, 0x5b, 0x4f, 0x42, 0x68, 0xaf, 0x9c, 0xa4, 0xee, - 0xa8, 0xd1, 0x33, 0x93, 0x35, 0xa2, 0x12, 0xa6, 0x76, 0xa7, 0x72, 0x0c, 0xd4, 0x74, 0x00, 0xd7, 0x12, 0x35, 0x41, - 0x4f, 0x0a, 0x36, 0x86, 0x23, 0xce, 0xe2, 0xa0, 0x1d, 0xc7, 0x28, 0x5e, 0xce, 0x95, 0x78, 0x39, 0x3f, 0x61, 0x1c, - 0xa0, 0xb5, 0x00, 0xa9, 0x5e, 0xc3, 0x7e, 0xe6, 0x0a, 0x16, 0xd8, 0xdc, 0xf9, 0x8e, 0x2c, 0x90, 0x21, 0x4e, 0x36, - 0xc7, 0xc9, 0x1e, 0xd7, 0x7a, 0xee, 0x05, 0x3e, 0x4e, 0xea, 0x85, 0x57, 0x57, 0xd9, 0xae, 0x6b, 0xc9, 0xca, 0x79, - 0x31, 0x98, 0x40, 0x50, 0x96, 0x72, 0x5e, 0x0c, 0x27, 0x0b, 0x9a, 0xc3, 0x8f, 0x45, 0x03, 0x1d, 0x62, 0x39, 0x48, - 0xe0, 0xd2, 0xd9, 0x63, 0xc0, 0x1b, 0x4a, 0x2d, 0xee, 0xc6, 0x3a, 0x72, 0xac, 0xa3, 0x38, 0x0c, 0x63, 0xc0, 0x95, - 0x75, 0x02, 0xef, 0xfd, 0xd7, 0xc7, 0x26, 0x20, 0xab, 0x76, 0x85, 0x57, 0xa3, 0xdc, 0x75, 0xa5, 0xd1, 0x97, 0x94, - 0x9e, 0xf0, 0x82, 0xa7, 0x92, 0xed, 0xb6, 0x67, 0xe0, 0x6c, 0x89, 0x87, 0xc4, 0x3b, 0x46, 0xf4, 0x62, 0xda, 0xc8, - 0xcc, 0x09, 0x9c, 0xd9, 0xee, 0xb2, 0x8d, 0xf9, 0xb1, 0x03, 0x1c, 0x2c, 0x82, 0x90, 0xb8, 0x21, 0x0c, 0x13, 0x3b, - 0x29, 0x87, 0x5a, 0x08, 0xd7, 0xb5, 0xf0, 0x3a, 0x4e, 0xcb, 0x18, 0x5c, 0xa4, 0xb5, 0x6d, 0xe2, 0x1e, 0xba, 0xee, - 0xf9, 0x31, 0xb7, 0x3a, 0x46, 0x5b, 0x48, 0xbf, 0x1d, 0x9d, 0x3e, 0x70, 0x18, 0x80, 0xa6, 0x07, 0xb3, 0xaa, 0x7d, - 0x26, 0x71, 0x73, 0xda, 0x09, 0x42, 0x22, 0x10, 0x45, 0xe9, 0x8c, 0x30, 0xfd, 0x3b, 0xcd, 0x65, 0x15, 0xad, 0x1e, - 0xe4, 0x99, 0x43, 0x9e, 0x85, 0xde, 0xf6, 0xa0, 0x55, 0x73, 0x37, 0x18, 0x27, 0x6e, 0xb7, 0x77, 0xfe, 0xdf, 0xb2, - 0xae, 0xad, 0xd6, 0x88, 0xc7, 0xed, 0xea, 0x07, 0x8d, 0xbd, 0xda, 0x53, 0x31, 0x60, 0x56, 0xd2, 0x3b, 0xa3, 0x4a, - 0x5e, 0x64, 0xbc, 0xc4, 0x93, 0x6a, 0xd5, 0xf0, 0xf1, 0xbe, 0xcd, 0x46, 0xe6, 0x81, 0x4c, 0x01, 0xf1, 0xfc, 0x36, - 0x35, 0xea, 0xe3, 0x14, 0x25, 0xe0, 0xef, 0x74, 0x7c, 0x23, 0xfa, 0xd1, 0xbe, 0xb8, 0xe2, 0xd5, 0xdb, 0x5b, 0x61, - 0x5e, 0x3c, 0xb7, 0x3a, 0x7f, 0xfa, 0xba, 0xf0, 0xa1, 0xc3, 0x51, 0x7b, 0x07, 0x45, 0x96, 0x4c, 0x9c, 0x4c, 0x8c, - 0xac, 0x4d, 0xcc, 0x3e, 0x2a, 0xb8, 0x98, 0xa8, 0x42, 0xcf, 0x3a, 0x7b, 0xc2, 0x14, 0xa0, 0x6f, 0x1c, 0xa3, 0x92, - 0x31, 0x2c, 0x18, 0xa8, 0xd3, 0x94, 0x10, 0x3d, 0x14, 0x33, 0x8c, 0x57, 0x0c, 0xa0, 0x30, 0x85, 0x02, 0x51, 0x74, - 0xf6, 0xe1, 0x40, 0x13, 0xfa, 0xfd, 0xdb, 0x54, 0x67, 0xa0, 0x65, 0x3d, 0x2d, 0x40, 0x54, 0x07, 0xd1, 0x56, 0x79, - 0x11, 0xfe, 0xb0, 0xa4, 0x65, 0x46, 0x97, 0x82, 0xa6, 0x82, 0x26, 0x19, 0xbd, 0xe4, 0x4a, 0x54, 0x7c, 0x29, 0x98, - 0xa2, 0xed, 0x86, 0xb0, 0xff, 0xd0, 0xa0, 0xeb, 0xad, 0x58, 0x6b, 0x68, 0x77, 0x82, 0x8c, 0xd0, 0x7c, 0xa1, 0x83, - 0x90, 0xa1, 0x72, 0x12, 0xba, 0x56, 0x69, 0xbc, 0x02, 0x97, 0x4c, 0xb3, 0xd1, 0x32, 0x2e, 0xc3, 0xc0, 0x7e, 0x15, - 0x58, 0x4c, 0x0e, 0x4c, 0x3a, 0x5b, 0x5f, 0x3c, 0x93, 0xd7, 0x2b, 0x29, 0xb8, 0xa8, 0x14, 0x44, 0xbf, 0xc1, 0x7d, - 0x37, 0x71, 0xd5, 0x59, 0xb3, 0x56, 0xfa, 0xd0, 0xb7, 0x3e, 0x6b, 0xe3, 0xbe, 0x30, 0x38, 0x06, 0x3b, 0x1f, 0x11, - 0x03, 0x69, 0x50, 0xe9, 0x16, 0x87, 0x26, 0x40, 0x97, 0x0e, 0x29, 0x64, 0xc9, 0x54, 0xa6, 0x4a, 0x50, 0xf1, 0x8d, - 0xdf, 0x4b, 0x59, 0x8d, 0xfe, 0x5c, 0xf3, 0xe2, 0xfe, 0x8c, 0xe7, 0x1c, 0xc7, 0x28, 0x48, 0x62, 0x71, 0x13, 0x97, - 0x01, 0xf1, 0x2d, 0xaf, 0x82, 0xa3, 0xd4, 0x84, 0x8d, 0xd9, 0xa9, 0x1a, 0xb5, 0x5e, 0x05, 0xfa, 0xca, 0x28, 0xdf, - 0x18, 0x0c, 0x4d, 0x44, 0x15, 0xf4, 0xbd, 0x56, 0xf7, 0xb4, 0xba, 0x61, 0x01, 0xf1, 0xe7, 0x4a, 0x2f, 0xd4, 0x7a, - 0xdd, 0x8c, 0xb9, 0x61, 0x22, 0x04, 0x8d, 0xbe, 0xaa, 0x17, 0x0e, 0x3f, 0x7f, 0xa3, 0x2c, 0x89, 0xe0, 0xc5, 0x26, - 0x5d, 0x17, 0x26, 0x96, 0x06, 0xd5, 0x01, 0x73, 0xa3, 0x4d, 0xce, 0xaf, 0x40, 0xf4, 0xe7, 0xac, 0x88, 0x26, 0x75, - 0x4d, 0x15, 0x82, 0x61, 0xb4, 0xb9, 0x6b, 0xa4, 0xd3, 0x7b, 0xf0, 0x72, 0x33, 0xd6, 0x48, 0xda, 0xd3, 0xb1, 0xa6, - 0x05, 0x2f, 0x57, 0x52, 0x94, 0x10, 0xdd, 0xb9, 0x37, 0xa6, 0xd7, 0x71, 0x26, 0xaa, 0x38, 0x13, 0xa7, 0xe5, 0x8a, - 0x27, 0xd5, 0x7b, 0xa8, 0x50, 0x1b, 0xe3, 0x60, 0xeb, 0xd5, 0xa8, 0xab, 0x70, 0xc8, 0xaf, 0x2e, 0x5f, 0xdc, 0xad, - 0x62, 0x91, 0xc2, 0xa8, 0xd7, 0xfb, 0x5e, 0x34, 0xa7, 0x63, 0x15, 0x17, 0x5c, 0x98, 0xa8, 0xc5, 0xb4, 0x62, 0x01, - 0xd7, 0x19, 0x03, 0xca, 0x55, 0xec, 0xce, 0x4c, 0xc5, 0x32, 0x8c, 0xcb, 0xf2, 0xc7, 0xac, 0xc4, 0x3b, 0x00, 0xb4, - 0x06, 0x4e, 0x8b, 0x99, 0x01, 0x01, 0xb9, 0xcf, 0x0d, 0x2e, 0x02, 0x0b, 0x8e, 0x9e, 0x8c, 0x57, 0x77, 0x01, 0xf5, - 0xde, 0x48, 0x75, 0x3d, 0x64, 0xc1, 0x78, 0xf4, 0x34, 0x70, 0xc8, 0x21, 0xfe, 0x47, 0x4f, 0x8e, 0xf6, 0x7f, 0x33, - 0x09, 0x48, 0x3d, 0x05, 0x55, 0x85, 0x51, 0x88, 0xc2, 0xb4, 0xbf, 0x5e, 0xab, 0x5b, 0xee, 0xdb, 0x8b, 0x92, 0x17, - 0x37, 0x10, 0xad, 0x9d, 0x4c, 0x33, 0x20, 0xe7, 0x52, 0x25, 0xc0, 0xa2, 0x88, 0xab, 0xaa, 0xc8, 0x2e, 0xc0, 0x44, - 0x09, 0x0d, 0xc0, 0xcc, 0xd3, 0x4b, 0x74, 0xf8, 0x88, 0xe6, 0x01, 0xf6, 0x29, 0x58, 0xd4, 0xa4, 0x2e, 0xa1, 0xb0, - 0xe4, 0x00, 0x83, 0xd5, 0xa9, 0xb8, 0xd2, 0x8e, 0x53, 0xaf, 0x7e, 0x8f, 0x96, 0x12, 0x63, 0xcd, 0xea, 0x79, 0x8a, - 0x2f, 0x4a, 0x99, 0xaf, 0x2b, 0xd0, 0x9e, 0x5f, 0x56, 0xd1, 0xd1, 0x93, 0xd5, 0xdd, 0x54, 0x75, 0x23, 0x82, 0x5e, - 0x4c, 0x15, 0xce, 0x5b, 0x12, 0xe7, 0x49, 0x38, 0x19, 0x8f, 0xbf, 0x38, 0x18, 0x1e, 0x40, 0x32, 0x99, 0xfe, 0x35, - 0x54, 0x8e, 0x5c, 0xc3, 0xc9, 0x78, 0x5c, 0xff, 0x5e, 0x9b, 0x30, 0xdf, 0xa6, 0x9e, 0x67, 0xbf, 0x1f, 0xab, 0xf5, - 0x7f, 0x72, 0x7c, 0xa8, 0x7f, 0xfc, 0x5e, 0xd7, 0xd3, 0xd7, 0x45, 0x38, 0xff, 0x57, 0xa8, 0xd6, 0xf7, 0x69, 0x51, - 0xc4, 0xf7, 0x35, 0x44, 0x36, 0x15, 0xce, 0xbb, 0x86, 0x7a, 0x64, 0x81, 0x1e, 0x91, 0xe9, 0xa5, 0x60, 0xf0, 0xcd, - 0xfb, 0x2a, 0x0c, 0x78, 0xb9, 0x1a, 0x72, 0x51, 0x65, 0xd5, 0xfd, 0x10, 0xf3, 0x04, 0xf8, 0xa9, 0x19, 0xc7, 0x67, - 0x85, 0x21, 0xbe, 0x97, 0x05, 0xe7, 0x7f, 0xf1, 0x50, 0x19, 0x8b, 0x8f, 0xd1, 0x58, 0x7c, 0x4c, 0x55, 0x37, 0x26, - 0x5f, 0x53, 0xdd, 0xb7, 0xc9, 0xd7, 0x60, 0x92, 0x95, 0xb5, 0xbf, 0x51, 0xc6, 0x9a, 0xd1, 0x98, 0xde, 0xbc, 0xcc, - 0xb3, 0x15, 0x5c, 0x0a, 0x96, 0xfa, 0x47, 0x4d, 0xe8, 0x7b, 0xde, 0xce, 0x3e, 0x1a, 0x8d, 0x9e, 0x15, 0x74, 0x34, - 0x1a, 0x7d, 0xcc, 0x6a, 0x42, 0x57, 0xa2, 0xe3, 0xfd, 0x7b, 0x4e, 0x2f, 0x64, 0x7a, 0x1f, 0x05, 0x01, 0x5d, 0x66, - 0x69, 0xca, 0x85, 0x2a, 0xeb, 0x2c, 0x6d, 0xe7, 0x55, 0x2d, 0x44, 0x20, 0x24, 0xdd, 0x46, 0x84, 0x64, 0x22, 0xf4, - 0xed, 0x4e, 0xcf, 0x46, 0xa3, 0xd1, 0x59, 0x6a, 0xaa, 0x75, 0x17, 0x94, 0xd7, 0x68, 0x4e, 0xe1, 0xfc, 0x14, 0xc0, - 0x1a, 0xc9, 0x44, 0x7f, 0x39, 0xfc, 0xef, 0xe1, 0x6c, 0x3e, 0x1e, 0x7e, 0x33, 0x5a, 0x3c, 0x3e, 0xa4, 0x41, 0xe0, - 0x83, 0x78, 0x87, 0xda, 0xba, 0x65, 0x5a, 0x1e, 0x8f, 0xa7, 0xa4, 0x1c, 0xb0, 0x27, 0xd6, 0xb7, 0xe8, 0x8b, 0x27, - 0x80, 0xcc, 0x8a, 0x22, 0xe5, 0xc0, 0x49, 0x43, 0xf1, 0x6a, 0xf6, 0x4a, 0x00, 0x5e, 0x9c, 0x8d, 0xec, 0x60, 0xb4, - 0xa2, 0xe3, 0x08, 0xca, 0xab, 0xad, 0xa9, 0x48, 0x8f, 0xb1, 0xcc, 0x44, 0x49, 0x1d, 0x4f, 0xcb, 0xdb, 0xac, 0x4a, - 0x96, 0x18, 0xe8, 0x29, 0x2e, 0x79, 0xf0, 0x45, 0x10, 0x95, 0xec, 0xe8, 0xe9, 0x54, 0xc1, 0x1d, 0x63, 0x52, 0xca, - 0xaf, 0x20, 0xf1, 0x9b, 0x31, 0x42, 0xc2, 0x12, 0xed, 0xc1, 0x89, 0x35, 0xbe, 0xcc, 0x65, 0x0c, 0x1e, 0xad, 0xa5, - 0xe6, 0xe1, 0xec, 0xc9, 0x68, 0xed, 0x51, 0x5a, 0xcd, 0x91, 0xd0, 0x9c, 0x50, 0x32, 0x79, 0x58, 0x52, 0xf9, 0xc5, - 0x04, 0xbd, 0xa4, 0xc0, 0xcd, 0x3c, 0x82, 0xe3, 0xdf, 0x5a, 0x7a, 0xe8, 0xe5, 0x93, 0xb2, 0xc3, 0xf9, 0xff, 0x2e, - 0xe9, 0x62, 0x70, 0xe8, 0x86, 0xe6, 0xad, 0x76, 0xe7, 0xad, 0x90, 0x71, 0xac, 0xc2, 0x67, 0x29, 0xb1, 0xc6, 0xb8, - 0x9c, 0x9d, 0x6c, 0x4c, 0x77, 0x46, 0x55, 0x91, 0x5d, 0x87, 0x44, 0xf7, 0xca, 0x81, 0x84, 0x06, 0x51, 0x36, 0xc2, - 0xf5, 0x03, 0xd6, 0x33, 0x5e, 0x27, 0x6f, 0x78, 0x51, 0x65, 0x89, 0x7a, 0x7f, 0xd3, 0x78, 0x5f, 0xd7, 0x26, 0xa0, - 0xea, 0xbb, 0x82, 0xc1, 0x3c, 0xbf, 0x2d, 0x00, 0xc4, 0x14, 0x69, 0x80, 0x4f, 0x30, 0x83, 0xa0, 0x76, 0xcd, 0xbc, - 0x6a, 0x04, 0xdf, 0x80, 0xaf, 0xde, 0x15, 0x80, 0x41, 0x12, 0x82, 0x14, 0x19, 0x42, 0x03, 0x81, 0x40, 0xc3, 0x90, - 0x0b, 0x0c, 0x7e, 0xe2, 0xc5, 0x91, 0x54, 0x4e, 0x89, 0x3c, 0x0c, 0xf0, 0x47, 0x40, 0x55, 0x00, 0x12, 0xe3, 0x71, - 0x08, 0x2f, 0xd4, 0x2f, 0xf7, 0x46, 0xed, 0x11, 0xf6, 0x3a, 0x0d, 0x21, 0xd8, 0x10, 0x3e, 0x04, 0xb0, 0xa4, 0x08, - 0x7d, 0x8b, 0x5c, 0x46, 0x18, 0x5c, 0xe6, 0xd9, 0x4a, 0x27, 0x55, 0xa3, 0x8e, 0xe6, 0x43, 0xa9, 0x1d, 0xc9, 0x01, - 0xf5, 0xd2, 0x63, 0x4c, 0x2f, 0x54, 0xba, 0x2a, 0xca, 0x19, 0xe5, 0xbc, 0xd3, 0x13, 0xe3, 0xc2, 0x16, 0x72, 0x88, - 0x84, 0xf3, 0xae, 0x50, 0xa1, 0x70, 0xf8, 0x02, 0xc0, 0xc0, 0x40, 0xda, 0xb1, 0x1b, 0xef, 0x46, 0x65, 0x3f, 0xe7, - 0xec, 0xf0, 0xbf, 0xe7, 0xf1, 0xf0, 0xaf, 0xf1, 0xf0, 0x9b, 0xc5, 0x20, 0x1c, 0xda, 0x9f, 0xe4, 0xf1, 0xa3, 0x43, - 0xfa, 0x92, 0x5b, 0x2e, 0x0d, 0x16, 0x7e, 0x23, 0xd8, 0x8f, 0x5a, 0x09, 0x41, 0x14, 0xe0, 0x0d, 0xcb, 0xad, 0xc6, - 0x09, 0x00, 0x1e, 0x06, 0xff, 0x15, 0xa0, 0xd1, 0x94, 0xbb, 0x78, 0x81, 0xbe, 0x44, 0xfd, 0x3e, 0xf9, 0xaa, 0x61, - 0x30, 0x08, 0xe2, 0x1a, 0x15, 0x13, 0x86, 0xe8, 0x32, 0x26, 0x0a, 0x06, 0xd9, 0x66, 0xdf, 0x6e, 0x7b, 0x6d, 0x49, - 0x18, 0x7e, 0xe9, 0x67, 0x9a, 0x98, 0x79, 0x87, 0x1b, 0xdb, 0x4a, 0xae, 0x42, 0xc4, 0x0a, 0xd4, 0xbf, 0x72, 0x06, - 0xb1, 0x37, 0x6f, 0x32, 0xf0, 0xe9, 0xb0, 0x5f, 0x8c, 0x67, 0xc0, 0x46, 0xc1, 0x9d, 0xaf, 0xe0, 0x97, 0x19, 0xb8, - 0x79, 0x8b, 0x18, 0x05, 0x0e, 0x76, 0x49, 0xf4, 0xfb, 0xbd, 0x3c, 0x0b, 0x73, 0x8d, 0x3b, 0x9d, 0xd7, 0x46, 0x0d, - 0x81, 0x3a, 0x72, 0x50, 0x3f, 0xe8, 0x21, 0x18, 0xaa, 0x21, 0x28, 0x3a, 0xda, 0xe2, 0xea, 0xb5, 0xf5, 0x14, 0xa6, - 0xb7, 0xaa, 0xbe, 0x62, 0xf4, 0x87, 0xcc, 0x04, 0x16, 0xd2, 0xae, 0x39, 0xd6, 0x35, 0xc7, 0x48, 0x7b, 0xfa, 0x7d, - 0xd1, 0x20, 0x3f, 0x9d, 0x85, 0x07, 0x81, 0x2a, 0x55, 0xee, 0x94, 0x45, 0xb9, 0x2d, 0xcd, 0x1b, 0xc3, 0x9a, 0xe6, - 0x99, 0x8d, 0x73, 0x33, 0xeb, 0xf5, 0xc2, 0x10, 0x1d, 0x3c, 0xb1, 0x54, 0xac, 0x0d, 0xc2, 0x1d, 0x99, 0x84, 0xd1, - 0x35, 0xc8, 0x2e, 0xc3, 0x73, 0x4e, 0x90, 0x4f, 0x05, 0xf6, 0x41, 0x55, 0xeb, 0xe5, 0x84, 0xc7, 0x46, 0xbe, 0x6c, - 0x04, 0x0d, 0xf2, 0x92, 0xa2, 0xde, 0xc4, 0xed, 0xd8, 0x47, 0x2d, 0xe4, 0xca, 0x4d, 0x3d, 0xed, 0x69, 0x52, 0xd1, - 0x63, 0xbd, 0x4a, 0xfd, 0x02, 0x4b, 0x0b, 0x4b, 0x3e, 0x08, 0xed, 0x69, 0x5a, 0x81, 0x19, 0x6e, 0x6c, 0x06, 0x43, - 0x3f, 0x1c, 0x3f, 0x01, 0x9d, 0x51, 0xdb, 0x12, 0xc2, 0xd8, 0x0d, 0xc2, 0xca, 0x7b, 0x22, 0x5f, 0x3c, 0xf1, 0x2e, - 0x06, 0x21, 0x37, 0x9b, 0x59, 0x34, 0x30, 0xdd, 0xaf, 0x65, 0xb3, 0x79, 0xba, 0xb9, 0x5e, 0x94, 0x50, 0x01, 0xdb, - 0x6d, 0x25, 0x08, 0xfe, 0xfd, 0x98, 0xcd, 0xf0, 0x6f, 0xd6, 0xef, 0xf7, 0x42, 0xfc, 0xc5, 0x31, 0x98, 0xd1, 0x5c, - 0x2c, 0xd8, 0x47, 0x90, 0x31, 0x91, 0x08, 0x53, 0x95, 0x31, 0x20, 0xab, 0xc0, 0x22, 0xd0, 0x7c, 0xa0, 0x72, 0x61, - 0x26, 0x7b, 0x99, 0x73, 0x0d, 0x39, 0x6d, 0x8d, 0x53, 0x36, 0xca, 0x12, 0xe5, 0xca, 0x91, 0x8d, 0xe2, 0x3c, 0x8b, - 0x4b, 0x5e, 0x6e, 0xb7, 0xfa, 0x70, 0x4c, 0x0a, 0x0e, 0xec, 0xba, 0xa2, 0x52, 0x25, 0xeb, 0x48, 0x75, 0xe3, 0x2f, - 0xc3, 0x02, 0xf7, 0x29, 0x9f, 0x17, 0x86, 0x46, 0x1c, 0x80, 0x30, 0x83, 0xa9, 0x5b, 0x7a, 0x2f, 0x2c, 0xa0, 0x79, - 0x25, 0x21, 0x1b, 0x4c, 0xf5, 0x2c, 0x7c, 0x63, 0x26, 0xe6, 0xc5, 0x02, 0xc2, 0xea, 0x14, 0x0b, 0xcd, 0x6c, 0xd2, - 0x84, 0xc5, 0x00, 0x9b, 0x17, 0x93, 0x29, 0xc4, 0x77, 0x57, 0xe5, 0xc4, 0x0b, 0x73, 0xdf, 0x4e, 0x1c, 0x72, 0x08, - 0xbc, 0xaa, 0x0d, 0xba, 0x9a, 0x6d, 0x38, 0xea, 0x48, 0x39, 0x31, 0xf9, 0xfd, 0x54, 0x41, 0x88, 0x3b, 0x71, 0x24, - 0x5c, 0xde, 0x6c, 0x17, 0x5e, 0x74, 0x20, 0xe8, 0xa8, 0xc1, 0x29, 0x3f, 0x31, 0x38, 0x1a, 0x93, 0x74, 0xe3, 0x9d, - 0x20, 0x45, 0x18, 0x93, 0x8d, 0x64, 0xd7, 0x32, 0x14, 0xf3, 0x78, 0x01, 0xca, 0xcb, 0x78, 0x01, 0x96, 0x46, 0xc6, - 0x20, 0x15, 0xe4, 0x77, 0xdc, 0x0b, 0x85, 0x45, 0x71, 0x85, 0x48, 0xcf, 0xea, 0xf7, 0x51, 0xd1, 0x0e, 0x05, 0x82, - 0xe2, 0x0e, 0x65, 0x9e, 0x9c, 0xf5, 0x58, 0x20, 0xb1, 0x21, 0x60, 0x7c, 0xa5, 0xd3, 0x54, 0x6b, 0xdd, 0x1b, 0x33, - 0x0f, 0x7c, 0x9a, 0x8d, 0x84, 0xac, 0xce, 0x2f, 0x41, 0xa4, 0xe4, 0xa3, 0xe3, 0x23, 0xbf, 0x88, 0x3b, 0xcb, 0xbc, - 0xb5, 0x2d, 0x2a, 0xd9, 0xc9, 0x06, 0x40, 0x0b, 0x75, 0xf4, 0x2c, 0x25, 0xb7, 0x29, 0x49, 0xed, 0x36, 0x05, 0xac, - 0x24, 0x7f, 0x01, 0x43, 0xf0, 0xb5, 0x03, 0xe1, 0x74, 0xac, 0x10, 0xaf, 0x69, 0x8a, 0x48, 0x93, 0x61, 0x49, 0x71, - 0x6c, 0x4b, 0x44, 0x41, 0xb5, 0x65, 0xd9, 0xc1, 0x30, 0x51, 0x82, 0x9f, 0xa7, 0x1e, 0x25, 0x0a, 0x02, 0xaa, 0x87, - 0x1c, 0x24, 0xd8, 0xb6, 0x81, 0xf0, 0x80, 0x3c, 0xa2, 0x37, 0xd6, 0xdf, 0x65, 0x9d, 0x67, 0x17, 0x9a, 0xe7, 0x72, - 0xbd, 0x2b, 0xcc, 0x18, 0xe1, 0x49, 0x66, 0xc2, 0x06, 0x78, 0xe7, 0x99, 0x51, 0xdb, 0xf4, 0x3c, 0xbc, 0xb6, 0x53, - 0x8c, 0xd0, 0xb7, 0x67, 0xd0, 0x4d, 0x30, 0xaf, 0x0e, 0x9b, 0xf5, 0x4a, 0x41, 0x6a, 0x98, 0x5a, 0x34, 0x31, 0xeb, - 0x59, 0x83, 0xf2, 0xed, 0xb6, 0xa7, 0xe7, 0x6a, 0xff, 0xdc, 0x6d, 0xb7, 0x3d, 0xec, 0xd6, 0xf3, 0xb4, 0xdb, 0x2a, - 0xbe, 0x52, 0x1f, 0xb4, 0xc7, 0x9f, 0xbb, 0xf1, 0xe7, 0x06, 0xd9, 0xa4, 0x74, 0x34, 0xd3, 0xd6, 0x07, 0xe1, 0x81, - 0xd3, 0xfb, 0x46, 0x93, 0xbe, 0xcb, 0x42, 0x49, 0x57, 0xa2, 0x51, 0x5d, 0xed, 0x4c, 0x4c, 0x1f, 0x5c, 0xff, 0x0f, - 0xaf, 0x02, 0x3c, 0xe2, 0xd4, 0xce, 0xde, 0xdb, 0xa0, 0xa2, 0xd1, 0x16, 0x8e, 0x14, 0xa1, 0x07, 0x24, 0x61, 0x5f, - 0xcb, 0x5a, 0xdc, 0xe6, 0x59, 0xf6, 0x30, 0x7d, 0x7a, 0x95, 0xfa, 0x5e, 0x08, 0x6e, 0x99, 0x65, 0xe6, 0xc0, 0xab, - 0x28, 0x0e, 0x68, 0xd4, 0x45, 0xfb, 0xae, 0xb3, 0xb2, 0x04, 0xaf, 0x17, 0xb8, 0x57, 0x9e, 0x71, 0x1f, 0x7e, 0xef, - 0xaa, 0x6a, 0x6e, 0xd2, 0xb3, 0x6c, 0x9e, 0x2d, 0xb6, 0xdb, 0x10, 0xff, 0x76, 0xb5, 0xc8, 0xd1, 0xe4, 0x39, 0xe8, - 0x34, 0x31, 0x92, 0x11, 0xd3, 0x8d, 0xf3, 0x36, 0xff, 0x1b, 0xd1, 0x70, 0x9a, 0x38, 0x05, 0x7a, 0x31, 0x7b, 0x04, - 0x32, 0x29, 0x03, 0x72, 0x20, 0x66, 0x7a, 0xcd, 0x40, 0x34, 0x32, 0x11, 0x01, 0xae, 0x30, 0x36, 0x12, 0x8d, 0x4e, - 0x38, 0xa9, 0x09, 0x58, 0xb0, 0xda, 0xf2, 0x3e, 0x58, 0xda, 0x56, 0x15, 0xf7, 0xde, 0x92, 0xe6, 0xb8, 0x0e, 0x9c, - 0xaf, 0x83, 0x19, 0x62, 0x53, 0x76, 0xb5, 0x40, 0xee, 0x97, 0xd7, 0xb4, 0x37, 0xae, 0x13, 0x98, 0xb5, 0x4d, 0x6d, - 0x19, 0x3f, 0x5b, 0xfa, 0x8f, 0x7a, 0x70, 0x95, 0x31, 0xd8, 0xdc, 0x58, 0x69, 0xd8, 0x7d, 0xe3, 0xf9, 0x52, 0x40, - 0x78, 0x3a, 0x9f, 0x1e, 0x9f, 0x65, 0x1e, 0x3d, 0x06, 0xa2, 0x63, 0x3e, 0x2a, 0xdd, 0x47, 0x76, 0xf7, 0xfa, 0x01, - 0x01, 0xe7, 0x55, 0xbb, 0xa0, 0x79, 0xb9, 0x80, 0xc0, 0xaa, 0x5e, 0x79, 0x85, 0xe5, 0x33, 0x63, 0x76, 0x05, 0x64, - 0xa8, 0x20, 0x10, 0xb8, 0xbb, 0xeb, 0x5c, 0x88, 0x55, 0x87, 0x95, 0x39, 0x4d, 0xc2, 0x4e, 0x42, 0x34, 0x6f, 0x0d, - 0x66, 0xc1, 0x7f, 0x05, 0x83, 0x72, 0x10, 0x44, 0x41, 0x14, 0x04, 0x64, 0x50, 0xc0, 0x2f, 0xc4, 0x5d, 0x23, 0x18, - 0xb3, 0x05, 0x3a, 0xfc, 0x8e, 0x33, 0x9f, 0x11, 0x79, 0xd1, 0x08, 0xeb, 0xe9, 0x06, 0xe0, 0x42, 0xca, 0x9c, 0xc7, - 0xe8, 0x73, 0xf2, 0x8e, 0xb3, 0x8c, 0xd0, 0x77, 0xde, 0xa9, 0xfc, 0x88, 0x37, 0x82, 0xfd, 0xed, 0x0e, 0xdb, 0x4b, - 0x90, 0x57, 0xf4, 0xc6, 0xf4, 0x1d, 0x27, 0x51, 0xd6, 0x70, 0xa6, 0xe6, 0xd0, 0xb3, 0xca, 0xb2, 0x56, 0xd4, 0x90, - 0x1b, 0x14, 0x73, 0x23, 0xcb, 0xe4, 0x64, 0xda, 0x6a, 0x4e, 0x05, 0xae, 0x3b, 0xbb, 0x5e, 0x40, 0x72, 0x28, 0x34, - 0x4b, 0x67, 0xc3, 0x79, 0xdb, 0x96, 0x3d, 0x6f, 0x9d, 0x42, 0x5e, 0x43, 0x54, 0x34, 0x48, 0x47, 0x40, 0x0d, 0xad, - 0xb8, 0xaa, 0xc0, 0x85, 0xd9, 0xb4, 0x87, 0x9b, 0xf6, 0x98, 0x66, 0x7c, 0x80, 0x98, 0x79, 0x1c, 0x5b, 0x06, 0x76, - 0x24, 0x0e, 0xdf, 0xc7, 0xf9, 0x02, 0xed, 0xd2, 0x5b, 0x57, 0x8b, 0x47, 0x58, 0x7b, 0xde, 0x0a, 0x09, 0x01, 0xe2, - 0xd3, 0x54, 0xba, 0xdd, 0x06, 0x01, 0x0c, 0x70, 0xbf, 0xdf, 0x03, 0xae, 0xd5, 0xb0, 0x93, 0xe6, 0xd6, 0x6c, 0x89, - 0xbd, 0xa2, 0xf0, 0x18, 0x98, 0x53, 0xf3, 0x9f, 0x41, 0x40, 0xf1, 0xdc, 0x0d, 0xc1, 0xde, 0x94, 0x9d, 0x6c, 0x8a, - 0x7e, 0xff, 0x79, 0x81, 0x0f, 0x28, 0x17, 0x06, 0x31, 0xb7, 0x8e, 0xe3, 0x61, 0xd8, 0x27, 0xf5, 0x21, 0x8e, 0x45, - 0x9e, 0x85, 0x8e, 0xb0, 0x54, 0x86, 0xb0, 0x70, 0xc5, 0x48, 0x07, 0x71, 0x50, 0x93, 0xce, 0xc1, 0xaa, 0x5c, 0xf0, - 0xe5, 0x5e, 0xef, 0x0d, 0xc0, 0xa4, 0x67, 0xde, 0xb0, 0xbc, 0xf7, 0x00, 0xd1, 0x7a, 0x3d, 0x5c, 0x28, 0xee, 0xe5, - 0xcb, 0x06, 0x1a, 0x27, 0xbe, 0xb4, 0xec, 0xfa, 0x4c, 0xcb, 0x4a, 0x46, 0xa3, 0x51, 0x55, 0x2b, 0xc9, 0x87, 0x23, - 0x2f, 0x2d, 0x14, 0x4f, 0x19, 0xa7, 0x3c, 0x05, 0xcb, 0x77, 0x43, 0xe9, 0xe6, 0x0b, 0xba, 0xe2, 0x22, 0x55, 0x3f, - 0x3d, 0xf4, 0xcd, 0x06, 0x71, 0xcd, 0x9a, 0x3a, 0x1c, 0x3b, 0xfc, 0x10, 0x00, 0xd3, 0x3e, 0xcc, 0x5c, 0xba, 0x86, - 0xe9, 0x05, 0xf1, 0x6c, 0x5c, 0xf0, 0xd0, 0xe5, 0x01, 0xec, 0x43, 0x73, 0x48, 0xe2, 0xa7, 0xf0, 0x73, 0x66, 0xd2, - 0x3a, 0x3e, 0xc3, 0xd9, 0x8c, 0x4a, 0x75, 0x23, 0x68, 0xbf, 0x86, 0x44, 0x62, 0x90, 0x9e, 0x1b, 0x0c, 0x45, 0xeb, - 0x6e, 0x03, 0x57, 0x7e, 0x4b, 0xef, 0x7c, 0x1a, 0x04, 0x58, 0xdf, 0x58, 0x0c, 0x00, 0xa8, 0xe2, 0x0f, 0x54, 0x5d, - 0x99, 0x2b, 0x8a, 0x69, 0x98, 0x4a, 0xb4, 0x77, 0x1c, 0xd7, 0x51, 0xe3, 0x3a, 0x2c, 0x58, 0x69, 0x6d, 0x9b, 0xdd, - 0x5b, 0x5a, 0xd8, 0x12, 0x50, 0x2d, 0x88, 0x3b, 0x01, 0x7c, 0x68, 0xa4, 0x3a, 0x10, 0x64, 0xf7, 0xc1, 0x01, 0x00, - 0x6f, 0x78, 0x1e, 0x86, 0xf0, 0x07, 0x16, 0x0e, 0x2c, 0x4b, 0xd5, 0xcf, 0xe5, 0x34, 0x86, 0x73, 0x37, 0x57, 0x3b, - 0x7c, 0xb6, 0x04, 0xc5, 0xa6, 0x9a, 0x53, 0x73, 0xf9, 0xca, 0x1b, 0xfb, 0x3d, 0x26, 0x98, 0xc7, 0xcc, 0x36, 0xfc, - 0xd6, 0xd3, 0x6d, 0x7d, 0x83, 0xdd, 0xc0, 0x49, 0x7b, 0xe1, 0xb4, 0x17, 0xdb, 0xa5, 0x81, 0xfc, 0xab, 0x1b, 0x42, - 0x84, 0x57, 0x9a, 0x58, 0x64, 0x0d, 0x99, 0x8e, 0xc5, 0x0a, 0x51, 0x6d, 0x2a, 0x9e, 0x69, 0x03, 0x81, 0x72, 0xaa, - 0x2e, 0x4c, 0xad, 0x54, 0x26, 0x0c, 0xe2, 0x4e, 0x09, 0x8b, 0x2a, 0x03, 0x0c, 0x83, 0x0a, 0x29, 0xae, 0xad, 0xe7, - 0x2f, 0x5c, 0xbe, 0x99, 0x69, 0xb3, 0xfd, 0xf4, 0x65, 0x1e, 0x5f, 0x6d, 0xb7, 0x61, 0xf7, 0x0b, 0x30, 0x47, 0x2d, - 0x95, 0x86, 0x11, 0x9c, 0x40, 0x94, 0xe4, 0x7a, 0x4f, 0xce, 0x89, 0xe3, 0xe4, 0xda, 0xcd, 0x9b, 0xed, 0xa4, 0x18, - 0x81, 0x05, 0x9c, 0xb8, 0x48, 0x07, 0x5a, 0x2a, 0x49, 0xed, 0x29, 0xe0, 0x6d, 0x7a, 0x47, 0xa9, 0xf0, 0x6a, 0xa1, - 0x49, 0x48, 0xe5, 0xee, 0x25, 0x76, 0xd4, 0x80, 0x73, 0x52, 0x77, 0x10, 0x70, 0xda, 0xd3, 0x8d, 0xb5, 0x8a, 0x64, - 0x93, 0xe0, 0xbd, 0xd2, 0x43, 0x97, 0x68, 0xa7, 0x76, 0xb7, 0xad, 0xca, 0x16, 0x0a, 0xe6, 0x41, 0xce, 0x12, 0x75, - 0x3c, 0xa0, 0xd0, 0x45, 0x1d, 0x0d, 0xf9, 0x82, 0x14, 0x7a, 0xe5, 0x68, 0x55, 0xf3, 0xae, 0x64, 0xa0, 0x54, 0xab, - 0x20, 0xaf, 0x89, 0x75, 0x5f, 0xcb, 0x1a, 0x8b, 0x2b, 0x27, 0xa4, 0xb0, 0x09, 0x9f, 0x5b, 0x8a, 0x85, 0x59, 0xec, - 0x8d, 0xa9, 0x2f, 0x5c, 0x22, 0xb4, 0xdd, 0x6d, 0x88, 0xd1, 0x06, 0xeb, 0x66, 0xbb, 0x7d, 0x55, 0x84, 0xf3, 0x6c, - 0x41, 0xe5, 0x28, 0x4b, 0x11, 0x52, 0xcd, 0x78, 0x2c, 0xdb, 0x2e, 0x98, 0x89, 0xa1, 0xae, 0x3d, 0x5e, 0x92, 0x29, - 0xd6, 0x26, 0xc9, 0x51, 0x7c, 0x21, 0x0b, 0xb5, 0xd6, 0x08, 0xc1, 0xc3, 0xfd, 0x8f, 0x14, 0x62, 0xda, 0x99, 0x75, - 0xf7, 0xed, 0xce, 0x0d, 0xf1, 0x0f, 0x08, 0xac, 0x50, 0xb2, 0x57, 0xc5, 0xe8, 0x22, 0x13, 0x29, 0xee, 0x54, 0x15, - 0x25, 0x58, 0xad, 0x83, 0x66, 0xcb, 0xed, 0xbd, 0xd8, 0x12, 0x05, 0x88, 0xf3, 0x2c, 0x34, 0xe3, 0x59, 0x39, 0xcb, - 0x99, 0x8c, 0x62, 0x43, 0xa2, 0xd2, 0x8b, 0x12, 0xef, 0xf3, 0x34, 0xa6, 0x87, 0x6e, 0x0d, 0x82, 0xeb, 0xea, 0xce, - 0x46, 0x9a, 0x2f, 0x08, 0x51, 0x13, 0x20, 0x61, 0xa3, 0x9a, 0x53, 0xeb, 0x4a, 0x3c, 0xcc, 0x2a, 0x9f, 0xeb, 0x83, - 0xf8, 0x4a, 0x00, 0x0f, 0xeb, 0x6d, 0xef, 0x6b, 0xe1, 0xb1, 0x36, 0xf8, 0x76, 0xbb, 0xbd, 0x12, 0xf3, 0x20, 0xf0, - 0x18, 0xcd, 0x5f, 0x94, 0xc4, 0xbc, 0x37, 0xa6, 0xb0, 0xe2, 0x7d, 0x17, 0xbf, 0x6e, 0x52, 0x6b, 0x2d, 0x72, 0x77, - 0xb8, 0x3e, 0xe0, 0x79, 0x4a, 0x1c, 0xed, 0xa8, 0x9c, 0x4a, 0x6b, 0x3b, 0x80, 0x5d, 0x11, 0x18, 0x28, 0xfb, 0xfb, - 0x94, 0x6d, 0xc0, 0x3c, 0x11, 0xac, 0x8f, 0xd0, 0x6f, 0x4b, 0xe9, 0x4f, 0xc6, 0x68, 0xdc, 0x23, 0xd7, 0x55, 0x74, - 0xc4, 0x75, 0x34, 0x7b, 0x1e, 0xfd, 0xed, 0xe9, 0x98, 0x16, 0xb1, 0x48, 0xe5, 0x35, 0xa8, 0x20, 0x40, 0x19, 0x82, - 0x8e, 0x10, 0x9a, 0x1a, 0x80, 0x06, 0xc1, 0x0d, 0xc0, 0x3f, 0x3b, 0x9d, 0x28, 0x6d, 0x4d, 0x3e, 0x46, 0xab, 0x2a, - 0x72, 0xd6, 0x86, 0x76, 0x53, 0xc9, 0x21, 0x79, 0x5c, 0x02, 0xbe, 0x25, 0x36, 0x4b, 0xd9, 0xa0, 0xa8, 0xcd, 0xa6, - 0x5e, 0x2b, 0x76, 0xe4, 0xae, 0x51, 0xb4, 0x59, 0x8b, 0xda, 0x6e, 0x64, 0xbe, 0x98, 0xde, 0x59, 0x61, 0xe0, 0xd4, - 0xb4, 0xe6, 0x76, 0x07, 0x4a, 0xce, 0xd6, 0x67, 0x72, 0x13, 0x20, 0x0e, 0x30, 0x5c, 0x77, 0xf3, 0xdb, 0x05, 0xa1, - 0x77, 0xec, 0xce, 0x8a, 0x55, 0x6f, 0xad, 0x5c, 0xc4, 0xa4, 0xdd, 0x0e, 0x26, 0x70, 0x19, 0x67, 0x85, 0x7d, 0xa1, - 0xd5, 0x0d, 0x45, 0x47, 0xdb, 0xa4, 0xfd, 0xbc, 0xa3, 0xdd, 0x70, 0xc1, 0xb7, 0x62, 0x1d, 0xe7, 0x96, 0x35, 0x55, - 0x68, 0xda, 0x81, 0xde, 0x0e, 0x01, 0xcd, 0xd9, 0x98, 0x2e, 0x69, 0x8a, 0x17, 0x68, 0xba, 0x06, 0x33, 0x9d, 0x4b, - 0xe8, 0x6b, 0xb7, 0x8f, 0xf6, 0xa5, 0xea, 0x89, 0xf0, 0x96, 0x28, 0xf8, 0xb6, 0xa4, 0xe0, 0xa5, 0x96, 0xf3, 0xd8, - 0xcc, 0x21, 0xe0, 0xd3, 0xa8, 0x12, 0xbd, 0x93, 0xe2, 0x0a, 0xb4, 0x99, 0x70, 0x04, 0x9a, 0xaa, 0x11, 0x5b, 0x39, - 0xc0, 0xed, 0xc5, 0xd3, 0x80, 0x50, 0x90, 0xea, 0xae, 0xed, 0x8a, 0xbc, 0x63, 0x27, 0x9b, 0x3b, 0x30, 0x13, 0xae, - 0xd6, 0x65, 0xeb, 0x2b, 0x9b, 0xec, 0x3e, 0xae, 0x09, 0xb6, 0xdd, 0xdb, 0x20, 0xe1, 0x1d, 0xbd, 0x25, 0x9b, 0xdb, - 0x7e, 0x3f, 0x84, 0xfe, 0x10, 0xaa, 0x3b, 0x74, 0xd7, 0xd9, 0xa1, 0x3b, 0x9f, 0xf9, 0xb5, 0x7a, 0x3e, 0xe5, 0x1d, - 0xf2, 0x01, 0x4d, 0xd6, 0xe8, 0x2a, 0xbe, 0x87, 0x4d, 0x1d, 0x55, 0x54, 0x55, 0x1e, 0x25, 0x14, 0x54, 0xe2, 0x19, - 0x2f, 0xcf, 0x38, 0xc6, 0x7a, 0xd5, 0x4f, 0xef, 0x34, 0xaf, 0xb6, 0x36, 0x6b, 0xb3, 0x5c, 0x5f, 0x80, 0x85, 0xc4, - 0x05, 0x8f, 0xae, 0x35, 0x2d, 0xb9, 0xf2, 0x98, 0xfa, 0x73, 0x1c, 0x95, 0xe0, 0x32, 0xce, 0x72, 0x50, 0xe3, 0x5e, - 0x36, 0xfb, 0x1f, 0x6a, 0xdb, 0xb1, 0x65, 0xe3, 0xcc, 0xbd, 0x09, 0xc9, 0xe6, 0x7f, 0x6c, 0xa0, 0x5e, 0x87, 0x18, - 0x21, 0xd6, 0x2c, 0xe8, 0xb7, 0x0c, 0x62, 0x85, 0x06, 0xe5, 0x3a, 0x49, 0x78, 0x59, 0x06, 0x46, 0xa9, 0xb5, 0x66, - 0x6b, 0x73, 0x9e, 0x3d, 0x62, 0x27, 0x8f, 0x7a, 0x8c, 0xdd, 0x11, 0x9a, 0x68, 0x9d, 0x90, 0xa9, 0x31, 0xf2, 0xb4, - 0x40, 0xba, 0x43, 0x51, 0x76, 0x19, 0xbe, 0x45, 0x21, 0x4b, 0x7b, 0x9f, 0x9b, 0x13, 0x59, 0x7d, 0xa3, 0x8d, 0x50, - 0x22, 0x95, 0x08, 0xb2, 0xf1, 0x5b, 0x04, 0x30, 0x86, 0x66, 0x07, 0x64, 0xb3, 0x64, 0x67, 0xf4, 0xdc, 0x9a, 0x04, - 0xc1, 0xeb, 0xb7, 0x2a, 0xd1, 0x8c, 0xb2, 0x22, 0xba, 0xca, 0xe8, 0xe7, 0x3e, 0x24, 0xd1, 0x79, 0x48, 0xfc, 0xdc, - 0xb0, 0xb4, 0x6e, 0x42, 0x14, 0x33, 0x9b, 0x0d, 0xaf, 0xba, 0xfb, 0xa8, 0xb1, 0xad, 0x8c, 0x8f, 0xf9, 0x9d, 0x4d, - 0x23, 0x53, 0xe8, 0xeb, 0x70, 0xd2, 0xef, 0xc3, 0x5f, 0x4d, 0x3f, 0xf0, 0x96, 0x82, 0xbf, 0xd8, 0x23, 0x52, 0x27, - 0x2c, 0x00, 0x78, 0xc6, 0x9c, 0x57, 0xcd, 0x09, 0x7c, 0xc4, 0x4e, 0x36, 0x8f, 0xc2, 0xb3, 0xc6, 0xcc, 0xdd, 0x87, - 0x78, 0xa9, 0x4a, 0x7a, 0xde, 0x3c, 0x99, 0x81, 0x58, 0x59, 0xad, 0xf9, 0x1d, 0xb3, 0xfa, 0x04, 0x20, 0x52, 0x77, - 0xd6, 0xc1, 0x16, 0x3f, 0x36, 0x5d, 0x26, 0x9b, 0x94, 0xb5, 0x99, 0x28, 0xa5, 0x22, 0x69, 0x2e, 0x02, 0xe8, 0x37, - 0x0c, 0x47, 0x0d, 0x70, 0xe7, 0x7a, 0xec, 0xcd, 0xd0, 0x78, 0x63, 0x6a, 0xe8, 0xd9, 0x46, 0x2f, 0x6f, 0x47, 0x21, - 0xcc, 0x58, 0x44, 0x77, 0xee, 0x58, 0x0c, 0xcf, 0xe8, 0x5b, 0xa8, 0xf0, 0x75, 0x88, 0xd1, 0x85, 0x49, 0x5d, 0x4f, - 0xd7, 0x6a, 0x2b, 0xdd, 0x12, 0x9a, 0x63, 0x54, 0x23, 0xaf, 0x6d, 0xf7, 0xd4, 0x08, 0xed, 0x09, 0xe5, 0xe1, 0x1d, - 0xad, 0xe8, 0xad, 0x65, 0x11, 0x9c, 0xfc, 0xd8, 0xcb, 0x4f, 0xe8, 0x85, 0x27, 0x30, 0x29, 0xda, 0x1a, 0xc0, 0xef, - 0x51, 0x3f, 0x9c, 0xd5, 0x53, 0x2b, 0xe5, 0xf0, 0x14, 0xbe, 0x64, 0x03, 0x72, 0x05, 0xbd, 0x58, 0x63, 0x76, 0x12, - 0x83, 0x0e, 0x6a, 0x67, 0x77, 0x78, 0x93, 0x52, 0x86, 0x68, 0x8d, 0xe8, 0x20, 0xaf, 0xfe, 0x09, 0x9a, 0x3e, 0x48, - 0x0b, 0x53, 0xba, 0x46, 0x01, 0x0f, 0xe8, 0x9b, 0xfa, 0xfd, 0x1c, 0x9f, 0x6b, 0xcf, 0x32, 0x0d, 0x7b, 0xbc, 0x24, - 0x74, 0xe9, 0xc5, 0xd1, 0x02, 0x69, 0xb3, 0x63, 0x15, 0x80, 0x15, 0x49, 0xa0, 0x11, 0x09, 0x58, 0x2e, 0x79, 0xe2, - 0xb2, 0x0d, 0x1a, 0xd4, 0x44, 0x25, 0x85, 0x2c, 0x91, 0x04, 0x7e, 0x18, 0x41, 0x99, 0xa2, 0x18, 0xc4, 0xbd, 0x7a, - 0x79, 0xc5, 0x35, 0x35, 0x60, 0x4d, 0x11, 0x4c, 0xb0, 0x4e, 0xa7, 0x40, 0x6c, 0xc5, 0x7a, 0x05, 0x9e, 0xa8, 0x8e, - 0x13, 0x47, 0x96, 0x00, 0x0d, 0xf4, 0x7c, 0xe9, 0xb4, 0x5b, 0xde, 0x9e, 0x68, 0xa9, 0x62, 0x73, 0xef, 0xc5, 0xc2, - 0x72, 0x8f, 0x95, 0xbf, 0x1d, 0x68, 0x2f, 0xac, 0x76, 0x44, 0xd4, 0x60, 0x75, 0xd8, 0xb6, 0xf3, 0x43, 0x69, 0xa8, - 0xee, 0x95, 0x63, 0x02, 0x2a, 0xba, 0x8a, 0xab, 0x65, 0x94, 0x8d, 0xe0, 0xcf, 0x76, 0x1b, 0x1c, 0x06, 0x60, 0x11, - 0xfa, 0xf3, 0xfb, 0x1f, 0x23, 0x0c, 0x57, 0xf5, 0xf3, 0xfb, 0x1f, 0xb7, 0xdb, 0xa7, 0xe3, 0xb1, 0xe1, 0x0a, 0x9c, - 0x5a, 0x07, 0xf8, 0x03, 0xc3, 0x36, 0xd8, 0x25, 0xbb, 0xdd, 0x3e, 0x05, 0x0e, 0x42, 0xb1, 0x0d, 0x66, 0x17, 0x2b, - 0xc7, 0x36, 0xc5, 0x6a, 0xe8, 0x1d, 0x09, 0xd8, 0x7d, 0x3b, 0x2c, 0xc5, 0x2e, 0xf5, 0x51, 0x21, 0x29, 0xf5, 0xa2, - 0x7f, 0xd1, 0x29, 0xb0, 0xa4, 0x60, 0xca, 0x1b, 0x2c, 0xab, 0x6a, 0x55, 0x46, 0x87, 0x87, 0xf1, 0x2a, 0x1b, 0x95, - 0x19, 0x6c, 0xf3, 0xf2, 0xe6, 0x0a, 0x00, 0x26, 0x02, 0xda, 0x78, 0xb7, 0x16, 0x99, 0x79, 0xb1, 0xa0, 0xcb, 0x0c, - 0xd7, 0x24, 0x98, 0x1d, 0xe4, 0xdc, 0xea, 0x26, 0xa7, 0xc4, 0x3e, 0x80, 0x0d, 0xe6, 0x76, 0xdb, 0xe0, 0x17, 0x4e, - 0x46, 0x4f, 0x67, 0xcb, 0x4c, 0x1b, 0xb8, 0x72, 0xb3, 0xff, 0x49, 0xe4, 0xa5, 0xa1, 0xe2, 0x93, 0x4c, 0x5f, 0x64, - 0xc0, 0xe7, 0xb1, 0xbf, 0x44, 0xe8, 0xb3, 0x5c, 0x8d, 0xd6, 0x00, 0x1b, 0x9b, 0x5d, 0xde, 0x8f, 0x52, 0x0e, 0x11, - 0x3a, 0x02, 0xab, 0xae, 0x59, 0x66, 0xc4, 0xb7, 0xa9, 0xb8, 0x6f, 0xa9, 0xc2, 0xfe, 0x12, 0x9e, 0xf3, 0x0e, 0x37, - 0x8e, 0x43, 0xbd, 0x49, 0x14, 0xbe, 0x40, 0x21, 0x2a, 0x47, 0xe3, 0x42, 0x27, 0x90, 0xca, 0x3c, 0x26, 0x14, 0x73, - 0xb8, 0x77, 0x3f, 0xa7, 0xce, 0x5c, 0xc6, 0x17, 0xee, 0xbd, 0xf0, 0x65, 0x26, 0x77, 0x12, 0x40, 0xa2, 0x54, 0xed, - 0x3f, 0x7d, 0x42, 0x6a, 0xfc, 0xaf, 0x54, 0x6b, 0x00, 0x7a, 0x3f, 0x41, 0x4d, 0x8e, 0x20, 0x60, 0x2b, 0xa6, 0x7e, - 0x74, 0x01, 0x2b, 0x99, 0xff, 0x80, 0xba, 0x1d, 0xc1, 0x36, 0x2a, 0x9e, 0x50, 0x54, 0xd1, 0x82, 0xa7, 0x6b, 0x91, - 0xc6, 0x22, 0xb9, 0x8f, 0x78, 0x3d, 0xc5, 0x92, 0x98, 0x8d, 0x18, 0xf6, 0x53, 0xb3, 0x0b, 0x3f, 0x16, 0x0d, 0x93, - 0x78, 0x5a, 0xfa, 0xdb, 0xca, 0xdb, 0x4c, 0x96, 0x71, 0x46, 0xa6, 0x5c, 0x21, 0x98, 0x5b, 0x7d, 0x8f, 0x39, 0xc1, - 0x9f, 0x1c, 0x3d, 0x21, 0xf4, 0x4e, 0x4e, 0x4b, 0x04, 0xe9, 0x13, 0xa9, 0x75, 0x5d, 0xc5, 0x7e, 0x4d, 0x21, 0xaa, - 0x85, 0x60, 0x10, 0xca, 0xd4, 0xb4, 0x4f, 0xf1, 0x7d, 0xb6, 0xec, 0xbf, 0x4c, 0xd9, 0x92, 0x6c, 0x04, 0x74, 0x4c, - 0x3a, 0xef, 0x57, 0x6f, 0xcf, 0xce, 0xbc, 0xdf, 0xa0, 0x09, 0x07, 0xd5, 0x0d, 0xb4, 0xab, 0x20, 0xd3, 0x18, 0xc5, - 0x66, 0x31, 0xd6, 0x6e, 0x4d, 0x44, 0x10, 0x84, 0xbb, 0x9c, 0x85, 0xed, 0x76, 0x42, 0xbc, 0x0d, 0x24, 0x50, 0xe0, - 0xda, 0x46, 0x39, 0x09, 0x89, 0xba, 0x90, 0xe9, 0xc9, 0xba, 0x91, 0x2c, 0xd0, 0x6b, 0xec, 0x28, 0xa0, 0xa7, 0xdc, - 0x3e, 0x05, 0xf4, 0x7d, 0xc1, 0x4e, 0xf9, 0x20, 0x18, 0x62, 0xbc, 0xd9, 0x80, 0xde, 0x4a, 0xf5, 0x08, 0x1e, 0xd3, - 0xc0, 0x72, 0xd1, 0x97, 0x05, 0x43, 0x98, 0xa5, 0x3f, 0x53, 0x36, 0xf9, 0xfa, 0xef, 0x6e, 0x7e, 0x2f, 0xb4, 0x98, - 0x1d, 0x84, 0xe2, 0xf6, 0x7a, 0x02, 0xc4, 0xaf, 0xe2, 0xd7, 0x60, 0x6d, 0xae, 0x25, 0xde, 0x6e, 0x7a, 0xfe, 0x10, - 0xbe, 0x1c, 0xdd, 0x7e, 0x52, 0x9a, 0x4f, 0x20, 0x68, 0x8f, 0x93, 0x94, 0xbb, 0xef, 0x3e, 0x4a, 0x57, 0x11, 0x8c, - 0x16, 0x20, 0xf8, 0xed, 0xad, 0xe4, 0xbc, 0x29, 0xfc, 0xc7, 0x3a, 0xdf, 0x63, 0x2c, 0x15, 0x79, 0x86, 0xd3, 0xdf, - 0x00, 0x07, 0xbf, 0xf7, 0x6f, 0x65, 0xd6, 0x90, 0xe8, 0x42, 0x7d, 0x04, 0xf4, 0x7f, 0xac, 0xc7, 0xef, 0x14, 0x25, - 0x7d, 0x49, 0x9c, 0x23, 0x7c, 0x13, 0x2f, 0xd1, 0x74, 0xb1, 0x37, 0xae, 0xe9, 0x9b, 0xc2, 0xbc, 0xd0, 0x0a, 0x0e, - 0xfb, 0xd6, 0x28, 0x3c, 0xf0, 0xcc, 0xfb, 0x56, 0x34, 0x04, 0xdd, 0xbf, 0xe2, 0xde, 0xf8, 0x56, 0xb0, 0x0c, 0x6f, - 0xca, 0x59, 0x66, 0xee, 0x70, 0xb7, 0x99, 0x48, 0xe5, 0x2d, 0x63, 0xc1, 0x5a, 0x28, 0x73, 0xde, 0x34, 0x98, 0x6d, - 0xea, 0x48, 0x25, 0xbb, 0xef, 0xff, 0x6a, 0x9c, 0xb0, 0xd9, 0x20, 0x38, 0xab, 0x64, 0x11, 0x5f, 0xf1, 0x60, 0xaa, - 0x55, 0x14, 0x19, 0xd8, 0x15, 0x02, 0x52, 0x8e, 0xd3, 0xde, 0xc1, 0x93, 0xa5, 0x66, 0x26, 0xe4, 0xb7, 0xd5, 0x59, - 0xc0, 0x5b, 0x33, 0x9a, 0xa7, 0x15, 0xec, 0x32, 0x5f, 0x49, 0xf1, 0x47, 0x4b, 0x92, 0x8d, 0xf5, 0x37, 0x64, 0xd8, - 0x56, 0x3e, 0x73, 0x01, 0x98, 0x3b, 0xb7, 0x52, 0x05, 0xfd, 0xeb, 0x01, 0x23, 0x84, 0x44, 0x40, 0x38, 0x8b, 0x89, - 0x7b, 0x61, 0xc2, 0x61, 0xba, 0x40, 0x41, 0x31, 0x06, 0x0a, 0xfa, 0x28, 0x43, 0x4e, 0x4f, 0xf9, 0x20, 0x69, 0xcc, - 0xd6, 0x1f, 0xaa, 0x44, 0x7a, 0x23, 0x09, 0x3d, 0x87, 0xdf, 0xe3, 0x16, 0x0f, 0xd4, 0x08, 0xd6, 0xe9, 0x6e, 0x4e, - 0x87, 0x2f, 0x0b, 0x32, 0xfc, 0x13, 0xbc, 0xdd, 0x62, 0x7b, 0x59, 0x4e, 0x60, 0x71, 0xc7, 0x5e, 0xf1, 0x34, 0x57, - 0x2d, 0x4e, 0x88, 0x47, 0x2c, 0x72, 0x9f, 0x58, 0xc0, 0x88, 0x1a, 0x46, 0xe3, 0x87, 0xb3, 0xb7, 0x6f, 0x34, 0x86, - 0x55, 0xee, 0x7f, 0x00, 0x23, 0xaa, 0xa5, 0xed, 0x76, 0xc0, 0x97, 0x23, 0x34, 0x60, 0x4f, 0xdd, 0x60, 0xf7, 0xfb, - 0x26, 0xed, 0xa4, 0xf4, 0xb2, 0x39, 0x31, 0xe8, 0x8e, 0xd2, 0x66, 0xa9, 0x0c, 0x8c, 0xbb, 0x0a, 0x47, 0x73, 0x62, - 0x23, 0x56, 0xf5, 0x3e, 0x0c, 0x97, 0x34, 0xb6, 0xb2, 0x72, 0xbb, 0x9b, 0x70, 0x64, 0x13, 0xe0, 0xfa, 0x14, 0xb4, - 0x57, 0x73, 0x0e, 0x5a, 0x50, 0xa2, 0xc0, 0x11, 0x6d, 0xb7, 0x21, 0x44, 0x24, 0x29, 0x86, 0x93, 0x59, 0x58, 0x0c, - 0x87, 0x6a, 0xe0, 0x0b, 0x42, 0xa2, 0x37, 0xc5, 0x3c, 0x5b, 0x28, 0x04, 0x23, 0x7f, 0x27, 0x7d, 0x5b, 0x28, 0x4e, - 0xb9, 0xf7, 0xad, 0x20, 0x9b, 0x5f, 0x53, 0x8c, 0xc1, 0xe8, 0x34, 0x9b, 0x19, 0x48, 0x58, 0x4f, 0x2b, 0xa2, 0xd6, - 0x91, 0x9d, 0x0d, 0x50, 0xc5, 0xa2, 0x69, 0x30, 0xa8, 0x5b, 0x3c, 0xb1, 0x9e, 0xd1, 0x7b, 0x50, 0x09, 0xa2, 0x5a, - 0xb0, 0x1b, 0xc3, 0xb5, 0xf6, 0x46, 0x84, 0x92, 0x72, 0xd2, 0x64, 0x66, 0xac, 0x68, 0xb0, 0x00, 0x21, 0x69, 0x5c, - 0x56, 0xaf, 0x65, 0x9a, 0x5d, 0x66, 0x80, 0x20, 0xe1, 0xfc, 0x09, 0x65, 0xe3, 0xcd, 0x33, 0x35, 0x2f, 0x5d, 0x89, - 0x33, 0x0b, 0x7b, 0xd2, 0xf5, 0x96, 0x16, 0x24, 0x2a, 0x80, 0x46, 0xf9, 0x5a, 0x9e, 0x7f, 0xec, 0x58, 0x85, 0xec, - 0x7e, 0x38, 0x55, 0xb6, 0x43, 0xfc, 0x84, 0x55, 0xc4, 0x3b, 0xad, 0x2b, 0x25, 0xd2, 0xe8, 0x68, 0x1b, 0x10, 0xc3, - 0x96, 0x7d, 0x8b, 0x1a, 0x3e, 0x08, 0xbb, 0xe8, 0x24, 0x3f, 0xe8, 0x29, 0x1e, 0x5b, 0x03, 0x49, 0x5f, 0x8b, 0xe0, - 0x6b, 0x74, 0xa4, 0x13, 0x65, 0x1a, 0x89, 0x29, 0x24, 0xfa, 0xf5, 0x42, 0x6b, 0x2c, 0xa3, 0xec, 0x2b, 0xf2, 0xbf, - 0xd3, 0xdd, 0xfb, 0x56, 0x6c, 0xb7, 0x30, 0xc9, 0x9e, 0x07, 0x1a, 0x6c, 0x6a, 0xd4, 0x0a, 0xe1, 0xec, 0x9c, 0x56, - 0xa8, 0x1d, 0xeb, 0x85, 0x25, 0x90, 0x07, 0xb0, 0x15, 0x69, 0x50, 0x06, 0xc9, 0xde, 0x14, 0x73, 0xb1, 0x70, 0xa2, - 0x1c, 0xa9, 0xf0, 0xcf, 0xe4, 0x28, 0xe5, 0x70, 0x15, 0x0b, 0x0b, 0x86, 0xfc, 0xea, 0xe8, 0xb2, 0x90, 0xd7, 0x20, - 0x29, 0x31, 0x0c, 0x95, 0xe5, 0x75, 0x71, 0xd5, 0x96, 0x84, 0xf6, 0xce, 0x01, 0x94, 0xa6, 0x00, 0xc1, 0x4b, 0xa3, - 0x86, 0x98, 0x6d, 0xd4, 0xee, 0x8a, 0xf6, 0x92, 0x03, 0xea, 0x74, 0xd7, 0x6e, 0xbd, 0x29, 0x5b, 0x75, 0x2b, 0x2e, - 0xfc, 0x03, 0x4a, 0x3f, 0xe5, 0x83, 0xc2, 0xa7, 0x12, 0xb8, 0xf1, 0xd5, 0x26, 0xcb, 0x2e, 0xef, 0x71, 0xe9, 0x57, - 0x8d, 0xf1, 0xeb, 0xf7, 0x7b, 0x6a, 0x21, 0x34, 0x52, 0x81, 0xf9, 0xf6, 0x99, 0xa9, 0xca, 0x68, 0x4a, 0xed, 0x25, - 0xb8, 0x72, 0xf6, 0x23, 0xa8, 0x88, 0xeb, 0x8a, 0xd4, 0xa6, 0x06, 0xe8, 0xc0, 0xcb, 0x0a, 0xb7, 0xb2, 0x00, 0x8f, - 0x9d, 0x80, 0x6c, 0xb7, 0x3c, 0x0c, 0xf4, 0xa1, 0x13, 0xf8, 0x5b, 0xf2, 0x0c, 0x99, 0x35, 0xfb, 0xf8, 0x93, 0x16, - 0xfc, 0x63, 0x0b, 0x7e, 0x44, 0x71, 0xa7, 0x95, 0xf9, 0xb7, 0xd2, 0xba, 0xc5, 0xfd, 0x3b, 0x99, 0x26, 0x14, 0x95, - 0x09, 0xb5, 0x5f, 0xe9, 0x6f, 0x26, 0x78, 0x94, 0xca, 0xfe, 0x41, 0xc2, 0x07, 0xb3, 0xc6, 0x13, 0x6b, 0x3c, 0x19, - 0x4e, 0xb7, 0xd2, 0xb0, 0x0c, 0x28, 0xf4, 0xf3, 0x32, 0x57, 0x54, 0x3f, 0xff, 0xb4, 0xe6, 0x6b, 0xde, 0x6c, 0xb1, - 0x4d, 0x7a, 0xa0, 0xc1, 0x5e, 0x1e, 0x4d, 0x29, 0x9c, 0x44, 0x9d, 0x1b, 0x89, 0xba, 0xa8, 0x59, 0x86, 0xea, 0x04, - 0xaf, 0xe6, 0xa9, 0x1e, 0xf6, 0x66, 0x22, 0x5a, 0x2b, 0x29, 0x4b, 0x0c, 0x58, 0xeb, 0xc8, 0x43, 0x72, 0xb7, 0xd6, - 0x71, 0xa7, 0xa1, 0x2e, 0x4d, 0xa1, 0x26, 0x58, 0xe1, 0x02, 0x1c, 0x41, 0x3f, 0x16, 0x21, 0x87, 0x6b, 0xaa, 0xd2, - 0x2f, 0x68, 0x4a, 0x9e, 0x78, 0x8a, 0x5a, 0xad, 0x48, 0xb7, 0x1f, 0xe5, 0xd8, 0x0d, 0xdf, 0x38, 0x21, 0x27, 0x46, - 0xe8, 0xef, 0x8e, 0xa5, 0x9c, 0xa1, 0xc5, 0x83, 0x3a, 0xc1, 0x7a, 0x79, 0x4b, 0x81, 0x62, 0x8e, 0x2e, 0xab, 0xae, - 0x79, 0x85, 0xb6, 0x2f, 0xcb, 0x7e, 0x3f, 0xb7, 0xf5, 0xa4, 0xec, 0x64, 0xb3, 0x34, 0xfb, 0x10, 0x15, 0x53, 0xb8, - 0xeb, 0x13, 0xcd, 0x5f, 0x85, 0xfa, 0xaa, 0x2d, 0x73, 0x3e, 0xe2, 0x88, 0x13, 0x92, 0x93, 0xfa, 0x27, 0x35, 0xf5, - 0x4a, 0xdc, 0xaf, 0x2a, 0xf9, 0x45, 0x18, 0x2b, 0x46, 0x17, 0xb8, 0x20, 0x55, 0x2a, 0xef, 0x17, 0x05, 0xc0, 0x5f, - 0x09, 0xf6, 0x26, 0x0d, 0xb5, 0xf2, 0x5b, 0xb4, 0x05, 0xfc, 0x1b, 0xc5, 0x0d, 0x58, 0x05, 0x06, 0x18, 0x4d, 0xb6, - 0xe7, 0x34, 0x81, 0x03, 0x4e, 0x68, 0x15, 0x05, 0x15, 0x66, 0x68, 0xa8, 0x2d, 0x8c, 0x9e, 0xa1, 0x8c, 0x5b, 0x65, - 0xf6, 0x6e, 0x8c, 0x9d, 0x16, 0x78, 0x0d, 0xff, 0x46, 0x2f, 0x14, 0xb3, 0x51, 0x07, 0xe9, 0xd1, 0x49, 0x4c, 0x7f, - 0xdc, 0xc2, 0xc9, 0xcd, 0xc2, 0x59, 0xd6, 0x2c, 0x81, 0xee, 0xc0, 0x05, 0x31, 0xee, 0xf7, 0x73, 0x38, 0x32, 0xcd, - 0xc8, 0x17, 0x2c, 0xa7, 0x31, 0x5b, 0x52, 0xed, 0x79, 0x78, 0x55, 0x85, 0x39, 0x5d, 0x5a, 0x19, 0x6f, 0xca, 0x40, - 0x65, 0xb4, 0xdd, 0x86, 0xf0, 0xa7, 0xdb, 0xda, 0x25, 0x9d, 0x2f, 0x21, 0x03, 0xfc, 0x01, 0x89, 0x28, 0x62, 0x81, - 0xff, 0x5b, 0x8d, 0x53, 0x7a, 0xa2, 0xb4, 0x66, 0x09, 0x5d, 0x33, 0x5d, 0x3f, 0xbd, 0x64, 0xeb, 0xc6, 0x52, 0xd8, - 0x6e, 0xc3, 0x66, 0x02, 0xd3, 0x9c, 0x2b, 0x99, 0x5e, 0xa2, 0x4e, 0x0a, 0xa8, 0x58, 0x78, 0x89, 0xcb, 0x2f, 0x25, - 0x14, 0x9a, 0x3b, 0x5f, 0x2e, 0x8c, 0x12, 0x13, 0x5a, 0x25, 0x3f, 0x7f, 0xa8, 0xcc, 0xd7, 0xc6, 0x43, 0xf0, 0xb7, - 0x34, 0x4c, 0x4c, 0x91, 0xa8, 0x10, 0x9d, 0x7d, 0x0b, 0xb2, 0x1c, 0x01, 0xb8, 0x9e, 0x67, 0xb2, 0xa6, 0x3f, 0xa4, - 0x10, 0x17, 0x1e, 0x1a, 0xf4, 0xae, 0x90, 0xd7, 0x59, 0xc9, 0x43, 0xbc, 0x27, 0x78, 0x9a, 0xd1, 0xfd, 0x06, 0x1f, - 0xda, 0xda, 0xa3, 0x27, 0xc8, 0xc6, 0x53, 0xee, 0xd7, 0xbf, 0x88, 0x70, 0x0e, 0xd1, 0x3b, 0x17, 0x54, 0xab, 0xab, - 0x1d, 0x20, 0x97, 0x67, 0x7b, 0xf5, 0x08, 0x4e, 0x37, 0x7d, 0x7d, 0xab, 0x42, 0x67, 0x0e, 0x20, 0xed, 0x21, 0x59, - 0xd7, 0x5c, 0xef, 0x00, 0x77, 0x24, 0x56, 0x6b, 0xa0, 0xb1, 0x6e, 0x6b, 0x76, 0xda, 0xa3, 0x78, 0x4c, 0x64, 0x66, - 0x2c, 0x52, 0x8c, 0xb9, 0x5b, 0xa7, 0x45, 0xd1, 0x06, 0xcd, 0x10, 0x76, 0xef, 0x3a, 0x7c, 0xdd, 0x8a, 0x38, 0xbf, - 0xdf, 0xf6, 0x05, 0x46, 0xc3, 0x98, 0x6b, 0xf7, 0x3c, 0x43, 0x37, 0x6c, 0xb0, 0x8d, 0x24, 0x88, 0x48, 0x90, 0x99, - 0x3a, 0x10, 0x65, 0x6d, 0x0d, 0xd8, 0x1e, 0x71, 0xbd, 0x69, 0x15, 0x3f, 0xaf, 0x62, 0xf0, 0xf6, 0xac, 0x71, 0x4a, - 0xeb, 0x6b, 0x5c, 0x73, 0x5c, 0x15, 0x22, 0x6a, 0x8b, 0x14, 0x00, 0xc3, 0xce, 0x17, 0xb8, 0x33, 0x2b, 0x0c, 0xe6, - 0x84, 0xa5, 0x92, 0x9d, 0xca, 0xf5, 0xe7, 0xb0, 0xc5, 0x41, 0x2a, 0x5f, 0x7a, 0xfd, 0xfd, 0xcd, 0x17, 0x5f, 0xa0, - 0xdb, 0x9e, 0xf3, 0x23, 0x08, 0x32, 0x81, 0x0e, 0x6a, 0x4a, 0xf5, 0xf8, 0x4b, 0x01, 0xd4, 0x1e, 0xe6, 0xe1, 0x97, - 0x82, 0x89, 0xf8, 0x26, 0xbb, 0x8a, 0x2b, 0x59, 0x8c, 0x6e, 0xb8, 0x48, 0x65, 0x61, 0xa5, 0xc6, 0xc1, 0xe9, 0x6a, - 0x95, 0xf3, 0x00, 0x4c, 0xe5, 0x2d, 0xa3, 0x6c, 0x2b, 0xcb, 0xf4, 0xe0, 0x6a, 0x79, 0x7a, 0xa5, 0x45, 0xe7, 0xe5, - 0xcd, 0x55, 0x10, 0xe1, 0xaf, 0x0b, 0xf3, 0xe3, 0x3a, 0x2e, 0x3f, 0x06, 0x91, 0xb5, 0xa9, 0x33, 0x3f, 0x50, 0x2a, - 0x0f, 0xfe, 0x4e, 0x20, 0xd3, 0xfd, 0xa5, 0x00, 0xcb, 0x6c, 0x5b, 0xf1, 0x71, 0x8c, 0xb5, 0x0e, 0x27, 0x64, 0xa6, - 0x4a, 0xf4, 0xde, 0x25, 0xeb, 0x02, 0xac, 0xfd, 0x14, 0xb6, 0xb3, 0xca, 0x35, 0xc3, 0xca, 0x54, 0x45, 0x66, 0x56, - 0xd6, 0xec, 0x30, 0xb4, 0x4e, 0x34, 0x73, 0xf4, 0x16, 0xd0, 0x0f, 0xe4, 0xf0, 0x8a, 0x96, 0x6b, 0xe6, 0xf9, 0xd8, - 0x34, 0x5e, 0x3f, 0x3a, 0xbc, 0x72, 0x0b, 0xf6, 0xce, 0xde, 0xc9, 0x51, 0x98, 0x08, 0x9e, 0xc6, 0x66, 0x7c, 0x91, - 0x67, 0x05, 0xec, 0xa0, 0xc9, 0x78, 0x4c, 0xbd, 0xa5, 0xd5, 0xba, 0x39, 0x3a, 0x64, 0xdb, 0xec, 0x71, 0xf5, 0x98, - 0x93, 0x43, 0xde, 0x32, 0xb5, 0x6d, 0x5b, 0xc7, 0x79, 0x9a, 0x7c, 0x65, 0xba, 0x2f, 0xd6, 0x36, 0x42, 0xbc, 0x72, - 0x76, 0x74, 0x5e, 0xd2, 0xad, 0x6f, 0x4a, 0x43, 0xaf, 0x25, 0x00, 0xf3, 0x69, 0x03, 0xfe, 0x82, 0x95, 0xeb, 0x51, - 0xc5, 0xcb, 0x0a, 0x24, 0x2c, 0x28, 0xc2, 0x9b, 0x62, 0x6f, 0x0a, 0x77, 0xe3, 0xf4, 0x1c, 0x76, 0xe0, 0x62, 0x8a, - 0xee, 0x38, 0x31, 0x99, 0x95, 0x46, 0x2b, 0x1a, 0xe9, 0x5f, 0xae, 0x2f, 0xb1, 0xee, 0x8b, 0x56, 0xe6, 0xd9, 0x9c, - 0x0a, 0x9b, 0xde, 0x55, 0x2e, 0x9d, 0xa8, 0xdf, 0x32, 0xe1, 0xca, 0x95, 0x20, 0x20, 0xd3, 0x82, 0xf5, 0x0a, 0xb3, - 0x8b, 0xe4, 0x1a, 0x08, 0x19, 0x18, 0xbe, 0x06, 0x6b, 0x51, 0x72, 0x63, 0x05, 0xeb, 0xdd, 0xf3, 0x75, 0x82, 0x90, - 0x82, 0x07, 0x6e, 0x82, 0xbe, 0x6f, 0xdd, 0xbc, 0x1d, 0x25, 0xca, 0x20, 0x3e, 0xb9, 0x76, 0xca, 0x41, 0x02, 0x01, - 0x38, 0xb0, 0x2a, 0x24, 0x89, 0x02, 0x9d, 0x07, 0x57, 0x33, 0x8e, 0x60, 0xf3, 0xca, 0x99, 0x8b, 0x1b, 0xc0, 0x79, - 0xe5, 0xcf, 0x65, 0x83, 0x2d, 0xeb, 0x11, 0x55, 0xe6, 0x8c, 0x53, 0x0c, 0xea, 0x64, 0x09, 0xfa, 0xca, 0x52, 0xda, - 0x2b, 0xd0, 0x34, 0x5e, 0xb3, 0x95, 0xf2, 0x01, 0xa0, 0x17, 0x6c, 0xa5, 0x8c, 0xfd, 0xf1, 0xeb, 0x73, 0xb6, 0xd2, - 0xd2, 0xe0, 0xe9, 0xf5, 0xec, 0x62, 0x76, 0x3e, 0x60, 0x47, 0x51, 0xa8, 0x0d, 0x18, 0x02, 0x17, 0x99, 0x20, 0x18, - 0x84, 0x1a, 0xff, 0x65, 0xa0, 0x02, 0x84, 0x11, 0x8f, 0xc7, 0x46, 0x1c, 0xb1, 0x70, 0x3c, 0xc4, 0x60, 0x60, 0xcd, - 0x17, 0x24, 0x20, 0xd4, 0x94, 0x86, 0xbe, 0x9e, 0xe1, 0x70, 0x72, 0x30, 0x81, 0x54, 0xcc, 0xcc, 0x54, 0x61, 0x6c, - 0x4c, 0x22, 0x88, 0xff, 0xda, 0x59, 0x2f, 0x94, 0xdb, 0x5d, 0xa3, 0x81, 0xa0, 0x19, 0x7c, 0x56, 0xc5, 0x93, 0x83, - 0x61, 0x57, 0xc5, 0x38, 0x0a, 0x37, 0x46, 0xf9, 0x76, 0x7e, 0x0c, 0x60, 0xbe, 0xe7, 0x43, 0x5f, 0x2e, 0x71, 0x7e, - 0xf8, 0x84, 0x3c, 0x7e, 0x42, 0xe8, 0x39, 0x3b, 0xff, 0xe2, 0x09, 0x3d, 0x57, 0xe4, 0xe4, 0x60, 0x12, 0xdd, 0x30, - 0x8b, 0x81, 0x73, 0xa4, 0x9a, 0x40, 0xaf, 0x46, 0x6b, 0xa1, 0x16, 0x98, 0x76, 0x68, 0x0a, 0xbf, 0x19, 0x1f, 0x04, - 0x83, 0x9b, 0x76, 0xd3, 0x6f, 0xda, 0x6d, 0xf5, 0xbc, 0xba, 0x0e, 0x8e, 0xa2, 0xdd, 0x62, 0x26, 0x7f, 0x1f, 0x1f, - 0xb8, 0x39, 0xc0, 0xfa, 0x1e, 0x1e, 0x13, 0xd3, 0xa4, 0x9d, 0x51, 0xf1, 0x6b, 0xfa, 0x0a, 0xfb, 0xd0, 0x2c, 0xb2, - 0xa3, 0x0f, 0xc3, 0x7f, 0xab, 0x13, 0xf5, 0xf9, 0x17, 0x47, 0x40, 0x8e, 0x40, 0x06, 0x8a, 0x25, 0x82, 0x19, 0x0e, - 0x34, 0x05, 0x14, 0x64, 0x7a, 0xdc, 0xa9, 0x1e, 0x7e, 0x35, 0x6a, 0x6a, 0x46, 0x6e, 0x60, 0x6a, 0xb0, 0x2d, 0xf8, - 0x81, 0xea, 0x86, 0xfe, 0x46, 0xa3, 0x3d, 0x69, 0x27, 0x33, 0xf3, 0x92, 0xda, 0x38, 0x77, 0x37, 0x10, 0xd0, 0xd9, - 0xc1, 0x2d, 0x4a, 0xf6, 0xe5, 0xf1, 0xd5, 0x01, 0xae, 0x22, 0x40, 0x0d, 0x63, 0xc1, 0x97, 0x83, 0x2b, 0xbd, 0xb9, - 0x0f, 0x02, 0x32, 0xf8, 0x32, 0x38, 0xf9, 0x72, 0x20, 0x07, 0xc1, 0xf1, 0xe1, 0xd5, 0x49, 0xe0, 0x8c, 0xfb, 0x21, - 0xe4, 0xa5, 0xaa, 0x28, 0x66, 0xc2, 0x54, 0x91, 0xd8, 0xda, 0x73, 0x5b, 0xaf, 0x32, 0x3e, 0xa3, 0xe9, 0xd4, 0x22, - 0xa1, 0x87, 0x29, 0x8b, 0xcd, 0xef, 0x60, 0xc2, 0xaf, 0x83, 0xc8, 0x05, 0x85, 0x9d, 0xe5, 0x51, 0x4c, 0x97, 0xec, - 0x4e, 0x84, 0x29, 0x4d, 0x0e, 0x73, 0x42, 0xa2, 0x70, 0xa9, 0xc0, 0x04, 0xd5, 0xeb, 0x04, 0xe2, 0xda, 0xba, 0xcf, - 0xef, 0x44, 0xb8, 0xa4, 0xf9, 0x61, 0x42, 0x5a, 0x45, 0xb8, 0x08, 0x35, 0x9b, 0x9a, 0x5e, 0xb2, 0x70, 0x45, 0xaf, - 0x80, 0x99, 0x92, 0xeb, 0xf0, 0x0a, 0xb8, 0xbc, 0xf5, 0x7c, 0xb5, 0x60, 0x57, 0x0d, 0xe9, 0x9b, 0xe1, 0x8b, 0x2f, - 0xad, 0x4f, 0x1e, 0xf0, 0x90, 0xce, 0x0f, 0x2f, 0x05, 0x1b, 0x80, 0x9b, 0x8c, 0xdf, 0x7e, 0x2b, 0xef, 0xf4, 0xbc, - 0xb4, 0xa7, 0x18, 0x67, 0xa6, 0x9d, 0x98, 0xb4, 0x13, 0x72, 0xff, 0xbe, 0xed, 0xbb, 0x17, 0xaf, 0x95, 0xcb, 0xaa, - 0x65, 0x48, 0x8a, 0xb5, 0x72, 0x9d, 0x46, 0xc9, 0xa9, 0x15, 0x78, 0xb2, 0x4b, 0x5e, 0x25, 0x4b, 0xff, 0xa0, 0xb2, - 0x56, 0x03, 0xf6, 0x18, 0xb1, 0x2c, 0x14, 0x8e, 0xfd, 0xeb, 0x8c, 0x15, 0x6b, 0x5f, 0xa0, 0x11, 0x23, 0xf7, 0xf6, - 0x3a, 0x63, 0x5e, 0x0c, 0xda, 0x64, 0xed, 0x85, 0xee, 0xf3, 0xd2, 0xf3, 0x16, 0xef, 0xe5, 0x94, 0x1a, 0x46, 0x22, - 0x7a, 0x30, 0x56, 0x66, 0x94, 0x2a, 0x51, 0x6b, 0xd0, 0x88, 0x60, 0x63, 0x17, 0x0c, 0x14, 0x9c, 0x50, 0xb9, 0xa7, - 0xce, 0xf6, 0xed, 0x94, 0x4a, 0x0f, 0x68, 0x97, 0x1a, 0x55, 0xb9, 0x5b, 0x66, 0x92, 0x55, 0x83, 0x60, 0xf4, 0x47, - 0x29, 0xc5, 0x0c, 0xef, 0x8c, 0x2c, 0x98, 0x82, 0x95, 0xa0, 0xaa, 0x65, 0x58, 0x0e, 0x39, 0x6a, 0xf1, 0x8c, 0x4f, - 0xaa, 0xd4, 0x3f, 0x3a, 0x82, 0x06, 0x2f, 0xd7, 0xad, 0xa0, 0xc1, 0x4f, 0xc6, 0x4f, 0xf4, 0x40, 0xa7, 0x6b, 0xed, - 0x78, 0xe8, 0xf3, 0xdb, 0x88, 0x37, 0xae, 0x7b, 0x4f, 0xb5, 0x56, 0xa1, 0x0c, 0xb4, 0x58, 0x51, 0xb9, 0x52, 0x4b, - 0xba, 0xdf, 0x45, 0x00, 0x2c, 0x62, 0x63, 0x36, 0xde, 0xb5, 0xcd, 0x0a, 0x41, 0xa3, 0xcb, 0x4e, 0x36, 0xf1, 0x80, - 0x25, 0xba, 0xb5, 0x83, 0x09, 0x8d, 0x4f, 0x58, 0xd9, 0xef, 0xe7, 0x27, 0x40, 0x4f, 0xb5, 0x11, 0x53, 0x01, 0x47, - 0xfe, 0xe7, 0x56, 0x64, 0x8a, 0x02, 0x9b, 0x35, 0x75, 0xb7, 0xc6, 0x32, 0x12, 0x7d, 0x99, 0xd2, 0xe5, 0x09, 0xcf, - 0x80, 0x69, 0xbd, 0x6e, 0x39, 0xae, 0xec, 0x2a, 0x8e, 0x3c, 0x15, 0x96, 0x15, 0xe7, 0x55, 0x38, 0xde, 0x7a, 0x7c, - 0x83, 0x43, 0xc3, 0xa6, 0x5d, 0xfa, 0x43, 0x08, 0x0b, 0xe1, 0x75, 0x06, 0xb7, 0x11, 0x6d, 0x27, 0x81, 0xca, 0x1b, - 0x73, 0x9d, 0x50, 0x36, 0xb7, 0xeb, 0xb5, 0x67, 0x90, 0x4e, 0xcc, 0x81, 0x52, 0x8d, 0xa0, 0x35, 0x9a, 0x05, 0x55, - 0x23, 0x1e, 0x39, 0x1e, 0xde, 0x19, 0xc4, 0x6a, 0xf9, 0x92, 0xa6, 0x52, 0x34, 0x00, 0xe3, 0x02, 0xb8, 0x3c, 0xfd, - 0xfc, 0xfe, 0xc7, 0x33, 0x1e, 0x17, 0xc9, 0xf2, 0x5d, 0x5c, 0xc4, 0xd7, 0x65, 0xb8, 0x51, 0x63, 0x14, 0xd7, 0x64, - 0x2a, 0x06, 0x4c, 0x9a, 0x95, 0xd4, 0xdc, 0x95, 0x9a, 0x10, 0x63, 0x9d, 0xc9, 0xba, 0xac, 0xe4, 0x75, 0xa3, 0xd2, - 0x75, 0x91, 0xe1, 0xc7, 0x2d, 0x9f, 0xd3, 0x43, 0x00, 0x36, 0x35, 0x2e, 0xa4, 0x91, 0xd4, 0x85, 0x18, 0x73, 0x11, - 0xaf, 0xeb, 0xe3, 0x71, 0xa3, 0xeb, 0x25, 0x7b, 0x3a, 0xfe, 0x6a, 0xfa, 0x3a, 0x0b, 0xb3, 0x81, 0x20, 0xa3, 0x6a, - 0xc9, 0x45, 0xcb, 0x94, 0x53, 0x99, 0x04, 0xa0, 0x8f, 0x67, 0x8f, 0xb1, 0xa3, 0xf1, 0x98, 0x6c, 0xda, 0xe2, 0x01, - 0x1e, 0x2e, 0xd7, 0x61, 0x41, 0x66, 0xba, 0x8e, 0x28, 0x10, 0xfc, 0xae, 0x0a, 0x00, 0xd9, 0xd2, 0x56, 0x65, 0xb8, - 0x34, 0xf6, 0x74, 0x3c, 0xa1, 0x12, 0xbb, 0x1d, 0x92, 0xda, 0xab, 0xd0, 0xcd, 0xbc, 0xf4, 0x3d, 0x8a, 0xa4, 0x71, - 0x59, 0xda, 0xa9, 0x54, 0xaa, 0x3d, 0x33, 0x73, 0x5d, 0x83, 0x98, 0x14, 0xa1, 0xae, 0xbb, 0xf4, 0xea, 0xde, 0x6d, - 0xae, 0x35, 0xdb, 0x01, 0xef, 0x35, 0x68, 0x86, 0x92, 0xb7, 0x98, 0xb7, 0xae, 0x88, 0x9a, 0xae, 0xd6, 0x60, 0x56, - 0x8c, 0xb2, 0xa5, 0x28, 0x5d, 0x53, 0x50, 0x0a, 0x46, 0x97, 0x6b, 0x6f, 0xe1, 0xbe, 0x96, 0x8d, 0x0b, 0x4b, 0xa6, - 0x57, 0x8b, 0x92, 0x12, 0xaa, 0x9b, 0x8a, 0x91, 0x12, 0x46, 0x4a, 0xc3, 0x53, 0xf9, 0x5e, 0xe0, 0x71, 0x9e, 0x07, - 0x51, 0xcb, 0x0b, 0xec, 0xb4, 0x22, 0xa7, 0xe0, 0xe8, 0x65, 0x72, 0x1a, 0x0a, 0xfc, 0x43, 0xa6, 0x40, 0x5d, 0x87, - 0xea, 0x7e, 0x83, 0x9b, 0xff, 0x9f, 0x05, 0x0b, 0x3c, 0xbe, 0xf5, 0x0a, 0xb7, 0xd1, 0x3f, 0x0b, 0x9f, 0x96, 0x3e, - 0x93, 0xbe, 0xab, 0x8b, 0x27, 0xed, 0xcd, 0x46, 0xc9, 0x32, 0xcb, 0xd3, 0x37, 0x32, 0xe5, 0x20, 0x32, 0x43, 0x6b, - 0x50, 0x76, 0x22, 0x1a, 0x37, 0x3c, 0x30, 0x62, 0x6c, 0xdc, 0xf8, 0x7e, 0xc8, 0x40, 0x36, 0x0c, 0x56, 0xdf, 0x2c, - 0x95, 0xc9, 0x1a, 0x10, 0x36, 0xb4, 0xfc, 0x44, 0xe3, 0x6d, 0x84, 0xfa, 0xfa, 0x05, 0x6e, 0x73, 0xa5, 0xef, 0x73, - 0xfe, 0x43, 0x46, 0x7f, 0x40, 0xe0, 0x97, 0x78, 0x05, 0x72, 0x8f, 0x67, 0x50, 0x37, 0xc2, 0xf6, 0x72, 0x0c, 0x96, - 0x84, 0xe8, 0x28, 0xa2, 0x62, 0x81, 0x82, 0xa6, 0x30, 0x88, 0x22, 0xea, 0x82, 0x39, 0xbc, 0xc8, 0x65, 0xf2, 0x71, - 0x6a, 0x7c, 0xe6, 0x87, 0x31, 0xc6, 0x90, 0x0e, 0x06, 0x61, 0x35, 0x0b, 0x86, 0xe3, 0xd1, 0xe4, 0xe8, 0x29, 0x9c, - 0xdb, 0xc1, 0x38, 0x20, 0x83, 0xa0, 0x2e, 0x57, 0xb1, 0xa0, 0xe5, 0xcd, 0x95, 0x2d, 0x03, 0x3f, 0xae, 0x83, 0xc1, - 0x3f, 0x0b, 0x4f, 0xf1, 0x0e, 0x9a, 0x93, 0x73, 0x19, 0x82, 0x8d, 0xfd, 0x9a, 0x80, 0xa4, 0xac, 0xa7, 0xf9, 0x49, - 0x7d, 0xb8, 0x31, 0xa5, 0xfd, 0x33, 0x87, 0x17, 0x1c, 0x76, 0x48, 0xa0, 0x40, 0x1a, 0x4f, 0xb3, 0xd1, 0x2b, 0xa5, - 0xc8, 0x7d, 0x57, 0x70, 0xb8, 0x33, 0xf7, 0x9c, 0xe9, 0x91, 0x53, 0x48, 0x34, 0xb3, 0x80, 0x1b, 0xf9, 0x2b, 0x71, - 0x13, 0xe7, 0x59, 0x7a, 0xd0, 0x7c, 0x73, 0x50, 0xde, 0x8b, 0x2a, 0xbe, 0x1b, 0x05, 0xc6, 0x9a, 0x90, 0xfb, 0xaa, - 0x27, 0x40, 0x4f, 0x80, 0x2d, 0x00, 0x06, 0xc4, 0x3b, 0x66, 0x26, 0x33, 0x1e, 0x81, 0x47, 0x60, 0xd3, 0x07, 0xb2, - 0xb8, 0x77, 0x2e, 0x49, 0xfe, 0x66, 0x2a, 0xed, 0x55, 0xaf, 0xdc, 0x29, 0xc8, 0x7a, 0xb5, 0x95, 0xbb, 0x6e, 0x7d, - 0xf6, 0x4d, 0x87, 0x57, 0xe0, 0x85, 0x04, 0xb7, 0xc8, 0x7e, 0xbf, 0x29, 0xa8, 0x14, 0x46, 0x45, 0xbc, 0x93, 0x5c, - 0xa3, 0x7f, 0xbb, 0x37, 0x36, 0x8a, 0xe4, 0x96, 0x0f, 0x0f, 0xa0, 0xce, 0xe4, 0x5d, 0x71, 0x3b, 0x87, 0xa8, 0xad, - 0xbb, 0xf1, 0xc0, 0x7b, 0x83, 0x76, 0x59, 0x73, 0x04, 0x5b, 0x5e, 0x1c, 0x64, 0x30, 0x16, 0x38, 0x2b, 0x23, 0xa5, - 0xc6, 0x35, 0xa4, 0x16, 0x7c, 0x92, 0xa7, 0x7b, 0xc8, 0x52, 0x4f, 0x82, 0x22, 0xc7, 0xb3, 0x18, 0x32, 0x8d, 0xb7, - 0x81, 0xd8, 0xef, 0x65, 0x08, 0xd2, 0xb4, 0xed, 0xb6, 0x39, 0x02, 0x65, 0xf7, 0xc0, 0x94, 0xa4, 0xae, 0x8d, 0xa9, - 0x81, 0x86, 0x1e, 0x44, 0x8d, 0x54, 0xc4, 0xd9, 0xc9, 0x6b, 0xd0, 0x21, 0x82, 0xef, 0x77, 0x9a, 0x95, 0x1d, 0x2f, - 0x26, 0x04, 0x4f, 0xde, 0x17, 0x77, 0x59, 0x59, 0x95, 0xd1, 0xfb, 0x14, 0x0d, 0xa1, 0x12, 0x29, 0xa2, 0x97, 0x10, - 0x5f, 0xb0, 0xc4, 0xdf, 0x65, 0xf4, 0x63, 0x4a, 0xe3, 0x34, 0xc5, 0xf4, 0xe7, 0x05, 0xfc, 0x7c, 0x06, 0x28, 0x97, - 0xb8, 0x13, 0xa2, 0x0b, 0x09, 0xf6, 0x6a, 0x10, 0xdd, 0xab, 0xe2, 0x80, 0x29, 0x1a, 0xdd, 0x09, 0x8a, 0x98, 0x75, - 0x98, 0xfd, 0xfb, 0x02, 0x85, 0x42, 0xaa, 0x98, 0x5f, 0x84, 0x7d, 0x88, 0x7e, 0xc0, 0x22, 0x4f, 0xdf, 0xbd, 0x32, - 0x43, 0x1a, 0xdd, 0x4b, 0xaa, 0xb7, 0x36, 0x1e, 0x5b, 0x88, 0xd2, 0x13, 0x5d, 0xad, 0xe9, 0x79, 0xbc, 0xca, 0xa2, - 0x0d, 0xe0, 0x4f, 0xbc, 0x7b, 0xf5, 0x4c, 0x59, 0x98, 0x3c, 0xcf, 0x40, 0x71, 0x70, 0xfa, 0xee, 0xd5, 0x6b, 0x99, - 0xae, 0x73, 0x1e, 0x9d, 0x4b, 0x24, 0xad, 0xa7, 0xef, 0x5e, 0xfd, 0x84, 0xe6, 0x5e, 0x3f, 0x16, 0xf0, 0xfe, 0x25, - 0xf0, 0x96, 0x51, 0xbc, 0x86, 0x3e, 0xa9, 0xdf, 0xc9, 0x1a, 0x3b, 0xe5, 0xd5, 0x5a, 0x46, 0x3f, 0xa7, 0xb5, 0x27, - 0xad, 0xfa, 0x57, 0xe1, 0x53, 0x3b, 0x4f, 0xc0, 0x73, 0x97, 0x67, 0xe2, 0x63, 0x64, 0x45, 0x3b, 0x41, 0xf4, 0xe5, - 0xc1, 0xdd, 0x75, 0x2e, 0xca, 0x08, 0x5f, 0x30, 0xb4, 0x0b, 0x8a, 0x0e, 0x0f, 0x6f, 0x6f, 0x6f, 0x47, 0xb7, 0x5f, - 0x8d, 0x64, 0x71, 0x75, 0x38, 0xf9, 0xe6, 0x9b, 0x6f, 0x0e, 0xf1, 0x6d, 0xf0, 0x65, 0xdb, 0xed, 0xbd, 0x22, 0x7c, - 0xc0, 0x02, 0x44, 0xec, 0xfe, 0x12, 0xae, 0x28, 0xa0, 0x85, 0x1b, 0x7c, 0x19, 0x7c, 0xa9, 0x0f, 0x9d, 0x2f, 0x8f, - 0xcb, 0x9b, 0x2b, 0x55, 0x7e, 0x57, 0xc9, 0x47, 0xe3, 0xf1, 0xf8, 0x10, 0x24, 0x50, 0x5f, 0x0e, 0xf8, 0x20, 0x38, - 0x09, 0x06, 0x19, 0x5c, 0x68, 0xca, 0x9b, 0xab, 0x93, 0xc0, 0x33, 0xcd, 0x6d, 0xb0, 0x88, 0x0e, 0xc4, 0x25, 0x38, - 0xbc, 0xa2, 0xc1, 0x97, 0x01, 0x71, 0x29, 0x5f, 0x40, 0xca, 0x17, 0x47, 0x4f, 0xfd, 0xb4, 0xff, 0xa5, 0xd2, 0xbe, - 0xf2, 0xd3, 0x8e, 0x31, 0xed, 0xab, 0x67, 0x7e, 0xda, 0x89, 0x4a, 0x7b, 0xe1, 0xa7, 0xfd, 0xef, 0x72, 0x00, 0xa9, - 0x07, 0xbe, 0xf5, 0xdf, 0x85, 0xd7, 0x1a, 0x3c, 0x85, 0xa2, 0xec, 0x3a, 0xbe, 0xe2, 0xd0, 0xe8, 0xc1, 0xdd, 0x75, - 0x4e, 0x83, 0x01, 0xb6, 0xd7, 0x33, 0x09, 0xf1, 0x3e, 0xf8, 0x72, 0x5d, 0xe4, 0x61, 0xf0, 0xe5, 0x00, 0x0b, 0x19, - 0x7c, 0x19, 0x90, 0x2f, 0x8d, 0x81, 0x8c, 0x60, 0x9b, 0xc0, 0x85, 0x66, 0x1d, 0xda, 0x80, 0x69, 0xbe, 0x34, 0xae, - 0xa6, 0x7f, 0x16, 0xdd, 0xd9, 0xf0, 0x96, 0xa8, 0xdc, 0x74, 0x83, 0x9a, 0xbe, 0x05, 0xef, 0x04, 0x68, 0x54, 0x14, - 0xdc, 0xc4, 0x45, 0x38, 0x1c, 0x96, 0x37, 0x57, 0x04, 0xec, 0x32, 0x57, 0x3c, 0xae, 0xa2, 0x40, 0xc8, 0xa1, 0xfa, - 0x19, 0xa8, 0x48, 0x60, 0x01, 0x42, 0x19, 0xc1, 0x7f, 0x41, 0x4d, 0xdf, 0x49, 0xb6, 0x09, 0x86, 0xb7, 0xfc, 0xe2, - 0x63, 0x56, 0x0d, 0x95, 0x68, 0xf1, 0x46, 0x50, 0xf8, 0x01, 0x7f, 0x5d, 0xd5, 0xd1, 0x9f, 0xe0, 0xc6, 0xdd, 0xd4, - 0xb0, 0xbf, 0x93, 0x8e, 0x45, 0x7d, 0x27, 0xe7, 0xd9, 0x62, 0xda, 0x3a, 0xd0, 0xdf, 0x4a, 0x52, 0xcd, 0xb3, 0x41, - 0x30, 0x0c, 0x06, 0x7c, 0xc1, 0xde, 0xca, 0x39, 0xf7, 0xcc, 0xa7, 0x1e, 0x49, 0x7f, 0x9a, 0x67, 0xd9, 0x00, 0x7c, - 0x53, 0x90, 0x1f, 0x39, 0xfc, 0xef, 0xf9, 0x10, 0x85, 0x87, 0x83, 0x47, 0x87, 0x64, 0x16, 0xac, 0xee, 0xd0, 0xa3, - 0x33, 0x0a, 0x32, 0xb1, 0xe4, 0x45, 0x56, 0x79, 0x4b, 0xe5, 0x7e, 0xdd, 0xf6, 0xf2, 0xd8, 0x7b, 0x36, 0xaf, 0x62, - 0x11, 0xa8, 0x73, 0x0e, 0x14, 0x6f, 0x28, 0x7b, 0x2a, 0x9b, 0x12, 0x52, 0x6d, 0xc8, 0x1b, 0x96, 0x03, 0x16, 0x1c, - 0xf7, 0x86, 0xc3, 0x83, 0x60, 0xe0, 0xd4, 0xb9, 0x83, 0xe0, 0x60, 0x38, 0x3c, 0x09, 0xdc, 0x7d, 0x28, 0x1b, 0xb9, - 0x3b, 0x23, 0x2d, 0xd8, 0xbf, 0x8a, 0xb0, 0xa4, 0x20, 0x1e, 0x93, 0x5a, 0xfc, 0xa5, 0xc1, 0x65, 0x06, 0x00, 0x7d, - 0xa4, 0x24, 0x60, 0x06, 0x56, 0x66, 0x00, 0xa1, 0xca, 0x69, 0xcc, 0xce, 0x81, 0x79, 0x04, 0x8e, 0x59, 0xc1, 0x64, - 0x01, 0x62, 0x49, 0x80, 0x73, 0x17, 0x44, 0xb1, 0x2e, 0xe4, 0x11, 0x04, 0x01, 0xc0, 0x9f, 0xc4, 0x94, 0x82, 0x49, - 0x3a, 0x76, 0x23, 0x08, 0xe2, 0xf8, 0xec, 0x46, 0xb4, 0x26, 0x67, 0x89, 0x0e, 0x66, 0x24, 0x01, 0x36, 0xc4, 0xc0, - 0xf0, 0xc1, 0xfd, 0x1c, 0x94, 0x1e, 0x56, 0xef, 0x84, 0x5c, 0xf0, 0x3d, 0xf7, 0x64, 0xb3, 0x70, 0xf5, 0x84, 0x83, - 0xe0, 0x9e, 0x6b, 0x16, 0x60, 0x54, 0x15, 0xeb, 0xb2, 0xe2, 0xe9, 0x87, 0xfb, 0x15, 0xc4, 0x02, 0xc4, 0x01, 0x7d, - 0x27, 0xf3, 0x2c, 0xb9, 0x0f, 0x9d, 0x3d, 0xd7, 0x46, 0xa5, 0x7f, 0xff, 0xe1, 0xf5, 0x8f, 0x11, 0x88, 0x1c, 0x6b, - 0x43, 0xe9, 0xef, 0x39, 0x9e, 0x4d, 0x7e, 0xc4, 0x2b, 0x7f, 0x63, 0xdf, 0x73, 0x7b, 0x7a, 0xf4, 0xfb, 0x50, 0x37, - 0xbd, 0xe7, 0xb3, 0x7b, 0x3e, 0x72, 0xc5, 0xa1, 0xba, 0xc2, 0x7d, 0x7d, 0xbb, 0xf6, 0x8d, 0x90, 0x1e, 0x9e, 0x67, - 0xca, 0x1b, 0xf3, 0xa3, 0x1d, 0x0c, 0x83, 0x60, 0xaa, 0x85, 0x92, 0x10, 0x85, 0x84, 0x29, 0x01, 0x43, 0x74, 0xa0, - 0x97, 0xd5, 0x14, 0x39, 0x37, 0x35, 0xb2, 0xf0, 0x7e, 0xc0, 0xb4, 0xd0, 0xa1, 0x91, 0x43, 0xf9, 0xc1, 0xe1, 0x84, - 0x31, 0x0b, 0xbf, 0x55, 0xc2, 0xf4, 0xab, 0x45, 0xe5, 0x1c, 0x44, 0x0f, 0xc0, 0x18, 0x57, 0xf0, 0x02, 0xba, 0xc2, - 0x6e, 0xd6, 0x2a, 0x4a, 0x08, 0x82, 0xe9, 0x21, 0x07, 0xe8, 0x61, 0x17, 0xb4, 0xac, 0x2c, 0xd5, 0xad, 0xca, 0x59, - 0xaa, 0xa8, 0xcb, 0x50, 0x56, 0xc6, 0x0a, 0x03, 0xbf, 0x64, 0xdf, 0x17, 0xe8, 0x59, 0x3e, 0x15, 0x5d, 0xf0, 0x42, - 0x28, 0xc1, 0x72, 0x5d, 0xef, 0x44, 0x20, 0xea, 0xfc, 0xd0, 0xbb, 0xea, 0x6b, 0x5c, 0x3f, 0x9e, 0xbe, 0x96, 0x29, - 0xd7, 0x26, 0x14, 0x9a, 0xcf, 0x97, 0xbe, 0x62, 0xa2, 0x60, 0xb7, 0xd0, 0xaf, 0xb6, 0x8d, 0x3e, 0xbb, 0x5f, 0xeb, - 0xcd, 0xa0, 0x44, 0xc7, 0xbc, 0x46, 0xc1, 0xb5, 0x52, 0x28, 0x18, 0xed, 0x6d, 0xfc, 0x09, 0x8e, 0xdc, 0xea, 0xf6, - 0xd0, 0xfb, 0xad, 0x8a, 0xaf, 0xde, 0xa0, 0x6f, 0xa7, 0xfd, 0x39, 0xaa, 0xe4, 0xcf, 0xab, 0x15, 0xf8, 0x50, 0x41, - 0xa4, 0x15, 0x8b, 0xd3, 0x0b, 0xf5, 0x9c, 0xbd, 0x3b, 0x7d, 0x03, 0x7e, 0x94, 0xf8, 0xfb, 0x97, 0xef, 0x82, 0x9a, - 0x4c, 0xe3, 0x59, 0x61, 0x3e, 0xb4, 0x39, 0x20, 0x54, 0x8b, 0x4b, 0xb3, 0xef, 0x67, 0x71, 0x93, 0x7d, 0xd7, 0x6c, - 0x3d, 0x2d, 0x9a, 0x48, 0x52, 0x86, 0xdb, 0x07, 0x03, 0x02, 0x7d, 0x80, 0x28, 0xce, 0xbe, 0xa0, 0x31, 0xa4, 0xf9, - 0xcc, 0xbe, 0x1f, 0x21, 0xf0, 0xc5, 0x4e, 0x48, 0x35, 0xae, 0xb0, 0x68, 0xf4, 0x90, 0xcf, 0x78, 0xa4, 0x0c, 0x8b, - 0xde, 0x63, 0x02, 0x71, 0x86, 0xd3, 0xea, 0x3d, 0x62, 0x40, 0xe3, 0xdd, 0x40, 0xcb, 0x1e, 0xa2, 0x8c, 0xba, 0xec, - 0x0d, 0x8b, 0xef, 0x8f, 0xeb, 0x30, 0xb3, 0x96, 0x97, 0x43, 0xf8, 0x1b, 0x68, 0x03, 0x70, 0xca, 0x91, 0xe5, 0xab, - 0xcc, 0x46, 0x57, 0x4b, 0x4c, 0x6f, 0x22, 0x88, 0x4d, 0xa4, 0xd3, 0x61, 0xed, 0xea, 0x54, 0xbd, 0xab, 0x9d, 0xcf, - 0x44, 0xaf, 0x02, 0xad, 0x5c, 0xdb, 0x1e, 0x0f, 0xe1, 0x3f, 0xb5, 0xb4, 0xc2, 0x46, 0xd8, 0x73, 0xf1, 0x85, 0xe7, - 0xd8, 0x9c, 0x80, 0x06, 0xd7, 0x32, 0x05, 0xe0, 0x2c, 0xad, 0x46, 0xa3, 0x46, 0xd8, 0x67, 0xe5, 0x7c, 0x0e, 0x5b, - 0x0b, 0xf1, 0xb4, 0x00, 0x1c, 0xb8, 0x89, 0xc9, 0xc9, 0xbb, 0x31, 0x39, 0xa7, 0x1f, 0x15, 0xdc, 0x77, 0x70, 0x5e, - 0x2e, 0xe3, 0x54, 0xde, 0x02, 0x36, 0x65, 0xe0, 0xa7, 0x62, 0xa9, 0x5e, 0x42, 0xb2, 0xe4, 0xc9, 0x47, 0xb4, 0xda, - 0x48, 0x03, 0xe0, 0x2a, 0xa7, 0xc6, 0x72, 0x4f, 0x81, 0xa6, 0xba, 0x52, 0x54, 0x42, 0x5c, 0x55, 0x71, 0xb2, 0x3c, - 0xc3, 0xd4, 0x70, 0x03, 0xbd, 0x88, 0x02, 0xb9, 0xe2, 0x02, 0x48, 0x7a, 0xce, 0x7e, 0xcb, 0x34, 0xf6, 0xfa, 0x33, - 0x89, 0x02, 0x26, 0x8d, 0xa2, 0x8c, 0x95, 0xb2, 0x17, 0xd2, 0x44, 0xbf, 0x0b, 0x82, 0xda, 0xbd, 0xfc, 0x13, 0xea, - 0x7e, 0x06, 0xad, 0x08, 0x1b, 0xe0, 0x85, 0x1a, 0xfc, 0x30, 0xb5, 0x4b, 0xce, 0x03, 0x32, 0x74, 0xde, 0x67, 0xb5, - 0xdd, 0xea, 0xcf, 0x96, 0x80, 0xf5, 0x9a, 0x1a, 0x9f, 0xc2, 0x30, 0x21, 0x26, 0x56, 0xb2, 0x55, 0x56, 0xda, 0x0d, - 0x65, 0xda, 0x49, 0x97, 0xcc, 0x6b, 0xe1, 0x34, 0xef, 0x31, 0xb6, 0x1c, 0xa9, 0xdc, 0xfd, 0x7e, 0x68, 0x7e, 0xb2, - 0x9c, 0x3e, 0xd3, 0x21, 0xac, 0xbd, 0xf1, 0xa0, 0x39, 0xd1, 0xea, 0xaa, 0x8e, 0x7e, 0x40, 0x07, 0x60, 0xa6, 0x2d, - 0x42, 0xa5, 0x0b, 0xbe, 0xed, 0x2b, 0x51, 0x71, 0x49, 0xc2, 0x52, 0x49, 0x60, 0x67, 0x37, 0x25, 0x3b, 0x9b, 0x80, - 0x78, 0x86, 0xbb, 0x9e, 0x16, 0x3b, 0x21, 0x4d, 0x78, 0x8b, 0x83, 0x04, 0x44, 0x1d, 0xaa, 0xba, 0x84, 0x6c, 0x8c, - 0xa1, 0x8b, 0x7f, 0x51, 0x0a, 0x13, 0xd6, 0x32, 0xa9, 0x4a, 0x4c, 0x50, 0xa8, 0x72, 0xb7, 0x45, 0x60, 0x89, 0x82, - 0x1d, 0xc0, 0xde, 0xbb, 0x51, 0x37, 0xa3, 0xa6, 0xaa, 0x53, 0x2f, 0xc1, 0xc7, 0x69, 0xd6, 0x55, 0x90, 0x59, 0xd8, - 0x55, 0xb1, 0xe6, 0x81, 0x8e, 0xd5, 0xa5, 0x8c, 0x89, 0xbb, 0xb4, 0xc8, 0x10, 0x1f, 0x19, 0x63, 0x0b, 0x6b, 0x38, - 0xd2, 0xf6, 0xb8, 0xe9, 0x09, 0x42, 0x3f, 0x61, 0x43, 0x09, 0xdc, 0x74, 0xb6, 0xa7, 0xa6, 0x99, 0x0f, 0x88, 0x38, - 0x0c, 0x28, 0x90, 0x6c, 0x1c, 0xd2, 0x1c, 0xe9, 0x0b, 0x92, 0x26, 0x0c, 0x94, 0xad, 0x78, 0x4e, 0x90, 0x15, 0x85, - 0x9e, 0xad, 0xab, 0x36, 0xce, 0x95, 0x61, 0x8e, 0x96, 0x9c, 0x0a, 0x4f, 0x13, 0x64, 0x62, 0x7b, 0xda, 0x66, 0x26, - 0xc3, 0x51, 0xb2, 0xc0, 0xfc, 0x0a, 0xa2, 0xc4, 0x9d, 0x69, 0x56, 0xe5, 0x60, 0x5c, 0xc0, 0x02, 0xad, 0x7c, 0x0f, - 0xea, 0xc6, 0x1a, 0xda, 0x68, 0x58, 0x66, 0xb7, 0x3f, 0xc1, 0x7e, 0xad, 0x9d, 0xd6, 0x65, 0x8a, 0xe5, 0x65, 0x0a, - 0xd1, 0x5e, 0xc8, 0xfc, 0x46, 0x91, 0xe8, 0x4e, 0x11, 0x86, 0x84, 0x75, 0x94, 0x3d, 0x69, 0x53, 0x03, 0xe8, 0xa9, - 0x17, 0x00, 0xbe, 0x73, 0x2d, 0xc3, 0x2e, 0xd2, 0xfd, 0x55, 0xc1, 0xb8, 0x74, 0x83, 0x20, 0x45, 0x6f, 0x52, 0x30, - 0xe7, 0xf5, 0x28, 0xa9, 0x37, 0xa7, 0x2d, 0x33, 0xaa, 0x8e, 0x8a, 0x90, 0x72, 0x82, 0xff, 0xe4, 0x95, 0xd4, 0xc4, - 0x26, 0x4c, 0xf0, 0xc0, 0x87, 0x79, 0x86, 0x0d, 0xbc, 0xdd, 0xbe, 0x4b, 0xc3, 0xa4, 0xcd, 0x36, 0xa4, 0x20, 0xad, - 0x30, 0x71, 0x42, 0xa0, 0xb2, 0x57, 0xb8, 0x5f, 0xb0, 0x9d, 0x34, 0x05, 0x0f, 0xc2, 0x46, 0x03, 0x13, 0xb7, 0xba, - 0xf8, 0x3a, 0x4c, 0x68, 0xb8, 0xa4, 0xda, 0xd9, 0x49, 0x4b, 0x9a, 0xdb, 0xeb, 0xf2, 0xd2, 0xf6, 0x41, 0xc7, 0x52, - 0xeb, 0x1a, 0x1e, 0x68, 0x5e, 0xb3, 0x8b, 0x2b, 0xa6, 0x69, 0xa2, 0xb1, 0x1e, 0x52, 0x96, 0x1c, 0xeb, 0x7a, 0xba, - 0xc2, 0xd5, 0x32, 0xd3, 0x40, 0xf7, 0x12, 0x2f, 0xf4, 0x80, 0x0f, 0x1e, 0xae, 0x48, 0x74, 0x89, 0xcd, 0x66, 0xab, - 0x9a, 0x4c, 0xf3, 0x7d, 0xd9, 0x72, 0x13, 0x20, 0xcf, 0x52, 0xdf, 0xdc, 0x27, 0xc7, 0x9a, 0xb6, 0xf9, 0x49, 0x80, - 0x6b, 0xee, 0x15, 0x90, 0x74, 0x2c, 0x41, 0x17, 0xef, 0xd3, 0x1f, 0x44, 0x6a, 0xa6, 0x82, 0xee, 0x9d, 0x2f, 0x52, - 0x37, 0xbf, 0x00, 0xdb, 0xa8, 0x8d, 0x31, 0xcd, 0xca, 0xd6, 0x61, 0xa2, 0x2c, 0xac, 0x91, 0x85, 0x5c, 0x82, 0x0f, - 0xe6, 0x6e, 0x53, 0xa7, 0xa7, 0x1d, 0x44, 0xd8, 0xef, 0xa2, 0xc7, 0x23, 0x8c, 0x15, 0x6b, 0x90, 0x18, 0x56, 0x61, - 0x4d, 0x9b, 0xcb, 0x21, 0xca, 0xa9, 0x59, 0x32, 0xd1, 0x92, 0xfa, 0x94, 0x22, 0x4a, 0xc1, 0xdc, 0x78, 0x5a, 0x36, - 0x4c, 0x09, 0x11, 0xb2, 0x42, 0x3a, 0xa0, 0x5a, 0x0b, 0x2d, 0xd5, 0x04, 0x01, 0x0f, 0xbd, 0x2c, 0x34, 0xa6, 0x20, - 0xfa, 0x88, 0x0c, 0x37, 0xe2, 0xc8, 0xe8, 0xee, 0x18, 0xc5, 0x04, 0x42, 0x77, 0x7b, 0x79, 0x61, 0xf5, 0x69, 0xd9, - 0x56, 0x07, 0x71, 0x8d, 0x69, 0xb2, 0x87, 0xa0, 0xc6, 0x28, 0x68, 0x73, 0xba, 0xd1, 0x9f, 0x8b, 0xd0, 0xb7, 0x0b, - 0xc7, 0x6e, 0x14, 0x44, 0x42, 0x44, 0x5a, 0xaf, 0xa9, 0x18, 0xa0, 0x76, 0x1e, 0xbb, 0x88, 0x55, 0xba, 0x5b, 0x88, - 0xf2, 0x46, 0x65, 0xfd, 0x71, 0x1d, 0x92, 0xed, 0x16, 0xcb, 0x02, 0x5f, 0xf6, 0xb3, 0xf5, 0x1e, 0x08, 0xf4, 0xd7, - 0xeb, 0x4f, 0x42, 0xa0, 0xbf, 0xca, 0x3e, 0x07, 0x02, 0xfd, 0xf5, 0xfa, 0x7f, 0x1a, 0x02, 0xfd, 0x6c, 0xed, 0x41, - 0xa0, 0xab, 0xc1, 0xf8, 0xb5, 0x60, 0xc1, 0xdb, 0x37, 0x01, 0x7d, 0x2e, 0x59, 0xf0, 0xf6, 0xe5, 0x4b, 0xdf, 0x08, - 0x44, 0x68, 0x24, 0x7f, 0x23, 0x0b, 0x46, 0xdc, 0x16, 0x78, 0x85, 0x5a, 0x27, 0x1f, 0xa8, 0x28, 0x03, 0x20, 0xfa, - 0xf2, 0x9f, 0x59, 0xb5, 0x0c, 0x83, 0xc3, 0x80, 0xcc, 0x1c, 0x24, 0xe8, 0x70, 0x02, 0xb7, 0x37, 0x28, 0xe5, 0xbb, - 0xcf, 0x42, 0x53, 0x1f, 0x8d, 0x46, 0x71, 0x71, 0x85, 0x77, 0x3a, 0xb3, 0x8f, 0x10, 0xef, 0x38, 0xe3, 0xa5, 0x8d, - 0x98, 0xb1, 0x8c, 0xcb, 0x73, 0x1d, 0xaa, 0xa6, 0xb4, 0x3b, 0xb1, 0x5c, 0xca, 0xdb, 0x73, 0x80, 0xed, 0xb7, 0x5b, - 0x33, 0xc6, 0x6e, 0x28, 0x86, 0x58, 0xc7, 0xd3, 0x7d, 0xb6, 0xd6, 0xef, 0x2e, 0xe2, 0x92, 0xbf, 0x8b, 0xab, 0x25, - 0x83, 0x4e, 0xea, 0xed, 0x5a, 0xc8, 0xf5, 0xca, 0x55, 0x72, 0xbe, 0x16, 0x1f, 0x85, 0xbc, 0x15, 0x6a, 0x53, 0x9d, - 0xf3, 0x1b, 0x68, 0x11, 0xdb, 0xa0, 0x32, 0x42, 0xf0, 0xa4, 0xf2, 0x58, 0x2c, 0x05, 0xf2, 0x9e, 0x51, 0x03, 0xf3, - 0xde, 0x91, 0x83, 0x86, 0x76, 0x10, 0xb5, 0xc7, 0xb0, 0x91, 0x45, 0x67, 0x60, 0xe2, 0xf8, 0x02, 0x4a, 0x07, 0x28, - 0x6e, 0x88, 0x03, 0x01, 0x77, 0x0a, 0xe4, 0x79, 0x1b, 0x50, 0x2c, 0xb4, 0xf4, 0xfd, 0x40, 0xd4, 0x19, 0x6a, 0x60, - 0x0c, 0x1b, 0xc3, 0x84, 0xf7, 0x26, 0xf4, 0x05, 0x05, 0x8d, 0x6e, 0x01, 0x2e, 0x87, 0x7f, 0xae, 0xf9, 0x79, 0x96, - 0x22, 0xe0, 0x4d, 0x96, 0x2a, 0x6b, 0xa2, 0x1e, 0x0a, 0x39, 0xf0, 0xd9, 0x53, 0x3e, 0xe9, 0x78, 0x61, 0x9e, 0xbd, - 0xd5, 0x46, 0xa9, 0x58, 0xe7, 0x60, 0xeb, 0xe3, 0xd7, 0x32, 0x97, 0x3a, 0xe0, 0xf4, 0xb9, 0x58, 0x5f, 0xf3, 0x22, - 0x4b, 0xce, 0x97, 0x59, 0x59, 0xc9, 0xe2, 0x7e, 0x61, 0x70, 0x0c, 0x74, 0x59, 0xad, 0x49, 0xdc, 0xfb, 0x1d, 0x38, - 0x33, 0xab, 0xc8, 0x14, 0xc3, 0xa7, 0x63, 0x52, 0x6b, 0x33, 0x68, 0x68, 0x20, 0xb5, 0xbf, 0x53, 0x09, 0xc0, 0xe9, - 0xee, 0xd9, 0x76, 0x8d, 0x36, 0x0d, 0xd8, 0xdb, 0x35, 0x52, 0xb3, 0x94, 0x0a, 0xfe, 0xe7, 0x9a, 0x1b, 0x18, 0xfb, - 0xd0, 0x41, 0x34, 0x97, 0x3d, 0xad, 0x63, 0x50, 0xd8, 0x3e, 0x44, 0xf1, 0xf8, 0x69, 0xfa, 0x02, 0xa1, 0xb6, 0xe1, - 0x6e, 0x8b, 0xda, 0x73, 0x1b, 0xa9, 0xa9, 0x6b, 0x6d, 0xcc, 0xa1, 0xad, 0x8b, 0xd9, 0xa7, 0x32, 0x0c, 0x06, 0xd1, - 0xa7, 0xb2, 0xb0, 0xc9, 0x03, 0x4b, 0x50, 0x65, 0x39, 0x36, 0x16, 0x73, 0x5a, 0x05, 0x0e, 0x89, 0x1e, 0x26, 0x2d, - 0x60, 0xcf, 0x00, 0x52, 0x6d, 0x02, 0xa3, 0xaa, 0xb5, 0xa2, 0x0e, 0x6c, 0x76, 0x8a, 0x46, 0x0b, 0xe1, 0xef, 0x8f, - 0x36, 0xcd, 0xcd, 0x50, 0x1f, 0x3e, 0xda, 0xc4, 0xf0, 0x5f, 0x52, 0xcf, 0x52, 0x5e, 0xc5, 0x59, 0xce, 0xe2, 0x3c, - 0xff, 0x9d, 0x6e, 0xae, 0x79, 0xb5, 0x94, 0x69, 0x14, 0x7c, 0xf7, 0xe2, 0x43, 0x60, 0xb4, 0x96, 0xb9, 0xc6, 0xab, - 0xd1, 0x82, 0xfc, 0x5c, 0x5e, 0x85, 0x39, 0xa1, 0xbd, 0x7c, 0x24, 0x3f, 0xee, 0x04, 0x78, 0xfc, 0xfd, 0xfb, 0x0f, - 0x1f, 0xde, 0x1d, 0xa0, 0xac, 0xbf, 0x77, 0x70, 0xa6, 0x1c, 0xc7, 0x0f, 0x1e, 0x6d, 0x72, 0xad, 0x5d, 0xad, 0x7f, - 0x77, 0x17, 0xf7, 0x96, 0x6e, 0x34, 0xd7, 0x5b, 0xc0, 0xab, 0xa2, 0x35, 0x37, 0xb9, 0x53, 0x60, 0xfa, 0x99, 0x95, - 0x62, 0x21, 0x40, 0xb1, 0xb9, 0xaa, 0x39, 0x0a, 0x28, 0xe4, 0x05, 0x90, 0xfd, 0xb0, 0xda, 0xb3, 0x19, 0xab, 0xae, - 0xcd, 0x28, 0x8b, 0x2a, 0x13, 0x57, 0xe7, 0x48, 0x1f, 0x3e, 0x6b, 0x53, 0x9a, 0x65, 0xa2, 0x28, 0x4a, 0x7b, 0x3f, - 0x36, 0x50, 0xaa, 0xb4, 0x3d, 0xa6, 0xde, 0x65, 0x20, 0x2b, 0x29, 0xeb, 0xa9, 0xff, 0xb1, 0x31, 0x16, 0xf0, 0xd3, - 0x14, 0x86, 0x17, 0x1c, 0x7f, 0xec, 0x24, 0x1e, 0x99, 0xf6, 0xdd, 0xe2, 0x95, 0xf9, 0x38, 0x69, 0x25, 0xcc, 0x86, - 0x93, 0x68, 0x42, 0x6c, 0x68, 0x01, 0x4d, 0xe5, 0xbe, 0x1b, 0xbd, 0x78, 0xf3, 0xe1, 0xd5, 0x87, 0x7f, 0x9d, 0x3f, - 0x3b, 0xfd, 0xf0, 0xe2, 0xbb, 0xb7, 0xef, 0x5f, 0xbd, 0x38, 0x43, 0x1c, 0x3d, 0x8d, 0x55, 0x18, 0x6e, 0xb4, 0x41, - 0x6c, 0xb3, 0xac, 0x48, 0xd4, 0xa4, 0xd9, 0x14, 0x05, 0x16, 0x84, 0x99, 0x6d, 0x91, 0x3f, 0xbf, 0x79, 0xfe, 0xe2, - 0xe5, 0xab, 0x37, 0x2f, 0x9e, 0xb7, 0xbf, 0x1e, 0x4e, 0x6a, 0x52, 0xbb, 0x99, 0xd3, 0xc1, 0x31, 0xb8, 0x1d, 0xaf, - 0x0e, 0x0a, 0x86, 0x0a, 0x59, 0x9f, 0x82, 0x65, 0x40, 0xb1, 0x98, 0x12, 0xd1, 0xe2, 0x6f, 0x1d, 0x88, 0x2a, 0x6b, - 0x6d, 0x80, 0x12, 0x07, 0x33, 0xa3, 0x8a, 0x64, 0x44, 0x02, 0x76, 0x83, 0x2d, 0x07, 0x0c, 0x5f, 0x53, 0x0a, 0x48, - 0x3e, 0x1d, 0xbb, 0x83, 0x2a, 0x7c, 0xfd, 0xf3, 0x24, 0xae, 0xf8, 0x95, 0x2c, 0xee, 0xa3, 0x6c, 0xd4, 0x4a, 0xa1, - 0x8d, 0x25, 0x11, 0x85, 0x20, 0x65, 0x6c, 0x24, 0x11, 0x45, 0x4e, 0x66, 0xde, 0xa0, 0xb8, 0x71, 0x9e, 0x3b, 0xe8, - 0xf8, 0x76, 0xc1, 0x64, 0xb1, 0xdd, 0x76, 0x0c, 0x63, 0x27, 0xbd, 0x8c, 0xe6, 0x99, 0x22, 0xa4, 0x0b, 0xe0, 0xd2, - 0xe0, 0x48, 0x54, 0xe7, 0x1d, 0x33, 0x47, 0xe4, 0xa9, 0x0e, 0x01, 0x09, 0xa6, 0x69, 0xee, 0xb5, 0x89, 0x32, 0xd2, - 0x3c, 0x43, 0xc7, 0x2d, 0x2a, 0x6d, 0x00, 0x5f, 0x5b, 0xa9, 0x6a, 0xe1, 0x69, 0xa0, 0x3d, 0x98, 0x3b, 0x88, 0xcd, - 0x64, 0xe4, 0x78, 0x61, 0x0e, 0xe6, 0x12, 0x8d, 0x19, 0x37, 0xe3, 0x90, 0x47, 0xd2, 0x60, 0xa6, 0x81, 0xfd, 0xd8, - 0x9e, 0x5c, 0xcb, 0xa8, 0x68, 0xa0, 0x1f, 0xca, 0xe6, 0xa0, 0x1e, 0x17, 0xcd, 0x67, 0x58, 0xd8, 0xad, 0x2c, 0x28, - 0xbf, 0x6b, 0x66, 0x82, 0x7b, 0x66, 0x32, 0x53, 0xd5, 0x8f, 0x2a, 0xf9, 0xa3, 0xbc, 0x35, 0xb2, 0xc2, 0xe3, 0xa2, - 0x23, 0x11, 0x77, 0x4b, 0x14, 0x1f, 0x27, 0xea, 0xc7, 0xa4, 0xde, 0x73, 0x70, 0xd4, 0x6e, 0x80, 0xad, 0x2c, 0xfb, - 0x77, 0xc5, 0x3f, 0x9f, 0x3f, 0xda, 0x64, 0xfa, 0xa4, 0xaa, 0x7f, 0xcf, 0x6c, 0x24, 0xd0, 0x06, 0x33, 0x52, 0xeb, - 0xa1, 0xf7, 0x81, 0x27, 0x3b, 0xb2, 0xe9, 0xf5, 0xc1, 0xb2, 0x4e, 0x8e, 0x66, 0xa4, 0x1e, 0xb9, 0x0a, 0x8c, 0xd8, - 0x9d, 0x85, 0xdf, 0xf1, 0x24, 0xec, 0x6a, 0x98, 0x92, 0x35, 0x98, 0x2e, 0x20, 0x16, 0xef, 0xfe, 0x43, 0xc1, 0x7e, - 0x86, 0xbf, 0xb3, 0x14, 0xfe, 0x56, 0xb5, 0x77, 0x30, 0xbc, 0x7b, 0x7b, 0xf6, 0x01, 0x14, 0x1c, 0x31, 0x6a, 0x24, - 0x37, 0x81, 0x36, 0x66, 0x18, 0x82, 0xca, 0x20, 0x88, 0x82, 0x78, 0x05, 0x27, 0x3b, 0xb2, 0x8e, 0x87, 0x77, 0xc3, - 0xdb, 0xdb, 0xdb, 0xff, 0xd3, 0xdc, 0xb3, 0x6e, 0xb7, 0x6d, 0x23, 0xfd, 0xbf, 0x4f, 0xc1, 0x30, 0xd9, 0x94, 0x4c, - 0x48, 0x9a, 0x94, 0x2c, 0x5b, 0x91, 0x2c, 0xb9, 0xcd, 0xa5, 0x5b, 0x77, 0xdd, 0xa6, 0x27, 0x71, 0xfb, 0xed, 0xae, - 0xeb, 0x63, 0x51, 0x12, 0x24, 0x71, 0x43, 0x91, 0x3a, 0x24, 0xe5, 0x4b, 0x15, 0xee, 0xb3, 0xec, 0x23, 0x7c, 0xcf, - 0xd0, 0x27, 0xfb, 0xce, 0xcc, 0x00, 0x24, 0x78, 0x93, 0xe4, 0x4d, 0xda, 0x7e, 0xa7, 0x4d, 0x22, 0x82, 0x00, 0x08, - 0x0c, 0x80, 0xb9, 0x61, 0x2e, 0x26, 0x98, 0x36, 0x9a, 0xeb, 0xc8, 0x67, 0xc1, 0x24, 0x84, 0xc4, 0x24, 0xa9, 0x40, - 0xf8, 0xac, 0x84, 0xf0, 0x21, 0x2e, 0x2a, 0x4f, 0xac, 0xf1, 0x7e, 0x11, 0xde, 0x7e, 0xed, 0xfb, 0xb2, 0xfc, 0x2e, - 0x98, 0x3e, 0x2e, 0xd2, 0x16, 0x10, 0x88, 0x06, 0xd7, 0x10, 0x96, 0x17, 0x5f, 0xf3, 0x8b, 0xe3, 0xe9, 0xf5, 0xf8, - 0xfe, 0x9a, 0x2b, 0xa7, 0xb3, 0xc0, 0xb4, 0xaf, 0x46, 0x27, 0x53, 0xef, 0x46, 0x41, 0xce, 0x74, 0xa0, 0x82, 0x57, - 0x8f, 0xcf, 0xc6, 0xeb, 0x24, 0x09, 0x03, 0x33, 0x0a, 0x6f, 0xd5, 0xe1, 0x09, 0x3d, 0x88, 0x0a, 0x2e, 0x3d, 0xaa, - 0xca, 0x57, 0x13, 0xdf, 0x9b, 0x7c, 0x18, 0xa8, 0x4f, 0x36, 0xde, 0x60, 0x58, 0xe2, 0x3f, 0xed, 0x54, 0x1d, 0xc2, - 0x58, 0x95, 0xaf, 0x7d, 0xff, 0xe4, 0x80, 0x5a, 0x0c, 0x4f, 0x0e, 0xa6, 0xde, 0xcd, 0x50, 0xca, 0x11, 0xc2, 0x2f, - 0xd0, 0x06, 0x3c, 0x16, 0x63, 0x66, 0x72, 0x14, 0xa3, 0x73, 0xff, 0x84, 0x69, 0xb9, 0x14, 0x04, 0x41, 0x47, 0x68, - 0xbc, 0xda, 0x04, 0xf5, 0xaa, 0x3e, 0xf0, 0xfc, 0x1f, 0x3f, 0x6a, 0x99, 0x41, 0xe2, 0x42, 0x8a, 0xd6, 0x85, 0xf7, - 0x3d, 0x58, 0xc5, 0xc0, 0x90, 0x23, 0xba, 0x26, 0x62, 0x8a, 0xf9, 0xba, 0x31, 0x49, 0x0d, 0x4c, 0xb5, 0xe2, 0xae, - 0x80, 0x47, 0xe0, 0x3f, 0x25, 0xd1, 0x68, 0x02, 0xe9, 0x95, 0x25, 0x04, 0xaf, 0x4b, 0xca, 0x77, 0x3a, 0x9b, 0x3c, - 0x60, 0x1c, 0x68, 0xcd, 0xf1, 0x3b, 0xa4, 0x10, 0xd7, 0x7c, 0x1d, 0xd2, 0x7b, 0x65, 0x51, 0x5a, 0xdc, 0x54, 0x24, - 0xd4, 0x12, 0x70, 0x39, 0x2d, 0xac, 0x50, 0xaf, 0xbc, 0x5e, 0x22, 0x7c, 0xe0, 0xa3, 0xb8, 0x69, 0xc9, 0xe0, 0x32, - 0x47, 0x4b, 0x8c, 0x12, 0x3d, 0x06, 0xf7, 0x2e, 0xe9, 0x06, 0x81, 0x19, 0xda, 0x65, 0x6c, 0x84, 0x57, 0x39, 0x0d, - 0x8b, 0x09, 0x7d, 0xf6, 0xc2, 0x34, 0x8f, 0xe4, 0x4b, 0xab, 0x3e, 0x7c, 0xb2, 0x09, 0x90, 0xe8, 0xc5, 0x83, 0x61, - 0x71, 0x1f, 0x24, 0xee, 0xd8, 0xa4, 0xcd, 0xac, 0x2a, 0x5f, 0x4d, 0xc7, 0x7e, 0xb6, 0xd8, 0x74, 0x34, 0x16, 0x6e, - 0x30, 0xf5, 0xd9, 0x85, 0x3b, 0xfe, 0x16, 0xeb, 0xbc, 0x1e, 0xfb, 0xaf, 0xa0, 0x42, 0xaa, 0x0e, 0x9f, 0x6c, 0x88, - 0xac, 0xd7, 0xa1, 0xf1, 0x94, 0xb6, 0x40, 0xf9, 0x3b, 0x3c, 0xf7, 0x0e, 0x8b, 0xa8, 0x35, 0x0e, 0x96, 0x48, 0x31, - 0xe1, 0xd9, 0xe2, 0xc8, 0x78, 0xee, 0x17, 0xd8, 0x9b, 0x0a, 0x3f, 0x94, 0x30, 0xae, 0x50, 0x1c, 0x50, 0x79, 0x67, - 0xca, 0x83, 0x25, 0x92, 0xfb, 0x2e, 0xbc, 0x15, 0x23, 0xe5, 0x00, 0xa0, 0x58, 0x85, 0xa7, 0xaf, 0x46, 0x27, 0xf2, - 0xfd, 0x00, 0x2a, 0x51, 0xa9, 0x5f, 0xf8, 0x95, 0xaa, 0x4a, 0x9e, 0x09, 0x68, 0x75, 0xa7, 0x0e, 0x4f, 0x0e, 0xe4, - 0xda, 0xc3, 0x51, 0xef, 0x5c, 0x9a, 0x1c, 0xf6, 0x0a, 0x40, 0x28, 0x96, 0x55, 0xa8, 0x0e, 0x24, 0xc7, 0xcb, 0xe9, - 0x12, 0x6d, 0x0f, 0x81, 0x16, 0x43, 0xbd, 0x97, 0xad, 0x11, 0xd9, 0xe0, 0x89, 0xde, 0x46, 0xfc, 0xdf, 0x7c, 0xce, - 0xa8, 0xd3, 0x64, 0x41, 0x1c, 0x46, 0x2a, 0xcc, 0xa3, 0x9c, 0x21, 0x47, 0x91, 0x32, 0x73, 0xe1, 0x8c, 0x6a, 0xa9, - 0x29, 0x40, 0xe4, 0xa0, 0xdc, 0x54, 0x9a, 0xd8, 0x48, 0xcf, 0x7f, 0x28, 0x7c, 0x32, 0x25, 0xac, 0x94, 0x0d, 0xb0, - 0x39, 0xf3, 0xd0, 0xe5, 0x5b, 0xcf, 0xf8, 0x9f, 0xd0, 0x98, 0xbb, 0xc6, 0xd2, 0x35, 0xde, 0x07, 0x57, 0x69, 0xed, - 0xea, 0x64, 0x59, 0xc3, 0x0c, 0xd6, 0xd7, 0x20, 0xd6, 0x0e, 0xd7, 0x80, 0x70, 0xbd, 0x80, 0x67, 0x71, 0xeb, 0x80, - 0x0b, 0x37, 0x9a, 0x33, 0x91, 0xac, 0x4b, 0xbc, 0x4d, 0x38, 0x54, 0x74, 0x09, 0x2c, 0x10, 0x88, 0x4a, 0x08, 0x38, - 0x9e, 0x35, 0x49, 0x22, 0xff, 0x6f, 0xec, 0x1e, 0x24, 0xcf, 0x38, 0x09, 0x57, 0xa0, 0x9d, 0x70, 0xe7, 0x5c, 0xdb, - 0x6c, 0x00, 0x2f, 0xb3, 0xcf, 0xe7, 0x3e, 0x7e, 0x64, 0x52, 0xfe, 0xa8, 0x24, 0x9c, 0xcf, 0x7d, 0xa6, 0x49, 0x79, - 0xa6, 0xb2, 0xcf, 0x9c, 0x3e, 0xb2, 0x45, 0x8c, 0x62, 0x3d, 0x6d, 0x3a, 0x39, 0x39, 0x2b, 0x28, 0xee, 0x75, 0x49, - 0x58, 0xc7, 0xdb, 0xa8, 0x1b, 0xbc, 0xd0, 0xe5, 0xeb, 0x92, 0x9f, 0x4c, 0x73, 0x1a, 0xae, 0xc7, 0x3e, 0x33, 0x71, - 0xbb, 0xc3, 0x27, 0x37, 0xe3, 0xf5, 0x78, 0xec, 0x53, 0x62, 0x28, 0x88, 0xb4, 0x15, 0xc6, 0xa8, 0x01, 0x4b, 0xf5, - 0x3e, 0x32, 0x68, 0x49, 0x79, 0xf8, 0x60, 0x1d, 0x07, 0x62, 0x03, 0x7d, 0x20, 0x01, 0x6d, 0x57, 0xf5, 0xd0, 0x0e, - 0x54, 0x10, 0x57, 0x58, 0xac, 0xf6, 0x6b, 0x38, 0xb9, 0xc1, 0xa5, 0xfa, 0x1e, 0x21, 0x8c, 0xd9, 0xeb, 0x5f, 0xd1, - 0xde, 0x55, 0x0d, 0x95, 0x8c, 0x7c, 0x78, 0x1e, 0x31, 0xd5, 0x50, 0x5f, 0x7b, 0xee, 0x3c, 0x08, 0xe3, 0xc4, 0x9b, - 0xa8, 0x57, 0xfd, 0x33, 0x4f, 0xbb, 0x5c, 0x26, 0x9a, 0x7e, 0x65, 0xfc, 0x55, 0xce, 0xf8, 0x24, 0x50, 0x21, 0x26, - 0x7c, 0x6a, 0xa8, 0x23, 0x9f, 0x9e, 0x6d, 0xf5, 0x04, 0xca, 0xc5, 0x3a, 0x7f, 0x1d, 0x40, 0xad, 0x52, 0xee, 0x28, - 0x4c, 0x0a, 0x08, 0xb9, 0xa3, 0xfe, 0xaa, 0xf7, 0x49, 0x2b, 0xf3, 0x6a, 0xbd, 0x41, 0x5e, 0x21, 0xc9, 0xa9, 0x2b, - 0x86, 0x3b, 0x17, 0x3e, 0x82, 0xf4, 0xfc, 0x48, 0xb6, 0x6f, 0x2f, 0xd0, 0xe9, 0xd1, 0xd7, 0x45, 0xc6, 0x03, 0x18, - 0x04, 0x30, 0x2e, 0x0b, 0xc2, 0x44, 0x81, 0x18, 0x5e, 0xf0, 0xc1, 0x51, 0xd9, 0x1e, 0x96, 0xf7, 0xaa, 0xe9, 0x29, - 0xc7, 0x02, 0x2f, 0x91, 0x58, 0x8a, 0xec, 0xef, 0x18, 0x8e, 0xb2, 0x10, 0xb1, 0x87, 0x7b, 0x61, 0xc1, 0xf2, 0x15, - 0xd8, 0x36, 0x09, 0xb1, 0x17, 0x09, 0xf6, 0x93, 0x4d, 0x7c, 0x2a, 0xa8, 0xf6, 0x59, 0x8c, 0x6b, 0x09, 0xfc, 0x08, - 0x27, 0xe3, 0xa9, 0xaa, 0x9c, 0x0a, 0x52, 0x83, 0x75, 0x0b, 0xf8, 0x53, 0x13, 0x5c, 0xae, 0x48, 0xea, 0xae, 0xf1, - 0x14, 0xd4, 0x82, 0xef, 0x2a, 0x1d, 0x3d, 0x08, 0xcb, 0x93, 0xb1, 0x54, 0x09, 0xd8, 0xd6, 0x22, 0x45, 0x00, 0xcc, - 0xc5, 0x99, 0x80, 0x51, 0x7a, 0x0d, 0xfc, 0x23, 0xc4, 0xaa, 0x12, 0x73, 0x34, 0x42, 0x39, 0x5d, 0x98, 0x17, 0xac, - 0xd6, 0x09, 0xc6, 0x20, 0x87, 0x01, 0xb0, 0x54, 0x55, 0x50, 0x5a, 0x04, 0x64, 0x9e, 0x4b, 0x41, 0xa9, 0xaa, 0x78, - 0xd3, 0x6a, 0x19, 0x57, 0xdd, 0x00, 0x8e, 0xc3, 0x69, 0xa0, 0x06, 0x1f, 0x1e, 0x23, 0x3e, 0x8d, 0x89, 0x91, 0x27, - 0xf0, 0xd0, 0x26, 0x78, 0xd3, 0x5d, 0x83, 0x40, 0x26, 0xd4, 0x4f, 0x5f, 0xf3, 0x6b, 0x27, 0x0b, 0x71, 0x89, 0x0b, - 0xd3, 0x1c, 0x3d, 0xd9, 0x04, 0xe9, 0x29, 0xc0, 0x6e, 0xf0, 0x64, 0xe3, 0x66, 0x46, 0x54, 0xea, 0x85, 0x4a, 0x16, - 0x54, 0x23, 0x04, 0xc3, 0x28, 0xbd, 0xce, 0x5d, 0x1a, 0xf3, 0xf9, 0xc2, 0x96, 0xa4, 0x72, 0x05, 0x6d, 0x9a, 0x06, - 0xdc, 0x72, 0x69, 0x15, 0x79, 0x4b, 0x37, 0xba, 0x27, 0x43, 0x27, 0x43, 0xb6, 0x86, 0xd2, 0x55, 0x85, 0xe8, 0x01, - 0x01, 0x80, 0x48, 0x83, 0xaa, 0x7c, 0x95, 0x95, 0x31, 0x3e, 0xdb, 0xcc, 0xda, 0x03, 0xbe, 0x75, 0xad, 0x3e, 0x67, - 0x16, 0xa9, 0x34, 0xa8, 0x49, 0x5f, 0x8b, 0x1b, 0xa6, 0x17, 0x17, 0xa7, 0x17, 0x14, 0x37, 0x1a, 0x4e, 0x86, 0x28, - 0x05, 0x8d, 0x1b, 0x67, 0x86, 0xe9, 0x0e, 0xeb, 0x57, 0x94, 0xde, 0xfd, 0xa1, 0xcb, 0xc1, 0x60, 0x39, 0x02, 0x58, - 0x0e, 0xe2, 0xae, 0x7f, 0x7a, 0x77, 0x96, 0xe5, 0x57, 0x04, 0xd5, 0xf8, 0x88, 0x6f, 0xcc, 0x18, 0xd9, 0x8c, 0x08, - 0x59, 0x0c, 0xca, 0x84, 0xa8, 0x64, 0x5b, 0x28, 0x82, 0xa3, 0x41, 0x63, 0xa7, 0xa3, 0x11, 0x0d, 0x06, 0x21, 0xb6, - 0x8a, 0xd2, 0x93, 0x03, 0xaa, 0x4d, 0x44, 0x91, 0x2a, 0x01, 0x18, 0x22, 0x98, 0x61, 0x0e, 0x05, 0x48, 0x05, 0x3d, - 0x70, 0x72, 0xf9, 0xc6, 0x5a, 0xe2, 0x05, 0xa4, 0x73, 0x5a, 0xe4, 0x68, 0xb0, 0x95, 0x3a, 0x3c, 0xc1, 0xe4, 0x8e, - 0x40, 0xd6, 0x21, 0xfc, 0xd1, 0xc9, 0x01, 0x3d, 0x2a, 0xa5, 0x13, 0x91, 0x77, 0x22, 0x14, 0x94, 0x3d, 0xde, 0xc1, - 0x83, 0x8e, 0x4a, 0x9c, 0xb0, 0x15, 0x94, 0xba, 0xa9, 0xaa, 0x2c, 0x39, 0x07, 0xc5, 0xe3, 0xac, 0x41, 0x10, 0x16, - 0x1b, 0x8c, 0xdf, 0x55, 0x65, 0xe9, 0xde, 0xe1, 0xcc, 0xc5, 0x1b, 0xf7, 0x4e, 0x73, 0xf8, 0xab, 0xfc, 0xac, 0xc5, - 0xc5, 0xb3, 0x36, 0xe1, 0x8b, 0x0b, 0x1e, 0x56, 0x82, 0x73, 0xd6, 0x16, 0x68, 0xb9, 0x52, 0xb3, 0xb8, 0x0b, 0xb1, - 0xb8, 0xd3, 0x86, 0xc5, 0x9d, 0x6e, 0x59, 0x5c, 0x9f, 0x2f, 0xa4, 0x92, 0x81, 0x2e, 0x42, 0xaf, 0xd9, 0x0c, 0x78, - 0x9c, 0x1f, 0xe9, 0xf1, 0x73, 0x86, 0x70, 0x32, 0x63, 0x1f, 0xac, 0x46, 0x1b, 0x60, 0x55, 0x07, 0x17, 0x09, 0x10, - 0xd5, 0x89, 0x67, 0xa7, 0x6e, 0x22, 0x29, 0x04, 0x34, 0xbf, 0x3c, 0x5f, 0xd8, 0xa5, 0xd8, 0xd0, 0xd0, 0x16, 0x0d, - 0x33, 0x5d, 0x6c, 0x99, 0xe9, 0xa4, 0x70, 0x74, 0xf9, 0xb4, 0xe9, 0x10, 0xca, 0x93, 0x82, 0x3d, 0x08, 0x96, 0xf4, - 0xb8, 0x65, 0x8a, 0xfb, 0xb0, 0x19, 0xc7, 0x4a, 0x3b, 0x6a, 0xe5, 0xc6, 0xf1, 0x6d, 0x18, 0xc1, 0x55, 0x34, 0x74, - 0xf3, 0xb0, 0x2d, 0xb5, 0xf4, 0x02, 0x1e, 0xe5, 0xaa, 0x71, 0x33, 0xe5, 0xef, 0xe5, 0x2d, 0xd5, 0xea, 0x74, 0xa8, - 0xc6, 0xca, 0x4d, 0x12, 0x16, 0x21, 0xd0, 0x5d, 0x48, 0x87, 0xf0, 0xff, 0x64, 0x9b, 0xd5, 0xe0, 0x10, 0x5f, 0xc2, - 0xea, 0x88, 0xa1, 0x57, 0xc0, 0x82, 0xd1, 0xdd, 0x53, 0xa0, 0x6f, 0xa4, 0x88, 0x99, 0x51, 0x06, 0xf8, 0x1f, 0xf0, - 0xb8, 0x6a, 0x91, 0xe4, 0xd3, 0xe9, 0x1c, 0xe9, 0xd6, 0xca, 0x9d, 0xbe, 0x07, 0x8b, 0x07, 0xad, 0x65, 0x80, 0xf7, - 0x82, 0x1c, 0x1f, 0x33, 0x22, 0x9e, 0x70, 0x92, 0x23, 0x49, 0xc4, 0x92, 0xdc, 0x36, 0x14, 0xdc, 0xca, 0x5d, 0x73, - 0x76, 0xb5, 0x69, 0xa5, 0x07, 0x73, 0x4f, 0xaf, 0x60, 0x4d, 0x40, 0x6d, 0xfe, 0x60, 0x98, 0xe9, 0xda, 0x7c, 0xc3, - 0x39, 0xd2, 0xe1, 0x4a, 0xec, 0x12, 0x12, 0x5f, 0xdb, 0x42, 0x5a, 0x1e, 0x45, 0x40, 0xb5, 0x2e, 0xed, 0xab, 0xf4, - 0xe9, 0x1c, 0x7f, 0x39, 0x57, 0xe9, 0xd3, 0x31, 0xfe, 0x6a, 0x5d, 0x61, 0x4a, 0xcf, 0x1a, 0x35, 0x81, 0x34, 0x67, - 0x75, 0x58, 0xd8, 0x4f, 0x64, 0x98, 0xfb, 0x80, 0x6d, 0xc3, 0x17, 0xf8, 0xf1, 0x93, 0x4d, 0x0c, 0xae, 0xe8, 0xf2, - 0x1c, 0x02, 0x2b, 0xd2, 0xd3, 0xda, 0xf2, 0x79, 0x43, 0xf9, 0x58, 0xff, 0x83, 0x09, 0x3f, 0xee, 0x92, 0x30, 0xa7, - 0x29, 0x45, 0x25, 0xc7, 0xf5, 0xd8, 0x0b, 0xdc, 0xe8, 0xfe, 0x9a, 0xa4, 0x10, 0x4d, 0xd2, 0xf6, 0x3e, 0xca, 0xa5, - 0xff, 0xfb, 0xa2, 0x1d, 0x40, 0x22, 0xdd, 0x65, 0xdd, 0x73, 0x42, 0x3f, 0xf8, 0x7b, 0x24, 0xf1, 0x77, 0x05, 0x39, - 0x95, 0x2f, 0x48, 0xe1, 0x43, 0xd7, 0x4f, 0x36, 0x1a, 0xab, 0x76, 0x53, 0x9a, 0x6d, 0x89, 0x81, 0x84, 0xe5, 0x41, - 0x99, 0x77, 0x39, 0xf5, 0x7a, 0x78, 0xd1, 0x3f, 0x0e, 0xef, 0xcc, 0x27, 0x9b, 0xe4, 0x54, 0x5d, 0xba, 0xd1, 0x07, - 0x36, 0x35, 0x27, 0x5e, 0x34, 0xf1, 0x81, 0x79, 0x1c, 0xfb, 0x6e, 0xf0, 0x81, 0x3f, 0x9a, 0xe1, 0x3a, 0x41, 0xd3, - 0x9d, 0x9d, 0x22, 0xb2, 0x80, 0x09, 0xe9, 0x0f, 0x91, 0xab, 0xad, 0x81, 0x82, 0xf2, 0x2a, 0xd3, 0xbf, 0xe5, 0x8c, - 0x62, 0x5e, 0xcb, 0x00, 0xcb, 0x73, 0xb0, 0x26, 0x02, 0x57, 0x7e, 0x43, 0xc5, 0xf5, 0x52, 0x0d, 0x79, 0xaa, 0x74, - 0xe5, 0x96, 0xe5, 0xa2, 0xbd, 0xc6, 0x1e, 0xfe, 0xfb, 0xcf, 0x41, 0xc9, 0x43, 0x3e, 0x97, 0xf5, 0xf2, 0x69, 0x33, - 0x84, 0x52, 0x93, 0x5c, 0xc8, 0x1e, 0xf0, 0x71, 0xce, 0x60, 0x36, 0x7f, 0x5a, 0x6e, 0xec, 0xc6, 0xf1, 0x7a, 0xc9, - 0xa6, 0x74, 0xb5, 0x76, 0x9a, 0x0f, 0xaa, 0x28, 0x87, 0xc8, 0x03, 0xfb, 0x65, 0xdd, 0x3a, 0x3e, 0x7c, 0x05, 0xa6, - 0x5c, 0xc0, 0x50, 0x86, 0xb3, 0x99, 0x9a, 0xab, 0x02, 0x76, 0x34, 0x73, 0x0e, 0x7f, 0x59, 0x7f, 0xf3, 0xc6, 0xfe, - 0x26, 0x6b, 0x1c, 0x00, 0x63, 0x2c, 0xec, 0x52, 0x38, 0x5f, 0x2c, 0x8d, 0x57, 0xcc, 0x68, 0xe6, 0x06, 0xcd, 0xd3, - 0xb9, 0x2c, 0x6c, 0xf1, 0x15, 0x63, 0x53, 0x60, 0xb8, 0x8d, 0x4a, 0xe9, 0xb5, 0xcf, 0x6e, 0x58, 0x66, 0xf3, 0x52, - 0xfd, 0x58, 0x4d, 0x0b, 0x0c, 0xca, 0xc9, 0x6f, 0x32, 0x39, 0x57, 0x27, 0x4d, 0x69, 0x84, 0x73, 0xe0, 0x33, 0x97, - 0x8f, 0x58, 0xe9, 0x48, 0x8d, 0x0c, 0x55, 0x1a, 0x40, 0xe3, 0xc8, 0x4e, 0x1b, 0xca, 0x7b, 0x80, 0xa8, 0x1b, 0xc6, - 0x66, 0x38, 0x7a, 0x0f, 0x92, 0x18, 0x70, 0x38, 0xf9, 0x70, 0xf2, 0xb4, 0x5c, 0x6b, 0xd2, 0x04, 0xb1, 0x3a, 0x5d, - 0x9a, 0x4a, 0x4a, 0x1a, 0x61, 0x06, 0x8e, 0xfe, 0x10, 0x42, 0x5d, 0x55, 0xbb, 0x36, 0x4a, 0x71, 0xe6, 0x63, 0x4c, - 0xf1, 0x1d, 0xb0, 0x38, 0x6e, 0x04, 0x58, 0xb6, 0xe8, 0x86, 0x9a, 0xd7, 0x2e, 0xc2, 0x23, 0x2f, 0x37, 0x6c, 0x03, - 0x58, 0x02, 0x9c, 0x60, 0xf9, 0x5b, 0x48, 0x5e, 0xae, 0x97, 0xdc, 0x90, 0x2f, 0x9a, 0x8f, 0x55, 0x6e, 0x64, 0xd5, - 0xf4, 0xfe, 0x56, 0xe5, 0x83, 0x2a, 0x90, 0xe9, 0xda, 0xa1, 0x69, 0x05, 0xd4, 0x5b, 0xd1, 0x2a, 0x61, 0x07, 0x62, - 0x4c, 0x25, 0xfc, 0xca, 0x66, 0x33, 0x36, 0x49, 0x62, 0x5d, 0xe8, 0x98, 0xb2, 0xb0, 0xda, 0x70, 0x7b, 0xf7, 0x68, - 0xa0, 0xfe, 0x00, 0xc1, 0x45, 0x44, 0xf4, 0x39, 0x3e, 0x20, 0x21, 0x33, 0xd5, 0x83, 0x89, 0x7a, 0x2c, 0x82, 0x88, - 0x7f, 0x05, 0xd4, 0xcc, 0x35, 0xe5, 0x38, 0x34, 0x4e, 0x7f, 0xf2, 0x7d, 0x11, 0x66, 0xe6, 0x7e, 0xdb, 0x51, 0xd1, - 0xb6, 0xe3, 0xbb, 0x71, 0xbe, 0xe9, 0x38, 0x76, 0xaa, 0x1a, 0xe0, 0xd4, 0xfa, 0xa1, 0xb4, 0x8d, 0x89, 0x40, 0x0d, - 0xd4, 0xf3, 0xb7, 0xaf, 0xfe, 0xf6, 0xe6, 0xf5, 0xbe, 0x18, 0x01, 0xbb, 0x6c, 0x43, 0x97, 0xeb, 0x60, 0x4b, 0xa7, - 0x3f, 0xfd, 0xf0, 0xb0, 0x6e, 0x5b, 0xce, 0x0b, 0x47, 0x35, 0xc8, 0x0e, 0x59, 0xc2, 0x8b, 0x93, 0xf0, 0x86, 0x45, - 0x9f, 0x0c, 0x06, 0xb9, 0xf3, 0xfa, 0xe1, 0xbe, 0xfd, 0xf1, 0xcd, 0x0f, 0x7b, 0x0f, 0xf5, 0xc8, 0xb1, 0x01, 0xb7, - 0x27, 0xe1, 0xea, 0x01, 0xb3, 0x6b, 0xab, 0x86, 0x3a, 0xf1, 0xc3, 0x98, 0x35, 0x8c, 0xe0, 0xd5, 0xf9, 0xdb, 0xf7, - 0x08, 0xae, 0x9c, 0x05, 0xa1, 0xae, 0x3e, 0x6d, 0xf2, 0x3f, 0xbe, 0x7b, 0xf3, 0xfe, 0xbd, 0x6a, 0x60, 0x5a, 0xe6, - 0x58, 0xee, 0x9d, 0x6f, 0xe2, 0x1d, 0x14, 0xa7, 0x76, 0xaf, 0x13, 0x55, 0x23, 0x41, 0xba, 0x38, 0x1b, 0x2a, 0xab, - 0x6c, 0x73, 0x4e, 0xed, 0xf8, 0x97, 0x49, 0xfa, 0xdd, 0x6b, 0x5e, 0x35, 0xf8, 0x68, 0x3b, 0x49, 0x2d, 0x94, 0x2c, - 0xbd, 0xe0, 0xba, 0xa6, 0xd4, 0xbd, 0xab, 0x29, 0x05, 0xf1, 0xb1, 0x82, 0x1f, 0xd7, 0xe1, 0x52, 0x62, 0x47, 0xd8, - 0xdd, 0x6e, 0x70, 0x49, 0x32, 0xdc, 0x27, 0x0c, 0x9a, 0xa7, 0xd5, 0x28, 0x8f, 0xba, 0xa6, 0x98, 0x0b, 0x5e, 0x19, - 0x6c, 0x27, 0x3e, 0x58, 0x5f, 0x33, 0xf9, 0x9e, 0xb1, 0xc8, 0xaa, 0x72, 0xdf, 0x89, 0x41, 0x49, 0x2a, 0xa0, 0x66, - 0x74, 0x37, 0xc3, 0x69, 0xca, 0xca, 0x9d, 0x82, 0x49, 0xb3, 0x39, 0x0e, 0x93, 0x24, 0x5c, 0xf6, 0x1c, 0x7b, 0x75, - 0xa7, 0x2a, 0x7d, 0xa1, 0xec, 0xe0, 0x16, 0xd7, 0xbd, 0xdf, 0xfe, 0x53, 0x42, 0xf3, 0x54, 0x7e, 0x9d, 0xb0, 0xe5, - 0x8a, 0x45, 0x6e, 0xb2, 0x8e, 0x58, 0xaa, 0xfc, 0xf6, 0xbf, 0xaf, 0x4a, 0x82, 0x7d, 0x5f, 0x6e, 0x43, 0x2c, 0xbd, - 0xdc, 0xe4, 0xda, 0x0f, 0x6f, 0x1f, 0xe5, 0xbe, 0x55, 0x3b, 0x2a, 0x2f, 0xbc, 0xf9, 0x22, 0xab, 0x7d, 0x9a, 0x6c, - 0x99, 0x9b, 0x18, 0x3d, 0xdd, 0x07, 0x28, 0xe7, 0xe1, 0x6d, 0xef, 0xb7, 0xff, 0x64, 0x0a, 0x9b, 0x9d, 0xbb, 0xae, - 0x7e, 0xa0, 0xc5, 0x15, 0xad, 0xaf, 0x53, 0x59, 0x62, 0x78, 0x5f, 0x59, 0xe0, 0x4a, 0x21, 0xed, 0xca, 0xea, 0xe5, - 0xdb, 0x96, 0x39, 0x7d, 0xeb, 0xcd, 0x17, 0x9f, 0x3a, 0x29, 0x00, 0xe8, 0xce, 0x59, 0x41, 0xa5, 0xcf, 0x30, 0xad, - 0x51, 0x6f, 0xff, 0x05, 0xfb, 0xc4, 0x79, 0xed, 0x9a, 0xd2, 0xe7, 0x98, 0x0d, 0xd7, 0xdc, 0xbe, 0x1a, 0x8d, 0xb2, - 0xb4, 0xa4, 0x72, 0x7b, 0xf0, 0x0e, 0x3b, 0xad, 0x94, 0x70, 0xf6, 0xa2, 0x67, 0xeb, 0x14, 0xb6, 0x65, 0x0f, 0x80, - 0xa0, 0x9d, 0x73, 0x0d, 0x38, 0x9a, 0xf1, 0x35, 0xb9, 0x2b, 0x55, 0xbe, 0x5d, 0x41, 0xd6, 0x50, 0x8a, 0x29, 0x2d, - 0xb3, 0x5b, 0x43, 0xa3, 0x7e, 0x38, 0xb7, 0x91, 0xbb, 0xa2, 0x4b, 0x02, 0x05, 0x6f, 0x4c, 0x40, 0xe9, 0x52, 0x92, - 0xa2, 0x6f, 0x5c, 0xff, 0x66, 0x3f, 0x81, 0xaa, 0x99, 0x82, 0x21, 0x69, 0xfe, 0xf3, 0x88, 0x37, 0xd2, 0xe5, 0xfd, - 0x69, 0x37, 0xa6, 0x0a, 0x7b, 0xdb, 0x64, 0x5e, 0xfd, 0xe3, 0x6e, 0xf3, 0xea, 0x8b, 0xbd, 0xcc, 0xab, 0x7f, 0xfc, - 0xec, 0xe6, 0xd5, 0x6f, 0x65, 0xf3, 0x6a, 0xd8, 0xc4, 0x6f, 0xd8, 0x5e, 0x46, 0xcf, 0xc2, 0xc8, 0x28, 0xbc, 0x8d, - 0x07, 0x0e, 0x17, 0x7a, 0xe2, 0xc9, 0x82, 0x81, 0x16, 0x89, 0x83, 0xcb, 0x0f, 0xe7, 0x60, 0x9b, 0xdc, 0x6c, 0x7d, - 0xfc, 0xb9, 0x6c, 0x8f, 0xfd, 0x70, 0xae, 0x4a, 0xc1, 0xd2, 0x03, 0x11, 0x2c, 0x1d, 0x1c, 0xc4, 0x7f, 0xb9, 0x73, - 0x5e, 0x5e, 0x3a, 0xfd, 0xb6, 0x03, 0xc1, 0x46, 0x40, 0x31, 0x80, 0x05, 0x76, 0xbf, 0xdd, 0x86, 0x82, 0x5b, 0xa9, - 0xa0, 0x05, 0x05, 0x9e, 0x54, 0xd0, 0x81, 0x82, 0x89, 0x54, 0x70, 0x04, 0x05, 0x53, 0xa9, 0xe0, 0x18, 0x0a, 0x6e, - 0xd4, 0xf4, 0x32, 0xc8, 0x8c, 0xc7, 0x8f, 0xf5, 0xab, 0x42, 0x9e, 0x8c, 0x3c, 0xff, 0x3c, 0xaf, 0x72, 0x6c, 0x88, - 0xa0, 0x8d, 0xe6, 0xa1, 0xce, 0xcd, 0xff, 0x46, 0x5f, 0x8c, 0xc0, 0x9d, 0x1a, 0x94, 0x7a, 0x06, 0xa8, 0x44, 0xa9, - 0x66, 0x5b, 0xbc, 0x56, 0x7b, 0xaa, 0x9e, 0x7d, 0xa0, 0x25, 0xec, 0xfe, 0x7a, 0xe8, 0x4a, 0x23, 0x2a, 0x77, 0x9e, - 0x2f, 0xb2, 0x08, 0x4e, 0xeb, 0x41, 0xee, 0x91, 0xd6, 0x86, 0x38, 0xb6, 0x70, 0x35, 0xfd, 0x1a, 0xf9, 0x03, 0x2b, - 0x09, 0xc1, 0xe1, 0x48, 0x44, 0x2e, 0x12, 0x1f, 0x50, 0x54, 0xfd, 0xd2, 0xbe, 0xea, 0xbb, 0x79, 0x90, 0x29, 0x1e, - 0xef, 0x8c, 0x46, 0xbf, 0xcc, 0xc2, 0x48, 0x91, 0x98, 0xbb, 0x36, 0x12, 0x77, 0xde, 0x5b, 0x18, 0xa4, 0xe3, 0xee, - 0xcd, 0x21, 0x2e, 0xe8, 0xe9, 0xb4, 0xb7, 0x32, 0x6e, 0x17, 0x2c, 0xe8, 0xcd, 0xb8, 0x39, 0x28, 0xac, 0x3f, 0x59, - 0xf1, 0x2c, 0x75, 0x61, 0x94, 0x86, 0x7b, 0x22, 0x7f, 0x4b, 0xa3, 0x34, 0xb3, 0xad, 0x94, 0x5b, 0x4e, 0x69, 0xb2, - 0xfe, 0xfb, 0x73, 0xd8, 0xb9, 0xbc, 0x66, 0xe3, 0xf5, 0x5c, 0x39, 0x0f, 0xe7, 0x3b, 0x6d, 0x5a, 0xe4, 0x57, 0x30, - 0x4a, 0x95, 0x2e, 0xfa, 0x4c, 0xb1, 0xbd, 0xf9, 0xb7, 0xe8, 0x31, 0x2d, 0xd6, 0x4f, 0x60, 0x6c, 0x4a, 0x42, 0x28, - 0x1b, 0xbe, 0x03, 0xd0, 0x96, 0x8c, 0x4a, 0xce, 0x01, 0x7e, 0xd2, 0xf3, 0x85, 0x2b, 0x8d, 0x67, 0xf8, 0x3d, 0x8b, - 0x63, 0x77, 0x2e, 0xea, 0x57, 0xc7, 0x09, 0x3e, 0x36, 0x99, 0xa4, 0x8f, 0x00, 0x04, 0x9d, 0xb1, 0x57, 0xb1, 0x05, - 0x02, 0x53, 0x66, 0x30, 0x7b, 0x83, 0x45, 0xcb, 0x0d, 0x67, 0x3c, 0x0b, 0x96, 0xa7, 0x68, 0xe2, 0x02, 0x48, 0xe4, - 0x86, 0xf9, 0xe5, 0xc2, 0xc4, 0x9d, 0x97, 0x8b, 0x68, 0xad, 0x53, 0x79, 0x6c, 0x99, 0x85, 0x49, 0xa1, 0xf0, 0x53, - 0x4c, 0x26, 0xfc, 0x70, 0xfe, 0xbb, 0xda, 0x4b, 0x6c, 0xb1, 0x73, 0x79, 0x1f, 0x18, 0x41, 0x32, 0xb2, 0x10, 0xc6, - 0x8a, 0x05, 0x20, 0xec, 0x05, 0xc9, 0xc2, 0x44, 0xef, 0x6e, 0xad, 0x15, 0xe8, 0x86, 0x85, 0x6b, 0xbb, 0x29, 0xc7, - 0xb4, 0xe8, 0x45, 0xf3, 0xb1, 0xab, 0x39, 0xad, 0x63, 0x43, 0xfc, 0xb1, 0xec, 0x8e, 0x9e, 0x62, 0x0f, 0xca, 0xd4, - 0xbb, 0xd9, 0xcc, 0xc2, 0x20, 0x31, 0x67, 0xee, 0xd2, 0xf3, 0xef, 0x7b, 0xcb, 0x30, 0x08, 0xe3, 0x95, 0x3b, 0x61, - 0xfd, 0x5c, 0x75, 0xd3, 0xc7, 0x68, 0x49, 0xdc, 0x61, 0xdf, 0xb1, 0x5a, 0x11, 0x5b, 0x52, 0xeb, 0x2c, 0x18, 0xd2, - 0xcc, 0x67, 0x77, 0x29, 0xff, 0x7c, 0xa1, 0x32, 0x55, 0xc5, 0x2d, 0x47, 0x2d, 0x40, 0x0e, 0xe1, 0x91, 0x96, 0x20, - 0xbe, 0x60, 0x9f, 0x33, 0xf3, 0x3d, 0xab, 0xd5, 0x89, 0xd8, 0x52, 0xb1, 0x3a, 0x8d, 0x9d, 0x47, 0xe1, 0xed, 0x10, - 0x46, 0x8b, 0x8d, 0xcd, 0x98, 0xf9, 0x33, 0x7c, 0x63, 0xa2, 0x73, 0xa7, 0xe8, 0xc7, 0x44, 0x95, 0x0f, 0xf4, 0xc6, - 0x96, 0x7d, 0x78, 0xdd, 0x6b, 0x29, 0x76, 0x7f, 0xe9, 0x05, 0x26, 0x4d, 0xe7, 0xd8, 0x5e, 0x49, 0x7d, 0xc9, 0xf0, - 0xd3, 0x37, 0x58, 0xdd, 0x51, 0xec, 0x3e, 0x88, 0xf6, 0x33, 0x3f, 0xbc, 0xed, 0x2d, 0xbc, 0xe9, 0x94, 0x05, 0x7d, - 0x1c, 0x73, 0x56, 0xc8, 0x7c, 0xdf, 0x5b, 0xc5, 0x5e, 0xdc, 0x5f, 0xba, 0x77, 0xbc, 0xd7, 0xc3, 0xa6, 0x5e, 0xdb, - 0xbc, 0xd7, 0xf6, 0xde, 0xbd, 0x4a, 0xdd, 0x80, 0x23, 0x29, 0xf5, 0xc3, 0x87, 0xd6, 0x51, 0xec, 0xd2, 0x3c, 0xf7, - 0xee, 0x75, 0x15, 0xb1, 0xcd, 0xd2, 0x8d, 0xe6, 0x5e, 0xd0, 0xb3, 0x53, 0xeb, 0x66, 0x43, 0x1b, 0xe3, 0x71, 0xb7, - 0xdb, 0x4d, 0xad, 0xa9, 0x78, 0xb2, 0xa7, 0xd3, 0xd4, 0x9a, 0x88, 0xa7, 0xd9, 0xcc, 0xb6, 0x67, 0xb3, 0xd4, 0xf2, - 0x44, 0x41, 0xbb, 0x35, 0x99, 0xb6, 0x5b, 0xa9, 0x75, 0x2b, 0xd5, 0x48, 0x2d, 0xc6, 0x9f, 0x22, 0x36, 0xed, 0xe3, - 0x46, 0xe2, 0x76, 0xe9, 0xc7, 0xb6, 0x9d, 0x22, 0x06, 0xb8, 0x2c, 0xe0, 0x26, 0xd4, 0x2a, 0x5e, 0x6d, 0xf6, 0xae, - 0xa9, 0xe4, 0x9f, 0x9b, 0x4c, 0x6a, 0xeb, 0x4d, 0xdd, 0xe8, 0xc3, 0x95, 0x22, 0xcd, 0xc2, 0x75, 0xa9, 0xda, 0x46, - 0x80, 0xc1, 0xbc, 0xeb, 0x41, 0xd4, 0xcc, 0xfe, 0x38, 0x8c, 0xe0, 0xcc, 0x46, 0xee, 0xd4, 0x5b, 0xc7, 0x3d, 0xa7, - 0xb5, 0xba, 0x13, 0x45, 0x7c, 0xaf, 0xe7, 0x05, 0x78, 0xf6, 0x7a, 0x71, 0xe8, 0x7b, 0x53, 0x51, 0xd4, 0x74, 0x96, - 0x9c, 0x96, 0xde, 0xc7, 0x98, 0x31, 0x1e, 0x46, 0x3e, 0x72, 0x7d, 0x5f, 0xb1, 0xda, 0xb1, 0xc2, 0xdc, 0x18, 0x6f, - 0x32, 0x14, 0x3b, 0x26, 0xb8, 0x60, 0x7c, 0x18, 0xe7, 0x70, 0x75, 0x97, 0xed, 0x79, 0xe7, 0x68, 0x75, 0x97, 0x7e, - 0xb5, 0x64, 0x53, 0xcf, 0x55, 0xb4, 0x7c, 0x37, 0x39, 0x36, 0xdc, 0x76, 0xe8, 0x9b, 0x86, 0x6d, 0x2a, 0x8e, 0x05, - 0x44, 0x17, 0x7e, 0xe4, 0x2d, 0x57, 0x61, 0x94, 0xb8, 0x41, 0x92, 0xa6, 0xa3, 0xab, 0x34, 0xed, 0x5f, 0x78, 0xda, - 0xe5, 0x3f, 0x34, 0xa2, 0x85, 0x74, 0x3b, 0x98, 0xea, 0x57, 0xc6, 0x1b, 0x26, 0x5b, 0x32, 0x01, 0x19, 0x43, 0x2b, - 0x26, 0xb9, 0x32, 0xd1, 0xdb, 0x6a, 0x65, 0x02, 0x72, 0x56, 0x9d, 0x0c, 0xa3, 0x8a, 0x55, 0x90, 0x02, 0x41, 0x85, - 0x37, 0x6c, 0x70, 0x21, 0x99, 0x45, 0x01, 0xd3, 0x83, 0x95, 0xc9, 0xb5, 0xef, 0x49, 0x13, 0xef, 0xf9, 0xf5, 0x6e, - 0xde, 0xf3, 0x9f, 0xc9, 0x3e, 0xbc, 0xe7, 0xd7, 0x9f, 0x9d, 0xf7, 0x7c, 0x52, 0x75, 0xed, 0x3b, 0x0b, 0x07, 0x6a, - 0x76, 0x97, 0x05, 0xa4, 0x29, 0xa2, 0xa0, 0x79, 0x67, 0xc9, 0x7f, 0xeb, 0x8a, 0x27, 0x7a, 0xa3, 0x34, 0xb0, 0x44, - 0xb9, 0x81, 0x81, 0x7f, 0x1b, 0x0c, 0xfe, 0x1e, 0xc9, 0xcf, 0xb3, 0xd9, 0xe0, 0x75, 0x28, 0x15, 0x64, 0x4f, 0xdc, - 0xcc, 0xa7, 0x10, 0xe0, 0x88, 0xde, 0x64, 0x86, 0x58, 0x90, 0x02, 0x0a, 0xe2, 0xa3, 0x90, 0xb1, 0xfd, 0x34, 0x33, - 0x87, 0xec, 0x17, 0x87, 0xa0, 0x65, 0x06, 0xc6, 0xc2, 0x0b, 0xb6, 0xa2, 0xb4, 0x9e, 0xb3, 0x84, 0x87, 0xad, 0x78, - 0x79, 0x7f, 0x36, 0xd5, 0xce, 0x42, 0x3d, 0xf5, 0xe2, 0xb7, 0x65, 0x1f, 0x54, 0x21, 0x82, 0xc8, 0xd3, 0x49, 0xb9, - 0x49, 0xa3, 0x14, 0x6a, 0x06, 0x5f, 0x53, 0xf3, 0xd3, 0xc2, 0x4c, 0x7b, 0x72, 0x43, 0x9e, 0x6b, 0xb2, 0x42, 0x8c, - 0xb9, 0x4b, 0xdf, 0x86, 0x73, 0x79, 0x98, 0x3e, 0x13, 0x43, 0x77, 0x4c, 0xa9, 0xb9, 0x37, 0x4d, 0x53, 0xbd, 0x2f, - 0x00, 0x21, 0x11, 0x5a, 0xb6, 0x8b, 0x89, 0x8b, 0x73, 0x81, 0x96, 0xdf, 0x45, 0xd3, 0x45, 0xf3, 0x19, 0x98, 0x6e, - 0xf0, 0x6b, 0x69, 0x0e, 0x33, 0x55, 0x21, 0xf0, 0x91, 0x49, 0x8f, 0x34, 0x21, 0xb0, 0x35, 0x90, 0x0d, 0xe1, 0x0a, - 0x0b, 0x52, 0x35, 0x2a, 0x26, 0xe0, 0xa0, 0xed, 0x09, 0x04, 0xda, 0x11, 0xda, 0x2e, 0x42, 0x3b, 0xbc, 0x0e, 0x3e, - 0xa4, 0x6a, 0xc6, 0xfb, 0xe1, 0xf6, 0x1b, 0x9e, 0x1c, 0x40, 0x83, 0x61, 0x49, 0x93, 0xb5, 0xc3, 0x64, 0x16, 0x58, - 0x89, 0xf8, 0xd6, 0xb0, 0xe2, 0x5b, 0xe5, 0xd9, 0x46, 0x04, 0xa9, 0x4a, 0xdc, 0x95, 0x09, 0xea, 0x13, 0xc4, 0xbd, - 0x1c, 0xe3, 0x49, 0xf1, 0xb0, 0xfa, 0xeb, 0x18, 0x70, 0x23, 0x4a, 0xf2, 0x88, 0x7f, 0xfa, 0x93, 0x75, 0x14, 0x87, - 0x51, 0x6f, 0x15, 0x7a, 0x41, 0xc2, 0xa2, 0x14, 0x41, 0x75, 0x89, 0xf0, 0x11, 0xe0, 0xb9, 0xda, 0x84, 0x2b, 0x77, - 0xe2, 0x25, 0xf7, 0x3d, 0x9b, 0xb3, 0x14, 0x76, 0x9f, 0x73, 0x07, 0x76, 0x6d, 0xfd, 0x1e, 0x87, 0xe6, 0x73, 0x64, - 0xfc, 0xa2, 0x2a, 0x3b, 0x23, 0x6f, 0xf3, 0xbe, 0xf4, 0x96, 0xc2, 0x74, 0x01, 0xfb, 0xe1, 0x46, 0xe6, 0x1c, 0xb0, - 0x3c, 0x2c, 0xb5, 0x3d, 0x65, 0x73, 0x03, 0xb1, 0x36, 0xdc, 0x00, 0x89, 0x3f, 0x56, 0x47, 0x57, 0xec, 0xfa, 0x62, - 0xe0, 0x78, 0xf4, 0x7d, 0x46, 0xd6, 0x73, 0x21, 0xa9, 0xa5, 0xb1, 0x4f, 0xcd, 0x31, 0x9b, 0x85, 0x11, 0xa3, 0x90, - 0xee, 0x4e, 0x77, 0x75, 0xb7, 0x7f, 0xf7, 0xdb, 0xa7, 0x5f, 0xdf, 0x4f, 0x10, 0x26, 0x9a, 0xe8, 0x4c, 0xdf, 0xd1, - 0x5b, 0x95, 0x9e, 0x01, 0x6b, 0x48, 0x90, 0x9f, 0x90, 0xc3, 0x49, 0x4f, 0x55, 0xfb, 0xb5, 0x91, 0x33, 0x57, 0x21, - 0xa7, 0x79, 0x11, 0xf3, 0xdd, 0xc4, 0xbb, 0x11, 0x3c, 0x63, 0xfb, 0x68, 0x75, 0x27, 0xd6, 0x18, 0x09, 0xde, 0x03, - 0x16, 0xa9, 0x34, 0x14, 0xb1, 0x48, 0xe5, 0x62, 0x5c, 0xa4, 0x7e, 0x65, 0x36, 0x22, 0x98, 0x54, 0x89, 0xd2, 0x77, - 0x56, 0x77, 0x32, 0x89, 0xce, 0x9b, 0x65, 0x94, 0xba, 0x1c, 0x05, 0x74, 0xe9, 0x4d, 0xa7, 0x3e, 0x4b, 0x0b, 0x0b, - 0x5d, 0x5c, 0x4b, 0x09, 0x38, 0x19, 0x1c, 0xdc, 0x71, 0x1c, 0xfa, 0xeb, 0x84, 0xd5, 0x83, 0x8b, 0x80, 0xd3, 0xb2, - 0x73, 0xe0, 0xe0, 0xef, 0xe2, 0x58, 0x3b, 0xc0, 0x6e, 0xc3, 0x36, 0xb1, 0xfb, 0x10, 0xf4, 0xdf, 0x6c, 0x17, 0x87, - 0x0e, 0xaf, 0xb2, 0x41, 0x1b, 0x35, 0x13, 0x31, 0x80, 0x2c, 0x11, 0xf6, 0x56, 0x2c, 0x87, 0x97, 0x65, 0x81, 0xcf, - 0xb3, 0xa2, 0xb4, 0x38, 0x99, 0xdf, 0xe7, 0x8c, 0xbd, 0xa8, 0x3f, 0x63, 0x2f, 0xc4, 0x19, 0xdb, 0xbe, 0x33, 0x1f, - 0xcf, 0x1c, 0xf8, 0xaf, 0x9f, 0x4f, 0xa8, 0x67, 0x2b, 0xed, 0xd5, 0x9d, 0xe2, 0xac, 0xee, 0x14, 0xb3, 0xb5, 0xba, - 0x53, 0xb0, 0x6b, 0xb4, 0x3c, 0x32, 0xac, 0x96, 0x6e, 0xd8, 0x0a, 0x14, 0xc2, 0x1f, 0xbb, 0xf0, 0xca, 0x39, 0x84, - 0x77, 0xd0, 0xaa, 0x53, 0x7d, 0xd7, 0xda, 0x7e, 0xd4, 0xe9, 0x2c, 0x09, 0xa4, 0xad, 0x5b, 0x89, 0x3b, 0x1e, 0xb3, - 0x69, 0x6f, 0x16, 0x4e, 0xd6, 0xf1, 0xbf, 0xf9, 0xf8, 0x39, 0x10, 0xb7, 0x22, 0x82, 0x52, 0x3f, 0xa2, 0x29, 0x68, - 0xf7, 0x6e, 0x98, 0xe8, 0x61, 0x93, 0xad, 0x53, 0x8f, 0x32, 0x14, 0xb4, 0xac, 0xc3, 0x9a, 0x4d, 0x5e, 0x0f, 0xe8, - 0xdf, 0x6d, 0x95, 0x9a, 0x51, 0xcc, 0x27, 0x80, 0x65, 0x2b, 0x38, 0x1e, 0x0e, 0x0d, 0xbe, 0x9a, 0x76, 0xb7, 0x7e, - 0xb8, 0x97, 0xe2, 0x4b, 0x57, 0x82, 0xa8, 0x70, 0xba, 0xc5, 0xdd, 0xa0, 0xb6, 0xf7, 0xda, 0xb4, 0x47, 0x2a, 0xbd, - 0x6e, 0x21, 0x08, 0x79, 0xdd, 0x3d, 0xb1, 0xfc, 0xe3, 0x17, 0x87, 0xf0, 0x1f, 0x71, 0xf5, 0xff, 0x4c, 0xea, 0x18, - 0xf5, 0xb3, 0xa4, 0xc0, 0xa8, 0x13, 0xab, 0x84, 0x8c, 0xf8, 0xfe, 0xf5, 0x67, 0xb3, 0x87, 0x35, 0xd8, 0xbb, 0x36, - 0x19, 0xed, 0x95, 0x6b, 0xbf, 0x0c, 0x43, 0xc8, 0x9e, 0x5d, 0xad, 0x2e, 0xc0, 0x43, 0x1e, 0x18, 0xc9, 0x00, 0x1a, - 0x09, 0x39, 0x82, 0xec, 0x45, 0x54, 0x6c, 0x43, 0xa2, 0xc4, 0x9b, 0x26, 0x51, 0xe2, 0xf5, 0x6e, 0x51, 0xe2, 0xbb, - 0xbd, 0x44, 0x89, 0xd7, 0x9f, 0x5d, 0x94, 0x78, 0x53, 0x15, 0x25, 0x2e, 0x42, 0x61, 0xa9, 0x6d, 0x9c, 0xad, 0xf9, - 0xcf, 0x9f, 0xe9, 0x2a, 0xf6, 0x3c, 0x1c, 0x74, 0x6c, 0xca, 0x3a, 0x70, 0xf1, 0x5f, 0x0b, 0x16, 0xb8, 0x11, 0xdf, - 0xa1, 0xe1, 0x62, 0x2e, 0x5a, 0x70, 0xcc, 0x8e, 0xdf, 0x91, 0x8a, 0xfd, 0x30, 0x98, 0xff, 0x08, 0x57, 0xf1, 0xa0, - 0x0e, 0x8c, 0xa4, 0x17, 0x5e, 0xfc, 0x63, 0xb8, 0x5a, 0xaf, 0xce, 0xa0, 0xaf, 0x9f, 0xbd, 0xd8, 0x1b, 0xfb, 0x2c, - 0x8b, 0x06, 0x42, 0x86, 0x96, 0x5c, 0xb7, 0x0e, 0xb6, 0xcd, 0xe2, 0xa7, 0x7b, 0x27, 0x7e, 0xa2, 0xf5, 0x33, 0xff, - 0x4d, 0x16, 0x9c, 0x6a, 0xbd, 0x20, 0x02, 0x61, 0xf3, 0x4a, 0x83, 0x7e, 0xb8, 0x30, 0x72, 0x11, 0xea, 0x35, 0xb3, - 0x14, 0x96, 0x35, 0x8d, 0xfd, 0xb0, 0x8a, 0x50, 0xb3, 0xd6, 0x8d, 0x2c, 0x0a, 0x66, 0x55, 0x9d, 0xbf, 0x0c, 0xd7, - 0x31, 0x9b, 0x86, 0xb7, 0x81, 0x6a, 0x04, 0xdc, 0x1c, 0x94, 0x12, 0x09, 0x66, 0x6d, 0x30, 0x7f, 0xf3, 0x7b, 0x64, - 0x94, 0x21, 0x62, 0x02, 0xa4, 0x0f, 0x5f, 0xaf, 0x4c, 0x32, 0x30, 0x30, 0x71, 0x8a, 0x6a, 0x96, 0x68, 0xf0, 0x91, - 0xa6, 0x85, 0x83, 0x87, 0xb5, 0x14, 0x46, 0x41, 0xa1, 0xc5, 0xb5, 0xc2, 0xb1, 0x16, 0x08, 0xe5, 0xa2, 0x08, 0x45, - 0x55, 0xb3, 0x70, 0xfc, 0x0d, 0x85, 0xfa, 0xc8, 0xdf, 0x42, 0x64, 0x88, 0x74, 0xcd, 0xd7, 0x83, 0x07, 0x66, 0xa2, - 0xc7, 0x57, 0x12, 0x18, 0xdf, 0xde, 0xb0, 0xc8, 0x77, 0xef, 0x35, 0x3d, 0x0d, 0x83, 0xef, 0x01, 0x00, 0xaf, 0xc3, - 0xdb, 0x40, 0xae, 0x80, 0xf9, 0xd2, 0x6a, 0xf6, 0x52, 0x6d, 0x08, 0x31, 0x70, 0xa7, 0x92, 0x46, 0x00, 0x99, 0xea, - 0xe7, 0xec, 0xef, 0x06, 0xfd, 0xfb, 0x0f, 0x3d, 0x35, 0xce, 0xc3, 0xec, 0x43, 0x3f, 0xad, 0xf6, 0xf8, 0xcc, 0xd3, - 0xa7, 0x8f, 0x9a, 0xa7, 0xad, 0x4d, 0x7c, 0xe6, 0x8a, 0xfc, 0xf3, 0x5a, 0x4d, 0x6b, 0xbd, 0xf1, 0x14, 0xc0, 0x28, - 0x2e, 0xc2, 0xf5, 0x64, 0x81, 0x26, 0xd5, 0x9f, 0x6f, 0xbe, 0x09, 0xf4, 0x89, 0x89, 0xc2, 0xb3, 0xa9, 0x97, 0x8a, - 0x72, 0x28, 0xe0, 0xf7, 0xdf, 0x40, 0x0c, 0xec, 0x3f, 0x11, 0x0c, 0xd5, 0x5d, 0x93, 0xb9, 0x5b, 0x3f, 0x68, 0xf3, - 0xf6, 0x21, 0x9f, 0x35, 0x8f, 0x2e, 0x25, 0x2e, 0xe9, 0xea, 0x91, 0x4c, 0x5a, 0x06, 0x9a, 0x1c, 0xc9, 0xb5, 0x29, - 0x48, 0xad, 0xf8, 0x0a, 0xb3, 0x48, 0x4c, 0xe7, 0x2e, 0x2d, 0x06, 0xe3, 0xd8, 0xaa, 0x84, 0x64, 0xb8, 0xa1, 0x0b, - 0x43, 0xf4, 0x55, 0x7e, 0xb7, 0xf4, 0x02, 0x03, 0x13, 0xb1, 0x54, 0xdf, 0xb8, 0x77, 0x90, 0x8a, 0x00, 0x90, 0x5b, - 0xf9, 0x15, 0x14, 0x1a, 0xb2, 0x23, 0x27, 0x64, 0x5b, 0x54, 0x6b, 0x21, 0x21, 0x6e, 0x03, 0x47, 0x5f, 0x28, 0x8a, - 0xa2, 0x64, 0x62, 0x84, 0x92, 0xc9, 0x11, 0x58, 0x8e, 0xe2, 0x00, 0xdc, 0x96, 0xa4, 0xab, 0x3b, 0x2a, 0x01, 0xc9, - 0x00, 0xaf, 0xb6, 0x45, 0x01, 0x8f, 0xb6, 0xdb, 0xb1, 0x45, 0x81, 0x10, 0xe8, 0x21, 0x52, 0xaa, 0x1b, 0x41, 0x50, - 0xfe, 0x9e, 0x82, 0x02, 0x3b, 0xbe, 0xe5, 0x9a, 0x60, 0xc5, 0xa6, 0xc7, 0x51, 0x9f, 0xd5, 0x87, 0x65, 0x0d, 0x24, - 0x2c, 0x08, 0xb7, 0x0e, 0xa5, 0x2c, 0x0b, 0x06, 0xab, 0xc1, 0x8d, 0x28, 0x17, 0xdd, 0x25, 0x4b, 0x16, 0xac, 0x55, - 0x4c, 0xcb, 0x88, 0x61, 0x72, 0xa1, 0xce, 0x6b, 0x62, 0xb6, 0x00, 0xdb, 0xd4, 0xb7, 0x5c, 0x10, 0x2d, 0x8c, 0x39, - 0x4a, 0x75, 0x8d, 0x09, 0xf7, 0x4d, 0x8c, 0x39, 0x6e, 0x2b, 0x53, 0x08, 0xbe, 0xa4, 0x61, 0x11, 0x9b, 0x73, 0x6f, - 0x64, 0xe4, 0x14, 0x28, 0x42, 0x15, 0x57, 0x17, 0x09, 0xb0, 0x6b, 0x6e, 0x79, 0xd1, 0xb2, 0x1b, 0x19, 0xb7, 0xa4, - 0x28, 0x8a, 0xf4, 0x6a, 0x37, 0x7c, 0x9c, 0x10, 0x1b, 0xb0, 0xb1, 0x9f, 0x49, 0xa5, 0x9f, 0x86, 0x49, 0x7f, 0x60, - 0xf7, 0x44, 0x48, 0x08, 0x54, 0x1f, 0xd8, 0x3d, 0xdc, 0xdb, 0xbf, 0x01, 0x6d, 0x8a, 0xba, 0x05, 0x5d, 0x1b, 0x90, - 0x6d, 0x67, 0x02, 0xf1, 0x22, 0xb7, 0x1c, 0x20, 0x3b, 0xdd, 0x82, 0xc5, 0x11, 0xc4, 0x81, 0x11, 0xf7, 0xc5, 0x21, - 0xe6, 0xce, 0x24, 0x5a, 0x2d, 0x8c, 0xcd, 0x9a, 0xa3, 0xa1, 0x3f, 0x73, 0x6c, 0xfb, 0xa0, 0x52, 0x1f, 0x14, 0xd9, - 0x75, 0xb5, 0x75, 0x23, 0x19, 0x38, 0xb6, 0xe9, 0x3d, 0xb3, 0x5a, 0xfd, 0x0a, 0x8d, 0x96, 0xc2, 0x39, 0x8f, 0x50, - 0xfd, 0x35, 0x7c, 0xb2, 0xd1, 0x2a, 0x07, 0x52, 0x2f, 0x3b, 0x67, 0xe0, 0xd8, 0x52, 0xae, 0xff, 0x1a, 0x55, 0x49, - 0x3f, 0x05, 0x93, 0xa6, 0xd4, 0x62, 0x23, 0x48, 0x48, 0xa0, 0xc1, 0x31, 0xfa, 0x8b, 0xf2, 0x5c, 0xd1, 0xe8, 0xf8, - 0xe8, 0xfa, 0xa8, 0x2f, 0x30, 0x8a, 0xf0, 0x5e, 0x94, 0x3b, 0x28, 0x7d, 0x31, 0x2e, 0x63, 0x38, 0x1e, 0xfa, 0x9c, - 0xe5, 0x37, 0x7a, 0x5b, 0xb9, 0x05, 0xec, 0xbf, 0x81, 0x7c, 0x5a, 0x63, 0x88, 0xaf, 0x01, 0x35, 0x20, 0x7d, 0xc9, - 0xce, 0x0e, 0x21, 0x6c, 0x92, 0xdc, 0x5d, 0x91, 0x48, 0xee, 0xdf, 0x19, 0x12, 0x1d, 0xbc, 0x43, 0xcb, 0xfa, 0xab, - 0x27, 0x77, 0x0f, 0xec, 0x92, 0x05, 0xd3, 0x62, 0x87, 0x25, 0xfa, 0xb5, 0x7f, 0x77, 0x05, 0x8c, 0x02, 0x79, 0x7d, - 0xc2, 0x1a, 0x8c, 0x92, 0x86, 0x01, 0x6e, 0x7e, 0x3a, 0x6e, 0xde, 0x5e, 0x5c, 0x0c, 0x36, 0xa0, 0xa0, 0x9c, 0x59, - 0x33, 0x49, 0x29, 0x0e, 0xc9, 0x23, 0xd0, 0xb9, 0x59, 0x13, 0x8c, 0x68, 0xe3, 0x4e, 0x4c, 0x84, 0x25, 0x69, 0xde, - 0xc6, 0xe3, 0xe1, 0xa0, 0xf7, 0xd5, 0x5a, 0x7b, 0xbb, 0xb5, 0xd6, 0xc9, 0x2e, 0xad, 0x35, 0x39, 0xee, 0x91, 0xf9, - 0x53, 0xe6, 0xc0, 0x28, 0x98, 0x73, 0xd9, 0x05, 0xb4, 0xa0, 0xea, 0x46, 0x3f, 0x3f, 0xd1, 0xaa, 0xd2, 0x1b, 0xd9, - 0x86, 0xa2, 0xfa, 0x5b, 0x12, 0x50, 0xc4, 0x85, 0xba, 0xac, 0x1b, 0xbf, 0xc8, 0x75, 0xe3, 0x24, 0xd5, 0xe4, 0x2e, - 0x5b, 0x82, 0xfb, 0x97, 0xdc, 0x21, 0x33, 0xe9, 0x20, 0x77, 0x8b, 0xcc, 0x47, 0x2a, 0x39, 0xfa, 0xe5, 0x82, 0x86, - 0xe4, 0x3e, 0x2a, 0xa4, 0x8c, 0xa2, 0x17, 0x69, 0xb1, 0x6a, 0xee, 0xe7, 0x97, 0x97, 0x83, 0xd6, 0x1d, 0x87, 0x9c, - 0x15, 0xcb, 0xdb, 0xa6, 0xe8, 0xe8, 0x25, 0xbf, 0x96, 0x36, 0x49, 0xe6, 0x91, 0x45, 0x00, 0x16, 0x6a, 0xfa, 0xd2, - 0xbd, 0x76, 0x66, 0x03, 0x81, 0x83, 0xac, 0x71, 0x20, 0xdd, 0xad, 0x9d, 0xa7, 0x94, 0x45, 0xf9, 0xd5, 0xb5, 0x83, - 0xd4, 0x9d, 0x6e, 0x82, 0x65, 0x7d, 0x04, 0xc2, 0xfa, 0x4a, 0xd2, 0x20, 0xf4, 0x6c, 0xc5, 0xee, 0xd7, 0x30, 0x00, - 0x48, 0xff, 0xcb, 0xcf, 0x9c, 0x15, 0x00, 0x4d, 0xa4, 0x62, 0xcb, 0x77, 0xfe, 0x78, 0x88, 0x4d, 0x32, 0x3f, 0xc3, - 0xaa, 0xd5, 0x6f, 0x92, 0xbe, 0x67, 0xc3, 0xdd, 0xb5, 0x8a, 0xea, 0x7c, 0x5e, 0xa3, 0x27, 0xc6, 0xc1, 0x77, 0x59, - 0xb4, 0x0e, 0x30, 0x13, 0x8d, 0x99, 0x44, 0xee, 0xe4, 0xc3, 0x46, 0xfa, 0x1e, 0x57, 0x89, 0x82, 0xba, 0xb8, 0x78, - 0xa9, 0xd0, 0x77, 0x31, 0x70, 0x33, 0xeb, 0x59, 0xad, 0x58, 0x52, 0xd4, 0xf4, 0x1e, 0xdb, 0x6d, 0xf7, 0xc5, 0xec, - 0xb0, 0xa4, 0x3f, 0x6d, 0x75, 0x8a, 0xda, 0xf5, 0x6c, 0x1c, 0xcb, 0xf0, 0x57, 0xee, 0xd8, 0xfa, 0xc7, 0x7f, 0x3a, - 0xe6, 0xdf, 0x2c, 0xad, 0xd1, 0xa7, 0x0c, 0x01, 0xda, 0x17, 0x2e, 0xa6, 0xe5, 0x6b, 0x9a, 0x4a, 0x49, 0xd3, 0xb0, - 0x66, 0x9e, 0xef, 0x9b, 0x3e, 0xb8, 0x17, 0x6d, 0x3e, 0x69, 0x7a, 0xd8, 0xcf, 0x1a, 0x52, 0x06, 0x7c, 0x42, 0x3f, - 0xc5, 0x9d, 0x92, 0x2c, 0xd6, 0xcb, 0xf1, 0x46, 0x56, 0x94, 0x4b, 0xfa, 0xf3, 0xaa, 0xce, 0x5c, 0xfe, 0xec, 0x6c, - 0x36, 0x2b, 0x6a, 0x8d, 0x6d, 0xe5, 0x10, 0x35, 0xbf, 0x8f, 0x6d, 0xdb, 0x2e, 0xc3, 0xb7, 0xe9, 0xa0, 0xd0, 0xc1, - 0x30, 0x51, 0x09, 0xdf, 0xdd, 0xbd, 0xa7, 0xfe, 0xa0, 0xd1, 0x52, 0x57, 0x4d, 0xe7, 0x91, 0xb6, 0xda, 0xff, 0x8b, - 0xa1, 0x20, 0x6a, 0xd8, 0x75, 0xfc, 0xab, 0x7b, 0x65, 0x4b, 0x4f, 0xe5, 0x03, 0xfc, 0xb0, 0xc6, 0x3b, 0xf6, 0xfa, - 0x1e, 0x4d, 0x9b, 0xb6, 0x77, 0x6a, 0xe5, 0x64, 0xb7, 0x60, 0xb3, 0xd4, 0x27, 0x4b, 0x25, 0x2f, 0x61, 0xcb, 0xb8, - 0x37, 0x61, 0x78, 0x41, 0x6a, 0x49, 0xd4, 0x16, 0xad, 0x7a, 0xcc, 0x39, 0xd8, 0x71, 0x39, 0x02, 0x0f, 0xdb, 0x0a, - 0x5e, 0x56, 0x55, 0x6e, 0xd6, 0xc4, 0x47, 0x90, 0x8a, 0x6d, 0xaa, 0x17, 0x4e, 0xb8, 0x4d, 0x3b, 0xf6, 0x5f, 0x0a, - 0xf5, 0x14, 0xe0, 0x4e, 0x37, 0xc2, 0xda, 0x84, 0x2e, 0x4f, 0xf0, 0xef, 0xec, 0x72, 0xee, 0xc5, 0xea, 0xae, 0x68, - 0xdc, 0xd5, 0x85, 0xeb, 0xa6, 0x9c, 0x94, 0xd1, 0xa8, 0xeb, 0x50, 0x5f, 0x66, 0x02, 0x34, 0x93, 0xad, 0x5b, 0xc0, - 0x82, 0xa6, 0x90, 0x20, 0xaf, 0xe6, 0x6e, 0x0c, 0xc5, 0x59, 0xd8, 0x79, 0xb9, 0x7e, 0x3f, 0x4f, 0xef, 0x0c, 0x73, - 0x30, 0x9e, 0x77, 0xf1, 0x72, 0xaf, 0xb0, 0x55, 0xd1, 0x54, 0x06, 0xf7, 0x80, 0x90, 0x48, 0x95, 0x75, 0xe4, 0x9b, - 0x94, 0x3d, 0x4e, 0xd3, 0x37, 0xd5, 0x79, 0x37, 0x77, 0xef, 0x74, 0xe0, 0x5e, 0xa3, 0x0a, 0xaa, 0xbd, 0xae, 0xf6, - 0xca, 0x77, 0xd8, 0x62, 0x9c, 0xb0, 0x02, 0xe0, 0x8a, 0xa2, 0xa0, 0xd1, 0x90, 0x52, 0xc2, 0x7d, 0x34, 0xe9, 0xec, - 0xad, 0x8c, 0xac, 0xc5, 0x3c, 0xb1, 0xbb, 0xfa, 0x2a, 0xd4, 0xb7, 0xb8, 0x19, 0x04, 0xd8, 0x71, 0xec, 0x84, 0xcf, - 0x26, 0xec, 0x18, 0x19, 0x5d, 0x39, 0xb8, 0x83, 0xf0, 0x94, 0x9a, 0x14, 0xdf, 0x96, 0x4e, 0x29, 0xde, 0x25, 0x7c, - 0x57, 0xab, 0xbc, 0xbf, 0x28, 0x68, 0xe3, 0xb9, 0x3f, 0x50, 0x4b, 0xdf, 0xab, 0xf6, 0xd2, 0x0b, 0xf6, 0xaf, 0xeb, - 0xde, 0xed, 0x5d, 0x17, 0x98, 0xc3, 0xbd, 0x2b, 0x03, 0x77, 0x49, 0x56, 0x4a, 0xc9, 0xe0, 0x3b, 0xe9, 0xf2, 0x40, - 0x8e, 0x65, 0xa1, 0x62, 0x2b, 0x92, 0xe8, 0x2f, 0xd6, 0x83, 0xd1, 0xc9, 0xe9, 0xdd, 0xd2, 0x57, 0x6e, 0x58, 0x04, - 0x99, 0x34, 0x07, 0xaa, 0x63, 0xd9, 0xaa, 0x82, 0x91, 0x19, 0xbc, 0x60, 0x3e, 0x50, 0x7f, 0xba, 0xf8, 0xc6, 0xec, - 0xaa, 0xa7, 0x60, 0x8e, 0x71, 0x33, 0x47, 0x16, 0xf7, 0xdc, 0xbd, 0x67, 0xd1, 0x75, 0x4b, 0x55, 0x30, 0x61, 0x26, - 0x31, 0xb7, 0x58, 0xa6, 0xb4, 0xd4, 0x3d, 0xf2, 0xb2, 0x29, 0x22, 0xb5, 0xb2, 0x0a, 0x88, 0xd5, 0x69, 0x75, 0x15, - 0xa7, 0x75, 0x68, 0x1d, 0x75, 0xd5, 0xe1, 0x17, 0x8a, 0x72, 0x32, 0x65, 0xb3, 0x78, 0x88, 0xea, 0x98, 0x13, 0xe4, - 0x07, 0xe9, 0xb7, 0xa2, 0x58, 0x13, 0x3f, 0x36, 0x1d, 0x65, 0xc3, 0x1f, 0x15, 0x05, 0x90, 0x51, 0x4f, 0x79, 0x3c, - 0x6b, 0xcd, 0x0e, 0x67, 0x2f, 0xfa, 0xbc, 0x38, 0xfd, 0xa2, 0x50, 0xdd, 0xa0, 0x7f, 0x5b, 0x52, 0xb3, 0x38, 0x89, - 0xc2, 0x0f, 0x8c, 0xf3, 0x92, 0x4a, 0xa6, 0x28, 0x2a, 0x37, 0x6d, 0x55, 0xbf, 0xe4, 0x74, 0xc7, 0x93, 0x59, 0x2b, - 0xaf, 0x8e, 0x63, 0x3c, 0xc8, 0x06, 0x79, 0x72, 0x20, 0x86, 0x7e, 0x22, 0x83, 0xc9, 0x31, 0xeb, 0x00, 0xe5, 0xa8, - 0x7c, 0x8e, 0x73, 0x31, 0xbf, 0x13, 0x08, 0x7b, 0x9e, 0x7b, 0x70, 0xc4, 0xd8, 0x6c, 0xa0, 0x7e, 0xef, 0xb4, 0xba, - 0x86, 0xe3, 0x1c, 0x59, 0x47, 0xdd, 0x89, 0x6d, 0x1c, 0x5a, 0x87, 0x66, 0xdb, 0x3a, 0x32, 0xba, 0x66, 0xd7, 0xe8, - 0x7e, 0xdb, 0x9d, 0x98, 0x87, 0xd6, 0xa1, 0x61, 0x9b, 0x5d, 0x28, 0x34, 0xbb, 0x66, 0xf7, 0xc6, 0x3c, 0xec, 0x4e, - 0x6c, 0x2c, 0x6d, 0x59, 0x9d, 0x8e, 0xe9, 0xd8, 0x56, 0xa7, 0x63, 0x74, 0xac, 0xa3, 0x23, 0xd3, 0x69, 0x5b, 0x47, - 0x47, 0xe7, 0x9d, 0xae, 0xd5, 0x86, 0x77, 0xed, 0xf6, 0xa4, 0x6d, 0x39, 0x8e, 0x09, 0x7f, 0x19, 0x5d, 0xab, 0x45, - 0x3f, 0x1c, 0xc7, 0x6a, 0x3b, 0x86, 0xed, 0x77, 0x5a, 0xd6, 0xd1, 0x0b, 0x03, 0xff, 0xc6, 0x6a, 0x06, 0xfe, 0x05, - 0xdd, 0x18, 0x2f, 0xac, 0xd6, 0x11, 0xfd, 0xc2, 0x0e, 0x6f, 0x0e, 0xbb, 0xff, 0x54, 0x0f, 0x1a, 0xe7, 0xe0, 0xd0, - 0x1c, 0xba, 0x1d, 0xab, 0xdd, 0x36, 0x0e, 0x1d, 0xab, 0xdb, 0x5e, 0x98, 0x87, 0x2d, 0xeb, 0xe8, 0x78, 0x62, 0x3a, - 0xd6, 0xf1, 0xb1, 0x61, 0x9b, 0x6d, 0xab, 0x65, 0x38, 0xd6, 0x61, 0x1b, 0x7f, 0xb4, 0xad, 0xd6, 0xcd, 0xf1, 0x0b, - 0xeb, 0xa8, 0xb3, 0x38, 0xb2, 0x0e, 0x7f, 0x3e, 0xec, 0x5a, 0xad, 0xf6, 0xa2, 0x7d, 0x64, 0xb5, 0x8e, 0x6f, 0x8e, - 0xac, 0xc3, 0x85, 0xd9, 0x3a, 0xda, 0xda, 0xd2, 0x69, 0x59, 0x00, 0x23, 0x7c, 0x0d, 0x2f, 0x0c, 0xfe, 0x02, 0xfe, - 0x2c, 0xb0, 0xed, 0x1f, 0xd8, 0x4d, 0x5c, 0x6d, 0xfa, 0xc2, 0xea, 0x1e, 0x4f, 0xa8, 0x3a, 0x14, 0x98, 0xa2, 0x06, - 0x34, 0xb9, 0x31, 0xe9, 0xb3, 0xd8, 0x9d, 0x29, 0x3a, 0x12, 0x7f, 0xf8, 0xc7, 0x6e, 0x4c, 0xf8, 0x30, 0x7d, 0xf7, - 0x4f, 0xed, 0x27, 0x5b, 0x72, 0x48, 0x14, 0xff, 0x05, 0xff, 0x87, 0x72, 0x2c, 0x8e, 0x8c, 0xf3, 0xa6, 0x4b, 0xc9, - 0x77, 0xbb, 0x2f, 0x25, 0xbf, 0x59, 0xef, 0x73, 0x29, 0xf9, 0xee, 0xb3, 0x5f, 0x4a, 0x9e, 0x97, 0x7d, 0x6b, 0xde, - 0x95, 0x53, 0x41, 0x7d, 0xb7, 0x29, 0xab, 0x1c, 0x3c, 0x57, 0xbb, 0xbc, 0x58, 0x5f, 0x41, 0x68, 0xbf, 0x77, 0xe1, - 0xe0, 0x9b, 0x75, 0xc1, 0xe0, 0x33, 0x04, 0x1c, 0xfb, 0x2e, 0x24, 0x1c, 0xfb, 0xc3, 0x7a, 0x00, 0x56, 0x66, 0x9c, - 0xcd, 0xf1, 0xa6, 0xe6, 0xc2, 0xf5, 0x67, 0x19, 0x8b, 0x04, 0x25, 0x7d, 0x2c, 0x06, 0xc7, 0x35, 0x20, 0xcf, 0x20, - 0xc9, 0xac, 0x97, 0x41, 0x0c, 0x16, 0xc1, 0x60, 0xc9, 0x31, 0x8b, 0xd2, 0x52, 0x63, 0x4b, 0x04, 0x43, 0xbc, 0xe6, - 0x5e, 0x50, 0x8d, 0xef, 0xd1, 0x00, 0xb8, 0xbe, 0x77, 0xa7, 0xda, 0xaf, 0x02, 0x96, 0x75, 0xc2, 0x40, 0x1a, 0xb8, - 0xfd, 0xba, 0xf7, 0x45, 0x33, 0xdc, 0x92, 0xe1, 0x75, 0xf3, 0x48, 0x61, 0x24, 0xe5, 0xf6, 0x4e, 0xd1, 0x8c, 0x77, - 0xd7, 0x34, 0x6b, 0x3e, 0x5f, 0x68, 0xbe, 0xc5, 0x86, 0x38, 0xeb, 0xb8, 0x0c, 0xaa, 0x52, 0x22, 0xe3, 0x5a, 0x80, - 0xe4, 0x02, 0x6a, 0x6e, 0x68, 0x9c, 0x73, 0xaa, 0xb6, 0x82, 0xfc, 0x8e, 0x2d, 0xbd, 0x2b, 0xf4, 0x29, 0x1b, 0x27, - 0x3f, 0xdb, 0xa0, 0x5c, 0xe1, 0xfd, 0x0a, 0x9c, 0x28, 0xe7, 0x78, 0xc6, 0xa1, 0x0c, 0xe7, 0x8d, 0xd4, 0x2f, 0x69, - 0x23, 0xd2, 0x85, 0xb3, 0xa9, 0xf2, 0xa2, 0x8d, 0x6e, 0x09, 0x0e, 0x5b, 0x0a, 0x2e, 0x08, 0x3f, 0x4f, 0x4e, 0x00, - 0x29, 0x39, 0x6a, 0xa0, 0x9f, 0xc3, 0xb6, 0xce, 0x44, 0xbd, 0xc7, 0xb0, 0x89, 0x79, 0xd0, 0x65, 0x45, 0x8e, 0x36, - 0xb3, 0x99, 0xf9, 0xa1, 0x9b, 0xf4, 0x90, 0x4d, 0x93, 0x58, 0xde, 0x16, 0x7a, 0x2c, 0xf4, 0xb7, 0x18, 0xd3, 0xc9, - 0x1d, 0xf3, 0x4e, 0xd0, 0xf3, 0x61, 0x9b, 0xfd, 0x5d, 0xe6, 0x70, 0xb6, 0x29, 0x98, 0xa3, 0x38, 0x9d, 0x63, 0xc3, - 0x39, 0x32, 0xac, 0xe3, 0x8e, 0x9e, 0x8a, 0x03, 0x27, 0x77, 0x59, 0x00, 0x08, 0x38, 0x40, 0x64, 0xc3, 0xf4, 0x02, - 0x2f, 0xf1, 0x5c, 0x3f, 0x05, 0x7e, 0xb8, 0x28, 0xa4, 0xfc, 0x6b, 0x1d, 0x27, 0x30, 0x47, 0xc1, 0xf4, 0xa2, 0xf3, - 0x87, 0x39, 0x66, 0xc9, 0x2d, 0x63, 0x41, 0x83, 0x61, 0x4c, 0xd9, 0x97, 0xe4, 0xf7, 0xb3, 0xac, 0x4f, 0xc9, 0x6a, - 0x6d, 0x9c, 0x04, 0x7c, 0x7f, 0x08, 0xc7, 0x87, 0x74, 0x64, 0xfc, 0xda, 0x84, 0x70, 0xff, 0xb5, 0x1b, 0xe1, 0x26, - 0x6c, 0x1f, 0x84, 0xfb, 0xaf, 0xcf, 0x8e, 0x70, 0x7f, 0x95, 0x11, 0x6e, 0xc1, 0x7f, 0x30, 0xbf, 0x61, 0x7a, 0x8f, - 0xcf, 0x1a, 0x24, 0x51, 0x79, 0xae, 0x1e, 0x10, 0x03, 0x0f, 0xf9, 0x25, 0x44, 0x14, 0xaf, 0x97, 0x85, 0x64, 0x9d, - 0xa8, 0x00, 0xc5, 0x04, 0x1d, 0x94, 0x18, 0xd0, 0x03, 0x57, 0xb7, 0x2c, 0x39, 0x20, 0xbb, 0x55, 0xce, 0x82, 0xc4, - 0xb7, 0xde, 0x71, 0x39, 0x12, 0x2e, 0x74, 0xbf, 0x09, 0xa3, 0xa5, 0x8b, 0xd1, 0x5f, 0x55, 0x4c, 0xf2, 0x0d, 0x0f, - 0x36, 0x38, 0xe3, 0x4e, 0xc2, 0x60, 0x9a, 0xdd, 0x4a, 0xb2, 0xc1, 0x25, 0x71, 0xdc, 0xea, 0x3d, 0x73, 0x23, 0xd5, - 0xa0, 0xd7, 0xb0, 0xb8, 0xcf, 0xda, 0xf6, 0xb3, 0xd6, 0xe1, 0xb3, 0x23, 0x1b, 0xfe, 0x77, 0x58, 0x3b, 0x35, 0x78, - 0xc5, 0x65, 0x18, 0x40, 0x9e, 0x41, 0x51, 0xb3, 0xa9, 0xda, 0x2d, 0x63, 0x1f, 0xf2, 0x5a, 0xc7, 0xf5, 0x95, 0xa6, - 0xee, 0x7d, 0x5e, 0xa7, 0xb6, 0xc6, 0x22, 0x5c, 0x4b, 0xc3, 0xaa, 0x19, 0x8d, 0x17, 0xac, 0x41, 0xcf, 0x2e, 0xd5, - 0x90, 0x5f, 0xf3, 0xe9, 0xe6, 0xf3, 0x62, 0xed, 0xf4, 0x2a, 0x4f, 0x66, 0x2a, 0x92, 0x2a, 0xee, 0x84, 0x20, 0xbf, - 0xa2, 0xb4, 0x31, 0xde, 0x37, 0x66, 0x9c, 0x80, 0x68, 0xdf, 0x59, 0x0a, 0x4a, 0x97, 0x16, 0x28, 0x89, 0xd6, 0xc1, - 0x44, 0xc3, 0x9f, 0xee, 0x38, 0xd6, 0xbc, 0x83, 0xc8, 0xe2, 0x1f, 0xd6, 0x71, 0xd5, 0xdc, 0xa1, 0x9d, 0x67, 0x7e, - 0x8b, 0xc5, 0xaa, 0xb8, 0xcf, 0x12, 0x23, 0xc2, 0x7b, 0x6c, 0x5a, 0x5a, 0x73, 0xe0, 0x3e, 0xcb, 0x1a, 0x3e, 0x4b, - 0x8c, 0xe0, 0x39, 0xdc, 0x7d, 0x0e, 0xec, 0xa7, 0x4f, 0xa9, 0x16, 0x64, 0x51, 0xa7, 0x69, 0x9d, 0x4e, 0xf2, 0xa0, - 0xa1, 0x8a, 0x3b, 0x0f, 0x29, 0x6e, 0x68, 0x6f, 0x62, 0x84, 0xcf, 0x9f, 0x0f, 0x07, 0x8e, 0x8e, 0x59, 0x45, 0x45, - 0x76, 0x70, 0x9e, 0xb0, 0xf6, 0x7c, 0x3f, 0x43, 0x23, 0xbd, 0xd6, 0x95, 0x76, 0x05, 0x32, 0x93, 0x2d, 0xdc, 0x11, - 0x38, 0xf6, 0x82, 0x04, 0x72, 0x64, 0x50, 0xe0, 0x0a, 0x83, 0x1f, 0x51, 0x27, 0x93, 0xba, 0xda, 0x96, 0x6d, 0xd9, - 0x6a, 0xd6, 0x70, 0xe6, 0xcd, 0x07, 0x9b, 0x30, 0x71, 0x21, 0x15, 0xa7, 0x1f, 0xce, 0xc1, 0x8f, 0x2e, 0xf1, 0x12, - 0x1f, 0xf2, 0x3a, 0x82, 0x43, 0xdd, 0x92, 0xe4, 0xf2, 0x94, 0x7b, 0x37, 0xb8, 0xd1, 0x07, 0xcc, 0xed, 0x2d, 0x5c, - 0x71, 0x31, 0x8e, 0xdd, 0xf7, 0x40, 0x0c, 0x35, 0x55, 0x03, 0xdd, 0x00, 0x8b, 0x62, 0x53, 0xf6, 0x16, 0xea, 0x29, - 0xd0, 0x46, 0x57, 0xf9, 0x24, 0x66, 0x91, 0xbb, 0x84, 0x1c, 0x48, 0x9b, 0xd4, 0xe0, 0x98, 0x56, 0xe5, 0xa8, 0x56, - 0x71, 0x5e, 0x1c, 0x19, 0x4a, 0xcb, 0x31, 0x14, 0x1b, 0xd0, 0xad, 0x9a, 0x1a, 0x9b, 0xf4, 0xaa, 0xbf, 0xcb, 0xe0, - 0x81, 0xf0, 0xcb, 0x63, 0x9a, 0x07, 0x99, 0x3a, 0xf0, 0xab, 0xa4, 0x84, 0xe2, 0x17, 0x6b, 0x52, 0x66, 0x13, 0x8f, - 0x2e, 0x3d, 0x2f, 0xd8, 0x5d, 0xa2, 0x63, 0xde, 0x43, 0x5e, 0xc5, 0xd3, 0x37, 0xe8, 0x30, 0xec, 0x05, 0x8a, 0xf7, - 0xf1, 0xa3, 0xe6, 0x81, 0x33, 0xd3, 0x40, 0x82, 0x0f, 0x3c, 0xeb, 0x05, 0x80, 0x79, 0xf9, 0x35, 0x3d, 0x02, 0x0b, - 0x3c, 0x0d, 0xe1, 0xdf, 0xbc, 0x58, 0xfc, 0xe0, 0x66, 0x12, 0x96, 0xef, 0x06, 0x73, 0x40, 0x69, 0x6e, 0x30, 0xaf, - 0x98, 0x63, 0x91, 0xcf, 0x73, 0xa9, 0x34, 0xef, 0x2a, 0x37, 0x95, 0x8a, 0x5f, 0xde, 0x5f, 0x50, 0x5e, 0x57, 0x4d, - 0x05, 0x2a, 0x87, 0x2e, 0xba, 0xf9, 0x4d, 0xee, 0xf3, 0xc1, 0x97, 0x27, 0x4b, 0x96, 0xb8, 0x74, 0x0d, 0x04, 0xc2, - 0x2f, 0xb0, 0x03, 0x0a, 0x27, 0x34, 0x3c, 0x36, 0xd4, 0x60, 0xca, 0x6e, 0xbc, 0x09, 0x97, 0x4b, 0x0d, 0x85, 0xd3, - 0x29, 0x13, 0x2d, 0x3e, 0x07, 0x8e, 0x41, 0x0e, 0x07, 0x13, 0x17, 0x43, 0x1d, 0x0f, 0x82, 0x50, 0x1d, 0x7e, 0x99, - 0xf9, 0x66, 0x36, 0x2d, 0x02, 0x24, 0x57, 0xbf, 0x8c, 0x98, 0xff, 0xef, 0xc1, 0x97, 0x40, 0xb8, 0xbf, 0xbc, 0x52, - 0xf5, 0x7e, 0x62, 0x2d, 0x22, 0x36, 0x1b, 0x7c, 0x59, 0x93, 0x64, 0x1c, 0xc5, 0x7b, 0x1a, 0x8b, 0xda, 0x6e, 0xe5, - 0x21, 0xe7, 0xda, 0x7b, 0x09, 0xf5, 0x43, 0x2e, 0xad, 0x83, 0x04, 0xb8, 0x29, 0xc8, 0xd8, 0x4e, 0x1f, 0xe5, 0xe7, - 0xb1, 0xef, 0x4e, 0x3e, 0xf4, 0xe9, 0x4d, 0xe1, 0xc1, 0x04, 0x6a, 0x3d, 0x71, 0x57, 0x3d, 0x24, 0xaf, 0x72, 0x21, - 0x78, 0x4f, 0x53, 0x69, 0xc6, 0xd9, 0xd5, 0xee, 0x65, 0xdc, 0xca, 0x1b, 0xfc, 0x32, 0x7e, 0xea, 0x76, 0xe1, 0x25, - 0x4c, 0x7c, 0x0a, 0x1f, 0xd2, 0x54, 0x08, 0xea, 0x24, 0xa2, 0xa2, 0x60, 0x6d, 0xb5, 0x15, 0xa7, 0xfb, 0x6d, 0xe7, - 0xc6, 0xb1, 0x17, 0x2d, 0xc7, 0xea, 0xfe, 0xec, 0x74, 0x17, 0x6d, 0xeb, 0xd8, 0x37, 0xdb, 0xd6, 0x31, 0xfc, 0xf9, - 0xf9, 0xd8, 0xea, 0x2e, 0xcc, 0x96, 0x75, 0xf8, 0xb3, 0xd3, 0xf2, 0xcd, 0xae, 0x75, 0x0c, 0x7f, 0xce, 0xa9, 0x15, - 0x08, 0x40, 0x24, 0xef, 0x7c, 0x59, 0xc0, 0x02, 0xd2, 0xef, 0xec, 0x4e, 0xd6, 0x28, 0x90, 0xb7, 0x9a, 0x7b, 0x5d, - 0x40, 0x19, 0x94, 0xfa, 0x07, 0x4d, 0x11, 0xfa, 0x5a, 0x30, 0x60, 0x94, 0xec, 0x47, 0x98, 0xb7, 0x09, 0x3f, 0x74, - 0x91, 0x5f, 0xa5, 0xf6, 0x18, 0xf1, 0x36, 0xf5, 0x39, 0x45, 0x44, 0x22, 0x58, 0xba, 0x08, 0xfe, 0x69, 0x85, 0xa1, - 0xf1, 0x44, 0xfa, 0x2c, 0x09, 0x2b, 0xe5, 0xc9, 0xc8, 0xd3, 0xdd, 0x03, 0x47, 0x6f, 0x7e, 0x96, 0x25, 0xc3, 0xfc, - 0xac, 0x7d, 0x4b, 0x59, 0xca, 0x3e, 0xa9, 0x1f, 0xcc, 0xce, 0x94, 0x27, 0x56, 0x82, 0x88, 0xe2, 0x53, 0x2f, 0xca, - 0x86, 0x27, 0xa1, 0x68, 0xa7, 0x3e, 0x19, 0x8b, 0x0e, 0x59, 0x03, 0xcf, 0x80, 0x4b, 0xbe, 0x71, 0x7d, 0xc9, 0x90, - 0x4d, 0x6a, 0xf9, 0x28, 0xc3, 0xfc, 0x4f, 0x9f, 0xe6, 0x83, 0x33, 0x4b, 0xe3, 0x3e, 0x71, 0x3a, 0x40, 0x76, 0x3b, - 0xac, 0xbd, 0xd5, 0xa6, 0x72, 0x77, 0x2c, 0xfa, 0x3c, 0x08, 0xb5, 0xb0, 0x9b, 0x12, 0x16, 0x1b, 0x8d, 0x86, 0x9d, - 0x15, 0x7b, 0x0d, 0x88, 0xe2, 0x5f, 0x12, 0x75, 0x54, 0xbd, 0x1f, 0x08, 0xf3, 0x83, 0x60, 0x4b, 0xfc, 0x7d, 0x2e, - 0x8b, 0xa9, 0x00, 0x9a, 0x2d, 0xf3, 0xd8, 0xe1, 0x20, 0xfe, 0x67, 0x4f, 0x02, 0x9d, 0x35, 0xc1, 0x5e, 0xa2, 0x74, - 0x5a, 0x0b, 0xce, 0x7b, 0x19, 0x5d, 0x25, 0x82, 0xca, 0xe2, 0x53, 0x15, 0x8a, 0x20, 0x9d, 0x2c, 0x66, 0x90, 0xce, - 0x8c, 0x45, 0x33, 0x6a, 0x91, 0x17, 0x18, 0x1e, 0x26, 0x33, 0x11, 0x8e, 0xa3, 0xfa, 0xd3, 0xa7, 0x8d, 0x44, 0x88, - 0x8c, 0x73, 0x62, 0x96, 0x64, 0x39, 0x2e, 0x55, 0x19, 0xbf, 0xa9, 0x32, 0x8a, 0xc9, 0xfa, 0x45, 0xac, 0x21, 0x6c, - 0x5c, 0x69, 0xef, 0xe1, 0xcf, 0x31, 0x73, 0x13, 0x8b, 0x5f, 0x96, 0x6a, 0x12, 0x71, 0x37, 0x1c, 0xd6, 0x06, 0xeb, - 0x56, 0x1e, 0x41, 0x93, 0x47, 0xa8, 0x7d, 0xb2, 0x79, 0xb9, 0xe6, 0x51, 0x1d, 0xa0, 0x8f, 0x8f, 0x76, 0x1e, 0x80, - 0xec, 0x6d, 0xe2, 0x52, 0x60, 0x18, 0x99, 0xe4, 0x86, 0x89, 0x2b, 0xd2, 0x36, 0x02, 0x5f, 0xde, 0xaf, 0x35, 0xbf, - 0x90, 0x22, 0x3f, 0x0c, 0xdf, 0x5e, 0x7c, 0xad, 0xf0, 0xfd, 0x4f, 0xd6, 0x02, 0x28, 0xc8, 0x50, 0x6a, 0x9f, 0x01, - 0xa5, 0xf6, 0x51, 0x78, 0x6e, 0x29, 0xc8, 0x77, 0x93, 0x1e, 0x10, 0x04, 0x51, 0x01, 0x4d, 0x36, 0x14, 0xcb, 0xb5, - 0x9f, 0x78, 0x2b, 0x37, 0x4a, 0x0e, 0x30, 0xaf, 0x0f, 0x20, 0x39, 0xb5, 0x29, 0x1e, 0x04, 0x99, 0x61, 0x88, 0xc0, - 0xad, 0x49, 0x20, 0xec, 0x30, 0x66, 0x9e, 0x9f, 0x99, 0x61, 0x88, 0x0f, 0xb8, 0x93, 0x09, 0x5b, 0x25, 0x83, 0x42, - 0xfe, 0xa0, 0x70, 0x92, 0xb0, 0xc4, 0x8c, 0x93, 0x88, 0xb9, 0x4b, 0x35, 0x0b, 0x10, 0x5e, 0xed, 0x2f, 0x5e, 0x8f, - 0x97, 0x5e, 0x92, 0x45, 0xd8, 0xa5, 0x09, 0x82, 0x41, 0x04, 0x0c, 0x71, 0x38, 0x4a, 0x39, 0x08, 0xcf, 0xc3, 0x79, - 0x69, 0x47, 0xe5, 0x9c, 0xcb, 0x29, 0xc6, 0x6f, 0x27, 0x49, 0x06, 0xb4, 0xc5, 0x93, 0xd0, 0xbf, 0xe6, 0x31, 0x2c, - 0xb2, 0x40, 0xc0, 0xea, 0xf0, 0x84, 0x8b, 0xb7, 0x0a, 0x86, 0x6f, 0x51, 0x3b, 0x36, 0x44, 0xa8, 0x6f, 0x8a, 0x6e, - 0x71, 0xc0, 0x2b, 0x03, 0x69, 0xa2, 0x9e, 0x31, 0xc9, 0x08, 0x8d, 0xe5, 0x02, 0x18, 0xa1, 0x82, 0xc1, 0xcc, 0xc2, - 0x19, 0x66, 0xee, 0x94, 0x38, 0x2a, 0xe4, 0x95, 0x3e, 0x7e, 0x7c, 0x35, 0xfa, 0xed, 0x3f, 0x90, 0x09, 0x65, 0xe1, - 0x88, 0x98, 0x12, 0x97, 0x72, 0x2d, 0xce, 0x7d, 0x1a, 0x23, 0x34, 0x96, 0x62, 0x53, 0x11, 0xa2, 0x47, 0x6c, 0xad, - 0x74, 0x74, 0x25, 0x42, 0x34, 0x42, 0x92, 0x24, 0x5d, 0x44, 0xbe, 0x18, 0xc1, 0xf2, 0x8e, 0x44, 0x4c, 0x14, 0xe5, - 0x97, 0xbb, 0x97, 0xc7, 0x4a, 0x1e, 0xc3, 0xa8, 0xce, 0xa2, 0x87, 0xf6, 0xd0, 0xf0, 0xc4, 0x55, 0x90, 0x69, 0x41, - 0xf6, 0x23, 0xee, 0x1d, 0xc0, 0x34, 0x17, 0xe1, 0x92, 0x59, 0x5e, 0x78, 0x70, 0xcb, 0xc6, 0xa6, 0xbb, 0xf2, 0xc8, - 0x2e, 0x07, 0xf5, 0x6e, 0x0a, 0x71, 0x7e, 0x99, 0xb9, 0x0b, 0xf1, 0xd7, 0x69, 0x0e, 0xca, 0xb0, 0x18, 0x93, 0xb3, - 0xd3, 0xca, 0xef, 0x01, 0x21, 0x7e, 0x81, 0x04, 0xc7, 0x70, 0x78, 0x72, 0xe0, 0x0e, 0x8b, 0x41, 0x81, 0x2d, 0x91, - 0xbd, 0xa6, 0x48, 0x04, 0x4e, 0x29, 0xb6, 0xaf, 0x08, 0xe3, 0x9b, 0x3f, 0x98, 0xe1, 0x6c, 0x26, 0x07, 0xf2, 0xb5, - 0x8a, 0xc3, 0xcb, 0x80, 0x96, 0x6f, 0xe9, 0x70, 0x45, 0x5f, 0xaa, 0x7e, 0x22, 0xfb, 0xa9, 0xf6, 0x30, 0x82, 0x37, - 0xcc, 0x19, 0x8e, 0x7b, 0x25, 0x20, 0x70, 0x06, 0xb1, 0xc7, 0x54, 0x89, 0xe3, 0x91, 0x72, 0xfa, 0x89, 0x06, 0xce, - 0xe5, 0xd1, 0x60, 0x40, 0x68, 0xae, 0x8c, 0xed, 0x00, 0x88, 0x35, 0x99, 0x7c, 0x60, 0xb2, 0x09, 0x34, 0x34, 0xc9, - 0x5d, 0x16, 0x1b, 0x95, 0xa7, 0x53, 0x1d, 0xe3, 0x81, 0x2b, 0xb6, 0x5f, 0x61, 0x83, 0xc2, 0xc6, 0xe3, 0xeb, 0x0e, - 0xf8, 0x5d, 0xf4, 0x53, 0x42, 0xf3, 0xca, 0x57, 0x84, 0xd1, 0x4d, 0xdf, 0xbd, 0x0f, 0x25, 0x33, 0x26, 0x1e, 0xd1, - 0xe4, 0x1c, 0x4b, 0x2f, 0x84, 0x27, 0x71, 0xe5, 0xa0, 0x65, 0x09, 0x51, 0xaa, 0x87, 0x4d, 0x4e, 0x62, 0xb2, 0xeb, - 0xac, 0xc9, 0x75, 0x8b, 0x93, 0x41, 0xe4, 0x99, 0xe6, 0xe7, 0xb0, 0xf0, 0x12, 0xd1, 0x42, 0x7a, 0x72, 0x00, 0xf3, - 0x83, 0x28, 0x2c, 0x05, 0xc6, 0xc9, 0xd3, 0x21, 0xd4, 0x8b, 0x1b, 0x93, 0x29, 0xd6, 0xd9, 0x54, 0xf0, 0x7c, 0x28, - 0x58, 0x4a, 0xd9, 0xfd, 0xa4, 0x2a, 0x55, 0x5e, 0xc6, 0xae, 0x67, 0x02, 0x77, 0x67, 0x0f, 0xfa, 0x61, 0x8d, 0xa9, - 0x83, 0xd2, 0x7e, 0xc2, 0x44, 0x90, 0x83, 0xf3, 0xa4, 0x21, 0x0e, 0x42, 0x53, 0x15, 0xe2, 0x67, 0xb7, 0x54, 0xc8, - 0xf7, 0xf1, 0xb6, 0x5a, 0x39, 0xe7, 0x94, 0x55, 0x5b, 0xb9, 0x9a, 0xfa, 0x18, 0x77, 0x7c, 0xa5, 0x36, 0x96, 0x42, - 0xbd, 0xf3, 0x64, 0x00, 0x55, 0x85, 0x2e, 0xde, 0x5d, 0xad, 0xa8, 0xb2, 0xde, 0x3f, 0x39, 0x20, 0xb1, 0x74, 0x48, - 0x3b, 0x6c, 0x78, 0x02, 0xa6, 0xdc, 0xb4, 0xe8, 0xee, 0x6a, 0xc5, 0x97, 0x94, 0x7e, 0xd1, 0x9b, 0x83, 0x45, 0xb2, - 0xf4, 0x87, 0xff, 0x07, 0x52, 0xaf, 0x09, 0x6c, 0x30, 0x6a, 0x03, 0x00}; + 0x5e, 0x6e, 0x0b, 0x04, 0x92, 0x99, 0x22, 0xb2, 0xd9, 0xee, 0xa9, 0x2b, 0x90, 0xcb, 0x9a, 0x4d, 0xa4, 0x5d, 0xf0, + 0x72, 0xcc, 0x41, 0x26, 0x53, 0xd6, 0x93, 0xf6, 0xc0, 0x16, 0x04, 0xc9, 0x4d, 0x1a, 0x91, 0x6d, 0x7f, 0x29, 0x3e, + 0x89, 0x01, 0x8d, 0x90, 0x15, 0xf8, 0x42, 0x61, 0x91, 0x03, 0xd7, 0x59, 0xf8, 0x8e, 0xbf, 0xd1, 0x52, 0x31, 0x50, + 0xc3, 0x21, 0x2e, 0xcc, 0xf3, 0x18, 0xe5, 0x7c, 0xa8, 0x0a, 0x9e, 0x5b, 0x0a, 0x44, 0x14, 0xbe, 0x5e, 0x1f, 0xc2, + 0x6b, 0x46, 0xae, 0x4d, 0x70, 0xbd, 0x75, 0x3f, 0xab, 0x97, 0x4b, 0x60, 0x1c, 0x8c, 0xb4, 0xcc, 0x45, 0xa1, 0x93, + 0x37, 0xd9, 0xa5, 0xe8, 0x35, 0x1a, 0xcc, 0x04, 0x9a, 0x22, 0x10, 0x55, 0x0e, 0xfc, 0x22, 0xe1, 0x8f, 0x8d, 0x1d, + 0xa5, 0x98, 0x8d, 0xc0, 0x07, 0xa1, 0xc1, 0x6b, 0x09, 0xeb, 0xb5, 0xb2, 0x11, 0x5e, 0x4c, 0x8e, 0x8d, 0xf5, 0x52, + 0xf6, 0x53, 0x86, 0x92, 0xad, 0xcc, 0x38, 0xb8, 0xdb, 0xea, 0x6f, 0xab, 0xfd, 0x7c, 0xc0, 0xed, 0x35, 0x1e, 0x37, + 0x71, 0x13, 0x0c, 0xa0, 0x56, 0x5b, 0x1b, 0xdc, 0xda, 0xf9, 0xc7, 0xd6, 0x28, 0x99, 0x6d, 0x43, 0x50, 0x94, 0x71, + 0x02, 0xec, 0xcd, 0xad, 0x8f, 0x9b, 0xa8, 0xcc, 0x9c, 0x14, 0xd2, 0x03, 0x90, 0xa3, 0x87, 0x04, 0x3a, 0xb7, 0x3f, + 0x2b, 0xba, 0x50, 0xc9, 0xc4, 0xe5, 0x18, 0xff, 0x11, 0xdc, 0xe6, 0x0d, 0xa2, 0x4f, 0x9f, 0xcc, 0x26, 0xff, 0xf4, + 0x29, 0xc2, 0xa1, 0x71, 0x7d, 0x14, 0xf0, 0x82, 0xd1, 0xb0, 0x0c, 0xad, 0x65, 0x36, 0x7e, 0xb3, 0x5d, 0x35, 0xf6, + 0x81, 0x56, 0x78, 0x07, 0xcb, 0x63, 0x1a, 0xdf, 0x71, 0x46, 0x1d, 0x70, 0x80, 0x37, 0x1b, 0xf0, 0x61, 0xef, 0x4d, + 0xac, 0xd0, 0xd1, 0xd1, 0x9b, 0x58, 0xa2, 0xfe, 0x35, 0x33, 0x77, 0x6e, 0xe0, 0x8d, 0x3e, 0xe0, 0x66, 0xf8, 0x32, + 0x40, 0x80, 0x6b, 0xb6, 0x2d, 0xd9, 0xbc, 0x35, 0xb1, 0x3f, 0x52, 0x88, 0x2d, 0x0e, 0x11, 0x8e, 0x1d, 0x48, 0xa0, + 0xd7, 0x37, 0x21, 0xb4, 0x7b, 0x8c, 0x30, 0x60, 0xe1, 0x4b, 0x5f, 0x41, 0x96, 0xcc, 0x59, 0x31, 0x65, 0xc5, 0x7a, + 0xfd, 0x81, 0x5a, 0xff, 0xbf, 0xad, 0x50, 0x95, 0xaa, 0xd7, 0x68, 0x50, 0x33, 0x7e, 0x10, 0x1f, 0xe8, 0x10, 0x1f, + 0xbe, 0x89, 0x0b, 0x84, 0xc0, 0xc2, 0x88, 0x8b, 0xa5, 0xf7, 0x75, 0xcb, 0x6a, 0xeb, 0x52, 0xa0, 0xb2, 0x91, 0x9c, + 0xb4, 0xf0, 0x8c, 0x64, 0xe5, 0x1a, 0x5d, 0xce, 0x7a, 0x8d, 0x46, 0x8e, 0x64, 0x9c, 0x0d, 0xf2, 0x21, 0xe6, 0xb8, + 0x80, 0xcb, 0xd4, 0xdd, 0x75, 0x58, 0xb0, 0x1a, 0xe5, 0x72, 0xf3, 0x5d, 0xd9, 0xb1, 0xa6, 0xcf, 0xe9, 0x26, 0xdc, + 0xdd, 0x34, 0x20, 0x12, 0xfb, 0x80, 0x2c, 0x2c, 0x90, 0x95, 0x07, 0xb2, 0x30, 0x40, 0x56, 0xa8, 0xbf, 0x80, 0xa0, + 0x4d, 0x0a, 0xa5, 0x3b, 0x14, 0xbd, 0x1e, 0x5e, 0xd4, 0xb9, 0xae, 0x60, 0x6e, 0x22, 0x5c, 0xb8, 0xe5, 0x00, 0x37, + 0x16, 0x37, 0x77, 0x45, 0x56, 0x51, 0x64, 0x22, 0xed, 0xe2, 0x5b, 0xf3, 0x27, 0xb9, 0xc5, 0x77, 0xf6, 0xc7, 0x5d, + 0xa0, 0x4c, 0x7a, 0x5f, 0xd3, 0x36, 0x70, 0x17, 0x97, 0x2e, 0x4a, 0x22, 0x40, 0x6b, 0x17, 0x64, 0x51, 0xd4, 0xdf, + 0x9d, 0x53, 0x36, 0x1c, 0x86, 0x68, 0x10, 0x85, 0x45, 0x40, 0x3a, 0xff, 0xf8, 0x23, 0x42, 0x7d, 0x01, 0xd1, 0x8c, + 0xdc, 0xc9, 0xd6, 0x6c, 0xa3, 0x46, 0x94, 0x44, 0x69, 0xec, 0x83, 0x65, 0xc0, 0xce, 0x88, 0xa2, 0xe0, 0xcd, 0x99, + 0x2a, 0xca, 0x5a, 0x6d, 0x18, 0x66, 0x50, 0x55, 0xf8, 0x8f, 0xab, 0xd5, 0x76, 0xb0, 0x25, 0x03, 0x55, 0x61, 0x22, + 0xdd, 0x20, 0xfb, 0x10, 0x1b, 0x23, 0xec, 0xe8, 0x88, 0x0d, 0xc4, 0x30, 0x78, 0x59, 0xad, 0xb2, 0x20, 0xd1, 0xe1, + 0xc2, 0xc5, 0x19, 0x44, 0xbb, 0x5f, 0xaf, 0xed, 0x5f, 0xf2, 0x9b, 0x91, 0x66, 0xe0, 0x89, 0xbc, 0xe0, 0x8c, 0x15, + 0xfb, 0x65, 0xb1, 0x44, 0xcb, 0xf7, 0x60, 0xd9, 0xe7, 0x62, 0x17, 0x72, 0x37, 0xd5, 0x76, 0xe9, 0x82, 0x63, 0x34, + 0x0a, 0x41, 0xe4, 0xe0, 0xea, 0x48, 0xc3, 0x0b, 0x1d, 0xe6, 0xd5, 0x22, 0x00, 0xe7, 0xaa, 0x0c, 0xe4, 0x0a, 0x47, + 0x4a, 0x02, 0x96, 0xde, 0x86, 0x4e, 0xc2, 0x8f, 0x3a, 0x95, 0x74, 0x2c, 0x24, 0x40, 0x81, 0x23, 0x73, 0x39, 0x6f, + 0x02, 0xf5, 0x33, 0xb4, 0x87, 0xc8, 0x05, 0x26, 0x34, 0x75, 0xd9, 0xd2, 0x45, 0xd4, 0x8a, 0xe6, 0x72, 0xa9, 0xd8, + 0x72, 0x01, 0xe7, 0x7b, 0x99, 0x96, 0xe5, 0x3c, 0xfb, 0x52, 0x4f, 0x01, 0x83, 0xc8, 0x5b, 0x3d, 0x67, 0x62, 0x19, + 0xb9, 0x79, 0xbe, 0xb2, 0xe2, 0xfe, 0x9b, 0x17, 0xf8, 0x03, 0xe9, 0x1c, 0xbf, 0xc2, 0x7f, 0x51, 0xf2, 0xa1, 0xf1, + 0x0a, 0x4f, 0x39, 0xb1, 0xbc, 0x41, 0xf2, 0xe6, 0xf5, 0xf5, 0x8b, 0x77, 0x2f, 0x3e, 0x3c, 0xfd, 0xf4, 0xe2, 0xd5, + 0xb3, 0x17, 0xaf, 0x5e, 0xbc, 0xfb, 0x88, 0xff, 0x49, 0xc9, 0xab, 0x93, 0xf6, 0x45, 0x0b, 0xbf, 0x27, 0xaf, 0x4e, + 0x3a, 0xf8, 0x56, 0x93, 0x57, 0x27, 0x67, 0x78, 0xa6, 0xc8, 0xab, 0xe3, 0xce, 0xc9, 0x29, 0x5e, 0x6a, 0xdb, 0x64, + 0x2e, 0xa7, 0xed, 0x16, 0xfe, 0xcb, 0x7d, 0x81, 0x78, 0x1f, 0xb8, 0xe1, 0xb0, 0x2d, 0xe3, 0x07, 0x53, 0x86, 0x8e, + 0x94, 0x31, 0x44, 0xb9, 0x0c, 0xd0, 0x69, 0xac, 0x42, 0x74, 0xb2, 0xa1, 0xa4, 0xc1, 0x86, 0x11, 0xd0, 0x8a, 0x13, + 0xd7, 0x0e, 0x3f, 0x69, 0xb3, 0x53, 0xa0, 0x4f, 0xbc, 0x14, 0x8e, 0x4b, 0x15, 0x4e, 0xdb, 0x69, 0x31, 0x26, 0xb9, + 0x94, 0x45, 0xbc, 0x04, 0x46, 0xc0, 0x68, 0x2d, 0xf8, 0x49, 0x19, 0xb3, 0x4a, 0x5c, 0x92, 0x76, 0xbf, 0x9d, 0x8a, + 0x4b, 0xd2, 0xe9, 0x77, 0xe0, 0x4f, 0xb7, 0xdf, 0x4d, 0xdb, 0x2d, 0x74, 0x1c, 0x8c, 0xe3, 0xe7, 0x1a, 0x5a, 0x0f, + 0x86, 0xd8, 0x75, 0xa1, 0xfe, 0x2a, 0xb4, 0x57, 0xe9, 0x09, 0xa7, 0x8e, 0x6d, 0xf7, 0xc4, 0x25, 0x33, 0x7a, 0x58, + 0xfe, 0x03, 0xa0, 0xb6, 0x71, 0xab, 0x29, 0x37, 0x8e, 0xfb, 0xc5, 0x4f, 0x04, 0xaa, 0x05, 0xc6, 0x89, 0xd9, 0xba, + 0x85, 0x80, 0x69, 0x34, 0xd9, 0x60, 0x0e, 0x94, 0x28, 0x59, 0x68, 0x1f, 0xdc, 0x5f, 0x35, 0x25, 0x4a, 0x16, 0x72, + 0x11, 0xd7, 0x54, 0x0d, 0xbf, 0x04, 0x66, 0x8e, 0x87, 0x5c, 0xbd, 0xa2, 0xaf, 0xe2, 0x1a, 0xcf, 0x13, 0xb2, 0x76, + 0xe1, 0xb6, 0xf8, 0x87, 0xb3, 0xa2, 0xa8, 0x81, 0xab, 0x04, 0xac, 0x1f, 0x55, 0x53, 0x5f, 0xc2, 0x2b, 0x86, 0xac, + 0xa1, 0xaf, 0x48, 0x40, 0x3d, 0x7f, 0x2d, 0xcd, 0xb8, 0x4a, 0x65, 0xb4, 0x57, 0x44, 0x1b, 0xb3, 0x20, 0xaf, 0x88, + 0xbe, 0x54, 0x06, 0x08, 0x92, 0xf0, 0x81, 0x18, 0xc2, 0x81, 0x6f, 0x07, 0x28, 0x0d, 0x9d, 0x03, 0xb5, 0x52, 0x65, + 0x26, 0x64, 0x3e, 0x4d, 0x88, 0x06, 0xd0, 0x3c, 0x55, 0x2a, 0x28, 0xf3, 0x89, 0x25, 0x0a, 0x86, 0xfe, 0x7b, 0xb8, + 0x01, 0x8e, 0x63, 0x83, 0x8a, 0xa1, 0x5d, 0x8d, 0xa8, 0xe7, 0xb7, 0x2f, 0x5a, 0x27, 0xaf, 0x82, 0xfc, 0xa5, 0xf2, + 0xf6, 0x1e, 0x9f, 0x03, 0x4a, 0x6e, 0x83, 0x8a, 0xb5, 0xb1, 0x8f, 0x07, 0xd7, 0x0b, 0x01, 0x72, 0xac, 0xd1, 0x89, + 0x79, 0xd0, 0xb1, 0x87, 0xf4, 0x31, 0x69, 0xb7, 0x20, 0x88, 0xdb, 0x1e, 0xca, 0xf7, 0xeb, 0x16, 0x4c, 0x75, 0x72, + 0xdb, 0x04, 0x5a, 0x0d, 0x6f, 0x3c, 0xdd, 0x35, 0x79, 0x72, 0x87, 0x55, 0x80, 0x33, 0xec, 0x98, 0x35, 0xc4, 0xb1, + 0x40, 0x2e, 0xf8, 0xad, 0xdd, 0x00, 0x9a, 0x8a, 0x8e, 0x7d, 0x6b, 0xd0, 0x1b, 0x47, 0x5d, 0x36, 0x93, 0xee, 0xf1, + 0xab, 0xa3, 0xa3, 0x58, 0x36, 0xc8, 0x07, 0x84, 0x57, 0x14, 0x6c, 0xb6, 0xc1, 0xf7, 0x8e, 0x5b, 0x26, 0x3e, 0x55, + 0x01, 0x75, 0x9c, 0xa8, 0xda, 0xb1, 0x56, 0x75, 0x56, 0xee, 0x06, 0x3f, 0xa6, 0x0e, 0x6a, 0x04, 0x69, 0x76, 0x74, + 0x9d, 0x1a, 0x94, 0x6b, 0x8e, 0x72, 0xb0, 0x2d, 0x1b, 0x7f, 0x51, 0xf4, 0xc3, 0x87, 0xe6, 0xab, 0x60, 0xc2, 0x35, + 0xd3, 0xa4, 0x0f, 0x8d, 0x0f, 0xe8, 0x87, 0x0f, 0x81, 0xab, 0x23, 0xaf, 0xd8, 0x13, 0xcf, 0x8d, 0xfc, 0x6a, 0xb9, + 0xd2, 0x5f, 0x41, 0xb2, 0x2f, 0xc8, 0xaf, 0x80, 0xe5, 0x94, 0xfc, 0x1a, 0xcb, 0x26, 0x84, 0x80, 0x24, 0xbf, 0xc6, + 0x05, 0xfc, 0xc8, 0xc9, 0xaf, 0x31, 0x60, 0x3b, 0x9e, 0x99, 0x1f, 0x45, 0x09, 0x0c, 0x70, 0xaf, 0x93, 0xd6, 0xcb, + 0xae, 0x58, 0xaf, 0xc5, 0xd1, 0x91, 0xb4, 0xbf, 0xe8, 0x55, 0x76, 0x74, 0x94, 0x5f, 0xce, 0xaa, 0xbe, 0xb9, 0xde, + 0x47, 0x5f, 0x0c, 0x42, 0xe1, 0xc0, 0x34, 0x8d, 0x87, 0x33, 0xfe, 0xa9, 0x46, 0x59, 0xa1, 0x81, 0xe6, 0x69, 0xe7, + 0xfe, 0xf9, 0x05, 0x86, 0x7f, 0xef, 0x07, 0x05, 0x75, 0xe6, 0x27, 0x46, 0xda, 0xac, 0x79, 0x5e, 0xd5, 0xb9, 0x0a, + 0xf0, 0x19, 0x33, 0xd4, 0x14, 0x47, 0x47, 0xfc, 0x32, 0xc0, 0x65, 0xcc, 0x50, 0x23, 0xb0, 0xd8, 0x7b, 0x58, 0xda, + 0x93, 0x19, 0xae, 0x09, 0x1e, 0xf7, 0xe5, 0x83, 0x62, 0x78, 0xa9, 0x1d, 0x35, 0x09, 0x43, 0x80, 0x2b, 0xd2, 0x72, + 0x9b, 0xac, 0x27, 0x9a, 0xea, 0xaa, 0xdd, 0x43, 0x92, 0xa8, 0x86, 0xb8, 0xba, 0x6a, 0x63, 0x50, 0xc9, 0xf7, 0x15, + 0x91, 0xa9, 0x20, 0xde, 0x4d, 0x71, 0x95, 0xcb, 0x54, 0xe1, 0x19, 0x4f, 0x85, 0x97, 0xb3, 0x5f, 0x7b, 0xeb, 0x69, + 0xe3, 0x38, 0x6a, 0x7a, 0x66, 0x58, 0xf4, 0x55, 0xe9, 0xf0, 0x08, 0x9b, 0x54, 0x0d, 0xe1, 0xed, 0xc4, 0x12, 0xf3, + 0x98, 0xf5, 0xf2, 0x63, 0x10, 0x9b, 0x5a, 0x35, 0xda, 0x90, 0x09, 0x9f, 0x9b, 0x54, 0xc1, 0x40, 0x4d, 0xe1, 0x4b, + 0x08, 0x7b, 0x98, 0x55, 0x86, 0xd9, 0xbe, 0x61, 0x28, 0x20, 0xa0, 0xc0, 0x15, 0x61, 0x81, 0x04, 0xcf, 0xb3, 0x1a, + 0xe1, 0xa8, 0x93, 0x0b, 0x3b, 0xb9, 0x4b, 0x05, 0xdd, 0x89, 0xe1, 0xa5, 0xee, 0x21, 0xd1, 0x68, 0x38, 0x6e, 0xfb, + 0x4a, 0x98, 0x41, 0x34, 0xdb, 0xc3, 0x2b, 0xd6, 0x43, 0xaa, 0xd9, 0x2c, 0x0d, 0x20, 0xaf, 0x5a, 0xeb, 0xb5, 0xba, + 0xf4, 0x8d, 0xf4, 0xfd, 0x39, 0x6e, 0xf8, 0x2e, 0x2f, 0x78, 0xfe, 0x2e, 0xc9, 0x20, 0x02, 0xaa, 0x0a, 0x7c, 0xb6, + 0x5c, 0x44, 0x38, 0x32, 0xcf, 0xea, 0xc1, 0x5f, 0xf3, 0x1c, 0x5a, 0x84, 0x23, 0xf7, 0xd2, 0x5e, 0x34, 0xac, 0x06, + 0x2b, 0xb2, 0x32, 0x48, 0x3c, 0x4f, 0x3e, 0x01, 0xe3, 0xa0, 0x3f, 0x2b, 0xb4, 0xaa, 0x7e, 0x27, 0xb9, 0x0b, 0x97, + 0xa2, 0xfc, 0xe3, 0x6f, 0x6e, 0x54, 0x9b, 0xfd, 0x0e, 0xaa, 0x1c, 0x47, 0xbe, 0x2a, 0x3c, 0xa2, 0xf0, 0x9d, 0xd7, + 0x27, 0xdb, 0xee, 0xd1, 0xf3, 0x55, 0xd9, 0x03, 0x70, 0xde, 0x9b, 0x0d, 0xc2, 0xbf, 0xcb, 0xbd, 0x2f, 0x20, 0x47, + 0x9f, 0xa4, 0x78, 0x42, 0x35, 0x8d, 0x1a, 0x6f, 0x8c, 0xe1, 0x9b, 0x95, 0xb3, 0x7a, 0xdf, 0x1a, 0x07, 0xfb, 0xb7, + 0xba, 0x87, 0x00, 0x16, 0xb5, 0xc7, 0x9a, 0xac, 0xec, 0x6b, 0xc2, 0x96, 0xc8, 0xc0, 0xf4, 0x6d, 0x0f, 0x3c, 0xfc, + 0x18, 0x29, 0xb8, 0x55, 0x5b, 0x3e, 0x89, 0x42, 0x64, 0xd8, 0x9a, 0x33, 0x37, 0xa4, 0xd8, 0x3e, 0x8c, 0xe3, 0xef, + 0x06, 0x85, 0x5c, 0xf7, 0x42, 0xd5, 0x89, 0x69, 0xd5, 0x8d, 0x91, 0x3a, 0xd8, 0x36, 0x0b, 0xce, 0xaa, 0xde, 0x8d, + 0x84, 0x52, 0xbd, 0x6b, 0x67, 0xde, 0x26, 0x6d, 0xb6, 0xcd, 0x63, 0xcf, 0xf6, 0xf5, 0x3b, 0x05, 0x86, 0xbc, 0x87, + 0x65, 0xd0, 0xae, 0x2b, 0x38, 0x76, 0xe3, 0x00, 0xb2, 0x92, 0x5c, 0xad, 0xdc, 0xcb, 0x74, 0x7c, 0x20, 0x87, 0x9b, + 0xf2, 0x9d, 0xba, 0x00, 0x0f, 0xaa, 0x91, 0xaa, 0x2c, 0xe4, 0x0c, 0xfc, 0x23, 0x8f, 0x35, 0xfd, 0x10, 0xff, 0x1b, + 0x0e, 0xf8, 0x0a, 0x49, 0x53, 0xab, 0x7e, 0x82, 0xf7, 0xa3, 0x40, 0xe1, 0x6d, 0xeb, 0xfe, 0x24, 0x43, 0x47, 0xdd, + 0xba, 0x4e, 0xc5, 0xfa, 0xc2, 0xd6, 0x15, 0x2b, 0x65, 0xe1, 0x80, 0x6a, 0xc5, 0x68, 0x93, 0x3a, 0xbf, 0x59, 0xf7, + 0xe8, 0xd4, 0x43, 0x01, 0xbe, 0x31, 0x5c, 0x8a, 0x67, 0x05, 0x44, 0x11, 0x0b, 0xf5, 0x69, 0xba, 0x08, 0x5f, 0x55, + 0x1e, 0xc0, 0x3d, 0x61, 0xc9, 0x73, 0x96, 0x2f, 0x81, 0xc3, 0x02, 0x29, 0xa0, 0x50, 0x0a, 0x8b, 0xf5, 0x3a, 0x16, + 0x26, 0xb6, 0x84, 0x0b, 0x2d, 0xec, 0xde, 0x10, 0x31, 0xfa, 0x3b, 0xa8, 0x8b, 0xbd, 0x7a, 0xc4, 0x98, 0xb0, 0xa2, + 0xf0, 0xd2, 0x49, 0x66, 0x41, 0x5f, 0xfb, 0xfa, 0x10, 0xd5, 0x94, 0xfb, 0xb1, 0xd1, 0xf7, 0xbe, 0xe3, 0x73, 0x26, + 0x97, 0xf0, 0x78, 0x13, 0x66, 0x44, 0x31, 0xed, 0xbf, 0x81, 0x82, 0xc0, 0x0b, 0x40, 0x3c, 0xc4, 0x47, 0xe0, 0xab, + 0x3c, 0xad, 0x2b, 0x32, 0xff, 0x24, 0x48, 0x64, 0x42, 0x76, 0x46, 0xfd, 0x08, 0xbc, 0x88, 0x40, 0x84, 0x22, 0x24, + 0x62, 0x62, 0x1c, 0xf5, 0x23, 0xe3, 0x92, 0x15, 0x81, 0xd5, 0x18, 0x28, 0xb9, 0x23, 0x3c, 0x55, 0x15, 0x11, 0x0b, + 0x6b, 0xea, 0xa0, 0x12, 0x4b, 0x8d, 0x99, 0xf6, 0x49, 0xa7, 0x02, 0x21, 0xcd, 0xb6, 0x05, 0x65, 0xbd, 0xa5, 0x2e, + 0xc0, 0x92, 0x18, 0xd3, 0x5b, 0x9e, 0x7c, 0x02, 0x6e, 0x8e, 0x8d, 0x5d, 0xd1, 0x15, 0xbf, 0x06, 0xf5, 0x74, 0x5a, + 0xe0, 0x4f, 0x86, 0x61, 0x1b, 0xa7, 0x74, 0x43, 0x38, 0xce, 0x48, 0x91, 0xd0, 0x5b, 0x88, 0xad, 0x31, 0xe7, 0x22, + 0xcd, 0xf1, 0x9c, 0xde, 0xa6, 0x33, 0x3c, 0xe7, 0xe2, 0x89, 0x5d, 0xf6, 0x74, 0x0c, 0x49, 0xfe, 0x63, 0xb9, 0x21, + 0xe6, 0x69, 0xb0, 0xf7, 0x8a, 0x15, 0x8f, 0x80, 0x57, 0x51, 0x31, 0xea, 0x8d, 0x8d, 0x4d, 0x39, 0xd7, 0x95, 0xf1, + 0xfa, 0x6b, 0x1d, 0x53, 0x9c, 0xe1, 0x1c, 0x25, 0xb9, 0xc4, 0xac, 0x2f, 0xd2, 0xd7, 0x10, 0x57, 0x3b, 0xc3, 0xf6, + 0x59, 0x31, 0x7e, 0xcb, 0xf2, 0x67, 0xb2, 0xf8, 0x60, 0xb6, 0x7c, 0x8e, 0xa0, 0x10, 0xb8, 0xa8, 0x88, 0x26, 0xdc, + 0xee, 0x2d, 0xfb, 0xb2, 0x6a, 0x8a, 0xde, 0xda, 0xa6, 0xdc, 0x10, 0x67, 0x10, 0x90, 0x38, 0x99, 0xf1, 0x46, 0x1b, + 0xb3, 0x7e, 0xeb, 0x3b, 0x8d, 0xce, 0x50, 0x59, 0x12, 0x61, 0x58, 0xab, 0xa6, 0x4a, 0x25, 0x11, 0x4d, 0xe5, 0x24, + 0xbc, 0x95, 0x01, 0x76, 0xaa, 0x70, 0x26, 0x97, 0x42, 0xa7, 0x32, 0xc0, 0x9b, 0xac, 0xda, 0x5c, 0xab, 0x5b, 0x0b, + 0x31, 0x8d, 0xef, 0xec, 0x0f, 0x86, 0x3f, 0x19, 0x15, 0xff, 0x5b, 0x30, 0xec, 0x51, 0xa9, 0x00, 0xf8, 0x81, 0xe1, + 0x2c, 0x40, 0xce, 0xf2, 0x93, 0xb7, 0x00, 0x3e, 0xcb, 0x42, 0xde, 0x41, 0x2a, 0x33, 0xa9, 0x77, 0x90, 0xca, 0x20, + 0xd5, 0x78, 0xd4, 0x1f, 0x8a, 0x4a, 0x59, 0x14, 0x36, 0x48, 0x14, 0x2e, 0xd5, 0xc1, 0x92, 0x88, 0x04, 0xda, 0x35, + 0xa2, 0xdc, 0x9c, 0x0b, 0x08, 0xad, 0x08, 0x8d, 0xdb, 0x6f, 0x7a, 0x0b, 0xdf, 0x77, 0x36, 0x9f, 0xf9, 0xfc, 0x3b, + 0x9b, 0x6f, 0x3a, 0xf2, 0x18, 0x5f, 0xbf, 0xed, 0x34, 0x96, 0xf1, 0xd2, 0x61, 0xed, 0xfb, 0xf2, 0x21, 0x9b, 0x96, + 0x79, 0x30, 0x9c, 0xb4, 0xf1, 0x3c, 0x40, 0xca, 0x66, 0xc5, 0xc3, 0x75, 0x70, 0xbb, 0x75, 0x1c, 0xf3, 0x26, 0x69, + 0x23, 0x74, 0xec, 0x84, 0x2b, 0x11, 0x1b, 0xc9, 0xe9, 0xf8, 0xc3, 0x09, 0xdc, 0xbd, 0x8c, 0xd4, 0x96, 0xaf, 0x94, + 0xad, 0xd6, 0x6c, 0xb7, 0x8e, 0xf9, 0xde, 0x2a, 0x8d, 0x36, 0x9e, 0x33, 0xb2, 0x02, 0x0f, 0x34, 0x5a, 0x58, 0x55, + 0x03, 0xb8, 0xac, 0xbe, 0x10, 0xbf, 0x2e, 0xe9, 0xd8, 0x7c, 0x1f, 0xdb, 0x94, 0xd7, 0x4b, 0xed, 0x93, 0x9a, 0x1c, + 0x06, 0xd1, 0x41, 0xae, 0x64, 0x90, 0x13, 0xf3, 0x13, 0x92, 0x74, 0xd1, 0x65, 0xbb, 0x9f, 0x74, 0x8f, 0xf9, 0x31, + 0x4f, 0x81, 0x87, 0x8d, 0x9b, 0xbe, 0x42, 0xb3, 0xed, 0xeb, 0x3c, 0x5e, 0x8e, 0x78, 0xe6, 0x9a, 0xaf, 0x3a, 0x28, + 0x53, 0xed, 0x1c, 0x21, 0x0b, 0x50, 0xcc, 0xf7, 0x12, 0x64, 0xd7, 0xbb, 0x39, 0xe6, 0x29, 0xf4, 0x03, 0xb5, 0x3a, + 0xb6, 0x56, 0x39, 0xb8, 0x5f, 0x97, 0x80, 0x60, 0xbe, 0xa3, 0xda, 0x5c, 0x6c, 0x7a, 0x33, 0xae, 0x3a, 0x3b, 0xe6, + 0xd5, 0x08, 0xc3, 0x32, 0xbb, 0xfd, 0xf9, 0xa9, 0x55, 0x5d, 0x1e, 0x07, 0x10, 0xf9, 0x75, 0xc9, 0x45, 0xd8, 0x69, + 0xd8, 0xad, 0xcb, 0x09, 0x3b, 0xad, 0xcf, 0x32, 0x28, 0xb2, 0xdb, 0xeb, 0xce, 0x4c, 0xeb, 0xb3, 0xbd, 0x06, 0x47, + 0x42, 0x98, 0x94, 0x59, 0xe9, 0x4c, 0xaa, 0x98, 0x1f, 0xbf, 0x47, 0xae, 0xf5, 0xd7, 0x4b, 0xed, 0xf3, 0x4b, 0x44, + 0x80, 0xec, 0xaa, 0xeb, 0xb2, 0x3a, 0xf4, 0x51, 0x36, 0xf1, 0xea, 0x98, 0x07, 0x2b, 0xf7, 0xf4, 0x76, 0x21, 0x53, + 0x8f, 0xaf, 0xfd, 0x56, 0xba, 0x83, 0x9c, 0x40, 0x3c, 0x5c, 0x77, 0x61, 0x59, 0x90, 0xb3, 0x9b, 0x3b, 0x28, 0x19, + 0x4e, 0xdc, 0x97, 0x7e, 0xcf, 0xec, 0x75, 0x03, 0xbf, 0x4c, 0xba, 0x30, 0xf5, 0xed, 0x1e, 0x8e, 0x3b, 0xd0, 0x87, + 0x81, 0xc3, 0x76, 0x83, 0x3e, 0xb3, 0x82, 0xc8, 0x63, 0x5e, 0x58, 0x3c, 0xbb, 0x22, 0xed, 0x3e, 0x4f, 0xdd, 0x66, + 0x32, 0xa2, 0x51, 0xbb, 0xc9, 0x83, 0x99, 0x01, 0x7e, 0xb9, 0xb2, 0x61, 0x11, 0xbf, 0x4e, 0x01, 0x94, 0x7c, 0xb1, + 0x6a, 0x7d, 0x2a, 0x78, 0xd5, 0x1b, 0x4e, 0xb7, 0xd3, 0xfd, 0xba, 0xc1, 0xed, 0xae, 0x87, 0x27, 0x3c, 0x44, 0x63, + 0xd1, 0xda, 0x4f, 0x7c, 0x0e, 0x1c, 0x50, 0xd2, 0xba, 0xdf, 0x05, 0x17, 0xca, 0x12, 0x96, 0xbb, 0xe5, 0x46, 0x3b, + 0xe5, 0x2c, 0x1c, 0x6d, 0xc9, 0x80, 0x3b, 0xd8, 0x86, 0x28, 0x74, 0x70, 0xdc, 0xc1, 0x49, 0xbb, 0xdd, 0xe9, 0xe2, + 0xe4, 0xac, 0x0b, 0x03, 0x6d, 0x24, 0xdd, 0xe3, 0x91, 0xb2, 0x00, 0x0c, 0x72, 0x36, 0xae, 0xdd, 0x47, 0x10, 0xb4, + 0x2a, 0x14, 0xaf, 0xf9, 0x71, 0x1c, 0xb7, 0x93, 0xfb, 0xad, 0x76, 0xf7, 0xa2, 0x01, 0x00, 0x6a, 0xba, 0x0f, 0x57, + 0xe3, 0xf5, 0x52, 0xd7, 0xab, 0x94, 0x08, 0x5f, 0xaf, 0xd6, 0xf0, 0xd5, 0x1a, 0xed, 0x4d, 0x35, 0x05, 0x5f, 0xd5, + 0x09, 0xe7, 0xb6, 0x88, 0x57, 0xda, 0x84, 0xdb, 0x22, 0xb6, 0x03, 0x89, 0x41, 0x3a, 0x4f, 0xba, 0x9d, 0x2e, 0xb2, + 0x63, 0xd1, 0x0e, 0x3f, 0xca, 0x7d, 0xb2, 0x53, 0xa4, 0xa1, 0x01, 0x49, 0xca, 0xd9, 0xc9, 0x25, 0x48, 0xd4, 0x9c, + 0x5c, 0xb5, 0x9b, 0x73, 0x96, 0xf8, 0x09, 0x98, 0x54, 0x58, 0xce, 0x72, 0x15, 0x5c, 0x52, 0x00, 0x88, 0x4b, 0x30, + 0x2e, 0xba, 0xdf, 0xed, 0xdf, 0x4f, 0xba, 0xe7, 0x1d, 0x4b, 0xf4, 0xf8, 0x65, 0xa7, 0x96, 0x66, 0xa6, 0x9e, 0x74, + 0x4d, 0x1a, 0x74, 0x9d, 0xdc, 0xef, 0x42, 0x19, 0x97, 0x12, 0x96, 0x82, 0x60, 0x1b, 0x55, 0x31, 0x88, 0xb0, 0x91, + 0xd6, 0x72, 0xcf, 0x6b, 0xd9, 0x17, 0x67, 0xa7, 0xf7, 0xbb, 0x21, 0xd4, 0xca, 0x59, 0x98, 0x85, 0x76, 0x13, 0xf1, + 0xb3, 0x83, 0xa5, 0x45, 0xc7, 0x49, 0x37, 0xdd, 0x99, 0xa0, 0xdd, 0x34, 0xc7, 0x06, 0x07, 0x02, 0x85, 0xe3, 0x53, + 0xe1, 0xf4, 0x25, 0xc1, 0xfd, 0x58, 0x65, 0x68, 0x12, 0x2a, 0x9c, 0xfd, 0x3d, 0x65, 0xf0, 0x9e, 0x66, 0x78, 0x55, + 0xf9, 0x98, 0x8a, 0xaf, 0x54, 0xbd, 0xa1, 0x10, 0x41, 0x44, 0x0c, 0x23, 0x17, 0xdf, 0xbc, 0x9e, 0xfb, 0x0f, 0x70, + 0x11, 0x66, 0x02, 0x2e, 0x34, 0xbd, 0x12, 0xb4, 0xe2, 0x05, 0x3e, 0x85, 0x0e, 0xb5, 0x66, 0x58, 0x7d, 0x9e, 0x3a, + 0x93, 0x82, 0x50, 0xb7, 0xf5, 0x9c, 0x7f, 0xaf, 0x5c, 0x52, 0x5e, 0x65, 0x27, 0x5d, 0x94, 0xb8, 0xcb, 0xf2, 0xa4, + 0x8d, 0x92, 0xc0, 0x84, 0xc4, 0x1d, 0xc9, 0x79, 0x46, 0x06, 0xd1, 0x6d, 0x84, 0xa3, 0xbb, 0x08, 0x47, 0xd6, 0x87, + 0xf9, 0x37, 0xf0, 0xe3, 0x8e, 0x70, 0x64, 0x5d, 0x99, 0x23, 0x1c, 0x69, 0x26, 0x20, 0xb0, 0x58, 0x34, 0xc4, 0x33, + 0x28, 0x6d, 0x3c, 0xab, 0xcb, 0xd2, 0x8f, 0xfd, 0x57, 0xe9, 0x7a, 0x6d, 0x53, 0x02, 0x29, 0x73, 0x6c, 0x76, 0xa8, + 0x7d, 0x18, 0x3b, 0xa2, 0x9e, 0x59, 0x8f, 0x30, 0x08, 0x20, 0xf4, 0xce, 0x3f, 0xac, 0x57, 0xc5, 0x24, 0x61, 0xa7, + 0xb0, 0xd2, 0xe0, 0x8a, 0x1e, 0x85, 0x67, 0x58, 0x84, 0x27, 0xc2, 0x17, 0x06, 0xb1, 0xc2, 0xff, 0xce, 0xa5, 0x5c, + 0xf8, 0xdf, 0x5a, 0x96, 0xbf, 0xe0, 0x39, 0x16, 0x67, 0xd1, 0x02, 0x96, 0x5b, 0x36, 0x04, 0xd2, 0x88, 0xd5, 0x47, + 0xf0, 0x69, 0xe2, 0xc2, 0xd4, 0x81, 0x44, 0xf8, 0xc9, 0x08, 0x54, 0x5e, 0x3e, 0xfc, 0x64, 0x43, 0x26, 0x99, 0x4f, + 0x88, 0x99, 0x06, 0x61, 0x91, 0x25, 0x5c, 0x68, 0x4c, 0x0b, 0xa6, 0x54, 0x64, 0x63, 0x09, 0x46, 0x52, 0xf8, 0xc7, + 0x21, 0x7d, 0xca, 0x44, 0x44, 0xa6, 0xc3, 0xfa, 0x6c, 0xad, 0x38, 0x9c, 0xcb, 0x42, 0xa5, 0xf6, 0xa5, 0x18, 0x0f, + 0xc6, 0x45, 0xf9, 0x0c, 0x63, 0x3a, 0xcb, 0x36, 0xd8, 0xde, 0x61, 0x97, 0x85, 0xdc, 0x95, 0x76, 0x58, 0x2a, 0xcf, + 0x36, 0xdf, 0x9a, 0x90, 0xaa, 0xcd, 0x28, 0x98, 0x68, 0x35, 0xa0, 0x2a, 0x70, 0x07, 0x14, 0xb6, 0x41, 0x69, 0xd2, + 0x55, 0x59, 0x32, 0x5d, 0x95, 0xcb, 0x70, 0xd6, 0x6a, 0x6d, 0x36, 0xb8, 0x60, 0x26, 0x90, 0xcb, 0xde, 0x12, 0x90, + 0xaf, 0x66, 0xf2, 0x26, 0xc8, 0x55, 0x69, 0x39, 0x4b, 0xb3, 0x44, 0x51, 0x60, 0x04, 0x1b, 0x6d, 0xf0, 0x57, 0xae, + 0x38, 0xc0, 0xd3, 0xcd, 0x6e, 0x24, 0x65, 0xce, 0x28, 0xc4, 0x50, 0x0b, 0x9a, 0xdc, 0xe0, 0x19, 0x1f, 0xb3, 0xfd, + 0x6d, 0x82, 0x19, 0xf3, 0xbf, 0xd7, 0xa2, 0x47, 0x20, 0xcb, 0xee, 0x19, 0xd4, 0x81, 0x45, 0x5c, 0x43, 0x07, 0xa1, + 0x0c, 0xbe, 0x0c, 0x71, 0x33, 0xa7, 0x77, 0x72, 0xa9, 0x01, 0x2e, 0x4b, 0x2d, 0xdf, 0xb8, 0x70, 0x08, 0x87, 0x2d, + 0xec, 0x23, 0x23, 0xac, 0x20, 0x64, 0x40, 0x0b, 0xdb, 0x88, 0x18, 0x2d, 0xec, 0x02, 0x15, 0xb4, 0xb0, 0x09, 0x4f, + 0xd1, 0xda, 0x94, 0xb1, 0xcd, 0xee, 0xca, 0x27, 0x35, 0xab, 0x4d, 0x30, 0x71, 0xd2, 0xa1, 0x26, 0x3a, 0xb8, 0x3d, + 0x64, 0x84, 0x37, 0x7e, 0xba, 0x7e, 0xfd, 0xca, 0x45, 0xae, 0xe6, 0x13, 0x70, 0xd9, 0x74, 0xaa, 0xb1, 0x3b, 0x1b, + 0x62, 0xbe, 0x52, 0x94, 0x5a, 0xe1, 0xd4, 0x04, 0xfb, 0x14, 0x3a, 0x4f, 0xec, 0xe5, 0xc5, 0x33, 0x59, 0xcc, 0xa9, + 0xbd, 0x31, 0xc2, 0x77, 0xca, 0x3d, 0x3e, 0x6f, 0xde, 0xb7, 0xa9, 0x26, 0xf9, 0x6e, 0xfb, 0x2a, 0x62, 0x92, 0x19, + 0xf9, 0x15, 0xb4, 0x01, 0xa6, 0xb2, 0x1f, 0x38, 0x2b, 0x88, 0x8b, 0xff, 0x1f, 0x90, 0x97, 0xb7, 0x96, 0xba, 0x44, + 0x51, 0x83, 0x1b, 0xfc, 0x64, 0x45, 0xa5, 0xe3, 0xe2, 0xe6, 0xfd, 0x48, 0xd2, 0x72, 0xe2, 0x45, 0xd4, 0x8a, 0xea, + 0x6f, 0xef, 0x1a, 0x55, 0x82, 0x8f, 0x1d, 0x9b, 0xe4, 0x12, 0x44, 0x8f, 0xf2, 0x99, 0x3f, 0x0e, 0xa2, 0x89, 0xbf, + 0x7b, 0xbe, 0x6a, 0x7b, 0x3a, 0x9b, 0x57, 0xea, 0xc4, 0xf2, 0xca, 0x04, 0x3c, 0x1c, 0xed, 0x43, 0x3a, 0x08, 0x07, + 0x89, 0xac, 0xd4, 0x1e, 0xfa, 0x5c, 0xd4, 0x8b, 0xf3, 0xcb, 0x36, 0x6b, 0x9e, 0xad, 0xd7, 0xf9, 0x55, 0x9b, 0xb5, + 0xbb, 0xf6, 0xd9, 0xbd, 0x48, 0x65, 0x40, 0x73, 0xf9, 0x84, 0x67, 0x11, 0x68, 0x67, 0x17, 0x99, 0x09, 0xa7, 0xe0, + 0xa5, 0x69, 0xb2, 0xd4, 0x55, 0x5f, 0x12, 0x8c, 0x4b, 0x89, 0xd5, 0xe3, 0x17, 0xa8, 0xdf, 0x4e, 0x77, 0x5d, 0xa5, + 0x9b, 0xed, 0xe3, 0xe0, 0xc2, 0xa5, 0x40, 0xb8, 0x03, 0x21, 0x0f, 0x40, 0xbf, 0xbb, 0x12, 0x60, 0x1a, 0x04, 0xa8, + 0xac, 0x40, 0xa4, 0xe5, 0xf3, 0xe5, 0xfc, 0x59, 0x41, 0xcd, 0x32, 0x3c, 0xe1, 0x53, 0xae, 0x55, 0x4a, 0x41, 0xba, + 0xdd, 0x97, 0xbe, 0xd9, 0x2f, 0x41, 0x65, 0xb5, 0xf8, 0xbb, 0x89, 0xe6, 0xd9, 0x17, 0xe5, 0x16, 0x0e, 0x61, 0xb3, + 0xb2, 0x02, 0x67, 0x68, 0x83, 0x73, 0x39, 0xa5, 0x05, 0xd7, 0xb3, 0xf9, 0xbf, 0xb5, 0x3a, 0x6c, 0xa0, 0x87, 0xe6, + 0xc2, 0x0a, 0x40, 0x42, 0xc5, 0x78, 0xbd, 0xe6, 0x27, 0xdf, 0xbf, 0x4f, 0xf2, 0x3e, 0xe1, 0x6d, 0xdc, 0xc1, 0xa7, + 0xb8, 0x8b, 0xdb, 0x2d, 0xdc, 0xee, 0xc2, 0xd5, 0x7d, 0x96, 0x2f, 0xc7, 0x4c, 0xc5, 0xf0, 0xfe, 0x9a, 0xbe, 0x4a, + 0x2e, 0x8e, 0xab, 0x57, 0x07, 0x8a, 0xc4, 0xa1, 0x4b, 0x10, 0xfc, 0xde, 0x45, 0x0d, 0x8c, 0xa2, 0x30, 0x64, 0xdd, + 0x22, 0x54, 0x9d, 0x94, 0xfa, 0x85, 0xab, 0xd3, 0x3e, 0xd8, 0x73, 0xdb, 0x95, 0x6d, 0x82, 0xd9, 0xb7, 0xfd, 0x99, + 0x56, 0x3f, 0x9b, 0xba, 0x44, 0x0c, 0x0f, 0xbd, 0x0a, 0x3d, 0xd0, 0x15, 0x69, 0x1f, 0x1d, 0x81, 0xd5, 0x51, 0x30, + 0x1b, 0x6e, 0xa3, 0x1f, 0xf0, 0x66, 0x2d, 0x0d, 0x82, 0x15, 0x80, 0x71, 0xe7, 0x1b, 0x4e, 0x56, 0x16, 0xb6, 0x1a, + 0xa8, 0x30, 0x2b, 0xc2, 0xb8, 0x7a, 0x21, 0xa9, 0x30, 0x42, 0x34, 0x1c, 0x61, 0x2e, 0x18, 0xca, 0x61, 0x0b, 0xcb, + 0xc9, 0x44, 0x31, 0x0d, 0x47, 0x47, 0xc1, 0xbe, 0xb2, 0x42, 0x99, 0x53, 0x64, 0xc4, 0xa6, 0x5c, 0x3c, 0xd4, 0xbf, + 0xb3, 0x42, 0x9a, 0x4f, 0xa3, 0xc1, 0x48, 0x23, 0xb3, 0x8a, 0x11, 0xce, 0x72, 0xbe, 0x80, 0xaa, 0xd3, 0x02, 0x9c, + 0x7e, 0xe0, 0x2f, 0x1f, 0xa7, 0x61, 0x9b, 0x40, 0xbe, 0x7e, 0xb3, 0x31, 0x5d, 0xf0, 0xb8, 0xa0, 0x37, 0xaf, 0xc5, + 0x63, 0xd8, 0x51, 0x0f, 0x0b, 0x46, 0x21, 0x1b, 0x92, 0xde, 0x41, 0x53, 0xf0, 0x01, 0x6d, 0xbe, 0x34, 0x80, 0x4b, + 0x2f, 0xcc, 0x87, 0xad, 0xe8, 0x63, 0x37, 0x26, 0x65, 0x5b, 0x26, 0xd3, 0x9c, 0xd2, 0x55, 0xa6, 0x8d, 0x42, 0x55, + 0x4e, 0x61, 0x83, 0x5d, 0xd4, 0x93, 0x70, 0x30, 0x63, 0xaa, 0x66, 0xe9, 0x60, 0x68, 0xfe, 0xbe, 0xb6, 0x25, 0x5b, + 0xd8, 0x45, 0x9c, 0xd9, 0x60, 0xf3, 0x70, 0x6a, 0x50, 0xbe, 0x8d, 0xe1, 0x1e, 0x16, 0x5e, 0xef, 0xac, 0x91, 0xcf, + 0x33, 0x4f, 0x36, 0xcf, 0x36, 0x1b, 0x33, 0x10, 0x95, 0x82, 0x1e, 0xe8, 0xad, 0xdf, 0x36, 0x2d, 0xd8, 0x1e, 0xe5, + 0x57, 0xb7, 0x85, 0xe7, 0x1c, 0x1e, 0x23, 0xf5, 0xed, 0x5d, 0xeb, 0x42, 0x7e, 0x71, 0x20, 0x69, 0x05, 0x29, 0x76, + 0x3a, 0x41, 0x67, 0xa7, 0x38, 0x18, 0x39, 0xd0, 0xf3, 0xeb, 0x2f, 0x16, 0xd6, 0xfe, 0xf7, 0x9b, 0xb2, 0xa0, 0x89, + 0xa7, 0x53, 0x4e, 0x28, 0xf3, 0xe7, 0xe7, 0x1b, 0x9e, 0x54, 0xa8, 0xe0, 0x5e, 0xf1, 0x82, 0x3d, 0x6d, 0x03, 0x7d, + 0xce, 0xe9, 0x67, 0xfb, 0xc3, 0xc6, 0xf0, 0x29, 0xb5, 0x6c, 0x59, 0x21, 0x95, 0x7a, 0x68, 0xd3, 0xec, 0xd1, 0x03, + 0x47, 0xe4, 0x4b, 0xe8, 0x02, 0x78, 0xfd, 0x71, 0x21, 0x17, 0x06, 0x11, 0xdc, 0x6f, 0x37, 0x6e, 0xe3, 0x2b, 0x00, + 0xde, 0x0e, 0x07, 0xd5, 0x3f, 0x2d, 0x60, 0x7f, 0xa3, 0xb2, 0xa4, 0x1f, 0x6f, 0xc7, 0x1e, 0xff, 0x85, 0x84, 0xa8, + 0xf1, 0x16, 0x0f, 0x13, 0x87, 0x4e, 0x25, 0x6b, 0x56, 0xfe, 0xdc, 0x29, 0x09, 0x18, 0x56, 0x2f, 0x18, 0xb2, 0x71, + 0x3b, 0xc5, 0x6d, 0xe6, 0x7f, 0x50, 0xc1, 0x60, 0xc1, 0xb7, 0x46, 0x52, 0xb1, 0x2c, 0x7e, 0xfb, 0xd4, 0xf9, 0xaf, + 0x3a, 0xc7, 0x75, 0xa8, 0x6b, 0x2f, 0x85, 0x8e, 0x4c, 0x94, 0xe6, 0x08, 0x1d, 0x1d, 0x6d, 0x65, 0xd0, 0x09, 0x00, + 0x1e, 0x39, 0xf6, 0xcb, 0x2f, 0x9f, 0x67, 0xc7, 0x8c, 0xe6, 0xb1, 0x88, 0x42, 0xe6, 0xce, 0x73, 0x73, 0x76, 0x22, + 0x4f, 0xa8, 0x9a, 0xf9, 0xc2, 0x00, 0xc7, 0x47, 0x3b, 0xa9, 0x80, 0xef, 0xd1, 0x66, 0xcf, 0x04, 0xb6, 0xf8, 0x2d, + 0x3b, 0xa9, 0x7d, 0x05, 0xfd, 0x02, 0xad, 0xf6, 0x31, 0x95, 0x5b, 0x0b, 0x1c, 0x6d, 0x4f, 0x64, 0xef, 0xd0, 0xb7, + 0xea, 0x94, 0xac, 0xc7, 0x8b, 0xfd, 0x46, 0x5f, 0x52, 0xec, 0x4b, 0xae, 0x68, 0xdb, 0x88, 0x55, 0xaf, 0x05, 0xeb, + 0xca, 0xd4, 0xa9, 0xba, 0xe6, 0xad, 0x2c, 0x6d, 0x4a, 0xbb, 0x24, 0x7b, 0xb7, 0xc5, 0xc2, 0xab, 0xf0, 0x46, 0xa3, + 0xbc, 0x08, 0x05, 0x7b, 0x2c, 0x31, 0xec, 0x71, 0x02, 0xd7, 0x0b, 0xeb, 0x75, 0x0c, 0x7f, 0xf6, 0x8d, 0x61, 0x9f, + 0xe9, 0xd2, 0x7b, 0xbe, 0xc5, 0xaf, 0x04, 0x01, 0x8b, 0x9d, 0x1d, 0x24, 0x58, 0x77, 0xb9, 0x41, 0xc3, 0x71, 0xe2, + 0xbf, 0xe0, 0xb9, 0x6c, 0xed, 0x5d, 0x0e, 0xe6, 0xd9, 0x37, 0x9e, 0xd8, 0x2b, 0x59, 0xcb, 0x5a, 0xb4, 0xfb, 0x2d, + 0x09, 0x86, 0xd8, 0x4d, 0xe9, 0x1c, 0xb7, 0x92, 0x36, 0x8a, 0x5c, 0xb1, 0x0a, 0xfd, 0xbf, 0x55, 0x24, 0xb3, 0x99, + 0xff, 0x75, 0x7e, 0x7e, 0xee, 0x52, 0x9c, 0xcd, 0x9f, 0x32, 0x1e, 0x70, 0x26, 0x81, 0x7d, 0xe5, 0x19, 0x33, 0x3a, + 0xe4, 0xb7, 0x30, 0x14, 0x22, 0xc8, 0x95, 0x70, 0xec, 0x12, 0xbc, 0xf6, 0x08, 0x94, 0x07, 0xd8, 0xbf, 0x27, 0x5b, + 0xe5, 0xfc, 0x73, 0x51, 0x3e, 0x9c, 0x72, 0xd9, 0x20, 0xfb, 0x6a, 0x3e, 0x07, 0xd6, 0x4c, 0x06, 0x5e, 0x48, 0x88, + 0xb0, 0xfd, 0x6d, 0x58, 0x5a, 0x67, 0x29, 0x83, 0x23, 0x2d, 0x97, 0xd9, 0xcc, 0x6a, 0xfe, 0xdd, 0x87, 0x29, 0xeb, + 0x9e, 0x1a, 0x82, 0xc8, 0x5d, 0x64, 0xe5, 0xa2, 0x82, 0x46, 0x3f, 0x96, 0x01, 0x40, 0x0f, 0x5e, 0xb1, 0x25, 0xfb, + 0x11, 0x1f, 0x54, 0x29, 0xf0, 0xf1, 0xb0, 0xe0, 0x34, 0xff, 0x11, 0x1f, 0x54, 0x81, 0x40, 0xc1, 0x15, 0xd2, 0xc4, + 0xd2, 0xc4, 0xe6, 0x59, 0xed, 0x34, 0x12, 0x40, 0x41, 0xf3, 0xc8, 0x1c, 0x64, 0xcf, 0x5d, 0x8c, 0xc6, 0xa4, 0x83, + 0x5d, 0x70, 0x30, 0x1b, 0x11, 0xd6, 0x06, 0x52, 0x87, 0xb8, 0x75, 0xe5, 0x6c, 0xcc, 0xd7, 0xa3, 0xad, 0x05, 0x31, + 0xca, 0x64, 0x72, 0xf5, 0x9c, 0xc7, 0x3b, 0x8b, 0x85, 0xc2, 0x6a, 0xc1, 0x02, 0xd5, 0xaa, 0x54, 0xe9, 0x61, 0xf1, + 0xdd, 0x82, 0x59, 0x50, 0xc4, 0x6c, 0xbd, 0x87, 0xb7, 0x5c, 0x11, 0x90, 0x92, 0x5d, 0x12, 0xbc, 0x8c, 0x6e, 0x30, + 0x95, 0xac, 0xe6, 0x72, 0xcc, 0x2c, 0xa1, 0x67, 0x4a, 0x47, 0xd8, 0xe4, 0x29, 0x88, 0x24, 0x76, 0xd8, 0xc2, 0x8e, + 0x35, 0x7a, 0x21, 0xbc, 0x90, 0x02, 0xe7, 0xaa, 0x69, 0x62, 0x4e, 0xb9, 0x89, 0x2e, 0xf6, 0x50, 0x2d, 0x58, 0xa6, + 0x2d, 0x02, 0x1c, 0x3a, 0x34, 0x94, 0xe2, 0xb9, 0x01, 0x85, 0x79, 0xd2, 0xdb, 0xa5, 0x3c, 0x86, 0xc5, 0x0b, 0x52, + 0x80, 0xa8, 0x71, 0x31, 0x2d, 0xeb, 0x2c, 0xf2, 0xe5, 0x94, 0x8b, 0x0a, 0x19, 0x0a, 0xa6, 0x16, 0x52, 0xc0, 0x8b, + 0x1a, 0x65, 0x11, 0x43, 0x87, 0x6a, 0xf8, 0x6e, 0x49, 0x58, 0x59, 0xc7, 0x1c, 0x53, 0x5c, 0x54, 0x35, 0x80, 0xb9, + 0x78, 0x68, 0x04, 0x44, 0x1f, 0x5e, 0xf6, 0xb5, 0x78, 0x27, 0x17, 0x55, 0xbe, 0xa7, 0x71, 0x3e, 0x70, 0xbd, 0xb3, + 0x1b, 0x46, 0x1b, 0xf3, 0xe8, 0x55, 0xb0, 0x7d, 0xdf, 0xf3, 0xea, 0x21, 0xb8, 0x8d, 0x79, 0x36, 0xab, 0xcc, 0x1a, + 0xb1, 0xf2, 0x8d, 0x88, 0xaa, 0xbd, 0x7a, 0x55, 0x29, 0x6c, 0x45, 0x80, 0x4a, 0xc1, 0xc7, 0x3b, 0xf9, 0x2f, 0xb4, + 0xcd, 0xb7, 0xe7, 0x50, 0x19, 0x1e, 0xc8, 0x93, 0xa1, 0xaa, 0x07, 0x5c, 0x94, 0x1f, 0x02, 0x58, 0xfc, 0xc8, 0xc4, + 0x0f, 0xde, 0x77, 0x81, 0xcc, 0x99, 0x8a, 0x25, 0x5e, 0x0d, 0xe8, 0x30, 0xb5, 0xf2, 0x50, 0x2a, 0xc1, 0xb6, 0xe7, + 0xa6, 0xe0, 0xda, 0x07, 0x2a, 0xc6, 0x03, 0x36, 0x4c, 0x57, 0xf5, 0x60, 0xc6, 0x36, 0x9c, 0xb2, 0x37, 0xe7, 0x34, + 0xd1, 0x7f, 0xe9, 0x10, 0xe7, 0x04, 0x6c, 0x8f, 0x3d, 0x7b, 0xfa, 0x26, 0xce, 0x50, 0xbf, 0xce, 0xe1, 0xaf, 0x36, + 0x38, 0xc7, 0x19, 0x4a, 0x1f, 0xc6, 0x70, 0x81, 0xb5, 0xc1, 0x00, 0xbe, 0xcc, 0x92, 0x2a, 0xf0, 0x48, 0xcd, 0x8c, + 0xc4, 0xea, 0x2e, 0x02, 0xd1, 0x4a, 0x87, 0xb7, 0xe3, 0xcc, 0x87, 0x03, 0x37, 0xdc, 0xeb, 0x33, 0x23, 0x1c, 0xce, + 0xb3, 0xb8, 0x76, 0xce, 0x70, 0x72, 0x75, 0xc8, 0x6b, 0x27, 0x26, 0x58, 0x7b, 0x87, 0xa7, 0x0a, 0xe8, 0xd1, 0xe0, + 0x54, 0xb1, 0x34, 0x04, 0x62, 0x26, 0x80, 0x37, 0x73, 0x78, 0xb4, 0x05, 0x38, 0x1f, 0x6d, 0x70, 0xf0, 0x95, 0xd6, + 0xba, 0xda, 0x56, 0xa2, 0x6c, 0x36, 0x78, 0x30, 0xce, 0xf0, 0x32, 0xc3, 0xd3, 0x6c, 0x18, 0x1e, 0x37, 0x59, 0x68, + 0xd2, 0xb5, 0x5e, 0x3f, 0x75, 0x66, 0x84, 0xc8, 0xfe, 0xb4, 0xf4, 0x07, 0xf5, 0x01, 0xe1, 0x53, 0xc8, 0x02, 0x5a, + 0xd2, 0x77, 0x7f, 0x1b, 0xf6, 0xb5, 0x70, 0xd4, 0x88, 0x79, 0x62, 0xc9, 0x48, 0xdf, 0xff, 0x28, 0xb3, 0x6c, 0x6b, + 0x8d, 0x68, 0x71, 0x7b, 0x10, 0x35, 0x7c, 0x7b, 0xd5, 0xf9, 0x32, 0x2a, 0xcd, 0x76, 0x00, 0x51, 0xac, 0x71, 0x92, + 0x0e, 0xd6, 0x48, 0xae, 0xd7, 0xb1, 0x4d, 0x21, 0x3c, 0x99, 0x33, 0xaa, 0x96, 0x85, 0x79, 0x40, 0x2f, 0x56, 0x28, + 0x31, 0xfc, 0x2e, 0x76, 0x36, 0xa2, 0xf0, 0x5e, 0x9d, 0x04, 0xc3, 0x8d, 0x58, 0x10, 0x59, 0x13, 0xb9, 0x3f, 0x65, + 0x95, 0x65, 0x90, 0x20, 0xc2, 0x88, 0xfc, 0xf6, 0xba, 0x54, 0xd8, 0x27, 0xfa, 0xec, 0x1f, 0xe3, 0x0b, 0x08, 0x37, + 0x6f, 0x53, 0x5a, 0x8c, 0xe8, 0x14, 0xd8, 0x58, 0x88, 0x43, 0xb8, 0x93, 0xb0, 0x5e, 0x0f, 0x86, 0x3d, 0x61, 0xc8, + 0xb3, 0x7b, 0x40, 0xb0, 0x6c, 0x68, 0x7f, 0x03, 0x70, 0xd5, 0x6d, 0xa9, 0xb9, 0x36, 0xba, 0x1f, 0x6a, 0xde, 0x38, + 0xe3, 0x2e, 0xc9, 0x3d, 0x53, 0x52, 0xbd, 0x44, 0x5e, 0xb3, 0x00, 0x37, 0xa1, 0xab, 0xf0, 0x18, 0x2f, 0xad, 0x0d, + 0xa7, 0x79, 0xd0, 0x8a, 0x9a, 0x77, 0xac, 0xe0, 0xf9, 0x6c, 0xc2, 0x06, 0xd9, 0x10, 0x8f, 0x7d, 0xb8, 0xf3, 0xc3, + 0xb7, 0xf1, 0x18, 0xa1, 0x82, 0x18, 0x98, 0x5a, 0x97, 0xed, 0x71, 0x65, 0xb7, 0x6f, 0x32, 0x0d, 0xc3, 0x60, 0x8c, + 0x98, 0xc7, 0xa1, 0x11, 0x73, 0xde, 0x68, 0xa0, 0x25, 0x19, 0x83, 0x11, 0xf3, 0x32, 0x68, 0x6d, 0x69, 0x1f, 0x3b, + 0x0d, 0xda, 0x5b, 0x22, 0xd4, 0xe3, 0x40, 0xd3, 0x34, 0x3c, 0x6b, 0x52, 0x3d, 0x2b, 0xef, 0x1f, 0xd9, 0x3a, 0xe9, + 0x80, 0x22, 0x61, 0x72, 0xe5, 0x27, 0x61, 0x5d, 0xc3, 0xed, 0xb8, 0x27, 0x66, 0xdc, 0xce, 0xb6, 0x41, 0x0d, 0xe4, + 0x20, 0x1b, 0x0e, 0x7b, 0xd2, 0x5b, 0x49, 0xb4, 0xf0, 0xa4, 0x7a, 0x08, 0xa5, 0x5a, 0xbc, 0xaf, 0x7a, 0xfb, 0xca, + 0x9b, 0xfb, 0xf7, 0x55, 0xb7, 0xcf, 0x63, 0xe0, 0x80, 0x0e, 0xe1, 0x7e, 0xa8, 0x8a, 0x0f, 0x76, 0xd2, 0x81, 0x28, + 0x68, 0x69, 0xab, 0x26, 0x90, 0x5a, 0x33, 0xbb, 0x58, 0x37, 0x15, 0x3a, 0x16, 0x10, 0x86, 0x4c, 0x55, 0xdd, 0xdd, + 0xaa, 0x40, 0x35, 0xc4, 0xe1, 0xd4, 0x7f, 0x6c, 0x8d, 0x58, 0xe3, 0xa8, 0x33, 0x8e, 0x8c, 0x91, 0xa4, 0x5d, 0x3e, + 0x78, 0xfb, 0x08, 0xac, 0x04, 0x7c, 0x0c, 0x6a, 0x93, 0x64, 0x0c, 0x09, 0xde, 0xb2, 0x4c, 0x1b, 0x3e, 0x84, 0x3b, + 0x04, 0xe5, 0x89, 0x0d, 0x4a, 0xeb, 0x2a, 0x59, 0xc8, 0x55, 0x5d, 0xde, 0x05, 0xe8, 0x79, 0x5b, 0xfe, 0xc6, 0x86, + 0x23, 0x0b, 0x06, 0x96, 0xed, 0xec, 0x13, 0xf0, 0xc8, 0xc7, 0x15, 0x82, 0xf8, 0xa5, 0xd0, 0x89, 0x89, 0xd7, 0x7d, + 0x0d, 0x1b, 0x14, 0x2f, 0xc0, 0x41, 0xd0, 0x49, 0x70, 0x18, 0xbc, 0xcb, 0xac, 0x26, 0xd9, 0xe0, 0xd6, 0x9c, 0xc4, + 0x8b, 0xf5, 0xba, 0x85, 0x8e, 0xff, 0x69, 0x9e, 0xa4, 0x9e, 0x94, 0x0a, 0xf7, 0x49, 0xa5, 0x70, 0x07, 0x4b, 0x40, + 0x32, 0x09, 0x74, 0xed, 0x58, 0x86, 0x6a, 0x74, 0x88, 0x96, 0xfe, 0x02, 0x62, 0x67, 0xbb, 0x63, 0x09, 0xf4, 0xec, + 0x3b, 0x05, 0xac, 0xae, 0xbd, 0x2c, 0x81, 0x8c, 0xe0, 0xee, 0x37, 0x81, 0x51, 0x21, 0x1a, 0x9f, 0x3f, 0xf3, 0xaa, + 0x05, 0x4f, 0x9c, 0x3f, 0xd7, 0xdc, 0xb0, 0xee, 0x05, 0xbd, 0x31, 0xcd, 0xc7, 0x13, 0xdc, 0x9c, 0x58, 0x70, 0x9e, + 0x74, 0xe0, 0xa7, 0x85, 0xe8, 0x49, 0x07, 0xbb, 0x54, 0x3c, 0x29, 0x81, 0x1c, 0xa2, 0xa7, 0x33, 0x90, 0x02, 0x56, + 0x3a, 0xb6, 0x5a, 0xa4, 0x29, 0x5a, 0xaf, 0xa7, 0x97, 0xa4, 0x85, 0xd0, 0x4a, 0xdd, 0x70, 0x9d, 0xcd, 0xc0, 0x47, + 0x1a, 0x14, 0x03, 0x6f, 0xa8, 0x9e, 0xc5, 0x08, 0x4f, 0xd0, 0x6a, 0xcc, 0x26, 0x74, 0x99, 0xeb, 0x54, 0xf5, 0x79, + 0x62, 0x03, 0xf7, 0x32, 0x1b, 0x09, 0xee, 0xa4, 0x83, 0xa7, 0x86, 0xbf, 0xfc, 0x60, 0xcc, 0x41, 0x8a, 0xcc, 0x24, + 0x4f, 0x4d, 0x02, 0xe6, 0x49, 0x96, 0x4b, 0xc5, 0x6c, 0x33, 0x3d, 0x6b, 0x5b, 0x0e, 0x21, 0xc9, 0x23, 0x5d, 0x70, + 0x63, 0x45, 0x19, 0xa5, 0x33, 0xa2, 0xfa, 0xea, 0xa4, 0x93, 0x4e, 0x31, 0x4f, 0x80, 0xd3, 0x7b, 0x27, 0x63, 0xd6, + 0x28, 0x6f, 0x45, 0xe7, 0xe8, 0x78, 0x86, 0x45, 0x75, 0x89, 0x3a, 0x47, 0xc7, 0x53, 0x84, 0xe7, 0x0d, 0x32, 0x53, + 0xe0, 0x31, 0xcc, 0xc5, 0xff, 0x91, 0xf2, 0xdf, 0x1c, 0x36, 0x84, 0x98, 0x7e, 0x0b, 0x3b, 0x85, 0x8d, 0xa3, 0x34, + 0x27, 0xe0, 0xb5, 0xd8, 0x3e, 0xc7, 0x19, 0x99, 0x36, 0x73, 0x1f, 0x70, 0xcf, 0xb4, 0xd2, 0xb8, 0xd5, 0xe8, 0x38, + 0xc3, 0xe3, 0xed, 0xa4, 0xd8, 0xcc, 0xb5, 0x99, 0xa7, 0x19, 0x9c, 0xef, 0xd5, 0x28, 0x5c, 0xf9, 0xe5, 0x76, 0x52, + 0x58, 0xde, 0x01, 0xb7, 0x39, 0xc6, 0xa2, 0x49, 0x71, 0x8e, 0xe7, 0xcd, 0x57, 0x78, 0xde, 0x7c, 0x5f, 0x66, 0x34, + 0x96, 0x58, 0x40, 0xf0, 0x3e, 0x48, 0xc4, 0xf3, 0x2a, 0x79, 0x8c, 0x45, 0xc3, 0x94, 0xc7, 0xf3, 0x46, 0x55, 0xba, + 0xb9, 0xc4, 0xa2, 0x61, 0x4a, 0x37, 0xde, 0xe3, 0x79, 0xe3, 0xd5, 0xbf, 0x98, 0x74, 0x94, 0x02, 0xba, 0x2c, 0xd0, + 0x2a, 0xb3, 0x43, 0xbc, 0xfe, 0xf5, 0xed, 0xbb, 0xf6, 0xa7, 0xce, 0xf1, 0x14, 0xfb, 0xf5, 0xcb, 0x0c, 0x8e, 0x65, + 0x3a, 0x66, 0x4d, 0x80, 0x68, 0x86, 0x3b, 0xc7, 0x33, 0xdc, 0x39, 0xce, 0x5c, 0x53, 0x9b, 0x79, 0x83, 0xdc, 0xea, + 0x10, 0x8a, 0x3a, 0x4a, 0x43, 0xf8, 0xf8, 0xc9, 0xa6, 0x53, 0x54, 0x03, 0x25, 0x3a, 0x9e, 0xd6, 0x40, 0x05, 0xdf, + 0xcb, 0xda, 0x77, 0x55, 0xaf, 0xc2, 0x20, 0x0b, 0x25, 0x14, 0xae, 0xb9, 0x01, 0x4f, 0x2d, 0xc5, 0x40, 0x26, 0x4c, + 0xb1, 0x40, 0xf9, 0x0e, 0x28, 0x8c, 0xf2, 0xc4, 0x0c, 0x3d, 0x98, 0x8e, 0x49, 0xfc, 0xff, 0x79, 0x32, 0xe5, 0xd0, + 0xcb, 0x2d, 0xb3, 0x33, 0x3d, 0x37, 0x99, 0x70, 0xf8, 0xc0, 0x63, 0xfd, 0x5f, 0x3b, 0x50, 0x6c, 0x40, 0x8a, 0xff, + 0x2f, 0x1d, 0x5d, 0x08, 0x46, 0xc8, 0x8a, 0xd2, 0xc2, 0x21, 0xfe, 0xf7, 0x87, 0x15, 0x74, 0x5f, 0xec, 0x74, 0x5f, + 0x98, 0xee, 0xc3, 0xa6, 0x8d, 0x2a, 0x27, 0xad, 0x2a, 0x59, 0xf2, 0x5f, 0xa7, 0x5b, 0x3b, 0xa0, 0x11, 0x35, 0x7a, + 0x36, 0x0d, 0x1b, 0x3c, 0x6c, 0xa7, 0x7b, 0x90, 0x79, 0xc3, 0xed, 0x0b, 0xa9, 0x70, 0xf8, 0x06, 0x77, 0xaa, 0x57, + 0x2d, 0xf0, 0xde, 0x54, 0x46, 0x5f, 0x19, 0x87, 0x96, 0x83, 0x74, 0xdb, 0x94, 0xdb, 0x18, 0x4b, 0x27, 0x5d, 0x6c, + 0x5c, 0x11, 0xa1, 0xd2, 0xed, 0x15, 0x28, 0xc5, 0x27, 0xba, 0xc9, 0xcc, 0xd7, 0xa5, 0x4e, 0xcc, 0x25, 0x54, 0xc3, + 0x7c, 0xde, 0x5d, 0xe9, 0x44, 0xcb, 0x85, 0xcd, 0xbb, 0xbb, 0x84, 0x3e, 0x41, 0xc3, 0xda, 0x08, 0xec, 0xf6, 0xb9, + 0xb3, 0x83, 0x0c, 0x0e, 0xc1, 0xf0, 0x00, 0x72, 0xa4, 0xc5, 0xf6, 0x81, 0x4d, 0x6b, 0xd8, 0x75, 0xd1, 0x2c, 0x13, + 0x6d, 0xab, 0x4d, 0x93, 0x6b, 0xf7, 0x30, 0x5f, 0x84, 0x3c, 0x85, 0x28, 0xac, 0x7e, 0x7c, 0x0f, 0xbb, 0xf1, 0xb5, + 0xc6, 0x48, 0xd4, 0x95, 0x4c, 0x25, 0xf4, 0x93, 0x5b, 0xcc, 0x92, 0x3b, 0xe3, 0xc5, 0xa8, 0x8c, 0xbf, 0x8f, 0x89, + 0xcb, 0x1f, 0x55, 0x92, 0x1c, 0x58, 0xf6, 0x37, 0x58, 0x72, 0x0b, 0xe6, 0x89, 0x65, 0x35, 0x89, 0x75, 0x72, 0x17, + 0x2c, 0xa2, 0x34, 0x8d, 0x6c, 0x0c, 0x03, 0x6a, 0x9a, 0xb1, 0xea, 0xc1, 0x43, 0x08, 0xf4, 0xd0, 0x2f, 0x4b, 0x69, + 0xd7, 0x59, 0x5a, 0xeb, 0x5e, 0x9b, 0xee, 0xb7, 0x07, 0x54, 0x4d, 0xe3, 0x26, 0xe0, 0x9a, 0xfe, 0xd5, 0x24, 0x92, + 0x11, 0xfb, 0x9b, 0xb3, 0xe2, 0xf1, 0xb2, 0x30, 0x98, 0x26, 0xfa, 0x3a, 0xc9, 0x16, 0x6d, 0x30, 0xd5, 0xcb, 0x16, + 0x9d, 0x5b, 0xec, 0xbe, 0xef, 0xec, 0xf7, 0x1d, 0x16, 0x7d, 0x66, 0x32, 0x52, 0x66, 0x8a, 0xf9, 0xef, 0x3b, 0xfb, + 0x7d, 0x87, 0x77, 0x07, 0xf3, 0xc5, 0x5f, 0x28, 0x96, 0xec, 0x0c, 0x97, 0x60, 0x42, 0x1e, 0x70, 0x37, 0xb5, 0x2c, + 0x13, 0x04, 0xb6, 0x96, 0x00, 0x71, 0x3e, 0x9f, 0xc6, 0x15, 0xaf, 0x86, 0x80, 0xfb, 0xf4, 0xae, 0xed, 0x55, 0x2a, + 0xf0, 0x98, 0xa0, 0x11, 0x31, 0xb1, 0x6d, 0xcc, 0xeb, 0x66, 0xc0, 0xe5, 0x11, 0x5d, 0xea, 0x49, 0x12, 0xe0, 0x55, + 0x8d, 0xca, 0xdb, 0x14, 0x29, 0xbf, 0x48, 0x90, 0xe3, 0x8b, 0x3d, 0xa2, 0x8a, 0x01, 0xac, 0xca, 0x92, 0x3e, 0x81, + 0xd4, 0xf3, 0x43, 0x4f, 0xcd, 0x6d, 0xe4, 0xb1, 0xef, 0xfc, 0x7e, 0x61, 0x7a, 0x56, 0xc8, 0xe5, 0x74, 0x06, 0x3e, + 0xb4, 0xc0, 0x32, 0x14, 0xa6, 0x5e, 0x65, 0xeb, 0x5f, 0x93, 0xdc, 0x04, 0x50, 0x38, 0xdd, 0x94, 0x09, 0xcd, 0xf4, + 0x92, 0xe6, 0xc6, 0x92, 0x94, 0x8b, 0xe9, 0x23, 0x79, 0xfb, 0x12, 0xb0, 0x9b, 0x12, 0xdd, 0xd8, 0x93, 0xf7, 0x16, + 0x76, 0x00, 0xce, 0x08, 0xdb, 0x57, 0xf1, 0xa1, 0x02, 0x9d, 0x3f, 0xce, 0x09, 0xdb, 0x57, 0xf5, 0x09, 0xb3, 0xd9, + 0x33, 0xb2, 0x35, 0xdc, 0x7e, 0x9c, 0x35, 0x72, 0x74, 0xd2, 0x49, 0xf3, 0x9e, 0x27, 0x06, 0x16, 0xa0, 0x01, 0x70, + 0x77, 0xb6, 0x67, 0x79, 0x77, 0x43, 0x40, 0xef, 0x92, 0x49, 0x7b, 0x5d, 0x6e, 0x52, 0xd6, 0xeb, 0x4e, 0x45, 0x05, + 0x0b, 0x3c, 0x0b, 0xf6, 0x02, 0xb5, 0x5f, 0x7b, 0x28, 0xce, 0x2f, 0xd9, 0xb6, 0xe9, 0x79, 0xd9, 0x77, 0x6f, 0xcf, + 0x22, 0x63, 0x9b, 0xf6, 0x76, 0x0f, 0x91, 0xb0, 0x9c, 0xb0, 0x0e, 0x38, 0xe1, 0xaa, 0x76, 0x40, 0x80, 0x3e, 0x05, + 0x22, 0x37, 0x96, 0x64, 0xb5, 0xa9, 0x8c, 0xee, 0x03, 0xbf, 0x5b, 0x4a, 0xa4, 0x1b, 0x6d, 0x49, 0x30, 0x7d, 0x82, + 0x51, 0xd3, 0x99, 0xa7, 0xa9, 0x6b, 0xaf, 0x2e, 0x6f, 0x8b, 0xb6, 0xfe, 0x0d, 0x68, 0x6c, 0xb6, 0x87, 0x89, 0xa1, + 0x0c, 0x62, 0xa0, 0xf7, 0x11, 0xef, 0x35, 0x1a, 0x19, 0x02, 0x85, 0x4c, 0x36, 0xc4, 0x32, 0xf1, 0x5a, 0xf4, 0xa3, + 0x23, 0x03, 0x8f, 0x2a, 0x01, 0x61, 0x0a, 0x42, 0x48, 0xd8, 0xb5, 0x41, 0xd8, 0x70, 0xb9, 0x6a, 0xb9, 0xb0, 0x91, + 0x6a, 0x43, 0x07, 0xff, 0xaf, 0x70, 0xd9, 0xea, 0x99, 0xe5, 0xa2, 0x18, 0xdc, 0xcc, 0x0d, 0x58, 0x24, 0x48, 0x8f, + 0x36, 0xdb, 0x43, 0x71, 0x7f, 0x2e, 0x36, 0x1b, 0x02, 0x12, 0x73, 0x98, 0xa0, 0x68, 0x38, 0x37, 0xc6, 0x58, 0x25, + 0x95, 0x96, 0xb5, 0x26, 0x31, 0x07, 0x01, 0xa3, 0xc3, 0x75, 0x5f, 0xdd, 0xa6, 0x0c, 0xdf, 0xa5, 0x02, 0xdf, 0x80, + 0x27, 0x4d, 0x2a, 0xb1, 0x7b, 0xbc, 0xa0, 0xd8, 0x10, 0xdd, 0xf3, 0xec, 0x6d, 0x01, 0xeb, 0x6c, 0xf6, 0x88, 0x08, + 0x7e, 0x57, 0xbf, 0xda, 0xe0, 0xbb, 0x85, 0x5f, 0x81, 0xf5, 0x73, 0x70, 0x92, 0x62, 0xd1, 0x90, 0xcd, 0xc2, 0x1d, + 0x19, 0x50, 0xae, 0xe2, 0x97, 0xc3, 0xd4, 0x9d, 0x62, 0xb8, 0xf6, 0xf1, 0x0a, 0xbf, 0xdf, 0x6a, 0xb7, 0xa1, 0xca, + 0xe2, 0x76, 0x6f, 0x8a, 0x86, 0xac, 0x9a, 0xde, 0x93, 0xb9, 0x95, 0x52, 0xff, 0x7a, 0x8f, 0x5b, 0x3b, 0xed, 0xfb, + 0x69, 0xbe, 0xf5, 0xe8, 0x5c, 0x35, 0xed, 0x53, 0x6b, 0x45, 0x70, 0xf0, 0xb3, 0x85, 0x9b, 0x3b, 0x03, 0x0e, 0xe0, + 0xe7, 0xef, 0x68, 0x5e, 0x67, 0x10, 0x9d, 0xde, 0x6a, 0xc6, 0xd7, 0xf1, 0x1f, 0xe3, 0x46, 0xdc, 0x4f, 0xff, 0x48, + 0xfe, 0x18, 0x37, 0x50, 0x1f, 0xc5, 0x8b, 0xdb, 0x35, 0x9b, 0xaf, 0x21, 0xd8, 0xda, 0xbd, 0x13, 0xfc, 0x26, 0x2c, + 0xc9, 0x35, 0xcd, 0x79, 0xb6, 0x76, 0x0f, 0x02, 0xae, 0xdd, 0xab, 0x44, 0x6b, 0xf3, 0xc6, 0xd5, 0x3a, 0x96, 0xa3, + 0x1c, 0x02, 0x0b, 0xc7, 0x07, 0xcd, 0xfe, 0xa0, 0xd5, 0x7c, 0x30, 0xb4, 0xff, 0x9a, 0x08, 0xf7, 0xa8, 0x16, 0xb1, + 0xed, 0xde, 0xd6, 0xd6, 0x8f, 0xc1, 0xb0, 0x03, 0x42, 0x81, 0x83, 0x5c, 0xfa, 0x3a, 0x43, 0xd6, 0xf7, 0x64, 0xbd, + 0x66, 0x2e, 0x9a, 0xb5, 0xd3, 0xe0, 0x97, 0xb1, 0x99, 0x8e, 0xdb, 0x49, 0xa7, 0xe7, 0xc5, 0x58, 0xd2, 0x80, 0x48, + 0xd3, 0x98, 0x41, 0x20, 0xa9, 0x95, 0xe1, 0xb0, 0x16, 0xb7, 0x51, 0x5a, 0xdd, 0x1f, 0x41, 0xca, 0x0f, 0x51, 0xca, + 0x4f, 0x08, 0x04, 0xd0, 0xb6, 0xcc, 0x51, 0xd9, 0x90, 0xf7, 0x5d, 0x7a, 0x68, 0x9c, 0x19, 0x1a, 0x7c, 0xbd, 0x6e, + 0x55, 0xc3, 0x54, 0x45, 0x7d, 0x98, 0xab, 0x0d, 0x16, 0xe4, 0x0d, 0xe8, 0x9a, 0x15, 0x11, 0xfd, 0xd0, 0x55, 0x1e, + 0xde, 0x43, 0xc6, 0x92, 0x80, 0x93, 0x7e, 0x5f, 0xf4, 0x0b, 0x72, 0xf5, 0x30, 0x06, 0x1f, 0x33, 0xcc, 0x07, 0x7a, + 0x50, 0x0c, 0x87, 0x28, 0x75, 0x4e, 0x67, 0xa9, 0x89, 0xb8, 0x12, 0xf8, 0x25, 0x17, 0xe0, 0x97, 0xac, 0x10, 0x1b, + 0x14, 0x43, 0xf2, 0x30, 0x8b, 0x25, 0x38, 0xe5, 0xef, 0xf1, 0x79, 0x7c, 0x1a, 0x1a, 0x98, 0x9a, 0x61, 0x99, 0x8b, + 0x6c, 0xb0, 0x98, 0xb3, 0x96, 0x40, 0x70, 0x33, 0xe0, 0x2e, 0xb5, 0x21, 0xd1, 0x58, 0x03, 0x45, 0xb7, 0x51, 0x68, + 0x66, 0xf4, 0x62, 0xa7, 0x8d, 0x41, 0xe4, 0xf0, 0xc2, 0x5c, 0xc3, 0x58, 0x04, 0x32, 0x97, 0xab, 0x1e, 0xfb, 0xcb, + 0x0f, 0x9b, 0x15, 0x06, 0xaf, 0xc8, 0x74, 0xe8, 0x8e, 0x63, 0xc6, 0x57, 0x79, 0xe2, 0x18, 0x82, 0x4c, 0x2c, 0x95, + 0x6e, 0x38, 0x26, 0xae, 0xa4, 0xcf, 0xc4, 0x90, 0xed, 0x86, 0x67, 0xe6, 0x42, 0x37, 0xdb, 0x7f, 0x3a, 0xb7, 0x73, + 0x4e, 0xb8, 0xd1, 0x4a, 0x1a, 0x6d, 0xd4, 0x33, 0x43, 0x55, 0x5d, 0x30, 0xbf, 0x87, 0x4e, 0x4b, 0x8b, 0x9d, 0xab, + 0x77, 0x2f, 0x7c, 0x9d, 0xaf, 0x8c, 0xbf, 0xc5, 0xaa, 0xd0, 0x8a, 0x0c, 0xb7, 0x5b, 0xc8, 0x9b, 0x33, 0x3d, 0xf4, + 0x8a, 0x5c, 0xa8, 0x0e, 0x7f, 0x51, 0x4f, 0x98, 0x07, 0x3b, 0xa3, 0x86, 0xf0, 0xe8, 0xf7, 0x26, 0x03, 0xe5, 0x1f, + 0x4c, 0x4c, 0xe6, 0x2c, 0xb9, 0xa1, 0x85, 0x88, 0x7f, 0x7c, 0x21, 0x4c, 0xac, 0xaa, 0x03, 0x18, 0xc8, 0x81, 0xa9, + 0x78, 0x00, 0xb7, 0x26, 0x7c, 0xc2, 0xd9, 0x38, 0x3d, 0x88, 0x7e, 0x6c, 0x88, 0xc6, 0x8f, 0xd1, 0x8f, 0xe0, 0xee, + 0xec, 0x5e, 0x87, 0x2c, 0xe3, 0x42, 0xf8, 0x7b, 0xac, 0x87, 0xa5, 0x4a, 0x19, 0x6b, 0xaf, 0x5b, 0x0e, 0x2f, 0xa4, + 0xee, 0x65, 0xf1, 0x43, 0x47, 0xac, 0x6d, 0x0a, 0xd6, 0x21, 0x25, 0x85, 0x67, 0x57, 0xcc, 0xad, 0x16, 0x73, 0x97, + 0x5a, 0xc2, 0x5f, 0x5f, 0x3d, 0x2c, 0x55, 0xd0, 0x70, 0x10, 0xba, 0xd2, 0x16, 0x12, 0x60, 0xe0, 0x52, 0xfa, 0x74, + 0xba, 0x33, 0x89, 0x8c, 0xb2, 0x18, 0xde, 0x3d, 0x08, 0x02, 0x09, 0xb0, 0xad, 0xb0, 0x2a, 0x70, 0xb9, 0x52, 0x45, + 0xbd, 0x94, 0x04, 0x02, 0xd0, 0x97, 0xde, 0x83, 0xf2, 0xb2, 0xe8, 0x35, 0x1a, 0x12, 0xb4, 0xb0, 0xd4, 0x5c, 0xab, + 0x62, 0x7a, 0x18, 0xbe, 0x6a, 0x18, 0x7c, 0x78, 0x87, 0xb4, 0xad, 0xa7, 0x45, 0x29, 0xa1, 0x76, 0x07, 0x1d, 0x82, + 0x55, 0x76, 0x50, 0xfe, 0x6d, 0x4c, 0x91, 0xcd, 0x1f, 0xb0, 0x1f, 0xa8, 0xeb, 0x70, 0xe8, 0x0a, 0x56, 0xbd, 0x94, + 0x51, 0x30, 0x60, 0xe5, 0x14, 0xa8, 0xbd, 0x93, 0x8c, 0x66, 0x33, 0x06, 0xea, 0x7e, 0x5b, 0xb4, 0x9a, 0xdb, 0x93, + 0xba, 0xdf, 0x90, 0x71, 0xf6, 0x11, 0xc6, 0xd9, 0x47, 0x81, 0x17, 0x8b, 0x24, 0x3f, 0xcb, 0x58, 0xe3, 0x58, 0x35, + 0x05, 0x3a, 0xe9, 0x00, 0x77, 0x06, 0x0e, 0x3c, 0x60, 0x8b, 0x72, 0x74, 0x44, 0x9d, 0xc5, 0x3d, 0x6d, 0x64, 0xde, + 0xdb, 0x13, 0x6a, 0x17, 0xb1, 0xc0, 0xcd, 0x9a, 0x99, 0x16, 0xb4, 0x56, 0x18, 0xe7, 0xf1, 0x30, 0x22, 0x63, 0x2d, + 0x7e, 0xc2, 0x96, 0x35, 0x55, 0xfd, 0x06, 0x9a, 0xa3, 0x5a, 0x90, 0x9b, 0x17, 0xc6, 0x5b, 0x95, 0x0c, 0xa2, 0x68, + 0x68, 0x39, 0x15, 0x62, 0x48, 0xc6, 0xa0, 0x35, 0x0c, 0x6e, 0xb5, 0xd7, 0x6b, 0xee, 0x11, 0x5f, 0xd4, 0xbc, 0xd5, + 0xcc, 0x2d, 0x40, 0x56, 0xc4, 0x51, 0x79, 0x6f, 0x12, 0x81, 0xf7, 0x6d, 0x19, 0x21, 0x6d, 0x35, 0xb0, 0x4f, 0x57, + 0x96, 0x8a, 0xcd, 0x77, 0x74, 0x3a, 0x4c, 0x23, 0x3b, 0xa2, 0x08, 0x7f, 0x2a, 0x21, 0x09, 0x57, 0x49, 0x9f, 0x54, + 0x26, 0x17, 0x4c, 0xa5, 0x1c, 0x7f, 0x2a, 0xa4, 0xd4, 0xd7, 0xf6, 0x4b, 0xe2, 0xea, 0x4e, 0x46, 0xe0, 0x4f, 0x53, + 0xa6, 0xdf, 0xd1, 0x62, 0xca, 0xc0, 0xaf, 0xc8, 0xdf, 0x8e, 0xa5, 0x94, 0x5c, 0xbd, 0x10, 0xf1, 0x80, 0x62, 0x78, + 0x77, 0x75, 0x88, 0xb5, 0x09, 0x81, 0x52, 0xe2, 0x22, 0x5c, 0x10, 0xbd, 0x29, 0xe4, 0xed, 0x5d, 0x5c, 0x60, 0xe7, + 0x00, 0x58, 0x3a, 0x4d, 0x02, 0xfc, 0xcb, 0xc7, 0x7c, 0xac, 0xc6, 0x9c, 0x1a, 0x5d, 0xbf, 0xfb, 0x9d, 0x7c, 0x02, + 0x7a, 0x5b, 0x3a, 0x0a, 0x0e, 0x5a, 0x43, 0xc8, 0x85, 0xbb, 0x30, 0xb8, 0xf8, 0x0a, 0x6b, 0x17, 0x85, 0xf1, 0xc6, + 0x02, 0xe8, 0x3d, 0xca, 0xc0, 0x82, 0x0d, 0x73, 0x4c, 0xe1, 0xd1, 0xda, 0x29, 0xd3, 0x41, 0x54, 0x90, 0x27, 0xe5, + 0xb3, 0xa4, 0xb5, 0xda, 0x6f, 0xd9, 0x04, 0xee, 0x30, 0x92, 0x6f, 0x17, 0x4e, 0x1c, 0x78, 0x40, 0xa6, 0xc9, 0x6c, + 0xb3, 0x6f, 0x7c, 0xe4, 0x91, 0xd7, 0x93, 0x78, 0x5f, 0x4b, 0x61, 0xbe, 0x59, 0xd1, 0x0d, 0x86, 0x50, 0x14, 0x61, + 0xbf, 0x37, 0x2a, 0xa6, 0xa8, 0x32, 0x68, 0x83, 0x86, 0xe5, 0x8d, 0xf8, 0x19, 0xce, 0x18, 0x5a, 0x2f, 0x64, 0xef, + 0xe8, 0xac, 0xc3, 0x99, 0xc3, 0x8c, 0x19, 0x81, 0x51, 0x69, 0x59, 0xd0, 0x29, 0x38, 0x3a, 0x57, 0x1f, 0x44, 0xc5, + 0xd5, 0xb1, 0x02, 0xf0, 0x24, 0x33, 0xf8, 0x27, 0xdf, 0x06, 0xeb, 0x61, 0xab, 0x66, 0x98, 0xfa, 0xb3, 0xde, 0x75, + 0x2d, 0x5f, 0x85, 0x38, 0xd2, 0xc6, 0x10, 0x5a, 0xe7, 0xf6, 0x0e, 0x50, 0xc4, 0x05, 0xbd, 0x48, 0x35, 0xfe, 0xa4, + 0x96, 0x23, 0xb3, 0xbe, 0xc6, 0x75, 0x4c, 0x1b, 0x44, 0xb1, 0xee, 0x9a, 0xf8, 0x53, 0xf5, 0x0a, 0xac, 0x4a, 0x81, + 0x75, 0x06, 0xe5, 0x87, 0x2a, 0x2f, 0x1b, 0x52, 0x49, 0xae, 0x4c, 0xa7, 0xd2, 0x74, 0x5a, 0x21, 0x94, 0x4b, 0x4f, + 0xca, 0xfb, 0x57, 0x08, 0x61, 0x60, 0xca, 0xec, 0xc1, 0x2a, 0xb5, 0x83, 0x55, 0xf0, 0xea, 0xc5, 0x16, 0x56, 0x49, + 0x38, 0x9e, 0x4b, 0x34, 0x2a, 0x2a, 0x1c, 0x32, 0xa4, 0x2f, 0xc4, 0x22, 0x48, 0x00, 0x2c, 0x7a, 0x99, 0xb9, 0xbc, + 0xef, 0xe1, 0x50, 0xd8, 0x93, 0x4c, 0xc2, 0xe9, 0x26, 0x34, 0x87, 0xe7, 0x81, 0x55, 0xdf, 0x23, 0xc4, 0xcc, 0xc4, + 0x7f, 0x82, 0x67, 0xa1, 0xbf, 0xff, 0x1c, 0xad, 0xb3, 0x20, 0x4f, 0xff, 0x25, 0x4a, 0x42, 0x63, 0xff, 0x39, 0x1e, + 0x3a, 0x24, 0x0c, 0x07, 0xbe, 0x3d, 0xc2, 0x0a, 0x07, 0x77, 0x8a, 0xf8, 0x0c, 0xee, 0xf0, 0xb1, 0x0e, 0x3d, 0x00, + 0x2c, 0xa1, 0x38, 0x04, 0xf9, 0x16, 0x8a, 0x99, 0x61, 0x6b, 0xb2, 0x0a, 0x2f, 0x70, 0xc1, 0x6a, 0xa1, 0xbc, 0xbf, + 0x6d, 0x79, 0x29, 0xad, 0x76, 0xc9, 0x6b, 0xcc, 0x81, 0xca, 0xcf, 0xf0, 0xc2, 0x57, 0x98, 0xf7, 0xaa, 0xdd, 0x17, + 0xfe, 0xe4, 0x80, 0x9e, 0x42, 0xc0, 0x48, 0xf7, 0x7b, 0x43, 0xb8, 0xa7, 0xe8, 0x65, 0x2e, 0x0e, 0xdb, 0x0e, 0xba, + 0x17, 0x98, 0xab, 0xeb, 0x2a, 0x6b, 0x01, 0xa6, 0xd0, 0xe0, 0xa0, 0x0a, 0x67, 0x04, 0xe6, 0xea, 0x45, 0x59, 0x70, + 0x01, 0xe2, 0x7d, 0x5f, 0x98, 0x9c, 0x32, 0x1a, 0xc0, 0xbb, 0xac, 0x7c, 0x74, 0xaa, 0xcf, 0xc1, 0x65, 0xdc, 0xb0, + 0x89, 0x4f, 0x84, 0x4f, 0x05, 0x56, 0xd2, 0x1a, 0x87, 0x46, 0x74, 0x4c, 0x17, 0x60, 0xb6, 0x01, 0x14, 0xdc, 0x9d, + 0x0f, 0x5b, 0x0b, 0x15, 0x3c, 0xc9, 0x5b, 0x7b, 0x41, 0x9b, 0x10, 0x67, 0xd2, 0x14, 0xdc, 0x6d, 0x17, 0x45, 0x60, + 0x7e, 0xfb, 0x6f, 0x85, 0x45, 0x82, 0x01, 0x95, 0x9a, 0x24, 0x08, 0x4f, 0x50, 0x1a, 0xe9, 0x56, 0x6e, 0x26, 0x90, + 0x4e, 0x44, 0x78, 0xc3, 0xfc, 0x72, 0xeb, 0x7c, 0x75, 0xd4, 0x40, 0x54, 0xd4, 0x40, 0x05, 0xd4, 0x40, 0xd6, 0xb7, + 0x7f, 0x01, 0x0b, 0x61, 0x23, 0x54, 0x89, 0x20, 0x20, 0xc2, 0x42, 0x1b, 0x3e, 0xa0, 0x48, 0x42, 0xc8, 0x1b, 0x40, + 0xc5, 0x94, 0xbc, 0x05, 0xa3, 0x71, 0x78, 0xbd, 0x07, 0xdc, 0x2f, 0x2d, 0xc3, 0xe0, 0x39, 0x05, 0x93, 0xff, 0xcc, + 0xe7, 0x43, 0xf5, 0x72, 0x75, 0x10, 0xc2, 0x4f, 0x20, 0x56, 0x84, 0xe3, 0x2f, 0x7e, 0x06, 0xb2, 0xa9, 0xb0, 0x3c, + 0x3a, 0x92, 0x20, 0xf0, 0x43, 0x14, 0xe1, 0x80, 0x67, 0x78, 0x9b, 0x6d, 0x11, 0x3d, 0x3f, 0x2b, 0x55, 0xcd, 0x4a, + 0x06, 0xb3, 0x2a, 0x3c, 0x8d, 0xa3, 0x1b, 0xc2, 0x40, 0x70, 0xa1, 0x76, 0xdf, 0x20, 0x04, 0xca, 0x96, 0x1b, 0x43, + 0x97, 0x9e, 0x82, 0xf9, 0x68, 0x1c, 0xbd, 0x65, 0xf0, 0xb0, 0xb0, 0x71, 0x47, 0x61, 0x9a, 0x65, 0xda, 0x30, 0x8f, + 0x8d, 0xc0, 0x49, 0x9d, 0xa2, 0xe4, 0xb3, 0xe4, 0x22, 0x8e, 0x9a, 0x57, 0x11, 0x6a, 0xc0, 0xbf, 0x0d, 0x8e, 0x7a, + 0x34, 0xa1, 0xe3, 0xb1, 0x0f, 0x7e, 0x93, 0x11, 0xb3, 0xc9, 0xd6, 0x6b, 0x51, 0x11, 0xf4, 0xc4, 0x6e, 0x30, 0x60, + 0x25, 0x9e, 0x00, 0xfb, 0x60, 0x39, 0x58, 0xf2, 0x4e, 0xc4, 0xca, 0x9f, 0x52, 0x18, 0xac, 0x9e, 0x33, 0x84, 0x70, + 0x16, 0x30, 0x29, 0xff, 0xf9, 0x4c, 0xc3, 0xf5, 0xf3, 0xf3, 0x75, 0x8c, 0x88, 0xf4, 0x41, 0xe4, 0x6a, 0xec, 0x88, + 0x08, 0xc2, 0x96, 0xe9, 0x81, 0x2b, 0xf3, 0x83, 0xb7, 0xae, 0x1e, 0xda, 0x70, 0x71, 0x60, 0x40, 0x8d, 0x02, 0xa3, + 0x15, 0x9c, 0x93, 0x72, 0xe0, 0xa0, 0x84, 0xd0, 0xac, 0x88, 0x67, 0xe4, 0x0a, 0x22, 0xe1, 0x65, 0xa8, 0x07, 0x86, + 0x05, 0x81, 0x04, 0x35, 0x03, 0x09, 0x2a, 0xf3, 0xb5, 0xc7, 0x30, 0xeb, 0xdc, 0xcc, 0x76, 0x86, 0x7a, 0x2e, 0xc8, + 0xcf, 0xcf, 0x3a, 0x1e, 0x03, 0x4b, 0x7b, 0x74, 0x54, 0x40, 0x04, 0x31, 0xa0, 0xe0, 0xa5, 0x04, 0x18, 0x68, 0xc0, + 0x8b, 0x2d, 0x0d, 0xf8, 0x42, 0x1b, 0xaf, 0x03, 0x63, 0xeb, 0x53, 0x06, 0xb9, 0x78, 0x55, 0xed, 0x69, 0x42, 0xc8, + 0x61, 0xab, 0xaf, 0xd3, 0xdd, 0x08, 0x89, 0xfd, 0x8f, 0xda, 0x04, 0x1a, 0x73, 0xa4, 0xbb, 0xda, 0x98, 0x7f, 0xd7, + 0xf4, 0x88, 0xd5, 0x24, 0xa4, 0x0b, 0xd2, 0xe5, 0xf9, 0xb4, 0x57, 0x70, 0xc5, 0x2a, 0x8d, 0x1c, 0x5c, 0x80, 0x3e, + 0x1b, 0x10, 0xa0, 0x40, 0xa5, 0xa9, 0x04, 0x2d, 0xe2, 0x22, 0x29, 0xd9, 0x30, 0xcc, 0x20, 0x4c, 0x61, 0xb5, 0x12, + 0x74, 0x6b, 0x0d, 0x80, 0x77, 0x66, 0xf6, 0x4f, 0xe9, 0x83, 0x4d, 0x37, 0xde, 0x3c, 0x02, 0x08, 0xc8, 0x61, 0xbb, + 0x64, 0xd7, 0xc5, 0x56, 0x65, 0x16, 0xd6, 0x32, 0xb6, 0x72, 0xbb, 0x1e, 0x63, 0xef, 0xc4, 0x2e, 0x9f, 0x00, 0x21, + 0x6a, 0x4b, 0xa6, 0x11, 0x4b, 0x18, 0xb2, 0xae, 0x0d, 0xd9, 0x68, 0x43, 0xe1, 0xa9, 0x44, 0x0e, 0x5c, 0xa2, 0x09, + 0x92, 0xef, 0xb8, 0x04, 0x87, 0xf0, 0xc2, 0x23, 0xfc, 0x57, 0x60, 0x91, 0x0a, 0xcc, 0xb0, 0x5c, 0xaf, 0xa1, 0x9e, + 0xc7, 0xfb, 0x6c, 0x3b, 0x38, 0xa9, 0xdc, 0x1a, 0xbb, 0xb4, 0x13, 0x8f, 0xcb, 0x26, 0x24, 0xce, 0xa0, 0x5f, 0x5f, + 0x11, 0xf5, 0x0f, 0xdb, 0xe9, 0x0b, 0xff, 0x5e, 0x99, 0xdb, 0x81, 0xd8, 0xb0, 0xde, 0x60, 0xf5, 0x01, 0xb4, 0xfc, + 0x73, 0xe6, 0x1f, 0x2a, 0x0b, 0x6e, 0x12, 0xd4, 0xf6, 0x22, 0xf6, 0x58, 0x0f, 0x31, 0x52, 0x5b, 0xdc, 0x3d, 0x42, + 0xfc, 0xe7, 0x9d, 0x28, 0x06, 0x3c, 0xa9, 0xf8, 0xe7, 0x18, 0xf5, 0x20, 0x14, 0xb5, 0xf5, 0xb0, 0x01, 0x4a, 0xbb, + 0xda, 0x54, 0x62, 0x64, 0x48, 0x20, 0xdf, 0xba, 0xf0, 0x82, 0xe6, 0x24, 0x52, 0x20, 0x27, 0x57, 0x5d, 0x3c, 0xca, + 0xb6, 0x84, 0xb9, 0xde, 0x0e, 0x8e, 0x99, 0xab, 0x8d, 0xac, 0x88, 0xdf, 0x01, 0x3b, 0xc3, 0x8d, 0x64, 0xe9, 0xc0, + 0xa7, 0x6a, 0xe0, 0xf3, 0x6b, 0x6e, 0x28, 0x8a, 0x42, 0xfd, 0x77, 0xf6, 0x91, 0x39, 0xf8, 0x9d, 0x06, 0xe2, 0x63, + 0xe6, 0x74, 0x24, 0x5b, 0xa1, 0xd6, 0x9c, 0x1d, 0x2f, 0xdb, 0x8e, 0x30, 0x28, 0x6c, 0xf4, 0xbe, 0x0a, 0x59, 0xc5, + 0xde, 0x4e, 0x45, 0x30, 0xa7, 0x1b, 0x55, 0x39, 0xa7, 0x72, 0xcb, 0xa8, 0x96, 0x9a, 0x06, 0x88, 0x70, 0xe5, 0x13, + 0xc9, 0x87, 0xcc, 0x84, 0x7f, 0x30, 0x18, 0x57, 0x8f, 0x14, 0xfe, 0x61, 0x5f, 0xec, 0x90, 0xdd, 0xe8, 0x70, 0x5b, + 0x41, 0xf3, 0x42, 0x05, 0x0f, 0x38, 0x2a, 0x59, 0x42, 0xa4, 0xc8, 0xd5, 0xa1, 0xaa, 0x99, 0xb2, 0x7d, 0x8a, 0x10, + 0x42, 0xda, 0xe3, 0xac, 0x1b, 0x5a, 0x3d, 0xf4, 0x48, 0xe5, 0x34, 0xb9, 0x43, 0x73, 0x5d, 0x80, 0x0a, 0x23, 0x90, + 0xae, 0xbe, 0xb0, 0xbb, 0x54, 0x42, 0xf4, 0xf2, 0x8d, 0x0b, 0x61, 0xec, 0xac, 0x2c, 0x71, 0x61, 0x46, 0x6d, 0xc3, + 0xe8, 0xba, 0x8d, 0xe1, 0x6c, 0x60, 0xcc, 0x34, 0x28, 0x69, 0x41, 0xa8, 0xeb, 0x1e, 0xbd, 0xcc, 0x4c, 0xa0, 0xc7, + 0x9c, 0xd0, 0x06, 0xc3, 0x33, 0xa2, 0xc1, 0xb2, 0xa9, 0x00, 0x0b, 0xbe, 0x55, 0x91, 0x5a, 0x9b, 0x4d, 0x16, 0x7f, + 0xd4, 0xb1, 0x79, 0xda, 0x2f, 0xaf, 0x98, 0xe7, 0xc2, 0x47, 0x47, 0xc8, 0x7c, 0x3c, 0xba, 0xa7, 0x6f, 0xae, 0x5f, + 0xbc, 0x7c, 0xfd, 0x6a, 0xbd, 0x6e, 0xb3, 0x66, 0xfb, 0x0c, 0xff, 0x43, 0x97, 0xf1, 0x60, 0xcb, 0x28, 0x40, 0x47, + 0x47, 0x87, 0xdc, 0xb8, 0xf0, 0x7c, 0xe1, 0x0b, 0x88, 0x1b, 0xa4, 0x87, 0x38, 0x2f, 0xca, 0x98, 0x20, 0xb7, 0x51, + 0x3f, 0xba, 0x8b, 0x40, 0x09, 0x55, 0x91, 0xbf, 0xdf, 0xb6, 0x67, 0x7f, 0x00, 0x81, 0x89, 0xa0, 0x3e, 0x44, 0x00, + 0x81, 0x78, 0xa5, 0xb8, 0x20, 0xcc, 0x27, 0x40, 0x14, 0xef, 0x09, 0x70, 0xa6, 0x26, 0x6a, 0xd5, 0x44, 0xc5, 0x05, + 0x90, 0x44, 0x1b, 0x8e, 0x92, 0x9e, 0x98, 0x00, 0xde, 0x10, 0x94, 0xd2, 0xfe, 0xea, 0xe5, 0xce, 0x5d, 0x2a, 0x47, + 0xfd, 0x56, 0x9a, 0xe3, 0x99, 0xfb, 0x9c, 0xc1, 0xe7, 0xac, 0xe7, 0x4f, 0x07, 0x71, 0x9c, 0xe3, 0x25, 0x11, 0xc7, + 0xfe, 0x59, 0xc4, 0xd5, 0xa2, 0x60, 0x5f, 0xb9, 0x5c, 0xaa, 0x74, 0x75, 0x9b, 0xca, 0xe4, 0xb6, 0x39, 0x3e, 0x8e, + 0x8b, 0xe4, 0xb6, 0xa9, 0x92, 0x5b, 0x84, 0xef, 0x52, 0x99, 0xdc, 0xd9, 0x94, 0xbb, 0xa6, 0x82, 0x9b, 0x2f, 0x2c, + 0xe0, 0x50, 0xb4, 0x45, 0x1b, 0xcb, 0xed, 0xa2, 0x36, 0xc5, 0x15, 0x0d, 0xa3, 0x29, 0xee, 0xd9, 0xf8, 0x61, 0xf8, + 0x12, 0x5c, 0x9a, 0x34, 0x91, 0x7f, 0x80, 0xf4, 0xd3, 0xaa, 0x0c, 0xdc, 0x67, 0xa4, 0xd5, 0x9b, 0x5d, 0x8a, 0x66, + 0xbb, 0xd7, 0x68, 0xcc, 0x60, 0xef, 0x66, 0x24, 0xf7, 0xc5, 0x66, 0x0d, 0x13, 0x5f, 0xe7, 0x30, 0x5b, 0xaf, 0x0f, + 0x73, 0x64, 0x36, 0xdc, 0x94, 0xc5, 0x7a, 0x30, 0x1b, 0xe2, 0x16, 0x7e, 0x9f, 0x21, 0xb4, 0x62, 0x83, 0xd9, 0x90, + 0xb0, 0xc1, 0xac, 0xd1, 0x1e, 0x5a, 0x43, 0x3b, 0xb3, 0x15, 0x37, 0x10, 0x42, 0x73, 0x36, 0x3c, 0x31, 0x25, 0xa5, + 0xcb, 0xb7, 0x5f, 0xb4, 0x0a, 0xe8, 0xa7, 0x6a, 0xc1, 0xcb, 0x24, 0xee, 0x40, 0x5f, 0xf4, 0xd2, 0x3e, 0xdd, 0x5a, + 0x90, 0xd3, 0x93, 0xca, 0xd5, 0x9e, 0x22, 0x6c, 0x7a, 0x52, 0xc7, 0xc5, 0xb1, 0x69, 0xc6, 0x75, 0x29, 0xdd, 0x77, + 0xa8, 0x19, 0xf9, 0xcb, 0xc1, 0x02, 0x10, 0xa4, 0x82, 0x47, 0x5e, 0xb8, 0x70, 0x4a, 0x21, 0x5c, 0x1c, 0x54, 0x76, + 0x60, 0x92, 0x93, 0x56, 0x2f, 0x37, 0x96, 0xfe, 0xb9, 0x8b, 0x68, 0x4a, 0x31, 0x25, 0x99, 0x2f, 0x99, 0x1b, 0xb0, + 0xd0, 0x6d, 0xca, 0x33, 0x03, 0xbd, 0xd2, 0x10, 0x8f, 0x09, 0xc4, 0x43, 0xea, 0x15, 0xc6, 0xc0, 0x2b, 0x9e, 0x35, + 0x8b, 0x01, 0x1b, 0xa2, 0x93, 0x53, 0x4c, 0x07, 0x7f, 0x66, 0x8b, 0x36, 0x3c, 0x16, 0xf8, 0xe7, 0x90, 0xcc, 0x9a, + 0xb2, 0x4c, 0x10, 0x90, 0x30, 0x6e, 0xca, 0x63, 0xd8, 0x4b, 0x08, 0x67, 0xb6, 0x62, 0x36, 0x60, 0xc3, 0xe6, 0xac, + 0xac, 0xd8, 0xf1, 0x15, 0x1b, 0xb2, 0x4c, 0xb0, 0x15, 0x1b, 0xae, 0x62, 0xf8, 0x3a, 0x83, 0x01, 0x41, 0x08, 0x00, + 0x06, 0x00, 0xd0, 0x28, 0x88, 0xe6, 0x8b, 0x15, 0xf1, 0x9b, 0xdd, 0xde, 0xe3, 0xb7, 0xc0, 0x02, 0xad, 0xb6, 0xff, + 0xf7, 0xa1, 0x0c, 0xd8, 0x53, 0x16, 0x26, 0x66, 0x6e, 0x61, 0x55, 0x74, 0x00, 0x95, 0x12, 0x61, 0x0a, 0x03, 0x99, + 0xc3, 0xcc, 0x40, 0x2d, 0xd0, 0x1a, 0xe4, 0x03, 0x3d, 0x6c, 0x66, 0x70, 0xc4, 0xc0, 0x3b, 0x34, 0x64, 0x66, 0x8c, + 0x09, 0xe3, 0x1c, 0xa6, 0x98, 0x19, 0xf0, 0xcc, 0xd2, 0xd6, 0x46, 0x1a, 0x59, 0xae, 0x9f, 0xf7, 0xff, 0xd2, 0xb1, + 0x1a, 0x14, 0xcd, 0xf6, 0x10, 0x1d, 0x12, 0x62, 0x3f, 0x86, 0xb0, 0xc9, 0x5c, 0x6a, 0xc3, 0x7c, 0x9f, 0x74, 0x52, + 0xfb, 0x09, 0x7f, 0x86, 0x1b, 0xb3, 0x03, 0x40, 0x47, 0x86, 0xcd, 0xfa, 0xcb, 0x9a, 0xca, 0xeb, 0xe3, 0xde, 0x28, + 0x95, 0xfb, 0xde, 0x9d, 0x0e, 0x54, 0x13, 0xa1, 0xb7, 0x1e, 0x2e, 0x1f, 0xea, 0x21, 0x60, 0xc6, 0x60, 0x6e, 0x99, + 0xd1, 0xf7, 0x42, 0x24, 0x17, 0x44, 0x02, 0x4b, 0x82, 0x29, 0x61, 0xb0, 0xb7, 0x8e, 0x8e, 0x4c, 0x35, 0xd6, 0x80, + 0xe7, 0x49, 0x11, 0x08, 0x06, 0x3e, 0x82, 0x32, 0xa0, 0x89, 0x32, 0xb7, 0xe1, 0xe4, 0x23, 0x73, 0xbf, 0x70, 0x79, + 0xfb, 0x58, 0x38, 0x6d, 0xab, 0xb9, 0x1e, 0x2f, 0x0b, 0xdc, 0x95, 0xf7, 0x92, 0x56, 0xc1, 0x8d, 0xec, 0x4d, 0x9e, + 0x32, 0x77, 0xeb, 0xbe, 0x54, 0x67, 0x7f, 0x33, 0x9d, 0xb2, 0x99, 0xce, 0x6e, 0x33, 0x61, 0x5c, 0xc9, 0x6f, 0x59, + 0x45, 0x9a, 0x93, 0x35, 0x51, 0x0b, 0x2a, 0xfe, 0x41, 0x17, 0xa0, 0x1d, 0xe5, 0xf6, 0x5e, 0x15, 0x4e, 0xae, 0x9c, + 0x5c, 0x1d, 0xe6, 0x86, 0xb8, 0x22, 0x73, 0xa1, 0x0e, 0x01, 0x5e, 0x5e, 0x94, 0x8f, 0x0f, 0x70, 0x29, 0x7e, 0x91, + 0x63, 0x17, 0xe5, 0x54, 0x48, 0x2d, 0x05, 0x8b, 0x90, 0x41, 0x55, 0x17, 0x03, 0x7b, 0x65, 0xf7, 0x9e, 0xe8, 0xf3, + 0x41, 0x15, 0x31, 0x6f, 0x68, 0x9e, 0xfb, 0xf8, 0x9e, 0xa6, 0xd8, 0xa9, 0x89, 0x33, 0xf2, 0x5b, 0x16, 0xe7, 0x20, + 0x9b, 0x0d, 0xaa, 0xd7, 0x7e, 0x1b, 0x6d, 0x5c, 0x34, 0x63, 0xd1, 0x37, 0x4f, 0x9c, 0xfc, 0x50, 0x18, 0xe3, 0x00, + 0xeb, 0xe8, 0x8f, 0x30, 0xb5, 0x60, 0xcf, 0x12, 0x4f, 0xa1, 0x93, 0x5b, 0x9b, 0x76, 0x17, 0xa6, 0xdd, 0x99, 0xb4, + 0x0e, 0x94, 0x03, 0xd2, 0xec, 0xca, 0x74, 0xee, 0xfc, 0xf7, 0x1d, 0xbc, 0x74, 0xbb, 0x81, 0x48, 0xdc, 0x8b, 0x47, + 0xc6, 0x18, 0xe2, 0x0d, 0xd8, 0x88, 0xaa, 0xa3, 0xa3, 0x9f, 0x9d, 0xf7, 0x6d, 0x25, 0xcb, 0x7e, 0x2b, 0x1c, 0xd8, + 0x16, 0x53, 0xe9, 0xf2, 0xc6, 0x32, 0x5b, 0x82, 0x5d, 0xe7, 0xe1, 0x37, 0xe2, 0xe1, 0x8b, 0x90, 0x69, 0xb1, 0xae, + 0xe2, 0xaf, 0xe4, 0xb8, 0xf4, 0x10, 0xd5, 0x10, 0x81, 0xb4, 0xb2, 0x2e, 0x0d, 0x4d, 0x47, 0xaf, 0x67, 0x74, 0x2c, + 0x6f, 0xde, 0x4a, 0xa9, 0x87, 0xf6, 0x45, 0x6e, 0x9d, 0xc0, 0xa3, 0x85, 0x35, 0x86, 0xe6, 0xae, 0xf4, 0x4e, 0xb2, + 0x01, 0x51, 0xeb, 0xe3, 0x0e, 0x25, 0x91, 0x58, 0x54, 0x77, 0x21, 0x1c, 0xee, 0x42, 0x30, 0x2f, 0x83, 0xb6, 0x41, + 0xec, 0x76, 0x17, 0xb4, 0x0d, 0x9c, 0xba, 0x6d, 0xe0, 0xf6, 0x60, 0xb0, 0xb0, 0xf7, 0xe1, 0xe5, 0x58, 0x8e, 0x85, + 0xe3, 0x0f, 0xee, 0xd9, 0x07, 0x80, 0x40, 0xed, 0xc3, 0x8a, 0x27, 0x0e, 0x04, 0x89, 0x33, 0x1c, 0xfd, 0xc0, 0xd9, + 0x8d, 0xb5, 0x1c, 0x9e, 0x2f, 0x96, 0x9a, 0x8d, 0xcd, 0x1d, 0x35, 0xa8, 0xf8, 0xea, 0x7e, 0x5e, 0xbf, 0x66, 0x35, + 0xdd, 0xf8, 0x3d, 0x08, 0x23, 0xe1, 0x94, 0x1d, 0x46, 0x21, 0x61, 0x83, 0x59, 0x95, 0xf1, 0xda, 0x7e, 0x87, 0x78, + 0x0f, 0xda, 0x84, 0x13, 0x2c, 0x6a, 0x17, 0x54, 0x11, 0xb6, 0xf1, 0xc6, 0x82, 0x28, 0x0f, 0x6f, 0x76, 0x8c, 0xa6, + 0x57, 0x1b, 0x08, 0x74, 0xdc, 0x8f, 0x9a, 0x51, 0x83, 0xa5, 0x2e, 0x28, 0xb3, 0x8f, 0x30, 0xae, 0x2e, 0xcf, 0x4c, + 0x9c, 0xf6, 0x52, 0xaf, 0xfe, 0x7b, 0x06, 0x06, 0xf8, 0x02, 0xbc, 0xc4, 0xc2, 0xe8, 0xae, 0x03, 0xdd, 0x80, 0xfa, + 0xb2, 0xc1, 0x86, 0x68, 0xbd, 0x6e, 0x95, 0xcf, 0x40, 0xb9, 0x6b, 0x2e, 0x61, 0xaf, 0xb9, 0x84, 0xbb, 0xe6, 0x12, + 0xfe, 0x9a, 0x4b, 0x98, 0x6b, 0x2e, 0xe1, 0xaf, 0xb9, 0x3c, 0x08, 0x7f, 0x0a, 0xe2, 0x38, 0xc6, 0x1c, 0xe2, 0x2a, + 0x6a, 0x1b, 0x19, 0x0f, 0x2e, 0x3c, 0x0f, 0x59, 0xa2, 0xca, 0xe5, 0x0f, 0x63, 0xc8, 0xe5, 0xdb, 0xb6, 0x12, 0xc6, + 0x6d, 0x8a, 0x29, 0x88, 0x9c, 0x7e, 0x74, 0x54, 0xb9, 0x3b, 0x0f, 0x5a, 0xc3, 0x94, 0xe3, 0x95, 0x75, 0xa2, 0xfd, + 0x27, 0xe8, 0xe4, 0xcd, 0xaf, 0x8f, 0xa9, 0xdc, 0x10, 0xe1, 0x4c, 0xee, 0x0f, 0xdb, 0x9e, 0x52, 0xfc, 0x94, 0x99, + 0xf0, 0xe4, 0x3c, 0xd1, 0x46, 0x04, 0x41, 0x88, 0x12, 0xf5, 0xff, 0xb2, 0xf7, 0xae, 0xcb, 0x6d, 0x23, 0x59, 0xba, + 0xe8, 0xab, 0x48, 0x0c, 0x9b, 0x05, 0x98, 0x49, 0x8a, 0xf2, 0xde, 0x33, 0x11, 0x07, 0x54, 0x9a, 0xe1, 0x4b, 0xb9, + 0xcb, 0x5d, 0xe5, 0x4b, 0x5b, 0xae, 0x6a, 0x57, 0x33, 0x78, 0x54, 0x10, 0x90, 0x24, 0xe0, 0x02, 0x01, 0x16, 0x00, + 0x4a, 0xa4, 0x49, 0xbc, 0xfb, 0x8e, 0xb5, 0x56, 0x5e, 0x41, 0x50, 0x76, 0xcf, 0xec, 0xf9, 0x75, 0xce, 0x1f, 0x5b, + 0x4c, 0x24, 0x12, 0x79, 0xcf, 0x95, 0xeb, 0xf2, 0x7d, 0x2c, 0xe2, 0x05, 0xad, 0x77, 0x15, 0x0a, 0x8f, 0xaa, 0x28, + 0xe5, 0x56, 0xf2, 0x32, 0x83, 0x20, 0x76, 0xf4, 0xc2, 0xf0, 0x27, 0x10, 0x42, 0x10, 0x61, 0xc2, 0xe7, 0x61, 0x46, + 0xdb, 0x59, 0xa4, 0x93, 0x7e, 0x1f, 0x66, 0xb8, 0x81, 0x95, 0xfc, 0x5c, 0xf5, 0xd9, 0x7e, 0x1b, 0x84, 0x6c, 0x17, + 0x44, 0xec, 0xb6, 0xd8, 0x06, 0xa5, 0x75, 0x24, 0x5e, 0x2b, 0xc3, 0xdf, 0xc2, 0xeb, 0xe5, 0x21, 0xc4, 0xfb, 0xf4, + 0xd2, 0xfc, 0x2c, 0x6d, 0x45, 0x01, 0xee, 0x23, 0xf4, 0xa8, 0x0e, 0x04, 0x3b, 0xe1, 0x09, 0x0f, 0xe0, 0x64, 0x35, + 0xab, 0xf8, 0xa3, 0x14, 0xc4, 0x89, 0x82, 0x43, 0xc0, 0xd5, 0xf6, 0x3a, 0xfd, 0x0a, 0x86, 0x2f, 0x1d, 0x6c, 0x39, + 0xbc, 0x2d, 0xb6, 0x3d, 0x56, 0xf2, 0x0f, 0xc0, 0xbe, 0xd5, 0x93, 0xb1, 0xba, 0x3d, 0x70, 0xd6, 0xa5, 0x14, 0x1d, + 0x6f, 0x8a, 0xc3, 0xdb, 0xf3, 0xd9, 0x7e, 0x1b, 0x44, 0x6c, 0x17, 0x64, 0x58, 0xeb, 0xa4, 0xe1, 0x38, 0x18, 0xc2, + 0x67, 0x31, 0xc2, 0xfe, 0x2f, 0xea, 0x81, 0x97, 0x90, 0x1a, 0x0a, 0x5c, 0x0c, 0x36, 0x1c, 0xad, 0xed, 0x32, 0x0d, + 0xdc, 0xd4, 0xa0, 0xd7, 0xf7, 0x14, 0xa2, 0xbc, 0x60, 0x34, 0x37, 0x82, 0x75, 0x63, 0xc8, 0xc5, 0xe1, 0xb8, 0x59, + 0x0c, 0x79, 0x49, 0xd3, 0x69, 0x10, 0x4a, 0x77, 0x96, 0x35, 0x24, 0x51, 0xf6, 0x41, 0xa8, 0x5d, 0x5b, 0xf6, 0xdb, + 0xc0, 0xf6, 0xe5, 0x8f, 0x86, 0xb1, 0x7f, 0xb1, 0x78, 0x22, 0xa4, 0x8b, 0x78, 0x0e, 0x82, 0xa8, 0xfd, 0x3c, 0x1b, + 0x6e, 0xfc, 0x8b, 0xf5, 0x13, 0xa1, 0xfc, 0xc6, 0x73, 0x5b, 0x0e, 0x11, 0x59, 0x0b, 0x5f, 0x18, 0x0f, 0x0f, 0xae, + 0x0c, 0x6d, 0x87, 0x83, 0xd0, 0x7f, 0x9b, 0x35, 0x82, 0x1b, 0x1b, 0xda, 0xe7, 0x0b, 0x1f, 0xb6, 0x36, 0x1a, 0x6b, + 0x8a, 0xe9, 0x16, 0xfa, 0x37, 0x99, 0x2d, 0xed, 0x69, 0x54, 0xf2, 0xe2, 0xd4, 0x34, 0x62, 0x21, 0x0c, 0x18, 0xfa, + 0xc9, 0x7c, 0x00, 0xd5, 0xdc, 0xf1, 0x08, 0x64, 0xf2, 0x81, 0x1e, 0xac, 0x49, 0xad, 0xfa, 0x6b, 0x98, 0xc9, 0xff, + 0x23, 0x15, 0x16, 0xa3, 0xbb, 0x6d, 0x98, 0xa9, 0x3f, 0x22, 0xf9, 0x07, 0xcb, 0xf9, 0x2e, 0xf5, 0x42, 0xed, 0xc7, + 0xc2, 0x0a, 0x0c, 0x4a, 0x54, 0x0d, 0xe8, 0x81, 0x08, 0xaa, 0x32, 0x48, 0x33, 0xac, 0xce, 0x41, 0xbf, 0x7b, 0x5a, + 0x75, 0x24, 0x87, 0xb4, 0x56, 0x43, 0x2a, 0x98, 0x2a, 0x35, 0xc8, 0x0f, 0x87, 0x65, 0xca, 0x74, 0x19, 0x70, 0x49, + 0x5f, 0xa6, 0x4a, 0x29, 0xfc, 0x17, 0x02, 0xd0, 0x39, 0xb8, 0xc7, 0x97, 0x63, 0x20, 0xcd, 0xb0, 0xf0, 0x5b, 0xb3, + 0xe3, 0x6b, 0x12, 0x6e, 0x93, 0xe0, 0x62, 0x80, 0x73, 0x74, 0x15, 0x96, 0xcb, 0x14, 0x22, 0xa8, 0x4a, 0xa8, 0x6f, + 0x65, 0x1a, 0x94, 0xb6, 0x1a, 0x84, 0x35, 0x09, 0x75, 0x26, 0xd9, 0xa8, 0xb4, 0xdd, 0x28, 0xcc, 0x16, 0x71, 0x3d, + 0x23, 0xac, 0x39, 0x9b, 0xa9, 0x06, 0x26, 0x0d, 0xc7, 0x4d, 0xa3, 0xb5, 0xa8, 0x50, 0x53, 0x98, 0xd7, 0xb8, 0xaa, + 0x54, 0x75, 0x37, 0xa7, 0x96, 0xd2, 0xa2, 0xbd, 0xea, 0x26, 0xd9, 0x90, 0xcb, 0x50, 0x86, 0xc1, 0x46, 0x8e, 0x60, + 0x02, 0x49, 0x72, 0xe6, 0x6f, 0xe4, 0x1f, 0x6a, 0xd3, 0xb5, 0x80, 0x39, 0xc6, 0x2c, 0x1b, 0x16, 0xf4, 0x0a, 0xdc, + 0x03, 0xad, 0xf4, 0x7c, 0x9a, 0x5d, 0xe4, 0x41, 0x32, 0x2c, 0xf4, 0xb2, 0xc9, 0xf8, 0x5f, 0xc2, 0x48, 0x93, 0x19, + 0x2b, 0x59, 0x64, 0xbb, 0x3a, 0x25, 0xce, 0xe3, 0x04, 0xb6, 0x47, 0xd3, 0x5b, 0xbe, 0xcf, 0x20, 0x2a, 0x08, 0x14, + 0xcc, 0x98, 0x2f, 0xbb, 0x78, 0xea, 0xfb, 0xcc, 0x32, 0x75, 0x1f, 0x0e, 0xc6, 0x8c, 0xed, 0xf7, 0xfb, 0x79, 0xbf, + 0xaf, 0xe6, 0x5b, 0xbf, 0x9f, 0x3c, 0x33, 0x7f, 0x7b, 0xc0, 0xa0, 0x20, 0x27, 0xa2, 0xa9, 0x10, 0xc1, 0x3f, 0x24, + 0x4f, 0x90, 0x8c, 0xee, 0xb8, 0xcf, 0x2d, 0x67, 0xcb, 0xea, 0x08, 0x04, 0xf3, 0x70, 0xb8, 0x54, 0x60, 0xd7, 0x12, + 0x45, 0x42, 0x96, 0xff, 0x04, 0x8c, 0x67, 0xee, 0x03, 0x2c, 0x19, 0x80, 0xb0, 0x55, 0x9e, 0xae, 0xf7, 0x7c, 0x15, + 0xbc, 0xd3, 0xf1, 0xae, 0xb1, 0x22, 0x03, 0x71, 0x0b, 0x6c, 0xc4, 0x5a, 0x7b, 0x40, 0xce, 0x14, 0xe0, 0x78, 0x71, + 0x38, 0x9c, 0xcb, 0x5f, 0xba, 0xd9, 0x3a, 0x81, 0x4a, 0x81, 0xdb, 0xa3, 0x93, 0x83, 0xff, 0x01, 0x34, 0x83, 0x72, + 0x98, 0xd7, 0xdb, 0x3f, 0x98, 0x93, 0x9f, 0x9e, 0xe2, 0x9f, 0xf0, 0x10, 0x9d, 0x7e, 0xbb, 0x37, 0x7f, 0x50, 0x54, + 0x1e, 0x0e, 0x6a, 0xf1, 0x9f, 0x73, 0x5e, 0xc1, 0x2f, 0x7c, 0x13, 0x98, 0x4d, 0xa6, 0xde, 0xc9, 0x37, 0x79, 0xce, + 0xd4, 0x6b, 0xbc, 0x62, 0xf2, 0x1d, 0x0e, 0xe7, 0x62, 0x54, 0x6f, 0x47, 0x4e, 0xb4, 0x53, 0x8e, 0x71, 0x30, 0xf8, + 0x2f, 0xa2, 0x6d, 0x42, 0x80, 0xa1, 0x1c, 0x8e, 0xcc, 0xc6, 0x95, 0x25, 0x9e, 0xa5, 0xf3, 0xcb, 0x49, 0x5d, 0xee, + 0xb4, 0xe2, 0x69, 0x0f, 0x2c, 0x6e, 0x6b, 0xf0, 0x02, 0xb8, 0xb3, 0xd8, 0xba, 0x52, 0x70, 0xb8, 0x80, 0x38, 0xc5, + 0x09, 0x88, 0xa0, 0xfd, 0xbe, 0xc4, 0x7b, 0x05, 0x7d, 0xd2, 0x8f, 0x10, 0x0c, 0xf9, 0x8b, 0x04, 0xdc, 0xf5, 0x7a, + 0x35, 0xc6, 0xf7, 0x52, 0x08, 0xae, 0xcf, 0x34, 0x00, 0x2d, 0xf8, 0x5d, 0x3e, 0x94, 0xd3, 0x6f, 0x22, 0xf0, 0x6c, + 0xd9, 0x9b, 0x28, 0x77, 0x1b, 0x9e, 0xf6, 0xba, 0x85, 0x00, 0x2c, 0xc5, 0x33, 0x25, 0x58, 0x90, 0x53, 0xcc, 0xc5, + 0xff, 0x0b, 0x3e, 0x62, 0xbe, 0x27, 0x5d, 0xc4, 0xd6, 0xdb, 0x47, 0x17, 0x06, 0x12, 0x68, 0x3a, 0x00, 0x3f, 0x5e, + 0x05, 0x74, 0x65, 0xfc, 0x3b, 0x2d, 0xeb, 0xb1, 0x3e, 0xfe, 0x53, 0x70, 0x9f, 0x7e, 0xa2, 0xf0, 0xd1, 0xe1, 0xb8, + 0x4a, 0x47, 0x3b, 0x4a, 0x41, 0x74, 0x74, 0xfb, 0x7c, 0xaa, 0xb2, 0xef, 0x2a, 0x20, 0xb7, 0x1c, 0xb5, 0xa7, 0x02, + 0xb0, 0xd8, 0xd2, 0x11, 0xf8, 0x34, 0xcb, 0x27, 0xe4, 0x7b, 0x3d, 0x15, 0x57, 0x97, 0x3a, 0x5d, 0x3c, 0x1b, 0x4f, + 0xe1, 0x7f, 0x20, 0xf6, 0xb0, 0x4c, 0x91, 0x1d, 0xbb, 0x2e, 0x7e, 0x10, 0x6f, 0x6b, 0x3b, 0xfa, 0x63, 0x07, 0x91, + 0x8e, 0x7b, 0x72, 0xa1, 0xbe, 0x84, 0x54, 0x72, 0xa1, 0x6e, 0x20, 0x76, 0xa1, 0xc6, 0x3b, 0x2e, 0x62, 0xad, 0xbf, + 0xad, 0x51, 0xb0, 0x12, 0x70, 0xa6, 0xbd, 0x05, 0x83, 0x0d, 0xac, 0x5b, 0x96, 0xc1, 0xdf, 0x70, 0x4d, 0x13, 0xb8, + 0x61, 0x91, 0xf5, 0xde, 0x60, 0x2b, 0xbd, 0x05, 0x47, 0xcb, 0xc4, 0xb9, 0x94, 0x24, 0x65, 0x8b, 0x8c, 0xab, 0x47, + 0x21, 0x55, 0xd3, 0xfd, 0xad, 0xa8, 0xef, 0x85, 0xc8, 0x83, 0x55, 0xca, 0xa2, 0x62, 0x05, 0x32, 0x7b, 0xf0, 0xaf, + 0x90, 0x91, 0xa3, 0x1c, 0x38, 0x0a, 0xfd, 0xa3, 0x09, 0x74, 0x9e, 0x3a, 0xd2, 0x79, 0x24, 0xd8, 0x4a, 0x3d, 0x14, + 0x56, 0x5e, 0x40, 0x74, 0xb0, 0x1d, 0x73, 0x2b, 0x4f, 0x42, 0xc5, 0xa6, 0x4c, 0xe4, 0x71, 0x50, 0x4b, 0xc0, 0x58, + 0x41, 0x30, 0x67, 0xb9, 0x74, 0x41, 0xaa, 0x1a, 0x3d, 0x2c, 0x32, 0xf7, 0x63, 0x41, 0xf9, 0x1f, 0xab, 0x9c, 0x70, + 0x7d, 0x19, 0x02, 0x1c, 0xed, 0x63, 0x10, 0x25, 0xc6, 0xfa, 0x45, 0x8b, 0x77, 0x32, 0x73, 0x36, 0xb5, 0xbd, 0x04, + 0x19, 0xdb, 0xe1, 0x57, 0x08, 0xad, 0x16, 0x8a, 0x2c, 0x1a, 0x2e, 0x98, 0x6e, 0x4f, 0x69, 0xd5, 0x3d, 0x6c, 0x78, + 0x52, 0x7a, 0xa8, 0xd4, 0xb7, 0x31, 0x81, 0x65, 0x95, 0x32, 0x7c, 0x3b, 0xa1, 0xea, 0xc4, 0xa0, 0x62, 0xdd, 0xb0, + 0x05, 0x1c, 0x62, 0x31, 0x69, 0xac, 0xb3, 0x01, 0x8f, 0x58, 0x02, 0xff, 0x6c, 0xf8, 0x98, 0x2d, 0x78, 0x34, 0xd9, + 0x5c, 0x2d, 0xfa, 0xfd, 0xd2, 0x0b, 0xbd, 0x7a, 0x96, 0x3d, 0x8e, 0xe6, 0xb3, 0x7c, 0xee, 0xa3, 0xe2, 0x62, 0x32, + 0x18, 0x6c, 0xfc, 0x6c, 0x38, 0x64, 0xc9, 0x70, 0x38, 0xc9, 0x1e, 0xc3, 0x6b, 0x8f, 0x79, 0xa4, 0x96, 0x54, 0x72, + 0x95, 0xc1, 0xfe, 0x3e, 0xe0, 0x91, 0xcf, 0x3a, 0x3f, 0x2d, 0x9b, 0x2e, 0xdd, 0xcf, 0xec, 0xb8, 0x0b, 0xdd, 0x01, + 0x36, 0xde, 0x36, 0xe8, 0xc8, 0xbf, 0xdd, 0x21, 0xa5, 0x6e, 0x32, 0x00, 0xbb, 0xd1, 0x00, 0x87, 0x4c, 0xf5, 0x52, + 0x64, 0xf5, 0x52, 0xa6, 0x7a, 0x49, 0x56, 0x2e, 0xc1, 0x42, 0x62, 0xaa, 0xdc, 0x46, 0x56, 0x6e, 0xd1, 0x70, 0x3d, + 0x1c, 0x6c, 0xad, 0xb8, 0x6c, 0x96, 0x70, 0x5f, 0x58, 0x51, 0xe0, 0xff, 0x2d, 0xbb, 0x61, 0x77, 0xf2, 0x18, 0x78, + 0x8b, 0x8e, 0x49, 0x70, 0x81, 0xb8, 0x63, 0xb7, 0x60, 0x87, 0x85, 0xbf, 0xe0, 0x3a, 0x39, 0x66, 0x3b, 0x7c, 0x14, + 0x7a, 0x05, 0xbb, 0xf5, 0x09, 0x68, 0x17, 0x6c, 0x0d, 0x90, 0x8d, 0x6d, 0xf1, 0xd1, 0xf2, 0x70, 0x78, 0xeb, 0xf9, + 0xec, 0x1e, 0x7f, 0x9c, 0x2f, 0x0f, 0x87, 0x9d, 0x67, 0xd4, 0x7b, 0xd7, 0x3c, 0x61, 0xef, 0x79, 0x32, 0xb9, 0xbe, + 0xe2, 0xf1, 0x64, 0x30, 0xb8, 0xf6, 0x6f, 0x78, 0x3d, 0xbb, 0x06, 0xed, 0xc0, 0xf9, 0x8d, 0xd4, 0x35, 0x7b, 0xb7, + 0x3c, 0xf3, 0x6e, 0x70, 0x6c, 0x6e, 0xe1, 0xe8, 0xed, 0xf7, 0xbd, 0x25, 0x8f, 0xbc, 0x5b, 0x52, 0x31, 0xad, 0xb8, + 0xe2, 0x78, 0xdb, 0xe2, 0x7e, 0xba, 0xe2, 0x21, 0x3c, 0xc2, 0xaa, 0x4c, 0xaf, 0x83, 0xf7, 0x3e, 0x5b, 0x69, 0x16, + 0xb8, 0x7b, 0xcc, 0xb1, 0x26, 0x3b, 0xa1, 0x99, 0xf8, 0x2b, 0xec, 0x9f, 0x6b, 0xd5, 0x3f, 0x34, 0xff, 0x4b, 0xdd, + 0x4f, 0xe0, 0xf6, 0x45, 0x16, 0x24, 0xf6, 0x9e, 0x5f, 0xb3, 0x3b, 0x6e, 0xd8, 0x66, 0xcf, 0x4c, 0xd9, 0x27, 0x4a, + 0x8d, 0x1f, 0x28, 0x75, 0x6d, 0x19, 0x56, 0x5a, 0x57, 0x3e, 0x04, 0x0e, 0x07, 0xe4, 0xa7, 0x25, 0xe2, 0x20, 0xb4, + 0x6e, 0xb2, 0x9a, 0x2b, 0xca, 0xb9, 0xd0, 0x86, 0x99, 0x97, 0x03, 0x8b, 0x59, 0x4a, 0xa1, 0xb1, 0x00, 0x40, 0x30, + 0x29, 0xb4, 0xf6, 0x5e, 0x06, 0x90, 0x13, 0x34, 0xfc, 0xb1, 0xb9, 0x2a, 0xcb, 0x5a, 0xb6, 0x24, 0x44, 0xd9, 0xae, + 0x87, 0x97, 0x08, 0x99, 0xd6, 0xef, 0x9f, 0x13, 0xc9, 0xda, 0xa4, 0xba, 0xaa, 0xd1, 0x12, 0x50, 0x91, 0x25, 0x60, + 0xe2, 0x57, 0x9a, 0x4f, 0x00, 0x9e, 0x74, 0x3c, 0xa8, 0x1e, 0xf3, 0x9a, 0x09, 0x22, 0xdb, 0xa8, 0xfc, 0x49, 0xf1, + 0x0c, 0xc9, 0x08, 0x8a, 0xc7, 0xb5, 0xca, 0x58, 0x18, 0xe6, 0x81, 0x02, 0xf2, 0xee, 0xdd, 0xa9, 0x6f, 0xed, 0x8f, + 0x1d, 0x7b, 0xb6, 0x56, 0xa1, 0x16, 0x6a, 0x0a, 0x97, 0x1c, 0xa2, 0x2b, 0xd0, 0x40, 0x11, 0xc9, 0x78, 0xf2, 0x7a, + 0x70, 0x39, 0x89, 0xae, 0xb8, 0x40, 0x67, 0x7c, 0x7d, 0xd3, 0x4d, 0x67, 0xd1, 0xe3, 0x6a, 0x3e, 0x21, 0x25, 0xd9, + 0xe1, 0x90, 0x8d, 0xaa, 0xba, 0x58, 0x4f, 0x43, 0xf9, 0xd3, 0x43, 0xf0, 0xf5, 0x82, 0x7a, 0x4d, 0x56, 0xa9, 0x7e, + 0x4c, 0x95, 0xf2, 0xa2, 0xe1, 0xa5, 0xff, 0xb8, 0x92, 0xfb, 0x1e, 0x90, 0xd6, 0xf2, 0x92, 0xcb, 0xf7, 0x23, 0xc4, + 0x18, 0xf1, 0x03, 0xaf, 0xe4, 0x11, 0x0b, 0xd5, 0x14, 0xae, 0x79, 0x84, 0x20, 0x6f, 0x99, 0x0e, 0xfe, 0xd6, 0x13, + 0xa7, 0xfb, 0x13, 0xa5, 0x5d, 0x7c, 0x61, 0x51, 0xf7, 0x1c, 0xe9, 0x06, 0xe4, 0x60, 0xc3, 0x74, 0x51, 0x90, 0x6d, + 0x4a, 0x23, 0x68, 0xa3, 0xe5, 0xc0, 0x86, 0x53, 0xa9, 0x0d, 0x67, 0xae, 0x21, 0xb8, 0xcf, 0xcf, 0xd3, 0xd1, 0x0d, + 0x7c, 0x48, 0x75, 0x7b, 0x89, 0x9f, 0x0f, 0x1b, 0x8e, 0x64, 0x76, 0xc4, 0x67, 0x36, 0x91, 0x74, 0x52, 0xe7, 0x0a, + 0xd8, 0xed, 0xec, 0x25, 0xc8, 0x11, 0x33, 0xf7, 0x15, 0xaa, 0x6f, 0xd1, 0x80, 0x2b, 0x63, 0xed, 0x6b, 0x92, 0xb1, + 0xf0, 0xaa, 0x9c, 0x86, 0x03, 0x80, 0xa1, 0xcb, 0xe8, 0x6b, 0x8b, 0x4d, 0x96, 0xfd, 0x52, 0x40, 0x10, 0x44, 0x49, + 0x3c, 0x3e, 0xe0, 0x7d, 0x59, 0x0d, 0x35, 0x4a, 0x3e, 0x96, 0x9d, 0xc0, 0xd7, 0x4b, 0xf4, 0x77, 0x63, 0x2e, 0x31, + 0xe0, 0xcb, 0xaa, 0x2d, 0x28, 0x9c, 0xe7, 0x87, 0xc3, 0x79, 0x3e, 0x32, 0x9e, 0x65, 0xa0, 0x5a, 0x99, 0xd6, 0xc1, + 0xc6, 0xcc, 0x17, 0x0b, 0x7f, 0xb1, 0x73, 0x12, 0x11, 0x05, 0x81, 0x1d, 0x09, 0x0f, 0x22, 0xf5, 0xfb, 0xca, 0xd3, + 0x9d, 0xea, 0xb3, 0xfd, 0x8d, 0x4d, 0xa4, 0x17, 0x94, 0x4c, 0x3e, 0x09, 0xf6, 0xaa, 0xbf, 0x83, 0xb0, 0x21, 0xbc, + 0x79, 0xd5, 0xeb, 0x2c, 0x53, 0xb3, 0x12, 0x24, 0xcc, 0x98, 0x23, 0x78, 0x1c, 0x76, 0x1a, 0xdb, 0xf0, 0xd8, 0xc2, + 0x6a, 0xf4, 0xd6, 0x6c, 0xc9, 0x56, 0xec, 0x56, 0xd5, 0xe9, 0x86, 0x87, 0xd3, 0xe1, 0x65, 0x80, 0xab, 0x6f, 0x7d, + 0xce, 0xf9, 0x92, 0x4e, 0xb0, 0xf5, 0x80, 0x47, 0x13, 0x31, 0x5b, 0x3f, 0x8e, 0xd4, 0xe2, 0x59, 0x0f, 0xf9, 0x0d, + 0xad, 0x3f, 0x31, 0x5b, 0x9a, 0xe4, 0xe5, 0x80, 0xdf, 0x4c, 0xd6, 0x8f, 0x23, 0x78, 0xf5, 0x31, 0x58, 0x31, 0x32, + 0x67, 0x96, 0xad, 0x1f, 0x47, 0x38, 0x66, 0xcb, 0xc7, 0x11, 0x8d, 0xda, 0x4a, 0xee, 0x4b, 0xb7, 0x0d, 0x08, 0x2b, + 0xb7, 0x2c, 0x86, 0xd7, 0x40, 0x3c, 0xd3, 0x46, 0xd2, 0xb5, 0x34, 0xf4, 0xc6, 0x3c, 0x9c, 0xc6, 0xc1, 0x9a, 0x5a, + 0x21, 0xcf, 0x0c, 0x31, 0x8b, 0x1f, 0x47, 0x73, 0xb6, 0xc2, 0x8a, 0x6c, 0x78, 0x3c, 0xb8, 0x9c, 0x6c, 0xae, 0xf8, + 0x1a, 0xc8, 0xcf, 0x26, 0x1b, 0xb3, 0x45, 0xdd, 0x72, 0x31, 0xdb, 0x3c, 0x8e, 0xe6, 0x93, 0x15, 0xf4, 0xac, 0x3d, + 0x60, 0xde, 0x6b, 0x10, 0xa1, 0x24, 0xa4, 0xa6, 0xdc, 0xf4, 0x7a, 0x6c, 0x3d, 0x0e, 0x96, 0x6c, 0x7d, 0x19, 0xdc, + 0xb2, 0xf5, 0x18, 0x88, 0x38, 0xa8, 0xdf, 0xbd, 0x0d, 0x2c, 0xbe, 0x88, 0xad, 0x2f, 0x4d, 0xda, 0xe6, 0x71, 0xc4, + 0xdc, 0xc1, 0x69, 0xe0, 0x82, 0xb5, 0xc8, 0xbc, 0x15, 0x83, 0x4b, 0xc8, 0xc2, 0x8b, 0xd9, 0x66, 0x78, 0xc9, 0xd6, + 0x23, 0x9c, 0xea, 0x89, 0xcf, 0x96, 0xfc, 0x96, 0x25, 0x7c, 0xd5, 0xc4, 0x57, 0x1b, 0xd0, 0x88, 0x1e, 0x65, 0xd0, + 0x57, 0x50, 0x33, 0x73, 0xde, 0x5b, 0x18, 0x95, 0xfb, 0x16, 0x1c, 0x50, 0x90, 0xb6, 0x01, 0x82, 0x24, 0x9e, 0xdd, + 0xcb, 0x70, 0x7d, 0x2d, 0x85, 0x01, 0x37, 0x81, 0x19, 0x30, 0x30, 0xfd, 0x0c, 0x7e, 0x58, 0xe9, 0x12, 0x21, 0xce, + 0x7e, 0x4a, 0x49, 0x32, 0xcf, 0xdf, 0x8b, 0x34, 0x77, 0x0b, 0xd7, 0x29, 0xcc, 0x8a, 0x02, 0xd5, 0x4f, 0x49, 0x69, + 0x60, 0xa1, 0x12, 0x99, 0x4a, 0xc1, 0x2f, 0x9b, 0xf3, 0x28, 0x3b, 0x46, 0xe7, 0x3a, 0xbf, 0x9c, 0x38, 0xa7, 0x93, + 0xbe, 0xff, 0xc0, 0x31, 0x6c, 0x21, 0x03, 0x17, 0xfe, 0xd4, 0x13, 0xc6, 0xa9, 0x15, 0x88, 0xa9, 0xe4, 0xd9, 0x53, + 0xf8, 0x4c, 0x68, 0x75, 0x74, 0xe1, 0xfb, 0x41, 0xa1, 0x4d, 0xd2, 0x2d, 0x48, 0x52, 0xf0, 0x14, 0x3d, 0xe7, 0xbc, + 0x0d, 0x54, 0x8a, 0x11, 0x2d, 0x88, 0xb4, 0xb5, 0xce, 0x1c, 0xa4, 0x2d, 0xcd, 0x77, 0x4d, 0xfc, 0x1c, 0x16, 0x70, + 0x11, 0x2d, 0x6c, 0x0d, 0x8f, 0xaa, 0x58, 0xb9, 0x37, 0x79, 0x8e, 0x70, 0x46, 0x97, 0x32, 0x01, 0x70, 0xbd, 0x5f, + 0x85, 0xb5, 0xc2, 0x2b, 0x6a, 0x6e, 0xf2, 0xa2, 0xa6, 0x4f, 0xb6, 0xc0, 0x7d, 0x2c, 0x4a, 0x14, 0x38, 0x6b, 0xc1, + 0x80, 0xad, 0xb0, 0x64, 0x27, 0x85, 0x4d, 0xd1, 0x12, 0x7a, 0x7b, 0xfc, 0x74, 0x50, 0x33, 0x19, 0x40, 0x13, 0x40, + 0xe3, 0xf1, 0x2f, 0x00, 0x35, 0xbd, 0xae, 0xc5, 0xba, 0x0a, 0x4a, 0xa5, 0xdc, 0x84, 0x9f, 0x81, 0x61, 0x86, 0x1f, + 0x0a, 0xb9, 0x4d, 0x94, 0xc8, 0xf9, 0x71, 0x53, 0x8a, 0x45, 0x29, 0xaa, 0xa4, 0xdd, 0x50, 0xf0, 0x88, 0x70, 0x1b, + 0x34, 0x66, 0x6e, 0x4f, 0x74, 0xd1, 0x8a, 0x50, 0x8e, 0xcd, 0x3a, 0x46, 0x1a, 0x65, 0x76, 0xb2, 0xeb, 0x64, 0xa1, + 0xfd, 0xbe, 0xca, 0x21, 0xeb, 0x80, 0x35, 0x92, 0xaf, 0xd7, 0x1c, 0xba, 0x6d, 0x94, 0x17, 0xf7, 0x9e, 0xaf, 0xe0, + 0x34, 0xc7, 0x13, 0xbb, 0xeb, 0x75, 0xa7, 0x48, 0xc4, 0x2b, 0x9c, 0x54, 0xf9, 0x48, 0x16, 0x8e, 0x3b, 0x77, 0x5a, + 0x8b, 0x55, 0xe5, 0xb2, 0x9e, 0x5a, 0x1c, 0x11, 0xf8, 0x54, 0x1e, 0xed, 0x85, 0xb6, 0x45, 0xb1, 0x10, 0x46, 0x8f, + 0x4e, 0xf8, 0x49, 0x09, 0xac, 0xaf, 0xc3, 0x61, 0xe9, 0x47, 0x1c, 0xfd, 0x4e, 0xa3, 0xd1, 0x0d, 0x21, 0x0d, 0x4f, + 0xbd, 0x68, 0x74, 0x53, 0x17, 0x75, 0x98, 0x3d, 0xcb, 0xf5, 0x40, 0x61, 0x18, 0x81, 0xfa, 0xc1, 0x55, 0x06, 0x9f, + 0x45, 0x88, 0x9a, 0x07, 0xa6, 0xd9, 0x10, 0x8e, 0xba, 0xc0, 0x43, 0x2b, 0x68, 0x31, 0x33, 0x1f, 0x85, 0x18, 0x3e, + 0xa4, 0x8b, 0xf3, 0x27, 0x64, 0xe5, 0x03, 0xec, 0x0e, 0xdd, 0x85, 0x72, 0xce, 0x54, 0x0c, 0xf0, 0xa3, 0x80, 0x7c, + 0x94, 0x80, 0x9b, 0x01, 0xb2, 0x47, 0x96, 0x00, 0x62, 0xc5, 0xe8, 0x68, 0xf2, 0xb9, 0xef, 0x45, 0x0a, 0xde, 0xd9, + 0x67, 0xb9, 0x9a, 0x30, 0x14, 0x3e, 0x31, 0xd0, 0xcd, 0x6f, 0xfc, 0xf6, 0xbc, 0x05, 0x23, 0xbb, 0x24, 0xc5, 0x6b, + 0xcd, 0x70, 0xbf, 0x01, 0xb7, 0x23, 0xa0, 0xac, 0xa9, 0x8e, 0x49, 0xb6, 0x69, 0x88, 0x64, 0xc0, 0x8c, 0x18, 0x11, + 0x54, 0x96, 0x0b, 0xff, 0xbb, 0x97, 0x45, 0x81, 0x03, 0xb8, 0x9a, 0xc9, 0xe0, 0xb5, 0x0b, 0xa3, 0x02, 0xe0, 0x9c, + 0x86, 0x4e, 0x69, 0xaf, 0xaa, 0x0e, 0xc9, 0xaa, 0xf9, 0xc1, 0x6c, 0xde, 0x34, 0x4c, 0x8c, 0x08, 0xa2, 0x8b, 0x70, + 0x82, 0xe9, 0x15, 0xe9, 0x6b, 0x25, 0xa7, 0xa3, 0x55, 0x47, 0x6b, 0x89, 0x89, 0xb9, 0xa2, 0xf8, 0x6b, 0xc0, 0xe3, + 0x06, 0xaf, 0x4e, 0xd2, 0x74, 0xa2, 0x7a, 0xf4, 0xf8, 0x75, 0x9a, 0x4e, 0x4a, 0xdc, 0x15, 0x7e, 0x03, 0x2e, 0x9a, + 0x6d, 0x3e, 0xf4, 0xe3, 0x17, 0x14, 0x71, 0x51, 0x83, 0x2b, 0xef, 0x54, 0x5f, 0xa9, 0x3e, 0x82, 0x5a, 0x78, 0x62, + 0x64, 0x2d, 0x3c, 0xb9, 0x64, 0xad, 0x05, 0xc1, 0xcc, 0xe6, 0xc0, 0x85, 0xfc, 0x4a, 0x29, 0xe2, 0x4d, 0x24, 0xd4, + 0x62, 0xd0, 0x7a, 0xcc, 0x9c, 0x55, 0xa3, 0x1b, 0x95, 0x19, 0xa1, 0x7d, 0x5b, 0x8b, 0xce, 0x6f, 0xe4, 0xa7, 0x3c, + 0xb5, 0x2f, 0xdb, 0xe3, 0x7c, 0xbc, 0x47, 0x77, 0xd5, 0x59, 0x66, 0x52, 0xc6, 0x27, 0xb3, 0x04, 0x85, 0xbb, 0x04, + 0x1b, 0x90, 0x64, 0xbf, 0xd5, 0x01, 0x32, 0x6a, 0xaf, 0xfd, 0xae, 0xb3, 0x7c, 0x75, 0xb3, 0x35, 0x14, 0x95, 0x5a, + 0x49, 0x8a, 0x83, 0x0c, 0xd7, 0x6d, 0xe5, 0xc3, 0xc5, 0x05, 0xf4, 0x8c, 0x91, 0xc8, 0x3c, 0x7f, 0x22, 0x5f, 0x82, + 0x73, 0xc6, 0x59, 0x21, 0x30, 0x61, 0xac, 0xde, 0xb5, 0x96, 0x4a, 0x43, 0x8a, 0xb1, 0xa3, 0x51, 0x96, 0x55, 0x96, + 0x2e, 0xb3, 0xb5, 0x84, 0x2d, 0xab, 0xc8, 0x2d, 0x6c, 0x9d, 0xc9, 0x6a, 0x7e, 0xa8, 0xb8, 0x83, 0xf2, 0xcd, 0x96, + 0x19, 0xdf, 0x4b, 0x64, 0xef, 0x36, 0x50, 0xc2, 0xb3, 0xd1, 0x7f, 0x20, 0xfd, 0x36, 0xc3, 0x38, 0xe5, 0xb6, 0x92, + 0x16, 0xe0, 0xf4, 0x0f, 0x87, 0x0f, 0x15, 0x06, 0x0d, 0x8e, 0x30, 0x8e, 0xac, 0xdf, 0xbf, 0xa9, 0xbc, 0x1a, 0x13, + 0x75, 0x7c, 0x56, 0xbf, 0x5f, 0xd1, 0xc3, 0x69, 0x35, 0x5a, 0xa5, 0x5b, 0x64, 0x27, 0xb4, 0xb1, 0xf2, 0x83, 0x5a, + 0x01, 0xb3, 0xb7, 0x3e, 0x9f, 0x0e, 0x40, 0xc7, 0x02, 0x24, 0x9a, 0xcd, 0x44, 0x62, 0x4e, 0xba, 0x27, 0xe1, 0xf1, + 0x81, 0x05, 0x0e, 0x30, 0x15, 0xff, 0xa7, 0xf0, 0x66, 0x60, 0x83, 0x46, 0x89, 0xbe, 0x46, 0x57, 0xb5, 0xb9, 0xd1, + 0xf1, 0xd2, 0x53, 0x48, 0x64, 0x05, 0xab, 0xe6, 0xbe, 0xdc, 0xc0, 0x69, 0x0f, 0x35, 0x87, 0xca, 0x02, 0xfc, 0xed, + 0x17, 0x60, 0xf0, 0xc8, 0xa0, 0xb0, 0xdd, 0x5a, 0x68, 0x6f, 0xcc, 0x52, 0x0d, 0x15, 0xe1, 0xa0, 0xf3, 0x95, 0x98, + 0xd5, 0x23, 0xfa, 0x7b, 0x7e, 0x38, 0xac, 0x08, 0x0c, 0x38, 0x2c, 0x65, 0x26, 0x5a, 0x28, 0x96, 0xd6, 0xd9, 0x8c, + 0xea, 0xc0, 0x03, 0x13, 0x73, 0x16, 0xee, 0x00, 0xb4, 0x49, 0xad, 0x02, 0xbd, 0x8a, 0xe8, 0x27, 0xee, 0xd7, 0xf6, + 0xeb, 0xf5, 0xc8, 0x2c, 0x1d, 0xb9, 0x31, 0x16, 0x00, 0x1c, 0x78, 0x5e, 0x93, 0x3c, 0x27, 0x5f, 0x43, 0xbb, 0x27, + 0x17, 0xf2, 0x27, 0x28, 0x5b, 0x78, 0xae, 0x9a, 0x56, 0x16, 0x2b, 0xae, 0xaa, 0x57, 0x17, 0xbc, 0x32, 0x99, 0x56, + 0x69, 0x25, 0x2a, 0x25, 0x18, 0x50, 0x97, 0x78, 0xad, 0x69, 0x46, 0xa9, 0x8d, 0x3a, 0x13, 0x35, 0x60, 0x83, 0xfd, + 0x54, 0x6d, 0x74, 0x72, 0x2e, 0x9f, 0x5f, 0x1a, 0x87, 0x4f, 0xbb, 0x7a, 0x33, 0x53, 0x39, 0xf0, 0xd7, 0xca, 0x87, + 0x56, 0x8f, 0x81, 0x0e, 0xc8, 0xe9, 0x8f, 0x61, 0x31, 0xb1, 0x3b, 0x34, 0x6f, 0x77, 0x97, 0xd5, 0x45, 0x7a, 0xa7, + 0x29, 0x99, 0xd5, 0x5b, 0x3e, 0xb3, 0x7a, 0x74, 0xc0, 0x8b, 0x87, 0x7a, 0xaf, 0x30, 0x93, 0x08, 0x2e, 0x86, 0x6a, + 0x12, 0xd9, 0x1d, 0x68, 0xcd, 0xa3, 0x8a, 0x09, 0xf0, 0x83, 0x52, 0x6b, 0x7a, 0x6f, 0x77, 0x85, 0x3a, 0xa5, 0xf0, + 0xb8, 0xb5, 0xe4, 0x07, 0xe6, 0x4e, 0xbb, 0xd6, 0xf9, 0x78, 0x7e, 0xe9, 0xfb, 0x8d, 0x3c, 0xa1, 0xcd, 0xce, 0xe4, + 0xf4, 0x4f, 0xde, 0xea, 0x1f, 0xa6, 0xfa, 0x16, 0xba, 0x13, 0xf4, 0x19, 0xba, 0xaa, 0xba, 0x2b, 0xb1, 0x85, 0xa1, + 0x9e, 0x58, 0xe4, 0x85, 0x3c, 0x69, 0x8d, 0x1d, 0x07, 0x7b, 0x03, 0x9c, 0xf8, 0xe5, 0xe1, 0x20, 0xae, 0x72, 0x9f, + 0x9d, 0x77, 0x8d, 0xac, 0x1c, 0xc0, 0x0a, 0xa2, 0x60, 0xdc, 0x9a, 0x8f, 0x6d, 0x90, 0x2e, 0x71, 0x35, 0x3e, 0x7e, + 0x43, 0xb1, 0x4c, 0x36, 0x11, 0x17, 0x17, 0xf9, 0xe3, 0xa7, 0x40, 0x5a, 0xd6, 0xef, 0x47, 0xcf, 0x2e, 0xa7, 0x4f, + 0x87, 0x51, 0x00, 0x8e, 0x5d, 0xf6, 0xf2, 0x32, 0xe6, 0xab, 0x4b, 0x66, 0x99, 0xc2, 0x22, 0xdf, 0x0c, 0xa8, 0x2e, + 0x59, 0x2d, 0x5d, 0xaf, 0x00, 0x4b, 0x97, 0xdf, 0xdc, 0x87, 0xa9, 0x01, 0x8d, 0xac, 0xb9, 0x3b, 0xcd, 0xb5, 0x40, + 0xa9, 0xe7, 0xfd, 0xcc, 0x90, 0xaf, 0xcb, 0xa0, 0x2b, 0x48, 0xf7, 0x3c, 0x22, 0xbd, 0xdc, 0x4b, 0xa7, 0xfb, 0x7d, + 0x29, 0xc0, 0x52, 0x5f, 0x8a, 0x2f, 0xa0, 0xb0, 0x68, 0x7c, 0x23, 0x40, 0x5b, 0x43, 0x35, 0xed, 0x95, 0xa2, 0xea, + 0x05, 0xbd, 0x52, 0x7c, 0xe9, 0xe9, 0xa1, 0x32, 0x5f, 0x96, 0x8e, 0xfe, 0x27, 0xd4, 0x5c, 0x70, 0x42, 0xcc, 0xc4, + 0x1c, 0x40, 0x25, 0x68, 0xe3, 0xbb, 0x3d, 0xda, 0xf8, 0x54, 0xaf, 0xe2, 0xa6, 0xcf, 0x6b, 0x6b, 0x99, 0x13, 0xc2, + 0xa6, 0x7b, 0x09, 0x50, 0x91, 0x57, 0xc2, 0x23, 0x58, 0x7e, 0xf9, 0x43, 0x9e, 0xae, 0x10, 0xad, 0xe3, 0x9e, 0x65, + 0x2e, 0x8d, 0xfd, 0x6b, 0x83, 0xe9, 0xeb, 0xdb, 0x6d, 0x91, 0x9f, 0x9a, 0x98, 0xb0, 0x1e, 0x2b, 0xfa, 0xe6, 0x5d, + 0xb8, 0x12, 0x28, 0x70, 0x28, 0x91, 0xd8, 0xa6, 0x0a, 0x45, 0x3c, 0x48, 0xfa, 0x74, 0xd1, 0xfa, 0x34, 0xc0, 0xd4, + 0x5a, 0x0e, 0xcc, 0x21, 0x5c, 0xc5, 0x85, 0x8f, 0x9e, 0xbe, 0xc5, 0x2c, 0x9c, 0x4f, 0xbc, 0x8f, 0x5e, 0x31, 0x32, + 0x1f, 0xf7, 0x51, 0xa9, 0xa4, 0x7f, 0x1e, 0x0e, 0xb3, 0x6a, 0xee, 0x3b, 0xf4, 0x91, 0x1e, 0xaa, 0x5c, 0x50, 0xf6, + 0xc6, 0x98, 0x44, 0xa0, 0x34, 0xc6, 0xfb, 0x38, 0x38, 0xce, 0xfb, 0x34, 0x80, 0xd4, 0x3e, 0xf1, 0x9e, 0x94, 0x1c, + 0x9e, 0x73, 0xcc, 0x09, 0xa5, 0x15, 0x01, 0x13, 0x7a, 0x86, 0x72, 0xdd, 0x29, 0x05, 0x93, 0x1c, 0x12, 0x0c, 0x7f, + 0xd5, 0xbc, 0x89, 0x15, 0x08, 0xbb, 0x66, 0x5e, 0x8d, 0x1e, 0x55, 0x49, 0x58, 0x0a, 0x38, 0x2a, 0x33, 0xcf, 0xb0, + 0x37, 0x3c, 0x32, 0x8c, 0x1c, 0x2c, 0xf7, 0x47, 0x75, 0x22, 0x72, 0x8f, 0x2e, 0x30, 0x2a, 0x0b, 0xcf, 0x1b, 0xba, + 0xd2, 0xa0, 0x92, 0xec, 0xf8, 0x2b, 0xae, 0x01, 0xb5, 0x35, 0x46, 0x0c, 0x05, 0x8c, 0x82, 0xd7, 0xf6, 0x87, 0x90, + 0x45, 0xd9, 0xfa, 0x0d, 0x8e, 0xf9, 0xac, 0xe4, 0xae, 0x77, 0x38, 0x0b, 0x2d, 0x21, 0x4f, 0xee, 0x18, 0xa4, 0x69, + 0x2c, 0x8d, 0x80, 0x13, 0x91, 0x6c, 0x63, 0x29, 0x1c, 0x01, 0x04, 0x04, 0xba, 0x29, 0x33, 0x8c, 0xe9, 0x60, 0xe4, + 0x79, 0xd4, 0x33, 0xde, 0xab, 0xf0, 0x14, 0xd2, 0x64, 0xfb, 0x7a, 0xfe, 0xde, 0x08, 0xb2, 0x72, 0xcb, 0x39, 0x1e, + 0x16, 0xdf, 0x38, 0xfb, 0x2a, 0x27, 0x4f, 0x31, 0xcb, 0x48, 0xef, 0x14, 0xf3, 0x02, 0xfe, 0x54, 0x96, 0xfa, 0x1c, + 0xa5, 0xb7, 0xcc, 0x27, 0xab, 0x48, 0xba, 0xf0, 0x36, 0xfd, 0x7e, 0x3c, 0x52, 0x87, 0x9a, 0xbf, 0x8f, 0x47, 0xf2, + 0x0c, 0xdb, 0xb0, 0x84, 0x85, 0x56, 0xc1, 0x18, 0x40, 0x12, 0x1b, 0x11, 0x0d, 0x46, 0x7b, 0x73, 0x38, 0x9c, 0x6f, + 0xcc, 0x59, 0xb2, 0x07, 0xd7, 0x57, 0x9e, 0x98, 0x77, 0xe0, 0xcb, 0x3c, 0x26, 0x88, 0xd8, 0xcc, 0xdb, 0xb0, 0x1a, + 0x3c, 0xd8, 0xc1, 0xf5, 0x11, 0x5b, 0x14, 0x6b, 0x1d, 0x4b, 0x65, 0x1d, 0x9c, 0xd6, 0xb1, 0x69, 0x46, 0x4a, 0x91, + 0x7d, 0x8e, 0xfd, 0xbd, 0x1b, 0x5c, 0x5d, 0x1b, 0x83, 0x5a, 0xe3, 0x0e, 0x73, 0xe7, 0x54, 0x40, 0x3d, 0xa6, 0x2b, + 0xa8, 0x9e, 0x55, 0xe4, 0xcb, 0x6f, 0xed, 0x1c, 0x10, 0x34, 0x02, 0x81, 0x8b, 0x06, 0x4a, 0xa6, 0x4b, 0x39, 0xef, + 0x02, 0x42, 0x7c, 0x97, 0x82, 0x3e, 0x9d, 0xc1, 0x26, 0x36, 0x9f, 0x40, 0x2c, 0x9a, 0xee, 0x73, 0xad, 0x99, 0x2f, + 0x46, 0xb4, 0x33, 0xeb, 0x6e, 0x91, 0x5b, 0x2d, 0x44, 0x32, 0x7a, 0xb6, 0x99, 0x70, 0xd7, 0xa1, 0x9c, 0x91, 0x80, + 0x09, 0x5a, 0x5b, 0x29, 0xf9, 0x5c, 0xf7, 0x3a, 0x41, 0x7b, 0x20, 0x69, 0xdd, 0xbf, 0x59, 0x74, 0x46, 0xc9, 0xc9, + 0xf5, 0x26, 0x67, 0x90, 0x82, 0x05, 0xdb, 0xcb, 0x9c, 0x70, 0x03, 0x7c, 0x64, 0xb3, 0xe4, 0x34, 0x0d, 0xf2, 0x58, + 0x18, 0xa4, 0x8f, 0x36, 0xbf, 0x2c, 0xa0, 0x43, 0xc9, 0xa2, 0x11, 0xe2, 0x01, 0x76, 0x0e, 0xc9, 0x55, 0x81, 0xba, + 0x69, 0xa0, 0x2b, 0x57, 0xce, 0x14, 0x53, 0xe0, 0x42, 0x28, 0x88, 0xda, 0xd1, 0x49, 0x54, 0xce, 0xfb, 0xa4, 0xba, + 0xcc, 0xa7, 0x85, 0x34, 0x0d, 0xe4, 0xd3, 0xca, 0x31, 0x0f, 0x6c, 0x6d, 0xe3, 0x9a, 0xc0, 0x40, 0xa7, 0xf6, 0xb5, + 0x28, 0xe7, 0x58, 0x45, 0xf4, 0x3e, 0x7f, 0x54, 0xd9, 0xd3, 0x07, 0x11, 0x36, 0x2a, 0xd0, 0x58, 0x4a, 0x8c, 0x8d, + 0x1c, 0xff, 0x96, 0x28, 0x1b, 0x32, 0x04, 0x84, 0x90, 0x36, 0x72, 0xfa, 0x61, 0x7d, 0xf9, 0x2e, 0xd3, 0xfe, 0x9f, + 0x24, 0x7e, 0x1b, 0xec, 0xe5, 0xd4, 0x9f, 0x7a, 0xc4, 0xe3, 0xb5, 0x46, 0x8f, 0x29, 0xe9, 0x36, 0xc8, 0x53, 0xe5, + 0x29, 0x48, 0x26, 0x8c, 0x05, 0x04, 0x8b, 0x72, 0xc1, 0x73, 0x5e, 0x71, 0x09, 0xf7, 0x51, 0xcb, 0x8a, 0x08, 0x55, + 0x89, 0x9c, 0x3e, 0x5f, 0x01, 0xcf, 0x04, 0x04, 0x3a, 0xc6, 0x48, 0xa3, 0x0a, 0xbe, 0x04, 0xc6, 0x3a, 0x50, 0x76, + 0x9a, 0x91, 0xe0, 0xb2, 0x7b, 0x8d, 0x44, 0xa9, 0xaf, 0x48, 0x49, 0xfa, 0x56, 0xd4, 0x78, 0x25, 0x56, 0x11, 0x09, + 0x64, 0xa8, 0x21, 0x62, 0x55, 0x3d, 0x75, 0xaf, 0x8a, 0xc9, 0x60, 0x50, 0xf9, 0x72, 0x7a, 0xe2, 0x0d, 0x0d, 0x95, + 0x77, 0x5d, 0xd1, 0x4e, 0xcf, 0xb5, 0x52, 0xde, 0x42, 0x5a, 0x82, 0xa6, 0x61, 0xa4, 0x39, 0x94, 0xba, 0x92, 0xee, + 0xc6, 0x20, 0xbe, 0x64, 0xa2, 0x67, 0x3b, 0xb5, 0xa3, 0xb4, 0x25, 0xed, 0x21, 0xa4, 0xe7, 0x2e, 0xf9, 0x98, 0x85, + 0x5c, 0xdd, 0x29, 0x27, 0xe5, 0x55, 0x88, 0x4e, 0xee, 0x7b, 0x0c, 0x89, 0x40, 0x9f, 0x73, 0x0c, 0xeb, 0xa2, 0xa1, + 0xce, 0x61, 0x85, 0x98, 0x2d, 0x94, 0x30, 0x5f, 0x32, 0x9e, 0x4a, 0x06, 0x0d, 0x80, 0x0c, 0xf8, 0xe2, 0x65, 0x60, + 0xf9, 0x2b, 0x88, 0x1f, 0x6d, 0x7c, 0x38, 0xfc, 0x55, 0x53, 0x88, 0xed, 0x5f, 0xb0, 0x19, 0xc2, 0xa3, 0x7a, 0xc0, + 0x33, 0xdf, 0xc4, 0x09, 0x5a, 0x01, 0x49, 0x99, 0x1d, 0x4d, 0x64, 0xaf, 0x7a, 0x08, 0xa7, 0xb2, 0x02, 0x75, 0x94, + 0x75, 0x56, 0xc2, 0x8f, 0x30, 0xd5, 0xad, 0xc4, 0x5a, 0xa0, 0xcd, 0xd5, 0x8a, 0xb5, 0x00, 0x0e, 0xfc, 0x1c, 0x82, + 0x27, 0xf2, 0x39, 0xb8, 0x18, 0x14, 0xe0, 0x73, 0x00, 0xbc, 0xc8, 0x5d, 0x78, 0x30, 0x0f, 0x2c, 0xab, 0x11, 0x86, + 0xa3, 0x8a, 0x58, 0xbf, 0x66, 0x3b, 0xf2, 0x81, 0xdb, 0x31, 0x3e, 0xd7, 0x1e, 0x4b, 0x96, 0x83, 0x51, 0xe6, 0x5e, + 0x2d, 0xd1, 0xf3, 0x26, 0x8d, 0x9b, 0xd1, 0xa3, 0x7d, 0x2d, 0xff, 0x17, 0xf4, 0x32, 0xe8, 0x6f, 0xe1, 0x96, 0xd7, + 0xfc, 0x61, 0xb9, 0x70, 0x9a, 0x5e, 0x41, 0xa4, 0x8c, 0x1a, 0x91, 0x31, 0x84, 0x4d, 0xaa, 0x9b, 0xdb, 0xa4, 0xba, + 0x10, 0xf0, 0x74, 0x44, 0xaa, 0x6b, 0x21, 0x6d, 0xe4, 0xd3, 0x3a, 0x90, 0xb1, 0x48, 0xef, 0x7e, 0xfc, 0xdb, 0xf3, + 0x4f, 0x6f, 0x7e, 0xfb, 0xf1, 0xe6, 0xcd, 0xbb, 0xd7, 0x6f, 0xde, 0xbd, 0xf9, 0xf4, 0x3b, 0x41, 0x78, 0x4c, 0x85, + 0xca, 0xf0, 0xe1, 0xfd, 0xf5, 0x1b, 0x27, 0x83, 0xed, 0xcd, 0x90, 0xb5, 0x6f, 0xe4, 0x60, 0x08, 0x44, 0x36, 0x08, + 0x19, 0x64, 0xa7, 0x64, 0x8e, 0x99, 0x98, 0x63, 0xec, 0x9d, 0xc0, 0x64, 0x0b, 0x92, 0xc3, 0x32, 0x2f, 0x19, 0x91, + 0xab, 0x42, 0xeb, 0x07, 0xb4, 0xe0, 0x2d, 0xb8, 0xc8, 0xa4, 0xf9, 0xf2, 0x37, 0x82, 0xd8, 0xa7, 0x95, 0x94, 0xfb, + 0x6a, 0x5b, 0xf3, 0x7c, 0x7b, 0xbf, 0x97, 0x70, 0xfe, 0x73, 0x69, 0x44, 0x2d, 0xc0, 0x01, 0xf8, 0x1c, 0xfe, 0xb8, + 0xd2, 0x96, 0x34, 0x99, 0x45, 0xfb, 0x19, 0x43, 0xd0, 0xa5, 0x81, 0x34, 0xb1, 0x47, 0x5e, 0xea, 0x93, 0x85, 0x04, + 0xee, 0x88, 0xe1, 0xd3, 0x8a, 0xa0, 0x57, 0x8c, 0x28, 0x2e, 0xb9, 0x42, 0xa5, 0x94, 0xfc, 0x1b, 0x65, 0x17, 0x15, + 0x72, 0x56, 0xb0, 0x3b, 0x45, 0x8e, 0x8c, 0x1f, 0x04, 0x13, 0x5f, 0x0e, 0xee, 0xbf, 0xc4, 0x3b, 0x9c, 0x29, 0x8e, + 0xe4, 0x84, 0xff, 0x99, 0x61, 0x60, 0x7f, 0x0e, 0x3e, 0xaf, 0x0e, 0xf3, 0xf2, 0x46, 0x9f, 0x72, 0x0b, 0x3e, 0x9e, + 0x2c, 0xae, 0xc0, 0x60, 0xbf, 0x50, 0xcd, 0x5d, 0xf3, 0x7a, 0xb6, 0x98, 0xb3, 0xfd, 0x2c, 0x9a, 0x07, 0x4b, 0x36, + 0xcb, 0xe6, 0xc1, 0xaa, 0xe1, 0x6b, 0x76, 0xcb, 0xd7, 0x56, 0xd5, 0xd6, 0x76, 0xd5, 0x26, 0x1b, 0x7e, 0x0b, 0x12, + 0xc2, 0xdb, 0xcc, 0x03, 0xde, 0xe3, 0xa5, 0xcf, 0x36, 0x20, 0xd1, 0xae, 0xd8, 0x06, 0x2e, 0x62, 0x6b, 0xfe, 0xa6, + 0xf2, 0x36, 0xac, 0x64, 0xe7, 0x63, 0x96, 0xe3, 0xfc, 0xf3, 0xe1, 0x01, 0xed, 0x85, 0xfa, 0xd9, 0xa5, 0x7a, 0x36, + 0x51, 0x76, 0xb3, 0xcd, 0xe8, 0xe6, 0x2e, 0xad, 0x36, 0x61, 0x86, 0x9e, 0xe5, 0xf0, 0xd1, 0x56, 0x0a, 0x7e, 0xfa, + 0x06, 0xbf, 0x64, 0x4d, 0x9c, 0x7f, 0xa6, 0x6d, 0xbb, 0x2a, 0xb1, 0x15, 0xb4, 0x28, 0xb2, 0x5a, 0xe1, 0x81, 0x39, + 0x7f, 0x06, 0x0b, 0x18, 0x7b, 0x8e, 0x73, 0x5e, 0xfb, 0x23, 0x64, 0xbc, 0x77, 0x00, 0xd0, 0x32, 0xc7, 0x01, 0x1e, + 0xb1, 0x62, 0x14, 0x0d, 0xde, 0xf9, 0xa5, 0xb2, 0x5a, 0x69, 0x4e, 0x42, 0xdb, 0x88, 0x55, 0xcb, 0x91, 0xaa, 0x19, + 0x91, 0x3e, 0x48, 0xcf, 0xfb, 0x1e, 0x51, 0x0d, 0xf6, 0x64, 0x5e, 0x07, 0xf6, 0xe9, 0x7d, 0x6b, 0x55, 0x77, 0x7e, + 0x4f, 0x95, 0x2e, 0x39, 0xb2, 0xe5, 0xa7, 0xcb, 0xf0, 0x5e, 0xfd, 0x29, 0xb9, 0x3e, 0x14, 0x38, 0xc2, 0x43, 0x15, + 0x70, 0xbe, 0x5e, 0x89, 0x76, 0x27, 0xc2, 0xae, 0x5c, 0x02, 0x42, 0x7c, 0x49, 0xd3, 0x1c, 0x8f, 0x23, 0x9a, 0x88, + 0xb0, 0x89, 0xd1, 0x5f, 0xd8, 0x7d, 0x28, 0xb1, 0x9c, 0xe7, 0x1a, 0x94, 0x5c, 0x32, 0x78, 0x4f, 0xda, 0x6b, 0xd0, + 0x2c, 0xaf, 0x4a, 0x4d, 0x26, 0x72, 0x50, 0x3e, 0x1c, 0x0a, 0xd8, 0x4b, 0x8d, 0x9f, 0x26, 0xfc, 0x84, 0xe5, 0xad, + 0xbd, 0x35, 0xa5, 0xa8, 0xa4, 0x01, 0x2a, 0xf0, 0x31, 0x83, 0xff, 0xdd, 0x19, 0x62, 0xc1, 0x14, 0x1d, 0x3f, 0x9c, + 0x89, 0xb9, 0xf5, 0xdc, 0x2a, 0xeb, 0x28, 0x5b, 0xa3, 0x9c, 0x80, 0x7f, 0x4f, 0x75, 0x9c, 0x24, 0xc2, 0xa9, 0xf7, + 0x88, 0x8b, 0xba, 0x97, 0x43, 0xd4, 0x0d, 0xfb, 0x54, 0xe9, 0x60, 0xcb, 0x69, 0x1a, 0x1c, 0x89, 0x5f, 0xa9, 0xcf, + 0x3e, 0x64, 0x16, 0x8f, 0x3a, 0xb2, 0x11, 0x25, 0x69, 0x1c, 0x8b, 0x1c, 0xb6, 0xf7, 0x1b, 0xb9, 0xff, 0xf7, 0xfb, + 0x10, 0x4e, 0x5a, 0x05, 0x71, 0xe9, 0x09, 0x44, 0x84, 0xa3, 0xc3, 0x8f, 0x08, 0x4f, 0xa4, 0xaa, 0xf0, 0x51, 0x7d, + 0xe2, 0xc6, 0xec, 0x5e, 0x98, 0xa3, 0x7a, 0x0b, 0x30, 0x8c, 0xf5, 0xd6, 0x22, 0x24, 0xd1, 0x4a, 0x33, 0xda, 0x7a, + 0x40, 0x8c, 0x78, 0xbf, 0xb6, 0xc8, 0x60, 0xac, 0x2d, 0x89, 0x04, 0xf0, 0x25, 0x09, 0x19, 0xda, 0x36, 0x02, 0x33, + 0x86, 0xb7, 0xb3, 0xe2, 0xd2, 0x75, 0xd8, 0xe6, 0x1c, 0xbe, 0x90, 0x1b, 0xcd, 0x3a, 0xa2, 0x34, 0x41, 0xc8, 0x3f, + 0xe0, 0x64, 0xa1, 0x30, 0x9a, 0x57, 0x47, 0xe9, 0x24, 0xb1, 0xbe, 0xef, 0x2a, 0x15, 0x6c, 0x36, 0xd7, 0xa8, 0x2f, + 0x3b, 0x4a, 0x7e, 0x09, 0x4e, 0x3a, 0x4e, 0xb2, 0xc8, 0x41, 0xd4, 0xa2, 0x72, 0xae, 0x93, 0xb0, 0xb4, 0xab, 0x53, + 0x6d, 0xd6, 0xeb, 0xa2, 0xac, 0xab, 0x57, 0x22, 0x52, 0xf4, 0x3e, 0xea, 0xd1, 0x23, 0x09, 0xa9, 0xd0, 0xaa, 0xd4, + 0x2e, 0x8f, 0xc0, 0x6d, 0x53, 0x2b, 0xb6, 0xe5, 0x12, 0x96, 0xa8, 0xf1, 0x9f, 0xa0, 0x8f, 0x72, 0x71, 0x2f, 0x03, + 0x34, 0x3a, 0x9e, 0x9a, 0xb7, 0x1e, 0x78, 0xe5, 0x28, 0xbf, 0xb4, 0xda, 0xa4, 0x5f, 0x01, 0x99, 0xd1, 0xfe, 0xd1, + 0x52, 0x02, 0x99, 0x81, 0x99, 0xb4, 0x34, 0x24, 0x72, 0x14, 0xb3, 0x34, 0xff, 0x13, 0x57, 0x6c, 0x85, 0x48, 0xc3, + 0x6a, 0xee, 0xf1, 0x1f, 0x2b, 0xaf, 0x96, 0x6b, 0x99, 0x69, 0x6e, 0x96, 0x38, 0x56, 0x2c, 0x2e, 0xea, 0x75, 0x25, + 0xb2, 0x40, 0x88, 0x23, 0x4c, 0x63, 0x3d, 0xf5, 0x46, 0x69, 0xf5, 0x01, 0x09, 0x65, 0x7e, 0xc4, 0xde, 0x8e, 0xbd, + 0x1e, 0x64, 0x21, 0x8e, 0x2d, 0x07, 0x9b, 0xad, 0xf7, 0xa9, 0x4c, 0x45, 0x7c, 0x56, 0x17, 0x67, 0x9b, 0x4a, 0x9c, + 0xd5, 0x89, 0x38, 0xfb, 0x01, 0x72, 0xfe, 0x70, 0x46, 0x45, 0x9f, 0xdd, 0xa7, 0x75, 0x52, 0x6c, 0x6a, 0x7a, 0xf2, + 0x1a, 0xcb, 0xf8, 0xe1, 0x8c, 0xb8, 0x6a, 0xce, 0x68, 0x24, 0xe3, 0xd1, 0xd9, 0x87, 0x0c, 0x48, 0x5e, 0xcf, 0xd2, + 0x15, 0x0c, 0xde, 0x59, 0x98, 0xc7, 0x67, 0xa5, 0x58, 0x82, 0xc5, 0xa9, 0xec, 0x7c, 0x0f, 0x32, 0xac, 0xc2, 0x3f, + 0xc5, 0x19, 0x40, 0xbb, 0x9e, 0xa5, 0xf5, 0x59, 0x5a, 0x9d, 0xe5, 0x45, 0x7d, 0xa6, 0xa4, 0x70, 0x08, 0xe3, 0x87, + 0xf7, 0xf4, 0x95, 0x5d, 0xde, 0x66, 0x71, 0x97, 0x45, 0xfe, 0x14, 0xbd, 0x8a, 0x88, 0x49, 0xa3, 0x12, 0x5e, 0xbb, + 0xbf, 0x6d, 0xee, 0x1f, 0x5e, 0x37, 0x76, 0x3f, 0xbb, 0x63, 0x44, 0x17, 0xd4, 0xe3, 0x95, 0xa4, 0x54, 0x50, 0x40, + 0xe0, 0x44, 0xb3, 0xc6, 0x83, 0x3b, 0x0e, 0x78, 0x35, 0xb0, 0x05, 0x5b, 0xfb, 0xfc, 0x59, 0x2c, 0xc3, 0xb4, 0x37, + 0x01, 0xfe, 0x55, 0xf6, 0xa6, 0xeb, 0x60, 0x81, 0xf7, 0x2d, 0x64, 0x1b, 0x7a, 0xf3, 0x8a, 0x3f, 0xf7, 0x72, 0xf5, + 0x37, 0xfb, 0x27, 0x00, 0x61, 0x40, 0xcc, 0xaa, 0x8f, 0x26, 0xee, 0x9d, 0x95, 0x65, 0xe7, 0x64, 0xd9, 0xf5, 0xd0, + 0xaf, 0x49, 0x8c, 0x4a, 0x2b, 0x4b, 0xe9, 0x64, 0x29, 0x21, 0x0b, 0xf8, 0xc4, 0x68, 0x6a, 0x23, 0x80, 0xb0, 0x1d, + 0xa5, 0xf2, 0x85, 0xca, 0x8b, 0x28, 0x9c, 0x13, 0x3c, 0x4f, 0xc4, 0xe8, 0xce, 0x4a, 0x06, 0x0c, 0x87, 0x10, 0xcc, + 0x41, 0x5b, 0xec, 0x0d, 0xdd, 0x44, 0xfc, 0xf5, 0xba, 0x28, 0xdf, 0xc4, 0xe4, 0x53, 0xb0, 0x3b, 0xf9, 0xb8, 0x84, + 0xc7, 0xe5, 0xc9, 0xc7, 0x21, 0x7a, 0x24, 0x9c, 0x7c, 0x0c, 0xbe, 0x47, 0x72, 0x5e, 0x77, 0x3d, 0x4e, 0x90, 0x5b, + 0x48, 0xf7, 0xb7, 0x63, 0x12, 0xa0, 0x79, 0x0d, 0xcb, 0x51, 0x53, 0x71, 0xcd, 0xcc, 0x18, 0xcf, 0x1b, 0xbd, 0x3f, + 0x76, 0xbc, 0x65, 0x0a, 0xc5, 0x2c, 0xe6, 0x35, 0xfc, 0x9e, 0x55, 0x81, 0xba, 0xeb, 0x6d, 0x92, 0x5b, 0x66, 0xf5, + 0x1c, 0xed, 0xbe, 0xef, 0xeb, 0x44, 0x50, 0xfb, 0x3b, 0xec, 0x79, 0x66, 0xbd, 0xab, 0x62, 0xe0, 0x52, 0x25, 0x3b, + 0x64, 0xaa, 0x9a, 0x1e, 0xa8, 0x94, 0x06, 0x4f, 0x2f, 0xad, 0xcb, 0x97, 0x4a, 0x1b, 0x79, 0xa6, 0xf9, 0x0d, 0xe0, + 0xc5, 0xd4, 0x65, 0xb1, 0xfb, 0xe6, 0xbe, 0x82, 0xdb, 0x78, 0xbf, 0xbf, 0xae, 0x3c, 0xf3, 0x13, 0x17, 0x80, 0xbd, + 0xa9, 0xd0, 0x3a, 0x81, 0x52, 0xc3, 0x3a, 0x7c, 0x99, 0x88, 0xe8, 0xcf, 0x76, 0xb9, 0xce, 0x5c, 0x07, 0x8c, 0x28, + 0xe2, 0xb7, 0xf1, 0xe8, 0x0f, 0x50, 0x5c, 0x1b, 0x7b, 0x40, 0x58, 0x87, 0x84, 0x3e, 0x23, 0x00, 0xa9, 0x47, 0x1f, + 0x25, 0xf7, 0xa0, 0x59, 0xd1, 0xdc, 0x31, 0xf9, 0xb9, 0xbe, 0x52, 0xfa, 0xfb, 0x75, 0xe5, 0x91, 0x39, 0xa5, 0x6d, + 0xa6, 0xb1, 0x5a, 0x53, 0x09, 0x84, 0x57, 0x54, 0xb2, 0x0a, 0x9f, 0xcd, 0x1b, 0xd1, 0xef, 0xcb, 0x23, 0x3c, 0xad, + 0x7e, 0xdc, 0x62, 0x7c, 0x2b, 0x20, 0x1a, 0x09, 0x50, 0xb0, 0x02, 0xcc, 0x8b, 0x6c, 0x66, 0xf7, 0x71, 0x40, 0x95, + 0x12, 0x4d, 0xe3, 0x6c, 0x9e, 0xdf, 0xd3, 0x9b, 0xb2, 0x83, 0x4e, 0x9d, 0x2a, 0x70, 0xc1, 0x55, 0xc9, 0x78, 0x65, + 0x3d, 0x91, 0xcf, 0x6f, 0x6e, 0x37, 0x69, 0x16, 0xbf, 0x2f, 0x7f, 0xc5, 0xb1, 0xd5, 0x75, 0x78, 0x60, 0xea, 0x74, + 0xed, 0x3c, 0xd2, 0xda, 0x0b, 0x01, 0x11, 0xed, 0x1a, 0x6a, 0xbd, 0xb0, 0xd0, 0x23, 0x3d, 0x11, 0xce, 0x49, 0xa2, + 0xa6, 0x1d, 0x68, 0x69, 0x84, 0xbe, 0xbe, 0xe6, 0xf4, 0x17, 0x06, 0x6b, 0x9f, 0x8f, 0x19, 0x90, 0x95, 0xe8, 0xc7, + 0xea, 0xa1, 0xb1, 0x99, 0x43, 0xcf, 0x5a, 0x95, 0x67, 0x5e, 0x75, 0x38, 0x20, 0x3e, 0x8c, 0xfe, 0x92, 0xdf, 0xef, + 0xbf, 0xa2, 0xf9, 0xc7, 0x84, 0x1a, 0x3f, 0xdb, 0x0c, 0xd0, 0xb5, 0xef, 0xca, 0x03, 0x51, 0xcf, 0xb5, 0x4a, 0x10, + 0xe2, 0x0d, 0x62, 0xa2, 0x19, 0x31, 0x07, 0xa7, 0x1d, 0x6a, 0xfe, 0x49, 0x6a, 0x40, 0x88, 0x12, 0xaf, 0x63, 0xca, + 0x82, 0x9c, 0x36, 0x71, 0xa4, 0x1f, 0x85, 0x13, 0xf9, 0x51, 0x54, 0x45, 0x76, 0x07, 0x17, 0x0c, 0xa6, 0xde, 0xd3, + 0x7e, 0x89, 0x7e, 0x4b, 0x38, 0x72, 0x8e, 0x56, 0x85, 0x20, 0x72, 0x42, 0x58, 0x6b, 0x08, 0x13, 0xc4, 0x06, 0xf1, + 0xb2, 0xef, 0x92, 0x0c, 0x47, 0x0a, 0x2e, 0xeb, 0xd8, 0x31, 0xe6, 0xea, 0xa8, 0x7a, 0x0d, 0x60, 0xbc, 0x72, 0x04, + 0xcd, 0x46, 0x91, 0x5d, 0x42, 0x54, 0x91, 0xe3, 0x09, 0xa8, 0x1d, 0x94, 0xc6, 0x66, 0x7a, 0x3e, 0x0e, 0xf2, 0xd1, + 0x4d, 0x85, 0x3a, 0x27, 0x96, 0xf1, 0x1a, 0x80, 0xb5, 0x73, 0xd5, 0xcf, 0xb3, 0x1a, 0x3c, 0x69, 0x88, 0xcf, 0xc7, + 0x68, 0x7b, 0x65, 0x73, 0x50, 0x6d, 0xa7, 0xb3, 0xf2, 0x8a, 0xe9, 0x72, 0x60, 0xdc, 0x37, 0xbc, 0xa2, 0x38, 0xc3, + 0x8f, 0x1e, 0x6c, 0x71, 0xfe, 0x74, 0x43, 0xed, 0xc7, 0xdc, 0xa8, 0x87, 0x81, 0xd6, 0x82, 0x37, 0x05, 0xb1, 0xfe, + 0x7e, 0xe8, 0xc8, 0xf6, 0x5e, 0x8b, 0x8c, 0x26, 0x9f, 0xfd, 0xfc, 0x43, 0x99, 0xae, 0x52, 0xb8, 0x2f, 0x39, 0x59, + 0x34, 0xf3, 0x10, 0xd8, 0x1b, 0x62, 0xb8, 0x3e, 0x2a, 0x3c, 0xa2, 0xac, 0xdf, 0x87, 0xdf, 0x57, 0x19, 0x98, 0x62, + 0xe0, 0xba, 0x42, 0x30, 0x1e, 0x02, 0x41, 0x3c, 0x4c, 0xa3, 0x93, 0x41, 0x0d, 0xda, 0xf0, 0x0d, 0x40, 0x66, 0x80, + 0x47, 0xe6, 0xc2, 0x23, 0xe0, 0x2e, 0x70, 0xed, 0xc9, 0x78, 0xec, 0x4f, 0x4c, 0x43, 0xa3, 0xa6, 0x34, 0xd3, 0x73, + 0xe3, 0x37, 0x1d, 0xd5, 0x72, 0xed, 0xfc, 0xc7, 0x97, 0xfc, 0x06, 0xbd, 0xa0, 0xe5, 0xe5, 0x3e, 0x52, 0x97, 0xfb, + 0x8c, 0xe2, 0x32, 0x91, 0x1c, 0x16, 0xc4, 0xb2, 0x84, 0x03, 0x8f, 0x51, 0xc9, 0x62, 0x4b, 0x8f, 0x55, 0xd1, 0xf2, + 0x45, 0xb9, 0x41, 0x3a, 0x74, 0x42, 0xb0, 0x44, 0x05, 0xc1, 0x12, 0x18, 0x17, 0xb1, 0xe6, 0x9b, 0x41, 0xce, 0xe2, + 0xd9, 0x66, 0xce, 0x91, 0xb0, 0x2e, 0x39, 0x1c, 0x0a, 0x09, 0x36, 0x93, 0xcd, 0xd6, 0x73, 0xb6, 0xf6, 0x19, 0x28, + 0x01, 0x4a, 0x99, 0x26, 0x28, 0x4d, 0x2b, 0xb6, 0xe2, 0xa6, 0x35, 0x58, 0xad, 0xa6, 0x6c, 0x55, 0x53, 0x76, 0x4e, + 0x53, 0x8e, 0x2a, 0x28, 0x39, 0xa1, 0x14, 0x65, 0x18, 0xc0, 0x88, 0x4d, 0xa2, 0xab, 0x0c, 0x7d, 0xbc, 0x13, 0x1e, + 0x41, 0x15, 0x11, 0xf9, 0x84, 0x21, 0x04, 0x26, 0xa2, 0xb8, 0x50, 0x85, 0x62, 0x80, 0x8c, 0x48, 0x20, 0x98, 0xa8, + 0xd4, 0x29, 0x30, 0x1f, 0x4d, 0x15, 0xc3, 0xa6, 0x3d, 0x51, 0xbe, 0xa7, 0x8e, 0x7b, 0x94, 0x6d, 0x7e, 0x16, 0xbb, + 0x20, 0x44, 0xee, 0xc6, 0x9d, 0xfa, 0x19, 0xf1, 0xde, 0xee, 0x08, 0xe3, 0x27, 0x3b, 0x6e, 0x11, 0xae, 0x08, 0xb6, + 0x50, 0x73, 0x88, 0xc5, 0xbc, 0x9a, 0x24, 0xa8, 0x65, 0x49, 0xfc, 0x0d, 0x4f, 0x06, 0x39, 0x5b, 0x80, 0x07, 0xed, + 0x9c, 0x65, 0x80, 0xbf, 0x62, 0xb5, 0xe8, 0xf7, 0xda, 0x5b, 0x80, 0xfc, 0xb4, 0xb1, 0x1b, 0x85, 0x89, 0x11, 0x24, + 0xea, 0x76, 0x65, 0x20, 0x3f, 0x7c, 0xc0, 0xe9, 0x78, 0xec, 0x29, 0x63, 0x6e, 0x65, 0x7a, 0x99, 0xce, 0x95, 0x7c, + 0x23, 0xf7, 0xd2, 0x87, 0x5e, 0x82, 0x9d, 0x03, 0xde, 0x40, 0xda, 0xc0, 0x6b, 0xd8, 0x2e, 0xbc, 0x36, 0x48, 0x98, + 0x11, 0x60, 0x8b, 0xe3, 0x63, 0xa4, 0x04, 0x86, 0x70, 0x9c, 0xa5, 0x00, 0x4c, 0xa3, 0x2f, 0xb3, 0x95, 0x7d, 0x99, + 0xd5, 0x9a, 0x2d, 0x95, 0xd3, 0xbd, 0x73, 0xeb, 0x76, 0x3e, 0x97, 0x00, 0x60, 0x52, 0xe7, 0x40, 0x9c, 0x99, 0x60, + 0x97, 0x26, 0x91, 0xe5, 0x63, 0x98, 0x2f, 0xc5, 0xeb, 0xb2, 0x58, 0xa9, 0xae, 0x68, 0xfb, 0xcc, 0xe4, 0x33, 0xd2, + 0x49, 0xa8, 0x80, 0x82, 0x42, 0xae, 0xf5, 0xe9, 0xbb, 0xf0, 0x5d, 0x50, 0x68, 0x60, 0xb6, 0x0a, 0xf7, 0x34, 0x59, + 0x23, 0xf5, 0x46, 0xd5, 0xef, 0x93, 0x6b, 0x20, 0xd5, 0x99, 0x43, 0xcb, 0x9e, 0x57, 0x18, 0x20, 0x76, 0xd4, 0x67, + 0x24, 0xd4, 0x81, 0xd4, 0x03, 0x86, 0x10, 0x6d, 0xd3, 0xc7, 0x9f, 0x0c, 0x89, 0x2e, 0xc0, 0x16, 0xa2, 0x0d, 0xfc, + 0xf8, 0x13, 0xec, 0xb3, 0x20, 0x3c, 0xa6, 0xf9, 0x5b, 0x48, 0x3a, 0x36, 0x70, 0x5a, 0x7d, 0x0a, 0x3e, 0x48, 0x72, + 0x30, 0x51, 0x07, 0x2f, 0xf7, 0x97, 0x7e, 0x1f, 0xb6, 0xec, 0x5c, 0x4a, 0x75, 0xac, 0xd4, 0xdb, 0xb6, 0xf6, 0x83, + 0x68, 0x0b, 0x8e, 0x10, 0xac, 0x9d, 0x21, 0x22, 0x98, 0x19, 0x44, 0xd8, 0xb5, 0x50, 0x77, 0x7b, 0x4a, 0x2d, 0x8b, + 0x7a, 0xdb, 0x53, 0x4a, 0xdd, 0x86, 0xe1, 0xbb, 0x09, 0x66, 0x8a, 0x1b, 0x7e, 0x9d, 0x79, 0xa1, 0xde, 0x78, 0x2c, + 0x9e, 0x76, 0xcf, 0xdf, 0x2f, 0x78, 0x35, 0xdb, 0x28, 0x13, 0xe6, 0x92, 0x2f, 0x66, 0xa1, 0xec, 0x6a, 0x69, 0xdc, + 0xf9, 0xe2, 0x2d, 0xd4, 0x7c, 0xf0, 0x0f, 0x87, 0x04, 0xe2, 0x8d, 0xe2, 0xab, 0x65, 0x23, 0xb7, 0xae, 0xc9, 0xe6, + 0xaa, 0x04, 0xd4, 0xef, 0xf3, 0x35, 0xee, 0xb7, 0x58, 0xff, 0xee, 0x69, 0x90, 0xb1, 0x9a, 0xe1, 0x8a, 0x29, 0x7c, + 0x0a, 0x00, 0x83, 0xc3, 0xa9, 0x20, 0x2d, 0xf0, 0x86, 0x97, 0xc3, 0xcb, 0xc9, 0x86, 0x4c, 0xba, 0x1b, 0x1f, 0xb9, + 0xb3, 0x40, 0xd5, 0xfb, 0x1d, 0xc5, 0x49, 0x83, 0x44, 0x63, 0xaf, 0xc1, 0xe7, 0x59, 0x46, 0xb9, 0x68, 0xe2, 0x3e, + 0x24, 0x5f, 0xe9, 0x01, 0xcc, 0x55, 0x28, 0x01, 0xa2, 0xdf, 0x58, 0x16, 0x1b, 0xd1, 0xb6, 0xd8, 0xc0, 0x52, 0xaa, + 0xe6, 0x7a, 0x35, 0x7d, 0xf1, 0x4a, 0x34, 0xef, 0xa3, 0x19, 0xa7, 0x34, 0x1a, 0x70, 0x9c, 0x46, 0xe1, 0xf6, 0xfd, + 0x9d, 0x28, 0x17, 0x19, 0x58, 0xb2, 0x55, 0x38, 0xc5, 0x65, 0xa3, 0xce, 0x88, 0xe7, 0x79, 0xac, 0x00, 0x3a, 0x1e, + 0x12, 0x00, 0xd5, 0x05, 0x01, 0x15, 0xd1, 0x52, 0x7a, 0x2b, 0xb4, 0x58, 0xa8, 0x37, 0x1c, 0xa5, 0xf0, 0x47, 0xfa, + 0xf3, 0x20, 0x9f, 0x02, 0x10, 0xbb, 0x3e, 0x8e, 0x5e, 0x17, 0x25, 0x7d, 0xaa, 0x98, 0xe5, 0x72, 0x30, 0x81, 0x5d, + 0x9d, 0xc8, 0x50, 0x2b, 0xc8, 0x5b, 0x75, 0xe5, 0xad, 0x4c, 0xde, 0xc6, 0x38, 0x25, 0x3f, 0x70, 0xd3, 0xb1, 0x46, + 0x0c, 0xbc, 0xf2, 0xb4, 0x4e, 0x13, 0xa4, 0xc9, 0x1b, 0x60, 0x18, 0xe2, 0x77, 0x99, 0xf7, 0xdc, 0x73, 0xa4, 0x2a, + 0x48, 0x66, 0xdb, 0xcc, 0x53, 0x17, 0x51, 0x7d, 0xe5, 0xd4, 0xd2, 0x99, 0xd3, 0x8f, 0x00, 0xde, 0x63, 0x6a, 0xd2, + 0x90, 0x8f, 0x70, 0x5b, 0x8a, 0xaf, 0xb7, 0xea, 0x1a, 0x2f, 0x8d, 0xce, 0xdd, 0xcb, 0x97, 0xee, 0x34, 0xe8, 0xa7, + 0x20, 0x28, 0xe7, 0xf3, 0x52, 0xc0, 0x9e, 0x32, 0x9b, 0xeb, 0xd5, 0xaa, 0x15, 0x5a, 0x87, 0xc3, 0x58, 0x3b, 0x0a, + 0x69, 0x75, 0x16, 0xb0, 0xd5, 0x48, 0xa7, 0x04, 0x08, 0xc1, 0x71, 0x1a, 0x76, 0x82, 0x71, 0x97, 0x4e, 0x23, 0xb2, + 0x5e, 0x29, 0x49, 0x17, 0x66, 0x90, 0xfc, 0x93, 0xbc, 0x9e, 0x01, 0x2d, 0x01, 0x1c, 0x8a, 0x58, 0xc2, 0xc3, 0x49, + 0x72, 0x05, 0xd0, 0xe9, 0x70, 0x50, 0x69, 0x68, 0xce, 0x6a, 0x96, 0xcc, 0x27, 0xb1, 0x54, 0x55, 0x1e, 0x0e, 0x9e, + 0x72, 0x33, 0xe8, 0xf7, 0xb3, 0x69, 0xa9, 0x5c, 0x00, 0x82, 0x58, 0x17, 0x06, 0x88, 0x47, 0x5a, 0x78, 0xb2, 0xe8, + 0x53, 0x12, 0xbf, 0x9c, 0x25, 0x73, 0x93, 0x0d, 0xef, 0xc0, 0x08, 0x36, 0xe3, 0xba, 0xa4, 0x4c, 0x7b, 0x54, 0x7e, + 0xcf, 0xe8, 0xa9, 0xed, 0x6b, 0xad, 0xb6, 0x88, 0x75, 0x1d, 0x5c, 0x95, 0xa8, 0xa7, 0xf8, 0xa0, 0x24, 0xc1, 0xfb, + 0x95, 0x73, 0x33, 0x52, 0xbe, 0x16, 0xb9, 0x1f, 0xb4, 0x33, 0xb5, 0x72, 0xe0, 0x08, 0xe4, 0x58, 0x45, 0x25, 0xaf, + 0x77, 0x1d, 0x82, 0x47, 0x77, 0xa5, 0x02, 0xe5, 0xe0, 0x67, 0x20, 0x46, 0xd7, 0x57, 0x9d, 0x35, 0xd4, 0x4c, 0xa3, + 0xca, 0x23, 0xe8, 0xd4, 0x01, 0x3c, 0x29, 0x78, 0xa9, 0xd5, 0x8f, 0x87, 0x83, 0x67, 0x7e, 0xf0, 0xf7, 0x99, 0xbe, + 0x85, 0x98, 0x28, 0xa7, 0x1a, 0x21, 0x71, 0xa5, 0x24, 0x11, 0x1f, 0x2f, 0x5a, 0x56, 0x8c, 0xca, 0xf0, 0x9e, 0x57, + 0xaa, 0x7c, 0x75, 0xaa, 0xf2, 0x62, 0xa4, 0x6d, 0x09, 0xbc, 0x26, 0xff, 0x10, 0xb9, 0xe6, 0xad, 0xaf, 0xbb, 0xca, + 0xd0, 0x97, 0xb2, 0x02, 0x1d, 0xc1, 0x56, 0x96, 0x92, 0x03, 0x3e, 0xa9, 0xee, 0xaa, 0x55, 0xeb, 0x73, 0xca, 0x36, + 0xc2, 0x4d, 0x7e, 0x1d, 0x3b, 0x38, 0x52, 0x7e, 0x83, 0xe7, 0x02, 0xd8, 0x6b, 0xc0, 0xde, 0x9c, 0xb3, 0xa2, 0x79, + 0x70, 0x48, 0xdb, 0x02, 0x8d, 0xcc, 0xdc, 0xce, 0xd5, 0x7d, 0x5b, 0x1e, 0xa5, 0x31, 0x44, 0xa6, 0x3d, 0x30, 0x1d, + 0x6c, 0x46, 0xf9, 0xef, 0x29, 0xbf, 0x55, 0x38, 0x06, 0xbe, 0x9d, 0x7a, 0x07, 0x50, 0xf5, 0xb4, 0x41, 0xc6, 0x9a, + 0x61, 0x68, 0x65, 0x97, 0x4b, 0xa1, 0x25, 0x68, 0xa9, 0x9b, 0x20, 0x38, 0x3f, 0x22, 0xca, 0x11, 0x80, 0x2e, 0x52, + 0xc0, 0x04, 0x3f, 0xa5, 0xed, 0xee, 0xf7, 0xd7, 0xa9, 0x47, 0xee, 0x5d, 0xa1, 0xb2, 0x59, 0x7e, 0x22, 0x18, 0xfb, + 0x89, 0xc6, 0x0c, 0x3a, 0xba, 0x22, 0x27, 0x3c, 0x6b, 0x75, 0x58, 0xd7, 0x4d, 0x19, 0x94, 0xc5, 0x31, 0xaf, 0xa6, + 0xb3, 0x3f, 0x1e, 0xed, 0xeb, 0x06, 0x59, 0xc8, 0xff, 0x60, 0x3d, 0x24, 0x83, 0xee, 0x41, 0x28, 0x44, 0x6f, 0x1e, + 0xcc, 0xf0, 0x3f, 0xb6, 0xe1, 0xd9, 0x77, 0xdc, 0xa8, 0x13, 0xc0, 0x1c, 0x71, 0xbd, 0xf4, 0x14, 0x6d, 0x3d, 0xdc, + 0x02, 0xd9, 0x1a, 0x2f, 0x6f, 0xed, 0x35, 0x90, 0x53, 0x1c, 0xff, 0x92, 0x67, 0x6a, 0x65, 0x83, 0x9f, 0x9e, 0xb2, + 0x1d, 0x78, 0x78, 0x11, 0x02, 0x8a, 0x61, 0xd9, 0xf8, 0xa5, 0xe5, 0x38, 0xa3, 0xff, 0xe6, 0x11, 0xc3, 0x60, 0x11, + 0xf9, 0xf1, 0x45, 0x29, 0xc4, 0x57, 0xe1, 0x7d, 0xaa, 0xbc, 0x25, 0x39, 0x65, 0x2e, 0xf5, 0x30, 0xba, 0x2e, 0x49, + 0xdf, 0x25, 0x1f, 0x5b, 0xc3, 0xf6, 0x87, 0x76, 0xbf, 0x19, 0x22, 0x08, 0xa1, 0x1c, 0x3f, 0x67, 0x74, 0x42, 0xe3, + 0xc3, 0x6a, 0x76, 0x7a, 0xfd, 0xde, 0x39, 0x5e, 0xb0, 0x35, 0x1a, 0xe0, 0xf1, 0xd0, 0xc5, 0x3c, 0x51, 0x43, 0xa7, + 0xeb, 0xda, 0x39, 0x78, 0x60, 0x90, 0xe5, 0xc9, 0x77, 0x0c, 0x4b, 0xec, 0x4f, 0x22, 0x9e, 0xb4, 0x55, 0x1b, 0x9b, + 0x23, 0xd5, 0x46, 0xcd, 0xc0, 0x0f, 0x5e, 0x41, 0x81, 0xd1, 0x05, 0xe9, 0x16, 0x8c, 0xc3, 0x11, 0x80, 0xac, 0x18, + 0xc7, 0x23, 0x83, 0x09, 0x0c, 0xe9, 0x86, 0xa2, 0x00, 0x3c, 0x3c, 0x8e, 0x07, 0x21, 0x03, 0x48, 0x17, 0x3c, 0x34, + 0x6c, 0x93, 0x90, 0xf2, 0xf3, 0x3c, 0xaf, 0xd5, 0x10, 0xfa, 0xce, 0x42, 0x75, 0xec, 0x47, 0xda, 0x2b, 0xd6, 0xb5, + 0x2a, 0x1d, 0xd9, 0xea, 0x00, 0x7d, 0x43, 0x06, 0xbe, 0x75, 0x6c, 0x01, 0x10, 0x2d, 0xf1, 0x7b, 0xea, 0xd5, 0xbe, + 0x8c, 0x59, 0xa1, 0x5e, 0xbf, 0x31, 0xed, 0x7a, 0x25, 0x2d, 0x0a, 0xa8, 0xb8, 0x6d, 0xd5, 0xf6, 0x48, 0xce, 0x7f, + 0x78, 0xd7, 0xd1, 0x8e, 0xcf, 0x4e, 0x8d, 0x2d, 0xa1, 0xcc, 0x2d, 0x9e, 0xc8, 0xea, 0x68, 0x4b, 0x75, 0xaa, 0x0f, + 0xb8, 0xd4, 0xa4, 0x3a, 0x33, 0x30, 0xbc, 0x46, 0x80, 0x72, 0x0b, 0x91, 0x34, 0x0e, 0x7b, 0xe7, 0x93, 0x41, 0xc1, + 0xdc, 0x22, 0x01, 0x09, 0x6c, 0x63, 0x6b, 0x17, 0xcd, 0xf5, 0xeb, 0xf7, 0xd4, 0xab, 0xda, 0x54, 0xf5, 0xe0, 0x8d, + 0x17, 0x38, 0x7b, 0xa7, 0xb5, 0x80, 0x00, 0x0a, 0x5b, 0xcb, 0x72, 0x70, 0xee, 0x76, 0x55, 0x4b, 0x45, 0x19, 0xf5, + 0xfb, 0xe7, 0xbf, 0xa7, 0xa8, 0x88, 0x3d, 0x55, 0x9c, 0xb2, 0x7e, 0xbb, 0x65, 0xde, 0x54, 0x96, 0xbc, 0x41, 0x15, + 0xad, 0xd5, 0x51, 0x53, 0xb9, 0x6e, 0xae, 0x5a, 0x32, 0x41, 0x8c, 0xee, 0xd3, 0xb5, 0xce, 0x9d, 0x7a, 0xef, 0x55, + 0x1c, 0x31, 0x10, 0xdc, 0x74, 0x8f, 0x0f, 0x0e, 0x42, 0xa3, 0xa2, 0x5c, 0x70, 0xa3, 0xb4, 0xaa, 0xa4, 0x14, 0xf2, + 0x56, 0x45, 0x73, 0xa6, 0x8f, 0x00, 0x88, 0x00, 0xab, 0x44, 0xfd, 0x6f, 0xbe, 0x34, 0xc6, 0x83, 0x07, 0xbe, 0x26, + 0xd7, 0xb1, 0xf5, 0xfe, 0x69, 0x8d, 0xb4, 0xda, 0x38, 0x26, 0xb5, 0xea, 0x65, 0xab, 0x78, 0xd9, 0xbd, 0x4e, 0xc5, + 0xe0, 0xf9, 0xff, 0xdc, 0x07, 0xa8, 0x11, 0x2d, 0x65, 0x70, 0xeb, 0x6a, 0x80, 0xc6, 0x87, 0x63, 0xe1, 0x1b, 0x3f, + 0x64, 0x9c, 0x0f, 0x66, 0xe8, 0xa8, 0x36, 0x07, 0x07, 0x04, 0x47, 0x75, 0x8f, 0xc6, 0x84, 0x59, 0x38, 0xf7, 0x20, + 0x50, 0x7d, 0xe2, 0x3e, 0xe3, 0xda, 0x0b, 0xda, 0x04, 0x3e, 0x59, 0xd7, 0x35, 0x45, 0x80, 0x8b, 0xd8, 0x98, 0x88, + 0x21, 0x2e, 0x9b, 0x44, 0xea, 0x9b, 0x31, 0x28, 0x00, 0x8a, 0x67, 0x15, 0xc9, 0xa5, 0x37, 0x69, 0x5e, 0x89, 0xb2, + 0xd6, 0xcd, 0xa8, 0x58, 0x31, 0x04, 0x80, 0x87, 0xa0, 0xb8, 0xaa, 0xcc, 0x84, 0x46, 0x6c, 0x20, 0x95, 0xa5, 0x60, + 0xd5, 0xb0, 0xf0, 0x9b, 0xf6, 0x9b, 0xe4, 0xa4, 0x77, 0x3e, 0x6e, 0x9d, 0x3b, 0xf6, 0xbd, 0xa3, 0x90, 0xd2, 0x1e, + 0x8a, 0x09, 0x82, 0xe0, 0xa7, 0x75, 0x38, 0x7f, 0xc6, 0x9f, 0x11, 0x98, 0x8a, 0x6c, 0xc6, 0x80, 0x83, 0x10, 0x91, + 0x19, 0xbf, 0xe7, 0xf0, 0x19, 0x2f, 0x27, 0xe1, 0x70, 0xe8, 0x83, 0x3e, 0x94, 0x67, 0xb3, 0x70, 0x28, 0xe6, 0xd2, + 0x7b, 0x1d, 0xac, 0x75, 0x21, 0xaf, 0x27, 0x21, 0xa2, 0x85, 0x86, 0x3e, 0x38, 0xaf, 0xbb, 0xe6, 0x08, 0x4b, 0x00, + 0x9a, 0x38, 0xfa, 0xb2, 0x7e, 0x3f, 0xf2, 0xb4, 0xa1, 0x45, 0x8a, 0x8b, 0x46, 0x99, 0xcd, 0x72, 0xd9, 0x09, 0x1b, + 0xd7, 0x6e, 0x81, 0x50, 0x3c, 0x4c, 0x5b, 0xa8, 0x5a, 0x4f, 0xf5, 0x7a, 0x6e, 0xda, 0x7d, 0xf7, 0xa0, 0x5a, 0xe5, + 0x48, 0x67, 0x6d, 0xba, 0x52, 0xab, 0x5b, 0x46, 0xd5, 0x3a, 0x4b, 0x23, 0xaa, 0xdc, 0x24, 0x77, 0x8d, 0x5a, 0xf0, + 0xc9, 0x86, 0x2e, 0x53, 0x76, 0xb6, 0x06, 0x27, 0x8e, 0x3c, 0x97, 0xdc, 0xf2, 0xdd, 0x79, 0x45, 0x77, 0xa7, 0xda, + 0xb7, 0x00, 0xf7, 0x66, 0xd8, 0x90, 0x39, 0xaf, 0xb1, 0xd3, 0x20, 0x4c, 0x02, 0x3f, 0x62, 0x1f, 0x33, 0x64, 0x83, + 0x01, 0x1d, 0x85, 0xf4, 0xbf, 0xb6, 0xcc, 0x91, 0x80, 0xc9, 0x5f, 0xcf, 0xfd, 0xe6, 0xa6, 0xc8, 0x61, 0x31, 0x7e, + 0xd8, 0x60, 0xa4, 0xb1, 0x5a, 0x83, 0x61, 0xb9, 0x44, 0xe4, 0x4f, 0xed, 0x8e, 0x69, 0xaa, 0xe3, 0xcd, 0x7a, 0xad, + 0xf9, 0xd5, 0xd3, 0xa7, 0xba, 0x3e, 0xff, 0xed, 0xfb, 0xcb, 0xb0, 0x66, 0xf6, 0x87, 0x20, 0x94, 0x76, 0xef, 0x16, + 0xe7, 0x8e, 0x44, 0xef, 0x58, 0x69, 0x66, 0x97, 0x76, 0xc9, 0x2e, 0x4d, 0x69, 0xd7, 0xe4, 0x7a, 0xf5, 0x8d, 0xf2, + 0xc6, 0xce, 0x2b, 0xa6, 0xfb, 0xf7, 0x42, 0xef, 0x28, 0xa7, 0x6a, 0x02, 0x11, 0x4d, 0xda, 0x91, 0xb8, 0xdd, 0x2b, + 0xc3, 0xa7, 0x93, 0xbc, 0x5d, 0xc2, 0x51, 0xd7, 0xb0, 0xdc, 0x7c, 0xfb, 0xd7, 0xbc, 0xea, 0xac, 0x70, 0xfb, 0xa5, + 0x31, 0x6b, 0x7f, 0x0a, 0xe2, 0xaa, 0xfe, 0xf4, 0x1e, 0xd5, 0x4c, 0xc9, 0xff, 0x55, 0x8f, 0x81, 0xab, 0x9f, 0x4c, + 0x3b, 0xba, 0xa7, 0x10, 0x36, 0x98, 0xfd, 0xfc, 0xf8, 0xa1, 0x45, 0xd7, 0xe8, 0x02, 0x45, 0x72, 0x00, 0x9d, 0xbb, + 0x64, 0x84, 0xf7, 0x3b, 0xc6, 0xb9, 0x7f, 0xf5, 0x9b, 0x9a, 0x1c, 0x21, 0xa2, 0x5d, 0x84, 0x03, 0x80, 0xb8, 0xd3, + 0x54, 0xd6, 0xa1, 0x06, 0xe8, 0x03, 0x02, 0xeb, 0xd0, 0xb7, 0x19, 0xc0, 0x41, 0x1f, 0x6d, 0x9e, 0x45, 0x20, 0xaf, + 0x7b, 0x77, 0xec, 0x2d, 0xdb, 0xf9, 0xfc, 0xd9, 0x2a, 0xf5, 0xee, 0xd0, 0x21, 0xf8, 0x7c, 0xec, 0x4f, 0x2f, 0x03, + 0x83, 0x0b, 0xcd, 0xde, 0x3e, 0x11, 0x6c, 0xc7, 0x76, 0x4f, 0x10, 0xa9, 0xa8, 0x3b, 0xff, 0xf0, 0xd2, 0x44, 0xcf, + 0x3b, 0x2f, 0x2c, 0xf9, 0x02, 0xc0, 0x03, 0x59, 0x0c, 0x28, 0x3e, 0x0b, 0xef, 0x57, 0x96, 0x80, 0x9a, 0xfc, 0x96, + 0xaf, 0xbd, 0x77, 0x94, 0x7a, 0x03, 0x7f, 0x0e, 0x28, 0x7d, 0x92, 0x73, 0x6f, 0x39, 0xbc, 0xf5, 0x2f, 0x9e, 0x82, + 0xf3, 0xc4, 0x6a, 0x78, 0x03, 0x7f, 0x15, 0x7c, 0xe8, 0x2d, 0x07, 0x98, 0x58, 0xf2, 0xa1, 0xb7, 0x1a, 0x40, 0xaa, + 0xc2, 0x85, 0xc4, 0xd8, 0x87, 0xcf, 0x41, 0xce, 0xf0, 0x8f, 0xdf, 0x35, 0x06, 0xeb, 0xe7, 0xa0, 0xd0, 0x68, 0xac, + 0xa5, 0x0a, 0x59, 0x8a, 0xc5, 0x99, 0x00, 0x9b, 0x70, 0xdc, 0xed, 0x8b, 0x55, 0x6d, 0xd6, 0x82, 0xfe, 0x7c, 0xc0, + 0xf7, 0x68, 0xac, 0xae, 0xca, 0xb9, 0x28, 0x3f, 0x22, 0x7d, 0xaa, 0xe3, 0x63, 0x54, 0x6c, 0xea, 0xee, 0x74, 0xaa, + 0x55, 0x47, 0xda, 0xef, 0xca, 0x35, 0xd8, 0xf1, 0x3a, 0x39, 0xb2, 0x14, 0x9e, 0x75, 0xd8, 0x79, 0xe9, 0x94, 0xe8, + 0x30, 0x8c, 0x77, 0x5b, 0xf5, 0x8c, 0xa1, 0x3c, 0x37, 0x18, 0xd3, 0x05, 0x8f, 0xf8, 0xb3, 0x41, 0x2e, 0x43, 0x63, + 0x3e, 0x20, 0x1b, 0x86, 0xf2, 0xa1, 0x45, 0x86, 0x84, 0x88, 0xf7, 0x50, 0x09, 0xd8, 0xb6, 0xa0, 0x4c, 0x0a, 0x38, + 0x8b, 0x06, 0xbf, 0xd7, 0x5e, 0x0e, 0xbc, 0x07, 0x91, 0xdf, 0x48, 0x97, 0x72, 0x89, 0x8d, 0x4e, 0x1c, 0xcb, 0x42, + 0x3b, 0x8f, 0xeb, 0xaf, 0x63, 0x50, 0xbf, 0x57, 0xfa, 0x0d, 0xca, 0xd9, 0x1f, 0x25, 0xeb, 0xb4, 0xf1, 0xc4, 0xf8, + 0x97, 0xab, 0xfc, 0x53, 0xb4, 0xd4, 0xc3, 0xff, 0x67, 0x4c, 0xa1, 0xf4, 0x2f, 0xd3, 0x32, 0xda, 0xac, 0x16, 0xa2, + 0x14, 0x79, 0x24, 0x4e, 0xbe, 0x16, 0xd9, 0xb9, 0x7c, 0xe7, 0x53, 0xe8, 0x17, 0x80, 0x96, 0x7d, 0x82, 0x8c, 0xfe, + 0x8d, 0x09, 0x3e, 0xfc, 0x4d, 0x3b, 0xd7, 0xe6, 0x7c, 0x3c, 0xc9, 0xaf, 0xac, 0xbd, 0xdb, 0xf1, 0x22, 0x31, 0x8a, + 0xb1, 0xdc, 0x57, 0xdd, 0xac, 0x9c, 0xa8, 0xe4, 0xc0, 0x48, 0xd7, 0x64, 0x2f, 0x57, 0xb2, 0x6e, 0xa7, 0x5b, 0x09, + 0x44, 0x54, 0x81, 0xf7, 0x18, 0x57, 0xb1, 0x8f, 0x60, 0xba, 0xee, 0xb8, 0x8c, 0x76, 0xbc, 0x67, 0xbc, 0x3a, 0x51, + 0x56, 0x70, 0xbb, 0x11, 0xed, 0x09, 0x1d, 0xfd, 0x34, 0xa9, 0x2d, 0x0b, 0x07, 0x20, 0x77, 0x09, 0x63, 0xd9, 0x10, + 0xac, 0x18, 0x94, 0xbe, 0x5e, 0x53, 0xb2, 0x2c, 0xc0, 0xa2, 0xb3, 0xcb, 0x08, 0xc4, 0xb0, 0x6e, 0x9a, 0x13, 0x3a, + 0x5e, 0xba, 0x38, 0xef, 0xb5, 0x8a, 0x14, 0x3c, 0xa3, 0x45, 0xc7, 0xdc, 0x74, 0xa4, 0x1b, 0xa3, 0xbd, 0x7d, 0x61, + 0x10, 0x52, 0x3c, 0x7f, 0x60, 0xab, 0x75, 0x71, 0x91, 0x78, 0x85, 0x4c, 0xb4, 0x20, 0x96, 0x22, 0x30, 0xe3, 0x85, + 0xa6, 0x11, 0x26, 0x28, 0x53, 0x82, 0x45, 0x6b, 0x74, 0x68, 0x7f, 0x58, 0xc2, 0xee, 0x31, 0x46, 0x80, 0x40, 0x95, + 0xe9, 0x45, 0xd8, 0x9a, 0x30, 0x9b, 0xba, 0xd8, 0x00, 0x6d, 0x15, 0x43, 0x83, 0xb0, 0x36, 0xc4, 0x7c, 0x4c, 0xf3, + 0xe5, 0x3f, 0xb1, 0x18, 0xdb, 0x13, 0x88, 0xed, 0xdd, 0xae, 0x49, 0x98, 0xee, 0xb5, 0xb8, 0xb1, 0x5e, 0x6e, 0x4f, + 0x39, 0xa6, 0x76, 0xac, 0x8d, 0xda, 0xb1, 0x16, 0x7a, 0xc7, 0x5a, 0xeb, 0x1d, 0x6b, 0xd9, 0xf0, 0x47, 0x99, 0x17, + 0xb3, 0x04, 0xf4, 0xbb, 0x2b, 0xae, 0x1a, 0x04, 0xcd, 0xd8, 0xb0, 0x5b, 0xf8, 0x2d, 0xb1, 0x76, 0x4b, 0xff, 0x62, + 0xc1, 0x6e, 0x4c, 0x1f, 0xe8, 0xd6, 0x01, 0x96, 0x11, 0x35, 0xf9, 0x0e, 0x79, 0x37, 0x9d, 0x15, 0x85, 0xdb, 0x13, + 0xbb, 0xf1, 0xd9, 0x5b, 0xf3, 0xe6, 0xdd, 0x93, 0x08, 0x72, 0xef, 0xb8, 0x77, 0x37, 0x7c, 0xeb, 0x5f, 0xe8, 0x16, + 0xc8, 0xc9, 0x2c, 0x67, 0x20, 0x75, 0xc4, 0x27, 0x88, 0x56, 0xf6, 0x94, 0xef, 0x84, 0xdc, 0xd9, 0xd6, 0x4f, 0xee, + 0xdc, 0x6d, 0x6d, 0xf9, 0xe4, 0x8e, 0x55, 0x23, 0x8a, 0x15, 0xa7, 0x29, 0x12, 0x66, 0xd1, 0x06, 0x78, 0xea, 0xe5, + 0xfb, 0x1d, 0x3b, 0xe6, 0x70, 0xf7, 0xa4, 0xa3, 0xe3, 0xe5, 0x1c, 0xb0, 0xbb, 0xff, 0x68, 0x13, 0x36, 0x56, 0xba, + 0x56, 0xa1, 0xc3, 0xdd, 0x93, 0x4c, 0xe3, 0x39, 0x1c, 0xc9, 0xa7, 0x63, 0x8d, 0x0d, 0x82, 0xba, 0x3e, 0x67, 0x50, + 0x3b, 0x76, 0x5f, 0x13, 0x76, 0xd9, 0x31, 0xaf, 0x75, 0xcd, 0xdb, 0x2b, 0x4f, 0xc5, 0x86, 0x80, 0x0e, 0x5f, 0xab, + 0x1b, 0xe4, 0x5f, 0x02, 0xa7, 0x08, 0x00, 0x39, 0x1c, 0x2f, 0x79, 0xec, 0xfb, 0x34, 0x4b, 0xeb, 0x1d, 0x6a, 0x2d, + 0x2a, 0xcb, 0x32, 0xac, 0xbd, 0x1f, 0xb4, 0x62, 0x58, 0x6a, 0xfa, 0xa7, 0xe3, 0xc0, 0xed, 0x6c, 0xb7, 0x32, 0x76, + 0x19, 0x4f, 0x8a, 0x8b, 0xdf, 0x4e, 0x0b, 0xe5, 0xda, 0xcd, 0xdb, 0xf8, 0x4d, 0xab, 0x25, 0x4b, 0x6b, 0x3d, 0xe4, + 0xa5, 0x65, 0x11, 0x81, 0x00, 0x86, 0x23, 0x65, 0x17, 0x4b, 0xb8, 0x47, 0x58, 0xdd, 0x83, 0x50, 0x32, 0x2f, 0x5c, + 0x3c, 0x65, 0x31, 0x24, 0x02, 0x6c, 0x77, 0xa8, 0xd8, 0x16, 0x2e, 0x9e, 0xb2, 0x0d, 0x2f, 0xfa, 0xfd, 0x4c, 0x75, + 0x0a, 0x59, 0x77, 0x16, 0x7c, 0xa3, 0x9a, 0x63, 0x0d, 0x35, 0x5b, 0x9b, 0x64, 0x6b, 0x9c, 0xdb, 0x8a, 0x8f, 0x65, + 0x5b, 0xf1, 0xb1, 0xb2, 0xd6, 0xa5, 0x7b, 0xbd, 0x47, 0x75, 0x01, 0x6c, 0xfd, 0xb7, 0xc7, 0x2b, 0xd7, 0xf3, 0x19, + 0x01, 0x7c, 0xdd, 0xf0, 0xf1, 0xe4, 0x06, 0xbd, 0x4a, 0x6e, 0xfc, 0xdb, 0x81, 0x1a, 0x7f, 0xa7, 0x73, 0x6f, 0x00, + 0xba, 0x92, 0xf2, 0x0a, 0xc8, 0x3b, 0xc8, 0x31, 0xb7, 0xec, 0xca, 0xbb, 0x93, 0xef, 0xb0, 0xb7, 0xbc, 0x9e, 0xdd, + 0xcc, 0xd9, 0x0e, 0x9c, 0x0a, 0x92, 0x81, 0xbd, 0xac, 0xd8, 0x2e, 0x88, 0xed, 0x84, 0xdf, 0x09, 0x98, 0xf2, 0x39, + 0x04, 0x71, 0x05, 0xb7, 0x10, 0x87, 0x27, 0xff, 0x1c, 0xdc, 0xb5, 0x36, 0xeb, 0x3b, 0x66, 0x75, 0x4e, 0xb0, 0x66, + 0x56, 0x0f, 0x06, 0x8b, 0x66, 0xb2, 0xea, 0xf7, 0xbd, 0x9d, 0x76, 0x7c, 0x5a, 0x4a, 0x9d, 0xd8, 0x69, 0xad, 0xd6, + 0x0d, 0x7b, 0x2b, 0xb5, 0x2e, 0xc6, 0xd0, 0x03, 0xc4, 0x4f, 0xb7, 0x03, 0x7e, 0xd7, 0xb1, 0xb6, 0xbc, 0xb7, 0xec, + 0x86, 0xed, 0xe0, 0x12, 0xd4, 0xb4, 0x97, 0xfd, 0x49, 0xe5, 0x82, 0x76, 0xec, 0x92, 0x78, 0x38, 0x63, 0x56, 0x29, + 0x33, 0xeb, 0xa4, 0xba, 0x12, 0x9d, 0x31, 0x9d, 0xb5, 0x9e, 0xcf, 0xd5, 0x7c, 0x52, 0x68, 0x50, 0xbf, 0x73, 0xe2, + 0x23, 0x2a, 0x3a, 0x4f, 0x60, 0x6b, 0x59, 0x41, 0xac, 0xf6, 0x39, 0x58, 0x6b, 0xb5, 0x4b, 0xbf, 0x97, 0x0f, 0xb8, + 0x4d, 0x39, 0xac, 0x03, 0x83, 0x9a, 0x13, 0x2b, 0xea, 0x21, 0xdb, 0x31, 0x6e, 0x7e, 0x7a, 0xf9, 0x83, 0x13, 0x96, + 0xac, 0x58, 0xed, 0x4f, 0x7f, 0x7b, 0xe2, 0xe9, 0xef, 0xd4, 0xfe, 0x85, 0xf0, 0x83, 0xf1, 0xbf, 0x6b, 0xf7, 0xb5, + 0x16, 0xa3, 0xb2, 0x55, 0x8e, 0xd0, 0xb8, 0x5b, 0x49, 0x93, 0xe5, 0x27, 0xe1, 0x09, 0x6b, 0xc1, 0xb3, 0x5c, 0x2f, + 0xd1, 0xac, 0x80, 0x15, 0xd6, 0x32, 0x09, 0x57, 0x18, 0xab, 0xa5, 0xad, 0xbe, 0x45, 0xd3, 0x1c, 0x1f, 0xce, 0xb5, + 0x41, 0x99, 0x72, 0x76, 0x46, 0xac, 0x86, 0xcb, 0xb0, 0x34, 0xa1, 0x08, 0xd9, 0xbd, 0x1d, 0xdc, 0xd8, 0x29, 0x4b, + 0x29, 0xc3, 0x39, 0x06, 0x13, 0x1e, 0x89, 0x51, 0x95, 0xef, 0xef, 0x4b, 0x8a, 0x9c, 0xb6, 0xe5, 0xa0, 0x0a, 0x61, + 0x1f, 0x49, 0x94, 0xc0, 0xad, 0x48, 0x0b, 0x45, 0xca, 0xe2, 0x6f, 0x07, 0xe8, 0x02, 0x2f, 0xa0, 0xae, 0x46, 0xdd, + 0xfe, 0x70, 0xc4, 0xc3, 0x07, 0xa6, 0x3e, 0x30, 0x62, 0x49, 0xa0, 0xb6, 0xe7, 0x59, 0xba, 0x04, 0x15, 0x7e, 0x0f, + 0x57, 0x13, 0xb1, 0x9f, 0x5b, 0x52, 0x54, 0x64, 0x23, 0xbd, 0xa1, 0x35, 0x78, 0x84, 0xd6, 0x94, 0x17, 0x4e, 0xaa, + 0x4d, 0x3a, 0xef, 0x08, 0x39, 0x56, 0xdf, 0x5a, 0xc2, 0x68, 0x57, 0xf4, 0xe2, 0xde, 0xd1, 0x7b, 0x9e, 0xae, 0x7a, + 0xee, 0x4f, 0x5c, 0x31, 0x4f, 0x6e, 0x23, 0x50, 0xb7, 0x82, 0xea, 0xf6, 0x5e, 0x25, 0x58, 0xb0, 0xa4, 0xdd, 0xc7, + 0x6f, 0x67, 0xed, 0x40, 0x54, 0xc6, 0x2a, 0x7d, 0x4b, 0x12, 0xf6, 0xc4, 0xa0, 0x53, 0xa8, 0xca, 0xed, 0xee, 0x68, + 0x0b, 0x5c, 0xc7, 0x2c, 0x45, 0xcf, 0x6d, 0x91, 0xbb, 0xe5, 0xdf, 0x3d, 0x57, 0xe4, 0xec, 0x97, 0x80, 0xe0, 0xd4, + 0x7c, 0x43, 0x7c, 0x39, 0xc2, 0xa3, 0xea, 0x16, 0x38, 0x4e, 0xdf, 0x01, 0xfc, 0xc3, 0xe1, 0x12, 0x34, 0x01, 0xb1, + 0x60, 0xbd, 0x34, 0xee, 0xb1, 0x5e, 0x5c, 0x6c, 0x96, 0x49, 0xbe, 0x01, 0x67, 0x06, 0x4a, 0xb5, 0xf4, 0x03, 0xc7, + 0x6a, 0x01, 0x15, 0x0e, 0x66, 0x27, 0xf5, 0xc2, 0x32, 0xea, 0x31, 0x7d, 0x7e, 0x06, 0x7b, 0x47, 0x48, 0x00, 0xdc, + 0x2f, 0xfb, 0x80, 0x04, 0x3c, 0x74, 0x66, 0x07, 0x84, 0x13, 0x66, 0x51, 0x15, 0x48, 0x24, 0x47, 0xfa, 0xd9, 0x63, + 0x26, 0x92, 0x3f, 0x98, 0xf5, 0x9c, 0x53, 0xa2, 0xc7, 0x7a, 0xea, 0x08, 0xe9, 0xb1, 0x9e, 0x75, 0x44, 0xf4, 0x58, + 0xcf, 0x3a, 0x3e, 0x7a, 0xac, 0x67, 0x8e, 0x9d, 0x1e, 0x04, 0x26, 0x40, 0xe4, 0x01, 0xeb, 0xd1, 0x64, 0xea, 0x29, + 0xee, 0x01, 0xa2, 0x41, 0x60, 0x3d, 0x29, 0x9c, 0xf7, 0x00, 0x79, 0x8c, 0xc4, 0xea, 0xa0, 0xf7, 0x1f, 0xe3, 0xc7, + 0x3d, 0x23, 0x23, 0x8f, 0x5b, 0x87, 0xd5, 0xff, 0xfa, 0x4f, 0x08, 0x80, 0xc3, 0xb3, 0xa9, 0x77, 0x39, 0x86, 0xac, + 0xb2, 0x8c, 0x40, 0xf2, 0x13, 0x83, 0x2f, 0x5f, 0x00, 0x54, 0x7d, 0xa6, 0x6b, 0x35, 0x39, 0x6a, 0x8f, 0x39, 0x74, + 0xc5, 0x00, 0xb0, 0x0d, 0x4b, 0x54, 0xd5, 0xc2, 0x26, 0x2c, 0x6e, 0x3f, 0xc3, 0x68, 0x2e, 0x9b, 0x5e, 0xd0, 0x40, + 0x3d, 0x42, 0xf0, 0x4b, 0xeb, 0xa1, 0xb5, 0x96, 0x29, 0x87, 0xae, 0x8d, 0xa2, 0xca, 0x86, 0xba, 0x84, 0xd5, 0x5a, + 0x44, 0x35, 0x51, 0xa4, 0x5c, 0x32, 0x8a, 0x62, 0xa9, 0x82, 0x7d, 0x26, 0x96, 0x10, 0x35, 0x4f, 0x5b, 0x6d, 0x15, + 0xec, 0x97, 0x80, 0xb0, 0x16, 0xd6, 0x42, 0x3a, 0x83, 0xda, 0x3b, 0xfd, 0x48, 0xf9, 0xcb, 0x0b, 0xb9, 0x9d, 0x5b, + 0x28, 0xc2, 0xed, 0x39, 0x28, 0x6f, 0xea, 0xaa, 0x54, 0x44, 0xa3, 0x25, 0x50, 0xca, 0x9c, 0x20, 0xb2, 0x00, 0x01, + 0x1c, 0x37, 0x10, 0xf8, 0xbc, 0xc6, 0x27, 0xd0, 0x28, 0x04, 0xf2, 0x03, 0xab, 0x70, 0xed, 0x21, 0x2d, 0xb5, 0x46, + 0x44, 0x89, 0xf8, 0xd1, 0xd5, 0x73, 0x6c, 0x5f, 0x3d, 0x8d, 0xb5, 0xa5, 0x34, 0x41, 0xfc, 0xc4, 0x62, 0x0b, 0x31, + 0x41, 0x54, 0x87, 0xe8, 0x08, 0x96, 0x13, 0x42, 0x14, 0xfe, 0x14, 0xfa, 0xa9, 0x81, 0xbf, 0x64, 0x8b, 0x22, 0xaf, + 0x09, 0x16, 0xb3, 0x62, 0x80, 0x56, 0x45, 0xe0, 0x99, 0xce, 0x96, 0xca, 0x9c, 0xe6, 0xd1, 0x91, 0x1d, 0x9c, 0x77, + 0x1d, 0xec, 0xa5, 0x2f, 0x63, 0x27, 0xcb, 0xa6, 0x51, 0x1b, 0x1b, 0x22, 0xe1, 0x15, 0xf9, 0xcb, 0x2c, 0x35, 0xce, + 0x91, 0xb9, 0x5c, 0xdf, 0x75, 0xb1, 0x5c, 0xd2, 0x36, 0x61, 0x15, 0x22, 0xd4, 0x6d, 0x43, 0xe5, 0x52, 0x98, 0x8d, + 0x4d, 0xd3, 0x00, 0x5f, 0x28, 0x2a, 0x95, 0xaa, 0xd4, 0x56, 0x2a, 0x39, 0xe1, 0x5d, 0xdf, 0xd4, 0x22, 0x75, 0x45, + 0xb0, 0x8d, 0x19, 0xea, 0xa1, 0xdc, 0xa8, 0xb1, 0x6f, 0x3b, 0x56, 0xe9, 0x1d, 0x26, 0xc8, 0x19, 0x79, 0x91, 0x83, + 0x8b, 0x92, 0x82, 0xcc, 0xd5, 0x10, 0xe6, 0x0f, 0x1a, 0x3e, 0x2d, 0x2c, 0xf7, 0x50, 0x02, 0x66, 0x47, 0x0d, 0x0f, + 0x23, 0x04, 0x22, 0x2e, 0x95, 0x7d, 0xc5, 0xc4, 0xef, 0x29, 0x98, 0x25, 0x13, 0xba, 0x17, 0xb1, 0x28, 0x42, 0x1b, + 0x9f, 0x24, 0xc9, 0xd4, 0xd3, 0x14, 0xdc, 0xc8, 0x65, 0x98, 0xa3, 0x11, 0x5a, 0xf2, 0x91, 0x03, 0xe9, 0x6b, 0x39, + 0x95, 0xe0, 0x23, 0xea, 0x14, 0x70, 0x3c, 0x3f, 0x2f, 0xac, 0x9f, 0x2c, 0x97, 0x98, 0xcb, 0xda, 0xfc, 0x97, 0x1d, + 0x1d, 0x83, 0x5d, 0x9e, 0x26, 0x8e, 0xab, 0xff, 0xa8, 0x4a, 0x8a, 0xfb, 0x5f, 0xd2, 0x1c, 0x50, 0x04, 0x33, 0x7b, + 0x8a, 0xf1, 0xb1, 0xcf, 0x32, 0x05, 0xfc, 0xed, 0x7a, 0x6b, 0xc9, 0xc4, 0x2e, 0x69, 0x37, 0x57, 0xc6, 0x2f, 0xb5, + 0x61, 0xc7, 0xc1, 0xb9, 0x01, 0x28, 0xce, 0x1a, 0x1d, 0x96, 0xd7, 0xba, 0x6d, 0x55, 0xa8, 0x40, 0xad, 0xff, 0xbd, + 0x5b, 0x98, 0xf2, 0x36, 0x2f, 0x95, 0xb7, 0x79, 0x68, 0x02, 0x04, 0x22, 0x33, 0xe4, 0x59, 0xd3, 0x31, 0x49, 0xdc, + 0x3b, 0x52, 0xd2, 0xbe, 0x23, 0xc5, 0x0f, 0xde, 0x91, 0x90, 0x6f, 0x09, 0x1d, 0xd9, 0x17, 0x9c, 0x9c, 0x40, 0x99, + 0xc1, 0x5e, 0x5e, 0x33, 0xd9, 0x3f, 0xa0, 0xbd, 0x70, 0x2e, 0xcb, 0x2b, 0xfe, 0x56, 0x78, 0x6b, 0x7f, 0xba, 0x3e, + 0xed, 0xaa, 0x7a, 0xfb, 0x8d, 0x99, 0x79, 0x38, 0x14, 0x87, 0x43, 0x65, 0x82, 0x76, 0x6f, 0xb8, 0x18, 0xe4, 0xec, + 0xce, 0x8d, 0x8f, 0x7f, 0xcb, 0x51, 0xc4, 0x56, 0xca, 0x23, 0xe9, 0x42, 0x25, 0x86, 0x97, 0x06, 0x1e, 0x66, 0xc7, + 0xc7, 0x93, 0xdd, 0xd5, 0xdd, 0x64, 0x30, 0xd8, 0xa9, 0xbe, 0xdd, 0xf2, 0x7a, 0xb6, 0x9b, 0xb3, 0x7b, 0x7e, 0x3b, + 0xdd, 0x06, 0xfb, 0x06, 0xb6, 0xdd, 0xdd, 0x95, 0x38, 0x1c, 0x76, 0xcf, 0xf8, 0x8d, 0xbf, 0xbf, 0x47, 0x40, 0x67, + 0x7e, 0x3e, 0x6e, 0x63, 0xfc, 0x5c, 0xb7, 0x5d, 0xb5, 0x76, 0x00, 0x4f, 0xff, 0xa3, 0x77, 0x3d, 0x5b, 0xcc, 0x7d, + 0xf6, 0x88, 0xdf, 0x83, 0x7f, 0x3e, 0x6e, 0x92, 0x48, 0x7d, 0xa2, 0x5d, 0x26, 0xaf, 0xc1, 0x81, 0x7c, 0xe7, 0xb3, + 0x57, 0xfc, 0x7e, 0xb6, 0x98, 0xf3, 0xe2, 0x70, 0x78, 0x3f, 0x0d, 0x91, 0xac, 0x29, 0xac, 0x88, 0x25, 0xc5, 0xf3, + 0x83, 0xf0, 0xf8, 0xbd, 0x88, 0x0c, 0x91, 0x96, 0x7b, 0x77, 0xc8, 0xae, 0x59, 0xe4, 0x07, 0xf0, 0x41, 0xb6, 0xf3, + 0x27, 0xb2, 0xa6, 0x74, 0xbf, 0x78, 0xe4, 0x1f, 0x0e, 0xf4, 0xd7, 0x2b, 0xff, 0x70, 0x78, 0xcf, 0xee, 0x11, 0x1c, + 0x9d, 0xef, 0xa0, 0x7f, 0xf4, 0xad, 0x03, 0xaa, 0x32, 0x7c, 0x3b, 0xdb, 0xcc, 0xfd, 0x67, 0x2b, 0xb6, 0x04, 0x2e, + 0x14, 0xe5, 0x85, 0x76, 0xcd, 0xee, 0xd1, 0xeb, 0x8c, 0x9c, 0x88, 0x66, 0xbb, 0xb9, 0xcf, 0x62, 0x7c, 0xae, 0xee, + 0x8b, 0xc9, 0x37, 0xef, 0x8b, 0x3b, 0xb6, 0xed, 0xbe, 0x2f, 0xca, 0x37, 0xdd, 0xf5, 0xb3, 0x65, 0x3b, 0x76, 0x0f, + 0x33, 0xec, 0x2d, 0xbf, 0x6e, 0x8e, 0x1d, 0x63, 0xbf, 0x79, 0x63, 0x04, 0x50, 0x66, 0x0b, 0x16, 0x0b, 0x0e, 0x4a, + 0xb5, 0x6a, 0x5b, 0x12, 0x79, 0xa5, 0x03, 0xd5, 0x66, 0x04, 0xf7, 0xd5, 0x42, 0xce, 0x3c, 0x33, 0xd0, 0xb7, 0x15, + 0xa2, 0x85, 0xc3, 0x06, 0xfc, 0x8d, 0xb6, 0x8e, 0x31, 0x4c, 0xb3, 0x9a, 0x69, 0x5b, 0xd4, 0xe5, 0xf7, 0xbd, 0x67, + 0xf2, 0x1b, 0x19, 0xd8, 0x42, 0x24, 0x85, 0xe3, 0xf8, 0xe2, 0xe9, 0x09, 0xff, 0x55, 0xcb, 0xa3, 0x56, 0xfb, 0x85, + 0x52, 0x9f, 0xbe, 0xa4, 0x23, 0x9a, 0xb8, 0x17, 0x6d, 0x19, 0xd6, 0x28, 0x6b, 0x6a, 0xe9, 0x30, 0x8c, 0x6b, 0xd8, + 0x97, 0x07, 0x0e, 0x7d, 0x07, 0x04, 0xda, 0x2a, 0x95, 0x02, 0x2d, 0x1c, 0xc3, 0x28, 0xcc, 0x42, 0xca, 0xc3, 0xc2, + 0x2c, 0xe5, 0x3d, 0x16, 0x68, 0x71, 0xab, 0xee, 0x31, 0xb5, 0xdd, 0x82, 0x08, 0xab, 0xb7, 0x8c, 0xf3, 0xcb, 0x46, + 0x15, 0x6e, 0x0b, 0x50, 0x14, 0x41, 0x19, 0xec, 0x49, 0x6e, 0xbb, 0x51, 0xd2, 0x6c, 0x14, 0xd6, 0x62, 0x59, 0x94, + 0xbb, 0x5e, 0xc3, 0x6e, 0xf0, 0x82, 0xaa, 0x9f, 0x10, 0xb6, 0x65, 0xcf, 0x3a, 0x94, 0x8b, 0xf4, 0xdf, 0xb2, 0xf4, + 0x7c, 0xbf, 0x35, 0xe7, 0x7f, 0xfa, 0x8a, 0x3e, 0x2a, 0xff, 0xfd, 0x4b, 0xfa, 0xc9, 0x60, 0x19, 0x39, 0xa5, 0x7e, + 0x8a, 0x46, 0xb7, 0x69, 0x4e, 0x18, 0x5b, 0xbe, 0x7e, 0xfa, 0x1d, 0x32, 0x05, 0xc9, 0xa1, 0x94, 0xaa, 0x9c, 0xec, + 0xa1, 0x2f, 0xbc, 0xee, 0xc3, 0x4c, 0x30, 0x00, 0xe1, 0x35, 0xda, 0x54, 0x13, 0x26, 0xf1, 0xe0, 0x0a, 0xfe, 0x6f, + 0x04, 0x31, 0x68, 0x9f, 0x28, 0xea, 0xd8, 0x36, 0xd2, 0x75, 0xdb, 0x39, 0x48, 0xee, 0xd4, 0x95, 0x3f, 0x2a, 0x27, + 0xff, 0x8e, 0x86, 0xc8, 0x2b, 0xae, 0x10, 0x2b, 0x0b, 0x2e, 0xb1, 0x18, 0x2a, 0x52, 0x80, 0x6b, 0x08, 0x22, 0x65, + 0x51, 0x52, 0xb8, 0xe5, 0xa0, 0x2a, 0x02, 0x30, 0xae, 0x56, 0x47, 0x9d, 0x08, 0x1f, 0xb7, 0xd6, 0x22, 0x04, 0x2b, + 0x1a, 0xb5, 0xb2, 0x56, 0xe0, 0x0b, 0xd2, 0x97, 0x0e, 0x05, 0x31, 0x3d, 0x0a, 0xa9, 0x2a, 0x1d, 0x0a, 0xa4, 0x39, + 0x54, 0x7c, 0x63, 0xb0, 0x51, 0x54, 0xa4, 0xe7, 0x2f, 0x4d, 0x4a, 0x2e, 0x8d, 0x19, 0x1f, 0x44, 0x19, 0x89, 0xbc, + 0x0e, 0x97, 0x62, 0x5a, 0x20, 0xdf, 0xe8, 0xf1, 0x83, 0xe0, 0x12, 0xde, 0x0d, 0xb9, 0x57, 0x80, 0x2d, 0x01, 0x3b, + 0xc0, 0xbd, 0x32, 0xa3, 0x5c, 0xa7, 0x75, 0xfd, 0xd6, 0x7a, 0x28, 0x86, 0xe1, 0x13, 0x4b, 0x60, 0x3b, 0x5a, 0x47, + 0x47, 0x7a, 0xf8, 0xf0, 0xbf, 0xae, 0x6a, 0x8e, 0x3a, 0x95, 0xcb, 0xd9, 0xf1, 0x84, 0xa5, 0x88, 0x19, 0x74, 0x7f, + 0xdd, 0xbe, 0x14, 0x40, 0xb7, 0xcb, 0x62, 0x9e, 0x8d, 0x76, 0xf2, 0x6f, 0xe9, 0xc6, 0x8a, 0xd2, 0x26, 0xde, 0x65, + 0xbd, 0xb1, 0x3f, 0x1c, 0xfd, 0xc7, 0x93, 0x77, 0x13, 0x42, 0xd5, 0xd9, 0xb0, 0xb5, 0x8e, 0x73, 0xf9, 0x5f, 0xff, + 0x39, 0x26, 0x2b, 0x08, 0x0a, 0xc2, 0xb2, 0x53, 0x4c, 0x54, 0x30, 0x8a, 0x14, 0x6b, 0x3e, 0x9e, 0xac, 0x51, 0x27, + 0xbc, 0xf6, 0x17, 0x5a, 0x27, 0x4c, 0x8c, 0xac, 0x54, 0xfe, 0x9a, 0x55, 0x6c, 0xa9, 0x32, 0x0b, 0xc8, 0x3c, 0xc8, + 0x27, 0x6b, 0xa3, 0xc1, 0x5c, 0xf1, 0x7a, 0xb6, 0x9e, 0x4b, 0xe5, 0x33, 0x98, 0x72, 0x16, 0x83, 0x93, 0xa5, 0xb0, + 0x3b, 0x12, 0x28, 0x5a, 0x33, 0x74, 0xed, 0x4f, 0xb1, 0x55, 0xaf, 0xd2, 0xaa, 0x06, 0x78, 0x40, 0x88, 0x81, 0xa1, + 0xf6, 0x6a, 0xe1, 0xa1, 0xb5, 0x00, 0xd6, 0xfe, 0xa8, 0xf4, 0x83, 0xf1, 0x64, 0xc1, 0x6f, 0x90, 0x7f, 0x39, 0x72, + 0xd4, 0xee, 0xfd, 0xbe, 0x77, 0x07, 0x52, 0x70, 0xe4, 0x5a, 0x28, 0x90, 0x08, 0xe8, 0x86, 0x6f, 0x7c, 0xe5, 0x83, + 0xf1, 0x16, 0xb5, 0xd5, 0xa0, 0xa0, 0x76, 0x74, 0xcb, 0x63, 0x47, 0xef, 0x7c, 0x77, 0x42, 0x5f, 0x7d, 0xa3, 0x85, + 0xe3, 0x6f, 0x9c, 0x91, 0x6b, 0xb6, 0xea, 0x90, 0x23, 0x9a, 0x49, 0x87, 0x10, 0xb1, 0x62, 0x6b, 0xf6, 0x96, 0x54, + 0xce, 0x9d, 0x43, 0x76, 0xfa, 0x08, 0x55, 0x7a, 0xad, 0x87, 0xb7, 0x13, 0xa5, 0xbb, 0x3d, 0xde, 0x4d, 0xbe, 0x67, + 0x13, 0x11, 0x83, 0x01, 0x6d, 0x10, 0xce, 0xc8, 0x3a, 0x44, 0x2a, 0x1d, 0x20, 0x04, 0x8e, 0x09, 0x68, 0xfa, 0xaf, + 0x6f, 0x49, 0x14, 0x70, 0xa4, 0x8d, 0x90, 0xb5, 0xec, 0x70, 0xc8, 0x41, 0xa3, 0xdc, 0xfc, 0xe9, 0x15, 0xea, 0x34, + 0x07, 0xe6, 0xe9, 0x12, 0xf6, 0x1c, 0x3c, 0xd2, 0x8b, 0xe3, 0x23, 0xfd, 0xbf, 0xa3, 0x89, 0x1a, 0xff, 0xfb, 0x9a, + 0x28, 0xa5, 0x45, 0x72, 0x54, 0x4b, 0xdf, 0xa5, 0x8e, 0x82, 0x8b, 0xbc, 0xa3, 0x16, 0xb2, 0x67, 0xd9, 0xb8, 0x51, + 0xcd, 0xfb, 0xff, 0xb5, 0x32, 0xff, 0x5f, 0xd3, 0xca, 0x30, 0x25, 0x3b, 0x96, 0x6a, 0xe6, 0x81, 0x56, 0x31, 0xcc, + 0x7e, 0x21, 0x09, 0x91, 0xe1, 0xd2, 0x80, 0x1f, 0x55, 0xb0, 0x8f, 0xd3, 0x6a, 0x9d, 0x85, 0x3b, 0x54, 0xa2, 0xde, + 0x8a, 0x65, 0x9a, 0x3f, 0xaf, 0xff, 0x25, 0xca, 0x02, 0xa6, 0xf6, 0xb2, 0x4c, 0xe3, 0x80, 0x2c, 0xfc, 0x59, 0x58, + 0xe2, 0xe4, 0xc6, 0x36, 0xfe, 0x22, 0xc7, 0xd3, 0x7e, 0xd5, 0x99, 0x79, 0x20, 0x81, 0x1a, 0xe8, 0x42, 0x72, 0x2e, + 0x2b, 0x8b, 0x7b, 0x84, 0x6e, 0xfe, 0xb1, 0x2c, 0x8b, 0xd2, 0xeb, 0x7d, 0x4a, 0xd2, 0xea, 0x6c, 0x25, 0xea, 0xa4, + 0x88, 0x15, 0x94, 0x4d, 0x0a, 0x30, 0xfa, 0xb0, 0xf2, 0x44, 0x1c, 0x9c, 0x21, 0x50, 0xc3, 0x59, 0x9d, 0x84, 0x00, + 0x34, 0xac, 0x10, 0xf6, 0xcf, 0xa0, 0x85, 0x67, 0x61, 0x1c, 0xae, 0x01, 0x26, 0x27, 0xad, 0xce, 0xd6, 0x65, 0x71, + 0x97, 0xc6, 0x22, 0x1e, 0xf5, 0x14, 0x25, 0xcb, 0xeb, 0xdc, 0x95, 0x73, 0xfd, 0xfd, 0x9f, 0x14, 0xc0, 0x6e, 0xc0, + 0x6c, 0x5b, 0x60, 0x07, 0x00, 0x09, 0x0a, 0x64, 0x0b, 0x75, 0x1a, 0x9d, 0xa9, 0xa5, 0x02, 0xef, 0xb9, 0x1e, 0xe0, + 0xaf, 0x73, 0xc0, 0x32, 0xae, 0x0b, 0x19, 0x30, 0x82, 0x00, 0x46, 0xe0, 0xa0, 0x04, 0x0c, 0x9d, 0x21, 0x6e, 0xab, + 0x72, 0xd6, 0x42, 0x73, 0xa5, 0xdb, 0x92, 0x9b, 0x46, 0x39, 0x5b, 0x89, 0x00, 0xfa, 0xea, 0xa6, 0xc4, 0xe9, 0x62, + 0xd1, 0x4a, 0xc2, 0xbe, 0x7d, 0xdf, 0x4e, 0x15, 0x79, 0x7c, 0x94, 0x86, 0xbc, 0x02, 0xcf, 0x33, 0x8e, 0x24, 0x51, + 0x22, 0x78, 0x9d, 0x37, 0x66, 0x1c, 0x7e, 0x6c, 0x53, 0x4e, 0xed, 0xcd, 0x7a, 0x01, 0x38, 0x4f, 0xd0, 0x96, 0x01, + 0xc6, 0x02, 0x06, 0xe7, 0x42, 0x2c, 0x79, 0x8a, 0xe0, 0x97, 0x4e, 0xa4, 0x30, 0xee, 0x72, 0x18, 0xe6, 0x41, 0xd1, + 0xbb, 0xa4, 0xfe, 0xe8, 0xf7, 0x51, 0x9b, 0x0c, 0x86, 0xa0, 0x12, 0x40, 0x65, 0xdd, 0x20, 0x31, 0xb0, 0x2a, 0xdd, + 0x48, 0x5c, 0x42, 0xbc, 0xcc, 0x57, 0x53, 0x11, 0x05, 0xef, 0xeb, 0x09, 0x21, 0x9c, 0x60, 0x7c, 0x88, 0x1b, 0x20, + 0x60, 0xb0, 0x8a, 0x0b, 0x0c, 0x92, 0xe7, 0x12, 0xdd, 0x1f, 0xcf, 0x77, 0x0c, 0x70, 0xe5, 0xbc, 0xa7, 0xda, 0xd5, + 0x03, 0x7b, 0xb9, 0x4a, 0x97, 0x8c, 0x10, 0x56, 0xfc, 0x5f, 0x44, 0xde, 0xb7, 0xc3, 0x04, 0xd4, 0x36, 0xf2, 0xc7, + 0x20, 0x31, 0x97, 0x89, 0x22, 0x88, 0x47, 0x59, 0xc1, 0x92, 0x34, 0xd8, 0x8c, 0x92, 0x14, 0x34, 0x9a, 0x18, 0x43, + 0xa6, 0x42, 0x3b, 0x24, 0x8d, 0x66, 0x63, 0xb2, 0x8f, 0x21, 0xaf, 0xe1, 0x62, 0xb1, 0xc0, 0xfb, 0x7e, 0x11, 0xaa, + 0x83, 0x6d, 0x69, 0x0e, 0x01, 0x27, 0x09, 0xf6, 0xd4, 0x15, 0x29, 0x09, 0xb3, 0xd1, 0xa7, 0x90, 0x73, 0x03, 0x3a, + 0x4e, 0x1a, 0x43, 0xf5, 0x81, 0x49, 0x78, 0x15, 0xa1, 0x93, 0xb2, 0x42, 0x58, 0xc0, 0x7d, 0x23, 0xa3, 0xd1, 0x4a, + 0x1a, 0x04, 0xde, 0x66, 0xd8, 0x0a, 0x6c, 0x42, 0xc3, 0x7f, 0xcc, 0x3c, 0x4c, 0xab, 0x59, 0x09, 0xe6, 0x7c, 0x03, + 0x95, 0x18, 0x4f, 0x16, 0x57, 0x7c, 0xe3, 0x62, 0x25, 0x26, 0xb3, 0xc5, 0x7c, 0xb2, 0x96, 0x54, 0x73, 0xb9, 0xb7, + 0x66, 0x19, 0x5b, 0xc0, 0xfe, 0x61, 0x60, 0x28, 0x1d, 0xd8, 0xd1, 0x54, 0xd3, 0x26, 0x01, 0x26, 0xd3, 0x39, 0xe7, + 0xc3, 0x4b, 0x44, 0x93, 0xd5, 0xa9, 0x3b, 0x99, 0xaa, 0x76, 0x70, 0x4d, 0xce, 0xe4, 0xf4, 0x48, 0x3d, 0xd5, 0xba, + 0x97, 0x7c, 0xb4, 0x1d, 0x56, 0xa3, 0xad, 0x1f, 0x80, 0x5b, 0xa7, 0xb0, 0xd3, 0x77, 0xc3, 0x6a, 0xb4, 0xf3, 0x35, + 0xec, 0x2e, 0x29, 0x04, 0xaa, 0xbf, 0xca, 0x9a, 0xcc, 0xc5, 0xeb, 0xe2, 0xde, 0x2b, 0xd8, 0x53, 0x7f, 0xa0, 0x7f, + 0x95, 0xec, 0xa9, 0x6f, 0x33, 0xb9, 0xfe, 0x95, 0x76, 0x8d, 0xc6, 0x4c, 0xc7, 0x6b, 0x57, 0x60, 0x85, 0x06, 0xc8, + 0x2f, 0xd8, 0xd1, 0xde, 0xe4, 0x20, 0x10, 0xa0, 0x7b, 0x09, 0x8e, 0xa2, 0x80, 0xa8, 0x69, 0x55, 0x79, 0x74, 0xba, + 0xf7, 0xf7, 0xf8, 0x46, 0x08, 0xd8, 0xe4, 0xa9, 0x75, 0x6f, 0x19, 0xfb, 0x87, 0x03, 0x84, 0xd0, 0xcb, 0xe9, 0x37, + 0xda, 0xb2, 0x7a, 0xb4, 0x63, 0xb9, 0x6f, 0x18, 0xf5, 0x14, 0x8c, 0x61, 0xe8, 0xc2, 0x2a, 0x46, 0xf2, 0x0c, 0xc8, + 0x1a, 0xbf, 0x41, 0x74, 0x01, 0x8b, 0x5e, 0xef, 0xd5, 0x11, 0x0d, 0x22, 0xa0, 0xd2, 0x6b, 0xd2, 0x58, 0xe4, 0x73, + 0x55, 0x88, 0xde, 0x7b, 0x6b, 0xe7, 0xcd, 0x8c, 0x64, 0x99, 0x34, 0x52, 0xed, 0x56, 0x16, 0xeb, 0xca, 0x9b, 0x9d, + 0x90, 0x2e, 0xe6, 0x18, 0x2a, 0x83, 0xc7, 0x01, 0x28, 0x3d, 0xff, 0x11, 0x7a, 0x25, 0x43, 0xa6, 0x59, 0xa2, 0x99, + 0xdd, 0x35, 0xfe, 0x64, 0x95, 0x7a, 0x31, 0x22, 0x66, 0x03, 0x5b, 0x88, 0xdb, 0xa2, 0xd2, 0x6d, 0x51, 0x28, 0x5b, + 0x14, 0xe9, 0x43, 0xed, 0x4c, 0x77, 0x66, 0xe1, 0xb3, 0xca, 0xb4, 0xef, 0x53, 0x66, 0xc6, 0x06, 0x68, 0xbb, 0x08, + 0xdf, 0x40, 0x07, 0x2a, 0x84, 0xfc, 0x0d, 0x22, 0x22, 0x11, 0xb0, 0xcb, 0xa9, 0x3b, 0xb1, 0xe9, 0x90, 0xcc, 0x43, + 0xcc, 0x0a, 0x35, 0xca, 0x0b, 0x9e, 0x1c, 0x0d, 0x48, 0x45, 0xa8, 0xdb, 0xfd, 0xfe, 0xf9, 0xc2, 0x05, 0xb5, 0x5f, + 0x53, 0xec, 0x18, 0xdd, 0x14, 0x70, 0x2e, 0x78, 0x94, 0xf7, 0xdc, 0x3b, 0x07, 0x34, 0xc7, 0xf6, 0x14, 0x59, 0x03, + 0x4e, 0x6f, 0xbb, 0x10, 0x60, 0xfb, 0xac, 0xd9, 0xda, 0x9f, 0xac, 0xae, 0xa2, 0xa9, 0x57, 0xf2, 0x99, 0xee, 0xa2, + 0xc4, 0xed, 0xa2, 0x58, 0x76, 0xd1, 0xa6, 0x81, 0x60, 0xc7, 0x95, 0x1f, 0x00, 0x6f, 0x68, 0xd4, 0xef, 0x97, 0xad, + 0x9e, 0x3d, 0xf9, 0xda, 0x71, 0xcf, 0x66, 0x3e, 0x2b, 0x4d, 0xcf, 0x7e, 0x4e, 0xdd, 0x9e, 0x95, 0x93, 0xbd, 0xe8, + 0x9c, 0xec, 0xd3, 0xd9, 0x3c, 0x10, 0x5c, 0xee, 0xdc, 0xe7, 0xf9, 0x54, 0x4f, 0xbb, 0xca, 0x0f, 0x5a, 0x43, 0x64, + 0xed, 0x72, 0x55, 0xf7, 0xba, 0x82, 0x05, 0x2c, 0xc1, 0xdd, 0x7a, 0x69, 0xfe, 0x19, 0xbb, 0xbf, 0x17, 0xf4, 0xd2, + 0xfc, 0x77, 0xfa, 0x93, 0x02, 0x38, 0x00, 0x8d, 0xa9, 0xdd, 0x02, 0x0f, 0x31, 0x54, 0x50, 0xb8, 0x9b, 0x95, 0x73, + 0xaf, 0x06, 0x38, 0x4c, 0xd2, 0x37, 0xb4, 0x7a, 0xa5, 0xc5, 0xae, 0x97, 0xc9, 0x5e, 0x01, 0x1e, 0xaa, 0x90, 0x87, + 0x87, 0x43, 0xd4, 0x31, 0xec, 0xa0, 0x8e, 0x80, 0x61, 0x0f, 0xa1, 0xb1, 0x05, 0x9e, 0x8f, 0xbf, 0x64, 0x7c, 0x2f, + 0x40, 0x6d, 0x84, 0xf0, 0x78, 0xb5, 0x28, 0x43, 0x6c, 0xd9, 0x1b, 0xa4, 0x92, 0xfa, 0x45, 0x20, 0xca, 0x68, 0x15, + 0xd0, 0x56, 0x7b, 0xcc, 0xd2, 0x78, 0x0d, 0xa1, 0x62, 0xa9, 0x8f, 0x21, 0x34, 0x70, 0xf8, 0x1d, 0x0e, 0x20, 0xc1, + 0x97, 0x5c, 0x93, 0xcd, 0xbd, 0xc9, 0xef, 0x68, 0x9f, 0x3f, 0x1c, 0xce, 0x2f, 0x11, 0x94, 0x2e, 0x85, 0x8f, 0x54, + 0x22, 0xaa, 0xa7, 0xb8, 0x29, 0x21, 0x9b, 0x25, 0x2b, 0xfd, 0xe0, 0xb3, 0xfa, 0x05, 0x00, 0xb2, 0x10, 0x68, 0x13, + 0x99, 0xfd, 0xe9, 0x4c, 0x45, 0x17, 0x00, 0x87, 0xf8, 0xc3, 0x27, 0x88, 0xbe, 0xa1, 0x65, 0x5a, 0x3e, 0x4e, 0x78, + 0x08, 0x5a, 0x5b, 0xd2, 0x49, 0xc4, 0x4a, 0x81, 0x0d, 0x91, 0xf0, 0xfd, 0xfe, 0x79, 0x2c, 0xe9, 0x40, 0xa3, 0x56, + 0xf7, 0xc6, 0xad, 0xee, 0x95, 0xaf, 0xeb, 0x4e, 0x6e, 0x7c, 0x50, 0xb4, 0xcf, 0xe6, 0x8d, 0xca, 0xf7, 0x7d, 0x9d, + 0xb3, 0x3b, 0xdd, 0x3b, 0x72, 0x4e, 0x7c, 0x7f, 0x0f, 0xa1, 0xe8, 0xa1, 0x29, 0xb2, 0x2c, 0x09, 0x03, 0x5a, 0x6b, + 0xd7, 0x9e, 0x65, 0x74, 0xf0, 0xda, 0x37, 0x84, 0x88, 0x3c, 0xc5, 0x27, 0x21, 0xb7, 0x38, 0x3e, 0x28, 0xd0, 0x3f, + 0x33, 0xfe, 0xcc, 0x89, 0x1f, 0xb6, 0xfa, 0x05, 0x70, 0x6e, 0xba, 0xf7, 0xee, 0xc4, 0xac, 0xc7, 0x50, 0xca, 0xc6, + 0xff, 0xfd, 0x3e, 0x91, 0x05, 0x3a, 0x1d, 0xd1, 0x30, 0x10, 0xdc, 0x45, 0xf5, 0x7f, 0xaf, 0x78, 0xdd, 0xb3, 0x56, + 0xe7, 0xcb, 0x4f, 0x9d, 0x9e, 0xf4, 0x7a, 0xe9, 0x56, 0xf8, 0x32, 0x4c, 0x7c, 0xe7, 0x75, 0xbf, 0x61, 0xbb, 0xef, + 0x7e, 0x79, 0x77, 0xf4, 0x32, 0xb0, 0x49, 0xe1, 0x3b, 0x9b, 0x92, 0xcf, 0x7a, 0xa0, 0xf0, 0xeb, 0xb1, 0x5e, 0x5d, + 0xac, 0x7b, 0xac, 0x87, 0x5a, 0x40, 0xf4, 0xb0, 0x00, 0xf5, 0x5f, 0xcf, 0x3e, 0x0d, 0x85, 0x83, 0x6c, 0x9c, 0x2a, + 0x50, 0x64, 0xc1, 0x9f, 0x89, 0xd1, 0xba, 0x20, 0x40, 0x64, 0xb3, 0x7d, 0x7d, 0xac, 0x4e, 0x66, 0xdf, 0x94, 0x5a, + 0x92, 0xc1, 0x37, 0x01, 0x99, 0x1d, 0x58, 0x39, 0x41, 0xe9, 0xb8, 0x35, 0xe0, 0xca, 0x16, 0x91, 0x78, 0xfb, 0xd3, + 0x20, 0x3b, 0x6b, 0x4e, 0x1a, 0xed, 0xc3, 0x3e, 0xcd, 0x03, 0x04, 0x22, 0x99, 0x8a, 0x20, 0xd7, 0xdc, 0x5b, 0xd2, + 0x47, 0x87, 0x73, 0x5e, 0xc8, 0x3f, 0xa7, 0x52, 0x87, 0x38, 0x94, 0x58, 0x03, 0x81, 0xca, 0x33, 0x54, 0x39, 0x6c, + 0x90, 0xe3, 0x8f, 0x8e, 0x64, 0x26, 0x31, 0x59, 0xe4, 0x6e, 0xcd, 0x54, 0xf8, 0x81, 0xe0, 0x63, 0x96, 0x73, 0xe0, + 0x02, 0x9b, 0xcd, 0x7d, 0x35, 0xc5, 0xc5, 0x15, 0xf8, 0x63, 0x0a, 0xbf, 0xe2, 0x29, 0xec, 0xb4, 0xfb, 0x75, 0x51, + 0xa5, 0xa8, 0xdb, 0x28, 0x2c, 0x2a, 0x59, 0x30, 0xad, 0x21, 0x4d, 0x74, 0x18, 0xfd, 0x49, 0xce, 0x40, 0x41, 0xc8, + 0x2f, 0x9b, 0x06, 0x18, 0xa9, 0xe4, 0xf2, 0xa0, 0x4a, 0x02, 0x2f, 0xc0, 0x36, 0xa8, 0xd8, 0xba, 0x80, 0x20, 0xdb, + 0xa4, 0x28, 0xd3, 0xaf, 0x45, 0x5e, 0x87, 0x59, 0x50, 0x8d, 0xd2, 0xea, 0x27, 0xfd, 0x13, 0x98, 0xb7, 0xa9, 0x18, + 0xd5, 0x2a, 0x26, 0xbf, 0xd1, 0xef, 0x17, 0x83, 0xd6, 0x87, 0x0c, 0x3e, 0x7a, 0x6d, 0x1a, 0xfc, 0xda, 0x69, 0xb0, + 0xc3, 0x44, 0x23, 0x00, 0x92, 0x39, 0xb5, 0xe4, 0xa1, 0xe8, 0xcf, 0x20, 0xc7, 0x1a, 0x55, 0x4e, 0xc1, 0x60, 0xfd, + 0xc7, 0xa3, 0x1d, 0x98, 0x7a, 0x71, 0xb4, 0x25, 0x3b, 0x68, 0xe5, 0x1b, 0xe0, 0x7e, 0x8d, 0x6c, 0x31, 0xcb, 0x01, + 0x9a, 0xbd, 0x46, 0x64, 0x7c, 0xf2, 0x02, 0x18, 0xb3, 0x75, 0x16, 0x46, 0x22, 0x0e, 0xc6, 0xaa, 0x31, 0x63, 0x06, + 0x06, 0x2e, 0xd0, 0xb5, 0x4c, 0x4a, 0xd2, 0x90, 0x0e, 0x06, 0xac, 0x94, 0x2d, 0x1c, 0xf0, 0xa2, 0x39, 0x6e, 0xc7, + 0xbb, 0x16, 0x8d, 0x07, 0xb6, 0x8b, 0xed, 0xef, 0x5e, 0x14, 0xdb, 0xb7, 0xe1, 0x96, 0xf4, 0x0a, 0x39, 0x4b, 0xe8, + 0xe7, 0x4f, 0xb2, 0xcf, 0x1a, 0x4e, 0x4e, 0x85, 0x66, 0x68, 0x29, 0x12, 0x4a, 0xf1, 0x4e, 0x4f, 0x0a, 0x8c, 0x65, + 0x2c, 0xfc, 0x3d, 0x70, 0x4e, 0x17, 0x8a, 0xc8, 0x1d, 0x38, 0x8e, 0xaf, 0xa1, 0x82, 0xe0, 0xbf, 0x00, 0xb3, 0x18, + 0x20, 0x4f, 0x67, 0x21, 0xe1, 0x14, 0xc2, 0xc5, 0x2a, 0xeb, 0xf7, 0xe5, 0x2f, 0xea, 0xa2, 0x8b, 0x4c, 0xd6, 0x7d, + 0x12, 0x8e, 0xcc, 0x58, 0x4e, 0xbd, 0x90, 0x3c, 0xef, 0x79, 0x32, 0x4d, 0x9e, 0xe4, 0x41, 0x04, 0x90, 0xcf, 0xe1, + 0x5d, 0x98, 0x66, 0x60, 0x95, 0x26, 0xe5, 0x47, 0x28, 0x7d, 0xf1, 0x79, 0xe5, 0x07, 0x3a, 0x7b, 0x6e, 0x92, 0xe1, + 0xcd, 0xaa, 0xf5, 0x26, 0xb5, 0xae, 0x8b, 0x07, 0xfc, 0xab, 0x33, 0xd8, 0x38, 0xd7, 0x99, 0xe0, 0xc0, 0x8b, 0xa4, + 0xd6, 0x6b, 0xc6, 0x9f, 0x65, 0xb8, 0x2e, 0x55, 0x1b, 0x7d, 0x14, 0xa2, 0x73, 0xc8, 0x54, 0x80, 0x42, 0x91, 0xf6, + 0x0f, 0x4a, 0xad, 0x4c, 0x2a, 0x6d, 0x24, 0x80, 0xee, 0x61, 0xd2, 0x60, 0x8b, 0xa1, 0x8c, 0xa5, 0x49, 0x94, 0x3b, + 0x0d, 0xe2, 0xca, 0x7e, 0xac, 0x24, 0x0e, 0x2d, 0x8b, 0xe4, 0xdf, 0xbb, 0x9e, 0xbe, 0x42, 0xea, 0x4e, 0x16, 0xc8, + 0x8c, 0xf1, 0x3c, 0x8f, 0x3f, 0x01, 0x61, 0x36, 0x68, 0xa3, 0xa2, 0x10, 0x42, 0x36, 0x88, 0x41, 0xe3, 0x79, 0x1e, + 0xbf, 0x50, 0x34, 0x1e, 0xf2, 0x51, 0xe4, 0xab, 0xbf, 0x4a, 0xfd, 0x57, 0xe8, 0x33, 0x13, 0x3c, 0x42, 0x35, 0xd1, + 0xbf, 0x7b, 0x3e, 0xbb, 0x03, 0xb5, 0x61, 0x14, 0x66, 0xa6, 0xfc, 0xca, 0x37, 0xc5, 0xd9, 0xeb, 0xaf, 0xe8, 0x2a, + 0xdb, 0xba, 0x1f, 0xbd, 0x3e, 0x22, 0xb0, 0x36, 0x46, 0x57, 0xdc, 0x18, 0x40, 0x0e, 0x93, 0xf7, 0x2b, 0x4a, 0xcb, + 0x21, 0x0d, 0x42, 0x07, 0x0d, 0x41, 0xaf, 0x24, 0xfa, 0x40, 0x62, 0x11, 0x63, 0x78, 0x21, 0x9e, 0x91, 0x9a, 0x4c, + 0x34, 0xc4, 0x2b, 0x62, 0x3f, 0x44, 0x4b, 0x4e, 0x4d, 0x74, 0x23, 0x4c, 0x31, 0x90, 0xd8, 0x19, 0x24, 0x27, 0x49, + 0xad, 0xfc, 0xe2, 0x99, 0x24, 0x2c, 0xb1, 0xf3, 0x10, 0x83, 0x49, 0x2d, 0xdd, 0xe9, 0x4d, 0x95, 0xbe, 0x1c, 0x69, + 0x39, 0x68, 0x1f, 0x80, 0x5d, 0x4a, 0x7a, 0xff, 0xa4, 0x50, 0xc4, 0x87, 0x30, 0x8e, 0x21, 0x7c, 0x8b, 0xa8, 0xae, + 0xc0, 0xb9, 0x56, 0xa0, 0xb1, 0x1a, 0x78, 0x68, 0x66, 0xd5, 0x7c, 0xc8, 0xe9, 0xa7, 0xd2, 0xf2, 0xc7, 0x88, 0xc6, + 0x46, 0xeb, 0xe6, 0x70, 0xd8, 0xd3, 0xaa, 0x97, 0xce, 0x41, 0x97, 0xcd, 0x24, 0x26, 0x6e, 0x20, 0x5d, 0x3f, 0xfa, + 0xcd, 0x84, 0xbd, 0x88, 0x0a, 0xb9, 0x14, 0x82, 0x82, 0x56, 0x07, 0x02, 0x87, 0xc2, 0x5b, 0x94, 0xf9, 0x22, 0xa6, + 0x0d, 0x84, 0xc1, 0xe7, 0x07, 0xf2, 0xf3, 0x4d, 0x41, 0x2a, 0x76, 0xac, 0x6b, 0xbf, 0xbf, 0x28, 0x3d, 0xc0, 0x93, + 0x33, 0x49, 0x9e, 0x36, 0x43, 0x58, 0x11, 0x40, 0x63, 0x56, 0x93, 0xc5, 0x09, 0x57, 0xe6, 0xf0, 0x75, 0xe5, 0x95, + 0x2c, 0x65, 0xea, 0x3c, 0xd5, 0x0b, 0x20, 0xea, 0x78, 0x83, 0x56, 0xa4, 0x7e, 0x85, 0xce, 0x5e, 0xb3, 0x12, 0x32, + 0x1e, 0x9e, 0x73, 0x9e, 0x8e, 0xee, 0x59, 0xc2, 0x23, 0xfc, 0x2b, 0x99, 0xe8, 0xc3, 0xef, 0x9e, 0xc3, 0xcd, 0x38, + 0xe1, 0x91, 0xdb, 0xec, 0x7d, 0x15, 0xae, 0xe0, 0x66, 0x5a, 0x00, 0x92, 0x5b, 0x90, 0x34, 0x01, 0x25, 0x24, 0x32, + 0x21, 0xb3, 0xa6, 0xe4, 0x8b, 0x96, 0xb6, 0xc1, 0x1a, 0x26, 0x9d, 0x07, 0xbc, 0x68, 0xf5, 0xd1, 0x6a, 0xa2, 0x5d, + 0x66, 0xf9, 0x7c, 0x88, 0x33, 0x54, 0x73, 0xdc, 0x9d, 0xc1, 0xcf, 0x01, 0xaf, 0x58, 0xd5, 0xa4, 0xa3, 0xdd, 0x80, + 0x0b, 0x4f, 0xae, 0xf3, 0x74, 0xb4, 0xc5, 0x5f, 0x72, 0x7f, 0x00, 0xe8, 0x60, 0xea, 0x12, 0xf8, 0x53, 0xb5, 0xd5, + 0x54, 0xea, 0xb7, 0xd6, 0x7e, 0x5d, 0x77, 0x56, 0x2b, 0xf7, 0xac, 0xcb, 0xd0, 0x1e, 0x19, 0x72, 0xc6, 0x0c, 0xf8, + 0x73, 0xc6, 0x92, 0x3f, 0x67, 0xac, 0xf8, 0x73, 0xc6, 0x8d, 0x91, 0x01, 0x94, 0xe0, 0x5e, 0xf2, 0x67, 0x7b, 0xc4, + 0x0c, 0xb1, 0x1a, 0x54, 0x02, 0x2b, 0x4b, 0x39, 0xf7, 0x91, 0x53, 0x4c, 0x39, 0x65, 0x78, 0xe9, 0x74, 0xe6, 0x0e, + 0xe4, 0x3c, 0x98, 0xb9, 0xc3, 0x64, 0xaf, 0xcf, 0x8d, 0x38, 0x96, 0xc6, 0xa4, 0xa8, 0x20, 0x9d, 0xd3, 0xe1, 0xe6, + 0xd5, 0x71, 0x9e, 0xb0, 0x8c, 0x8f, 0xdb, 0x67, 0x0a, 0x84, 0xd8, 0xe2, 0x19, 0x12, 0x29, 0x55, 0xb3, 0xdc, 0xe6, + 0x0f, 0x87, 0x7a, 0x74, 0xaf, 0x77, 0x7a, 0xf8, 0x95, 0xb0, 0xdf, 0x32, 0xcf, 0x3e, 0x41, 0x00, 0x93, 0x44, 0x9e, + 0x49, 0x38, 0xfa, 0xb1, 0x1c, 0xfd, 0x4d, 0xc3, 0xbf, 0x64, 0xa8, 0xee, 0x0e, 0x81, 0x89, 0x2d, 0x3b, 0x70, 0x08, + 0x4e, 0x57, 0x95, 0x48, 0xc0, 0xc1, 0x66, 0xc3, 0x22, 0xbd, 0xc7, 0x43, 0x9c, 0x0f, 0x0a, 0x1f, 0xa1, 0x61, 0x46, + 0xef, 0xf7, 0x37, 0xc2, 0xab, 0x64, 0x2b, 0x0f, 0x87, 0xc4, 0xba, 0x0b, 0x3b, 0xfa, 0x38, 0xda, 0xa3, 0x84, 0xda, + 0x8f, 0x6a, 0xbd, 0xa9, 0xd4, 0x83, 0xdc, 0xec, 0x42, 0x62, 0x50, 0xb1, 0x54, 0x9f, 0x5e, 0xa9, 0x3e, 0xd4, 0xac, + 0xf3, 0xbb, 0x3a, 0xee, 0x53, 0x31, 0x5a, 0xcb, 0x09, 0x01, 0xae, 0x83, 0x44, 0xa3, 0x03, 0x60, 0x9c, 0x6d, 0xb6, + 0xbc, 0xd4, 0xd6, 0x89, 0xd2, 0x71, 0x9c, 0xeb, 0xe3, 0xf8, 0x70, 0x90, 0x62, 0xc6, 0xe5, 0x91, 0x98, 0x71, 0xd9, + 0x00, 0xbc, 0x59, 0xe7, 0x41, 0x7d, 0x38, 0x5c, 0xd2, 0xa5, 0xc8, 0x74, 0xb6, 0x51, 0x7e, 0xd6, 0xa3, 0xfb, 0x27, + 0x09, 0x9a, 0x7b, 0x2b, 0xec, 0xbd, 0x48, 0xb6, 0x67, 0xb2, 0x4e, 0xbd, 0x8c, 0x7c, 0x7a, 0xe1, 0x9e, 0x5d, 0x72, + 0xf5, 0xc3, 0xea, 0xeb, 0xe9, 0x67, 0xe1, 0x45, 0xac, 0xa2, 0xdd, 0xba, 0x64, 0xc2, 0xde, 0x52, 0x2a, 0x69, 0x95, + 0x97, 0x4f, 0x37, 0x7e, 0x80, 0x99, 0x69, 0x4f, 0x1f, 0x64, 0x23, 0xaa, 0x3f, 0x2b, 0x51, 0x2b, 0xc3, 0x64, 0xe1, + 0xbc, 0x64, 0xea, 0xc9, 0x80, 0xc7, 0xac, 0xe4, 0x91, 0xec, 0xf4, 0xc6, 0x20, 0x08, 0x60, 0x9d, 0x93, 0x56, 0x9d, + 0x71, 0x34, 0x5a, 0x55, 0x2e, 0x4e, 0x57, 0xb9, 0xc0, 0x70, 0xbb, 0x35, 0xdb, 0xa8, 0x3a, 0xcb, 0x4d, 0xad, 0x52, + 0xbe, 0x03, 0xf8, 0x58, 0x56, 0xb9, 0xa0, 0x63, 0xca, 0xd4, 0x79, 0x03, 0xc1, 0xd8, 0xaa, 0xc6, 0x85, 0x53, 0xe3, + 0x82, 0x47, 0xd4, 0xee, 0xa6, 0xa9, 0x47, 0x5b, 0x60, 0x29, 0x1d, 0xed, 0x78, 0x89, 0x2a, 0x85, 0x9f, 0x05, 0xdf, + 0x87, 0x71, 0xfc, 0xa2, 0xd8, 0xaa, 0x03, 0xf1, 0xb6, 0xd8, 0x22, 0xed, 0x8b, 0xfc, 0x0b, 0x71, 0xc0, 0x6b, 0x5d, + 0x53, 0x5e, 0x5b, 0x73, 0x1a, 0xd8, 0x1a, 0x46, 0x4a, 0x0a, 0xe7, 0xe6, 0xcf, 0xc3, 0x81, 0x56, 0x76, 0xad, 0xee, + 0x0a, 0xb5, 0x1e, 0x73, 0xd8, 0xb0, 0x6f, 0xb2, 0x70, 0x27, 0x4a, 0x70, 0xe4, 0x92, 0x7f, 0x1d, 0x0e, 0x5a, 0x65, + 0xa9, 0x8e, 0xf4, 0xd9, 0xfe, 0x6b, 0x30, 0x66, 0xe8, 0xd2, 0x04, 0x2c, 0x1b, 0x23, 0xf9, 0x57, 0xd3, 0xcc, 0x1b, + 0x26, 0x6b, 0xa6, 0x70, 0x1c, 0x1a, 0x46, 0x48, 0x03, 0xba, 0x0d, 0x6a, 0xc3, 0x93, 0xf9, 0xa6, 0x2a, 0xbf, 0xba, + 0x23, 0xd5, 0x7e, 0x30, 0xbc, 0x9c, 0x88, 0x73, 0xba, 0x24, 0xa9, 0xa7, 0x12, 0x4a, 0x42, 0xb0, 0x4b, 0x1f, 0xc8, + 0x89, 0x15, 0x90, 0xb5, 0x8c, 0xe5, 0xb7, 0x7a, 0x40, 0xe8, 0x3f, 0xed, 0xd6, 0x0b, 0xfd, 0xa7, 0x69, 0xb6, 0x50, + 0xd7, 0x1f, 0x26, 0xf7, 0x1d, 0xbd, 0xfe, 0xe0, 0xf0, 0x4e, 0x5d, 0x55, 0x5c, 0xc5, 0xa3, 0xda, 0x30, 0xc9, 0x8d, + 0xb2, 0x70, 0x57, 0x6c, 0x6a, 0xb5, 0x3c, 0x1d, 0x87, 0x11, 0x98, 0x11, 0x14, 0x20, 0xeb, 0xba, 0x8d, 0x88, 0x61, + 0x25, 0x97, 0x09, 0xf9, 0x84, 0x80, 0x2c, 0x4a, 0x8d, 0xf3, 0x71, 0x0b, 0x54, 0x22, 0x18, 0x9c, 0x86, 0xd6, 0xaa, + 0x9b, 0xfc, 0xa4, 0xb2, 0xb1, 0x25, 0x90, 0x43, 0x92, 0xc9, 0x62, 0x39, 0xba, 0x15, 0x8b, 0xa2, 0x14, 0xbf, 0x60, + 0x3d, 0x5c, 0xb3, 0x85, 0xfb, 0x0c, 0x08, 0xed, 0x27, 0x4a, 0x7b, 0x13, 0x69, 0x82, 0xee, 0x25, 0x5b, 0x01, 0xc8, + 0x00, 0x8a, 0xba, 0xda, 0xad, 0xcf, 0xf9, 0x39, 0x92, 0x66, 0x38, 0x8c, 0x6e, 0x9f, 0x2e, 0x83, 0xe5, 0xe0, 0x12, + 0xb5, 0xd2, 0x97, 0x2c, 0x6e, 0x61, 0x50, 0xed, 0xcd, 0x12, 0x0e, 0x6a, 0x66, 0xad, 0x8d, 0x40, 0x30, 0xd9, 0x43, + 0x41, 0xc5, 0x5c, 0xc1, 0x3e, 0x28, 0x58, 0x4b, 0x5e, 0x07, 0x87, 0x5b, 0xfb, 0xb2, 0x52, 0x5c, 0x3c, 0xbd, 0x48, + 0x5a, 0x17, 0x96, 0xf2, 0xe2, 0x69, 0x03, 0x06, 0x97, 0x23, 0x6c, 0x2a, 0x30, 0x49, 0x00, 0xe8, 0x56, 0x44, 0x11, + 0x2f, 0x4a, 0x61, 0xdb, 0xca, 0x67, 0x4e, 0xd8, 0x60, 0xc3, 0xee, 0xe1, 0x5e, 0x19, 0x94, 0x0c, 0x2e, 0xc4, 0xb8, + 0xdd, 0xec, 0x02, 0x5c, 0xc1, 0x50, 0x18, 0x5b, 0xf3, 0x77, 0x99, 0x17, 0x29, 0x01, 0x37, 0x43, 0x94, 0xaf, 0x0d, + 0x9c, 0x4c, 0x7a, 0x72, 0x2d, 0x58, 0x0c, 0x58, 0xd0, 0xe0, 0x3b, 0x6a, 0xfd, 0x9d, 0xc9, 0xbf, 0xf1, 0xf4, 0xd0, + 0x0f, 0x5e, 0x64, 0xde, 0xc2, 0x67, 0xef, 0x2a, 0x19, 0xad, 0x49, 0xa2, 0xbc, 0x7a, 0xb8, 0x00, 0xb9, 0x61, 0x31, + 0xba, 0x67, 0x0b, 0x10, 0x27, 0x16, 0xa3, 0x84, 0x32, 0xba, 0xc2, 0xbd, 0xca, 0x6c, 0x99, 0x08, 0xa4, 0x38, 0xb0, + 0x90, 0x72, 0x6f, 0xb1, 0x0e, 0x16, 0xb8, 0x3f, 0x91, 0x5c, 0x40, 0xc9, 0x03, 0x28, 0x57, 0x0a, 0x08, 0xf8, 0x74, + 0x00, 0xe5, 0x4b, 0x79, 0x11, 0xfe, 0xc4, 0x89, 0x1a, 0x2c, 0x46, 0xf7, 0x0d, 0xfb, 0xc9, 0x0b, 0x2d, 0xfb, 0xc3, + 0x52, 0x6b, 0x1a, 0x56, 0x7c, 0x09, 0xd3, 0x62, 0xe2, 0xf6, 0xe5, 0xca, 0xae, 0x8a, 0xcf, 0x56, 0xea, 0xec, 0xa6, + 0x86, 0x24, 0xec, 0x1b, 0xb2, 0x0a, 0x70, 0xb0, 0x2a, 0xe2, 0x9e, 0x75, 0xb9, 0x0f, 0xa3, 0xbf, 0x36, 0x69, 0x29, + 0x2c, 0x54, 0x49, 0x7f, 0xdf, 0x94, 0x02, 0xa9, 0x4c, 0x74, 0xa2, 0x85, 0xe0, 0x0a, 0x0c, 0x02, 0x77, 0x22, 0xaf, + 0x01, 0x30, 0x06, 0x5c, 0x0a, 0x94, 0x65, 0x5b, 0x42, 0x48, 0x75, 0x3f, 0x03, 0xb5, 0x9d, 0xb8, 0x4b, 0x23, 0xb2, + 0x16, 0xa2, 0xaf, 0x82, 0x31, 0x73, 0x5e, 0x4a, 0xb7, 0xd8, 0x74, 0xb5, 0x59, 0x5d, 0xa3, 0x73, 0x69, 0xcb, 0xcd, + 0x4f, 0xd8, 0x62, 0xad, 0x40, 0xd9, 0x84, 0xa4, 0xed, 0x9c, 0xe7, 0x28, 0x9b, 0xd0, 0xd2, 0xde, 0x53, 0x8f, 0x0a, + 0xd5, 0xc9, 0xd6, 0x4b, 0xd5, 0xd4, 0x22, 0xac, 0x16, 0x17, 0x95, 0x1f, 0x80, 0x6e, 0x2a, 0xad, 0x9e, 0xd7, 0x35, + 0x9a, 0x42, 0xad, 0x16, 0x8e, 0x1b, 0xed, 0x6c, 0xba, 0x48, 0x97, 0x88, 0xb3, 0x2a, 0xed, 0xd0, 0x3f, 0x65, 0xda, + 0xf5, 0xb2, 0xa3, 0xdf, 0x8c, 0xab, 0x0b, 0x5c, 0x88, 0x0d, 0xf8, 0x9c, 0xfb, 0xcb, 0xeb, 0x3d, 0x8d, 0x7b, 0xfe, + 0xe1, 0x80, 0xec, 0x49, 0xed, 0x0f, 0xd5, 0xc7, 0xae, 0x60, 0xc8, 0xc2, 0x28, 0xf5, 0x17, 0x29, 0xef, 0x3d, 0xc2, + 0x71, 0xff, 0x52, 0xf5, 0xd8, 0xaf, 0x19, 0xdf, 0xd7, 0xc5, 0x26, 0x4a, 0x28, 0xaa, 0xa1, 0xb7, 0x2a, 0x36, 0x95, + 0x88, 0x8b, 0xfb, 0xbc, 0xc7, 0x30, 0x19, 0xc6, 0x42, 0xa6, 0xc2, 0x9f, 0x32, 0x15, 0x3c, 0x42, 0x28, 0x71, 0xb3, + 0xee, 0x91, 0x76, 0x13, 0xe2, 0x94, 0x6a, 0x51, 0xca, 0x64, 0xfc, 0x5b, 0x3f, 0x81, 0xf2, 0x9c, 0xa2, 0x65, 0xfa, + 0x51, 0xe1, 0x32, 0x7d, 0xb3, 0x3e, 0x2e, 0x3d, 0x13, 0xa1, 0xce, 0x5c, 0x6c, 0x6a, 0x9d, 0x8e, 0xb1, 0x53, 0x3a, + 0xb5, 0x61, 0x5f, 0x2b, 0xc5, 0x65, 0x45, 0xe1, 0xdf, 0x48, 0x64, 0xd5, 0x33, 0xe2, 0xf8, 0x3f, 0xb3, 0xf6, 0x19, + 0x56, 0x81, 0x5f, 0x06, 0xf2, 0x7e, 0x01, 0xf0, 0x71, 0x5d, 0x97, 0xe9, 0xed, 0x06, 0x68, 0x43, 0x68, 0xf8, 0x7b, + 0x3e, 0x32, 0x60, 0xba, 0x8f, 0x70, 0x86, 0xf4, 0x50, 0xe7, 0x9c, 0xce, 0xca, 0x74, 0xce, 0x55, 0x58, 0x4b, 0xb0, + 0x97, 0x93, 0x26, 0x97, 0xeb, 0x12, 0xd4, 0x4c, 0xe0, 0xf6, 0xa1, 0x3d, 0x22, 0x84, 0xda, 0x94, 0xd5, 0xf4, 0x12, + 0x6a, 0xde, 0xc9, 0x69, 0x47, 0x93, 0x12, 0x5c, 0x35, 0x74, 0x56, 0xae, 0xff, 0x3a, 0x1c, 0x7a, 0xb7, 0x59, 0x11, + 0xfd, 0xd9, 0x43, 0x7f, 0xc7, 0xed, 0x75, 0xfa, 0x15, 0xa2, 0x65, 0xac, 0xbf, 0x21, 0x03, 0x3a, 0x9e, 0x0c, 0x6f, + 0x8b, 0x6d, 0x8f, 0x7d, 0x45, 0x0d, 0x96, 0xbe, 0x7e, 0x5c, 0x83, 0x84, 0xaa, 0x6b, 0x5f, 0x58, 0x3c, 0x61, 0x9e, + 0x12, 0x6d, 0x0b, 0x1f, 0xc2, 0x42, 0xbf, 0x42, 0x64, 0x24, 0x84, 0x9b, 0xca, 0xee, 0x51, 0xd2, 0x2e, 0xf4, 0xa5, + 0xaf, 0x65, 0x5f, 0xf9, 0xce, 0x05, 0xc0, 0xca, 0x3e, 0xb5, 0xe1, 0x9e, 0xf4, 0xa7, 0x54, 0x1f, 0xb6, 0xbf, 0x25, + 0x0b, 0x28, 0xb4, 0xb0, 0x9e, 0xca, 0xd9, 0xb9, 0x2c, 0x79, 0x9e, 0x4d, 0xf7, 0x6b, 0xd8, 0xa3, 0xee, 0xd0, 0x6b, + 0x2a, 0x38, 0xbf, 0x34, 0xa3, 0xf7, 0xbb, 0xa1, 0x50, 0x1d, 0x75, 0xee, 0x20, 0xcb, 0xd2, 0xba, 0xe4, 0xfc, 0x65, + 0xe5, 0x8e, 0xc2, 0xfc, 0x2e, 0x04, 0xcf, 0xb0, 0xee, 0xdd, 0xc5, 0x79, 0xef, 0x73, 0x6b, 0x8e, 0xfc, 0x9a, 0xcd, + 0x52, 0xc4, 0x22, 0x99, 0x83, 0xd5, 0x0f, 0xfd, 0x3c, 0xf6, 0xdb, 0x20, 0x87, 0xe3, 0xa6, 0x01, 0x1d, 0x36, 0x64, + 0xd6, 0xbe, 0x44, 0xe0, 0x54, 0x23, 0x48, 0x53, 0x13, 0xd4, 0x2c, 0x0f, 0x91, 0xd8, 0x2e, 0x65, 0xdb, 0x20, 0xd7, + 0x5d, 0x30, 0xcd, 0x91, 0xf6, 0x0c, 0xde, 0x37, 0x69, 0x92, 0x0a, 0xcd, 0xa2, 0x8b, 0x95, 0x8c, 0x7f, 0x47, 0xda, + 0x4c, 0xc9, 0x1e, 0x5b, 0x03, 0xef, 0x25, 0x28, 0x27, 0xc3, 0x14, 0xc3, 0x77, 0x7c, 0xbd, 0xf3, 0xe8, 0x22, 0x7e, + 0x3e, 0x66, 0x9b, 0x94, 0x1d, 0xc1, 0x24, 0xd9, 0xf8, 0x86, 0xe2, 0x0d, 0xdf, 0xdf, 0x56, 0xa2, 0x04, 0xd0, 0xcb, + 0x82, 0x3f, 0x93, 0x36, 0x57, 0xe8, 0x76, 0xf7, 0x8e, 0x52, 0xf8, 0x25, 0x2f, 0x0f, 0x87, 0x6d, 0xea, 0x85, 0xd0, + 0xf9, 0x22, 0x7e, 0x07, 0xe6, 0x30, 0x86, 0xd8, 0x8c, 0x00, 0x61, 0x8e, 0x0f, 0xa8, 0x83, 0xf5, 0x23, 0x00, 0x8d, + 0x13, 0x28, 0xc0, 0xe8, 0xab, 0x6d, 0x41, 0xdf, 0xf2, 0xe2, 0x22, 0x42, 0xd4, 0x28, 0xc0, 0x44, 0x49, 0xb3, 0x18, + 0x86, 0x03, 0x9d, 0xdf, 0x37, 0xb7, 0x75, 0x29, 0x70, 0xe8, 0x1d, 0xcb, 0xf0, 0xdf, 0xfe, 0xc7, 0xda, 0xd2, 0xaa, + 0xb2, 0xdd, 0x1a, 0xa7, 0x99, 0xff, 0xed, 0xb6, 0xd0, 0xf7, 0x5f, 0x0a, 0xc5, 0xf3, 0x8e, 0xd7, 0xed, 0x2f, 0x10, + 0xbd, 0xaf, 0x5b, 0xb9, 0x2a, 0xb5, 0x1b, 0x66, 0xca, 0xef, 0xd3, 0x3c, 0x2e, 0xee, 0x47, 0x71, 0xeb, 0xc8, 0x9b, + 0xa4, 0xe7, 0x9c, 0x7f, 0xa9, 0xfa, 0x7d, 0xef, 0x0b, 0x90, 0xf1, 0xbe, 0x14, 0xc6, 0x11, 0x93, 0x38, 0xf8, 0xf6, + 0x62, 0x14, 0x6d, 0x4a, 0xd8, 0x90, 0xdb, 0xa7, 0x25, 0x68, 0x66, 0xfa, 0x7d, 0x94, 0x28, 0xad, 0xf9, 0xfe, 0x0f, + 0x39, 0xdf, 0x5f, 0x0a, 0x79, 0xb3, 0x92, 0x1f, 0x3e, 0x5a, 0x61, 0xe0, 0x7b, 0x9c, 0x7e, 0x15, 0x3d, 0xb6, 0x2a, + 0x7d, 0xf8, 0xae, 0xb4, 0xf4, 0x59, 0x45, 0xfd, 0x0b, 0x15, 0x35, 0x2f, 0xc5, 0x88, 0x88, 0x07, 0x41, 0x3b, 0xdb, + 0x2e, 0xb5, 0x6b, 0x09, 0xda, 0x05, 0x9b, 0xc2, 0xfe, 0xfe, 0xe0, 0x90, 0xf7, 0xfb, 0x1f, 0x73, 0xaf, 0xc5, 0xeb, + 0x6e, 0xe0, 0x2e, 0x4b, 0x0f, 0x21, 0x80, 0xb5, 0x0c, 0x94, 0x71, 0x84, 0x49, 0x17, 0x79, 0x8d, 0xb2, 0xe9, 0x44, + 0xe0, 0x63, 0x96, 0x5d, 0x39, 0xc9, 0x34, 0xc0, 0x8c, 0x6a, 0x0a, 0x33, 0x01, 0x46, 0xea, 0x23, 0xd6, 0x4d, 0x4f, + 0xab, 0xd0, 0xf2, 0x35, 0x04, 0xeb, 0x22, 0xcb, 0x38, 0x8a, 0x99, 0x00, 0x60, 0xf3, 0x11, 0xe4, 0x2b, 0xba, 0x3a, + 0x24, 0xad, 0x54, 0x79, 0xbf, 0xce, 0x88, 0x8c, 0x26, 0x21, 0x9a, 0xdf, 0xc2, 0x03, 0xfb, 0xb6, 0x99, 0x51, 0xa5, + 0x9e, 0x51, 0x95, 0xcf, 0x70, 0x58, 0x0a, 0xc7, 0x88, 0xff, 0x73, 0xaa, 0x7a, 0x44, 0xa0, 0x57, 0x65, 0x5a, 0x45, + 0x45, 0x9e, 0x8b, 0x08, 0x11, 0xaa, 0xa5, 0x73, 0x38, 0xf4, 0x63, 0xbf, 0x8f, 0x03, 0x61, 0x5e, 0xac, 0x93, 0x07, + 0xba, 0xb2, 0xa6, 0xb5, 0x92, 0x02, 0xa7, 0xa2, 0x46, 0x88, 0x10, 0xde, 0x67, 0xe0, 0x59, 0x4d, 0x7d, 0xbf, 0xb1, + 0x4c, 0x74, 0xbf, 0x67, 0x40, 0xf9, 0x03, 0xf2, 0x75, 0x25, 0xc5, 0x19, 0x91, 0x3c, 0x24, 0xce, 0x38, 0x00, 0x31, + 0xdf, 0x96, 0x68, 0x34, 0xf6, 0x3f, 0x20, 0xc1, 0x50, 0xfd, 0x60, 0xa7, 0x9b, 0x7a, 0xff, 0xcc, 0x24, 0x8e, 0xa2, + 0x4f, 0xdb, 0xe4, 0xb1, 0x64, 0x69, 0xb4, 0x70, 0xf4, 0x1e, 0x31, 0x8c, 0xc3, 0xe9, 0x7c, 0x4c, 0xb2, 0x8d, 0xc9, + 0x2a, 0x80, 0x74, 0x32, 0x53, 0xc7, 0x94, 0x3a, 0x1a, 0xe7, 0x7a, 0x41, 0x15, 0x7a, 0xac, 0x4b, 0x9e, 0x83, 0xf5, + 0xe4, 0x47, 0xaf, 0xf4, 0xa7, 0x42, 0xce, 0x61, 0x23, 0x11, 0x14, 0x7e, 0x80, 0xab, 0xc1, 0x4a, 0x01, 0x83, 0xa9, + 0x6f, 0xe1, 0x6b, 0xe2, 0x39, 0x0a, 0x1e, 0x85, 0x5d, 0x8c, 0xad, 0x95, 0xef, 0x7c, 0x52, 0x50, 0xee, 0x59, 0x31, + 0xe7, 0x15, 0x70, 0x2e, 0x83, 0x42, 0x98, 0x8e, 0x67, 0xf9, 0x3f, 0x93, 0xbc, 0x9e, 0xd8, 0x10, 0x20, 0x83, 0x3f, + 0x25, 0x4e, 0x4b, 0x77, 0xe8, 0xce, 0x43, 0xcf, 0x22, 0x0e, 0x1b, 0x3d, 0x5a, 0x97, 0xc5, 0x36, 0x45, 0xbd, 0x84, + 0xf9, 0x81, 0xfc, 0xbc, 0x25, 0xdf, 0x87, 0x28, 0xde, 0x06, 0x3f, 0x67, 0x2c, 0x16, 0xf8, 0xd7, 0xdf, 0x32, 0x46, + 0x13, 0x2d, 0xf8, 0x7b, 0xd6, 0x20, 0x51, 0x31, 0x60, 0x45, 0x00, 0x97, 0xa9, 0xfa, 0xf0, 0x29, 0x31, 0xde, 0x9a, + 0x0d, 0x0f, 0x7c, 0xb3, 0x02, 0x9d, 0xfa, 0xdc, 0x5d, 0xd9, 0x9e, 0xae, 0x46, 0xaa, 0xaa, 0xf1, 0x73, 0xaa, 0xaa, + 0xf1, 0x73, 0x4a, 0xd5, 0xf8, 0x2b, 0xa3, 0xf8, 0x9d, 0xca, 0x67, 0xc8, 0x9c, 0x6c, 0x62, 0x92, 0x4e, 0xdf, 0x1b, + 0x4e, 0xec, 0xb2, 0xdf, 0xba, 0x4d, 0xa4, 0x99, 0x89, 0x14, 0x72, 0x6f, 0x00, 0x6a, 0x26, 0x7e, 0xcc, 0x0d, 0xa7, + 0xc4, 0xf9, 0xb9, 0x87, 0x2b, 0x36, 0xad, 0x5e, 0xd2, 0x82, 0x05, 0x36, 0x2f, 0xb3, 0x3c, 0xd3, 0x04, 0xb6, 0x4d, + 0x99, 0xf5, 0x97, 0xdc, 0x03, 0x08, 0x66, 0x52, 0x13, 0x00, 0xd2, 0x42, 0x54, 0x0a, 0x91, 0xbf, 0xc4, 0x59, 0x7d, + 0xce, 0x7b, 0x9b, 0x3c, 0x26, 0xd2, 0xea, 0x5e, 0xbf, 0x9f, 0x9e, 0xa5, 0x39, 0x05, 0x35, 0x1c, 0x67, 0x9d, 0xfe, + 0x94, 0x05, 0x22, 0x91, 0xab, 0xf4, 0x1f, 0x6e, 0x90, 0x97, 0xf1, 0x7d, 0xdd, 0xf6, 0xfc, 0x89, 0xfa, 0x7b, 0x67, + 0xfd, 0x6d, 0x81, 0xe0, 0x4e, 0x8e, 0xfd, 0x64, 0x55, 0xca, 0x23, 0xe3, 0xd2, 0xde, 0xf3, 0x9b, 0xba, 0x28, 0xb2, + 0x3a, 0x5d, 0x7f, 0x90, 0x7a, 0x1a, 0xdd, 0x17, 0x7b, 0x30, 0x06, 0xef, 0x00, 0xf0, 0x4c, 0x87, 0x06, 0x48, 0xdf, + 0x33, 0xf2, 0x70, 0x9f, 0x5b, 0xf2, 0x93, 0xca, 0xda, 0x24, 0x61, 0x45, 0xb1, 0x19, 0xc6, 0x08, 0x25, 0xe3, 0x34, + 0xb6, 0x7e, 0xbf, 0xaf, 0xfe, 0xde, 0x61, 0x14, 0x15, 0x15, 0x77, 0x8c, 0x46, 0x65, 0x55, 0x8f, 0xb6, 0x83, 0xc3, + 0xe1, 0x3c, 0xb7, 0x71, 0xb4, 0xf5, 0x0a, 0xd8, 0x5b, 0xa1, 0x52, 0xf6, 0x4a, 0x84, 0xe5, 0x87, 0x2b, 0xbf, 0xdf, + 0x87, 0x7f, 0x65, 0xa4, 0x85, 0xe7, 0x4f, 0xf1, 0xd7, 0x4d, 0x5d, 0x60, 0x78, 0x06, 0xad, 0xd1, 0x0a, 0x82, 0x09, + 0xfe, 0xd1, 0x81, 0x7a, 0x69, 0xa5, 0x7d, 0x04, 0xdd, 0x0a, 0xf4, 0xa0, 0xb1, 0x0f, 0x24, 0xed, 0x0b, 0x89, 0xba, + 0xbd, 0xd5, 0x69, 0xf4, 0x67, 0xc5, 0x72, 0x5e, 0xc1, 0xe4, 0x70, 0x43, 0x9f, 0x56, 0xe1, 0xf6, 0x13, 0x3c, 0xfd, + 0x05, 0x28, 0xb7, 0x0e, 0x87, 0x1c, 0xc4, 0x16, 0x70, 0xf3, 0x58, 0x85, 0x5f, 0x8a, 0x52, 0x46, 0xd4, 0xc7, 0xd3, + 0x12, 0xb4, 0x77, 0x01, 0x3a, 0x60, 0x69, 0x10, 0xaf, 0x90, 0x3c, 0x67, 0x23, 0x80, 0x65, 0x07, 0x96, 0xb3, 0x8c, + 0x53, 0x98, 0x67, 0xf9, 0xac, 0xd2, 0xf8, 0xec, 0x89, 0x57, 0xb3, 0x0c, 0x9c, 0x05, 0x2e, 0x2a, 0x9f, 0x65, 0x5a, + 0xf5, 0x54, 0x24, 0xe8, 0xf3, 0x4a, 0x4e, 0x70, 0x25, 0x38, 0xd9, 0x80, 0xfc, 0x02, 0x24, 0x69, 0x4a, 0x59, 0x53, + 0x3e, 0xbb, 0xa4, 0x1b, 0x32, 0x7a, 0xce, 0x7b, 0x5e, 0x34, 0x0c, 0xfd, 0x0b, 0xaf, 0x84, 0xf0, 0x4d, 0xdc, 0xb6, + 0x51, 0x0a, 0xfb, 0x9b, 0xc0, 0xe2, 0x13, 0xf6, 0xa3, 0xb7, 0xf0, 0xa7, 0xe3, 0x20, 0x1c, 0x22, 0x37, 0x54, 0xcc, + 0x81, 0x3d, 0x0d, 0x58, 0x6c, 0xe2, 0xab, 0xcd, 0x24, 0x1e, 0x0c, 0x7c, 0x9d, 0xb1, 0x98, 0xc5, 0x40, 0x83, 0x1c, + 0x0f, 0x2e, 0xe7, 0xfa, 0x84, 0xd0, 0x0f, 0x23, 0x2a, 0x47, 0x05, 0x3a, 0x07, 0xd1, 0x60, 0x01, 0x78, 0xea, 0xad, + 0x6c, 0x90, 0x64, 0x68, 0xa0, 0x13, 0xd7, 0x9a, 0xa4, 0x3a, 0x9c, 0xd0, 0x3a, 0xd0, 0x71, 0xf5, 0x06, 0x3a, 0x1f, + 0xd7, 0xbd, 0x8f, 0x57, 0xc3, 0x1b, 0x2a, 0xfd, 0x42, 0x0c, 0xbc, 0x7a, 0x3a, 0x0e, 0x2e, 0xe9, 0x56, 0x78, 0xb3, + 0x0a, 0xb7, 0xbf, 0xc8, 0x07, 0x8e, 0x3b, 0x2a, 0x69, 0x08, 0x0c, 0xde, 0x1e, 0xba, 0x9b, 0x19, 0xc7, 0x94, 0xa3, + 0xc3, 0x38, 0x92, 0x43, 0xac, 0x5a, 0x71, 0x21, 0xbd, 0x11, 0x7c, 0xbb, 0x50, 0x8c, 0x65, 0x63, 0x97, 0x86, 0xa2, + 0xf0, 0x67, 0x00, 0x3b, 0xd4, 0xfe, 0x4a, 0x25, 0x1f, 0x23, 0xa3, 0x9a, 0x06, 0x3a, 0x06, 0x60, 0xc9, 0xd2, 0x44, + 0x52, 0x45, 0x1a, 0x89, 0x3f, 0x32, 0x63, 0x1d, 0x35, 0x5d, 0x5f, 0xb0, 0x1c, 0x59, 0x92, 0x6e, 0x67, 0x12, 0xcb, + 0x89, 0x24, 0xb5, 0xdd, 0x47, 0xc4, 0x60, 0xe0, 0x83, 0x8d, 0x98, 0x66, 0x22, 0x1c, 0xf1, 0xa8, 0x44, 0x16, 0x5d, + 0x7e, 0x1b, 0x61, 0xd2, 0xf6, 0x65, 0x45, 0xb6, 0x20, 0x98, 0x9e, 0x44, 0x1f, 0x24, 0x29, 0xa7, 0x22, 0x91, 0x66, + 0x84, 0x00, 0x3f, 0x9e, 0x94, 0x57, 0xfa, 0x73, 0xd0, 0xb4, 0x12, 0xbc, 0x64, 0x90, 0x3c, 0x12, 0x3f, 0x93, 0x82, + 0x59, 0x8c, 0x55, 0x83, 0x01, 0x96, 0x53, 0x3d, 0x71, 0x4c, 0xd2, 0x7f, 0xeb, 0x74, 0xc2, 0x7e, 0xee, 0xe5, 0xb6, + 0x96, 0x37, 0xcd, 0xbd, 0xe7, 0x5e, 0xc5, 0x52, 0x0d, 0xcb, 0xa0, 0xff, 0x9a, 0x68, 0x17, 0x6c, 0x6d, 0x19, 0x13, + 0x56, 0xfd, 0x00, 0xd2, 0x1e, 0xe9, 0xf2, 0xaa, 0x61, 0xce, 0x04, 0x8f, 0x2e, 0xac, 0x79, 0x10, 0x5d, 0x08, 0x1f, + 0xb9, 0xec, 0x26, 0xc9, 0xd5, 0x78, 0xe2, 0x87, 0x83, 0x81, 0x02, 0xa0, 0xa5, 0x75, 0x52, 0x0c, 0xc2, 0x27, 0x42, + 0x0e, 0xa4, 0xd1, 0x51, 0x15, 0x60, 0xb1, 0xcc, 0xae, 0xca, 0x49, 0x36, 0x18, 0xf8, 0x20, 0x36, 0x26, 0x76, 0x43, + 0xb3, 0xb9, 0xcf, 0x4e, 0x14, 0x64, 0xb5, 0x39, 0x6a, 0xcd, 0x74, 0x0b, 0x0c, 0x00, 0x06, 0x11, 0xc1, 0x72, 0x9f, + 0x1a, 0xf9, 0x88, 0x3a, 0x3d, 0x85, 0x11, 0x10, 0xfc, 0x72, 0x22, 0x10, 0xb9, 0x48, 0xa0, 0x1e, 0x60, 0x26, 0xc0, + 0x8c, 0x2a, 0x86, 0x97, 0xc0, 0x2e, 0x9e, 0x9b, 0x57, 0x0c, 0xfa, 0x17, 0x89, 0xd9, 0x89, 0xa6, 0x12, 0x47, 0x63, + 0xe4, 0x54, 0x1a, 0x23, 0x03, 0x62, 0x17, 0xc7, 0xbf, 0xa7, 0xf4, 0x28, 0x48, 0xd9, 0x8b, 0xca, 0x10, 0x87, 0xa3, + 0xf8, 0x0a, 0x56, 0x8d, 0xc3, 0xa1, 0x36, 0xaf, 0xa7, 0xb3, 0x7a, 0x3e, 0x10, 0x01, 0xfc, 0x37, 0x14, 0xec, 0x37, + 0x4d, 0x45, 0x6e, 0x90, 0x3a, 0x0f, 0x87, 0x14, 0xe4, 0x53, 0xdd, 0xe4, 0x9f, 0x2a, 0x77, 0x3f, 0x9d, 0xcd, 0xad, + 0x39, 0x7a, 0x51, 0xe3, 0xba, 0xb5, 0xba, 0xa1, 0x90, 0x68, 0x4d, 0x93, 0xe2, 0xaa, 0x9a, 0x14, 0x03, 0x9e, 0xfb, + 0x42, 0x75, 0xb1, 0x35, 0x82, 0x85, 0x3f, 0xb7, 0x40, 0x98, 0xf4, 0xb7, 0x92, 0x0e, 0xa9, 0x1a, 0x77, 0x6d, 0xb5, + 0xdb, 0x56, 0x36, 0xa4, 0x68, 0x3e, 0xbc, 0x84, 0x5d, 0x3a, 0x45, 0xb4, 0xed, 0x92, 0xe0, 0x0b, 0xd0, 0xb2, 0x7a, + 0x23, 0xf2, 0x98, 0x7e, 0x85, 0xfc, 0x52, 0x0c, 0xff, 0x53, 0xba, 0x37, 0xa7, 0x36, 0xc8, 0x01, 0x6c, 0xf7, 0x1e, + 0x6e, 0xc7, 0xe8, 0x81, 0x0c, 0xde, 0x08, 0x39, 0xe7, 0xfc, 0x72, 0x6a, 0xcd, 0x98, 0x68, 0x58, 0xb0, 0x72, 0x18, + 0xf9, 0x01, 0x32, 0x5e, 0x4e, 0x81, 0x95, 0xfd, 0xa8, 0x88, 0x4b, 0x7f, 0x18, 0xf9, 0x17, 0x4f, 0x83, 0x8c, 0x7b, + 0xd1, 0xb0, 0xe3, 0x0b, 0xb0, 0x57, 0x5f, 0x3c, 0x65, 0xd1, 0x80, 0x57, 0x57, 0xf5, 0x34, 0x0b, 0x86, 0x19, 0x8b, + 0xae, 0x8a, 0x21, 0xf8, 0xd0, 0x3e, 0x2b, 0x07, 0xa1, 0xef, 0x9b, 0x9d, 0x43, 0x77, 0x43, 0x2c, 0x8f, 0xb0, 0x9f, + 0xc0, 0x6d, 0x57, 0x4b, 0xcc, 0x60, 0xb2, 0x59, 0x46, 0xcc, 0x60, 0xcb, 0x5f, 0x3c, 0x35, 0x5c, 0x42, 0xd5, 0x33, + 0xa9, 0xd9, 0x28, 0xd0, 0x9c, 0x5c, 0xa1, 0x39, 0x59, 0x09, 0xb5, 0xe4, 0x93, 0x0a, 0x27, 0xec, 0x7c, 0x92, 0x2b, + 0xbb, 0xd1, 0x18, 0x03, 0x17, 0xad, 0xb9, 0x1d, 0x0a, 0x23, 0x33, 0x9d, 0xa5, 0x68, 0xc0, 0xc2, 0x33, 0x71, 0x4a, + 0x63, 0x40, 0xfb, 0x72, 0x60, 0x69, 0x43, 0x7e, 0x95, 0x33, 0x03, 0x6d, 0x43, 0x4a, 0xa3, 0x66, 0xe0, 0xcf, 0xd4, + 0x84, 0xf9, 0x0c, 0x56, 0x22, 0x88, 0xea, 0x02, 0x4c, 0x92, 0x9c, 0x8c, 0x46, 0xca, 0x4a, 0x24, 0xe7, 0x80, 0xf7, + 0x11, 0x3c, 0x59, 0xc4, 0xb6, 0xf6, 0xa7, 0xf4, 0xbf, 0x3a, 0x7c, 0x2e, 0xfd, 0x27, 0x02, 0x58, 0xc8, 0xa5, 0x41, + 0x64, 0xa0, 0x70, 0x48, 0x2d, 0xc3, 0x7b, 0xe2, 0x78, 0x06, 0xbe, 0x86, 0x0b, 0x34, 0x05, 0xf4, 0x07, 0x35, 0xa3, + 0x88, 0x2c, 0xfc, 0xd5, 0xb3, 0x9b, 0xba, 0xd0, 0xf3, 0xcc, 0x79, 0x0d, 0x9a, 0x19, 0x08, 0xe9, 0x71, 0xaa, 0xde, + 0x86, 0x44, 0xe7, 0xe5, 0xb5, 0x7e, 0x99, 0x10, 0xc9, 0xca, 0xc8, 0xd3, 0xf7, 0x39, 0x98, 0x47, 0x14, 0xa1, 0x83, + 0x2b, 0xf3, 0x70, 0x38, 0x17, 0x14, 0xbe, 0xa3, 0x3c, 0x1f, 0x70, 0x9a, 0x65, 0x09, 0x68, 0x03, 0x59, 0x6e, 0xca, + 0x5c, 0x26, 0x2d, 0x53, 0xf7, 0x1e, 0xac, 0x04, 0x15, 0xba, 0x39, 0x05, 0x85, 0x32, 0x12, 0x94, 0xd2, 0x6a, 0x10, + 0x4a, 0x75, 0x58, 0x04, 0x91, 0x43, 0x16, 0x02, 0x6e, 0xa6, 0xa2, 0xd1, 0x92, 0x86, 0x47, 0x38, 0x37, 0x50, 0x08, + 0x40, 0x62, 0x4f, 0x15, 0x65, 0x5c, 0x0e, 0x01, 0x1f, 0x25, 0x1c, 0xe2, 0xac, 0x49, 0x5b, 0x9e, 0x83, 0x38, 0x96, + 0x0b, 0xbe, 0xac, 0x10, 0x0c, 0x22, 0xf4, 0x19, 0xf2, 0x27, 0xcb, 0xf9, 0x77, 0xeb, 0x30, 0xed, 0x08, 0x1f, 0x76, + 0xb5, 0x1b, 0x2e, 0x66, 0xb7, 0xf3, 0x09, 0xc4, 0xb7, 0xdc, 0xce, 0x8f, 0x31, 0x44, 0x6e, 0xfc, 0xc1, 0x72, 0x28, + 0xb9, 0xa2, 0xd0, 0x65, 0x3d, 0x22, 0x45, 0xf6, 0x74, 0xcd, 0x11, 0x04, 0x07, 0x5a, 0x35, 0xc8, 0xd0, 0x48, 0x7c, + 0xf1, 0x14, 0xb2, 0x06, 0x6b, 0xfe, 0xa2, 0x22, 0x67, 0x75, 0x7f, 0xb2, 0x81, 0x6a, 0x92, 0xc9, 0x5a, 0x51, 0x39, + 0x7f, 0xbb, 0x2a, 0x8b, 0x93, 0x55, 0x19, 0xae, 0x06, 0x5d, 0x55, 0x59, 0x70, 0xa4, 0x36, 0x40, 0x6b, 0xba, 0x42, + 0x0c, 0x85, 0xac, 0xc1, 0xc2, 0xaa, 0xca, 0x9a, 0xfa, 0x04, 0x02, 0x7d, 0x80, 0x65, 0xd4, 0xec, 0xa7, 0xc3, 0x5f, + 0x83, 0x5f, 0x55, 0xc8, 0x52, 0x9d, 0xd6, 0x99, 0xf8, 0x1c, 0x2c, 0x18, 0xfe, 0xf1, 0x7b, 0xb0, 0x06, 0x2c, 0x01, + 0xb2, 0xdc, 0x6d, 0x6c, 0xb4, 0x5e, 0x79, 0x85, 0x78, 0x57, 0xeb, 0x8b, 0x7e, 0xeb, 0x36, 0x51, 0x2b, 0xc0, 0x08, + 0x85, 0x16, 0x01, 0xb6, 0x7a, 0xe0, 0x9e, 0x82, 0x1f, 0x88, 0xe1, 0x5c, 0x93, 0xd6, 0xd4, 0x09, 0xaf, 0xb3, 0x71, + 0x24, 0xa2, 0x7a, 0x0b, 0x17, 0xf7, 0x7a, 0x6b, 0xf1, 0x37, 0x2a, 0x10, 0x00, 0x59, 0x4c, 0xb1, 0x76, 0xde, 0x90, + 0x5e, 0x19, 0x76, 0x12, 0x7a, 0x6f, 0xd8, 0x09, 0xe4, 0xc5, 0x61, 0xa7, 0xd0, 0x25, 0xda, 0x4e, 0x91, 0x9a, 0x68, + 0x3b, 0xe9, 0x66, 0x15, 0x96, 0x10, 0xfc, 0xaa, 0xbd, 0x75, 0x94, 0xed, 0x8b, 0x2c, 0x61, 0xda, 0x02, 0x46, 0xb9, + 0x55, 0x9f, 0x39, 0x45, 0xac, 0x94, 0xbd, 0xd3, 0x49, 0x95, 0xbb, 0xc8, 0xa7, 0x56, 0x53, 0x64, 0xf2, 0x8b, 0xe3, + 0x16, 0xc9, 0x27, 0xbf, 0xb4, 0x1b, 0x26, 0xd3, 0x3f, 0x1e, 0x7d, 0x01, 0x5d, 0x91, 0x9d, 0x3e, 0x81, 0x80, 0x4c, + 0x05, 0xd5, 0xea, 0x56, 0x31, 0xcd, 0xdb, 0x55, 0x76, 0x7b, 0xa1, 0xc4, 0x70, 0x3a, 0x3b, 0x09, 0x8f, 0x36, 0x43, + 0x06, 0x0e, 0x41, 0xa0, 0x10, 0x2a, 0x8a, 0xe1, 0x11, 0xa8, 0x35, 0x92, 0x0f, 0xf0, 0xa3, 0xdd, 0xa9, 0x20, 0x52, + 0xbb, 0xa9, 0xb8, 0x71, 0x72, 0xd3, 0xf5, 0x52, 0xa0, 0xd6, 0x29, 0x59, 0x01, 0x94, 0x10, 0xf5, 0x27, 0xb1, 0xad, + 0x5f, 0xc2, 0x15, 0x9b, 0xef, 0x1b, 0x45, 0x4f, 0xae, 0x4f, 0x51, 0xb7, 0xe2, 0xea, 0x34, 0x6d, 0x35, 0xc7, 0x8e, + 0x33, 0xe4, 0xe0, 0x59, 0x41, 0xb0, 0x1d, 0x95, 0x28, 0xdf, 0xb6, 0x9b, 0x8e, 0x89, 0xad, 0xfe, 0xb9, 0xa9, 0x36, + 0x4b, 0xa8, 0x88, 0x88, 0x8f, 0xb2, 0x9b, 0x27, 0xed, 0x77, 0xb0, 0xc7, 0x5a, 0x0d, 0x22, 0xfb, 0x0c, 0xae, 0x72, + 0x9d, 0x16, 0xb9, 0x2d, 0x83, 0xf3, 0x0f, 0xaf, 0x76, 0x15, 0x36, 0x39, 0xd6, 0xd5, 0xd5, 0x4c, 0x75, 0x52, 0xb1, + 0x81, 0xb1, 0xa6, 0xb5, 0x54, 0xf3, 0x18, 0x92, 0xee, 0xca, 0xe2, 0xac, 0x4a, 0xba, 0xe9, 0xb9, 0x71, 0xa6, 0x10, + 0x03, 0x67, 0xab, 0xd1, 0x72, 0x86, 0x21, 0xba, 0x3e, 0xcc, 0x12, 0xbf, 0xd5, 0x53, 0xee, 0xf3, 0x70, 0xeb, 0x77, + 0xf5, 0x82, 0x93, 0xc9, 0x7e, 0x72, 0x9c, 0xbb, 0x5d, 0xa4, 0xfd, 0xc4, 0xb7, 0x61, 0xfe, 0xf5, 0x0d, 0x62, 0x29, + 0xea, 0x5f, 0x2b, 0x00, 0x1a, 0xdc, 0xe4, 0xb1, 0x44, 0xa9, 0xdf, 0xab, 0xea, 0x07, 0x35, 0x53, 0x35, 0x0d, 0x04, + 0x73, 0x2a, 0x05, 0xfc, 0xe1, 0x76, 0xe1, 0x8a, 0x47, 0xdc, 0xb0, 0x30, 0xfe, 0xe5, 0xd5, 0xec, 0x54, 0x50, 0x19, + 0xb8, 0x19, 0xff, 0xe5, 0x09, 0x76, 0x0a, 0x6b, 0x05, 0x64, 0x85, 0xbf, 0xbc, 0xfc, 0x81, 0xf7, 0x2b, 0xfe, 0x97, + 0x57, 0x3d, 0xf0, 0x3e, 0xe2, 0xbc, 0xfc, 0x85, 0xa4, 0x4e, 0x88, 0xea, 0xf2, 0x17, 0x61, 0x8a, 0xad, 0xd2, 0xfc, + 0x15, 0x29, 0x7c, 0x82, 0x2f, 0xc0, 0x77, 0xb8, 0x0a, 0xb7, 0xe6, 0x37, 0x78, 0xec, 0x58, 0x6c, 0xbb, 0xd4, 0x17, + 0x50, 0x8e, 0xc0, 0x22, 0x72, 0xfb, 0xed, 0xca, 0x7e, 0xb5, 0x30, 0xca, 0x18, 0xbb, 0x2f, 0x59, 0x89, 0xd2, 0x59, + 0xbf, 0x5f, 0x48, 0xc1, 0xc8, 0x2e, 0xac, 0xd1, 0x1e, 0xa5, 0xea, 0xd5, 0xb7, 0x61, 0x1d, 0x25, 0x69, 0xbe, 0x94, + 0xd1, 0x47, 0x32, 0xec, 0x48, 0x5f, 0x49, 0x89, 0xf6, 0x5a, 0x85, 0xe5, 0x68, 0xf6, 0xeb, 0x92, 0x03, 0xe5, 0x75, + 0x2b, 0x28, 0x5f, 0x35, 0x01, 0xf4, 0x4a, 0xb5, 0xcf, 0x40, 0x2b, 0x28, 0x2c, 0x95, 0x07, 0x2b, 0x71, 0x2e, 0xfa, + 0xac, 0x38, 0x1c, 0xd4, 0xc5, 0x90, 0x50, 0xa0, 0x4a, 0x9c, 0x84, 0x46, 0x3c, 0x87, 0x0b, 0xa1, 0x78, 0x96, 0x63, + 0x6c, 0x45, 0x0e, 0x1c, 0xc8, 0xf0, 0x03, 0x02, 0xef, 0x65, 0xff, 0x0a, 0x06, 0xc3, 0x04, 0x37, 0x32, 0xea, 0xe4, + 0x9c, 0xfd, 0x85, 0x81, 0x19, 0xd4, 0x93, 0xda, 0x7d, 0x76, 0xaf, 0x02, 0x7b, 0xe1, 0x0c, 0x68, 0xef, 0xc6, 0xe8, + 0x67, 0x55, 0xac, 0x9d, 0xf4, 0x4f, 0xc5, 0x1a, 0x92, 0xe9, 0xb0, 0x38, 0xda, 0xa6, 0xe1, 0x91, 0x3c, 0x39, 0x8e, + 0x37, 0xfd, 0xc3, 0x61, 0x8c, 0x1f, 0x47, 0xf9, 0xb5, 0x05, 0xbc, 0x8a, 0x5b, 0x48, 0x63, 0x91, 0xa2, 0x77, 0x20, + 0xe6, 0x50, 0xf4, 0x92, 0xfd, 0x96, 0xf1, 0x72, 0x22, 0x28, 0x25, 0x89, 0x0d, 0xef, 0x48, 0x4f, 0xd3, 0x7a, 0xb4, + 0x95, 0x01, 0xfb, 0xf5, 0x68, 0x47, 0x7f, 0x81, 0xe2, 0xd1, 0xc2, 0x5f, 0xd2, 0xdf, 0xc5, 0xdd, 0xdc, 0x73, 0xbe, + 0x69, 0x7c, 0x47, 0x5c, 0xa0, 0x58, 0xb3, 0xfb, 0x6b, 0x5a, 0x3a, 0xeb, 0x40, 0x70, 0xc0, 0x5b, 0xec, 0xa2, 0x7d, + 0xbf, 0x71, 0x9d, 0x9e, 0xf6, 0xdf, 0xbb, 0x35, 0xca, 0xf7, 0x7e, 0x95, 0x28, 0x07, 0xfb, 0x37, 0x2e, 0x9a, 0xbf, + 0xfd, 0x94, 0x21, 0xa9, 0xd0, 0xdc, 0x60, 0x3b, 0xd9, 0x22, 0xac, 0x8d, 0x71, 0x50, 0xb1, 0x65, 0x19, 0x46, 0xc0, + 0xa0, 0x8e, 0xfd, 0x8f, 0x3e, 0x9b, 0x36, 0x64, 0x1f, 0x00, 0x2a, 0x57, 0x21, 0x60, 0x0f, 0xc0, 0x89, 0x46, 0xb8, + 0x01, 0x6e, 0x35, 0x5a, 0xd2, 0x41, 0xdd, 0x16, 0x0c, 0x44, 0x4b, 0xd8, 0xc8, 0xdb, 0xae, 0x4e, 0xdf, 0x10, 0x3e, + 0xd4, 0x4e, 0x4a, 0x87, 0xf2, 0x37, 0xcf, 0xd9, 0x7f, 0xef, 0xb0, 0xa6, 0xa6, 0x5c, 0x03, 0x66, 0xce, 0x4a, 0xe4, + 0x15, 0x42, 0xa7, 0xc8, 0xef, 0x55, 0x5d, 0x89, 0xe1, 0xa2, 0x16, 0x65, 0x67, 0x76, 0xeb, 0x44, 0xef, 0x9c, 0x82, + 0x5a, 0x2a, 0x1b, 0xe4, 0x24, 0xd5, 0xe6, 0x23, 0x6b, 0x05, 0x25, 0xea, 0x1a, 0x05, 0x8e, 0x4f, 0xb9, 0x76, 0xff, + 0xef, 0x9c, 0x09, 0x6a, 0xb6, 0x51, 0xdd, 0x5f, 0xe9, 0xa7, 0xaa, 0x26, 0xb1, 0x00, 0x97, 0x93, 0x34, 0xef, 0x78, + 0x84, 0xd5, 0x3f, 0x4e, 0x96, 0x22, 0xd0, 0xab, 0x88, 0x76, 0x25, 0x20, 0x41, 0x3b, 0x39, 0x0b, 0x15, 0x81, 0x02, + 0x7d, 0xfd, 0xc5, 0x26, 0xcd, 0x62, 0xb9, 0x9a, 0xed, 0x61, 0xa2, 0x2c, 0xd6, 0x43, 0x04, 0x39, 0x33, 0x75, 0xb0, + 0xdf, 0xd3, 0x8c, 0x66, 0xe1, 0x95, 0x29, 0xc1, 0xa5, 0xb8, 0x8a, 0x8a, 0x1c, 0x7c, 0x0e, 0xf1, 0x85, 0x4f, 0x85, + 0xdc, 0x20, 0xa2, 0xe9, 0x4f, 0x12, 0xd5, 0x8e, 0x14, 0xc8, 0xa1, 0xe4, 0x27, 0xc4, 0x5f, 0xb2, 0x36, 0xc6, 0xfd, + 0xd2, 0xa9, 0xf6, 0x4b, 0x85, 0xe0, 0xfe, 0x8b, 0x2d, 0x36, 0xaa, 0x3c, 0xd1, 0x83, 0x4f, 0xb1, 0xfe, 0x27, 0x0b, + 0x28, 0xd5, 0x7d, 0x1b, 0x9c, 0x8a, 0x47, 0xe1, 0xa6, 0x2e, 0xae, 0x11, 0x5a, 0xa0, 0x1c, 0x55, 0xc5, 0xa6, 0x8c, + 0x88, 0x13, 0x76, 0x53, 0x17, 0x3d, 0xcd, 0x81, 0x2e, 0xe7, 0x75, 0x22, 0x4f, 0x84, 0x76, 0x0b, 0xba, 0xa7, 0x39, + 0x56, 0xe2, 0xb9, 0x2c, 0x1d, 0x64, 0x9d, 0x48, 0x13, 0x2a, 0x77, 0x75, 0xd5, 0x51, 0xa9, 0xd4, 0x0d, 0xaf, 0x53, + 0xcd, 0xf8, 0xbb, 0x30, 0x7f, 0x62, 0xd9, 0xaf, 0x5b, 0xbf, 0xd5, 0x6a, 0x6f, 0xac, 0x1e, 0x95, 0xac, 0x39, 0xce, + 0x26, 0x24, 0xa5, 0x4f, 0xd8, 0x6e, 0x26, 0x5d, 0xeb, 0xc0, 0x93, 0xe0, 0x72, 0xe8, 0x09, 0xa8, 0x18, 0x34, 0xf1, + 0x76, 0x17, 0xa8, 0x47, 0xe0, 0x19, 0x28, 0x9f, 0xa8, 0x75, 0xc0, 0xcf, 0x6b, 0x2d, 0x4f, 0x19, 0x61, 0x58, 0xed, + 0x2c, 0x5a, 0x0e, 0xce, 0x3b, 0x45, 0xe0, 0xda, 0x95, 0xc0, 0xf3, 0xa1, 0x7a, 0x2f, 0x04, 0x0c, 0xf7, 0x4f, 0x85, + 0xca, 0x66, 0x37, 0xc3, 0x79, 0xd4, 0x38, 0x3d, 0xd0, 0xde, 0x76, 0xad, 0x87, 0x7a, 0xd7, 0xed, 0xdc, 0x56, 0xba, + 0xf7, 0x6b, 0x27, 0x93, 0x2e, 0xa0, 0xb5, 0xf9, 0xec, 0x3b, 0xbb, 0xd2, 0xba, 0xe9, 0x39, 0x7b, 0xb0, 0x75, 0x4b, + 0x74, 0x2e, 0x88, 0x26, 0xbf, 0x1f, 0x78, 0xd6, 0xb6, 0xa3, 0xdf, 0xa6, 0x1d, 0xdb, 0xdc, 0x43, 0xdd, 0x2b, 0xa8, + 0xf5, 0x86, 0xe6, 0xfd, 0x33, 0xd7, 0xb6, 0xe3, 0xab, 0x5f, 0xd7, 0x1d, 0xae, 0xf3, 0x26, 0x38, 0x6e, 0xba, 0xb6, + 0xd5, 0xce, 0x7e, 0xee, 0xee, 0xad, 0x9b, 0x28, 0xcc, 0xb2, 0x9f, 0x8a, 0xe2, 0xcf, 0x4a, 0xdf, 0x11, 0xe8, 0xe8, + 0xce, 0x8b, 0x3a, 0x5d, 0xec, 0x3e, 0x10, 0xc6, 0x93, 0x57, 0x1f, 0x11, 0xdd, 0xfa, 0x3e, 0x73, 0xbf, 0x02, 0xdc, + 0x08, 0xee, 0x20, 0xda, 0xbb, 0xa5, 0x3e, 0xa9, 0xd5, 0xd7, 0x7a, 0xed, 0x3c, 0x3d, 0xbf, 0xe9, 0xdc, 0x7e, 0xf7, + 0xcd, 0xd1, 0xd6, 0x7b, 0x5c, 0x58, 0x2b, 0x4b, 0x4f, 0x55, 0xc1, 0xde, 0x2c, 0x4f, 0x55, 0xc1, 0xe4, 0x81, 0xd7, + 0xec, 0x17, 0x34, 0xb8, 0xd2, 0xd1, 0xc6, 0x7b, 0xa2, 0x06, 0x6e, 0x51, 0x58, 0x3a, 0xfc, 0x92, 0x9b, 0xc9, 0x4b, + 0xdc, 0x5f, 0x2a, 0x72, 0xb1, 0xef, 0x9c, 0xd1, 0x9d, 0x99, 0x75, 0xaf, 0x2a, 0x5c, 0x2d, 0xc8, 0xd5, 0x81, 0xad, + 0x65, 0x17, 0x87, 0x1b, 0x16, 0x51, 0x80, 0x40, 0x4c, 0xaf, 0xd4, 0xda, 0x1f, 0xd1, 0x20, 0xe4, 0x83, 0x81, 0x5f, + 0x60, 0xb0, 0x2a, 0x50, 0xf8, 0x40, 0x91, 0xfc, 0x8d, 0x27, 0x60, 0x17, 0xcf, 0x00, 0xdd, 0x8a, 0xcd, 0x8a, 0x11, + 0x22, 0x64, 0xb2, 0x9c, 0xd5, 0x74, 0x06, 0xf9, 0xd4, 0x17, 0xdf, 0xd9, 0xaa, 0xd3, 0x79, 0x5b, 0x53, 0xe5, 0xd4, + 0xa1, 0xd0, 0xdd, 0x4d, 0xdd, 0xb9, 0x75, 0x91, 0xa7, 0x0e, 0x21, 0x57, 0x2a, 0x56, 0x62, 0x1a, 0x6a, 0x9e, 0xa4, + 0x19, 0xf5, 0x37, 0x7b, 0xbf, 0xd7, 0x28, 0x9c, 0xf2, 0xa7, 0x63, 0x50, 0x85, 0xab, 0x1a, 0xe2, 0x58, 0xaa, 0xe2, + 0x91, 0x0d, 0x02, 0xcd, 0xab, 0x5b, 0x95, 0x34, 0x21, 0x93, 0x1b, 0xe1, 0x53, 0x93, 0x52, 0x9e, 0xa6, 0x4d, 0x5a, + 0x29, 0x52, 0x07, 0x1f, 0xd4, 0xa9, 0xc6, 0x73, 0xb3, 0x7a, 0x06, 0x60, 0xc6, 0xf9, 0x15, 0xbf, 0x54, 0x5c, 0x46, + 0x6d, 0x65, 0x26, 0xed, 0x4f, 0x8e, 0xc6, 0x46, 0x5d, 0x4e, 0x1b, 0x65, 0x84, 0x95, 0xd2, 0x9c, 0x14, 0xcb, 0xf1, + 0xfc, 0x03, 0x06, 0x6b, 0x9e, 0xc0, 0x0e, 0x26, 0x2a, 0xe5, 0x7d, 0x04, 0xc4, 0xd7, 0x49, 0xba, 0x4c, 0x20, 0x45, + 0xfa, 0x97, 0x2e, 0x78, 0xea, 0x30, 0x36, 0x10, 0x63, 0x56, 0xcc, 0x8c, 0xfe, 0x07, 0x77, 0x49, 0x7f, 0x12, 0x02, + 0xe0, 0x26, 0x9a, 0x42, 0xa7, 0xce, 0x93, 0x8b, 0x3c, 0x58, 0x5c, 0x78, 0x68, 0xc5, 0x88, 0x07, 0xff, 0xf9, 0x2c, + 0x44, 0x10, 0x73, 0x4c, 0xf1, 0xf4, 0x0b, 0xa3, 0xff, 0x08, 0x2e, 0x31, 0x82, 0xd0, 0xdd, 0x3b, 0x87, 0x21, 0xdc, + 0xec, 0x41, 0x06, 0xf5, 0x87, 0x3a, 0x24, 0x6a, 0xf8, 0x6b, 0xe5, 0x41, 0xff, 0xd7, 0x99, 0xb0, 0xd4, 0x7e, 0x7a, + 0x3a, 0x80, 0x0a, 0xde, 0x57, 0xbc, 0x8d, 0x88, 0xef, 0x13, 0x3f, 0x89, 0x07, 0x9b, 0x27, 0x1b, 0xb0, 0xd6, 0x3d, + 0xca, 0x8d, 0x75, 0x95, 0xb0, 0x81, 0x80, 0xaf, 0x31, 0xad, 0x3d, 0xaf, 0xdd, 0xee, 0xc1, 0x7f, 0xfa, 0x17, 0x21, + 0x03, 0x26, 0x4e, 0xdf, 0x67, 0x4e, 0xd6, 0xe8, 0x22, 0x93, 0xe9, 0x43, 0x27, 0x7d, 0xa3, 0xd3, 0x7d, 0x27, 0xfc, + 0xa3, 0x62, 0x16, 0x1f, 0x6e, 0xe9, 0x2b, 0x4d, 0x8a, 0x3b, 0x60, 0x65, 0xf3, 0xa0, 0x20, 0xd4, 0xb9, 0x88, 0xbe, + 0x31, 0xe5, 0x5b, 0x42, 0xcd, 0xbe, 0xb1, 0xa4, 0x94, 0xee, 0x35, 0xf4, 0x3a, 0xad, 0xf5, 0xdb, 0x28, 0xc1, 0x98, + 0xe8, 0x78, 0xf2, 0x32, 0x1e, 0x2b, 0xef, 0xe3, 0x71, 0x23, 0x15, 0xf2, 0x00, 0x44, 0xa0, 0x62, 0xfc, 0xe9, 0xca, + 0x93, 0x93, 0x5e, 0x18, 0xaf, 0x42, 0x29, 0x28, 0x0c, 0xe8, 0x0a, 0xa4, 0x80, 0x47, 0xed, 0x89, 0xce, 0xc2, 0x2e, + 0xe1, 0x1e, 0xdd, 0x04, 0x8c, 0xf5, 0xf9, 0x57, 0x40, 0x73, 0x17, 0xee, 0xf0, 0x62, 0x80, 0xda, 0xd4, 0xab, 0xbb, + 0x8f, 0x6b, 0x75, 0x0e, 0x87, 0xe0, 0x60, 0x35, 0x88, 0xe0, 0x74, 0x3e, 0x75, 0x34, 0xcb, 0x02, 0x54, 0x4e, 0x96, + 0x1b, 0x79, 0xf3, 0x68, 0xd1, 0xab, 0xfb, 0xde, 0x22, 0x2d, 0xab, 0x3a, 0xc8, 0x58, 0x16, 0x56, 0x80, 0xab, 0x43, + 0xeb, 0x07, 0xe1, 0xb2, 0x70, 0xfe, 0x40, 0x08, 0x62, 0xf7, 0x6a, 0x5b, 0xf0, 0x5c, 0xcd, 0xe1, 0x27, 0x4f, 0xd9, + 0x9a, 0x4b, 0xd4, 0x49, 0x67, 0x22, 0x00, 0xb1, 0xa7, 0x66, 0x15, 0x5d, 0x03, 0x49, 0x9d, 0x66, 0x15, 0x5d, 0x53, + 0xb3, 0x8d, 0x71, 0x20, 0x1f, 0xad, 0x52, 0xc0, 0xbe, 0x9b, 0x8e, 0x83, 0xd5, 0x93, 0x58, 0x5e, 0x87, 0x96, 0x4f, + 0x36, 0xca, 0x67, 0x50, 0xb7, 0xda, 0x18, 0x13, 0xdb, 0xcd, 0x97, 0x73, 0xfd, 0x76, 0xb0, 0xf0, 0xed, 0xa0, 0x39, + 0xa7, 0xec, 0xa5, 0x2e, 0x7b, 0x65, 0x97, 0x4d, 0x3d, 0x77, 0x54, 0xb4, 0x1a, 0x03, 0x7a, 0x03, 0x0b, 0xd6, 0xe7, + 0x22, 0xcd, 0x56, 0xa5, 0x2a, 0x01, 0x2f, 0x8c, 0x15, 0x5b, 0xfa, 0x8d, 0xcc, 0x90, 0x84, 0x79, 0x9c, 0x89, 0xb7, + 0x74, 0xaf, 0x85, 0xc9, 0x71, 0x2c, 0x92, 0x29, 0xa1, 0x53, 0xba, 0xb3, 0x0d, 0x9d, 0xab, 0x30, 0x8a, 0x68, 0xad, + 0xa4, 0xd2, 0x48, 0x60, 0x6a, 0x06, 0x28, 0x99, 0x2b, 0x70, 0x4a, 0x97, 0xfb, 0xdf, 0x91, 0x18, 0x67, 0xbe, 0x28, + 0x99, 0x01, 0xdd, 0xf2, 0xeb, 0x62, 0xdd, 0x4a, 0x91, 0x11, 0xe6, 0xcd, 0x71, 0x7b, 0x5d, 0x1f, 0x02, 0xb9, 0x5a, + 0xf6, 0x28, 0x1a, 0x07, 0x85, 0x0e, 0x97, 0x2a, 0x01, 0xf6, 0x45, 0xe2, 0x67, 0x84, 0x2d, 0xed, 0x81, 0xdc, 0x1e, + 0x9d, 0x09, 0x73, 0xce, 0x49, 0x59, 0x76, 0x2e, 0xcd, 0xe0, 0x72, 0xe2, 0x4a, 0x70, 0x91, 0xde, 0xb6, 0xa7, 0x49, + 0x4b, 0xdb, 0xc7, 0x86, 0x73, 0x34, 0xb4, 0x0d, 0xba, 0x63, 0x7f, 0x68, 0x2e, 0x16, 0xb1, 0x75, 0xb1, 0x18, 0x76, + 0x66, 0x3f, 0x5a, 0x2c, 0x40, 0x0e, 0x00, 0x47, 0xdd, 0x86, 0x8f, 0xd9, 0x02, 0x38, 0xad, 0xa6, 0xd9, 0xd4, 0xdb, + 0xf0, 0xea, 0x89, 0xea, 0xe9, 0x05, 0xcf, 0x9f, 0x08, 0x33, 0x16, 0x1b, 0x9e, 0x3f, 0xb1, 0x8e, 0x9c, 0xea, 0x89, + 0x50, 0xa2, 0x75, 0x01, 0xcd, 0xc0, 0x6b, 0x0a, 0x18, 0xb1, 0x64, 0x32, 0xa5, 0x8a, 0x3c, 0xee, 0x4d, 0x37, 0x6a, + 0xf0, 0x82, 0xc2, 0x21, 0x90, 0xd2, 0xe9, 0x17, 0x4f, 0x99, 0x7e, 0xef, 0xe2, 0x69, 0x87, 0xac, 0x6d, 0x98, 0x2e, + 0x37, 0xc3, 0x64, 0x50, 0xfa, 0x4f, 0xcc, 0xc4, 0xb8, 0xb0, 0x26, 0x09, 0x20, 0xfe, 0x8d, 0xfd, 0x0e, 0x29, 0xdc, + 0xbc, 0xbf, 0x18, 0xc6, 0x0f, 0xbc, 0x1f, 0x23, 0x7b, 0x92, 0x66, 0x88, 0x35, 0x93, 0x0a, 0xb9, 0xfb, 0x6a, 0xfd, + 0x63, 0x62, 0x37, 0xd9, 0x03, 0x0b, 0x40, 0x6c, 0x4d, 0x5b, 0xdd, 0xf2, 0x7e, 0xdf, 0x33, 0x45, 0x80, 0x1f, 0x94, + 0x7f, 0x74, 0x67, 0x48, 0x06, 0x65, 0xd7, 0x0d, 0x21, 0x1e, 0x94, 0x4d, 0xd3, 0x5e, 0x6f, 0x7b, 0x67, 0x1e, 0xab, + 0xeb, 0xb4, 0xb3, 0xb8, 0x5a, 0x64, 0x90, 0x56, 0x1f, 0xb2, 0xe3, 0xcc, 0x3e, 0x3b, 0x5a, 0x2a, 0xdd, 0xef, 0x43, + 0x44, 0xdc, 0x51, 0xd6, 0xf6, 0xdb, 0x2d, 0xb8, 0x86, 0xa3, 0x41, 0xe8, 0xca, 0xde, 0x2e, 0xa3, 0x8d, 0x0b, 0x71, + 0xdc, 0x33, 0x9d, 0x2f, 0xf8, 0xf2, 0x28, 0xed, 0x3c, 0x38, 0xd5, 0x13, 0x7d, 0x6e, 0xba, 0xab, 0x4c, 0xae, 0x75, + 0x58, 0x8d, 0x41, 0x6d, 0x16, 0xb6, 0x70, 0x17, 0xb6, 0xd1, 0x41, 0x6b, 0x5f, 0x16, 0xfc, 0x53, 0x06, 0xe0, 0x4b, + 0xcf, 0x96, 0x6d, 0xaf, 0x49, 0xab, 0xd7, 0x32, 0x0a, 0xb1, 0xa5, 0xed, 0xd5, 0xa7, 0xa3, 0x7c, 0xdc, 0x9c, 0x50, + 0x5c, 0xc8, 0x51, 0x7e, 0xf0, 0x1a, 0xa2, 0xae, 0x75, 0x1d, 0x17, 0x8b, 0x0e, 0x37, 0xae, 0xba, 0xed, 0xc6, 0xf5, + 0x23, 0xe2, 0xad, 0xd1, 0x26, 0x85, 0x5a, 0x19, 0x3b, 0x82, 0x97, 0xe5, 0xc3, 0x21, 0x13, 0xc3, 0xa1, 0x84, 0x4c, + 0x7d, 0xe8, 0xde, 0xd0, 0xb4, 0xcf, 0x4f, 0x5b, 0x3f, 0x62, 0xa9, 0x71, 0x14, 0x1b, 0xde, 0xe9, 0x3b, 0x8f, 0xad, + 0x71, 0x25, 0x5f, 0x06, 0xb3, 0x5d, 0x41, 0xb5, 0x35, 0xde, 0xb0, 0x97, 0xf3, 0x9f, 0x2a, 0xa9, 0xe4, 0x6f, 0x7f, + 0x86, 0x6b, 0x78, 0x6b, 0x4b, 0x07, 0x4d, 0x35, 0xcb, 0x59, 0xae, 0xef, 0x05, 0xc7, 0x1f, 0x77, 0xaf, 0x08, 0x06, + 0xbf, 0xa7, 0xa3, 0x20, 0x17, 0x4b, 0xb5, 0x06, 0x14, 0xa4, 0x23, 0x3b, 0xa6, 0xb2, 0xc0, 0x30, 0x80, 0x37, 0x64, + 0x80, 0x3c, 0xa6, 0x70, 0x37, 0x54, 0x78, 0xe1, 0x6f, 0x15, 0xd9, 0x25, 0xb0, 0xad, 0x19, 0x1f, 0x33, 0xdc, 0x41, + 0xc8, 0x3f, 0x82, 0x2d, 0xd9, 0x8a, 0xdd, 0xb2, 0x1b, 0x86, 0x64, 0xe3, 0x38, 0x8c, 0x31, 0x1f, 0x4f, 0xe2, 0x2b, + 0x31, 0x89, 0x07, 0x3c, 0x42, 0xc7, 0x88, 0x35, 0xaf, 0x67, 0xb1, 0x1c, 0x40, 0xb6, 0xe4, 0x4a, 0x07, 0x84, 0xd0, + 0xd8, 0xd0, 0x92, 0xd7, 0x85, 0xc1, 0xc5, 0x8e, 0x7d, 0x46, 0x22, 0x19, 0x87, 0x60, 0xd1, 0xaa, 0x06, 0x16, 0x26, + 0x76, 0xcb, 0x8b, 0xd9, 0x6a, 0x8e, 0xff, 0x1c, 0x0e, 0x08, 0x80, 0x1d, 0xec, 0x1b, 0xb6, 0x8c, 0x10, 0xe9, 0xed, + 0x86, 0x2f, 0x2d, 0x4f, 0x17, 0x76, 0xc7, 0xdf, 0xf2, 0x31, 0x3b, 0xff, 0xd1, 0x83, 0xc8, 0xd9, 0xf3, 0x8f, 0x80, + 0x86, 0x78, 0xc7, 0x6f, 0x53, 0xaf, 0x62, 0xb7, 0x44, 0x41, 0x78, 0x0b, 0xce, 0x40, 0x77, 0x10, 0x01, 0xfb, 0x96, + 0xdf, 0x60, 0xac, 0xd8, 0x59, 0xba, 0xf0, 0x30, 0x23, 0xd4, 0x9e, 0xce, 0x97, 0xb5, 0x9a, 0x84, 0x9b, 0xab, 0xc5, + 0x64, 0x30, 0xd8, 0xf8, 0x3b, 0xbe, 0x06, 0x3e, 0x98, 0xf3, 0x1f, 0xbd, 0x1d, 0x95, 0x0b, 0xff, 0x79, 0x9d, 0x25, + 0xef, 0x7c, 0xf6, 0x76, 0xc0, 0x6f, 0x00, 0x6f, 0x09, 0x1d, 0xb8, 0xee, 0x7c, 0x26, 0xf1, 0xda, 0xde, 0xea, 0x6b, + 0x04, 0x12, 0xf9, 0x02, 0x30, 0x62, 0x62, 0x7e, 0xbf, 0x85, 0x08, 0x8c, 0x18, 0x7c, 0x5b, 0xb5, 0x47, 0xfc, 0x96, + 0x1b, 0xc0, 0xaf, 0xcc, 0x67, 0xf7, 0x3c, 0xd4, 0x3f, 0x13, 0x9f, 0x5d, 0xf3, 0xf7, 0xfc, 0x99, 0x27, 0x25, 0xe9, + 0x72, 0xf6, 0x7e, 0x0e, 0xd7, 0x43, 0x29, 0x4f, 0x87, 0xf4, 0xb3, 0x31, 0x18, 0x40, 0x28, 0x64, 0x5e, 0x7b, 0xc0, + 0x9a, 0x14, 0xe2, 0x5f, 0xc0, 0xb7, 0xa3, 0x84, 0xcd, 0x6b, 0x6f, 0xeb, 0x6b, 0x79, 0xf3, 0xda, 0xbb, 0xf7, 0x29, + 0x0a, 0xb0, 0x0a, 0x4a, 0x59, 0x60, 0x15, 0x84, 0x8d, 0x36, 0xc2, 0x18, 0xb8, 0x7a, 0xd7, 0x18, 0xea, 0x7a, 0x8e, + 0xd8, 0xb6, 0xd2, 0x77, 0xe1, 0x3b, 0xc8, 0x80, 0x0f, 0x5e, 0x17, 0x25, 0xd1, 0xe7, 0xd4, 0x14, 0x49, 0xeb, 0x9e, + 0xfb, 0xad, 0x75, 0x47, 0x6b, 0x4a, 0x7d, 0xe4, 0x6a, 0x7c, 0x38, 0xd4, 0xcf, 0x84, 0x16, 0x09, 0xa6, 0xa0, 0x71, + 0x0d, 0xda, 0x02, 0x04, 0x7d, 0x1e, 0x20, 0x6b, 0x49, 0xb1, 0xe0, 0xdb, 0x5f, 0x21, 0x06, 0xaf, 0x4c, 0xef, 0x5c, + 0xae, 0x32, 0x12, 0xb6, 0x17, 0x7e, 0x39, 0xac, 0xfd, 0x89, 0x53, 0x0b, 0x4b, 0xab, 0x39, 0xa8, 0x9f, 0xd8, 0x72, + 0x9c, 0xaa, 0xda, 0xdf, 0x25, 0x49, 0xb5, 0xab, 0xb4, 0x9c, 0xde, 0xd9, 0x37, 0x5d, 0x26, 0xd8, 0xd8, 0x0f, 0xa8, + 0x3a, 0xb2, 0x1a, 0x76, 0x5f, 0xa8, 0x2f, 0x7a, 0x4a, 0x26, 0x34, 0x1f, 0x55, 0x34, 0xcf, 0xee, 0x37, 0x3b, 0xea, + 0x3f, 0xbd, 0x1c, 0x8a, 0x00, 0xc9, 0x2a, 0x2d, 0x96, 0x22, 0x67, 0x63, 0x3f, 0x1e, 0x26, 0x99, 0x0a, 0x2f, 0x48, + 0x47, 0x77, 0xbf, 0x71, 0x7f, 0xcb, 0x0d, 0x64, 0x85, 0x56, 0x6d, 0x30, 0x56, 0x8a, 0x96, 0xc1, 0xfa, 0x6a, 0xdc, + 0xef, 0x8b, 0xab, 0xf1, 0x54, 0x04, 0x35, 0x10, 0x17, 0x89, 0x67, 0xe3, 0x69, 0x4d, 0x2c, 0xa9, 0x5d, 0x81, 0x31, + 0x7a, 0x5c, 0x15, 0xb5, 0x4f, 0xfd, 0x0c, 0x42, 0x91, 0x6a, 0xcd, 0x1c, 0x6b, 0xdc, 0x18, 0x11, 0x77, 0x58, 0xb9, + 0x76, 0x6a, 0xaf, 0x03, 0xb0, 0xbc, 0x1a, 0x17, 0x84, 0x45, 0x72, 0xec, 0x5c, 0xc0, 0x6a, 0x34, 0xa4, 0xda, 0x0d, + 0xb7, 0x5e, 0x76, 0x7e, 0xf3, 0x4d, 0x62, 0x6b, 0x23, 0xdc, 0x52, 0x40, 0x19, 0xe5, 0x37, 0x96, 0x13, 0x76, 0xa7, + 0x7a, 0x47, 0xaa, 0x76, 0xc4, 0x89, 0x0b, 0x58, 0x6e, 0x78, 0x6a, 0xf5, 0x4d, 0x0c, 0x4e, 0x84, 0xaa, 0x95, 0x0e, + 0x77, 0x32, 0x81, 0xb8, 0x5f, 0xdd, 0xd7, 0xbd, 0x12, 0xfc, 0x24, 0xe4, 0xf5, 0x5b, 0xde, 0x01, 0x60, 0xc5, 0x87, + 0xbc, 0x98, 0x16, 0x8e, 0xd6, 0x65, 0x50, 0x06, 0x88, 0xd0, 0x0c, 0x80, 0x4e, 0xae, 0x0e, 0xa2, 0x34, 0x70, 0xc5, + 0x1d, 0x22, 0xfc, 0x34, 0x7a, 0x92, 0x3f, 0x0b, 0x9f, 0x54, 0xd3, 0xf0, 0x22, 0x0f, 0xa2, 0x8b, 0x2a, 0x88, 0x9e, + 0x54, 0x57, 0xe1, 0x93, 0x7c, 0x1a, 0x5d, 0xe4, 0x41, 0x78, 0x51, 0x35, 0xf6, 0x5d, 0xbb, 0xbb, 0x27, 0xe4, 0x6d, + 0x57, 0x7f, 0xe4, 0x5c, 0xd9, 0x53, 0xa6, 0xe7, 0xe7, 0xb5, 0x5e, 0xa9, 0xdd, 0xe6, 0x7a, 0x8d, 0x9a, 0xa9, 0x8f, + 0xb2, 0xbf, 0xd9, 0xc6, 0xc2, 0xa3, 0x39, 0x84, 0x3e, 0x23, 0x2d, 0xe6, 0x1e, 0xe7, 0x7a, 0xb3, 0x27, 0x85, 0x81, + 0x11, 0x93, 0x4a, 0x46, 0x4e, 0x2f, 0x70, 0x11, 0xaa, 0x10, 0xc3, 0x5a, 0xba, 0xda, 0x67, 0x5d, 0x7a, 0x03, 0x75, + 0x4d, 0xb1, 0xaf, 0x21, 0x03, 0x2f, 0x9a, 0x5e, 0x06, 0x63, 0x40, 0x8e, 0xc0, 0x3b, 0x3e, 0x5b, 0xc0, 0x81, 0xb9, + 0x06, 0xe8, 0x9b, 0x07, 0x7d, 0x5d, 0x96, 0x7c, 0xad, 0xfa, 0x66, 0xba, 0x1e, 0x29, 0xe5, 0xc7, 0x8a, 0x2f, 0x2f, + 0x9e, 0xb2, 0x5b, 0xae, 0x51, 0x51, 0x5e, 0xe8, 0xc5, 0x7a, 0x07, 0x5c, 0x75, 0x2f, 0xe0, 0x36, 0x8b, 0xc7, 0xae, + 0x3c, 0x60, 0xd9, 0x96, 0xdd, 0xb3, 0x6b, 0xf6, 0x9e, 0x3d, 0x62, 0xaf, 0xd8, 0x57, 0x56, 0x23, 0x44, 0x79, 0xa9, + 0xa4, 0x3c, 0xff, 0x86, 0xdf, 0x4a, 0xdb, 0xa3, 0x84, 0x25, 0xbb, 0xb7, 0xed, 0x34, 0xc3, 0x0d, 0x7b, 0xcf, 0x6f, + 0x86, 0x2b, 0xf6, 0x0a, 0xb2, 0xa1, 0x50, 0x3c, 0x58, 0xb1, 0x1a, 0xae, 0xb0, 0x94, 0x41, 0x9f, 0x86, 0xa5, 0x25, + 0x2c, 0x9a, 0x42, 0x51, 0x8a, 0x7e, 0xc5, 0x6b, 0xc2, 0x4e, 0xab, 0xb1, 0x10, 0xf9, 0xa1, 0xe1, 0x8a, 0xdd, 0xf3, + 0x9b, 0xc1, 0x8a, 0xbd, 0xd7, 0x36, 0xa2, 0xc1, 0xc6, 0x2d, 0x8e, 0xc0, 0xac, 0x74, 0x61, 0x52, 0xa0, 0xde, 0xda, + 0x37, 0xc1, 0x0d, 0xbb, 0xc6, 0xfa, 0x3d, 0xc2, 0xa2, 0x51, 0xe6, 0x1f, 0xac, 0xd8, 0x57, 0x2e, 0x31, 0xd4, 0xdc, + 0xf2, 0xa4, 0x63, 0xa8, 0x2e, 0x90, 0xae, 0x08, 0x8f, 0x38, 0xbd, 0xc8, 0xbe, 0x62, 0x19, 0xf4, 0x95, 0xe1, 0x8a, + 0x6d, 0xb1, 0x76, 0xd7, 0xc6, 0xb8, 0x65, 0x55, 0x4f, 0x82, 0x02, 0xa3, 0xac, 0x52, 0x5a, 0x2e, 0x8e, 0x58, 0x36, + 0x75, 0xd4, 0xa0, 0x36, 0x0c, 0xe8, 0x83, 0xd1, 0x7f, 0xf8, 0xfa, 0xdd, 0x0f, 0x5e, 0xa9, 0x6f, 0xbe, 0x2f, 0x1c, + 0xef, 0xca, 0x12, 0xbd, 0x2b, 0x3f, 0xf3, 0x72, 0xf6, 0x62, 0x3e, 0xd1, 0xb5, 0xa4, 0x4d, 0x86, 0xdc, 0x4d, 0x67, + 0x2f, 0x3a, 0xfc, 0x2d, 0x3f, 0xfb, 0x7e, 0x63, 0xf5, 0xb1, 0xfa, 0xae, 0xee, 0xde, 0xfb, 0xc1, 0xa6, 0x71, 0x2a, + 0xbe, 0x3b, 0x5d, 0x71, 0x6c, 0x67, 0xad, 0xbd, 0x33, 0xff, 0x87, 0x6b, 0xbd, 0xc5, 0xb1, 0xbb, 0xe6, 0xdb, 0xe1, + 0xc6, 0x1e, 0x06, 0xf9, 0x7d, 0xe5, 0x97, 0x5f, 0xf3, 0xe7, 0x5e, 0xa7, 0x24, 0x0b, 0xa8, 0x46, 0x9f, 0x8c, 0x34, + 0x74, 0xc9, 0x4c, 0x4c, 0x43, 0x7c, 0x91, 0x01, 0x3a, 0x17, 0x88, 0x67, 0x77, 0x7c, 0x3c, 0xb9, 0xbb, 0x8a, 0x27, + 0x77, 0x03, 0xfe, 0xc9, 0xb4, 0xa0, 0xbd, 0xe0, 0xee, 0x7c, 0xf6, 0x99, 0x17, 0xf6, 0x92, 0x7c, 0xe1, 0xb3, 0x77, + 0xc2, 0x5d, 0xa5, 0x2f, 0x7c, 0xf6, 0x55, 0xf0, 0xcf, 0x23, 0x4d, 0x96, 0xc1, 0xbe, 0xd6, 0xfc, 0xf3, 0x08, 0x59, + 0x3f, 0xd8, 0x17, 0xc1, 0xdf, 0x81, 0xff, 0x77, 0x95, 0xa0, 0x65, 0xfc, 0x4b, 0xad, 0x7e, 0xbe, 0x97, 0xb1, 0x39, + 0xf0, 0x26, 0xb4, 0x82, 0xde, 0xbc, 0xad, 0xe5, 0x4f, 0xe2, 0xe2, 0x48, 0xd5, 0x53, 0xc3, 0x41, 0x8b, 0xc5, 0xdc, + 0xd4, 0x47, 0xe9, 0x54, 0xde, 0xe4, 0x2d, 0x4f, 0xa4, 0x85, 0xf9, 0x0e, 0xc2, 0x81, 0xdf, 0xda, 0x30, 0x05, 0x3b, + 0x8e, 0x9b, 0xc1, 0x5b, 0x06, 0x10, 0x92, 0xd9, 0x74, 0xcb, 0xaf, 0xf9, 0x23, 0xfe, 0x95, 0xef, 0x82, 0x7b, 0xfe, + 0x9e, 0xbf, 0xe2, 0x75, 0xcd, 0x77, 0x6c, 0x21, 0x21, 0x4f, 0xeb, 0xed, 0x65, 0xb0, 0x65, 0xf5, 0xee, 0x32, 0xb8, + 0x67, 0xf5, 0xf6, 0x69, 0x70, 0xcd, 0xea, 0xdd, 0xd3, 0xe0, 0x3d, 0xdb, 0x5e, 0x06, 0x8f, 0xd8, 0xee, 0x32, 0x78, + 0xc5, 0xb6, 0x4f, 0x83, 0xaf, 0x6c, 0xf7, 0x34, 0xa8, 0x15, 0xd2, 0xc3, 0x57, 0x21, 0x99, 0x4e, 0xbe, 0xd6, 0xcc, + 0xb0, 0xea, 0x06, 0x5f, 0x84, 0xf5, 0x8b, 0x6a, 0x19, 0x7c, 0xa9, 0x99, 0x6e, 0x73, 0x20, 0x04, 0xd3, 0x2d, 0x0e, + 0x6e, 0xe9, 0x89, 0x69, 0x57, 0x90, 0x0a, 0xd6, 0xd5, 0xd2, 0xe0, 0xa6, 0x6e, 0x5a, 0x27, 0xb3, 0xe3, 0x9d, 0x18, + 0x77, 0x78, 0x27, 0xde, 0xb0, 0x45, 0xd3, 0xe9, 0xaa, 0x73, 0xfa, 0x3c, 0xd0, 0x47, 0x80, 0xde, 0xfb, 0x2b, 0xe9, + 0x41, 0x53, 0x34, 0x3c, 0x57, 0xba, 0xe3, 0xd6, 0x7e, 0x1f, 0x5a, 0xfb, 0x3d, 0x93, 0x8a, 0xb4, 0x88, 0x45, 0x65, + 0x51, 0x55, 0xc8, 0x27, 0x1e, 0x64, 0x5a, 0xab, 0x96, 0x30, 0x52, 0x67, 0x02, 0x26, 0x7d, 0x41, 0x87, 0x41, 0x4e, + 0x76, 0x05, 0xb6, 0xe0, 0x9b, 0x41, 0xc2, 0xd6, 0x3c, 0x9e, 0x0e, 0x93, 0x60, 0xc1, 0x96, 0x7c, 0xd8, 0x2d, 0x16, + 0xac, 0x54, 0x18, 0x93, 0xbe, 0x3e, 0x1d, 0xed, 0xee, 0xbc, 0xb7, 0x4a, 0xe3, 0x38, 0x13, 0xa8, 0x73, 0xab, 0xf4, + 0x36, 0xbf, 0x75, 0x76, 0xf5, 0xb5, 0xda, 0xe5, 0x41, 0x60, 0xf8, 0x0c, 0x44, 0x3b, 0xc4, 0x7b, 0x07, 0x35, 0x46, + 0xba, 0x25, 0xb3, 0xee, 0x2b, 0x7b, 0x5f, 0xdf, 0x9a, 0xad, 0xfa, 0xdf, 0x2d, 0x82, 0xf6, 0x72, 0xd9, 0xfb, 0x9f, + 0xcc, 0xab, 0xbf, 0x77, 0xbc, 0xba, 0xf1, 0x27, 0xf7, 0xfc, 0x13, 0x46, 0x27, 0x60, 0x22, 0xdb, 0xf1, 0x4f, 0xa3, + 0x6d, 0xe3, 0x94, 0x27, 0xf7, 0xf2, 0xff, 0x2b, 0x05, 0xda, 0xbb, 0x79, 0x65, 0x6f, 0x8a, 0x5b, 0xde, 0xb1, 0x97, + 0x2f, 0xac, 0x3d, 0xd1, 0x20, 0x94, 0x7c, 0xe2, 0x6e, 0x50, 0x34, 0xec, 0x89, 0x2f, 0x78, 0x35, 0xfb, 0x34, 0x9f, + 0x6c, 0xf9, 0xf1, 0x8e, 0xf8, 0xa9, 0x63, 0x47, 0x7c, 0xe1, 0x0f, 0x16, 0xcd, 0xb7, 0x7a, 0xb5, 0x73, 0x27, 0x77, + 0x2a, 0xbd, 0xe3, 0xc7, 0xfb, 0xf8, 0xf0, 0xdf, 0xae, 0xf4, 0xee, 0xbb, 0x2b, 0x6d, 0x57, 0xb9, 0xbb, 0xf3, 0x4d, + 0xc7, 0x37, 0xb2, 0xd6, 0x18, 0x6e, 0x66, 0x14, 0x8c, 0x30, 0x6d, 0x61, 0x9a, 0x06, 0x91, 0xa5, 0x58, 0x84, 0x44, + 0x8d, 0xd2, 0x39, 0xd1, 0x67, 0x41, 0xa7, 0xa0, 0x8b, 0x1b, 0xfd, 0x2d, 0x1f, 0xb3, 0x1b, 0xe3, 0xb2, 0x79, 0x7b, + 0x75, 0x33, 0x19, 0x0c, 0x6e, 0xfd, 0xfd, 0x1d, 0x0f, 0x67, 0xb7, 0x73, 0xf6, 0x96, 0xdf, 0xd1, 0x7a, 0x9a, 0xa8, + 0xc6, 0x17, 0x0f, 0x49, 0x60, 0xb7, 0xbe, 0x3f, 0xb1, 0x88, 0x60, 0xed, 0x1b, 0xe7, 0xad, 0x3f, 0x90, 0x66, 0x69, + 0xb9, 0xb5, 0xbf, 0x7f, 0x58, 0x43, 0x71, 0x0b, 0x42, 0xc6, 0x7b, 0x5b, 0xe5, 0xf0, 0x8a, 0x7f, 0xf4, 0xde, 0xfa, + 0xd3, 0xb7, 0x3a, 0xf8, 0x66, 0xa2, 0xce, 0xa5, 0x57, 0x17, 0x4f, 0xd9, 0x67, 0xfe, 0x49, 0x9e, 0x29, 0xef, 0x84, + 0x9c, 0xb6, 0xd7, 0x48, 0xe2, 0x44, 0x47, 0xc5, 0x57, 0x37, 0x91, 0x40, 0x21, 0x60, 0x57, 0xf8, 0x5a, 0xf3, 0xfb, + 0x49, 0x39, 0xf5, 0x76, 0x40, 0xf2, 0xca, 0x6d, 0x45, 0xf4, 0x2d, 0xe7, 0xfc, 0x66, 0x78, 0x39, 0xfd, 0xda, 0xed, + 0xdb, 0xa3, 0xc2, 0xda, 0x54, 0xc4, 0xdb, 0x2d, 0x06, 0x61, 0x9d, 0xcc, 0x2c, 0x73, 0xc9, 0x97, 0xbe, 0xd6, 0x66, + 0xee, 0x31, 0xbd, 0xe3, 0x4c, 0x33, 0x64, 0xf4, 0x05, 0x66, 0xa6, 0xc3, 0x61, 0x79, 0x8e, 0xe5, 0xf1, 0xe1, 0xab, + 0x27, 0x8f, 0x06, 0x8f, 0x30, 0x84, 0xcb, 0x0a, 0x0b, 0xf9, 0xca, 0x87, 0x59, 0xdd, 0xba, 0x76, 0x5c, 0x3c, 0x1d, + 0xbe, 0x80, 0xbc, 0x41, 0xd7, 0x43, 0x53, 0x44, 0xab, 0xfc, 0x8e, 0xa2, 0x4f, 0x94, 0x1c, 0x74, 0x3c, 0x81, 0xda, + 0x21, 0x17, 0xee, 0xd7, 0x27, 0x1c, 0x14, 0x1d, 0x58, 0x6a, 0xbf, 0x7f, 0xfe, 0x89, 0x08, 0xa5, 0x61, 0xbc, 0x5f, + 0x84, 0xd1, 0x9f, 0x71, 0x59, 0xac, 0xe1, 0x88, 0x1d, 0xc0, 0xe7, 0x9e, 0xe8, 0x6b, 0xd8, 0xd2, 0xf7, 0xfd, 0xc0, + 0xdb, 0xf2, 0x6b, 0xf6, 0x95, 0x7b, 0x97, 0xc3, 0x57, 0xfe, 0x93, 0x47, 0x20, 0x3f, 0x21, 0x4e, 0x0a, 0x86, 0xc4, + 0x76, 0x14, 0xa3, 0xd6, 0xe1, 0x97, 0x1a, 0x62, 0xb5, 0x3e, 0x21, 0x75, 0x17, 0xa4, 0x7f, 0x50, 0xc8, 0x7e, 0x42, + 0x60, 0x35, 0x49, 0x9f, 0x02, 0x93, 0xf8, 0xb6, 0x86, 0x04, 0xd2, 0xb4, 0x40, 0x0c, 0x0e, 0x14, 0x9f, 0x0a, 0xfe, + 0x75, 0xf8, 0x85, 0xe4, 0xbf, 0x9b, 0x9a, 0x8f, 0xe1, 0x6f, 0x18, 0x9a, 0x49, 0x75, 0x9f, 0xd6, 0x51, 0xe2, 0xd5, + 0x70, 0xea, 0x85, 0x95, 0x50, 0x27, 0x43, 0x90, 0x8a, 0x21, 0x17, 0xe2, 0xe2, 0xe9, 0xe4, 0xb6, 0x14, 0xe1, 0x9f, + 0x13, 0x7c, 0x26, 0x57, 0x9a, 0x7c, 0x46, 0x4f, 0x1a, 0x59, 0xc0, 0xbd, 0x7c, 0x5f, 0xf6, 0x6a, 0x70, 0x53, 0x0f, + 0xf9, 0x6d, 0xed, 0xbe, 0x2f, 0xe7, 0x04, 0x3d, 0xb2, 0x1f, 0xd0, 0x1c, 0x0c, 0xd4, 0x0c, 0xa4, 0x0c, 0xc1, 0x2d, + 0x5c, 0xfa, 0x3d, 0x55, 0x90, 0x2f, 0xbf, 0xf7, 0x45, 0xc8, 0xc0, 0x95, 0x1b, 0xc2, 0x94, 0x4b, 0x85, 0x14, 0x38, + 0x6e, 0xeb, 0xc1, 0x17, 0x8d, 0x4e, 0x22, 0xc1, 0xa7, 0x04, 0x24, 0x49, 0xcb, 0x03, 0x49, 0x23, 0xa6, 0x03, 0x71, + 0xa1, 0x34, 0xcd, 0x4a, 0x8a, 0x38, 0xc4, 0xae, 0xfa, 0x16, 0x09, 0xcf, 0x82, 0xf7, 0x0c, 0xd6, 0x8e, 0x14, 0x2d, + 0xbe, 0x1a, 0xd3, 0xb1, 0x0e, 0x1b, 0x5a, 0xca, 0xe2, 0x3e, 0x4b, 0xea, 0x34, 0x12, 0x57, 0xde, 0x09, 0xf9, 0xf3, + 0x9f, 0x4a, 0x04, 0xd2, 0xbb, 0x1a, 0x88, 0x41, 0xf0, 0x03, 0xf4, 0x1f, 0xb0, 0xc8, 0x41, 0x50, 0xaa, 0xcb, 0x30, + 0xaf, 0x32, 0x2a, 0x70, 0xb6, 0x63, 0xdb, 0x39, 0x53, 0x75, 0x0b, 0xbe, 0x08, 0xc3, 0x90, 0x76, 0xb6, 0x6a, 0x4e, + 0x6e, 0xf5, 0x06, 0xea, 0x99, 0xc4, 0x91, 0x5a, 0x8a, 0x23, 0x6d, 0xcd, 0x7d, 0xba, 0xf0, 0xba, 0xe5, 0x05, 0x0d, + 0x17, 0xa0, 0x17, 0xa5, 0xbb, 0xce, 0x27, 0x14, 0xba, 0xac, 0xc6, 0xd5, 0x50, 0xd4, 0xa1, 0x1c, 0x63, 0xed, 0xcf, + 0x95, 0x3c, 0xbf, 0x03, 0xeb, 0x11, 0x1a, 0xbe, 0x2a, 0x75, 0x10, 0xdb, 0x4f, 0xf4, 0xae, 0x53, 0xa9, 0xbf, 0x01, + 0x60, 0xe0, 0xd4, 0xf1, 0x50, 0x1f, 0xb5, 0x53, 0xc8, 0x76, 0xee, 0x2d, 0x31, 0x2a, 0x57, 0xc2, 0x53, 0xa5, 0xe5, + 0x29, 0x65, 0xd5, 0xd7, 0x82, 0x5b, 0xd9, 0x7d, 0x36, 0x80, 0x8c, 0x36, 0x28, 0x90, 0x67, 0xd4, 0xd6, 0x78, 0x90, + 0x6a, 0x9a, 0x25, 0x8e, 0xe1, 0x83, 0x22, 0xcd, 0x2a, 0xb0, 0x78, 0x99, 0x4b, 0xe6, 0xa0, 0x60, 0xb9, 0xde, 0x6c, + 0xa6, 0x99, 0xea, 0x8b, 0xdc, 0xde, 0x68, 0xbc, 0x4c, 0xff, 0xcd, 0x92, 0x01, 0x8f, 0x2e, 0x9e, 0xfa, 0x01, 0xa4, + 0x49, 0x8a, 0x07, 0x48, 0x82, 0xed, 0xc1, 0x2e, 0x76, 0x18, 0xb6, 0x8a, 0x95, 0x3d, 0x79, 0xba, 0xdc, 0xa1, 0x29, + 0x97, 0xe0, 0x92, 0x13, 0x73, 0x39, 0xf5, 0x7d, 0xc9, 0x7a, 0x43, 0x71, 0xca, 0xa6, 0x09, 0x28, 0x09, 0xb4, 0x5b, + 0xf0, 0x5f, 0xf8, 0xd4, 0xd0, 0x69, 0x01, 0x96, 0xda, 0x6e, 0xc0, 0x7f, 0xa1, 0x5f, 0x6c, 0x77, 0x51, 0x3f, 0x30, + 0x0f, 0xf6, 0x66, 0x71, 0x65, 0x0c, 0x38, 0x49, 0x5c, 0x69, 0x1e, 0xb9, 0x7e, 0x50, 0xf4, 0xe9, 0xb2, 0x76, 0xe0, + 0x4c, 0x71, 0x61, 0x95, 0xda, 0x24, 0xbd, 0xf6, 0x5b, 0x6a, 0xe2, 0x4d, 0x94, 0x54, 0x85, 0xed, 0x90, 0xf6, 0x2f, + 0x29, 0x67, 0xaa, 0xb8, 0x43, 0xf4, 0x64, 0x37, 0x71, 0x15, 0x78, 0x61, 0x55, 0xb1, 0x11, 0x6a, 0x33, 0xb2, 0x9c, + 0xc0, 0xe9, 0x1e, 0xab, 0x0b, 0x3e, 0xb6, 0xab, 0xd9, 0x05, 0x2b, 0xd9, 0x9a, 0x49, 0xf7, 0x79, 0x3b, 0xe6, 0x42, + 0x5e, 0xe9, 0x65, 0xd1, 0x0a, 0x68, 0x0f, 0x02, 0x87, 0x5f, 0x68, 0xba, 0x47, 0xcf, 0x36, 0xdb, 0xd4, 0x66, 0x63, + 0x6b, 0x11, 0x42, 0x06, 0xa2, 0xa1, 0x2f, 0xe4, 0x8c, 0x22, 0x5f, 0xa5, 0xe5, 0x5a, 0x6d, 0xac, 0x32, 0x5e, 0x60, + 0x22, 0xc8, 0x70, 0x16, 0xde, 0xa1, 0xa7, 0xf5, 0x48, 0x53, 0x4c, 0x82, 0x93, 0x2e, 0xfe, 0x02, 0x6c, 0x28, 0x4f, + 0x72, 0x73, 0x40, 0x0e, 0xa0, 0x72, 0x29, 0x4a, 0xa5, 0x0c, 0xfe, 0x45, 0xdd, 0x91, 0x6d, 0xd5, 0x7f, 0xa7, 0x81, + 0x0c, 0xee, 0x40, 0xdf, 0xf6, 0x42, 0x6b, 0x47, 0x3b, 0x57, 0xb6, 0xa6, 0x6d, 0x91, 0xe6, 0x31, 0xb2, 0xd8, 0x00, + 0xf2, 0x89, 0x74, 0x0e, 0x44, 0x5e, 0x13, 0x8d, 0x77, 0xf6, 0x8c, 0x8f, 0xa7, 0xe2, 0x21, 0x79, 0xaf, 0xf2, 0x7d, + 0x73, 0xaf, 0x0f, 0xc6, 0xd8, 0xb7, 0xa0, 0x4c, 0x7c, 0xb0, 0xda, 0x5a, 0x97, 0x58, 0x6f, 0x95, 0x26, 0xd1, 0x0d, + 0x57, 0xd0, 0x71, 0x24, 0x6e, 0x10, 0x83, 0x63, 0xc6, 0x6b, 0xab, 0x2c, 0x7d, 0x85, 0x65, 0xae, 0x63, 0x96, 0x0c, + 0x99, 0xd4, 0x79, 0xa2, 0xe0, 0xc9, 0xcf, 0x13, 0x92, 0x11, 0x51, 0xb3, 0x2d, 0x47, 0x29, 0x37, 0x2d, 0xe0, 0x32, + 0x23, 0x03, 0xf8, 0x26, 0x4d, 0x00, 0xca, 0xe5, 0x4b, 0x90, 0x4a, 0x43, 0x04, 0xd7, 0x6c, 0x2f, 0x19, 0xdd, 0x3a, + 0x5a, 0x07, 0x55, 0x92, 0xb9, 0x83, 0x73, 0x3b, 0x8b, 0x94, 0x7a, 0xf3, 0x11, 0x86, 0x9d, 0x7c, 0x08, 0xeb, 0x04, + 0xbf, 0x0d, 0xa8, 0x49, 0x9f, 0x0a, 0x2f, 0x1a, 0x01, 0x9a, 0xfa, 0x4e, 0x95, 0xf1, 0xa9, 0xf0, 0xb2, 0xd1, 0x96, + 0x65, 0x94, 0x42, 0x75, 0xc1, 0xec, 0xd6, 0x74, 0x21, 0xe6, 0x55, 0x35, 0xd0, 0x06, 0xb9, 0x5d, 0xc7, 0x0c, 0x68, + 0xd4, 0x76, 0xe5, 0x91, 0x05, 0xb8, 0x35, 0x13, 0x81, 0x91, 0xf3, 0xef, 0xf3, 0x97, 0x2a, 0x9c, 0xa7, 0xdf, 0x0f, + 0xbd, 0xfd, 0x36, 0x88, 0x46, 0xdb, 0x4b, 0xb6, 0x0b, 0xa2, 0xd1, 0xee, 0xb2, 0x61, 0xf4, 0xfb, 0x29, 0xfd, 0x7e, + 0xda, 0x80, 0xaa, 0x44, 0x98, 0x88, 0x7b, 0xfd, 0x46, 0x2d, 0x5f, 0xa9, 0xf5, 0x3b, 0xb5, 0x7c, 0xa9, 0x86, 0xb7, + 0xf6, 0x24, 0x12, 0x44, 0x96, 0xc6, 0xe6, 0x5e, 0xb2, 0xa5, 0x5a, 0x2a, 0x1d, 0xa3, 0xca, 0x88, 0x5a, 0x3a, 0x9b, + 0x63, 0xc5, 0x48, 0x3b, 0x07, 0x25, 0x03, 0x32, 0x2d, 0xae, 0x6a, 0x4c, 0x37, 0x2b, 0x5a, 0x62, 0x32, 0xc2, 0xca, + 0xb6, 0xbc, 0xdd, 0xa4, 0x6a, 0x3a, 0x27, 0x37, 0xb7, 0x4a, 0xb9, 0xb9, 0x15, 0x3c, 0xff, 0x86, 0x6e, 0xb9, 0xe4, + 0xda, 0xcb, 0x6c, 0x5a, 0x28, 0xdd, 0x32, 0xae, 0xc1, 0xd6, 0xbe, 0x09, 0x64, 0x99, 0x0f, 0x14, 0x35, 0xb6, 0x17, + 0x8d, 0xf2, 0x0d, 0xb2, 0x15, 0x31, 0xea, 0x94, 0x05, 0xe3, 0x6f, 0x77, 0xf4, 0x40, 0x06, 0xaa, 0xaa, 0xda, 0x38, + 0xb8, 0xb3, 0xd2, 0x1f, 0x96, 0x17, 0x4f, 0x59, 0x62, 0xa5, 0x93, 0x0b, 0x55, 0xe8, 0x0f, 0x42, 0x74, 0x53, 0xd9, + 0x70, 0x70, 0xa8, 0x8b, 0xad, 0x0c, 0x08, 0x3d, 0x4c, 0xef, 0x6d, 0xac, 0x64, 0xb9, 0x6b, 0xca, 0x17, 0x33, 0x9e, + 0x70, 0x1c, 0x7d, 0xb9, 0x5a, 0x84, 0xb5, 0x5a, 0x64, 0x27, 0xc0, 0x43, 0x6b, 0xb5, 0x14, 0x72, 0xb5, 0x08, 0x67, + 0xa6, 0x0b, 0x35, 0xd3, 0x33, 0x50, 0x40, 0x0a, 0x35, 0xcb, 0x13, 0x80, 0x85, 0x17, 0x66, 0x86, 0x0b, 0x33, 0xc3, + 0x71, 0x48, 0x8d, 0xff, 0x83, 0xde, 0xeb, 0xdc, 0x73, 0xcb, 0xdd, 0xe8, 0x34, 0xe2, 0xdb, 0xd1, 0x06, 0x73, 0x7c, + 0x10, 0x4e, 0xaa, 0x7e, 0x3f, 0x2d, 0x11, 0xab, 0xc7, 0xc0, 0x08, 0xca, 0xa1, 0x72, 0xb4, 0x5f, 0x16, 0x96, 0x64, + 0x49, 0x58, 0x92, 0x7b, 0x35, 0xce, 0xa5, 0xe5, 0xe2, 0x55, 0x12, 0x88, 0x44, 0xc6, 0x4b, 0x69, 0x82, 0x4f, 0x78, + 0x39, 0x32, 0x52, 0xf3, 0xe4, 0x26, 0xf5, 0x72, 0x96, 0xb1, 0x31, 0x62, 0x18, 0x85, 0x7e, 0x53, 0xf5, 0xfb, 0x79, + 0xe9, 0xe5, 0xd4, 0xce, 0x4f, 0xe0, 0x7a, 0x79, 0xea, 0x2c, 0x72, 0x84, 0xbc, 0x1a, 0x49, 0x85, 0xe5, 0xb5, 0x52, + 0x4f, 0x5f, 0x82, 0x0f, 0xea, 0xee, 0x8d, 0x02, 0x20, 0x2e, 0x72, 0xe9, 0x5f, 0x5b, 0xc2, 0xa5, 0x29, 0x37, 0x30, + 0xe8, 0x21, 0xcf, 0x49, 0x08, 0x95, 0x20, 0x24, 0x85, 0x75, 0xe3, 0xbe, 0x78, 0x3a, 0x71, 0xdd, 0x59, 0x6c, 0x60, + 0x82, 0xc3, 0x01, 0x10, 0x0f, 0xa6, 0x5e, 0x34, 0xe0, 0xa5, 0x9a, 0x33, 0x1f, 0xbd, 0x9c, 0x60, 0x32, 0x40, 0x55, + 0x31, 0x70, 0xca, 0x7a, 0x22, 0x1f, 0x19, 0x37, 0x33, 0xdf, 0x0f, 0xf0, 0xdd, 0xba, 0x90, 0xe8, 0x0f, 0x0a, 0xa0, + 0x20, 0x53, 0x00, 0x05, 0x89, 0x01, 0x28, 0x88, 0x0d, 0x40, 0xc1, 0xa6, 0xe1, 0x4b, 0xa9, 0xc3, 0x8d, 0x80, 0x2e, + 0xc2, 0x87, 0x9e, 0x85, 0x8d, 0x15, 0x8a, 0x67, 0x63, 0x36, 0x66, 0x85, 0xda, 0x79, 0x72, 0x39, 0x15, 0x3b, 0x8b, + 0xb1, 0xae, 0x22, 0xeb, 0xc4, 0x0b, 0x09, 0x45, 0xce, 0xb9, 0x91, 0xa8, 0xbb, 0x9f, 0x7b, 0x2f, 0xc9, 0x58, 0x32, + 0x6f, 0x68, 0xd4, 0x60, 0x5e, 0x76, 0x1d, 0xc0, 0xb4, 0xe4, 0xdb, 0x82, 0x06, 0xd3, 0xa9, 0xf2, 0x88, 0x34, 0x09, + 0x6a, 0xe7, 0x32, 0x29, 0x72, 0x42, 0x98, 0x04, 0xbd, 0x12, 0xfc, 0x46, 0xa2, 0xfc, 0x7f, 0xd3, 0x09, 0x1e, 0xe0, + 0x98, 0x68, 0x95, 0x7c, 0x05, 0x03, 0x66, 0xce, 0x9f, 0x4b, 0xa7, 0x6c, 0x84, 0x62, 0x2c, 0xd3, 0x78, 0xf4, 0x95, + 0x0d, 0x11, 0xda, 0xea, 0x39, 0x9a, 0x98, 0xa0, 0x0e, 0xf0, 0x88, 0xfe, 0x1a, 0x7d, 0x35, 0x14, 0x2a, 0x5d, 0x8d, + 0xd4, 0x35, 0x3b, 0xe7, 0xfc, 0x5d, 0x6d, 0x38, 0x91, 0x31, 0x6d, 0x0a, 0x7c, 0x03, 0x02, 0xf9, 0x06, 0x02, 0xc0, + 0x55, 0xd3, 0x99, 0xbd, 0x02, 0x38, 0x07, 0x02, 0x78, 0x9c, 0x77, 0x3c, 0x7e, 0xa0, 0xbf, 0x8a, 0xe3, 0xde, 0x69, + 0x1a, 0xb6, 0xff, 0x0a, 0x8c, 0xc5, 0x50, 0x8e, 0xe7, 0x3b, 0x05, 0xc9, 0x1e, 0xa5, 0x2c, 0x5d, 0x35, 0x91, 0x1d, + 0x8a, 0xf5, 0x69, 0x4e, 0x19, 0x4b, 0xdb, 0x72, 0x8c, 0x36, 0x5e, 0x3f, 0xc4, 0xe3, 0x9b, 0x1b, 0x3d, 0xf9, 0xa0, + 0x07, 0xb7, 0xb7, 0x37, 0xaf, 0x7a, 0xcc, 0xe6, 0x5b, 0xb1, 0x78, 0x56, 0xc4, 0x89, 0xd3, 0x3a, 0xe4, 0x00, 0x07, + 0x39, 0x09, 0x81, 0x74, 0x8c, 0x4b, 0x2d, 0x3a, 0xa8, 0x59, 0xce, 0x6b, 0x60, 0x99, 0x45, 0x90, 0x0d, 0x10, 0xd5, + 0x34, 0x15, 0xab, 0xe1, 0x41, 0xa9, 0x9a, 0x53, 0x2a, 0xb5, 0x6f, 0x38, 0x5b, 0x9d, 0x3e, 0xb1, 0x6a, 0x13, 0x6e, + 0xfd, 0xb9, 0xf6, 0x04, 0x6d, 0x25, 0x0d, 0x84, 0x7a, 0xbe, 0x4a, 0x97, 0x14, 0xc5, 0xe3, 0xcc, 0xc4, 0x53, 0x15, + 0x18, 0xfb, 0xd6, 0x8e, 0xa0, 0x20, 0x69, 0xba, 0x0e, 0x38, 0x4c, 0xa3, 0x13, 0x16, 0xff, 0x94, 0x3e, 0x94, 0x17, + 0xb5, 0x02, 0x27, 0xf9, 0x87, 0x70, 0x11, 0x49, 0x2c, 0xf4, 0x4b, 0x02, 0x20, 0x91, 0xc1, 0xab, 0x51, 0xb1, 0x16, + 0x2a, 0x40, 0x4e, 0x51, 0x7a, 0xab, 0xf8, 0xb8, 0x14, 0xa5, 0x4a, 0xa9, 0xcc, 0x8d, 0x4a, 0x01, 0x61, 0x6d, 0xe0, + 0xe8, 0x02, 0xbe, 0x80, 0xa0, 0xb5, 0xdc, 0xad, 0x6d, 0xcf, 0x1b, 0x99, 0xcf, 0x4c, 0xf3, 0xb4, 0xfa, 0xa0, 0xfe, + 0x7e, 0xbf, 0xc0, 0x30, 0x1b, 0x4f, 0x7f, 0xdf, 0x66, 0x08, 0x37, 0x7f, 0xc3, 0x10, 0x2d, 0x01, 0x1c, 0xb3, 0xb4, + 0x87, 0x42, 0x16, 0x4c, 0xb0, 0x86, 0xaa, 0x3c, 0xe5, 0xb3, 0x97, 0x4f, 0x6e, 0x00, 0x4d, 0x0d, 0x5d, 0xdc, 0xe8, + 0x54, 0x57, 0x25, 0x08, 0xdf, 0x77, 0x85, 0x7a, 0x6c, 0x0e, 0x38, 0x35, 0x00, 0x14, 0x8b, 0xbc, 0xd6, 0x63, 0xfb, + 0x07, 0xbd, 0x51, 0x6f, 0x80, 0x78, 0x3a, 0xe7, 0x85, 0x7f, 0x44, 0xbf, 0x4e, 0xfd, 0x19, 0x17, 0x82, 0xa8, 0xd7, + 0x93, 0xf0, 0x4e, 0x9c, 0xa5, 0x71, 0x70, 0xd6, 0x1b, 0x98, 0x8b, 0x40, 0x71, 0x96, 0xe6, 0x67, 0x20, 0x96, 0x23, + 0x3c, 0x62, 0xcd, 0x56, 0x80, 0x18, 0x58, 0xea, 0x90, 0x64, 0xd5, 0xb1, 0xfd, 0xfe, 0xeb, 0x91, 0xe1, 0x4d, 0x47, + 0x44, 0x18, 0xfd, 0xbb, 0x02, 0x01, 0x0a, 0x96, 0x99, 0xed, 0xcc, 0xa4, 0xab, 0x3d, 0xab, 0xe7, 0xcd, 0x26, 0xef, + 0xea, 0x1d, 0xab, 0x69, 0x39, 0x35, 0xad, 0xb2, 0x9a, 0x36, 0xc9, 0xa1, 0x66, 0xa2, 0xdf, 0xd7, 0xf8, 0xa8, 0xf9, + 0x1c, 0x70, 0xd9, 0x30, 0xf9, 0xf5, 0xac, 0x9a, 0xf7, 0xfb, 0x9e, 0x7c, 0x04, 0xbf, 0x90, 0xb8, 0xcc, 0xad, 0xb1, + 0x7c, 0xfa, 0x86, 0xf8, 0xcc, 0x0c, 0xe2, 0xd1, 0xea, 0x08, 0xea, 0xeb, 0x5a, 0x78, 0x1d, 0x73, 0x85, 0xcd, 0xc4, + 0xf4, 0x35, 0x0c, 0x9e, 0x27, 0x7c, 0xf0, 0x96, 0xa3, 0xbf, 0x91, 0xce, 0x4c, 0xc1, 0x42, 0xce, 0xfd, 0xc9, 0x6b, + 0x84, 0x4e, 0x46, 0xa4, 0x07, 0x9d, 0x4e, 0xd0, 0x90, 0xfd, 0xfe, 0x2d, 0x74, 0x66, 0x2b, 0x95, 0xb2, 0x55, 0x51, + 0x99, 0xae, 0xeb, 0xa2, 0xac, 0xa0, 0x63, 0xe9, 0xe7, 0xad, 0x90, 0x99, 0xf5, 0x33, 0x0b, 0xf9, 0xe9, 0x56, 0x62, + 0x4d, 0xd9, 0xf6, 0x89, 0xda, 0x20, 0xcd, 0xba, 0x50, 0x5d, 0xe0, 0xdc, 0x59, 0x7b, 0xbd, 0x11, 0xea, 0x9f, 0xf3, + 0xd1, 0xba, 0x58, 0x7b, 0xe0, 0x12, 0x33, 0x4b, 0xe7, 0x8a, 0x43, 0x23, 0xf7, 0x47, 0x5f, 0x8a, 0x34, 0xa7, 0x3c, + 0x40, 0x83, 0x28, 0xe6, 0xf6, 0x5b, 0x20, 0xfd, 0xd0, 0x5b, 0x20, 0xfb, 0xe8, 0x9c, 0x93, 0xd7, 0x00, 0x4e, 0x87, + 0x88, 0xb8, 0x15, 0x09, 0x3a, 0x56, 0x0d, 0x6f, 0x2c, 0xdc, 0xd3, 0x5e, 0x1a, 0xf7, 0xd2, 0xfc, 0x2c, 0xed, 0xf7, + 0x0d, 0x80, 0x66, 0x8a, 0xc8, 0xf0, 0x38, 0x23, 0x77, 0x49, 0x0b, 0xc1, 0x94, 0xf6, 0x5f, 0x8d, 0x21, 0x41, 0x20, + 0xe0, 0xff, 0x10, 0xde, 0x23, 0x40, 0xdb, 0xa4, 0x0d, 0xb8, 0xea, 0x31, 0x1d, 0x98, 0x2d, 0x39, 0x5b, 0x75, 0x36, + 0x00, 0xe5, 0x54, 0x69, 0x3d, 0xe5, 0x71, 0x4d, 0x11, 0x91, 0x2a, 0x0b, 0xf5, 0x1b, 0xeb, 0xc9, 0x64, 0x95, 0x8b, + 0x0c, 0x39, 0x2a, 0xd3, 0xbb, 0x9a, 0x11, 0x62, 0x97, 0x7e, 0x7e, 0x03, 0x4b, 0x36, 0xfe, 0x88, 0x93, 0xb7, 0x04, + 0x48, 0xdb, 0x59, 0xbb, 0xaa, 0x76, 0x39, 0x6e, 0xed, 0xe6, 0x80, 0xe4, 0xeb, 0x8d, 0x46, 0x23, 0xed, 0x27, 0x27, + 0x60, 0xa8, 0x7a, 0x6a, 0x29, 0xf4, 0x58, 0xad, 0xb0, 0x75, 0x3b, 0x72, 0x99, 0x25, 0x83, 0xf9, 0xc2, 0x38, 0x7e, + 0x69, 0x3e, 0xfa, 0x70, 0xa9, 0xac, 0x5d, 0x47, 0x7c, 0xfd, 0x47, 0x59, 0xad, 0xef, 0x79, 0x57, 0x35, 0x01, 0x5f, + 0x54, 0xb1, 0xa5, 0xdf, 0xf1, 0x9e, 0xec, 0x5d, 0x7c, 0xed, 0x1a, 0xbb, 0xe4, 0x7b, 0xde, 0xa2, 0xce, 0xf3, 0x95, + 0xaf, 0x1b, 0x55, 0xba, 0xbd, 0x97, 0xdc, 0xe0, 0xda, 0x3b, 0x6a, 0x1a, 0xeb, 0x99, 0x1f, 0x3d, 0x2c, 0x42, 0xb6, + 0xf3, 0xa1, 0xf7, 0x55, 0xf3, 0xf4, 0xac, 0xa1, 0x37, 0xa9, 0xa1, 0x0f, 0xbd, 0x28, 0xdb, 0xa7, 0xa6, 0x11, 0xbd, + 0x86, 0x0d, 0x7d, 0xe8, 0x2d, 0x39, 0x39, 0x24, 0x18, 0x9c, 0x1a, 0xf3, 0x87, 0x87, 0xd3, 0x19, 0xfe, 0x8e, 0x01, + 0x95, 0x98, 0xcc, 0xa7, 0xc7, 0xb4, 0xa3, 0x00, 0x33, 0xaa, 0xf4, 0xf6, 0xe9, 0x81, 0xed, 0x78, 0x59, 0x0f, 0x2d, + 0xbd, 0x7b, 0x72, 0x74, 0x3b, 0x5e, 0x55, 0xe3, 0x4b, 0x39, 0xe4, 0x79, 0x3e, 0x1b, 0x8d, 0x46, 0xc2, 0xa0, 0x73, + 0x57, 0x7a, 0x03, 0x2b, 0x90, 0xc1, 0x45, 0xf5, 0xa1, 0x5c, 0x7a, 0x3b, 0x75, 0x68, 0x57, 0xfe, 0x24, 0x3f, 0x1c, + 0x8a, 0x91, 0x39, 0xc6, 0x01, 0xe7, 0xa4, 0x50, 0x72, 0x94, 0xac, 0x25, 0x88, 0x4e, 0x69, 0x3c, 0x95, 0xf5, 0xda, + 0x8a, 0xc8, 0xab, 0x11, 0xf2, 0x21, 0xf8, 0xc9, 0x03, 0xb5, 0xf8, 0x33, 0x2d, 0x88, 0x3d, 0xf4, 0xa9, 0x52, 0x3a, + 0xc4, 0xab, 0x02, 0x42, 0x84, 0x01, 0x6f, 0xa0, 0x1d, 0x94, 0xe0, 0xb0, 0xc3, 0x7d, 0x40, 0x84, 0xe8, 0x37, 0x5e, + 0x3e, 0x93, 0xe1, 0xca, 0xbd, 0x41, 0x35, 0x67, 0x80, 0x58, 0xe9, 0x33, 0x70, 0xc1, 0x04, 0xd4, 0x53, 0x7c, 0x8a, + 0xfe, 0xf5, 0xe6, 0x61, 0xd3, 0xf5, 0x69, 0x09, 0xa8, 0x88, 0x9e, 0xfd, 0x7c, 0x0c, 0xe0, 0x9d, 0x5d, 0x9b, 0x91, + 0xf6, 0xf2, 0x37, 0xc0, 0xb0, 0x52, 0x92, 0x68, 0xe7, 0x94, 0x08, 0xdc, 0xf9, 0xc8, 0x96, 0x7e, 0x94, 0x02, 0x31, + 0x77, 0x3c, 0x49, 0x64, 0x0f, 0x36, 0x72, 0x02, 0xb7, 0x18, 0xf0, 0xe8, 0x00, 0x54, 0xae, 0x14, 0xe4, 0x5e, 0x73, + 0x24, 0x77, 0xfc, 0xd0, 0xfb, 0x61, 0x50, 0x0f, 0x7e, 0xe8, 0x9d, 0xa5, 0x24, 0x77, 0x84, 0x67, 0x6a, 0x4a, 0x88, + 0xf8, 0xec, 0x87, 0x41, 0x3e, 0xc0, 0xb3, 0x44, 0x8b, 0xb4, 0xc8, 0xad, 0x26, 0x6a, 0xdc, 0x84, 0x77, 0x89, 0xa4, + 0x21, 0xda, 0x76, 0x1e, 0x11, 0x37, 0x00, 0x92, 0xc5, 0x67, 0xf3, 0x86, 0xa2, 0xde, 0x4d, 0xf8, 0x16, 0xdd, 0x65, + 0xb1, 0xdf, 0xdf, 0xe4, 0x69, 0xdd, 0xd3, 0xa1, 0x32, 0xf8, 0x82, 0x54, 0x13, 0xe0, 0xd1, 0xfe, 0xca, 0x1c, 0xaf, + 0x5e, 0x6d, 0x8e, 0x94, 0x1b, 0x55, 0xa2, 0x7e, 0x8b, 0xd5, 0xac, 0x87, 0x88, 0xdc, 0x59, 0x66, 0xec, 0xed, 0x05, + 0xaf, 0xe4, 0xac, 0x8a, 0xed, 0x72, 0x7c, 0x45, 0x58, 0x5b, 0x49, 0x80, 0x8e, 0xd6, 0x63, 0x6d, 0x8a, 0x91, 0x5f, + 0x29, 0x24, 0xe0, 0xa2, 0x63, 0x6b, 0xa1, 0xd8, 0x78, 0x01, 0xfa, 0x92, 0x9d, 0x69, 0x80, 0xf5, 0x46, 0xaf, 0x22, + 0x6e, 0xcb, 0x07, 0x2a, 0xbc, 0xc9, 0x4d, 0x95, 0x59, 0xd9, 0xdc, 0xb4, 0xfb, 0xa9, 0xe2, 0x15, 0xe2, 0xd6, 0x1b, + 0xb5, 0x47, 0x01, 0x6a, 0x0f, 0x2d, 0x94, 0x01, 0xba, 0x34, 0xcd, 0x00, 0x90, 0x01, 0x40, 0xa6, 0x8a, 0xf8, 0x4c, + 0x80, 0x4a, 0x5b, 0xdd, 0x28, 0x70, 0x22, 0xbd, 0x01, 0xc6, 0x05, 0x56, 0xfa, 0xc8, 0x46, 0x06, 0x8b, 0x2d, 0x02, + 0xdc, 0x72, 0xa4, 0x0f, 0xd3, 0x70, 0xb2, 0x8d, 0xe6, 0x30, 0x49, 0xf3, 0xbb, 0x30, 0x4b, 0x25, 0xb4, 0xc4, 0x8f, + 0xb2, 0xc6, 0x88, 0x05, 0xa4, 0xef, 0xd3, 0x37, 0x45, 0x16, 0x13, 0x24, 0x9c, 0xf5, 0xd4, 0x01, 0x54, 0x93, 0x73, + 0xad, 0x69, 0xf5, 0xac, 0x36, 0x79, 0xc8, 0x02, 0x9d, 0x3d, 0x18, 0x93, 0x5a, 0x6e, 0xe8, 0x91, 0xfd, 0x95, 0xe3, + 0x19, 0xe1, 0xbb, 0x9e, 0xe1, 0xd4, 0x7f, 0xd7, 0x35, 0x90, 0x32, 0x25, 0x80, 0x20, 0x83, 0xa3, 0x09, 0xa1, 0x3c, + 0x1d, 0x93, 0xa9, 0xcd, 0x8f, 0x40, 0x38, 0x22, 0x78, 0x05, 0xcf, 0x0d, 0xad, 0x5b, 0x6e, 0xec, 0x2c, 0xf2, 0x34, + 0x01, 0x64, 0xf1, 0x82, 0xdf, 0x01, 0x32, 0xa7, 0x5e, 0x15, 0xb2, 0x67, 0xcf, 0xc5, 0x74, 0x36, 0x0f, 0xfe, 0x4c, + 0x68, 0xff, 0x62, 0xc2, 0x6f, 0xba, 0xab, 0xe4, 0xca, 0xd4, 0xba, 0x37, 0xd1, 0x63, 0x2e, 0x77, 0xfa, 0xb4, 0xe2, + 0x18, 0xf1, 0x0c, 0x56, 0x01, 0x39, 0x67, 0x43, 0xfe, 0xec, 0x1c, 0xb0, 0x5b, 0x56, 0xc2, 0x8b, 0xf8, 0xb3, 0x50, + 0x56, 0x0b, 0x90, 0x1f, 0x39, 0x8f, 0xcc, 0x2f, 0x5f, 0x6d, 0x87, 0x72, 0x4e, 0x51, 0x44, 0xcb, 0xa9, 0x69, 0x49, + 0x21, 0x3b, 0xf4, 0x14, 0x4c, 0xa6, 0xb6, 0xfc, 0x7d, 0x97, 0xb8, 0x24, 0xdf, 0x4c, 0x22, 0xfb, 0x3a, 0xc0, 0x9a, + 0xb5, 0xea, 0x1e, 0xba, 0x21, 0x18, 0x20, 0x32, 0x42, 0x99, 0xcd, 0xf5, 0xdd, 0x7a, 0x30, 0x50, 0x30, 0xbf, 0x82, + 0x6e, 0x5a, 0x74, 0x8a, 0x03, 0xe4, 0xac, 0x75, 0x8d, 0x4a, 0x55, 0x71, 0xe8, 0x30, 0xef, 0x96, 0x55, 0xd9, 0x65, + 0xe9, 0x85, 0x20, 0x35, 0xea, 0x2a, 0x58, 0xa4, 0x54, 0x44, 0xf1, 0x9e, 0xfc, 0x1a, 0x98, 0x78, 0x66, 0xe5, 0x28, + 0x8d, 0xe7, 0x80, 0x18, 0xa4, 0x80, 0x38, 0xe5, 0x57, 0x80, 0x26, 0xba, 0x88, 0xc2, 0xec, 0x4d, 0x5c, 0x05, 0xb5, + 0xd5, 0xf4, 0x7b, 0x07, 0x32, 0xf6, 0xbc, 0xee, 0xf7, 0x53, 0x62, 0xf4, 0xc3, 0x28, 0x0c, 0xfc, 0x7b, 0x3c, 0xdd, + 0x37, 0x41, 0x6a, 0x5e, 0xf9, 0x13, 0x5e, 0xd1, 0xe5, 0xd6, 0xa6, 0x5c, 0xd1, 0xb8, 0xf0, 0xd7, 0x08, 0x0e, 0x9f, + 0x3a, 0x8a, 0xed, 0x36, 0x55, 0x4e, 0x6d, 0x0c, 0x06, 0x21, 0xdc, 0xb7, 0x32, 0x7e, 0x9f, 0x78, 0xf9, 0x2c, 0x9a, + 0x83, 0xa2, 0x34, 0xd3, 0x7c, 0x21, 0x85, 0x74, 0x13, 0xa0, 0x8f, 0x06, 0xa1, 0x56, 0x57, 0x5e, 0x27, 0x5e, 0xaa, + 0xa6, 0xb5, 0x79, 0x8a, 0x35, 0x0a, 0xc4, 0x2c, 0x9a, 0x37, 0x2c, 0xa3, 0x43, 0x52, 0x5d, 0x2e, 0x4d, 0x33, 0xae, + 0xad, 0x66, 0xa8, 0x56, 0x1c, 0x35, 0x41, 0x8d, 0xd2, 0x35, 0x5c, 0x00, 0x7f, 0xa6, 0x3b, 0x8e, 0x6a, 0x14, 0x29, + 0x1a, 0xf0, 0x09, 0x62, 0xc4, 0x9a, 0xcd, 0x13, 0xd6, 0x9a, 0xba, 0x66, 0xf4, 0xfb, 0x32, 0x64, 0xc8, 0x24, 0x21, + 0x4f, 0x1f, 0x2e, 0xd7, 0x8f, 0xa4, 0xba, 0x00, 0x7e, 0xe5, 0x8a, 0xcd, 0x7a, 0xbd, 0x39, 0xc0, 0xf5, 0xc2, 0xfa, + 0x85, 0x8d, 0x2b, 0x38, 0xbf, 0x24, 0xf8, 0x5d, 0xf5, 0x23, 0xcc, 0x32, 0xa8, 0x02, 0x32, 0xfe, 0x58, 0x28, 0xea, + 0x79, 0x8b, 0xd9, 0x7d, 0xa4, 0x2e, 0x28, 0xb3, 0x74, 0x6e, 0x71, 0x82, 0x80, 0xf3, 0xb0, 0x7a, 0x02, 0xc9, 0xbe, + 0x7c, 0xec, 0xd3, 0x8c, 0x02, 0xd5, 0x11, 0xe0, 0xb3, 0x59, 0x3f, 0x84, 0xfd, 0x03, 0x22, 0x0b, 0xf5, 0x37, 0xdf, + 0xca, 0x59, 0x43, 0xf2, 0x40, 0xaa, 0xb9, 0x8f, 0xe1, 0xd4, 0xb8, 0xc1, 0x97, 0x6e, 0x7a, 0x53, 0xc1, 0x6b, 0x42, + 0xe6, 0xbe, 0x41, 0x6b, 0xdf, 0x0d, 0x1c, 0x21, 0x82, 0xcb, 0x28, 0xc5, 0x69, 0x6f, 0xd7, 0x0b, 0x90, 0xdb, 0xdc, + 0x82, 0xbc, 0x7e, 0xe9, 0xe2, 0x17, 0xa7, 0x48, 0xcf, 0xa2, 0x0b, 0x0c, 0x74, 0x41, 0xe6, 0x8d, 0x7f, 0x56, 0xb0, + 0x72, 0x01, 0xbd, 0x97, 0x8a, 0x95, 0x9c, 0x6c, 0x3b, 0xf5, 0x47, 0xa9, 0xec, 0xb7, 0x67, 0xd6, 0x04, 0x7e, 0x9f, + 0xd8, 0x2f, 0x91, 0xc9, 0x37, 0x3d, 0x36, 0xf9, 0xca, 0xb0, 0xe8, 0xd4, 0x32, 0x38, 0xa7, 0x47, 0x06, 0xe7, 0xde, + 0xce, 0xaa, 0x4d, 0x08, 0x43, 0x41, 0x12, 0x68, 0xba, 0xf0, 0xb0, 0x6e, 0xfa, 0xf3, 0x93, 0x16, 0xd5, 0x56, 0xed, + 0x5b, 0xf7, 0xe3, 0x10, 0xbb, 0xf8, 0x7d, 0xe2, 0x19, 0x22, 0x52, 0x1f, 0xe8, 0xc0, 0x64, 0xf0, 0xc4, 0x65, 0xbf, + 0x0f, 0x85, 0xcd, 0xc6, 0xf3, 0x51, 0x5d, 0xfc, 0x52, 0xdc, 0x03, 0xaa, 0x43, 0x05, 0x76, 0x39, 0x94, 0xa1, 0x8c, + 0xd8, 0xd4, 0x96, 0x7b, 0xfe, 0x78, 0x19, 0xe6, 0x20, 0xef, 0x68, 0x78, 0x9c, 0x33, 0x10, 0xc3, 0xe0, 0xeb, 0x3f, + 0x3c, 0xda, 0xa7, 0xcd, 0x0f, 0x67, 0xf0, 0xdd, 0xd1, 0xd9, 0x07, 0xa4, 0xbb, 0x39, 0x5b, 0x97, 0xc5, 0x5d, 0x1a, + 0x8b, 0xb3, 0x1f, 0x20, 0xf5, 0x87, 0xb3, 0xa2, 0x3c, 0xfb, 0x41, 0x55, 0xe6, 0x87, 0x33, 0x5a, 0x70, 0xa3, 0x3f, + 0xac, 0x89, 0xf7, 0x7b, 0xa5, 0x19, 0xd0, 0x16, 0x10, 0x99, 0xa5, 0xd5, 0x8f, 0xa0, 0x44, 0x54, 0xfc, 0xa8, 0x32, + 0xaa, 0xd5, 0xda, 0x71, 0x3e, 0x24, 0x1a, 0x29, 0x9b, 0x26, 0x24, 0xae, 0x96, 0xb0, 0x0e, 0xf5, 0xec, 0xb4, 0xf9, + 0x76, 0x9c, 0x07, 0xea, 0x80, 0xc8, 0xf9, 0xb3, 0x7c, 0xb4, 0xa5, 0xaf, 0xc1, 0xb7, 0x0e, 0x87, 0x7c, 0xb4, 0x33, + 0x3f, 0x7d, 0xb2, 0x56, 0xca, 0xb8, 0x23, 0x45, 0x2e, 0x84, 0x9c, 0x71, 0xdb, 0x1e, 0x03, 0x0e, 0x00, 0xff, 0x70, + 0xa0, 0xdf, 0x3b, 0xf9, 0x5b, 0xed, 0x96, 0x56, 0x3d, 0x1f, 0xb5, 0xb8, 0x33, 0xde, 0xd4, 0x86, 0xa8, 0x6d, 0x2f, + 0xb1, 0xa5, 0xf7, 0x4d, 0x83, 0x9a, 0x22, 0xfa, 0x09, 0xab, 0x89, 0x55, 0x1c, 0x16, 0xa4, 0x84, 0x24, 0x86, 0x63, + 0xb4, 0x43, 0x8f, 0xd3, 0xc5, 0xd2, 0x93, 0xfb, 0x0e, 0x2f, 0xb7, 0xbe, 0x0f, 0x48, 0x5a, 0x85, 0xf3, 0x0f, 0x5e, + 0x68, 0xe0, 0xd1, 0x8b, 0xbc, 0x2a, 0x32, 0x31, 0x12, 0x34, 0xca, 0x6f, 0x48, 0x9c, 0x39, 0xc3, 0x5a, 0x9c, 0x29, + 0xb0, 0xb0, 0x90, 0xd0, 0xbd, 0x8b, 0x92, 0xd2, 0x83, 0xb3, 0x47, 0xfb, 0xb2, 0xf9, 0x83, 0xe0, 0x21, 0x46, 0x37, + 0xc0, 0x88, 0xb3, 0x6b, 0x97, 0x77, 0x1f, 0x96, 0xb9, 0xf7, 0xc7, 0x9b, 0x65, 0x5e, 0x40, 0x88, 0xe6, 0x99, 0x54, + 0xac, 0x96, 0x67, 0xc0, 0x98, 0x27, 0xe2, 0xb3, 0xb0, 0x92, 0xd3, 0xa0, 0xea, 0x28, 0x56, 0x6f, 0xe3, 0xb9, 0x07, + 0x14, 0xdf, 0x1f, 0x12, 0xe0, 0x72, 0xf7, 0xd9, 0x6b, 0xe5, 0x9a, 0x4a, 0x7a, 0xe4, 0x39, 0x44, 0x4b, 0xbe, 0x4c, + 0x80, 0xe2, 0x19, 0xe2, 0x24, 0x85, 0xd5, 0x73, 0x13, 0xa4, 0x22, 0x5f, 0x9f, 0x50, 0x7c, 0xd1, 0x3c, 0x8a, 0x1a, + 0x16, 0xb2, 0x04, 0x8e, 0x87, 0x64, 0x96, 0xcd, 0x91, 0xa5, 0x3c, 0x6d, 0x4f, 0x91, 0x8e, 0x4e, 0x2c, 0xf1, 0xdb, + 0x9a, 0x5f, 0x2f, 0x52, 0x11, 0x98, 0xb4, 0xb3, 0x95, 0xb9, 0x17, 0xc2, 0x50, 0x25, 0xdc, 0x7b, 0x53, 0xcf, 0x42, + 0xb9, 0x29, 0x5a, 0x15, 0xb3, 0x87, 0x29, 0x31, 0xc3, 0x14, 0xeb, 0x2f, 0x6c, 0xf8, 0xdb, 0xc4, 0x8b, 0xc1, 0x70, + 0xbd, 0xe0, 0xe5, 0x6c, 0x63, 0x16, 0xc2, 0xe1, 0xb0, 0x99, 0x14, 0xb3, 0x05, 0x84, 0xb9, 0x2e, 0xe6, 0x87, 0x43, + 0x57, 0xcb, 0xd6, 0xc2, 0x83, 0x87, 0xaa, 0x85, 0x9b, 0x86, 0xe5, 0xf0, 0x33, 0x99, 0xc5, 0xd8, 0xbe, 0xc6, 0x67, + 0xf6, 0xe7, 0x8b, 0xee, 0x59, 0x82, 0xe4, 0x1b, 0x6b, 0xa0, 0x1d, 0x9b, 0xb5, 0x3b, 0x5c, 0x8d, 0x80, 0xa4, 0x74, + 0x37, 0xfa, 0xbb, 0xb2, 0x93, 0xa7, 0x04, 0xb9, 0xa3, 0x15, 0xd8, 0xef, 0xbe, 0xf1, 0x27, 0x5a, 0xec, 0x41, 0xbb, + 0x8d, 0x2d, 0x21, 0xaa, 0x69, 0xcf, 0xe5, 0x4a, 0xb1, 0x34, 0x6f, 0xa5, 0x8d, 0x9e, 0x0f, 0xeb, 0x73, 0xdf, 0xc8, + 0x81, 0x82, 0x31, 0xe2, 0xa9, 0x75, 0x10, 0xcd, 0xe6, 0x40, 0x83, 0x81, 0xe6, 0x11, 0x9e, 0x5a, 0xe8, 0xa0, 0xcc, + 0xda, 0xb0, 0x9f, 0x27, 0x27, 0xcb, 0xe3, 0xf0, 0x2d, 0xfc, 0xcb, 0x67, 0xd8, 0x24, 0xa6, 0xd8, 0x1e, 0xff, 0xaa, + 0x14, 0x15, 0x1e, 0xdb, 0x11, 0xd7, 0xda, 0xb5, 0xa8, 0x0d, 0x95, 0xc3, 0xbf, 0x84, 0x7d, 0x84, 0xfd, 0x85, 0x26, + 0x08, 0x83, 0x5d, 0x7f, 0x26, 0x10, 0x22, 0x16, 0xe2, 0x05, 0xff, 0xaa, 0x24, 0x15, 0x9d, 0xf0, 0xd9, 0xae, 0x04, + 0xde, 0x3a, 0x0c, 0xe8, 0x13, 0xf2, 0x33, 0x91, 0x30, 0x34, 0x13, 0x7a, 0x47, 0xff, 0x9d, 0xd8, 0xc9, 0x26, 0xb9, + 0x15, 0xf2, 0x81, 0xa4, 0x92, 0x60, 0x82, 0x95, 0x17, 0xca, 0x1f, 0xdd, 0x0b, 0xa5, 0xd6, 0x5a, 0xd0, 0xfa, 0xe5, + 0xcf, 0x13, 0xcf, 0xe0, 0xef, 0x81, 0x8c, 0x41, 0xb7, 0x11, 0xd5, 0x24, 0xc7, 0xf4, 0x51, 0x3a, 0xcf, 0x40, 0x05, + 0x74, 0xb6, 0xce, 0xc2, 0x7a, 0x51, 0x94, 0xab, 0x56, 0xa4, 0xa8, 0x2c, 0x7d, 0xa4, 0x1e, 0x63, 0x5e, 0x98, 0x27, + 0x27, 0xf2, 0xc1, 0x23, 0x00, 0xc6, 0xa3, 0x3c, 0xad, 0x3a, 0x4a, 0xeb, 0x07, 0x96, 0x01, 0x23, 0x70, 0xa2, 0x0c, + 0x78, 0x84, 0x65, 0x60, 0x9e, 0x76, 0x19, 0x6a, 0x10, 0x6b, 0x54, 0x5d, 0xa9, 0x0d, 0xe6, 0x44, 0x51, 0xf2, 0x29, + 0x96, 0x56, 0x18, 0x43, 0x53, 0x57, 0x1e, 0x59, 0x2f, 0x39, 0x61, 0x4f, 0x76, 0x03, 0xe9, 0x16, 0x36, 0x0a, 0x67, + 0xd0, 0xb5, 0x2c, 0x51, 0x2e, 0xba, 0x65, 0x44, 0x99, 0x08, 0xa9, 0x9f, 0x3d, 0x9c, 0x69, 0xb5, 0xdf, 0xd8, 0x49, + 0xfb, 0xf6, 0x48, 0xd1, 0x0b, 0x06, 0xed, 0xd3, 0x1e, 0x29, 0xf5, 0xac, 0x91, 0xcb, 0xc0, 0x96, 0x2e, 0x55, 0x3d, + 0xff, 0x05, 0xca, 0x77, 0x30, 0x33, 0xce, 0x66, 0x7f, 0xe8, 0xcd, 0xed, 0xd1, 0xbe, 0x6e, 0xfe, 0x60, 0xbd, 0x1e, + 0x6c, 0x0d, 0x32, 0xf1, 0xb9, 0x62, 0xa1, 0xb2, 0x0a, 0xb1, 0x82, 0xb4, 0xff, 0x25, 0xbc, 0x3f, 0xe0, 0xad, 0x11, + 0x9a, 0x95, 0xf1, 0x30, 0x1f, 0x3d, 0xda, 0x8b, 0xe6, 0x8f, 0xce, 0xb2, 0xad, 0x5c, 0x95, 0xcc, 0xf6, 0xc7, 0x51, + 0xd2, 0x9c, 0x3d, 0x5c, 0x23, 0xa9, 0x03, 0x7c, 0xb8, 0x3e, 0xc3, 0x07, 0x2a, 0xa1, 0xd4, 0x82, 0xaa, 0x06, 0xad, + 0x8f, 0xfd, 0xd1, 0x7a, 0x4e, 0x1f, 0x3f, 0x96, 0xd3, 0x2d, 0x29, 0xc2, 0xf8, 0x81, 0xc1, 0x94, 0x9d, 0x38, 0x75, + 0xc9, 0x9b, 0x21, 0xbd, 0xeb, 0x56, 0x49, 0x5d, 0xf6, 0x28, 0x11, 0x84, 0x3a, 0x58, 0xbf, 0xd8, 0x0f, 0x61, 0x66, + 0x8b, 0xfe, 0xb0, 0x59, 0xcd, 0x09, 0x10, 0x11, 0xd0, 0x5a, 0xe5, 0x7d, 0xe0, 0x98, 0x2f, 0xcc, 0x9a, 0x1b, 0xd2, + 0xad, 0x37, 0x57, 0xda, 0x2b, 0x29, 0xa0, 0x9f, 0x83, 0xcc, 0xed, 0xa3, 0x5b, 0xae, 0x5a, 0xe6, 0xb9, 0xb4, 0xe5, + 0x80, 0x45, 0x0b, 0x81, 0x9a, 0x9d, 0x4b, 0x87, 0x03, 0x05, 0xa1, 0xae, 0x44, 0x15, 0x71, 0x75, 0x14, 0x2d, 0x44, + 0xad, 0x56, 0xed, 0x72, 0xb2, 0xa9, 0x90, 0x2d, 0x89, 0x20, 0xa3, 0x14, 0x43, 0x97, 0x3e, 0xca, 0xd5, 0x9e, 0x69, + 0x38, 0x40, 0x13, 0xb0, 0x69, 0x83, 0xbf, 0x05, 0xee, 0x65, 0x70, 0x66, 0xda, 0xa7, 0x61, 0x04, 0x9c, 0xe6, 0x10, + 0xf3, 0xe7, 0x77, 0x3d, 0xa8, 0xe0, 0x41, 0x47, 0xfa, 0x9b, 0x7a, 0x56, 0xe0, 0x99, 0x7b, 0xe2, 0xf9, 0xeb, 0x13, + 0xe9, 0x45, 0x0e, 0x0f, 0x34, 0x0d, 0x62, 0xc6, 0x9f, 0x97, 0x65, 0xb8, 0x1b, 0x2d, 0xca, 0x62, 0xe5, 0x45, 0x7a, + 0x1f, 0xcf, 0xa4, 0x18, 0x48, 0xcc, 0x98, 0x19, 0x5d, 0xc5, 0x3a, 0xce, 0x61, 0xdc, 0xdb, 0x93, 0xb0, 0x42, 0xfb, + 0x67, 0x89, 0xbd, 0x2e, 0x00, 0xcb, 0x21, 0x6b, 0xd0, 0x0a, 0xef, 0x74, 0x7b, 0xbb, 0xc7, 0x25, 0x3b, 0x8a, 0x1b, + 0x40, 0x3f, 0xab, 0xa1, 0x65, 0x82, 0x5a, 0x66, 0xdd, 0xc9, 0x64, 0x8a, 0xe4, 0xf2, 0x6d, 0xd8, 0x6b, 0x56, 0xe4, + 0xf3, 0x46, 0x6e, 0x0f, 0xef, 0xc2, 0x95, 0x88, 0xb5, 0x05, 0x9d, 0x74, 0x64, 0x1c, 0xee, 0x85, 0xe6, 0x46, 0xba, + 0x7f, 0x54, 0x25, 0x61, 0x29, 0x62, 0xb8, 0x05, 0xb2, 0xbd, 0xda, 0x56, 0x82, 0x12, 0xf8, 0x60, 0x3f, 0x94, 0x62, + 0x91, 0x6e, 0x05, 0xe0, 0x3a, 0xf0, 0xcf, 0x12, 0x91, 0xd0, 0xdd, 0x79, 0x88, 0x62, 0x8d, 0xbc, 0x6f, 0x10, 0x8d, + 0xfd, 0x15, 0xc8, 0x69, 0x40, 0x26, 0x52, 0x8c, 0x64, 0xc1, 0xc0, 0x07, 0x90, 0xf3, 0x35, 0x98, 0xe4, 0xa6, 0xb9, + 0xe7, 0x07, 0xb9, 0xee, 0x60, 0xda, 0x07, 0xdd, 0x8b, 0x6b, 0xcd, 0x72, 0xf0, 0x8a, 0x89, 0xf8, 0xcf, 0xb5, 0x57, + 0xb2, 0x9c, 0x65, 0x7e, 0x63, 0x2e, 0x3a, 0x19, 0x5c, 0x35, 0x84, 0x5f, 0xcc, 0xb2, 0x39, 0x8f, 0x66, 0x99, 0x8e, + 0xfa, 0x2f, 0x9a, 0xa3, 0x52, 0x00, 0x4e, 0x1d, 0x2f, 0xc0, 0x1a, 0xfa, 0x4a, 0x37, 0xad, 0x78, 0xa0, 0x31, 0x46, + 0x41, 0x85, 0x0e, 0x42, 0x3f, 0xd7, 0x80, 0xb4, 0xc1, 0x24, 0x4d, 0x42, 0xe5, 0x83, 0x0b, 0xba, 0x61, 0x5e, 0xae, + 0x5c, 0xae, 0x9a, 0x54, 0x2d, 0xbf, 0x1c, 0x51, 0xdf, 0xd5, 0x92, 0x4b, 0xb5, 0xf9, 0xd4, 0x28, 0x6b, 0x04, 0x99, + 0x1c, 0xa5, 0xdf, 0xa7, 0x5c, 0xb8, 0x95, 0x31, 0x59, 0x1f, 0x0e, 0x5e, 0xc1, 0x4d, 0x8d, 0xdf, 0xe4, 0x44, 0x28, + 0x6a, 0x0f, 0x89, 0xb0, 0xb5, 0x5b, 0xa1, 0x7b, 0x8f, 0x1b, 0xa5, 0x79, 0x94, 0x6d, 0x62, 0x51, 0x79, 0xbd, 0x04, + 0xac, 0xc5, 0x3d, 0xe0, 0x45, 0xa5, 0xa5, 0x5f, 0xb1, 0x02, 0xd0, 0x03, 0xa4, 0xb0, 0xf1, 0x06, 0x19, 0xb0, 0x3e, + 0x78, 0xa9, 0xdf, 0xef, 0x1b, 0x53, 0xfe, 0xfb, 0xfb, 0x1c, 0x48, 0x0a, 0x45, 0x59, 0xef, 0x60, 0x02, 0xc1, 0xb5, + 0x93, 0xb4, 0x67, 0x35, 0x7f, 0xb6, 0xae, 0x3d, 0xe0, 0xb7, 0xf2, 0x2d, 0x12, 0xab, 0x57, 0xf6, 0xc5, 0x66, 0x9f, + 0x56, 0xd7, 0x46, 0xe3, 0x20, 0x58, 0x5a, 0xbd, 0xd1, 0x2a, 0x87, 0xbc, 0xe1, 0x05, 0x88, 0x54, 0xd6, 0xd5, 0xb5, + 0x72, 0xae, 0xae, 0x05, 0x47, 0x2e, 0xd9, 0x92, 0xe7, 0xf0, 0x5f, 0xc8, 0xbd, 0xf2, 0x70, 0x28, 0xfc, 0x7e, 0x3f, + 0x9d, 0x91, 0x56, 0x16, 0xd8, 0xd3, 0xd6, 0xb5, 0x17, 0xfa, 0x87, 0xc3, 0x1b, 0xf0, 0x1a, 0xf1, 0x0f, 0x87, 0xb2, + 0xdf, 0xff, 0x68, 0x6e, 0x32, 0xe7, 0x63, 0xa5, 0x94, 0xbd, 0x44, 0xa5, 0xfb, 0xa7, 0x84, 0xf7, 0xfe, 0xf7, 0xe8, + 0x7f, 0x8f, 0x2e, 0x7b, 0xb2, 0xeb, 0x7f, 0x49, 0xf8, 0x0c, 0x6f, 0xe8, 0x4c, 0x5d, 0xce, 0x99, 0x74, 0x77, 0x57, + 0x7e, 0xe8, 0x3d, 0x0d, 0x15, 0xdf, 0x9b, 0x9b, 0x36, 0xfe, 0x5c, 0x1d, 0x69, 0x12, 0x3a, 0x2e, 0xfa, 0x87, 0xc3, + 0x2f, 0x89, 0xd6, 0xa7, 0xa5, 0x4a, 0x9f, 0xa6, 0x70, 0x94, 0x0c, 0xb9, 0x9b, 0x5b, 0x98, 0x0e, 0xec, 0xc7, 0xcd, + 0x57, 0xc9, 0x8b, 0xb3, 0x14, 0xae, 0xbd, 0xf9, 0x2c, 0x9d, 0x4f, 0xc1, 0xba, 0x32, 0xcc, 0x67, 0xf5, 0x3c, 0x80, + 0xd4, 0x21, 0xa4, 0x59, 0xd3, 0xf0, 0x1f, 0x95, 0x2b, 0x78, 0x6b, 0x8f, 0x77, 0x03, 0x17, 0xa5, 0x8e, 0xf4, 0x49, + 0x1b, 0x4d, 0x97, 0x54, 0xf2, 0x1f, 0x45, 0x1e, 0x63, 0xcc, 0xc6, 0x1b, 0xe2, 0xfd, 0x2c, 0xf2, 0x97, 0x05, 0x60, + 0x17, 0x01, 0x18, 0x72, 0x3a, 0x77, 0x24, 0xf1, 0x8f, 0xc9, 0xf7, 0x7f, 0x4c, 0x97, 0xf6, 0xa1, 0x2c, 0x96, 0xa5, + 0xa8, 0xaa, 0xa3, 0xd2, 0xb6, 0xb6, 0x5c, 0x0f, 0x4c, 0xa2, 0xfd, 0xbe, 0x64, 0x12, 0x4d, 0x31, 0x14, 0x05, 0x6e, + 0x8d, 0xbd, 0x69, 0xca, 0x15, 0x63, 0xf5, 0xc8, 0x58, 0x3f, 0x5f, 0xec, 0xde, 0xc4, 0x5e, 0xea, 0x07, 0x29, 0x08, + 0xc2, 0x1a, 0x4a, 0x29, 0x45, 0x3e, 0x38, 0x9f, 0x61, 0x2a, 0x51, 0xeb, 0x52, 0xaa, 0xfc, 0x61, 0xa4, 0xf9, 0x30, + 0x05, 0xbd, 0xec, 0xbf, 0x2a, 0x98, 0xff, 0xba, 0x3d, 0x58, 0x9f, 0xd6, 0x65, 0x1a, 0x55, 0x44, 0x95, 0x17, 0xa6, + 0xda, 0x04, 0x22, 0xf8, 0x33, 0x61, 0xf1, 0xfd, 0xfa, 0xe4, 0x48, 0xd0, 0x98, 0xc9, 0xf2, 0xfa, 0xc8, 0xfd, 0xc2, + 0xbe, 0x72, 0x1d, 0xcf, 0xff, 0xdc, 0xcc, 0xff, 0x01, 0x3a, 0x43, 0x16, 0xcf, 0xb8, 0x65, 0xb0, 0xc0, 0xd9, 0x2f, + 0x5d, 0x3d, 0xe0, 0x6f, 0xe6, 0x89, 0x67, 0x40, 0xc7, 0xfc, 0x0c, 0x5d, 0x15, 0xd3, 0x59, 0x31, 0x00, 0x2e, 0x5b, + 0xbf, 0xb1, 0xe6, 0xc4, 0x3b, 0x8b, 0xf2, 0x4a, 0x2e, 0x08, 0x7d, 0x5d, 0x85, 0xd9, 0xb8, 0x2a, 0x36, 0x95, 0x28, + 0x36, 0x75, 0x8f, 0xd4, 0xb2, 0xf9, 0xb4, 0xb6, 0x15, 0xb2, 0x7f, 0x17, 0x2d, 0x06, 0x2f, 0xc3, 0x3a, 0x19, 0x65, + 0xe9, 0x7a, 0x0a, 0xfc, 0x7a, 0x01, 0x9c, 0x45, 0xe6, 0x95, 0xaf, 0xce, 0x1e, 0xb0, 0x45, 0xe3, 0x29, 0x90, 0xa3, + 0xd2, 0x1f, 0x79, 0x63, 0x74, 0x7a, 0xa2, 0xdf, 0xcf, 0xa7, 0x14, 0xf3, 0xf5, 0x77, 0x80, 0xe7, 0xaa, 0xe5, 0x02, + 0xf4, 0x65, 0xa8, 0x83, 0x4a, 0x94, 0x5a, 0x31, 0x8c, 0x58, 0xf8, 0xbb, 0x40, 0x22, 0x67, 0x0a, 0x6c, 0x56, 0x51, + 0x12, 0x2a, 0x51, 0x29, 0xd9, 0x9a, 0xa0, 0x96, 0xde, 0x17, 0x65, 0xbd, 0xaf, 0xc0, 0x51, 0x32, 0xd2, 0x66, 0x39, + 0x69, 0xc6, 0x15, 0x28, 0x73, 0xd1, 0x0f, 0xf6, 0xf7, 0xca, 0xf3, 0x1b, 0x99, 0xcf, 0x72, 0xdf, 0xd1, 0x39, 0x6d, + 0xc7, 0x05, 0xca, 0xdc, 0x72, 0xda, 0x6a, 0xc9, 0x63, 0xf2, 0x9e, 0x85, 0xda, 0xb2, 0x04, 0x29, 0x16, 0x61, 0x3e, + 0xa1, 0xca, 0xe6, 0x5f, 0x10, 0x6a, 0x8b, 0x03, 0x7b, 0xec, 0xc2, 0x44, 0xfc, 0xb7, 0x60, 0x49, 0x0c, 0xb3, 0x52, + 0x84, 0xf1, 0x0e, 0xbc, 0x7f, 0x36, 0x95, 0x18, 0x9d, 0xa1, 0x93, 0xfb, 0xd9, 0x7d, 0x5a, 0x27, 0x67, 0x6f, 0x5e, + 0x9d, 0xfd, 0xd0, 0x1b, 0x14, 0xa3, 0x34, 0x1e, 0xf4, 0x7e, 0x38, 0x5b, 0x6d, 0x00, 0x2d, 0x53, 0x9c, 0xc5, 0x64, + 0x4a, 0x13, 0xf1, 0x19, 0x19, 0x06, 0xcf, 0xea, 0x44, 0x9c, 0xd1, 0xc4, 0x74, 0x5f, 0xa3, 0x34, 0xf9, 0x76, 0x14, + 0xe6, 0xf0, 0x72, 0x29, 0x36, 0x95, 0x88, 0xc1, 0x4e, 0xa9, 0xe6, 0x59, 0xde, 0x3e, 0x8b, 0xf3, 0x51, 0x87, 0xac, + 0xd2, 0x81, 0xbf, 0x3d, 0x91, 0x76, 0x55, 0xba, 0x02, 0x42, 0x0f, 0x80, 0x93, 0xae, 0xfc, 0x79, 0x38, 0xa4, 0x09, + 0x84, 0x5a, 0x30, 0x27, 0xd3, 0x88, 0x6e, 0x48, 0x2f, 0xb1, 0xcf, 0xc0, 0x2c, 0xa4, 0x34, 0x0f, 0x6e, 0xae, 0x16, + 0x43, 0x77, 0xc5, 0xca, 0x51, 0x58, 0xad, 0x45, 0x54, 0x23, 0xeb, 0x31, 0x38, 0xef, 0x40, 0x04, 0x80, 0x22, 0x07, + 0xcf, 0x78, 0xd4, 0xef, 0x47, 0x2a, 0x28, 0x27, 0xa1, 0x5f, 0x14, 0xfa, 0xa5, 0xe1, 0x28, 0x63, 0xfe, 0x25, 0xd4, + 0x1c, 0x01, 0xf5, 0x96, 0x87, 0x8a, 0x2e, 0x00, 0x97, 0x73, 0xc4, 0x8c, 0xf3, 0xde, 0xff, 0xe1, 0xed, 0x4b, 0xb8, + 0xdb, 0xb6, 0xb5, 0x75, 0xff, 0x8a, 0xc5, 0x97, 0xaa, 0x44, 0x04, 0xc9, 0x92, 0x93, 0xf4, 0x9c, 0x52, 0x86, 0x75, + 0xdd, 0x0c, 0x6d, 0x7a, 0x9a, 0xa1, 0x71, 0xd2, 0x49, 0x4f, 0xd7, 0xa5, 0x49, 0xd8, 0x62, 0x43, 0x03, 0x2a, 0x49, + 0x79, 0x88, 0xc4, 0xff, 0xfe, 0xd6, 0xde, 0x18, 0x49, 0xd1, 0x4e, 0xce, 0x79, 0xf7, 0xbd, 0x95, 0xb5, 0x62, 0x11, + 0x04, 0x31, 0x63, 0x63, 0x63, 0x0f, 0xdf, 0x66, 0x4d, 0x60, 0x4e, 0x13, 0x82, 0xc2, 0x5c, 0x07, 0x0b, 0x03, 0x40, + 0xef, 0xda, 0xa3, 0x2d, 0x27, 0x5d, 0x82, 0xc5, 0x73, 0x03, 0x8b, 0x57, 0x17, 0x8b, 0xea, 0x92, 0x6b, 0xb9, 0x85, + 0x4d, 0x29, 0xab, 0x18, 0x02, 0x08, 0x34, 0x63, 0x86, 0xdd, 0x70, 0x97, 0x23, 0x59, 0x17, 0x05, 0x17, 0x3b, 0x81, + 0xa1, 0x9b, 0x71, 0xc9, 0xcc, 0xc1, 0xd5, 0x0c, 0xeb, 0xa4, 0xa2, 0x00, 0xbb, 0xba, 0x00, 0xd9, 0x0b, 0x43, 0x5d, + 0x37, 0xb3, 0xe5, 0x3a, 0xf0, 0x75, 0xe9, 0xc2, 0x97, 0x14, 0xbc, 0x5c, 0x49, 0x51, 0x66, 0x57, 0xfc, 0x27, 0xfb, + 0xb2, 0x19, 0x4b, 0x0a, 0xed, 0x48, 0x5f, 0xb5, 0xbb, 0xa3, 0xc5, 0x38, 0xb6, 0x1c, 0xdf, 0x52, 0xe9, 0x46, 0x8f, + 0xaa, 0x17, 0x42, 0x5b, 0xe7, 0x5a, 0x66, 0x69, 0xca, 0xc5, 0x4b, 0x91, 0x66, 0x89, 0x97, 0x1c, 0xeb, 0x58, 0xd5, + 0x2e, 0x08, 0x96, 0x0b, 0x93, 0xfc, 0x2c, 0x2b, 0x31, 0x76, 0x70, 0xa3, 0x51, 0xad, 0xa8, 0x53, 0x26, 0x06, 0x86, + 0x7c, 0x87, 0xc1, 0xb7, 0x99, 0x4c, 0x80, 0xe1, 0xc7, 0x44, 0x7d, 0x49, 0x4f, 0x21, 0xe0, 0x83, 0x0a, 0xcd, 0xfd, + 0x8c, 0x23, 0xf8, 0xb5, 0x55, 0x99, 0x03, 0x93, 0xad, 0x55, 0x90, 0x88, 0x7b, 0x97, 0xcd, 0xf5, 0x22, 0x5a, 0xa8, + 0xbb, 0x50, 0x2f, 0xde, 0x6e, 0x7b, 0x89, 0xa2, 0x03, 0x4e, 0x7e, 0x1a, 0xbc, 0x88, 0xb3, 0x9c, 0xa7, 0x7b, 0x95, + 0xdc, 0x53, 0x1b, 0x6a, 0x4f, 0x39, 0x73, 0xc0, 0xce, 0xfb, 0xba, 0xda, 0xd3, 0x6b, 0x7a, 0x4f, 0xb7, 0x73, 0x0f, + 0x2e, 0x18, 0xb8, 0x73, 0x2f, 0xb2, 0x2b, 0x2e, 0xf6, 0x40, 0x19, 0x68, 0x8d, 0x07, 0xea, 0xb2, 0x1a, 0xa9, 0x89, + 0xd1, 0x31, 0xac, 0x13, 0x7d, 0x30, 0x07, 0xf4, 0x67, 0x08, 0x6b, 0xdf, 0x7a, 0xbb, 0xd2, 0x07, 0x6d, 0x40, 0xdf, + 0x2d, 0x4d, 0x1f, 0x74, 0xe0, 0x78, 0x15, 0x1d, 0xb8, 0x31, 0xa4, 0x1a, 0xb4, 0xd5, 0xc8, 0x2a, 0x50, 0xbc, 0xe1, + 0x2d, 0xde, 0x9d, 0x6b, 0xc9, 0xc6, 0x7b, 0x89, 0x18, 0x5f, 0x99, 0xa8, 0xe2, 0x4c, 0x1c, 0x7b, 0xa9, 0xbc, 0xd6, + 0x4e, 0x32, 0xc2, 0xf8, 0x96, 0x95, 0xd4, 0xdf, 0x21, 0xe6, 0x16, 0x69, 0x0e, 0x83, 0xe7, 0x61, 0x45, 0x66, 0xbc, + 0xdf, 0x97, 0x33, 0x19, 0x95, 0x33, 0xb1, 0x5f, 0x46, 0x0a, 0xac, 0xed, 0x2e, 0x11, 0xd0, 0xbd, 0x12, 0x20, 0x5f, + 0x00, 0x54, 0xdd, 0x27, 0xfc, 0xb9, 0x4f, 0xea, 0xd3, 0x29, 0xf4, 0x29, 0xb4, 0xf5, 0x8a, 0x2b, 0x88, 0x57, 0x75, + 0x63, 0x64, 0x1b, 0x15, 0xb4, 0x78, 0x2c, 0xcf, 0x6a, 0xc3, 0xd8, 0x9c, 0x5a, 0xff, 0x7a, 0xb3, 0xc1, 0x94, 0xcd, + 0x85, 0x5a, 0x85, 0x21, 0x89, 0x3e, 0x96, 0x5e, 0x24, 0x11, 0x0b, 0x9b, 0xd5, 0xda, 0xfc, 0x26, 0x0c, 0x48, 0x26, + 0x52, 0xdc, 0xcf, 0x96, 0x38, 0x77, 0xf1, 0x78, 0x5e, 0xf5, 0xb5, 0x96, 0x16, 0x99, 0x36, 0xdf, 0xe8, 0xcb, 0x90, + 0xa6, 0xa2, 0x86, 0x34, 0xea, 0xcc, 0xa0, 0xfb, 0x76, 0x79, 0xcb, 0x6a, 0x84, 0x09, 0xf0, 0x4a, 0x67, 0xd0, 0x8d, + 0xc6, 0x03, 0xb1, 0xac, 0x46, 0xc5, 0x5a, 0x08, 0x04, 0x1e, 0x86, 0x1c, 0x33, 0x4b, 0x48, 0xb2, 0x4f, 0xfc, 0x3b, + 0x15, 0x67, 0xa1, 0x88, 0xaf, 0x0d, 0xb2, 0x77, 0x65, 0x5d, 0xbb, 0xeb, 0xc8, 0xcf, 0x89, 0x85, 0xd5, 0xfe, 0x43, + 0xf3, 0xa8, 0x35, 0xce, 0x02, 0xda, 0x9a, 0x56, 0x37, 0x1c, 0xee, 0x51, 0x1d, 0x8b, 0xd2, 0x60, 0x13, 0x7b, 0x64, + 0xb9, 0x68, 0x1d, 0x33, 0x68, 0x40, 0x7f, 0x93, 0x5d, 0xae, 0x2f, 0x11, 0xc0, 0xad, 0x44, 0xd6, 0x49, 0x2a, 0xff, + 0x92, 0xf6, 0xa8, 0x6b, 0x7b, 0x2a, 0xff, 0xdb, 0x36, 0x55, 0x0e, 0x2d, 0xa6, 0x3c, 0x76, 0x73, 0x16, 0xa8, 0x8e, + 0x04, 0x51, 0xa0, 0xb6, 0x5e, 0x30, 0xf5, 0x4e, 0x99, 0xa2, 0x03, 0x04, 0xba, 0x30, 0x67, 0xd8, 0x17, 0x1c, 0x31, + 0x66, 0xa9, 0xc4, 0x60, 0xea, 0x63, 0x8c, 0x6a, 0x5a, 0x2b, 0x40, 0xd7, 0x4f, 0x37, 0xf0, 0x27, 0x2a, 0x6a, 0x34, + 0xd4, 0x1a, 0x49, 0xa1, 0x68, 0xa2, 0x42, 0x91, 0xa5, 0x85, 0x8e, 0xab, 0xd0, 0x49, 0x24, 0x2c, 0x01, 0x0d, 0x13, + 0xa2, 0x93, 0x0a, 0xbc, 0x35, 0x80, 0x33, 0x1f, 0x17, 0xe5, 0xba, 0xd0, 0x06, 0x73, 0x3f, 0xc4, 0x57, 0xfc, 0xe5, + 0x33, 0x67, 0x54, 0xdf, 0xb2, 0xd6, 0xf7, 0xb4, 0x20, 0x3f, 0x84, 0x9c, 0xa2, 0x03, 0x13, 0x3b, 0xda, 0xa0, 0x31, + 0x46, 0x59, 0xeb, 0xa8, 0x17, 0x6f, 0x74, 0x28, 0x16, 0x6d, 0x82, 0x77, 0x8f, 0xa7, 0x88, 0x36, 0x3c, 0x14, 0xc6, + 0xaa, 0x1a, 0x9f, 0x4a, 0xd6, 0xd2, 0x83, 0x15, 0x3c, 0x5d, 0x27, 0x3c, 0x04, 0x3d, 0x12, 0x61, 0x47, 0x61, 0x31, + 0x8f, 0x17, 0x70, 0x9c, 0x14, 0x04, 0xd4, 0x0e, 0xfa, 0x0a, 0x3e, 0x5f, 0xa0, 0xfb, 0xab, 0x44, 0x0f, 0x30, 0xb4, + 0x20, 0x6e, 0x46, 0x41, 0x1d, 0x5d, 0xc6, 0xab, 0x86, 0x8a, 0x84, 0xcf, 0x0b, 0xb0, 0x1d, 0x52, 0xea, 0x29, 0xd0, + 0x42, 0x25, 0x4a, 0x3f, 0x0c, 0x7c, 0x87, 0xc6, 0xc0, 0xd6, 0x3a, 0x40, 0x43, 0x3f, 0x63, 0x9a, 0x5a, 0x67, 0xa8, + 0x7c, 0xe6, 0xdd, 0x33, 0xa3, 0xe5, 0xcc, 0xa2, 0x31, 0xe8, 0xdb, 0x68, 0x8a, 0xe2, 0x9c, 0x7c, 0x16, 0x14, 0x71, + 0x9a, 0xc5, 0x39, 0xf8, 0x6d, 0xc6, 0x05, 0x66, 0x4c, 0xe2, 0x8a, 0x5f, 0xc8, 0x02, 0xb4, 0xdd, 0xb9, 0x4a, 0xad, + 0x6b, 0x10, 0x90, 0xfd, 0x00, 0x56, 0x2f, 0x0d, 0x1d, 0x95, 0xf3, 0xee, 0xd2, 0xa6, 0x10, 0xb1, 0x08, 0xc1, 0xa6, + 0x99, 0x2e, 0xd9, 0x71, 0xa8, 0xb4, 0x39, 0x10, 0xea, 0x08, 0x8d, 0xfb, 0xa7, 0x61, 0x6c, 0x35, 0xc5, 0xd6, 0xee, + 0x6d, 0xbb, 0xfd, 0x57, 0xe9, 0xa5, 0xd3, 0x9c, 0xf4, 0x18, 0xfb, 0x57, 0x19, 0x16, 0x23, 0xdb, 0x11, 0x02, 0x4b, + 0xce, 0xfb, 0xd4, 0x7f, 0x45, 0xcb, 0x79, 0x02, 0xa6, 0x23, 0x3a, 0x58, 0x2e, 0x50, 0x76, 0x0c, 0xe8, 0x0e, 0x0c, + 0xae, 0xe8, 0xf7, 0xc1, 0x2a, 0xc3, 0x5c, 0x48, 0x96, 0x24, 0x65, 0xf0, 0x3c, 0xf5, 0xe0, 0xe0, 0xd7, 0x4c, 0x99, + 0xbb, 0x28, 0xeb, 0xd3, 0x25, 0x99, 0xa6, 0xc8, 0x40, 0xac, 0xc3, 0x4d, 0x96, 0x46, 0x89, 0x12, 0x91, 0x2d, 0xd1, + 0x3f, 0xd2, 0x50, 0x2c, 0x1d, 0xb9, 0x17, 0xa9, 0x12, 0xa1, 0x62, 0x9e, 0xe2, 0x49, 0x9d, 0xd6, 0xe9, 0x08, 0x43, + 0x4f, 0x82, 0x52, 0xae, 0x86, 0x81, 0x2a, 0xa9, 0x5e, 0x0a, 0x9b, 0x62, 0xbb, 0xd5, 0x17, 0x2b, 0x31, 0x8f, 0x17, + 0xf8, 0x52, 0xe0, 0x28, 0xfe, 0x8b, 0x7b, 0x61, 0xa7, 0xd4, 0xf6, 0xa0, 0x76, 0x44, 0x09, 0xfd, 0x17, 0x87, 0x8b, + 0xc4, 0x77, 0x52, 0x87, 0x00, 0x44, 0x8b, 0x90, 0x53, 0x75, 0x90, 0x1a, 0x6e, 0x68, 0x47, 0xf8, 0x6f, 0xb8, 0x3e, + 0xe3, 0x8c, 0xde, 0x54, 0x33, 0x6a, 0x28, 0x5f, 0x0f, 0xda, 0x18, 0xf5, 0xd9, 0xc0, 0x61, 0x85, 0x28, 0xb4, 0x61, + 0x47, 0xa5, 0x12, 0x2d, 0x0c, 0xa5, 0xfa, 0x4b, 0xa8, 0x38, 0xe2, 0xce, 0x8c, 0xb2, 0x64, 0x7c, 0x5a, 0x1e, 0x8a, + 0xe9, 0x60, 0x50, 0x92, 0xca, 0x58, 0xe8, 0xc1, 0xf5, 0xc0, 0xf3, 0xef, 0x81, 0x5b, 0x88, 0x87, 0x8c, 0x2c, 0x86, + 0xdc, 0xe0, 0xe4, 0xb7, 0x38, 0xb9, 0x6a, 0x54, 0xaa, 0x38, 0xd6, 0x44, 0xb5, 0xe0, 0xfb, 0x32, 0x0c, 0xd0, 0x27, + 0x29, 0x00, 0x93, 0xc1, 0x94, 0xdf, 0x80, 0x44, 0xe9, 0x54, 0xdd, 0x90, 0x3e, 0x88, 0x82, 0x9f, 0xf3, 0x82, 0x8b, + 0xc4, 0x15, 0x60, 0x79, 0x07, 0xdb, 0xeb, 0xa8, 0xa2, 0x0a, 0x93, 0xd7, 0xf4, 0x38, 0xe2, 0xc6, 0xfb, 0xcf, 0xf4, + 0xd8, 0x62, 0xb6, 0x5a, 0xc7, 0x06, 0x9f, 0x39, 0x06, 0x17, 0x74, 0x2d, 0xb1, 0x35, 0x54, 0xc3, 0x8a, 0xc0, 0xc0, + 0x05, 0x1c, 0x84, 0x25, 0x8a, 0x63, 0x2b, 0x79, 0x45, 0x1a, 0x52, 0xda, 0x7b, 0x86, 0xa3, 0x4d, 0x72, 0x7c, 0x9b, + 0x65, 0x37, 0x81, 0xf3, 0x45, 0xe7, 0xa4, 0x99, 0xb0, 0x36, 0x78, 0x9f, 0x37, 0xe7, 0xd7, 0xdd, 0x43, 0x42, 0x55, + 0xdc, 0x1b, 0xde, 0x8e, 0x7b, 0xe3, 0x84, 0x5f, 0x73, 0xb1, 0xd0, 0xa1, 0x5a, 0xcc, 0x25, 0xcb, 0x6f, 0xad, 0x77, + 0x4b, 0x92, 0x5a, 0x01, 0xed, 0xb3, 0x2c, 0xa8, 0x89, 0x00, 0x90, 0x3f, 0xfc, 0x05, 0x42, 0x67, 0xf8, 0xdb, 0x63, + 0x70, 0x45, 0x0a, 0xef, 0x1c, 0x02, 0x61, 0x4d, 0x37, 0x77, 0x6a, 0x03, 0xbe, 0x18, 0xf7, 0x67, 0x4c, 0x3d, 0xfd, + 0x36, 0x93, 0xbb, 0xba, 0x6e, 0x8f, 0x2c, 0xc3, 0x47, 0xb8, 0x52, 0x00, 0x37, 0x13, 0xfe, 0x62, 0x98, 0x49, 0xf5, + 0x09, 0x60, 0xaa, 0xe9, 0xe0, 0x3e, 0x41, 0x60, 0x00, 0x95, 0x68, 0x31, 0xba, 0x52, 0x8e, 0x68, 0x06, 0x6e, 0x4d, + 0xb7, 0xc2, 0x78, 0xeb, 0x41, 0x0b, 0x3d, 0xd3, 0x70, 0xe2, 0x3f, 0x68, 0xe6, 0x55, 0x01, 0x01, 0xb4, 0x32, 0x82, + 0xb7, 0xd6, 0x47, 0x73, 0x84, 0xf8, 0x84, 0x25, 0xd1, 0x84, 0xc5, 0x33, 0xc5, 0x8f, 0x09, 0xdd, 0x34, 0xb5, 0x4d, + 0xef, 0x91, 0xfe, 0xe2, 0x9a, 0xf5, 0x53, 0x96, 0xb5, 0x6f, 0x0f, 0x15, 0x2f, 0xa6, 0xcd, 0x38, 0x88, 0x89, 0x2a, + 0xc6, 0xff, 0x82, 0xfb, 0x52, 0x2b, 0x40, 0x64, 0xee, 0xaa, 0xa7, 0xdf, 0x6f, 0x66, 0xcb, 0x81, 0x50, 0xf9, 0x9d, + 0x41, 0xd2, 0xa7, 0x43, 0xfb, 0x81, 0x4d, 0xa2, 0xb6, 0xd0, 0xf3, 0xc7, 0xa5, 0x6e, 0xe2, 0xe5, 0xb5, 0xa9, 0x11, + 0xad, 0x90, 0xa1, 0xb2, 0x75, 0xc0, 0xfa, 0xfe, 0x21, 0xdc, 0x5d, 0xd4, 0x34, 0xd4, 0xba, 0xe7, 0xae, 0x45, 0xc1, + 0x89, 0x3f, 0xc0, 0x58, 0x5c, 0x48, 0x6a, 0x1d, 0x8f, 0x49, 0x3f, 0x5a, 0xc8, 0xe4, 0x46, 0x5d, 0x9d, 0x9c, 0x29, + 0xe6, 0x09, 0x5c, 0x80, 0xcb, 0xb6, 0xbf, 0xa2, 0x52, 0x97, 0x72, 0x7b, 0x45, 0x69, 0x7a, 0x48, 0xdb, 0xab, 0x38, + 0x6f, 0x0b, 0x2e, 0xf8, 0x17, 0x0a, 0x2e, 0xac, 0x83, 0x75, 0xc7, 0x9d, 0xb2, 0x27, 0x3c, 0x51, 0xa6, 0xb5, 0xc1, + 0x5d, 0x37, 0x18, 0x13, 0x63, 0xbf, 0xbb, 0xe4, 0xc9, 0x47, 0x64, 0xc1, 0xbf, 0xcb, 0x04, 0x78, 0x26, 0xbb, 0x57, + 0x2a, 0xff, 0x0f, 0xfe, 0xd5, 0xd6, 0xbe, 0xb3, 0xe6, 0x9f, 0x9e, 0xf5, 0x70, 0xe7, 0x30, 0xf9, 0xb1, 0x3a, 0x03, + 0xba, 0xb9, 0x94, 0x29, 0x07, 0x64, 0x00, 0x6b, 0x91, 0x8c, 0x06, 0x7c, 0x68, 0x65, 0xd9, 0xf6, 0x9d, 0x56, 0x17, + 0x84, 0x3b, 0x09, 0xdc, 0xf4, 0xee, 0xda, 0xcc, 0xcc, 0xe9, 0x5a, 0x89, 0xa6, 0x4b, 0x63, 0x6b, 0x59, 0xaa, 0x30, + 0xde, 0xef, 0x3c, 0xc9, 0xa6, 0xf9, 0xe1, 0x72, 0x9a, 0x5b, 0xea, 0xb6, 0x71, 0xcb, 0x06, 0xd0, 0x10, 0xbb, 0xd6, + 0x56, 0x0e, 0x78, 0xb9, 0x3d, 0x88, 0xe6, 0x6b, 0x45, 0xe8, 0xa9, 0x12, 0xa1, 0x4f, 0xd3, 0x66, 0x1f, 0xec, 0xaa, + 0x5a, 0x37, 0x42, 0x1e, 0x0d, 0x52, 0xcd, 0xc8, 0xbf, 0xb9, 0xe2, 0xc5, 0x79, 0x2e, 0xaf, 0x01, 0x0e, 0x99, 0xd4, + 0x46, 0x61, 0x79, 0x09, 0xee, 0xfc, 0xe8, 0x38, 0xce, 0xc4, 0x28, 0xc7, 0xb8, 0xad, 0x88, 0x94, 0xac, 0x13, 0x67, + 0x80, 0x87, 0xec, 0x4f, 0x9a, 0x0e, 0xed, 0x5a, 0x60, 0x78, 0x5f, 0xe0, 0xae, 0x72, 0x76, 0xb4, 0xc9, 0xed, 0xa2, + 0x6f, 0xce, 0xb0, 0xee, 0x48, 0x69, 0x6d, 0x2c, 0xba, 0xee, 0x60, 0xad, 0x19, 0xb4, 0x45, 0x28, 0xf9, 0x90, 0x3b, + 0x69, 0x3f, 0x05, 0x34, 0x38, 0xcd, 0xd2, 0x1b, 0x6b, 0x95, 0xbf, 0xd1, 0x42, 0x9c, 0x28, 0xa6, 0x4e, 0x7c, 0x13, + 0x25, 0xfa, 0xfc, 0x4c, 0x8c, 0x1b, 0x08, 0xa4, 0xfe, 0x80, 0xf1, 0x35, 0x8a, 0x30, 0x81, 0xeb, 0x40, 0x14, 0xdb, + 0x13, 0xb5, 0xb1, 0x1c, 0x41, 0x27, 0x84, 0x78, 0x07, 0x65, 0x18, 0xab, 0x8b, 0x03, 0x6d, 0xb0, 0xf4, 0x75, 0x6b, + 0x9d, 0x1b, 0x42, 0x61, 0x9c, 0xc0, 0x14, 0x83, 0xa4, 0xce, 0x3a, 0xcb, 0x04, 0x55, 0x76, 0x4c, 0x3a, 0xef, 0x03, + 0x74, 0x77, 0x2d, 0x9a, 0xe2, 0xeb, 0xce, 0x1d, 0x74, 0x17, 0xd7, 0xaf, 0xb5, 0xc8, 0x0d, 0xfe, 0xbc, 0x25, 0xc2, + 0x22, 0x70, 0xd6, 0x9a, 0x7c, 0xd5, 0x08, 0x07, 0xa6, 0x24, 0xd3, 0xb0, 0x97, 0x2b, 0x9b, 0xee, 0xed, 0xb6, 0xd7, + 0xbb, 0x53, 0xc4, 0xd5, 0x63, 0xac, 0xf2, 0x6e, 0xe6, 0xf6, 0x4e, 0xb5, 0x16, 0xbb, 0x37, 0x6d, 0x3f, 0xc5, 0x8e, + 0x5a, 0x6b, 0xb7, 0x1b, 0x4e, 0xa8, 0x21, 0xdf, 0x8a, 0x2a, 0xad, 0x4e, 0x37, 0x06, 0xed, 0x10, 0xda, 0x5a, 0x64, + 0x70, 0xa3, 0x7c, 0xe6, 0x84, 0x4e, 0x2a, 0xe4, 0xaa, 0x53, 0x17, 0x6c, 0x2e, 0x79, 0xb5, 0x94, 0x69, 0x24, 0x28, + 0xda, 0x9c, 0x47, 0x25, 0x4d, 0xe4, 0x5a, 0x54, 0x91, 0xac, 0x51, 0x2f, 0x6a, 0x35, 0x06, 0x08, 0xc8, 0x74, 0xda, + 0xf4, 0xa0, 0x0a, 0x66, 0x43, 0x19, 0xc9, 0xe9, 0x0b, 0xb0, 0xb4, 0x47, 0x8e, 0xb5, 0xbe, 0xab, 0xce, 0x16, 0xdf, + 0xea, 0x09, 0xc1, 0x14, 0x66, 0x0f, 0x44, 0x84, 0x6b, 0x1a, 0x43, 0x4e, 0xbb, 0xc4, 0x65, 0x4d, 0xb7, 0x84, 0x3b, + 0xb8, 0x5d, 0xc9, 0x8e, 0xdc, 0x3c, 0x69, 0x6e, 0xae, 0x60, 0x47, 0xc5, 0x7c, 0x0c, 0xda, 0x2f, 0xa9, 0xae, 0x5d, + 0x9a, 0x5b, 0x8f, 0x07, 0x01, 0x0d, 0x06, 0x85, 0xe1, 0x5f, 0x27, 0xc6, 0xc3, 0x93, 0x06, 0x04, 0x49, 0xb9, 0x08, + 0xc7, 0xbe, 0x11, 0xfd, 0x64, 0x2a, 0x0f, 0x39, 0x5a, 0xbc, 0x43, 0xab, 0x73, 0x08, 0xe8, 0x25, 0x42, 0x49, 0x8c, + 0xaa, 0xd0, 0x88, 0xa0, 0x3c, 0x2d, 0x7f, 0xa9, 0xaa, 0x43, 0x40, 0x21, 0xed, 0x2b, 0x0a, 0x65, 0x9b, 0xc4, 0xd0, + 0x0c, 0xbf, 0x9c, 0x4f, 0x16, 0x7a, 0x06, 0x06, 0x72, 0x7e, 0xb0, 0xd0, 0xb3, 0x30, 0x90, 0xf3, 0x47, 0x8b, 0xda, + 0xad, 0x03, 0x4d, 0x40, 0x3c, 0x17, 0x8e, 0x4e, 0x4a, 0xab, 0xb2, 0x05, 0x74, 0x73, 0x1f, 0x41, 0xff, 0x97, 0x3d, + 0x04, 0x9d, 0x5c, 0x68, 0x47, 0x6e, 0x40, 0xdb, 0x21, 0x09, 0xec, 0x15, 0x93, 0x0a, 0x13, 0x8b, 0xe8, 0x90, 0x8d, + 0xc1, 0x10, 0x5b, 0x7d, 0x70, 0xc8, 0xc6, 0x53, 0x9f, 0x04, 0x01, 0xa3, 0xfb, 0x83, 0x01, 0x07, 0xbf, 0xc1, 0xab, + 0xf4, 0xd1, 0x46, 0xa0, 0x9b, 0xbe, 0xbb, 0x1b, 0x7a, 0x17, 0x57, 0x70, 0xaa, 0x76, 0xf7, 0x24, 0x74, 0x93, 0x69, + 0xc7, 0xea, 0x35, 0xc4, 0x0d, 0xf9, 0x95, 0xd1, 0x68, 0x64, 0x53, 0x42, 0x42, 0x0c, 0xe7, 0xd0, 0xcc, 0x69, 0xb9, + 0x7c, 0x75, 0xeb, 0xd9, 0x80, 0x0c, 0x33, 0xbd, 0x61, 0xb2, 0xbe, 0x87, 0xb2, 0xea, 0x31, 0xb4, 0x43, 0xef, 0x91, + 0xe3, 0xfb, 0x07, 0xdf, 0x64, 0xfc, 0xcc, 0xe1, 0xda, 0xc3, 0xb9, 0xf0, 0x5d, 0xd6, 0x8c, 0xcc, 0xa1, 0xf3, 0xec, + 0xe3, 0x78, 0x0f, 0xe3, 0xe4, 0xf3, 0x2c, 0x94, 0x37, 0x5e, 0xd3, 0xff, 0xa8, 0xf4, 0x66, 0x87, 0x43, 0x4e, 0x57, + 0xb0, 0xe2, 0x66, 0x55, 0x68, 0xf8, 0x59, 0xe4, 0x8d, 0x23, 0x5e, 0x93, 0xa8, 0xea, 0x3e, 0xef, 0x6d, 0xc4, 0xd2, + 0x8e, 0x71, 0x00, 0x70, 0xa2, 0x56, 0x0d, 0xbb, 0xd2, 0xb8, 0x56, 0x07, 0x31, 0x22, 0x25, 0x6c, 0x95, 0x38, 0x12, + 0xca, 0xdf, 0x00, 0x84, 0xc5, 0x50, 0x1c, 0x6f, 0x0d, 0xeb, 0x3d, 0xec, 0x87, 0x2e, 0xd0, 0x34, 0xa7, 0x54, 0x33, + 0x00, 0x48, 0x02, 0xfe, 0xe8, 0xe9, 0xa6, 0xa1, 0xb2, 0xcd, 0xf3, 0xd0, 0xb2, 0xba, 0x82, 0x7b, 0x7a, 0xea, 0x4a, + 0x06, 0xc6, 0x55, 0x1d, 0x7b, 0x9b, 0xbb, 0xdb, 0xa3, 0x55, 0xe4, 0x3b, 0x9b, 0xd4, 0x34, 0x0b, 0x20, 0x45, 0xe3, + 0xd2, 0x17, 0x7a, 0x3a, 0x01, 0x5a, 0xaf, 0x2d, 0x15, 0xed, 0xf7, 0x51, 0x8c, 0x1a, 0x17, 0x0a, 0xac, 0xc2, 0x04, + 0x85, 0x43, 0x84, 0x11, 0x42, 0x7f, 0x2e, 0xc3, 0x8d, 0x2f, 0xc8, 0x20, 0x1a, 0xae, 0x45, 0x87, 0x22, 0x72, 0xbc, + 0x68, 0x5b, 0xaa, 0x6a, 0x4e, 0x9a, 0xb6, 0x04, 0xde, 0x44, 0x06, 0x6c, 0xe7, 0x9f, 0x36, 0x44, 0xae, 0xc2, 0x05, + 0x0c, 0xdf, 0x11, 0xd7, 0x82, 0xe8, 0xa6, 0x36, 0xf5, 0x36, 0xec, 0x10, 0x1d, 0x4d, 0xf1, 0xe8, 0x90, 0x7b, 0xee, + 0x9e, 0xdb, 0x22, 0xbe, 0xfe, 0x0c, 0xb9, 0x6b, 0x3a, 0x7b, 0x29, 0xc2, 0xa0, 0x6e, 0xd9, 0x40, 0xb1, 0x0e, 0x9d, + 0xa0, 0x00, 0x03, 0xb8, 0x7c, 0x02, 0x3a, 0x36, 0x18, 0x54, 0x04, 0x9f, 0x14, 0xb6, 0x4d, 0x83, 0xfc, 0x11, 0xef, + 0x86, 0x0e, 0xaf, 0x2d, 0x79, 0x20, 0x5e, 0x61, 0x9f, 0x29, 0xe1, 0xee, 0x05, 0x05, 0xdd, 0x51, 0x5e, 0xae, 0x0a, + 0x57, 0xa5, 0x01, 0xa8, 0xb2, 0xe3, 0xb9, 0xd6, 0x94, 0xb4, 0x80, 0x95, 0x92, 0xba, 0xf3, 0x9b, 0xe0, 0xb8, 0x25, + 0x53, 0xe1, 0x5b, 0x75, 0xa3, 0xca, 0x43, 0x89, 0x22, 0x1d, 0x7b, 0xb6, 0x73, 0xb0, 0x06, 0xc0, 0x53, 0xd8, 0x5e, + 0x9c, 0x09, 0xf8, 0xdc, 0x69, 0x97, 0x2d, 0x73, 0x09, 0x14, 0xf5, 0xfd, 0x38, 0x2f, 0x3b, 0xbe, 0xdc, 0x1d, 0x6d, + 0xef, 0xa1, 0x37, 0x62, 0x63, 0xbc, 0xbe, 0x8c, 0x9a, 0x7e, 0xf1, 0x0c, 0x57, 0x96, 0x82, 0xdc, 0xd3, 0x54, 0x8f, + 0x30, 0x3a, 0x04, 0xa6, 0x29, 0x3f, 0x62, 0xe3, 0xe9, 0x70, 0x68, 0xc8, 0xa0, 0xd7, 0x4c, 0x0c, 0x05, 0xf6, 0x05, + 0xb4, 0xce, 0x4c, 0x5c, 0xe3, 0xd3, 0xf6, 0x15, 0xb4, 0xba, 0x41, 0x99, 0xdc, 0x29, 0x18, 0x3e, 0xd0, 0x92, 0x29, + 0x98, 0x2a, 0xbc, 0x21, 0x52, 0xc9, 0x3e, 0x2d, 0xad, 0xc3, 0xbe, 0x5d, 0x28, 0xb4, 0xd0, 0xc4, 0xaf, 0x32, 0xc4, + 0x4f, 0x5d, 0x67, 0xfe, 0x6d, 0xda, 0xa7, 0x06, 0xb1, 0x70, 0x24, 0x06, 0x11, 0xbf, 0x38, 0x55, 0xb6, 0x13, 0x42, + 0xc5, 0xc6, 0x43, 0xd7, 0xba, 0x71, 0x24, 0x55, 0x18, 0x4a, 0xa1, 0xf1, 0xd4, 0x70, 0xdf, 0x0b, 0x1d, 0xbe, 0x0e, + 0xb3, 0xb8, 0xcd, 0x1a, 0x49, 0x8d, 0x71, 0x2a, 0x4c, 0x9c, 0x4a, 0xb9, 0x8a, 0x04, 0x06, 0xca, 0xb3, 0x85, 0x41, + 0x80, 0x49, 0x4c, 0x32, 0xb6, 0x16, 0xc2, 0x84, 0xb1, 0x73, 0x85, 0x69, 0xea, 0x22, 0xf5, 0x9b, 0x81, 0xc9, 0x82, + 0x86, 0xfc, 0x1e, 0x8d, 0xd6, 0x54, 0x4d, 0x01, 0x86, 0x71, 0x94, 0x6a, 0xfc, 0x5b, 0x84, 0xda, 0x0c, 0x03, 0x00, + 0xdb, 0xbc, 0x95, 0x99, 0xa8, 0x5e, 0x0a, 0x84, 0x40, 0x73, 0xf6, 0x53, 0x71, 0xb5, 0x33, 0x0b, 0x46, 0xd1, 0x6e, + 0xaf, 0x7c, 0x3e, 0x70, 0x42, 0x79, 0xac, 0x2e, 0x50, 0x2f, 0x64, 0xf1, 0x4a, 0xa6, 0xbc, 0x15, 0x22, 0x73, 0x4f, + 0xb2, 0x9f, 0xf2, 0x11, 0x9c, 0x57, 0xe8, 0x54, 0x6e, 0xb6, 0x89, 0x32, 0x4b, 0x92, 0x8c, 0x05, 0xc6, 0xe6, 0x25, + 0x98, 0x49, 0xcd, 0x8c, 0xe1, 0xd7, 0x10, 0x67, 0x6c, 0xe7, 0x24, 0xdc, 0xdc, 0xcd, 0x03, 0x43, 0x94, 0x72, 0xd1, + 0x12, 0x0d, 0x5b, 0x3b, 0x5e, 0x4f, 0xae, 0x09, 0xf7, 0x61, 0x23, 0xd6, 0x64, 0x8c, 0x71, 0x6d, 0x6e, 0x64, 0xfd, + 0x68, 0x81, 0x07, 0x63, 0xca, 0xfa, 0x13, 0xc8, 0xb4, 0x92, 0xb2, 0xce, 0x17, 0x46, 0xcc, 0xa4, 0x12, 0xbd, 0xdb, + 0x37, 0x3e, 0xab, 0xbb, 0x88, 0xfa, 0xad, 0xfd, 0x9e, 0xd4, 0xc3, 0xad, 0xff, 0xa0, 0xb0, 0x06, 0x95, 0x11, 0x97, + 0x11, 0xe5, 0x99, 0x03, 0xdd, 0x34, 0x29, 0xe2, 0xf4, 0x74, 0x15, 0x17, 0x25, 0x4f, 0xa1, 0x52, 0x4d, 0xdd, 0xa2, + 0xde, 0x04, 0xec, 0x0d, 0x91, 0x24, 0x59, 0x4b, 0x63, 0x2b, 0x76, 0x69, 0x90, 0x9e, 0x3b, 0x23, 0x2e, 0xbd, 0xa8, + 0xd0, 0x90, 0x96, 0x7a, 0x67, 0xa1, 0x92, 0xf9, 0x2b, 0xfe, 0x33, 0xa8, 0x15, 0xe8, 0x68, 0x93, 0x62, 0x3c, 0x05, + 0x46, 0x7c, 0x37, 0x98, 0xd5, 0x3d, 0xc4, 0x45, 0x13, 0x94, 0x7a, 0x47, 0xec, 0xf8, 0xb9, 0xc9, 0xc3, 0xbb, 0x90, + 0x73, 0x06, 0x9f, 0xde, 0xcf, 0x12, 0xb5, 0xd6, 0x91, 0x18, 0xa9, 0x19, 0x40, 0xd3, 0x41, 0x99, 0xf3, 0x58, 0x04, + 0xb3, 0x9e, 0x49, 0x8c, 0x7a, 0x5c, 0xff, 0x02, 0x0d, 0xb5, 0xdf, 0xac, 0x2c, 0xcf, 0xaa, 0xdb, 0x2f, 0xe1, 0xc0, + 0xa6, 0xb6, 0x82, 0x1e, 0xaf, 0x2b, 0x79, 0x71, 0xa1, 0xba, 0xed, 0x17, 0x62, 0xe4, 0x74, 0x8d, 0x6b, 0xe9, 0xbc, + 0x5a, 0xb0, 0x5e, 0x77, 0xba, 0x59, 0xdc, 0xcd, 0x32, 0x1a, 0x08, 0x6b, 0x3b, 0x9f, 0x68, 0xfe, 0xac, 0xd9, 0x76, + 0x1f, 0x6f, 0x41, 0xcc, 0x02, 0x80, 0x48, 0x0f, 0xa2, 0x60, 0x99, 0xa5, 0x3c, 0xa0, 0xf2, 0x2e, 0x8e, 0xb2, 0x50, + 0x7a, 0x39, 0xcb, 0xf8, 0x69, 0xd3, 0x58, 0xeb, 0xac, 0x50, 0x86, 0xd6, 0x46, 0x77, 0xba, 0xca, 0x10, 0xdb, 0x4f, + 0xe2, 0x6c, 0x01, 0xee, 0x8f, 0x19, 0x0a, 0x0d, 0x9d, 0x65, 0xa4, 0x89, 0x86, 0xef, 0xba, 0x63, 0x90, 0x51, 0x9c, + 0xac, 0xf3, 0x4a, 0xba, 0xd1, 0x67, 0x6d, 0x24, 0xcc, 0x3d, 0x44, 0xbf, 0x8a, 0xc1, 0xa3, 0xdc, 0xe7, 0xb5, 0xd1, + 0xc9, 0xb4, 0x8c, 0xb4, 0x3b, 0x3f, 0xa9, 0x97, 0x59, 0xaa, 0x75, 0xd8, 0x3e, 0xc3, 0xde, 0x1a, 0x93, 0xde, 0x84, + 0xd4, 0x30, 0x12, 0x9f, 0xcf, 0xa8, 0x11, 0x02, 0xda, 0x72, 0xfc, 0x1d, 0x3e, 0xc3, 0xd0, 0x14, 0x58, 0xaa, 0xb8, + 0x85, 0xdd, 0xf0, 0x35, 0x9f, 0xac, 0x5a, 0x00, 0x82, 0x59, 0xf9, 0x7a, 0x17, 0xaf, 0x84, 0xfa, 0x54, 0x9b, 0x01, + 0x20, 0x0b, 0x4a, 0xb9, 0xe3, 0xa7, 0x54, 0x3a, 0x58, 0xa2, 0x68, 0x7b, 0x39, 0x7d, 0xa3, 0x63, 0xe3, 0xfb, 0xf4, + 0x5c, 0xc0, 0x76, 0x21, 0xbf, 0x75, 0xa7, 0x5e, 0xa2, 0x22, 0xb5, 0x6d, 0xd6, 0x3d, 0x7c, 0xb9, 0x41, 0x93, 0x30, + 0x82, 0x32, 0x65, 0x0a, 0x60, 0x70, 0x53, 0x8d, 0x82, 0x49, 0xab, 0x91, 0xb0, 0xa5, 0x9e, 0x64, 0xb9, 0xe9, 0x83, + 0x53, 0xdd, 0x21, 0xe8, 0xb9, 0x51, 0xce, 0x17, 0x2d, 0xfb, 0xb5, 0x82, 0xa3, 0x93, 0xab, 0x21, 0x6a, 0xe6, 0xbd, + 0xb6, 0x23, 0x43, 0xca, 0x65, 0x18, 0x08, 0xa6, 0x1c, 0xf3, 0xf4, 0xd8, 0x7a, 0x46, 0x44, 0xf7, 0x9c, 0x7d, 0xa6, + 0x5b, 0x75, 0x25, 0x01, 0xd1, 0xf1, 0x9b, 0xc7, 0x2f, 0x2f, 0xe3, 0x0b, 0x83, 0xa2, 0xd4, 0xb0, 0x88, 0x51, 0xa6, + 0x7d, 0x95, 0x84, 0xc1, 0xfb, 0xf0, 0xee, 0x27, 0x95, 0xa5, 0xf6, 0x7b, 0xb0, 0xb1, 0xa2, 0xaa, 0x0f, 0x25, 0x2f, + 0x9a, 0x02, 0xac, 0xbb, 0x2c, 0x51, 0x20, 0xf7, 0x3b, 0x9b, 0x66, 0xbe, 0x89, 0x1a, 0x37, 0x1b, 0xd6, 0x1b, 0xd7, + 0xed, 0x52, 0x5b, 0xb2, 0x23, 0x2b, 0x91, 0x33, 0x8b, 0xc1, 0x8c, 0x1f, 0x15, 0x06, 0xa5, 0x61, 0x83, 0xaa, 0x54, + 0xfc, 0xde, 0x88, 0xe0, 0xd4, 0xb1, 0xaa, 0x30, 0xa6, 0x01, 0xb3, 0xad, 0xa8, 0x35, 0xa8, 0x83, 0x52, 0xda, 0x9a, + 0x80, 0x6c, 0xbf, 0xb1, 0x82, 0x9a, 0xdf, 0xbf, 0x1b, 0x43, 0xbe, 0xa6, 0x14, 0x54, 0x12, 0xb0, 0x33, 0x68, 0xf4, + 0x54, 0x09, 0x03, 0x29, 0x08, 0x9e, 0x00, 0xe5, 0x8b, 0xa8, 0xb1, 0xda, 0xed, 0xab, 0x53, 0x63, 0xb4, 0x05, 0x84, + 0x16, 0xd2, 0xa3, 0xcb, 0x3e, 0x6e, 0x63, 0x1d, 0x48, 0x3c, 0x38, 0xc1, 0x76, 0xae, 0xae, 0xd1, 0x48, 0x68, 0x7e, + 0xdf, 0x68, 0xc0, 0x6b, 0x5a, 0x81, 0x42, 0x3d, 0xc7, 0xd1, 0xd0, 0xd9, 0x21, 0x05, 0x11, 0x1b, 0xb4, 0xb0, 0xef, + 0x8e, 0x0f, 0xcd, 0xbe, 0x9e, 0x27, 0x0b, 0x52, 0x53, 0xe9, 0x3e, 0x77, 0x4b, 0xc8, 0x5a, 0x75, 0x28, 0x2b, 0x0f, + 0x70, 0xbc, 0x50, 0x32, 0x7f, 0x87, 0x49, 0x8d, 0xd2, 0x98, 0xd0, 0x18, 0xb1, 0x80, 0x25, 0x41, 0x7b, 0x3d, 0x50, + 0xbf, 0x0c, 0x42, 0x85, 0x33, 0x3d, 0x91, 0xf8, 0x94, 0x72, 0xf5, 0x69, 0x41, 0xea, 0x69, 0xc1, 0x1c, 0xe8, 0xa5, + 0x6f, 0xe5, 0x57, 0x36, 0x3e, 0xda, 0xdd, 0xbb, 0xe6, 0xc2, 0x3a, 0x86, 0xb8, 0xd8, 0xc2, 0x6f, 0x4e, 0x4d, 0x01, + 0xd8, 0xf0, 0x58, 0x97, 0xe5, 0x1b, 0x35, 0x91, 0x59, 0x1c, 0x92, 0x08, 0x24, 0xdb, 0xcd, 0xcd, 0x6d, 0x04, 0xdb, + 0xde, 0x42, 0x6d, 0xa8, 0xbf, 0xbc, 0xed, 0x7e, 0xc7, 0xf0, 0x72, 0x4f, 0xee, 0xdd, 0xb4, 0xa1, 0xfc, 0xe1, 0xee, + 0x55, 0xf2, 0x7f, 0x55, 0xc9, 0xdd, 0x56, 0x99, 0x75, 0x5b, 0xbc, 0xdf, 0x75, 0xdc, 0x72, 0x8c, 0x06, 0x81, 0x35, + 0x05, 0x06, 0xd2, 0x93, 0xc6, 0x34, 0xd1, 0xd1, 0x95, 0x19, 0x33, 0x78, 0x74, 0x01, 0x9a, 0xc3, 0x74, 0x9e, 0xc7, + 0x00, 0x1c, 0xe0, 0x1f, 0x79, 0x84, 0xfa, 0xa7, 0xf3, 0x3c, 0x38, 0x0d, 0x06, 0xe5, 0x20, 0xd0, 0x9f, 0xb8, 0xe6, + 0x04, 0x0b, 0xd0, 0xb9, 0xc5, 0x0c, 0xe2, 0x4e, 0x5a, 0x33, 0x87, 0xf8, 0x30, 0x99, 0x0e, 0x06, 0x31, 0xd9, 0x00, + 0x48, 0x5f, 0xbc, 0xb0, 0xce, 0x41, 0x85, 0x5e, 0x90, 0xad, 0xba, 0x8b, 0x66, 0xc5, 0x5e, 0xb5, 0xd3, 0xbc, 0xdf, + 0xcf, 0xe7, 0xe5, 0x20, 0x68, 0x54, 0x58, 0x18, 0xef, 0x3f, 0xda, 0xfc, 0xd2, 0xe8, 0xa4, 0x09, 0x46, 0xac, 0x3d, + 0x46, 0xf5, 0x8a, 0xa7, 0x19, 0x6d, 0xdc, 0x8e, 0x95, 0xf2, 0x05, 0x44, 0xf1, 0xc0, 0x90, 0xb5, 0xf2, 0xee, 0x1c, + 0xbc, 0x2e, 0x37, 0xde, 0x1c, 0x51, 0x80, 0xdd, 0x14, 0xc6, 0x49, 0xcd, 0x45, 0x17, 0x35, 0xf1, 0x0c, 0x76, 0xba, + 0x7a, 0x2b, 0xd1, 0x6a, 0xbc, 0x17, 0xef, 0x9a, 0x8d, 0xbf, 0x96, 0x7b, 0xba, 0xcc, 0xbd, 0x73, 0x40, 0x9c, 0xdd, + 0x8b, 0xab, 0x3d, 0x2c, 0x75, 0x2f, 0x18, 0x58, 0xe4, 0x90, 0x76, 0xb5, 0x7a, 0x28, 0x22, 0x75, 0x1e, 0x83, 0x01, + 0x93, 0x69, 0x48, 0x4d, 0xa6, 0xbd, 0x58, 0x41, 0xda, 0x58, 0x6b, 0x01, 0x6d, 0x38, 0x2c, 0x76, 0xec, 0x86, 0xdd, + 0xe9, 0xd6, 0xa1, 0x50, 0xc2, 0x40, 0xd6, 0x75, 0xf3, 0x50, 0x6b, 0x78, 0x22, 0xe8, 0x41, 0x35, 0xda, 0x4f, 0x0f, + 0xe5, 0x49, 0x7b, 0x2c, 0xc0, 0x45, 0x0f, 0x5f, 0x3e, 0x17, 0x78, 0xd1, 0xde, 0x41, 0x9e, 0x33, 0x9f, 0x2a, 0x1f, + 0xc4, 0x86, 0x5b, 0x86, 0x0f, 0xed, 0xe3, 0x5b, 0x81, 0x4c, 0xea, 0x8e, 0xa6, 0xb6, 0x76, 0x47, 0xe3, 0x98, 0x40, + 0xbf, 0x29, 0x47, 0x29, 0x13, 0x53, 0xcb, 0x92, 0x1d, 0xf5, 0x72, 0xe5, 0x0d, 0x95, 0xb2, 0xa3, 0x65, 0x9b, 0xf3, + 0x4b, 0x1b, 0x09, 0xfd, 0xbe, 0x76, 0x07, 0xc2, 0x37, 0x6a, 0xbd, 0x21, 0x2f, 0x1b, 0x22, 0x96, 0x43, 0xcc, 0xc0, + 0xf1, 0x42, 0x2a, 0xd7, 0xee, 0xa2, 0xa9, 0xaa, 0xdb, 0xd9, 0xca, 0x05, 0x2d, 0xf1, 0x56, 0x0a, 0xac, 0x22, 0x75, + 0x7a, 0x3d, 0x95, 0x78, 0xd7, 0x47, 0xb1, 0xfd, 0x08, 0xd8, 0xc6, 0xc6, 0xd1, 0xd8, 0xb8, 0x45, 0x6c, 0xf0, 0x55, + 0x54, 0xd1, 0x82, 0x03, 0x04, 0x77, 0x5b, 0x52, 0x4b, 0x33, 0x87, 0xb8, 0xaf, 0x78, 0x80, 0xf6, 0x5d, 0x1c, 0x71, + 0x2a, 0xc0, 0xb6, 0xae, 0x75, 0xce, 0x6a, 0x39, 0x60, 0x33, 0xd1, 0xf3, 0x4f, 0xab, 0x46, 0x22, 0x86, 0x55, 0x36, + 0x52, 0x56, 0x68, 0xf7, 0x4a, 0x97, 0x70, 0xf1, 0x05, 0x78, 0xd9, 0xbe, 0x5b, 0xd9, 0x7d, 0xba, 0xc4, 0xfe, 0x61, + 0x5e, 0x35, 0xc1, 0x23, 0xaf, 0xf1, 0xf6, 0x1e, 0x26, 0xbe, 0x54, 0x0a, 0xe1, 0x55, 0x4a, 0x43, 0x09, 0xc0, 0x20, + 0x09, 0x6a, 0xb8, 0xd2, 0xb6, 0x19, 0xa4, 0x32, 0x86, 0xdd, 0xad, 0xde, 0xea, 0xff, 0xb4, 0x0a, 0x17, 0x95, 0x2c, + 0xc6, 0x24, 0xd0, 0x39, 0xd5, 0x72, 0x13, 0x58, 0xf0, 0x74, 0x97, 0x1c, 0x81, 0xc2, 0x4e, 0x00, 0x37, 0x94, 0xb0, + 0xdf, 0xf1, 0x36, 0x94, 0xb3, 0xd7, 0x56, 0xf2, 0xe4, 0xf6, 0x25, 0x15, 0x34, 0x21, 0x53, 0x61, 0xf7, 0x6f, 0x6b, + 0xc3, 0xbe, 0x0c, 0xe5, 0x48, 0x0a, 0x5c, 0x1c, 0x74, 0x0e, 0x60, 0x7f, 0x90, 0xcb, 0xd8, 0x7c, 0x26, 0xfd, 0xbe, + 0x7a, 0xff, 0x34, 0xcf, 0x92, 0x8f, 0x3b, 0xef, 0x0d, 0x4f, 0xb3, 0x64, 0x40, 0x25, 0x62, 0x6a, 0x5d, 0x15, 0xc3, + 0xa5, 0x76, 0x31, 0x6e, 0x90, 0x8c, 0xf8, 0x4e, 0xea, 0x10, 0x23, 0xc6, 0x17, 0xd9, 0x21, 0x29, 0x39, 0x5d, 0xd6, + 0x9d, 0x3d, 0xd7, 0xa2, 0x19, 0x34, 0x86, 0xdb, 0xf1, 0x5e, 0xd2, 0x2b, 0x40, 0x05, 0x88, 0xee, 0x59, 0xe0, 0x1a, + 0xde, 0x5c, 0x12, 0x8d, 0x2d, 0x3d, 0x6d, 0x89, 0x06, 0xee, 0x94, 0x09, 0x49, 0xb5, 0x71, 0x80, 0x45, 0xac, 0xeb, + 0x8f, 0x61, 0x01, 0x40, 0xad, 0x06, 0xe9, 0x95, 0xbe, 0x20, 0x54, 0x25, 0x21, 0x18, 0x9d, 0x48, 0x78, 0x19, 0xd0, + 0x38, 0x33, 0x89, 0x16, 0x36, 0x38, 0xa0, 0x2f, 0x2b, 0x93, 0x68, 0x6c, 0xc8, 0x03, 0xca, 0x6d, 0x1a, 0xc0, 0xe0, + 0x83, 0x24, 0x89, 0xbe, 0x5f, 0x9a, 0x24, 0x10, 0x94, 0xa0, 0x7c, 0x83, 0xfe, 0x51, 0x7a, 0x3e, 0x96, 0x3f, 0x7a, + 0x87, 0xd2, 0x0f, 0x61, 0x01, 0x32, 0x45, 0x5d, 0x31, 0xcd, 0xd8, 0x51, 0xd6, 0x6d, 0x4c, 0xe2, 0x79, 0xda, 0x5d, + 0x15, 0xca, 0xa5, 0x0b, 0xfc, 0xca, 0x32, 0xc4, 0xb1, 0x7e, 0x1a, 0xaf, 0xd8, 0x71, 0xc8, 0x35, 0x5e, 0xfa, 0xd3, + 0x78, 0x85, 0x33, 0x44, 0xab, 0x56, 0x02, 0x51, 0xfe, 0xab, 0x36, 0x70, 0x88, 0xfb, 0x04, 0x83, 0x5c, 0x54, 0xde, + 0x03, 0x81, 0xbc, 0xad, 0x20, 0x22, 0xcd, 0xec, 0x3a, 0x8c, 0x48, 0xb5, 0x93, 0x64, 0xbe, 0xfc, 0x51, 0x66, 0xc2, + 0xfb, 0x06, 0x1e, 0x9b, 0xcd, 0xb2, 0x29, 0xe6, 0x0b, 0x15, 0xcc, 0xc1, 0x7d, 0xa2, 0xe2, 0x52, 0x54, 0xfe, 0x13, + 0x76, 0xc1, 0x8b, 0xf1, 0xe0, 0xf5, 0x1a, 0x01, 0xf6, 0x2b, 0xff, 0xc9, 0x1b, 0xb3, 0xbf, 0xac, 0x1b, 0x5f, 0x66, + 0x22, 0x3e, 0xf0, 0xd1, 0x0d, 0xe5, 0xa3, 0x5b, 0x2f, 0xd3, 0x77, 0x0d, 0x28, 0x91, 0x51, 0x59, 0xf1, 0xd5, 0x8a, + 0xa7, 0xb3, 0xab, 0x24, 0xca, 0x46, 0x15, 0x17, 0x30, 0xbd, 0xe0, 0x78, 0x97, 0xac, 0xcf, 0xb2, 0xe4, 0x25, 0xc4, + 0x1e, 0x58, 0x49, 0x85, 0xc5, 0x0f, 0xcb, 0x4c, 0x2d, 0x66, 0x21, 0x2b, 0x29, 0x78, 0x30, 0xbb, 0x4e, 0xa2, 0xbf, + 0x96, 0x1e, 0x92, 0x9a, 0x99, 0xb2, 0x4d, 0xed, 0x08, 0xb5, 0xf1, 0x75, 0xa4, 0x1b, 0x6d, 0x01, 0x00, 0xf7, 0x6c, + 0x91, 0x46, 0x92, 0x89, 0xe1, 0xa4, 0x66, 0xdc, 0xa4, 0x17, 0x98, 0x1a, 0xd7, 0xac, 0xa2, 0x89, 0xb3, 0x90, 0x01, + 0xbd, 0x3f, 0xcd, 0xf5, 0x73, 0x06, 0xf7, 0x1f, 0xb4, 0x06, 0x2e, 0x0f, 0x8b, 0x7e, 0x5f, 0x1e, 0x16, 0xdb, 0x6d, + 0x79, 0x14, 0xf7, 0xfb, 0xf2, 0x28, 0x36, 0xfc, 0x83, 0x52, 0x6c, 0x1b, 0x73, 0x83, 0x84, 0xe6, 0x12, 0xa2, 0x16, + 0x8d, 0xe0, 0x0f, 0xcd, 0x72, 0x2e, 0xa2, 0xfc, 0x30, 0xe9, 0xf7, 0x7b, 0xcb, 0x99, 0x18, 0xe4, 0xc3, 0x24, 0xca, + 0x87, 0x89, 0xe7, 0x84, 0xf8, 0x8b, 0xe7, 0x84, 0xa8, 0x68, 0xe0, 0x0a, 0xce, 0x0c, 0x40, 0x14, 0xf0, 0xe9, 0x1f, + 0xd5, 0xb5, 0x14, 0xba, 0x96, 0x58, 0xd5, 0x92, 0xe8, 0x0a, 0x6a, 0x76, 0x5d, 0x84, 0x25, 0x96, 0x42, 0x97, 0xec, + 0xbb, 0x25, 0xf0, 0x44, 0x39, 0xaf, 0x36, 0xc0, 0xc0, 0x46, 0x78, 0xe7, 0x30, 0xe1, 0x24, 0xd6, 0x35, 0xa0, 0x9d, + 0x6e, 0x6a, 0x7a, 0x4e, 0x57, 0xf4, 0x02, 0xf9, 0xd9, 0x73, 0x30, 0x58, 0x3a, 0x64, 0xf9, 0x74, 0x30, 0x38, 0x27, + 0x2b, 0x56, 0xce, 0xc3, 0x78, 0x10, 0xae, 0x67, 0xf9, 0xf0, 0x3c, 0x3a, 0x27, 0xe4, 0xab, 0x62, 0x41, 0x7b, 0xab, + 0x51, 0xf9, 0x31, 0x83, 0xf0, 0x7e, 0xe9, 0x2c, 0xcc, 0x4c, 0x9c, 0x8f, 0xd5, 0xe8, 0x86, 0xae, 0x20, 0x7e, 0x0d, + 0xdc, 0x48, 0x48, 0x04, 0x1d, 0xb9, 0xa0, 0x2b, 0xba, 0xa6, 0xd2, 0xcc, 0x30, 0x46, 0xeb, 0xb6, 0xc7, 0x49, 0x02, + 0x8e, 0xc9, 0xae, 0xf8, 0x68, 0xac, 0x0a, 0xef, 0xfa, 0x8e, 0xd0, 0x5e, 0x2f, 0x71, 0x83, 0xf4, 0x43, 0x7b, 0x90, + 0x80, 0x11, 0x19, 0xa9, 0x81, 0x32, 0x23, 0x23, 0xa9, 0x99, 0x54, 0x1c, 0x92, 0xd8, 0x1f, 0x12, 0x35, 0x0e, 0x89, + 0x3f, 0x0e, 0xb9, 0x1e, 0x07, 0xe4, 0xee, 0x97, 0x6c, 0x4c, 0x53, 0x36, 0xa6, 0x6b, 0x35, 0x2a, 0xf4, 0x92, 0x9e, + 0x69, 0xea, 0x78, 0xca, 0x5e, 0xc1, 0x81, 0x3d, 0x08, 0xf3, 0x59, 0x3c, 0x7c, 0x15, 0xbd, 0x22, 0xe4, 0x2b, 0x49, + 0xaf, 0xd4, 0xa5, 0x0c, 0x02, 0x21, 0x5e, 0x82, 0x73, 0xa9, 0x0b, 0x75, 0x72, 0x69, 0x76, 0x1c, 0x3e, 0x5d, 0x34, + 0x9e, 0xce, 0x20, 0xa2, 0x0f, 0x5a, 0xa9, 0xf4, 0xfb, 0xe1, 0x39, 0x2b, 0xe7, 0xa7, 0xe1, 0x98, 0x00, 0x0e, 0x8f, + 0x1e, 0xce, 0xf3, 0xd1, 0x0d, 0x3d, 0x1f, 0xdd, 0x12, 0xb0, 0xf0, 0x1a, 0x4f, 0xd7, 0x87, 0x2c, 0x9e, 0x0e, 0x06, + 0x6b, 0xa4, 0xea, 0x2a, 0xf7, 0x9a, 0x2c, 0xe8, 0x39, 0x4e, 0x04, 0x01, 0x86, 0x3e, 0x13, 0x6b, 0x43, 0xc3, 0x5f, + 0x31, 0xf8, 0xf8, 0x96, 0x9d, 0x8f, 0x6e, 0xe9, 0x0d, 0x7b, 0xb5, 0x1d, 0x4f, 0x81, 0x99, 0x5a, 0xcd, 0xc2, 0xdb, + 0xc3, 0x8b, 0xd9, 0x05, 0xbb, 0x8d, 0x6e, 0x8f, 0xa0, 0xa1, 0x97, 0xec, 0x16, 0x01, 0x97, 0xd2, 0x87, 0xcb, 0xc1, + 0x2b, 0xb2, 0x3f, 0x18, 0xa4, 0x24, 0x0a, 0xaf, 0x42, 0xaf, 0x95, 0xaf, 0xe8, 0x2d, 0xa1, 0x2b, 0x76, 0x83, 0xa3, + 0x71, 0xc1, 0xf0, 0x83, 0x33, 0x76, 0x5b, 0x5f, 0x85, 0xde, 0x6e, 0x4e, 0x44, 0x27, 0x88, 0x11, 0xfa, 0x1a, 0x38, + 0x9a, 0xe5, 0xc2, 0x4c, 0xc0, 0x93, 0xb9, 0xc8, 0x68, 0x51, 0x68, 0x06, 0xe2, 0xac, 0x04, 0xc4, 0x92, 0xa8, 0xfb, + 0xcd, 0x46, 0xa7, 0xb0, 0x9c, 0xfb, 0xfd, 0x5e, 0x65, 0xe8, 0x01, 0x22, 0x67, 0x76, 0xd2, 0x83, 0x9e, 0x4f, 0x0f, + 0xf0, 0x13, 0xbd, 0x6a, 0x10, 0x27, 0xf3, 0x87, 0x65, 0xf4, 0x8b, 0x47, 0x1f, 0x3e, 0x74, 0x53, 0x9e, 0x32, 0xff, + 0xf7, 0x29, 0x8f, 0xcc, 0xa3, 0x57, 0x95, 0x07, 0x82, 0xe7, 0xad, 0x49, 0xa5, 0x91, 0xa8, 0x46, 0xa7, 0xab, 0x18, + 0xb4, 0x91, 0xa8, 0x6d, 0xd0, 0x4f, 0x68, 0x61, 0x05, 0x11, 0x72, 0x0e, 0x9e, 0x81, 0x41, 0x2a, 0x84, 0xca, 0x51, + 0x8b, 0x12, 0x0d, 0x41, 0x72, 0x59, 0x72, 0x15, 0x3e, 0x87, 0x50, 0x75, 0xfa, 0x38, 0x13, 0x61, 0x43, 0x8f, 0x43, + 0x1f, 0x00, 0xfe, 0xf7, 0x1d, 0x72, 0x51, 0xf2, 0x0b, 0x3c, 0x9b, 0xdb, 0x04, 0xa3, 0x60, 0x89, 0x68, 0x86, 0xb6, + 0x41, 0xec, 0xc7, 0x92, 0x60, 0x3d, 0x92, 0xc6, 0xa3, 0xd2, 0x1c, 0x11, 0x7e, 0x14, 0x1f, 0x45, 0x4f, 0x63, 0x43, + 0x22, 0x39, 0x92, 0x48, 0x3e, 0x00, 0xc2, 0x49, 0xd0, 0x5f, 0xdc, 0x35, 0xd9, 0xb5, 0x90, 0x18, 0xf4, 0xa7, 0x25, + 0xd3, 0xb2, 0x7b, 0xd5, 0x63, 0x5f, 0x11, 0xe4, 0x8e, 0xe9, 0xdf, 0xbc, 0x3e, 0xfc, 0xbd, 0xc4, 0x19, 0xb4, 0x9e, + 0x2f, 0xaa, 0x33, 0x33, 0x6f, 0x70, 0x23, 0xaf, 0xcb, 0xda, 0x75, 0xf9, 0x9c, 0xef, 0xf1, 0x9b, 0x8a, 0x8b, 0xb4, + 0xdc, 0xfb, 0xb9, 0x6a, 0xe3, 0x39, 0x95, 0xeb, 0x95, 0x8b, 0xb3, 0xa2, 0x8c, 0x53, 0x3d, 0xa9, 0x8b, 0xb1, 0x86, + 0x6d, 0xf8, 0x3d, 0xa2, 0xae, 0xa4, 0xe5, 0xe8, 0x29, 0xe5, 0xaa, 0x99, 0x72, 0xbe, 0xce, 0xf3, 0x9f, 0x76, 0x52, + 0x71, 0x8a, 0x9b, 0x29, 0x48, 0x95, 0x5a, 0x2e, 0xa0, 0x7a, 0x8e, 0x5a, 0xee, 0x96, 0x66, 0x07, 0x38, 0xb7, 0x4d, + 0xf5, 0xb1, 0x32, 0xbb, 0xf0, 0x92, 0x1b, 0xf7, 0x27, 0x53, 0x86, 0x05, 0xa3, 0xd0, 0x66, 0xd5, 0x95, 0xb6, 0x2f, + 0xb4, 0x4e, 0xc3, 0x70, 0xe5, 0xc7, 0x0b, 0x48, 0x17, 0x30, 0x8e, 0x17, 0x25, 0x13, 0xe3, 0xf6, 0xe8, 0xad, 0x20, + 0xbe, 0x64, 0x2b, 0x90, 0x7e, 0xbf, 0x27, 0xbc, 0x5d, 0xd7, 0xd1, 0x76, 0x4f, 0x9c, 0x32, 0x2a, 0x57, 0xb1, 0xf8, + 0x3e, 0x5e, 0x19, 0xc8, 0x64, 0x75, 0x3c, 0x36, 0xc6, 0x74, 0xfa, 0x7d, 0x12, 0xfa, 0x85, 0x50, 0xf0, 0x59, 0x2f, + 0xad, 0x3c, 0xb9, 0x3d, 0x2c, 0xe3, 0x1a, 0xbd, 0x12, 0x57, 0xba, 0x6f, 0x46, 0x0a, 0xa9, 0x47, 0xbe, 0x6a, 0x0a, + 0xe8, 0xcd, 0xd8, 0x37, 0x53, 0x61, 0xde, 0xee, 0x18, 0x73, 0x85, 0x60, 0xa5, 0xca, 0x6e, 0xdf, 0xa9, 0x31, 0x15, + 0x33, 0x98, 0x62, 0xdb, 0x59, 0x4c, 0xba, 0x95, 0x7f, 0xda, 0xb9, 0x4f, 0xf3, 0x0e, 0x77, 0x45, 0xfd, 0x16, 0xb8, + 0xd0, 0xac, 0x28, 0xab, 0xb6, 0x6c, 0xd8, 0x36, 0xde, 0xc8, 0x42, 0xb1, 0x01, 0x96, 0x3d, 0xf7, 0x2d, 0x3c, 0x40, + 0xdc, 0x84, 0x7b, 0x76, 0x51, 0xc3, 0x8d, 0xe1, 0xcb, 0x4a, 0xf2, 0x5d, 0x69, 0xcc, 0xa5, 0x4f, 0x95, 0x26, 0x86, + 0x93, 0xc5, 0x88, 0x8b, 0x74, 0x51, 0x67, 0x76, 0x2d, 0x7c, 0xc6, 0xcb, 0x70, 0xce, 0x17, 0x46, 0x37, 0xa5, 0x4b, + 0x2f, 0x58, 0xa2, 0x3b, 0xbd, 0x59, 0x69, 0xac, 0x94, 0x88, 0x5b, 0xb3, 0x4c, 0xa0, 0x2c, 0x65, 0xad, 0x84, 0x37, + 0x45, 0xcb, 0x56, 0xd2, 0xc8, 0x7b, 0xe6, 0xe0, 0x3e, 0xf6, 0x01, 0x31, 0x91, 0x4d, 0x60, 0x52, 0x34, 0x74, 0x40, + 0xbb, 0xea, 0xc2, 0x37, 0xa3, 0x1e, 0x0c, 0x72, 0x4b, 0x12, 0xb1, 0x82, 0x14, 0x2b, 0x58, 0xd7, 0xac, 0x98, 0xe7, + 0x0b, 0x7a, 0xce, 0xe4, 0x3c, 0x5d, 0xd0, 0x15, 0x93, 0xf3, 0x35, 0xde, 0x84, 0xce, 0xe1, 0x84, 0x24, 0x9b, 0x58, + 0x29, 0x60, 0xcf, 0xf1, 0xf2, 0x86, 0x67, 0xaa, 0xa6, 0x65, 0x17, 0x8a, 0x03, 0x8c, 0xcf, 0xca, 0x30, 0x2c, 0x87, + 0xe7, 0x60, 0x2d, 0xb1, 0x1f, 0xae, 0xe6, 0x7c, 0xa1, 0x7e, 0x43, 0xd4, 0xf9, 0x24, 0x54, 0xec, 0x82, 0xdd, 0x0b, + 0x64, 0x7a, 0x39, 0xe7, 0x0b, 0x35, 0x12, 0xba, 0xe0, 0x4b, 0x6b, 0x6c, 0x12, 0x7b, 0x82, 0x96, 0x59, 0x3c, 0x1f, + 0x2f, 0xa2, 0xb8, 0x86, 0x65, 0x78, 0xa2, 0x66, 0xa6, 0x25, 0xff, 0x49, 0xd4, 0x86, 0x26, 0xfa, 0x06, 0xab, 0xc8, + 0x1f, 0x1e, 0x1f, 0x5d, 0x02, 0x19, 0x3b, 0xbb, 0x92, 0x99, 0x0f, 0x7d, 0x1f, 0x19, 0xdc, 0x73, 0x53, 0xce, 0xb8, + 0x0a, 0x12, 0x65, 0xe0, 0xee, 0xd5, 0x2c, 0x19, 0x6b, 0x11, 0xbe, 0x7b, 0x54, 0x14, 0x7d, 0x26, 0x4d, 0x03, 0xba, + 0x8f, 0x04, 0x73, 0xa0, 0xf7, 0x0a, 0x1d, 0x2e, 0xab, 0x6d, 0x26, 0xe0, 0x2f, 0x12, 0xe4, 0xb7, 0x42, 0xaf, 0x6a, + 0x0c, 0xaa, 0x68, 0x17, 0xb1, 0xf4, 0xef, 0x23, 0x7e, 0x94, 0xcd, 0xdf, 0xcc, 0x3d, 0x5e, 0x49, 0x18, 0xfc, 0x90, + 0x9a, 0x4d, 0x32, 0x6f, 0xaf, 0xd8, 0x77, 0xd0, 0x51, 0x8f, 0x5a, 0xe3, 0x7d, 0xf5, 0x9c, 0x53, 0x88, 0x51, 0x42, + 0xd1, 0x49, 0x30, 0x80, 0xdb, 0x25, 0xa4, 0xb8, 0x1b, 0xec, 0xa6, 0x79, 0xcd, 0x8b, 0x82, 0xb3, 0x75, 0x55, 0x05, + 0x7e, 0x40, 0xc3, 0xf9, 0x62, 0x37, 0x84, 0xe1, 0x98, 0xb6, 0xae, 0x61, 0x10, 0x66, 0x0c, 0x23, 0x21, 0x78, 0xfd, + 0x8b, 0x1e, 0xd1, 0x24, 0x5e, 0x7d, 0xc7, 0x3f, 0x65, 0xbc, 0x50, 0x44, 0x1a, 0x44, 0x48, 0xdd, 0xc4, 0x37, 0x32, + 0x4d, 0x0a, 0x28, 0x04, 0x18, 0x05, 0x54, 0x62, 0x43, 0x53, 0xf1, 0xb7, 0x5a, 0x7c, 0xf0, 0x53, 0xd3, 0xf1, 0x68, + 0x5c, 0xb7, 0x3a, 0xa3, 0x82, 0xce, 0x40, 0x8f, 0x5a, 0x51, 0x4f, 0x83, 0x56, 0x82, 0x69, 0xa4, 0x79, 0xeb, 0x1e, + 0x02, 0xaf, 0x4c, 0x8b, 0x77, 0x1e, 0xd0, 0xcd, 0xa9, 0x0f, 0x9e, 0x3c, 0xa6, 0xa7, 0x0e, 0x3d, 0xb9, 0x62, 0x47, + 0x55, 0x0f, 0xb5, 0xf7, 0x66, 0x84, 0x82, 0x7e, 0x1f, 0x53, 0xa0, 0x1b, 0x41, 0xed, 0x5d, 0xdd, 0x2b, 0xb9, 0xcb, + 0xe1, 0x3b, 0xce, 0x72, 0x03, 0x58, 0x2a, 0xb2, 0x56, 0xe0, 0x51, 0x80, 0xba, 0x54, 0x86, 0xb0, 0xc5, 0x1c, 0x0e, + 0x95, 0xdd, 0xaa, 0xd5, 0x50, 0x92, 0xc3, 0x72, 0x04, 0x0e, 0xa1, 0xeb, 0x72, 0x50, 0x8e, 0x96, 0x59, 0xf5, 0x0e, + 0x7f, 0x6b, 0xd6, 0x21, 0xc9, 0xee, 0x62, 0x1d, 0xb8, 0x65, 0x1d, 0xa6, 0x1f, 0x0d, 0x52, 0x00, 0x9a, 0x6c, 0x04, + 0x2e, 0x01, 0x78, 0x6f, 0xff, 0x11, 0xa1, 0x56, 0xa6, 0x77, 0x32, 0x16, 0xea, 0xfb, 0x46, 0x12, 0x94, 0xd0, 0x4c, + 0xa8, 0x1c, 0x4b, 0xc1, 0x3b, 0x8f, 0x74, 0x4e, 0xea, 0x4c, 0xbc, 0x03, 0x71, 0x5a, 0x78, 0xcf, 0xde, 0x82, 0xe0, + 0x9c, 0x05, 0xbd, 0xc5, 0xdb, 0xac, 0x96, 0xda, 0xe8, 0x81, 0x02, 0xf8, 0xdd, 0xe0, 0x16, 0x41, 0xbe, 0x1a, 0xc3, + 0xb5, 0x92, 0xd7, 0x21, 0x1f, 0x16, 0xf4, 0x80, 0x0c, 0xec, 0xb3, 0x18, 0xc6, 0xf4, 0x80, 0x1c, 0xda, 0x67, 0xe9, + 0x06, 0x70, 0x20, 0xf5, 0xa8, 0xd2, 0x03, 0x68, 0xd0, 0x6f, 0xb6, 0x45, 0xee, 0x00, 0x94, 0x46, 0x11, 0x03, 0x55, + 0x82, 0x88, 0x5a, 0xfc, 0x7e, 0x6f, 0xae, 0x5b, 0xcc, 0x05, 0xc2, 0x1c, 0x0c, 0x38, 0x88, 0xdb, 0x20, 0x34, 0x07, + 0xcc, 0xe6, 0x26, 0x12, 0xf4, 0xd6, 0x1a, 0x66, 0x76, 0xf4, 0x87, 0x5b, 0x09, 0xbe, 0xc9, 0x5a, 0xa3, 0xce, 0x8b, + 0x43, 0x20, 0x08, 0xde, 0x14, 0xaa, 0xda, 0xab, 0x1e, 0xd8, 0x78, 0xab, 0x7e, 0x6c, 0xb7, 0xe3, 0xa9, 0x70, 0xd7, + 0x7e, 0x41, 0xe1, 0xe4, 0x53, 0xf2, 0xaf, 0x77, 0x26, 0x83, 0x03, 0x23, 0xc3, 0x97, 0xde, 0xfe, 0x85, 0xaf, 0xb5, + 0x74, 0x4f, 0x0c, 0x4a, 0xf2, 0xf0, 0x40, 0xd1, 0xbf, 0x3b, 0x65, 0xe5, 0x53, 0x3b, 0xfd, 0xdb, 0xad, 0x59, 0x9f, + 0x87, 0xa3, 0xc9, 0x76, 0xdb, 0x8b, 0x2b, 0xed, 0xb1, 0xa6, 0x17, 0x04, 0x3a, 0xd7, 0x93, 0xfd, 0x03, 0x88, 0x8a, + 0xd0, 0x8c, 0xbb, 0x59, 0x36, 0x24, 0x32, 0x7e, 0x9c, 0xce, 0xb2, 0x21, 0xd8, 0xe1, 0x5e, 0x54, 0xe2, 0x72, 0xd4, + 0xda, 0xe0, 0xf4, 0x36, 0x09, 0x21, 0x94, 0x03, 0x56, 0x76, 0xa3, 0xfe, 0xdc, 0x2a, 0x33, 0x21, 0x35, 0x59, 0xdd, + 0x4e, 0xe9, 0x1e, 0xa6, 0xf9, 0x9e, 0x19, 0xc1, 0x01, 0xf7, 0xf6, 0x57, 0xfd, 0x31, 0x4c, 0x32, 0x4d, 0x4e, 0x91, + 0xfc, 0x22, 0x3d, 0x85, 0xa4, 0x1d, 0x7a, 0xaa, 0x08, 0xe0, 0x84, 0xda, 0x8f, 0xe1, 0x37, 0x8c, 0xfb, 0x77, 0xcd, + 0xd7, 0x6e, 0x2a, 0xa2, 0xc7, 0x14, 0xcb, 0xd4, 0xe4, 0x34, 0xc9, 0x8a, 0x04, 0xa2, 0x36, 0xaa, 0x66, 0x44, 0x8f, + 0x5c, 0xcc, 0x47, 0x45, 0xf8, 0xbc, 0x5a, 0xff, 0x67, 0x08, 0x9f, 0x51, 0xb8, 0x01, 0x5c, 0x5e, 0x71, 0x71, 0x16, + 0x3e, 0x79, 0x4c, 0xf7, 0x26, 0xdf, 0x1c, 0xd0, 0xbd, 0x83, 0x47, 0x4f, 0x08, 0xc0, 0xa2, 0x5d, 0x9c, 0x85, 0x07, + 0x4f, 0x9e, 0xd0, 0xbd, 0x6f, 0xbf, 0xa5, 0x7b, 0x93, 0x47, 0x07, 0x8d, 0xb4, 0xc9, 0x93, 0x6f, 0xe9, 0xde, 0x37, + 0x8f, 0x1b, 0x69, 0x07, 0xe3, 0x27, 0x74, 0xef, 0x9f, 0xdf, 0x98, 0xb4, 0x7f, 0x40, 0xb6, 0x6f, 0x0f, 0xf0, 0x3f, + 0x93, 0x36, 0x79, 0xf2, 0x88, 0xee, 0x4d, 0xc6, 0x50, 0xc9, 0x13, 0x57, 0xc9, 0x78, 0x02, 0x1f, 0x3f, 0x82, 0xff, + 0xfe, 0x41, 0x60, 0x13, 0x48, 0x96, 0x0b, 0xd4, 0x9f, 0xa1, 0x88, 0x13, 0x55, 0x13, 0x09, 0x0f, 0x31, 0xb3, 0xfa, + 0x26, 0x0e, 0x03, 0xe2, 0xd2, 0xa1, 0x20, 0xba, 0x37, 0x1e, 0x3d, 0x21, 0x81, 0x0f, 0x4f, 0xf7, 0xd1, 0x07, 0x19, + 0xcb, 0xc5, 0x3c, 0xfb, 0x2a, 0x37, 0xb1, 0x15, 0x3c, 0x00, 0xab, 0x13, 0x3f, 0x17, 0x97, 0xf3, 0xec, 0x2b, 0x2e, + 0x77, 0x73, 0xfd, 0xab, 0x05, 0x28, 0xef, 0xaf, 0x5a, 0xf6, 0xb1, 0x50, 0xa1, 0xd3, 0x5a, 0xa3, 0xcf, 0x4e, 0x30, + 0x7d, 0x30, 0xf0, 0x6e, 0xd8, 0xdf, 0xef, 0x94, 0xd3, 0xfa, 0x46, 0xa3, 0x50, 0xa3, 0xf2, 0x90, 0xb0, 0x23, 0x28, + 0x7a, 0x30, 0x00, 0x9e, 0xc0, 0xc3, 0x7d, 0xfb, 0x37, 0xcb, 0x38, 0xe9, 0x28, 0xe3, 0x0f, 0x94, 0x21, 0xa0, 0x51, + 0x0f, 0xb3, 0x9b, 0x1e, 0x36, 0xba, 0xd5, 0x4b, 0x96, 0xea, 0x64, 0x6a, 0x7a, 0x06, 0xfb, 0x5a, 0xd7, 0x72, 0xcf, + 0x88, 0xa2, 0xe5, 0xf9, 0x5e, 0xca, 0x67, 0x15, 0xfb, 0x7e, 0x89, 0xea, 0xad, 0xa8, 0xf1, 0x46, 0x66, 0xb3, 0x8a, + 0xfd, 0x6c, 0xde, 0x00, 0x37, 0xc3, 0xfe, 0xa5, 0x9e, 0xfc, 0xc0, 0x19, 0x99, 0xb4, 0xed, 0x51, 0x26, 0x46, 0x80, + 0x15, 0x90, 0x81, 0x03, 0x0f, 0x80, 0x0e, 0xfa, 0xa3, 0xbd, 0xdd, 0xaa, 0x94, 0x66, 0x9f, 0x2d, 0x0c, 0xa0, 0x61, + 0xde, 0x26, 0x1e, 0xaa, 0x59, 0x43, 0x5e, 0x82, 0xc2, 0xad, 0x66, 0x79, 0x3b, 0x85, 0x21, 0x84, 0x60, 0x95, 0x32, + 0x00, 0x1c, 0x08, 0x30, 0x18, 0x6b, 0x19, 0x50, 0xb3, 0xe5, 0xa3, 0x0d, 0x57, 0xea, 0x49, 0xe0, 0x0c, 0xce, 0x65, + 0x91, 0xf0, 0x37, 0x5a, 0xec, 0x8f, 0xd6, 0x8f, 0xbe, 0x6f, 0x8f, 0x07, 0x6b, 0xdf, 0xe3, 0x23, 0xfd, 0x59, 0xe3, + 0x3a, 0xb0, 0x69, 0xf9, 0xc6, 0x8b, 0xda, 0x4a, 0x3c, 0x4a, 0xe0, 0x0d, 0x4c, 0x44, 0x0a, 0x83, 0x54, 0x0b, 0x1c, + 0x83, 0xf2, 0xc6, 0x42, 0x2c, 0x55, 0x57, 0x37, 0x74, 0x4b, 0x86, 0xe0, 0xe1, 0xf6, 0xe3, 0x52, 0x05, 0x8e, 0xea, + 0xf7, 0x33, 0xe9, 0xbb, 0x3d, 0x19, 0x3b, 0x72, 0x9c, 0xfa, 0xa9, 0x70, 0xf0, 0xdf, 0xa4, 0xae, 0x8d, 0xdd, 0x7d, + 0xca, 0x2c, 0xcb, 0xc2, 0x8e, 0x42, 0x2d, 0xf7, 0xa8, 0x3c, 0x48, 0xbe, 0x90, 0x43, 0x24, 0x0b, 0x8c, 0x42, 0x41, + 0x86, 0x13, 0x2a, 0x46, 0x6b, 0x51, 0x2e, 0xb3, 0xf3, 0x2a, 0xdc, 0x28, 0x85, 0x32, 0xa7, 0xe8, 0xdb, 0x0d, 0x0e, + 0x24, 0x24, 0xca, 0xca, 0xd7, 0xf1, 0xeb, 0x10, 0xc1, 0xea, 0xb8, 0xb6, 0x85, 0xe2, 0xde, 0xfe, 0xcc, 0xd2, 0x2e, + 0xfe, 0xc8, 0xb8, 0x80, 0xba, 0x58, 0x4c, 0xc3, 0x89, 0xd5, 0xef, 0xb8, 0x2f, 0xac, 0xa6, 0x07, 0xa0, 0xbe, 0x4b, + 0x25, 0x46, 0x50, 0x5f, 0x19, 0xfb, 0xd8, 0x1e, 0x63, 0x72, 0x06, 0xb1, 0x86, 0xf5, 0xdd, 0x4e, 0xf5, 0x8d, 0xb0, + 0x23, 0x00, 0x6e, 0x84, 0xd6, 0xe8, 0xc8, 0x24, 0x55, 0x88, 0xe7, 0xa5, 0x0a, 0xdf, 0x9a, 0x11, 0x3a, 0x06, 0x6f, + 0x2a, 0xdb, 0x48, 0x21, 0x7d, 0xc1, 0xa0, 0x39, 0xb6, 0x75, 0x14, 0x56, 0x5b, 0x59, 0x76, 0x04, 0x70, 0x03, 0xd9, + 0xa1, 0xb9, 0x78, 0xce, 0xaa, 0x79, 0xb6, 0x88, 0x4c, 0x50, 0xc0, 0xa5, 0xb0, 0x0c, 0xda, 0xeb, 0x3b, 0x64, 0x3b, + 0x0e, 0xa1, 0x1b, 0xee, 0x23, 0x18, 0x4f, 0xbb, 0x29, 0x58, 0x41, 0x34, 0x42, 0x3c, 0xcc, 0x98, 0xc5, 0xf7, 0x4a, + 0x53, 0x9e, 0xaa, 0x96, 0x40, 0xe0, 0x28, 0x84, 0xba, 0xd8, 0x35, 0x4a, 0x70, 0x99, 0x1a, 0xc1, 0x0c, 0x76, 0xec, + 0x48, 0x6d, 0x97, 0x9c, 0xd3, 0xa1, 0x9a, 0xd2, 0x52, 0x4f, 0xa9, 0xf6, 0x35, 0x14, 0xf3, 0x12, 0x3d, 0xf4, 0xc0, + 0xf5, 0x40, 0x3b, 0xe4, 0x95, 0x74, 0x62, 0x22, 0xe8, 0xb4, 0xda, 0x84, 0x9d, 0x1b, 0xe9, 0x96, 0xd5, 0xc8, 0x3b, + 0x86, 0x66, 0x47, 0x3c, 0xf7, 0x03, 0x75, 0x01, 0x44, 0xc8, 0x9d, 0x2d, 0x32, 0xb3, 0xcf, 0xb2, 0xf2, 0x05, 0x94, + 0xc5, 0x11, 0x5b, 0x57, 0xc0, 0xb5, 0x14, 0x4c, 0x2e, 0x79, 0x94, 0xa5, 0x88, 0x08, 0x78, 0xac, 0xb4, 0xeb, 0x3b, + 0x2d, 0x21, 0x54, 0xa4, 0x40, 0xdc, 0x5c, 0x14, 0xe7, 0xda, 0x06, 0xb2, 0x00, 0xfa, 0xf6, 0x53, 0x76, 0xe9, 0x85, + 0x83, 0xdd, 0x5c, 0x66, 0xe2, 0x19, 0x3f, 0xcf, 0x04, 0x4f, 0x11, 0xec, 0xea, 0xc6, 0x3c, 0x70, 0xc7, 0xb6, 0x81, + 0xe5, 0xdb, 0x77, 0xb0, 0x60, 0xca, 0x50, 0x2b, 0x25, 0x32, 0x11, 0x09, 0xc8, 0xec, 0x33, 0x77, 0xaf, 0x32, 0xf1, + 0x2a, 0xbe, 0x01, 0x6f, 0x8a, 0x06, 0x3f, 0x3d, 0x3a, 0xc3, 0x2f, 0x11, 0x49, 0x14, 0x62, 0xd8, 0x62, 0x44, 0x2c, + 0x44, 0x8e, 0x1d, 0x13, 0xca, 0x95, 0xa0, 0xb5, 0x35, 0x04, 0x5e, 0xfc, 0x69, 0xd5, 0xbd, 0xcb, 0x4c, 0x18, 0xfb, + 0x8c, 0xcb, 0xf8, 0x86, 0x95, 0x0a, 0xcc, 0x02, 0xe3, 0xdc, 0xb7, 0xa5, 0x24, 0x97, 0x99, 0x30, 0x02, 0x92, 0xcb, + 0xf8, 0x86, 0x36, 0x65, 0x1c, 0xda, 0x8a, 0xce, 0x8b, 0xf3, 0xbb, 0x3b, 0xfc, 0x12, 0x43, 0xad, 0x8c, 0xfb, 0x7d, + 0x90, 0x98, 0x49, 0xdb, 0x94, 0x99, 0x8c, 0xa4, 0x46, 0x0b, 0xa9, 0x28, 0x1f, 0x4c, 0xc8, 0xee, 0x4a, 0xb5, 0x8c, + 0xa8, 0xfd, 0x2a, 0x14, 0xb3, 0x71, 0x34, 0x21, 0x74, 0xd2, 0xb1, 0xde, 0x4d, 0x6b, 0x21, 0xd3, 0xe8, 0x49, 0xe4, + 0xf9, 0x74, 0x16, 0xac, 0x9a, 0x16, 0x87, 0x8c, 0x4f, 0x8b, 0xc1, 0x80, 0x68, 0x97, 0xc2, 0x0d, 0xd6, 0x03, 0xa6, + 0x34, 0x2e, 0xde, 0x9a, 0x69, 0xf5, 0x0b, 0xa9, 0x42, 0xd2, 0x7b, 0x06, 0x24, 0x42, 0xba, 0x60, 0xb7, 0x20, 0x51, + 0xf4, 0xfc, 0xef, 0xd4, 0x16, 0xdc, 0xf5, 0x60, 0x6c, 0x46, 0xf7, 0xf5, 0x8c, 0xff, 0x50, 0xdb, 0x82, 0xa8, 0x4f, + 0x25, 0xeb, 0x75, 0x24, 0xaa, 0x90, 0x8b, 0xf0, 0xb3, 0xa3, 0x21, 0x86, 0xa8, 0xf6, 0x58, 0x20, 0xd6, 0x97, 0x67, + 0xbc, 0xc0, 0xe9, 0x67, 0xee, 0x72, 0x05, 0xdb, 0x82, 0x56, 0x86, 0x46, 0xbd, 0x8e, 0x5f, 0x47, 0xf6, 0xb2, 0xa0, + 0x8b, 0x7c, 0x86, 0x42, 0xd6, 0x3c, 0x0c, 0xab, 0x61, 0x7b, 0x10, 0xc9, 0x7e, 0x7b, 0x12, 0x1a, 0x8d, 0x81, 0x05, + 0xb2, 0x43, 0x23, 0x70, 0x11, 0x5a, 0xf9, 0xdb, 0x21, 0xb8, 0x70, 0x59, 0x44, 0x96, 0xa1, 0x8e, 0xdf, 0xd4, 0x6e, + 0x82, 0xea, 0x15, 0x3a, 0x4d, 0x61, 0x55, 0xca, 0x24, 0x1f, 0x7e, 0xbd, 0x90, 0x05, 0x66, 0xf2, 0xba, 0xec, 0xd1, + 0xd7, 0x76, 0x7b, 0x07, 0xa6, 0x60, 0xdd, 0x27, 0xef, 0xeb, 0x87, 0x9d, 0x3d, 0x01, 0xa3, 0x58, 0x95, 0xa3, 0x29, + 0xa4, 0xd4, 0x3e, 0x28, 0xf5, 0xc7, 0x70, 0x29, 0x34, 0xc7, 0x6e, 0x01, 0x93, 0x80, 0x7d, 0x86, 0x54, 0x8f, 0x69, + 0xc7, 0x3e, 0x47, 0x1b, 0x58, 0x12, 0x70, 0xf8, 0x47, 0x42, 0xd6, 0xfe, 0xd5, 0xbd, 0x4c, 0x9b, 0x21, 0x5b, 0xe6, + 0x0b, 0xe0, 0xf3, 0x61, 0xd7, 0x46, 0x25, 0xca, 0x26, 0x22, 0x49, 0x61, 0xcb, 0x63, 0x90, 0xf6, 0x28, 0xa6, 0xab, + 0x82, 0x27, 0x19, 0x4a, 0x29, 0x12, 0xed, 0x13, 0x9c, 0xc3, 0x1b, 0xdc, 0x8f, 0x2a, 0x20, 0xbc, 0x0a, 0x39, 0x1d, + 0xa5, 0x54, 0x5b, 0xc0, 0x28, 0xea, 0x01, 0xa2, 0xbc, 0x0c, 0xe4, 0x78, 0xdb, 0xed, 0x84, 0xae, 0xd8, 0x72, 0x38, + 0xa1, 0x48, 0x4a, 0x2e, 0xb0, 0xdc, 0x4b, 0xd0, 0x79, 0x9c, 0xb1, 0xde, 0x73, 0xc0, 0x22, 0x38, 0x85, 0xbf, 0x31, + 0xa1, 0x57, 0xf0, 0x37, 0x27, 0xf4, 0x15, 0x0b, 0x2f, 0x87, 0x17, 0x64, 0x3f, 0x4c, 0x07, 0x13, 0x25, 0x18, 0xbb, + 0x65, 0x69, 0x19, 0xaa, 0xc4, 0xd5, 0xfe, 0x39, 0x79, 0x78, 0x4e, 0x6f, 0xe8, 0x35, 0x3d, 0xa1, 0x6f, 0x80, 0xf0, + 0xdf, 0x1e, 0x4e, 0xf8, 0x70, 0xf2, 0xb8, 0xdf, 0xef, 0x9d, 0xf5, 0xfb, 0xbd, 0x53, 0x63, 0x40, 0xa1, 0x77, 0xd1, + 0x45, 0x4d, 0xf5, 0xaf, 0xcb, 0x7a, 0x31, 0x7d, 0xa3, 0x36, 0x6e, 0xc2, 0xb3, 0x3c, 0xbc, 0xdc, 0xbf, 0x25, 0x43, + 0x7c, 0x3c, 0xcf, 0xa5, 0x2c, 0xc2, 0x8b, 0xfd, 0x5b, 0x42, 0xdf, 0x1c, 0x81, 0xde, 0x14, 0xeb, 0x7b, 0xf3, 0xf0, + 0x56, 0xd7, 0x46, 0xe8, 0xf3, 0x30, 0x81, 0x6d, 0x72, 0xc3, 0xec, 0x5d, 0x7b, 0x32, 0x86, 0x58, 0x26, 0xb7, 0x5e, + 0x79, 0xb7, 0x0f, 0x6f, 0xc8, 0xfe, 0x0d, 0x78, 0x8a, 0x5a, 0xf2, 0x37, 0x0b, 0xaf, 0x59, 0xab, 0x86, 0x87, 0xb7, + 0xf4, 0xa4, 0xd5, 0x88, 0x87, 0xb7, 0x24, 0x0a, 0xaf, 0xd9, 0x05, 0x3d, 0x61, 0x97, 0x84, 0x9e, 0xf5, 0xfb, 0xa7, + 0xfd, 0xbe, 0xec, 0xf7, 0xbf, 0x8f, 0xc3, 0x30, 0x1e, 0x16, 0x64, 0x5f, 0xd2, 0xdb, 0xfd, 0x09, 0x7f, 0x44, 0x66, + 0xa1, 0x6e, 0xbe, 0x5a, 0x70, 0x56, 0xe5, 0xad, 0x72, 0xdd, 0x52, 0xb0, 0x56, 0xb8, 0x65, 0xea, 0xe9, 0x0d, 0xbd, + 0x66, 0x05, 0x3d, 0x61, 0x31, 0x89, 0xae, 0xa0, 0x15, 0x67, 0xb3, 0x22, 0xba, 0xa6, 0x27, 0xec, 0x74, 0x16, 0x47, + 0x27, 0xf4, 0x0d, 0xcb, 0x87, 0x13, 0xc8, 0x7b, 0x32, 0xbc, 0x26, 0xfb, 0x6f, 0x48, 0x14, 0xbe, 0xd1, 0xbf, 0x6f, + 0xe9, 0x05, 0x0f, 0xdf, 0x50, 0xaf, 0x9a, 0x37, 0xc4, 0x54, 0xdf, 0xa8, 0xfd, 0x0d, 0x89, 0xfc, 0xc1, 0x7c, 0x63, + 0xed, 0x69, 0x1e, 0x38, 0xda, 0xb8, 0x2e, 0xc3, 0x5b, 0x42, 0xd7, 0x65, 0x78, 0x4d, 0xc8, 0xb4, 0x39, 0x76, 0x30, + 0xa0, 0xb3, 0x07, 0x51, 0x42, 0xe8, 0xb5, 0x5f, 0xea, 0x35, 0x8e, 0xa1, 0x19, 0x21, 0x95, 0x76, 0x82, 0x69, 0xb8, + 0x0e, 0x9e, 0x69, 0xb0, 0x8e, 0xb3, 0x7e, 0x3f, 0x5c, 0xf7, 0xfb, 0x10, 0xe9, 0xbe, 0x98, 0x99, 0xd8, 0x6e, 0x8e, + 0x6c, 0xd2, 0x6b, 0xd0, 0xfe, 0x3f, 0x1b, 0x0c, 0xa0, 0x33, 0x5e, 0x49, 0xe1, 0xf5, 0xe0, 0xd9, 0xc3, 0x5b, 0xa2, + 0xea, 0x28, 0x68, 0x29, 0xc3, 0x82, 0xbe, 0xa2, 0x19, 0x00, 0x7e, 0x3d, 0x1b, 0x0c, 0x48, 0x64, 0x3e, 0x23, 0xd3, + 0x67, 0x87, 0x6f, 0xa6, 0x83, 0xc1, 0x33, 0xb3, 0x4d, 0x3e, 0xb1, 0x3b, 0x4a, 0x81, 0xf5, 0x77, 0xda, 0xef, 0x7f, + 0x3a, 0x8a, 0xc9, 0x59, 0xc1, 0xe3, 0x8f, 0xd3, 0x66, 0x5b, 0x3e, 0xb9, 0xa8, 0x6a, 0xa7, 0xfd, 0xfe, 0xba, 0xdf, + 0x3f, 0x01, 0xec, 0xa2, 0x99, 0xf3, 0xf5, 0x04, 0x69, 0xcb, 0xdc, 0x51, 0x24, 0x4d, 0x72, 0x68, 0x0c, 0x6d, 0x8b, + 0x55, 0xdb, 0x66, 0x1d, 0x19, 0x58, 0x1c, 0x35, 0x2b, 0x8a, 0x6b, 0x12, 0x85, 0xbd, 0xd3, 0xed, 0xf6, 0x84, 0x31, + 0x16, 0x13, 0x90, 0x7e, 0xf8, 0xaf, 0x4f, 0xea, 0x46, 0x0c, 0xb1, 0x52, 0x89, 0xef, 0x36, 0x4b, 0x7b, 0x08, 0x44, + 0x1c, 0x36, 0xfd, 0x3b, 0x73, 0x2f, 0x17, 0xb5, 0xe3, 0x5b, 0xff, 0x00, 0x10, 0x22, 0xc9, 0x42, 0x3e, 0xc3, 0x31, + 0x28, 0x33, 0x00, 0x32, 0x8f, 0xd4, 0xcc, 0x4b, 0x00, 0x01, 0x26, 0xdb, 0xed, 0x68, 0x3c, 0x9e, 0xd0, 0x82, 0x8d, + 0xfe, 0xf1, 0xe4, 0x61, 0xf5, 0x30, 0x0c, 0x82, 0x41, 0x46, 0x5a, 0x7a, 0x0a, 0xbb, 0x58, 0xab, 0x7d, 0x30, 0x82, + 0xd7, 0xec, 0xe3, 0x55, 0xf6, 0xc5, 0xec, 0x23, 0x12, 0xd6, 0x06, 0xe3, 0xc8, 0x45, 0xda, 0xd2, 0xdb, 0xdd, 0xc1, + 0x60, 0x72, 0x91, 0x7e, 0x86, 0xed, 0xf4, 0xf9, 0x37, 0x0f, 0xc6, 0x13, 0x0e, 0x46, 0x77, 0x51, 0xd0, 0x67, 0xda, + 0x76, 0x5b, 0xf9, 0x97, 0xc0, 0xd7, 0x98, 0x0a, 0x3a, 0x36, 0xcb, 0xc2, 0x0d, 0x2a, 0xa2, 0x8e, 0x96, 0x41, 0x55, + 0x2b, 0xdb, 0x39, 0xa0, 0x96, 0x58, 0x95, 0x89, 0x5b, 0x60, 0x18, 0x32, 0xd4, 0xe5, 0x1e, 0x57, 0x7f, 0xf0, 0x42, + 0x1a, 0xf8, 0x0c, 0x27, 0x22, 0xf4, 0xb8, 0x35, 0xee, 0x73, 0x6b, 0xe2, 0x33, 0xdc, 0x5a, 0x89, 0x24, 0xd6, 0xc0, + 0x92, 0x9a, 0xcb, 0x51, 0xc2, 0x8e, 0x4a, 0xc6, 0x67, 0x65, 0x94, 0xd0, 0x18, 0x1e, 0x24, 0x13, 0x33, 0x19, 0x25, + 0x68, 0x9f, 0xe8, 0x22, 0x0c, 0xfe, 0x0d, 0x98, 0xfd, 0x34, 0x87, 0xbf, 0x92, 0x4c, 0x93, 0x43, 0x08, 0x08, 0x71, + 0x38, 0x9e, 0xc5, 0xe1, 0x98, 0x44, 0xc9, 0x11, 0x3c, 0xc1, 0x7f, 0x45, 0x38, 0x26, 0xb5, 0xbe, 0xc3, 0x48, 0x75, + 0xb9, 0x4d, 0x18, 0xc0, 0x95, 0x8d, 0x67, 0x93, 0xc8, 0x4a, 0x77, 0xe5, 0xc3, 0xd1, 0xf8, 0x09, 0x99, 0xc6, 0xa1, + 0x1c, 0x24, 0x84, 0x82, 0x77, 0x6f, 0x58, 0x0e, 0x13, 0x0d, 0xcf, 0x06, 0x6c, 0x5e, 0xe9, 0xd8, 0x3c, 0x09, 0x27, + 0x20, 0x0c, 0x13, 0x72, 0xac, 0x77, 0x20, 0xa5, 0xe8, 0xf3, 0x1c, 0xfb, 0xa9, 0x8f, 0x20, 0xcc, 0x8e, 0x5a, 0x2a, + 0xbe, 0x02, 0xa0, 0x4b, 0x1c, 0x1c, 0x6a, 0xcf, 0x7c, 0x31, 0x0b, 0x4b, 0x8f, 0x4a, 0x99, 0xea, 0xf6, 0x45, 0x83, + 0xf2, 0x9b, 0x06, 0xed, 0x0b, 0x32, 0x98, 0xd0, 0xf2, 0x68, 0xc2, 0x1f, 0x41, 0x00, 0x8f, 0x46, 0xc4, 0x2f, 0x85, + 0x13, 0x03, 0xe1, 0x55, 0x90, 0x81, 0x4a, 0x6b, 0xd5, 0x98, 0x91, 0xad, 0x78, 0x0f, 0xc2, 0xa4, 0xec, 0x5d, 0xcb, + 0x75, 0x9e, 0x42, 0x54, 0xb0, 0x75, 0x5e, 0xed, 0x5d, 0x80, 0x25, 0x7b, 0x5c, 0x41, 0x9c, 0xb0, 0xf5, 0x0a, 0xb0, + 0x73, 0x1f, 0x6c, 0xca, 0x7a, 0x4f, 0x7d, 0xb7, 0x87, 0x2d, 0x87, 0x57, 0x95, 0xdc, 0x9b, 0x8c, 0xc7, 0xe3, 0xd1, + 0x9f, 0x70, 0x74, 0x00, 0xa1, 0x25, 0x91, 0xe1, 0x93, 0x01, 0x1a, 0x77, 0x5d, 0x71, 0x6f, 0x5c, 0x28, 0xca, 0x4a, + 0x27, 0x13, 0x02, 0xe2, 0x67, 0xd3, 0x37, 0xd8, 0x57, 0x5c, 0xc7, 0x3f, 0xd9, 0xfd, 0xc4, 0xac, 0x68, 0xb5, 0x52, + 0x47, 0x6f, 0xdf, 0x9c, 0xbc, 0x7c, 0xff, 0xf2, 0x97, 0xe7, 0xa7, 0x2f, 0x5f, 0xbf, 0x78, 0xf9, 0xfa, 0xe5, 0xfb, + 0xdf, 0xef, 0x61, 0xb0, 0x7d, 0x5b, 0x11, 0x3b, 0xf6, 0xde, 0x3d, 0xc6, 0xab, 0xc5, 0x17, 0xce, 0x1e, 0xb8, 0x5b, + 0x2c, 0xc0, 0x26, 0x18, 0x6e, 0x41, 0x50, 0xcd, 0x68, 0x54, 0xfa, 0x9e, 0x80, 0x8c, 0x46, 0x85, 0x6c, 0x3c, 0xac, + 0xd8, 0x0a, 0xb9, 0x78, 0xc7, 0x70, 0xf0, 0x91, 0xfd, 0xad, 0x38, 0x13, 0x6e, 0x47, 0x5b, 0xb3, 0x22, 0xe0, 0xf3, + 0xb5, 0x16, 0x95, 0xc7, 0x85, 0xa8, 0xbd, 0x6d, 0x9f, 0x43, 0x42, 0x3d, 0x22, 0xd7, 0xc1, 0xfb, 0x36, 0xc8, 0x1e, + 0x1f, 0x79, 0x4f, 0xca, 0x33, 0xd4, 0xe7, 0x68, 0xf8, 0xa8, 0xf1, 0x8c, 0x4e, 0xcc, 0xb5, 0xd1, 0xa1, 0x9e, 0x16, + 0xb0, 0xbf, 0x95, 0x18, 0x9b, 0x16, 0xac, 0x4c, 0x11, 0xeb, 0xc3, 0xe9, 0x7e, 0x77, 0x6f, 0x46, 0x3f, 0xc3, 0xf1, + 0xa3, 0x54, 0x13, 0x48, 0x8b, 0x02, 0xa5, 0x2b, 0x43, 0x6e, 0x7b, 0x16, 0x16, 0xe6, 0x67, 0xd8, 0x20, 0x80, 0xf6, + 0xb2, 0x63, 0x49, 0xa0, 0x59, 0xbc, 0xd6, 0xf5, 0xcf, 0xcb, 0x97, 0x89, 0x76, 0xbe, 0xf8, 0x06, 0x42, 0x0c, 0xfb, + 0x57, 0x84, 0xc6, 0x84, 0xbb, 0x49, 0x76, 0x97, 0x16, 0x73, 0xaf, 0xba, 0x8c, 0xf1, 0xb8, 0xbb, 0xe3, 0x4a, 0xd1, + 0xbc, 0x75, 0x81, 0x3d, 0x50, 0xf3, 0x3a, 0x5e, 0xb2, 0x10, 0xb0, 0x19, 0xf7, 0xed, 0x22, 0x71, 0x7e, 0xef, 0x74, + 0x42, 0xf6, 0x0f, 0xa6, 0x7c, 0xc8, 0x4a, 0x2a, 0x06, 0xac, 0xac, 0x77, 0xa8, 0x39, 0x6f, 0x13, 0x72, 0xb1, 0x4b, + 0xc3, 0xc5, 0x90, 0xdf, 0x77, 0x49, 0x7a, 0xcf, 0x1b, 0x0e, 0xd5, 0xb6, 0xb9, 0x18, 0xd2, 0x94, 0xd3, 0x5d, 0x2a, + 0x03, 0x42, 0xa4, 0xcb, 0xb8, 0x22, 0xb5, 0x3e, 0xaa, 0x52, 0x27, 0xe9, 0xb8, 0xca, 0x36, 0x9f, 0xb9, 0x64, 0xab, + 0xdb, 0xb5, 0x7f, 0xad, 0x6e, 0x5f, 0x98, 0x81, 0xfc, 0xfd, 0x85, 0xa8, 0x26, 0x06, 0xa2, 0x0b, 0xa8, 0xe0, 0x5f, + 0xe0, 0xe5, 0xc9, 0x23, 0xad, 0x00, 0xbd, 0xeb, 0xec, 0xe8, 0xda, 0xe3, 0x8d, 0x59, 0x6c, 0x2d, 0x71, 0xce, 0x2a, + 0xdf, 0x59, 0x5e, 0x95, 0xad, 0xd0, 0x75, 0x04, 0xfb, 0x23, 0xec, 0xe8, 0xbb, 0xb7, 0x0d, 0x80, 0x28, 0x85, 0x95, + 0x3b, 0xfb, 0x85, 0x77, 0xf6, 0x0b, 0x7b, 0xf6, 0xdb, 0x4d, 0xa0, 0x7c, 0x58, 0xa1, 0x65, 0x2f, 0xa4, 0xa8, 0x4c, + 0x93, 0xc7, 0x4d, 0x5d, 0x16, 0xd2, 0x62, 0xbe, 0x6f, 0x69, 0xd7, 0xe3, 0x31, 0x95, 0xa8, 0x1e, 0xf9, 0x01, 0x5b, + 0xb5, 0x5f, 0x92, 0xfb, 0xef, 0x99, 0xff, 0xb3, 0x37, 0xc8, 0xbb, 0xee, 0x76, 0xff, 0x37, 0x17, 0x3a, 0xb8, 0xad, + 0xa5, 0xc2, 0x53, 0x57, 0xc7, 0x05, 0xde, 0xd5, 0xd2, 0xfb, 0xef, 0x6a, 0x6f, 0x33, 0xbd, 0xec, 0x2a, 0x40, 0x0d, + 0x12, 0xeb, 0x4b, 0x5e, 0x64, 0x49, 0x6d, 0x15, 0x1a, 0x6f, 0x38, 0x84, 0xf6, 0xf0, 0x0e, 0x2e, 0x90, 0xc3, 0x12, + 0x42, 0x3f, 0x56, 0x46, 0x00, 0xe8, 0xb3, 0xd8, 0x6f, 0x78, 0x98, 0x91, 0x81, 0x2f, 0xf1, 0x93, 0xd2, 0x17, 0x17, + 0xef, 0xef, 0x64, 0x26, 0xe8, 0x55, 0xe2, 0xa2, 0xe6, 0xca, 0x76, 0xcc, 0x0f, 0xff, 0x0b, 0x8c, 0x06, 0xe1, 0xb5, + 0x25, 0xdb, 0x17, 0x1d, 0xb3, 0x5c, 0xc1, 0x51, 0x5b, 0xba, 0x32, 0x65, 0xeb, 0xfa, 0x59, 0x0d, 0x33, 0x7d, 0xa6, + 0xbc, 0x01, 0xd9, 0x17, 0x72, 0xf7, 0x53, 0x5d, 0xb1, 0x20, 0x47, 0x93, 0xf1, 0x94, 0x88, 0xc1, 0xa0, 0x95, 0x7c, + 0x88, 0xc9, 0xc3, 0xe1, 0x0e, 0x73, 0x29, 0x74, 0x3f, 0xbc, 0x3e, 0x40, 0x7d, 0x8d, 0x2d, 0x49, 0x36, 0x15, 0xfb, + 0x1b, 0xcc, 0x62, 0x81, 0x38, 0x3a, 0xf8, 0xc5, 0xf9, 0x02, 0x40, 0x96, 0x61, 0x99, 0x69, 0x61, 0x91, 0x4c, 0x95, + 0x8f, 0x6c, 0xc1, 0xe4, 0xe1, 0x78, 0xe6, 0xf7, 0xdc, 0x31, 0x38, 0x84, 0x44, 0x13, 0x6b, 0xfc, 0xe2, 0x67, 0xc1, + 0x38, 0x0e, 0xe5, 0x91, 0x6c, 0x7c, 0x57, 0x92, 0x68, 0x6c, 0x4c, 0x95, 0xf5, 0x55, 0xa2, 0x1a, 0x26, 0xe4, 0x61, + 0x41, 0xf6, 0x0b, 0xba, 0xf4, 0xc7, 0x12, 0xd3, 0xf7, 0xe3, 0xfd, 0xc9, 0x98, 0x3c, 0x8c, 0x1f, 0x4e, 0x0c, 0xdc, + 0xb0, 0x9f, 0x23, 0x1f, 0x2e, 0xc9, 0x7e, 0xb3, 0x4a, 0x30, 0x45, 0x35, 0x3d, 0xf3, 0x2b, 0x49, 0x06, 0xcb, 0x41, + 0xfa, 0xb0, 0x95, 0x17, 0x6b, 0xd5, 0xe3, 0xbd, 0x3e, 0xe4, 0x53, 0x22, 0x1a, 0x37, 0x86, 0x35, 0xbd, 0x8c, 0xff, + 0x92, 0x45, 0x24, 0x25, 0x20, 0x12, 0x82, 0x7a, 0x3b, 0x3b, 0xcf, 0x92, 0x58, 0xa4, 0x51, 0x5a, 0x13, 0x9a, 0x1e, + 0xb1, 0xc9, 0x78, 0x96, 0xb2, 0xf4, 0x70, 0xf2, 0x64, 0x36, 0x79, 0x12, 0x1d, 0x8c, 0xa3, 0x74, 0x30, 0x80, 0xe4, + 0x83, 0x31, 0xb8, 0xd8, 0xc1, 0x6f, 0x76, 0x00, 0x43, 0x77, 0x84, 0x2c, 0x61, 0x01, 0x4d, 0xfb, 0xb2, 0x26, 0xe9, + 0xe1, 0x3c, 0x57, 0x3d, 0x89, 0x6f, 0xe8, 0xda, 0x73, 0x70, 0xf1, 0x5b, 0x78, 0xee, 0x5a, 0x78, 0xbe, 0xdb, 0x42, + 0xa1, 0xc9, 0x76, 0x2c, 0xff, 0x7f, 0xdc, 0x30, 0xee, 0xba, 0x4b, 0x98, 0xc5, 0x75, 0x95, 0x8d, 0x56, 0x85, 0xac, + 0x24, 0xdc, 0x26, 0x94, 0x28, 0x6c, 0x14, 0xaf, 0x56, 0xb9, 0x76, 0x11, 0x9b, 0x57, 0x14, 0xc0, 0x5d, 0x20, 0x4e, + 0x31, 0xb0, 0xd0, 0xc6, 0x40, 0xee, 0x13, 0x2f, 0x24, 0xb3, 0x6a, 0x1f, 0x73, 0x8f, 0xfc, 0x2b, 0x04, 0x63, 0x54, + 0x71, 0x34, 0x9e, 0x29, 0xac, 0x8b, 0xcf, 0xc9, 0x7b, 0xff, 0x8d, 0xa3, 0xc8, 0x1e, 0xcd, 0xa0, 0x27, 0x88, 0x9c, + 0x47, 0x9c, 0x3d, 0x99, 0xbc, 0x0c, 0xdc, 0xcf, 0x60, 0xa5, 0xbf, 0xee, 0x36, 0x63, 0x6d, 0x7b, 0x74, 0x2f, 0x8c, + 0x50, 0xf4, 0x13, 0xbe, 0x33, 0xf5, 0x02, 0x2e, 0xa1, 0x1a, 0xd8, 0xf5, 0xc5, 0x05, 0x2f, 0x01, 0x44, 0x28, 0x13, + 0xfd, 0x7e, 0xef, 0x2f, 0x03, 0x4d, 0x5a, 0xf2, 0xe2, 0x55, 0x26, 0xac, 0x33, 0x0e, 0x34, 0x15, 0xa8, 0xff, 0xc7, + 0xca, 0x3e, 0xd3, 0x31, 0x99, 0xf9, 0x8f, 0xc3, 0x09, 0x89, 0x9a, 0xaf, 0xc9, 0x67, 0x4e, 0xd3, 0xcf, 0x5c, 0xd1, + 0xfe, 0x03, 0x99, 0xb9, 0xe1, 0x90, 0xa1, 0xfe, 0xd2, 0x31, 0x4f, 0x46, 0xaf, 0x13, 0xb3, 0x23, 0xc1, 0xaa, 0x19, + 0x44, 0x61, 0x2f, 0xe0, 0x41, 0x5d, 0xcb, 0xe2, 0x29, 0xcc, 0x3e, 0xa8, 0x11, 0xc5, 0x21, 0x1b, 0xcf, 0x42, 0x19, + 0x4e, 0xc0, 0xbe, 0x77, 0x32, 0x86, 0xfb, 0x80, 0x0c, 0x3f, 0x56, 0x21, 0x76, 0x0e, 0xd2, 0x3e, 0x56, 0xa8, 0x98, + 0x00, 0x88, 0x40, 0xc8, 0xdb, 0xef, 0x4b, 0x95, 0x84, 0xaf, 0x4b, 0x4c, 0x29, 0xd4, 0x07, 0xff, 0x89, 0x54, 0xdd, + 0x31, 0xfd, 0x6a, 0xfd, 0xf8, 0x33, 0xa1, 0xf8, 0x74, 0x97, 0x12, 0xdf, 0x40, 0x70, 0xe7, 0x02, 0x74, 0x10, 0x15, + 0x9a, 0xb1, 0xdd, 0xcf, 0xef, 0x8a, 0xbb, 0xf9, 0x5d, 0xf1, 0xff, 0x8e, 0xdf, 0x15, 0xf7, 0x31, 0x86, 0x95, 0x85, + 0x86, 0x9f, 0x05, 0xe3, 0x20, 0xfa, 0xcf, 0xf9, 0xc4, 0x3b, 0x79, 0xea, 0xcb, 0x4c, 0x4c, 0xef, 0x60, 0x9a, 0x7d, + 0x82, 0x82, 0xb0, 0x8a, 0xbb, 0xf4, 0x64, 0x5d, 0xd9, 0x5b, 0x2b, 0x19, 0x62, 0x9e, 0x7b, 0x58, 0xa3, 0xb0, 0xf2, + 0x80, 0xee, 0x51, 0xb5, 0x41, 0x9c, 0x08, 0x1e, 0xc6, 0xcc, 0x4a, 0xdf, 0xb7, 0x5b, 0xa3, 0xc2, 0xbc, 0x97, 0x8b, + 0x82, 0xec, 0xe6, 0xe3, 0xd9, 0x38, 0x0a, 0xb1, 0x01, 0xff, 0x31, 0x63, 0xd5, 0x90, 0xcd, 0x77, 0x32, 0x52, 0x3b, + 0x26, 0x4f, 0x93, 0x5d, 0xd2, 0x3b, 0xe0, 0x1d, 0xf2, 0xf3, 0xfa, 0x63, 0x18, 0x4b, 0xc3, 0x6f, 0xc9, 0x8b, 0xb8, + 0xc8, 0xaa, 0xe5, 0x65, 0x96, 0x20, 0xd3, 0x05, 0x2f, 0xbe, 0x98, 0xe9, 0xf2, 0x3e, 0xd6, 0x07, 0x8c, 0xa7, 0x14, + 0xaf, 0x1b, 0xa2, 0xf4, 0x75, 0xcb, 0xb3, 0x42, 0x5d, 0x9e, 0x54, 0xcc, 0xf6, 0xac, 0x04, 0xa7, 0x53, 0x30, 0xc1, + 0xd7, 0x3f, 0x5d, 0xef, 0x13, 0xc0, 0x05, 0x85, 0x9a, 0xd3, 0x42, 0xae, 0x0c, 0x96, 0x93, 0x85, 0xee, 0x04, 0xcc, + 0x50, 0x29, 0xf0, 0x02, 0x05, 0x7f, 0xd1, 0xc0, 0x88, 0xbe, 0x70, 0xbf, 0xc9, 0xc0, 0x20, 0x5d, 0x9a, 0x13, 0x61, + 0xec, 0xb8, 0x9d, 0x38, 0x6d, 0x45, 0x39, 0xe3, 0xec, 0x9d, 0xba, 0x52, 0x80, 0x01, 0xde, 0xe6, 0x3a, 0x3a, 0x4d, + 0xd0, 0x6b, 0x41, 0xe9, 0xbc, 0x81, 0xbb, 0x59, 0x46, 0x46, 0xb8, 0xf8, 0xb0, 0xf2, 0x58, 0x70, 0xcf, 0x7e, 0x21, + 0xb1, 0xb6, 0x7e, 0x60, 0xcc, 0xe6, 0x05, 0x0b, 0x14, 0x2a, 0x50, 0x60, 0x39, 0xd3, 0x96, 0xa6, 0xd5, 0x90, 0xef, + 0x1f, 0xa0, 0xb5, 0x69, 0x35, 0xe0, 0xfb, 0x07, 0x75, 0x94, 0x1d, 0x42, 0x96, 0x23, 0x3f, 0x83, 0x7a, 0x5d, 0x47, + 0x26, 0xc5, 0x64, 0xf7, 0xeb, 0x4b, 0xfd, 0x51, 0xdd, 0x80, 0xeb, 0x07, 0x20, 0x80, 0x0d, 0xc0, 0x21, 0x50, 0x0d, + 0x96, 0x46, 0x04, 0x8b, 0x32, 0x85, 0xf6, 0x35, 0xf4, 0xde, 0x68, 0xf8, 0x2f, 0x70, 0x17, 0x91, 0x2b, 0xff, 0x13, + 0x04, 0xfe, 0x8a, 0x32, 0xad, 0x4c, 0xf1, 0x3f, 0xd1, 0xea, 0x15, 0xca, 0x59, 0xd3, 0x9a, 0x0f, 0xa2, 0x35, 0x11, + 0xaa, 0x19, 0x43, 0xf0, 0x6f, 0x65, 0x99, 0xb6, 0x54, 0x55, 0xea, 0x43, 0xe3, 0xb5, 0x56, 0x38, 0xcb, 0xc7, 0x91, + 0xf7, 0x1a, 0x43, 0xc7, 0x26, 0xce, 0x52, 0x4e, 0xa5, 0xce, 0x5e, 0xef, 0xcb, 0xc8, 0x01, 0x4e, 0x27, 0x6c, 0x3c, + 0x4d, 0x0e, 0xe5, 0x34, 0x71, 0x90, 0xf9, 0x39, 0xc3, 0xc8, 0xaa, 0x06, 0x84, 0x45, 0xd9, 0x50, 0xda, 0x02, 0x4c, + 0x72, 0x42, 0xc8, 0x14, 0x43, 0x51, 0xe4, 0x23, 0xdd, 0x0f, 0xeb, 0xcd, 0xea, 0xbe, 0x78, 0xab, 0x01, 0x4e, 0xc3, + 0x04, 0x02, 0x81, 0x17, 0xf1, 0x75, 0x26, 0x2e, 0xc0, 0x63, 0x78, 0x00, 0x5f, 0x82, 0x9b, 0x5c, 0xca, 0x7e, 0xab, + 0xc2, 0x1c, 0xd7, 0x16, 0x30, 0x68, 0xb0, 0x7a, 0x10, 0x1d, 0x2e, 0xa5, 0xcd, 0xae, 0x02, 0xc4, 0xc6, 0x14, 0x62, + 0x59, 0xb0, 0xb5, 0x65, 0xcf, 0x7e, 0x56, 0x4d, 0x43, 0xeb, 0x84, 0x63, 0x71, 0x91, 0x43, 0x14, 0x95, 0x41, 0x0c, + 0xee, 0x48, 0x1e, 0x9f, 0xf7, 0x40, 0x84, 0xe7, 0x04, 0xdc, 0xca, 0x12, 0x19, 0xae, 0xe8, 0x72, 0x74, 0x43, 0xd7, + 0xa3, 0x6b, 0x3a, 0xa6, 0x93, 0x7f, 0x8e, 0xd1, 0x22, 0x5b, 0xa5, 0xde, 0xd2, 0xf5, 0x68, 0x49, 0xbf, 0x1d, 0xd3, + 0x83, 0x7f, 0x8c, 0xc9, 0x34, 0xc7, 0xc3, 0x84, 0x9e, 0x83, 0x63, 0x17, 0xa9, 0xd1, 0x53, 0xd3, 0x37, 0x38, 0xac, + 0x46, 0xf9, 0x90, 0x8f, 0x72, 0xca, 0x47, 0xc5, 0xb0, 0x1a, 0x81, 0xa7, 0x63, 0x35, 0xe4, 0xa3, 0x8a, 0xf2, 0xd1, + 0xd9, 0xb0, 0x1a, 0x9d, 0x91, 0x66, 0xd3, 0x5f, 0x56, 0xfc, 0xb2, 0x64, 0x6b, 0xd8, 0x16, 0xb0, 0x7c, 0xdd, 0x2a, + 0xcb, 0x53, 0x7f, 0x55, 0x9b, 0x93, 0xd9, 0x72, 0xf6, 0xf6, 0xba, 0xcb, 0x89, 0xc5, 0xe3, 0xb6, 0xe9, 0x70, 0xf5, + 0xe5, 0x44, 0x9d, 0xf4, 0x0a, 0xf9, 0x61, 0x3c, 0x15, 0xea, 0x1c, 0x02, 0x33, 0x89, 0x59, 0x18, 0x33, 0x6c, 0xa6, + 0x4e, 0x03, 0x05, 0x4e, 0x36, 0xf2, 0x5c, 0x14, 0xb3, 0x51, 0x4e, 0xe1, 0x7d, 0x4c, 0x48, 0x24, 0xe0, 0xac, 0x3a, + 0xaa, 0x46, 0x05, 0xc4, 0x1c, 0x61, 0x21, 0x3e, 0x42, 0xbf, 0xd4, 0x47, 0x1e, 0x12, 0x78, 0x86, 0x7d, 0x2d, 0x06, + 0x31, 0x1c, 0xf1, 0xb6, 0xb2, 0x6a, 0x16, 0x26, 0x50, 0x59, 0x35, 0x2c, 0x4d, 0x65, 0x05, 0xcd, 0x46, 0x95, 0x5f, + 0x59, 0x85, 0x63, 0x94, 0x10, 0x12, 0x95, 0xba, 0x32, 0x50, 0x9f, 0x24, 0x2c, 0x2c, 0x75, 0x65, 0x67, 0xea, 0xa3, + 0x33, 0xbf, 0xb2, 0x33, 0x70, 0x21, 0x1d, 0x24, 0xfe, 0x55, 0x6a, 0x99, 0xb6, 0xaf, 0x83, 0x8d, 0x55, 0x45, 0x37, + 0xfc, 0xa6, 0x2a, 0xe2, 0xa8, 0xa4, 0x2e, 0x06, 0x34, 0x2e, 0x8c, 0x48, 0x52, 0xbd, 0x46, 0xc1, 0x1f, 0x12, 0x44, + 0xa5, 0x31, 0x78, 0x75, 0x26, 0x5d, 0x2b, 0xb5, 0xa2, 0x62, 0x50, 0x0e, 0x0a, 0xb8, 0x3f, 0xe5, 0xad, 0x85, 0xf4, + 0x33, 0x44, 0x54, 0x86, 0xf2, 0x06, 0x1f, 0x30, 0x78, 0x32, 0xbb, 0x48, 0xc3, 0x64, 0x74, 0x4b, 0xe3, 0xd1, 0x12, + 0xe1, 0x60, 0xd8, 0x79, 0xaa, 0xf0, 0xd6, 0x57, 0x90, 0x7e, 0x43, 0xe3, 0xd1, 0x35, 0x4d, 0xad, 0xcd, 0xa9, 0x81, + 0xba, 0xea, 0x8d, 0xe9, 0x4d, 0x04, 0xaf, 0x6f, 0xa3, 0x25, 0x85, 0xad, 0x74, 0x9c, 0x67, 0x17, 0x22, 0x4a, 0x29, + 0x22, 0x10, 0xae, 0x11, 0x39, 0x70, 0xa9, 0xd1, 0x06, 0xd7, 0x03, 0x28, 0x43, 0xc3, 0x05, 0x2e, 0x07, 0xf1, 0x68, + 0xe9, 0x91, 0xa9, 0x54, 0x5f, 0x64, 0x11, 0x3e, 0xda, 0xd9, 0x68, 0x29, 0x9e, 0x11, 0x0b, 0xe3, 0x0a, 0x86, 0x50, + 0x17, 0x56, 0x9a, 0x82, 0xa4, 0x0b, 0x1c, 0xd9, 0x0b, 0xe3, 0x2a, 0xdc, 0x80, 0x69, 0xd1, 0x2d, 0x98, 0x47, 0x81, + 0xc2, 0xc1, 0x25, 0x48, 0x3f, 0xa1, 0x6c, 0xe7, 0x28, 0x4d, 0x0e, 0x6f, 0x82, 0xd6, 0x3b, 0x13, 0x84, 0xb4, 0xab, + 0x9b, 0x6c, 0x49, 0xdf, 0x60, 0x7b, 0x87, 0x4e, 0x45, 0x05, 0xd5, 0xe7, 0x16, 0x4c, 0x96, 0x6c, 0x10, 0xb6, 0x84, + 0xe9, 0x99, 0x5e, 0x03, 0xf6, 0xf4, 0xfe, 0xc1, 0xce, 0x7c, 0x17, 0xb3, 0xd7, 0xfb, 0x65, 0x34, 0x56, 0x16, 0xbc, + 0xb9, 0x25, 0x76, 0x4b, 0x36, 0x9e, 0x2e, 0x0f, 0xcb, 0xe9, 0x12, 0x89, 0x9d, 0xa1, 0x5b, 0x8c, 0xcf, 0x97, 0x0b, + 0x9a, 0xe0, 0xd9, 0xc6, 0xaa, 0xf9, 0xd2, 0xa0, 0xa5, 0xa4, 0x0c, 0xd7, 0xdb, 0x12, 0xfd, 0xff, 0xd5, 0xc5, 0x2f, + 0x05, 0x78, 0x09, 0xc6, 0x02, 0x40, 0xb8, 0x07, 0xd3, 0x82, 0xd4, 0x46, 0xd9, 0x48, 0xd3, 0x30, 0xc5, 0x45, 0x60, + 0x52, 0xfa, 0xfd, 0x30, 0x67, 0x29, 0xf1, 0xa0, 0x43, 0xed, 0x28, 0x9d, 0xa7, 0xbe, 0x10, 0x04, 0x78, 0x24, 0x75, + 0x8e, 0x4d, 0xfe, 0x39, 0x9e, 0x05, 0x6a, 0x20, 0x82, 0x28, 0x3b, 0xc4, 0x47, 0x0c, 0x5c, 0x14, 0xe9, 0xb8, 0x9d, + 0xae, 0x88, 0xd5, 0xee, 0x31, 0x0b, 0x71, 0x92, 0x30, 0xd7, 0x2c, 0x1b, 0xb2, 0x2a, 0xc2, 0x04, 0x5d, 0x18, 0xd8, + 0xaf, 0x0d, 0x59, 0xb5, 0x7f, 0x00, 0x91, 0x5a, 0x6d, 0x19, 0x17, 0x5d, 0x65, 0x7c, 0x0b, 0x40, 0xd6, 0x8c, 0xb1, + 0x83, 0x7f, 0x8c, 0x67, 0xea, 0x9b, 0x28, 0xe4, 0x47, 0x07, 0xff, 0x80, 0xe4, 0xc3, 0x6f, 0x91, 0x99, 0x83, 0xe4, + 0x46, 0x41, 0x97, 0xcd, 0x59, 0xd7, 0x50, 0x9a, 0xb8, 0xf6, 0x4a, 0xbd, 0xf6, 0xa4, 0x59, 0x7b, 0x05, 0xba, 0x53, + 0x1b, 0xde, 0x43, 0xd9, 0xce, 0x82, 0x09, 0x3a, 0x9a, 0xdd, 0x81, 0x0e, 0xde, 0x29, 0x82, 0x5e, 0x26, 0xa1, 0xf1, + 0x08, 0x55, 0x46, 0xbd, 0x18, 0x0f, 0xaa, 0x93, 0x75, 0xc9, 0x3c, 0x03, 0xe6, 0xd8, 0x9e, 0x43, 0x62, 0x98, 0xab, + 0x83, 0x3a, 0x65, 0xe5, 0x30, 0xc7, 0x03, 0x78, 0xcd, 0xe4, 0x50, 0x0c, 0x72, 0x8d, 0xf2, 0x7d, 0xce, 0x8a, 0x61, + 0x39, 0xc8, 0x35, 0x37, 0x33, 0x6d, 0xc6, 0xa6, 0x4d, 0x74, 0x78, 0xe6, 0x15, 0x3b, 0x5a, 0xf5, 0x80, 0x8f, 0x05, + 0x4f, 0x66, 0xdf, 0xf3, 0xf1, 0x29, 0x70, 0x32, 0x9b, 0x9b, 0x68, 0x49, 0x6f, 0xa3, 0x94, 0x5e, 0x47, 0x6b, 0xba, + 0x8c, 0xce, 0x8d, 0x89, 0x71, 0x52, 0xc3, 0x39, 0x00, 0xad, 0x02, 0x48, 0x3c, 0xf5, 0xeb, 0x1d, 0x4f, 0xaa, 0x70, + 0x49, 0x53, 0x70, 0x1b, 0xf6, 0xed, 0x33, 0xcf, 0x7c, 0x89, 0xd4, 0x06, 0x31, 0xd6, 0xac, 0xa1, 0xe2, 0xc6, 0x5b, + 0xf7, 0x91, 0xa8, 0x61, 0xe7, 0xba, 0xd8, 0x44, 0xd5, 0x70, 0x32, 0x2d, 0x01, 0xb1, 0xb5, 0x1c, 0x0e, 0xdd, 0x11, + 0xb2, 0x7b, 0xfc, 0xe8, 0x40, 0xcf, 0x3d, 0x69, 0xb1, 0x6d, 0x5b, 0xfe, 0xc0, 0x10, 0xa6, 0xf4, 0xf3, 0x47, 0x3e, + 0x20, 0x56, 0x5c, 0xc2, 0xd9, 0x08, 0xd4, 0xd1, 0x0a, 0x9d, 0x7e, 0xab, 0xc2, 0x42, 0x1f, 0xe0, 0x9b, 0x9b, 0x28, + 0xa1, 0xb7, 0x51, 0xee, 0x91, 0xb5, 0x65, 0xcd, 0xe4, 0xf4, 0x34, 0x0b, 0x79, 0xfb, 0x40, 0x2f, 0x17, 0x00, 0xa2, + 0x35, 0x88, 0x7d, 0xa9, 0xeb, 0x01, 0x38, 0x0d, 0xa1, 0x49, 0x68, 0x04, 0x57, 0x15, 0x84, 0x11, 0x70, 0x25, 0xe1, + 0x6f, 0x30, 0x51, 0x81, 0x2f, 0xc0, 0x45, 0x26, 0x4d, 0x73, 0x1e, 0xd4, 0xfe, 0x48, 0xbe, 0x2a, 0xda, 0xde, 0xae, + 0x30, 0x9a, 0x60, 0xec, 0x89, 0xf6, 0x79, 0xa4, 0x1c, 0xc5, 0x45, 0x12, 0x66, 0xa3, 0x1b, 0x75, 0x9e, 0xd3, 0x6c, + 0x74, 0xab, 0x7f, 0x55, 0x74, 0x4c, 0x7f, 0xd1, 0x01, 0x6d, 0x94, 0xf4, 0xad, 0xe3, 0x6c, 0x40, 0xeb, 0xc5, 0xd2, + 0xf8, 0x5f, 0xcb, 0xd1, 0x0d, 0x95, 0xa3, 0x5b, 0xdf, 0x92, 0x6a, 0x32, 0x2d, 0x0e, 0x05, 0x1a, 0x52, 0x75, 0x7e, + 0x5f, 0x00, 0x3f, 0x57, 0x1a, 0xdf, 0x69, 0xf3, 0xbd, 0xd7, 0xfe, 0xd3, 0x4e, 0x9e, 0x40, 0xb1, 0x44, 0x05, 0xab, + 0x46, 0x60, 0xc7, 0xbe, 0xce, 0xe3, 0xc2, 0x8c, 0x52, 0x4c, 0xad, 0x49, 0x3f, 0x06, 0xae, 0x98, 0xf6, 0x0a, 0x70, + 0xb5, 0x04, 0x27, 0x01, 0x88, 0xa1, 0x09, 0x7b, 0x76, 0x0c, 0x51, 0xcf, 0x8d, 0x63, 0x94, 0x6c, 0xb8, 0x07, 0xc4, + 0x5a, 0xe6, 0xad, 0x5c, 0x02, 0x12, 0x78, 0xeb, 0x61, 0x52, 0x00, 0xc6, 0x60, 0xb9, 0x24, 0x3a, 0x8f, 0x87, 0x3e, + 0xa1, 0x5e, 0x68, 0xd4, 0x09, 0xd9, 0xd8, 0x12, 0x38, 0xfe, 0xb0, 0x3e, 0x04, 0x82, 0x57, 0x79, 0xae, 0xbf, 0xd2, + 0xba, 0xfe, 0x52, 0xe9, 0xb9, 0x63, 0xb9, 0xae, 0xdf, 0xb6, 0xa9, 0xd1, 0x0b, 0xb0, 0xf0, 0xdd, 0x28, 0xf3, 0x48, + 0x6e, 0x11, 0x52, 0x15, 0x58, 0xa9, 0x5b, 0x48, 0x30, 0xff, 0x4a, 0xce, 0x56, 0x65, 0xbe, 0x7a, 0xe4, 0x5e, 0x39, + 0x9b, 0x9e, 0xfe, 0x86, 0x04, 0xed, 0xb6, 0x23, 0xcd, 0xe3, 0x2d, 0x3a, 0x7c, 0x76, 0xad, 0x25, 0xe6, 0x4e, 0xa2, + 0xe2, 0xf9, 0x14, 0xb0, 0xd5, 0xb3, 0xec, 0x52, 0xf9, 0x58, 0xed, 0xe2, 0xf8, 0x99, 0xf3, 0x27, 0xa9, 0xc2, 0xb5, + 0x68, 0x28, 0x41, 0xc0, 0x9b, 0xc3, 0xd8, 0x15, 0xaa, 0x80, 0x86, 0xe6, 0x06, 0x8e, 0x73, 0x35, 0xac, 0x34, 0x01, + 0xd3, 0x52, 0x1e, 0x1d, 0xe0, 0xd0, 0xe4, 0x51, 0xbb, 0x69, 0x58, 0x19, 0xba, 0xd6, 0xe8, 0x73, 0x5b, 0xe9, 0x8c, + 0x37, 0x1b, 0xbe, 0x7f, 0x30, 0xa8, 0xf0, 0x27, 0x69, 0x8e, 0x46, 0x3b, 0x37, 0xdc, 0x69, 0x04, 0x66, 0xae, 0xe4, + 0x8a, 0xec, 0x8e, 0x92, 0x97, 0xdf, 0xd3, 0x0b, 0x0b, 0xe8, 0xcf, 0x7f, 0x2e, 0x26, 0x9c, 0xb4, 0xc4, 0x84, 0x68, + 0xe9, 0xa0, 0x45, 0x07, 0x3b, 0xca, 0x2b, 0xfb, 0x12, 0x2f, 0x9d, 0xe3, 0x7f, 0x5f, 0x8f, 0xb5, 0xab, 0x40, 0x68, + 0x75, 0x72, 0xbf, 0x3d, 0x59, 0x20, 0x6a, 0x40, 0x35, 0xbb, 0x2a, 0x47, 0x99, 0x76, 0x56, 0x64, 0xd3, 0x90, 0xb9, + 0xee, 0x66, 0x69, 0xd8, 0x4c, 0x76, 0x2c, 0x2c, 0x33, 0x0c, 0xd6, 0x4e, 0x15, 0x7d, 0x0e, 0x5a, 0x7e, 0x04, 0x2f, + 0x9b, 0xca, 0x33, 0x9f, 0xcd, 0x32, 0xe2, 0x05, 0x3a, 0xe7, 0x54, 0x2c, 0x9a, 0xd2, 0xb1, 0x72, 0xbb, 0x2d, 0xd1, + 0x58, 0xa2, 0x8c, 0x82, 0xa0, 0xb6, 0x41, 0xd8, 0x75, 0xe9, 0x9e, 0xf4, 0x69, 0x17, 0x9f, 0x56, 0xa0, 0xef, 0xf1, + 0x5d, 0x06, 0x12, 0x53, 0x4f, 0xf2, 0x50, 0x35, 0x9a, 0xa3, 0x93, 0x67, 0x49, 0xaa, 0xf1, 0xf9, 0x95, 0xec, 0xac, + 0x79, 0xb7, 0x1a, 0x53, 0xfc, 0x47, 0xea, 0xf6, 0x9d, 0xcb, 0xd0, 0x44, 0x7f, 0x2d, 0x0f, 0x5a, 0x0a, 0x0b, 0x8e, + 0xdb, 0xc6, 0x5f, 0xbf, 0xcd, 0x1c, 0x62, 0x58, 0xba, 0x1c, 0xde, 0x84, 0x0e, 0xdd, 0x5d, 0x65, 0x67, 0xae, 0x0f, + 0xa8, 0x53, 0x17, 0xeb, 0x36, 0xa0, 0x64, 0xc9, 0xbb, 0x75, 0x7a, 0x62, 0xa5, 0x5f, 0xf6, 0xc3, 0x9d, 0x79, 0xd4, + 0xec, 0xee, 0x76, 0x3b, 0x21, 0x6d, 0xfb, 0x60, 0xbc, 0x2f, 0x61, 0x21, 0xce, 0x3b, 0x6c, 0xef, 0xe7, 0xb0, 0x7a, + 0xc8, 0x07, 0x7f, 0xe0, 0x38, 0xc3, 0xe8, 0x67, 0xca, 0xd0, 0xe7, 0x45, 0x21, 0x2f, 0x55, 0xa7, 0x7c, 0xa1, 0x5b, + 0xcb, 0xd4, 0xfb, 0x75, 0xfc, 0xba, 0x15, 0x20, 0xc6, 0xeb, 0x8a, 0x95, 0xe2, 0x0d, 0xad, 0x30, 0xae, 0x81, 0xdb, + 0xe4, 0x50, 0x4b, 0xb5, 0x40, 0xd4, 0xe5, 0x27, 0x0f, 0x79, 0x64, 0xd4, 0x99, 0xf0, 0xdd, 0x43, 0xee, 0x4b, 0xd7, + 0x76, 0x9b, 0xf8, 0xb9, 0xa6, 0xed, 0xef, 0x0e, 0x74, 0x47, 0xeb, 0xee, 0x6f, 0x9e, 0xcd, 0xcf, 0x23, 0xf3, 0xc5, + 0x00, 0x9b, 0xb5, 0xcb, 0xb8, 0xec, 0x18, 0xee, 0x7b, 0xd3, 0x83, 0xb1, 0x80, 0x40, 0x62, 0x86, 0x5e, 0x06, 0x2e, + 0x70, 0x81, 0xbb, 0xc2, 0x80, 0x21, 0xae, 0x69, 0xc9, 0xad, 0xb6, 0xb2, 0xf5, 0x91, 0xb7, 0x51, 0x21, 0x58, 0xd7, + 0x1d, 0x37, 0x49, 0x0e, 0xc1, 0x09, 0x5b, 0xee, 0x7d, 0xed, 0xb5, 0x33, 0xfc, 0x30, 0x10, 0xce, 0x2d, 0xd1, 0x33, + 0x6a, 0x7b, 0xa8, 0xd5, 0xbd, 0x86, 0x57, 0xb9, 0x8d, 0x3c, 0xeb, 0x37, 0xf3, 0xd2, 0xb0, 0x2f, 0x78, 0x2d, 0x05, + 0x87, 0xc6, 0x76, 0x2b, 0xdc, 0x62, 0xf1, 0x8e, 0x56, 0x2b, 0x6b, 0x6d, 0xb5, 0xd7, 0x4a, 0x45, 0xef, 0x5e, 0x73, + 0x9c, 0x38, 0x4b, 0x61, 0xfb, 0xe1, 0xfd, 0x05, 0xbb, 0x26, 0x80, 0x41, 0x8b, 0xc9, 0x02, 0x25, 0xa8, 0x64, 0xad, + 0x6a, 0xb7, 0x53, 0xe2, 0x97, 0xfb, 0x45, 0x97, 0xd9, 0xce, 0xe3, 0xd7, 0x4d, 0xda, 0x67, 0x3e, 0x47, 0x3f, 0xcc, + 0xef, 0xac, 0x93, 0x92, 0x33, 0x8c, 0x6b, 0xf9, 0xff, 0x55, 0xf4, 0xa2, 0xc8, 0xd2, 0x68, 0x63, 0x78, 0x30, 0x1b, + 0x6a, 0xd3, 0x87, 0xc6, 0xa8, 0xdc, 0xb2, 0x51, 0x44, 0xb4, 0xba, 0x01, 0xc1, 0x8c, 0xe2, 0xbe, 0x44, 0x9b, 0x57, + 0xaa, 0x2c, 0xbc, 0xc3, 0x67, 0x36, 0x7a, 0xc3, 0xf6, 0x84, 0x50, 0xbe, 0x7b, 0x5a, 0x98, 0x55, 0x4b, 0x45, 0x83, + 0xed, 0x12, 0xde, 0xc5, 0xa8, 0xd2, 0x4f, 0x98, 0x6c, 0x59, 0x30, 0xd5, 0xff, 0xef, 0x8b, 0x2c, 0x6d, 0x53, 0x74, + 0x60, 0x3a, 0x9b, 0x3e, 0x9d, 0x74, 0x83, 0xeb, 0x0c, 0x58, 0x44, 0xb0, 0xa5, 0xc2, 0xf1, 0x28, 0xb5, 0x1b, 0x24, + 0x4c, 0x04, 0x37, 0x51, 0x2f, 0x3b, 0x5a, 0xa6, 0x64, 0x55, 0xc0, 0xf3, 0x2b, 0x57, 0x99, 0x8e, 0xa3, 0xa1, 0xdf, + 0x3f, 0x4b, 0x4d, 0xe8, 0x57, 0xea, 0xa5, 0x2a, 0xce, 0xc3, 0xa8, 0x3a, 0x54, 0x18, 0xa3, 0x25, 0x4d, 0xe1, 0x18, + 0xcc, 0xce, 0xc3, 0x14, 0x2f, 0x67, 0x9b, 0x84, 0x7d, 0xc1, 0x40, 0x2e, 0xb5, 0x41, 0xbd, 0xa6, 0x44, 0x6b, 0xd6, + 0xde, 0xcc, 0x29, 0xa1, 0xe7, 0xac, 0xf4, 0xef, 0x42, 0x6b, 0x10, 0x28, 0xca, 0x66, 0xca, 0xf4, 0x54, 0xb7, 0xf3, + 0x9c, 0x26, 0xb4, 0xa0, 0x2b, 0x52, 0x83, 0xbe, 0xd7, 0xc9, 0xd9, 0xd1, 0xc9, 0xce, 0xcc, 0x7a, 0xcc, 0x8a, 0xe1, + 0x64, 0x1a, 0xc3, 0x35, 0x2d, 0x76, 0xd7, 0xb4, 0x65, 0xf3, 0xc6, 0xd5, 0xd8, 0x38, 0x0d, 0xda, 0x05, 0xd2, 0x36, + 0xcd, 0xed, 0xa7, 0x1e, 0xb7, 0xbf, 0xae, 0xd9, 0x72, 0xda, 0x5b, 0x6f, 0xb7, 0xbd, 0x14, 0x6c, 0x44, 0x3d, 0x3e, + 0x7e, 0xad, 0xa4, 0xeb, 0x96, 0xcb, 0x4f, 0xe1, 0xd9, 0xe3, 0xeb, 0x97, 0x3e, 0xb8, 0x1c, 0xad, 0xda, 0xdc, 0xfd, + 0x72, 0x17, 0x59, 0xee, 0x8b, 0x86, 0x96, 0xeb, 0x19, 0x6a, 0x92, 0x67, 0xa3, 0xbd, 0x43, 0x2d, 0x58, 0xce, 0xba, + 0x09, 0x4f, 0x0c, 0x76, 0xec, 0x55, 0x63, 0x73, 0x54, 0xe6, 0x92, 0xd5, 0x20, 0x81, 0x3e, 0xc9, 0x33, 0x4d, 0x7f, + 0x2f, 0xc3, 0x7c, 0x74, 0x43, 0x73, 0xc0, 0x15, 0xab, 0xec, 0x25, 0x83, 0xd4, 0x55, 0x7b, 0x89, 0x2b, 0x5f, 0xe1, + 0x90, 0x6c, 0xf0, 0xc9, 0x30, 0x55, 0x9f, 0x5d, 0xf2, 0xe0, 0xff, 0x6d, 0xd5, 0x2a, 0x3d, 0x37, 0xc9, 0x0d, 0xc7, + 0xbf, 0x4e, 0xda, 0x3e, 0x26, 0x06, 0x09, 0x78, 0x6a, 0x17, 0x43, 0x35, 0xaa, 0x8a, 0x58, 0x94, 0xb9, 0x89, 0x39, + 0x76, 0x67, 0xd7, 0xd0, 0x41, 0x19, 0xfc, 0xba, 0xe1, 0x13, 0x73, 0x07, 0xb6, 0x02, 0x1d, 0x9d, 0x68, 0x2e, 0xc3, + 0xcc, 0x5c, 0x86, 0x69, 0xd7, 0x56, 0x81, 0xe1, 0x55, 0x5b, 0x25, 0x51, 0xae, 0x46, 0x3d, 0x6e, 0x66, 0xa9, 0xd9, + 0x8b, 0xbc, 0x7b, 0x4d, 0x7a, 0x12, 0x7f, 0xba, 0xf4, 0xe4, 0xf5, 0x30, 0x20, 0xf2, 0x4b, 0x96, 0x86, 0x6b, 0x14, + 0x04, 0xa7, 0x56, 0x3b, 0x90, 0xe6, 0x23, 0x40, 0xe6, 0xc7, 0x69, 0xf8, 0x4e, 0x8b, 0x73, 0xc8, 0x46, 0x69, 0x9c, + 0xd8, 0xd2, 0xa8, 0x87, 0xe0, 0xce, 0x7b, 0xc9, 0x63, 0x08, 0x7c, 0xf8, 0x1e, 0x37, 0x83, 0x8a, 0x6e, 0x4b, 0x4c, + 0x94, 0x36, 0x8f, 0xba, 0xe5, 0xa3, 0x86, 0x50, 0xc9, 0xca, 0xf0, 0x12, 0x68, 0xef, 0x8e, 0xc0, 0xa8, 0x72, 0x02, + 0x99, 0x61, 0xb1, 0x7f, 0x30, 0x4c, 0x95, 0xa0, 0x68, 0x28, 0x87, 0x4b, 0x94, 0x03, 0x62, 0x12, 0x08, 0x8c, 0x8a, + 0x41, 0xaa, 0x2b, 0x53, 0x2f, 0x06, 0xa9, 0xbe, 0x55, 0x91, 0xfa, 0x34, 0x0b, 0x2b, 0xaa, 0x5b, 0x44, 0xc7, 0x74, + 0x28, 0xe9, 0xd2, 0xec, 0xd4, 0x5c, 0x4b, 0x2f, 0xd4, 0x72, 0x7c, 0xaa, 0xd3, 0x60, 0x14, 0x4f, 0x5c, 0x8a, 0x7e, + 0xab, 0xf6, 0xb3, 0xff, 0x16, 0x53, 0x6a, 0xc4, 0xa6, 0xf6, 0x16, 0x31, 0xac, 0xda, 0xf7, 0x59, 0x95, 0x83, 0x76, + 0x17, 0x94, 0x8d, 0x95, 0x71, 0x9e, 0x6f, 0x04, 0x33, 0x07, 0x6d, 0x63, 0xd5, 0xf4, 0xa1, 0x37, 0x62, 0xd4, 0xde, + 0x98, 0x6a, 0xdc, 0x13, 0xf8, 0x69, 0x83, 0xa6, 0x7b, 0x91, 0xe7, 0xa8, 0x47, 0xde, 0xfd, 0xcf, 0x1c, 0xd9, 0x99, + 0x7c, 0x16, 0xcb, 0xa4, 0x6e, 0x1f, 0x93, 0x60, 0xa1, 0xea, 0x18, 0x5d, 0xb8, 0x91, 0x29, 0xed, 0xe7, 0xce, 0xf4, + 0x23, 0x9e, 0xc9, 0xfd, 0x76, 0x68, 0xd4, 0x97, 0x86, 0xb5, 0xa4, 0x88, 0xfa, 0x82, 0xde, 0x9a, 0xea, 0xe8, 0x80, + 0x7a, 0x1d, 0x81, 0xd5, 0x15, 0x6d, 0x50, 0x03, 0x30, 0x19, 0xd7, 0xb6, 0x36, 0x9f, 0x83, 0xa9, 0xad, 0xaa, 0xe0, + 0x09, 0xdd, 0x15, 0x4a, 0xf7, 0x26, 0x75, 0xdd, 0x1a, 0x62, 0x0b, 0x18, 0x10, 0xb8, 0xd1, 0x53, 0xd3, 0x1f, 0x34, + 0x51, 0x01, 0x68, 0xd0, 0xb8, 0x9d, 0xe9, 0x1c, 0x89, 0x7e, 0xa7, 0x36, 0x6d, 0x33, 0xd5, 0xab, 0xca, 0x07, 0x50, + 0xf1, 0x67, 0xe9, 0xf4, 0xdc, 0x8c, 0x58, 0x00, 0xe3, 0x1e, 0x38, 0x53, 0xbd, 0xe3, 0x0c, 0xac, 0x27, 0xf2, 0x3c, + 0x2b, 0x79, 0x22, 0x05, 0xcc, 0x88, 0xbc, 0xbc, 0x94, 0x02, 0x86, 0x41, 0x0d, 0x00, 0x5a, 0x34, 0x97, 0xd1, 0x84, + 0x3f, 0xaa, 0xe9, 0x5d, 0x79, 0xf8, 0x23, 0x9d, 0xeb, 0x9b, 0x71, 0x0d, 0x86, 0xca, 0xeb, 0x8a, 0xef, 0x64, 0xfa, + 0x86, 0x3f, 0xf6, 0x32, 0x2d, 0xe5, 0xba, 0xd8, 0xc9, 0xf2, 0xe8, 0x1b, 0xfe, 0x44, 0xe7, 0x39, 0x78, 0x5c, 0xd3, + 0x34, 0xbe, 0xdd, 0xc9, 0xf2, 0xcf, 0x6f, 0x1e, 0xdb, 0x3c, 0x8f, 0xc6, 0x35, 0xbd, 0xe6, 0xfc, 0xa3, 0xcb, 0x34, + 0xd1, 0x55, 0x8d, 0x1f, 0xff, 0xd3, 0xe6, 0x7a, 0x5c, 0xd3, 0x4b, 0x29, 0xaa, 0xe5, 0x4e, 0x51, 0x07, 0xdf, 0x1c, + 0xfc, 0x93, 0x7f, 0x63, 0xba, 0x77, 0x50, 0xd3, 0xbf, 0xd7, 0x71, 0x51, 0xf1, 0x62, 0xa7, 0xb8, 0x7f, 0xfc, 0xf3, + 0x9f, 0x8f, 0x6d, 0xc6, 0xc7, 0x35, 0xbd, 0xe5, 0x71, 0x47, 0xdb, 0x27, 0x4f, 0x1e, 0xf3, 0x7f, 0xd4, 0x35, 0xfd, + 0x95, 0xf9, 0xc1, 0x51, 0x8f, 0x33, 0x4f, 0x0f, 0x9f, 0xcb, 0x26, 0x6a, 0xc0, 0xd0, 0x43, 0x03, 0x58, 0x4a, 0xab, + 0xa6, 0xb9, 0xc3, 0x2b, 0x17, 0xdc, 0xbe, 0x4f, 0xe3, 0x34, 0x5e, 0xc1, 0x41, 0xb0, 0x41, 0xe3, 0xac, 0x02, 0x38, + 0x55, 0xe0, 0x3d, 0xa3, 0x92, 0x66, 0xa5, 0xfc, 0x95, 0xf3, 0x8f, 0x30, 0x68, 0x08, 0x69, 0xa3, 0x22, 0x03, 0xbd, + 0x59, 0xe9, 0xc8, 0x46, 0xe8, 0xbf, 0xd9, 0x8c, 0x83, 0xe3, 0xc3, 0xe8, 0xf5, 0xfb, 0x61, 0xc1, 0x44, 0x58, 0x10, + 0x42, 0xff, 0x0a, 0x0b, 0x70, 0x28, 0x29, 0x98, 0x97, 0xcf, 0xf8, 0x9e, 0x6b, 0xa3, 0xb0, 0x10, 0x44, 0x77, 0x91, + 0x7d, 0x40, 0xd5, 0xa3, 0xef, 0xd0, 0x0d, 0xf1, 0xb2, 0xc2, 0x82, 0xa1, 0x55, 0x0d, 0xcc, 0x10, 0x14, 0xff, 0x8a, + 0x87, 0x12, 0x7c, 0xe2, 0x01, 0x3e, 0x7a, 0x4c, 0x66, 0x5c, 0x5d, 0x6b, 0xdf, 0x9c, 0x87, 0x05, 0x0d, 0x74, 0xdb, + 0x21, 0xe8, 0x40, 0xe4, 0xbf, 0x00, 0x4f, 0x81, 0x81, 0x0f, 0x0b, 0xbb, 0xee, 0xc0, 0xf3, 0xf9, 0xd5, 0xb0, 0x8e, + 0x2e, 0xfc, 0xe8, 0xaf, 0xd6, 0x85, 0x3d, 0x23, 0x53, 0x79, 0x58, 0x0e, 0x27, 0xd3, 0xc1, 0x40, 0xba, 0x38, 0x6e, + 0xc7, 0xd9, 0xfc, 0xd7, 0xb9, 0x5c, 0x2c, 0x50, 0xf7, 0x8d, 0xf3, 0x3a, 0xd3, 0x7f, 0x23, 0xed, 0x7c, 0xf0, 0xea, + 0xf8, 0xb7, 0xd3, 0x93, 0xe3, 0x17, 0xe0, 0x7c, 0xf0, 0xfe, 0xf9, 0xf7, 0xcf, 0xdf, 0xa9, 0xe0, 0xee, 0x6a, 0xce, + 0xfb, 0x7d, 0x27, 0xf5, 0x09, 0xf9, 0xb0, 0x22, 0xfb, 0x61, 0xfc, 0xb0, 0x50, 0x46, 0x0f, 0xe4, 0x90, 0x59, 0x28, + 0x64, 0xa8, 0xa2, 0xb6, 0xbf, 0xcb, 0xe1, 0xc4, 0x03, 0xb3, 0xb8, 0x69, 0x88, 0x70, 0xfd, 0x96, 0xdb, 0x20, 0x6b, + 0xf2, 0xc8, 0xeb, 0x07, 0x27, 0x53, 0xe9, 0xd8, 0xc2, 0x82, 0x41, 0xd9, 0xd0, 0xa6, 0xe3, 0x6c, 0x5e, 0x2c, 0x6c, + 0xbb, 0xdc, 0x02, 0x19, 0xa5, 0xd9, 0xf9, 0x79, 0xa8, 0xa0, 0xab, 0x8f, 0x40, 0x03, 0x60, 0x1a, 0x55, 0xb8, 0x16, + 0xf1, 0x99, 0x5f, 0x7e, 0x34, 0xf6, 0x9a, 0x77, 0x85, 0xba, 0x27, 0xd3, 0xac, 0xaa, 0x31, 0xa0, 0x83, 0x09, 0xe5, + 0x6e, 0xd0, 0x4d, 0x30, 0x19, 0xd5, 0x96, 0x5f, 0xe7, 0xd5, 0xc2, 0x34, 0xc7, 0x0d, 0x43, 0xe5, 0x95, 0x7c, 0x2e, + 0x1b, 0x88, 0x0c, 0x24, 0xc3, 0xb0, 0x47, 0x63, 0x14, 0xa9, 0xef, 0xed, 0x7a, 0xc7, 0x6f, 0x72, 0x09, 0xd1, 0x14, + 0x33, 0x90, 0xce, 0x1f, 0x0b, 0xe5, 0x5c, 0x2e, 0x19, 0x9f, 0x8b, 0xc5, 0x11, 0xb8, 0x9d, 0xcf, 0xc5, 0x22, 0xc2, + 0xa0, 0x7c, 0x19, 0xc4, 0x2a, 0x01, 0xbb, 0x17, 0x07, 0xe1, 0xdb, 0x09, 0x6d, 0x60, 0x37, 0x90, 0x64, 0x83, 0xd2, + 0xae, 0x34, 0x44, 0xb9, 0x53, 0x1e, 0x6d, 0x10, 0x79, 0x88, 0x55, 0xf3, 0xaa, 0xed, 0xc9, 0x66, 0x2e, 0x26, 0xb8, + 0xca, 0x62, 0x26, 0xa7, 0xf1, 0x21, 0x2b, 0xa6, 0x31, 0x94, 0x12, 0xa7, 0x69, 0x18, 0xd3, 0x09, 0x15, 0x84, 0x24, + 0x8c, 0xcf, 0xe3, 0x05, 0x4d, 0x50, 0x4a, 0x10, 0x42, 0xc8, 0x8f, 0x11, 0xda, 0xe6, 0xc0, 0x92, 0xb7, 0xdb, 0xcf, + 0xd3, 0xcf, 0xed, 0x18, 0x2e, 0xa3, 0x22, 0x74, 0x83, 0xce, 0x1a, 0xfe, 0x8d, 0xa8, 0xa0, 0x31, 0x56, 0x0c, 0x41, + 0xc0, 0x0b, 0x8c, 0x4a, 0x58, 0x90, 0x98, 0x55, 0x10, 0x45, 0xa0, 0x9c, 0xc7, 0x0b, 0x56, 0xd0, 0xa6, 0xcd, 0x69, + 0xac, 0x4d, 0x82, 0x7a, 0x0e, 0x4b, 0x6d, 0x4f, 0x2a, 0x15, 0x62, 0x8f, 0xcf, 0x44, 0x74, 0xad, 0x0d, 0x0d, 0x00, + 0x05, 0x4a, 0xc9, 0xc5, 0xaf, 0xbf, 0xdc, 0xc3, 0x4d, 0x41, 0xff, 0xb3, 0x8d, 0x89, 0x76, 0x96, 0xab, 0x43, 0x6f, + 0xbe, 0xa0, 0x71, 0x9e, 0x43, 0x28, 0x36, 0x83, 0x40, 0x2e, 0xb2, 0x0a, 0x22, 0x5a, 0xdc, 0x06, 0x26, 0x24, 0x1c, + 0xb4, 0xe9, 0x03, 0xa4, 0x36, 0xc4, 0xe4, 0xca, 0x13, 0x03, 0xbb, 0xad, 0x12, 0x04, 0x1c, 0xe9, 0x79, 0xf6, 0xa9, + 0x89, 0xb1, 0xa6, 0xa9, 0x99, 0x89, 0xb7, 0xa1, 0x10, 0x0d, 0x5a, 0x10, 0xcd, 0xe0, 0xfd, 0x73, 0xc9, 0xf1, 0xaa, + 0x03, 0x3f, 0xe0, 0x9d, 0x8b, 0x33, 0xaf, 0x66, 0x1e, 0x91, 0x53, 0x8f, 0x73, 0x44, 0xbf, 0xe4, 0x61, 0x35, 0xd2, + 0xc9, 0x18, 0x2b, 0x89, 0x83, 0xde, 0x06, 0x0b, 0xe6, 0x84, 0xae, 0x78, 0x68, 0xf9, 0xf8, 0x17, 0xc8, 0x64, 0x94, + 0xd4, 0x58, 0xd1, 0x95, 0x16, 0x23, 0xce, 0x6b, 0x98, 0xa5, 0xc9, 0x8a, 0x2e, 0x16, 0x9a, 0x34, 0x0b, 0x65, 0x1a, + 0xe0, 0x13, 0x68, 0x31, 0x72, 0x0f, 0x35, 0x6d, 0x20, 0x34, 0xec, 0x0e, 0x01, 0x1f, 0xb9, 0x87, 0x0e, 0xff, 0x3f, + 0xcf, 0x2e, 0x10, 0x69, 0xef, 0xd2, 0x44, 0xc6, 0x23, 0x75, 0x03, 0x07, 0xc5, 0xf8, 0xd8, 0x37, 0x13, 0xbf, 0x70, + 0x46, 0xef, 0x93, 0xca, 0x77, 0xf8, 0x60, 0xf9, 0xe3, 0x4d, 0xcd, 0xac, 0x8c, 0x60, 0x3d, 0x6c, 0xb7, 0xb8, 0x20, + 0xda, 0x2e, 0x80, 0xd4, 0x33, 0x5e, 0x2d, 0x7c, 0xe3, 0xd5, 0xf8, 0x0e, 0xe3, 0x55, 0x67, 0x85, 0x15, 0xe6, 0x64, + 0x83, 0xfa, 0x2c, 0x25, 0xcf, 0xcf, 0x51, 0x26, 0xd8, 0x74, 0x39, 0x2b, 0xa9, 0x4a, 0x25, 0xb4, 0x17, 0xfb, 0x19, + 0xe3, 0x1b, 0x82, 0x71, 0x56, 0x1c, 0x46, 0x02, 0x55, 0xa9, 0xa4, 0x0e, 0x7b, 0x05, 0xa8, 0xc7, 0xe0, 0xbd, 0xc1, + 0x10, 0x35, 0x32, 0x76, 0xd3, 0x06, 0x42, 0x43, 0x63, 0x3d, 0xda, 0xb3, 0xd6, 0xa3, 0xdb, 0x6d, 0x65, 0xfc, 0xed, + 0xe4, 0xba, 0x48, 0x10, 0x55, 0x58, 0x8d, 0x26, 0xc0, 0x9b, 0x26, 0xf6, 0xb6, 0xe4, 0x94, 0x16, 0x18, 0x3e, 0xfb, + 0xaf, 0xb0, 0x74, 0x2a, 0x89, 0x92, 0xcc, 0xca, 0x68, 0xe0, 0xce, 0xc1, 0x67, 0x71, 0x05, 0x6b, 0x00, 0x22, 0x39, + 0xa2, 0x87, 0xeb, 0x5f, 0xa1, 0x74, 0x99, 0x25, 0x99, 0x49, 0xc8, 0xcc, 0x45, 0xda, 0xce, 0x3a, 0x98, 0x38, 0x93, + 0x5a, 0x6f, 0x2c, 0xe4, 0xd0, 0x20, 0x3f, 0x80, 0x32, 0xc4, 0xe1, 0x93, 0x0f, 0x26, 0x54, 0xaa, 0x50, 0xaa, 0x8d, + 0x6e, 0x76, 0x03, 0xaf, 0xbc, 0xcf, 0x2e, 0x79, 0x59, 0xc5, 0x97, 0x2b, 0x63, 0x49, 0xcc, 0xd9, 0x5d, 0x6e, 0x7b, + 0x54, 0x98, 0x57, 0xaf, 0x9f, 0x7f, 0x7f, 0xdc, 0x78, 0xb5, 0x8b, 0x38, 0x1a, 0x82, 0x6d, 0xc5, 0x18, 0xa3, 0xb7, + 0xf8, 0x34, 0x98, 0x28, 0xd7, 0x08, 0xf4, 0x2e, 0x05, 0xfd, 0xf6, 0x97, 0x7a, 0x02, 0x5e, 0x72, 0xbd, 0xfc, 0x92, + 0x8f, 0x80, 0x25, 0x2a, 0xf4, 0xac, 0x30, 0x37, 0x2b, 0xb3, 0x3b, 0xbb, 0x15, 0x99, 0x69, 0x57, 0x1a, 0x19, 0x88, + 0x57, 0xdb, 0x61, 0x2c, 0x5c, 0xba, 0xa6, 0xdb, 0xc1, 0xae, 0x96, 0x9e, 0x25, 0xf2, 0x76, 0x5b, 0x42, 0x87, 0xec, + 0x80, 0x7b, 0x2f, 0xe3, 0x1b, 0x78, 0x59, 0x7a, 0xdd, 0x6c, 0x06, 0x4f, 0x00, 0x33, 0xe1, 0xc2, 0x59, 0x16, 0xc7, + 0x2c, 0x4b, 0x42, 0x15, 0x9b, 0xab, 0x21, 0xf2, 0x56, 0x84, 0xd6, 0xec, 0xaf, 0x50, 0x8c, 0xc0, 0xee, 0xe4, 0xe4, + 0x63, 0xb6, 0x9a, 0xad, 0x01, 0x35, 0xff, 0x32, 0x13, 0x40, 0x73, 0xed, 0x5a, 0xb0, 0x4d, 0xa1, 0xcd, 0x75, 0xfd, + 0x34, 0x5e, 0xc5, 0x09, 0xa8, 0x6e, 0xc0, 0x5b, 0xe4, 0x46, 0x8b, 0xae, 0x0c, 0xba, 0x28, 0xbd, 0xa7, 0x1c, 0x4b, + 0x0a, 0x1d, 0x7d, 0xef, 0x09, 0x75, 0xee, 0x19, 0xc0, 0x25, 0x8d, 0x9a, 0xa7, 0x5a, 0xca, 0x58, 0x00, 0x2c, 0x74, + 0x30, 0x53, 0x64, 0x2b, 0xba, 0x32, 0x98, 0x14, 0xf0, 0xd6, 0x00, 0x7f, 0x88, 0xac, 0x52, 0x77, 0xc5, 0x32, 0x2c, + 0x3d, 0xfb, 0xeb, 0x7e, 0x3f, 0xf6, 0xec, 0xaf, 0x57, 0x9a, 0xd6, 0xc5, 0xed, 0x06, 0x90, 0x1a, 0x03, 0x88, 0x1c, + 0xeb, 0x81, 0x30, 0x11, 0xc5, 0x9a, 0xbe, 0x7f, 0xc7, 0x26, 0x8b, 0x02, 0xa1, 0xdf, 0xa9, 0xd7, 0x93, 0x92, 0x80, + 0x4e, 0xad, 0x62, 0x47, 0x03, 0x6d, 0xf6, 0x01, 0x01, 0x51, 0xfd, 0x8c, 0x6c, 0xbe, 0x50, 0xce, 0xc5, 0x2a, 0x7c, + 0xf8, 0x98, 0x42, 0x40, 0xe1, 0x8e, 0x1a, 0x9d, 0xb7, 0x21, 0x12, 0x28, 0x2b, 0x14, 0xb1, 0xe6, 0xc5, 0x5a, 0x12, + 0x32, 0x1f, 0x2f, 0x50, 0x70, 0xe5, 0x80, 0x5d, 0x39, 0x9b, 0x0c, 0xcb, 0x88, 0xb3, 0xf0, 0xee, 0x6f, 0x26, 0x0b, + 0x82, 0x9a, 0x2b, 0x3f, 0x90, 0xe3, 0x4e, 0xa6, 0xc6, 0x9e, 0x6a, 0xd4, 0x20, 0x98, 0x8c, 0x20, 0x30, 0xdc, 0xf0, + 0x0b, 0x3e, 0x3e, 0x58, 0x10, 0x50, 0x91, 0x59, 0xb3, 0x10, 0xf3, 0xe2, 0xf0, 0x11, 0xa0, 0xc6, 0x8c, 0x0e, 0x9e, + 0x4c, 0x39, 0x83, 0x43, 0x94, 0x8e, 0x41, 0x46, 0x2b, 0xe0, 0xb7, 0x50, 0xbf, 0x5b, 0x27, 0xbe, 0x0f, 0xfd, 0x2a, + 0xe8, 0x79, 0x0c, 0x0c, 0x47, 0x34, 0xd9, 0x0f, 0xf9, 0x60, 0x32, 0x00, 0x6d, 0x89, 0xb7, 0xfb, 0x5a, 0x5a, 0x71, + 0x73, 0xba, 0x74, 0xba, 0x7f, 0xd2, 0x26, 0x48, 0x22, 0x95, 0xac, 0x54, 0xc4, 0x00, 0x42, 0x59, 0xaa, 0x6d, 0xb2, + 0x06, 0xcb, 0x0a, 0xb3, 0xa4, 0xb9, 0x41, 0x49, 0xdc, 0xdd, 0x0c, 0x1c, 0xa3, 0x66, 0x1d, 0x87, 0x65, 0xcb, 0x8d, + 0x1a, 0xe0, 0x73, 0x12, 0x56, 0xd8, 0x1b, 0xce, 0x4c, 0x7a, 0x67, 0x3a, 0x5c, 0x1d, 0x73, 0xf6, 0x8a, 0x23, 0x18, + 0x47, 0x82, 0x37, 0x1e, 0xba, 0x64, 0x1a, 0x2a, 0x32, 0x65, 0x1c, 0x4c, 0x7b, 0x80, 0x7b, 0xcf, 0xc1, 0x38, 0x8c, + 0x0d, 0x2a, 0x4b, 0xea, 0x53, 0xef, 0x2e, 0x04, 0x82, 0xb4, 0xd6, 0xcb, 0x7c, 0x86, 0xa7, 0x67, 0x84, 0xb2, 0x3f, + 0xe4, 0xf0, 0x05, 0xd8, 0x51, 0x90, 0xa3, 0x09, 0x7f, 0xf2, 0x70, 0x37, 0x50, 0x15, 0x1f, 0x04, 0x7b, 0xb1, 0x48, + 0xf7, 0x82, 0x81, 0x80, 0x5f, 0x05, 0xdf, 0xab, 0xa4, 0xdc, 0x3b, 0x8f, 0x8b, 0xbd, 0x78, 0x15, 0x17, 0xd5, 0xde, + 0x75, 0x56, 0x2d, 0xf7, 0x4c, 0x87, 0x00, 0x9a, 0x37, 0x18, 0xc4, 0x83, 0x60, 0x2f, 0x18, 0x14, 0x66, 0x6a, 0x57, + 0xac, 0x6c, 0x1c, 0x67, 0x26, 0x44, 0x59, 0xd0, 0x0c, 0x10, 0xd6, 0x38, 0x0d, 0x80, 0x4f, 0x5d, 0xb3, 0x94, 0x9e, + 0x63, 0xb8, 0x01, 0x31, 0x5d, 0x43, 0x1f, 0x80, 0x47, 0x5e, 0xd3, 0x18, 0x96, 0xc0, 0xf9, 0x60, 0x40, 0xce, 0x21, + 0x72, 0xc1, 0x9a, 0xda, 0x20, 0x0e, 0xe1, 0x5a, 0xd9, 0x69, 0xef, 0x02, 0x33, 0x6d, 0xb7, 0x80, 0xa8, 0x3c, 0x21, + 0xfd, 0xbe, 0xfd, 0x86, 0xfa, 0x17, 0xec, 0x25, 0xd8, 0x5f, 0x15, 0x55, 0x98, 0x4b, 0xa5, 0xf9, 0xbe, 0x60, 0x47, + 0x03, 0x15, 0x71, 0x78, 0xc7, 0x91, 0xa2, 0x8d, 0xca, 0x65, 0xd9, 0x93, 0x65, 0xc3, 0x57, 0xe2, 0x92, 0x3b, 0x3f, + 0xae, 0x4a, 0xca, 0xbc, 0xca, 0x56, 0x8a, 0xfd, 0x9b, 0x71, 0xcd, 0xfd, 0x81, 0xf5, 0x67, 0xf3, 0x15, 0x5c, 0x5b, + 0xbd, 0x77, 0x4d, 0xae, 0x11, 0x39, 0x4b, 0x28, 0x97, 0xd4, 0x36, 0x0f, 0x6f, 0xe9, 0xfb, 0xfc, 0xea, 0xdb, 0x4c, + 0xa7, 0xf1, 0x59, 0x85, 0x85, 0x0b, 0xd1, 0x8a, 0xe0, 0xd0, 0x90, 0x8b, 0xe6, 0x11, 0x60, 0xae, 0x7d, 0xb6, 0x82, + 0x82, 0xd4, 0xa7, 0x15, 0x7a, 0xb7, 0x42, 0xc2, 0x0b, 0xcd, 0x2e, 0xdd, 0x0f, 0xa4, 0x8c, 0xdb, 0x43, 0x4b, 0x98, + 0xb4, 0xbc, 0x08, 0xef, 0xbd, 0xe6, 0x26, 0xf7, 0x32, 0xc4, 0xe8, 0x45, 0x9e, 0x9d, 0x80, 0xb1, 0xee, 0x92, 0x9d, + 0x0d, 0x4f, 0xfc, 0x86, 0xe7, 0xac, 0x45, 0xa3, 0xe9, 0x92, 0x25, 0xfd, 0x7e, 0x0c, 0x26, 0xde, 0x29, 0xcb, 0xe1, + 0x57, 0xbe, 0xa0, 0x6b, 0x06, 0x98, 0x62, 0xf4, 0x1c, 0x12, 0x52, 0x44, 0x22, 0x59, 0xab, 0x93, 0xe4, 0x33, 0xdd, + 0x05, 0x60, 0xf4, 0xf3, 0x59, 0x1a, 0x2d, 0xef, 0x34, 0xb3, 0x40, 0xf2, 0x0c, 0x7d, 0xd7, 0xc1, 0xf6, 0xc6, 0x3e, + 0x48, 0x39, 0x3f, 0x14, 0xd3, 0xc1, 0x80, 0x13, 0x0d, 0x37, 0x5e, 0x2a, 0x71, 0xad, 0x6e, 0x71, 0xc7, 0x30, 0x96, + 0xfa, 0xb6, 0x88, 0xc1, 0x01, 0xbb, 0x68, 0x65, 0xb7, 0x0f, 0xb0, 0xaf, 0x1c, 0xef, 0x52, 0x65, 0x77, 0x7a, 0xcc, + 0x34, 0x97, 0xad, 0x26, 0x9d, 0x54, 0xdc, 0x4d, 0xe4, 0x9b, 0xdc, 0x41, 0x97, 0xcb, 0xb1, 0xe6, 0x2d, 0x07, 0xa0, + 0xa2, 0x1f, 0x29, 0xaa, 0xfb, 0x05, 0x8e, 0x30, 0xf7, 0xd6, 0x6d, 0x3e, 0xd9, 0x37, 0x05, 0x0e, 0x91, 0x27, 0x6d, + 0x34, 0x05, 0x74, 0xef, 0xe2, 0x61, 0x57, 0xbf, 0x2d, 0xdd, 0x05, 0x4a, 0xb4, 0x53, 0x71, 0xc3, 0x8f, 0x89, 0x3a, + 0x9d, 0x69, 0x43, 0xe8, 0x5f, 0x19, 0x71, 0x7f, 0x69, 0x5c, 0xc5, 0x9b, 0xde, 0xe5, 0x33, 0x0e, 0x75, 0x76, 0x43, + 0x28, 0x00, 0x57, 0xed, 0xe9, 0xd4, 0x8d, 0x21, 0xbd, 0x52, 0xa2, 0xdb, 0xe0, 0x60, 0x77, 0xfa, 0x8c, 0xa3, 0xe8, + 0xc7, 0xa8, 0x91, 0xaf, 0x23, 0xf1, 0x50, 0x0e, 0xe2, 0x87, 0x05, 0x5d, 0x46, 0xe2, 0x61, 0x31, 0x88, 0x1f, 0xca, + 0xba, 0xde, 0x3d, 0x57, 0xee, 0xee, 0x23, 0xf2, 0xac, 0x3b, 0x7b, 0xa9, 0x84, 0x8d, 0x81, 0x67, 0xd7, 0x02, 0xc2, + 0x29, 0x78, 0x22, 0x5b, 0x4b, 0x1f, 0x3a, 0xb7, 0xfb, 0xd8, 0x32, 0x49, 0x10, 0xf4, 0xbc, 0xcd, 0x26, 0x51, 0xec, + 0x6c, 0xf3, 0xe8, 0xc3, 0x29, 0x90, 0xd0, 0xed, 0xb6, 0x59, 0x57, 0x6b, 0x40, 0x31, 0x0d, 0xc7, 0x7c, 0xbf, 0x18, + 0x5d, 0xfb, 0xee, 0xfa, 0xfb, 0xc5, 0x68, 0x49, 0x86, 0x13, 0x33, 0xf9, 0xf1, 0xd1, 0x78, 0x16, 0x47, 0x93, 0xba, + 0xe3, 0xb4, 0xd0, 0xf8, 0xa7, 0xde, 0x2d, 0x14, 0x81, 0x53, 0x31, 0x82, 0x23, 0xa7, 0x42, 0x39, 0x29, 0x35, 0x30, + 0xfc, 0xf7, 0xaa, 0x1d, 0x6d, 0xda, 0xab, 0xb8, 0x4a, 0x96, 0x99, 0xb8, 0xd0, 0xe1, 0xc3, 0x75, 0x74, 0x71, 0x1b, + 0xd0, 0xce, 0xbb, 0x4c, 0x3b, 0x7e, 0x9d, 0x34, 0xe8, 0x89, 0xab, 0x99, 0x01, 0xb7, 0xee, 0x47, 0x68, 0x86, 0xc0, + 0x68, 0x79, 0xfe, 0x16, 0x31, 0xb7, 0x7f, 0x51, 0x36, 0xbf, 0x8a, 0xf6, 0x39, 0x32, 0x52, 0xb6, 0xc9, 0x48, 0x05, + 0x46, 0x98, 0x52, 0x24, 0x71, 0x15, 0x42, 0x20, 0xfb, 0x2f, 0x29, 0xae, 0xc5, 0xd2, 0x7b, 0x0d, 0xc2, 0x04, 0xdb, + 0x05, 0xed, 0x57, 0xb7, 0x73, 0x5b, 0x69, 0xb1, 0x47, 0xea, 0xfb, 0xdc, 0xd9, 0xae, 0x68, 0xf2, 0xf7, 0x65, 0x03, + 0xda, 0x00, 0xa2, 0xbc, 0xab, 0x8f, 0x4a, 0xe0, 0x64, 0xc4, 0x0d, 0x25, 0x46, 0x2f, 0xe8, 0xea, 0x44, 0xee, 0xd9, + 0xa9, 0x79, 0x53, 0x31, 0x53, 0x71, 0xe5, 0x9b, 0x3d, 0xf3, 0x1f, 0x0c, 0x05, 0x2d, 0xc1, 0xc0, 0xdb, 0x9c, 0xf1, + 0xe8, 0x40, 0x77, 0x6d, 0x74, 0x5a, 0xb0, 0x59, 0x50, 0x97, 0x75, 0xdd, 0xc6, 0x83, 0x46, 0x1c, 0x14, 0xc5, 0xaa, + 0x50, 0x23, 0xe1, 0x89, 0x40, 0xc0, 0x94, 0x5d, 0xf2, 0xc8, 0x08, 0x6a, 0x7a, 0x13, 0x0a, 0x1b, 0x0a, 0xfe, 0x2a, + 0x51, 0x4d, 0x6f, 0x42, 0x9b, 0x4c, 0x9c, 0x66, 0x10, 0xc1, 0x8c, 0xd8, 0xee, 0xb7, 0x80, 0x36, 0xb7, 0x66, 0xb4, + 0xa9, 0x6b, 0xab, 0xad, 0x42, 0x2e, 0x29, 0x52, 0x96, 0xff, 0x4e, 0x4d, 0x05, 0x25, 0xb5, 0x5c, 0xf4, 0x26, 0x4d, + 0x17, 0x3d, 0x9e, 0x19, 0x49, 0xa0, 0x72, 0xcb, 0x1d, 0xa3, 0x3f, 0x84, 0x05, 0x1e, 0x31, 0x71, 0x62, 0xc1, 0xdc, + 0xea, 0x88, 0x65, 0x73, 0xb1, 0x18, 0xad, 0x24, 0x84, 0x0d, 0x3e, 0x64, 0xd9, 0xbc, 0xd4, 0x0f, 0xa1, 0x2f, 0x2c, + 0x7d, 0x03, 0x76, 0xb1, 0xc1, 0x4a, 0x96, 0x01, 0xf8, 0x5e, 0xd0, 0xcd, 0x4a, 0x96, 0x91, 0x54, 0xdd, 0x8f, 0x6b, + 0x2c, 0x41, 0xa5, 0x15, 0x2a, 0x2d, 0xa9, 0xb1, 0x20, 0xf0, 0x55, 0xd5, 0xe5, 0x43, 0xb2, 0xab, 0x40, 0x3d, 0x75, + 0xd4, 0x80, 0x53, 0xa0, 0xaa, 0xc0, 0x82, 0x24, 0xa8, 0x0c, 0x5d, 0x15, 0x98, 0x56, 0x60, 0x9a, 0xa9, 0xc2, 0x45, + 0x99, 0x1d, 0x4a, 0xb3, 0x5e, 0xf2, 0x59, 0x3c, 0x08, 0x93, 0x61, 0x4c, 0x1e, 0x22, 0xd4, 0xfe, 0x7e, 0x1e, 0xc5, + 0x5a, 0x2e, 0x79, 0xe1, 0xfc, 0xe2, 0xaf, 0x3f, 0x63, 0xaf, 0x7b, 0x8a, 0xc1, 0x02, 0x9c, 0xa5, 0xed, 0x65, 0x26, + 0xde, 0xca, 0x56, 0x70, 0x1c, 0xcc, 0xa2, 0x1c, 0x56, 0x3d, 0x39, 0xa2, 0xb9, 0xc8, 0xb5, 0x77, 0x11, 0x22, 0x07, + 0x99, 0x3d, 0x06, 0xd8, 0x8d, 0xf0, 0x75, 0x68, 0x6d, 0x6e, 0x75, 0x85, 0xf8, 0x1b, 0x25, 0x12, 0x3f, 0x49, 0xf9, + 0x71, 0xbd, 0x52, 0xb9, 0x2a, 0x83, 0xc7, 0xaa, 0x9b, 0xc1, 0x33, 0xed, 0x7b, 0xac, 0xfd, 0x5b, 0xdb, 0xcd, 0xf1, + 0xde, 0x83, 0x07, 0xad, 0xff, 0xad, 0x27, 0x21, 0xb4, 0x57, 0x4e, 0x52, 0x77, 0xd4, 0xe8, 0x99, 0xc9, 0x1a, 0x51, + 0x09, 0x53, 0xbb, 0x53, 0x39, 0x06, 0x6a, 0x3a, 0x80, 0x6b, 0x89, 0x9a, 0xa0, 0x27, 0x05, 0x1b, 0xc3, 0x11, 0x67, + 0x71, 0xd0, 0x0e, 0x63, 0x14, 0x2f, 0xe7, 0x4a, 0xbc, 0x9c, 0x1f, 0x31, 0x0e, 0xd0, 0x5a, 0x80, 0x54, 0xaf, 0x61, + 0x3f, 0x73, 0x05, 0x0b, 0x6c, 0xee, 0x7c, 0x07, 0x16, 0xc8, 0x10, 0x27, 0x9b, 0xe3, 0x64, 0x8f, 0x6b, 0x3d, 0xf7, + 0x02, 0x1f, 0x27, 0xf5, 0xc2, 0xab, 0xab, 0x6c, 0xd7, 0xb5, 0x64, 0xe5, 0xbc, 0x18, 0x4c, 0x20, 0x28, 0x4b, 0x39, + 0x2f, 0x86, 0x93, 0x05, 0xcd, 0xe1, 0xc7, 0xa2, 0x81, 0x0e, 0xb1, 0x1c, 0x24, 0x70, 0xe9, 0xec, 0x31, 0xe0, 0x0d, + 0xa5, 0x16, 0x77, 0x63, 0x1d, 0x39, 0xd6, 0x51, 0xec, 0x87, 0x31, 0xe0, 0xca, 0x3a, 0x81, 0xf7, 0xdd, 0xd7, 0xc7, + 0x26, 0x20, 0xab, 0x76, 0x85, 0x57, 0xa3, 0xdc, 0x75, 0xa5, 0xd1, 0x97, 0x94, 0x9e, 0xf0, 0x82, 0xa7, 0x92, 0xed, + 0xb6, 0x67, 0xe0, 0x6c, 0x89, 0x87, 0xc4, 0x3b, 0x46, 0xf4, 0x62, 0xda, 0xc8, 0xcc, 0x09, 0x9c, 0xd9, 0xee, 0xb2, + 0x8d, 0xf9, 0xb1, 0x03, 0x1c, 0x2c, 0x82, 0x90, 0xb8, 0x21, 0x0c, 0x13, 0x3b, 0x2a, 0x87, 0x5a, 0x08, 0xd7, 0xb5, + 0xf0, 0x3a, 0x4e, 0xcb, 0x18, 0x5c, 0xa4, 0xb5, 0x6d, 0xe2, 0x1d, 0x74, 0xdd, 0xf3, 0x63, 0x6e, 0x75, 0x8c, 0xb6, + 0x90, 0x7e, 0x3b, 0x3a, 0xbd, 0xe7, 0x30, 0x00, 0x4d, 0x0f, 0x66, 0x55, 0xfb, 0x4c, 0xe2, 0xe6, 0xb4, 0x13, 0x84, + 0x44, 0x20, 0x8a, 0xd2, 0x19, 0x61, 0xfa, 0x77, 0x9a, 0xcb, 0x2a, 0x5a, 0xdd, 0xcb, 0x33, 0x87, 0x3c, 0x0b, 0xbd, + 0xed, 0x41, 0xab, 0xe6, 0x6e, 0x30, 0x4e, 0xdc, 0x6e, 0xef, 0xfc, 0xbf, 0x65, 0x5d, 0x5b, 0xad, 0x11, 0x0f, 0xdb, + 0xd5, 0x0f, 0x1a, 0x7b, 0xb5, 0xa7, 0x62, 0xc0, 0x5c, 0x48, 0xef, 0x8c, 0x2a, 0x79, 0x91, 0xf1, 0x12, 0x4f, 0xaa, + 0x8b, 0x86, 0x8f, 0xf7, 0x75, 0x36, 0x32, 0x0f, 0x64, 0x0a, 0x88, 0xe7, 0x1f, 0x53, 0xa3, 0x3e, 0x4e, 0x51, 0x02, + 0xfe, 0x56, 0xc7, 0x37, 0xa2, 0x27, 0xf6, 0xc5, 0x05, 0xaf, 0xde, 0x5c, 0x0b, 0xf3, 0xe2, 0x99, 0xd5, 0xf9, 0xd3, + 0xa7, 0x85, 0x0f, 0x1d, 0x8e, 0xda, 0x3b, 0x28, 0xb2, 0x64, 0xe2, 0x68, 0x62, 0x64, 0x6d, 0x62, 0x76, 0xa2, 0xe0, + 0x62, 0xa2, 0x0a, 0x3d, 0xeb, 0xec, 0x09, 0x53, 0x80, 0xbe, 0x71, 0x8c, 0x4a, 0xc6, 0xb0, 0x60, 0xa0, 0x4e, 0x53, + 0x42, 0xf4, 0x50, 0xcc, 0x30, 0x5e, 0x31, 0x80, 0xc2, 0x14, 0x0a, 0x44, 0xd1, 0xd9, 0x87, 0x03, 0x4d, 0xe8, 0xf7, + 0x3f, 0xa6, 0x3a, 0x03, 0x2d, 0xeb, 0x69, 0x01, 0xa2, 0x3a, 0x88, 0xb6, 0x0a, 0x84, 0x39, 0xa5, 0x65, 0x46, 0x97, + 0x82, 0xa6, 0x82, 0x26, 0x19, 0x3d, 0xe7, 0x4a, 0x54, 0x7c, 0x2e, 0x98, 0xa2, 0xed, 0x86, 0xb0, 0xff, 0xd8, 0xa0, + 0xeb, 0xad, 0x58, 0x6b, 0x68, 0x77, 0x82, 0x8c, 0xd0, 0x7c, 0xa1, 0x83, 0x90, 0xa1, 0x72, 0x12, 0xf1, 0xe1, 0x35, + 0x5e, 0x81, 0x4b, 0xa6, 0xd9, 0x68, 0x19, 0x97, 0x61, 0x60, 0xbf, 0x0a, 0x2c, 0x26, 0x07, 0x26, 0x9d, 0xac, 0xcf, + 0x9e, 0xca, 0xcb, 0x95, 0x14, 0x5c, 0x54, 0x0a, 0xa2, 0xdf, 0xe0, 0xbe, 0x9b, 0xb8, 0xea, 0xac, 0x59, 0x2b, 0xbd, + 0xef, 0x5b, 0x9f, 0xb5, 0x71, 0x5f, 0x18, 0x1c, 0x83, 0x9d, 0x8f, 0x88, 0x81, 0x34, 0xa8, 0x74, 0x8b, 0x43, 0x13, + 0xa0, 0x4b, 0x87, 0x14, 0xb2, 0x64, 0x2a, 0x53, 0x25, 0xa8, 0xf8, 0xc6, 0xef, 0xa4, 0xac, 0x46, 0x7f, 0xaf, 0x79, + 0x71, 0x7b, 0xc2, 0x73, 0x8e, 0x63, 0x14, 0x24, 0xb1, 0xb8, 0x8a, 0xcb, 0x80, 0xf8, 0x96, 0x57, 0xc1, 0x41, 0x6a, + 0xc2, 0xc6, 0xec, 0x54, 0x8d, 0x5a, 0xaf, 0x02, 0x7d, 0x65, 0x94, 0x6f, 0x0c, 0x86, 0x26, 0xa2, 0x0a, 0xfa, 0x5e, + 0xab, 0x7b, 0x5a, 0xdd, 0xb0, 0x80, 0xf8, 0x73, 0xa5, 0x17, 0x6a, 0xbd, 0x6e, 0xc6, 0xdc, 0x30, 0x11, 0x82, 0x46, + 0x8f, 0xea, 0x85, 0xc3, 0xcf, 0xdf, 0x28, 0x4b, 0x22, 0x78, 0xb1, 0x49, 0xd7, 0x85, 0x89, 0xa5, 0x41, 0x75, 0xc0, + 0xdc, 0x68, 0x93, 0xf3, 0x0b, 0x10, 0xfd, 0x39, 0x2b, 0xa2, 0x49, 0x5d, 0x53, 0x85, 0x60, 0x18, 0x6d, 0x6e, 0x1a, + 0xe9, 0xf4, 0x16, 0xbc, 0xdc, 0x8c, 0x35, 0x92, 0xf6, 0x74, 0xac, 0x69, 0xc1, 0xcb, 0x95, 0x14, 0x25, 0x44, 0x77, + 0xee, 0x8d, 0xe9, 0x65, 0x9c, 0x89, 0x2a, 0xce, 0xc4, 0x71, 0xb9, 0xe2, 0x49, 0xf5, 0x0e, 0x2a, 0xd4, 0xc6, 0x38, + 0xd8, 0x7a, 0x35, 0xea, 0x2a, 0x1c, 0xf2, 0xcb, 0xf3, 0xe7, 0x37, 0xab, 0x58, 0xa4, 0x30, 0xea, 0xf5, 0x5d, 0x2f, + 0x9a, 0xd3, 0xb1, 0x8a, 0x0b, 0x2e, 0x4c, 0xd4, 0x62, 0x5a, 0xb1, 0x80, 0xeb, 0x8c, 0x01, 0xe5, 0x2a, 0x76, 0x67, + 0xa6, 0x62, 0x19, 0xc6, 0x65, 0xf9, 0x53, 0x56, 0xe2, 0x1d, 0x00, 0x5a, 0x03, 0xa7, 0xc5, 0xcc, 0x80, 0x80, 0xdc, + 0xe6, 0x06, 0x17, 0x81, 0x05, 0x07, 0x8f, 0xc7, 0xab, 0x9b, 0x80, 0x7a, 0x6f, 0xa4, 0xba, 0x1e, 0xb2, 0x60, 0x3c, + 0x7a, 0x12, 0x38, 0xe4, 0x10, 0xff, 0xa3, 0xc7, 0x07, 0x77, 0x7f, 0x33, 0x09, 0x48, 0x3d, 0x05, 0x55, 0x85, 0x51, + 0x88, 0xc2, 0xb4, 0xbf, 0x5a, 0xab, 0x5b, 0xee, 0x9b, 0xb3, 0x92, 0x17, 0x57, 0x10, 0xad, 0x9d, 0x4c, 0x33, 0x20, + 0xe7, 0x52, 0x25, 0xc0, 0xa2, 0x88, 0xab, 0xaa, 0xc8, 0xce, 0xc0, 0x44, 0x09, 0x0d, 0xc0, 0xcc, 0xd3, 0x0b, 0x74, + 0xf8, 0x88, 0xe6, 0x01, 0xf6, 0x29, 0x58, 0xd4, 0xa4, 0x2e, 0xa1, 0xb0, 0x64, 0x0f, 0x83, 0xd5, 0xa9, 0xb8, 0xd2, + 0x0e, 0xe0, 0xbb, 0xfa, 0x33, 0x5a, 0x4a, 0x8c, 0x35, 0xab, 0xe7, 0x29, 0x3e, 0x2b, 0x65, 0xbe, 0xae, 0x40, 0x7b, + 0x7e, 0x5e, 0x45, 0x07, 0x8f, 0x57, 0x37, 0x53, 0xd5, 0x8d, 0x08, 0x7a, 0x31, 0x55, 0x38, 0x6f, 0x49, 0x9c, 0x27, + 0xe1, 0x64, 0x3c, 0xfe, 0x6a, 0x6f, 0xb8, 0x07, 0xc9, 0x64, 0xfa, 0x69, 0xa8, 0x1c, 0xb9, 0x86, 0x93, 0xf1, 0xb8, + 0xfe, 0xb3, 0x36, 0x61, 0xbe, 0x4d, 0x3d, 0x4f, 0xff, 0x3c, 0x54, 0xeb, 0xff, 0xe8, 0x70, 0x5f, 0xff, 0xf8, 0xb3, + 0xae, 0xa7, 0x4f, 0x8b, 0x70, 0xfe, 0x7b, 0xa8, 0xd6, 0xf7, 0x71, 0x51, 0xc4, 0xb7, 0x35, 0x44, 0x36, 0x15, 0xce, + 0xbb, 0x86, 0x7a, 0x64, 0x81, 0x1e, 0x90, 0xe9, 0xb9, 0x60, 0xf0, 0xcd, 0xbb, 0x2a, 0x0c, 0x78, 0xb9, 0x1a, 0x72, + 0x51, 0x65, 0xd5, 0xed, 0x10, 0xf3, 0x04, 0xf8, 0xa9, 0xc5, 0x33, 0x2b, 0x0c, 0xf1, 0x3d, 0x2f, 0x38, 0xff, 0xc4, + 0x43, 0x65, 0x2c, 0x3e, 0x46, 0x63, 0xf1, 0x31, 0x55, 0xdd, 0x98, 0x7c, 0x43, 0x75, 0xdf, 0x26, 0xdf, 0x80, 0x49, + 0x56, 0xd6, 0xfe, 0x46, 0x19, 0x6b, 0x46, 0x63, 0x7a, 0xf5, 0x22, 0xcf, 0x56, 0x70, 0x29, 0x58, 0xea, 0x1f, 0x35, + 0xa1, 0xef, 0x78, 0x3b, 0xfb, 0x68, 0x34, 0x7a, 0x53, 0xd0, 0xd1, 0x68, 0xf4, 0x31, 0xab, 0x09, 0x5d, 0x89, 0x8e, + 0xf7, 0xef, 0x38, 0x3d, 0x93, 0xe9, 0x6d, 0x14, 0x04, 0x74, 0x99, 0xa5, 0x29, 0x17, 0xaa, 0xac, 0x57, 0x69, 0x3b, + 0xaf, 0x6a, 0x21, 0x02, 0x21, 0xe9, 0x36, 0x22, 0x24, 0x13, 0xa1, 0x6f, 0x77, 0x7a, 0x36, 0x1a, 0x8d, 0x5e, 0xa5, + 0xa6, 0x5a, 0x77, 0x41, 0x79, 0x8a, 0xe6, 0x14, 0xce, 0x4f, 0x01, 0xac, 0x91, 0x4c, 0xf4, 0x97, 0xfd, 0xff, 0x1e, + 0xce, 0xe6, 0xe3, 0xe1, 0xb7, 0xa3, 0xc5, 0xc3, 0x7d, 0x1a, 0x04, 0x7e, 0xe8, 0x86, 0x50, 0x5b, 0xb7, 0x4c, 0xcb, + 0xc3, 0xf1, 0x94, 0x94, 0x03, 0xf6, 0xd8, 0xfa, 0x16, 0x7d, 0xf5, 0x18, 0x90, 0x59, 0x51, 0xa4, 0x1c, 0x38, 0x69, + 0x28, 0x5e, 0xcd, 0x5e, 0x0a, 0xc0, 0x8b, 0xb3, 0x91, 0x1d, 0x8c, 0x56, 0x74, 0x1c, 0x41, 0x79, 0xb5, 0x35, 0x15, + 0xe9, 0x31, 0x96, 0x99, 0x28, 0xa9, 0xe3, 0x69, 0x79, 0x9d, 0x55, 0xc9, 0x12, 0x03, 0x3d, 0xc5, 0x25, 0x0f, 0xbe, + 0x0a, 0xa2, 0x92, 0x1d, 0x3c, 0x99, 0x2a, 0xb8, 0x63, 0x4c, 0x4a, 0xf9, 0x05, 0x24, 0x7e, 0x3b, 0x46, 0x48, 0x58, + 0xa2, 0x3d, 0x38, 0xb1, 0xc6, 0x17, 0xb9, 0x8c, 0xc1, 0xa3, 0xb5, 0xd4, 0x3c, 0x9c, 0x3d, 0x19, 0xad, 0x3d, 0x4a, + 0xab, 0x39, 0x12, 0x9a, 0x13, 0x4a, 0x26, 0xf7, 0x4b, 0x2a, 0xbf, 0x9a, 0xa0, 0x97, 0x14, 0xb8, 0x99, 0x47, 0x70, + 0xfc, 0x5b, 0x4b, 0x0f, 0xbd, 0x7c, 0x52, 0xb6, 0x3f, 0xff, 0xdf, 0x25, 0x5d, 0x0c, 0xf6, 0xdd, 0xd0, 0xbc, 0xd5, + 0xee, 0xbc, 0x15, 0x32, 0x8e, 0x55, 0xf8, 0x26, 0x25, 0xd6, 0x18, 0x97, 0xb3, 0xa3, 0x8d, 0xe9, 0xce, 0xa8, 0x2a, + 0xb2, 0xcb, 0x90, 0xe8, 0x5e, 0x39, 0x90, 0xd0, 0x20, 0xca, 0x46, 0xb8, 0x7e, 0xc0, 0x7a, 0xc6, 0xeb, 0xe4, 0x15, + 0x2f, 0xaa, 0x2c, 0x51, 0xef, 0xaf, 0x1a, 0xef, 0xeb, 0xda, 0x04, 0x54, 0x7d, 0x50, 0x30, 0x98, 0xe7, 0xb7, 0x05, + 0x80, 0x98, 0x22, 0x0d, 0xf0, 0x09, 0x66, 0x10, 0xd4, 0xae, 0x99, 0x97, 0x8d, 0xe0, 0x1b, 0xf0, 0xd5, 0x83, 0x02, + 0x30, 0x48, 0x42, 0x90, 0x22, 0x43, 0x68, 0x20, 0x10, 0x68, 0x18, 0x72, 0x81, 0xc1, 0x4f, 0xbc, 0x38, 0x92, 0xca, + 0x29, 0x91, 0x87, 0x01, 0xfe, 0x08, 0xa8, 0x0a, 0x40, 0x62, 0x3c, 0x0e, 0xe1, 0x85, 0xfa, 0xe5, 0xde, 0xa8, 0x3d, + 0xc2, 0x9e, 0xa6, 0x21, 0x04, 0x1b, 0xc2, 0x87, 0x00, 0x96, 0x14, 0xa1, 0x6f, 0x91, 0xcb, 0x08, 0x83, 0xf3, 0x3c, + 0x5b, 0xe9, 0xa4, 0x6a, 0xd4, 0xd1, 0x7c, 0x28, 0xb5, 0x23, 0x39, 0xa0, 0x5e, 0x7a, 0x8c, 0xe9, 0x85, 0x4a, 0x57, + 0x45, 0x39, 0xa3, 0x9c, 0x07, 0x7a, 0x62, 0x5c, 0xd8, 0x42, 0x0e, 0x91, 0x70, 0x1e, 0x14, 0x2a, 0x14, 0x0e, 0x5f, + 0x00, 0x18, 0x18, 0x48, 0x3b, 0x76, 0xe3, 0xdd, 0xa8, 0xec, 0xa7, 0x9c, 0xed, 0xff, 0xf7, 0x3c, 0x1e, 0x7e, 0x1a, + 0x0f, 0xbf, 0x5d, 0x0c, 0xc2, 0xa1, 0xfd, 0x49, 0x1e, 0x3e, 0xd8, 0xa7, 0x2f, 0xb8, 0xe5, 0xd2, 0x60, 0xe1, 0x37, + 0x82, 0xfd, 0xa8, 0x95, 0x10, 0x44, 0x01, 0xde, 0xb0, 0xdc, 0x6a, 0x9c, 0x00, 0xe0, 0x61, 0xf0, 0x5f, 0x01, 0x1a, + 0x4d, 0xb9, 0x8b, 0x17, 0xe8, 0x4b, 0xd4, 0xef, 0xa3, 0x47, 0x0d, 0x83, 0x41, 0x10, 0xd7, 0xa8, 0x98, 0x30, 0x44, + 0x97, 0x31, 0x51, 0x30, 0xc8, 0x36, 0xfb, 0x76, 0xdb, 0x6b, 0x4b, 0xc2, 0xf0, 0x4b, 0x3f, 0xd3, 0xc4, 0xcc, 0x3b, + 0xdc, 0xd8, 0x56, 0x72, 0x15, 0x22, 0x56, 0xa0, 0xfe, 0x95, 0x33, 0x88, 0xbd, 0x79, 0x95, 0x81, 0x4f, 0x87, 0xfd, + 0x62, 0x3c, 0x03, 0x36, 0x0a, 0xee, 0x7c, 0x05, 0x3f, 0xcf, 0xc0, 0xcd, 0x5b, 0xc4, 0x28, 0x70, 0xb0, 0x4b, 0xa2, + 0xdf, 0xef, 0xe5, 0x59, 0x98, 0x6b, 0xdc, 0xe9, 0xbc, 0x36, 0x6a, 0x08, 0xd4, 0x91, 0x83, 0xfa, 0x41, 0x0f, 0xc1, + 0x50, 0x0d, 0x41, 0xd1, 0xd1, 0x16, 0x57, 0xaf, 0xad, 0xa7, 0x30, 0xbd, 0x55, 0xf5, 0x15, 0xa3, 0xbf, 0x64, 0x26, + 0xb0, 0x90, 0x76, 0xcd, 0xb1, 0xae, 0x39, 0x46, 0xda, 0xd3, 0xef, 0x8b, 0x06, 0xf9, 0xe9, 0x2c, 0x3c, 0x08, 0x54, + 0xa9, 0x72, 0xa7, 0x2c, 0xca, 0x6d, 0x69, 0xde, 0x18, 0xd6, 0x34, 0xcf, 0x6c, 0x9c, 0x9b, 0x59, 0xaf, 0x17, 0x86, + 0xe8, 0xe0, 0x89, 0xa5, 0x62, 0x6d, 0x10, 0xee, 0xc8, 0x24, 0x8c, 0x2e, 0x41, 0x76, 0x19, 0x9e, 0x72, 0x82, 0x7c, + 0x2a, 0xb0, 0x0f, 0xaa, 0x5a, 0x2f, 0x27, 0x3c, 0x36, 0xf2, 0x65, 0x23, 0x68, 0x90, 0x97, 0x14, 0xf5, 0x26, 0x6e, + 0xc7, 0x1e, 0xb7, 0x90, 0x2b, 0x37, 0xf5, 0xb4, 0xa7, 0x49, 0x45, 0x8f, 0xf5, 0x2a, 0xf5, 0x0b, 0x2c, 0x2d, 0x2c, + 0xf9, 0x20, 0xb4, 0xa7, 0x69, 0x05, 0x66, 0xb8, 0xb2, 0x19, 0x0c, 0xfd, 0x70, 0xfc, 0x04, 0x74, 0x46, 0x6d, 0x4b, + 0x08, 0x63, 0x37, 0x08, 0x2b, 0xef, 0x89, 0x7c, 0xf5, 0xd8, 0xbb, 0x18, 0x84, 0xdc, 0x6c, 0x66, 0xd1, 0xc0, 0x74, + 0x3f, 0x93, 0xcd, 0xe6, 0xe9, 0xe6, 0x7a, 0x51, 0x42, 0x05, 0x6c, 0xb7, 0x95, 0x20, 0xf8, 0xf7, 0x63, 0x36, 0xc3, + 0xbf, 0x59, 0xbf, 0xdf, 0x0b, 0xf1, 0x17, 0xc7, 0x60, 0x46, 0x73, 0xb1, 0x60, 0x1f, 0x41, 0xc6, 0x44, 0x22, 0x4c, + 0x55, 0xc6, 0x80, 0xac, 0x02, 0x8b, 0x40, 0xf3, 0x81, 0xca, 0x85, 0x99, 0xec, 0x65, 0xce, 0x35, 0xe4, 0x79, 0x6b, + 0x9c, 0xb2, 0x51, 0x96, 0x28, 0x57, 0x8e, 0x6c, 0x14, 0xe7, 0x59, 0x5c, 0xf2, 0x72, 0xbb, 0xd5, 0x87, 0x63, 0x52, + 0x70, 0x60, 0xd7, 0x15, 0x95, 0x2a, 0x59, 0x47, 0xaa, 0x07, 0x5e, 0x1a, 0x16, 0xb8, 0x4f, 0xf9, 0xbc, 0x30, 0x34, + 0x62, 0x0f, 0x84, 0x19, 0x4c, 0xdd, 0xd2, 0x7b, 0x61, 0x01, 0xcd, 0x2b, 0x09, 0xd9, 0x60, 0xaa, 0x67, 0xe1, 0x1b, + 0x33, 0x31, 0x2f, 0x16, 0x10, 0x56, 0xa7, 0x58, 0x68, 0x66, 0x93, 0x26, 0x2c, 0x06, 0xd8, 0xbc, 0x98, 0x4c, 0x21, + 0xbe, 0xbb, 0x2a, 0x27, 0x5e, 0x98, 0xfb, 0x76, 0xe2, 0x90, 0x43, 0xe0, 0x55, 0x6d, 0xd0, 0xd5, 0x6c, 0xc3, 0x51, + 0x47, 0xca, 0x89, 0xc9, 0xef, 0xa7, 0x0a, 0x42, 0xdc, 0x89, 0x23, 0xe1, 0xf2, 0x66, 0xbb, 0xf0, 0xb2, 0x03, 0x41, + 0x47, 0x0d, 0x4e, 0xf9, 0x99, 0xc1, 0xd1, 0x98, 0xa4, 0x1b, 0xef, 0x04, 0x29, 0xc2, 0x98, 0x6c, 0x24, 0x3b, 0x93, + 0xa1, 0x98, 0xc7, 0x0b, 0x50, 0x5e, 0xc6, 0x0b, 0xb0, 0x34, 0x32, 0x06, 0xa9, 0x20, 0xbf, 0xe3, 0x5e, 0x28, 0x2c, + 0x8a, 0x2b, 0x44, 0x7a, 0x56, 0xbf, 0xc7, 0x45, 0x3b, 0x14, 0x08, 0x8a, 0x3b, 0x94, 0x79, 0x72, 0xd6, 0x63, 0x81, + 0xc4, 0x86, 0x80, 0xf1, 0x95, 0x4e, 0x53, 0xad, 0x75, 0x6f, 0x6c, 0xf4, 0xaa, 0x69, 0x36, 0x12, 0xb2, 0x3a, 0x3d, + 0x07, 0x91, 0x92, 0x8f, 0x8e, 0x8f, 0xfc, 0x22, 0xee, 0x2c, 0xf3, 0xd6, 0xb6, 0xa8, 0x64, 0x47, 0x1b, 0x00, 0x2d, + 0xd4, 0xd1, 0xb3, 0x94, 0xdc, 0xa6, 0x24, 0xb5, 0xdb, 0x14, 0xb0, 0x92, 0xfc, 0x05, 0x0c, 0xc1, 0xd7, 0xf6, 0x84, + 0xd3, 0xb1, 0x42, 0xbc, 0xa6, 0x29, 0x22, 0x4d, 0x86, 0x25, 0xc5, 0xb1, 0x2d, 0x11, 0x05, 0xd5, 0x96, 0x65, 0x07, + 0xc3, 0x44, 0x09, 0x7e, 0x96, 0x7a, 0x94, 0x28, 0x08, 0xa8, 0x1e, 0x72, 0x90, 0x60, 0xdb, 0x06, 0xc2, 0x03, 0xf2, + 0x88, 0xde, 0x58, 0x7f, 0x9f, 0x75, 0x9e, 0x5d, 0x68, 0x9e, 0xcb, 0xf5, 0xae, 0x30, 0x63, 0x84, 0x27, 0x99, 0x09, + 0x1b, 0xe0, 0x9d, 0x67, 0x46, 0x6d, 0xd3, 0xf3, 0xf0, 0xda, 0x9e, 0x63, 0x84, 0xbe, 0x3b, 0x06, 0xdd, 0x04, 0xf3, + 0xea, 0xb0, 0x59, 0xaf, 0x14, 0xa4, 0x86, 0xa9, 0x45, 0x13, 0xb3, 0x9e, 0x35, 0x28, 0xdf, 0x6e, 0x7b, 0x7a, 0xae, + 0xee, 0x9e, 0xbb, 0xed, 0xb6, 0x87, 0xdd, 0x7a, 0x96, 0x76, 0x5b, 0xc5, 0x57, 0xea, 0x83, 0xf6, 0xf8, 0x73, 0x37, + 0xfe, 0xdc, 0x20, 0x9b, 0x94, 0x8e, 0x66, 0xda, 0xfa, 0x20, 0x3c, 0x70, 0x7a, 0xdb, 0x68, 0xd2, 0xf7, 0x59, 0x28, + 0xe9, 0x4a, 0x34, 0xaa, 0x33, 0x21, 0xcc, 0x58, 0x75, 0xff, 0xfa, 0xbf, 0x7f, 0x15, 0xe0, 0x11, 0xa7, 0x76, 0xf6, + 0x9d, 0x0d, 0x2a, 0x1a, 0x6d, 0xe1, 0x48, 0x11, 0x7a, 0x40, 0x12, 0xee, 0x6a, 0x59, 0x8b, 0xdb, 0x3c, 0xc9, 0xee, + 0xa7, 0x4f, 0xef, 0x53, 0xdf, 0x0b, 0xc1, 0x2d, 0xb3, 0xcc, 0x1c, 0x78, 0x15, 0xc5, 0x01, 0x8d, 0xba, 0x68, 0xdf, + 0x65, 0x56, 0x96, 0xe0, 0xf5, 0x02, 0xf7, 0xca, 0x13, 0xee, 0xc3, 0xef, 0x5d, 0x54, 0xcd, 0x4d, 0x7a, 0x92, 0xcd, + 0xb3, 0xc5, 0x76, 0x1b, 0xe2, 0xdf, 0xae, 0x16, 0x39, 0x9a, 0x3c, 0x07, 0x9d, 0x26, 0x46, 0x32, 0x62, 0xba, 0x71, + 0xde, 0xe6, 0x7f, 0x2d, 0x1a, 0x4e, 0x13, 0xcf, 0x81, 0x5e, 0xcc, 0x8e, 0x41, 0x26, 0x65, 0x40, 0x0e, 0xc4, 0x4c, + 0xaf, 0x19, 0x88, 0x46, 0x26, 0x22, 0xc0, 0x15, 0xc6, 0x46, 0xa2, 0xd1, 0x09, 0x27, 0x35, 0x01, 0x0b, 0x56, 0x5b, + 0xde, 0x4f, 0x96, 0xb6, 0x55, 0xc5, 0xad, 0xb7, 0xa4, 0x39, 0xae, 0x03, 0xe7, 0xeb, 0x60, 0x86, 0xd8, 0x94, 0x5d, + 0x2d, 0x90, 0xfb, 0xe5, 0x35, 0xed, 0x8d, 0xeb, 0x04, 0x66, 0x6d, 0x53, 0x5b, 0xc6, 0xcf, 0x96, 0xfe, 0x4e, 0x0f, + 0xae, 0x32, 0x06, 0x9b, 0x1b, 0x2b, 0x0d, 0xbb, 0x6f, 0x3c, 0x5f, 0x0a, 0x08, 0x4f, 0xe7, 0xd3, 0xe3, 0x93, 0xcc, + 0xa3, 0xc7, 0x40, 0x74, 0xcc, 0x47, 0xa5, 0xfb, 0xc8, 0xee, 0x5e, 0x3f, 0x20, 0xe0, 0xbc, 0x6a, 0x17, 0x34, 0x2f, + 0x17, 0x10, 0x58, 0xd5, 0x2b, 0xaf, 0xb0, 0x7c, 0x66, 0xcc, 0x2e, 0x80, 0x0c, 0x15, 0x04, 0x02, 0x77, 0x77, 0x9d, + 0x0b, 0xb1, 0xea, 0xb0, 0x32, 0xa7, 0x49, 0xd8, 0x51, 0x88, 0xe6, 0xad, 0xc1, 0x2c, 0xf8, 0xaf, 0x60, 0x50, 0x0e, + 0x82, 0x28, 0x88, 0x82, 0x80, 0x0c, 0x0a, 0xf8, 0x85, 0xb8, 0x6b, 0x04, 0x63, 0xb6, 0x40, 0x87, 0xdf, 0x72, 0xe6, + 0x33, 0x22, 0x2f, 0xfd, 0xb0, 0x9e, 0xde, 0x00, 0x9c, 0x49, 0x99, 0xf3, 0x18, 0x7d, 0x4e, 0xde, 0x72, 0x96, 0x11, + 0xfa, 0xd6, 0x3b, 0x95, 0x1f, 0xf0, 0x46, 0xb0, 0xbf, 0xdd, 0x61, 0x7b, 0x01, 0xf2, 0x8a, 0xde, 0x98, 0xbe, 0xe5, + 0x24, 0xca, 0x1a, 0xce, 0xd4, 0x1c, 0x7a, 0x56, 0x59, 0xd6, 0x8a, 0x1a, 0x72, 0x83, 0x62, 0x6e, 0x64, 0x99, 0x9c, + 0x4c, 0x5b, 0xcd, 0xa9, 0xc0, 0x75, 0x67, 0xd7, 0x0b, 0x48, 0x0e, 0x85, 0x66, 0xe9, 0x6c, 0x38, 0x6f, 0xdb, 0xb2, + 0x67, 0xad, 0x53, 0xc8, 0x6b, 0x88, 0x8a, 0x06, 0xe9, 0x08, 0xa8, 0xa1, 0x15, 0x17, 0x15, 0xb8, 0x30, 0x9b, 0xf6, + 0x70, 0xd3, 0x1e, 0xd3, 0x8c, 0x9f, 0x20, 0x66, 0x1e, 0xc7, 0x96, 0x81, 0x1d, 0x89, 0xc3, 0xf7, 0x71, 0xbe, 0x40, + 0xbb, 0xf4, 0xd6, 0xd5, 0xe2, 0x11, 0xd6, 0x9e, 0xb7, 0x42, 0x42, 0x80, 0xf8, 0x34, 0x95, 0x6e, 0xb7, 0x41, 0x00, + 0x03, 0xdc, 0xef, 0xf7, 0x80, 0x6b, 0x35, 0xec, 0xa4, 0xb9, 0x35, 0x5b, 0x62, 0xaf, 0x28, 0x3c, 0x06, 0xe6, 0xd4, + 0xfc, 0x67, 0x10, 0x50, 0x3c, 0x77, 0x43, 0xb0, 0x37, 0x65, 0x47, 0x1b, 0x88, 0x38, 0x54, 0xe0, 0x03, 0xca, 0x85, + 0x41, 0xcc, 0xad, 0xe3, 0x78, 0x18, 0xf6, 0x49, 0x7d, 0x88, 0x63, 0x91, 0x67, 0xa1, 0x23, 0x2c, 0x95, 0x21, 0x2c, + 0x5c, 0x31, 0xd2, 0x41, 0x1c, 0xd4, 0xa4, 0x73, 0xb0, 0x2a, 0x17, 0x7c, 0xb9, 0xd7, 0x7b, 0x0d, 0x30, 0xe9, 0x99, + 0x37, 0x2c, 0x2f, 0x3c, 0x40, 0xb4, 0x5e, 0x0f, 0x17, 0x8a, 0x47, 0x26, 0x1a, 0x68, 0x9c, 0xf8, 0xd2, 0xb2, 0xeb, + 0x33, 0x2d, 0x2b, 0x19, 0x8d, 0x46, 0x55, 0xad, 0x24, 0x1f, 0xf6, 0xbb, 0x4f, 0x2d, 0x14, 0x4f, 0x19, 0xa7, 0x3c, + 0x05, 0xcb, 0x77, 0x43, 0xe9, 0xe6, 0x0b, 0xba, 0xe2, 0x22, 0x55, 0x3f, 0x3d, 0xf4, 0xcd, 0x06, 0x71, 0xcd, 0x9a, + 0x3a, 0x1c, 0x3b, 0xfc, 0x10, 0x00, 0xd3, 0x3e, 0xcc, 0x5c, 0xba, 0x86, 0xe9, 0x05, 0xf1, 0x6c, 0x5c, 0xf0, 0xd0, + 0xe5, 0x01, 0xec, 0x43, 0x73, 0x48, 0xe2, 0xa7, 0xf0, 0x73, 0x66, 0xd2, 0x3a, 0x3e, 0xc3, 0xd9, 0x8c, 0x4a, 0x75, + 0x23, 0x68, 0xbf, 0x86, 0x44, 0x62, 0x90, 0x9e, 0x1b, 0x0c, 0x45, 0xeb, 0x6e, 0x03, 0x57, 0x7e, 0x4b, 0xef, 0x7c, + 0x1a, 0x04, 0x58, 0xdf, 0x58, 0x0c, 0x00, 0xa8, 0xe2, 0x0f, 0x54, 0x5d, 0x99, 0x2b, 0x8a, 0x69, 0x98, 0x4a, 0xb4, + 0x77, 0x1c, 0xd7, 0x51, 0xe3, 0x3a, 0x2c, 0x58, 0x69, 0x6d, 0x9b, 0xdd, 0x5b, 0x88, 0x3f, 0xa2, 0x4b, 0x40, 0xb5, + 0x20, 0xee, 0x04, 0xf0, 0xa1, 0x91, 0xea, 0x40, 0x90, 0xdd, 0x07, 0x07, 0x00, 0xbc, 0xe1, 0x79, 0x18, 0xc2, 0x1f, + 0x58, 0x38, 0xb0, 0x2c, 0x55, 0x3f, 0x97, 0xd3, 0x18, 0xce, 0xdd, 0x5c, 0xed, 0xf0, 0xd9, 0x12, 0x14, 0x9b, 0x6a, + 0x4e, 0xcd, 0xe5, 0x2b, 0x6f, 0xec, 0xf7, 0x98, 0x60, 0x1e, 0x33, 0xdb, 0xf0, 0x5b, 0x4f, 0xb7, 0xf5, 0x0d, 0x76, + 0x03, 0x27, 0xed, 0x85, 0xd3, 0x5e, 0x6c, 0x97, 0x06, 0xf2, 0xaf, 0x6e, 0x08, 0x11, 0xde, 0x6b, 0x62, 0x91, 0x35, + 0x64, 0x3a, 0x16, 0x2b, 0x44, 0xb5, 0xa9, 0x78, 0xaa, 0x0d, 0x04, 0xca, 0xa9, 0xba, 0x30, 0xb5, 0x52, 0x99, 0x30, + 0x88, 0x3b, 0x25, 0x2c, 0xaa, 0x0c, 0x30, 0x0c, 0x2a, 0xa4, 0xb8, 0xb6, 0x9e, 0xbf, 0x70, 0xf9, 0x66, 0xa6, 0xcd, + 0xf6, 0xd3, 0x17, 0x79, 0x7c, 0xb1, 0xdd, 0x86, 0xdd, 0x2f, 0xc0, 0x1c, 0xb5, 0x54, 0x1a, 0x46, 0x70, 0x02, 0x51, + 0x92, 0xeb, 0x3b, 0x72, 0x4e, 0x1c, 0x27, 0xd7, 0x6e, 0xde, 0x6c, 0x27, 0xc5, 0x08, 0x2c, 0xe0, 0xc4, 0x45, 0x3a, + 0xd0, 0x52, 0x49, 0x6a, 0x4f, 0x01, 0x6f, 0xd3, 0x3b, 0x4a, 0x85, 0x57, 0x0b, 0x4d, 0x42, 0x2a, 0x77, 0x2f, 0xb1, + 0xa3, 0x06, 0x9c, 0x93, 0xba, 0x83, 0x80, 0xd3, 0x9e, 0x6e, 0xac, 0x55, 0x24, 0x9b, 0x04, 0xef, 0x95, 0x1e, 0xba, + 0x44, 0x3b, 0xb5, 0xbb, 0x6d, 0x55, 0xb6, 0x50, 0x30, 0xf7, 0x72, 0x96, 0xa8, 0xe3, 0x01, 0x85, 0x2e, 0xea, 0x68, + 0xc8, 0x17, 0xa4, 0xd0, 0x2b, 0x47, 0xab, 0x9a, 0x77, 0x25, 0x03, 0xa5, 0x5a, 0x05, 0x79, 0x4d, 0xac, 0xfb, 0x5a, + 0xd6, 0x58, 0x5c, 0x39, 0x21, 0x85, 0x4d, 0xf8, 0xd2, 0x52, 0x2c, 0xcc, 0x62, 0x6f, 0x4c, 0x7d, 0xe1, 0x12, 0xa1, + 0xed, 0x6e, 0x43, 0x8c, 0x36, 0x58, 0x37, 0xdb, 0xed, 0xfb, 0x22, 0x9c, 0x67, 0x0b, 0x2a, 0x47, 0x59, 0x8a, 0x90, + 0x6a, 0xc6, 0x63, 0xd9, 0x76, 0xc1, 0x4c, 0x0c, 0x75, 0xed, 0xf1, 0x92, 0x4c, 0xb1, 0x36, 0x49, 0x8e, 0xe2, 0x33, + 0x59, 0xa8, 0xb5, 0x46, 0x08, 0x1e, 0xee, 0xdf, 0xa5, 0x10, 0xd3, 0xce, 0xac, 0xbb, 0x5f, 0x76, 0x6e, 0x88, 0xdf, + 0x41, 0x60, 0x85, 0x92, 0xbd, 0x2f, 0x46, 0x67, 0x99, 0x48, 0x71, 0xa7, 0xaa, 0x28, 0xc1, 0x6a, 0x1d, 0x34, 0x5b, + 0x6e, 0xef, 0xc5, 0x96, 0x28, 0x40, 0x9c, 0x67, 0xa1, 0x19, 0xcf, 0xca, 0x59, 0xce, 0x64, 0x14, 0x1b, 0x12, 0x95, + 0x5e, 0x94, 0x78, 0x9f, 0xa7, 0x31, 0x3d, 0x74, 0x6b, 0x10, 0x5c, 0x57, 0x77, 0x36, 0xd2, 0x7c, 0x41, 0x88, 0x9a, + 0x00, 0x09, 0x1b, 0xd5, 0x9c, 0x5a, 0x17, 0xe2, 0x7e, 0x56, 0xf9, 0x56, 0x1f, 0xc4, 0x17, 0x02, 0x78, 0x58, 0x6f, + 0x7b, 0x5f, 0x0a, 0x8f, 0xb5, 0xc1, 0xb7, 0xdb, 0xed, 0x85, 0x98, 0x07, 0x81, 0xc7, 0x68, 0xfe, 0xa0, 0x24, 0xe6, + 0xbd, 0x31, 0x85, 0x15, 0xef, 0xbb, 0xf8, 0x75, 0x93, 0x5a, 0x6b, 0x91, 0xbb, 0xc3, 0xf5, 0x01, 0xcf, 0x53, 0xe2, + 0x68, 0x47, 0xe5, 0x54, 0x5a, 0xdb, 0x01, 0xec, 0x8a, 0xc0, 0x40, 0xd9, 0x1f, 0x52, 0xb6, 0x01, 0xf3, 0x44, 0xb0, + 0x3e, 0x42, 0xbf, 0x2d, 0xa5, 0x3f, 0x19, 0xa3, 0x71, 0x8f, 0x5c, 0x57, 0xd1, 0x01, 0xd7, 0xd1, 0xec, 0x79, 0xf4, + 0x8f, 0x27, 0x63, 0x5a, 0xc4, 0x22, 0x95, 0x97, 0xa0, 0x82, 0x00, 0x65, 0x08, 0x3a, 0x42, 0x68, 0x6a, 0x00, 0x1a, + 0x04, 0x37, 0x00, 0xbf, 0x76, 0x3a, 0x51, 0xda, 0x9a, 0x7c, 0x8c, 0x56, 0x55, 0xe4, 0xac, 0x0d, 0xed, 0xa6, 0x92, + 0x43, 0xf2, 0xb0, 0x04, 0x7c, 0x4b, 0x6c, 0x96, 0xb2, 0x41, 0x51, 0x9b, 0x4d, 0xbd, 0x56, 0xec, 0xc8, 0x4d, 0xa3, + 0x68, 0xb3, 0x16, 0xb5, 0xdd, 0xc8, 0x7c, 0x31, 0xbd, 0xb1, 0xc2, 0xc0, 0xa9, 0x69, 0xcd, 0xf5, 0x0e, 0x94, 0x9c, + 0xad, 0xcf, 0xe4, 0x26, 0x40, 0x1c, 0x60, 0xb8, 0x6e, 0xe6, 0xd7, 0x0b, 0x42, 0x6f, 0xd8, 0x8d, 0x15, 0xab, 0x5e, + 0x5b, 0xb9, 0x88, 0x49, 0xbb, 0x1e, 0x4c, 0xe0, 0x32, 0xce, 0x0a, 0xfb, 0x42, 0xab, 0x1b, 0x8a, 0x8e, 0xb6, 0x49, + 0xfb, 0x79, 0x47, 0xbb, 0xe1, 0x82, 0x6f, 0xc5, 0x3a, 0xce, 0x2d, 0x6b, 0xaa, 0xd0, 0xb4, 0x03, 0xbd, 0x1d, 0x02, + 0x9a, 0xb3, 0x31, 0x5d, 0xd2, 0x14, 0x2f, 0xd0, 0x74, 0x0d, 0x66, 0x3a, 0xe7, 0xd0, 0xd7, 0x6e, 0x1f, 0xed, 0x73, + 0xd5, 0x13, 0xe1, 0x2d, 0x51, 0xf0, 0x6d, 0x49, 0xc1, 0x4b, 0x2d, 0xe7, 0xb1, 0x99, 0x43, 0xc0, 0xa7, 0x51, 0x25, + 0x7a, 0x27, 0xc5, 0x05, 0x68, 0x33, 0xe1, 0x08, 0x34, 0x55, 0x23, 0xb6, 0x72, 0x80, 0xdb, 0x8b, 0xa7, 0x01, 0xa1, + 0x20, 0xd5, 0x5d, 0xdb, 0x15, 0x79, 0xc3, 0x8e, 0x36, 0x37, 0x60, 0x26, 0x5c, 0xad, 0xcb, 0xd6, 0x57, 0x36, 0xd9, + 0x7d, 0x5c, 0x13, 0x6c, 0xbb, 0xb7, 0x41, 0xc2, 0x1b, 0x7a, 0x4d, 0x36, 0xd7, 0xfd, 0x7e, 0x08, 0xfd, 0x21, 0x54, + 0x77, 0xe8, 0xa6, 0xb3, 0x43, 0x37, 0x5e, 0x3b, 0xcf, 0xac, 0x9e, 0x4f, 0x79, 0x87, 0xbc, 0x47, 0x93, 0x35, 0xba, + 0x8a, 0x6f, 0x61, 0x53, 0x47, 0x15, 0x55, 0x95, 0x47, 0x09, 0x05, 0x95, 0x78, 0xc6, 0xcb, 0x13, 0x8e, 0xb1, 0x5e, + 0xf5, 0xd3, 0x5b, 0xcd, 0xab, 0xad, 0xcd, 0xda, 0x2c, 0xd7, 0x67, 0x60, 0x21, 0x71, 0xc6, 0xa3, 0x4b, 0x4d, 0x4b, + 0x2e, 0x7c, 0x28, 0x4d, 0x1c, 0x95, 0xe0, 0x3c, 0xce, 0x72, 0x50, 0xe3, 0x9e, 0x37, 0xfb, 0x1f, 0x6a, 0xdb, 0xb1, + 0x65, 0xe3, 0xcc, 0xbd, 0x0a, 0xc9, 0xe6, 0x7f, 0x6c, 0xa0, 0x5e, 0x85, 0x18, 0x21, 0xd6, 0x2c, 0xe8, 0x37, 0x0c, + 0x62, 0x85, 0x06, 0xe5, 0x3a, 0x49, 0x78, 0x59, 0x06, 0x46, 0xa9, 0xb5, 0x66, 0x6b, 0x73, 0x9e, 0x3d, 0x60, 0x47, + 0x0f, 0x7a, 0x8c, 0xdd, 0x10, 0x9a, 0x68, 0x9d, 0x90, 0xa9, 0x31, 0xf2, 0xb4, 0x40, 0xba, 0x43, 0x51, 0x76, 0x1e, + 0xbe, 0x41, 0x21, 0x4b, 0x7b, 0x9f, 0x9b, 0x13, 0x59, 0x7d, 0xa3, 0x8d, 0x50, 0x22, 0x95, 0x08, 0xb2, 0xf1, 0x6b, + 0x04, 0x30, 0x86, 0x66, 0x07, 0x64, 0xb3, 0x64, 0x27, 0xf4, 0xd4, 0x9a, 0x04, 0xc1, 0xeb, 0x37, 0x2a, 0xd1, 0x8c, + 0xb2, 0x22, 0xba, 0xca, 0xe8, 0xe7, 0x36, 0x24, 0xd1, 0x69, 0x48, 0xfc, 0xdc, 0xb0, 0xb4, 0xae, 0x42, 0x14, 0x33, + 0x9b, 0x0d, 0xaf, 0x15, 0x51, 0x8d, 0x6d, 0x65, 0x7c, 0xcc, 0x6f, 0x6c, 0x1a, 0x99, 0x42, 0x5f, 0x87, 0x93, 0x7e, + 0x1f, 0xfe, 0x6a, 0xfa, 0x81, 0xb7, 0x14, 0xfc, 0xc5, 0x1e, 0x90, 0x3a, 0x61, 0x01, 0xc0, 0x33, 0xe6, 0xbc, 0x6a, + 0x4e, 0xe0, 0x03, 0x76, 0xb4, 0x79, 0x10, 0x9e, 0x34, 0x66, 0xee, 0x36, 0xc4, 0x4b, 0x55, 0xd2, 0xf3, 0xe6, 0xc9, + 0x0c, 0xc4, 0xca, 0x6a, 0xcd, 0x6f, 0x98, 0xd5, 0x27, 0x00, 0x91, 0xba, 0xb1, 0x0e, 0xb6, 0xf8, 0xb1, 0xe9, 0x32, + 0xd9, 0xa4, 0xac, 0xcd, 0x44, 0x29, 0x15, 0x49, 0x73, 0x11, 0x40, 0xbf, 0x61, 0x38, 0x6a, 0x80, 0x3b, 0xd7, 0x63, + 0x6f, 0x86, 0xc6, 0x1b, 0x53, 0x43, 0xcf, 0x36, 0x7a, 0x79, 0x3b, 0x0a, 0x61, 0xc6, 0x22, 0xba, 0x71, 0xc7, 0x62, + 0x78, 0x42, 0xdf, 0x40, 0x85, 0xaf, 0x42, 0x8c, 0x2e, 0x4c, 0xea, 0x7a, 0xba, 0x56, 0x5b, 0xe9, 0x9a, 0xd0, 0x1c, + 0xa3, 0x1a, 0x79, 0x6d, 0xbb, 0xa5, 0x46, 0x68, 0x4f, 0x28, 0x0f, 0x6f, 0x68, 0x45, 0xaf, 0x2d, 0x8b, 0xe0, 0xe4, + 0xc7, 0x5e, 0x7e, 0x42, 0xcf, 0x3c, 0x81, 0x49, 0xd1, 0xd6, 0x00, 0x7e, 0x40, 0xfd, 0x70, 0x56, 0x4f, 0xad, 0x94, + 0xc3, 0x53, 0xf8, 0x92, 0x0d, 0xc8, 0x15, 0xf4, 0x62, 0x8d, 0xd9, 0x51, 0x0c, 0x3a, 0xa8, 0x9d, 0xdd, 0xe1, 0x4d, + 0x4a, 0x19, 0xa2, 0x35, 0xa2, 0x83, 0xbc, 0xfa, 0x15, 0x34, 0x7d, 0x90, 0x16, 0xa6, 0x74, 0x8d, 0x02, 0x1e, 0xd0, + 0x37, 0xf5, 0xfb, 0x39, 0x3e, 0xd7, 0x9e, 0x65, 0x9a, 0xb2, 0x40, 0x26, 0x74, 0xe9, 0xc5, 0xed, 0x02, 0x69, 0xb3, + 0x63, 0x15, 0x80, 0x15, 0x49, 0xa0, 0x11, 0x09, 0x58, 0x2e, 0x79, 0xe2, 0xb2, 0x0d, 0x1a, 0xd4, 0x44, 0x25, 0x85, + 0x2c, 0x91, 0x04, 0x7e, 0x18, 0x41, 0x99, 0xa2, 0x18, 0xc4, 0xbd, 0x7a, 0x79, 0xc5, 0x35, 0x35, 0x60, 0x4d, 0x11, + 0x4c, 0xb0, 0x4e, 0xa7, 0x40, 0x6c, 0xc5, 0x7a, 0x05, 0x9e, 0xa8, 0xee, 0x22, 0x89, 0x2c, 0x01, 0x1a, 0xe8, 0xf9, + 0xd2, 0x69, 0xb7, 0xbc, 0x3d, 0xd1, 0x52, 0xc5, 0xe6, 0xde, 0x8b, 0x85, 0xe5, 0x1e, 0x2b, 0x7f, 0x3b, 0xd0, 0x5e, + 0x58, 0xed, 0x88, 0xa8, 0xc1, 0xea, 0xb0, 0x6d, 0xe7, 0x87, 0xd2, 0x50, 0xdd, 0x2b, 0xc7, 0x04, 0x54, 0x74, 0x15, + 0x57, 0xcb, 0x28, 0x1b, 0xc1, 0x9f, 0xed, 0x36, 0xd8, 0x0f, 0xc0, 0x22, 0xf4, 0xc3, 0xbb, 0x9f, 0x22, 0x0c, 0x57, + 0xf5, 0xe1, 0xdd, 0x4f, 0xdb, 0xed, 0x93, 0xf1, 0xd8, 0x70, 0x05, 0x4e, 0xad, 0x03, 0xfc, 0x81, 0x61, 0x1b, 0xec, + 0x92, 0xdd, 0x6e, 0x9f, 0x00, 0x07, 0xa1, 0xd8, 0x06, 0xb3, 0x8b, 0x95, 0x63, 0x9b, 0x62, 0x35, 0xf4, 0x8e, 0x04, + 0xec, 0xbe, 0x1d, 0x96, 0x62, 0x97, 0xfa, 0xa8, 0x90, 0x94, 0x7a, 0xd1, 0x3f, 0xef, 0x14, 0x58, 0x52, 0x30, 0xe5, + 0x0d, 0x96, 0x55, 0xb5, 0x2a, 0xa3, 0xfd, 0xfd, 0x78, 0x95, 0x8d, 0xca, 0x0c, 0xb6, 0x79, 0x79, 0x75, 0x01, 0x00, + 0x13, 0x01, 0x6d, 0xbc, 0x5b, 0x8b, 0xcc, 0xbc, 0x58, 0xd0, 0x65, 0x86, 0x6b, 0x12, 0xcc, 0x0e, 0x72, 0x6e, 0x75, + 0x93, 0x53, 0x62, 0x1f, 0xc0, 0x06, 0x73, 0xbb, 0x6d, 0xf0, 0x0b, 0x47, 0xa3, 0x27, 0xb3, 0x65, 0xa6, 0x0d, 0x5c, + 0xb9, 0xd9, 0xff, 0x24, 0xf2, 0xd2, 0x50, 0xf1, 0x49, 0xa6, 0xcf, 0x33, 0xe0, 0xf3, 0xd8, 0x27, 0x11, 0xfa, 0x2c, + 0x57, 0xa3, 0x35, 0xc0, 0xc6, 0x66, 0xe7, 0xb7, 0xa3, 0x94, 0x43, 0x84, 0x8e, 0xc0, 0xaa, 0x6b, 0x96, 0x19, 0xf1, + 0x6d, 0x2a, 0x6e, 0x5a, 0xaa, 0xb0, 0x4f, 0xc2, 0x73, 0xde, 0xe1, 0xc6, 0x71, 0xa8, 0x37, 0x89, 0xc2, 0xe7, 0x28, + 0x44, 0xe5, 0x68, 0x5c, 0xe8, 0xe4, 0x6b, 0x99, 0xc7, 0x84, 0x62, 0x0e, 0xf7, 0xee, 0xf7, 0xd4, 0x99, 0xcb, 0xf8, + 0xc2, 0xbd, 0xe7, 0xbe, 0xcc, 0xe4, 0x4a, 0x02, 0x48, 0x94, 0xaa, 0xfd, 0xe7, 0xcf, 0x48, 0x8d, 0xff, 0x4e, 0xb5, + 0x06, 0xa0, 0xf7, 0x33, 0xd4, 0xe4, 0x08, 0x02, 0xb6, 0x62, 0xea, 0x47, 0x17, 0xb0, 0x92, 0xf9, 0x9f, 0x50, 0xb7, + 0x23, 0xd8, 0x46, 0xc5, 0x13, 0x8a, 0x2a, 0x5a, 0xf0, 0x74, 0x2d, 0xd2, 0x58, 0x24, 0xb7, 0x11, 0xaf, 0xa7, 0x58, + 0x12, 0xb3, 0x11, 0xc3, 0x7e, 0x6e, 0x76, 0xe1, 0x5d, 0xd1, 0x30, 0x89, 0xa7, 0xa5, 0xbf, 0xad, 0xbc, 0xcd, 0x64, + 0x19, 0x67, 0x64, 0xca, 0x15, 0x82, 0xb9, 0xd5, 0xf7, 0x98, 0x13, 0xfc, 0xf1, 0xc1, 0x63, 0x42, 0xaf, 0xe4, 0xb4, + 0x44, 0x90, 0x3e, 0x91, 0x5a, 0xd7, 0x55, 0xec, 0xd7, 0x14, 0xa2, 0x5a, 0x08, 0x06, 0xa1, 0x4c, 0x4d, 0xfb, 0x14, + 0xdf, 0x67, 0xcb, 0xfe, 0x64, 0xca, 0x96, 0x64, 0x23, 0xa0, 0x63, 0xd2, 0x79, 0xbf, 0x7a, 0x7b, 0x76, 0xe6, 0xfd, + 0x06, 0x4d, 0x38, 0xa8, 0x6e, 0xa0, 0x5d, 0x05, 0x99, 0xc6, 0x28, 0x36, 0x8b, 0xb1, 0x76, 0x6b, 0x22, 0x82, 0x20, + 0xdc, 0xe5, 0x2c, 0x6c, 0xb7, 0x13, 0xe2, 0x6d, 0x20, 0x81, 0x02, 0xd7, 0x36, 0xca, 0x49, 0x48, 0xd4, 0x85, 0xcc, + 0x1c, 0x13, 0x92, 0x05, 0x7a, 0x8d, 0x1d, 0x04, 0xf4, 0x98, 0xdb, 0xa7, 0x80, 0xbe, 0x28, 0xd8, 0x31, 0x1f, 0x04, + 0x43, 0x8c, 0x37, 0x1b, 0xd0, 0x8f, 0x52, 0x3d, 0x82, 0xc7, 0x34, 0xb0, 0x5c, 0xf4, 0x75, 0xc1, 0x10, 0x66, 0xe9, + 0xb7, 0x94, 0x4d, 0xbe, 0xf9, 0xa7, 0x9b, 0xdf, 0x33, 0x2d, 0x66, 0x07, 0xa1, 0xb8, 0xbd, 0x9e, 0x00, 0xf1, 0xab, + 0xf8, 0x25, 0x58, 0x9b, 0x6b, 0x89, 0xb7, 0x27, 0x79, 0x10, 0xbe, 0x1c, 0xdd, 0x7e, 0x52, 0x9a, 0x4f, 0x20, 0x68, + 0x8f, 0x93, 0x94, 0xbb, 0xef, 0x4e, 0xa4, 0xab, 0x08, 0x46, 0x0b, 0x10, 0xfc, 0xee, 0xac, 0xe4, 0xb4, 0x29, 0xfc, + 0xc7, 0x3a, 0x5f, 0x60, 0x2c, 0x15, 0x79, 0x82, 0xd3, 0xdf, 0x04, 0x07, 0xf7, 0x6f, 0x65, 0xd6, 0x90, 0xe8, 0x4c, + 0x7d, 0x04, 0xf4, 0x7f, 0xac, 0xc7, 0xef, 0x18, 0x25, 0x7d, 0x49, 0x9c, 0x23, 0x7c, 0x13, 0x2f, 0xd1, 0x74, 0xb1, + 0x37, 0xae, 0xe9, 0xa7, 0xc2, 0xbc, 0xd0, 0x0a, 0x0e, 0xfb, 0xd6, 0x28, 0x3c, 0xf0, 0xcc, 0xfb, 0x4e, 0x34, 0x04, + 0xdd, 0xff, 0xc2, 0xbd, 0xf1, 0x9d, 0x60, 0x19, 0xde, 0x94, 0xb3, 0xcc, 0xdc, 0xe1, 0xae, 0x33, 0x91, 0xca, 0x6b, + 0xc6, 0x82, 0xb5, 0x50, 0xe6, 0xbc, 0x69, 0x30, 0xdb, 0xd4, 0x91, 0x4a, 0x76, 0xdf, 0xff, 0xd5, 0x38, 0x61, 0xb3, + 0x41, 0x70, 0x52, 0xc9, 0x22, 0xbe, 0xe0, 0xc1, 0x54, 0xab, 0x28, 0x32, 0xb0, 0x2b, 0x04, 0xa4, 0x1c, 0xa7, 0xbd, + 0x83, 0x27, 0x4b, 0xcd, 0x4c, 0xc8, 0x6f, 0xab, 0xb3, 0x80, 0xb7, 0x66, 0x34, 0x8f, 0x2b, 0xd8, 0x65, 0xbe, 0x92, + 0xe2, 0xbb, 0x96, 0x24, 0x1b, 0xeb, 0x6f, 0xc8, 0xb0, 0xad, 0x7c, 0xe6, 0x0c, 0x30, 0x77, 0x3e, 0x4a, 0x15, 0xf4, + 0xaf, 0xc7, 0xd8, 0xb5, 0x44, 0x22, 0x20, 0x9c, 0xc5, 0xc4, 0xad, 0x30, 0xe1, 0x30, 0x5d, 0xa0, 0xa0, 0x18, 0x03, + 0x05, 0x9d, 0xc8, 0x90, 0xd3, 0x63, 0x3e, 0x48, 0x1a, 0xb3, 0xf5, 0x97, 0x2a, 0x91, 0x5e, 0x4b, 0x42, 0x4f, 0xe1, + 0xf7, 0xb8, 0xc5, 0x03, 0x35, 0x82, 0x75, 0xba, 0x9b, 0xd3, 0xfe, 0xeb, 0x82, 0x0c, 0x7f, 0x03, 0x6f, 0xb7, 0xd8, + 0x5e, 0x96, 0x13, 0x58, 0xdc, 0xb1, 0x57, 0x3c, 0xcd, 0x55, 0x8b, 0x13, 0xe2, 0x11, 0x8b, 0xdc, 0x27, 0x16, 0x30, + 0xa2, 0x86, 0xd1, 0xf8, 0xf1, 0xe4, 0xcd, 0x6b, 0x8d, 0x61, 0x95, 0xfb, 0x1f, 0xc0, 0x88, 0x6a, 0x69, 0xbb, 0x1d, + 0xf0, 0xe5, 0x08, 0x0d, 0xd8, 0x53, 0x37, 0xd8, 0xfd, 0xbe, 0x49, 0x3b, 0x2a, 0xbd, 0x6c, 0x4e, 0x0c, 0xba, 0xa3, + 0xb4, 0x59, 0x2a, 0x03, 0xe3, 0xae, 0xc2, 0xd1, 0x9c, 0xd8, 0x88, 0x55, 0xbd, 0x0f, 0xc3, 0x25, 0x8d, 0xad, 0xac, + 0xdc, 0xee, 0x26, 0x1c, 0xd9, 0x04, 0xb8, 0x3e, 0x05, 0xed, 0xd5, 0x9c, 0x83, 0x16, 0x94, 0x28, 0x70, 0x44, 0xdb, + 0x6d, 0x08, 0x11, 0x49, 0x8a, 0xe1, 0x64, 0x16, 0x16, 0xc3, 0xa1, 0x1a, 0xf8, 0x82, 0x90, 0xe8, 0x53, 0x31, 0xcf, + 0x16, 0x0a, 0xc1, 0xc8, 0xdf, 0x49, 0xbf, 0x14, 0x8a, 0x53, 0xee, 0x7d, 0x27, 0xc8, 0xe6, 0x5f, 0x29, 0xc6, 0x60, + 0x74, 0x9a, 0xcd, 0x0c, 0x24, 0xac, 0xc7, 0x15, 0x51, 0xeb, 0xc8, 0xce, 0x06, 0xa8, 0x62, 0xd1, 0x34, 0x18, 0xd4, + 0x2d, 0x9e, 0x58, 0xcf, 0xe8, 0x3d, 0xa8, 0x04, 0x51, 0x2d, 0xd8, 0x8d, 0xe1, 0x5a, 0x7b, 0x2d, 0x42, 0x49, 0x39, + 0x69, 0x32, 0x33, 0x56, 0x34, 0x58, 0x80, 0x90, 0x34, 0x2e, 0xab, 0x57, 0x32, 0xcd, 0xce, 0x33, 0x40, 0x90, 0x70, + 0xfe, 0x84, 0xb2, 0xf1, 0xe6, 0xa9, 0x9a, 0x97, 0xae, 0xc4, 0x99, 0x85, 0x3d, 0xe9, 0x7a, 0x4b, 0x0b, 0x12, 0x15, + 0x40, 0xa3, 0x7c, 0x2d, 0xcf, 0xf7, 0x3b, 0x56, 0x21, 0xbb, 0x1f, 0x4e, 0x95, 0xed, 0x10, 0x3f, 0x62, 0x15, 0xf1, + 0x4e, 0xeb, 0x4a, 0x89, 0x34, 0x3a, 0xda, 0x06, 0xc4, 0xb0, 0x65, 0xdf, 0xa2, 0x86, 0x0f, 0xc2, 0x2e, 0x3a, 0xc9, + 0x0f, 0x7a, 0x8a, 0xc7, 0xd6, 0x40, 0xd2, 0xd7, 0x22, 0xf8, 0x1a, 0x1d, 0xe9, 0x44, 0x99, 0x46, 0x62, 0x0a, 0x89, + 0x7e, 0xbd, 0xd0, 0x1a, 0xcb, 0x28, 0xfb, 0x8a, 0xfc, 0x9f, 0x75, 0xf7, 0xbe, 0x13, 0xdb, 0x2d, 0x4c, 0xb2, 0xe7, + 0x81, 0x06, 0x9b, 0x1a, 0xb5, 0x42, 0x38, 0x3b, 0xc7, 0x15, 0x6a, 0xc7, 0x7a, 0x61, 0x09, 0xe4, 0x01, 0x6c, 0x45, + 0x1a, 0x94, 0x41, 0xb2, 0x4f, 0xc5, 0x5c, 0x2c, 0x9c, 0x28, 0x47, 0x2a, 0xfc, 0x33, 0x39, 0x4a, 0x39, 0x5c, 0xc5, + 0xc2, 0x82, 0x21, 0xbf, 0x3a, 0x3a, 0x2f, 0xe4, 0x25, 0x48, 0x4a, 0x0c, 0x43, 0x65, 0x79, 0x5d, 0x5c, 0xb5, 0x25, + 0xa1, 0xbd, 0x53, 0x00, 0xa5, 0x29, 0x40, 0xf0, 0xd2, 0xa8, 0x21, 0x66, 0x1b, 0xb5, 0xbb, 0xa2, 0x3b, 0xc9, 0x01, + 0x75, 0xba, 0x6b, 0xb7, 0xde, 0x94, 0xad, 0xba, 0x15, 0x17, 0xfe, 0x05, 0xa5, 0x1f, 0xf3, 0x41, 0xe1, 0x53, 0x09, + 0xdc, 0xf8, 0x6a, 0x93, 0x65, 0xe7, 0xb7, 0xb8, 0xf4, 0xab, 0xc6, 0xf8, 0xf5, 0xfb, 0x3d, 0xb5, 0x10, 0x1a, 0xa9, + 0xc0, 0x7c, 0xfb, 0xcc, 0x54, 0x65, 0x34, 0xa5, 0xf6, 0x12, 0x5c, 0x39, 0xfb, 0x11, 0x54, 0xc4, 0x75, 0x45, 0x6a, + 0x53, 0x03, 0xb4, 0xe7, 0x65, 0x85, 0x5b, 0x59, 0x80, 0xc7, 0x4e, 0x40, 0xb6, 0x5b, 0x1e, 0x06, 0xfa, 0xd0, 0x09, + 0xfc, 0x2d, 0xf9, 0x0a, 0x99, 0x35, 0xfb, 0xf8, 0x87, 0x16, 0xfc, 0x63, 0x0b, 0x7e, 0x42, 0x71, 0xa7, 0x95, 0xf9, + 0xb7, 0xd2, 0xba, 0xc5, 0xfd, 0x3b, 0x99, 0x26, 0x14, 0x95, 0x09, 0xb5, 0x5f, 0xe9, 0x8f, 0x26, 0x78, 0x94, 0xca, + 0xfe, 0x5e, 0xc2, 0x07, 0xb3, 0xc6, 0x13, 0x6b, 0x3c, 0x19, 0x4e, 0xb7, 0xd2, 0xb0, 0x0c, 0x28, 0xf4, 0xf3, 0x32, + 0x57, 0x54, 0x3f, 0xff, 0xbc, 0xe6, 0x6b, 0xde, 0x6c, 0xb1, 0x4d, 0xba, 0xa7, 0xc1, 0x5e, 0x1e, 0x4d, 0x29, 0x9c, + 0x44, 0x9d, 0x1b, 0x89, 0xba, 0xa8, 0x59, 0x86, 0xea, 0x04, 0xaf, 0xe6, 0xa9, 0x1e, 0xf6, 0x66, 0x22, 0x5a, 0x2b, + 0x29, 0x4b, 0x0c, 0x58, 0xeb, 0xc8, 0x43, 0x72, 0xb7, 0xd6, 0x71, 0xa7, 0xa1, 0x2e, 0x4d, 0xa1, 0x26, 0x58, 0xe1, + 0x02, 0x1c, 0x41, 0xef, 0x8a, 0x90, 0xc3, 0x35, 0x55, 0xe9, 0x17, 0x34, 0x25, 0x4f, 0x3c, 0x45, 0xad, 0x56, 0xa4, + 0xdb, 0x8f, 0x72, 0xec, 0x86, 0x6f, 0x9c, 0x90, 0x13, 0x23, 0xf4, 0x77, 0xc7, 0x52, 0xce, 0xd0, 0xe2, 0x41, 0x9d, + 0x60, 0xbd, 0xbc, 0xa5, 0x40, 0x31, 0x47, 0x97, 0x55, 0xd7, 0xbc, 0x44, 0xdb, 0x97, 0x65, 0xbf, 0x9f, 0xdb, 0x7a, + 0x52, 0x76, 0xb4, 0x59, 0x9a, 0x7d, 0x88, 0x8a, 0x29, 0xdc, 0xf5, 0x89, 0xe6, 0xaf, 0x42, 0x7d, 0xd5, 0x96, 0x39, + 0x1f, 0x71, 0xc4, 0x09, 0xc9, 0x49, 0xfd, 0x87, 0x9a, 0x7a, 0x25, 0xee, 0x57, 0x95, 0xfc, 0x22, 0x8c, 0x15, 0xa3, + 0x25, 0x86, 0x28, 0xd2, 0xee, 0x8d, 0xe9, 0xcb, 0x02, 0xe0, 0xaf, 0x04, 0xfb, 0x94, 0x86, 0x5a, 0xf9, 0x2d, 0xda, + 0x02, 0xfe, 0x8d, 0xe2, 0x06, 0xac, 0x02, 0x03, 0x8c, 0x26, 0xdb, 0x73, 0x9a, 0xc0, 0x01, 0x27, 0xb4, 0x8a, 0x82, + 0x0a, 0x33, 0x34, 0xd4, 0x16, 0x46, 0x5f, 0xa1, 0x8c, 0x5b, 0x65, 0xf6, 0x6e, 0x8c, 0x9d, 0x16, 0x78, 0x0d, 0xff, + 0x46, 0x2f, 0x14, 0xb3, 0x51, 0x07, 0xe9, 0xd1, 0x49, 0x4c, 0x7f, 0xdc, 0xc2, 0xc9, 0xcd, 0xc2, 0x59, 0xd6, 0x2c, + 0x81, 0xee, 0xc0, 0x05, 0x31, 0xee, 0xf7, 0x73, 0x38, 0x32, 0xcd, 0xc8, 0x17, 0x2c, 0xa7, 0x31, 0x5b, 0x52, 0xed, + 0x79, 0x78, 0x51, 0x85, 0x39, 0x5d, 0x5a, 0x19, 0x6f, 0xca, 0x40, 0x65, 0xb4, 0xdd, 0x86, 0xf0, 0xa7, 0xdb, 0xda, + 0x25, 0x9d, 0x2f, 0x21, 0x03, 0xfc, 0x01, 0x89, 0x28, 0x62, 0x81, 0xff, 0x5b, 0x8d, 0x53, 0x7a, 0xa2, 0xb4, 0x66, + 0x09, 0x5d, 0x33, 0x5d, 0x3f, 0x3d, 0x67, 0xeb, 0xc6, 0x52, 0xd8, 0x6e, 0xc3, 0x66, 0x02, 0xd3, 0x9c, 0x2b, 0x99, + 0x9e, 0xa3, 0x4e, 0x0a, 0xa8, 0x58, 0x78, 0x8e, 0xcb, 0x2f, 0x25, 0x14, 0x9a, 0x3b, 0x5f, 0x2e, 0x8c, 0x12, 0x13, + 0x5a, 0x25, 0xbf, 0x7c, 0xa8, 0xcc, 0xd7, 0xc6, 0x43, 0xf0, 0xc7, 0x34, 0x4c, 0x4c, 0x91, 0xa8, 0x10, 0x9d, 0xfd, + 0x02, 0xb2, 0x1c, 0x01, 0xb8, 0x9e, 0xaf, 0x20, 0x0a, 0xdc, 0x1a, 0xe2, 0xc2, 0x43, 0x83, 0xde, 0x16, 0xf2, 0x32, + 0x2b, 0x79, 0x88, 0xf7, 0x04, 0x4f, 0x33, 0x7a, 0xb7, 0xc1, 0x87, 0xb6, 0xf6, 0xe8, 0x09, 0xb2, 0xf1, 0x94, 0xfb, + 0xf5, 0x2f, 0x22, 0x9c, 0x43, 0xf4, 0xce, 0x05, 0xd5, 0xea, 0x6a, 0x07, 0xc8, 0xe5, 0xd9, 0x5e, 0x3d, 0x80, 0xd3, + 0x4d, 0x5f, 0xdf, 0xaa, 0xd0, 0x99, 0x03, 0x48, 0x7b, 0x48, 0xd6, 0x35, 0xd7, 0x3b, 0xc0, 0x3b, 0x12, 0xd7, 0x40, + 0x63, 0xdd, 0xd6, 0xec, 0xb4, 0x47, 0xf1, 0x98, 0xc8, 0xcc, 0x58, 0xa4, 0x18, 0x73, 0xb7, 0x4e, 0x8b, 0xa2, 0x0d, + 0x9a, 0x21, 0xec, 0xde, 0x75, 0xb2, 0x75, 0x2b, 0xe2, 0xfc, 0xdd, 0xb6, 0x2f, 0x30, 0x1a, 0xc6, 0x5c, 0xbb, 0xe7, + 0x1b, 0xba, 0xad, 0xdd, 0xc8, 0x68, 0x24, 0xc8, 0x4c, 0x1d, 0x88, 0xb2, 0xb6, 0x06, 0x6c, 0x0f, 0xb8, 0xde, 0xb4, + 0xc0, 0xcf, 0x9b, 0x18, 0xbc, 0x3d, 0x6b, 0x9c, 0xd2, 0xfa, 0x1a, 0xd7, 0x1c, 0x57, 0x85, 0x88, 0xda, 0x22, 0x05, + 0xc0, 0xb0, 0xf3, 0x05, 0xee, 0xcc, 0x0a, 0x83, 0x39, 0x61, 0xa9, 0x64, 0xa7, 0x72, 0xfd, 0x39, 0x6c, 0x71, 0x90, + 0xca, 0x97, 0x5e, 0x7f, 0xff, 0xf0, 0xc5, 0x17, 0xe8, 0xb6, 0xe7, 0xfc, 0x08, 0x82, 0x4c, 0xa0, 0x83, 0x9a, 0x52, + 0x3d, 0xfe, 0x50, 0x00, 0xb5, 0x87, 0x79, 0xf8, 0xa1, 0x60, 0x22, 0xbe, 0xca, 0x2e, 0xe2, 0x4a, 0x16, 0xa3, 0x2b, + 0x2e, 0x52, 0x59, 0x58, 0xa9, 0x71, 0x70, 0xbc, 0x5a, 0xe5, 0x3c, 0x00, 0x53, 0x79, 0xcb, 0x28, 0x3b, 0xb9, 0xa4, + 0x1e, 0x5c, 0x2d, 0x4f, 0xaf, 0xb4, 0xe8, 0xbc, 0xbc, 0xba, 0x08, 0x22, 0xfc, 0x75, 0x66, 0x7e, 0x5c, 0xc6, 0xe5, + 0xc7, 0x20, 0xb2, 0x36, 0x75, 0xe6, 0x07, 0x4a, 0xe5, 0xc1, 0xdf, 0x09, 0x64, 0xba, 0x3f, 0x14, 0x60, 0x99, 0x6d, + 0x2b, 0x3e, 0x8c, 0xb1, 0xd6, 0xe1, 0x84, 0xcc, 0x54, 0x89, 0xde, 0xbb, 0x64, 0x5d, 0x80, 0xb5, 0x9f, 0xc2, 0x76, + 0x56, 0xb9, 0x66, 0x58, 0x99, 0xaa, 0xc8, 0x10, 0xb4, 0x35, 0xdb, 0x0f, 0xad, 0x13, 0xcd, 0x1c, 0xbd, 0x05, 0xf4, + 0x03, 0xd9, 0xbf, 0xa0, 0x72, 0xcd, 0x3c, 0x1f, 0x9b, 0xc6, 0xeb, 0x07, 0xfb, 0x17, 0x9e, 0x40, 0xc9, 0xde, 0xc9, + 0x51, 0x98, 0x08, 0x9e, 0xc6, 0x66, 0x7c, 0x91, 0x67, 0x05, 0xec, 0xa0, 0xc9, 0x78, 0x4c, 0xbd, 0xa5, 0xd5, 0xba, + 0x39, 0x3a, 0x64, 0xdb, 0xec, 0x61, 0xf5, 0x90, 0x93, 0x7d, 0xde, 0x32, 0xb5, 0x6d, 0x5b, 0xc7, 0x79, 0x9a, 0x7c, + 0x65, 0xba, 0x5f, 0xae, 0x6d, 0x84, 0x78, 0xe5, 0xec, 0xe8, 0xbc, 0xa4, 0x5b, 0xdf, 0x94, 0x86, 0x5e, 0x4b, 0x00, + 0xe6, 0xd3, 0x06, 0xfc, 0x05, 0x93, 0xeb, 0x51, 0xc5, 0xcb, 0x0a, 0x24, 0x2c, 0x28, 0xc2, 0x9b, 0x62, 0x6f, 0x0a, + 0x77, 0xe3, 0xf4, 0x1c, 0x76, 0xe0, 0x62, 0x8a, 0xee, 0x38, 0x31, 0x99, 0x95, 0x46, 0x2b, 0x1a, 0xe9, 0x5f, 0xae, + 0x2f, 0xb1, 0xee, 0x8b, 0x56, 0xe6, 0xd9, 0x9c, 0x0a, 0x9b, 0xde, 0x55, 0x2e, 0x9d, 0xa8, 0xdf, 0x32, 0xe1, 0xca, + 0x95, 0x20, 0x20, 0xd3, 0x82, 0xf5, 0x0a, 0xb3, 0x8b, 0x0a, 0x24, 0x64, 0x60, 0xf8, 0x1a, 0xac, 0x45, 0xc9, 0x8d, + 0x15, 0xac, 0x77, 0xcf, 0xd7, 0x09, 0x42, 0x0a, 0x1e, 0xb8, 0x09, 0xfa, 0xd0, 0xba, 0x79, 0x3b, 0x4a, 0x94, 0x41, + 0x7c, 0x72, 0xed, 0x94, 0x83, 0x04, 0x02, 0x70, 0x60, 0x55, 0x48, 0x12, 0x05, 0x3a, 0x0f, 0xae, 0x66, 0x1c, 0xc1, + 0xe6, 0x95, 0x33, 0x17, 0x37, 0x80, 0xf3, 0xca, 0x9f, 0xcb, 0x06, 0x5b, 0xd6, 0x23, 0xaa, 0xcc, 0x19, 0xa7, 0x18, + 0xd4, 0xc9, 0x12, 0xf4, 0x95, 0xa5, 0xb4, 0x17, 0xa0, 0x69, 0xbc, 0x64, 0x2b, 0xe5, 0x03, 0x40, 0xcf, 0xd8, 0x4a, + 0x19, 0xfb, 0xe3, 0xd7, 0xa7, 0x6c, 0xa5, 0xa5, 0xc1, 0xd3, 0xcb, 0xd9, 0xd9, 0xec, 0x74, 0xc0, 0x0e, 0xa2, 0x50, + 0x1b, 0x30, 0x04, 0x2e, 0x32, 0x41, 0x30, 0x08, 0x35, 0xfe, 0xcb, 0x40, 0x05, 0x08, 0x23, 0x1e, 0x8f, 0x8d, 0x38, + 0x62, 0xe1, 0x78, 0x88, 0xc1, 0xc0, 0x9a, 0x2f, 0x48, 0x40, 0xa8, 0x29, 0x0d, 0x7d, 0x3d, 0xc3, 0xe1, 0x64, 0x6f, + 0x02, 0xa9, 0x98, 0x99, 0xa9, 0xc2, 0xd8, 0x98, 0x44, 0x10, 0xff, 0xb5, 0xb3, 0x5e, 0x28, 0xb7, 0xbb, 0x46, 0x03, + 0x41, 0x33, 0xf8, 0xa2, 0x8a, 0x27, 0x7b, 0xc3, 0xae, 0x8a, 0x71, 0x14, 0xae, 0x8c, 0xf2, 0xed, 0xf4, 0x10, 0xc0, + 0x7c, 0x4f, 0x87, 0xbe, 0x5c, 0xe2, 0x74, 0xff, 0x31, 0x79, 0xf8, 0x98, 0xd0, 0x53, 0x76, 0xfa, 0xd5, 0x63, 0x7a, + 0xaa, 0xc8, 0xc9, 0xde, 0x24, 0xba, 0x62, 0x16, 0x03, 0xe7, 0x40, 0x35, 0x81, 0x5e, 0x8c, 0xd6, 0x42, 0x2d, 0x30, + 0xed, 0xd0, 0x14, 0x7e, 0x3b, 0xde, 0x0b, 0x06, 0x57, 0xed, 0xa6, 0x5f, 0xb5, 0xdb, 0xea, 0x79, 0x75, 0xed, 0x1d, + 0x44, 0xbb, 0xc5, 0x4c, 0xfe, 0x39, 0xde, 0x73, 0x73, 0x80, 0xf5, 0xdd, 0x3f, 0x26, 0xa6, 0x49, 0x3b, 0xa3, 0xe2, + 0xd7, 0xf4, 0x08, 0xfb, 0xd0, 0x2c, 0xb2, 0xa3, 0x0f, 0xc3, 0x7f, 0xab, 0x13, 0xf5, 0xe9, 0x57, 0x07, 0x40, 0x8e, + 0x40, 0x06, 0x8a, 0x25, 0x82, 0x19, 0x0e, 0x34, 0x05, 0x14, 0x64, 0x7a, 0xdc, 0xa9, 0x1e, 0x7e, 0x35, 0x6a, 0x6a, + 0x46, 0xae, 0x60, 0x6a, 0xb0, 0x2d, 0xf8, 0x81, 0xea, 0x86, 0xfe, 0x46, 0xa3, 0x3d, 0x69, 0x27, 0x33, 0xf3, 0x92, + 0xda, 0x38, 0x77, 0x57, 0x10, 0xd0, 0xd9, 0xc1, 0x2d, 0x4a, 0xf6, 0xf5, 0xe1, 0xc5, 0x1e, 0xae, 0x22, 0x40, 0x0d, + 0x63, 0xc1, 0xd7, 0x83, 0x0b, 0xbd, 0xb9, 0xf7, 0x02, 0x32, 0xf8, 0x3a, 0x38, 0xfa, 0x7a, 0x20, 0x07, 0xc1, 0xe1, + 0xfe, 0xc5, 0x51, 0xe0, 0x8c, 0xfb, 0x21, 0xe4, 0xa5, 0xaa, 0x28, 0x66, 0xc2, 0x54, 0x91, 0xd8, 0xda, 0x73, 0x5b, + 0xaf, 0x32, 0x3e, 0xa3, 0xe9, 0xd4, 0x22, 0xa1, 0x87, 0x29, 0x8b, 0xcd, 0xef, 0x60, 0xc2, 0x2f, 0x83, 0xc8, 0x05, + 0x85, 0x9d, 0xe5, 0x51, 0x4c, 0x97, 0xec, 0x46, 0x84, 0x29, 0x4d, 0xf6, 0x73, 0x42, 0xa2, 0x70, 0xa9, 0xc0, 0x04, + 0xd5, 0xeb, 0x04, 0xe2, 0xda, 0xba, 0xcf, 0x6f, 0x44, 0xb8, 0xa4, 0xf9, 0x7e, 0x42, 0x5a, 0x45, 0xb8, 0x08, 0x35, + 0x9b, 0x9a, 0x9e, 0xb3, 0x70, 0x45, 0x2f, 0xd0, 0x54, 0x73, 0x1d, 0x5e, 0x00, 0x97, 0xb7, 0x9e, 0xaf, 0x16, 0xec, + 0xa2, 0x21, 0x7d, 0x33, 0x7c, 0xf1, 0xb9, 0xf5, 0xc9, 0x03, 0x1e, 0xd2, 0xf9, 0xe1, 0xa5, 0x60, 0x03, 0x70, 0x95, + 0xf1, 0xeb, 0xef, 0xe4, 0x8d, 0x9e, 0x97, 0xf6, 0x14, 0xe3, 0xcc, 0xb4, 0x13, 0x93, 0x76, 0x42, 0xee, 0xdf, 0xb7, + 0x7d, 0xf7, 0xe2, 0xb5, 0x72, 0x59, 0xb5, 0x0c, 0x49, 0xbc, 0x56, 0xae, 0xd3, 0x28, 0x39, 0xb5, 0x02, 0x4f, 0x76, + 0xce, 0xab, 0x64, 0xe9, 0x1f, 0x54, 0xd6, 0x6a, 0xc0, 0x1e, 0x23, 0x96, 0x85, 0xc2, 0xb1, 0x7f, 0x95, 0xb1, 0x78, + 0xdd, 0x40, 0x06, 0x46, 0xee, 0xed, 0x55, 0xc6, 0xbc, 0x18, 0xb4, 0xf9, 0xda, 0x0b, 0xdd, 0xe7, 0xa5, 0x2f, 0x5b, + 0xbc, 0x97, 0x53, 0x6a, 0x18, 0x89, 0xe8, 0xde, 0x58, 0x99, 0x51, 0xaa, 0x44, 0xad, 0x41, 0x23, 0x82, 0x8d, 0x5d, + 0x30, 0x50, 0x70, 0x42, 0xe5, 0x9e, 0x3a, 0xdb, 0xb7, 0x53, 0x2a, 0x3d, 0xa0, 0x5d, 0x6a, 0x54, 0xe5, 0x6e, 0x99, + 0x49, 0x56, 0x0d, 0x82, 0xd1, 0x5f, 0xa5, 0x14, 0x33, 0xbc, 0x33, 0xb2, 0x60, 0x0a, 0x56, 0x82, 0xaa, 0x96, 0x61, + 0x39, 0xe4, 0xa8, 0xc5, 0x33, 0x3e, 0xa9, 0x52, 0xff, 0xe8, 0x08, 0x1a, 0x9c, 0xae, 0x5b, 0x41, 0x83, 0x1f, 0x8f, + 0x1f, 0xeb, 0x81, 0x5e, 0xaf, 0xb5, 0xe3, 0xa1, 0xcf, 0x6f, 0x23, 0xde, 0xb8, 0xee, 0x3d, 0xd5, 0x5a, 0x85, 0x32, + 0xd0, 0x62, 0x45, 0xe5, 0x4a, 0x2d, 0xe9, 0xdd, 0x2e, 0x02, 0x60, 0x11, 0x1b, 0xb3, 0xf1, 0xae, 0x6d, 0x56, 0x08, + 0x1a, 0x5d, 0x76, 0xb4, 0x89, 0x07, 0x2c, 0xd1, 0xad, 0x1d, 0x4c, 0x68, 0x7c, 0xc4, 0xca, 0x7e, 0x3f, 0x3f, 0x02, + 0x7a, 0xaa, 0x8d, 0x98, 0x0a, 0x38, 0xf2, 0xbf, 0xb4, 0x22, 0x53, 0x14, 0xd8, 0xac, 0xa9, 0xbb, 0x35, 0x96, 0x91, + 0xe8, 0xcb, 0x94, 0x2e, 0x4f, 0x78, 0x06, 0x4c, 0xe7, 0xeb, 0x96, 0xe3, 0xca, 0xae, 0xe2, 0xc8, 0x53, 0x61, 0x59, + 0x71, 0x5e, 0x85, 0xe3, 0xad, 0xc7, 0x37, 0xd8, 0x37, 0x6c, 0xda, 0xca, 0x1f, 0x42, 0x58, 0x08, 0xaf, 0x32, 0xb8, + 0x8d, 0x68, 0x3b, 0x09, 0x54, 0xde, 0x98, 0xeb, 0x84, 0xb2, 0xb9, 0x3d, 0x5f, 0x7b, 0x06, 0xe9, 0xc4, 0x1c, 0x28, + 0xd5, 0x08, 0x5a, 0xa3, 0x59, 0x50, 0x35, 0xe2, 0x91, 0x33, 0xff, 0x72, 0x06, 0xb1, 0x5a, 0xbe, 0xa4, 0xa9, 0x14, + 0x0d, 0xc0, 0xb8, 0x00, 0x2e, 0x4f, 0x1f, 0xde, 0xfd, 0x74, 0xc2, 0xe3, 0x22, 0x59, 0xbe, 0x8d, 0x8b, 0xf8, 0xb2, + 0x0c, 0x37, 0x6a, 0x8c, 0xe2, 0x9a, 0x4c, 0xc5, 0x80, 0x49, 0xb3, 0x92, 0x9a, 0xbb, 0x52, 0x13, 0x62, 0xac, 0x33, + 0x59, 0x97, 0x95, 0xbc, 0x6c, 0x54, 0xba, 0x2e, 0x32, 0xfc, 0xb8, 0xe5, 0x73, 0xba, 0x0f, 0xc0, 0xa6, 0xc6, 0x85, + 0x34, 0x92, 0xba, 0x10, 0x63, 0x2e, 0xe2, 0x75, 0x7d, 0x3c, 0x6e, 0x74, 0xbd, 0x64, 0x4f, 0xc6, 0x8f, 0xa6, 0xaf, + 0xb2, 0x30, 0x1b, 0x08, 0x32, 0xaa, 0x96, 0x5c, 0xb4, 0x4c, 0x39, 0x95, 0x49, 0x00, 0xfa, 0x78, 0xf6, 0x18, 0x3b, + 0x18, 0x8f, 0xc9, 0xa6, 0x2d, 0x1e, 0xe0, 0x61, 0xba, 0x0e, 0x0b, 0x32, 0xd3, 0x75, 0x44, 0x81, 0xe0, 0x37, 0x55, + 0x00, 0xc8, 0x96, 0xb6, 0x2a, 0xc3, 0xa5, 0xb1, 0x27, 0xe3, 0x09, 0x95, 0xd8, 0xed, 0x90, 0xd4, 0x5e, 0x85, 0x6e, + 0xe6, 0xa5, 0xef, 0x51, 0x24, 0x8d, 0xcb, 0xd2, 0x4e, 0xa5, 0x52, 0xed, 0x99, 0x99, 0xeb, 0x1a, 0xc4, 0xa4, 0x08, + 0x75, 0xdd, 0xa5, 0x57, 0xf7, 0x6e, 0x73, 0xad, 0xd9, 0x0e, 0x78, 0xaf, 0x41, 0x33, 0x94, 0xbc, 0xc5, 0xbc, 0x75, + 0x45, 0xd4, 0xf4, 0x62, 0x0d, 0x66, 0xc5, 0x28, 0x5b, 0x8a, 0xd6, 0x6b, 0x0a, 0x4a, 0xc1, 0x68, 0xb5, 0xf6, 0x16, + 0xee, 0x53, 0xd9, 0xb8, 0xb0, 0x64, 0x7a, 0xb5, 0x28, 0x29, 0xa1, 0xba, 0xa9, 0x18, 0x29, 0x61, 0xa4, 0x34, 0x3c, + 0x95, 0xef, 0x05, 0x1e, 0xe7, 0x79, 0x10, 0xb5, 0xbc, 0xc0, 0x8e, 0x2b, 0x72, 0x0c, 0x8e, 0x5e, 0x26, 0xa7, 0xa1, + 0xc0, 0x3f, 0x66, 0x0a, 0xd4, 0x75, 0xa8, 0xee, 0x37, 0xb8, 0xf9, 0x7f, 0x2d, 0x58, 0xe0, 0xf1, 0xad, 0x97, 0xb8, + 0x8d, 0x7e, 0x2d, 0x7c, 0x5a, 0xfa, 0x46, 0xfa, 0xae, 0x2e, 0x9e, 0xb4, 0x37, 0x1b, 0x25, 0xcb, 0x2c, 0x4f, 0x5f, + 0xcb, 0x94, 0x83, 0xc8, 0x0c, 0xad, 0x41, 0xd9, 0x91, 0x68, 0xdc, 0xf0, 0xc0, 0x88, 0xb1, 0x71, 0xe3, 0xfb, 0x31, + 0x03, 0xd9, 0x30, 0x58, 0x7d, 0xb3, 0x54, 0x26, 0x6b, 0x40, 0xd8, 0xd0, 0xf2, 0x13, 0x8d, 0xb7, 0x11, 0xea, 0xeb, + 0x17, 0xb8, 0xcd, 0x95, 0xbe, 0xcf, 0xf9, 0x8f, 0x19, 0xfd, 0x11, 0x81, 0x5f, 0xe2, 0x15, 0xc8, 0x3d, 0x9e, 0x42, + 0xdd, 0x08, 0xdb, 0xcb, 0x31, 0x58, 0x12, 0xa2, 0xa3, 0x88, 0x8a, 0x05, 0x0a, 0x9a, 0xc2, 0x20, 0x8a, 0xa8, 0x0b, + 0xe6, 0xf0, 0x2c, 0x97, 0xc9, 0xc7, 0xa9, 0xf1, 0x99, 0x1f, 0xc6, 0x18, 0x43, 0x3a, 0x18, 0x84, 0xd5, 0x2c, 0x18, + 0x8e, 0x47, 0x93, 0x83, 0x27, 0x70, 0x6e, 0x07, 0xe3, 0x80, 0x0c, 0x82, 0xba, 0x5c, 0xc5, 0x82, 0x96, 0x57, 0x17, + 0xb6, 0x0c, 0xfc, 0xb8, 0x0e, 0x06, 0xbf, 0x16, 0x9e, 0xe2, 0x1d, 0x34, 0x27, 0xb7, 0x32, 0x0c, 0x02, 0x7a, 0xb1, + 0x26, 0x20, 0x29, 0xeb, 0x69, 0x7e, 0x52, 0x1f, 0x6e, 0x4c, 0x69, 0xff, 0xcc, 0xe1, 0x05, 0x87, 0x1d, 0x12, 0x28, + 0x90, 0xc6, 0xd3, 0x6c, 0xf4, 0x52, 0x29, 0x72, 0xdf, 0x16, 0x1c, 0xee, 0xcc, 0x3d, 0x67, 0x7a, 0xe4, 0x14, 0x12, + 0xcd, 0x2c, 0xe0, 0x46, 0xfe, 0x52, 0x5c, 0xc5, 0x79, 0x96, 0xee, 0x35, 0xdf, 0xec, 0x95, 0xb7, 0xa2, 0x8a, 0x6f, + 0x46, 0x81, 0xb1, 0x26, 0xe4, 0xbe, 0xea, 0x09, 0xd0, 0x13, 0x60, 0x0b, 0x80, 0x01, 0xf1, 0x8e, 0x99, 0xc9, 0x8c, + 0x47, 0xe0, 0x11, 0xd8, 0xf4, 0x81, 0x2c, 0x6e, 0x9d, 0x4b, 0x92, 0xbf, 0x99, 0x4a, 0x7b, 0xd5, 0x2b, 0x77, 0x0a, + 0xb2, 0x5e, 0x6d, 0xe5, 0xae, 0x5b, 0x9f, 0x7d, 0xd3, 0xe1, 0x15, 0x78, 0x2a, 0xc1, 0x2d, 0xb2, 0xdf, 0x6f, 0x0a, + 0x2a, 0x85, 0x51, 0x11, 0xef, 0x24, 0xd7, 0xe8, 0xdf, 0xee, 0x8d, 0x8d, 0x22, 0xb9, 0xe5, 0xfd, 0x03, 0xa8, 0x33, + 0x79, 0x57, 0xdc, 0xce, 0x21, 0x6a, 0xeb, 0x6e, 0x3c, 0xf0, 0xde, 0xa0, 0x5d, 0xd6, 0x1c, 0xc1, 0x96, 0x17, 0x7b, + 0x19, 0x8c, 0x05, 0xce, 0xca, 0x48, 0xa9, 0x71, 0xad, 0x8c, 0x06, 0xd4, 0x26, 0x77, 0x90, 0xa5, 0x9e, 0x04, 0x45, + 0x8e, 0x67, 0x31, 0x64, 0x1a, 0x6f, 0x03, 0xb1, 0xdf, 0xc8, 0x10, 0xa4, 0x69, 0xdb, 0x6d, 0x73, 0x04, 0xca, 0xee, + 0x81, 0x29, 0x49, 0x5d, 0x1b, 0x53, 0x03, 0x0d, 0x3d, 0x88, 0x1a, 0xa9, 0x88, 0xb3, 0xa3, 0xa7, 0xa0, 0x43, 0x04, + 0xdf, 0xef, 0x34, 0x2b, 0x3b, 0x5e, 0x4c, 0x08, 0x9e, 0xbc, 0xcf, 0x6f, 0xb2, 0xb2, 0x2a, 0xa3, 0x17, 0x29, 0x1a, + 0x42, 0x25, 0x52, 0x44, 0xaf, 0x21, 0xbe, 0x60, 0x89, 0xbf, 0xcb, 0xe8, 0x5d, 0x4a, 0xe3, 0x34, 0xc5, 0xf4, 0x67, + 0x05, 0xfc, 0x7c, 0x0a, 0x28, 0x97, 0xb8, 0x13, 0xa2, 0x53, 0x09, 0xf6, 0x6a, 0x10, 0xdd, 0xab, 0xe2, 0x80, 0x29, + 0x1a, 0xdd, 0x08, 0x8a, 0x98, 0x75, 0x98, 0xfd, 0x43, 0x81, 0x42, 0x21, 0x55, 0xcc, 0x2f, 0xc2, 0x3e, 0x44, 0xd5, + 0x1a, 0xca, 0x39, 0x7e, 0xfb, 0xd2, 0x0c, 0x69, 0x74, 0x23, 0xa9, 0xde, 0xda, 0x78, 0x6c, 0x21, 0x4a, 0x4f, 0x74, + 0xb9, 0xa6, 0xa7, 0xf1, 0x2a, 0x8b, 0x36, 0x80, 0x3f, 0xf1, 0xf6, 0xe5, 0x53, 0x65, 0x61, 0xf2, 0x32, 0x03, 0xc5, + 0xc1, 0xf1, 0xdb, 0x97, 0xaf, 0x64, 0xba, 0xce, 0x79, 0x74, 0x2b, 0x91, 0xb4, 0x1e, 0xbf, 0x7d, 0xf9, 0x33, 0x9a, + 0x7b, 0xbd, 0x2b, 0xe0, 0xfd, 0x0b, 0xe0, 0x2d, 0xa3, 0x64, 0x0d, 0x7d, 0x52, 0xbf, 0xf3, 0x35, 0x76, 0xca, 0xab, + 0xb5, 0x8c, 0x7e, 0x4f, 0x6b, 0x4f, 0x5a, 0xf5, 0x77, 0xe1, 0x53, 0x3b, 0x4f, 0xc0, 0x73, 0x93, 0x67, 0xe2, 0x63, + 0x64, 0x45, 0x3b, 0x41, 0xf4, 0xf5, 0xde, 0xcd, 0x65, 0x2e, 0xca, 0x08, 0x5f, 0x30, 0xb4, 0x0b, 0x8a, 0xf6, 0xf7, + 0xaf, 0xaf, 0xaf, 0x47, 0xd7, 0x8f, 0x46, 0xb2, 0xb8, 0xd8, 0x9f, 0x7c, 0xfb, 0xed, 0xb7, 0xfb, 0xf8, 0x36, 0xf8, + 0xba, 0xed, 0xf6, 0x5e, 0x11, 0x3e, 0x60, 0x01, 0x22, 0x76, 0x7f, 0x0d, 0x57, 0x14, 0xd0, 0xc2, 0x0d, 0xbe, 0x0e, + 0xbe, 0xd6, 0x87, 0xce, 0xd7, 0x87, 0xe5, 0xd5, 0x85, 0x2a, 0xbf, 0xab, 0xe4, 0x83, 0xf1, 0x78, 0xbc, 0x0f, 0x12, + 0xa8, 0xaf, 0x07, 0x7c, 0x10, 0x1c, 0x05, 0x83, 0x0c, 0x2e, 0x34, 0xe5, 0xd5, 0xc5, 0x51, 0xe0, 0x19, 0xd8, 0x36, + 0x58, 0x44, 0x07, 0xe2, 0x12, 0xec, 0x5f, 0xd0, 0xe0, 0xeb, 0x80, 0xb8, 0x94, 0xaf, 0x20, 0xe5, 0xab, 0x83, 0x27, + 0x7e, 0xda, 0xff, 0x52, 0x69, 0x8f, 0xfc, 0xb4, 0x43, 0x4c, 0x7b, 0xf4, 0xd4, 0x4f, 0x3b, 0x52, 0x69, 0xcf, 0xfd, + 0xb4, 0xff, 0x5d, 0x0e, 0x20, 0x75, 0xcf, 0xb7, 0xfe, 0x3b, 0xf5, 0x5a, 0x83, 0xa7, 0x50, 0x94, 0x5d, 0xc6, 0x17, + 0x1c, 0x1a, 0x3d, 0xb8, 0xb9, 0xcc, 0x69, 0x30, 0xc0, 0xf6, 0x7a, 0x46, 0x1e, 0xde, 0x07, 0x5f, 0xaf, 0x8b, 0x3c, + 0x0c, 0xbe, 0x1e, 0x60, 0x21, 0x83, 0xaf, 0x03, 0xf2, 0xb5, 0x3e, 0xd2, 0xae, 0x04, 0xdb, 0x04, 0x2e, 0x34, 0xeb, + 0xd0, 0x06, 0x4c, 0xf3, 0xa5, 0x71, 0x35, 0xfd, 0xad, 0xe8, 0xce, 0x86, 0xb7, 0x44, 0xe5, 0xa6, 0x1b, 0xd4, 0xf4, + 0x2d, 0x78, 0x27, 0x40, 0xa3, 0xa2, 0xe0, 0x2a, 0x2e, 0xc2, 0xe1, 0xb0, 0xbc, 0xba, 0x20, 0x60, 0x97, 0xb9, 0xe2, + 0x71, 0x15, 0x05, 0x42, 0x0e, 0xd5, 0xcf, 0x40, 0x45, 0x02, 0x0b, 0x10, 0xca, 0x08, 0xfe, 0x0b, 0x6a, 0xfa, 0x40, + 0xb2, 0x4d, 0x30, 0xbc, 0xe6, 0x67, 0x1f, 0xb3, 0x6a, 0xa8, 0x44, 0x8b, 0x57, 0x82, 0xc2, 0x0f, 0xf8, 0xeb, 0xaa, + 0x8e, 0x7e, 0x03, 0x37, 0xee, 0xa6, 0x86, 0xfd, 0x81, 0xf4, 0x1c, 0xda, 0xe4, 0x3c, 0x5b, 0x4c, 0x5b, 0x07, 0xfa, + 0x5b, 0x49, 0xaa, 0x79, 0x36, 0x08, 0x86, 0xc1, 0x80, 0x2f, 0xd8, 0x5b, 0x39, 0xe7, 0x9e, 0xf9, 0xd4, 0xb1, 0xf4, + 0xa7, 0x79, 0x96, 0x0d, 0xc0, 0x37, 0x05, 0xf9, 0x91, 0xfd, 0xff, 0x9e, 0x0f, 0x51, 0x78, 0x38, 0x78, 0xb0, 0x4f, + 0x66, 0xc1, 0xea, 0x06, 0x3d, 0x3a, 0xa3, 0x20, 0x13, 0x4b, 0x5e, 0x64, 0x95, 0xb7, 0x54, 0x6e, 0xd6, 0x6d, 0x2f, + 0x8f, 0x3b, 0xcf, 0xe6, 0x55, 0x2c, 0x02, 0x75, 0xce, 0x81, 0xe2, 0x0d, 0x65, 0x4f, 0x65, 0x53, 0x42, 0xaa, 0x0d, + 0x79, 0xc3, 0x72, 0xc0, 0x82, 0xc3, 0xde, 0x70, 0xb8, 0x17, 0x0c, 0x9c, 0x3a, 0x77, 0x10, 0xec, 0x0d, 0x87, 0x47, + 0x81, 0xbb, 0x0f, 0x65, 0x23, 0x77, 0x67, 0xa4, 0x05, 0xfb, 0xbb, 0x08, 0x4b, 0x0a, 0xe2, 0x31, 0xa9, 0xc5, 0x5f, + 0x1a, 0x5c, 0x66, 0x00, 0xd0, 0x47, 0x4a, 0x02, 0x66, 0x60, 0x65, 0x06, 0x10, 0xaa, 0x9c, 0xc6, 0xec, 0x16, 0x98, + 0x47, 0xe0, 0x98, 0x15, 0x4c, 0x16, 0x20, 0x96, 0x04, 0x38, 0x77, 0x41, 0x14, 0xeb, 0x42, 0x8e, 0x21, 0x08, 0x00, + 0xfe, 0x24, 0xa6, 0x14, 0x4c, 0xd2, 0xb1, 0x1b, 0x41, 0x10, 0xc7, 0x67, 0x57, 0xa2, 0x35, 0x39, 0x4b, 0x74, 0x30, + 0x23, 0x09, 0xb0, 0x21, 0x06, 0x86, 0x0f, 0xee, 0xe7, 0xa0, 0xf4, 0xb0, 0x7a, 0x27, 0xe4, 0x82, 0x6f, 0xb9, 0x63, + 0xa1, 0xae, 0xe0, 0xea, 0x09, 0x07, 0xc1, 0x2d, 0xd7, 0x2c, 0xc0, 0xa8, 0x2a, 0xd6, 0x65, 0xc5, 0xd3, 0xf7, 0xb7, + 0x2b, 0x88, 0x05, 0x88, 0x03, 0xfa, 0x56, 0xe6, 0x59, 0x72, 0x1b, 0x3a, 0x7b, 0xae, 0x8d, 0x4a, 0xff, 0xe1, 0xfd, + 0xab, 0x9f, 0x22, 0x10, 0x39, 0xd6, 0x86, 0xd2, 0xdf, 0x72, 0x3c, 0x9b, 0xfc, 0x88, 0x57, 0xfe, 0xc6, 0xbe, 0xe5, + 0xf6, 0xf4, 0xe8, 0xf7, 0xa1, 0x6e, 0x7a, 0xcb, 0x67, 0xb7, 0x7c, 0xe4, 0x8a, 0x43, 0x75, 0x85, 0xfb, 0xfa, 0xe3, + 0xda, 0x37, 0x42, 0xba, 0x7f, 0x9e, 0x29, 0x6f, 0xcc, 0x8f, 0x76, 0x30, 0x0c, 0x82, 0xa9, 0x16, 0x4a, 0x42, 0x14, + 0x12, 0xa6, 0x04, 0x0c, 0xd1, 0x9e, 0x5e, 0x56, 0x53, 0xe4, 0xdc, 0xd4, 0xc8, 0xc2, 0xfb, 0x01, 0xd3, 0x42, 0x87, + 0x46, 0x0e, 0xe5, 0x07, 0x87, 0x13, 0xc6, 0x2c, 0xfc, 0x56, 0x09, 0xd3, 0xaf, 0x16, 0x95, 0x73, 0x10, 0xdd, 0x03, + 0x63, 0x5c, 0xc1, 0x0b, 0xe8, 0x0a, 0xbb, 0x5e, 0xab, 0x28, 0x21, 0x08, 0xa6, 0x87, 0x1c, 0xa0, 0x87, 0x5d, 0xd0, + 0xb2, 0xb2, 0x54, 0xb7, 0x2a, 0x67, 0xa9, 0xa2, 0x2e, 0x43, 0x59, 0x19, 0x2b, 0x0c, 0xfc, 0x92, 0x7d, 0x28, 0xd0, + 0xb3, 0x7c, 0x2a, 0xba, 0xe0, 0x85, 0x50, 0x82, 0xe5, 0xba, 0xde, 0x89, 0x40, 0xd4, 0xf9, 0xa1, 0x77, 0xd5, 0xd7, + 0xb8, 0x7e, 0x3c, 0x7d, 0x25, 0x53, 0xae, 0x4d, 0x28, 0x34, 0x9f, 0x2f, 0x7d, 0xc5, 0x44, 0xc1, 0x3e, 0x42, 0xbf, + 0xda, 0x36, 0xfa, 0xec, 0x66, 0xad, 0x37, 0x83, 0x12, 0x1d, 0xf3, 0x1a, 0x05, 0xd7, 0x4a, 0xa1, 0x60, 0xb4, 0xb7, + 0xf1, 0x67, 0x38, 0x72, 0xab, 0xdb, 0x43, 0xef, 0xb7, 0x2a, 0xbe, 0x78, 0x8d, 0xbe, 0x9d, 0xf6, 0xe7, 0xa8, 0x92, + 0x1f, 0x56, 0x2b, 0xf0, 0xa1, 0x82, 0x48, 0x2b, 0x16, 0xa7, 0x17, 0xea, 0x39, 0x79, 0x7b, 0xfc, 0x1a, 0xfc, 0x28, + 0xf1, 0xf7, 0x2f, 0xdf, 0x07, 0x35, 0x99, 0xc6, 0xb3, 0xc2, 0x7c, 0x68, 0x73, 0x40, 0xa8, 0x16, 0x97, 0x66, 0xdf, + 0xcf, 0xe2, 0x26, 0xfb, 0xae, 0xd9, 0x7a, 0x5a, 0x34, 0x91, 0xa4, 0x0c, 0xb7, 0x0f, 0x06, 0x04, 0xfa, 0x00, 0x51, + 0x9c, 0x7d, 0x41, 0x63, 0x48, 0xf3, 0x99, 0x7d, 0x3f, 0x42, 0xe0, 0xcb, 0x9d, 0x90, 0x6a, 0x5c, 0x61, 0xd1, 0xe8, + 0x21, 0x9f, 0xf1, 0x48, 0x19, 0x16, 0xbd, 0xc3, 0x04, 0xe2, 0x0c, 0xa7, 0xd5, 0x7b, 0xc4, 0x80, 0xc6, 0xbb, 0x81, + 0x96, 0x3d, 0x44, 0x19, 0x75, 0xd9, 0x1b, 0x16, 0xdf, 0x27, 0xeb, 0x30, 0xb3, 0x96, 0x97, 0x43, 0xf8, 0x1b, 0x68, + 0x03, 0x70, 0xca, 0x91, 0xe5, 0xab, 0xcc, 0x46, 0x57, 0x4b, 0x4c, 0x6f, 0x22, 0x88, 0x4d, 0xa4, 0xd3, 0x61, 0xed, + 0xea, 0x54, 0xbd, 0xab, 0x9d, 0xcf, 0x44, 0xaf, 0x02, 0xad, 0x5c, 0xdb, 0x1e, 0x0f, 0xe1, 0x3f, 0xb5, 0xb4, 0xc2, + 0x46, 0xd8, 0x73, 0xf1, 0x85, 0xe7, 0xd8, 0x9c, 0x80, 0x06, 0x97, 0x32, 0x05, 0xe0, 0x2c, 0xad, 0x46, 0xa3, 0x46, + 0xd8, 0x67, 0xe5, 0x7c, 0x0e, 0x5b, 0x0b, 0xf1, 0xb4, 0x00, 0x1c, 0xb8, 0x89, 0xc9, 0xc9, 0xbb, 0x31, 0x39, 0xa7, + 0x1f, 0x15, 0xdc, 0x77, 0x70, 0x5a, 0x2e, 0xe3, 0x54, 0x5e, 0x03, 0x36, 0x65, 0xe0, 0xa7, 0x62, 0xa9, 0x5e, 0x42, + 0xb2, 0xe4, 0xc9, 0x47, 0xb4, 0xda, 0x48, 0x03, 0xe0, 0x2a, 0xa7, 0xc6, 0x72, 0x4f, 0x81, 0xa6, 0xba, 0x52, 0x54, + 0x42, 0x5c, 0x55, 0x71, 0xb2, 0x3c, 0xc1, 0xd4, 0x70, 0x03, 0xbd, 0x88, 0x02, 0xb9, 0xe2, 0x02, 0x48, 0x7a, 0xce, + 0xfe, 0xc8, 0x34, 0xf6, 0xfa, 0x1b, 0x89, 0x02, 0x26, 0x8d, 0xa2, 0x8c, 0x95, 0xb2, 0x97, 0xd2, 0x44, 0xbf, 0x0b, + 0x82, 0xda, 0xbd, 0xfc, 0x1b, 0xea, 0x7e, 0x0a, 0xad, 0x08, 0x1b, 0xe0, 0x85, 0x1a, 0xfc, 0x30, 0xb5, 0x4b, 0xce, + 0x03, 0x32, 0x74, 0xde, 0x67, 0xb5, 0xdd, 0xea, 0x4f, 0x97, 0x80, 0xf5, 0x9a, 0x1a, 0x9f, 0xc2, 0x30, 0x21, 0x26, + 0x56, 0xb2, 0x55, 0x56, 0xda, 0x0d, 0x65, 0xda, 0x49, 0x97, 0xcc, 0x6b, 0xe1, 0x34, 0xef, 0x31, 0xb6, 0x1c, 0xa9, + 0xdc, 0xfd, 0x7e, 0x68, 0x7e, 0xb2, 0x9c, 0xbe, 0xd1, 0x21, 0xac, 0xbd, 0xf1, 0xa0, 0x39, 0xd1, 0xea, 0xaa, 0x8e, + 0x7e, 0x40, 0x07, 0x60, 0xa6, 0x2d, 0x42, 0xa5, 0x0b, 0xbe, 0xed, 0x2b, 0x51, 0x71, 0x49, 0xc2, 0x52, 0x49, 0x60, + 0x67, 0x37, 0x25, 0x3b, 0x9b, 0x80, 0x78, 0x86, 0xbb, 0x9e, 0x16, 0x3b, 0x21, 0x4d, 0x78, 0x8b, 0xbd, 0x04, 0x44, + 0x1d, 0xaa, 0xba, 0x84, 0x6c, 0x8c, 0xa1, 0x8b, 0x7f, 0x51, 0x0a, 0x13, 0xd6, 0x32, 0xa9, 0x4a, 0x4c, 0x50, 0xa8, + 0x72, 0xb7, 0x45, 0x60, 0x89, 0x82, 0x1d, 0xc0, 0xde, 0xbb, 0x51, 0x37, 0xa3, 0xa6, 0xaa, 0x53, 0x2f, 0xc1, 0xc7, + 0x69, 0xd6, 0x55, 0x90, 0x59, 0xd8, 0x55, 0xb1, 0xe6, 0x81, 0x8e, 0xd5, 0xa5, 0x8c, 0x89, 0xbb, 0xb4, 0xc8, 0x10, + 0x1f, 0x19, 0x63, 0x0b, 0x6b, 0x38, 0xd2, 0xf6, 0xb8, 0xe9, 0x09, 0x42, 0x3f, 0x61, 0x43, 0x09, 0xdc, 0x74, 0xb6, + 0xa7, 0xa6, 0x99, 0x0f, 0x88, 0x38, 0x0c, 0x28, 0x90, 0x6c, 0x1c, 0xd2, 0x1c, 0xe9, 0x0b, 0x92, 0x26, 0x0c, 0x94, + 0xad, 0x78, 0x4e, 0x90, 0x15, 0x85, 0x9e, 0xad, 0xab, 0x1a, 0xe2, 0xe7, 0x32, 0xcc, 0xd1, 0x92, 0x53, 0xe1, 0x69, + 0x82, 0x4c, 0xec, 0x8e, 0xb6, 0x99, 0xc9, 0x70, 0x94, 0x2c, 0x30, 0xbf, 0x82, 0x28, 0x71, 0x67, 0x9a, 0x55, 0x39, + 0x18, 0x17, 0xb0, 0x40, 0x2b, 0xdf, 0x83, 0xba, 0xb1, 0x86, 0x36, 0x1a, 0x96, 0xd9, 0xed, 0x4f, 0xb0, 0x5f, 0x6b, + 0xa7, 0x75, 0x99, 0x62, 0x79, 0x99, 0x42, 0xb4, 0x17, 0x32, 0xbf, 0x51, 0x24, 0xba, 0x53, 0x84, 0x21, 0x61, 0x1d, + 0x65, 0x4f, 0xda, 0xd4, 0x00, 0x7a, 0xea, 0x05, 0x80, 0xef, 0x5c, 0xcb, 0xb0, 0x8b, 0x74, 0x7f, 0x55, 0x30, 0x2e, + 0xdd, 0x20, 0x48, 0xd1, 0x9b, 0x14, 0xcc, 0x79, 0x3d, 0x4a, 0xea, 0xcd, 0x69, 0xcb, 0x8c, 0xaa, 0xa3, 0x22, 0xa4, + 0x9c, 0xe0, 0x3f, 0x79, 0x29, 0x35, 0xb1, 0x09, 0x13, 0x3c, 0xf0, 0x61, 0x9e, 0x61, 0x03, 0x6f, 0xb7, 0x0f, 0xd2, + 0x30, 0x69, 0xb3, 0x0d, 0x29, 0x48, 0x2b, 0x4c, 0x9c, 0x10, 0xa8, 0xec, 0x25, 0xee, 0x17, 0x6c, 0x27, 0x4d, 0xc1, + 0x83, 0xb0, 0xd1, 0xc0, 0xc4, 0xad, 0xae, 0x6c, 0x1d, 0x26, 0x34, 0x5c, 0x52, 0xed, 0xec, 0xa4, 0x92, 0xcf, 0xdb, + 0xeb, 0xf2, 0xdc, 0xf6, 0x41, 0xc7, 0x52, 0xeb, 0x1a, 0x1e, 0x68, 0x5e, 0xb3, 0x8b, 0x2b, 0xa6, 0x69, 0xa2, 0xb1, + 0x1e, 0x52, 0x96, 0x1c, 0xeb, 0x7a, 0xba, 0xc2, 0xd5, 0x32, 0xd3, 0x40, 0xf7, 0x12, 0x2f, 0xf4, 0x80, 0x0f, 0x1e, + 0xae, 0x48, 0x74, 0x8e, 0xcd, 0x66, 0xab, 0x9a, 0x4c, 0xf3, 0xbb, 0xb2, 0xe5, 0x26, 0x40, 0x9e, 0xa5, 0xbe, 0xb9, + 0x4f, 0x8e, 0x35, 0x6d, 0xf3, 0x93, 0x00, 0xd7, 0xdc, 0x2b, 0x20, 0xe9, 0x58, 0x82, 0x2e, 0xde, 0xa7, 0x3f, 0x88, + 0xd4, 0x4c, 0x05, 0xbd, 0x73, 0xbe, 0x48, 0xdd, 0xfc, 0x02, 0x6c, 0xa3, 0x36, 0xc6, 0x34, 0x4b, 0xac, 0xc3, 0x44, + 0x59, 0x58, 0x23, 0x0b, 0xb9, 0x04, 0x1f, 0xcc, 0xdd, 0xa6, 0x4e, 0x9f, 0x77, 0x10, 0x61, 0xbf, 0x8b, 0x1e, 0x8f, + 0x30, 0x56, 0xac, 0x41, 0x62, 0x58, 0x85, 0x35, 0x6d, 0x2e, 0x87, 0x28, 0xa7, 0x66, 0xc9, 0x44, 0x4b, 0xea, 0x53, + 0x8a, 0x28, 0x05, 0x73, 0xe3, 0x69, 0xd9, 0x30, 0x25, 0x44, 0xc8, 0x0a, 0xe9, 0x80, 0x6a, 0x2d, 0xb4, 0x54, 0x13, + 0x04, 0x3c, 0xf4, 0xb2, 0xd0, 0x98, 0x82, 0xe8, 0x23, 0x32, 0xdc, 0x88, 0x23, 0xa3, 0xbb, 0x63, 0x14, 0x13, 0x08, + 0xdd, 0xed, 0xe5, 0x85, 0xd5, 0xa7, 0x65, 0x5b, 0x1d, 0xc4, 0x35, 0xa6, 0xc9, 0x1d, 0x04, 0x35, 0x46, 0x41, 0x9b, + 0xd3, 0x8d, 0xfe, 0x5e, 0x84, 0xbe, 0x5d, 0x38, 0x76, 0xa3, 0x20, 0x12, 0x22, 0xd2, 0x7a, 0x4d, 0xc5, 0x00, 0xb5, + 0xf3, 0xd8, 0x45, 0xac, 0xd2, 0xdd, 0x42, 0x94, 0x37, 0x2a, 0xeb, 0x93, 0x75, 0x48, 0xb6, 0x5b, 0x2c, 0x0b, 0x7c, + 0xd9, 0x5f, 0xad, 0xef, 0x80, 0x40, 0x7f, 0xba, 0xfe, 0x2c, 0x04, 0xfa, 0xb3, 0xec, 0x4b, 0x20, 0xd0, 0x9f, 0xae, + 0xff, 0xa7, 0x21, 0xd0, 0x5f, 0xad, 0x3d, 0x08, 0x74, 0x35, 0x18, 0xff, 0x2a, 0x58, 0xf0, 0xe6, 0x75, 0x40, 0x9f, + 0x49, 0x16, 0xbc, 0x79, 0xf1, 0xc2, 0x13, 0xa6, 0xff, 0x20, 0x34, 0x92, 0xbf, 0x91, 0x05, 0x23, 0x6e, 0x0b, 0xbc, + 0x42, 0xad, 0x93, 0x0f, 0x54, 0x94, 0x01, 0x10, 0x7d, 0xf9, 0x6b, 0x56, 0x2d, 0xc3, 0x60, 0x3f, 0x20, 0x33, 0x07, + 0x09, 0x3a, 0x9c, 0x34, 0x6e, 0x6f, 0x1f, 0x44, 0x43, 0xa8, 0x63, 0x23, 0x0f, 0xc0, 0x57, 0x9e, 0xc8, 0xde, 0xbf, + 0x21, 0xe2, 0x27, 0x33, 0x0b, 0x3a, 0xba, 0x1f, 0x10, 0xf0, 0x58, 0xca, 0x3c, 0x04, 0xce, 0xb9, 0x1f, 0x12, 0xfa, + 0xed, 0xda, 0xb3, 0x2d, 0xfa, 0x20, 0xc2, 0x0a, 0x7c, 0xee, 0xfe, 0x5e, 0xf3, 0xd3, 0x2c, 0x25, 0x4e, 0x1e, 0xca, + 0x45, 0x22, 0x53, 0xfe, 0xe1, 0xdd, 0x4b, 0x8b, 0x3c, 0x1e, 0x2a, 0xe8, 0x25, 0x82, 0x21, 0x8d, 0x53, 0x7e, 0x95, + 0x25, 0x7c, 0xf6, 0xe7, 0x83, 0x4d, 0x67, 0x46, 0xf5, 0x9a, 0xd4, 0xfb, 0x7f, 0x46, 0x41, 0xa0, 0xc7, 0xe0, 0xcf, + 0x07, 0x9b, 0xac, 0xde, 0x7f, 0xb0, 0xa9, 0x46, 0xa9, 0x04, 0x78, 0x6f, 0xf8, 0x2d, 0xeb, 0x07, 0x9b, 0x12, 0x7e, + 0xf0, 0xfa, 0x4f, 0x0f, 0x98, 0xcd, 0x36, 0xc8, 0xeb, 0x83, 0x55, 0x5e, 0x39, 0x4c, 0xd0, 0x7b, 0x0a, 0x16, 0xa6, + 0x50, 0x87, 0x47, 0xb5, 0xf6, 0xe4, 0x7e, 0x53, 0xdd, 0x75, 0x42, 0xe0, 0x1a, 0xe9, 0x06, 0x0e, 0xa1, 0xb2, 0x04, + 0x3b, 0xea, 0xe8, 0x94, 0x20, 0xa6, 0xe6, 0xfd, 0x40, 0xd9, 0xfa, 0x7a, 0xc1, 0x8a, 0x5d, 0x33, 0x31, 0xbe, 0xd3, + 0x18, 0xd8, 0x70, 0xd1, 0xd5, 0x62, 0xce, 0xfe, 0x34, 0x3d, 0xde, 0xad, 0x42, 0x12, 0xc4, 0xc8, 0xf6, 0xfb, 0xc4, + 0xeb, 0x59, 0xca, 0xab, 0x38, 0xcb, 0x59, 0x9c, 0xe7, 0x7f, 0xa2, 0x2c, 0xe2, 0xfb, 0x2f, 0x02, 0xdd, 0x1f, 0x8d, + 0x46, 0x71, 0x71, 0x81, 0x57, 0x7f, 0x43, 0x6e, 0x11, 0x16, 0x3b, 0xe3, 0xa5, 0x0d, 0xac, 0xb2, 0x8c, 0xcb, 0x53, + 0x1d, 0xd1, 0xa8, 0xb4, 0x04, 0xbb, 0x5c, 0xca, 0xeb, 0x53, 0x88, 0xee, 0x60, 0x29, 0x78, 0x8c, 0x03, 0xa8, 0xee, + 0x4d, 0x26, 0xec, 0xf2, 0x5a, 0xbf, 0x3b, 0x8b, 0x4b, 0xfe, 0x36, 0xae, 0x96, 0x0c, 0xf6, 0x82, 0xa6, 0xea, 0x85, + 0x5c, 0xaf, 0x5c, 0x25, 0xa7, 0x6b, 0xf1, 0x51, 0xc8, 0x6b, 0xa1, 0x68, 0xef, 0x29, 0xbf, 0x82, 0x16, 0xb1, 0x0d, + 0xea, 0xac, 0x04, 0x4f, 0x2a, 0x8f, 0x13, 0x57, 0xb1, 0x00, 0x32, 0x6a, 0xa2, 0x01, 0x74, 0xe4, 0xa0, 0xa1, 0xdd, + 0x6b, 0xda, 0xb1, 0xdc, 0xa8, 0x2c, 0x32, 0xb0, 0x84, 0x7d, 0x0e, 0xa5, 0x03, 0x62, 0x3b, 0x84, 0x0b, 0x81, 0xab, + 0x27, 0x5e, 0x8d, 0x1a, 0x88, 0x3d, 0xb4, 0xf4, 0xdd, 0x85, 0x14, 0xab, 0x65, 0xd0, 0x2e, 0x1b, 0xc3, 0x84, 0xd7, + 0x6b, 0x74, 0x19, 0x06, 0xc5, 0x7f, 0xe1, 0x16, 0x25, 0xe2, 0x22, 0x65, 0xa9, 0x32, 0x3a, 0xeb, 0xa1, 0x2c, 0x0c, + 0x9f, 0x3d, 0x1d, 0xa5, 0x0e, 0x2b, 0xe7, 0x99, 0xe5, 0x6d, 0x94, 0x26, 0x7e, 0x0e, 0x26, 0x61, 0x7e, 0x2d, 0x73, + 0xa9, 0xe3, 0x92, 0x9f, 0x8a, 0xf5, 0x25, 0x2f, 0xb2, 0xe4, 0x74, 0x99, 0x95, 0x95, 0x2c, 0x6e, 0x17, 0x06, 0xee, + 0x42, 0x97, 0xd5, 0x9a, 0xc4, 0x3b, 0xbf, 0x03, 0x9f, 0x77, 0x15, 0xc0, 0x64, 0xf8, 0x64, 0x4c, 0x6a, 0x6d, 0x2d, + 0x0f, 0x0d, 0xa4, 0xf6, 0xb7, 0xda, 0x27, 0xee, 0xd9, 0x76, 0x8d, 0x36, 0xfd, 0x1c, 0xda, 0x35, 0x52, 0xb3, 0x94, + 0x0a, 0xfe, 0xf7, 0x9a, 0x9b, 0x68, 0x07, 0xa1, 0x43, 0xf2, 0x0e, 0x4b, 0x7d, 0x18, 0x69, 0x12, 0xad, 0x90, 0xa0, + 0x14, 0xf5, 0x6d, 0xbd, 0x50, 0x6d, 0x20, 0x44, 0xdd, 0x16, 0xd3, 0xf4, 0x39, 0x82, 0xb6, 0x83, 0x94, 0x04, 0xf7, + 0x96, 0x8d, 0xf9, 0xd5, 0xb5, 0x7c, 0xe6, 0xd0, 0x9d, 0xc5, 0xec, 0x73, 0x19, 0x06, 0x83, 0xe8, 0x73, 0x59, 0xd8, + 0xe4, 0x9e, 0x55, 0xaa, 0xb2, 0x1c, 0x1a, 0xdb, 0xcb, 0x29, 0x9a, 0xb2, 0x84, 0x0f, 0xd6, 0x61, 0x73, 0xed, 0x53, + 0x9c, 0x7d, 0xba, 0xb9, 0xe4, 0xd5, 0x52, 0xa6, 0x51, 0xf0, 0xfd, 0xf3, 0xf7, 0x81, 0x51, 0x5d, 0x17, 0x1a, 0xb4, + 0x48, 0x6b, 0x73, 0x72, 0x79, 0x01, 0xb2, 0xcc, 0x5e, 0x31, 0x92, 0x1f, 0x77, 0xa2, 0x7c, 0xfe, 0xf9, 0xc3, 0xfb, + 0xf7, 0x6f, 0xf7, 0x50, 0xe1, 0xd3, 0xdb, 0x3b, 0x51, 0xe8, 0x01, 0x7b, 0x0f, 0x36, 0x85, 0x56, 0xb1, 0xd7, 0x7f, + 0xda, 0xb3, 0xaa, 0x68, 0x29, 0xc8, 0x0d, 0x28, 0xa0, 0x57, 0x45, 0x6b, 0x58, 0x0b, 0xa7, 0xc5, 0xf6, 0x33, 0x2b, + 0xed, 0x52, 0x80, 0xba, 0x13, 0x55, 0x73, 0xa4, 0xf4, 0xf2, 0x10, 0x69, 0x21, 0xac, 0xee, 0xd8, 0x6a, 0x55, 0xd7, + 0x56, 0x93, 0x45, 0x95, 0x89, 0x8b, 0x53, 0xdc, 0xfd, 0x5f, 0xb4, 0xe5, 0xcc, 0x0c, 0x2b, 0x7a, 0xd1, 0xde, 0x6d, + 0x0d, 0xa8, 0x32, 0x6d, 0x94, 0xab, 0xf7, 0x10, 0x08, 0xcc, 0xca, 0x7a, 0xea, 0x7f, 0x6c, 0x2c, 0x46, 0xfc, 0x34, + 0x05, 0xe4, 0x06, 0x3c, 0x10, 0x3b, 0x8a, 0x47, 0xa6, 0x7d, 0xd7, 0x28, 0x37, 0x39, 0x4c, 0x5a, 0x09, 0xb3, 0xe1, + 0x24, 0x9a, 0x10, 0x1b, 0x5f, 0x42, 0xd3, 0xb0, 0xef, 0x47, 0xcf, 0x5f, 0xbf, 0x7f, 0xf9, 0xfe, 0xf7, 0xd3, 0xa7, + 0xc7, 0xef, 0x9f, 0x7f, 0xff, 0xe6, 0xdd, 0xcb, 0xe7, 0x27, 0x78, 0x42, 0x68, 0xc0, 0xca, 0x70, 0xa3, 0xad, 0xa2, + 0x9b, 0x65, 0x45, 0xa2, 0x26, 0xcd, 0xa6, 0x28, 0xc4, 0x28, 0xcc, 0x6c, 0x8b, 0xfc, 0xf0, 0xfa, 0xd9, 0xf3, 0x17, + 0x2f, 0x5f, 0x3f, 0x7f, 0xd6, 0xfe, 0x7a, 0x38, 0xa9, 0x49, 0xed, 0x66, 0x4e, 0x47, 0x48, 0xe1, 0x76, 0xbc, 0x3a, + 0xe8, 0x13, 0x6a, 0xe5, 0x7d, 0xfa, 0x94, 0xc1, 0x8a, 0x64, 0x4a, 0x4e, 0x8f, 0xbf, 0x3d, 0xfc, 0x5f, 0xb5, 0xf1, + 0xb6, 0x5b, 0xe0, 0x21, 0x90, 0x8c, 0x29, 0x59, 0x3f, 0x8c, 0x6a, 0x46, 0xd5, 0xcb, 0x48, 0x50, 0x5b, 0x1a, 0xd8, + 0x40, 0xa7, 0x54, 0x85, 0x54, 0x38, 0x4d, 0xe2, 0x8a, 0x5f, 0xc8, 0xe2, 0x36, 0xca, 0x46, 0xad, 0x14, 0xda, 0x58, + 0x00, 0x51, 0x08, 0x82, 0xe5, 0x46, 0x12, 0xe9, 0x29, 0x02, 0xe0, 0x0d, 0x81, 0x1b, 0xd5, 0xb9, 0x8b, 0x16, 0xd0, + 0x2e, 0x98, 0x2c, 0xb6, 0xdb, 0x8e, 0x41, 0xeb, 0xa4, 0x7d, 0xd1, 0x3c, 0x53, 0x44, 0x71, 0x01, 0x8c, 0x39, 0x1c, + 0x6f, 0xea, 0xec, 0x62, 0xe6, 0xb8, 0x3b, 0xd6, 0x51, 0x3f, 0xc1, 0x1a, 0xd1, 0xbd, 0x36, 0x81, 0x65, 0x9a, 0xe7, + 0xe1, 0xb8, 0x45, 0x71, 0x0d, 0xc6, 0x6f, 0x2b, 0x55, 0x2d, 0x33, 0x8d, 0xad, 0x08, 0x33, 0x05, 0xe1, 0xb8, 0x8c, + 0xe8, 0x36, 0xcc, 0xc1, 0x42, 0xa6, 0x31, 0xbf, 0x66, 0x1c, 0xf2, 0x48, 0x1a, 0x98, 0x3c, 0x30, 0x19, 0xbc, 0x23, + 0xd7, 0x32, 0x2a, 0x1a, 0x80, 0x97, 0xb2, 0x39, 0xa8, 0x87, 0xff, 0xa7, 0xb9, 0xa7, 0xdd, 0x6e, 0xdb, 0x46, 0xf6, + 0x7f, 0x9f, 0x82, 0x61, 0xb2, 0x29, 0x99, 0x90, 0x34, 0x29, 0x59, 0xb6, 0x22, 0x59, 0x72, 0x9b, 0xaf, 0x6d, 0x5a, + 0xb7, 0xe9, 0x49, 0xdc, 0xec, 0xdd, 0xf5, 0xfa, 0x58, 0x94, 0x04, 0x49, 0xdc, 0x50, 0xa4, 0x0e, 0x49, 0xf9, 0xa3, + 0x0a, 0xf7, 0x59, 0xf6, 0x11, 0xee, 0x33, 0xf4, 0xc9, 0xee, 0x99, 0x19, 0x80, 0x04, 0xbf, 0x24, 0x79, 0x93, 0xb6, + 0xf7, 0xb4, 0x49, 0x44, 0x10, 0x00, 0x81, 0x01, 0x30, 0x33, 0x98, 0xcf, 0xa8, 0xf8, 0x0c, 0xdb, 0xb8, 0x54, 0x05, + 0x45, 0xb6, 0xc5, 0x4a, 0x20, 0x5a, 0x98, 0x9c, 0xd2, 0xe7, 0xad, 0x24, 0x3c, 0x0b, 0x6f, 0x84, 0x78, 0xf8, 0x24, + 0xaa, 0x29, 0xc4, 0xb3, 0xd1, 0x73, 0x4f, 0x26, 0xf4, 0xc3, 0x49, 0x1b, 0x88, 0x40, 0x9a, 0x03, 0x38, 0x63, 0x4e, + 0x47, 0x74, 0x65, 0xba, 0x7a, 0xb4, 0x11, 0x1b, 0x2f, 0x1d, 0x79, 0x59, 0xf2, 0xd7, 0x02, 0x63, 0x91, 0x72, 0xd0, + 0xcb, 0xb1, 0x46, 0x6b, 0xaa, 0xf1, 0xfd, 0x31, 0xf0, 0x6a, 0xb9, 0x13, 0x8b, 0x1e, 0x19, 0xe5, 0xc2, 0xac, 0xaf, + 0xc2, 0x6e, 0xd9, 0x44, 0xab, 0x1b, 0x18, 0x89, 0x97, 0xc4, 0x14, 0x30, 0xfc, 0x32, 0x62, 0xfc, 0x9f, 0x2b, 0x18, + 0x1f, 0xad, 0xec, 0x32, 0x84, 0xff, 0xf3, 0xdb, 0xf7, 0xe7, 0xa0, 0xbd, 0x72, 0x51, 0xdd, 0xbc, 0x51, 0xb9, 0xa5, + 0x8a, 0x09, 0xfa, 0x20, 0xb5, 0xa7, 0xba, 0x2b, 0xa0, 0xc7, 0x78, 0x2f, 0x38, 0xb8, 0x35, 0x6f, 0x6e, 0x6e, 0x4c, + 0xb0, 0x5b, 0x35, 0xd7, 0x91, 0x4f, 0x3c, 0xe0, 0x54, 0x4d, 0x05, 0x22, 0x67, 0x25, 0x44, 0x0e, 0x41, 0x6f, 0x79, + 0xd6, 0x94, 0xf7, 0x8b, 0xf0, 0xe6, 0x5b, 0xdf, 0x97, 0x85, 0x33, 0x82, 0x55, 0xe3, 0xf2, 0x8a, 0x02, 0x62, 0xd0, + 0x40, 0xc7, 0x64, 0x79, 0xf1, 0x15, 0xb7, 0x0a, 0x98, 0x5e, 0x8d, 0xef, 0xae, 0xb8, 0xe6, 0x21, 0x8b, 0x3a, 0xfc, + 0x62, 0x74, 0x32, 0xf5, 0xae, 0x15, 0xe4, 0x27, 0x07, 0x2a, 0xb8, 0x6c, 0xf9, 0x6c, 0xbc, 0x4e, 0x92, 0x30, 0x30, + 0xa3, 0xf0, 0x46, 0x1d, 0x9e, 0xd0, 0x83, 0xa8, 0xe0, 0xd2, 0xa3, 0xaa, 0x7c, 0x33, 0xf1, 0xbd, 0xc9, 0xc7, 0x81, + 0xfa, 0x68, 0xe3, 0x0d, 0x86, 0x25, 0xae, 0xd1, 0x4e, 0xd5, 0x21, 0x8c, 0x55, 0xf9, 0xd6, 0xf7, 0x4f, 0x0e, 0xa8, + 0xc5, 0xf0, 0xe4, 0x60, 0xea, 0x5d, 0x0f, 0xa5, 0x04, 0x30, 0x5c, 0x3b, 0x3a, 0xe0, 0x81, 0x36, 0x33, 0x7b, 0xb2, + 0x18, 0x23, 0x37, 0x4c, 0x98, 0x96, 0x5f, 0x71, 0x21, 0xa2, 0x0c, 0x8d, 0x57, 0x9b, 0xa0, 0xd0, 0xdc, 0x87, 0x0b, + 0xdd, 0xa7, 0x4f, 0x5a, 0x66, 0x6d, 0xba, 0x90, 0x42, 0xb1, 0xa1, 0x32, 0x0f, 0xab, 0x18, 0x18, 0x4f, 0x46, 0xd7, + 0x44, 0xc0, 0x38, 0x5f, 0x37, 0x26, 0xa9, 0x81, 0x79, 0x74, 0xdc, 0x15, 0xe8, 0x15, 0xf9, 0x4f, 0xe9, 0xde, 0x3b, + 0x81, 0xdc, 0xd9, 0x12, 0xe2, 0xd6, 0x25, 0xcd, 0x0a, 0x9d, 0x42, 0x1e, 0x0d, 0x10, 0x54, 0x22, 0xf8, 0x1d, 0xd2, + 0x76, 0x68, 0xbe, 0x0e, 0xb9, 0xdb, 0xb2, 0x10, 0x3c, 0x6e, 0x2a, 0xb2, 0xa5, 0x09, 0xb8, 0x9c, 0x16, 0x56, 0xa8, + 0x57, 0x5e, 0x2f, 0x11, 0x1b, 0xf2, 0x41, 0xdc, 0xb4, 0x64, 0xa0, 0xa9, 0xd3, 0x12, 0xa3, 0x44, 0x67, 0xc1, 0x77, + 0x4f, 0x52, 0x0f, 0x31, 0x43, 0xbb, 0x88, 0x8d, 0xf0, 0x32, 0xa7, 0x4d, 0x31, 0x21, 0xca, 0x5e, 0x98, 0xe6, 0x61, + 0x9a, 0x69, 0xd5, 0x87, 0x8f, 0x36, 0x01, 0x12, 0xb3, 0x78, 0x30, 0x2c, 0xee, 0x83, 0xc4, 0x1d, 0x9b, 0xb4, 0x99, + 0x55, 0xe5, 0x9b, 0xe9, 0xd8, 0xcf, 0x16, 0x9b, 0x0e, 0xc1, 0xc2, 0x0d, 0xa6, 0x3e, 0x3b, 0x77, 0xc7, 0xdf, 0x61, + 0x9d, 0x97, 0x63, 0xff, 0x05, 0x54, 0x48, 0xd5, 0xe1, 0xa3, 0x0d, 0x91, 0xeb, 0x3a, 0x84, 0x9d, 0xd2, 0x16, 0x28, + 0x7f, 0x87, 0x27, 0x56, 0x62, 0x11, 0xb5, 0xc6, 0xc1, 0x12, 0x89, 0x25, 0x8c, 0x5a, 0x1c, 0x19, 0x4f, 0xec, 0x03, + 0x7b, 0x53, 0xe1, 0xa7, 0x16, 0xc6, 0x15, 0x8a, 0x13, 0x2c, 0xef, 0x4c, 0x79, 0xb0, 0x44, 0x4a, 0xdf, 0x85, 0x37, + 0x62, 0xa4, 0x1c, 0x00, 0x14, 0x88, 0xf2, 0xf4, 0xc5, 0xe8, 0x44, 0x56, 0xfe, 0xa0, 0x84, 0x9c, 0xfa, 0x85, 0x5f, + 0xa9, 0xaa, 0xe4, 0x69, 0x9e, 0x56, 0xb7, 0xea, 0xf0, 0xe4, 0x40, 0xae, 0x3d, 0x1c, 0xf5, 0xce, 0xa4, 0xc9, 0x61, + 0xaf, 0xe2, 0x76, 0x7c, 0x91, 0x3f, 0xa4, 0x97, 0x0a, 0xdc, 0x85, 0x53, 0x28, 0x01, 0x18, 0x15, 0x9b, 0x54, 0xc8, + 0x0f, 0x24, 0x46, 0xcc, 0x09, 0x14, 0xed, 0x1e, 0x81, 0x1f, 0x43, 0xbd, 0x97, 0x2d, 0x21, 0xd9, 0x5f, 0x8a, 0xde, + 0x46, 0xfc, 0xdf, 0x1c, 0x24, 0x28, 0xcf, 0x66, 0x41, 0x1c, 0x46, 0x2a, 0x4c, 0xb3, 0x9c, 0x1d, 0x49, 0x91, 0xb2, + 0xb2, 0xe1, 0x84, 0x6b, 0xc9, 0x2a, 0x00, 0xec, 0xa0, 0xdc, 0x54, 0x9a, 0xf7, 0x48, 0xcf, 0x7f, 0x28, 0x7c, 0x32, + 0x25, 0xa4, 0x95, 0x0d, 0xb0, 0x39, 0xeb, 0xd4, 0xc5, 0x5b, 0xcf, 0xf8, 0x5b, 0x68, 0x2c, 0x5d, 0x63, 0xec, 0x1a, + 0xef, 0x83, 0xcb, 0xb4, 0x76, 0xf1, 0xb2, 0x8c, 0x71, 0x06, 0xeb, 0x6b, 0x10, 0x67, 0xa9, 0x78, 0xaf, 0xf0, 0x2c, + 0x6e, 0x19, 0x72, 0xee, 0x46, 0x73, 0x26, 0x12, 0xb5, 0x89, 0xb7, 0x42, 0x42, 0xa0, 0x4b, 0x60, 0x81, 0x20, 0x64, + 0x0f, 0xb8, 0x01, 0x9d, 0x67, 0x4d, 0x92, 0xc8, 0xff, 0x81, 0xdd, 0xc1, 0x75, 0x32, 0x4e, 0xc2, 0x15, 0x48, 0xa6, + 0xdc, 0x39, 0xd7, 0x34, 0x18, 0xc0, 0xd4, 0xec, 0xf3, 0xb9, 0x4f, 0x9f, 0x98, 0x94, 0x3b, 0x2c, 0x09, 0xe7, 0x73, + 0x9f, 0x69, 0x52, 0x8e, 0xb1, 0xec, 0x33, 0xa7, 0x0f, 0x6c, 0x11, 0x9f, 0x5a, 0x4f, 0x9b, 0x0e, 0x56, 0xce, 0x01, + 0x0a, 0x9d, 0x3e, 0x20, 0x2e, 0x32, 0xa1, 0x42, 0x26, 0x5c, 0x13, 0xe7, 0x22, 0x3f, 0xb8, 0xe6, 0x34, 0x5c, 0x8f, + 0x7d, 0x66, 0xe2, 0x69, 0x80, 0x4f, 0x6e, 0xc6, 0xeb, 0xf1, 0xd8, 0xa7, 0xa4, 0x60, 0x10, 0x65, 0x2d, 0x8c, 0x51, + 0xfa, 0x99, 0xea, 0x7d, 0xe4, 0xd4, 0x92, 0xf2, 0xf0, 0xc1, 0x32, 0x12, 0x6e, 0x0b, 0xf4, 0x81, 0x04, 0x24, 0x9d, + 0xd5, 0x33, 0x3d, 0x50, 0xe1, 0x96, 0xc2, 0x62, 0xb5, 0x5f, 0xc3, 0xd2, 0x0d, 0x2e, 0xd4, 0xf7, 0x08, 0x61, 0xc5, + 0x0d, 0xa6, 0xca, 0x0b, 0xda, 0xbb, 0xaa, 0xa1, 0x92, 0x81, 0x17, 0xcf, 0x21, 0xa7, 0x1a, 0xea, 0x4b, 0xcf, 0x9d, + 0x07, 0x61, 0x9c, 0x78, 0x13, 0xf5, 0xb2, 0xff, 0xd2, 0xd3, 0x2e, 0x96, 0x89, 0xa6, 0x5f, 0x1a, 0x7f, 0x95, 0xb3, + 0x7d, 0x09, 0x4c, 0x89, 0xc9, 0xbe, 0x1a, 0xea, 0xc8, 0xa7, 0x67, 0x5b, 0x3d, 0x81, 0x91, 0xb1, 0xce, 0x5f, 0x07, + 0x50, 0xab, 0x94, 0x37, 0x0c, 0x13, 0x42, 0x42, 0xde, 0xb0, 0xbf, 0xea, 0x7d, 0x12, 0xb5, 0x7c, 0xbb, 0xde, 0x20, + 0xd3, 0x90, 0xe4, 0xc4, 0x17, 0x43, 0xdd, 0x0b, 0xff, 0x50, 0x7a, 0x7e, 0x20, 0xfb, 0x36, 0x14, 0xc8, 0xf8, 0xe8, + 0xdb, 0x22, 0x07, 0xf2, 0x68, 0x93, 0xa4, 0x60, 0x58, 0x18, 0x84, 0x89, 0x02, 0xf1, 0xdb, 0xe0, 0x83, 0xa3, 0xb2, + 0x2d, 0x34, 0xef, 0x55, 0xd3, 0x53, 0x8e, 0x05, 0x9e, 0x23, 0x2d, 0x45, 0xf9, 0x24, 0x84, 0x9b, 0x80, 0x50, 0xa4, + 0x85, 0x68, 0x4d, 0xdc, 0x03, 0x0f, 0x96, 0xaf, 0xc0, 0xbf, 0x49, 0x78, 0xbf, 0x48, 0xcf, 0x1f, 0x6d, 0xe2, 0x53, + 0x41, 0xd4, 0xdf, 0xc4, 0xb8, 0x96, 0xc0, 0xae, 0x70, 0x2a, 0x9f, 0xaa, 0xca, 0xa9, 0xa0, 0x44, 0x58, 0xb7, 0x80, + 0x5e, 0x35, 0xc1, 0xee, 0x46, 0x22, 0x32, 0x3e, 0x4f, 0x3f, 0x2e, 0x18, 0xb0, 0xd2, 0xd1, 0x83, 0x90, 0x4c, 0x19, + 0x6f, 0x95, 0x80, 0x5d, 0x35, 0x12, 0x0c, 0xc0, 0x5c, 0x9c, 0x47, 0x18, 0xa5, 0x57, 0xc0, 0x48, 0x42, 0x9c, 0x32, + 0x31, 0x47, 0x23, 0x94, 0x53, 0xc5, 0x79, 0xc1, 0x6a, 0x9d, 0x60, 0xfc, 0x79, 0x18, 0x00, 0x4b, 0x55, 0x05, 0x2f, + 0x89, 0x80, 0xeb, 0xf3, 0xcb, 0x4f, 0xaa, 0x2a, 0xde, 0xb4, 0x5a, 0xc6, 0xe5, 0x31, 0x80, 0xe3, 0x70, 0x1a, 0xa8, + 0xbd, 0x81, 0xc7, 0x88, 0x4f, 0x63, 0x62, 0xe4, 0xc9, 0x5b, 0xb4, 0x09, 0x5a, 0x39, 0xd4, 0x20, 0x90, 0x09, 0xf5, + 0xd3, 0xd7, 0xfc, 0xda, 0xc9, 0x42, 0x4c, 0xea, 0xc2, 0x34, 0x47, 0x20, 0x89, 0x3c, 0x05, 0xd8, 0x0d, 0x1e, 0x6d, + 0xdc, 0xcc, 0x80, 0x4e, 0x3d, 0x57, 0xc9, 0x7a, 0x6e, 0x84, 0x60, 0x18, 0xa5, 0x57, 0xb9, 0x3b, 0x6b, 0x3e, 0x5f, + 0xd8, 0x92, 0x54, 0xae, 0xa0, 0x3d, 0xdb, 0x80, 0x5b, 0xad, 0xad, 0x22, 0x6f, 0xe9, 0x46, 0x77, 0x64, 0xe4, 0x66, + 0xc8, 0x96, 0x70, 0xba, 0xaa, 0x10, 0x3d, 0x20, 0x00, 0x10, 0x69, 0x50, 0x95, 0x6f, 0xb2, 0x32, 0xc6, 0x67, 0x9b, + 0x59, 0xfa, 0xc0, 0xb7, 0xae, 0xd4, 0xa7, 0xcc, 0x22, 0x29, 0x23, 0x35, 0xe9, 0x6b, 0x71, 0xc3, 0xf4, 0xe2, 0xe2, + 0xf4, 0x82, 0xe2, 0x46, 0xc3, 0xc9, 0x10, 0xa5, 0xa0, 0x71, 0xe3, 0xcc, 0x30, 0xd5, 0x65, 0xfd, 0x8a, 0xd2, 0xbb, + 0x3f, 0x74, 0x39, 0x18, 0x2c, 0x47, 0x00, 0xcb, 0x51, 0x23, 0x80, 0x75, 0xc5, 0x8a, 0x00, 0x2f, 0x02, 0x5c, 0x48, + 0x84, 0x1c, 0x08, 0x65, 0xc1, 0x54, 0xb2, 0x2d, 0x14, 0xc1, 0xd1, 0xa0, 0xb1, 0xd3, 0xd1, 0x88, 0x06, 0x83, 0x10, + 0x5b, 0x45, 0xe9, 0xc9, 0x01, 0xd5, 0x26, 0xa2, 0x48, 0x95, 0x00, 0x0c, 0x11, 0xcc, 0x30, 0x87, 0x02, 0xa4, 0x01, + 0x1f, 0x38, 0xf9, 0x45, 0xc7, 0x5a, 0xa2, 0xf2, 0xd9, 0x39, 0x2d, 0x32, 0x3c, 0xd8, 0x4a, 0x1d, 0x9e, 0x60, 0x62, + 0x4f, 0x20, 0xeb, 0x10, 0xfa, 0xea, 0xe4, 0x80, 0x1e, 0x95, 0xd2, 0x89, 0xc8, 0x3b, 0x11, 0x52, 0xc7, 0x1e, 0xef, + 0xe0, 0x5e, 0x47, 0x25, 0x4e, 0xd8, 0x0a, 0x4a, 0xdd, 0x54, 0x55, 0x96, 0x9c, 0xc1, 0xe2, 0x31, 0xf6, 0x20, 0x00, + 0x8f, 0x0d, 0x8e, 0x0f, 0xaa, 0xb2, 0x74, 0x6f, 0x71, 0xe6, 0xe2, 0x8d, 0x7b, 0xab, 0x39, 0xfc, 0x55, 0x7e, 0xd6, + 0xe2, 0xe2, 0x59, 0x9b, 0xf0, 0xc5, 0x05, 0xef, 0x3a, 0xc1, 0x58, 0x6b, 0x0b, 0xb4, 0x5a, 0xaa, 0x59, 0xdc, 0x85, + 0x58, 0xdc, 0x69, 0xc3, 0xe2, 0x4e, 0xb7, 0x2c, 0xae, 0xcf, 0x17, 0x52, 0xc9, 0x40, 0x17, 0xa1, 0xc7, 0x74, 0x06, + 0x3c, 0xce, 0x8f, 0xf4, 0xf8, 0x39, 0x43, 0x38, 0x99, 0xb1, 0x0f, 0x16, 0xc3, 0x0d, 0xb0, 0xaa, 0x83, 0x8b, 0x04, + 0x88, 0xea, 0xc4, 0xb3, 0x53, 0x37, 0x91, 0x24, 0x03, 0x9a, 0x5f, 0x9e, 0x2f, 0xec, 0x52, 0x6c, 0x68, 0x68, 0x8b, + 0x86, 0x99, 0x2e, 0xb6, 0xcc, 0x74, 0x52, 0x38, 0xba, 0x7c, 0xda, 0x74, 0x08, 0xe5, 0x49, 0xc1, 0x1e, 0x04, 0x2f, + 0x0a, 0xdc, 0x32, 0xc5, 0x7d, 0xd8, 0x8c, 0x63, 0xa5, 0x1d, 0xb5, 0x72, 0xe3, 0xf8, 0x26, 0x8c, 0xc0, 0x0c, 0x01, + 0xba, 0xb9, 0xdf, 0x96, 0x5a, 0x7a, 0x01, 0x8f, 0x70, 0xd6, 0xb8, 0x99, 0xf2, 0xf7, 0xf2, 0x96, 0x6a, 0x75, 0x3a, + 0x54, 0x63, 0xe5, 0x26, 0x09, 0x8b, 0x10, 0xe8, 0x2e, 0xa4, 0xc2, 0xf8, 0x7f, 0xb2, 0xcd, 0x6a, 0x70, 0x88, 0x2f, + 0x61, 0x75, 0xc4, 0xd0, 0x2b, 0x60, 0xc1, 0x48, 0xef, 0x18, 0xe8, 0x1b, 0x29, 0x5a, 0x6a, 0x94, 0x01, 0xfe, 0x27, + 0x3c, 0xae, 0x5a, 0x24, 0xf9, 0xf3, 0x3a, 0x47, 0xba, 0xb5, 0x72, 0xa7, 0xef, 0xc1, 0xda, 0x45, 0x6b, 0x19, 0xe0, + 0xb9, 0x22, 0xc7, 0x46, 0x8d, 0x88, 0x27, 0x9c, 0xe4, 0x48, 0x12, 0xb1, 0x24, 0xb7, 0x0b, 0x86, 0x90, 0x02, 0xae, + 0x39, 0xbb, 0xdc, 0xb4, 0xd2, 0x83, 0xb9, 0xa7, 0x57, 0xb0, 0x26, 0xa0, 0x36, 0x7f, 0x30, 0xcc, 0x84, 0x6e, 0xbe, + 0xe1, 0x1c, 0xe9, 0xa0, 0x0e, 0xbd, 0x80, 0xa4, 0xe7, 0xb6, 0xb8, 0x4c, 0x8f, 0x22, 0xa0, 0x5a, 0xa0, 0x3c, 0x7c, + 0x3c, 0xc7, 0x5f, 0xce, 0x65, 0xfa, 0x78, 0x8c, 0xbf, 0x5a, 0x97, 0x99, 0xaa, 0xaa, 0x24, 0x45, 0x90, 0xe6, 0xac, + 0x0e, 0x0b, 0xfb, 0x89, 0x8c, 0xb2, 0xef, 0xb1, 0x6d, 0xf8, 0x02, 0x3f, 0x7c, 0xb4, 0x89, 0x21, 0x0c, 0x81, 0x3c, + 0x87, 0xc0, 0x8a, 0xf4, 0xb4, 0xb6, 0x7c, 0xde, 0x50, 0x3e, 0xd6, 0xff, 0x60, 0xc2, 0x8f, 0xbb, 0x24, 0xcc, 0x69, + 0x4a, 0x51, 0x06, 0x72, 0x35, 0xf6, 0x02, 0x37, 0xba, 0xbb, 0xa2, 0x5b, 0x88, 0x26, 0x09, 0x79, 0x1f, 0xe4, 0xc2, + 0x81, 0xbb, 0xa2, 0x0d, 0x48, 0x22, 0x29, 0xa8, 0xee, 0x38, 0xa1, 0x1f, 0xfc, 0x10, 0x49, 0xfc, 0x5d, 0xe1, 0x1a, + 0xcb, 0x17, 0xa4, 0xf0, 0xa1, 0xab, 0x47, 0x1b, 0x8d, 0x55, 0xbb, 0x29, 0xcd, 0xb6, 0xc4, 0x40, 0xc2, 0xf2, 0xe0, + 0x95, 0x78, 0x39, 0xf5, 0x7a, 0x68, 0xe4, 0x31, 0x0e, 0x6f, 0xcd, 0x47, 0x9b, 0xe4, 0x54, 0x5d, 0xba, 0xd1, 0x47, + 0x36, 0x35, 0x27, 0x5e, 0x34, 0xf1, 0x81, 0x79, 0x1c, 0xfb, 0x6e, 0xf0, 0x91, 0x3f, 0x9a, 0xe1, 0x3a, 0x41, 0xb3, + 0xad, 0x9d, 0x37, 0x68, 0x01, 0x13, 0x12, 0x24, 0x22, 0x57, 0x5b, 0x03, 0x05, 0xe5, 0xc5, 0x48, 0x5c, 0xeb, 0x73, + 0x46, 0x31, 0xaf, 0x65, 0x80, 0xd7, 0x01, 0x58, 0x92, 0x41, 0x18, 0x07, 0x43, 0xc5, 0xf5, 0x52, 0x0d, 0x79, 0xaa, + 0xa4, 0x47, 0xcb, 0xf2, 0x10, 0x5f, 0x61, 0x0f, 0xff, 0xfd, 0xe7, 0xa0, 0xe4, 0x3e, 0x9f, 0xcb, 0x7a, 0xf9, 0xbc, + 0x19, 0x42, 0xa9, 0x49, 0xee, 0x83, 0xf7, 0xf8, 0x38, 0x67, 0x30, 0x9b, 0x3f, 0x2d, 0x37, 0x76, 0xe3, 0x78, 0xbd, + 0x64, 0x53, 0x52, 0x86, 0x9d, 0xe6, 0x83, 0x2a, 0xde, 0x43, 0xe4, 0x81, 0xfd, 0x73, 0xdd, 0x3a, 0x3e, 0x7c, 0x01, + 0x66, 0x7c, 0xc0, 0x50, 0x86, 0xb3, 0x99, 0x9a, 0x8b, 0x02, 0x76, 0x34, 0x73, 0x0e, 0xff, 0xb9, 0x7e, 0xfd, 0xca, + 0x7e, 0x9d, 0x35, 0x0e, 0x80, 0x31, 0x16, 0x36, 0x49, 0x9c, 0x2f, 0x96, 0xc6, 0x2b, 0x66, 0x34, 0x73, 0x83, 0xe6, + 0xe9, 0x5c, 0x14, 0xb6, 0xf8, 0x8a, 0xb1, 0x29, 0x30, 0xdc, 0x46, 0xa5, 0xf4, 0xca, 0x67, 0xd7, 0x2c, 0xb3, 0x77, + 0xaa, 0x7e, 0xac, 0xa6, 0x05, 0x06, 0x64, 0xe5, 0xba, 0x47, 0xce, 0xd5, 0x49, 0x53, 0x1a, 0xe1, 0x1c, 0xf8, 0xcc, + 0xe5, 0x23, 0x56, 0x3a, 0x52, 0x23, 0x43, 0x95, 0x06, 0xd0, 0x38, 0xb2, 0xd3, 0x86, 0xf2, 0x1e, 0x20, 0xea, 0x86, + 0xb1, 0x19, 0x8e, 0xde, 0x83, 0x04, 0x16, 0x1c, 0x4e, 0x3e, 0x9c, 0x3c, 0x2d, 0x97, 0x9a, 0x34, 0x41, 0xac, 0x4e, + 0xd4, 0xa6, 0x92, 0x90, 0x46, 0xb8, 0x00, 0xa0, 0x2f, 0x8c, 0x10, 0x57, 0xd5, 0xae, 0x8d, 0x52, 0x9c, 0xf9, 0x18, + 0xd3, 0xbb, 0x07, 0x2c, 0x8e, 0x1b, 0x01, 0x96, 0x2d, 0xba, 0xa1, 0xe6, 0xb5, 0x8b, 0xf0, 0xc8, 0xcb, 0x0d, 0xdb, + 0x00, 0x96, 0x00, 0x27, 0x58, 0xfe, 0x16, 0x92, 0x97, 0xab, 0x25, 0x37, 0xe2, 0x8c, 0xe6, 0x63, 0x95, 0x1b, 0xd8, + 0x35, 0xbd, 0xbf, 0x51, 0xf9, 0xa0, 0x0a, 0x64, 0xba, 0x76, 0x68, 0x5a, 0x01, 0xf5, 0x56, 0xa4, 0x4a, 0xd8, 0x81, + 0x18, 0x53, 0x09, 0xbf, 0xb2, 0xd9, 0x8c, 0x4d, 0x92, 0x58, 0x17, 0x32, 0xa6, 0x2c, 0xa4, 0x3a, 0x28, 0xed, 0x1e, + 0x0c, 0xd4, 0x9f, 0x20, 0xb0, 0x8c, 0x88, 0x3c, 0xc8, 0x07, 0x24, 0xee, 0x4c, 0xf5, 0x60, 0xa2, 0x1e, 0x8b, 0x20, + 0xe2, 0x5f, 0x01, 0x29, 0x74, 0x4d, 0x39, 0x0e, 0x8d, 0xd3, 0x9f, 0x7c, 0x5f, 0x84, 0x99, 0xa9, 0xe7, 0x76, 0x54, + 0xb4, 0xed, 0xf8, 0x6e, 0x9c, 0xd7, 0x1d, 0xc7, 0x4e, 0x55, 0x03, 0x1c, 0x9a, 0x3f, 0x96, 0xb6, 0x31, 0x11, 0xa8, + 0x81, 0x7a, 0xf6, 0xf6, 0xc5, 0x0f, 0xaf, 0x5e, 0xee, 0x8b, 0x11, 0xb0, 0xcb, 0x36, 0x74, 0xb9, 0x0e, 0xb6, 0x74, + 0xfa, 0xcb, 0x4f, 0xf7, 0xeb, 0xb6, 0xe5, 0x3c, 0x73, 0x54, 0x83, 0x6c, 0xd0, 0x25, 0xbc, 0x38, 0x09, 0xaf, 0x59, + 0xf4, 0xd9, 0x60, 0x90, 0x3b, 0xaf, 0x1f, 0xee, 0xdb, 0x9f, 0x5f, 0xfd, 0xb4, 0xf7, 0x50, 0x8f, 0x1c, 0x1b, 0x70, + 0x7b, 0x12, 0xae, 0xee, 0x31, 0xbb, 0xb6, 0x6a, 0xa8, 0x13, 0x3f, 0x8c, 0x59, 0xc3, 0x08, 0x5e, 0x9c, 0xbd, 0x7d, + 0x8f, 0xe0, 0xca, 0x59, 0x10, 0xea, 0xea, 0xf3, 0x26, 0xff, 0xf3, 0xbb, 0x57, 0xef, 0xdf, 0xab, 0x06, 0xa6, 0xe4, + 0x8e, 0xe5, 0xde, 0xf9, 0x26, 0xde, 0x41, 0x71, 0x6a, 0xf7, 0x3a, 0x51, 0x35, 0xba, 0x48, 0x17, 0x67, 0x43, 0x65, + 0x95, 0x6d, 0xce, 0xa9, 0x1d, 0xff, 0x32, 0xdd, 0x7e, 0xf7, 0x9a, 0x57, 0x0d, 0x3e, 0xda, 0x4e, 0x52, 0x0b, 0x25, + 0x4b, 0x2f, 0xb8, 0xaa, 0x29, 0x75, 0x6f, 0x6b, 0x4a, 0xe1, 0xfa, 0x58, 0xc1, 0x8f, 0xeb, 0x70, 0x29, 0xb1, 0x23, + 0xec, 0x76, 0x37, 0xb8, 0xa4, 0x3b, 0xdc, 0x67, 0x0c, 0x9a, 0xa7, 0x54, 0x29, 0x8f, 0xba, 0xa6, 0x98, 0x5f, 0xbc, + 0x32, 0xd8, 0x4e, 0x7c, 0xb0, 0xbc, 0x67, 0xb2, 0x1a, 0xb2, 0xc8, 0xaa, 0x72, 0xbf, 0x99, 0x41, 0xe9, 0x56, 0x40, + 0xcd, 0x48, 0x75, 0xc3, 0x69, 0xca, 0xca, 0x9d, 0x82, 0x39, 0xbb, 0x39, 0x0e, 0x93, 0x24, 0x5c, 0xf6, 0x1c, 0x7b, + 0x75, 0xab, 0x2a, 0x7d, 0x21, 0xec, 0xe0, 0xd6, 0xf6, 0xbd, 0xdf, 0xfe, 0x53, 0x42, 0xf3, 0x54, 0x7e, 0x95, 0xb0, + 0xe5, 0x8a, 0x45, 0x6e, 0xb2, 0x8e, 0x58, 0xaa, 0xfc, 0xf6, 0xbf, 0x2f, 0x4a, 0x17, 0xfb, 0xbe, 0xdc, 0x86, 0x58, + 0x7a, 0xb9, 0xc9, 0x95, 0x1f, 0xde, 0x3c, 0xc8, 0xfd, 0xea, 0x76, 0x54, 0x5e, 0x78, 0xf3, 0x45, 0x56, 0xfb, 0x34, + 0xd9, 0x32, 0x37, 0x31, 0x7a, 0xd2, 0x07, 0x28, 0x67, 0xe1, 0x4d, 0xef, 0xb7, 0xff, 0x64, 0x02, 0x9b, 0x9d, 0xbb, + 0xae, 0x7e, 0xa0, 0xc5, 0x15, 0xad, 0xaf, 0x53, 0x59, 0x62, 0x78, 0x5f, 0x59, 0xe0, 0x4a, 0x21, 0xed, 0xca, 0xaa, + 0x6e, 0x6e, 0xcb, 0x9c, 0xbe, 0xf3, 0xe6, 0x8b, 0xcf, 0x9d, 0x14, 0x00, 0x74, 0xe7, 0xac, 0xa0, 0xd2, 0x17, 0x98, + 0xd6, 0xa8, 0xb7, 0xff, 0x82, 0x7d, 0xe6, 0xbc, 0x76, 0x4d, 0xe9, 0x4b, 0xcc, 0x86, 0x4b, 0x6e, 0x5f, 0x8c, 0x46, + 0x59, 0x4a, 0x5a, 0xb9, 0x3d, 0x78, 0x06, 0x9e, 0x56, 0x4a, 0x38, 0x7b, 0xd1, 0xb3, 0x75, 0x0a, 0xd9, 0xb3, 0x07, + 0x40, 0xd0, 0xc6, 0xbd, 0x06, 0x1c, 0xcd, 0xf8, 0x9a, 0x5c, 0xd5, 0x2a, 0xdf, 0xae, 0x20, 0x6b, 0x28, 0xc5, 0x74, + 0xa6, 0x99, 0xd6, 0xd0, 0xa8, 0x1f, 0xce, 0x4d, 0xe4, 0xae, 0x48, 0x49, 0xa0, 0xa0, 0xc6, 0x04, 0x84, 0x2e, 0xa5, + 0x5b, 0xf4, 0xb5, 0xeb, 0x5f, 0xef, 0x77, 0xa1, 0x6a, 0xa6, 0x60, 0x48, 0x9a, 0xff, 0x3c, 0xe2, 0x8d, 0x74, 0x79, + 0x7f, 0xda, 0x8d, 0x69, 0xe2, 0x5e, 0x35, 0x99, 0xd6, 0xbf, 0xd9, 0x6d, 0x5a, 0x7f, 0xbe, 0x97, 0x69, 0xfd, 0x9b, + 0x2f, 0x6e, 0x5a, 0xff, 0x4a, 0x36, 0xad, 0x87, 0x4d, 0xfc, 0x8a, 0xed, 0x65, 0xc9, 0x2c, 0xac, 0x8d, 0xc2, 0x9b, + 0x78, 0xe0, 0xf0, 0x4b, 0x4f, 0x3c, 0x59, 0x30, 0x90, 0x22, 0x71, 0x70, 0xf9, 0xe1, 0x1c, 0x0c, 0x8e, 0x9b, 0x4d, + 0x8a, 0xbf, 0x94, 0x41, 0xb1, 0x1f, 0xce, 0x55, 0x29, 0x50, 0x7e, 0x20, 0x02, 0xe5, 0x43, 0x70, 0x80, 0x7f, 0xde, + 0x3a, 0xcf, 0x2f, 0x9c, 0x7e, 0xdb, 0x81, 0x40, 0x33, 0x20, 0x18, 0xc0, 0x02, 0xbb, 0xdf, 0x6e, 0x43, 0xc1, 0x8d, + 0x54, 0xd0, 0x82, 0x02, 0x4f, 0x2a, 0xe8, 0x40, 0xc1, 0x44, 0x2a, 0x38, 0x82, 0x82, 0xa9, 0x54, 0x70, 0x0c, 0x05, + 0xd7, 0x6a, 0x7a, 0x11, 0x64, 0x8e, 0x03, 0xc7, 0xfa, 0x65, 0x21, 0x47, 0x4a, 0x26, 0xc5, 0x12, 0x55, 0x8e, 0x0d, + 0x11, 0xb0, 0xd3, 0x3c, 0xd4, 0xb9, 0x89, 0xfa, 0xe8, 0xab, 0x11, 0xb8, 0xd2, 0x83, 0x50, 0xcf, 0x00, 0x91, 0x28, + 0xd5, 0x6c, 0x8b, 0xd7, 0x6a, 0x2f, 0x33, 0xb4, 0xb7, 0x8d, 0x96, 0x30, 0x5c, 0xef, 0xa1, 0x1b, 0x95, 0xa8, 0xdc, + 0x79, 0xba, 0xc8, 0xa2, 0x77, 0xad, 0x07, 0xb9, 0x37, 0x62, 0x1b, 0x62, 0x18, 0x83, 0x6a, 0xfa, 0x25, 0xf2, 0x07, + 0x56, 0x12, 0x82, 0xb3, 0x99, 0x88, 0x5a, 0x25, 0x3e, 0xa0, 0xa0, 0x37, 0x42, 0xdf, 0xcd, 0x03, 0x8c, 0xf1, 0x58, + 0x77, 0x34, 0xfa, 0x65, 0x16, 0x42, 0x8c, 0xae, 0xb9, 0x6b, 0x23, 0x71, 0xe7, 0xbd, 0x85, 0x41, 0x32, 0xee, 0xde, + 0x1c, 0x62, 0xc2, 0x9e, 0x4e, 0x7b, 0x2b, 0xe3, 0x66, 0xc1, 0x82, 0xde, 0x8c, 0x5b, 0x81, 0xc2, 0xfa, 0x93, 0x91, + 0xcf, 0x52, 0x17, 0xd6, 0x69, 0xb8, 0x27, 0xf2, 0xb7, 0x34, 0x4a, 0x33, 0xdb, 0x4a, 0xb9, 0x61, 0x95, 0x26, 0xcb, + 0xbf, 0xbf, 0x84, 0x19, 0xcc, 0x4b, 0x36, 0x5e, 0xcf, 0x95, 0xb3, 0x70, 0xbe, 0xd3, 0xe4, 0x45, 0x7e, 0x05, 0xa3, + 0x54, 0x49, 0xd1, 0x67, 0x8a, 0xed, 0xcd, 0xbf, 0x45, 0x8f, 0x69, 0xb1, 0x7e, 0x02, 0x63, 0x53, 0x12, 0x42, 0xd9, + 0xf0, 0x1d, 0x80, 0xb6, 0x64, 0x54, 0x72, 0x06, 0xf0, 0x93, 0x9e, 0xcf, 0x5d, 0x69, 0x3c, 0xc3, 0x1f, 0x59, 0x1c, + 0xbb, 0x73, 0x51, 0xbf, 0x3a, 0x4e, 0xf0, 0xaf, 0xca, 0x6e, 0xfa, 0x08, 0x40, 0x90, 0x19, 0x7b, 0x15, 0x53, 0x21, + 0xb0, 0x60, 0x06, 0x13, 0x3a, 0x58, 0xb4, 0xdc, 0xae, 0xc6, 0xb3, 0x60, 0x79, 0x8a, 0x26, 0x2e, 0x80, 0x44, 0xae, + 0x99, 0x5f, 0x2e, 0x4c, 0xdc, 0x79, 0xb9, 0x88, 0xd6, 0x3a, 0x95, 0xc7, 0x96, 0x59, 0x98, 0x14, 0x0a, 0x3f, 0xc7, + 0x64, 0xc2, 0x0f, 0xe7, 0xbf, 0xab, 0xbd, 0xc4, 0x16, 0x3b, 0x97, 0xf7, 0x81, 0x11, 0x24, 0x23, 0x0b, 0x61, 0xac, + 0x58, 0x00, 0xc2, 0x5e, 0x90, 0x2c, 0x4c, 0xf4, 0xec, 0xd7, 0x5a, 0x81, 0x6e, 0x58, 0xb8, 0xb6, 0x9b, 0x72, 0x3c, + 0x93, 0x5e, 0x34, 0x1f, 0xbb, 0x9a, 0xd3, 0x3a, 0x36, 0xc4, 0x1f, 0xcb, 0xee, 0xe8, 0x29, 0xf6, 0xa0, 0x4c, 0xbd, + 0xeb, 0xcd, 0x2c, 0x0c, 0x12, 0x73, 0xe6, 0x2e, 0x3d, 0xff, 0xae, 0xb7, 0x0c, 0x83, 0x30, 0x5e, 0xb9, 0x13, 0xd6, + 0xcf, 0x45, 0x37, 0x7d, 0x8c, 0x94, 0xc5, 0x83, 0x35, 0x38, 0x56, 0x2b, 0x62, 0x4b, 0x6a, 0x9d, 0x05, 0xc2, 0x9a, + 0xf9, 0xec, 0x36, 0xe5, 0x9f, 0x2f, 0x54, 0xa6, 0xaa, 0xb8, 0xe5, 0xa8, 0x05, 0xdc, 0x43, 0x78, 0x94, 0x2d, 0x88, + 0x2d, 0xd9, 0xe7, 0xcc, 0x7c, 0xcf, 0x6a, 0x75, 0x22, 0xb6, 0x54, 0xac, 0x4e, 0x63, 0xe7, 0x51, 0x78, 0x33, 0x84, + 0xd1, 0x62, 0x63, 0x33, 0x66, 0xfe, 0x0c, 0xdf, 0x98, 0xe8, 0xd8, 0x2b, 0xfa, 0x31, 0x51, 0xe4, 0x03, 0xbd, 0xb1, + 0x65, 0x1f, 0x5e, 0xf7, 0x5a, 0x8a, 0xdd, 0x5f, 0x7a, 0x81, 0x49, 0xd3, 0x39, 0xb6, 0x57, 0x52, 0x5f, 0x32, 0xfc, + 0xf4, 0x0d, 0x56, 0x77, 0x14, 0xbb, 0x0f, 0x57, 0xfb, 0x99, 0x1f, 0xde, 0xf4, 0x16, 0xde, 0x74, 0xca, 0x82, 0x3e, + 0x8e, 0x39, 0x2b, 0x64, 0xbe, 0xef, 0xad, 0x62, 0x2f, 0xee, 0x2f, 0xdd, 0x5b, 0xde, 0xeb, 0x61, 0x53, 0xaf, 0x6d, + 0xde, 0x6b, 0x7b, 0xef, 0x5e, 0xa5, 0x6e, 0xc0, 0x89, 0x98, 0xfa, 0xe1, 0x43, 0xeb, 0x28, 0x76, 0x69, 0x9e, 0x7b, + 0xf7, 0xba, 0x8a, 0xd8, 0x66, 0xe9, 0x46, 0x73, 0x2f, 0xe8, 0xd9, 0xa9, 0x75, 0xbd, 0xa1, 0x8d, 0xf1, 0xb0, 0xdb, + 0xed, 0xa6, 0xd6, 0x54, 0x3c, 0xd9, 0xd3, 0x69, 0x6a, 0x4d, 0xc4, 0xd3, 0x6c, 0x66, 0xdb, 0xb3, 0x59, 0x6a, 0x79, + 0xa2, 0xa0, 0xdd, 0x9a, 0x4c, 0xdb, 0xad, 0xd4, 0xba, 0x91, 0x6a, 0xa4, 0x16, 0xe3, 0x4f, 0x11, 0x9b, 0xf6, 0x71, + 0x23, 0x71, 0x73, 0xf4, 0x63, 0xdb, 0x4e, 0x11, 0x03, 0x5c, 0x14, 0x70, 0x13, 0x4a, 0x15, 0x2f, 0x37, 0x7b, 0xd7, + 0x54, 0xf2, 0xcf, 0x4d, 0x26, 0xb5, 0xf5, 0xa6, 0x6e, 0xf4, 0xf1, 0x52, 0x91, 0x66, 0xe1, 0xba, 0x54, 0x6d, 0x23, + 0xc0, 0x60, 0xde, 0xf6, 0x20, 0x62, 0x6a, 0x7f, 0x1c, 0x46, 0x70, 0x66, 0x23, 0x77, 0xea, 0xad, 0xe3, 0x9e, 0xd3, + 0x5a, 0xdd, 0x8a, 0x22, 0xbe, 0xd7, 0xf3, 0x02, 0x3c, 0x7b, 0xbd, 0x38, 0xf4, 0xbd, 0xa9, 0x28, 0x6a, 0x3a, 0x4b, + 0x4e, 0x4b, 0xef, 0x63, 0xbc, 0x20, 0x0f, 0xa3, 0x5e, 0xb9, 0xbe, 0xaf, 0x58, 0xed, 0x58, 0x61, 0x6e, 0x8c, 0x9a, + 0x0c, 0xc5, 0x8e, 0x09, 0x2e, 0x18, 0x1b, 0xc8, 0x39, 0x5c, 0xdd, 0x66, 0x7b, 0xde, 0x39, 0x5a, 0xdd, 0xa6, 0xdf, + 0x2c, 0xd9, 0xd4, 0x73, 0x15, 0x2d, 0xdf, 0x4d, 0x8e, 0x0d, 0xda, 0x0e, 0x7d, 0xd3, 0xb0, 0x4d, 0xc5, 0xb1, 0x80, + 0xc8, 0xd2, 0x0f, 0xbc, 0xe5, 0x2a, 0x8c, 0x12, 0x37, 0x48, 0xd2, 0x74, 0x74, 0x99, 0xa6, 0xfd, 0x73, 0x4f, 0xbb, + 0xf8, 0xbb, 0x46, 0xb4, 0x90, 0xb4, 0x83, 0xa9, 0x7e, 0x69, 0xbc, 0x62, 0xb2, 0x25, 0x13, 0x90, 0x31, 0xb4, 0x62, + 0x92, 0x2b, 0x13, 0xbd, 0xad, 0x56, 0x26, 0x20, 0x67, 0xd5, 0xc9, 0x30, 0xaa, 0x58, 0x05, 0x29, 0x10, 0x54, 0x78, + 0xc5, 0x06, 0xe7, 0x92, 0x59, 0x14, 0x30, 0x3d, 0x58, 0x99, 0xdc, 0x3a, 0x5f, 0x36, 0xf1, 0x9e, 0xe7, 0xbb, 0x79, + 0xcf, 0x7f, 0x24, 0xfb, 0xf0, 0x9e, 0xe7, 0x5f, 0x9c, 0xf7, 0x7c, 0x59, 0x75, 0xeb, 0x3c, 0x0f, 0x07, 0x6a, 0xa6, + 0xcb, 0x02, 0xd2, 0x14, 0x51, 0xc0, 0xc4, 0x97, 0xc9, 0x7f, 0xeb, 0x5f, 0x27, 0x7a, 0xa3, 0x14, 0xc0, 0x44, 0xb9, + 0x81, 0x81, 0x7f, 0x1b, 0x0c, 0x7e, 0x88, 0xe4, 0xe7, 0xd9, 0x6c, 0xf0, 0x32, 0x94, 0x0a, 0xb2, 0x27, 0x6e, 0xe6, + 0x53, 0x08, 0x6e, 0x45, 0x6f, 0x32, 0x43, 0x2c, 0x48, 0xff, 0x05, 0xb1, 0x71, 0xc8, 0xea, 0x7e, 0x9a, 0x99, 0x43, + 0xf6, 0x8b, 0x43, 0xd0, 0x32, 0xfb, 0x63, 0xe1, 0x01, 0x5d, 0x11, 0x5a, 0xcf, 0x59, 0xc2, 0x43, 0x96, 0x3c, 0xbf, + 0x7b, 0x33, 0xd5, 0xce, 0x43, 0x3d, 0xf5, 0xe2, 0xb7, 0x65, 0xff, 0x63, 0x71, 0x05, 0x91, 0xa7, 0x93, 0x72, 0x93, + 0x46, 0x29, 0xcc, 0x10, 0xbe, 0xa6, 0xe6, 0xa7, 0x85, 0x99, 0xf6, 0xe4, 0x86, 0x3c, 0xcf, 0x68, 0x85, 0x18, 0x73, + 0x3f, 0xbd, 0x0d, 0xe7, 0xf2, 0x30, 0x75, 0x2a, 0x86, 0x6d, 0x99, 0x52, 0x73, 0x6f, 0x9a, 0xa6, 0x7a, 0x5f, 0x00, + 0x42, 0x22, 0xb4, 0x6c, 0x17, 0x13, 0x17, 0xe7, 0x17, 0x5a, 0xae, 0x8b, 0x26, 0x45, 0xf3, 0x39, 0x98, 0x6e, 0x70, + 0xb5, 0x34, 0x87, 0x99, 0xaa, 0x10, 0xf8, 0xc8, 0xa4, 0x47, 0x9a, 0x10, 0xd8, 0x1a, 0xc8, 0x86, 0x70, 0x85, 0x05, + 0xa9, 0xda, 0x1c, 0x13, 0x70, 0xd0, 0xf6, 0x04, 0x82, 0x2c, 0x09, 0x69, 0x17, 0xa1, 0x1d, 0x5e, 0x07, 0x1f, 0x52, + 0x35, 0xe3, 0xfd, 0x70, 0xfb, 0x0d, 0x4f, 0x0e, 0xa0, 0xc1, 0xb0, 0x24, 0xc9, 0xda, 0x61, 0x32, 0x0b, 0xac, 0x44, + 0x7c, 0x63, 0x58, 0xf1, 0x8d, 0xf2, 0x64, 0x23, 0x02, 0x94, 0x25, 0xee, 0xca, 0x04, 0xf1, 0x09, 0xe2, 0x5e, 0x8e, + 0xf1, 0xa4, 0x58, 0x68, 0xfd, 0x75, 0x0c, 0xb8, 0x11, 0x6f, 0xf2, 0x88, 0x7f, 0xfa, 0x93, 0x75, 0x14, 0x87, 0x51, + 0x6f, 0x15, 0x7a, 0x41, 0xc2, 0xa2, 0x14, 0x41, 0x75, 0x81, 0xf0, 0x11, 0xe0, 0xb9, 0xdc, 0x84, 0x2b, 0x77, 0xe2, + 0x25, 0x77, 0x3d, 0x9b, 0xb3, 0x14, 0x76, 0x9f, 0x73, 0x07, 0x76, 0x6d, 0xfd, 0x1e, 0x87, 0xe6, 0x53, 0x64, 0xfc, + 0xa2, 0x2a, 0x3b, 0x23, 0x6f, 0xf3, 0xbe, 0xf4, 0x96, 0x42, 0xb4, 0x01, 0xfb, 0xe1, 0x46, 0xe6, 0x1c, 0xb0, 0x3c, + 0x2c, 0xb5, 0x3d, 0x65, 0x73, 0x03, 0xb1, 0x36, 0x68, 0x80, 0xc4, 0x1f, 0xab, 0xa3, 0x2b, 0x76, 0x7d, 0x31, 0x70, + 0x3c, 0xfa, 0x3e, 0x23, 0xeb, 0xb9, 0x90, 0xd0, 0xd4, 0xd8, 0xa7, 0xe6, 0x98, 0xcd, 0xc2, 0x88, 0x51, 0x38, 0x7f, + 0xa7, 0xbb, 0xba, 0xdd, 0xbf, 0xfb, 0xed, 0xd3, 0xaf, 0xef, 0x27, 0x08, 0x13, 0x4d, 0x74, 0xa6, 0xef, 0xe8, 0xad, + 0x4a, 0xcf, 0x80, 0x35, 0x24, 0xc8, 0x4f, 0xc8, 0x1f, 0x05, 0x5c, 0xb1, 0x6b, 0xa3, 0xa6, 0xae, 0x42, 0x4e, 0xf3, + 0x22, 0xe6, 0xbb, 0x89, 0x77, 0x2d, 0x78, 0xc6, 0xf6, 0xd1, 0xea, 0x56, 0xac, 0x31, 0x12, 0xbc, 0x7b, 0x2c, 0x52, + 0x69, 0x28, 0x62, 0x91, 0xca, 0xc5, 0xb8, 0x48, 0xfd, 0xca, 0x6c, 0x44, 0x20, 0xb1, 0x12, 0xa5, 0xef, 0xac, 0x6e, + 0x65, 0x12, 0x9d, 0x37, 0xcb, 0x28, 0x75, 0x39, 0x02, 0xec, 0xd2, 0x9b, 0x4e, 0x7d, 0x96, 0x16, 0x16, 0xba, 0xb8, + 0x96, 0x12, 0x70, 0x32, 0x38, 0xb8, 0xe3, 0x38, 0xf4, 0xd7, 0x09, 0xab, 0x07, 0x17, 0x01, 0xa7, 0x65, 0xe7, 0xc0, + 0xc1, 0xdf, 0xc5, 0xb1, 0x76, 0x80, 0xdd, 0x86, 0x6d, 0x62, 0xf7, 0x21, 0xe1, 0x83, 0xd9, 0x2e, 0x0e, 0x1d, 0x5e, + 0x65, 0x83, 0x36, 0x6a, 0x26, 0x62, 0x00, 0x59, 0x22, 0xec, 0xad, 0x58, 0x0e, 0x2f, 0xcb, 0x82, 0xde, 0x67, 0x45, + 0x69, 0x71, 0x32, 0xbf, 0xcf, 0x19, 0x7b, 0x56, 0x7f, 0xc6, 0x9e, 0x89, 0x33, 0xb6, 0x7d, 0x67, 0x3e, 0x9c, 0x39, + 0xf0, 0x5f, 0x3f, 0x9f, 0x50, 0xcf, 0x56, 0xda, 0xab, 0x5b, 0xc5, 0x59, 0xdd, 0x2a, 0x66, 0x6b, 0x75, 0xab, 0x60, + 0xd7, 0x68, 0x79, 0x64, 0x58, 0x2d, 0xdd, 0xb0, 0x15, 0x28, 0x84, 0x3f, 0x76, 0xe1, 0x95, 0x73, 0x08, 0xef, 0xa0, + 0x55, 0xa7, 0xfa, 0xae, 0xb5, 0xfd, 0xa8, 0xd3, 0x59, 0x12, 0x48, 0x5b, 0xb7, 0x12, 0x77, 0x3c, 0x66, 0xd3, 0xde, + 0x2c, 0x9c, 0xac, 0xe3, 0x7f, 0xf3, 0xf1, 0x73, 0x20, 0x6e, 0x45, 0x04, 0xa5, 0x7e, 0x44, 0x53, 0x90, 0xee, 0x5d, + 0x33, 0xd1, 0xc3, 0x26, 0x5b, 0xa7, 0x1e, 0x65, 0xa7, 0x68, 0x59, 0x87, 0x35, 0x9b, 0xbc, 0x1e, 0xd0, 0xbf, 0xdb, + 0x2a, 0x35, 0xa3, 0x98, 0xcf, 0x00, 0xcb, 0x56, 0x70, 0xdc, 0x1f, 0x1a, 0x7c, 0x35, 0xed, 0x6e, 0xfd, 0x70, 0x2f, + 0xc4, 0x97, 0x2e, 0x05, 0x51, 0xe1, 0x74, 0x8b, 0x7b, 0x49, 0x6d, 0xef, 0xb5, 0x69, 0x8f, 0x54, 0x7a, 0xdd, 0x42, + 0x10, 0xf2, 0xba, 0x7b, 0x62, 0xf9, 0x87, 0xcf, 0x0e, 0xe1, 0x3f, 0xe2, 0xea, 0xff, 0x91, 0xd4, 0x31, 0xea, 0x2f, + 0x93, 0x02, 0xa3, 0x4e, 0xac, 0x12, 0x32, 0xe2, 0xfb, 0xd7, 0x9f, 0xcd, 0xee, 0xd7, 0x60, 0xef, 0xda, 0x64, 0xb4, + 0x57, 0xae, 0xfd, 0x3c, 0x0c, 0x21, 0x73, 0x7a, 0xb5, 0xba, 0x00, 0x0f, 0x79, 0x60, 0x24, 0x03, 0x68, 0x24, 0xee, + 0x11, 0x64, 0x2f, 0xa2, 0x62, 0x1b, 0xba, 0x4a, 0x9c, 0x35, 0x5d, 0x25, 0xde, 0xed, 0xbe, 0x4a, 0x7c, 0xbf, 0xd7, + 0x55, 0xe2, 0xdd, 0x17, 0xbf, 0x4a, 0x9c, 0x55, 0xaf, 0x12, 0x67, 0xa1, 0xb0, 0xd4, 0x36, 0x5e, 0xaf, 0xf9, 0xcf, + 0x0f, 0xa4, 0x8a, 0x7d, 0x17, 0x0e, 0x3a, 0x36, 0x65, 0x9c, 0x38, 0xff, 0xaf, 0x2f, 0x16, 0xb8, 0x11, 0xdf, 0xa1, + 0xe1, 0x62, 0x7e, 0xb5, 0xe0, 0x98, 0x1d, 0xbf, 0x23, 0x15, 0xfb, 0x61, 0x30, 0xff, 0x19, 0x54, 0xf1, 0x20, 0x0e, + 0x8c, 0xa4, 0x17, 0x5e, 0xfc, 0x73, 0xb8, 0x5a, 0xaf, 0xde, 0x40, 0x5f, 0x1f, 0xbc, 0xd8, 0x1b, 0xfb, 0x2c, 0x0b, + 0xf1, 0x41, 0x86, 0x96, 0x5c, 0xb6, 0x0e, 0xb6, 0xcd, 0xe2, 0xa7, 0x7b, 0x2b, 0x7e, 0xa2, 0xf5, 0x33, 0xff, 0x4d, + 0x16, 0x9c, 0x6a, 0xfd, 0x45, 0x04, 0x42, 0x26, 0x96, 0x06, 0x7d, 0xff, 0xcb, 0xc8, 0x59, 0xa8, 0xd7, 0xcc, 0x52, + 0x58, 0xd6, 0x34, 0xf6, 0xc3, 0xca, 0xfd, 0xbc, 0x5e, 0xeb, 0x46, 0x16, 0x01, 0xb5, 0x2a, 0xce, 0x5f, 0x86, 0xeb, + 0x98, 0x4d, 0xc3, 0x9b, 0x40, 0x35, 0x02, 0x6e, 0x0e, 0x4a, 0x49, 0x24, 0xb3, 0x36, 0x98, 0xbb, 0xfb, 0x3d, 0x32, + 0xca, 0x10, 0x28, 0x01, 0x52, 0xc7, 0xaf, 0x57, 0x26, 0x19, 0x18, 0x98, 0x38, 0x45, 0x35, 0x4b, 0x32, 0xf9, 0x40, + 0xd3, 0xc2, 0xc1, 0xfd, 0x5a, 0x0a, 0xa3, 0xa0, 0xd0, 0xe2, 0x52, 0xe1, 0x58, 0x0b, 0x84, 0x70, 0x51, 0x84, 0x21, + 0xab, 0x59, 0x38, 0xfe, 0x86, 0xe2, 0x77, 0xe4, 0x6f, 0x21, 0x20, 0x44, 0xba, 0xe6, 0xeb, 0xc1, 0x83, 0x72, 0xd1, + 0xe3, 0x0b, 0x09, 0x8c, 0x6f, 0xaf, 0x59, 0xe4, 0xbb, 0x77, 0x9a, 0x9e, 0x86, 0xc1, 0x8f, 0x00, 0x80, 0x97, 0xe1, + 0x4d, 0x20, 0x57, 0xc0, 0x5c, 0x79, 0x35, 0x7b, 0xa9, 0x36, 0x7c, 0x1c, 0xb8, 0x53, 0x49, 0x23, 0xf0, 0xac, 0x95, + 0x3b, 0x67, 0xff, 0x63, 0xd0, 0xbf, 0x7f, 0xd7, 0x53, 0xe3, 0x5d, 0x98, 0x7d, 0xe8, 0x97, 0xd5, 0x1e, 0x9f, 0x79, + 0xfc, 0xf8, 0x41, 0xf3, 0xb4, 0xb5, 0x89, 0xcf, 0xdc, 0x48, 0x8c, 0xa2, 0xa6, 0xb5, 0xde, 0x78, 0x0a, 0x60, 0x14, + 0xe7, 0xe1, 0x7a, 0xb2, 0x40, 0x93, 0xea, 0x2f, 0x37, 0xdf, 0x04, 0xfa, 0xc4, 0x24, 0xf1, 0xd9, 0xd4, 0x4b, 0x45, + 0x39, 0x14, 0xf0, 0xfb, 0xaf, 0x20, 0xfe, 0xf9, 0x9f, 0x08, 0x86, 0xea, 0xae, 0xc9, 0xbc, 0xb1, 0xef, 0xb5, 0x79, + 0xfb, 0x90, 0xcb, 0x9c, 0x47, 0x16, 0x13, 0x4a, 0xba, 0x7a, 0x24, 0x93, 0x96, 0x81, 0x26, 0x47, 0xf1, 0x6d, 0x0a, + 0x50, 0x2c, 0xbe, 0xc2, 0x2c, 0xba, 0xa6, 0x73, 0x97, 0x16, 0x83, 0x71, 0x6c, 0x55, 0x42, 0x32, 0xdc, 0xd0, 0x85, + 0x21, 0xfa, 0x2a, 0xbf, 0x5b, 0x7a, 0x81, 0x81, 0x49, 0x78, 0xaa, 0x6f, 0xdc, 0x5b, 0x48, 0x43, 0x01, 0xc8, 0xad, + 0xfc, 0x0a, 0x0a, 0x0d, 0xd9, 0x91, 0x13, 0x32, 0x6d, 0xaa, 0xb5, 0x90, 0x10, 0xda, 0xc0, 0xd1, 0x57, 0x8a, 0xa2, + 0x28, 0xd9, 0x35, 0x42, 0xc9, 0xee, 0x11, 0x58, 0x8e, 0xd7, 0x01, 0xd0, 0x96, 0xa4, 0xab, 0x5b, 0x2a, 0x81, 0x9b, + 0x01, 0xaa, 0xb6, 0x45, 0x01, 0x8f, 0xb4, 0xdc, 0xb1, 0x45, 0x81, 0xb8, 0xd0, 0x43, 0x94, 0x5c, 0x37, 0x82, 0x84, + 0x0c, 0x3d, 0x05, 0x2f, 0xec, 0xf8, 0x96, 0x4b, 0x82, 0x15, 0x9b, 0x1e, 0x47, 0x7d, 0x56, 0x1f, 0x92, 0x37, 0x90, + 0xb0, 0x20, 0x68, 0x1d, 0x4a, 0x19, 0x36, 0x0c, 0x56, 0x83, 0x1b, 0xf1, 0x5e, 0x74, 0x9b, 0x2c, 0x59, 0xb0, 0x56, + 0x31, 0x25, 0x27, 0x86, 0x48, 0x86, 0x3a, 0x2f, 0x89, 0xd9, 0x02, 0x6c, 0x53, 0xdf, 0x72, 0x41, 0xb4, 0x30, 0xe6, + 0x28, 0xd5, 0x35, 0x26, 0xdc, 0x37, 0x31, 0xe6, 0xb8, 0xad, 0x4c, 0x21, 0xf8, 0x92, 0x86, 0x45, 0x6c, 0xce, 0xbd, + 0x91, 0x91, 0x53, 0xa0, 0xb0, 0x53, 0x5c, 0x5c, 0x24, 0xc0, 0xae, 0xb9, 0xe5, 0x45, 0xcb, 0x34, 0x32, 0x6e, 0x49, + 0x50, 0x14, 0xe9, 0xd5, 0x6e, 0xf8, 0x38, 0x21, 0x2e, 0x64, 0x63, 0x3f, 0x93, 0x4a, 0x3f, 0x0d, 0x93, 0xfe, 0xc8, + 0xee, 0x88, 0x90, 0x10, 0xa8, 0x3e, 0xb2, 0x3b, 0xd0, 0xdb, 0xbf, 0x02, 0x69, 0x8a, 0xba, 0x05, 0x5d, 0x1b, 0x90, + 0x69, 0x69, 0x02, 0xb1, 0x42, 0xb7, 0x1c, 0x20, 0x3b, 0xdd, 0x82, 0xc5, 0x11, 0xc4, 0x81, 0x11, 0xf7, 0xc5, 0x21, + 0xe6, 0xce, 0x24, 0x5a, 0x2d, 0x8c, 0xcd, 0x9a, 0xa3, 0xa1, 0x3f, 0x71, 0x6c, 0xfb, 0xa0, 0x52, 0x1f, 0x04, 0xd9, + 0x75, 0xb5, 0x75, 0x23, 0x19, 0x38, 0xb6, 0xe9, 0x3d, 0xb1, 0x5a, 0xfd, 0x0a, 0x8d, 0x96, 0x42, 0x79, 0x8f, 0x50, + 0xfc, 0x35, 0x7c, 0xb4, 0xd1, 0x2a, 0x07, 0x52, 0x2f, 0x3b, 0x67, 0xe0, 0xd8, 0x52, 0x2e, 0xff, 0x1a, 0x55, 0x49, + 0x3f, 0x05, 0x12, 0xa7, 0xb4, 0x72, 0x23, 0x48, 0x46, 0xa1, 0xc1, 0x31, 0xfa, 0x8b, 0xf2, 0x54, 0xd1, 0xe8, 0xf8, + 0xe8, 0xfa, 0xa8, 0x2f, 0x30, 0x8a, 0xf0, 0x5e, 0x94, 0x3b, 0x28, 0x7d, 0x31, 0x2e, 0x63, 0x38, 0x1e, 0xf6, 0x9e, + 0xe5, 0x1a, 0xbd, 0xad, 0xdc, 0x02, 0xf6, 0xdf, 0x40, 0x3e, 0xad, 0x31, 0x84, 0xdf, 0x80, 0x1a, 0x90, 0xba, 0x66, + 0x67, 0x87, 0x10, 0x2d, 0x49, 0xee, 0xae, 0x48, 0x24, 0xf7, 0xef, 0x0c, 0x89, 0x0e, 0xea, 0xd0, 0xb2, 0xfe, 0xea, + 0xc9, 0xdd, 0x3d, 0xbb, 0x64, 0xc1, 0xb4, 0xd8, 0x61, 0x89, 0x7e, 0xed, 0xdf, 0x5d, 0x01, 0xa3, 0x40, 0x4e, 0xa7, + 0xb0, 0x06, 0xa3, 0xa4, 0x61, 0x80, 0x9b, 0x9f, 0x8e, 0x9b, 0xb7, 0x17, 0x17, 0x83, 0x0d, 0x28, 0x20, 0x6b, 0xd6, + 0x4c, 0x12, 0x8a, 0x43, 0xe2, 0x10, 0x74, 0x6e, 0xd6, 0x04, 0x23, 0xda, 0xb8, 0x13, 0x13, 0x61, 0x49, 0x9a, 0xb7, + 0xf1, 0x78, 0x28, 0xf0, 0x7d, 0xa5, 0xd6, 0xde, 0x6e, 0xa9, 0x75, 0xb2, 0x4b, 0x6a, 0x4d, 0x8e, 0x7b, 0x64, 0xfe, + 0x94, 0x39, 0x30, 0x0a, 0xe6, 0x5c, 0x76, 0x01, 0x2d, 0x88, 0xba, 0xd1, 0xcf, 0x4f, 0xb4, 0xaa, 0xf4, 0x46, 0xb6, + 0xa1, 0x28, 0xfe, 0x96, 0x2e, 0x28, 0x42, 0xa1, 0x2e, 0xcb, 0xc6, 0xcf, 0x72, 0xd9, 0x38, 0xdd, 0x6a, 0x72, 0x97, + 0x2d, 0xc1, 0xfd, 0x4b, 0xee, 0x90, 0xd9, 0xed, 0x20, 0x77, 0x8b, 0xcc, 0x47, 0x2a, 0x39, 0xfa, 0xe5, 0x17, 0x0d, + 0xc9, 0x7d, 0x54, 0xdc, 0x32, 0x8a, 0x5e, 0xa4, 0xc5, 0xaa, 0xb9, 0x9f, 0x5f, 0x5e, 0x0e, 0x52, 0x77, 0x1c, 0x72, + 0x56, 0x2c, 0x6f, 0x9b, 0xa2, 0xa3, 0x97, 0xfc, 0x5a, 0xda, 0x24, 0x99, 0x47, 0x16, 0x01, 0x58, 0x88, 0xe9, 0x4b, + 0x7a, 0xed, 0xcc, 0x06, 0x02, 0x07, 0x59, 0xe3, 0x40, 0xba, 0x5b, 0x3a, 0x4f, 0xe9, 0xaa, 0x72, 0xd5, 0xb5, 0x83, + 0xd4, 0x9d, 0x34, 0xc1, 0xb2, 0x3c, 0x02, 0x61, 0x7d, 0x29, 0x49, 0x10, 0x7a, 0xb6, 0x62, 0xf7, 0x6b, 0x18, 0x00, + 0xa4, 0xff, 0xe5, 0x67, 0xce, 0x0a, 0x80, 0x24, 0x52, 0xb1, 0x65, 0x9d, 0x3f, 0x1e, 0x62, 0x93, 0xcc, 0xcf, 0xb0, + 0x6a, 0xf5, 0x9b, 0x24, 0xef, 0xd9, 0x70, 0x77, 0xad, 0xa2, 0x38, 0x9f, 0xd7, 0xe8, 0x89, 0x71, 0xf0, 0x5d, 0x16, + 0xad, 0x03, 0xcc, 0x42, 0x64, 0x26, 0x91, 0x3b, 0xf9, 0xb8, 0x91, 0xbe, 0xc7, 0x45, 0xa2, 0x20, 0x2e, 0x2e, 0x2a, + 0x15, 0xfa, 0x2e, 0x06, 0xed, 0x66, 0x3d, 0xab, 0x15, 0x4b, 0x82, 0x9a, 0xde, 0x43, 0xbb, 0xed, 0x3e, 0x9b, 0x1d, + 0x96, 0xe4, 0xa7, 0xad, 0x4e, 0x51, 0xba, 0x9e, 0x8d, 0x63, 0x19, 0xfe, 0xca, 0x1d, 0x5b, 0xff, 0xf8, 0x4f, 0xc7, + 0xfc, 0x9b, 0xa5, 0x35, 0xfa, 0x9c, 0x21, 0x40, 0xfb, 0x82, 0x62, 0x5a, 0x56, 0xd3, 0x54, 0x4a, 0x9a, 0x86, 0x35, + 0xf3, 0x7c, 0xdf, 0xf4, 0xc1, 0xbd, 0x68, 0xf3, 0x59, 0xd3, 0xc3, 0x7e, 0xd6, 0x90, 0x2e, 0xe2, 0x33, 0xfa, 0x29, + 0xee, 0x94, 0x64, 0xb1, 0x5e, 0x8e, 0x37, 0xb2, 0xa0, 0x5c, 0x92, 0x9f, 0x57, 0x65, 0xe6, 0xf2, 0x67, 0x67, 0xb3, + 0x59, 0x51, 0x6a, 0x6c, 0x2b, 0x87, 0x28, 0xf9, 0x7d, 0x68, 0xdb, 0x76, 0x19, 0xbe, 0x4d, 0x07, 0x85, 0x0e, 0x86, + 0x89, 0x42, 0xf8, 0xee, 0xee, 0x3d, 0xf5, 0x07, 0x8d, 0x96, 0xba, 0x6a, 0x3a, 0x8f, 0xb4, 0xd5, 0xfe, 0x5f, 0x0c, + 0x05, 0x51, 0xc3, 0xae, 0xe3, 0x5f, 0xdd, 0x2b, 0x5b, 0x7a, 0x2a, 0x1f, 0xe0, 0xfb, 0x35, 0xde, 0xb1, 0xd7, 0xf7, + 0x68, 0xda, 0xb4, 0xbd, 0x53, 0x2b, 0x27, 0xbb, 0x05, 0x9b, 0xa5, 0x3e, 0x59, 0x2a, 0x79, 0x09, 0x5b, 0xc6, 0xbd, + 0x09, 0x43, 0x05, 0xa9, 0x25, 0x51, 0x5b, 0xb4, 0xea, 0x31, 0xe7, 0x60, 0xc7, 0xe5, 0x08, 0x3c, 0x6c, 0x2b, 0xa8, + 0xac, 0xaa, 0x68, 0xd6, 0xc4, 0x47, 0x90, 0x8a, 0x6d, 0xaa, 0x0a, 0x27, 0xdc, 0xa6, 0x1d, 0xfb, 0x2f, 0x85, 0x7a, + 0x0a, 0x70, 0xa7, 0x1b, 0x61, 0x6d, 0x42, 0xca, 0x13, 0xfc, 0x3b, 0x53, 0xce, 0x3d, 0x5b, 0xdd, 0x16, 0x8d, 0xbb, + 0xba, 0xa0, 0x6e, 0xca, 0x49, 0x19, 0x8d, 0xba, 0x0e, 0xf5, 0x65, 0x26, 0x40, 0x33, 0xd9, 0xba, 0x05, 0x2c, 0x68, + 0x0a, 0xc9, 0x11, 0x6b, 0x74, 0x63, 0x78, 0x9d, 0x85, 0x9d, 0x97, 0xcb, 0xf7, 0xf3, 0xd4, 0xde, 0x30, 0x07, 0xe3, + 0x69, 0x17, 0x95, 0x7b, 0x85, 0xad, 0x8a, 0xa6, 0x32, 0xb8, 0x07, 0xc4, 0x8d, 0x54, 0x59, 0x47, 0xbe, 0x49, 0x99, + 0x03, 0x35, 0x7d, 0x53, 0x9d, 0x77, 0x73, 0xf7, 0x4e, 0x07, 0xf4, 0x1a, 0x55, 0x50, 0xed, 0xa5, 0xda, 0x2b, 0xeb, + 0xb0, 0xc5, 0x38, 0x61, 0x05, 0xc0, 0x15, 0x45, 0x41, 0xa3, 0x21, 0xa5, 0x84, 0xfb, 0x68, 0xd2, 0xd9, 0x5b, 0x19, + 0x59, 0x8b, 0x79, 0x62, 0x77, 0xf5, 0x55, 0xa8, 0x6f, 0xa1, 0x19, 0x04, 0xd8, 0x71, 0xec, 0x84, 0xcf, 0x26, 0xec, + 0x18, 0x19, 0x5d, 0x39, 0xb8, 0x83, 0xf0, 0x94, 0x9a, 0x14, 0x91, 0x96, 0x4e, 0x29, 0xea, 0x12, 0xbe, 0xaf, 0x15, + 0xde, 0x9f, 0x17, 0xa4, 0xf1, 0xdc, 0x1f, 0xa8, 0xa5, 0xef, 0x55, 0x7b, 0xe9, 0x05, 0xfb, 0xd7, 0x75, 0x6f, 0xf7, + 0xae, 0x0b, 0xcc, 0xe1, 0xde, 0x95, 0x81, 0xbb, 0x24, 0x2b, 0xa5, 0x64, 0xf0, 0xbd, 0xa4, 0x3c, 0x90, 0x63, 0x59, + 0xa8, 0xd8, 0x8a, 0x6e, 0xf4, 0x3f, 0xad, 0x07, 0xa3, 0x93, 0xd3, 0xdb, 0xa5, 0xaf, 0x5c, 0xb3, 0x08, 0xb2, 0xa8, + 0x0e, 0x54, 0xc7, 0xb2, 0x55, 0x05, 0x23, 0x33, 0x78, 0xc1, 0x7c, 0xa0, 0xfe, 0x72, 0xfe, 0xda, 0xec, 0xaa, 0xa7, + 0x60, 0x8e, 0x71, 0x3d, 0x47, 0x16, 0xf7, 0xcc, 0xbd, 0x63, 0xd1, 0x55, 0x4b, 0x55, 0x30, 0x59, 0x2a, 0x31, 0xb7, + 0x58, 0xa6, 0xb4, 0xd4, 0x3d, 0x72, 0xf2, 0x29, 0x22, 0xad, 0xb6, 0x0a, 0x88, 0xd5, 0x69, 0x75, 0x15, 0xa7, 0x75, + 0x68, 0x1d, 0x75, 0xd5, 0xe1, 0x57, 0x8a, 0x72, 0x32, 0x65, 0xb3, 0x78, 0x88, 0xe2, 0x98, 0x13, 0xe4, 0x07, 0xe9, + 0xb7, 0xa2, 0x58, 0x13, 0x3f, 0x36, 0x1d, 0x65, 0xc3, 0x1f, 0x15, 0x05, 0x90, 0x51, 0x4f, 0x79, 0x38, 0x6b, 0xcd, + 0x0e, 0x67, 0xcf, 0xfa, 0xbc, 0x38, 0xfd, 0xaa, 0x50, 0xdd, 0xa0, 0x7f, 0x5b, 0x52, 0xb3, 0x38, 0x89, 0xc2, 0x8f, + 0x8c, 0xf3, 0x92, 0x4a, 0x26, 0x28, 0x2a, 0x37, 0x6d, 0x55, 0xbf, 0xe4, 0x74, 0xc7, 0x93, 0x59, 0x2b, 0xaf, 0x8e, + 0x63, 0x3c, 0xc8, 0x06, 0x79, 0x72, 0x20, 0x86, 0x7e, 0x22, 0x83, 0xc9, 0x31, 0xeb, 0x00, 0xe5, 0xa8, 0x7c, 0x8e, + 0x73, 0x31, 0xbf, 0x13, 0x08, 0x79, 0x9f, 0x7b, 0x70, 0xc4, 0xd8, 0x6c, 0xa0, 0xfe, 0xe8, 0xb4, 0xba, 0x86, 0xe3, + 0x1c, 0x59, 0x47, 0xdd, 0x89, 0x6d, 0x1c, 0x5a, 0x87, 0x66, 0xdb, 0x3a, 0x32, 0xba, 0x66, 0xd7, 0xe8, 0x7e, 0xd7, + 0x9d, 0x98, 0x87, 0xd6, 0xa1, 0x61, 0x9b, 0x5d, 0x28, 0x34, 0xbb, 0x66, 0xf7, 0xda, 0x3c, 0xec, 0x4e, 0x6c, 0x2c, + 0x6d, 0x59, 0x9d, 0x8e, 0xe9, 0xd8, 0x56, 0xa7, 0x63, 0x74, 0xac, 0xa3, 0x23, 0xd3, 0x69, 0x5b, 0x47, 0x47, 0x67, + 0x9d, 0xae, 0xd5, 0x86, 0x77, 0xed, 0xf6, 0xa4, 0x6d, 0x39, 0x8e, 0x09, 0x7f, 0x19, 0x5d, 0xab, 0x45, 0x3f, 0x1c, + 0xc7, 0x6a, 0x3b, 0x86, 0xed, 0x77, 0x5a, 0xd6, 0xd1, 0x33, 0x03, 0xff, 0xc6, 0x6a, 0x06, 0xfe, 0x05, 0xdd, 0x18, + 0xcf, 0xac, 0xd6, 0x11, 0xfd, 0xc2, 0x0e, 0xaf, 0x0f, 0xbb, 0xff, 0x50, 0x0f, 0x1a, 0xe7, 0xe0, 0xd0, 0x1c, 0xba, + 0x1d, 0xab, 0xdd, 0x36, 0x0e, 0x1d, 0xab, 0xdb, 0x5e, 0x98, 0x87, 0x2d, 0xeb, 0xe8, 0x78, 0x62, 0x3a, 0xd6, 0xf1, + 0xb1, 0x61, 0x9b, 0x6d, 0xab, 0x65, 0x38, 0xd6, 0x61, 0x1b, 0x7f, 0xb4, 0xad, 0xd6, 0xf5, 0xf1, 0x33, 0xeb, 0xa8, + 0xb3, 0x38, 0xb2, 0x0e, 0x3f, 0x1c, 0x76, 0xad, 0x56, 0x7b, 0xd1, 0x3e, 0xb2, 0x5a, 0xc7, 0xd7, 0x47, 0xd6, 0xe1, + 0xc2, 0x6c, 0x1d, 0x6d, 0x6d, 0xe9, 0xb4, 0x2c, 0x80, 0x11, 0xbe, 0x86, 0x17, 0x06, 0x7f, 0x01, 0x7f, 0x16, 0xd8, + 0xf6, 0x0f, 0xec, 0x26, 0xae, 0x36, 0x7d, 0x66, 0x75, 0x8f, 0x27, 0x54, 0x1d, 0x0a, 0x4c, 0x51, 0x03, 0x9a, 0x5c, + 0x9b, 0xf4, 0x59, 0xec, 0xce, 0x14, 0x1d, 0x89, 0x3f, 0xfc, 0x63, 0xd7, 0x26, 0x7c, 0x98, 0xbe, 0xfb, 0xa7, 0xf6, + 0x93, 0x2d, 0xf9, 0xc9, 0xc1, 0x9c, 0xb6, 0xfe, 0x7c, 0xf8, 0x15, 0xe5, 0xd7, 0x1c, 0x19, 0xbf, 0x36, 0x29, 0x25, + 0xff, 0xb5, 0x5b, 0x29, 0xf9, 0x7c, 0xbd, 0x8f, 0x52, 0xf2, 0x5f, 0x5f, 0x5c, 0x29, 0xf9, 0x6b, 0xd9, 0xb7, 0xe6, + 0x75, 0x39, 0x0d, 0xd8, 0xf7, 0x9b, 0xb2, 0xc8, 0x21, 0x70, 0xb5, 0x8b, 0x9f, 0xd6, 0x97, 0x10, 0xda, 0xef, 0x75, + 0x38, 0x78, 0xbe, 0x2e, 0x18, 0x7c, 0x86, 0x80, 0x63, 0x5f, 0x87, 0x84, 0x63, 0x3f, 0xac, 0x07, 0x60, 0x65, 0xc6, + 0xd9, 0x1c, 0x6f, 0x6a, 0x2e, 0x5c, 0x7f, 0x96, 0xb1, 0x48, 0x50, 0xd2, 0xc7, 0x62, 0x70, 0x5c, 0x03, 0xf2, 0x0c, + 0x37, 0x99, 0xf5, 0x32, 0x88, 0xc1, 0x22, 0x18, 0x2c, 0x39, 0x66, 0x51, 0x5a, 0x6a, 0x6c, 0x89, 0x60, 0x88, 0x57, + 0xdc, 0x0b, 0xaa, 0xf1, 0x3d, 0x1a, 0x00, 0xd7, 0xf7, 0xee, 0x54, 0xfb, 0x55, 0xc0, 0xb2, 0x4e, 0x18, 0x48, 0x03, + 0xb7, 0x5f, 0xf7, 0xbe, 0x68, 0x86, 0x5b, 0x32, 0xbc, 0x6e, 0x1e, 0x29, 0x8c, 0xa4, 0xdc, 0xde, 0x29, 0x9a, 0xf1, + 0xee, 0x9a, 0x66, 0xcd, 0xe7, 0x0b, 0xcd, 0xb7, 0xd8, 0x10, 0x67, 0x1d, 0x97, 0x41, 0x55, 0x4a, 0x62, 0x5d, 0x0b, + 0x90, 0xfc, 0x82, 0x9a, 0x1b, 0x1a, 0xe7, 0x9c, 0xaa, 0xad, 0x20, 0xbf, 0x63, 0x4b, 0xef, 0x0a, 0x7d, 0xca, 0xc6, + 0xc9, 0x4f, 0x36, 0x78, 0xaf, 0xf0, 0x7e, 0x05, 0x4e, 0x94, 0x73, 0x3c, 0xe3, 0x50, 0x86, 0xf3, 0x46, 0xea, 0x97, + 0xa4, 0x11, 0xe9, 0xc2, 0xd9, 0x54, 0x79, 0xd1, 0x46, 0xb7, 0x04, 0x87, 0x2d, 0x05, 0x17, 0x84, 0x9f, 0x27, 0x27, + 0x80, 0x94, 0x1c, 0x35, 0xd0, 0xcf, 0x61, 0x5b, 0x67, 0xa2, 0xde, 0x43, 0xd8, 0xc4, 0x3c, 0x26, 0xb3, 0x22, 0x47, + 0x9b, 0xd9, 0xcc, 0xfc, 0xd0, 0x4d, 0x7a, 0xc8, 0xa6, 0x49, 0x2c, 0x6f, 0x0b, 0x3d, 0x16, 0xfa, 0x5b, 0x8c, 0xe9, + 0xe4, 0x8e, 0x79, 0x27, 0xe8, 0xf9, 0xb0, 0xcd, 0xfe, 0x2e, 0x73, 0x38, 0xdb, 0x14, 0xcc, 0x51, 0x9c, 0xce, 0xb1, + 0xe1, 0x1c, 0x19, 0xd6, 0x71, 0x47, 0x4f, 0xc5, 0x81, 0x93, 0xbb, 0x2c, 0x00, 0x04, 0x1c, 0x20, 0xb2, 0x61, 0x7a, + 0x81, 0x97, 0x78, 0xae, 0x9f, 0x02, 0x3f, 0x5c, 0xbc, 0xa4, 0xfc, 0x6b, 0x1d, 0x27, 0x30, 0x47, 0xc1, 0xf4, 0xa2, + 0xf3, 0x87, 0x39, 0x66, 0xc9, 0x0d, 0x63, 0x41, 0x83, 0x61, 0x4c, 0xd9, 0x97, 0xe4, 0xf7, 0xb3, 0xac, 0x4f, 0xc9, + 0x6a, 0x6d, 0x9c, 0x04, 0x7c, 0x7f, 0x08, 0xc7, 0x87, 0x74, 0x64, 0x7c, 0xd7, 0x84, 0x70, 0x7f, 0xd9, 0x8d, 0x70, + 0x13, 0xb6, 0x0f, 0xc2, 0xfd, 0xe5, 0x8b, 0x23, 0xdc, 0xef, 0x64, 0x84, 0x5b, 0xf0, 0x1f, 0xcc, 0x35, 0x4c, 0xef, + 0xf1, 0x59, 0x83, 0xcc, 0x28, 0x4f, 0xd5, 0x03, 0x62, 0xe0, 0x55, 0x3d, 0x4f, 0x1f, 0xf4, 0xb7, 0x42, 0xa2, 0x56, + 0x14, 0x80, 0x62, 0xd6, 0x0d, 0x4a, 0x0a, 0xe9, 0x81, 0xab, 0x5b, 0x96, 0x18, 0x92, 0xdd, 0x28, 0x6f, 0x82, 0xc4, + 0xb7, 0xde, 0xf1, 0x7b, 0x24, 0x28, 0x74, 0x5f, 0x87, 0xd1, 0xd2, 0xc5, 0xe8, 0xaf, 0x2a, 0x26, 0x78, 0x87, 0x07, + 0x1b, 0x9c, 0x71, 0x27, 0x61, 0x30, 0xcd, 0xb4, 0x92, 0x6c, 0x70, 0x41, 0x1c, 0xb7, 0x7a, 0xc7, 0xdc, 0x48, 0x35, + 0xe8, 0x35, 0x2c, 0xee, 0x93, 0xb6, 0xfd, 0xa4, 0x75, 0xf8, 0xe4, 0xc8, 0x86, 0xff, 0x1d, 0xd6, 0x4e, 0x0d, 0x5e, + 0x71, 0x19, 0x06, 0x90, 0x63, 0x52, 0xd4, 0x6c, 0xaa, 0x76, 0xc3, 0xd8, 0xc7, 0xbc, 0xd6, 0x71, 0x7d, 0xa5, 0xa9, + 0x7b, 0x97, 0xd7, 0xa9, 0xad, 0xb1, 0x08, 0xd7, 0xd2, 0xb0, 0x6a, 0x46, 0xe3, 0x05, 0x6b, 0x90, 0xb3, 0x4b, 0x35, + 0xe4, 0xd7, 0x7c, 0xba, 0xf9, 0xbc, 0x58, 0x3b, 0xbd, 0xcc, 0x13, 0xd9, 0x8a, 0x7c, 0x46, 0x3b, 0x21, 0xc8, 0x55, + 0x94, 0x36, 0x86, 0x03, 0xc7, 0x44, 0x13, 0x10, 0x0c, 0x3c, 0x4b, 0x3f, 0xea, 0xd2, 0x02, 0x25, 0xd1, 0x3a, 0x98, + 0x68, 0xf8, 0xd3, 0x1d, 0xc7, 0x9a, 0x77, 0x10, 0x59, 0xfc, 0xc3, 0x3a, 0xae, 0x9a, 0x3b, 0xb4, 0xf3, 0xac, 0x7f, + 0xb1, 0x58, 0x15, 0xf7, 0x49, 0x62, 0x44, 0xa8, 0xc7, 0xa6, 0xa5, 0x35, 0x07, 0xee, 0x93, 0xac, 0xe1, 0x93, 0xc4, + 0x08, 0x9e, 0x82, 0xee, 0x73, 0x60, 0x3f, 0x7e, 0x4c, 0xb5, 0x1e, 0x0c, 0xc4, 0xb4, 0x4e, 0x27, 0x79, 0xd0, 0x50, + 0xc5, 0x9d, 0x87, 0x14, 0x37, 0xb4, 0x37, 0x31, 0xc2, 0xa7, 0x4f, 0x87, 0x03, 0x47, 0xc7, 0x8c, 0xb2, 0x22, 0x33, + 0x3c, 0x4f, 0x56, 0x7c, 0xb6, 0x9f, 0xa1, 0x91, 0x5e, 0xeb, 0x4a, 0xbb, 0x82, 0x3b, 0x93, 0x2d, 0xdc, 0x11, 0x38, + 0xf6, 0x82, 0xe4, 0x81, 0x64, 0x50, 0xe0, 0x0a, 0x83, 0x1f, 0x51, 0x27, 0xbb, 0x75, 0xb5, 0x2d, 0xdb, 0xb2, 0xd5, + 0xac, 0xe1, 0xcc, 0x9b, 0x0f, 0x36, 0x61, 0xe2, 0x42, 0x1a, 0x56, 0x3f, 0x9c, 0x83, 0x1f, 0x5d, 0xe2, 0x25, 0x3e, + 0xe4, 0xf4, 0x04, 0x87, 0xba, 0x25, 0xdd, 0xcb, 0x53, 0xee, 0xdd, 0xe0, 0x46, 0x1f, 0x31, 0xaf, 0xbb, 0x70, 0xc5, + 0xc5, 0x38, 0x76, 0x3f, 0x02, 0x31, 0xd4, 0x54, 0x0d, 0x64, 0x03, 0x2c, 0x8a, 0x4d, 0xd9, 0x5b, 0xa8, 0xa7, 0x40, + 0x1b, 0x5d, 0xe5, 0x93, 0x98, 0x45, 0xee, 0x12, 0x12, 0x1b, 0x6d, 0x52, 0x83, 0x63, 0x5a, 0x95, 0xa3, 0x5a, 0xc5, + 0x79, 0x76, 0x64, 0x28, 0x2d, 0xc7, 0x50, 0x6c, 0x40, 0xb7, 0x6a, 0x6a, 0x6c, 0xd2, 0xcb, 0xfe, 0x2e, 0x83, 0x07, + 0xc2, 0x2f, 0x0f, 0x69, 0x1e, 0x64, 0xea, 0xc0, 0x55, 0x49, 0x09, 0xc5, 0x2f, 0xd6, 0xa4, 0x84, 0x26, 0x1e, 0x29, + 0x3d, 0xcf, 0xd9, 0x6d, 0xa2, 0x63, 0xce, 0x4b, 0x5e, 0xc5, 0xd3, 0x37, 0xe8, 0x30, 0xec, 0x05, 0x8a, 0xf7, 0xe9, + 0x93, 0xe6, 0x81, 0x33, 0xd3, 0x40, 0x82, 0x0f, 0x3c, 0xeb, 0x05, 0x80, 0x79, 0xb9, 0x9a, 0x1e, 0x81, 0x05, 0x9e, + 0x86, 0xf0, 0x6f, 0x5e, 0x2c, 0x7e, 0x70, 0x33, 0x09, 0xcb, 0x77, 0x83, 0x39, 0xa0, 0x34, 0x37, 0x98, 0x57, 0xcc, + 0xb1, 0xc8, 0xe7, 0xb9, 0x54, 0x9a, 0x77, 0x95, 0x9b, 0x4a, 0xc5, 0xcf, 0xef, 0xce, 0x29, 0xa7, 0xaf, 0xa6, 0x02, + 0x95, 0x43, 0x17, 0xdd, 0x5c, 0x93, 0xfb, 0x74, 0xf0, 0xf5, 0xc9, 0x92, 0x25, 0x2e, 0xa9, 0x81, 0xe0, 0xf2, 0x0b, + 0xec, 0x80, 0xc2, 0x09, 0x0d, 0x8f, 0x0d, 0x35, 0xa0, 0x30, 0xe7, 0x44, 0x27, 0x0c, 0x85, 0xd3, 0x29, 0x13, 0x2d, + 0x3e, 0x07, 0x8e, 0x41, 0x0e, 0x07, 0x13, 0x17, 0x43, 0x1d, 0x0f, 0x82, 0x50, 0x1d, 0x7e, 0x9d, 0xf9, 0x66, 0x36, + 0x2d, 0x82, 0xef, 0x05, 0x1f, 0x2f, 0x22, 0xe6, 0xff, 0x7b, 0xf0, 0x35, 0x10, 0xee, 0xaf, 0x2f, 0x55, 0xbd, 0x9f, + 0x58, 0x8b, 0x88, 0xcd, 0x06, 0x5f, 0xd7, 0x24, 0x98, 0xc7, 0xeb, 0x3d, 0x8d, 0x45, 0x6d, 0xb7, 0xf2, 0x90, 0x73, + 0xed, 0xbd, 0x2e, 0xf5, 0x43, 0x7e, 0x5b, 0x87, 0x1b, 0xe0, 0xa6, 0x70, 0xc7, 0x76, 0xfa, 0x78, 0x7f, 0x1e, 0xfb, + 0xee, 0xe4, 0x63, 0x9f, 0xde, 0x14, 0x1e, 0x4c, 0xa0, 0xd6, 0x13, 0x77, 0xd5, 0x43, 0xf2, 0x2a, 0x17, 0x82, 0xf7, + 0x34, 0x95, 0x66, 0x9c, 0x5d, 0xed, 0x5e, 0xc6, 0xad, 0xbc, 0xc1, 0x2f, 0xe3, 0xa7, 0x6e, 0x16, 0x5e, 0xc2, 0xc4, + 0xa7, 0xf0, 0x21, 0x4d, 0xc5, 0x45, 0x9d, 0xae, 0xa8, 0x78, 0xb1, 0xb6, 0xda, 0x8a, 0xd3, 0xfd, 0xae, 0x73, 0xed, + 0xd8, 0x8b, 0x96, 0x63, 0x75, 0x3f, 0x38, 0xdd, 0x45, 0xdb, 0x3a, 0xf6, 0xcd, 0xb6, 0x75, 0x0c, 0x7f, 0x3e, 0x1c, + 0x5b, 0xdd, 0x85, 0xd9, 0xb2, 0x0e, 0x3f, 0x38, 0x2d, 0xdf, 0xec, 0x5a, 0xc7, 0xf0, 0xe7, 0x8c, 0x5a, 0xc1, 0x05, + 0x88, 0xee, 0x3b, 0x5f, 0x17, 0xb0, 0x80, 0xf4, 0x3b, 0xd3, 0xc9, 0x1a, 0x05, 0xf2, 0x56, 0xa3, 0xd7, 0x05, 0x94, + 0x41, 0x19, 0x7f, 0xd0, 0x14, 0xa1, 0xaf, 0x05, 0x03, 0x46, 0x39, 0x7e, 0x84, 0x79, 0x9b, 0xf0, 0x43, 0x17, 0x89, + 0x56, 0x6a, 0x8f, 0x11, 0x6f, 0x53, 0x9f, 0x5c, 0x44, 0x24, 0x01, 0x26, 0x45, 0xf0, 0x2f, 0x2b, 0x0c, 0x8d, 0x27, + 0x72, 0x62, 0x49, 0x58, 0x29, 0x4f, 0x44, 0x9f, 0xee, 0x1e, 0x38, 0x7a, 0xf3, 0xb3, 0x2c, 0x11, 0xea, 0x17, 0xed, + 0x5b, 0x4a, 0x3d, 0xf6, 0x59, 0xfd, 0x60, 0x52, 0xa6, 0x3c, 0x9f, 0x12, 0x44, 0x14, 0x9f, 0x7a, 0x51, 0x36, 0x3c, + 0x09, 0x45, 0x3b, 0xf5, 0x59, 0x59, 0x74, 0xc8, 0x18, 0xf9, 0x06, 0xb8, 0xe4, 0x6b, 0xd7, 0x97, 0x0c, 0xd9, 0xa4, + 0x96, 0x0f, 0x32, 0xcc, 0xff, 0xf8, 0x71, 0x3e, 0x38, 0xb3, 0x34, 0xee, 0x13, 0xa7, 0x03, 0x64, 0xb7, 0xc3, 0xda, + 0x5b, 0x6d, 0x2a, 0x77, 0xc7, 0xa2, 0xcf, 0x83, 0x50, 0x0b, 0xbb, 0x29, 0x61, 0xb1, 0xd1, 0x68, 0xd8, 0x59, 0xb1, + 0xd7, 0x80, 0x28, 0xfe, 0xa5, 0xab, 0x8e, 0xaa, 0xf7, 0x03, 0x61, 0x7e, 0x10, 0x6c, 0x89, 0xbf, 0xcf, 0xef, 0x62, + 0x2a, 0x80, 0x66, 0xcb, 0x3c, 0x76, 0x38, 0x88, 0xff, 0xd9, 0x93, 0x40, 0x67, 0x4d, 0xb0, 0x97, 0x28, 0x9d, 0xd6, + 0x82, 0xf3, 0x5e, 0x46, 0x57, 0x89, 0xa0, 0xb2, 0xf8, 0x54, 0x85, 0x22, 0x48, 0x25, 0x8c, 0xd9, 0xc3, 0x33, 0x63, + 0xd1, 0x8c, 0x5a, 0xe4, 0x05, 0x86, 0x87, 0xb9, 0x4e, 0x84, 0xe3, 0xa8, 0xfe, 0xf8, 0x71, 0x23, 0x11, 0x22, 0xe3, + 0x9c, 0x98, 0x25, 0x59, 0x7e, 0x53, 0x55, 0xc6, 0x6f, 0xaa, 0x8c, 0x62, 0xb2, 0x7e, 0x11, 0x6b, 0x08, 0x1b, 0x57, + 0xda, 0x7b, 0xf8, 0x73, 0xcc, 0xdc, 0xc4, 0xe2, 0xca, 0x52, 0x4d, 0x22, 0xee, 0x86, 0xc3, 0xda, 0x60, 0xdd, 0xca, + 0x23, 0x68, 0x66, 0x69, 0x12, 0xff, 0xb6, 0xe6, 0x51, 0x1d, 0xa0, 0x8f, 0x4f, 0x76, 0x1e, 0x80, 0xec, 0x6d, 0xe2, + 0x52, 0x60, 0x18, 0x99, 0xe4, 0x86, 0x89, 0x2b, 0x52, 0x76, 0x02, 0x5f, 0xde, 0xaf, 0x35, 0xbf, 0x90, 0x22, 0x3f, + 0x0c, 0xdf, 0x9e, 0x7f, 0xab, 0xf0, 0xfd, 0x4f, 0xd6, 0x02, 0x78, 0x91, 0xa1, 0xcc, 0x3f, 0x03, 0xca, 0xfc, 0xa3, + 0xf0, 0x24, 0x53, 0x2a, 0xe6, 0x6c, 0x24, 0x08, 0xa2, 0x00, 0x9a, 0x6c, 0x28, 0x96, 0x6b, 0x3f, 0xf1, 0x56, 0x6e, + 0x94, 0x1c, 0x60, 0xda, 0x1f, 0x40, 0x72, 0x6a, 0x53, 0x3c, 0x08, 0x32, 0xc3, 0x10, 0x81, 0x5b, 0x93, 0x40, 0xd8, + 0x61, 0xcc, 0x3c, 0x3f, 0x33, 0xc3, 0x10, 0x1f, 0x70, 0x27, 0x13, 0xb6, 0x4a, 0x06, 0x85, 0xf4, 0x42, 0xe1, 0x24, + 0x61, 0x89, 0x19, 0x27, 0x11, 0x73, 0x97, 0x6a, 0x16, 0x20, 0xbc, 0xda, 0x5f, 0xbc, 0x1e, 0x2f, 0xbd, 0x24, 0x8b, + 0xb0, 0x4b, 0x13, 0x04, 0x83, 0x08, 0x18, 0xe2, 0x70, 0x94, 0x72, 0x10, 0x9e, 0x85, 0xf3, 0xd2, 0x8e, 0xca, 0x39, + 0x97, 0x53, 0x8c, 0xdf, 0x4e, 0x37, 0x19, 0x90, 0x16, 0x4f, 0x42, 0xff, 0x8a, 0xc7, 0xb0, 0xc8, 0x02, 0x01, 0xab, + 0xc3, 0x13, 0x7e, 0xbd, 0x55, 0x30, 0x7c, 0x8b, 0xda, 0xb1, 0x21, 0x42, 0x7d, 0x53, 0x74, 0x8b, 0x03, 0x5e, 0x19, + 0x48, 0x13, 0xf5, 0x8c, 0x49, 0x46, 0x68, 0x2c, 0xe7, 0xc0, 0x08, 0x15, 0x0c, 0x66, 0x16, 0xce, 0x30, 0x73, 0xa7, + 0xc4, 0x51, 0x21, 0xaf, 0xf4, 0xe9, 0xd3, 0x8b, 0xd1, 0x6f, 0xff, 0x81, 0x4c, 0x28, 0x0b, 0x47, 0xc4, 0x94, 0xb8, + 0x90, 0x6b, 0x71, 0xee, 0xd3, 0x18, 0xa1, 0xb1, 0x14, 0x9b, 0x8a, 0x10, 0x3d, 0x62, 0x6b, 0xa5, 0xa3, 0x4b, 0x11, + 0xa2, 0x11, 0x72, 0x28, 0xe9, 0x22, 0xf2, 0x05, 0xa6, 0xe4, 0x1c, 0x89, 0x98, 0x28, 0xca, 0x3f, 0x6f, 0x9f, 0x1f, + 0x2b, 0x79, 0x0c, 0xa3, 0x3a, 0x8b, 0x1e, 0xda, 0x43, 0xc3, 0x13, 0x57, 0x41, 0xa6, 0x05, 0xd9, 0x8f, 0xb8, 0x77, + 0x00, 0xd3, 0x5c, 0x84, 0x4b, 0x66, 0x79, 0xe1, 0xc1, 0x0d, 0x1b, 0x9b, 0xee, 0xca, 0x23, 0xbb, 0x1c, 0x94, 0xbb, + 0x29, 0xc4, 0xf9, 0x65, 0xe6, 0x2e, 0xc4, 0x5f, 0xa7, 0x39, 0x28, 0xc3, 0x62, 0x4c, 0xce, 0x4e, 0x2b, 0xd7, 0x03, + 0x42, 0xfc, 0x02, 0x09, 0x8e, 0xe1, 0xf0, 0xe4, 0xc0, 0x1d, 0x16, 0x83, 0x02, 0x5b, 0x22, 0xb9, 0x4d, 0x91, 0x08, + 0x9c, 0x52, 0x6c, 0x5f, 0x11, 0xc6, 0x37, 0x7f, 0x30, 0xc3, 0xd9, 0x4c, 0x0e, 0xe4, 0x6b, 0x15, 0x87, 0x97, 0x01, + 0x2d, 0xdf, 0xd2, 0xe1, 0x8a, 0xbe, 0x54, 0xfd, 0x44, 0xf6, 0x53, 0xed, 0x61, 0x04, 0x6f, 0x98, 0x33, 0x1c, 0xf7, + 0x4a, 0x40, 0xe0, 0x0c, 0x62, 0x0f, 0xa9, 0x12, 0xc7, 0x23, 0xe5, 0xf4, 0x13, 0x0d, 0x9c, 0xcb, 0x83, 0xc1, 0x80, + 0xd0, 0x5c, 0x19, 0xdb, 0x01, 0x10, 0x6b, 0x12, 0xfd, 0xc0, 0x64, 0x13, 0x68, 0x68, 0x92, 0xbb, 0x2c, 0x36, 0x2a, + 0x4f, 0xa7, 0x3a, 0xc6, 0x03, 0x57, 0x6c, 0xbf, 0xc2, 0x06, 0x85, 0x8d, 0xc7, 0xd7, 0x1d, 0xf0, 0xbb, 0xe8, 0xa7, + 0x84, 0xe6, 0x95, 0x6f, 0x08, 0xa3, 0x9b, 0xbe, 0x7b, 0x17, 0x4a, 0x66, 0x4c, 0x3c, 0xa2, 0xc9, 0x19, 0x96, 0x9e, + 0x0b, 0x4f, 0xe2, 0xca, 0x41, 0xcb, 0x12, 0xa2, 0x54, 0x0f, 0x9b, 0x9c, 0xc4, 0x64, 0xd7, 0x59, 0x93, 0xeb, 0x16, + 0x27, 0x83, 0xc8, 0x33, 0xcd, 0xcf, 0x61, 0xe1, 0x25, 0xa2, 0x85, 0xf4, 0xe4, 0x00, 0xe6, 0x07, 0x51, 0x58, 0x0a, + 0x8c, 0x93, 0xa7, 0x43, 0xa8, 0x17, 0x37, 0x26, 0x53, 0xac, 0x37, 0x53, 0xc1, 0xf3, 0xe1, 0xc5, 0x52, 0x4a, 0xf3, + 0x27, 0x55, 0xa9, 0xf2, 0x32, 0x76, 0x3d, 0x13, 0xb8, 0x3b, 0x7b, 0xd0, 0x87, 0x35, 0xa6, 0x0e, 0x4a, 0xfb, 0x09, + 0x13, 0x41, 0x0e, 0xce, 0x92, 0x86, 0x38, 0x08, 0x4d, 0x55, 0x88, 0x9f, 0xdd, 0x52, 0x21, 0xdf, 0xc7, 0xdb, 0x6a, + 0xe5, 0x9c, 0x53, 0x56, 0x6d, 0xee, 0x6a, 0xea, 0x43, 0xdc, 0xf1, 0x95, 0xda, 0x58, 0x0a, 0xf5, 0xce, 0x92, 0x01, + 0x54, 0x15, 0xb2, 0x78, 0x77, 0xb5, 0xa2, 0xca, 0x7a, 0xff, 0xe4, 0x80, 0xae, 0xa5, 0x43, 0xda, 0x61, 0xc3, 0x13, + 0x30, 0xe5, 0xa6, 0x45, 0x77, 0x57, 0x2b, 0xbe, 0xa4, 0xf4, 0x8b, 0xde, 0x1c, 0x2c, 0x92, 0xa5, 0x3f, 0xfc, 0x3f, + 0x04, 0xdf, 0xdf, 0xf4, 0x2c, 0x6c, 0x03, 0x00}; -} // namespace esphome::web_server +} // namespace web_server +} // namespace esphome #endif #endif From e7001c5eea1ce79110a97ed7bc33b6b18ab5ec30 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:05:37 -1000 Subject: [PATCH 104/302] [api] Auto-generate zero-copy pointer access for incoming API bytes fields (#12654) --- esphome/components/api/api.proto | 8 +++---- esphome/components/api/api_pb2.h | 8 +++---- script/api_protobuf/api_protobuf.py | 35 +++++++++++++---------------- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index debea5808c..fc05947774 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -747,7 +747,7 @@ message NoiseEncryptionSetKeyRequest { option (source) = SOURCE_CLIENT; option (ifdef) = "USE_API_NOISE"; - bytes key = 1 [(pointer_to_buffer) = true]; + bytes key = 1; } message NoiseEncryptionSetKeyResponse { @@ -796,7 +796,7 @@ message HomeassistantActionResponse { uint32 call_id = 1; // Matches the call_id from HomeassistantActionRequest bool success = 2; // Whether the service call succeeded string error_message = 3; // Error message if success = false - bytes response_data = 4 [(pointer_to_buffer) = true, (field_ifdef) = "USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON"]; + bytes response_data = 4 [(field_ifdef) = "USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON"]; } // ==================== IMPORT HOME ASSISTANT STATES ==================== @@ -1692,7 +1692,7 @@ message BluetoothGATTWriteRequest { uint32 handle = 2; bool response = 3; - bytes data = 4 [(pointer_to_buffer) = true]; + bytes data = 4; } message BluetoothGATTReadDescriptorRequest { @@ -1712,7 +1712,7 @@ message BluetoothGATTWriteDescriptorRequest { uint64 address = 1; uint32 handle = 2; - bytes data = 3 [(pointer_to_buffer) = true]; + bytes data = 3; } message BluetoothGATTNotifyRequest { diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index 9d7a1eb9cb..2579ebbae2 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -1069,7 +1069,7 @@ class SubscribeLogsResponse final : public ProtoMessage { class NoiseEncryptionSetKeyRequest final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 124; - static constexpr uint8_t ESTIMATED_SIZE = 19; + static constexpr uint8_t ESTIMATED_SIZE = 9; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "noise_encryption_set_key_request"; } #endif @@ -1161,7 +1161,7 @@ class HomeassistantActionRequest final : public ProtoMessage { class HomeassistantActionResponse final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 130; - static constexpr uint8_t ESTIMATED_SIZE = 34; + static constexpr uint8_t ESTIMATED_SIZE = 24; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "homeassistant_action_response"; } #endif @@ -2146,7 +2146,7 @@ class BluetoothGATTReadResponse final : public ProtoMessage { class BluetoothGATTWriteRequest final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 75; - static constexpr uint8_t ESTIMATED_SIZE = 29; + static constexpr uint8_t ESTIMATED_SIZE = 19; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "bluetooth_gatt_write_request"; } #endif @@ -2182,7 +2182,7 @@ class BluetoothGATTReadDescriptorRequest final : public ProtoDecodableMessage { class BluetoothGATTWriteDescriptorRequest final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 77; - static constexpr uint8_t ESTIMATED_SIZE = 27; + static constexpr uint8_t ESTIMATED_SIZE = 17; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "bluetooth_gatt_write_descriptor_request"; } #endif diff --git a/script/api_protobuf/api_protobuf.py b/script/api_protobuf/api_protobuf.py index f22b248747..5b68c6a3d2 100755 --- a/script/api_protobuf/api_protobuf.py +++ b/script/api_protobuf/api_protobuf.py @@ -354,28 +354,23 @@ def create_field_type_info( return FixedArrayRepeatedType(field, size_define) return RepeatedTypeInfo(field) - # Check for mutually exclusive options on bytes fields - if field.type == 12: - has_pointer_to_buffer = get_field_opt(field, pb.pointer_to_buffer, False) - fixed_size = get_field_opt(field, pb.fixed_array_size, None) - - if has_pointer_to_buffer and fixed_size is not None: - raise ValueError( - f"Field '{field.name}' has both pointer_to_buffer and fixed_array_size. " - "These options are mutually exclusive. Use pointer_to_buffer for zero-copy " - "or fixed_array_size for traditional array storage." - ) - - if has_pointer_to_buffer: - # Zero-copy pointer approach - no size needed, will use size_t for length - return PointerToBytesBufferType(field, None) - - if fixed_size is not None: - # Traditional fixed array approach with copy - return FixedArrayBytesType(field, fixed_size) - # Special handling for bytes fields if field.type == 12: + fixed_size = get_field_opt(field, pb.fixed_array_size, None) + + if fixed_size is not None: + # Traditional fixed array approach with copy (takes priority) + return FixedArrayBytesType(field, fixed_size) + + # For SOURCE_CLIENT only messages (decode but no encode), use pointer + # for zero-copy access to the receive buffer + if needs_decode and not needs_encode: + return PointerToBytesBufferType(field, None) + + # For SOURCE_BOTH/SOURCE_SERVER, explicit annotation is still needed + if get_field_opt(field, pb.pointer_to_buffer, False): + return PointerToBytesBufferType(field, None) + return BytesType(field, needs_decode, needs_encode) # Special handling for string fields From 4cb066bcbf3308664a8f0eddefdbca66adfc28b2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:05:50 -1000 Subject: [PATCH 105/302] [api] Use StringRef in handle_action_response to avoid temporary string (#12655) --- esphome/components/api/api_server.cpp | 4 ++-- esphome/components/api/api_server.h | 6 +++--- esphome/components/api/homeassistant_service.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/esphome/components/api/api_server.cpp b/esphome/components/api/api_server.cpp index 7a03d8f8ad..23cecd2663 100644 --- a/esphome/components/api/api_server.cpp +++ b/esphome/components/api/api_server.cpp @@ -394,7 +394,7 @@ void APIServer::register_action_response_callback(uint32_t call_id, ActionRespon this->action_response_callbacks_.push_back({call_id, std::move(callback)}); } -void APIServer::handle_action_response(uint32_t call_id, bool success, const std::string &error_message) { +void APIServer::handle_action_response(uint32_t call_id, bool success, StringRef error_message) { for (auto it = this->action_response_callbacks_.begin(); it != this->action_response_callbacks_.end(); ++it) { if (it->call_id == call_id) { auto callback = std::move(it->callback); @@ -406,7 +406,7 @@ void APIServer::handle_action_response(uint32_t call_id, bool success, const std } } #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON -void APIServer::handle_action_response(uint32_t call_id, bool success, const std::string &error_message, +void APIServer::handle_action_response(uint32_t call_id, bool success, StringRef error_message, const uint8_t *response_data, size_t response_data_len) { for (auto it = this->action_response_callbacks_.begin(); it != this->action_response_callbacks_.end(); ++it) { if (it->call_id == call_id) { diff --git a/esphome/components/api/api_server.h b/esphome/components/api/api_server.h index 96c56fd08a..11d726a40a 100644 --- a/esphome/components/api/api_server.h +++ b/esphome/components/api/api_server.h @@ -143,10 +143,10 @@ class APIServer : public Component, // Action response handling using ActionResponseCallback = std::function; void register_action_response_callback(uint32_t call_id, ActionResponseCallback callback); - void handle_action_response(uint32_t call_id, bool success, const std::string &error_message); + void handle_action_response(uint32_t call_id, bool success, StringRef error_message); #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON - void handle_action_response(uint32_t call_id, bool success, const std::string &error_message, - const uint8_t *response_data, size_t response_data_len); + void handle_action_response(uint32_t call_id, bool success, StringRef error_message, const uint8_t *response_data, + size_t response_data_len); #endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON #endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES #endif // USE_API_HOMEASSISTANT_SERVICES diff --git a/esphome/components/api/homeassistant_service.h b/esphome/components/api/homeassistant_service.h index 2da6e15362..1fdcc51803 100644 --- a/esphome/components/api/homeassistant_service.h +++ b/esphome/components/api/homeassistant_service.h @@ -67,10 +67,10 @@ template class TemplatableKeyValuePair { // the callback is invoked synchronously while the message is on the stack). class ActionResponse { public: - ActionResponse(bool success, const std::string &error_message) : success_(success), error_message_(error_message) {} + ActionResponse(bool success, StringRef error_message) : success_(success), error_message_(error_message) {} #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON - ActionResponse(bool success, const std::string &error_message, const uint8_t *data, size_t data_len) + ActionResponse(bool success, StringRef error_message, const uint8_t *data, size_t data_len) : success_(success), error_message_(error_message) { if (data == nullptr || data_len == 0) return; From f394cf3f4d8b2382a40bb5cd6451f392b0c8d330 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:06:03 -1000 Subject: [PATCH 106/302] [packet_transport] Use stack-based format_hex_pretty_to for logging (#12791) --- .../components/packet_transport/packet_transport.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/esphome/components/packet_transport/packet_transport.cpp b/esphome/components/packet_transport/packet_transport.cpp index da7f5f8bff..4a53ab110b 100644 --- a/esphome/components/packet_transport/packet_transport.cpp +++ b/esphome/components/packet_transport/packet_transport.cpp @@ -1,11 +1,15 @@ #include "esphome/core/log.h" #include "esphome/core/application.h" +#include "esphome/core/helpers.h" #include "packet_transport.h" #include "esphome/components/xxtea/xxtea.h" namespace esphome { namespace packet_transport { + +// Maximum bytes to log in hex output (168 * 3 = 504, under TX buffer size of 512) +static constexpr size_t PACKET_MAX_LOG_BYTES = 168; /** * Structure of a data packet; everything is little-endian * @@ -263,7 +267,8 @@ void PacketTransport::flush_() { xxtea::encrypt((uint32_t *) (encode_buffer.data() + header_len), len / 4, (uint32_t *) this->encryption_key_.data()); } - ESP_LOGVV(TAG, "Sending packet %s", format_hex_pretty(encode_buffer.data(), encode_buffer.size()).c_str()); + char hex_buf[format_hex_pretty_size(PACKET_MAX_LOG_BYTES)]; + ESP_LOGVV(TAG, "Sending packet %s", format_hex_pretty_to(hex_buf, encode_buffer.data(), encode_buffer.size())); this->send_packet(encode_buffer); } @@ -505,8 +510,9 @@ void PacketTransport::process_(const std::vector &data) { } if (decoder.get(byte) == DECODE_OK) { ESP_LOGW(TAG, "Unknown key %X", byte); + char hex_buf[format_hex_pretty_size(PACKET_MAX_LOG_BYTES)]; ESP_LOGD(TAG, "Buffer pos: %zu contents: %s", data.size() - decoder.get_remaining_size(), - format_hex_pretty(data).c_str()); + format_hex_pretty_to(hex_buf, data.data(), data.size())); } break; } From 0b7ff09657f16707206e878c03a6440261e3958a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:09:40 -1000 Subject: [PATCH 107/302] [api] Use pointer to FixedVector for siren tones field (#12657) --- esphome/components/api/api.proto | 2 +- esphome/components/api/api_pb2.cpp | 10 +++++----- esphome/components/api/api_pb2.h | 2 +- esphome/components/api/api_pb2_dump.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index fc05947774..b5aaec430c 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -1292,7 +1292,7 @@ message ListEntitiesSirenResponse { string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"]; bool disabled_by_default = 6; - repeated string tones = 7; + repeated string tones = 7 [(container_pointer_no_template) = "FixedVector"]; bool supports_duration = 8; bool supports_volume = 9; EntityCategory entity_category = 10; diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index edd6dfc6a9..1147cd986e 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -1710,8 +1710,8 @@ void ListEntitiesSirenResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); - for (auto &it : this->tones) { - buffer.encode_string(7, it, true); + for (const char *it : *this->tones) { + buffer.encode_string(7, it, strlen(it), true); } buffer.encode_bool(8, this->supports_duration); buffer.encode_bool(9, this->supports_volume); @@ -1728,9 +1728,9 @@ void ListEntitiesSirenResponse::calculate_size(ProtoSize &size) const { size.add_length(1, this->icon_ref_.size()); #endif size.add_bool(1, this->disabled_by_default); - if (!this->tones.empty()) { - for (const auto &it : this->tones) { - size.add_length_force(1, it.size()); + if (!this->tones->empty()) { + for (const char *it : *this->tones) { + size.add_length_force(1, strlen(it)); } } size.add_bool(1, this->supports_duration); diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index 2579ebbae2..4b14697181 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -1708,7 +1708,7 @@ class ListEntitiesSirenResponse final : public InfoResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "list_entities_siren_response"; } #endif - std::vector tones{}; + const FixedVector *tones{}; bool supports_duration{false}; bool supports_volume{false}; void encode(ProtoWriteBuffer buffer) const override; diff --git a/esphome/components/api/api_pb2_dump.cpp b/esphome/components/api/api_pb2_dump.cpp index 567f10fcc0..12df109a3d 100644 --- a/esphome/components/api/api_pb2_dump.cpp +++ b/esphome/components/api/api_pb2_dump.cpp @@ -1579,7 +1579,7 @@ void ListEntitiesSirenResponse::dump_to(std::string &out) const { dump_field(out, "icon", this->icon_ref_); #endif dump_field(out, "disabled_by_default", this->disabled_by_default); - for (const auto &it : this->tones) { + for (const auto &it : *this->tones) { dump_field(out, "tones", it, 4); } dump_field(out, "supports_duration", this->supports_duration); From 51259888bf1a3fb640bb299f8dfd4b9a5ff48fe2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:10:21 -1000 Subject: [PATCH 108/302] [voice_assistant] Use zero-copy buffer access for audio data (#12656) --- esphome/components/api/api.proto | 2 +- esphome/components/api/api_pb2.cpp | 10 ++++++---- esphome/components/api/api_pb2.h | 11 +++-------- esphome/components/api/api_pb2_dump.cpp | 6 +----- .../voice_assistant/voice_assistant.cpp | 15 ++++++++------- 5 files changed, 19 insertions(+), 25 deletions(-) diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index b5aaec430c..43b721c2d5 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -1937,7 +1937,7 @@ message VoiceAssistantAudio { option (source) = SOURCE_BOTH; option (ifdef) = "USE_VOICE_ASSISTANT"; - bytes data = 1; + bytes data = 1 [(pointer_to_buffer) = true]; bool end = 2; } diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index 1147cd986e..698e08f9b3 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -2527,20 +2527,22 @@ bool VoiceAssistantAudio::decode_varint(uint32_t field_id, ProtoVarInt value) { } bool VoiceAssistantAudio::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->data = value.as_string(); + case 1: { + this->data = value.data(); + this->data_len = value.size(); break; + } default: return false; } return true; } void VoiceAssistantAudio::encode(ProtoWriteBuffer buffer) const { - buffer.encode_bytes(1, this->data_ptr_, this->data_len_); + buffer.encode_bytes(1, this->data, this->data_len); buffer.encode_bool(2, this->end); } void VoiceAssistantAudio::calculate_size(ProtoSize &size) const { - size.add_length(1, this->data_len_); + size.add_length(1, this->data_len); size.add_bool(1, this->end); } bool VoiceAssistantTimerEventResponse::decode_varint(uint32_t field_id, ProtoVarInt value) { diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index 4b14697181..6275b4c211 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -2521,17 +2521,12 @@ class VoiceAssistantEventResponse final : public ProtoDecodableMessage { class VoiceAssistantAudio final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 106; - static constexpr uint8_t ESTIMATED_SIZE = 11; + static constexpr uint8_t ESTIMATED_SIZE = 21; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "voice_assistant_audio"; } #endif - std::string data{}; - const uint8_t *data_ptr_{nullptr}; - size_t data_len_{0}; - void set_data(const uint8_t *data, size_t len) { - this->data_ptr_ = data; - this->data_len_ = len; - } + const uint8_t *data{nullptr}; + uint16_t data_len{0}; bool end{false}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; diff --git a/esphome/components/api/api_pb2_dump.cpp b/esphome/components/api/api_pb2_dump.cpp index 12df109a3d..1ec6645b3f 100644 --- a/esphome/components/api/api_pb2_dump.cpp +++ b/esphome/components/api/api_pb2_dump.cpp @@ -1978,11 +1978,7 @@ void VoiceAssistantEventResponse::dump_to(std::string &out) const { void VoiceAssistantAudio::dump_to(std::string &out) const { MessageDumpHelper helper(out, "VoiceAssistantAudio"); out.append(" data: "); - if (this->data_ptr_ != nullptr) { - out.append(format_hex_pretty(this->data_ptr_, this->data_len_)); - } else { - out.append(format_hex_pretty(reinterpret_cast(this->data.data()), this->data.size())); - } + out.append(format_hex_pretty(this->data, this->data_len)); out.append("\n"); dump_field(out, "end", this->end); } diff --git a/esphome/components/voice_assistant/voice_assistant.cpp b/esphome/components/voice_assistant/voice_assistant.cpp index 9bb5393be2..8101d210b3 100644 --- a/esphome/components/voice_assistant/voice_assistant.cpp +++ b/esphome/components/voice_assistant/voice_assistant.cpp @@ -272,7 +272,8 @@ void VoiceAssistant::loop() { size_t read_bytes = this->ring_buffer_->read((void *) this->send_buffer_, SEND_BUFFER_SIZE, 0); if (this->audio_mode_ == AUDIO_MODE_API) { api::VoiceAssistantAudio msg; - msg.set_data(this->send_buffer_, read_bytes); + msg.data = this->send_buffer_; + msg.data_len = read_bytes; this->api_client_->send_message(msg, api::VoiceAssistantAudio::MESSAGE_TYPE); } else { if (!this->udp_socket_running_) { @@ -841,12 +842,12 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { void VoiceAssistant::on_audio(const api::VoiceAssistantAudio &msg) { #ifdef USE_SPEAKER // We should never get to this function if there is no speaker anyway if ((this->speaker_ != nullptr) && (this->speaker_buffer_ != nullptr)) { - if (this->speaker_buffer_index_ + msg.data.length() < SPEAKER_BUFFER_SIZE) { - memcpy(this->speaker_buffer_ + this->speaker_buffer_index_, msg.data.data(), msg.data.length()); - this->speaker_buffer_index_ += msg.data.length(); - this->speaker_buffer_size_ += msg.data.length(); - this->speaker_bytes_received_ += msg.data.length(); - ESP_LOGV(TAG, "Received audio: %u bytes from API", msg.data.length()); + if (this->speaker_buffer_index_ + msg.data_len < SPEAKER_BUFFER_SIZE) { + memcpy(this->speaker_buffer_ + this->speaker_buffer_index_, msg.data, msg.data_len); + this->speaker_buffer_index_ += msg.data_len; + this->speaker_buffer_size_ += msg.data_len; + this->speaker_bytes_received_ += msg.data_len; + ESP_LOGV(TAG, "Received audio: %u bytes from API", msg.data_len); } else { ESP_LOGE(TAG, "Cannot receive audio, buffer is full"); } From 0ef49a8b7306ff6ce2150229f36d8462903f7c38 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:11:31 -1000 Subject: [PATCH 109/302] [ld2410][ld2412][ld2450] Use stack buffers for hex logging (#12688) --- esphome/components/ld2410/ld2410.cpp | 13 ++++++++++--- esphome/components/ld2412/ld2412.cpp | 13 ++++++++++--- esphome/components/ld2450/ld2450.cpp | 13 ++++++++++--- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/esphome/components/ld2410/ld2410.cpp b/esphome/components/ld2410/ld2410.cpp index bb2e4e2f4c..5ea47d5084 100644 --- a/esphome/components/ld2410/ld2410.cpp +++ b/esphome/components/ld2410/ld2410.cpp @@ -413,7 +413,8 @@ bool LD2410Component::handle_ack_data_() { return true; } if (!ld2410::validate_header_footer(CMD_FRAME_HEADER, this->buffer_data_)) { - ESP_LOGW(TAG, "Invalid header: %s", format_hex_pretty(this->buffer_data_, HEADER_FOOTER_SIZE).c_str()); + char hex_buf[format_hex_pretty_size(HEADER_FOOTER_SIZE)]; + ESP_LOGW(TAG, "Invalid header: %s", format_hex_pretty_to(hex_buf, this->buffer_data_, HEADER_FOOTER_SIZE)); return true; } if (this->buffer_data_[COMMAND_STATUS] != 0x01) { @@ -597,11 +598,17 @@ void LD2410Component::readline_(int readch) { return; // Not enough data to process yet } if (ld2410::validate_header_footer(DATA_FRAME_FOOTER, &this->buffer_data_[this->buffer_pos_ - 4])) { - ESP_LOGV(TAG, "Handling Periodic Data: %s", format_hex_pretty(this->buffer_data_, this->buffer_pos_).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MAX_LINE_LENGTH)]; + ESP_LOGV(TAG, "Handling Periodic Data: %s", format_hex_pretty_to(hex_buf, this->buffer_data_, this->buffer_pos_)); +#endif this->handle_periodic_data_(); this->buffer_pos_ = 0; // Reset position index for next message } else if (ld2410::validate_header_footer(CMD_FRAME_FOOTER, &this->buffer_data_[this->buffer_pos_ - 4])) { - ESP_LOGV(TAG, "Handling Ack Data: %s", format_hex_pretty(this->buffer_data_, this->buffer_pos_).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MAX_LINE_LENGTH)]; + ESP_LOGV(TAG, "Handling Ack Data: %s", format_hex_pretty_to(hex_buf, this->buffer_data_, this->buffer_pos_)); +#endif if (this->handle_ack_data_()) { this->buffer_pos_ = 0; // Reset position index for next message } else { diff --git a/esphome/components/ld2412/ld2412.cpp b/esphome/components/ld2412/ld2412.cpp index 0f6fe62d30..3d51800065 100644 --- a/esphome/components/ld2412/ld2412.cpp +++ b/esphome/components/ld2412/ld2412.cpp @@ -457,7 +457,8 @@ bool LD2412Component::handle_ack_data_() { return true; } if (!ld2412::validate_header_footer(CMD_FRAME_HEADER, this->buffer_data_)) { - ESP_LOGW(TAG, "Invalid header: %s", format_hex_pretty(this->buffer_data_, HEADER_FOOTER_SIZE).c_str()); + char hex_buf[format_hex_pretty_size(HEADER_FOOTER_SIZE)]; + ESP_LOGW(TAG, "Invalid header: %s", format_hex_pretty_to(hex_buf, this->buffer_data_, HEADER_FOOTER_SIZE)); return true; } if (this->buffer_data_[COMMAND_STATUS] != 0x01) { @@ -670,11 +671,17 @@ void LD2412Component::readline_(int readch) { return; // Not enough data to process yet } if (ld2412::validate_header_footer(DATA_FRAME_FOOTER, &this->buffer_data_[this->buffer_pos_ - 4])) { - ESP_LOGV(TAG, "Handling Periodic Data: %s", format_hex_pretty(this->buffer_data_, this->buffer_pos_).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MAX_LINE_LENGTH)]; + ESP_LOGV(TAG, "Handling Periodic Data: %s", format_hex_pretty_to(hex_buf, this->buffer_data_, this->buffer_pos_)); +#endif this->handle_periodic_data_(); this->buffer_pos_ = 0; // Reset position index for next message } else if (ld2412::validate_header_footer(CMD_FRAME_FOOTER, &this->buffer_data_[this->buffer_pos_ - 4])) { - ESP_LOGV(TAG, "Handling Ack Data: %s", format_hex_pretty(this->buffer_data_, this->buffer_pos_).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MAX_LINE_LENGTH)]; + ESP_LOGV(TAG, "Handling Ack Data: %s", format_hex_pretty_to(hex_buf, this->buffer_data_, this->buffer_pos_)); +#endif if (this->handle_ack_data_()) { this->buffer_pos_ = 0; // Reset position index for next message } else { diff --git a/esphome/components/ld2450/ld2450.cpp b/esphome/components/ld2450/ld2450.cpp index e69ef31d4f..2c137c3578 100644 --- a/esphome/components/ld2450/ld2450.cpp +++ b/esphome/components/ld2450/ld2450.cpp @@ -607,7 +607,8 @@ bool LD2450Component::handle_ack_data_() { return true; } if (!ld2450::validate_header_footer(CMD_FRAME_HEADER, this->buffer_data_)) { - ESP_LOGW(TAG, "Invalid header: %s", format_hex_pretty(this->buffer_data_, HEADER_FOOTER_SIZE).c_str()); + char hex_buf[format_hex_pretty_size(HEADER_FOOTER_SIZE)]; + ESP_LOGW(TAG, "Invalid header: %s", format_hex_pretty_to(hex_buf, this->buffer_data_, HEADER_FOOTER_SIZE)); return true; } if (this->buffer_data_[COMMAND_STATUS] != 0x01) { @@ -758,11 +759,17 @@ void LD2450Component::readline_(int readch) { } if (this->buffer_data_[this->buffer_pos_ - 2] == DATA_FRAME_FOOTER[0] && this->buffer_data_[this->buffer_pos_ - 1] == DATA_FRAME_FOOTER[1]) { - ESP_LOGV(TAG, "Handling Periodic Data: %s", format_hex_pretty(this->buffer_data_, this->buffer_pos_).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MAX_LINE_LENGTH)]; + ESP_LOGV(TAG, "Handling Periodic Data: %s", format_hex_pretty_to(hex_buf, this->buffer_data_, this->buffer_pos_)); +#endif this->handle_periodic_data_(); this->buffer_pos_ = 0; // Reset position index for next frame } else if (ld2450::validate_header_footer(CMD_FRAME_FOOTER, &this->buffer_data_[this->buffer_pos_ - 4])) { - ESP_LOGV(TAG, "Handling Ack Data: %s", format_hex_pretty(this->buffer_data_, this->buffer_pos_).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MAX_LINE_LENGTH)]; + ESP_LOGV(TAG, "Handling Ack Data: %s", format_hex_pretty_to(hex_buf, this->buffer_data_, this->buffer_pos_)); +#endif if (this->handle_ack_data_()) { this->buffer_pos_ = 0; // Reset position index for next message } else { From 167a42aa27b7a55444cb517fb167749b84e248e8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:11:45 -1000 Subject: [PATCH 110/302] [api] Use StringRef in send_action_response and send_execute_service_response (#12658) --- esphome/components/api/api_connection.cpp | 8 ++++---- esphome/components/api/api_connection.h | 4 ++-- esphome/components/api/api_server.cpp | 4 ++-- esphome/components/api/api_server.h | 4 ++-- esphome/components/api/user_services.h | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 26ddb16e9a..8588651968 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -1749,20 +1749,20 @@ void APIConnection::execute_service(const ExecuteServiceRequest &msg) { // the action list. This ensures async actions (delays, waits) complete first. } #ifdef USE_API_USER_DEFINED_ACTION_RESPONSES -void APIConnection::send_execute_service_response(uint32_t call_id, bool success, const std::string &error_message) { +void APIConnection::send_execute_service_response(uint32_t call_id, bool success, StringRef error_message) { ExecuteServiceResponse resp; resp.call_id = call_id; resp.success = success; - resp.set_error_message(StringRef(error_message)); + resp.set_error_message(error_message); this->send_message(resp, ExecuteServiceResponse::MESSAGE_TYPE); } #ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON -void APIConnection::send_execute_service_response(uint32_t call_id, bool success, const std::string &error_message, +void APIConnection::send_execute_service_response(uint32_t call_id, bool success, StringRef error_message, const uint8_t *response_data, size_t response_data_len) { ExecuteServiceResponse resp; resp.call_id = call_id; resp.success = success; - resp.set_error_message(StringRef(error_message)); + resp.set_error_message(error_message); resp.response_data = response_data; resp.response_data_len = response_data_len; this->send_message(resp, ExecuteServiceResponse::MESSAGE_TYPE); diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index 6363116900..47609f79b6 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -233,9 +233,9 @@ class APIConnection final : public APIServerConnection { #ifdef USE_API_USER_DEFINED_ACTIONS void execute_service(const ExecuteServiceRequest &msg) override; #ifdef USE_API_USER_DEFINED_ACTION_RESPONSES - void send_execute_service_response(uint32_t call_id, bool success, const std::string &error_message); + void send_execute_service_response(uint32_t call_id, bool success, StringRef error_message); #ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON - void send_execute_service_response(uint32_t call_id, bool success, const std::string &error_message, + void send_execute_service_response(uint32_t call_id, bool success, StringRef error_message, const uint8_t *response_data, size_t response_data_len); #endif // USE_API_USER_DEFINED_ACTION_RESPONSES_JSON #endif // USE_API_USER_DEFINED_ACTION_RESPONSES diff --git a/esphome/components/api/api_server.cpp b/esphome/components/api/api_server.cpp index 23cecd2663..8b76740e4d 100644 --- a/esphome/components/api/api_server.cpp +++ b/esphome/components/api/api_server.cpp @@ -678,7 +678,7 @@ void APIServer::unregister_active_action_calls_for_connection(APIConnection *con } } -void APIServer::send_action_response(uint32_t action_call_id, bool success, const std::string &error_message) { +void APIServer::send_action_response(uint32_t action_call_id, bool success, StringRef error_message) { for (auto &call : this->active_action_calls_) { if (call.action_call_id == action_call_id) { call.connection->send_execute_service_response(call.client_call_id, success, error_message); @@ -688,7 +688,7 @@ void APIServer::send_action_response(uint32_t action_call_id, bool success, cons ESP_LOGW(TAG, "Cannot send response: no active call found for action_call_id %u", action_call_id); } #ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON -void APIServer::send_action_response(uint32_t action_call_id, bool success, const std::string &error_message, +void APIServer::send_action_response(uint32_t action_call_id, bool success, StringRef error_message, const uint8_t *response_data, size_t response_data_len) { for (auto &call : this->active_action_calls_) { if (call.action_call_id == action_call_id) { diff --git a/esphome/components/api/api_server.h b/esphome/components/api/api_server.h index 11d726a40a..b855d2cce0 100644 --- a/esphome/components/api/api_server.h +++ b/esphome/components/api/api_server.h @@ -165,9 +165,9 @@ class APIServer : public Component, void unregister_active_action_call(uint32_t action_call_id); void unregister_active_action_calls_for_connection(APIConnection *conn); // Send response for a specific action call (uses action_call_id, sends client_call_id in response) - void send_action_response(uint32_t action_call_id, bool success, const std::string &error_message); + void send_action_response(uint32_t action_call_id, bool success, StringRef error_message); #ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON - void send_action_response(uint32_t action_call_id, bool success, const std::string &error_message, + void send_action_response(uint32_t action_call_id, bool success, StringRef error_message, const uint8_t *response_data, size_t response_data_len); #endif // USE_API_USER_DEFINED_ACTION_RESPONSES_JSON #endif // USE_API_USER_DEFINED_ACTION_RESPONSES diff --git a/esphome/components/api/user_services.h b/esphome/components/api/user_services.h index 001add626f..8e3a61b279 100644 --- a/esphome/components/api/user_services.h +++ b/esphome/components/api/user_services.h @@ -255,7 +255,7 @@ template class APIRespondAction : public Action { bool return_response = std::get<1>(args); if (!return_response) { // Client doesn't want response data, just send success/error - this->parent_->send_action_response(call_id, success, error_message); + this->parent_->send_action_response(call_id, success, StringRef(error_message)); return; } } @@ -265,12 +265,12 @@ template class APIRespondAction : public Action { json::JsonBuilder builder; this->json_builder_(x..., builder.root()); std::string json_str = builder.serialize(); - this->parent_->send_action_response(call_id, success, error_message, + this->parent_->send_action_response(call_id, success, StringRef(error_message), reinterpret_cast(json_str.data()), json_str.size()); return; } #endif - this->parent_->send_action_response(call_id, success, error_message); + this->parent_->send_action_response(call_id, success, StringRef(error_message)); } protected: From 25e60d62cf549c1fe65a0829d86361932e53498b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:12:04 -1000 Subject: [PATCH 111/302] [mqtt] Avoid heap allocations when logging IP addresses (#12686) --- esphome/components/mqtt/mqtt_client.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/mqtt/mqtt_client.cpp b/esphome/components/mqtt/mqtt_client.cpp index ba701b90a3..c650c99f62 100644 --- a/esphome/components/mqtt/mqtt_client.cpp +++ b/esphome/components/mqtt/mqtt_client.cpp @@ -153,13 +153,14 @@ void MQTTClientComponent::on_log(uint8_t level, const char *tag, const char *mes #endif void MQTTClientComponent::dump_config() { + char ip_buf[network::IP_ADDRESS_BUFFER_SIZE]; ESP_LOGCONFIG(TAG, "MQTT:\n" " Server Address: %s:%u (%s)\n" " Username: " LOG_SECRET("'%s'") "\n" " Client ID: " LOG_SECRET("'%s'") "\n" " Clean Session: %s", - this->credentials_.address.c_str(), this->credentials_.port, this->ip_.str().c_str(), + this->credentials_.address.c_str(), this->credentials_.port, this->ip_.str_to(ip_buf), this->credentials_.username.c_str(), this->credentials_.client_id.c_str(), YESNO(this->credentials_.clean_session)); if (this->is_discovery_ip_enabled()) { @@ -246,7 +247,8 @@ void MQTTClientComponent::check_dnslookup_() { return; } - ESP_LOGD(TAG, "Resolved broker IP address to %s", this->ip_.str().c_str()); + char ip_buf[network::IP_ADDRESS_BUFFER_SIZE]; + ESP_LOGD(TAG, "Resolved broker IP address to %s", this->ip_.str_to(ip_buf)); this->start_connect_(); } #if defined(USE_ESP8266) && LWIP_VERSION_MAJOR == 1 From 023be88a87b228eafcc79a5243b2c427d65e8d0e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:13:08 -1000 Subject: [PATCH 112/302] [tuya] Use stack buffers for hex logging to avoid heap allocations (#12689) --- esphome/components/tuya/tuya.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/esphome/components/tuya/tuya.cpp b/esphome/components/tuya/tuya.cpp index 12b14be9ff..2812fb6ad6 100644 --- a/esphome/components/tuya/tuya.cpp +++ b/esphome/components/tuya/tuya.cpp @@ -20,6 +20,8 @@ static const char *const TAG = "tuya"; static const int COMMAND_DELAY = 10; static const int RECEIVE_TIMEOUT = 300; static const int MAX_RETRIES = 5; +// Max bytes to log for datapoint values (larger values are truncated) +static constexpr size_t MAX_DATAPOINT_LOG_BYTES = 16; void Tuya::setup() { this->set_interval("heartbeat", 15000, [this] { this->send_empty_command_(TuyaCommandType::HEARTBEAT); }); @@ -51,7 +53,9 @@ void Tuya::dump_config() { } for (auto &info : this->datapoints_) { if (info.type == TuyaDatapointType::RAW) { - ESP_LOGCONFIG(TAG, " Datapoint %u: raw (value: %s)", info.id, format_hex_pretty(info.value_raw).c_str()); + char hex_buf[format_hex_pretty_size(MAX_DATAPOINT_LOG_BYTES)]; + ESP_LOGCONFIG(TAG, " Datapoint %u: raw (value: %s)", info.id, + format_hex_pretty_to(hex_buf, info.value_raw.data(), info.value_raw.size())); } else if (info.type == TuyaDatapointType::BOOLEAN) { ESP_LOGCONFIG(TAG, " Datapoint %u: switch (value: %s)", info.id, ONOFF(info.value_bool)); } else if (info.type == TuyaDatapointType::INTEGER) { @@ -122,8 +126,11 @@ bool Tuya::validate_message_() { // valid message const uint8_t *message_data = data + 6; +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MAX_DATAPOINT_LOG_BYTES)]; ESP_LOGV(TAG, "Received Tuya: CMD=0x%02X VERSION=%u DATA=[%s] INIT_STATE=%u", command, version, - format_hex_pretty(message_data, length).c_str(), static_cast(this->init_state_)); + format_hex_pretty_to(hex_buf, message_data, length), static_cast(this->init_state_)); +#endif this->handle_command_(command, version, message_data, length); // return false to reset rx buffer @@ -349,7 +356,11 @@ void Tuya::handle_datapoints_(const uint8_t *buffer, size_t len) { switch (datapoint.type) { case TuyaDatapointType::RAW: datapoint.value_raw = std::vector(data, data + data_size); - ESP_LOGD(TAG, "Datapoint %u update to %s", datapoint.id, format_hex_pretty(datapoint.value_raw).c_str()); + { + char hex_buf[format_hex_pretty_size(MAX_DATAPOINT_LOG_BYTES)]; + ESP_LOGD(TAG, "Datapoint %u update to %s", datapoint.id, + format_hex_pretty_to(hex_buf, datapoint.value_raw.data(), datapoint.value_raw.size())); + } break; case TuyaDatapointType::BOOLEAN: if (data_size != 1) { @@ -460,8 +471,12 @@ void Tuya::send_raw_command_(TuyaCommand command) { break; } +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(MAX_DATAPOINT_LOG_BYTES)]; ESP_LOGV(TAG, "Sending Tuya: CMD=0x%02X VERSION=%u DATA=[%s] INIT_STATE=%u", static_cast(command.cmd), - version, format_hex_pretty(command.payload).c_str(), static_cast(this->init_state_)); + version, format_hex_pretty_to(hex_buf, command.payload.data(), command.payload.size()), + static_cast(this->init_state_)); +#endif this->write_array({0x55, 0xAA, version, (uint8_t) command.cmd, len_hi, len_lo}); if (!command.payload.empty()) @@ -675,7 +690,8 @@ void Tuya::set_numeric_datapoint_value_(uint8_t datapoint_id, TuyaDatapointType } void Tuya::set_raw_datapoint_value_(uint8_t datapoint_id, const std::vector &value, bool forced) { - ESP_LOGD(TAG, "Setting datapoint %u to %s", datapoint_id, format_hex_pretty(value).c_str()); + char hex_buf[format_hex_pretty_size(MAX_DATAPOINT_LOG_BYTES)]; + ESP_LOGD(TAG, "Setting datapoint %u to %s", datapoint_id, format_hex_pretty_to(hex_buf, value.data(), value.size())); optional datapoint = this->get_datapoint_(datapoint_id); if (!datapoint.has_value()) { ESP_LOGW(TAG, "Setting unknown datapoint %u", datapoint_id); From e732f8469efced5214ea86ff7221982ffb2e1516 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:13:26 -1000 Subject: [PATCH 113/302] [udp] Avoid heap allocations when joining multicast groups (#12685) --- esphome/components/udp/udp_component.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/esphome/components/udp/udp_component.cpp b/esphome/components/udp/udp_component.cpp index daa6c52f98..4474efeb77 100644 --- a/esphome/components/udp/udp_component.cpp +++ b/esphome/components/udp/udp_component.cpp @@ -65,11 +65,14 @@ void UDPComponent::setup() { server.sin_port = htons(this->listen_port_); if (this->listen_address_.has_value()) { + // Only 16 bytes needed for IPv4, but use standard size for consistency + char addr_buf[network::IP_ADDRESS_BUFFER_SIZE]; + this->listen_address_.value().str_to(addr_buf); struct ip_mreq imreq = {}; imreq.imr_interface.s_addr = ESPHOME_INADDR_ANY; - inet_aton(this->listen_address_.value().str().c_str(), &imreq.imr_multiaddr); + inet_aton(addr_buf, &imreq.imr_multiaddr); server.sin_addr.s_addr = imreq.imr_multiaddr.s_addr; - ESP_LOGD(TAG, "Join multicast %s", this->listen_address_.value().str().c_str()); + ESP_LOGD(TAG, "Join multicast %s", addr_buf); err = this->listen_socket_->setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, &imreq, sizeof(imreq)); if (err < 0) { ESP_LOGE(TAG, "Failed to set IP_ADD_MEMBERSHIP. Error %d", errno); From 00ab64a3c7c74df024482ada1e8ba6a4ff1395fd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:13:43 -1000 Subject: [PATCH 114/302] [wifi] Use wifi_ssid_to() to avoid heap allocations in automation and connection checks (#12678) --- esphome/components/wifi/automation.h | 6 ++++-- esphome/components/wifi/wifi_component.cpp | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/esphome/components/wifi/automation.h b/esphome/components/wifi/automation.h index 7997baff65..fb0e71bcf6 100644 --- a/esphome/components/wifi/automation.h +++ b/esphome/components/wifi/automation.h @@ -45,7 +45,8 @@ template class WiFiConfigureAction : public Action, publi if (this->connecting_) return; // If already connected to the same AP, do nothing - if (global_wifi_component->wifi_ssid() == ssid) { + char ssid_buf[SSID_BUFFER_SIZE]; + if (strcmp(global_wifi_component->wifi_ssid_to(ssid_buf), ssid.c_str()) == 0) { // Callback to notify the user that the connection was successful this->connect_trigger_->trigger(); return; @@ -94,7 +95,8 @@ template class WiFiConfigureAction : public Action, publi this->cancel_timeout("wifi-connect-timeout"); this->cancel_timeout("wifi-fallback-timeout"); this->connecting_ = false; - if (global_wifi_component->wifi_ssid() == this->new_sta_.get_ssid()) { + char ssid_buf[SSID_BUFFER_SIZE]; + if (strcmp(global_wifi_component->wifi_ssid_to(ssid_buf), this->new_sta_.get_ssid().c_str()) == 0) { // Callback to notify the user that the connection was successful this->connect_trigger_->trigger(); } else { diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 50c0938cf1..001d5f254a 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -1167,7 +1167,8 @@ void WiFiComponent::check_connecting_finished() { auto status = this->wifi_sta_connect_status_(); if (status == WiFiSTAConnectStatus::CONNECTED) { - if (wifi_ssid().empty()) { + char ssid_buf[SSID_BUFFER_SIZE]; + if (wifi_ssid_to(ssid_buf)[0] == '\0') { ESP_LOGW(TAG, "Connection incomplete"); this->retry_connect(); return; From ddb6c6cfd468bf16277a2d4b8d69b38228145270 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:13:59 -1000 Subject: [PATCH 115/302] [captive_portal] Use stack buffer for IP address logging in DNS server (#12679) --- esphome/components/captive_portal/dns_server_esp32_idf.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/esphome/components/captive_portal/dns_server_esp32_idf.cpp b/esphome/components/captive_portal/dns_server_esp32_idf.cpp index 5188b2047f..5743cbd671 100644 --- a/esphome/components/captive_portal/dns_server_esp32_idf.cpp +++ b/esphome/components/captive_portal/dns_server_esp32_idf.cpp @@ -47,7 +47,10 @@ struct DNSAnswer { void DNSServer::start(const network::IPAddress &ip) { this->server_ip_ = ip; - ESP_LOGV(TAG, "Starting DNS server on %s", ip.str().c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char ip_buf[network::IP_ADDRESS_BUFFER_SIZE]; + ESP_LOGV(TAG, "Starting DNS server on %s", ip.str_to(ip_buf)); +#endif // Create loop-monitored UDP socket this->socket_ = socket::socket_ip_loop_monitored(SOCK_DGRAM, IPPROTO_UDP); From 2ff9535f5fb91908b4a8b8b95b28c911bfd7d807 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:14:12 -1000 Subject: [PATCH 116/302] [esp32_improv] Use stack buffer for URL formatting to avoid heap allocation (#12682) --- .../components/esp32_improv/esp32_improv_component.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/esphome/components/esp32_improv/esp32_improv_component.cpp b/esphome/components/esp32_improv/esp32_improv_component.cpp index 0ad54bbb15..05a30e2941 100644 --- a/esphome/components/esp32_improv/esp32_improv_component.cpp +++ b/esphome/components/esp32_improv/esp32_improv_component.cpp @@ -403,8 +403,12 @@ void ESP32ImprovComponent::check_wifi_connection_() { #ifdef USE_WEBSERVER for (auto &ip : wifi::global_wifi_component->wifi_sta_ip_addresses()) { if (ip.is_ip4()) { - char url_buffer[64]; - snprintf(url_buffer, sizeof(url_buffer), "http://%s:%d", ip.str().c_str(), USE_WEBSERVER_PORT); + // "http://" (7) + IPv4 max (15) + ":" (1) + port max (5) + null = 29 + char url_buffer[32]; + memcpy(url_buffer, "http://", 7); // NOLINT(bugprone-not-null-terminated-result) - str_to null-terminates + ip.str_to(url_buffer + 7); + size_t len = strlen(url_buffer); + snprintf(url_buffer + len, sizeof(url_buffer) - len, ":%d", USE_WEBSERVER_PORT); url_strings[url_count++] = url_buffer; break; } From 2230e5634787af2ebb26a0978fd834a8856eac2c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:14:24 -1000 Subject: [PATCH 117/302] [wifi] Use stack buffers for IP address logging to avoid heap allocations (#12680) --- esphome/components/wifi/wifi_component.cpp | 17 +++++++++++++---- .../components/wifi/wifi_component_esp8266.cpp | 7 +++++-- .../components/wifi/wifi_component_esp_idf.cpp | 13 +++++++++---- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 001d5f254a..a0a7d3d946 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -655,12 +655,15 @@ void WiFiComponent::setup_ap_config_() { #ifdef USE_WIFI_MANUAL_IP auto manual_ip = this->ap_.get_manual_ip(); if (manual_ip.has_value()) { + char static_ip_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char gateway_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char subnet_buf[network::IP_ADDRESS_BUFFER_SIZE]; ESP_LOGCONFIG(TAG, " AP Static IP: '%s'\n" " AP Gateway: '%s'\n" " AP Subnet: '%s'", - manual_ip->static_ip.str().c_str(), manual_ip->gateway.str().c_str(), - manual_ip->subnet.str().c_str()); + manual_ip->static_ip.str_to(static_ip_buf), manual_ip->gateway.str_to(gateway_buf), + manual_ip->subnet.str_to(subnet_buf)); } #endif @@ -816,8 +819,14 @@ void WiFiComponent::start_connecting(const WiFiAP &ap) { #ifdef USE_WIFI_MANUAL_IP if (ap.get_manual_ip().has_value()) { ManualIP m = *ap.get_manual_ip(); - ESP_LOGV(TAG, " Manual IP: Static IP=%s Gateway=%s Subnet=%s DNS1=%s DNS2=%s", m.static_ip.str().c_str(), - m.gateway.str().c_str(), m.subnet.str().c_str(), m.dns1.str().c_str(), m.dns2.str().c_str()); + char static_ip_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char gateway_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char subnet_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char dns1_buf[network::IP_ADDRESS_BUFFER_SIZE]; + char dns2_buf[network::IP_ADDRESS_BUFFER_SIZE]; + ESP_LOGV(TAG, " Manual IP: Static IP=%s Gateway=%s Subnet=%s DNS1=%s DNS2=%s", m.static_ip.str_to(static_ip_buf), + m.gateway.str_to(gateway_buf), m.subnet.str_to(subnet_buf), m.dns1.str_to(dns1_buf), + m.dns2.str_to(dns2_buf)); } else #endif { diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index 1c744648bb..86c8a8891b 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -810,10 +810,13 @@ bool WiFiComponent::wifi_ap_ip_config_(const optional &manual_ip) { network::IPAddress start_address = network::IPAddress(&info.ip); start_address += 99; lease.start_ip = start_address; - ESP_LOGV(TAG, "DHCP server IP lease start: %s", start_address.str().c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char ip_buf[network::IP_ADDRESS_BUFFER_SIZE]; +#endif + ESP_LOGV(TAG, "DHCP server IP lease start: %s", start_address.str_to(ip_buf)); start_address += 10; lease.end_ip = start_address; - ESP_LOGV(TAG, "DHCP server IP lease end: %s", start_address.str().c_str()); + ESP_LOGV(TAG, "DHCP server IP lease end: %s", start_address.str_to(ip_buf)); if (!wifi_softap_set_dhcps_lease(&lease)) { ESP_LOGE(TAG, "Set SoftAP DHCP lease failed"); return false; diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 5d4d003d62..d9b5e7c114 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -969,10 +969,13 @@ bool WiFiComponent::wifi_ap_ip_config_(const optional &manual_ip) { network::IPAddress start_address = network::IPAddress(&info.ip); start_address += 99; lease.start_ip = start_address; - ESP_LOGV(TAG, "DHCP server IP lease start: %s", start_address.str().c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char ip_buf[network::IP_ADDRESS_BUFFER_SIZE]; +#endif + ESP_LOGV(TAG, "DHCP server IP lease start: %s", start_address.str_to(ip_buf)); start_address += 10; lease.end_ip = start_address; - ESP_LOGV(TAG, "DHCP server IP lease end: %s", start_address.str().c_str()); + ESP_LOGV(TAG, "DHCP server IP lease end: %s", start_address.str_to(ip_buf)); err = esp_netif_dhcps_option(s_ap_netif, ESP_NETIF_OP_SET, ESP_NETIF_REQUESTED_IP_ADDRESS, &lease, sizeof(lease)); if (err != ESP_OK) { @@ -984,8 +987,10 @@ bool WiFiComponent::wifi_ap_ip_config_(const optional &manual_ip) { // Configure DHCP Option 114 (Captive Portal URI) if captive portal is enabled // This provides a standards-compliant way for clients to discover the captive portal if (captive_portal::global_captive_portal != nullptr) { - static char captive_portal_uri[32]; - snprintf(captive_portal_uri, sizeof(captive_portal_uri), "http://%s", network::IPAddress(&info.ip).str().c_str()); + // Buffer must be static - dhcps_set_option_info stores pointer, doesn't copy + static char captive_portal_uri[24]; // "http://" (7) + IPv4 max (15) + null + memcpy(captive_portal_uri, "http://", 7); // NOLINT(bugprone-not-null-terminated-result) - str_to null-terminates + network::IPAddress(&info.ip).str_to(captive_portal_uri + 7); err = esp_netif_dhcps_option(s_ap_netif, ESP_NETIF_OP_SET, ESP_NETIF_CAPTIVEPORTAL_URI, captive_portal_uri, strlen(captive_portal_uri)); if (err != ESP_OK) { From 0e108c2178231f3bd76cf39ea5d4bc4dd55dc84f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:14:52 -1000 Subject: [PATCH 118/302] [esp32] Add minimum_chip_revision setting and log chip revision at startup (#12696) --- esphome/components/esp32/__init__.py | 39 ++++++++++++++++++++++++++++ esphome/core/application.cpp | 16 ++++++++++++ esphome/core/defines.h | 1 + 3 files changed, 56 insertions(+) diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index d8397a87cc..da550e58dc 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -85,6 +85,7 @@ CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES = "enable_idf_experimental_features" CONF_ENABLE_LWIP_ASSERT = "enable_lwip_assert" CONF_ENABLE_OTA_ROLLBACK = "enable_ota_rollback" CONF_EXECUTE_FROM_PSRAM = "execute_from_psram" +CONF_MINIMUM_CHIP_REVISION = "minimum_chip_revision" CONF_RELEASE = "release" LOG_LEVELS_IDF = [ @@ -109,6 +110,21 @@ COMPILER_OPTIMIZATIONS = { "SIZE": "CONFIG_COMPILER_OPTIMIZATION_SIZE", } +# ESP32 (original) chip revision options +# Setting minimum revision to 3.0 or higher: +# - Reduces flash size by excluding workaround code for older chip bugs +# - For PSRAM users: disables CONFIG_SPIRAM_CACHE_WORKAROUND, which saves significant +# IRAM by keeping C library functions in ROM instead of recompiling them +# See: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/chip_revision.html +ESP32_CHIP_REVISIONS = { + "0.0": "CONFIG_ESP32_REV_MIN_0", + "1.0": "CONFIG_ESP32_REV_MIN_1", + "1.1": "CONFIG_ESP32_REV_MIN_1_1", + "2.0": "CONFIG_ESP32_REV_MIN_2", + "3.0": "CONFIG_ESP32_REV_MIN_3", + "3.1": "CONFIG_ESP32_REV_MIN_3_1", +} + # Socket limit configuration for ESP-IDF # ESP-IDF CONFIG_LWIP_MAX_SOCKETS has range 1-253, default 10 DEFAULT_MAX_SOCKETS = 10 # ESP-IDF default @@ -566,6 +582,16 @@ def final_validate(config): path=[CONF_FRAMEWORK, CONF_ADVANCED, CONF_IGNORE_EFUSE_MAC_CRC], ) ) + if ( + config[CONF_VARIANT] != VARIANT_ESP32 + and advanced.get(CONF_MINIMUM_CHIP_REVISION) is not None + ): + errs.append( + cv.Invalid( + f"'{CONF_MINIMUM_CHIP_REVISION}' is only supported on {VARIANT_ESP32}", + path=[CONF_FRAMEWORK, CONF_ADVANCED, CONF_MINIMUM_CHIP_REVISION], + ) + ) if advanced[CONF_EXECUTE_FROM_PSRAM]: if config[CONF_VARIANT] != VARIANT_ESP32S3: errs.append( @@ -694,6 +720,9 @@ FRAMEWORK_SCHEMA = cv.Schema( cv.Optional(CONF_ENABLE_LWIP_ASSERT, default=True): cv.boolean, cv.Optional(CONF_IGNORE_EFUSE_CUSTOM_MAC, default=False): cv.boolean, cv.Optional(CONF_IGNORE_EFUSE_MAC_CRC, default=False): cv.boolean, + cv.Optional(CONF_MINIMUM_CHIP_REVISION): cv.one_of( + *ESP32_CHIP_REVISIONS + ), # DHCP server is needed for WiFi AP mode. When WiFi component is used, # it will handle disabling DHCP server when AP is not configured. # Default to false (disabled) when WiFi is not used. @@ -1017,6 +1046,16 @@ async def to_code(config): add_idf_sdkconfig_option( f"CONFIG_ESPTOOLPY_FLASHSIZE_{config[CONF_FLASH_SIZE]}", True ) + + # Set minimum chip revision for ESP32 variant + # Setting this to 3.0 or higher reduces flash size by excluding workaround code, + # and for PSRAM users saves significant IRAM by keeping C library functions in ROM. + if variant == VARIANT_ESP32: + min_rev = conf[CONF_ADVANCED].get(CONF_MINIMUM_CHIP_REVISION) + if min_rev is not None: + for rev, flag in ESP32_CHIP_REVISIONS.items(): + add_idf_sdkconfig_option(flag, rev == min_rev) + cg.add_define("USE_ESP32_MIN_CHIP_REVISION_SET") add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_SINGLE_APP", False) add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_CUSTOM", True) add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_CUSTOM_FILENAME", "partitions.csv") diff --git a/esphome/core/application.cpp b/esphome/core/application.cpp index 4c9cc6b2b6..f8fa3b333e 100644 --- a/esphome/core/application.cpp +++ b/esphome/core/application.cpp @@ -7,6 +7,9 @@ #ifdef USE_ESP8266 #include #endif +#ifdef USE_ESP32 +#include +#endif #include "esphome/core/version.h" #include "esphome/core/hal.h" #include @@ -203,6 +206,19 @@ void Application::loop() { ESP_LOGI(TAG, "ESPHome version " ESPHOME_VERSION " compiled on %s", build_time_str); #ifdef ESPHOME_PROJECT_NAME ESP_LOGI(TAG, "Project " ESPHOME_PROJECT_NAME " version " ESPHOME_PROJECT_VERSION); +#endif +#ifdef USE_ESP32 + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + ESP_LOGI(TAG, "ESP32 Chip: %s r%d.%d, %d core(s)", ESPHOME_VARIANT, chip_info.revision / 100, + chip_info.revision % 100, chip_info.cores); +#if defined(USE_ESP32_VARIANT_ESP32) && !defined(USE_ESP32_MIN_CHIP_REVISION_SET) + // Suggest optimization for chips that don't need the PSRAM cache workaround + if (chip_info.revision >= 300) { + ESP_LOGW(TAG, "Set minimum_chip_revision: \"%d.%d\" to reduce binary size", chip_info.revision / 100, + chip_info.revision % 100); + } +#endif #endif } diff --git a/esphome/core/defines.h b/esphome/core/defines.h index 579edc065a..1fddc426d4 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -166,6 +166,7 @@ #define USE_MQTT_IDF_ENQUEUE #define USE_ESPHOME_TASK_LOG_BUFFER #define USE_OTA_ROLLBACK +#define USE_ESP32_MIN_CHIP_REVISION_SET #define USE_BLUETOOTH_PROXY #define BLUETOOTH_PROXY_MAX_CONNECTIONS 3 From 0c4184b129cde19b3fd1aaf83a572628d92c8efd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:20:17 -1000 Subject: [PATCH 119/302] [cse7766] Use stack buffer for hex formatting in debug logging (#12732) --- esphome/components/cse7766/cse7766.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/esphome/components/cse7766/cse7766.cpp b/esphome/components/cse7766/cse7766.cpp index fe81ae91fe..71fe15f0ae 100644 --- a/esphome/components/cse7766/cse7766.cpp +++ b/esphome/components/cse7766/cse7766.cpp @@ -1,11 +1,13 @@ #include "cse7766.h" -#include "esphome/core/log.h" #include "esphome/core/application.h" +#include "esphome/core/helpers.h" +#include "esphome/core/log.h" namespace esphome { namespace cse7766 { static const char *const TAG = "cse7766"; +static constexpr size_t CSE7766_RAW_DATA_SIZE = 24; void CSE7766Component::loop() { const uint32_t now = App.get_loop_component_start_time(); @@ -70,8 +72,8 @@ bool CSE7766Component::check_byte_() { void CSE7766Component::parse_data_() { #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE { - std::string s = format_hex_pretty(this->raw_data_, sizeof(this->raw_data_)); - ESP_LOGVV(TAG, "Raw data: %s", s.c_str()); + char hex_buf[format_hex_pretty_size(CSE7766_RAW_DATA_SIZE)]; + ESP_LOGVV(TAG, "Raw data: %s", format_hex_pretty_to(hex_buf, this->raw_data_, sizeof(this->raw_data_))); } #endif From b711172b33a898b5c46f6eed0df19bc8f800e1da Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:21:09 -1000 Subject: [PATCH 120/302] [wifi] Use precision format specifier for SSID logging to avoid stack copy (#12704) --- .../wifi/wifi_component_esp8266.cpp | 19 ++++++--------- .../wifi/wifi_component_esp_idf.cpp | 24 +++++++------------ .../wifi/wifi_component_libretiny.cpp | 20 +++++++--------- 3 files changed, 24 insertions(+), 39 deletions(-) diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index 86c8a8891b..055a13afc8 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -518,15 +518,12 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { switch (event->event) { case EVENT_STAMODE_CONNECTED: { auto it = event->event_info.connected; - char buf[33]; - memcpy(buf, it.ssid, it.ssid_len); - buf[it.ssid_len] = '\0'; - ESP_LOGV(TAG, "Connected ssid='%s' bssid=%s channel=%u", buf, format_mac_address_pretty(it.bssid).c_str(), - it.channel); + ESP_LOGV(TAG, "Connected ssid='%.*s' bssid=%s channel=%u", it.ssid_len, (const char *) it.ssid, + format_mac_address_pretty(it.bssid).c_str(), it.channel); s_sta_connected = true; #ifdef USE_WIFI_LISTENERS for (auto *listener : global_wifi_component->connect_state_listeners_) { - listener->on_wifi_connect_state(StringRef(buf, it.ssid_len), it.bssid); + listener->on_wifi_connect_state(StringRef(it.ssid, it.ssid_len), it.bssid); } // For static IP configurations, GOT_IP event may not fire, so notify IP listeners here #ifdef USE_WIFI_MANUAL_IP @@ -543,17 +540,15 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { } case EVENT_STAMODE_DISCONNECTED: { auto it = event->event_info.disconnected; - char buf[33]; - memcpy(buf, it.ssid, it.ssid_len); - buf[it.ssid_len] = '\0'; if (it.reason == REASON_NO_AP_FOUND) { - ESP_LOGW(TAG, "Disconnected ssid='%s' reason='Probe Request Unsuccessful'", buf); + ESP_LOGW(TAG, "Disconnected ssid='%.*s' reason='Probe Request Unsuccessful'", it.ssid_len, + (const char *) it.ssid); s_sta_connect_not_found = true; } else { char bssid_s[18]; format_mac_addr_upper(it.bssid, bssid_s); - ESP_LOGW(TAG, "Disconnected ssid='%s' bssid=" LOG_SECRET("%s") " reason='%s'", buf, bssid_s, - LOG_STR_ARG(get_disconnect_reason_str(it.reason))); + ESP_LOGW(TAG, "Disconnected ssid='%.*s' bssid=" LOG_SECRET("%s") " reason='%s'", it.ssid_len, + (const char *) it.ssid, bssid_s, LOG_STR_ARG(get_disconnect_reason_str(it.reason))); s_sta_connect_error = true; } s_sta_connected = false; diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index d9b5e7c114..f68a095bff 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -734,16 +734,13 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { } else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_STA_CONNECTED) { const auto &it = data->data.sta_connected; - char buf[33]; - assert(it.ssid_len <= 32); - memcpy(buf, it.ssid, it.ssid_len); - buf[it.ssid_len] = '\0'; - ESP_LOGV(TAG, "Connected ssid='%s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", buf, - format_mac_address_pretty(it.bssid).c_str(), it.channel, get_auth_mode_str(it.authmode)); + ESP_LOGV(TAG, "Connected ssid='%.*s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", it.ssid_len, + (const char *) it.ssid, format_mac_address_pretty(it.bssid).c_str(), it.channel, + get_auth_mode_str(it.authmode)); s_sta_connected = true; #ifdef USE_WIFI_LISTENERS for (auto *listener : this->connect_state_listeners_) { - listener->on_wifi_connect_state(StringRef(buf, it.ssid_len), it.bssid); + listener->on_wifi_connect_state(StringRef(it.ssid, it.ssid_len), it.bssid); } // For static IP configurations, GOT_IP event may not fire, so notify IP listeners here #ifdef USE_WIFI_MANUAL_IP @@ -757,21 +754,18 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { } else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_STA_DISCONNECTED) { const auto &it = data->data.sta_disconnected; - char buf[33]; - assert(it.ssid_len <= 32); - memcpy(buf, it.ssid, it.ssid_len); - buf[it.ssid_len] = '\0'; if (it.reason == WIFI_REASON_NO_AP_FOUND) { - ESP_LOGW(TAG, "Disconnected ssid='%s' reason='Probe Request Unsuccessful'", buf); + ESP_LOGW(TAG, "Disconnected ssid='%.*s' reason='Probe Request Unsuccessful'", it.ssid_len, + (const char *) it.ssid); s_sta_connect_not_found = true; } else if (it.reason == WIFI_REASON_ROAMING) { - ESP_LOGI(TAG, "Disconnected ssid='%s' reason='Station Roaming'", buf); + ESP_LOGI(TAG, "Disconnected ssid='%.*s' reason='Station Roaming'", it.ssid_len, (const char *) it.ssid); return; } else { char bssid_s[18]; format_mac_addr_upper(it.bssid, bssid_s); - ESP_LOGW(TAG, "Disconnected ssid='%s' bssid=" LOG_SECRET("%s") " reason='%s'", buf, bssid_s, - get_disconnect_reason_str(it.reason)); + ESP_LOGW(TAG, "Disconnected ssid='%.*s' bssid=" LOG_SECRET("%s") " reason='%s'", it.ssid_len, + (const char *) it.ssid, bssid_s, get_disconnect_reason_str(it.reason)); s_sta_connect_error = true; } s_sta_connected = false; diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index 9b8653d0db..9bbd319f33 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -296,14 +296,12 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ } case ESPHOME_EVENT_ID_WIFI_STA_CONNECTED: { auto it = info.wifi_sta_connected; - char buf[33]; - memcpy(buf, it.ssid, it.ssid_len); - buf[it.ssid_len] = '\0'; - ESP_LOGV(TAG, "Connected ssid='%s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", buf, - format_mac_address_pretty(it.bssid).c_str(), it.channel, get_auth_mode_str(it.authmode)); + ESP_LOGV(TAG, "Connected ssid='%.*s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", it.ssid_len, + (const char *) it.ssid, format_mac_address_pretty(it.bssid).c_str(), it.channel, + get_auth_mode_str(it.authmode)); #ifdef USE_WIFI_LISTENERS for (auto *listener : this->connect_state_listeners_) { - listener->on_wifi_connect_state(StringRef(buf, it.ssid_len), it.bssid); + listener->on_wifi_connect_state(StringRef(it.ssid, it.ssid_len), it.bssid); } // For static IP configurations, GOT_IP event may not fire, so notify IP listeners here #ifdef USE_WIFI_MANUAL_IP @@ -318,9 +316,6 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ } case ESPHOME_EVENT_ID_WIFI_STA_DISCONNECTED: { auto it = info.wifi_sta_disconnected; - char buf[33]; - memcpy(buf, it.ssid, it.ssid_len); - buf[it.ssid_len] = '\0'; // LibreTiny can send spurious disconnect events with empty ssid/bssid during connection. // These are typically "Association Leave" events that don't indicate actual failures: @@ -339,12 +334,13 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ } if (it.reason == WIFI_REASON_NO_AP_FOUND) { - ESP_LOGW(TAG, "Disconnected ssid='%s' reason='Probe Request Unsuccessful'", buf); + ESP_LOGW(TAG, "Disconnected ssid='%.*s' reason='Probe Request Unsuccessful'", it.ssid_len, + (const char *) it.ssid); } else { char bssid_s[18]; format_mac_addr_upper(it.bssid, bssid_s); - ESP_LOGW(TAG, "Disconnected ssid='%s' bssid=" LOG_SECRET("%s") " reason='%s'", buf, bssid_s, - get_disconnect_reason_str(it.reason)); + ESP_LOGW(TAG, "Disconnected ssid='%.*s' bssid=" LOG_SECRET("%s") " reason='%s'", it.ssid_len, + (const char *) it.ssid, bssid_s, get_disconnect_reason_str(it.reason)); } uint8_t reason = it.reason; From 20b66cba238b03549aacf5c897e7d42ca9ce7b13 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:21:23 -1000 Subject: [PATCH 121/302] [shelly_dimmer] Use stack buffer for hex formatting in command logging (#12721) --- esphome/components/shelly_dimmer/shelly_dimmer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/esphome/components/shelly_dimmer/shelly_dimmer.cpp b/esphome/components/shelly_dimmer/shelly_dimmer.cpp index b336bbcb65..3b5307805e 100644 --- a/esphome/components/shelly_dimmer/shelly_dimmer.cpp +++ b/esphome/components/shelly_dimmer/shelly_dimmer.cpp @@ -270,7 +270,10 @@ void ShellyDimmer::send_settings_() { } bool ShellyDimmer::send_command_(uint8_t cmd, const uint8_t *const payload, uint8_t len) { - ESP_LOGD(TAG, "Sending command: 0x%02x (%d bytes) payload 0x%s", cmd, len, format_hex(payload, len).c_str()); + // Buffer for hex formatting: max frame size * 2 + null (covers any payload) + char hex_buf[SHELLY_DIMMER_PROTO_MAX_FRAME_SIZE * 2 + 1]; + ESP_LOGD(TAG, "Sending command: 0x%02x (%d bytes) payload 0x%s", cmd, len, + format_hex_to(hex_buf, sizeof(hex_buf), payload, len)); // Prepare a command frame. uint8_t frame[SHELLY_DIMMER_PROTO_MAX_FRAME_SIZE]; From 9ccb100cca3afd8c32d7f0d62d71b5cc83425a05 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:21:42 -1000 Subject: [PATCH 122/302] [remote_base] Use stack buffer for hex formatting in mirage protocol logging (#12722) --- esphome/components/remote_base/mirage_protocol.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/esphome/components/remote_base/mirage_protocol.cpp b/esphome/components/remote_base/mirage_protocol.cpp index 10d644a1cd..2ae877f193 100644 --- a/esphome/components/remote_base/mirage_protocol.cpp +++ b/esphome/components/remote_base/mirage_protocol.cpp @@ -1,4 +1,5 @@ #include "mirage_protocol.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" namespace esphome { @@ -13,9 +14,12 @@ constexpr uint32_t BIT_ONE_SPACE_US = 1592; constexpr uint32_t BIT_ZERO_SPACE_US = 545; constexpr unsigned int MIRAGE_IR_PACKET_BIT_SIZE = 120; +// Max data bytes in packet (excluding checksum) +constexpr size_t MIRAGE_MAX_DATA_BYTES = (MIRAGE_IR_PACKET_BIT_SIZE / 8); void MirageProtocol::encode(RemoteTransmitData *dst, const MirageData &data) { - ESP_LOGI(TAG, "Transive Mirage: %s", format_hex_pretty(data.data).c_str()); + char hex_buf[format_hex_pretty_size(MIRAGE_MAX_DATA_BYTES)]; + ESP_LOGI(TAG, "Transmit Mirage: %s", format_hex_pretty_to(hex_buf, data.data.data(), data.data.size())); dst->set_carrier_frequency(38000); dst->reserve(5 + ((data.data.size() + 1) * 2)); dst->mark(HEADER_MARK_US); @@ -77,7 +81,8 @@ optional MirageProtocol::decode(RemoteReceiveData src) { } void MirageProtocol::dump(const MirageData &data) { - ESP_LOGI(TAG, "Received Mirage: %s", format_hex_pretty(data.data).c_str()); + char hex_buf[format_hex_pretty_size(MIRAGE_MAX_DATA_BYTES)]; + ESP_LOGI(TAG, "Received Mirage: %s", format_hex_pretty_to(hex_buf, data.data.data(), data.data.size())); } } // namespace remote_base From f9b4e0e489c7c022258c185d7011e3c6949c8e0c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:22:26 -1000 Subject: [PATCH 123/302] [remote_base] Use stack buffer for hex formatting in haier protocol logging (#12723) --- esphome/components/remote_base/haier_protocol.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/esphome/components/remote_base/haier_protocol.cpp b/esphome/components/remote_base/haier_protocol.cpp index ec5cb5775c..734f3c7789 100644 --- a/esphome/components/remote_base/haier_protocol.cpp +++ b/esphome/components/remote_base/haier_protocol.cpp @@ -1,4 +1,5 @@ #include "haier_protocol.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" namespace esphome { @@ -12,6 +13,8 @@ constexpr uint32_t BIT_MARK_US = 540; constexpr uint32_t BIT_ONE_SPACE_US = 1650; constexpr uint32_t BIT_ZERO_SPACE_US = 580; constexpr unsigned int HAIER_IR_PACKET_BIT_SIZE = 112; +// Max data bytes in packet (excluding checksum) +constexpr size_t HAIER_MAX_DATA_BYTES = (HAIER_IR_PACKET_BIT_SIZE / 8); void HaierProtocol::encode_byte_(RemoteTransmitData *dst, uint8_t item) { for (uint8_t mask = 1 << 7; mask != 0; mask >>= 1) { @@ -77,7 +80,8 @@ optional HaierProtocol::decode(RemoteReceiveData src) { } void HaierProtocol::dump(const HaierData &data) { - ESP_LOGI(TAG, "Received Haier: %s", format_hex_pretty(data.data).c_str()); + char hex_buf[format_hex_pretty_size(HAIER_MAX_DATA_BYTES)]; + ESP_LOGI(TAG, "Received Haier: %s", format_hex_pretty_to(hex_buf, data.data.data(), data.data.size())); } } // namespace remote_base From b4e5e0bc9b6f28b81c1892f07a5192d20596c9d8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:22:58 -1000 Subject: [PATCH 124/302] [rc522] Use stack buffers for hex formatting in tag logging (#12725) --- esphome/components/rc522/rc522.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/esphome/components/rc522/rc522.cpp b/esphome/components/rc522/rc522.cpp index fa8564f614..8f8740c925 100644 --- a/esphome/components/rc522/rc522.cpp +++ b/esphome/components/rc522/rc522.cpp @@ -12,6 +12,9 @@ static const uint8_t WAIT_I_RQ = 0x30; // RxIRq and IdleIRq static const char *const TAG = "rc522"; +// Max UID size for RFID tags (4, 7, or 10 bytes) +static constexpr size_t RC522_MAX_UID_SIZE = 10; + static const uint8_t RESET_COUNT = 5; void RC522::setup() { @@ -191,8 +194,9 @@ void RC522::loop() { if (status == STATUS_TIMEOUT) { ESP_LOGV(TAG, "STATE_READ_SERIAL_DONE -> TIMEOUT (no tag present) %d", status); } else { + char hex_buf[format_hex_pretty_size(RC522_MAX_UID_SIZE)]; ESP_LOGW(TAG, "Unexpected response. Read status is %d. Read bytes: %d (%s)", status, back_length_, - format_hex_pretty(buffer_, back_length_, '-', false).c_str()); + format_hex_pretty_to(hex_buf, buffer_, back_length_, '-')); } state_ = STATE_DONE; @@ -237,13 +241,18 @@ void RC522::loop() { trigger->process(rfid_uid); if (report) { - ESP_LOGD(TAG, "Found new tag '%s'", format_hex_pretty(rfid_uid, '-', false).c_str()); + char uid_buf[format_hex_pretty_size(RC522_MAX_UID_SIZE)]; + ESP_LOGD(TAG, "Found new tag '%s'", format_hex_pretty_to(uid_buf, rfid_uid.data(), rfid_uid.size(), '-')); } break; } case STATE_DONE: { if (!this->current_uid_.empty()) { - ESP_LOGV(TAG, "Tag '%s' removed", format_hex_pretty(this->current_uid_, '-', false).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char uid_buf[format_hex_pretty_size(RC522_MAX_UID_SIZE)]; + ESP_LOGV(TAG, "Tag '%s' removed", + format_hex_pretty_to(uid_buf, this->current_uid_.data(), this->current_uid_.size(), '-')); +#endif for (auto *trigger : this->triggers_ontagremoved_) trigger->process(this->current_uid_); } @@ -338,7 +347,10 @@ void RC522::pcd_clear_register_bit_mask_(PcdRegister reg, ///< The register to * @return STATUS_OK on success, STATUS_??? otherwise. */ void RC522::pcd_transceive_data_(uint8_t send_len) { - ESP_LOGV(TAG, "PCD TRANSCEIVE: RX: %s", format_hex_pretty(buffer_, send_len, '-', false).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(RC522_MAX_UID_SIZE)]; + ESP_LOGV(TAG, "PCD TRANSCEIVE: RX: %s", format_hex_pretty_to(hex_buf, buffer_, send_len, '-')); +#endif delayMicroseconds(1000); // we need 1 ms delay between antenna on and those communication commands send_len_ = send_len; // Prepare values for BitFramingReg @@ -412,8 +424,11 @@ RC522::StatusCode RC522::await_transceive_() { error_reg_value); // TODO: is this always due to collissions? return STATUS_ERROR; } +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(RC522_MAX_UID_SIZE)]; ESP_LOGV(TAG, "received %d bytes: %s", back_length_, - format_hex_pretty(buffer_ + send_len_, back_length_, '-', false).c_str()); + format_hex_pretty_to(hex_buf, buffer_ + send_len_, back_length_, '-')); +#endif return STATUS_OK; } From 61b6476de4491406d07793e797b98a1b6bcf919e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:23:18 -1000 Subject: [PATCH 125/302] [opentherm] Replace heap-allocating format calls with printf format specifiers in debug_error (#12726) --- esphome/components/opentherm/opentherm.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/esphome/components/opentherm/opentherm.cpp b/esphome/components/opentherm/opentherm.cpp index d59b9584d1..750ef08b33 100644 --- a/esphome/components/opentherm/opentherm.cpp +++ b/esphome/components/opentherm/opentherm.cpp @@ -7,6 +7,7 @@ #include "opentherm.h" #include "esphome/core/helpers.h" +#include #ifdef USE_ESP32 #include "driver/timer.h" #include "esp_err.h" @@ -569,8 +570,8 @@ void OpenTherm::debug_data(OpenthermData &data) { to_string(data.f88()).c_str()); } void OpenTherm::debug_error(OpenThermError &error) const { - ESP_LOGD(TAG, "data: %s; clock: %s; capture: %s; bit_pos: %s", format_hex(error.data).c_str(), - to_string(clock_).c_str(), format_bin(error.capture).c_str(), to_string(error.bit_pos).c_str()); + ESP_LOGD(TAG, "data: 0x%08" PRIx32 "; clock: %u; capture: 0x%08" PRIx32 "; bit_pos: %u", error.data, this->clock_, + error.capture, error.bit_pos); } float OpenthermData::f88() { return ((float) this->s16()) / 256.0; } From 7fa04b6c25e75c995406ad66d6e5653ec8ec69f7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:23:33 -1000 Subject: [PATCH 126/302] [a01nyub] Use stack buffer for hex formatting in error logging (#12727) --- esphome/components/a01nyub/a01nyub.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esphome/components/a01nyub/a01nyub.cpp b/esphome/components/a01nyub/a01nyub.cpp index d0bc89a0c9..210c3557b3 100644 --- a/esphome/components/a01nyub/a01nyub.cpp +++ b/esphome/components/a01nyub/a01nyub.cpp @@ -30,7 +30,9 @@ void A01nyubComponent::check_buffer_() { ESP_LOGV(TAG, "Distance from sensor: %f mm, %f m", distance, meters); this->publish_state(meters); } else { - ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str()); + char hex_buf[format_hex_pretty_size(4)]; + ESP_LOGW(TAG, "Invalid data read from sensor: %s", + format_hex_pretty_to(hex_buf, this->buffer_.data(), this->buffer_.size())); } } else { ESP_LOGW(TAG, "checksum failed: %02x != %02x", checksum, this->buffer_[3]); From 17033436947c4b72532311409793556a5fd6886d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:24:30 -1000 Subject: [PATCH 127/302] [a02yyuw] Use stack buffer for hex formatting in error logging (#12728) --- esphome/components/a02yyuw/a02yyuw.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esphome/components/a02yyuw/a02yyuw.cpp b/esphome/components/a02yyuw/a02yyuw.cpp index ee378c3283..a2aad0cef1 100644 --- a/esphome/components/a02yyuw/a02yyuw.cpp +++ b/esphome/components/a02yyuw/a02yyuw.cpp @@ -29,7 +29,9 @@ void A02yyuwComponent::check_buffer_() { ESP_LOGV(TAG, "Distance from sensor: %f mm", distance); this->publish_state(distance); } else { - ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str()); + char hex_buf[format_hex_pretty_size(4)]; + ESP_LOGW(TAG, "Invalid data read from sensor: %s", + format_hex_pretty_to(hex_buf, this->buffer_.data(), this->buffer_.size())); } } else { ESP_LOGW(TAG, "checksum failed: %02x != %02x", checksum, this->buffer_[3]); From 30efd7fb0732a947ad93b4822f7841b205f0fe6e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:24:47 -1000 Subject: [PATCH 128/302] [jsn_sr04t] Use stack buffer for hex formatting in error logging (#12729) --- esphome/components/jsn_sr04t/jsn_sr04t.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esphome/components/jsn_sr04t/jsn_sr04t.cpp b/esphome/components/jsn_sr04t/jsn_sr04t.cpp index 84181dac48..6fd8b1bd65 100644 --- a/esphome/components/jsn_sr04t/jsn_sr04t.cpp +++ b/esphome/components/jsn_sr04t/jsn_sr04t.cpp @@ -39,7 +39,9 @@ void Jsnsr04tComponent::check_buffer_() { ESP_LOGV(TAG, "Distance from sensor: %umm, %.3fm", distance, meters); this->publish_state(meters); } else { - ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str()); + char hex_buf[format_hex_pretty_size(4)]; + ESP_LOGW(TAG, "Invalid data read from sensor: %s", + format_hex_pretty_to(hex_buf, this->buffer_.data(), this->buffer_.size())); } } else { ESP_LOGW(TAG, "checksum failed: %02x != %02x", checksum, this->buffer_[3]); From c8241b01223eb320fed49ef0fe2f817fe406317a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:25:02 -1000 Subject: [PATCH 129/302] [sonoff_d1] Use stack buffer for hex formatting in logging (#12730) --- esphome/components/sonoff_d1/sonoff_d1.cpp | 23 ++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/esphome/components/sonoff_d1/sonoff_d1.cpp b/esphome/components/sonoff_d1/sonoff_d1.cpp index cd09f31dd7..0ecde83b8b 100644 --- a/esphome/components/sonoff_d1/sonoff_d1.cpp +++ b/esphome/components/sonoff_d1/sonoff_d1.cpp @@ -42,12 +42,17 @@ * M 6C - CRC over bytes 2 to F (Addition) \*********************************************************************************************/ #include "sonoff_d1.h" +#include "esphome/core/helpers.h" namespace esphome { namespace sonoff_d1 { static const char *const TAG = "sonoff_d1"; +// Protocol constants +static constexpr size_t SONOFF_D1_ACK_SIZE = 7; +static constexpr size_t SONOFF_D1_MAX_CMD_SIZE = 17; + uint8_t SonoffD1Output::calc_checksum_(const uint8_t *cmd, const size_t len) { uint8_t crc = 0; for (size_t i = 2; i < len - 1; i++) { @@ -86,8 +91,11 @@ bool SonoffD1Output::read_command_(uint8_t *cmd, size_t &len) { // Read a minimal packet if (this->read_array(cmd, 6)) { +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(6)]; ESP_LOGV(TAG, "[%04d] Reading from dimmer:", this->write_count_); - ESP_LOGV(TAG, "[%04d] %s", this->write_count_, format_hex_pretty(cmd, 6).c_str()); + ESP_LOGV(TAG, "[%04d] %s", this->write_count_, format_hex_pretty_to(hex_buf, cmd, 6)); +#endif if (cmd[0] != 0xAA || cmd[1] != 0x55) { ESP_LOGW(TAG, "[%04d] RX: wrong header (%x%x, must be AA55)", this->write_count_, cmd[0], cmd[1]); @@ -101,7 +109,10 @@ bool SonoffD1Output::read_command_(uint8_t *cmd, size_t &len) { return false; } if (this->read_array(&cmd[6], cmd[5] + 1 /*checksum suffix*/)) { - ESP_LOGV(TAG, "[%04d] %s", this->write_count_, format_hex_pretty(&cmd[6], cmd[5] + 1).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf2[format_hex_pretty_size(SONOFF_D1_MAX_CMD_SIZE)]; + ESP_LOGV(TAG, "[%04d] %s", this->write_count_, format_hex_pretty_to(hex_buf2, &cmd[6], cmd[5] + 1)); +#endif // Check the checksum uint8_t valid_checksum = this->calc_checksum_(cmd, cmd[5] + 7); @@ -145,9 +156,10 @@ bool SonoffD1Output::read_ack_(const uint8_t *cmd, const size_t len) { ESP_LOGD(TAG, "[%04d] Acknowledge received", this->write_count_); return true; } else { + char hex_buf[format_hex_pretty_size(SONOFF_D1_ACK_SIZE)]; ESP_LOGW(TAG, "[%04d] Unexpected acknowledge received (possible clash of RF/HA commands), expected ack was:", this->write_count_); - ESP_LOGW(TAG, "[%04d] %s", this->write_count_, format_hex_pretty(ref_buffer, sizeof(ref_buffer)).c_str()); + ESP_LOGW(TAG, "[%04d] %s", this->write_count_, format_hex_pretty_to(hex_buf, ref_buffer, sizeof(ref_buffer))); } return false; } @@ -174,8 +186,11 @@ bool SonoffD1Output::write_command_(uint8_t *cmd, const size_t len, bool needs_a // 2. UART command initiated by this component can clash with a command initiated by RF uint32_t retries = 10; do { +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(SONOFF_D1_MAX_CMD_SIZE)]; ESP_LOGV(TAG, "[%04d] Writing to the dimmer:", this->write_count_); - ESP_LOGV(TAG, "[%04d] %s", this->write_count_, format_hex_pretty(cmd, len).c_str()); + ESP_LOGV(TAG, "[%04d] %s", this->write_count_, format_hex_pretty_to(hex_buf, cmd, len)); +#endif this->write_array(cmd, len); this->write_count_++; if (!needs_ack) From 56ed5af27df7119adf0da80c18d4ea24be76a4b3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:26:14 -1000 Subject: [PATCH 130/302] [nextion] Use stack buffers for hex formatting in upload logging (#12733) --- .../nextion/nextion_upload_arduino.cpp | 17 ++++++++++++----- .../components/nextion/nextion_upload_esp32.cpp | 17 ++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/esphome/components/nextion/nextion_upload_arduino.cpp b/esphome/components/nextion/nextion_upload_arduino.cpp index dfbb5a497e..d210bad004 100644 --- a/esphome/components/nextion/nextion_upload_arduino.cpp +++ b/esphome/components/nextion/nextion_upload_arduino.cpp @@ -7,12 +7,14 @@ #include "esphome/components/network/util.h" #include "esphome/core/application.h" #include "esphome/core/defines.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #include "esphome/core/util.h" namespace esphome { namespace nextion { static const char *const TAG = "nextion.upload.arduino"; +static constexpr size_t NEXTION_MAX_RESPONSE_LOG_BYTES = 16; // Followed guide // https://unofficialnextion.com/t/nextion-upload-protocol-v1-2-the-fast-one/1044/2 @@ -89,8 +91,10 @@ int Nextion::upload_by_chunks_(HTTPClient &http_client, uint32_t &range_start) { EspClass::getFreeHeap()); upload_first_chunk_sent_ = true; if (recv_string[0] == 0x08 && recv_string.size() == 5) { // handle partial upload request - ESP_LOGD(TAG, "Recv: [%s]", - format_hex_pretty(reinterpret_cast(recv_string.data()), recv_string.size()).c_str()); + char hex_buf[format_hex_pretty_size(NEXTION_MAX_RESPONSE_LOG_BYTES)]; + ESP_LOGD( + TAG, "Recv: [%s]", + format_hex_pretty_to(hex_buf, reinterpret_cast(recv_string.data()), recv_string.size())); uint32_t result = 0; for (int j = 0; j < 4; ++j) { result += static_cast(recv_string[j + 1]) << (8 * j); @@ -107,8 +111,10 @@ int Nextion::upload_by_chunks_(HTTPClient &http_client, uint32_t &range_start) { buffer = nullptr; return range_end + 1; } else if (recv_string[0] != 0x05 and recv_string[0] != 0x08) { // 0x05 == "ok" - ESP_LOGE(TAG, "Invalid response: [%s]", - format_hex_pretty(reinterpret_cast(recv_string.data()), recv_string.size()).c_str()); + char hex_buf[format_hex_pretty_size(NEXTION_MAX_RESPONSE_LOG_BYTES)]; + ESP_LOGE( + TAG, "Invalid response: [%s]", + format_hex_pretty_to(hex_buf, reinterpret_cast(recv_string.data()), recv_string.size())); // Deallocate buffer allocator.deallocate(buffer, 4096); buffer = nullptr; @@ -274,8 +280,9 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) { this->recv_ret_string_(response, 5000, true); // This can take some time to return // The Nextion display will, if it's ready to accept data, send a 0x05 byte. + char hex_buf[format_hex_pretty_size(NEXTION_MAX_RESPONSE_LOG_BYTES)]; ESP_LOGD(TAG, "Upload resp: [%s] %zu B", - format_hex_pretty(reinterpret_cast(response.data()), response.size()).c_str(), + format_hex_pretty_to(hex_buf, reinterpret_cast(response.data()), response.size()), response.length()); ESP_LOGV(TAG, "Heap: %" PRIu32, EspClass::getFreeHeap()); diff --git a/esphome/components/nextion/nextion_upload_esp32.cpp b/esphome/components/nextion/nextion_upload_esp32.cpp index 29a7e3c8d7..712fa8e78e 100644 --- a/esphome/components/nextion/nextion_upload_esp32.cpp +++ b/esphome/components/nextion/nextion_upload_esp32.cpp @@ -9,12 +9,14 @@ #include "esphome/components/network/util.h" #include "esphome/core/application.h" #include "esphome/core/defines.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #include "esphome/core/util.h" namespace esphome { namespace nextion { static const char *const TAG = "nextion.upload.esp32"; +static constexpr size_t NEXTION_MAX_RESPONSE_LOG_BYTES = 16; // Followed guide // https://unofficialnextion.com/t/nextion-upload-protocol-v1-2-the-fast-one/1044/2 @@ -110,8 +112,10 @@ int Nextion::upload_by_chunks_(esp_http_client_handle_t http_client, uint32_t &r #endif upload_first_chunk_sent_ = true; if (recv_string[0] == 0x08 && recv_string.size() == 5) { // handle partial upload request - ESP_LOGD(TAG, "Recv: [%s]", - format_hex_pretty(reinterpret_cast(recv_string.data()), recv_string.size()).c_str()); + char hex_buf[format_hex_pretty_size(NEXTION_MAX_RESPONSE_LOG_BYTES)]; + ESP_LOGD( + TAG, "Recv: [%s]", + format_hex_pretty_to(hex_buf, reinterpret_cast(recv_string.data()), recv_string.size())); uint32_t result = 0; for (int j = 0; j < 4; ++j) { result += static_cast(recv_string[j + 1]) << (8 * j); @@ -128,8 +132,10 @@ int Nextion::upload_by_chunks_(esp_http_client_handle_t http_client, uint32_t &r buffer = nullptr; return range_end + 1; } else if (recv_string[0] != 0x05 and recv_string[0] != 0x08) { // 0x05 == "ok" - ESP_LOGE(TAG, "Invalid response: [%s]", - format_hex_pretty(reinterpret_cast(recv_string.data()), recv_string.size()).c_str()); + char hex_buf[format_hex_pretty_size(NEXTION_MAX_RESPONSE_LOG_BYTES)]; + ESP_LOGE( + TAG, "Invalid response: [%s]", + format_hex_pretty_to(hex_buf, reinterpret_cast(recv_string.data()), recv_string.size())); // Deallocate buffer allocator.deallocate(buffer, 4096); buffer = nullptr; @@ -287,8 +293,9 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) { this->recv_ret_string_(response, 5000, true); // This can take some time to return // The Nextion display will, if it's ready to accept data, send a 0x05 byte. + char hex_buf[format_hex_pretty_size(NEXTION_MAX_RESPONSE_LOG_BYTES)]; ESP_LOGD(TAG, "Upload resp: [%s] %zu B", - format_hex_pretty(reinterpret_cast(response.data()), response.size()).c_str(), + format_hex_pretty_to(hex_buf, reinterpret_cast(response.data()), response.size()), response.length()); ESP_LOGV(TAG, "Heap: %" PRIu32, esp_get_free_heap_size()); From 7d21411ca43744bad02365ea9235553fe0458bd0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:27:00 -1000 Subject: [PATCH 131/302] [epaper_spi] Use stack buffer for hex formatting in command logging (#12734) --- esphome/components/epaper_spi/epaper_spi.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/esphome/components/epaper_spi/epaper_spi.cpp b/esphome/components/epaper_spi/epaper_spi.cpp index b2e58694c8..4e6b4a7fd6 100644 --- a/esphome/components/epaper_spi/epaper_spi.cpp +++ b/esphome/components/epaper_spi/epaper_spi.cpp @@ -7,6 +7,7 @@ namespace esphome::epaper_spi { static const char *const TAG = "epaper_spi"; +static constexpr size_t EPAPER_MAX_CMD_LOG_BYTES = 128; static constexpr const char *const EPAPER_STATE_STRINGS[] = { "IDLE", "UPDATE", "RESET", "RESET_END", "SHOULD_WAIT", "INITIALISE", @@ -68,8 +69,11 @@ void EPaperBase::data(uint8_t value) { // The command is the first byte, length is the length of data only in the second byte, followed by the data. // [COMMAND, LENGTH, DATA...] void EPaperBase::cmd_data(uint8_t command, const uint8_t *ptr, size_t length) { +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(EPAPER_MAX_CMD_LOG_BYTES)]; ESP_LOGV(TAG, "Command: 0x%02X, Length: %d, Data: %s", command, length, - format_hex_pretty(ptr, length, '.', false).c_str()); + format_hex_pretty_to(hex_buf, ptr, length, '.')); +#endif this->dc_pin_->digital_write(false); this->enable(); From e2f45c590e5e2b833e8e4acb061f1ff99dd49879 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:28:38 -1000 Subject: [PATCH 132/302] [esp32_improv] Use stack buffer for hex formatting in verbose logging (#12737) --- .../components/esp32_improv/esp32_improv_component.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/esphome/components/esp32_improv/esp32_improv_component.cpp b/esphome/components/esp32_improv/esp32_improv_component.cpp index 05a30e2941..4a6aec1892 100644 --- a/esphome/components/esp32_improv/esp32_improv_component.cpp +++ b/esphome/components/esp32_improv/esp32_improv_component.cpp @@ -4,6 +4,7 @@ #include "esphome/components/esp32_ble/ble.h" #include "esphome/components/esp32_ble_server/ble_2902.h" #include "esphome/core/application.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #ifdef USE_ESP32 @@ -14,6 +15,7 @@ namespace esp32_improv { using namespace bytebuffer; static const char *const TAG = "esp32_improv.component"; +static constexpr size_t IMPROV_MAX_LOG_BYTES = 128; static const char *const ESPHOME_MY_LINK = "https://my.home-assistant.io/redirect/config_flow_start?domain=esphome"; static constexpr uint16_t STOP_ADVERTISING_DELAY = 10000; // Delay (ms) before stopping service to allow BLE clients to read the final state @@ -314,7 +316,11 @@ void ESP32ImprovComponent::dump_config() { void ESP32ImprovComponent::process_incoming_data_() { uint8_t length = this->incoming_data_[1]; - ESP_LOGV(TAG, "Processing bytes - %s", format_hex_pretty(this->incoming_data_).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(IMPROV_MAX_LOG_BYTES)]; + ESP_LOGV(TAG, "Processing bytes - %s", + format_hex_pretty_to(hex_buf, this->incoming_data_.data(), this->incoming_data_.size())); +#endif if (this->incoming_data_.size() - 3 == length) { this->set_error_(improv::ERROR_NONE); improv::ImprovCommand command = improv::parse_improv_data(this->incoming_data_); From 916370a943a1ff7d4a65b6f385497dd85a863033 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 15:42:56 -1000 Subject: [PATCH 133/302] [gpio] Avoid heap allocation in dump_summary (#12760) --- esphome/components/ch422g/ch422g.cpp | 4 +- esphome/components/ch422g/ch422g.h | 2 +- esphome/components/esp32/gpio.cpp | 6 +- esphome/components/esp32/gpio.h | 2 +- esphome/components/esp8266/gpio.cpp | 6 +- esphome/components/esp8266/gpio.h | 2 +- esphome/components/hlw8012/hlw8012.cpp | 6 +- esphome/components/host/gpio.cpp | 6 +- esphome/components/host/gpio.h | 2 +- esphome/components/libretiny/gpio_arduino.cpp | 6 +- esphome/components/libretiny/gpio_arduino.h | 2 +- esphome/components/max6956/max6956.cpp | 6 +- esphome/components/max6956/max6956.h | 2 +- esphome/components/mcp23016/mcp23016.cpp | 6 +- esphome/components/mcp23016/mcp23016.h | 2 +- .../mcp23xxx_base/mcp23xxx_base.cpp | 4 +- .../components/mcp23xxx_base/mcp23xxx_base.h | 2 +- esphome/components/mpr121/mpr121.cpp | 6 +- esphome/components/mpr121/mpr121.h | 2 +- esphome/components/pca6416a/pca6416a.cpp | 6 +- esphome/components/pca6416a/pca6416a.h | 2 +- esphome/components/pca9554/pca9554.cpp | 6 +- esphome/components/pca9554/pca9554.h | 2 +- esphome/components/pcf8574/pcf8574.cpp | 6 +- esphome/components/pcf8574/pcf8574.h | 2 +- .../components/pi4ioe5v6408/pi4ioe5v6408.cpp | 4 +- .../components/pi4ioe5v6408/pi4ioe5v6408.h | 2 +- esphome/components/rp2040/gpio.cpp | 6 +- esphome/components/rp2040/gpio.h | 2 +- esphome/components/sn74hc165/sn74hc165.cpp | 4 +- esphome/components/sn74hc165/sn74hc165.h | 2 +- esphome/components/sn74hc595/sn74hc595.cpp | 4 +- esphome/components/sn74hc595/sn74hc595.h | 2 +- esphome/components/spi/spi.cpp | 6 +- esphome/components/spi/spi.h | 6 +- esphome/components/sx1509/sx1509_gpio_pin.cpp | 6 +- esphome/components/sx1509/sx1509_gpio_pin.h | 2 +- esphome/components/tca9555/tca9555.cpp | 4 +- esphome/components/tca9555/tca9555.h | 2 +- .../waveshare_epaper/waveshare_213v3.cpp | 8 +-- esphome/components/weikai/weikai.cpp | 6 +- esphome/components/weikai/weikai.h | 2 +- esphome/components/xl9535/xl9535.cpp | 4 +- esphome/components/xl9535/xl9535.h | 2 +- esphome/components/zephyr/gpio.cpp | 6 +- esphome/components/zephyr/gpio.h | 2 +- esphome/core/gpio.cpp | 24 +++++++ esphome/core/gpio.h | 66 +++++++++++++++++-- 48 files changed, 168 insertions(+), 102 deletions(-) create mode 100644 esphome/core/gpio.cpp diff --git a/esphome/components/ch422g/ch422g.cpp b/esphome/components/ch422g/ch422g.cpp index 9a4e342525..f47b67da6f 100644 --- a/esphome/components/ch422g/ch422g.cpp +++ b/esphome/components/ch422g/ch422g.cpp @@ -128,7 +128,9 @@ void CH422GGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this-> bool CH422GGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; } void CH422GGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value ^ this->inverted_); } -std::string CH422GGPIOPin::dump_summary() const { return str_sprintf("EXIO%u via CH422G", pin_); } +size_t CH422GGPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "EXIO%u via CH422G", this->pin_); +} void CH422GGPIOPin::set_flags(gpio::Flags flags) { flags_ = flags; this->parent_->pin_mode(this->pin_, flags); diff --git a/esphome/components/ch422g/ch422g.h b/esphome/components/ch422g/ch422g.h index 1193a3db27..8ed63db90a 100644 --- a/esphome/components/ch422g/ch422g.h +++ b/esphome/components/ch422g/ch422g.h @@ -50,7 +50,7 @@ class CH422GGPIOPin : public GPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_parent(CH422GComponent *parent) { parent_ = parent; } void set_pin(uint8_t pin) { pin_ = pin; } diff --git a/esphome/components/esp32/gpio.cpp b/esphome/components/esp32/gpio.cpp index a98245b889..4b53d3a172 100644 --- a/esphome/components/esp32/gpio.cpp +++ b/esphome/components/esp32/gpio.cpp @@ -97,10 +97,8 @@ void ESP32InternalGPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpi gpio_isr_handler_add(this->get_pin_num(), func, arg); } -std::string ESP32InternalGPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "GPIO%" PRIu32, static_cast(this->pin_)); - return buffer; +size_t ESP32InternalGPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "GPIO%" PRIu32, static_cast(this->pin_)); } void ESP32InternalGPIOPin::setup() { diff --git a/esphome/components/esp32/gpio.h b/esphome/components/esp32/gpio.h index d30f4bdcba..3c13bd9b4f 100644 --- a/esphome/components/esp32/gpio.h +++ b/esphome/components/esp32/gpio.h @@ -24,7 +24,7 @@ class ESP32InternalGPIOPin : public InternalGPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void detach_interrupt() const override; ISRInternalGPIOPin to_isr() const override; uint8_t get_pin() const override { return this->pin_; } diff --git a/esphome/components/esp8266/gpio.cpp b/esphome/components/esp8266/gpio.cpp index 124df39ce3..7a5ee08984 100644 --- a/esphome/components/esp8266/gpio.cpp +++ b/esphome/components/esp8266/gpio.cpp @@ -98,10 +98,8 @@ void ESP8266GPIOPin::pin_mode(gpio::Flags flags) { pinMode(pin_, flags_to_mode(flags, pin_)); // NOLINT } -std::string ESP8266GPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "GPIO%u", pin_); - return buffer; +size_t ESP8266GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "GPIO%u", this->pin_); } bool ESP8266GPIOPin::digital_read() { diff --git a/esphome/components/esp8266/gpio.h b/esphome/components/esp8266/gpio.h index 213a5c54be..ff149abfbe 100644 --- a/esphome/components/esp8266/gpio.h +++ b/esphome/components/esp8266/gpio.h @@ -17,7 +17,7 @@ class ESP8266GPIOPin : public InternalGPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void detach_interrupt() const override; ISRInternalGPIOPin to_isr() const override; uint8_t get_pin() const override { return pin_; } diff --git a/esphome/components/hlw8012/hlw8012.cpp b/esphome/components/hlw8012/hlw8012.cpp index 73696bd2a5..70a05e4f72 100644 --- a/esphome/components/hlw8012/hlw8012.cpp +++ b/esphome/components/hlw8012/hlw8012.cpp @@ -34,9 +34,9 @@ void HLW8012Component::setup() { } void HLW8012Component::dump_config() { ESP_LOGCONFIG(TAG, "HLW8012:"); - LOG_PIN(" SEL Pin: ", this->sel_pin_) - LOG_PIN(" CF Pin: ", this->cf_pin_) - LOG_PIN(" CF1 Pin: ", this->cf1_pin_) + LOG_PIN(" SEL Pin: ", this->sel_pin_); + LOG_PIN(" CF Pin: ", this->cf_pin_); + LOG_PIN(" CF1 Pin: ", this->cf1_pin_); ESP_LOGCONFIG(TAG, " Change measurement mode every %" PRIu32 "\n" " Current resistor: %.1f mΩ\n" diff --git a/esphome/components/host/gpio.cpp b/esphome/components/host/gpio.cpp index e46f158513..f99b82bcc2 100644 --- a/esphome/components/host/gpio.cpp +++ b/esphome/components/host/gpio.cpp @@ -25,11 +25,7 @@ void HostGPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::Interr } void HostGPIOPin::pin_mode(gpio::Flags flags) { ESP_LOGD(TAG, "Setting pin %d mode to %02X", pin_, (uint32_t) flags); } -std::string HostGPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "GPIO%u", pin_); - return buffer; -} +size_t HostGPIOPin::dump_summary(char *buffer, size_t len) const { return snprintf(buffer, len, "GPIO%u", this->pin_); } bool HostGPIOPin::digital_read() { return inverted_; } void HostGPIOPin::digital_write(bool value) { diff --git a/esphome/components/host/gpio.h b/esphome/components/host/gpio.h index ae677291b9..ea6b13f436 100644 --- a/esphome/components/host/gpio.h +++ b/esphome/components/host/gpio.h @@ -17,7 +17,7 @@ class HostGPIOPin : public InternalGPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void detach_interrupt() const override; ISRInternalGPIOPin to_isr() const override; uint8_t get_pin() const override { return pin_; } diff --git a/esphome/components/libretiny/gpio_arduino.cpp b/esphome/components/libretiny/gpio_arduino.cpp index 7a1e014ea4..0b14c77cf2 100644 --- a/esphome/components/libretiny/gpio_arduino.cpp +++ b/esphome/components/libretiny/gpio_arduino.cpp @@ -63,10 +63,8 @@ void ArduinoInternalGPIOPin::pin_mode(gpio::Flags flags) { pinMode(pin_, flags_to_mode(flags)); // NOLINT } -std::string ArduinoInternalGPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%u", pin_); - return buffer; +size_t ArduinoInternalGPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u", this->pin_); } bool ArduinoInternalGPIOPin::digital_read() { diff --git a/esphome/components/libretiny/gpio_arduino.h b/esphome/components/libretiny/gpio_arduino.h index 3674748c18..30c7c33869 100644 --- a/esphome/components/libretiny/gpio_arduino.h +++ b/esphome/components/libretiny/gpio_arduino.h @@ -16,7 +16,7 @@ class ArduinoInternalGPIOPin : public InternalGPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void detach_interrupt() const override; ISRInternalGPIOPin to_isr() const override; uint8_t get_pin() const override { return pin_; } diff --git a/esphome/components/max6956/max6956.cpp b/esphome/components/max6956/max6956.cpp index a377a1a192..13fe5a5323 100644 --- a/esphome/components/max6956/max6956.cpp +++ b/esphome/components/max6956/max6956.cpp @@ -161,10 +161,8 @@ void MAX6956GPIOPin::setup() { pin_mode(flags_); } void MAX6956GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); } bool MAX6956GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; } void MAX6956GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); } -std::string MAX6956GPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%u via Max6956", pin_); - return buffer; +size_t MAX6956GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via Max6956", this->pin_); } } // namespace max6956 diff --git a/esphome/components/max6956/max6956.h b/esphome/components/max6956/max6956.h index 0a1fd5e4b5..0c609b0b43 100644 --- a/esphome/components/max6956/max6956.h +++ b/esphome/components/max6956/max6956.h @@ -76,7 +76,7 @@ class MAX6956GPIOPin : public GPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_parent(MAX6956 *parent) { parent_ = parent; } void set_pin(uint8_t pin) { pin_ = pin; } diff --git a/esphome/components/mcp23016/mcp23016.cpp b/esphome/components/mcp23016/mcp23016.cpp index be86cb2256..87c2668962 100644 --- a/esphome/components/mcp23016/mcp23016.cpp +++ b/esphome/components/mcp23016/mcp23016.cpp @@ -99,10 +99,8 @@ void MCP23016GPIOPin::setup() { pin_mode(flags_); } void MCP23016GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); } bool MCP23016GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; } void MCP23016GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); } -std::string MCP23016GPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%u via MCP23016", pin_); - return buffer; +size_t MCP23016GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via MCP23016", this->pin_); } } // namespace mcp23016 diff --git a/esphome/components/mcp23016/mcp23016.h b/esphome/components/mcp23016/mcp23016.h index 781c207de0..c2bc885c95 100644 --- a/esphome/components/mcp23016/mcp23016.h +++ b/esphome/components/mcp23016/mcp23016.h @@ -60,7 +60,7 @@ class MCP23016GPIOPin : public GPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_parent(MCP23016 *parent) { parent_ = parent; } void set_pin(uint8_t pin) { pin_ = pin; } diff --git a/esphome/components/mcp23xxx_base/mcp23xxx_base.cpp b/esphome/components/mcp23xxx_base/mcp23xxx_base.cpp index 81324e794f..302f6b8280 100644 --- a/esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +++ b/esphome/components/mcp23xxx_base/mcp23xxx_base.cpp @@ -16,8 +16,8 @@ template bool MCP23XXXGPIOPin::digital_read() { template void MCP23XXXGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); } -template std::string MCP23XXXGPIOPin::dump_summary() const { - return str_snprintf("%u via MCP23XXX", 15, pin_); +template size_t MCP23XXXGPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via MCP23XXX", this->pin_); } template class MCP23XXXGPIOPin<8>; diff --git a/esphome/components/mcp23xxx_base/mcp23xxx_base.h b/esphome/components/mcp23xxx_base/mcp23xxx_base.h index cf0ef5d41c..fb992466d5 100644 --- a/esphome/components/mcp23xxx_base/mcp23xxx_base.h +++ b/esphome/components/mcp23xxx_base/mcp23xxx_base.h @@ -36,7 +36,7 @@ template class MCP23XXXGPIOPin : public GPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_parent(MCP23XXXBase *parent) { parent_ = parent; } void set_pin(uint8_t pin) { pin_ = pin; } diff --git a/esphome/components/mpr121/mpr121.cpp b/esphome/components/mpr121/mpr121.cpp index 5a8a8e7205..4b358e384c 100644 --- a/esphome/components/mpr121/mpr121.cpp +++ b/esphome/components/mpr121/mpr121.cpp @@ -153,10 +153,8 @@ void MPR121GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_ - 4, value != this->inverted_); } -std::string MPR121GPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "ELE%u on MPR121", this->pin_); - return buffer; +size_t MPR121GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "ELE%u on MPR121", this->pin_); } } // namespace mpr121 diff --git a/esphome/components/mpr121/mpr121.h b/esphome/components/mpr121/mpr121.h index 6dd2c38309..085018fff0 100644 --- a/esphome/components/mpr121/mpr121.h +++ b/esphome/components/mpr121/mpr121.h @@ -109,7 +109,7 @@ class MPR121GPIOPin : public GPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_parent(MPR121Component *parent) { this->parent_ = parent; } void set_pin(uint8_t pin) { this->pin_ = pin; } diff --git a/esphome/components/pca6416a/pca6416a.cpp b/esphome/components/pca6416a/pca6416a.cpp index c0056e780b..909bac5f05 100644 --- a/esphome/components/pca6416a/pca6416a.cpp +++ b/esphome/components/pca6416a/pca6416a.cpp @@ -180,10 +180,8 @@ void PCA6416AGPIOPin::setup() { pin_mode(flags_); } void PCA6416AGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); } bool PCA6416AGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; } void PCA6416AGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); } -std::string PCA6416AGPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%u via PCA6416A", pin_); - return buffer; +size_t PCA6416AGPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via PCA6416A", this->pin_); } } // namespace pca6416a diff --git a/esphome/components/pca6416a/pca6416a.h b/esphome/components/pca6416a/pca6416a.h index 10a4a64e9b..138a51cc20 100644 --- a/esphome/components/pca6416a/pca6416a.h +++ b/esphome/components/pca6416a/pca6416a.h @@ -52,7 +52,7 @@ class PCA6416AGPIOPin : public GPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_parent(PCA6416AComponent *parent) { parent_ = parent; } void set_pin(uint8_t pin) { pin_ = pin; } diff --git a/esphome/components/pca9554/pca9554.cpp b/esphome/components/pca9554/pca9554.cpp index e8d49f66e2..a6f9c2396c 100644 --- a/esphome/components/pca9554/pca9554.cpp +++ b/esphome/components/pca9554/pca9554.cpp @@ -129,10 +129,8 @@ void PCA9554GPIOPin::setup() { pin_mode(flags_); } void PCA9554GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); } bool PCA9554GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; } void PCA9554GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); } -std::string PCA9554GPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%u via PCA9554", pin_); - return buffer; +size_t PCA9554GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via PCA9554", this->pin_); } } // namespace pca9554 diff --git a/esphome/components/pca9554/pca9554.h b/esphome/components/pca9554/pca9554.h index 7b356b4068..bf752e50c9 100644 --- a/esphome/components/pca9554/pca9554.h +++ b/esphome/components/pca9554/pca9554.h @@ -59,7 +59,7 @@ class PCA9554GPIOPin : public GPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_parent(PCA9554Component *parent) { parent_ = parent; } void set_pin(uint8_t pin) { pin_ = pin; } diff --git a/esphome/components/pcf8574/pcf8574.cpp b/esphome/components/pcf8574/pcf8574.cpp index 72d8865d7f..15418bfee5 100644 --- a/esphome/components/pcf8574/pcf8574.cpp +++ b/esphome/components/pcf8574/pcf8574.cpp @@ -104,10 +104,8 @@ void PCF8574GPIOPin::setup() { pin_mode(flags_); } void PCF8574GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); } bool PCF8574GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; } void PCF8574GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); } -std::string PCF8574GPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%u via PCF8574", pin_); - return buffer; +size_t PCF8574GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via PCF8574", this->pin_); } } // namespace pcf8574 diff --git a/esphome/components/pcf8574/pcf8574.h b/esphome/components/pcf8574/pcf8574.h index fd1ea8af63..5203030142 100644 --- a/esphome/components/pcf8574/pcf8574.h +++ b/esphome/components/pcf8574/pcf8574.h @@ -54,7 +54,7 @@ class PCF8574GPIOPin : public GPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_parent(PCF8574Component *parent) { parent_ = parent; } void set_pin(uint8_t pin) { pin_ = pin; } diff --git a/esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp b/esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp index 517ca833e6..f3a1f013d9 100644 --- a/esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +++ b/esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp @@ -164,7 +164,9 @@ bool PI4IOE5V6408GPIOPin::digital_read() { return this->parent_->digital_read(th void PI4IOE5V6408GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); } -std::string PI4IOE5V6408GPIOPin::dump_summary() const { return str_sprintf("%u via PI4IOE5V6408", this->pin_); } +size_t PI4IOE5V6408GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via PI4IOE5V6408", this->pin_); +} } // namespace pi4ioe5v6408 } // namespace esphome diff --git a/esphome/components/pi4ioe5v6408/pi4ioe5v6408.h b/esphome/components/pi4ioe5v6408/pi4ioe5v6408.h index 82b3076fab..4dc31201ce 100644 --- a/esphome/components/pi4ioe5v6408/pi4ioe5v6408.h +++ b/esphome/components/pi4ioe5v6408/pi4ioe5v6408.h @@ -52,7 +52,7 @@ class PI4IOE5V6408GPIOPin : public GPIOPin, public Parentedpin_ = pin; } void set_inverted(bool inverted) { this->inverted_ = inverted; } diff --git a/esphome/components/rp2040/gpio.cpp b/esphome/components/rp2040/gpio.cpp index 3927815e46..2b1699f888 100644 --- a/esphome/components/rp2040/gpio.cpp +++ b/esphome/components/rp2040/gpio.cpp @@ -64,10 +64,8 @@ void RP2040GPIOPin::pin_mode(gpio::Flags flags) { pinMode(pin_, flags_to_mode(flags, pin_)); // NOLINT } -std::string RP2040GPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "GPIO%u", pin_); - return buffer; +size_t RP2040GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "GPIO%u", this->pin_); } bool RP2040GPIOPin::digital_read() { diff --git a/esphome/components/rp2040/gpio.h b/esphome/components/rp2040/gpio.h index 47a6fe17f2..a98e1dab14 100644 --- a/esphome/components/rp2040/gpio.h +++ b/esphome/components/rp2040/gpio.h @@ -18,7 +18,7 @@ class RP2040GPIOPin : public InternalGPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void detach_interrupt() const override; ISRInternalGPIOPin to_isr() const override; uint8_t get_pin() const override { return pin_; } diff --git a/esphome/components/sn74hc165/sn74hc165.cpp b/esphome/components/sn74hc165/sn74hc165.cpp index 416d9db293..718e0b86ed 100644 --- a/esphome/components/sn74hc165/sn74hc165.cpp +++ b/esphome/components/sn74hc165/sn74hc165.cpp @@ -64,7 +64,9 @@ float SN74HC165Component::get_setup_priority() const { return setup_priority::IO bool SN74HC165GPIOPin::digital_read() { return this->parent_->digital_read_(this->pin_) != this->inverted_; } -std::string SN74HC165GPIOPin::dump_summary() const { return str_snprintf("%u via SN74HC165", 18, pin_); } +size_t SN74HC165GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via SN74HC165", this->pin_); +} } // namespace sn74hc165 } // namespace esphome diff --git a/esphome/components/sn74hc165/sn74hc165.h b/esphome/components/sn74hc165/sn74hc165.h index 4684844687..5a3f3fe8ef 100644 --- a/esphome/components/sn74hc165/sn74hc165.h +++ b/esphome/components/sn74hc165/sn74hc165.h @@ -47,7 +47,7 @@ class SN74HC165GPIOPin : public GPIOPin, public Parented { void pin_mode(gpio::Flags flags) override {} bool digital_read() override; void digital_write(bool value) override{}; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_pin(uint16_t pin) { pin_ = pin; } void set_inverted(bool inverted) { inverted_ = inverted; } diff --git a/esphome/components/sn74hc595/sn74hc595.cpp b/esphome/components/sn74hc595/sn74hc595.cpp index a9ada432e4..6b5c5d9fc4 100644 --- a/esphome/components/sn74hc595/sn74hc595.cpp +++ b/esphome/components/sn74hc595/sn74hc595.cpp @@ -93,7 +93,9 @@ float SN74HC595Component::get_setup_priority() const { return setup_priority::IO void SN74HC595GPIOPin::digital_write(bool value) { this->parent_->digital_write_(this->pin_, value != this->inverted_); } -std::string SN74HC595GPIOPin::dump_summary() const { return str_snprintf("%u via SN74HC595", 18, pin_); } +size_t SN74HC595GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via SN74HC595", this->pin_); +} } // namespace sn74hc595 } // namespace esphome diff --git a/esphome/components/sn74hc595/sn74hc595.h b/esphome/components/sn74hc595/sn74hc595.h index 181015b1e6..1cf70c86b5 100644 --- a/esphome/components/sn74hc595/sn74hc595.h +++ b/esphome/components/sn74hc595/sn74hc595.h @@ -54,7 +54,7 @@ class SN74HC595GPIOPin : public GPIOPin, public Parented { void pin_mode(gpio::Flags flags) override {} bool digital_read() override { return false; } void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_pin(uint16_t pin) { pin_ = pin; } void set_inverted(bool inverted) { inverted_ = inverted; } diff --git a/esphome/components/spi/spi.cpp b/esphome/components/spi/spi.cpp index c4876d1a74..36344a6d38 100644 --- a/esphome/components/spi/spi.cpp +++ b/esphome/components/spi/spi.cpp @@ -64,9 +64,9 @@ void SPIComponent::setup() { void SPIComponent::dump_config() { ESP_LOGCONFIG(TAG, "SPI bus:"); - LOG_PIN(" CLK Pin: ", this->clk_pin_) - LOG_PIN(" SDI Pin: ", this->sdi_pin_) - LOG_PIN(" SDO Pin: ", this->sdo_pin_) + LOG_PIN(" CLK Pin: ", this->clk_pin_); + LOG_PIN(" SDI Pin: ", this->sdi_pin_); + LOG_PIN(" SDO Pin: ", this->sdo_pin_); for (size_t i = 0; i != this->data_pins_.size(); i++) { ESP_LOGCONFIG(TAG, " Data pin %u: GPIO%d", i, this->data_pins_[i]); } diff --git a/esphome/components/spi/spi.h b/esphome/components/spi/spi.h index 256cbcc65f..e237cf44f4 100644 --- a/esphome/components/spi/spi.h +++ b/esphome/components/spi/spi.h @@ -120,7 +120,11 @@ class NullPin : public GPIOPin { void digital_write(bool value) override {} - std::string dump_summary() const override { return std::string(); } + size_t dump_summary(char *buffer, size_t len) const override { + if (len > 0) + buffer[0] = '\0'; + return 0; + } protected: static GPIOPin *const NULL_PIN; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) diff --git a/esphome/components/sx1509/sx1509_gpio_pin.cpp b/esphome/components/sx1509/sx1509_gpio_pin.cpp index a74c8b60b8..41a99eba4b 100644 --- a/esphome/components/sx1509/sx1509_gpio_pin.cpp +++ b/esphome/components/sx1509/sx1509_gpio_pin.cpp @@ -12,10 +12,8 @@ void SX1509GPIOPin::setup() { pin_mode(flags_); } void SX1509GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); } bool SX1509GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; } void SX1509GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); } -std::string SX1509GPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%u via sx1509", this->pin_); - return buffer; +size_t SX1509GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via sx1509", this->pin_); } } // namespace sx1509 diff --git a/esphome/components/sx1509/sx1509_gpio_pin.h b/esphome/components/sx1509/sx1509_gpio_pin.h index eb9207e882..5903af9d12 100644 --- a/esphome/components/sx1509/sx1509_gpio_pin.h +++ b/esphome/components/sx1509/sx1509_gpio_pin.h @@ -13,7 +13,7 @@ class SX1509GPIOPin : public GPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_parent(SX1509Component *parent) { this->parent_ = parent; } void set_pin(uint8_t pin) { this->pin_ = pin; } diff --git a/esphome/components/tca9555/tca9555.cpp b/esphome/components/tca9555/tca9555.cpp index c3449ce254..376de6a370 100644 --- a/esphome/components/tca9555/tca9555.cpp +++ b/esphome/components/tca9555/tca9555.cpp @@ -138,7 +138,9 @@ void TCA9555GPIOPin::setup() { this->pin_mode(this->flags_); } void TCA9555GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); } bool TCA9555GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; } void TCA9555GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); } -std::string TCA9555GPIOPin::dump_summary() const { return str_sprintf("%u via TCA9555", this->pin_); } +size_t TCA9555GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via TCA9555", this->pin_); +} } // namespace tca9555 } // namespace esphome diff --git a/esphome/components/tca9555/tca9555.h b/esphome/components/tca9555/tca9555.h index 0c236ae4e3..9f7273b1e7 100644 --- a/esphome/components/tca9555/tca9555.h +++ b/esphome/components/tca9555/tca9555.h @@ -48,7 +48,7 @@ class TCA9555GPIOPin : public GPIOPin, public Parented { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void set_pin(uint8_t pin) { this->pin_ = pin; } void set_inverted(bool inverted) { this->inverted_ = inverted; } diff --git a/esphome/components/waveshare_epaper/waveshare_213v3.cpp b/esphome/components/waveshare_epaper/waveshare_213v3.cpp index 068cb91d31..b55f3c8d26 100644 --- a/esphome/components/waveshare_epaper/waveshare_213v3.cpp +++ b/esphome/components/waveshare_epaper/waveshare_213v3.cpp @@ -177,10 +177,10 @@ uint32_t WaveshareEPaper2P13InV3::idle_timeout_() { return 5000; } void WaveshareEPaper2P13InV3::dump_config() { LOG_DISPLAY("", "Waveshare E-Paper", this) ESP_LOGCONFIG(TAG, " Model: 2.13inV3"); - LOG_PIN(" CS Pin: ", this->cs_) - LOG_PIN(" Reset Pin: ", this->reset_pin_) - LOG_PIN(" DC Pin: ", this->dc_pin_) - LOG_PIN(" Busy Pin: ", this->busy_pin_) + LOG_PIN(" CS Pin: ", this->cs_); + LOG_PIN(" Reset Pin: ", this->reset_pin_); + LOG_PIN(" DC Pin: ", this->dc_pin_); + LOG_PIN(" Busy Pin: ", this->busy_pin_); LOG_UPDATE_INTERVAL(this); } diff --git a/esphome/components/weikai/weikai.cpp b/esphome/components/weikai/weikai.cpp index ebe987cc65..3384a0572f 100644 --- a/esphome/components/weikai/weikai.cpp +++ b/esphome/components/weikai/weikai.cpp @@ -245,10 +245,8 @@ void WeikaiGPIOPin::setup() { this->pin_mode(this->flags_); } -std::string WeikaiGPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%u via WeiKai %s", this->pin_, this->parent_->get_name()); - return buffer; +size_t WeikaiGPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via WeiKai %s", this->pin_, this->parent_->get_name()); } /////////////////////////////////////////////////////////////////////////////// diff --git a/esphome/components/weikai/weikai.h b/esphome/components/weikai/weikai.h index 987278213a..a27c14106d 100644 --- a/esphome/components/weikai/weikai.h +++ b/esphome/components/weikai/weikai.h @@ -278,7 +278,7 @@ class WeikaiGPIOPin : public GPIOPin { gpio::Flags get_flags() const override { return this->flags_; } void setup() override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void pin_mode(gpio::Flags flags) override { this->parent_->set_pin_direction_(this->pin_, flags); } bool digital_read() override { return this->parent_->read_pin_val_(this->pin_) != this->inverted_; } void digital_write(bool value) override { this->parent_->write_pin_val_(this->pin_, value != this->inverted_); } diff --git a/esphome/components/xl9535/xl9535.cpp b/esphome/components/xl9535/xl9535.cpp index 958fc5eede..dd6c8188eb 100644 --- a/esphome/components/xl9535/xl9535.cpp +++ b/esphome/components/xl9535/xl9535.cpp @@ -110,7 +110,9 @@ void XL9535Component::pin_mode(uint8_t pin, gpio::Flags mode) { void XL9535GPIOPin::setup() { this->pin_mode(this->flags_); } -std::string XL9535GPIOPin::dump_summary() const { return str_snprintf("%u via XL9535", 15, this->pin_); } +size_t XL9535GPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "%u via XL9535", this->pin_); +} void XL9535GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); } bool XL9535GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; } diff --git a/esphome/components/xl9535/xl9535.h b/esphome/components/xl9535/xl9535.h index 3b511fd9b3..be0e2fbd82 100644 --- a/esphome/components/xl9535/xl9535.h +++ b/esphome/components/xl9535/xl9535.h @@ -39,7 +39,7 @@ class XL9535GPIOPin : public GPIOPin { gpio::Flags get_flags() const override { return this->flags_; } void setup() override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; diff --git a/esphome/components/zephyr/gpio.cpp b/esphome/components/zephyr/gpio.cpp index 41b983535c..8041c361cc 100644 --- a/esphome/components/zephyr/gpio.cpp +++ b/esphome/components/zephyr/gpio.cpp @@ -85,10 +85,8 @@ void ZephyrGPIOPin::pin_mode(gpio::Flags flags) { } } -std::string ZephyrGPIOPin::dump_summary() const { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "GPIO%u, P%u.%u", this->pin_, this->pin_ / 32, this->pin_ % 32); - return buffer; +size_t ZephyrGPIOPin::dump_summary(char *buffer, size_t len) const { + return snprintf(buffer, len, "GPIO%u, P%u.%u", this->pin_, this->pin_ / 32, this->pin_ % 32); } bool ZephyrGPIOPin::digital_read() { diff --git a/esphome/components/zephyr/gpio.h b/esphome/components/zephyr/gpio.h index 6e8f81857a..b405f385bc 100644 --- a/esphome/components/zephyr/gpio.h +++ b/esphome/components/zephyr/gpio.h @@ -16,7 +16,7 @@ class ZephyrGPIOPin : public InternalGPIOPin { void pin_mode(gpio::Flags flags) override; bool digital_read() override; void digital_write(bool value) override; - std::string dump_summary() const override; + size_t dump_summary(char *buffer, size_t len) const override; void detach_interrupt() const override; ISRInternalGPIOPin to_isr() const override; uint8_t get_pin() const override { return this->pin_; } diff --git a/esphome/core/gpio.cpp b/esphome/core/gpio.cpp new file mode 100644 index 0000000000..21e88b5b6d --- /dev/null +++ b/esphome/core/gpio.cpp @@ -0,0 +1,24 @@ +#include "esphome/core/gpio.h" +#include "esphome/core/log.h" + +namespace esphome { + +#ifdef USE_ESP8266 +void log_pin(const char *tag, const __FlashStringHelper *prefix, GPIOPin *pin) { + if (pin == nullptr) + return; + static constexpr size_t LOG_PIN_PREFIX_MAX_LEN = 32; + char prefix_buf[LOG_PIN_PREFIX_MAX_LEN]; + strncpy_P(prefix_buf, reinterpret_cast(prefix), sizeof(prefix_buf) - 1); + prefix_buf[sizeof(prefix_buf) - 1] = '\0'; + log_pin_with_prefix(tag, prefix_buf, pin); +} +#else +void log_pin(const char *tag, const char *prefix, GPIOPin *pin) { + if (pin == nullptr) + return; + log_pin_with_prefix(tag, prefix, pin); +} +#endif + +} // namespace esphome diff --git a/esphome/core/gpio.h b/esphome/core/gpio.h index dd6f14fef9..f2f85e18bc 100644 --- a/esphome/core/gpio.h +++ b/esphome/core/gpio.h @@ -1,13 +1,22 @@ #pragma once +#include #include +#include #include +#include "esphome/core/helpers.h" +#include "esphome/core/log.h" + namespace esphome { -#define LOG_PIN(prefix, pin) \ - if ((pin) != nullptr) { \ - ESP_LOGCONFIG(TAG, prefix "%s", (pin)->dump_summary().c_str()); \ - } +/// Maximum buffer size for dump_summary output +inline constexpr size_t GPIO_SUMMARY_MAX_LEN = 48; + +#ifdef USE_ESP8266 +#define LOG_PIN(prefix, pin) log_pin(TAG, F(prefix), pin) +#else +#define LOG_PIN(prefix, pin) log_pin(TAG, prefix, pin) +#endif // put GPIO flags in a namespace to not pollute esphome namespace namespace gpio { @@ -64,7 +73,17 @@ class GPIOPin { virtual void digital_write(bool value) = 0; - virtual std::string dump_summary() const = 0; + /// Write a summary of this pin to the provided buffer. + /// @param buffer The buffer to write to + /// @param len The size of the buffer (must be > 0) + /// @return The number of characters that would be written (excluding null terminator), + /// which may exceed len-1 if truncation occurred (snprintf semantics) + virtual size_t dump_summary(char *buffer, size_t len) const; + + /// Get a summary of this pin as a string. + /// @deprecated Use dump_summary(char*, size_t) instead. Will be removed in 2026.7.0. + ESPDEPRECATED("Override dump_summary(char*, size_t) instead. Will be removed in 2026.7.0.", "2026.1.0") + virtual std::string dump_summary() const; virtual bool is_internal() { return false; } }; @@ -103,4 +122,41 @@ class InternalGPIOPin : public GPIOPin { virtual void attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const = 0; }; +// Inline default implementations for GPIOPin virtual methods. +// These provide bridge functionality for backwards compatibility with external components. + +// Default implementation bridges to old std::string method for backwards compatibility. +inline size_t GPIOPin::dump_summary(char *buffer, size_t len) const { + if (len == 0) + return 0; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + std::string s = this->dump_summary(); +#pragma GCC diagnostic pop + size_t copy_len = std::min(s.size(), len - 1); + memcpy(buffer, s.c_str(), copy_len); + buffer[copy_len] = '\0'; + return s.size(); // Return would-be length (snprintf semantics) +} + +// Default implementation returns empty string. +// External components should override this if they haven't migrated to buffer-based version. +// Remove before 2026.7.0 +inline std::string GPIOPin::dump_summary() const { return {}; } + +// Inline helper for log_pin - allows compiler to inline into log_pin in gpio.cpp +inline void log_pin_with_prefix(const char *tag, const char *prefix, GPIOPin *pin) { + char buffer[GPIO_SUMMARY_MAX_LEN]; + size_t len = pin->dump_summary(buffer, sizeof(buffer)); + len = std::min(len, sizeof(buffer) - 1); + esp_log_printf_(ESPHOME_LOG_LEVEL_CONFIG, tag, __LINE__, "%s%.*s", prefix, (int) len, buffer); +} + +// log_pin function declarations - implementation in gpio.cpp +#ifdef USE_ESP8266 +void log_pin(const char *tag, const __FlashStringHelper *prefix, GPIOPin *pin); +#else +void log_pin(const char *tag, const char *prefix, GPIOPin *pin); +#endif + } // namespace esphome From 3cc6810be52702b0668b489c99af24376fe19921 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 15:46:01 -1000 Subject: [PATCH 134/302] [core] Remove object_id RAM storage - no longer in hot path after #12627 (#12631) --- esphome/core/entity_base.cpp | 84 ++++----- esphome/core/entity_base.h | 11 +- esphome/core/entity_helpers.py | 34 +--- esphome/core/helpers.h | 14 ++ esphome/helpers.py | 28 ++- .../binary_sensor/test_binary_sensor.py | 2 +- tests/component_tests/button/test_button.py | 2 +- tests/component_tests/text/test_text.py | 2 +- .../text_sensor/test_text_sensor.py | 15 +- tests/integration/conftest.py | 3 + tests/integration/entity_utils.py | 145 +++++++++++++++ .../fixtures/fnv1_hash_object_id.yaml | 76 ++++++++ .../fixtures/object_id_api_verification.yaml | 125 +++++++++++++ ...object_id_friendly_name_no_mac_suffix.yaml | 27 +++ ...ect_id_no_friendly_name_no_mac_suffix.yaml | 25 +++ ...t_id_no_friendly_name_with_mac_suffix.yaml | 26 +++ tests/integration/test_fnv1_hash_object_id.py | 75 ++++++++ .../test_object_id_api_verification.py | 176 ++++++++++++++++++ ...t_object_id_friendly_name_no_mac_suffix.py | 81 ++++++++ .../test_object_id_no_friendly_name.py | 140 ++++++++++++++ tests/unit_tests/core/test_entity_helpers.py | 168 +++++++++++++++-- tests/unit_tests/test_helpers.py | 71 +++++++ 22 files changed, 1213 insertions(+), 117 deletions(-) create mode 100644 tests/integration/entity_utils.py create mode 100644 tests/integration/fixtures/fnv1_hash_object_id.yaml create mode 100644 tests/integration/fixtures/object_id_api_verification.yaml create mode 100644 tests/integration/fixtures/object_id_friendly_name_no_mac_suffix.yaml create mode 100644 tests/integration/fixtures/object_id_no_friendly_name_no_mac_suffix.yaml create mode 100644 tests/integration/fixtures/object_id_no_friendly_name_with_mac_suffix.yaml create mode 100644 tests/integration/test_fnv1_hash_object_id.py create mode 100644 tests/integration/test_object_id_api_verification.py create mode 100644 tests/integration/test_object_id_friendly_name_no_mac_suffix.py create mode 100644 tests/integration/test_object_id_no_friendly_name.py diff --git a/esphome/core/entity_base.cpp b/esphome/core/entity_base.cpp index b7616a9ad3..8508b93411 100644 --- a/esphome/core/entity_base.cpp +++ b/esphome/core/entity_base.cpp @@ -9,7 +9,8 @@ static const char *const TAG = "entity_base"; // Entity Name const StringRef &EntityBase::get_name() const { return this->name_; } -void EntityBase::set_name(const char *name) { +void EntityBase::set_name(const char *name) { this->set_name(name, 0); } +void EntityBase::set_name(const char *name, uint32_t object_id_hash) { this->name_ = StringRef(name); if (this->name_.empty()) { #ifdef USE_DEVICES @@ -18,11 +19,29 @@ void EntityBase::set_name(const char *name) { } else #endif { - this->name_ = StringRef(App.get_friendly_name()); + // Bug-for-bug compatibility with OLD behavior: + // - With MAC suffix: OLD code used App.get_friendly_name() directly (no fallback) + // - Without MAC suffix: OLD code used pre-computed object_id with fallback to device name + const std::string &friendly = App.get_friendly_name(); + if (App.is_name_add_mac_suffix_enabled()) { + // MAC suffix enabled - use friendly_name directly (even if empty) for compatibility + this->name_ = StringRef(friendly); + } else { + // No MAC suffix - fallback to device name if friendly_name is empty + this->name_ = StringRef(!friendly.empty() ? friendly : App.get_name()); + } } this->flags_.has_own_name = false; + // Dynamic name - must calculate hash at runtime + this->calc_object_id_(); } else { this->flags_.has_own_name = true; + // Static name - use pre-computed hash if provided + if (object_id_hash != 0) { + this->object_id_hash_ = object_id_hash; + } else { + this->calc_object_id_(); + } } } @@ -45,69 +64,30 @@ void EntityBase::set_icon(const char *icon) { #endif } -// Check if the object_id is dynamic (changes with MAC suffix) -bool EntityBase::is_object_id_dynamic_() const { - return !this->flags_.has_own_name && App.is_name_add_mac_suffix_enabled(); -} - -// Entity Object ID +// Entity Object ID - computed on-demand from name std::string EntityBase::get_object_id() const { - // Check if `App.get_friendly_name()` is constant or dynamic. - if (this->is_object_id_dynamic_()) { - // `App.get_friendly_name()` is dynamic. - return str_sanitize(str_snake_case(App.get_friendly_name())); - } - // `App.get_friendly_name()` is constant. - return this->object_id_c_str_ == nullptr ? "" : this->object_id_c_str_; -} -void EntityBase::set_object_id(const char *object_id) { - this->object_id_c_str_ = object_id; - this->calc_object_id_(); -} - -void EntityBase::set_name_and_object_id(const char *name, const char *object_id) { - this->set_name(name); - this->object_id_c_str_ = object_id; - this->calc_object_id_(); -} - -// Calculate Object ID Hash from Entity Name -void EntityBase::calc_object_id_() { char buf[OBJECT_ID_MAX_LEN]; - StringRef object_id = this->get_object_id_to(buf); - this->object_id_hash_ = fnv1_hash(object_id.c_str()); + size_t len = this->write_object_id_to(buf, sizeof(buf)); + return std::string(buf, len); } -// Format dynamic object_id: sanitized snake_case of friendly_name -static size_t format_dynamic_object_id(char *buf, size_t buf_size) { - const std::string &name = App.get_friendly_name(); - size_t len = std::min(name.size(), buf_size - 1); - for (size_t i = 0; i < len; i++) { - buf[i] = to_sanitized_char(to_snake_case_char(name[i])); - } - buf[len] = '\0'; - return len; +// Calculate Object ID Hash directly from name using snake_case + sanitize +void EntityBase::calc_object_id_() { + this->object_id_hash_ = fnv1_hash_object_id(this->name_.c_str(), this->name_.size()); } size_t EntityBase::write_object_id_to(char *buf, size_t buf_size) const { - if (this->is_object_id_dynamic_()) { - return format_dynamic_object_id(buf, buf_size); + size_t len = std::min(this->name_.size(), buf_size - 1); + for (size_t i = 0; i < len; i++) { + buf[i] = to_sanitized_char(to_snake_case_char(this->name_[i])); } - const char *src = this->object_id_c_str_ == nullptr ? "" : this->object_id_c_str_; - size_t len = strlen(src); - if (len >= buf_size) - len = buf_size - 1; - memcpy(buf, src, len); buf[len] = '\0'; return len; } StringRef EntityBase::get_object_id_to(std::span buf) const { - if (this->is_object_id_dynamic_()) { - size_t len = format_dynamic_object_id(buf.data(), buf.size()); - return StringRef(buf.data(), len); - } - return this->object_id_c_str_ == nullptr ? StringRef() : StringRef(this->object_id_c_str_); + size_t len = this->write_object_id_to(buf.data(), buf.size()); + return StringRef(buf.data(), len); } uint32_t EntityBase::get_object_id_hash() { return this->object_id_hash_; } diff --git a/esphome/core/entity_base.h b/esphome/core/entity_base.h index a5c69f132c..a45c7795bf 100644 --- a/esphome/core/entity_base.h +++ b/esphome/core/entity_base.h @@ -28,6 +28,9 @@ class EntityBase { // Get/set the name of this Entity const StringRef &get_name() const; void set_name(const char *name); + /// Set name with pre-computed object_id hash (avoids runtime hash calculation) + /// Use hash=0 for dynamic names that need runtime calculation + void set_name(const char *name, uint32_t object_id_hash); // Get whether this Entity has its own name or it should use the device friendly_name. bool has_own_name() const { return this->flags_.has_own_name; } @@ -43,10 +46,6 @@ class EntityBase { "which will remain available longer. get_object_id() will be removed in 2026.7.0", "2025.12.0") std::string get_object_id() const; - void set_object_id(const char *object_id); - - // Set both name and object_id in one call (reduces generated code size) - void set_name_and_object_id(const char *name, const char *object_id); // Get the unique Object ID of this Entity uint32_t get_object_id_hash(); @@ -142,11 +141,7 @@ class EntityBase { protected: void calc_object_id_(); - /// Check if the object_id is dynamic (changes with MAC suffix) - bool is_object_id_dynamic_() const; - StringRef name_; - const char *object_id_c_str_{nullptr}; #ifdef USE_ENTITY_ICON const char *icon_c_str_{nullptr}; #endif diff --git a/esphome/core/entity_helpers.py b/esphome/core/entity_helpers.py index f360b4d809..c1801c0bda 100644 --- a/esphome/core/entity_helpers.py +++ b/esphome/core/entity_helpers.py @@ -15,7 +15,7 @@ from esphome.const import ( from esphome.core import CORE, ID from esphome.cpp_generator import MockObj, add, get_variable import esphome.final_validate as fv -from esphome.helpers import sanitize, snake_case +from esphome.helpers import fnv1_hash_object_id, sanitize, snake_case from esphome.types import ConfigType, EntityMetadata _LOGGER = logging.getLogger(__name__) @@ -75,34 +75,18 @@ async def setup_entity(var: MockObj, config: ConfigType, platform: str) -> None: config: Configuration dictionary containing entity settings platform: The platform name (e.g., "sensor", "binary_sensor") """ - # Get device info - device_name: str | None = None - device_id_obj: ID | None + # Get device info if configured if device_id_obj := config.get(CONF_DEVICE_ID): device: MockObj = await get_variable(device_id_obj) add(var.set_device(device)) - # Get device name for object ID calculation - device_name = device_id_obj.id - # Calculate base object_id using the same logic as C++ - # This must match the C++ behavior in esphome/core/entity_base.cpp - base_object_id = get_base_entity_object_id( - config[CONF_NAME], CORE.friendly_name, device_name - ) - - if not config[CONF_NAME]: - _LOGGER.debug( - "Entity has empty name, using '%s' as object_id base", base_object_id - ) - - # Set both name and object_id in one call to reduce generated code size - add(var.set_name_and_object_id(config[CONF_NAME], base_object_id)) - _LOGGER.debug( - "Setting object_id '%s' for entity '%s' on platform '%s'", - base_object_id, - config[CONF_NAME], - platform, - ) + # Set the entity name with pre-computed object_id hash + # For named entities: pre-compute hash from entity name + # For empty-name entities: pass 0, C++ calculates hash at runtime from + # device name, friendly_name, or app name (bug-for-bug compatibility) + entity_name = config[CONF_NAME] + object_id_hash = fnv1_hash_object_id(entity_name) if entity_name else 0 + add(var.set_name(entity_name, object_id_hash)) # Only set disabled_by_default if True (default is False) if config[CONF_DISABLED_BY_DEFAULT]: add(var.set_disabled_by_default(True)) diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index ac7a96a8c8..f7a14ed2ec 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -529,6 +529,20 @@ constexpr char to_sanitized_char(char c) { /// Sanitizes the input string by removing all characters but alphanumerics, dashes and underscores. std::string str_sanitize(const std::string &str); +/// Calculate FNV-1 hash of a string while applying snake_case + sanitize transformations. +/// This computes object_id hashes directly from names without creating an intermediate buffer. +/// IMPORTANT: Must match Python fnv1_hash_object_id() in esphome/helpers.py. +/// If you modify this function, update the Python version and tests in both places. +inline uint32_t fnv1_hash_object_id(const char *str, size_t len) { + uint32_t hash = FNV1_OFFSET_BASIS; + for (size_t i = 0; i < len; i++) { + hash *= FNV1_PRIME; + // Apply snake_case (space->underscore, uppercase->lowercase) then sanitize + hash ^= static_cast(to_sanitized_char(to_snake_case_char(str[i]))); + } + return hash; +} + /// snprintf-like function returning std::string of maximum length \p len (excluding null terminator). std::string __attribute__((format(printf, 1, 3))) str_snprintf(const char *fmt, size_t len, ...); diff --git a/esphome/helpers.py b/esphome/helpers.py index d1623d1d3c..ae142b7f8b 100644 --- a/esphome/helpers.py +++ b/esphome/helpers.py @@ -35,6 +35,10 @@ IS_MACOS = platform.system() == "Darwin" IS_WINDOWS = platform.system() == "Windows" IS_LINUX = platform.system() == "Linux" +# FNV-1 hash constants (must match C++ in esphome/core/helpers.h) +FNV1_OFFSET_BASIS = 2166136261 +FNV1_PRIME = 16777619 + def ensure_unique_string(preferred_string, current_strings): test_string = preferred_string @@ -49,8 +53,17 @@ def ensure_unique_string(preferred_string, current_strings): return test_string +def fnv1_hash(string: str) -> int: + """FNV-1 32-bit hash function (multiply then XOR).""" + hash_value = FNV1_OFFSET_BASIS + for char in string: + hash_value = (hash_value * FNV1_PRIME) & 0xFFFFFFFF + hash_value ^= ord(char) + return hash_value + + def fnv1a_32bit_hash(string: str) -> int: - """FNV-1a 32-bit hash function. + """FNV-1a 32-bit hash function (XOR then multiply). Note: This uses 32-bit hash instead of 64-bit for several reasons: 1. ESPHome targets 32-bit microcontrollers with limited RAM (often <320KB) @@ -63,13 +76,22 @@ def fnv1a_32bit_hash(string: str) -> int: a handful of area_ids and device_ids (typically <10 areas and <100 devices), making collisions virtually impossible. """ - hash_value = 2166136261 + hash_value = FNV1_OFFSET_BASIS for char in string: hash_value ^= ord(char) - hash_value = (hash_value * 16777619) & 0xFFFFFFFF + hash_value = (hash_value * FNV1_PRIME) & 0xFFFFFFFF return hash_value +def fnv1_hash_object_id(name: str) -> int: + """Compute FNV-1 hash of name with snake_case + sanitize transformations. + + IMPORTANT: Must produce same result as C++ fnv1_hash_object_id() in helpers.h. + Used for pre-computing entity object_id hashes at code generation time. + """ + return fnv1_hash(sanitize(snake_case(name))) + + def strip_accents(value: str) -> str: """Remove accents from a string.""" import unicodedata diff --git a/tests/component_tests/binary_sensor/test_binary_sensor.py b/tests/component_tests/binary_sensor/test_binary_sensor.py index 86e0705023..ce4e64681f 100644 --- a/tests/component_tests/binary_sensor/test_binary_sensor.py +++ b/tests/component_tests/binary_sensor/test_binary_sensor.py @@ -29,7 +29,7 @@ def test_binary_sensor_sets_mandatory_fields(generate_main): ) # Then - assert 'bs_1->set_name_and_object_id("test bs1", "test_bs1");' in main_cpp + assert 'bs_1->set_name("test bs1",' in main_cpp assert "bs_1->set_pin(" in main_cpp diff --git a/tests/component_tests/button/test_button.py b/tests/component_tests/button/test_button.py index b21665288c..797b6fb1a4 100644 --- a/tests/component_tests/button/test_button.py +++ b/tests/component_tests/button/test_button.py @@ -26,7 +26,7 @@ def test_button_sets_mandatory_fields(generate_main): main_cpp = generate_main("tests/component_tests/button/test_button.yaml") # Then - assert 'wol_1->set_name_and_object_id("wol_test_1", "wol_test_1");' in main_cpp + assert 'wol_1->set_name("wol_test_1",' in main_cpp assert "wol_2->set_macaddr(18, 52, 86, 120, 144, 171);" in main_cpp diff --git a/tests/component_tests/text/test_text.py b/tests/component_tests/text/test_text.py index bfc3131f6d..6b047bc62f 100644 --- a/tests/component_tests/text/test_text.py +++ b/tests/component_tests/text/test_text.py @@ -25,7 +25,7 @@ def test_text_sets_mandatory_fields(generate_main): main_cpp = generate_main("tests/component_tests/text/test_text.yaml") # Then - assert 'it_1->set_name_and_object_id("test 1 text", "test_1_text");' in main_cpp + assert 'it_1->set_name("test 1 text",' in main_cpp def test_text_config_value_internal_set(generate_main): diff --git a/tests/component_tests/text_sensor/test_text_sensor.py b/tests/component_tests/text_sensor/test_text_sensor.py index 934ee67cef..1593d0b6d8 100644 --- a/tests/component_tests/text_sensor/test_text_sensor.py +++ b/tests/component_tests/text_sensor/test_text_sensor.py @@ -25,18 +25,9 @@ def test_text_sensor_sets_mandatory_fields(generate_main): main_cpp = generate_main("tests/component_tests/text_sensor/test_text_sensor.yaml") # Then - assert ( - 'ts_1->set_name_and_object_id("Template Text Sensor 1", "template_text_sensor_1");' - in main_cpp - ) - assert ( - 'ts_2->set_name_and_object_id("Template Text Sensor 2", "template_text_sensor_2");' - in main_cpp - ) - assert ( - 'ts_3->set_name_and_object_id("Template Text Sensor 3", "template_text_sensor_3");' - in main_cpp - ) + assert 'ts_1->set_name("Template Text Sensor 1",' in main_cpp + assert 'ts_2->set_name("Template Text Sensor 2",' in main_cpp + assert 'ts_3->set_name("Template Text Sensor 3",' in main_cpp def test_text_sensor_config_value_internal_set(generate_main): diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 965363972f..50e8d4122b 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -51,6 +51,9 @@ if platform.system() == "Windows": import pty # not available on Windows +# Register assert rewrite for entity_utils so assertions have proper error messages +pytest.register_assert_rewrite("tests.integration.entity_utils") + def _get_platformio_env(cache_dir: Path) -> dict[str, str]: """Get environment variables for PlatformIO with shared cache.""" diff --git a/tests/integration/entity_utils.py b/tests/integration/entity_utils.py new file mode 100644 index 0000000000..7596983ee2 --- /dev/null +++ b/tests/integration/entity_utils.py @@ -0,0 +1,145 @@ +"""Utilities for computing entity object_id in integration tests. + +This module contains the algorithm that aioesphomeapi will use to compute +object_id client-side from API data. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from esphome.helpers import fnv1_hash_object_id, sanitize, snake_case + +if TYPE_CHECKING: + from aioesphomeapi import DeviceInfo, EntityInfo + + +def compute_object_id(name: str) -> str: + """Compute object_id from name using snake_case + sanitize.""" + return sanitize(snake_case(name)) + + +def infer_name_add_mac_suffix(device_info: DeviceInfo) -> bool: + """Infer name_add_mac_suffix from device name ending with MAC suffix.""" + mac_suffix = device_info.mac_address.replace(":", "")[-6:].lower() + return device_info.name.endswith(f"-{mac_suffix}") + + +def _get_name_for_object_id( + entity: EntityInfo, + device_info: DeviceInfo, + device_id_to_name: dict[int, str], +) -> str: + """Get the name used for object_id computation. + + This is the algorithm that aioesphomeapi will use to determine which + name to use for computing object_id client-side from API data. + + Args: + entity: The entity to get name for + device_info: Device info from the API + device_id_to_name: Mapping of device_id to device name for sub-devices + + Returns: + The name to use for object_id computation + """ + if entity.name: + # Named entity: use entity name + return entity.name + if entity.device_id != 0: + # Empty name on sub-device: use sub-device name + return device_id_to_name[entity.device_id] + if infer_name_add_mac_suffix(device_info) or device_info.friendly_name: + # Empty name on main device with MAC suffix or friendly_name: use friendly_name + # (even if empty - this is bug-for-bug compatibility for MAC suffix case) + return device_info.friendly_name + # Empty name on main device, no friendly_name: use device name + return device_info.name + + +def compute_entity_object_id( + entity: EntityInfo, + device_info: DeviceInfo, + device_id_to_name: dict[int, str], +) -> str: + """Compute expected object_id for an entity. + + Args: + entity: The entity to compute object_id for + device_info: Device info from the API + device_id_to_name: Mapping of device_id to device name for sub-devices + + Returns: + The computed object_id string + """ + name_for_id = _get_name_for_object_id(entity, device_info, device_id_to_name) + return compute_object_id(name_for_id) + + +def compute_entity_hash( + entity: EntityInfo, + device_info: DeviceInfo, + device_id_to_name: dict[int, str], +) -> int: + """Compute expected object_id hash for an entity. + + Args: + entity: The entity to compute hash for + device_info: Device info from the API + device_id_to_name: Mapping of device_id to device name for sub-devices + + Returns: + The computed FNV-1 hash + """ + name_for_id = _get_name_for_object_id(entity, device_info, device_id_to_name) + return fnv1_hash_object_id(name_for_id) + + +def verify_entity_object_id( + entity: EntityInfo, + device_info: DeviceInfo, + device_id_to_name: dict[int, str], +) -> None: + """Verify an entity's object_id and hash match the expected values. + + Args: + entity: The entity to verify + device_info: Device info from the API + device_id_to_name: Mapping of device_id to device name for sub-devices + + Raises: + AssertionError: If object_id or hash doesn't match expected value + """ + expected_object_id = compute_entity_object_id( + entity, device_info, device_id_to_name + ) + assert entity.object_id == expected_object_id, ( + f"object_id mismatch for entity '{entity.name}': " + f"expected '{expected_object_id}', got '{entity.object_id}'" + ) + + expected_hash = compute_entity_hash(entity, device_info, device_id_to_name) + assert entity.key == expected_hash, ( + f"hash mismatch for entity '{entity.name}': " + f"expected {expected_hash:#x}, got {entity.key:#x}" + ) + + +def verify_all_entities( + entities: list[EntityInfo], + device_info: DeviceInfo, +) -> None: + """Verify all entities have correct object_id and hash values. + + Args: + entities: List of entities to verify + device_info: Device info from the API + + Raises: + AssertionError: If any entity's object_id or hash doesn't match + """ + # Build device_id -> name lookup from sub-devices + device_id_to_name = {d.device_id: d.name for d in device_info.devices} + + for entity in entities: + verify_entity_object_id(entity, device_info, device_id_to_name) diff --git a/tests/integration/fixtures/fnv1_hash_object_id.yaml b/tests/integration/fixtures/fnv1_hash_object_id.yaml new file mode 100644 index 0000000000..2097b2fbf9 --- /dev/null +++ b/tests/integration/fixtures/fnv1_hash_object_id.yaml @@ -0,0 +1,76 @@ +esphome: + name: fnv1-hash-object-id-test + platformio_options: + build_flags: + - "-DDEBUG" + on_boot: + - lambda: |- + using esphome::fnv1_hash_object_id; + + // Test basic lowercase (hash matches Python fnv1_hash_object_id("foo")) + uint32_t hash_foo = fnv1_hash_object_id("foo", 3); + if (hash_foo == 0x408f5e13) { + ESP_LOGI("FNV1_OID", "foo PASSED"); + } else { + ESP_LOGE("FNV1_OID", "foo FAILED: 0x%08x != 0x408f5e13", hash_foo); + } + + // Test uppercase conversion (should match lowercase) + uint32_t hash_Foo = fnv1_hash_object_id("Foo", 3); + if (hash_Foo == 0x408f5e13) { + ESP_LOGI("FNV1_OID", "upper PASSED"); + } else { + ESP_LOGE("FNV1_OID", "upper FAILED: 0x%08x != 0x408f5e13", hash_Foo); + } + + // Test space to underscore conversion ("foo bar" -> "foo_bar") + uint32_t hash_space = fnv1_hash_object_id("foo bar", 7); + if (hash_space == 0x3ae35aa1) { + ESP_LOGI("FNV1_OID", "space PASSED"); + } else { + ESP_LOGE("FNV1_OID", "space FAILED: 0x%08x != 0x3ae35aa1", hash_space); + } + + // Test underscore preserved ("foo_bar") + uint32_t hash_underscore = fnv1_hash_object_id("foo_bar", 7); + if (hash_underscore == 0x3ae35aa1) { + ESP_LOGI("FNV1_OID", "underscore PASSED"); + } else { + ESP_LOGE("FNV1_OID", "underscore FAILED: 0x%08x != 0x3ae35aa1", hash_underscore); + } + + // Test hyphen preserved ("foo-bar") + uint32_t hash_hyphen = fnv1_hash_object_id("foo-bar", 7); + if (hash_hyphen == 0x438b12e3) { + ESP_LOGI("FNV1_OID", "hyphen PASSED"); + } else { + ESP_LOGE("FNV1_OID", "hyphen FAILED: 0x%08x != 0x438b12e3", hash_hyphen); + } + + // Test special chars become underscore ("foo!bar" -> "foo_bar") + uint32_t hash_special = fnv1_hash_object_id("foo!bar", 7); + if (hash_special == 0x3ae35aa1) { + ESP_LOGI("FNV1_OID", "special PASSED"); + } else { + ESP_LOGE("FNV1_OID", "special FAILED: 0x%08x != 0x3ae35aa1", hash_special); + } + + // Test complex name ("My Sensor Name" -> "my_sensor_name") + uint32_t hash_complex = fnv1_hash_object_id("My Sensor Name", 14); + if (hash_complex == 0x2760962a) { + ESP_LOGI("FNV1_OID", "complex PASSED"); + } else { + ESP_LOGE("FNV1_OID", "complex FAILED: 0x%08x != 0x2760962a", hash_complex); + } + + // Test empty string returns FNV1_OFFSET_BASIS + uint32_t hash_empty = fnv1_hash_object_id("", 0); + if (hash_empty == 0x811c9dc5) { + ESP_LOGI("FNV1_OID", "empty PASSED"); + } else { + ESP_LOGE("FNV1_OID", "empty FAILED: 0x%08x != 0x811c9dc5", hash_empty); + } + +host: +api: +logger: diff --git a/tests/integration/fixtures/object_id_api_verification.yaml b/tests/integration/fixtures/object_id_api_verification.yaml new file mode 100644 index 0000000000..386270fc2c --- /dev/null +++ b/tests/integration/fixtures/object_id_api_verification.yaml @@ -0,0 +1,125 @@ +esphome: + name: object-id-test + friendly_name: Test Device + # Enable MAC suffix - host MAC is 98:35:69:ab:f6:79, suffix is "abf679" + # friendly_name becomes "Test Device abf679" + name_add_mac_suffix: true + # Sub-devices for testing empty-name entities on devices + devices: + - id: sub_device_1 + name: Sub Device One + - id: sub_device_2 + name: Sub Device Two + +host: + +api: + +logger: + +sensor: + # Test 1: Basic name -> object_id = "temperature_sensor" + - platform: template + name: "Temperature Sensor" + id: sensor_basic + lambda: return 42.0; + update_interval: 60s + + # Test 2: Uppercase name -> object_id = "uppercase_name" + - platform: template + name: "UPPERCASE NAME" + id: sensor_uppercase + lambda: return 43.0; + update_interval: 60s + + # Test 3: Special characters -> object_id = "special__chars_" + - platform: template + name: "Special!@Chars#" + id: sensor_special + lambda: return 44.0; + update_interval: 60s + + # Test 4: Hyphen preserved -> object_id = "temp-sensor" + - platform: template + name: "Temp-Sensor" + id: sensor_hyphen + lambda: return 45.0; + update_interval: 60s + + # Test 5: Underscore preserved -> object_id = "temp_sensor" + - platform: template + name: "Temp_Sensor" + id: sensor_underscore + lambda: return 46.0; + update_interval: 60s + + # Test 6: Mixed case with spaces -> object_id = "living_room_temperature" + - platform: template + name: "Living Room Temperature" + id: sensor_mixed + lambda: return 47.0; + update_interval: 60s + + # Test 7: Empty name - uses friendly_name with MAC suffix + # friendly_name = "Test Device abf679" -> object_id = "test_device_abf679" + - platform: template + name: "" + id: sensor_empty_name + lambda: return 48.0; + update_interval: 60s + +binary_sensor: + # Test 8: Different platform same conversion rules + - platform: template + name: "Door Open" + id: binary_door + lambda: return true; + + # Test 9: Numbers in name -> object_id = "sensor_123" + - platform: template + name: "Sensor 123" + id: binary_numbers + lambda: return false; + +switch: + # Test 10: Long name with multiple spaces + - platform: template + name: "My Very Long Switch Name Here" + id: switch_long + lambda: return false; + turn_on_action: + - logger.log: "on" + turn_off_action: + - logger.log: "off" + +text_sensor: + # Test 11: Name starting with number (should work fine) + - platform: template + name: "123 Start" + id: text_num_start + lambda: return {"test"}; + update_interval: 60s + +button: + # Test 12: Named entity on sub-device -> object_id from entity name + - platform: template + name: "Device Button" + id: button_on_device + device_id: sub_device_1 + on_press: [] + + # Test 13: Empty name on sub-device -> object_id from device name + # Device name "Sub Device One" -> object_id = "sub_device_one" + - platform: template + name: "" + id: button_empty_on_device1 + device_id: sub_device_1 + on_press: [] + + # Test 14: Empty name on different sub-device + # Device name "Sub Device Two" -> object_id = "sub_device_two" + - platform: template + name: "" + id: button_empty_on_device2 + device_id: sub_device_2 + on_press: [] diff --git a/tests/integration/fixtures/object_id_friendly_name_no_mac_suffix.yaml b/tests/integration/fixtures/object_id_friendly_name_no_mac_suffix.yaml new file mode 100644 index 0000000000..7a86e37d08 --- /dev/null +++ b/tests/integration/fixtures/object_id_friendly_name_no_mac_suffix.yaml @@ -0,0 +1,27 @@ +esphome: + name: test-device + # friendly_name set but NO MAC suffix + # Empty-name entity should use friendly_name for object_id + friendly_name: My Friendly Device + +host: + +api: + +logger: + +sensor: + # Empty name entity - should use friendly_name for object_id + # friendly_name = "My Friendly Device" -> object_id = "my_friendly_device" + - platform: template + name: "" + id: sensor_empty_name + lambda: return 42.0; + update_interval: 60s + + # Named entity for comparison + - platform: template + name: "Temperature" + id: sensor_named + lambda: return 43.0; + update_interval: 60s diff --git a/tests/integration/fixtures/object_id_no_friendly_name_no_mac_suffix.yaml b/tests/integration/fixtures/object_id_no_friendly_name_no_mac_suffix.yaml new file mode 100644 index 0000000000..4a947e0f6a --- /dev/null +++ b/tests/integration/fixtures/object_id_no_friendly_name_no_mac_suffix.yaml @@ -0,0 +1,25 @@ +esphome: + name: test-device + # No friendly_name set, no MAC suffix + # OLD behavior: object_id = device name because Python pre-computed with fallback + +host: + +api: + +logger: + +sensor: + # Empty name entity - OLD behavior used device name as fallback + - platform: template + name: "" + id: sensor_empty_name + lambda: return 42.0; + update_interval: 60s + + # Named entity for comparison + - platform: template + name: "Temperature" + id: sensor_named + lambda: return 43.0; + update_interval: 60s diff --git a/tests/integration/fixtures/object_id_no_friendly_name_with_mac_suffix.yaml b/tests/integration/fixtures/object_id_no_friendly_name_with_mac_suffix.yaml new file mode 100644 index 0000000000..ab12e670a0 --- /dev/null +++ b/tests/integration/fixtures/object_id_no_friendly_name_with_mac_suffix.yaml @@ -0,0 +1,26 @@ +esphome: + name: test-device + # No friendly_name set, MAC suffix enabled + # OLD behavior: object_id = "" (empty) because is_object_id_dynamic_() used App.get_friendly_name() directly + name_add_mac_suffix: true + +host: + +api: + +logger: + +sensor: + # Empty name entity - OLD behavior produced empty object_id when MAC suffix enabled + - platform: template + name: "" + id: sensor_empty_name + lambda: return 42.0; + update_interval: 60s + + # Named entity for comparison + - platform: template + name: "Temperature" + id: sensor_named + lambda: return 43.0; + update_interval: 60s diff --git a/tests/integration/test_fnv1_hash_object_id.py b/tests/integration/test_fnv1_hash_object_id.py new file mode 100644 index 0000000000..23e8ca04c2 --- /dev/null +++ b/tests/integration/test_fnv1_hash_object_id.py @@ -0,0 +1,75 @@ +"""Integration test for fnv1_hash_object_id function. + +This test verifies that the C++ fnv1_hash_object_id() function in +esphome/core/helpers.h produces the same hash values as the Python +fnv1_hash_object_id() function in esphome/helpers.py. + +If this test fails, one of the implementations has diverged and needs +to be updated to match the other. +""" + +from __future__ import annotations + +import asyncio +import re + +import pytest + +from .types import APIClientConnectedFactory, RunCompiledFunction + + +@pytest.mark.asyncio +async def test_fnv1_hash_object_id( + yaml_config: str, + run_compiled: RunCompiledFunction, + api_client_connected: APIClientConnectedFactory, +) -> None: + """Test that C++ fnv1_hash_object_id matches Python implementation.""" + + test_results: dict[str, str] = {} + all_tests_complete = asyncio.Event() + expected_tests = { + "foo", + "upper", + "space", + "underscore", + "hyphen", + "special", + "complex", + "empty", + } + + def on_log_line(line: str) -> None: + """Capture log lines with test results.""" + # Strip ANSI escape codes + clean_line = re.sub(r"\x1b\[[0-9;]*m", "", line) + # Look for our test result messages + # Format: "[timestamp][level][FNV1_OID:line]: test_name PASSED" + match = re.search(r"\[FNV1_OID:\d+\]:\s+(\w+)\s+(PASSED|FAILED)", clean_line) + if match: + test_name = match.group(1) + result = match.group(2) + test_results[test_name] = result + if set(test_results.keys()) >= expected_tests: + all_tests_complete.set() + + async with ( + run_compiled(yaml_config, line_callback=on_log_line), + api_client_connected() as client, + ): + device_info = await client.device_info() + assert device_info is not None + assert device_info.name == "fnv1-hash-object-id-test" + + # Wait for all tests to complete or timeout + try: + await asyncio.wait_for(all_tests_complete.wait(), timeout=2.0) + except TimeoutError: + pytest.fail(f"Tests timed out. Got results for: {set(test_results.keys())}") + + # Verify all tests passed + for test_name in expected_tests: + assert test_name in test_results, f"{test_name} test not found" + assert test_results[test_name] == "PASSED", ( + f"{test_name} test failed - C++ and Python hash mismatch" + ) diff --git a/tests/integration/test_object_id_api_verification.py b/tests/integration/test_object_id_api_verification.py new file mode 100644 index 0000000000..c8603e0682 --- /dev/null +++ b/tests/integration/test_object_id_api_verification.py @@ -0,0 +1,176 @@ +"""Integration test to verify object_id from API matches Python computation. + +This test verifies a three-way match between: +1. C++ object_id generation (get_object_id_to using to_sanitized_char/to_snake_case_char) +2. C++ hash generation (fnv1_hash_object_id in helpers.h) +3. Python computation (sanitize/snake_case in helpers.py, fnv1_hash_object_id) + +The API response contains C++ computed values, so verifying API == Python +implicitly verifies C++ == Python == API for both object_id and hash. + +This is important for the planned migration to remove object_id from the API +protocol and have clients (like aioesphomeapi) compute it from the name. +See: https://github.com/esphome/backlog/issues/76 + +Test cases covered: +- Named entities with various characters (uppercase, special chars, hyphens, etc.) +- Empty-name entities on main device (uses device's friendly_name with MAC suffix) +- Empty-name entities on sub-devices (uses sub-device's name) +- Named entities on sub-devices (uses entity name, not device name) +- MAC suffix handling (name_add_mac_suffix modifies friendly_name at runtime) +- Both object_id string and hash (key) verification +""" + +from __future__ import annotations + +import pytest + +from esphome.helpers import fnv1_hash_object_id + +from .entity_utils import compute_object_id, verify_all_entities +from .types import APIClientConnectedFactory, RunCompiledFunction + +# Host platform default MAC: 98:35:69:ab:f6:79 -> suffix "abf679" +MAC_SUFFIX = "abf679" + + +# Expected entities with their own names and expected object_ids +# Format: (entity_name, expected_object_id) +NAMED_ENTITIES = [ + # sensor platform + ("Temperature Sensor", "temperature_sensor"), + ("UPPERCASE NAME", "uppercase_name"), + ("Special!@Chars#", "special__chars_"), + ("Temp-Sensor", "temp-sensor"), + ("Temp_Sensor", "temp_sensor"), + ("Living Room Temperature", "living_room_temperature"), + # binary_sensor platform + ("Door Open", "door_open"), + ("Sensor 123", "sensor_123"), + # switch platform + ("My Very Long Switch Name Here", "my_very_long_switch_name_here"), + # text_sensor platform + ("123 Start", "123_start"), + # button platform - named entity on sub-device (uses entity name, not device name) + ("Device Button", "device_button"), +] + +# Sub-device names and their expected object_ids for empty-name entities +# Format: (device_name, expected_object_id) +SUB_DEVICE_EMPTY_NAME_ENTITIES = [ + ("Sub Device One", "sub_device_one"), + ("Sub Device Two", "sub_device_two"), +] + + +@pytest.mark.asyncio +async def test_object_id_api_verification( + yaml_config: str, + run_compiled: RunCompiledFunction, + api_client_connected: APIClientConnectedFactory, +) -> None: + """Test that object_id from API matches Python computation. + + Tests: + 1. Named entities - object_id computed from entity name + 2. Empty-name entities - object_id computed from friendly_name (with MAC suffix) + 3. Hash verification - key can be computed from name + 4. Generic verification - all entities can have object_id computed from API data + """ + async with run_compiled(yaml_config), api_client_connected() as client: + # Get device info + device_info = await client.device_info() + assert device_info is not None + + # Device name should include MAC suffix (hyphen separator) + assert device_info.name == f"object-id-test-{MAC_SUFFIX}", ( + f"Device name mismatch: got '{device_info.name}'" + ) + # Friendly name should include MAC suffix (space separator) + expected_friendly_name = f"Test Device {MAC_SUFFIX}" + assert device_info.friendly_name == expected_friendly_name, ( + f"Friendly name mismatch: got '{device_info.friendly_name}'" + ) + + # Get all entities + entities, _ = await client.list_entities_services() + + # Create a map of entity names to entity info + entity_map = {} + for entity in entities: + entity_map[entity.name] = entity + + # === Test 1: Verify each named entity === + for entity_name, expected_object_id in NAMED_ENTITIES: + assert entity_name in entity_map, ( + f"Entity '{entity_name}' not found in API response. " + f"Available: {list(entity_map.keys())}" + ) + + entity = entity_map[entity_name] + + # Verify object_id matches expected + assert entity.object_id == expected_object_id, ( + f"Entity '{entity_name}': object_id mismatch. " + f"API returned '{entity.object_id}', expected '{expected_object_id}'" + ) + + # Verify Python computation matches + computed = compute_object_id(entity_name) + assert computed == expected_object_id, ( + f"Entity '{entity_name}': Python computation mismatch. " + f"Computed '{computed}', expected '{expected_object_id}'" + ) + + # Verify hash can be computed from the name + hash_from_name = fnv1_hash_object_id(entity_name) + assert hash_from_name == entity.key, ( + f"Entity '{entity_name}': hash mismatch. " + f"Python hash {hash_from_name:#x}, API key {entity.key:#x}" + ) + + # === Test 2: Verify empty-name entities === + # Empty-name entities have name="" in API, object_id comes from: + # - Main device: friendly_name (with MAC suffix) + # - Sub-device: device name + + # Get all empty-name entities + empty_name_entities = [e for e in entities if e.name == ""] + # We expect 3: 1 on main device, 2 on sub-devices + assert len(empty_name_entities) == 3, ( + f"Expected 3 empty-name entities, got {len(empty_name_entities)}" + ) + + # Build device_id -> device_name map from device_info + device_id_to_name = {d.device_id: d.name for d in device_info.devices} + + # Verify each empty-name entity + for entity in empty_name_entities: + if entity.device_id == 0: + # Main device - uses friendly_name with MAC suffix + expected_name = expected_friendly_name + else: + # Sub-device - uses device name + assert entity.device_id in device_id_to_name, ( + f"Entity device_id {entity.device_id} not found in devices" + ) + expected_name = device_id_to_name[entity.device_id] + + expected_object_id = compute_object_id(expected_name) + assert entity.object_id == expected_object_id, ( + f"Empty-name entity (device_id={entity.device_id}): object_id mismatch. " + f"API: '{entity.object_id}', expected: '{expected_object_id}' " + f"(from name '{expected_name}')" + ) + + # Verify hash matches + expected_hash = fnv1_hash_object_id(expected_name) + assert entity.key == expected_hash, ( + f"Empty-name entity (device_id={entity.device_id}): hash mismatch. " + f"API key: {entity.key:#x}, expected: {expected_hash:#x}" + ) + + # === Test 3: Verify ALL entities using the algorithm from entity_utils === + # This uses the algorithm that aioesphomeapi will use to compute object_id + # client-side from API data. + verify_all_entities(entities, device_info) diff --git a/tests/integration/test_object_id_friendly_name_no_mac_suffix.py b/tests/integration/test_object_id_friendly_name_no_mac_suffix.py new file mode 100644 index 0000000000..7199a2b371 --- /dev/null +++ b/tests/integration/test_object_id_friendly_name_no_mac_suffix.py @@ -0,0 +1,81 @@ +"""Integration test for object_id with friendly_name but no MAC suffix. + +This test covers Branch 4 of the algorithm: +- Empty name on main device +- NO MAC suffix enabled +- friendly_name IS set +- Result: use friendly_name for object_id +""" + +from __future__ import annotations + +import pytest + +from esphome.helpers import fnv1_hash_object_id + +from .entity_utils import ( + compute_object_id, + infer_name_add_mac_suffix, + verify_all_entities, +) +from .types import APIClientConnectedFactory, RunCompiledFunction + + +@pytest.mark.asyncio +async def test_object_id_friendly_name_no_mac_suffix( + yaml_config: str, + run_compiled: RunCompiledFunction, + api_client_connected: APIClientConnectedFactory, +) -> None: + """Test object_id when friendly_name is set but no MAC suffix. + + This covers Branch 4 of the algorithm: + - Empty name entity + - name_add_mac_suffix = false (or not set) + - friendly_name = "My Friendly Device" + - Expected: object_id = "my_friendly_device" + """ + async with run_compiled(yaml_config), api_client_connected() as client: + device_info = await client.device_info() + assert device_info is not None + + # Device name should NOT include MAC suffix + assert device_info.name == "test-device" + + # Friendly name should be set + assert device_info.friendly_name == "My Friendly Device" + + entities, _ = await client.list_entities_services() + + # Find the empty-name entity + empty_name_entities = [e for e in entities if e.name == ""] + assert len(empty_name_entities) == 1 + + entity = empty_name_entities[0] + + # Should use friendly_name for object_id (Branch 4) + expected_object_id = compute_object_id("My Friendly Device") + assert expected_object_id == "my_friendly_device" # Verify our expectation + assert entity.object_id == expected_object_id, ( + f"Expected object_id '{expected_object_id}' from friendly_name, " + f"got '{entity.object_id}'" + ) + + # Hash should match friendly_name + expected_hash = fnv1_hash_object_id("My Friendly Device") + assert entity.key == expected_hash, ( + f"Expected hash {expected_hash:#x}, got {entity.key:#x}" + ) + + # Named entity should work normally + named_entities = [e for e in entities if e.name == "Temperature"] + assert len(named_entities) == 1 + assert named_entities[0].object_id == "temperature" + + # Verify our inference: no MAC suffix in this test + assert not infer_name_add_mac_suffix(device_info), ( + "Device name should NOT have MAC suffix" + ) + + # Verify the full algorithm from entity_utils works for ALL entities + verify_all_entities(entities, device_info) diff --git a/tests/integration/test_object_id_no_friendly_name.py b/tests/integration/test_object_id_no_friendly_name.py new file mode 100644 index 0000000000..b548f02fde --- /dev/null +++ b/tests/integration/test_object_id_no_friendly_name.py @@ -0,0 +1,140 @@ +"""Integration tests for object_id when friendly_name is not set. + +These tests verify bug-for-bug compatibility with the old behavior: + +1. With MAC suffix enabled + no friendly_name: + - OLD: is_object_id_dynamic_() was true, used App.get_friendly_name() directly + - OLD: object_id = "" (empty) because friendly_name was empty + - NEW: Must maintain same behavior for compatibility + +2. Without MAC suffix + no friendly_name: + - OLD: is_object_id_dynamic_() was false, used pre-computed object_id_c_str_ + - OLD: Python computed object_id with fallback to device name + - NEW: Must maintain same behavior (object_id = device name) +""" + +from __future__ import annotations + +import pytest + +from esphome.helpers import fnv1_hash_object_id + +from .entity_utils import compute_object_id, verify_all_entities +from .types import APIClientConnectedFactory, RunCompiledFunction + +# Host platform default MAC: 98:35:69:ab:f6:79 -> suffix "abf679" +MAC_SUFFIX = "abf679" + +# FNV1 offset basis - hash of empty string +FNV1_OFFSET_BASIS = 2166136261 + + +@pytest.mark.asyncio +async def test_object_id_no_friendly_name_with_mac_suffix( + yaml_config: str, + run_compiled: RunCompiledFunction, + api_client_connected: APIClientConnectedFactory, +) -> None: + """Test object_id when friendly_name not set but MAC suffix enabled. + + OLD behavior (bug-for-bug compatibility): + - is_object_id_dynamic_() returned true (no own name AND mac suffix enabled) + - format_dynamic_object_id() used App.get_friendly_name() directly + - Since friendly_name was empty, object_id was empty + + This was arguably a bug, but we maintain it for compatibility. + """ + async with run_compiled(yaml_config), api_client_connected() as client: + device_info = await client.device_info() + assert device_info is not None + + # Device name should include MAC suffix + expected_device_name = f"test-device-{MAC_SUFFIX}" + assert device_info.name == expected_device_name + + # Friendly name should be empty (not set in config) + assert device_info.friendly_name == "" + + entities, _ = await client.list_entities_services() + + # Find the empty-name entity + empty_name_entities = [e for e in entities if e.name == ""] + assert len(empty_name_entities) == 1 + + entity = empty_name_entities[0] + + # OLD behavior: object_id was empty because App.get_friendly_name() was empty + # This is bug-for-bug compatibility + assert entity.object_id == "", ( + f"Expected empty object_id for bug-for-bug compatibility, " + f"got '{entity.object_id}'" + ) + + # Hash should be FNV1_OFFSET_BASIS (hash of empty string) + assert entity.key == FNV1_OFFSET_BASIS, ( + f"Expected hash of empty string ({FNV1_OFFSET_BASIS:#x}), " + f"got {entity.key:#x}" + ) + + # Named entity should work normally + named_entities = [e for e in entities if e.name == "Temperature"] + assert len(named_entities) == 1 + assert named_entities[0].object_id == "temperature" + + # Verify the full algorithm from entity_utils works for ALL entities + verify_all_entities(entities, device_info) + + +@pytest.mark.asyncio +async def test_object_id_no_friendly_name_no_mac_suffix( + yaml_config: str, + run_compiled: RunCompiledFunction, + api_client_connected: APIClientConnectedFactory, +) -> None: + """Test object_id when friendly_name not set and no MAC suffix. + + OLD behavior: + - is_object_id_dynamic_() returned false (mac suffix not enabled) + - Used object_id_c_str_ which was pre-computed in Python + - Python used get_base_entity_object_id() with fallback to CORE.name + + Result: object_id = sanitize(snake_case(device_name)) + """ + async with run_compiled(yaml_config), api_client_connected() as client: + device_info = await client.device_info() + assert device_info is not None + + # Device name should NOT include MAC suffix + assert device_info.name == "test-device" + + # Friendly name should be empty (not set in config) + assert device_info.friendly_name == "" + + entities, _ = await client.list_entities_services() + + # Find the empty-name entity + empty_name_entities = [e for e in entities if e.name == ""] + assert len(empty_name_entities) == 1 + + entity = empty_name_entities[0] + + # OLD behavior: object_id was computed from device name + expected_object_id = compute_object_id("test-device") + assert entity.object_id == expected_object_id, ( + f"Expected object_id '{expected_object_id}' from device name, " + f"got '{entity.object_id}'" + ) + + # Hash should match device name + expected_hash = fnv1_hash_object_id("test-device") + assert entity.key == expected_hash, ( + f"Expected hash {expected_hash:#x}, got {entity.key:#x}" + ) + + # Named entity should work normally + named_entities = [e for e in entities if e.name == "Temperature"] + assert len(named_entities) == 1 + assert named_entities[0].object_id == "temperature" + + # Verify the full algorithm from entity_utils works for ALL entities + verify_all_entities(entities, device_info) diff --git a/tests/unit_tests/core/test_entity_helpers.py b/tests/unit_tests/core/test_entity_helpers.py index 01de0f27f9..a58d4784ce 100644 --- a/tests/unit_tests/core/test_entity_helpers.py +++ b/tests/unit_tests/core/test_entity_helpers.py @@ -27,13 +27,9 @@ from esphome.helpers import sanitize, snake_case from .common import load_config_from_fixture -# Pre-compiled regex patterns for extracting object IDs from expressions -# Matches both old format: .set_object_id("obj_id") -# and new format: .set_name_and_object_id("name", "obj_id") -OBJECT_ID_PATTERN = re.compile(r'\.set_object_id\(["\'](.*?)["\']\)') -COMBINED_PATTERN = re.compile( - r'\.set_name_and_object_id\(["\'].*?["\']\s*,\s*["\'](.*?)["\']\)' -) +# Pre-compiled regex pattern for extracting names from set_name calls +# Matches: .set_name("name", hash) or .set_name("name") +SET_NAME_PATTERN = re.compile(r'\.set_name\(["\']([^"\']*)["\']') FIXTURES_DIR = Path(__file__).parent.parent / "fixtures" / "core" / "entity_helpers" @@ -276,14 +272,21 @@ def setup_test_environment() -> Generator[list[str], None, None]: def extract_object_id_from_expressions(expressions: list[str]) -> str | None: - """Extract the object ID that was set from the generated expressions.""" + """Extract the object ID that would be computed from set_name calls. + + Since object_id is now computed from the name (via snake_case + sanitize), + we extract the name from set_name() calls and compute the expected object_id. + For empty names, we fall back to CORE.friendly_name or CORE.name. + """ for expr in expressions: - # First try new combined format: .set_name_and_object_id("name", "obj_id") - if match := COMBINED_PATTERN.search(expr): - return match.group(1) - # Fall back to old format: .set_object_id("obj_id") - if match := OBJECT_ID_PATTERN.search(expr): - return match.group(1) + if match := SET_NAME_PATTERN.search(expr): + name = match.group(1) + if name: + return sanitize(snake_case(name)) + # Empty name - fall back to friendly_name or device name + if CORE.friendly_name: + return sanitize(snake_case(CORE.friendly_name)) + return sanitize(snake_case(CORE.name)) if CORE.name else None return None @@ -757,3 +760,140 @@ def test_entity_duplicate_validator_same_name_no_enhanced_message() -> None: r"Each entity on a device must have a unique name within its platform\.$", ): validator(config2) + + +@pytest.mark.asyncio +async def test_setup_entity_empty_name_with_device( + setup_test_environment: list[str], +) -> None: + """Test setup_entity with empty entity name on a sub-device. + + For empty-name entities, Python passes 0 and C++ calculates the hash + at runtime from the device's actual name. + """ + added_expressions = setup_test_environment + + # Mock get_variable to return a mock device + original_get_variable = entity_helpers.get_variable + + async def mock_get_variable(id_: ID) -> MockObj: + return MockObj("sub_device_1") + + entity_helpers.get_variable = mock_get_variable + + var = MockObj("sensor1") + device_id = ID("sub_device_1", type="Device") + + config = { + CONF_NAME: "", + CONF_DISABLED_BY_DEFAULT: False, + CONF_DEVICE_ID: device_id, + } + + await setup_entity(var, config, "sensor") + + entity_helpers.get_variable = original_get_variable + + # Check that set_device was called + assert any("sensor1.set_device" in expr for expr in added_expressions) + + # For empty-name entities, Python passes 0 - C++ calculates hash at runtime + assert any('set_name("", 0)' in expr for expr in added_expressions), ( + f"Expected set_name with hash 0, got {added_expressions}" + ) + + +@pytest.mark.asyncio +async def test_setup_entity_empty_name_with_mac_suffix( + setup_test_environment: list[str], +) -> None: + """Test setup_entity with empty name and MAC suffix enabled. + + For empty-name entities, Python passes 0 and C++ calculates the hash + at runtime from friendly_name (bug-for-bug compatibility). + """ + added_expressions = setup_test_environment + + # Set up CORE.config with name_add_mac_suffix enabled + CORE.config = {"name_add_mac_suffix": True} + # Set friendly_name to a specific value + CORE.friendly_name = "My Device" + + var = MockObj("sensor1") + + config = { + CONF_NAME: "", + CONF_DISABLED_BY_DEFAULT: False, + } + + await setup_entity(var, config, "sensor") + + # For empty-name entities, Python passes 0 - C++ calculates hash at runtime + assert any('set_name("", 0)' in expr for expr in added_expressions), ( + f"Expected set_name with hash 0, got {added_expressions}" + ) + + +@pytest.mark.asyncio +async def test_setup_entity_empty_name_with_mac_suffix_no_friendly_name( + setup_test_environment: list[str], +) -> None: + """Test setup_entity with empty name, MAC suffix enabled, but no friendly_name. + + For empty-name entities, Python passes 0 and C++ calculates the hash + at runtime. In this case C++ will hash the empty friendly_name + (bug-for-bug compatibility). + """ + added_expressions = setup_test_environment + + # Set up CORE.config with name_add_mac_suffix enabled + CORE.config = {"name_add_mac_suffix": True} + # Set friendly_name to empty + CORE.friendly_name = "" + + var = MockObj("sensor1") + + config = { + CONF_NAME: "", + CONF_DISABLED_BY_DEFAULT: False, + } + + await setup_entity(var, config, "sensor") + + # For empty-name entities, Python passes 0 - C++ calculates hash at runtime + assert any('set_name("", 0)' in expr for expr in added_expressions), ( + f"Expected set_name with hash 0, got {added_expressions}" + ) + + +@pytest.mark.asyncio +async def test_setup_entity_empty_name_no_mac_suffix_no_friendly_name( + setup_test_environment: list[str], +) -> None: + """Test setup_entity with empty name, no MAC suffix, and no friendly_name. + + For empty-name entities, Python passes 0 and C++ calculates the hash + at runtime from the device name. + """ + added_expressions = setup_test_environment + + # No MAC suffix (either not set or False) + CORE.config = {} + # No friendly_name + CORE.friendly_name = "" + # Device name is set + CORE.name = "my-test-device" + + var = MockObj("sensor1") + + config = { + CONF_NAME: "", + CONF_DISABLED_BY_DEFAULT: False, + } + + await setup_entity(var, config, "sensor") + + # For empty-name entities, Python passes 0 - C++ calculates hash at runtime + assert any('set_name("", 0)' in expr for expr in added_expressions), ( + f"Expected set_name with hash 0, got {added_expressions}" + ) diff --git a/tests/unit_tests/test_helpers.py b/tests/unit_tests/test_helpers.py index 47b945e0eb..159d3230ab 100644 --- a/tests/unit_tests/test_helpers.py +++ b/tests/unit_tests/test_helpers.py @@ -279,6 +279,77 @@ def test_sanitize(text, expected): assert actual == expected +@pytest.mark.parametrize( + ("name", "expected_hash"), + ( + # Basic strings - hash of sanitize(snake_case(name)) + ("foo", 0x408F5E13), + ("Foo", 0x408F5E13), # Same as "foo" (lowercase) + ("FOO", 0x408F5E13), # Same as "foo" (lowercase) + # Spaces become underscores + ("foo bar", 0x3AE35AA1), # Transforms to "foo_bar" + ("Foo Bar", 0x3AE35AA1), # Same (lowercase + underscore) + # Already snake_case + ("foo_bar", 0x3AE35AA1), + # Special chars become underscores + ("foo!bar", 0x3AE35AA1), # Transforms to "foo_bar" + ("foo@bar", 0x3AE35AA1), # Transforms to "foo_bar" + # Hyphens are preserved + ("foo-bar", 0x438B12E3), + # Numbers are preserved + ("foo123", 0xF3B0067D), + # Empty string + ("", 0x811C9DC5), # FNV1_OFFSET_BASIS (no chars processed) + # Single char + ("a", 0x050C5D7E), + # Mixed case and spaces + ("My Sensor Name", 0x2760962A), # Transforms to "my_sensor_name" + ), +) +def test_fnv1_hash_object_id(name, expected_hash): + """Test fnv1_hash_object_id produces expected hashes. + + These expected values were computed to match the C++ implementation + in esphome/core/helpers.h. If this test fails after modifying either + implementation, ensure both Python and C++ versions stay in sync. + """ + actual = helpers.fnv1_hash_object_id(name) + + assert actual == expected_hash + + +def _fnv1_hash_py(s: str) -> int: + """Python implementation of FNV-1 hash for verification.""" + hash_val = 2166136261 # FNV1_OFFSET_BASIS + for c in s: + hash_val = (hash_val * 16777619) & 0xFFFFFFFF # FNV1_PRIME + hash_val ^= ord(c) + return hash_val + + +@pytest.mark.parametrize( + "name", + ( + "Simple", + "With Space", + "MixedCase", + "special!@#chars", + "already_snake_case", + "123numbers", + ), +) +def test_fnv1_hash_object_id_matches_manual_calculation(name): + """Verify fnv1_hash_object_id matches snake_case + sanitize + standard FNV-1.""" + # Manual calculation: snake_case -> sanitize -> fnv1_hash + transformed = helpers.sanitize(helpers.snake_case(name)) + expected = _fnv1_hash_py(transformed) + + # Direct calculation via fnv1_hash_object_id + actual = helpers.fnv1_hash_object_id(name) + + assert actual == expected + + @pytest.mark.parametrize( "text, expected", ((["127.0.0.1", "fe80::1", "2001::2"], ["2001::2", "127.0.0.1", "fe80::1"]),), From f0391f02138d4df25505310fba08d699efdf0106 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 16:32:46 -1000 Subject: [PATCH 135/302] [api] Remove object_id from API protocol - clients compute it from name #12698 (#12818) --- esphome/components/api/api_connection.cpp | 2 +- esphome/components/api/api_connection.h | 31 +++++++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 8588651968..2ecd54bb00 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -1530,7 +1530,7 @@ bool APIConnection::send_hello_response(const HelloRequest &msg) { HelloResponse resp; resp.api_version_major = 1; - resp.api_version_minor = 13; + resp.api_version_minor = 14; // Send only the version string - the client only logs this for debugging and doesn't use it otherwise resp.set_server_info(ESPHOME_VERSION_REF); resp.set_name(StringRef(App.get_name())); diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index 47609f79b6..59c42aa033 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -24,9 +24,10 @@ struct ClientInfo { // Keepalive timeout in milliseconds static constexpr uint32_t KEEPALIVE_TIMEOUT_MS = 60000; // Maximum number of entities to process in a single batch during initial state/info sending -// This was increased from 20 to 24 after removing the unique_id field from entity info messages, -// which reduced message sizes allowing more entities per batch without exceeding packet limits -static constexpr size_t MAX_INITIAL_PER_BATCH = 24; +// API 1.14+ clients compute object_id client-side, so messages are smaller and we can fit more per batch +// TODO: Remove MAX_INITIAL_PER_BATCH_LEGACY before 2026.7.0 - all clients should support API 1.14 by then +static constexpr size_t MAX_INITIAL_PER_BATCH_LEGACY = 24; // For clients < API 1.14 (includes object_id) +static constexpr size_t MAX_INITIAL_PER_BATCH = 34; // For clients >= API 1.14 (no object_id) // Maximum number of packets to process in a single batch (platform-dependent) // This limit exists to prevent stack overflow from the PacketInfo array in process_batch_ // Each PacketInfo is 8 bytes, so 64 * 8 = 512 bytes, 32 * 8 = 256 bytes @@ -323,10 +324,16 @@ class APIConnection final : public APIServerConnection { APIConnection *conn, uint32_t remaining_size, bool is_single) { // Set common fields that are shared by all entity types msg.key = entity->get_object_id_hash(); - // Get object_id with zero heap allocation - // Static case returns direct reference, dynamic case uses buffer + + // API 1.14+ clients compute object_id client-side from the entity name + // For older clients, we must send object_id for backward compatibility + // See: https://github.com/esphome/backlog/issues/76 + // TODO: Remove this backward compat code before 2026.7.0 - all clients should support API 1.14 by then + // Buffer must remain in scope until encode_message_to_buffer is called char object_id_buf[OBJECT_ID_MAX_LEN]; - msg.set_object_id(entity->get_object_id_to(object_id_buf)); + if (!conn->client_supports_api_version(1, 14)) { + msg.set_object_id(entity->get_object_id_to(object_id_buf)); + } if (entity->has_own_name()) { msg.set_name(entity->get_name()); @@ -349,16 +356,24 @@ class APIConnection final : public APIServerConnection { inline bool check_voice_assistant_api_connection_() const; #endif + // Get the max batch size based on client API version + // API 1.14+ clients don't receive object_id, so messages are smaller and more fit per batch + // TODO: Remove this method before 2026.7.0 and use MAX_INITIAL_PER_BATCH directly + size_t get_max_batch_size_() const { + return this->client_supports_api_version(1, 14) ? MAX_INITIAL_PER_BATCH : MAX_INITIAL_PER_BATCH_LEGACY; + } + // Helper method to process multiple entities from an iterator in a batch template void process_iterator_batch_(Iterator &iterator) { size_t initial_size = this->deferred_batch_.size(); - while (!iterator.completed() && (this->deferred_batch_.size() - initial_size) < MAX_INITIAL_PER_BATCH) { + size_t max_batch = this->get_max_batch_size_(); + while (!iterator.completed() && (this->deferred_batch_.size() - initial_size) < max_batch) { iterator.advance(); } // If the batch is full, process it immediately // Note: iterator.advance() already calls schedule_batch_() via schedule_message_() - if (this->deferred_batch_.size() >= MAX_INITIAL_PER_BATCH) { + if (this->deferred_batch_.size() >= max_batch) { this->process_batch_(); } } From 1240e7907ecfb0a06f295419ac0874af07e3fdfd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 16:35:44 -1000 Subject: [PATCH 136/302] [api] Use stack-based format_hex_pretty_to for packet logging macros (#12788) --- esphome/components/api/api_frame_helper.cpp | 18 ++++++++++++++++-- .../components/api/api_frame_helper_noise.cpp | 18 ++++++++++++++++-- .../api/api_frame_helper_plaintext.cpp | 18 ++++++++++++++++-- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/esphome/components/api/api_frame_helper.cpp b/esphome/components/api/api_frame_helper.cpp index 20f8fcaf61..420f42a90a 100644 --- a/esphome/components/api/api_frame_helper.cpp +++ b/esphome/components/api/api_frame_helper.cpp @@ -13,12 +13,26 @@ namespace esphome::api { static const char *const TAG = "api.frame_helper"; +// Maximum bytes to log in hex format (168 * 3 = 504, under TX buffer size of 512) +static constexpr size_t API_MAX_LOG_BYTES = 168; + #define HELPER_LOG(msg, ...) \ ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__) #ifdef HELPER_LOG_PACKETS -#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str()) -#define LOG_PACKET_SENDING(data, len) ESP_LOGVV(TAG, "Sending raw: %s", format_hex_pretty(data, len).c_str()) +#define LOG_PACKET_RECEIVED(buffer) \ + do { \ + char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \ + ESP_LOGVV(TAG, "Received frame: %s", \ + format_hex_pretty_to(hex_buf_, (buffer).data(), \ + (buffer).size() < API_MAX_LOG_BYTES ? (buffer).size() : API_MAX_LOG_BYTES)); \ + } while (0) +#define LOG_PACKET_SENDING(data, len) \ + do { \ + char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \ + ESP_LOGVV(TAG, "Sending raw: %s", \ + format_hex_pretty_to(hex_buf_, data, (len) < API_MAX_LOG_BYTES ? (len) : API_MAX_LOG_BYTES)); \ + } while (0) #else #define LOG_PACKET_RECEIVED(buffer) ((void) 0) #define LOG_PACKET_SENDING(data, len) ((void) 0) diff --git a/esphome/components/api/api_frame_helper_noise.cpp b/esphome/components/api/api_frame_helper_noise.cpp index 1d6f32ee9d..37b497e2a1 100644 --- a/esphome/components/api/api_frame_helper_noise.cpp +++ b/esphome/components/api/api_frame_helper_noise.cpp @@ -24,12 +24,26 @@ static const char *const PROLOGUE_INIT = "NoiseAPIInit"; #endif static constexpr size_t PROLOGUE_INIT_LEN = 12; // strlen("NoiseAPIInit") +// Maximum bytes to log in hex format (168 * 3 = 504, under TX buffer size of 512) +static constexpr size_t API_MAX_LOG_BYTES = 168; + #define HELPER_LOG(msg, ...) \ ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__) #ifdef HELPER_LOG_PACKETS -#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str()) -#define LOG_PACKET_SENDING(data, len) ESP_LOGVV(TAG, "Sending raw: %s", format_hex_pretty(data, len).c_str()) +#define LOG_PACKET_RECEIVED(buffer) \ + do { \ + char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \ + ESP_LOGVV(TAG, "Received frame: %s", \ + format_hex_pretty_to(hex_buf_, (buffer).data(), \ + (buffer).size() < API_MAX_LOG_BYTES ? (buffer).size() : API_MAX_LOG_BYTES)); \ + } while (0) +#define LOG_PACKET_SENDING(data, len) \ + do { \ + char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \ + ESP_LOGVV(TAG, "Sending raw: %s", \ + format_hex_pretty_to(hex_buf_, data, (len) < API_MAX_LOG_BYTES ? (len) : API_MAX_LOG_BYTES)); \ + } while (0) #else #define LOG_PACKET_RECEIVED(buffer) ((void) 0) #define LOG_PACKET_SENDING(data, len) ((void) 0) diff --git a/esphome/components/api/api_frame_helper_plaintext.cpp b/esphome/components/api/api_frame_helper_plaintext.cpp index b5d90b2429..8b7d002d7c 100644 --- a/esphome/components/api/api_frame_helper_plaintext.cpp +++ b/esphome/components/api/api_frame_helper_plaintext.cpp @@ -18,12 +18,26 @@ namespace esphome::api { static const char *const TAG = "api.plaintext"; +// Maximum bytes to log in hex format (168 * 3 = 504, under TX buffer size of 512) +static constexpr size_t API_MAX_LOG_BYTES = 168; + #define HELPER_LOG(msg, ...) \ ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__) #ifdef HELPER_LOG_PACKETS -#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str()) -#define LOG_PACKET_SENDING(data, len) ESP_LOGVV(TAG, "Sending raw: %s", format_hex_pretty(data, len).c_str()) +#define LOG_PACKET_RECEIVED(buffer) \ + do { \ + char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \ + ESP_LOGVV(TAG, "Received frame: %s", \ + format_hex_pretty_to(hex_buf_, (buffer).data(), \ + (buffer).size() < API_MAX_LOG_BYTES ? (buffer).size() : API_MAX_LOG_BYTES)); \ + } while (0) +#define LOG_PACKET_SENDING(data, len) \ + do { \ + char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \ + ESP_LOGVV(TAG, "Sending raw: %s", \ + format_hex_pretty_to(hex_buf_, data, (len) < API_MAX_LOG_BYTES ? (len) : API_MAX_LOG_BYTES)); \ + } while (0) #else #define LOG_PACKET_RECEIVED(buffer) ((void) 0) #define LOG_PACKET_SENDING(data, len) ((void) 0) From a57011b50bc4e4a4e22bab83f2605c7003a030c0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 16:36:57 -1000 Subject: [PATCH 137/302] [kuntze] Use stack buffer for hex formatting in verbose logging (#12775) --- esphome/components/kuntze/kuntze.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/esphome/components/kuntze/kuntze.cpp b/esphome/components/kuntze/kuntze.cpp index 30f98aaa99..1b772d062c 100644 --- a/esphome/components/kuntze/kuntze.cpp +++ b/esphome/components/kuntze/kuntze.cpp @@ -1,4 +1,5 @@ #include "kuntze.h" +#include "esphome/core/helpers.h" #include "esphome/core/log.h" #include "esphome/core/application.h" @@ -10,11 +11,17 @@ static const char *const TAG = "kuntze"; static const uint8_t CMD_READ_REG = 0x03; static const uint16_t REGISTER[] = {4136, 4160, 4680, 6000, 4688, 4728, 5832}; +// Maximum bytes to log for Modbus responses (2 registers = 4, plus count = 5) +static constexpr size_t KUNTZE_MAX_LOG_BYTES = 8; + void Kuntze::on_modbus_data(const std::vector &data) { auto get_16bit = [&](int i) -> uint16_t { return (uint16_t(data[i * 2]) << 8) | uint16_t(data[i * 2 + 1]); }; this->waiting_ = false; - ESP_LOGV(TAG, "Data: %s", format_hex_pretty(data).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_pretty_size(KUNTZE_MAX_LOG_BYTES)]; +#endif + ESP_LOGV(TAG, "Data: %s", format_hex_pretty_to(hex_buf, data.data(), data.size())); float value = (float) get_16bit(0); for (int i = 0; i < data[3]; i++) From d946ddabfd312b552890d5516ca2445a8e6641d8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 16:37:16 -1000 Subject: [PATCH 138/302] [xiaomi_ble] Use stack-based hex formatting in verbose logging (#12793) --- esphome/components/xiaomi_ble/xiaomi_ble.cpp | 32 ++++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/esphome/components/xiaomi_ble/xiaomi_ble.cpp b/esphome/components/xiaomi_ble/xiaomi_ble.cpp index 564870d74e..9f25063133 100644 --- a/esphome/components/xiaomi_ble/xiaomi_ble.cpp +++ b/esphome/components/xiaomi_ble/xiaomi_ble.cpp @@ -12,6 +12,9 @@ namespace xiaomi_ble { static const char *const TAG = "xiaomi_ble"; +// Maximum bytes to log in very verbose hex output (covers largest packet of ~24 bytes) +static constexpr size_t XIAOMI_MAX_LOG_BYTES = 32; + bool parse_xiaomi_value(uint16_t value_type, const uint8_t *data, uint8_t value_length, XiaomiParseResult &result) { // button pressed, 3 bytes, only byte 3 is used for supported devices so far if ((value_type == 0x1001) && (value_length == 3)) { @@ -263,7 +266,10 @@ optional parse_xiaomi_header(const esp32_ble_tracker::Service bool decrypt_xiaomi_payload(std::vector &raw, const uint8_t *bindkey, const uint64_t &address) { if ((raw.size() != 19) && ((raw.size() < 22) || (raw.size() > 24))) { ESP_LOGVV(TAG, "decrypt_xiaomi_payload(): data packet has wrong size (%d)!", raw.size()); - ESP_LOGVV(TAG, " Packet : %s", format_hex_pretty(raw.data(), raw.size()).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + char hex_buf[format_hex_pretty_size(XIAOMI_MAX_LOG_BYTES)]; +#endif + ESP_LOGVV(TAG, " Packet : %s", format_hex_pretty_to(hex_buf, raw.data(), raw.size())); return false; } @@ -320,12 +326,17 @@ bool decrypt_xiaomi_payload(std::vector &raw, const uint8_t *bindkey, c memcpy(mac_address + 4, mac_reverse + 1, 1); memcpy(mac_address + 5, mac_reverse, 1); ESP_LOGVV(TAG, "decrypt_xiaomi_payload(): authenticated decryption failed."); - ESP_LOGVV(TAG, " MAC address : %s", format_mac_address_pretty(mac_address).c_str()); - ESP_LOGVV(TAG, " Packet : %s", format_hex_pretty(raw.data(), raw.size()).c_str()); - ESP_LOGVV(TAG, " Key : %s", format_hex_pretty(vector.key, vector.keysize).c_str()); - ESP_LOGVV(TAG, " Iv : %s", format_hex_pretty(vector.iv, vector.ivsize).c_str()); - ESP_LOGVV(TAG, " Cipher : %s", format_hex_pretty(vector.ciphertext, vector.datasize).c_str()); - ESP_LOGVV(TAG, " Tag : %s", format_hex_pretty(vector.tag, vector.tagsize).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(mac_address, mac_buf); + char hex_buf[format_hex_pretty_size(XIAOMI_MAX_LOG_BYTES)]; +#endif + ESP_LOGVV(TAG, " MAC address : %s", mac_buf); + ESP_LOGVV(TAG, " Packet : %s", format_hex_pretty_to(hex_buf, raw.data(), raw.size())); + ESP_LOGVV(TAG, " Key : %s", format_hex_pretty_to(hex_buf, vector.key, vector.keysize)); + ESP_LOGVV(TAG, " Iv : %s", format_hex_pretty_to(hex_buf, vector.iv, vector.ivsize)); + ESP_LOGVV(TAG, " Cipher : %s", format_hex_pretty_to(hex_buf, vector.ciphertext, vector.datasize)); + ESP_LOGVV(TAG, " Tag : %s", format_hex_pretty_to(hex_buf, vector.tag, vector.tagsize)); mbedtls_ccm_free(&ctx); return false; } @@ -341,8 +352,11 @@ bool decrypt_xiaomi_payload(std::vector &raw, const uint8_t *bindkey, c raw[0] &= ~0x08; ESP_LOGVV(TAG, "decrypt_xiaomi_payload(): authenticated decryption passed."); - ESP_LOGVV(TAG, " Plaintext : %s, Packet : %d", format_hex_pretty(raw.data() + cipher_pos, vector.datasize).c_str(), - static_cast(raw[4])); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + char hex_buf[format_hex_pretty_size(XIAOMI_MAX_LOG_BYTES)]; +#endif + ESP_LOGVV(TAG, " Plaintext : %s, Packet : %d", + format_hex_pretty_to(hex_buf, raw.data() + cipher_pos, vector.datasize), static_cast(raw[4])); mbedtls_ccm_free(&ctx); return true; From 64ba37633019b46e18e011b87285ee5922a90c72 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 16:37:38 -1000 Subject: [PATCH 139/302] [hte501] Use stack-based hex formatting in verbose logging (#12794) --- esphome/components/hte501/hte501.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/esphome/components/hte501/hte501.cpp b/esphome/components/hte501/hte501.cpp index b7d3be63fe..cde6886109 100644 --- a/esphome/components/hte501/hte501.cpp +++ b/esphome/components/hte501/hte501.cpp @@ -7,6 +7,8 @@ namespace hte501 { static const char *const TAG = "hte501"; +static constexpr size_t HTE501_SERIAL_NUMBER_SIZE = 7; + void HTE501Component::setup() { uint8_t address[] = {0x70, 0x29}; uint8_t identification[9]; @@ -16,7 +18,10 @@ void HTE501Component::setup() { this->mark_failed(); return; } - ESP_LOGV(TAG, " Serial Number: 0x%s", format_hex(identification + 0, 7).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char serial_hex[format_hex_size(HTE501_SERIAL_NUMBER_SIZE)]; +#endif + ESP_LOGV(TAG, " Serial Number: 0x%s", format_hex_to(serial_hex, identification, HTE501_SERIAL_NUMBER_SIZE)); } void HTE501Component::dump_config() { From ace48464a8f435f43369a3dd791dede7f2b83647 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 16:39:44 -1000 Subject: [PATCH 140/302] [addressable_light] Use StringRef to avoid allocation when saving effect name (#12759) --- .../addressable_light/addressable_light_display.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/esphome/components/addressable_light/addressable_light_display.h b/esphome/components/addressable_light/addressable_light_display.h index f47389fd05..53f8604b7d 100644 --- a/esphome/components/addressable_light/addressable_light_display.h +++ b/esphome/components/addressable_light/addressable_light_display.h @@ -25,11 +25,13 @@ class AddressableLightDisplay : public display::DisplayBuffer { if (enabled_ && !enabled) { // enabled -> disabled // - Tell the parent light to refresh, effectively wiping the display. Also // restores the previous effect (if any). - light_state_->make_call().set_effect(this->last_effect_).perform(); + if (this->last_effect_index_.has_value()) { + light_state_->make_call().set_effect(*this->last_effect_index_).perform(); + } } else if (!enabled_ && enabled) { // disabled -> enabled - // - Save the current effect. - this->last_effect_ = light_state_->get_effect_name(); + // - Save the current effect index. + this->last_effect_index_ = light_state_->get_current_effect_index(); // - Disable any current effect. light_state_->make_call().set_effect(0).perform(); } @@ -56,7 +58,7 @@ class AddressableLightDisplay : public display::DisplayBuffer { int32_t width_; int32_t height_; std::vector addressable_light_buffer_; - optional last_effect_; + optional last_effect_index_; optional> pixel_mapper_f_; }; } // namespace addressable_light From 016eeef04afcdb5665ad7a882d97ee4e01b4ffc4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 16:40:06 -1000 Subject: [PATCH 141/302] [tee501] Use stack-based hex formatting in verbose logging (#12795) --- esphome/components/tee501/tee501.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/esphome/components/tee501/tee501.cpp b/esphome/components/tee501/tee501.cpp index d6513dbbe0..06481b628b 100644 --- a/esphome/components/tee501/tee501.cpp +++ b/esphome/components/tee501/tee501.cpp @@ -7,6 +7,8 @@ namespace tee501 { static const char *const TAG = "tee501"; +static constexpr size_t TEE501_SERIAL_NUMBER_SIZE = 7; + void TEE501Component::setup() { uint8_t address[] = {0x70, 0x29}; uint8_t identification[9]; @@ -17,7 +19,10 @@ void TEE501Component::setup() { this->mark_failed(); return; } - ESP_LOGV(TAG, " Serial Number: 0x%s", format_hex(identification + 0, 7).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char serial_hex[format_hex_size(TEE501_SERIAL_NUMBER_SIZE)]; +#endif + ESP_LOGV(TAG, " Serial Number: 0x%s", format_hex_to(serial_hex, identification, TEE501_SERIAL_NUMBER_SIZE)); } void TEE501Component::dump_config() { From c3ffc1635d90fdf73258b4140c8c682b7693b7f7 Mon Sep 17 00:00:00 2001 From: Thomas Rupprecht Date: Sat, 3 Jan 2026 03:40:28 +0100 Subject: [PATCH 142/302] =?UTF-8?q?[gps]=20add=20icon=20for=20HDOP=20and?= =?UTF-8?q?=20use=20correct=20state=5Fclass=20for=20longitude=20and?= =?UTF-8?q?=E2=80=A6=20(#12718)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- esphome/components/gps/__init__.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/esphome/components/gps/__init__.py b/esphome/components/gps/__init__.py index a872cf7015..2135189bd5 100644 --- a/esphome/components/gps/__init__.py +++ b/esphome/components/gps/__init__.py @@ -11,6 +11,7 @@ from esphome.const import ( CONF_SPEED, DEVICE_CLASS_SPEED, STATE_CLASS_MEASUREMENT, + STATE_CLASS_MEASUREMENT_ANGLE, UNIT_DEGREES, UNIT_KILOMETER_PER_HOUR, UNIT_METER, @@ -21,6 +22,7 @@ CONF_HDOP = "hdop" ICON_ALTIMETER = "mdi:altimeter" ICON_COMPASS = "mdi:compass" +ICON_CIRCLE_DOUBLE = "mdi:circle-double" ICON_LATITUDE = "mdi:latitude" ICON_LONGITUDE = "mdi:longitude" ICON_SATELLITE = "mdi:satellite-variant" @@ -50,7 +52,7 @@ CONFIG_SCHEMA = cv.All( unit_of_measurement=UNIT_DEGREES, icon=ICON_LONGITUDE, accuracy_decimals=6, - state_class=STATE_CLASS_MEASUREMENT, + state_class=STATE_CLASS_MEASUREMENT_ANGLE, ), cv.Optional(CONF_SPEED): sensor.sensor_schema( unit_of_measurement=UNIT_KILOMETER_PER_HOUR, @@ -63,7 +65,7 @@ CONFIG_SCHEMA = cv.All( unit_of_measurement=UNIT_DEGREES, icon=ICON_COMPASS, accuracy_decimals=2, - state_class=STATE_CLASS_MEASUREMENT, + state_class=STATE_CLASS_MEASUREMENT_ANGLE, ), cv.Optional(CONF_ALTITUDE): sensor.sensor_schema( unit_of_measurement=UNIT_METER, @@ -72,11 +74,14 @@ CONFIG_SCHEMA = cv.All( state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional(CONF_SATELLITES): sensor.sensor_schema( + # no unit_of_measurement icon=ICON_SATELLITE, accuracy_decimals=0, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional(CONF_HDOP): sensor.sensor_schema( + # no unit_of_measurement + icon=ICON_CIRCLE_DOUBLE, accuracy_decimals=3, state_class=STATE_CLASS_MEASUREMENT, ), From bc1af007b44d2bb67a72f966d58eba556253e6d4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 16:40:47 -1000 Subject: [PATCH 143/302] [vbus] Use stack-based hex formatting in verbose logging (#12796) --- esphome/components/vbus/vbus.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/esphome/components/vbus/vbus.cpp b/esphome/components/vbus/vbus.cpp index e474dcfe17..b9496a08de 100644 --- a/esphome/components/vbus/vbus.cpp +++ b/esphome/components/vbus/vbus.cpp @@ -8,6 +8,9 @@ namespace vbus { static const char *const TAG = "vbus"; +// Maximum bytes to log in verbose hex output (16 frames * 4 bytes = 64 bytes typical) +static constexpr size_t VBUS_MAX_LOG_BYTES = 64; + void VBus::dump_config() { ESP_LOGCONFIG(TAG, "VBus:"); check_uart_settings(9600); @@ -101,8 +104,11 @@ void VBus::loop() { this->buffer_.push_back(this->fbytes_[i]); if (++this->cframe_ < this->frames_) continue; +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_size(VBUS_MAX_LOG_BYTES)]; +#endif ESP_LOGV(TAG, "P2 C%04x %04x->%04x: %s", this->command_, this->source_, this->dest_, - format_hex(this->buffer_).c_str()); + format_hex_to(hex_buf, this->buffer_.data(), this->buffer_.size())); for (auto &listener : this->listeners_) listener->on_message(this->command_, this->source_, this->dest_, this->buffer_); this->state_ = 0; From 6409970f6e5e64c2694f685138ee1888f2140f58 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 16:41:02 -1000 Subject: [PATCH 144/302] [uponor_smatrix] Use stack-based hex formatting in verbose logging (#12797) Co-authored-by: Stefan Rado <628587+kroimon@users.noreply.github.com> --- esphome/components/uponor_smatrix/uponor_smatrix.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/esphome/components/uponor_smatrix/uponor_smatrix.cpp b/esphome/components/uponor_smatrix/uponor_smatrix.cpp index 221f07c80e..4c3a4b05df 100644 --- a/esphome/components/uponor_smatrix/uponor_smatrix.cpp +++ b/esphome/components/uponor_smatrix/uponor_smatrix.cpp @@ -8,6 +8,9 @@ namespace uponor_smatrix { static const char *const TAG = "uponor_smatrix"; +// Maximum bytes to log in verbose hex output +static constexpr size_t UPONOR_MAX_LOG_BYTES = 36; + void UponorSmatrixComponent::setup() { #ifdef USE_TIME if (this->time_id_ != nullptr) { @@ -97,8 +100,11 @@ bool UponorSmatrixComponent::parse_byte_(uint8_t byte) { return false; } +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char hex_buf[format_hex_size(UPONOR_MAX_LOG_BYTES)]; +#endif ESP_LOGV(TAG, "Received packet: addr=%08X, data=%s, crc=%04X", device_address, - format_hex(&packet[4], packet_len - 6).c_str(), crc); + format_hex_to(hex_buf, &packet[4], packet_len - 6), crc); // Handle packet size_t data_len = (packet_len - 6) / 3; From c4d339a4c9be9035f1a4d6a1d5df213252cbba9d Mon Sep 17 00:00:00 2001 From: Robert Klep Date: Sat, 3 Jan 2026 05:42:18 +0100 Subject: [PATCH 145/302] [core] Add CONF_ON_START (#12439) (#12440) --- esphome/components/esp32_improv/__init__.py | 3 +-- esphome/components/voice_assistant/__init__.py | 2 +- esphome/const.py | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/esp32_improv/__init__.py b/esphome/components/esp32_improv/__init__.py index 2e69d400ca..ad2f057163 100644 --- a/esphome/components/esp32_improv/__init__.py +++ b/esphome/components/esp32_improv/__init__.py @@ -3,7 +3,7 @@ import esphome.codegen as cg from esphome.components import binary_sensor, esp32_ble, improv_base, output from esphome.components.esp32_ble import BTLoggers import esphome.config_validation as cv -from esphome.const import CONF_ID, CONF_ON_STATE, CONF_TRIGGER_ID +from esphome.const import CONF_ID, CONF_ON_START, CONF_ON_STATE, CONF_TRIGGER_ID AUTO_LOAD = ["esp32_ble_server", "improv_base"] CODEOWNERS = ["@jesserockz"] @@ -15,7 +15,6 @@ CONF_BLE_SERVER_ID = "ble_server_id" CONF_IDENTIFY_DURATION = "identify_duration" CONF_ON_PROVISIONED = "on_provisioned" CONF_ON_PROVISIONING = "on_provisioning" -CONF_ON_START = "on_start" CONF_ON_STOP = "on_stop" CONF_STATUS_INDICATOR = "status_indicator" CONF_WIFI_TIMEOUT = "wifi_timeout" diff --git a/esphome/components/voice_assistant/__init__.py b/esphome/components/voice_assistant/__init__.py index 59c7ec8383..d28c786dd8 100644 --- a/esphome/components/voice_assistant/__init__.py +++ b/esphome/components/voice_assistant/__init__.py @@ -11,6 +11,7 @@ from esphome.const import ( CONF_ON_CLIENT_DISCONNECTED, CONF_ON_ERROR, CONF_ON_IDLE, + CONF_ON_START, CONF_SPEAKER, ) @@ -24,7 +25,6 @@ CONF_ON_INTENT_END = "on_intent_end" CONF_ON_INTENT_PROGRESS = "on_intent_progress" CONF_ON_INTENT_START = "on_intent_start" CONF_ON_LISTENING = "on_listening" -CONF_ON_START = "on_start" CONF_ON_STT_END = "on_stt_end" CONF_ON_STT_VAD_END = "on_stt_vad_end" CONF_ON_STT_VAD_START = "on_stt_vad_start" diff --git a/esphome/const.py b/esphome/const.py index 1d46e81f9d..518247aa60 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -710,6 +710,7 @@ CONF_ON_RELEASE = "on_release" CONF_ON_RESPONSE = "on_response" CONF_ON_SHUTDOWN = "on_shutdown" CONF_ON_SPEED_SET = "on_speed_set" +CONF_ON_START = "on_start" CONF_ON_STATE = "on_state" CONF_ON_SUCCESS = "on_success" CONF_ON_TAG = "on_tag" From 2a5be725c8d807715e6ea748a4ee2ea85c91cf7d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 19:50:30 -1000 Subject: [PATCH 146/302] [api] Enable zero-copy bytes SOURCE_BOTH messages (#12816) --- esphome/components/api/api.proto | 4 ++-- esphome/components/api/api_pb2.h | 16 ++++++++-------- script/api_protobuf/api_protobuf.py | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index 43b721c2d5..5efd839673 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -2425,7 +2425,7 @@ message ZWaveProxyFrame { option (ifdef) = "USE_ZWAVE_PROXY"; option (no_delay) = true; - bytes data = 1 [(pointer_to_buffer) = true]; + bytes data = 1; } enum ZWaveProxyRequestType { @@ -2439,5 +2439,5 @@ message ZWaveProxyRequest { option (ifdef) = "USE_ZWAVE_PROXY"; ZWaveProxyRequestType type = 1; - bytes data = 2 [(pointer_to_buffer) = true]; + bytes data = 2; } diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index 6275b4c211..e08cf65bb9 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -1046,7 +1046,7 @@ class SubscribeLogsRequest final : public ProtoDecodableMessage { class SubscribeLogsResponse final : public ProtoMessage { public: static constexpr uint8_t MESSAGE_TYPE = 29; - static constexpr uint8_t ESTIMATED_SIZE = 11; + static constexpr uint8_t ESTIMATED_SIZE = 21; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "subscribe_logs_response"; } #endif @@ -1069,7 +1069,7 @@ class SubscribeLogsResponse final : public ProtoMessage { class NoiseEncryptionSetKeyRequest final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 124; - static constexpr uint8_t ESTIMATED_SIZE = 9; + static constexpr uint8_t ESTIMATED_SIZE = 19; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "noise_encryption_set_key_request"; } #endif @@ -1161,7 +1161,7 @@ class HomeassistantActionRequest final : public ProtoMessage { class HomeassistantActionResponse final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 130; - static constexpr uint8_t ESTIMATED_SIZE = 24; + static constexpr uint8_t ESTIMATED_SIZE = 34; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "homeassistant_action_response"; } #endif @@ -1388,7 +1388,7 @@ class ListEntitiesCameraResponse final : public InfoResponseProtoMessage { class CameraImageResponse final : public StateResponseProtoMessage { public: static constexpr uint8_t MESSAGE_TYPE = 44; - static constexpr uint8_t ESTIMATED_SIZE = 20; + static constexpr uint8_t ESTIMATED_SIZE = 30; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "camera_image_response"; } #endif @@ -2123,7 +2123,7 @@ class BluetoothGATTReadRequest final : public ProtoDecodableMessage { class BluetoothGATTReadResponse final : public ProtoMessage { public: static constexpr uint8_t MESSAGE_TYPE = 74; - static constexpr uint8_t ESTIMATED_SIZE = 17; + static constexpr uint8_t ESTIMATED_SIZE = 27; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "bluetooth_gatt_read_response"; } #endif @@ -2146,7 +2146,7 @@ class BluetoothGATTReadResponse final : public ProtoMessage { class BluetoothGATTWriteRequest final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 75; - static constexpr uint8_t ESTIMATED_SIZE = 19; + static constexpr uint8_t ESTIMATED_SIZE = 29; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "bluetooth_gatt_write_request"; } #endif @@ -2182,7 +2182,7 @@ class BluetoothGATTReadDescriptorRequest final : public ProtoDecodableMessage { class BluetoothGATTWriteDescriptorRequest final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 77; - static constexpr uint8_t ESTIMATED_SIZE = 17; + static constexpr uint8_t ESTIMATED_SIZE = 27; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "bluetooth_gatt_write_descriptor_request"; } #endif @@ -2218,7 +2218,7 @@ class BluetoothGATTNotifyRequest final : public ProtoDecodableMessage { class BluetoothGATTNotifyDataResponse final : public ProtoMessage { public: static constexpr uint8_t MESSAGE_TYPE = 79; - static constexpr uint8_t ESTIMATED_SIZE = 17; + static constexpr uint8_t ESTIMATED_SIZE = 27; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "bluetooth_gatt_notify_data_response"; } #endif diff --git a/script/api_protobuf/api_protobuf.py b/script/api_protobuf/api_protobuf.py index 5b68c6a3d2..7293f2abbc 100755 --- a/script/api_protobuf/api_protobuf.py +++ b/script/api_protobuf/api_protobuf.py @@ -362,12 +362,12 @@ def create_field_type_info( # Traditional fixed array approach with copy (takes priority) return FixedArrayBytesType(field, fixed_size) - # For SOURCE_CLIENT only messages (decode but no encode), use pointer + # For messages that decode (SOURCE_CLIENT or SOURCE_BOTH), use pointer # for zero-copy access to the receive buffer - if needs_decode and not needs_encode: + if needs_decode: return PointerToBytesBufferType(field, None) - # For SOURCE_BOTH/SOURCE_SERVER, explicit annotation is still needed + # For SOURCE_SERVER (encode only), explicit annotation is still needed if get_field_opt(field, pb.pointer_to_buffer, False): return PointerToBytesBufferType(field, None) From 00fd4f2fdd316a58ce3f104d7ea296592e10b0d9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 19:51:07 -1000 Subject: [PATCH 147/302] [esp8266] Exclude unused waveform code to save ~596 bytes RAM (#12690) --- esphome/components/esp8266/__init__.py | 29 ++++++++++- esphome/components/esp8266/const.py | 20 ++++++++ .../esp8266/exclude_waveform.py.script | 50 +++++++++++++++++++ esphome/components/esp8266/waveform_stubs.cpp | 34 +++++++++++++ esphome/components/esp8266_pwm/output.py | 5 +- script/ci-custom.py | 2 + 6 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 esphome/components/esp8266/exclude_waveform.py.script create mode 100644 esphome/components/esp8266/waveform_stubs.cpp diff --git a/esphome/components/esp8266/__init__.py b/esphome/components/esp8266/__init__.py index c4969a79b2..77ccaf52c1 100644 --- a/esphome/components/esp8266/__init__.py +++ b/esphome/components/esp8266/__init__.py @@ -28,6 +28,7 @@ from .const import ( KEY_ESP8266, KEY_FLASH_SIZE, KEY_PIN_INITIAL_STATES, + KEY_WAVEFORM_REQUIRED, esp8266_ns, ) from .gpio import PinInitialState, add_pin_initial_states_array @@ -192,7 +193,12 @@ async def to_code(config): cg.add_platformio_option( "extra_scripts", - ["pre:testing_mode.py", "pre:exclude_updater.py", "post:post_build.py"], + [ + "pre:testing_mode.py", + "pre:exclude_updater.py", + "pre:exclude_waveform.py", + "post:post_build.py", + ], ) conf = config[CONF_FRAMEWORK] @@ -264,10 +270,24 @@ async def to_code(config): cg.add_platformio_option("board_build.ldscript", ld_script) CORE.add_job(add_pin_initial_states_array) + CORE.add_job(finalize_waveform_config) + + +@coroutine_with_priority(CoroPriority.WORKAROUNDS) +async def finalize_waveform_config() -> None: + """Add waveform stubs define if waveform is not required. + + This runs at WORKAROUNDS priority (-999) to ensure all components + have had a chance to call require_waveform() first. + """ + if not CORE.data.get(KEY_ESP8266, {}).get(KEY_WAVEFORM_REQUIRED, False): + # No component needs waveform - enable stubs and exclude Arduino waveform code + # Use build flag (visible to both C++ code and PlatformIO script) + cg.add_build_flag("-DUSE_ESP8266_WAVEFORM_STUBS") # Called by writer.py -def copy_files(): +def copy_files() -> None: dir = Path(__file__).parent post_build_file = dir / "post_build.py.script" copy_file_if_changed( @@ -284,3 +304,8 @@ def copy_files(): exclude_updater_file, CORE.relative_build_path("exclude_updater.py"), ) + exclude_waveform_file = dir / "exclude_waveform.py.script" + copy_file_if_changed( + exclude_waveform_file, + CORE.relative_build_path("exclude_waveform.py"), + ) diff --git a/esphome/components/esp8266/const.py b/esphome/components/esp8266/const.py index b718306b01..14425cde68 100644 --- a/esphome/components/esp8266/const.py +++ b/esphome/components/esp8266/const.py @@ -1,4 +1,5 @@ import esphome.codegen as cg +from esphome.core import CORE KEY_ESP8266 = "esp8266" KEY_BOARD = "board" @@ -6,6 +7,25 @@ KEY_PIN_INITIAL_STATES = "pin_initial_states" CONF_RESTORE_FROM_FLASH = "restore_from_flash" CONF_EARLY_PIN_INIT = "early_pin_init" KEY_FLASH_SIZE = "flash_size" +KEY_WAVEFORM_REQUIRED = "waveform_required" # esp8266 namespace is already defined by arduino, manually prefix esphome esp8266_ns = cg.global_ns.namespace("esphome").namespace("esp8266") + + +def require_waveform() -> None: + """Mark that Arduino waveform/PWM support is required. + + Call this from components that need the Arduino waveform generator + (startWaveform, stopWaveform, analogWrite, Tone, Servo). + + If no component calls this, the waveform code is excluded from the build + to save ~596 bytes of RAM and 464 bytes of flash. + + Example: + from esphome.components.esp8266.const import require_waveform + + async def to_code(config): + require_waveform() + """ + CORE.data.setdefault(KEY_ESP8266, {})[KEY_WAVEFORM_REQUIRED] = True diff --git a/esphome/components/esp8266/exclude_waveform.py.script b/esphome/components/esp8266/exclude_waveform.py.script new file mode 100644 index 0000000000..35d6bc31f6 --- /dev/null +++ b/esphome/components/esp8266/exclude_waveform.py.script @@ -0,0 +1,50 @@ +# pylint: disable=E0602 +Import("env") # noqa + +import os + +# Filter out waveform/PWM code from the Arduino core build +# This saves ~596 bytes of RAM and 464 bytes of flash by not +# instantiating the waveform generator state structures (wvfState + pwmState). +# +# The waveform code is used by: analogWrite, Tone, Servo, and direct +# startWaveform/stopWaveform calls. ESPHome's esp8266_pwm component +# calls require_waveform() to keep this code when needed. +# +# When excluded, we provide stub implementations of stopWaveform() and +# _stopPWM() since digitalWrite() calls these unconditionally. + + +def has_define_flag(env, name): + """Check if a define exists in the build flags.""" + define_flag = f"-D{name}" + # Check BUILD_FLAGS (where ESPHome puts its defines) + for flag in env.get("BUILD_FLAGS", []): + if flag == define_flag or flag.startswith(f"{define_flag}="): + return True + # Also check CPPDEFINES list (parsed defines) + for define in env.get("CPPDEFINES", []): + if isinstance(define, tuple): + if define[0] == name: + return True + elif define == name: + return True + return False + +# USE_ESP8266_WAVEFORM_STUBS is defined when no component needs waveform +if has_define_flag(env, "USE_ESP8266_WAVEFORM_STUBS"): + + def filter_waveform_from_core(env, node): + """Filter callback to exclude waveform files from framework build.""" + path = node.get_path() + filename = os.path.basename(path) + if filename in ( + "core_esp8266_waveform_pwm.cpp", + "core_esp8266_waveform_phase.cpp", + ): + print(f"ESPHome: Excluding {filename} from build (waveform not required)") + return None + return node + + # Apply the filter to framework sources + env.AddBuildMiddleware(filter_waveform_from_core, "**/cores/esp8266/*.cpp") diff --git a/esphome/components/esp8266/waveform_stubs.cpp b/esphome/components/esp8266/waveform_stubs.cpp new file mode 100644 index 0000000000..686e03c6a9 --- /dev/null +++ b/esphome/components/esp8266/waveform_stubs.cpp @@ -0,0 +1,34 @@ +#ifdef USE_ESP8266_WAVEFORM_STUBS + +// Stub implementations for Arduino waveform/PWM functions. +// +// When the waveform generator is not needed (no esp8266_pwm component), +// we exclude core_esp8266_waveform_pwm.cpp from the build to save ~596 bytes +// of RAM and 464 bytes of flash. +// +// These stubs satisfy calls from the Arduino GPIO code when the real +// waveform implementation is excluded. They must be in the global namespace +// with C linkage to match the Arduino core function declarations. + +#include + +// Empty namespace to satisfy linter - actual stubs must be at global scope +namespace esphome::esp8266 {} // namespace esphome::esp8266 + +extern "C" { + +// Called by Arduino GPIO code to stop any waveform on a pin +int stopWaveform(uint8_t pin) { + (void) pin; + return 1; // Success (no waveform to stop) +} + +// Called by Arduino GPIO code to stop any PWM on a pin +bool _stopPWM(uint8_t pin) { + (void) pin; + return false; // No PWM was running +} + +} // extern "C" + +#endif // USE_ESP8266_WAVEFORM_STUBS diff --git a/esphome/components/esp8266_pwm/output.py b/esphome/components/esp8266_pwm/output.py index 2ddf4b9014..a78831c516 100644 --- a/esphome/components/esp8266_pwm/output.py +++ b/esphome/components/esp8266_pwm/output.py @@ -1,6 +1,7 @@ from esphome import automation, pins import esphome.codegen as cg from esphome.components import output +from esphome.components.esp8266.const import require_waveform import esphome.config_validation as cv from esphome.const import CONF_FREQUENCY, CONF_ID, CONF_NUMBER, CONF_PIN @@ -34,7 +35,9 @@ CONFIG_SCHEMA = cv.All( ) -async def to_code(config): +async def to_code(config) -> None: + require_waveform() + var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) await output.register_output(var, config) diff --git a/script/ci-custom.py b/script/ci-custom.py index 609d89403f..f0676d594b 100755 --- a/script/ci-custom.py +++ b/script/ci-custom.py @@ -552,6 +552,8 @@ def convert_path_to_relative(abspath, current): exclude=[ "esphome/components/libretiny/generate_components.py", "esphome/components/web_server/__init__.py", + # const.py has absolute import in docstring example for external components + "esphome/components/esp8266/const.py", ], ) def lint_relative_py_import(fname: Path, line, col, content): From 98e3695c897974ae746232192947df5c079bbb2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 3 Jan 2026 06:45:17 +0000 Subject: [PATCH 148/302] Bump aioesphomeapi from 43.9.1 to 43.10.0 (#12821) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d457be9cd2..63cc7e4a16 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile esptool==5.1.0 click==8.1.7 esphome-dashboard==20251013.0 -aioesphomeapi==43.9.1 +aioesphomeapi==43.10.0 zeroconf==0.148.0 puremagic==1.30 ruamel.yaml==0.18.17 # dashboard_import From 538c6544a0430d20f60e17215d3050e601caff3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Jan 2026 20:51:56 -1000 Subject: [PATCH 149/302] Bump ruamel-yaml from 0.18.17 to 0.19.1 (#12768) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 63cc7e4a16..833ccbb0ed 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ esphome-dashboard==20251013.0 aioesphomeapi==43.10.0 zeroconf==0.148.0 puremagic==1.30 -ruamel.yaml==0.18.17 # dashboard_import +ruamel.yaml==0.19.1 # dashboard_import ruamel.yaml.clib==0.2.15 # dashboard_import esphome-glyphsets==0.2.0 pillow==11.3.0 From 89b550b74a429b13d5c8e145a24b5e6c17dbfa4e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 21:00:46 -1000 Subject: [PATCH 150/302] [tests] Remove reserved / character from entity names in component tests (#12820) --- tests/components/micronova/common.yaml | 2 +- tests/components/opentherm/common.yaml | 8 ++++---- tests/components/zhlt01/common.yaml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/components/micronova/common.yaml b/tests/components/micronova/common.yaml index 660970350a..5870d3726f 100644 --- a/tests/components/micronova/common.yaml +++ b/tests/components/micronova/common.yaml @@ -41,7 +41,7 @@ sensor: switch: - platform: micronova stove: - name: Stove on/off + name: Stove text_sensor: - platform: micronova diff --git a/tests/components/opentherm/common.yaml b/tests/components/opentherm/common.yaml index 1e58a04bf0..fb5fb39eb8 100644 --- a/tests/components/opentherm/common.yaml +++ b/tests/components/opentherm/common.yaml @@ -92,7 +92,7 @@ sensor: ch_pump_starts: name: "Boiler Number of starts CH pump" dhw_pump_valve_starts: - name: "Boiler Number of starts DHW pump/valve" + name: "Boiler Number of starts DHW pump valve" dhw_burner_starts: name: "Boiler Number of starts burner during DHW mode" burner_operation_hours: @@ -139,7 +139,7 @@ binary_sensor: dhw_present: name: "Boiler DHW present" control_type_on_off: - name: "Boiler Control type is on/off" + name: "Boiler Control type is on-off" cooling_supported: name: "Boiler Cooling supported" dhw_storage_tank: @@ -153,9 +153,9 @@ binary_sensor: max_ch_setpoint_transfer_enabled: name: "Boiler CH maximum setpoint transfer enabled" dhw_setpoint_rw: - name: "Boiler DHW setpoint read/write" + name: "Boiler DHW setpoint read-write" max_ch_setpoint_rw: - name: "Boiler CH maximum setpoint read/write" + name: "Boiler CH maximum setpoint read-write" switch: - platform: opentherm diff --git a/tests/components/zhlt01/common.yaml b/tests/components/zhlt01/common.yaml index d0fd531c87..483f9f3c4e 100644 --- a/tests/components/zhlt01/common.yaml +++ b/tests/components/zhlt01/common.yaml @@ -1,4 +1,4 @@ climate: - platform: zhlt01 - name: ZH/LT-01 Climate + name: ZH-LT-01 Climate transmitter_id: xmitr From 95a7356ea08e7ba3a9c577b40339c1d7df1dda50 Mon Sep 17 00:00:00 2001 From: tomaszduda23 Date: Sat, 3 Jan 2026 10:43:17 +0100 Subject: [PATCH 151/302] [uart] make sure that all variables are initialized (#12823) --- esphome/components/uart/uart_component.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/uart/uart_component.h b/esphome/components/uart/uart_component.h index fd528e228f..ea6e1562f4 100644 --- a/esphome/components/uart/uart_component.h +++ b/esphome/components/uart/uart_component.h @@ -189,10 +189,10 @@ class UARTComponent { size_t rx_buffer_size_; size_t rx_full_threshold_{1}; size_t rx_timeout_{0}; - uint32_t baud_rate_; - uint8_t stop_bits_; - uint8_t data_bits_; - UARTParityOptions parity_; + uint32_t baud_rate_{0}; + uint8_t stop_bits_{0}; + uint8_t data_bits_{0}; + UARTParityOptions parity_{UART_CONFIG_PARITY_NONE}; #ifdef USE_UART_DEBUGGER CallbackManager debug_callback_{}; #endif From 1d323c2d71f7566e413c052318338902c822b996 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 07:14:48 -1000 Subject: [PATCH 152/302] [api] Remove deprecated password authentication (#12819) --- esphome/components/api/__init__.py | 42 +++-------- esphome/components/api/api.proto | 30 ++++---- esphome/components/api/api_connection.cpp | 27 +------- esphome/components/api/api_connection.h | 6 -- esphome/components/api/api_pb2.cpp | 21 ------ esphome/components/api/api_pb2.h | 38 +--------- esphome/components/api/api_pb2_dump.cpp | 15 ---- esphome/components/api/api_pb2_service.cpp | 23 +------ esphome/components/api/api_pb2_service.h | 10 --- esphome/components/api/api_server.cpp | 36 ---------- esphome/components/api/api_server.h | 7 -- esphome/components/api/proto.h | 18 +---- .../fixtures/host_mode_api_password.yaml | 14 ---- .../test_host_mode_api_password.py | 69 ------------------- 14 files changed, 28 insertions(+), 328 deletions(-) delete mode 100644 tests/integration/fixtures/host_mode_api_password.yaml delete mode 100644 tests/integration/test_host_mode_api_password.py diff --git a/esphome/components/api/__init__.py b/esphome/components/api/__init__.py index 88618acef4..0e2c612279 100644 --- a/esphome/components/api/__init__.py +++ b/esphome/components/api/__init__.py @@ -226,32 +226,6 @@ def _encryption_schema(config): return ENCRYPTION_SCHEMA(config) -def _validate_api_config(config: ConfigType) -> ConfigType: - """Validate API configuration with mutual exclusivity check and deprecation warning.""" - # Check if both password and encryption are configured - has_password = CONF_PASSWORD in config and config[CONF_PASSWORD] - has_encryption = CONF_ENCRYPTION in config - - if has_password and has_encryption: - raise cv.Invalid( - "The 'password' and 'encryption' options are mutually exclusive. " - "The API client only supports one authentication method at a time. " - "Please remove one of them. " - "Note: 'password' authentication is deprecated and will be removed in version 2026.1.0. " - "We strongly recommend using 'encryption' instead for better security." - ) - - # Warn about password deprecation - if has_password: - _LOGGER.warning( - "API 'password' authentication has been deprecated since May 2022 and will be removed in version 2026.1.0. " - "Please migrate to the 'encryption' configuration. " - "See https://esphome.io/components/api/#configuration-variables" - ) - - return config - - def _consume_api_sockets(config: ConfigType) -> ConfigType: """Register socket needs for API component.""" from esphome.components import socket @@ -268,7 +242,17 @@ CONFIG_SCHEMA = cv.All( { cv.GenerateID(): cv.declare_id(APIServer), cv.Optional(CONF_PORT, default=6053): cv.port, - cv.Optional(CONF_PASSWORD, default=""): cv.string_strict, + # Removed in 2026.1.0 - kept to provide helpful error message + cv.Optional(CONF_PASSWORD): cv.invalid( + "The 'password' option has been removed in ESPHome 2026.1.0.\n" + "Password authentication was deprecated in May 2022.\n" + "Please migrate to encryption for secure API communication:\n\n" + "api:\n" + " encryption:\n" + " key: !secret api_encryption_key\n\n" + "Generate a key with: openssl rand -base64 32\n" + "Or visit https://esphome.io/components/api/#configuration-variables" + ), cv.Optional( CONF_REBOOT_TIMEOUT, default="15min" ): cv.positive_time_period_milliseconds, @@ -330,7 +314,6 @@ CONFIG_SCHEMA = cv.All( } ).extend(cv.COMPONENT_SCHEMA), cv.rename_key(CONF_SERVICES, CONF_ACTIONS), - _validate_api_config, _consume_api_sockets, ) @@ -344,9 +327,6 @@ async def to_code(config: ConfigType) -> None: CORE.register_controller() cg.add(var.set_port(config[CONF_PORT])) - if config[CONF_PASSWORD]: - cg.add_define("USE_API_PASSWORD") - cg.add(var.set_password(config[CONF_PASSWORD])) cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT])) cg.add(var.set_batch_delay(config[CONF_BATCH_DELAY])) if CONF_LISTEN_BACKLOG in config: diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index 5efd839673..652b456850 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -7,10 +7,7 @@ service APIConnection { option (needs_setup_connection) = false; option (needs_authentication) = false; } - rpc authenticate (AuthenticationRequest) returns (AuthenticationResponse) { - option (needs_setup_connection) = false; - option (needs_authentication) = false; - } + // REMOVED in ESPHome 2026.1.0: rpc authenticate (AuthenticationRequest) returns (AuthenticationResponse) rpc disconnect (DisconnectRequest) returns (DisconnectResponse) { option (needs_setup_connection) = false; option (needs_authentication) = false; @@ -82,14 +79,13 @@ service APIConnection { // * VarInt denoting the type of message. // * The message object encoded as a ProtoBuf message -// The connection is established in 4 steps: +// The connection is established in 2 steps: // * First, the client connects to the server and sends a "Hello Request" identifying itself -// * The server responds with a "Hello Response" and selects the protocol version -// * After receiving this message, the client attempts to authenticate itself using -// the password and a "Connect Request" -// * The server responds with a "Connect Response" and notifies of invalid password. +// * The server responds with a "Hello Response" and the connection is authenticated // If anything in this initial process fails, the connection must immediately closed // by both sides and _no_ disconnection message is to be sent. +// Note: Password authentication via AuthenticationRequest/AuthenticationResponse (message IDs 3, 4) +// was removed in ESPHome 2026.1.0. Those message IDs are reserved and should not be reused. // Message sent at the beginning of each connection // Can only be sent by the client and only at the beginning of the connection @@ -130,25 +126,23 @@ message HelloResponse { string name = 4; } -// Message sent at the beginning of each connection to authenticate the client -// Can only be sent by the client and only at the beginning of the connection +// DEPRECATED in ESPHome 2026.1.0 - Password authentication is no longer supported. +// These messages are kept for protocol documentation but are not processed by the server. +// Use noise encryption instead: https://esphome.io/components/api/#configuration-variables message AuthenticationRequest { option (id) = 3; option (source) = SOURCE_CLIENT; option (no_delay) = true; - option (ifdef) = "USE_API_PASSWORD"; + option deprecated = true; - // The password to log in with string password = 1; } -// Confirmation of successful connection. After this the connection is available for all traffic. -// Can only be sent by the server and only at the beginning of the connection message AuthenticationResponse { option (id) = 4; option (source) = SOURCE_SERVER; option (no_delay) = true; - option (ifdef) = "USE_API_PASSWORD"; + option deprecated = true; bool invalid_password = 1; } @@ -205,7 +199,9 @@ message DeviceInfoResponse { option (id) = 10; option (source) = SOURCE_SERVER; - bool uses_password = 1 [(field_ifdef) = "USE_API_PASSWORD"]; + // Deprecated in ESPHome 2026.1.0, but kept for backward compatibility + // with older ESPHome versions that still send this field. + bool uses_password = 1 [deprecated = true]; // The name of the node, given by "App.set_name()" string name = 2; diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 2ecd54bb00..3ded5e4408 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -1535,27 +1535,11 @@ bool APIConnection::send_hello_response(const HelloRequest &msg) { resp.set_server_info(ESPHOME_VERSION_REF); resp.set_name(StringRef(App.get_name())); -#ifdef USE_API_PASSWORD - // Password required - wait for authentication - this->flags_.connection_state = static_cast(ConnectionState::CONNECTED); -#else - // No password configured - auto-authenticate + // Auto-authenticate - password auth was removed in ESPHome 2026.1.0 this->complete_authentication_(); -#endif return this->send_message(resp, HelloResponse::MESSAGE_TYPE); } -#ifdef USE_API_PASSWORD -bool APIConnection::send_authenticate_response(const AuthenticationRequest &msg) { - AuthenticationResponse resp; - // bool invalid_password = 1; - resp.invalid_password = !this->parent_->check_password(msg.password.byte(), msg.password.size()); - if (!resp.invalid_password) { - this->complete_authentication_(); - } - return this->send_message(resp, AuthenticationResponse::MESSAGE_TYPE); -} -#endif // USE_API_PASSWORD bool APIConnection::send_ping_response(const PingRequest &msg) { PingResponse resp; @@ -1564,9 +1548,6 @@ bool APIConnection::send_ping_response(const PingRequest &msg) { bool APIConnection::send_device_info_response(const DeviceInfoRequest &msg) { DeviceInfoResponse resp{}; -#ifdef USE_API_PASSWORD - resp.uses_password = true; -#endif resp.set_name(StringRef(App.get_name())); resp.set_friendly_name(StringRef(App.get_friendly_name())); #ifdef USE_AREAS @@ -1845,12 +1826,6 @@ bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) { // Do not set last_traffic_ on send return true; } -#ifdef USE_API_PASSWORD -void APIConnection::on_unauthenticated_access() { - this->on_fatal_error(); - ESP_LOGD(TAG, "%s (%s) no authentication", this->client_info_.name.c_str(), this->client_info_.peername.c_str()); -} -#endif void APIConnection::on_no_setup_connection() { this->on_fatal_error(); ESP_LOGD(TAG, "%s (%s) no connection setup", this->client_info_.name.c_str(), this->client_info_.peername.c_str()); diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index 59c42aa033..ffe3614f20 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -203,9 +203,6 @@ class APIConnection final : public APIServerConnection { void on_get_time_response(const GetTimeResponse &value) override; #endif bool send_hello_response(const HelloRequest &msg) override; -#ifdef USE_API_PASSWORD - bool send_authenticate_response(const AuthenticationRequest &msg) override; -#endif bool send_disconnect_response(const DisconnectRequest &msg) override; bool send_ping_response(const PingRequest &msg) override; bool send_device_info_response(const DeviceInfoRequest &msg) override; @@ -261,9 +258,6 @@ class APIConnection final : public APIServerConnection { } void on_fatal_error() override; -#ifdef USE_API_PASSWORD - void on_unauthenticated_access() override; -#endif void on_no_setup_connection() override; ProtoWriteBuffer create_buffer(uint32_t reserve_size) override { // FIXME: ensure no recursive writes can happen diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index 698e08f9b3..d26b309552 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -43,21 +43,6 @@ void HelloResponse::calculate_size(ProtoSize &size) const { size.add_length(1, this->server_info_ref_.size()); size.add_length(1, this->name_ref_.size()); } -#ifdef USE_API_PASSWORD -bool AuthenticationRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { - switch (field_id) { - case 1: { - this->password = StringRef(reinterpret_cast(value.data()), value.size()); - break; - } - default: - return false; - } - return true; -} -void AuthenticationResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(1, this->invalid_password); } -void AuthenticationResponse::calculate_size(ProtoSize &size) const { size.add_bool(1, this->invalid_password); } -#endif #ifdef USE_AREAS void AreaInfo::encode(ProtoWriteBuffer buffer) const { buffer.encode_uint32(1, this->area_id); @@ -81,9 +66,6 @@ void DeviceInfo::calculate_size(ProtoSize &size) const { } #endif void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const { -#ifdef USE_API_PASSWORD - buffer.encode_bool(1, this->uses_password); -#endif buffer.encode_string(2, this->name_ref_); buffer.encode_string(3, this->mac_address_ref_); buffer.encode_string(4, this->esphome_version_ref_); @@ -139,9 +121,6 @@ void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const { #endif } void DeviceInfoResponse::calculate_size(ProtoSize &size) const { -#ifdef USE_API_PASSWORD - size.add_bool(1, this->uses_password); -#endif size.add_length(1, this->name_ref_.size()); size.add_length(1, this->mac_address_ref_.size()); size.add_length(1, this->esphome_version_ref_.size()); diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index e08cf65bb9..0605051e29 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -393,39 +393,6 @@ class HelloResponse final : public ProtoMessage { protected: }; -#ifdef USE_API_PASSWORD -class AuthenticationRequest final : public ProtoDecodableMessage { - public: - static constexpr uint8_t MESSAGE_TYPE = 3; - static constexpr uint8_t ESTIMATED_SIZE = 9; -#ifdef HAS_PROTO_MESSAGE_DUMP - const char *message_name() const override { return "authentication_request"; } -#endif - StringRef password{}; -#ifdef HAS_PROTO_MESSAGE_DUMP - void dump_to(std::string &out) const override; -#endif - - protected: - bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override; -}; -class AuthenticationResponse final : public ProtoMessage { - public: - static constexpr uint8_t MESSAGE_TYPE = 4; - static constexpr uint8_t ESTIMATED_SIZE = 2; -#ifdef HAS_PROTO_MESSAGE_DUMP - const char *message_name() const override { return "authentication_response"; } -#endif - bool invalid_password{false}; - void encode(ProtoWriteBuffer buffer) const override; - void calculate_size(ProtoSize &size) const override; -#ifdef HAS_PROTO_MESSAGE_DUMP - void dump_to(std::string &out) const override; -#endif - - protected: -}; -#endif class DisconnectRequest final : public ProtoMessage { public: static constexpr uint8_t MESSAGE_TYPE = 5; @@ -525,12 +492,9 @@ class DeviceInfo final : public ProtoMessage { class DeviceInfoResponse final : public ProtoMessage { public: static constexpr uint8_t MESSAGE_TYPE = 10; - static constexpr uint16_t ESTIMATED_SIZE = 257; + static constexpr uint8_t ESTIMATED_SIZE = 255; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "device_info_response"; } -#endif -#ifdef USE_API_PASSWORD - bool uses_password{false}; #endif StringRef name_ref_{}; void set_name(const StringRef &ref) { this->name_ref_ = ref; } diff --git a/esphome/components/api/api_pb2_dump.cpp b/esphome/components/api/api_pb2_dump.cpp index 1ec6645b3f..ac5f04f3fb 100644 --- a/esphome/components/api/api_pb2_dump.cpp +++ b/esphome/components/api/api_pb2_dump.cpp @@ -748,18 +748,6 @@ void HelloResponse::dump_to(std::string &out) const { dump_field(out, "server_info", this->server_info_ref_); dump_field(out, "name", this->name_ref_); } -#ifdef USE_API_PASSWORD -void AuthenticationRequest::dump_to(std::string &out) const { - MessageDumpHelper helper(out, "AuthenticationRequest"); - out.append(" password: "); - out.append("'").append(this->password.c_str(), this->password.size()).append("'"); - out.append("\n"); -} -void AuthenticationResponse::dump_to(std::string &out) const { - MessageDumpHelper helper(out, "AuthenticationResponse"); - dump_field(out, "invalid_password", this->invalid_password); -} -#endif void DisconnectRequest::dump_to(std::string &out) const { out.append("DisconnectRequest {}"); } void DisconnectResponse::dump_to(std::string &out) const { out.append("DisconnectResponse {}"); } void PingRequest::dump_to(std::string &out) const { out.append("PingRequest {}"); } @@ -782,9 +770,6 @@ void DeviceInfo::dump_to(std::string &out) const { #endif void DeviceInfoResponse::dump_to(std::string &out) const { MessageDumpHelper helper(out, "DeviceInfoResponse"); -#ifdef USE_API_PASSWORD - dump_field(out, "uses_password", this->uses_password); -#endif dump_field(out, "name", this->name_ref_); dump_field(out, "mac_address", this->mac_address_ref_); dump_field(out, "esphome_version", this->esphome_version_ref_); diff --git a/esphome/components/api/api_pb2_service.cpp b/esphome/components/api/api_pb2_service.cpp index 984cb0bb6e..c9bf638ad7 100644 --- a/esphome/components/api/api_pb2_service.cpp +++ b/esphome/components/api/api_pb2_service.cpp @@ -24,17 +24,6 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, this->on_hello_request(msg); break; } -#ifdef USE_API_PASSWORD - case AuthenticationRequest::MESSAGE_TYPE: { - AuthenticationRequest msg; - msg.decode(msg_data, msg_size); -#ifdef HAS_PROTO_MESSAGE_DUMP - ESP_LOGVV(TAG, "on_authentication_request: %s", msg.dump().c_str()); -#endif - this->on_authentication_request(msg); - break; - } -#endif case DisconnectRequest::MESSAGE_TYPE: { DisconnectRequest msg; // Empty message: no decode needed @@ -643,13 +632,6 @@ void APIServerConnection::on_hello_request(const HelloRequest &msg) { this->on_fatal_error(); } } -#ifdef USE_API_PASSWORD -void APIServerConnection::on_authentication_request(const AuthenticationRequest &msg) { - if (!this->send_authenticate_response(msg)) { - this->on_fatal_error(); - } -} -#endif void APIServerConnection::on_disconnect_request(const DisconnectRequest &msg) { if (!this->send_disconnect_response(msg)) { this->on_fatal_error(); @@ -841,10 +823,7 @@ void APIServerConnection::on_z_wave_proxy_request(const ZWaveProxyRequest &msg) void APIServerConnection::read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data) { // Check authentication/connection requirements for messages switch (msg_type) { - case HelloRequest::MESSAGE_TYPE: // No setup required -#ifdef USE_API_PASSWORD - case AuthenticationRequest::MESSAGE_TYPE: // No setup required -#endif + case HelloRequest::MESSAGE_TYPE: // No setup required case DisconnectRequest::MESSAGE_TYPE: // No setup required case PingRequest::MESSAGE_TYPE: // No setup required break; // Skip all checks for these messages diff --git a/esphome/components/api/api_pb2_service.h b/esphome/components/api/api_pb2_service.h index 261d9fbd27..e2a23827dc 100644 --- a/esphome/components/api/api_pb2_service.h +++ b/esphome/components/api/api_pb2_service.h @@ -26,10 +26,6 @@ class APIServerConnectionBase : public ProtoService { virtual void on_hello_request(const HelloRequest &value){}; -#ifdef USE_API_PASSWORD - virtual void on_authentication_request(const AuthenticationRequest &value){}; -#endif - virtual void on_disconnect_request(const DisconnectRequest &value){}; virtual void on_disconnect_response(const DisconnectResponse &value){}; virtual void on_ping_request(const PingRequest &value){}; @@ -228,9 +224,6 @@ class APIServerConnectionBase : public ProtoService { class APIServerConnection : public APIServerConnectionBase { public: virtual bool send_hello_response(const HelloRequest &msg) = 0; -#ifdef USE_API_PASSWORD - virtual bool send_authenticate_response(const AuthenticationRequest &msg) = 0; -#endif virtual bool send_disconnect_response(const DisconnectRequest &msg) = 0; virtual bool send_ping_response(const PingRequest &msg) = 0; virtual bool send_device_info_response(const DeviceInfoRequest &msg) = 0; @@ -357,9 +350,6 @@ class APIServerConnection : public APIServerConnectionBase { #endif protected: void on_hello_request(const HelloRequest &msg) override; -#ifdef USE_API_PASSWORD - void on_authentication_request(const AuthenticationRequest &msg) override; -#endif void on_disconnect_request(const DisconnectRequest &msg) override; void on_ping_request(const PingRequest &msg) override; void on_device_info_request(const DeviceInfoRequest &msg) override; diff --git a/esphome/components/api/api_server.cpp b/esphome/components/api/api_server.cpp index 8b76740e4d..eedf8c7172 100644 --- a/esphome/components/api/api_server.cpp +++ b/esphome/components/api/api_server.cpp @@ -224,38 +224,6 @@ void APIServer::dump_config() { #endif } -#ifdef USE_API_PASSWORD -bool APIServer::check_password(const uint8_t *password_data, size_t password_len) const { - // depend only on input password length - const char *a = this->password_.c_str(); - uint32_t len_a = this->password_.length(); - const char *b = reinterpret_cast(password_data); - uint32_t len_b = password_len; - - // disable optimization with volatile - volatile uint32_t length = len_b; - volatile const char *left = nullptr; - volatile const char *right = b; - uint8_t result = 0; - - if (len_a == length) { - left = *((volatile const char **) &a); - result = 0; - } - if (len_a != length) { - left = b; - result = 1; - } - - for (size_t i = 0; i < length; i++) { - result |= *left++ ^ *right++; // NOLINT - } - - return result == 0; -} - -#endif - void APIServer::handle_disconnect(APIConnection *conn) {} // Macro for controller update dispatch @@ -377,10 +345,6 @@ float APIServer::get_setup_priority() const { return setup_priority::AFTER_WIFI; void APIServer::set_port(uint16_t port) { this->port_ = port; } -#ifdef USE_API_PASSWORD -void APIServer::set_password(const std::string &password) { this->password_ = password; } -#endif - void APIServer::set_batch_delay(uint16_t batch_delay) { this->batch_delay_ = batch_delay; } #ifdef USE_API_HOMEASSISTANT_SERVICES diff --git a/esphome/components/api/api_server.h b/esphome/components/api/api_server.h index b855d2cce0..2b2e8bae73 100644 --- a/esphome/components/api/api_server.h +++ b/esphome/components/api/api_server.h @@ -59,10 +59,6 @@ class APIServer : public Component, #endif #ifdef USE_CAMERA void on_camera_image(const std::shared_ptr &image) override; -#endif -#ifdef USE_API_PASSWORD - bool check_password(const uint8_t *password_data, size_t password_len) const; - void set_password(const std::string &password); #endif void set_port(uint16_t port); void set_reboot_timeout(uint32_t reboot_timeout); @@ -256,9 +252,6 @@ class APIServer : public Component, // Vectors and strings (12 bytes each on 32-bit) std::vector> clients_; -#ifdef USE_API_PASSWORD - std::string password_; -#endif std::vector shared_write_buffer_; // Shared proto write buffer for all connections #ifdef USE_API_HOMEASSISTANT_STATES std::vector state_subs_; diff --git a/esphome/components/api/proto.h b/esphome/components/api/proto.h index efdab9341c..f8b5cd9a5d 100644 --- a/esphome/components/api/proto.h +++ b/esphome/components/api/proto.h @@ -833,9 +833,6 @@ class ProtoService { virtual bool is_authenticated() = 0; virtual bool is_connection_setup() = 0; virtual void on_fatal_error() = 0; -#ifdef USE_API_PASSWORD - virtual void on_unauthenticated_access() = 0; -#endif virtual void on_no_setup_connection() = 0; /** * Create a buffer with a reserved size. @@ -873,20 +870,7 @@ class ProtoService { return true; } - inline bool check_authenticated_() { -#ifdef USE_API_PASSWORD - if (!this->check_connection_setup_()) { - return false; - } - if (!this->is_authenticated()) { - this->on_unauthenticated_access(); - return false; - } - return true; -#else - return this->check_connection_setup_(); -#endif - } + inline bool check_authenticated_() { return this->check_connection_setup_(); } }; } // namespace esphome::api diff --git a/tests/integration/fixtures/host_mode_api_password.yaml b/tests/integration/fixtures/host_mode_api_password.yaml deleted file mode 100644 index 038b6871e0..0000000000 --- a/tests/integration/fixtures/host_mode_api_password.yaml +++ /dev/null @@ -1,14 +0,0 @@ -esphome: - name: host-mode-api-password -host: -api: - password: "test_password_123" -logger: - level: DEBUG -# Test sensor to verify connection works -sensor: - - platform: template - name: Test Sensor - id: test_sensor - lambda: return 42.0; - update_interval: 0.1s diff --git a/tests/integration/test_host_mode_api_password.py b/tests/integration/test_host_mode_api_password.py deleted file mode 100644 index 5c5e689e45..0000000000 --- a/tests/integration/test_host_mode_api_password.py +++ /dev/null @@ -1,69 +0,0 @@ -"""Integration test for API password authentication.""" - -from __future__ import annotations - -import asyncio - -from aioesphomeapi import APIConnectionError, InvalidAuthAPIError -import pytest - -from .types import APIClientConnectedFactory, RunCompiledFunction - - -@pytest.mark.asyncio -async def test_host_mode_api_password( - yaml_config: str, - run_compiled: RunCompiledFunction, - api_client_connected: APIClientConnectedFactory, -) -> None: - """Test API authentication with password.""" - async with run_compiled(yaml_config): - # Connect with correct password - async with api_client_connected(password="test_password_123") as client: - # Verify we can get device info - device_info = await client.device_info() - assert device_info is not None - assert device_info.uses_password is True - assert device_info.name == "host-mode-api-password" - - # Subscribe to states to ensure authenticated connection works - loop = asyncio.get_running_loop() - state_future: asyncio.Future[bool] = loop.create_future() - states = {} - - def on_state(state): - states[state.key] = state - if not state_future.done(): - state_future.set_result(True) - - client.subscribe_states(on_state) - - # Wait for at least one state with timeout - try: - await asyncio.wait_for(state_future, timeout=5.0) - except TimeoutError: - pytest.fail("No states received within timeout") - - # Should have received at least one state (the test sensor) - assert len(states) > 0 - - # Test with wrong password - should fail - # Try connecting with wrong password - try: - async with api_client_connected( - password="wrong_password", timeout=5 - ) as client: - # If we get here without exception, try to use the connection - # which should fail if auth failed - await client.device_info_and_list_entities() - # If we successfully got device info and entities, auth didn't fail properly - pytest.fail("Connection succeeded with wrong password") - except (InvalidAuthAPIError, APIConnectionError) as e: - # Expected - auth should fail - # Accept either InvalidAuthAPIError or generic APIConnectionError - # since the client might not always distinguish - assert ( - "password" in str(e).lower() - or "auth" in str(e).lower() - or "invalid" in str(e).lower() - ) From 69867bf8187a1bfc491ec657ed5a42b195c37283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Kry=C5=84ski?= Date: Sat, 3 Jan 2026 19:58:56 +0100 Subject: [PATCH 153/302] [nrf52, zephyr] move nrf52-specific code to nrf52 component (#12582) Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Co-authored-by: J. Nick Koston Co-authored-by: J. Nick Koston Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: J. Nick Koston --- esphome/components/logger/__init__.py | 2 +- esphome/components/nrf52/__init__.py | 16 +++++++++++- esphome/components/nrf52/gpio.py | 9 ++++++- esphome/components/zephyr/__init__.py | 30 ++++++++--------------- esphome/components/zephyr/core.cpp | 9 ++++++- esphome/components/zephyr/gpio.cpp | 29 +++++----------------- esphome/components/zephyr/gpio.h | 13 +++++++--- esphome/components/zephyr/preferences.cpp | 2 ++ 8 files changed, 60 insertions(+), 50 deletions(-) diff --git a/esphome/components/logger/__init__.py b/esphome/components/logger/__init__.py index 8968a5eab8..7132cd8956 100644 --- a/esphome/components/logger/__init__.py +++ b/esphome/components/logger/__init__.py @@ -386,7 +386,7 @@ async def to_code(config): except cv.Invalid: pass - if CORE.using_zephyr: + if CORE.is_nrf52: if config[CONF_HARDWARE_UART] == UART0: zephyr_add_overlay("""&uart0 { status = "okay";};""") if config[CONF_HARDWARE_UART] == UART1: diff --git a/esphome/components/nrf52/__init__.py b/esphome/components/nrf52/__init__.py index 03927e8ea2..bf90a41df5 100644 --- a/esphome/components/nrf52/__init__.py +++ b/esphome/components/nrf52/__init__.py @@ -12,6 +12,7 @@ from esphome.components.zephyr import ( zephyr_add_prj_conf, zephyr_data, zephyr_set_core_data, + zephyr_setup_preferences, zephyr_to_code, ) from esphome.components.zephyr.const import ( @@ -49,7 +50,7 @@ from .const import ( from .gpio import nrf52_pin_to_code # noqa CODEOWNERS = ["@tomaszduda23"] -AUTO_LOAD = ["zephyr"] +AUTO_LOAD = ["zephyr", "preferences"] IS_TARGET_PLATFORM = True _LOGGER = logging.getLogger(__name__) @@ -194,6 +195,7 @@ async def to_code(config: ConfigType) -> None: cg.add_platformio_option("board_upload.require_upload_port", "true") cg.add_platformio_option("board_upload.wait_for_upload_port", "true") + zephyr_setup_preferences() zephyr_to_code(config) if dfu_config := config.get(CONF_DFU): @@ -206,6 +208,18 @@ async def to_code(config: ConfigType) -> None: if reg0_config[CONF_UICR_ERASE]: cg.add_define("USE_NRF52_UICR_ERASE") + # c++ support + zephyr_add_prj_conf("CPLUSPLUS", True) + zephyr_add_prj_conf("LIB_CPLUSPLUS", True) + # watchdog + zephyr_add_prj_conf("WATCHDOG", True) + zephyr_add_prj_conf("WDT_DISABLE_AT_BOOT", False) + # disable console + zephyr_add_prj_conf("UART_CONSOLE", False) + zephyr_add_prj_conf("CONSOLE", False) + # use NFC pins as GPIO + zephyr_add_prj_conf("NFCT_PINS_AS_GPIOS", True) + @coroutine_with_priority(CoroPriority.DIAGNOSTICS) async def _dfu_to_code(dfu_config): diff --git a/esphome/components/nrf52/gpio.py b/esphome/components/nrf52/gpio.py index 17329042b2..498e8cc330 100644 --- a/esphome/components/nrf52/gpio.py +++ b/esphome/components/nrf52/gpio.py @@ -71,8 +71,15 @@ NRF52_PIN_SCHEMA = cv.All( @pins.PIN_SCHEMA_REGISTRY.register(PLATFORM_NRF52, NRF52_PIN_SCHEMA) async def nrf52_pin_to_code(config): - var = cg.new_Pvariable(config[CONF_ID]) num = config[CONF_NUMBER] + port = num // 32 + pin_name_prefix = f"P{port}." + var = cg.new_Pvariable( + config[CONF_ID], + cg.RawExpression(f"DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio{port}))"), + 32, + pin_name_prefix, + ) cg.add(var.set_pin(num)) # Only set if true to avoid bloating setup() function # (inverted bit in pin_flags_ bitfield is zero-initialized to false) diff --git a/esphome/components/zephyr/__init__.py b/esphome/components/zephyr/__init__.py index 0381fbcba9..a91d976e6b 100644 --- a/esphome/components/zephyr/__init__.py +++ b/esphome/components/zephyr/__init__.py @@ -21,7 +21,6 @@ from .const import ( ) CODEOWNERS = ["@tomaszduda23"] -AUTO_LOAD = ["preferences"] PrjConfValueType = bool | str | int @@ -111,32 +110,15 @@ def add_extra_script(stage: str, filename: str, path: Path) -> None: def zephyr_to_code(config): - cg.add(zephyr_ns.setup_preferences()) cg.add_build_flag("-DUSE_ZEPHYR") cg.set_cpp_standard("gnu++20") # build is done by west so bypass board checking in platformio cg.add_platformio_option("boards_dir", CORE.relative_build_path("boards")) - # c++ support zephyr_add_prj_conf("NEWLIB_LIBC", True) - zephyr_add_prj_conf("CONFIG_FPU", True) + zephyr_add_prj_conf("FPU", True) zephyr_add_prj_conf("NEWLIB_LIBC_FLOAT_PRINTF", True) - zephyr_add_prj_conf("CPLUSPLUS", True) - zephyr_add_prj_conf("CONFIG_STD_CPP20", True) - zephyr_add_prj_conf("LIB_CPLUSPLUS", True) - # preferences - zephyr_add_prj_conf("SETTINGS", True) - zephyr_add_prj_conf("NVS", True) - zephyr_add_prj_conf("FLASH_MAP", True) - zephyr_add_prj_conf("CONFIG_FLASH", True) - # watchdog - zephyr_add_prj_conf("WATCHDOG", True) - zephyr_add_prj_conf("WDT_DISABLE_AT_BOOT", False) - # disable console - zephyr_add_prj_conf("UART_CONSOLE", False) - zephyr_add_prj_conf("CONSOLE", False, False) - # use NFC pins as GPIO - zephyr_add_prj_conf("NFCT_PINS_AS_GPIOS", True) + zephyr_add_prj_conf("STD_CPP20", True) # os: ***** USAGE FAULT ***** # os: Illegal load of EXC_RETURN into PC @@ -149,6 +131,14 @@ def zephyr_to_code(config): ) +def zephyr_setup_preferences(): + cg.add(zephyr_ns.setup_preferences()) + zephyr_add_prj_conf("SETTINGS", True) + zephyr_add_prj_conf("NVS", True) + zephyr_add_prj_conf("FLASH_MAP", True) + zephyr_add_prj_conf("FLASH", True) + + def _format_prj_conf_val(value: PrjConfValueType) -> str: if isinstance(value, bool): return "y" if value else "n" diff --git a/esphome/components/zephyr/core.cpp b/esphome/components/zephyr/core.cpp index d5427a0ebf..46589cdb62 100644 --- a/esphome/components/zephyr/core.cpp +++ b/esphome/components/zephyr/core.cpp @@ -10,8 +10,10 @@ namespace esphome { +#ifdef CONFIG_WATCHDOG static int wdt_channel_id = -1; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) static const device *const WDT = DEVICE_DT_GET(DT_ALIAS(watchdog0)); +#endif void yield() { ::k_yield(); } uint32_t millis() { return k_ticks_to_ms_floor32(k_uptime_ticks()); } @@ -20,6 +22,7 @@ void delayMicroseconds(uint32_t us) { ::k_usleep(us); } void delay(uint32_t ms) { ::k_msleep(ms); } void arch_init() { +#ifdef CONFIG_WATCHDOG if (device_is_ready(WDT)) { static wdt_timeout_cfg wdt_config{}; wdt_config.flags = WDT_FLAG_RESET_SOC; @@ -36,12 +39,15 @@ void arch_init() { wdt_setup(WDT, options); } } +#endif } void arch_feed_wdt() { +#ifdef CONFIG_WATCHDOG if (wdt_channel_id >= 0) { wdt_feed(WDT, wdt_channel_id); } +#endif } void arch_restart() { sys_reboot(SYS_REBOOT_COLD); } @@ -72,6 +78,7 @@ bool random_bytes(uint8_t *data, size_t len) { return true; } +#ifdef USE_NRF52 void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter) mac[0] = ((NRF_FICR->DEVICEADDR[1] & 0xFFFF) >> 8) | 0xC0; mac[1] = NRF_FICR->DEVICEADDR[1] & 0xFFFF; @@ -80,7 +87,7 @@ void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parame mac[4] = NRF_FICR->DEVICEADDR[0] >> 8; mac[5] = NRF_FICR->DEVICEADDR[0]; } - +#endif } // namespace esphome void setup(); diff --git a/esphome/components/zephyr/gpio.cpp b/esphome/components/zephyr/gpio.cpp index 8041c361cc..1d5b0f282b 100644 --- a/esphome/components/zephyr/gpio.cpp +++ b/esphome/components/zephyr/gpio.cpp @@ -50,25 +50,7 @@ void ZephyrGPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::Inte } void ZephyrGPIOPin::setup() { - const struct device *gpio = nullptr; - if (this->pin_ < 32) { -#define GPIO0 DT_NODELABEL(gpio0) -#if DT_NODE_HAS_STATUS(GPIO0, okay) - gpio = DEVICE_DT_GET(GPIO0); -#else -#error "gpio0 is disabled" -#endif - } else { -#define GPIO1 DT_NODELABEL(gpio1) -#if DT_NODE_HAS_STATUS(GPIO1, okay) - gpio = DEVICE_DT_GET(GPIO1); -#else -#error "gpio1 is disabled" -#endif - } - if (device_is_ready(gpio)) { - this->gpio_ = gpio; - } else { + if (!device_is_ready(this->gpio_)) { ESP_LOGE(TAG, "gpio %u is not ready.", this->pin_); return; } @@ -79,21 +61,22 @@ void ZephyrGPIOPin::pin_mode(gpio::Flags flags) { if (nullptr == this->gpio_) { return; } - auto ret = gpio_pin_configure(this->gpio_, this->pin_ % 32, flags_to_mode(flags, this->inverted_, this->value_)); + auto ret = gpio_pin_configure(this->gpio_, this->pin_ % this->gpio_size_, + flags_to_mode(flags, this->inverted_, this->value_)); if (ret != 0) { ESP_LOGE(TAG, "gpio %u cannot be configured %d.", this->pin_, ret); } } size_t ZephyrGPIOPin::dump_summary(char *buffer, size_t len) const { - return snprintf(buffer, len, "GPIO%u, P%u.%u", this->pin_, this->pin_ / 32, this->pin_ % 32); + return snprintf(buffer, len, "GPIO%u, %s%u", this->pin_, this->pin_name_prefix_, this->pin_ % this->gpio_size_); } bool ZephyrGPIOPin::digital_read() { if (nullptr == this->gpio_) { return false; } - return bool(gpio_pin_get(this->gpio_, this->pin_ % 32) != this->inverted_); + return bool(gpio_pin_get(this->gpio_, this->pin_ % this->gpio_size_) != this->inverted_); } void ZephyrGPIOPin::digital_write(bool value) { @@ -103,7 +86,7 @@ void ZephyrGPIOPin::digital_write(bool value) { if (nullptr == this->gpio_) { return; } - gpio_pin_set(this->gpio_, this->pin_ % 32, value != this->inverted_ ? 1 : 0); + gpio_pin_set(this->gpio_, this->pin_ % this->gpio_size_, value != this->inverted_ ? 1 : 0); } void ZephyrGPIOPin::detach_interrupt() const { // TODO diff --git a/esphome/components/zephyr/gpio.h b/esphome/components/zephyr/gpio.h index b405f385bc..c9540f4f01 100644 --- a/esphome/components/zephyr/gpio.h +++ b/esphome/components/zephyr/gpio.h @@ -8,6 +8,11 @@ namespace zephyr { class ZephyrGPIOPin : public InternalGPIOPin { public: + ZephyrGPIOPin(const device *gpio, int gpio_size, const char *pin_name_prefix) { + this->gpio_ = gpio; + this->gpio_size_ = gpio_size; + this->pin_name_prefix_ = pin_name_prefix; + } void set_pin(uint8_t pin) { this->pin_ = pin; } void set_inverted(bool inverted) { this->inverted_ = inverted; } void set_flags(gpio::Flags flags) { this->flags_ = flags; } @@ -25,10 +30,12 @@ class ZephyrGPIOPin : public InternalGPIOPin { protected: void attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const override; - uint8_t pin_; - bool inverted_{}; - gpio::Flags flags_{}; const device *gpio_{nullptr}; + const char *pin_name_prefix_{nullptr}; + gpio::Flags flags_{}; + uint8_t pin_; + uint8_t gpio_size_{}; + bool inverted_{}; bool value_{false}; }; diff --git a/esphome/components/zephyr/preferences.cpp b/esphome/components/zephyr/preferences.cpp index d702366044..08b361b8fb 100644 --- a/esphome/components/zephyr/preferences.cpp +++ b/esphome/components/zephyr/preferences.cpp @@ -1,4 +1,5 @@ #ifdef USE_ZEPHYR +#ifdef CONFIG_SETTINGS #include #include "esphome/core/preferences.h" @@ -154,3 +155,4 @@ ESPPreferences *global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const } // namespace esphome #endif +#endif From c34665f6500bb6449236ef583790249d88647d1a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 09:13:07 -1000 Subject: [PATCH 154/302] [api] Fix KeyError when running logs after password removal (#12831) --- esphome/components/api/client.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/esphome/components/api/client.py b/esphome/components/api/client.py index ca1fc089fa..200d0938bd 100644 --- a/esphome/components/api/client.py +++ b/esphome/components/api/client.py @@ -16,7 +16,7 @@ with warnings.catch_warnings(): import contextlib -from esphome.const import CONF_KEY, CONF_PASSWORD, CONF_PORT, __version__ +from esphome.const import CONF_KEY, CONF_PORT, __version__ from esphome.core import CORE from . import CONF_ENCRYPTION @@ -35,7 +35,6 @@ async def async_run_logs(config: dict[str, Any], addresses: list[str]) -> None: conf = config["api"] name = config["esphome"]["name"] port: int = int(conf[CONF_PORT]) - password: str = conf[CONF_PASSWORD] noise_psk: str | None = None if (encryption := conf.get(CONF_ENCRYPTION)) and (key := encryption.get(CONF_KEY)): noise_psk = key @@ -50,7 +49,7 @@ async def async_run_logs(config: dict[str, Any], addresses: list[str]) -> None: cli = APIClient( addresses[0], # Primary address for compatibility port, - password, + "", # Password auth removed in 2026.1.0 client_info=f"ESPHome Logs {__version__}", noise_psk=noise_psk, addresses=addresses, # Pass all addresses for automatic retry From 5cfcf8d104fae1b3c77e34c4278cd9510252e640 Mon Sep 17 00:00:00 2001 From: Jasper van der Neut - Stulen Date: Sat, 3 Jan 2026 21:51:48 +0100 Subject: [PATCH 155/302] [mhz19] Make detection range configurable (#12677) Co-authored-by: Fabio Pugliese Ornellas --- esphome/components/mhz19/mhz19.cpp | 44 ++++++++++++++++++++++++++++++ esphome/components/mhz19/mhz19.h | 29 +++++++++++++++++++- esphome/components/mhz19/sensor.py | 41 ++++++++++++++++++++++++++++ tests/components/mhz19/common.yaml | 1 + 4 files changed, 114 insertions(+), 1 deletion(-) diff --git a/esphome/components/mhz19/mhz19.cpp b/esphome/components/mhz19/mhz19.cpp index c3c8120362..00e6e14d85 100644 --- a/esphome/components/mhz19/mhz19.cpp +++ b/esphome/components/mhz19/mhz19.cpp @@ -13,6 +13,9 @@ static const uint8_t MHZ19_COMMAND_GET_PPM[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x static const uint8_t MHZ19_COMMAND_ABC_ENABLE[] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00}; static const uint8_t MHZ19_COMMAND_ABC_DISABLE[] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00}; static const uint8_t MHZ19_COMMAND_CALIBRATE_ZERO[] = {0xFF, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00}; +static const uint8_t MHZ19_COMMAND_DETECTION_RANGE_0_2000PPM[] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x07, 0xD0}; +static const uint8_t MHZ19_COMMAND_DETECTION_RANGE_0_5000PPM[] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x13, 0x88}; +static const uint8_t MHZ19_COMMAND_DETECTION_RANGE_0_10000PPM[] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x27, 0x10}; uint8_t mhz19_checksum(const uint8_t *command) { uint8_t sum = 0; @@ -28,6 +31,8 @@ void MHZ19Component::setup() { } else if (this->abc_boot_logic_ == MHZ19_ABC_DISABLED) { this->abc_disable(); } + + this->range_set(this->detection_range_); } void MHZ19Component::update() { @@ -86,6 +91,26 @@ void MHZ19Component::abc_disable() { this->mhz19_write_command_(MHZ19_COMMAND_ABC_DISABLE, nullptr); } +void MHZ19Component::range_set(MHZ19DetectionRange detection_ppm) { + switch (detection_ppm) { + case MHZ19_DETECTION_RANGE_DEFAULT: + ESP_LOGV(TAG, "Using previously set detection range (no change)"); + break; + case MHZ19_DETECTION_RANGE_0_2000PPM: + ESP_LOGD(TAG, "Setting detection range to 0 to 2000ppm"); + this->mhz19_write_command_(MHZ19_COMMAND_DETECTION_RANGE_0_2000PPM, nullptr); + break; + case MHZ19_DETECTION_RANGE_0_5000PPM: + ESP_LOGD(TAG, "Setting detection range to 0 to 5000ppm"); + this->mhz19_write_command_(MHZ19_COMMAND_DETECTION_RANGE_0_5000PPM, nullptr); + break; + case MHZ19_DETECTION_RANGE_0_10000PPM: + ESP_LOGD(TAG, "Setting detection range to 0 to 10000ppm"); + this->mhz19_write_command_(MHZ19_COMMAND_DETECTION_RANGE_0_10000PPM, nullptr); + break; + } +} + bool MHZ19Component::mhz19_write_command_(const uint8_t *command, uint8_t *response) { // Empty RX Buffer while (this->available()) @@ -99,7 +124,9 @@ bool MHZ19Component::mhz19_write_command_(const uint8_t *command, uint8_t *respo return this->read_array(response, MHZ19_RESPONSE_LENGTH); } + float MHZ19Component::get_setup_priority() const { return setup_priority::DATA; } + void MHZ19Component::dump_config() { ESP_LOGCONFIG(TAG, "MH-Z19:"); LOG_SENSOR(" ", "CO2", this->co2_sensor_); @@ -113,6 +140,23 @@ void MHZ19Component::dump_config() { } ESP_LOGCONFIG(TAG, " Warmup time: %" PRIu32 " s", this->warmup_seconds_); + + const char *range_str; + switch (this->detection_range_) { + case MHZ19_DETECTION_RANGE_DEFAULT: + range_str = "default"; + break; + case MHZ19_DETECTION_RANGE_0_2000PPM: + range_str = "0 to 2000ppm"; + break; + case MHZ19_DETECTION_RANGE_0_5000PPM: + range_str = "0 to 5000ppm"; + break; + case MHZ19_DETECTION_RANGE_0_10000PPM: + range_str = "0 to 10000ppm"; + break; + } + ESP_LOGCONFIG(TAG, " Detection range: %s", range_str); } } // namespace mhz19 diff --git a/esphome/components/mhz19/mhz19.h b/esphome/components/mhz19/mhz19.h index be36886d62..feb67bdd82 100644 --- a/esphome/components/mhz19/mhz19.h +++ b/esphome/components/mhz19/mhz19.h @@ -8,7 +8,18 @@ namespace esphome { namespace mhz19 { -enum MHZ19ABCLogic { MHZ19_ABC_NONE = 0, MHZ19_ABC_ENABLED, MHZ19_ABC_DISABLED }; +enum MHZ19ABCLogic { + MHZ19_ABC_NONE = 0, + MHZ19_ABC_ENABLED, + MHZ19_ABC_DISABLED, +}; + +enum MHZ19DetectionRange { + MHZ19_DETECTION_RANGE_DEFAULT = 0, + MHZ19_DETECTION_RANGE_0_2000PPM, + MHZ19_DETECTION_RANGE_0_5000PPM, + MHZ19_DETECTION_RANGE_0_10000PPM, +}; class MHZ19Component : public PollingComponent, public uart::UARTDevice { public: @@ -21,11 +32,13 @@ class MHZ19Component : public PollingComponent, public uart::UARTDevice { void calibrate_zero(); void abc_enable(); void abc_disable(); + void range_set(MHZ19DetectionRange detection_ppm); void set_temperature_sensor(sensor::Sensor *temperature_sensor) { temperature_sensor_ = temperature_sensor; } void set_co2_sensor(sensor::Sensor *co2_sensor) { co2_sensor_ = co2_sensor; } void set_abc_enabled(bool abc_enabled) { abc_boot_logic_ = abc_enabled ? MHZ19_ABC_ENABLED : MHZ19_ABC_DISABLED; } void set_warmup_seconds(uint32_t seconds) { warmup_seconds_ = seconds; } + void set_detection_range(MHZ19DetectionRange detection_range) { detection_range_ = detection_range; } protected: bool mhz19_write_command_(const uint8_t *command, uint8_t *response); @@ -33,7 +46,10 @@ class MHZ19Component : public PollingComponent, public uart::UARTDevice { sensor::Sensor *temperature_sensor_{nullptr}; sensor::Sensor *co2_sensor_{nullptr}; MHZ19ABCLogic abc_boot_logic_{MHZ19_ABC_NONE}; + uint32_t warmup_seconds_; + + MHZ19DetectionRange detection_range_{MHZ19_DETECTION_RANGE_DEFAULT}; }; template class MHZ19CalibrateZeroAction : public Action { @@ -66,5 +82,16 @@ template class MHZ19ABCDisableAction : public Action { MHZ19Component *mhz19_; }; +template class MHZ19DetectionRangeSetAction : public Action { + public: + MHZ19DetectionRangeSetAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} + TEMPLATABLE_VALUE(MHZ19DetectionRange, detection_range) + + void play(const Ts &...x) override { this->mhz19_->range_set(this->detection_range_.value(x...)); } + + protected: + MHZ19Component *mhz19_; +}; + } // namespace mhz19 } // namespace esphome diff --git a/esphome/components/mhz19/sensor.py b/esphome/components/mhz19/sensor.py index 106636a6ba..0156ee4be0 100644 --- a/esphome/components/mhz19/sensor.py +++ b/esphome/components/mhz19/sensor.py @@ -19,6 +19,7 @@ DEPENDENCIES = ["uart"] CONF_AUTOMATIC_BASELINE_CALIBRATION = "automatic_baseline_calibration" CONF_WARMUP_TIME = "warmup_time" +CONF_DETECTION_RANGE = "detection_range" mhz19_ns = cg.esphome_ns.namespace("mhz19") MHZ19Component = mhz19_ns.class_("MHZ19Component", cg.PollingComponent, uart.UARTDevice) @@ -27,6 +28,18 @@ MHZ19CalibrateZeroAction = mhz19_ns.class_( ) MHZ19ABCEnableAction = mhz19_ns.class_("MHZ19ABCEnableAction", automation.Action) MHZ19ABCDisableAction = mhz19_ns.class_("MHZ19ABCDisableAction", automation.Action) +MHZ19DetectionRangeSetAction = mhz19_ns.class_( + "MHZ19DetectionRangeSetAction", automation.Action +) + +mhz19_detection_range = mhz19_ns.enum("MHZ19DetectionRange") +MHZ19_DETECTION_RANGE_ENUM = { + 2000: mhz19_detection_range.MHZ19_DETECTION_RANGE_0_2000PPM, + 5000: mhz19_detection_range.MHZ19_DETECTION_RANGE_0_5000PPM, + 10000: mhz19_detection_range.MHZ19_DETECTION_RANGE_0_10000PPM, +} + +_validate_ppm = cv.float_with_unit("parts per million", "ppm") CONFIG_SCHEMA = ( cv.Schema( @@ -49,6 +62,9 @@ CONFIG_SCHEMA = ( cv.Optional( CONF_WARMUP_TIME, default="75s" ): cv.positive_time_period_seconds, + cv.Optional(CONF_DETECTION_RANGE): cv.All( + _validate_ppm, cv.enum(MHZ19_DETECTION_RANGE_ENUM) + ), } ) .extend(cv.polling_component_schema("60s")) @@ -78,6 +94,9 @@ async def to_code(config): cg.add(var.set_warmup_seconds(config[CONF_WARMUP_TIME])) + if CONF_DETECTION_RANGE in config: + cg.add(var.set_detection_range(config[CONF_DETECTION_RANGE])) + CALIBRATION_ACTION_SCHEMA = maybe_simple_id( { @@ -98,3 +117,25 @@ CALIBRATION_ACTION_SCHEMA = maybe_simple_id( async def mhz19_calibration_to_code(config, action_id, template_arg, args): paren = await cg.get_variable(config[CONF_ID]) return cg.new_Pvariable(action_id, template_arg, paren) + + +RANGE_ACTION_SCHEMA = maybe_simple_id( + { + cv.Required(CONF_ID): cv.use_id(MHZ19Component), + cv.Required(CONF_DETECTION_RANGE): cv.All( + _validate_ppm, cv.enum(MHZ19_DETECTION_RANGE_ENUM) + ), + } +) + + +@automation.register_action( + "mhz19.detection_range_set", MHZ19DetectionRangeSetAction, RANGE_ACTION_SCHEMA +) +async def mhz19_detection_range_set_to_code(config, action_id, template_arg, args): + paren = await cg.get_variable(config[CONF_ID]) + var = cg.new_Pvariable(action_id, template_arg, paren) + detection_range = config.get(CONF_DETECTION_RANGE) + template_ = await cg.templatable(detection_range, args, mhz19_detection_range) + cg.add(var.set_detection_range(template_)) + return var diff --git a/tests/components/mhz19/common.yaml b/tests/components/mhz19/common.yaml index 94989fecbe..b12ca50197 100644 --- a/tests/components/mhz19/common.yaml +++ b/tests/components/mhz19/common.yaml @@ -6,3 +6,4 @@ sensor: name: MH-Z19 Temperature automatic_baseline_calibration: false update_interval: 15s + detection_range: 5000ppm From ede7391582cc2842f89de62efb105d2836481a3b Mon Sep 17 00:00:00 2001 From: Conrad Juhl Andersen Date: Sat, 3 Jan 2026 23:06:33 +0100 Subject: [PATCH 156/302] [wts01] Fix negative values for WTS01 sensor (#12835) --- esphome/components/wts01/wts01.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/esphome/components/wts01/wts01.cpp b/esphome/components/wts01/wts01.cpp index cb910d89cf..a7948c805a 100644 --- a/esphome/components/wts01/wts01.cpp +++ b/esphome/components/wts01/wts01.cpp @@ -71,17 +71,20 @@ void WTS01Sensor::process_packet_() { } // Extract temperature value - int8_t temp = this->buffer_[6]; - int32_t sign = 1; + const uint8_t raw = this->buffer_[6]; - // Handle negative temperatures - if (temp < 0) { - sign = -1; + // WTS01 encodes sign in bit 7, magnitude in bits 0-6 + const bool negative = (raw & 0x80) != 0; + const uint8_t magnitude = raw & 0x7F; + + const float decimal = static_cast(this->buffer_[7]) / 100.0f; + + float temperature = static_cast(magnitude) + decimal; + + if (negative) { + temperature = -temperature; } - // Calculate temperature (temp + decimal/100) - float temperature = static_cast(temp) + (sign * static_cast(this->buffer_[7]) / 100.0f); - ESP_LOGV(TAG, "Received new temperature: %.2f°C", temperature); this->publish_state(temperature); From a6e9aa78765b4659fcbb51c893faa6b9c9f42753 Mon Sep 17 00:00:00 2001 From: Jasper van der Neut - Stulen Date: Sat, 3 Jan 2026 23:11:02 +0100 Subject: [PATCH 157/302] [mhz19] Refactor Actions to Parented (#12837) --- esphome/components/mhz19/mhz19.h | 35 +++++++----------------------- esphome/components/mhz19/sensor.py | 33 +++++++++++++++++----------- 2 files changed, 28 insertions(+), 40 deletions(-) diff --git a/esphome/components/mhz19/mhz19.h b/esphome/components/mhz19/mhz19.h index feb67bdd82..5898bab649 100644 --- a/esphome/components/mhz19/mhz19.h +++ b/esphome/components/mhz19/mhz19.h @@ -52,45 +52,26 @@ class MHZ19Component : public PollingComponent, public uart::UARTDevice { MHZ19DetectionRange detection_range_{MHZ19_DETECTION_RANGE_DEFAULT}; }; -template class MHZ19CalibrateZeroAction : public Action { +template class MHZ19CalibrateZeroAction : public Action, public Parented { public: - MHZ19CalibrateZeroAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} - - void play(const Ts &...x) override { this->mhz19_->calibrate_zero(); } - - protected: - MHZ19Component *mhz19_; + void play(const Ts &...x) override { this->parent_->calibrate_zero(); } }; -template class MHZ19ABCEnableAction : public Action { +template class MHZ19ABCEnableAction : public Action, public Parented { public: - MHZ19ABCEnableAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} - - void play(const Ts &...x) override { this->mhz19_->abc_enable(); } - - protected: - MHZ19Component *mhz19_; + void play(const Ts &...x) override { this->parent_->abc_enable(); } }; -template class MHZ19ABCDisableAction : public Action { +template class MHZ19ABCDisableAction : public Action, public Parented { public: - MHZ19ABCDisableAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} - - void play(const Ts &...x) override { this->mhz19_->abc_disable(); } - - protected: - MHZ19Component *mhz19_; + void play(const Ts &...x) override { this->parent_->abc_disable(); } }; -template class MHZ19DetectionRangeSetAction : public Action { +template class MHZ19DetectionRangeSetAction : public Action, public Parented { public: - MHZ19DetectionRangeSetAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} TEMPLATABLE_VALUE(MHZ19DetectionRange, detection_range) - void play(const Ts &...x) override { this->mhz19_->range_set(this->detection_range_.value(x...)); } - - protected: - MHZ19Component *mhz19_; + void play(const Ts &...x) override { this->parent_->range_set(this->detection_range_.value(x...)); } }; } // namespace mhz19 diff --git a/esphome/components/mhz19/sensor.py b/esphome/components/mhz19/sensor.py index 0156ee4be0..1f698be404 100644 --- a/esphome/components/mhz19/sensor.py +++ b/esphome/components/mhz19/sensor.py @@ -24,12 +24,18 @@ CONF_DETECTION_RANGE = "detection_range" mhz19_ns = cg.esphome_ns.namespace("mhz19") MHZ19Component = mhz19_ns.class_("MHZ19Component", cg.PollingComponent, uart.UARTDevice) MHZ19CalibrateZeroAction = mhz19_ns.class_( - "MHZ19CalibrateZeroAction", automation.Action + "MHZ19CalibrateZeroAction", automation.Action, cg.Parented.template(MHZ19Component) +) +MHZ19ABCEnableAction = mhz19_ns.class_( + "MHZ19ABCEnableAction", automation.Action, cg.Parented.template(MHZ19Component) +) +MHZ19ABCDisableAction = mhz19_ns.class_( + "MHZ19ABCDisableAction", automation.Action, cg.Parented.template(MHZ19Component) ) -MHZ19ABCEnableAction = mhz19_ns.class_("MHZ19ABCEnableAction", automation.Action) -MHZ19ABCDisableAction = mhz19_ns.class_("MHZ19ABCDisableAction", automation.Action) MHZ19DetectionRangeSetAction = mhz19_ns.class_( - "MHZ19DetectionRangeSetAction", automation.Action + "MHZ19DetectionRangeSetAction", + automation.Action, + cg.Parented.template(MHZ19Component), ) mhz19_detection_range = mhz19_ns.enum("MHZ19DetectionRange") @@ -98,7 +104,7 @@ async def to_code(config): cg.add(var.set_detection_range(config[CONF_DETECTION_RANGE])) -CALIBRATION_ACTION_SCHEMA = maybe_simple_id( +NO_ARGS_ACTION_SCHEMA = maybe_simple_id( { cv.Required(CONF_ID): cv.use_id(MHZ19Component), } @@ -106,17 +112,18 @@ CALIBRATION_ACTION_SCHEMA = maybe_simple_id( @automation.register_action( - "mhz19.calibrate_zero", MHZ19CalibrateZeroAction, CALIBRATION_ACTION_SCHEMA + "mhz19.calibrate_zero", MHZ19CalibrateZeroAction, NO_ARGS_ACTION_SCHEMA ) @automation.register_action( - "mhz19.abc_enable", MHZ19ABCEnableAction, CALIBRATION_ACTION_SCHEMA + "mhz19.abc_enable", MHZ19ABCEnableAction, NO_ARGS_ACTION_SCHEMA ) @automation.register_action( - "mhz19.abc_disable", MHZ19ABCDisableAction, CALIBRATION_ACTION_SCHEMA + "mhz19.abc_disable", MHZ19ABCDisableAction, NO_ARGS_ACTION_SCHEMA ) -async def mhz19_calibration_to_code(config, action_id, template_arg, args): - paren = await cg.get_variable(config[CONF_ID]) - return cg.new_Pvariable(action_id, template_arg, paren) +async def mhz19_no_args_action_to_code(config, action_id, template_arg, args): + var = cg.new_Pvariable(action_id, template_arg) + await cg.register_parented(var, config[CONF_ID]) + return var RANGE_ACTION_SCHEMA = maybe_simple_id( @@ -133,8 +140,8 @@ RANGE_ACTION_SCHEMA = maybe_simple_id( "mhz19.detection_range_set", MHZ19DetectionRangeSetAction, RANGE_ACTION_SCHEMA ) async def mhz19_detection_range_set_to_code(config, action_id, template_arg, args): - paren = await cg.get_variable(config[CONF_ID]) - var = cg.new_Pvariable(action_id, template_arg, paren) + var = cg.new_Pvariable(action_id, template_arg) + await cg.register_parented(var, config[CONF_ID]) detection_range = config.get(CONF_DETECTION_RANGE) template_ = await cg.templatable(detection_range, args, mhz19_detection_range) cg.add(var.set_detection_range(template_)) From 0a0501c1403206c2f7ee6e6f68252e3680142dce Mon Sep 17 00:00:00 2001 From: John Hollowell Date: Sat, 3 Jan 2026 17:11:48 -0500 Subject: [PATCH 158/302] Fix comment typos (#12828) --- esphome/components/i2c/__init__.py | 2 +- esphome/components/one_wire/__init__.py | 2 +- esphome/components/uart/__init__.py | 2 +- esphome/cpp_generator.py | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/components/i2c/__init__.py b/esphome/components/i2c/__init__.py index 56e0c8e4ab..19efda0b49 100644 --- a/esphome/components/i2c/__init__.py +++ b/esphome/components/i2c/__init__.py @@ -250,7 +250,7 @@ async def register_i2c_device(var, config): Sets the i2c bus to use and the i2c address. - This is a coroutine, you need to await it with a 'yield' expression! + This is a coroutine, you need to await it with an 'await' expression! """ parent = await cg.get_variable(config[CONF_I2C_ID]) cg.add(var.set_i2c_bus(parent)) diff --git a/esphome/components/one_wire/__init__.py b/esphome/components/one_wire/__init__.py index e12cca3e27..9173b7014b 100644 --- a/esphome/components/one_wire/__init__.py +++ b/esphome/components/one_wire/__init__.py @@ -32,7 +32,7 @@ async def register_one_wire_device(var, config): Sets the 1-wire bus to use and the 1-wire address. - This is a coroutine, you need to await it with a 'yield' expression! + This is a coroutine, you need to await it with an 'await' expression! """ parent = await cg.get_variable(config[CONF_ONE_WIRE_ID]) cg.add(var.set_one_wire_bus(parent)) diff --git a/esphome/components/uart/__init__.py b/esphome/components/uart/__init__.py index 9baa6ebd81..9ec95964ec 100644 --- a/esphome/components/uart/__init__.py +++ b/esphome/components/uart/__init__.py @@ -482,7 +482,7 @@ def final_validate_device_schema( async def register_uart_device(var, config): """Register a UART device, setting up all the internal values. - This is a coroutine, you need to await it with a 'yield' expression! + This is a coroutine, you need to await it with an 'await' expression! """ parent = await cg.get_variable(config[CONF_UART_ID]) cg.add(var.set_uart_parent(parent)) diff --git a/esphome/cpp_generator.py b/esphome/cpp_generator.py index ddccb574e4..cff0748c95 100644 --- a/esphome/cpp_generator.py +++ b/esphome/cpp_generator.py @@ -643,7 +643,7 @@ async def get_variable(id_: ID) -> "MockObj": Wait for the given ID to be defined in the code generation and return it as a MockObj. - This is a coroutine, you need to await it with a 'await' expression! + This is a coroutine, you need to await it with an 'await' expression! :param id_: The ID to retrieve :return: The variable as a MockObj. @@ -656,7 +656,7 @@ async def get_variable_with_full_id(id_: ID) -> tuple[ID, "MockObj"]: Wait for the given ID to be defined in the code generation and return it as a MockObj. - This is a coroutine, you need to await it with a 'await' expression! + This is a coroutine, you need to await it with an 'await' expression! :param id_: The ID to retrieve :return: The variable as a MockObj. From 9781073f2a78aa0f416a5c7ea09090bfc8f53223 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 12:31:38 -1000 Subject: [PATCH 159/302] [espnow] Use stack-based MAC formatting and remove dead code (#12836) --- .../components/espnow/espnow_component.cpp | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/esphome/components/espnow/espnow_component.cpp b/esphome/components/espnow/espnow_component.cpp index 16e2331937..991803d870 100644 --- a/esphome/components/espnow/espnow_component.cpp +++ b/esphome/components/espnow/espnow_component.cpp @@ -64,18 +64,6 @@ static const LogString *espnow_error_to_str(esp_err_t error) { } } -std::string peer_str(uint8_t *peer) { - if (peer == nullptr || peer[0] == 0) { - return "[Not Set]"; - } else if (memcmp(peer, ESPNOW_BROADCAST_ADDR, ESP_NOW_ETH_ALEN) == 0) { - return "[Broadcast]"; - } else if (memcmp(peer, ESPNOW_MULTICAST_ADDR, ESP_NOW_ETH_ALEN) == 0) { - return "[Multicast]"; - } else { - return format_mac_address_pretty(peer); - } -} - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0) void on_send_report(const esp_now_send_info_t *info, esp_now_send_status_t status) #else @@ -140,11 +128,13 @@ void ESPNowComponent::dump_config() { ESP_LOGCONFIG(TAG, " Disabled"); return; } + char own_addr_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(this->own_address_, own_addr_buf); ESP_LOGCONFIG(TAG, " Own address: %s\n" " Version: v%" PRIu32 "\n" " Wi-Fi channel: %d", - format_mac_address_pretty(this->own_address_).c_str(), version, this->wifi_channel_); + own_addr_buf, version, this->wifi_channel_); #ifdef USE_WIFI ESP_LOGCONFIG(TAG, " Wi-Fi enabled: %s", YESNO(this->is_wifi_enabled())); #endif @@ -300,9 +290,12 @@ void ESPNowComponent::loop() { // Intentionally left as if instead of else in case the peer is added above if (esp_now_is_peer_exist(info.src_addr)) { #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char src_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + char dst_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; char hex_buf[format_hex_pretty_size(ESP_NOW_MAX_DATA_LEN)]; - ESP_LOGV(TAG, "<<< [%s -> %s] %s", format_mac_address_pretty(info.src_addr).c_str(), - format_mac_address_pretty(info.des_addr).c_str(), + format_mac_addr_upper(info.src_addr, src_buf); + format_mac_addr_upper(info.des_addr, dst_buf); + ESP_LOGV(TAG, "<<< [%s -> %s] %s", src_buf, dst_buf, format_hex_pretty_to(hex_buf, packet->packet_.receive.data, packet->packet_.receive.size)); #endif if (memcmp(info.des_addr, ESPNOW_BROADCAST_ADDR, ESP_NOW_ETH_ALEN) == 0) { @@ -321,8 +314,9 @@ void ESPNowComponent::loop() { } case ESPNowPacket::SENT: { #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE - ESP_LOGV(TAG, ">>> [%s] %s", format_mac_address_pretty(packet->packet_.sent.address).c_str(), - LOG_STR_ARG(espnow_error_to_str(packet->packet_.sent.status))); + char addr_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(packet->packet_.sent.address, addr_buf); + ESP_LOGV(TAG, ">>> [%s] %s", addr_buf, LOG_STR_ARG(espnow_error_to_str(packet->packet_.sent.status))); #endif if (this->current_send_packet_ != nullptr) { this->current_send_packet_->callback_(packet->packet_.sent.status); @@ -409,8 +403,9 @@ void ESPNowComponent::send_() { this->current_send_packet_ = packet; esp_err_t err = esp_now_send(packet->address_, packet->data_, packet->size_); if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to send packet to %s - %s", format_mac_address_pretty(packet->address_).c_str(), - LOG_STR_ARG(espnow_error_to_str(err))); + char addr_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(packet->address_, addr_buf); + ESP_LOGE(TAG, "Failed to send packet to %s - %s", addr_buf, LOG_STR_ARG(espnow_error_to_str(err))); if (packet->callback_ != nullptr) { packet->callback_(err); } @@ -439,8 +434,9 @@ esp_err_t ESPNowComponent::add_peer(const uint8_t *peer) { esp_err_t err = esp_now_add_peer(&peer_info); if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to add peer %s - %s", format_mac_address_pretty(peer).c_str(), - LOG_STR_ARG(espnow_error_to_str(err))); + char peer_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(peer, peer_buf); + ESP_LOGE(TAG, "Failed to add peer %s - %s", peer_buf, LOG_STR_ARG(espnow_error_to_str(err))); this->status_momentary_warning("peer-add-failed"); return err; } @@ -468,8 +464,9 @@ esp_err_t ESPNowComponent::del_peer(const uint8_t *peer) { if (esp_now_is_peer_exist(peer)) { esp_err_t err = esp_now_del_peer(peer); if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to delete peer %s - %s", format_mac_address_pretty(peer).c_str(), - LOG_STR_ARG(espnow_error_to_str(err))); + char peer_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(peer, peer_buf); + ESP_LOGE(TAG, "Failed to delete peer %s - %s", peer_buf, LOG_STR_ARG(espnow_error_to_str(err))); this->status_momentary_warning("peer-del-failed"); return err; } From d505f0316b7df4ccd2afc0fe3f58a3c991130c91 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 12:31:58 -1000 Subject: [PATCH 160/302] [wifi] Combine scan result log lines to reduce loop blocking with many matching APs (#12830) --- esphome/components/wifi/wifi_component.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index a0a7d3d946..0738a76777 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -1049,15 +1049,27 @@ template static void insertion_sort_scan_results(VectorType } // Helper function to log matching scan results - marked noinline to prevent re-inlining into loop +// +// IMPORTANT: This function deliberately uses a SINGLE log call to minimize blocking. +// In environments with many matching networks (e.g., 18+ mesh APs), multiple log calls +// per network would block the main loop for an unacceptable duration. Each log call +// has overhead from UART transmission, so combining INFO+DEBUG into one line halves +// the blocking time. Do NOT split this into separate ESP_LOGI/ESP_LOGD calls. __attribute__((noinline)) static void log_scan_result(const WiFiScanResult &res) { char bssid_s[18]; auto bssid = res.get_bssid(); format_mac_addr_upper(bssid.data(), bssid_s); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG + // Single combined log line with all details when DEBUG enabled + ESP_LOGI(TAG, "- '%s' %s" LOG_SECRET("(%s) ") "%s Ch:%2u %3ddB P:%d", res.get_ssid().c_str(), + res.get_is_hidden() ? LOG_STR_LITERAL("(HIDDEN) ") : LOG_STR_LITERAL(""), bssid_s, + LOG_STR_ARG(get_signal_bars(res.get_rssi())), res.get_channel(), res.get_rssi(), res.get_priority()); +#else ESP_LOGI(TAG, "- '%s' %s" LOG_SECRET("(%s) ") "%s", res.get_ssid().c_str(), res.get_is_hidden() ? LOG_STR_LITERAL("(HIDDEN) ") : LOG_STR_LITERAL(""), bssid_s, LOG_STR_ARG(get_signal_bars(res.get_rssi()))); - ESP_LOGD(TAG, " Channel: %2u, RSSI: %3d dB, Priority: %4d", res.get_channel(), res.get_rssi(), res.get_priority()); +#endif } #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE From 6685fa1da98a4c422c3aa5455eb28fe02ec64518 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 12:32:10 -1000 Subject: [PATCH 161/302] [core] Fix startup delay from setup timing logs when console connected (#12832) --- esphome/core/component.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/esphome/core/component.cpp b/esphome/core/component.cpp index 97ab2edb5a..90be6cf646 100644 --- a/esphome/core/component.cpp +++ b/esphome/core/component.cpp @@ -205,7 +205,13 @@ void Component::call() { this->call_setup(); #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG uint32_t setup_time = millis() - start_time; - ESP_LOGCONFIG(TAG, "Setup %s took %ums", LOG_STR_ARG(this->get_component_log_str()), (unsigned) setup_time); + // Only log at CONFIG level if setup took longer than the blocking threshold + // to avoid spamming the log and blocking the event loop + if (setup_time >= WARN_IF_BLOCKING_OVER_MS) { + ESP_LOGCONFIG(TAG, "Setup %s took %ums", LOG_STR_ARG(this->get_component_log_str()), (unsigned) setup_time); + } else { + ESP_LOGV(TAG, "Setup %s took %ums", LOG_STR_ARG(this->get_component_log_str()), (unsigned) setup_time); + } #endif break; } From cb3edfc654af364e9a6cf2bb2b59acaa284b42c2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 12:32:22 -1000 Subject: [PATCH 162/302] [wifi] Use stack-based MAC formatting in ESP8266 and IDF event handlers (#12834) --- .../wifi/wifi_component_esp8266.cpp | 33 +++++++++++++++---- .../wifi/wifi_component_esp_idf.cpp | 25 +++++++++++--- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index 055a13afc8..9d99e0b94c 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -518,8 +518,12 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { switch (event->event) { case EVENT_STAMODE_CONNECTED: { auto it = event->event_info.connected; - ESP_LOGV(TAG, "Connected ssid='%.*s' bssid=%s channel=%u", it.ssid_len, (const char *) it.ssid, - format_mac_address_pretty(it.bssid).c_str(), it.channel); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char bssid_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.bssid, bssid_buf); + ESP_LOGV(TAG, "Connected ssid='%.*s' bssid=%s channel=%u", it.ssid_len, (const char *) it.ssid, bssid_buf, + it.channel); +#endif s_sta_connected = true; #ifdef USE_WIFI_LISTENERS for (auto *listener : global_wifi_component->connect_state_listeners_) { @@ -594,18 +598,30 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { break; } case EVENT_SOFTAPMODE_STACONNECTED: { +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE auto it = event->event_info.sta_connected; - ESP_LOGV(TAG, "AP client connected MAC=%s aid=%u", format_mac_address_pretty(it.mac).c_str(), it.aid); + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.mac, mac_buf); + ESP_LOGV(TAG, "AP client connected MAC=%s aid=%u", mac_buf, it.aid); +#endif break; } case EVENT_SOFTAPMODE_STADISCONNECTED: { +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE auto it = event->event_info.sta_disconnected; - ESP_LOGV(TAG, "AP client disconnected MAC=%s aid=%u", format_mac_address_pretty(it.mac).c_str(), it.aid); + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.mac, mac_buf); + ESP_LOGV(TAG, "AP client disconnected MAC=%s aid=%u", mac_buf, it.aid); +#endif break; } case EVENT_SOFTAPMODE_PROBEREQRECVED: { +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE auto it = event->event_info.ap_probereqrecved; - ESP_LOGVV(TAG, "AP receive Probe Request MAC=%s RSSI=%d", format_mac_address_pretty(it.mac).c_str(), it.rssi); + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.mac, mac_buf); + ESP_LOGVV(TAG, "AP receive Probe Request MAC=%s RSSI=%d", mac_buf, it.rssi); +#endif break; } #if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 4, 0) @@ -616,9 +632,12 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { break; } case EVENT_SOFTAPMODE_DISTRIBUTE_STA_IP: { +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE auto it = event->event_info.distribute_sta_ip; - ESP_LOGV(TAG, "AP Distribute Station IP MAC=%s IP=%s aid=%u", format_mac_address_pretty(it.mac).c_str(), - format_ip_addr(it.ip).c_str(), it.aid); + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.mac, mac_buf); + ESP_LOGV(TAG, "AP Distribute Station IP MAC=%s IP=%s aid=%u", mac_buf, format_ip_addr(it.ip).c_str(), it.aid); +#endif break; } #endif diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index f68a095bff..820725ed31 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -734,9 +734,12 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { } else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_STA_CONNECTED) { const auto &it = data->data.sta_connected; +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char bssid_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.bssid, bssid_buf); ESP_LOGV(TAG, "Connected ssid='%.*s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", it.ssid_len, - (const char *) it.ssid, format_mac_address_pretty(it.bssid).c_str(), it.channel, - get_auth_mode_str(it.authmode)); + (const char *) it.ssid, bssid_buf, it.channel, get_auth_mode_str(it.authmode)); +#endif s_sta_connected = true; #ifdef USE_WIFI_LISTENERS for (auto *listener : this->connect_state_listeners_) { @@ -855,16 +858,28 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { this->ap_started_ = false; } else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_AP_PROBEREQRECVED) { +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE const auto &it = data->data.ap_probe_req_rx; - ESP_LOGVV(TAG, "AP receive Probe Request MAC=%s RSSI=%d", format_mac_address_pretty(it.mac).c_str(), it.rssi); + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.mac, mac_buf); + ESP_LOGVV(TAG, "AP receive Probe Request MAC=%s RSSI=%d", mac_buf, it.rssi); +#endif } else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_AP_STACONNECTED) { +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE const auto &it = data->data.ap_staconnected; - ESP_LOGV(TAG, "AP client connected MAC=%s", format_mac_address_pretty(it.mac).c_str()); + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.mac, mac_buf); + ESP_LOGV(TAG, "AP client connected MAC=%s", mac_buf); +#endif } else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_AP_STADISCONNECTED) { +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE const auto &it = data->data.ap_stadisconnected; - ESP_LOGV(TAG, "AP client disconnected MAC=%s", format_mac_address_pretty(it.mac).c_str()); + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.mac, mac_buf); + ESP_LOGV(TAG, "AP client disconnected MAC=%s", mac_buf); +#endif } else if (data->event_base == IP_EVENT && data->event_id == IP_EVENT_AP_STAIPASSIGNED) { const auto &it = data->data.ip_ap_staipassigned; From c29aa61e2a0fef32cc9bf3bbdfa33c8a8b5a3b44 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Sun, 4 Jan 2026 09:08:47 +1000 Subject: [PATCH 163/302] [image] Use alternative version of CairoSVG on Windows (#12811) --- requirements.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 833ccbb0ed..bada581f56 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,13 @@ ruamel.yaml==0.19.1 # dashboard_import ruamel.yaml.clib==0.2.15 # dashboard_import esphome-glyphsets==0.2.0 pillow==11.3.0 -cairosvg==2.8.2 + +# pycairo fork for Windows +cairosvg @ git+https://github.com/clydebarrow/cairosvg.git@release ; sys_platform == 'win32' + +# Original for everything else +cairosvg==2.8.2 ; sys_platform != 'win32' + freetype-py==2.5.1 jinja2==3.1.6 bleak==2.1.1 From 2e2e54811ac3f98b9eaccd4eac919e1ed0690004 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 13:52:23 -1000 Subject: [PATCH 164/302] [absolute_humidity] Combine log statements to reduce loop blocking (#12838) --- esphome/components/absolute_humidity/absolute_humidity.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/esphome/components/absolute_humidity/absolute_humidity.cpp b/esphome/components/absolute_humidity/absolute_humidity.cpp index 74d675b80b..b13fcd519a 100644 --- a/esphome/components/absolute_humidity/absolute_humidity.cpp +++ b/esphome/components/absolute_humidity/absolute_humidity.cpp @@ -90,13 +90,16 @@ void AbsoluteHumidityComponent::loop() { this->status_set_error(LOG_STR("Invalid saturation vapor pressure equation selection!")); return; } - ESP_LOGD(TAG, "Saturation vapor pressure %f kPa", es); // Calculate absolute humidity const float absolute_humidity = vapor_density(es, hr, temperature_k); + ESP_LOGD(TAG, + "Saturation vapor pressure %f kPa\n" + "Publishing absolute humidity %f g/m³", + es, absolute_humidity); + // Publish absolute humidity - ESP_LOGD(TAG, "Publishing absolute humidity %f g/m³", absolute_humidity); this->status_clear_warning(); this->publish_state(absolute_humidity); } From ec05692f0db5394c1d2d7c9097be9196c991a781 Mon Sep 17 00:00:00 2001 From: tomaszduda23 Date: Sun, 4 Jan 2026 01:12:31 +0100 Subject: [PATCH 165/302] [nrf52] add printk doc (#12839) --- esphome/components/logger/logger_zephyr.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/components/logger/logger_zephyr.cpp b/esphome/components/logger/logger_zephyr.cpp index 330dfa96ec..41f53beec0 100644 --- a/esphome/components/logger/logger_zephyr.cpp +++ b/esphome/components/logger/logger_zephyr.cpp @@ -66,6 +66,8 @@ void Logger::pre_setup() { void HOT Logger::write_msg_(const char *msg, size_t len) { // Single write with newline already in buffer (added by caller) #ifdef CONFIG_PRINTK + // Requires the debug component and an active SWD connection. + // It is used for pyocd rtt -t nrf52840 k_str_out(const_cast(msg), len); #endif if (this->uart_dev_ == nullptr) { From f11abc7dbfb6b0d2c8c8d48baca54094fd534297 Mon Sep 17 00:00:00 2001 From: Douwe <61123717+dhoeben@users.noreply.github.com> Date: Sun, 4 Jan 2026 01:45:49 +0100 Subject: [PATCH 166/302] [water_heater] (2/4) Implement template for new water_heater component (#12516) Co-authored-by: J. Nick Koston Co-authored-by: J. Nick Koston --- .../template/water_heater/__init__.py | 123 ++++++++++++++++++ .../template/water_heater/automation.h | 35 +++++ .../water_heater/template_water_heater.cpp | 88 +++++++++++++ .../water_heater/template_water_heater.h | 53 ++++++++ tests/components/template/common-base.yaml | 30 +++++ 5 files changed, 329 insertions(+) create mode 100644 esphome/components/template/water_heater/__init__.py create mode 100644 esphome/components/template/water_heater/automation.h create mode 100644 esphome/components/template/water_heater/template_water_heater.cpp create mode 100644 esphome/components/template/water_heater/template_water_heater.h diff --git a/esphome/components/template/water_heater/__init__.py b/esphome/components/template/water_heater/__init__.py new file mode 100644 index 0000000000..716289035a --- /dev/null +++ b/esphome/components/template/water_heater/__init__.py @@ -0,0 +1,123 @@ +from esphome import automation +import esphome.codegen as cg +from esphome.components import water_heater +import esphome.config_validation as cv +from esphome.const import ( + CONF_ID, + CONF_MODE, + CONF_OPTIMISTIC, + CONF_RESTORE_MODE, + CONF_SET_ACTION, + CONF_SUPPORTED_MODES, + CONF_TARGET_TEMPERATURE, +) +from esphome.core import ID +from esphome.cpp_generator import MockObj, TemplateArgsType +from esphome.types import ConfigType + +from .. import template_ns + +CONF_CURRENT_TEMPERATURE = "current_temperature" + +TemplateWaterHeater = template_ns.class_( + "TemplateWaterHeater", water_heater.WaterHeater +) + +TemplateWaterHeaterPublishAction = template_ns.class_( + "TemplateWaterHeaterPublishAction", + automation.Action, + cg.Parented.template(TemplateWaterHeater), +) + +TemplateWaterHeaterRestoreMode = template_ns.enum("TemplateWaterHeaterRestoreMode") +RESTORE_MODES = { + "NO_RESTORE": TemplateWaterHeaterRestoreMode.WATER_HEATER_NO_RESTORE, + "RESTORE": TemplateWaterHeaterRestoreMode.WATER_HEATER_RESTORE, + "RESTORE_AND_CALL": TemplateWaterHeaterRestoreMode.WATER_HEATER_RESTORE_AND_CALL, +} + +CONFIG_SCHEMA = water_heater.water_heater_schema(TemplateWaterHeater).extend( + { + cv.Optional(CONF_OPTIMISTIC, default=True): cv.boolean, + cv.Optional(CONF_SET_ACTION): automation.validate_automation(single=True), + cv.Optional(CONF_RESTORE_MODE, default="NO_RESTORE"): cv.enum( + RESTORE_MODES, upper=True + ), + cv.Optional(CONF_CURRENT_TEMPERATURE): cv.returning_lambda, + cv.Optional(CONF_MODE): cv.returning_lambda, + cv.Optional(CONF_SUPPORTED_MODES): cv.ensure_list( + water_heater.validate_water_heater_mode + ), + } +) + + +async def to_code(config: ConfigType) -> None: + var = cg.new_Pvariable(config[CONF_ID]) + await water_heater.register_water_heater(var, config) + + cg.add(var.set_optimistic(config[CONF_OPTIMISTIC])) + + if CONF_SET_ACTION in config: + await automation.build_automation( + var.get_set_trigger(), [], config[CONF_SET_ACTION] + ) + + cg.add(var.set_restore_mode(config[CONF_RESTORE_MODE])) + + if CONF_CURRENT_TEMPERATURE in config: + template_ = await cg.process_lambda( + config[CONF_CURRENT_TEMPERATURE], + [], + return_type=cg.optional.template(cg.float_), + ) + cg.add(var.set_current_temperature_lambda(template_)) + + if CONF_MODE in config: + template_ = await cg.process_lambda( + config[CONF_MODE], + [], + return_type=cg.optional.template(water_heater.WaterHeaterMode), + ) + cg.add(var.set_mode_lambda(template_)) + + if CONF_SUPPORTED_MODES in config: + cg.add(var.set_supported_modes(config[CONF_SUPPORTED_MODES])) + + +@automation.register_action( + "water_heater.template.publish", + TemplateWaterHeaterPublishAction, + cv.Schema( + { + cv.GenerateID(): cv.use_id(TemplateWaterHeater), + cv.Optional(CONF_CURRENT_TEMPERATURE): cv.templatable(cv.temperature), + cv.Optional(CONF_TARGET_TEMPERATURE): cv.templatable(cv.temperature), + cv.Optional(CONF_MODE): cv.templatable( + water_heater.validate_water_heater_mode + ), + } + ), +) +async def water_heater_template_publish_to_code( + config: ConfigType, + action_id: ID, + template_arg: cg.TemplateArguments, + args: TemplateArgsType, +) -> MockObj: + var = cg.new_Pvariable(action_id, template_arg) + await cg.register_parented(var, config[CONF_ID]) + + if current_temp := config.get(CONF_CURRENT_TEMPERATURE): + template_ = await cg.templatable(current_temp, args, float) + cg.add(var.set_current_temperature(template_)) + + if target_temp := config.get(CONF_TARGET_TEMPERATURE): + template_ = await cg.templatable(target_temp, args, float) + cg.add(var.set_target_temperature(template_)) + + if mode := config.get(CONF_MODE): + template_ = await cg.templatable(mode, args, water_heater.WaterHeaterMode) + cg.add(var.set_mode(template_)) + + return var diff --git a/esphome/components/template/water_heater/automation.h b/esphome/components/template/water_heater/automation.h new file mode 100644 index 0000000000..3dad2b85ae --- /dev/null +++ b/esphome/components/template/water_heater/automation.h @@ -0,0 +1,35 @@ +#pragma once + +#include "template_water_heater.h" +#include "esphome/core/automation.h" + +namespace esphome::template_ { + +template +class TemplateWaterHeaterPublishAction : public Action, public Parented { + public: + TEMPLATABLE_VALUE(float, current_temperature) + TEMPLATABLE_VALUE(float, target_temperature) + TEMPLATABLE_VALUE(water_heater::WaterHeaterMode, mode) + + void play(const Ts &...x) override { + if (this->current_temperature_.has_value()) { + this->parent_->set_current_temperature(this->current_temperature_.value(x...)); + } + bool needs_call = this->target_temperature_.has_value() || this->mode_.has_value(); + if (needs_call) { + auto call = this->parent_->make_call(); + if (this->target_temperature_.has_value()) { + call.set_target_temperature(this->target_temperature_.value(x...)); + } + if (this->mode_.has_value()) { + call.set_mode(this->mode_.value(x...)); + } + call.perform(); + } else { + this->parent_->publish_state(); + } + } +}; + +} // namespace esphome::template_ diff --git a/esphome/components/template/water_heater/template_water_heater.cpp b/esphome/components/template/water_heater/template_water_heater.cpp new file mode 100644 index 0000000000..18ef8d3f06 --- /dev/null +++ b/esphome/components/template/water_heater/template_water_heater.cpp @@ -0,0 +1,88 @@ +#include "template_water_heater.h" +#include "esphome/core/log.h" + +namespace esphome::template_ { + +static const char *const TAG = "template.water_heater"; + +TemplateWaterHeater::TemplateWaterHeater() : set_trigger_(new Trigger<>()) {} + +void TemplateWaterHeater::setup() { + if (this->restore_mode_ == TemplateWaterHeaterRestoreMode::WATER_HEATER_RESTORE || + this->restore_mode_ == TemplateWaterHeaterRestoreMode::WATER_HEATER_RESTORE_AND_CALL) { + auto restore = this->restore_state(); + + if (restore.has_value()) { + restore->perform(); + } + } + if (!this->current_temperature_f_.has_value() && !this->mode_f_.has_value()) + this->disable_loop(); +} + +water_heater::WaterHeaterTraits TemplateWaterHeater::traits() { + auto traits = water_heater::WaterHeater::get_traits(); + + if (!this->supported_modes_.empty()) { + traits.set_supported_modes(this->supported_modes_); + } + + traits.set_supports_current_temperature(true); + return traits; +} + +void TemplateWaterHeater::loop() { + bool changed = false; + + auto curr_temp = this->current_temperature_f_.call(); + if (curr_temp.has_value()) { + if (*curr_temp != this->current_temperature_) { + this->current_temperature_ = *curr_temp; + changed = true; + } + } + + auto new_mode = this->mode_f_.call(); + if (new_mode.has_value()) { + if (*new_mode != this->mode_) { + this->mode_ = *new_mode; + changed = true; + } + } + + if (changed) { + this->publish_state(); + } +} + +void TemplateWaterHeater::dump_config() { + LOG_WATER_HEATER("", "Template Water Heater", this); + ESP_LOGCONFIG(TAG, " Optimistic: %s", YESNO(this->optimistic_)); +} + +float TemplateWaterHeater::get_setup_priority() const { return setup_priority::HARDWARE; } + +water_heater::WaterHeaterCallInternal TemplateWaterHeater::make_call() { + return water_heater::WaterHeaterCallInternal(this); +} + +void TemplateWaterHeater::control(const water_heater::WaterHeaterCall &call) { + if (call.get_mode().has_value()) { + if (this->optimistic_) { + this->mode_ = *call.get_mode(); + } + } + if (!std::isnan(call.get_target_temperature())) { + if (this->optimistic_) { + this->target_temperature_ = call.get_target_temperature(); + } + } + + this->set_trigger_->trigger(); + + if (this->optimistic_) { + this->publish_state(); + } +} + +} // namespace esphome::template_ diff --git a/esphome/components/template/water_heater/template_water_heater.h b/esphome/components/template/water_heater/template_water_heater.h new file mode 100644 index 0000000000..e5f51b72dc --- /dev/null +++ b/esphome/components/template/water_heater/template_water_heater.h @@ -0,0 +1,53 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/core/automation.h" +#include "esphome/core/template_lambda.h" +#include "esphome/components/water_heater/water_heater.h" + +namespace esphome::template_ { + +enum TemplateWaterHeaterRestoreMode { + WATER_HEATER_NO_RESTORE, + WATER_HEATER_RESTORE, + WATER_HEATER_RESTORE_AND_CALL, +}; + +class TemplateWaterHeater : public water_heater::WaterHeater { + public: + TemplateWaterHeater(); + + template void set_current_temperature_lambda(F &&f) { + this->current_temperature_f_.set(std::forward(f)); + } + template void set_mode_lambda(F &&f) { this->mode_f_.set(std::forward(f)); } + + void set_optimistic(bool optimistic) { this->optimistic_ = optimistic; } + void set_restore_mode(TemplateWaterHeaterRestoreMode restore_mode) { this->restore_mode_ = restore_mode; } + void set_supported_modes(const std::initializer_list &modes) { + this->supported_modes_ = modes; + } + + Trigger<> *get_set_trigger() const { return this->set_trigger_; } + + void setup() override; + void loop() override; + void dump_config() override; + float get_setup_priority() const override; + + water_heater::WaterHeaterCallInternal make_call() override; + + protected: + void control(const water_heater::WaterHeaterCall &call) override; + water_heater::WaterHeaterTraits traits() override; + + // Ordered to minimize padding on 32-bit: 4-byte members first, then smaller + Trigger<> *set_trigger_; + TemplateLambda current_temperature_f_; + TemplateLambda mode_f_; + TemplateWaterHeaterRestoreMode restore_mode_{WATER_HEATER_NO_RESTORE}; + water_heater::WaterHeaterModeMask supported_modes_; + bool optimistic_{true}; +}; + +} // namespace esphome::template_ diff --git a/tests/components/template/common-base.yaml b/tests/components/template/common-base.yaml index f101eea942..e050c0b307 100644 --- a/tests/components/template/common-base.yaml +++ b/tests/components/template/common-base.yaml @@ -9,6 +9,18 @@ esphome: id: template_sens state: !lambda "return 42.0;" + - water_heater.template.publish: + id: template_water_heater + target_temperature: 50.0 + mode: ECO + + # Templated + - water_heater.template.publish: + id: template_water_heater + current_temperature: !lambda "return 45.0;" + target_temperature: !lambda "return 55.0;" + mode: !lambda "return water_heater::WATER_HEATER_MODE_GAS;" + # Test C++ API: set_template() with stateless lambda (no captures) # NOTE: set_template() is not intended to be a public API, but we test it to ensure it doesn't break. - lambda: |- @@ -299,6 +311,24 @@ alarm_control_panel: codes: - "1234" +water_heater: + - platform: template + id: template_water_heater + name: "Template Water Heater" + optimistic: true + current_temperature: !lambda "return 42.0f;" + mode: !lambda "return water_heater::WATER_HEATER_MODE_ECO;" + supported_modes: + - "OFF" + - ECO + - GAS + - ELECTRIC + - HEAT_PUMP + - HIGH_DEMAND + - PERFORMANCE + set_action: + - logger.log: "set_action" + datetime: - platform: template name: Date From d7a1ac83ca5e76e4d157385d706b4c07726894ab Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:00:51 -1000 Subject: [PATCH 167/302] [esp32_ble_tracker] Combine log statements to reduce loop blocking (#12860) --- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp index 63675ec377..73a5dfb187 100644 --- a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +++ b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp @@ -657,8 +657,10 @@ void ESP32BLETracker::dump_config() { " Continuous Scanning: %s", this->scan_duration_, this->scan_interval_ * 0.625f, this->scan_window_ * 0.625f, this->scan_active_ ? "ACTIVE" : "PASSIVE", YESNO(this->scan_continuous_)); - ESP_LOGCONFIG(TAG, " Scanner State: %s", this->scanner_state_to_string_(this->scanner_state_)); - ESP_LOGCONFIG(TAG, " Connecting: %d, discovered: %d, disconnecting: %d", this->client_state_counts_.connecting, + ESP_LOGCONFIG(TAG, + " Scanner State: %s\n" + " Connecting: %d, discovered: %d, disconnecting: %d", + this->scanner_state_to_string_(this->scanner_state_), this->client_state_counts_.connecting, this->client_state_counts_.discovered, this->client_state_counts_.disconnecting); if (this->scan_start_fail_count_) { ESP_LOGCONFIG(TAG, " Scan Start Fail Count: %d", this->scan_start_fail_count_); From 5e24469ce34d64c99f78352f6fb0342baf84883d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:01:01 -1000 Subject: [PATCH 168/302] [http_request] Combine log statements to reduce loop blocking (#12859) --- esphome/components/http_request/ota/ota_http_request.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/esphome/components/http_request/ota/ota_http_request.cpp b/esphome/components/http_request/ota/ota_http_request.cpp index 2cd7489e38..2a7db9137f 100644 --- a/esphome/components/http_request/ota/ota_http_request.cpp +++ b/esphome/components/http_request/ota/ota_http_request.cpp @@ -105,9 +105,8 @@ uint8_t OtaHttpRequestComponent::do_ota_() { // we will compute MD5 on the fly for verification -- Arduino OTA seems to ignore it md5_receive.init(); - ESP_LOGV(TAG, "MD5Digest initialized"); - - ESP_LOGV(TAG, "OTA backend begin"); + ESP_LOGV(TAG, "MD5Digest initialized\n" + "OTA backend begin"); auto backend = ota::make_ota_backend(); auto error_code = backend->begin(container->content_length); if (error_code != ota::OTA_RESPONSE_OK) { From 5f5edf90e9ff45b86089e3eda127c298f10c74f5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:01:12 -1000 Subject: [PATCH 169/302] [water_heater] Combine log statements to reduce loop blocking (#12858) --- esphome/components/water_heater/water_heater.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/water_heater/water_heater.cpp b/esphome/components/water_heater/water_heater.cpp index 441872ec00..d092203d06 100644 --- a/esphome/components/water_heater/water_heater.cpp +++ b/esphome/components/water_heater/water_heater.cpp @@ -152,8 +152,10 @@ void WaterHeater::setup() { void WaterHeater::publish_state() { auto traits = this->get_traits(); - ESP_LOGD(TAG, "'%s' - Sending state:", this->name_.c_str()); - ESP_LOGD(TAG, " Mode: %s", LOG_STR_ARG(water_heater_mode_to_string(this->mode_))); + ESP_LOGD(TAG, + "'%s' - Sending state:\n" + " Mode: %s", + this->name_.c_str(), LOG_STR_ARG(water_heater_mode_to_string(this->mode_))); if (!std::isnan(this->current_temperature_)) { ESP_LOGD(TAG, " Current Temperature: %.2f°C", this->current_temperature_); } From 07a581e13a68682d86d17e11cc1fa66d4743fb22 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:01:24 -1000 Subject: [PATCH 170/302] [update] Combine log statements to reduce loop blocking (#12857) --- esphome/components/update/update_entity.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/update/update_entity.cpp b/esphome/components/update/update_entity.cpp index 567fc9fc8e..6d13341a8a 100644 --- a/esphome/components/update/update_entity.cpp +++ b/esphome/components/update/update_entity.cpp @@ -9,8 +9,10 @@ namespace update { static const char *const TAG = "update"; void UpdateEntity::publish_state() { - ESP_LOGD(TAG, "'%s' - Publishing:", this->name_.c_str()); - ESP_LOGD(TAG, " Current Version: %s", this->update_info_.current_version.c_str()); + ESP_LOGD(TAG, + "'%s' - Publishing:\n" + " Current Version: %s", + this->name_.c_str(), this->update_info_.current_version.c_str()); if (!this->update_info_.md5.empty()) { ESP_LOGD(TAG, " Latest Version: %s", this->update_info_.latest_version.c_str()); From 2a6b192af8a330cef9714ca6aeaf624fd8568451 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:01:35 -1000 Subject: [PATCH 171/302] [ethernet] Combine log statements to reduce loop blocking (#12854) --- esphome/components/ethernet/ethernet_component.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/ethernet/ethernet_component.cpp b/esphome/components/ethernet/ethernet_component.cpp index af4f652d8b..896c5cc874 100644 --- a/esphome/components/ethernet/ethernet_component.cpp +++ b/esphome/components/ethernet/ethernet_component.cpp @@ -813,8 +813,10 @@ void EthernetComponent::write_phy_register_(esp_eth_mac_t *mac, PHYRegister regi ESPHL_ERROR_CHECK(err, "Select PHY Register page failed"); } - ESP_LOGD(TAG, "Writing to PHY Register Address: 0x%02" PRIX32, register_data.address); - ESP_LOGD(TAG, "Writing to PHY Register Value: 0x%04" PRIX32, register_data.value); + ESP_LOGD(TAG, + "Writing to PHY Register Address: 0x%02" PRIX32 "\n" + "Writing to PHY Register Value: 0x%04" PRIX32, + register_data.address, register_data.value); err = mac->write_phy_reg(mac, this->phy_addr_, register_data.address, register_data.value); ESPHL_ERROR_CHECK(err, "Writing PHY Register failed"); From d364432e3a095d85a63b18a17aa266a9cd8c4cb3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:02:12 -1000 Subject: [PATCH 172/302] [uart] Combine log statements to reduce loop blocking (#12855) --- esphome/components/uart/uart_component_libretiny.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/uart/uart_component_libretiny.cpp b/esphome/components/uart/uart_component_libretiny.cpp index 01c7063fe8..863732c88d 100644 --- a/esphome/components/uart/uart_component_libretiny.cpp +++ b/esphome/components/uart/uart_component_libretiny.cpp @@ -120,8 +120,10 @@ void LibreTinyUARTComponent::setup() { void LibreTinyUARTComponent::dump_config() { bool is_software = this->hardware_idx_ == -1; - ESP_LOGCONFIG(TAG, "UART Bus:"); - ESP_LOGCONFIG(TAG, " Type: %s", UART_TYPE[is_software]); + ESP_LOGCONFIG(TAG, + "UART Bus:\n" + " Type: %s", + UART_TYPE[is_software]); if (!is_software) { ESP_LOGCONFIG(TAG, " Port number: %d", this->hardware_idx_); } From 8ddfeb2d38588e1d1f99b58f318f6e1bb8f5e931 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:02:26 -1000 Subject: [PATCH 173/302] [captive_portal] Combine log statements to reduce loop blocking (#12853) --- esphome/components/captive_portal/captive_portal.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/esphome/components/captive_portal/captive_portal.cpp b/esphome/components/captive_portal/captive_portal.cpp index 749aa705df..d0515166b6 100644 --- a/esphome/components/captive_portal/captive_portal.cpp +++ b/esphome/components/captive_portal/captive_portal.cpp @@ -49,9 +49,11 @@ void CaptivePortal::handle_config(AsyncWebServerRequest *request) { void CaptivePortal::handle_wifisave(AsyncWebServerRequest *request) { std::string ssid = request->arg("ssid").c_str(); // NOLINT(readability-redundant-string-cstr) std::string psk = request->arg("psk").c_str(); // NOLINT(readability-redundant-string-cstr) - ESP_LOGI(TAG, "Requested WiFi Settings Change:"); - ESP_LOGI(TAG, " SSID='%s'", ssid.c_str()); - ESP_LOGI(TAG, " Password=" LOG_SECRET("'%s'"), psk.c_str()); + ESP_LOGI(TAG, + "Requested WiFi Settings Change:\n" + " SSID='%s'\n" + " Password=" LOG_SECRET("'%s'"), + ssid.c_str(), psk.c_str()); // Defer save to main loop thread to avoid NVS operations from HTTP thread this->defer([ssid, psk]() { wifi::global_wifi_component->save_wifi_sta(ssid, psk); }); request->redirect(ESPHOME_F("/?save")); From 41a188ac3589bf646e4297840da316869fb72335 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:03:01 -1000 Subject: [PATCH 174/302] [ac_dimmer] Fix ESP8266 build by requiring waveform support (#12852) --- esphome/components/ac_dimmer/output.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/esphome/components/ac_dimmer/output.py b/esphome/components/ac_dimmer/output.py index 5e24779510..9f9afb6d80 100644 --- a/esphome/components/ac_dimmer/output.py +++ b/esphome/components/ac_dimmer/output.py @@ -3,6 +3,7 @@ import esphome.codegen as cg from esphome.components import output import esphome.config_validation as cv from esphome.const import CONF_ID, CONF_METHOD, CONF_MIN_POWER +from esphome.core import CORE CODEOWNERS = ["@glmnet"] @@ -36,6 +37,12 @@ CONFIG_SCHEMA = cv.All( async def to_code(config): + if CORE.is_esp8266: + # ac_dimmer uses setTimer1Callback which requires the waveform generator + from esphome.components.esp8266.const import require_waveform + + require_waveform() + var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) From ea848db683867152fe731202438ce1efb98ae227 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:03:20 -1000 Subject: [PATCH 175/302] [bp1658cj] Combine log statements to reduce loop blocking (#12851) --- esphome/components/bp1658cj/bp1658cj.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/bp1658cj/bp1658cj.cpp b/esphome/components/bp1658cj/bp1658cj.cpp index b8ad5dc3d2..d5516384ff 100644 --- a/esphome/components/bp1658cj/bp1658cj.cpp +++ b/esphome/components/bp1658cj/bp1658cj.cpp @@ -22,13 +22,13 @@ void BP1658CJ::setup() { this->pwm_amounts_.resize(5, 0); } void BP1658CJ::dump_config() { - ESP_LOGCONFIG(TAG, "BP1658CJ:"); - LOG_PIN(" Data Pin: ", this->data_pin_); - LOG_PIN(" Clock Pin: ", this->clock_pin_); ESP_LOGCONFIG(TAG, + "BP1658CJ:\n" " Color Channels Max Power: %u\n" " White Channels Max Power: %u", this->max_power_color_channels_, this->max_power_white_channels_); + LOG_PIN(" Data Pin: ", this->data_pin_); + LOG_PIN(" Clock Pin: ", this->clock_pin_); } void BP1658CJ::loop() { From 0196d6ee5573c338f3823a7a649c23dcd46cac45 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:03:44 -1000 Subject: [PATCH 176/302] [ble_nus] Combine log statements to reduce loop blocking (#12850) --- esphome/components/ble_nus/ble_nus.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/ble_nus/ble_nus.cpp b/esphome/components/ble_nus/ble_nus.cpp index bd80592d89..0de65b623f 100644 --- a/esphome/components/ble_nus/ble_nus.cpp +++ b/esphome/components/ble_nus/ble_nus.cpp @@ -103,8 +103,10 @@ void BLENUS::on_log(uint8_t level, const char *tag, const char *message, size_t #endif void BLENUS::dump_config() { - ESP_LOGCONFIG(TAG, "ble nus:"); - ESP_LOGCONFIG(TAG, " log: %s", YESNO(this->expose_log_)); + ESP_LOGCONFIG(TAG, + "ble nus:\n" + " log: %s", + YESNO(this->expose_log_)); uint32_t mtu = 0; bt_conn *conn = this->conn_.load(); if (conn) { From 41e7ecb29fd86a7468b6f93ac6eff3a64a504b57 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:04:21 -1000 Subject: [PATCH 177/302] [bedjet] Combine log statements to reduce loop blocking (#12848) --- esphome/components/bedjet/bedjet_hub.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/esphome/components/bedjet/bedjet_hub.cpp b/esphome/components/bedjet/bedjet_hub.cpp index 38fcf29b3b..a3054cf48e 100644 --- a/esphome/components/bedjet/bedjet_hub.cpp +++ b/esphome/components/bedjet/bedjet_hub.cpp @@ -216,11 +216,14 @@ bool BedJetHub::discover_characteristics_() { } } - ESP_LOGI(TAG, "[%s] Discovered service characteristics: ", this->get_name().c_str()); - ESP_LOGI(TAG, " - Command char: 0x%x", this->char_handle_cmd_); - ESP_LOGI(TAG, " - Status char: 0x%x", this->char_handle_status_); - ESP_LOGI(TAG, " - config descriptor: 0x%x", this->config_descr_status_); - ESP_LOGI(TAG, " - Name char: 0x%x", this->char_handle_name_); + ESP_LOGI(TAG, + "[%s] Discovered service characteristics:\n" + " - Command char: 0x%x\n" + " - Status char: 0x%x\n" + " - config descriptor: 0x%x\n" + " - Name char: 0x%x", + this->get_name().c_str(), this->char_handle_cmd_, this->char_handle_status_, this->config_descr_status_, + this->char_handle_name_); return result; } From 6bbee3cfc67a522a26c785fb90831500f5bfe37f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:04:38 -1000 Subject: [PATCH 178/302] [as3935] Combine log statements to reduce loop blocking (#12846) --- esphome/components/as3935/as3935.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/esphome/components/as3935/as3935.cpp b/esphome/components/as3935/as3935.cpp index 2609af07d3..93a0bff5b3 100644 --- a/esphome/components/as3935/as3935.cpp +++ b/esphome/components/as3935/as3935.cpp @@ -305,12 +305,14 @@ bool AS3935Component::calibrate_oscillator() { } void AS3935Component::tune_antenna() { - ESP_LOGI(TAG, "Starting antenna tuning"); uint8_t div_ratio = this->read_div_ratio(); uint8_t tune_val = this->read_capacitance(); - ESP_LOGI(TAG, "Division Ratio is set to: %d", div_ratio); - ESP_LOGI(TAG, "Internal Capacitor is set to: %d", tune_val); - ESP_LOGI(TAG, "Displaying oscillator on INT pin. Measure its frequency - multiply value by Division Ratio"); + ESP_LOGI(TAG, + "Starting antenna tuning\n" + "Division Ratio is set to: %d\n" + "Internal Capacitor is set to: %d\n" + "Displaying oscillator on INT pin. Measure its frequency - multiply value by Division Ratio", + div_ratio, tune_val); this->display_oscillator(true, ANTFREQ); } From d84562f87882b7cee98701a13830a62b24d67b10 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:04:57 -1000 Subject: [PATCH 179/302] [anova] Combine log statements to reduce loop blocking (#12845) --- esphome/components/anova/anova.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/anova/anova.cpp b/esphome/components/anova/anova.cpp index 2693224a97..5054488089 100644 --- a/esphome/components/anova/anova.cpp +++ b/esphome/components/anova/anova.cpp @@ -67,8 +67,10 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_ case ESP_GATTC_SEARCH_CMPL_EVT: { auto *chr = this->parent_->get_characteristic(ANOVA_SERVICE_UUID, ANOVA_CHARACTERISTIC_UUID); if (chr == nullptr) { - ESP_LOGW(TAG, "[%s] No control service found at device, not an Anova..?", this->get_name().c_str()); - ESP_LOGW(TAG, "[%s] Note, this component does not currently support Anova Nano.", this->get_name().c_str()); + ESP_LOGW(TAG, + "[%s] No control service found at device, not an Anova..?\n" + "[%s] Note, this component does not currently support Anova Nano.", + this->get_name().c_str(), this->get_name().c_str()); break; } this->char_handle_ = chr->handle; From 9cb265347ce27d809704c6c01d8bfd4190911c13 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:05:15 -1000 Subject: [PATCH 180/302] [ads1118] Combine log statements to reduce loop blocking (#12844) --- esphome/components/ads1118/sensor/ads1118_sensor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/ads1118/sensor/ads1118_sensor.cpp b/esphome/components/ads1118/sensor/ads1118_sensor.cpp index c3ce3bdc9c..7193c3c880 100644 --- a/esphome/components/ads1118/sensor/ads1118_sensor.cpp +++ b/esphome/components/ads1118/sensor/ads1118_sensor.cpp @@ -9,8 +9,10 @@ static const char *const TAG = "ads1118.sensor"; void ADS1118Sensor::dump_config() { LOG_SENSOR(" ", "ADS1118 Sensor", this); - ESP_LOGCONFIG(TAG, " Multiplexer: %u", this->multiplexer_); - ESP_LOGCONFIG(TAG, " Gain: %u", this->gain_); + ESP_LOGCONFIG(TAG, + " Multiplexer: %u\n" + " Gain: %u", + this->multiplexer_, this->gain_); } float ADS1118Sensor::sample() { From 102862e99dceea007fbb14ba2dcccf24c224a491 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:05:29 -1000 Subject: [PATCH 181/302] [ads1115] Combine log statements to reduce loop blocking (#12843) --- esphome/components/ads1115/sensor/ads1115_sensor.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/esphome/components/ads1115/sensor/ads1115_sensor.cpp b/esphome/components/ads1115/sensor/ads1115_sensor.cpp index 6de95f1d12..fac6b60d0a 100644 --- a/esphome/components/ads1115/sensor/ads1115_sensor.cpp +++ b/esphome/components/ads1115/sensor/ads1115_sensor.cpp @@ -21,10 +21,12 @@ void ADS1115Sensor::update() { void ADS1115Sensor::dump_config() { LOG_SENSOR(" ", "ADS1115 Sensor", this); - ESP_LOGCONFIG(TAG, " Multiplexer: %u", this->multiplexer_); - ESP_LOGCONFIG(TAG, " Gain: %u", this->gain_); - ESP_LOGCONFIG(TAG, " Resolution: %u", this->resolution_); - ESP_LOGCONFIG(TAG, " Sample rate: %u", this->samplerate_); + ESP_LOGCONFIG(TAG, + " Multiplexer: %u\n" + " Gain: %u\n" + " Resolution: %u\n" + " Sample rate: %u", + this->multiplexer_, this->gain_, this->resolution_, this->samplerate_); } } // namespace ads1115 From 723ccd7547f73eb0647f54e91631958b5fcb2ff0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:05:41 -1000 Subject: [PATCH 182/302] [ade7880] Combine log statements to reduce loop blocking (#12842) --- esphome/components/ade7880/ade7880.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/ade7880/ade7880.cpp b/esphome/components/ade7880/ade7880.cpp index fd560e0676..f6a15190cd 100644 --- a/esphome/components/ade7880/ade7880.cpp +++ b/esphome/components/ade7880/ade7880.cpp @@ -162,11 +162,13 @@ void ADE7880::update() { } void ADE7880::dump_config() { - ESP_LOGCONFIG(TAG, "ADE7880:"); + ESP_LOGCONFIG(TAG, + "ADE7880:\n" + " Frequency: %.0f Hz", + this->frequency_); LOG_PIN(" IRQ0 Pin: ", this->irq0_pin_); LOG_PIN(" IRQ1 Pin: ", this->irq1_pin_); LOG_PIN(" RESET Pin: ", this->reset_pin_); - ESP_LOGCONFIG(TAG, " Frequency: %.0f Hz", this->frequency_); if (this->channel_a_ != nullptr) { ESP_LOGCONFIG(TAG, " Phase A:"); From ee65f2f0cd9bf93b63053fe7d335c4458f383be7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:24:41 -1000 Subject: [PATCH 183/302] [adc] Combine log statements to reduce loop blocking (#12841) --- esphome/components/adc/adc_sensor_esp32.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/esphome/components/adc/adc_sensor_esp32.cpp b/esphome/components/adc/adc_sensor_esp32.cpp index 120cb1c926..ea1263db5f 100644 --- a/esphome/components/adc/adc_sensor_esp32.cpp +++ b/esphome/components/adc/adc_sensor_esp32.cpp @@ -121,23 +121,21 @@ void ADCSensor::setup() { void ADCSensor::dump_config() { LOG_SENSOR("", "ADC Sensor", this); LOG_PIN(" Pin: ", this->pin_); - ESP_LOGCONFIG(TAG, - " Channel: %d\n" - " Unit: %s\n" - " Attenuation: %s\n" - " Samples: %i\n" - " Sampling mode: %s", - this->channel_, LOG_STR_ARG(adc_unit_to_str(this->adc_unit_)), - this->autorange_ ? "Auto" : LOG_STR_ARG(attenuation_to_str(this->attenuation_)), this->sample_count_, - LOG_STR_ARG(sampling_mode_to_str(this->sampling_mode_))); - ESP_LOGCONFIG( TAG, + " Channel: %d\n" + " Unit: %s\n" + " Attenuation: %s\n" + " Samples: %i\n" + " Sampling mode: %s\n" " Setup Status:\n" " Handle Init: %s\n" " Config: %s\n" " Calibration: %s\n" " Overall Init: %s", + this->channel_, LOG_STR_ARG(adc_unit_to_str(this->adc_unit_)), + this->autorange_ ? "Auto" : LOG_STR_ARG(attenuation_to_str(this->attenuation_)), this->sample_count_, + LOG_STR_ARG(sampling_mode_to_str(this->sampling_mode_)), this->setup_flags_.handle_init_complete ? "OK" : "FAILED", this->setup_flags_.config_complete ? "OK" : "FAILED", this->setup_flags_.calibration_complete ? "OK" : "FAILED", this->setup_flags_.init_complete ? "OK" : "FAILED"); From 8b80fe9c6bb73746b881e09baf3959853c9779f4 Mon Sep 17 00:00:00 2001 From: Frederic Meeuwissen <13856291+Frederic98@users.noreply.github.com> Date: Sun, 4 Jan 2026 02:32:27 +0100 Subject: [PATCH 184/302] [esp32_rmt_led_strip] Support inverted logic (#12825) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- esphome/components/esp32_rmt_led_strip/led_strip.cpp | 2 +- esphome/components/esp32_rmt_led_strip/led_strip.h | 2 ++ esphome/components/esp32_rmt_led_strip/light.py | 8 ++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/esphome/components/esp32_rmt_led_strip/led_strip.cpp b/esphome/components/esp32_rmt_led_strip/led_strip.cpp index 2c7963b366..4ca0b998b1 100644 --- a/esphome/components/esp32_rmt_led_strip/led_strip.cpp +++ b/esphome/components/esp32_rmt_led_strip/led_strip.cpp @@ -98,7 +98,7 @@ void ESP32RMTLEDStripLightOutput::setup() { channel.trans_queue_depth = 1; channel.flags.io_loop_back = 0; channel.flags.io_od_mode = 0; - channel.flags.invert_out = 0; + channel.flags.invert_out = this->invert_out_; channel.flags.with_dma = this->use_dma_; channel.intr_priority = 0; if (rmt_new_tx_channel(&channel, &this->channel_) != ESP_OK) { diff --git a/esphome/components/esp32_rmt_led_strip/led_strip.h b/esphome/components/esp32_rmt_led_strip/led_strip.h index 72ce659b4f..6f3aea9878 100644 --- a/esphome/components/esp32_rmt_led_strip/led_strip.h +++ b/esphome/components/esp32_rmt_led_strip/led_strip.h @@ -49,6 +49,7 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight { } void set_pin(uint8_t pin) { this->pin_ = pin; } + void set_inverted(bool inverted) { this->invert_out_ = inverted; } void set_num_leds(uint16_t num_leds) { this->num_leds_ = num_leds; } void set_is_rgbw(bool is_rgbw) { this->is_rgbw_ = is_rgbw; } void set_is_wrgb(bool is_wrgb) { this->is_wrgb_ = is_wrgb; } @@ -93,6 +94,7 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight { bool is_wrgb_{false}; bool use_dma_{false}; bool use_psram_{false}; + bool invert_out_{false}; RGBOrder rgb_order_{ORDER_RGB}; diff --git a/esphome/components/esp32_rmt_led_strip/light.py b/esphome/components/esp32_rmt_led_strip/light.py index f020d02e86..3be3c758f1 100644 --- a/esphome/components/esp32_rmt_led_strip/light.py +++ b/esphome/components/esp32_rmt_led_strip/light.py @@ -8,9 +8,11 @@ from esphome.components.const import CONF_USE_PSRAM import esphome.config_validation as cv from esphome.const import ( CONF_CHIPSET, + CONF_INVERTED, CONF_IS_RGBW, CONF_MAX_REFRESH_RATE, CONF_NUM_LEDS, + CONF_NUMBER, CONF_OUTPUT_ID, CONF_PIN, CONF_RGB_ORDER, @@ -71,7 +73,7 @@ CONFIG_SCHEMA = cv.All( light.ADDRESSABLE_LIGHT_SCHEMA.extend( { cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(ESP32RMTLEDStripLightOutput), - cv.Required(CONF_PIN): pins.internal_gpio_output_pin_number, + cv.Required(CONF_PIN): pins.internal_gpio_output_pin_schema, cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int, cv.Required(CONF_RGB_ORDER): cv.enum(RGB_ORDERS, upper=True), cv.SplitDefault( @@ -132,7 +134,9 @@ async def to_code(config): await cg.register_component(var, config) cg.add(var.set_num_leds(config[CONF_NUM_LEDS])) - cg.add(var.set_pin(config[CONF_PIN])) + cg.add(var.set_pin(config[CONF_PIN][CONF_NUMBER])) + if config[CONF_PIN][CONF_INVERTED]: + cg.add(var.set_inverted(True)) if CONF_MAX_REFRESH_RATE in config: cg.add(var.set_max_refresh_rate(config[CONF_MAX_REFRESH_RATE])) From 997ab553c1b80148433f911e0cac50fefc3de07c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:36:08 -1000 Subject: [PATCH 185/302] [ac_dimmer] Combine log statements to reduce loop blocking (#12840) Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> --- esphome/components/ac_dimmer/ac_dimmer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/ac_dimmer/ac_dimmer.cpp b/esphome/components/ac_dimmer/ac_dimmer.cpp index e6f7a1214a..04c01948c8 100644 --- a/esphome/components/ac_dimmer/ac_dimmer.cpp +++ b/esphome/components/ac_dimmer/ac_dimmer.cpp @@ -211,13 +211,13 @@ void AcDimmer::write_state(float state) { this->store_.value = new_value; } void AcDimmer::dump_config() { - ESP_LOGCONFIG(TAG, "AcDimmer:"); - LOG_PIN(" Output Pin: ", this->gate_pin_); - LOG_PIN(" Zero-Cross Pin: ", this->zero_cross_pin_); ESP_LOGCONFIG(TAG, + "AcDimmer:\n" " Min Power: %.1f%%\n" " Init with half cycle: %s", this->store_.min_power / 10.0f, YESNO(this->init_with_half_cycle_)); + LOG_PIN(" Output Pin: ", this->gate_pin_); + LOG_PIN(" Zero-Cross Pin: ", this->zero_cross_pin_); if (method_ == DIM_METHOD_LEADING_PULSE) { ESP_LOGCONFIG(TAG, " Method: leading pulse"); } else if (method_ == DIM_METHOD_LEADING) { From 7b74f94360603e18e230036b04544694369d5bb3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:54:56 -1000 Subject: [PATCH 186/302] [wifi] Combine log statements to reduce loop blocking (#12856) Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> --- esphome/components/wifi/wifi_component.cpp | 28 +++++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 0738a76777..ca7b1ba9cc 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -781,8 +781,10 @@ void WiFiComponent::start_connecting(const WiFiAP &ap) { get_max_retries_for_phase(this->retry_phase_), LOG_STR_ARG(retry_phase_to_log_string(this->retry_phase_))); #ifdef ESPHOME_LOG_HAS_VERBOSE - ESP_LOGV(TAG, "Connection Params:"); - ESP_LOGV(TAG, " SSID: '%s'", ap.get_ssid().c_str()); + ESP_LOGV(TAG, + "Connection Params:\n" + " SSID: '%s'", + ap.get_ssid().c_str()); if (ap.has_bssid()) { ESP_LOGV(TAG, " BSSID: %s", bssid_s); } else { @@ -791,20 +793,28 @@ void WiFiComponent::start_connecting(const WiFiAP &ap) { #ifdef USE_WIFI_WPA2_EAP if (ap.get_eap().has_value()) { - ESP_LOGV(TAG, " WPA2 Enterprise authentication configured:"); EAPAuth eap_config = ap.get_eap().value(); - ESP_LOGV(TAG, " Identity: " LOG_SECRET("'%s'"), eap_config.identity.c_str()); - ESP_LOGV(TAG, " Username: " LOG_SECRET("'%s'"), eap_config.username.c_str()); - ESP_LOGV(TAG, " Password: " LOG_SECRET("'%s'"), eap_config.password.c_str()); + // clang-format off + ESP_LOGV( + TAG, + " WPA2 Enterprise authentication configured:\n" + " Identity: " LOG_SECRET("'%s'") "\n" + " Username: " LOG_SECRET("'%s'") "\n" + " Password: " LOG_SECRET("'%s'"), + eap_config.identity.c_str(), eap_config.username.c_str(), eap_config.password.c_str()); + // clang-format on #if defined(USE_ESP32) && defined(USE_WIFI_WPA2_EAP) && ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE ESP_LOGV(TAG, " TTLS Phase 2: " LOG_SECRET("'%s'"), eap_phase2_to_str(eap_config.ttls_phase_2)); #endif bool ca_cert_present = eap_config.ca_cert != nullptr && strlen(eap_config.ca_cert); bool client_cert_present = eap_config.client_cert != nullptr && strlen(eap_config.client_cert); bool client_key_present = eap_config.client_key != nullptr && strlen(eap_config.client_key); - ESP_LOGV(TAG, " CA Cert: %s", ca_cert_present ? "present" : "not present"); - ESP_LOGV(TAG, " Client Cert: %s", client_cert_present ? "present" : "not present"); - ESP_LOGV(TAG, " Client Key: %s", client_key_present ? "present" : "not present"); + ESP_LOGV(TAG, + " CA Cert: %s\n" + " Client Cert: %s\n" + " Client Key: %s", + ca_cert_present ? "present" : "not present", client_cert_present ? "present" : "not present", + client_key_present ? "present" : "not present"); } else { #endif ESP_LOGV(TAG, " Password: " LOG_SECRET("'%s'"), ap.get_password().c_str()); From 6b4b1272db27b7292a6f2adf1cad1e269d6a6eeb Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 15:56:52 -1000 Subject: [PATCH 187/302] [binary_sensor] Combine log statements to reduce loop blocking (#12849) --- esphome/components/binary_sensor/automation.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/binary_sensor/automation.cpp b/esphome/components/binary_sensor/automation.cpp index 66d8d6e90f..dfe911a2f8 100644 --- a/esphome/components/binary_sensor/automation.cpp +++ b/esphome/components/binary_sensor/automation.cpp @@ -21,8 +21,10 @@ void MultiClickTrigger::on_state_(bool state) { // Start matching MultiClickTriggerEvent evt = this->timing_[0]; if (evt.state == state) { - ESP_LOGV(TAG, "START min=%" PRIu32 " max=%" PRIu32, evt.min_length, evt.max_length); - ESP_LOGV(TAG, "Multi Click: Starting multi click action!"); + ESP_LOGV(TAG, + "START min=%" PRIu32 " max=%" PRIu32 "\n" + "Multi Click: Starting multi click action!", + evt.min_length, evt.max_length); this->at_index_ = 1; if (this->timing_.size() == 1 && evt.max_length == 4294967294UL) { this->set_timeout("trigger", evt.min_length, [this]() { this->trigger_(); }); From 32562ca9916794c6450ccff4d7bb2af5182f7a74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 4 Jan 2026 01:59:03 +0000 Subject: [PATCH 188/302] Bump aioesphomeapi from 43.10.0 to 43.10.1 (#12865) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index bada581f56..6631cb55bd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile esptool==5.1.0 click==8.1.7 esphome-dashboard==20251013.0 -aioesphomeapi==43.10.0 +aioesphomeapi==43.10.1 zeroconf==0.148.0 puremagic==1.30 ruamel.yaml==0.19.1 # dashboard_import From 5d384c77c545c4452e21f0737353eba34db585b0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 16:00:50 -1000 Subject: [PATCH 189/302] [esp32] Move heap functions to flash, saving ~6KB (#12862) --- esphome/components/esp32/__init__.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index da550e58dc..aa7d215c06 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -644,6 +644,7 @@ CONF_DISABLE_VFS_SUPPORT_SELECT = "disable_vfs_support_select" CONF_DISABLE_VFS_SUPPORT_DIR = "disable_vfs_support_dir" CONF_FREERTOS_IN_IRAM = "freertos_in_iram" CONF_RINGBUF_IN_IRAM = "ringbuf_in_iram" +CONF_HEAP_IN_IRAM = "heap_in_iram" CONF_LOOP_TASK_STACK_SIZE = "loop_task_stack_size" # VFS requirement tracking @@ -745,6 +746,7 @@ FRAMEWORK_SCHEMA = cv.Schema( cv.Optional(CONF_DISABLE_VFS_SUPPORT_DIR, default=True): cv.boolean, cv.Optional(CONF_FREERTOS_IN_IRAM, default=False): cv.boolean, cv.Optional(CONF_RINGBUF_IN_IRAM, default=False): cv.boolean, + cv.Optional(CONF_HEAP_IN_IRAM, default=False): cv.boolean, cv.Optional(CONF_EXECUTE_FROM_PSRAM, default=False): cv.boolean, cv.Optional(CONF_LOOP_TASK_STACK_SIZE, default=8192): cv.int_range( min=8192, max=32768 @@ -1090,6 +1092,12 @@ async def to_code(config): # Place in flash to save IRAM (default) add_idf_sdkconfig_option("CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH", True) + # Place heap functions into flash to save IRAM (~4-6KB savings) + # Safe as long as heap functions are not called from ISRs (which they shouldn't be) + # Users can set heap_in_iram: true as an escape hatch if needed + if not conf[CONF_ADVANCED][CONF_HEAP_IN_IRAM]: + add_idf_sdkconfig_option("CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH", True) + # Setup watchdog add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT", True) add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_PANIC", True) From 5f1eacf4ecf8fcc73775311508a92d4d7ff3296b Mon Sep 17 00:00:00 2001 From: Douwe <61123717+dhoeben@users.noreply.github.com> Date: Sun, 4 Jan 2026 03:43:31 +0100 Subject: [PATCH 190/302] [water_heater] (4/4) Implement tests for new water_heater component (#12517) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: J. Nick Koston Co-authored-by: J. Nick Koston --- .../water_heater/template_water_heater.cpp | 2 +- tests/components/water_heater/common.yaml | 16 +++ tests/components/web_server/common.yaml | 1 + .../fixtures/water_heater_template.yaml | 23 ++++ .../integration/test_water_heater_template.py | 109 ++++++++++++++++++ 5 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 tests/components/water_heater/common.yaml create mode 100644 tests/integration/fixtures/water_heater_template.yaml create mode 100644 tests/integration/test_water_heater_template.py diff --git a/esphome/components/template/water_heater/template_water_heater.cpp b/esphome/components/template/water_heater/template_water_heater.cpp index 18ef8d3f06..5ae5c30f36 100644 --- a/esphome/components/template/water_heater/template_water_heater.cpp +++ b/esphome/components/template/water_heater/template_water_heater.cpp @@ -21,7 +21,7 @@ void TemplateWaterHeater::setup() { } water_heater::WaterHeaterTraits TemplateWaterHeater::traits() { - auto traits = water_heater::WaterHeater::get_traits(); + water_heater::WaterHeaterTraits traits; if (!this->supported_modes_.empty()) { traits.set_supported_modes(this->supported_modes_); diff --git a/tests/components/water_heater/common.yaml b/tests/components/water_heater/common.yaml new file mode 100644 index 0000000000..8ec2b1b297 --- /dev/null +++ b/tests/components/water_heater/common.yaml @@ -0,0 +1,16 @@ +water_heater: + - platform: template + id: my_boiler + name: "Test Boiler" + min_temperature: 10 + max_temperature: 85 + target_temperature_step: 0.5 + current_temperature_step: 0.1 + optimistic: true + current_temperature: 45.0 + mode: !lambda "return water_heater::WATER_HEATER_MODE_ECO;" + visual: + min_temperature: 10 + max_temperature: 85 + target_temperature_step: 0.5 + current_temperature_step: 0.1 diff --git a/tests/components/web_server/common.yaml b/tests/components/web_server/common.yaml index eb768eeb91..82307c189c 100644 --- a/tests/components/web_server/common.yaml +++ b/tests/components/web_server/common.yaml @@ -36,3 +36,4 @@ datetime: optimistic: yes event: update: +water_heater: diff --git a/tests/integration/fixtures/water_heater_template.yaml b/tests/integration/fixtures/water_heater_template.yaml new file mode 100644 index 0000000000..b54ebed789 --- /dev/null +++ b/tests/integration/fixtures/water_heater_template.yaml @@ -0,0 +1,23 @@ +esphome: + name: water-heater-template-test +host: +api: +logger: + +water_heater: + - platform: template + id: test_boiler + name: Test Boiler + optimistic: true + current_temperature: !lambda "return 45.0f;" + # Note: No mode lambda - we want optimistic mode changes to stick + # A mode lambda would override mode changes in loop() + supported_modes: + - "off" + - eco + - gas + - performance + visual: + min_temperature: 30.0 + max_temperature: 85.0 + target_temperature_step: 0.5 diff --git a/tests/integration/test_water_heater_template.py b/tests/integration/test_water_heater_template.py new file mode 100644 index 0000000000..b5f1fb64c0 --- /dev/null +++ b/tests/integration/test_water_heater_template.py @@ -0,0 +1,109 @@ +"""Integration test for template water heater component.""" + +from __future__ import annotations + +import asyncio + +import aioesphomeapi +from aioesphomeapi import WaterHeaterInfo, WaterHeaterMode, WaterHeaterState +import pytest + +from .state_utils import InitialStateHelper +from .types import APIClientConnectedFactory, RunCompiledFunction + + +@pytest.mark.asyncio +async def test_water_heater_template( + yaml_config: str, + run_compiled: RunCompiledFunction, + api_client_connected: APIClientConnectedFactory, +) -> None: + """Test template water heater basic state and mode changes.""" + loop = asyncio.get_running_loop() + async with run_compiled(yaml_config), api_client_connected() as client: + states: dict[int, aioesphomeapi.EntityState] = {} + gas_mode_future: asyncio.Future[WaterHeaterState] = loop.create_future() + eco_mode_future: asyncio.Future[WaterHeaterState] = loop.create_future() + + def on_state(state: aioesphomeapi.EntityState) -> None: + states[state.key] = state + if isinstance(state, WaterHeaterState): + # Wait for GAS mode + if state.mode == WaterHeaterMode.GAS and not gas_mode_future.done(): + gas_mode_future.set_result(state) + # Wait for ECO mode (we start at OFF, so test transitioning to ECO) + elif state.mode == WaterHeaterMode.ECO and not eco_mode_future.done(): + eco_mode_future.set_result(state) + + # Get entities and set up state synchronization + entities, services = await client.list_entities_services() + initial_state_helper = InitialStateHelper(entities) + water_heater_infos = [e for e in entities if isinstance(e, WaterHeaterInfo)] + assert len(water_heater_infos) == 1, ( + f"Expected exactly 1 water heater entity, got {len(water_heater_infos)}. Entity types: {[type(e).__name__ for e in entities]}" + ) + + test_water_heater = water_heater_infos[0] + + # Verify water heater entity info + assert test_water_heater.object_id == "test_boiler" + assert test_water_heater.name == "Test Boiler" + assert test_water_heater.min_temperature == 30.0 + assert test_water_heater.max_temperature == 85.0 + assert test_water_heater.target_temperature_step == 0.5 + + # Verify supported modes + supported_modes = test_water_heater.supported_modes + assert WaterHeaterMode.OFF in supported_modes, "Expected OFF in supported modes" + assert WaterHeaterMode.ECO in supported_modes, "Expected ECO in supported modes" + assert WaterHeaterMode.GAS in supported_modes, "Expected GAS in supported modes" + assert WaterHeaterMode.PERFORMANCE in supported_modes, ( + "Expected PERFORMANCE in supported modes" + ) + assert len(supported_modes) == 4, ( + f"Expected 4 supported modes, got {len(supported_modes)}: {supported_modes}" + ) + + # Subscribe with the wrapper that filters initial states + client.subscribe_states(initial_state_helper.on_state_wrapper(on_state)) + + # Wait for all initial states to be broadcast + try: + await initial_state_helper.wait_for_initial_states() + except TimeoutError: + pytest.fail("Timeout waiting for initial states") + + # Get initial state and verify + initial_state = initial_state_helper.initial_states.get(test_water_heater.key) + assert initial_state is not None, "Water heater initial state not found" + assert isinstance(initial_state, WaterHeaterState) + # Initial mode is OFF (default) since we don't have a mode lambda + # A mode lambda would override optimistic mode changes + assert initial_state.mode == WaterHeaterMode.OFF, ( + f"Expected initial mode OFF, got {initial_state.mode}" + ) + assert initial_state.current_temperature == 45.0, ( + f"Expected current temp 45.0, got {initial_state.current_temperature}" + ) + + # Test changing to GAS mode + client.water_heater_command(test_water_heater.key, mode=WaterHeaterMode.GAS) + + try: + gas_state = await asyncio.wait_for(gas_mode_future, timeout=5.0) + except TimeoutError: + pytest.fail("GAS mode change not received within 5 seconds") + + assert isinstance(gas_state, WaterHeaterState) + assert gas_state.mode == WaterHeaterMode.GAS + + # Test changing to ECO mode (from GAS) + client.water_heater_command(test_water_heater.key, mode=WaterHeaterMode.ECO) + + try: + eco_state = await asyncio.wait_for(eco_mode_future, timeout=5.0) + except TimeoutError: + pytest.fail("ECO mode change not received within 5 seconds") + + assert isinstance(eco_state, WaterHeaterState) + assert eco_state.mode == WaterHeaterMode.ECO From 12c6f5749e22bbaf4c8bfba02d452b11f1b4219b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 16:46:29 -1000 Subject: [PATCH 191/302] [cst816] Combine log statements to reduce loop blocking (#12872) --- .../components/cst816/touchscreen/cst816_touchscreen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/cst816/touchscreen/cst816_touchscreen.cpp b/esphome/components/cst816/touchscreen/cst816_touchscreen.cpp index 5be93692c0..d18d4e7c94 100644 --- a/esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +++ b/esphome/components/cst816/touchscreen/cst816_touchscreen.cpp @@ -83,14 +83,14 @@ void CST816Touchscreen::update_touches() { } void CST816Touchscreen::dump_config() { - ESP_LOGCONFIG(TAG, "CST816 Touchscreen:"); - LOG_I2C_DEVICE(this); - LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_); - LOG_PIN(" Reset Pin: ", this->reset_pin_); ESP_LOGCONFIG(TAG, + "CST816 Touchscreen:\n" " X Raw Min: %d, X Raw Max: %d\n" " Y Raw Min: %d, Y Raw Max: %d", this->x_raw_min_, this->x_raw_max_, this->y_raw_min_, this->y_raw_max_); + LOG_I2C_DEVICE(this); + LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_); + LOG_PIN(" Reset Pin: ", this->reset_pin_); const char *name; switch (this->chip_id_) { case CST716_CHIP_ID: From c96d0015a003f0a918bd648059b32e6980709cdf Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 16:48:04 -1000 Subject: [PATCH 192/302] [esp_ldo] Combine log statements to reduce loop blocking (#12886) --- esphome/components/esp_ldo/esp_ldo.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/esphome/components/esp_ldo/esp_ldo.cpp b/esphome/components/esp_ldo/esp_ldo.cpp index 5e3d4159f3..2eee855b46 100644 --- a/esphome/components/esp_ldo/esp_ldo.cpp +++ b/esphome/components/esp_ldo/esp_ldo.cpp @@ -21,9 +21,11 @@ void EspLdo::setup() { } } void EspLdo::dump_config() { - ESP_LOGCONFIG(TAG, "ESP LDO Channel %d:", this->channel_); - ESP_LOGCONFIG(TAG, " Voltage: %fV", this->voltage_); - ESP_LOGCONFIG(TAG, " Adjustable: %s", YESNO(this->adjustable_)); + ESP_LOGCONFIG(TAG, + "ESP LDO Channel %d:\n" + " Voltage: %fV\n" + " Adjustable: %s", + this->channel_, this->voltage_, YESNO(this->adjustable_)); } void EspLdo::adjust_voltage(float voltage) { From 16ada4d477146f2ff33caa445f295c4817d1825b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 16:48:39 -1000 Subject: [PATCH 193/302] [epaper_spi] Combine log statements to reduce loop blocking (#12881) --- esphome/components/epaper_spi/epaper_spi.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/esphome/components/epaper_spi/epaper_spi.cpp b/esphome/components/epaper_spi/epaper_spi.cpp index 4e6b4a7fd6..0b600feeae 100644 --- a/esphome/components/epaper_spi/epaper_spi.cpp +++ b/esphome/components/epaper_spi/epaper_spi.cpp @@ -331,20 +331,21 @@ void HOT EPaperBase::draw_pixel_at(int x, int y, Color color) { void EPaperBase::dump_config() { LOG_DISPLAY("", "E-Paper SPI", this); - ESP_LOGCONFIG(TAG, " Model: %s", this->name_); - LOG_PIN(" Reset Pin: ", this->reset_pin_); - LOG_PIN(" DC Pin: ", this->dc_pin_); - LOG_PIN(" Busy Pin: ", this->busy_pin_); - LOG_PIN(" CS Pin: ", this->cs_); - LOG_UPDATE_INTERVAL(this); ESP_LOGCONFIG(TAG, + " Model: %s\n" " SPI Data Rate: %uMHz\n" " Full update every: %d\n" " Swap X/Y: %s\n" " Mirror X: %s\n" " Mirror Y: %s", - (unsigned) (this->data_rate_ / 1000000), this->full_update_every_, YESNO(this->transform_ & SWAP_XY), - YESNO(this->transform_ & MIRROR_X), YESNO(this->transform_ & MIRROR_Y)); + this->name_, (unsigned) (this->data_rate_ / 1000000), this->full_update_every_, + YESNO(this->transform_ & SWAP_XY), YESNO(this->transform_ & MIRROR_X), + YESNO(this->transform_ & MIRROR_Y)); + LOG_PIN(" Reset Pin: ", this->reset_pin_); + LOG_PIN(" DC Pin: ", this->dc_pin_); + LOG_PIN(" Busy Pin: ", this->busy_pin_); + LOG_PIN(" CS Pin: ", this->cs_); + LOG_UPDATE_INTERVAL(this); } } // namespace esphome::epaper_spi From cf93b66306a7e7f941a8a204709856be9eebb4fb Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 16:59:55 -1000 Subject: [PATCH 194/302] [chsc6x] Combine log statements to reduce loop blocking (#12871) --- esphome/components/chsc6x/chsc6x_touchscreen.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/chsc6x/chsc6x_touchscreen.cpp b/esphome/components/chsc6x/chsc6x_touchscreen.cpp index 31c9466691..941144e451 100644 --- a/esphome/components/chsc6x/chsc6x_touchscreen.cpp +++ b/esphome/components/chsc6x/chsc6x_touchscreen.cpp @@ -32,14 +32,14 @@ void CHSC6XTouchscreen::update_touches() { } void CHSC6XTouchscreen::dump_config() { - ESP_LOGCONFIG(TAG, "CHSC6X Touchscreen:"); - LOG_I2C_DEVICE(this); - LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_); ESP_LOGCONFIG(TAG, + "CHSC6X Touchscreen:\n" " Touch timeout: %d\n" " x_raw_max_: %d\n" " y_raw_max_: %d", this->touch_timeout_, this->x_raw_max_, this->y_raw_max_); + LOG_I2C_DEVICE(this); + LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_); } } // namespace chsc6x From bc9093127e5fff67c901b29691c4c4dae000bc2f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 17:00:14 -1000 Subject: [PATCH 195/302] [cap1188] Combine log statements to reduce loop blocking (#12868) --- esphome/components/cap1188/cap1188.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/cap1188/cap1188.cpp b/esphome/components/cap1188/cap1188.cpp index 683e5cf487..9e8c87d147 100644 --- a/esphome/components/cap1188/cap1188.cpp +++ b/esphome/components/cap1188/cap1188.cpp @@ -63,14 +63,14 @@ void CAP1188Component::finish_setup_() { } void CAP1188Component::dump_config() { - ESP_LOGCONFIG(TAG, "CAP1188:"); - LOG_I2C_DEVICE(this); - LOG_PIN(" Reset Pin: ", this->reset_pin_); ESP_LOGCONFIG(TAG, + "CAP1188:\n" " Product ID: 0x%x\n" " Manufacture ID: 0x%x\n" " Revision ID: 0x%x", this->cap1188_product_id_, this->cap1188_manufacture_id_, this->cap1188_revision_); + LOG_I2C_DEVICE(this); + LOG_PIN(" Reset Pin: ", this->reset_pin_); switch (this->error_code_) { case COMMUNICATION_FAILED: From 44fa6bae95bf3a60962c1752c187532251ebe5c2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 17:57:53 -1000 Subject: [PATCH 196/302] [dht] Combine log statements to reduce loop blocking (#12877) --- esphome/components/dht/dht.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/esphome/components/dht/dht.cpp b/esphome/components/dht/dht.cpp index e0abb7c5f0..6cb204c8de 100644 --- a/esphome/components/dht/dht.cpp +++ b/esphome/components/dht/dht.cpp @@ -17,11 +17,14 @@ void DHT::setup() { } void DHT::dump_config() { - ESP_LOGCONFIG(TAG, "DHT:"); + ESP_LOGCONFIG(TAG, + "DHT:\n" + " %sModel: %s\n" + " Internal pull-up: %s", + this->is_auto_detect_ ? "Auto-detected " : "", + this->model_ == DHT_MODEL_DHT11 ? "DHT11" : "DHT22 or equivalent", + ONOFF(this->t_pin_->get_flags() & gpio::FLAG_PULLUP)); LOG_PIN(" Pin: ", this->t_pin_); - ESP_LOGCONFIG(TAG, " %sModel: %s", this->is_auto_detect_ ? "Auto-detected " : "", - this->model_ == DHT_MODEL_DHT11 ? "DHT11" : "DHT22 or equivalent"); - ESP_LOGCONFIG(TAG, " Internal pull-up: %s", ONOFF(this->t_pin_->get_flags() & gpio::FLAG_PULLUP)); LOG_UPDATE_INTERVAL(this); LOG_SENSOR(" ", "Temperature", this->temperature_sensor_); LOG_SENSOR(" ", "Humidity", this->humidity_sensor_); From 9f06f046d67f64041eb472bb017e0b03d223b341 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 17:59:53 -1000 Subject: [PATCH 197/302] [espnow] Combine log statements to reduce loop blocking (#12887) --- .../espnow/packet_transport/espnow_transport.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/esphome/components/espnow/packet_transport/espnow_transport.cpp b/esphome/components/espnow/packet_transport/espnow_transport.cpp index c1252acc9d..3d16f28c7d 100644 --- a/esphome/components/espnow/packet_transport/espnow_transport.cpp +++ b/esphome/components/espnow/packet_transport/espnow_transport.cpp @@ -21,9 +21,11 @@ void ESPNowTransport::setup() { return; } - ESP_LOGI(TAG, "Registering ESP-NOW handlers"); - ESP_LOGI(TAG, "Peer address: %02X:%02X:%02X:%02X:%02X:%02X", this->peer_address_[0], this->peer_address_[1], - this->peer_address_[2], this->peer_address_[3], this->peer_address_[4], this->peer_address_[5]); + ESP_LOGI(TAG, + "Registering ESP-NOW handlers\n" + "Peer address: %02X:%02X:%02X:%02X:%02X:%02X", + this->peer_address_[0], this->peer_address_[1], this->peer_address_[2], this->peer_address_[3], + this->peer_address_[4], this->peer_address_[5]); // Register received handler this->parent_->register_received_handler(this); From 6e8817cbc47f1dcf116eb2bdd06fbbfdb8b8f892 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 18:00:11 -1000 Subject: [PATCH 198/302] [esp8266_pwm] Combine log statements to reduce loop blocking (#12885) --- esphome/components/esp8266_pwm/esp8266_pwm.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/esp8266_pwm/esp8266_pwm.cpp b/esphome/components/esp8266_pwm/esp8266_pwm.cpp index 0aaef597d3..cc6bfbc8a8 100644 --- a/esphome/components/esp8266_pwm/esp8266_pwm.cpp +++ b/esphome/components/esp8266_pwm/esp8266_pwm.cpp @@ -18,9 +18,11 @@ void ESP8266PWM::setup() { this->turn_off(); } void ESP8266PWM::dump_config() { - ESP_LOGCONFIG(TAG, "ESP8266 PWM:"); + ESP_LOGCONFIG(TAG, + "ESP8266 PWM:\n" + " Frequency: %.1f Hz", + this->frequency_); LOG_PIN(" Pin: ", this->pin_); - ESP_LOGCONFIG(TAG, " Frequency: %.1f Hz", this->frequency_); LOG_FLOAT_OUTPUT(this); } void HOT ESP8266PWM::write_state(float state) { From cb598c43e891c6887efd1ede490e621041a72a0a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 18:00:31 -1000 Subject: [PATCH 199/302] [endstop] Combine log statements to reduce loop blocking (#12879) --- esphome/components/endstop/endstop_cover.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/endstop/endstop_cover.cpp b/esphome/components/endstop/endstop_cover.cpp index 381f098eb5..2c281ea2e6 100644 --- a/esphome/components/endstop/endstop_cover.cpp +++ b/esphome/components/endstop/endstop_cover.cpp @@ -104,10 +104,12 @@ void EndstopCover::loop() { } void EndstopCover::dump_config() { LOG_COVER("", "Endstop Cover", this); + ESP_LOGCONFIG(TAG, + " Open Duration: %.1fs\n" + " Close Duration: %.1fs", + this->open_duration_ / 1e3f, this->close_duration_ / 1e3f); LOG_BINARY_SENSOR(" ", "Open Endstop", this->open_endstop_); - ESP_LOGCONFIG(TAG, " Open Duration: %.1fs", this->open_duration_ / 1e3f); LOG_BINARY_SENSOR(" ", "Close Endstop", this->close_endstop_); - ESP_LOGCONFIG(TAG, " Close Duration: %.1fs", this->close_duration_ / 1e3f); } float EndstopCover::get_setup_priority() const { return setup_priority::DATA; } void EndstopCover::stop_prev_trigger_() { From e94158a12f303543bea4e901601373a60d471af6 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 18:00:52 -1000 Subject: [PATCH 200/302] [fan] Combine log statements to reduce loop blocking (#12889) --- esphome/components/fan/fan.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/fan/fan.cpp b/esphome/components/fan/fan.cpp index bf5506da4b..0ffb60e50d 100644 --- a/esphome/components/fan/fan.cpp +++ b/esphome/components/fan/fan.cpp @@ -179,8 +179,10 @@ void Fan::add_on_state_callback(std::function &&callback) { this->state_ void Fan::publish_state() { auto traits = this->get_traits(); - ESP_LOGD(TAG, "'%s' - Sending state:", this->name_.c_str()); - ESP_LOGD(TAG, " State: %s", ONOFF(this->state)); + ESP_LOGD(TAG, + "'%s' - Sending state:\n" + " State: %s", + this->name_.c_str(), ONOFF(this->state)); if (traits.supports_speed()) { ESP_LOGD(TAG, " Speed: %d", this->speed); } From c59314ec09c5e311ca313d9c4baa37c29ccf2e7f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 18:01:28 -1000 Subject: [PATCH 201/302] [debug] Combine log statements to reduce loop blocking (#12875) --- esphome/components/debug/debug_esp8266.cpp | 19 +++++---- esphome/components/debug/debug_libretiny.cpp | 15 ++++--- esphome/components/debug/debug_zephyr.cpp | 43 +++++++++++--------- 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/esphome/components/debug/debug_esp8266.cpp b/esphome/components/debug/debug_esp8266.cpp index 3395d9db12..7427b32290 100644 --- a/esphome/components/debug/debug_esp8266.cpp +++ b/esphome/components/debug/debug_esp8266.cpp @@ -47,14 +47,17 @@ void DebugComponent::get_device_info_(std::string &device_info) { #if !defined(CLANG_TIDY) auto reset_reason = get_reset_reason_(); - ESP_LOGD(TAG, "Chip ID: 0x%08X", ESP.getChipId()); - ESP_LOGD(TAG, "SDK Version: %s", ESP.getSdkVersion()); - ESP_LOGD(TAG, "Core Version: %s", ESP.getCoreVersion().c_str()); - ESP_LOGD(TAG, "Boot Version=%u Mode=%u", ESP.getBootVersion(), ESP.getBootMode()); - ESP_LOGD(TAG, "CPU Frequency: %u", ESP.getCpuFreqMHz()); - ESP_LOGD(TAG, "Flash Chip ID=0x%08X", ESP.getFlashChipId()); - ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str()); - ESP_LOGD(TAG, "Reset Info: %s", ESP.getResetInfo().c_str()); + ESP_LOGD(TAG, + "Chip ID: 0x%08X\n" + "SDK Version: %s\n" + "Core Version: %s\n" + "Boot Version=%u Mode=%u\n" + "CPU Frequency: %u\n" + "Flash Chip ID=0x%08X\n" + "Reset Reason: %s\n" + "Reset Info: %s", + ESP.getChipId(), ESP.getSdkVersion(), ESP.getCoreVersion().c_str(), ESP.getBootVersion(), ESP.getBootMode(), + ESP.getCpuFreqMHz(), ESP.getFlashChipId(), reset_reason.c_str(), ESP.getResetInfo().c_str()); device_info += "|Chip: 0x" + format_hex(ESP.getChipId()); device_info += "|SDK: "; diff --git a/esphome/components/debug/debug_libretiny.cpp b/esphome/components/debug/debug_libretiny.cpp index b5e2a5b310..e823ac6c77 100644 --- a/esphome/components/debug/debug_libretiny.cpp +++ b/esphome/components/debug/debug_libretiny.cpp @@ -13,12 +13,15 @@ uint32_t DebugComponent::get_free_heap_() { return lt_heap_get_free(); } void DebugComponent::get_device_info_(std::string &device_info) { std::string reset_reason = get_reset_reason_(); - ESP_LOGD(TAG, "LibreTiny Version: %s", lt_get_version()); - ESP_LOGD(TAG, "Chip: %s (%04x) @ %u MHz", lt_cpu_get_model_name(), lt_cpu_get_model(), lt_cpu_get_freq_mhz()); - ESP_LOGD(TAG, "Chip ID: 0x%06X", lt_cpu_get_mac_id()); - ESP_LOGD(TAG, "Board: %s", lt_get_board_code()); - ESP_LOGD(TAG, "Flash: %u KiB / RAM: %u KiB", lt_flash_get_size() / 1024, lt_ram_get_size() / 1024); - ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str()); + ESP_LOGD(TAG, + "LibreTiny Version: %s\n" + "Chip: %s (%04x) @ %u MHz\n" + "Chip ID: 0x%06X\n" + "Board: %s\n" + "Flash: %u KiB / RAM: %u KiB\n" + "Reset Reason: %s", + lt_get_version(), lt_cpu_get_model_name(), lt_cpu_get_model(), lt_cpu_get_freq_mhz(), lt_cpu_get_mac_id(), + lt_get_board_code(), lt_flash_get_size() / 1024, lt_ram_get_size() / 1024, reset_reason.c_str()); device_info += "|Version: "; device_info += LT_BANNER_STR + 10; diff --git a/esphome/components/debug/debug_zephyr.cpp b/esphome/components/debug/debug_zephyr.cpp index c888c41a78..6abf983e9e 100644 --- a/esphome/components/debug/debug_zephyr.cpp +++ b/esphome/components/debug/debug_zephyr.cpp @@ -106,13 +106,13 @@ static void fa_cb(const struct flash_area *fa, void *user_data) { void DebugComponent::log_partition_info_() { #if CONFIG_FLASH_MAP_LABELS ESP_LOGCONFIG(TAG, "ID | Device | Device Name " - "| Label | Offset | Size"); - ESP_LOGCONFIG(TAG, "--------------------------------------------" + "| Label | Offset | Size\n" + "--------------------------------------------" "-----------------------------------------------"); #else ESP_LOGCONFIG(TAG, "ID | Device | Device Name " - "| Offset | Size"); - ESP_LOGCONFIG(TAG, "-----------------------------------------" + "| Offset | Size\n" + "-----------------------------------------" "------------------------------"); #endif flash_area_foreach(fa_cb, nullptr); @@ -300,18 +300,18 @@ void DebugComponent::get_device_info_(std::string &device_info) { return "Unspecified"; }; - ESP_LOGD(TAG, "Code page size: %u, code size: %u, device id: 0x%08x%08x", NRF_FICR->CODEPAGESIZE, NRF_FICR->CODESIZE, - NRF_FICR->DEVICEID[1], NRF_FICR->DEVICEID[0]); - ESP_LOGD(TAG, "Encryption root: 0x%08x%08x%08x%08x, Identity Root: 0x%08x%08x%08x%08x", NRF_FICR->ER[0], + ESP_LOGD(TAG, + "Code page size: %u, code size: %u, device id: 0x%08x%08x\n" + "Encryption root: 0x%08x%08x%08x%08x, Identity Root: 0x%08x%08x%08x%08x\n" + "Device address type: %s, address: %s\n" + "Part code: nRF%x, version: %c%c%c%c, package: %s\n" + "RAM: %ukB, Flash: %ukB, production test: %sdone", + NRF_FICR->CODEPAGESIZE, NRF_FICR->CODESIZE, NRF_FICR->DEVICEID[1], NRF_FICR->DEVICEID[0], NRF_FICR->ER[0], NRF_FICR->ER[1], NRF_FICR->ER[2], NRF_FICR->ER[3], NRF_FICR->IR[0], NRF_FICR->IR[1], NRF_FICR->IR[2], - NRF_FICR->IR[3]); - ESP_LOGD(TAG, "Device address type: %s, address: %s", (NRF_FICR->DEVICEADDRTYPE & 0x1 ? "Random" : "Public"), - get_mac_address_pretty().c_str()); - ESP_LOGD(TAG, "Part code: nRF%x, version: %c%c%c%c, package: %s", NRF_FICR->INFO.PART, - NRF_FICR->INFO.VARIANT >> 24 & 0xFF, NRF_FICR->INFO.VARIANT >> 16 & 0xFF, NRF_FICR->INFO.VARIANT >> 8 & 0xFF, - NRF_FICR->INFO.VARIANT & 0xFF, package(NRF_FICR->INFO.PACKAGE)); - ESP_LOGD(TAG, "RAM: %ukB, Flash: %ukB, production test: %sdone", NRF_FICR->INFO.RAM, NRF_FICR->INFO.FLASH, - (NRF_FICR->PRODTEST[0] == 0xBB42319F ? "" : "not ")); + NRF_FICR->IR[3], (NRF_FICR->DEVICEADDRTYPE & 0x1 ? "Random" : "Public"), get_mac_address_pretty().c_str(), + NRF_FICR->INFO.PART, NRF_FICR->INFO.VARIANT >> 24 & 0xFF, NRF_FICR->INFO.VARIANT >> 16 & 0xFF, + NRF_FICR->INFO.VARIANT >> 8 & 0xFF, NRF_FICR->INFO.VARIANT & 0xFF, package(NRF_FICR->INFO.PACKAGE), + NRF_FICR->INFO.RAM, NRF_FICR->INFO.FLASH, (NRF_FICR->PRODTEST[0] == 0xBB42319F ? "" : "not ")); bool n_reset_enabled = NRF_UICR->PSELRESET[0] == NRF_UICR->PSELRESET[1] && (NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) == UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos; @@ -329,9 +329,10 @@ void DebugComponent::get_device_info_(std::string &device_info) { #else ESP_LOGD(TAG, "bootloader: Adafruit, version %u.%u.%u", (BOOTLOADER_VERSION_REGISTER >> 16) & 0xFF, (BOOTLOADER_VERSION_REGISTER >> 8) & 0xFF, BOOTLOADER_VERSION_REGISTER & 0xFF); - ESP_LOGD(TAG, "MBR bootloader addr 0x%08x, UICR bootloader addr 0x%08x", read_mem_u32(MBR_BOOTLOADER_ADDR), - NRF_UICR->NRFFW[0]); - ESP_LOGD(TAG, "MBR param page addr 0x%08x, UICR param page addr 0x%08x", read_mem_u32(MBR_PARAM_PAGE_ADDR), + ESP_LOGD(TAG, + "MBR bootloader addr 0x%08x, UICR bootloader addr 0x%08x\n" + "MBR param page addr 0x%08x, UICR param page addr 0x%08x", + read_mem_u32(MBR_BOOTLOADER_ADDR), NRF_UICR->NRFFW[0], read_mem_u32(MBR_PARAM_PAGE_ADDR), NRF_UICR->NRFFW[1]); if (is_sd_present()) { uint32_t const sd_id = sd_id_get(); @@ -368,8 +369,10 @@ void DebugComponent::get_device_info_(std::string &device_info) { } return res; }; - ESP_LOGD(TAG, "NRFFW %s", uicr(NRF_UICR->NRFFW, 13).c_str()); - ESP_LOGD(TAG, "NRFHW %s", uicr(NRF_UICR->NRFHW, 12).c_str()); + ESP_LOGD(TAG, + "NRFFW %s\n" + "NRFHW %s", + uicr(NRF_UICR->NRFFW, 13).c_str(), uicr(NRF_UICR->NRFHW, 12).c_str()); } void DebugComponent::update_platform_() {} From 096de869b6c67cb72126da67ca4d4a6699bc78e7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 18:01:55 -1000 Subject: [PATCH 202/302] [esp32_ble_client] Combine log statements to reduce loop blocking (#12883) --- .../components/esp32_ble_client/ble_client_base.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/esphome/components/esp32_ble_client/ble_client_base.cpp b/esphome/components/esp32_ble_client/ble_client_base.cpp index 8017b577f4..26eb5dd092 100644 --- a/esphome/components/esp32_ble_client/ble_client_base.cpp +++ b/esphome/components/esp32_ble_client/ble_client_base.cpp @@ -70,9 +70,9 @@ float BLEClientBase::get_setup_priority() const { return setup_priority::AFTER_B void BLEClientBase::dump_config() { ESP_LOGCONFIG(TAG, " Address: %s\n" - " Auto-Connect: %s", - this->address_str(), TRUEFALSE(this->auto_connect_)); - ESP_LOGCONFIG(TAG, " State: %s", espbt::client_state_to_string(this->state())); + " Auto-Connect: %s\n" + " State: %s", + this->address_str(), TRUEFALSE(this->auto_connect_), espbt::client_state_to_string(this->state())); if (this->status_ == ESP_GATT_NO_RESOURCES) { ESP_LOGE(TAG, " Failed due to no resources. Try to reduce number of BLE clients in config."); } else if (this->status_ != ESP_GATT_OK) { @@ -415,8 +415,10 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_ for (auto &svc : this->services_) { char uuid_buf[espbt::UUID_STR_LEN]; svc->uuid.to_str(uuid_buf); - ESP_LOGV(TAG, "[%d] [%s] Service UUID: %s", this->connection_index_, this->address_str_, uuid_buf); - ESP_LOGV(TAG, "[%d] [%s] start_handle: 0x%x end_handle: 0x%x", this->connection_index_, this->address_str_, + ESP_LOGV(TAG, + "[%d] [%s] Service UUID: %s\n" + "[%d] [%s] start_handle: 0x%x end_handle: 0x%x", + this->connection_index_, this->address_str_, uuid_buf, this->connection_index_, this->address_str_, svc->start_handle, svc->end_handle); } #endif From facf4777a400327b1120e1898425d06a025b9c11 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 3 Jan 2026 18:04:00 -1000 Subject: [PATCH 203/302] [ezo_pmp] Combine log statements to reduce loop blocking (#12888) --- esphome/components/ezo_pmp/ezo_pmp.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/esphome/components/ezo_pmp/ezo_pmp.cpp b/esphome/components/ezo_pmp/ezo_pmp.cpp index 9ec41cce30..61b601328a 100644 --- a/esphome/components/ezo_pmp/ezo_pmp.cpp +++ b/esphome/components/ezo_pmp/ezo_pmp.cpp @@ -148,10 +148,13 @@ void EzoPMP::read_command_result_() { char current_char = response_buffer[i]; if (current_char == '\0') { - ESP_LOGV(TAG, "Read Response from device: %s", (char *) response_buffer); - ESP_LOGV(TAG, "First Component: %s", (char *) first_parameter_buffer); - ESP_LOGV(TAG, "Second Component: %s", (char *) second_parameter_buffer); - ESP_LOGV(TAG, "Third Component: %s", (char *) third_parameter_buffer); + ESP_LOGV(TAG, + "Read Response from device: %s\n" + "First Component: %s\n" + "Second Component: %s\n" + "Third Component: %s", + (char *) response_buffer, (char *) first_parameter_buffer, (char *) second_parameter_buffer, + (char *) third_parameter_buffer); break; } From b1f9c08f51682c928a78d7997d279af5e4c7734c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 08:11:36 -1000 Subject: [PATCH 204/302] [esp32_ble_tracker] Make start_scan action idempotent (#12864) --- esphome/components/esp32_ble_tracker/automation.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/esphome/components/esp32_ble_tracker/automation.h b/esphome/components/esp32_ble_tracker/automation.h index bbf7992fa4..6d26040ccb 100644 --- a/esphome/components/esp32_ble_tracker/automation.h +++ b/esphome/components/esp32_ble_tracker/automation.h @@ -98,7 +98,13 @@ template class ESP32BLEStartScanAction : public Action { TEMPLATABLE_VALUE(bool, continuous) void play(const Ts &...x) override { this->parent_->set_scan_continuous(this->continuous_.value(x...)); - this->parent_->start_scan(); + // Only call start_scan() if scanner is IDLE + // For other states (STARTING, RUNNING, STOPPING, FAILED), the normal state + // machine flow will eventually transition back to IDLE, at which point + // loop() will see scan_continuous_ and restart scanning if it is true. + if (this->parent_->get_scanner_state() == ScannerState::IDLE) { + this->parent_->start_scan(); + } } protected: From 8a4ee19c0b99fadde31e66ff577378c19121e567 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 08:26:19 -1000 Subject: [PATCH 205/302] [es8388] Combine log statements to reduce loop blocking (#12882) --- esphome/components/es8388/es8388.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/esphome/components/es8388/es8388.cpp b/esphome/components/es8388/es8388.cpp index 5abe7a5e5f..d1834e7043 100644 --- a/esphome/components/es8388/es8388.cpp +++ b/esphome/components/es8388/es8388.cpp @@ -210,9 +210,11 @@ bool ES8388::set_dac_output(DacOutputLine line) { return false; }; - ESP_LOGV(TAG, "Setting ES8388_DACPOWER to 0x%02X", dac_power); - ESP_LOGV(TAG, "Setting ES8388_DACCONTROL24 / ES8388_DACCONTROL25 to 0x%02X", reg_out1); - ESP_LOGV(TAG, "Setting ES8388_DACCONTROL26 / ES8388_DACCONTROL27 to 0x%02X", reg_out2); + ESP_LOGV(TAG, + "Setting ES8388_DACPOWER to 0x%02X\n" + "Setting ES8388_DACCONTROL24 / ES8388_DACCONTROL25 to 0x%02X\n" + "Setting ES8388_DACCONTROL26 / ES8388_DACCONTROL27 to 0x%02X", + dac_power, reg_out1, reg_out2); ES8388_ERROR_CHECK(this->write_byte(ES8388_DACCONTROL24, reg_out1)); // LOUT1VOL ES8388_ERROR_CHECK(this->write_byte(ES8388_DACCONTROL25, reg_out1)); // ROUT1VOL From 766826cc9cc12732b289edfb8b34e0f226e2ef93 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 08:28:01 -1000 Subject: [PATCH 206/302] [esp32][libretiny] Reuse preference buffer to avoid heap churn (#12890) --- esphome/components/esp32/preferences.cpp | 6 ++++-- esphome/components/libretiny/preferences.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/esphome/components/esp32/preferences.cpp b/esphome/components/esp32/preferences.cpp index 5e1e8734e5..08439746b6 100644 --- a/esphome/components/esp32/preferences.cpp +++ b/esphome/components/esp32/preferences.cpp @@ -23,9 +23,11 @@ struct NVSData { size_t len; void set_data(const uint8_t *src, size_t size) { - this->data = std::make_unique(size); + if (!this->data || this->len != size) { + this->data = std::make_unique(size); + this->len = size; + } memcpy(this->data.get(), src, size); - this->len = size; } }; diff --git a/esphome/components/libretiny/preferences.cpp b/esphome/components/libretiny/preferences.cpp index e47e88c6f3..68bc279767 100644 --- a/esphome/components/libretiny/preferences.cpp +++ b/esphome/components/libretiny/preferences.cpp @@ -22,9 +22,11 @@ struct NVSData { size_t len; void set_data(const uint8_t *src, size_t size) { - this->data = std::make_unique(size); + if (!this->data || this->len != size) { + this->data = std::make_unique(size); + this->len = size; + } memcpy(this->data.get(), src, size); - this->len = size; } }; From 1e70091a27f8c6ea45da8cf2586359823d7679e2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 08:28:17 -1000 Subject: [PATCH 207/302] [esp32_hosted] Combine log statements to reduce loop blocking (#12884) --- .../esp32_hosted/update/esp32_hosted_update.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/esphome/components/esp32_hosted/update/esp32_hosted_update.cpp b/esphome/components/esp32_hosted/update/esp32_hosted_update.cpp index de130ca71f..626bda3af3 100644 --- a/esphome/components/esp32_hosted/update/esp32_hosted_update.cpp +++ b/esphome/components/esp32_hosted/update/esp32_hosted_update.cpp @@ -41,11 +41,13 @@ void Esp32HostedUpdate::setup() { if (this->firmware_size_ >= app_desc_offset + sizeof(esp_app_desc_t)) { esp_app_desc_t *app_desc = (esp_app_desc_t *) (this->firmware_data_ + app_desc_offset); if (app_desc->magic_word == ESP_APP_DESC_MAGIC_WORD) { - ESP_LOGD(TAG, "Firmware version: %s", app_desc->version); - ESP_LOGD(TAG, "Project name: %s", app_desc->project_name); - ESP_LOGD(TAG, "Build date: %s", app_desc->date); - ESP_LOGD(TAG, "Build time: %s", app_desc->time); - ESP_LOGD(TAG, "IDF version: %s", app_desc->idf_ver); + ESP_LOGD(TAG, + "Firmware version: %s\n" + "Project name: %s\n" + "Build date: %s\n" + "Build time: %s\n" + "IDF version: %s", + app_desc->version, app_desc->project_name, app_desc->date, app_desc->time, app_desc->idf_ver); this->update_info_.latest_version = app_desc->version; if (this->update_info_.latest_version != this->update_info_.current_version) { this->state_ = update::UPDATE_STATE_AVAILABLE; From cf513975f3a4ea61c546f8ca5040aeb4a062f9ea Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 08:30:45 -1000 Subject: [PATCH 208/302] [ens160_base] Combine log statements to reduce loop blocking (#12880) --- esphome/components/ens160_base/ens160_base.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/esphome/components/ens160_base/ens160_base.cpp b/esphome/components/ens160_base/ens160_base.cpp index 6ffaac9588..785b053f04 100644 --- a/esphome/components/ens160_base/ens160_base.cpp +++ b/esphome/components/ens160_base/ens160_base.cpp @@ -151,14 +151,16 @@ void ENS160Component::update() { } // verbose status logging - ESP_LOGV(TAG, "Status: ENS160 STATAS bit 0x%x", - (ENS160_DATA_STATUS_STATAS & (status_value)) == ENS160_DATA_STATUS_STATAS); - ESP_LOGV(TAG, "Status: ENS160 STATER bit 0x%x", - (ENS160_DATA_STATUS_STATER & (status_value)) == ENS160_DATA_STATUS_STATER); - ESP_LOGV(TAG, "Status: ENS160 VALIDITY FLAG 0x%02x", (ENS160_DATA_STATUS_VALIDITY & status_value) >> 2); - ESP_LOGV(TAG, "Status: ENS160 NEWDAT bit 0x%x", - (ENS160_DATA_STATUS_NEWDAT & (status_value)) == ENS160_DATA_STATUS_NEWDAT); - ESP_LOGV(TAG, "Status: ENS160 NEWGPR bit 0x%x", + ESP_LOGV(TAG, + "Status: ENS160 STATAS bit 0x%x\n" + "Status: ENS160 STATER bit 0x%x\n" + "Status: ENS160 VALIDITY FLAG 0x%02x\n" + "Status: ENS160 NEWDAT bit 0x%x\n" + "Status: ENS160 NEWGPR bit 0x%x", + (ENS160_DATA_STATUS_STATAS & (status_value)) == ENS160_DATA_STATUS_STATAS, + (ENS160_DATA_STATUS_STATER & (status_value)) == ENS160_DATA_STATUS_STATER, + (ENS160_DATA_STATUS_VALIDITY & status_value) >> 2, + (ENS160_DATA_STATUS_NEWDAT & (status_value)) == ENS160_DATA_STATUS_NEWDAT, (ENS160_DATA_STATUS_NEWGPR & (status_value)) == ENS160_DATA_STATUS_NEWGPR); data_ready = ENS160_DATA_STATUS_NEWDAT & status_value; From 9e5dbb073a6015f45c7eaf07f15d69f79be27716 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 08:31:14 -1000 Subject: [PATCH 209/302] [emmeti] Combine log statements to reduce loop blocking (#12878) --- esphome/components/emmeti/emmeti.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/esphome/components/emmeti/emmeti.cpp b/esphome/components/emmeti/emmeti.cpp index 3cb184f868..5286f962b8 100644 --- a/esphome/components/emmeti/emmeti.cpp +++ b/esphome/components/emmeti/emmeti.cpp @@ -153,8 +153,10 @@ void EmmetiClimate::reverse_add_(T val, size_t len, esphome::remote_base::Remote bool EmmetiClimate::check_checksum_(uint8_t checksum) { uint8_t expected = this->gen_checksum_(); - ESP_LOGV(TAG, "Expected checksum: %X", expected); - ESP_LOGV(TAG, "Checksum received: %X", checksum); + ESP_LOGV(TAG, + "Expected checksum: %X\n" + "Checksum received: %X", + expected, checksum); return checksum == expected; } @@ -264,8 +266,10 @@ bool EmmetiClimate::on_receive(remote_base::RemoteReceiveData data) { } } - ESP_LOGD(TAG, "Swing: %d", (curr_state.bitmap >> 1) & 0x01); - ESP_LOGD(TAG, "Sleep: %d", (curr_state.bitmap >> 2) & 0x01); + ESP_LOGD(TAG, + "Swing: %d\n" + "Sleep: %d", + (curr_state.bitmap >> 1) & 0x01, (curr_state.bitmap >> 2) & 0x01); for (size_t pos = 0; pos < 4; pos++) { if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) { @@ -291,10 +295,13 @@ bool EmmetiClimate::on_receive(remote_base::RemoteReceiveData data) { } } - ESP_LOGD(TAG, "Turbo: %d", (curr_state.bitmap >> 3) & 0x01); - ESP_LOGD(TAG, "Light: %d", (curr_state.bitmap >> 4) & 0x01); - ESP_LOGD(TAG, "Tree: %d", (curr_state.bitmap >> 5) & 0x01); - ESP_LOGD(TAG, "Blow: %d", (curr_state.bitmap >> 6) & 0x01); + ESP_LOGD(TAG, + "Turbo: %d\n" + "Light: %d\n" + "Tree: %d\n" + "Blow: %d", + (curr_state.bitmap >> 3) & 0x01, (curr_state.bitmap >> 4) & 0x01, (curr_state.bitmap >> 5) & 0x01, + (curr_state.bitmap >> 6) & 0x01); uint16_t control_data = 0; for (size_t pos = 0; pos < 11; pos++) { From a6db5a2ed836d643a6e47cb8e12422e5c54e20a4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 08:33:38 -1000 Subject: [PATCH 210/302] [dfrobot_sen0395] Combine log statements to reduce loop blocking (#12876) --- esphome/components/dfrobot_sen0395/commands.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/esphome/components/dfrobot_sen0395/commands.cpp b/esphome/components/dfrobot_sen0395/commands.cpp index 42074c80cf..8bb6ddf942 100644 --- a/esphome/components/dfrobot_sen0395/commands.cpp +++ b/esphome/components/dfrobot_sen0395/commands.cpp @@ -179,8 +179,10 @@ uint8_t DetRangeCfgCommand::on_message(std::string &message) { ESP_LOGE(TAG, "Cannot configure range config. Sensor is not stopped!"); return 1; // Command done } else if (message == "Done") { - ESP_LOGI(TAG, "Updated detection area config:"); - ESP_LOGI(TAG, "Detection area 1 from %.02fm to %.02fm.", this->min1_, this->max1_); + ESP_LOGI(TAG, + "Updated detection area config:\n" + "Detection area 1 from %.02fm to %.02fm.", + this->min1_, this->max1_); if (this->min2_ >= 0 && this->max2_ >= 0) { ESP_LOGI(TAG, "Detection area 2 from %.02fm to %.02fm.", this->min2_, this->max2_); } @@ -209,9 +211,11 @@ uint8_t SetLatencyCommand::on_message(std::string &message) { ESP_LOGE(TAG, "Cannot configure output latency. Sensor is not stopped!"); return 1; // Command done } else if (message == "Done") { - ESP_LOGI(TAG, "Updated output latency config:"); - ESP_LOGI(TAG, "Signal that someone was detected is delayed by %.03f s.", this->delay_after_detection_); - ESP_LOGI(TAG, "Signal that nobody is detected anymore is delayed by %.03f s.", this->delay_after_disappear_); + ESP_LOGI(TAG, + "Updated output latency config:\n" + "Signal that someone was detected is delayed by %.03f s.\n" + "Signal that nobody is detected anymore is delayed by %.03f s.", + this->delay_after_detection_, this->delay_after_disappear_); ESP_LOGD(TAG, "Used command: %s", this->cmd_.c_str()); return 1; // Command done } From 25a325da617c4df23999d91ead7f805d2f7a6ffd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 08:33:49 -1000 Subject: [PATCH 211/302] [current_based] Combine log statements to reduce loop blocking (#12873) --- esphome/components/current_based/current_based_cover.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/current_based/current_based_cover.cpp b/esphome/components/current_based/current_based_cover.cpp index 895b5515cb..cb3f65c9cd 100644 --- a/esphome/components/current_based/current_based_cover.cpp +++ b/esphome/components/current_based/current_based_cover.cpp @@ -146,8 +146,10 @@ void CurrentBasedCover::dump_config() { if (this->close_obstacle_current_threshold_ != FLT_MAX) { ESP_LOGCONFIG(TAG, " Close obstacle current threshold: %.11fA", this->close_obstacle_current_threshold_); } - ESP_LOGCONFIG(TAG, " Close Duration: %.1fs", this->close_duration_ / 1e3f); - ESP_LOGCONFIG(TAG, "Obstacle Rollback: %.1f%%", this->obstacle_rollback_ * 100); + ESP_LOGCONFIG(TAG, + " Close Duration: %.1fs\n" + "Obstacle Rollback: %.1f%%", + this->close_duration_ / 1e3f, this->obstacle_rollback_ * 100); if (this->max_duration_ != UINT32_MAX) { ESP_LOGCONFIG(TAG, "Maximum duration: %.1fs", this->max_duration_ / 1e3f); } From 5a8b0f59b88651b2ec32c1bb08417001eea405f9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 08:33:58 -1000 Subject: [PATCH 212/302] [cd74hc4067] Combine log statements to reduce loop blocking (#12870) --- esphome/components/cd74hc4067/cd74hc4067.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/cd74hc4067/cd74hc4067.cpp b/esphome/components/cd74hc4067/cd74hc4067.cpp index 174dc676f9..4293d7af07 100644 --- a/esphome/components/cd74hc4067/cd74hc4067.cpp +++ b/esphome/components/cd74hc4067/cd74hc4067.cpp @@ -21,12 +21,14 @@ void CD74HC4067Component::setup() { } void CD74HC4067Component::dump_config() { - ESP_LOGCONFIG(TAG, "CD74HC4067 Multiplexer:"); + ESP_LOGCONFIG(TAG, + "CD74HC4067 Multiplexer:\n" + " switch delay: %" PRIu32, + this->switch_delay_); LOG_PIN(" S0 Pin: ", this->pin_s0_); LOG_PIN(" S1 Pin: ", this->pin_s1_); LOG_PIN(" S2 Pin: ", this->pin_s2_); LOG_PIN(" S3 Pin: ", this->pin_s3_); - ESP_LOGCONFIG(TAG, "switch delay: %" PRIu32, this->switch_delay_); } void CD74HC4067Component::activate_pin(uint8_t pin) { From dff8dc0ed1e325556d84a08d95aa3778eb248324 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 08:34:07 -1000 Subject: [PATCH 213/302] [cc1101] Combine log statements to reduce loop blocking (#12869) --- esphome/components/cc1101/cc1101.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/cc1101/cc1101.cpp b/esphome/components/cc1101/cc1101.cpp index 7e5309e165..10f72018f9 100644 --- a/esphome/components/cc1101/cc1101.cpp +++ b/esphome/components/cc1101/cc1101.cpp @@ -212,9 +212,8 @@ void CC1101Component::dump_config() { XTAL_FREQUENCY / (1 << 16); float symbol_rate = (((256.0f + this->state_.DRATE_M) * (1 << this->state_.DRATE_E)) / (1 << 28)) * XTAL_FREQUENCY; float bw = XTAL_FREQUENCY / (8.0f * (4 + this->state_.CHANBW_M) * (1 << this->state_.CHANBW_E)); - ESP_LOGCONFIG(TAG, "CC1101:"); - LOG_PIN(" CS Pin: ", this->cs_); ESP_LOGCONFIG(TAG, + "CC1101:\n" " Chip ID: 0x%04X\n" " Frequency: %" PRId32 " Hz\n" " Channel: %u\n" @@ -224,6 +223,7 @@ void CC1101Component::dump_config() { " Output Power: %.1f dBm", this->chip_id_, freq, this->state_.CHANNR, MODULATION_NAMES[this->state_.MOD_FORMAT & 0x07], symbol_rate, bw, this->output_power_effective_); + LOG_PIN(" CS Pin: ", this->cs_); } void CC1101Component::begin_tx() { From 77b3ffee001305d85cd79ab89268c9757a9db8e7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 08:34:16 -1000 Subject: [PATCH 214/302] [factory_reset] Combine log statements to reduce loop blocking (#12866) --- esphome/components/factory_reset/factory_reset.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/factory_reset/factory_reset.cpp b/esphome/components/factory_reset/factory_reset.cpp index bbbe399148..2e3f802343 100644 --- a/esphome/components/factory_reset/factory_reset.cpp +++ b/esphome/components/factory_reset/factory_reset.cpp @@ -30,8 +30,8 @@ static bool was_power_cycled() { void FactoryResetComponent::dump_config() { uint8_t count = 0; this->flash_.load(&count); - ESP_LOGCONFIG(TAG, "Factory Reset by Reset:"); ESP_LOGCONFIG(TAG, + "Factory Reset by Reset:\n" " Max interval between resets: %u seconds\n" " Current count: %u\n" " Factory reset after %u resets", From 9ae19d53dca62ed83f2630672e208480bbe7ab35 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Sun, 4 Jan 2026 13:39:56 -0500 Subject: [PATCH 215/302] [ultrasonic] Fix timeout issues and deprecate timeout option (#12897) Co-authored-by: Claude --- esphome/components/ultrasonic/sensor.py | 14 ++++++++++++-- .../components/ultrasonic/ultrasonic_sensor.cpp | 17 +++++------------ .../components/ultrasonic/ultrasonic_sensor.h | 4 ---- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/esphome/components/ultrasonic/sensor.py b/esphome/components/ultrasonic/sensor.py index d341acb9d1..4b04ee7578 100644 --- a/esphome/components/ultrasonic/sensor.py +++ b/esphome/components/ultrasonic/sensor.py @@ -1,3 +1,5 @@ +import logging + from esphome import pins import esphome.codegen as cg from esphome.components import sensor @@ -11,6 +13,8 @@ from esphome.const import ( UNIT_METER, ) +_LOGGER = logging.getLogger(__name__) + CONF_PULSE_TIME = "pulse_time" ultrasonic_ns = cg.esphome_ns.namespace("ultrasonic") @@ -30,7 +34,7 @@ CONFIG_SCHEMA = ( { cv.Required(CONF_TRIGGER_PIN): pins.internal_gpio_output_pin_schema, cv.Required(CONF_ECHO_PIN): pins.internal_gpio_input_pin_schema, - cv.Optional(CONF_TIMEOUT, default="2m"): cv.distance, + cv.Optional(CONF_TIMEOUT): cv.distance, cv.Optional( CONF_PULSE_TIME, default="10us" ): cv.positive_time_period_microseconds, @@ -49,5 +53,11 @@ async def to_code(config): echo = await cg.gpio_pin_expression(config[CONF_ECHO_PIN]) cg.add(var.set_echo_pin(echo)) - cg.add(var.set_timeout_us(config[CONF_TIMEOUT] / (0.000343 / 2))) + # Remove before 2026.8.0 + if CONF_TIMEOUT in config: + _LOGGER.warning( + "'timeout' option is deprecated and will be removed in 2026.8.0. " + "The option has no effect and can be safely removed." + ) + cg.add(var.set_pulse_time_us(config[CONF_PULSE_TIME])) diff --git a/esphome/components/ultrasonic/ultrasonic_sensor.cpp b/esphome/components/ultrasonic/ultrasonic_sensor.cpp index 184d93f189..369a10edbd 100644 --- a/esphome/components/ultrasonic/ultrasonic_sensor.cpp +++ b/esphome/components/ultrasonic/ultrasonic_sensor.cpp @@ -6,8 +6,8 @@ namespace esphome::ultrasonic { static const char *const TAG = "ultrasonic.sensor"; -static constexpr uint32_t DEBOUNCE_US = 50; // Ignore edges within 50us (noise filtering) -static constexpr uint32_t TIMEOUT_MARGIN_US = 1000; // Extra margin for sensor processing time +static constexpr uint32_t DEBOUNCE_US = 50; // Ignore edges within 50us (noise filtering) +static constexpr uint32_t MEASUREMENT_TIMEOUT_US = 80000; // Maximum time to wait for measurement completion void IRAM_ATTR UltrasonicSensorStore::gpio_intr(UltrasonicSensorStore *arg) { uint32_t now = micros(); @@ -64,12 +64,8 @@ void UltrasonicSensorComponent::loop() { } uint32_t elapsed = micros() - this->measurement_start_us_; - if (elapsed >= this->timeout_us_ + TIMEOUT_MARGIN_US) { - ESP_LOGD(TAG, - "'%s' - Timeout after %" PRIu32 "us (measurement_start=%" PRIu32 ", echo_start=%" PRIu32 - ", echo_end=%" PRIu32 ")", - this->name_.c_str(), elapsed, this->measurement_start_us_, this->store_.echo_start_us, - this->store_.echo_end_us); + if (elapsed >= MEASUREMENT_TIMEOUT_US) { + ESP_LOGD(TAG, "'%s' - Measurement timed out after %" PRIu32 "us", this->name_.c_str(), elapsed); this->publish_state(NAN); this->measurement_pending_ = false; } @@ -79,10 +75,7 @@ void UltrasonicSensorComponent::dump_config() { LOG_SENSOR("", "Ultrasonic Sensor", this); LOG_PIN(" Echo Pin: ", this->echo_pin_); LOG_PIN(" Trigger Pin: ", this->trigger_pin_); - ESP_LOGCONFIG(TAG, - " Pulse time: %" PRIu32 " us\n" - " Timeout: %" PRIu32 " us", - this->pulse_time_us_, this->timeout_us_); + ESP_LOGCONFIG(TAG, " Pulse time: %" PRIu32 " us", this->pulse_time_us_); LOG_UPDATE_INTERVAL(this); } diff --git a/esphome/components/ultrasonic/ultrasonic_sensor.h b/esphome/components/ultrasonic/ultrasonic_sensor.h index e2266543ce..b0c00e51f0 100644 --- a/esphome/components/ultrasonic/ultrasonic_sensor.h +++ b/esphome/components/ultrasonic/ultrasonic_sensor.h @@ -22,9 +22,6 @@ class UltrasonicSensorComponent : public sensor::Sensor, public PollingComponent void set_trigger_pin(InternalGPIOPin *trigger_pin) { this->trigger_pin_ = trigger_pin; } void set_echo_pin(InternalGPIOPin *echo_pin) { this->echo_pin_ = echo_pin; } - /// Set the timeout for waiting for the echo in µs. - void set_timeout_us(uint32_t timeout_us) { this->timeout_us_ = timeout_us; } - void setup() override; void loop() override; void dump_config() override; @@ -44,7 +41,6 @@ class UltrasonicSensorComponent : public sensor::Sensor, public PollingComponent ISRInternalGPIOPin trigger_pin_isr_; InternalGPIOPin *echo_pin_; UltrasonicSensorStore store_; - uint32_t timeout_us_{}; uint32_t pulse_time_us_{}; uint32_t measurement_start_us_{0}; From 449e478becae951c293991e713c70ab7123db93d Mon Sep 17 00:00:00 2001 From: Stuart Parmenter Date: Sun, 4 Jan 2026 12:50:10 -0800 Subject: [PATCH 216/302] [hub75] Bump esp-hub75 version to 0.2.2 (#12674) --- esphome/components/hub75/display.py | 33 +++++++++++++--- esphome/components/hub75/hub75.cpp | 19 +++++++-- esphome/components/hub75/hub75_component.h | 4 +- esphome/idf_component.yml | 2 +- .../hub75/test.esp32-s3-idf-rotate.yaml | 39 +++++++++++++++++++ 5 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 tests/components/hub75/test.esp32-s3-idf-rotate.yaml diff --git a/esphome/components/hub75/display.py b/esphome/components/hub75/display.py index 7736319330..40202e52ca 100644 --- a/esphome/components/hub75/display.py +++ b/esphome/components/hub75/display.py @@ -15,6 +15,7 @@ from esphome.const import ( CONF_ID, CONF_LAMBDA, CONF_OE_PIN, + CONF_ROTATION, CONF_UPDATE_INTERVAL, ) from esphome.core import ID @@ -134,6 +135,14 @@ CLOCK_SPEEDS = { "20MHZ": Hub75ClockSpeed.HZ_20M, } +Hub75Rotation = cg.global_ns.enum("Hub75Rotation", is_class=True) +ROTATIONS = { + 0: Hub75Rotation.ROTATE_0, + 90: Hub75Rotation.ROTATE_90, + 180: Hub75Rotation.ROTATE_180, + 270: Hub75Rotation.ROTATE_270, +} + HUB75Display = hub75_ns.class_("HUB75Display", cg.PollingComponent, display.Display) Hub75Config = cg.global_ns.struct("Hub75Config") Hub75Pins = cg.global_ns.struct("Hub75Pins") @@ -361,6 +370,8 @@ CONFIG_SCHEMA = cv.All( display.FULL_DISPLAY_SCHEMA.extend( { cv.GenerateID(): cv.declare_id(HUB75Display), + # Override rotation - store Hub75Rotation directly (driver handles rotation) + cv.Optional(CONF_ROTATION): cv.enum(ROTATIONS, int=True), # Board preset (optional - provides default pin mappings) cv.Optional(CONF_BOARD): cv.one_of(*BOARDS.keys(), lower=True), # Panel dimensions @@ -378,7 +389,7 @@ CONFIG_SCHEMA = cv.All( # Display configuration cv.Optional(CONF_DOUBLE_BUFFER): cv.boolean, cv.Optional(CONF_BRIGHTNESS): cv.int_range(min=0, max=255), - cv.Optional(CONF_BIT_DEPTH): cv.int_range(min=6, max=12), + cv.Optional(CONF_BIT_DEPTH): cv.int_range(min=4, max=12), cv.Optional(CONF_GAMMA_CORRECT): cv.enum( {"LINEAR": 0, "CIE1931": 1, "GAMMA_2_2": 2}, upper=True ), @@ -490,10 +501,11 @@ def _build_config_struct( Fields must be added in declaration order (see hub75_types.h) to satisfy C++ designated initializer requirements. The order is: 1. fields_before_pins (panel_width through layout) - 2. pins - 3. output_clock_speed - 4. min_refresh_rate - 5. fields_after_min_refresh (latch_blanking through brightness) + 2. rotation + 3. pins + 4. output_clock_speed + 5. min_refresh_rate + 6. fields_after_min_refresh (latch_blanking through brightness) """ fields_before_pins = [ (CONF_PANEL_WIDTH, "panel_width"), @@ -516,6 +528,10 @@ def _build_config_struct( _append_config_fields(config, fields_before_pins, config_fields) + # Rotation - config already contains Hub75Rotation enum from cv.enum + if CONF_ROTATION in config: + config_fields.append(("rotation", config[CONF_ROTATION])) + config_fields.append(("pins", pins_struct)) if CONF_CLOCK_SPEED in config: @@ -531,7 +547,7 @@ def _build_config_struct( async def to_code(config: ConfigType) -> None: add_idf_component( name="esphome/esp-hub75", - ref="0.1.7", + ref="0.2.2", ) # Set compile-time configuration via defines @@ -570,6 +586,11 @@ async def to_code(config: ConfigType) -> None: pins_struct = _build_pins_struct(pin_expressions, e_pin_num) hub75_config = _build_config_struct(config, pins_struct, min_refresh) + # Rotation is handled by the hub75 driver (config_.rotation already set above). + # Force rotation to 0 for ESPHome's Display base class to avoid double-rotation. + if CONF_ROTATION in config: + config[CONF_ROTATION] = 0 + # Create display and register var = cg.new_Pvariable(config[CONF_ID], hub75_config) await display.register_display(var, config) diff --git a/esphome/components/hub75/hub75.cpp b/esphome/components/hub75/hub75.cpp index e29f1a898c..cf8661b2b3 100644 --- a/esphome/components/hub75/hub75.cpp +++ b/esphome/components/hub75/hub75.cpp @@ -92,14 +92,25 @@ void HUB75Display::fill(Color color) { if (!this->enabled_) [[unlikely]] return; - // Special case: black (off) - use fast hardware clear - if (!color.is_on()) { + // Start with full display rect + display::Rect fill_rect(0, 0, this->get_width_internal(), this->get_height_internal()); + + // Apply clipping using Rect::shrink() to intersect + display::Rect clip = this->get_clipping(); + if (clip.is_set()) { + fill_rect.shrink(clip); + if (!fill_rect.is_set()) + return; // Completely clipped + } + + // Fast path: black filling entire display + if (!color.is_on() && fill_rect.x == 0 && fill_rect.y == 0 && fill_rect.w == this->get_width_internal() && + fill_rect.h == this->get_height_internal()) { driver_->clear(); return; } - // For non-black colors, fall back to base class (pixel-by-pixel) - Display::fill(color); + driver_->fill(fill_rect.x, fill_rect.y, fill_rect.w, fill_rect.h, color.r, color.g, color.b); } void HOT HUB75Display::draw_pixel_at(int x, int y, Color color) { diff --git a/esphome/components/hub75/hub75_component.h b/esphome/components/hub75/hub75_component.h index f0e7ea10d5..ab7e3fc5b1 100644 --- a/esphome/components/hub75/hub75_component.h +++ b/esphome/components/hub75/hub75_component.h @@ -39,8 +39,8 @@ class HUB75Display : public display::Display { protected: // Display internal methods - int get_width_internal() override { return config_.panel_width * config_.layout_cols; } - int get_height_internal() override { return config_.panel_height * config_.layout_rows; } + int get_width_internal() override { return this->driver_ != nullptr ? this->driver_->get_width() : 0; } + int get_height_internal() override { return this->driver_ != nullptr ? this->driver_->get_height() : 0; } // Member variables Hub75Driver *driver_{nullptr}; diff --git a/esphome/idf_component.yml b/esphome/idf_component.yml index 4573391bc1..36aa77c524 100644 --- a/esphome/idf_component.yml +++ b/esphome/idf_component.yml @@ -28,6 +28,6 @@ dependencies: rules: - if: "target in [esp32s2, esp32s3, esp32p4]" esphome/esp-hub75: - version: 0.1.7 + version: 0.2.2 rules: - if: "target in [esp32, esp32s2, esp32s3, esp32p4]" diff --git a/tests/components/hub75/test.esp32-s3-idf-rotate.yaml b/tests/components/hub75/test.esp32-s3-idf-rotate.yaml new file mode 100644 index 0000000000..9855fcb4e6 --- /dev/null +++ b/tests/components/hub75/test.esp32-s3-idf-rotate.yaml @@ -0,0 +1,39 @@ +display: + - platform: hub75 + id: my_hub75 + board: apollo-automation-rev6 + panel_width: 64 + panel_height: 64 + layout_rows: 1 + layout_cols: 2 + rotation: 90 + bit_depth: 4 + double_buffer: true + auto_clear_enabled: true + update_interval: 16ms + latch_blanking: 1 + clock_speed: 20MHz + lambda: |- + // Test clipping: 8 columns x 4 rows of 16x16 colored squares + Color colors[32] = { + Color(255, 0, 0), Color(0, 255, 0), Color(0, 0, 255), Color(255, 255, 0), + Color(255, 0, 255), Color(0, 255, 255), Color(255, 128, 0), Color(128, 0, 255), + Color(0, 128, 255), Color(255, 0, 128), Color(128, 255, 0), Color(0, 255, 128), + Color(255, 128, 128), Color(128, 255, 128), Color(128, 128, 255), Color(255, 255, 128), + Color(255, 128, 255), Color(128, 255, 255), Color(192, 64, 0), Color(64, 192, 0), + Color(0, 64, 192), Color(192, 0, 64), Color(64, 0, 192), Color(0, 192, 64), + Color(128, 64, 64), Color(64, 128, 64), Color(64, 64, 128), Color(128, 128, 64), + Color(128, 64, 128), Color(64, 128, 128), Color(255, 255, 255), Color(128, 128, 128) + }; + int idx = 0; + for (int row = 0; row < 4; row++) { + for (int col = 0; col < 8; col++) { + // Clipping mode: clip to square bounds, then fill "entire screen" + it.start_clipping(col * 16, row * 16, (col + 1) * 16, (row + 1) * 16); + it.fill(colors[idx]); + it.end_clipping(); + idx++; + } + } + +<<: !include common.yaml From dd8259b2ce5fa2f45571bb69c2059a38e7637cd2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:24:36 -1000 Subject: [PATCH 217/302] [gcja5] Combine log statements to reduce loop blocking (#12898) --- esphome/components/gcja5/gcja5.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/esphome/components/gcja5/gcja5.cpp b/esphome/components/gcja5/gcja5.cpp index a7342bc828..f7f7f8d02c 100644 --- a/esphome/components/gcja5/gcja5.cpp +++ b/esphome/components/gcja5/gcja5.cpp @@ -95,11 +95,13 @@ void GCJA5Component::parse_data_() { if (!this->first_status_log_) { this->first_status_log_ = true; - ESP_LOGI(TAG, "GCJA5 Status"); - ESP_LOGI(TAG, "Overall Status : %i", (status >> 6) & 0x03); - ESP_LOGI(TAG, "PD Status : %i", (status >> 4) & 0x03); - ESP_LOGI(TAG, "LD Status : %i", (status >> 2) & 0x03); - ESP_LOGI(TAG, "Fan Status : %i", (status >> 0) & 0x03); + ESP_LOGI(TAG, + "GCJA5 Status\n" + "Overall Status : %i\n" + "PD Status : %i\n" + "LD Status : %i\n" + "Fan Status : %i", + (status >> 6) & 0x03, (status >> 4) & 0x03, (status >> 2) & 0x03, (status >> 0) & 0x03); } } From 8287484a36880b45fdf88e8bbabd931cd1ad5e7d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:24:51 -1000 Subject: [PATCH 218/302] [gl_r01_i2c] Combine log statements to reduce loop blocking (#12899) --- esphome/components/gl_r01_i2c/gl_r01_i2c.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/gl_r01_i2c/gl_r01_i2c.cpp b/esphome/components/gl_r01_i2c/gl_r01_i2c.cpp index e2a64b6877..38328c4b03 100644 --- a/esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +++ b/esphome/components/gl_r01_i2c/gl_r01_i2c.cpp @@ -27,8 +27,10 @@ void GLR01I2CComponent::setup() { } void GLR01I2CComponent::dump_config() { - ESP_LOGCONFIG(TAG, "GL-R01 I2C:"); - ESP_LOGCONFIG(TAG, " Firmware Version: 0x%04X", this->version_); + ESP_LOGCONFIG(TAG, + "GL-R01 I2C:\n" + " Firmware Version: 0x%04X", + this->version_); LOG_I2C_DEVICE(this); LOG_SENSOR(" ", "Distance", this); } From 7e758260647761466a9c357fd726080c6a1df534 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:25:24 -1000 Subject: [PATCH 219/302] [wifi] Fix LibreTiny thread safety with queue-based event handling (#12833) --- esphome/components/wifi/wifi_component.h | 5 + .../wifi/wifi_component_libretiny.cpp | 288 +++++++++++++++--- 2 files changed, 248 insertions(+), 45 deletions(-) diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 5bf1f444e8..1906b672b8 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -245,6 +245,10 @@ enum WifiMinAuthMode : uint8_t { struct IDFWiFiEvent; #endif +#ifdef USE_LIBRETINY +struct LTWiFiEvent; +#endif + /** Listener interface for WiFi IP state changes. * * Components can implement this interface to receive IP address updates @@ -583,6 +587,7 @@ class WiFiComponent : public Component { #ifdef USE_LIBRETINY void wifi_event_callback_(arduino_event_id_t event, arduino_event_info_t info); + void wifi_process_event_(LTWiFiEvent *event); void wifi_scan_done_callback_(); #endif diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index 9bbd319f33..e9ccb86871 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -3,12 +3,16 @@ #ifdef USE_WIFI #ifdef USE_LIBRETINY +#include #include #include #include "lwip/ip_addr.h" #include "lwip/err.h" #include "lwip/dns.h" +#include +#include + #include "esphome/core/application.h" #include "esphome/core/hal.h" #include "esphome/core/helpers.h" @@ -19,7 +23,68 @@ namespace esphome::wifi { static const char *const TAG = "wifi_lt"; -static bool s_sta_connecting = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +// Thread-safe event handling for LibreTiny WiFi +// +// LibreTiny's WiFi.onEvent() callback runs in the WiFi driver's thread context, +// not the main ESPHome loop. Without synchronization, modifying shared state +// (like connection status flags) from the callback causes race conditions: +// - The main loop may never see state changes (values cached in registers) +// - State changes may be visible in inconsistent order +// - LibreTiny targets (BK7231, RTL8720) lack atomic instructions (no LDREX/STREX) +// +// Solution: Queue events in the callback and process them in the main loop. +// This is the same approach used by ESP32 IDF's wifi_process_event_(). +// All state modifications happen in the main loop context, eliminating races. + +static constexpr size_t EVENT_QUEUE_SIZE = 16; // Max pending WiFi events before overflow +static QueueHandle_t s_event_queue = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +static volatile uint32_t s_event_queue_overflow_count = + 0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + +// Event structure for queued WiFi events - contains a copy of event data +// to avoid lifetime issues with the original event data from the callback +struct LTWiFiEvent { + arduino_event_id_t event_id; + union { + struct { + uint8_t ssid[33]; + uint8_t ssid_len; + uint8_t bssid[6]; + uint8_t channel; + uint8_t authmode; + } sta_connected; + struct { + uint8_t ssid[33]; + uint8_t ssid_len; + uint8_t bssid[6]; + uint8_t reason; + } sta_disconnected; + struct { + uint8_t old_mode; + uint8_t new_mode; + } sta_authmode_change; + struct { + uint32_t status; + uint8_t number; + uint8_t scan_id; + } scan_done; + struct { + uint8_t mac[6]; + int rssi; + } ap_probe_req; + } data; +}; + +// Connection state machine - only modified from main loop after queue processing +enum class LTWiFiSTAState : uint8_t { + IDLE, // Not connecting + CONNECTING, // Connection in progress + CONNECTED, // Successfully connected with IP + ERROR_NOT_FOUND, // AP not found (probe failed) + ERROR_FAILED, // Connection failed (auth, timeout, etc.) +}; + +static LTWiFiSTAState s_sta_state = LTWiFiSTAState::IDLE; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) bool WiFiComponent::wifi_mode_(optional sta, optional ap) { uint8_t current_mode = WiFi.getMode(); @@ -136,7 +201,8 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) { this->wifi_apply_hostname_(); - s_sta_connecting = true; + // Reset state machine before connecting + s_sta_state = LTWiFiSTAState::CONNECTING; WiFiStatus status = WiFi.begin(ap.get_ssid().c_str(), ap.get_password().empty() ? NULL : ap.get_password().c_str(), ap.get_channel(), // 0 = auto @@ -271,16 +337,101 @@ const char *get_disconnect_reason_str(uint8_t reason) { using esphome_wifi_event_id_t = arduino_event_id_t; using esphome_wifi_event_info_t = arduino_event_info_t; +// Event callback - runs in WiFi driver thread context +// Only queues events for processing in main loop, no logging or state changes here void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_wifi_event_info_t info) { + if (s_event_queue == nullptr) { + return; + } + + // Allocate on heap and fill directly to avoid extra memcpy + auto *to_send = new LTWiFiEvent{}; // NOLINT(cppcoreguidelines-owning-memory) + to_send->event_id = event; + + // Copy event-specific data switch (event) { + case ESPHOME_EVENT_ID_WIFI_STA_CONNECTED: { + auto &it = info.wifi_sta_connected; + to_send->data.sta_connected.ssid_len = it.ssid_len; + memcpy(to_send->data.sta_connected.ssid, it.ssid, + std::min(static_cast(it.ssid_len), sizeof(to_send->data.sta_connected.ssid) - 1)); + memcpy(to_send->data.sta_connected.bssid, it.bssid, 6); + to_send->data.sta_connected.channel = it.channel; + to_send->data.sta_connected.authmode = it.authmode; + break; + } + case ESPHOME_EVENT_ID_WIFI_STA_DISCONNECTED: { + auto &it = info.wifi_sta_disconnected; + to_send->data.sta_disconnected.ssid_len = it.ssid_len; + memcpy(to_send->data.sta_disconnected.ssid, it.ssid, + std::min(static_cast(it.ssid_len), sizeof(to_send->data.sta_disconnected.ssid) - 1)); + memcpy(to_send->data.sta_disconnected.bssid, it.bssid, 6); + to_send->data.sta_disconnected.reason = it.reason; + break; + } + case ESPHOME_EVENT_ID_WIFI_STA_AUTHMODE_CHANGE: { + auto &it = info.wifi_sta_authmode_change; + to_send->data.sta_authmode_change.old_mode = it.old_mode; + to_send->data.sta_authmode_change.new_mode = it.new_mode; + break; + } + case ESPHOME_EVENT_ID_WIFI_SCAN_DONE: { + auto &it = info.wifi_scan_done; + to_send->data.scan_done.status = it.status; + to_send->data.scan_done.number = it.number; + to_send->data.scan_done.scan_id = it.scan_id; + break; + } + case ESPHOME_EVENT_ID_WIFI_AP_PROBEREQRECVED: { + auto &it = info.wifi_ap_probereqrecved; + memcpy(to_send->data.ap_probe_req.mac, it.mac, 6); + to_send->data.ap_probe_req.rssi = it.rssi; + break; + } + case ESPHOME_EVENT_ID_WIFI_AP_STACONNECTED: { + auto &it = info.wifi_sta_connected; + memcpy(to_send->data.sta_connected.bssid, it.bssid, 6); + break; + } + case ESPHOME_EVENT_ID_WIFI_AP_STADISCONNECTED: { + auto &it = info.wifi_sta_disconnected; + memcpy(to_send->data.sta_disconnected.bssid, it.bssid, 6); + break; + } + case ESPHOME_EVENT_ID_WIFI_READY: + case ESPHOME_EVENT_ID_WIFI_STA_START: + case ESPHOME_EVENT_ID_WIFI_STA_STOP: + case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP: + case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP6: + case ESPHOME_EVENT_ID_WIFI_STA_LOST_IP: + case ESPHOME_EVENT_ID_WIFI_AP_START: + case ESPHOME_EVENT_ID_WIFI_AP_STOP: + case ESPHOME_EVENT_ID_WIFI_AP_STAIPASSIGNED: + // No additional data needed + break; + default: + // Unknown event, don't queue + delete to_send; // NOLINT(cppcoreguidelines-owning-memory) + return; + } + + // Queue event (don't block if queue is full) + if (xQueueSend(s_event_queue, &to_send, 0) != pdPASS) { + delete to_send; // NOLINT(cppcoreguidelines-owning-memory) + s_event_queue_overflow_count++; + } +} + +// Process a single event from the queue - runs in main loop context +void WiFiComponent::wifi_process_event_(LTWiFiEvent *event) { + switch (event->event_id) { case ESPHOME_EVENT_ID_WIFI_READY: { ESP_LOGV(TAG, "Ready"); break; } case ESPHOME_EVENT_ID_WIFI_SCAN_DONE: { - auto it = info.wifi_scan_done; - ESP_LOGV(TAG, "Scan done: status=%u number=%u scan_id=%u", it.status, it.number, it.scan_id); - + auto &it = event->data.scan_done; + ESP_LOGV(TAG, "Scan done: status=%" PRIu32 " number=%u scan_id=%u", it.status, it.number, it.scan_id); this->wifi_scan_done_callback_(); break; } @@ -291,14 +442,18 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ } case ESPHOME_EVENT_ID_WIFI_STA_STOP: { ESP_LOGV(TAG, "STA stop"); - s_sta_connecting = false; + s_sta_state = LTWiFiSTAState::IDLE; break; } case ESPHOME_EVENT_ID_WIFI_STA_CONNECTED: { - auto it = info.wifi_sta_connected; + auto &it = event->data.sta_connected; + char bssid_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.bssid, bssid_buf); ESP_LOGV(TAG, "Connected ssid='%.*s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", it.ssid_len, - (const char *) it.ssid, format_mac_address_pretty(it.bssid).c_str(), it.channel, - get_auth_mode_str(it.authmode)); + (const char *) it.ssid, bssid_buf, it.channel, get_auth_mode_str(it.authmode)); + // Note: We don't set CONNECTED state here yet - wait for GOT_IP + // This matches ESP32 IDF behavior where s_sta_connected is set but + // wifi_sta_connect_status_() also checks got_ipv4_address_ #ifdef USE_WIFI_LISTENERS for (auto *listener : this->connect_state_listeners_) { listener->on_wifi_connect_state(StringRef(it.ssid, it.ssid_len), it.bssid); @@ -306,6 +461,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ // For static IP configurations, GOT_IP event may not fire, so notify IP listeners here #ifdef USE_WIFI_MANUAL_IP if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) { + s_sta_state = LTWiFiSTAState::CONNECTED; for (auto *listener : this->ip_state_listeners_) { listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1)); } @@ -315,19 +471,18 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ break; } case ESPHOME_EVENT_ID_WIFI_STA_DISCONNECTED: { - auto it = info.wifi_sta_disconnected; + auto &it = event->data.sta_disconnected; // LibreTiny can send spurious disconnect events with empty ssid/bssid during connection. // These are typically "Association Leave" events that don't indicate actual failures: // [W][wifi_lt]: Disconnected ssid='' bssid=00:00:00:00:00:00 reason='Association Leave' // [W][wifi_lt]: Disconnected ssid='' bssid=00:00:00:00:00:00 reason='Association Leave' // [V][wifi_lt]: Connected ssid='WIFI' bssid=... channel=3, authmode=WPA2 PSK - // Without this check, the spurious events set s_sta_connecting=false, causing - // wifi_sta_connect_status_() to return IDLE. The main loop then sees - // "Unknown connection status 0" (wifi_component.cpp check_connecting_finished) - // and calls retry_connect(), aborting a connection that may succeed moments later. - // Real connection failures will have ssid/bssid populated, or we'll hit the connection timeout. - if (it.ssid_len == 0 && s_sta_connecting) { + // Without this check, the spurious events would transition state to ERROR_FAILED, + // causing wifi_sta_connect_status_() to return an error. The main loop would then + // call retry_connect(), aborting a connection that may succeed moments later. + // Only ignore benign reasons - real failures like NO_AP_FOUND should still be processed. + if (it.ssid_len == 0 && s_sta_state == LTWiFiSTAState::CONNECTING && it.reason != WIFI_REASON_NO_AP_FOUND) { ESP_LOGV(TAG, "Ignoring disconnect event with empty ssid while connecting (reason=%s)", get_disconnect_reason_str(it.reason)); break; @@ -336,11 +491,13 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ if (it.reason == WIFI_REASON_NO_AP_FOUND) { ESP_LOGW(TAG, "Disconnected ssid='%.*s' reason='Probe Request Unsuccessful'", it.ssid_len, (const char *) it.ssid); + s_sta_state = LTWiFiSTAState::ERROR_NOT_FOUND; } else { - char bssid_s[18]; + char bssid_s[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; format_mac_addr_upper(it.bssid, bssid_s); ESP_LOGW(TAG, "Disconnected ssid='%.*s' bssid=" LOG_SECRET("%s") " reason='%s'", it.ssid_len, (const char *) it.ssid, bssid_s, get_disconnect_reason_str(it.reason)); + s_sta_state = LTWiFiSTAState::ERROR_FAILED; } uint8_t reason = it.reason; @@ -351,7 +508,6 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ this->error_from_callback_ = true; } - s_sta_connecting = false; #ifdef USE_WIFI_LISTENERS static constexpr uint8_t EMPTY_BSSID[6] = {}; for (auto *listener : this->connect_state_listeners_) { @@ -361,24 +517,22 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ break; } case ESPHOME_EVENT_ID_WIFI_STA_AUTHMODE_CHANGE: { - auto it = info.wifi_sta_authmode_change; + auto &it = event->data.sta_authmode_change; ESP_LOGV(TAG, "Authmode Change old=%s new=%s", get_auth_mode_str(it.old_mode), get_auth_mode_str(it.new_mode)); // Mitigate CVE-2020-12638 // https://lbsfilm.at/blog/wpa2-authenticationmode-downgrade-in-espressif-microprocessors if (it.old_mode != WIFI_AUTH_OPEN && it.new_mode == WIFI_AUTH_OPEN) { ESP_LOGW(TAG, "Potential Authmode downgrade detected, disconnecting"); - // we can't call retry_connect() from this context, so disconnect immediately - // and notify main thread with error_from_callback_ WiFi.disconnect(); this->error_from_callback_ = true; + s_sta_state = LTWiFiSTAState::ERROR_FAILED; } break; } case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP: { - // auto it = info.got_ip.ip_info; ESP_LOGV(TAG, "static_ip=%s gateway=%s", format_ip4_addr(WiFi.localIP()).c_str(), format_ip4_addr(WiFi.gatewayIP()).c_str()); - s_sta_connecting = false; + s_sta_state = LTWiFiSTAState::CONNECTED; #ifdef USE_WIFI_LISTENERS for (auto *listener : this->ip_state_listeners_) { listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1)); @@ -387,7 +541,6 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ break; } case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP6: { - // auto it = info.got_ip.ip_info; ESP_LOGV(TAG, "Got IPv6"); #ifdef USE_WIFI_LISTENERS for (auto *listener : this->ip_state_listeners_) { @@ -398,6 +551,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ } case ESPHOME_EVENT_ID_WIFI_STA_LOST_IP: { ESP_LOGV(TAG, "Lost IP"); + // Don't change state to IDLE - let the disconnect event handle that break; } case ESPHOME_EVENT_ID_WIFI_AP_START: { @@ -409,15 +563,21 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ break; } case ESPHOME_EVENT_ID_WIFI_AP_STACONNECTED: { - auto it = info.wifi_sta_connected; - auto &mac = it.bssid; - ESP_LOGV(TAG, "AP client connected MAC=%s", format_mac_address_pretty(mac).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + auto &it = event->data.sta_connected; + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.bssid, mac_buf); + ESP_LOGV(TAG, "AP client connected MAC=%s", mac_buf); +#endif break; } case ESPHOME_EVENT_ID_WIFI_AP_STADISCONNECTED: { - auto it = info.wifi_sta_disconnected; - auto &mac = it.bssid; - ESP_LOGV(TAG, "AP client disconnected MAC=%s", format_mac_address_pretty(mac).c_str()); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + auto &it = event->data.sta_disconnected; + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.bssid, mac_buf); + ESP_LOGV(TAG, "AP client disconnected MAC=%s", mac_buf); +#endif break; } case ESPHOME_EVENT_ID_WIFI_AP_STAIPASSIGNED: { @@ -425,8 +585,12 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ break; } case ESPHOME_EVENT_ID_WIFI_AP_PROBEREQRECVED: { - auto it = info.wifi_ap_probereqrecved; - ESP_LOGVV(TAG, "AP receive Probe Request MAC=%s RSSI=%d", format_mac_address_pretty(it.mac).c_str(), it.rssi); +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE + auto &it = event->data.ap_probe_req; + char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + format_mac_addr_upper(it.mac, mac_buf); + ESP_LOGVV(TAG, "AP receive Probe Request MAC=%s RSSI=%d", mac_buf, it.rssi); +#endif break; } default: @@ -434,23 +598,35 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_ } } void WiFiComponent::wifi_pre_setup_() { + // Create event queue for thread-safe event handling + // Events are pushed from WiFi callback thread and processed in main loop + s_event_queue = xQueueCreate(EVENT_QUEUE_SIZE, sizeof(LTWiFiEvent *)); + if (s_event_queue == nullptr) { + ESP_LOGE(TAG, "Failed to create event queue"); + return; + } + auto f = std::bind(&WiFiComponent::wifi_event_callback_, this, std::placeholders::_1, std::placeholders::_2); WiFi.onEvent(f); // Make sure WiFi is in clean state before anything starts this->wifi_mode_(false, false); } WiFiSTAConnectStatus WiFiComponent::wifi_sta_connect_status_() { - auto status = WiFi.status(); - if (status == WL_CONNECTED) { - return WiFiSTAConnectStatus::CONNECTED; - } else if (status == WL_CONNECT_FAILED || status == WL_CONNECTION_LOST) { - return WiFiSTAConnectStatus::ERROR_CONNECT_FAILED; - } else if (status == WL_NO_SSID_AVAIL) { - return WiFiSTAConnectStatus::ERROR_NETWORK_NOT_FOUND; - } else if (s_sta_connecting) { - return WiFiSTAConnectStatus::CONNECTING; + // Use state machine instead of querying WiFi.status() directly + // State is updated in main loop from queued events, ensuring thread safety + switch (s_sta_state) { + case LTWiFiSTAState::CONNECTED: + return WiFiSTAConnectStatus::CONNECTED; + case LTWiFiSTAState::ERROR_NOT_FOUND: + return WiFiSTAConnectStatus::ERROR_NETWORK_NOT_FOUND; + case LTWiFiSTAState::ERROR_FAILED: + return WiFiSTAConnectStatus::ERROR_CONNECT_FAILED; + case LTWiFiSTAState::CONNECTING: + return WiFiSTAConnectStatus::CONNECTING; + case LTWiFiSTAState::IDLE: + default: + return WiFiSTAConnectStatus::IDLE; } - return WiFiSTAConnectStatus::IDLE; } bool WiFiComponent::wifi_scan_start_(bool passive) { // enable STA @@ -534,9 +710,9 @@ network::IPAddress WiFiComponent::wifi_soft_ap_ip() { return {WiFi.softAPIP()}; #endif // USE_WIFI_AP bool WiFiComponent::wifi_disconnect_() { - // Clear connecting flag first so disconnect events aren't ignored + // Reset state first so disconnect events aren't ignored // and wifi_sta_connect_status_() returns IDLE instead of CONNECTING - s_sta_connecting = false; + s_sta_state = LTWiFiSTAState::IDLE; return WiFi.disconnect(); } @@ -563,7 +739,29 @@ int32_t WiFiComponent::get_wifi_channel() { return WiFi.channel(); } network::IPAddress WiFiComponent::wifi_subnet_mask_() { return {WiFi.subnetMask()}; } network::IPAddress WiFiComponent::wifi_gateway_ip_() { return {WiFi.gatewayIP()}; } network::IPAddress WiFiComponent::wifi_dns_ip_(int num) { return {WiFi.dnsIP(num)}; } -void WiFiComponent::wifi_loop_() {} +void WiFiComponent::wifi_loop_() { + // Process all pending events from the queue + if (s_event_queue == nullptr) { + return; + } + + // Check for dropped events due to queue overflow + if (s_event_queue_overflow_count > 0) { + ESP_LOGW(TAG, "Event queue overflow, %" PRIu32 " events dropped", s_event_queue_overflow_count); + s_event_queue_overflow_count = 0; + } + + while (true) { + LTWiFiEvent *event; + if (xQueueReceive(s_event_queue, &event, 0) != pdTRUE) { + // No more events + break; + } + + wifi_process_event_(event); + delete event; // NOLINT(cppcoreguidelines-owning-memory) + } +} } // namespace esphome::wifi #endif // USE_LIBRETINY From 61ecfb5f2b6421a3824e060ebbad4c35d71c1113 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:25:52 -1000 Subject: [PATCH 220/302] [openthread] Combine log statements to reduce loop blocking (#12917) --- esphome/components/openthread/openthread_esp.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/esphome/components/openthread/openthread_esp.cpp b/esphome/components/openthread/openthread_esp.cpp index 1f18e51496..a9aff3cce4 100644 --- a/esphome/components/openthread/openthread_esp.cpp +++ b/esphome/components/openthread/openthread_esp.cpp @@ -126,9 +126,12 @@ void OpenThreadComponent::ot_main() { ESP_LOGE(TAG, "Failed to set OpenThread linkmode."); } link_mode_config = otThreadGetLinkMode(esp_openthread_get_instance()); - ESP_LOGD(TAG, "Link Mode Device Type: %s", link_mode_config.mDeviceType ? "true" : "false"); - ESP_LOGD(TAG, "Link Mode Network Data: %s", link_mode_config.mNetworkData ? "true" : "false"); - ESP_LOGD(TAG, "Link Mode RX On When Idle: %s", link_mode_config.mRxOnWhenIdle ? "true" : "false"); + ESP_LOGD(TAG, + "Link Mode Device Type: %s\n" + "Link Mode Network Data: %s\n" + "Link Mode RX On When Idle: %s", + link_mode_config.mDeviceType ? "true" : "false", link_mode_config.mNetworkData ? "true" : "false", + link_mode_config.mRxOnWhenIdle ? "true" : "false"); // Run the main loop #if CONFIG_OPENTHREAD_CLI @@ -144,8 +147,8 @@ void OpenThreadComponent::ot_main() { // Make sure the length is 0 so we fallback to the configuration dataset.mLength = 0; } else { - ESP_LOGI(TAG, "Found OpenThread-managed dataset, ignoring esphome configuration"); - ESP_LOGI(TAG, "(set force_dataset: true to override)"); + ESP_LOGI(TAG, "Found OpenThread-managed dataset, ignoring esphome configuration\n" + "(set force_dataset: true to override)"); } #endif From fc9683f024e69886fd54844e77170222e476af98 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:26:13 -1000 Subject: [PATCH 221/302] [opentherm] Combine log statements to reduce loop blocking (#12916) --- esphome/components/opentherm/hub.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/opentherm/hub.cpp b/esphome/components/opentherm/hub.cpp index b23792fc7a..7a0cdc7f80 100644 --- a/esphome/components/opentherm/hub.cpp +++ b/esphome/components/opentherm/hub.cpp @@ -395,10 +395,8 @@ void OpenthermHub::dump_config() { this->write_initial_messages_(initial_messages); this->write_repeating_messages_(repeating_messages); - ESP_LOGCONFIG(TAG, "OpenTherm:"); - LOG_PIN(" In: ", this->in_pin_); - LOG_PIN(" Out: ", this->out_pin_); ESP_LOGCONFIG(TAG, + "OpenTherm:\n" " Sync mode: %s\n" " Sensors: %s\n" " Binary sensors: %s\n" @@ -409,6 +407,8 @@ void OpenthermHub::dump_config() { YESNO(this->sync_mode_), SHOW(OPENTHERM_SENSOR_LIST(ID, )), SHOW(OPENTHERM_BINARY_SENSOR_LIST(ID, )), SHOW(OPENTHERM_SWITCH_LIST(ID, )), SHOW(OPENTHERM_INPUT_SENSOR_LIST(ID, )), SHOW(OPENTHERM_OUTPUT_LIST(ID, )), SHOW(OPENTHERM_NUMBER_LIST(ID, ))); + LOG_PIN(" In: ", this->in_pin_); + LOG_PIN(" Out: ", this->out_pin_); ESP_LOGCONFIG(TAG, " Initial requests:"); for (auto type : initial_messages) { ESP_LOGCONFIG(TAG, " - %d (%s)", type, this->opentherm_->message_id_to_str(type)); From 6d9d593e12c76a799ae3b944b9262c852186e909 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:27:14 -1000 Subject: [PATCH 222/302] [my9231] Combine log statements to reduce loop blocking (#12915) --- esphome/components/my9231/my9231.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/my9231/my9231.cpp b/esphome/components/my9231/my9231.cpp index fba7ac2bf3..5b77a49e72 100644 --- a/esphome/components/my9231/my9231.cpp +++ b/esphome/components/my9231/my9231.cpp @@ -58,14 +58,14 @@ void MY9231OutputComponent::setup() { } } void MY9231OutputComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MY9231:"); - LOG_PIN(" DI Pin: ", this->pin_di_); - LOG_PIN(" DCKI Pin: ", this->pin_dcki_); ESP_LOGCONFIG(TAG, + "MY9231:\n" " Total number of channels: %u\n" " Number of chips: %u\n" " Bit depth: %u", this->num_channels_, this->num_chips_, this->bit_depth_); + LOG_PIN(" DI Pin: ", this->pin_di_); + LOG_PIN(" DCKI Pin: ", this->pin_dcki_); } void MY9231OutputComponent::loop() { if (!this->update_) From ccc9d95c9d8a66384c153d6dd2e543ab0f99214b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:28:14 -1000 Subject: [PATCH 223/302] [mqtt] Combine log statements to reduce loop blocking (#12914) --- esphome/components/mqtt/mqtt_backend_esp32.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/esphome/components/mqtt/mqtt_backend_esp32.cpp b/esphome/components/mqtt/mqtt_backend_esp32.cpp index e3105f4860..3838d6df26 100644 --- a/esphome/components/mqtt/mqtt_backend_esp32.cpp +++ b/esphome/components/mqtt/mqtt_backend_esp32.cpp @@ -166,10 +166,12 @@ void MQTTBackendESP32::mqtt_event_handler_(const Event &event) { case MQTT_EVENT_ERROR: ESP_LOGE(TAG, "MQTT_EVENT_ERROR"); if (event.error_handle.error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) { - ESP_LOGE(TAG, "Last error code reported from esp-tls: 0x%x", event.error_handle.esp_tls_last_esp_err); - ESP_LOGE(TAG, "Last tls stack error number: 0x%x", event.error_handle.esp_tls_stack_err); - ESP_LOGE(TAG, "Last captured errno : %d (%s)", event.error_handle.esp_transport_sock_errno, - strerror(event.error_handle.esp_transport_sock_errno)); + ESP_LOGE(TAG, + "Last error code reported from esp-tls: 0x%x\n" + "Last tls stack error number: 0x%x\n" + "Last captured errno : %d (%s)", + event.error_handle.esp_tls_last_esp_err, event.error_handle.esp_tls_stack_err, + event.error_handle.esp_transport_sock_errno, strerror(event.error_handle.esp_transport_sock_errno)); } else if (event.error_handle.error_type == MQTT_ERROR_TYPE_CONNECTION_REFUSED) { ESP_LOGE(TAG, "Connection refused error: 0x%x", event.error_handle.connect_return_code); } else { From d1d5c942ec81a7dc8d2cb1f2566faf1253ce2423 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:51:01 -1000 Subject: [PATCH 224/302] [mcp9600] Combine log statements to reduce loop blocking (#12913) --- esphome/components/mcp9600/mcp9600.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/mcp9600/mcp9600.cpp b/esphome/components/mcp9600/mcp9600.cpp index e1a88988c4..ff411bef7a 100644 --- a/esphome/components/mcp9600/mcp9600.cpp +++ b/esphome/components/mcp9600/mcp9600.cpp @@ -63,12 +63,12 @@ void MCP9600Component::setup() { } void MCP9600Component::dump_config() { - ESP_LOGCONFIG(TAG, "MCP9600:"); + ESP_LOGCONFIG(TAG, + "MCP9600:\n" + " Device ID: 0x%x", + this->device_id_); LOG_I2C_DEVICE(this); LOG_UPDATE_INTERVAL(this); - - ESP_LOGCONFIG(TAG, " Device ID: 0x%x", this->device_id_); - LOG_SENSOR(" ", "Hot Junction Temperature", this->hot_junction_sensor_); LOG_SENSOR(" ", "Cold Junction Temperature", this->cold_junction_sensor_); From aa4b274b3c69f228463bdefd09c812b488990240 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:51:18 -1000 Subject: [PATCH 225/302] [mcp3204] Combine log statements to reduce loop blocking (#12912) --- esphome/components/mcp3204/mcp3204.cpp | 6 ++++-- esphome/components/mcp3204/sensor/mcp3204_sensor.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/esphome/components/mcp3204/mcp3204.cpp b/esphome/components/mcp3204/mcp3204.cpp index f0dd171a14..abefcad0eb 100644 --- a/esphome/components/mcp3204/mcp3204.cpp +++ b/esphome/components/mcp3204/mcp3204.cpp @@ -11,9 +11,11 @@ float MCP3204::get_setup_priority() const { return setup_priority::HARDWARE; } void MCP3204::setup() { this->spi_setup(); } void MCP3204::dump_config() { - ESP_LOGCONFIG(TAG, "MCP3204:"); + ESP_LOGCONFIG(TAG, + "MCP3204:\n" + " Reference Voltage: %.2fV", + this->reference_voltage_); LOG_PIN(" CS Pin:", this->cs_); - ESP_LOGCONFIG(TAG, " Reference Voltage: %.2fV", this->reference_voltage_); } float MCP3204::read_data(uint8_t pin, bool differential) { diff --git a/esphome/components/mcp3204/sensor/mcp3204_sensor.cpp b/esphome/components/mcp3204/sensor/mcp3204_sensor.cpp index 4c4abef4a7..e673537be1 100644 --- a/esphome/components/mcp3204/sensor/mcp3204_sensor.cpp +++ b/esphome/components/mcp3204/sensor/mcp3204_sensor.cpp @@ -11,8 +11,10 @@ float MCP3204Sensor::get_setup_priority() const { return setup_priority::DATA; } void MCP3204Sensor::dump_config() { LOG_SENSOR("", "MCP3204 Sensor", this); - ESP_LOGCONFIG(TAG, " Pin: %u", this->pin_); - ESP_LOGCONFIG(TAG, " Differential Mode: %s", YESNO(this->differential_mode_)); + ESP_LOGCONFIG(TAG, + " Pin: %u\n" + " Differential Mode: %s", + this->pin_, YESNO(this->differential_mode_)); LOG_UPDATE_INTERVAL(this); } float MCP3204Sensor::sample() { return this->parent_->read_data(this->pin_, this->differential_mode_); } From 9b2a36a313be718bb7b6425a14d670d3f5d09dfc Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:51:33 -1000 Subject: [PATCH 226/302] [hc8] Combine log statements to reduce loop blocking (#12900) --- esphome/components/hc8/hc8.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/esphome/components/hc8/hc8.cpp b/esphome/components/hc8/hc8.cpp index 5b649c2735..4d0f77df1b 100644 --- a/esphome/components/hc8/hc8.cpp +++ b/esphome/components/hc8/hc8.cpp @@ -89,11 +89,12 @@ void HC8Component::calibrate(uint16_t baseline) { float HC8Component::get_setup_priority() const { return setup_priority::DATA; } void HC8Component::dump_config() { - ESP_LOGCONFIG(TAG, "HC8:"); + ESP_LOGCONFIG(TAG, + "HC8:\n" + " Warmup time: %" PRIu32 " s", + this->warmup_seconds_); LOG_SENSOR(" ", "CO2", this->co2_sensor_); this->check_uart_settings(9600); - - ESP_LOGCONFIG(TAG, " Warmup time: %" PRIu32 " s", this->warmup_seconds_); } } // namespace esphome::hc8 From 8ae1f26b6adefc02e40e0a1033808e68452b6a0c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:51:45 -1000 Subject: [PATCH 227/302] [hlw8012] Combine log statements to reduce loop blocking (#12901) --- esphome/components/hlw8012/hlw8012.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/hlw8012/hlw8012.cpp b/esphome/components/hlw8012/hlw8012.cpp index 70a05e4f72..f037ee9d8b 100644 --- a/esphome/components/hlw8012/hlw8012.cpp +++ b/esphome/components/hlw8012/hlw8012.cpp @@ -33,15 +33,15 @@ void HLW8012Component::setup() { } } void HLW8012Component::dump_config() { - ESP_LOGCONFIG(TAG, "HLW8012:"); - LOG_PIN(" SEL Pin: ", this->sel_pin_); - LOG_PIN(" CF Pin: ", this->cf_pin_); - LOG_PIN(" CF1 Pin: ", this->cf1_pin_); ESP_LOGCONFIG(TAG, + "HLW8012:\n" " Change measurement mode every %" PRIu32 "\n" " Current resistor: %.1f mΩ\n" " Voltage Divider: %.1f", this->change_mode_every_, this->current_resistor_ * 1000.0f, this->voltage_divider_); + LOG_PIN(" SEL Pin: ", this->sel_pin_); + LOG_PIN(" CF Pin: ", this->cf_pin_); + LOG_PIN(" CF1 Pin: ", this->cf1_pin_); LOG_UPDATE_INTERVAL(this); LOG_SENSOR(" ", "Voltage", this->voltage_sensor_); LOG_SENSOR(" ", "Current", this->current_sensor_); From 9bbfad4a081f83a257ae7b7ad12182199dbbf204 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:52:08 -1000 Subject: [PATCH 228/302] [honeywellabp] Combine log statements to reduce loop blocking (#12902) --- esphome/components/honeywellabp/honeywellabp.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/honeywellabp/honeywellabp.cpp b/esphome/components/honeywellabp/honeywellabp.cpp index 4c00f034aa..c204325dfc 100644 --- a/esphome/components/honeywellabp/honeywellabp.cpp +++ b/esphome/components/honeywellabp/honeywellabp.cpp @@ -35,8 +35,10 @@ uint8_t HONEYWELLABPSensor::readsensor_() { pressure_count_ = ((uint16_t) (buf_[0]) << 8 & 0x3F00) | ((uint16_t) (buf_[1]) & 0xFF); // 11 - bit temperature is all of byte 2 (lowest 8 bits) and the first three bits of byte 3 temperature_count_ = (((uint16_t) (buf_[2]) << 3) & 0x7F8) | (((uint16_t) (buf_[3]) >> 5) & 0x7); - ESP_LOGV(TAG, "Sensor pressure_count_ %d", pressure_count_); - ESP_LOGV(TAG, "Sensor temperature_count_ %d", temperature_count_); + ESP_LOGV(TAG, + "Sensor pressure_count_ %d\n" + "Sensor temperature_count_ %d", + pressure_count_, temperature_count_); } return status_; } From 548600b47a30783c534abb883cf5ea0aaab65e11 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:52:34 -1000 Subject: [PATCH 229/302] [ina260] Combine log statements to reduce loop blocking (#12903) --- esphome/components/ina260/ina260.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/components/ina260/ina260.cpp b/esphome/components/ina260/ina260.cpp index 9dd922cec2..4d6acf400c 100644 --- a/esphome/components/ina260/ina260.cpp +++ b/esphome/components/ina260/ina260.cpp @@ -61,13 +61,13 @@ void INA260Component::setup() { } void INA260Component::dump_config() { - ESP_LOGCONFIG(TAG, "INA260:"); + ESP_LOGCONFIG(TAG, + "INA260:\n" + " Manufacture ID: 0x%x\n" + " Device ID: 0x%x", + this->manufacture_id_, this->device_id_); LOG_I2C_DEVICE(this); LOG_UPDATE_INTERVAL(this); - - ESP_LOGCONFIG(TAG, " Manufacture ID: 0x%x", this->manufacture_id_); - ESP_LOGCONFIG(TAG, " Device ID: 0x%x", this->device_id_); - LOG_SENSOR(" ", "Bus Voltage", this->bus_voltage_sensor_); LOG_SENSOR(" ", "Current", this->current_sensor_); LOG_SENSOR(" ", "Power", this->power_sensor_); From 1fccddf67f3ad46bdc45c72df1717cada4fcf4d2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:52:56 -1000 Subject: [PATCH 230/302] [ina2xx_base] Combine log statements to reduce loop blocking (#12904) --- esphome/components/ina2xx_base/ina2xx_base.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/ina2xx_base/ina2xx_base.cpp b/esphome/components/ina2xx_base/ina2xx_base.cpp index 4ab02703e8..7185d21810 100644 --- a/esphome/components/ina2xx_base/ina2xx_base.cpp +++ b/esphome/components/ina2xx_base/ina2xx_base.cpp @@ -364,8 +364,10 @@ bool INA2XX::configure_shunt_() { ESP_LOGW(TAG, "Shunt value too high"); } this->shunt_cal_ &= 0x7FFF; - ESP_LOGV(TAG, "Given Rshunt=%f Ohm and Max_current=%.3f", this->shunt_resistance_ohm_, this->max_current_a_); - ESP_LOGV(TAG, "New CURRENT_LSB=%f, SHUNT_CAL=%u", this->current_lsb_, this->shunt_cal_); + ESP_LOGV(TAG, + "Given Rshunt=%f Ohm and Max_current=%.3f\n" + "New CURRENT_LSB=%f, SHUNT_CAL=%u", + this->shunt_resistance_ohm_, this->max_current_a_, this->current_lsb_, this->shunt_cal_); return this->write_unsigned_16_(RegisterMap::REG_SHUNT_CAL, this->shunt_cal_); } From b0855b4a0e68dc1483c733eaffd2714744b8941b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:53:50 -1000 Subject: [PATCH 231/302] [lc709203f] Combine log statements to reduce loop blocking (#12905) --- esphome/components/lc709203f/lc709203f.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/esphome/components/lc709203f/lc709203f.cpp b/esphome/components/lc709203f/lc709203f.cpp index 7e6ac878f8..ad9d6b3098 100644 --- a/esphome/components/lc709203f/lc709203f.cpp +++ b/esphome/components/lc709203f/lc709203f.cpp @@ -146,19 +146,14 @@ void Lc709203f::update() { } void Lc709203f::dump_config() { - ESP_LOGCONFIG(TAG, "LC709203F:"); - LOG_I2C_DEVICE(this); - - LOG_UPDATE_INTERVAL(this); ESP_LOGCONFIG(TAG, + "LC709203F:\n" " Pack Size: %d mAH\n" - " Pack APA: 0x%02X", - this->pack_size_, this->apa_); - - // This is only true if the pack_voltage_ is either 0x0000 or 0x0001. The config validator - // should have already verified this. - ESP_LOGCONFIG(TAG, " Pack Rated Voltage: 3.%sV", this->pack_voltage_ == 0x0000 ? "8" : "7"); - + " Pack APA: 0x%02X\n" + " Pack Rated Voltage: 3.%sV", + this->pack_size_, this->apa_, this->pack_voltage_ == 0x0000 ? "8" : "7"); + LOG_I2C_DEVICE(this); + LOG_UPDATE_INTERVAL(this); LOG_SENSOR(" ", "Voltage", this->voltage_sensor_); LOG_SENSOR(" ", "Battery Remaining", this->battery_remaining_sensor_); From ca574a15509c83b68ade2c32aabb437532839be0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:54:14 -1000 Subject: [PATCH 232/302] [ledc] Combine log statements to reduce loop blocking (#12906) --- esphome/components/ledc/ledc_output.cpp | 37 +++++++++++++++---------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/esphome/components/ledc/ledc_output.cpp b/esphome/components/ledc/ledc_output.cpp index aaa4794586..a203dde115 100644 --- a/esphome/components/ledc/ledc_output.cpp +++ b/esphome/components/ledc/ledc_output.cpp @@ -130,8 +130,10 @@ void LEDCOutput::setup() { } int hpoint = ledc_angle_to_htop(this->phase_angle_, this->bit_depth_); - ESP_LOGV(TAG, "Configured frequency %f with a bit depth of %u bits", this->frequency_, this->bit_depth_); - ESP_LOGV(TAG, "Angle of %.1f° results in hpoint %u", this->phase_angle_, hpoint); + ESP_LOGV(TAG, + "Configured frequency %f with a bit depth of %u bits\n" + "Angle of %.1f° results in hpoint %u", + this->frequency_, this->bit_depth_, this->phase_angle_, hpoint); ledc_channel_config_t chan_conf{}; chan_conf.gpio_num = this->pin_->get_pin(); @@ -147,25 +149,30 @@ void LEDCOutput::setup() { } void LEDCOutput::dump_config() { - ESP_LOGCONFIG(TAG, "Output:"); - LOG_PIN(" Pin ", this->pin_); ESP_LOGCONFIG(TAG, + "Output:\n" " Channel: %u\n" " PWM Frequency: %.1f Hz\n" " Phase angle: %.1f°\n" " Bit depth: %u", this->channel_, this->frequency_, this->phase_angle_, this->bit_depth_); - ESP_LOGV(TAG, " Max frequency for bit depth: %f", ledc_max_frequency_for_bit_depth(this->bit_depth_)); - ESP_LOGV(TAG, " Min frequency for bit depth: %f", - ledc_min_frequency_for_bit_depth(this->bit_depth_, (this->frequency_ < 100))); - ESP_LOGV(TAG, " Max frequency for bit depth-1: %f", ledc_max_frequency_for_bit_depth(this->bit_depth_ - 1)); - ESP_LOGV(TAG, " Min frequency for bit depth-1: %f", - ledc_min_frequency_for_bit_depth(this->bit_depth_ - 1, (this->frequency_ < 100))); - ESP_LOGV(TAG, " Max frequency for bit depth+1: %f", ledc_max_frequency_for_bit_depth(this->bit_depth_ + 1)); - ESP_LOGV(TAG, " Min frequency for bit depth+1: %f", - ledc_min_frequency_for_bit_depth(this->bit_depth_ + 1, (this->frequency_ < 100))); - ESP_LOGV(TAG, " Max res bits: %d", MAX_RES_BITS); - ESP_LOGV(TAG, " Clock frequency: %f", CLOCK_FREQUENCY); + LOG_PIN(" Pin ", this->pin_); + ESP_LOGV(TAG, + " Max frequency for bit depth: %f\n" + " Min frequency for bit depth: %f\n" + " Max frequency for bit depth-1: %f\n" + " Min frequency for bit depth-1: %f\n" + " Max frequency for bit depth+1: %f\n" + " Min frequency for bit depth+1: %f\n" + " Max res bits: %d\n" + " Clock frequency: %f", + ledc_max_frequency_for_bit_depth(this->bit_depth_), + ledc_min_frequency_for_bit_depth(this->bit_depth_, (this->frequency_ < 100)), + ledc_max_frequency_for_bit_depth(this->bit_depth_ - 1), + ledc_min_frequency_for_bit_depth(this->bit_depth_ - 1, (this->frequency_ < 100)), + ledc_max_frequency_for_bit_depth(this->bit_depth_ + 1), + ledc_min_frequency_for_bit_depth(this->bit_depth_ + 1, (this->frequency_ < 100)), MAX_RES_BITS, + CLOCK_FREQUENCY); } void LEDCOutput::update_frequency(float frequency) { From b8d93f2150759a9bbb01de105e215ec3652882ff Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:54:31 -1000 Subject: [PATCH 233/302] [mopeka_std_check] Combine log statements to reduce loop blocking (#12911) --- .../components/mopeka_std_check/mopeka_std_check.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/esphome/components/mopeka_std_check/mopeka_std_check.cpp b/esphome/components/mopeka_std_check/mopeka_std_check.cpp index 986a9a9fdc..231d09b909 100644 --- a/esphome/components/mopeka_std_check/mopeka_std_check.cpp +++ b/esphome/components/mopeka_std_check/mopeka_std_check.cpp @@ -17,10 +17,12 @@ static const uint16_t MANUFACTURER_ID = 0x000D; static constexpr size_t MOPEKA_MAX_LOG_BYTES = 32; void MopekaStdCheck::dump_config() { - ESP_LOGCONFIG(TAG, "Mopeka Std Check"); - ESP_LOGCONFIG(TAG, " Propane Butane mix: %.0f%%", this->propane_butane_mix_ * 100); - ESP_LOGCONFIG(TAG, " Tank distance empty: %" PRIi32 "mm", this->empty_mm_); - ESP_LOGCONFIG(TAG, " Tank distance full: %" PRIi32 "mm", this->full_mm_); + ESP_LOGCONFIG(TAG, + "Mopeka Std Check\n" + " Propane Butane mix: %.0f%%\n" + " Tank distance empty: %" PRIi32 "mm\n" + " Tank distance full: %" PRIi32 "mm", + this->propane_butane_mix_ * 100, this->empty_mm_, this->full_mm_); LOG_SENSOR(" ", "Level", this->level_); LOG_SENSOR(" ", "Temperature", this->temperature_); LOG_SENSOR(" ", "Battery Level", this->battery_level_); From a5368d1d95b5dc4dcf612b087cfb885a1fa80f9d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:54:47 -1000 Subject: [PATCH 234/302] [modbus] Combine log statements to reduce loop blocking (#12910) --- esphome/components/modbus/modbus.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/modbus/modbus.cpp b/esphome/components/modbus/modbus.cpp index 457dff4075..5e9387b843 100644 --- a/esphome/components/modbus/modbus.cpp +++ b/esphome/components/modbus/modbus.cpp @@ -196,12 +196,12 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) { } void Modbus::dump_config() { - ESP_LOGCONFIG(TAG, "Modbus:"); - LOG_PIN(" Flow Control Pin: ", this->flow_control_pin_); ESP_LOGCONFIG(TAG, + "Modbus:\n" " Send Wait Time: %d ms\n" " CRC Disabled: %s", this->send_wait_time_, YESNO(this->disable_crc_)); + LOG_PIN(" Flow Control Pin: ", this->flow_control_pin_); } float Modbus::get_setup_priority() const { // After UART bus From f2308c77c67e9b2f0d4c898435542472603ea983 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:55:18 -1000 Subject: [PATCH 235/302] [libretiny_pwm] Combine log statements to reduce loop blocking (#12907) --- esphome/components/libretiny_pwm/libretiny_pwm.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/libretiny_pwm/libretiny_pwm.cpp b/esphome/components/libretiny_pwm/libretiny_pwm.cpp index 92e4097c0e..4e4a16d761 100644 --- a/esphome/components/libretiny_pwm/libretiny_pwm.cpp +++ b/esphome/components/libretiny_pwm/libretiny_pwm.cpp @@ -31,9 +31,11 @@ void LibreTinyPWM::setup() { } void LibreTinyPWM::dump_config() { - ESP_LOGCONFIG(TAG, "PWM Output:"); + ESP_LOGCONFIG(TAG, + "PWM Output:\n" + " Frequency: %.1f Hz", + this->frequency_); LOG_PIN(" Pin ", this->pin_); - ESP_LOGCONFIG(TAG, " Frequency: %.1f Hz", this->frequency_); } void LibreTinyPWM::update_frequency(float frequency) { From 05695affff57afb8bbf00da629dca2d042b71365 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:55:31 -1000 Subject: [PATCH 236/302] [m5stack_8angle] Combine log statements to reduce loop blocking (#12908) --- esphome/components/m5stack_8angle/m5stack_8angle.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/m5stack_8angle/m5stack_8angle.cpp b/esphome/components/m5stack_8angle/m5stack_8angle.cpp index c542b4459e..5a9a5e8c9d 100644 --- a/esphome/components/m5stack_8angle/m5stack_8angle.cpp +++ b/esphome/components/m5stack_8angle/m5stack_8angle.cpp @@ -26,9 +26,11 @@ void M5Stack8AngleComponent::setup() { } void M5Stack8AngleComponent::dump_config() { - ESP_LOGCONFIG(TAG, "M5STACK_8ANGLE:"); + ESP_LOGCONFIG(TAG, + "M5STACK_8ANGLE:\n" + " Firmware version: %d", + this->fw_version_); LOG_I2C_DEVICE(this); - ESP_LOGCONFIG(TAG, " Firmware version: %d ", this->fw_version_); } float M5Stack8AngleComponent::read_knob_pos(uint8_t channel, AnalogBits bits) { From 71940acc492f8141d3daf9feba4b58265889e0a6 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Mon, 5 Jan 2026 08:37:44 +1000 Subject: [PATCH 237/302] [esp32_ble] Remove requirement for configured network (#12891) --- esphome/components/esp32_ble/__init__.py | 1 - esphome/components/socket/__init__.py | 7 ++- esphome/core/__init__.py | 19 ++++++ .../socket/test_wake_loop_threadsafe.py | 35 +++++++++++ tests/unit_tests/test_core.py | 62 +++++++++++++++++++ 5 files changed, 122 insertions(+), 2 deletions(-) diff --git a/esphome/components/esp32_ble/__init__.py b/esphome/components/esp32_ble/__init__.py index ced7e3fec9..dcc3ce71cf 100644 --- a/esphome/components/esp32_ble/__init__.py +++ b/esphome/components/esp32_ble/__init__.py @@ -22,7 +22,6 @@ from esphome.core import CORE, CoroPriority, TimePeriod, coroutine_with_priority import esphome.final_validate as fv DEPENDENCIES = ["esp32"] -AUTO_LOAD = ["socket"] CODEOWNERS = ["@jesserockz", "@Rapsssito", "@bdraco"] DOMAIN = "esp32_ble" diff --git a/esphome/components/socket/__init__.py b/esphome/components/socket/__init__.py index 49e074a6ee..e364da78f8 100644 --- a/esphome/components/socket/__init__.py +++ b/esphome/components/socket/__init__.py @@ -47,6 +47,8 @@ def require_wake_loop_threadsafe() -> None: This enables the shared UDP loopback socket mechanism (~208 bytes RAM). The socket is shared across all components that use this feature. + This call is a no-op if networking is not enabled in the configuration. + IMPORTANT: This is for background thread context only, NOT ISR context. Socket operations are not safe to call from ISR handlers. @@ -56,8 +58,11 @@ def require_wake_loop_threadsafe() -> None: async def to_code(config): socket.require_wake_loop_threadsafe() """ + # Only set up once (idempotent - multiple components can call this) - if not CORE.data.get(KEY_WAKE_LOOP_THREADSAFE_REQUIRED, False): + if CORE.has_networking and not CORE.data.get( + KEY_WAKE_LOOP_THREADSAFE_REQUIRED, False + ): CORE.data[KEY_WAKE_LOOP_THREADSAFE_REQUIRED] = True cg.add_define("USE_WAKE_LOOP_THREADSAFE") # Consume 1 socket for the shared wake notification socket diff --git a/esphome/core/__init__.py b/esphome/core/__init__.py index 3baec93186..70593d8153 100644 --- a/esphome/core/__init__.py +++ b/esphome/core/__init__.py @@ -721,6 +721,25 @@ class EsphomeCore: def config_filename(self) -> str: return self.config_path.name + def has_at_least_one_component(self, *components: str) -> bool: + """ + Are any of the given components configured? + :param components: component names + :return: true if so + """ + if self.config is None: + raise ValueError("Config has not been loaded yet") + + return any(component in self.config for component in components) + + @property + def has_networking(self) -> bool: + """ + Is a network component configured? + :return: true if so + """ + return self.has_at_least_one_component("wifi", "ethernet", "openthread") + def relative_config_path(self, *path: str | Path) -> Path: path_ = Path(*path).expanduser() return self.config_dir / path_ diff --git a/tests/components/socket/test_wake_loop_threadsafe.py b/tests/components/socket/test_wake_loop_threadsafe.py index 45e5ea2211..b4bc95176d 100644 --- a/tests/components/socket/test_wake_loop_threadsafe.py +++ b/tests/components/socket/test_wake_loop_threadsafe.py @@ -4,6 +4,7 @@ from esphome.core import CORE def test_require_wake_loop_threadsafe__first_call() -> None: """Test that first call sets up define and consumes socket.""" + CORE.config = {"wifi": True} socket.require_wake_loop_threadsafe() # Verify CORE.data was updated @@ -17,6 +18,7 @@ def test_require_wake_loop_threadsafe__idempotent() -> None: """Test that subsequent calls are idempotent.""" # Set up initial state as if already called CORE.data[socket.KEY_WAKE_LOOP_THREADSAFE_REQUIRED] = True + CORE.config = {"ethernet": True} # Call again - should not raise or fail socket.require_wake_loop_threadsafe() @@ -31,6 +33,7 @@ def test_require_wake_loop_threadsafe__idempotent() -> None: def test_require_wake_loop_threadsafe__multiple_calls() -> None: """Test that multiple calls only set up once.""" # Call three times + CORE.config = {"openthread": True} socket.require_wake_loop_threadsafe() socket.require_wake_loop_threadsafe() socket.require_wake_loop_threadsafe() @@ -40,3 +43,35 @@ def test_require_wake_loop_threadsafe__multiple_calls() -> None: # Verify the define was added (only once, but we can just check it exists) assert any(d.name == "USE_WAKE_LOOP_THREADSAFE" for d in CORE.defines) + + +def test_require_wake_loop_threadsafe__no_networking() -> None: + """Test that wake loop is NOT configured when no networking is configured.""" + # Set up config without any networking components + CORE.config = {"esphome": {"name": "test"}, "logger": {}} + + # Call require_wake_loop_threadsafe + socket.require_wake_loop_threadsafe() + + # Verify CORE.data flag was NOT set (since has_networking returns False) + assert socket.KEY_WAKE_LOOP_THREADSAFE_REQUIRED not in CORE.data + + # Verify the define was NOT added + assert not any(d.name == "USE_WAKE_LOOP_THREADSAFE" for d in CORE.defines) + + +def test_require_wake_loop_threadsafe__no_networking_does_not_consume_socket() -> None: + """Test that no socket is consumed when no networking is configured.""" + # Set up config without any networking components + CORE.config = {"logger": {}} + + # Track initial socket consumer state + initial_consumers = CORE.data.get(socket.KEY_SOCKET_CONSUMERS, {}) + + # Call require_wake_loop_threadsafe + socket.require_wake_loop_threadsafe() + + # Verify no socket was consumed + consumers = CORE.data.get(socket.KEY_SOCKET_CONSUMERS, {}) + assert "socket.wake_loop_threadsafe" not in consumers + assert consumers == initial_consumers diff --git a/tests/unit_tests/test_core.py b/tests/unit_tests/test_core.py index e52cb24831..1fc8dab358 100644 --- a/tests/unit_tests/test_core.py +++ b/tests/unit_tests/test_core.py @@ -718,3 +718,65 @@ class TestEsphomeCore: # Even though "web_server" is in loaded_integrations due to the platform, # web_port must return None because the full web_server component is not configured assert target.web_port is None + + def test_has_at_least_one_component__none_configured(self, target): + """Test has_at_least_one_component returns False when none of the components are configured.""" + target.config = {const.CONF_ESPHOME: {"name": "test"}, "logger": {}} + + assert target.has_at_least_one_component("wifi", "ethernet") is False + + def test_has_at_least_one_component__one_configured(self, target): + """Test has_at_least_one_component returns True when one component is configured.""" + target.config = {const.CONF_WIFI: {}, "logger": {}} + + assert target.has_at_least_one_component("wifi", "ethernet") is True + + def test_has_at_least_one_component__multiple_configured(self, target): + """Test has_at_least_one_component returns True when multiple components are configured.""" + target.config = { + const.CONF_WIFI: {}, + const.CONF_ETHERNET: {}, + "logger": {}, + } + + assert ( + target.has_at_least_one_component("wifi", "ethernet", "bluetooth") is True + ) + + def test_has_at_least_one_component__single_component(self, target): + """Test has_at_least_one_component works with a single component.""" + target.config = {const.CONF_MQTT: {}} + + assert target.has_at_least_one_component("mqtt") is True + assert target.has_at_least_one_component("wifi") is False + + def test_has_at_least_one_component__config_not_loaded(self, target): + """Test has_at_least_one_component raises ValueError when config is not loaded.""" + target.config = None + + with pytest.raises(ValueError, match="Config has not been loaded yet"): + target.has_at_least_one_component("wifi") + + def test_has_networking__with_wifi(self, target): + """Test has_networking returns True when wifi is configured.""" + target.config = {const.CONF_WIFI: {}} + + assert target.has_networking is True + + def test_has_networking__with_ethernet(self, target): + """Test has_networking returns True when ethernet is configured.""" + target.config = {const.CONF_ETHERNET: {}} + + assert target.has_networking is True + + def test_has_networking__with_openthread(self, target): + """Test has_networking returns True when openthread is configured.""" + target.config = {const.CONF_OPENTHREAD: {}} + + assert target.has_networking is True + + def test_has_networking__without_networking(self, target): + """Test has_networking returns False when no networking component is configured.""" + target.config = {const.CONF_ESPHOME: {"name": "test"}, "logger": {}} + + assert target.has_networking is False From 25ef9aff044e6adc265eec5c2aa6f724c78b39c2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 12:53:46 -1000 Subject: [PATCH 238/302] [vl53l0x] Combine log statements to reduce loop blocking (#12929) --- esphome/components/vl53l0x/vl53l0x_sensor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/vl53l0x/vl53l0x_sensor.cpp b/esphome/components/vl53l0x/vl53l0x_sensor.cpp index d2548a5bbd..e833657fc4 100644 --- a/esphome/components/vl53l0x/vl53l0x_sensor.cpp +++ b/esphome/components/vl53l0x/vl53l0x_sensor.cpp @@ -27,8 +27,10 @@ void VL53L0XSensor::dump_config() { if (this->enable_pin_ != nullptr) { LOG_PIN(" Enable Pin: ", this->enable_pin_); } - ESP_LOGCONFIG(TAG, " Timeout: %u%s", this->timeout_us_, this->timeout_us_ > 0 ? "us" : " (no timeout)"); - ESP_LOGCONFIG(TAG, " Timing Budget %uus ", this->measurement_timing_budget_us_); + ESP_LOGCONFIG(TAG, + " Timeout: %u%s\n" + " Timing Budget %uus ", + this->timeout_us_, this->timeout_us_ > 0 ? "us" : " (no timeout)", this->measurement_timing_budget_us_); } void VL53L0XSensor::setup() { From 022c42f9ca0f19158426fcc5b04509e712307442 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 12:53:58 -1000 Subject: [PATCH 239/302] [tuya] Combine log statements to reduce loop blocking (#12924) --- .../components/tuya/binary_sensor/tuya_binary_sensor.cpp | 6 ++++-- esphome/components/tuya/text_sensor/tuya_text_sensor.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/esphome/components/tuya/binary_sensor/tuya_binary_sensor.cpp b/esphome/components/tuya/binary_sensor/tuya_binary_sensor.cpp index edfbb2ac60..a63e9c8318 100644 --- a/esphome/components/tuya/binary_sensor/tuya_binary_sensor.cpp +++ b/esphome/components/tuya/binary_sensor/tuya_binary_sensor.cpp @@ -14,8 +14,10 @@ void TuyaBinarySensor::setup() { } void TuyaBinarySensor::dump_config() { - ESP_LOGCONFIG(TAG, "Tuya Binary Sensor:"); - ESP_LOGCONFIG(TAG, " Binary Sensor has datapoint ID %u", this->sensor_id_); + ESP_LOGCONFIG(TAG, + "Tuya Binary Sensor:\n" + " Binary Sensor has datapoint ID %u", + this->sensor_id_); } } // namespace tuya diff --git a/esphome/components/tuya/text_sensor/tuya_text_sensor.cpp b/esphome/components/tuya/text_sensor/tuya_text_sensor.cpp index fbe511811f..c71bf176a4 100644 --- a/esphome/components/tuya/text_sensor/tuya_text_sensor.cpp +++ b/esphome/components/tuya/text_sensor/tuya_text_sensor.cpp @@ -33,8 +33,10 @@ void TuyaTextSensor::setup() { } void TuyaTextSensor::dump_config() { - ESP_LOGCONFIG(TAG, "Tuya Text Sensor:"); - ESP_LOGCONFIG(TAG, " Text Sensor has datapoint ID %u", this->sensor_id_); + ESP_LOGCONFIG(TAG, + "Tuya Text Sensor:\n" + " Text Sensor has datapoint ID %u", + this->sensor_id_); } } // namespace tuya From e9cab96cb79644ebbf105d78da71153b5f190779 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 12:56:50 -1000 Subject: [PATCH 240/302] [sx1509] Combine log statements to reduce loop blocking (#12920) --- esphome/components/sx1509/output/sx1509_float_output.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/sx1509/output/sx1509_float_output.cpp b/esphome/components/sx1509/output/sx1509_float_output.cpp index 1d2541bb46..4a24d78478 100644 --- a/esphome/components/sx1509/output/sx1509_float_output.cpp +++ b/esphome/components/sx1509/output/sx1509_float_output.cpp @@ -22,8 +22,10 @@ void SX1509FloatOutputChannel::setup() { } void SX1509FloatOutputChannel::dump_config() { - ESP_LOGCONFIG(TAG, "SX1509 PWM:"); - ESP_LOGCONFIG(TAG, " sx1509 pin: %d", this->pin_); + ESP_LOGCONFIG(TAG, + "SX1509 PWM:\n" + " sx1509 pin: %d", + this->pin_); LOG_FLOAT_OUTPUT(this); } From 56d1d928f9400935007b9bffdc16ee5a9bca448a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 12:57:10 -1000 Subject: [PATCH 241/302] [tlc5947] Combine log statements to reduce loop blocking (#12921) --- esphome/components/tlc5947/tlc5947.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/tlc5947/tlc5947.cpp b/esphome/components/tlc5947/tlc5947.cpp index 6d4e099f7a..0a278bbaf6 100644 --- a/esphome/components/tlc5947/tlc5947.cpp +++ b/esphome/components/tlc5947/tlc5947.cpp @@ -21,12 +21,14 @@ void TLC5947::setup() { this->pwm_amounts_.resize(this->num_chips_ * N_CHANNELS_PER_CHIP, 0); } void TLC5947::dump_config() { - ESP_LOGCONFIG(TAG, "TLC5947:"); + ESP_LOGCONFIG(TAG, + "TLC5947:\n" + " Number of chips: %u", + this->num_chips_); LOG_PIN(" Data Pin: ", this->data_pin_); LOG_PIN(" Clock Pin: ", this->clock_pin_); LOG_PIN(" LAT Pin: ", this->lat_pin_); LOG_PIN(" OE Pin: ", this->outenable_pin_); - ESP_LOGCONFIG(TAG, " Number of chips: %u", this->num_chips_); } void TLC5947::loop() { From 88cb5d9671d3975a2a966de1066ff423f0ecf69a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 12:58:20 -1000 Subject: [PATCH 242/302] [tmp1075] Combine log statements to reduce loop blocking (#12923) --- esphome/components/tmp1075/tmp1075.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/esphome/components/tmp1075/tmp1075.cpp b/esphome/components/tmp1075/tmp1075.cpp index 1d9b384c66..9eb1e86c75 100644 --- a/esphome/components/tmp1075/tmp1075.cpp +++ b/esphome/components/tmp1075/tmp1075.cpp @@ -73,12 +73,15 @@ void TMP1075Sensor::set_fault_count(const int faults) { } void TMP1075Sensor::log_config_() { - ESP_LOGV(TAG, " oneshot : %d", config_.fields.oneshot); - ESP_LOGV(TAG, " rate : %d", config_.fields.rate); - ESP_LOGV(TAG, " faults : %d", config_.fields.faults); - ESP_LOGV(TAG, " polarity : %d", config_.fields.polarity); - ESP_LOGV(TAG, " alert_mode: %d", config_.fields.alert_mode); - ESP_LOGV(TAG, " shutdown : %d", config_.fields.shutdown); + ESP_LOGV(TAG, + " oneshot : %d\n" + " rate : %d\n" + " faults : %d\n" + " polarity : %d\n" + " alert_mode: %d\n" + " shutdown : %d", + config_.fields.oneshot, config_.fields.rate, config_.fields.faults, config_.fields.polarity, + config_.fields.alert_mode, config_.fields.shutdown); } void TMP1075Sensor::write_config() { From 32b3d27c7c1c8701a950fe43281422f2a67ed5b2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 12:58:42 -1000 Subject: [PATCH 243/302] [uln2003] Combine log statements to reduce loop blocking (#12926) --- esphome/components/uln2003/uln2003.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/uln2003/uln2003.cpp b/esphome/components/uln2003/uln2003.cpp index 991fe53487..11e1c3d4c0 100644 --- a/esphome/components/uln2003/uln2003.cpp +++ b/esphome/components/uln2003/uln2003.cpp @@ -34,12 +34,14 @@ void ULN2003::loop() { this->write_step_(this->current_uln_pos_); } void ULN2003::dump_config() { - ESP_LOGCONFIG(TAG, "ULN2003:"); + ESP_LOGCONFIG(TAG, + "ULN2003:\n" + " Sleep when done: %s", + YESNO(this->sleep_when_done_)); LOG_PIN(" Pin A: ", this->pin_a_); LOG_PIN(" Pin B: ", this->pin_b_); LOG_PIN(" Pin C: ", this->pin_c_); LOG_PIN(" Pin D: ", this->pin_d_); - ESP_LOGCONFIG(TAG, " Sleep when done: %s", YESNO(this->sleep_when_done_)); const char *step_mode_s; switch (this->step_mode_) { case ULN2003_STEP_MODE_FULL_STEP: From c59455e445bc4347ac9eb8687a9d2a9530cff3bd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 12:59:47 -1000 Subject: [PATCH 244/302] [mqtt] Combine log statements to reduce loop blocking (#12938) --- esphome/components/mqtt/mqtt_client.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/mqtt/mqtt_client.cpp b/esphome/components/mqtt/mqtt_client.cpp index c650c99f62..d26548acfc 100644 --- a/esphome/components/mqtt/mqtt_client.cpp +++ b/esphome/components/mqtt/mqtt_client.cpp @@ -154,15 +154,17 @@ void MQTTClientComponent::on_log(uint8_t level, const char *tag, const char *mes void MQTTClientComponent::dump_config() { char ip_buf[network::IP_ADDRESS_BUFFER_SIZE]; + // clang-format off ESP_LOGCONFIG(TAG, "MQTT:\n" " Server Address: %s:%u (%s)\n" " Username: " LOG_SECRET("'%s'") "\n" - " Client ID: " LOG_SECRET("'%s'") "\n" - " Clean Session: %s", + " Client ID: " LOG_SECRET("'%s'") "\n" + " Clean Session: %s", this->credentials_.address.c_str(), this->credentials_.port, this->ip_.str_to(ip_buf), this->credentials_.username.c_str(), this->credentials_.client_id.c_str(), YESNO(this->credentials_.clean_session)); + // clang-format on if (this->is_discovery_ip_enabled()) { ESP_LOGCONFIG(TAG, " Discovery IP enabled"); } From 6e633f7f3bb3ae1fa191f3ecce7e5939283c0d78 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:00:03 -1000 Subject: [PATCH 245/302] [usb_uart] Combine log statements to reduce loop blocking (#12928) --- esphome/components/usb_uart/cp210x.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/usb_uart/cp210x.cpp b/esphome/components/usb_uart/cp210x.cpp index be024d1ba2..483286560a 100644 --- a/esphome/components/usb_uart/cp210x.cpp +++ b/esphome/components/usb_uart/cp210x.cpp @@ -58,8 +58,10 @@ std::vector USBUartTypeCP210X::parse_descriptors(usb_device_handle_t dev ESP_LOGE(TAG, "get_active_config_descriptor failed"); return {}; } - ESP_LOGD(TAG, "bDeviceClass: %u, bDeviceSubClass: %u", device_desc->bDeviceClass, device_desc->bDeviceSubClass); - ESP_LOGD(TAG, "bNumInterfaces: %u", config_desc->bNumInterfaces); + ESP_LOGD(TAG, + "bDeviceClass: %u, bDeviceSubClass: %u\n" + "bNumInterfaces: %u", + device_desc->bDeviceClass, device_desc->bDeviceSubClass, config_desc->bNumInterfaces); if (device_desc->bDeviceClass != 0) { ESP_LOGE(TAG, "bDeviceClass != 0"); return {}; From 557b6a9ef0657dec888cf9347fbaaca61908d84e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:00:59 -1000 Subject: [PATCH 246/302] [sun] Combine log statements to reduce loop blocking (#12919) --- esphome/components/sun/sun.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/esphome/components/sun/sun.cpp b/esphome/components/sun/sun.cpp index df7030461b..e8fc4e44d1 100644 --- a/esphome/components/sun/sun.cpp +++ b/esphome/components/sun/sun.cpp @@ -172,21 +172,25 @@ struct SunAtTime { void debug() const { // debug output like in example 25.a, p. 165 - ESP_LOGV(TAG, "jde: %f", jde); - ESP_LOGV(TAG, "T: %f", t); - ESP_LOGV(TAG, "L_0: %f", mean_longitude()); - ESP_LOGV(TAG, "M: %f", mean_anomaly()); - ESP_LOGV(TAG, "e: %f", eccentricity()); - ESP_LOGV(TAG, "C: %f", equation_of_center()); - ESP_LOGV(TAG, "Odot: %f", true_longitude()); - ESP_LOGV(TAG, "Omega: %f", omega()); - ESP_LOGV(TAG, "lambda: %f", apparent_longitude()); - ESP_LOGV(TAG, "epsilon_0: %f", mean_obliquity()); - ESP_LOGV(TAG, "epsilon: %f", true_obliquity()); - ESP_LOGV(TAG, "v: %f", true_anomaly()); auto eq = equatorial_coordinate(); - ESP_LOGV(TAG, "right_ascension: %f", eq.right_ascension); - ESP_LOGV(TAG, "declination: %f", eq.declination); + ESP_LOGV(TAG, + "jde: %f\n" + "T: %f\n" + "L_0: %f\n" + "M: %f\n" + "e: %f\n" + "C: %f\n" + "Odot: %f\n" + "Omega: %f\n" + "lambda: %f\n" + "epsilon_0: %f\n" + "epsilon: %f\n" + "v: %f\n" + "right_ascension: %f\n" + "declination: %f", + jde, t, mean_longitude(), mean_anomaly(), eccentricity(), equation_of_center(), true_longitude(), omega(), + apparent_longitude(), mean_obliquity(), true_obliquity(), true_anomaly(), eq.right_ascension, + eq.declination); } }; From 0b996616b87261d6758e57c8faedb486d9e20236 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:01:33 -1000 Subject: [PATCH 247/302] [waveshare_epaper] Combine log statements to reduce loop blocking (#12931) --- .../waveshare_epaper/waveshare_epaper.cpp | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/esphome/components/waveshare_epaper/waveshare_epaper.cpp b/esphome/components/waveshare_epaper/waveshare_epaper.cpp index 9ab050395d..4db9438206 100644 --- a/esphome/components/waveshare_epaper/waveshare_epaper.cpp +++ b/esphome/components/waveshare_epaper/waveshare_epaper.cpp @@ -1825,8 +1825,10 @@ void WaveshareEPaper2P9InV2R2::write_lut_(const uint8_t *lut, const uint8_t size void WaveshareEPaper2P9InV2R2::dump_config() { LOG_DISPLAY("", "Waveshare E-Paper", this); - ESP_LOGCONFIG(TAG, " Model: 2.9inV2R2"); - ESP_LOGCONFIG(TAG, " Full Update Every: %" PRIu32, this->full_update_every_); + ESP_LOGCONFIG(TAG, + " Model: 2.9inV2R2\n" + " Full Update Every: %" PRIu32, + this->full_update_every_); LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" Busy Pin: ", this->busy_pin_); @@ -2528,8 +2530,10 @@ int GDEY042T81::get_height_internal() { return 300; } uint32_t GDEY042T81::idle_timeout_() { return 5000; } void GDEY042T81::dump_config() { LOG_DISPLAY("", "GoodDisplay E-Paper", this); - ESP_LOGCONFIG(TAG, " Model: 4.2in B/W GDEY042T81"); - ESP_LOGCONFIG(TAG, " Full Update Every: %" PRIu32, this->full_update_every_); + ESP_LOGCONFIG(TAG, + " Model: 4.2in B/W GDEY042T81\n" + " Full Update Every: %" PRIu32, + this->full_update_every_); LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" Busy Pin: ", this->busy_pin_); @@ -3159,8 +3163,10 @@ int GDEY0583T81::get_height_internal() { return 480; } uint32_t GDEY0583T81::idle_timeout_() { return 5000; } void GDEY0583T81::dump_config() { LOG_DISPLAY("", "GoodDisplay E-Paper", this); - ESP_LOGCONFIG(TAG, " Model: 5.83in B/W GDEY0583T81"); - ESP_LOGCONFIG(TAG, " Full Update Every: %" PRIu32, this->full_update_every_); + ESP_LOGCONFIG(TAG, + " Model: 5.83in B/W GDEY0583T81\n" + " Full Update Every: %" PRIu32, + this->full_update_every_); LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" Busy Pin: ", this->busy_pin_); @@ -4340,8 +4346,10 @@ int WaveshareEPaper7P5InV2P::get_height_internal() { return 480; } uint32_t WaveshareEPaper7P5InV2P::idle_timeout_() { return 10000; } void WaveshareEPaper7P5InV2P::dump_config() { LOG_DISPLAY("", "Waveshare E-Paper", this); - ESP_LOGCONFIG(TAG, " Model: 7.50inv2p"); - ESP_LOGCONFIG(TAG, " Full Update Every: %" PRIu32, this->full_update_every_); + ESP_LOGCONFIG(TAG, + " Model: 7.50inv2p\n" + " Full Update Every: %" PRIu32, + this->full_update_every_); LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" Busy Pin: ", this->busy_pin_); From c44d095f8ac6d2fc5250b5270a6f48df6a55e94c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:01:49 -1000 Subject: [PATCH 248/302] [usb_host] Combine log statements to reduce loop blocking (#12927) --- .../components/usb_host/usb_host_client.cpp | 95 +++++++++++-------- 1 file changed, 55 insertions(+), 40 deletions(-) diff --git a/esphome/components/usb_host/usb_host_client.cpp b/esphome/components/usb_host/usb_host_client.cpp index 664f49d137..09da6e3b73 100644 --- a/esphome/components/usb_host/usb_host_client.cpp +++ b/esphome/components/usb_host/usb_host_client.cpp @@ -39,37 +39,46 @@ static void print_ep_desc(const usb_ep_desc_t *ep_desc) { break; } - ESP_LOGV(TAG, "\t\t*** Endpoint descriptor ***"); - ESP_LOGV(TAG, "\t\tbLength %d", ep_desc->bLength); - ESP_LOGV(TAG, "\t\tbDescriptorType %d", ep_desc->bDescriptorType); - ESP_LOGV(TAG, "\t\tbEndpointAddress 0x%x\tEP %d %s", ep_desc->bEndpointAddress, USB_EP_DESC_GET_EP_NUM(ep_desc), - USB_EP_DESC_GET_EP_DIR(ep_desc) ? "IN" : "OUT"); - ESP_LOGV(TAG, "\t\tbmAttributes 0x%x\t%s", ep_desc->bmAttributes, ep_type_str); - ESP_LOGV(TAG, "\t\twMaxPacketSize %d", ep_desc->wMaxPacketSize); - ESP_LOGV(TAG, "\t\tbInterval %d", ep_desc->bInterval); + ESP_LOGV(TAG, + "\t\t*** Endpoint descriptor ***\n" + "\t\tbLength %d\n" + "\t\tbDescriptorType %d\n" + "\t\tbEndpointAddress 0x%x\tEP %d %s\n" + "\t\tbmAttributes 0x%x\t%s\n" + "\t\twMaxPacketSize %d\n" + "\t\tbInterval %d", + ep_desc->bLength, ep_desc->bDescriptorType, ep_desc->bEndpointAddress, USB_EP_DESC_GET_EP_NUM(ep_desc), + USB_EP_DESC_GET_EP_DIR(ep_desc) ? "IN" : "OUT", ep_desc->bmAttributes, ep_type_str, ep_desc->wMaxPacketSize, + ep_desc->bInterval); } static void usbh_print_intf_desc(const usb_intf_desc_t *intf_desc) { - ESP_LOGV(TAG, "\t*** Interface descriptor ***"); - ESP_LOGV(TAG, "\tbLength %d", intf_desc->bLength); - ESP_LOGV(TAG, "\tbDescriptorType %d", intf_desc->bDescriptorType); - ESP_LOGV(TAG, "\tbInterfaceNumber %d", intf_desc->bInterfaceNumber); - ESP_LOGV(TAG, "\tbAlternateSetting %d", intf_desc->bAlternateSetting); - ESP_LOGV(TAG, "\tbNumEndpoints %d", intf_desc->bNumEndpoints); - ESP_LOGV(TAG, "\tbInterfaceClass 0x%x", intf_desc->bInterfaceProtocol); - ESP_LOGV(TAG, "\tiInterface %d", intf_desc->iInterface); + ESP_LOGV(TAG, + "\t*** Interface descriptor ***\n" + "\tbLength %d\n" + "\tbDescriptorType %d\n" + "\tbInterfaceNumber %d\n" + "\tbAlternateSetting %d\n" + "\tbNumEndpoints %d\n" + "\tbInterfaceClass 0x%x\n" + "\tiInterface %d", + intf_desc->bLength, intf_desc->bDescriptorType, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting, + intf_desc->bNumEndpoints, intf_desc->bInterfaceProtocol, intf_desc->iInterface); } static void usbh_print_cfg_desc(const usb_config_desc_t *cfg_desc) { - ESP_LOGV(TAG, "*** Configuration descriptor ***"); - ESP_LOGV(TAG, "bLength %d", cfg_desc->bLength); - ESP_LOGV(TAG, "bDescriptorType %d", cfg_desc->bDescriptorType); - ESP_LOGV(TAG, "wTotalLength %d", cfg_desc->wTotalLength); - ESP_LOGV(TAG, "bNumInterfaces %d", cfg_desc->bNumInterfaces); - ESP_LOGV(TAG, "bConfigurationValue %d", cfg_desc->bConfigurationValue); - ESP_LOGV(TAG, "iConfiguration %d", cfg_desc->iConfiguration); - ESP_LOGV(TAG, "bmAttributes 0x%x", cfg_desc->bmAttributes); - ESP_LOGV(TAG, "bMaxPower %dmA", cfg_desc->bMaxPower * 2); + ESP_LOGV(TAG, + "*** Configuration descriptor ***\n" + "bLength %d\n" + "bDescriptorType %d\n" + "wTotalLength %d\n" + "bNumInterfaces %d\n" + "bConfigurationValue %d\n" + "iConfiguration %d\n" + "bmAttributes 0x%x\n" + "bMaxPower %dmA", + cfg_desc->bLength, cfg_desc->bDescriptorType, cfg_desc->wTotalLength, cfg_desc->bNumInterfaces, + cfg_desc->bConfigurationValue, cfg_desc->iConfiguration, cfg_desc->bmAttributes, cfg_desc->bMaxPower * 2); } static void usb_client_print_device_descriptor(const usb_device_desc_t *devc_desc) { @@ -77,21 +86,27 @@ static void usb_client_print_device_descriptor(const usb_device_desc_t *devc_des return; } - ESP_LOGV(TAG, "*** Device descriptor ***"); - ESP_LOGV(TAG, "bLength %d", devc_desc->bLength); - ESP_LOGV(TAG, "bDescriptorType %d", devc_desc->bDescriptorType); - ESP_LOGV(TAG, "bcdUSB %d.%d0", ((devc_desc->bcdUSB >> 8) & 0xF), ((devc_desc->bcdUSB >> 4) & 0xF)); - ESP_LOGV(TAG, "bDeviceClass 0x%x", devc_desc->bDeviceClass); - ESP_LOGV(TAG, "bDeviceSubClass 0x%x", devc_desc->bDeviceSubClass); - ESP_LOGV(TAG, "bDeviceProtocol 0x%x", devc_desc->bDeviceProtocol); - ESP_LOGV(TAG, "bMaxPacketSize0 %d", devc_desc->bMaxPacketSize0); - ESP_LOGV(TAG, "idVendor 0x%x", devc_desc->idVendor); - ESP_LOGV(TAG, "idProduct 0x%x", devc_desc->idProduct); - ESP_LOGV(TAG, "bcdDevice %d.%d0", ((devc_desc->bcdDevice >> 8) & 0xF), ((devc_desc->bcdDevice >> 4) & 0xF)); - ESP_LOGV(TAG, "iManufacturer %d", devc_desc->iManufacturer); - ESP_LOGV(TAG, "iProduct %d", devc_desc->iProduct); - ESP_LOGV(TAG, "iSerialNumber %d", devc_desc->iSerialNumber); - ESP_LOGV(TAG, "bNumConfigurations %d", devc_desc->bNumConfigurations); + ESP_LOGV(TAG, + "*** Device descriptor ***\n" + "bLength %d\n" + "bDescriptorType %d\n" + "bcdUSB %d.%d0\n" + "bDeviceClass 0x%x\n" + "bDeviceSubClass 0x%x\n" + "bDeviceProtocol 0x%x\n" + "bMaxPacketSize0 %d\n" + "idVendor 0x%x\n" + "idProduct 0x%x\n" + "bcdDevice %d.%d0\n" + "iManufacturer %d\n" + "iProduct %d\n" + "iSerialNumber %d\n" + "bNumConfigurations %d", + devc_desc->bLength, devc_desc->bDescriptorType, ((devc_desc->bcdUSB >> 8) & 0xF), + ((devc_desc->bcdUSB >> 4) & 0xF), devc_desc->bDeviceClass, devc_desc->bDeviceSubClass, + devc_desc->bDeviceProtocol, devc_desc->bMaxPacketSize0, devc_desc->idVendor, devc_desc->idProduct, + ((devc_desc->bcdDevice >> 8) & 0xF), ((devc_desc->bcdDevice >> 4) & 0xF), devc_desc->iManufacturer, + devc_desc->iProduct, devc_desc->iSerialNumber, devc_desc->bNumConfigurations); } static void usb_client_print_config_descriptor(const usb_config_desc_t *cfg_desc, From 29d332af920876a5bf1894d0325ffa204308295d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:02:02 -1000 Subject: [PATCH 249/302] [wireguard] Combine log statements to reduce loop blocking (#12932) --- esphome/components/wireguard/wireguard.cpp | 24 ++++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/esphome/components/wireguard/wireguard.cpp b/esphome/components/wireguard/wireguard.cpp index 2de6f0d2e3..7810a40ae1 100644 --- a/esphome/components/wireguard/wireguard.cpp +++ b/esphome/components/wireguard/wireguard.cpp @@ -131,15 +131,21 @@ void Wireguard::update() { } void Wireguard::dump_config() { - ESP_LOGCONFIG(TAG, "WireGuard:"); - ESP_LOGCONFIG(TAG, " Address: %s", this->address_.c_str()); - ESP_LOGCONFIG(TAG, " Netmask: %s", this->netmask_.c_str()); - ESP_LOGCONFIG(TAG, " Private Key: " LOG_SECRET("%s"), mask_key(this->private_key_).c_str()); - ESP_LOGCONFIG(TAG, " Peer Endpoint: " LOG_SECRET("%s"), this->peer_endpoint_.c_str()); - ESP_LOGCONFIG(TAG, " Peer Port: " LOG_SECRET("%d"), this->peer_port_); - ESP_LOGCONFIG(TAG, " Peer Public Key: " LOG_SECRET("%s"), this->peer_public_key_.c_str()); - ESP_LOGCONFIG(TAG, " Peer Pre-shared Key: " LOG_SECRET("%s"), - (!this->preshared_key_.empty() ? mask_key(this->preshared_key_).c_str() : "NOT IN USE")); + // clang-format off + ESP_LOGCONFIG( + TAG, + "WireGuard:\n" + " Address: %s\n" + " Netmask: %s\n" + " Private Key: " LOG_SECRET("%s") "\n" + " Peer Endpoint: " LOG_SECRET("%s") "\n" + " Peer Port: " LOG_SECRET("%d") "\n" + " Peer Public Key: " LOG_SECRET("%s") "\n" + " Peer Pre-shared Key: " LOG_SECRET("%s"), + this->address_.c_str(), this->netmask_.c_str(), mask_key(this->private_key_).c_str(), + this->peer_endpoint_.c_str(), this->peer_port_, this->peer_public_key_.c_str(), + (!this->preshared_key_.empty() ? mask_key(this->preshared_key_).c_str() : "NOT IN USE")); + // clang-format on ESP_LOGCONFIG(TAG, " Peer Allowed IPs:"); for (auto &allowed_ip : this->allowed_ips_) { ESP_LOGCONFIG(TAG, " - %s/%s", std::get<0>(allowed_ip).c_str(), std::get<1>(allowed_ip).c_str()); From 9d9f9c3c8498e2bdf481b967e14f6d1a9a153bd0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:02:52 -1000 Subject: [PATCH 250/302] [xiaomi_xmwsdj04mmc] Combine log statements to reduce loop blocking (#12936) --- .../components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp b/esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp index d3fec6cc9e..31e426f0cc 100644 --- a/esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +++ b/esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp @@ -13,8 +13,10 @@ static constexpr size_t XMWSDJ04MMC_BINDKEY_SIZE = 16; void XiaomiXMWSDJ04MMC::dump_config() { char bindkey_hex[format_hex_pretty_size(XMWSDJ04MMC_BINDKEY_SIZE)]; - ESP_LOGCONFIG(TAG, "Xiaomi XMWSDJ04MMC"); - ESP_LOGCONFIG(TAG, " Bindkey: %s", format_hex_pretty_to(bindkey_hex, this->bindkey_, XMWSDJ04MMC_BINDKEY_SIZE, '.')); + ESP_LOGCONFIG(TAG, + "Xiaomi XMWSDJ04MMC\n" + " Bindkey: %s", + format_hex_pretty_to(bindkey_hex, this->bindkey_, XMWSDJ04MMC_BINDKEY_SIZE, '.')); LOG_SENSOR(" ", "Temperature", this->temperature_); LOG_SENSOR(" ", "Humidity", this->humidity_); LOG_SENSOR(" ", "Battery Level", this->battery_level_); From 5713d69efecb26619cd1fae57050095fdceeb858 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:03:06 -1000 Subject: [PATCH 251/302] [ufire_ec] Combine log statements to reduce loop blocking (#12925) --- esphome/components/ufire_ec/ufire_ec.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/components/ufire_ec/ufire_ec.cpp b/esphome/components/ufire_ec/ufire_ec.cpp index 0a57ecc67b..3868dc92b7 100644 --- a/esphome/components/ufire_ec/ufire_ec.cpp +++ b/esphome/components/ufire_ec/ufire_ec.cpp @@ -102,16 +102,16 @@ void UFireECComponent::write_data_(uint8_t reg, float data) { } void UFireECComponent::dump_config() { - ESP_LOGCONFIG(TAG, "uFire-EC"); + ESP_LOGCONFIG(TAG, + "uFire-EC:\n" + " Temperature Compensation: %f\n" + " Temperature Coefficient: %f", + this->temperature_compensation_, this->temperature_coefficient_); LOG_I2C_DEVICE(this) LOG_UPDATE_INTERVAL(this); LOG_SENSOR(" ", "EC Sensor", this->ec_sensor_); LOG_SENSOR(" ", "Temperature Sensor", this->temperature_sensor_); LOG_SENSOR(" ", "Temperature Sensor external", this->temperature_sensor_external_); - ESP_LOGCONFIG(TAG, - " Temperature Compensation: %f\n" - " Temperature Coefficient: %f", - this->temperature_compensation_, this->temperature_coefficient_); } } // namespace ufire_ec From 3ea11d4e5983679b706c0abcc2510d242ff337ca Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:03:22 -1000 Subject: [PATCH 252/302] [xpt2046] Combine log statements to reduce loop blocking (#12937) --- esphome/components/xpt2046/touchscreen/xpt2046.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/esphome/components/xpt2046/touchscreen/xpt2046.cpp b/esphome/components/xpt2046/touchscreen/xpt2046.cpp index fa99e3afa7..84d3daf823 100644 --- a/esphome/components/xpt2046/touchscreen/xpt2046.cpp +++ b/esphome/components/xpt2046/touchscreen/xpt2046.cpp @@ -59,10 +59,8 @@ void XPT2046Component::update_touches() { } void XPT2046Component::dump_config() { - ESP_LOGCONFIG(TAG, "XPT2046:"); - - LOG_PIN(" IRQ Pin: ", this->irq_pin_); ESP_LOGCONFIG(TAG, + "XPT2046:\n" " X min: %d\n" " X max: %d\n" " Y min: %d\n" @@ -73,7 +71,7 @@ void XPT2046Component::dump_config() { " threshold: %d", this->x_raw_min_, this->x_raw_max_, this->y_raw_min_, this->y_raw_max_, YESNO(this->swap_x_y_), YESNO(this->invert_x_), YESNO(this->invert_y_), this->threshold_); - + LOG_PIN(" IRQ Pin: ", this->irq_pin_); LOG_UPDATE_INTERVAL(this); } From 161545584d23811f547ace48ead7dcc82e1cf746 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:03:42 -1000 Subject: [PATCH 253/302] [wl_134] Combine log statements to reduce loop blocking (#12933) --- esphome/components/wl_134/wl_134.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/esphome/components/wl_134/wl_134.cpp b/esphome/components/wl_134/wl_134.cpp index 403f8bd1b3..20a145d183 100644 --- a/esphome/components/wl_134/wl_134.cpp +++ b/esphome/components/wl_134/wl_134.cpp @@ -68,12 +68,15 @@ Wl134Component::Rfid134Error Wl134Component::read_packet_() { reading.reserved1 = this->hex_lsb_ascii_to_uint64_(&(packet[RFID134_PACKET_RESERVED1]), RFID134_PACKET_CHECKSUM - RFID134_PACKET_RESERVED1); - ESP_LOGV(TAG, "Tag id: %012lld", reading.id); - ESP_LOGV(TAG, "Country: %03d", reading.country); - ESP_LOGV(TAG, "isData: %s", reading.isData ? "true" : "false"); - ESP_LOGV(TAG, "isAnimal: %s", reading.isAnimal ? "true" : "false"); - ESP_LOGV(TAG, "Reserved0: %d", reading.reserved0); - ESP_LOGV(TAG, "Reserved1: %" PRId32, reading.reserved1); + ESP_LOGV(TAG, + "Tag id: %012lld\n" + "Country: %03d\n" + "isData: %s\n" + "isAnimal: %s\n" + "Reserved0: %d\n" + "Reserved1: %" PRId32, + reading.id, reading.country, reading.isData ? "true" : "false", reading.isAnimal ? "true" : "false", + reading.reserved0, reading.reserved1); char buf[20]; sprintf(buf, "%03d%012lld", reading.country, reading.id); From b291f359ae6656ed585dc288fb645a87e20898e3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:03:56 -1000 Subject: [PATCH 254/302] [x9c] Combine log statements to reduce loop blocking (#12934) --- esphome/components/x9c/x9c.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/x9c/x9c.cpp b/esphome/components/x9c/x9c.cpp index 5cd4fba8c0..8f66c46015 100644 --- a/esphome/components/x9c/x9c.cpp +++ b/esphome/components/x9c/x9c.cpp @@ -62,14 +62,14 @@ void X9cOutput::write_state(float state) { } void X9cOutput::dump_config() { - ESP_LOGCONFIG(TAG, "X9C Potentiometer Output:"); - LOG_PIN(" Chip Select Pin: ", this->cs_pin_); - LOG_PIN(" Increment Pin: ", this->inc_pin_); - LOG_PIN(" Up/Down Pin: ", this->ud_pin_); ESP_LOGCONFIG(TAG, + "X9C Potentiometer Output:\n" " Initial Value: %f\n" " Step Delay: %d", this->initial_value_, this->step_delay_); + LOG_PIN(" Chip Select Pin: ", this->cs_pin_); + LOG_PIN(" Increment Pin: ", this->inc_pin_); + LOG_PIN(" Up/Down Pin: ", this->ud_pin_); LOG_FLOAT_OUTPUT(this); } From 9ed107bc331af53665381551d2f7546b3c33f022 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:04:08 -1000 Subject: [PATCH 255/302] [xgzp68xx] Combine log statements to reduce loop blocking (#12935) --- esphome/components/xgzp68xx/xgzp68xx.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/xgzp68xx/xgzp68xx.cpp b/esphome/components/xgzp68xx/xgzp68xx.cpp index 2b0824de0a..b5b786c105 100644 --- a/esphome/components/xgzp68xx/xgzp68xx.cpp +++ b/esphome/components/xgzp68xx/xgzp68xx.cpp @@ -72,8 +72,10 @@ void XGZP68XXComponent::update() { temperature_raw = encode_uint16(data[3], data[4]); // Convert the pressure data to hPa - ESP_LOGV(TAG, "Got raw pressure=%" PRIu32 ", raw temperature=%u", pressure_raw, temperature_raw); - ESP_LOGV(TAG, "K value is %u", this->k_value_); + ESP_LOGV(TAG, + "Got raw pressure=%" PRIu32 ", raw temperature=%u\n" + "K value is %u", + pressure_raw, temperature_raw, this->k_value_); // Sign extend the pressure float pressure_in_pa = (float) (((int32_t) pressure_raw << 8) >> 8); From 7fde110ac5125de0ff6da54b7010b662b2e6b7c0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:04:22 -1000 Subject: [PATCH 256/302] [voice_assistant] Combine log statements to reduce loop blocking (#12930) --- .../voice_assistant/voice_assistant.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/esphome/components/voice_assistant/voice_assistant.cpp b/esphome/components/voice_assistant/voice_assistant.cpp index 8101d210b3..de683113bb 100644 --- a/esphome/components/voice_assistant/voice_assistant.cpp +++ b/esphome/components/voice_assistant/voice_assistant.cpp @@ -429,10 +429,12 @@ void VoiceAssistant::client_subscription(api::APIConnection *client, bool subscr } if (this->api_client_ != nullptr) { - ESP_LOGE(TAG, "Multiple API Clients attempting to connect to Voice Assistant"); - ESP_LOGE(TAG, "Current client: %s (%s)", this->api_client_->get_name().c_str(), - this->api_client_->get_peername().c_str()); - ESP_LOGE(TAG, "New client: %s (%s)", client->get_name().c_str(), client->get_peername().c_str()); + ESP_LOGE(TAG, + "Multiple API Clients attempting to connect to Voice Assistant\n" + "Current client: %s (%s)\n" + "New client: %s (%s)", + this->api_client_->get_name().c_str(), this->api_client_->get_peername().c_str(), + client->get_name().c_str(), client->get_peername().c_str()); return; } @@ -864,9 +866,11 @@ void VoiceAssistant::on_timer_event(const api::VoiceAssistantTimerEventResponse .is_active = msg.is_active, }; this->timers_[timer.id] = timer; - ESP_LOGD(TAG, "Timer Event"); - ESP_LOGD(TAG, " Type: %" PRId32, msg.event_type); - ESP_LOGD(TAG, " %s", timer.to_string().c_str()); + ESP_LOGD(TAG, + "Timer Event\n" + " Type: %" PRId32 "\n" + " %s", + msg.event_type, timer.to_string().c_str()); switch (msg.event_type) { case api::enums::VOICE_ASSISTANT_TIMER_STARTED: From 7309a651671e6b76ded484ea238adb41908a6146 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:11:08 -1000 Subject: [PATCH 257/302] [tlc5971] Combine log statements to reduce loop blocking (#12922) --- esphome/components/tlc5971/tlc5971.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/tlc5971/tlc5971.cpp b/esphome/components/tlc5971/tlc5971.cpp index 719ab7c2b3..be17780f8c 100644 --- a/esphome/components/tlc5971/tlc5971.cpp +++ b/esphome/components/tlc5971/tlc5971.cpp @@ -15,10 +15,12 @@ void TLC5971::setup() { this->pwm_amounts_.resize(this->num_chips_ * N_CHANNELS_PER_CHIP, 0); } void TLC5971::dump_config() { - ESP_LOGCONFIG(TAG, "TLC5971:"); + ESP_LOGCONFIG(TAG, + "TLC5971:\n" + " Number of chips: %u", + this->num_chips_); LOG_PIN(" Data Pin: ", this->data_pin_); LOG_PIN(" Clock Pin: ", this->clock_pin_); - ESP_LOGCONFIG(TAG, " Number of chips: %u", this->num_chips_); } void TLC5971::loop() { From a37d4b17eb66e8e96d252fc330e1d4b267a34dec Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:11:48 -1000 Subject: [PATCH 258/302] [wifi] Combine log statements to reduce loop blocking (#12939) --- esphome/components/wifi/wifi_component.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index ca7b1ba9cc..ba25bc9f76 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -932,19 +932,21 @@ void WiFiComponent::print_connect_params_() { char gateway_buf[network::IP_ADDRESS_BUFFER_SIZE]; char dns1_buf[network::IP_ADDRESS_BUFFER_SIZE]; char dns2_buf[network::IP_ADDRESS_BUFFER_SIZE]; + // clang-format off ESP_LOGCONFIG(TAG, " SSID: " LOG_SECRET("'%s'") "\n" - " BSSID: " LOG_SECRET("%s") "\n" - " Hostname: '%s'\n" - " Signal strength: %d dB %s\n" - " Channel: %" PRId32 "\n" - " Subnet: %s\n" - " Gateway: %s\n" - " DNS1: %s\n" - " DNS2: %s", + " BSSID: " LOG_SECRET("%s") "\n" + " Hostname: '%s'\n" + " Signal strength: %d dB %s\n" + " Channel: %" PRId32 "\n" + " Subnet: %s\n" + " Gateway: %s\n" + " DNS1: %s\n" + " DNS2: %s", wifi_ssid_to(ssid_buf), bssid_s, App.get_name().c_str(), rssi, LOG_STR_ARG(get_signal_bars(rssi)), get_wifi_channel(), wifi_subnet_mask_().str_to(subnet_buf), wifi_gateway_ip_().str_to(gateway_buf), wifi_dns_ip_(0).str_to(dns1_buf), wifi_dns_ip_(1).str_to(dns2_buf)); + // clang-format on #ifdef ESPHOME_LOG_HAS_VERBOSE if (const WiFiAP *config = this->get_selected_sta_(); config && config->has_bssid()) { ESP_LOGV(TAG, " Priority: %d", this->get_sta_priority(config->get_bssid())); From 850f18922595650c223cc856887e0639fe94d756 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 13:44:49 -1000 Subject: [PATCH 259/302] [api] Fix message batch size mismatch and improve naming consistency (#12940) --- esphome/components/api/api_connection.cpp | 32 +++++++------- esphome/components/api/api_connection.h | 11 ++--- esphome/components/api/api_frame_helper.h | 23 +++++----- .../components/api/api_frame_helper_noise.cpp | 44 +++++++++---------- .../components/api/api_frame_helper_noise.h | 2 +- .../api/api_frame_helper_plaintext.cpp | 37 ++++++++-------- .../api/api_frame_helper_plaintext.h | 2 +- esphome/core/helpers.h | 4 ++ 8 files changed, 76 insertions(+), 79 deletions(-) diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 3ded5e4408..b173ebc8cb 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -1874,9 +1874,9 @@ bool APIConnection::schedule_batch_() { } void APIConnection::process_batch_() { - // Ensure PacketInfo remains trivially destructible for our placement new approach - static_assert(std::is_trivially_destructible::value, - "PacketInfo must remain trivially destructible with this placement-new approach"); + // Ensure MessageInfo remains trivially destructible for our placement new approach + static_assert(std::is_trivially_destructible::value, + "MessageInfo must remain trivially destructible with this placement-new approach"); if (this->deferred_batch_.empty()) { this->flags_.batch_scheduled = false; @@ -1916,12 +1916,12 @@ void APIConnection::process_batch_() { return; } - size_t packets_to_process = std::min(num_items, MAX_PACKETS_PER_BATCH); + size_t messages_to_process = std::min(num_items, MAX_MESSAGES_PER_BATCH); - // Stack-allocated array for packet info - alignas(PacketInfo) char packet_info_storage[MAX_PACKETS_PER_BATCH * sizeof(PacketInfo)]; - PacketInfo *packet_info = reinterpret_cast(packet_info_storage); - size_t packet_count = 0; + // Stack-allocated array for message info + alignas(MessageInfo) char message_info_storage[MAX_MESSAGES_PER_BATCH * sizeof(MessageInfo)]; + MessageInfo *message_info = reinterpret_cast(message_info_storage); + size_t message_count = 0; // Cache these values to avoid repeated virtual calls const uint8_t header_padding = this->helper_->frame_header_padding(); @@ -1952,7 +1952,7 @@ void APIConnection::process_batch_() { uint32_t current_offset = 0; // Process items and encode directly to buffer (up to our limit) - for (size_t i = 0; i < packets_to_process; i++) { + for (size_t i = 0; i < messages_to_process; i++) { const auto &item = this->deferred_batch_[i]; // Try to encode message // The creator will calculate overhead to determine if the message fits @@ -1966,11 +1966,11 @@ void APIConnection::process_batch_() { // Message was encoded successfully // payload_size is header_padding + actual payload size + footer_size uint16_t proto_payload_size = payload_size - header_padding - footer_size; - // Use placement new to construct PacketInfo in pre-allocated stack array - // This avoids default-constructing all MAX_PACKETS_PER_BATCH elements - // Explicit destruction is not needed because PacketInfo is trivially destructible, + // Use placement new to construct MessageInfo in pre-allocated stack array + // This avoids default-constructing all MAX_MESSAGES_PER_BATCH elements + // Explicit destruction is not needed because MessageInfo is trivially destructible, // as ensured by the static_assert in its definition. - new (&packet_info[packet_count++]) PacketInfo(item.message_type, current_offset, proto_payload_size); + new (&message_info[message_count++]) MessageInfo(item.message_type, current_offset, proto_payload_size); // Update tracking variables items_processed++; @@ -1994,9 +1994,9 @@ void APIConnection::process_batch_() { shared_buf.resize(shared_buf.size() + footer_size); } - // Send all collected packets - APIError err = this->helper_->write_protobuf_packets(ProtoWriteBuffer{&shared_buf}, - std::span(packet_info, packet_count)); + // Send all collected messages + APIError err = this->helper_->write_protobuf_messages(ProtoWriteBuffer{&shared_buf}, + std::span(message_info, message_count)); if (err != APIError::OK && err != APIError::WOULD_BLOCK) { this->fatal_error_with_log_(LOG_STR("Batch write failed"), err); } diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index ffe3614f20..cffd52bfdb 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -28,14 +28,9 @@ static constexpr uint32_t KEEPALIVE_TIMEOUT_MS = 60000; // TODO: Remove MAX_INITIAL_PER_BATCH_LEGACY before 2026.7.0 - all clients should support API 1.14 by then static constexpr size_t MAX_INITIAL_PER_BATCH_LEGACY = 24; // For clients < API 1.14 (includes object_id) static constexpr size_t MAX_INITIAL_PER_BATCH = 34; // For clients >= API 1.14 (no object_id) -// Maximum number of packets to process in a single batch (platform-dependent) -// This limit exists to prevent stack overflow from the PacketInfo array in process_batch_ -// Each PacketInfo is 8 bytes, so 64 * 8 = 512 bytes, 32 * 8 = 256 bytes -#if defined(USE_ESP32) || defined(USE_HOST) -static constexpr size_t MAX_PACKETS_PER_BATCH = 64; // ESP32 has 8KB+ stack, HOST has plenty -#else -static constexpr size_t MAX_PACKETS_PER_BATCH = 32; // ESP8266/RP2040/etc have smaller stacks -#endif +// Verify MAX_MESSAGES_PER_BATCH (defined in api_frame_helper.h) can hold the initial batch +static_assert(MAX_MESSAGES_PER_BATCH >= MAX_INITIAL_PER_BATCH, + "MAX_MESSAGES_PER_BATCH must be >= MAX_INITIAL_PER_BATCH"); class APIConnection final : public APIServerConnection { public: diff --git a/esphome/components/api/api_frame_helper.h b/esphome/components/api/api_frame_helper.h index b582bcea9a..383e763e6d 100644 --- a/esphome/components/api/api_frame_helper.h +++ b/esphome/components/api/api_frame_helper.h @@ -29,6 +29,10 @@ static constexpr uint16_t MAX_MESSAGE_SIZE = 8192; // 8 KiB for ESP8266 static constexpr uint16_t MAX_MESSAGE_SIZE = 32768; // 32 KiB for ESP32 and other platforms #endif +// Maximum number of messages to batch in a single write operation +// Must be >= MAX_INITIAL_PER_BATCH in api_connection.h (enforced by static_assert there) +static constexpr size_t MAX_MESSAGES_PER_BATCH = 34; + // Forward declaration struct ClientInfo; @@ -40,13 +44,13 @@ struct ReadPacketBuffer { uint16_t type; }; -// Packed packet info structure to minimize memory usage -struct PacketInfo { +// Packed message info structure to minimize memory usage +struct MessageInfo { uint16_t offset; // Offset in buffer where message starts uint16_t payload_size; // Size of the message payload uint8_t message_type; // Message type (0-255) - PacketInfo(uint8_t type, uint16_t off, uint16_t size) : offset(off), payload_size(size), message_type(type) {} + MessageInfo(uint8_t type, uint16_t off, uint16_t size) : offset(off), payload_size(size), message_type(type) {} }; enum class APIError : uint16_t { @@ -108,10 +112,10 @@ class APIFrameHelper { return APIError::OK; } virtual APIError write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) = 0; - // Write multiple protobuf packets in a single operation - // packets contains (message_type, offset, length) for each message in the buffer + // Write multiple protobuf messages in a single operation + // messages contains (message_type, offset, length) for each message in the buffer // The buffer contains all messages with appropriate padding before each - virtual APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span packets) = 0; + virtual APIError write_protobuf_messages(ProtoWriteBuffer buffer, std::span messages) = 0; // Get the frame header padding required by this protocol uint8_t frame_header_padding() const { return frame_header_padding_; } // Get the frame footer size required by this protocol @@ -127,12 +131,6 @@ class APIFrameHelper { // Use swap trick since shrink_to_fit() is non-binding and may be ignored std::vector().swap(this->rx_buf_); } - // reusable_iovs_: Safe to release unconditionally. - // Only used within write_protobuf_packets() calls - cleared at start, - // populated with pointers, used for writev(), then function returns. - // The iovecs contain stale pointers after the call (data was either sent - // or copied to tx_buf_), and are cleared on next write_protobuf_packets(). - std::vector().swap(this->reusable_iovs_); } protected: @@ -186,7 +184,6 @@ class APIFrameHelper { // Containers (size varies, but typically 12+ bytes on 32-bit) std::array, API_MAX_SEND_QUEUE> tx_buf_; - std::vector reusable_iovs_; std::vector rx_buf_; // Pointer to client info (4 bytes on 32-bit) diff --git a/esphome/components/api/api_frame_helper_noise.cpp b/esphome/components/api/api_frame_helper_noise.cpp index 37b497e2a1..be8d93fbf9 100644 --- a/esphome/components/api/api_frame_helper_noise.cpp +++ b/esphome/components/api/api_frame_helper_noise.cpp @@ -429,12 +429,12 @@ APIError APINoiseFrameHelper::read_packet(ReadPacketBuffer *buffer) { APIError APINoiseFrameHelper::write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) { // Resize to include MAC space (required for Noise encryption) buffer.get_buffer()->resize(buffer.get_buffer()->size() + frame_footer_size_); - PacketInfo packet{type, 0, - static_cast(buffer.get_buffer()->size() - frame_header_padding_ - frame_footer_size_)}; - return write_protobuf_packets(buffer, std::span(&packet, 1)); + MessageInfo msg{type, 0, + static_cast(buffer.get_buffer()->size() - frame_header_padding_ - frame_footer_size_)}; + return write_protobuf_messages(buffer, std::span(&msg, 1)); } -APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, std::span packets) { +APIError APINoiseFrameHelper::write_protobuf_messages(ProtoWriteBuffer buffer, std::span messages) { APIError aerr = state_action_(); if (aerr != APIError::OK) { return aerr; @@ -444,20 +444,20 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, st return APIError::WOULD_BLOCK; } - if (packets.empty()) { + if (messages.empty()) { return APIError::OK; } uint8_t *buffer_data = buffer.get_buffer()->data(); - this->reusable_iovs_.clear(); - this->reusable_iovs_.reserve(packets.size()); + // Stack-allocated iovec array - no heap allocation + StaticVector iovs; uint16_t total_write_len = 0; - // We need to encrypt each packet in place - for (const auto &packet : packets) { + // We need to encrypt each message in place + for (const auto &msg : messages) { // The buffer already has padding at offset - uint8_t *buf_start = buffer_data + packet.offset; + uint8_t *buf_start = buffer_data + msg.offset; // Write noise header buf_start[0] = 0x01; // indicator @@ -465,10 +465,10 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, st // Write message header (to be encrypted) const uint8_t msg_offset = 3; - buf_start[msg_offset] = static_cast(packet.message_type >> 8); // type high byte - buf_start[msg_offset + 1] = static_cast(packet.message_type); // type low byte - buf_start[msg_offset + 2] = static_cast(packet.payload_size >> 8); // data_len high byte - buf_start[msg_offset + 3] = static_cast(packet.payload_size); // data_len low byte + buf_start[msg_offset] = static_cast(msg.message_type >> 8); // type high byte + buf_start[msg_offset + 1] = static_cast(msg.message_type); // type low byte + buf_start[msg_offset + 2] = static_cast(msg.payload_size >> 8); // data_len high byte + buf_start[msg_offset + 3] = static_cast(msg.payload_size); // data_len low byte // payload data is already in the buffer starting at offset + 7 // Make sure we have space for MAC @@ -477,8 +477,8 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, st // Encrypt the message in place NoiseBuffer mbuf; noise_buffer_init(mbuf); - noise_buffer_set_inout(mbuf, buf_start + msg_offset, 4 + packet.payload_size, - 4 + packet.payload_size + frame_footer_size_); + noise_buffer_set_inout(mbuf, buf_start + msg_offset, 4 + msg.payload_size, + 4 + msg.payload_size + frame_footer_size_); int err = noise_cipherstate_encrypt(send_cipher_, &mbuf); APIError aerr = @@ -490,14 +490,14 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, st buf_start[1] = static_cast(mbuf.size >> 8); buf_start[2] = static_cast(mbuf.size); - // Add iovec for this encrypted packet - size_t packet_len = static_cast(3 + mbuf.size); // indicator + size + encrypted data - this->reusable_iovs_.push_back({buf_start, packet_len}); - total_write_len += packet_len; + // Add iovec for this encrypted message + size_t msg_len = static_cast(3 + mbuf.size); // indicator + size + encrypted data + iovs.push_back({buf_start, msg_len}); + total_write_len += msg_len; } - // Send all encrypted packets in one writev call - return this->write_raw_(this->reusable_iovs_.data(), this->reusable_iovs_.size(), total_write_len); + // Send all encrypted messages in one writev call + return this->write_raw_(iovs.data(), iovs.size(), total_write_len); } APIError APINoiseFrameHelper::write_frame_(const uint8_t *data, uint16_t len) { diff --git a/esphome/components/api/api_frame_helper_noise.h b/esphome/components/api/api_frame_helper_noise.h index 7eb01058db..1268086194 100644 --- a/esphome/components/api/api_frame_helper_noise.h +++ b/esphome/components/api/api_frame_helper_noise.h @@ -23,7 +23,7 @@ class APINoiseFrameHelper final : public APIFrameHelper { APIError loop() override; APIError read_packet(ReadPacketBuffer *buffer) override; APIError write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) override; - APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span packets) override; + APIError write_protobuf_messages(ProtoWriteBuffer buffer, std::span messages) override; protected: APIError state_action_(); diff --git a/esphome/components/api/api_frame_helper_plaintext.cpp b/esphome/components/api/api_frame_helper_plaintext.cpp index 8b7d002d7c..a974a2458e 100644 --- a/esphome/components/api/api_frame_helper_plaintext.cpp +++ b/esphome/components/api/api_frame_helper_plaintext.cpp @@ -230,29 +230,30 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) { return APIError::OK; } APIError APIPlaintextFrameHelper::write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) { - PacketInfo packet{type, 0, static_cast(buffer.get_buffer()->size() - frame_header_padding_)}; - return write_protobuf_packets(buffer, std::span(&packet, 1)); + MessageInfo msg{type, 0, static_cast(buffer.get_buffer()->size() - frame_header_padding_)}; + return write_protobuf_messages(buffer, std::span(&msg, 1)); } -APIError APIPlaintextFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, std::span packets) { +APIError APIPlaintextFrameHelper::write_protobuf_messages(ProtoWriteBuffer buffer, + std::span messages) { if (state_ != State::DATA) { return APIError::BAD_STATE; } - if (packets.empty()) { + if (messages.empty()) { return APIError::OK; } uint8_t *buffer_data = buffer.get_buffer()->data(); - this->reusable_iovs_.clear(); - this->reusable_iovs_.reserve(packets.size()); + // Stack-allocated iovec array - no heap allocation + StaticVector iovs; uint16_t total_write_len = 0; - for (const auto &packet : packets) { + for (const auto &msg : messages) { // Calculate varint sizes for header layout - uint8_t size_varint_len = api::ProtoSize::varint(static_cast(packet.payload_size)); - uint8_t type_varint_len = api::ProtoSize::varint(static_cast(packet.message_type)); + uint8_t size_varint_len = api::ProtoSize::varint(static_cast(msg.payload_size)); + uint8_t type_varint_len = api::ProtoSize::varint(static_cast(msg.message_type)); uint8_t total_header_len = 1 + size_varint_len + type_varint_len; // Calculate where to start writing the header @@ -280,25 +281,25 @@ APIError APIPlaintextFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer // // The message starts at offset + frame_header_padding_ // So we write the header starting at offset + frame_header_padding_ - total_header_len - uint8_t *buf_start = buffer_data + packet.offset; + uint8_t *buf_start = buffer_data + msg.offset; uint32_t header_offset = frame_header_padding_ - total_header_len; // Write the plaintext header buf_start[header_offset] = 0x00; // indicator // Encode varints directly into buffer - ProtoVarInt(packet.payload_size).encode_to_buffer_unchecked(buf_start + header_offset + 1, size_varint_len); - ProtoVarInt(packet.message_type) + ProtoVarInt(msg.payload_size).encode_to_buffer_unchecked(buf_start + header_offset + 1, size_varint_len); + ProtoVarInt(msg.message_type) .encode_to_buffer_unchecked(buf_start + header_offset + 1 + size_varint_len, type_varint_len); - // Add iovec for this packet (header + payload) - size_t packet_len = static_cast(total_header_len + packet.payload_size); - this->reusable_iovs_.push_back({buf_start + header_offset, packet_len}); - total_write_len += packet_len; + // Add iovec for this message (header + payload) + size_t msg_len = static_cast(total_header_len + msg.payload_size); + iovs.push_back({buf_start + header_offset, msg_len}); + total_write_len += msg_len; } - // Send all packets in one writev call - return write_raw_(this->reusable_iovs_.data(), this->reusable_iovs_.size(), total_write_len); + // Send all messages in one writev call + return write_raw_(iovs.data(), iovs.size(), total_write_len); } } // namespace esphome::api diff --git a/esphome/components/api/api_frame_helper_plaintext.h b/esphome/components/api/api_frame_helper_plaintext.h index bba981d26b..7af9fc64b9 100644 --- a/esphome/components/api/api_frame_helper_plaintext.h +++ b/esphome/components/api/api_frame_helper_plaintext.h @@ -21,7 +21,7 @@ class APIPlaintextFrameHelper final : public APIFrameHelper { APIError loop() override; APIError read_packet(ReadPacketBuffer *buffer) override; APIError write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) override; - APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span packets) override; + APIError write_protobuf_messages(ProtoWriteBuffer buffer, std::span messages) override; protected: APIError try_read_frame_(); diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index f7a14ed2ec..6c338797a9 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -162,6 +162,10 @@ template class StaticVector { size_t size() const { return count_; } bool empty() const { return count_ == 0; } + // Direct access to underlying data + T *data() { return data_.data(); } + const T *data() const { return data_.data(); } + T &operator[](size_t i) { return data_[i]; } const T &operator[](size_t i) const { return data_[i]; } From f41f0506c1df3f452268b6a5b3e957ec48321a60 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 14:05:17 -1000 Subject: [PATCH 260/302] [pcf8574] Combine log statements to reduce loop blocking (#12941) --- esphome/components/pcf8574/pcf8574.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/pcf8574/pcf8574.cpp b/esphome/components/pcf8574/pcf8574.cpp index 15418bfee5..8bdd312ab9 100644 --- a/esphome/components/pcf8574/pcf8574.cpp +++ b/esphome/components/pcf8574/pcf8574.cpp @@ -21,9 +21,11 @@ void PCF8574Component::loop() { this->reset_pin_cache_(); } void PCF8574Component::dump_config() { - ESP_LOGCONFIG(TAG, "PCF8574:"); + ESP_LOGCONFIG(TAG, + "PCF8574:\n" + " Is PCF8575: %s", + YESNO(this->pcf8575_)); LOG_I2C_DEVICE(this) - ESP_LOGCONFIG(TAG, " Is PCF8575: %s", YESNO(this->pcf8575_)); if (this->is_failed()) { ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL); } From 6c809583d386e65a0828aee9bdb06aff7f09d20f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 14:45:22 -1000 Subject: [PATCH 261/302] [qspi_dbi] Combine log statements to reduce loop blocking (#12948) Co-authored-by: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- esphome/components/qspi_dbi/qspi_dbi.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/esphome/components/qspi_dbi/qspi_dbi.cpp b/esphome/components/qspi_dbi/qspi_dbi.cpp index 00a4a375eb..d42f95dca3 100644 --- a/esphome/components/qspi_dbi/qspi_dbi.cpp +++ b/esphome/components/qspi_dbi/qspi_dbi.cpp @@ -216,12 +216,14 @@ void QspiDbi::write_sequence_(const std::vector &vec) { void QspiDbi::dump_config() { ESP_LOGCONFIG("", "QSPI_DBI Display"); ESP_LOGCONFIG("", "Model: %s", this->model_); - ESP_LOGCONFIG(TAG, " Height: %u", this->height_); - ESP_LOGCONFIG(TAG, " Width: %u", this->width_); - ESP_LOGCONFIG(TAG, " Draw rounding: %u", this->draw_rounding_); + ESP_LOGCONFIG(TAG, + " Height: %u\n" + " Width: %u\n" + " Draw rounding: %u\n" + " SPI Data rate: %uMHz", + this->height_, this->width_, this->draw_rounding_, (unsigned) (this->data_rate_ / 1000000)); LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" Reset Pin: ", this->reset_pin_); - ESP_LOGCONFIG(TAG, " SPI Data rate: %dMHz", (unsigned) (this->data_rate_ / 1000000)); } } // namespace qspi_dbi From 50f27cdd77eaeb66274d28d87e4971aeb91c5260 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 14:45:38 -1000 Subject: [PATCH 262/302] [pn7160] Combine log statements to reduce loop blocking (#12945) --- esphome/components/pn7160/pn7160.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/esphome/components/pn7160/pn7160.cpp b/esphome/components/pn7160/pn7160.cpp index a8edfadd8e..8c8028b04a 100644 --- a/esphome/components/pn7160/pn7160.cpp +++ b/esphome/components/pn7160/pn7160.cpp @@ -262,9 +262,12 @@ uint8_t PN7160::reset_core_(const bool reset_config, const bool power) { return nfc::STATUS_FAILED; } - ESP_LOGD(TAG, "Configuration %s", rx.get_message()[4] ? "reset" : "retained"); - ESP_LOGD(TAG, "NCI version: %s", rx.get_message()[5] == 0x20 ? "2.0" : "1.0"); - ESP_LOGD(TAG, "Manufacturer ID: 0x%02X", rx.get_message()[6]); + ESP_LOGD(TAG, + "Configuration %s\n" + "NCI version: %s\n" + "Manufacturer ID: 0x%02X", + rx.get_message()[4] ? "reset" : "retained", rx.get_message()[5] == 0x20 ? "2.0" : "1.0", + rx.get_message()[6]); rx.get_message().erase(rx.get_message().begin(), rx.get_message().begin() + 8); ESP_LOGD(TAG, "Manufacturer info: %s", nfc::format_bytes(rx.get_message()).c_str()); @@ -291,11 +294,13 @@ uint8_t PN7160::init_core_() { uint8_t flash_minor_version = rx.get_message()[20 + rx.get_message()[8]]; std::vector features(rx.get_message().begin() + 4, rx.get_message().begin() + 8); - ESP_LOGD(TAG, "Hardware version: %u", hw_version); - ESP_LOGD(TAG, "ROM code version: %u", rom_code_version); - ESP_LOGD(TAG, "FLASH major version: %u", flash_major_version); - ESP_LOGD(TAG, "FLASH minor version: %u", flash_minor_version); - ESP_LOGD(TAG, "Features: %s", nfc::format_bytes(features).c_str()); + ESP_LOGD(TAG, + "Hardware version: %u\n" + "ROM code version: %u\n" + "FLASH major version: %u\n" + "FLASH minor version: %u\n" + "Features: %s", + hw_version, rom_code_version, flash_major_version, flash_minor_version, nfc::format_bytes(features).c_str()); return rx.get_simple_status_response(); } @@ -871,8 +876,8 @@ void PN7160::process_rf_intf_activated_oid_(nfc::NciMessage &rx) { // an endpoi case EP_WRITE: if (this->next_task_message_to_write_ != nullptr) { - ESP_LOGD(TAG, " Tag writing"); - ESP_LOGD(TAG, " Tag formatting"); + ESP_LOGD(TAG, " Tag writing\n" + " Tag formatting"); if (this->format_endpoint_(working_endpoint.tag->get_uid()) != nfc::STATUS_OK) { ESP_LOGE(TAG, " Tag could not be formatted for writing"); } else { From 6d8142c539b8b12baf43e8281d680112fa791ef9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 14:45:52 -1000 Subject: [PATCH 263/302] [rpi_dpi_rgb] Combine log statements to reduce loop blocking (#12953) --- esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp b/esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp index 042b8877e6..a81bb17dfc 100644 --- a/esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +++ b/esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp @@ -126,8 +126,10 @@ void RpiDpiRgb::draw_pixel_at(int x, int y, Color color) { void RpiDpiRgb::dump_config() { ESP_LOGCONFIG("", "RPI_DPI_RGB LCD"); - ESP_LOGCONFIG(TAG, " Height: %u", this->height_); - ESP_LOGCONFIG(TAG, " Width: %u", this->width_); + ESP_LOGCONFIG(TAG, + " Height: %u\n" + " Width: %u", + this->height_, this->width_); LOG_PIN(" DE Pin: ", this->de_pin_); LOG_PIN(" Enable Pin: ", this->enable_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_); From 2d8abbb2ac81093474021f0a68d2610242231723 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 14:46:09 -1000 Subject: [PATCH 264/302] [pn7150] Combine log statements to reduce loop blocking (#12944) --- esphome/components/pn7150/pn7150.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/esphome/components/pn7150/pn7150.cpp b/esphome/components/pn7150/pn7150.cpp index f827bd151a..f6ddcb0767 100644 --- a/esphome/components/pn7150/pn7150.cpp +++ b/esphome/components/pn7150/pn7150.cpp @@ -240,8 +240,11 @@ uint8_t PN7150::reset_core_(const bool reset_config, const bool power) { return nfc::STATUS_FAILED; } - ESP_LOGD(TAG, "Configuration %s", rx.get_message()[nfc::NCI_PKT_PAYLOAD_OFFSET + 2] ? "reset" : "retained"); - ESP_LOGD(TAG, "NCI version: %s", rx.get_message()[nfc::NCI_PKT_PAYLOAD_OFFSET + 1] == 0x20 ? "2.0" : "1.0"); + ESP_LOGD(TAG, + "Configuration %s\n" + "NCI version: %s", + rx.get_message()[nfc::NCI_PKT_PAYLOAD_OFFSET + 2] ? "reset" : "retained", + rx.get_message()[nfc::NCI_PKT_PAYLOAD_OFFSET + 1] == 0x20 ? "2.0" : "1.0"); return nfc::STATUS_OK; } @@ -266,11 +269,13 @@ uint8_t PN7150::init_core_() { uint8_t flash_major_version = rx.get_message()[18 + rx.get_message()[8]]; uint8_t flash_minor_version = rx.get_message()[19 + rx.get_message()[8]]; - ESP_LOGD(TAG, "Manufacturer ID: 0x%02X", manf_id); - ESP_LOGD(TAG, "Hardware version: 0x%02X", hw_version); - ESP_LOGD(TAG, "ROM code version: 0x%02X", rom_code_version); - ESP_LOGD(TAG, "FLASH major version: 0x%02X", flash_major_version); - ESP_LOGD(TAG, "FLASH minor version: 0x%02X", flash_minor_version); + ESP_LOGD(TAG, + "Manufacturer ID: 0x%02X\n" + "Hardware version: 0x%02X\n" + "ROM code version: 0x%02X\n" + "FLASH major version: 0x%02X\n" + "FLASH minor version: 0x%02X", + manf_id, hw_version, rom_code_version, flash_major_version, flash_minor_version); return rx.get_simple_status_response(); } @@ -847,8 +852,8 @@ void PN7150::process_rf_intf_activated_oid_(nfc::NciMessage &rx) { // an endpoi case EP_WRITE: if (this->next_task_message_to_write_ != nullptr) { - ESP_LOGD(TAG, " Tag writing"); - ESP_LOGD(TAG, " Tag formatting"); + ESP_LOGD(TAG, " Tag writing\n" + " Tag formatting"); if (this->format_endpoint_(working_endpoint.tag->get_uid()) != nfc::STATUS_OK) { ESP_LOGE(TAG, " Tag could not be formatted for writing"); } else { From 0b9fcf9ed375f63b2f2bbcfdfdf107961b463eca Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 14:46:21 -1000 Subject: [PATCH 265/302] [pn532] Combine log statements to reduce loop blocking (#12943) --- esphome/components/pn532/pn532.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/pn532/pn532.cpp b/esphome/components/pn532/pn532.cpp index ef4022db4b..d5e892a576 100644 --- a/esphome/components/pn532/pn532.cpp +++ b/esphome/components/pn532/pn532.cpp @@ -31,8 +31,10 @@ void PN532::setup() { this->mark_failed(); return; } - ESP_LOGD(TAG, "Found chip PN5%02X", version_data[0]); - ESP_LOGD(TAG, "Firmware ver. %d.%d", version_data[1], version_data[2]); + ESP_LOGD(TAG, + "Found chip PN5%02X\n" + "Firmware ver. %d.%d", + version_data[0], version_data[1], version_data[2]); if (!this->write_command_({ PN532_COMMAND_SAMCONFIGURATION, From a635c8283096859221201d1ba11750c7cb185e97 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:04:50 -1000 Subject: [PATCH 266/302] [pid] Combine log statements to reduce loop blocking (#12942) --- esphome/components/pid/pid_autotuner.cpp | 67 ++++++++++++++---------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/esphome/components/pid/pid_autotuner.cpp b/esphome/components/pid/pid_autotuner.cpp index 28d16e17ab..d1d9c200cf 100644 --- a/esphome/components/pid/pid_autotuner.cpp +++ b/esphome/components/pid/pid_autotuner.cpp @@ -138,20 +138,21 @@ PIDAutotuner::PIDAutotuneResult PIDAutotuner::update(float setpoint, float proce } void PIDAutotuner::dump_config() { if (this->state_ == AUTOTUNE_SUCCEEDED) { - ESP_LOGI(TAG, "%s: PID Autotune:", this->id_.c_str()); - ESP_LOGI(TAG, " State: Succeeded!"); + ESP_LOGI(TAG, + "%s: PID Autotune:\n" + " State: Succeeded!", + this->id_.c_str()); bool has_issue = false; if (!this->amplitude_detector_.is_amplitude_convergent()) { - ESP_LOGW(TAG, " Could not reliably determine oscillation amplitude, PID parameters may be inaccurate!"); - ESP_LOGW(TAG, " Please make sure you eliminate all outside influences on the measured temperature."); + ESP_LOGW(TAG, " Could not reliably determine oscillation amplitude, PID parameters may be inaccurate!\n" + " Please make sure you eliminate all outside influences on the measured temperature."); has_issue = true; } if (!this->frequency_detector_.is_increase_decrease_symmetrical()) { - ESP_LOGW(TAG, " Oscillation Frequency is not symmetrical. PID parameters may be inaccurate!"); - ESP_LOGW( - TAG, - " This is usually because the heat and cool processes do not change the temperature at the same rate."); ESP_LOGW(TAG, + " Oscillation Frequency is not symmetrical. PID parameters may be inaccurate!\n" + " This is usually because the heat and cool processes do not change the temperature at the same " + "rate.\n" " Please try reducing the positive_output value (or increase negative_output in case of a cooler)"); has_issue = true; } @@ -160,18 +161,23 @@ void PIDAutotuner::dump_config() { } auto fac = get_ziegler_nichols_pid_(); - ESP_LOGI(TAG, " Calculated PID parameters (\"Ziegler-Nichols PID\" rule):"); - ESP_LOGI(TAG, " "); - ESP_LOGI(TAG, " control_parameters:"); - ESP_LOGI(TAG, " kp: %.5f", fac.kp); - ESP_LOGI(TAG, " ki: %.5f", fac.ki); - ESP_LOGI(TAG, " kd: %.5f", fac.kd); - ESP_LOGI(TAG, " "); - ESP_LOGI(TAG, " Please copy these values into your YAML configuration! They will reset on the next reboot."); + ESP_LOGI(TAG, + " Calculated PID parameters (\"Ziegler-Nichols PID\" rule):\n" + "\n" + " control_parameters:\n" + " kp: %.5f\n" + " ki: %.5f\n" + " kd: %.5f\n" + "\n" + " Please copy these values into your YAML configuration! They will reset on the next reboot.", + fac.kp, fac.ki, fac.kd); - ESP_LOGV(TAG, " Oscillation Period: %f", this->frequency_detector_.get_mean_oscillation_period()); - ESP_LOGV(TAG, " Oscillation Amplitude: %f", this->amplitude_detector_.get_mean_oscillation_amplitude()); - ESP_LOGV(TAG, " Ku: %f, Pu: %f", this->ku_, this->pu_); + ESP_LOGV(TAG, + " Oscillation Period: %f\n" + " Oscillation Amplitude: %f\n" + " Ku: %f, Pu: %f", + this->frequency_detector_.get_mean_oscillation_period(), + this->amplitude_detector_.get_mean_oscillation_amplitude(), this->ku_, this->pu_); ESP_LOGD(TAG, " Alternative Rules:"); // http://www.mstarlabs.com/control/znrule.html @@ -183,13 +189,16 @@ void PIDAutotuner::dump_config() { } if (this->state_ == AUTOTUNE_RUNNING) { - ESP_LOGD(TAG, "%s: PID Autotune:", this->id_.c_str()); - ESP_LOGD(TAG, " Autotune is still running!"); - ESP_LOGD(TAG, " Status: Trying to reach %.2f °C", setpoint_ - relay_function_.current_target_error()); - ESP_LOGD(TAG, " Stats so far:"); - ESP_LOGD(TAG, " Phases: %" PRIu32, relay_function_.phase_count); - ESP_LOGD(TAG, " Detected %zu zero-crossings", frequency_detector_.zerocrossing_intervals.size()); - ESP_LOGD(TAG, " Current Phase Min: %.2f, Max: %.2f", amplitude_detector_.phase_min, + ESP_LOGD(TAG, + "%s: PID Autotune:\n" + " Autotune is still running!\n" + " Status: Trying to reach %.2f °C\n" + " Stats so far:\n" + " Phases: %" PRIu32 "\n" + " Detected %zu zero-crossings\n" + " Current Phase Min: %.2f, Max: %.2f", + this->id_.c_str(), setpoint_ - relay_function_.current_target_error(), relay_function_.phase_count, + frequency_detector_.zerocrossing_intervals.size(), amplitude_detector_.phase_min, amplitude_detector_.phase_max); } } @@ -205,8 +214,10 @@ PIDAutotuner::PIDResult PIDAutotuner::calculate_pid_(float kp_factor, float ki_f } void PIDAutotuner::print_rule_(const char *name, float kp_factor, float ki_factor, float kd_factor) { auto fac = calculate_pid_(kp_factor, ki_factor, kd_factor); - ESP_LOGD(TAG, " Rule '%s':", name); - ESP_LOGD(TAG, " kp: %.5f, ki: %.5f, kd: %.5f", fac.kp, fac.ki, fac.kd); + ESP_LOGD(TAG, + " Rule '%s':\n" + " kp: %.5f, ki: %.5f, kd: %.5f", + name, fac.kp, fac.ki, fac.kd); } // ================== RelayFunction ================== From 3c8fd5c5c0715740e4ef3e346f541c7b9b3d3694 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:05:05 -1000 Subject: [PATCH 267/302] [pulse_counter] Combine log statements to reduce loop blocking (#12946) --- esphome/components/pulse_counter/pulse_counter_sensor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/pulse_counter/pulse_counter_sensor.cpp b/esphome/components/pulse_counter/pulse_counter_sensor.cpp index 6300d6fe96..c0d74cef4a 100644 --- a/esphome/components/pulse_counter/pulse_counter_sensor.cpp +++ b/esphome/components/pulse_counter/pulse_counter_sensor.cpp @@ -68,8 +68,10 @@ bool HwPulseCounterStorage::pulse_counter_setup(InternalGPIOPin *pin) { next_pcnt_channel = pcnt_channel_t(int(next_pcnt_channel) + 1); } - ESP_LOGCONFIG(TAG, " PCNT Unit Number: %u", this->pcnt_unit); - ESP_LOGCONFIG(TAG, " PCNT Channel Number: %u", this->pcnt_channel); + ESP_LOGCONFIG(TAG, + " PCNT Unit Number: %u\n" + " PCNT Channel Number: %u", + this->pcnt_unit, this->pcnt_channel); pcnt_count_mode_t rising = PCNT_COUNT_DIS, falling = PCNT_COUNT_DIS; switch (this->rising_edge_mode) { From e6a630ae647cd3dc60f30023ca5452d569097d0a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:06:34 -1000 Subject: [PATCH 268/302] [qmp6988] Combine log statements to reduce loop blocking (#12947) --- esphome/components/qmp6988/qmp6988.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/esphome/components/qmp6988/qmp6988.cpp b/esphome/components/qmp6988/qmp6988.cpp index 57f54b6432..4e1ef27d5e 100644 --- a/esphome/components/qmp6988/qmp6988.cpp +++ b/esphome/components/qmp6988/qmp6988.cpp @@ -127,9 +127,11 @@ bool QMP6988Component::get_calibration_data_() { qmp6988_data_.qmp6988_cali.COE_b21 = (int16_t) encode_uint16(a_data_uint8_tr[14], a_data_uint8_tr[15]); qmp6988_data_.qmp6988_cali.COE_bp3 = (int16_t) encode_uint16(a_data_uint8_tr[16], a_data_uint8_tr[17]); - ESP_LOGV(TAG, "<-----------calibration data-------------->\r\n"); - ESP_LOGV(TAG, "COE_a0[%d] COE_a1[%d] COE_a2[%d] COE_b00[%d]\r\n", qmp6988_data_.qmp6988_cali.COE_a0, - qmp6988_data_.qmp6988_cali.COE_a1, qmp6988_data_.qmp6988_cali.COE_a2, qmp6988_data_.qmp6988_cali.COE_b00); + ESP_LOGV(TAG, + "<-----------calibration data-------------->\n" + "COE_a0[%d] COE_a1[%d] COE_a2[%d] COE_b00[%d]", + qmp6988_data_.qmp6988_cali.COE_a0, qmp6988_data_.qmp6988_cali.COE_a1, qmp6988_data_.qmp6988_cali.COE_a2, + qmp6988_data_.qmp6988_cali.COE_b00); ESP_LOGV(TAG, "COE_bt1[%d] COE_bt2[%d] COE_bp1[%d] COE_b11[%d]\r\n", qmp6988_data_.qmp6988_cali.COE_bt1, qmp6988_data_.qmp6988_cali.COE_bt2, qmp6988_data_.qmp6988_cali.COE_bp1, qmp6988_data_.qmp6988_cali.COE_b11); ESP_LOGV(TAG, "COE_bp2[%d] COE_b12[%d] COE_b21[%d] COE_bp3[%d]\r\n", qmp6988_data_.qmp6988_cali.COE_bp2, @@ -150,9 +152,10 @@ bool QMP6988Component::get_calibration_data_() { qmp6988_data_.ik.b12 = 6846L * (int64_t) qmp6988_data_.qmp6988_cali.COE_b12 + 85590281L; // 29Q53 qmp6988_data_.ik.b21 = 13836L * (int64_t) qmp6988_data_.qmp6988_cali.COE_b21 + 79333336L; // 29Q60 qmp6988_data_.ik.bp3 = 2915L * (int64_t) qmp6988_data_.qmp6988_cali.COE_bp3 + 157155561L; // 28Q65 - ESP_LOGV(TAG, "<----------- int calibration data -------------->\r\n"); - ESP_LOGV(TAG, "a0[%d] a1[%d] a2[%d] b00[%d]\r\n", qmp6988_data_.ik.a0, qmp6988_data_.ik.a1, qmp6988_data_.ik.a2, - qmp6988_data_.ik.b00); + ESP_LOGV(TAG, + "<----------- int calibration data -------------->\n" + "a0[%d] a1[%d] a2[%d] b00[%d]", + qmp6988_data_.ik.a0, qmp6988_data_.ik.a1, qmp6988_data_.ik.a2, qmp6988_data_.ik.b00); ESP_LOGV(TAG, "bt1[%lld] bt2[%lld] bp1[%lld] b11[%lld]\r\n", qmp6988_data_.ik.bt1, qmp6988_data_.ik.bt2, qmp6988_data_.ik.bp1, qmp6988_data_.ik.b11); ESP_LOGV(TAG, "bp2[%lld] b12[%lld] b21[%lld] bp3[%lld]\r\n", qmp6988_data_.ik.bp2, qmp6988_data_.ik.b12, @@ -330,8 +333,10 @@ void QMP6988Component::dump_config() { LOG_SENSOR(" ", "Temperature", this->temperature_sensor_); ESP_LOGCONFIG(TAG, " Temperature Oversampling: %s", oversampling_to_str(this->temperature_oversampling_)); LOG_SENSOR(" ", "Pressure", this->pressure_sensor_); - ESP_LOGCONFIG(TAG, " Pressure Oversampling: %s", oversampling_to_str(this->pressure_oversampling_)); - ESP_LOGCONFIG(TAG, " IIR Filter: %s", iir_filter_to_str(this->iir_filter_)); + ESP_LOGCONFIG(TAG, + " Pressure Oversampling: %s\n" + " IIR Filter: %s", + oversampling_to_str(this->pressure_oversampling_), iir_filter_to_str(this->iir_filter_)); } void QMP6988Component::update() { From 3ec05a5a13f96855b7c1ba1c207a453dba1992c1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:06:55 -1000 Subject: [PATCH 269/302] [radon_eye_rd200] Combine log statements to reduce loop blocking (#12949) --- esphome/components/radon_eye_rd200/radon_eye_rd200.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/esphome/components/radon_eye_rd200/radon_eye_rd200.cpp b/esphome/components/radon_eye_rd200/radon_eye_rd200.cpp index 3959178b94..3ccb7bf082 100644 --- a/esphome/components/radon_eye_rd200/radon_eye_rd200.cpp +++ b/esphome/components/radon_eye_rd200/radon_eye_rd200.cpp @@ -118,10 +118,11 @@ void RadonEyeRD200::read_sensors_(uint8_t *value, uint16_t value_len) { radon_long_term_sensor_->publish_state(radon_day); } - ESP_LOGV(TAG, " Measurements (Bq/m³) now: %0.03f, day: %0.03f, month: %0.03f", radon_now, radon_day, radon_month); - - ESP_LOGV(TAG, " Measurements (pCi/L) now: %0.03f, day: %0.03f, month: %0.03f", radon_now / convert_to_bwpm3, - radon_day / convert_to_bwpm3, radon_month / convert_to_bwpm3); + ESP_LOGV(TAG, + " Measurements (Bq/m³) now: %0.03f, day: %0.03f, month: %0.03f\n" + " Measurements (pCi/L) now: %0.03f, day: %0.03f, month: %0.03f", + radon_now, radon_day, radon_month, radon_now / convert_to_bwpm3, radon_day / convert_to_bwpm3, + radon_month / convert_to_bwpm3); // This instance must not stay connected // so other clients can connect to it (e.g. the From 44fc156ef6f238b1f9053c719d5f98b8a0df6647 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:07:50 -1000 Subject: [PATCH 270/302] [remote_base] Combine log statements to reduce loop blocking (#12950) --- esphome/components/remote_base/pronto_protocol.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/remote_base/pronto_protocol.cpp b/esphome/components/remote_base/pronto_protocol.cpp index 9fbc9e85ba..401a0976b2 100644 --- a/esphome/components/remote_base/pronto_protocol.cpp +++ b/esphome/components/remote_base/pronto_protocol.cpp @@ -104,8 +104,10 @@ void ProntoProtocol::send_pronto_(RemoteTransmitData *dst, const std::vector Date: Sun, 4 Jan 2026 16:08:45 -1000 Subject: [PATCH 271/302] [remote_receiver] Combine log statements to reduce loop blocking (#12951) --- esphome/components/remote_receiver/remote_receiver.cpp | 4 ++-- esphome/components/remote_receiver/remote_receiver_esp32.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/remote_receiver/remote_receiver.cpp b/esphome/components/remote_receiver/remote_receiver.cpp index a7ac74199d..de47457dac 100644 --- a/esphome/components/remote_receiver/remote_receiver.cpp +++ b/esphome/components/remote_receiver/remote_receiver.cpp @@ -76,9 +76,8 @@ void RemoteReceiverComponent::setup() { } void RemoteReceiverComponent::dump_config() { - ESP_LOGCONFIG(TAG, "Remote Receiver:"); - LOG_PIN(" Pin: ", this->pin_); ESP_LOGCONFIG(TAG, + "Remote Receiver:\n" " Buffer Size: %u\n" " Tolerance: %u%s\n" " Filter out pulses shorter than: %u us\n" @@ -86,6 +85,7 @@ void RemoteReceiverComponent::dump_config() { this->buffer_size_, this->tolerance_, (this->tolerance_mode_ == remote_base::TOLERANCE_MODE_TIME) ? " us" : "%", this->filter_us_, this->idle_us_); + LOG_PIN(" Pin: ", this->pin_); } void RemoteReceiverComponent::loop() { diff --git a/esphome/components/remote_receiver/remote_receiver_esp32.cpp b/esphome/components/remote_receiver/remote_receiver_esp32.cpp index bd0bc8e57b..eda8365169 100644 --- a/esphome/components/remote_receiver/remote_receiver_esp32.cpp +++ b/esphome/components/remote_receiver/remote_receiver_esp32.cpp @@ -117,9 +117,8 @@ void RemoteReceiverComponent::setup() { } void RemoteReceiverComponent::dump_config() { - ESP_LOGCONFIG(TAG, "Remote Receiver:"); - LOG_PIN(" Pin: ", this->pin_); ESP_LOGCONFIG(TAG, + "Remote Receiver:\n" " Clock resolution: %" PRIu32 " hz\n" " RMT symbols: %" PRIu32 "\n" " Filter symbols: %" PRIu32 "\n" @@ -132,6 +131,7 @@ void RemoteReceiverComponent::dump_config() { this->clock_resolution_, this->rmt_symbols_, this->filter_symbols_, this->receive_symbols_, this->tolerance_, (this->tolerance_mode_ == remote_base::TOLERANCE_MODE_TIME) ? " us" : "%", this->carrier_frequency_, this->carrier_duty_percent_, this->filter_us_, this->idle_us_); + LOG_PIN(" Pin: ", this->pin_); if (this->is_failed()) { ESP_LOGE(TAG, "Configuring RMT driver failed: %s (%s)", esp_err_to_name(this->error_code_), this->error_string_.c_str()); From 4f20c1ceb17aad02d8c5aec2dfbbb1f00cf5ffe9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:09:51 -1000 Subject: [PATCH 272/302] [rp2040_pwm] Combine log statements to reduce loop blocking (#12952) --- esphome/components/rp2040_pwm/rp2040_pwm.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/rp2040_pwm/rp2040_pwm.cpp b/esphome/components/rp2040_pwm/rp2040_pwm.cpp index ec164b3c05..90a507b14f 100644 --- a/esphome/components/rp2040_pwm/rp2040_pwm.cpp +++ b/esphome/components/rp2040_pwm/rp2040_pwm.cpp @@ -36,9 +36,11 @@ void RP2040PWM::setup_pwm_() { } void RP2040PWM::dump_config() { - ESP_LOGCONFIG(TAG, "RP2040 PWM:"); + ESP_LOGCONFIG(TAG, + "RP2040 PWM:\n" + " Frequency: %.1f Hz", + this->frequency_); LOG_PIN(" Pin: ", this->pin_); - ESP_LOGCONFIG(TAG, " Frequency: %.1f Hz", this->frequency_); LOG_FLOAT_OUTPUT(this); } void HOT RP2040PWM::write_state(float state) { From 7449421cea5b8fa76dfa5e713bdaae30a4850847 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:10:06 -1000 Subject: [PATCH 273/302] [shelly_dimmer] Combine log statements to reduce loop blocking (#12956) --- .../shelly_dimmer/shelly_dimmer.cpp | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/esphome/components/shelly_dimmer/shelly_dimmer.cpp b/esphome/components/shelly_dimmer/shelly_dimmer.cpp index 3b5307805e..bdb33d31af 100644 --- a/esphome/components/shelly_dimmer/shelly_dimmer.cpp +++ b/esphome/components/shelly_dimmer/shelly_dimmer.cpp @@ -113,26 +113,20 @@ void ShellyDimmer::setup() { void ShellyDimmer::update() { this->send_command_(SHELLY_DIMMER_PROTO_CMD_POLL, nullptr, 0); } void ShellyDimmer::dump_config() { - ESP_LOGCONFIG(TAG, "ShellyDimmer:"); - LOG_PIN(" NRST Pin: ", this->pin_nrst_); - LOG_PIN(" BOOT0 Pin: ", this->pin_boot0_); - ESP_LOGCONFIG(TAG, + "ShellyDimmer:\n" " Leading Edge: %s\n" " Warmup Brightness: %d\n" " Minimum Brightness: %d\n" - " Maximum Brightness: %d", - YESNO(this->leading_edge_), this->warmup_brightness_, this->min_brightness_, this->max_brightness_); - // ESP_LOGCONFIG(TAG, " Warmup Time: %d", this->warmup_time_); - // ESP_LOGCONFIG(TAG, " Fade Rate: %d", this->fade_rate_); - - LOG_UPDATE_INTERVAL(this); - - ESP_LOGCONFIG(TAG, - " STM32 current firmware version: %d.%d \n" + " Maximum Brightness: %d\n" + " STM32 current firmware version: %d.%d\n" " STM32 required firmware version: %d.%d", + YESNO(this->leading_edge_), this->warmup_brightness_, this->min_brightness_, this->max_brightness_, this->version_major_, this->version_minor_, USE_SHD_FIRMWARE_MAJOR_VERSION, USE_SHD_FIRMWARE_MINOR_VERSION); + LOG_PIN(" NRST Pin: ", this->pin_nrst_); + LOG_PIN(" BOOT0 Pin: ", this->pin_boot0_); + LOG_UPDATE_INTERVAL(this); if (this->version_major_ != USE_SHD_FIRMWARE_MAJOR_VERSION || this->version_minor_ != USE_SHD_FIRMWARE_MINOR_VERSION) { @@ -439,13 +433,15 @@ bool ShellyDimmer::handle_frame_() { current = CURRENT_SCALING_FACTOR / static_cast(current_raw); } - ESP_LOGI(TAG, "Got dimmer data:"); - ESP_LOGI(TAG, " HW version: %d", hw_version); - ESP_LOGI(TAG, " Brightness: %d", brightness); - ESP_LOGI(TAG, " Fade rate: %d", fade_rate); - ESP_LOGI(TAG, " Power: %f W", power); - ESP_LOGI(TAG, " Voltage: %f V", voltage); - ESP_LOGI(TAG, " Current: %f A", current); + ESP_LOGI(TAG, + "Got dimmer data:\n" + " HW version: %d\n" + " Brightness: %d\n" + " Fade rate: %d\n" + " Power: %f W\n" + " Voltage: %f V\n" + " Current: %f A", + hw_version, brightness, fade_rate, power, voltage, current); // Update sensors. if (this->power_sensor_ != nullptr) { From 9f7925c1d589b54fa857bd9b379d9fbbc9cc82cc Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:10:19 -1000 Subject: [PATCH 274/302] [safe_mode] Combine log statements to reduce loop blocking (#12955) --- esphome/components/safe_mode/safe_mode.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/safe_mode/safe_mode.cpp b/esphome/components/safe_mode/safe_mode.cpp index c933222273..c7bd8748f5 100644 --- a/esphome/components/safe_mode/safe_mode.cpp +++ b/esphome/components/safe_mode/safe_mode.cpp @@ -40,8 +40,10 @@ void SafeModeComponent::dump_config() { #ifdef USE_OTA_ROLLBACK const esp_partition_t *last_invalid = esp_ota_get_last_invalid_partition(); if (last_invalid != nullptr) { - ESP_LOGW(TAG, "OTA rollback detected! Rolled back from partition '%s'", last_invalid->label); - ESP_LOGW(TAG, "The device reset before the boot was marked successful"); + ESP_LOGW(TAG, + "OTA rollback detected! Rolled back from partition '%s'\n" + "The device reset before the boot was marked successful", + last_invalid->label); } #endif } From ab0e15e4bbd6f31371e280395ab9b1c14ab8c948 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:10:51 -1000 Subject: [PATCH 275/302] [runtime_stats] Combine log statements to reduce loop blocking (#12954) --- esphome/components/runtime_stats/runtime_stats.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/runtime_stats/runtime_stats.cpp b/esphome/components/runtime_stats/runtime_stats.cpp index f95be5291f..7e837a18e8 100644 --- a/esphome/components/runtime_stats/runtime_stats.cpp +++ b/esphome/components/runtime_stats/runtime_stats.cpp @@ -27,8 +27,10 @@ void RuntimeStatsCollector::record_component_time(Component *component, uint32_t } void RuntimeStatsCollector::log_stats_() { - ESP_LOGI(TAG, "Component Runtime Statistics"); - ESP_LOGI(TAG, "Period stats (last %" PRIu32 "ms):", this->log_interval_); + ESP_LOGI(TAG, + "Component Runtime Statistics\n" + "Period stats (last %" PRIu32 "ms):", + this->log_interval_); // First collect stats we want to display std::vector stats_to_display; From 12027569d33e7069bca7ed7986ba332ae3f55617 Mon Sep 17 00:00:00 2001 From: tomaszduda23 Date: Mon, 5 Jan 2026 03:11:14 +0100 Subject: [PATCH 276/302] [nrf52,zigbee] add support for binary_input (#11535) Co-authored-by: J. Nick Koston Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: J. Nick Koston Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Co-authored-by: J. Nick Koston --- CODEOWNERS | 1 + esphome/components/binary_sensor/__init__.py | 6 +- esphome/components/zephyr/core.cpp | 5 + esphome/components/zigbee/__init__.py | 124 ++++++++ esphome/components/zigbee/automation.h | 16 ++ esphome/components/zigbee/const_zephyr.py | 24 ++ .../zigbee/zigbee_binary_sensor_zephyr.cpp | 37 +++ .../zigbee/zigbee_binary_sensor_zephyr.h | 45 +++ esphome/components/zigbee/zigbee_zephyr.cpp | 190 +++++++++++++ esphome/components/zigbee/zigbee_zephyr.h | 104 +++++++ esphome/components/zigbee/zigbee_zephyr.py | 265 ++++++++++++++++++ esphome/core/defines.h | 3 + script/helpers_zephyr.py | 12 +- tests/components/zigbee/common.yaml | 34 +++ .../zigbee/test.nrf52-adafruit.yaml | 1 + .../components/zigbee/test.nrf52-mcumgr.yaml | 1 + .../zigbee/test.nrf52-xiao-ble.yaml | 1 + 17 files changed, 866 insertions(+), 3 deletions(-) create mode 100644 esphome/components/zigbee/__init__.py create mode 100644 esphome/components/zigbee/automation.h create mode 100644 esphome/components/zigbee/const_zephyr.py create mode 100644 esphome/components/zigbee/zigbee_binary_sensor_zephyr.cpp create mode 100644 esphome/components/zigbee/zigbee_binary_sensor_zephyr.h create mode 100644 esphome/components/zigbee/zigbee_zephyr.cpp create mode 100644 esphome/components/zigbee/zigbee_zephyr.h create mode 100644 esphome/components/zigbee/zigbee_zephyr.py create mode 100644 tests/components/zigbee/common.yaml create mode 100644 tests/components/zigbee/test.nrf52-adafruit.yaml create mode 100644 tests/components/zigbee/test.nrf52-mcumgr.yaml create mode 100644 tests/components/zigbee/test.nrf52-xiao-ble.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 0d9396aa6f..00db5a3c79 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -575,5 +575,6 @@ esphome/components/xpt2046/touchscreen/* @nielsnl68 @numo68 esphome/components/xxtea/* @clydebarrow esphome/components/zephyr/* @tomaszduda23 esphome/components/zhlt01/* @cfeenstra1024 +esphome/components/zigbee/* @tomaszduda23 esphome/components/zio_ultrasonic/* @kahrendt esphome/components/zwave_proxy/* @kbx81 diff --git a/esphome/components/binary_sensor/__init__.py b/esphome/components/binary_sensor/__init__.py index cbf935a501..c38d6b78d3 100644 --- a/esphome/components/binary_sensor/__init__.py +++ b/esphome/components/binary_sensor/__init__.py @@ -3,7 +3,7 @@ from logging import getLogger from esphome import automation, core from esphome.automation import Condition, maybe_simple_id import esphome.codegen as cg -from esphome.components import mqtt, web_server +from esphome.components import mqtt, web_server, zigbee from esphome.components.const import CONF_ON_STATE_CHANGE import esphome.config_validation as cv from esphome.const import ( @@ -439,6 +439,7 @@ def validate_publish_initial_state(value): _BINARY_SENSOR_SCHEMA = ( cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA) .extend(cv.MQTT_COMPONENT_SCHEMA) + .extend(zigbee.BINARY_SENSOR_SCHEMA) .extend( { cv.GenerateID(): cv.declare_id(BinarySensor), @@ -520,6 +521,7 @@ _BINARY_SENSOR_SCHEMA = ( _BINARY_SENSOR_SCHEMA.add_extra(entity_duplicate_validator("binary_sensor")) +_BINARY_SENSOR_SCHEMA.add_extra(zigbee.validate_binary_sensor) def binary_sensor_schema( @@ -621,6 +623,8 @@ async def setup_binary_sensor_core_(var, config): if web_server_config := config.get(CONF_WEB_SERVER): await web_server.add_entity_config(var, web_server_config) + await zigbee.setup_binary_sensor(var, config) + async def register_binary_sensor(var, config): if not CORE.has_id(config[CONF_ID]): diff --git a/esphome/components/zephyr/core.cpp b/esphome/components/zephyr/core.cpp index 46589cdb62..d7027b33f5 100644 --- a/esphome/components/zephyr/core.cpp +++ b/esphome/components/zephyr/core.cpp @@ -26,7 +26,12 @@ void arch_init() { if (device_is_ready(WDT)) { static wdt_timeout_cfg wdt_config{}; wdt_config.flags = WDT_FLAG_RESET_SOC; +#ifdef USE_ZIGBEE + // zboss thread use a lot of cpu cycles during start + wdt_config.window.max = 10000; +#else wdt_config.window.max = 2000; +#endif wdt_channel_id = wdt_install_timeout(WDT, &wdt_config); if (wdt_channel_id >= 0) { uint8_t options = 0; diff --git a/esphome/components/zigbee/__init__.py b/esphome/components/zigbee/__init__.py new file mode 100644 index 0000000000..2009f92d2e --- /dev/null +++ b/esphome/components/zigbee/__init__.py @@ -0,0 +1,124 @@ +from typing import Any + +from esphome import automation, core +import esphome.codegen as cg +from esphome.components.nrf52.boards import BOOTLOADER_CONFIG, Section +from esphome.components.zephyr import zephyr_add_pm_static, zephyr_data +from esphome.components.zephyr.const import KEY_BOOTLOADER +import esphome.config_validation as cv +from esphome.const import CONF_ID, CONF_INTERNAL +from esphome.core import CORE +from esphome.types import ConfigType + +from .const_zephyr import ( + CONF_MAX_EP_NUMBER, + CONF_ON_JOIN, + CONF_WIPE_ON_BOOT, + CONF_ZIGBEE_ID, + KEY_EP_NUMBER, + KEY_ZIGBEE, + ZigbeeComponent, + zigbee_ns, +) +from .zigbee_zephyr import zephyr_binary_sensor + +CODEOWNERS = ["@tomaszduda23"] + + +def zigbee_set_core_data(config: ConfigType) -> ConfigType: + if zephyr_data()[KEY_BOOTLOADER] in BOOTLOADER_CONFIG: + zephyr_add_pm_static( + [Section("empty_after_zboss_offset", 0xF4000, 0xC000, "flash_primary")] + ) + + return config + + +BINARY_SENSOR_SCHEMA = cv.Schema({}).extend(zephyr_binary_sensor) + +CONFIG_SCHEMA = cv.All( + cv.Schema( + { + cv.GenerateID(CONF_ID): cv.declare_id(ZigbeeComponent), + cv.Optional(CONF_ON_JOIN): automation.validate_automation(single=True), + cv.Optional(CONF_WIPE_ON_BOOT, default=False): cv.All( + cv.boolean, + cv.requires_component("nrf52"), + ), + } + ).extend(cv.COMPONENT_SCHEMA), + zigbee_set_core_data, + cv.only_with_framework("zephyr"), +) + + +def validate_number_of_ep(config: ConfigType) -> None: + if KEY_ZIGBEE not in CORE.data: + raise cv.Invalid("At least one zigbee device need to be included") + count = len(CORE.data[KEY_ZIGBEE][KEY_EP_NUMBER]) + if count == 1: + raise cv.Invalid( + "Single endpoint is not supported https://github.com/Koenkk/zigbee2mqtt/issues/29888" + ) + if count > CONF_MAX_EP_NUMBER: + raise cv.Invalid(f"Maximum number of end points is {CONF_MAX_EP_NUMBER}") + + +FINAL_VALIDATE_SCHEMA = cv.All( + validate_number_of_ep, +) + + +async def to_code(config: ConfigType) -> None: + cg.add_define("USE_ZIGBEE") + if CORE.using_zephyr: + from .zigbee_zephyr import zephyr_to_code + + await zephyr_to_code(config) + + +async def setup_binary_sensor(entity: cg.MockObj, config: ConfigType) -> None: + if not config.get(CONF_ZIGBEE_ID) or config.get(CONF_INTERNAL): + return + if CORE.using_zephyr: + from .zigbee_zephyr import zephyr_setup_binary_sensor + + await zephyr_setup_binary_sensor(entity, config) + + +def validate_binary_sensor(config: ConfigType) -> ConfigType: + if not config.get(CONF_ZIGBEE_ID) or config.get(CONF_INTERNAL): + return config + data: dict[str, Any] = CORE.data.setdefault(KEY_ZIGBEE, {}) + slots: list[str] = data.setdefault(KEY_EP_NUMBER, []) + slots.extend([""]) + return config + + +ZIGBEE_ACTION_SCHEMA = automation.maybe_simple_id( + cv.Schema( + { + cv.GenerateID(): cv.use_id(ZigbeeComponent), + } + ) +) + +FactoryResetAction = zigbee_ns.class_( + "FactoryResetAction", automation.Action, cg.Parented.template(ZigbeeComponent) +) + + +@automation.register_action( + "zigbee.factory_reset", + FactoryResetAction, + ZIGBEE_ACTION_SCHEMA, +) +async def reset_zigbee_to_code( + config: ConfigType, + action_id: core.ID, + template_arg: cg.TemplateArguments, + args: list[tuple], +) -> cg.Pvariable: + var = cg.new_Pvariable(action_id, template_arg) + await cg.register_parented(var, config[CONF_ID]) + return var diff --git a/esphome/components/zigbee/automation.h b/esphome/components/zigbee/automation.h new file mode 100644 index 0000000000..1822e6a029 --- /dev/null +++ b/esphome/components/zigbee/automation.h @@ -0,0 +1,16 @@ +#pragma once +#include "esphome/core/defines.h" +#ifdef USE_ZIGBEE +#ifdef USE_NRF52 +#include "zigbee_zephyr.h" +#endif +namespace esphome::zigbee { + +template class FactoryResetAction : public Action, public Parented { + public: + void play(const Ts &...x) override { this->parent_->factory_reset(); } +}; + +} // namespace esphome::zigbee + +#endif diff --git a/esphome/components/zigbee/const_zephyr.py b/esphome/components/zigbee/const_zephyr.py new file mode 100644 index 0000000000..ecd08f1f0a --- /dev/null +++ b/esphome/components/zigbee/const_zephyr.py @@ -0,0 +1,24 @@ +import esphome.codegen as cg + +zigbee_ns = cg.esphome_ns.namespace("zigbee") +ZigbeeComponent = zigbee_ns.class_("ZigbeeComponent", cg.Component) +BinaryAttrs = zigbee_ns.struct("BinaryAttrs") + +CONF_MAX_EP_NUMBER = 8 +CONF_ZIGBEE_ID = "zigbee_id" +CONF_ON_JOIN = "on_join" +CONF_WIPE_ON_BOOT = "wipe_on_boot" +CONF_ZIGBEE_BINARY_SENSOR = "zigbee_binary_sensor" + +# Keys for CORE.data storage +KEY_ZIGBEE = "zigbee" +KEY_EP_NUMBER = "ep_number" + +# External ZBOSS SDK types (just strings for codegen) +ZB_ZCL_BASIC_ATTRS_EXT_T = "zb_zcl_basic_attrs_ext_t" +ZB_ZCL_IDENTIFY_ATTRS_T = "zb_zcl_identify_attrs_t" + +# Cluster IDs +ZB_ZCL_CLUSTER_ID_BASIC = "ZB_ZCL_CLUSTER_ID_BASIC" +ZB_ZCL_CLUSTER_ID_IDENTIFY = "ZB_ZCL_CLUSTER_ID_IDENTIFY" +ZB_ZCL_CLUSTER_ID_BINARY_INPUT = "ZB_ZCL_CLUSTER_ID_BINARY_INPUT" diff --git a/esphome/components/zigbee/zigbee_binary_sensor_zephyr.cpp b/esphome/components/zigbee/zigbee_binary_sensor_zephyr.cpp new file mode 100644 index 0000000000..744d04adc5 --- /dev/null +++ b/esphome/components/zigbee/zigbee_binary_sensor_zephyr.cpp @@ -0,0 +1,37 @@ +#include "zigbee_binary_sensor_zephyr.h" +#if defined(USE_ZIGBEE) && defined(USE_NRF52) && defined(USE_BINARY_SENSOR) +#include "esphome/core/log.h" +extern "C" { +#include +#include +#include +#include +#include +} +namespace esphome::zigbee { + +static const char *const TAG = "zigbee.binary_sensor"; + +ZigbeeBinarySensor::ZigbeeBinarySensor(binary_sensor::BinarySensor *binary_sensor) : binary_sensor_(binary_sensor) {} + +void ZigbeeBinarySensor::setup() { + this->binary_sensor_->add_on_state_callback([this](bool state) { + this->cluster_attributes_->present_value = state ? ZB_TRUE : ZB_FALSE; + ESP_LOGD(TAG, "Set attribute end point: %d, present_value %d", this->end_point_, + this->cluster_attributes_->present_value); + ZB_ZCL_SET_ATTRIBUTE(this->end_point_, ZB_ZCL_CLUSTER_ID_BINARY_INPUT, ZB_ZCL_CLUSTER_SERVER_ROLE, + ZB_ZCL_ATTR_BINARY_INPUT_PRESENT_VALUE_ID, &this->cluster_attributes_->present_value, + ZB_FALSE); + this->parent_->flush(); + }); +} + +void ZigbeeBinarySensor::dump_config() { + ESP_LOGCONFIG(TAG, + "Zigbee Binary Sensor\n" + " End point: %d, present_value %u", + this->end_point_, this->cluster_attributes_->present_value); +} + +} // namespace esphome::zigbee +#endif diff --git a/esphome/components/zigbee/zigbee_binary_sensor_zephyr.h b/esphome/components/zigbee/zigbee_binary_sensor_zephyr.h new file mode 100644 index 0000000000..aae79fa289 --- /dev/null +++ b/esphome/components/zigbee/zigbee_binary_sensor_zephyr.h @@ -0,0 +1,45 @@ +#pragma once +#include "esphome/core/defines.h" +#if defined(USE_ZIGBEE) && defined(USE_NRF52) && defined(USE_BINARY_SENSOR) +#include "esphome/components/zigbee/zigbee_zephyr.h" +#include "esphome/core/component.h" +#include "esphome/components/binary_sensor/binary_sensor.h" +extern "C" { +#include +#include +} + +// it should have been defined inside of sdk. It is missing though +#define ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_BINARY_INPUT_DESCRIPTION_ID(data_ptr) \ + { \ + ZB_ZCL_ATTR_BINARY_INPUT_DESCRIPTION_ID, ZB_ZCL_ATTR_TYPE_CHAR_STRING, ZB_ZCL_ATTR_ACCESS_READ_ONLY, \ + (ZB_ZCL_NON_MANUFACTURER_SPECIFIC), (void *) (data_ptr) \ + } + +// copy of ZB_ZCL_DECLARE_BINARY_INPUT_ATTRIB_LIST + description +#define ESPHOME_ZB_ZCL_DECLARE_BINARY_INPUT_ATTRIB_LIST(attr_list, out_of_service, present_value, status_flag, \ + description) \ + ZB_ZCL_START_DECLARE_ATTRIB_LIST_CLUSTER_REVISION(attr_list, ZB_ZCL_BINARY_INPUT) \ + ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_BINARY_INPUT_OUT_OF_SERVICE_ID, (out_of_service)) \ + ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_BINARY_INPUT_PRESENT_VALUE_ID, (present_value)) \ + ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_BINARY_INPUT_STATUS_FLAG_ID, (status_flag)) \ + ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_BINARY_INPUT_DESCRIPTION_ID, (description)) \ + ZB_ZCL_FINISH_DECLARE_ATTRIB_LIST + +namespace esphome::zigbee { + +class ZigbeeBinarySensor : public ZigbeeEntity, public Component { + public: + explicit ZigbeeBinarySensor(binary_sensor::BinarySensor *binary_sensor); + void set_cluster_attributes(BinaryAttrs &cluster_attributes) { this->cluster_attributes_ = &cluster_attributes; } + + void setup() override; + void dump_config() override; + + protected: + BinaryAttrs *cluster_attributes_{nullptr}; + binary_sensor::BinarySensor *binary_sensor_; +}; + +} // namespace esphome::zigbee +#endif diff --git a/esphome/components/zigbee/zigbee_zephyr.cpp b/esphome/components/zigbee/zigbee_zephyr.cpp new file mode 100644 index 0000000000..c9027d0a74 --- /dev/null +++ b/esphome/components/zigbee/zigbee_zephyr.cpp @@ -0,0 +1,190 @@ +#include "zigbee_zephyr.h" +#if defined(USE_ZIGBEE) && defined(USE_NRF52) +#include "esphome/core/log.h" +#include +#include + +extern "C" { +#include +#include +#include +#include +#include +} + +namespace esphome::zigbee { + +static const char *const TAG = "zigbee"; + +ZigbeeComponent *global_zigbee = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + +const uint8_t IEEE_ADDR_BUF_SIZE = 17; + +void ZigbeeComponent::zboss_signal_handler_esphome(zb_bufid_t bufid) { + zb_zdo_app_signal_hdr_t *sig_hndler = nullptr; + zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &sig_hndler); + zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid); + + switch (sig) { + case ZB_ZDO_SIGNAL_SKIP_STARTUP: + ESP_LOGD(TAG, "ZB_ZDO_SIGNAL_SKIP_STARTUP, status: %d", status); + break; + case ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY: + ESP_LOGD(TAG, "ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY, status: %d", status); + break; + case ZB_ZDO_SIGNAL_LEAVE: + ESP_LOGD(TAG, "ZB_ZDO_SIGNAL_LEAVE, status: %d", status); + break; + case ZB_BDB_SIGNAL_DEVICE_REBOOT: + ESP_LOGD(TAG, "ZB_BDB_SIGNAL_DEVICE_REBOOT, status: %d", status); + if (status == RET_OK) { + on_join_(); + } + break; + case ZB_BDB_SIGNAL_STEERING: + break; + case ZB_COMMON_SIGNAL_CAN_SLEEP: + ESP_LOGV(TAG, "ZB_COMMON_SIGNAL_CAN_SLEEP, status: %d", status); + break; + case ZB_BDB_SIGNAL_DEVICE_FIRST_START: + ESP_LOGD(TAG, "ZB_BDB_SIGNAL_DEVICE_FIRST_START, status: %d", status); + break; + case ZB_NLME_STATUS_INDICATION: + ESP_LOGD(TAG, "ZB_NLME_STATUS_INDICATION, status: %d", status); + break; + case ZB_BDB_SIGNAL_TC_REJOIN_DONE: + ESP_LOGD(TAG, "ZB_BDB_SIGNAL_TC_REJOIN_DONE, status: %d", status); + break; + default: + ESP_LOGD(TAG, "zboss_signal_handler sig: %d, status: %d", sig, status); + break; + } + + auto err = zigbee_default_signal_handler(bufid); + if (err != RET_OK) { + ESP_LOGE(TAG, "Zigbee_default_signal_handler ERROR %u [%s]", err, zb_error_to_string_get(err)); + } + + switch (sig) { + case ZB_BDB_SIGNAL_STEERING: + ESP_LOGD(TAG, "ZB_BDB_SIGNAL_STEERING, status: %d", status); + if (status == RET_OK) { + zb_ext_pan_id_t extended_pan_id; + char ieee_addr_buf[IEEE_ADDR_BUF_SIZE] = {0}; + int addr_len; + + zb_get_extended_pan_id(extended_pan_id); + addr_len = ieee_addr_to_str(ieee_addr_buf, sizeof(ieee_addr_buf), extended_pan_id); + + for (int i = 0; i < addr_len; ++i) { + if (ieee_addr_buf[i] != '0') { + on_join_(); + break; + } + } + } + break; + } + + /* All callbacks should either reuse or free passed buffers. + * If bufid == 0, the buffer is invalid (not passed). + */ + if (bufid) { + zb_buf_free(bufid); + } +} + +void ZigbeeComponent::zcl_device_cb(zb_bufid_t bufid) { + zb_zcl_device_callback_param_t *p_device_cb_param = ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t); + zb_zcl_device_callback_id_t device_cb_id = p_device_cb_param->device_cb_id; + zb_uint16_t cluster_id = p_device_cb_param->cb_param.set_attr_value_param.cluster_id; + zb_uint16_t attr_id = p_device_cb_param->cb_param.set_attr_value_param.attr_id; + auto endpoint = p_device_cb_param->endpoint; + + ESP_LOGI(TAG, "Zcl_device_cb %s id %hd, cluster_id %d, attr_id %d, endpoint: %d", __func__, device_cb_id, cluster_id, + attr_id, endpoint); + + // endpoints are enumerated from 1 + if (global_zigbee->callbacks_.size() >= endpoint) { + global_zigbee->callbacks_[endpoint - 1](bufid); + return; + } + p_device_cb_param->status = RET_ERROR; +} + +void ZigbeeComponent::on_join_() { + this->defer([this]() { + ESP_LOGD(TAG, "Joined the network"); + this->join_trigger_.trigger(); + this->join_cb_.call(); + }); +} + +#ifdef USE_ZIGBEE_WIPE_ON_BOOT +void ZigbeeComponent::erase_flash_(int area) { + const struct flash_area *fap; + flash_area_open(area, &fap); + flash_area_erase(fap, 0, fap->fa_size); + flash_area_close(fap); +} +#endif + +void ZigbeeComponent::setup() { + global_zigbee = this; + auto err = settings_subsys_init(); + if (err) { + ESP_LOGE(TAG, "Failed to initialize settings subsystem, err: %d", err); + return; + } + +#ifdef USE_ZIGBEE_WIPE_ON_BOOT + erase_flash_(FIXED_PARTITION_ID(ZBOSS_NVRAM)); + erase_flash_(FIXED_PARTITION_ID(ZBOSS_PRODUCT_CONFIG)); + erase_flash_(FIXED_PARTITION_ID(SETTINGS_STORAGE)); +#endif + + ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb); + err = settings_load(); + if (err) { + ESP_LOGE(TAG, "Cannot load settings, err: %d", err); + return; + } + zigbee_enable(); +} + +void ZigbeeComponent::dump_config() { + bool wipe = false; +#ifdef USE_ZIGBEE_WIPE_ON_BOOT + wipe = true; +#endif + ESP_LOGCONFIG(TAG, + "Zigbee\n" + " Wipe on boot: %s", + YESNO(wipe)); +} + +static void send_attribute_report(zb_bufid_t bufid, zb_uint16_t cmd_id) { + ESP_LOGD(TAG, "Force zboss scheduler to wake and send attribute report"); + zb_buf_free(bufid); +} + +void ZigbeeComponent::flush() { this->need_flush_ = true; } + +void ZigbeeComponent::loop() { + if (this->need_flush_) { + this->need_flush_ = false; + zb_buf_get_out_delayed_ext(send_attribute_report, 0, 0); + } +} + +void ZigbeeComponent::factory_reset() { + ESP_LOGD(TAG, "Factory reset"); + ZB_SCHEDULE_APP_CALLBACK(zb_bdb_reset_via_local_action, 0); +} + +} // namespace esphome::zigbee + +extern "C" void zboss_signal_handler(zb_uint8_t param) { + esphome::zigbee::global_zigbee->zboss_signal_handler_esphome(param); +} +#endif diff --git a/esphome/components/zigbee/zigbee_zephyr.h b/esphome/components/zigbee/zigbee_zephyr.h new file mode 100644 index 0000000000..853c6deb4d --- /dev/null +++ b/esphome/components/zigbee/zigbee_zephyr.h @@ -0,0 +1,104 @@ +#pragma once +#include "esphome/core/defines.h" +#if defined(USE_ZIGBEE) && defined(USE_NRF52) +#include "esphome/core/component.h" +#include "esphome/core/automation.h" +extern "C" { +#include +#include +} + +// copy of ZB_DECLARE_SIMPLE_DESC. Due to https://github.com/nrfconnect/sdk-nrfxlib/pull/666 +#define ESPHOME_ZB_DECLARE_SIMPLE_DESC(ep_name, in_clusters_count, out_clusters_count) \ + typedef ZB_PACKED_PRE struct zb_af_simple_desc_##ep_name##_##in_clusters_count##_##out_clusters_count##_s { \ + zb_uint8_t endpoint; /* Endpoint */ \ + zb_uint16_t app_profile_id; /* Application profile identifier */ \ + zb_uint16_t app_device_id; /* Application device identifier */ \ + zb_bitfield_t app_device_version : 4; /* Application device version */ \ + zb_bitfield_t reserved : 4; /* Reserved */ \ + zb_uint8_t app_input_cluster_count; /* Application input cluster count */ \ + zb_uint8_t app_output_cluster_count; /* Application output cluster count */ \ + /* Application input and output cluster list */ \ + zb_uint16_t app_cluster_list[(in_clusters_count) + (out_clusters_count)]; \ + } ZB_PACKED_STRUCT zb_af_simple_desc_##ep_name##_##in_clusters_count##_##out_clusters_count##_t + +#define ESPHOME_CAT7(a, b, c, d, e, f, g) a##b##c##d##e##f##g +// needed to use ESPHOME_ZB_DECLARE_SIMPLE_DESC +#define ESPHOME_ZB_AF_SIMPLE_DESC_TYPE(ep_name, in_num, out_num) \ + ESPHOME_CAT7(zb_af_simple_desc_, ep_name, _, in_num, _, out_num, _t) + +// needed to use ESPHOME_ZB_DECLARE_SIMPLE_DESC +#define ESPHOME_ZB_ZCL_DECLARE_SIMPLE_DESC(ep_name, ep_id, in_clust_num, out_clust_num, ...) \ + ESPHOME_ZB_DECLARE_SIMPLE_DESC(ep_name, in_clust_num, out_clust_num); \ + ESPHOME_ZB_AF_SIMPLE_DESC_TYPE(ep_name, in_clust_num, out_clust_num) \ + simple_desc_##ep_name = {ep_id, ZB_AF_HA_PROFILE_ID, ZB_HA_SIMPLE_SENSOR_DEVICE_ID, 0, 0, in_clust_num, \ + out_clust_num, {__VA_ARGS__}} + +// needed to use ESPHOME_ZB_ZCL_DECLARE_SIMPLE_DESC +#define ESPHOME_ZB_HA_DECLARE_EP(ep_name, ep_id, cluster_list, in_cluster_num, out_cluster_num, report_attr_count, \ + ...) \ + ESPHOME_ZB_ZCL_DECLARE_SIMPLE_DESC(ep_name, ep_id, in_cluster_num, out_cluster_num, __VA_ARGS__); \ + ZBOSS_DEVICE_DECLARE_REPORTING_CTX(reporting_info##ep_name, report_attr_count); \ + ZB_AF_DECLARE_ENDPOINT_DESC(ep_name, ep_id, ZB_AF_HA_PROFILE_ID, 0, NULL, \ + ZB_ZCL_ARRAY_SIZE(cluster_list, zb_zcl_cluster_desc_t), cluster_list, \ + (zb_af_simple_desc_1_1_t *) &simple_desc_##ep_name, report_attr_count, \ + reporting_info##ep_name, 0, NULL) + +namespace esphome::zigbee { + +struct BinaryAttrs { + zb_bool_t out_of_service; + zb_bool_t present_value; + zb_uint8_t status_flags; + zb_uchar_t description[ZB_ZCL_MAX_STRING_SIZE]; +}; + +struct AnalogAttrs { + zb_bool_t out_of_service; + float present_value; + zb_uint8_t status_flags; + zb_uchar_t description[ZB_ZCL_MAX_STRING_SIZE]; + float max_present_value; + float min_present_value; + float resolution; +}; + +class ZigbeeComponent : public Component { + public: + void setup() override; + void dump_config() override; + void add_callback(zb_uint8_t endpoint, std::function &&cb) { + // endpoints are enumerated from 1 + this->callbacks_[endpoint - 1] = std::move(cb); + } + void add_join_callback(std::function &&cb) { this->join_cb_.add(std::move(cb)); } + void zboss_signal_handler_esphome(zb_bufid_t bufid); + void factory_reset(); + Trigger<> *get_join_trigger() { return &this->join_trigger_; }; + void flush(); + void loop() override; + + protected: + static void zcl_device_cb(zb_bufid_t bufid); + void on_join_(); +#ifdef USE_ZIGBEE_WIPE_ON_BOOT + void erase_flash_(int area); +#endif + StaticVector, ZIGBEE_ENDPOINTS_COUNT> callbacks_; + CallbackManager join_cb_; + Trigger<> join_trigger_; + bool need_flush_{false}; +}; + +class ZigbeeEntity { + public: + void set_parent(ZigbeeComponent *parent) { this->parent_ = parent; } + void set_end_point(zb_uint8_t end_point) { this->end_point_ = end_point; } + + protected: + zb_uint8_t end_point_{0}; + ZigbeeComponent *parent_{nullptr}; +}; + +} // namespace esphome::zigbee +#endif diff --git a/esphome/components/zigbee/zigbee_zephyr.py b/esphome/components/zigbee/zigbee_zephyr.py new file mode 100644 index 0000000000..ce55675c41 --- /dev/null +++ b/esphome/components/zigbee/zigbee_zephyr.py @@ -0,0 +1,265 @@ +from datetime import datetime + +from esphome import automation +import esphome.codegen as cg +from esphome.components.zephyr import zephyr_add_prj_conf +import esphome.config_validation as cv +from esphome.const import CONF_ID, CONF_NAME, __version__ +from esphome.core import CORE, CoroPriority, coroutine_with_priority +from esphome.cpp_generator import ( + AssignmentExpression, + MockObj, + VariableDeclarationExpression, +) +from esphome.types import ConfigType + +from .const_zephyr import ( + CONF_ON_JOIN, + CONF_WIPE_ON_BOOT, + CONF_ZIGBEE_BINARY_SENSOR, + CONF_ZIGBEE_ID, + KEY_EP_NUMBER, + KEY_ZIGBEE, + ZB_ZCL_BASIC_ATTRS_EXT_T, + ZB_ZCL_CLUSTER_ID_BASIC, + ZB_ZCL_CLUSTER_ID_BINARY_INPUT, + ZB_ZCL_CLUSTER_ID_IDENTIFY, + ZB_ZCL_IDENTIFY_ATTRS_T, + BinaryAttrs, + ZigbeeComponent, + zigbee_ns, +) + +ZigbeeBinarySensor = zigbee_ns.class_("ZigbeeBinarySensor", cg.Component) + +zephyr_binary_sensor = cv.Schema( + { + cv.OnlyWith(CONF_ZIGBEE_ID, ["nrf52", "zigbee"]): cv.use_id(ZigbeeComponent), + cv.OnlyWith(CONF_ZIGBEE_BINARY_SENSOR, ["nrf52", "zigbee"]): cv.declare_id( + ZigbeeBinarySensor + ), + } +) + + +async def zephyr_to_code(config: ConfigType) -> None: + zephyr_add_prj_conf("ZIGBEE", True) + zephyr_add_prj_conf("ZIGBEE_APP_UTILS", True) + zephyr_add_prj_conf("ZIGBEE_ROLE_END_DEVICE", True) + + zephyr_add_prj_conf("ZIGBEE_CHANNEL_SELECTION_MODE_MULTI", True) + + zephyr_add_prj_conf("CRYPTO", True) + + zephyr_add_prj_conf("NET_IPV6", False) + zephyr_add_prj_conf("NET_IP_ADDR_CHECK", False) + zephyr_add_prj_conf("NET_UDP", False) + + if config[CONF_WIPE_ON_BOOT]: + cg.add_define("USE_ZIGBEE_WIPE_ON_BOOT") + var = cg.new_Pvariable(config[CONF_ID]) + + if on_join_config := config.get(CONF_ON_JOIN): + await automation.build_automation(var.get_join_trigger(), [], on_join_config) + + await cg.register_component(var, config) + + await _attr_to_code(config) + CORE.add_job(_ctx_to_code, config) + + +async def _attr_to_code(config: ConfigType) -> None: + # Create the basic attributes structure and attribute list + basic_attrs = zigbee_new_variable("zigbee_basic_attrs", ZB_ZCL_BASIC_ATTRS_EXT_T) + zigbee_new_attr_list( + "zigbee_basic_attrib_list", + "ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST_EXT", + zigbee_assign(basic_attrs.zcl_version, cg.RawExpression("ZB_ZCL_VERSION")), + zigbee_assign(basic_attrs.app_version, 0), + zigbee_assign(basic_attrs.stack_version, 0), + zigbee_assign(basic_attrs.hw_version, 0), + zigbee_set_string(basic_attrs.mf_name, "esphome"), + zigbee_set_string(basic_attrs.model_id, CORE.name), + zigbee_set_string( + basic_attrs.date_code, datetime.now().strftime("%d/%m/%y %H:%M") + ), + zigbee_assign( + basic_attrs.power_source, + cg.RawExpression("ZB_ZCL_BASIC_POWER_SOURCE_DC_SOURCE"), + ), + zigbee_set_string(basic_attrs.location_id, ""), + zigbee_assign( + basic_attrs.ph_env, cg.RawExpression("ZB_ZCL_BASIC_ENV_UNSPECIFIED") + ), + zigbee_set_string(basic_attrs.sw_ver, __version__), + ) + + # Create the identify attributes structure and attribute list + identify_attrs = zigbee_new_variable( + "zigbee_identify_attrs", ZB_ZCL_IDENTIFY_ATTRS_T + ) + zigbee_new_attr_list( + "zigbee_identify_attrib_list", + "ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST", + zigbee_assign( + identify_attrs.identify_time, + cg.RawExpression("ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE"), + ), + ) + + +def zigbee_new_variable(name: str, type_: str) -> cg.MockObj: + """Create a global variable with the given name and type.""" + decl = VariableDeclarationExpression(type_, "", name) + CORE.add_global(decl) + return MockObj(name, ".") + + +def zigbee_assign(target: cg.MockObj, expression: cg.RawExpression | int) -> str: + """Assign an expression to a target and return a reference to it.""" + cg.add(AssignmentExpression("", "", target, expression)) + return f"&{target}" + + +def zigbee_set_string(target: cg.MockObj, value: str) -> str: + """Set a ZCL string value and return the target name (arrays decay to pointers).""" + cg.add( + cg.RawExpression( + f"ZB_ZCL_SET_STRING_VAL({target}, {cg.safe_exp(value)}, ZB_ZCL_STRING_CONST_SIZE({cg.safe_exp(value)}))" + ) + ) + return str(target) + + +def zigbee_new_attr_list(name: str, macro: str, *args: str) -> str: + """Create an attribute list using a ZBOSS macro and return the name.""" + obj = cg.RawExpression(f"{macro}({name}, {', '.join(args)})") + CORE.add_global(obj) + return name + + +class ZigbeeClusterDesc: + """Represents a Zigbee cluster descriptor for code generation.""" + + def __init__(self, cluster_id: str, attr_list_name: str | None = None) -> None: + self._cluster_id = cluster_id + self._attr_list_name = attr_list_name + + @property + def cluster_id(self) -> str: + return self._cluster_id + + @property + def has_attrs(self) -> bool: + return self._attr_list_name is not None + + def __str__(self) -> str: + role = ( + "ZB_ZCL_CLUSTER_SERVER_ROLE" + if self._attr_list_name + else "ZB_ZCL_CLUSTER_CLIENT_ROLE" + ) + if self._attr_list_name: + attr_count = f"ZB_ZCL_ARRAY_SIZE({self._attr_list_name}, zb_zcl_attr_t)" + return f"ZB_ZCL_CLUSTER_DESC({self._cluster_id}, {attr_count}, {self._attr_list_name}, {role}, ZB_ZCL_MANUF_CODE_INVALID)" + return f"ZB_ZCL_CLUSTER_DESC({self._cluster_id}, 0, NULL, {role}, ZB_ZCL_MANUF_CODE_INVALID)" + + +def zigbee_new_cluster_list( + name: str, clusters: list[ZigbeeClusterDesc] +) -> tuple[str, list[ZigbeeClusterDesc]]: + """Create a cluster list array and return its name and the clusters.""" + # Always include basic and identify clusters first + all_clusters = [ + ZigbeeClusterDesc(ZB_ZCL_CLUSTER_ID_BASIC, "zigbee_basic_attrib_list"), + ZigbeeClusterDesc(ZB_ZCL_CLUSTER_ID_IDENTIFY, "zigbee_identify_attrib_list"), + ] + all_clusters.extend(clusters) + + cluster_strs = [str(c) for c in all_clusters] + CORE.add_global( + cg.RawExpression( + f"zb_zcl_cluster_desc_t {name}[] = {{{', '.join(cluster_strs)}}}" + ) + ) + return (name, all_clusters) + + +def zigbee_register_ep( + ep_name: str, + cluster_list_name: str, + report_attr_count: int, + clusters: list[ZigbeeClusterDesc], + slot_index: int, +) -> None: + """Register a Zigbee endpoint.""" + in_cluster_num = sum(1 for c in clusters if c.has_attrs) + out_cluster_num = len(clusters) - in_cluster_num + cluster_ids = [c.cluster_id for c in clusters] + + # Store endpoint name for device context generation + CORE.data[KEY_ZIGBEE][KEY_EP_NUMBER][slot_index] = ep_name + + # Generate the endpoint declaration + ep_id = slot_index + 1 # Endpoints are 1-indexed + obj = cg.RawExpression( + f"ESPHOME_ZB_HA_DECLARE_EP({ep_name}, {ep_id}, {cluster_list_name}, " + f"{in_cluster_num}, {out_cluster_num}, {report_attr_count}, {', '.join(cluster_ids)})" + ) + CORE.add_global(obj) + + +@coroutine_with_priority(CoroPriority.LATE) +async def _ctx_to_code(config: ConfigType) -> None: + cg.add_define("ZIGBEE_ENDPOINTS_COUNT", len(CORE.data[KEY_ZIGBEE][KEY_EP_NUMBER])) + cg.add_global( + cg.RawExpression( + f"ZBOSS_DECLARE_DEVICE_CTX_EP_VA(zb_device_ctx, &{', &'.join(CORE.data[KEY_ZIGBEE][KEY_EP_NUMBER])})" + ) + ) + cg.add(cg.RawExpression("ZB_AF_REGISTER_DEVICE_CTX(&zb_device_ctx)")) + + +async def zephyr_setup_binary_sensor(entity: cg.MockObj, config: ConfigType) -> None: + CORE.add_job(_add_binary_sensor, entity, config) + + +async def _add_binary_sensor(entity: cg.MockObj, config: ConfigType) -> None: + # Find the next available endpoint slot + slot_index = next( + (i for i, v in enumerate(CORE.data[KEY_ZIGBEE][KEY_EP_NUMBER]) if v == ""), None + ) + + # Create unique names for this sensor's variables based on slot index + prefix = f"zigbee_ep{slot_index + 1}" + attrs_name = f"{prefix}_binary_attrs" + attr_list_name = f"{prefix}_binary_input_attrib_list" + cluster_list_name = f"{prefix}_cluster_list" + ep_name = f"{prefix}_ep" + + # Create the binary attributes structure + binary_attrs = zigbee_new_variable(attrs_name, BinaryAttrs) + attr_list = zigbee_new_attr_list( + attr_list_name, + "ESPHOME_ZB_ZCL_DECLARE_BINARY_INPUT_ATTRIB_LIST", + zigbee_assign(binary_attrs.out_of_service, 0), + zigbee_assign(binary_attrs.present_value, 0), + zigbee_assign(binary_attrs.status_flags, 0), + zigbee_set_string(binary_attrs.description, config[CONF_NAME]), + ) + + # Create cluster list and register endpoint + cluster_list_name, clusters = zigbee_new_cluster_list( + cluster_list_name, + [ZigbeeClusterDesc(ZB_ZCL_CLUSTER_ID_BINARY_INPUT, attr_list)], + ) + zigbee_register_ep(ep_name, cluster_list_name, 2, clusters, slot_index) + + # Create the ZigbeeBinarySensor component + var = cg.new_Pvariable(config[CONF_ZIGBEE_BINARY_SENSOR], entity) + await cg.register_component(var, config) + + cg.add(var.set_end_point(slot_index + 1)) + cg.add(var.set_cluster_attributes(binary_attrs)) + hub = await cg.get_variable(config[CONF_ZIGBEE_ID]) + cg.add(var.set_parent(hub)) diff --git a/esphome/core/defines.h b/esphome/core/defines.h index 1fddc426d4..cee46a2df0 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -299,6 +299,9 @@ #define USE_NRF52_UICR_ERASE #define USE_SOFTDEVICE_ID 7 #define USE_SOFTDEVICE_VERSION 1 +#define USE_ZIGBEE +#define USE_ZIGBEE_WIPE_ON_BOOT +#define ZIGBEE_ENDPOINTS_COUNT 8 #endif // Disabled feature flags diff --git a/script/helpers_zephyr.py b/script/helpers_zephyr.py index f72b335e64..1242a60cf4 100644 --- a/script/helpers_zephyr.py +++ b/script/helpers_zephyr.py @@ -17,6 +17,7 @@ def load_idedata(environment, temp_folder, platformio_ini): """ #include int main() { return 0;} +extern "C" void zboss_signal_handler() {}; """, encoding="utf-8", ) @@ -27,6 +28,12 @@ int main() { return 0;} CONFIG_NEWLIB_LIBC=y CONFIG_BT=y CONFIG_ADC=y +#zigbee begin +CONFIG_ZIGBEE=y +CONFIG_CRYPTO=y +CONFIG_NVS=y +CONFIG_SETTINGS=y +#zigbee end """, encoding="utf-8", ) @@ -44,10 +51,11 @@ CONFIG_ADC=y def extract_defines(command): define_pattern = re.compile(r"-D\s*([^\s]+)") + ignore_prefixes = ("_ASMLANGUAGE", "NRF_802154_ECB_PRIORITY=") return [ - match + match.replace("\\", "") for match in define_pattern.findall(command) - if match not in ("_ASMLANGUAGE") + if not any(match.startswith(prefix) for prefix in ignore_prefixes) ] def find_cxx_path(commands): diff --git a/tests/components/zigbee/common.yaml b/tests/components/zigbee/common.yaml new file mode 100644 index 0000000000..eb30205446 --- /dev/null +++ b/tests/components/zigbee/common.yaml @@ -0,0 +1,34 @@ +--- +binary_sensor: + - platform: template + name: "Garage Door Open 1" + - platform: template + name: "Garage Door Open 2" + - platform: template + name: "Garage Door Open 3" + - platform: template + name: "Garage Door Open 4" + - platform: template + name: "Garage Door Open 5" + - platform: template + name: "Garage Door Open 6" + - platform: template + name: "Garage Door Open 7" + internal: True + - platform: template + name: "Garage Door Open 8" + - platform: template + name: "Garage Door Open 9" + +zigbee: + wipe_on_boot: true + on_join: + then: + - logger.log: "Joined network" + +output: + - platform: template + id: output_factory + type: binary + write_action: + - zigbee.factory_reset diff --git a/tests/components/zigbee/test.nrf52-adafruit.yaml b/tests/components/zigbee/test.nrf52-adafruit.yaml new file mode 100644 index 0000000000..dade44d145 --- /dev/null +++ b/tests/components/zigbee/test.nrf52-adafruit.yaml @@ -0,0 +1 @@ +<<: !include common.yaml diff --git a/tests/components/zigbee/test.nrf52-mcumgr.yaml b/tests/components/zigbee/test.nrf52-mcumgr.yaml new file mode 100644 index 0000000000..dade44d145 --- /dev/null +++ b/tests/components/zigbee/test.nrf52-mcumgr.yaml @@ -0,0 +1 @@ +<<: !include common.yaml diff --git a/tests/components/zigbee/test.nrf52-xiao-ble.yaml b/tests/components/zigbee/test.nrf52-xiao-ble.yaml new file mode 100644 index 0000000000..dade44d145 --- /dev/null +++ b/tests/components/zigbee/test.nrf52-xiao-ble.yaml @@ -0,0 +1 @@ +<<: !include common.yaml From a011d5ea9628cf955111d34a70353c2aa40a963f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:14:57 -1000 Subject: [PATCH 277/302] [sht3xd] Combine log statements to reduce loop blocking (#12957) --- esphome/components/sht3xd/sht3xd.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/sht3xd/sht3xd.cpp b/esphome/components/sht3xd/sht3xd.cpp index 79f1674020..d473df43c7 100644 --- a/esphome/components/sht3xd/sht3xd.cpp +++ b/esphome/components/sht3xd/sht3xd.cpp @@ -60,8 +60,10 @@ void SHT3XDComponent::dump_config() { ESP_LOGE(TAG, " Communication with SHT3xD failed!"); return; } - ESP_LOGD(TAG, " Serial Number: 0x%08" PRIX32, this->serial_number_); - ESP_LOGD(TAG, " Heater Enabled: %s", this->heater_enabled_ ? "true" : "false"); + ESP_LOGD(TAG, + " Serial Number: 0x%08" PRIX32 "\n" + " Heater Enabled: %s", + this->serial_number_, TRUEFALSE(this->heater_enabled_)); LOG_I2C_DEVICE(this); LOG_UPDATE_INTERVAL(this); From 2295f57dec2dc5fd31851f7faff0bb976d9d496c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:51:11 -1000 Subject: [PATCH 278/302] [st7567_i2c] Combine log statements to reduce loop blocking (#12975) --- esphome/components/st7567_i2c/st7567_i2c.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/st7567_i2c/st7567_i2c.cpp b/esphome/components/st7567_i2c/st7567_i2c.cpp index 14c21d5148..3214339571 100644 --- a/esphome/components/st7567_i2c/st7567_i2c.cpp +++ b/esphome/components/st7567_i2c/st7567_i2c.cpp @@ -20,14 +20,14 @@ void I2CST7567::setup() { void I2CST7567::dump_config() { LOG_DISPLAY("", "I2CST7567", this); - LOG_I2C_DEVICE(this); - ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); - LOG_PIN(" Reset Pin: ", this->reset_pin_); ESP_LOGCONFIG(TAG, + " Model: %s\n" " Mirror X: %s\n" " Mirror Y: %s\n" " Invert Colors: %s", - YESNO(this->mirror_x_), YESNO(this->mirror_y_), YESNO(this->invert_colors_)); + this->model_str_(), YESNO(this->mirror_x_), YESNO(this->mirror_y_), YESNO(this->invert_colors_)); + LOG_I2C_DEVICE(this); + LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_UPDATE_INTERVAL(this); if (this->error_code_ == COMMUNICATION_FAILED) { From 405b26426c4a7334c130ecf18c2c3b5e640bf139 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:51:24 -1000 Subject: [PATCH 279/302] [st7567_spi] Combine log statements to reduce loop blocking (#12976) --- esphome/components/st7567_spi/st7567_spi.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/esphome/components/st7567_spi/st7567_spi.cpp b/esphome/components/st7567_spi/st7567_spi.cpp index 813afcf682..7476fd7c8d 100644 --- a/esphome/components/st7567_spi/st7567_spi.cpp +++ b/esphome/components/st7567_spi/st7567_spi.cpp @@ -18,13 +18,15 @@ void SPIST7567::setup() { void SPIST7567::dump_config() { LOG_DISPLAY("", "SPI ST7567", this); - ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); + ESP_LOGCONFIG(TAG, + " Model: %s\n" + " Mirror X: %s\n" + " Mirror Y: %s\n" + " Invert Colors: %s", + this->model_str_(), YESNO(this->mirror_x_), YESNO(this->mirror_y_), YESNO(this->invert_colors_)); LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_); - ESP_LOGCONFIG(TAG, " Mirror X: %s", YESNO(this->mirror_x_)); - ESP_LOGCONFIG(TAG, " Mirror Y: %s", YESNO(this->mirror_y_)); - ESP_LOGCONFIG(TAG, " Invert Colors: %s", YESNO(this->invert_colors_)); LOG_UPDATE_INTERVAL(this); } From 1d0f36ba35b7d0fc21e0bc2306580e915c2cbadc Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:51:37 -1000 Subject: [PATCH 280/302] [st7789v] Combine log statements to reduce loop blocking (#12978) --- esphome/components/st7789v/st7789v.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/st7789v/st7789v.cpp b/esphome/components/st7789v/st7789v.cpp index ade9c1126f..cd0b6cabc3 100644 --- a/esphome/components/st7789v/st7789v.cpp +++ b/esphome/components/st7789v/st7789v.cpp @@ -127,15 +127,15 @@ void ST7789V::dump_config() { " Width: %u\n" " Height Offset: %u\n" " Width Offset: %u\n" - " 8-bit color mode: %s", + " 8-bit color mode: %s\n" + " Data rate: %dMHz", this->model_str_, this->height_, this->width_, this->offset_height_, this->offset_width_, - YESNO(this->eightbitcolor_)); + YESNO(this->eightbitcolor_), (unsigned) (this->data_rate_ / 1000000)); LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_PIN(" B/L Pin: ", this->backlight_pin_); LOG_UPDATE_INTERVAL(this); - ESP_LOGCONFIG(TAG, " Data rate: %dMHz", (unsigned) (this->data_rate_ / 1000000)); #ifdef USE_POWER_SUPPLY ESP_LOGCONFIG(TAG, " Power Supply Configured: yes"); #endif From 4bc1a02fc2a5e9f2a0e8dde600a552fb6a0ecfb5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:52:03 -1000 Subject: [PATCH 281/302] [shtcx] Combine log statements to reduce loop blocking (#12960) --- esphome/components/shtcx/shtcx.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/shtcx/shtcx.cpp b/esphome/components/shtcx/shtcx.cpp index d532bd7f44..933dd9bde9 100644 --- a/esphome/components/shtcx/shtcx.cpp +++ b/esphome/components/shtcx/shtcx.cpp @@ -49,8 +49,10 @@ void SHTCXComponent::setup() { } void SHTCXComponent::dump_config() { - ESP_LOGCONFIG(TAG, "SHTCx:"); - ESP_LOGCONFIG(TAG, " Model: %s (%04x)", to_string(this->type_), this->sensor_id_); + ESP_LOGCONFIG(TAG, + "SHTCx:\n" + " Model: %s (%04x)", + to_string(this->type_), this->sensor_id_); LOG_I2C_DEVICE(this); if (this->is_failed()) { ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL); From c742db48b8857d684f6e291271a39cb8069f34f0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:52:57 -1000 Subject: [PATCH 282/302] [sim800l] Combine log statements to reduce loop blocking (#12961) --- esphome/components/sim800l/sim800l.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/sim800l/sim800l.cpp b/esphome/components/sim800l/sim800l.cpp index 55cadcf182..e3edda0e72 100644 --- a/esphome/components/sim800l/sim800l.cpp +++ b/esphome/components/sim800l/sim800l.cpp @@ -323,8 +323,10 @@ void Sim800LComponent::parse_cmd_(std::string message) { kick ESPHome callback now */ if (ok || message.compare(0, 6, "+CMGL:") == 0) { - ESP_LOGD(TAG, "Received SMS from: %s", this->sender_.c_str()); - ESP_LOGD(TAG, "%s", this->message_.c_str()); + ESP_LOGD(TAG, + "Received SMS from: %s\n" + "%s", + this->sender_.c_str(), this->message_.c_str()); this->sms_received_callback_.call(this->message_, this->sender_); this->state_ = STATE_RECEIVED_SMS; } else { From 9128fc312076812f0a8f0b0b04f96956f4829441 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:54:03 -1000 Subject: [PATCH 283/302] [sm16716] Combine log statements to reduce loop blocking (#12962) --- esphome/components/sm16716/sm16716.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/esphome/components/sm16716/sm16716.cpp b/esphome/components/sm16716/sm16716.cpp index aa33b7b679..b8e293929b 100644 --- a/esphome/components/sm16716/sm16716.cpp +++ b/esphome/components/sm16716/sm16716.cpp @@ -14,11 +14,13 @@ void SM16716::setup() { this->pwm_amounts_.resize(this->num_channels_, 0); } void SM16716::dump_config() { - ESP_LOGCONFIG(TAG, "SM16716:"); + ESP_LOGCONFIG(TAG, + "SM16716:\n" + " Total number of channels: %u\n" + " Number of chips: %u", + this->num_channels_, this->num_chips_); LOG_PIN(" Data Pin: ", this->data_pin_); LOG_PIN(" Clock Pin: ", this->clock_pin_); - ESP_LOGCONFIG(TAG, " Total number of channels: %u", this->num_channels_); - ESP_LOGCONFIG(TAG, " Number of chips: %u", this->num_chips_); } void SM16716::loop() { if (!this->update_) From 47223965b6924afae80c40c0084a4ee2c9228245 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:54:17 -1000 Subject: [PATCH 284/302] [sm2135] Combine log statements to reduce loop blocking (#12963) --- esphome/components/sm2135/sm2135.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/esphome/components/sm2135/sm2135.cpp b/esphome/components/sm2135/sm2135.cpp index e55f836929..1293c3f321 100644 --- a/esphome/components/sm2135/sm2135.cpp +++ b/esphome/components/sm2135/sm2135.cpp @@ -34,11 +34,13 @@ void SM2135::setup() { } void SM2135::dump_config() { - ESP_LOGCONFIG(TAG, "SM2135:"); + ESP_LOGCONFIG(TAG, + "SM2135:\n" + " CW Current: %dmA\n" + " RGB Current: %dmA", + 10 + (this->cw_current_ * 5), 10 + (this->rgb_current_ * 5)); LOG_PIN(" Data Pin: ", this->data_pin_); LOG_PIN(" Clock Pin: ", this->clock_pin_); - ESP_LOGCONFIG(TAG, " CW Current: %dmA", 10 + (this->cw_current_ * 5)); - ESP_LOGCONFIG(TAG, " RGB Current: %dmA", 10 + (this->rgb_current_ * 5)); } void SM2135::write_byte_(uint8_t data) { From f67a8d0d1fa9f5d10149f1be76f417d21cb45c68 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:55:11 -1000 Subject: [PATCH 285/302] [sonoff_d1] Combine log statements to reduce loop blocking (#12966) --- esphome/components/sonoff_d1/sonoff_d1.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/esphome/components/sonoff_d1/sonoff_d1.cpp b/esphome/components/sonoff_d1/sonoff_d1.cpp index 0ecde83b8b..7b99086546 100644 --- a/esphome/components/sonoff_d1/sonoff_d1.cpp +++ b/esphome/components/sonoff_d1/sonoff_d1.cpp @@ -93,8 +93,10 @@ bool SonoffD1Output::read_command_(uint8_t *cmd, size_t &len) { if (this->read_array(cmd, 6)) { #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE char hex_buf[format_hex_pretty_size(6)]; - ESP_LOGV(TAG, "[%04d] Reading from dimmer:", this->write_count_); - ESP_LOGV(TAG, "[%04d] %s", this->write_count_, format_hex_pretty_to(hex_buf, cmd, 6)); + ESP_LOGV(TAG, + "[%04d] Reading from dimmer:\n" + "[%04d] %s", + this->write_count_, this->write_count_, format_hex_pretty_to(hex_buf, cmd, 6)); #endif if (cmd[0] != 0xAA || cmd[1] != 0x55) { @@ -188,8 +190,10 @@ bool SonoffD1Output::write_command_(uint8_t *cmd, const size_t len, bool needs_a do { #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE char hex_buf[format_hex_pretty_size(SONOFF_D1_MAX_CMD_SIZE)]; - ESP_LOGV(TAG, "[%04d] Writing to the dimmer:", this->write_count_); - ESP_LOGV(TAG, "[%04d] %s", this->write_count_, format_hex_pretty_to(hex_buf, cmd, len)); + ESP_LOGV(TAG, + "[%04d] Writing to the dimmer:\n" + "[%04d] %s", + this->write_count_, this->write_count_, format_hex_pretty_to(hex_buf, cmd, len)); #endif this->write_array(cmd, len); this->write_count_++; From 9cd003034c1324b631d562deb9ef0d82153df0c7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:55:31 -1000 Subject: [PATCH 286/302] [spi_device] Combine log statements to reduce loop blocking (#12967) --- esphome/components/spi_device/spi_device.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/spi_device/spi_device.cpp b/esphome/components/spi_device/spi_device.cpp index dbfbc9eccb..4cc7286ba9 100644 --- a/esphome/components/spi_device/spi_device.cpp +++ b/esphome/components/spi_device/spi_device.cpp @@ -11,9 +11,11 @@ static const char *const TAG = "spi_device"; void SPIDeviceComponent::setup() { this->spi_setup(); } void SPIDeviceComponent::dump_config() { - ESP_LOGCONFIG(TAG, "SPIDevice"); + ESP_LOGCONFIG(TAG, + "SPIDevice\n" + " Mode: %d", + this->mode_); LOG_PIN(" CS pin: ", this->cs_); - ESP_LOGCONFIG(TAG, " Mode: %d", this->mode_); if (this->data_rate_ < 1000000) { ESP_LOGCONFIG(TAG, " Data rate: %" PRId32 "kHz", this->data_rate_ / 1000); } else { From ae3cdeda99f9803a7916e4a27890af7222fdb74f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:55:55 -1000 Subject: [PATCH 287/302] [ssd1325_spi] Combine log statements to reduce loop blocking (#12972) --- esphome/components/ssd1325_spi/ssd1325_spi.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/esphome/components/ssd1325_spi/ssd1325_spi.cpp b/esphome/components/ssd1325_spi/ssd1325_spi.cpp index 3c9dfd3324..07a5119d8f 100644 --- a/esphome/components/ssd1325_spi/ssd1325_spi.cpp +++ b/esphome/components/ssd1325_spi/ssd1325_spi.cpp @@ -19,12 +19,14 @@ void SPISSD1325::setup() { } void SPISSD1325::dump_config() { LOG_DISPLAY("", "SPI SSD1325", this); - ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); + ESP_LOGCONFIG(TAG, + " Model: %s\n" + " Initial Brightness: %.2f\n" + " External VCC: %s", + this->model_str_(), this->brightness_, YESNO(this->external_vcc_)); LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_); - ESP_LOGCONFIG(TAG, " Initial Brightness: %.2f", this->brightness_); - ESP_LOGCONFIG(TAG, " External VCC: %s", YESNO(this->external_vcc_)); LOG_UPDATE_INTERVAL(this); } void SPISSD1325::command(uint8_t value) { From d8387799d9dfb9fc1d7d09a48f990e1fa8e08d3d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:56:30 -1000 Subject: [PATCH 288/302] [sm2335] Combine log statements to reduce loop blocking (#12965) --- esphome/components/sm2335/sm2335.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/sm2335/sm2335.cpp b/esphome/components/sm2335/sm2335.cpp index 0580a782f5..f860517021 100644 --- a/esphome/components/sm2335/sm2335.cpp +++ b/esphome/components/sm2335/sm2335.cpp @@ -15,13 +15,13 @@ void SM2335::setup() { } void SM2335::dump_config() { - ESP_LOGCONFIG(TAG, "sm2335:"); - LOG_PIN(" Data Pin: ", this->data_pin_); - LOG_PIN(" Clock Pin: ", this->clock_pin_); ESP_LOGCONFIG(TAG, + "sm2335:\n" " Color Channels Max Power: %u\n" " White Channels Max Power: %u", this->max_power_color_channels_, this->max_power_white_channels_); + LOG_PIN(" Data Pin: ", this->data_pin_); + LOG_PIN(" Clock Pin: ", this->clock_pin_); } } // namespace sm2335 From a2bb9468ff3fa6c60498884d58b7c98c09e624c4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:57:43 -1000 Subject: [PATCH 289/302] [sm2235] Combine log statements to reduce loop blocking (#12964) Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> --- esphome/components/sm2235/sm2235.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/sm2235/sm2235.cpp b/esphome/components/sm2235/sm2235.cpp index 820fcb521a..4476862318 100644 --- a/esphome/components/sm2235/sm2235.cpp +++ b/esphome/components/sm2235/sm2235.cpp @@ -15,13 +15,13 @@ void SM2235::setup() { } void SM2235::dump_config() { - ESP_LOGCONFIG(TAG, "sm2235:"); - LOG_PIN(" Data Pin: ", this->data_pin_); - LOG_PIN(" Clock Pin: ", this->clock_pin_); ESP_LOGCONFIG(TAG, + "SM2235:\n" " Color Channels Max Power: %u\n" " White Channels Max Power: %u", this->max_power_color_channels_, this->max_power_white_channels_); + LOG_PIN(" Data Pin: ", this->data_pin_); + LOG_PIN(" Clock Pin: ", this->clock_pin_); } } // namespace sm2235 From ed332a034b87e09fb041965cec0f359edab6cd3b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:59:36 -1000 Subject: [PATCH 290/302] [ssd1351_spi] Combine log statements to reduce loop blocking (#12974) --- esphome/components/ssd1351_spi/ssd1351_spi.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/ssd1351_spi/ssd1351_spi.cpp b/esphome/components/ssd1351_spi/ssd1351_spi.cpp index ffac07b82b..b046f0adcb 100644 --- a/esphome/components/ssd1351_spi/ssd1351_spi.cpp +++ b/esphome/components/ssd1351_spi/ssd1351_spi.cpp @@ -19,11 +19,13 @@ void SPISSD1351::setup() { } void SPISSD1351::dump_config() { LOG_DISPLAY("", "SPI SSD1351", this); - ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); + ESP_LOGCONFIG(TAG, + " Model: %s\n" + " Initial Brightness: %.2f", + this->model_str_(), this->brightness_); LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_); - ESP_LOGCONFIG(TAG, " Initial Brightness: %.2f", this->brightness_); LOG_UPDATE_INTERVAL(this); } void SPISSD1351::command(uint8_t value) { From 06101c54a5ff2b72efd3dbd1045ff080b83f1bc6 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 16:59:52 -1000 Subject: [PATCH 291/302] [ssd1327_spi] Combine log statements to reduce loop blocking (#12973) --- esphome/components/ssd1327_spi/ssd1327_spi.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/ssd1327_spi/ssd1327_spi.cpp b/esphome/components/ssd1327_spi/ssd1327_spi.cpp index c26238ae19..54d1a51100 100644 --- a/esphome/components/ssd1327_spi/ssd1327_spi.cpp +++ b/esphome/components/ssd1327_spi/ssd1327_spi.cpp @@ -19,11 +19,13 @@ void SPISSD1327::setup() { } void SPISSD1327::dump_config() { LOG_DISPLAY("", "SPI SSD1327", this); - ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); + ESP_LOGCONFIG(TAG, + " Model: %s\n" + " Initial Brightness: %.2f", + this->model_str_(), this->brightness_); LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_); - ESP_LOGCONFIG(TAG, " Initial Brightness: %.2f", this->brightness_); LOG_UPDATE_INTERVAL(this); } void SPISSD1327::command(uint8_t value) { From 2381ea7ff5a62b41e416fbdb8dc363bdcb3dc17a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 17:00:09 -1000 Subject: [PATCH 292/302] [ssd1322_spi] Combine log statements to reduce loop blocking (#12971) --- esphome/components/ssd1322_spi/ssd1322_spi.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/ssd1322_spi/ssd1322_spi.cpp b/esphome/components/ssd1322_spi/ssd1322_spi.cpp index 6a8918353b..bc7d298922 100644 --- a/esphome/components/ssd1322_spi/ssd1322_spi.cpp +++ b/esphome/components/ssd1322_spi/ssd1322_spi.cpp @@ -19,11 +19,13 @@ void SPISSD1322::setup() { } void SPISSD1322::dump_config() { LOG_DISPLAY("", "SPI SSD1322", this); - ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); + ESP_LOGCONFIG(TAG, + " Model: %s\n" + " Initial Brightness: %.2f", + this->model_str_(), this->brightness_); LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_); - ESP_LOGCONFIG(TAG, " Initial Brightness: %.2f", this->brightness_); LOG_UPDATE_INTERVAL(this); } void SPISSD1322::command(uint8_t value) { From 0bd8a7e1a02c8d1960b77031f2a3c1434daf83a6 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 17:00:21 -1000 Subject: [PATCH 293/302] [ssd1306_spi] Combine log statements to reduce loop blocking (#12970) --- esphome/components/ssd1306_spi/ssd1306_spi.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/esphome/components/ssd1306_spi/ssd1306_spi.cpp b/esphome/components/ssd1306_spi/ssd1306_spi.cpp index d93742c0e5..db28dfc564 100644 --- a/esphome/components/ssd1306_spi/ssd1306_spi.cpp +++ b/esphome/components/ssd1306_spi/ssd1306_spi.cpp @@ -16,19 +16,19 @@ void SPISSD1306::setup() { } void SPISSD1306::dump_config() { LOG_DISPLAY("", "SPI SSD1306", this); - ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); - LOG_PIN(" CS Pin: ", this->cs_); - LOG_PIN(" DC Pin: ", this->dc_pin_); - LOG_PIN(" Reset Pin: ", this->reset_pin_); ESP_LOGCONFIG(TAG, + " Model: %s\n" " External VCC: %s\n" " Flip X: %s\n" " Flip Y: %s\n" " Offset X: %d\n" " Offset Y: %d\n" " Inverted Color: %s", - YESNO(this->external_vcc_), YESNO(this->flip_x_), YESNO(this->flip_y_), this->offset_x_, - this->offset_y_, YESNO(this->invert_)); + this->model_str_(), YESNO(this->external_vcc_), YESNO(this->flip_x_), YESNO(this->flip_y_), + this->offset_x_, this->offset_y_, YESNO(this->invert_)); + LOG_PIN(" CS Pin: ", this->cs_); + LOG_PIN(" DC Pin: ", this->dc_pin_); + LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_UPDATE_INTERVAL(this); } void SPISSD1306::command(uint8_t value) { From 28d30fdddbdd3272ac60f7395f55552be7ac688b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 17:00:40 -1000 Subject: [PATCH 294/302] [ssd1306_i2c] Combine log statements to reduce loop blocking (#12969) --- esphome/components/ssd1306_i2c/ssd1306_i2c.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/components/ssd1306_i2c/ssd1306_i2c.cpp b/esphome/components/ssd1306_i2c/ssd1306_i2c.cpp index 8e490834bc..ab6fee7b02 100644 --- a/esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +++ b/esphome/components/ssd1306_i2c/ssd1306_i2c.cpp @@ -20,18 +20,18 @@ void I2CSSD1306::setup() { } void I2CSSD1306::dump_config() { LOG_DISPLAY("", "I2C SSD1306", this); - LOG_I2C_DEVICE(this); - ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); - LOG_PIN(" Reset Pin: ", this->reset_pin_); ESP_LOGCONFIG(TAG, + " Model: %s\n" " External VCC: %s\n" " Flip X: %s\n" " Flip Y: %s\n" " Offset X: %d\n" " Offset Y: %d\n" " Inverted Color: %s", - YESNO(this->external_vcc_), YESNO(this->flip_x_), YESNO(this->flip_y_), this->offset_x_, - this->offset_y_, YESNO(this->invert_)); + this->model_str_(), YESNO(this->external_vcc_), YESNO(this->flip_x_), YESNO(this->flip_y_), + this->offset_x_, this->offset_y_, YESNO(this->invert_)); + LOG_I2C_DEVICE(this); + LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_UPDATE_INTERVAL(this); if (this->error_code_ == COMMUNICATION_FAILED) { From 80ab9485e00c2ea9debe20ccfc5b3290bafe4cf0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 17:00:59 -1000 Subject: [PATCH 295/302] [spi_led_strip] Combine log statements to reduce loop blocking (#12968) --- esphome/components/spi_led_strip/spi_led_strip.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/spi_led_strip/spi_led_strip.cpp b/esphome/components/spi_led_strip/spi_led_strip.cpp index 85c10ee87d..afb51afe3a 100644 --- a/esphome/components/spi_led_strip/spi_led_strip.cpp +++ b/esphome/components/spi_led_strip/spi_led_strip.cpp @@ -34,8 +34,10 @@ light::LightTraits SpiLedStrip::get_traits() { return traits; } void SpiLedStrip::dump_config() { - esph_log_config(TAG, "SPI LED Strip:"); - esph_log_config(TAG, " LEDs: %d", this->num_leds_); + esph_log_config(TAG, + "SPI LED Strip:\n" + " LEDs: %d", + this->num_leds_); if (this->data_rate_ >= spi::DATA_RATE_1MHZ) { esph_log_config(TAG, " Data rate: %uMHz", (unsigned) (this->data_rate_ / 1000000)); } else { From d107b37d3b6534b5aa3dc5b16d9bd3587c1c7fef Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 17:51:02 -1000 Subject: [PATCH 296/302] [st7735] Combine log statements to reduce loop blocking (#12977) --- esphome/components/st7735/st7735.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/esphome/components/st7735/st7735.cpp b/esphome/components/st7735/st7735.cpp index 160ba151f7..1a74b5ce1e 100644 --- a/esphome/components/st7735/st7735.cpp +++ b/esphome/components/st7735/st7735.cpp @@ -373,15 +373,18 @@ void ST7735::display_init_(const uint8_t *addr) { void ST7735::dump_config() { LOG_DISPLAY("", "ST7735", this); - ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_); - ESP_LOGD(TAG, " Buffer Size: %zu", this->get_buffer_length()); - ESP_LOGD(TAG, " Height: %d", this->height_); - ESP_LOGD(TAG, " Width: %d", this->width_); - ESP_LOGD(TAG, " ColStart: %d", this->colstart_); - ESP_LOGD(TAG, " RowStart: %d", this->rowstart_); + ESP_LOGCONFIG(TAG, + " Model: %s\n" + " Buffer Size: %zu\n" + " Height: %d\n" + " Width: %d\n" + " ColStart: %d\n" + " RowStart: %d", + this->model_str_(), this->get_buffer_length(), this->height_, this->width_, this->colstart_, + this->rowstart_); LOG_UPDATE_INTERVAL(this); } From 086eb4b93017b7030e22f9c753671093e1dbf308 Mon Sep 17 00:00:00 2001 From: Samuel Schultze Date: Mon, 5 Jan 2026 13:45:32 -0300 Subject: [PATCH 297/302] [whirlpool] support for 14 byte whirlpool IR receiver messages (#12774) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> --- esphome/components/whirlpool/whirlpool.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/esphome/components/whirlpool/whirlpool.cpp b/esphome/components/whirlpool/whirlpool.cpp index 1ac32f30da..6fe735362d 100644 --- a/esphome/components/whirlpool/whirlpool.cpp +++ b/esphome/components/whirlpool/whirlpool.cpp @@ -163,6 +163,7 @@ bool WhirlpoolClimate::on_receive(remote_base::RemoteReceiveData data) { } uint8_t remote_state[WHIRLPOOL_STATE_LENGTH] = {0}; + bool skip_footer = false; // Read all bytes. for (int i = 0; i < WHIRLPOOL_STATE_LENGTH; i++) { // Read bit @@ -170,6 +171,13 @@ bool WhirlpoolClimate::on_receive(remote_base::RemoteReceiveData data) { if (!data.expect_item(WHIRLPOOL_BIT_MARK, WHIRLPOOL_GAP)) return false; } + if (i == 14 && !data.is_valid()) { + // Remote control only sent 14 bytes, nothing more to read, not even the footer + ESP_LOGV(TAG, "Remote control only sent %d bytes", i); + skip_footer = true; + break; + } + for (int j = 0; j < 8; j++) { if (data.expect_item(WHIRLPOOL_BIT_MARK, WHIRLPOOL_ONE_SPACE)) { remote_state[i] |= 1 << j; @@ -183,7 +191,7 @@ bool WhirlpoolClimate::on_receive(remote_base::RemoteReceiveData data) { ESP_LOGVV(TAG, "Byte %d %02X", i, remote_state[i]); } // Validate footer - if (!data.expect_mark(WHIRLPOOL_BIT_MARK)) { + if (!data.expect_mark(WHIRLPOOL_BIT_MARK) && !skip_footer) { ESP_LOGV(TAG, "Footer fail"); return false; } @@ -196,7 +204,7 @@ bool WhirlpoolClimate::on_receive(remote_base::RemoteReceiveData data) { for (uint8_t i = 14; i < 20; i++) checksum20 ^= remote_state[i]; - if (checksum13 != remote_state[13] || checksum20 != remote_state[20]) { + if (checksum13 != remote_state[13] || (!skip_footer && checksum20 != remote_state[20])) { ESP_LOGVV(TAG, "Checksum fail"); return false; } From 0990a9c2b0515ce46f7fb477d64615409309885e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 5 Jan 2026 07:39:24 -1000 Subject: [PATCH 298/302] [esp32_ble] Avoid heap allocation in ESPBTUUID::from_raw for string literals (#12980) --- esphome/components/alpha3/alpha3.h | 6 ++--- esphome/components/esp32_ble/ble_uuid.cpp | 28 +++++++++++------------ esphome/components/esp32_ble/ble_uuid.h | 8 ++++++- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/esphome/components/alpha3/alpha3.h b/esphome/components/alpha3/alpha3.h index 7189ecbc33..19d8e99331 100644 --- a/esphome/components/alpha3/alpha3.h +++ b/esphome/components/alpha3/alpha3.h @@ -15,10 +15,8 @@ namespace alpha3 { namespace espbt = esphome::esp32_ble_tracker; static const espbt::ESPBTUUID ALPHA3_GENI_SERVICE_UUID = espbt::ESPBTUUID::from_uint16(0xfe5d); -static const espbt::ESPBTUUID ALPHA3_GENI_CHARACTERISTIC_UUID = - espbt::ESPBTUUID::from_raw({static_cast(0xa9), 0x7b, static_cast(0xb8), static_cast(0x85), 0x0, - 0x1a, 0x28, static_cast(0xaa), 0x2a, 0x43, 0x6e, 0x3, static_cast(0xd1), - static_cast(0xff), static_cast(0x9c), static_cast(0x85)}); +static const espbt::ESPBTUUID ALPHA3_GENI_CHARACTERISTIC_UUID = espbt::ESPBTUUID::from_raw( + {0xa9, 0x7b, 0xb8, 0x85, 0x00, 0x1a, 0x28, 0xaa, 0x2a, 0x43, 0x6e, 0x03, 0xd1, 0xff, 0x9c, 0x85}); static const int16_t GENI_RESPONSE_HEADER_LENGTH = 13; static const size_t GENI_RESPONSE_TYPE_LENGTH = 8; diff --git a/esphome/components/esp32_ble/ble_uuid.cpp b/esphome/components/esp32_ble/ble_uuid.cpp index c6b27f3bb9..7bad8d1866 100644 --- a/esphome/components/esp32_ble/ble_uuid.cpp +++ b/esphome/components/esp32_ble/ble_uuid.cpp @@ -39,36 +39,36 @@ ESPBTUUID ESPBTUUID::from_raw_reversed(const uint8_t *data) { ret.uuid_.uuid.uuid128[ESP_UUID_LEN_128 - 1 - i] = data[i]; return ret; } -ESPBTUUID ESPBTUUID::from_raw(const std::string &data) { +ESPBTUUID ESPBTUUID::from_raw(const char *data, size_t length) { ESPBTUUID ret; - if (data.length() == 4) { + if (length == 4) { // 16-bit UUID as 4-character hex string - auto parsed = parse_hex(data); + auto parsed = parse_hex(data, length); if (parsed.has_value()) { ret.uuid_.len = ESP_UUID_LEN_16; ret.uuid_.uuid.uuid16 = parsed.value(); } - } else if (data.length() == 8) { + } else if (length == 8) { // 32-bit UUID as 8-character hex string - auto parsed = parse_hex(data); + auto parsed = parse_hex(data, length); if (parsed.has_value()) { ret.uuid_.len = ESP_UUID_LEN_32; ret.uuid_.uuid.uuid32 = parsed.value(); } - } else if (data.length() == 16) { // how we can have 16 byte length string reprezenting 128 bit uuid??? needs to be - // investigated (lack of time) + } else if (length == 16) { // how we can have 16 byte length string reprezenting 128 bit uuid??? needs to be + // investigated (lack of time) ret.uuid_.len = ESP_UUID_LEN_128; - memcpy(ret.uuid_.uuid.uuid128, (uint8_t *) data.data(), 16); - } else if (data.length() == 36) { + memcpy(ret.uuid_.uuid.uuid128, reinterpret_cast(data), 16); + } else if (length == 36) { // If the length of the string is 36 bytes then we will assume it is a long hex string in // UUID format. ret.uuid_.len = ESP_UUID_LEN_128; int n = 0; - for (uint i = 0; i < data.length(); i += 2) { - if (data.c_str()[i] == '-') + for (size_t i = 0; i < length; i += 2) { + if (data[i] == '-') i++; - uint8_t msb = data.c_str()[i]; - uint8_t lsb = data.c_str()[i + 1]; + uint8_t msb = data[i]; + uint8_t lsb = data[i + 1]; if (msb > '9') msb -= 7; @@ -77,7 +77,7 @@ ESPBTUUID ESPBTUUID::from_raw(const std::string &data) { ret.uuid_.uuid.uuid128[15 - n++] = ((msb & 0x0F) << 4) | (lsb & 0x0F); } } else { - ESP_LOGE(TAG, "ERROR: UUID value not 2, 4, 16 or 36 bytes - %s", data.c_str()); + ESP_LOGE(TAG, "ERROR: UUID value not 2, 4, 16 or 36 bytes - %s", data); } return ret; } diff --git a/esphome/components/esp32_ble/ble_uuid.h b/esphome/components/esp32_ble/ble_uuid.h index ed561d70e4..2d8c69e44e 100644 --- a/esphome/components/esp32_ble/ble_uuid.h +++ b/esphome/components/esp32_ble/ble_uuid.h @@ -7,6 +7,7 @@ #ifdef USE_ESP32 #ifdef USE_ESP32_BLE_UUID +#include #include #include #include @@ -27,7 +28,12 @@ class ESPBTUUID { static ESPBTUUID from_raw(const uint8_t *data); static ESPBTUUID from_raw_reversed(const uint8_t *data); - static ESPBTUUID from_raw(const std::string &data); + static ESPBTUUID from_raw(const char *data, size_t length); + static ESPBTUUID from_raw(const char *data) { return from_raw(data, strlen(data)); } + static ESPBTUUID from_raw(const std::string &data) { return from_raw(data.c_str(), data.length()); } + static ESPBTUUID from_raw(std::initializer_list data) { + return from_raw(reinterpret_cast(data.begin()), data.size()); + } static ESPBTUUID from_uuid(esp_bt_uuid_t uuid); From 1bb4be435c6b9c384a5e9a77f566053aac18f08f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 5 Jan 2026 07:39:37 -1000 Subject: [PATCH 299/302] [esp32_ble_tracker, ble_client] Reduce heap allocations with stack-based string formatting (#12982) --- esphome/components/ble_client/automation.h | 10 ++++-- .../ble_client/output/ble_binary_output.cpp | 32 ++++++++++++------- .../ble_client/sensor/ble_sensor.cpp | 23 +++++++++---- .../text_sensor/ble_text_sensor.cpp | 20 ++++++++---- esphome/components/esp32_ble/ble_uuid.cpp | 8 ++--- esphome/components/esp32_ble/ble_uuid.h | 2 +- .../esp32_ble_client/ble_client_base.cpp | 2 +- .../esp32_ble_client/ble_client_base.h | 5 ++- .../esp32_ble_tracker/esp32_ble_tracker.cpp | 8 ++--- .../esp32_ble_tracker/esp32_ble_tracker.h | 7 ++++ 10 files changed, 77 insertions(+), 40 deletions(-) diff --git a/esphome/components/ble_client/automation.h b/esphome/components/ble_client/automation.h index f9f613ae76..01590d1d53 100644 --- a/esphome/components/ble_client/automation.h +++ b/esphome/components/ble_client/automation.h @@ -186,8 +186,10 @@ template class BLEClientWriteAction : public Action, publ case ESP_GATTC_SEARCH_CMPL_EVT: { auto *chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_); if (chr == nullptr) { + char char_buf[esp32_ble::UUID_STR_LEN]; + char service_buf[esp32_ble::UUID_STR_LEN]; esph_log_w("ble_write_action", "Characteristic %s was not found in service %s", - this->char_uuid_.to_string().c_str(), this->service_uuid_.to_string().c_str()); + this->char_uuid_.to_str(char_buf), this->service_uuid_.to_str(service_buf)); break; } this->char_handle_ = chr->handle; @@ -199,11 +201,13 @@ template class BLEClientWriteAction : public Action, publ this->write_type_ = ESP_GATT_WRITE_TYPE_NO_RSP; esph_log_d(Automation::TAG, "Write type: ESP_GATT_WRITE_TYPE_NO_RSP"); } else { - esph_log_e(Automation::TAG, "Characteristic %s does not allow writing", this->char_uuid_.to_string().c_str()); + char char_buf[esp32_ble::UUID_STR_LEN]; + esph_log_e(Automation::TAG, "Characteristic %s does not allow writing", this->char_uuid_.to_str(char_buf)); break; } this->node_state = espbt::ClientState::ESTABLISHED; - esph_log_d(Automation::TAG, "Found characteristic %s on device %s", this->char_uuid_.to_string().c_str(), + char char_buf[esp32_ble::UUID_STR_LEN]; + esph_log_d(Automation::TAG, "Found characteristic %s on device %s", this->char_uuid_.to_str(char_buf), ble_client_->address_str()); break; } diff --git a/esphome/components/ble_client/output/ble_binary_output.cpp b/esphome/components/ble_client/output/ble_binary_output.cpp index 1d874a65e4..1cb83b9d8b 100644 --- a/esphome/components/ble_client/output/ble_binary_output.cpp +++ b/esphome/components/ble_client/output/ble_binary_output.cpp @@ -9,12 +9,15 @@ static const char *const TAG = "ble_binary_output"; void BLEBinaryOutput::dump_config() { ESP_LOGCONFIG(TAG, "BLE Binary Output:"); + char service_buf[esp32_ble::UUID_STR_LEN]; + char char_buf[esp32_ble::UUID_STR_LEN]; + this->service_uuid_.to_str(service_buf); + this->char_uuid_.to_str(char_buf); ESP_LOGCONFIG(TAG, " MAC address : %s\n" " Service UUID : %s\n" " Characteristic UUID: %s", - this->parent_->address_str(), this->service_uuid_.to_string().c_str(), - this->char_uuid_.to_string().c_str()); + this->parent_->address_str(), service_buf, char_buf); LOG_BINARY_OUTPUT(this); } @@ -24,8 +27,10 @@ void BLEBinaryOutput::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_i case ESP_GATTC_SEARCH_CMPL_EVT: { auto *chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_); if (chr == nullptr) { - ESP_LOGW(TAG, "Characteristic %s was not found in service %s", this->char_uuid_.to_string().c_str(), - this->service_uuid_.to_string().c_str()); + char char_buf[esp32_ble::UUID_STR_LEN]; + char service_buf[esp32_ble::UUID_STR_LEN]; + ESP_LOGW(TAG, "Characteristic %s was not found in service %s", this->char_uuid_.to_str(char_buf), + this->service_uuid_.to_str(service_buf)); break; } this->char_handle_ = chr->handle; @@ -37,20 +42,24 @@ void BLEBinaryOutput::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_i this->write_type_ = ESP_GATT_WRITE_TYPE_NO_RSP; ESP_LOGD(TAG, "Write type: ESP_GATT_WRITE_TYPE_NO_RSP"); } else { - ESP_LOGE(TAG, "Characteristic %s does not allow writing with%s response", this->char_uuid_.to_string().c_str(), + char char_buf[esp32_ble::UUID_STR_LEN]; + ESP_LOGE(TAG, "Characteristic %s does not allow writing with%s response", this->char_uuid_.to_str(char_buf), this->require_response_ ? "" : "out"); break; } this->node_state = espbt::ClientState::ESTABLISHED; - ESP_LOGD(TAG, "Found characteristic %s on device %s", this->char_uuid_.to_string().c_str(), + char char_buf[esp32_ble::UUID_STR_LEN]; + ESP_LOGD(TAG, "Found characteristic %s on device %s", this->char_uuid_.to_str(char_buf), this->parent()->address_str()); this->node_state = espbt::ClientState::ESTABLISHED; break; } case ESP_GATTC_WRITE_CHAR_EVT: { if (param->write.handle == this->char_handle_) { - if (param->write.status != 0) - ESP_LOGW(TAG, "[%s] Write error, status=%d", this->char_uuid_.to_string().c_str(), param->write.status); + if (param->write.status != 0) { + char char_buf[esp32_ble::UUID_STR_LEN]; + ESP_LOGW(TAG, "[%s] Write error, status=%d", this->char_uuid_.to_str(char_buf), param->write.status); + } } break; } @@ -60,18 +69,19 @@ void BLEBinaryOutput::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_i } void BLEBinaryOutput::write_state(bool state) { + char char_buf[esp32_ble::UUID_STR_LEN]; if (this->node_state != espbt::ClientState::ESTABLISHED) { ESP_LOGW(TAG, "[%s] Not connected to BLE client. State update can not be written.", - this->char_uuid_.to_string().c_str()); + this->char_uuid_.to_str(char_buf)); return; } uint8_t state_as_uint = (uint8_t) state; - ESP_LOGV(TAG, "[%s] Write State: %d", this->char_uuid_.to_string().c_str(), state_as_uint); + ESP_LOGV(TAG, "[%s] Write State: %d", this->char_uuid_.to_str(char_buf), state_as_uint); esp_err_t err = esp_ble_gattc_write_char(this->parent()->get_gattc_if(), this->parent()->get_conn_id(), this->char_handle_, sizeof(state_as_uint), &state_as_uint, this->write_type_, ESP_GATT_AUTH_REQ_NONE); if (err != ESP_GATT_OK) - ESP_LOGW(TAG, "[%s] Write error, err=%d", this->char_uuid_.to_string().c_str(), err); + ESP_LOGW(TAG, "[%s] Write error, err=%d", this->char_uuid_.to_str(char_buf), err); } } // namespace esphome::ble_client diff --git a/esphome/components/ble_client/sensor/ble_sensor.cpp b/esphome/components/ble_client/sensor/ble_sensor.cpp index 38d90faff0..fe5f11bbc2 100644 --- a/esphome/components/ble_client/sensor/ble_sensor.cpp +++ b/esphome/components/ble_client/sensor/ble_sensor.cpp @@ -18,14 +18,17 @@ void BLESensor::loop() { void BLESensor::dump_config() { LOG_SENSOR("", "BLE Sensor", this); + char service_buf[esp32_ble::UUID_STR_LEN]; + char char_buf[esp32_ble::UUID_STR_LEN]; + char descr_buf[esp32_ble::UUID_STR_LEN]; ESP_LOGCONFIG(TAG, " MAC address : %s\n" " Service UUID : %s\n" " Characteristic UUID: %s\n" " Descriptor UUID : %s\n" " Notifications : %s", - this->parent()->address_str(), this->service_uuid_.to_string().c_str(), - this->char_uuid_.to_string().c_str(), this->descr_uuid_.to_string().c_str(), YESNO(this->notify_)); + this->parent()->address_str(), this->service_uuid_.to_str(service_buf), + this->char_uuid_.to_str(char_buf), this->descr_uuid_.to_str(descr_buf), YESNO(this->notify_)); LOG_UPDATE_INTERVAL(this); } @@ -51,8 +54,10 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga if (chr == nullptr) { this->status_set_warning(); this->publish_state(NAN); - ESP_LOGW(TAG, "No sensor characteristic found at service %s char %s", this->service_uuid_.to_string().c_str(), - this->char_uuid_.to_string().c_str()); + char service_buf[esp32_ble::UUID_STR_LEN]; + char char_buf[esp32_ble::UUID_STR_LEN]; + ESP_LOGW(TAG, "No sensor characteristic found at service %s char %s", this->service_uuid_.to_str(service_buf), + this->char_uuid_.to_str(char_buf)); break; } this->handle = chr->handle; @@ -61,9 +66,12 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga if (descr == nullptr) { this->status_set_warning(); this->publish_state(NAN); + char service_buf[esp32_ble::UUID_STR_LEN]; + char char_buf[esp32_ble::UUID_STR_LEN]; + char descr_buf[esp32_ble::UUID_STR_LEN]; ESP_LOGW(TAG, "No sensor descriptor found at service %s char %s descr %s", - this->service_uuid_.to_string().c_str(), this->char_uuid_.to_string().c_str(), - this->descr_uuid_.to_string().c_str()); + this->service_uuid_.to_str(service_buf), this->char_uuid_.to_str(char_buf), + this->descr_uuid_.to_str(descr_buf)); break; } this->handle = descr->handle; @@ -109,7 +117,8 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga break; } this->node_state = espbt::ClientState::ESTABLISHED; - ESP_LOGD(TAG, "Register for notify on %s complete", this->char_uuid_.to_string().c_str()); + char char_buf[esp32_ble::UUID_STR_LEN]; + ESP_LOGD(TAG, "Register for notify on %s complete", this->char_uuid_.to_str(char_buf)); } break; } diff --git a/esphome/components/ble_client/text_sensor/ble_text_sensor.cpp b/esphome/components/ble_client/text_sensor/ble_text_sensor.cpp index 415981a1ba..53c9a9d10e 100644 --- a/esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +++ b/esphome/components/ble_client/text_sensor/ble_text_sensor.cpp @@ -21,14 +21,17 @@ void BLETextSensor::loop() { void BLETextSensor::dump_config() { LOG_TEXT_SENSOR("", "BLE Text Sensor", this); + char service_buf[esp32_ble::UUID_STR_LEN]; + char char_buf[esp32_ble::UUID_STR_LEN]; + char descr_buf[esp32_ble::UUID_STR_LEN]; ESP_LOGCONFIG(TAG, " MAC address : %s\n" " Service UUID : %s\n" " Characteristic UUID: %s\n" " Descriptor UUID : %s\n" " Notifications : %s", - this->parent()->address_str(), this->service_uuid_.to_string().c_str(), - this->char_uuid_.to_string().c_str(), this->descr_uuid_.to_string().c_str(), YESNO(this->notify_)); + this->parent()->address_str(), this->service_uuid_.to_str(service_buf), + this->char_uuid_.to_str(char_buf), this->descr_uuid_.to_str(descr_buf), YESNO(this->notify_)); LOG_UPDATE_INTERVAL(this); } @@ -53,8 +56,10 @@ void BLETextSensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_ if (chr == nullptr) { this->status_set_warning(); this->publish_state(EMPTY); - ESP_LOGW(TAG, "No sensor characteristic found at service %s char %s", this->service_uuid_.to_string().c_str(), - this->char_uuid_.to_string().c_str()); + char service_buf[esp32_ble::UUID_STR_LEN]; + char char_buf[esp32_ble::UUID_STR_LEN]; + ESP_LOGW(TAG, "No sensor characteristic found at service %s char %s", this->service_uuid_.to_str(service_buf), + this->char_uuid_.to_str(char_buf)); break; } this->handle = chr->handle; @@ -63,9 +68,12 @@ void BLETextSensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_ if (descr == nullptr) { this->status_set_warning(); this->publish_state(EMPTY); + char service_buf[esp32_ble::UUID_STR_LEN]; + char char_buf[esp32_ble::UUID_STR_LEN]; + char descr_buf[esp32_ble::UUID_STR_LEN]; ESP_LOGW(TAG, "No sensor descriptor found at service %s char %s descr %s", - this->service_uuid_.to_string().c_str(), this->char_uuid_.to_string().c_str(), - this->descr_uuid_.to_string().c_str()); + this->service_uuid_.to_str(service_buf), this->char_uuid_.to_str(char_buf), + this->descr_uuid_.to_str(descr_buf)); break; } this->handle = descr->handle; diff --git a/esphome/components/esp32_ble/ble_uuid.cpp b/esphome/components/esp32_ble/ble_uuid.cpp index 7bad8d1866..334780e3b8 100644 --- a/esphome/components/esp32_ble/ble_uuid.cpp +++ b/esphome/components/esp32_ble/ble_uuid.cpp @@ -143,7 +143,7 @@ bool ESPBTUUID::operator==(const ESPBTUUID &uuid) const { return this->as_128bit() == uuid.as_128bit(); } esp_bt_uuid_t ESPBTUUID::get_uuid() const { return this->uuid_; } -void ESPBTUUID::to_str(std::span output) const { +const char *ESPBTUUID::to_str(std::span output) const { char *pos = output.data(); switch (this->uuid_.len) { @@ -155,7 +155,7 @@ void ESPBTUUID::to_str(std::span output) const { *pos++ = format_hex_pretty_char((this->uuid_.uuid.uuid16 >> 4) & 0x0F); *pos++ = format_hex_pretty_char(this->uuid_.uuid.uuid16 & 0x0F); *pos = '\0'; - return; + return output.data(); case ESP_UUID_LEN_32: *pos++ = '0'; @@ -164,7 +164,7 @@ void ESPBTUUID::to_str(std::span output) const { *pos++ = format_hex_pretty_char((this->uuid_.uuid.uuid32 >> shift) & 0x0F); } *pos = '\0'; - return; + return output.data(); default: case ESP_UUID_LEN_128: @@ -178,7 +178,7 @@ void ESPBTUUID::to_str(std::span output) const { } } *pos = '\0'; - return; + return output.data(); } } std::string ESPBTUUID::to_string() const { diff --git a/esphome/components/esp32_ble/ble_uuid.h b/esphome/components/esp32_ble/ble_uuid.h index 2d8c69e44e..ae593955a4 100644 --- a/esphome/components/esp32_ble/ble_uuid.h +++ b/esphome/components/esp32_ble/ble_uuid.h @@ -47,7 +47,7 @@ class ESPBTUUID { esp_bt_uuid_t get_uuid() const; std::string to_string() const; - void to_str(std::span output) const; + const char *to_str(std::span output) const; protected: esp_bt_uuid_t uuid_; diff --git a/esphome/components/esp32_ble_client/ble_client_base.cpp b/esphome/components/esp32_ble_client/ble_client_base.cpp index 26eb5dd092..149fcc79d5 100644 --- a/esphome/components/esp32_ble_client/ble_client_base.cpp +++ b/esphome/components/esp32_ble_client/ble_client_base.cpp @@ -529,7 +529,7 @@ void BLEClientBase::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_ case ESP_GAP_BLE_AUTH_CMPL_EVT: if (!this->check_addr(param->ble_security.auth_cmpl.bd_addr)) return; - char addr_str[MAC_ADDR_STR_LEN]; + char addr_str[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; format_mac_addr_upper(param->ble_security.auth_cmpl.bd_addr, addr_str); ESP_LOGI(TAG, "[%d] [%s] auth complete addr: %s", this->connection_index_, this->address_str_, addr_str); if (!param->ble_security.auth_cmpl.success) { diff --git a/esphome/components/esp32_ble_client/ble_client_base.h b/esphome/components/esp32_ble_client/ble_client_base.h index 7786495915..92c7444ee1 100644 --- a/esphome/components/esp32_ble_client/ble_client_base.h +++ b/esphome/components/esp32_ble_client/ble_client_base.h @@ -22,7 +22,6 @@ namespace esphome::esp32_ble_client { namespace espbt = esphome::esp32_ble_tracker; static const int UNSET_CONN_ID = 0xFFFF; -static constexpr size_t MAC_ADDR_STR_LEN = 18; // "AA:BB:CC:DD:EE:FF\0" class BLEClientBase : public espbt::ESPBTClient, public Component { public: @@ -111,8 +110,8 @@ class BLEClientBase : public espbt::ESPBTClient, public Component { esp_gatt_status_t status_{ESP_GATT_OK}; // Group 4: Arrays - char address_str_[MAC_ADDR_STR_LEN]{}; // 18 bytes: "AA:BB:CC:DD:EE:FF\0" - esp_bd_addr_t remote_bda_; // 6 bytes + char address_str_[MAC_ADDRESS_PRETTY_BUFFER_SIZE]{}; + esp_bd_addr_t remote_bda_; // 6 bytes // Group 5: 2-byte types uint16_t conn_id_{UNSET_CONN_ID}; diff --git a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp index 73a5dfb187..995755ac84 100644 --- a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +++ b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp @@ -639,9 +639,8 @@ void ESPBTDevice::parse_adv_(const uint8_t *payload, uint8_t len) { } std::string ESPBTDevice::address_str() const { - char mac[18]; - format_mac_addr_upper(this->address_, mac); - return mac; + char buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + return this->address_str_to(buf); } uint64_t ESPBTDevice::address_uint64() const { return esp32_ble::ble_addr_to_uint64(this->address_); } @@ -676,7 +675,8 @@ void ESP32BLETracker::print_bt_device_info(const ESPBTDevice &device) { } this->already_discovered_.push_back(address); - ESP_LOGD(TAG, "Found device %s RSSI=%d", device.address_str().c_str(), device.get_rssi()); + char addr_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; + ESP_LOGD(TAG, "Found device %s RSSI=%d", device.address_str_to(addr_buf), device.get_rssi()); const char *address_type_s; switch (device.get_address_type()) { diff --git a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h index b64e36279c..f538a0eddc 100644 --- a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +++ b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h @@ -6,6 +6,7 @@ #include "esphome/core/helpers.h" #include +#include #include #include @@ -73,6 +74,12 @@ class ESPBTDevice { std::string address_str() const; + /// Format MAC address into provided buffer, returns pointer to buffer for convenience + const char *address_str_to(std::span buf) const { + format_mac_addr_upper(this->address_, buf.data()); + return buf.data(); + } + uint64_t address_uint64() const; const uint8_t *address() const { return address_; } From 3fb5b289309a662db2c2ac26852ca01317480df9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 5 Jan 2026 07:40:04 -1000 Subject: [PATCH 300/302] [captive_portal] Avoid defer overhead on ESP8266 when saving WiFi credentials (#12981) --- esphome/components/captive_portal/captive_portal.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/esphome/components/captive_portal/captive_portal.cpp b/esphome/components/captive_portal/captive_portal.cpp index d0515166b6..5ba70bcc50 100644 --- a/esphome/components/captive_portal/captive_portal.cpp +++ b/esphome/components/captive_portal/captive_portal.cpp @@ -54,8 +54,13 @@ void CaptivePortal::handle_wifisave(AsyncWebServerRequest *request) { " SSID='%s'\n" " Password=" LOG_SECRET("'%s'"), ssid.c_str(), psk.c_str()); +#ifdef USE_ESP8266 + // ESP8266 is single-threaded, call directly + wifi::global_wifi_component->save_wifi_sta(ssid, psk); +#else // Defer save to main loop thread to avoid NVS operations from HTTP thread this->defer([ssid, psk]() { wifi::global_wifi_component->save_wifi_sta(ssid, psk); }); +#endif request->redirect(ESPHOME_F("/?save")); } From e87a3b39160c29fc622df614cdea35794b026bb7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 5 Jan 2026 07:40:24 -1000 Subject: [PATCH 301/302] [light] Use zero-copy set_effect overload in JSON schema parsing (#12979) --- esphome/components/light/light_json_schema.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/light/light_json_schema.cpp b/esphome/components/light/light_json_schema.cpp index 7679002e74..98b03f9458 100644 --- a/esphome/components/light/light_json_schema.cpp +++ b/esphome/components/light/light_json_schema.cpp @@ -160,7 +160,7 @@ void LightJSONSchema::parse_json(LightState &state, LightCall &call, JsonObject if (root[ESPHOME_F("effect")].is()) { const char *effect = root[ESPHOME_F("effect")]; - call.set_effect(effect); + call.set_effect(effect, strlen(effect)); } if (root[ESPHOME_F("effect_index")].is()) { From 6aaaae5d0e81a177c4b692d71d5427a672b3a4ca Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 5 Jan 2026 07:40:49 -1000 Subject: [PATCH 302/302] [ci] Add LibreTiny (BK72XX) to memory impact analysis (#12983) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- esphome/analyze_memory/const.py | 88 +++++++++++++++++++++++++++++- script/ci_memory_impact_extract.py | 9 ++- script/determine-jobs.py | 14 +++-- 3 files changed, 103 insertions(+), 8 deletions(-) diff --git a/esphome/analyze_memory/const.py b/esphome/analyze_memory/const.py index 78af82059f..8dd6664bc0 100644 --- a/esphome/analyze_memory/const.py +++ b/esphome/analyze_memory/const.py @@ -88,6 +88,77 @@ SYMBOL_PATTERNS = { "sys_mbox_new", "sys_arch_mbox_tryfetch", ], + # LibreTiny/Beken BK7231 radio calibration + "bk_radio_cal": [ + "bk7011_", + "calibration_main", + "gcali_", + "rwnx_cal", + ], + # LibreTiny/Beken WiFi MAC layer + "bk_wifi_mac": [ + "rxu_", # RX upper layer + "txu_", # TX upper layer + "txl_", # TX lower layer + "rxl_", # RX lower layer + "scanu_", # Scan unit + "mm_hw_", # MAC management hardware + "mm_bcn", # MAC management beacon + "mm_tim", # MAC management TIM + "mm_check", # MAC management checks + "sm_connect", # Station management + "me_beacon", # Management entity beacon + "me_build", # Management entity build + "hapd_", # Host AP daemon + "chan_pre_", # Channel management + "handle_probe_", # Probe handling + ], + # LibreTiny/Beken system control + "bk_system": [ + "sctrl_", # System control + "icu_ctrl", # Interrupt control unit + "gdma_ctrl", # DMA control + "mpb_ctrl", # MPB control + "uf2_", # UF2 OTA + "bkreg_", # Beken registers + ], + # LibreTiny/Beken BLE stack + "bk_ble": [ + "gapc_", # GAP client + "gattc_", # GATT client + "attc_", # ATT client + "attmdb_", # ATT database + "atts_", # ATT server + "l2cc_", # L2CAP + "prf_env", # Profile environment + ], + # LibreTiny/Beken scheduler + "bk_scheduler": [ + "sch_plan_", # Scheduler plan + "sch_prog_", # Scheduler program + "sch_arb_", # Scheduler arbiter + ], + # LibreTiny/Beken DMA descriptors + "bk_dma": [ + "rx_payload_desc", + "rx_dma_hdrdesc", + "tx_hw_desc", + "host_event_data", + "host_cmd_data", + ], + # ARM EABI compiler runtime (LibreTiny uses ARM Cortex-M) + "arm_runtime": [ + "__aeabi_", + "__adddf3", + "__subdf3", + "__muldf3", + "__divdf3", + "__addsf3", + "__subsf3", + "__mulsf3", + "__divsf3", + "__gnu_unwind", + ], "xtensa": ["xt_", "_xt_", "xPortEnterCriticalTimeout"], "heap": ["heap_", "multi_heap"], "spi_flash": ["spi_flash"], @@ -782,7 +853,22 @@ SYMBOL_PATTERNS = { "math_internal": ["__mdiff", "__lshift", "__mprec_tens", "quorem"], "character_class": ["__chclass"], "camellia": ["camellia_", "camellia_feistel"], - "crypto_tables": ["FSb", "FSb2", "FSb3", "FSb4"], + "crypto_tables": [ + "FSb", + "FSb2", + "FSb3", + "FSb4", + "Te0", # AES encryption table + "Td0", # AES decryption table + "crc32_table", # CRC32 lookup table + "crc_tab", # CRC lookup table + ], + "crypto_hash": [ + "SHA1Transform", # SHA1 hash function + "MD5Transform", # MD5 hash function + "SHA256", + "SHA512", + ], "event_buffer": ["g_eb_list_desc", "eb_space"], "base_node": ["base_node_", "base_node_add_handler"], "file_descriptor": ["s_fd_table"], diff --git a/script/ci_memory_impact_extract.py b/script/ci_memory_impact_extract.py index 77d59417e3..dd91fa861c 100755 --- a/script/ci_memory_impact_extract.py +++ b/script/ci_memory_impact_extract.py @@ -92,18 +92,23 @@ def run_detailed_analysis(build_dir: str) -> dict | None: print(f"Build directory not found: {build_dir}", file=sys.stderr) return None - # Find firmware.elf + # Find firmware.elf (or raw_firmware.elf for LibreTiny) elf_path = None for elf_candidate in [ build_path / "firmware.elf", build_path / ".pioenvs" / build_path.name / "firmware.elf", + # LibreTiny uses raw_firmware.elf + build_path / "raw_firmware.elf", + build_path / ".pioenvs" / build_path.name / "raw_firmware.elf", ]: if elf_candidate.exists(): elf_path = str(elf_candidate) break if not elf_path: - print(f"firmware.elf not found in {build_dir}", file=sys.stderr) + print( + f"firmware.elf/raw_firmware.elf not found in {build_dir}", file=sys.stderr + ) return None # Find idedata.json - check multiple locations diff --git a/script/determine-jobs.py b/script/determine-jobs.py index 5cc3f2570a..44e8e4b5ab 100755 --- a/script/determine-jobs.py +++ b/script/determine-jobs.py @@ -89,6 +89,7 @@ class Platform(StrEnum): ESP32_C6_IDF = "esp32-c6-idf" ESP32_S2_IDF = "esp32-s2-idf" ESP32_S3_IDF = "esp32-s3-idf" + BK72XX_ARD = "bk72xx-ard" # LibreTiny BK7231N # Memory impact analysis constants @@ -120,6 +121,7 @@ PLATFORM_SPECIFIC_COMPONENTS = frozenset( # fastest build times, most sensitive to code size changes # 3. ESP32 IDF - Primary ESP32 platform, most representative of modern ESPHome # 4-6. Other ESP32 variants - Less commonly used but still supported +# 7. BK72XX - LibreTiny platform (good for detecting LibreTiny-specific changes) MEMORY_IMPACT_PLATFORM_PREFERENCE = [ Platform.ESP32_C6_IDF, # ESP32-C6 IDF (newest, supports Thread/Zigbee) Platform.ESP8266_ARD, # ESP8266 Arduino (most memory constrained, fastest builds) @@ -127,6 +129,7 @@ MEMORY_IMPACT_PLATFORM_PREFERENCE = [ Platform.ESP32_C3_IDF, # ESP32-C3 IDF Platform.ESP32_S2_IDF, # ESP32-S2 IDF Platform.ESP32_S3_IDF, # ESP32-S3 IDF + Platform.BK72XX_ARD, # LibreTiny BK7231N ] @@ -404,7 +407,7 @@ def _detect_platform_hint_from_filename(filename: str) -> Platform | None: - wifi_component_esp_idf.cpp, *_idf.h -> ESP32 IDF variants - wifi_component_esp8266.cpp, *_esp8266.h -> ESP8266_ARD - *_esp32*.cpp -> ESP32 IDF (generic) - - *_libretiny.cpp, *_retiny.* -> LibreTiny (not in preference list) + - *_libretiny.cpp, *_bk72*.* -> BK72XX (LibreTiny) - *_pico.cpp, *_rp2040.* -> RP2040 (not in preference list) Args: @@ -438,10 +441,11 @@ def _detect_platform_hint_from_filename(filename: str) -> Platform | None: if "esp32" in filename_lower: return Platform.ESP32_IDF - # LibreTiny and RP2040 are not in MEMORY_IMPACT_PLATFORM_PREFERENCE - # so we don't return them as hints - # if "retiny" in filename_lower or "libretiny" in filename_lower: - # return None # No specific LibreTiny platform preference + # LibreTiny (via 'libretiny' pattern or BK72xx-specific files) + if "libretiny" in filename_lower or "bk72" in filename_lower: + return Platform.BK72XX_ARD + + # RP2040 is not in MEMORY_IMPACT_PLATFORM_PREFERENCE # if "pico" in filename_lower or "rp2040" in filename_lower: # return None # No RP2040 platform preference