diff --git a/README.md b/README.md index 3f3709ff..4a58a82f 100644 --- a/README.md +++ b/README.md @@ -164,13 +164,13 @@ rows: ## Basic -| Name | Type | Description | -| ------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| type | string | Must be `custom:android-tv-card` | -| title | string | Title to display in the card header. | -| remote_id | string | The `remote` entity id to control, required for default `key` and `source` actions. Also autofills into service call data when `autofill_entity_id` is set to true. | -| media_player_id | string | A `media_player` entity ID to autofill into service call data when `autofill_entity_id` is set to true. Also populates `slider_id` if it is not present. | -| autofill_entity_id | boolean | Enable autofilling of the entity ID of `remote` and `media_player` service calls if no target IDs are provided, defaults to `false`. | +| Name | Type | Description | +| ------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| type | string | Must be `custom:android-tv-card` | +| title | string | Title to display in the card header. | +| remote_id | string | The `remote` entity id to control, required for default `key` and `source` actions. Also autofills into service call data when `autofill_entity_id` is set to true. | +| media_player_id | string | A `media_player` entity ID to autofill into service call data when `autofill_entity_id` is set to true. Also populates `slider_id` if it is not present and autofills for the `kodi` and `denonavr` domains. | +| autofill_entity_id | boolean | Enable autofilling of the entity ID of `remote` and `media_player` service calls if no target IDs are provided, defaults to `false`. | All fields are technically optional except for `type`, but the card will not function unless you customize it using the above options. Using only these options you will get an empty card (or almost empty, if you set a title). @@ -824,88 +824,66 @@ Like buttons, double tap actions introduces a 200ms delay to single taps, and th In addition to regular tap, hold, and double tap actions, the touchpad can also be programmed with multi touch actions by creating custom actions for `multi_tap_action`, `multi_hold_action`, and `multi_double_tap_action`. These actions are triggered by perform a tap, double tap, or hold tap action with more than one finger for `center`, or a single swipe or hold swipe with more than one finger for `up`, `down`, `left`, and `right`. ```yaml +media_player_id: media_player.kodi +autofill_entity_id: true custom_actions: up: tap_action: service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Up multi_tap_action: service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Application.SetVolume volume: increment down: tap_action: service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Down multi_tap_action: service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Application.SetVolume volume: decrement left: tap_action: service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Left right: tap_action: service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Right center: tap_action: service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Select double_tap_action: service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Back hold_action: service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.ContextMenu multi_tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Player.PlayPause playerid: 1 multi_hold_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Home multi_double_tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Info ``` @@ -1143,6 +1121,8 @@ Apple TV. ```yaml type: custom:android-tv-card remote_id: remote.appletv +media_player_id: media_player.appletv +autofill_entity_id: true rows: - - power - menu @@ -1239,64 +1219,48 @@ custom_actions: service: media_player.select_source data: source: Prime Video - target: - entity_id: media_player.appletv netflix: tap_action: action: call-service service: media_player.select_source data: source: Netflix - target: - entity_id: media_player.appletv spotify: tap_action: action: call-service service: media_player.select_source data: source: Spotify - target: - entity_id: media_player.appletv disney: tap_action: action: call-service service: media_player.select_source data: source: Disney+ - target: - entity_id: media_player.appletv youtube: tap_action: action: call-service service: media_player.select_source data: source: YouTube - target: - entity_id: media_player.appletv appletv: tap_action: action: call-service service: media_player.select_source data: source: TV - target: - entity_id: media_player.appletv max: tap_action: action: call-service service: media_player.select_source data: source: HBO Max - target: - entity_id: media_player.appletv skyshowtime: tap_action: action: call-service service: media_player.select_source data: source: SkyShowtime - target: - entity_id: media_player.appletv plex: icon: mdi:plex tap_action: @@ -1304,8 +1268,6 @@ custom_actions: service: media_player.select_source data: source: Plex - target: - entity_id: media_player.appletv discovery: icon: discovery tap_action: @@ -1313,8 +1275,6 @@ custom_actions: service: media_player.select_source data: source: discovery+ - target: - entity_id: media_player.appletv viaplay: icon: viaplay tap_action: @@ -1322,8 +1282,6 @@ custom_actions: service: media_player.select_source data: source: Viaplay - target: - entity_id: media_player.appletv tv2play: icon: tv2play tap_action: @@ -1331,8 +1289,6 @@ custom_actions: service: media_player.select_source data: source: TV 2 Play - target: - entity_id: media_player.appletv nrktv: icon: nrktv tap_action: @@ -1340,8 +1296,6 @@ custom_actions: service: media_player.select_source data: source: NRK TV - target: - entity_id: media_player.appletv allente: icon: allente tap_action: @@ -1349,8 +1303,6 @@ custom_actions: service: media_player.select_source data: source: Allente - target: - entity_id: media_player.appletv ``` Result: @@ -1365,6 +1317,8 @@ Kodi with keyboard and touchpad. Use the [Kodi JSON-RPC API](https://kodi.wiki/v type: custom:android-tv-card keyboard_id: media_player.kodi keyboard_mode: KODI +media_player_id: media_player.kodi +autofill_entity_id: true rows: - - back - home @@ -1388,62 +1342,46 @@ custom_actions: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Up down: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Down left: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Left right: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Right center: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Select double_tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Back hold_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.ContextMenu back: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Back search: @@ -1458,8 +1396,6 @@ custom_actions: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Application.SetMute mute: toggle @@ -1467,8 +1403,6 @@ custom_actions: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Application.SetVolume volume: increment @@ -1476,8 +1410,6 @@ custom_actions: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Application.SetVolume volume: decrement @@ -1485,32 +1417,24 @@ custom_actions: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.ContextMenu home: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Home info: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Input.Info play_pause: tap_action: action: call-service service: kodi.call_method - target: - entity_id: media_player.kodi data: method: Player.PlayPause playerid: 1 @@ -1561,7 +1485,8 @@ Marantz Receiver. ```yaml type: custom:android-tv-card -entity_id: media_player.marantz_sr7013 +media_player_id: media_player.marantz_sr7013 +autofill_entity_id: true rows: - - touchpad touchpad_style: @@ -1571,47 +1496,35 @@ custom_actions: tap_action: action: call-service service: denonavr.get_command - target: - entity_id: media_player.marantz_sr7013 data: command: /goform/formiPhoneAppDirect.xml?MNCDN up: tap_action: action: call-service service: denonavr.get_command - target: - entity_id: media_player.marantz_sr7013 data: command: /goform/formiPhoneAppDirect.xml?MNCUP left: tap_action: action: call-service service: denonavr.get_command - target: - entity_id: media_player.marantz_sr7013 data: command: /goform/formiPhoneAppDirect.xml?MNCLT right: tap_action: action: call-service service: denonavr.get_command - target: - entity_id: media_player.marantz_sr7013 data: command: /goform/formiPhoneAppDirect.xml?MNCRT center: tap_action: action: call-service service: denonavr.get_command - target: - entity_id: media_player.marantz_sr7013 data: command: /goform/formiPhoneAppDirect.xml?MNENT double_tap_action: action: call-service service: denonavr.get_command - target: - entity_id: media_player.marantz_sr7013 data: command: /goform/formiPhoneAppDirect.xml?MNRTN ``` @@ -1726,7 +1639,8 @@ Samsung TV, using [ha-samsungtv-smart](https://github.com/ollo69/ha-samsungtv-sm ```yaml type: custom:android-tv-card -slider_id: media_player.samsung_tv +media_player_id: media_player.samsung_tv +autofill_entity_id: true custom_icons: dazn: >- m14.774 8.291.772-2.596.79 2.596zm3.848 @@ -1769,7 +1683,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_0 '1': @@ -1778,7 +1691,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_1 '2': @@ -1787,7 +1699,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_2 '3': @@ -1796,7 +1707,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_3 '4': @@ -1805,7 +1715,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_4 '5': @@ -1814,7 +1723,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_5 '6': @@ -1823,7 +1731,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_6 '7': @@ -1832,7 +1739,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_7 '8': @@ -1841,7 +1747,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_8 '9': @@ -1850,7 +1755,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_9 up: @@ -1858,7 +1762,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_UP down: @@ -1866,7 +1769,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_DOWN left: @@ -1874,7 +1776,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_LEFT right: @@ -1882,7 +1783,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_RIGHT center: @@ -1890,7 +1790,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_ENTER power: @@ -1898,14 +1797,11 @@ custom_actions: tap_action: action: call-service service: media_player.toggle - target: - entity_id: media_player.samsung_tv home: tap_action: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_HOME back: @@ -1913,7 +1809,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_RETURN volume_mute: @@ -1921,7 +1816,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_MUTE ch_up: @@ -1930,7 +1824,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_CHUP ch_down: @@ -1939,7 +1832,6 @@ custom_actions: action: call-service service: media_player.play_media data: - entity_id: media_player.samsung_tv media_content_type: send_key media_content_id: KEY_CHDOWN DAZN: @@ -1948,7 +1840,6 @@ custom_actions: action: call-service service: media_player.select_source data: - entity_id: media_player.samsung_tv source: DAZN netflix: icon: mdi:netflix @@ -1956,7 +1847,6 @@ custom_actions: action: call-service service: media_player.select_source data: - entity_id: media_player.samsung_tv source: Netflix youtube: icon: mdi:youtube @@ -1964,7 +1854,6 @@ custom_actions: action: call-service service: media_player.select_source data: - entity_id: media_player.samsung_tv source: YouTube rows: - - power diff --git a/dist/android-tv-card.min.js b/dist/android-tv-card.min.js index 7e47cbe8..6aa1a667 100644 --- a/dist/android-tv-card.min.js +++ b/dist/android-tv-card.min.js @@ -82,7 +82,7 @@ position: relative; --size: 48px; } - `}applyThemesOnElement(t,e,i){(0,l.applyThemesOnElement)(t,e,i)}}n([(0,a.property)({attribute:!1})],d.prototype,"hass",void 0),n([(0,a.property)({attribute:!1})],d.prototype,"config",void 0),customElements.define("android-tv-card",d),window.customCards=window.customCards||[],window.customCards.push({type:"android-tv-card",name:"Android TV Card",description:"Remote for Android TV"}),window.structuredClone||(window.structuredClone=t=>JSON.parse(JSON.stringify(t))),window.performance||(window.performance=window.Date)},5032:function(t,e,i){"use strict";var n=this&&this.__decorate||function(t,e,i,n){var r,o=arguments.length,s=o<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,i,n);else for(var a=t.length-1;a>=0;a--)(r=t[a])&&(s=(o<3?r(s):o>3?r(e,i,s):r(e,i))||s);return o>3&&s&&Object.defineProperty(e,i,s),s};Object.defineProperty(e,"__esModule",{value:!0}),e.BaseKeyboardElement=void 0;const r=i(5595),o=i(5984);let s=class extends o.RemoteButton{onStart(t){this.swiping=!1}};e.BaseKeyboardElement=s,n([(0,r.property)({attribute:!1})],s.prototype,"keyboardId",void 0),n([(0,r.property)({attribute:!1})],s.prototype,"keyboardMode",void 0),e.BaseKeyboardElement=s=n([(0,r.customElement)("base-keyboard-element")],s)},8666:function(t,e,i){"use strict";var n=this&&this.__decorate||function(t,e,i,n){var r,o=arguments.length,s=o<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,i,n);else for(var a=t.length-1;a>=0;a--)(r=t[a])&&(s=(o<3?r(s):o>3?r(e,i,s):r(e,i))||s);return o>3&&s&&Object.defineProperty(e,i,s),s};Object.defineProperty(e,"__esModule",{value:!0}),e.BaseRemoteElement=void 0;const r=i(1814),o=i(5595),s=i(6197),a=i(839);let c=class extends r.LitElement{constructor(){super(...arguments),this.autofillEntityId=!1,this.value=0,this.fireMouseEvent=!0,this.swiping=!1}fireHapticEvent(t){var e;(null===(e=this.renderTemplate(this.actions.haptics))||void 0===e||e)&&(0,s.forwardHaptic)(t)}endAction(){this.buttonPressStart=void 0,this.buttonPressEnd=void 0,this.swiping=!1,this.initialX=void 0,this.initialY=void 0}sendAction(t,e=this.actions){var i,n,r,o,s,a,c,l,u;let h;switch(t){case"momentary_start_action":h=e.momentary_start_action;break;case"momentary_end_action":h=e.momentary_end_action;break;case"multi_hold_action":h=null!==(r=null!==(n=null!==(i=e.multi_hold_action)&&void 0!==i?i:e.hold_action)&&void 0!==n?n:e.multi_tap_action)&&void 0!==r?r:e.tap_action;break;case"multi_double_tap_action":h=null!==(a=null!==(s=null!==(o=e.multi_double_tap_action)&&void 0!==o?o:e.double_tap_action)&&void 0!==s?s:e.multi_tap_action)&&void 0!==a?a:e.tap_action;break;case"multi_tap_action":h=null!==(c=e.multi_tap_action)&&void 0!==c?c:e.tap_action;break;case"hold_action":h=null!==(l=e.hold_action)&&void 0!==l?l:e.tap_action;break;case"double_tap_action":h=null!==(u=e.double_tap_action)&&void 0!==u?u:e.tap_action;break;default:h=e.tap_action}if(this.handleConfirmation(h))try{switch(h.action){case"navigate":this.navigate(h);break;case"url":this.toUrl(h);break;case"assist":this.assist(h);break;case"more-info":this.moreInfo(h);break;case"call-service":this.callService(h);break;case"source":this.changeSource(h.source);break;case"key":this.sendCommand(h.key,t);break;case"fire-dom-event":this.fireDomEvent(h)}}catch(t){throw this.endAction(),t}}sendCommand(t,e){const i={entity_id:this.renderTemplate(this.remoteId),command:this.renderTemplate(t)};"hold_action"!=e||"hold_action"in this.actions||(i.hold_secs=.5),this.hass.callService("remote","send_command",i)}changeSource(t){this.hass.callService("remote","turn_on",{entity_id:this.renderTemplate(this.remoteId),activity:this.renderTemplate(t)})}callService(t){const e=this.renderTemplate(t.service),[i,n]=e.split(".");let r=structuredClone(t.data);for(const t in r)if(Array.isArray(r[t]))for(const e in r[t])r[t][e]=this.renderTemplate(r[t][e]);else r[t]=this.renderTemplate(r[t]);if(this.renderTemplate(this.autofillEntityId)){let t;switch(i){case"remote":t=this.remoteId;break;case"media_player":t=this.mediaPlayerId}!t||"entity_id"in(null!=r?r:{})||"device_id"in(null!=r?r:{})||"area_id"in(null!=r?r:{})||(r=Object.assign(Object.assign({},r),{entity_id:t}))}this.hass.callService(i,n,r)}navigate(t){var e,i,n;const r=null!==(e=this.renderTemplate(t.navigation_path))&&void 0!==e?e:"",o=null!==(i=this.renderTemplate(t.navigation_replace))&&void 0!==i&&i;if(r.includes("//"))return void console.error('Protocol detected in navigation path. To navigate to another website use the action "url" with the key "url_path" instead.');1==o?window.history.replaceState((null===(n=window.history.state)||void 0===n?void 0:n.root)?{root:!0}:null,"",r):window.history.pushState(null,"",r);const s=new Event("location-changed",{bubbles:!1,cancelable:!0,composed:!1});s.detail={replace:1==o},window.dispatchEvent(s)}toUrl(t){var e;let i=null!==(e=this.renderTemplate(t.url_path))&&void 0!==e?e:"";i.includes("//")||(i=`https://${i}`),window.open(i)}assist(t){var e,i,n,r,o,s,a;(null===(r=null===(n=null===(i=null===(e=this.hass)||void 0===e?void 0:e.auth)||void 0===i?void 0:i.external)||void 0===n?void 0:n.config)||void 0===r?void 0:r.hasAssist)?null===(a=null===(s=null===(o=this.hass)||void 0===o?void 0:o.auth)||void 0===s?void 0:s.external)||void 0===a||a.fireMessage({type:"assist/show",payload:{pipeline_id:t.pipeline_id,start_listening:t.start_listening}}):window.open(`${window.location.href}?conversation=1`,"_self")}moreInfo(t){var e;const i=this.renderTemplate(null===(e=t.data)||void 0===e?void 0:e.entity_id),n=new Event("hass-more-info",{bubbles:!0,cancelable:!0,composed:!0});n.detail={entityId:i},this.dispatchEvent(n)}fireDomEvent(t){const e=new Event("ll-custom",{composed:!0,bubbles:!0});e.detail=t,this.dispatchEvent(e)}handleConfirmation(t){if("confirmation"in t){let e=t.confirmation;if("string"==typeof e&&(e=this.renderTemplate(t.confirmation)),0!=e){this.fireHapticEvent("warning");let i="";if(1!=e&&"text"in e)i=this.renderTemplate(e.text);else switch(t.action){case"navigate":i=`Are you sure you want to navigate to '${this.renderTemplate(t.navigation_path)}'`;break;case"url":i=`Are you sure you want to navigate to '${this.renderTemplate(t.url_path)}'?`;break;case"assist":i="Are you sure you want to call assist?";break;case"none":return!1;case"call-service":i=`Are you sure you want to run action '${this.renderTemplate(t.service)}'?`;break;case"source":i=`Are you sure you want to run action '${this.renderTemplate(t.source)}'?`;break;default:i=`Are you sure you want to run action '${this.renderTemplate(t.key)}'?`}if(1==e){if(!confirm(i))return!1}else if("exemptions"in e){if(!e.exemptions.map((t=>this.renderTemplate(t.user))).includes(this.hass.user.id)&&!confirm(i))return!1}else if(!confirm(i))return!1}}return!0}renderTemplate(t,e){var i;if(!e){let t=0;this.buttonPressStart&&this.buttonPressEnd&&(t=(this.buttonPressEnd-this.buttonPressStart)/1e3),e={VALUE:this.value,HOLD_SECS:null!=t?t:0}}if("string"==typeof(t=(0,a.renderTemplate)(this.hass,t,e)))for(const n in e)n in e&&(t==n?t=e[n]:t.toString().includes(n)&&(t=t.toString().replace(new RegExp(n,"g"),(null!==(i=e[n])&&void 0!==i?i:"").toString())));return t}buildStyle(t={},e){const i=structuredClone(t);for(const t in i)i[t]=this.renderTemplate(i[t],e);return i}onStart(t){}onEnd(t){}onMove(t){}onMouseDown(t){this.fireMouseEvent&&this.onStart(t)}onMouseUp(t){this.fireMouseEvent&&this.onEnd(t),this.fireMouseEvent=!0}onMouseMove(t){this.fireMouseEvent&&this.onMove(t)}onTouchStart(t){this.fireMouseEvent=!1,this.onStart(t)}onTouchEnd(t){this.fireMouseEvent=!1,this.onEnd(t)}onTouchMove(t){this.fireMouseEvent=!1,this.onMove(t)}onContextMenu(t){if(!this.fireMouseEvent)return t.preventDefault(),t.stopPropagation(),!1}render(){}static get styles(){return r.css``}};e.BaseRemoteElement=c,n([(0,o.property)({attribute:!1})],c.prototype,"hass",void 0),n([(0,o.property)({attribute:!1})],c.prototype,"actions",void 0),n([(0,o.property)({attribute:!1})],c.prototype,"autofillEntityId",void 0),n([(0,o.property)({attribute:!1})],c.prototype,"remoteId",void 0),n([(0,o.property)({attribute:!1})],c.prototype,"mediaPlayerId",void 0),n([(0,o.state)()],c.prototype,"value",void 0),n([(0,o.eventOptions)({passive:!0})],c.prototype,"onMouseDown",null),n([(0,o.eventOptions)({passive:!0})],c.prototype,"onMouseMove",null),n([(0,o.eventOptions)({passive:!0})],c.prototype,"onTouchStart",null),n([(0,o.eventOptions)({passive:!0})],c.prototype,"onTouchMove",null),e.BaseRemoteElement=c=n([(0,o.customElement)("base-remote-element")],c)},5984:function(t,e,i){"use strict";var n=this&&this.__decorate||function(t,e,i,n){var r,o=arguments.length,s=o<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,i,n);else for(var a=t.length-1;a>=0;a--)(r=t[a])&&(s=(o<3?r(s):o>3?r(e,i,s):r(e,i))||s);return o>3&&s&&Object.defineProperty(e,i,s),s};Object.defineProperty(e,"__esModule",{value:!0}),e.RemoteButton=void 0;const r=i(1814),o=i(5595),s=i(8921),a=i(8666);let c=class extends a.BaseRemoteElement{constructor(){super(...arguments),this.clickCount=0,this.hold=!1}onClick(t){var e;if(t.stopImmediatePropagation(),this.clickCount++,"double_tap_action"in this.actions&&"none"!=this.renderTemplate(this.actions.double_tap_action.action))if(this.clickCount>1)this.fireHapticEvent("success"),this.sendAction("double_tap_action"),this.endAction();else{const t="double_tap_window"in(null!==(e=this.actions.double_tap_action)&&void 0!==e?e:{})?this.renderTemplate(this.actions.double_tap_action.double_tap_window):200;this.clickTimer||(this.clickTimer=setTimeout((()=>{this.fireHapticEvent("light"),this.sendAction("tap_action"),this.endAction()}),t))}else this.fireHapticEvent("light"),this.sendAction("tap_action"),this.endAction()}onStart(t){var e;if(this.swiping=!1,"targetTouches"in t?(this.initialX=t.targetTouches[0].clientX,this.initialY=t.targetTouches[0].clientY):(this.initialX=t.clientX,this.initialY=t.clientY),"momentary_start_action"in this.actions&&"none"!=this.renderTemplate(this.actions.momentary_start_action.action))this.fireHapticEvent("light"),this.buttonPressStart=performance.now(),this.sendAction("momentary_start_action");else if("momentary_end_action"in this.actions&&"none"!=this.renderTemplate(this.actions.momentary_end_action.action))this.fireHapticEvent("light"),this.buttonPressStart=performance.now();else if(!this.holdTimer){const t="hold_time"in(null!==(e=this.actions.hold_action)&&void 0!==e?e:{})?this.renderTemplate(this.actions.hold_action.hold_time):500;this.holdTimer=setTimeout((()=>{var t,e;if(!this.swiping)if(this.hold=!0,"repeat"==this.renderTemplate(null===(t=this.actions.hold_action)||void 0===t?void 0:t.action)){const t="repeat_delay"in(null!==(e=this.actions.hold_action)&&void 0!==e?e:{})?this.renderTemplate(this.actions.hold_action.repeat_delay):100;this.holdInterval||(this.holdInterval=setInterval((()=>{this.fireHapticEvent("selection"),this.sendAction("tap_action")}),t))}else this.fireHapticEvent("medium"),this.sendAction("hold_action")}),t)}}onEnd(t){this.swiping||("momentary_end_action"in this.actions&&"none"!=this.renderTemplate(this.actions.momentary_end_action.action)?(this.fireHapticEvent("selection"),this.buttonPressEnd=performance.now(),this.sendAction("momentary_end_action"),this.endAction()):"momentary_start_action"in this.actions&&"none"!=this.renderTemplate(this.actions.momentary_start_action.action)?this.endAction():this.hold?(t.stopImmediatePropagation(),t.preventDefault(),this.endAction()):this.onClick(t))}onMove(t){var e,i;let n,r;"targetTouches"in t?(n=t.targetTouches[0].clientX,r=t.targetTouches[0].clientY):(n=t.clientX,r=t.clientY);const o=(null!==(e=this.initialX)&&void 0!==e?e:n)-n,s=(null!==(i=this.initialY)&&void 0!==i?i:r)-r;Math.abs(Math.abs(o)-Math.abs(s))>8&&(this.endAction(),this.swiping=!0)}onMouseLeave(t){this.endAction(),this.swiping=!0}endAction(){clearTimeout(this.clickTimer),this.clickTimer=void 0,this.clickCount=0,clearTimeout(this.holdTimer),clearInterval(this.holdInterval),this.holdTimer=void 0,this.holdInterval=void 0,this.hold=!1,super.endAction()}render(t){var e,i,n;const o=null!==(e=this.renderTemplate(this.actions.icon))&&void 0!==e?e:"";let a,c=r.html``;o.includes(":")?c=r.html``:a=null!==(i=this.icons[o])&&void 0!==i?i:o;const l=this.renderTemplate(this.actionKey);return r.html` + `}applyThemesOnElement(t,e,i){(0,l.applyThemesOnElement)(t,e,i)}}n([(0,a.property)({attribute:!1})],d.prototype,"hass",void 0),n([(0,a.property)({attribute:!1})],d.prototype,"config",void 0),customElements.define("android-tv-card",d),window.customCards=window.customCards||[],window.customCards.push({type:"android-tv-card",name:"Android TV Card",description:"Remote for Android TV"}),window.structuredClone||(window.structuredClone=t=>JSON.parse(JSON.stringify(t))),window.performance||(window.performance=window.Date)},5032:function(t,e,i){"use strict";var n=this&&this.__decorate||function(t,e,i,n){var r,o=arguments.length,s=o<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,i,n);else for(var a=t.length-1;a>=0;a--)(r=t[a])&&(s=(o<3?r(s):o>3?r(e,i,s):r(e,i))||s);return o>3&&s&&Object.defineProperty(e,i,s),s};Object.defineProperty(e,"__esModule",{value:!0}),e.BaseKeyboardElement=void 0;const r=i(5595),o=i(5984);let s=class extends o.RemoteButton{onStart(t){this.swiping=!1}};e.BaseKeyboardElement=s,n([(0,r.property)({attribute:!1})],s.prototype,"keyboardId",void 0),n([(0,r.property)({attribute:!1})],s.prototype,"keyboardMode",void 0),e.BaseKeyboardElement=s=n([(0,r.customElement)("base-keyboard-element")],s)},8666:function(t,e,i){"use strict";var n=this&&this.__decorate||function(t,e,i,n){var r,o=arguments.length,s=o<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,i,n);else for(var a=t.length-1;a>=0;a--)(r=t[a])&&(s=(o<3?r(s):o>3?r(e,i,s):r(e,i))||s);return o>3&&s&&Object.defineProperty(e,i,s),s};Object.defineProperty(e,"__esModule",{value:!0}),e.BaseRemoteElement=void 0;const r=i(1814),o=i(5595),s=i(6197),a=i(839);let c=class extends r.LitElement{constructor(){super(...arguments),this.autofillEntityId=!1,this.value=0,this.fireMouseEvent=!0,this.swiping=!1}fireHapticEvent(t){var e;(null===(e=this.renderTemplate(this.actions.haptics))||void 0===e||e)&&(0,s.forwardHaptic)(t)}endAction(){this.buttonPressStart=void 0,this.buttonPressEnd=void 0,this.swiping=!1,this.initialX=void 0,this.initialY=void 0}sendAction(t,e=this.actions){var i,n,r,o,s,a,c,l,u;let h;switch(t){case"momentary_start_action":h=e.momentary_start_action;break;case"momentary_end_action":h=e.momentary_end_action;break;case"multi_hold_action":h=null!==(r=null!==(n=null!==(i=e.multi_hold_action)&&void 0!==i?i:e.hold_action)&&void 0!==n?n:e.multi_tap_action)&&void 0!==r?r:e.tap_action;break;case"multi_double_tap_action":h=null!==(a=null!==(s=null!==(o=e.multi_double_tap_action)&&void 0!==o?o:e.double_tap_action)&&void 0!==s?s:e.multi_tap_action)&&void 0!==a?a:e.tap_action;break;case"multi_tap_action":h=null!==(c=e.multi_tap_action)&&void 0!==c?c:e.tap_action;break;case"hold_action":h=null!==(l=e.hold_action)&&void 0!==l?l:e.tap_action;break;case"double_tap_action":h=null!==(u=e.double_tap_action)&&void 0!==u?u:e.tap_action;break;default:h=e.tap_action}if(this.handleConfirmation(h))try{switch(h.action){case"navigate":this.navigate(h);break;case"url":this.toUrl(h);break;case"assist":this.assist(h);break;case"more-info":this.moreInfo(h);break;case"call-service":this.callService(h);break;case"source":this.changeSource(h.source);break;case"key":this.sendCommand(h.key,t);break;case"fire-dom-event":this.fireDomEvent(h)}}catch(t){throw this.endAction(),t}}sendCommand(t,e){const i={entity_id:this.renderTemplate(this.remoteId),command:this.renderTemplate(t)};"hold_action"!=e||"hold_action"in this.actions||(i.hold_secs=.5),this.hass.callService("remote","send_command",i)}changeSource(t){this.hass.callService("remote","turn_on",{entity_id:this.renderTemplate(this.remoteId),activity:this.renderTemplate(t)})}callService(t){const e=this.renderTemplate(t.service),[i,n]=e.split(".");let r=structuredClone(t.data);for(const t in r)if(Array.isArray(r[t]))for(const e in r[t])r[t][e]=this.renderTemplate(r[t][e]);else r[t]=this.renderTemplate(r[t]);if(this.renderTemplate(this.autofillEntityId)){let t;switch(i){case"remote":t=this.remoteId;break;case"media_player":case"kodi":case"denonavr":t=this.mediaPlayerId}!t||"entity_id"in(null!=r?r:{})||"device_id"in(null!=r?r:{})||"area_id"in(null!=r?r:{})||(r=Object.assign(Object.assign({},r),{entity_id:t}))}this.hass.callService(i,n,r)}navigate(t){var e,i,n;const r=null!==(e=this.renderTemplate(t.navigation_path))&&void 0!==e?e:"",o=null!==(i=this.renderTemplate(t.navigation_replace))&&void 0!==i&&i;if(r.includes("//"))return void console.error('Protocol detected in navigation path. To navigate to another website use the action "url" with the key "url_path" instead.');1==o?window.history.replaceState((null===(n=window.history.state)||void 0===n?void 0:n.root)?{root:!0}:null,"",r):window.history.pushState(null,"",r);const s=new Event("location-changed",{bubbles:!1,cancelable:!0,composed:!1});s.detail={replace:1==o},window.dispatchEvent(s)}toUrl(t){var e;let i=null!==(e=this.renderTemplate(t.url_path))&&void 0!==e?e:"";i.includes("//")||(i=`https://${i}`),window.open(i)}assist(t){var e,i,n,r,o,s,a;(null===(r=null===(n=null===(i=null===(e=this.hass)||void 0===e?void 0:e.auth)||void 0===i?void 0:i.external)||void 0===n?void 0:n.config)||void 0===r?void 0:r.hasAssist)?null===(a=null===(s=null===(o=this.hass)||void 0===o?void 0:o.auth)||void 0===s?void 0:s.external)||void 0===a||a.fireMessage({type:"assist/show",payload:{pipeline_id:t.pipeline_id,start_listening:t.start_listening}}):window.open(`${window.location.href}?conversation=1`,"_self")}moreInfo(t){var e;const i=this.renderTemplate(null===(e=t.data)||void 0===e?void 0:e.entity_id),n=new Event("hass-more-info",{bubbles:!0,cancelable:!0,composed:!0});n.detail={entityId:i},this.dispatchEvent(n)}fireDomEvent(t){const e=new Event("ll-custom",{composed:!0,bubbles:!0});e.detail=t,this.dispatchEvent(e)}handleConfirmation(t){if("confirmation"in t){let e=t.confirmation;if("string"==typeof e&&(e=this.renderTemplate(t.confirmation)),0!=e){this.fireHapticEvent("warning");let i="";if(1!=e&&"text"in e)i=this.renderTemplate(e.text);else switch(t.action){case"navigate":i=`Are you sure you want to navigate to '${this.renderTemplate(t.navigation_path)}'`;break;case"url":i=`Are you sure you want to navigate to '${this.renderTemplate(t.url_path)}'?`;break;case"assist":i="Are you sure you want to call assist?";break;case"none":return!1;case"call-service":i=`Are you sure you want to run action '${this.renderTemplate(t.service)}'?`;break;case"source":i=`Are you sure you want to run action '${this.renderTemplate(t.source)}'?`;break;default:i=`Are you sure you want to run action '${this.renderTemplate(t.key)}'?`}if(1==e){if(!confirm(i))return!1}else if("exemptions"in e){if(!e.exemptions.map((t=>this.renderTemplate(t.user))).includes(this.hass.user.id)&&!confirm(i))return!1}else if(!confirm(i))return!1}}return!0}renderTemplate(t,e){var i;if(!e){let t=0;this.buttonPressStart&&this.buttonPressEnd&&(t=(this.buttonPressEnd-this.buttonPressStart)/1e3),e={VALUE:this.value,HOLD_SECS:null!=t?t:0}}if("string"==typeof(t=(0,a.renderTemplate)(this.hass,t,e)))for(const n in e)n in e&&(t==n?t=e[n]:t.toString().includes(n)&&(t=t.toString().replace(new RegExp(n,"g"),(null!==(i=e[n])&&void 0!==i?i:"").toString())));return t}buildStyle(t={},e){const i=structuredClone(t);for(const t in i)i[t]=this.renderTemplate(i[t],e);return i}onStart(t){}onEnd(t){}onMove(t){}onMouseDown(t){this.fireMouseEvent&&this.onStart(t)}onMouseUp(t){this.fireMouseEvent&&this.onEnd(t),this.fireMouseEvent=!0}onMouseMove(t){this.fireMouseEvent&&this.onMove(t)}onTouchStart(t){this.fireMouseEvent=!1,this.onStart(t)}onTouchEnd(t){this.fireMouseEvent=!1,this.onEnd(t)}onTouchMove(t){this.fireMouseEvent=!1,this.onMove(t)}onContextMenu(t){if(!this.fireMouseEvent)return t.preventDefault(),t.stopPropagation(),!1}render(){}static get styles(){return r.css``}};e.BaseRemoteElement=c,n([(0,o.property)({attribute:!1})],c.prototype,"hass",void 0),n([(0,o.property)({attribute:!1})],c.prototype,"actions",void 0),n([(0,o.property)({attribute:!1})],c.prototype,"autofillEntityId",void 0),n([(0,o.property)({attribute:!1})],c.prototype,"remoteId",void 0),n([(0,o.property)({attribute:!1})],c.prototype,"mediaPlayerId",void 0),n([(0,o.state)()],c.prototype,"value",void 0),n([(0,o.eventOptions)({passive:!0})],c.prototype,"onMouseDown",null),n([(0,o.eventOptions)({passive:!0})],c.prototype,"onMouseMove",null),n([(0,o.eventOptions)({passive:!0})],c.prototype,"onTouchStart",null),n([(0,o.eventOptions)({passive:!0})],c.prototype,"onTouchMove",null),e.BaseRemoteElement=c=n([(0,o.customElement)("base-remote-element")],c)},5984:function(t,e,i){"use strict";var n=this&&this.__decorate||function(t,e,i,n){var r,o=arguments.length,s=o<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,i,n);else for(var a=t.length-1;a>=0;a--)(r=t[a])&&(s=(o<3?r(s):o>3?r(e,i,s):r(e,i))||s);return o>3&&s&&Object.defineProperty(e,i,s),s};Object.defineProperty(e,"__esModule",{value:!0}),e.RemoteButton=void 0;const r=i(1814),o=i(5595),s=i(8921),a=i(8666);let c=class extends a.BaseRemoteElement{constructor(){super(...arguments),this.clickCount=0,this.hold=!1}onClick(t){var e;if(t.stopImmediatePropagation(),this.clickCount++,"double_tap_action"in this.actions&&"none"!=this.renderTemplate(this.actions.double_tap_action.action))if(this.clickCount>1)this.fireHapticEvent("success"),this.sendAction("double_tap_action"),this.endAction();else{const t="double_tap_window"in(null!==(e=this.actions.double_tap_action)&&void 0!==e?e:{})?this.renderTemplate(this.actions.double_tap_action.double_tap_window):200;this.clickTimer||(this.clickTimer=setTimeout((()=>{this.fireHapticEvent("light"),this.sendAction("tap_action"),this.endAction()}),t))}else this.fireHapticEvent("light"),this.sendAction("tap_action"),this.endAction()}onStart(t){var e;if(this.swiping=!1,"targetTouches"in t?(this.initialX=t.targetTouches[0].clientX,this.initialY=t.targetTouches[0].clientY):(this.initialX=t.clientX,this.initialY=t.clientY),"momentary_start_action"in this.actions&&"none"!=this.renderTemplate(this.actions.momentary_start_action.action))this.fireHapticEvent("light"),this.buttonPressStart=performance.now(),this.sendAction("momentary_start_action");else if("momentary_end_action"in this.actions&&"none"!=this.renderTemplate(this.actions.momentary_end_action.action))this.fireHapticEvent("light"),this.buttonPressStart=performance.now();else if(!this.holdTimer){const t="hold_time"in(null!==(e=this.actions.hold_action)&&void 0!==e?e:{})?this.renderTemplate(this.actions.hold_action.hold_time):500;this.holdTimer=setTimeout((()=>{var t,e;if(!this.swiping)if(this.hold=!0,"repeat"==this.renderTemplate(null===(t=this.actions.hold_action)||void 0===t?void 0:t.action)){const t="repeat_delay"in(null!==(e=this.actions.hold_action)&&void 0!==e?e:{})?this.renderTemplate(this.actions.hold_action.repeat_delay):100;this.holdInterval||(this.holdInterval=setInterval((()=>{this.fireHapticEvent("selection"),this.sendAction("tap_action")}),t))}else this.fireHapticEvent("medium"),this.sendAction("hold_action")}),t)}}onEnd(t){this.swiping||("momentary_end_action"in this.actions&&"none"!=this.renderTemplate(this.actions.momentary_end_action.action)?(this.fireHapticEvent("selection"),this.buttonPressEnd=performance.now(),this.sendAction("momentary_end_action"),this.endAction()):"momentary_start_action"in this.actions&&"none"!=this.renderTemplate(this.actions.momentary_start_action.action)?this.endAction():this.hold?(t.stopImmediatePropagation(),t.preventDefault(),this.endAction()):this.onClick(t))}onMove(t){var e,i;let n,r;"targetTouches"in t?(n=t.targetTouches[0].clientX,r=t.targetTouches[0].clientY):(n=t.clientX,r=t.clientY);const o=(null!==(e=this.initialX)&&void 0!==e?e:n)-n,s=(null!==(i=this.initialY)&&void 0!==i?i:r)-r;Math.abs(Math.abs(o)-Math.abs(s))>8&&(this.endAction(),this.swiping=!0)}onMouseLeave(t){this.endAction(),this.swiping=!0}endAction(){clearTimeout(this.clickTimer),this.clickTimer=void 0,this.clickCount=0,clearTimeout(this.holdTimer),clearInterval(this.holdInterval),this.holdTimer=void 0,this.holdInterval=void 0,this.hold=!1,super.endAction()}render(t){var e,i,n;const o=null!==(e=this.renderTemplate(this.actions.icon))&&void 0!==e?e:"";let a,c=r.html``;o.includes(":")?c=r.html``:a=null!==(i=this.icons[o])&&void 0!==i?i:o;const l=this.renderTemplate(this.actionKey);return r.html`