UNPKG

dictate-button

Version:

Customizable Web Component that adds speech-to-text dictation capabilities to text fields

764 lines (756 loc) 25.9 kB
const St = (t, n) => t === n, I = { equals: St }; let pt = _t; const x = 1, N = 2, ht = { owned: null, cleanups: null, context: null, owner: null }; var b = null; let W = null, xt = null, g = null, w = null, E = null, z = 0; function At(t, n) { const e = g, o = b, r = t.length === 0, i = n === void 0 ? o : n, l = r ? ht : { owned: null, cleanups: null, context: i ? i.context : null, owner: i }, s = r ? t : () => t(() => V(() => L(l))); b = l, g = null; try { return M(s, !0); } finally { g = e, b = o; } } function gt(t, n) { n = n ? Object.assign({}, I, n) : I; const e = { value: t, observers: null, observerSlots: null, comparator: n.equals || void 0 }, o = (r) => (typeof r == "function" && (r = r(e.value)), yt(e, r)); return [bt.bind(e), o]; } function D(t, n, e) { const o = Z(t, n, !1, x); $(o); } function kt(t, n, e) { pt = Mt; const o = Z(t, n, !1, x); o.user = !0, E ? E.push(o) : $(o); } function Tt(t, n, e) { e = e ? Object.assign({}, I, e) : I; const o = Z(t, n, !0, 0); return o.observers = null, o.observerSlots = null, o.comparator = e.equals || void 0, $(o), bt.bind(o); } function V(t) { if (g === null) return t(); const n = g; g = null; try { return t(); } finally { g = n; } } function Pt(t) { return b === null || (b.cleanups === null ? b.cleanups = [t] : b.cleanups.push(t)), t; } function bt() { if (this.sources && this.state) if (this.state === x) $(this); else { const t = w; w = null, M(() => K(this), !1), w = t; } if (g) { const t = this.observers ? this.observers.length : 0; g.sources ? (g.sources.push(this), g.sourceSlots.push(t)) : (g.sources = [this], g.sourceSlots = [t]), this.observers ? (this.observers.push(g), this.observerSlots.push(g.sources.length - 1)) : (this.observers = [g], this.observerSlots = [g.sources.length - 1]); } return this.value; } function yt(t, n, e) { let o = t.value; return (!t.comparator || !t.comparator(o, n)) && (t.value = n, t.observers && t.observers.length && M(() => { for (let r = 0; r < t.observers.length; r += 1) { const i = t.observers[r], l = W && W.running; l && W.disposed.has(i), (l ? !i.tState : !i.state) && (i.pure ? w.push(i) : E.push(i), i.observers && wt(i)), l || (i.state = x); } if (w.length > 1e6) throw w = [], new Error(); }, !1)), n; } function $(t) { if (!t.fn) return; L(t); const n = z; Lt(t, t.value, n); } function Lt(t, n, e) { let o; const r = b, i = g; g = b = t; try { o = t.fn(n); } catch (l) { return t.pure && (t.state = x, t.owned && t.owned.forEach(L), t.owned = null), t.updatedAt = e + 1, vt(l); } finally { g = i, b = r; } (!t.updatedAt || t.updatedAt <= e) && (t.updatedAt != null && "observers" in t ? yt(t, o) : t.value = o, t.updatedAt = e); } function Z(t, n, e, o = x, r) { const i = { fn: t, state: o, updatedAt: null, owned: null, sources: null, sourceSlots: null, cleanups: null, value: n, owner: b, context: b ? b.context : null, pure: e }; return b === null || b !== ht && (b.owned ? b.owned.push(i) : b.owned = [i]), i; } function F(t) { if (t.state === 0) return; if (t.state === N) return K(t); if (t.suspense && V(t.suspense.inFallback)) return t.suspense.effects.push(t); const n = [t]; for (; (t = t.owner) && (!t.updatedAt || t.updatedAt < z); ) t.state && n.push(t); for (let e = n.length - 1; e >= 0; e--) if (t = n[e], t.state === x) $(t); else if (t.state === N) { const o = w; w = null, M(() => K(t, n[0]), !1), w = o; } } function M(t, n) { if (w) return t(); let e = !1; n || (w = []), E ? e = !0 : E = [], z++; try { const o = t(); return $t(e), o; } catch (o) { e || (E = null), w = null, vt(o); } } function $t(t) { if (w && (_t(w), w = null), t) return; const n = E; E = null, n.length && M(() => pt(n), !1); } function _t(t) { for (let n = 0; n < t.length; n++) F(t[n]); } function Mt(t) { let n, e = 0; for (n = 0; n < t.length; n++) { const o = t[n]; o.user ? t[e++] = o : F(o); } for (n = 0; n < e; n++) F(t[n]); } function K(t, n) { t.state = 0; for (let e = 0; e < t.sources.length; e += 1) { const o = t.sources[e]; if (o.sources) { const r = o.state; r === x ? o !== n && (!o.updatedAt || o.updatedAt < z) && F(o) : r === N && K(o, n); } } } function wt(t) { for (let n = 0; n < t.observers.length; n += 1) { const e = t.observers[n]; e.state || (e.state = N, e.pure ? w.push(e) : E.push(e), e.observers && wt(e)); } } function L(t) { let n; if (t.sources) for (; t.sources.length; ) { const e = t.sources.pop(), o = t.sourceSlots.pop(), r = e.observers; if (r && r.length) { const i = r.pop(), l = e.observerSlots.pop(); o < r.length && (i.sourceSlots[l] = o, r[o] = i, e.observerSlots[o] = l); } } if (t.tOwned) { for (n = t.tOwned.length - 1; n >= 0; n--) L(t.tOwned[n]); delete t.tOwned; } if (t.owned) { for (n = t.owned.length - 1; n >= 0; n--) L(t.owned[n]); t.owned = null; } if (t.cleanups) { for (n = t.cleanups.length - 1; n >= 0; n--) t.cleanups[n](); t.cleanups = null; } t.state = 0; } function Ot(t) { return t instanceof Error ? t : new Error(typeof t == "string" ? t : "Unknown error", { cause: t }); } function vt(t, n = b) { throw Ot(t); } function j(t, n) { return V(() => t(n || {})); } const B = (t) => Tt(() => t()); function Rt(t, n, e) { let o = e.length, r = n.length, i = o, l = 0, s = 0, a = n[r - 1].nextSibling, d = null; for (; l < r || s < i; ) { if (n[l] === e[s]) { l++, s++; continue; } for (; n[r - 1] === e[i - 1]; ) r--, i--; if (r === l) { const c = i < o ? s ? e[s - 1].nextSibling : e[i - s] : a; for (; s < i; ) t.insertBefore(e[s++], c); } else if (i === s) for (; l < r; ) (!d || !d.has(n[l])) && n[l].remove(), l++; else if (n[l] === e[i - 1] && e[s] === n[r - 1]) { const c = n[--r].nextSibling; t.insertBefore(e[s++], n[l++].nextSibling), t.insertBefore(e[--i], c), n[r] = e[i]; } else { if (!d) { d = /* @__PURE__ */ new Map(); let y = s; for (; y < i; ) d.set(e[y], y++); } const c = d.get(n[l]); if (c != null) if (s < c && c < i) { let y = l, C = 1, p; for (; ++y < r && y < i && !((p = d.get(n[y])) == null || p !== c + C); ) C++; if (C > c - s) { const q = n[l]; for (; s < c; ) t.insertBefore(e[s++], q); } else t.replaceChild(e[s++], n[l++]); } else l++; else n[l++].remove(); } } } function O(t, n, e, o) { let r; const i = () => { const s = document.createElement("template"); return s.innerHTML = t, s.content.firstChild; }, l = () => (r || (r = i())).cloneNode(!0); return l.cloneNode = l, l; } function P(t, n, e) { e == null ? t.removeAttribute(n) : t.setAttribute(n, e); } function jt(t, n, e) { if (!n) return e ? P(t, "style") : n; const o = t.style; if (typeof n == "string") return o.cssText = n; typeof e == "string" && (o.cssText = e = void 0), e || (e = {}), n || (n = {}); let r, i; for (i in e) n[i] == null && o.removeProperty(i), delete e[i]; for (i in n) r = n[i], r !== e[i] && (o.setProperty(i, r), e[i] = r); return e; } function Bt(t, n, e) { return V(() => t(n, e)); } function A(t, n, e, o) { if (e !== void 0 && !o && (o = []), typeof n != "function") return U(t, n, o, e); D((r) => U(t, n(), r, e), o); } function U(t, n, e, o, r) { for (; typeof e == "function"; ) e = e(); if (n === e) return e; const i = typeof n, l = o !== void 0; if (t = l && e[0] && e[0].parentNode || t, i === "string" || i === "number") { if (i === "number" && (n = n.toString(), n === e)) return e; if (l) { let s = e[0]; s && s.nodeType === 3 ? s.data !== n && (s.data = n) : s = document.createTextNode(n), e = k(t, e, o, s); } else e !== "" && typeof e == "string" ? e = t.firstChild.data = n : e = t.textContent = n; } else if (n == null || i === "boolean") e = k(t, e, o); else { if (i === "function") return D(() => { let s = n(); for (; typeof s == "function"; ) s = s(); e = U(t, s, e, o); }), () => e; if (Array.isArray(n)) { const s = [], a = e && Array.isArray(e); if (X(s, n, e, r)) return D(() => e = U(t, s, e, o, !0)), () => e; if (s.length === 0) { if (e = k(t, e, o), l) return e; } else a ? e.length === 0 ? at(t, s, o) : Rt(t, e, s) : (e && k(t), at(t, s)); e = s; } else if (n.nodeType) { if (Array.isArray(e)) { if (l) return e = k(t, e, o, n); k(t, e, null, n); } else e == null || e === "" || !t.firstChild ? t.appendChild(n) : t.replaceChild(n, t.firstChild); e = n; } } return e; } function X(t, n, e, o) { let r = !1; for (let i = 0, l = n.length; i < l; i++) { let s = n[i], a = e && e[t.length], d; if (!(s == null || s === !0 || s === !1)) if ((d = typeof s) == "object" && s.nodeType) t.push(s); else if (Array.isArray(s)) r = X(t, s, a) || r; else if (d === "function") if (o) { for (; typeof s == "function"; ) s = s(); r = X(t, Array.isArray(s) ? s : [s], Array.isArray(a) ? a : [a]) || r; } else t.push(s), r = !0; else { const c = String(s); a && a.nodeType === 3 && a.data === c ? t.push(a) : t.push(document.createTextNode(c)); } } return r; } function at(t, n, e = null) { for (let o = 0, r = n.length; o < r; o++) t.insertBefore(n[o], e); } function k(t, n, e, o) { if (e === void 0) return t.textContent = ""; const r = o || document.createTextNode(""); if (n.length) { let i = !1; for (let l = n.length - 1; l >= 0; l--) { const s = n[l]; if (r !== s) { const a = s.parentNode === t; !i && !l ? a ? t.replaceChild(r, s) : t.insertBefore(r, e) : a && s.remove(); } else i = !0; } } else t.insertBefore(r, e); return [r]; } function It(t) { return Object.keys(t).reduce((e, o) => { const r = t[o]; return e[o] = Object.assign({}, r), mt(r.value) && !Ut(r.value) && !Array.isArray(r.value) && (e[o].value = Object.assign({}, r.value)), Array.isArray(r.value) && (e[o].value = r.value.slice(0)), e; }, {}); } function Nt(t) { return t ? Object.keys(t).reduce((e, o) => { const r = t[o]; return e[o] = mt(r) && "value" in r ? r : { value: r }, e[o].attribute || (e[o].attribute = Kt(o)), e[o].parse = "parse" in e[o] ? e[o].parse : typeof e[o].value != "string", e; }, {}) : {}; } function Dt(t) { return Object.keys(t).reduce((e, o) => (e[o] = t[o].value, e), {}); } function Ft(t, n) { const e = It(n); return Object.keys(n).forEach((r) => { const i = e[r], l = t.getAttribute(i.attribute), s = t[r]; l != null && (i.value = i.parse ? Ct(l) : l), s != null && (i.value = Array.isArray(s) ? s.slice(0) : s), i.reflect && ct(t, i.attribute, i.value, !!i.parse), Object.defineProperty(t, r, { get() { return i.value; }, set(a) { const d = i.value; i.value = a, i.reflect && ct(this, i.attribute, i.value, !!i.parse); for (let c = 0, y = this.__propertyChangedCallbacks.length; c < y; c++) this.__propertyChangedCallbacks[c](r, a, d); }, enumerable: !0, configurable: !0 }); }), e; } function Ct(t) { if (t) try { return JSON.parse(t); } catch { return t; } } function ct(t, n, e, o) { if (e == null || e === !1) return t.removeAttribute(n); let r = o ? JSON.stringify(e) : e; t.__updating[n] = !0, r === "true" && (r = ""), t.setAttribute(n, r), Promise.resolve().then(() => delete t.__updating[n]); } function Kt(t) { return t.replace(/\.?([A-Z]+)/g, (n, e) => "-" + e.toLowerCase()).replace("_", "-").replace(/^-/, ""); } function mt(t) { return t != null && (typeof t == "object" || typeof t == "function"); } function Ut(t) { return Object.prototype.toString.call(t) === "[object Function]"; } function zt(t) { return typeof t == "function" && t.toString().indexOf("class") === 0; } let G; function Vt(t, n) { const e = Object.keys(n); return class extends t { static get observedAttributes() { return e.map((r) => n[r].attribute); } constructor() { super(), this.__initialized = !1, this.__released = !1, this.__releaseCallbacks = [], this.__propertyChangedCallbacks = [], this.__updating = {}, this.props = {}; for (let r of e) this[r] = void 0; } connectedCallback() { if (this.__initialized) return; this.__releaseCallbacks = [], this.__propertyChangedCallbacks = [], this.__updating = {}, this.props = Ft(this, n); const r = Dt(this.props), i = this.Component, l = G; try { G = this, this.__initialized = !0, zt(i) ? new i(r, { element: this }) : i(r, { element: this }); } finally { G = l; } } async disconnectedCallback() { if (await Promise.resolve(), this.isConnected) return; this.__propertyChangedCallbacks.length = 0; let r = null; for (; r = this.__releaseCallbacks.pop(); ) r(this); delete this.__initialized, this.__released = !0; } attributeChangedCallback(r, i, l) { if (this.__initialized && !this.__updating[r] && (r = this.lookupProp(r), r in n)) { if (l == null && !this[r]) return; this[r] = n[r].parse ? Ct(l) : l; } } lookupProp(r) { if (n) return e.find((i) => r === i || r === n[i].attribute); } get renderRoot() { return this.shadowRoot || this.attachShadow({ mode: "open" }); } addReleaseCallback(r) { this.__releaseCallbacks.push(r); } addPropertyChangedCallback(r) { this.__propertyChangedCallbacks.push(r); } }; } function qt(t, n = {}, e = {}) { const { BaseElement: o = HTMLElement, extension: r, customElements: i = window.customElements } = e; return (l) => { let s = i.get(t); return s ? (s.prototype.Component = l, s) : (s = Vt(o, Nt(n)), s.prototype.Component = l, s.prototype.registeredTag = t, i.define(t, s, r), s); }; } function Ht(t) { const n = Object.keys(t), e = {}; for (let o = 0; o < n.length; o++) { const [r, i] = gt(t[n[o]]); Object.defineProperty(e, n[o], { get: r, set(l) { i(() => l); } }); } return e; } function Wt(t) { if (t.assignedSlot && t.assignedSlot._$owner) return t.assignedSlot._$owner; let n = t.parentNode; for (; n && !n._$owner && !(n.assignedSlot && n.assignedSlot._$owner); ) n = n.parentNode; return n && n.assignedSlot ? n.assignedSlot._$owner : t._$owner; } function Gt(t) { return (n, e) => { const { element: o } = e; return At((r) => { const i = Ht(n); o.addPropertyChangedCallback((s, a) => i[s] = a), o.addReleaseCallback(() => { o.renderRoot.textContent = "", r(); }); const l = t(i, e); return A(o.renderRoot, l); }, Wt(o)); }; } function Jt(t, n, e) { return arguments.length === 2 && (e = n, n = {}), qt(t, n)(Gt(e)); } const Xt = ` :host([theme="dark"]) { color-scheme: only dark; } :host([theme="light"]) { color-scheme: only light; } :host .dictate-button__button { cursor: pointer; padding: 8px; display: inline-flex; align-items: center; justify-content: center; color: light-dark(rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 1)); background-color: light-dark(rgba(0, 0, 0, 0.08), rgba(255, 255, 255, 0.85)); border-radius: 50%; border: none; transition: box-shadow 0.05s linear, background-color 0.2s ease; box-sizing: border-box; } :host .dictate-button__button:hover { background-color: light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.7)); } :host .dictate-button__button:focus { background-color: light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.7)); outline: none; } :host .dictate-button__button:focus-visible { outline: 2px solid light-dark(rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0.8)); outline-offset: 2px; } :host .dictate-button__button .dictate-button__icon { width: 100%; height: 100%; } :host .dictate-button__button .dictate-button__icon.dictate-button__icon--processing { animation: dictate-button-rotate 1s linear infinite; } @keyframes dictate-button-rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @media (forced-colors: active) { :host .dictate-button__button { border: 1px solid currentColor; } :host .dictate-button__button:focus-visible { outline: 3px solid currentColor; } } `; var Zt = /* @__PURE__ */ O('<div part=container class=dictate-button__container><style></style><div aria-live=polite class=dictate-button__status-announcer style="position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0"></div><button part=button class=dictate-button__button>'), Qt = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--idle"fill=none viewBox="0 0 24 24"stroke-width=1.5 stroke=currentColor role=img aria-hidden=true><path stroke-linecap=round stroke-linejoin=round d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 1 1 6 0v8.25a3 3 0 0 1-3 3Z">'), Yt = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--recording"viewBox="0 0 24 24"fill=currentColor role=img aria-hidden=true><circle cx=12 cy=12 r=10>'), te = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--processing"viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round role=img aria-hidden=true><path d="M12 2v4"></path><path d="m16.2 7.8 2.9-2.9"></path><path d="M18 12h4"></path><path d="m16.2 16.2 2.9 2.9"></path><path d="M12 18v4"></path><path d="m4.9 19.1 2.9-2.9"></path><path d="M2 12h4"></path><path d="m4.9 4.9 2.9 2.9">'), ee = /* @__PURE__ */ O('<svg part=icon class="dictate-button__icon dictate-button__icon--error"viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=4 stroke-linecap=round stroke-linejoin=round role=img aria-hidden=true><line x1=12 x2=12 y1=4 y2=14></line><line x1=12 x2=12.01 y1=20 y2=20>'); console.debug("dictate-button version:", "1.9.0"); const ne = "https://api.dictate-button.io/transcribe", S = "dictate-button.io", J = -70, ut = -10, dt = 0, re = 4, oe = 0.25, ie = 0.05; customElements.get("dictate-button") ? console.debug("dictate-button: We don't require importing the dictate-button component separately anymore, so you may remove the script tag which imports https://cdn.dictate-button.io/dictate-button.js from the HTML head.") : Jt("dictate-button", { size: 30, apiEndpoint: ne, language: void 0 }, (t, { element: n }) => { console.debug("api", t.apiEndpoint); const [e, o] = gt("idle"); let r = null, i = null, l = [], s = null, a = null, d = null, c = null, y = !1, C = 0; const p = (f) => f <= J ? 0 : f >= ut ? 1 : (f - J) / (ut - J), q = (f) => { let _ = 0; for (let v = 0; v < f.length; v++) { const u = (f[v] - 128) / 128; _ += u * u; } return Math.sqrt(_ / f.length); }, Et = (f) => 20 * Math.log10(Math.max(f, 1e-8)), Q = (f) => { const _ = n.shadowRoot.querySelector(".dictate-button__button"); if (!_) return; const v = dt + f * (re - dt), u = 0 + f * 0.4; _.style.boxShadow = `0 0 0 ${v}px light-dark(rgba(0, 0, 0, ${u}), rgba(255, 255, 255, ${u}))`; }, Y = () => { if (!y || !d || !c) return; d.getByteTimeDomainData(c); const f = q(c), _ = Et(f), v = p(_), u = v > C ? oe : ie; C = u * v + (1 - u) * C, Q(C), requestAnimationFrame(Y); }, tt = () => { r && r.state !== "inactive" && r.stop(), i && (i.getTracks().forEach((f) => f.stop()), i = null), l = [], s = null, y = !1, a && a.state !== "closed" && a.close(), a = null, d = null, c = null, C = 0, Q(0); }; n.addEventListener("disconnected", tt); const et = async (f) => { if (e() === "idle") { s = f; try { const _ = await navigator.mediaDevices.getUserMedia({ audio: !0 }); i = _, a = new (window.AudioContext || window.webkitAudioContext)(); const v = a.createMediaStreamSource(_); d = a.createAnalyser(), d.fftSize = 2048, v.connect(d), c = new Uint8Array(d.fftSize), r = new MediaRecorder(_, { mimeType: "audio/webm" }), l = [], r.ondataavailable = (u) => { l.push(u.data); }, r.onstop = async () => { y = !1, o("processing"), T(n, "transcribing:started", "Started transcribing"); const u = new Blob(l, { type: "audio/webm" }); try { const m = new FormData(); m.append("audio", u, "recording.webm"), m.append("origin", window?.location?.origin), t.language && m.append("language", t.language); const h = await fetch(t.apiEndpoint, { method: "POST", body: m }); if (!h.ok) throw new Error("Failed to transcribe audio"); const H = await h.json(); if (e() !== "processing") return; T(n, "transcribing:finished", H.text), o("idle"); } catch (m) { console.error("Failed to transcribe audio:", m), T(n, "transcribing:failed", "Failed to transcribe audio"), rt(); } }, r.start(), T(n, "recording:started", "Started recording"), y = !0, Y(), o("recording"); } catch (_) { console.error("Failed to start recording:", _), T(n, "recording:failed", "Failed to start recording"), rt(); } } }, nt = () => { e() === "recording" && (T(n, "recording:stopped", "Stopped recording"), o("idle"), tt()); }, rt = () => { o("error"), setTimeout(() => o("idle"), 2e3); }; let R; return kt(() => { if (!R) return; const f = de(R, { onShortTap: () => { e() === "idle" ? et("short-tap") : e() === "recording" && s === "short-tap" && nt(); }, onLongPressStart: () => { e() === "idle" && et("long-press"); }, onLongPressEnd: () => { e() === "recording" && s === "long-press" && nt(); } }); Pt(f); }), (() => { var f = Zt(), _ = f.firstChild, v = _.nextSibling, u = v.nextSibling; A(_, Xt), A(v, () => ft(e())); var m = R; return typeof m == "function" ? Bt(m, u) : R = u, A(u, (() => { var h = B(() => e() === "idle"); return () => h() && j(le, {}); })(), null), A(u, (() => { var h = B(() => e() === "recording"); return () => h() && j(ae, {}); })(), null), A(u, (() => { var h = B(() => e() === "processing"); return () => h() && j(ce, {}); })(), null), A(u, (() => { var h = B(() => e() === "error"); return () => h() && j(ue, {}); })(), null), D((h) => { var H = `width:${t.size}px;height:${t.size}px"`, ot = se(e()), it = ft(e()), st = e() === "recording", lt = e() === "processing"; return h.e = jt(u, H, h.e), ot !== h.t && P(u, "title", h.t = ot), it !== h.a && P(u, "aria-label", h.a = it), st !== h.o && P(u, "aria-pressed", h.o = st), lt !== h.i && P(u, "aria-busy", h.i = lt), h; }, { e: void 0, t: void 0, a: void 0, o: void 0, i: void 0 }), f; })(); }); const se = (t) => { switch (t) { case "idle": return `Start dictation (${S})`; case "recording": return `Stop dictation (${S})`; case "processing": return `Stop processing (${S})`; case "error": return `Click to reset (${S})`; } }, ft = (t) => { switch (t) { case "idle": return `Start dictation (${S})`; case "recording": return `Dictation in progress. Click to stop it (${S})`; case "processing": return `Processing dictation. Click to cancel it (${S})`; case "error": return `Dictation error. Click to reset (${S})`; } }, T = (t, n, e) => { t.dispatchEvent(new CustomEvent(n, { detail: e, bubbles: !0, composed: !0 })); }, le = () => Qt(), ae = () => Yt(), ce = () => te(), ue = () => ee(); function de(t, { threshold: n = 500, preventScroll: e = !0, onShortTap: o, onLongPressStart: r, onLongPressEnd: i } = {}) { let l, s = !1; const a = (p) => p.preventDefault(), d = (p) => { l && clearTimeout(l), s = !1, p.preventDefault(), t.setPointerCapture(p.pointerId), l = window.setTimeout(() => { s = !0, r?.(p), t.dispatchEvent(new CustomEvent("longpress", { detail: p })); }, n); }, c = (p) => { l && clearTimeout(l), t.releasePointerCapture(p.pointerId), s ? (i?.(p), t.dispatchEvent(new CustomEvent("longpressend", { detail: p }))) : (o?.(p), t.dispatchEvent(new CustomEvent("shorttap", { detail: p }))); }, y = (p) => { l && clearTimeout(l), t.releasePointerCapture(p.pointerId), s = !1; }, C = (p) => { p.preventDefault(), p.stopPropagation(); }; return e && (t.style.touchAction = "none", t.addEventListener("contextmenu", a)), t.addEventListener("pointerdown", d), t.addEventListener("pointerup", c), t.addEventListener("pointercancel", y), t.addEventListener("click", C), () => { e && t.removeEventListener("contextmenu", a), t.removeEventListener("pointerdown", d), t.removeEventListener("pointerup", c), t.removeEventListener("pointercancel", y), t.removeEventListener("click", C); }; }