From 24bde7d16cd3f236c70817962b9f3bfaf2789b76 Mon Sep 17 00:00:00 2001 From: Aleksandr Meshchriakov Date: Tue, 10 Mar 2026 14:05:26 +0100 Subject: [PATCH] chore: prepare release v1.0.5 --- package-lock.json | 4 ++-- package.json | 2 +- universal-card.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3cf1d6c..7a6156f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "universal-card", - "version": "1.0.4", + "version": "1.0.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "universal-card", - "version": "1.0.4", + "version": "1.0.5", "license": "MIT", "devDependencies": { "@playwright/test": "^1.54.2", diff --git a/package.json b/package.json index 6a3cfcc..d6a4953 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "universal-card", - "version": "1.0.4", + "version": "1.0.5", "description": "Advanced Lovelace custom card for Home Assistant", "private": true, "scripts": { diff --git a/universal-card.js b/universal-card.js index 2e7a658..c8e8f24 100644 --- a/universal-card.js +++ b/universal-card.js @@ -1,5 +1,5 @@ /** - * Universal Card v1.0.4 + * Universal Card v1.0.5 * @license MIT */ "use strict";(()=>{var kt=!1;function it(r){kt=r}function p(...r){kt&&console.log(...r)}function Mt(r="uc"){let e=Math.random().toString(36).substring(2,10);return`${r}-${e}`}function f(r){return r!==null&&typeof r=="object"&&!Array.isArray(r)}function M(r){return typeof r=="string"&&r.trim().length>0}function v(r){return typeof r=="number"&&!Number.isNaN(r)}function j(r){if(r===null||typeof r!="object")return r;if(Array.isArray(r))return r.map(t=>j(t));let e={};return Object.keys(r).forEach(t=>{e[t]=j(r[t])}),e}function L(r,e,t={},n={}){let i=new CustomEvent(e,{bubbles:n.bubbles!==!1,cancelable:n.cancelable!==!1,composed:n.composed!==!1,detail:t});return r.dispatchEvent(i),i}function Q(r){return M(r)?/^[a-z_]+\.[a-z0-9_]+$/.test(r):!1}var rt="1.0.3",Lt="Universal Card",Pt="\u041F\u0440\u043E\u0434\u0432\u0438\u043D\u0443\u0442\u0430\u044F \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0441 7 \u0440\u0435\u0436\u0438\u043C\u0430\u043C\u0438 body, grid layout, lazy loading \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u043D\u043E\u0439 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u043E\u0439",E=Object.freeze({EXPAND:"expand",MODAL:"modal",FULLSCREEN:"fullscreen",TABS:"tabs",CAROUSEL:"carousel",SUBVIEW:"subview",NONE:"none"}),we=Object.values(E),Ee=Object.freeze({START:"start",CENTER:"center",STRETCH:"stretch"}),se=Object.values(Ee),Se=Object.freeze({DEFAULT:"default",STACKED:"stacked",CENTERED:"centered"}),de=Object.values(Se),Ae=Object.freeze({START:"start",CENTER:"center",END:"end"}),le=Object.values(Ae),ce=Object.freeze({RIGHT:"right",BELOW_CONTENT:"below_content"}),ue=Object.values(ce),Ot=Object.freeze({TAP:"tap",HOLD:"hold",DOUBLE_TAP:"double_tap",NONE:"none"}),Te=Object.values(Ot),Rt=Object.freeze({CARD:"card",DASHBOARD:"dashboard",GLOBAL:"global"}),ke=Object.values(Rt),J=Object.freeze({DEFAULT:"default",TRANSPARENT:"transparent",SOLID:"solid",GLASS:"glass",GLASSMORPHISM:"glassmorphism",NEUMORPHISM:"neumorphism",MINIMAL:"minimal",GRADIENT:"gradient",DARK:"dark",NEON:"neon",AURORA:"aurora",CARBON:"carbon",SLATE:"slate",OBSIDIAN:"obsidian",CHARCOAL:"charcoal",MIDNIGHT:"midnight",CYBER:"cyber",VOID:"void",EMBER:"ember",FOREST:"forest",OCEAN:"ocean",PURPLE_HAZE:"purple-haze",MATRIX:"matrix",GRAPHITE:"graphite",SMOKE:"smoke",NORD:"nord",DRACULA:"dracula",MONOKAI:"monokai",TOKYO_NIGHT:"tokyo-night",CATPPUCCIN:"catppuccin"}),Ht=Object.freeze({NONE:"none",FADE:"fade",FADE_UP:"fadeUp",FADE_DOWN:"fadeDown",SCALE:"scale",SLIDE:"slide",BOUNCE:"bounce",FLIP:"flip"}),Me=Object.values(Ht),It=Object.freeze({NONE:"none",FADE:"fade",FADE_DOWN:"fadeDown",FADE_UP:"fadeUp",SCALE:"scale",SLIDE:"slide"}),Le=Object.values(It),Nt=Object.freeze({NONE:"none",FADE_UP:"fadeUp",FADE_DOWN:"fadeDown",FADE_LEFT:"fadeLeft",FADE_RIGHT:"fadeRight",SCALE:"scale",BOUNCE:"bounce",FLIP:"flip"}),Pe=Object.values(Nt),Dt=Object.freeze({SEQUENTIAL:"sequential",REVERSE:"reverse",CENTER_OUT:"center-out",EDGES_IN:"edges-in",DIAGONAL:"diagonal",WAVE:"wave",RANDOM:"random"}),Oe=Object.values(Dt),xn=Object.freeze({NONE:"none",FADE:"fade",SLIDE:"slide",BOUNCE:"bounce",ELASTIC:"elastic",SMOOTH:"smooth",SHARP:"sharp",ZOOM:"zoom"}),Cn=Object.freeze({SKELETON:"skeleton",SPINNER:"spinner",DOTS:"dots",PROGRESS:"progress",SHIMMER:"shimmer",PULSE:"pulse"}),C=Object.freeze({STATE:"state",NUMERIC_STATE:"numeric_state",USER:"user",TIME:"time",SCREEN:"screen",AND:"and",OR:"or",NOT:"not"}),ot=Object.values(C),wn=Object.freeze({MON:"mon",TUE:"tue",WED:"wed",THU:"thu",FRI:"fri",SAT:"sat",SUN:"sun"}),Re=Object.values(wn),x=Object.freeze({NONE:"none",TOGGLE:"toggle",CALL_SERVICE:"call-service",NAVIGATE:"navigate",URL:"url",MORE_INFO:"more-info",FIRE_EVENT:"fire-dom-event",EXPAND:"expand",COLLAPSE:"collapse"}),Bt=Object.freeze({HORIZONTAL:"horizontal",VERTICAL:"vertical",BOTH:"both"}),He=Object.values(Bt),En=Object.freeze({NONE:"none",EXPAND:"expand",COLLAPSE:"collapse",TOGGLE:"toggle",NEXT:"next",PREV:"prev"}),Ie=Object.values(En),$=Object.freeze({STATE:"state",ATTRIBUTE:"attribute",COUNTER:"counter",CUSTOM:"custom"}),Ne=Object.values($),he=Object.freeze({EQUALS:"==",NOT_EQUALS:"!=",GREATER_THAN:">",LESS_THAN:"<",GREATER_THAN_OR_EQUALS:">=",LESS_THAN_OR_EQUALS:"<="}),G=Object.values(he),at=Object.freeze({NONE:"none",TIME:"time",DATE:"date",DURATION:"duration"}),De=Object.values(at),X=Object.freeze({LAZY:"lazy",PRELOAD:"preload"}),pe=Object.values(X),Y=Object.freeze({CARD_EXPANDED:"universal-card-expanded",CARD_COLLAPSED:"universal-card-collapsed",CARD_CONTROL:"universal-card-control",CONFIG_CHANGED:"config-changed",HASS_UPDATED:"hass-updated"}),hi=Object.freeze({PRIMARY:"--uc-primary-color",SECONDARY:"--uc-secondary-color",ACCENT:"--uc-accent-color",BACKGROUND:"--uc-background-color",SURFACE:"--uc-surface-color",TEXT:"--uc-text-color",TEXT_SECONDARY:"--uc-text-secondary-color",BORDER:"--uc-border-color",BORDER_RADIUS:"--uc-border-radius",PADDING:"--uc-padding",GAP:"--uc-gap",SHADOW:"--uc-shadow",SHADOW_HOVER:"--uc-shadow-hover",TRANSITION_DURATION:"--uc-transition-duration",TRANSITION_TIMING:"--uc-transition-timing"}),u=Object.freeze({body_mode:E.EXPAND,expand_trigger:Ot.TAP,expanded:!1,animation:!0,stability_mode:!1,theme:J.DEFAULT,border_radius:"var(--ha-card-border-radius, 12px)",padding:"16px",grid_columns:1,grid_gap:"16px",modal_width:"90%",modal_height:"auto",modal_max_width:"600px",modal_max_height:"85vh",modal_loading_strategy:X.LAZY,backdrop_color:"rgba(0, 0, 0, 0.6)",fullscreen_width:"100%",fullscreen_height:"100%",fullscreen_max_width:"1200px",fullscreen_max_height:"100vh",fullscreen_padding:"16px",fullscreen_background:"var(--primary-background-color, #fafafa)",tabs_content_padding:"16px",tabs_tab_min_width:"72px",tabs_tab_alignment:Ee.START,header_layout_variant:Se.DEFAULT,header_gap:"12px",header_content_gap:"2px",header_content_align:Ae.START,header_badges_position:ce.RIGHT,carousel_show_arrows:!0,carousel_show_indicators:!0,carousel_loop:!0,carousel_height:"auto",lazy_load:!0,lazy_initial_batch:4,lazy_batch_size:4,lazy_idle_timeout:800,remember_expanded_state:!1,remember_mode_state:!0,auto_collapse_after:0,enable_card_pool:!0,pool_scope:Rt.CARD,pool_ttl_ms:10*60*1e3,pool_max_entries:32,show_expand_icon:!0,expand_icon:"mdi:chevron-down",haptic:!1,loading_type:Cn.SKELETON,skeleton_count:3,carousel_autoplay:!1,carousel_interval:5e3,swipe_enabled:!1,swipe_direction:Bt.HORIZONTAL,swipe_threshold:50,swipe_velocity_threshold:.3,swipe_prevent_scroll:!1,expand_animation:Ht.SLIDE,collapse_animation:It.SLIDE,cards_animation:Nt.FADE_UP,cards_stagger:50,cards_direction:Dt.SEQUENTIAL,animation_preset:xn.SMOOTH,animation_duration:300}),_e=Object.freeze({TTI_MS:250,RENDER_MS:16,UPDATE_MS:12,BODY_LOAD_MS:180,BUNDLE_SIZE_KB:360}),h=Object.freeze({MAX_GRID_COLUMNS:12,MIN_GRID_COLUMNS:1,MAX_CARDS_PER_BODY:100,MAX_TABS:20,UPDATE_THROTTLE_MS:100,RESIZE_DEBOUNCE_MS:200,INTERSECTION_MARGIN:"100px",LAZY_MIN_BATCH:1,LAZY_MAX_BATCH:25,LAZY_MIN_TIMEOUT_MS:50,LAZY_MAX_TIMEOUT_MS:5e3,CARD_POOL_MAX_ENTRIES:32,CARD_POOL_MAX_AGE_MS:10*60*1e3,CARD_POOL_HARD_MAX_ENTRIES:512,POOL_MIN_TTL_MS:1e3,POOL_MAX_TTL_MS:60*60*1e3,POOL_MIN_MAX_ENTRIES:1,POOL_MAX_MAX_ENTRIES:512,AUTO_COLLAPSE_MAX_SECONDS:3600,ANIMATION_DURATION_MAX_MS:2e3,CAROUSEL_MIN_INTERVAL_MS:1e3,CAROUSEL_MAX_INTERVAL_MS:6e4,CARDS_STAGGER_MAX_MS:200,SWIPE_MAX_THRESHOLD_PX:400,SWIPE_MAX_VELOCITY_THRESHOLD:5,BADGE_MAX_PRECISION:6,METRICS_HISTORY_SIZE:200,MAX_UNDO_HISTORY:50,MAX_LOG_ENTRIES:1e3});var Be=1,T=2;function Ut(r){if(Array.isArray(r))return{cards:r};if(f(r)){let e=r;return Array.isArray(e.cards)?{...e,cards:e.cards}:{...e}}return null}function A(r,e,t){r.push({path:e,message:t})}function Sn(r,e){if(r.cards!==void 0&&(f(r.body)||(r.body={}),r.body.cards===void 0?(r.body.cards=Array.isArray(r.cards)?[...r.cards]:r.cards,A(e,"cards","Moved legacy root cards to body.cards.")):A(e,"cards","Dropped legacy root cards because body.cards already exists."),delete r.cards),r.remember_state!==void 0&&(r.remember_expanded_state===void 0?(r.remember_expanded_state=r.remember_state,A(e,"remember_state","Renamed remember_state to remember_expanded_state.")):A(e,"remember_state","Removed remember_state because remember_expanded_state already exists."),delete r.remember_state),r.state_styles_entity!==void 0&&(r.entity===void 0?(r.entity=r.state_styles_entity,A(e,"state_styles_entity","Promoted state_styles_entity to root entity.")):A(e,"state_styles_entity","Removed state_styles_entity because root entity already exists."),delete r.state_styles_entity),r.debug!==void 0&&(delete r.debug,A(e,"debug","Removed deprecated debug config field.")),f(r.header)){let{header:t}=r;if(t.left!==void 0){if(r.header_left===void 0){let n=Ut(t.left);n&&(r.header_left=n,A(e,"header.left","Moved legacy header.left to root header_left."))}else A(e,"header.left","Dropped legacy header.left because header_left already exists.");delete t.left}if(t.right!==void 0){if(r.header_right===void 0){let n=Ut(t.right);n&&(r.header_right=n,A(e,"header.right","Moved legacy header.right to root header_right."))}else A(e,"header.right","Dropped legacy header.right because header_right already exists.");delete t.right}Object.keys(t).length===0&&delete r.header}if(f(r.carousel)){let{carousel:t}=r;r.carousel_autoplay===void 0&&typeof t.autoplay=="boolean"&&(r.carousel_autoplay=t.autoplay,A(e,"carousel.autoplay","Moved carousel.autoplay to root carousel_autoplay.")),r.carousel_interval===void 0&&typeof t.interval=="number"&&(r.carousel_interval=t.interval,A(e,"carousel.interval","Moved carousel.interval to root carousel_interval.")),["show_indicators","show_arrows","loop"].forEach(n=>{t[n]!==void 0&&A(e,`carousel.${n}`,`Removed legacy carousel.${n}; this option is no longer configurable.`)}),delete r.carousel}f(r.swipe)&&Object.entries({swipe_left:"left",swipe_right:"right",swipe_up:"up",swipe_down:"down"}).forEach(([n,i])=>{r.swipe[n]!==void 0&&(r.swipe[i]===void 0?(r.swipe[i]=r.swipe[n],A(e,`swipe.${n}`,`Renamed swipe.${n} to swipe.${i}.`)):A(e,`swipe.${n}`,`Removed swipe.${n} because swipe.${i} already exists.`),delete r.swipe[n])}),Array.isArray(r.badges)&&(r.badges=r.badges.map((t,n)=>{if(!f(t)||t.text===void 0)return t;let i={...t};return i.value===void 0?(i.value=i.text,A(e,`badges[${n}].text`,"Moved badges[].text to badges[].value.")):i.label===void 0?(i.label=i.text,A(e,`badges[${n}].text`,"Moved badges[].text to badges[].label because value already exists.")):A(e,`badges[${n}].text`,"Removed badges[].text because value/label already exist."),delete i.text,i}))}function An(r){return Number.isInteger(r.config_version)&&r.config_version>0?r.config_version:Be}function $t(r){let e=Number.isInteger(r.config_version)&&r.config_version>0,t=An(r),n=j(r),i=[];return t<2&&Sn(n,i),n.config_version=T,{config:n,fromVersion:t,toVersion:T,changed:e&&t!==T||i.length>0,explicitVersion:e,changes:i}}var d=class extends Error{constructor(e,t){super(t?`${t}: ${e}`:e),this.name="ConfigValidationError",this.path=t}},D=class{static getCurrentConfigVersion(){return T}static migrate(e){if(!f(e))throw new d("Configuration must be an object");if(e.config_version!==void 0){if(!Number.isInteger(e.config_version)||e.config_version<1)throw new d("config_version must be a positive integer","config_version");if(e.config_version>T)throw new d(`config_version ${e.config_version} is newer than this runtime. Current supported version is ${T}.`,"config_version")}return $t(e)}static validate(e){this._validateCurrentConfig(e)}static _validateCurrentConfig(e){var n,i,o,a,s;if(!f(e))throw new d("Configuration must be an object");if(e.config_version!==void 0){if(!Number.isInteger(e.config_version)||e.config_version<1)throw new d("config_version must be a positive integer","config_version");if(e.config_versionT)throw new d(`config_version ${e.config_version} is newer than this runtime. Current supported version is ${T}.`,"config_version")}if(e.body_mode&&!we.includes(e.body_mode))throw new d(`Invalid body_mode: "${e.body_mode}". Valid modes: ${we.join(", ")}`,"body_mode");let t=Object.values(J);if(e.theme&&!t.includes(e.theme))throw new d(`Invalid theme: "${e.theme}". Valid themes: ${t.join(", ")}`,"theme");if(e.entity&&!Q(e.entity))throw new d(`Invalid entity format: "${e.entity}"`,"entity");if(e.icon_color!==void 0&&typeof e.icon_color!="string")throw new d("icon_color must be a string","icon_color");if(e.attribute!==void 0&&!M(e.attribute))throw new d("attribute must be a non-empty string","attribute");if(e.cards!==void 0)throw new d("Root-level cards were removed. Use body.cards instead.","cards");if(e.remember_state!==void 0)throw new d("remember_state was removed. Use remember_expanded_state instead.","remember_state");if(e.debug!==void 0)throw new d("debug was removed from the config contract. Use devtools instead.","debug");if(e.state_styles_entity!==void 0)throw new d("state_styles_entity was removed. Use root entity and optional attribute instead.","state_styles_entity");if(f(e.header)&&(e.header.left!==void 0||e.header.right!==void 0))throw new d("Legacy header.left/header.right were removed. Use root header_left/header_right sections.","header");if(e.header!==void 0&&this._validateHeaderConfig(e.header,"header"),e.carousel!==void 0)throw new d("Legacy carousel object was removed. Use root carousel_autoplay and carousel_interval fields.","carousel");if(e.expand_trigger!==void 0&&(typeof e.expand_trigger!="string"||!Te.includes(e.expand_trigger)))throw new d(`expand_trigger must be one of: ${Te.join(", ")}`,"expand_trigger");if(e.grid&&e.grid.columns!==void 0){let l=e.grid.columns;if(typeof l=="number"){if(lh.MAX_GRID_COLUMNS)throw new d("Grid columns must be between "+h.MIN_GRID_COLUMNS+" and "+h.MAX_GRID_COLUMNS,"grid.columns")}else if(typeof l!="string")throw new d("Grid columns must be a number or CSS template string","grid.columns")}if(e.modal!==void 0&&this._validateModal(e.modal,"modal"),e.fullscreen!==void 0&&this._validateFullscreen(e.fullscreen,"fullscreen"),e.tabs_config!==void 0&&this._validateTabsUiConfig(e.tabs_config,"tabs_config"),e.carousel_options!==void 0&&this._validateCarouselOptions(e.carousel_options,"carousel_options"),e.subview!==void 0&&this._validateSubview(e.subview,"subview"),e.lazy_initial_batch!==void 0){if(!v(e.lazy_initial_batch))throw new d("lazy_initial_batch must be a number","lazy_initial_batch");if(e.lazy_initial_batchh.LAZY_MAX_BATCH)throw new d(`lazy_initial_batch must be between ${h.LAZY_MIN_BATCH} and ${h.LAZY_MAX_BATCH}`,"lazy_initial_batch")}if(e.lazy_batch_size!==void 0){if(!v(e.lazy_batch_size))throw new d("lazy_batch_size must be a number","lazy_batch_size");if(e.lazy_batch_sizeh.LAZY_MAX_BATCH)throw new d(`lazy_batch_size must be between ${h.LAZY_MIN_BATCH} and ${h.LAZY_MAX_BATCH}`,"lazy_batch_size")}if(e.lazy_idle_timeout!==void 0){if(!v(e.lazy_idle_timeout))throw new d("lazy_idle_timeout must be a number","lazy_idle_timeout");if(e.lazy_idle_timeouth.LAZY_MAX_TIMEOUT_MS)throw new d(`lazy_idle_timeout must be between ${h.LAZY_MIN_TIMEOUT_MS} and ${h.LAZY_MAX_TIMEOUT_MS}`,"lazy_idle_timeout")}if(e.auto_collapse_after!==void 0){if(!v(e.auto_collapse_after))throw new d("auto_collapse_after must be a number","auto_collapse_after");if(e.auto_collapse_after<0||e.auto_collapse_after>h.AUTO_COLLAPSE_MAX_SECONDS)throw new d(`auto_collapse_after must be between 0 and ${h.AUTO_COLLAPSE_MAX_SECONDS}`,"auto_collapse_after")}if(e.remember_expanded_state!==void 0&&typeof e.remember_expanded_state!="boolean")throw new d("remember_expanded_state must be a boolean","remember_expanded_state");if(e.remember_mode_state!==void 0&&typeof e.remember_mode_state!="boolean")throw new d("remember_mode_state must be a boolean","remember_mode_state");if(e.stability_mode!==void 0&&typeof e.stability_mode!="boolean")throw new d("stability_mode must be a boolean","stability_mode");if(e.carousel_autoplay!==void 0&&typeof e.carousel_autoplay!="boolean")throw new d("carousel_autoplay must be a boolean","carousel_autoplay");if(e.carousel_interval!==void 0){if(!v(e.carousel_interval))throw new d("carousel_interval must be a number","carousel_interval");if(e.carousel_intervalh.CAROUSEL_MAX_INTERVAL_MS)throw new d(`carousel_interval must be between ${h.CAROUSEL_MIN_INTERVAL_MS} and ${h.CAROUSEL_MAX_INTERVAL_MS}`,"carousel_interval")}if(e.animation_duration!==void 0){if(!v(e.animation_duration))throw new d("animation_duration must be a number","animation_duration");if(e.animation_duration<0||e.animation_duration>h.ANIMATION_DURATION_MAX_MS)throw new d(`animation_duration must be between 0 and ${h.ANIMATION_DURATION_MAX_MS}`,"animation_duration")}if(e.expand_animation!==void 0&&(typeof e.expand_animation!="string"||!Me.includes(e.expand_animation)))throw new d(`expand_animation must be one of: ${Me.join(", ")}`,"expand_animation");if(e.collapse_animation!==void 0&&(typeof e.collapse_animation!="string"||!Le.includes(e.collapse_animation)))throw new d(`collapse_animation must be one of: ${Le.join(", ")}`,"collapse_animation");if(e.cards_animation!==void 0&&(typeof e.cards_animation!="string"||!Pe.includes(e.cards_animation)))throw new d(`cards_animation must be one of: ${Pe.join(", ")}`,"cards_animation");if(e.cards_stagger!==void 0){if(!v(e.cards_stagger))throw new d("cards_stagger must be a number","cards_stagger");if(e.cards_stagger<0||e.cards_stagger>h.CARDS_STAGGER_MAX_MS)throw new d(`cards_stagger must be between 0 and ${h.CARDS_STAGGER_MAX_MS}`,"cards_stagger")}if(e.cards_direction!==void 0&&(typeof e.cards_direction!="string"||!Oe.includes(e.cards_direction)))throw new d(`cards_direction must be one of: ${Oe.join(", ")}`,"cards_direction");if(e.enable_card_pool!==void 0&&typeof e.enable_card_pool!="boolean")throw new d("enable_card_pool must be a boolean","enable_card_pool");if(e.pool_scope!==void 0&&(typeof e.pool_scope!="string"||!ke.includes(e.pool_scope)))throw new d(`pool_scope must be one of: ${ke.join(", ")}`,"pool_scope");if(e.pool_ttl_ms!==void 0){if(!v(e.pool_ttl_ms))throw new d("pool_ttl_ms must be a number","pool_ttl_ms");if(e.pool_ttl_msh.POOL_MAX_TTL_MS)throw new d(`pool_ttl_ms must be between ${h.POOL_MIN_TTL_MS} and ${h.POOL_MAX_TTL_MS}`,"pool_ttl_ms")}if(e.pool_max_entries!==void 0){if(!v(e.pool_max_entries))throw new d("pool_max_entries must be a number","pool_max_entries");if(e.pool_max_entriesh.POOL_MAX_MAX_ENTRIES)throw new d(`pool_max_entries must be between ${h.POOL_MIN_MAX_ENTRIES} and ${h.POOL_MAX_MAX_ENTRIES}`,"pool_max_entries")}if(this._validateCardCollection((n=e.body)==null?void 0:n.cards,"body.cards",{maxCards:h.MAX_CARDS_PER_BODY}),this._validateCardCollection((i=e.header)==null?void 0:i.cards,"header.cards"),this._validateCardCollection((o=e.footer)==null?void 0:o.cards,"footer.cards"),this._validateCardCollection((a=e.header_left)==null?void 0:a.cards,"header_left.cards"),this._validateCardCollection((s=e.header_right)==null?void 0:s.cards,"header_right.cards"),e.tabs&&this._validateTabs(e.tabs),e.visibility&&this._validateConditions(e.visibility,"visibility"),e.section_visibility!==void 0){if(!f(e.section_visibility))throw new d("section_visibility must be an object with header/body/footer arrays","section_visibility");["header","body","footer"].forEach(l=>{let c=e.section_visibility[l];c!==void 0&&this._validateConditions(c,`section_visibility.${l}`)})}if(e.state_styles!==void 0){if(!e.entity)throw new d("state_styles requires root entity. Separate state_styles_entity is no longer supported.","state_styles");this._validateStateStyles(e.state_styles,"state_styles")}if(e.swipe!==void 0&&this._validateSwipeConfig(e.swipe,"swipe"),e.badges!==void 0&&this._validateBadges(e.badges,"badges"),e.theme_tokens!==void 0){if(!f(e.theme_tokens))throw new d("theme_tokens must be an object","theme_tokens");let l=/^--[a-z0-9_-]+$/i;Object.entries(e.theme_tokens).forEach(([c,m])=>{if(!l.test(c))throw new d(`Invalid CSS variable name "${c}"`,`theme_tokens.${c}`);if(typeof m!="string")throw new d("Theme token value must be a string",`theme_tokens.${c}`)})}return e.custom_css!==void 0&&this._validateCustomCSS(e.custom_css,"custom_css"),["tap_action","hold_action","double_tap_action"].forEach(l=>{e[l]&&this._validateAction(e[l],l)}),!0}static _validateCardConfig(e,t){if(!f(e))throw new d("Card config must be an object",t);if(!e.type)throw new d("Card must have a type",t)}static _validateCardCollection(e,t,n={}){if(e!==void 0){if(!Array.isArray(e))throw new d(`${t} must be an array`,t);if(n.maxCards&&e.length>n.maxCards)throw new d(`Maximum ${n.maxCards} cards allowed in ${t}`,t);e.forEach((i,o)=>{this._validateCardConfig(i,`${t}[${o}]`)})}}static _validateTabs(e){if(!Array.isArray(e))throw new d("tabs must be an array","tabs");if(e.length>h.MAX_TABS)throw new d(`Maximum ${h.MAX_TABS} tabs allowed`,"tabs");e.forEach((t,n)=>{if(!f(t))throw new d("Tab config must be an object",`tabs[${n}]`);if(t.cards&&!Array.isArray(t.cards))throw new d("Tab cards must be an array",`tabs[${n}].cards`)})}static _validateHeaderConfig(e,t){if(!f(e))throw new d("header must be an object",t);if(this._validateCardCollection(e.cards,`${t}.cards`),e.sticky!==void 0&&typeof e.sticky!="boolean")throw new d("header.sticky must be a boolean",`${t}.sticky`);if(e.clickable!==void 0&&typeof e.clickable!="boolean")throw new d("header.clickable must be a boolean",`${t}.clickable`);e.layout!==void 0&&this._validateHeaderLayout(e.layout,`${t}.layout`)}static _validateHeaderLayout(e,t){if(!f(e))throw new d("header.layout must be an object",t);if(["gap","content_gap"].forEach(n=>{if(e[n]!==void 0&&!M(e[n]))throw new d(`header.layout.${n} must be a non-empty string`,`${t}.${n}`)}),e.variant!==void 0&&(typeof e.variant!="string"||!de.includes(e.variant)))throw new d(`header.layout.variant must be one of: ${de.join(", ")}`,`${t}.variant`);if(e.align!==void 0&&(typeof e.align!="string"||!le.includes(e.align)))throw new d(`header.layout.align must be one of: ${le.join(", ")}`,`${t}.align`);if(e.badges_position!==void 0&&(typeof e.badges_position!="string"||!ue.includes(e.badges_position)))throw new d(`header.layout.badges_position must be one of: ${ue.join(", ")}`,`${t}.badges_position`)}static _validateConditions(e,t){if(!Array.isArray(e))throw new d("Visibility must be an array",t);e.forEach((n,i)=>{let o=`${t}[${i}]`;if(!f(n))throw new d("Condition must be an object",o);let a=n.condition;if(!a)throw new d('Condition must have a "condition" type',o);if(!ot.includes(a))throw new d(`Invalid condition type: "${a}"`,o);switch(a){case C.STATE:this._validateStateCondition(n,o);break;case C.NUMERIC_STATE:this._validateNumericStateCondition(n,o);break;case C.USER:this._validateUserCondition(n,o);break;case C.TIME:this._validateTimeCondition(n,o);break;case C.SCREEN:this._validateScreenCondition(n,o);break;case C.AND:case C.OR:case C.NOT:this._validateConditionGroup(n,o);break}})}static _validateConditionEntity(e,t){if(!M(e.entity))throw new d("Condition entity must be a non-empty string",`${t}.entity`);if(!Q(e.entity))throw new d(`Invalid entity format: "${e.entity}"`,`${t}.entity`);if(e.attribute!==void 0&&!M(e.attribute))throw new d("Condition attribute must be a non-empty string",`${t}.attribute`)}static _validateStateCondition(e,t){if(this._validateConditionEntity(e,t),e.state===void 0&&e.state_not===void 0)throw new d('state condition requires "state" or "state_not"',t);if(e.state!==void 0&&e.state_not!==void 0)throw new d('state condition cannot define both "state" and "state_not"',t);e.state!==void 0&&this._validateStringOrStringArray(e.state,`${t}.state`,"state"),e.state_not!==void 0&&this._validateStringOrStringArray(e.state_not,`${t}.state_not`,"state_not")}static _validateNumericStateCondition(e,t){if(this._validateConditionEntity(e,t),e.above===void 0&&e.below===void 0)throw new d('numeric_state condition requires "above" or "below"',t);if(e.above!==void 0&&!v(e.above))throw new d("numeric_state.above must be a number",`${t}.above`);if(e.below!==void 0&&!v(e.below))throw new d("numeric_state.below must be a number",`${t}.below`);if(v(e.above)&&v(e.below)&&e.above>=e.below)throw new d("numeric_state.above must be lower than numeric_state.below",t)}static _validateUserCondition(e,t){if(e.users===void 0&&e.is_admin===void 0&&e.is_owner===void 0)throw new d("user condition requires users, is_admin, or is_owner",t);if(e.users!==void 0&&this._validateStringArray(e.users,`${t}.users`,"users"),e.is_admin!==void 0&&typeof e.is_admin!="boolean")throw new d("user.is_admin must be a boolean",`${t}.is_admin`);if(e.is_owner!==void 0&&typeof e.is_owner!="boolean")throw new d("user.is_owner must be a boolean",`${t}.is_owner`)}static _validateTimeCondition(e,t){if(e.after===void 0&&e.before===void 0&&e.weekday===void 0)throw new d("time condition requires after, before, or weekday",t);if(e.after!==void 0&&!this._isValidTimeString(e.after))throw new d("time.after must be in HH:MM format",`${t}.after`);if(e.before!==void 0&&!this._isValidTimeString(e.before))throw new d("time.before must be in HH:MM format",`${t}.before`);if(e.weekday!==void 0){if(!Array.isArray(e.weekday))throw new d("time.weekday must be an array",`${t}.weekday`);e.weekday.forEach((n,i)=>{if(typeof n!="string"||!Re.includes(n))throw new d(`Invalid weekday: "${String(n)}"`,`${t}.weekday[${i}]`)})}}static _validateScreenCondition(e,t){if(e.media_query===void 0&&e.min_width===void 0&&e.max_width===void 0)throw new d("screen condition requires media_query, min_width, or max_width",t);if(e.media_query!==void 0&&!M(e.media_query))throw new d("screen.media_query must be a non-empty string",`${t}.media_query`);if(e.min_width!==void 0&&!v(e.min_width))throw new d("screen.min_width must be a number",`${t}.min_width`);if(e.max_width!==void 0&&!v(e.max_width))throw new d("screen.max_width must be a number",`${t}.max_width`);if(v(e.min_width)&&v(e.max_width)&&e.min_width>e.max_width)throw new d("screen.min_width must be lower than or equal to screen.max_width",t)}static _validateConditionGroup(e,t){if(!Array.isArray(e.conditions)||e.conditions.length===0)throw new d('Logical conditions require a non-empty "conditions" array',`${t}.conditions`);this._validateConditions(e.conditions,`${t}.conditions`)}static _validateStringOrStringArray(e,t,n){if(typeof e=="string"){if(!e.trim())throw new d(`${n} must not be empty`,t);return}if(!Array.isArray(e)||e.length===0)throw new d(`${n} must be a string or non-empty array of strings`,t);e.forEach((i,o)=>{if(typeof i!="string"||!i.trim())throw new d(`${n} items must be non-empty strings`,`${t}[${o}]`)})}static _validateStringArray(e,t,n){if(!Array.isArray(e)||e.length===0)throw new d(`${n} must be a non-empty array of strings`,t);e.forEach((i,o)=>{if(typeof i!="string"||!i.trim())throw new d(`${n} items must be non-empty strings`,`${t}[${o}]`)})}static _validateStateStyles(e,t){if(!f(e))throw new d("state_styles must be an object map",t);Object.entries(e).forEach(([n,i],o)=>{let a=`${t}.${n||o}`;if(!n||!n.trim())throw new d("state_styles keys must be non-empty strings",a);if(!f(i))throw new d("state_styles entries must be objects",a);Object.entries(i).forEach(([s,l])=>{if(s==="class"){if(typeof l!="string"&&(!Array.isArray(l)||l.some(c=>typeof c!="string"||!c.trim())))throw new d("state_styles.class must be a string or array of strings",`${a}.class`);return}if(typeof l!="string"&&!v(l))throw new d(`state_styles.${s} must be a string or number`,`${a}.${s}`)})})}static _validateSwipeConfig(e,t){if(!f(e))throw new d("swipe must be an object",t);if(e.swipe_left!==void 0||e.swipe_right!==void 0||e.swipe_up!==void 0||e.swipe_down!==void 0)throw new d("Legacy swipe.swipe_left/swipe_right/swipe_up/swipe_down keys were removed. Use swipe.left/right/up/down.",t);if(e.enabled!==void 0&&typeof e.enabled!="boolean")throw new d("swipe.enabled must be a boolean",`${t}.enabled`);if(e.direction!==void 0&&(typeof e.direction!="string"||!He.includes(e.direction)))throw new d(`swipe.direction must be one of: ${He.join(", ")}`,`${t}.direction`);if(e.threshold!==void 0){if(!v(e.threshold))throw new d("swipe.threshold must be a number",`${t}.threshold`);if(e.threshold<0||e.threshold>h.SWIPE_MAX_THRESHOLD_PX)throw new d(`swipe.threshold must be between 0 and ${h.SWIPE_MAX_THRESHOLD_PX}`,`${t}.threshold`)}if(e.velocityThreshold!==void 0){if(!v(e.velocityThreshold))throw new d("swipe.velocityThreshold must be a number",`${t}.velocityThreshold`);if(e.velocityThreshold<0||e.velocityThreshold>h.SWIPE_MAX_VELOCITY_THRESHOLD)throw new d(`swipe.velocityThreshold must be between 0 and ${h.SWIPE_MAX_VELOCITY_THRESHOLD}`,`${t}.velocityThreshold`)}if(e.preventScroll!==void 0&&typeof e.preventScroll!="boolean")throw new d("swipe.preventScroll must be a boolean",`${t}.preventScroll`);["left","right","up","down"].forEach(n=>{e[n]!==void 0&&this._validateSwipeActionConfig(e[n],`${t}.${n}`)})}static _validateSwipeActionConfig(e,t){if(!f(e))throw new d("Swipe action must be an object",t);if(e.action===void 0)throw new d('Swipe action requires an "action" field',`${t}.action`);if(typeof e.action!="string"||!Ie.includes(e.action))throw new d(`Swipe action must be one of: ${Ie.join(", ")}`,`${t}.action`)}static _validateBadges(e,t){if(!Array.isArray(e))throw new d("badges must be an array",t);e.forEach((n,i)=>{let o=`${t}[${i}]`;if(!f(n))throw new d("Badge must be an object",o);if(n.text!==void 0)throw new d("badges[].text was removed. Use badges[].value or badges[].label instead.",`${o}.text`);let a=n.type||$.STATE;if(typeof a!="string"||!Ne.includes(a))throw new d(`Badge type must be one of: ${Ne.join(", ")}`,`${o}.type`);let s=typeof n.entity=="string"?n.entity.trim():n.entity;if(s!==void 0&&!Q(s))throw new d(`Invalid entity format: "${n.entity}"`,`${o}.entity`);if(n.attribute!==void 0&&!M(n.attribute))throw new d("Badge attribute must be a non-empty string",`${o}.attribute`);if(["icon","color","label","unit","domain"].forEach(l=>{if(n[l]!==void 0&&typeof n[l]!="string")throw new d(`Badge ${l} must be a string`,`${o}.${l}`)}),n.value!==void 0&&typeof n.value!="string"&&!v(n.value))throw new d("Badge value must be a string or number",`${o}.value`);if(["min","max"].forEach(l=>{if(n[l]!==void 0&&!v(n[l]))throw new d(`Badge ${l} must be a number`,`${o}.${l}`)}),v(n.min)&&v(n.max)&&n.min>=n.max)throw new d("Badge min must be lower than max",o);if(["show_name","show_progress"].forEach(l=>{if(n[l]!==void 0&&typeof n[l]!="boolean")throw new d(`Badge ${l} must be a boolean`,`${o}.${l}`)}),n.icon_only!==void 0&&typeof n.icon_only!="boolean")throw new d("Badge icon_only must be a boolean",`${o}.icon_only`);if(n.precision!==void 0){if(!Number.isInteger(n.precision))throw new d("Badge precision must be an integer",`${o}.precision`);if(n.precision<0||n.precision>h.BADGE_MAX_PRECISION)throw new d(`Badge precision must be between 0 and ${h.BADGE_MAX_PRECISION}`,`${o}.precision`)}if(n.format!==void 0&&(typeof n.format!="string"||!De.includes(n.format)))throw new d(`Badge format must be one of: ${De.join(", ")}`,`${o}.format`);if(n.entities!==void 0){if(!Array.isArray(n.entities)||n.entities.length===0)throw new d("Badge entities must be a non-empty array",`${o}.entities`);let l=n.entities.map(c=>typeof c=="string"?c.trim():c).filter(c=>c!=="");if(l.length===0)throw new d("Badge entities must contain at least one valid entity ID",`${o}.entities`);l.forEach((c,m)=>{if(!Q(c))throw new d(`Invalid entity format: "${c}"`,`${o}.entities[${m}]`)})}if(n.state!==void 0&&typeof n.state!="string")throw new d("Badge state must be a string",`${o}.state`);if(n.count_state!==void 0&&typeof n.count_state!="string")throw new d("Badge count_state must be a string",`${o}.count_state`);switch(n.thresholds!==void 0&&this._validateBadgeThresholds(n.thresholds,`${o}.thresholds`),n.visibility!==void 0&&this._validateBadgeRules(n.visibility,`${o}.visibility`),n.color_rules!==void 0&&this._validateBadgeColorRules(n.color_rules,`${o}.color_rules`),n.tap_action!==void 0&&this._validateAction(n.tap_action,`${o}.tap_action`),n.icon_tap_action!==void 0&&this._validateAction(n.icon_tap_action,`${o}.icon_tap_action`),a){case $.STATE:if(!n.entity&&n.value===void 0)throw new d("State badges require entity or static value",o);break;case $.ATTRIBUTE:if(!n.entity)throw new d("Attribute badges require entity",`${o}.entity`);if(!n.attribute)throw new d("Attribute badges require attribute",`${o}.attribute`);break;case $.COUNTER:if(!n.domain&&!n.entities)throw new d("Counter badges require domain or entities",o);break;case $.CUSTOM:if(n.value===void 0)throw new d("Custom badges require value",`${o}.value`);break}})}static _validateModal(e,t){if(!f(e))throw new d("modal must be an object",t);if(["width","height","max_width","max_height","backdrop_color"].forEach(n=>{if(e[n]!==void 0&&!M(e[n]))throw new d(`modal.${n} must be a non-empty string`,`${t}.${n}`)}),["backdrop_blur","close_on_backdrop","close_on_escape","show_close"].forEach(n=>{if(e[n]!==void 0&&typeof e[n]!="boolean")throw new d(`modal.${n} must be a boolean`,`${t}.${n}`)}),e.loading_strategy!==void 0&&(typeof e.loading_strategy!="string"||!pe.includes(e.loading_strategy)))throw new d(`modal.loading_strategy must be one of: ${pe.join(", ")}`,`${t}.loading_strategy`)}static _validateFullscreen(e,t){if(!f(e))throw new d("fullscreen must be an object",t);["width","height","max_width","max_height","padding","background"].forEach(n=>{if(e[n]!==void 0&&!M(e[n]))throw new d(`fullscreen.${n} must be a non-empty string`,`${t}.${n}`)}),["show_close","close_on_escape"].forEach(n=>{if(e[n]!==void 0&&typeof e[n]!="boolean")throw new d(`fullscreen.${n} must be a boolean`,`${t}.${n}`)})}static _validateTabsUiConfig(e,t){if(!f(e))throw new d("tabs_config must be an object",t);if(e.position!==void 0&&!M(e.position))throw new d("tabs_config.position must be a non-empty string",`${t}.position`);if(["show_icons","show_labels"].forEach(n=>{if(e[n]!==void 0&&typeof e[n]!="boolean")throw new d(`tabs_config.${n} must be a boolean`,`${t}.${n}`)}),["content_padding","tab_min_width"].forEach(n=>{if(e[n]!==void 0&&!M(e[n]))throw new d(`tabs_config.${n} must be a non-empty string`,`${t}.${n}`)}),e.tab_alignment!==void 0&&(typeof e.tab_alignment!="string"||!se.includes(e.tab_alignment)))throw new d(`tabs_config.tab_alignment must be one of: ${se.join(", ")}`,`${t}.tab_alignment`)}static _validateCarouselOptions(e,t){if(!f(e))throw new d("carousel_options must be an object",t);if(["show_arrows","show_indicators","loop"].forEach(n=>{if(e[n]!==void 0&&typeof e[n]!="boolean")throw new d(`carousel_options.${n} must be a boolean`,`${t}.${n}`)}),e.swipe_threshold!==void 0){if(!v(e.swipe_threshold))throw new d("carousel_options.swipe_threshold must be a number",`${t}.swipe_threshold`);if(e.swipe_threshold<0||e.swipe_threshold>h.SWIPE_MAX_THRESHOLD_PX)throw new d(`carousel_options.swipe_threshold must be between 0 and ${h.SWIPE_MAX_THRESHOLD_PX}`,`${t}.swipe_threshold`)}if(e.height!==void 0&&!M(e.height))throw new d("carousel_options.height must be a non-empty string",`${t}.height`)}static _validateSubview(e,t){if(!f(e))throw new d("subview must be an object",t);["path","navigation_path"].forEach(n=>{if(e[n]!==void 0&&!M(e[n]))throw new d(`subview.${n} must be a non-empty string`,`${t}.${n}`)}),["replace_state","return_on_close"].forEach(n=>{if(e[n]!==void 0&&typeof e[n]!="boolean")throw new d(`subview.${n} must be a boolean`,`${t}.${n}`)})}static _validateBadgeThresholds(e,t){if(!Array.isArray(e))throw new d("Badge thresholds must be an array",t);e.forEach((n,i)=>{let o=`${t}[${i}]`;if(!f(n))throw new d("Badge threshold must be an object",o);if(!v(n.value))throw new d("Badge threshold value must be a number",`${o}.value`);if(!M(n.color))throw new d("Badge threshold color must be a non-empty string",`${o}.color`)})}static _validateBadgeRules(e,t){if(!Array.isArray(e))throw new d("Badge rules must be an array",t);e.forEach((n,i)=>{let o=`${t}[${i}]`;if(!f(n))throw new d("Badge rule must be an object",o);if(typeof n.operator!="string"||!G.includes(n.operator))throw new d(`Badge rule operator must be one of: ${G.join(", ")}`,`${o}.operator`);let a=typeof n.value;if(n.value===void 0||!["string","number","boolean"].includes(a))throw new d("Badge rule value must be a string, number, or boolean",`${o}.value`);if(n.entity!==void 0){let s=typeof n.entity=="string"?n.entity.trim():n.entity;if(!Q(s))throw new d(`Invalid entity format: "${n.entity}"`,`${o}.entity`)}if(n.attribute!==void 0&&!M(n.attribute))throw new d("Badge rule attribute must be a non-empty string",`${o}.attribute`)})}static _validateBadgeColorRules(e,t){this._validateBadgeRules(e,t),e.forEach((n,i)=>{if(!M(n.color))throw new d("Badge color rule color must be a non-empty string",`${t}[${i}].color`)})}static _isValidTimeString(e){if(typeof e!="string")return!1;let t=e.match(/^(\d{2}):(\d{2})$/);if(!t)return!1;let n=Number(t[1]),i=Number(t[2]);return n>=0&&n<=23&&i>=0&&i<=59}static _validateAction(e,t){if(!f(e))throw new d("Action must be an object",t);let n=Object.values(x);if(e.action&&!n.includes(e.action))throw new d(`Invalid action: "${e.action}"`,t);if(e.action===x.CALL_SERVICE&&!e.service)throw new d('call-service action requires a "service" property',t);if(e.action===x.NAVIGATE&&!e.navigation_path)throw new d('navigate action requires a "navigation_path" property',t);if(e.action===x.URL&&!e.url_path)throw new d('url action requires a "url_path" property',t)}static normalize(e){e=this.migrate(e).config,this._validateCurrentConfig(e);let t={...u,...e};if(t.config_version=T,t.card_id||(t.card_id=Mt("uc")),t.header=this._normalizeHeader(e.header),e.header_left&&(t.header_left=this._normalizeSection(e.header_left,"header_left")),e.header_right&&(t.header_right=this._normalizeSection(e.header_right,"header_right")),e.body?t.body=this._normalizeSection(e.body,"body"):t.body={cards:[]},e.footer&&(t.footer=this._normalizeSection(e.footer,"footer")),e.tabs&&(t.tabs=e.tabs.map((n,i)=>({label:n.label||`Tab ${i+1}`,icon:n.icon||null,cards:n.cards||[],...n}))),t.grid=this._normalizeGrid(e.grid),t.modal=this._normalizeModal(e.modal),t.fullscreen=this._normalizeFullscreen(e.fullscreen),t.tabs_config=this._normalizeTabsConfig(e.tabs_config),t.carousel_options=this._normalizeCarouselOptions(e.carousel_options),t.subview=this._normalizeSubview(e.subview),t.tap_action=this._normalizeAction(e.tap_action,"none"),t.hold_action=this._normalizeAction(e.hold_action,"none"),t.double_tap_action=this._normalizeAction(e.double_tap_action,"none"),e.visibility&&(t.visibility=e.visibility.map(n=>this._normalizeCondition(n))),t.section_visibility=this._normalizeSectionVisibility(e.section_visibility),e.attribute!==void 0){let n=e.attribute.trim();n?t.attribute=n:delete t.attribute}if(typeof e.icon_color=="string"){let n=e.icon_color.trim();n?t.icon_color=n:delete t.icon_color}return t.state_styles=this._normalizeStateStyles(e.state_styles),t.swipe=this._normalizeSwipe(e.swipe),t.badges=this._normalizeBadges(e.badges),t.theme_tokens=this._normalizeThemeTokens(e.theme_tokens),t.stability_mode&&(t.animation=!1,t.expand_animation="none",t.collapse_animation="none",t.cards_animation="none",t.cards_stagger=0,t.animation_duration=0,t.enable_card_pool=!1,t.carousel_autoplay=!1),t}static _normalizeSection(e,t){return e?{cards:e.cards||[],...e}:{cards:[]}}static _normalizeHeader(e){let t=this._normalizeSection(e,"header");return typeof t.sticky!="boolean"&&delete t.sticky,typeof t.clickable!="boolean"&&delete t.clickable,t.layout=this._normalizeHeaderLayout(e==null?void 0:e.layout),t}static _normalizeHeaderLayout(e){let t=f(e)?e:{},n=(i,o)=>typeof i!="string"?o:i.trim()||o;return{variant:typeof t.variant=="string"&&de.includes(t.variant)?t.variant:u.header_layout_variant,gap:n(t.gap,u.header_gap),content_gap:n(t.content_gap,u.header_content_gap),align:typeof t.align=="string"&&le.includes(t.align)?t.align:u.header_content_align,badges_position:typeof t.badges_position=="string"&&ue.includes(t.badges_position)?t.badges_position:u.header_badges_position}}static _normalizeGrid(e){return e?{columns:e.columns||u.grid_columns,gap:e.gap||u.grid_gap,responsive:e.responsive||null}:{columns:u.grid_columns,gap:u.grid_gap}}static _normalizeModal(e){let t=f(e)?e:{},n=(i,o)=>typeof i!="string"?o:i.trim()||o;return{width:n(t.width,u.modal_width),height:n(t.height,u.modal_height),max_width:n(t.max_width,u.modal_max_width),max_height:n(t.max_height,u.modal_max_height),loading_strategy:typeof t.loading_strategy=="string"&&pe.includes(t.loading_strategy)?t.loading_strategy:u.modal_loading_strategy,backdrop_blur:t.backdrop_blur!==!1,backdrop_color:n(t.backdrop_color,u.backdrop_color),close_on_backdrop:t.close_on_backdrop!==!1,close_on_escape:t.close_on_escape!==!1,show_close:t.show_close!==!1}}static _normalizeFullscreen(e){let t=f(e)?e:{},n=(i,o)=>typeof i!="string"?o:i.trim()||o;return{width:n(t.width,u.fullscreen_width),height:n(t.height,u.fullscreen_height),max_width:n(t.max_width,u.fullscreen_max_width),max_height:n(t.max_height,u.fullscreen_max_height),padding:n(t.padding,u.fullscreen_padding),background:n(t.background,u.fullscreen_background),show_close:t.show_close!==!1,close_on_escape:t.close_on_escape!==!1}}static _normalizeTabsConfig(e){let t=f(e)?e:{},n=(i,o)=>typeof i!="string"?o:i.trim()||o;return{position:n(t.position,"top"),show_icons:t.show_icons!==!1,show_labels:t.show_labels!==!1,content_padding:n(t.content_padding,u.tabs_content_padding),tab_min_width:n(t.tab_min_width,u.tabs_tab_min_width),tab_alignment:typeof t.tab_alignment=="string"&&se.includes(t.tab_alignment)?t.tab_alignment:u.tabs_tab_alignment}}static _normalizeCarouselOptions(e){let t=f(e)?e:{},n=(i,o)=>typeof i!="string"?o:i.trim()||o;return{show_arrows:t.show_arrows!==!1,show_indicators:t.show_indicators!==!1,loop:t.loop!==!1,swipe_threshold:v(t.swipe_threshold)?t.swipe_threshold:u.swipe_threshold,height:n(t.height,u.carousel_height)}}static _normalizeSubview(e){let t=f(e)?e:{},n=i=>typeof i!="string"?void 0:i.trim()||void 0;return{path:n(t.path),navigation_path:n(t.navigation_path),replace_state:t.replace_state===!0,return_on_close:t.return_on_close===!0}}static _normalizeAction(e,t="none"){return e?{action:e.action||t,...e}:{action:t}}static _normalizeCondition(e){let t={condition:e.condition,...e};return typeof t.entity=="string"&&(t.entity=t.entity.trim()),typeof t.attribute=="string"&&(t.attribute=t.attribute.trim()),e.condition===C.STATE&&(e.state!==void 0&&(t.state=this._normalizeStringListValue(e.state)),e.state_not!==void 0&&(t.state_not=this._normalizeStringListValue(e.state_not))),e.condition===C.USER&&Array.isArray(e.users)&&(t.users=e.users.map(n=>typeof n=="string"?n.trim():"").filter(Boolean)),e.condition===C.TIME&&Array.isArray(e.weekday)&&(t.weekday=e.weekday.map(n=>typeof n=="string"?n.trim():"").filter(n=>Re.includes(n))),[C.AND,C.OR,C.NOT].includes(e.condition)&&Array.isArray(e.conditions)&&(t.conditions=e.conditions.map(n=>this._normalizeCondition(n))),t}static _normalizeSectionVisibility(e){let t=f(e)?e:{},n=i=>Array.isArray(i)?i.map(o=>this._normalizeCondition(o)):[];return{header:n(t.header),body:n(t.body),footer:n(t.footer)}}static _normalizeThemeTokens(e){if(!f(e))return{};let t={},n=/^--[a-z0-9_-]+$/i;return Object.entries(e).forEach(([i,o])=>{if(!n.test(i)||typeof o!="string")return;let a=o.trim();a&&(t[i]=a)}),t}static _normalizeStateStyles(e){if(!f(e))return{};let t={};return Object.entries(e).forEach(([n,i])=>{let o=typeof n=="string"?n.trim():"";if(!o||!f(i))return;let a={};Object.entries(i).forEach(([s,l])=>{if(s==="class"){if(Array.isArray(l)){let c=l.map(m=>typeof m=="string"?m.trim():"").filter(Boolean);c.length>0&&(a.class=c);return}typeof l=="string"&&l.trim()&&(a.class=l.trim());return}if(typeof l=="string"){let c=l.trim();c&&(a[s]=c);return}v(l)&&(a[s]=l)}),Object.keys(a).length>0&&(t[o]=a)}),t}static _normalizeSwipe(e){var n,i,o,a;if(!f(e))return{enabled:u.swipe_enabled,direction:u.swipe_direction,threshold:u.swipe_threshold,velocityThreshold:u.swipe_velocity_threshold,preventScroll:u.swipe_prevent_scroll};let t={enabled:(n=e.enabled)!=null?n:u.swipe_enabled,direction:e.direction||u.swipe_direction,threshold:(i=e.threshold)!=null?i:u.swipe_threshold,velocityThreshold:(o=e.velocityThreshold)!=null?o:u.swipe_velocity_threshold,preventScroll:(a=e.preventScroll)!=null?a:u.swipe_prevent_scroll};return["left","right","up","down"].forEach(s=>{!f(e[s])||!e[s].action||e[s].action==="none"||(t[s]={action:e[s].action})}),t}static _normalizeBadges(e){return Array.isArray(e)?e.filter(t=>f(t)).map(t=>{let n={...t,type:t.type||$.STATE};if(["entity","attribute","icon","color","label","unit","domain","state","count_state"].forEach(i=>{if(typeof n[i]=="string"){let o=n[i].trim();o?n[i]=o:delete n[i]}}),typeof n.value=="string"){let i=n.value.trim();i?n.value=i:delete n.value}return Array.isArray(n.entities)&&(n.entities=[...new Set(n.entities.map(i=>typeof i=="string"?i.trim():"").filter(Boolean))],n.entities.length===0&&delete n.entities),Array.isArray(n.thresholds)&&(n.thresholds=n.thresholds.filter(i=>f(i)&&v(i.value)&&typeof i.color=="string"&&i.color.trim()).map(i=>({value:i.value,color:i.color.trim()})),n.thresholds.length===0&&delete n.thresholds),Array.isArray(n.visibility)&&(n.visibility=n.visibility.filter(i=>f(i)&&G.includes(i.operator)).map(i=>this._normalizeBadgeRule(i)).filter(Boolean),n.visibility.length===0&&delete n.visibility),Array.isArray(n.color_rules)&&(n.color_rules=n.color_rules.filter(i=>f(i)&&G.includes(i.operator)).map(i=>this._normalizeBadgeColorRule(i)).filter(Boolean),n.color_rules.length===0&&delete n.color_rules),n}):[]}static _normalizeBadgeRule(e){if(!f(e))return null;let t={operator:e.operator||he.EQUALS,value:e.value};if(typeof e.entity=="string"){let n=e.entity.trim();n&&(t.entity=n)}if(typeof e.attribute=="string"){let n=e.attribute.trim();n&&(t.attribute=n)}if(typeof t.value=="string"){let n=t.value.trim();if(!n)return null;t.value=n}return t}static _normalizeBadgeColorRule(e){let t=this._normalizeBadgeRule(e);return!t||typeof e.color!="string"||!e.color.trim()?null:{...t,color:e.color.trim()}}static _normalizeStringListValue(e){if(typeof e=="string")return e.trim()||void 0;if(!Array.isArray(e))return;let t=e.map(n=>typeof n=="string"?n.trim():"").filter(Boolean);if(t.length!==0)return t.length===1?t[0]:t}static getTitle(e,t){var n;return e.title?e.title:e.entity&&((n=t==null?void 0:t.states)!=null&&n[e.entity])?t.states[e.entity].attributes.friendly_name||e.entity:""}static getSubtitle(e,t){var n;return e.subtitle?e.subtitle:e.entity&&((n=t==null?void 0:t.states)!=null&&n[e.entity])?t.states[e.entity].state:""}static hasChanged(e,t){return JSON.stringify(e)!==JSON.stringify(t)}static getSchema(){let e={type:"object",properties:{action:{type:"string",enum:Object.values(x),default:x.NONE},service:{type:"string"},navigation_path:{type:"string"},url_path:{type:"string"}}},t={type:"object",properties:{action:{type:"string",enum:Ie,default:"none"}}},i={type:"array",items:{type:"object",properties:{type:{type:"string"}}}},o={type:"object",properties:{cards:i}},a={type:"object",properties:{condition:{type:"string",enum:ot},entity:{type:"string",description:"Entity referenced by state-based visibility conditions."},attribute:{type:"string",description:"Optional entity attribute used instead of the primary state."},state:{type:["string","array"],description:"Allowed state or list of allowed states.",items:{type:"string"}},state_not:{type:["string","array"],description:"Blocked state or list of blocked states.",items:{type:"string"}},above:{type:"number",description:"Numeric lower bound (exclusive)."},below:{type:"number",description:"Numeric upper bound (exclusive)."},users:{type:"array",description:"Allowed user names or ids.",items:{type:"string"}},is_admin:{type:"boolean",description:"Require current user to be an admin."},is_owner:{type:"boolean",description:"Require current user to be the owner."},after:{type:"string",description:"Show only after the given HH:MM time."},before:{type:"string",description:"Show only before the given HH:MM time."},weekday:{type:"array",description:"Allowed weekdays.",items:{type:"string",enum:Re}},media_query:{type:"string",description:"CSS media query matched against the current viewport."},min_width:{type:"number",description:"Minimum viewport width in pixels."},max_width:{type:"number",description:"Maximum viewport width in pixels."}}};a.properties.conditions={type:"array",description:"Nested logical conditions for and/or/not groups.",items:a};let s={type:"object",properties:{background:{type:["string","number"]},color:{type:["string","number"]},border:{type:["string","number"]},class:{type:["string","array"],items:{type:"string"}}}},l={type:"object",properties:{value:{type:"number"},color:{type:"string"}}},c={type:"object",properties:{type:{type:"string",enum:Ne,default:$.STATE},entity:{type:"string"},attribute:{type:"string"},icon:{type:"string"},color:{type:"string"},value:{type:["string","number"]},label:{type:"string"},unit:{type:"string"},min:{type:"number"},max:{type:"number"},icon_only:{type:"boolean",default:!1},show_name:{type:"boolean",default:!1},show_progress:{type:"boolean",default:!1},precision:{type:"number",minimum:0,maximum:h.BADGE_MAX_PRECISION},format:{type:"string",enum:De,default:at.NONE},entities:{type:"array",items:{type:"string"}},domain:{type:"string"},state:{type:"string"},count_state:{type:"string"},thresholds:{type:"array",items:l},visibility:{type:"array",items:{type:"object",properties:{operator:{type:"string",enum:G,default:he.EQUALS},value:{type:["string","number","boolean"]},entity:{type:"string"},attribute:{type:"string"}}}},color_rules:{type:"array",items:{type:"object",properties:{operator:{type:"string",enum:G,default:he.EQUALS},value:{type:["string","number","boolean"]},entity:{type:"string"},attribute:{type:"string"},color:{type:"string"}}}},tap_action:e,icon_tap_action:e}},m={type:"object",properties:{enabled:{type:"boolean",default:u.swipe_enabled},direction:{type:"string",enum:He,default:u.swipe_direction},threshold:{type:"number",minimum:0,maximum:h.SWIPE_MAX_THRESHOLD_PX,default:u.swipe_threshold},velocityThreshold:{type:"number",minimum:0,maximum:h.SWIPE_MAX_VELOCITY_THRESHOLD,default:u.swipe_velocity_threshold},preventScroll:{type:"boolean",default:u.swipe_prevent_scroll},left:t,right:t,up:t,down:t}};return{type:"object",properties:{config_version:{type:"number",minimum:Be,maximum:T,default:T,description:"Config contract version. Legacy configs are migrated to the current version during normalize()."},card_id:{type:"string",description:"Stable identifier for cross-card control and persisted mode state."},title:{type:"string",description:"Primary card title."},subtitle:{type:"string",description:"Optional secondary title shown in the header."},icon:{type:"string",description:"Header icon in mdi format."},icon_color:{type:"string",description:"Optional CSS color value for the primary header icon."},entity:{type:"string",description:"Primary Home Assistant entity bound to the card."},attribute:{type:"string",description:"Optional root attribute used by state_styles and other state-aware features."},body_mode:{type:"string",enum:we,default:E.EXPAND,description:"Presentation mode used for the body region."},expand_trigger:{type:"string",enum:Te,default:u.expand_trigger,description:"Header gesture that toggles body expansion by default."},theme:{type:"string",enum:Object.values(J),default:u.theme,description:"Theme preset applied to the card shell."},padding:{type:"string",default:u.padding,description:"Internal card padding."},border_radius:{type:"string",default:u.border_radius,description:"Border radius applied to the card shell."},expanded:{type:"boolean",default:!1,description:"Whether the card starts expanded."},animation:{type:"boolean",default:!0,description:"Master switch for card animations."},animation_duration:{type:"number",minimum:0,maximum:h.ANIMATION_DURATION_MAX_MS,default:u.animation_duration,description:"Base animation duration applied to body and nested cards."},expand_animation:{type:"string",enum:Me,default:u.expand_animation,description:"Body expand animation variant."},collapse_animation:{type:"string",enum:Le,default:u.collapse_animation,description:"Body collapse animation variant."},cards_animation:{type:"string",enum:Pe,default:u.cards_animation,description:"Nested card reveal animation variant."},cards_stagger:{type:"number",minimum:0,maximum:h.CARDS_STAGGER_MAX_MS,default:u.cards_stagger,description:"Delay between nested card reveal steps in milliseconds."},cards_direction:{type:"string",enum:Oe,default:u.cards_direction,description:"Ordering strategy for nested card reveal."},stability_mode:{type:"boolean",default:!1,description:"Disables high-risk effects for predictable rendering."},lazy_load:{type:"boolean",default:!0,description:"Enables progressive body card loading."},lazy_initial_batch:{type:"number",minimum:h.LAZY_MIN_BATCH,maximum:h.LAZY_MAX_BATCH,default:u.lazy_initial_batch,description:"Initial number of cards to load before idle batching."},lazy_batch_size:{type:"number",minimum:h.LAZY_MIN_BATCH,maximum:h.LAZY_MAX_BATCH,default:u.lazy_batch_size,description:"Number of cards added on each idle lazy-load pass."},lazy_idle_timeout:{type:"number",minimum:h.LAZY_MIN_TIMEOUT_MS,maximum:h.LAZY_MAX_TIMEOUT_MS,default:u.lazy_idle_timeout,description:"Idle callback timeout used for deferred body work."},auto_collapse_after:{type:"number",minimum:0,maximum:h.AUTO_COLLAPSE_MAX_SECONDS,default:u.auto_collapse_after,description:"Automatically collapse the card after N seconds. Set 0 to disable."},remember_expanded_state:{type:"boolean",default:u.remember_expanded_state,description:"Persist expanded/collapsed state across renders."},remember_mode_state:{type:"boolean",default:u.remember_mode_state,description:"Persist active tab and slide indices across renders."},enable_card_pool:{type:"boolean",default:u.enable_card_pool,description:"Reuse detached body card elements to reduce churn."},pool_scope:{type:"string",enum:ke,default:u.pool_scope,description:"Reuse scope for pooled body card elements."},pool_ttl_ms:{type:"number",minimum:h.POOL_MIN_TTL_MS,maximum:h.POOL_MAX_TTL_MS,default:u.pool_ttl_ms,description:"Time-to-live for pooled body card instances."},pool_max_entries:{type:"number",minimum:h.POOL_MIN_MAX_ENTRIES,maximum:h.POOL_MAX_MAX_ENTRIES,default:u.pool_max_entries,description:"Maximum pooled entries retained for a reuse scope."},show_expand_icon:{type:"boolean",default:u.show_expand_icon,description:"Show the expand/collapse affordance in the header."},expand_icon:{type:"string",default:u.expand_icon,description:"Icon used for the expand affordance."},sticky_header:{type:"boolean",default:!1,description:"Keep the header pinned while the body scrolls."},grid:{type:"object",properties:{columns:{type:["number","string"],minimum:h.MIN_GRID_COLUMNS,maximum:h.MAX_GRID_COLUMNS,default:u.grid_columns,description:"Column count or CSS grid-template-columns string."},gap:{type:"string",default:u.grid_gap,description:"Gap between grid items."}}},modal:{type:"object",description:"Modal body mode sizing and overlay behavior.",properties:{width:{type:"string",default:u.modal_width,description:"Modal width. Use CSS lengths or auto."},height:{type:"string",default:u.modal_height,description:"Modal height. Use CSS lengths or auto."},max_width:{type:"string",default:u.modal_max_width,description:"Maximum width cap applied to the modal dialog."},max_height:{type:"string",default:u.modal_max_height,description:"Maximum height cap applied to the modal dialog."},loading_strategy:{type:"string",enum:pe,default:u.modal_loading_strategy,description:"Modal content loading strategy."},backdrop_blur:{type:"boolean",default:!0},backdrop_color:{type:"string",default:u.backdrop_color},close_on_backdrop:{type:"boolean",default:!0},close_on_escape:{type:"boolean",default:!0},show_close:{type:"boolean",default:!0}}},fullscreen:{type:"object",description:"Fullscreen body mode sizing and overlay behavior.",properties:{width:{type:"string",default:u.fullscreen_width},height:{type:"string",default:u.fullscreen_height},max_width:{type:"string",default:u.fullscreen_max_width},max_height:{type:"string",default:u.fullscreen_max_height},padding:{type:"string",default:u.fullscreen_padding},background:{type:"string",default:u.fullscreen_background},show_close:{type:"boolean",default:!0},close_on_escape:{type:"boolean",default:!0}}},header:{type:"object",description:"Header region configuration.",properties:{cards:i,sticky:{type:"boolean",default:!1},clickable:{type:"boolean",default:!0},layout:{type:"object",properties:{variant:{type:"string",enum:de,default:u.header_layout_variant},gap:{type:"string",default:u.header_gap},content_gap:{type:"string",default:u.header_content_gap},align:{type:"string",enum:le,default:u.header_content_align},badges_position:{type:"string",enum:ue,default:u.header_badges_position}}}}},header_left:{...o,description:"Cards rendered in the left header slot."},header_right:{...o,description:"Cards rendered in the right header slot."},body:{...o,description:"Body region configuration."},footer:{...o,description:"Footer region configuration."},tabs:{type:"array",description:"Tab definitions used by tabs body mode.",items:{type:"object",properties:{label:{type:"string"},icon:{type:"string"},cards:i}}},tabs_config:{type:"object",description:"Tabs body mode UI controls.",properties:{position:{type:"string",default:"top"},show_icons:{type:"boolean",default:!0},show_labels:{type:"boolean",default:!0},content_padding:{type:"string",default:u.tabs_content_padding},tab_min_width:{type:"string",default:u.tabs_tab_min_width},tab_alignment:{type:"string",enum:se,default:u.tabs_tab_alignment}}},carousel_options:{type:"object",description:"Carousel body mode layout and control options.",properties:{show_arrows:{type:"boolean",default:u.carousel_show_arrows},show_indicators:{type:"boolean",default:u.carousel_show_indicators},loop:{type:"boolean",default:u.carousel_loop},swipe_threshold:{type:"number",minimum:0,maximum:h.SWIPE_MAX_THRESHOLD_PX,default:u.swipe_threshold},height:{type:"string",default:u.carousel_height}}},subview:{type:"object",description:"Subview navigation settings used by subview body mode.",properties:{path:{type:"string"},navigation_path:{type:"string"},replace_state:{type:"boolean",default:!1},return_on_close:{type:"boolean",default:!1}}},carousel_autoplay:{type:"boolean",default:u.carousel_autoplay,description:"Automatically advance slides in carousel mode."},carousel_interval:{type:"number",minimum:h.CAROUSEL_MIN_INTERVAL_MS,maximum:h.CAROUSEL_MAX_INTERVAL_MS,default:u.carousel_interval,description:"Delay between autoplay slide changes in carousel mode."},tap_action:{...e,description:"Action executed on tap."},hold_action:{...e,description:"Action executed on hold."},double_tap_action:{...e,description:"Action executed on double tap."},visibility:{type:"array",description:"Top-level card visibility conditions.",items:a},section_visibility:{type:"object",description:"Per-section visibility conditions for header/body/footer.",properties:{header:{type:"array",items:a},body:{type:"array",items:a},footer:{type:"array",items:a}}},swipe:{...m,description:"Gesture handling for top-level card swipes."},badges:{type:"array",description:"Header badge definitions.",items:c},state_styles:{type:"object",description:"Map of states or numeric matchers to style overrides applied to the card shell.",additionalProperties:s},theme_tokens:{type:"object",description:"CSS variable overrides applied after theme resolution.",additionalProperties:{type:"string"}},custom_css:{type:["string","object","array"],description:"Scoped custom CSS definitions."}}}}static _validateCustomCSS(e,t){if(typeof e=="string")return;if(Array.isArray(e)){e.forEach((o,a)=>{this._validateCustomCSS(o,`${t}[${a}]`)});return}if(!f(e))throw new d("custom_css must be a string, object, or array",t);if(["css","scope","mode","priority","id"].some(o=>o in e)){if(e.css!==void 0&&typeof e.css!="string")throw new d("custom_css.css must be a string",`${t}.css`);if(e.scope!==void 0&&typeof e.scope!="string")throw new d("custom_css.scope must be a string",`${t}.scope`);return}Object.entries(e).forEach(([o,a])=>{if(typeof a!="string")throw new d("custom_css scoped values must be strings",`${t}.${o}`)})}};function st(r,e=100,t={}){let{leading:n=!1,trailing:i=!0}=t,o=null,a=null,s=null,l,c=null;function m(w){let P=a,Z=s;return P&&(a=null,s=null,c=w,l=r.apply(Z,P)),l}function b(w){let P=c===null?e:w-c;return c===null||P>=e}function _(){let w=Date.now();return b(w)?y(w):(o=setTimeout(_,e-(w-c)),l)}function y(w){return o=null,i&&a?m(w):(a=null,s=null,l)}function S(w){return c=w,o=setTimeout(_,e),n?m(w):l}function k(...w){let P=Date.now(),Z=b(P);return a=w,s=this,Z&&o===null?S(P):(o===null&&(o=setTimeout(_,e)),l)}return k.cancel=function(){o!==null&&clearTimeout(o),a=null,s=null,c=null,o=null},k.flush=function(){return o!==null?y(Date.now()):l},k.pending=function(){return o!==null},k}function Ue(r,e=16,t={}){let{leading:n=!0,trailing:i=!0}=t,o=0,a=null,s=null,l=null;function c(){let b=s,_=l;if(b)return s=null,l=null,o=Date.now(),r.apply(_,b)}function m(...b){let y=Date.now()-o;if(s=b,l=this,y>=e&&(a!==null&&(clearTimeout(a),a=null),n))return c();if(a===null&&i){let S=e-y;a=setTimeout(()=>{a=null,c()},S>0?S:0)}}return m.cancel=function(){a!==null&&(clearTimeout(a),a=null),o=0,s=null,l=null},m}function zt(r,e={}){let{timeout:t=1e3}=e;return"requestIdleCallback"in window?window.requestIdleCallback(r,{timeout:t}):setTimeout(r,1)}function Vt(r){"cancelIdleCallback"in window?window.cancelIdleCallback(r):clearTimeout(r)}var dt=class{constructor(){this._cards=new Set,this._cardsById=new Map,this._listening=!1,this._boundControlHandler=this._handleControl.bind(this),this._boundResizeHandler=Ue(()=>this._handleResize(),h.RESIZE_DEBOUNCE_MS)}register(e){var t;!e||this._cards.has(e)||(this._cards.add(e),this._indexCard(e,(t=e._config)==null?void 0:t.card_id),this._listening||this._attachListeners())}unregister(e){var t;!e||!this._cards.has(e)||(this._cards.delete(e),this._deindexCard(e,(t=e._config)==null?void 0:t.card_id),this._cards.size===0&&this._detachListeners())}updateCardId(e,t,n){!e||!this._cards.has(e)||t===n||(this._deindexCard(e,t),this._indexCard(e,n))}_attachListeners(){window.addEventListener(Y.CARD_CONTROL,this._boundControlHandler),window.addEventListener("resize",this._boundResizeHandler),this._listening=!0}_detachListeners(){this._listening&&(window.removeEventListener(Y.CARD_CONTROL,this._boundControlHandler),window.removeEventListener("resize",this._boundResizeHandler),typeof this._boundResizeHandler.cancel=="function"&&this._boundResizeHandler.cancel(),this._listening=!1)}_handleControl(e){var n;let t=(n=e==null?void 0:e.detail)==null?void 0:n.card_id;if(t){let i=this._cardsById.get(t);if(!i)return;i.forEach(o=>{o!=null&&o.isConnected&&o._handleExternalControl(e)});return}this._cards.forEach(i=>{i!=null&&i.isConnected&&i._handleExternalControl(e)})}_handleResize(){this._cards.forEach(e=>{e!=null&&e.isConnected&&typeof e._resizeHandler=="function"&&e._resizeHandler()})}_indexCard(e,t){if(!t)return;let n=this._cardsById.get(t);n||(n=new Set,this._cardsById.set(t,n)),n.add(e)}_deindexCard(e,t){if(!t)return;let n=this._cardsById.get(t);n&&(n.delete(e),n.size===0&&this._cardsById.delete(t))}},lt=class{constructor(){this._cache=new Map,this._dirty=new Map,this._flushTimer=null,this._flushDelayMs=200}get(e,t=null){if(!e)return t;if(this._cache.has(e))return this._cache.get(e);let n=t;try{let i=localStorage.getItem(e);i!==null&&(n=JSON.parse(i))}catch(i){n=t}return this._cache.set(e,n),n}set(e,t){e&&(this._cache.set(e,t),this._dirty.set(e,t),this._scheduleFlush())}_scheduleFlush(){this._flushTimer===null&&(this._flushTimer=setTimeout(()=>{this._flush()},this._flushDelayMs))}_flush(){this._flushTimer=null,this._dirty.size!==0&&(this._dirty.forEach((e,t)=>{try{localStorage.setItem(t,JSON.stringify(e))}catch(n){}}),this._dirty.clear())}},ct=class{constructor(){this._entries=new Map,this._defaultMaxEntries=h.CARD_POOL_MAX_ENTRIES,this._defaultMaxAgeMs=h.CARD_POOL_MAX_AGE_MS,this._hardMaxEntries=Math.max(this._defaultMaxEntries,h.CARD_POOL_HARD_MAX_ENTRIES||this._defaultMaxEntries),this._hits=0,this._misses=0}acquire(e){if(!e)return null;this._pruneExpired();let t=this._entries.get(e);if(!t)return this._misses+=1,null;this._entries.delete(e);let n=t.cards.filter(i=>i instanceof HTMLElement);return n.length===0?(this._misses+=1,null):(this._hits+=1,n)}release(e,t,n={}){if(!e||!Array.isArray(t)||t.length===0)return;this._pruneExpired();let i=t.filter(l=>l instanceof HTMLElement);if(i.length===0)return;i.forEach(l=>{l.parentElement&&l.parentElement.removeChild(l)});let o=this._normalizeScope(n.scope),a=this._normalizeNumber(n.maxAgeMs,this._defaultMaxAgeMs,h.POOL_MIN_TTL_MS,h.POOL_MAX_TTL_MS),s=this._normalizeNumber(n.maxEntries,this._defaultMaxEntries,h.POOL_MIN_MAX_ENTRIES,h.POOL_MAX_MAX_ENTRIES);this._entries.delete(e),this._entries.set(e,{cards:i,timestamp:Date.now(),scope:o,maxAgeMs:a,maxEntries:s}),this._pruneToScopeLimit(o,s),this._pruneToHardLimit()}invalidate(e){e&&this._entries.delete(e)}clear(){this._entries.clear()}getStats(){let e={};return this._entries.forEach(t=>{let n=(t==null?void 0:t.scope)||"card";e[n]=(e[n]||0)+1}),{size:this._entries.size,hits:this._hits,misses:this._misses,byScope:e}}_pruneExpired(){let e=Date.now();this._entries.forEach((t,n)=>{let i=this._normalizeNumber(t==null?void 0:t.maxAgeMs,this._defaultMaxAgeMs,h.POOL_MIN_TTL_MS,h.POOL_MAX_TTL_MS);(!t||e-t.timestamp>i)&&this._entries.delete(n)})}_pruneToHardLimit(){for(;this._entries.size>this._hardMaxEntries;){let e=this._entries.keys().next().value;if(!e)break;this._entries.delete(e)}}_pruneToScopeLimit(e,t){if(!e||!Number.isFinite(t))return;let n=0;for(this._entries.forEach(i=>{((i==null?void 0:i.scope)||"card")===e&&(n+=1)});n>t;){let i=this._findOldestKeyByScope(e);if(!i)break;this._entries.delete(i),n-=1}}_findOldestKeyByScope(e){for(let[t,n]of this._entries.entries())if(((n==null?void 0:n.scope)||"card")===e)return t;return null}_normalizeScope(e){return e==="dashboard"||e==="global"?e:"card"}_normalizeNumber(e,t,n,i){let o=Number(e);if(!Number.isFinite(o))return t;let a=Math.floor(o);return Math.min(i,Math.max(n,a))}},ut=class{constructor(){this._metrics=new Map,this._budgets={tti:_e.TTI_MS,render:_e.RENDER_MS,update:_e.UPDATE_MS,body_load:_e.BODY_LOAD_MS},this._historyLimit=h.METRICS_HISTORY_SIZE}record(e,t,n={}){if(!e||!Number.isFinite(t))return;let i=this._ensureBucket(e),o={type:e,durationMs:t,timestamp:Date.now(),...n};i.push(o),i.length>this._historyLimit&&i.shift();let a=this._budgets[e];Number.isFinite(a)&&t>a&&console.warn(`[UniversalCard][perf] ${e} ${t.toFixed(1)}ms > ${a}ms`,n);try{window.dispatchEvent(new CustomEvent("universal-card-performance",{detail:o}))}catch(s){}}getStats(e){let t=this._metrics.get(e)||[];if(t.length===0)return{count:0,min:0,max:0,avg:0,samples:[]};let n=1/0,i=0,o=0;return t.forEach(a=>{let s=a.durationMs;n=Math.min(n,s),i=Math.max(i,s),o+=s}),{count:t.length,min:n,max:i,avg:o/t.length,samples:[...t]}}snapshot(){let e={};return this._metrics.forEach((t,n)=>{e[n]=this.getStats(n)}),e}_ensureBucket(e){let t=this._metrics.get(e);return t||(t=[],this._metrics.set(e,t)),t}},$e=new dt,me=new lt,R=new ct,ze=new ut;var Tn={APPEND:"append",PREPEND:"prepend",REPLACE:"replace"},K={CARD:"card",HEADER:"header",BODY:"body",FOOTER:"footer",GLOBAL:"global"},kn={enabled:!0,sanitize:!0,allowVariables:!0,allowAnimations:!0,maxLength:5e4,blockedProperties:["behavior","expression","-moz-binding"],blockedSelectors:["body","html",":root","head","script"]},Ve=class{constructor(e,t={}){this._shadowRoot=e,this._config={...kn,...t},this._styles=new Map,this._styleElement=null,this._init()}_init(){this._styleElement=document.createElement("style"),this._styleElement.setAttribute("data-custom-css","true"),this._shadowRoot.appendChild(this._styleElement)}add(e,t,n={}){if(!this._config.enabled)return!1;let{scope:i=K.CARD,mode:o=Tn.APPEND,priority:a=0}=n;if(!t||typeof t!="string")return console.warn("[CustomCSS] Invalid CSS"),!1;if(t.length>this._config.maxLength)return console.warn("[CustomCSS] CSS exceeds maximum length"),!1;let s=t;return this._config.sanitize&&(s=this._sanitize(t),!s)?(console.warn("[CustomCSS] CSS failed sanitization"),!1):(s=this._addScopePrefix(s,i),this._styles.set(e,{css:s,originalCSS:t,scope:i,mode:o,priority:a,enabled:!0}),this._updateStyles(),!0)}remove(e){let t=this._styles.delete(e);return t&&this._updateStyles(),t}enable(e){let t=this._styles.get(e);t&&(t.enabled=!0,this._updateStyles())}disable(e){let t=this._styles.get(e);t&&(t.enabled=!1,this._updateStyles())}update(e,t){let n=this._styles.get(e);return n?this.add(e,t,{scope:n.scope,mode:n.mode,priority:n.priority}):!1}_sanitize(e){let t=e;t=t.replace(/\/\*[\s\S]*?\*\//g,"");for(let n of this._config.blockedProperties)if(new RegExp(`${n}\\s*:`,"gi").test(t))return console.warn(`[CustomCSS] Blocked property detected: ${n}`),null;for(let n of this._config.blockedSelectors)if(new RegExp(`(^|[{},\\s])${n}[\\s{,]`,"gi").test(t))return console.warn(`[CustomCSS] Blocked selector detected: ${n}`),null;return/url\s*\(\s*['"]?\s*javascript:/gi.test(t)?(console.warn("[CustomCSS] JavaScript URL detected"),null):(/@import/gi.test(t)&&(console.warn("[CustomCSS] @import is not allowed"),t=t.replace(/@import[^;]*;/gi,"")),this._config.allowAnimations||(t=t.replace(/animation[^;]*;/gi,""),t=t.replace(/transition[^;]*;/gi,"")),t)}_addScopePrefix(e,t){if(t===K.GLOBAL)return e;let i={[K.CARD]:":host",[K.HEADER]:".uc-header",[K.BODY]:".uc-body",[K.FOOTER]:".uc-footer"}[t]||"";return i?e.replace(/([^{}]+)(\{[^}]*\})/g,(o,a,s)=>`${a.split(",").map(c=>(c=c.trim(),c.startsWith(":host")||c.startsWith(i)?c:i===":host"?`:host ${c}`:`${i} ${c}`)).join(", ")} ${s}`):e}_updateStyles(){if(!this._styleElement)return;let t=Array.from(this._styles.values()).filter(n=>n.enabled).sort((n,i)=>n.priority-i.priority).map(n=>n.css).join(`