/** * @license * Copyright 2019 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const oe = globalThis, ge = oe.ShadowRoot && (oe.ShadyCSS === void 0 || oe.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, _e = Symbol(), xe = /* @__PURE__ */ new WeakMap(); let Be = class { constructor(e, i, n) { if (this._$cssResult$ = !0, n !== _e) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead."); this.cssText = e, this.t = i; } get styleSheet() { let e = this.o; const i = this.t; if (ge && e === void 0) { const n = i !== void 0 && i.length === 1; n && (e = xe.get(i)), e === void 0 && ((this.o = e = new CSSStyleSheet()).replaceSync(this.cssText), n && xe.set(i, e)); } return e; } toString() { return this.cssText; } }; const rt = (t) => new Be(typeof t == "string" ? t : t + "", void 0, _e), Fe = (t, ...e) => { const i = t.length === 1 ? t[0] : e.reduce(((n, s, o) => n + ((r) => { if (r._$cssResult$ === !0) return r.cssText; if (typeof r == "number") return r; throw Error("Value passed to 'css' function must be a 'css' function result: " + r + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security."); })(s) + t[o + 1]), t[0]); return new Be(i, t, _e); }, at = (t, e) => { if (ge) t.adoptedStyleSheets = e.map(((i) => i instanceof CSSStyleSheet ? i : i.styleSheet)); else for (const i of e) { const n = document.createElement("style"), s = oe.litNonce; s !== void 0 && n.setAttribute("nonce", s), n.textContent = i.cssText, t.appendChild(n); } }, we = ge ? (t) => t : (t) => t instanceof CSSStyleSheet ? ((e) => { let i = ""; for (const n of e.cssRules) i += n.cssText; return rt(i); })(t) : t; /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const { is: lt, defineProperty: ct, getOwnPropertyDescriptor: ht, getOwnPropertyNames: ut, getOwnPropertySymbols: dt, getPrototypeOf: ft } = Object, E = globalThis, Ae = E.trustedTypes, pt = Ae ? Ae.emptyScript : "", gt = E.reactiveElementPolyfillSupport, J = (t, e) => t, se = { toAttribute(t, e) { switch (e) { case Boolean: t = t ? pt : null; break; case Object: case Array: t = t == null ? t : JSON.stringify(t); } return t; }, fromAttribute(t, e) { let i = t; switch (e) { case Boolean: i = t !== null; break; case Number: i = t === null ? null : Number(t); break; case Object: case Array: try { i = JSON.parse(t); } catch { i = null; } } return i; } }, me = (t, e) => !lt(t, e), ke = { attribute: !0, type: String, converter: se, reflect: !1, useDefault: !1, hasChanged: me }; Symbol.metadata ?? (Symbol.metadata = Symbol("metadata")), E.litPropertyMetadata ?? (E.litPropertyMetadata = /* @__PURE__ */ new WeakMap()); let U = class extends HTMLElement { static addInitializer(e) { this._$Ei(), (this.l ?? (this.l = [])).push(e); } static get observedAttributes() { return this.finalize(), this._$Eh && [...this._$Eh.keys()]; } static createProperty(e, i = ke) { if (i.state && (i.attribute = !1), this._$Ei(), this.prototype.hasOwnProperty(e) && ((i = Object.create(i)).wrapped = !0), this.elementProperties.set(e, i), !i.noAccessor) { const n = Symbol(), s = this.getPropertyDescriptor(e, n, i); s !== void 0 && ct(this.prototype, e, s); } } static getPropertyDescriptor(e, i, n) { const { get: s, set: o } = ht(this.prototype, e) ?? { get() { return this[i]; }, set(r) { this[i] = r; } }; return { get: s, set(r) { const a = s?.call(this); o?.call(this, r), this.requestUpdate(e, a, n); }, configurable: !0, enumerable: !0 }; } static getPropertyOptions(e) { return this.elementProperties.get(e) ?? ke; } static _$Ei() { if (this.hasOwnProperty(J("elementProperties"))) return; const e = ft(this); e.finalize(), e.l !== void 0 && (this.l = [...e.l]), this.elementProperties = new Map(e.elementProperties); } static finalize() { if (this.hasOwnProperty(J("finalized"))) return; if (this.finalized = !0, this._$Ei(), this.hasOwnProperty(J("properties"))) { const i = this.properties, n = [...ut(i), ...dt(i)]; for (const s of n) this.createProperty(s, i[s]); } const e = this[Symbol.metadata]; if (e !== null) { const i = litPropertyMetadata.get(e); if (i !== void 0) for (const [n, s] of i) this.elementProperties.set(n, s); } this._$Eh = /* @__PURE__ */ new Map(); for (const [i, n] of this.elementProperties) { const s = this._$Eu(i, n); s !== void 0 && this._$Eh.set(s, i); } this.elementStyles = this.finalizeStyles(this.styles); } static finalizeStyles(e) { const i = []; if (Array.isArray(e)) { const n = new Set(e.flat(1 / 0).reverse()); for (const s of n) i.unshift(we(s)); } else e !== void 0 && i.push(we(e)); return i; } static _$Eu(e, i) { const n = i.attribute; return n === !1 ? void 0 : typeof n == "string" ? n : typeof e == "string" ? e.toLowerCase() : void 0; } constructor() { super(), this._$Ep = void 0, this.isUpdatePending = !1, this.hasUpdated = !1, this._$Em = null, this._$Ev(); } _$Ev() { this._$ES = new Promise(((e) => this.enableUpdating = e)), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach(((e) => e(this))); } addController(e) { (this._$EO ?? (this._$EO = /* @__PURE__ */ new Set())).add(e), this.renderRoot !== void 0 && this.isConnected && e.hostConnected?.(); } removeController(e) { this._$EO?.delete(e); } _$E_() { const e = /* @__PURE__ */ new Map(), i = this.constructor.elementProperties; for (const n of i.keys()) this.hasOwnProperty(n) && (e.set(n, this[n]), delete this[n]); e.size > 0 && (this._$Ep = e); } createRenderRoot() { const e = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions); return at(e, this.constructor.elementStyles), e; } connectedCallback() { this.renderRoot ?? (this.renderRoot = this.createRenderRoot()), this.enableUpdating(!0), this._$EO?.forEach(((e) => e.hostConnected?.())); } enableUpdating(e) { } disconnectedCallback() { this._$EO?.forEach(((e) => e.hostDisconnected?.())); } attributeChangedCallback(e, i, n) { this._$AK(e, n); } _$ET(e, i) { const n = this.constructor.elementProperties.get(e), s = this.constructor._$Eu(e, n); if (s !== void 0 && n.reflect === !0) { const o = (n.converter?.toAttribute !== void 0 ? n.converter : se).toAttribute(i, n.type); this._$Em = e, o == null ? this.removeAttribute(s) : this.setAttribute(s, o), this._$Em = null; } } _$AK(e, i) { const n = this.constructor, s = n._$Eh.get(e); if (s !== void 0 && this._$Em !== s) { const o = n.getPropertyOptions(s), r = typeof o.converter == "function" ? { fromAttribute: o.converter } : o.converter?.fromAttribute !== void 0 ? o.converter : se; this._$Em = s; const a = r.fromAttribute(i, o.type); this[s] = a ?? this._$Ej?.get(s) ?? a, this._$Em = null; } } requestUpdate(e, i, n) { if (e !== void 0) { const s = this.constructor, o = this[e]; if (n ?? (n = s.getPropertyOptions(e)), !((n.hasChanged ?? me)(o, i) || n.useDefault && n.reflect && o === this._$Ej?.get(e) && !this.hasAttribute(s._$Eu(e, n)))) return; this.C(e, i, n); } this.isUpdatePending === !1 && (this._$ES = this._$EP()); } C(e, i, { useDefault: n, reflect: s, wrapped: o }, r) { n && !(this._$Ej ?? (this._$Ej = /* @__PURE__ */ new Map())).has(e) && (this._$Ej.set(e, r ?? i ?? this[e]), o !== !0 || r !== void 0) || (this._$AL.has(e) || (this.hasUpdated || n || (i = void 0), this._$AL.set(e, i)), s === !0 && this._$Em !== e && (this._$Eq ?? (this._$Eq = /* @__PURE__ */ new Set())).add(e)); } async _$EP() { this.isUpdatePending = !0; try { await this._$ES; } catch (i) { Promise.reject(i); } const e = this.scheduleUpdate(); return e != null && await e, !this.isUpdatePending; } scheduleUpdate() { return this.performUpdate(); } performUpdate() { if (!this.isUpdatePending) return; if (!this.hasUpdated) { if (this.renderRoot ?? (this.renderRoot = this.createRenderRoot()), this._$Ep) { for (const [s, o] of this._$Ep) this[s] = o; this._$Ep = void 0; } const n = this.constructor.elementProperties; if (n.size > 0) for (const [s, o] of n) { const { wrapped: r } = o, a = this[s]; r !== !0 || this._$AL.has(s) || a === void 0 || this.C(s, void 0, o, a); } } let e = !1; const i = this._$AL; try { e = this.shouldUpdate(i), e ? (this.willUpdate(i), this._$EO?.forEach(((n) => n.hostUpdate?.())), this.update(i)) : this._$EM(); } catch (n) { throw e = !1, this._$EM(), n; } e && this._$AE(i); } willUpdate(e) { } _$AE(e) { this._$EO?.forEach(((i) => i.hostUpdated?.())), this.hasUpdated || (this.hasUpdated = !0, this.firstUpdated(e)), this.updated(e); } _$EM() { this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = !1; } get updateComplete() { return this.getUpdateComplete(); } getUpdateComplete() { return this._$ES; } shouldUpdate(e) { return !0; } update(e) { this._$Eq && (this._$Eq = this._$Eq.forEach(((i) => this._$ET(i, this[i])))), this._$EM(); } updated(e) { } firstUpdated(e) { } }; U.elementStyles = [], U.shadowRootOptions = { mode: "open" }, U[J("elementProperties")] = /* @__PURE__ */ new Map(), U[J("finalized")] = /* @__PURE__ */ new Map(), gt?.({ ReactiveElement: U }), (E.reactiveElementVersions ?? (E.reactiveElementVersions = [])).push("2.1.1"); /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const Z = globalThis, re = Z.trustedTypes, Ce = re ? re.createPolicy("lit-html", { createHTML: (t) => t }) : void 0, je = "$lit$", V = `lit$${Math.random().toFixed(9).slice(2)}$`, qe = "?" + V, _t = `<${qe}>`, I = document, Q = () => I.createComment(""), K = (t) => t === null || typeof t != "object" && typeof t != "function", be = Array.isArray, mt = (t) => be(t) || typeof t?.[Symbol.iterator] == "function", de = `[ \f\r]`, W = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, Se = /-->/g, ze = />/g, P = RegExp(`>|${de}(?:([^\\s"'>=/]+)(${de}*=${de}*(?:[^ \f\r"'\`<>=]|("|')|))|$)`, "g"), Me = /'/g, Ve = /"/g, We = /^(?:script|style|textarea|title)$/i, Ge = (t) => (e, ...i) => ({ _$litType$: t, strings: e, values: i }), x = Ge(1), D = Ge(2), j = Symbol.for("lit-noChange"), _ = Symbol.for("lit-nothing"), Ee = /* @__PURE__ */ new WeakMap(), O = I.createTreeWalker(I, 129); function Ye(t, e) { if (!be(t) || !t.hasOwnProperty("raw")) throw Error("invalid template strings array"); return Ce !== void 0 ? Ce.createHTML(e) : e; } const bt = (t, e) => { const i = t.length - 1, n = []; let s, o = e === 2 ? "" : e === 3 ? "" : "", r = W; for (let a = 0; a < i; a++) { const l = t[a]; let h, c, u = -1, f = 0; for (; f < l.length && (r.lastIndex = f, c = r.exec(l), c !== null); ) f = r.lastIndex, r === W ? c[1] === "!--" ? r = Se : c[1] !== void 0 ? r = ze : c[2] !== void 0 ? (We.test(c[2]) && (s = RegExp("" ? (r = s ?? W, u = -1) : c[1] === void 0 ? u = -2 : (u = r.lastIndex - c[2].length, h = c[1], r = c[3] === void 0 ? P : c[3] === '"' ? Ve : Me) : r === Ve || r === Me ? r = P : r === Se || r === ze ? r = W : (r = P, s = void 0); const d = r === P && t[a + 1].startsWith("/>") ? " " : ""; o += r === W ? l + _t : u >= 0 ? (n.push(h), l.slice(0, u) + je + l.slice(u) + V + d) : l + V + (u === -2 ? a : d); } return [Ye(t, o + (t[i] || "") + (e === 2 ? "" : e === 3 ? "" : "")), n]; }; class ee { constructor({ strings: e, _$litType$: i }, n) { let s; this.parts = []; let o = 0, r = 0; const a = e.length - 1, l = this.parts, [h, c] = bt(e, i); if (this.el = ee.createElement(h, n), O.currentNode = this.el.content, i === 2 || i === 3) { const u = this.el.content.firstChild; u.replaceWith(...u.childNodes); } for (; (s = O.nextNode()) !== null && l.length < a; ) { if (s.nodeType === 1) { if (s.hasAttributes()) for (const u of s.getAttributeNames()) if (u.endsWith(je)) { const f = c[r++], d = s.getAttribute(u).split(V), p = /([.?@])?(.*)/.exec(f); l.push({ type: 1, index: o, name: p[2], strings: d, ctor: p[1] === "." ? yt : p[1] === "?" ? $t : p[1] === "@" ? xt : le }), s.removeAttribute(u); } else u.startsWith(V) && (l.push({ type: 6, index: o }), s.removeAttribute(u)); if (We.test(s.tagName)) { const u = s.textContent.split(V), f = u.length - 1; if (f > 0) { s.textContent = re ? re.emptyScript : ""; for (let d = 0; d < f; d++) s.append(u[d], Q()), O.nextNode(), l.push({ type: 2, index: ++o }); s.append(u[f], Q()); } } } else if (s.nodeType === 8) if (s.data === qe) l.push({ type: 2, index: o }); else { let u = -1; for (; (u = s.data.indexOf(V, u + 1)) !== -1; ) l.push({ type: 7, index: o }), u += V.length - 1; } o++; } } static createElement(e, i) { const n = I.createElement("template"); return n.innerHTML = e, n; } } function q(t, e, i = t, n) { if (e === j) return e; let s = n !== void 0 ? i._$Co?.[n] : i._$Cl; const o = K(e) ? void 0 : e._$litDirective$; return s?.constructor !== o && (s?._$AO?.(!1), o === void 0 ? s = void 0 : (s = new o(t), s._$AT(t, i, n)), n !== void 0 ? (i._$Co ?? (i._$Co = []))[n] = s : i._$Cl = s), s !== void 0 && (e = q(t, s._$AS(t, e.values), s, n)), e; } class vt { constructor(e, i) { this._$AV = [], this._$AN = void 0, this._$AD = e, this._$AM = i; } get parentNode() { return this._$AM.parentNode; } get _$AU() { return this._$AM._$AU; } u(e) { const { el: { content: i }, parts: n } = this._$AD, s = (e?.creationScope ?? I).importNode(i, !0); O.currentNode = s; let o = O.nextNode(), r = 0, a = 0, l = n[0]; for (; l !== void 0; ) { if (r === l.index) { let h; l.type === 2 ? h = new te(o, o.nextSibling, this, e) : l.type === 1 ? h = new l.ctor(o, l.name, l.strings, this, e) : l.type === 6 && (h = new wt(o, this, e)), this._$AV.push(h), l = n[++a]; } r !== l?.index && (o = O.nextNode(), r++); } return O.currentNode = I, s; } p(e) { let i = 0; for (const n of this._$AV) n !== void 0 && (n.strings !== void 0 ? (n._$AI(e, n, i), i += n.strings.length - 2) : n._$AI(e[i])), i++; } } class te { get _$AU() { return this._$AM?._$AU ?? this._$Cv; } constructor(e, i, n, s) { this.type = 2, this._$AH = _, this._$AN = void 0, this._$AA = e, this._$AB = i, this._$AM = n, this.options = s, this._$Cv = s?.isConnected ?? !0; } get parentNode() { let e = this._$AA.parentNode; const i = this._$AM; return i !== void 0 && e?.nodeType === 11 && (e = i.parentNode), e; } get startNode() { return this._$AA; } get endNode() { return this._$AB; } _$AI(e, i = this) { e = q(this, e, i), K(e) ? e === _ || e == null || e === "" ? (this._$AH !== _ && this._$AR(), this._$AH = _) : e !== this._$AH && e !== j && this._(e) : e._$litType$ !== void 0 ? this.$(e) : e.nodeType !== void 0 ? this.T(e) : mt(e) ? this.k(e) : this._(e); } O(e) { return this._$AA.parentNode.insertBefore(e, this._$AB); } T(e) { this._$AH !== e && (this._$AR(), this._$AH = this.O(e)); } _(e) { this._$AH !== _ && K(this._$AH) ? this._$AA.nextSibling.data = e : this.T(I.createTextNode(e)), this._$AH = e; } $(e) { const { values: i, _$litType$: n } = e, s = typeof n == "number" ? this._$AC(e) : (n.el === void 0 && (n.el = ee.createElement(Ye(n.h, n.h[0]), this.options)), n); if (this._$AH?._$AD === s) this._$AH.p(i); else { const o = new vt(s, this), r = o.u(this.options); o.p(i), this.T(r), this._$AH = o; } } _$AC(e) { let i = Ee.get(e.strings); return i === void 0 && Ee.set(e.strings, i = new ee(e)), i; } k(e) { be(this._$AH) || (this._$AH = [], this._$AR()); const i = this._$AH; let n, s = 0; for (const o of e) s === i.length ? i.push(n = new te(this.O(Q()), this.O(Q()), this, this.options)) : n = i[s], n._$AI(o), s++; s < i.length && (this._$AR(n && n._$AB.nextSibling, s), i.length = s); } _$AR(e = this._$AA.nextSibling, i) { for (this._$AP?.(!1, !0, i); e !== this._$AB; ) { const n = e.nextSibling; e.remove(), e = n; } } setConnected(e) { this._$AM === void 0 && (this._$Cv = e, this._$AP?.(e)); } } class le { get tagName() { return this.element.tagName; } get _$AU() { return this._$AM._$AU; } constructor(e, i, n, s, o) { this.type = 1, this._$AH = _, this._$AN = void 0, this.element = e, this.name = i, this._$AM = s, this.options = o, n.length > 2 || n[0] !== "" || n[1] !== "" ? (this._$AH = Array(n.length - 1).fill(new String()), this.strings = n) : this._$AH = _; } _$AI(e, i = this, n, s) { const o = this.strings; let r = !1; if (o === void 0) e = q(this, e, i, 0), r = !K(e) || e !== this._$AH && e !== j, r && (this._$AH = e); else { const a = e; let l, h; for (e = o[0], l = 0; l < o.length - 1; l++) h = q(this, a[n + l], i, l), h === j && (h = this._$AH[l]), r || (r = !K(h) || h !== this._$AH[l]), h === _ ? e = _ : e !== _ && (e += (h ?? "") + o[l + 1]), this._$AH[l] = h; } r && !s && this.j(e); } j(e) { e === _ ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, e ?? ""); } } class yt extends le { constructor() { super(...arguments), this.type = 3; } j(e) { this.element[this.name] = e === _ ? void 0 : e; } } class $t extends le { constructor() { super(...arguments), this.type = 4; } j(e) { this.element.toggleAttribute(this.name, !!e && e !== _); } } class xt extends le { constructor(e, i, n, s, o) { super(e, i, n, s, o), this.type = 5; } _$AI(e, i = this) { if ((e = q(this, e, i, 0) ?? _) === j) return; const n = this._$AH, s = e === _ && n !== _ || e.capture !== n.capture || e.once !== n.once || e.passive !== n.passive, o = e !== _ && (n === _ || s); s && this.element.removeEventListener(this.name, this, n), o && this.element.addEventListener(this.name, this, e), this._$AH = e; } handleEvent(e) { typeof this._$AH == "function" ? this._$AH.call(this.options?.host ?? this.element, e) : this._$AH.handleEvent(e); } } class wt { constructor(e, i, n) { this.element = e, this.type = 6, this._$AN = void 0, this._$AM = i, this.options = n; } get _$AU() { return this._$AM._$AU; } _$AI(e) { q(this, e); } } const At = Z.litHtmlPolyfillSupport; At?.(ee, te), (Z.litHtmlVersions ?? (Z.litHtmlVersions = [])).push("3.3.1"); const kt = (t, e, i) => { const n = i?.renderBefore ?? e; let s = n._$litPart$; if (s === void 0) { const o = i?.renderBefore ?? null; n._$litPart$ = s = new te(e.insertBefore(Q(), o), o, void 0, i ?? {}); } return s._$AI(t), s; }; /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const X = globalThis; class B extends U { constructor() { super(...arguments), this.renderOptions = { host: this }, this._$Do = void 0; } createRenderRoot() { var i; const e = super.createRenderRoot(); return (i = this.renderOptions).renderBefore ?? (i.renderBefore = e.firstChild), e; } update(e) { const i = this.render(); this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(e), this._$Do = kt(i, this.renderRoot, this.renderOptions); } connectedCallback() { super.connectedCallback(), this._$Do?.setConnected(!0); } disconnectedCallback() { super.disconnectedCallback(), this._$Do?.setConnected(!1); } render() { return j; } } B._$litElement$ = !0, B.finalized = !0, X.litElementHydrateSupport?.({ LitElement: B }); const Ct = X.litElementPolyfillSupport; Ct?.({ LitElement: B }); (X.litElementVersions ?? (X.litElementVersions = [])).push("4.2.1"); /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const Je = (t) => (e, i) => { i !== void 0 ? i.addInitializer((() => { customElements.define(t, e); })) : customElements.define(t, e); }; /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const St = { attribute: !0, type: String, converter: se, reflect: !1, hasChanged: me }, zt = (t = St, e, i) => { const { kind: n, metadata: s } = i; let o = globalThis.litPropertyMetadata.get(s); if (o === void 0 && globalThis.litPropertyMetadata.set(s, o = /* @__PURE__ */ new Map()), n === "setter" && ((t = Object.create(t)).wrapped = !0), o.set(i.name, t), n === "accessor") { const { name: r } = i; return { set(a) { const l = e.get.call(this); e.set.call(this, a), this.requestUpdate(r, l, t); }, init(a) { return a !== void 0 && this.C(r, void 0, t, a), a; } }; } if (n === "setter") { const { name: r } = i; return function(a) { const l = this[r]; e.call(this, a), this.requestUpdate(r, l, t); }; } throw Error("Unsupported decorator location: " + n); }; function ce(t) { return (e, i) => typeof i == "object" ? zt(t, e, i) : ((n, s, o) => { const r = s.hasOwnProperty(o); return s.constructor.createProperty(o, n), r ? Object.getOwnPropertyDescriptor(s, o) : void 0; })(t, e, i); } /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ function ve(t) { return ce({ ...t, state: !0, attribute: !1 }); } var Te, Pe; (function(t) { t.language = "language", t.system = "system", t.comma_decimal = "comma_decimal", t.decimal_comma = "decimal_comma", t.space_comma = "space_comma", t.none = "none"; })(Te || (Te = {})), (function(t) { t.language = "language", t.system = "system", t.am_pm = "12", t.twenty_four = "24"; })(Pe || (Pe = {})); var pe = function(t, e, i, n) { n = n || {}, i = i ?? {}; var s = new Event(e, { bubbles: n.bubbles === void 0 || n.bubbles, cancelable: !!n.cancelable, composed: n.composed === void 0 || n.composed }); return s.detail = i, t.dispatchEvent(s), s; }, Mt = function(t, e, i) { var n; return i === void 0 && (i = !1), function() { var s = [].slice.call(arguments), o = this, r = function() { n = null, i || t.apply(o, s); }, a = i && !n; clearTimeout(n), n = setTimeout(r, e), a && t.apply(o, s); }; }, Vt = function(t, e, i) { i === void 0 && (i = !1), i ? history.replaceState(null, "", e) : history.pushState(null, "", e), pe(window, "location-changed", { replace: i }); }; function Ze(t) { return typeof t == "object" && t !== null && "entity" in t && typeof t.entity == "string"; } function Et(t) { return Array.isArray(t) && t.every((e) => typeof e == "string"); } function Tt(t) { return Array.isArray(t) && t.length === 3 && t.every((e) => typeof e == "number"); } function Pt(t) { return Array.isArray(t) && t.length === 2 && t.every((e) => typeof e == "number"); } function Nt(t) { return typeof t == "string" && (t === "heating" || t === "cooling" || t === "idle" || t === "off"); } function Dt(t) { return Nt(t) ? t : void 0; } function F(t) { if (typeof t == "number" && !Number.isNaN(t)) return t; } function L(t) { if (typeof t == "string") return t; } function Ot(t) { return Et(t) ? t : []; } function It(t) { if (Tt(t)) return t; } function Ht(t) { if (Pt(t)) return t; } function ie(t, e) { return e.includes("*") ? new RegExp(`^${e.replaceAll("*", ".*")}$`).test(t) : t === e; } const Rt = /* @__PURE__ */ new Set(["unavailable", "unknown", "none"]); function Lt(t) { return Rt.has(t.toLowerCase()); } function Ut(t, e) { const i = t / 360, n = e / 100, s = 0.5; let o, r, a; if (n === 0) o = r = a = s; else { const l = (u, f, d) => (d < 0 && (d += 1), d > 1 && (d -= 1), d < 0.16666666666666666 ? u + (f - u) * 6 * d : d < 0.5 ? f : d < 0.6666666666666666 ? u + (f - u) * (0.6666666666666666 - d) * 6 : u), h = s + n - s * n, c = 2 * s - h; o = l(c, h, i + 1 / 3), r = l(c, h, i), a = l(c, h, i - 1 / 3); } return [Math.round(o * 255), Math.round(r * 255), Math.round(a * 255)]; } function ye(t) { if (t.startsWith("#")) { const i = t.replaceAll("#", ""); return [ Number.parseInt(i.slice(0, 2), 16), Number.parseInt(i.slice(2, 4), 16), Number.parseInt(i.slice(4, 6), 16) ]; } const e = /rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(t); return e ? [ Number.parseInt(e[1] ?? "0", 10), Number.parseInt(e[2] ?? "0", 10), Number.parseInt(e[3] ?? "0", 10) ] : null; } function Bt(t, e, i) { return (0.299 * t + 0.587 * e + 0.114 * i) / 255; } function Ft(t) { const e = ye(t); return (e ? Bt(e[0], e[1], e[2]) > 0.5 : !1) ? { icon: "rgba(0, 0, 0, 0.7)", label: "rgba(0, 0, 0, 0.9)", value: "rgba(0, 0, 0, 0.7)" } : { icon: "rgba(255, 255, 255, 0.85)", label: "rgba(255, 255, 255, 0.95)", value: "rgba(255, 255, 255, 0.85)" }; } function S(t, e, i, n) { const s = t.replaceAll("#", ""), o = e.replaceAll("#", ""), r = Number.parseInt(s.slice(0, 2), 16), a = Number.parseInt(s.slice(2, 4), 16), l = Number.parseInt(s.slice(4, 6), 16), h = Number.parseInt(o.slice(0, 2), 16), c = Number.parseInt(o.slice(2, 4), 16), u = Number.parseInt(o.slice(4, 6), 16), f = Math.round(r + (h - r) * i), d = Math.round(a + (c - a) * i), p = Math.round(l + (u - l) * i); return n !== void 0 ? `rgba(${f}, ${d}, ${p}, ${n})` : `rgb(${f}, ${d}, ${p})`; } function jt(t) { const { clampedValue: e, minValue: i, maxValue: n, midPoint: s, colorLow: o, colorMid: r, colorHigh: a, opacity: l } = t; if (e <= s) { if (i >= s) return S(r, r, 1, l); const h = (e - i) / (s - i); return S(o, r, h, l); } else { if (n <= s) return S(r, r, 1, l); const h = (e - s) / (n - s); return S(r, a, h, l); } } function qt(t) { const { clampedValue: e, minValue: i, maxValue: n, neutral: s, colorLow: o, colorHigh: r, opacity: a } = t; if (e <= s) { if (i >= s) return S(o, r, 0.5, a); const l = (e - i) / (s - i); return S(o, r, l * 0.5, a); } else { if (n <= s) return S(o, r, 0.5, a); const l = (e - s) / (n - s); return S(o, r, 0.5 + l * 0.5, a); } } function Wt(t, e, i, n) { const { colorHigh: s, colorLow: o, colorMid: r, opacity: a } = n, l = n.scaleMin ?? e, h = n.scaleMax ?? i, c = n.neutral, u = Math.max(l, Math.min(h, t)), f = c ?? (l + h) / 2; if (r) return jt({ clampedValue: u, minValue: l, maxValue: h, midPoint: f, colorLow: o, colorMid: r, colorHigh: s, opacity: a }); if (c !== void 0) return qt({ clampedValue: u, minValue: l, maxValue: h, neutral: c, colorLow: o, colorHigh: s, opacity: a }); if (h === l) return S(s, s, 1, a); const d = (u - l) / (h - l); return S(o, s, d, a); } function G(t, e) { const i = ye(t); return i ? `rgba(${i[0]}, ${i[1]}, ${i[2]}, ${e})` : t; } function Gt(t) { return t.startsWith("light."); } function Yt({ attributes: t, state: e }) { const i = e === "on", n = F(t.brightness), s = i ? Math.round((n ?? 255) / 255 * 100) : 0, r = Ot(t.supported_color_modes).some( (l) => ["rgb", "rgbw", "rgbww", "hs", "xy"].includes(l) ), a = { brightness: s, isOn: i, supportsColor: r }; if (i && r) { const l = It(t.rgb_color), h = Ht(t.hs_color); l ? a.rgb = l : h && (a.hs = h); } return a; } function Jt(t, e, i) { if (!t || !t.isOn) return e; const n = 0.3 + t.brightness / 100 * 0.7; if (t.supportsColor && t.rgb) { const [o, r, a] = t.rgb; return `rgba(${o}, ${r}, ${a}, ${n})`; } if (t.supportsColor && t.hs) { const [o, r] = t.hs, [a, l, h] = Ut(o, r); return `rgba(${a}, ${l}, ${h}, ${n})`; } const s = ye(i); return s ? `rgba(${s[0]}, ${s[1]}, ${s[2]}, ${n})` : i; } const Zt = ["switch", "input_boolean", "binary_sensor"]; function Xt(t) { const e = t.split(".")[0]; return Zt.includes(e ?? ""); } function Qt({ state: t }) { return { isOn: t === "on" }; } function Kt(t, e, i) { return t ? i : e; } function ei(t) { return t.startsWith("climate."); } function ti({ attributes: t, state: e }) { const i = F(t.current_temperature), n = F(t.temperature), s = Dt(t.hvac_action), o = e, r = i ?? null, a = n ?? null; let l = 0, h = 0; if (r !== null && a !== null) { const c = r - a; o === "heat" ? h = Math.min(c, 0) : o === "cool" ? h = Math.max(c, 0) : h = c, l = Math.abs(h); } return { currentTemperature: r, targetTemperature: a, tempDifference: l, tempOffset: h, hvacAction: s ?? null, hvacMode: o ?? null }; } function fe(t, e) { return e === "temp_difference" ? t.tempDifference : e === "temp_offset" ? t.tempOffset : e === "current_temperature" ? t.currentTemperature : e === "temperature" ? t.targetTemperature : e === "hvac_action" ? t.hvacAction : e === "hvac_mode" ? t.hvacMode : null; } function ii(t, e = {}, i = 0) { const { width: n = 100, height: s = 20 } = e, o = 1, r = s - i, a = e.min ?? Math.min(...t), h = (e.max ?? Math.max(...t)) - a || 1, c = t.map((f, d) => { const p = d / (t.length - 1) * n, $ = r - o - (f - a) / h * (r - o * 2); return `${p.toFixed(1)},${$.toFixed(1)}`; }).join(" "), u = `0,${r} ${c} ${n},${r}`; return { linePoints: c, fillPoints: u }; } function ni(t) { return t === "light" ? { line: "rgba(255, 255, 255, 0.25)", fillTop: "rgba(255, 255, 255, 0.25)", fillBottom: "rgba(255, 255, 255, 0.12)" } : { line: "rgba(0, 0, 0, 0.15)", fillTop: "rgba(0, 0, 0, 0.2)", fillBottom: "rgba(0, 0, 0, 0.1)" }; } let oi = 0; function si(t) { return t === "light" ? { heating: "rgba(255, 255, 255, 0.4)", cooling: "rgba(255, 255, 255, 0.4)" } : { heating: "rgba(0, 0, 0, 0.35)", cooling: "rgba(0, 0, 0, 0.35)" }; } function ri(t, e) { const n = e * 4, s = Array.from({ length: n }, () => null); for (const o of t) { if (o.action !== "heating" && o.action !== "cooling") continue; const r = Math.floor(o.start * n), a = Math.ceil(o.end * n); for (let l = r; l < a && l < n; l++) l >= 0 && (o.action === "heating" || s[l] !== "heating") && (s[l] = o.action); } return s; } function ai(t) { const { segments: e, data: i, width: n, height: s, colors: o, periodHours: r } = t; if (i.length < 2) return D``; const a = ri(e, r), l = a.length, h = t.min ?? Math.min(...i), u = (t.max ?? Math.max(...i)) - h || 1, f = 1, d = (m) => s - f - (m - h) / u * (s - f * 2), p = (m) => { const g = m * (i.length - 1), b = Math.floor(g), w = Math.min(Math.ceil(g), i.length - 1), A = g - b; return (i[b] ?? 0) * (1 - A) + (i[w] ?? 0) * A; }, $ = []; let v = null; for (let m = 0; m < l; m++) { const g = a[m]; g ? v !== null && v.action === g ? v.end = (m + 1) / l : (v && $.push(v), v = { start: m / l, end: (m + 1) / l, action: g }) : v && ($.push(v), v = null); } return v && $.push(v), D` ${$.map((m) => { const g = m.action === "heating" ? o.heating : o.cooling, b = 10, w = (m.end - m.start) / b; let A = `${(m.start * n).toFixed(1)},${s}`; for (let k = 0; k <= b; k++) { const C = m.start + k * w, y = C * n, z = d(p(C)); A += ` ${y.toFixed(1)},${z.toFixed(1)}`; } return A += ` ${(m.end * n).toFixed(1)},${s}`, D``; })} `; } function Ne(t, e = {}, i) { const { width: n = 100, height: s = 20, mode: o = "dark", line: r, fill: a, hvac: l, periodHours: h = 24 } = e, c = t.length > 1, u = l?.show !== !1 && i && i.length > 0, { linePoints: f, fillPoints: d } = c ? ii(t, e, 0) : { linePoints: "", fillPoints: "" }, p = ni(o), $ = si(o), v = a?.show !== !1 && c, m = r?.show !== !1 && c, g = `sparkline-gradient-${oi++}`, b = !!a?.style, w = a?.style || `fill: url(#${g});`, A = `stroke: ${p.line}; stroke-width: 1.5;`, k = r?.style ? `${A} ${r.style}` : A; return D` ${v && !b ? D` ` : _} ${u && c ? ai({ segments: i, data: t, width: n, height: s, colors: $, periodHours: h, min: e.min, max: e.max }) : _} ${v && !i ? D`` : _} ${m ? D`` : _} `; } function li(t, e = {}) { if (t && typeof t == "object" && "temperature" in t) { const i = t, n = i.temperature && i.temperature.length > 1, s = i.hvacActions && i.hvacActions.length > 0; return n || s ? Ne( n ? i.temperature : [], e, i.hvacActions ) : _; } return Array.isArray(t) && t.length > 1 ? Ne(t, e) : _; } function ci(t) { return t === "heating" || t === "cooling" || t === "idle" || t === "off"; } const Xe = { "12h": { hours: 12, statsPeriod: "5minute" }, "24h": { hours: 24, statsPeriod: "hour" }, "7d": { hours: 168, statsPeriod: "hour" }, "30d": { hours: 720, statsPeriod: "day" } }, De = /* @__PURE__ */ new Map(), hi = 300 * 1e3; async function ui(t, e, i = "24h") { const n = /* @__PURE__ */ new Map(), s = Date.now(), o = []; for (const r of e) { const a = `${r}:${i}`, l = De.get(a); l && s - l.fetchedAt < hi ? n.set(r, l.data) : o.push(r); } if (o.length > 0) { const r = await di(t, o, i); for (const [a, l] of r) { const h = `${a}:${i}`; De.set(h, { data: l, fetchedAt: s }), n.set(a, l); } } return n; } async function di(t, e, i) { const n = /* @__PURE__ */ new Map(); if (e.length === 0) return n; const s = e.filter((r) => r.startsWith("climate.")), o = e.filter((r) => !r.startsWith("climate.")); if (o.length > 0) { const r = await Qe(t, o, i); for (const [a, l] of r) n.set(a, { temperature: l }); } if (s.length > 0) { const r = await fi(t, s, i); for (const [a, l] of r) n.set(a, l); } return n; } async function fi(t, e, i) { const n = /* @__PURE__ */ new Map(), s = Xe[i], o = new Date(Date.now() - s.hours * 60 * 60 * 1e3), r = await Qe(t, e, i), a = []; for (const h of e) { const c = r.get(h); !c || c.length === 0 ? a.push(h) : n.set(h, { temperature: c }); } const l = await pi(t, e, o, s); for (const h of a) { const c = l.get(h); c && c.temperature.length > 0 && n.set(h, { temperature: c.temperature }); } for (const [h, c] of l) { const u = n.get(h); u ? u.hvacActions = c.hvacActions : n.set(h, { temperature: [], hvacActions: c.hvacActions }); } return n; } async function pi(t, e, i, n) { const s = /* @__PURE__ */ new Map(); if (e.length === 0) return s; try { const o = await t.callWS({ type: "history/history_during_period", start_time: i.toISOString(), entity_ids: e, no_attributes: !1, significant_changes_only: !1 // Get all changes for better temperature resolution }); if (o) { const r = n.hours * 60 * 60 * 1e3, a = Date.now(); for (const l of e) { const h = o[l]; if (h && h.length > 0) { const c = gi(h), u = _i(h, i.getTime(), a, r); s.set(l, { temperature: c, hvacActions: u }); } } } } catch (o) { console.warn("[treemap] Failed to fetch climate history:", o); } return s; } function gi(t) { const e = [], n = Math.max(1, Math.floor(t.length / 60)); for (let s = 0; s < t.length; s += n) { const o = t[s]; if (!o) continue; const a = (o.attributes || o.a)?.current_temperature; typeof a == "number" && !Number.isNaN(a) && e.push(a); } return e; } function _i(t, e, i, n) { const s = []; for (let o = 0; o < t.length; o++) { const r = t[o]; if (!r) continue; const a = t[o + 1], h = (r.attributes || r.a)?.hvac_action; if (!ci(h) || h === "idle" || h === "off") continue; const c = h, u = r.last_updated ? new Date(r.last_updated).getTime() : new Date((r.lu ?? 0) * 1e3).getTime(); let f; a ? f = a.last_updated ? new Date(a.last_updated).getTime() : new Date((a.lu ?? 0) * 1e3).getTime() : f = i; const d = Math.max(0, (u - e) / n), p = Math.min(1, (f - e) / n); d < 1 && p > 0 && s.push({ start: d, end: p, action: c }); } return s; } async function Qe(t, e, i) { const n = /* @__PURE__ */ new Map(); if (e.length === 0) return n; const s = Xe[i], o = new Date(Date.now() - s.hours * 60 * 60 * 1e3).toISOString(); try { const r = await t.callWS({ type: "recorder/statistics_during_period", start_time: o, statistic_ids: e, period: s.statsPeriod }); if (r) for (const [a, l] of Object.entries(r)) { const h = l.map(({ mean: c }) => c).filter((c) => c != null); n.set(a, h); } } catch (r) { console.warn("[treemap] Failed to fetch statistics:", r); for (const a of e) n.has(a) || n.set(a, []); } return n; } function Oe(t, e) { if (t.length === 0) return 1 / 0; const i = t.reduce((a, l) => a + l, 0), n = Math.max(...t), s = Math.min(...t), o = e * e, r = i * i; return Math.max(o * n / r, r / (o * s)); } function mi(t, e, i) { const n = t.reduce((r, a) => r + a.normalizedValue, 0), s = []; let o = 0; if (i) { const r = n / e.height; for (const a of t) { const l = a.normalizedValue / r; s.push({ label: a.item.label, value: a.item.value, sizeValue: a.item.sizeValue, sortValue: a.item.sortValue, colorValue: a.item.colorValue, entity_id: a.item.entity_id, icon: a.item.icon, light: a.item.light, climate: a.item.climate, binary: a.item.binary, color: a.item.color, sparklineData: a.item.sparklineData, unavailable: a.item.unavailable, rawState: a.item.rawState, x: e.x, y: e.y + o, width: r, height: l }), o += l; } return { rects: s, remaining: { x: e.x + r, y: e.y, width: e.width - r, height: e.height } }; } else { const r = n / e.width; for (const a of t) { const l = a.normalizedValue / r; s.push({ label: a.item.label, value: a.item.value, sizeValue: a.item.sizeValue, sortValue: a.item.sortValue, colorValue: a.item.colorValue, entity_id: a.item.entity_id, icon: a.item.icon, light: a.item.light, climate: a.item.climate, binary: a.item.binary, color: a.item.color, sparklineData: a.item.sparklineData, unavailable: a.item.unavailable, rawState: a.item.rawState, x: e.x + o, y: e.y, width: l, height: r }), o += l; } return { rects: s, remaining: { x: e.x, y: e.y + r, width: e.width, height: e.height - r } }; } } function bi(t, e, i) { return e === "default" ? [...t] : [...t].sort((n, s) => { let o; if (e === "entity_id") { const r = n.entity_id ?? "", a = s.entity_id ?? ""; o = r.localeCompare(a); } else e === "label" ? o = n.label.localeCompare(s.label) : o = n.sortValue - s.sortValue; return i ? o : -o; }); } function Ie(t, e, i, n = !1, s = "value") { const o = t.length; if (o === 0) return { rects: [], rows: 0 }; const r = e / i; let a = Math.ceil(Math.sqrt(o * r)), l = Math.ceil(o / a); for (; a * (l - 1) >= o && l > 1; ) l--; for (; (a - 1) * l >= o && a > 1; ) a--; const h = e / a, c = i / l; return { rects: bi(t, s, n).map((d, p) => ({ label: d.label, value: d.value, sizeValue: d.sizeValue, sortValue: d.sortValue, colorValue: d.colorValue, entity_id: d.entity_id, icon: d.icon, light: d.light, climate: d.climate, binary: d.binary, color: d.color, sparklineData: d.sparklineData, unavailable: d.unavailable, rawState: d.rawState, x: p % a * h, y: Math.floor(p / a) * c, width: h, height: c })), rows: l }; } function vi(t, e, i, n) { const s = t.map((c) => Math.abs(c.value)), o = Math.max(...s), r = e ? s.map((c) => Math.sqrt(c / o) * o) : s, a = r.reduce((c, u) => c + u, 0), l = []; for (const [c, u] of t.entries()) { const f = s[c], d = r[c]; f !== void 0 && d !== void 0 && d > 0 && u && l.push({ item: u, absValue: f, sizeValue: d }); } const h = l.map(({ item: c, sizeValue: u }) => ({ item: c, normalizedValue: u / a * i })); return n === "default" || (n === "entity_id" ? h.sort((c, u) => { const f = c.item.entity_id ?? "", d = u.item.entity_id ?? ""; return f.localeCompare(d); }) : n === "label" ? h.sort((c, u) => c.item.label.localeCompare(u.item.label)) : h.sort((c, u) => u.normalizedValue - c.normalizedValue)), h; } function yi(t, e) { const i = []; let n = [], s = [...t]; for (; s.length > 0; ) { const o = s[0]; if (!o) break; const r = [...n, o.normalizedValue], a = Oe(n, e), l = Oe(r, e), h = s.length <= 3 && n.length > 0; if (n.length > 0 && l > a && !h) break; i.push(o), n = r, s = s.slice(1); } return { row: i, rowValues: n, newRemaining: s }; } function $i(t, e, i) { for (const o of t) o.x = e - o.x - o.width, o.y = i - o.y - o.height; const n = Math.min(...t.map((o) => o.x)), s = Math.min(...t.map((o) => o.y)); if (n !== 0 || s !== 0) for (const o of t) o.x -= n, o.y -= s; } function xi(t, e, i, n = {}) { const { compressRange: s = !0, equalSize: o = !1, ascending: r = !1, sortBy: a = "value" } = n; if (t.length === 0) return { rects: [], rows: 0 }; if (o) return Ie(t, e, i, r, a); const l = t.map((g) => Math.abs(g.value)), h = Math.max(...l); if (h === 0) return { rects: [], rows: 0 }; const c = l.filter((g) => g > 0); if (c.length > 1) { const g = Math.min(...c); if ((h - g) / h < 0.01) return Ie(t, e, i, r, a); } const u = e * i, f = vi(t, s, u, a), d = []; let p = { x: 0, y: 0, width: e, height: i }, $ = [...f]; for (; $.length > 0; ) { const g = p.width < p.height, b = g ? p.height : p.width, { row: w, newRemaining: A } = yi($, b); $ = A; const { rects: k, remaining: C } = mi(w, p, g); if (d.push(...k), p = C, p.width <= 0 || p.height <= 0) break; } r && d.length > 0 && $i(d, e, i); const m = new Set(d.map((g) => Math.round(g.y * 100) / 100)).size; return { rects: d, rows: m }; } function wi(t) { let e = Number.POSITIVE_INFINITY, i = Number.NEGATIVE_INFINITY, n = Number.POSITIVE_INFINITY, s = Number.NEGATIVE_INFINITY; for (const o of t) o.colorValue < e && (e = o.colorValue), o.colorValue > i && (i = o.colorValue), o.sizeValue < n && (n = o.sizeValue), o.sizeValue > s && (s = o.sizeValue); return { colorMin: e, colorMax: i, sizeMin: n, sizeMax: s }; } function Ai(t, e, i) { const n = i + e; for (const r of t) r.sizeValue = n - r.sizeValue, r.sortValue = -r.sortValue; const s = n - e, o = s * 0.1; for (const r of t) r.sizeValue < o && (r.sizeValue = o); return s; } function He(t, e, i) { const n = e ? !i : i; return [...t].sort( (s, o) => n ? s.sizeValue - o.sizeValue : o.sizeValue - s.sizeValue ); } function ki(t, e) { let i = 1; for (const n of t) e !== void 0 && n.sizeValue > e && (n.sizeValue = e), n.sizeValue > i && (i = n.sizeValue); return i; } function Ci(t, e, i) { const n = e ?? i * 0.15; for (const s of t) s.sizeValue < n && (s.sizeValue = n); } function Si(t, e = {}) { const { inverse: i = !1, ascending: n = !1, limit: s, sizeMin: o, sizeMax: r, sortBy: a } = e; if (t.length === 0) return { items: [], colorMin: 0, colorMax: 0 }; const l = wi(t); if (l.sizeMin < 0) { const f = Math.abs(l.sizeMin); for (const d of t) d.sizeValue = d.sizeValue + f; l.sizeMin = 0, l.sizeMax = l.sizeMax + f; } i && Ai(t, l.sizeMin, l.sizeMax); const h = !a || a === "value"; let c; if (h) { const f = He(t, i, n); c = s !== void 0 && s > 0 ? f.slice(0, s) : f; } else if (s !== void 0 && s > 0) { const f = He(t, i, n), d = new Set(f.slice(0, s).map((p) => p.entity_id ?? p.label)); c = t.filter((p) => d.has(p.entity_id ?? p.label)); } else c = [...t]; const u = ki(c, r); return Ci(c, o, u), { items: c, colorMin: l.colorMin, colorMax: l.colorMax }; } const zi = [ { threshold: 1e12, suffix: "T" }, { threshold: 1e9, suffix: "B" }, { threshold: 1e6, suffix: "M" }, { threshold: 1e3, suffix: "k" } ]; function Mi(t, e = 1, i = !1) { let n = t, s = ""; if (i) { for (const o of zi) if (Math.abs(t) >= o.threshold) { n = t / o.threshold, s = o.suffix; break; } } return n.toFixed(e) + s; } function Vi(t, e) { return t !== void 0 ? t : e !== void 0 ? e : 1; } const Ei = Fe` :host { display: block; } ha-card { height: 100%; display: flex; flex-direction: column; } .treemap-header { padding: 8px 16px 0px; font-size: 16px; font-weight: 500; color: var(--primary-text-color); } .card-content { flex: 1; padding: 16px; } .treemap-container { position: relative; width: 100%; border-radius: 8px; overflow: hidden; } .treemap-item { position: absolute; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 8px; overflow: hidden; cursor: pointer; transition: filter 0.2s ease; border-radius: 8px; } .treemap-item:hover { filter: brightness(1.1); } .treemap-icon { --mdc-icon-size: 28px; opacity: 0.85; } /* Pulsing animation for active HVAC states (heating/cooling) */ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .treemap-icon.hvac-active { animation: pulse 2s ease-in-out infinite; } .treemap-label { font-size: 14px; font-weight: 600; color: white; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; opacity: 0.9; } .treemap-value { font-size: 14px; font-weight: 500; color: rgba(255, 255, 255, 0.85); opacity: 0.85; } .treemap-item.small .treemap-icon { --mdc-icon-size: 20px; } .treemap-item.small .treemap-label { font-size: 9px; } .treemap-item.small .treemap-value { font-size: 12px; } .treemap-item.tiny .treemap-icon { --mdc-icon-size: 16px; } .treemap-item.tiny .treemap-label { font-size: 8px; } .treemap-item.tiny .treemap-value { display: none; } .error { color: var(--error-color, #db4437); padding: 16px; } .empty { color: var(--secondary-text-color, #727272); padding: 16px; text-align: center; } /* Sparkline styles */ .treemap-sparkline { position: absolute; bottom: 0; left: 0; right: 0; height: 20px; pointer-events: none; } .treemap-sparkline svg { width: 100%; height: 100%; } .treemap-item.small .treemap-sparkline { height: 14px; } .treemap-item.tiny .treemap-sparkline { display: none; } `; var Ti = Object.defineProperty, Pi = Object.getOwnPropertyDescriptor, he = (t, e, i, n) => { for (var s = n > 1 ? void 0 : n ? Pi(e, i) : e, o = t.length - 1, r; o >= 0; o--) (r = t[o]) && (s = (n ? r(e, i, s) : r(s)) || s); return n && s && Ti(e, i, s), s; }; const Ni = "0.15.2"; console.info( `%c TREEMAP-CARD %c v${Ni}`, "color: white; background: #3498db; font-weight: bold;", "color: #3498db; background: white; font-weight: bold;" ); let T = class extends B { constructor() { super(...arguments), this._sparklineData = /* @__PURE__ */ new Map(), this._fetchingSparklines = !1, this._debouncedFetchSparklines = Mt(() => void this._fetchSparklineData(), 100), this._entityConfigMap = /* @__PURE__ */ new Map(), this._holdTimer = null, this._holdFired = !1; } /** * Return the editor element for visual configuration */ static getConfigElement() { return Promise.resolve().then(() => rn), document.createElement("treemap-card-editor"); } /** * Return stub config for card picker (finds temperature sensors for preview) */ static getStubConfig(t) { const e = Object.keys(t.states).filter((i) => i.startsWith("sensor.") ? t.states[i]?.attributes?.device_class === "temperature" : !1).slice(0, 3); return { type: "custom:treemap-card", entities: e.length > 0 ? e : ["sensor.*"] }; } /** * Optimize re-renders: only update when relevant entity states change */ shouldUpdate(t) { if (t.has("_config") || t.has("_sparklineData")) return !0; if (t.has("hass") && this.hass && this._config) { const e = this._getRelevantStatesHash(); return e !== this._lastRelevantStates ? (this._lastRelevantStates = e, !0) : !1; } return !0; } /** * Get a hash of relevant entity states for change detection */ _getRelevantStatesHash() { if (!this.hass) return ""; const t = this._getConfiguredEntityIds(), e = []; for (const i of t) { const n = this.hass.states[i]; n && e.push(`${i}:${n.state}:${n.last_updated}`); } return e.join("|"); } /** * Get entity IDs from config (supports wildcards) */ _getConfiguredEntityIds() { if (!this.hass || !this._config) return []; if (this._config.entity) return [this._config.entity]; if (this._config.entities) { const t = Object.keys(this.hass.states), e = []; for (const i of this._config.entities) { const { entity: n } = this._normalizeEntity(i); if (n.includes("*")) for (const s of t) ie(s, n) && e.push(s); else e.push(n); } return e; } return []; } setConfig(t) { if (!t.entities && !t.entity) throw new Error('Please define "entities" (list) or "entity" (single with JSON array)'); if (this._config = { gap: 4, // smaller gap ...t }, this._entityConfigMap = /* @__PURE__ */ new Map(), t.entities) for (const e of t.entities) { const i = this._normalizeEntity(e); (i.tap_action || i.hold_action || i.double_tap_action) && this._entityConfigMap.set(i.entity, i); } } /** * Normalize EntityInput to object format * Converts "sensor.foo" to { entity: "sensor.foo" } * Preserves existing { entity, name, icon } objects as-is */ _normalizeEntity(t) { return typeof t == "string" ? { entity: t } : Ze(t) ? t : { entity: String(t) }; } getCardSize() { return 4; } updated() { this._debouncedFetchSparklines(); } async _fetchSparklineData() { if (!this.hass || this._fetchingSparklines || this._config?.sparkline?.show === !1) return; const e = this._resolveData().map(({ entity_id: i }) => i).filter((i) => !!i); if (e.length !== 0) { this._fetchingSparklines = !0; try { const i = this._config?.sparkline?.period || "24h", n = await ui(this.hass, e, i); n.size > 0 && !this._sparklineDataEquals(n) && (this._sparklineData = n); } finally { this._fetchingSparklines = !1; } } } /** * Compare sparkline data maps to avoid unnecessary re-renders. */ _sparklineDataEquals(t) { if (this._sparklineData.size !== t.size) return !1; for (const [e, i] of t) { const n = this._sparklineData.get(e); if (!n || n.temperature.length !== i.temperature.length) return !1; const s = n.hvacActions?.length ?? 0, o = i.hvacActions?.length ?? 0; if (s !== o) return !1; } return !0; } /** * Get period hours from config for HVAC quantization. */ _getPeriodHours() { const t = this._config?.sparkline?.period || "24h"; return { "12h": 12, "24h": 24, "7d": 168, "30d": 720 }[t] ?? 24; } _resolveData() { if (!this.hass || !this._config) return []; const t = this._lastRelevantStates; if (this._cachedData && this._cachedDataHash === t) return this._cachedData; let e; return this._config.entities ? e = this._resolveEntities(this._config.entities) : this._config.entity ? e = this._resolveJsonEntity(this._config.entity) : e = [], this._cachedData = e, this._cachedDataHash = t, e; } _isExcluded(t) { const e = this._config?.exclude; if (!e || e.length === 0) return !1; for (const i of e) if (ie(t, i)) return !0; return !1; } _resolveEntities(t) { if (!this.hass) return []; const e = [], i = Object.keys(this.hass.states); for (const n of t) { const { entity: s, name: o, icon: r, color: a } = this._normalizeEntity(n), l = i.filter( (h) => ie(h, s) && !this._isExcluded(h) ); for (const h of l) { const c = this.hass.states[h]; if (!c) continue; const u = this._config?.label?.attribute || "friendly_name", f = u === "entity_id" ? h : String(c.attributes[u] ?? h.split(".").pop() ?? h), d = o ?? f, p = r ?? L(c.attributes.icon); if (Gt(h)) { const g = Yt(c), { brightness: b } = g; let w; g.isOn ? w = 40 + b / 100 * 60 : w = 10, e.push({ label: d, value: b, // Display brightness as percentage sizeValue: w, sortValue: b, colorValue: b, entity_id: h, icon: p ?? "mdi:lightbulb", unit: "%", light: g, color: a }); continue; } if (ei(h)) { const g = ti(c), b = this._config?.value?.attribute || "current_temperature", w = this._config?.size?.attribute || b, A = this._config?.color?.attribute || b; let k = fe(g, b), C = fe(g, w), y = fe(g, A); k === null && (k = F(c.attributes[b]) ?? 0), C === null && (C = F(c.attributes[w]) ?? 0), y === null && (y = F(c.attributes[A]) ?? 0); const z = typeof k == "number" ? k : 0, M = typeof C == "number" ? Math.max(0.1, Math.abs(C)) : 0.1, st = typeof y == "number" ? y : 0; let R; if (p) R = p; else switch (g.hvacAction) { case "heating": { R = "mdi:fire"; break; } case "cooling": { R = "mdi:snowflake"; break; } case "off": { R = "mdi:thermostat-off"; break; } default: R = "mdi:thermostat"; } e.push({ label: d, value: z, sizeValue: M, sortValue: z, colorValue: st, entity_id: h, icon: R, unit: L(c.attributes.unit_of_measurement), climate: g, color: a }); continue; } if (Xt(h)) { const g = Qt(c), { isOn: b } = g; e.push({ label: d, value: b ? 1 : 0, sizeValue: 1, // Equal size for all binary entities sortValue: b ? 1 : 0, colorValue: b ? 1 : 0, entity_id: h, icon: p, binary: g, color: a }); continue; } const $ = this._config?.value?.attribute || "state"; let v; if ($ === "state") v = Number.parseFloat(c.state); else { const g = c.attributes[$]; v = Number.parseFloat(String(g ?? 0)); } if (Number.isNaN(v)) { if (!Lt(c.state) || !this._config?.filter?.unavailable) continue; const b = L(c.attributes.unit_of_measurement); e.push({ label: d, value: 0, // Placeholder value for sizing sizeValue: 1, // Minimal size sortValue: 0, colorValue: 0, entity_id: h, icon: p, unit: b, unavailable: !0, rawState: c.state, color: a }); continue; } const m = L(c.attributes.unit_of_measurement); e.push({ label: d, value: v, sizeValue: v, sortValue: v, colorValue: v, entity_id: h, icon: p, unit: m, color: a }); } } return e; } _resolveJsonEntity(t) { if (!this.hass) return []; const e = this.hass.states[t]; if (!e) return []; const i = this._config?.data_attribute || "items", n = e.attributes[i]; if (!Array.isArray(n)) return []; const s = this._config?.label?.attribute ?? this._config?.label?.param ?? "label", o = this._config?.value?.attribute ?? this._config?.value?.param ?? "value", r = this._config?.size?.attribute ?? this._config?.size?.param ?? o, a = this._config?.color?.attribute ?? this._config?.color?.param ?? o, l = this._config?.icon?.attribute ?? this._config?.icon?.param ?? "icon", h = this._config?.sparkline?.attribute; return n.filter((c) => typeof c == "object" && c !== null).map((c) => { let u; if (h) { const d = c[h]; Array.isArray(d) && (u = d.filter((p) => typeof p == "number")); } const f = Number(c[o] ?? 0); return { label: String(c[s] ?? c.label ?? ""), value: f, sizeValue: Number(c[r] ?? c[o] ?? 0), sortValue: f, colorValue: Number(c[a] ?? c[o] ?? 0), icon: L(c[l]), entity_id: L(c.entity_id), sparklineData: u }; }).filter((c) => c.label && !Number.isNaN(c.value)); } _getGradientColorOptions() { return { colorHigh: this._config?.color?.high || "#16a34a", colorLow: this._config?.color?.low || "#b91c1c", colorMid: this._config?.color?.mid, scaleMin: this._config?.color?.scale?.min, scaleMax: this._config?.color?.scale?.max, neutral: this._config?.color?.scale?.neutral, opacity: this._config?.color?.opacity }; } _getColor(t, e, i) { return Wt(t, e, i, this._getGradientColorOptions()); } _getSizeClass(t) { const e = t.width * t.height; return e < 50 ? "tiny" : e < 150 ? "small" : ""; } _getLightColor(t) { const e = this._config?.color?.low ?? "#333333", i = this._config?.color?.high ?? "#fbbf24"; return Jt(t.light, e, i); } _filterData(t) { if (!this._config) return t; const e = this._config.filter?.above, i = this._config.filter?.below; return t.filter((n) => n.unavailable ? !0 : !(e !== void 0 && n.value <= e || i !== void 0 && n.value >= i)); } render() { if (!this._config) return x`
No configuration
`; const t = this._resolveData(), e = this._filterData(t), i = !!this._config.header?.title, n = this._config.header?.title, s = this._config.header?.show ?? !!n, o = this._config.header?.style || "", r = this._config.card_style || "", a = i ? void 0 : this._config.title; if (e.length === 0) return x` ${s && n ? x`
${n}
` : _}
No data available
`; const { items: l, colorMin: h, colorMax: c } = Si(e, { inverse: this._config?.size?.inverse, ascending: this._config?.order === "asc", limit: this._config?.limit, sizeMin: this._config?.size?.min, sizeMax: this._config?.size?.max, sortBy: this._config?.sort_by ?? "value" }), u = this._config?.size?.equal === !0, f = /* @__PURE__ */ new Map(); for (const y of l) { const z = y.entity_id ?? y.label; f.set(z, { value: y.value, sortValue: y.sortValue, colorValue: y.colorValue, sizeValue: y.sizeValue, unit: y.unit }); } const d = l.map((y) => ({ ...y, value: y.sizeValue })), p = this._config?.order === "asc", v = this._config?.size?.inverse === !0 ? !p : p, m = this._config?.sort_by ?? "value", { rects: g, rows: b } = xi(d, 100, 100, { compressRange: !0, equalSize: u, ascending: v, sortBy: m }); for (const y of g) { const z = y.entity_id ?? y.label, M = f.get(z); M && (y.value = M.value, y.sortValue = M.sortValue, y.colorValue = M.colorValue, y.sizeValue = M.sizeValue, y.unit = M.unit); } const w = Math.max(1, b), A = Math.max(100, w * 100), k = this._config.height ?? A, C = this._config.gap ?? 6; return x` ${s && n ? x`
${n}
` : _}
${g.map((y) => this._renderRect(y, h, c, k, C))}
`; } /** * Determine color for a treemap rect based on entity type and state. * Priority: unavailable > climate off > climate HVAC active > light > gradient */ _getRectColor(t, e, i) { const n = this._config?.color?.opacity; if (t.color) return n === void 0 ? t.color : G(t.color, n); if (t.unavailable) { const s = this._config?.color?.unavailable ?? "#868e96"; return n === void 0 ? s : G(s, n); } if (t.climate && (t.climate.hvacMode === "off" || t.climate.hvacMode === "unavailable")) { const s = this._config?.color?.hvac?.off ?? "#868e96"; return n === void 0 ? s : G(s, n); } if (t.climate && this._config?.color?.hvac) { const s = this._config.color.hvac; if (t.climate.hvacAction === "heating" && s.heating) return n === void 0 ? s.heating : G(s.heating, n); if (t.climate.hvacAction === "cooling" && s.cooling) return n === void 0 ? s.cooling : G(s.cooling, n); } if (t.light) return this._getLightColor(t); if (t.binary) { const s = this._config?.color?.low ?? "#333333", o = this._config?.color?.high ?? "#22c55e"; return Kt(t.binary.isOn, s, o); } return this._getColor(t.colorValue, e, i); } /** * Format label with replace regex and prefix/suffix. */ _formatLabel(t) { let e = t.label; const i = this._config?.label?.replace; if (i) { const o = i.split("/"), r = o[0], a = o[1]; if (o.length >= 2 && r !== void 0 && a !== void 0) try { const l = new RegExp(r, o[2] ?? ""); e = t.label.replace(l, a); } catch { } } const n = this._config?.label?.prefix || "", s = this._config?.label?.suffix || ""; return `${n}${e}${s}`; } /** * Format value with precision, abbreviation, prefix/suffix, and unit. */ _formatValue(t) { const e = this._config?.value?.prefix, i = this._config?.value?.suffix; if (t.unavailable && t.rawState) return t.rawState.charAt(0).toUpperCase() + t.rawState.slice(1); if (t.binary) return t.binary.isOn ? "On" : "Off"; const n = t.entity_id ? this.hass?.entities?.[t.entity_id]?.display_precision : void 0, s = Vi(this._config?.value?.precision, n), o = this._config?.value?.abbreviate ?? !1, r = Mi(t.value, s, o), l = this._config?.value?.attribute === "temp_offset" && t.value > 0 ? "+" : "", h = e !== void 0 || i !== void 0, c = t.unit ? " " + t.unit : ""; return h ? `${e ?? ""}${l}${r}${i ?? ""}` : `${l}${r}${c}`; } /** * Calculate styles for icon, label, and value based on color target mode. */ _calculateStyles(t) { const i = (this._config?.color?.target ?? "background") === "foreground", n = i ? "rgba(0, 0, 0, 0.1)" : t, s = i ? { icon: t, label: t, value: t } : Ft(t), o = this._config?.icon?.style || `color: ${s.icon};`, r = this._config?.label?.style || `color: ${s.label};`, a = this._config?.value?.style || `color: ${s.value};`; return { backgroundColor: n, iconStyle: o, labelStyle: r, valueStyle: a }; } _renderRect(t, e, i, n, s) { const o = this._getRectColor(t, e, i), r = this._getSizeClass(t), a = t.climate?.hvacAction === "heating" || t.climate?.hvacAction === "cooling", l = this._config?.icon?.show ?? !0, h = this._config?.label?.show ?? !0, c = this._config?.value?.show ?? !0, u = this._formatLabel(t), f = this._formatValue(t), { backgroundColor: d, iconStyle: p, labelStyle: $, valueStyle: v } = this._calculateStyles(o), m = s / 2; return x`
${l && (t.icon || this._config?.icon?.icon) ? x`` : _} ${h ? x`${u}` : _} ${c ? x`${f}` : _} ${this._config?.sparkline?.show !== !1 ? (() => { const g = t.sparklineData ?? (t.entity_id ? this._sparklineData.get(t.entity_id) : void 0); return x`
${li(g, { mode: this._config?.sparkline?.mode || "dark", line: this._config?.sparkline?.line, fill: this._config?.sparkline?.fill, hvac: this._config?.sparkline?.hvac, periodHours: this._getPeriodHours(), min: this._config?.sparkline?.min, max: this._config?.sparkline?.max })}
`; })() : _}
`; } /** * Get the effective action config for a rect, with per-entity override support. */ _getActionConfig(t, e) { if (this._entityConfigMap.size > 0 && t.entity_id) { const n = this._entityConfigMap.get(t.entity_id); if (n?.[e]) return n[e]; for (const [s, o] of this._entityConfigMap) if (o[e] && ie(t.entity_id, s)) return o[e]; } const i = this._config?.[e]; return i || { action: e === "tap_action" ? "more-info" : "none" }; } _executeAction(t, e) { switch (t.action) { case "more-info": e && pe(this, "hass-more-info", { entityId: e }); break; case "navigate": "navigation_path" in t && t.navigation_path && Vt(this, t.navigation_path); break; case "url": "url_path" in t && t.url_path && window.open(t.url_path); break; case "toggle": if (e && this.hass) { const i = e.split(".")[0] ?? "homeassistant"; this.hass.callService(i, "toggle", { entity_id: e }); } break; case "call-service": if ("service" in t && t.service && this.hass) { const i = t.service.split("."), n = i[0] ?? "", s = i[1] ?? ""; this.hass.callService(n, s, t.service_data); } break; case "assist": pe(this, "hass-launch-voice-assistant", {}); break; } } _onPointerDown(t, e) { if (t.button !== 0 && t.pointerType === "mouse") return; this._holdFired = !1, this._clearHoldTimer(); const i = this._getActionConfig(e, "hold_action"); i.action !== "none" && (this._holdTimer = setTimeout(() => { this._holdFired = !0, this._clearHoldTimer(), this._executeAction(i, e.entity_id); }, T._HOLD_THRESHOLD_MS)); } _onPointerUp(t, e) { if (t.button !== 0 && t.pointerType === "mouse" || (this._clearHoldTimer(), this._holdFired)) return; const i = this._getActionConfig(e, "tap_action"); i.action !== "none" && this._executeAction(i, e.entity_id); } _clearHoldTimer() { this._holdTimer !== null && (clearTimeout(this._holdTimer), this._holdTimer = null); } }; T.styles = Ei; T._HOLD_THRESHOLD_MS = 500; he([ ce({ attribute: !1 }) ], T.prototype, "hass", 2); he([ ve() ], T.prototype, "_config", 2); he([ ve() ], T.prototype, "_sparklineData", 2); T = he([ Je("treemap-card") ], T); window.customCards = window.customCards || []; window.customCards.push({ type: "treemap-card", name: "Treemap Card", description: "Visualize entities as a treemap with size and color based on values", preview: !0 }); function ae(t) { return t === "__proto__"; } function Di(t) { switch (typeof t) { case "number": case "symbol": return !1; case "string": return t.includes(".") || t.includes("[") || t.includes("]"); } } function $e(t) { return typeof t == "string" || typeof t == "symbol" ? t : Object.is(t?.valueOf?.(), -0) ? "-0" : String(t); } function Ke(t) { if (t == null) return ""; if (typeof t == "string") return t; if (Array.isArray(t)) return t.map(Ke).join(","); const e = String(t); return e === "0" && Object.is(Number(t), -0) ? "-0" : e; } function et(t) { if (Array.isArray(t)) return t.map($e); if (typeof t == "symbol") return [t]; t = Ke(t); const e = [], i = t.length; if (i === 0) return e; let n = 0, s = "", o = "", r = !1; for (t.charCodeAt(0) === 46 && (e.push(""), n++); n < i; ) { const a = t[n]; o ? a === "\\" && n + 1 < i ? (n++, s += t[n]) : a === o ? o = "" : s += a : r ? a === '"' || a === "'" ? o = a : a === "]" ? (r = !1, e.push(s), s = "") : s += a : a === "[" ? (r = !0, s && (e.push(s), s = "")) : a === "." ? s && (e.push(s), s = "") : s += a, n++; } return s && e.push(s), e; } function tt(t, e, i) { if (t == null) return i; switch (typeof e) { case "string": { if (ae(e)) return i; const n = t[e]; return n === void 0 ? Di(e) ? tt(t, et(e), i) : i : n; } case "number": case "symbol": { typeof e == "number" && (e = $e(e)); const n = t[e]; return n === void 0 ? i : n; } default: { if (Array.isArray(e)) return Oi(t, e, i); if (Object.is(e?.valueOf(), -0) ? e = "-0" : e = String(e), ae(e)) return i; const n = t[e]; return n === void 0 ? i : n; } } } function Oi(t, e, i) { if (e.length === 0) return i; let n = t; for (let s = 0; s < e.length; s++) { if (n == null || ae(e[s])) return i; n = n[e[s]]; } return n === void 0 ? i : n; } function Re(t) { return t !== null && (typeof t == "object" || typeof t == "function"); } function Ii(t, e) { return t === e || Number.isNaN(t) && Number.isNaN(e); } const Hi = /^(?:0|[1-9]\d*)$/; function Ri(t, e = Number.MAX_SAFE_INTEGER) { switch (typeof t) { case "number": return Number.isInteger(t) && t >= 0 && t < e; case "symbol": return !1; case "string": return Hi.test(t); } } function Li(t) { return typeof t == "symbol" || t instanceof Symbol; } const Ui = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, Bi = /^\w*$/; function Fi(t, e) { return Array.isArray(t) ? !1 : typeof t == "number" || typeof t == "boolean" || t == null || Li(t) ? !0 : typeof t == "string" && (Bi.test(t) || !Ui.test(t)) || e != null && Object.hasOwn(e, t); } const ji = (t, e, i) => { const n = t[e]; (!(Object.hasOwn(t, e) && Ii(n, i)) || i === void 0 && !(e in t)) && (t[e] = i); }; function qi(t, e, i, n) { if (t == null && !Re(t)) return t; let s; Fi(e, t) ? s = [e] : Array.isArray(e) ? s = e : s = et(e); const o = i(tt(t, s)); let r = t; for (let a = 0; a < s.length && r != null; a++) { const l = $e(s[a]); if (ae(l)) continue; let h; if (a === s.length - 1) h = o; else { const c = r[l], u = n?.(c, l, t); h = u !== void 0 ? u : Re(c) ? c : Ri(s[a + 1]) ? [] : {}; } ji(r, l, h), r = r[l]; } return t; } function N(t, e, i) { return qi(t, e, () => i, () => { }); } const Wi = Fe` :host { display: block; } .editor { display: flex; flex-direction: column; gap: 12px; } /* Info message for YAML-only features */ .info-message { padding: 12px 16px; background: var(--secondary-background-color, #f5f5f5); border-radius: 8px; font-size: 14px; color: var(--secondary-text-color, #666); } /* Field styling */ .field { display: flex; flex-direction: column; gap: 4px; } .field-label { font-size: 12px; font-weight: 500; color: var(--secondary-text-color, #666); } .field-helper { font-size: 11px; color: var(--secondary-text-color, #888); } /* Inputs */ .input { width: 100%; padding: 8px 12px; border: 1px solid var(--divider-color, #e0e0e0); border-radius: 4px; font-size: 14px; background: var(--card-background-color, #fff); color: var(--primary-text-color, #333); box-sizing: border-box; } .input:focus { outline: none; border-color: var(--primary-color, #03a9f4); } .textarea { width: 100%; padding: 8px 12px; border: 1px solid var(--divider-color, #e0e0e0); border-radius: 4px; font-family: monospace; font-size: 13px; background: var(--card-background-color, #fff); color: var(--primary-text-color, #333); box-sizing: border-box; resize: vertical; } .textarea:focus { outline: none; border-color: var(--primary-color, #03a9f4); } /* ha-expansion-panel */ ha-expansion-panel input[type='checkbox'] { width: 16px; height: 16px; margin: 0 8px 0 0; cursor: pointer; accent-color: var(--primary-color, #03a9f4); } ha-expansion-panel .content { padding: 12px; display: flex; flex-direction: column; gap: 12px; } /* Docs link at end of section */ .docs-link { align-self: flex-end; color: var(--secondary-text-color, #888); opacity: 0.6; transition: opacity 0.2s; padding: 4px 8px; margin: -4px -8px; min-width: 40px; min-height: 28px; display: flex; align-items: center; justify-content: center; } .docs-link:hover { opacity: 1; } .docs-link ha-icon { --mdc-icon-size: 20px; } /* Color picker row */ .color-row { display: flex; gap: 16px; } .color-field { display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; } .color-field input[type='color'] { width: 48px; height: 32px; padding: 0; border: 1px solid var(--divider-color, #e0e0e0); border-radius: 4px; cursor: pointer; background: none; } .color-field input[type='color']::-webkit-color-swatch-wrapper { padding: 2px; } .color-field input[type='color']::-webkit-color-swatch { border: none; border-radius: 2px; } .color-field span { font-size: 11px; color: var(--secondary-text-color, #666); } /* Inline input field */ .inline-field { display: flex; flex-direction: column; gap: 4px; } /* Side-by-side fields */ .field-row { display: flex; gap: 8px; } .field-row ha-textfield, .field-row ha-select { flex: 1; } /* Checkbox with label */ .checkbox-field { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; color: var(--primary-text-color, #333); } .checkbox-field input[type='checkbox'] { width: 16px; height: 16px; margin: 0; cursor: pointer; accent-color: var(--primary-color, #03a9f4); } .checkbox-field input[type='checkbox']:disabled { opacity: 0.5; cursor: not-allowed; } .checkbox-field input[type='checkbox']:disabled + span { opacity: 0.5; } /* Color + scale value row */ .color-scale-row { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; } .color-scale-row .color-field { margin: 0; } .color-scale-row ha-textfield { flex: 1; } .color-label { font-size: 14px; color: var(--primary-text-color, #333); align-self: center; } /* Footer banner */ .footer-banner { display: flex; justify-content: center; align-items: center; gap: 8px; padding: 8px; font-size: 13px; color: var(--secondary-text-color, #888); } .footer-banner a { display: flex; align-items: center; gap: 6px; color: var(--secondary-text-color, #888); text-decoration: none; transition: color 0.2s; padding: 10px 12px; min-height: 44px; box-sizing: border-box; border-radius: 8px; } .footer-banner a:hover { color: var(--primary-text-color, #333); background: var(--secondary-background-color, rgba(0, 0, 0, 0.05)); } .footer-banner ha-icon { --mdc-icon-size: 18px; } .footer-banner .separator { opacity: 0.3; } `, it = { no_config: "Keine Konfiguration", yaml_only: "JSON-Attributmodus wird nur über YAML konfiguriert.", entities: { label: "Entitätsmuster (eines pro Zeile)", helper: "Wildcards (*) werden unterstützt", placeholder: `sensor.temperature_* climate.* light.living_*` }, exclude: { label: "Ausschlussmuster", placeholder: `*_battery *_unavailable light.*` }, label: { title: "Bezeichnung", prefix: "Präfix", suffix: "Suffix", find: "Suchen", replace: "Ersetzen mit", find_placeholder: "Temperatur", replace_placeholder: "Temp" }, value: { title: "Wert", prefix: "Präfix", suffix: "Suffix", suffix_placeholder: "%", precision: "Dezimalstellen", abbreviate: "Große Zahlen abkürzen (k, M, B)" }, icon: { title: "Symbol", override: "Symbol ersetzen" }, sparkline: { title: "Sparkline", period: "Zeitraum", period_12h: "12 Stunden", period_24h: "24 Stunden", period_7d: "7 Tage", period_30d: "30 Tage", mode: "Modus", mode_dark: "Dunkel", mode_light: "Hell", show_line: "Linie anzeigen", show_fill: "Füllung anzeigen", show_hvac: "HVAC-Balken anzeigen (Klimaentitäten)", min: "Y-Achse Min", max: "Y-Achse Max" }, colors: { title: "Farben", target: "Farbe anwenden auf", target_background: "Hintergrund", target_foreground: "Vordergrund (Text)", gradient: "Farbverlauf (niedrig → mittel → hoch)", low: "Niedrig ≤", mid: "Mittel =", high: "Hoch ≥", auto: "auto", middle: "mitte", hvac_colors: "HVAC-Farben (Klimaentitäten)", heating: "Heizen", cooling: "Kühlen", off: "Aus", unavailable: "Nicht verfügbar" }, size: { title: "Größe", equal: "Gleich große Rechtecke", inverse: "Invertiert (niedrige Werte = größer)", min: "Min", max: "Max" }, layout: { title: "Layout", height: "Höhe (px)", gap: "Abstand (px)" }, footer: { docs: "Doku", issues: "Bug oder Idee?", star: "Gefällt es? Stern geben!" }, actions: { title: "Aktionen", tap_action: "Tipp-Aktion", hold_action: "Halten-Aktion" }, data: { title: "Daten", order: "Sortierung", desc: "Absteigend (hoch zuerst)", asc: "Aufsteigend (niedrig zuerst)", limit: "Limit", all: "alle", above: "Filter oberhalb", below: "Filter unterhalb", unavailable: "Nicht verfügbare Entitäten einschließen", sort_by: "Sortieren nach", sort_by_value: "Wert (optimales Layout)", sort_by_entity_id: "Entitäts-ID", sort_by_label: "Bezeichnung", sort_by_default: "Konfigurationsreihenfolge" } }, Gi = { editor: it }, Yi = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: Gi, editor: it }, Symbol.toStringTag, { value: "Module" })), nt = { no_config: "No configuration", yaml_only: "JSON attribute mode is configured via YAML only.", entities: { label: "Entity patterns (one per line)", helper: "Wildcards (*) are supported", placeholder: `sensor.temperature_* climate.* light.living_*` }, exclude: { label: "Exclude patterns", placeholder: `*_battery *_unavailable light.*` }, label: { title: "Label", prefix: "Prefix", suffix: "Suffix", find: "Find", replace: "Replace with", find_placeholder: "Temperature", replace_placeholder: "Temp" }, value: { title: "Value", prefix: "Prefix", suffix: "Suffix", suffix_placeholder: "%", precision: "Decimal places", abbreviate: "Abbreviate large numbers (k, M, B)" }, icon: { title: "Icon", override: "Override icon" }, sparkline: { title: "Sparkline", period: "Period", period_12h: "12 hours", period_24h: "24 hours", period_7d: "7 days", period_30d: "30 days", mode: "Mode", mode_dark: "Dark", mode_light: "Light", show_line: "Show line", show_fill: "Show fill", show_hvac: "Show HVAC bars (climate entities)", min: "Y-axis min", max: "Y-axis max" }, colors: { title: "Colors", target: "Apply color to", target_background: "Background", target_foreground: "Foreground (text)", gradient: "Color gradient (low → mid → high)", low: "Low ≤", mid: "Mid =", high: "High ≥", auto: "auto", middle: "middle", hvac_colors: "HVAC colors (climate entities)", heating: "Heating", cooling: "Cooling", off: "Off", unavailable: "Unavailable" }, size: { title: "Size", equal: "Equal size rectangles", inverse: "Inverse (low values = bigger)", min: "Min", max: "Max" }, layout: { title: "Layout", height: "Height (px)", gap: "Gap (px)" }, footer: { docs: "Docs", issues: "Bug or idea?", star: "Like it? Star it!" }, actions: { title: "Actions", tap_action: "Tap action", hold_action: "Hold action" }, data: { title: "Data", order: "Order", desc: "Descending (high first)", asc: "Ascending (low first)", sort_by: "Sort by", sort_by_value: "Value (optimal layout)", sort_by_entity_id: "Entity ID", sort_by_label: "Label", sort_by_default: "Config order", limit: "Limit", all: "all", above: "Filter above", below: "Filter below", unavailable: "Include unavailable entities" } }, Ji = { editor: nt }, Zi = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: Ji, editor: nt }, Symbol.toStringTag, { value: "Module" })), ot = { no_config: "Aucune configuration", yaml_only: "Le mode attribut JSON est configurable uniquement via YAML.", entities: { label: "Motifs d'entités (un par ligne)", helper: "Wildcards (*) supportés", placeholder: `sensor.temperature_* climate.* light.living_*` }, exclude: { label: "Motifs à exclure", placeholder: `*_battery *_unavailable light.*` }, label: { title: "Libellé", prefix: "Préfixe", suffix: "Suffixe", find: "Rechercher", replace: "Remplacer par", find_placeholder: "Température", replace_placeholder: "Temp" }, value: { title: "Valeur", prefix: "Préfixe", suffix: "Suffixe", suffix_placeholder: "%", precision: "Décimales", abbreviate: "Abréger les grands nombres (k, M, B)" }, icon: { title: "Icône", override: "Remplacer l'icône" }, sparkline: { title: "Sparkline", period: "Période", period_12h: "12 heures", period_24h: "24 heures", period_7d: "7 jours", period_30d: "30 jours", mode: "Mode", mode_dark: "Sombre", mode_light: "Clair", show_line: "Afficher la ligne", show_fill: "Afficher le remplissage", show_hvac: "Afficher les barres HVAC (entités climatiques)", min: "Min axe Y", max: "Max axe Y" }, colors: { title: "Couleurs", target: "Appliquer la couleur à", target_background: "Arrière-plan", target_foreground: "Premier plan (texte)", gradient: "Dégradé de couleur (bas → milieu → haut)", low: "Bas ≤", mid: "Milieu =", high: "Haut ≥", auto: "auto", middle: "milieu", hvac_colors: "Couleurs HVAC (entités climatiques)", heating: "Chauffage", cooling: "Climatisation", off: "Éteint", unavailable: "Indisponible" }, size: { title: "Taille", equal: "Rectangles de taille égale", inverse: "Inverse (valeurs basses = plus grand)", min: "Min", max: "Max" }, layout: { title: "Disposition", height: "Hauteur (px)", gap: "Espacement (px)" }, footer: { docs: "Docs", issues: "Bug ou idée?", star: "Vous aimez? Étoile!" }, actions: { title: "Actions", tap_action: "Action au tap", hold_action: "Action au maintien" }, data: { title: "Données", order: "Ordre", desc: "Décroissant (haut en premier)", asc: "Croissant (bas en premier)", limit: "Limite", all: "tous", above: "Filtrer au-dessus", below: "Filtrer en-dessous", unavailable: "Inclure les entités indisponibles", sort_by: "Trier par", sort_by_value: "Valeur (disposition optimale)", sort_by_entity_id: "ID d'entité", sort_by_label: "Étiquette", sort_by_default: "Ordre de configuration" } }, Xi = { editor: ot }, Qi = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: Xi, editor: ot }, Symbol.toStringTag, { value: "Module" })), Le = { de: Yi, en: Zi, fr: Qi }; function Ki(t) { return typeof t == "object" && t !== null; } function Ue(t, e) { const i = e.split("."); let n = t; for (const s of i) if (n && Ki(n) && s in n) n = n[s]; else return; return typeof n == "string" ? n : void 0; } function en(t) { return (t?.language ?? "en").split("-")[0] ?? "en"; } function tn(t, e) { const i = en(t), n = Le[i]; if (n) { const s = Ue(n, e); if (s) return s; } if (i !== "en") { const s = Le.en; if (s) { const o = Ue(s, e); if (o) return o; } } return e; } var nn = Object.defineProperty, on = Object.getOwnPropertyDescriptor, ue = (t, e, i, n) => { for (var s = n > 1 ? void 0 : n ? on(e, i) : e, o = t.length - 1, r; o >= 0; o--) (r = t[o]) && (s = (n ? r(e, i, s) : r(s)) || s); return n && s && nn(e, i, s), s; }; const ne = "https://github.com/omachala/ha-treemap-card"; function Y(t) { const e = t.target; if (e && typeof e == "object" && "value" in e) { const i = e.value; return String(i ?? ""); } return ""; } function sn(t) { const e = t.target; return e instanceof HTMLInputElement ? e.checked : !1; } let H = class extends B { constructor() { super(...arguments), this._actionsSchema = [ { name: "tap_action", selector: { ui_action: { default_action: "more-info" } } }, { name: "hold_action", selector: { ui_action: { default_action: "none" } } } ]; } setConfig(t) { this._config = { ...t }; } /** * Shorthand for localize with current hass context */ _t(t) { return tn(this.hass, t); } _fireConfigChanged() { this._config && this.dispatchEvent( new CustomEvent("config-changed", { detail: { config: this._config }, bubbles: !0, composed: !0 }) ); } /** * Generic handler for text input changes */ _handleTextChange(t, e) { if (!this._config) return; const i = Y(e) || void 0; this._config = N({ ...this._config }, t, i), this._fireConfigChanged(); } /** * Generic handler for checkbox changes */ _handleBoolChange(t, e) { if (!this._config) return; const i = sn(e); this._config = N({ ...this._config }, t, i), this._fireConfigChanged(); } /** * Generic handler for number input changes */ _handleNumberChange(t, e) { if (!this._config) return; const i = Y(e), n = i ? Number.parseFloat(i) : void 0; this._config = N({ ...this._config }, t, n), this._fireConfigChanged(); } /** * Handler for entities textarea (splits lines into array) */ _handleEntitiesChange(t) { if (!this._config) return; const i = Y(t).split(` `).map((n) => n.trim()).filter((n) => n.length > 0); this._config = N({ ...this._config }, "entities", i), this._fireConfigChanged(); } /** * Handler for ha-icon-picker value-changed event */ _handleIconChange(t) { if (!this._config) return; const e = t.detail?.value || void 0; this._config = N({ ...this._config }, "icon.icon", e), this._fireConfigChanged(); } /** * Handler for find/replace inputs (combines into 'find/replace' format) */ _handleReplaceChange(t, e) { if (!this._config) return; const i = Y(e), s = (this._config.label?.replace ?? "/").split("/"), o = t === "find" ? i : s[0] ?? "", r = t === "replace" ? i : s[1] ?? "", a = o || r ? `${o}/${r}` : void 0; this._config = N({ ...this._config }, "label.replace", a), this._fireConfigChanged(); } /** * Handler for exclude textarea (splits lines into array, removes if empty) */ _handleExcludeChange(t) { if (!this._config) return; const i = Y(t).split(` `).map((n) => n.trim()).filter((n) => n.length > 0); this._config = N({ ...this._config }, "exclude", i.length > 0 ? i : void 0), this._fireConfigChanged(); } _handleActionsChanged(t) { if (!this._config) return; const e = t.detail?.value?.tap_action, i = t.detail?.value?.hold_action; this._config = { ...this._config, ...e !== void 0 && { tap_action: e }, ...i !== void 0 && { hold_action: i } }, this._fireConfigChanged(); } _docsUrl(t) { return `${ne}?tab=readme-ov-file#${t}`; } _renderDocsLink(t) { return x` `; } _renderToggleSection(t) { return x` e.stopPropagation()} /> ${t.title}
${t.content} ${t.docsAnchor ? this._renderDocsLink(t.docsAnchor) : ""}
`; } render() { if (!this._config) return x`
${this._t("editor.no_config")}
`; if (this._config.entity) return x`
${this._t("editor.yaml_only")}
`; const t = this._config.entities?.map((o) => Ze(o) ? o.entity : o).join(` `) ?? "", e = this._config.exclude?.join(` `) ?? "", i = this._config.label ?? {}, n = this._config.value ?? {}, s = this._config.icon ?? {}; return x`
${this._t("editor.entities.helper")}
${this._renderToggleSection({ id: "label", title: this._t("editor.label.title"), checked: i.show !== !1, onToggle: (o) => this._handleBoolChange("label.show", o), docsAnchor: "label", content: x`
this._handleTextChange("label.prefix", o)} > this._handleTextChange("label.suffix", o)} >
this._handleReplaceChange("find", o)} placeholder=${this._t("editor.label.find_placeholder")} > this._handleReplaceChange("replace", o)} placeholder=${this._t("editor.label.replace_placeholder")} >
` })} ${this._renderToggleSection({ id: "value", title: this._t("editor.value.title"), checked: n.show !== !1, onToggle: (o) => this._handleBoolChange("value.show", o), docsAnchor: "value", content: x`
this._handleTextChange("value.prefix", o)} > this._handleTextChange("value.suffix", o)} placeholder=${this._t("editor.value.suffix_placeholder")} >
this._handleNumberChange("value.precision", o)} placeholder="1" >
` })} ${this._renderToggleSection({ id: "icon", title: this._t("editor.icon.title"), checked: s.show !== !1, onToggle: (o) => this._handleBoolChange("icon.show", o), docsAnchor: "icon", content: x` ` })} this._handleBoolChange("sparkline.show", o)} @click=${(o) => o.stopPropagation()} /> ${this._t("editor.sparkline.title")}
this._handleTextChange("sparkline.period", o)} @closed=${(o) => o.stopPropagation()} > ${this._t("editor.sparkline.period_12h")} ${this._t("editor.sparkline.period_24h")} ${this._t("editor.sparkline.period_7d")} ${this._t("editor.sparkline.period_30d")} this._handleTextChange("sparkline.mode", o)} @closed=${(o) => o.stopPropagation()} > ${this._t("editor.sparkline.mode_dark")} ${this._t("editor.sparkline.mode_light")}
this._handleNumberChange("sparkline.min", o)} placeholder=${this._t("editor.colors.auto")} > this._handleNumberChange("sparkline.max", o)} placeholder=${this._t("editor.colors.auto")} >
${this._renderDocsLink("sparkline")}
${this._t("editor.colors.title")}
this._handleTextChange("color.target", o)} @closed=${(o) => o.stopPropagation()} > ${this._t("editor.colors.target_background")} ${this._t("editor.colors.target_foreground")} ${this._t("editor.colors.gradient")}
this._handleNumberChange("color.scale.min", o)} placeholder=${this._t("editor.colors.auto")} >
this._handleNumberChange("color.scale.neutral", o)} placeholder=${this._t("editor.colors.middle")} >
this._handleNumberChange("color.scale.max", o)} placeholder=${this._t("editor.colors.auto")} >
${this._t("editor.colors.unavailable")}
${this._t("editor.colors.hvac_colors")}
${this._renderDocsLink("color")}
${this._t("editor.size.title")}
this._handleNumberChange("size.min", o)} placeholder=${this._t("editor.colors.auto")} > this._handleNumberChange("size.max", o)} placeholder=${this._t("editor.colors.auto")} >
${this._renderDocsLink("size")}
${this._t("editor.data.title")}
this._handleTextChange("sort_by", o)} @closed=${(o) => o.stopPropagation()} > ${this._t("editor.data.sort_by_value")} ${this._t("editor.data.sort_by_entity_id")} ${this._t("editor.data.sort_by_label")} ${this._t("editor.data.sort_by_default")} this._handleTextChange("order", o)} @closed=${(o) => o.stopPropagation()} > ${this._t("editor.data.desc")} ${this._t("editor.data.asc")} this._handleNumberChange("limit", o)} placeholder=${this._t("editor.data.all")} >
this._handleNumberChange("filter.above", o)} > this._handleNumberChange("filter.below", o)} >
${this._renderDocsLink("order--filter")}
${this._t("editor.layout.title")}
this._handleNumberChange("height", o)} placeholder=${this._t("editor.colors.auto")} > this._handleNumberChange("gap", o)} placeholder="6" >
${this._renderDocsLink("layout")}
${this._t("editor.actions.title")}
this._t(`editor.actions.${o.name}`)} @value-changed=${this._handleActionsChanged} data-testid="actions-form" > ${this._renderDocsLink("tap--hold-actions")}
`; } }; H.styles = Wi; ue([ ce({ attribute: !1 }) ], H.prototype, "hass", 2); ue([ ce({ attribute: !1 }) ], H.prototype, "lovelace", 2); ue([ ve() ], H.prototype, "_config", 2); H = ue([ Je("treemap-card-editor") ], H); const rn = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, get TreemapCardEditor() { return H; } }, Symbol.toStringTag, { value: "Module" })); export { T as TreemapCard };