diff --git a/dist/ring-view.js b/dist/ring-view.js index 31c4717..b4247eb 100644 --- a/dist/ring-view.js +++ b/dist/ring-view.js @@ -1,16 +1,16 @@ -var ue = "M11,15H13V17H11V15M11,7H13V13H11V7M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20Z", nt = "M10,21H14A2,2 0 0,1 12,23A2,2 0 0,1 10,21M21,19V20H3V19L5,17V11C5,7.9 7.03,5.17 10,4.29C10,4.19 10,4.1 10,4A2,2 0 0,1 12,2A2,2 0 0,1 14,4C14,4.1 14,4.19 14,4.29C16.97,5.17 19,7.9 19,11V17L21,19M17,11A5,5 0 0,0 12,6A5,5 0 0,0 7,11V18H17V11M19.75,3.19L18.33,4.61C20.04,6.3 21,8.6 21,11H23C23,8.07 21.84,5.25 19.75,3.19M1,11H3C3,8.6 3.96,6.3 5.67,4.61L4.25,3.19C2.16,5.25 1,8.07 1,11Z", Rt = "M9,12C9,11.19 9.3,10.5 9.89,9.89C10.5,9.3 11.19,9 12,9C12.81,9 13.5,9.3 14.11,9.89C14.7,10.5 15,11.19 15,12C15,12.81 14.7,13.5 14.11,14.11C13.5,14.7 12.81,15 12,15C11.19,15 10.5,14.7 9.89,14.11C9.3,13.5 9,12.81 9,12M5.53,8.44L7.31,10.22L5.53,12L7.31,13.78L5.53,15.56L2,12L5.53,8.44M8.44,18.47L10.22,16.69L12,18.47L13.78,16.69L15.56,18.47L12,22L8.44,18.47M18.47,15.56L16.69,13.78L18.47,12L16.69,10.22L18.47,8.44L22,12L18.47,15.56M15.56,5.53L13.78,7.31L12,5.53L10.22,7.31L8.44,5.53L12,2L15.56,5.53Z", rt = "M20,4H16.83L15,2H9L7.17,4H4A2,2 0 0,0 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V6A2,2 0 0,0 20,4M20,18H4V6H8.05L9.88,4H14.12L15.95,6H20V18M12,7A5,5 0 0,0 7,12A5,5 0 0,0 12,17A5,5 0 0,0 17,12A5,5 0 0,0 12,7M12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15Z", Oe = "M12 2C6.5 2 2 6.5 2 12S6.5 22 12 22 22 17.5 22 12 17.5 2 12 2M12 20C7.59 20 4 16.41 4 12S7.59 4 12 4 20 7.59 20 12 16.41 20 12 20M16.59 7.58L10 14.17L7.41 11.59L6 13L10 17L18 9L16.59 7.58Z", Et = "M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z", Lt = "M16,11H18V13H16V11M12,3H19C20.11,3 21,3.89 21,5V19H22V21H2V19H10V5C10,3.89 10.89,3 12,3M12,5V19H19V5H12Z", Ue = "M12,3C10.89,3 10,3.89 10,5H3V19H2V21H22V19H21V5C21,3.89 20.11,3 19,3H12M12,5H19V19H12V5M5,11H7V13H5V11Z", Pt = "M14 15C14 16.11 13.11 17 12 17S10 16.11 10 15 10.9 13 12 13 14 13.9 14 15M18 4V20C18 21.1 17.11 22 16 22H8C6.9 22 6 21.11 6 20V4C6 2.9 6.9 2 8 2H16C17.11 2 18 2.9 18 4M10.5 7C10.5 7.83 11.17 8.5 12 8.5S13.5 7.83 13.5 7 12.83 5.5 12 5.5 10.5 6.17 10.5 7M16 10H8V20H16V10Z", Mt = "M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z", Dt = "M13.5,8H12V13L16.28,15.54L17,14.33L13.5,12.25V8M13,3A9,9 0 0,0 4,12H1L4.96,16.03L9,12H6A7,7 0 0,1 13,5A7,7 0 0,1 20,12A7,7 0 0,1 13,19C11.07,19 9.32,18.21 8.06,16.94L6.64,18.36C8.27,20 10.5,21 13,21A9,9 0 0,0 22,12A9,9 0 0,0 13,3", ze = "M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z", at = "M10 13C11.1 13 12 13.89 12 15C12 16.11 11.11 17 10 17S8 16.11 8 15 8.9 13 10 13M18 1C15.24 1 13 3.24 13 6V8H4C2.9 8 2 8.9 2 10V20C2 21.1 2.9 22 4 22H16C17.1 22 18 21.1 18 20V10C18 8.9 17.1 8 16 8H15V6C15 4.34 16.34 3 18 3S21 4.34 21 6V8H23V6C23 3.24 20.76 1 18 1M16 10V20H4V10H16Z", dt = "M12,2A3,3 0 0,1 15,5V11A3,3 0 0,1 12,14A3,3 0 0,1 9,11V5A3,3 0 0,1 12,2M19,11C19,14.53 16.39,17.44 13,17.93V21H11V17.93C7.61,17.44 5,14.53 5,11H7A5,5 0 0,0 12,16A5,5 0 0,0 17,11H19Z", ct = "M19,11C19,12.19 18.66,13.3 18.1,14.28L16.87,13.05C17.14,12.43 17.3,11.74 17.3,11H19M15,11.16L9,5.18V5A3,3 0 0,1 12,2A3,3 0 0,1 15,5V11L15,11.16M4.27,3L21,19.73L19.73,21L15.54,16.81C14.77,17.27 13.91,17.58 13,17.72V21H11V17.72C7.72,17.23 5,14.41 5,11H6.7C6.7,14 9.24,16.1 12,16.1C12.81,16.1 13.6,15.91 14.31,15.58L12.65,13.92L12,14A3,3 0 0,1 9,11V10.28L3,4.27L4.27,3Z", It = "M12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2C17.5,2 22,6 22,11A6,6 0 0,1 16,17H14.2C13.9,17 13.7,17.2 13.7,17.5C13.7,17.6 13.8,17.7 13.8,17.8C14.2,18.3 14.4,18.9 14.4,19.5C14.5,20.9 13.4,22 12,22M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C12.3,20 12.5,19.8 12.5,19.5C12.5,19.3 12.4,19.2 12.4,19.1C12,18.6 11.8,18.1 11.8,17.5C11.8,16.1 12.9,15 14.3,15H16A4,4 0 0,0 20,11C20,7.1 16.4,4 12,4M6.5,10C7.3,10 8,10.7 8,11.5C8,12.3 7.3,13 6.5,13C5.7,13 5,12.3 5,11.5C5,10.7 5.7,10 6.5,10M9.5,6C10.3,6 11,6.7 11,7.5C11,8.3 10.3,9 9.5,9C8.7,9 8,8.3 8,7.5C8,6.7 8.7,6 9.5,6M14.5,6C15.3,6 16,6.7 16,7.5C16,8.3 15.3,9 14.5,9C13.7,9 13,8.3 13,7.5C13,6.7 13.7,6 14.5,6M17.5,10C18.3,10 19,10.7 19,11.5C19,12.3 18.3,13 17.5,13C16.7,13 16,12.3 16,11.5C16,10.7 16.7,10 17.5,10Z", lt = "M8,5.14V19.14L19,12.14L8,5.14Z", Vt = "M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M10,16.5L16,12L10,7.5V16.5Z"; -const ie = globalThis, Se = ie.ShadowRoot && (ie.ShadyCSS === void 0 || ie.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, $e = /* @__PURE__ */ Symbol(), Fe = /* @__PURE__ */ new WeakMap(); -let ht = class { +var pe = "M11,15H13V17H11V15M11,7H13V13H11V7M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20Z", dt = "M10,21H14A2,2 0 0,1 12,23A2,2 0 0,1 10,21M21,19V20H3V19L5,17V11C5,7.9 7.03,5.17 10,4.29C10,4.19 10,4.1 10,4A2,2 0 0,1 12,2A2,2 0 0,1 14,4C14,4.1 14,4.19 14,4.29C16.97,5.17 19,7.9 19,11V17L21,19M17,11A5,5 0 0,0 12,6A5,5 0 0,0 7,11V18H17V11M19.75,3.19L18.33,4.61C20.04,6.3 21,8.6 21,11H23C23,8.07 21.84,5.25 19.75,3.19M1,11H3C3,8.6 3.96,6.3 5.67,4.61L4.25,3.19C2.16,5.25 1,8.07 1,11Z", Dt = "M9,12C9,11.19 9.3,10.5 9.89,9.89C10.5,9.3 11.19,9 12,9C12.81,9 13.5,9.3 14.11,9.89C14.7,10.5 15,11.19 15,12C15,12.81 14.7,13.5 14.11,14.11C13.5,14.7 12.81,15 12,15C11.19,15 10.5,14.7 9.89,14.11C9.3,13.5 9,12.81 9,12M5.53,8.44L7.31,10.22L5.53,12L7.31,13.78L5.53,15.56L2,12L5.53,8.44M8.44,18.47L10.22,16.69L12,18.47L13.78,16.69L15.56,18.47L12,22L8.44,18.47M18.47,15.56L16.69,13.78L18.47,12L16.69,10.22L18.47,8.44L22,12L18.47,15.56M15.56,5.53L13.78,7.31L12,5.53L10.22,7.31L8.44,5.53L12,2L15.56,5.53Z", ct = "M20,4H16.83L15,2H9L7.17,4H4A2,2 0 0,0 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V6A2,2 0 0,0 20,4M20,18H4V6H8.05L9.88,4H14.12L15.95,6H20V18M12,7A5,5 0 0,0 7,12A5,5 0 0,0 12,17A5,5 0 0,0 17,12A5,5 0 0,0 12,7M12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15Z", ze = "M12 2C6.5 2 2 6.5 2 12S6.5 22 12 22 22 17.5 22 12 17.5 2 12 2M12 20C7.59 20 4 16.41 4 12S7.59 4 12 4 20 7.59 20 12 16.41 20 12 20M16.59 7.58L10 14.17L7.41 11.59L6 13L10 17L18 9L16.59 7.58Z", It = "M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z", Vt = "M16,11H18V13H16V11M12,3H19C20.11,3 21,3.89 21,5V19H22V21H2V19H10V5C10,3.89 10.89,3 12,3M12,5V19H19V5H12Z", Fe = "M12,3C10.89,3 10,3.89 10,5H3V19H2V21H22V19H21V5C21,3.89 20.11,3 19,3H12M12,5H19V19H12V5M5,11H7V13H5V11Z", Ht = "M14 15C14 16.11 13.11 17 12 17S10 16.11 10 15 10.9 13 12 13 14 13.9 14 15M18 4V20C18 21.1 17.11 22 16 22H8C6.9 22 6 21.11 6 20V4C6 2.9 6.9 2 8 2H16C17.11 2 18 2.9 18 4M10.5 7C10.5 7.83 11.17 8.5 12 8.5S13.5 7.83 13.5 7 12.83 5.5 12 5.5 10.5 6.17 10.5 7M16 10H8V20H16V10Z", Ot = "M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z", Ut = "M13.5,8H12V13L16.28,15.54L17,14.33L13.5,12.25V8M13,3A9,9 0 0,0 4,12H1L4.96,16.03L9,12H6A7,7 0 0,1 13,5A7,7 0 0,1 20,12A7,7 0 0,1 13,19C11.07,19 9.32,18.21 8.06,16.94L6.64,18.36C8.27,20 10.5,21 13,21A9,9 0 0,0 22,12A9,9 0 0,0 13,3", Ne = "M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z", lt = "M10 13C11.1 13 12 13.89 12 15C12 16.11 11.11 17 10 17S8 16.11 8 15 8.9 13 10 13M18 1C15.24 1 13 3.24 13 6V8H4C2.9 8 2 8.9 2 10V20C2 21.1 2.9 22 4 22H16C17.1 22 18 21.1 18 20V10C18 8.9 17.1 8 16 8H15V6C15 4.34 16.34 3 18 3S21 4.34 21 6V8H23V6C23 3.24 20.76 1 18 1M16 10V20H4V10H16Z", ht = "M12,2A3,3 0 0,1 15,5V11A3,3 0 0,1 12,14A3,3 0 0,1 9,11V5A3,3 0 0,1 12,2M19,11C19,14.53 16.39,17.44 13,17.93V21H11V17.93C7.61,17.44 5,14.53 5,11H7A5,5 0 0,0 12,16A5,5 0 0,0 17,11H19Z", ut = "M19,11C19,12.19 18.66,13.3 18.1,14.28L16.87,13.05C17.14,12.43 17.3,11.74 17.3,11H19M15,11.16L9,5.18V5A3,3 0 0,1 12,2A3,3 0 0,1 15,5V11L15,11.16M4.27,3L21,19.73L19.73,21L15.54,16.81C14.77,17.27 13.91,17.58 13,17.72V21H11V17.72C7.72,17.23 5,14.41 5,11H6.7C6.7,14 9.24,16.1 12,16.1C12.81,16.1 13.6,15.91 14.31,15.58L12.65,13.92L12,14A3,3 0 0,1 9,11V10.28L3,4.27L4.27,3Z", zt = "M12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2C17.5,2 22,6 22,11A6,6 0 0,1 16,17H14.2C13.9,17 13.7,17.2 13.7,17.5C13.7,17.6 13.8,17.7 13.8,17.8C14.2,18.3 14.4,18.9 14.4,19.5C14.5,20.9 13.4,22 12,22M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C12.3,20 12.5,19.8 12.5,19.5C12.5,19.3 12.4,19.2 12.4,19.1C12,18.6 11.8,18.1 11.8,17.5C11.8,16.1 12.9,15 14.3,15H16A4,4 0 0,0 20,11C20,7.1 16.4,4 12,4M6.5,10C7.3,10 8,10.7 8,11.5C8,12.3 7.3,13 6.5,13C5.7,13 5,12.3 5,11.5C5,10.7 5.7,10 6.5,10M9.5,6C10.3,6 11,6.7 11,7.5C11,8.3 10.3,9 9.5,9C8.7,9 8,8.3 8,7.5C8,6.7 8.7,6 9.5,6M14.5,6C15.3,6 16,6.7 16,7.5C16,8.3 15.3,9 14.5,9C13.7,9 13,8.3 13,7.5C13,6.7 13.7,6 14.5,6M17.5,10C18.3,10 19,10.7 19,11.5C19,12.3 18.3,13 17.5,13C16.7,13 16,12.3 16,11.5C16,10.7 16.7,10 17.5,10Z", pt = "M8,5.14V19.14L19,12.14L8,5.14Z", Ft = "M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M10,16.5L16,12L10,7.5V16.5Z"; +const ie = globalThis, Te = ie.ShadowRoot && (ie.ShadyCSS === void 0 || ie.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, Ce = /* @__PURE__ */ Symbol(), qe = /* @__PURE__ */ new WeakMap(); +let vt = class { constructor(t, i, o) { - if (this._$cssResult$ = !0, o !== $e) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead."); + if (this._$cssResult$ = !0, o !== Ce) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead."); this.cssText = t, this.t = i; } get styleSheet() { let t = this.o; const i = this.t; - if (Se && t === void 0) { + if (Te && t === void 0) { const o = i !== void 0 && i.length === 1; - o && (t = Fe.get(i)), t === void 0 && ((this.o = t = new CSSStyleSheet()).replaceSync(this.cssText), o && Fe.set(i, t)); + o && (t = qe.get(i)), t === void 0 && ((this.o = t = new CSSStyleSheet()).replaceSync(this.cssText), o && qe.set(i, t)); } return t; } @@ -18,28 +18,28 @@ let ht = class { return this.cssText; } }; -const Ht = (e) => new ht(typeof e == "string" ? e : e + "", void 0, $e), F = (e, ...t) => { - const i = e.length === 1 ? e[0] : t.reduce((o, s, n) => o + ((a) => { +const Nt = (e) => new vt(typeof e == "string" ? e : e + "", void 0, Ce), N = (e, ...t) => { + const i = e.length === 1 ? e[0] : t.reduce((o, n, s) => o + ((a) => { if (a._$cssResult$ === !0) return a.cssText; if (typeof a == "number") return a; throw Error("Value passed to 'css' function must be a 'css' function result: " + a + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security."); - })(s) + e[n + 1], e[0]); - return new ht(i, e, $e); -}, Ot = (e, t) => { - if (Se) e.adoptedStyleSheets = t.map((i) => i instanceof CSSStyleSheet ? i : i.styleSheet); + })(n) + e[s + 1], e[0]); + return new vt(i, e, Ce); +}, qt = (e, t) => { + if (Te) e.adoptedStyleSheets = t.map((i) => i instanceof CSSStyleSheet ? i : i.styleSheet); else for (const i of t) { - const o = document.createElement("style"), s = ie.litNonce; - s !== void 0 && o.setAttribute("nonce", s), o.textContent = i.cssText, e.appendChild(o); + const o = document.createElement("style"), n = ie.litNonce; + n !== void 0 && o.setAttribute("nonce", n), o.textContent = i.cssText, e.appendChild(o); } -}, Ne = Se ? (e) => e : (e) => e instanceof CSSStyleSheet ? ((t) => { +}, Be = Te ? (e) => e : (e) => e instanceof CSSStyleSheet ? ((t) => { let i = ""; for (const o of t.cssRules) i += o.cssText; - return Ht(i); + return Nt(i); })(e) : e; -const { is: Ut, defineProperty: zt, getOwnPropertyDescriptor: Ft, getOwnPropertyNames: Nt, getOwnPropertySymbols: qt, getPrototypeOf: Bt } = Object, ce = globalThis, qe = ce.trustedTypes, Kt = qe ? qe.emptyScript : "", Wt = ce.reactiveElementPolyfillSupport, B = (e, t) => e, ne = { toAttribute(e, t) { +const { is: Bt, defineProperty: Kt, getOwnPropertyDescriptor: Wt, getOwnPropertyNames: jt, getOwnPropertySymbols: Zt, getPrototypeOf: Gt } = Object, le = globalThis, Ke = le.trustedTypes, Yt = Ke ? Ke.emptyScript : "", Qt = le.reactiveElementPolyfillSupport, K = (e, t) => e, re = { toAttribute(e, t) { switch (t) { case Boolean: - e = e ? Kt : null; + e = e ? Yt : null; break; case Object: case Array: @@ -64,55 +64,55 @@ const { is: Ut, defineProperty: zt, getOwnPropertyDescriptor: Ft, getOwnProperty } } return i; -} }, Te = (e, t) => !Ut(e, t), Be = { attribute: !0, type: String, converter: ne, reflect: !1, useDefault: !1, hasChanged: Te }; -Symbol.metadata ??= /* @__PURE__ */ Symbol("metadata"), ce.litPropertyMetadata ??= /* @__PURE__ */ new WeakMap(); -let U = class extends HTMLElement { +} }, xe = (e, t) => !Bt(e, t), We = { attribute: !0, type: String, converter: re, reflect: !1, useDefault: !1, hasChanged: xe }; +Symbol.metadata ??= /* @__PURE__ */ Symbol("metadata"), le.litPropertyMetadata ??= /* @__PURE__ */ new WeakMap(); +let z = class extends HTMLElement { static addInitializer(t) { this._$Ei(), (this.l ??= []).push(t); } static get observedAttributes() { return this.finalize(), this._$Eh && [...this._$Eh.keys()]; } - static createProperty(t, i = Be) { + static createProperty(t, i = We) { if (i.state && (i.attribute = !1), this._$Ei(), this.prototype.hasOwnProperty(t) && ((i = Object.create(i)).wrapped = !0), this.elementProperties.set(t, i), !i.noAccessor) { - const o = /* @__PURE__ */ Symbol(), s = this.getPropertyDescriptor(t, o, i); - s !== void 0 && zt(this.prototype, t, s); + const o = /* @__PURE__ */ Symbol(), n = this.getPropertyDescriptor(t, o, i); + n !== void 0 && Kt(this.prototype, t, n); } } static getPropertyDescriptor(t, i, o) { - const { get: s, set: n } = Ft(this.prototype, t) ?? { get() { + const { get: n, set: s } = Wt(this.prototype, t) ?? { get() { return this[i]; }, set(a) { this[i] = a; } }; - return { get: s, set(a) { - const l = s?.call(this); - n?.call(this, a), this.requestUpdate(t, l, o); + return { get: n, set(a) { + const l = n?.call(this); + s?.call(this, a), this.requestUpdate(t, l, o); }, configurable: !0, enumerable: !0 }; } static getPropertyOptions(t) { - return this.elementProperties.get(t) ?? Be; + return this.elementProperties.get(t) ?? We; } static _$Ei() { - if (this.hasOwnProperty(B("elementProperties"))) return; - const t = Bt(this); + if (this.hasOwnProperty(K("elementProperties"))) return; + const t = Gt(this); t.finalize(), t.l !== void 0 && (this.l = [...t.l]), this.elementProperties = new Map(t.elementProperties); } static finalize() { - if (this.hasOwnProperty(B("finalized"))) return; - if (this.finalized = !0, this._$Ei(), this.hasOwnProperty(B("properties"))) { - const i = this.properties, o = [...Nt(i), ...qt(i)]; - for (const s of o) this.createProperty(s, i[s]); + if (this.hasOwnProperty(K("finalized"))) return; + if (this.finalized = !0, this._$Ei(), this.hasOwnProperty(K("properties"))) { + const i = this.properties, o = [...jt(i), ...Zt(i)]; + for (const n of o) this.createProperty(n, i[n]); } const t = this[Symbol.metadata]; if (t !== null) { const i = litPropertyMetadata.get(t); - if (i !== void 0) for (const [o, s] of i) this.elementProperties.set(o, s); + if (i !== void 0) for (const [o, n] of i) this.elementProperties.set(o, n); } this._$Eh = /* @__PURE__ */ new Map(); for (const [i, o] of this.elementProperties) { - const s = this._$Eu(i, o); - s !== void 0 && this._$Eh.set(s, i); + const n = this._$Eu(i, o); + n !== void 0 && this._$Eh.set(n, i); } this.elementStyles = this.finalizeStyles(this.styles); } @@ -120,8 +120,8 @@ let U = class extends HTMLElement { const i = []; if (Array.isArray(t)) { const o = new Set(t.flat(1 / 0).reverse()); - for (const s of o) i.unshift(Ne(s)); - } else t !== void 0 && i.push(Ne(t)); + for (const n of o) i.unshift(Be(n)); + } else t !== void 0 && i.push(Be(t)); return i; } static _$Eu(t, i) { @@ -147,7 +147,7 @@ let U = class extends HTMLElement { } createRenderRoot() { const t = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions); - return Ot(t, this.constructor.elementStyles), t; + return qt(t, this.constructor.elementStyles), t; } connectedCallback() { this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(!0), this._$EO?.forEach((t) => t.hostConnected?.()); @@ -161,31 +161,31 @@ let U = class extends HTMLElement { this._$AK(t, o); } _$ET(t, i) { - const o = this.constructor.elementProperties.get(t), s = this.constructor._$Eu(t, o); - if (s !== void 0 && o.reflect === !0) { - const n = (o.converter?.toAttribute !== void 0 ? o.converter : ne).toAttribute(i, o.type); - this._$Em = t, n == null ? this.removeAttribute(s) : this.setAttribute(s, n), this._$Em = null; + const o = this.constructor.elementProperties.get(t), n = this.constructor._$Eu(t, o); + if (n !== void 0 && o.reflect === !0) { + const s = (o.converter?.toAttribute !== void 0 ? o.converter : re).toAttribute(i, o.type); + this._$Em = t, s == null ? this.removeAttribute(n) : this.setAttribute(n, s), this._$Em = null; } } _$AK(t, i) { - const o = this.constructor, s = o._$Eh.get(t); - if (s !== void 0 && this._$Em !== s) { - const n = o.getPropertyOptions(s), a = typeof n.converter == "function" ? { fromAttribute: n.converter } : n.converter?.fromAttribute !== void 0 ? n.converter : ne; - this._$Em = s; - const l = a.fromAttribute(i, n.type); - this[s] = l ?? this._$Ej?.get(s) ?? l, this._$Em = null; + const o = this.constructor, n = o._$Eh.get(t); + if (n !== void 0 && this._$Em !== n) { + const s = o.getPropertyOptions(n), a = typeof s.converter == "function" ? { fromAttribute: s.converter } : s.converter?.fromAttribute !== void 0 ? s.converter : re; + this._$Em = n; + const l = a.fromAttribute(i, s.type); + this[n] = l ?? this._$Ej?.get(n) ?? l, this._$Em = null; } } - requestUpdate(t, i, o, s = !1, n) { + requestUpdate(t, i, o, n = !1, s) { if (t !== void 0) { const a = this.constructor; - if (s === !1 && (n = this[t]), o ??= a.getPropertyOptions(t), !((o.hasChanged ?? Te)(n, i) || o.useDefault && o.reflect && n === this._$Ej?.get(t) && !this.hasAttribute(a._$Eu(t, o)))) return; + if (n === !1 && (s = this[t]), o ??= a.getPropertyOptions(t), !((o.hasChanged ?? xe)(s, i) || o.useDefault && o.reflect && s === this._$Ej?.get(t) && !this.hasAttribute(a._$Eu(t, o)))) return; this.C(t, i, o); } this.isUpdatePending === !1 && (this._$ES = this._$EP()); } - C(t, i, { useDefault: o, reflect: s, wrapped: n }, a) { - o && !(this._$Ej ??= /* @__PURE__ */ new Map()).has(t) && (this._$Ej.set(t, a ?? i ?? this[t]), n !== !0 || a !== void 0) || (this._$AL.has(t) || (this.hasUpdated || o || (i = void 0), this._$AL.set(t, i)), s === !0 && this._$Em !== t && (this._$Eq ??= /* @__PURE__ */ new Set()).add(t)); + C(t, i, { useDefault: o, reflect: n, wrapped: s }, a) { + o && !(this._$Ej ??= /* @__PURE__ */ new Map()).has(t) && (this._$Ej.set(t, a ?? i ?? this[t]), s !== !0 || a !== void 0) || (this._$AL.has(t) || (this.hasUpdated || o || (i = void 0), this._$AL.set(t, i)), n === !0 && this._$Em !== t && (this._$Eq ??= /* @__PURE__ */ new Set()).add(t)); } async _$EP() { this.isUpdatePending = !0; @@ -204,13 +204,13 @@ let U = class extends HTMLElement { if (!this.isUpdatePending) return; if (!this.hasUpdated) { if (this.renderRoot ??= this.createRenderRoot(), this._$Ep) { - for (const [s, n] of this._$Ep) this[s] = n; + for (const [n, s] of this._$Ep) this[n] = s; this._$Ep = void 0; } const o = this.constructor.elementProperties; - if (o.size > 0) for (const [s, n] of o) { - const { wrapped: a } = n, l = this[s]; - a !== !0 || this._$AL.has(s) || l === void 0 || this.C(s, void 0, n, l); + if (o.size > 0) for (const [n, s] of o) { + const { wrapped: a } = s, l = this[n]; + a !== !0 || this._$AL.has(n) || l === void 0 || this.C(n, void 0, s, l); } } let t = !1; @@ -247,70 +247,70 @@ let U = class extends HTMLElement { firstUpdated(t) { } }; -U.elementStyles = [], U.shadowRootOptions = { mode: "open" }, U[B("elementProperties")] = /* @__PURE__ */ new Map(), U[B("finalized")] = /* @__PURE__ */ new Map(), Wt?.({ ReactiveElement: U }), (ce.reactiveElementVersions ??= []).push("2.1.2"); -const Ce = globalThis, Ke = (e) => e, re = Ce.trustedTypes, We = re ? re.createPolicy("lit-html", { createHTML: (e) => e }) : void 0, ut = "$lit$", L = `lit$${Math.random().toFixed(9).slice(2)}$`, pt = "?" + L, jt = `<${pt}>`, H = document, K = () => H.createComment(""), W = (e) => e === null || typeof e != "object" && typeof e != "function", xe = Array.isArray, Zt = (e) => xe(e) || typeof e?.[Symbol.iterator] == "function", pe = `[ -\f\r]`, q = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, je = /-->/g, Ze = />/g, I = RegExp(`>|${pe}(?:([^\\s"'>=/]+)(${pe}*=${pe}*(?:[^ -\f\r"'\`<>=]|("|')|))|$)`, "g"), Ge = /'/g, Ye = /"/g, vt = /^(?:script|style|textarea|title)$/i, Gt = (e) => (t, ...i) => ({ _$litType$: e, strings: t, values: i }), h = Gt(1), P = /* @__PURE__ */ Symbol.for("lit-noChange"), c = /* @__PURE__ */ Symbol.for("lit-nothing"), Qe = /* @__PURE__ */ new WeakMap(), V = H.createTreeWalker(H, 129); -function gt(e, t) { - if (!xe(e) || !e.hasOwnProperty("raw")) throw Error("invalid template strings array"); - return We !== void 0 ? We.createHTML(t) : t; +z.elementStyles = [], z.shadowRootOptions = { mode: "open" }, z[K("elementProperties")] = /* @__PURE__ */ new Map(), z[K("finalized")] = /* @__PURE__ */ new Map(), Qt?.({ ReactiveElement: z }), (le.reactiveElementVersions ??= []).push("2.1.2"); +const Re = globalThis, je = (e) => e, ae = Re.trustedTypes, Ze = ae ? ae.createPolicy("lit-html", { createHTML: (e) => e }) : void 0, ft = "$lit$", L = `lit$${Math.random().toFixed(9).slice(2)}$`, gt = "?" + L, Jt = `<${gt}>`, O = document, W = () => O.createComment(""), j = (e) => e === null || typeof e != "object" && typeof e != "function", Ee = Array.isArray, Xt = (e) => Ee(e) || typeof e?.[Symbol.iterator] == "function", ve = `[ +\f\r]`, B = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, Ge = /-->/g, Ye = />/g, I = RegExp(`>|${ve}(?:([^\\s"'>=/]+)(${ve}*=${ve}*(?:[^ +\f\r"'\`<>=]|("|')|))|$)`, "g"), Qe = /'/g, Je = /"/g, mt = /^(?:script|style|textarea|title)$/i, ei = (e) => (t, ...i) => ({ _$litType$: e, strings: t, values: i }), h = ei(1), P = /* @__PURE__ */ Symbol.for("lit-noChange"), c = /* @__PURE__ */ Symbol.for("lit-nothing"), Xe = /* @__PURE__ */ new WeakMap(), V = O.createTreeWalker(O, 129); +function _t(e, t) { + if (!Ee(e) || !e.hasOwnProperty("raw")) throw Error("invalid template strings array"); + return Ze !== void 0 ? Ze.createHTML(t) : t; } -const Yt = (e, t) => { +const ti = (e, t) => { const i = e.length - 1, o = []; - let s, n = t === 2 ? "" : t === 3 ? "" : "", a = q; + let n, s = t === 2 ? "" : t === 3 ? "" : "", a = B; for (let l = 0; l < i; l++) { const d = e[l]; - let p, v, g = -1, A = 0; - for (; A < d.length && (a.lastIndex = A, v = a.exec(d), v !== null); ) A = a.lastIndex, a === q ? v[1] === "!--" ? a = je : v[1] !== void 0 ? a = Ze : v[2] !== void 0 ? (vt.test(v[2]) && (s = RegExp("" ? (a = s ?? q, g = -1) : v[1] === void 0 ? g = -2 : (g = a.lastIndex - v[2].length, p = v[1], a = v[3] === void 0 ? I : v[3] === '"' ? Ye : Ge) : a === Ye || a === Ge ? a = I : a === je || a === Ze ? a = q : (a = I, s = void 0); + let p, v, f = -1, A = 0; + for (; A < d.length && (a.lastIndex = A, v = a.exec(d), v !== null); ) A = a.lastIndex, a === B ? v[1] === "!--" ? a = Ge : v[1] !== void 0 ? a = Ye : v[2] !== void 0 ? (mt.test(v[2]) && (n = RegExp("" ? (a = n ?? B, f = -1) : v[1] === void 0 ? f = -2 : (f = a.lastIndex - v[2].length, p = v[1], a = v[3] === void 0 ? I : v[3] === '"' ? Je : Qe) : a === Je || a === Qe ? a = I : a === Ge || a === Ye ? a = B : (a = I, n = void 0); const T = a === I && e[l + 1].startsWith("/>") ? " " : ""; - n += a === q ? d + jt : g >= 0 ? (o.push(p), d.slice(0, g) + ut + d.slice(g) + L + T) : d + L + (g === -2 ? l : T); + s += a === B ? d + Jt : f >= 0 ? (o.push(p), d.slice(0, f) + ft + d.slice(f) + L + T) : d + L + (f === -2 ? l : T); } - return [gt(e, n + (e[i] || "") + (t === 2 ? "" : t === 3 ? "" : "")), o]; + return [_t(e, s + (e[i] || "") + (t === 2 ? "" : t === 3 ? "" : "")), o]; }; -class j { +class Z { constructor({ strings: t, _$litType$: i }, o) { - let s; + let n; this.parts = []; - let n = 0, a = 0; - const l = t.length - 1, d = this.parts, [p, v] = Yt(t, i); - if (this.el = j.createElement(p, o), V.currentNode = this.el.content, i === 2 || i === 3) { - const g = this.el.content.firstChild; - g.replaceWith(...g.childNodes); + let s = 0, a = 0; + const l = t.length - 1, d = this.parts, [p, v] = ti(t, i); + if (this.el = Z.createElement(p, o), V.currentNode = this.el.content, i === 2 || i === 3) { + const f = this.el.content.firstChild; + f.replaceWith(...f.childNodes); } - for (; (s = V.nextNode()) !== null && d.length < l; ) { - if (s.nodeType === 1) { - if (s.hasAttributes()) for (const g of s.getAttributeNames()) if (g.endsWith(ut)) { - const A = v[a++], T = s.getAttribute(g).split(L), X = /([.?@])?(.*)/.exec(A); - d.push({ type: 1, index: n, name: X[2], strings: T, ctor: X[1] === "." ? Jt : X[1] === "?" ? Xt : X[1] === "@" ? ei : le }), s.removeAttribute(g); - } else g.startsWith(L) && (d.push({ type: 6, index: n }), s.removeAttribute(g)); - if (vt.test(s.tagName)) { - const g = s.textContent.split(L), A = g.length - 1; + for (; (n = V.nextNode()) !== null && d.length < l; ) { + if (n.nodeType === 1) { + if (n.hasAttributes()) for (const f of n.getAttributeNames()) if (f.endsWith(ft)) { + const A = v[a++], T = n.getAttribute(f).split(L), X = /([.?@])?(.*)/.exec(A); + d.push({ type: 1, index: s, name: X[2], strings: T, ctor: X[1] === "." ? oi : X[1] === "?" ? ni : X[1] === "@" ? si : he }), n.removeAttribute(f); + } else f.startsWith(L) && (d.push({ type: 6, index: s }), n.removeAttribute(f)); + if (mt.test(n.tagName)) { + const f = n.textContent.split(L), A = f.length - 1; if (A > 0) { - s.textContent = re ? re.emptyScript : ""; - for (let T = 0; T < A; T++) s.append(g[T], K()), V.nextNode(), d.push({ type: 2, index: ++n }); - s.append(g[A], K()); + n.textContent = ae ? ae.emptyScript : ""; + for (let T = 0; T < A; T++) n.append(f[T], W()), V.nextNode(), d.push({ type: 2, index: ++s }); + n.append(f[A], W()); } } - } else if (s.nodeType === 8) if (s.data === pt) d.push({ type: 2, index: n }); + } else if (n.nodeType === 8) if (n.data === gt) d.push({ type: 2, index: s }); else { - let g = -1; - for (; (g = s.data.indexOf(L, g + 1)) !== -1; ) d.push({ type: 7, index: n }), g += L.length - 1; + let f = -1; + for (; (f = n.data.indexOf(L, f + 1)) !== -1; ) d.push({ type: 7, index: s }), f += L.length - 1; } - n++; + s++; } } static createElement(t, i) { - const o = H.createElement("template"); + const o = O.createElement("template"); return o.innerHTML = t, o; } } -function z(e, t, i = e, o) { +function F(e, t, i = e, o) { if (t === P) return t; - let s = o !== void 0 ? i._$Co?.[o] : i._$Cl; - const n = W(t) ? void 0 : t._$litDirective$; - return s?.constructor !== n && (s?._$AO?.(!1), n === void 0 ? s = void 0 : (s = new n(e), s._$AT(e, i, o)), o !== void 0 ? (i._$Co ??= [])[o] = s : i._$Cl = s), s !== void 0 && (t = z(e, s._$AS(e, t.values), s, o)), t; + let n = o !== void 0 ? i._$Co?.[o] : i._$Cl; + const s = j(t) ? void 0 : t._$litDirective$; + return n?.constructor !== s && (n?._$AO?.(!1), s === void 0 ? n = void 0 : (n = new s(e), n._$AT(e, i, o)), o !== void 0 ? (i._$Co ??= [])[o] = n : i._$Cl = n), n !== void 0 && (t = F(e, n._$AS(e, t.values), n, o)), t; } -class Qt { +class ii { constructor(t, i) { this._$AV = [], this._$AN = void 0, this._$AD = t, this._$AM = i; } @@ -321,17 +321,17 @@ class Qt { return this._$AM._$AU; } u(t) { - const { el: { content: i }, parts: o } = this._$AD, s = (t?.creationScope ?? H).importNode(i, !0); - V.currentNode = s; - let n = V.nextNode(), a = 0, l = 0, d = o[0]; + const { el: { content: i }, parts: o } = this._$AD, n = (t?.creationScope ?? O).importNode(i, !0); + V.currentNode = n; + let s = V.nextNode(), a = 0, l = 0, d = o[0]; for (; d !== void 0; ) { if (a === d.index) { let p; - d.type === 2 ? p = new Q(n, n.nextSibling, this, t) : d.type === 1 ? p = new d.ctor(n, d.name, d.strings, this, t) : d.type === 6 && (p = new ti(n, this, t)), this._$AV.push(p), d = o[++l]; + d.type === 2 ? p = new Q(s, s.nextSibling, this, t) : d.type === 1 ? p = new d.ctor(s, d.name, d.strings, this, t) : d.type === 6 && (p = new ri(s, this, t)), this._$AV.push(p), d = o[++l]; } - a !== d?.index && (n = V.nextNode(), a++); + a !== d?.index && (s = V.nextNode(), a++); } - return V.currentNode = H, s; + return V.currentNode = O, n; } p(t) { let i = 0; @@ -342,8 +342,8 @@ class Q { get _$AU() { return this._$AM?._$AU ?? this._$Cv; } - constructor(t, i, o, s) { - this.type = 2, this._$AH = c, this._$AN = void 0, this._$AA = t, this._$AB = i, this._$AM = o, this.options = s, this._$Cv = s?.isConnected ?? !0; + constructor(t, i, o, n) { + this.type = 2, this._$AH = c, this._$AN = void 0, this._$AA = t, this._$AB = i, this._$AM = o, this.options = n, this._$Cv = n?.isConnected ?? !0; } get parentNode() { let t = this._$AA.parentNode; @@ -357,7 +357,7 @@ class Q { return this._$AB; } _$AI(t, i = this) { - t = z(this, t, i), W(t) ? t === c || t == null || t === "" ? (this._$AH !== c && this._$AR(), this._$AH = c) : t !== this._$AH && t !== P && this._(t) : t._$litType$ !== void 0 ? this.$(t) : t.nodeType !== void 0 ? this.T(t) : Zt(t) ? this.k(t) : this._(t); + t = F(this, t, i), j(t) ? t === c || t == null || t === "" ? (this._$AH !== c && this._$AR(), this._$AH = c) : t !== this._$AH && t !== P && this._(t) : t._$litType$ !== void 0 ? this.$(t) : t.nodeType !== void 0 ? this.T(t) : Xt(t) ? this.k(t) : this._(t); } O(t) { return this._$AA.parentNode.insertBefore(t, this._$AB); @@ -366,63 +366,63 @@ class Q { this._$AH !== t && (this._$AR(), this._$AH = this.O(t)); } _(t) { - this._$AH !== c && W(this._$AH) ? this._$AA.nextSibling.data = t : this.T(H.createTextNode(t)), this._$AH = t; + this._$AH !== c && j(this._$AH) ? this._$AA.nextSibling.data = t : this.T(O.createTextNode(t)), this._$AH = t; } $(t) { - const { values: i, _$litType$: o } = t, s = typeof o == "number" ? this._$AC(t) : (o.el === void 0 && (o.el = j.createElement(gt(o.h, o.h[0]), this.options)), o); - if (this._$AH?._$AD === s) this._$AH.p(i); + const { values: i, _$litType$: o } = t, n = typeof o == "number" ? this._$AC(t) : (o.el === void 0 && (o.el = Z.createElement(_t(o.h, o.h[0]), this.options)), o); + if (this._$AH?._$AD === n) this._$AH.p(i); else { - const n = new Qt(s, this), a = n.u(this.options); - n.p(i), this.T(a), this._$AH = n; + const s = new ii(n, this), a = s.u(this.options); + s.p(i), this.T(a), this._$AH = s; } } _$AC(t) { - let i = Qe.get(t.strings); - return i === void 0 && Qe.set(t.strings, i = new j(t)), i; + let i = Xe.get(t.strings); + return i === void 0 && Xe.set(t.strings, i = new Z(t)), i; } k(t) { - xe(this._$AH) || (this._$AH = [], this._$AR()); + Ee(this._$AH) || (this._$AH = [], this._$AR()); const i = this._$AH; - let o, s = 0; - for (const n of t) s === i.length ? i.push(o = new Q(this.O(K()), this.O(K()), this, this.options)) : o = i[s], o._$AI(n), s++; - s < i.length && (this._$AR(o && o._$AB.nextSibling, s), i.length = s); + let o, n = 0; + for (const s of t) n === i.length ? i.push(o = new Q(this.O(W()), this.O(W()), this, this.options)) : o = i[n], o._$AI(s), n++; + n < i.length && (this._$AR(o && o._$AB.nextSibling, n), i.length = n); } _$AR(t = this._$AA.nextSibling, i) { for (this._$AP?.(!1, !0, i); t !== this._$AB; ) { - const o = Ke(t).nextSibling; - Ke(t).remove(), t = o; + const o = je(t).nextSibling; + je(t).remove(), t = o; } } setConnected(t) { this._$AM === void 0 && (this._$Cv = t, this._$AP?.(t)); } } -class le { +class he { get tagName() { return this.element.tagName; } get _$AU() { return this._$AM._$AU; } - constructor(t, i, o, s, n) { - this.type = 1, this._$AH = c, this._$AN = void 0, this.element = t, this.name = i, this._$AM = s, this.options = n, o.length > 2 || o[0] !== "" || o[1] !== "" ? (this._$AH = Array(o.length - 1).fill(new String()), this.strings = o) : this._$AH = c; + constructor(t, i, o, n, s) { + this.type = 1, this._$AH = c, this._$AN = void 0, this.element = t, this.name = i, this._$AM = n, this.options = s, o.length > 2 || o[0] !== "" || o[1] !== "" ? (this._$AH = Array(o.length - 1).fill(new String()), this.strings = o) : this._$AH = c; } - _$AI(t, i = this, o, s) { - const n = this.strings; + _$AI(t, i = this, o, n) { + const s = this.strings; let a = !1; - if (n === void 0) t = z(this, t, i, 0), a = !W(t) || t !== this._$AH && t !== P, a && (this._$AH = t); + if (s === void 0) t = F(this, t, i, 0), a = !j(t) || t !== this._$AH && t !== P, a && (this._$AH = t); else { const l = t; let d, p; - for (t = n[0], d = 0; d < n.length - 1; d++) p = z(this, l[o + d], i, d), p === P && (p = this._$AH[d]), a ||= !W(p) || p !== this._$AH[d], p === c ? t = c : t !== c && (t += (p ?? "") + n[d + 1]), this._$AH[d] = p; + for (t = s[0], d = 0; d < s.length - 1; d++) p = F(this, l[o + d], i, d), p === P && (p = this._$AH[d]), a ||= !j(p) || p !== this._$AH[d], p === c ? t = c : t !== c && (t += (p ?? "") + s[d + 1]), this._$AH[d] = p; } - a && !s && this.j(t); + a && !n && this.j(t); } j(t) { t === c ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t ?? ""); } } -class Jt extends le { +class oi extends he { constructor() { super(...arguments), this.type = 3; } @@ -430,7 +430,7 @@ class Jt extends le { this.element[this.name] = t === c ? void 0 : t; } } -class Xt extends le { +class ni extends he { constructor() { super(...arguments), this.type = 4; } @@ -438,20 +438,20 @@ class Xt extends le { this.element.toggleAttribute(this.name, !!t && t !== c); } } -class ei extends le { - constructor(t, i, o, s, n) { - super(t, i, o, s, n), this.type = 5; +class si extends he { + constructor(t, i, o, n, s) { + super(t, i, o, n, s), this.type = 5; } _$AI(t, i = this) { - if ((t = z(this, t, i, 0) ?? c) === P) return; - const o = this._$AH, s = t === c && o !== c || t.capture !== o.capture || t.once !== o.once || t.passive !== o.passive, n = t !== c && (o === c || s); - s && this.element.removeEventListener(this.name, this, o), n && this.element.addEventListener(this.name, this, t), this._$AH = t; + if ((t = F(this, t, i, 0) ?? c) === P) return; + const o = this._$AH, n = t === c && o !== c || t.capture !== o.capture || t.once !== o.once || t.passive !== o.passive, s = t !== c && (o === c || n); + n && this.element.removeEventListener(this.name, this, o), s && this.element.addEventListener(this.name, this, t), this._$AH = t; } handleEvent(t) { typeof this._$AH == "function" ? this._$AH.call(this.options?.host ?? this.element, t) : this._$AH.handleEvent(t); } } -class ti { +class ri { constructor(t, i, o) { this.element = t, this.type = 6, this._$AN = void 0, this._$AM = i, this.options = o; } @@ -459,22 +459,22 @@ class ti { return this._$AM._$AU; } _$AI(t) { - z(this, t); + F(this, t); } } -const ii = Ce.litHtmlPolyfillSupport; -ii?.(j, Q), (Ce.litHtmlVersions ??= []).push("3.3.3"); -const oi = (e, t, i) => { +const ai = Re.litHtmlPolyfillSupport; +ai?.(Z, Q), (Re.litHtmlVersions ??= []).push("3.3.3"); +const di = (e, t, i) => { const o = i?.renderBefore ?? t; - let s = o._$litPart$; - if (s === void 0) { - const n = i?.renderBefore ?? null; - o._$litPart$ = s = new Q(t.insertBefore(K(), n), n, void 0, i ?? {}); + let n = o._$litPart$; + if (n === void 0) { + const s = i?.renderBefore ?? null; + o._$litPart$ = n = new Q(t.insertBefore(W(), s), s, void 0, i ?? {}); } - return s._$AI(e), s; + return n._$AI(e), n; }; -const Re = globalThis; -let x = class extends U { +const Le = globalThis; +let x = class extends z { constructor() { super(...arguments), this.renderOptions = { host: this }, this._$Do = void 0; } @@ -484,7 +484,7 @@ let x = class extends U { } update(t) { const i = this.render(); - this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t), this._$Do = oi(i, this.renderRoot, this.renderOptions); + this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t), this._$Do = di(i, this.renderRoot, this.renderOptions); } connectedCallback() { super.connectedCallback(), this._$Do?.setConnected(!0); @@ -496,12 +496,12 @@ let x = class extends U { return P; } }; -x._$litElement$ = !0, x.finalized = !0, Re.litElementHydrateSupport?.({ LitElement: x }); -const si = Re.litElementPolyfillSupport; -si?.({ LitElement: x }); -(Re.litElementVersions ??= []).push("4.2.2"); -const ft = { ATTRIBUTE: 1 }, Ee = (e) => (...t) => ({ _$litDirective$: e, values: t }); -let Le = class { +x._$litElement$ = !0, x.finalized = !0, Le.litElementHydrateSupport?.({ LitElement: x }); +const ci = Le.litElementPolyfillSupport; +ci?.({ LitElement: x }); +(Le.litElementVersions ??= []).push("4.2.2"); +const bt = { ATTRIBUTE: 1 }, Pe = (e) => (...t) => ({ _$litDirective$: e, values: t }); +let Me = class { constructor(t) { } get _$AU() { @@ -517,9 +517,9 @@ let Le = class { return this.render(...i); } }; -const mt = "important", ni = " !" + mt, fe = Ee(class extends Le { +const wt = "important", li = " !" + wt, me = Pe(class extends Me { constructor(e) { - if (super(e), e.type !== ft.ATTRIBUTE || e.name !== "style" || e.strings?.length > 2) throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute."); + if (super(e), e.type !== bt.ATTRIBUTE || e.name !== "style" || e.strings?.length > 2) throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute."); } render(e) { return Object.keys(e).reduce((t, i) => { @@ -532,25 +532,25 @@ const mt = "important", ni = " !" + mt, fe = Ee(class extends Le { if (this.ft === void 0) return this.ft = new Set(Object.keys(t)), this.render(t); for (const o of this.ft) t[o] == null && (this.ft.delete(o), o.includes("-") ? i.removeProperty(o) : i[o] = null); for (const o in t) { - const s = t[o]; - if (s != null) { + const n = t[o]; + if (n != null) { this.ft.add(o); - const n = typeof s == "string" && s.endsWith(ni); - o.includes("-") || n ? i.setProperty(o, n ? s.slice(0, -11) : s, n ? mt : "") : i[o] = s; + const s = typeof n == "string" && n.endsWith(li); + o.includes("-") || s ? i.setProperty(o, s ? n.slice(0, -11) : n, s ? wt : "") : i[o] = n; } } return P; } }); -const N = (e) => (t, i) => { +const q = (e) => (t, i) => { i !== void 0 ? i.addInitializer(() => { customElements.define(e, t); }) : customElements.define(e, t); }; -const ri = { attribute: !0, type: String, converter: ne, reflect: !1, hasChanged: Te }, ai = (e = ri, t, i) => { - const { kind: o, metadata: s } = i; - let n = globalThis.litPropertyMetadata.get(s); - if (n === void 0 && globalThis.litPropertyMetadata.set(s, n = /* @__PURE__ */ new Map()), o === "setter" && ((e = Object.create(e)).wrapped = !0), n.set(i.name, e), o === "accessor") { +const hi = { attribute: !0, type: String, converter: re, reflect: !1, hasChanged: xe }, ui = (e = hi, t, i) => { + const { kind: o, metadata: n } = i; + let s = globalThis.litPropertyMetadata.get(n); + if (s === void 0 && globalThis.litPropertyMetadata.set(n, s = /* @__PURE__ */ new Map()), o === "setter" && ((e = Object.create(e)).wrapped = !0), s.set(i.name, e), o === "accessor") { const { name: a } = i; return { set(l) { const d = t.get.call(this); @@ -569,15 +569,15 @@ const ri = { attribute: !0, type: String, converter: ne, reflect: !1, hasChanged throw Error("Unsupported decorator location: " + o); }; function _(e) { - return (t, i) => typeof i == "object" ? ai(e, t, i) : ((o, s, n) => { - const a = s.hasOwnProperty(n); - return s.constructor.createProperty(n, o), a ? Object.getOwnPropertyDescriptor(s, n) : void 0; + return (t, i) => typeof i == "object" ? ui(e, t, i) : ((o, n, s) => { + const a = n.hasOwnProperty(s); + return n.constructor.createProperty(s, o), a ? Object.getOwnPropertyDescriptor(n, s) : void 0; })(e, t, i); } function u(e) { return _({ ...e, state: !0, attribute: !1 }); } -const di = ` +const pi = ` @@ -608,7 +608,7 @@ const di = ` -`, ci = { +`, vi = { "common.camera": "Kamera", "common.close": "Schließen", "common.last_recording": "Letzte Aufnahme", @@ -675,7 +675,7 @@ const di = ` "u" ? void 0 : document.documentElement.lang, i = typeof navigator > "u" ? void 0 : navigator.language; return e?.language || e?.locale?.language || t || i || "en"; } -function _t(e) { - return hi(e).trim().toLowerCase().split(/[-_]/)[0] === "de" ? "de" : "en"; +function yt(e) { + return gi(e).trim().toLowerCase().split(/[-_]/)[0] === "de" ? "de" : "en"; } function r(e, t, i = {}) { - return (Je[_t(e)][t] ?? Je.en[t]).replace( + return (et[yt(e)][t] ?? et.en[t]).replace( /\{([a-z_]+)\}/gi, - (s, n) => n in i ? String(i[n]) : s + (n, s) => s in i ? String(i[s]) : n ); } -function bt(e, t, i) { +function kt(e, t, i) { return e?.localize?.(t) || r(e, i); } -const ui = /^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(Z|[+-]\d{2}:?\d{2})?$/i, pi = /^-?\d+(?:\.\d+)?$/, vi = 1e11; -function gi(e) { - const t = Number(e[1]), i = Number(e[2]), o = Number(e[3]), s = Number(e[4]), n = Number(e[5]), a = Number(e[6] ?? 0), l = new Date(Date.UTC(t, i, 0)).getUTCDate(); - return i >= 1 && i <= 12 && o >= 1 && o <= l && s >= 0 && s <= 23 && n >= 0 && n <= 59 && a >= 0 && a <= 59; +function mi(e) { + return e?.platform === "ring" ? "official_ring" : e?.platform === "mqtt" ? "mqtt" : "other"; +} +function _e(e, t, i) { + const o = e.entities?.[i]; + return { + role: t, + entityId: i, + entity: e.states[i], + registry: o, + provider: mi(o), + deviceId: o?.device_id ?? void 0 + }; +} +function _i(e, t) { + const i = e.entities?.[t]?.device_id; + return i ? Object.values(e.entities ?? {}).filter((o) => o.device_id === i && o.disabled_by == null && !!e.states[o.entity_id]).map((o) => o.entity_id).sort() : []; +} +const bi = /^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(Z|[+-]\d{2}:?\d{2})?$/i, wi = /^-?\d+(?:\.\d+)?$/, yi = 1e11, ki = [ + "lastDingTime", + "lastMotionTime", + "lastDing", + "lastMotion" +], At = /* @__PURE__ */ new Set(["unknown", "unavailable"]); +function Ai(e) { + const t = Number(e[1]), i = Number(e[2]), o = Number(e[3]), n = Number(e[4]), s = Number(e[5]), a = Number(e[6] ?? 0), l = new Date(Date.UTC(t, i, 0)).getUTCDate(); + return i >= 1 && i <= 12 && o >= 1 && o <= l && n >= 0 && n <= 23 && s >= 0 && s <= 59 && a >= 0 && a <= 59; } -function fi(e) { +function St(e) { if (typeof e != "string" && typeof e != "number") return; const t = String(e).trim(); if (!t || ["unknown", "unavailable", "none", "null"].includes(t.toLowerCase())) return; - if (pi.test(t)) { - const n = Number(t); - if (!Number.isFinite(n)) return; - const a = Math.abs(n) < vi ? n * 1e3 : n; + if (wi.test(t)) { + const s = Number(t); + if (!Number.isFinite(s)) return; + const a = Math.abs(s) < yi ? s * 1e3 : s; return Number.isFinite(new Date(a).getTime()) ? a : void 0; } - const i = t.match(ui); - if (!i || !gi(i)) return; - const o = t.includes(" ") ? t.replace(" ", "T") : t, s = Date.parse(o); - return Number.isFinite(s) ? s : void 0; + const i = t.match(bi); + if (!i || !Ai(i)) return; + const o = t.includes(" ") ? t.replace(" ", "T") : t, n = Date.parse(o); + return Number.isFinite(n) ? n : void 0; } -function Z(e) { - return fi(e?.state); +function Si(e) { + return St(e?.state); } -function mi(e) { +function oe(e) { + const t = e.filter((i) => i !== void 0); + return t.length > 0 ? Math.max(...t) : void 0; +} +function tt(e) { + if (!(!e || At.has(e.state))) + return oe( + ki.map( + (t) => St(e.attributes[t]) + ) + ); +} +function H(e, t) { + const i = e.states[t], o = i && !At.has(i.state), n = o ? [Si(i)] : []; + if (!t.startsWith("binary_sensor.") || (o && n.push(tt(i)), _e(e, "activity", t).provider !== "mqtt")) return oe(n); + for (const a of _i(e, t)) + a === t || !a.startsWith("binary_sensor.") || _e(e, "activity", a).provider !== "mqtt" || n.push(tt(e.states[a])); + return oe(n); +} +function $i(e) { const t = Math.abs(e); return t < 60 ? { unit: "second", seconds: 1 } : t < 3600 ? { unit: "minute", seconds: 60 } : t < 86400 ? { unit: "hour", seconds: 3600 } : t < 2629746 ? { unit: "day", seconds: 86400 } : t < 31556952 ? { unit: "month", seconds: 2629746 } : { unit: "year", seconds: 31556952 }; } -function _i(e, t) { +function Ti(e, t) { const i = Math.trunc(e / t); return Object.is(i, -0) ? 0 : i; } -function wt(e, t, i = Date.now()) { - const o = _t(e), s = (t - i) / 1e3, { unit: n, seconds: a } = mi(s), l = _i(s, a), d = new Intl.RelativeTimeFormat(o, { +function $t(e, t, i = Date.now()) { + const o = yt(e), n = (t - i) / 1e3, { unit: s, seconds: a } = $i(n), l = Ti(n, a), d = new Intl.RelativeTimeFormat(o, { numeric: "auto", style: "short" - }).format(l, n), p = o === "en" ? d.replace(/\b(sec|min|hr)\./g, "$1") : d, v = new Intl.RelativeTimeFormat(o, { + }).format(l, s), p = o === "en" ? d.replace(/\b(sec|min|hr)\./g, "$1") : d, v = new Intl.RelativeTimeFormat(o, { numeric: "auto", style: "long" - }).format(l, n), g = new Intl.DateTimeFormat(o, { + }).format(l, s), f = new Intl.DateTimeFormat(o, { dateStyle: "medium", timeStyle: "short" }).format(t); @@ -1074,25 +1116,23 @@ function wt(e, t, i = Date.now()) { accessible: r(e, "activity.accessible", { time: v }), - title: r(e, "activity.title", { time: g }) + title: r(e, "activity.title", { time: f }) }; } -var bi = Object.defineProperty, wi = Object.getOwnPropertyDescriptor, Pe = (e, t, i, o) => { - for (var s = o > 1 ? void 0 : o ? wi(t, i) : t, n = e.length - 1, a; n >= 0; n--) - (a = e[n]) && (s = (o ? a(t, i, s) : a(s)) || s); - return o && s && bi(t, i, s), s; +var Ci = Object.defineProperty, xi = Object.getOwnPropertyDescriptor, De = (e, t, i, o) => { + for (var n = o > 1 ? void 0 : o ? xi(t, i) : t, s = e.length - 1, a; s >= 0; s--) + (a = e[s]) && (n = (o ? a(t, i, n) : a(n)) || n); + return o && n && Ci(t, i, n), n; }; -const yi = 3e4; +const Ri = 3e4; let G = class extends x { disconnectedCallback() { this.clearRefreshTimer(), super.disconnectedCallback(); } render() { - const e = Z( - this.entityId ? this.hass?.states[this.entityId] : void 0 - ); + const e = this.hass && this.entityId ? H(this.hass, this.entityId) : void 0; if (e === void 0) return c; - const t = wt(this.hass, e); + const t = $t(this.hass, e); return h` ${t.relative} @@ -1100,22 +1140,20 @@ let G = class extends x { `; } updated() { - this.clearRefreshTimer(), Z( - this.entityId ? this.hass?.states[this.entityId] : void 0 - ) !== void 0 && (this.refreshTimer = window.setTimeout(() => { + this.clearRefreshTimer(), (this.hass && this.entityId ? H(this.hass, this.entityId) : void 0) !== void 0 && (this.refreshTimer = window.setTimeout(() => { this.refreshTimer = void 0, this.requestUpdate(), this.dispatchEvent( new CustomEvent("ring-view-activity-tick", { bubbles: !0, composed: !0 }) ); - }, yi)); + }, Ri)); } clearRefreshTimer() { this.refreshTimer !== void 0 && (window.clearTimeout(this.refreshTimer), this.refreshTimer = void 0); } }; -G.styles = F` +G.styles = N` :host { display: block; min-width: 0; @@ -1137,163 +1175,149 @@ G.styles = F` white-space: nowrap; } `; -Pe([ +De([ _({ attribute: !1 }) ], G.prototype, "hass", 2); -Pe([ +De([ _({ attribute: "entity-id" }) ], G.prototype, "entityId", 2); -G = Pe([ - N("ring-view-activity-time") +G = De([ + q("ring-view-activity-time") ], G); -function ki(e) { - return e?.platform === "ring" ? "official_ring" : e?.platform === "mqtt" ? "mqtt" : "other"; -} -function Ai(e, t, i) { - const o = e.entities?.[i]; - return { - role: t, - entityId: i, - entity: e.states[i], - registry: o, - provider: ki(o), - deviceId: o?.device_id ?? void 0 - }; -} -const Si = 2, $i = 1; +const Ei = 2, Li = 1; function w(e) { return !e || e.state === "unavailable" || e.state === "unknown"; } -function yt(e) { - return (Number(e?.attributes.supported_features ?? 0) & Si) !== 0; +function Tt(e) { + return (Number(e?.attributes.supported_features ?? 0) & Ei) !== 0; } -function me(e, t) { - return Ai(e, "live", t).provider === "official_ring" && yt(e.states[t]); +function be(e, t) { + return _e(e, "live", t).provider === "official_ring" && Tt(e.states[t]); } -function oe(e) { - return (Number(e?.attributes.supported_features ?? 0) & $i) !== 0; +function ne(e) { + return (Number(e?.attributes.supported_features ?? 0) & Li) !== 0; } -function Ti(e) { +function Pi(e) { return !!(e?.attributes.video_url || e?.attributes.entity_picture); } -function Ci(e, t) { +function Mi(e, t) { if (!e || !t) return []; - const i = e.states[t.recording_entity], o = e.states[t.live_entity], s = []; - if (w(i) ? s.push({ + const i = e.states[t.recording_entity], o = e.states[t.live_entity], n = []; + if (w(i) ? n.push({ kind: "recording", message: r(e, "warning.unavailable", { name: S(i, t.recording_entity) }) - }) : Ti(i) || s.push({ + }) : Pi(i) || n.push({ kind: "recording", message: r(e, "warning.recording_media") - }), w(o) ? s.push({ + }), w(o) ? n.push({ kind: "live", message: r(e, "warning.unavailable", { name: S(o, t.live_entity) }) - }) : yt(o) ? t.two_way_audio && !me(e, t.live_entity) && s.push({ + }) : Tt(o) ? t.two_way_audio && !be(e, t.live_entity) && n.push({ kind: "talkback", message: r(e, "warning.talkback_unsupported") - }) : s.push({ + }) : n.push({ kind: "live", message: r(e, "warning.live_stream") }), t.snapshot_entity && ["snapshot", "newest"].includes(t.preview_source)) { - const n = e.states[t.snapshot_entity]; - w(n) && s.push({ + const s = e.states[t.snapshot_entity]; + w(s) && n.push({ kind: "snapshot", message: r(e, "warning.unavailable", { - name: S(n, t.snapshot_entity) + name: S(s, t.snapshot_entity) }) }); - } else ["snapshot", "newest"].includes(t.preview_source) && s.push({ + } else ["snapshot", "newest"].includes(t.preview_source) && n.push({ kind: "snapshot", message: r(e, "warning.snapshot_required") }); if (t.last_activity_entity) { - const n = e.states[t.last_activity_entity]; - w(n) ? s.push({ + const s = e.states[t.last_activity_entity]; + w(s) ? n.push({ kind: "last_activity", message: r(e, "warning.unavailable", { - name: S(n, t.last_activity_entity) + name: S(s, t.last_activity_entity) }) - }) : Z(n) === void 0 && s.push({ + }) : H(e, t.last_activity_entity) === void 0 && n.push({ kind: "last_activity", message: r(e, "warning.activity_timestamp") }); } if (t.doorbell_entity) { - const n = e.states[t.doorbell_entity]; - w(n) ? s.push({ + const s = e.states[t.doorbell_entity]; + w(s) ? n.push({ kind: "doorbell", message: r(e, "warning.unavailable", { - name: S(n, t.doorbell_entity) + name: S(s, t.doorbell_entity) }) - }) : Array.isArray(n?.attributes.event_types) && !n.attributes.event_types.includes("ring") && s.push({ + }) : Array.isArray(s?.attributes.event_types) && !s.attributes.event_types.includes("ring") && n.push({ kind: "doorbell", message: r(e, "warning.doorbell_event") }); } if (t.door_entity) { - const n = e.states[t.door_entity]; - w(n) ? s.push({ + const s = e.states[t.door_entity]; + w(s) ? n.push({ kind: "door", message: r(e, "warning.unavailable", { - name: S(n, t.door_entity) + name: S(s, t.door_entity) }) - }) : t.door_action === "open" && !oe(n) && s.push({ + }) : t.door_action === "open" && !ne(s) && n.push({ kind: "door", message: r(e, "warning.door_open_unsupported") }); } if (t.door_contact_entity) { - const n = e.states[t.door_contact_entity]; - w(n) && s.push({ + const s = e.states[t.door_contact_entity]; + w(s) && n.push({ kind: "door_contact", message: r(e, "warning.unavailable", { - name: S(n, t.door_contact_entity) + name: S(s, t.door_contact_entity) }) }); } - return customElements.get("ha-camera-stream") || s.push({ + return customElements.get("ha-camera-stream") || n.push({ kind: "compatibility", message: r(e, "warning.compatibility") - }), s; + }), n; } function S(e, t) { return e?.attributes.friendly_name || t; } -const xi = "/media/ring-view"; -function he(e) { +const Di = "/media/ring-view"; +function ue(e) { const t = e.trim(); return t.length > 1 ? t.replace(/\/+$/, "") : t; } -function Ri(e) { +function Ii(e) { if (typeof e != "string" || e.trim() === "") return "required"; - const t = he(e); + const t = ue(e); if (!t.startsWith("/")) return "absolute"; if (t === "/") return "root"; if (/[\u0000-\u001f\u007f]/.test(t) || t.includes("{{") || t.includes("}}") || t.split("/").some((i) => i === "." || i === "..")) return "unsafe"; } -function Ei(e) { - const t = he(e); +function Vi(e) { + const t = ue(e); if (t === "/config/www" || t.startsWith("/config/www/")) return "public"; if (!(t === "/media" || t.startsWith("/media/"))) return "custom"; } -function Li(e, t) { +function Hi(e, t) { return t.snapshot_entity && !w(e.states[t.snapshot_entity]) ? t.snapshot_entity : w(e.states[t.live_entity]) ? void 0 : t.live_entity; } -function Pi(e, t) { +function Oi(e, t) { const i = e.states[t.live_entity]; return (t.name || S(i, t.live_entity.split(".", 2)[1] || "ring-camera")).normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "") || "ring-camera"; } -function O(e, t) { +function U(e, t) { return e.find((i) => i.type === t)?.value ?? "00"; } -function Mi(e, t) { +function Ui(e, t) { const i = Number.isFinite(e.getTime()) ? e : /* @__PURE__ */ new Date(0), o = { timeZone: t, year: "numeric", @@ -1304,23 +1328,23 @@ function Mi(e, t) { second: "2-digit", hourCycle: "h23" }; - let s; + let n; try { - s = new Intl.DateTimeFormat("en-CA", o).formatToParts(i); + n = new Intl.DateTimeFormat("en-CA", o).formatToParts(i); } catch { - delete o.timeZone, s = new Intl.DateTimeFormat("en-CA", o).formatToParts(i); + delete o.timeZone, n = new Intl.DateTimeFormat("en-CA", o).formatToParts(i); } - const n = String(i.getMilliseconds()).padStart(3, "0"); + const s = String(i.getMilliseconds()).padStart(3, "0"); return [ - `${O(s, "year")}-${O(s, "month")}-${O(s, "day")}`, - `${O(s, "hour")}-${O(s, "minute")}-${O(s, "second")}-${n}` + `${U(n, "year")}-${U(n, "month")}-${U(n, "day")}`, + `${U(n, "hour")}-${U(n, "minute")}-${U(n, "second")}-${s}` ].join("_"); } -function Di(e, t, i = /* @__PURE__ */ new Date()) { - const o = he(t.snapshot_directory), s = Mi(i, e.config?.time_zone); - return `${o}/${Pi(e, t)}_${s}.jpg`; +function zi(e, t, i = /* @__PURE__ */ new Date()) { + const o = ue(t.snapshot_directory), n = Ui(i, e.config?.time_zone); + return `${o}/${Oi(e, t)}_${n}.jpg`; } -const Me = "custom:ring-view", _e = "ring-view", Ii = "Ring View", b = { +const Ie = "custom:ring-view", we = "ring-view", Fi = "Ring View", b = { default_mode: "last_recording", remember_last_mode: !1, autoplay_recording: !0, @@ -1337,20 +1361,20 @@ const Me = "custom:ring-view", _e = "ring-view", Ii = "Ring View", b = { preview_source: "last_recording", preview_fallback: "last_recording", show_snapshot_button: !1, - snapshot_directory: xi, + snapshot_directory: Di, aspect_ratio: "16:9", fit_mode: "cover" -}, Vi = /* @__PURE__ */ new Set(["last_recording", "live"]), Hi = /* @__PURE__ */ new Set([ +}, Ni = /* @__PURE__ */ new Set(["last_recording", "live"]), qi = /* @__PURE__ */ new Set([ "last_recording", "live", "default", "snapshot", "newest" -]), Oi = /* @__PURE__ */ new Set(["last_recording", "snapshot"]), Ui = /* @__PURE__ */ new Set(["auto", "16:9", "4:3", "1:1"]), zi = /* @__PURE__ */ new Set(["cover", "contain"]), Fi = /* @__PURE__ */ new Set(["unlock", "open"]), Ni = /* @__PURE__ */ new Set(["live_only", "all_views"]), qi = /* @__PURE__ */ new Set([ +]), Bi = /* @__PURE__ */ new Set(["last_recording", "snapshot"]), Ki = /* @__PURE__ */ new Set(["auto", "16:9", "4:3", "1:1"]), Wi = /* @__PURE__ */ new Set(["cover", "contain"]), ji = /* @__PURE__ */ new Set(["unlock", "open"]), Zi = /* @__PURE__ */ new Set(["live_only", "all_views"]), Gi = /* @__PURE__ */ new Set([ "viewer_only", "dashboard_and_viewer" -]), Bi = /* @__PURE__ */ new Set(["open_viewer", "interactive"]), Ki = /* @__PURE__ */ new Set(["on_demand", "last_recording", "live"]), Wi = ["event.", "binary_sensor."]; -function ve(e, t) { +]), Yi = /* @__PURE__ */ new Set(["open_viewer", "interactive"]), Qi = /* @__PURE__ */ new Set(["on_demand", "last_recording", "live"]), Ji = ["event.", "binary_sensor."]; +function fe(e, t) { if (typeof e != "string" || !e.startsWith("camera.")) throw new Error( r(void 0, "config.entity_required", { @@ -1358,48 +1382,48 @@ function ve(e, t) { }) ); } -function ji(e) { +function Xi(e) { if (!e || typeof e != "object") throw new Error(r(void 0, "config.invalid")); - if (ve(e.recording_entity, "config.recording_entity"), ve(e.live_entity, "config.live_entity"), e.snapshot_entity !== void 0 && e.snapshot_entity !== "" && ve(e.snapshot_entity, "config.snapshot_entity"), e.last_activity_entity !== void 0 && e.last_activity_entity !== "" && (typeof e.last_activity_entity != "string" || !/^[a-z0-9_]+\.[a-z0-9_]+$/i.test(e.last_activity_entity))) + if (fe(e.recording_entity, "config.recording_entity"), fe(e.live_entity, "config.live_entity"), e.snapshot_entity !== void 0 && e.snapshot_entity !== "" && fe(e.snapshot_entity, "config.snapshot_entity"), e.last_activity_entity !== void 0 && e.last_activity_entity !== "" && (typeof e.last_activity_entity != "string" || !/^[a-z0-9_]+\.[a-z0-9_]+$/i.test(e.last_activity_entity))) throw new Error(r(void 0, "config.last_activity_entity")); - if (e.default_mode && !Vi.has(e.default_mode)) + if (e.default_mode && !Ni.has(e.default_mode)) throw new Error(r(void 0, "config.default_mode")); - if (e.preview_source && !Hi.has(e.preview_source)) + if (e.preview_source && !qi.has(e.preview_source)) throw new Error(r(void 0, "config.preview_source")); - if (e.preview_fallback && !Oi.has(e.preview_fallback)) + if (e.preview_fallback && !Bi.has(e.preview_fallback)) throw new Error(r(void 0, "config.preview_fallback")); if (e.snapshot_directory !== void 0) { - const t = Ri(e.snapshot_directory); + const t = Ii(e.snapshot_directory); if (t) throw new Error( r(void 0, `config.snapshot_directory_${t}`) ); } - if (e.aspect_ratio && !Ui.has(e.aspect_ratio)) + if (e.aspect_ratio && !Ki.has(e.aspect_ratio)) throw new Error(r(void 0, "config.aspect_ratio")); - if (e.fit_mode && !zi.has(e.fit_mode)) + if (e.fit_mode && !Wi.has(e.fit_mode)) throw new Error(r(void 0, "config.fit_mode")); - if (e.doorbell_entity !== void 0 && e.doorbell_entity !== "" && (typeof e.doorbell_entity != "string" || !Wi.some((t) => e.doorbell_entity.startsWith(t)))) + if (e.doorbell_entity !== void 0 && e.doorbell_entity !== "" && (typeof e.doorbell_entity != "string" || !Ji.some((t) => e.doorbell_entity.startsWith(t)))) throw new Error(r(void 0, "config.doorbell_entity")); if (e.door_entity !== void 0 && e.door_entity !== "" && (typeof e.door_entity != "string" || !e.door_entity.startsWith("lock."))) throw new Error(r(void 0, "config.door_entity")); if (e.door_contact_entity !== void 0 && e.door_contact_entity !== "" && (typeof e.door_contact_entity != "string" || !e.door_contact_entity.startsWith("binary_sensor."))) throw new Error(r(void 0, "config.door_contact_entity")); - if (e.door_action && !Fi.has(e.door_action)) + if (e.door_action && !ji.has(e.door_action)) throw new Error(r(void 0, "config.door_action")); - if (e.door_control_visibility && !Ni.has(e.door_control_visibility)) + if (e.door_control_visibility && !Zi.has(e.door_control_visibility)) throw new Error(r(void 0, "config.door_control_visibility")); - if (e.door_control_location && !qi.has(e.door_control_location)) + if (e.door_control_location && !Gi.has(e.door_control_location)) throw new Error(r(void 0, "config.door_control_location")); - if (e.dashboard_behavior && !Bi.has(e.dashboard_behavior)) + if (e.dashboard_behavior && !Yi.has(e.dashboard_behavior)) throw new Error(r(void 0, "config.dashboard_behavior")); - if (e.dashboard_start && !Ki.has(e.dashboard_start)) + if (e.dashboard_start && !Qi.has(e.dashboard_start)) throw new Error(r(void 0, "config.dashboard_start")); } -function be(e) { - return ji(e), { - type: e.type ?? Me, +function ye(e) { + return Xi(e), { + type: e.type ?? Ie, recording_entity: e.recording_entity, live_entity: e.live_entity, snapshot_entity: e.snapshot_entity || void 0, @@ -1424,7 +1448,7 @@ function be(e) { preview_source: e.preview_source ?? b.preview_source, preview_fallback: e.preview_fallback ?? b.preview_fallback, show_snapshot_button: e.show_snapshot_button ?? b.show_snapshot_button, - snapshot_directory: he( + snapshot_directory: ue( e.snapshot_directory ?? b.snapshot_directory ), aspect_ratio: e.aspect_ratio ?? b.aspect_ratio, @@ -1432,7 +1456,7 @@ function be(e) { grid_options: e.grid_options }; } -function kt(e) { +function Ct(e) { switch (e) { case "16:9": return 16 / 9; @@ -1444,43 +1468,43 @@ function kt(e) { return; } } -function Zi(e) { +function eo(e) { return e === "auto" ? "16 / 9" : e.replace(":", " / "); } -const De = "ring-view-live-entity", Ie = "ring-view-recording-entity", Ve = "ring-view-mode", ae = "ring-view-ringing-until"; -function At() { +const Ve = "ring-view-live-entity", He = "ring-view-recording-entity", Oe = "ring-view-mode", de = "ring-view-ringing-until"; +function xt() { return `${window.location.pathname}${window.location.search}${window.location.hash}`; } -function we(e = window.location.search) { - const t = e instanceof URLSearchParams ? e : new URLSearchParams(e), i = t.get(De), o = t.get(Ie), s = t.get(Ve); - if (!i?.startsWith("camera.") || !o?.startsWith("camera.") || s !== "live" && s !== "last_recording") +function ke(e = window.location.search) { + const t = e instanceof URLSearchParams ? e : new URLSearchParams(e), i = t.get(Ve), o = t.get(He), n = t.get(Oe); + if (!i?.startsWith("camera.") || !o?.startsWith("camera.") || n !== "live" && n !== "last_recording") return; - const n = t.get(ae), a = n === null ? void 0 : Number(n); + const s = t.get(de), a = s === null ? void 0 : Number(s); return { liveEntity: i, recordingEntity: o, - mode: s, + mode: n, ringingUntil: a !== void 0 && Number.isFinite(a) ? a : void 0 }; } -function ye(e, t) { +function Ae(e, t) { return e?.liveEntity === t.live_entity && e.recordingEntity === t.recording_entity; } -function Gi(e, t) { +function to(e, t) { const i = new URL(e, window.location.origin); - return i.searchParams.set(De, t.liveEntity), i.searchParams.set(Ie, t.recordingEntity), i.searchParams.set(Ve, t.mode), t.ringingUntil !== void 0 && t.ringingUntil > Date.now() ? i.searchParams.set(ae, String(t.ringingUntil)) : i.searchParams.delete(ae), `${i.pathname}${i.search}${i.hash}`; + return i.searchParams.set(Ve, t.liveEntity), i.searchParams.set(He, t.recordingEntity), i.searchParams.set(Oe, t.mode), t.ringingUntil !== void 0 && t.ringingUntil > Date.now() ? i.searchParams.set(de, String(t.ringingUntil)) : i.searchParams.delete(de), `${i.pathname}${i.search}${i.hash}`; } -function St(e) { +function Rt(e) { const t = new URL(e, window.location.origin); - return t.searchParams.delete(De), t.searchParams.delete(Ie), t.searchParams.delete(Ve), t.searchParams.delete(ae), `${t.pathname}${t.search}${t.hash}`; + return t.searchParams.delete(Ve), t.searchParams.delete(He), t.searchParams.delete(Oe), t.searchParams.delete(de), `${t.pathname}${t.search}${t.hash}`; } -function ke(e, t) { +function Se(e, t) { try { const i = window.history.state && typeof window.history.state == "object" ? window.history.state : {}; let o = i; if (t === null) { - const { refreshUrl: s, ...n } = i; - o = n; + const { refreshUrl: n, ...s } = i; + o = s; } else t !== void 0 && (o = { ...i, refreshUrl: t }); window.history.replaceState( o, @@ -1490,25 +1514,25 @@ function ke(e, t) { } catch { } } -const He = "ring-view-dialog", se = 12e3; +const Ue = "ring-view-dialog", se = 12e3; let Y; -function Yi(e) { +function io(e) { Y = e; } -function Qi(e) { +function oo(e) { Y === e && (Y = void 0); } -function Ji(e) { +function no(e) { return !e.restored || !Y?.isOpenFor(e) ? !1 : (Y.adoptRestoredDialog(e), !0); } function ge(e, t) { - if (Ji(t)) return; - const i = St(At()); - ke(i), e.dispatchEvent( + if (no(t)) return; + const i = Rt(xt()); + Se(i), e.dispatchEvent( new CustomEvent("show-dialog", { detail: { - dialogTag: He, - dialogImport: () => Promise.resolve().then(() => Mo), + dialogTag: Ue, + dialogImport: () => Promise.resolve().then(() => Uo), dialogParams: { ...t, returnUrl: i }, addHistory: !0 }, @@ -1517,24 +1541,24 @@ function ge(e, t) { }) ); } -const Xi = 9e3, Xe = /* @__PURE__ */ new WeakMap(); -function $t(e, t, i) { +const so = 9e3, it = /* @__PURE__ */ new WeakMap(); +function Et(e, t, i) { const o = t?.attributes.entity_picture; return typeof o == "string" && o.length > 0 ? e.hassUrl(o) : e.hassUrl(`/api/camera_proxy/${encodeURIComponent(i)}`); } -async function eo(e, t, i, o) { - const s = await to(e, t), n = s.includes("?") ? "&" : "?"; - return `${s}${n}width=${et(i)}&height=${et(o)}`; +async function ro(e, t, i, o) { + const n = await ao(e, t), s = n.includes("?") ? "&" : "?"; + return `${n}${s}width=${ot(i)}&height=${ot(o)}`; } -function et(e) { +function ot(e) { return Math.max(1, Math.ceil(Number.isFinite(e) ? e : 1)); } -async function to(e, t) { - let i = Xe.get(e); - i || (i = /* @__PURE__ */ new Map(), Xe.set(e, i)); - const o = Date.now(), s = i.get(t); - if (s && s.expiresAt > o) return s.promise; - const n = e.callWS({ +async function ao(e, t) { + let i = it.get(e); + i || (i = /* @__PURE__ */ new Map(), it.set(e, i)); + const o = Date.now(), n = i.get(t); + if (n && n.expiresAt > o) return n.promise; + const s = e.callWS({ type: "auth/sign_path", path: `/api/camera_proxy/${encodeURIComponent(t)}` }).then((a) => { @@ -1543,29 +1567,29 @@ async function to(e, t) { return e.hassUrl(a.path); }); i.set(t, { - expiresAt: o + Xi, - promise: n + expiresAt: o + so, + promise: s }); try { - return await n; + return await s; } catch (a) { throw i.delete(t), a; } } -function tt(e) { +function nt(e) { return e === "live" ? h`` : h` `; } -function io(e, t) { +function co(e, t) { return r( t, e === "live" ? "common.live" : "common.last_recording" ); } -const oo = F` +const lo = N` :host { display: block; min-width: 0; @@ -1718,7 +1742,7 @@ const oo = F` display: none; } } -`, so = F` +`, ho = N` :host { position: fixed; inset: 0; @@ -2494,7 +2518,7 @@ const oo = F` :host([inline]) .state-layer.with-visitor-controls .spinner { flex: 0 0 auto; } -`, no = F` +`, uo = N` :host { display: block; min-width: 0; @@ -2511,29 +2535,29 @@ const oo = F` gap: 8px; margin: 0 0 12px; } -`, ro = "ring-view:mode:"; -function Tt(e) { - return `${ro}${e.recording_entity}|${e.live_entity}`; +`, po = "ring-view:mode:"; +function Lt(e) { + return `${po}${e.recording_entity}|${e.live_entity}`; } function ee(e) { if (!e.remember_last_mode) return e.default_mode; try { - const t = window.localStorage.getItem(Tt(e)); + const t = window.localStorage.getItem(Lt(e)); return t === "live" || t === "last_recording" ? t : e.default_mode; } catch { return e.default_mode; } } -function ao(e, t) { +function vo(e, t) { if (e.remember_last_mode) try { - window.localStorage.setItem(Tt(e), t); + window.localStorage.setItem(Lt(e), t); } catch { } } -const C = Ee(class extends Le { +const C = Pe(class extends Me { constructor(e) { - if (super(e), e.type !== ft.ATTRIBUTE || e.name !== "class" || e.strings?.length > 2) throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute."); + if (super(e), e.type !== bt.ATTRIBUTE || e.name !== "class" || e.strings?.length > 2) throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute."); } render(e) { return " " + Object.keys(e).filter((t) => e[t]).join(" ") + " "; @@ -2547,14 +2571,14 @@ const C = Ee(class extends Le { const i = e.element.classList; for (const o of this.st) o in t || (i.remove(o), this.st.delete(o)); for (const o in t) { - const s = !!t[o]; - s === this.st.has(o) || this.nt?.has(o) || (s ? (i.add(o), this.st.add(o)) : (i.remove(o), this.st.delete(o))); + const n = !!t[o]; + n === this.st.has(o) || this.nt?.has(o) || (n ? (i.add(o), this.st.add(o)) : (i.remove(o), this.st.delete(o))); } return P; } }); -const co = {}, lo = (e, t = co) => e._$AH = t; -const it = Ee(class extends Le { +const fo = {}, go = (e, t = fo) => e._$AH = t; +const st = Pe(class extends Me { constructor() { super(...arguments), this.key = c; } @@ -2562,23 +2586,23 @@ const it = Ee(class extends Le { return this.key = e, t; } update(e, [t, i]) { - return t !== this.key && (lo(e), this.key = t), i; + return t !== this.key && (go(e), this.key = t), i; } }); -var ho = Object.defineProperty, uo = Object.getOwnPropertyDescriptor, E = (e, t, i, o) => { - for (var s = o > 1 ? void 0 : o ? uo(t, i) : t, n = e.length - 1, a; n >= 0; n--) - (a = e[n]) && (s = (o ? a(t, i, s) : a(s)) || s); - return o && s && ho(t, i, s), s; +var mo = Object.defineProperty, _o = Object.getOwnPropertyDescriptor, E = (e, t, i, o) => { + for (var n = o > 1 ? void 0 : o ? _o(t, i) : t, s = e.length - 1, a; s >= 0; s--) + (a = e[s]) && (n = (o ? a(t, i, n) : a(n)) || n); + return o && n && mo(t, i, n), n; }; -const de = "ha-camera-stream", po = 8e3, ot = "ring-view-native-layout"; -async function vo(e, t) { +const ce = "ha-camera-stream", bo = 8e3, rt = "ring-view-native-layout"; +async function wo(e, t) { if (customElements.get(e)) return !0; let i; try { return await Promise.race([ customElements.whenDefined(e), - new Promise((o, s) => { - i = window.setTimeout(() => s(new Error("timeout")), t); + new Promise((o, n) => { + i = window.setTimeout(() => n(new Error("timeout")), t); }) ]), !!customElements.get(e); } catch { @@ -2587,17 +2611,17 @@ async function vo(e, t) { i !== void 0 && window.clearTimeout(i); } } -async function Ct() { - if (customElements.get(de)) return !0; +async function Pt() { + if (customElements.get(ce)) return !0; try { await (await window.loadCardHelpers?.())?.importMoreInfoControl?.("camera"); } catch { } - return vo(de, po); + return wo(ce, bo); } let $ = class extends x { constructor() { - super(...arguments), this.controls = !0, this.muted = !0, this.allowExoPlayer = !0, this.fitMode = "cover", this.passiveSurface = !1, this.nativeAvailable = !!customElements.get(de), this.handledStreamEvents = /* @__PURE__ */ new WeakSet(), this.ready = !1, this.handleSurfaceClick = (e) => { + super(...arguments), this.controls = !0, this.muted = !0, this.allowExoPlayer = !0, this.fitMode = "cover", this.passiveSurface = !1, this.nativeAvailable = !!customElements.get(ce), this.handledStreamEvents = /* @__PURE__ */ new WeakSet(), this.ready = !1, this.handleSurfaceClick = (e) => { if (!this.passiveSurface || e.detail === 0 || !this.eventHost) return; const t = this.eventHost.getBoundingClientRect(), i = this.controls ? 64 : 0; e.clientY >= t.bottom - i || (e.preventDefault(), e.stopImmediatePropagation()); @@ -2645,11 +2669,11 @@ let $ = class extends x { } updated() { if (!this.nativeAvailable) return; - const e = this.renderRoot.querySelector(de); + const e = this.renderRoot.querySelector(ce); e && this.attachEventListeners(e); } async loadNativeComponent() { - const e = await Ct(); + const e = await Pt(); if (this.isConnected) { if (!e) { this.dispatchFailure("component-unavailable"); @@ -2669,9 +2693,9 @@ let $ = class extends x { }), this.mediaObserver.observe(t, { childList: !0, subtree: !0 }), this.prepareNativeRoot(t), this.detectReadyMedia(t)); } prepareNativeRoot(e) { - if (e.getElementById(ot)) return; + if (e.getElementById(rt)) return; const t = document.createElement("style"); - t.id = ot, t.textContent = ` + t.id = rt, t.textContent = ` :host { display: block; width: 100%; @@ -2722,7 +2746,7 @@ let $ = class extends x { ); } }; -$.styles = F` +$.styles = N` :host { display: block; width: 100%; @@ -2764,16 +2788,16 @@ E([ u() ], $.prototype, "nativeAvailable", 2); $ = E([ - N("ring-view-native-camera-adapter") + q("ring-view-native-camera-adapter") ], $); -const go = (e) => e ?? c; -var fo = Object.defineProperty, mo = Object.getOwnPropertyDescriptor, k = (e, t, i, o) => { - for (var s = o > 1 ? void 0 : o ? mo(t, i) : t, n = e.length - 1, a; n >= 0; n--) - (a = e[n]) && (s = (o ? a(t, i, s) : a(s)) || s); - return o && s && fo(t, i, s), s; +const yo = (e) => e ?? c; +var ko = Object.defineProperty, Ao = Object.getOwnPropertyDescriptor, k = (e, t, i, o) => { + for (var n = o > 1 ? void 0 : o ? Ao(t, i) : t, s = e.length - 1, a; s >= 0; s--) + (a = e[s]) && (n = (o ? a(t, i, n) : a(n)) || n); + return o && n && ko(t, i, n), n; }; -const _o = 3e3; -function bo(e, t) { +const So = 3e3; +function $o(e, t) { if (t instanceof DOMException) { if (t.name === "NotAllowedError") return r(e, "talkback.permission_denied"); if (t.name === "NotFoundError") return r(e, "talkback.no_microphone"); @@ -2817,14 +2841,14 @@ let y = class extends x { }, video: !1 }), e !== this.connectionToken || !this.audioSender) - return i.getTracks().forEach((s) => s.stop()), !1; + return i.getTracks().forEach((n) => n.stop()), !1; const o = i.getAudioTracks()[0]; if (!o) throw new Error(r(this.hass, "talkback.no_microphone")); return o.enabled = !1, o.addEventListener("ended", () => { e !== this.connectionToken || this.localStream !== i || (this.cancelActivePress(), this.localStream = void 0, this.microphoneState = "failed", this.showStatusMessage(r(this.hass, "talkback.microphone_ended"), "error")); - }), await this.audioSender.replaceTrack(o), e !== this.connectionToken ? (i.getTracks().forEach((s) => s.stop()), !1) : (this.localStream?.getTracks().forEach((s) => s.stop()), this.localStream = i, this.microphoneState = "ready", this.showStatusMessage(""), !0); + }), await this.audioSender.replaceTrack(o), e !== this.connectionToken ? (i.getTracks().forEach((n) => n.stop()), !1) : (this.localStream?.getTracks().forEach((n) => n.stop()), this.localStream = i, this.microphoneState = "ready", this.showStatusMessage(""), !0); } catch (o) { - return i?.getTracks().forEach((s) => s.stop()), e !== this.connectionToken || (this.microphoneState = "failed", this.showStatusMessage(bo(this.hass, o), "error")), !1; + return i?.getTracks().forEach((n) => n.stop()), e !== this.connectionToken || (this.microphoneState = "failed", this.showStatusMessage($o(this.hass, o), "error")), !1; } })(); this.microphoneRequest = t; @@ -2885,8 +2909,8 @@ let y = class extends x { } updated(e) { if (e.has("muted")) { - const s = this.renderRoot.querySelector("video"); - s && (s.muted = this.actualMuted); + const n = this.renderRoot.querySelector("video"); + n && (n.muted = this.actualMuted); } if (this.signalingConnection && this.hass?.connection !== this.signalingConnection) { this.requestLiveResume(); @@ -2903,20 +2927,20 @@ let y = class extends x { })); } render() { - const e = this.microphoneState === "active", t = this.microphoneState === "requesting", i = this.connectionState === "connected", o = `--ring-view-talkback-fit-mode: ${this.fitMode}`, s = t ? r(this.hass, "talkback.requesting_microphone") : e ? r(this.hass, "talkback.release_to_stop") : r(this.hass, "talkback.hold_to_talk"); + const e = this.microphoneState === "active", t = this.microphoneState === "requesting", i = this.connectionState === "connected", o = `--ring-view-talkback-fit-mode: ${this.fitMode}`, n = t ? r(this.hass, "talkback.requesting_microphone") : e ? r(this.hass, "talkback.release_to_stop") : r(this.hass, "talkback.hold_to_talk"); return h` ${this.playbackBlocked ? h` ` : c} @@ -2924,9 +2948,9 @@ let y = class extends x { ` : c} ${!this.externalControls && this.statusMessage && !this.playbackBlocked ? h`
this.handleRemoteTrack(a, e), o.onicecandidate = (a) => { a.candidate?.candidate && this.handleLocalCandidate(a.candidate, e); }, o.onconnectionstatechange = () => this.handleConnectionState(e); - const s = o.addTransceiver("audio", { + const n = o.addTransceiver("audio", { direction: "sendrecv" }); - this.audioSender = s.sender, o.addTransceiver("video", { direction: "recvonly" }); - const n = await o.createOffer(); - if (await o.setLocalDescription(n), e !== this.connectionToken || !o.localDescription?.sdp) return; + this.audioSender = n.sender, o.addTransceiver("video", { direction: "recvonly" }); + const s = await o.createOffer(); + if (await o.setLocalDescription(s), e !== this.connectionToken || !o.localDescription?.sdp) return; this.unsubscribePromise = Promise.resolve( t.subscribeMessage( (a) => { @@ -3111,7 +3135,7 @@ let y = class extends x { }) ), e && (this.statusMessageTimeout = window.setTimeout(() => { this.statusMessageTimeout = void 0, this.showStatusMessage(""); - }, _o)); + }, So)); } dispatchTalkbackState() { const e = { @@ -3158,7 +3182,7 @@ let y = class extends x { return h``; } }; -y.styles = F` +y.styles = N` :host { position: absolute; inset: 0; @@ -3327,13 +3351,13 @@ k([ u() ], y.prototype, "readyDispatched", 2); y = k([ - N("ring-view-ring-webrtc-player") + q("ring-view-ring-webrtc-player") ], y); -const wo = /* @__PURE__ */ new Set(["unknown", "unavailable"]); -function xt(e, t, i) { - return !i || t === void 0 || wo.has(i.state) ? !1 : e.startsWith("binary_sensor.") ? t === "off" && i.state === "on" : e.startsWith("event.") && t !== "unavailable" && t !== i.state && (i.attributes.event_type === void 0 || i.attributes.event_type === "ring"); +const To = /* @__PURE__ */ new Set(["unknown", "unavailable"]); +function Mt(e, t, i) { + return !i || t === void 0 || To.has(i.state) ? !1 : e.startsWith("binary_sensor.") ? t === "off" && i.state === "on" : e.startsWith("event.") && t !== "unavailable" && t !== i.state && (i.attributes.event_type === void 0 || i.attributes.event_type === "ring"); } -class yo { +class Co { constructor() { this.generation = 0; } @@ -3357,19 +3381,19 @@ class yo { this.clearTimeout(), this.generation += 1; } } -var ko = Object.defineProperty, Ao = Object.getOwnPropertyDescriptor, m = (e, t, i, o) => { - for (var s = o > 1 ? void 0 : o ? Ao(t, i) : t, n = e.length - 1, a; n >= 0; n--) - (a = e[n]) && (s = (o ? a(t, i, s) : a(s)) || s); - return o && s && ko(t, i, s), s; +var xo = Object.defineProperty, Ro = Object.getOwnPropertyDescriptor, m = (e, t, i, o) => { + for (var n = o > 1 ? void 0 : o ? Ro(t, i) : t, s = e.length - 1, a; s >= 0; s--) + (a = e[s]) && (n = (o ? a(t, i, n) : a(n)) || n); + return o && n && xo(t, i, n), n; }; -const So = 20, $o = 2500, To = 2500, Co = 900, xo = 2e3, Ro = 3e3, Eo = 2e3, Lo = 3e3; -function Po(e) { +const Eo = 20, Lo = 2500, Po = 2500, Mo = 900, Do = 2e3, Io = 3e3, Vo = 2e3, Ho = 3e3; +function Oo(e) { const t = e instanceof Error ? e.message.toLowerCase() : String(e).toLowerCase(); return /timeout|timed out/.test(t) ? "snapshot.timeout" : /unauthorized|forbidden|permission denied/.test(t) ? "snapshot.permission_failed" : /cannot write|can't write|no access to path|read-only|readonly/.test(t) ? "snapshot.write_failed" : /connection|websocket|service api unavailable/.test(t) ? "snapshot.connection_failed" : /no image|could not provide|not supported|snapshot unavailable/.test(t) ? "snapshot.camera_failed" : "snapshot.failed"; } -let f = class extends x { +let g = class extends x { constructor() { - super(...arguments), this.open = !1, this.inline = !1, this.ringing = !1, this.mode = "last_recording", this.mediaStatus = "idle", this.session = 0, this.suspended = !1, this.recordingMuted = !1, this.recordingStarted = !0, this.recordingControlsVisible = !0, this.recordingEnded = !1, this.liveMuted = !0, this.recordingVideoFailed = !1, this.retryCount = 0, this.statusAnnouncement = "", this.talkbackReady = !1, this.talkbackRequesting = !1, this.talkbackTalking = !1, this.doorActionStatus = "idle", this.snapshotActionStatus = "idle", this.inlineStarted = !0, this.lifecycle = new yo(), this.recordingPlayback = /* @__PURE__ */ new WeakSet(), this.recordingPaused = !1, this.automaticLiveRetry = !0, this.pageUnloading = !1, this.talkKeyboardPressed = !1, this.doorKeyboardPressed = !1, this.doorActionToken = 0, this.snapshotActionToken = 0, this.inlineVisible = !1, this.inlineActive = !1, this.takeSnapshot = async () => { + super(...arguments), this.open = !1, this.inline = !1, this.ringing = !1, this.mode = "last_recording", this.mediaStatus = "idle", this.session = 0, this.suspended = !1, this.recordingMuted = !1, this.recordingStarted = !0, this.recordingControlsVisible = !0, this.recordingEnded = !1, this.liveMuted = !0, this.recordingVideoFailed = !1, this.retryCount = 0, this.statusAnnouncement = "", this.talkbackReady = !1, this.talkbackRequesting = !1, this.talkbackTalking = !1, this.doorActionStatus = "idle", this.snapshotActionStatus = "idle", this.inlineStarted = !0, this.lifecycle = new Co(), this.recordingPlayback = /* @__PURE__ */ new WeakSet(), this.recordingPaused = !1, this.automaticLiveRetry = !0, this.pageUnloading = !1, this.talkKeyboardPressed = !1, this.doorKeyboardPressed = !1, this.doorActionToken = 0, this.snapshotActionToken = 0, this.inlineVisible = !1, this.inlineActive = !1, this.takeSnapshot = async () => { const e = this.hass, t = this.config, i = this.snapshotEntityId(); if (!e || !t || !i || !this.shouldShowSnapshotAction() || this.snapshotActionStatus === "working") return; @@ -3381,19 +3405,19 @@ let f = class extends x { if (await e.callService( "camera", "snapshot", - { filename: Di(e, t) }, + { filename: zi(e, t) }, { entity_id: i } ), o !== this.snapshotActionToken || !this.open) return; - const s = r(this.hass, "snapshot.saved"); - this.snapshotActionStatus = "success", this.snapshotFeedbackMessage = s, this.clearViewerFeedback("snapshot"), this.statusAnnouncement = s, this.snapshotFeedbackTimer = window.setTimeout(() => { + const n = r(this.hass, "snapshot.saved"); + this.snapshotActionStatus = "success", this.snapshotFeedbackMessage = n, this.clearViewerFeedback("snapshot"), this.statusAnnouncement = n, this.snapshotFeedbackTimer = window.setTimeout(() => { o === this.snapshotActionToken && (this.snapshotFeedbackTimer = void 0, this.snapshotFeedbackMessage = void 0, this.snapshotActionStatus = "idle"); - }, Eo); - } catch (s) { + }, Vo); + } catch (n) { if (o !== this.snapshotActionToken || !this.open) return; - const n = r(this.hass, Po(s)); - this.snapshotActionStatus = "error", this.snapshotFeedbackMessage = n, this.setViewerFeedback("snapshot", n, "error"), this.statusAnnouncement = n, this.snapshotFeedbackTimer = window.setTimeout(() => { + const s = r(this.hass, Oo(n)); + this.snapshotActionStatus = "error", this.snapshotFeedbackMessage = s, this.setViewerFeedback("snapshot", s, "error"), this.statusAnnouncement = s, this.snapshotFeedbackTimer = window.setTimeout(() => { o === this.snapshotActionToken && (this.snapshotFeedbackTimer = void 0, this.snapshotFeedbackMessage = void 0, this.snapshotActionStatus = "idle"); - }, Lo); + }, Ho); } }, this.handleTalkbackState = (e) => { e.currentTarget === this.renderRoot.querySelector("ring-view-ring-webrtc-player") && (e.detail.ready || this.cancelTalkPress(e.currentTarget), this.talkbackReady = e.detail.ready, this.talkbackRequesting = e.detail.requesting, this.talkbackTalking = e.detail.talking); @@ -3505,9 +3529,9 @@ let f = class extends x { const t = this.focusableElements(); if (t.length === 0) return; const i = t[0], o = t[t.length - 1]; - let s = this.shadowRoot?.activeElement; - for (; s?.shadowRoot?.activeElement; ) s = s.shadowRoot.activeElement; - e.shiftKey && s === i ? (e.preventDefault(), o.focus()) : !e.shiftKey && s === o && (e.preventDefault(), i.focus()); + let n = this.shadowRoot?.activeElement; + for (; n?.shadowRoot?.activeElement; ) n = n.shadowRoot.activeElement; + e.shiftKey && n === i ? (e.preventDefault(), o.focus()) : !e.shiftKey && n === o && (e.preventDefault(), i.focus()); }, this.handleTabKeyDown = (e) => { if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(e.key)) return; e.preventDefault(); @@ -3561,7 +3585,7 @@ let f = class extends x { this.adoptRestoredDialog(e), this.syncUrl(); return; } - this.open && this.finishClose(!1, !1), this.inline = !1, this.config = e.config, this.opener = e.opener, this.returnUrl = e.returnUrl ?? St(At()), this.mode = e.mode, this.liveMuted = e.restored && this.mode === "live" ? !0 : this.config.live_muted, this.recordingStarted = this.mode === "live" || this.config.autoplay_recording, this.resetMediaAttempt(), this.automaticLiveRetry = !e.restored, this.pageUnloading = !1, this.suspended = !1, this.statusAnnouncement = "", this.resetVisitorActions(), this.resetSnapshotAction(), this.lastDoorbellState = this.config.doorbell_entity ? this.hass.states[this.config.doorbell_entity]?.state : void 0, this.setRingingUntil(e.ringingUntil), this.open = !0, Yi(this), this.syncUrl(), this.attachGlobalListeners(), e.restored && this.mode === "live" ? this.prepareAutomaticLiveResume() : this.startMedia(), this.updateComplete.then(() => this.focusInitialControl()); + this.open && this.finishClose(!1, !1), this.inline = !1, this.config = e.config, this.opener = e.opener, this.returnUrl = e.returnUrl ?? Rt(xt()), this.mode = e.mode, this.liveMuted = e.restored && this.mode === "live" ? !0 : this.config.live_muted, this.recordingStarted = this.mode === "live" || this.config.autoplay_recording, this.resetMediaAttempt(), this.automaticLiveRetry = !e.restored, this.pageUnloading = !1, this.suspended = !1, this.statusAnnouncement = "", this.resetVisitorActions(), this.resetSnapshotAction(), this.lastDoorbellState = this.config.doorbell_entity ? this.hass.states[this.config.doorbell_entity]?.state : void 0, this.setRingingUntil(e.ringingUntil), this.open = !0, io(this), this.syncUrl(), this.attachGlobalListeners(), e.restored && this.mode === "live" ? this.prepareAutomaticLiveResume() : this.startMedia(), this.updateComplete.then(() => this.focusInitialControl()); } } showInline(e) { @@ -3602,9 +3626,7 @@ let f = class extends x { } render() { if (!this.open || !this.hass || !this.config) return c; - const e = this.dialogTitle(), t = this.config.show_name, i = Z( - this.config.last_activity_entity ? this.hass.states[this.config.last_activity_entity] : void 0 - ) !== void 0, o = this.config.aspect_ratio, s = { + const e = this.dialogTitle(), t = this.config.show_name, i = this.config.last_activity_entity ? H(this.hass, this.config.last_activity_entity) !== void 0 : !1, o = this.config.aspect_ratio, n = { "--ring-view-aspect-ratio": o === "auto" ? "16 / 9" : o.replace(":", " / "), "--ring-view-fit-mode": this.config.fit_mode }; @@ -3612,7 +3634,7 @@ let f = class extends x { ${this.inline ? c : h`
`}
- ${this.icon(this.inline ? Mt : Et)} + ${this.icon(this.inline ? Ot : It)}
${this.renderModeSwitch()} @@ -3673,7 +3695,7 @@ let f = class extends x { aria-label=${e} title=${e} > - ${this.icon(nt)} + ${this.icon(dt)} ${e}
`; @@ -3698,7 +3720,7 @@ let f = class extends x { @click=${() => this.selectMode("last_recording")} @keydown=${this.handleTabKeyDown} > - ${tt("last_recording")} + ${nt("last_recording")} `; } renderSnapshotAction() { if (!this.shouldShowSnapshotAction()) return c; - const e = this.snapshotEntityId(), t = this.hass?.connection?.connected !== !1, i = this.snapshotActionStatus === "working", o = i || !e || !t, s = t ? e ? this.snapshotActionStatus === "working" ? "snapshot.saving" : this.snapshotActionStatus === "success" ? "snapshot.saved" : this.snapshotActionStatus === "error" ? this.snapshotFeedbackMessage ? void 0 : "snapshot.failed" : "snapshot.take" : "snapshot.unavailable" : "snapshot.connection_failed", n = s ? r(this.hass, s) : this.snapshotFeedbackMessage, a = this.snapshotActionStatus === "working" ? ze : this.snapshotActionStatus === "success" ? Oe : this.snapshotActionStatus === "error" ? ue : rt; + const e = this.snapshotEntityId(), t = this.hass?.connection?.connected !== !1, i = this.snapshotActionStatus === "working", o = i || !e || !t, n = t ? e ? this.snapshotActionStatus === "working" ? "snapshot.saving" : this.snapshotActionStatus === "success" ? "snapshot.saved" : this.snapshotActionStatus === "error" ? this.snapshotFeedbackMessage ? void 0 : "snapshot.failed" : "snapshot.take" : "snapshot.unavailable" : "snapshot.connection_failed", s = n ? r(this.hass, n) : this.snapshotFeedbackMessage, a = this.snapshotActionStatus === "working" ? Ne : this.snapshotActionStatus === "success" ? ze : this.snapshotActionStatus === "error" ? pe : ct; return h` ` : c} @@ -3804,11 +3826,11 @@ let f = class extends x { error: !l && this.doorActionStatus === "error" })} type="button" - aria-label=${d ? `${s}. ${p}` : s} + aria-label=${d ? `${n}. ${p}` : n} aria-busy=${String(this.doorActionStatus === "working")} aria-describedby=${this.viewerFeedback?.source === "door" ? "ring-view-door-feedback" : c} ?disabled=${i} - @contextmenu=${(g) => g.preventDefault()} + @contextmenu=${(f) => f.preventDefault()} @click=${this.handleDoorClick} @pointerdown=${this.handleDoorPointerDown} @pointerup=${this.handleDoorPointerEnd} @@ -3817,7 +3839,7 @@ let f = class extends x { @keydown=${this.handleDoorKeyDown} @keyup=${this.handleDoorKeyUp} > - ${this.icon(n)} + ${this.icon(s)} ${o} ${d ? h`${p}` : c} @@ -3834,7 +3856,7 @@ let f = class extends x { )) && (this.mode === "live" || this.config.door_control_visibility === "all_views")); } shouldShowTalkControl() { - return !!(this.mode === "live" && this.config?.two_way_audio && this.hass && me(this.hass, this.config.live_entity) && ["pending", "ready", "playback-blocked"].includes(this.mediaStatus)); + return !!(this.mode === "live" && this.config?.two_way_audio && this.hass && be(this.hass, this.config.live_entity) && ["pending", "ready", "playback-blocked"].includes(this.mediaStatus)); } doorEntity() { const e = this.config?.door_entity; @@ -3848,11 +3870,11 @@ let f = class extends x { } doorActionDisabled() { const e = this.doorEntity(); - return !this.config?.door_entity || this.doorContactState() === "open" || w(e) || e?.state === "jammed" || this.doorActionStatus === "working" || this.doorActionStatus === "success" || this.doorWaitingForLiveVideo() ? !0 : this.config.door_action === "open" ? !oe(e) || ["open", "opening"].includes(e?.state ?? "") : ["unlocked", "unlocking", "open", "opening"].includes(e?.state ?? ""); + return !this.config?.door_entity || this.doorContactState() === "open" || w(e) || e?.state === "jammed" || this.doorActionStatus === "working" || this.doorActionStatus === "success" || this.doorWaitingForLiveVideo() ? !0 : this.config.door_action === "open" ? !ne(e) || ["open", "opening"].includes(e?.state ?? "") : ["unlocked", "unlocking", "open", "opening"].includes(e?.state ?? ""); } doorActionLabel() { const e = this.doorEntity(); - return this.doorContactState() === "open" ? r(this.hass, "door.contact_open") : w(e) ? r(this.hass, "door.unavailable") : e?.state === "jammed" ? r(this.hass, "door.jammed") : this.config?.door_action === "open" && !oe(e) ? r(this.hass, "door.open_unsupported") : this.doorWaitingForLiveVideo() ? r( + return this.doorContactState() === "open" ? r(this.hass, "door.contact_open") : w(e) ? r(this.hass, "door.unavailable") : e?.state === "jammed" ? r(this.hass, "door.jammed") : this.config?.door_action === "open" && !ne(e) ? r(this.hass, "door.open_unsupported") : this.doorWaitingForLiveVideo() ? r( this.hass, this.config?.door_action === "open" ? "door.open_when_ready" : "door.unlock_when_ready" ) : this.doorActionStatus === "working" || this.config?.door_action === "unlock" && e?.state === "unlocking" || this.config?.door_action === "open" && e?.state === "opening" ? r( @@ -3880,7 +3902,7 @@ let f = class extends x { } doorActionIcon() { const e = this.doorEntity(), t = this.doorContactState(); - return t === "open" ? Ue : t === "closed" ? Lt : t === "unknown" || w(e) || e?.state === "jammed" || this.config?.door_action === "open" && !oe(e) || this.doorActionStatus === "error" ? ue : this.doorActionStatus === "working" ? ze : this.doorActionStatus === "success" ? Oe : this.config?.door_action === "open" ? Ue : at; + return t === "open" ? Fe : t === "closed" ? Vt : t === "unknown" || w(e) || e?.state === "jammed" || this.config?.door_action === "open" && !ne(e) || this.doorActionStatus === "error" ? pe : this.doorActionStatus === "working" ? Ne : this.doorActionStatus === "success" ? ze : this.config?.door_action === "open" ? Fe : lt; } talkbackPlayer() { return this.shadowRoot?.querySelector("ring-view-ring-webrtc-player") ?? null; @@ -3891,7 +3913,7 @@ let f = class extends x { beginDoorHold() { this.doorHoldTimer !== void 0 || this.doorActionDisabled() || (this.clearDoorFeedback(), this.doorActionStatus = "holding", this.doorHoldTimer = window.setTimeout(() => { this.doorHoldTimer = void 0, this.doorPointerId = void 0, this.doorKeyboardPressed = !1, this.executeDoorAction(); - }, Co)); + }, Mo)); } cancelDoorHold() { this.doorHoldTimer !== void 0 && (window.clearTimeout(this.doorHoldTimer), this.doorHoldTimer = void 0), this.doorPointerId = void 0, this.doorKeyboardPressed = !1, this.doorActionStatus === "holding" && (this.doorActionStatus = "idle"); @@ -3907,22 +3929,22 @@ let f = class extends x { try { if (!e.callService) throw new Error("Home Assistant service API unavailable"); if (await e.callService("lock", i, { entity_id: t }), o !== this.doorActionToken || !this.open) return; - const s = r( + const n = r( this.hass, i === "open" ? "door.opened" : "door.unlocked" ); - this.doorActionStatus = "success", this.clearViewerFeedback("door"), this.statusAnnouncement = s, this.doorFeedbackTimer = window.setTimeout(() => { + this.doorActionStatus = "success", this.clearViewerFeedback("door"), this.statusAnnouncement = n, this.doorFeedbackTimer = window.setTimeout(() => { o === this.doorActionToken && (this.doorFeedbackTimer = void 0, this.clearViewerFeedback("door"), this.doorActionStatus = "idle"); - }, xo); + }, Do); } catch { if (o !== this.doorActionToken || !this.open) return; - const s = r( + const n = r( this.hass, i === "open" ? "door.open_failed" : "door.unlock_failed" ); - this.doorActionStatus = "error", this.setViewerFeedback("door", s, "error"), this.statusAnnouncement = s, this.doorFeedbackTimer = window.setTimeout(() => { + this.doorActionStatus = "error", this.setViewerFeedback("door", n, "error"), this.statusAnnouncement = n, this.doorFeedbackTimer = window.setTimeout(() => { o === this.doorActionToken && (this.doorFeedbackTimer = void 0, this.clearViewerFeedback("door"), this.doorActionStatus = "idle"); - }, Ro); + }, Io); } } clearDoorFeedback() { @@ -3938,7 +3960,7 @@ let f = class extends x { this.viewerFeedback?.source === e && (this.viewerFeedback = void 0); } renderMedia() { - const e = this.activeEntity(), t = this.activeEntityId(), i = w(e), o = !i && !this.suspended && (this.mode === "live" || this.recordingStarted), s = kt(this.config.aspect_ratio), n = $t(this.hass, e, t), a = this.mode === "last_recording" && typeof e?.attributes.video_url == "string" ? e.attributes.video_url : void 0, l = o && ["pending", "ready", "playback-blocked"].includes(this.mediaStatus), d = !!(l && a && !this.recordingVideoFailed), p = !!(o && this.mode === "live" && this.config.two_way_audio && me(this.hass, t)), v = !!(this.inline && !this.inlineStarted || this.mode === "last_recording" && !this.recordingStarted); + const e = this.activeEntity(), t = this.activeEntityId(), i = w(e), o = !i && !this.suspended && (this.mode === "live" || this.recordingStarted), n = Ct(this.config.aspect_ratio), s = Et(this.hass, e, t), a = this.mode === "last_recording" && typeof e?.attributes.video_url == "string" ? e.attributes.video_url : void 0, l = o && ["pending", "ready", "playback-blocked"].includes(this.mediaStatus), d = !!(l && a && !this.recordingVideoFailed), p = !!(o && this.mode === "live" && this.config.two_way_audio && be(this.hass, t)), v = !!(this.inline && !this.inlineStarted || this.mode === "last_recording" && !this.recordingStarted); return h`
- + ${v ? h` ` : c} - ${l && !d ? it( + ${l && !d ? st( `${t}:${this.session}`, h` ${p ? h` @@ -3974,7 +3996,7 @@ let f = class extends x { .entityId=${t} .muted=${this.liveMuted} .fitMode=${this.config.fit_mode} - .poster=${n} + .poster=${s} .externalControls=${!0} @ring-webrtc-ready=${this.handleMediaReady} @ring-webrtc-error=${this.handleRingWebRtcError} @@ -3991,7 +4013,7 @@ let f = class extends x { .controls=${!0} .muted=${this.mode === "live" ? this.liveMuted : this.recordingMuted} .allowExoPlayer=${!0} - .aspectRatio=${s} + .aspectRatio=${n} .fitMode=${this.config.fit_mode} .passiveSurface=${this.mode === "live"} @native-media-ready=${this.handleMediaReady} @@ -4001,7 +4023,7 @@ let f = class extends x { `} ` ) : c} - ${d ? it( + ${d ? st( `${t}:${this.session}:recording-video`, h`
@@ -4201,7 +4223,7 @@ let f = class extends x { this.inline && !this.inlineStarted && (this.inlineStarted = !0, this.recordingStarted = !0, this.resetMediaAttempt(), this.startMedia()); return; } - this.resetVisitorActions(), this.resetSnapshotAction(), this.clearAutomaticLiveRecovery(), this.lifecycle.dispose(), this.releaseInlineLive(), this.automaticLiveRetry = !0, this.mode = e, ao(this.config, e), this.liveMuted = this.inline ? this.config.dashboard_live_muted : this.config.live_muted, this.inlineStarted = !0, this.recordingStarted = this.inline ? !0 : e === "live" || this.config.autoplay_recording, this.resetMediaAttempt(), this.statusAnnouncement = r( + this.resetVisitorActions(), this.resetSnapshotAction(), this.clearAutomaticLiveRecovery(), this.lifecycle.dispose(), this.releaseInlineLive(), this.automaticLiveRetry = !0, this.mode = e, vo(this.config, e), this.liveMuted = this.inline ? this.config.dashboard_live_muted : this.config.live_muted, this.inlineStarted = !0, this.recordingStarted = this.inline ? !0 : e === "live" || this.config.autoplay_recording, this.resetMediaAttempt(), this.statusAnnouncement = r( this.hass, e === "live" ? "viewer.mode_selected_live" : "viewer.mode_selected_recording" ), this.syncUrl(), this.startMedia(); @@ -4230,7 +4252,7 @@ let f = class extends x { } this.mode === "last_recording" && this.resetRecordingControls(), this.mediaStatus = "pending", this.session = this.lifecycle.next(), this.lifecycle.scheduleTimeout( () => this.failMedia(), - So * 1e3 + Eo * 1e3 ); } resetMediaAttempt() { @@ -4256,7 +4278,7 @@ let f = class extends x { scheduleRecordingControlsHide(e, t) { this.clearRecordingControlsTimer(), this.recordingControlsTimer = window.setTimeout(() => { this.recordingControlsTimer = void 0, this.isCurrentRecording(e, t) && (e.controls = !1, this.recordingControlsVisible = !1); - }, To); + }, Po); } resetRecordingControls() { this.clearRecordingControlsTimer(), this.recordingControlsVisible = !0, this.recordingEnded = !1, this.recordingPaused = !1; @@ -4301,7 +4323,7 @@ let f = class extends x { return; } if (this.automaticLiveRetry && this.mode === "live" && this.retryCount < 1) { - this.retryCount += 1, this.scheduleLiveReconnect($o); + this.retryCount += 1, this.scheduleLiveReconnect(Lo); return; } this.lifecycle.dispose(), this.releaseInlineLive(), this.session = this.lifecycle.current(), this.mediaStatus = "error", this.statusAnnouncement = this.mode === "live" ? r(this.hass, "viewer.live_failed") : r(this.hass, "viewer.recording_unavailable"); @@ -4357,7 +4379,7 @@ let f = class extends x { const t = this.config?.doorbell_entity; if (!t || !this.hass) return; const i = this.hass.states[t], o = e?.states[t]?.state ?? this.lastDoorbellState; - this.lastDoorbellState = i?.state, xt(t, o, i) && this.setRingingUntil(Date.now() + se); + this.lastDoorbellState = i?.state, Mt(t, o, i) && this.setRingingUntil(Date.now() + se); } setRingingUntil(e) { this.ringAlertTimer !== void 0 && (window.clearTimeout(this.ringAlertTimer), this.ringAlertTimer = void 0); @@ -4372,25 +4394,25 @@ let f = class extends x { } syncUrl() { if (this.inline || !this.open || !this.config || !this.returnUrl) return; - const e = Gi(this.returnUrl, { + const e = to(this.returnUrl, { liveEntity: this.config.live_entity, recordingEntity: this.config.recording_entity, mode: this.mode, ringingUntil: this.ringingUntil }); - ke(e, e); + Se(e, e); } finishClose(e = !0, t = !0) { if (!this.open) return; const i = this.inline; this.clearAutomaticLiveRecovery(); - const o = this.opener, s = this.returnUrl, n = this.config; - this.renderRoot.querySelector("ring-view-ring-webrtc-player")?.stopTalking(), this.lifecycle.dispose(), this.releaseInlineLive(), this.session = this.lifecycle.current(), this.mediaStatus = "idle", this.open = !1, Qi(this), this.suspended = !1, this.resetMediaAttempt(), this.automaticLiveRetry = !0, this.recordingStarted = !0, this.statusAnnouncement = "", this.resetVisitorActions(), this.resetSnapshotAction(), this.setRingingUntil(), this.lastDoorbellState = void 0, this.detachGlobalListeners(), document.fullscreenElement && document.exitFullscreen().catch(() => { - }), t && s && n && ye(we(), n) && ke(s, null), i || this.dispatchEvent( + const o = this.opener, n = this.returnUrl, s = this.config; + this.renderRoot.querySelector("ring-view-ring-webrtc-player")?.stopTalking(), this.lifecycle.dispose(), this.releaseInlineLive(), this.session = this.lifecycle.current(), this.mediaStatus = "idle", this.open = !1, oo(this), this.suspended = !1, this.resetMediaAttempt(), this.automaticLiveRetry = !0, this.recordingStarted = !0, this.statusAnnouncement = "", this.resetVisitorActions(), this.resetSnapshotAction(), this.setRingingUntil(), this.lastDoorbellState = void 0, this.detachGlobalListeners(), document.fullscreenElement && document.exitFullscreen().catch(() => { + }), t && n && s && Ae(ke(), s) && Se(n, null), i || this.dispatchEvent( new CustomEvent("viewer-closed", { bubbles: !0, composed: !0 }) ), t && this.dispatchEvent( new CustomEvent("dialog-closed", { - detail: { dialog: He }, + detail: { dialog: Ue }, bubbles: !0, composed: !0 }) @@ -4417,94 +4439,94 @@ let f = class extends x { !this.inline || !this.open || this.mode !== "live" || (this.resetVisitorActions(), this.clearAutomaticLiveRecovery(), this.lifecycle.dispose(), this.releaseInlineLive(), this.session = this.lifecycle.current(), this.automaticLiveRetry = !1, this.mediaStatus = "awaiting-resume", this.statusAnnouncement = r(this.hass, "viewer.resume_live")); } }; -f.styles = so; +g.styles = ho; m([ _({ attribute: !1 }) -], f.prototype, "hass", 2); +], g.prototype, "hass", 2); m([ _({ attribute: !1 }) -], f.prototype, "config", 2); +], g.prototype, "config", 2); m([ _({ type: Boolean, reflect: !0 }) -], f.prototype, "open", 2); +], g.prototype, "open", 2); m([ _({ type: Boolean, reflect: !0 }) -], f.prototype, "inline", 2); +], g.prototype, "inline", 2); m([ u() -], f.prototype, "ringing", 2); +], g.prototype, "ringing", 2); m([ u() -], f.prototype, "mode", 2); +], g.prototype, "mode", 2); m([ u() -], f.prototype, "mediaStatus", 2); +], g.prototype, "mediaStatus", 2); m([ u() -], f.prototype, "session", 2); +], g.prototype, "session", 2); m([ u() -], f.prototype, "suspended", 2); +], g.prototype, "suspended", 2); m([ u() -], f.prototype, "recordingMuted", 2); +], g.prototype, "recordingMuted", 2); m([ u() -], f.prototype, "recordingStarted", 2); +], g.prototype, "recordingStarted", 2); m([ u() -], f.prototype, "recordingControlsVisible", 2); +], g.prototype, "recordingControlsVisible", 2); m([ u() -], f.prototype, "recordingEnded", 2); +], g.prototype, "recordingEnded", 2); m([ u() -], f.prototype, "liveMuted", 2); +], g.prototype, "liveMuted", 2); m([ u() -], f.prototype, "liveHasAudio", 2); +], g.prototype, "liveHasAudio", 2); m([ u() -], f.prototype, "recordingVideoFailed", 2); +], g.prototype, "recordingVideoFailed", 2); m([ u() -], f.prototype, "retryCount", 2); +], g.prototype, "retryCount", 2); m([ u() -], f.prototype, "statusAnnouncement", 2); +], g.prototype, "statusAnnouncement", 2); m([ u() -], f.prototype, "talkbackReady", 2); +], g.prototype, "talkbackReady", 2); m([ u() -], f.prototype, "talkbackRequesting", 2); +], g.prototype, "talkbackRequesting", 2); m([ u() -], f.prototype, "talkbackTalking", 2); +], g.prototype, "talkbackTalking", 2); m([ u() -], f.prototype, "doorActionStatus", 2); +], g.prototype, "doorActionStatus", 2); m([ u() -], f.prototype, "snapshotActionStatus", 2); +], g.prototype, "snapshotActionStatus", 2); m([ u() -], f.prototype, "snapshotFeedbackMessage", 2); +], g.prototype, "snapshotFeedbackMessage", 2); m([ u() -], f.prototype, "viewerFeedback", 2); +], g.prototype, "viewerFeedback", 2); m([ u() -], f.prototype, "inlineStarted", 2); -f = m([ - N(He) -], f); -const te = /* @__PURE__ */ new Map(), Mo = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ +], g.prototype, "inlineStarted", 2); +g = m([ + q(Ue) +], g); +const te = /* @__PURE__ */ new Map(), Uo = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, get RingViewDialog() { - return f; + return g; } -}, Symbol.toStringTag, { value: "Module" })), Do = [ +}, Symbol.toStringTag, { value: "Module" })), zo = [ "timestamp", "capture_timestamp", "captured_at", @@ -4512,7 +4534,7 @@ const te = /* @__PURE__ */ new Map(), Mo = /* @__PURE__ */ Object.freeze(/* @__P "last_recording_at", "recording_timestamp" ]; -function Io(e) { +function Fo(e) { if (typeof e == "number") return !Number.isFinite(e) || e <= 0 ? void 0 : e < 1e12 ? e * 1e3 : e; if (typeof e != "string" || e.trim() === "") return; @@ -4522,14 +4544,14 @@ function Io(e) { const i = Date.parse(e); return Number.isFinite(i) && i > 0 ? i : void 0; } -function Ae(e) { +function $e(e) { if (e) - for (const t of Do) { - const i = Io(e.attributes[t]); + for (const t of zo) { + const i = Fo(e.attributes[t]); if (i !== void 0) return i; } } -function Vo(e) { +function No(e) { if (e) for (const t of ["last_video_id", "video_url", "entity_picture"]) { const i = e.attributes[t]; @@ -4537,42 +4559,42 @@ function Vo(e) { if (typeof i == "number" && Number.isFinite(i)) return `${t}:${i}`; } } -function Ho(e, t, i) { - const o = t.recording_entity, s = t.snapshot_entity; - if (!s) return o; - const n = e.states[o], a = e.states[s], l = !w(n), d = !w(a); +function qo(e, t, i) { + const o = t.recording_entity, n = t.snapshot_entity; + if (!n) return o; + const s = e.states[o], a = e.states[n], l = !w(s), d = !w(a); if (l && !d) return o; - if (d && !l) return s; + if (d && !l) return n; if (l && d) { - const p = Ae(n), v = Ae(a); + const p = $e(s), v = $e(a); if (p !== void 0 && v !== void 0) - return p !== v ? v > p ? s : o : t.preview_fallback === "snapshot" ? s : o; + return p !== v ? v > p ? n : o : t.preview_fallback === "snapshot" ? n : o; if (i !== void 0) - return i === "snapshot" ? s : o; + return i === "snapshot" ? n : o; } - return t.preview_fallback === "snapshot" ? s : o; + return t.preview_fallback === "snapshot" ? n : o; } -function Oo(e, t, i, o) { +function Bo(e, t, i, o) { switch (t.preview_source) { case "live": return t.live_entity; case "snapshot": return t.snapshot_entity ?? t.recording_entity; case "newest": - return Ho(e, t, o); + return qo(e, t, o); case "default": return i === "live" ? t.live_entity : t.recording_entity; default: return t.recording_entity; } } -var Uo = Object.defineProperty, zo = Object.getOwnPropertyDescriptor, D = (e, t, i, o) => { - for (var s = o > 1 ? void 0 : o ? zo(t, i) : t, n = e.length - 1, a; n >= 0; n--) - (a = e[n]) && (s = (o ? a(t, i, s) : a(s)) || s); - return o && s && Uo(t, i, s), s; +var Ko = Object.defineProperty, Wo = Object.getOwnPropertyDescriptor, D = (e, t, i, o) => { + for (var n = o > 1 ? void 0 : o ? Wo(t, i) : t, s = e.length - 1, a; s >= 0; s--) + (a = e[s]) && (n = (o ? a(t, i, n) : a(n)) || n); + return o && n && Ko(t, i, n), n; }; -const Fo = 1e4, No = 640, qo = 16 / 9, st = 16, Bo = `data:image/svg+xml;charset=UTF-8,${encodeURIComponent( - di +const jo = 1e4, Zo = 640, Go = 16 / 9, at = 16, Yo = `data:image/svg+xml;charset=UTF-8,${encodeURIComponent( + pi )}`; let R = class extends x { constructor() { @@ -4609,22 +4631,22 @@ let R = class extends x { }; } static async getConfigElement() { - return await Promise.resolve().then(() => Yo), document.createElement("ring-view-editor"); + return await Promise.resolve().then(() => on), document.createElement("ring-view-editor"); } static getStubConfig(e) { - const t = Object.keys(e?.states ?? {}).filter((s) => s.startsWith("camera.")), i = t.find( - (s) => (Number(e?.states[s]?.attributes.supported_features ?? 0) & 2) !== 0 - ) ?? t.find((s) => /live(_view)?$/i.test(s)) ?? t[1] ?? "camera.live_view", o = t.find( - (s) => s !== i && (Number(e?.states[s]?.attributes.supported_features ?? 0) & 2) === 0 - ) ?? t.find((s) => s !== i) ?? t[0] ?? "camera.latest_recording"; + const t = Object.keys(e?.states ?? {}).filter((n) => n.startsWith("camera.")), i = t.find( + (n) => (Number(e?.states[n]?.attributes.supported_features ?? 0) & 2) !== 0 + ) ?? t.find((n) => /live(_view)?$/i.test(n)) ?? t[1] ?? "camera.live_view", o = t.find( + (n) => n !== i && (Number(e?.states[n]?.attributes.supported_features ?? 0) & 2) === 0 + ) ?? t.find((n) => n !== i) ?? t[0] ?? "camera.latest_recording"; return { - type: Me, + type: Ie, recording_entity: o, live_entity: i }; } setConfig(e) { - const t = be(e); + const t = ye(e); (t.recording_entity !== this.config?.recording_entity || t.snapshot_entity !== this.config?.snapshot_entity) && (this.previewMarkersInitialized = !1, this.recordingMarker = void 0, this.snapshotTimestamp = void 0, this.latestObservedPreviewSource = void 0), this.config = t; } getCardSize() { @@ -4655,11 +4677,11 @@ let R = class extends x { if (i !== "hass") return !0; if (!e.has("hass") || !this.hass || !this.config) return !1; const t = e.get("hass"); - return t ? t.language !== this.hass.language || t.locale?.language !== this.hass.locale?.language || t.states[this.config.recording_entity] !== this.hass.states[this.config.recording_entity] || t.states[this.config.live_entity] !== this.hass.states[this.config.live_entity] || this.config.snapshot_entity !== void 0 && t.states[this.config.snapshot_entity] !== this.hass.states[this.config.snapshot_entity] || this.config.last_activity_entity !== void 0 && t.states[this.config.last_activity_entity] !== this.hass.states[this.config.last_activity_entity] || this.config.doorbell_entity !== void 0 && t.states[this.config.doorbell_entity] !== this.hass.states[this.config.doorbell_entity] || this.config.door_entity !== void 0 && t.states[this.config.door_entity] !== this.hass.states[this.config.door_entity] || this.config.door_contact_entity !== void 0 && t.states[this.config.door_contact_entity] !== this.hass.states[this.config.door_contact_entity] : !0; + return t ? t.language !== this.hass.language || t.locale?.language !== this.hass.locale?.language || t.states[this.config.recording_entity] !== this.hass.states[this.config.recording_entity] || t.states[this.config.live_entity] !== this.hass.states[this.config.live_entity] || this.config.snapshot_entity !== void 0 && t.states[this.config.snapshot_entity] !== this.hass.states[this.config.snapshot_entity] || this.config.last_activity_entity !== void 0 && H(t, this.config.last_activity_entity) !== H(this.hass, this.config.last_activity_entity) || this.config.doorbell_entity !== void 0 && t.states[this.config.doorbell_entity] !== this.hass.states[this.config.doorbell_entity] || this.config.door_entity !== void 0 && t.states[this.config.door_entity] !== this.hass.states[this.config.door_entity] || this.config.door_contact_entity !== void 0 && t.states[this.config.door_contact_entity] !== this.hass.states[this.config.door_contact_entity] : !0; } willUpdate(e) { if (!this.hass || !this.config || (this.observePreviewMedia(), this.detectDoorbellEvent(e.get("hass")), this.isInCardPicker())) return; - const t = this.previewEntityId(), i = $t(this.hass, this.hass.states[t], t); + const t = this.previewEntityId(), i = Et(this.hass, this.hass.states[t], t); (t !== this.activePreviewEntityId || i !== this.lastFallbackPoster) && (this.activePreviewEntityId = t, this.lastFallbackPoster = i, this.lastPoster = i, this.lastPreviewSize = void 0, this.previewRequestId += 1, this.previewFailed = !1); } updated(e) { @@ -4671,14 +4693,14 @@ let R = class extends x { const e = this.previewEntityId(), t = this.hass.states[e], i = this.config.name || S( this.hass.states[this.config.recording_entity], r(this.hass, "common.camera") - ), o = this.ringAlertVisible ? "live" : ee(this.config), s = this.isInCardPicker(), n = s || this.preview, a = s ? !1 : w(t), l = { - "--ring-view-aspect-ratio": Zi(this.config.aspect_ratio), + ), o = this.ringAlertVisible ? "live" : ee(this.config), n = this.isInCardPicker(), s = n || this.preview, a = n ? !1 : w(t), l = { + "--ring-view-aspect-ratio": eo(this.config.aspect_ratio), "--ring-view-fit-mode": this.config.fit_mode }; - if (this.config.dashboard_behavior === "interactive" && !n) + if (this.config.dashboard_behavior === "interactive" && !s) return h` -
+
`; - const d = !n, p = Z( - this.config.last_activity_entity ? this.hass.states[this.config.last_activity_entity] : void 0 - ), v = p === void 0 ? void 0 : wt(this.hass, p), g = d ? r(this.hass, "card.open_viewer", { + const d = !s, p = this.config.last_activity_entity ? H(this.hass, this.config.last_activity_entity) : void 0, v = p === void 0 ? void 0 : $t(this.hass, p), f = d ? r(this.hass, "card.open_viewer", { name: i, - mode: io(o, this.hass) - }) : r(this.hass, "card.preview_alt", { name: i }), A = v ? `${g}. ${v.accessible}.` : g; + mode: co(o, this.hass) + }) : r(this.hass, "card.preview_alt", { name: i }), A = v ? `${f}. ${v.accessible}.` : f; return h` - +
${!a && !this.previewFailed ? h` ${r(this.hass, @@ -4732,7 +4752,7 @@ let R = class extends x { ` : c} ${this.ringAlertVisible ? h`
${r(this.hass, "ring.alert")}
` : c} @@ -4741,7 +4761,7 @@ let R = class extends x { `; } previewEntityId() { - return Oo( + return Bo( this.hass, this.config, ee(this.config), @@ -4749,9 +4769,9 @@ let R = class extends x { ); } observePreviewMedia() { - const e = Vo( + const e = No( this.hass?.states[this.config.recording_entity] - ), t = Ae( + ), t = $e( this.config.snapshot_entity ? this.hass?.states[this.config.snapshot_entity] : void 0 ); if (!this.previewMarkersInitialized) { @@ -4775,11 +4795,11 @@ let R = class extends x { } scheduleViewerRestore() { if (this.restoreViewerTimer !== void 0 || !this.config) return; - const e = we(); - ye(e, this.config) && (this.restoreViewerTimer = window.setTimeout(() => { + const e = ke(); + Ae(e, this.config) && (this.restoreViewerTimer = window.setTimeout(() => { if (this.restoreViewerTimer = void 0, !this.isConnected || !this.hass || !this.config) return; - const t = we(); - if (!ye(t, this.config)) return; + const t = ke(); + if (!Ae(t, this.config)) return; const i = this.renderRoot.querySelector(".preview") ?? void 0; this.config.dashboard_behavior === "interactive" && (this.renderRoot.querySelector("ring-view-dialog[inline]")?.stopInline(), this.inlinePausedForViewer = !0), ge(i ?? this, { config: this.config, @@ -4794,9 +4814,9 @@ let R = class extends x { const t = this.config?.doorbell_entity; if (!t || !e || !this.hass) return; const i = e.states[t], o = this.hass.states[t]; - if (!xt(t, i?.state, o)) return; - const s = Date.now(); - s - this.lastRingAlertAt < 5e3 || (this.lastRingAlertAt = s, this.updateRingAlert()); + if (!Mt(t, i?.state, o)) return; + const n = Date.now(); + n - this.lastRingAlertAt < 5e3 || (this.lastRingAlertAt = n, this.updateRingAlert()); } updateRingAlert() { this.clearRingAlertTimer(); @@ -4834,7 +4854,7 @@ let R = class extends x { if (e) { this.refreshPreview(!0), this.previewRefreshTimer = window.setInterval(() => { this.refreshPreview(!0); - }, Fo); + }, jo); return; } this.stopPreviewRefreshTimer(), this.previewRequestId += 1; @@ -4847,13 +4867,13 @@ let R = class extends x { if (this.isInCardPicker() || !this.previewVisible || !this.hass || !this.config) return; const t = this.renderRoot.querySelector(".preview"); if (!t) return; - const i = Math.max(1, window.devicePixelRatio || 1), o = t.clientWidth || t.getBoundingClientRect().width, s = o > 0 ? o : No, n = t.clientHeight || t.getBoundingClientRect().height, a = kt(this.config.aspect_ratio) ?? qo, l = n > 0 ? n : s / a, d = Math.ceil(s * i), p = Math.ceil(l * i); - if (!e && this.lastPreviewSize && Math.abs(d - this.lastPreviewSize.width) < st && Math.abs(p - this.lastPreviewSize.height) < st) + const i = Math.max(1, window.devicePixelRatio || 1), o = t.clientWidth || t.getBoundingClientRect().width, n = o > 0 ? o : Zo, s = t.clientHeight || t.getBoundingClientRect().height, a = Ct(this.config.aspect_ratio) ?? Go, l = s > 0 ? s : n / a, d = Math.ceil(n * i), p = Math.ceil(l * i); + if (!e && this.lastPreviewSize && Math.abs(d - this.lastPreviewSize.width) < at && Math.abs(p - this.lastPreviewSize.height) < at) return; this.lastPreviewSize = { width: d, height: p }; - const v = this.previewEntityId(), g = this.hass, A = ++this.previewRequestId; + const v = this.previewEntityId(), f = this.hass, A = ++this.previewRequestId; try { - const T = await eo(g, v, d, p); + const T = await ro(f, v, d, p); if (A !== this.previewRequestId || !this.isConnected || !this.previewVisible || this.previewEntityId() !== v) return; this.lastPoster = T, this.previewFailed = !1; @@ -4875,7 +4895,7 @@ let R = class extends x { return !1; } }; -R.styles = oo; +R.styles = lo; D([ _({ attribute: !1 }) ], R.prototype, "hass", 2); @@ -4898,12 +4918,12 @@ D([ u() ], R.prototype, "ringAlertVisible", 2); R = D([ - N(_e) + q(we) ], R); window.customCards = window.customCards || []; -window.customCards.some((e) => e.type === _e) || window.customCards.push({ - type: _e, - name: Ii, +window.customCards.some((e) => e.type === we) || window.customCards.push({ + type: we, + name: Fi, description: r(void 0, "card.description"), preview: !0, getEntitySuggestion: (e, t) => { @@ -4913,19 +4933,19 @@ window.customCards.some((e) => e.type === _e) || window.customCards.push({ ); return i ? { config: { - type: Me, + type: Ie, recording_entity: t, live_entity: i } } : null; } }); -var Ko = Object.defineProperty, Wo = Object.getOwnPropertyDescriptor, J = (e, t, i, o) => { - for (var s = o > 1 ? void 0 : o ? Wo(t, i) : t, n = e.length - 1, a; n >= 0; n--) - (a = e[n]) && (s = (o ? a(t, i, s) : a(s)) || s); - return o && s && Ko(t, i, s), s; +var Qo = Object.defineProperty, Jo = Object.getOwnPropertyDescriptor, J = (e, t, i, o) => { + for (var n = o > 1 ? void 0 : o ? Jo(t, i) : t, s = e.length - 1, a; s >= 0; s--) + (a = e[s]) && (n = (o ? a(t, i, n) : a(n)) || n); + return o && n && Qo(t, i, n), n; }; -function jo(e, t) { +function Xo(e, t) { const i = [ { name: "dashboard_behavior", @@ -5109,14 +5129,14 @@ function jo(e, t) { name: "dashboard_preview", type: "expandable", flatten: !0, - iconPath: Rt, + iconPath: Dt, schema: i }, { name: "viewer_behavior", type: "expandable", flatten: !0, - iconPath: Vt, + iconPath: Ft, schema: [ { name: "default_mode", @@ -5143,7 +5163,7 @@ function jo(e, t) { name: "snapshots", type: "expandable", flatten: !0, - iconPath: rt, + iconPath: ct, schema: [ { name: "show_snapshot_button", selector: { boolean: {} } }, ...t.show_snapshot_button ? [{ @@ -5157,7 +5177,7 @@ function jo(e, t) { name: "doorbell_features", type: "expandable", flatten: !0, - iconPath: Pt, + iconPath: Ht, schema: [ { name: "doorbell_entity", @@ -5176,14 +5196,14 @@ function jo(e, t) { name: "door_access", type: "expandable", flatten: !0, - iconPath: at, + iconPath: lt, schema: o }, { name: "card_appearance", type: "expandable", flatten: !0, - iconPath: It, + iconPath: zt, schema: [ { name: "name", selector: { text: {} } }, { name: "show_name", selector: { boolean: {} } }, @@ -5194,7 +5214,8 @@ function jo(e, t) { filter: [ { domain: "sensor" }, { domain: "event" }, - { domain: "input_datetime" } + { domain: "input_datetime" }, + { domain: "binary_sensor" } ] } } @@ -5253,7 +5274,7 @@ function jo(e, t) { } ]; } -const Zo = { +const en = { recording_entity: "editor.recording_entity", live_entity: "editor.live_entity", snapshot_entity: "editor.snapshot_entity", @@ -5287,7 +5308,7 @@ const Zo = { preview_fallback: "editor.preview_fallback", aspect_ratio: "editor.aspect_ratio", fit_mode: "editor.fit_mode" -}, Go = { +}, tn = { dashboard_behavior: "editor.helper_dashboard_behavior", dashboard_start: "editor.helper_dashboard_start", dashboard_live_muted: "editor.helper_dashboard_live_muted", @@ -5312,13 +5333,13 @@ const Zo = { let M = class extends x { constructor() { super(...arguments), this.nativeChecked = !1, this.nativeAvailable = !1, this.computeLabel = (e) => { - const t = Zo[e.name]; + const t = en[e.name]; if (!t) return; const i = r(this.hass, t); if (!["name", "door_contact_entity", "last_activity_entity"].includes( e.name )) return i; - const o = bt( + const o = kt( this.hass, "ui.panel.lovelace.editor.card.config.optional", "common.optional" @@ -5326,14 +5347,14 @@ let M = class extends x { return `${i} (${o})`; }, this.computeHelper = (e) => { if (e.name === "snapshot_directory" && this.config) { - const i = Ei(this.config.snapshot_directory); + const i = Vi(this.config.snapshot_directory); return i === "public" ? r(this.hass, "editor.helper_snapshot_directory_public") : i === "custom" ? r(this.hass, "editor.helper_snapshot_directory_custom") : void 0; } - const t = Go[e.name]; + const t = tn[e.name]; return t ? r(this.hass, t) : void 0; }, this.valueChanged = (e) => { if (!this.config) return; - const t = be({ + const t = ye({ ...this.config, ...e.detail.value }); @@ -5346,7 +5367,7 @@ let M = class extends x { "door_control_location" ]), o = Object.fromEntries( Object.entries(t).filter( - ([s, n]) => n !== void 0 && (!!t.door_entity || !i.has(s)) + ([n, s]) => s !== void 0 && (!!t.door_entity || !i.has(n)) ) ); this.dispatchEvent( @@ -5359,16 +5380,16 @@ let M = class extends x { }; } setConfig(e) { - this.config = be(e); + this.config = ye(e); } connectedCallback() { - super.connectedCallback(), Ct().then((e) => { + super.connectedCallback(), Pt().then((e) => { this.isConnected && (this.nativeAvailable = e, this.nativeChecked = !0); }); } render() { if (!this.hass || !this.config) return c; - const e = Ci(this.hass, this.config).filter( + const e = Mi(this.hass, this.config).filter( (t) => t.kind !== "compatibility" || this.nativeChecked && !this.nativeAvailable ); return h` @@ -5388,7 +5409,7 @@ let M = class extends x { { this.refreshTimer = undefined; diff --git a/src/ring-view-dialog.ts b/src/ring-view-dialog.ts index 98395f9..01b998b 100644 --- a/src/ring-view-dialog.ts +++ b/src/ring-view-dialog.ts @@ -53,7 +53,7 @@ import type { HomeAssistant, NormalizedConfig, } from "./types"; -import { activityTimestamp } from "./utilities/activity-time"; +import { resolveActivityTimestamp } from "./utilities/activity-time"; import { isDoorbellRingTransition } from "./utilities/doorbell"; import { entityIsUnavailable, @@ -337,11 +337,10 @@ export class RingViewDialog extends LitElement { if (!this.open || !this.hass || !this.config) return nothing; const title = this.dialogTitle(); const showTitle = this.config.show_name; - const showActivity = activityTimestamp( - this.config.last_activity_entity - ? this.hass.states[this.config.last_activity_entity] - : undefined, - ) !== undefined; + const showActivity = this.config.last_activity_entity + ? resolveActivityTimestamp(this.hass, this.config.last_activity_entity) + !== undefined + : false; const ratio = this.config.aspect_ratio; const style = { "--ring-view-aspect-ratio": diff --git a/src/ring-view-editor.ts b/src/ring-view-editor.ts index ac3214e..de63840 100644 --- a/src/ring-view-editor.ts +++ b/src/ring-view-editor.ts @@ -329,6 +329,7 @@ function configSchema( { domain: "sensor" }, { domain: "event" }, { domain: "input_datetime" }, + { domain: "binary_sensor" }, ], }, }, diff --git a/src/ring-view.ts b/src/ring-view.ts index fe24e89..a1a73ca 100644 --- a/src/ring-view.ts +++ b/src/ring-view.ts @@ -26,8 +26,8 @@ import { loadMode } from "./utilities/mode-storage"; import "./ring-view-dialog"; import type { RingViewDialog } from "./ring-view-dialog"; import { - activityTimestamp, formatActivityTime, + resolveActivityTimestamp, } from "./utilities/activity-time"; import { isDoorbellRingTransition } from "./utilities/doorbell"; import { @@ -189,8 +189,8 @@ export class RingView extends LitElement { previous.states[this.config.snapshot_entity] !== this.hass.states[this.config.snapshot_entity]) || (this.config.last_activity_entity !== undefined && - previous.states[this.config.last_activity_entity] !== - this.hass.states[this.config.last_activity_entity]) || + resolveActivityTimestamp(previous, this.config.last_activity_entity) !== + resolveActivityTimestamp(this.hass, this.config.last_activity_entity)) || (this.config.doorbell_entity !== undefined && previous.states[this.config.doorbell_entity] !== this.hass.states[this.config.doorbell_entity]) || @@ -283,11 +283,9 @@ export class RingView extends LitElement { } const previewInteractive = !safePreview; - const activityAt = activityTimestamp( - this.config.last_activity_entity - ? this.hass.states[this.config.last_activity_entity] - : undefined, - ); + const activityAt = this.config.last_activity_entity + ? resolveActivityTimestamp(this.hass, this.config.last_activity_entity) + : undefined; const activity = activityAt === undefined ? undefined : formatActivityTime(this.hass, activityAt); diff --git a/src/translations/de.json b/src/translations/de.json index 70da3a6..8f51f1c 100644 --- a/src/translations/de.json +++ b/src/translations/de.json @@ -65,7 +65,7 @@ "editor.helper_door_hold_to_activate": "Vor Ablauf einer Sekunde loslassen, um abzubrechen. Wenn deaktiviert, betätigt ein einzelnes Tippen die Tür.", "editor.helper_door_control_location": "Lege fest, wo die Türaktion erscheint. Nur Vollbild ist für gemeinsam genutzte Dashboards sicherer.", "editor.helper_show_name": "Wird oben links auf der Karte und in der Kameraansicht angezeigt.", - "editor.helper_last_activity_entity": "Zeigt oben links eine relative Zeit an, bei sichtbarem Kameranamen darunter. Wähle einen Zeitstempel-Sensor, eine Ereignis-Entität oder einen Datum-und-Uhrzeit-Helfer, dessen Zustand Datum und Uhrzeit enthält.", + "editor.helper_last_activity_entity": "Zeigt oben links eine relative Zeit an, bei sichtbarem Kameranamen darunter. Wähle einen Zeitstempel-Sensor, eine Ereignis-Entität, einen Datum-und-Uhrzeit-Helfer oder einen Ring-MQTT-Klingel- oder Bewegungssensor.", "editor.helper_preview_source": "Verwendet immer ein Standbild und bindet auf dem Dashboard keinen Livestream ein.", "editor.helper_snapshot_entity": "Wähle die von Ring-MQTT oder einer anderen Integration bereitgestellte Schnappschuss-Kamera.", "editor.helper_preview_fallback": "Wird verwendet, wenn beide Bilder verfügbar sind, ihre Aufnahmezeiten aber nicht zuverlässig verglichen werden können.", @@ -98,7 +98,7 @@ "warning.doorbell_event": "Das ausgewählte Türklingelereignis unterstützt den Ereignistyp ring nicht.", "warning.door_open_unsupported": "Das ausgewählte Schloss unterstützt das Öffnen der Türfalle nicht. Wähle Entriegeln oder ein kompatibles Schloss.", "warning.snapshot_required": "Wähle eine Kamera für Geräte-Schnappschüsse aus, um diese Vorschauoption zu verwenden.", - "warning.activity_timestamp": "Die ausgewählte Entität für die letzte Aktivität liefert derzeit kein gültiges Datum mit Uhrzeit in ihrem Zustand.", + "warning.activity_timestamp": "Die ausgewählte Entität für die letzte Aktivität liefert derzeit kein gültiges Aktivitätsdatum mit Uhrzeit.", "warning.compatibility": "Die native Kamerakomponente von Home Assistant ist noch nicht geladen. Die Karte versucht, sie beim Öffnen zu laden.", "config.invalid": "Ungültige Kartenkonfiguration.", "config.entity_required": "{label} muss eine Kamera-Entität sein.", diff --git a/src/translations/en.json b/src/translations/en.json index 2d6eefa..24d35c8 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -65,7 +65,7 @@ "editor.helper_door_hold_to_activate": "Release before one second to cancel. Turning this off makes a single tap operate the door.", "editor.helper_door_control_location": "Choose where the door action appears. Fullscreen only is safer for shared dashboards.", "editor.helper_show_name": "Shown at the top left of both the card and viewer.", - "editor.helper_last_activity_entity": "Shows relative time at the top left, below the camera name when it is visible. Choose a timestamp sensor, event entity, or Date and/or time helper whose state contains both a date and time.", + "editor.helper_last_activity_entity": "Shows relative time at the top left, below the camera name when it is visible. Choose a timestamp sensor, event entity, Date and/or time helper, or a Ring-MQTT Ding or motion sensor.", "editor.helper_preview_source": "Always uses a still image and never mounts a live stream on the dashboard.", "editor.helper_snapshot_entity": "Choose the snapshot camera provided by Ring-MQTT or another integration.", "editor.helper_preview_fallback": "Used when both images are available but their capture times cannot be reliably compared.", @@ -98,7 +98,7 @@ "warning.doorbell_event": "The selected doorbell event does not advertise the ring event type.", "warning.door_open_unsupported": "The selected lock does not advertise support for opening the door latch. Choose Unlock or a compatible lock.", "warning.snapshot_required": "Select a device snapshot camera to use this preview option.", - "warning.activity_timestamp": "The selected last activity entity does not currently provide a valid date and time in its state.", + "warning.activity_timestamp": "The selected last activity entity does not currently provide a valid activity date and time.", "warning.compatibility": "Home Assistant’s native camera component is not loaded yet. The card will attempt to load it when opened.", "config.invalid": "Invalid card configuration.", "config.entity_required": "{label} must be a camera entity.", diff --git a/src/utilities/activity-time.ts b/src/utilities/activity-time.ts index 1941e03..b95871a 100644 --- a/src/utilities/activity-time.ts +++ b/src/utilities/activity-time.ts @@ -1,10 +1,21 @@ import { languageCode, localize } from "../localize"; import type { HassEntity, HomeAssistant } from "../types"; +import { + resolveEntitySource, + sameDeviceEntityIds, +} from "./entity-sources"; const DATE_TIME_PATTERN = /^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(Z|[+-]\d{2}:?\d{2})?$/i; const NUMERIC_PATTERN = /^-?\d+(?:\.\d+)?$/; const UNIX_MILLISECONDS_THRESHOLD = 100_000_000_000; +const RING_MQTT_ACTIVITY_ATTRIBUTES = [ + "lastDingTime", + "lastMotionTime", + "lastDing", + "lastMotion", +] as const; +const UNAVAILABLE_STATES = new Set(["unknown", "unavailable"]); export interface ActivityTimeDisplay { relative: string; @@ -61,6 +72,66 @@ export function activityTimestamp(entity?: HassEntity): number | undefined { return parseTimestampValue(entity?.state); } +function latestTimestamp(values: Array): number | undefined { + const timestamps = values.filter((value): value is number => value !== undefined); + return timestamps.length > 0 ? Math.max(...timestamps) : undefined; +} + +/** + * Ring-MQTT exposes the latest Ding and motion timestamps as attributes on its + * binary sensors. Restricting this to the documented keys avoids presenting + * unrelated Home Assistant metadata as camera activity. + */ +export function ringMqttActivityTimestamp( + entity?: HassEntity, +): number | undefined { + if (!entity || UNAVAILABLE_STATES.has(entity.state)) return undefined; + return latestTimestamp( + RING_MQTT_ACTIVITY_ATTRIBUTES.map((attribute) => + parseTimestampValue(entity.attributes[attribute]), + ), + ); +} + +/** + * Resolve the configured activity source without relying on last_changed or + * last_updated. Official Ring timestamp entities continue to use their state. + * A Ring-MQTT binary sensor additionally contributes its own approved + * attributes and those of available MQTT binary-sensor siblings on the same + * Home Assistant device. + */ +export function resolveActivityTimestamp( + hass: HomeAssistant, + entityId: string, +): number | undefined { + const selected = hass.states[entityId]; + const selectedAvailable = selected && !UNAVAILABLE_STATES.has(selected.state); + const candidates = selectedAvailable + ? [activityTimestamp(selected)] + : []; + if (!entityId.startsWith("binary_sensor.")) { + return latestTimestamp(candidates); + } + + if (selectedAvailable) { + candidates.push(ringMqttActivityTimestamp(selected)); + } + const source = resolveEntitySource(hass, "activity", entityId); + if (source.provider !== "mqtt") return latestTimestamp(candidates); + + for (const siblingId of sameDeviceEntityIds(hass, entityId)) { + if ( + siblingId === entityId + || !siblingId.startsWith("binary_sensor.") + || resolveEntitySource(hass, "activity", siblingId).provider !== "mqtt" + ) { + continue; + } + candidates.push(ringMqttActivityTimestamp(hass.states[siblingId])); + } + return latestTimestamp(candidates); +} + function relativeUnit(deltaSeconds: number): { unit: Intl.RelativeTimeFormatUnit; seconds: number; diff --git a/src/utilities/entity-validation.ts b/src/utilities/entity-validation.ts index cd86775..f53566c 100644 --- a/src/utilities/entity-validation.ts +++ b/src/utilities/entity-validation.ts @@ -1,6 +1,6 @@ import { localize } from "../localize"; import type { HassEntity, HomeAssistant, NormalizedConfig } from "../types"; -import { activityTimestamp } from "./activity-time"; +import { resolveActivityTimestamp } from "./activity-time"; import { resolveEntitySource } from "./entity-sources"; export const CAMERA_STREAM_FEATURE = 2; @@ -124,7 +124,9 @@ export function validateEntities( name: friendlyName(activity, config.last_activity_entity), }), }); - } else if (activityTimestamp(activity) === undefined) { + } else if ( + resolveActivityTimestamp(hass, config.last_activity_entity) === undefined + ) { warnings.push({ kind: "last_activity", message: localize(hass, "warning.activity_timestamp"), diff --git a/tests/browser/card.spec.ts b/tests/browser/card.spec.ts index eb3c72c..b47628a 100644 --- a/tests/browser/card.spec.ts +++ b/tests/browser/card.spec.ts @@ -186,12 +186,13 @@ test("places the optional last activity source beside the name appearance contro { domain: "sensor" }, { domain: "event" }, { domain: "input_datetime" }, + { domain: "binary_sensor" }, ], }, }, label: "Last activity timestamp (optional)", helper: - "Shows relative time at the top left, below the camera name when it is visible. Choose a timestamp sensor, event entity, or Date and/or time helper whose state contains both a date and time.", + "Shows relative time at the top left, below the camera name when it is visible. Choose a timestamp sensor, event entity, Date and/or time helper, or a Ring-MQTT Ding or motion sensor.", }); }); diff --git a/tests/unit/activity-time.test.ts b/tests/unit/activity-time.test.ts index b097fc8..ef2f708 100644 --- a/tests/unit/activity-time.test.ts +++ b/tests/unit/activity-time.test.ts @@ -5,6 +5,8 @@ import { activityTimestamp, formatActivityTime, parseTimestampValue, + resolveActivityTimestamp, + ringMqttActivityTimestamp, } from "../../src/utilities/activity-time"; const entity = (state: string): HassEntity => ({ @@ -58,6 +60,110 @@ describe("last activity timestamps", () => { expect(activityTimestamp(entity("unknown"))).toBeUndefined(); }); + it("reads only the approved Ring-MQTT Ding and motion attributes", () => { + const mqttEntity: HassEntity = { + entity_id: "binary_sensor.front_door_ding", + state: "off", + attributes: { + lastDingTime: "2026-09-12T10:15:30Z", + lastMotionTime: "2026-09-12T10:16:30Z", + lastDing: 1_789_208_130, + lastMotion: "1789208250000", + timestamp: "2026-09-12T11:00:00Z", + }, + last_changed: "2026-09-12T12:00:00Z", + last_updated: "2026-09-12T13:00:00Z", + }; + + expect(ringMqttActivityTimestamp(mqttEntity)).toBe(1_789_208_250_000); + expect(ringMqttActivityTimestamp({ + ...mqttEntity, + state: "unavailable", + })).toBeUndefined(); + expect(ringMqttActivityTimestamp({ + ...mqttEntity, + attributes: { timestamp: "2026-09-12T11:00:00Z" }, + })).toBeUndefined(); + }); + + it("uses the freshest available MQTT Ding or motion sibling on the same device", () => { + const ding: HassEntity = { + entity_id: "binary_sensor.renamed_ding", + state: "off", + attributes: { lastDingTime: "2026-09-12T10:15:30Z" }, + }; + const motion: HassEntity = { + entity_id: "binary_sensor.renamed_motion", + state: "off", + attributes: { lastMotionTime: "2026-09-12T10:17:30Z" }, + }; + const unavailable: HassEntity = { + entity_id: "binary_sensor.unavailable_motion", + state: "unavailable", + attributes: { lastMotionTime: "2026-09-12T10:20:30Z" }, + }; + const info: HassEntity = { + entity_id: "sensor.renamed_info", + state: "2026-09-12T10:30:30Z", + attributes: { lastMotionTime: "2026-09-12T10:30:30Z" }, + }; + const hass: HomeAssistant = { + states: { + [ding.entity_id]: ding, + [motion.entity_id]: motion, + [unavailable.entity_id]: unavailable, + [info.entity_id]: info, + }, + entities: Object.fromEntries( + Object.keys({ + [ding.entity_id]: ding, + [motion.entity_id]: motion, + [unavailable.entity_id]: unavailable, + [info.entity_id]: info, + }).map((entityId) => [entityId, { + entity_id: entityId, + platform: "mqtt", + device_id: "front-door", + }]), + ), + hassUrl: (path = "") => path, + callWS: async () => ({}) as never, + }; + + expect(resolveActivityTimestamp(hass, ding.entity_id)).toBe( + Date.parse("2026-09-12T10:17:30Z"), + ); + + hass.states[ding.entity_id] = { ...ding, state: "unavailable" }; + expect(resolveActivityTimestamp(hass, ding.entity_id)).toBe( + Date.parse("2026-09-12T10:17:30Z"), + ); + }); + + it("degrades to selected attributes without registry data and preserves state timestamps", () => { + const ding: HassEntity = { + entity_id: "binary_sensor.front_door_ding", + state: "off", + attributes: { lastDingTime: "2026-09-12T10:15:30Z" }, + }; + const official = entity("2026-09-12T10:18:30Z"); + const hass: HomeAssistant = { + states: { + [ding.entity_id]: ding, + [official.entity_id]: official, + }, + hassUrl: (path = "") => path, + callWS: async () => ({}) as never, + }; + + expect(resolveActivityTimestamp(hass, ding.entity_id)).toBe( + Date.parse("2026-09-12T10:15:30Z"), + ); + expect(resolveActivityTimestamp(hass, official.entity_id)).toBe( + Date.parse("2026-09-12T10:18:30Z"), + ); + }); + it("formats compact visible text and a fuller accessible label in English", () => { const now = Date.parse("2026-09-12T10:15:30Z"); const display = formatActivityTime( diff --git a/tests/unit/card-lifecycle.test.ts b/tests/unit/card-lifecycle.test.ts index 3eca42e..00d344e 100644 --- a/tests/unit/card-lifecycle.test.ts +++ b/tests/unit/card-lifecycle.test.ts @@ -363,6 +363,69 @@ describe("card stream lifecycle", () => { ); }); + it("updates Ring-MQTT activity when a same-device motion sibling changes", async () => { + vi.useFakeTimers(); + vi.setSystemTime(Date.parse("2026-09-12T10:30:30Z")); + const ding: HassEntity = { + entity_id: "binary_sensor.renamed_ding", + state: "off", + attributes: { lastDingTime: "2026-09-12T10:15:30Z" }, + }; + const motion: HassEntity = { + entity_id: "binary_sensor.renamed_motion", + state: "off", + attributes: { lastMotionTime: "2026-09-12T10:17:30Z" }, + }; + const mqttHass: HomeAssistant = { + ...hass, + states: { + ...hass.states, + [ding.entity_id]: ding, + [motion.entity_id]: motion, + }, + entities: { + ...hass.entities, + [ding.entity_id]: { + entity_id: ding.entity_id, + platform: "mqtt", + device_id: "front-door", + }, + [motion.entity_id]: { + entity_id: motion.entity_id, + platform: "mqtt", + device_id: "front-door", + }, + }, + }; + const card = document.createElement("ring-view"); + card.setConfig({ + recording_entity: "camera.recording", + live_entity: "camera.live", + last_activity_entity: ding.entity_id, + }); + card.hass = mqttHass; + document.body.append(card); + await card.updateComplete; + let activity = card.shadowRoot?.querySelector("ring-view-activity-time"); + await activity?.updateComplete; + expect(activity?.shadowRoot?.textContent).toContain("13 min ago"); + + card.hass = { + ...mqttHass, + states: { + ...mqttHass.states, + [motion.entity_id]: { + ...motion, + attributes: { lastMotionTime: "2026-09-12T10:25:30Z" }, + }, + }, + }; + await card.updateComplete; + activity = card.shadowRoot?.querySelector("ring-view-activity-time"); + await activity?.updateComplete; + expect(activity?.shadowRoot?.textContent).toContain("5 min ago"); + }); + it("keeps the card and viewer name hidden while preserving a dialog label", async () => { const card = await mount(); expect(card.shadowRoot?.querySelector(".name")).toBeNull(); diff --git a/tests/unit/editor.test.ts b/tests/unit/editor.test.ts index 6570685..c0a961e 100644 --- a/tests/unit/editor.test.ts +++ b/tests/unit/editor.test.ts @@ -475,6 +475,7 @@ describe("visual editor", () => { { domain: "sensor" }, { domain: "event" }, { domain: "input_datetime" }, + { domain: "binary_sensor" }, ], }, }); diff --git a/tests/unit/entity-validation.test.ts b/tests/unit/entity-validation.test.ts index 0347e17..61ab7a7 100644 --- a/tests/unit/entity-validation.test.ts +++ b/tests/unit/entity-validation.test.ts @@ -265,7 +265,7 @@ describe("entity validation", () => { ); }); - it("validates the configured last activity timestamp without exposing its value", () => { + it("validates the configured last activity source without exposing its value", () => { const config = normalizeConfig({ recording_entity: "camera.recording", live_entity: "camera.live", @@ -301,7 +301,7 @@ describe("entity validation", () => { }; const invalidWarnings = validateEntities(hass, config); expect(invalidWarnings.find((warning) => warning.kind === "last_activity")?.message) - .toContain("does not currently provide a valid date and time"); + .toContain("does not currently provide a valid activity date and time"); expect(JSON.stringify(invalidWarnings)).not.toContain( "motion detected at the front door", ); @@ -311,4 +311,40 @@ describe("entity validation", () => { "last_activity", ); }); + + it("accepts Ring-MQTT Ding attributes as a last activity source", () => { + const activity = { + ...entity("binary_sensor.front_door_ding", { + lastDingTime: "2026-09-12T10:15:30Z", + }), + state: "off", + }; + const config = normalizeConfig({ + recording_entity: "camera.recording", + live_entity: "camera.live", + last_activity_entity: activity.entity_id, + }); + const hass: HomeAssistant = { + states: { + "camera.recording": entity("camera.recording", { + entity_picture: "/recording.jpg", + }), + "camera.live": entity("camera.live", { supported_features: 2 }), + [activity.entity_id]: activity, + }, + entities: { + [activity.entity_id]: { + entity_id: activity.entity_id, + platform: "mqtt", + device_id: "front-door", + }, + }, + hassUrl: (path = "") => path, + callWS: async () => ({}) as never, + }; + + expect(validateEntities(hass, config).map((warning) => warning.kind)).not.toContain( + "last_activity", + ); + }); });