Merge pull request #3 from home-assistant/dev

Get latest
This commit is contained in:
jbarrancos 2017-10-11 16:04:37 +02:00 committed by GitHub
commit 2c9010d661
197 changed files with 7332 additions and 1468 deletions

View file

@ -149,6 +149,9 @@ omit =
homeassistant/components/rachio.py
homeassistant/components/*/rachio.py
homeassistant/components/raincloud.py
homeassistant/components/*/raincloud.py
homeassistant/components/raspihats.py
homeassistant/components/*/raspihats.py
@ -166,6 +169,9 @@ omit =
homeassistant/components/scsgate.py
homeassistant/components/*/scsgate.py
homeassistant/components/skybell.py
homeassistant/components/*/skybell.py
homeassistant/components/tado.py
homeassistant/components/*/tado.py
@ -179,6 +185,9 @@ omit =
homeassistant/components/tesla.py
homeassistant/components/*/tesla.py
homeassistant/components/thethingsnetwork.py
homeassistant/components/*/thethingsnetwork.py
homeassistant/components/*/thinkingcleaner.py
homeassistant/components/tradfri.py
@ -399,6 +408,7 @@ omit =
homeassistant/components/notify/aws_sqs.py
homeassistant/components/notify/ciscospark.py
homeassistant/components/notify/clicksend.py
homeassistant/components/notify/clicksendaudio.py
homeassistant/components/notify/discord.py
homeassistant/components/notify/facebook.py
homeassistant/components/notify/free_mobile.py
@ -420,6 +430,7 @@ omit =
homeassistant/components/notify/pushover.py
homeassistant/components/notify/pushsafer.py
homeassistant/components/notify/rest.py
homeassistant/components/notify/rocketchat.py
homeassistant/components/notify/sendgrid.py
homeassistant/components/notify/simplepush.py
homeassistant/components/notify/slack.py
@ -538,9 +549,11 @@ omit =
homeassistant/components/sensor/tank_utility.py
homeassistant/components/sensor/ted5000.py
homeassistant/components/sensor/temper.py
homeassistant/components/sensor/tibber.py
homeassistant/components/sensor/time_date.py
homeassistant/components/sensor/torque.py
homeassistant/components/sensor/transmission.py
homeassistant/components/sensor/travisci.py
homeassistant/components/sensor/twitch.py
homeassistant/components/sensor/uber.py
homeassistant/components/sensor/upnp.py
@ -578,6 +591,7 @@ omit =
homeassistant/components/switch/telnet.py
homeassistant/components/switch/transmission.py
homeassistant/components/switch/wake_on_lan.py
homeassistant/components/switch/xiaomi_miio.py
homeassistant/components/telegram_bot/*
homeassistant/components/thingspeak.py
homeassistant/components/tts/amazon_polly.py

View file

@ -29,6 +29,9 @@ homeassistant/components/weblink.py @home-assistant/core
homeassistant/components/websocket_api.py @home-assistant/core
homeassistant/components/zone.py @home-assistant/core
# To monitor non-pypi additions
requirements_all.txt @andrey-git
Dockerfile @home-assistant/docker
virtualization/Docker/* @home-assistant/docker
@ -36,6 +39,25 @@ homeassistant/components/zwave/* @home-assistant/z-wave
homeassistant/components/*/zwave.py @home-assistant/z-wave
# Indiviudal components
homeassistant/components/alarm_control_panel/egardia.py @jeroenterheerdt
homeassistant/components/climate/eq3btsmart.py @rytilahti
homeassistant/components/climate/sensibo.py @andrey-git
homeassistant/components/cover/template.py @PhracturedBlue
homeassistant/components/device_tracker/automatic.py @armills
homeassistant/components/history_graph.py @andrey-git
homeassistant/components/light/tplink.py @rytilahti
homeassistant/components/light/yeelight.py @rytilahti
homeassistant/components/media_player/kodi.py @armills
homeassistant/components/sensor/airvisual.py @bachya
homeassistant/components/sensor/miflora.py @danielhiversen
homeassistant/components/sensor/tibber.py @danielhiversen
homeassistant/components/sensor/waqi.py @andrey-git
homeassistant/components/switch/rainmachine.py @bachya
homeassistant/components/switch/tplink.py @rytilahti
homeassistant/components/*/broadlink.py @danielhiversen
homeassistant/components/*/rfxtrx.py @danielhiversen
homeassistant/components/tesla.py @zabuldon
homeassistant/components/*/tesla.py @zabuldon
homeassistant/components/*/xiaomi_aqara.py @danielhiversen
homeassistant/components/*/xiaomi_miio.py @rytilahti

View file

@ -11,9 +11,10 @@ MAINTAINER Paulus Schoutsen <Paulus@PaulusSchoutsen.nl>
#ENV INSTALL_FFMPEG no
#ENV INSTALL_LIBCEC no
#ENV INSTALL_PHANTOMJS no
#ENV INSTALL_COAP_CLIENT no
#ENV INSTALL_COAP no
#ENV INSTALL_SSOCR no
VOLUME /config
RUN mkdir -p /usr/src/app
@ -25,7 +26,6 @@ RUN virtualization/Docker/setup_docker_prereqs
# Install hass component dependencies
COPY requirements_all.txt requirements_all.txt
# Uninstall enum34 because some depenndecies install it but breaks Python 3.4+.
# See PR #8103 for more info.
RUN pip3 install --no-cache-dir -r requirements_all.txt && \

View file

@ -117,7 +117,11 @@ def linkcode_resolve(domain, info):
linespec = "#L%d" % (lineno + 1)
else:
linespec = ""
fn = relpath(fn, start='../')
index = fn.find("/homeassistant/")
if index == -1:
index = 0
fn = fn[index:]
return '{}/blob/{}/{}{}'.format(GITHUB_URL, code_branch, fn, linespec)

View file

@ -11,13 +11,11 @@ from typing import Any, Optional, Dict
import voluptuous as vol
import homeassistant.components as core_components
from homeassistant import (
core, config as conf_util, loader, components as core_components)
from homeassistant.components import persistent_notification
import homeassistant.config as conf_util
import homeassistant.core as core
from homeassistant.const import EVENT_HOMEASSISTANT_CLOSE
from homeassistant.setup import async_setup_component
import homeassistant.loader as loader
from homeassistant.util.logging import AsyncHandler
from homeassistant.util.package import async_get_user_site, get_user_site
from homeassistant.util.yaml import clear_secret_cache
@ -83,6 +81,18 @@ def async_from_config_dict(config: Dict[str, Any],
This method is a coroutine.
"""
start = time()
if enable_log:
async_enable_logging(hass, verbose, log_rotate_days, log_file)
if sys.version_info[:2] < (3, 5):
_LOGGER.warning(
'Python 3.4 support has been deprecated and will be removed in '
'the begining of 2018. Please upgrade Python or your operating '
'system. More info: https://home-assistant.io/blog/2017/10/06/'
'deprecating-python-3.4-support/'
)
core_config = config.get(core.DOMAIN, {})
try:
@ -93,9 +103,6 @@ def async_from_config_dict(config: Dict[str, Any],
yield from hass.async_add_job(conf_util.process_ha_config_upgrade, hass)
if enable_log:
async_enable_logging(hass, verbose, log_rotate_days, log_file)
hass.config.skip_pip = skip_pip
if skip_pip:
_LOGGER.warning("Skipping pip installation of required modules. "

View file

@ -21,7 +21,7 @@ from homeassistant.const import (ATTR_ATTRIBUTION, ATTR_DATE, ATTR_TIME,
EVENT_HOMEASSISTANT_STOP,
EVENT_HOMEASSISTANT_START)
REQUIREMENTS = ['abodepy==0.11.8']
REQUIREMENTS = ['abodepy==0.12.1']
_LOGGER = logging.getLogger(__name__)

View file

@ -0,0 +1,121 @@
"""
Support for Arlo Alarm Control Panels.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.arlo/
"""
import asyncio
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.alarm_control_panel import (
AlarmControlPanel, PLATFORM_SCHEMA)
from homeassistant.components.arlo import (DATA_ARLO, CONF_ATTRIBUTION)
from homeassistant.const import (
ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED)
_LOGGER = logging.getLogger(__name__)
ARMED = 'armed'
CONF_HOME_MODE_NAME = 'home_mode_name'
DEPENDENCIES = ['arlo']
DISARMED = 'disarmed'
ICON = 'mdi:security'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_HOME_MODE_NAME, default=ARMED): cv.string,
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up the Arlo Alarm Control Panels."""
data = hass.data[DATA_ARLO]
if not data.base_stations:
return
home_mode_name = config.get(CONF_HOME_MODE_NAME)
base_stations = []
for base_station in data.base_stations:
base_stations.append(ArloBaseStation(base_station, home_mode_name))
async_add_devices(base_stations, True)
class ArloBaseStation(AlarmControlPanel):
"""Representation of an Arlo Alarm Control Panel."""
def __init__(self, data, home_mode_name):
"""Initialize the alarm control panel."""
self._base_station = data
self._home_mode_name = home_mode_name
self._state = None
@property
def icon(self):
"""Return icon."""
return ICON
@property
def state(self):
"""Return the state of the device."""
return self._state
def update(self):
"""Update the state of the device."""
# PyArlo sometimes returns None for mode. So retry 3 times before
# returning None.
num_retries = 3
i = 0
while i < num_retries:
mode = self._base_station.mode
if mode:
self._state = self._get_state_from_mode(mode)
return
i += 1
self._state = None
@asyncio.coroutine
def async_alarm_disarm(self, code=None):
"""Send disarm command."""
self._base_station.mode = DISARMED
@asyncio.coroutine
def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
self._base_station.mode = ARMED
@asyncio.coroutine
def async_alarm_arm_home(self, code=None):
"""Send arm home command. Uses custom mode."""
self._base_station.mode = self._home_mode_name
@property
def name(self):
"""Return the name of the base station."""
return self._base_station.name
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
'device_id': self._base_station.device_id
}
def _get_state_from_mode(self, mode):
"""Convert Arlo mode to Home Assistant state."""
if mode == ARMED:
return STATE_ALARM_ARMED_AWAY
elif mode == DISARMED:
return STATE_ALARM_DISARMED
elif mode == self._home_mode_name:
return STATE_ALARM_ARMED_HOME
return None

View file

@ -18,13 +18,14 @@ from homeassistant.const import (
CONF_NAME, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_TRIGGERED)
REQUIREMENTS = ['pythonegardia==1.0.20']
REQUIREMENTS = ['pythonegardia==1.0.22']
_LOGGER = logging.getLogger(__name__)
CONF_REPORT_SERVER_CODES = 'report_server_codes'
CONF_REPORT_SERVER_ENABLED = 'report_server_enabled'
CONF_REPORT_SERVER_PORT = 'report_server_port'
CONF_REPORT_SERVER_CODES_IGNORE = 'ignore'
DEFAULT_NAME = 'Egardia'
DEFAULT_PORT = 80
@ -148,9 +149,15 @@ class EgardiaAlarm(alarm.AlarmControlPanel):
def parsestatus(self, status):
"""Parse the status."""
newstatus = ([v for k, v in STATES.items()
if status.upper() == k][0])
self._status = newstatus
_LOGGER.debug("Parsing status %s", status)
# Ignore the statuscode if it is IGNORE
if status.lower().strip() != CONF_REPORT_SERVER_CODES_IGNORE:
_LOGGER.debug("Not ignoring status")
newstatus = ([v for k, v in STATES.items()
if status.upper() == k][0])
self._status = newstatus
else:
_LOGGER.error("Ignoring status")
def update(self):
"""Update the alarm status."""

View file

@ -6,88 +6,100 @@ from uuid import uuid4
from homeassistant.const import (
ATTR_SUPPORTED_FEATURES, ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF)
from homeassistant.components import switch, light
from homeassistant.util.decorator import Registry
HANDLERS = Registry()
_LOGGER = logging.getLogger(__name__)
ATTR_HEADER = 'header'
ATTR_NAME = 'name'
ATTR_NAMESPACE = 'namespace'
ATTR_MESSAGE_ID = 'messageId'
ATTR_PAYLOAD = 'payload'
ATTR_PAYLOAD_VERSION = 'payloadVersion'
API_DIRECTIVE = 'directive'
API_EVENT = 'event'
API_HEADER = 'header'
API_PAYLOAD = 'payload'
API_ENDPOINT = 'endpoint'
MAPPING_COMPONENT = {
switch.DOMAIN: ['SWITCH', ('turnOff', 'turnOn'), None],
switch.DOMAIN: ['SWITCH', ('Alexa.PowerController',), None],
light.DOMAIN: [
'LIGHT', ('turnOff', 'turnOn'), {
light.SUPPORT_BRIGHTNESS: 'setPercentage'
'LIGHT', ('Alexa.PowerController',), {
light.SUPPORT_BRIGHTNESS: 'Alexa.BrightnessController'
}
],
}
def mapping_api_function(name):
"""Return function pointer to api function for name.
Async friendly.
"""
mapping = {
'DiscoverAppliancesRequest': async_api_discovery,
'TurnOnRequest': async_api_turn_on,
'TurnOffRequest': async_api_turn_off,
'SetPercentageRequest': async_api_set_percentage,
}
return mapping.get(name, None)
@asyncio.coroutine
def async_handle_message(hass, message):
"""Handle incoming API messages."""
assert int(message[ATTR_HEADER][ATTR_PAYLOAD_VERSION]) == 2
assert message[API_DIRECTIVE][API_HEADER]['payloadVersion'] == '3'
# Read head data
message = message[API_DIRECTIVE]
namespace = message[API_HEADER]['namespace']
name = message[API_HEADER]['name']
# Do we support this API request?
funct_ref = mapping_api_function(message[ATTR_HEADER][ATTR_NAME])
funct_ref = HANDLERS.get((namespace, name))
if not funct_ref:
_LOGGER.warning(
"Unsupported API request %s", message[ATTR_HEADER][ATTR_NAME])
"Unsupported API request %s/%s", namespace, name)
return api_error(message)
return (yield from funct_ref(hass, message))
def api_message(name, namespace, payload=None):
def api_message(request, name='Response', namespace='Alexa', payload=None):
"""Create a API formatted response message.
Async friendly.
"""
payload = payload or {}
return {
ATTR_HEADER: {
ATTR_MESSAGE_ID: uuid4(),
ATTR_NAME: name,
ATTR_NAMESPACE: namespace,
ATTR_PAYLOAD_VERSION: '2',
},
ATTR_PAYLOAD: payload,
response = {
API_EVENT: {
API_HEADER: {
'namespace': namespace,
'name': name,
'messageId': str(uuid4()),
'payloadVersion': '3',
},
API_PAYLOAD: payload,
}
}
# If a correlation token exsits, add it to header / Need by Async requests
token = request[API_HEADER].get('correlationToken')
if token:
response[API_EVENT][API_HEADER]['correlationToken'] = token
def api_error(request, exc='DriverInternalError'):
# Extend event with endpoint object / Need by Async requests
if API_ENDPOINT in request:
response[API_EVENT][API_ENDPOINT] = request[API_ENDPOINT].copy()
return response
def api_error(request, error_type='INTERNAL_ERROR', error_message=""):
"""Create a API formatted error response.
Async friendly.
"""
return api_message(exc, request[ATTR_HEADER][ATTR_NAMESPACE])
payload = {
'type': error_type,
'message': error_message,
}
return api_message(request, name='ErrorResponse', payload=payload)
@HANDLERS.register(('Alexa.Discovery', 'Discover'))
@asyncio.coroutine
def async_api_discovery(hass, request):
"""Create a API formatted discovery response.
Async friendly.
"""
discovered_appliances = []
discovery_endpoints = []
for entity in hass.states.async_all():
class_data = MAPPING_COMPONENT.get(entity.domain)
@ -95,35 +107,42 @@ def async_api_discovery(hass, request):
if not class_data:
continue
appliance = {
'actions': [],
'applianceTypes': [class_data[0]],
endpoint = {
'displayCategories': [class_data[0]],
'additionalApplianceDetails': {},
'applianceId': entity.entity_id.replace('.', '#'),
'friendlyDescription': '',
'endpointId': entity.entity_id.replace('.', '#'),
'friendlyName': entity.name,
'isReachable': True,
'description': '',
'manufacturerName': 'Unknown',
'modelName': 'Unknown',
'version': 'Unknown',
}
actions = set()
# static actions
if class_data[1]:
appliance['actions'].extend(list(class_data[1]))
actions |= set(class_data[1])
# dynamic actions
if class_data[2]:
supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
for feature, action_name in class_data[2].items():
if feature & supported > 0:
appliance['actions'].append(action_name)
actions.add(action_name)
discovered_appliances.append(appliance)
# Write action into capabilities
capabilities = []
for action in actions:
capabilities.append({
'type': 'AlexaInterface',
'interface': action,
'version': 3,
})
endpoint['capabilities'] = capabilities
discovery_endpoints.append(endpoint)
return api_message(
'DiscoverAppliancesResponse', 'Alexa.ConnectedHome.Discovery',
payload={'discoveredAppliances': discovered_appliances})
request, name='Discover.Response', namespace='Alexa.Discovery',
payload={'endpoints': discovery_endpoints})
def extract_entity(funct):
@ -131,21 +150,21 @@ def extract_entity(funct):
@asyncio.coroutine
def async_api_entity_wrapper(hass, request):
"""Process a turn on request."""
entity_id = \
request[ATTR_PAYLOAD]['appliance']['applianceId'].replace('#', '.')
entity_id = request[API_ENDPOINT]['endpointId'].replace('#', '.')
# extract state object
entity = hass.states.get(entity_id)
if not entity:
_LOGGER.error("Can't process %s for %s",
request[ATTR_HEADER][ATTR_NAME], entity_id)
return api_error(request)
request[API_HEADER]['name'], entity_id)
return api_error(request, error_type='NO_SUCH_ENDPOINT')
return (yield from funct(hass, request, entity))
return async_api_entity_wrapper
@HANDLERS.register(('Alexa.PowerController', 'TurnOn'))
@extract_entity
@asyncio.coroutine
def async_api_turn_on(hass, request, entity):
@ -154,9 +173,10 @@ def async_api_turn_on(hass, request, entity):
ATTR_ENTITY_ID: entity.entity_id
}, blocking=True)
return api_message('TurnOnConfirmation', 'Alexa.ConnectedHome.Control')
return api_message(request)
@HANDLERS.register(('Alexa.PowerController', 'TurnOff'))
@extract_entity
@asyncio.coroutine
def async_api_turn_off(hass, request, entity):
@ -165,21 +185,19 @@ def async_api_turn_off(hass, request, entity):
ATTR_ENTITY_ID: entity.entity_id
}, blocking=True)
return api_message('TurnOffConfirmation', 'Alexa.ConnectedHome.Control')
return api_message(request)
@HANDLERS.register(('Alexa.BrightnessController', 'SetBrightness'))
@extract_entity
@asyncio.coroutine
def async_api_set_percentage(hass, request, entity):
"""Process a set percentage request."""
if entity.domain == light.DOMAIN:
brightness = request[ATTR_PAYLOAD]['percentageState']['value']
yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_BRIGHTNESS: brightness,
}, blocking=True)
else:
return api_error(request)
def async_api_set_brightness(hass, request, entity):
"""Process a set brightness request."""
brightness = request[API_PAYLOAD]['brightness']
return api_message(
'SetPercentageConfirmation', 'Alexa.ConnectedHome.Control')
yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_BRIGHTNESS: brightness,
}, blocking=True)
return api_message(request)

View file

@ -1,5 +1,5 @@
"""
This component provides basic support for Netgear Arlo IP cameras.
This component provides support for Netgear Arlo IP cameras.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/arlo/
@ -12,7 +12,7 @@ from requests.exceptions import HTTPError, ConnectTimeout
from homeassistant.helpers import config_validation as cv
from homeassistant.const import CONF_USERNAME, CONF_PASSWORD
REQUIREMENTS = ['pyarlo==0.0.6']
REQUIREMENTS = ['pyarlo==0.0.7']
_LOGGER = logging.getLogger(__name__)
@ -23,7 +23,7 @@ DEFAULT_BRAND = 'Netgear Arlo'
DOMAIN = 'arlo'
NOTIFICATION_ID = 'arlo_notification'
NOTIFICATION_TITLE = 'Arlo Camera Setup'
NOTIFICATION_TITLE = 'Arlo Component Setup'
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({

View file

@ -21,7 +21,7 @@ _LOGGER = logging.getLogger(__name__)
TRIGGER_SCHEMA = vol.Schema({
vol.Required(CONF_PLATFORM): 'event',
vol.Required(CONF_EVENT_TYPE): cv.string,
vol.Optional(CONF_EVENT_DATA): dict,
vol.Optional(CONF_EVENT_DATA, default={}): dict,
})
@ -29,18 +29,24 @@ TRIGGER_SCHEMA = vol.Schema({
def async_trigger(hass, config, action):
"""Listen for events based on configuration."""
event_type = config.get(CONF_EVENT_TYPE)
event_data = config.get(CONF_EVENT_DATA)
event_data_schema = vol.Schema(
config.get(CONF_EVENT_DATA),
extra=vol.ALLOW_EXTRA)
@callback
def handle_event(event):
"""Listen for events and calls the action when data matches."""
if not event_data or all(val == event.data.get(key) for key, val
in event_data.items()):
hass.async_run_job(action, {
'trigger': {
'platform': 'event',
'event': event,
},
})
try:
event_data_schema(event.data)
except vol.Invalid:
# If event data doesn't match requested schema, skip event
return
hass.async_run_job(action, {
'trigger': {
'platform': 'event',
'event': event,
},
})
return hass.bus.async_listen(event_type, handle_event)

View file

@ -99,8 +99,8 @@ def async_trigger(hass, config, action):
return
async_remove_track_same = async_track_same_state(
hass, True, time_delta, call_action, entity_ids=entity_id,
async_check_func=check_numeric_state)
hass, time_delta, call_action, entity_ids=entity_id,
async_check_same_func=check_numeric_state)
unsub = async_track_state_change(
hass, entity_id, state_automation_listener)

View file

@ -65,7 +65,9 @@ def async_trigger(hass, config, action):
return
async_remove_track_same = async_track_same_state(
hass, to_s.state, time_delta, call_action, entity_ids=entity_id)
hass, time_delta, call_action,
lambda _, _2, to_state: to_state.state == to_s.state,
entity_ids=entity_id)
unsub = async_track_state_change(
hass, entity_id, state_automation_listener, from_state, to_state)

View file

@ -13,7 +13,8 @@ import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.const import (CONF_NAME, ATTR_LONGITUDE, ATTR_LATITUDE)
from homeassistant.const import (
CONF_NAME, ATTR_LONGITUDE, ATTR_LATITUDE, CONF_SHOW_ON_MAP)
from homeassistant.util import Throttle
REQUIREMENTS = ['pyiss==1.0.1']
@ -23,8 +24,6 @@ _LOGGER = logging.getLogger(__name__)
ATTR_ISS_NEXT_RISE = 'next_rise'
ATTR_ISS_NUMBER_PEOPLE_SPACE = 'number_of_people_in_space'
CONF_SHOW_ON_MAP = 'show_on_map'
DEFAULT_NAME = 'ISS'
DEFAULT_DEVICE_CLASS = 'visible'

View file

@ -0,0 +1,72 @@
"""
Support for Melnor RainCloud sprinkler water timer.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.raincloud/
"""
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.raincloud import (
BINARY_SENSORS, DATA_RAINCLOUD, ICON_MAP, RainCloudEntity)
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.const import CONF_MONITORED_CONDITIONS
DEPENDENCIES = ['raincloud']
_LOGGER = logging.getLogger(__name__)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_MONITORED_CONDITIONS, default=list(BINARY_SENSORS)):
vol.All(cv.ensure_list, [vol.In(BINARY_SENSORS)]),
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up a sensor for a raincloud device."""
raincloud = hass.data[DATA_RAINCLOUD].data
sensors = []
for sensor_type in config.get(CONF_MONITORED_CONDITIONS):
if sensor_type == 'status':
sensors.append(
RainCloudBinarySensor(raincloud.controller, sensor_type))
sensors.append(
RainCloudBinarySensor(raincloud.controller.faucet,
sensor_type))
else:
# create an sensor for each zone managed by faucet
for zone in raincloud.controller.faucet.zones:
sensors.append(RainCloudBinarySensor(zone, sensor_type))
add_devices(sensors, True)
return True
class RainCloudBinarySensor(RainCloudEntity, BinarySensorDevice):
"""A sensor implementation for raincloud device."""
@property
def is_on(self):
"""Return true if the binary sensor is on."""
return self._state
def update(self):
"""Get the latest data and updates the state."""
_LOGGER.debug("Updating RainCloud sensor: %s", self._name)
self._state = getattr(self.data, self._sensor_type)
if self._sensor_type == 'status':
self._state = self._state == 'Online'
@property
def icon(self):
"""Return the icon of this device."""
if self._sensor_type == 'is_watering':
return 'mdi:water' if self.is_on else 'mdi:water-off'
elif self._sensor_type == 'status':
return 'mdi:pipe' if self.is_on else 'mdi:pipe-disconnected'
return ICON_MAP.get(self._sensor_type)

View file

@ -0,0 +1,97 @@
"""
Binary sensor support for the Skybell HD Doorbell.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.skybell/
"""
from datetime import timedelta
import logging
import voluptuous as vol
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.components.skybell import (
DEFAULT_ENTITY_NAMESPACE, DOMAIN as SKYBELL_DOMAIN, SkybellDevice)
from homeassistant.const import (
CONF_ENTITY_NAMESPACE, CONF_MONITORED_CONDITIONS)
import homeassistant.helpers.config_validation as cv
DEPENDENCIES = ['skybell']
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=5)
# Sensor types: Name, device_class, event
SENSOR_TYPES = {
'button': ['Button', 'occupancy', 'device:sensor:button'],
'motion': ['Motion', 'motion', 'device:sensor:motion'],
}
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_ENTITY_NAMESPACE, default=DEFAULT_ENTITY_NAMESPACE):
cv.string,
vol.Required(CONF_MONITORED_CONDITIONS, default=[]):
vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]),
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the platform for a Skybell device."""
skybell = hass.data.get(SKYBELL_DOMAIN)
sensors = []
for sensor_type in config.get(CONF_MONITORED_CONDITIONS):
for device in skybell.get_devices():
sensors.append(SkybellBinarySensor(device, sensor_type))
add_devices(sensors, True)
class SkybellBinarySensor(SkybellDevice, BinarySensorDevice):
"""A binary sensor implementation for Skybell devices."""
def __init__(self, device, sensor_type):
"""Initialize a binary sensor for a Skybell device."""
super().__init__(device)
self._sensor_type = sensor_type
self._name = "{0} {1}".format(self._device.name,
SENSOR_TYPES[self._sensor_type][0])
self._device_class = SENSOR_TYPES[self._sensor_type][1]
self._event = {}
self._state = None
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def is_on(self):
"""Return True if the binary sensor is on."""
return self._state
@property
def device_class(self):
"""Return the class of the binary sensor."""
return self._device_class
@property
def device_state_attributes(self):
"""Return the state attributes."""
attrs = super().device_state_attributes
attrs['event_date'] = self._event.get('createdAt')
return attrs
def update(self):
"""Get the latest data and updates the state."""
super().update()
event = self._device.latest(SENSOR_TYPES[self._sensor_type][2])
self._state = bool(event and event.get('id') != self._event.get('id'))
self._event = event

View file

@ -135,7 +135,7 @@ class BinarySensorTemplate(BinarySensorDevice):
return False
@callback
def _async_render(self, *args):
def _async_render(self):
"""Get the state of template."""
try:
return self._template.async_render().lower() == 'true'
@ -171,5 +171,5 @@ class BinarySensorTemplate(BinarySensorDevice):
period = self._delay_on if state else self._delay_off
async_track_same_state(
self.hass, state, period, set_state, entity_ids=self._entities,
async_check_func=self._async_render)
self.hass, period, set_state, entity_ids=self._entities,
async_check_same_func=lambda *args: self._async_render() == state)

View file

@ -30,7 +30,6 @@ class TeslaBinarySensor(TeslaDevice, BinarySensorDevice):
def __init__(self, tesla_device, controller, sensor_type):
"""Initialisation of binary sensor."""
super().__init__(tesla_device, controller)
self._name = self.tesla_device.name
self._state = False
self.entity_id = ENTITY_ID_FORMAT.format(self.tesla_id)
self._sensor_type = sensor_type

View file

@ -20,15 +20,18 @@ from homeassistant.helpers.event import async_track_state_change
_LOGGER = logging.getLogger(__name__)
ATTR_HYSTERESIS = 'hysteresis'
ATTR_SENSOR_VALUE = 'sensor_value'
ATTR_THRESHOLD = 'threshold'
ATTR_TYPE = 'type'
CONF_HYSTERESIS = 'hysteresis'
CONF_LOWER = 'lower'
CONF_THRESHOLD = 'threshold'
CONF_UPPER = 'upper'
DEFAULT_NAME = 'Threshold'
DEFAULT_HYSTERESIS = 0.0
SENSOR_TYPES = [CONF_LOWER, CONF_UPPER]
@ -36,6 +39,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_ENTITY_ID): cv.entity_id,
vol.Required(CONF_THRESHOLD): vol.Coerce(float),
vol.Required(CONF_TYPE): vol.In(SENSOR_TYPES),
vol.Optional(
CONF_HYSTERESIS, default=DEFAULT_HYSTERESIS): vol.Coerce(float),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
@ -47,28 +52,32 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
entity_id = config.get(CONF_ENTITY_ID)
name = config.get(CONF_NAME)
threshold = config.get(CONF_THRESHOLD)
hysteresis = config.get(CONF_HYSTERESIS)
limit_type = config.get(CONF_TYPE)
device_class = config.get(CONF_DEVICE_CLASS)
async_add_devices(
[ThresholdSensor(hass, entity_id, name, threshold, limit_type,
device_class)], True)
async_add_devices([ThresholdSensor(
hass, entity_id, name, threshold,
hysteresis, limit_type, device_class)
], True)
return True
class ThresholdSensor(BinarySensorDevice):
"""Representation of a Threshold sensor."""
def __init__(self, hass, entity_id, name, threshold, limit_type,
device_class):
def __init__(self, hass, entity_id, name, threshold,
hysteresis, limit_type, device_class):
"""Initialize the Threshold sensor."""
self._hass = hass
self._entity_id = entity_id
self.is_upper = limit_type == 'upper'
self._name = name
self._threshold = threshold
self._hysteresis = hysteresis
self._device_class = device_class
self._deviation = False
self._state = False
self.sensor_value = 0
@callback
@ -97,7 +106,7 @@ class ThresholdSensor(BinarySensorDevice):
@property
def is_on(self):
"""Return true if sensor is on."""
return self._deviation
return self._state
@property
def should_poll(self):
@ -116,13 +125,16 @@ class ThresholdSensor(BinarySensorDevice):
ATTR_ENTITY_ID: self._entity_id,
ATTR_SENSOR_VALUE: self.sensor_value,
ATTR_THRESHOLD: self._threshold,
ATTR_HYSTERESIS: self._hysteresis,
ATTR_TYPE: CONF_UPPER if self.is_upper else CONF_LOWER,
}
@asyncio.coroutine
def async_update(self):
"""Get the latest data and updates the states."""
if self.is_upper:
self._deviation = bool(self.sensor_value > self._threshold)
else:
self._deviation = bool(self.sensor_value < self._threshold)
if self._hysteresis == 0 and self.sensor_value == self._threshold:
self._state = False
elif self.sensor_value > (self._threshold + self._hysteresis):
self._state = self.is_upper
elif self.sensor_value < (self._threshold - self._hysteresis):
self._state = not self.is_upper

View file

@ -1,37 +1,40 @@
"""
This component provides basic support for Netgear Arlo IP cameras.
Support for Netgear Arlo IP cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.arlo/
"""
import asyncio
import logging
from datetime import timedelta
import voluptuous as vol
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream
import homeassistant.helpers.config_validation as cv
from homeassistant.components.arlo import DEFAULT_BRAND, DATA_ARLO
from homeassistant.components.camera import Camera, PLATFORM_SCHEMA
from homeassistant.components.ffmpeg import DATA_FFMPEG
from homeassistant.const import ATTR_BATTERY_LEVEL
DEPENDENCIES = ['arlo', 'ffmpeg']
from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(minutes=10)
ARLO_MODE_ARMED = 'armed'
ARLO_MODE_DISARMED = 'disarmed'
ATTR_BRIGHTNESS = 'brightness'
ATTR_FLIPPED = 'flipped'
ATTR_MIRRORED = 'mirrored'
ATTR_MOTION_SENSITIVITY = 'motion_detection_sensitivity'
ATTR_POWER_SAVE_MODE = 'power_save_mode'
ATTR_MOTION = 'motion_detection_sensitivity'
ATTR_POWERSAVE = 'power_save_mode'
ATTR_SIGNAL_STRENGTH = 'signal_strength'
ATTR_UNSEEN_VIDEOS = 'unseen_videos'
CONF_FFMPEG_ARGUMENTS = 'ffmpeg_arguments'
ARLO_MODE_ARMED = 'armed'
ARLO_MODE_DISARMED = 'disarmed'
DEPENDENCIES = ['arlo', 'ffmpeg']
POWERSAVE_MODE_MAPPING = {
1: 'best_battery_life',
@ -40,7 +43,8 @@ POWERSAVE_MODE_MAPPING = {
}
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_FFMPEG_ARGUMENTS): cv.string,
vol.Optional(CONF_FFMPEG_ARGUMENTS):
cv.string,
})
@ -69,6 +73,7 @@ class ArloCam(Camera):
self._motion_status = False
self._ffmpeg = hass.data[DATA_FFMPEG]
self._ffmpeg_arguments = device_info.get(CONF_FFMPEG_ARGUMENTS)
self.attrs = {}
def camera_image(self):
"""Return a still image response from the camera."""
@ -100,32 +105,24 @@ class ArloCam(Camera):
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_BATTERY_LEVEL:
self._camera.get_battery_level,
ATTR_BRIGHTNESS:
self._camera.get_brightness,
ATTR_FLIPPED:
self._camera.get_flip_state,
ATTR_MIRRORED:
self._camera.get_mirror_state,
ATTR_MOTION_SENSITIVITY:
self._camera.get_motion_detection_sensitivity,
ATTR_POWER_SAVE_MODE:
POWERSAVE_MODE_MAPPING[self._camera.get_powersave_mode],
ATTR_SIGNAL_STRENGTH:
self._camera.get_signal_strength,
ATTR_UNSEEN_VIDEOS:
self._camera.unseen_videos
ATTR_BATTERY_LEVEL: self.attrs.get(ATTR_BATTERY_LEVEL),
ATTR_BRIGHTNESS: self.attrs.get(ATTR_BRIGHTNESS),
ATTR_FLIPPED: self.attrs.get(ATTR_FLIPPED),
ATTR_MIRRORED: self.attrs.get(ATTR_MIRRORED),
ATTR_MOTION: self.attrs.get(ATTR_MOTION),
ATTR_POWERSAVE: self.attrs.get(ATTR_POWERSAVE),
ATTR_SIGNAL_STRENGTH: self.attrs.get(ATTR_SIGNAL_STRENGTH),
ATTR_UNSEEN_VIDEOS: self.attrs.get(ATTR_UNSEEN_VIDEOS),
}
@property
def model(self):
"""Camera model."""
"""Return the camera model."""
return self._camera.model_id
@property
def brand(self):
"""Camera brand."""
"""Return the camera brand."""
return DEFAULT_BRAND
@property
@ -135,7 +132,7 @@ class ArloCam(Camera):
@property
def motion_detection_enabled(self):
"""Camera Motion Detection Status."""
"""Return the camera motion detection status."""
return self._motion_status
def set_base_station_mode(self, mode):
@ -143,7 +140,7 @@ class ArloCam(Camera):
# Get the list of base stations identified by library
base_stations = self.hass.data[DATA_ARLO].base_stations
# Some Arlo cameras does not have basestation
# Some Arlo cameras does not have base station
# So check if there is base station detected first
# if yes, then choose the primary base station
# Set the mode on the chosen base station
@ -160,3 +157,16 @@ class ArloCam(Camera):
"""Disable the motion detection in base station (Disarm)."""
self._motion_status = False
self.set_base_station_mode(ARLO_MODE_DISARMED)
def update(self):
"""Add an attribute-update task to the executor pool."""
self.attrs[ATTR_BATTERY_LEVEL] = self._camera.get_battery_level
self.attrs[ATTR_BRIGHTNESS] = self._camera.get_battery_level
self.attrs[ATTR_FLIPPED] = self._camera.get_flip_state,
self.attrs[ATTR_MIRRORED] = self._camera.get_mirror_state,
self.attrs[
ATTR_MOTION] = self._camera.get_motion_detection_sensitivity,
self.attrs[ATTR_POWERSAVE] = POWERSAVE_MODE_MAPPING[
self._camera.get_powersave_mode],
self.attrs[ATTR_SIGNAL_STRENGTH] = self._camera.get_signal_strength,
self.attrs[ATTR_UNSEEN_VIDEOS] = self._camera.unseen_videos

View file

@ -0,0 +1,67 @@
"""
Camera support for the Skybell HD Doorbell.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.skybell/
"""
from datetime import timedelta
import logging
import requests
from homeassistant.components.camera import Camera
from homeassistant.components.skybell import (
DOMAIN as SKYBELL_DOMAIN, SkybellDevice)
DEPENDENCIES = ['skybell']
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=90)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the platform for a Skybell device."""
skybell = hass.data.get(SKYBELL_DOMAIN)
sensors = []
for device in skybell.get_devices():
sensors.append(SkybellCamera(device))
add_devices(sensors, True)
class SkybellCamera(SkybellDevice, Camera):
"""A camera implementation for Skybell devices."""
def __init__(self, device):
"""Initialize a camera for a Skybell device."""
SkybellDevice.__init__(self, device)
Camera.__init__(self)
self._name = self._device.name
self._url = None
self._response = None
@property
def name(self):
"""Return the name of the sensor."""
return self._name
def camera_image(self):
"""Get the latest camera image."""
super().update()
if self._url != self._device.image:
self._url = self._device.image
try:
self._response = requests.get(
self._url, stream=True, timeout=10)
except requests.HTTPError as err:
_LOGGER.warning("Failed to get camera image: %s", err)
self._response = None
if not self._response:
return None
return self._response.content

View file

@ -7,44 +7,25 @@ https://home-assistant.io/components/camera.synology/
import asyncio
import logging
import requests
import voluptuous as vol
import aiohttp
import async_timeout
from homeassistant.const import (
CONF_NAME, CONF_USERNAME, CONF_PASSWORD,
CONF_URL, CONF_WHITELIST, CONF_VERIFY_SSL, CONF_TIMEOUT)
from homeassistant.components.camera import (
Camera, PLATFORM_SCHEMA)
from homeassistant.helpers.aiohttp_client import (
async_get_clientsession, async_create_clientsession,
async_create_clientsession,
async_aiohttp_proxy_web)
import homeassistant.helpers.config_validation as cv
from homeassistant.util.async import run_coroutine_threadsafe
REQUIREMENTS = ['py-synology==0.1.3']
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'Synology Camera'
DEFAULT_STREAM_ID = '0'
DEFAULT_TIMEOUT = 5
CONF_CAMERA_NAME = 'camera_name'
CONF_STREAM_ID = 'stream_id'
QUERY_CGI = 'query.cgi'
QUERY_API = 'SYNO.API.Info'
AUTH_API = 'SYNO.API.Auth'
CAMERA_API = 'SYNO.SurveillanceStation.Camera'
STREAMING_API = 'SYNO.SurveillanceStation.VideoStream'
SESSION_ID = '0'
WEBAPI_PATH = '/webapi/'
AUTH_PATH = 'auth.cgi'
CAMERA_PATH = 'camera.cgi'
STREAMING_PATH = 'SurveillanceStation/videoStreaming.cgi'
CONTENT_TYPE_HEADER = 'Content-Type'
SYNO_API_URL = '{0}{1}{2}'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
@ -62,189 +43,89 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up a Synology IP Camera."""
verify_ssl = config.get(CONF_VERIFY_SSL)
timeout = config.get(CONF_TIMEOUT)
websession_init = async_get_clientsession(hass, verify_ssl)
# Determine API to use for authentication
syno_api_url = SYNO_API_URL.format(
config.get(CONF_URL), WEBAPI_PATH, QUERY_CGI)
query_payload = {
'api': QUERY_API,
'method': 'Query',
'version': '1',
'query': 'SYNO.'
}
try:
with async_timeout.timeout(timeout, loop=hass.loop):
query_req = yield from websession_init.get(
syno_api_url,
params=query_payload
)
# Skip content type check because Synology doesn't return JSON with
# right content type
query_resp = yield from query_req.json(content_type=None)
auth_path = query_resp['data'][AUTH_API]['path']
camera_api = query_resp['data'][CAMERA_API]['path']
camera_path = query_resp['data'][CAMERA_API]['path']
streaming_path = query_resp['data'][STREAMING_API]['path']
except (asyncio.TimeoutError, aiohttp.ClientError):
_LOGGER.exception("Error on %s", syno_api_url)
from synology.surveillance_station import SurveillanceStation
surveillance = SurveillanceStation(
config.get(CONF_URL),
config.get(CONF_USERNAME),
config.get(CONF_PASSWORD),
verify_ssl=verify_ssl,
timeout=timeout
)
except (requests.exceptions.RequestException, ValueError):
_LOGGER.exception("Error when initializing SurveillanceStation")
return False
# Authticate to NAS to get a session id
syno_auth_url = SYNO_API_URL.format(
config.get(CONF_URL), WEBAPI_PATH, auth_path)
session_id = yield from get_session_id(
hass,
websession_init,
config.get(CONF_USERNAME),
config.get(CONF_PASSWORD),
syno_auth_url,
timeout
)
# init websession
websession = async_create_clientsession(
hass, verify_ssl, cookies={'id': session_id})
# Use SessionID to get cameras in system
syno_camera_url = SYNO_API_URL.format(
config.get(CONF_URL), WEBAPI_PATH, camera_api)
camera_payload = {
'api': CAMERA_API,
'method': 'List',
'version': '1'
}
try:
with async_timeout.timeout(timeout, loop=hass.loop):
camera_req = yield from websession.get(
syno_camera_url,
params=camera_payload
)
except (asyncio.TimeoutError, aiohttp.ClientError):
_LOGGER.exception("Error on %s", syno_camera_url)
return False
camera_resp = yield from camera_req.json(content_type=None)
cameras = camera_resp['data']['cameras']
cameras = surveillance.get_all_cameras()
websession = async_create_clientsession(hass, verify_ssl)
# add cameras
devices = []
for camera in cameras:
if not config.get(CONF_WHITELIST):
camera_id = camera['id']
snapshot_path = camera['snapshot_path']
device = SynologyCamera(
hass, websession, config, camera_id, camera['name'],
snapshot_path, streaming_path, camera_path, auth_path, timeout
)
device = SynologyCamera(websession, surveillance, camera.camera_id)
devices.append(device)
async_add_devices(devices)
@asyncio.coroutine
def get_session_id(hass, websession, username, password, login_url, timeout):
"""Get a session id."""
auth_payload = {
'api': AUTH_API,
'method': 'Login',
'version': '2',
'account': username,
'passwd': password,
'session': 'SurveillanceStation',
'format': 'sid'
}
try:
with async_timeout.timeout(timeout, loop=hass.loop):
auth_req = yield from websession.get(
login_url,
params=auth_payload
)
auth_resp = yield from auth_req.json(content_type=None)
return auth_resp['data']['sid']
except (asyncio.TimeoutError, aiohttp.ClientError):
_LOGGER.exception("Error on %s", login_url)
return False
class SynologyCamera(Camera):
"""An implementation of a Synology NAS based IP camera."""
def __init__(self, hass, websession, config, camera_id,
camera_name, snapshot_path, streaming_path, camera_path,
auth_path, timeout):
def __init__(self, websession, surveillance, camera_id):
"""Initialize a Synology Surveillance Station camera."""
super().__init__()
self.hass = hass
self._websession = websession
self._name = camera_name
self._synology_url = config.get(CONF_URL)
self._camera_name = config.get(CONF_CAMERA_NAME)
self._stream_id = config.get(CONF_STREAM_ID)
self._surveillance = surveillance
self._camera_id = camera_id
self._snapshot_path = snapshot_path
self._streaming_path = streaming_path
self._camera_path = camera_path
self._auth_path = auth_path
self._timeout = timeout
self._camera = self._surveillance.get_camera(camera_id)
self._motion_setting = self._surveillance.get_motion_setting(camera_id)
self.is_streaming = self._camera.is_enabled
def camera_image(self):
"""Return bytes of camera image."""
return run_coroutine_threadsafe(
self.async_camera_image(), self.hass.loop).result()
@asyncio.coroutine
def async_camera_image(self):
"""Return a still image response from the camera."""
image_url = SYNO_API_URL.format(
self._synology_url, WEBAPI_PATH, self._camera_path)
image_payload = {
'api': CAMERA_API,
'method': 'GetSnapshot',
'version': '1',
'cameraId': self._camera_id
}
try:
with async_timeout.timeout(self._timeout, loop=self.hass.loop):
response = yield from self._websession.get(
image_url,
params=image_payload
)
except (asyncio.TimeoutError, aiohttp.ClientError):
_LOGGER.error("Error fetching %s", image_url)
return None
image = yield from response.read()
return image
return self._surveillance.get_camera_image(self._camera_id)
@asyncio.coroutine
def handle_async_mjpeg_stream(self, request):
"""Return a MJPEG stream image response directly from the camera."""
streaming_url = SYNO_API_URL.format(
self._synology_url, WEBAPI_PATH, self._streaming_path)
streaming_payload = {
'api': STREAMING_API,
'method': 'Stream',
'version': '1',
'cameraId': self._camera_id,
'format': 'mjpeg'
}
stream_coro = self._websession.get(
streaming_url, params=streaming_payload)
streaming_url = self._camera.video_stream_url
stream_coro = self._websession.get(streaming_url)
yield from async_aiohttp_proxy_web(self.hass, request, stream_coro)
@property
def name(self):
"""Return the name of this device."""
return self._name
return self._camera.name
@property
def is_recording(self):
"""Return true if the device is recording."""
return self._camera.is_recording
def should_poll(self):
"""Update the recording state periodically."""
return True
def update(self):
"""Update the status of the camera."""
self._surveillance.update()
self._camera = self._surveillance.get_camera(self._camera.camera_id)
self._motion_setting = self._surveillance.get_motion_setting(
self._camera.camera_id)
self.is_streaming = self._camera.is_enabled
@property
def motion_detection_enabled(self):
"""Return the camera motion detection status."""
return self._motion_setting.is_enabled
def enable_motion_detection(self):
"""Enable motion detection in the camera."""
self._surveillance.enable_motion_detection(self._camera_id)
def disable_motion_detection(self):
"""Disable motion detection in camera."""
self._surveillance.disable_motion_detection(self._camera_id)

View file

@ -27,6 +27,7 @@ ATTR_RESUME_ALL = 'resume_all'
DEFAULT_RESUME_ALL = False
TEMPERATURE_HOLD = 'temp'
VACATION_HOLD = 'vacation'
AWAY_MODE = 'awayMode'
DEPENDENCIES = ['ecobee']
@ -144,20 +145,20 @@ class Thermostat(ClimateDevice):
@property
def current_temperature(self):
"""Return the current temperature."""
return self.thermostat['runtime']['actualTemperature'] / 10
return self.thermostat['runtime']['actualTemperature'] / 10.0
@property
def target_temperature_low(self):
"""Return the lower bound temperature we try to reach."""
if self.current_operation == STATE_AUTO:
return int(self.thermostat['runtime']['desiredHeat'] / 10)
return self.thermostat['runtime']['desiredHeat'] / 10.0
return None
@property
def target_temperature_high(self):
"""Return the upper bound temperature we try to reach."""
if self.current_operation == STATE_AUTO:
return int(self.thermostat['runtime']['desiredCool'] / 10)
return self.thermostat['runtime']['desiredCool'] / 10.0
return None
@property
@ -166,9 +167,9 @@ class Thermostat(ClimateDevice):
if self.current_operation == STATE_AUTO:
return None
if self.current_operation == STATE_HEAT:
return int(self.thermostat['runtime']['desiredHeat'] / 10)
return self.thermostat['runtime']['desiredHeat'] / 10.0
elif self.current_operation == STATE_COOL:
return int(self.thermostat['runtime']['desiredCool'] / 10)
return self.thermostat['runtime']['desiredCool'] / 10.0
return None
@property
@ -186,6 +187,11 @@ class Thermostat(ClimateDevice):
@property
def current_hold_mode(self):
"""Return current hold mode."""
mode = self._current_hold_mode
return None if mode == AWAY_MODE else mode
@property
def _current_hold_mode(self):
events = self.thermostat['events']
for event in events:
if event['running']:
@ -195,8 +201,8 @@ class Thermostat(ClimateDevice):
int(event['startDate'][0:4]) <= 1:
# A temporary hold from away climate is a hold
return 'away'
# A permanent hold from away climate is away_mode
return None
# A permanent hold from away climate
return AWAY_MODE
elif event['holdClimateRef'] != "":
# Any other hold based on climate
return event['holdClimateRef']
@ -269,7 +275,7 @@ class Thermostat(ClimateDevice):
@property
def is_away_mode_on(self):
"""Return true if away mode is on."""
return self.current_hold_mode == 'away'
return self._current_hold_mode == AWAY_MODE
@property
def is_aux_heat_on(self):
@ -277,12 +283,17 @@ class Thermostat(ClimateDevice):
return 'auxHeat' in self.thermostat['equipmentStatus']
def turn_away_mode_on(self):
"""Turn away on."""
self.set_hold_mode('away')
"""Turn away mode on by setting it on away hold indefinitely."""
if self._current_hold_mode != AWAY_MODE:
self.data.ecobee.set_climate_hold(self.thermostat_index, 'away',
'indefinite')
self.update_without_throttle = True
def turn_away_mode_off(self):
"""Turn away off."""
self.set_hold_mode(None)
if self._current_hold_mode == AWAY_MODE:
self.data.ecobee.resume_program(self.thermostat_index)
self.update_without_throttle = True
def set_hold_mode(self, hold_mode):
"""Set hold mode (away, home, temp, sleep, etc.)."""
@ -299,7 +310,7 @@ class Thermostat(ClimateDevice):
self.data.ecobee.resume_program(self.thermostat_index)
else:
if hold_mode == TEMPERATURE_HOLD:
self.set_temp_hold(int(self.current_temperature))
self.set_temp_hold(self.current_temperature)
else:
self.data.ecobee.set_climate_hold(
self.thermostat_index, hold_mode, self.hold_preference())
@ -325,15 +336,11 @@ class Thermostat(ClimateDevice):
elif self.current_operation == STATE_COOL:
heat_temp = temp - 20
cool_temp = temp
self.data.ecobee.set_hold_temp(self.thermostat_index, cool_temp,
heat_temp, self.hold_preference())
_LOGGER.debug("Setting ecobee hold_temp to: low=%s, is=%s, "
"cool=%s, is=%s", heat_temp, isinstance(
heat_temp, (int, float)), cool_temp,
isinstance(cool_temp, (int, float)))
self.update_without_throttle = True
else:
# In auto mode set temperature between
heat_temp = temp - 10
cool_temp = temp + 10
self.set_auto_temp_hold(heat_temp, cool_temp)
def set_temperature(self, **kwargs):
"""Set new target temperature."""
@ -343,9 +350,9 @@ class Thermostat(ClimateDevice):
if self.current_operation == STATE_AUTO and low_temp is not None \
and high_temp is not None:
self.set_auto_temp_hold(int(low_temp), int(high_temp))
self.set_auto_temp_hold(low_temp, high_temp)
elif temp is not None:
self.set_temp_hold(int(temp))
self.set_temp_hold(temp)
else:
_LOGGER.error(
"Missing valid arguments for set_temperature in %s", kwargs)
@ -364,7 +371,7 @@ class Thermostat(ClimateDevice):
def resume_program(self, resume_all):
"""Resume the thermostat schedule program."""
self.data.ecobee.resume_program(
self.thermostat_index, str(resume_all).lower())
self.thermostat_index, 'true' if resume_all else 'false')
self.update_without_throttle = True
def hold_preference(self):

View file

@ -17,7 +17,7 @@ from homeassistant.const import (
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['python-eq3bt==0.1.5']
REQUIREMENTS = ['python-eq3bt==0.1.6']
_LOGGER = logging.getLogger(__name__)
@ -164,4 +164,8 @@ class EQ3BTSmartThermostat(ClimateDevice):
def update(self):
"""Update the data from the thermostat."""
self._thermostat.update()
from bluepy.btle import BTLEException
try:
self._thermostat.update()
except BTLEException as ex:
_LOGGER.warning("Updating the state failed: %s", ex)

View file

@ -0,0 +1,483 @@
"""
Support for MQTT climate devices.
For more details about this platform, please refer to the documentation
https://home-assistant.io/components/climate.mqtt/
"""
import asyncio
import logging
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.components.mqtt as mqtt
from homeassistant.components.climate import (
STATE_HEAT, STATE_COOL, STATE_DRY, STATE_FAN_ONLY, ClimateDevice,
PLATFORM_SCHEMA as CLIMATE_PLATFORM_SCHEMA, STATE_AUTO,
ATTR_OPERATION_MODE)
from homeassistant.const import (
STATE_ON, STATE_OFF, ATTR_TEMPERATURE, CONF_NAME)
from homeassistant.components.mqtt import (CONF_QOS, CONF_RETAIN)
import homeassistant.helpers.config_validation as cv
from homeassistant.components.fan import (SPEED_LOW, SPEED_MEDIUM,
SPEED_HIGH)
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['mqtt']
DEFAULT_NAME = 'MQTT HVAC'
CONF_POWER_COMMAND_TOPIC = 'power_command_topic'
CONF_POWER_STATE_TOPIC = 'power_state_topic'
CONF_MODE_COMMAND_TOPIC = 'mode_command_topic'
CONF_MODE_STATE_TOPIC = 'mode_state_topic'
CONF_TEMPERATURE_COMMAND_TOPIC = 'temperature_command_topic'
CONF_TEMPERATURE_STATE_TOPIC = 'temperature_state_topic'
CONF_FAN_MODE_COMMAND_TOPIC = 'fan_mode_command_topic'
CONF_FAN_MODE_STATE_TOPIC = 'fan_mode_state_topic'
CONF_SWING_MODE_COMMAND_TOPIC = 'swing_mode_command_topic'
CONF_SWING_MODE_STATE_TOPIC = 'swing_mode_state_topic'
CONF_AWAY_MODE_COMMAND_TOPIC = 'away_mode_command_topic'
CONF_AWAY_MODE_STATE_TOPIC = 'away_mode_state_topic'
CONF_HOLD_COMMAND_TOPIC = 'hold_command_topic'
CONF_HOLD_STATE_TOPIC = 'hold_state_topic'
CONF_AUX_COMMAND_TOPIC = 'aux_command_topic'
CONF_AUX_STATE_TOPIC = 'aux_state_topic'
CONF_CURRENT_TEMPERATURE_TOPIC = 'current_temperature_topic'
CONF_PAYLOAD_ON = 'payload_on'
CONF_PAYLOAD_OFF = 'payload_off'
CONF_FAN_MODE_LIST = 'fan_modes'
CONF_MODE_LIST = 'modes'
CONF_SWING_MODE_LIST = 'swing_modes'
CONF_INITIAL = 'initial'
CONF_SEND_IF_OFF = 'send_if_off'
PLATFORM_SCHEMA = CLIMATE_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_POWER_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_MODE_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_TEMPERATURE_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_FAN_MODE_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_SWING_MODE_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_AWAY_MODE_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_HOLD_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_AUX_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_POWER_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_MODE_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_TEMPERATURE_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_FAN_MODE_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_SWING_MODE_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_AWAY_MODE_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_HOLD_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_AUX_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_CURRENT_TEMPERATURE_TOPIC):
mqtt.valid_subscribe_topic,
vol.Optional(CONF_FAN_MODE_LIST,
default=[STATE_AUTO, SPEED_LOW,
SPEED_MEDIUM, SPEED_HIGH]): cv.ensure_list,
vol.Optional(CONF_SWING_MODE_LIST,
default=[STATE_ON, STATE_OFF]): cv.ensure_list,
vol.Optional(CONF_MODE_LIST,
default=[STATE_AUTO, STATE_OFF, STATE_COOL, STATE_HEAT,
STATE_DRY, STATE_FAN_ONLY]): cv.ensure_list,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_INITIAL, default=21): cv.positive_int,
vol.Optional(CONF_SEND_IF_OFF, default=True): cv.boolean,
vol.Optional(CONF_PAYLOAD_ON, default="ON"): cv.string,
vol.Optional(CONF_PAYLOAD_OFF, default="OFF"): cv.string,
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up the MQTT climate devices."""
async_add_devices([
MqttClimate(
hass,
config.get(CONF_NAME),
{
key: config.get(key) for key in (
CONF_POWER_COMMAND_TOPIC,
CONF_MODE_COMMAND_TOPIC,
CONF_TEMPERATURE_COMMAND_TOPIC,
CONF_FAN_MODE_COMMAND_TOPIC,
CONF_SWING_MODE_COMMAND_TOPIC,
CONF_AWAY_MODE_COMMAND_TOPIC,
CONF_HOLD_COMMAND_TOPIC,
CONF_AUX_COMMAND_TOPIC,
CONF_POWER_STATE_TOPIC,
CONF_MODE_STATE_TOPIC,
CONF_TEMPERATURE_STATE_TOPIC,
CONF_FAN_MODE_STATE_TOPIC,
CONF_SWING_MODE_STATE_TOPIC,
CONF_AWAY_MODE_STATE_TOPIC,
CONF_HOLD_STATE_TOPIC,
CONF_AUX_STATE_TOPIC,
CONF_CURRENT_TEMPERATURE_TOPIC
)
},
config.get(CONF_QOS),
config.get(CONF_RETAIN),
config.get(CONF_MODE_LIST),
config.get(CONF_FAN_MODE_LIST),
config.get(CONF_SWING_MODE_LIST),
config.get(CONF_INITIAL),
False, None, SPEED_LOW,
STATE_OFF, STATE_OFF, False,
config.get(CONF_SEND_IF_OFF),
config.get(CONF_PAYLOAD_ON),
config.get(CONF_PAYLOAD_OFF))
])
class MqttClimate(ClimateDevice):
"""Representation of a demo climate device."""
def __init__(self, hass, name, topic, qos, retain, mode_list,
fan_mode_list, swing_mode_list, target_temperature, away,
hold, current_fan_mode, current_swing_mode,
current_operation, aux, send_if_off, payload_on,
payload_off):
"""Initialize the climate device."""
self.hass = hass
self._name = name
self._topic = topic
self._qos = qos
self._retain = retain
self._target_temperature = target_temperature
self._unit_of_measurement = hass.config.units.temperature_unit
self._away = away
self._hold = hold
self._current_temperature = None
self._current_fan_mode = current_fan_mode
self._current_operation = current_operation
self._aux = aux
self._current_swing_mode = current_swing_mode
self._fan_list = fan_mode_list
self._operation_list = mode_list
self._swing_list = swing_mode_list
self._target_temperature_step = 1
self._send_if_off = send_if_off
self._payload_on = payload_on
self._payload_off = payload_off
def async_added_to_hass(self):
"""Handle being added to home assistant."""
@callback
def handle_current_temp_received(topic, payload, qos):
"""Handle current temperature coming via MQTT."""
try:
self._current_temperature = float(payload)
self.async_schedule_update_ha_state()
except ValueError:
_LOGGER.error("Could not parse temperature from %s", payload)
if self._topic[CONF_CURRENT_TEMPERATURE_TOPIC] is not None:
yield from mqtt.async_subscribe(
self.hass, self._topic[CONF_CURRENT_TEMPERATURE_TOPIC],
handle_current_temp_received, self._qos)
@callback
def handle_mode_received(topic, payload, qos):
"""Handle receiving mode via MQTT."""
if payload not in self._operation_list:
_LOGGER.error("Invalid mode: %s", payload)
else:
self._current_operation = payload
self.async_schedule_update_ha_state()
if self._topic[CONF_MODE_STATE_TOPIC] is not None:
yield from mqtt.async_subscribe(
self.hass, self._topic[CONF_MODE_STATE_TOPIC],
handle_mode_received, self._qos)
@callback
def handle_temperature_received(topic, payload, qos):
"""Handle target temperature coming via MQTT."""
try:
self._target_temperature = float(payload)
self.async_schedule_update_ha_state()
except ValueError:
_LOGGER.error("Could not parse temperature from %s", payload)
if self._topic[CONF_TEMPERATURE_STATE_TOPIC] is not None:
yield from mqtt.async_subscribe(
self.hass, self._topic[CONF_TEMPERATURE_STATE_TOPIC],
handle_temperature_received, self._qos)
@callback
def handle_fan_mode_received(topic, payload, qos):
"""Handle receiving fan mode via MQTT."""
if payload not in self._fan_list:
_LOGGER.error("Invalid fan mode: %s", payload)
else:
self._current_fan_mode = payload
self.async_schedule_update_ha_state()
if self._topic[CONF_FAN_MODE_STATE_TOPIC] is not None:
yield from mqtt.async_subscribe(
self.hass, self._topic[CONF_FAN_MODE_STATE_TOPIC],
handle_fan_mode_received, self._qos)
@callback
def handle_swing_mode_received(topic, payload, qos):
"""Handle receiving swing mode via MQTT."""
if payload not in self._swing_list:
_LOGGER.error("Invalid swing mode: %s", payload)
else:
self._current_swing_mode = payload
self.async_schedule_update_ha_state()
if self._topic[CONF_SWING_MODE_STATE_TOPIC] is not None:
yield from mqtt.async_subscribe(
self.hass, self._topic[CONF_SWING_MODE_STATE_TOPIC],
handle_swing_mode_received, self._qos)
@callback
def handle_away_mode_received(topic, payload, qos):
"""Handle receiving away mode via MQTT."""
if payload == self._payload_on:
self._away = True
elif payload == self._payload_off:
self._away = False
else:
_LOGGER.error("Invalid away mode: %s", payload)
self.async_schedule_update_ha_state()
if self._topic[CONF_AWAY_MODE_STATE_TOPIC] is not None:
yield from mqtt.async_subscribe(
self.hass, self._topic[CONF_AWAY_MODE_STATE_TOPIC],
handle_away_mode_received, self._qos)
@callback
def handle_aux_mode_received(topic, payload, qos):
"""Handle receiving aux mode via MQTT."""
if payload == self._payload_on:
self._aux = True
elif payload == self._payload_off:
self._aux = False
else:
_LOGGER.error("Invalid aux mode: %s", payload)
self.async_schedule_update_ha_state()
if self._topic[CONF_AUX_STATE_TOPIC] is not None:
yield from mqtt.async_subscribe(
self.hass, self._topic[CONF_AUX_STATE_TOPIC],
handle_aux_mode_received, self._qos)
@callback
def handle_hold_mode_received(topic, payload, qos):
"""Handle receiving hold mode via MQTT."""
self._hold = payload
self.async_schedule_update_ha_state()
if self._topic[CONF_HOLD_STATE_TOPIC] is not None:
yield from mqtt.async_subscribe(
self.hass, self._topic[CONF_HOLD_STATE_TOPIC],
handle_hold_mode_received, self._qos)
@property
def should_poll(self):
"""Return the polling state."""
return False
@property
def name(self):
"""Return the name of the climate device."""
return self._name
@property
def temperature_unit(self):
"""Return the unit of measurement."""
return self._unit_of_measurement
@property
def current_temperature(self):
"""Return the current temperature."""
return self._current_temperature
@property
def target_temperature(self):
"""Return the temperature we try to reach."""
return self._target_temperature
@property
def current_operation(self):
"""Return current operation ie. heat, cool, idle."""
return self._current_operation
@property
def operation_list(self):
"""Return the list of available operation modes."""
return self._operation_list
@property
def target_temperature_step(self):
"""Return the supported step of target temperature."""
return self._target_temperature_step
@property
def is_away_mode_on(self):
"""Return if away mode is on."""
return self._away
@property
def current_hold_mode(self):
"""Return hold mode setting."""
return self._hold
@property
def is_aux_heat_on(self):
"""Return true if away mode is on."""
return self._aux
@property
def current_fan_mode(self):
"""Return the fan setting."""
return self._current_fan_mode
@property
def fan_list(self):
"""Return the list of available fan modes."""
return self._fan_list
@asyncio.coroutine
def async_set_temperature(self, **kwargs):
"""Set new target temperatures."""
if kwargs.get(ATTR_OPERATION_MODE) is not None:
operation_mode = kwargs.get(ATTR_OPERATION_MODE)
yield from self.async_set_operation_mode(operation_mode)
if kwargs.get(ATTR_TEMPERATURE) is not None:
if self._topic[CONF_TEMPERATURE_STATE_TOPIC] is None:
# optimistic mode
self._target_temperature = kwargs.get(ATTR_TEMPERATURE)
if self._send_if_off or self._current_operation != STATE_OFF:
mqtt.async_publish(
self.hass, self._topic[CONF_TEMPERATURE_COMMAND_TOPIC],
kwargs.get(ATTR_TEMPERATURE), self._qos, self._retain)
self.async_schedule_update_ha_state()
@asyncio.coroutine
def async_set_swing_mode(self, swing_mode):
"""Set new swing mode."""
if self._send_if_off or self._current_operation != STATE_OFF:
mqtt.async_publish(
self.hass, self._topic[CONF_SWING_MODE_COMMAND_TOPIC],
swing_mode, self._qos, self._retain)
if self._topic[CONF_SWING_MODE_STATE_TOPIC] is None:
self._current_swing_mode = swing_mode
self.async_schedule_update_ha_state()
@asyncio.coroutine
def async_set_fan_mode(self, fan):
"""Set new target temperature."""
if self._send_if_off or self._current_operation != STATE_OFF:
mqtt.async_publish(
self.hass, self._topic[CONF_FAN_MODE_COMMAND_TOPIC],
fan, self._qos, self._retain)
if self._topic[CONF_FAN_MODE_STATE_TOPIC] is None:
self._current_fan_mode = fan
self.async_schedule_update_ha_state()
@asyncio.coroutine
def async_set_operation_mode(self, operation_mode) -> None:
"""Set new operation mode."""
if self._topic[CONF_POWER_COMMAND_TOPIC] is not None:
if (self._current_operation == STATE_OFF and
operation_mode != STATE_OFF):
mqtt.async_publish(
self.hass, self._topic[CONF_POWER_COMMAND_TOPIC],
self._payload_on, self._qos, self._retain)
elif (self._current_operation != STATE_OFF and
operation_mode == STATE_OFF):
mqtt.async_publish(
self.hass, self._topic[CONF_POWER_COMMAND_TOPIC],
self._payload_off, self._qos, self._retain)
if self._topic[CONF_MODE_COMMAND_TOPIC] is not None:
mqtt.async_publish(
self.hass, self._topic[CONF_MODE_COMMAND_TOPIC],
operation_mode, self._qos, self._retain)
if self._topic[CONF_MODE_STATE_TOPIC] is None:
self._current_operation = operation_mode
self.async_schedule_update_ha_state()
@property
def current_swing_mode(self):
"""Return the swing setting."""
return self._current_swing_mode
@property
def swing_list(self):
"""List of available swing modes."""
return self._swing_list
@asyncio.coroutine
def async_turn_away_mode_on(self):
"""Turn away mode on."""
if self._topic[CONF_AWAY_MODE_COMMAND_TOPIC] is not None:
mqtt.async_publish(self.hass,
self._topic[CONF_AWAY_MODE_COMMAND_TOPIC],
self._payload_on, self._qos, self._retain)
if self._topic[CONF_AWAY_MODE_STATE_TOPIC] is None:
self._away = True
self.async_schedule_update_ha_state()
@asyncio.coroutine
def async_turn_away_mode_off(self):
"""Turn away mode off."""
if self._topic[CONF_AWAY_MODE_COMMAND_TOPIC] is not None:
mqtt.async_publish(self.hass,
self._topic[CONF_AWAY_MODE_COMMAND_TOPIC],
self._payload_off, self._qos, self._retain)
if self._topic[CONF_AWAY_MODE_STATE_TOPIC] is None:
self._away = False
self.async_schedule_update_ha_state()
@asyncio.coroutine
def async_set_hold_mode(self, hold):
"""Update hold mode on."""
if self._topic[CONF_HOLD_COMMAND_TOPIC] is not None:
mqtt.async_publish(self.hass,
self._topic[CONF_HOLD_COMMAND_TOPIC],
hold, self._qos, self._retain)
if self._topic[CONF_HOLD_STATE_TOPIC] is None:
self._hold = hold
self.async_schedule_update_ha_state()
@asyncio.coroutine
def async_turn_aux_heat_on(self):
"""Turn auxillary heater on."""
if self._topic[CONF_AUX_COMMAND_TOPIC] is not None:
mqtt.async_publish(self.hass, self._topic[CONF_AUX_COMMAND_TOPIC],
self._payload_on, self._qos, self._retain)
if self._topic[CONF_AUX_STATE_TOPIC] is None:
self._aux = True
self.async_schedule_update_ha_state()
@asyncio.coroutine
def async_turn_aux_heat_off(self):
"""Turn auxillary heater off."""
if self._topic[CONF_AUX_COMMAND_TOPIC] is not None:
mqtt.async_publish(self.hass, self._topic[CONF_AUX_COMMAND_TOPIC],
self._payload_off, self._qos, self._retain)
if self._topic[CONF_AUX_STATE_TOPIC] is None:
self._aux = False
self.async_schedule_update_ha_state()

View file

@ -35,7 +35,6 @@ class TeslaThermostat(TeslaDevice, ClimateDevice):
self.entity_id = ENTITY_ID_FORMAT.format(self.tesla_id)
self._target_temperature = None
self._temperature = None
self._name = self.tesla_device.name
@property
def current_operation(self):

View file

@ -0,0 +1,121 @@
"""
Support for Rflink Cover devices.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/cover.rflink/
"""
import asyncio
import logging
import voluptuous as vol
from homeassistant.components.rflink import (
DATA_ENTITY_GROUP_LOOKUP, DATA_ENTITY_LOOKUP,
DEVICE_DEFAULTS_SCHEMA, EVENT_KEY_COMMAND, RflinkCommand)
from homeassistant.components.cover import (
CoverDevice, PLATFORM_SCHEMA)
import homeassistant.helpers.config_validation as cv
from homeassistant.const import CONF_NAME
DEPENDENCIES = ['rflink']
_LOGGER = logging.getLogger(__name__)
CONF_ALIASES = 'aliases'
CONF_GROUP_ALIASES = 'group_aliases'
CONF_GROUP = 'group'
CONF_NOGROUP_ALIASES = 'nogroup_aliases'
CONF_DEVICE_DEFAULTS = 'device_defaults'
CONF_DEVICES = 'devices'
CONF_AUTOMATIC_ADD = 'automatic_add'
CONF_FIRE_EVENT = 'fire_event'
CONF_IGNORE_DEVICES = 'ignore_devices'
CONF_RECONNECT_INTERVAL = 'reconnect_interval'
CONF_SIGNAL_REPETITIONS = 'signal_repetitions'
CONF_WAIT_FOR_ACK = 'wait_for_ack'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_DEVICE_DEFAULTS, default=DEVICE_DEFAULTS_SCHEMA({})):
DEVICE_DEFAULTS_SCHEMA,
vol.Optional(CONF_DEVICES, default={}): vol.Schema({
cv.string: {
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_ALIASES, default=[]):
vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_GROUP_ALIASES, default=[]):
vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_NOGROUP_ALIASES, default=[]):
vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_FIRE_EVENT, default=False): cv.boolean,
vol.Optional(CONF_SIGNAL_REPETITIONS): vol.Coerce(int),
vol.Optional(CONF_GROUP, default=True): cv.boolean,
},
}),
})
def devices_from_config(domain_config, hass=None):
"""Parse configuration and add Rflink cover devices."""
devices = []
for device_id, config in domain_config[CONF_DEVICES].items():
device_config = dict(domain_config[CONF_DEVICE_DEFAULTS], **config)
device = RflinkCover(device_id, hass, **device_config)
devices.append(device)
# Register entity (and aliases) to listen to incoming rflink events
# Device id and normal aliases respond to normal and group command
hass.data[DATA_ENTITY_LOOKUP][
EVENT_KEY_COMMAND][device_id].append(device)
if config[CONF_GROUP]:
hass.data[DATA_ENTITY_GROUP_LOOKUP][
EVENT_KEY_COMMAND][device_id].append(device)
for _id in config[CONF_ALIASES]:
hass.data[DATA_ENTITY_LOOKUP][
EVENT_KEY_COMMAND][_id].append(device)
hass.data[DATA_ENTITY_GROUP_LOOKUP][
EVENT_KEY_COMMAND][_id].append(device)
return devices
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up the Rflink cover platform."""
async_add_devices(devices_from_config(config, hass))
class RflinkCover(RflinkCommand, CoverDevice):
"""Rflink entity which can switch on/stop/off (eg: cover)."""
def _handle_event(self, event):
"""Adjust state if Rflink picks up a remote command for this device."""
self.cancel_queued_send_commands()
command = event['command']
if command in ['on', 'allon']:
self._state = True
elif command in ['off', 'alloff']:
self._state = False
@property
def should_poll(self):
"""No polling available in RFlink cover."""
return False
@property
def is_closed(self):
"""Return if the cover is closed."""
return None
def async_close_cover(self, **kwargs):
"""Turn the device close."""
return self._async_handle_command("close_cover")
def async_open_cover(self, **kwargs):
"""Turn the device open."""
return self._async_handle_command("open_cover")
def async_stop_cover(self, **kwargs):
"""Turn the device stop."""
return self._async_handle_command("stop_cover")

View file

@ -87,8 +87,8 @@ def async_setup(hass, config):
# Set up input boolean
tasks.append(bootstrap.async_setup_component(
hass, 'input_slider',
{'input_slider': {
hass, 'input_number',
{'input_number': {
'noise_allowance': {'icon': 'mdi:bell-ring',
'min': 0,
'max': 10,
@ -163,7 +163,7 @@ def async_setup(hass, config):
'scene.romantic_lights']))
tasks2.append(group.Group.async_create_group(hass, 'Bedroom', [
lights[0], switches[1], media_players[0],
'input_slider.noise_allowance']))
'input_number.noise_allowance']))
tasks2.append(group.Group.async_create_group(hass, 'Kitchen', [
lights[2], 'cover.kitchen_window', 'lock.kitchen_door']))
tasks2.append(group.Group.async_create_group(hass, 'Doors', [

View file

@ -18,11 +18,10 @@ from homeassistant.setup import async_prepare_setup_platform
from homeassistant.core import callback
from homeassistant.loader import bind_hass
from homeassistant.components import group, zone
from homeassistant.components.discovery import SERVICE_NETGEAR
from homeassistant.config import load_yaml_config_file, async_log_exception
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers import config_per_platform, discovery
from homeassistant.helpers import config_per_platform
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.restore_state import async_get_last_state
@ -89,10 +88,6 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
cv.time_period, cv.positive_timedelta)
})
DISCOVERY_PLATFORMS = {
SERVICE_NETGEAR: 'netgear',
}
@bind_hass
def is_on(hass: HomeAssistantType, entity_id: str=None):
@ -180,22 +175,6 @@ def async_setup(hass: HomeAssistantType, config: ConfigType):
tracker.async_setup_group()
@callback
def async_device_tracker_discovered(service, info):
"""Handle the discovery of device tracker platforms."""
hass.async_add_job(
async_setup_platform(DISCOVERY_PLATFORMS[service], {}, info))
discovery.async_listen(
hass, DISCOVERY_PLATFORMS.keys(), async_device_tracker_discovered)
@asyncio.coroutine
def async_platform_discovered(platform, info):
"""Load a platform."""
yield from async_setup_platform(platform, {}, disc_info=info)
discovery.async_listen_platform(hass, DOMAIN, async_platform_discovered)
# Clean up stale devices
async_track_utc_time_change(
hass, tracker.async_update_stale, second=range(0, 60, 5))

View file

@ -1,5 +1,5 @@
"""
Support the OwnTracks platform.
Device tracker platform that adds support for OwnTracks over MQTT.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.owntracks/
@ -64,13 +64,7 @@ def get_cipher():
@asyncio.coroutine
def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up an OwnTracks tracker."""
max_gps_accuracy = config.get(CONF_MAX_GPS_ACCURACY)
waypoint_import = config.get(CONF_WAYPOINT_IMPORT)
waypoint_whitelist = config.get(CONF_WAYPOINT_WHITELIST)
secret = config.get(CONF_SECRET)
context = OwnTracksContext(async_see, secret, max_gps_accuracy,
waypoint_import, waypoint_whitelist)
context = context_from_config(async_see, config)
@asyncio.coroutine
def async_handle_mqtt_message(topic, payload, qos):
@ -179,6 +173,17 @@ def _decrypt_payload(secret, topic, ciphertext):
return None
def context_from_config(async_see, config):
"""Create an async context from Home Assistant config."""
max_gps_accuracy = config.get(CONF_MAX_GPS_ACCURACY)
waypoint_import = config.get(CONF_WAYPOINT_IMPORT)
waypoint_whitelist = config.get(CONF_WAYPOINT_WHITELIST)
secret = config.get(CONF_SECRET)
return OwnTracksContext(async_see, secret, max_gps_accuracy,
waypoint_import, waypoint_whitelist)
class OwnTracksContext:
"""Hold the current OwnTracks context."""
@ -402,7 +407,8 @@ def async_handle_message(hass, context, message):
handler = HANDLERS.get(msgtype)
if handler is None:
error = 'Received unsupported message type: {}.'.format(msgtype)
_LOGGER.warning(error)
_LOGGER.warning(
'Received unsupported message type: %s.', msgtype)
return
yield from handler(hass, context, message)

View file

@ -0,0 +1,54 @@
"""
Device tracker platform that adds support for OwnTracks over HTTP.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.owntracks_http/
"""
import asyncio
from aiohttp.web_exceptions import HTTPInternalServerError
from homeassistant.components.http import HomeAssistantView
# pylint: disable=unused-import
from .owntracks import ( # NOQA
REQUIREMENTS, PLATFORM_SCHEMA, context_from_config, async_handle_message)
DEPENDENCIES = ['http']
@asyncio.coroutine
def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up an OwnTracks tracker."""
context = context_from_config(async_see, config)
hass.http.register_view(OwnTracksView(context))
return True
class OwnTracksView(HomeAssistantView):
"""View to handle OwnTracks HTTP requests."""
url = '/api/owntracks/{user}/{device}'
name = 'api:owntracks'
def __init__(self, context):
"""Initialize OwnTracks URL endpoints."""
self.context = context
@asyncio.coroutine
def post(self, request, user, device):
"""Handle an OwnTracks message."""
hass = request.app['hass']
message = yield from request.json()
message['topic'] = 'owntracks/{}/{}'.format(user, device)
try:
yield from async_handle_message(hass, self.context, message)
return self.json([])
except ValueError:
raise HTTPInternalServerError

View file

@ -16,7 +16,7 @@ from homeassistant.const import CONF_HOST
_LOGGER = logging.getLogger(__name__)
REQUIREMENTS = ['pysnmp==4.3.9']
REQUIREMENTS = ['pysnmp==4.3.10']
CONF_COMMUNITY = 'community'
CONF_AUTHKEY = 'authkey'
@ -36,7 +36,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
# pylint: disable=unused-argument
def get_scanner(hass, config):
"""Validate the configuration and return an snmp scanner."""
"""Validate the configuration and return an SNMP scanner."""
scanner = SnmpScanner(config[DOMAIN])
return scanner if scanner.success_init else None

View file

@ -32,7 +32,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): vol.Any(
cv.boolean, cv.isfile)
})

View file

@ -21,7 +21,7 @@ from homeassistant.helpers.event import async_track_point_in_utc_time
from homeassistant.helpers.discovery import async_load_platform, async_discover
import homeassistant.util.dt as dt_util
REQUIREMENTS = ['netdisco==1.2.0']
REQUIREMENTS = ['netdisco==1.2.2']
DOMAIN = 'discovery'

View file

@ -15,7 +15,7 @@ from homeassistant.helpers import discovery
from homeassistant.const import CONF_API_KEY
from homeassistant.util import Throttle
REQUIREMENTS = ['python-ecobee-api==0.0.9']
REQUIREMENTS = ['python-ecobee-api==0.0.10']
_CONFIGURING = {}
_LOGGER = logging.getLogger(__name__)

View file

@ -3,10 +3,10 @@
FINGERPRINTS = {
"compatibility.js": "1686167ff210e001f063f5c606b2e74b",
"core.js": "2a7d01e45187c7d4635da05065b5e54e",
"frontend.html": "7e13ce36d3141182a62a5b061e87e77a",
"mdi.html": "89074face5529f5fe6fbae49ecb3e88b",
"frontend.html": "2de1bde3b4a6c6c47dd95504fc098906",
"mdi.html": "2e848b4da029bf73d426d5ba058a088d",
"micromarkdown-js.html": "93b5ec4016f0bba585521cf4d18dec1a",
"panels/ha-panel-config.html": "61f65e75e39368e07441d7d6a4e36ae3",
"panels/ha-panel-config.html": "52e2e1d477bfd6dc3708d65b8337f0af",
"panels/ha-panel-dev-event.html": "d409e7ab537d9fe629126d122345279c",
"panels/ha-panel-dev-info.html": "b0e55eb657fd75f21aba2426ac0cedc0",
"panels/ha-panel-dev-mqtt.html": "94b222b013a98583842de3e72d5888c6",

File diff suppressed because one or more lines are too long

@ -1 +1 @@
Subproject commit a46e6b4cfa24d99011a9755e2588d761d78af152
Subproject commit 3092a4c08473df6b8643221e2740791fc6c8b03d

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -37,7 +37,7 @@
/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */
'use strict';
var precacheConfig = [["/","da6c72cc82251a0456b2e678ebb6795c"],["/frontend/panels/dev-event-d409e7ab537d9fe629126d122345279c.html","936814991f2a5e23d61d29f0d40f81b8"],["/frontend/panels/dev-info-b0e55eb657fd75f21aba2426ac0cedc0.html","1fa953b0224470f70d4e87bbe4dff191"],["/frontend/panels/dev-mqtt-94b222b013a98583842de3e72d5888c6.html","dc3ddfac58397feda97317358f0aecbb"],["/frontend/panels/dev-service-422b2c181ee0713fa31d45a64e605baf.html","ae7d26b1c8c3309fd3c65944f89ea03f"],["/frontend/panels/dev-state-7948d3dba058f31517d880df8ed0e857.html","ff8156bb1a52490fcc07466556fce0e1"],["/frontend/panels/dev-template-928e7b81b9c113b70edc9f4a1d051827.html","312c8313800b44c83bcb8dc2df30c759"],["/frontend/panels/map-565db019147162080c21af962afc097f.html","a1a360042395682335e2f471dddad309"],["/static/compatibility-1686167ff210e001f063f5c606b2e74b.js","6ee7b5e2dd82b510c3bd92f7e215988e"],["/static/core-2a7d01e45187c7d4635da05065b5e54e.js","90a0a8a6a6dd0ca41b16f40e7d23924d"],["/static/frontend-7e13ce36d3141182a62a5b061e87e77a.html","73f53a9b597e1e69e0b3e56f4fc8f020"],["/static/mdi-89074face5529f5fe6fbae49ecb3e88b.html","97754e463f9e56a95c813d4d8e792347"],["static/fonts/roboto/Roboto-Bold.ttf","d329cc8b34667f114a95422aaad1b063"],["static/fonts/roboto/Roboto-Light.ttf","7b5fb88f12bec8143f00e21bc3222124"],["static/fonts/roboto/Roboto-Medium.ttf","fe13e4170719c2fc586501e777bde143"],["static/fonts/roboto/Roboto-Regular.ttf","ac3f799d5bbaf5196fab15ab8de8431c"],["static/icons/favicon-192x192.png","419903b8422586a7e28021bbe9011175"],["static/icons/favicon.ico","04235bda7843ec2fceb1cbe2bc696cf4"],["static/images/card_media_player_bg.png","a34281d1c1835d338a642e90930e61aa"]];
var precacheConfig = [["/","517bbe13d945f188a0896870cd3055d0"],["/frontend/panels/dev-event-d409e7ab537d9fe629126d122345279c.html","936814991f2a5e23d61d29f0d40f81b8"],["/frontend/panels/dev-info-b0e55eb657fd75f21aba2426ac0cedc0.html","1fa953b0224470f70d4e87bbe4dff191"],["/frontend/panels/dev-mqtt-94b222b013a98583842de3e72d5888c6.html","dc3ddfac58397feda97317358f0aecbb"],["/frontend/panels/dev-service-422b2c181ee0713fa31d45a64e605baf.html","ae7d26b1c8c3309fd3c65944f89ea03f"],["/frontend/panels/dev-state-7948d3dba058f31517d880df8ed0e857.html","ff8156bb1a52490fcc07466556fce0e1"],["/frontend/panels/dev-template-928e7b81b9c113b70edc9f4a1d051827.html","312c8313800b44c83bcb8dc2df30c759"],["/frontend/panels/map-565db019147162080c21af962afc097f.html","a1a360042395682335e2f471dddad309"],["/static/compatibility-1686167ff210e001f063f5c606b2e74b.js","6ee7b5e2dd82b510c3bd92f7e215988e"],["/static/core-2a7d01e45187c7d4635da05065b5e54e.js","90a0a8a6a6dd0ca41b16f40e7d23924d"],["/static/frontend-2de1bde3b4a6c6c47dd95504fc098906.html","51faf83c8a2d86529bc76a67fe6b5234"],["/static/mdi-89074face5529f5fe6fbae49ecb3e88b.html","97754e463f9e56a95c813d4d8e792347"],["static/fonts/roboto/Roboto-Bold.ttf","d329cc8b34667f114a95422aaad1b063"],["static/fonts/roboto/Roboto-Light.ttf","7b5fb88f12bec8143f00e21bc3222124"],["static/fonts/roboto/Roboto-Medium.ttf","fe13e4170719c2fc586501e777bde143"],["static/fonts/roboto/Roboto-Regular.ttf","ac3f799d5bbaf5196fab15ab8de8431c"],["static/icons/favicon-192x192.png","419903b8422586a7e28021bbe9011175"],["static/icons/favicon.ico","04235bda7843ec2fceb1cbe2bc696cf4"],["static/images/card_media_player_bg.png","a34281d1c1835d338a642e90930e61aa"]];
var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');

View file

@ -7,6 +7,13 @@
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
@ -20,174 +27,170 @@ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
'use strict';var Jb="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:this;
(function(){function k(){var a=this;this.s={};this.g=document.documentElement;var b=new Ka;b.rules=[];this.h=t.set(this.g,new t(b));this.i=!1;this.b=this.a=null;Kb(function(){a.c()})}function F(){this.customStyles=[];this.enqueued=!1}function Lb(){}function pa(a){this.cache={};this.c=void 0===a?100:a}function p(){}function t(a,b,c,d,e){this.G=a||null;this.b=b||null;this.ra=c||[];this.P=null;this.Z=e||"";this.a=this.B=this.K=null}function r(){}function Ka(){this.end=this.start=0;this.rules=this.parent=
this.previous=null;this.cssText=this.parsedCssText="";this.atRule=!1;this.type=0;this.parsedSelector=this.selector=this.keyframesName=""}function Id(a){function b(b,c){Object.defineProperty(b,"innerHTML",{enumerable:c.enumerable,configurable:!0,get:c.get,set:function(b){var d=this,e=void 0;n(this)&&(e=[],P(this,function(a){a!==d&&e.push(a)}));c.set.call(this,b);if(e)for(var f=0;f<e.length;f++){var g=e[f];1===g.__CE_state&&a.disconnectedCallback(g)}this.ownerDocument.__CE_hasRegistry?a.f(this):a.l(this);
return b}})}function c(b,c){u(b,"insertAdjacentElement",function(b,d){var e=n(d);b=c.call(this,b,d);e&&a.a(d);n(b)&&a.b(d);return b})}Mb?u(Element.prototype,"attachShadow",function(a){return this.__CE_shadowRoot=a=Mb.call(this,a)}):console.warn("Custom Elements: `Element#attachShadow` was not patched.");if(La&&La.get)b(Element.prototype,La);else if(Ma&&Ma.get)b(HTMLElement.prototype,Ma);else{var d=Na.call(document,"div");a.v(function(a){b(a,{enumerable:!0,configurable:!0,get:function(){return Nb.call(this,
!0).innerHTML},set:function(a){var b="template"===this.localName?this.content:this;for(d.innerHTML=a;0<b.childNodes.length;)Oa.call(b,b.childNodes[0]);for(;0<d.childNodes.length;)qa.call(b,d.childNodes[0])}})})}u(Element.prototype,"setAttribute",function(b,c){if(1!==this.__CE_state)return Ob.call(this,b,c);var d=Pa.call(this,b);Ob.call(this,b,c);c=Pa.call(this,b);a.attributeChangedCallback(this,b,d,c,null)});u(Element.prototype,"setAttributeNS",function(b,c,d){if(1!==this.__CE_state)return Pb.call(this,
b,c,d);var e=ra.call(this,b,c);Pb.call(this,b,c,d);d=ra.call(this,b,c);a.attributeChangedCallback(this,c,e,d,b)});u(Element.prototype,"removeAttribute",function(b){if(1!==this.__CE_state)return Qb.call(this,b);var c=Pa.call(this,b);Qb.call(this,b);null!==c&&a.attributeChangedCallback(this,b,c,null,null)});u(Element.prototype,"removeAttributeNS",function(b,c){if(1!==this.__CE_state)return Rb.call(this,b,c);var d=ra.call(this,b,c);Rb.call(this,b,c);var e=ra.call(this,b,c);d!==e&&a.attributeChangedCallback(this,
c,d,e,b)});Sb?c(HTMLElement.prototype,Sb):Tb?c(Element.prototype,Tb):console.warn("Custom Elements: `Element#insertAdjacentElement` was not patched.");Ub(a,Element.prototype,{Ka:Jd,append:Kd});Ld(a,{kb:Md,jb:Nd,replaceWith:Od,remove:Pd})}function Ld(a,b){var c=Element.prototype;c.before=function(c){for(var d=[],f=0;f<arguments.length;++f)d[f-0]=arguments[f];f=d.filter(function(a){return a instanceof Node&&n(a)});b.kb.apply(this,d);for(var g=0;g<f.length;g++)a.a(f[g]);if(n(this))for(f=0;f<d.length;f++)g=
d[f],g instanceof Element&&a.b(g)};c.after=function(c){for(var d=[],f=0;f<arguments.length;++f)d[f-0]=arguments[f];f=d.filter(function(a){return a instanceof Node&&n(a)});b.jb.apply(this,d);for(var g=0;g<f.length;g++)a.a(f[g]);if(n(this))for(f=0;f<d.length;f++)g=d[f],g instanceof Element&&a.b(g)};c.replaceWith=function(c){for(var d=[],f=0;f<arguments.length;++f)d[f-0]=arguments[f];f=d.filter(function(a){return a instanceof Node&&n(a)});var g=n(this);b.replaceWith.apply(this,d);for(var h=0;h<f.length;h++)a.a(f[h]);
if(g)for(a.a(this),f=0;f<d.length;f++)g=d[f],g instanceof Element&&a.b(g)};c.remove=function(){var c=n(this);b.remove.call(this);c&&a.a(this)}}function Qd(a){function b(b,d){Object.defineProperty(b,"textContent",{enumerable:d.enumerable,configurable:!0,get:d.get,set:function(b){if(this.nodeType===Node.TEXT_NODE)d.set.call(this,b);else{var c=void 0;if(this.firstChild){var e=this.childNodes,h=e.length;if(0<h&&n(this)){c=Array(h);for(var m=0;m<h;m++)c[m]=e[m]}}d.set.call(this,b);if(c)for(b=0;b<c.length;b++)a.a(c[b])}}})}
u(Node.prototype,"insertBefore",function(b,d){if(b instanceof DocumentFragment){var c=Array.prototype.slice.apply(b.childNodes);b=Vb.call(this,b,d);if(n(this))for(d=0;d<c.length;d++)a.b(c[d]);return b}c=n(b);d=Vb.call(this,b,d);c&&a.a(b);n(this)&&a.b(b);return d});u(Node.prototype,"appendChild",function(b){if(b instanceof DocumentFragment){var c=Array.prototype.slice.apply(b.childNodes);b=qa.call(this,b);if(n(this))for(var e=0;e<c.length;e++)a.b(c[e]);return b}c=n(b);e=qa.call(this,b);c&&a.a(b);n(this)&&
a.b(b);return e});u(Node.prototype,"cloneNode",function(b){b=Nb.call(this,b);this.ownerDocument.__CE_hasRegistry?a.f(b):a.l(b);return b});u(Node.prototype,"removeChild",function(b){var c=n(b),e=Oa.call(this,b);c&&a.a(b);return e});u(Node.prototype,"replaceChild",function(b,d){if(b instanceof DocumentFragment){var c=Array.prototype.slice.apply(b.childNodes);b=Wb.call(this,b,d);if(n(this))for(a.a(d),d=0;d<c.length;d++)a.b(c[d]);return b}c=n(b);var f=Wb.call(this,b,d),g=n(this);g&&a.a(d);c&&a.a(b);g&&
a.b(b);return f});Qa&&Qa.get?b(Node.prototype,Qa):a.v(function(a){b(a,{enumerable:!0,configurable:!0,get:function(){for(var a=[],b=0;b<this.childNodes.length;b++)a.push(this.childNodes[b].textContent);return a.join("")},set:function(a){for(;this.firstChild;)Oa.call(this,this.firstChild);qa.call(this,document.createTextNode(a))}})})}function Rd(a){u(Document.prototype,"createElement",function(b){if(this.__CE_hasRegistry){var c=a.c(b);if(c)return new c.constructor}b=Na.call(this,b);a.g(b);return b});
u(Document.prototype,"importNode",function(b,c){b=Sd.call(this,b,c);this.__CE_hasRegistry?a.f(b):a.l(b);return b});u(Document.prototype,"createElementNS",function(b,c){if(this.__CE_hasRegistry&&(null===b||"http://www.w3.org/1999/xhtml"===b)){var d=a.c(c);if(d)return new d.constructor}b=Td.call(this,b,c);a.g(b);return b});Ub(a,Document.prototype,{Ka:Ud,append:Vd})}function Ub(a,b,c){b.prepend=function(b){for(var d=[],f=0;f<arguments.length;++f)d[f-0]=arguments[f];f=d.filter(function(a){return a instanceof
Node&&n(a)});c.Ka.apply(this,d);for(var g=0;g<f.length;g++)a.a(f[g]);if(n(this))for(f=0;f<d.length;f++)g=d[f],g instanceof Element&&a.b(g)};b.append=function(b){for(var d=[],f=0;f<arguments.length;++f)d[f-0]=arguments[f];f=d.filter(function(a){return a instanceof Node&&n(a)});c.append.apply(this,d);for(var g=0;g<f.length;g++)a.a(f[g]);if(n(this))for(f=0;f<d.length;f++)g=d[f],g instanceof Element&&a.b(g)}}function Wd(a){window.HTMLElement=function(){function b(){var b=this.constructor,d=a.C(b);if(!d)throw Error("The custom element being constructed was not registered with `customElements`.");
var e=d.constructionStack;if(0===e.length)return e=Na.call(document,d.localName),Object.setPrototypeOf(e,b.prototype),e.__CE_state=1,e.__CE_definition=d,a.g(e),e;d=e.length-1;var f=e[d];if(f===Xb)throw Error("The HTMLElement constructor was either called reentrantly for this constructor or called multiple times.");e[d]=Xb;Object.setPrototypeOf(f,b.prototype);a.g(f);return f}b.prototype=Xd.prototype;return b}()}function x(a){this.c=!1;this.a=a;this.h=new Map;this.f=function(a){return a()};this.b=!1;
this.g=[];this.i=new Ra(a,document)}function Yb(){var a=this;this.b=this.a=void 0;this.c=new Promise(function(b){a.b=b;a.a&&b(a.a)})}function Ra(a,b){this.b=a;this.a=b;this.N=void 0;this.b.f(this.a);"loading"===this.a.readyState&&(this.N=new MutationObserver(this.f.bind(this)),this.N.observe(this.a,{childList:!0,subtree:!0}))}function z(){this.u=new Map;this.s=new Map;this.j=[];this.h=!1}function l(a,b,c){if(a!==Zb)throw new TypeError("Illegal constructor");a=document.createDocumentFragment();a.__proto__=
l.prototype;a.D(b,c);return a}function sa(a){if(!a.__shady||void 0===a.__shady.firstChild){a.__shady=a.__shady||{};a.__shady.firstChild=Sa(a);a.__shady.lastChild=Ta(a);$b(a);for(var b=a.__shady.childNodes=U(a),c=0,d;c<b.length&&(d=b[c]);c++)d.__shady=d.__shady||{},d.__shady.parentNode=a,d.__shady.nextSibling=b[c+1]||null,d.__shady.previousSibling=b[c-1]||null,ac(d)}}function Yd(a){var b=a&&a.N;b&&(b.ba.delete(a.ab),b.ba.size||(a.fb.__shady.X=null))}function Zd(a,b){a.__shady=a.__shady||{};a.__shady.X||
(a.__shady.X=new ta);a.__shady.X.ba.add(b);var c=a.__shady.X;return{ab:b,N:c,fb:a,takeRecords:function(){return c.takeRecords()}}}function ta(){this.a=!1;this.addedNodes=[];this.removedNodes=[];this.ba=new Set}function Q(a,b){V[W]=a;V[W+1]=b;W+=2;2===W&&(Ua?Ua(X):$d())}function ae(){return function(){return process.Gb(X)}}function be(){return"undefined"!==typeof Va?function(){Va(X)}:Wa()}function ce(){var a=0,b=new bc(X),c=document.createTextNode("");b.observe(c,{characterData:!0});return function(){c.data=
a=++a%2}}function de(){var a=new MessageChannel;a.port1.onmessage=X;return function(){return a.port2.postMessage(0)}}function Wa(){var a=setTimeout;return function(){return a(X,1)}}function X(){for(var a=0;a<W;a+=2)(0,V[a])(V[a+1]),V[a]=void 0,V[a+1]=void 0;W=0}function ee(){try{var a=require("vertx");Va=a.Ib||a.Hb;return be()}catch(b){return Wa()}}function Xa(a,b){var c=this,d=new this.constructor(Y);void 0===d[ua]&&cc(d);var e=c.o;if(e){var f=arguments[e-1];Q(function(){return dc(e,d,f,c.m)})}else Ya(c,
d,a,b);return d}function Za(a){if(a&&"object"===typeof a&&a.constructor===this)return a;var b=new this(Y);ea(b,a);return b}function Y(){}function ec(a){try{return a.then}catch(b){return fa.error=b,fa}}function fe(a,b,c,d){try{a.call(b,c,d)}catch(e){return e}}function ge(a,b,c){Q(function(a){var d=!1,f=fe(c,b,function(c){d||(d=!0,b!==c?ea(a,c):K(a,c))},function(b){d||(d=!0,A(a,b))});!d&&f&&(d=!0,A(a,f))},a)}function he(a,b){1===b.o?K(a,b.m):2===b.o?A(a,b.m):Ya(b,void 0,function(b){return ea(a,b)},
function(b){return A(a,b)})}function fc(a,b,c){b.constructor===a.constructor&&c===Xa&&b.constructor.resolve===Za?he(a,b):c===fa?(A(a,fa.error),fa.error=null):void 0===c?K(a,b):"function"===typeof c?ge(a,b,c):K(a,b)}function ea(a,b){if(a===b)A(a,new TypeError("You cannot resolve a promise with itself"));else{var c=typeof b;null===b||"object"!==c&&"function"!==c?K(a,b):fc(a,b,ec(b))}}function ie(a){a.Ba&&a.Ba(a.m);$a(a)}function K(a,b){void 0===a.o&&(a.m=b,a.o=1,0!==a.U.length&&Q($a,a))}function A(a,
b){void 0===a.o&&(a.o=2,a.m=b,Q(ie,a))}function Ya(a,b,c,d){var e=a.U,f=e.length;a.Ba=null;e[f]=b;e[f+1]=c;e[f+2]=d;0===f&&a.o&&Q($a,a)}function $a(a){var b=a.U,c=a.o;if(0!==b.length){for(var d,e,f=a.m,g=0;g<b.length;g+=3)d=b[g],e=b[g+c],d?dc(c,d,e,f):e(f);a.U.length=0}}function gc(){this.error=null}function dc(a,b,c,d){var e="function"===typeof c;if(e){try{var f=c(d)}catch(H){ab.error=H,f=ab}if(f===ab){var g=!0;var h=f.error;f.error=null}else var m=!0;if(b===f){A(b,new TypeError("A promises callback cannot return that same promise."));
return}}else f=d,m=!0;void 0===b.o&&(e&&m?ea(b,f):g?A(b,h):1===a?K(b,f):2===a&&A(b,f))}function je(a,b){try{b(function(b){ea(a,b)},function(b){A(a,b)})}catch(c){A(a,c)}}function cc(a){a[ua]=hc++;a.o=void 0;a.m=void 0;a.U=[]}function ha(a,b){this.eb=a;this.J=new a(Y);this.J[ua]||cc(this.J);ic(b)?(this.$=this.length=b.length,this.m=Array(this.length),0===this.length?K(this.J,this.m):(this.length=this.length||0,this.cb(b),0===this.$&&K(this.J,this.m))):A(this.J,Error("Array Methods must be provided an Array"))}
function y(a){this[ua]=hc++;this.m=this.o=void 0;this.U=[];if(Y!==a){if("function"!==typeof a)throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(this instanceof y)je(this,a);else throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");}}function Z(a){return a.__shady&&void 0!==a.__shady.firstChild}function I(a){return"ShadyRoot"===a.Wa}function ia(a){a=a.getRootNode();
if(I(a))return a}function bb(a,b){if(a&&b)for(var c=Object.getOwnPropertyNames(b),d=0,e;d<c.length&&(e=c[d]);d++){var f=Object.getOwnPropertyDescriptor(b,e);f&&Object.defineProperty(a,e,f)}}function cb(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=arguments[d];for(d=0;d<c.length;d++)bb(a,c[d]);return a}function ke(a,b){for(var c in b)a[c]=b[c]}function jc(a){db.push(a);eb.textContent=kc++}function lc(a){fb||(fb=!0,jc(va));ja.push(a)}function va(){fb=!1;for(var a=!!ja.length;ja.length;)ja.shift()();
return a}function le(a,b){var c=b.getRootNode();return a.map(function(a){var b=c===a.target.getRootNode();if(b&&a.addedNodes){if(b=Array.from(a.addedNodes).filter(function(a){return c===a.getRootNode()}),b.length)return a=Object.create(a),Object.defineProperty(a,"addedNodes",{value:b,configurable:!0}),a}else if(b)return a}).filter(function(a){return a})}function mc(a){switch(a){case "&":return"&amp;";case "<":return"&lt;";case ">":return"&gt;";case '"':return"&quot;";case "\u00a0":return"&nbsp;"}}
function nc(a){for(var b={},c=0;c<a.length;c++)b[a[c]]=!0;return b}function gb(a,b){"template"===a.localName&&(a=a.content);for(var c="",d=b?b(a):a.childNodes,e=0,f=d.length,g;e<f&&(g=d[e]);e++){a:{var h=g;var m=a;var H=b;switch(h.nodeType){case Node.ELEMENT_NODE:for(var k=h.localName,l="<"+k,n=h.attributes,p=0;m=n[p];p++)l+=" "+m.name+'="'+m.value.replace(me,mc)+'"';l+=">";h=ne[k]?l:l+gb(h,H)+"</"+k+">";break a;case Node.TEXT_NODE:h=h.data;h=m&&oe[m.localName]?h:h.replace(pe,mc);break a;case Node.COMMENT_NODE:h=
"\x3c!--"+h.data+"--\x3e";break a;default:throw window.console.error(h),Error("not implemented");}}c+=h}return c}function aa(a){B.currentNode=a;return B.parentNode()}function Sa(a){B.currentNode=a;return B.firstChild()}function Ta(a){B.currentNode=a;return B.lastChild()}function oc(a){B.currentNode=a;return B.previousSibling()}function pc(a){B.currentNode=a;return B.nextSibling()}function U(a){var b=[];B.currentNode=a;for(a=B.firstChild();a;)b.push(a),a=B.nextSibling();return b}function qc(a){C.currentNode=
a;return C.parentNode()}function rc(a){C.currentNode=a;return C.firstChild()}function sc(a){C.currentNode=a;return C.lastChild()}function tc(a){C.currentNode=a;return C.previousSibling()}function uc(a){C.currentNode=a;return C.nextSibling()}function vc(a){var b=[];C.currentNode=a;for(a=C.firstChild();a;)b.push(a),a=C.nextSibling();return b}function wc(a){return gb(a,function(a){return U(a)})}function xc(a){switch(a.nodeType){case Node.ELEMENT_NODE:case Node.DOCUMENT_FRAGMENT_NODE:a=document.createTreeWalker(a,
NodeFilter.SHOW_TEXT,null,!1);for(var b="",c;c=a.nextNode();)b+=c.nodeValue;return b;default:return a.nodeValue}}function M(a,b,c){for(var d in b){var e=Object.getOwnPropertyDescriptor(a,d);e&&e.configurable||!e&&c?Object.defineProperty(a,d,b[d]):c&&console.warn("Could not define",d,"on",a)}}function R(a){M(a,yc);M(a,hb);M(a,ib)}function zc(a,b,c){ac(a);c=c||null;a.__shady=a.__shady||{};b.__shady=b.__shady||{};c&&(c.__shady=c.__shady||{});a.__shady.previousSibling=c?c.__shady.previousSibling:b.lastChild;
var d=a.__shady.previousSibling;d&&d.__shady&&(d.__shady.nextSibling=a);(d=a.__shady.nextSibling=c)&&d.__shady&&(d.__shady.previousSibling=a);a.__shady.parentNode=b;c?c===b.__shady.firstChild&&(b.__shady.firstChild=a):(b.__shady.lastChild=a,b.__shady.firstChild||(b.__shady.firstChild=a));b.__shady.childNodes=null}function jb(a,b,c){if(b===a)throw Error("Failed to execute 'appendChild' on 'Node': The new child element contains the parent.");if(c){var d=c.__shady&&c.__shady.parentNode;if(void 0!==d&&
d!==a||void 0===d&&aa(c)!==a)throw Error("Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.");}if(c===b)return b;b.parentNode&&kb(b.parentNode,b);d=ia(a);var e;if(e=d)a:{if(!b.__noInsertionPoint){var f;"slot"===b.localName?f=[b]:b.querySelectorAll&&(f=b.querySelectorAll("slot"));if(f&&f.length){e=f;break a}}e=void 0}f=e;d&&("slot"===a.localName||f)&&d.M();if(Z(a)){e=c;$b(a);a.__shady=a.__shady||{};void 0!==a.__shady.firstChild&&
(a.__shady.childNodes=null);if(b.nodeType===Node.DOCUMENT_FRAGMENT_NODE){for(var g=b.childNodes,h=0;h<g.length;h++)zc(g[h],a,e);b.__shady=b.__shady||{};e=void 0!==b.__shady.firstChild?null:void 0;b.__shady.firstChild=b.__shady.lastChild=e;b.__shady.childNodes=e}else zc(b,a,e);if(lb(a)){a.__shady.root.M();var m=!0}else a.__shady.root&&(m=!0)}m||(m=I(a)?a.host:a,c?(c=Ac(c),mb.call(m,b,c)):Bc.call(m,b));Cc(a,b);f&&d.$a(f);return b}function kb(a,b){if(b.parentNode!==a)throw Error("The node to be removed is not a child of this node: "+
b);var c=ia(b);if(Z(a)){b.__shady=b.__shady||{};a.__shady=a.__shady||{};b===a.__shady.firstChild&&(a.__shady.firstChild=b.__shady.nextSibling);b===a.__shady.lastChild&&(a.__shady.lastChild=b.__shady.previousSibling);var d=b.__shady.previousSibling;var e=b.__shady.nextSibling;d&&(d.__shady=d.__shady||{},d.__shady.nextSibling=e);e&&(e.__shady=e.__shady||{},e.__shady.previousSibling=d);b.__shady.parentNode=b.__shady.previousSibling=b.__shady.nextSibling=void 0;void 0!==a.__shady.childNodes&&(a.__shady.childNodes=
null);if(lb(a)){a.__shady.root.M();var f=!0}}Dc(b);c&&((e=a&&"slot"===a.localName)&&(f=!0),((d=c.gb(b))||e)&&c.M());f||(f=I(a)?a.host:a,(!a.__shady.root&&"slot"!==b.localName||f===aa(b))&&ka.call(f,b));Cc(a,null,b);return b}function Dc(a){if(a.__shady&&void 0!==a.__shady.sa)for(var b=a.childNodes,c=0,d=b.length,e;c<d&&(e=b[c]);c++)Dc(e);a.__shady&&(a.__shady.sa=void 0)}function Ac(a){var b=a;a&&"slot"===a.localName&&(b=(b=a.__shady&&a.__shady.V)&&b.length?b[0]:Ac(a.nextSibling));return b}function lb(a){return(a=
a&&a.__shady&&a.__shady.root)&&a.Aa()}function Ec(a,b){"slot"===b?(a=a.parentNode,lb(a)&&a.__shady.root.M()):"slot"===a.localName&&"name"===b&&(b=ia(a))&&(b.ib(a),b.M())}function Cc(a,b,c){if(a=a.__shady&&a.__shady.X)b&&a.addedNodes.push(b),c&&a.removedNodes.push(c),a.vb()}function Fc(a){if(a&&a.nodeType){a.__shady=a.__shady||{};var b=a.__shady.sa;void 0===b&&(I(a)?b=a:b=(b=a.parentNode)?Fc(b):a,document.documentElement.contains(a)&&(a.__shady.sa=b));return b}}function wa(a,b,c){var d=[];Gc(a.childNodes,
b,c,d);return d}function Gc(a,b,c,d){for(var e=0,f=a.length,g;e<f&&(g=a[e]);e++){var h;if(h=g.nodeType===Node.ELEMENT_NODE){h=g;var m=b,H=c,k=d,l=m(h);l&&k.push(h);H&&H(l)?h=l:(Gc(h.childNodes,m,H,k),h=void 0)}if(h)break}}function Hc(a){a=a.getRootNode();I(a)&&a.Da()}function Ic(a,b,c){xa||(xa=window.ShadyCSS&&window.ShadyCSS.ScopingShim);xa&&"class"===b?xa.setElementClass(a,c):(Jc.call(a,b,c),Ec(a,b))}function Kc(a,b){if(a.ownerDocument!==document)return nb.call(document,a,b);var c=nb.call(document,
a,!1);if(b){a=a.childNodes;b=0;for(var d;b<a.length;b++)d=Kc(a[b],!0),c.appendChild(d)}return c}function ob(a,b){var c=[],d=a;for(a=a===window?window:a.getRootNode();d;)c.push(d),d=d.assignedSlot?d.assignedSlot:d.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&d.host&&(b||d!==a)?d.host:d.parentNode;c[c.length-1]===document&&c.push(window);return c}function Lc(a,b){if(!I)return a;a=ob(a,!0);for(var c=0,d,e,f,g;c<b.length;c++)if(d=b[c],f=d===window?window:d.getRootNode(),f!==e&&(g=a.indexOf(f),e=f),!I(f)||
-1<g)return d}function pb(a){function b(b,d){b=new a(b,d);b.ia=d&&!!d.composed;return b}ke(b,a);b.prototype=a.prototype;return b}function Mc(a,b,c){if(c=b.__handlers&&b.__handlers[a.type]&&b.__handlers[a.type][c])for(var d=0,e;(e=c[d])&&a.target!==a.relatedTarget&&(e.call(b,a),!a.Ua);d++);}function qe(a){var b=a.composedPath();Object.defineProperty(a,"currentTarget",{get:function(){return d},configurable:!0});for(var c=b.length-1;0<=c;c--){var d=b[c];Mc(a,d,"capture");if(a.ja)return}Object.defineProperty(a,
"eventPhase",{get:function(){return Event.AT_TARGET}});var e;for(c=0;c<b.length;c++){d=b[c];var f=d.__shady&&d.__shady.root;if(0===c||f&&f===e)if(Mc(a,d,"bubble"),d!==window&&(e=d.getRootNode()),a.ja)break}}function Nc(a,b,c,d,e,f){for(var g=0;g<a.length;g++){var h=a[g],m=h.type,H=h.capture,k=h.once,l=h.passive;if(b===h.node&&c===m&&d===H&&e===k&&f===l)return g}return-1}function Oc(a,b,c){if(b){if("object"===typeof c){var d=!!c.capture;var e=!!c.once;var f=!!c.passive}else d=!!c,f=e=!1;var g=c&&c.ka||
this,h=b[la];if(h){if(-1<Nc(h,g,a,d,e,f))return}else b[la]=[];h=function(d){e&&this.removeEventListener(a,b,c);d.__target||Pc(d);if(g!==this){var f=Object.getOwnPropertyDescriptor(d,"currentTarget");Object.defineProperty(d,"currentTarget",{get:function(){return g},configurable:!0})}if(d.composed||-1<d.composedPath().indexOf(g))if(d.target===d.relatedTarget)d.eventPhase===Event.BUBBLING_PHASE&&d.stopImmediatePropagation();else if(d.eventPhase===Event.CAPTURING_PHASE||d.bubbles||d.target===g){var h=
"object"===typeof b&&b.handleEvent?b.handleEvent(d):b.call(g,d);g!==this&&(f?(Object.defineProperty(d,"currentTarget",f),f=null):delete d.currentTarget);return h}};b[la].push({node:this,type:a,capture:d,once:e,passive:f,zb:h});qb[a]?(this.__handlers=this.__handlers||{},this.__handlers[a]=this.__handlers[a]||{capture:[],bubble:[]},this.__handlers[a][d?"capture":"bubble"].push(h)):(this instanceof Window?Qc:Rc).call(this,a,h,c)}}function Sc(a,b,c){if(b){if("object"===typeof c){var d=!!c.capture;var e=
!!c.once;var f=!!c.passive}else d=!!c,f=e=!1;var g=c&&c.ka||this,h=void 0;var m=null;try{m=b[la]}catch(H){}m&&(e=Nc(m,g,a,d,e,f),-1<e&&(h=m.splice(e,1)[0].zb,m.length||(b[la]=void 0)));(this instanceof Window?Tc:Uc).call(this,a,h||b,c);h&&qb[a]&&this.__handlers&&this.__handlers[a]&&(a=this.__handlers[a][d?"capture":"bubble"],h=a.indexOf(h),-1<h&&a.splice(h,1))}}function re(){for(var a in qb)window.addEventListener(a,function(a){a.__target||(Pc(a),qe(a))},!0)}function Pc(a){a.__target=a.target;a.ya=
a.relatedTarget;if(D.W){var b=Vc,c=Object.getPrototypeOf(a);if(!c.hasOwnProperty("__patchProto")){var d=Object.create(c);d.Bb=c;bb(d,b);c.__patchProto=d}a.__proto__=c.__patchProto}else bb(a,Vc)}function ma(a,b){return{index:a,Y:[],aa:b}}function se(a,b,c,d){var e=0,f=0,g=0,h=0,m=Math.min(b-e,d-f);if(0==e&&0==f)a:{for(g=0;g<m;g++)if(a[g]!==c[g])break a;g=m}if(b==a.length&&d==c.length){h=a.length;for(var k=c.length,l=0;l<m-g&&te(a[--h],c[--k]);)l++;h=l}e+=g;f+=g;b-=h;d-=h;if(0==b-e&&0==d-f)return[];
if(e==b){for(b=ma(e,0);f<d;)b.Y.push(c[f++]);return[b]}if(f==d)return[ma(e,b-e)];m=e;g=f;d=d-g+1;h=b-m+1;b=Array(d);for(k=0;k<d;k++)b[k]=Array(h),b[k][0]=k;for(k=0;k<h;k++)b[0][k]=k;for(k=1;k<d;k++)for(l=1;l<h;l++)if(a[m+l-1]===c[g+k-1])b[k][l]=b[k-1][l-1];else{var n=b[k-1][l]+1,p=b[k][l-1]+1;b[k][l]=n<p?n:p}m=b.length-1;g=b[0].length-1;d=b[m][g];for(a=[];0<m||0<g;)0==m?(a.push(2),g--):0==g?(a.push(3),m--):(h=b[m-1][g-1],k=b[m-1][g],l=b[m][g-1],n=k<l?k<h?k:h:l<h?l:h,n==h?(h==d?a.push(0):(a.push(1),
d=h),m--,g--):n==k?(a.push(3),m--,d=k):(a.push(2),g--,d=l));a.reverse();b=void 0;m=[];for(g=0;g<a.length;g++)switch(a[g]){case 0:b&&(m.push(b),b=void 0);e++;f++;break;case 1:b||(b=ma(e,0));b.aa++;e++;b.Y.push(c[f]);f++;break;case 2:b||(b=ma(e,0));b.aa++;e++;break;case 3:b||(b=ma(e,0)),b.Y.push(c[f]),f++}b&&m.push(b);return m}function te(a,b){return a===b}function Wc(a){var b=[];do b.unshift(a);while(a=a.parentNode);return b}function Xc(a){Hc(a);return a.__shady&&a.__shady.assignedSlot||null}function N(a,
b){for(var c=Object.getOwnPropertyNames(b),d=0;d<c.length;d++){var e=c[d],f=Object.getOwnPropertyDescriptor(b,e);f.value?a[e]=f.value:Object.defineProperty(a,e,f)}}function ue(){var a=window.customElements&&window.customElements.nativeHTMLElement||HTMLElement;N(window.Node.prototype,ve);N(window.Window.prototype,we);N(window.Text.prototype,xe);N(window.DocumentFragment.prototype,rb);N(window.Element.prototype,Yc);N(window.Document.prototype,Zc);window.HTMLSlotElement&&N(window.HTMLSlotElement.prototype,
$c);N(a.prototype,ye);D.W&&(R(window.Node.prototype),R(window.Text.prototype),R(window.DocumentFragment.prototype),R(window.Element.prototype),R(a.prototype),R(window.Document.prototype),window.HTMLSlotElement&&R(window.HTMLSlotElement.prototype))}function ad(a){var b=ze.has(a);a=/^[a-z][.0-9_a-z]*-[\-.0-9_a-z]*$/.test(a);return!b&&a}function n(a){var b=a.isConnected;if(void 0!==b)return b;for(;a&&!(a.__CE_isImportDocument||a instanceof Document);)a=a.parentNode||(window.ShadowRoot&&a instanceof ShadowRoot?
a.host:void 0);return!(!a||!(a.__CE_isImportDocument||a instanceof Document))}function sb(a,b){for(;b&&b!==a&&!b.nextSibling;)b=b.parentNode;return b&&b!==a?b.nextSibling:null}function P(a,b,c){c=c?c:new Set;for(var d=a;d;){if(d.nodeType===Node.ELEMENT_NODE){var e=d;b(e);var f=e.localName;if("link"===f&&"import"===e.getAttribute("rel")){d=e.import;if(d instanceof Node&&!c.has(d))for(c.add(d),d=d.firstChild;d;d=d.nextSibling)P(d,b,c);d=sb(a,e);continue}else if("template"===f){d=sb(a,e);continue}if(e=
e.__CE_shadowRoot)for(e=e.firstChild;e;e=e.nextSibling)P(e,b,c)}d=d.firstChild?d.firstChild:sb(a,d)}}function u(a,b,c){a[b]=c}function tb(a){a=a.replace(G.mb,"").replace(G.port,"");var b=bd,c=a,d=new Ka;d.start=0;d.end=c.length;for(var e=d,f=0,g=c.length;f<g;f++)if("{"===c[f]){e.rules||(e.rules=[]);var h=e,m=h.rules[h.rules.length-1]||null;e=new Ka;e.start=f+1;e.parent=h;e.previous=m;h.rules.push(e)}else"}"===c[f]&&(e.end=f+1,e=e.parent||d);return b(d,a)}function bd(a,b){var c=b.substring(a.start,
a.end-1);a.parsedCssText=a.cssText=c.trim();a.parent&&(c=b.substring(a.previous?a.previous.end:a.parent.start,a.start-1),c=Ae(c),c=c.replace(G.Ja," "),c=c.substring(c.lastIndexOf(";")+1),c=a.parsedSelector=a.selector=c.trim(),a.atRule=0===c.indexOf("@"),a.atRule?0===c.indexOf("@media")?a.type=L.MEDIA_RULE:c.match(G.rb)&&(a.type=L.ha,a.keyframesName=a.selector.split(G.Ja).pop()):a.type=0===c.indexOf("--")?L.ua:L.STYLE_RULE);if(c=a.rules)for(var d=0,e=c.length,f;d<e&&(f=c[d]);d++)bd(f,b);return a}function Ae(a){return a.replace(/\\([0-9a-f]{1,6})\s/gi,
function(a,c){a=c;for(c=6-a.length;c--;)a="0"+a;return"\\"+a})}function cd(a,b,c){c=void 0===c?"":c;var d="";if(a.cssText||a.rules){var e=a.rules,f;if(f=e)f=e[0],f=!(f&&f.selector&&0===f.selector.indexOf("--"));if(f){f=0;for(var g=e.length,h;f<g&&(h=e[f]);f++)d=cd(h,b,d)}else b?b=a.cssText:(b=a.cssText,b=b.replace(G.Ea,"").replace(G.Ia,""),b=b.replace(G.sb,"").replace(G.xb,"")),(d=b.trim())&&(d=" "+d+"\n")}d&&(a.selector&&(c+=a.selector+" {\n"),c+=d,a.selector&&(c+="}\n\n"));return c}function dd(a){v=
a&&a.shimcssproperties?!1:q||!(navigator.userAgent.match(/AppleWebKit\/601|Edge\/15/)||!window.CSS||!CSS.supports||!CSS.supports("box-shadow","0 0 0 var(--foo)"))}function ba(a,b){if(!a)return"";"string"===typeof a&&(a=tb(a));b&&ca(a,b);return cd(a,v)}function ya(a){!a.__cssRules&&a.textContent&&(a.__cssRules=tb(a.textContent));return a.__cssRules||null}function ed(a){return!!a.parent&&a.parent.type===L.ha}function ca(a,b,c,d){if(a){var e=!1,f=a.type;if(d&&f===L.MEDIA_RULE){var g=a.selector.match(Be);
g&&(window.matchMedia(g[1]).matches||(e=!0))}f===L.STYLE_RULE?b(a):c&&f===L.ha?c(a):f===L.ua&&(e=!0);if((a=a.rules)&&!e){e=0;f=a.length;for(var h;e<f&&(h=a[e]);e++)ca(h,b,c,d)}}}function ub(a,b,c,d){var e=document.createElement("style");b&&e.setAttribute("scope",b);e.textContent=a;fd(e,c,d);return e}function fd(a,b,c){b=b||document.head;b.insertBefore(a,c&&c.nextSibling||b.firstChild);S?a.compareDocumentPosition(S)===Node.DOCUMENT_POSITION_PRECEDING&&(S=a):S=a}function gd(a,b){var c=a.indexOf("var(");
if(-1===c)return b(a,"","","");a:{var d=0;var e=c+3;for(var f=a.length;e<f;e++)if("("===a[e])d++;else if(")"===a[e]&&0===--d)break a;e=-1}d=a.substring(c+4,e);c=a.substring(0,c);a=gd(a.substring(e+1),b);e=d.indexOf(",");return-1===e?b(c,d.trim(),"",a):b(c,d.substring(0,e).trim(),d.substring(e+1).trim(),a)}function za(a,b){q?a.setAttribute("class",b):window.ShadyDOM.nativeMethods.setAttribute.call(a,"class",b)}function T(a){var b=a.localName,c="";b?-1<b.indexOf("-")||(c=b,b=a.getAttribute&&a.getAttribute("is")||
""):(b=a.is,c=a.extends);return{is:b,Z:c}}function hd(a){for(var b=0;b<a.length;b++){var c=a[b];if(c.target!==document.documentElement&&c.target!==document.head)for(var d=0;d<c.addedNodes.length;d++){var e=c.addedNodes[d];if(e.nodeType===Node.ELEMENT_NODE){var f=e.getRootNode();var g=e;var h=[];g.classList?h=Array.from(g.classList):g instanceof window.SVGElement&&g.hasAttribute("class")&&(h=g.getAttribute("class").split(/\s+/));g=h;h=g.indexOf(w.c);(g=-1<h?g[h+1]:"")&&f===e.ownerDocument?w.a(e,g,
!0):f.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&(f=f.host)&&(f=T(f).is,g!==f&&(g&&w.a(e,g,!0),w.a(e,f)))}}}}function Ce(a){if(a=Aa[a])a._applyShimCurrentVersion=a._applyShimCurrentVersion||0,a._applyShimValidatingVersion=a._applyShimValidatingVersion||0,a._applyShimNextVersion=(a._applyShimNextVersion||0)+1}function id(a){return a._applyShimCurrentVersion===a._applyShimNextVersion}function De(a){a._applyShimValidatingVersion=a._applyShimNextVersion;a.b||(a.b=!0,Ee.then(function(){a._applyShimCurrentVersion=
a._applyShimNextVersion;a.b=!1}))}function Kb(a){requestAnimationFrame(function(){jd?jd(a):(vb||(vb=new Promise(function(a){wb=a}),"complete"===document.readyState?wb():document.addEventListener("readystatechange",function(){"complete"===document.readyState&&wb()})),vb.then(function(){a&&a()}))})}(function(){if(!function(){var a=document.createEvent("Event");a.initEvent("foo",!0,!0);a.preventDefault();return a.defaultPrevented}()){var a=Event.prototype.preventDefault;Event.prototype.preventDefault=
function(){this.cancelable&&(a.call(this),Object.defineProperty(this,"defaultPrevented",{get:function(){return!0},configurable:!0}))}}var b=/Trident/.test(navigator.userAgent);if(!window.CustomEvent||b&&"function"!==typeof window.CustomEvent)window.CustomEvent=function(a,b){b=b||{};var c=document.createEvent("CustomEvent");c.initCustomEvent(a,!!b.bubbles,!!b.cancelable,b.detail);return c},window.CustomEvent.prototype=window.Event.prototype;if(!window.Event||b&&"function"!==typeof window.Event){var c=
window.Event;window.Event=function(a,b){b=b||{};var c=document.createEvent("Event");c.initEvent(a,!!b.bubbles,!!b.cancelable);return c};if(c)for(var d in c)window.Event[d]=c[d];window.Event.prototype=c.prototype}if(!window.MouseEvent||b&&"function"!==typeof window.MouseEvent){b=window.MouseEvent;window.MouseEvent=function(a,b){b=b||{};var c=document.createEvent("MouseEvent");c.initMouseEvent(a,!!b.bubbles,!!b.cancelable,b.view||window,b.detail,b.screenX,b.screenY,b.clientX,b.clientY,b.ctrlKey,b.altKey,
b.shiftKey,b.metaKey,b.button,b.relatedTarget);return c};if(b)for(d in b)window.MouseEvent[d]=b[d];window.MouseEvent.prototype=b.prototype}Array.from||(Array.from=function(a){return[].slice.call(a)});Object.assign||(Object.assign=function(a,b){for(var c=[].slice.call(arguments,1),d=0,e;d<c.length;d++)if(e=c[d])for(var f=a,k=e,l=Object.getOwnPropertyNames(k),n=0;n<l.length;n++)e=l[n],f[e]=k[e];return a})})(window.WebComponents);(function(){function a(){}var b="undefined"===typeof HTMLTemplateElement;
/Trident/.test(navigator.userAgent)&&function(){var a=Document.prototype.importNode;Document.prototype.importNode=function(){var b=a.apply(this,arguments);if(b.nodeType===Node.DOCUMENT_FRAGMENT_NODE){var c=this.createDocumentFragment();c.appendChild(b);return c}return b}}();var c=Node.prototype.cloneNode,d=Document.prototype.createElement,e=Document.prototype.importNode,f=function(){if(!b){var a=document.createElement("template"),c=document.createElement("template");c.content.appendChild(document.createElement("div"));
a.content.appendChild(c);a=a.cloneNode(!0);return 0===a.content.childNodes.length||0===a.content.firstChild.content.childNodes.length||!(document.createDocumentFragment().cloneNode()instanceof DocumentFragment)}}();if(b){var g=function(a){switch(a){case "&":return"&amp;";case "<":return"&lt;";case ">":return"&gt;";case "\u00a0":return"&nbsp;"}},h=function(b){Object.defineProperty(b,"innerHTML",{get:function(){for(var a="",b=this.content.firstChild;b;b=b.nextSibling)a+=b.outerHTML||b.data.replace(r,
g);return a},set:function(b){m.body.innerHTML=b;for(a.b(m);this.content.firstChild;)this.content.removeChild(this.content.firstChild);for(;m.body.firstChild;)this.content.appendChild(m.body.firstChild)},configurable:!0})},m=document.implementation.createHTMLDocument("template"),k=!0,l=document.createElement("style");l.textContent="template{display:none;}";var n=document.head;n.insertBefore(l,n.firstElementChild);a.prototype=Object.create(HTMLElement.prototype);var p=!document.createElement("div").hasOwnProperty("innerHTML");
a.O=function(b){if(!b.content){b.content=m.createDocumentFragment();for(var c;c=b.firstChild;)b.content.appendChild(c);if(p)b.__proto__=a.prototype;else if(b.cloneNode=function(b){return a.a(this,b)},k)try{h(b)}catch(df){k=!1}a.b(b.content)}};h(a.prototype);a.b=function(b){b=b.querySelectorAll("template");for(var c=0,d=b.length,e;c<d&&(e=b[c]);c++)a.O(e)};document.addEventListener("DOMContentLoaded",function(){a.b(document)});Document.prototype.createElement=function(){var b=d.apply(this,arguments);
"template"===b.localName&&a.O(b);return b};var r=/[&\u00A0<>]/g}if(b||f)a.a=function(a,b){var d=c.call(a,!1);this.O&&this.O(d);b&&(d.content.appendChild(c.call(a.content,!0)),this.qa(d.content,a.content));return d},a.prototype.cloneNode=function(b){return a.a(this,b)},a.qa=function(a,b){if(b.querySelectorAll){b=b.querySelectorAll("template");a=a.querySelectorAll("template");for(var c=0,d=a.length,e,f;c<d;c++)f=b[c],e=a[c],this.O&&this.O(f),e.parentNode.replaceChild(f.cloneNode(!0),e)}},Node.prototype.cloneNode=
function(b){if(this instanceof DocumentFragment)if(b)var d=this.ownerDocument.importNode(this,!0);else return this.ownerDocument.createDocumentFragment();else d=c.call(this,b);b&&a.qa(d,this);return d},Document.prototype.importNode=function(b,c){if("template"===b.localName)return a.a(b,c);var d=e.call(this,b,c);c&&a.qa(d,b);return d},f&&(window.HTMLTemplateElement.prototype.cloneNode=function(b){return a.a(this,b)});b&&(window.HTMLTemplateElement=a)})();var xb;Array.isArray?xb=Array.isArray:xb=function(a){return"[object Array]"===
Object.prototype.toString.call(a)};var ic=xb,W=0,Va,Ua,kd="undefined"!==typeof window?window:void 0,ld=kd||{},bc=ld.MutationObserver||ld.WebKitMutationObserver,Fe="undefined"!==typeof Uint8ClampedArray&&"undefined"!==typeof importScripts&&"undefined"!==typeof MessageChannel,V=Array(1E3);var $d="undefined"===typeof self&&"undefined"!==typeof process&&"[object process]"==={}.toString.call(process)?ae():bc?ce():Fe?de():kd||"function"!==typeof require?Wa():ee();var ua=Math.random().toString(36).substring(16),
fa=new gc,ab=new gc,hc=0;ha.prototype.cb=function(a){for(var b=0;void 0===this.o&&b<a.length;b++)this.bb(a[b],b)};ha.prototype.bb=function(a,b){var c=this.eb,d=c.resolve;d===Za?(d=ec(a),d===Xa&&void 0!==a.o?this.na(a.o,b,a.m):"function"!==typeof d?(this.$--,this.m[b]=a):c===y?(c=new c(Y),fc(c,a,d),this.oa(c,b)):this.oa(new c(function(b){return b(a)}),b)):this.oa(d(a),b)};ha.prototype.na=function(a,b,c){var d=this.J;void 0===d.o&&(this.$--,2===a?A(d,c):this.m[b]=c);0===this.$&&K(d,this.m)};ha.prototype.oa=
function(a,b){var c=this;Ya(a,void 0,function(a){return c.na(1,b,a)},function(a){return c.na(2,b,a)})};y.g=function(a){return(new ha(this,a)).J};y.h=function(a){var b=this;return ic(a)?new b(function(c,d){for(var e=a.length,f=0;f<e;f++)b.resolve(a[f]).then(c,d)}):new b(function(a,b){return b(new TypeError("You must pass an array to race."))})};y.resolve=Za;y.i=function(a){var b=new this(Y);A(b,a);return b};y.f=function(a){Ua=a};y.c=function(a){Q=a};y.b=Q;y.prototype={constructor:y,then:Xa};y.a=function(){if("undefined"!==
typeof global)var a=global;else if("undefined"!==typeof self)a=self;else try{a=Function("return this")()}catch(d){throw Error("polyfill failed because global object is unavailable in this environment");}var b=a.Promise;if(b){var c=null;try{c=Object.prototype.toString.call(b.resolve())}catch(d){}if("[object Promise]"===c&&!b.Eb)return}a.Promise=y};y.Promise=y;y.a();(function(a){function b(a,b){if("function"===typeof window.CustomEvent)return new CustomEvent(a,b);var c=document.createEvent("CustomEvent");
c.initCustomEvent(a,!!b.bubbles,!!b.cancelable,b.detail);return c}function c(a){if(l)return a.ownerDocument!==document?a.ownerDocument:null;var b=a.__importDoc;if(!b&&a.parentNode){b=a.parentNode;if("function"===typeof b.closest)b=b.closest("link[rel=import]");else for(;!h(b)&&(b=b.parentNode););a.__importDoc=b}return b}function d(a){var b=document.querySelectorAll("link[rel=import]:not(import-dependency)"),c=b.length;c?k(b,function(b){return g(b,function(){0===--c&&a()})}):a()}function e(a){function b(){"loading"!==
document.readyState&&document.body&&(document.removeEventListener("readystatechange",b),a())}document.addEventListener("readystatechange",b);b()}function f(a){e(function(){return d(function(){return a&&a()})})}function g(a,b){if(a.__loaded)b&&b();else if("script"===a.localName&&!a.src||"style"===a.localName&&!a.firstChild)a.__loaded=!0,b&&b();else{var c=function(d){a.removeEventListener(d.type,c);a.__loaded=!0;b&&b()};a.addEventListener("load",c);x&&"style"===a.localName||a.addEventListener("error",
c)}}function h(a){return a.nodeType===Node.ELEMENT_NODE&&"link"===a.localName&&"import"===a.rel}function m(){var a=this;this.a={};this.b=0;this.f=new MutationObserver(function(b){return a.l(b)});this.f.observe(document.head,{childList:!0,subtree:!0});this.c(document)}function k(a,b,c){var d=a?a.length:0,e=c?-1:1;for(c=c?d-1:0;c<d&&0<=c;c+=e)b(a[c],c)}var l="import"in document.createElement("link"),n=null;!1==="currentScript"in document&&Object.defineProperty(document,"currentScript",{get:function(){return n||
("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null)},configurable:!0});var p=/(^\/)|(^#)|(^[\w-\d]*:)/,r=/(url\()([^)]*)(\))/g,t=/(@import[\s]+(?!url\())([^;]*)(;)/g,w=/(<link[^>]*)(rel=['|"]?stylesheet['|"]?[^>]*>)/g,q={nb:function(a,b){a.href&&a.setAttribute("href",q.ta(a.getAttribute("href"),b));a.src&&a.setAttribute("src",q.ta(a.getAttribute("src"),b));if("style"===a.localName){var c=q.La(a.textContent,b,r);a.textContent=q.La(c,b,t)}},La:function(a,b,c){return a.replace(c,
function(a,c,d,e){a=d.replace(/["']/g,"");b&&(a=q.Ma(a,b));return c+"'"+a+"'"+e})},ta:function(a,b){return a&&p.test(a)?a:q.Ma(a,b)},Ma:function(a,b){if(void 0===q.la){q.la=!1;try{var c=new URL("b","http://a");c.pathname="c%20d";q.la="http://a/c%20d"===c.href}catch(ef){}}if(q.la)return(new URL(a,b)).href;c=q.Za;c||(c=document.implementation.createHTMLDocument("temp"),q.Za=c,c.wa=c.createElement("base"),c.head.appendChild(c.wa),c.va=c.createElement("a"));c.wa.href=b;c.va.href=a;return c.va.href||a}},
y={async:!0,load:function(a,b,c){if(a)if(a.match(/^data:/)){a=a.split(",");var d=a[1];d=-1<a[0].indexOf(";base64")?atob(d):decodeURIComponent(d);b(d)}else{var e=new XMLHttpRequest;e.open("GET",a,y.async);e.onload=function(){var a=e.responseURL||e.getResponseHeader("Location");a&&0===a.indexOf("/")&&(a=(location.origin||location.protocol+"//"+location.host)+a);var d=e.response||e.responseText;304===e.status||0===e.status||200<=e.status&&300>e.status?b(d,a):c(d)};e.send()}else c("error: href must be specified")}},
x=/Trident/.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent);m.prototype.c=function(a){var b=this;a=a.querySelectorAll("link[rel=import]");k(a,function(a){return b.h(a)})};m.prototype.h=function(a){var b=this,c=a.href;if(void 0!==this.a[c]){var d=this.a[c];d&&d.__loaded&&(a.import=d,this.g(a))}else this.b++,this.a[c]="pending",y.load(c,function(a,d){a=b.s(a,d||c);b.a[c]=a;b.b--;b.c(a);b.i()},function(){b.a[c]=null;b.b--;b.i()})};m.prototype.s=function(a,b){if(!a)return document.createDocumentFragment();
x&&(a=a.replace(w,function(a,b,c){return-1===a.indexOf("type=")?b+" type=import-disable "+c:a}));var c=document.createElement("template");c.innerHTML=a;if(c.content)a=c.content;else for(a=document.createDocumentFragment();c.firstChild;)a.appendChild(c.firstChild);if(c=a.querySelector("base"))b=q.ta(c.getAttribute("href"),b),c.removeAttribute("href");c=a.querySelectorAll('link[rel=import], link[rel=stylesheet][href][type=import-disable],\n style:not([type]), link[rel=stylesheet][href]:not([type]),\n script:not([type]), script[type="application/javascript"],\n script[type="text/javascript"]');
var d=0;k(c,function(a){g(a);q.nb(a,b);a.setAttribute("import-dependency","");"script"===a.localName&&!a.src&&a.textContent&&(a.setAttribute("src","data:text/javascript;charset=utf-8,"+encodeURIComponent(a.textContent+("\n//# sourceURL="+b+(d?"-"+d:"")+".js\n"))),a.textContent="",d++)});return a};m.prototype.i=function(){var a=this;if(!this.b){this.f.disconnect();this.flatten(document);var b=!1,c=!1,d=function(){c&&b&&(a.c(document),a.b||(a.f.observe(document.head,{childList:!0,subtree:!0}),a.j()))};
this.v(function(){c=!0;d()});this.u(function(){b=!0;d()})}};m.prototype.flatten=function(a){var b=this;a=a.querySelectorAll("link[rel=import]");k(a,function(a){var c=b.a[a.href];(a.import=c)&&c.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&(b.a[a.href]=a,a.readyState="loading",a.import=a,b.flatten(c),a.appendChild(c))})};m.prototype.u=function(a){function b(e){if(e<d){var f=c[e],h=document.createElement("script");f.removeAttribute("import-dependency");k(f.attributes,function(a){return h.setAttribute(a.name,
a.value)});n=h;f.parentNode.replaceChild(h,f);g(h,function(){n=null;b(e+1)})}else a()}var c=document.querySelectorAll("script[import-dependency]"),d=c.length;b(0)};m.prototype.v=function(a){var b=document.querySelectorAll("style[import-dependency],\n link[rel=stylesheet][import-dependency]"),d=b.length;if(d){var e=x&&!!document.querySelector("link[rel=stylesheet][href][type=import-disable]");k(b,function(b){g(b,function(){b.removeAttribute("import-dependency");0===--d&&a()});if(e&&b.parentNode!==
document.head){var f=document.createElement(b.localName);f.__appliedElement=b;f.setAttribute("type","import-placeholder");b.parentNode.insertBefore(f,b.nextSibling);for(f=c(b);f&&c(f);)f=c(f);f.parentNode!==document.head&&(f=null);document.head.insertBefore(b,f);b.removeAttribute("type")}})}else a()};m.prototype.j=function(){var a=this,b=document.querySelectorAll("link[rel=import]");k(b,function(b){return a.g(b)},!0)};m.prototype.g=function(a){a.__loaded||(a.__loaded=!0,a.import&&(a.import.readyState=
"complete"),a.dispatchEvent(b(a.import?"load":"error",{bubbles:!1,cancelable:!1,detail:void 0})))};m.prototype.l=function(a){var b=this;k(a,function(a){return k(a.addedNodes,function(a){a&&a.nodeType===Node.ELEMENT_NODE&&(h(a)?b.h(a):b.c(a))})})};if(l){var v=document.querySelectorAll("link[rel=import]");k(v,function(a){a.import&&"loading"===a.import.readyState||(a.__loaded=!0)});v=function(a){a=a.target;h(a)&&(a.__loaded=!0)};document.addEventListener("load",v,!0);document.addEventListener("error",
v,!0)}else{var u=Object.getOwnPropertyDescriptor(Node.prototype,"baseURI");Object.defineProperty((!u||u.configurable?Node:Element).prototype,"baseURI",{get:function(){var a=h(this)?this:c(this);return a?a.href:u&&u.get?u.get.call(this):(document.querySelector("base")||window.location).href},configurable:!0,enumerable:!0});e(function(){return new m})}f(function(){return document.dispatchEvent(b("HTMLImportsLoaded",{cancelable:!0,bubbles:!0,detail:void 0}))});a.useNative=l;a.whenReady=f;a.importForElement=
c})(window.HTMLImports=window.HTMLImports||{});window.WebComponents=window.WebComponents||{flags:{}};var md=document.querySelector('script[src*="webcomponents-lite.js"]'),Ge=/wc-(.+)/,E={};if(!E.noOpts){location.search.slice(1).split("&").forEach(function(a){a=a.split("=");var b;a[0]&&(b=a[0].match(Ge))&&(E[b[1]]=a[1]||!0)});if(md)for(var nd=0,Ba;Ba=md.attributes[nd];nd++)"src"!==Ba.name&&(E[Ba.name]=Ba.value||!0);if(E.log&&E.log.split){var He=E.log.split(",");E.log={};He.forEach(function(a){E.log[a]=
!0})}else E.log={}}window.WebComponents.flags=E;var od=E.shadydom;od&&(window.ShadyDOM=window.ShadyDOM||{},window.ShadyDOM.force=od);var pd=E.register||E.ce;pd&&window.customElements&&(window.customElements.forcePolyfill=pd);var D=window.ShadyDOM||{};D.ob=!(!Element.prototype.attachShadow||!Node.prototype.getRootNode);var yb=Object.getOwnPropertyDescriptor(Node.prototype,"firstChild");D.W=!!(yb&&yb.configurable&&yb.get);D.Ha=D.force||!D.ob;var da=Element.prototype,qd=da.matches||da.matchesSelector||
da.mozMatchesSelector||da.msMatchesSelector||da.oMatchesSelector||da.webkitMatchesSelector,eb=document.createTextNode(""),kc=0,db=[];(new MutationObserver(function(){for(;db.length;)try{db.shift()()}catch(a){throw eb.textContent=kc++,a;}})).observe(eb,{characterData:!0});var ja=[],fb;va.list=ja;ta.prototype.vb=function(){var a=this;this.a||(this.a=!0,jc(function(){a.b()}))};ta.prototype.b=function(){if(this.a){this.a=!1;var a=this.takeRecords();a.length&&this.ba.forEach(function(b){b(a)})}};ta.prototype.takeRecords=
function(){if(this.addedNodes.length||this.removedNodes.length){var a=[{addedNodes:this.addedNodes,removedNodes:this.removedNodes}];this.addedNodes=[];this.removedNodes=[];return a}return[]};var Bc=Element.prototype.appendChild,mb=Element.prototype.insertBefore,ka=Element.prototype.removeChild,Jc=Element.prototype.setAttribute,rd=Element.prototype.removeAttribute,zb=Element.prototype.cloneNode,nb=Document.prototype.importNode,Rc=Element.prototype.addEventListener,Uc=Element.prototype.removeEventListener,
Qc=Window.prototype.addEventListener,Tc=Window.prototype.removeEventListener,Ab=Element.prototype.dispatchEvent,Ie=Object.freeze({appendChild:Bc,insertBefore:mb,removeChild:ka,setAttribute:Jc,removeAttribute:rd,cloneNode:zb,importNode:nb,addEventListener:Rc,removeEventListener:Uc,Jb:Qc,Kb:Tc,dispatchEvent:Ab,querySelector:Element.prototype.querySelector,querySelectorAll:Element.prototype.querySelectorAll}),me=/[&\u00A0"]/g,pe=/[&\u00A0<>]/g,ne=nc("area base br col command embed hr img input keygen link meta param source track wbr".split(" ")),
oe=nc("style script xmp iframe noembed noframes plaintext noscript".split(" ")),B=document.createTreeWalker(document,NodeFilter.SHOW_ALL,null,!1),C=document.createTreeWalker(document,NodeFilter.SHOW_ELEMENT,null,!1),Je=Object.freeze({parentNode:aa,firstChild:Sa,lastChild:Ta,previousSibling:oc,nextSibling:pc,childNodes:U,parentElement:qc,firstElementChild:rc,lastElementChild:sc,previousElementSibling:tc,nextElementSibling:uc,children:vc,innerHTML:wc,textContent:xc}),Bb=Object.getOwnPropertyDescriptor(Element.prototype,
"innerHTML")||Object.getOwnPropertyDescriptor(HTMLElement.prototype,"innerHTML"),Ca=document.implementation.createHTMLDocument("inert").createElement("div"),Cb=Object.getOwnPropertyDescriptor(Document.prototype,"activeElement"),yc={parentElement:{get:function(){var a=this.__shady&&this.__shady.parentNode;a&&a.nodeType!==Node.ELEMENT_NODE&&(a=null);return void 0!==a?a:qc(this)},configurable:!0},parentNode:{get:function(){var a=this.__shady&&this.__shady.parentNode;return void 0!==a?a:aa(this)},configurable:!0},
nextSibling:{get:function(){var a=this.__shady&&this.__shady.nextSibling;return void 0!==a?a:pc(this)},configurable:!0},previousSibling:{get:function(){var a=this.__shady&&this.__shady.previousSibling;return void 0!==a?a:oc(this)},configurable:!0},className:{get:function(){return this.getAttribute("class")||""},set:function(a){this.setAttribute("class",a)},configurable:!0},nextElementSibling:{get:function(){if(this.__shady&&void 0!==this.__shady.nextSibling){for(var a=this.nextSibling;a&&a.nodeType!==
Node.ELEMENT_NODE;)a=a.nextSibling;return a}return uc(this)},configurable:!0},previousElementSibling:{get:function(){if(this.__shady&&void 0!==this.__shady.previousSibling){for(var a=this.previousSibling;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}return tc(this)},configurable:!0}},hb={childNodes:{get:function(){if(Z(this)){if(!this.__shady.childNodes){this.__shady.childNodes=[];for(var a=this.firstChild;a;a=a.nextSibling)this.__shady.childNodes.push(a)}var b=this.__shady.childNodes}else b=
U(this);b.item=function(a){return b[a]};return b},configurable:!0},childElementCount:{get:function(){return this.children.length},configurable:!0},firstChild:{get:function(){var a=this.__shady&&this.__shady.firstChild;return void 0!==a?a:Sa(this)},configurable:!0},lastChild:{get:function(){var a=this.__shady&&this.__shady.lastChild;return void 0!==a?a:Ta(this)},configurable:!0},textContent:{get:function(){if(Z(this)){for(var a=[],b=0,c=this.childNodes,d;d=c[b];b++)d.nodeType!==Node.COMMENT_NODE&&
a.push(d.textContent);return a.join("")}return xc(this)},set:function(a){switch(this.nodeType){case Node.ELEMENT_NODE:case Node.DOCUMENT_FRAGMENT_NODE:for(;this.firstChild;)this.removeChild(this.firstChild);(0<a.length||this.nodeType===Node.ELEMENT_NODE)&&this.appendChild(document.createTextNode(a));break;default:this.nodeValue=a}},configurable:!0},firstElementChild:{get:function(){if(this.__shady&&void 0!==this.__shady.firstChild){for(var a=this.firstChild;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.nextSibling;
return a}return rc(this)},configurable:!0},lastElementChild:{get:function(){if(this.__shady&&void 0!==this.__shady.lastChild){for(var a=this.lastChild;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}return sc(this)},configurable:!0},children:{get:function(){var a;Z(this)?a=Array.prototype.filter.call(this.childNodes,function(a){return a.nodeType===Node.ELEMENT_NODE}):a=vc(this);a.item=function(b){return a[b]};return a},configurable:!0},innerHTML:{get:function(){var a="template"===
this.localName?this.content:this;return Z(this)?gb(a):wc(a)},set:function(a){for(var b="template"===this.localName?this.content:this;b.firstChild;)b.removeChild(b.firstChild);for(Bb&&Bb.set?Bb.set.call(Ca,a):Ca.innerHTML=a;Ca.firstChild;)b.appendChild(Ca.firstChild)},configurable:!0}},sd={shadowRoot:{get:function(){return this.__shady&&this.__shady.tb||null},configurable:!0}},ib={activeElement:{get:function(){var a=Cb&&Cb.get?Cb.get.call(document):D.W?void 0:document.activeElement;if(a&&a.nodeType){var b=
!!I(this);if(this===document||b&&this.host!==a&&this.host.contains(a)){for(b=ia(a);b&&b!==this;)a=b.host,b=ia(a);a=this===document?b?null:a:b===this?a:null}else a=null}else a=null;return a},set:function(){},configurable:!0}},ac=D.W?function(){}:function(a){a.__shady&&a.__shady.Xa||(a.__shady=a.__shady||{},a.__shady.Xa=!0,M(a,yc,!0))},$b=D.W?function(){}:function(a){a.__shady&&a.__shady.Va||(a.__shady=a.__shady||{},a.__shady.Va=!0,M(a,hb,!0),M(a,sd,!0))},xa=null,la="__eventWrappers"+Date.now(),Ke=
{blur:!0,focus:!0,focusin:!0,focusout:!0,click:!0,dblclick:!0,mousedown:!0,mouseenter:!0,mouseleave:!0,mousemove:!0,mouseout:!0,mouseover:!0,mouseup:!0,wheel:!0,beforeinput:!0,input:!0,keydown:!0,keyup:!0,compositionstart:!0,compositionupdate:!0,compositionend:!0,touchstart:!0,touchend:!0,touchmove:!0,touchcancel:!0,pointerover:!0,pointerenter:!0,pointerdown:!0,pointermove:!0,pointerup:!0,pointercancel:!0,pointerout:!0,pointerleave:!0,gotpointercapture:!0,lostpointercapture:!0,dragstart:!0,drag:!0,
dragenter:!0,dragleave:!0,dragover:!0,drop:!0,dragend:!0,DOMActivate:!0,DOMFocusIn:!0,DOMFocusOut:!0,keypress:!0},Vc={get composed(){!1!==this.isTrusted&&void 0===this.ia&&(this.ia=Ke[this.type]);return this.ia||!1},composedPath:function(){this.xa||(this.xa=ob(this.__target,this.composed));return this.xa},get target(){return Lc(this.currentTarget,this.composedPath())},get relatedTarget(){if(!this.ya)return null;this.za||(this.za=ob(this.ya,!0));return Lc(this.currentTarget,this.za)},stopPropagation:function(){Event.prototype.stopPropagation.call(this);
this.ja=!0},stopImmediatePropagation:function(){Event.prototype.stopImmediatePropagation.call(this);this.ja=this.Ua=!0}},qb={focus:!0,blur:!0},Le=pb(window.Event),Me=pb(window.CustomEvent),Ne=pb(window.MouseEvent),Zb={};l.prototype=Object.create(DocumentFragment.prototype);l.prototype.D=function(a,b){this.Wa="ShadyRoot";sa(a);sa(this);this.host=a;this.L=b&&b.mode;a.__shady=a.__shady||{};a.__shady.root=this;a.__shady.tb="closed"!==this.L?this:null;this.T=!1;this.b=[];this.a=null;b=U(a);for(var c=0,
d=b.length;c<d;c++)ka.call(a,b[c])};l.prototype.M=function(){var a=this;this.T||(this.T=!0,lc(function(){return a.Da()}))};l.prototype.C=function(){for(var a=this,b=this;b;)b.T&&(a=b),b=b.hb();return a};l.prototype.hb=function(){var a=this.host.getRootNode();if(I(a))for(var b=this.host.childNodes,c=0,d;c<b.length;c++)if(d=b[c],this.h(d))return a};l.prototype.Da=function(){this.T&&this.C()._renderRoot()};l.prototype._renderRoot=function(){this.T=!1;this.v();this.s()};l.prototype.v=function(){for(var a=
0,b;a<this.b.length;a++)b=this.b[a],this.l(b);for(b=this.host.firstChild;b;b=b.nextSibling)this.f(b);for(a=0;a<this.b.length;a++){b=this.b[a];if(!b.__shady.assignedNodes.length)for(var c=b.firstChild;c;c=c.nextSibling)this.f(c,b);c=b.parentNode;(c=c.__shady&&c.__shady.root)&&c.Aa()&&c._renderRoot();this.c(b.__shady.V,b.__shady.assignedNodes);if(c=b.__shady.Ca){for(var d=0;d<c.length;d++)c[d].__shady.ma=null;b.__shady.Ca=null;c.length>b.__shady.assignedNodes.length&&(b.__shady.pa=!0)}b.__shady.pa&&
(b.__shady.pa=!1,this.g(b))}};l.prototype.f=function(a,b){a.__shady=a.__shady||{};var c=a.__shady.ma;a.__shady.ma=null;b||(b=(b=this.a[a.slot||"__catchall"])&&b[0]);b?(b.__shady.assignedNodes.push(a),a.__shady.assignedSlot=b):a.__shady.assignedSlot=void 0;c!==a.__shady.assignedSlot&&a.__shady.assignedSlot&&(a.__shady.assignedSlot.__shady.pa=!0)};l.prototype.l=function(a){var b=a.__shady.assignedNodes;a.__shady.assignedNodes=[];a.__shady.V=[];if(a.__shady.Ca=b)for(var c=0;c<b.length;c++){var d=b[c];
d.__shady.ma=d.__shady.assignedSlot;d.__shady.assignedSlot===a&&(d.__shady.assignedSlot=null)}};l.prototype.c=function(a,b){for(var c=0,d;c<b.length&&(d=b[c]);c++)"slot"==d.localName?this.c(a,d.__shady.assignedNodes):a.push(b[c])};l.prototype.g=function(a){Ab.call(a,new Event("slotchange"));a.__shady.assignedSlot&&this.g(a.__shady.assignedSlot)};l.prototype.s=function(){for(var a=this.b,b=[],c=0;c<a.length;c++){var d=a[c].parentNode;d.__shady&&d.__shady.root||!(0>b.indexOf(d))||b.push(d)}for(a=0;a<
b.length;a++)c=b[a],this.I(c===this?this.host:c,this.u(c))};l.prototype.u=function(a){var b=[];a=a.childNodes;for(var c=0;c<a.length;c++){var d=a[c];if(this.h(d)){d=d.__shady.V;for(var e=0;e<d.length;e++)b.push(d[e])}else b.push(d)}return b};l.prototype.h=function(a){return"slot"==a.localName};l.prototype.I=function(a,b){for(var c=U(a),d=se(b,b.length,c,c.length),e=0,f=0,g;e<d.length&&(g=d[e]);e++){for(var h=0,k;h<g.Y.length&&(k=g.Y[h]);h++)aa(k)===a&&ka.call(a,k),c.splice(g.index+f,1);f-=g.aa}for(e=
0;e<d.length&&(g=d[e]);e++)for(f=c[g.index],h=g.index;h<g.index+g.aa;h++)k=b[h],mb.call(a,k,f),c.splice(h,0,k)};l.prototype.$a=function(a){this.a=this.a||{};this.b=this.b||[];for(var b=0;b<a.length;b++){var c=a[b];c.__shady=c.__shady||{};sa(c);sa(c.parentNode);var d=this.i(c);if(this.a[d]){var e=e||{};e[d]=!0;this.a[d].push(c)}else this.a[d]=[c];this.b.push(c)}if(e)for(var f in e)this.a[f]=this.j(this.a[f])};l.prototype.i=function(a){var b=a.name||a.getAttribute("name")||"__catchall";return a.Ya=
b};l.prototype.j=function(a){return a.sort(function(a,c){a=Wc(a);for(var b=Wc(c),e=0;e<a.length;e++){c=a[e];var f=b[e];if(c!==f)return a=Array.from(c.parentNode.childNodes),a.indexOf(c)-a.indexOf(f)}})};l.prototype.gb=function(a){this.a=this.a||{};this.b=this.b||[];var b=this.a,c;for(c in b)for(var d=b[c],e=0;e<d.length;e++){var f=d[e],g;a:{for(g=f;g;){if(g==a){g=!0;break a}g=g.parentNode}g=void 0}if(g){d.splice(e,1);var h=this.b.indexOf(f);0<=h&&this.b.splice(h,1);e--;this.H(f);h=!0}}return h};l.prototype.ib=
function(a){var b=a.Ya,c=this.i(a);if(c!==b){b=this.a[b];var d=b.indexOf(a);0<=d&&b.splice(d,1);b=this.a[c]||(this.a[c]=[]);b.push(a);1<b.length&&(this.a[c]=this.j(b))}};l.prototype.H=function(a){if(a=a.__shady.V)for(var b=0;b<a.length;b++){var c=a[b],d=aa(c);d&&ka.call(d,c)}};l.prototype.Aa=function(){return!!this.b.length};l.prototype.addEventListener=function(a,b,c){"object"!==typeof c&&(c={capture:!!c});c.ka=this;this.host.addEventListener(a,b,c)};l.prototype.removeEventListener=function(a,b,
c){"object"!==typeof c&&(c={capture:!!c});c.ka=this;this.host.removeEventListener(a,b,c)};l.prototype.getElementById=function(a){return wa(this,function(b){return b.id==a},function(a){return!!a})[0]||null};(function(a){M(a,hb,!0);M(a,ib,!0)})(l.prototype);var we={addEventListener:Oc.bind(window),removeEventListener:Sc.bind(window)},ve={addEventListener:Oc,removeEventListener:Sc,appendChild:function(a){return jb(this,a)},insertBefore:function(a,b){return jb(this,a,b)},removeChild:function(a){return kb(this,
a)},replaceChild:function(a,b){jb(this,a,b);kb(this,b);return a},cloneNode:function(a){if("template"==this.localName)var b=zb.call(this,a);else if(b=zb.call(this,!1),a){a=this.childNodes;for(var c=0,d;c<a.length;c++)d=a[c].cloneNode(!0),b.appendChild(d)}return b},getRootNode:function(){return Fc(this)},get isConnected(){var a=this.ownerDocument;if(a&&a.contains&&a.contains(this)||(a=a.documentElement)&&a.contains&&a.contains(this))return!0;for(a=this;a&&!(a instanceof Document);)a=a.parentNode||(a instanceof
l?a.host:void 0);return!!(a&&a instanceof Document)},dispatchEvent:function(a){va();return Ab.call(this,a)}},xe={get assignedSlot(){return Xc(this)}},rb={querySelector:function(a){return wa(this,function(b){return qd.call(b,a)},function(a){return!!a})[0]||null},querySelectorAll:function(a){return wa(this,function(b){return qd.call(b,a)})}},$c={assignedNodes:function(a){if("slot"===this.localName)return Hc(this),this.__shady?(a&&a.flatten?this.__shady.V:this.__shady.assignedNodes)||[]:[]}},Yc=cb({setAttribute:function(a,
b){Ic(this,a,b)},removeAttribute:function(a){rd.call(this,a);Ec(this,a)},attachShadow:function(a){if(!this)throw"Must provide a host.";if(!a)throw"Not enough arguments.";return new l(Zb,this,a)},get slot(){return this.getAttribute("slot")},set slot(a){Ic(this,"slot",a)},get assignedSlot(){return Xc(this)}},rb,$c);Object.defineProperties(Yc,sd);var Zc=cb({importNode:function(a,b){return Kc(a,b)},getElementById:function(a){return wa(this,function(b){return b.id==a},function(a){return!!a})[0]||null}},
rb);Object.defineProperties(Zc,{_activeElement:ib.activeElement});var Oe=HTMLElement.prototype.blur,ye=cb({blur:function(){var a=this.__shady&&this.__shady.root;(a=a&&a.activeElement)?a.blur():Oe.call(this)}});D.Ha&&(window.ShadyDOM={inUse:D.Ha,patch:function(a){return a},isShadyRoot:I,enqueue:lc,flush:va,settings:D,filterMutations:le,observeChildren:Zd,unobserveChildren:Yd,nativeMethods:Ie,nativeTree:Je},window.Event=Le,window.CustomEvent=Me,window.MouseEvent=Ne,re(),ue(),window.ShadowRoot=l);var ze=
new Set("annotation-xml color-profile font-face font-face-src font-face-uri font-face-format font-face-name missing-glyph".split(" "));z.prototype.D=function(a,b){this.u.set(a,b);this.s.set(b.constructor,b)};z.prototype.c=function(a){return this.u.get(a)};z.prototype.C=function(a){return this.s.get(a)};z.prototype.v=function(a){this.h=!0;this.j.push(a)};z.prototype.l=function(a){var b=this;this.h&&P(a,function(a){return b.g(a)})};z.prototype.g=function(a){if(this.h&&!a.__CE_patched){a.__CE_patched=
!0;for(var b=0;b<this.j.length;b++)this.j[b](a)}};z.prototype.b=function(a){var b=[];P(a,function(a){return b.push(a)});for(a=0;a<b.length;a++){var c=b[a];1===c.__CE_state?this.connectedCallback(c):this.i(c)}};z.prototype.a=function(a){var b=[];P(a,function(a){return b.push(a)});for(a=0;a<b.length;a++){var c=b[a];1===c.__CE_state&&this.disconnectedCallback(c)}};z.prototype.f=function(a,b){var c=this;b=b?b:{};var d=b.yb||new Set,e=b.Na||function(a){return c.i(a)},f=[];P(a,function(a){if("link"===a.localName&&
"import"===a.getAttribute("rel")){var b=a.import;b instanceof Node&&"complete"===b.readyState?(b.__CE_isImportDocument=!0,b.__CE_hasRegistry=!0):a.addEventListener("load",function(){var b=a.import;b.__CE_documentLoadHandled||(b.__CE_documentLoadHandled=!0,b.__CE_isImportDocument=!0,b.__CE_hasRegistry=!0,d.delete(b),c.f(b,{yb:d,Na:e}))})}else f.push(a)},d);if(this.h)for(a=0;a<f.length;a++)this.g(f[a]);for(a=0;a<f.length;a++)e(f[a])};z.prototype.i=function(a){if(void 0===a.__CE_state){var b=this.c(a.localName);
if(b){b.constructionStack.push(a);var c=b.constructor;try{try{if(new c!==a)throw Error("The custom element constructor did not produce the element being upgraded.");}finally{b.constructionStack.pop()}}catch(f){throw a.__CE_state=2,f;}a.__CE_state=1;a.__CE_definition=b;if(b.attributeChangedCallback)for(b=b.observedAttributes,c=0;c<b.length;c++){var d=b[c],e=a.getAttribute(d);null!==e&&this.attributeChangedCallback(a,d,null,e,null)}n(a)&&this.connectedCallback(a)}}};z.prototype.connectedCallback=function(a){var b=
a.__CE_definition;b.connectedCallback&&b.connectedCallback.call(a)};z.prototype.disconnectedCallback=function(a){var b=a.__CE_definition;b.disconnectedCallback&&b.disconnectedCallback.call(a)};z.prototype.attributeChangedCallback=function(a,b,c,d,e){var f=a.__CE_definition;f.attributeChangedCallback&&-1<f.observedAttributes.indexOf(b)&&f.attributeChangedCallback.call(a,b,c,d,e)};Ra.prototype.c=function(){this.N&&this.N.disconnect()};Ra.prototype.f=function(a){var b=this.a.readyState;"interactive"!==
b&&"complete"!==b||this.c();for(b=0;b<a.length;b++)for(var c=a[b].addedNodes,d=0;d<c.length;d++)this.b.f(c[d])};Yb.prototype.resolve=function(a){if(this.a)throw Error("Already resolved.");this.a=a;this.b&&this.b(a)};x.prototype.define=function(a,b){var c=this;if(!(b instanceof Function))throw new TypeError("Custom element constructors must be functions.");if(!ad(a))throw new SyntaxError("The element name '"+a+"' is not valid.");if(this.a.c(a))throw Error("A custom element with name '"+a+"' has already been defined.");
if(this.c)throw Error("A custom element is already being defined.");this.c=!0;try{var d=function(a){var b=e[a];if(void 0!==b&&!(b instanceof Function))throw Error("The '"+a+"' callback must be a function.");return b},e=b.prototype;if(!(e instanceof Object))throw new TypeError("The custom element constructor's prototype is not an object.");var f=d("connectedCallback");var g=d("disconnectedCallback");var h=d("adoptedCallback");var k=d("attributeChangedCallback");var l=b.observedAttributes||[]}catch(cf){return}finally{this.c=
!1}b={localName:a,constructor:b,connectedCallback:f,disconnectedCallback:g,adoptedCallback:h,attributeChangedCallback:k,observedAttributes:l,constructionStack:[]};this.a.D(a,b);this.g.push(b);this.b||(this.b=!0,this.f(function(){return c.j()}))};x.prototype.j=function(){var a=this;if(!1!==this.b){this.b=!1;for(var b=this.g,c=[],d=new Map,e=0;e<b.length;e++)d.set(b[e].localName,[]);this.a.f(document,{Na:function(b){if(void 0===b.__CE_state){var e=b.localName,f=d.get(e);f?f.push(b):a.a.c(e)&&c.push(b)}}});
for(e=0;e<c.length;e++)this.a.i(c[e]);for(;0<b.length;){var f=b.shift();e=f.localName;f=d.get(f.localName);for(var g=0;g<f.length;g++)this.a.i(f[g]);(e=this.h.get(e))&&e.resolve(void 0)}}};x.prototype.get=function(a){if(a=this.a.c(a))return a.constructor};x.prototype.whenDefined=function(a){if(!ad(a))return Promise.reject(new SyntaxError("'"+a+"' is not a valid custom element name."));var b=this.h.get(a);if(b)return b.c;b=new Yb;this.h.set(a,b);this.a.c(a)&&!this.g.some(function(b){return b.localName===
a})&&b.resolve(void 0);return b.c};x.prototype.l=function(a){this.i.c();var b=this.f;this.f=function(c){return a(function(){return b(c)})}};window.CustomElementRegistry=x;x.prototype.define=x.prototype.define;x.prototype.get=x.prototype.get;x.prototype.whenDefined=x.prototype.whenDefined;x.prototype.polyfillWrapFlushCallback=x.prototype.l;var Na=window.Document.prototype.createElement,Td=window.Document.prototype.createElementNS,Sd=window.Document.prototype.importNode,Ud=window.Document.prototype.prepend,
Vd=window.Document.prototype.append,Nb=window.Node.prototype.cloneNode,qa=window.Node.prototype.appendChild,Vb=window.Node.prototype.insertBefore,Oa=window.Node.prototype.removeChild,Wb=window.Node.prototype.replaceChild,Qa=Object.getOwnPropertyDescriptor(window.Node.prototype,"textContent"),Mb=window.Element.prototype.attachShadow,La=Object.getOwnPropertyDescriptor(window.Element.prototype,"innerHTML"),Pa=window.Element.prototype.getAttribute,Ob=window.Element.prototype.setAttribute,Qb=window.Element.prototype.removeAttribute,
ra=window.Element.prototype.getAttributeNS,Pb=window.Element.prototype.setAttributeNS,Rb=window.Element.prototype.removeAttributeNS,Tb=window.Element.prototype.insertAdjacentElement,Jd=window.Element.prototype.prepend,Kd=window.Element.prototype.append,Md=window.Element.prototype.before,Nd=window.Element.prototype.after,Od=window.Element.prototype.replaceWith,Pd=window.Element.prototype.remove,Xd=window.HTMLElement,Ma=Object.getOwnPropertyDescriptor(window.HTMLElement.prototype,"innerHTML"),Sb=window.HTMLElement.prototype.insertAdjacentElement,
Xb=new function(){},Da=window.customElements;if(!Da||Da.forcePolyfill||"function"!=typeof Da.define||"function"!=typeof Da.get){var na=new z;Wd(na);Rd(na);Qd(na);Id(na);document.__CE_hasRegistry=!0;var Pe=new x(na);Object.defineProperty(window,"customElements",{configurable:!0,enumerable:!0,value:Pe})}var L={STYLE_RULE:1,ha:7,MEDIA_RULE:4,ua:1E3},G={mb:/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,port:/@import[^;]*;/gim,Ea:/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\n]|$)/gim,Ia:/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\n]|$)?/gim,
sb:/@apply\s*\(?[^);]*\)?\s*(?:[;\n]|$)?/gim,xb:/[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim,rb:/^@[^\s]*keyframes/,Ja:/\s+/g},q=!(window.ShadyDOM&&window.ShadyDOM.inUse);if(window.ShadyCSS&&void 0!==window.ShadyCSS.nativeCss)var v=window.ShadyCSS.nativeCss;else window.ShadyCSS?(dd(window.ShadyCSS),window.ShadyCSS=void 0):dd(window.WebComponents&&window.WebComponents.flags);var Ea=/(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};{])+)|\{([^}]*)\}(?:(?=[;\s}])|$))/gi,
Fa=/(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi,Qe=/(--[\w-]+)\s*([:,;)]|$)/gi,Re=/(animation\s*:)|(animation-name\s*:)/,Be=/@media\s(.*)/,Se=/\{[^}]*\}/g,S=null;r.prototype.a=function(a,b,c){a.__styleScoped?a.__styleScoped=null:this.i(a,b||"",c)};r.prototype.i=function(a,b,c){a.nodeType===Node.ELEMENT_NODE&&this.C(a,b,c);if(a="template"===a.localName?(a.content||a.Cb).childNodes:a.children||a.childNodes)for(var d=0;d<a.length;d++)this.i(a[d],b,c)};r.prototype.C=function(a,b,c){if(b)if(a.classList)c?(a.classList.remove("style-scope"),
a.classList.remove(b)):(a.classList.add("style-scope"),a.classList.add(b));else if(a.getAttribute){var d=a.getAttribute(Te);c?d&&(b=d.replace("style-scope","").replace(b,""),za(a,b)):za(a,(d?d+" ":"")+"style-scope "+b)}};r.prototype.b=function(a,b,c){var d=a.__cssBuild;q||"shady"===d?b=ba(b,c):(a=T(a),b=this.I(b,a.is,a.Z,c)+"\n\n");return b.trim()};r.prototype.I=function(a,b,c,d){var e=this.f(b,c);b=this.h(b);var f=this;return ba(a,function(a){a.c||(f.S(a,b,e),a.c=!0);d&&d(a,b,e)})};r.prototype.h=
function(a){return a?Ue+a:""};r.prototype.f=function(a,b){return b?"[is="+a+"]":a};r.prototype.S=function(a,b,c){this.j(a,this.g,b,c)};r.prototype.j=function(a,b,c,d){a.selector=a.A=this.l(a,b,c,d)};r.prototype.l=function(a,b,c,d){var e=a.selector.split(td);if(!ed(a)){a=0;for(var f=e.length,g;a<f&&(g=e[a]);a++)e[a]=b.call(this,g,c,d)}return e.join(td)};r.prototype.u=function(a){return a.replace(Db,function(a,c,d){-1<d.indexOf("+")?d=d.replace(/\+/g,"___"):-1<d.indexOf("___")&&(d=d.replace(/___/g,
"+"));return":"+c+"("+d+")"})};r.prototype.g=function(a,b,c){var d=this,e=!1;a=a.trim();var f=Db.test(a);f&&(a=a.replace(Db,function(a,b,c){return":"+b+"("+c.replace(/\s/g,"")+")"}),a=this.u(a));a=a.replace(Ve,Eb+" $1");a=a.replace(We,function(a,f,k){e||(a=d.D(k,f,b,c),e=e||a.stop,f=a.lb,k=a.value);return f+k});f&&(a=this.u(a));return a};r.prototype.D=function(a,b,c,d){var e=a.indexOf(Fb);0<=a.indexOf(Eb)?a=this.H(a,d):0!==e&&(a=c?this.s(a,c):a);c=!1;0<=e&&(b="",c=!0);if(c){var f=!0;c&&(a=a.replace(Xe,
function(a,b){return" > "+b}))}a=a.replace(Ye,function(a,b,c){return'[dir="'+c+'"] '+b+", "+b+'[dir="'+c+'"]'});return{value:a,lb:b,stop:f}};r.prototype.s=function(a,b){a=a.split(ud);a[0]+=b;return a.join(ud)};r.prototype.H=function(a,b){var c=a.match(vd);return(c=c&&c[2].trim()||"")?c[0].match(wd)?a.replace(vd,function(a,c,f){return b+f}):c.split(wd)[0]===b?c:Ze:a.replace(Eb,b)};r.prototype.R=function(a){a.selector=a.parsedSelector;this.v(a);this.j(a,this.L)};r.prototype.v=function(a){a.selector===
$e&&(a.selector="html")};r.prototype.L=function(a){return a.match(Fb)?this.g(a,xd):this.s(a.trim(),xd)};Jb.Object.defineProperties(r.prototype,{c:{configurable:!0,enumerable:!0,get:function(){return"style-scope"}}});var Db=/:(nth[-\w]+)\(([^)]+)\)/,xd=":not(.style-scope)",td=",",We=/(^|[\s>+~]+)((?:\[.+?\]|[^\s>+~=[])+)/g,wd=/[[.:#*]/,Eb=":host",$e=":root",Fb="::slotted",Ve=new RegExp("^("+Fb+")"),vd=/(:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/,Xe=/(?:::slotted)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/,Ye=
/(.*):dir\((?:(ltr|rtl))\)/,Ue=".",ud=":",Te="class",Ze="should_not_match",w=new r;t.get=function(a){return a?a.__styleInfo:null};t.set=function(a,b){return a.__styleInfo=b};t.prototype.c=function(){return this.G};t.prototype._getStyleRules=t.prototype.c;var yd=function(a){return a.matches||a.matchesSelector||a.mozMatchesSelector||a.msMatchesSelector||a.oMatchesSelector||a.webkitMatchesSelector}(window.Element.prototype),af=navigator.userAgent.match("Trident");p.prototype.R=function(a){var b=this,
c={},d=[],e=0;ca(a,function(a){b.c(a);a.index=e++;b.I(a.w.cssText,c)},function(a){d.push(a)});a.b=d;a=[];for(var f in c)a.push(f);return a};p.prototype.c=function(a){if(!a.w){var b={},c={};this.b(a,c)&&(b.F=c,a.rules=null);b.cssText=this.H(a);a.w=b}};p.prototype.b=function(a,b){var c=a.w;if(c){if(c.F)return Object.assign(b,c.F),!0}else{c=a.parsedCssText;for(var d;a=Ea.exec(c);){d=(a[2]||a[3]).trim();if("inherit"!==d||"unset"!==d)b[a[1].trim()]=d;d=!0}return d}};p.prototype.H=function(a){return this.L(a.parsedCssText)};
p.prototype.L=function(a){return a.replace(Se,"").replace(Ea,"")};p.prototype.I=function(a,b){for(var c;c=Qe.exec(a);){var d=c[1];":"!==c[2]&&(b[d]=!0)}};p.prototype.ea=function(a){for(var b=Object.getOwnPropertyNames(a),c=0,d;c<b.length;c++)d=b[c],a[d]=this.a(a[d],a)};p.prototype.a=function(a,b){if(a)if(0<=a.indexOf(";"))a=this.f(a,b);else{var c=this;a=gd(a,function(a,e,f,g){if(!e)return a+g;(e=c.a(b[e],b))&&"initial"!==e?"apply-shim-inherit"===e&&(e="inherit"):e=c.a(b[f]||f,b)||f;return a+(e||"")+
g})}return a&&a.trim()||""};p.prototype.f=function(a,b){a=a.split(";");for(var c=0,d,e;c<a.length;c++)if(d=a[c]){Fa.lastIndex=0;if(e=Fa.exec(d))d=this.a(b[e[1]],b);else if(e=d.indexOf(":"),-1!==e){var f=d.substring(e);f=f.trim();f=this.a(f,b)||f;d=d.substring(0,e)+f}a[c]=d&&d.lastIndexOf(";")===d.length-1?d.slice(0,-1):d||""}return a.join(";")};p.prototype.D=function(a,b){var c="";a.w||this.c(a);a.w.cssText&&(c=this.f(a.w.cssText,b));a.cssText=c};p.prototype.C=function(a,b){var c=a.cssText,d=a.cssText;
null==a.Ga&&(a.Ga=Re.test(c));if(a.Ga)if(null==a.ca){a.ca=[];for(var e in b)d=b[e],d=d(c),c!==d&&(c=d,a.ca.push(e))}else{for(e=0;e<a.ca.length;++e)d=b[a.ca[e]],c=d(c);d=c}a.cssText=d};p.prototype.da=function(a,b){var c={},d=this,e=[];ca(a,function(a){a.w||d.c(a);var f=a.A||a.parsedSelector;b&&a.w.F&&f&&yd.call(b,f)&&(d.b(a,c),a=a.index,f=parseInt(a/32,10),e[f]=(e[f]||0)|1<<a%32)},null,!0);return{F:c,key:e}};p.prototype.ga=function(a,b,c,d){b.w||this.c(b);if(b.w.F){var e=T(a);a=e.is;e=e.Z;e=a?w.f(a,
e):"html";var f=b.parsedSelector,g=":host > *"===f||"html"===f,h=0===f.indexOf(":host")&&!g;"shady"===c&&(g=f===e+" > *."+e||-1!==f.indexOf("html"),h=!g&&0===f.indexOf(e));"shadow"===c&&(g=":host > *"===f||"html"===f,h=h&&!g);if(g||h)c=e,h&&(q&&!b.A&&(b.A=w.l(b,w.g,w.h(a),e)),c=b.A||e),d({wb:c,qb:h,Fb:g})}};p.prototype.S=function(a,b){var c={},d={},e=this,f=b&&b.__cssBuild;ca(b,function(b){e.ga(a,b,f,function(f){yd.call(a.Db||a,f.wb)&&(f.qb?e.b(b,c):e.b(b,d))})},null,!0);return{ub:d,pb:c}};p.prototype.fa=
function(a,b,c){var d=this,e=T(a),f=w.f(e.is,e.Z),g=new RegExp("(?:^|[^.#[:])"+(a.extends?"\\"+f.slice(0,-1)+"\\]":f)+"($|[.:[\\s>+~])");e=t.get(a).G;var h=this.h(e,c);return w.b(a,e,function(a){d.D(a,b);q||ed(a)||!a.cssText||(d.C(a,h),d.l(a,g,f,c))})};p.prototype.h=function(a,b){a=a.b;var c={};if(!q&&a)for(var d=0,e=a[d];d<a.length;e=a[++d])this.j(e,b),c[e.keyframesName]=this.i(e);return c};p.prototype.i=function(a){return function(b){return b.replace(a.f,a.a)}};p.prototype.j=function(a,b){a.f=new RegExp(a.keyframesName,
"g");a.a=a.keyframesName+"-"+b;a.A=a.A||a.selector;a.selector=a.A.replace(a.keyframesName,a.a)};p.prototype.l=function(a,b,c,d){a.A=a.A||a.selector;d="."+d;for(var e=a.A.split(","),f=0,g=e.length,h;f<g&&(h=e[f]);f++)e[f]=h.match(b)?h.replace(c,d):d+" "+h;a.selector=e.join(",")};p.prototype.u=function(a,b,c){var d=a.getAttribute("class")||"",e=d;c&&(e=d.replace(new RegExp("\\s*x-scope\\s*"+c+"\\s*","g")," "));e+=(e?" ":"")+"x-scope "+b;d!==e&&za(a,e)};p.prototype.v=function(a,b,c,d){b=d?d.textContent||
"":this.fa(a,b,c);var e=t.get(a),f=e.a;f&&!q&&f!==d&&(f._useCount--,0>=f._useCount&&f.parentNode&&f.parentNode.removeChild(f));q?e.a?(e.a.textContent=b,d=e.a):b&&(d=ub(b,c,a.shadowRoot,e.b)):d?d.parentNode||(af&&-1<b.indexOf("@media")&&(d.textContent=b),fd(d,null,e.b)):b&&(d=ub(b,c,null,e.b));d&&(d._useCount=d._useCount||0,e.a!=d&&d._useCount++,e.a=d);return d};p.prototype.s=function(a,b){var c=ya(a),d=this;a.textContent=ba(c,function(a){var c=a.cssText=a.parsedCssText;a.w&&a.w.cssText&&(c=c.replace(G.Ea,
"").replace(G.Ia,""),a.cssText=d.f(c,b))})};Jb.Object.defineProperties(p.prototype,{g:{configurable:!0,enumerable:!0,get:function(){return"x-scope"}}});var O=new p,Gb={},Ga=window.customElements;if(Ga&&!q){var bf=Ga.define;Ga.define=function(a,b,c){var d=document.createComment(" Shady DOM styles for "+a+" "),e=document.head;e.insertBefore(d,(S?S.nextSibling:null)||e.firstChild);S=d;Gb[a]=d;return bf.call(Ga,a,b,c)}}pa.prototype.a=function(a,b,c){for(var d=0;d<c.length;d++){var e=c[d];if(a.F[e]!==
b[e])return!1}return!0};pa.prototype.b=function(a,b,c,d){var e=this.cache[a]||[];e.push({F:b,styleElement:c,B:d});e.length>this.c&&e.shift();this.cache[a]=e};pa.prototype.fetch=function(a,b,c){if(a=this.cache[a])for(var d=a.length-1;0<=d;d--){var e=a[d];if(this.a(e,b,c))return e}};if(!q){var zd=new MutationObserver(hd),Ad=function(a){zd.observe(a,{childList:!0,subtree:!0})};if(window.customElements&&!window.customElements.polyfillWrapFlushCallback)Ad(document);else{var Hb=function(){Ad(document.body)};
window.HTMLImports?window.HTMLImports.whenReady(Hb):requestAnimationFrame(function(){if("loading"===document.readyState){var a=function(){Hb();document.removeEventListener("readystatechange",a)};document.addEventListener("readystatechange",a)}else Hb()})}Lb=function(){hd(zd.takeRecords())}}var Aa={},Ee=Promise.resolve(),vb=null,jd=window.HTMLImports&&window.HTMLImports.whenReady||null,wb,Ha=null,oa=null;F.prototype.Fa=function(){!this.enqueued&&oa&&(this.enqueued=!0,Kb(oa))};F.prototype.b=function(a){a.__seenByShadyCSS||
(a.__seenByShadyCSS=!0,this.customStyles.push(a),this.Fa())};F.prototype.a=function(a){return a.__shadyCSSCachedStyle?a.__shadyCSSCachedStyle:a.getStyle?a.getStyle():a};F.prototype.c=function(){for(var a=this.customStyles,b=0;b<a.length;b++){var c=a[b];if(!c.__shadyCSSCachedStyle){var d=this.a(c);d&&(d=d.__appliedElement||d,Ha&&Ha(d),c.__shadyCSSCachedStyle=d)}}return a};F.prototype.addCustomStyle=F.prototype.b;F.prototype.getStyleForCustomStyle=F.prototype.a;F.prototype.processStyles=F.prototype.c;
Object.defineProperties(F.prototype,{transformCallback:{get:function(){return Ha},set:function(a){Ha=a}},validateCallback:{get:function(){return oa},set:function(a){var b=!1;oa||(b=!0);oa=a;b&&this.Fa()}}});var Bd=new pa;k.prototype.C=function(){Lb()};k.prototype.S=function(a){var b=this.s[a]=(this.s[a]||0)+1;return a+"-"+b};k.prototype.Ra=function(a){return ya(a)};k.prototype.Ta=function(a){return ba(a)};k.prototype.R=function(a){a=a.content.querySelectorAll("style");for(var b=[],c=0;c<a.length;c++){var d=
a[c];b.push(d.textContent);d.parentNode.removeChild(d)}return b.join("").trim()};k.prototype.ea=function(a){return(a=a.content.querySelector("style"))?a.getAttribute("css-build")||"":""};k.prototype.prepareTemplate=function(a,b,c){if(!a.f){a.f=!0;a.name=b;a.extends=c;Aa[b]=a;var d=this.ea(a),e=this.R(a);c={is:b,extends:c,Ab:d};q||w.a(a.content,b);this.c();var f=Fa.test(e)||Ea.test(e);Fa.lastIndex=0;Ea.lastIndex=0;e=tb(e);f&&v&&this.a&&this.a.transformRules(e,b);a._styleAst=e;a.g=d;d=[];v||(d=O.R(a._styleAst));
if(!d.length||v)b=this.da(c,a._styleAst,q?a.content:null,Gb[b]),a.a=b;a.c=d}};k.prototype.da=function(a,b,c,d){b=w.b(a,b);if(b.length)return ub(b,a.is,c,d)};k.prototype.ga=function(a){var b=T(a),c=b.is;b=b.Z;var d=Gb[c];c=Aa[c];if(c){var e=c._styleAst;var f=c.c}return t.set(a,new t(e,d,f,0,b))};k.prototype.H=function(){!this.a&&window.ShadyCSS&&window.ShadyCSS.ApplyShim&&(this.a=window.ShadyCSS.ApplyShim,this.a.invalidCallback=Ce)};k.prototype.I=function(){var a=this;!this.b&&window.ShadyCSS&&window.ShadyCSS.CustomStyleInterface&&
(this.b=window.ShadyCSS.CustomStyleInterface,this.b.transformCallback=function(b){a.v(b)},this.b.validateCallback=function(){requestAnimationFrame(function(){(a.b.enqueued||a.i)&&a.f()})})};k.prototype.c=function(){this.H();this.I()};k.prototype.f=function(){this.c();if(this.b){var a=this.b.processStyles();this.b.enqueued&&(v?this.Pa(a):(this.u(this.g,this.h),this.D(a)),this.b.enqueued=!1,this.i&&!v&&this.styleDocument())}};k.prototype.styleElement=function(a,b){var c=T(a).is,d=t.get(a);d||(d=this.ga(a));
this.j(a)||(this.i=!0);b&&(d.P=d.P||{},Object.assign(d.P,b));if(v){if(d.P){b=d.P;for(var e in b)null===e?a.style.removeProperty(e):a.style.setProperty(e,b[e])}if(((e=Aa[c])||this.j(a))&&e&&e.a&&!id(e)){if(id(e)||e._applyShimValidatingVersion!==e._applyShimNextVersion)this.c(),this.a&&this.a.transformRules(e._styleAst,c),e.a.textContent=w.b(a,d.G),De(e);q&&(c=a.shadowRoot)&&(c.querySelector("style").textContent=w.b(a,d.G));d.G=e._styleAst}}else this.u(a,d),d.ra&&d.ra.length&&this.L(a,d)};k.prototype.l=
function(a){return(a=a.getRootNode().host)?t.get(a)?a:this.l(a):this.g};k.prototype.j=function(a){return a===this.g};k.prototype.L=function(a,b){var c=T(a).is,d=Bd.fetch(c,b.K,b.ra),e=d?d.styleElement:null,f=b.B;b.B=d&&d.B||this.S(c);e=O.v(a,b.K,b.B,e);q||O.u(a,b.B,f);d||Bd.b(c,b.K,e,b.B)};k.prototype.u=function(a,b){var c=this.l(a),d=t.get(c);c=Object.create(d.K||null);var e=O.S(a,b.G);a=O.da(d.G,a).F;Object.assign(c,e.pb,a,e.ub);this.fa(c,b.P);O.ea(c);b.K=c};k.prototype.fa=function(a,b){for(var c in b){var d=
b[c];if(d||0===d)a[c]=d}};k.prototype.styleDocument=function(a){this.styleSubtree(this.g,a)};k.prototype.styleSubtree=function(a,b){var c=a.shadowRoot;(c||this.j(a))&&this.styleElement(a,b);if(b=c&&(c.children||c.childNodes))for(a=0;a<b.length;a++)this.styleSubtree(b[a]);else if(a=a.children||a.childNodes)for(b=0;b<a.length;b++)this.styleSubtree(a[b])};k.prototype.Pa=function(a){for(var b=0;b<a.length;b++){var c=this.b.getStyleForCustomStyle(a[b]);c&&this.Oa(c)}};k.prototype.D=function(a){for(var b=
0;b<a.length;b++){var c=this.b.getStyleForCustomStyle(a[b]);c&&O.s(c,this.h.K)}};k.prototype.v=function(a){var b=this,c=ya(a);ca(c,function(a){q?w.v(a):w.R(a);v&&(b.c(),b.a&&b.a.transformRule(a))});v?a.textContent=ba(c):this.h.G.rules.push(c)};k.prototype.Oa=function(a){if(v&&this.a){var b=ya(a);this.c();this.a.transformRules(b);a.textContent=ba(b)}};k.prototype.getComputedStyleValue=function(a,b){var c;v||(c=(t.get(a)||t.get(this.l(a))).K[b]);return(c=c||window.getComputedStyle(a).getPropertyValue(b))?
c.trim():""};k.prototype.Sa=function(a,b){var c=a.getRootNode();b=b?b.split(/\s/):[];c=c.host&&c.host.localName;if(!c){var d=a.getAttribute("class");if(d){d=d.split(/\s/);for(var e=0;e<d.length;e++)if(d[e]===w.c){c=d[e+1];break}}}c&&b.push(w.c,c);v||(c=t.get(a))&&c.B&&b.push(O.g,c.B);za(a,b.join(" "))};k.prototype.Qa=function(a){return t.get(a)};k.prototype.flush=k.prototype.C;k.prototype.prepareTemplate=k.prototype.prepareTemplate;k.prototype.styleElement=k.prototype.styleElement;k.prototype.styleDocument=
k.prototype.styleDocument;k.prototype.styleSubtree=k.prototype.styleSubtree;k.prototype.getComputedStyleValue=k.prototype.getComputedStyleValue;k.prototype.setElementClass=k.prototype.Sa;k.prototype._styleInfoForNode=k.prototype.Qa;k.prototype.transformCustomStyleForDocument=k.prototype.v;k.prototype.getStyleAst=k.prototype.Ra;k.prototype.styleAstToString=k.prototype.Ta;k.prototype.flushCustomStyles=k.prototype.f;Object.defineProperties(k.prototype,{nativeShadow:{get:function(){return q}},nativeCss:{get:function(){return v}}});
var J=new k;if(window.ShadyCSS){var Cd=window.ShadyCSS.ApplyShim;var Dd=window.ShadyCSS.CustomStyleInterface}window.ShadyCSS={ScopingShim:J,prepareTemplate:function(a,b,c){J.f();J.prepareTemplate(a,b,c)},styleSubtree:function(a,b){J.f();J.styleSubtree(a,b)},styleElement:function(a){J.f();J.styleElement(a)},styleDocument:function(a){J.f();J.styleDocument(a)},getComputedStyleValue:function(a,b){return J.getComputedStyleValue(a,b)},nativeCss:v,nativeShadow:q};Cd&&(window.ShadyCSS.ApplyShim=Cd);Dd&&(window.ShadyCSS.CustomStyleInterface=
Dd);var Ib=window.customElements,Ia=window.HTMLImports;window.WebComponents=window.WebComponents||{};if(Ib&&Ib.polyfillWrapFlushCallback){var Ja,Ed=function(){if(Ja){var a=Ja;Ja=null;a();return!0}},Fd=Ia.whenReady;Ib.polyfillWrapFlushCallback(function(a){Ja=a;Fd(Ed)});Ia.whenReady=function(a){Fd(function(){Ed()?Ia.whenReady(a):a()})}}Ia.whenReady(function(){requestAnimationFrame(function(){window.WebComponents.ready=!0;document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})});
var Gd=document.createElement("style");Gd.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";var Hd=document.querySelector("head");Hd.insertBefore(Gd,Hd.firstChild)})();}).call(this);
'use strict';var N="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:this,Oa="function"==typeof Object.defineProperties?Object.defineProperty:function(g,t,R){g!=Array.prototype&&g!=Object.prototype&&(g[t]=R.value)};function Pb(){Pb=function(){};N.Symbol||(N.Symbol=Qb)}var Qb=function(){var g=0;return function(t){return"jscomp_symbol_"+(t||"")+g++}}();
function Od(){Pb();var g=N.Symbol.iterator;g||(g=N.Symbol.iterator=N.Symbol("iterator"));"function"!=typeof Array.prototype[g]&&Oa(Array.prototype,g,{configurable:!0,writable:!0,value:function(){return Pd(this)}});Od=function(){}}function Pd(g){var t=0;return Qd(function(){return t<g.length?{done:!1,value:g[t++]}:{done:!0}})}function Qd(g){Od();g={next:g};g[N.Symbol.iterator]=function(){return this};return g}function Rd(g){Od();var t=g[Symbol.iterator];return t?t.call(g):Pd(g)}
function Sd(g){for(var t,R=[];!(t=g.next()).done;)R.push(t.value);return R}
(function(){function g(){var a=this;this.s={};this.g=document.documentElement;var b=new Pa;b.rules=[];this.h=w.set(this.g,new w(b));this.i=!1;this.b=this.a=null;Rb(function(){a.c()})}function t(){this.customStyles=[];this.enqueued=!1}function R(){}function ta(a){this.cache={};this.c=void 0===a?100:a}function p(){}function w(a,b,c,d,e){this.G=a||null;this.b=b||null;this.ua=c||[];this.S=null;this.$=e||"";this.a=this.C=this.M=null}function v(){}function Pa(){this.end=this.start=0;this.rules=this.parent=
this.previous=null;this.cssText=this.parsedCssText="";this.atRule=!1;this.type=0;this.parsedSelector=this.selector=this.keyframesName=""}function Td(a){function b(b,c){Object.defineProperty(b,"innerHTML",{enumerable:c.enumerable,configurable:!0,get:c.get,set:function(b){var d=this,e=void 0;u(this)&&(e=[],S(this,function(a){a!==d&&e.push(a)}));c.set.call(this,b);if(e)for(var f=0;f<e.length;f++){var h=e[f];1===h.__CE_state&&a.disconnectedCallback(h)}this.ownerDocument.__CE_hasRegistry?a.f(this):a.l(this);
return b}})}function c(b,c){x(b,"insertAdjacentElement",function(b,d){var e=u(d);b=c.call(this,b,d);e&&a.a(d);u(b)&&a.b(d);return b})}Sb&&x(Element.prototype,"attachShadow",function(a){return this.__CE_shadowRoot=a=Sb.call(this,a)});if(Qa&&Qa.get)b(Element.prototype,Qa);else if(Ra&&Ra.get)b(HTMLElement.prototype,Ra);else{var d=Sa.call(document,"div");a.v(function(a){b(a,{enumerable:!0,configurable:!0,get:function(){return Tb.call(this,!0).innerHTML},set:function(a){var b="template"===this.localName?
this.content:this;for(d.innerHTML=a;0<b.childNodes.length;)Ta.call(b,b.childNodes[0]);for(;0<d.childNodes.length;)ua.call(b,d.childNodes[0])}})})}x(Element.prototype,"setAttribute",function(b,c){if(1!==this.__CE_state)return Ub.call(this,b,c);var d=Ua.call(this,b);Ub.call(this,b,c);c=Ua.call(this,b);a.attributeChangedCallback(this,b,d,c,null)});x(Element.prototype,"setAttributeNS",function(b,c,d){if(1!==this.__CE_state)return Vb.call(this,b,c,d);var e=va.call(this,b,c);Vb.call(this,b,c,d);d=va.call(this,
b,c);a.attributeChangedCallback(this,c,e,d,b)});x(Element.prototype,"removeAttribute",function(b){if(1!==this.__CE_state)return Wb.call(this,b);var c=Ua.call(this,b);Wb.call(this,b);null!==c&&a.attributeChangedCallback(this,b,c,null,null)});x(Element.prototype,"removeAttributeNS",function(b,c){if(1!==this.__CE_state)return Xb.call(this,b,c);var d=va.call(this,b,c);Xb.call(this,b,c);var e=va.call(this,b,c);d!==e&&a.attributeChangedCallback(this,c,d,e,b)});Yb?c(HTMLElement.prototype,Yb):Zb?c(Element.prototype,
Zb):console.warn("Custom Elements: `Element#insertAdjacentElement` was not patched.");Va(a,Element.prototype,{ea:Ud,append:Vd});Wd(a,{ra:Xd,jb:Yd,replaceWith:Zd,remove:$d})}function Wd(a,b){var c=Element.prototype;function d(b){return function(c){for(var d=[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];e=[];for(var f=[],q=0;q<d.length;q++){var g=d[q];g instanceof Element&&u(g)&&f.push(g);if(g instanceof DocumentFragment)for(g=g.firstChild;g;g=g.nextSibling)e.push(g);else e.push(g)}b.apply(this,
d);for(d=0;d<f.length;d++)a.a(f[d]);if(u(this))for(d=0;d<e.length;d++)f=e[d],f instanceof Element&&a.b(f)}}void 0!==b.ra&&(c.before=d(b.ra));void 0!==b.ra&&(c.after=d(b.jb));void 0!==b.replaceWith&&x(c,"replaceWith",function(c){for(var d=[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];e=[];for(var k=[],m=0;m<d.length;m++){var g=d[m];g instanceof Element&&u(g)&&k.push(g);if(g instanceof DocumentFragment)for(g=g.firstChild;g;g=g.nextSibling)e.push(g);else e.push(g)}m=u(this);b.replaceWith.apply(this,
d);for(d=0;d<k.length;d++)a.a(k[d]);if(m)for(a.a(this),d=0;d<e.length;d++)k=e[d],k instanceof Element&&a.b(k)});void 0!==b.remove&&x(c,"remove",function(){var c=u(this);b.remove.call(this);c&&a.a(this)})}function ae(a){function b(b,d){Object.defineProperty(b,"textContent",{enumerable:d.enumerable,configurable:!0,get:d.get,set:function(b){if(this.nodeType===Node.TEXT_NODE)d.set.call(this,b);else{var c=void 0;if(this.firstChild){var e=this.childNodes,k=e.length;if(0<k&&u(this)){c=Array(k);for(var m=
0;m<k;m++)c[m]=e[m]}}d.set.call(this,b);if(c)for(b=0;b<c.length;b++)a.a(c[b])}}})}x(Node.prototype,"insertBefore",function(b,d){if(b instanceof DocumentFragment){var c=Array.prototype.slice.apply(b.childNodes);b=$b.call(this,b,d);if(u(this))for(d=0;d<c.length;d++)a.b(c[d]);return b}c=u(b);d=$b.call(this,b,d);c&&a.a(b);u(this)&&a.b(b);return d});x(Node.prototype,"appendChild",function(b){if(b instanceof DocumentFragment){var c=Array.prototype.slice.apply(b.childNodes);b=ua.call(this,b);if(u(this))for(var e=
0;e<c.length;e++)a.b(c[e]);return b}c=u(b);e=ua.call(this,b);c&&a.a(b);u(this)&&a.b(b);return e});x(Node.prototype,"cloneNode",function(b){b=Tb.call(this,b);this.ownerDocument.__CE_hasRegistry?a.f(b):a.l(b);return b});x(Node.prototype,"removeChild",function(b){var c=u(b),e=Ta.call(this,b);c&&a.a(b);return e});x(Node.prototype,"replaceChild",function(b,d){if(b instanceof DocumentFragment){var c=Array.prototype.slice.apply(b.childNodes);b=ac.call(this,b,d);if(u(this))for(a.a(d),d=0;d<c.length;d++)a.b(c[d]);
return b}c=u(b);var f=ac.call(this,b,d),h=u(this);h&&a.a(d);c&&a.a(b);h&&a.b(b);return f});Wa&&Wa.get?b(Node.prototype,Wa):a.v(function(a){b(a,{enumerable:!0,configurable:!0,get:function(){for(var a=[],b=0;b<this.childNodes.length;b++)a.push(this.childNodes[b].textContent);return a.join("")},set:function(a){for(;this.firstChild;)Ta.call(this,this.firstChild);ua.call(this,document.createTextNode(a))}})})}function be(a){x(Document.prototype,"createElement",function(b){if(this.__CE_hasRegistry){var c=
a.c(b);if(c)return new c.constructor}b=Sa.call(this,b);a.g(b);return b});x(Document.prototype,"importNode",function(b,c){b=ce.call(this,b,c);this.__CE_hasRegistry?a.f(b):a.l(b);return b});x(Document.prototype,"createElementNS",function(b,c){if(this.__CE_hasRegistry&&(null===b||"http://www.w3.org/1999/xhtml"===b)){var d=a.c(c);if(d)return new d.constructor}b=de.call(this,b,c);a.g(b);return b});Va(a,Document.prototype,{ea:ee,append:fe})}function Va(a,b,c){function d(b){return function(c){for(var d=
[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];e=[];for(var f=[],g=0;g<d.length;g++){var n=d[g];n instanceof Element&&u(n)&&f.push(n);if(n instanceof DocumentFragment)for(n=n.firstChild;n;n=n.nextSibling)e.push(n);else e.push(n)}b.apply(this,d);for(d=0;d<f.length;d++)a.a(f[d]);if(u(this))for(d=0;d<e.length;d++)f=e[d],f instanceof Element&&a.b(f)}}void 0!==c.ea&&(b.prepend=d(c.ea));void 0!==c.append&&(b.append=d(c.append))}function ge(a){window.HTMLElement=function(){function b(){var b=this.constructor,
d=a.B(b);if(!d)throw Error("The custom element being constructed was not registered with `customElements`.");var e=d.constructionStack;if(0===e.length)return e=Sa.call(document,d.localName),Object.setPrototypeOf(e,b.prototype),e.__CE_state=1,e.__CE_definition=d,a.g(e),e;d=e.length-1;var f=e[d];if(f===bc)throw Error("The HTMLElement constructor was either called reentrantly for this constructor or called multiple times.");e[d]=bc;Object.setPrototypeOf(f,b.prototype);a.g(f);return f}b.prototype=he.prototype;
return b}()}function y(a){this.c=!1;this.a=a;this.h=new Map;this.f=function(a){return a()};this.b=!1;this.g=[];this.i=new Xa(a,document)}function cc(){var a=this;this.b=this.a=void 0;this.c=new Promise(function(b){a.b=b;a.a&&b(a.a)})}function Xa(a,b){this.b=a;this.a=b;this.P=void 0;this.b.f(this.a);"loading"===this.a.readyState&&(this.P=new MutationObserver(this.f.bind(this)),this.P.observe(this.a,{childList:!0,subtree:!0}))}function B(){this.u=new Map;this.s=new Map;this.j=[];this.h=!1}function l(a,
b,c){if(a!==dc)throw new TypeError("Illegal constructor");a=document.createDocumentFragment();a.__proto__=l.prototype;a.H(b,c);return a}function wa(a){if(!a.__shady||void 0===a.__shady.firstChild){a.__shady=a.__shady||{};a.__shady.firstChild=Ya(a);a.__shady.lastChild=Za(a);ec(a);for(var b=a.__shady.childNodes=X(a),c=0,d;c<b.length&&(d=b[c]);c++)d.__shady=d.__shady||{},d.__shady.parentNode=a,d.__shady.nextSibling=b[c+1]||null,d.__shady.previousSibling=b[c-1]||null,fc(d)}}function ie(a){var b=a&&a.P;
b&&(b.ca.delete(a.ab),b.ca.size||(a.fb.__shady.Y=null))}function je(a,b){a.__shady=a.__shady||{};a.__shady.Y||(a.__shady.Y=new xa);a.__shady.Y.ca.add(b);var c=a.__shady.Y;return{ab:b,P:c,fb:a,takeRecords:function(){return c.takeRecords()}}}function xa(){this.a=!1;this.addedNodes=[];this.removedNodes=[];this.ca=new Set}function T(a,b){Y[Z]=a;Y[Z+1]=b;Z+=2;2===Z&&($a?$a(aa):ke())}function le(){return function(){return process.Hb(aa)}}function me(){return"undefined"!==typeof ab?function(){ab(aa)}:bb()}
function ne(){var a=0,b=new gc(aa),c=document.createTextNode("");b.observe(c,{characterData:!0});return function(){c.data=a=++a%2}}function oe(){var a=new MessageChannel;a.port1.onmessage=aa;return function(){return a.port2.postMessage(0)}}function bb(){var a=setTimeout;return function(){return a(aa,1)}}function aa(){for(var a=0;a<Z;a+=2)(0,Y[a])(Y[a+1]),Y[a]=void 0,Y[a+1]=void 0;Z=0}function pe(){try{var a=require("vertx");ab=a.Jb||a.Ib;return me()}catch(b){return bb()}}function cb(a,b){var c=this,
d=new this.constructor(ba);void 0===d[ya]&&hc(d);var e=c.o;if(e){var f=arguments[e-1];T(function(){return ic(e,d,f,c.m)})}else db(c,d,a,b);return d}function eb(a){if(a&&"object"===typeof a&&a.constructor===this)return a;var b=new this(ba);ja(b,a);return b}function ba(){}function jc(a){try{return a.then}catch(b){return ka.error=b,ka}}function qe(a,b,c,d){try{a.call(b,c,d)}catch(e){return e}}function re(a,b,c){T(function(a){var d=!1,f=qe(c,b,function(c){d||(d=!0,b!==c?ja(a,c):L(a,c))},function(b){d||
(d=!0,C(a,b))});!d&&f&&(d=!0,C(a,f))},a)}function se(a,b){1===b.o?L(a,b.m):2===b.o?C(a,b.m):db(b,void 0,function(b){return ja(a,b)},function(b){return C(a,b)})}function kc(a,b,c){b.constructor===a.constructor&&c===cb&&b.constructor.resolve===eb?se(a,b):c===ka?(C(a,ka.error),ka.error=null):void 0===c?L(a,b):"function"===typeof c?re(a,b,c):L(a,b)}function ja(a,b){if(a===b)C(a,new TypeError("You cannot resolve a promise with itself"));else{var c=typeof b;null===b||"object"!==c&&"function"!==c?L(a,b):
kc(a,b,jc(b))}}function te(a){a.Da&&a.Da(a.m);fb(a)}function L(a,b){void 0===a.o&&(a.m=b,a.o=1,0!==a.V.length&&T(fb,a))}function C(a,b){void 0===a.o&&(a.o=2,a.m=b,T(te,a))}function db(a,b,c,d){var e=a.V,f=e.length;a.Da=null;e[f]=b;e[f+1]=c;e[f+2]=d;0===f&&a.o&&T(fb,a)}function fb(a){var b=a.V,c=a.o;if(0!==b.length){for(var d,e,f=a.m,h=0;h<b.length;h+=3)d=b[h],e=b[h+c],d?ic(c,d,e,f):e(f);a.V.length=0}}function lc(){this.error=null}function ic(a,b,c,d){var e="function"===typeof c;if(e){try{var f=c(d)}catch(q){gb.error=
q,f=gb}if(f===gb){var h=!0;var k=f.error;f.error=null}else var m=!0;if(b===f){C(b,new TypeError("A promises callback cannot return that same promise."));return}}else f=d,m=!0;void 0===b.o&&(e&&m?ja(b,f):h?C(b,k):1===a?L(b,f):2===a&&C(b,f))}function ue(a,b){try{b(function(b){ja(a,b)},function(b){C(a,b)})}catch(c){C(a,c)}}function hc(a){a[ya]=mc++;a.o=void 0;a.m=void 0;a.V=[]}function la(a,b){this.eb=a;this.L=new a(ba);this.L[ya]||hc(this.L);nc(b)?(this.aa=this.length=b.length,this.m=Array(this.length),
0===this.length?L(this.L,this.m):(this.length=this.length||0,this.cb(b),0===this.aa&&L(this.L,this.m))):C(this.L,Error("Array Methods must be provided an Array"))}function D(a){this[ya]=mc++;this.m=this.o=void 0;this.V=[];if(ba!==a){if("function"!==typeof a)throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(this instanceof D)ue(this,a);else throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
}}function ca(a){return a.__shady&&void 0!==a.__shady.firstChild}function J(a){return"ShadyRoot"===a.Wa}function ma(a){a=a.getRootNode();if(J(a))return a}function hb(a,b){if(a&&b)for(var c=Object.getOwnPropertyNames(b),d=0,e;d<c.length&&(e=c[d]);d++){var f=Object.getOwnPropertyDescriptor(b,e);f&&Object.defineProperty(a,e,f)}}function ib(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=arguments[d];for(d=0;d<c.length;d++)hb(a,c[d]);return a}function ve(a,b){for(var c in b)a[c]=b[c]}function oc(a){jb.push(a);
kb.textContent=pc++}function qc(a,b){for(;b;){if(b==a)return!0;b=b.parentNode}return!1}function rc(a){lb||(lb=!0,oc(za));na.push(a)}function za(){lb=!1;for(var a=!!na.length;na.length;)na.shift()();return a}function we(a,b){var c=b.getRootNode();return a.map(function(a){var b=c===a.target.getRootNode();if(b&&a.addedNodes){if(b=Array.from(a.addedNodes).filter(function(a){return c===a.getRootNode()}),b.length)return a=Object.create(a),Object.defineProperty(a,"addedNodes",{value:b,configurable:!0}),
a}else if(b)return a}).filter(function(a){return a})}function sc(a){switch(a){case "&":return"&amp;";case "<":return"&lt;";case ">":return"&gt;";case '"':return"&quot;";case "\u00a0":return"&nbsp;"}}function tc(a){for(var b={},c=0;c<a.length;c++)b[a[c]]=!0;return b}function mb(a,b){"template"===a.localName&&(a=a.content);for(var c="",d=b?b(a):a.childNodes,e=0,f=d.length,h;e<f&&(h=d[e]);e++){a:{var k=h;var m=a;var g=b;switch(k.nodeType){case Node.ELEMENT_NODE:for(var n=k.localName,l="<"+n,t=k.attributes,
p=0;m=t[p];p++)l+=" "+m.name+'="'+m.value.replace(xe,sc)+'"';l+=">";k=ye[n]?l:l+mb(k,g)+"</"+n+">";break a;case Node.TEXT_NODE:k=k.data;k=m&&ze[m.localName]?k:k.replace(Ae,sc);break a;case Node.COMMENT_NODE:k="\x3c!--"+k.data+"--\x3e";break a;default:throw window.console.error(k),Error("not implemented");}}c+=k}return c}function da(a){E.currentNode=a;return E.parentNode()}function Ya(a){E.currentNode=a;return E.firstChild()}function Za(a){E.currentNode=a;return E.lastChild()}function uc(a){E.currentNode=
a;return E.previousSibling()}function vc(a){E.currentNode=a;return E.nextSibling()}function X(a){var b=[];E.currentNode=a;for(a=E.firstChild();a;)b.push(a),a=E.nextSibling();return b}function wc(a){F.currentNode=a;return F.parentNode()}function xc(a){F.currentNode=a;return F.firstChild()}function yc(a){F.currentNode=a;return F.lastChild()}function zc(a){F.currentNode=a;return F.previousSibling()}function Ac(a){F.currentNode=a;return F.nextSibling()}function Bc(a){var b=[];F.currentNode=a;for(a=F.firstChild();a;)b.push(a),
a=F.nextSibling();return b}function Cc(a){return mb(a,function(a){return X(a)})}function Dc(a){switch(a.nodeType){case Node.ELEMENT_NODE:case Node.DOCUMENT_FRAGMENT_NODE:a=document.createTreeWalker(a,NodeFilter.SHOW_TEXT,null,!1);for(var b="",c;c=a.nextNode();)b+=c.nodeValue;return b;default:return a.nodeValue}}function O(a,b,c){for(var d in b){var e=Object.getOwnPropertyDescriptor(a,d);e&&e.configurable||!e&&c?Object.defineProperty(a,d,b[d]):c&&console.warn("Could not define",d,"on",a)}}function U(a){O(a,
Ec);O(a,nb);O(a,ob)}function Fc(a,b,c){fc(a);c=c||null;a.__shady=a.__shady||{};b.__shady=b.__shady||{};c&&(c.__shady=c.__shady||{});a.__shady.previousSibling=c?c.__shady.previousSibling:b.lastChild;var d=a.__shady.previousSibling;d&&d.__shady&&(d.__shady.nextSibling=a);(d=a.__shady.nextSibling=c)&&d.__shady&&(d.__shady.previousSibling=a);a.__shady.parentNode=b;c?c===b.__shady.firstChild&&(b.__shady.firstChild=a):(b.__shady.lastChild=a,b.__shady.firstChild||(b.__shady.firstChild=a));b.__shady.childNodes=
null}function pb(a,b,c){if(b===a)throw Error("Failed to execute 'appendChild' on 'Node': The new child element contains the parent.");if(c){var d=c.__shady&&c.__shady.parentNode;if(void 0!==d&&d!==a||void 0===d&&da(c)!==a)throw Error("Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.");}if(c===b)return b;b.parentNode&&qb(b.parentNode,b);d=ma(a);var e;if(e=d)a:{if(!b.__noInsertionPoint){var f;"slot"===b.localName?f=[b]:b.querySelectorAll&&
(f=b.querySelectorAll("slot"));if(f&&f.length){e=f;break a}}e=void 0}(f=e)&&d.$a(f);d&&("slot"===a.localName||f)&&d.O();if(ca(a)){d=c;ec(a);a.__shady=a.__shady||{};void 0!==a.__shady.firstChild&&(a.__shady.childNodes=null);if(b.nodeType===Node.DOCUMENT_FRAGMENT_NODE){f=b.childNodes;for(e=0;e<f.length;e++)Fc(f[e],a,d);b.__shady=b.__shady||{};d=void 0!==b.__shady.firstChild?null:void 0;b.__shady.firstChild=b.__shady.lastChild=d;b.__shady.childNodes=d}else Fc(b,a,d);if(rb(a)){a.__shady.root.O();var h=
!0}else a.__shady.root&&(h=!0)}h||(h=J(a)?a.host:a,c?(c=Gc(c),sb.call(h,b,c)):Hc.call(h,b));Ic(a,b);return b}function qb(a,b){if(b.parentNode!==a)throw Error("The node to be removed is not a child of this node: "+b);var c=ma(b);if(ca(a)){b.__shady=b.__shady||{};a.__shady=a.__shady||{};b===a.__shady.firstChild&&(a.__shady.firstChild=b.__shady.nextSibling);b===a.__shady.lastChild&&(a.__shady.lastChild=b.__shady.previousSibling);var d=b.__shady.previousSibling;var e=b.__shady.nextSibling;d&&(d.__shady=
d.__shady||{},d.__shady.nextSibling=e);e&&(e.__shady=e.__shady||{},e.__shady.previousSibling=d);b.__shady.parentNode=b.__shady.previousSibling=b.__shady.nextSibling=void 0;void 0!==a.__shady.childNodes&&(a.__shady.childNodes=null);if(rb(a)){a.__shady.root.O();var f=!0}}Jc(b);c&&((e=a&&"slot"===a.localName)&&(f=!0),((d=c.gb(b))||e)&&c.O());f||(f=J(a)?a.host:a,(!a.__shady.root&&"slot"!==b.localName||f===da(b))&&oa.call(f,b));Ic(a,null,b);return b}function Jc(a){if(a.__shady&&void 0!==a.__shady.va)for(var b=
a.childNodes,c=0,d=b.length,e;c<d&&(e=b[c]);c++)Jc(e);a.__shady&&(a.__shady.va=void 0)}function Gc(a){var b=a;a&&"slot"===a.localName&&(b=(b=a.__shady&&a.__shady.W)&&b.length?b[0]:Gc(a.nextSibling));return b}function rb(a){return(a=a&&a.__shady&&a.__shady.root)&&a.Ca()}function Kc(a,b){"slot"===b?(a=a.parentNode,rb(a)&&a.__shady.root.O()):"slot"===a.localName&&"name"===b&&(b=ma(a))&&(b.ib(a),b.O())}function Ic(a,b,c){if(a=a.__shady&&a.__shady.Y)b&&a.addedNodes.push(b),c&&a.removedNodes.push(c),a.ub()}
function Lc(a){if(a&&a.nodeType){a.__shady=a.__shady||{};var b=a.__shady.va;void 0===b&&(J(a)?b=a:b=(b=a.parentNode)?Lc(b):a,pa.call(document.documentElement,a)&&(a.__shady.va=b));return b}}function Aa(a,b,c){var d=[];Mc(a.childNodes,b,c,d);return d}function Mc(a,b,c,d){for(var e=0,f=a.length,h;e<f&&(h=a[e]);e++){var k;if(k=h.nodeType===Node.ELEMENT_NODE){k=h;var m=b,g=c,n=d,l=m(k);l&&n.push(k);g&&g(l)?k=l:(Mc(k.childNodes,m,g,n),k=void 0)}if(k)break}}function Nc(a){a=a.getRootNode();J(a)&&a.Fa()}
function Oc(a,b,c){Ba||(Ba=window.ShadyCSS&&window.ShadyCSS.ScopingShim);Ba&&"class"===b?Ba.setElementClass(a,c):(Pc.call(a,b,c),Kc(a,b))}function Qc(a,b){if(a.ownerDocument!==document)return tb.call(document,a,b);var c=tb.call(document,a,!1);if(b){a=a.childNodes;b=0;for(var d;b<a.length;b++)d=Qc(a[b],!0),c.appendChild(d)}return c}function ub(a,b){var c=[],d=a;for(a=a===window?window:a.getRootNode();d;)c.push(d),d=d.assignedSlot?d.assignedSlot:d.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&d.host&&(b||
d!==a)?d.host:d.parentNode;c[c.length-1]===document&&c.push(window);return c}function Rc(a,b){if(!J)return a;a=ub(a,!0);for(var c=0,d,e,f,h;c<b.length;c++)if(d=b[c],f=d===window?window:d.getRootNode(),f!==e&&(h=a.indexOf(f),e=f),!J(f)||-1<h)return d}function vb(a){function b(b,d){b=new a(b,d);b.ka=d&&!!d.composed;return b}ve(b,a);b.prototype=a.prototype;return b}function Sc(a,b,c){if(c=b.__handlers&&b.__handlers[a.type]&&b.__handlers[a.type][c])for(var d=0,e;(e=c[d])&&a.target!==a.relatedTarget&&
(e.call(b,a),!a.Ua);d++);}function Be(a){var b=a.composedPath();Object.defineProperty(a,"currentTarget",{get:function(){return d},configurable:!0});for(var c=b.length-1;0<=c;c--){var d=b[c];Sc(a,d,"capture");if(a.la)return}Object.defineProperty(a,"eventPhase",{get:function(){return Event.AT_TARGET}});var e;for(c=0;c<b.length;c++){d=b[c];var f=d.__shady&&d.__shady.root;if(0===c||f&&f===e)if(Sc(a,d,"bubble"),d!==window&&(e=d.getRootNode()),a.la)break}}function Tc(a,b,c,d,e,f){for(var h=0;h<a.length;h++){var k=
a[h],m=k.type,g=k.capture,n=k.once,l=k.passive;if(b===k.node&&c===m&&d===g&&e===n&&f===l)return h}return-1}function Uc(a,b,c){if(b){if("object"===typeof c){var d=!!c.capture;var e=!!c.once;var f=!!c.passive}else d=!!c,f=e=!1;var h=c&&c.ma||this,k=b[qa];if(k){if(-1<Tc(k,h,a,d,e,f))return}else b[qa]=[];k=function(d){e&&this.removeEventListener(a,b,c);d.__target||Vc(d);if(h!==this){var f=Object.getOwnPropertyDescriptor(d,"currentTarget");Object.defineProperty(d,"currentTarget",{get:function(){return h},
configurable:!0})}if(d.composed||-1<d.composedPath().indexOf(h))if(d.target===d.relatedTarget)d.eventPhase===Event.BUBBLING_PHASE&&d.stopImmediatePropagation();else if(d.eventPhase===Event.CAPTURING_PHASE||d.bubbles||d.target===h){var k="object"===typeof b&&b.handleEvent?b.handleEvent(d):b.call(h,d);h!==this&&(f?(Object.defineProperty(d,"currentTarget",f),f=null):delete d.currentTarget);return k}};b[qa].push({node:this,type:a,capture:d,once:e,passive:f,yb:k});wb[a]?(this.__handlers=this.__handlers||
{},this.__handlers[a]=this.__handlers[a]||{capture:[],bubble:[]},this.__handlers[a][d?"capture":"bubble"].push(k)):(this instanceof Window?Wc:Xc).call(this,a,k,c)}}function Yc(a,b,c){if(b){if("object"===typeof c){var d=!!c.capture;var e=!!c.once;var f=!!c.passive}else d=!!c,f=e=!1;var h=c&&c.ma||this,k=void 0;var g=null;try{g=b[qa]}catch(q){}g&&(e=Tc(g,h,a,d,e,f),-1<e&&(k=g.splice(e,1)[0].yb,g.length||(b[qa]=void 0)));(this instanceof Window?Zc:$c).call(this,a,k||b,c);k&&wb[a]&&this.__handlers&&this.__handlers[a]&&
(a=this.__handlers[a][d?"capture":"bubble"],k=a.indexOf(k),-1<k&&a.splice(k,1))}}function Ce(){for(var a in wb)window.addEventListener(a,function(a){a.__target||(Vc(a),Be(a))},!0)}function Vc(a){a.__target=a.target;a.Aa=a.relatedTarget;if(G.X){var b=ad,c=Object.getPrototypeOf(a);if(!c.hasOwnProperty("__patchProto")){var d=Object.create(c);d.Ab=c;hb(d,b);c.__patchProto=d}a.__proto__=c.__patchProto}else hb(a,ad)}function ra(a,b){return{index:a,Z:[],ba:b}}function De(a,b,c,d){var e=0,f=0,h=0,k=0,g=Math.min(b-
e,d-f);if(0==e&&0==f)a:{for(h=0;h<g;h++)if(a[h]!==c[h])break a;h=g}if(b==a.length&&d==c.length){k=a.length;for(var q=c.length,n=0;n<g-h&&Ee(a[--k],c[--q]);)n++;k=n}e+=h;f+=h;b-=k;d-=k;if(0==b-e&&0==d-f)return[];if(e==b){for(b=ra(e,0);f<d;)b.Z.push(c[f++]);return[b]}if(f==d)return[ra(e,b-e)];g=e;h=f;d=d-h+1;k=b-g+1;b=Array(d);for(q=0;q<d;q++)b[q]=Array(k),b[q][0]=q;for(q=0;q<k;q++)b[0][q]=q;for(q=1;q<d;q++)for(n=1;n<k;n++)if(a[g+n-1]===c[h+q-1])b[q][n]=b[q-1][n-1];else{var l=b[q-1][n]+1,p=b[q][n-1]+
1;b[q][n]=l<p?l:p}g=b.length-1;h=b[0].length-1;d=b[g][h];for(a=[];0<g||0<h;)0==g?(a.push(2),h--):0==h?(a.push(3),g--):(k=b[g-1][h-1],q=b[g-1][h],n=b[g][h-1],l=q<n?q<k?q:k:n<k?n:k,l==k?(k==d?a.push(0):(a.push(1),d=k),g--,h--):l==q?(a.push(3),g--,d=q):(a.push(2),h--,d=n));a.reverse();b=void 0;g=[];for(h=0;h<a.length;h++)switch(a[h]){case 0:b&&(g.push(b),b=void 0);e++;f++;break;case 1:b||(b=ra(e,0));b.ba++;e++;b.Z.push(c[f]);f++;break;case 2:b||(b=ra(e,0));b.ba++;e++;break;case 3:b||(b=ra(e,0)),b.Z.push(c[f]),
f++}b&&g.push(b);return g}function Ee(a,b){return a===b}function bd(a){var b=[];do b.unshift(a);while(a=a.parentNode);return b}function cd(a){Nc(a);return a.__shady&&a.__shady.assignedSlot||null}function P(a,b){for(var c=Object.getOwnPropertyNames(b),d=0;d<c.length;d++){var e=c[d],f=Object.getOwnPropertyDescriptor(b,e);f.value?a[e]=f.value:Object.defineProperty(a,e,f)}}function Fe(){var a=window.customElements&&window.customElements.nativeHTMLElement||HTMLElement;P(window.Node.prototype,Ge);P(window.Window.prototype,
He);P(window.Text.prototype,Ie);P(window.DocumentFragment.prototype,xb);P(window.Element.prototype,dd);P(window.Document.prototype,ed);window.HTMLSlotElement&&P(window.HTMLSlotElement.prototype,fd);P(a.prototype,Je);G.X&&(U(window.Node.prototype),U(window.Text.prototype),U(window.DocumentFragment.prototype),U(window.Element.prototype),U(a.prototype),U(window.Document.prototype),window.HTMLSlotElement&&U(window.HTMLSlotElement.prototype))}function gd(a){var b=Ke.has(a);a=/^[a-z][.0-9_a-z]*-[\-.0-9_a-z]*$/.test(a);
return!b&&a}function u(a){var b=a.isConnected;if(void 0!==b)return b;for(;a&&!(a.__CE_isImportDocument||a instanceof Document);)a=a.parentNode||(window.ShadowRoot&&a instanceof ShadowRoot?a.host:void 0);return!(!a||!(a.__CE_isImportDocument||a instanceof Document))}function yb(a,b){for(;b&&b!==a&&!b.nextSibling;)b=b.parentNode;return b&&b!==a?b.nextSibling:null}function S(a,b,c){c=c?c:new Set;for(var d=a;d;){if(d.nodeType===Node.ELEMENT_NODE){var e=d;b(e);var f=e.localName;if("link"===f&&"import"===
e.getAttribute("rel")){d=e.import;if(d instanceof Node&&!c.has(d))for(c.add(d),d=d.firstChild;d;d=d.nextSibling)S(d,b,c);d=yb(a,e);continue}else if("template"===f){d=yb(a,e);continue}if(e=e.__CE_shadowRoot)for(e=e.firstChild;e;e=e.nextSibling)S(e,b,c)}d=d.firstChild?d.firstChild:yb(a,d)}}function x(a,b,c){a[b]=c}function zb(a){a=a.replace(I.lb,"").replace(I.port,"");var b=hd,c=a,d=new Pa;d.start=0;d.end=c.length;for(var e=d,f=0,h=c.length;f<h;f++)if("{"===c[f]){e.rules||(e.rules=[]);var k=e,g=k.rules[k.rules.length-
1]||null;e=new Pa;e.start=f+1;e.parent=k;e.previous=g;k.rules.push(e)}else"}"===c[f]&&(e.end=f+1,e=e.parent||d);return b(d,a)}function hd(a,b){var c=b.substring(a.start,a.end-1);a.parsedCssText=a.cssText=c.trim();a.parent&&(c=b.substring(a.previous?a.previous.end:a.parent.start,a.start-1),c=Le(c),c=c.replace(I.La," "),c=c.substring(c.lastIndexOf(";")+1),c=a.parsedSelector=a.selector=c.trim(),a.atRule=0===c.indexOf("@"),a.atRule?0===c.indexOf("@media")?a.type=M.MEDIA_RULE:c.match(I.qb)&&(a.type=M.ja,
a.keyframesName=a.selector.split(I.La).pop()):a.type=0===c.indexOf("--")?M.wa:M.STYLE_RULE);if(c=a.rules)for(var d=0,e=c.length,f;d<e&&(f=c[d]);d++)hd(f,b);return a}function Le(a){return a.replace(/\\([0-9a-f]{1,6})\s/gi,function(a,c){a=c;for(c=6-a.length;c--;)a="0"+a;return"\\"+a})}function id(a,b,c){c=void 0===c?"":c;var d="";if(a.cssText||a.rules){var e=a.rules,f;if(f=e)f=e[0],f=!(f&&f.selector&&0===f.selector.indexOf("--"));if(f){f=0;for(var h=e.length,k;f<h&&(k=e[f]);f++)d=id(k,b,d)}else b?b=
a.cssText:(b=a.cssText,b=b.replace(I.Ga,"").replace(I.Ka,""),b=b.replace(I.rb,"").replace(I.wb,"")),(d=b.trim())&&(d=" "+d+"\n")}d&&(a.selector&&(c+=a.selector+" {\n"),c+=d,a.selector&&(c+="}\n\n"));return c}function jd(a){A=a&&a.shimcssproperties?!1:z||!(navigator.userAgent.match(/AppleWebKit\/601|Edge\/15/)||!window.CSS||!CSS.supports||!CSS.supports("box-shadow","0 0 0 var(--foo)"))}function ea(a,b){if(!a)return"";"string"===typeof a&&(a=zb(a));b&&fa(a,b);return id(a,A)}function Ca(a){!a.__cssRules&&
a.textContent&&(a.__cssRules=zb(a.textContent));return a.__cssRules||null}function kd(a){return!!a.parent&&a.parent.type===M.ja}function fa(a,b,c,d){if(a){var e=!1,f=a.type;if(d&&f===M.MEDIA_RULE){var h=a.selector.match(Me);h&&(window.matchMedia(h[1]).matches||(e=!0))}f===M.STYLE_RULE?b(a):c&&f===M.ja?c(a):f===M.wa&&(e=!0);if((a=a.rules)&&!e){e=0;f=a.length;for(var k;e<f&&(k=a[e]);e++)fa(k,b,c,d)}}}function Ab(a,b,c,d){var e=document.createElement("style");b&&e.setAttribute("scope",b);e.textContent=
a;ld(e,c,d);return e}function ld(a,b,c){b=b||document.head;b.insertBefore(a,c&&c.nextSibling||b.firstChild);V?a.compareDocumentPosition(V)===Node.DOCUMENT_POSITION_PRECEDING&&(V=a):V=a}function md(a,b){var c=a.indexOf("var(");if(-1===c)return b(a,"","","");a:{var d=0;var e=c+3;for(var f=a.length;e<f;e++)if("("===a[e])d++;else if(")"===a[e]&&0===--d)break a;e=-1}d=a.substring(c+4,e);c=a.substring(0,c);a=md(a.substring(e+1),b);e=d.indexOf(",");return-1===e?b(c,d.trim(),"",a):b(c,d.substring(0,e).trim(),
d.substring(e+1).trim(),a)}function Da(a,b){z?a.setAttribute("class",b):window.ShadyDOM.nativeMethods.setAttribute.call(a,"class",b)}function W(a){var b=a.localName,c="";b?-1<b.indexOf("-")||(c=b,b=a.getAttribute&&a.getAttribute("is")||""):(b=a.is,c=a.extends);return{is:b,$:c}}function nd(a){for(var b=0;b<a.length;b++){var c=a[b];if(c.target!==document.documentElement&&c.target!==document.head)for(var d=0;d<c.addedNodes.length;d++){var e=c.addedNodes[d];if(e.nodeType===Node.ELEMENT_NODE){var f=e.getRootNode();
var h=e;var k=[];h.classList?k=Array.from(h.classList):h instanceof window.SVGElement&&h.hasAttribute("class")&&(k=h.getAttribute("class").split(/\s+/));h=k;k=h.indexOf(r.a);if((h=-1<k?h[k+1]:"")&&f===e.ownerDocument)r.b(e,h,!0);else if(f.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&(f=f.host))if(f=W(f).is,h===f)for(e=window.ShadyDOM.nativeMethods.querySelectorAll.call(e,":not(."+r.a+")"),f=0;f<e.length;f++)r.h(e[f],h);else h&&r.b(e,h,!0),r.b(e,f)}}}}function Ne(a){if(a=Ea[a])a._applyShimCurrentVersion=
a._applyShimCurrentVersion||0,a._applyShimValidatingVersion=a._applyShimValidatingVersion||0,a._applyShimNextVersion=(a._applyShimNextVersion||0)+1}function od(a){return a._applyShimCurrentVersion===a._applyShimNextVersion}function Oe(a){a._applyShimValidatingVersion=a._applyShimNextVersion;a.b||(a.b=!0,Pe.then(function(){a._applyShimCurrentVersion=a._applyShimNextVersion;a.b=!1}))}function Rb(a){requestAnimationFrame(function(){pd?pd(a):(Bb||(Bb=new Promise(function(a){Cb=a}),"complete"===document.readyState?
Cb():document.addEventListener("readystatechange",function(){"complete"===document.readyState&&Cb()})),Bb.then(function(){a&&a()}))})}(function(){if(!function(){var a=document.createEvent("Event");a.initEvent("foo",!0,!0);a.preventDefault();return a.defaultPrevented}()){var a=Event.prototype.preventDefault;Event.prototype.preventDefault=function(){this.cancelable&&(a.call(this),Object.defineProperty(this,"defaultPrevented",{get:function(){return!0},configurable:!0}))}}var b=/Trident/.test(navigator.userAgent);
if(!window.CustomEvent||b&&"function"!==typeof window.CustomEvent)window.CustomEvent=function(a,b){b=b||{};var c=document.createEvent("CustomEvent");c.initCustomEvent(a,!!b.bubbles,!!b.cancelable,b.detail);return c},window.CustomEvent.prototype=window.Event.prototype;if(!window.Event||b&&"function"!==typeof window.Event){var c=window.Event;window.Event=function(a,b){b=b||{};var c=document.createEvent("Event");c.initEvent(a,!!b.bubbles,!!b.cancelable);return c};if(c)for(var d in c)window.Event[d]=
c[d];window.Event.prototype=c.prototype}if(!window.MouseEvent||b&&"function"!==typeof window.MouseEvent){b=window.MouseEvent;window.MouseEvent=function(a,b){b=b||{};var c=document.createEvent("MouseEvent");c.initMouseEvent(a,!!b.bubbles,!!b.cancelable,b.view||window,b.detail,b.screenX,b.screenY,b.clientX,b.clientY,b.ctrlKey,b.altKey,b.shiftKey,b.metaKey,b.button,b.relatedTarget);return c};if(b)for(d in b)window.MouseEvent[d]=b[d];window.MouseEvent.prototype=b.prototype}Array.from||(Array.from=function(a){return[].slice.call(a)});
Object.assign||(Object.assign=function(a,b){for(var c=[].slice.call(arguments,1),d=0,e;d<c.length;d++)if(e=c[d])for(var f=a,g=e,l=Object.getOwnPropertyNames(g),p=0;p<l.length;p++)e=l[p],f[e]=g[e];return a})})(window.WebComponents);(function(){function a(){}var b="undefined"===typeof HTMLTemplateElement;/Trident/.test(navigator.userAgent)&&function(){var a=Document.prototype.importNode;Document.prototype.importNode=function(){var b=a.apply(this,arguments);if(b.nodeType===Node.DOCUMENT_FRAGMENT_NODE){var c=
this.createDocumentFragment();c.appendChild(b);return c}return b}}();var c=Node.prototype.cloneNode,d=Document.prototype.createElement,e=Document.prototype.importNode,f=function(){if(!b){var a=document.createElement("template"),c=document.createElement("template");c.content.appendChild(document.createElement("div"));a.content.appendChild(c);a=a.cloneNode(!0);return 0===a.content.childNodes.length||0===a.content.firstChild.content.childNodes.length||!(document.createDocumentFragment().cloneNode()instanceof
DocumentFragment)}}();if(b){var h=function(a){switch(a){case "&":return"&amp;";case "<":return"&lt;";case ">":return"&gt;";case "\u00a0":return"&nbsp;"}},k=function(b){Object.defineProperty(b,"innerHTML",{get:function(){for(var a="",b=this.content.firstChild;b;b=b.nextSibling)a+=b.outerHTML||b.data.replace(u,h);return a},set:function(b){g.body.innerHTML=b;for(a.b(g);this.content.firstChild;)this.content.removeChild(this.content.firstChild);for(;g.body.firstChild;)this.content.appendChild(g.body.firstChild)},
configurable:!0})},g=document.implementation.createHTMLDocument("template"),q=!0,l=document.createElement("style");l.textContent="template{display:none;}";var p=document.head;p.insertBefore(l,p.firstElementChild);a.prototype=Object.create(HTMLElement.prototype);var t=!document.createElement("div").hasOwnProperty("innerHTML");a.R=function(b){if(!b.content){b.content=g.createDocumentFragment();for(var c;c=b.firstChild;)b.content.appendChild(c);if(t)b.__proto__=a.prototype;else if(b.cloneNode=function(b){return a.a(this,
b)},q)try{k(b)}catch(rf){q=!1}a.b(b.content)}};k(a.prototype);a.b=function(b){b=b.querySelectorAll("template");for(var c=0,d=b.length,e;c<d&&(e=b[c]);c++)a.R(e)};document.addEventListener("DOMContentLoaded",function(){a.b(document)});Document.prototype.createElement=function(){var b=d.apply(this,arguments);"template"===b.localName&&a.R(b);return b};var u=/[&\u00A0<>]/g}if(b||f)a.a=function(a,b){var d=c.call(a,!1);this.R&&this.R(d);b&&(d.content.appendChild(c.call(a.content,!0)),this.ta(d.content,
a.content));return d},a.prototype.cloneNode=function(b){return a.a(this,b)},a.ta=function(a,b){if(b.querySelectorAll){b=b.querySelectorAll("template");a=a.querySelectorAll("template");for(var c=0,d=a.length,e,f;c<d;c++)f=b[c],e=a[c],this.R&&this.R(f),e.parentNode.replaceChild(f.cloneNode(!0),e)}},Node.prototype.cloneNode=function(b){if(this instanceof DocumentFragment)if(b)var d=this.ownerDocument.importNode(this,!0);else return this.ownerDocument.createDocumentFragment();else d=c.call(this,b);b&&
a.ta(d,this);return d},Document.prototype.importNode=function(b,c){if("template"===b.localName)return a.a(b,c);var d=e.call(this,b,c);c&&a.ta(d,b);return d},f&&(window.HTMLTemplateElement.prototype.cloneNode=function(b){return a.a(this,b)});b&&(window.HTMLTemplateElement=a)})();var Db;Array.isArray?Db=Array.isArray:Db=function(a){return"[object Array]"===Object.prototype.toString.call(a)};var nc=Db,Z=0,ab,$a,qd="undefined"!==typeof window?window:void 0,rd=qd||{},gc=rd.MutationObserver||rd.WebKitMutationObserver,
Qe="undefined"!==typeof Uint8ClampedArray&&"undefined"!==typeof importScripts&&"undefined"!==typeof MessageChannel,Y=Array(1E3);var ke="undefined"===typeof self&&"undefined"!==typeof process&&"[object process]"==={}.toString.call(process)?le():gc?ne():Qe?oe():qd||"function"!==typeof require?bb():pe();var ya=Math.random().toString(36).substring(16),ka=new lc,gb=new lc,mc=0;la.prototype.cb=function(a){for(var b=0;void 0===this.o&&b<a.length;b++)this.bb(a[b],b)};la.prototype.bb=function(a,b){var c=this.eb,
d=c.resolve;d===eb?(d=jc(a),d===cb&&void 0!==a.o?this.pa(a.o,b,a.m):"function"!==typeof d?(this.aa--,this.m[b]=a):c===D?(c=new c(ba),kc(c,a,d),this.qa(c,b)):this.qa(new c(function(b){return b(a)}),b)):this.qa(d(a),b)};la.prototype.pa=function(a,b,c){var d=this.L;void 0===d.o&&(this.aa--,2===a?C(d,c):this.m[b]=c);0===this.aa&&L(d,this.m)};la.prototype.qa=function(a,b){var c=this;db(a,void 0,function(a){return c.pa(1,b,a)},function(a){return c.pa(2,b,a)})};D.all=function(a){return(new la(this,a)).L};
D.race=function(a){var b=this;return nc(a)?new b(function(c,d){for(var e=a.length,f=0;f<e;f++)b.resolve(a[f]).then(c,d)}):new b(function(a,b){return b(new TypeError("You must pass an array to race."))})};D.resolve=eb;D.reject=function(a){var b=new this(ba);C(b,a);return b};D.Fb=function(a){$a=a};D.Eb=function(a){T=a};D.Bb=T;D.prototype={constructor:D,then:cb,a:function(a){return this.then(null,a)}};window.Promise||(window.Promise=D,D.prototype["catch"]=D.prototype.a);(function(a){function b(a,b){if("function"===
typeof window.CustomEvent)return new CustomEvent(a,b);var c=document.createEvent("CustomEvent");c.initCustomEvent(a,!!b.bubbles,!!b.cancelable,b.detail);return c}function c(a){if(n)return a.ownerDocument!==document?a.ownerDocument:null;var b=a.__importDoc;if(!b&&a.parentNode){b=a.parentNode;if("function"===typeof b.closest)b=b.closest("link[rel=import]");else for(;!g(b)&&(b=b.parentNode););a.__importDoc=b}return b}function d(a){var b=document.querySelectorAll("link[rel=import]:not([import-dependency])"),
c=b.length;c?l(b,function(b){return h(b,function(){0===--c&&a()})}):a()}function e(a){function b(){"loading"!==document.readyState&&document.body&&(document.removeEventListener("readystatechange",b),a())}document.addEventListener("readystatechange",b);b()}function f(a){e(function(){return d(function(){return a&&a()})})}function h(a,b){if(a.__loaded)b&&b();else if("script"===a.localName&&!a.src||"style"===a.localName&&!a.firstChild)a.__loaded=!0,b&&b();else{var c=function(d){a.removeEventListener(d.type,
c);a.__loaded=!0;b&&b()};a.addEventListener("load",c);z&&"style"===a.localName||a.addEventListener("error",c)}}function g(a){return a.nodeType===Node.ELEMENT_NODE&&"link"===a.localName&&"import"===a.rel}function m(){var a=this;this.a={};this.b=0;this.f=new MutationObserver(function(b){return a.l(b)});this.f.observe(document.head,{childList:!0,subtree:!0});this.c(document)}function l(a,b,c){var d=a?a.length:0,e=c?-1:1;for(c=c?d-1:0;c<d&&0<=c;c+=e)b(a[c],c)}var n="import"in document.createElement("link"),
p=null;!1==="currentScript"in document&&Object.defineProperty(document,"currentScript",{get:function(){return p||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null)},configurable:!0});var t=/(url\()([^)]*)(\))/g,u=/(@import[\s]+(?!url\())([^;]*)(;)/g,v=/(<link[^>]*)(rel=['|"]?stylesheet['|"]?[^>]*>)/g,r={mb:function(a,b){a.href&&a.setAttribute("href",r.fa(a.getAttribute("href"),b));a.src&&a.setAttribute("src",r.fa(a.getAttribute("src"),b));if("style"===a.localName){var c=
r.Ma(a.textContent,b,t);a.textContent=r.Ma(c,b,u)}},Ma:function(a,b,c){return a.replace(c,function(a,c,d,e){a=d.replace(/["']/g,"");b&&(a=r.fa(a,b));return c+"'"+a+"'"+e})},fa:function(a,b){if(void 0===r.na){r.na=!1;try{var c=new URL("b","http://a");c.pathname="c%20d";r.na="http://a/c%20d"===c.href}catch(sf){}}if(r.na)return(new URL(a,b)).href;c=r.Za;c||(c=document.implementation.createHTMLDocument("temp"),r.Za=c,c.ya=c.createElement("base"),c.head.appendChild(c.ya),c.xa=c.createElement("a"));c.ya.href=
b;c.xa.href=a;return c.xa.href||a}},w={async:!0,load:function(a,b,c){if(a)if(a.match(/^data:/)){a=a.split(",");var d=a[1];d=-1<a[0].indexOf(";base64")?atob(d):decodeURIComponent(d);b(d)}else{var e=new XMLHttpRequest;e.open("GET",a,w.async);e.onload=function(){var a=e.responseURL||e.getResponseHeader("Location");a&&0===a.indexOf("/")&&(a=(location.origin||location.protocol+"//"+location.host)+a);var d=e.response||e.responseText;304===e.status||0===e.status||200<=e.status&&300>e.status?b(d,a):c(d)};
e.send()}else c("error: href must be specified")}},z=/Trident/.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent);m.prototype.c=function(a){var b=this;a=a.querySelectorAll("link[rel=import]");l(a,function(a){return b.h(a)})};m.prototype.h=function(a){var b=this,c=a.href;if(void 0!==this.a[c]){var d=this.a[c];d&&d.__loaded&&(a.import=d,this.g(a))}else this.b++,this.a[c]="pending",w.load(c,function(a,d){a=b.s(a,d||c);b.a[c]=a;b.b--;b.c(a);b.i()},function(){b.a[c]=null;b.b--;b.i()})};
m.prototype.s=function(a,b){if(!a)return document.createDocumentFragment();z&&(a=a.replace(v,function(a,b,c){return-1===a.indexOf("type=")?b+" type=import-disable "+c:a}));var c=document.createElement("template");c.innerHTML=a;if(c.content)a=c.content;else for(a=document.createDocumentFragment();c.firstChild;)a.appendChild(c.firstChild);if(c=a.querySelector("base"))b=r.fa(c.getAttribute("href"),b),c.removeAttribute("href");c=a.querySelectorAll('link[rel=import], link[rel=stylesheet][href][type=import-disable],\n style:not([type]), link[rel=stylesheet][href]:not([type]),\n script:not([type]), script[type="application/javascript"],\n script[type="text/javascript"]');
var d=0;l(c,function(a){h(a);r.mb(a,b);a.setAttribute("import-dependency","");"script"===a.localName&&!a.src&&a.textContent&&(a.setAttribute("src","data:text/javascript;charset=utf-8,"+encodeURIComponent(a.textContent+("\n//# sourceURL="+b+(d?"-"+d:"")+".js\n"))),a.textContent="",d++)});return a};m.prototype.i=function(){var a=this;if(!this.b){this.f.disconnect();this.flatten(document);var b=!1,c=!1,d=function(){c&&b&&(a.c(document),a.b||(a.f.observe(document.head,{childList:!0,subtree:!0}),a.j()))};
this.v(function(){c=!0;d()});this.u(function(){b=!0;d()})}};m.prototype.flatten=function(a){var b=this;a=a.querySelectorAll("link[rel=import]");l(a,function(a){var c=b.a[a.href];(a.import=c)&&c.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&(b.a[a.href]=a,a.readyState="loading",a.import=a,b.flatten(c),a.appendChild(c))})};m.prototype.u=function(a){function b(e){if(e<d){var f=c[e],g=document.createElement("script");f.removeAttribute("import-dependency");l(f.attributes,function(a){return g.setAttribute(a.name,
a.value)});p=g;f.parentNode.replaceChild(g,f);h(g,function(){p=null;b(e+1)})}else a()}var c=document.querySelectorAll("script[import-dependency]"),d=c.length;b(0)};m.prototype.v=function(a){var b=document.querySelectorAll("style[import-dependency],\n link[rel=stylesheet][import-dependency]"),d=b.length;if(d){var e=z&&!!document.querySelector("link[rel=stylesheet][href][type=import-disable]");l(b,function(b){h(b,function(){b.removeAttribute("import-dependency");0===--d&&a()});if(e&&b.parentNode!==
document.head){var f=document.createElement(b.localName);f.__appliedElement=b;f.setAttribute("type","import-placeholder");b.parentNode.insertBefore(f,b.nextSibling);for(f=c(b);f&&c(f);)f=c(f);f.parentNode!==document.head&&(f=null);document.head.insertBefore(b,f);b.removeAttribute("type")}})}else a()};m.prototype.j=function(){var a=this,b=document.querySelectorAll("link[rel=import]");l(b,function(b){return a.g(b)},!0)};m.prototype.g=function(a){a.__loaded||(a.__loaded=!0,a.import&&(a.import.readyState=
"complete"),a.dispatchEvent(b(a.import?"load":"error",{bubbles:!1,cancelable:!1,detail:void 0})))};m.prototype.l=function(a){var b=this;l(a,function(a){return l(a.addedNodes,function(a){a&&a.nodeType===Node.ELEMENT_NODE&&(g(a)?b.h(a):b.c(a))})})};if(n){var x=document.querySelectorAll("link[rel=import]");l(x,function(a){a.import&&"loading"===a.import.readyState||(a.__loaded=!0)});x=function(a){a=a.target;g(a)&&(a.__loaded=!0)};document.addEventListener("load",x,!0);document.addEventListener("error",
x,!0)}else{var y=Object.getOwnPropertyDescriptor(Node.prototype,"baseURI");Object.defineProperty((!y||y.configurable?Node:Element).prototype,"baseURI",{get:function(){var a=g(this)?this:c(this);return a?a.href:y&&y.get?y.get.call(this):(document.querySelector("base")||window.location).href},configurable:!0,enumerable:!0});e(function(){return new m})}f(function(){return document.dispatchEvent(b("HTMLImportsLoaded",{cancelable:!0,bubbles:!0,detail:void 0}))});a.useNative=n;a.whenReady=f;a.importForElement=
c})(window.HTMLImports=window.HTMLImports||{});window.WebComponents=window.WebComponents||{flags:{}};var sd=document.querySelector('script[src*="webcomponents-lite.js"]'),Re=/wc-(.+)/,H={};if(!H.noOpts){location.search.slice(1).split("&").forEach(function(a){a=a.split("=");var b;a[0]&&(b=a[0].match(Re))&&(H[b[1]]=a[1]||!0)});if(sd)for(var td=0,Fa;Fa=sd.attributes[td];td++)"src"!==Fa.name&&(H[Fa.name]=Fa.value||!0);if(H.log&&H.log.split){var Se=H.log.split(",");H.log={};Se.forEach(function(a){H.log[a]=
!0})}else H.log={}}window.WebComponents.flags=H;var ud=H.shadydom;ud&&(window.ShadyDOM=window.ShadyDOM||{},window.ShadyDOM.force=ud);var vd=H.register||H.ce;vd&&window.customElements&&(window.customElements.forcePolyfill=vd);var G=window.ShadyDOM||{};G.nb=!(!Element.prototype.attachShadow||!Node.prototype.getRootNode);var Eb=Object.getOwnPropertyDescriptor(Node.prototype,"firstChild");G.X=!!(Eb&&Eb.configurable&&Eb.get);G.Ja=G.force||!G.nb;var ha=Element.prototype,wd=ha.matches||ha.matchesSelector||
ha.mozMatchesSelector||ha.msMatchesSelector||ha.oMatchesSelector||ha.webkitMatchesSelector,kb=document.createTextNode(""),pc=0,jb=[];(new MutationObserver(function(){for(;jb.length;)try{jb.shift()()}catch(a){throw kb.textContent=pc++,a;}})).observe(kb,{characterData:!0});var Te=!!document.contains,na=[],lb;za.list=na;xa.prototype.ub=function(){var a=this;this.a||(this.a=!0,oc(function(){a.b()}))};xa.prototype.b=function(){if(this.a){this.a=!1;var a=this.takeRecords();a.length&&this.ca.forEach(function(b){b(a)})}};
xa.prototype.takeRecords=function(){if(this.addedNodes.length||this.removedNodes.length){var a=[{addedNodes:this.addedNodes,removedNodes:this.removedNodes}];this.addedNodes=[];this.removedNodes=[];return a}return[]};var Hc=Element.prototype.appendChild,sb=Element.prototype.insertBefore,oa=Element.prototype.removeChild,Pc=Element.prototype.setAttribute,xd=Element.prototype.removeAttribute,Fb=Element.prototype.cloneNode,tb=Document.prototype.importNode,Xc=Element.prototype.addEventListener,$c=Element.prototype.removeEventListener,
Wc=Window.prototype.addEventListener,Zc=Window.prototype.removeEventListener,Gb=Element.prototype.dispatchEvent,pa=Node.prototype.contains||HTMLElement.prototype.contains,Ue=Object.freeze({appendChild:Hc,insertBefore:sb,removeChild:oa,setAttribute:Pc,removeAttribute:xd,cloneNode:Fb,importNode:tb,addEventListener:Xc,removeEventListener:$c,Kb:Wc,Lb:Zc,dispatchEvent:Gb,querySelector:Element.prototype.querySelector,querySelectorAll:Element.prototype.querySelectorAll,contains:pa}),xe=/[&\u00A0"]/g,Ae=
/[&\u00A0<>]/g,ye=tc("area base br col command embed hr img input keygen link meta param source track wbr".split(" ")),ze=tc("style script xmp iframe noembed noframes plaintext noscript".split(" ")),E=document.createTreeWalker(document,NodeFilter.SHOW_ALL,null,!1),F=document.createTreeWalker(document,NodeFilter.SHOW_ELEMENT,null,!1),Ve=Object.freeze({parentNode:da,firstChild:Ya,lastChild:Za,previousSibling:uc,nextSibling:vc,childNodes:X,parentElement:wc,firstElementChild:xc,lastElementChild:yc,previousElementSibling:zc,
nextElementSibling:Ac,children:Bc,innerHTML:Cc,textContent:Dc}),Hb=Object.getOwnPropertyDescriptor(Element.prototype,"innerHTML")||Object.getOwnPropertyDescriptor(HTMLElement.prototype,"innerHTML"),Ga=document.implementation.createHTMLDocument("inert").createElement("div"),Ib=Object.getOwnPropertyDescriptor(Document.prototype,"activeElement"),Ec={parentElement:{get:function(){var a=this.__shady&&this.__shady.parentNode;a&&a.nodeType!==Node.ELEMENT_NODE&&(a=null);return void 0!==a?a:wc(this)},configurable:!0},
parentNode:{get:function(){var a=this.__shady&&this.__shady.parentNode;return void 0!==a?a:da(this)},configurable:!0},nextSibling:{get:function(){var a=this.__shady&&this.__shady.nextSibling;return void 0!==a?a:vc(this)},configurable:!0},previousSibling:{get:function(){var a=this.__shady&&this.__shady.previousSibling;return void 0!==a?a:uc(this)},configurable:!0},className:{get:function(){return this.getAttribute("class")||""},set:function(a){this.setAttribute("class",a)},configurable:!0},nextElementSibling:{get:function(){if(this.__shady&&
void 0!==this.__shady.nextSibling){for(var a=this.nextSibling;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.nextSibling;return a}return Ac(this)},configurable:!0},previousElementSibling:{get:function(){if(this.__shady&&void 0!==this.__shady.previousSibling){for(var a=this.previousSibling;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}return zc(this)},configurable:!0}},nb={childNodes:{get:function(){if(ca(this)){if(!this.__shady.childNodes){this.__shady.childNodes=[];for(var a=this.firstChild;a;a=
a.nextSibling)this.__shady.childNodes.push(a)}var b=this.__shady.childNodes}else b=X(this);b.item=function(a){return b[a]};return b},configurable:!0},childElementCount:{get:function(){return this.children.length},configurable:!0},firstChild:{get:function(){var a=this.__shady&&this.__shady.firstChild;return void 0!==a?a:Ya(this)},configurable:!0},lastChild:{get:function(){var a=this.__shady&&this.__shady.lastChild;return void 0!==a?a:Za(this)},configurable:!0},textContent:{get:function(){if(ca(this)){for(var a=
[],b=0,c=this.childNodes,d;d=c[b];b++)d.nodeType!==Node.COMMENT_NODE&&a.push(d.textContent);return a.join("")}return Dc(this)},set:function(a){switch(this.nodeType){case Node.ELEMENT_NODE:case Node.DOCUMENT_FRAGMENT_NODE:for(;this.firstChild;)this.removeChild(this.firstChild);(0<a.length||this.nodeType===Node.ELEMENT_NODE)&&this.appendChild(document.createTextNode(a));break;default:this.nodeValue=a}},configurable:!0},firstElementChild:{get:function(){if(this.__shady&&void 0!==this.__shady.firstChild){for(var a=
this.firstChild;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.nextSibling;return a}return xc(this)},configurable:!0},lastElementChild:{get:function(){if(this.__shady&&void 0!==this.__shady.lastChild){for(var a=this.lastChild;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}return yc(this)},configurable:!0},children:{get:function(){var a;ca(this)?a=Array.prototype.filter.call(this.childNodes,function(a){return a.nodeType===Node.ELEMENT_NODE}):a=Bc(this);a.item=function(b){return a[b]};return a},
configurable:!0},innerHTML:{get:function(){var a="template"===this.localName?this.content:this;return ca(this)?mb(a):Cc(a)},set:function(a){for(var b="template"===this.localName?this.content:this;b.firstChild;)b.removeChild(b.firstChild);for(Hb&&Hb.set?Hb.set.call(Ga,a):Ga.innerHTML=a;Ga.firstChild;)b.appendChild(Ga.firstChild)},configurable:!0}},yd={shadowRoot:{get:function(){return this.__shady&&this.__shady.sb||null},configurable:!0}},ob={activeElement:{get:function(){var a=Ib&&Ib.get?Ib.get.call(document):
G.X?void 0:document.activeElement;if(a&&a.nodeType){var b=!!J(this);if(this===document||b&&this.host!==a&&pa.call(this.host,a)){for(b=ma(a);b&&b!==this;)a=b.host,b=ma(a);a=this===document?b?null:a:b===this?a:null}else a=null}else a=null;return a},set:function(){},configurable:!0}},fc=G.X?function(){}:function(a){a.__shady&&a.__shady.Xa||(a.__shady=a.__shady||{},a.__shady.Xa=!0,O(a,Ec,!0))},ec=G.X?function(){}:function(a){a.__shady&&a.__shady.Va||(a.__shady=a.__shady||{},a.__shady.Va=!0,O(a,nb,!0),
O(a,yd,!0))},Ba=null,qa="__eventWrappers"+Date.now(),We={blur:!0,focus:!0,focusin:!0,focusout:!0,click:!0,dblclick:!0,mousedown:!0,mouseenter:!0,mouseleave:!0,mousemove:!0,mouseout:!0,mouseover:!0,mouseup:!0,wheel:!0,beforeinput:!0,input:!0,keydown:!0,keyup:!0,compositionstart:!0,compositionupdate:!0,compositionend:!0,touchstart:!0,touchend:!0,touchmove:!0,touchcancel:!0,pointerover:!0,pointerenter:!0,pointerdown:!0,pointermove:!0,pointerup:!0,pointercancel:!0,pointerout:!0,pointerleave:!0,gotpointercapture:!0,
lostpointercapture:!0,dragstart:!0,drag:!0,dragenter:!0,dragleave:!0,dragover:!0,drop:!0,dragend:!0,DOMActivate:!0,DOMFocusIn:!0,DOMFocusOut:!0,keypress:!0},ad={get composed(){!1!==this.isTrusted&&void 0===this.ka&&(this.ka=We[this.type]);return this.ka||!1},composedPath:function(){this.za||(this.za=ub(this.__target,this.composed));return this.za},get target(){return Rc(this.currentTarget,this.composedPath())},get relatedTarget(){if(!this.Aa)return null;this.Ba||(this.Ba=ub(this.Aa,!0));return Rc(this.currentTarget,
this.Ba)},stopPropagation:function(){Event.prototype.stopPropagation.call(this);this.la=!0},stopImmediatePropagation:function(){Event.prototype.stopImmediatePropagation.call(this);this.la=this.Ua=!0}},wb={focus:!0,blur:!0},Xe=vb(window.Event),Ye=vb(window.CustomEvent),Ze=vb(window.MouseEvent),dc={};l.prototype=Object.create(DocumentFragment.prototype);l.prototype.H=function(a,b){this.Wa="ShadyRoot";wa(a);wa(this);this.host=a;this.J=b&&b.mode;a.__shady=a.__shady||{};a.__shady.root=this;a.__shady.sb=
"closed"!==this.J?this:null;this.U=!1;this.b=[];this.a={};this.c=[];b=X(a);for(var c=0,d=b.length;c<d;c++)oa.call(a,b[c])};l.prototype.O=function(){var a=this;this.U||(this.U=!0,rc(function(){return a.Fa()}))};l.prototype.N=function(){for(var a=this,b=this;b;)b.U&&(a=b),b=b.hb();return a};l.prototype.hb=function(){var a=this.host.getRootNode();if(J(a))for(var b=this.host.childNodes,c=0,d;c<b.length;c++)if(d=b[c],this.j(d))return a};l.prototype.Fa=function(){this.U&&this.N()._renderRoot()};l.prototype._renderRoot=
function(){this.U=!1;this.D();this.v()};l.prototype.D=function(){this.f();for(var a=0,b;a<this.b.length;a++)b=this.b[a],this.u(b);for(b=this.host.firstChild;b;b=b.nextSibling)this.h(b);for(a=0;a<this.b.length;a++){b=this.b[a];if(!b.__shady.assignedNodes.length)for(var c=b.firstChild;c;c=c.nextSibling)this.h(c,b);c=b.parentNode;(c=c.__shady&&c.__shady.root)&&c.Ca()&&c._renderRoot();this.g(b.__shady.W,b.__shady.assignedNodes);if(c=b.__shady.Ea){for(var d=0;d<c.length;d++)c[d].__shady.oa=null;b.__shady.Ea=
null;c.length>b.__shady.assignedNodes.length&&(b.__shady.sa=!0)}b.__shady.sa&&(b.__shady.sa=!1,this.i(b))}};l.prototype.h=function(a,b){a.__shady=a.__shady||{};var c=a.__shady.oa;a.__shady.oa=null;b||(b=(b=this.a[a.slot||"__catchall"])&&b[0]);b?(b.__shady.assignedNodes.push(a),a.__shady.assignedSlot=b):a.__shady.assignedSlot=void 0;c!==a.__shady.assignedSlot&&a.__shady.assignedSlot&&(a.__shady.assignedSlot.__shady.sa=!0)};l.prototype.u=function(a){var b=a.__shady.assignedNodes;a.__shady.assignedNodes=
[];a.__shady.W=[];if(a.__shady.Ea=b)for(var c=0;c<b.length;c++){var d=b[c];d.__shady.oa=d.__shady.assignedSlot;d.__shady.assignedSlot===a&&(d.__shady.assignedSlot=null)}};l.prototype.g=function(a,b){for(var c=0,d;c<b.length&&(d=b[c]);c++)"slot"==d.localName?this.g(a,d.__shady.assignedNodes):a.push(b[c])};l.prototype.i=function(a){Gb.call(a,new Event("slotchange"));a.__shady.assignedSlot&&this.i(a.__shady.assignedSlot)};l.prototype.v=function(){for(var a=this.b,b=[],c=0;c<a.length;c++){var d=a[c].parentNode;
d.__shady&&d.__shady.root||!(0>b.indexOf(d))||b.push(d)}for(a=0;a<b.length;a++)c=b[a],this.T(c===this?this.host:c,this.B(c))};l.prototype.B=function(a){var b=[];a=a.childNodes;for(var c=0;c<a.length;c++){var d=a[c];if(this.j(d)){d=d.__shady.W;for(var e=0;e<d.length;e++)b.push(d[e])}else b.push(d)}return b};l.prototype.j=function(a){return"slot"==a.localName};l.prototype.T=function(a,b){for(var c=X(a),d=De(b,b.length,c,c.length),e=0,f=0,h;e<d.length&&(h=d[e]);e++){for(var g=0,m;g<h.Z.length&&(m=h.Z[g]);g++)da(m)===
a&&oa.call(a,m),c.splice(h.index+f,1);f-=h.ba}for(e=0;e<d.length&&(h=d[e]);e++)for(f=c[h.index],g=h.index;g<h.index+h.ba;g++)m=b[g],sb.call(a,m,f),c.splice(g,0,m)};l.prototype.$a=function(a){this.c.push.apply(this.c,[].concat(a instanceof Array?a:Sd(Rd(a))))};l.prototype.f=function(){this.c.length&&(this.I(this.c),this.c=[])};l.prototype.I=function(a){for(var b,c=0;c<a.length;c++){var d=a[c];d.__shady=d.__shady||{};wa(d);wa(d.parentNode);var e=this.l(d);this.a[e]?(b=b||{},b[e]=!0,this.a[e].push(d)):
this.a[e]=[d];this.b.push(d)}if(b)for(var f in b)this.a[f]=this.s(this.a[f])};l.prototype.l=function(a){var b=a.name||a.getAttribute("name")||"__catchall";return a.Ya=b};l.prototype.s=function(a){return a.sort(function(a,c){a=bd(a);for(var b=bd(c),e=0;e<a.length;e++){c=a[e];var f=b[e];if(c!==f)return a=Array.from(c.parentNode.childNodes),a.indexOf(c)-a.indexOf(f)}})};l.prototype.gb=function(a){this.f();var b=this.a,c;for(c in b)for(var d=b[c],e=0;e<d.length;e++){var f=d[e];if(qc(a,f)){d.splice(e,
1);var h=this.b.indexOf(f);0<=h&&this.b.splice(h,1);e--;this.K(f);h=!0}}return h};l.prototype.ib=function(a){var b=a.Ya,c=this.l(a);if(c!==b){b=this.a[b];var d=b.indexOf(a);0<=d&&b.splice(d,1);b=this.a[c]||(this.a[c]=[]);b.push(a);1<b.length&&(this.a[c]=this.s(b))}};l.prototype.K=function(a){if(a=a.__shady.W)for(var b=0;b<a.length;b++){var c=a[b],d=da(c);d&&oa.call(d,c)}};l.prototype.Ca=function(){this.f();return!!this.b.length};l.prototype.addEventListener=function(a,b,c){"object"!==typeof c&&(c=
{capture:!!c});c.ma=this;this.host.addEventListener(a,b,c)};l.prototype.removeEventListener=function(a,b,c){"object"!==typeof c&&(c={capture:!!c});c.ma=this;this.host.removeEventListener(a,b,c)};l.prototype.getElementById=function(a){return Aa(this,function(b){return b.id==a},function(a){return!!a})[0]||null};(function(a){O(a,nb,!0);O(a,ob,!0)})(l.prototype);var He={addEventListener:Uc.bind(window),removeEventListener:Yc.bind(window)},Ge={addEventListener:Uc,removeEventListener:Yc,appendChild:function(a){return pb(this,
a)},insertBefore:function(a,b){return pb(this,a,b)},removeChild:function(a){return qb(this,a)},replaceChild:function(a,b){pb(this,a,b);qb(this,b);return a},cloneNode:function(a){if("template"==this.localName)var b=Fb.call(this,a);else if(b=Fb.call(this,!1),a){a=this.childNodes;for(var c=0,d;c<a.length;c++)d=a[c].cloneNode(!0),b.appendChild(d)}return b},getRootNode:function(){return Lc(this)},contains:function(a){return qc(this,a)},get isConnected(){var a=this.ownerDocument;if(Te&&pa.call(a,this)||
a.documentElement&&pa.call(a.documentElement,this))return!0;for(a=this;a&&!(a instanceof Document);)a=a.parentNode||(a instanceof l?a.host:void 0);return!!(a&&a instanceof Document)},dispatchEvent:function(a){za();return Gb.call(this,a)}},Ie={get assignedSlot(){return cd(this)}},xb={querySelector:function(a){return Aa(this,function(b){return wd.call(b,a)},function(a){return!!a})[0]||null},querySelectorAll:function(a){return Aa(this,function(b){return wd.call(b,a)})}},fd={assignedNodes:function(a){if("slot"===
this.localName)return Nc(this),this.__shady?(a&&a.flatten?this.__shady.W:this.__shady.assignedNodes)||[]:[]}},dd=ib({setAttribute:function(a,b){Oc(this,a,b)},removeAttribute:function(a){xd.call(this,a);Kc(this,a)},attachShadow:function(a){if(!this)throw"Must provide a host.";if(!a)throw"Not enough arguments.";return new l(dc,this,a)},get slot(){return this.getAttribute("slot")},set slot(a){Oc(this,"slot",a)},get assignedSlot(){return cd(this)}},xb,fd);Object.defineProperties(dd,yd);var ed=ib({importNode:function(a,
b){return Qc(a,b)},getElementById:function(a){return Aa(this,function(b){return b.id==a},function(a){return!!a})[0]||null}},xb);Object.defineProperties(ed,{_activeElement:ob.activeElement});var $e=HTMLElement.prototype.blur,Je=ib({blur:function(){var a=this.__shady&&this.__shady.root;(a=a&&a.activeElement)?a.blur():$e.call(this)}});G.Ja&&(window.ShadyDOM={inUse:G.Ja,patch:function(a){return a},isShadyRoot:J,enqueue:rc,flush:za,settings:G,filterMutations:we,observeChildren:je,unobserveChildren:ie,
nativeMethods:Ue,nativeTree:Ve},window.Event=Xe,window.CustomEvent=Ye,window.MouseEvent=Ze,Ce(),Fe(),window.ShadowRoot=l);var Ke=new Set("annotation-xml color-profile font-face font-face-src font-face-uri font-face-format font-face-name missing-glyph".split(" "));B.prototype.D=function(a,b){this.u.set(a,b);this.s.set(b.constructor,b)};B.prototype.c=function(a){return this.u.get(a)};B.prototype.B=function(a){return this.s.get(a)};B.prototype.v=function(a){this.h=!0;this.j.push(a)};B.prototype.l=function(a){var b=
this;this.h&&S(a,function(a){return b.g(a)})};B.prototype.g=function(a){if(this.h&&!a.__CE_patched){a.__CE_patched=!0;for(var b=0;b<this.j.length;b++)this.j[b](a)}};B.prototype.b=function(a){var b=[];S(a,function(a){return b.push(a)});for(a=0;a<b.length;a++){var c=b[a];1===c.__CE_state?this.connectedCallback(c):this.i(c)}};B.prototype.a=function(a){var b=[];S(a,function(a){return b.push(a)});for(a=0;a<b.length;a++){var c=b[a];1===c.__CE_state&&this.disconnectedCallback(c)}};B.prototype.f=function(a,
b){var c=this;b=b?b:{};var d=b.xb||new Set,e=b.Na||function(a){return c.i(a)},f=[];S(a,function(a){if("link"===a.localName&&"import"===a.getAttribute("rel")){var b=a.import;b instanceof Node&&"complete"===b.readyState?(b.__CE_isImportDocument=!0,b.__CE_hasRegistry=!0):a.addEventListener("load",function(){var b=a.import;if(!b.__CE_documentLoadHandled){b.__CE_documentLoadHandled=!0;b.__CE_isImportDocument=!0;b.__CE_hasRegistry=!0;var f=new Set(d);f.delete(b);c.f(b,{xb:f,Na:e})}})}else f.push(a)},d);
if(this.h)for(a=0;a<f.length;a++)this.g(f[a]);for(a=0;a<f.length;a++)e(f[a])};B.prototype.i=function(a){if(void 0===a.__CE_state){var b=this.c(a.localName);if(b){b.constructionStack.push(a);var c=b.constructor;try{try{if(new c!==a)throw Error("The custom element constructor did not produce the element being upgraded.");}finally{b.constructionStack.pop()}}catch(f){throw a.__CE_state=2,f;}a.__CE_state=1;a.__CE_definition=b;if(b.attributeChangedCallback)for(b=b.observedAttributes,c=0;c<b.length;c++){var d=
b[c],e=a.getAttribute(d);null!==e&&this.attributeChangedCallback(a,d,null,e,null)}u(a)&&this.connectedCallback(a)}}};B.prototype.connectedCallback=function(a){var b=a.__CE_definition;b.connectedCallback&&b.connectedCallback.call(a)};B.prototype.disconnectedCallback=function(a){var b=a.__CE_definition;b.disconnectedCallback&&b.disconnectedCallback.call(a)};B.prototype.attributeChangedCallback=function(a,b,c,d,e){var f=a.__CE_definition;f.attributeChangedCallback&&-1<f.observedAttributes.indexOf(b)&&
f.attributeChangedCallback.call(a,b,c,d,e)};Xa.prototype.c=function(){this.P&&this.P.disconnect()};Xa.prototype.f=function(a){var b=this.a.readyState;"interactive"!==b&&"complete"!==b||this.c();for(b=0;b<a.length;b++)for(var c=a[b].addedNodes,d=0;d<c.length;d++)this.b.f(c[d])};cc.prototype.resolve=function(a){if(this.a)throw Error("Already resolved.");this.a=a;this.b&&this.b(a)};y.prototype.define=function(a,b){var c=this;if(!(b instanceof Function))throw new TypeError("Custom element constructors must be functions.");
if(!gd(a))throw new SyntaxError("The element name '"+a+"' is not valid.");if(this.a.c(a))throw Error("A custom element with name '"+a+"' has already been defined.");if(this.c)throw Error("A custom element is already being defined.");this.c=!0;try{var d=function(a){var b=e[a];if(void 0!==b&&!(b instanceof Function))throw Error("The '"+a+"' callback must be a function.");return b},e=b.prototype;if(!(e instanceof Object))throw new TypeError("The custom element constructor's prototype is not an object.");
var f=d("connectedCallback");var g=d("disconnectedCallback");var k=d("adoptedCallback");var l=d("attributeChangedCallback");var q=b.observedAttributes||[]}catch(n){return}finally{this.c=!1}b={localName:a,constructor:b,connectedCallback:f,disconnectedCallback:g,adoptedCallback:k,attributeChangedCallback:l,observedAttributes:q,constructionStack:[]};this.a.D(a,b);this.g.push(b);this.b||(this.b=!0,this.f(function(){return c.j()}))};y.prototype.j=function(){var a=this;if(!1!==this.b){this.b=!1;for(var b=
this.g,c=[],d=new Map,e=0;e<b.length;e++)d.set(b[e].localName,[]);this.a.f(document,{Na:function(b){if(void 0===b.__CE_state){var e=b.localName,f=d.get(e);f?f.push(b):a.a.c(e)&&c.push(b)}}});for(e=0;e<c.length;e++)this.a.i(c[e]);for(;0<b.length;){var f=b.shift();e=f.localName;f=d.get(f.localName);for(var g=0;g<f.length;g++)this.a.i(f[g]);(e=this.h.get(e))&&e.resolve(void 0)}}};y.prototype.get=function(a){if(a=this.a.c(a))return a.constructor};y.prototype.whenDefined=function(a){if(!gd(a))return Promise.reject(new SyntaxError("'"+
a+"' is not a valid custom element name."));var b=this.h.get(a);if(b)return b.c;b=new cc;this.h.set(a,b);this.a.c(a)&&!this.g.some(function(b){return b.localName===a})&&b.resolve(void 0);return b.c};y.prototype.l=function(a){this.i.c();var b=this.f;this.f=function(c){return a(function(){return b(c)})}};window.CustomElementRegistry=y;y.prototype.define=y.prototype.define;y.prototype.get=y.prototype.get;y.prototype.whenDefined=y.prototype.whenDefined;y.prototype.polyfillWrapFlushCallback=y.prototype.l;
var Sa=window.Document.prototype.createElement,de=window.Document.prototype.createElementNS,ce=window.Document.prototype.importNode,ee=window.Document.prototype.prepend,fe=window.Document.prototype.append,af=window.DocumentFragment.prototype.prepend,bf=window.DocumentFragment.prototype.append,Tb=window.Node.prototype.cloneNode,ua=window.Node.prototype.appendChild,$b=window.Node.prototype.insertBefore,Ta=window.Node.prototype.removeChild,ac=window.Node.prototype.replaceChild,Wa=Object.getOwnPropertyDescriptor(window.Node.prototype,
"textContent"),Sb=window.Element.prototype.attachShadow,Qa=Object.getOwnPropertyDescriptor(window.Element.prototype,"innerHTML"),Ua=window.Element.prototype.getAttribute,Ub=window.Element.prototype.setAttribute,Wb=window.Element.prototype.removeAttribute,va=window.Element.prototype.getAttributeNS,Vb=window.Element.prototype.setAttributeNS,Xb=window.Element.prototype.removeAttributeNS,Zb=window.Element.prototype.insertAdjacentElement,Ud=window.Element.prototype.prepend,Vd=window.Element.prototype.append,
Xd=window.Element.prototype.before,Yd=window.Element.prototype.after,Zd=window.Element.prototype.replaceWith,$d=window.Element.prototype.remove,he=window.HTMLElement,Ra=Object.getOwnPropertyDescriptor(window.HTMLElement.prototype,"innerHTML"),Yb=window.HTMLElement.prototype.insertAdjacentElement,bc=new function(){},Ha=window.customElements;if(!Ha||Ha.forcePolyfill||"function"!=typeof Ha.define||"function"!=typeof Ha.get){var ia=new B;ge(ia);be(ia);Va(ia,DocumentFragment.prototype,{ea:af,append:bf});
ae(ia);Td(ia);document.__CE_hasRegistry=!0;var cf=new y(ia);Object.defineProperty(window,"customElements",{configurable:!0,enumerable:!0,value:cf})}var M={STYLE_RULE:1,ja:7,MEDIA_RULE:4,wa:1E3},I={lb:/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,port:/@import[^;]*;/gim,Ga:/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\n]|$)/gim,Ka:/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\n]|$)?/gim,rb:/@apply\s*\(?[^);]*\)?\s*(?:[;\n]|$)?/gim,wb:/[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim,qb:/^@[^\s]*keyframes/,La:/\s+/g},
z=!(window.ShadyDOM&&window.ShadyDOM.inUse);if(window.ShadyCSS&&void 0!==window.ShadyCSS.nativeCss)var A=window.ShadyCSS.nativeCss;else window.ShadyCSS?(jd(window.ShadyCSS),window.ShadyCSS=void 0):jd(window.WebComponents&&window.WebComponents.flags);var Ia=/(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};{])+)|\{([^}]*)\}(?:(?=[;\s}])|$))/gi,Ja=/(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi,df=/(--[\w-]+)\s*([:,;)]|$)/gi,ef=/(animation\s*:)|(animation-name\s*:)/,Me=/@media\s(.*)/,
ff=/\{[^}]*\}/g,V=null;v.prototype.b=function(a,b,c){a.__styleScoped?a.__styleScoped=null:this.j(a,b||"",c)};v.prototype.j=function(a,b,c){a.nodeType===Node.ELEMENT_NODE&&this.h(a,b,c);if(a="template"===a.localName?(a.content||a.Cb).childNodes:a.children||a.childNodes)for(var d=0;d<a.length;d++)this.j(a[d],b,c)};v.prototype.h=function(a,b,c){if(b)if(a.classList)c?(a.classList.remove("style-scope"),a.classList.remove(b)):(a.classList.add("style-scope"),a.classList.add(b));else if(a.getAttribute){var d=
a.getAttribute(gf);c?d&&(b=d.replace("style-scope","").replace(b,""),Da(a,b)):Da(a,(d?d+" ":"")+"style-scope "+b)}};v.prototype.c=function(a,b,c){var d=a.__cssBuild;z||"shady"===d?b=ea(b,c):(a=W(a),b=this.I(b,a.is,a.$,c)+"\n\n");return b.trim()};v.prototype.I=function(a,b,c,d){var e=this.f(b,c);b=this.i(b);var f=this;return ea(a,function(a){a.c||(f.K(a,b,e),a.c=!0);d&&d(a,b,e)})};v.prototype.i=function(a){return a?hf+a:""};v.prototype.f=function(a,b){return b?"[is="+a+"]":a};v.prototype.K=function(a,
b,c){this.l(a,this.g,b,c)};v.prototype.l=function(a,b,c,d){a.selector=a.A=this.s(a,b,c,d)};v.prototype.s=function(a,b,c,d){var e=a.selector.split(zd);if(!kd(a)){a=0;for(var f=e.length,g;a<f&&(g=e[a]);a++)e[a]=b.call(this,g,c,d)}return e.join(zd)};v.prototype.v=function(a){return a.replace(Jb,function(a,c,d){-1<d.indexOf("+")?d=d.replace(/\+/g,"___"):-1<d.indexOf("___")&&(d=d.replace(/___/g,"+"));return":"+c+"("+d+")"})};v.prototype.g=function(a,b,c){var d=this,e=!1;a=a.trim();var f=Jb.test(a);f&&
(a=a.replace(Jb,function(a,b,c){return":"+b+"("+c.replace(/\s/g,"")+")"}),a=this.v(a));a=a.replace(jf,Kb+" $1");a=a.replace(kf,function(a,f,g){e||(a=d.D(g,f,b,c),e=e||a.stop,f=a.kb,g=a.value);return f+g});f&&(a=this.v(a));return a};v.prototype.D=function(a,b,c,d){var e=a.indexOf(Lb);0<=a.indexOf(Kb)?a=this.H(a,d):0!==e&&(a=c?this.u(a,c):a);c=!1;0<=e&&(b="",c=!0);if(c){var f=!0;c&&(a=a.replace(lf,function(a,b){return" > "+b}))}a=a.replace(mf,function(a,b,c){return'[dir="'+c+'"] '+b+", "+b+'[dir="'+
c+'"]'});return{value:a,kb:b,stop:f}};v.prototype.u=function(a,b){a=a.split(Ad);a[0]+=b;return a.join(Ad)};v.prototype.H=function(a,b){var c=a.match(Bd);return(c=c&&c[2].trim()||"")?c[0].match(Cd)?a.replace(Bd,function(a,c,f){return b+f}):c.split(Cd)[0]===b?c:nf:a.replace(Kb,b)};v.prototype.J=function(a){a.selector=a.parsedSelector;this.B(a);this.l(a,this.N)};v.prototype.B=function(a){a.selector===of&&(a.selector="html")};v.prototype.N=function(a){return a.match(Lb)?this.g(a,Dd):this.u(a.trim(),Dd)};
N.Object.defineProperties(v.prototype,{a:{configurable:!0,enumerable:!0,get:function(){return"style-scope"}}});var Jb=/:(nth[-\w]+)\(([^)]+)\)/,Dd=":not(.style-scope)",zd=",",kf=/(^|[\s>+~]+)((?:\[.+?\]|[^\s>+~=[])+)/g,Cd=/[[.:#*]/,Kb=":host",of=":root",Lb="::slotted",jf=new RegExp("^("+Lb+")"),Bd=/(:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/,lf=/(?:::slotted)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/,mf=/(.*):dir\((?:(ltr|rtl))\)/,hf=".",Ad=":",gf="class",nf="should_not_match",r=new v;w.get=function(a){return a?
a.__styleInfo:null};w.set=function(a,b){return a.__styleInfo=b};w.prototype.c=function(){return this.G};w.prototype._getStyleRules=w.prototype.c;var Ed=function(a){return a.matches||a.matchesSelector||a.mozMatchesSelector||a.msMatchesSelector||a.oMatchesSelector||a.webkitMatchesSelector}(window.Element.prototype),pf=navigator.userAgent.match("Trident");p.prototype.J=function(a){var b=this,c={},d=[],e=0;fa(a,function(a){b.c(a);a.index=e++;b.I(a.w.cssText,c)},function(a){d.push(a)});a.b=d;a=[];for(var f in c)a.push(f);
return a};p.prototype.c=function(a){if(!a.w){var b={},c={};this.b(a,c)&&(b.F=c,a.rules=null);b.cssText=this.H(a);a.w=b}};p.prototype.b=function(a,b){var c=a.w;if(c){if(c.F)return Object.assign(b,c.F),!0}else{c=a.parsedCssText;for(var d;a=Ia.exec(c);){d=(a[2]||a[3]).trim();if("inherit"!==d||"unset"!==d)b[a[1].trim()]=d;d=!0}return d}};p.prototype.H=function(a){return this.N(a.parsedCssText)};p.prototype.N=function(a){return a.replace(ff,"").replace(Ia,"")};p.prototype.I=function(a,b){for(var c;c=df.exec(a);){var d=
c[1];":"!==c[2]&&(b[d]=!0)}};p.prototype.ga=function(a){for(var b=Object.getOwnPropertyNames(a),c=0,d;c<b.length;c++)d=b[c],a[d]=this.a(a[d],a)};p.prototype.a=function(a,b){if(a)if(0<=a.indexOf(";"))a=this.f(a,b);else{var c=this;a=md(a,function(a,e,f,g){if(!e)return a+g;(e=c.a(b[e],b))&&"initial"!==e?"apply-shim-inherit"===e&&(e="inherit"):e=c.a(b[f]||f,b)||f;return a+(e||"")+g})}return a&&a.trim()||""};p.prototype.f=function(a,b){a=a.split(";");for(var c=0,d,e;c<a.length;c++)if(d=a[c]){Ja.lastIndex=
0;if(e=Ja.exec(d))d=this.a(b[e[1]],b);else if(e=d.indexOf(":"),-1!==e){var f=d.substring(e);f=f.trim();f=this.a(f,b)||f;d=d.substring(0,e)+f}a[c]=d&&d.lastIndexOf(";")===d.length-1?d.slice(0,-1):d||""}return a.join(";")};p.prototype.D=function(a,b){var c="";a.w||this.c(a);a.w.cssText&&(c=this.f(a.w.cssText,b));a.cssText=c};p.prototype.B=function(a,b){var c=a.cssText,d=a.cssText;null==a.Ia&&(a.Ia=ef.test(c));if(a.Ia)if(null==a.da){a.da=[];for(var e in b)d=b[e],d=d(c),c!==d&&(c=d,a.da.push(e))}else{for(e=
0;e<a.da.length;++e)d=b[a.da[e]],c=d(c);d=c}a.cssText=d};p.prototype.T=function(a,b){var c={},d=this,e=[];fa(a,function(a){a.w||d.c(a);var f=a.A||a.parsedSelector;b&&a.w.F&&f&&Ed.call(b,f)&&(d.b(a,c),a=a.index,f=parseInt(a/32,10),e[f]=(e[f]||0)|1<<a%32)},null,!0);return{F:c,key:e}};p.prototype.ia=function(a,b,c,d){b.w||this.c(b);if(b.w.F){var e=W(a);a=e.is;e=e.$;e=a?r.f(a,e):"html";var f=b.parsedSelector,g=":host > *"===f||"html"===f,k=0===f.indexOf(":host")&&!g;"shady"===c&&(g=f===e+" > *."+e||-1!==
f.indexOf("html"),k=!g&&0===f.indexOf(e));"shadow"===c&&(g=":host > *"===f||"html"===f,k=k&&!g);if(g||k)c=e,k&&(z&&!b.A&&(b.A=r.s(b,r.g,r.i(a),e)),c=b.A||e),d({vb:c,pb:k,Gb:g})}};p.prototype.K=function(a,b){var c={},d={},e=this,f=b&&b.__cssBuild;fa(b,function(b){e.ia(a,b,f,function(f){Ed.call(a.Db||a,f.vb)&&(f.pb?e.b(b,c):e.b(b,d))})},null,!0);return{tb:d,ob:c}};p.prototype.ha=function(a,b,c){var d=this,e=W(a),f=r.f(e.is,e.$),g=new RegExp("(?:^|[^.#[:])"+(a.extends?"\\"+f.slice(0,-1)+"\\]":f)+"($|[.:[\\s>+~])");
e=w.get(a).G;var k=this.h(e,c);return r.c(a,e,function(a){d.D(a,b);z||kd(a)||!a.cssText||(d.B(a,k),d.l(a,g,f,c))})};p.prototype.h=function(a,b){a=a.b;var c={};if(!z&&a)for(var d=0,e=a[d];d<a.length;e=a[++d])this.j(e,b),c[e.keyframesName]=this.i(e);return c};p.prototype.i=function(a){return function(b){return b.replace(a.f,a.a)}};p.prototype.j=function(a,b){a.f=new RegExp(a.keyframesName,"g");a.a=a.keyframesName+"-"+b;a.A=a.A||a.selector;a.selector=a.A.replace(a.keyframesName,a.a)};p.prototype.l=function(a,
b,c,d){a.A=a.A||a.selector;d="."+d;for(var e=a.A.split(","),f=0,g=e.length,k;f<g&&(k=e[f]);f++)e[f]=k.match(b)?k.replace(c,d):d+" "+k;a.selector=e.join(",")};p.prototype.u=function(a,b,c){var d=a.getAttribute("class")||"",e=d;c&&(e=d.replace(new RegExp("\\s*x-scope\\s*"+c+"\\s*","g")," "));e+=(e?" ":"")+"x-scope "+b;d!==e&&Da(a,e)};p.prototype.v=function(a,b,c,d){b=d?d.textContent||"":this.ha(a,b,c);var e=w.get(a),f=e.a;f&&!z&&f!==d&&(f._useCount--,0>=f._useCount&&f.parentNode&&f.parentNode.removeChild(f));
z?e.a?(e.a.textContent=b,d=e.a):b&&(d=Ab(b,c,a.shadowRoot,e.b)):d?d.parentNode||(pf&&-1<b.indexOf("@media")&&(d.textContent=b),ld(d,null,e.b)):b&&(d=Ab(b,c,null,e.b));d&&(d._useCount=d._useCount||0,e.a!=d&&d._useCount++,e.a=d);return d};p.prototype.s=function(a,b){var c=Ca(a),d=this;a.textContent=ea(c,function(a){var c=a.cssText=a.parsedCssText;a.w&&a.w.cssText&&(c=c.replace(I.Ga,"").replace(I.Ka,""),a.cssText=d.f(c,b))})};N.Object.defineProperties(p.prototype,{g:{configurable:!0,enumerable:!0,get:function(){return"x-scope"}}});
var Q=new p,Mb={},Ka=window.customElements;if(Ka&&!z){var qf=Ka.define;Ka.define=function(a,b,c){var d=document.createComment(" Shady DOM styles for "+a+" "),e=document.head;e.insertBefore(d,(V?V.nextSibling:null)||e.firstChild);V=d;Mb[a]=d;return qf.call(Ka,a,b,c)}}ta.prototype.a=function(a,b,c){for(var d=0;d<c.length;d++){var e=c[d];if(a.F[e]!==b[e])return!1}return!0};ta.prototype.b=function(a,b,c,d){var e=this.cache[a]||[];e.push({F:b,styleElement:c,C:d});e.length>this.c&&e.shift();this.cache[a]=
e};ta.prototype.fetch=function(a,b,c){if(a=this.cache[a])for(var d=a.length-1;0<=d;d--){var e=a[d];if(this.a(e,b,c))return e}};if(!z){var Fd=new MutationObserver(nd),Gd=function(a){Fd.observe(a,{childList:!0,subtree:!0})};if(window.customElements&&!window.customElements.polyfillWrapFlushCallback)Gd(document);else{var Nb=function(){Gd(document.body)};window.HTMLImports?window.HTMLImports.whenReady(Nb):requestAnimationFrame(function(){if("loading"===document.readyState){var a=function(){Nb();document.removeEventListener("readystatechange",
a)};document.addEventListener("readystatechange",a)}else Nb()})}R=function(){nd(Fd.takeRecords())}}var Ea={},Pe=Promise.resolve(),Bb=null,pd=window.HTMLImports&&window.HTMLImports.whenReady||null,Cb,La=null,sa=null;t.prototype.Ha=function(){!this.enqueued&&sa&&(this.enqueued=!0,Rb(sa))};t.prototype.b=function(a){a.__seenByShadyCSS||(a.__seenByShadyCSS=!0,this.customStyles.push(a),this.Ha())};t.prototype.a=function(a){return a.__shadyCSSCachedStyle?a.__shadyCSSCachedStyle:a.getStyle?a.getStyle():a};
t.prototype.c=function(){for(var a=this.customStyles,b=0;b<a.length;b++){var c=a[b];if(!c.__shadyCSSCachedStyle){var d=this.a(c);d&&(d=d.__appliedElement||d,La&&La(d),c.__shadyCSSCachedStyle=d)}}return a};t.prototype.addCustomStyle=t.prototype.b;t.prototype.getStyleForCustomStyle=t.prototype.a;t.prototype.processStyles=t.prototype.c;Object.defineProperties(t.prototype,{transformCallback:{get:function(){return La},set:function(a){La=a}},validateCallback:{get:function(){return sa},set:function(a){var b=
!1;sa||(b=!0);sa=a;b&&this.Ha()}}});var Hd=new ta;g.prototype.B=function(){R()};g.prototype.K=function(a){var b=this.s[a]=(this.s[a]||0)+1;return a+"-"+b};g.prototype.Ra=function(a){return Ca(a)};g.prototype.Ta=function(a){return ea(a)};g.prototype.J=function(a){a=a.content.querySelectorAll("style");for(var b=[],c=0;c<a.length;c++){var d=a[c];b.push(d.textContent);d.parentNode.removeChild(d)}return b.join("").trim()};g.prototype.ga=function(a){return(a=a.content.querySelector("style"))?a.getAttribute("css-build")||
"":""};g.prototype.prepareTemplate=function(a,b,c){if(!a.f){a.f=!0;a.name=b;a.extends=c;Ea[b]=a;var d=this.ga(a),e=this.J(a);c={is:b,extends:c,zb:d};z||r.b(a.content,b);this.c();var f=Ja.test(e)||Ia.test(e);Ja.lastIndex=0;Ia.lastIndex=0;e=zb(e);f&&A&&this.a&&this.a.transformRules(e,b);a._styleAst=e;a.g=d;d=[];A||(d=Q.J(a._styleAst));if(!d.length||A)b=this.T(c,a._styleAst,z?a.content:null,Mb[b]),a.a=b;a.c=d}};g.prototype.T=function(a,b,c,d){b=r.c(a,b);if(b.length)return Ab(b,a.is,c,d)};g.prototype.ia=
function(a){var b=W(a),c=b.is;b=b.$;var d=Mb[c];c=Ea[c];if(c){var e=c._styleAst;var f=c.c}return w.set(a,new w(e,d,f,0,b))};g.prototype.H=function(){!this.a&&window.ShadyCSS&&window.ShadyCSS.ApplyShim&&(this.a=window.ShadyCSS.ApplyShim,this.a.invalidCallback=Ne)};g.prototype.I=function(){var a=this;!this.b&&window.ShadyCSS&&window.ShadyCSS.CustomStyleInterface&&(this.b=window.ShadyCSS.CustomStyleInterface,this.b.transformCallback=function(b){a.v(b)},this.b.validateCallback=function(){requestAnimationFrame(function(){(a.b.enqueued||
a.i)&&a.f()})})};g.prototype.c=function(){this.H();this.I()};g.prototype.f=function(){this.c();if(this.b){var a=this.b.processStyles();this.b.enqueued&&(A?this.Pa(a):(this.u(this.g,this.h),this.D(a)),this.b.enqueued=!1,this.i&&!A&&this.styleDocument())}};g.prototype.styleElement=function(a,b){var c=W(a).is,d=w.get(a);d||(d=this.ia(a));this.j(a)||(this.i=!0);b&&(d.S=d.S||{},Object.assign(d.S,b));if(A){if(d.S){b=d.S;for(var e in b)null===e?a.style.removeProperty(e):a.style.setProperty(e,b[e])}if(((e=
Ea[c])||this.j(a))&&e&&e.a&&!od(e)){if(od(e)||e._applyShimValidatingVersion!==e._applyShimNextVersion)this.c(),this.a&&this.a.transformRules(e._styleAst,c),e.a.textContent=r.c(a,d.G),Oe(e);z&&(c=a.shadowRoot)&&(c.querySelector("style").textContent=r.c(a,d.G));d.G=e._styleAst}}else this.u(a,d),d.ua&&d.ua.length&&this.N(a,d)};g.prototype.l=function(a){return(a=a.getRootNode().host)?w.get(a)?a:this.l(a):this.g};g.prototype.j=function(a){return a===this.g};g.prototype.N=function(a,b){var c=W(a).is,d=
Hd.fetch(c,b.M,b.ua),e=d?d.styleElement:null,f=b.C;b.C=d&&d.C||this.K(c);e=Q.v(a,b.M,b.C,e);z||Q.u(a,b.C,f);d||Hd.b(c,b.M,e,b.C)};g.prototype.u=function(a,b){var c=this.l(a),d=w.get(c);c=Object.create(d.M||null);var e=Q.K(a,b.G);a=Q.T(d.G,a).F;Object.assign(c,e.ob,a,e.tb);this.ha(c,b.S);Q.ga(c);b.M=c};g.prototype.ha=function(a,b){for(var c in b){var d=b[c];if(d||0===d)a[c]=d}};g.prototype.styleDocument=function(a){this.styleSubtree(this.g,a)};g.prototype.styleSubtree=function(a,b){var c=a.shadowRoot;
(c||this.j(a))&&this.styleElement(a,b);if(b=c&&(c.children||c.childNodes))for(a=0;a<b.length;a++)this.styleSubtree(b[a]);else if(a=a.children||a.childNodes)for(b=0;b<a.length;b++)this.styleSubtree(a[b])};g.prototype.Pa=function(a){for(var b=0;b<a.length;b++){var c=this.b.getStyleForCustomStyle(a[b]);c&&this.Oa(c)}};g.prototype.D=function(a){for(var b=0;b<a.length;b++){var c=this.b.getStyleForCustomStyle(a[b]);c&&Q.s(c,this.h.M)}};g.prototype.v=function(a){var b=this,c=Ca(a);fa(c,function(a){z?r.B(a):
r.J(a);A&&(b.c(),b.a&&b.a.transformRule(a))});A?a.textContent=ea(c):this.h.G.rules.push(c)};g.prototype.Oa=function(a){if(A&&this.a){var b=Ca(a);this.c();this.a.transformRules(b);a.textContent=ea(b)}};g.prototype.getComputedStyleValue=function(a,b){var c;A||(c=(w.get(a)||w.get(this.l(a))).M[b]);return(c=c||window.getComputedStyle(a).getPropertyValue(b))?c.trim():""};g.prototype.Sa=function(a,b){var c=a.getRootNode();b=b?b.split(/\s/):[];c=c.host&&c.host.localName;if(!c){var d=a.getAttribute("class");
if(d){d=d.split(/\s/);for(var e=0;e<d.length;e++)if(d[e]===r.a){c=d[e+1];break}}}c&&b.push(r.a,c);A||(c=w.get(a))&&c.C&&b.push(Q.g,c.C);Da(a,b.join(" "))};g.prototype.Qa=function(a){return w.get(a)};g.prototype.flush=g.prototype.B;g.prototype.prepareTemplate=g.prototype.prepareTemplate;g.prototype.styleElement=g.prototype.styleElement;g.prototype.styleDocument=g.prototype.styleDocument;g.prototype.styleSubtree=g.prototype.styleSubtree;g.prototype.getComputedStyleValue=g.prototype.getComputedStyleValue;
g.prototype.setElementClass=g.prototype.Sa;g.prototype._styleInfoForNode=g.prototype.Qa;g.prototype.transformCustomStyleForDocument=g.prototype.v;g.prototype.getStyleAst=g.prototype.Ra;g.prototype.styleAstToString=g.prototype.Ta;g.prototype.flushCustomStyles=g.prototype.f;Object.defineProperties(g.prototype,{nativeShadow:{get:function(){return z}},nativeCss:{get:function(){return A}}});var K=new g;if(window.ShadyCSS){var Id=window.ShadyCSS.ApplyShim;var Jd=window.ShadyCSS.CustomStyleInterface}window.ShadyCSS=
{ScopingShim:K,prepareTemplate:function(a,b,c){K.f();K.prepareTemplate(a,b,c)},styleSubtree:function(a,b){K.f();K.styleSubtree(a,b)},styleElement:function(a){K.f();K.styleElement(a)},styleDocument:function(a){K.f();K.styleDocument(a)},getComputedStyleValue:function(a,b){return K.getComputedStyleValue(a,b)},nativeCss:A,nativeShadow:z};Id&&(window.ShadyCSS.ApplyShim=Id);Jd&&(window.ShadyCSS.CustomStyleInterface=Jd);var Ob=window.customElements,Ma=window.HTMLImports;window.WebComponents=window.WebComponents||
{};if(Ob&&Ob.polyfillWrapFlushCallback){var Na,Kd=function(){if(Na){var a=Na;Na=null;a();return!0}},Ld=Ma.whenReady;Ob.polyfillWrapFlushCallback(function(a){Na=a;Ld(Kd)});Ma.whenReady=function(a){Ld(function(){Kd()?Ma.whenReady(a):a()})}}Ma.whenReady(function(){requestAnimationFrame(function(){window.WebComponents.ready=!0;document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})});var Md=document.createElement("style");Md.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";
var Nd=document.querySelector("head");Nd.insertBefore(Md,Nd.firstChild)})();}).call(this);
//# sourceMappingURL=webcomponents-lite.js.map

View file

@ -24,7 +24,7 @@ from homeassistant.helpers.event import track_time_change
from homeassistant.util import convert, dt
REQUIREMENTS = [
'google-api-python-client==1.6.2',
'google-api-python-client==1.6.4',
'oauth2client==4.0.0',
]
@ -99,10 +99,10 @@ def do_authentication(hass, config):
from oauth2client.file import Storage
oauth = OAuth2WebServerFlow(
config[CONF_CLIENT_ID],
config[CONF_CLIENT_SECRET],
'https://www.googleapis.com/auth/calendar.readonly',
'Home-Assistant.io',
client_id=config[CONF_CLIENT_ID],
client_secret=config[CONF_CLIENT_SECRET],
scope='https://www.googleapis.com/auth/calendar.readonly',
redirect_uri='Home-Assistant.io',
)
try:

View file

@ -269,7 +269,7 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_RELOAD, reload_service_handler,
descriptions[DOMAIN][SERVICE_RELOAD], schema=RELOAD_SERVICE_SCHEMA)
descriptions[SERVICE_RELOAD], schema=RELOAD_SERVICE_SCHEMA)
@asyncio.coroutine
def groups_service_handler(service):
@ -346,11 +346,11 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET, groups_service_handler,
descriptions[DOMAIN][SERVICE_SET], schema=SET_SERVICE_SCHEMA)
descriptions[SERVICE_SET], schema=SET_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_REMOVE, groups_service_handler,
descriptions[DOMAIN][SERVICE_REMOVE], schema=REMOVE_SERVICE_SCHEMA)
descriptions[SERVICE_REMOVE], schema=REMOVE_SERVICE_SCHEMA)
@asyncio.coroutine
def visibility_service_handler(service):
@ -368,7 +368,7 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET_VISIBILITY, visibility_service_handler,
descriptions[DOMAIN][SERVICE_SET_VISIBILITY],
descriptions[SERVICE_SET_VISIBILITY],
schema=SET_VISIBILITY_SERVICE_SCHEMA)
return True

View file

@ -0,0 +1,59 @@
reload:
description: "Reload group configuration."
set_visibility:
description: Hide or show a group
fields:
entity_id:
description: Name(s) of entities to set value
example: 'group.travel'
visible:
description: True if group should be shown or False if it should be hidden.
example: True
set:
description: Create/Update a user group
fields:
object_id:
description: Group id and part of entity id
example: 'test_group'
name:
description: Name of group
example: 'My test group'
view:
description: Boolean for if the group is a view
example: True
icon:
description: Name of icon for the group
example: 'mdi:camera'
control:
description: Value for control the group control
example: 'hidden'
visible:
description: If the group is visible on UI
example: True
entities:
description: List of all members in the group. Not compatible with 'delta'
example: domain.entity_id1, domain.entity_id2
add_entities:
description: List of members they will change on group listening.
example: domain.entity_id1, domain.entity_id2
remove:
description: Remove a user group
fields:
object_id:
description: Group id and part of entity id
example: 'test_group'

View file

@ -14,9 +14,13 @@ from aiohttp import web
from aiohttp.web_exceptions import HTTPBadGateway
from aiohttp.hdrs import CONTENT_TYPE
import async_timeout
import voluptuous as vol
from homeassistant.const import CONTENT_TYPE_TEXT_PLAIN
from homeassistant.components.http import HomeAssistantView, KEY_AUTHENTICATED
import homeassistant.helpers.config_validation as cv
from homeassistant.const import CONTENT_TYPE_TEXT_PLAIN, SERVER_PORT
from homeassistant.components.http import (
HomeAssistantView, KEY_AUTHENTICATED, CONF_API_PASSWORD, CONF_SERVER_PORT,
CONF_SSL_CERTIFICATE)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.components.frontend import register_built_in_panel
@ -25,16 +29,42 @@ _LOGGER = logging.getLogger(__name__)
DOMAIN = 'hassio'
DEPENDENCIES = ['http']
SERVICE_ADDON_START = 'addon_start'
SERVICE_ADDON_STOP = 'addon_stop'
SERVICE_ADDON_RESTART = 'addon_restart'
SERVICE_ADDON_STDIN = 'addon_stdin'
ATTR_ADDON = 'addon'
ATTR_INPUT = 'input'
NO_TIMEOUT = {
re.compile(r'^homeassistant/update$'), re.compile(r'^host/update$'),
re.compile(r'^supervisor/update$'), re.compile(r'^addons/[^/]*/update$'),
re.compile(r'^addons/[^/]*/install$')
re.compile(r'^homeassistant/update$'),
re.compile(r'^host/update$'),
re.compile(r'^supervisor/update$'),
re.compile(r'^addons/[^/]*/update$'),
re.compile(r'^addons/[^/]*/install$'),
re.compile(r'^addons/[^/]*/rebuild$')
}
NO_AUTH = {
re.compile(r'^panel$'), re.compile(r'^addons/[^/]*/logo$')
}
SCHEMA_ADDON = vol.Schema({
vol.Required(ATTR_ADDON): cv.slug,
})
SCHEMA_ADDON_STDIN = SCHEMA_ADDON.extend({
vol.Required(ATTR_INPUT): vol.Any(dict, cv.string)
})
MAP_SERVICE_API = {
SERVICE_ADDON_START: ('/addons/{addon}/start', SCHEMA_ADDON),
SERVICE_ADDON_STOP: ('/addons/{addon}/stop', SCHEMA_ADDON),
SERVICE_ADDON_RESTART: ('/addons/{addon}/restart', SCHEMA_ADDON),
SERVICE_ADDON_STDIN: ('/addons/{addon}/stdin', SCHEMA_ADDON_STDIN),
}
@asyncio.coroutine
def async_setup(hass, config):
@ -48,8 +78,7 @@ def async_setup(hass, config):
websession = async_get_clientsession(hass)
hassio = HassIO(hass.loop, websession, host)
api_ok = yield from hassio.is_connected()
if not api_ok:
if not (yield from hassio.is_connected()):
_LOGGER.error("Not connected with HassIO!")
return False
@ -59,6 +88,23 @@ def async_setup(hass, config):
register_built_in_panel(hass, 'hassio', 'Hass.io',
'mdi:access-point-network')
if 'http' in config:
yield from hassio.update_hass_api(config.get('http'))
@asyncio.coroutine
def async_service_handler(service):
"""Handle service calls for HassIO."""
api_command = MAP_SERVICE_API[service.service][0]
addon = service.data[ATTR_ADDON]
data = service.data[ATTR_INPUT] if ATTR_INPUT in service.data else None
yield from hassio.send_command(
api_command.format(addon=addon), payload=data, timeout=60)
for service, settings in MAP_SERVICE_API.items():
hass.services.async_register(
DOMAIN, service, async_service_handler, schema=settings[1])
return True
@ -71,30 +117,52 @@ class HassIO(object):
self.websession = websession
self._ip = ip
@asyncio.coroutine
def is_connected(self):
"""Return True if it connected to HassIO supervisor.
This method return a coroutine.
"""
return self.send_command("/supervisor/ping", method="get")
def update_hass_api(self, http_config):
"""Update Home-Assistant API data on HassIO.
This method return a coroutine.
"""
port = http_config.get(CONF_SERVER_PORT) or SERVER_PORT
options = {
'ssl': CONF_SSL_CERTIFICATE in http_config,
'port': port,
'password': http_config.get(CONF_API_PASSWORD),
}
return self.send_command("/homeassistant/options", payload=options)
@asyncio.coroutine
def send_command(self, command, method="post", payload=None, timeout=10):
"""Send API command to HassIO.
This method is a coroutine.
"""
try:
with async_timeout.timeout(10, loop=self.loop):
request = yield from self.websession.get(
"http://{}{}".format(self._ip, "/supervisor/ping")
)
with async_timeout.timeout(timeout, loop=self.loop):
request = yield from self.websession.request(
method, "http://{}{}".format(self._ip, command),
json=payload)
if request.status != 200:
_LOGGER.error("Ping return code %d.", request.status)
_LOGGER.error(
"%s return code %d.", command, request.status)
return False
answer = yield from request.json()
return answer and answer['result'] == 'ok'
except asyncio.TimeoutError:
_LOGGER.error("Timeout on ping request")
_LOGGER.error("Timeout on %s request", command)
except aiohttp.ClientError as err:
_LOGGER.error("Client error on ping request %s", err)
_LOGGER.error("Client error on %s request %s", command, err)
return False

View file

@ -41,6 +41,7 @@ def last_recorder_run(hass):
with session_scope(hass=hass) as session:
res = (session.query(RecorderRuns)
.filter(RecorderRuns.end.isnot(None))
.order_by(RecorderRuns.end.desc()).first())
if res is None:
return None
@ -283,9 +284,10 @@ class HistoryPeriodView(HomeAssistantView):
end_time = request.query.get('end_time')
if end_time:
end_time = dt_util.as_utc(
dt_util.parse_datetime(end_time))
if end_time is None:
end_time = dt_util.parse_datetime(end_time)
if end_time:
end_time = dt_util.as_utc(end_time)
else:
return self.json_message('Invalid end_time', HTTP_BAD_REQUEST)
else:
end_time = start_time + one_day

View file

@ -21,7 +21,7 @@ from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import track_time_interval
from homeassistant.config import load_yaml_config_file
REQUIREMENTS = ['pyhomematic==0.1.32']
REQUIREMENTS = ['pyhomematic==0.1.33']
DOMAIN = 'homematic'
@ -69,7 +69,8 @@ HM_DEVICE_TYPES = {
'IPSmoke'],
DISCOVER_CLIMATE: [
'Thermostat', 'ThermostatWall', 'MAXThermostat', 'ThermostatWall2',
'MAXWallThermostat', 'IPThermostat', 'IPThermostatWall'],
'MAXWallThermostat', 'IPThermostat', 'IPThermostatWall',
'ThermostatGroup'],
DISCOVER_BINARY_SENSORS: [
'ShutterContact', 'Smoke', 'SmokeV2', 'Motion', 'MotionV2',
'RemoteMotion', 'WeatherSensor', 'TiltSensor', 'IPShutterContact',
@ -129,6 +130,7 @@ CONF_LOCAL_IP = 'local_ip'
CONF_LOCAL_PORT = 'local_port'
CONF_IP = 'ip'
CONF_PORT = 'port'
CONF_PATH = 'path'
CONF_CALLBACK_IP = 'callback_ip'
CONF_CALLBACK_PORT = 'callback_port'
CONF_RESOLVENAMES = 'resolvenames'
@ -140,6 +142,7 @@ DEFAULT_LOCAL_IP = '0.0.0.0'
DEFAULT_LOCAL_PORT = 0
DEFAULT_RESOLVENAMES = False
DEFAULT_PORT = 2001
DEFAULT_PATH = ''
DEFAULT_USERNAME = 'Admin'
DEFAULT_PASSWORD = ''
DEFAULT_VARIABLES = False
@ -160,8 +163,8 @@ CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_HOSTS): {cv.match_all: {
vol.Required(CONF_IP): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT):
cv.port,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_PATH, default=DEFAULT_PATH): cv.string,
vol.Optional(CONF_USERNAME, default=DEFAULT_USERNAME): cv.string,
vol.Optional(CONF_PASSWORD, default=DEFAULT_PASSWORD): cv.string,
vol.Optional(CONF_VARIABLES, default=DEFAULT_VARIABLES):
@ -258,6 +261,7 @@ def setup(hass, config):
remotes[rname] = {}
remotes[rname][CONF_IP] = server
remotes[rname][CONF_PORT] = rconfig.get(CONF_PORT)
remotes[rname][CONF_PATH] = rconfig.get(CONF_PATH)
remotes[rname][CONF_RESOLVENAMES] = rconfig.get(CONF_RESOLVENAMES)
remotes[rname][CONF_USERNAME] = rconfig.get(CONF_USERNAME)
remotes[rname][CONF_PASSWORD] = rconfig.get(CONF_PASSWORD)

View file

@ -1,8 +1,11 @@
"""Authentication for HTTP component."""
import asyncio
import base64
import hmac
import logging
from aiohttp import hdrs
from homeassistant.const import HTTP_HEADER_HA_AUTH
from .util import get_real_ip
from .const import KEY_TRUSTED_NETWORKS, KEY_AUTHENTICATED
@ -41,6 +44,10 @@ def auth_middleware(app, handler):
validate_password(request, request.query[DATA_API_PASSWORD])):
authenticated = True
elif (hdrs.AUTHORIZATION in request.headers and
validate_authorization_header(request)):
authenticated = True
elif is_trusted_ip(request):
authenticated = True
@ -64,3 +71,22 @@ def validate_password(request, api_password):
"""Test if password is valid."""
return hmac.compare_digest(
api_password, request.app['hass'].http.api_password)
def validate_authorization_header(request):
"""Test an authorization header if valid password."""
if hdrs.AUTHORIZATION not in request.headers:
return False
auth_type, auth = request.headers.get(hdrs.AUTHORIZATION).split(' ', 1)
if auth_type != 'Basic':
return False
decoded = base64.b64decode(auth).decode('utf-8')
username, password = decoded.split(':', 1)
if username != 'homeassistant':
return False
return validate_password(request, password)

View file

@ -17,7 +17,7 @@ from homeassistant.components.image_processing import (
ImageProcessingEntity)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['numpy==1.13.1']
REQUIREMENTS = ['numpy==1.13.3']
_LOGGER = logging.getLogger(__name__)
@ -28,7 +28,7 @@ CASCADE_URL = \
'https://raw.githubusercontent.com/opencv/opencv/master/data/' + \
'lbpcascades/lbpcascade_frontalface.xml'
CONF_CLASSIFIER = 'classifer'
CONF_CLASSIFIER = 'classifier'
CONF_FILE = 'file'
CONF_MIN_SIZE = 'min_size'
CONF_NEIGHBORS = 'neighbors'

View file

@ -18,7 +18,7 @@ from homeassistant.helpers import state as state_helper
from homeassistant.helpers.entity_values import EntityValues
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['influxdb==3.0.0']
REQUIREMENTS = ['influxdb==4.1.1']
_LOGGER = logging.getLogger(__name__)

View file

@ -0,0 +1,227 @@
"""
Component to offer a way to select a date and / or a time.
For more details about this component, please refer to the documentation
at https://home-assistant.io/components/input_datetime/
"""
import asyncio
import logging
import datetime
import voluptuous as vol
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_ICON, CONF_NAME, STATE_UNKNOWN)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.restore_state import async_get_last_state
from homeassistant.util import dt as dt_util
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'input_datetime'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
CONF_HAS_DATE = 'has_date'
CONF_HAS_TIME = 'has_time'
CONF_INITIAL = 'initial'
ATTR_DATE = 'date'
ATTR_TIME = 'time'
SERVICE_SET_DATETIME = 'set_datetime'
SERVICE_SET_DATETIME_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
vol.Optional(ATTR_DATE): cv.date,
vol.Optional(ATTR_TIME): cv.time,
})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: vol.All({
vol.Optional(CONF_NAME): cv.string,
vol.Required(CONF_HAS_DATE): cv.boolean,
vol.Required(CONF_HAS_TIME): cv.boolean,
vol.Optional(CONF_ICON): cv.icon,
vol.Optional(CONF_INITIAL): cv.datetime,
}, cv.has_at_least_one_key_value((CONF_HAS_DATE, True),
(CONF_HAS_TIME, True)))})
}, extra=vol.ALLOW_EXTRA)
@asyncio.coroutine
def async_set_datetime(hass, entity_id, dt_value):
"""Set date and / or time of input_datetime."""
yield from hass.services.async_call(DOMAIN, SERVICE_SET_DATETIME, {
ATTR_ENTITY_ID: entity_id,
ATTR_DATE: dt_value.date(),
ATTR_TIME: dt_value.time()
})
@asyncio.coroutine
def async_setup(hass, config):
"""Set up an input datetime."""
component = EntityComponent(_LOGGER, DOMAIN, hass)
entities = []
for object_id, cfg in config[DOMAIN].items():
name = cfg.get(CONF_NAME)
has_time = cfg.get(CONF_HAS_TIME)
has_date = cfg.get(CONF_HAS_DATE)
icon = cfg.get(CONF_ICON)
initial = cfg.get(CONF_INITIAL)
entities.append(InputDatetime(object_id, name,
has_date, has_time, icon, initial))
if not entities:
return False
@asyncio.coroutine
def async_set_datetime_service(call):
"""Handle a call to the input datetime 'set datetime' service."""
target_inputs = component.async_extract_from_service(call)
tasks = []
for input_datetime in target_inputs:
time = call.data.get(ATTR_TIME)
date = call.data.get(ATTR_DATE)
if (input_datetime.has_date() and not date) or \
(input_datetime.has_time() and not time):
_LOGGER.error("Invalid service data for "
"input_datetime.set_datetime: %s",
str(call.data))
continue
tasks.append(input_datetime.async_set_datetime(date, time))
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
hass.services.async_register(
DOMAIN, SERVICE_SET_DATETIME, async_set_datetime_service,
schema=SERVICE_SET_DATETIME_SCHEMA)
yield from component.async_add_entities(entities)
return True
class InputDatetime(Entity):
"""Representation of a datetime input."""
def __init__(self, object_id, name, has_date, has_time, icon, initial):
"""Initialize a select input."""
self.entity_id = ENTITY_ID_FORMAT.format(object_id)
self._name = name
self._has_date = has_date
self._has_time = has_time
self._icon = icon
self._initial = initial
self._current_datetime = None
@asyncio.coroutine
def async_added_to_hass(self):
"""Run when entity about to be added."""
restore_val = None
# Priority 1: Initial State
if self._initial is not None:
restore_val = self._initial
# Priority 2: Old state
if restore_val is None:
old_state = yield from async_get_last_state(self.hass,
self.entity_id)
if old_state is not None:
restore_val = dt_util.parse_datetime(old_state.state)
if restore_val is not None:
if not self._has_date:
self._current_datetime = restore_val.time()
elif not self._has_time:
self._current_datetime = restore_val.date()
else:
self._current_datetime = restore_val
def has_date(self):
"""Return whether the input datetime carries a date."""
return self._has_date
def has_time(self):
"""Return whether the input datetime carries a time."""
return self._has_time
@property
def should_poll(self):
"""If entity should be polled."""
return False
@property
def name(self):
"""Return the name of the select input."""
return self._name
@property
def icon(self):
"""Return the icon to be used for this entity."""
return self._icon
@property
def state(self):
"""Return the state of the component."""
if self._current_datetime is None:
return STATE_UNKNOWN
return self._current_datetime
@property
def state_attributes(self):
"""Return the state attributes."""
attrs = {
'has_date': self._has_date,
'has_time': self._has_time,
}
if self._current_datetime is None:
return attrs
if self._has_date and self._current_datetime is not None:
attrs['year'] = self._current_datetime.year
attrs['month'] = self._current_datetime.month
attrs['day'] = self._current_datetime.day
if self._has_time and self._current_datetime is not None:
attrs['hour'] = self._current_datetime.hour
attrs['minute'] = self._current_datetime.minute
attrs['second'] = self._current_datetime.second
if self._current_datetime is not None:
if not self._has_date:
attrs['timestamp'] = self._current_datetime.hour * 3600 + \
self._current_datetime.minute * 60 + \
self._current_datetime.second
elif not self._has_time:
extended = datetime.datetime.combine(self._current_datetime,
datetime.time(0, 0))
attrs['timestamp'] = extended.timestamp()
else:
attrs['timestamp'] = self._current_datetime.timestamp()
return attrs
@asyncio.coroutine
def async_set_datetime(self, date_val, time_val):
"""Set a new date / time."""
if self._has_date and self._has_time and date_val and time_val:
self._current_datetime = datetime.datetime.combine(date_val,
time_val)
elif self._has_date and not self._has_time and date_val:
self._current_datetime = date_val
if self._has_time and not self._has_date and time_val:
self._current_datetime = time_val
yield from self.async_update_ha_state()

View file

@ -1,8 +1,8 @@
"""
Component to offer a way to select a value from a slider.
Component to offer a way to set a numeric value from a slider or text box.
For more details about this component, please refer to the documentation
at https://home-assistant.io/components/input_slider/
at https://home-assistant.io/components/input_number/
"""
import asyncio
import logging
@ -19,29 +19,34 @@ from homeassistant.helpers.restore_state import async_get_last_state
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'input_slider'
DOMAIN = 'input_number'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
CONF_INITIAL = 'initial'
CONF_MIN = 'min'
CONF_MAX = 'max'
CONF_MODE = 'mode'
CONF_STEP = 'step'
MODE_SLIDER = 'slider'
MODE_BOX = 'box'
ATTR_VALUE = 'value'
ATTR_MIN = 'min'
ATTR_MAX = 'max'
ATTR_STEP = 'step'
ATTR_MODE = 'mode'
SERVICE_SELECT_VALUE = 'select_value'
SERVICE_SET_VALUE = 'set_value'
SERVICE_SELECT_VALUE_SCHEMA = vol.Schema({
SERVICE_SET_VALUE_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
vol.Required(ATTR_VALUE): vol.Coerce(float),
})
def _cv_input_slider(cfg):
"""Configure validation helper for input slider (voluptuous)."""
def _cv_input_number(cfg):
"""Configure validation helper for input number (voluptuous)."""
minimum = cfg.get(CONF_MIN)
maximum = cfg.get(CONF_MAX)
if minimum >= maximum:
@ -64,16 +69,18 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_STEP, default=1):
vol.All(vol.Coerce(float), vol.Range(min=1e-3)),
vol.Optional(CONF_ICON): cv.icon,
vol.Optional(ATTR_UNIT_OF_MEASUREMENT): cv.string
}, _cv_input_slider)
vol.Optional(ATTR_UNIT_OF_MEASUREMENT): cv.string,
vol.Optional(CONF_MODE, default=MODE_SLIDER):
vol.In([MODE_BOX, MODE_SLIDER]),
}, _cv_input_number)
})
}, required=True, extra=vol.ALLOW_EXTRA)
@bind_hass
def select_value(hass, entity_id, value):
"""Set input_slider to value."""
hass.services.call(DOMAIN, SERVICE_SELECT_VALUE, {
def set_value(hass, entity_id, value):
"""Set input_number to value."""
hass.services.call(DOMAIN, SERVICE_SET_VALUE, {
ATTR_ENTITY_ID: entity_id,
ATTR_VALUE: value,
})
@ -94,37 +101,39 @@ def async_setup(hass, config):
step = cfg.get(CONF_STEP)
icon = cfg.get(CONF_ICON)
unit = cfg.get(ATTR_UNIT_OF_MEASUREMENT)
mode = cfg.get(CONF_MODE)
entities.append(InputSlider(
object_id, name, initial, minimum, maximum, step, icon, unit))
entities.append(InputNumber(
object_id, name, initial, minimum, maximum, step, icon, unit,
mode))
if not entities:
return False
@asyncio.coroutine
def async_select_value_service(call):
def async_set_value_service(call):
"""Handle a calls to the input slider services."""
target_inputs = component.async_extract_from_service(call)
tasks = [input_slider.async_select_value(call.data[ATTR_VALUE])
for input_slider in target_inputs]
tasks = [input_number.async_set_value(call.data[ATTR_VALUE])
for input_number in target_inputs]
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
hass.services.async_register(
DOMAIN, SERVICE_SELECT_VALUE, async_select_value_service,
schema=SERVICE_SELECT_VALUE_SCHEMA)
DOMAIN, SERVICE_SET_VALUE, async_set_value_service,
schema=SERVICE_SET_VALUE_SCHEMA)
yield from component.async_add_entities(entities)
return True
class InputSlider(Entity):
class InputNumber(Entity):
"""Represent an slider."""
def __init__(self, object_id, name, initial, minimum, maximum, step, icon,
unit):
"""Initialize a select input."""
unit, mode):
"""Initialize an input number."""
self.entity_id = ENTITY_ID_FORMAT.format(object_id)
self._name = name
self._current_value = initial
@ -133,6 +142,7 @@ class InputSlider(Entity):
self._step = step
self._icon = icon
self._unit = unit
self._mode = mode
@property
def should_poll(self):
@ -141,7 +151,7 @@ class InputSlider(Entity):
@property
def name(self):
"""Return the name of the select input slider."""
"""Return the name of the input slider."""
return self._name
@property
@ -165,7 +175,8 @@ class InputSlider(Entity):
return {
ATTR_MIN: self._minimum,
ATTR_MAX: self._maximum,
ATTR_STEP: self._step
ATTR_STEP: self._step,
ATTR_MODE: self._mode,
}
@asyncio.coroutine
@ -184,8 +195,8 @@ class InputSlider(Entity):
self._current_value = self._minimum
@asyncio.coroutine
def async_select_value(self, value):
"""Select new value."""
def async_set_value(self, value):
"""Set new value."""
num_value = float(value)
if num_value < self._minimum or num_value > self._maximum:
_LOGGER.warning("Invalid value: %s (range %s - %s)",

View file

@ -263,7 +263,7 @@ def setup_bridge(host, hass, add_devices, filename, allow_unreachable,
# create a service for calling run_scene directly on the bridge,
# used to simplify automation rules.
def hue_activate_scene(call):
"""Service to call directly directly into bridge to set scenes."""
"""Service to call directly into bridge to set scenes."""
group_name = call.data[ATTR_GROUP_NAME]
scene_name = call.data[ATTR_SCENE_NAME]
bridge.run_scene(group_name, scene_name)

View file

@ -213,7 +213,7 @@ class MqttJson(Light):
except KeyError:
pass
except ValueError:
_LOGGER.warning("Invalid white value value received")
_LOGGER.warning("Invalid white value received")
if self._xy is not None:
try:

View file

@ -0,0 +1,87 @@
"""
Light/LED support for the Skybell HD Doorbell.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.skybell/
"""
import logging
from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_RGB_COLOR,
SUPPORT_BRIGHTNESS, SUPPORT_RGB_COLOR, Light)
from homeassistant.components.skybell import (
DOMAIN as SKYBELL_DOMAIN, SkybellDevice)
DEPENDENCIES = ['skybell']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the platform for a Skybell device."""
skybell = hass.data.get(SKYBELL_DOMAIN)
sensors = []
for device in skybell.get_devices():
sensors.append(SkybellLight(device))
add_devices(sensors, True)
def _to_skybell_level(level):
"""Convert the given HASS light level (0-255) to Skybell (0-100)."""
return int((level * 100) / 255)
def _to_hass_level(level):
"""Convert the given Skybell (0-100) light level to HASS (0-255)."""
return int((level * 255) / 100)
class SkybellLight(SkybellDevice, Light):
"""A binary sensor implementation for Skybell devices."""
def __init__(self, device):
"""Initialize a light for a Skybell device."""
super().__init__(device)
self._name = self._device.name
@property
def name(self):
"""Return the name of the sensor."""
return self._name
def turn_on(self, **kwargs):
"""Turn on the light."""
if ATTR_RGB_COLOR in kwargs:
self._device.led_rgb = kwargs[ATTR_RGB_COLOR]
elif ATTR_BRIGHTNESS in kwargs:
self._device.led_intensity = _to_skybell_level(
kwargs[ATTR_BRIGHTNESS])
else:
self._device.led_intensity = _to_skybell_level(255)
def turn_off(self, **kwargs):
"""Turn off the light."""
self._device.led_intensity = 0
@property
def is_on(self):
"""Return true if device is on."""
return self._device.led_intensity > 0
@property
def brightness(self):
"""Return the brightness of the light."""
return _to_hass_level(self._device.led_intensity)
@property
def rgb_color(self):
"""Return the color of the light."""
return self._device.led_rgb
@property
def supported_features(self):
"""Flag supported features."""
return SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR

View file

@ -17,7 +17,7 @@ from homeassistant.util.color import (
from typing import Tuple
REQUIREMENTS = ['pyHS100==0.2.4.2']
REQUIREMENTS = ['pyHS100==0.3.0']
_LOGGER = logging.getLogger(__name__)
@ -124,7 +124,7 @@ class TPLinkSmartBulb(Light):
def update(self):
"""Update the TP-Link Bulb's state."""
from pyHS100 import SmartPlugException
from pyHS100 import SmartDeviceException
try:
self._state = (
self.smartbulb.state == self.smartbulb.BULB_STATE_ON)
@ -136,7 +136,7 @@ class TPLinkSmartBulb(Light):
self._color_temp = kelvin_to_mired(
self.smartbulb.color_temp)
self._rgb = hsv_to_rgb(self.smartbulb.hsv)
except (SmartPlugException, OSError) as ex:
except (SmartDeviceException, OSError) as ex:
_LOGGER.warning('Could not read state for %s: %s', self.name, ex)
@property

View file

@ -4,15 +4,18 @@ Support for the IKEA Tradfri platform.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.tradfri/
"""
import asyncio
import logging
from homeassistant.core import callback
from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR, SUPPORT_BRIGHTNESS,
SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR, Light)
from homeassistant.components.light import (
PLATFORM_SCHEMA as LIGHT_PLATFORM_SCHEMA)
from homeassistant.components.tradfri import (
KEY_GATEWAY, KEY_TRADFRI_GROUPS, KEY_API)
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR, ATTR_TRANSITION,
SUPPORT_BRIGHTNESS, SUPPORT_TRANSITION, SUPPORT_COLOR_TEMP,
SUPPORT_RGB_COLOR, Light)
from homeassistant.components.light import \
PLATFORM_SCHEMA as LIGHT_PLATFORM_SCHEMA
from homeassistant.components.tradfri import KEY_GATEWAY, KEY_TRADFRI_GROUPS, \
KEY_API
from homeassistant.util import color as color_util
_LOGGER = logging.getLogger(__name__)
@ -20,10 +23,13 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['tradfri']
PLATFORM_SCHEMA = LIGHT_PLATFORM_SCHEMA
IKEA = 'IKEA of Sweden'
TRADFRI_LIGHT_MANAGER = 'Tradfri Light Manager'
SUPPORTED_FEATURES = (SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION)
ALLOWED_TEMPERATURES = {IKEA}
def setup_platform(hass, config, add_devices, discovery_info=None):
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up the IKEA Tradfri Light platform."""
if discovery_info is None:
return
@ -31,14 +37,21 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
gateway_id = discovery_info['gateway']
api = hass.data[KEY_API][gateway_id]
gateway = hass.data[KEY_GATEWAY][gateway_id]
devices = api(gateway.get_devices())
lights = [dev for dev in devices if api(dev).has_light_control]
add_devices(Tradfri(light, api) for light in lights)
devices_command = gateway.get_devices()
devices_commands = yield from api(devices_command)
devices = yield from api(*devices_commands)
lights = [dev for dev in devices if dev.has_light_control]
if lights:
async_add_devices(TradfriLight(light, api) for light in lights)
allow_tradfri_groups = hass.data[KEY_TRADFRI_GROUPS][gateway_id]
if allow_tradfri_groups:
groups = api(gateway.get_groups())
add_devices(TradfriGroup(group, api) for group in groups)
groups_command = gateway.get_groups()
groups_commands = yield from api(groups_command)
groups = yield from api(*groups_commands)
if groups:
async_add_devices(TradfriGroup(group, api) for group in groups)
class TradfriGroup(Light):
@ -46,14 +59,26 @@ class TradfriGroup(Light):
def __init__(self, light, api):
"""Initialize a Group."""
self._group = api(light)
self._api = api
self._name = self._group.name
self._group = light
self._name = light.name
self._refresh(light)
@asyncio.coroutine
def async_added_to_hass(self):
"""Start thread when added to hass."""
self._async_start_observe()
@property
def should_poll(self):
"""No polling needed for tradfri group."""
return False
@property
def supported_features(self):
"""Flag supported features."""
return SUPPORT_BRIGHTNESS
return SUPPORTED_FEATURES
@property
def name(self):
@ -70,49 +95,68 @@ class TradfriGroup(Light):
"""Return the brightness of the group lights."""
return self._group.dimmer
def turn_off(self, **kwargs):
@asyncio.coroutine
def async_turn_off(self, **kwargs):
"""Instruct the group lights to turn off."""
self._api(self._group.set_state(0))
self.hass.async_add_job(self._api(self._group.set_state(0)))
def turn_on(self, **kwargs):
@asyncio.coroutine
def async_turn_on(self, **kwargs):
"""Instruct the group lights to turn on, or dim."""
keys = {}
if ATTR_TRANSITION in kwargs:
keys['transition_time'] = int(kwargs[ATTR_TRANSITION]) * 10
if ATTR_BRIGHTNESS in kwargs:
self._api(self._group.set_dimmer(kwargs[ATTR_BRIGHTNESS]))
self.hass.async_add_job(self._api(
self._group.set_dimmer(kwargs[ATTR_BRIGHTNESS], **keys)))
else:
self._api(self._group.set_state(1))
self.hass.async_add_job(self._api(self._group.set_state(1)))
@callback
def _async_start_observe(self, exc=None):
"""Start observation of light."""
from pytradfri.error import PyTradFriError
if exc:
_LOGGER.warning("Observation failed for %s", self._name,
exc_info=exc)
def update(self):
"""Fetch new state data for this group."""
from pytradfri import RequestTimeout
try:
self._api(self._group.update())
except RequestTimeout:
_LOGGER.warning("Tradfri update request timed out")
cmd = self._group.observe(callback=self._observe_update,
err_callback=self._async_start_observe,
duration=0)
self.hass.async_add_job(self._api(cmd))
except PyTradFriError as err:
_LOGGER.warning("Observation failed, trying again", exc_info=err)
self._async_start_observe()
def _refresh(self, group):
"""Refresh the light data."""
self._group = group
self._name = group.name
def _observe_update(self, tradfri_device):
"""Receive new state data for this light."""
self._refresh(tradfri_device)
self.hass.async_add_job(self.async_update_ha_state())
class Tradfri(Light):
"""The platform class required by Home Asisstant."""
class TradfriLight(Light):
"""The platform class required by Home Assistant."""
def __init__(self, light, api):
"""Initialize a Light."""
self._light = api(light)
self._api = api
# Caching of LightControl and light object
self._light_control = self._light.light_control
self._light_data = self._light_control.lights[0]
self._name = self._light.name
self._light = None
self._light_control = None
self._light_data = None
self._name = None
self._rgb_color = None
self._features = SUPPORT_BRIGHTNESS
self._features = SUPPORTED_FEATURES
self._temp_supported = False
if self._light_data.hex_color is not None:
if self._light.device_info.manufacturer == IKEA:
self._features |= SUPPORT_COLOR_TEMP
else:
self._features |= SUPPORT_RGB_COLOR
self._ok_temps = \
self._light.device_info.manufacturer in ALLOWED_TEMPERATURES
self._refresh(light)
@property
def min_mireds(self):
@ -126,6 +170,30 @@ class Tradfri(Light):
from pytradfri.color import MIN_KELVIN_WS
return color_util.color_temperature_kelvin_to_mired(MIN_KELVIN_WS)
@property
def device_state_attributes(self):
"""Return the devices' state attributes."""
info = self._light.device_info
attrs = {
'manufacturer': info.manufacturer,
'model_number': info.model_number,
'serial': info.serial,
'firmware_version': info.firmware_version,
'power_source': info.power_source_str,
'battery_level': info.battery_level
}
return attrs
@asyncio.coroutine
def async_added_to_hass(self):
"""Start thread when added to hass."""
self._async_start_observe()
@property
def should_poll(self):
"""No polling needed for tradfri light."""
return False
@property
def supported_features(self):
"""Flag supported features."""
@ -151,7 +219,7 @@ class Tradfri(Light):
"""Return the CT color value in mireds."""
if (self._light_data.kelvin_color is None or
self.supported_features & SUPPORT_COLOR_TEMP == 0 or
not self._ok_temps):
not self._temp_supported):
return None
return color_util.color_temperature_kelvin_to_mired(
self._light_data.kelvin_color
@ -162,42 +230,90 @@ class Tradfri(Light):
"""RGB color of the light."""
return self._rgb_color
def turn_off(self, **kwargs):
@asyncio.coroutine
def async_turn_off(self, **kwargs):
"""Instruct the light to turn off."""
self._api(self._light_control.set_state(False))
self.hass.async_add_job(self._api(
self._light_control.set_state(False)))
def turn_on(self, **kwargs):
@asyncio.coroutine
def async_turn_on(self, **kwargs):
"""
Instruct the light to turn on.
After adding "self._light_data.hexcolor is not None"
for ATTR_RGB_COLOR, this also supports Philips Hue bulbs.
"""
if ATTR_BRIGHTNESS in kwargs:
self._api(self._light_control.set_dimmer(kwargs[ATTR_BRIGHTNESS]))
else:
self._api(self._light_control.set_state(True))
if ATTR_RGB_COLOR in kwargs and self._light_data.hex_color is not None:
self._api(self._light.light_control.set_rgb_color(
*kwargs[ATTR_RGB_COLOR]))
self.hass.async_add_job(self._api(
self._light.light_control.set_rgb_color(
*kwargs[ATTR_RGB_COLOR])))
elif ATTR_COLOR_TEMP in kwargs and \
self._light_data.hex_color is not None and self._ok_temps:
self._light_data.hex_color is not None and \
self._temp_supported:
kelvin = color_util.color_temperature_mired_to_kelvin(
kwargs[ATTR_COLOR_TEMP])
self._api(self._light_control.set_kelvin_color(kelvin))
self.hass.async_add_job(self._api(
self._light_control.set_kelvin_color(kelvin)))
keys = {}
if ATTR_TRANSITION in kwargs:
keys['transition_time'] = int(kwargs[ATTR_TRANSITION]) * 10
if ATTR_BRIGHTNESS in kwargs:
self.hass.async_add_job(self._api(
self._light_control.set_dimmer(kwargs[ATTR_BRIGHTNESS],
**keys)))
else:
self.hass.async_add_job(self._api(
self._light_control.set_state(True)))
@callback
def _async_start_observe(self, exc=None):
"""Start observation of light."""
from pytradfri.error import PyTradFriError
if exc:
_LOGGER.warning("Observation failed for %s", self._name,
exc_info=exc)
def update(self):
"""Fetch new state data for this light."""
from pytradfri import RequestTimeout
try:
self._api(self._light.update())
except RequestTimeout as exception:
_LOGGER.warning("Tradfri update request timed out: %s", exception)
cmd = self._light.observe(callback=self._observe_update,
err_callback=self._async_start_observe,
duration=0)
self.hass.async_add_job(self._api(cmd))
except PyTradFriError as err:
_LOGGER.warning("Observation failed, trying again", exc_info=err)
self._async_start_observe()
def _refresh(self, light):
"""Refresh the light data."""
self._light = light
# Caching of LightControl and light object
self._light_control = light.light_control
self._light_data = light.light_control.lights[0]
self._name = light.name
self._rgb_color = None
self._features = SUPPORTED_FEATURES
if self._light_data.hex_color is not None:
if self._light.device_info.manufacturer == IKEA:
self._features |= SUPPORT_COLOR_TEMP
else:
self._features |= SUPPORT_RGB_COLOR
self._temp_supported = self._light.device_info.manufacturer \
in ALLOWED_TEMPERATURES
def _observe_update(self, tradfri_device):
"""Receive new state data for this light."""
self._refresh(tradfri_device)
# Handle Hue lights paired with the gateway
# hex_color is 0 when bulb is unreachable
if self._light_data.hex_color not in (None, '0'):
self._rgb_color = color_util.rgb_hex_to_rgb_list(
self._light_data.hex_color)
self.hass.async_add_job(self.async_update_ha_state())

View file

@ -54,6 +54,10 @@ SUPPORT_YEELIGHT_RGB = (SUPPORT_YEELIGHT |
SUPPORT_EFFECT |
SUPPORT_COLOR_TEMP)
YEELIGHT_MIN_KELVIN = YEELIGHT_MAX_KELVIN = 2700
YEELIGHT_RGB_MIN_KELVIN = 1700
YEELIGHT_RGB_MAX_KELVIN = 6500
EFFECT_DISCO = "Disco"
EFFECT_TEMP = "Slow Temp"
EFFECT_STROBE = "Strobe epilepsy!"
@ -191,6 +195,20 @@ class YeelightLight(Light):
"""Return the brightness of this light between 1..255."""
return self._brightness
@property
def min_mireds(self):
"""Return minimum supported color temperature."""
if self.supported_features & SUPPORT_COLOR_TEMP:
return kelvin_to_mired(YEELIGHT_RGB_MAX_KELVIN)
return kelvin_to_mired(YEELIGHT_MAX_KELVIN)
@property
def max_mireds(self):
"""Return maximum supported color temperature."""
if self.supported_features & SUPPORT_COLOR_TEMP:
return kelvin_to_mired(YEELIGHT_RGB_MIN_KELVIN)
return kelvin_to_mired(YEELIGHT_MIN_KELVIN)
def _get_rgb_from_properties(self):
rgb = self._properties.get('rgb', None)
color_mode = self._properties.get('color_mode', None)
@ -434,7 +452,10 @@ class YeelightLight(Light):
def turn_off(self, **kwargs) -> None:
"""Turn off."""
import yeelight
duration = int(self.config[CONF_TRANSITION]) # in ms
if ATTR_TRANSITION in kwargs: # passed kwarg overrides config
duration = int(kwargs.get(ATTR_TRANSITION) * 1000) # kwarg in s
try:
self._bulb.turn_off()
self._bulb.turn_off(duration=duration)
except yeelight.BulbException as ex:
_LOGGER.error("Unable to turn the bulb off: %s", ex)

View file

@ -29,20 +29,17 @@ class TeslaLock(TeslaDevice, LockDevice):
"""Initialisation of the lock."""
self._state = None
super().__init__(tesla_device, controller)
self._name = self.tesla_device.name
self.entity_id = ENTITY_ID_FORMAT.format(self.tesla_id)
def lock(self, **kwargs):
"""Send the lock command."""
_LOGGER.debug("Locking doors for: %s", self._name)
self.tesla_device.lock()
self._state = STATE_LOCKED
def unlock(self, **kwargs):
"""Send the unlock command."""
_LOGGER.debug("Unlocking doors for: %s", self._name)
self.tesla_device.unlock()
self._state = STATE_UNLOCKED
@property
def is_locked(self):

View file

@ -15,7 +15,7 @@ from homeassistant.components.media_player import (
from homeassistant.config import load_yaml_config_file
from homeassistant.helpers import config_validation as cv
REQUIREMENTS = ['youtube_dl==2017.9.24']
REQUIREMENTS = ['youtube_dl==2017.10.01']
_LOGGER = logging.getLogger(__name__)

View file

@ -225,7 +225,7 @@ class DenonDevice(MediaPlayerDevice):
self.telnet_command('MU' + ('ON' if mute else 'OFF'))
def media_play(self):
"""Play media media player."""
"""Play media player."""
self.telnet_command('NS9A')
def media_pause(self):

View file

@ -124,7 +124,7 @@ class DuneHDPlayerEntity(MediaPlayerDevice):
self.schedule_update_ha_state()
def media_play(self):
"""Play media media player."""
"""Play media player."""
self._state = self._player.play()
self.schedule_update_ha_state()

View file

@ -287,12 +287,6 @@ class PlexClient(MediaPlayerDevice):
self._is_player_available = False
self._machine_identifier = None
self._make = ''
self._media_content_id = None
self._media_content_rating = None
self._media_content_type = None
self._media_duration = None
self._media_image_url = None
self._media_title = None
self._name = None
self._player_state = 'idle'
self._previous_volume_level = 1 # Used in fake muting
@ -308,16 +302,7 @@ class PlexClient(MediaPlayerDevice):
self.update_devices = update_devices
self.update_sessions = update_sessions
# Music
self._media_album_artist = None
self._media_album_name = None
self._media_artist = None
self._media_track = None
# TV Show
self._media_episode = None
self._media_season = None
self._media_series_title = None
self._clear_media()
self.refresh(device, session)
@ -339,10 +324,32 @@ class PlexClient(MediaPlayerDevice):
'media_player', prefix,
self.name.lower().replace('-', '_'))
def _clear_media(self):
"""Set all Media Items to None."""
# General
self._media_content_id = None
self._media_content_rating = None
self._media_content_type = None
self._media_duration = None
self._media_image_url = None
self._media_title = None
self._media_position = None
# Music
self._media_album_artist = None
self._media_album_name = None
self._media_artist = None
self._media_track = None
# TV Show
self._media_episode = None
self._media_season = None
self._media_series_title = None
def refresh(self, device, session):
"""Refresh key device data."""
# new data refresh
if session:
self._clear_media()
if session: # Not being triggered by Chrome or FireTablet Plex App
self._session = session
if device:
self._device = device
@ -369,9 +376,6 @@ class PlexClient(MediaPlayerDevice):
self._session.ratingKey)
self._media_content_rating = self._convert_na_to_none(
self._session.contentRating)
else:
self._media_position = None
self._media_content_id = None
# player dependent data
if self._session and self._session.player:
@ -405,7 +409,6 @@ class PlexClient(MediaPlayerDevice):
self._session.duration)
else:
self._session_type = None
self._media_duration = None
# media type
if self._session_type == 'clip':
@ -418,11 +421,9 @@ class PlexClient(MediaPlayerDevice):
self._media_content_type = MEDIA_TYPE_VIDEO
elif self._session_type == 'track':
self._media_content_type = MEDIA_TYPE_MUSIC
else:
self._media_content_type = None
# title (movie name, tv episode name, music song name)
if self._session:
if self._session and self._is_player_active:
self._media_title = self._convert_na_to_none(self._session.title)
# Movies
@ -431,9 +432,7 @@ class PlexClient(MediaPlayerDevice):
self._media_title += ' (' + str(self._session.year) + ')'
# TV Show
if (self._is_player_active and
self._media_content_type is MEDIA_TYPE_TVSHOW):
if self._media_content_type is MEDIA_TYPE_TVSHOW:
# season number (00)
if callable(self._convert_na_to_none(self._session.seasons)):
self._media_season = self._convert_na_to_none(
@ -443,23 +442,15 @@ class PlexClient(MediaPlayerDevice):
self._media_season = self._session.parentIndex.zfill(2)
else:
self._media_season = None
# show name
self._media_series_title = self._convert_na_to_none(
self._session.grandparentTitle)
# episode number (00)
if self._convert_na_to_none(
self._session.index) is not None:
if self._convert_na_to_none(self._session.index) is not None:
self._media_episode = str(self._session.index).zfill(2)
else:
self._media_season = None
self._media_series_title = None
self._media_episode = None
# Music
if (self._is_player_active and
self._media_content_type == MEDIA_TYPE_MUSIC):
if self._media_content_type == MEDIA_TYPE_MUSIC:
self._media_album_name = self._convert_na_to_none(
self._session.parentTitle)
self._media_album_artist = self._convert_na_to_none(
@ -469,14 +460,9 @@ class PlexClient(MediaPlayerDevice):
self._session.originalTitle)
# use album artist if track artist is missing
if self._media_artist is None:
_LOGGER.debug("Using album artist because track artist was "
"not found: %s", self.entity_id)
_LOGGER.debug("Using album artist because track artist "
"was not found: %s", self.entity_id)
self._media_artist = self._media_album_artist
else:
self._media_album_name = None
self._media_album_artist = None
self._media_track = None
self._media_artist = None
# set app name to library name
if (self._session is not None
@ -501,8 +487,6 @@ class PlexClient(MediaPlayerDevice):
thumb_url = self._get_thumbnail_url(self._session.art)
self._media_image_url = thumb_url
else:
self._media_image_url = None
def _get_thumbnail_url(self, property_value):
"""Return full URL (if exists) for a thumbnail property."""
@ -521,6 +505,7 @@ class PlexClient(MediaPlayerDevice):
"""Force client to idle."""
self._state = STATE_IDLE
self._session = None
self._clear_media()
@property
def unique_id(self):

View file

@ -18,7 +18,7 @@ from homeassistant.const import (CONF_NAME, CONF_HOST, STATE_OFF, STATE_ON,
STATE_PLAYING, STATE_IDLE)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['rxv==0.4.0']
REQUIREMENTS = ['rxv==0.5.1']
_LOGGER = logging.getLogger(__name__)

View file

@ -33,7 +33,9 @@ SUPPORTED_FEATURES = (
SUPPORT_SELECT_SOURCE
)
REQUIREMENTS = ['pymusiccast==0.1.0']
KNOWN_HOSTS_KEY = 'data_yamaha_musiccast'
REQUIREMENTS = ['pymusiccast==0.1.2']
DEFAULT_NAME = "Yamaha Receiver"
DEFAULT_PORT = 5005
@ -47,16 +49,48 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Yamaha MusicCast platform."""
import socket
import pymusiccast
known_hosts = hass.data.get(KNOWN_HOSTS_KEY)
if known_hosts is None:
known_hosts = hass.data[KNOWN_HOSTS_KEY] = []
_LOGGER.debug("known_hosts: %s", known_hosts)
name = config.get(CONF_NAME)
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
receiver = pymusiccast.McDevice(host, udp_port=port)
_LOGGER.debug("receiver: %s / Port: %d", receiver, port)
# Get IP of host to prevent duplicates
try:
ipaddr = socket.gethostbyname(host)
except (OSError) as error:
_LOGGER.error(
"Could not communicate with %s:%d: %s", host, port, error)
return
add_devices([YamahaDevice(receiver, name)], True)
if [item for item in known_hosts if item[0] == ipaddr]:
_LOGGER.warning("Host %s:%d already registered.", host, port)
return
if [item for item in known_hosts if item[1] == port]:
_LOGGER.warning("Port %s:%d already registered.", host, port)
return
reg_host = (ipaddr, port)
known_hosts.append(reg_host)
try:
receiver = pymusiccast.McDevice(ipaddr, udp_port=port)
except pymusiccast.exceptions.YMCInitError as err:
_LOGGER.error(err)
receiver = None
if receiver:
_LOGGER.debug("receiver: %s / Port: %d", receiver, port)
add_devices([YamahaDevice(receiver, name)], True)
else:
known_hosts.remove(reg_host)
class YamahaDevice(MediaPlayerDevice):

View file

@ -14,7 +14,7 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP,
CONF_HOST, CONF_METHOD, CONF_PORT, ATTR_STATE)
CONF_HOST, CONF_METHOD, CONF_PORT, CONF_TYPE, CONF_TIMEOUT, ATTR_STATE)
DOMAIN = 'modbus'
@ -24,7 +24,6 @@ REQUIREMENTS = ['pymodbus==1.3.1']
CONF_BAUDRATE = 'baudrate'
CONF_BYTESIZE = 'bytesize'
CONF_STOPBITS = 'stopbits'
CONF_TYPE = 'type'
CONF_PARITY = 'parity'
SERIAL_SCHEMA = {
@ -35,12 +34,14 @@ SERIAL_SCHEMA = {
vol.Required(CONF_PARITY): vol.Any('E', 'O', 'N'),
vol.Required(CONF_STOPBITS): vol.Any(1, 2),
vol.Required(CONF_TYPE): 'serial',
vol.Optional(CONF_TIMEOUT, default=3): cv.socket_timeout,
}
ETHERNET_SCHEMA = {
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PORT): cv.positive_int,
vol.Required(CONF_TYPE): vol.Any('tcp', 'udp'),
vol.Optional(CONF_TIMEOUT, default=3): cv.socket_timeout,
}
@ -89,15 +90,18 @@ def setup(hass, config):
baudrate=config[DOMAIN][CONF_BAUDRATE],
stopbits=config[DOMAIN][CONF_STOPBITS],
bytesize=config[DOMAIN][CONF_BYTESIZE],
parity=config[DOMAIN][CONF_PARITY])
parity=config[DOMAIN][CONF_PARITY],
timeout=config[DOMAIN][CONF_TIMEOUT])
elif client_type == 'tcp':
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
client = ModbusClient(host=config[DOMAIN][CONF_HOST],
port=config[DOMAIN][CONF_PORT])
port=config[DOMAIN][CONF_PORT],
timeout=config[DOMAIN][CONF_TIMEOUT])
elif client_type == 'udp':
from pymodbus.client.sync import ModbusUdpClient as ModbusClient
client = ModbusClient(host=config[DOMAIN][CONF_HOST],
port=config[DOMAIN][CONF_PORT])
port=config[DOMAIN][CONF_PORT],
timeout=config[DOMAIN][CONF_TIMEOUT])
else:
return False

View file

@ -12,14 +12,19 @@ from homeassistant.const import MATCH_ALL
from homeassistant.core import callback
from homeassistant.components.mqtt import valid_publish_topic
from homeassistant.helpers.event import async_track_state_change
import homeassistant.helpers.config_validation as cv
CONF_BASE_TOPIC = 'base_topic'
CONF_PUBLISH_ATTRIBUTES = 'publish_attributes'
CONF_PUBLISH_TIMESTAMPS = 'publish_timestamps'
DEPENDENCIES = ['mqtt']
DOMAIN = 'mqtt_statestream'
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_BASE_TOPIC): valid_publish_topic
vol.Required(CONF_BASE_TOPIC): valid_publish_topic,
vol.Optional(CONF_PUBLISH_ATTRIBUTES, default=False): cv.boolean,
vol.Optional(CONF_PUBLISH_TIMESTAMPS, default=False): cv.boolean
})
}, extra=vol.ALLOW_EXTRA)
@ -29,6 +34,8 @@ def async_setup(hass, config):
"""Set up the MQTT state feed."""
conf = config.get(DOMAIN, {})
base_topic = conf.get(CONF_BASE_TOPIC)
publish_attributes = conf.get(CONF_PUBLISH_ATTRIBUTES)
publish_timestamps = conf.get(CONF_PUBLISH_TIMESTAMPS)
if not base_topic.endswith('/'):
base_topic = base_topic + '/'
@ -38,8 +45,28 @@ def async_setup(hass, config):
return
payload = new_state.state
topic = base_topic + entity_id.replace('.', '/') + '/state'
hass.components.mqtt.async_publish(topic, payload, 1, True)
mybase = base_topic + entity_id.replace('.', '/') + '/'
hass.components.mqtt.async_publish(mybase + 'state', payload, 1, True)
if publish_timestamps:
if new_state.last_updated:
hass.components.mqtt.async_publish(
mybase + 'last_updated',
new_state.last_updated.isoformat(),
1,
True)
if new_state.last_changed:
hass.components.mqtt.async_publish(
mybase + 'last_changed',
new_state.last_changed.isoformat(),
1,
True)
if publish_attributes:
for key, val in new_state.attributes.items():
if val:
hass.components.mqtt.async_publish(mybase + key,
val, 1, True)
async_track_state_change(hass, MATCH_ALL, _state_publisher)
return True

View file

@ -0,0 +1,90 @@
"""
Clicksend audio platform for notify component.
This platform sends text to speech audio messages through clicksend
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.clicksendaudio/
"""
import json
import logging
import requests
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.const import (
CONF_USERNAME, CONF_API_KEY, CONF_RECIPIENT, HTTP_HEADER_CONTENT_TYPE,
CONTENT_TYPE_JSON)
from homeassistant.components.notify import (
PLATFORM_SCHEMA, BaseNotificationService)
_LOGGER = logging.getLogger(__name__)
BASE_API_URL = 'https://rest.clicksend.com/v3'
HEADERS = {HTTP_HEADER_CONTENT_TYPE: CONTENT_TYPE_JSON}
CONF_LANGUAGE = 'language'
CONF_VOICE = 'voice'
DEFAULT_LANGUAGE = 'en-us'
DEFAULT_VOICE = 'female'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_API_KEY): cv.string,
vol.Required(CONF_RECIPIENT): cv.string,
vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string,
vol.Optional(CONF_VOICE, default=DEFAULT_VOICE): cv.string,
})
def get_service(hass, config, discovery_info=None):
"""Get the ClickSend notification service."""
if _authenticate(config) is False:
_LOGGER.error("You are not authorized to access ClickSend")
return None
return ClicksendNotificationService(config)
class ClicksendNotificationService(BaseNotificationService):
"""Implementation of a notification service for the ClickSend service."""
def __init__(self, config):
"""Initialize the service."""
self.username = config.get(CONF_USERNAME)
self.api_key = config.get(CONF_API_KEY)
self.recipient = config.get(CONF_RECIPIENT)
self.language = config.get(CONF_LANGUAGE)
self.voice = config.get(CONF_VOICE)
def send_message(self, message="", **kwargs):
"""Send a voice call to a user."""
data = ({'messages': [{'source': 'hass.notify', 'from': self.recipient,
'to': self.recipient, 'body': message,
'lang': self.language, 'voice': self.voice}]})
api_url = "{}/voice/send".format(BASE_API_URL)
resp = requests.post(api_url, data=json.dumps(data), headers=HEADERS,
auth=(self.username, self.api_key), timeout=5)
obj = json.loads(resp.text)
response_msg = obj['response_msg']
response_code = obj['response_code']
if resp.status_code != 200:
_LOGGER.error("Error %s : %s (Code %s)", resp.status_code,
response_msg, response_code)
def _authenticate(config):
"""Authenticate with ClickSend."""
api_url = '{}/account'.format(BASE_API_URL)
resp = requests.get(api_url, headers=HEADERS,
auth=(config.get(CONF_USERNAME),
config.get(CONF_API_KEY)), timeout=5)
if resp.status_code != 200:
return False
return True

View file

@ -15,7 +15,7 @@ from homeassistant.components.notify import (
_LOGGER = logging.getLogger(__name__)
REQUIREMENTS = ['discord.py==0.16.11']
REQUIREMENTS = ['discord.py==0.16.12']
CONF_TOKEN = 'token'

View file

@ -56,8 +56,15 @@ class FacebookNotificationService(BaseNotificationService):
return
for target in targets:
# If the target starts with a "+", we suppose it's a phone number,
# otherwise it's a user id.
if target.startswith('+'):
recipient = {"phone_number": target}
else:
recipient = {"id": target}
body = {
"recipient": {"phone_number": target},
"recipient": recipient,
"message": body_message
}
import json

View file

@ -0,0 +1,76 @@
"""
Rocket.Chat notification service.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.rocketchat/
"""
import logging
import voluptuous as vol
from homeassistant.const import (
CONF_URL, CONF_USERNAME, CONF_PASSWORD)
from homeassistant.components.notify import (
ATTR_DATA, PLATFORM_SCHEMA,
BaseNotificationService)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['rocketchat-API==0.6.1']
CONF_ROOM = 'room'
_LOGGER = logging.getLogger(__name__)
# pylint: disable=no-value-for-parameter
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_URL): vol.Url(),
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_ROOM): cv.string,
})
def get_service(hass, config, discovery_info=None):
"""Return the notify service."""
from rocketchat_API.APIExceptions.RocketExceptions import (
RocketConnectionException, RocketAuthenticationException)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
url = config.get(CONF_URL)
room = config.get(CONF_ROOM)
try:
return RocketChatNotificationService(url, username, password, room)
except RocketConnectionException:
_LOGGER.warning(
"Unable to connect to Rocket.Chat server at %s.", url)
except RocketAuthenticationException:
_LOGGER.warning(
"Rocket.Chat authentication failed for user %s.", username)
_LOGGER.info("Please check your username/password.")
return None
class RocketChatNotificationService(BaseNotificationService):
"""Implement the notification service for Rocket.Chat."""
def __init__(self, url, username, password, room):
"""Initialize the service."""
from rocketchat_API.rocketchat import RocketChat
self._room = room
self._server = RocketChat(username, password, server_url=url)
def send_message(self, message="", **kwargs):
"""Send a message to Rocket.Chat."""
data = kwargs.get(ATTR_DATA) or {}
resp = self._server.chat_post_message(message, channel=self._room,
**data)
if resp.status_code == 200:
success = resp.json()["success"]
if not success:
_LOGGER.error("Unable to post Rocket.Chat message")
else:
_LOGGER.error("Incorrect status code when posting message: %d",
resp.status_code)

View file

@ -15,8 +15,8 @@ from homeassistant.const import CONF_PASSWORD, CONF_SENDER, CONF_RECIPIENT
REQUIREMENTS = ['sleekxmpp==1.3.2',
'dnspython3==1.15.0',
'pyasn1==0.3.6',
'pyasn1-modules==0.1.4']
'pyasn1==0.3.7',
'pyasn1-modules==0.1.5']
_LOGGER = logging.getLogger(__name__)

View file

@ -129,11 +129,11 @@ def async_setup(hass, config):
)
hass.services.async_register(DOMAIN, SERVICE_CREATE, create_service,
descriptions[DOMAIN][SERVICE_CREATE],
descriptions[SERVICE_CREATE],
SCHEMA_SERVICE_CREATE)
hass.services.async_register(DOMAIN, SERVICE_DISMISS, dismiss_service,
descriptions[DOMAIN][SERVICE_DISMISS],
descriptions[SERVICE_DISMISS],
SCHEMA_SERVICE_DISMISS)
return True

View file

@ -0,0 +1,23 @@
create:
description: Show a notification in the frontend
fields:
message:
description: Message body of the notification. [Templates accepted]
example: Please check your configuration.yaml.
title:
description: Optional title for your notification. [Optional, Templates accepted]
example: Test notification
notification_id:
description: Target ID of the notification, will replace a notification with the same Id. [Optional]
example: 1234
dismiss:
description: Remove a notification from the frontend
fields:
notification_id:
description: Target ID of the notification, which should be removed. [Required]
example: 1234

View file

@ -1,8 +1,9 @@
"""Component to allow running Python scripts."""
import glob
import os
import logging
import datetime
import glob
import logging
import os
import time
import voluptuous as vol
@ -10,6 +11,7 @@ from homeassistant.const import SERVICE_RELOAD
from homeassistant.exceptions import HomeAssistantError
from homeassistant.loader import bind_hass
from homeassistant.util import sanitize_filename
import homeassistant.util.dt as dt_util
DOMAIN = 'python_script'
REQUIREMENTS = ['restrictedpython==4.0a3']
@ -25,6 +27,13 @@ ALLOWED_EVENTBUS = set(['fire'])
ALLOWED_STATEMACHINE = set(['entity_ids', 'all', 'get', 'is_state',
'is_state_attr', 'remove', 'set'])
ALLOWED_SERVICEREGISTRY = set(['services', 'has_service', 'call'])
ALLOWED_TIME = set(['sleep', 'strftime', 'strptime', 'gmtime', 'localtime',
'ctime', 'time', 'mktime'])
ALLOWED_DATETIME = set(['date', 'time', 'datetime', 'timedelta', 'tzinfo'])
ALLOWED_DT_UTIL = set([
'utcnow', 'now', 'as_utc', 'as_timestamp', 'as_local',
'utc_from_timestamp', 'start_of_local_day', 'parse_datetime', 'parse_date',
'get_age'])
class ScriptError(HomeAssistantError):
@ -111,7 +120,10 @@ def execute(hass, filename, source, data=None):
elif (obj is hass and name not in ALLOWED_HASS or
obj is hass.bus and name not in ALLOWED_EVENTBUS or
obj is hass.states and name not in ALLOWED_STATEMACHINE or
obj is hass.services and name not in ALLOWED_SERVICEREGISTRY):
obj is hass.services and name not in ALLOWED_SERVICEREGISTRY or
obj is dt_util and name not in ALLOWED_DT_UTIL or
obj is datetime and name not in ALLOWED_DATETIME or
isinstance(obj, TimeWrapper) and name not in ALLOWED_TIME):
raise ScriptError('Not allowed to access {}.{}'.format(
obj.__class__.__name__, name))
@ -120,6 +132,8 @@ def execute(hass, filename, source, data=None):
builtins = safe_builtins.copy()
builtins.update(utility_builtins)
builtins['datetime'] = datetime
builtins['time'] = TimeWrapper()
builtins['dt_util'] = dt_util
restricted_globals = {
'__builtins__': builtins,
'_print_': StubPrinter,
@ -159,3 +173,24 @@ class StubPrinter:
# pylint: disable=no-self-use
_LOGGER.warning(
"Don't use print() inside scripts. Use logger.info() instead.")
class TimeWrapper:
"""Wrapper of the time module."""
# Class variable, only going to warn once per Home Assistant run
warned = False
# pylint: disable=no-self-use
def sleep(self, *args, **kwargs):
"""Sleep method that warns once."""
if not TimeWrapper.warned:
TimeWrapper.warned = True
_LOGGER.warning('Using time.sleep can reduce the performance of '
'Home Assistant')
time.sleep(*args, **kwargs)
def __getattr__(self, attr):
"""Fetch an attribute from Time module."""
return getattr(time, attr)

View file

@ -0,0 +1,179 @@
"""
Support for Melnor RainCloud sprinkler water timer.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/raincloud/
"""
import asyncio
import logging
from datetime import timedelta
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.const import (
ATTR_ATTRIBUTION, CONF_USERNAME, CONF_PASSWORD, CONF_SCAN_INTERVAL)
from homeassistant.helpers.event import track_time_interval
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.dispatcher import (
async_dispatcher_connect, dispatcher_send)
from requests.exceptions import HTTPError, ConnectTimeout
REQUIREMENTS = ['raincloudy==0.0.3']
_LOGGER = logging.getLogger(__name__)
ALLOWED_WATERING_TIME = [5, 10, 15, 30, 45, 60]
CONF_ATTRIBUTION = "Data provided by Melnor Aquatimer.com"
CONF_WATERING_TIME = 'watering_minutes'
NOTIFICATION_ID = 'raincloud_notification'
NOTIFICATION_TITLE = 'Rain Cloud Setup'
DATA_RAINCLOUD = 'raincloud'
DOMAIN = 'raincloud'
DEFAULT_WATERING_TIME = 15
KEY_MAP = {
'auto_watering': 'Automatic Watering',
'battery': 'Battery',
'is_watering': 'Watering',
'manual_watering': 'Manual Watering',
'next_cycle': 'Next Cycle',
'rain_delay': 'Rain Delay',
'status': 'Status',
'watering_time': 'Remaining Watering Time',
}
ICON_MAP = {
'auto_watering': 'mdi:autorenew',
'battery': '',
'is_watering': '',
'manual_watering': 'mdi:water-pump',
'next_cycle': 'mdi:calendar-clock',
'rain_delay': 'mdi:weather-rainy',
'status': '',
'watering_time': 'mdi:water-pump',
}
UNIT_OF_MEASUREMENT_MAP = {
'auto_watering': '',
'battery': '%',
'is_watering': '',
'manual_watering': '',
'next_cycle': '',
'rain_delay': 'days',
'status': '',
'watering_time': 'min',
}
BINARY_SENSORS = ['is_watering', 'status']
SENSORS = ['battery', 'next_cycle', 'rain_delay', 'watering_time']
SWITCHES = ['auto_watering', 'manual_watering']
SCAN_INTERVAL = timedelta(seconds=20)
SIGNAL_UPDATE_RAINCLOUD = "raincloud_update"
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL):
cv.time_period,
}),
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
"""Set up the Melnor RainCloud component."""
conf = config[DOMAIN]
username = conf.get(CONF_USERNAME)
password = conf.get(CONF_PASSWORD)
scan_interval = conf.get(CONF_SCAN_INTERVAL)
try:
from raincloudy.core import RainCloudy
raincloud = RainCloudy(username=username, password=password)
if not raincloud.is_connected:
raise HTTPError
hass.data[DATA_RAINCLOUD] = RainCloudHub(raincloud)
except (ConnectTimeout, HTTPError) as ex:
_LOGGER.error("Unable to connect to Rain Cloud service: %s", str(ex))
hass.components.persistent_notification.create(
'Error: {}<br />'
'You will need to restart hass after fixing.'
''.format(ex),
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
def hub_refresh(event_time):
"""Call Raincloud hub to refresh information."""
_LOGGER.debug("Updating RainCloud Hub component.")
hass.data[DATA_RAINCLOUD].data.update()
dispatcher_send(hass, SIGNAL_UPDATE_RAINCLOUD)
# Call the Raincloud API to refresh updates
track_time_interval(hass, hub_refresh, scan_interval)
return True
class RainCloudHub(object):
"""Representation of a base RainCloud device."""
def __init__(self, data):
"""Initialize the entity."""
self.data = data
class RainCloudEntity(Entity):
"""Entity class for RainCloud devices."""
def __init__(self, data, sensor_type):
"""Initialize the RainCloud entity."""
self.data = data
self._sensor_type = sensor_type
self._name = "{0} {1}".format(
self.data.name, KEY_MAP.get(self._sensor_type))
self._state = None
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@asyncio.coroutine
def async_added_to_hass(self):
"""Register callbacks."""
async_dispatcher_connect(
self.hass, SIGNAL_UPDATE_RAINCLOUD, self._update_callback)
def _update_callback(self):
"""Callback update method."""
self.schedule_update_ha_state(True)
@property
def unit_of_measurement(self):
"""Return the units of measurement."""
return UNIT_OF_MEASUREMENT_MAP.get(self._sensor_type)
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
'current_time': self.data.current_time,
'identifier': self.data.serial,
}
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return ICON_MAP.get(self._sensor_type)

View file

@ -12,7 +12,8 @@ from homeassistant.const import (
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP
)
REQUIREMENTS = ['raspihats==2.2.1']
REQUIREMENTS = ['raspihats==2.2.3',
'smbus-cffi==0.5.1']
_LOGGER = logging.getLogger(__name__)

View file

@ -10,10 +10,11 @@ https://home-assistant.io/components/recorder/
import asyncio
import concurrent.futures
import logging
from os import path
import queue
import threading
import time
from datetime import timedelta, datetime
from datetime import datetime, timedelta
from typing import Optional, Dict
import voluptuous as vol
@ -28,6 +29,7 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.typing import ConfigType
import homeassistant.util.dt as dt_util
from homeassistant import config as conf_util
from . import purge, migration
from .const import DATA_INSTANCE
@ -39,11 +41,21 @@ _LOGGER = logging.getLogger(__name__)
DOMAIN = 'recorder'
SERVICE_PURGE = 'purge'
ATTR_KEEP_DAYS = 'keep_days'
SERVICE_PURGE_SCHEMA = vol.Schema({
vol.Required(ATTR_KEEP_DAYS):
vol.All(vol.Coerce(int), vol.Range(min=0))
})
DEFAULT_URL = 'sqlite:///{hass_config_path}'
DEFAULT_DB_FILE = 'home-assistant_v2.db'
CONF_DB_URL = 'db_url'
CONF_PURGE_DAYS = 'purge_days'
CONF_PURGE_KEEP_DAYS = 'purge_keep_days'
CONF_PURGE_INTERVAL = 'purge_interval'
CONF_EVENT_TYPES = 'event_types'
CONNECT_RETRY_WAIT = 3
@ -65,7 +77,9 @@ FILTER_SCHEMA = vol.Schema({
CONFIG_SCHEMA = vol.Schema({
DOMAIN: FILTER_SCHEMA.extend({
vol.Optional(CONF_PURGE_DAYS):
vol.Inclusive(CONF_PURGE_KEEP_DAYS, 'purge'):
vol.All(vol.Coerce(int), vol.Range(min=1)),
vol.Inclusive(CONF_PURGE_INTERVAL, 'purge'):
vol.All(vol.Coerce(int), vol.Range(min=1)),
vol.Optional(CONF_DB_URL): cv.string,
})
@ -106,7 +120,8 @@ def run_information(hass, point_in_time: Optional[datetime]=None):
def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the recorder."""
conf = config.get(DOMAIN, {})
purge_days = conf.get(CONF_PURGE_DAYS)
purge_days = conf.get(CONF_PURGE_KEEP_DAYS)
purge_interval = conf.get(CONF_PURGE_INTERVAL)
db_url = conf.get(CONF_DB_URL, None)
if not db_url:
@ -116,24 +131,46 @@ def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
include = conf.get(CONF_INCLUDE, {})
exclude = conf.get(CONF_EXCLUDE, {})
instance = hass.data[DATA_INSTANCE] = Recorder(
hass, purge_days=purge_days, uri=db_url, include=include,
exclude=exclude)
hass, uri=db_url, include=include, exclude=exclude)
instance.async_initialize()
instance.start()
@asyncio.coroutine
def async_handle_purge_interval(now):
"""Handle purge interval."""
instance.do_purge(purge_days)
@asyncio.coroutine
def async_handle_purge_service(service):
"""Handle calls to the purge service."""
instance.do_purge(service.data[ATTR_KEEP_DAYS])
descriptions = yield from hass.async_add_job(
conf_util.load_yaml_config_file, path.join(
path.dirname(__file__), 'services.yaml'))
if purge_interval and purge_days:
async_track_time_interval(hass, async_handle_purge_interval,
timedelta(days=purge_interval))
hass.services.async_register(DOMAIN, SERVICE_PURGE,
async_handle_purge_service,
descriptions.get(SERVICE_PURGE),
schema=SERVICE_PURGE_SCHEMA)
return (yield from instance.async_db_ready)
class Recorder(threading.Thread):
"""A threaded recorder class."""
def __init__(self, hass: HomeAssistant, purge_days: int, uri: str,
def __init__(self, hass: HomeAssistant, uri: str,
include: Dict, exclude: Dict) -> None:
"""Initialize the recorder."""
threading.Thread.__init__(self, name='Recorder')
self.hass = hass
self.purge_days = purge_days
self.purge_days = None
self.queue = queue.Queue() # type: Any
self.recording_start = dt_util.utcnow()
self.db_url = uri
@ -148,12 +185,19 @@ class Recorder(threading.Thread):
self.exclude_t = exclude.get(CONF_EVENT_TYPES, [])
self.get_session = None
self.purge_task = object()
@callback
def async_initialize(self):
"""Initialize the recorder."""
self.hass.bus.async_listen(MATCH_ALL, self.event_listener)
def do_purge(self, purge_days=None):
"""Event listener for purging data."""
if purge_days is not None:
self.purge_days = purge_days
self.queue.put(self.purge_task)
def run(self):
"""Start processing events to save."""
from .models import States, Events
@ -190,7 +234,6 @@ class Recorder(threading.Thread):
self.hass.add_job(connection_failed)
return
purge_task = object()
shutdown_task = object()
hass_started = concurrent.futures.Future()
@ -220,15 +263,6 @@ class Recorder(threading.Thread):
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START,
notify_hass_started)
if self.purge_days is not None:
@callback
def do_purge(now):
"""Event listener for purging data."""
self.queue.put(purge_task)
async_track_time_interval(self.hass, do_purge,
timedelta(days=2))
self.hass.add_job(register)
result = hass_started.result()
@ -244,7 +278,7 @@ class Recorder(threading.Thread):
self._close_connection()
self.queue.task_done()
return
elif event is purge_task:
elif event is self.purge_task:
purge.purge_old_data(self, self.purge_days)
continue
elif event.event_type == EVENT_TIME_CHANGED:

View file

@ -0,0 +1,9 @@
# Describes the format for available recorder services
purge:
description: Start purge task - delete events and states older than x days, according to keep_days service data.
fields:
keep_days:
description: Number of history days to keep in database after purge. Value >= 0
example: 2

View file

@ -16,7 +16,7 @@ from homeassistant.const import (
CONF_DEVICES)
from homeassistant.components.remote import PLATFORM_SCHEMA
REQUIREMENTS = ['pyitachip2ir==0.0.6']
REQUIREMENTS = ['pyitachip2ir==0.0.7']
_LOGGER = logging.getLogger(__name__)

View file

@ -11,6 +11,7 @@ import logging
import os
import async_timeout
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_COMMAND, CONF_HOST, CONF_PORT,
@ -22,6 +23,7 @@ from homeassistant.helpers.deprecation import get_deprecated
from homeassistant.helpers.entity import Entity
import voluptuous as vol
REQUIREMENTS = ['rflink==0.0.34']
_LOGGER = logging.getLogger(__name__)
@ -370,6 +372,19 @@ class RflinkCommand(RflinkDevice):
# if the state is true, it gets set as false
self._state = self._state in [STATE_UNKNOWN, False]
# Cover options for RFlink
elif command == 'close_cover':
cmd = 'DOWN'
self._state = False
elif command == 'open_cover':
cmd = 'UP'
self._state = True
elif command == 'stop_cover':
cmd = 'STOP'
self._state = True
# Send initial command and queue repetitions.
# This allows the entity state to be updated quickly and not having to
# wait for all repetitions to be sent

View file

@ -0,0 +1,81 @@
"""
Support for Abode Security System sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.abode/
"""
import logging
from homeassistant.components.abode import AbodeDevice, DOMAIN as ABODE_DOMAIN
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['abode']
# Sensor types: Name, icon
SENSOR_TYPES = {
'temp': ['Temperature', 'thermometer'],
'humidity': ['Humidity', 'water-percent'],
'lux': ['Lux', 'lightbulb'],
}
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up a sensor for an Abode device."""
import abodepy.helpers.constants as CONST
data = hass.data[ABODE_DOMAIN]
devices = []
for device in data.abode.get_devices(generic_type=CONST.TYPE_SENSOR):
if data.is_excluded(device):
continue
for sensor_type in SENSOR_TYPES:
devices.append(AbodeSensor(data, device, sensor_type))
data.devices.extend(devices)
add_devices(devices)
class AbodeSensor(AbodeDevice):
"""A sensor implementation for Abode devices."""
def __init__(self, data, device, sensor_type):
"""Initialize a sensor for an Abode device."""
super().__init__(data, device)
self._sensor_type = sensor_type
self._icon = 'mdi:{}'.format(SENSOR_TYPES[self._sensor_type][1])
self._name = '{0} {1}'.format(self._device.name,
SENSOR_TYPES[self._sensor_type][0])
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return self._icon
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def state(self):
"""Return the state of the sensor."""
if self._sensor_type == 'temp':
return self._device.temp
elif self._sensor_type == 'humidity':
return self._device.humidity
elif self._sensor_type == 'lux':
return self._device.lux
@property
def unit_of_measurement(self):
"""Return the units of measurement."""
if self._sensor_type == 'temp':
return self._device.temp_unit
elif self._sensor_type == 'humidity':
return self._device.humidity_unit
elif self._sensor_type == 'lux':
return self._device.lux_unit

View file

@ -4,7 +4,6 @@ Support for AirVisual air quality sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.airvisual/
"""
import asyncio
from logging import getLogger
from datetime import timedelta
@ -15,13 +14,15 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import (
ATTR_ATTRIBUTION, ATTR_LATITUDE, ATTR_LONGITUDE, CONF_API_KEY,
CONF_LATITUDE, CONF_LONGITUDE, CONF_MONITORED_CONDITIONS, CONF_STATE)
CONF_LATITUDE, CONF_LONGITUDE, CONF_MONITORED_CONDITIONS, CONF_STATE,
CONF_SHOW_ON_MAP)
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
_LOGGER = getLogger(__name__)
REQUIREMENTS = ['pyairvisual==1.0.0']
_LOGGER = getLogger(__name__)
ATTR_CITY = 'city'
ATTR_COUNTRY = 'country'
ATTR_POLLUTANT_SYMBOL = 'pollutant_symbol'
@ -32,6 +33,7 @@ ATTR_TIMESTAMP = 'timestamp'
CONF_CITY = 'city'
CONF_COUNTRY = 'country'
CONF_RADIUS = 'radius'
CONF_ATTRIBUTION = "Data provided by AirVisual"
MASS_PARTS_PER_MILLION = 'ppm'
MASS_PARTS_PER_BILLION = 'ppb'
@ -39,56 +41,22 @@ VOLUME_MICROGRAMS_PER_CUBIC_METER = 'µg/m3'
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=10)
POLLUTANT_LEVEL_MAPPING = [{
'label': 'Good',
'minimum': 0,
'maximum': 50
}, {
'label': 'Moderate',
'minimum': 51,
'maximum': 100
}, {
'label': 'Unhealthy for Sensitive Groups',
'minimum': 101,
'maximum': 150
}, {
'label': 'Unhealthy',
'minimum': 151,
'maximum': 200
}, {
'label': 'Very Unhealthy',
'minimum': 201,
'maximum': 300
}, {
'label': 'Hazardous',
'minimum': 301,
'maximum': 10000
}]
POLLUTANT_LEVEL_MAPPING = [
{'label': 'Good', 'minimum': 0, 'maximum': 50},
{'label': 'Moderate', 'minimum': 51, 'maximum': 100},
{'label': 'Unhealthy for sensitive group', 'minimum': 101, 'maximum': 150},
{'label': 'Unhealthy', 'minimum': 151, 'maximum': 200},
{'label': 'Very Unhealthy', 'minimum': 201, 'maximum': 300},
{'label': 'Hazardous', 'minimum': 301, 'maximum': 10000}
]
POLLUTANT_MAPPING = {
'co': {
'label': 'Carbon Monoxide',
'unit': MASS_PARTS_PER_MILLION
},
'n2': {
'label': 'Nitrogen Dioxide',
'unit': MASS_PARTS_PER_BILLION
},
'o3': {
'label': 'Ozone',
'unit': MASS_PARTS_PER_BILLION
},
'p1': {
'label': 'PM10',
'unit': VOLUME_MICROGRAMS_PER_CUBIC_METER
},
'p2': {
'label': 'PM2.5',
'unit': VOLUME_MICROGRAMS_PER_CUBIC_METER
},
's2': {
'label': 'Sulfur Dioxide',
'unit': MASS_PARTS_PER_BILLION
}
'co': {'label': 'Carbon Monoxide', 'unit': MASS_PARTS_PER_MILLION},
'n2': {'label': 'Nitrogen Dioxide', 'unit': MASS_PARTS_PER_BILLION},
'o3': {'label': 'Ozone', 'unit': MASS_PARTS_PER_BILLION},
'p1': {'label': 'PM10', 'unit': VOLUME_MICROGRAMS_PER_CUBIC_METER},
'p2': {'label': 'PM2.5', 'unit': VOLUME_MICROGRAMS_PER_CUBIC_METER},
's2': {'label': 'Sulfur Dioxide', 'unit': MASS_PARTS_PER_BILLION},
}
SENSOR_LOCALES = {'cn': 'Chinese', 'us': 'U.S.'}
@ -99,22 +67,16 @@ SENSOR_TYPES = [
]
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_API_KEY):
cv.string,
vol.Required(CONF_API_KEY): cv.string,
vol.Required(CONF_MONITORED_CONDITIONS):
vol.All(cv.ensure_list, [vol.In(SENSOR_LOCALES)]),
vol.Optional(CONF_LATITUDE):
cv.latitude,
vol.Optional(CONF_LONGITUDE):
cv.longitude,
vol.Optional(CONF_RADIUS, default=1000):
cv.positive_int,
vol.Optional(CONF_CITY):
cv.string,
vol.Optional(CONF_STATE):
cv.string,
vol.Optional(CONF_COUNTRY):
cv.string
vol.All(cv.ensure_list, [vol.In(SENSOR_LOCALES)]),
vol.Optional(CONF_CITY): cv.string,
vol.Optional(CONF_COUNTRY): cv.string,
vol.Optional(CONF_LATITUDE): cv.latitude,
vol.Optional(CONF_LONGITUDE): cv.longitude,
vol.Optional(CONF_RADIUS, default=1000): cv.positive_int,
vol.Optional(CONF_SHOW_ON_MAP, default=True): cv.boolean,
vol.Optional(CONF_STATE): cv.string,
})
@ -123,8 +85,6 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Configure the platform and add the sensors."""
import pyairvisual as pav
_LOGGER.debug('Received configuration: %s', config)
api_key = config.get(CONF_API_KEY)
monitored_locales = config.get(CONF_MONITORED_CONDITIONS)
latitude = config.get(CONF_LATITUDE, hass.config.latitude)
@ -133,20 +93,20 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
city = config.get(CONF_CITY)
state = config.get(CONF_STATE)
country = config.get(CONF_COUNTRY)
show_on_map = config.get(CONF_SHOW_ON_MAP)
if city and state and country:
_LOGGER.debug('Using city, state, and country: %s, %s, %s', city,
state, country)
_LOGGER.debug(
"Using city, state, and country: %s, %s, %s", city, state, country)
data = AirVisualData(
pav.Client(api_key), city=city, state=state, country=country)
pav.Client(api_key), city=city, state=state, country=country,
show_on_map=show_on_map)
else:
_LOGGER.debug('Using latitude and longitude: %s, %s', latitude,
longitude)
_LOGGER.debug(
"Using latitude and longitude: %s, %s", latitude, longitude)
data = AirVisualData(
pav.Client(api_key),
latitude=latitude,
longitude=longitude,
radius=radius)
pav.Client(api_key), latitude=latitude, longitude=longitude,
radius=radius, show_on_map=show_on_map)
sensors = []
for locale in monitored_locales:
@ -167,7 +127,7 @@ class AirVisualBaseSensor(Entity):
"""Define a base class for all of our sensors."""
def __init__(self, data, name, icon, locale):
"""Initialize."""
"""Initialize the sensor."""
self._data = data
self._icon = icon
self._locale = locale
@ -177,17 +137,24 @@ class AirVisualBaseSensor(Entity):
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: 'AirVisual©',
"""Return the device state attributes."""
attrs = {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
ATTR_CITY: self._data.city,
ATTR_COUNTRY: self._data.country,
ATTR_REGION: self._data.state,
ATTR_LATITUDE: self._data.latitude,
ATTR_LONGITUDE: self._data.longitude,
ATTR_TIMESTAMP: self._data.pollution_info.get('ts')
}
if self._data.show_on_map:
attrs[ATTR_LATITUDE] = self._data.latitude
attrs[ATTR_LONGITUDE] = self._data.longitude
else:
attrs['lati'] = self._data.latitude
attrs['long'] = self._data.longitude
return attrs
@property
def icon(self):
"""Return the icon."""
@ -206,7 +173,7 @@ class AirVisualBaseSensor(Entity):
@asyncio.coroutine
def async_update(self):
"""Update the status of the sensor."""
_LOGGER.debug('Updating sensor: %s', self._name)
_LOGGER.debug("Updating sensor: %s", self._name)
self._data.update()
@ -251,14 +218,14 @@ class MainPollutantSensor(AirVisualBaseSensor):
"""Define a sensor to the main pollutant of an area."""
def __init__(self, data, name, icon, locale):
"""Initialize."""
"""Initialize the sensor."""
super().__init__(data, name, icon, locale)
self._symbol = None
self._unit = None
@property
def device_state_attributes(self):
"""Return the state attributes."""
"""Return the device state attributes."""
return merge_two_dicts(super().device_state_attributes, {
ATTR_POLLUTANT_SYMBOL: self._symbol,
ATTR_POLLUTANT_UNIT: self._unit
@ -279,7 +246,7 @@ class AirVisualData(object):
"""Define an object to hold sensor data."""
def __init__(self, client, **kwargs):
"""Initialize."""
"""Initialize the AirVisual data element."""
self._client = client
self.pollution_info = None
@ -291,6 +258,8 @@ class AirVisualData(object):
self.longitude = kwargs.get(CONF_LONGITUDE)
self._radius = kwargs.get(CONF_RADIUS)
self.show_on_map = kwargs.get(CONF_SHOW_ON_MAP)
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Update with new AirVisual data."""
@ -298,21 +267,21 @@ class AirVisualData(object):
try:
if self.city and self.state and self.country:
resp = self._client.city(self.city, self.state,
self.country).get('data')
self.longitude, self.latitude = resp.get('location').get(
'coordinates')
resp = self._client.city(
self.city, self.state, self.country).get('data')
else:
resp = self._client.nearest_city(self.latitude, self.longitude,
self._radius).get('data')
_LOGGER.debug('New data retrieved: %s', resp)
resp = self._client.nearest_city(
self.latitude, self.longitude, self._radius).get('data')
_LOGGER.debug("New data retrieved: %s", resp)
self.city = resp.get('city')
self.state = resp.get('state')
self.country = resp.get('country')
self.longitude, self.latitude = resp.get('location').get(
'coordinates')
self.pollution_info = resp.get('current', {}).get('pollution', {})
except exceptions.HTTPError as exc_info:
_LOGGER.error('Unable to retrieve data on this location: %s',
_LOGGER.error("Unable to retrieve data on this location: %s",
self.__dict__)
_LOGGER.debug(exc_info)
self.pollution_info = {}

View file

@ -9,6 +9,7 @@ import asyncio
from homeassistant.components.android_ip_webcam import (
KEY_MAP, ICON_MAP, DATA_IP_WEBCAM, AndroidIPCamEntity, CONF_HOST,
CONF_NAME, CONF_SENSORS)
from homeassistant.helpers.icon import icon_for_battery_level
DEPENDENCIES = ['android_ip_webcam']
@ -75,14 +76,5 @@ class IPWebcamSensor(AndroidIPCamEntity):
def icon(self):
"""Return the icon for the sensor."""
if self._sensor == 'battery_level' and self._state is not None:
rounded_level = round(int(self._state), -1)
returning_icon = 'mdi:battery'
if rounded_level < 10:
returning_icon = 'mdi:battery-outline'
elif self._state == 100:
returning_icon = 'mdi:battery'
else:
returning_icon = 'mdi:battery-{}'.format(str(rounded_level))
return returning_icon
return icon_for_battery_level(int(self._state))
return ICON_MAP.get(self._sensor, 'mdi:eye')

View file

@ -7,26 +7,29 @@ https://home-assistant.io/components/sensor.arlo/
import asyncio
import logging
from datetime import timedelta
import voluptuous as vol
from homeassistant.helpers import config_validation as cv
import homeassistant.helpers.config_validation as cv
from homeassistant.components.arlo import (
CONF_ATTRIBUTION, DEFAULT_BRAND, DATA_ARLO)
from homeassistant.const import (
ATTR_ATTRIBUTION, CONF_MONITORED_CONDITIONS, STATE_UNKNOWN)
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import (ATTR_ATTRIBUTION, CONF_MONITORED_CONDITIONS)
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.icon import icon_for_battery_level
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['arlo']
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=90)
# sensor_type [ description, unit, icon ]
SENSOR_TYPES = {
'last_capture': ['Last', None, 'run-fast'],
'total_cameras': ['Arlo Cameras', None, 'video'],
'captured_today': ['Captured Today', None, 'file-video'],
'battery_level': ['Battery Level', '%', 'battery-50']
}
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@ -34,8 +37,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]),
})
SCAN_INTERVAL = timedelta(seconds=90)
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
@ -47,18 +48,15 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
sensors = []
for sensor_type in config.get(CONF_MONITORED_CONDITIONS):
if sensor_type == 'total_cameras':
sensors.append(ArloSensor(hass,
SENSOR_TYPES[sensor_type][0],
arlo,
sensor_type))
sensors.append(ArloSensor(
hass, SENSOR_TYPES[sensor_type][0], arlo, sensor_type))
else:
for camera in arlo.cameras:
name = '{0} {1}'.format(SENSOR_TYPES[sensor_type][0],
camera.name)
name = '{0} {1}'.format(
SENSOR_TYPES[sensor_type][0], camera.name)
sensors.append(ArloSensor(hass, name, camera, sensor_type))
async_add_devices(sensors, True)
return True
class ArloSensor(Entity):
@ -87,6 +85,9 @@ class ArloSensor(Entity):
@property
def icon(self):
"""Icon to use in the frontend, if any."""
if self._sensor_type == 'battery_level' and self._state is not None:
return icon_for_battery_level(battery_level=int(self._state),
charging=False)
return self._icon
@property
@ -109,18 +110,25 @@ class ArloSensor(Entity):
video = self._data.videos()[0]
self._state = video.created_at_pretty("%m-%d-%Y %H:%M:%S")
except (AttributeError, IndexError):
self._state = STATE_UNKNOWN
self._state = None
elif self._sensor_type == 'battery_level':
try:
self._state = self._data.get_battery_level
except TypeError:
self._state = None
@property
def device_state_attributes(self):
"""Return the state attributes."""
"""Return the device state attributes."""
attrs = {}
attrs[ATTR_ATTRIBUTION] = CONF_ATTRIBUTION
attrs['brand'] = DEFAULT_BRAND
if self._sensor_type == 'last_capture' or \
self._sensor_type == 'captured_today':
self._sensor_type == 'captured_today' or \
self._sensor_type == 'battery_level':
attrs['model'] = self._data.model_id
return attrs

View file

@ -42,7 +42,7 @@ def discover_sensors(topic, payload):
name = parts[2] + " Moisture"
return ArwnSensor(name, 'moisture', unit, "mdi:water-percent")
if domain == "rain":
if len(parts) >= 2 and parts[2] == "today":
if len(parts) >= 3 and parts[2] == "today":
return ArwnSensor("Rain Since Midnight", 'since_midnight',
"in", "mdi:water")
if domain == 'barometer':

View file

@ -40,7 +40,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.string,
vol.Optional(CONF_HOST, default=None): cv.string,
vol.Optional(CONF_DSMR_VERSION, default=DEFAULT_DSMR_VERSION): vol.All(
cv.string, vol.In(['4', '2.2'])),
cv.string, vol.In(['5', '4', '2.2'])),
vol.Optional(CONF_RECONNECT_INTERVAL, default=30): int,
})
@ -73,7 +73,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
devices = [DSMREntity(name, obis) for name, obis in obis_mapping]
# Protocol version specific obis
if dsmr_version == '4':
if dsmr_version in ('4', '5'):
gas_obis = obis_ref.HOURLY_GAS_METER_READING
else:
gas_obis = obis_ref.GAS_METER_READING

View file

@ -82,6 +82,11 @@ class FedexSensor(Entity):
"""Return the state of the sensor."""
return self._state
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return 'packages'
def _update(self):
"""Update device state."""
import fedexdeliverymanager

View file

@ -17,7 +17,7 @@ from homeassistant.components.http import HomeAssistantView
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import ATTR_ATTRIBUTION
from homeassistant.helpers.entity import Entity
from homeassistant.util.icon import icon_for_battery_level
from homeassistant.helpers.icon import icon_for_battery_level
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['fitbit==0.3.0']

View file

@ -20,7 +20,7 @@ import homeassistant.helpers.config_validation as cv
import homeassistant.helpers.location as location
import homeassistant.util.dt as dt_util
REQUIREMENTS = ['googlemaps==2.4.6']
REQUIREMENTS = ['googlemaps==2.5.1']
_LOGGER = logging.getLogger(__name__)

View file

@ -22,6 +22,8 @@ import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
REQUIREMENTS = ['influxdb==4.1.1']
DEFAULT_HOST = 'localhost'
DEFAULT_PORT = 8086
DEFAULT_DATABASE = 'home_assistant'
@ -37,7 +39,6 @@ CONF_FIELD = 'field'
CONF_MEASUREMENT_NAME = 'measurement'
CONF_WHERE = 'where'
REQUIREMENTS = ['influxdb==3.0.0']
_QUERY_SCHEME = vol.Schema({
vol.Required(CONF_NAME): cv.string,

View file

@ -6,7 +6,7 @@ https://home-assistant.io/ecosystem/ios/
"""
from homeassistant.components import ios
from homeassistant.helpers.entity import Entity
from homeassistant.util.icon import icon_for_battery_level
from homeassistant.helpers.icon import icon_for_battery_level
DEPENDENCIES = ['ios']

View file

@ -44,6 +44,18 @@ SENSOR_TYPES = {
'ipv4_in': ['IPv4 In', 'kb/s', 'system.ipv4', 'received', 0],
'ipv4_out': ['IPv4 Out', 'kb/s', 'system.ipv4', 'sent', 0],
'disk_free': ['Disk Free', 'GiB', 'disk_space._', 'avail', 2],
'cpu_iowait': ['CPU IOWait', '%', 'system.cpu', 'iowait', 1],
'cpu_user': ['CPU User', '%', 'system.cpu', 'user', 1],
'cpu_system': ['CPU System', '%', 'system.cpu', 'system', 1],
'cpu_softirq': ['CPU SoftIRQ', '%', 'system.cpu', 'softirq', 1],
'cpu_guest': ['CPU Guest', '%', 'system.cpu', 'guest', 1],
'uptime': ['Uptime', 's', 'system.uptime', 'uptime', 0],
'packets_received': ['Packets Received', 'packets/s', 'ipv4.packets',
'received', 0],
'packets_sent': ['Packets Sent', 'packets/s', 'ipv4.packets',
'sent', 0],
'connections': ['Active Connections', 'Count',
'netfilter.conntrack_sockets', 'connections', 0]
}
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({

View file

@ -61,8 +61,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
'[.-]*')):
sensor_id = os.path.split(device_folder)[1]
device_file = os.path.join(device_folder, 'w1_slave')
devs.append(OneWire(device_names.get(sensor_id, sensor_id),
device_file, 'temperature'))
devs.append(OneWireDirect(device_names.get(sensor_id,
sensor_id),
device_file, 'temperature'))
else:
for family_file_path in glob(os.path.join(base_dir, '*', 'family')):
family_file = open(family_file_path, "r")
@ -73,8 +74,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
os.path.split(family_file_path)[0])[1]
device_file = os.path.join(
os.path.split(family_file_path)[0], sensor_value)
devs.append(OneWire(device_names.get(sensor_id, sensor_id),
device_file, sensor_key))
devs.append(OneWireOWFS(device_names.get(sensor_id,
sensor_id),
device_file, sensor_key))
if devs == []:
_LOGGER.error("No onewire sensor found. Check if dtoverlay=w1-gpio "
@ -97,9 +99,8 @@ class OneWire(Entity):
def _read_value_raw(self):
"""Read the value as it is returned by the sensor."""
ds_device_file = open(self._device_file, 'r')
lines = ds_device_file.readlines()
ds_device_file.close()
with open(self._device_file, 'r') as ds_device_file:
lines = ds_device_file.readlines()
return lines
@property
@ -117,30 +118,37 @@ class OneWire(Entity):
"""Return the unit the value is expressed in."""
return self._unit_of_measurement
class OneWireDirect(OneWire):
"""Implementation of an One wire Sensor directly connected to RPI GPIO."""
def update(self):
"""Get the latest data from the device."""
value = None
if self._device_file.startswith(DEFAULT_MOUNT_DIR):
lines = self._read_value_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = self._read_value_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = self._read_value_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
value_string = lines[1][equals_pos+2:]
value = round(float(value_string) / 1000.0, 1)
else:
try:
ds_device_file = open(self._device_file, 'r')
value_read = ds_device_file.readlines()
ds_device_file.close()
if len(value_read) == 1:
value = round(float(value_read[0]), 1)
except ValueError:
_LOGGER.warning("Invalid value read from %s",
self._device_file)
except FileNotFoundError:
_LOGGER.warning(
"Cannot read from sensor: %s", self._device_file)
equals_pos = lines[1].find('t=')
if equals_pos != -1:
value_string = lines[1][equals_pos + 2:]
value = round(float(value_string) / 1000.0, 1)
self._state = value
class OneWireOWFS(OneWire):
"""Implementation of an One wire Sensor through owfs."""
def update(self):
"""Get the latest data from the device."""
value = None
try:
value_read = self._read_value_raw()
if len(value_read) == 1:
value = round(float(value_read[0]), 1)
except ValueError:
_LOGGER.warning("Invalid value read from %s", self._device_file)
except FileNotFoundError:
_LOGGER.warning("Cannot read from sensor: %s", self._device_file)
self._state = value

Some files were not shown because too many files have changed in this diff Show more