From f14fda4c07ea0dd94fe2315c76cd33e50e5de38a Mon Sep 17 00:00:00 2001 From: Ben Youngblood Date: Tue, 11 Jul 2023 17:12:32 -0700 Subject: [PATCH] Use Z-Wave XML to generate command/device class mappings This also adds support for new command classes in the 2022B specification. --- lib/grizzly/zwave/command_classes.ex | 138 +- lib/grizzly/zwave/device_classes.ex | 201 +- lib/grizzly/zwave/generated_mappings.ex | 298 + lib/mix/tasks/zwave.gen.xml.ex | 139 + mix.exs | 1 + mix.lock | 1 + resources/ZWave_custom_cmd_classes.xml | 18826 ++++++++++++---------- 7 files changed, 10642 insertions(+), 8962 deletions(-) create mode 100644 lib/grizzly/zwave/generated_mappings.ex create mode 100644 lib/mix/tasks/zwave.gen.xml.ex diff --git a/lib/grizzly/zwave/command_classes.ex b/lib/grizzly/zwave/command_classes.ex index 102e28a8..8db3f422 100644 --- a/lib/grizzly/zwave/command_classes.ex +++ b/lib/grizzly/zwave/command_classes.ex @@ -4,153 +4,27 @@ defmodule Grizzly.ZWave.CommandClasses do defmodule Generate do @moduledoc false - @mappings [ - {0x00, :no_operation}, - {0x02, :zensor_net}, - {0x20, :basic}, - {0x21, :controller_replication}, - {0x22, :application_status}, - {0x23, :zip}, - {0x24, :security_panel_mode}, - {0x25, :switch_binary}, - {0x26, :switch_multilevel}, - {0x27, :switch_all}, - {0x28, :switch_toggle_binary}, - {0x2A, :chimney_fan}, - {0x2B, :scene_activation}, - {0x2C, :scene_actuator_conf}, - {0x2D, :scene_controller_conf}, - {0x2E, :security_panel_zone}, - {0x2F, :security_panel_zone_sensor}, - {0x30, :sensor_binary}, - {0x31, :sensor_multilevel}, - {0x32, :meter}, - {0x33, :switch_color}, - {0x34, :network_management_inclusion}, - {0x35, :meter_pulse}, - {0x36, :basic_tariff_info}, - {0x37, :hrv_status}, - {0x38, :thermostat_heating}, - {0x39, :hrv_control}, - {0x3A, :dcp_config}, - {0x3B, :dcp_monitor}, - {0x3C, :meter_tbl_config}, - {0x3D, :meter_tbl_monitor}, - {0x3E, :meter_tbl_push}, - {0x3F, :prepayment}, - {0x40, :thermostat_mode}, - {0x41, :prepayment_encapsulation}, - {0x42, :thermostat_operating_state}, - {0x43, :thermostat_setpoint}, - {0x44, :thermostat_fan_mode}, - {0x45, :thermostat_fan_state}, - {0x46, :climate_control_schedule}, - {0x47, :thermostat_setback}, - {0x48, :rate_tbl_config}, - {0x49, :rate_tbl_monitor}, - {0x4A, :tariff_config}, - {0x4B, :tariff_tbl_monitor}, - {0x4C, :door_lock_logging}, - {0x4D, :network_management_basic}, - {0x4E, :schedule_entry_lock}, - {0x4F, :zip_6lowpan}, - {0x50, :basic_window_covering}, - {0x51, :mtp_window_covering}, - {0x52, :network_management_proxy}, - {0x53, :schedule}, - {0x54, :network_management_primary}, - {0x55, :transport_service}, - {0x56, :crc_16_encap}, - {0x57, :application_capability}, - {0x58, :zip_nd}, - {0x59, :association_group_info}, - {0x5A, :device_reset_locally}, - {0x5B, :central_scene}, - {0x5C, :ip_association}, - {0x5D, :antitheft}, - {0x5E, :zwaveplus_info}, - {0x5F, :zip_gateway}, - {0x60, :multi_channel}, - {0x61, :zip_portal}, - {0x62, :door_lock}, - {0x63, :user_code}, - {0x64, :humidity_control_setpoint}, - {0x65, :dmx}, - {0x66, :barrier_operator}, - {0x67, :network_management_installation_maintenance}, - {0x68, :zip_naming}, - {0x69, :mailbox}, - {0x6A, :window_covering}, - {0x6B, :irrigation}, - {0x6C, :supervision}, - {0x6D, :humidity_control_mode}, - {0x6E, :humidity_control_operating_state}, - {0x6F, :entry_control}, - {0x70, :configuration}, - {0x71, :alarm}, - {0x72, :manufacturer_specific}, - {0x73, :powerlevel}, - {0x74, :inclusion_controller}, - {0x75, :protection}, - {0x76, :lock}, - {0x77, :node_naming}, - {0x78, :node_provisioning}, - {0x7A, :firmware_update_md}, - {0x7B, :grouping_name}, - {0x7C, :remote_association_activate}, - {0x7D, :remote_association}, - {0x7E, :antitheft_unlock}, - {0x80, :battery}, - {0x81, :clock}, - {0x82, :hail}, - {0x84, :wake_up}, - {0x85, :association}, - {0x86, :version}, - {0x87, :indicator}, - {0x88, :proprietary}, - {0x89, :language}, - {0x8A, :time}, - {0x8B, :time_parameters}, - {0x8C, :geographic_location}, - {0x8E, :multi_channel_association}, - {0x8F, :multi_cmd}, - {0x90, :energy_production}, - {0x91, :manufacturer_proprietary}, - {0x92, :screen_md}, - {0x93, :screen_attributes}, - {0x94, :simple_av_control}, - {0x95, :av_content_directory_md}, - {0x96, :av_content_renderer_status}, - {0x97, :av_content_search_md}, - {0x98, :security}, - {0x99, :av_tagging_md}, - {0x9A, :ip_configuration}, - {0x9B, :association_command_configuration}, - {0x9C, :sensor_alarm}, - {0x9D, :silence_alarm}, - {0x9E, :sensor_configuration}, - {0x9F, :security_2}, - {0xEF, :mark}, - {0xF0, :non_interoperable} - ] + import Grizzly.ZWave.GeneratedMappings, only: [command_class_mappings: 0] defmacro __before_compile__(_) do + mappings = command_class_mappings() + to_byte = - for {byte, command_class} <- @mappings do + for {byte, command_class} <- mappings do quote do def to_byte(unquote(command_class)), do: unquote(byte) end end from_byte = - for {byte, command_class} <- @mappings do + for {byte, command_class} <- mappings do quote do def from_byte(unquote(byte)), do: {:ok, unquote(command_class)} end end command_classes = - @mappings + mappings |> Enum.map(&elem(&1, 1)) |> Enum.reverse() |> Enum.reduce(&{:|, [], [&1, &2]}) diff --git a/lib/grizzly/zwave/device_classes.ex b/lib/grizzly/zwave/device_classes.ex index dce79da4..d6090d21 100644 --- a/lib/grizzly/zwave/device_classes.ex +++ b/lib/grizzly/zwave/device_classes.ex @@ -6,211 +6,48 @@ defmodule Grizzly.ZWave.DeviceClasses do defmodule Generate do @moduledoc false - @basic_mappings [ - {0x01, :controller}, - {0x02, :static_controller}, - {0x03, :slave}, - {0x04, :routing_slave} - ] - - @generic_mappings [ - {0x01, :generic_controller}, - {0x02, :static_controller}, - {0x03, :av_control_point}, - {0x04, :display}, - {0x05, :network_extender}, - {0x06, :appliance}, - {0x07, :sensor_notification}, - {0x08, :thermostat}, - {0x09, :window_covering}, - {0x0F, :repeater_slave}, - {0x10, :switch_binary}, - {0x11, :switch_multilevel}, - {0x12, :switch_remote}, - {0x13, :switch_toggle}, - {0x15, :zip_node}, - {0x16, :ventilation}, - {0x17, :security_panel}, - {0x18, :wall_controller}, - {0x20, :sensor_binary}, - {0x21, :sensor_multilevel}, - {0x30, :meter_pulse}, - {0x31, :meter}, - {0x40, :entry_control}, - {0x50, :semi_interoperable}, - {0xA1, :sensor_alarm}, - {0xFF, :non_interoperable} - ] - - @specific_mappings [ - # generic controller (0x01) - {:generic_controller, 0x00, :not_used}, - {:generic_controller, 0x01, :portable_remote_controller}, - {:generic_controller, 0x02, :portable_scene_controller}, - {:generic_controller, 0x03, :installer_tool}, - {:generic_controller, 0x04, :remote_control_av}, - {:generic_controller, 0x06, :remote_control_simple}, - # static controller (0x02) - {:static_controller, 0x00, :not_used}, - {:static_controller, 0x01, :pc_controller}, - {:static_controller, 0x02, :scene_controller}, - {:static_controller, 0x03, :static_installer_tool}, - {:static_controller, 0x04, :set_top_box}, - {:static_controller, 0x05, :sub_system_controller}, - {:static_controller, 0x06, :tv}, - {:static_controller, 0x07, :gateway}, - # av control point (0x03) - {:av_control_point, 0x00, :not_used}, - {:av_control_point, 0x01, :sound_switch}, - {:av_control_point, 0x04, :satellite_receiver}, - {:av_control_point, 0x11, :satellite_receiver_v2}, - {:av_control_point, 0x12, :doorbell}, - # display - {:display, 0x00, :not_used}, - {:display, 0x01, :simple_display}, - # network_extender - {:network_extender, 0x00, :not_used}, - {:network_extender, 0x01, :secure_extender}, - # appliance - {:appliance, 0x00, :not_used}, - {:appliance, 0x01, :general_appliance}, - {:appliance, 0x02, :kitchen_appliance}, - {:appliance, 0x03, :laundry_appliance}, - # sensor_notification - {:sensor_notification, 0x00, :not_used}, - {:sensor_notification, 0x01, :notification_sensor}, - # thermostat - {:thermostat, 0x00, :not_used}, - {:thermostat, 0x01, :thermostat_heating}, - {:thermostat, 0x02, :thermostat_general}, - {:thermostat, 0x03, :setback_schedule_thermostat}, - {:thermostat, 0x04, :setpoint_thermostat}, - {:thermostat, 0x05, :setback_thermostat}, - {:thermostat, 0x06, :thermostat_general_v2}, - # window covering - {:window_covering, 0x00, :not_used}, - {:window_covering, 0x01, :simple_window_covering}, - # switch_binary - {:switch_binary, 0x00, :not_used}, - {:switch_binary, 0x01, :power_switch_binary}, - {:switch_binary, 0x02, :color_tunable_binary}, - {:switch_binary, 0x03, :scene_switch_binary}, - {:switch_binary, 0x04, :power_strip}, - {:switch_binary, 0x05, :siren}, - {:switch_binary, 0x06, :valve_open_close}, - {:switch_binary, 0x07, :irrigation_controller}, - # switch multilevel - {:switch_multilevel, 0x00, :not_used}, - {:switch_multilevel, 0x01, :power_switch_multilevel}, - {:switch_multilevel, 0x02, :color_tunable_multilevel}, - {:switch_multilevel, 0x03, :motor_multipositions}, - {:switch_multilevel, 0x04, :scene_switch_multilevel}, - {:switch_multilevel, 0x05, :class_a_motor_control}, - {:switch_multilevel, 0x06, :class_b_motor_control}, - {:switch_multilevel, 0x07, :class_c_motor_control}, - {:switch_multilevel, 0x08, :fan_switch}, - # repeater slave - {:repeater_slave, 0x00, :not_used}, - {:repeater_slave, 0x01, :repeater_slave}, - {:repeater_slave, 0x02, :virtual_node}, - # switch remote (0x13) - {:switch_remote, 0x00, :not_used}, - {:switch_remote, 0x01, :switch_remote_binary}, - {:switch_remote, 0x02, :switch_remote_multilevel}, - {:switch_remote, 0x03, :switch_remote_toggle_binary}, - {:switch_remote, 0x04, :switch_remote_toggle_multilevel}, - # switch toggle (0x14) - {:switch_toggle, 0x00, :not_used}, - {:switch_toggle, 0x01, :switch_toggle_binary}, - {:switch_toggle, 0x02, :switch_toggle_multilevel}, - # zip node (0x15) - {:zip_node, 0x00, :not_used}, - {:zip_node, 0x01, :zip_adv_node}, - {:zip_node, 0x02, :zip_tun_node}, - # security_panel (0x17) - {:security_panel, 0x00, :not_used}, - {:security_panel, 0x01, :zoned_security_panel}, - # wall controller (0x18) - {:wall_controller, 0x00, :not_used}, - {:wall_controller, 0x01, :basic_wall_controller}, - # sensor binary (0x20) - {:sensor_binary, 0x00, :not_used}, - {:sensor_binary, 0x01, :routing_sensor_binary}, - # sensor multilevel (0x21) - {:sensor_multilevel, 0x00, :not_used}, - {:sensor_multilevel, 0x01, :routing_sensor_multilevel}, - {:sensor_multilevel, 0x02, :chimney_fan}, - # meter pulse (0x30) - {:meter_pulse, 0x00, :not_used}, - # meter (0x31) - {:meter, 0x00, :not_used}, - {:meter, 0x01, :simple_meter}, - {:meter, 0x02, :adv_energy_meter}, - {:meter, 0x03, :whole_home_meter_simple}, - # entry control (0x40) - {:entry_control, 0x00, :not_used}, - {:entry_control, 0x01, :door_lock}, - {:entry_control, 0x02, :advanced_door_lock}, - {:entry_control, 0x03, :secure_keypad_door_lock}, - {:entry_control, 0x04, :secure_keypad_door_lock_deadbolt}, - {:entry_control, 0x05, :secure_door}, - {:entry_control, 0x06, :secure_gate}, - {:entry_control, 0x07, :secure_barrier_addon}, - {:entry_control, 0x08, :secure_barrier_open_only}, - {:entry_control, 0x09, :secure_barrier_close_only}, - {:entry_control, 0x0A, :secure_lockbox}, - {:entry_control, 0x0B, :secure_keypad}, - # semi interoperable (0x50) - {:semi_interoperable, 0x00, :not_used}, - {:semi_interoperable, 0x01, :energy_production}, - # sensor alarm (0xA1) - {:sensor_alarm, 0x00, :not_used}, - {:sensor_alarm, 0x01, :basic_routing_alarm_sensor}, - {:sensor_alarm, 0x02, :routing_alarm_sensor}, - {:sensor_alarm, 0x03, :basic_zensor_net_alarm_sensor}, - {:sensor_alarm, 0x04, :zensor_net_alarm_sensor}, - {:sensor_alarm, 0x05, :adv_zensor_net_alarm_sensor}, - {:sensor_alarm, 0x06, :basic_routing_smoke_sensor}, - {:sensor_alarm, 0x07, :routing_smoke_sensor}, - {:sensor_alarm, 0x08, :basic_zensor_net_smoke_sensor}, - {:sensor_alarm, 0x09, :zensor_net_smoke_sensor}, - {:sensor_alarm, 0x0A, :adv_zensor_net_smoke_sensor}, - {:sensor_alarm, 0x0B, :alarm_sensor}, - # non interoperable (0xFF) - {:non_interoperable, 0x00, :not_used} - ] + import Grizzly.ZWave.GeneratedMappings, + only: [ + basic_device_class_mappings: 0, + generic_device_class_mappings: 0, + specific_device_class_mappings: 0 + ] defmacro __before_compile__(_) do + basic_mappings = basic_device_class_mappings() + generic_mappings = generic_device_class_mappings() + specific_mappings = specific_device_class_mappings() + basic_device_class_from_byte = - for {byte, device_class} <- @basic_mappings do + for {byte, device_class} <- basic_mappings do quote do def basic_device_class_from_byte(unquote(byte)), do: {:ok, unquote(device_class)} end end basic_device_class_to_byte = - for {byte, device_class} <- @basic_mappings do + for {byte, device_class} <- basic_mappings do quote do def basic_device_class_to_byte(unquote(device_class)), do: unquote(byte) end end generic_device_class_from_byte = - for {byte, device_class} <- @generic_mappings do + for {byte, device_class} <- generic_mappings do quote do def generic_device_class_from_byte(unquote(byte)), do: {:ok, unquote(device_class)} end end generic_device_class_to_byte = - for {byte, device_class} <- @generic_mappings do + for {byte, device_class} <- generic_mappings do quote do def generic_device_class_to_byte(unquote(device_class)), do: unquote(byte) end end specific_device_class_from_byte = - for {gen_class, byte, spec_class} <- @specific_mappings do + for {gen_class, byte, spec_class} <- specific_mappings do quote do def specific_device_class_from_byte(unquote(gen_class), unquote(byte)), do: {:ok, unquote(spec_class)} @@ -218,7 +55,7 @@ defmodule Grizzly.ZWave.DeviceClasses do end specific_device_class_to_byte = - for {gen_class, byte, spec_class} <- @specific_mappings do + for {gen_class, byte, spec_class} <- specific_mappings do quote do def specific_device_class_to_byte(unquote(gen_class), unquote(spec_class)), do: unquote(byte) @@ -226,19 +63,19 @@ defmodule Grizzly.ZWave.DeviceClasses do end basic_classes_union = - @basic_mappings + basic_mappings |> Enum.map(&elem(&1, 1)) |> Enum.reverse() |> Enum.reduce(&{:|, [], [&1, &2]}) generic_classes_union = - @generic_mappings + generic_mappings |> Enum.map(&elem(&1, 1)) |> Enum.reverse() |> Enum.reduce(&{:|, [], [&1, &2]}) specific_classes_union = - @specific_mappings + specific_mappings |> Enum.map(&elem(&1, 2)) |> Enum.reverse() |> Enum.uniq() diff --git a/lib/grizzly/zwave/generated_mappings.ex b/lib/grizzly/zwave/generated_mappings.ex new file mode 100644 index 00000000..283632c8 --- /dev/null +++ b/lib/grizzly/zwave/generated_mappings.ex @@ -0,0 +1,298 @@ +# !! THIS FILE IS GENERATED BY `mix zwave.gen.xml` +# !! DO NOT EDIT DIRECTLY + +defmodule Grizzly.ZWave.GeneratedMappings do + @moduledoc false + def command_class_mappings() do + [ + {0, :no_operation}, + {1, :zwave_cmd_class}, + {2, :zensor_net}, + {4, :zwave_cmd_class_lr}, + {32, :basic}, + {33, :controller_replication}, + {34, :application_status}, + {35, :zip}, + {36, :security_panel_mode}, + {37, :switch_binary}, + {38, :switch_multilevel}, + {39, :switch_all}, + {40, :switch_toggle_binary}, + {41, :switch_toggle_multilevel}, + {42, :chimney_fan}, + {43, :scene_activation}, + {44, :scene_actuator_conf}, + {45, :scene_controller_conf}, + {46, :security_panel_zone}, + {47, :security_panel_zone_sensor}, + {48, :sensor_binary}, + {49, :sensor_multilevel}, + {50, :meter}, + {51, :switch_color}, + {52, :network_management_inclusion}, + {53, :meter_pulse}, + {54, :basic_tariff_info}, + {55, :hrv_status}, + {56, :thermostat_heating}, + {57, :hrv_control}, + {58, :dcp_config}, + {59, :dcp_monitor}, + {60, :meter_tbl_config}, + {61, :meter_tbl_monitor}, + {62, :meter_tbl_push}, + {63, :prepayment}, + {64, :thermostat_mode}, + {65, :prepayment_encapsulation}, + {66, :thermostat_operating_state}, + {67, :thermostat_setpoint}, + {68, :thermostat_fan_mode}, + {69, :thermostat_fan_state}, + {70, :climate_control_schedule}, + {71, :thermostat_setback}, + {72, :rate_tbl_config}, + {73, :rate_tbl_monitor}, + {74, :tariff_config}, + {75, :tariff_tbl_monitor}, + {76, :door_lock_logging}, + {77, :network_management_basic}, + {78, :schedule_entry_lock}, + {79, :zip_6lowpan}, + {80, :basic_window_covering}, + {81, :mtp_window_covering}, + {82, :network_management_proxy}, + {83, :schedule}, + {84, :network_management_primary}, + {85, :transport_service}, + {86, :crc_16_encap}, + {87, :application_capability}, + {88, :zip_nd}, + {89, :association_group_info}, + {90, :device_reset_locally}, + {91, :central_scene}, + {92, :ip_association}, + {93, :antitheft}, + {94, :zwaveplus_info}, + {95, :zip_gateway}, + {96, :multi_channel}, + {97, :zip_portal}, + {98, :door_lock}, + {99, :user_code}, + {100, :humidity_control_setpoint}, + {101, :dmx}, + {102, :barrier_operator}, + {103, :network_management_installation_maintenance}, + {104, :zip_naming}, + {105, :mailbox}, + {106, :window_covering}, + {107, :irrigation}, + {108, :supervision}, + {109, :humidity_control_mode}, + {110, :humidity_control_operating_state}, + {111, :entry_control}, + {112, :configuration}, + {113, :alarm}, + {114, :manufacturer_specific}, + {115, :powerlevel}, + {116, :inclusion_controller}, + {117, :protection}, + {118, :lock}, + {119, :node_naming}, + {120, :node_provisioning}, + {121, :sound_switch}, + {122, :firmware_update_md}, + {123, :grouping_name}, + {124, :remote_association_activate}, + {125, :remote_association}, + {126, :antitheft_unlock}, + {128, :battery}, + {129, :clock}, + {130, :hail}, + {132, :wake_up}, + {133, :association}, + {134, :version}, + {135, :indicator}, + {136, :proprietary}, + {137, :language}, + {138, :time}, + {139, :time_parameters}, + {140, :geographic_location}, + {142, :multi_channel_association}, + {143, :multi_cmd}, + {144, :energy_production}, + {145, :manufacturer_proprietary}, + {146, :screen_md}, + {147, :screen_attributes}, + {148, :simple_av_control}, + {149, :av_content_directory_md}, + {150, :av_content_renderer_status}, + {151, :av_content_search_md}, + {152, :security}, + {153, :av_tagging_md}, + {154, :ip_configuration}, + {155, :association_command_configuration}, + {156, :sensor_alarm}, + {157, :silence_alarm}, + {158, :sensor_configuration}, + {159, :security_2}, + {160, :ir_repeater}, + {161, :authentication}, + {162, :authentication_media_write}, + {163, :generic_schedule}, + {239, :mark}, + {240, :non_interoperable} + ] + end + + def basic_device_class_mappings() do + [{1, :controller}, {2, :static_controller}, {3, :slave}, {4, :routing_slave}] + end + + def generic_device_class_mappings() do + [ + {1, :generic_controller}, + {2, :static_controller}, + {3, :av_control_point}, + {4, :display}, + {5, :network_extender}, + {6, :appliance}, + {7, :sensor_notification}, + {8, :thermostat}, + {9, :window_covering}, + {15, :repeater_slave}, + {16, :switch_binary}, + {17, :switch_multilevel}, + {18, :switch_remote}, + {19, :switch_toggle}, + {21, :zip_node}, + {22, :ventilation}, + {23, :security_panel}, + {24, :wall_controller}, + {32, :sensor_binary}, + {33, :sensor_multilevel}, + {48, :meter_pulse}, + {49, :meter}, + {64, :entry_control}, + {80, :semi_interoperable}, + {161, :sensor_alarm}, + {255, :non_interoperable} + ] + end + + def specific_device_class_mappings() do + [ + {:appliance, 0, :not_used}, + {:appliance, 1, :general_appliance}, + {:appliance, 2, :kitchen_appliance}, + {:appliance, 3, :laundry_appliance}, + {:av_control_point, 0, :not_used}, + {:av_control_point, 1, :sound_switch}, + {:av_control_point, 4, :satellite_receiver}, + {:av_control_point, 17, :satellite_receiver_v2}, + {:av_control_point, 18, :doorbell}, + {:display, 0, :not_used}, + {:display, 1, :simple_display}, + {:entry_control, 0, :not_used}, + {:entry_control, 1, :door_lock}, + {:entry_control, 2, :advanced_door_lock}, + {:entry_control, 3, :secure_keypad_door_lock}, + {:entry_control, 4, :secure_keypad_door_lock_deadbolt}, + {:entry_control, 5, :secure_door}, + {:entry_control, 6, :secure_gate}, + {:entry_control, 7, :secure_barrier_addon}, + {:entry_control, 8, :secure_barrier_open_only}, + {:entry_control, 9, :secure_barrier_close_only}, + {:entry_control, 10, :secure_lockbox}, + {:entry_control, 11, :secure_keypad}, + {:generic_controller, 0, :not_used}, + {:generic_controller, 1, :portable_remote_controller}, + {:generic_controller, 2, :portable_scene_controller}, + {:generic_controller, 3, :portable_installer_tool}, + {:generic_controller, 4, :remote_control_av}, + {:generic_controller, 6, :remote_control_simple}, + {:meter, 0, :not_used}, + {:meter, 1, :simple_meter}, + {:meter, 2, :adv_energy_control}, + {:meter, 3, :whole_home_meter_simple}, + {:meter_pulse, 0, :not_used}, + {:network_extender, 0, :not_used}, + {:network_extender, 1, :secure_extender}, + {:non_interoperable, 0, :not_used}, + {:repeater_slave, 0, :not_used}, + {:repeater_slave, 1, :repeater_slave}, + {:repeater_slave, 2, :virtual_node}, + {:repeater_slave, 3, :ir_repeater}, + {:security_panel, 0, :not_used}, + {:security_panel, 1, :zoned_security_panel}, + {:semi_interoperable, 0, :not_used}, + {:semi_interoperable, 1, :energy_production}, + {:sensor_alarm, 0, :not_used}, + {:sensor_alarm, 1, :basic_routing_alarm_sensor}, + {:sensor_alarm, 2, :routing_alarm_sensor}, + {:sensor_alarm, 3, :basic_zensor_net_alarm_sensor}, + {:sensor_alarm, 4, :zensor_net_alarm_sensor}, + {:sensor_alarm, 5, :adv_zensor_net_alarm_sensor}, + {:sensor_alarm, 6, :basic_routing_smoke_sensor}, + {:sensor_alarm, 7, :routing_smoke_sensor}, + {:sensor_alarm, 8, :basic_zensor_net_smoke_sensor}, + {:sensor_alarm, 9, :zensor_net_smoke_sensor}, + {:sensor_alarm, 10, :adv_zensor_net_smoke_sensor}, + {:sensor_alarm, 11, :alarm_sensor}, + {:sensor_binary, 0, :not_used}, + {:sensor_binary, 1, :routing_sensor_binary}, + {:sensor_multilevel, 0, :not_used}, + {:sensor_multilevel, 1, :routing_sensor_multilevel}, + {:sensor_multilevel, 2, :chimney_fan}, + {:sensor_notification, 0, :not_used}, + {:sensor_notification, 1, :notification_sensor}, + {:static_controller, 0, :not_used}, + {:static_controller, 1, :pc_controller}, + {:static_controller, 2, :scene_controller}, + {:static_controller, 3, :static_installer_tool}, + {:static_controller, 4, :set_top_box}, + {:static_controller, 5, :sub_system_controller}, + {:static_controller, 6, :tv}, + {:static_controller, 7, :gateway}, + {:switch_binary, 0, :not_used}, + {:switch_binary, 1, :power_switch_binary}, + {:switch_binary, 2, :color_tunable_binary}, + {:switch_binary, 3, :scene_switch_binary}, + {:switch_binary, 4, :power_strip}, + {:switch_binary, 5, :siren}, + {:switch_binary, 6, :valve_open_close}, + {:switch_binary, 7, :irrigation_controller}, + {:switch_multilevel, 0, :not_used}, + {:switch_multilevel, 1, :power_switch_multilevel}, + {:switch_multilevel, 2, :color_tunable_multilevel}, + {:switch_multilevel, 3, :motor_multiposition}, + {:switch_multilevel, 4, :scene_switch_multilevel}, + {:switch_multilevel, 5, :class_a_motor_control}, + {:switch_multilevel, 6, :class_b_motor_control}, + {:switch_multilevel, 7, :class_c_motor_control}, + {:switch_multilevel, 8, :fan_switch}, + {:switch_remote, 0, :not_used}, + {:switch_remote, 1, :switch_remote_binary}, + {:switch_remote, 2, :switch_remote_multilevel}, + {:switch_remote, 3, :switch_remote_toggle_binary}, + {:switch_remote, 4, :switch_remote_toggle_multilevel}, + {:switch_toggle, 0, :not_used}, + {:switch_toggle, 1, :switch_toggle_binary}, + {:switch_toggle, 2, :switch_toggle_multilevel}, + {:thermostat, 0, :not_used}, + {:thermostat, 1, :thermostat_heating}, + {:thermostat, 2, :thermostat_general}, + {:thermostat, 3, :setback_schedule_thermostat}, + {:thermostat, 4, :setpoint_thermostat}, + {:thermostat, 5, :setback_thermostat}, + {:thermostat, 6, :thermostat_general_v2}, + {:ventilation, 0, :not_used}, + {:ventilation, 1, :residential_hrv}, + {:wall_controller, 0, :not_used}, + {:wall_controller, 1, :basic_wall_controller}, + {:window_covering, 0, :not_used}, + {:window_covering, 1, :simple_window_covering}, + {:zip_node, 0, :not_used}, + {:zip_node, 1, :zip_tun_node}, + {:zip_node, 2, :zip_adv_node} + ] + end +end diff --git a/lib/mix/tasks/zwave.gen.xml.ex b/lib/mix/tasks/zwave.gen.xml.ex new file mode 100644 index 00000000..ef247128 --- /dev/null +++ b/lib/mix/tasks/zwave.gen.xml.ex @@ -0,0 +1,139 @@ +if Code.ensure_loaded?(SweetXml) do + defmodule Mix.Tasks.Zwave.Gen.Xml do + @moduledoc """ + Generates a module that provides mappings based on the data in `ZWave_custom_cmd_classes.xml`. + + mix zwave.gen.xml + + ### Flags + + * `--input ` - reads the xml from the provided path + * `--dry-run` - print the generated module out to the console + * `--output ` - writes the generated module at the provided path + """ + + use Mix.Task + + import SweetXml + + @shortdoc "Generates a module that provides mappings based on the data in `ZWave_custom_cmd_classes.xml`" + + @switches [dry_run: :boolean] + + @command_class_name_overrides %{ + 0x4F => :zip_6lowpan, + 0x59 => :association_group_info, + 0x96 => :av_content_renderer_status + } + + def run(args) do + {opts, _, _} = OptionParser.parse(args, switches: @switches) + + input_path = Keyword.get(opts, :input, "resources/ZWave_custom_cmd_classes.xml") + + doc = input_path |> File.read!() |> parse() + + command_class_mappings = build_macro(:command_class_mappings, command_class_mappings(doc)) + + basic_device_class_mappings = + build_macro(:basic_device_class_mappings, basic_device_class_mappings(doc)) + + generic_device_class_mappings = + build_macro(:generic_device_class_mappings, generic_device_class_mappings(doc)) + + specific_device_class_mappings = + build_macro(:specific_device_class_mappings, specific_device_class_mappings(doc)) + + module = + quote do + defmodule Grizzly.ZWave.GeneratedMappings do + @moduledoc false + + unquote(command_class_mappings) + unquote(basic_device_class_mappings) + unquote(generic_device_class_mappings) + unquote(specific_device_class_mappings) + end + end + + module_code = module |> Macro.to_string() |> Code.format_string!() + + module_code = + """ + # !! THIS FILE IS GENERATED BY `mix zwave.gen.xml` + # !! DO NOT EDIT DIRECTLY + + #{module_code} + """ + + if opts[:dry_run] do + Mix.shell().info(module_code) + else + output_path = Keyword.get(opts, :output, "lib/grizzly/zwave/generated_mappings.ex") + + Mix.Generator.create_file(output_path, module_code) + end + end + + defp build_macro(name, value) do + quote do + defmacro unquote(name)(), do: unquote(value) + end + end + + defp command_class_mappings(doc) do + doc + |> xpath(~x"//zw_classes/cmd_class"l, key: ~x"@key"s, name: ~x"@name"s) + |> Enum.map(key_name_mapper("COMMAND_CLASS_", @command_class_name_overrides)) + |> Enum.uniq_by(fn {key, _} -> key end) + |> Enum.sort() + end + + defp basic_device_class_mappings(doc) do + doc + |> xpath(~x"//zw_classes/bas_dev"l, key: ~x"@key"s, name: ~x"@name"s) + |> Enum.map(key_name_mapper("BASIC_TYPE_")) + |> Enum.sort() + end + + defp generic_device_class_mappings(doc) do + doc + |> xpath(~x"//zw_classes/gen_dev"l, key: ~x"@key"s, name: ~x"@name"s) + |> Enum.map(key_name_mapper("GENERIC_TYPE_")) + |> Enum.sort() + end + + defp specific_device_class_mappings(doc) do + doc + |> xpath(~x"//zw_classes/gen_dev"l, + generic_type: ~x"@name"s, + specific_types: [~x"./spec_dev"l, key: ~x"@key"s, name: ~x"@name"s] + ) + |> Enum.flat_map(fn %{generic_type: generic_type, specific_types: specific_types} -> + Enum.map(specific_types, fn %{name: name, key: key} -> + generic_type = parse_name(generic_type, "GENERIC_TYPE_") + specific_type = parse_name(name, "SPECIFIC_TYPE_") + key = parse_hex_string(key) + Macro.escape({generic_type, key, specific_type}) + end) + end) + |> Enum.sort() + end + + defp key_name_mapper(name_prefix, name_overrides \\ %{}) do + fn %{name: name, key: key} -> + key = parse_hex_string(key) + name = Map.get(name_overrides, key, parse_name(name, name_prefix)) + {key, name} + end + end + + defp parse_hex_string(string) do + string |> String.replace_leading("0x", "") |> String.to_integer(16) + end + + defp parse_name(name, prefix) do + name |> String.replace(prefix, "") |> Macro.underscore() |> String.to_atom() + end + end +end diff --git a/mix.exs b/mix.exs index e0653f46..1271d38c 100644 --- a/mix.exs +++ b/mix.exs @@ -38,6 +38,7 @@ defmodule Grizzly.MixProject do {:muontrap, "~> 1.0 or ~> 0.4"}, {:ex_doc, "~> 0.21", only: :docs, runtime: false}, {:credo, "~> 1.4", only: [:dev, :test], runtime: false}, + {:sweet_xml, "~> 0.7", only: [:dev, :test]}, {:junit_formatter, "~> 3.3", only: :test}, {:beam_notify, "~> 1.0 or ~> 0.2.0"} ] diff --git a/mix.lock b/mix.lock index 67365a44..745e6700 100644 --- a/mix.lock +++ b/mix.lock @@ -17,4 +17,5 @@ "makeup_erlang": {:hex, :makeup_erlang, "0.1.2", "ad87296a092a46e03b7e9b0be7631ddcf64c790fa68a9ef5323b6cbb36affc72", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f3f5a1ca93ce6e092d92b6d9c049bcda58a3b617a8d888f8e7231c85630e8108"}, "muontrap": {:hex, :muontrap, "1.3.1", "828e095467ba81f59774bd1285428a69cd89ec98e87cb421cc886b56f921ede6", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "f789de809d5ab124a30c8fa24a6b3b477824ca786a57347493ff35301120ab04"}, "nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"}, + "sweet_xml": {:hex, :sweet_xml, "0.7.3", "debb256781c75ff6a8c5cbf7981146312b66f044a2898f453709a53e5031b45b", [:mix], [], "hexpm", "e110c867a1b3fe74bfc7dd9893aa851f0eed5518d0d7cad76d7baafd30e4f5ba"}, } diff --git a/resources/ZWave_custom_cmd_classes.xml b/resources/ZWave_custom_cmd_classes.xml index 8886e635..cd40d6a9 100644 --- a/resources/ZWave_custom_cmd_classes.xml +++ b/resources/ZWave_custom_cmd_classes.xml @@ -1,20 +1,21 @@ - - - - - - - + + + + + + + - + + - + - + @@ -28,73 +29,74 @@ - + - + - + - + - + - + - + + - + - + - + - + - - - - - - - - - - + + + + + + + + + + - + - + - + - + - + - + @@ -104,7 +106,7 @@ - + @@ -113,81 +115,73 @@ - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - - - - - + + + - - - - - - - + + + - - - - - - + + + + @@ -203,22 +197,15 @@ - - - - - - - - - - - - + + + + + - + @@ -233,18 +220,14 @@ - - - - - - - - + + + + - - + + @@ -259,21 +242,20 @@ - - + - - - - + + + + - - + + @@ -290,12 +272,10 @@ - - - - - - + + + + @@ -310,26 +290,17 @@ - - - + - - - - - - - - - - - - + + + + + - + @@ -344,23 +315,19 @@ - - - - - + + + - - - - - + + + - - + + @@ -375,21 +342,20 @@ - - + - - - - + + + + - - + + @@ -405,8 +371,8 @@ - - + + @@ -422,8 +388,8 @@ - - + + @@ -438,21 +404,19 @@ - - + + - - + + - - - - - - + + + + @@ -469,26 +433,18 @@ - - - + - - - - - - - - - - - + + + + + - + @@ -505,23 +461,19 @@ - - - - - + + + - - - - - + + + - - + + @@ -538,21 +490,21 @@ - + - - - - + + + + - - + + @@ -570,8 +522,8 @@ - - + + @@ -589,8 +541,8 @@ - - + + @@ -607,21 +559,19 @@ - - + + - - + + - - - - - - + + + + @@ -638,26 +588,18 @@ - - - + - - - - - - - - - - - + + + + + - + @@ -674,23 +616,19 @@ - - - - - + + + - - - - - + + + - - + + @@ -707,21 +645,21 @@ - + - - - - + + + + - - + + @@ -739,8 +677,8 @@ - - + + @@ -758,8 +696,8 @@ - - + + @@ -776,21 +714,19 @@ - - + + - - + + - - - - - - + + + + @@ -808,26 +744,18 @@ - - - + - - - - - - - - - - - + + + + + - + @@ -845,23 +773,19 @@ - - - - - + + + - - - - - + + + - - + + @@ -879,21 +803,21 @@ - + - - - - + + + + - - + + @@ -912,8 +836,8 @@ - - + + @@ -932,8 +856,8 @@ - - + + @@ -951,21 +875,19 @@ - - + + - - + + - - - - - - + + + + @@ -987,26 +909,18 @@ - - - + - - - - - - - - - - - + + + + + - + @@ -1028,23 +942,19 @@ - - - - - + + + - - - - - + + + - - + + @@ -1066,21 +976,21 @@ - + - - - - + + + + - - + + @@ -1103,8 +1013,8 @@ - - + + @@ -1127,8 +1037,8 @@ - - + + @@ -1150,21 +1060,56 @@ - - + + - - + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -1184,28 +1129,93 @@ - + + + + + + + + + + + - - + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1225,25 +1235,128 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - + + @@ -1263,23 +1376,27 @@ - + + + + + - + - - - - + + + + - - + + @@ -1299,11 +1416,15 @@ - + + + + + - - + + @@ -1323,11 +1444,15 @@ - + + + + + - - + + @@ -1347,305 +1472,330 @@ - - - - + + + + + + + + - - + + - - - + + + - - - + - - - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + - - - + + + - - - - - - + + - - - - - + + + - - - - - + + + - - - - - - + + + + - - - - - - - - - - - - + + + + + + - - - - - - + + + + - - - - - + + + - - - - - + + + - - - - - - + + + + - - - - - - + + + + + + - - - - - + + + + + - - - + + + + + + + + + + + + + + + + + - - + + + + + + + - - - - + + + + + + + + - - - - - - - - - + + + + + + + + + - - - + + + - - - + + + - - - + + + - - - - - + + + + + - - + + - - - - - - - - - - - - - - + + + + + + - - - + - - - - + + + + - + - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + + + + - - - - - + + + + + - - + + + + + + + + + + + - - + + + - - - + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + @@ -1653,7 +1803,7 @@ - + @@ -1661,7 +1811,7 @@ - + @@ -1669,7 +1819,7 @@ - + @@ -1677,7 +1827,7 @@ - + @@ -1686,25 +1836,25 @@ - - + + - - - + + + - + - - + + @@ -1712,179 +1862,156 @@ - - - - + + + + - - + + - - - + + + - - + + - - - - - + + + - - - - + + - - - - - - + + + + - - - - + + - - - + + + - - + + - - - + + + - - + + + + + + + - - + + - - - - - - - - - - - - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - + + + + + - - + + - - + + - - + + - - + + - - + + - - - - - + + + - - - + + - - - - + + + + - - + + - - - + + + - - + + - - - + + + @@ -1893,19 +2020,19 @@ - + - - + + - - - + + + @@ -1914,426 +2041,340 @@ - + - - - - + + - + - - + + - - + + - - - - + + + + - - + + - - - + + + - - + + - - - - - + + + - - - - + + - - - - - - - - - - + + + + + + + + - - - - + + + + + + + + + - - - - - + + + + - - - + + + + + + + + - - - - - + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + - - + + - - - - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - + + + - - - - - - - - - + + + + + - - - + + + - - - - + + - - - - - - + + + + - - + + - - - - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - + + + - - - - - - - - - + + + + + - - - + + + - - - - + + - - - - - - + + + + - - + + - - - - - - + + + + - - + + - - - - + + - - - - - - - - - + + + + + - - - - + + - - - - - - - - - + + + + + - - - - + + - - - - - - + + + + @@ -2342,143 +2383,105 @@ - - + + - - + + - - - - - + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - + + + - - - - - - - - - + + + + + - - - + + + - - - - + + - - - - - - + + + + - - + + - - - - - - + + + + - - + + - - - - + + - - - - - - - - - + + + + + - - - - + + - - - - - - - - - + + + + + - - - - + + - - - - - - + + + + @@ -2486,243 +2489,126 @@ - + - - + + - - + + - - + + - - - - + + - + - - - - - - - - - - - + + + + + - - - - - - - - - + + + + + - - - - - - - - - - - - - + + + + + - - - - - - - - - + + + + + - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -2730,174 +2616,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + - - - - + + + + - - + + - - - - - - + + - - + + - - + + - - - - - - + + - - - + + + @@ -2906,22 +2714,16 @@ - - + + - - - - - - - - - + + + - - + + @@ -2932,43 +2734,35 @@ - - - - + + + + - - + + - - - - - - + + - - + + - - + + - - - - - - + + - - - + + + @@ -2978,22 +2772,16 @@ - - + + - - - - - - - - - + + + - - + + @@ -3005,43 +2793,35 @@ - - - - + + + + - - + + - - - - - - + + - - + + - - + + - - - - - - + + - - - + + + @@ -3051,20 +2831,14 @@ - - + + - - - - - - - - - - + + + + @@ -3074,14 +2848,14 @@ - + - - + + @@ -3093,234 +2867,278 @@ - - - - - - - - - - - - - - - + + + + + + - - - - + + + - - + + + + + + + + - - - - - - + + + + - - + + + - - + + + + + + + + - - - - - - - - - - + + + + + + + + + + + - - - - - + + + - - + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - - + + + + + - - + + - - + + + - - - - - - + + + - - - - - - + + + + + + + - - - - - + + + + + + + + + + + + + + + - - + + + + - - + + - - - - - - + + + + + + + + + + + + - - - + - - - + + + - - - - - - - - + + + - - - - - - - - - - + + + + - - + + - - + + - - - - - - - - + + + + + + + + + + + + - - + + + + + + - - + + + - - + + + + + + + + + + + + - - + + + + + + - - - - + + + + + + + + + + + + + - - - - - - + + + + - - - + - - - + + + - - - - - - - - + + + + - - - - - - - - - - - - - - - - + + + + + + - - + + @@ -3328,95 +3146,61 @@ - - + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - + + + + - - - + - - - + + + - - - - - - - - + + + + - - - - - - - - - - - - - - - - - + + + + + + + - - + + @@ -3424,8 +3208,8 @@ - - + + @@ -3438,127 +3222,73 @@ - - - + - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - + - - - - - - + + + + - - - + - - - + + + - - - - - - - - + + + + - - - - - - - - - - - - - - - - - + + + + + + + - - - + - - + + @@ -3567,8 +3297,8 @@ - - + + @@ -3582,165 +3312,346 @@ - - + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + - - + + + + + + - - + + + + + + - - + + + + - - - - - - + + + + + + + + + - - + + + + + + + + + + + + - - + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + - - + + + + + + - - + + + + + + - - + + + - - + + + + + + + + + + + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + - - - - - + + + - - - - - - + + + + - - - - - + + + - - - - - - - - - - - - + + + + + + + + - + - - - - - - + + + + - + - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -3750,9 +3661,9 @@ - - - + + + @@ -3762,10 +3673,10 @@ - - - - + + + + @@ -3773,8 +3684,8 @@ - - + + @@ -3782,21 +3693,17 @@ - - - - - + + + - - - - + + - - - + + + @@ -3806,8 +3713,8 @@ - - + + @@ -3816,19 +3723,19 @@ - - + + - - + + - - - - + + + + @@ -3839,26 +3746,24 @@ - - - - - + + + + - - - + + - - - + + + @@ -3894,18 +3799,17 @@ - - - + + - - + + - - + + @@ -3940,30 +3844,27 @@ - + - - - + - - - + + - - + + - - + + @@ -3998,20 +3899,18 @@ - + - - - + - + @@ -4048,7 +3947,7 @@ - + @@ -4083,7 +3982,7 @@ - + @@ -4118,12 +4017,12 @@ - - + + - - + + @@ -4132,394 +4031,934 @@ - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + - - - + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + - - - + + - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + - - - + + + - - + + - - + + - - - - - - - + + + + + - - - - + + + + - - + + - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - + - - - + + + - - + + @@ -4527,263 +4966,287 @@ - - - - - - - - - + + + - - - - - + + + + + - - + + - - - - + + + + - - + + - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + - - - + + + + + + + + + - - - - + + + + + - - + + - - - - + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - + - - - + + + - - + + @@ -4791,198 +5254,162 @@ - - - - - - - - - + + + - - - - - + + + + + - - + + - - - - + + + + - - + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - + + + + + + - - - - + + + + - - + + - - + + - - - - + + + + - - - + + + - - + + - - + + - - - - - + + + - - - - - + + + + + - - + + - - - - + + + + - - - + + + - - + + - - - - - + + - - + + + - - - - - + + + + + - - - + - - - - + + + + @@ -4991,13 +5418,11 @@ - - - + - - - + + + @@ -5011,29 +5436,25 @@ - - + + - - + + - - - - - - - - + + + + - - - - - + + + + + @@ -5047,868 +5468,1167 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - + + + - - - - + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + - - - - + + + + - - + + - - + + + - - - - - - - - - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + - - - - + - - - + + + + + - - + + + + + + + + + + + + + + - - - - - + + + - - - - - + + + - - - - - - + + + + - + - - - - - - + + + + - - - - - - + + + + + + - - + + - - + + + + + + + + + + + + - + - - - - - - + + + + - - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + - + - - - + + + + + - - + + + + + + + + + + + + + + - - - - + + + + - - - + + + - - - - - - - - + + + + - - - + + + - - + + - - - - - - - - + + + + - - - - - - - + + + - - - - - - - - - - - - - + + + + + + + - - - - + + + + - - + + - - - + + + - - - - - - - - + + + + - - - - + + - - - - - - + + + + - - - - + + + + - - - + + + - - - - - - - - + + + + - - - + + + - - + + - - - - - - - - + + + + - - - - - - - + + + - - - - - - - - - - - - - + + + + + + + - - - - + + + + - - + + - - - + + + - - - - - - - - + + + + - - - - + + - - - - - - + + + + - - - - + + + + - - - + + + - - - - - - - - + + + + - - - + + + - - + + - - - - - - - - + + + + - - - - - - - + + + - - - - - - - - - - - - - + + + + + + + - - - - + + + + - - + + - - + + - - - + + + - - - - - - - - + + + + - - - - + + - - - - - - + + + + - - - + + + - - - + + + - - - - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - + + + - - - - - + + + - - - - - - + + + + - + - - - - - - - + + + - - - + + + + + + - - - - - - - - - - + - - - - - - - + + + - - - - - - + + + + - + - - - - - - - + + + - - - - - - - - - - - - - + + + + + + + - - - - + + - - - - - - - + + + - - - - - - - + + + + + - - - + - - - - - - + + + + - - + + - - - - + + + + + + + + + + - - + + + + + + + + + - - + + + - - + + + + + + + + - - + + + + + + + + + + + - - + + + - - - + + + - - + + + + + + - - - - + + - - - - - - + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + - - - + - - - - - - + + + + - - + + - - - - - - - + + + - - + + + + + + - - + + + + + + + + + - - + + + - - + + + + + + + + + + + + - - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + - - + + + - - + + + - - - - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + - - - - - - + + + - - - - - - + + - - - - - - - - - - - - + + + + + + @@ -5919,17 +6639,12 @@ - - - - + + - - - - - - + + + @@ -5937,73 +6652,52 @@ - - - - + + - - - - - - + + + - - - - - - - + + + + + + - - + - - - - - - + + + - - - - - - - - - - - + + + + + + - - - - - - - - - - - - + + + + + + @@ -6014,17 +6708,12 @@ - - - - + + - - - - - - + + + @@ -6032,67 +6721,52 @@ - - - - + + - - - - - - + + + - - - + + + + + - - - + + + + + - - + + - - - - - - - - - - - - - - - + + + + + + + + - - - + - - - - - - - - - + + + + @@ -6100,8 +6774,8 @@ - - + + @@ -6112,83 +6786,54 @@ - - - - - - + + + - - - - - - - - - - - + + + + + - - + + - - - - - - - - - - - + + + + + - - - - - - - - - + + + + - - - - - - + + + - - - + - - - - - - - - - + + + + + @@ -6198,116 +6843,76 @@ - - - + - - - - - - + + + - - - + - - - - - - - + + + - - - - - - + + + - - - - - - - - - - + + + + - - - - - - + + + + + - - - - - - - + + + - - - - - - + + + + + - - - - - - - - - - - - - - - + + + + + + + + - - - + - - - - - - - - - + + + + @@ -6316,8 +6921,8 @@ - - + + @@ -6328,96 +6933,56 @@ - - - - - - + + + - - - - - - - - - - - + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - + + + + - - - - - - + + + - - - + - - - - - - - - - + + + + + @@ -6427,1537 +6992,1448 @@ - - - + - - - - - - + + + - - - - - - - - - + + + - - - - - - - + + + - - - - - - + + + - - - - - - - - - - + + + + - - - - - - + + + + + - - - - - - - + + + - - - - - - + + + + + - - - - - - + + + + - - - + - - - - - + + + - + - - - + - - - - - - + + + + - - + + - - - - - - + + + + - - + + - - - - - - - - - + + + + + + + + + + + + - - - - + + + + + + + + + + + - - + + + + + + + + + + - - - - - - + + + + + + - - + + + + + + - - - - - + + + - - + + + + + - - - - - - - - - - - - - - - - - + + + + + - - + + - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - + + + + + + + + + - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - + + + + - - - - - + + + + + + + + - - - - + + + - - - + + + + + + + + - - - - - - - - + + + + + + - - - - - + + + + + + + - - - - - - + + + + + - - - - + + - - - - - + + + + + + - - - + + - - - - + + + + + - - - + + - - - - - - - - - + + + + + - - + + - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - + + + + + + - - + + + - - - + + + + + - - + + + + + - - + + - - - - - - + + + + + + + + - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - + - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - + + + + + + + + - - - - - - + + + - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + - - - - + + + + + + - - - + + + + + + + - - + + - - - - - + + + + + + - - - - + + - - - - - + + + + + - - - - + + - - + + + + + + - - - + + - - - - - - - - + + + + + + + + - - - + + + - - + + + + + + + - - - - + + + + + + - - - - + + - - + + + + + - - - + + - - - + + + + + + - - + + - - - - + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + - - - + + + + - - + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - + + + - - + + + + - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + - - - - + + + - - + + + + - - - - - - + + + + + + + - - - - - - - - + + + + + - - - - - - - - + + + + + + + + + + + + + + - - - + + + - - - - - - - + + + + - - - + + + - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - + + - - + + + + + + - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + + + + + - - + + + + + + + - - - - - - - - + + + + - - - - - - - + + + - - - - - - - - - + + + + - - - - - - - - + + + - - - + + + - - - - - - - + + + - - - + + + - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - + + + + + + + - - + + + + + + - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + - - + + + + + + - - + + + + - - - - - - - + + + + - - + + + + - - - + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - + + + + + + - - + + + + + + - - + + + + - - + + + + + - - + + + + - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - + + + - - - - - + + + + + - - - - - - - - - - - - + + + + - - - - - - - - + + + + + + + + + - - - + + + + + + + + + - - - + + + - - - - - - - - + + + + - - - - + + + + + + + + + + + - - + + + + + + + + + + + + + + + - - - + + + - - - + + + - - - - - - - - + + + + - + - - - - - + + + + @@ -7965,9 +8441,8 @@ - - - + + @@ -7975,201 +8450,146 @@ - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + - - - + + + - - - - + + - - - - - - + + + - - - - + + + + - - - - - - - - + + + + + + - + - - + + - - - + + + - - + + - - + + - - - - - + + + - - - + + + - - + + - - - - - + + - - + + + - - - - + + + + - - - - + + - - - - + + - - - - + + - - - - + + + @@ -8179,12 +8599,9 @@ - - - - - - + + + @@ -8193,38 +8610,39 @@ - - + - - - + - - - - - - - + + + + + + + + + + + + - - - - + + + + - - - - + + + @@ -8242,13 +8660,12 @@ - - + + - - + @@ -8266,10 +8683,10 @@ - - - - + + + + @@ -8288,11 +8705,10 @@ - - - - - + + + + @@ -8307,23 +8723,22 @@ - - + + - - + + - - - + + + - - + @@ -8338,79 +8753,189 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + @@ -8418,34 +8943,114 @@ + + + + + + + + + + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + - - - - - - - - + + + + + + + + @@ -8454,33 +9059,39 @@ + + + + + + + + + + - - - - - - - + + + - - - + + + - - - - - - - - + + + + + + + + @@ -8499,28 +9110,31 @@ + + + - - + + - - + + - - - - - - - - + + + + + + + + @@ -8539,20 +9153,23 @@ + + + - - + + - - + + - - - - + + + + @@ -8584,23 +9201,26 @@ + + + - - + + - - - - - - - - + + + + + + + + @@ -8619,23 +9239,26 @@ + + + - - + + - - - - - - - - + + + + + + + + @@ -8654,29 +9277,32 @@ + + + - - + + - - - + + + - - - - - - - - + + + + + + + + @@ -8698,28 +9324,45 @@ + + + + + + + + + + + + + + + + + - - + + - - + + - - - - - - - - + + + + + + + + @@ -8741,20 +9384,37 @@ + + + + + + + + + + + + + + + + + - - + + - - + + - - - - + + + + @@ -8789,23 +9449,40 @@ + + + + + + + + + + + + + + + + + - - + + - - - - - - - - + + + + + + + + @@ -8827,23 +9504,40 @@ + + + + + + + + + + + + + + + + + - - + + - - - - - - - - + + + + + + + + @@ -8865,29 +9559,46 @@ + + + + + + + + + + + + + + + + + - - + + - - - + + + - - - - - - - - + + + + + + + + @@ -8926,28 +9637,32 @@ + + + + - - + + - - + + - - - - - - - - + + + + + + + + @@ -8986,20 +9701,24 @@ + + + + - - + + - - + + - - - - + + + + @@ -9051,23 +9770,27 @@ + + + + - - + + - - - - - - - - + + + + + + + + @@ -9106,23 +9829,27 @@ + + + + - - + + - - - - - - - - + + + + + + + + @@ -9161,29 +9888,33 @@ + + + + - - + + - - - + + + - - - - - - - - + + + + + + + + @@ -9226,28 +9957,31 @@ + + + - - + + - - + + - - - - - - - - + + + + + + + + @@ -9290,20 +10024,23 @@ + + + - - + + - - + + - - - - + + + + @@ -9359,23 +10096,26 @@ + + + - - + + - - - - - - - - + + + + + + + + @@ -9418,23 +10158,26 @@ + + + - - + + - - - - - - - - + + + + + + + + @@ -9477,29 +10220,32 @@ + + + - - + + - - - + + + - - - - - - - - + + + + + + + + @@ -9545,28 +10291,30 @@ + + - - + + - - + + - - - - - - - - + + + + + + + + @@ -9612,20 +10360,22 @@ + + - - + + - - + + - - - - + + + + @@ -9684,23 +10434,25 @@ + + - - + + - - - - - - - - + + + + + + + + @@ -9746,23 +10498,25 @@ + + - - + + - - - - - - - - + + + + + + + + @@ -9808,29 +10562,31 @@ + + - - + + - - - + + + - - - - - - - - + + + + + + + + @@ -9878,28 +10634,48 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - + + + + + + + + @@ -9947,20 +10723,40 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - + + + + @@ -10021,23 +10817,28 @@ + + + + + - - + + - - - - - - - - + + + + + + + + @@ -10085,23 +10886,43 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + @@ -10149,85 +10970,166 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + - - + + + + - - + + + + + + + + + + + + - - + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + - - - + + + + - - + + + + + + + + + + + - - - - - - - + + + - - - + + + + + + + - - - + + + + + + + + + + + - - + + + + + + + + + + + + - - - - - - + + + + + + - - + + @@ -10235,141 +11137,125 @@ - - - - - + + + + - - - + + - - - - + + + + - + - + - - + + - + - - - - - + + + + - - - + + - - - + + + - - - + - + - - - - - + + + + - - - + + - - + - - - + + + - - - - - - + + - + - - - - - + + + + - - - + + - - + - - - + + + @@ -10384,60 +11270,50 @@ - - - - - - - - - + + + - - - - - + + + + + - - + + - - - - - + + + + - - - - + + - - - + + - - - + + + - - - + + + @@ -10452,269 +11328,169 @@ - - - - - - - - - + + + - - - - - + + + + + - - + + - - - - - - + + + + + - - - - - - + + + + + - - - + + + - - - + - + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - + + + + + - - + + + + + + + + + + + + + - - + + + + - - + + - - + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + - - + + + + + + + + + + - - + + + + + + + + + + + + + - - - - - + + + - - + + - - - - - + + + + + @@ -10723,9 +11499,9 @@ - - - + + + @@ -10734,10 +11510,10 @@ - - - - + + + + @@ -10745,11 +11521,11 @@ - - - - - + + + + + @@ -10760,9 +11536,9 @@ - - - + + + @@ -10774,10 +11550,10 @@ - - - - + + + + @@ -10787,11 +11563,11 @@ - - - - - + + + + + @@ -10805,9 +11581,9 @@ - - - + + + @@ -10821,10 +11597,10 @@ - - - - + + + + @@ -10836,11 +11612,11 @@ - - - - - + + + + + @@ -10862,9 +11638,9 @@ - - - + + + @@ -10886,10 +11662,83 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -10909,23 +11758,24 @@ - - - - - + + + + + + - - - - - + + + + + @@ -10940,16 +11790,16 @@ - - - + + + - - - + + + @@ -10960,8 +11810,8 @@ - - + + @@ -10972,65 +11822,55 @@ - - - + + + - - - - + + - - - - - - + + + + - - + + - - - - - - + + + + - - + + - - - + + + - - - - - - - + + + - - - - - + + + + + @@ -11046,9 +11886,9 @@ - - - + + + @@ -11064,10 +11904,10 @@ - - - - + + + + @@ -11082,11 +11922,11 @@ - - - - - + + + + + @@ -11105,9 +11945,9 @@ - - - + + + @@ -11126,10 +11966,10 @@ - - - - + + + + @@ -11147,11 +11987,11 @@ - - - - - + + + + + @@ -11187,13 +12027,13 @@ - - + + - - - + + + @@ -11229,14 +12069,14 @@ - - + + - - - - + + + + @@ -11253,30 +12093,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + @@ -11289,11 +12114,11 @@ - - - - - + + + + + @@ -11310,10 +12135,10 @@ - - - - + + + + @@ -11328,9 +12153,9 @@ - - - + + + @@ -11345,35 +12170,25 @@ - - - - - - - + + + + + - - - - - - - - - - - - + + + + - - - - - + + + + + @@ -11381,8 +12196,7 @@ - - + @@ -11392,9 +12206,9 @@ - - - + + + @@ -11402,8 +12216,7 @@ - - + @@ -11414,10 +12227,10 @@ - - - - + + + + @@ -11433,9 +12246,9 @@ - - - + + + @@ -11450,18 +12263,18 @@ - - + + - - + + - - - + + + @@ -11476,19 +12289,19 @@ - - + + - - + + - - - - + + + + @@ -11499,10 +12312,10 @@ - - - - + + + + @@ -11521,9 +12334,9 @@ - - - + + + @@ -11541,18 +12354,18 @@ - - + + - - + + - - - + + + @@ -11570,19 +12383,19 @@ - - + + - - + + - - - - + + + + @@ -11596,10 +12409,10 @@ - - - - + + + + @@ -11620,9 +12433,9 @@ - - - + + + @@ -11642,18 +12455,18 @@ - - + + - - + + - - - + + + @@ -11673,19 +12486,19 @@ - - + + - - + + - - - - + + + + @@ -11700,9 +12513,9 @@ - - - + + + @@ -11723,9 +12536,9 @@ - - - + + + @@ -11745,663 +12558,820 @@ - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - - - + + + + + + - - - + + + - - - - - + + + - - - - - - - - - - - - - - - - - - + + + + + + - - - + + + - - - - - - + + - - - - - - - - - - + + + + + + + + - - - - - + + + - - - - - + + + - - - + + + - - + + - - - + + + - - + + - - - + - - - - - - + + + + - - - - - - + + + - - - + + + + - - - - - + + + + - - - - - - - - + + + - - - - - - - - - - + + + + + + + + - - - - - + + + - - - - - - + + + - - + + + - - - - - - - - + + + + - - - - - + + + - - - - - + + + - - + + - - - - - + + + - - + + - - - - - + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - + + + + + + - - - - - - + + + + + + + - - - - - - - - - - - - - + + + + - - + + - - + + + + + + - - + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + - - - - - - - + + + - - + + - - - - + + + + - - - - + + + + - - + + + + - - + + + + - - + + + + + - - - + + + + + + + + + + + + + + + + + - - + + + + - - + + + - - + + - - + + - - - - + + + + - - - - - - - + - - + + + + + + - - + + + - - + + - - + + + - - + + - - - - + + + + - + - - + + - - - - - + + + - - + + - - - - - + + + - - + + - - - - + + + + - + - - + + - - - - - + + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - + + + + + - - - + + + @@ -12419,7 +13389,7 @@ - + @@ -12429,357 +13399,32 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - + + - - - - - - - + + + + + + + @@ -12787,608 +13432,564 @@ + + + - - - - + + + + - - - - - - + + - - - - - - + + + + - - - - + + - - - - - - - + + + - - - + + + - - - - - - - + + + - - - + + + - - - - - - + + - - - - + + - - - - - - + + + + - - - - + + - - - - - - - + + + - - - + + + - - - - - - - + + + - - - + - - - + + + - - - - - - + + - - - - + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + - - - - - - - + + + - + - - - + + + - - - - - - - + + + - - - - + + - - - - - - - - + + + + + + - - - - - - - - - + + + + + - - + + - - - - - - - - - - - + + + + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - + + + + + + + - - - + - - - - - - - - - - - + + + + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - + + + + + + + - - - - + + - - - - - - - + + + - - - - - - + + + + - - - - - - - - + + + + + + - - - - - - - - - - - - + + + + + + + + - - - - - - - - - + + + + + - - + + - - - - - - + + - - - - - - - - - - - + + + + + - - - + + + - - + + - - + + - - - - - - - - - - - - + + + - - - - - - + + + + + + + - - - - - - + + - - - - - - - - - - - + + + + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + - - + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + - - + + + - - + + + + + + + + + + + + + - - - + + + + + + - - - + + + + + + + - - - + + + + + + + + - - - + + + - - - + + + - - + + + + + + + + + + + + + - - - - - - + + + + + + + + - - - + + + + + + + + - - + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + - - + + - - - - - - + + - - - - - - - - - - - + + + + + - - + + @@ -13396,65 +13997,47 @@ - - + + - - + + - - + + - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - + + + + - - - - - - - - - - - + + + + + - - + + @@ -13462,97 +14045,80 @@ - - + + - - + + - - + + - - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + - - - - - - - - - - + + + + - - - - + + - - - - - + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + - - + + @@ -13563,72 +14129,51 @@ - - - - - - + + + - - - - - - - - - - - + + + + + - - + + - - - - - - - - - - - + + + + + - - - - - - - - - - + + + + + + - - - + + + - - - + - - - + + + @@ -13636,64 +14181,87 @@ - - - - - + + + - - + + - - - - + + + + + + + + + + + + + + + - - - + + + + + + + + + - - + + + - - + + + + + + + + + + + + + + + - - - + + + - - - + - - - + + + - - - - - - - - + + + + - + @@ -13736,83 +14304,61 @@ - - - - - - + + - - - + + + - - - + - - - - - - - - - + + + + + - - - - - + + + - - - - - - - - - + + + + + - - - + + + - - - + - - - + + + - - - - - - - - + + + + - + @@ -13868,76 +14414,54 @@ - - - - - - + + - - - + + + - - - + - - - - - - - - - + + + + + - - - - - + + + - - - - - - - - - + + + + + - - - + + + - - - + - - - + + + - - - - - - - - + + + + @@ -13945,7 +14469,7 @@ - + @@ -14035,71 +14559,53 @@ - - - - - - + + - - - + + + - - - + - - - - - - - - - + + + + + - - + + - - - - - - - - - - - - - + + + + + + + + + - - - + - - - - - - - + + + + + - - + + @@ -14111,12 +14617,10 @@ - - - - - - + + + + @@ -14127,25 +14631,21 @@ - - - + - - - - - - - + + + + + - - + + @@ -14157,12 +14657,10 @@ - - - - - - + + + + @@ -14174,150 +14672,143 @@ - - - + - - - + + + - - - - + + + + - + - - - - - - - - + + + + - - - - - - + + - - - - - - - - - - - - - - + + + + + + - - - - - - - - + + + + - - - - + + + + - - + + - - - - - - - - + + + + - - - - - - - - - - - - - + + + + + + + - - - - + + + + - - + + - - + + + + - - + + + + + + + + - - + + + + - - - - + + + + + + + + + - - + + + + - - + + + + + + + + + - - + + + + + - - - - - - - + + + + + @@ -14327,7 +14818,7 @@ - + @@ -14336,13 +14827,11 @@ - - - - - - - + + + + + @@ -14352,237 +14841,191 @@ - + - - - - - - + + - - - + + + - - - + + + - - - + + + + - - - - - - - - + + + - - + + - - - - + + - - - - - - + + + + + - - - - - - - - + + + - - + + - - + + - - - - - - + + + + - - - - - - - + + + + + - - - + + + - + - - + + - - - - + + + + - + - - + + - - - - + + + + - - + + + - - + + + - - - - - - - - + + - - - - + + - - - - - - - + + + + - - + + + - - + + + - - - - - + + - + - - + + - - - + - - + + - - - + - - - + - - - - - - - - - - - - + + + + - - - - - + + + - - + + - - - + + + - - - + + + @@ -14590,109 +15033,285 @@ - - - - - - - + + + + + + - - - + + - + - - - + + - - - + + - + - - - - + + + + + + + + + + + - - + + + + + + + + + + + - - + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + - + + + + + - - - - + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + - - + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + - + + + + + - - - - + + - - - - - - + + + + @@ -14700,61 +15319,90 @@ - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + - - - - + + + + - - - - + + + + - - - + + + - - - - + + + + - - - - - + + + + + - - - - - + + + - - - + + + @@ -14765,22 +15413,16 @@ - - - - - - - - + + + + - - - - - - + + + + @@ -14792,37 +15434,93 @@ - - + + + + + + + + + + + + + + + + + + + + + + - - + + + - - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - + + - - + + @@ -14841,16 +15539,16 @@ - - - - - - + + + + + + - - + + @@ -14869,30 +15567,24 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + @@ -14911,28 +15603,24 @@ - - - - - - - - - + + + + + + + - - - + - - - + + + - + @@ -14951,19 +15639,17 @@ - - - - - - - - - + + + + + + + - - + + @@ -14982,103 +15668,95 @@ - - - - - - + + + + + + - - - - - + + + - - - - - + + + - - + + - - - - - + + + - - - - - - + + + + - - + + - - + + - - - + + + - - - - - - - - + + + + - + + + + + - - + + - - - - - - - - + + + + - + + + + + - - + + @@ -15090,204 +15768,181 @@ - - + + - - + + - - - + + - + + + + + - - - + + - + + + + + - - + + - - - + + + - - - - - - - - - - - - - + + + + - - - - + + + + - - - - - - - - + + + + - - - - - - + + + + - - + + - - + + - - + + - - + + - - - - - + + + - + - - - + - - - - - - + + + + - - + + - - + + - - + + - - + + - - - - - - - + + + + + - - + + - - + + - - + + - - + + - - + + - - - + - - + + - - - - - - - - + + + + @@ -15296,343 +15951,492 @@ - - + + - - - - - - - - - - - + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - + - - + + - - - - - - - - - - - + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + - - - - + + - - - - - - - - - - - + + + + + + - - - + + + + + + + - - - - - - - - - - - + + + + + + + - - - + + + + + + + - - - - - - - - - - + + + + + + + - - + + + + + + + - - - - - - + + - - - - - - + + + + + + + - - + + - - - - + + + + + - - + + - - + + - - - + + + + - - - + + + + - - + + - - + + - - - - + + + + + - - - + + + + - - - + + + - - - + + + + - - - + + + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + - - - - + + + + + - - - - + + + + + - - - - - + + + + + @@ -15641,13 +16445,11 @@ - - - - - - - + + + + + @@ -15655,7 +16457,7 @@ - + @@ -15683,41 +16485,37 @@ - - - - - + + + - - - - - - - + + + + + - - - - + + + + - - + + - - + + - - + + @@ -15745,58 +16543,790 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + + + + + + + + + + - - + + + + + + + + + + + + - - - + + + + + - - + + - - - - + + + + + - - + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + \ No newline at end of file