@moq/watch 0.2.15 → 0.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/broadcast-CG8jZRfA.js +1651 -0
- package/broadcast-CG8jZRfA.js.map +1 -0
- package/element.js +1 -1
- package/index.js +1 -1
- package/package.json +3 -3
- package/support/element.js +39 -39
- package/support/element.js.map +1 -1
- package/ui/components/button.d.ts +3 -0
- package/ui/components/button.d.ts.map +1 -0
- package/ui/components/center-play.d.ts +5 -0
- package/ui/components/center-play.d.ts.map +1 -0
- package/ui/components/control-bar.d.ts +6 -0
- package/ui/components/control-bar.d.ts.map +1 -0
- package/ui/components/fullscreen-button.d.ts +2 -1
- package/ui/components/fullscreen-button.d.ts.map +1 -1
- package/ui/components/latency.d.ts +5 -0
- package/ui/components/latency.d.ts.map +1 -0
- package/ui/components/live-badge.d.ts +9 -0
- package/ui/components/live-badge.d.ts.map +1 -0
- package/ui/components/play-pause.d.ts +1 -0
- package/ui/components/play-pause.d.ts.map +1 -1
- package/ui/components/quality.d.ts +5 -0
- package/ui/components/quality.d.ts.map +1 -0
- package/ui/components/settings-button.d.ts +5 -0
- package/ui/components/settings-button.d.ts.map +1 -0
- package/ui/components/settings-panel.d.ts +6 -0
- package/ui/components/settings-panel.d.ts.map +1 -0
- package/ui/components/volume-slider.d.ts +1 -0
- package/ui/components/volume-slider.d.ts.map +1 -1
- package/ui/element.d.ts.map +1 -1
- package/ui/element.js +577 -260
- package/ui/element.js.map +1 -1
- package/ui/format.d.ts +11 -0
- package/ui/format.d.ts.map +1 -0
- package/ui/fullscreen.d.ts +16 -0
- package/ui/fullscreen.d.ts.map +1 -0
- package/ui/graph.d.ts +18 -0
- package/ui/graph.d.ts.map +1 -0
- package/ui/icons.d.ts +5 -1
- package/ui/icons.d.ts.map +1 -1
- package/ui/state.d.ts +9 -0
- package/ui/state.d.ts.map +1 -0
- package/ui/stats.d.ts +3 -2
- package/ui/stats.d.ts.map +1 -1
- package/broadcast-jtLUfuyL.js +0 -4291
- package/broadcast-jtLUfuyL.js.map +0 -1
- package/dom-Yz3UT5ap.js +0 -29
- package/dom-Yz3UT5ap.js.map +0 -1
- package/libav-opus-af-CzuaKpJb.js +0 -252
- package/libav-opus-af-CzuaKpJb.js.map +0 -1
- package/main-bFFHfuX4.js +0 -1999
- package/main-bFFHfuX4.js.map +0 -1
- package/ui/components/quality-selector.d.ts +0 -4
- package/ui/components/quality-selector.d.ts.map +0 -1
- package/ui/components/stats-button.d.ts +0 -3
- package/ui/components/stats-button.d.ts.map +0 -1
- package/ui/components/watch-status-indicator.d.ts +0 -4
- package/ui/components/watch-status-indicator.d.ts.map +0 -1
package/support/element.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
import { isSupported as e } from "./index.js";
|
|
2
|
+
import { Effect as t, Signal as n } from "@moq/signals";
|
|
3
|
+
import * as r from "@moq/signals/dom";
|
|
4
4
|
//#region src/support/element.ts
|
|
5
5
|
var i = navigator.userAgent.toLowerCase().includes("firefox"), a = ["show", "details"], o = class extends HTMLElement {
|
|
6
|
-
#e = new
|
|
7
|
-
#t = new
|
|
8
|
-
#n = new
|
|
9
|
-
#r = new
|
|
6
|
+
#e = new n("warning");
|
|
7
|
+
#t = new n(!1);
|
|
8
|
+
#n = new n(void 0);
|
|
9
|
+
#r = new n(!1);
|
|
10
10
|
#i;
|
|
11
11
|
static observedAttributes = a;
|
|
12
12
|
constructor() {
|
|
13
|
-
super(),
|
|
13
|
+
super(), e().then((e) => this.#n.set(e)).catch((e) => console.error("Failed to detect watch support:", e));
|
|
14
14
|
}
|
|
15
15
|
connectedCallback() {
|
|
16
|
-
this.#i = new
|
|
16
|
+
this.#i = new t(), this.#i.run(this.#o.bind(this));
|
|
17
17
|
}
|
|
18
18
|
disconnectedCallback() {
|
|
19
19
|
this.#i?.close(), this.#i = void 0;
|
|
@@ -41,49 +41,49 @@ var i = navigator.userAgent.toLowerCase().includes("firefox"), a = ["show", "det
|
|
|
41
41
|
#a(e) {
|
|
42
42
|
return e.webtransport === "none" || !e.audio.decoding || !e.video.decoding || !e.audio.render || !e.video.render || !Object.values(e.audio.decoding).some((e) => e === !0 || e === "full" || e === "partial") || !Object.values(e.video.decoding).some((e) => e.software || e.hardware) ? "none" : !Object.values(e.audio.decoding).every((e) => e === !0 || e === "full") || !Object.values(e.video.decoding).every((e) => e.software || e.hardware) ? "partial" : "full";
|
|
43
43
|
}
|
|
44
|
-
#o(
|
|
45
|
-
let
|
|
46
|
-
if (!
|
|
47
|
-
let
|
|
48
|
-
if (
|
|
49
|
-
let i = this.#a(
|
|
50
|
-
if (
|
|
51
|
-
let a =
|
|
44
|
+
#o(e) {
|
|
45
|
+
let t = e.get(this.#n);
|
|
46
|
+
if (!t || e.get(this.#r)) return;
|
|
47
|
+
let n = e.get(this.#e);
|
|
48
|
+
if (n === "never") return;
|
|
49
|
+
let i = this.#a(t);
|
|
50
|
+
if (n === "warning" && i === "full" || n === "error" && i !== "none") return;
|
|
51
|
+
let a = r.create("div", { style: {
|
|
52
52
|
margin: "0 auto",
|
|
53
53
|
maxWidth: "28rem",
|
|
54
54
|
padding: "1rem"
|
|
55
55
|
} });
|
|
56
|
-
this.appendChild(a),
|
|
56
|
+
this.appendChild(a), e.cleanup(() => this.removeChild(a)), this.#s(a, i, e), e.get(this.#t) && this.#c(a, t, e);
|
|
57
57
|
}
|
|
58
|
-
#s(t, n
|
|
59
|
-
let i =
|
|
58
|
+
#s(e, t, n) {
|
|
59
|
+
let i = r.create("div", { style: {
|
|
60
60
|
display: "flex",
|
|
61
61
|
flexDirection: "row",
|
|
62
62
|
gap: "1rem",
|
|
63
63
|
flexWrap: "wrap",
|
|
64
64
|
justifyContent: "space-between",
|
|
65
65
|
alignItems: "center"
|
|
66
|
-
} }), a =
|
|
67
|
-
|
|
68
|
-
let o =
|
|
66
|
+
} }), a = r.create("div", { style: { fontWeight: "bold" } });
|
|
67
|
+
t === "full" ? a.textContent = "🟢 Full Browser Support" : t === "partial" ? a.textContent = "🟡 Partial Browser Support" : t === "none" && (a.textContent = "🔴 No Browser Support");
|
|
68
|
+
let o = r.create("button", {
|
|
69
69
|
type: "button",
|
|
70
70
|
style: { fontSize: "14px" }
|
|
71
71
|
});
|
|
72
|
-
|
|
72
|
+
n.event(o, "click", () => {
|
|
73
73
|
this.#t.update((e) => !e);
|
|
74
|
-
}),
|
|
74
|
+
}), n.run((e) => {
|
|
75
75
|
o.textContent = e.get(this.#t) ? "Details ➖" : "Details ➕";
|
|
76
76
|
});
|
|
77
|
-
let s =
|
|
77
|
+
let s = r.create("button", {
|
|
78
78
|
type: "button",
|
|
79
79
|
style: { fontSize: "14px" }
|
|
80
80
|
}, "Close ❌");
|
|
81
|
-
|
|
81
|
+
n.event(s, "click", () => {
|
|
82
82
|
this.#r.set(!0);
|
|
83
|
-
}), i.appendChild(a), i.appendChild(o), i.appendChild(s),
|
|
83
|
+
}), i.appendChild(a), i.appendChild(o), i.appendChild(s), e.appendChild(i), n.cleanup(() => e.removeChild(i));
|
|
84
84
|
}
|
|
85
|
-
#c(t, n
|
|
86
|
-
let a =
|
|
85
|
+
#c(e, t, n) {
|
|
86
|
+
let a = r.create("div", { style: {
|
|
87
87
|
display: "grid",
|
|
88
88
|
gridTemplateColumns: "1fr 1fr 1fr",
|
|
89
89
|
columnGap: "0.5rem",
|
|
@@ -92,28 +92,28 @@ var i = navigator.userAgent.toLowerCase().includes("firefox"), a = ["show", "det
|
|
|
92
92
|
borderRadius: "0.5rem",
|
|
93
93
|
padding: "1rem",
|
|
94
94
|
fontSize: "0.875rem"
|
|
95
|
-
} }), o = (e) => e ? "🟢 Yes" : "🔴 No", s = (e) => e?.hardware ? "🟢 Hardware" : e?.software ? `🟡 Software${i ? "*" : ""}` : "🔴 No", c = (e) => e === "full" ? "🟢 Full" : e === "partial" ? "🟡 Polyfill" : "🔴 None", l = (t, n
|
|
96
|
-
let i =
|
|
95
|
+
} }), o = (e) => e ? "🟢 Yes" : "🔴 No", s = (e) => e?.hardware ? "🟢 Hardware" : e?.software ? `🟡 Software${i ? "*" : ""}` : "🔴 No", c = (e) => e === "full" ? "🟢 Full" : e === "partial" ? "🟡 Polyfill" : "🔴 None", l = (e, t, n) => {
|
|
96
|
+
let i = r.create("div", { style: {
|
|
97
97
|
gridColumnStart: "1",
|
|
98
98
|
fontWeight: "bold",
|
|
99
99
|
textAlign: "right"
|
|
100
|
-
} },
|
|
100
|
+
} }, e), o = r.create("div", { style: {
|
|
101
101
|
gridColumnStart: "2",
|
|
102
102
|
textAlign: "center"
|
|
103
|
-
} },
|
|
103
|
+
} }, t), s = r.create("div", { style: { gridColumnStart: "3" } }, n);
|
|
104
104
|
a.appendChild(i), a.appendChild(o), a.appendChild(s);
|
|
105
105
|
};
|
|
106
|
-
if (l("WebTransport", "", c(
|
|
107
|
-
let
|
|
106
|
+
if (l("WebTransport", "", c(t.webtransport)), l("Rendering", "Audio", o(t.audio.render)), l("", "Video", o(t.video.render)), l("Decoding", "Opus", c(t.audio.decoding.opus)), l("", "AAC", o(t.audio.decoding.aac)), l("", "AV1", s(t.video.decoding?.av1)), l("", "H.265", s(t.video.decoding?.h265)), l("", "H.264", s(t.video.decoding?.h264)), l("", "VP9", s(t.video.decoding?.vp9)), l("", "VP8", s(t.video.decoding?.vp8)), i) {
|
|
107
|
+
let e = r.create("div", { style: {
|
|
108
108
|
gridColumnStart: "1",
|
|
109
109
|
gridColumnEnd: "4",
|
|
110
110
|
textAlign: "center",
|
|
111
111
|
fontSize: "0.875rem",
|
|
112
112
|
fontStyle: "italic"
|
|
113
|
-
} }, "Hardware acceleration is ",
|
|
114
|
-
a.appendChild(
|
|
113
|
+
} }, "Hardware acceleration is ", r.create("a", { href: "https://github.com/w3c/webcodecs/issues/896" }, "undetectable"), " on Firefox.");
|
|
114
|
+
a.appendChild(e);
|
|
115
115
|
}
|
|
116
|
-
|
|
116
|
+
e.appendChild(a), n.cleanup(() => e.removeChild(a));
|
|
117
117
|
}
|
|
118
118
|
};
|
|
119
119
|
customElements.define("moq-watch-support", o);
|
package/support/element.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element.js","names":["#support","#signals","#render","#show","#details","#close","#getSummary","#renderHeader","#renderDetails"],"sources":["../../src/support/element.ts"],"sourcesContent":["import { Effect, Signal } from \"@moq/signals\";\nimport * as DOM from \"@moq/signals/dom\";\nimport { type Codec, type Full, isSupported, type Partial } from \"./\";\n\n// https://bugzilla.mozilla.org/show_bug.cgi?id=1967793\nconst isFirefox = navigator.userAgent.toLowerCase().includes(\"firefox\");\n\nconst OBSERVED = [\"show\", \"details\"] as const;\ntype Observed = (typeof OBSERVED)[number];\n\n// Whether to display the support banner.\n// - \"always\": Always display the banner.\n// - \"warning\": Display the banner if a required feature needs a polyfill/fallback.\n// - \"error\": Display the banner if a required feature is unsupported.\n// - \"never\": Never display the banner.\nexport type Show = \"always\" | \"warning\" | \"error\" | \"never\";\n\nexport default class MoqWatchSupport extends HTMLElement {\n\t#show = new Signal<Show>(\"warning\");\n\t#details = new Signal<boolean>(false);\n\t#support = new Signal<Full | undefined>(undefined);\n\t#close = new Signal<boolean>(false);\n\n\t#signals?: Effect;\n\n\tstatic observedAttributes = OBSERVED;\n\n\tconstructor() {\n\t\tsuper();\n\n\t\tisSupported()\n\t\t\t.then((s) => this.#support.set(s))\n\t\t\t.catch((err) => console.error(\"Failed to detect watch support:\", err));\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#signals = new Effect();\n\t\tthis.#signals.run(this.#render.bind(this));\n\t}\n\n\tdisconnectedCallback() {\n\t\tthis.#signals?.close();\n\t\tthis.#signals = undefined;\n\t}\n\n\tattributeChangedCallback(name: Observed, _oldValue: string | null, newValue: string | null) {\n\t\tif (name === \"show\") {\n\t\t\tconst show = newValue ?? \"warning\";\n\t\t\tif (show === \"always\" || show === \"warning\" || show === \"error\" || show === \"never\") {\n\t\t\t\tthis.show = show;\n\t\t\t} else {\n\t\t\t\tthrow new Error(`Invalid show: ${show}`);\n\t\t\t}\n\t\t} else if (name === \"details\") {\n\t\t\tthis.details = newValue !== null;\n\t\t} else {\n\t\t\tconst exhaustive: never = name;\n\t\t\tthrow new Error(`Invalid attribute: ${exhaustive}`);\n\t\t}\n\t}\n\n\tget show(): Show {\n\t\treturn this.#show.peek();\n\t}\n\n\tset show(show: Show) {\n\t\tthis.#show.set(show);\n\t}\n\n\tget details(): boolean {\n\t\treturn this.#details.peek();\n\t}\n\n\tset details(details: boolean) {\n\t\tthis.#details.set(details);\n\t}\n\n\t#getSummary(support: Full): Partial {\n\t\tif (support.webtransport === \"none\") return \"none\";\n\n\t\tif (!support.audio.decoding || !support.video.decoding) return \"none\";\n\t\tif (!support.audio.render || !support.video.render) return \"none\";\n\n\t\tif (!Object.values(support.audio.decoding).some((v) => v === true || v === \"full\" || v === \"partial\"))\n\t\t\treturn \"none\";\n\t\tif (!Object.values(support.video.decoding).some((v) => v.software || v.hardware)) return \"none\";\n\n\t\tif (!Object.values(support.audio.decoding).every((v) => v === true || v === \"full\")) return \"partial\";\n\t\tif (!Object.values(support.video.decoding).every((v) => v.software || v.hardware)) return \"partial\";\n\n\t\treturn \"full\";\n\t}\n\n\t#render(effect: Effect) {\n\t\tconst support = effect.get(this.#support);\n\t\tif (!support) return;\n\n\t\tconst close = effect.get(this.#close);\n\t\tif (close) return;\n\n\t\tconst show = effect.get(this.#show);\n\t\tif (show === \"never\") return;\n\n\t\tconst summary = this.#getSummary(support);\n\n\t\t// Don't render the banner if we have full support and they only asked for warnings.\n\t\tif (show === \"warning\" && summary === \"full\") return;\n\n\t\t// Don't render the banner if we have at least partial support and they only asked for errors.\n\t\tif (show === \"error\" && summary !== \"none\") return;\n\n\t\tconst container = DOM.create(\"div\", {\n\t\t\tstyle: {\n\t\t\t\tmargin: \"0 auto\",\n\t\t\t\tmaxWidth: \"28rem\",\n\t\t\t\tpadding: \"1rem\",\n\t\t\t},\n\t\t});\n\n\t\tthis.appendChild(container);\n\t\teffect.cleanup(() => this.removeChild(container));\n\n\t\tthis.#renderHeader(container, summary, effect);\n\n\t\tif (effect.get(this.#details)) {\n\t\t\tthis.#renderDetails(container, support, effect);\n\t\t}\n\t}\n\n\t#renderHeader(parent: HTMLDivElement, summary: Partial, effect: Effect) {\n\t\tconst headerDiv = DOM.create(\"div\", {\n\t\t\tstyle: {\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tflexDirection: \"row\",\n\t\t\t\tgap: \"1rem\",\n\t\t\t\tflexWrap: \"wrap\",\n\t\t\t\tjustifyContent: \"space-between\",\n\t\t\t\talignItems: \"center\",\n\t\t\t},\n\t\t});\n\n\t\tconst statusDiv = DOM.create(\"div\", {\n\t\t\tstyle: { fontWeight: \"bold\" },\n\t\t});\n\n\t\tif (summary === \"full\") {\n\t\t\tstatusDiv.textContent = \"🟢 Full Browser Support\";\n\t\t} else if (summary === \"partial\") {\n\t\t\tstatusDiv.textContent = \"🟡 Partial Browser Support\";\n\t\t} else if (summary === \"none\") {\n\t\t\tstatusDiv.textContent = \"🔴 No Browser Support\";\n\t\t}\n\n\t\tconst detailsButton = DOM.create(\"button\", {\n\t\t\ttype: \"button\",\n\t\t\tstyle: { fontSize: \"14px\" },\n\t\t});\n\n\t\teffect.event(detailsButton, \"click\", () => {\n\t\t\tthis.#details.update((prev) => !prev);\n\t\t});\n\n\t\teffect.run((effect) => {\n\t\t\tdetailsButton.textContent = effect.get(this.#details) ? \"Details ➖\" : \"Details ➕\";\n\t\t});\n\n\t\tconst closeButton = DOM.create(\n\t\t\t\"button\",\n\t\t\t{\n\t\t\t\ttype: \"button\",\n\t\t\t\tstyle: { fontSize: \"14px\" },\n\t\t\t},\n\t\t\t\"Close ❌\",\n\t\t);\n\n\t\teffect.event(closeButton, \"click\", () => {\n\t\t\tthis.#close.set(true);\n\t\t});\n\n\t\theaderDiv.appendChild(statusDiv);\n\t\theaderDiv.appendChild(detailsButton);\n\t\theaderDiv.appendChild(closeButton);\n\n\t\tparent.appendChild(headerDiv);\n\t\teffect.cleanup(() => parent.removeChild(headerDiv));\n\t}\n\n\t#renderDetails(parent: HTMLDivElement, support: Full, effect: Effect) {\n\t\tconst container = DOM.create(\"div\", {\n\t\t\tstyle: {\n\t\t\t\tdisplay: \"grid\",\n\t\t\t\tgridTemplateColumns: \"1fr 1fr 1fr\",\n\t\t\t\tcolumnGap: \"0.5rem\",\n\t\t\t\trowGap: \"0.2rem\",\n\t\t\t\tbackgroundColor: \"rgba(0, 0, 0, 0.6)\",\n\t\t\t\tborderRadius: \"0.5rem\",\n\t\t\t\tpadding: \"1rem\",\n\t\t\t\tfontSize: \"0.875rem\",\n\t\t\t},\n\t\t});\n\n\t\tconst binary = (value: boolean | undefined) => (value ? \"🟢 Yes\" : \"🔴 No\");\n\t\tconst hardware = (codec: Codec | undefined) =>\n\t\t\tcodec?.hardware ? \"🟢 Hardware\" : codec?.software ? `🟡 Software${isFirefox ? \"*\" : \"\"}` : \"🔴 No\";\n\t\tconst partial = (value: Partial | undefined) =>\n\t\t\tvalue === \"full\" ? \"🟢 Full\" : value === \"partial\" ? \"🟡 Polyfill\" : \"🔴 None\";\n\n\t\tconst addRow = (label: string, col2: string, col3: string) => {\n\t\t\tconst labelDiv = DOM.create(\n\t\t\t\t\"div\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tgridColumnStart: \"1\",\n\t\t\t\t\t\tfontWeight: \"bold\",\n\t\t\t\t\t\ttextAlign: \"right\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tlabel,\n\t\t\t);\n\n\t\t\tconst col2Div = DOM.create(\n\t\t\t\t\"div\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tgridColumnStart: \"2\",\n\t\t\t\t\t\ttextAlign: \"center\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tcol2,\n\t\t\t);\n\n\t\t\tconst col3Div = DOM.create(\n\t\t\t\t\"div\",\n\t\t\t\t{\n\t\t\t\t\tstyle: { gridColumnStart: \"3\" },\n\t\t\t\t},\n\t\t\t\tcol3,\n\t\t\t);\n\n\t\t\tcontainer.appendChild(labelDiv);\n\t\t\tcontainer.appendChild(col2Div);\n\t\t\tcontainer.appendChild(col3Div);\n\t\t};\n\n\t\taddRow(\"WebTransport\", \"\", partial(support.webtransport));\n\t\taddRow(\"Rendering\", \"Audio\", binary(support.audio.render));\n\t\taddRow(\"\", \"Video\", binary(support.video.render));\n\t\taddRow(\"Decoding\", \"Opus\", partial(support.audio.decoding.opus));\n\t\taddRow(\"\", \"AAC\", binary(support.audio.decoding.aac));\n\t\taddRow(\"\", \"AV1\", hardware(support.video.decoding?.av1));\n\t\taddRow(\"\", \"H.265\", hardware(support.video.decoding?.h265));\n\t\taddRow(\"\", \"H.264\", hardware(support.video.decoding?.h264));\n\t\taddRow(\"\", \"VP9\", hardware(support.video.decoding?.vp9));\n\t\taddRow(\"\", \"VP8\", hardware(support.video.decoding?.vp8));\n\n\t\tif (isFirefox) {\n\t\t\tconst noteDiv = DOM.create(\n\t\t\t\t\"div\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tgridColumnStart: \"1\",\n\t\t\t\t\t\tgridColumnEnd: \"4\",\n\t\t\t\t\t\ttextAlign: \"center\",\n\t\t\t\t\t\tfontSize: \"0.875rem\",\n\t\t\t\t\t\tfontStyle: \"italic\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"Hardware acceleration is \",\n\t\t\t\tDOM.create(\n\t\t\t\t\t\"a\",\n\t\t\t\t\t{\n\t\t\t\t\t\thref: \"https://github.com/w3c/webcodecs/issues/896\",\n\t\t\t\t\t},\n\t\t\t\t\t\"undetectable\",\n\t\t\t\t),\n\t\t\t\t\" on Firefox.\",\n\t\t\t);\n\t\t\tcontainer.appendChild(noteDiv);\n\t\t}\n\n\t\tparent.appendChild(container);\n\t\teffect.cleanup(() => parent.removeChild(container));\n\t}\n}\n\ncustomElements.define(\"moq-watch-support\", MoqWatchSupport);\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"moq-watch-support\": MoqWatchSupport;\n\t}\n}\n"],"mappings":";;;;AAKA,IAAM,IAAY,UAAU,UAAU,YAAY,EAAE,SAAS,SAAS,GAEhE,IAAW,CAAC,QAAQ,SAAS,GAUd,IAArB,cAA6C,YAAY;CACxD,KAAQ,IAAI,EAAa,SAAS;CAClC,KAAW,IAAI,EAAgB,EAAK;CACpC,KAAW,IAAI,EAAyB,KAAA,CAAS;CACjD,KAAS,IAAI,EAAgB,EAAK;CAElC;CAEA,OAAO,qBAAqB;CAE5B,cAAc;EAGb,AAFA,MAAM,GAEN,EAAY,EACV,MAAM,MAAM,KAAKA,GAAS,IAAI,CAAC,CAAC,EAChC,OAAO,MAAQ,QAAQ,MAAM,mCAAmC,CAAG,CAAC;CACvE;CAEA,oBAAoB;EAEnB,AADA,KAAKC,KAAW,IAAI,EAAO,GAC3B,KAAKA,GAAS,IAAI,KAAKC,GAAQ,KAAK,IAAI,CAAC;CAC1C;CAEA,uBAAuB;EAEtB,AADA,KAAKD,IAAU,MAAM,GACrB,KAAKA,KAAW,KAAA;CACjB;CAEA,yBAAyB,GAAgB,GAA0B,GAAyB;EAC3F,IAAI,MAAS,QAAQ;GACpB,IAAM,IAAO,KAAY;GACzB,IAAI,MAAS,YAAY,MAAS,aAAa,MAAS,WAAW,MAAS,SAC3E,KAAK,OAAO;QAEZ,MAAU,MAAM,iBAAiB,GAAM;EAEzC,OAAO,IAAI,MAAS,WACnB,KAAK,UAAU,MAAa;OAG5B,MAAU,MAAM,sBAAsB,GAAY;CAEpD;CAEA,IAAI,OAAa;EAChB,OAAO,KAAKE,GAAM,KAAK;CACxB;CAEA,IAAI,KAAK,GAAY;EACpB,KAAKA,GAAM,IAAI,CAAI;CACpB;CAEA,IAAI,UAAmB;EACtB,OAAO,KAAKC,GAAS,KAAK;CAC3B;CAEA,IAAI,QAAQ,GAAkB;EAC7B,KAAKA,GAAS,IAAI,CAAO;CAC1B;CAEA,GAAY,GAAwB;EAanC,OAZI,EAAQ,iBAAiB,UAEzB,CAAC,EAAQ,MAAM,YAAY,CAAC,EAAQ,MAAM,YAC1C,CAAC,EAAQ,MAAM,UAAU,CAAC,EAAQ,MAAM,UAExC,CAAC,OAAO,OAAO,EAAQ,MAAM,QAAQ,EAAE,MAAM,MAAM,MAAM,MAAQ,MAAM,UAAU,MAAM,SAAS,KAEhG,CAAC,OAAO,OAAO,EAAQ,MAAM,QAAQ,EAAE,MAAM,MAAM,EAAE,YAAY,EAAE,QAAQ,IAAU,SAErF,CAAC,OAAO,OAAO,EAAQ,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,MAAQ,MAAM,MAAM,KAC9E,CAAC,OAAO,OAAO,EAAQ,MAAM,QAAQ,EAAE,OAAO,MAAM,EAAE,YAAY,EAAE,QAAQ,IAAU,YAEnF;CACR;CAEA,GAAQ,GAAgB;EACvB,IAAM,IAAU,EAAO,IAAI,KAAKJ,EAAQ;EAIxC,IAHI,CAAC,KAES,EAAO,IAAI,KAAKK,EAC1B,GAAO;EAEX,IAAM,IAAO,EAAO,IAAI,KAAKF,EAAK;EAClC,IAAI,MAAS,SAAS;EAEtB,IAAM,IAAU,KAAKG,GAAY,CAAO;EAMxC,IAHI,MAAS,aAAa,MAAY,UAGlC,MAAS,WAAW,MAAY,QAAQ;EAE5C,IAAM,IAAY,EAAW,OAAO,EACnC,OAAO;GACN,QAAQ;GACR,UAAU;GACV,SAAS;EACV,EACD,CAAC;EAOD,AALA,KAAK,YAAY,CAAS,GAC1B,EAAO,cAAc,KAAK,YAAY,CAAS,CAAC,GAEhD,KAAKC,GAAc,GAAW,GAAS,CAAM,GAEzC,EAAO,IAAI,KAAKH,EAAQ,KAC3B,KAAKI,GAAe,GAAW,GAAS,CAAM;CAEhD;CAEA,GAAc,GAAwB,GAAkB,GAAgB;EACvE,IAAM,IAAY,EAAW,OAAO,EACnC,OAAO;GACN,SAAS;GACT,eAAe;GACf,KAAK;GACL,UAAU;GACV,gBAAgB;GAChB,YAAY;EACb,EACD,CAAC,GAEK,IAAY,EAAW,OAAO,EACnC,OAAO,EAAE,YAAY,OAAO,EAC7B,CAAC;EAED,AAAI,MAAY,SACf,EAAU,cAAc,4BACd,MAAY,YACtB,EAAU,cAAc,+BACd,MAAY,WACtB,EAAU,cAAc;EAGzB,IAAM,IAAgB,EAAW,UAAU;GAC1C,MAAM;GACN,OAAO,EAAE,UAAU,OAAO;EAC3B,CAAC;EAMD,AAJA,EAAO,MAAM,GAAe,eAAe;GAC1C,KAAKJ,GAAS,QAAQ,MAAS,CAAC,CAAI;EACrC,CAAC,GAED,EAAO,KAAK,MAAW;GACtB,EAAc,cAAc,EAAO,IAAI,KAAKA,EAAQ,IAAI,cAAc;EACvE,CAAC;EAED,IAAM,IAAc,EACnB,UACA;GACC,MAAM;GACN,OAAO,EAAE,UAAU,OAAO;EAC3B,GACA,SACD;EAWA,AATA,EAAO,MAAM,GAAa,eAAe;GACxC,KAAKC,GAAO,IAAI,EAAI;EACrB,CAAC,GAED,EAAU,YAAY,CAAS,GAC/B,EAAU,YAAY,CAAa,GACnC,EAAU,YAAY,CAAW,GAEjC,EAAO,YAAY,CAAS,GAC5B,EAAO,cAAc,EAAO,YAAY,CAAS,CAAC;CACnD;CAEA,GAAe,GAAwB,GAAe,GAAgB;EACrE,IAAM,IAAY,EAAW,OAAO,EACnC,OAAO;GACN,SAAS;GACT,qBAAqB;GACrB,WAAW;GACX,QAAQ;GACR,iBAAiB;GACjB,cAAc;GACd,SAAS;GACT,UAAU;EACX,EACD,CAAC,GAEK,KAAU,MAAgC,IAAQ,WAAW,SAC7D,KAAY,MACjB,GAAO,WAAW,gBAAgB,GAAO,WAAW,cAAc,IAAY,MAAM,OAAO,SACtF,KAAW,MAChB,MAAU,SAAS,YAAY,MAAU,YAAY,gBAAgB,WAEhE,KAAU,GAAe,GAAc,MAAiB;GAC7D,IAAM,IAAW,EAChB,OACA,EACC,OAAO;IACN,iBAAiB;IACjB,YAAY;IACZ,WAAW;GACZ,EACD,GACA,CACD,GAEM,IAAU,EACf,OACA,EACC,OAAO;IACN,iBAAiB;IACjB,WAAW;GACZ,EACD,GACA,CACD,GAEM,IAAU,EACf,OACA,EACC,OAAO,EAAE,iBAAiB,IAAI,EAC/B,GACA,CACD;GAIA,AAFA,EAAU,YAAY,CAAQ,GAC9B,EAAU,YAAY,CAAO,GAC7B,EAAU,YAAY,CAAO;EAC9B;EAaA,IAXA,EAAO,gBAAgB,IAAI,EAAQ,EAAQ,YAAY,CAAC,GACxD,EAAO,aAAa,SAAS,EAAO,EAAQ,MAAM,MAAM,CAAC,GACzD,EAAO,IAAI,SAAS,EAAO,EAAQ,MAAM,MAAM,CAAC,GAChD,EAAO,YAAY,QAAQ,EAAQ,EAAQ,MAAM,SAAS,IAAI,CAAC,GAC/D,EAAO,IAAI,OAAO,EAAO,EAAQ,MAAM,SAAS,GAAG,CAAC,GACpD,EAAO,IAAI,OAAO,EAAS,EAAQ,MAAM,UAAU,GAAG,CAAC,GACvD,EAAO,IAAI,SAAS,EAAS,EAAQ,MAAM,UAAU,IAAI,CAAC,GAC1D,EAAO,IAAI,SAAS,EAAS,EAAQ,MAAM,UAAU,IAAI,CAAC,GAC1D,EAAO,IAAI,OAAO,EAAS,EAAQ,MAAM,UAAU,GAAG,CAAC,GACvD,EAAO,IAAI,OAAO,EAAS,EAAQ,MAAM,UAAU,GAAG,CAAC,GAEnD,GAAW;GACd,IAAM,IAAU,EACf,OACA,EACC,OAAO;IACN,iBAAiB;IACjB,eAAe;IACf,WAAW;IACX,UAAU;IACV,WAAW;GACZ,EACD,GACA,6BACA,EACC,KACA,EACC,MAAM,8CACP,GACA,cACD,GACA,cACD;GACA,EAAU,YAAY,CAAO;EAC9B;EAGA,AADA,EAAO,YAAY,CAAS,GAC5B,EAAO,cAAc,EAAO,YAAY,CAAS,CAAC;CACnD;AACD;AAEA,eAAe,OAAO,qBAAqB,CAAe"}
|
|
1
|
+
{"version":3,"file":"element.js","names":["#support","#signals","#render","#show","#details","#close","#getSummary","#renderHeader","#renderDetails"],"sources":["../../src/support/element.ts"],"sourcesContent":["import { Effect, Signal } from \"@moq/signals\";\nimport * as DOM from \"@moq/signals/dom\";\nimport { type Codec, type Full, isSupported, type Partial } from \"./\";\n\n// https://bugzilla.mozilla.org/show_bug.cgi?id=1967793\nconst isFirefox = navigator.userAgent.toLowerCase().includes(\"firefox\");\n\nconst OBSERVED = [\"show\", \"details\"] as const;\ntype Observed = (typeof OBSERVED)[number];\n\n// Whether to display the support banner.\n// - \"always\": Always display the banner.\n// - \"warning\": Display the banner if a required feature needs a polyfill/fallback.\n// - \"error\": Display the banner if a required feature is unsupported.\n// - \"never\": Never display the banner.\nexport type Show = \"always\" | \"warning\" | \"error\" | \"never\";\n\nexport default class MoqWatchSupport extends HTMLElement {\n\t#show = new Signal<Show>(\"warning\");\n\t#details = new Signal<boolean>(false);\n\t#support = new Signal<Full | undefined>(undefined);\n\t#close = new Signal<boolean>(false);\n\n\t#signals?: Effect;\n\n\tstatic observedAttributes = OBSERVED;\n\n\tconstructor() {\n\t\tsuper();\n\n\t\tisSupported()\n\t\t\t.then((s) => this.#support.set(s))\n\t\t\t.catch((err) => console.error(\"Failed to detect watch support:\", err));\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#signals = new Effect();\n\t\tthis.#signals.run(this.#render.bind(this));\n\t}\n\n\tdisconnectedCallback() {\n\t\tthis.#signals?.close();\n\t\tthis.#signals = undefined;\n\t}\n\n\tattributeChangedCallback(name: Observed, _oldValue: string | null, newValue: string | null) {\n\t\tif (name === \"show\") {\n\t\t\tconst show = newValue ?? \"warning\";\n\t\t\tif (show === \"always\" || show === \"warning\" || show === \"error\" || show === \"never\") {\n\t\t\t\tthis.show = show;\n\t\t\t} else {\n\t\t\t\tthrow new Error(`Invalid show: ${show}`);\n\t\t\t}\n\t\t} else if (name === \"details\") {\n\t\t\tthis.details = newValue !== null;\n\t\t} else {\n\t\t\tconst exhaustive: never = name;\n\t\t\tthrow new Error(`Invalid attribute: ${exhaustive}`);\n\t\t}\n\t}\n\n\tget show(): Show {\n\t\treturn this.#show.peek();\n\t}\n\n\tset show(show: Show) {\n\t\tthis.#show.set(show);\n\t}\n\n\tget details(): boolean {\n\t\treturn this.#details.peek();\n\t}\n\n\tset details(details: boolean) {\n\t\tthis.#details.set(details);\n\t}\n\n\t#getSummary(support: Full): Partial {\n\t\tif (support.webtransport === \"none\") return \"none\";\n\n\t\tif (!support.audio.decoding || !support.video.decoding) return \"none\";\n\t\tif (!support.audio.render || !support.video.render) return \"none\";\n\n\t\tif (!Object.values(support.audio.decoding).some((v) => v === true || v === \"full\" || v === \"partial\"))\n\t\t\treturn \"none\";\n\t\tif (!Object.values(support.video.decoding).some((v) => v.software || v.hardware)) return \"none\";\n\n\t\tif (!Object.values(support.audio.decoding).every((v) => v === true || v === \"full\")) return \"partial\";\n\t\tif (!Object.values(support.video.decoding).every((v) => v.software || v.hardware)) return \"partial\";\n\n\t\treturn \"full\";\n\t}\n\n\t#render(effect: Effect) {\n\t\tconst support = effect.get(this.#support);\n\t\tif (!support) return;\n\n\t\tconst close = effect.get(this.#close);\n\t\tif (close) return;\n\n\t\tconst show = effect.get(this.#show);\n\t\tif (show === \"never\") return;\n\n\t\tconst summary = this.#getSummary(support);\n\n\t\t// Don't render the banner if we have full support and they only asked for warnings.\n\t\tif (show === \"warning\" && summary === \"full\") return;\n\n\t\t// Don't render the banner if we have at least partial support and they only asked for errors.\n\t\tif (show === \"error\" && summary !== \"none\") return;\n\n\t\tconst container = DOM.create(\"div\", {\n\t\t\tstyle: {\n\t\t\t\tmargin: \"0 auto\",\n\t\t\t\tmaxWidth: \"28rem\",\n\t\t\t\tpadding: \"1rem\",\n\t\t\t},\n\t\t});\n\n\t\tthis.appendChild(container);\n\t\teffect.cleanup(() => this.removeChild(container));\n\n\t\tthis.#renderHeader(container, summary, effect);\n\n\t\tif (effect.get(this.#details)) {\n\t\t\tthis.#renderDetails(container, support, effect);\n\t\t}\n\t}\n\n\t#renderHeader(parent: HTMLDivElement, summary: Partial, effect: Effect) {\n\t\tconst headerDiv = DOM.create(\"div\", {\n\t\t\tstyle: {\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tflexDirection: \"row\",\n\t\t\t\tgap: \"1rem\",\n\t\t\t\tflexWrap: \"wrap\",\n\t\t\t\tjustifyContent: \"space-between\",\n\t\t\t\talignItems: \"center\",\n\t\t\t},\n\t\t});\n\n\t\tconst statusDiv = DOM.create(\"div\", {\n\t\t\tstyle: { fontWeight: \"bold\" },\n\t\t});\n\n\t\tif (summary === \"full\") {\n\t\t\tstatusDiv.textContent = \"🟢 Full Browser Support\";\n\t\t} else if (summary === \"partial\") {\n\t\t\tstatusDiv.textContent = \"🟡 Partial Browser Support\";\n\t\t} else if (summary === \"none\") {\n\t\t\tstatusDiv.textContent = \"🔴 No Browser Support\";\n\t\t}\n\n\t\tconst detailsButton = DOM.create(\"button\", {\n\t\t\ttype: \"button\",\n\t\t\tstyle: { fontSize: \"14px\" },\n\t\t});\n\n\t\teffect.event(detailsButton, \"click\", () => {\n\t\t\tthis.#details.update((prev) => !prev);\n\t\t});\n\n\t\teffect.run((effect) => {\n\t\t\tdetailsButton.textContent = effect.get(this.#details) ? \"Details ➖\" : \"Details ➕\";\n\t\t});\n\n\t\tconst closeButton = DOM.create(\n\t\t\t\"button\",\n\t\t\t{\n\t\t\t\ttype: \"button\",\n\t\t\t\tstyle: { fontSize: \"14px\" },\n\t\t\t},\n\t\t\t\"Close ❌\",\n\t\t);\n\n\t\teffect.event(closeButton, \"click\", () => {\n\t\t\tthis.#close.set(true);\n\t\t});\n\n\t\theaderDiv.appendChild(statusDiv);\n\t\theaderDiv.appendChild(detailsButton);\n\t\theaderDiv.appendChild(closeButton);\n\n\t\tparent.appendChild(headerDiv);\n\t\teffect.cleanup(() => parent.removeChild(headerDiv));\n\t}\n\n\t#renderDetails(parent: HTMLDivElement, support: Full, effect: Effect) {\n\t\tconst container = DOM.create(\"div\", {\n\t\t\tstyle: {\n\t\t\t\tdisplay: \"grid\",\n\t\t\t\tgridTemplateColumns: \"1fr 1fr 1fr\",\n\t\t\t\tcolumnGap: \"0.5rem\",\n\t\t\t\trowGap: \"0.2rem\",\n\t\t\t\tbackgroundColor: \"rgba(0, 0, 0, 0.6)\",\n\t\t\t\tborderRadius: \"0.5rem\",\n\t\t\t\tpadding: \"1rem\",\n\t\t\t\tfontSize: \"0.875rem\",\n\t\t\t},\n\t\t});\n\n\t\tconst binary = (value: boolean | undefined) => (value ? \"🟢 Yes\" : \"🔴 No\");\n\t\tconst hardware = (codec: Codec | undefined) =>\n\t\t\tcodec?.hardware ? \"🟢 Hardware\" : codec?.software ? `🟡 Software${isFirefox ? \"*\" : \"\"}` : \"🔴 No\";\n\t\tconst partial = (value: Partial | undefined) =>\n\t\t\tvalue === \"full\" ? \"🟢 Full\" : value === \"partial\" ? \"🟡 Polyfill\" : \"🔴 None\";\n\n\t\tconst addRow = (label: string, col2: string, col3: string) => {\n\t\t\tconst labelDiv = DOM.create(\n\t\t\t\t\"div\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tgridColumnStart: \"1\",\n\t\t\t\t\t\tfontWeight: \"bold\",\n\t\t\t\t\t\ttextAlign: \"right\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tlabel,\n\t\t\t);\n\n\t\t\tconst col2Div = DOM.create(\n\t\t\t\t\"div\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tgridColumnStart: \"2\",\n\t\t\t\t\t\ttextAlign: \"center\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tcol2,\n\t\t\t);\n\n\t\t\tconst col3Div = DOM.create(\n\t\t\t\t\"div\",\n\t\t\t\t{\n\t\t\t\t\tstyle: { gridColumnStart: \"3\" },\n\t\t\t\t},\n\t\t\t\tcol3,\n\t\t\t);\n\n\t\t\tcontainer.appendChild(labelDiv);\n\t\t\tcontainer.appendChild(col2Div);\n\t\t\tcontainer.appendChild(col3Div);\n\t\t};\n\n\t\taddRow(\"WebTransport\", \"\", partial(support.webtransport));\n\t\taddRow(\"Rendering\", \"Audio\", binary(support.audio.render));\n\t\taddRow(\"\", \"Video\", binary(support.video.render));\n\t\taddRow(\"Decoding\", \"Opus\", partial(support.audio.decoding.opus));\n\t\taddRow(\"\", \"AAC\", binary(support.audio.decoding.aac));\n\t\taddRow(\"\", \"AV1\", hardware(support.video.decoding?.av1));\n\t\taddRow(\"\", \"H.265\", hardware(support.video.decoding?.h265));\n\t\taddRow(\"\", \"H.264\", hardware(support.video.decoding?.h264));\n\t\taddRow(\"\", \"VP9\", hardware(support.video.decoding?.vp9));\n\t\taddRow(\"\", \"VP8\", hardware(support.video.decoding?.vp8));\n\n\t\tif (isFirefox) {\n\t\t\tconst noteDiv = DOM.create(\n\t\t\t\t\"div\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tgridColumnStart: \"1\",\n\t\t\t\t\t\tgridColumnEnd: \"4\",\n\t\t\t\t\t\ttextAlign: \"center\",\n\t\t\t\t\t\tfontSize: \"0.875rem\",\n\t\t\t\t\t\tfontStyle: \"italic\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"Hardware acceleration is \",\n\t\t\t\tDOM.create(\n\t\t\t\t\t\"a\",\n\t\t\t\t\t{\n\t\t\t\t\t\thref: \"https://github.com/w3c/webcodecs/issues/896\",\n\t\t\t\t\t},\n\t\t\t\t\t\"undetectable\",\n\t\t\t\t),\n\t\t\t\t\" on Firefox.\",\n\t\t\t);\n\t\t\tcontainer.appendChild(noteDiv);\n\t\t}\n\n\t\tparent.appendChild(container);\n\t\teffect.cleanup(() => parent.removeChild(container));\n\t}\n}\n\ncustomElements.define(\"moq-watch-support\", MoqWatchSupport);\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"moq-watch-support\": MoqWatchSupport;\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/ui/components/button.ts"],"names":[],"mappings":"AAEA,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB,CAQ3E"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Effect } from "@moq/signals";
|
|
2
|
+
import type MoqWatch from "../../element";
|
|
3
|
+
/** A large centered play button shown while paused. */
|
|
4
|
+
export declare function centerPlay(parent: Effect, watch: MoqWatch): HTMLElement;
|
|
5
|
+
//# sourceMappingURL=center-play.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"center-play.d.ts","sourceRoot":"","sources":["../../../src/ui/components/center-play.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAG1C,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,WAAW,CAkBvE"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Effect } from "@moq/signals";
|
|
2
|
+
import type MoqWatch from "../../element";
|
|
3
|
+
import type { UiState } from "../state";
|
|
4
|
+
/** The bottom control bar: essentials on the left, settings + fullscreen on the right. */
|
|
5
|
+
export declare function controlBar(parent: Effect, watch: MoqWatch, state: UiState, player: HTMLElement): HTMLElement;
|
|
6
|
+
//# sourceMappingURL=control-bar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-bar.d.ts","sourceRoot":"","sources":["../../../src/ui/components/control-bar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAOxC,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,WAAW,CAa5G"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Effect } from "@moq/signals";
|
|
2
2
|
import type MoqWatch from "../../element";
|
|
3
|
-
|
|
3
|
+
/** Fullscreen toggle button wired to the shared cross-browser fullscreen controller. */
|
|
4
|
+
export declare function fullscreenButton(parent: Effect, player: HTMLElement, watch: MoqWatch): HTMLElement;
|
|
4
5
|
//# sourceMappingURL=fullscreen-button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fullscreen-button.d.ts","sourceRoot":"","sources":["../../../src/ui/components/fullscreen-button.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"fullscreen-button.d.ts","sourceRoot":"","sources":["../../../src/ui/components/fullscreen-button.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAK1C,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,GAAG,WAAW,CAmBlG"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Effect } from "@moq/signals";
|
|
2
|
+
import type MoqWatch from "../../element";
|
|
3
|
+
/** The Latency tab: choose a buffer target and watch the live buffer timeline. */
|
|
4
|
+
export declare function latencyTab(parent: Effect, watch: MoqWatch): HTMLElement;
|
|
5
|
+
//# sourceMappingURL=latency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"latency.d.ts","sourceRoot":"","sources":["../../../src/ui/components/latency.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAe1C,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,WAAW,CAmDvE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Effect } from "@moq/signals";
|
|
2
|
+
import type MoqWatch from "../../element";
|
|
3
|
+
import type { UiState } from "../state";
|
|
4
|
+
/**
|
|
5
|
+
* Compact status pill. Shows a pulsing dot + LIVE when streaming, plus the
|
|
6
|
+
* current buffer latency. Clicking jumps to the Latency tab.
|
|
7
|
+
*/
|
|
8
|
+
export declare function liveBadge(parent: Effect, watch: MoqWatch, state: UiState): HTMLElement;
|
|
9
|
+
//# sourceMappingURL=live-badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-badge.d.ts","sourceRoot":"","sources":["../../../src/ui/components/live-badge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAkBxC;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,WAAW,CAyCtF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Effect } from "@moq/signals";
|
|
2
2
|
import type MoqWatch from "../../element";
|
|
3
|
+
/** Play/pause control bound to the backend paused state. */
|
|
3
4
|
export declare function playPauseButton(parent: Effect, watch: MoqWatch): HTMLElement;
|
|
4
5
|
//# sourceMappingURL=play-pause.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"play-pause.d.ts","sourceRoot":"","sources":["../../../src/ui/components/play-pause.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"play-pause.d.ts","sourceRoot":"","sources":["../../../src/ui/components/play-pause.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAI1C,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,WAAW,CAe5E"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Effect } from "@moq/signals";
|
|
2
|
+
import type MoqWatch from "../../element";
|
|
3
|
+
/** The Quality tab: pick a video rendition or let ABR choose automatically. */
|
|
4
|
+
export declare function qualityTab(parent: Effect, watch: MoqWatch): HTMLElement;
|
|
5
|
+
//# sourceMappingURL=quality.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../../src/ui/components/quality.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AA6C1C,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,WAAW,CA8CvE"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Effect } from "@moq/signals";
|
|
2
|
+
import type { UiState } from "../state";
|
|
3
|
+
/** Gear button that toggles the settings panel open/closed. */
|
|
4
|
+
export declare function settingsButton(parent: Effect, state: UiState): HTMLElement;
|
|
5
|
+
//# sourceMappingURL=settings-button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-button.d.ts","sourceRoot":"","sources":["../../../src/ui/components/settings-button.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGxC,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,WAAW,CAgB1E"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Effect } from "@moq/signals";
|
|
2
|
+
import type MoqWatch from "../../element";
|
|
3
|
+
import type { UiState } from "../state";
|
|
4
|
+
/** The slide-in settings sheet: tab strip + the active tab's content. */
|
|
5
|
+
export declare function settingsPanel(parent: Effect, watch: MoqWatch, state: UiState): HTMLElement;
|
|
6
|
+
//# sourceMappingURL=settings-panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-panel.d.ts","sourceRoot":"","sources":["../../../src/ui/components/settings-panel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAO,OAAO,EAAE,MAAM,UAAU,CAAC;AAW7C,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,WAAW,CAmE1F"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Effect } from "@moq/signals";
|
|
2
2
|
import type MoqWatch from "../../element";
|
|
3
|
+
/** Volume control with a mute toggle; the slider expands on hover. */
|
|
3
4
|
export declare function volumeSlider(parent: Effect, watch: MoqWatch): HTMLElement;
|
|
4
5
|
//# sourceMappingURL=volume-slider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"volume-slider.d.ts","sourceRoot":"","sources":["../../../src/ui/components/volume-slider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAU1C,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"volume-slider.d.ts","sourceRoot":"","sources":["../../../src/ui/components/volume-slider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAU1C,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,WAAW,CA0CzE"}
|
package/ui/element.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/ui/element.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/ui/element.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;;;IAiBlD,iBAAiB;IASjB,oBAAoB;CAgFpB;AAID,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,cAAc,EAAE,UAAU,CAAC;KAC3B;CACD"}
|