@viceme-ai/sdk 0.6.2 → 0.8.0
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/README.md +65 -17
- package/dist/capability-mount.d.ts +2 -0
- package/dist/capability-mount.d.ts.map +1 -1
- package/dist/chunks/client-DbPCnwf-.js +1471 -0
- package/dist/chunks/client-DbPCnwf-.js.map +1 -0
- package/dist/chunks/integration-CTsnJ8mN.js +38 -0
- package/dist/chunks/integration-CTsnJ8mN.js.map +1 -0
- package/dist/chunks/version-DXLLix7K.js +6 -0
- package/dist/chunks/{version-BJiUVcir.js.map → version-DXLLix7K.js.map} +1 -1
- package/dist/core/access-bridge.d.ts +17 -0
- package/dist/core/access-bridge.d.ts.map +1 -0
- package/dist/core/capabilities.d.ts +12 -2
- package/dist/core/capabilities.d.ts.map +1 -1
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/presentation.d.ts +10 -1
- package/dist/core/presentation.d.ts.map +1 -1
- package/dist/danmaku/mount.d.ts.map +1 -1
- package/dist/danmaku.js +117 -91
- package/dist/danmaku.js.map +1 -1
- package/dist/engagement/integration.d.ts +15 -0
- package/dist/engagement/integration.d.ts.map +1 -0
- package/dist/generated/public-contract.d.ts +260 -12
- package/dist/generated/public-contract.d.ts.map +1 -1
- package/dist/index.js +29 -27
- package/dist/index.js.map +1 -1
- package/dist/loader/auto-loader.d.ts.map +1 -1
- package/dist/manifest.json +37 -28
- package/dist/session/session.d.ts +36 -3
- package/dist/session/session.d.ts.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/tip/index.d.ts +2 -0
- package/dist/tip/index.d.ts.map +1 -1
- package/dist/tip/mount.d.ts.map +1 -1
- package/dist/tip.js +211 -194
- package/dist/tip.js.map +1 -1
- package/dist/transport/transport.d.ts +2 -0
- package/dist/transport/transport.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/viceme.min.js +51 -8
- package/dist/viceme.min.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/client-DEg6YouY.js +0 -1027
- package/dist/chunks/client-DEg6YouY.js.map +0 -1
- package/dist/chunks/version-BJiUVcir.js +0 -6
package/dist/danmaku.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { B as
|
|
2
|
-
import { c as
|
|
3
|
-
import { S as
|
|
1
|
+
import { B as oe } from "./chunks/build-endpoints-NrDmg6jf.js";
|
|
2
|
+
import { c as A, V as P } from "./chunks/errors-C7DfLKcF.js";
|
|
3
|
+
import { S as se } from "./chunks/version-DXLLix7K.js";
|
|
4
|
+
import { r as ie, h as le, o as ce } from "./chunks/integration-CTsnJ8mN.js";
|
|
4
5
|
function Z(a = window, t = document) {
|
|
5
|
-
const r =
|
|
6
|
+
const r = de(a, t), e = me(a, t);
|
|
6
7
|
return {
|
|
7
|
-
anchorKey: `page:${
|
|
8
|
+
anchorKey: `page:${he(r)}:scroll:${e}`,
|
|
8
9
|
scrollBucket: e
|
|
9
10
|
};
|
|
10
11
|
}
|
|
11
|
-
function
|
|
12
|
+
function de(a, t) {
|
|
12
13
|
const r = t.querySelector('link[rel="canonical"][href]'), e = r?.href || a.location.href;
|
|
13
14
|
try {
|
|
14
15
|
const l = new URL(e, a.location.href);
|
|
@@ -17,7 +18,7 @@ function ne(a, t) {
|
|
|
17
18
|
return a.location.href;
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
|
-
function
|
|
21
|
+
function me(a, t) {
|
|
21
22
|
const r = t.documentElement, e = t.body, l = a.scrollY || a.pageYOffset || r.scrollTop || e?.scrollTop || 0, m = Math.max(
|
|
22
23
|
r.scrollHeight,
|
|
23
24
|
r.offsetHeight,
|
|
@@ -26,10 +27,10 @@ function oe(a, t) {
|
|
|
26
27
|
e?.offsetHeight ?? 0
|
|
27
28
|
), v = Math.max(0, m - a.innerHeight);
|
|
28
29
|
if (v <= 1) return "0-100";
|
|
29
|
-
const
|
|
30
|
+
const u = Math.max(0, Math.min(99, l / v * 100)), y = Math.min(90, Math.floor(u / 10) * 10);
|
|
30
31
|
return `${y}-${y + 10}`;
|
|
31
32
|
}
|
|
32
|
-
function
|
|
33
|
+
function he(a) {
|
|
33
34
|
let t = 3735928559 ^ a.length, r = 1103547991 ^ a.length;
|
|
34
35
|
for (let e = 0; e < a.length; e += 1) {
|
|
35
36
|
const l = a.charCodeAt(e);
|
|
@@ -37,10 +38,15 @@ function se(a) {
|
|
|
37
38
|
}
|
|
38
39
|
return t = Math.imul(t ^ t >>> 16, 2246822507), t ^= Math.imul(r ^ r >>> 13, 3266489909), r = Math.imul(r ^ r >>> 16, 2246822507), r ^= Math.imul(t ^ t >>> 13, 3266489909), ((r >>> 0).toString(36).padStart(7, "0") + (t >>> 0).toString(36).padStart(7, "0")).slice(0, 16);
|
|
39
40
|
}
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
if (
|
|
43
|
-
|
|
41
|
+
const b = 32, J = 12, j = 56, ue = 360, ge = 328, fe = 340, ye = 120, pe = 1e3, ee = 8e3, be = ["source", "action", "workKey"];
|
|
42
|
+
function ve(a, t) {
|
|
43
|
+
if (typeof a != "object" || a === null || Array.isArray(a)) return !1;
|
|
44
|
+
const r = Object.keys(a);
|
|
45
|
+
return r.length === t.length && t.every((e) => r.includes(e));
|
|
46
|
+
}
|
|
47
|
+
async function Ee(a, t) {
|
|
48
|
+
if (t.signal?.aborted) throw A();
|
|
49
|
+
if (await a.ready(), t.signal?.aborted) throw A();
|
|
44
50
|
if (!a.hasCapability("danmaku"))
|
|
45
51
|
throw new P({
|
|
46
52
|
code: "CAPABILITY_DISABLED",
|
|
@@ -56,42 +62,42 @@ async function me(a, t) {
|
|
|
56
62
|
retryable: !1,
|
|
57
63
|
capability: "danmaku"
|
|
58
64
|
});
|
|
59
|
-
const l =
|
|
65
|
+
const l = oe[a.region];
|
|
60
66
|
let m = Z(e, r);
|
|
61
67
|
const v = r.documentElement.lang.trim() || e.navigator.language || "en";
|
|
62
|
-
let
|
|
63
|
-
const x = /* @__PURE__ */ new WeakSet(),
|
|
68
|
+
let u = !1, y, T, g, I = !1, U = 0, R = "", L = !1, _;
|
|
69
|
+
const x = /* @__PURE__ */ new WeakSet(), O = /* @__PURE__ */ new Set(), h = r.createElement("div");
|
|
64
70
|
h.dataset.vicemeDanmaku = "mounted", h.style.all = "initial", h.style.position = "fixed", h.style.inset = "0", h.style.width = "100%", h.style.height = "100%", h.style.pointerEvents = "none", h.style.zIndex = "2147483000", h.style.contain = "layout style size";
|
|
65
|
-
const
|
|
66
|
-
p.style.boxSizing = "border-box", p.style.position = "fixed", p.style.inset = "0", p.style.width = "100%", p.style.height = "100%", p.style.pointerEvents = "none",
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
return
|
|
70
|
-
},
|
|
71
|
-
const
|
|
72
|
-
return
|
|
71
|
+
const re = h.attachShadow({ mode: "open" }), p = r.createElement("div");
|
|
72
|
+
p.style.boxSizing = "border-box", p.style.position = "fixed", p.style.inset = "0", p.style.width = "100%", p.style.height = "100%", p.style.pointerEvents = "none", re.append(p);
|
|
73
|
+
const D = (n) => {
|
|
74
|
+
const c = new URL("/embed/danmaku", l);
|
|
75
|
+
return c.searchParams.set("mode", n), c.searchParams.set("workKey", a.workKey), c.searchParams.set("theme", t.theme), c.searchParams.set("locale", v), c.searchParams.set("sdk", se), c.searchParams.set("anchorKey", m.anchorKey), c;
|
|
76
|
+
}, N = (n, c, w) => {
|
|
77
|
+
const i = r.createElement("iframe");
|
|
78
|
+
return i.title = c, i.src = w, i.loading = "eager", i.referrerPolicy = "no-referrer", i.setAttribute("allowtransparency", "true"), i.setAttribute(
|
|
73
79
|
"sandbox",
|
|
74
80
|
"allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
|
|
75
|
-
),
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
const d =
|
|
81
|
+
), i.dataset.mode = n, i.style.boxSizing = "border-box", i.style.colorScheme = "normal", i.style.position = "fixed", i.style.margin = "0", i.style.border = "0", i.style.background = "transparent", i.style.width = "100%", i.style.zIndex = "2147483000", i;
|
|
82
|
+
}, f = N("stage", "ViceMe Danmaku", D("stage").toString());
|
|
83
|
+
f.setAttribute("aria-hidden", "true"), f.style.inset = "0", f.style.height = "100%", f.style.pointerEvents = "none";
|
|
84
|
+
const d = N(
|
|
79
85
|
"controls",
|
|
80
86
|
"ViceMe Danmaku controls",
|
|
81
|
-
|
|
87
|
+
D("controls").toString()
|
|
82
88
|
);
|
|
83
|
-
d.style.left = "50%", d.style.bottom = "env(safe-area-inset-bottom, 0px)", d.style.
|
|
84
|
-
let
|
|
85
|
-
const
|
|
89
|
+
d.style.left = "50%", d.style.bottom = "env(safe-area-inset-bottom, 0px)", d.style.transform = "translateX(-50%)";
|
|
90
|
+
let W = !1, G = j;
|
|
91
|
+
const C = () => {
|
|
86
92
|
const n = Math.max(
|
|
87
|
-
|
|
88
|
-
Math.floor(e.innerWidth ||
|
|
93
|
+
b,
|
|
94
|
+
Math.floor(e.innerWidth || b)
|
|
89
95
|
);
|
|
90
|
-
d.style.width = `${
|
|
96
|
+
d.style.width = `${W ? b : n}px`, d.style.height = `${G}px`;
|
|
91
97
|
};
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
|
|
98
|
+
C(), d.style.pointerEvents = "none";
|
|
99
|
+
const s = N("modal", "ViceMe Danmaku dialog", "about:blank");
|
|
100
|
+
s.dataset.src = D("modal").toString(), s.style.inset = "0", s.style.height = "100%", s.style.display = "none", s.style.pointerEvents = "none", p.append(f, d, s);
|
|
95
101
|
const M = (n) => {
|
|
96
102
|
x.has(n) && n.contentWindow?.postMessage(
|
|
97
103
|
{
|
|
@@ -102,27 +108,37 @@ async function me(a, t) {
|
|
|
102
108
|
l
|
|
103
109
|
);
|
|
104
110
|
}, z = () => {
|
|
105
|
-
M(
|
|
106
|
-
}, F = () => {
|
|
107
|
-
|
|
111
|
+
M(f), M(d), s.getAttribute("src") !== "about:blank" && M(s);
|
|
112
|
+
}, F = (n) => {
|
|
113
|
+
d.contentWindow?.postMessage(
|
|
114
|
+
{
|
|
115
|
+
source: "viceme-engagement",
|
|
116
|
+
action: "tip-availability",
|
|
117
|
+
available: n,
|
|
118
|
+
workKey: a.workKey
|
|
119
|
+
},
|
|
120
|
+
l
|
|
121
|
+
);
|
|
122
|
+
}, B = () => {
|
|
123
|
+
if (u) return m;
|
|
108
124
|
const n = Z(e, r);
|
|
109
125
|
return n.anchorKey !== m.anchorKey && (m = n, z()), m;
|
|
110
|
-
},
|
|
111
|
-
y !== void 0 && e.clearTimeout(y), y = e.setTimeout(
|
|
112
|
-
},
|
|
113
|
-
|
|
114
|
-
},
|
|
115
|
-
const
|
|
116
|
-
|
|
126
|
+
}, E = () => {
|
|
127
|
+
y !== void 0 && e.clearTimeout(y), y = e.setTimeout(B, ye);
|
|
128
|
+
}, V = () => {
|
|
129
|
+
C(), E();
|
|
130
|
+
}, k = (n) => {
|
|
131
|
+
const c = n.currentTarget;
|
|
132
|
+
c.getAttribute("src") !== "about:blank" && (x.add(c), M(c));
|
|
117
133
|
};
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
134
|
+
f.addEventListener("load", k), d.addEventListener("load", k), s.addEventListener("load", k);
|
|
135
|
+
const Y = (n = !1) => {
|
|
136
|
+
g !== void 0 && (e.clearTimeout(g), g = void 0), s.style.display = "none", s.style.pointerEvents = "none", n && (R = "", L = !1, x.delete(s), s.src = "about:blank");
|
|
121
137
|
};
|
|
122
138
|
let $, q;
|
|
123
|
-
const
|
|
124
|
-
$ = n, q =
|
|
125
|
-
|
|
139
|
+
const ae = new Promise((n, c) => {
|
|
140
|
+
$ = n, q = c, T = e.setTimeout(() => {
|
|
141
|
+
c(
|
|
126
142
|
new P({
|
|
127
143
|
code: "INTERNAL_ERROR",
|
|
128
144
|
message: "Hosted danmaku frames did not become ready in time.",
|
|
@@ -130,47 +146,57 @@ async function me(a, t) {
|
|
|
130
146
|
capability: "danmaku"
|
|
131
147
|
})
|
|
132
148
|
);
|
|
133
|
-
},
|
|
134
|
-
}),
|
|
149
|
+
}, ee);
|
|
150
|
+
}), X = (n) => {
|
|
135
151
|
if (n.origin !== l) return;
|
|
136
|
-
const
|
|
137
|
-
if (!
|
|
138
|
-
const
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
152
|
+
const c = n.source === f.contentWindow, w = n.source === d.contentWindow, i = n.source === s.contentWindow;
|
|
153
|
+
if (!c && !w && !i) return;
|
|
154
|
+
const o = n.data;
|
|
155
|
+
if (w && ve(o, be) && o.source === "viceme-engagement" && o.workKey === a.workKey) {
|
|
156
|
+
o.action === "request-tip-availability" ? F(le(a, t.target)) : o.action === "open-tip" && I && ce(a, t.target);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (!o || o.source !== "viceme-danmaku") return;
|
|
160
|
+
const K = i ? "modal" : c ? "stage" : "controls";
|
|
161
|
+
if (o.action === "frame-ready") {
|
|
162
|
+
if (o.mode !== K) return;
|
|
163
|
+
if (K === "modal") {
|
|
164
|
+
if (o.frameToken !== R) return;
|
|
165
|
+
L = !0, g !== void 0 && (e.clearTimeout(g), g = void 0), s.style.display === "block" && (s.style.pointerEvents = "auto");
|
|
146
166
|
return;
|
|
147
167
|
}
|
|
148
|
-
|
|
168
|
+
O.add(K), O.has("stage") && O.has("controls") && !I && (I = !0, T !== void 0 && (e.clearTimeout(T), T = void 0), d.style.pointerEvents = "auto", $?.());
|
|
149
169
|
return;
|
|
150
170
|
}
|
|
151
|
-
if (
|
|
152
|
-
if (typeof
|
|
171
|
+
if (o.action === "resize-controls" && w) {
|
|
172
|
+
if (typeof o.width != "number" || !Number.isSafeInteger(o.width) || o.width < b || typeof o.height != "number" || !Number.isSafeInteger(o.height) || o.height < b || o.height > ue)
|
|
153
173
|
return;
|
|
154
|
-
|
|
174
|
+
const S = o.width === b && o.height <= b + J;
|
|
175
|
+
if (!S && o.height < j) return;
|
|
176
|
+
W = S, G = S ? b + J : o.height === ge ? fe : o.height, C();
|
|
155
177
|
}
|
|
156
|
-
if (
|
|
178
|
+
if (o.action === "request-anchor" && M(i ? s : c ? f : d), o.action === "open-modal" && w) {
|
|
157
179
|
if (!I) return;
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
180
|
+
if (s.getAttribute("src") === "about:blank") {
|
|
181
|
+
U += 1, R = String(U);
|
|
182
|
+
const S = new URL(s.dataset.src ?? "about:blank");
|
|
183
|
+
S.searchParams.set("frameToken", R), s.src = S.toString();
|
|
162
184
|
}
|
|
163
|
-
|
|
185
|
+
s.style.display = "block", s.style.pointerEvents = L ? "auto" : "none", L || (g !== void 0 && e.clearTimeout(g), g = e.setTimeout(() => Y(!0), ee));
|
|
164
186
|
}
|
|
165
|
-
|
|
166
|
-
},
|
|
167
|
-
q?.(
|
|
187
|
+
o.action === "close-modal" && (i || w) && Y(!L);
|
|
188
|
+
}, ne = e.setInterval(B, pe), Q = () => {
|
|
189
|
+
q?.(A()), H();
|
|
168
190
|
}, H = () => {
|
|
169
|
-
|
|
191
|
+
u || (u = !0, y !== void 0 && e.clearTimeout(y), T !== void 0 && e.clearTimeout(T), g !== void 0 && e.clearTimeout(g), e.clearInterval(ne), e.removeEventListener("message", X), e.removeEventListener("scroll", E), e.removeEventListener("resize", V), e.removeEventListener("popstate", E), e.removeEventListener("hashchange", E), f.removeEventListener("load", k), d.removeEventListener("load", k), s.removeEventListener("load", k), _?.(), _ = void 0, t.signal?.removeEventListener("abort", Q), h.remove());
|
|
170
192
|
};
|
|
171
193
|
try {
|
|
172
|
-
if (e.addEventListener("message",
|
|
173
|
-
t.target.appendChild(h), z(), await
|
|
194
|
+
if (e.addEventListener("message", X), e.addEventListener("scroll", E, { passive: !0 }), e.addEventListener("resize", V), e.addEventListener("popstate", E), e.addEventListener("hashchange", E), t.signal?.addEventListener("abort", Q, { once: !0 }), t.signal?.aborted) throw A();
|
|
195
|
+
if (t.target.appendChild(h), z(), await ae, u || t.signal?.aborted) throw A();
|
|
196
|
+
_ = ie(a, t.target, {
|
|
197
|
+
focus: () => d.focus(),
|
|
198
|
+
setTipAvailable: F
|
|
199
|
+
});
|
|
174
200
|
} catch (n) {
|
|
175
201
|
throw H(), n;
|
|
176
202
|
}
|
|
@@ -179,27 +205,27 @@ async function me(a, t) {
|
|
|
179
205
|
destroy: H
|
|
180
206
|
};
|
|
181
207
|
}
|
|
182
|
-
const
|
|
183
|
-
function
|
|
184
|
-
let r =
|
|
185
|
-
r || (r = /* @__PURE__ */ new WeakMap(),
|
|
208
|
+
const te = /* @__PURE__ */ new WeakMap();
|
|
209
|
+
function Le(a, t) {
|
|
210
|
+
let r = te.get(a);
|
|
211
|
+
r || (r = /* @__PURE__ */ new WeakMap(), te.set(a, r));
|
|
186
212
|
const e = r.get(t.target);
|
|
187
213
|
if (e) return e;
|
|
188
|
-
const l =
|
|
214
|
+
const l = Ee(a, t).then((m) => {
|
|
189
215
|
let v = !1;
|
|
190
|
-
const
|
|
216
|
+
const u = {
|
|
191
217
|
capability: "danmaku",
|
|
192
218
|
destroy() {
|
|
193
|
-
v || (v = !0, t.signal?.removeEventListener("abort",
|
|
219
|
+
v || (v = !0, t.signal?.removeEventListener("abort", u.destroy), r.get(t.target) === l && r.delete(t.target), m.destroy());
|
|
194
220
|
}
|
|
195
221
|
};
|
|
196
|
-
return t.signal?.addEventListener("abort",
|
|
222
|
+
return t.signal?.addEventListener("abort", u.destroy, { once: !0 }), t.signal?.aborted && u.destroy(), u;
|
|
197
223
|
}).catch((m) => {
|
|
198
224
|
throw r.get(t.target) === l && r.delete(t.target), m;
|
|
199
225
|
});
|
|
200
226
|
return r.set(t.target, l), l;
|
|
201
227
|
}
|
|
202
228
|
export {
|
|
203
|
-
|
|
229
|
+
Le as mountDanmaku
|
|
204
230
|
};
|
|
205
231
|
//# sourceMappingURL=danmaku.js.map
|
package/dist/danmaku.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"danmaku.js","sources":["../src/danmaku/anchor.ts","../src/danmaku/mount.ts","../src/danmaku/index.ts"],"sourcesContent":["export interface DanmakuPageAnchor {\n /** Stable page-and-position key sent to the hosted danmaku runtime. */\n anchorKey: string;\n /** Human-readable 10% scroll bucket, useful for diagnostics. */\n scrollBucket: string;\n}\n\n/**\n * Build a stable page-position anchor without exposing the page URL.\n *\n * Canonical URLs and SPA hash routes participate in the local hash. Only the\n * resulting opaque key leaves the host page.\n */\nexport function readDanmakuPageAnchor(\n windowObject: Window = window,\n documentObject: Document = document,\n): DanmakuPageAnchor {\n const pageUrl = canonicalPageUrl(windowObject, documentObject);\n const bucket = scrollBucket(windowObject, documentObject);\n return {\n anchorKey: `page:${hashString(pageUrl)}:scroll:${bucket}`,\n scrollBucket: bucket,\n };\n}\n\nfunction canonicalPageUrl(windowObject: Window, documentObject: Document): string {\n const canonical = documentObject.querySelector<HTMLLinkElement>('link[rel=\"canonical\"][href]');\n const rawUrl = canonical?.href || windowObject.location.href;\n try {\n const url = new URL(rawUrl, windowObject.location.href);\n url.username = '';\n url.password = '';\n if (canonical && !url.hash && windowObject.location.hash) {\n url.hash = windowObject.location.hash;\n }\n return url.toString();\n } catch {\n return windowObject.location.href;\n }\n}\n\nfunction scrollBucket(windowObject: Window, documentObject: Document): string {\n const root = documentObject.documentElement;\n const body = documentObject.body;\n const scrollTop =\n windowObject.scrollY || windowObject.pageYOffset || root.scrollTop || body?.scrollTop || 0;\n const scrollHeight = Math.max(\n root.scrollHeight,\n root.offsetHeight,\n root.clientHeight,\n body?.scrollHeight ?? 0,\n body?.offsetHeight ?? 0,\n );\n const maxScroll = Math.max(0, scrollHeight - windowObject.innerHeight);\n if (maxScroll <= 1) return '0-100';\n\n const percent = Math.max(0, Math.min(99, (scrollTop / maxScroll) * 100));\n const start = Math.min(90, Math.floor(percent / 10) * 10);\n return `${start}-${start + 10}`;\n}\n\n/** Deterministic 64-bit-style hash encoded as at most 16 base36 characters. */\nfunction hashString(value: string): string {\n let high = 0xdeadbeef ^ value.length;\n let low = 0x41c6ce57 ^ value.length;\n for (let index = 0; index < value.length; index += 1) {\n const character = value.charCodeAt(index);\n high = Math.imul(high ^ character, 2654435761);\n low = Math.imul(low ^ character, 1597334677);\n }\n high = Math.imul(high ^ (high >>> 16), 2246822507);\n high ^= Math.imul(low ^ (low >>> 13), 3266489909);\n low = Math.imul(low ^ (low >>> 16), 2246822507);\n low ^= Math.imul(high ^ (high >>> 13), 3266489909);\n return (\n (low >>> 0).toString(36).padStart(7, '0') + (high >>> 0).toString(36).padStart(7, '0')\n ).slice(0, 16);\n}\n","import type { ViceMeClient } from '../core/client.ts';\nimport { BUILD_WIDGET_ORIGINS } from '../core/build-endpoints.ts';\nimport { clientDestroyed, ViceMeError } from '../core/errors.ts';\nimport type { CapabilityMountHandle, CapabilityMountOptions } from '../capability-mount.ts';\nimport { SDK_VERSION } from '../version.ts';\nimport { readDanmakuPageAnchor, type DanmakuPageAnchor } from './anchor.ts';\n\ntype DanmakuFrameMode = 'stage' | 'controls' | 'modal';\n\ninterface DanmakuBridgeMessage {\n source?: unknown;\n action?: unknown;\n frameToken?: unknown;\n mode?: unknown;\n width?: unknown;\n height?: unknown;\n}\n\nconst CONTROLS_MIN_SIZE = 32;\nconst CONTROLS_BAR_HEIGHT = 56;\nconst CONTROLS_MAX_HEIGHT = 360;\nconst CONTROLS_MAX_WIDTH = 480;\nconst ANCHOR_DEBOUNCE_MS = 120;\nconst LOCATION_POLL_MS = 1_000;\nexport const FRAME_READY_TIMEOUT_MS = 8_000;\n\nexport async function mount(\n client: ViceMeClient,\n options: CapabilityMountOptions,\n): Promise<CapabilityMountHandle> {\n if (options.signal?.aborted) throw clientDestroyed();\n await client.ready();\n if (options.signal?.aborted) throw clientDestroyed();\n if (!client.hasCapability('danmaku')) {\n throw new ViceMeError({\n code: 'CAPABILITY_DISABLED',\n message: 'Danmaku is not available in this SDK build.',\n retryable: false,\n capability: 'danmaku',\n });\n }\n\n const documentObject = options.target.ownerDocument;\n const windowObject = documentObject.defaultView;\n if (!windowObject) {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Danmaku requires a browser document.',\n retryable: false,\n capability: 'danmaku',\n });\n }\n\n const widgetOrigin = BUILD_WIDGET_ORIGINS[client.region];\n let currentAnchor = readDanmakuPageAnchor(windowObject, documentObject);\n const locale =\n documentObject.documentElement.lang.trim() || windowObject.navigator.language || 'en';\n let destroyed = false;\n let anchorTimer: number | undefined;\n let readyTimer: number | undefined;\n let modalReadyTimer: number | undefined;\n let initialFramesReady = false;\n let modalAttempt = 0;\n let modalFrameToken = '';\n let modalReady = false;\n const loadedFrames = new WeakSet<HTMLIFrameElement>();\n const readyModes = new Set<DanmakuFrameMode>();\n\n const portal = documentObject.createElement('div');\n portal.dataset.vicemeDanmaku = 'mounted';\n portal.style.all = 'initial';\n portal.style.position = 'fixed';\n portal.style.inset = '0';\n portal.style.width = '100%';\n portal.style.height = '100%';\n portal.style.pointerEvents = 'none';\n portal.style.zIndex = '2147483000';\n portal.style.contain = 'layout style size';\n\n const shadow = portal.attachShadow({ mode: 'open' });\n const root = documentObject.createElement('div');\n root.style.boxSizing = 'border-box';\n root.style.position = 'fixed';\n root.style.inset = '0';\n root.style.width = '100%';\n root.style.height = '100%';\n root.style.pointerEvents = 'none';\n shadow.append(root);\n\n const frameUrl = (mode: DanmakuFrameMode): URL => {\n const url = new URL('/embed/danmaku', widgetOrigin);\n url.searchParams.set('mode', mode);\n url.searchParams.set('workKey', client.workKey);\n url.searchParams.set('theme', options.theme);\n url.searchParams.set('locale', locale);\n url.searchParams.set('sdk', SDK_VERSION);\n url.searchParams.set('anchorKey', currentAnchor.anchorKey);\n return url;\n };\n\n const createFrame = (\n mode: DanmakuFrameMode,\n title: string,\n source: string,\n ): HTMLIFrameElement => {\n const frame = documentObject.createElement('iframe');\n frame.title = title;\n frame.src = source;\n frame.loading = 'eager';\n frame.referrerPolicy = 'no-referrer';\n frame.setAttribute('allowtransparency', 'true');\n frame.setAttribute(\n 'sandbox',\n 'allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts',\n );\n frame.dataset.mode = mode;\n frame.style.boxSizing = 'border-box';\n frame.style.colorScheme = 'normal';\n frame.style.position = 'fixed';\n frame.style.margin = '0';\n frame.style.border = '0';\n frame.style.background = 'transparent';\n frame.style.width = '100%';\n frame.style.zIndex = '2147483000';\n return frame;\n };\n\n const stage = createFrame('stage', 'ViceMe Danmaku', frameUrl('stage').toString());\n stage.setAttribute('aria-hidden', 'true');\n stage.style.inset = '0';\n stage.style.height = '100%';\n stage.style.pointerEvents = 'none';\n\n const controls = createFrame(\n 'controls',\n 'ViceMe Danmaku controls',\n frameUrl('controls').toString(),\n );\n controls.style.left = '50%';\n controls.style.bottom = 'env(safe-area-inset-bottom, 0px)';\n controls.style.maxWidth = `${CONTROLS_MAX_WIDTH}px`;\n controls.style.transform = 'translateX(-50%)';\n let controlsRequestedWidth = CONTROLS_MAX_WIDTH;\n let controlsRequestedHeight = CONTROLS_BAR_HEIGHT;\n const applyControlsSize = (): void => {\n const viewportWidth = Math.max(\n CONTROLS_MIN_SIZE,\n Math.floor(windowObject.innerWidth || CONTROLS_MAX_WIDTH),\n );\n controls.style.width = `${Math.min(controlsRequestedWidth, viewportWidth)}px`;\n controls.style.height = `${controlsRequestedHeight}px`;\n };\n applyControlsSize();\n controls.style.pointerEvents = 'none';\n\n const modal = createFrame('modal', 'ViceMe Danmaku dialog', 'about:blank');\n modal.dataset.src = frameUrl('modal').toString();\n modal.style.inset = '0';\n modal.style.height = '100%';\n modal.style.display = 'none';\n modal.style.pointerEvents = 'none';\n\n root.append(stage, controls, modal);\n\n const postAnchor = (frame: HTMLIFrameElement): void => {\n if (!loadedFrames.has(frame)) return;\n frame.contentWindow?.postMessage(\n {\n source: 'viceme-danmaku',\n action: 'anchor-change',\n anchorKey: currentAnchor.anchorKey,\n },\n widgetOrigin,\n );\n };\n const postAnchorToMountedFrames = (): void => {\n postAnchor(stage);\n postAnchor(controls);\n if (modal.getAttribute('src') !== 'about:blank') postAnchor(modal);\n };\n\n const refreshAnchor = (): DanmakuPageAnchor => {\n if (destroyed) return currentAnchor;\n const next = readDanmakuPageAnchor(windowObject, documentObject);\n if (next.anchorKey !== currentAnchor.anchorKey) {\n currentAnchor = next;\n postAnchorToMountedFrames();\n }\n return currentAnchor;\n };\n const scheduleAnchorRefresh = (): void => {\n if (anchorTimer !== undefined) windowObject.clearTimeout(anchorTimer);\n anchorTimer = windowObject.setTimeout(refreshAnchor, ANCHOR_DEBOUNCE_MS);\n };\n const handleWindowResize = (): void => {\n applyControlsSize();\n scheduleAnchorRefresh();\n };\n\n const frameLoaded = (event: Event): void => {\n const frame = event.currentTarget as HTMLIFrameElement;\n if (frame.getAttribute('src') === 'about:blank') return;\n loadedFrames.add(frame);\n postAnchor(frame);\n };\n stage.addEventListener('load', frameLoaded);\n controls.addEventListener('load', frameLoaded);\n modal.addEventListener('load', frameLoaded);\n\n const hideModal = (resetFrame = false): void => {\n if (modalReadyTimer !== undefined) {\n windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = undefined;\n }\n modal.style.display = 'none';\n modal.style.pointerEvents = 'none';\n if (resetFrame) {\n modalFrameToken = '';\n modalReady = false;\n loadedFrames.delete(modal);\n modal.src = 'about:blank';\n }\n };\n\n let resolveInitialFrames: (() => void) | undefined;\n let rejectInitialFrames: ((error: ViceMeError) => void) | undefined;\n const initialFrameReadiness = new Promise<void>((resolve, reject) => {\n resolveInitialFrames = resolve;\n rejectInitialFrames = reject;\n readyTimer = windowObject.setTimeout(() => {\n reject(\n new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Hosted danmaku frames did not become ready in time.',\n retryable: true,\n capability: 'danmaku',\n }),\n );\n }, FRAME_READY_TIMEOUT_MS);\n });\n\n const onMessage = (event: MessageEvent): void => {\n if (event.origin !== widgetOrigin) return;\n const fromStage = event.source === stage.contentWindow;\n const fromControls = event.source === controls.contentWindow;\n const fromModal = event.source === modal.contentWindow;\n if (!fromStage && !fromControls && !fromModal) return;\n\n const message = event.data as DanmakuBridgeMessage | null;\n if (!message || message.source !== 'viceme-danmaku') return;\n\n const sourceMode: DanmakuFrameMode = fromModal ? 'modal' : fromStage ? 'stage' : 'controls';\n if (message.action === 'frame-ready') {\n if (message.mode !== sourceMode) return;\n if (sourceMode === 'modal') {\n if (message.frameToken !== modalFrameToken) return;\n modalReady = true;\n if (modalReadyTimer !== undefined) {\n windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = undefined;\n }\n if (modal.style.display === 'block') modal.style.pointerEvents = 'auto';\n return;\n }\n readyModes.add(sourceMode);\n if (readyModes.has('stage') && readyModes.has('controls') && !initialFramesReady) {\n initialFramesReady = true;\n if (readyTimer !== undefined) {\n windowObject.clearTimeout(readyTimer);\n readyTimer = undefined;\n }\n controls.style.pointerEvents = 'auto';\n resolveInitialFrames?.();\n }\n return;\n }\n if (message.action === 'resize-controls' && fromControls) {\n if (\n typeof message.width !== 'number' ||\n !Number.isInteger(message.width) ||\n message.width < CONTROLS_MIN_SIZE ||\n message.width > CONTROLS_MAX_WIDTH ||\n typeof message.height !== 'number' ||\n !Number.isInteger(message.height) ||\n message.height < CONTROLS_MIN_SIZE ||\n message.height > CONTROLS_MAX_HEIGHT\n ) {\n return;\n }\n controlsRequestedWidth = message.width;\n controlsRequestedHeight = message.height;\n applyControlsSize();\n }\n if (message.action === 'request-anchor') {\n postAnchor(fromModal ? modal : fromStage ? stage : controls);\n }\n if (message.action === 'open-modal' && fromControls) {\n if (!initialFramesReady) return;\n if (modal.getAttribute('src') === 'about:blank') {\n modalAttempt += 1;\n modalFrameToken = String(modalAttempt);\n const modalUrl = new URL(modal.dataset.src ?? 'about:blank');\n modalUrl.searchParams.set('frameToken', modalFrameToken);\n modal.src = modalUrl.toString();\n }\n modal.style.display = 'block';\n modal.style.pointerEvents = modalReady ? 'auto' : 'none';\n if (!modalReady) {\n if (modalReadyTimer !== undefined) windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = windowObject.setTimeout(() => hideModal(true), FRAME_READY_TIMEOUT_MS);\n }\n }\n if (message.action === 'close-modal' && (fromModal || fromControls)) {\n hideModal(!modalReady);\n }\n };\n\n const locationPoll = windowObject.setInterval(refreshAnchor, LOCATION_POLL_MS);\n const onAbort = (): void => {\n rejectInitialFrames?.(clientDestroyed());\n cleanup();\n };\n const cleanup = (): void => {\n if (destroyed) return;\n destroyed = true;\n if (anchorTimer !== undefined) windowObject.clearTimeout(anchorTimer);\n if (readyTimer !== undefined) windowObject.clearTimeout(readyTimer);\n if (modalReadyTimer !== undefined) windowObject.clearTimeout(modalReadyTimer);\n windowObject.clearInterval(locationPoll);\n windowObject.removeEventListener('message', onMessage);\n windowObject.removeEventListener('scroll', scheduleAnchorRefresh);\n windowObject.removeEventListener('resize', handleWindowResize);\n windowObject.removeEventListener('popstate', scheduleAnchorRefresh);\n windowObject.removeEventListener('hashchange', scheduleAnchorRefresh);\n stage.removeEventListener('load', frameLoaded);\n controls.removeEventListener('load', frameLoaded);\n modal.removeEventListener('load', frameLoaded);\n options.signal?.removeEventListener('abort', onAbort);\n portal.remove();\n };\n\n try {\n windowObject.addEventListener('message', onMessage);\n windowObject.addEventListener('scroll', scheduleAnchorRefresh, { passive: true });\n windowObject.addEventListener('resize', handleWindowResize);\n windowObject.addEventListener('popstate', scheduleAnchorRefresh);\n windowObject.addEventListener('hashchange', scheduleAnchorRefresh);\n options.signal?.addEventListener('abort', onAbort, { once: true });\n if (options.signal?.aborted) throw clientDestroyed();\n options.target.appendChild(portal);\n postAnchorToMountedFrames();\n await initialFrameReadiness;\n } catch (error) {\n cleanup();\n throw error;\n }\n\n return {\n capability: 'danmaku',\n destroy: cleanup,\n };\n}\n","import type { ViceMeClient } from '../core/client.ts';\nimport { mount } from './mount.ts';\n\nexport interface DanmakuMountOptions {\n target: Element;\n theme: 'light' | 'dark' | 'auto';\n signal?: AbortSignal;\n}\n\nexport interface DanmakuMountHandle {\n readonly capability: 'danmaku';\n destroy(): void;\n}\n\nconst mounts = new WeakMap<ViceMeClient, WeakMap<Element, Promise<DanmakuMountHandle>>>();\n\n/** Explicit ESM/npm entry point; the CDN loader calls the same mount function. */\nexport function mountDanmaku(\n client: ViceMeClient,\n options: DanmakuMountOptions,\n): Promise<DanmakuMountHandle> {\n let byTarget = mounts.get(client);\n if (!byTarget) {\n byTarget = new WeakMap();\n mounts.set(client, byTarget);\n }\n const existing = byTarget.get(options.target);\n if (existing) return existing;\n\n const pending: Promise<DanmakuMountHandle> = mount(client, options)\n .then((raw) => {\n let destroyed = false;\n const handle: DanmakuMountHandle = {\n capability: 'danmaku' as const,\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n options.signal?.removeEventListener('abort', handle.destroy);\n if (byTarget.get(options.target) === pending) byTarget.delete(options.target);\n raw.destroy();\n },\n };\n options.signal?.addEventListener('abort', handle.destroy, { once: true });\n if (options.signal?.aborted) handle.destroy();\n return handle;\n })\n .catch((error: unknown) => {\n if (byTarget.get(options.target) === pending) byTarget.delete(options.target);\n throw error;\n });\n byTarget.set(options.target, pending);\n return pending;\n}\n"],"names":["readDanmakuPageAnchor","windowObject","documentObject","pageUrl","canonicalPageUrl","bucket","scrollBucket","hashString","canonical","rawUrl","url","root","body","scrollTop","scrollHeight","maxScroll","percent","start","value","high","low","index","character","CONTROLS_MIN_SIZE","CONTROLS_BAR_HEIGHT","CONTROLS_MAX_HEIGHT","CONTROLS_MAX_WIDTH","ANCHOR_DEBOUNCE_MS","LOCATION_POLL_MS","FRAME_READY_TIMEOUT_MS","mount","client","options","clientDestroyed","ViceMeError","widgetOrigin","BUILD_WIDGET_ORIGINS","currentAnchor","locale","destroyed","anchorTimer","readyTimer","modalReadyTimer","initialFramesReady","modalAttempt","modalFrameToken","modalReady","loadedFrames","readyModes","portal","shadow","frameUrl","mode","SDK_VERSION","createFrame","title","source","frame","stage","controls","controlsRequestedWidth","controlsRequestedHeight","applyControlsSize","viewportWidth","modal","postAnchor","postAnchorToMountedFrames","refreshAnchor","next","scheduleAnchorRefresh","handleWindowResize","frameLoaded","event","hideModal","resetFrame","resolveInitialFrames","rejectInitialFrames","initialFrameReadiness","resolve","reject","onMessage","fromStage","fromControls","fromModal","message","sourceMode","modalUrl","locationPoll","onAbort","cleanup","error","mounts","mountDanmaku","byTarget","existing","pending","raw","handle"],"mappings":";;;AAaO,SAASA,EACdC,IAAuB,QACvBC,IAA2B,UACR;AACnB,QAAMC,IAAUC,GAAiBH,GAAcC,CAAc,GACvDG,IAASC,GAAaL,GAAcC,CAAc;AACxD,SAAO;AAAA,IACL,WAAW,QAAQK,GAAWJ,CAAO,CAAC,WAAWE,CAAM;AAAA,IACvD,cAAcA;AAAA,EAAA;AAElB;AAEA,SAASD,GAAiBH,GAAsBC,GAAkC;AAChF,QAAMM,IAAYN,EAAe,cAA+B,6BAA6B,GACvFO,IAASD,GAAW,QAAQP,EAAa,SAAS;AACxD,MAAI;AACF,UAAMS,IAAM,IAAI,IAAID,GAAQR,EAAa,SAAS,IAAI;AACtD,WAAAS,EAAI,WAAW,IACfA,EAAI,WAAW,IACXF,KAAa,CAACE,EAAI,QAAQT,EAAa,SAAS,SAClDS,EAAI,OAAOT,EAAa,SAAS,OAE5BS,EAAI,SAAA;AAAA,EACb,QAAQ;AACN,WAAOT,EAAa,SAAS;AAAA,EAC/B;AACF;AAEA,SAASK,GAAaL,GAAsBC,GAAkC;AAC5E,QAAMS,IAAOT,EAAe,iBACtBU,IAAOV,EAAe,MACtBW,IACJZ,EAAa,WAAWA,EAAa,eAAeU,EAAK,aAAaC,GAAM,aAAa,GACrFE,IAAe,KAAK;AAAA,IACxBH,EAAK;AAAA,IACLA,EAAK;AAAA,IACLA,EAAK;AAAA,IACLC,GAAM,gBAAgB;AAAA,IACtBA,GAAM,gBAAgB;AAAA,EAAA,GAElBG,IAAY,KAAK,IAAI,GAAGD,IAAeb,EAAa,WAAW;AACrE,MAAIc,KAAa,EAAG,QAAO;AAE3B,QAAMC,IAAU,KAAK,IAAI,GAAG,KAAK,IAAI,IAAKH,IAAYE,IAAa,GAAG,CAAC,GACjEE,IAAQ,KAAK,IAAI,IAAI,KAAK,MAAMD,IAAU,EAAE,IAAI,EAAE;AACxD,SAAO,GAAGC,CAAK,IAAIA,IAAQ,EAAE;AAC/B;AAGA,SAASV,GAAWW,GAAuB;AACzC,MAAIC,IAAO,aAAaD,EAAM,QAC1BE,IAAM,aAAaF,EAAM;AAC7B,WAASG,IAAQ,GAAGA,IAAQH,EAAM,QAAQG,KAAS,GAAG;AACpD,UAAMC,IAAYJ,EAAM,WAAWG,CAAK;AACxC,IAAAF,IAAO,KAAK,KAAKA,IAAOG,GAAW,UAAU,GAC7CF,IAAM,KAAK,KAAKA,IAAME,GAAW,UAAU;AAAA,EAC7C;AACA,SAAAH,IAAO,KAAK,KAAKA,IAAQA,MAAS,IAAK,UAAU,GACjDA,KAAQ,KAAK,KAAKC,IAAOA,MAAQ,IAAK,UAAU,GAChDA,IAAM,KAAK,KAAKA,IAAOA,MAAQ,IAAK,UAAU,GAC9CA,KAAO,KAAK,KAAKD,IAAQA,MAAS,IAAK,UAAU,KAE9CC,MAAQ,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,KAAKD,MAAS,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,GACrF,MAAM,GAAG,EAAE;AACf;AC3DA,MAAMI,IAAoB,IACpBC,KAAsB,IACtBC,KAAsB,KACtBC,IAAqB,KACrBC,KAAqB,KACrBC,KAAmB,KACZC,IAAyB;AAEtC,eAAsBC,GACpBC,GACAC,GACgC;AAChC,MAAIA,EAAQ,QAAQ,QAAS,OAAMC,EAAA;AAEnC,MADA,MAAMF,EAAO,MAAA,GACTC,EAAQ,QAAQ,QAAS,OAAMC,EAAA;AACnC,MAAI,CAACF,EAAO,cAAc,SAAS;AACjC,UAAM,IAAIG,EAAY;AAAA,MACpB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,MACX,YAAY;AAAA,IAAA,CACb;AAGH,QAAMhC,IAAiB8B,EAAQ,OAAO,eAChC/B,IAAeC,EAAe;AACpC,MAAI,CAACD;AACH,UAAM,IAAIiC,EAAY;AAAA,MACpB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,MACX,YAAY;AAAA,IAAA,CACb;AAGH,QAAMC,IAAeC,GAAqBL,EAAO,MAAM;AACvD,MAAIM,IAAgBrC,EAAsBC,GAAcC,CAAc;AACtE,QAAMoC,IACJpC,EAAe,gBAAgB,KAAK,UAAUD,EAAa,UAAU,YAAY;AACnF,MAAIsC,IAAY,IACZC,GACAC,GACAC,GACAC,IAAqB,IACrBC,IAAe,GACfC,IAAkB,IAClBC,IAAa;AACjB,QAAMC,wBAAmB,QAAA,GACnBC,wBAAiB,IAAA,GAEjBC,IAAS/C,EAAe,cAAc,KAAK;AACjD,EAAA+C,EAAO,QAAQ,gBAAgB,WAC/BA,EAAO,MAAM,MAAM,WACnBA,EAAO,MAAM,WAAW,SACxBA,EAAO,MAAM,QAAQ,KACrBA,EAAO,MAAM,QAAQ,QACrBA,EAAO,MAAM,SAAS,QACtBA,EAAO,MAAM,gBAAgB,QAC7BA,EAAO,MAAM,SAAS,cACtBA,EAAO,MAAM,UAAU;AAEvB,QAAMC,IAASD,EAAO,aAAa,EAAE,MAAM,QAAQ,GAC7CtC,IAAOT,EAAe,cAAc,KAAK;AAC/C,EAAAS,EAAK,MAAM,YAAY,cACvBA,EAAK,MAAM,WAAW,SACtBA,EAAK,MAAM,QAAQ,KACnBA,EAAK,MAAM,QAAQ,QACnBA,EAAK,MAAM,SAAS,QACpBA,EAAK,MAAM,gBAAgB,QAC3BuC,EAAO,OAAOvC,CAAI;AAElB,QAAMwC,IAAW,CAACC,MAAgC;AAChD,UAAM1C,IAAM,IAAI,IAAI,kBAAkByB,CAAY;AAClD,WAAAzB,EAAI,aAAa,IAAI,QAAQ0C,CAAI,GACjC1C,EAAI,aAAa,IAAI,WAAWqB,EAAO,OAAO,GAC9CrB,EAAI,aAAa,IAAI,SAASsB,EAAQ,KAAK,GAC3CtB,EAAI,aAAa,IAAI,UAAU4B,CAAM,GACrC5B,EAAI,aAAa,IAAI,OAAO2C,EAAW,GACvC3C,EAAI,aAAa,IAAI,aAAa2B,EAAc,SAAS,GAClD3B;AAAA,EACT,GAEM4C,IAAc,CAClBF,GACAG,GACAC,MACsB;AACtB,UAAMC,IAAQvD,EAAe,cAAc,QAAQ;AACnD,WAAAuD,EAAM,QAAQF,GACdE,EAAM,MAAMD,GACZC,EAAM,UAAU,SAChBA,EAAM,iBAAiB,eACvBA,EAAM,aAAa,qBAAqB,MAAM,GAC9CA,EAAM;AAAA,MACJ;AAAA,MACA;AAAA,IAAA,GAEFA,EAAM,QAAQ,OAAOL,GACrBK,EAAM,MAAM,YAAY,cACxBA,EAAM,MAAM,cAAc,UAC1BA,EAAM,MAAM,WAAW,SACvBA,EAAM,MAAM,SAAS,KACrBA,EAAM,MAAM,SAAS,KACrBA,EAAM,MAAM,aAAa,eACzBA,EAAM,MAAM,QAAQ,QACpBA,EAAM,MAAM,SAAS,cACdA;AAAA,EACT,GAEMC,IAAQJ,EAAY,SAAS,kBAAkBH,EAAS,OAAO,EAAE,UAAU;AACjF,EAAAO,EAAM,aAAa,eAAe,MAAM,GACxCA,EAAM,MAAM,QAAQ,KACpBA,EAAM,MAAM,SAAS,QACrBA,EAAM,MAAM,gBAAgB;AAE5B,QAAMC,IAAWL;AAAA,IACf;AAAA,IACA;AAAA,IACAH,EAAS,UAAU,EAAE,SAAA;AAAA,EAAS;AAEhC,EAAAQ,EAAS,MAAM,OAAO,OACtBA,EAAS,MAAM,SAAS,oCACxBA,EAAS,MAAM,WAAW,GAAGjC,CAAkB,MAC/CiC,EAAS,MAAM,YAAY;AAC3B,MAAIC,IAAyBlC,GACzBmC,IAA0BrC;AAC9B,QAAMsC,IAAoB,MAAY;AACpC,UAAMC,IAAgB,KAAK;AAAA,MACzBxC;AAAA,MACA,KAAK,MAAMtB,EAAa,cAAcyB,CAAkB;AAAA,IAAA;AAE1D,IAAAiC,EAAS,MAAM,QAAQ,GAAG,KAAK,IAAIC,GAAwBG,CAAa,CAAC,MACzEJ,EAAS,MAAM,SAAS,GAAGE,CAAuB;AAAA,EACpD;AACA,EAAAC,EAAA,GACAH,EAAS,MAAM,gBAAgB;AAE/B,QAAMK,IAAQV,EAAY,SAAS,yBAAyB,aAAa;AACzE,EAAAU,EAAM,QAAQ,MAAMb,EAAS,OAAO,EAAE,SAAA,GACtCa,EAAM,MAAM,QAAQ,KACpBA,EAAM,MAAM,SAAS,QACrBA,EAAM,MAAM,UAAU,QACtBA,EAAM,MAAM,gBAAgB,QAE5BrD,EAAK,OAAO+C,GAAOC,GAAUK,CAAK;AAElC,QAAMC,IAAa,CAACR,MAAmC;AACrD,IAAKV,EAAa,IAAIU,CAAK,KAC3BA,EAAM,eAAe;AAAA,MACnB;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,WAAWpB,EAAc;AAAA,MAAA;AAAA,MAE3BF;AAAA,IAAA;AAAA,EAEJ,GACM+B,IAA4B,MAAY;AAC5C,IAAAD,EAAWP,CAAK,GAChBO,EAAWN,CAAQ,GACfK,EAAM,aAAa,KAAK,MAAM,mBAA0BA,CAAK;AAAA,EACnE,GAEMG,IAAgB,MAAyB;AAC7C,QAAI5B,EAAW,QAAOF;AACtB,UAAM+B,IAAOpE,EAAsBC,GAAcC,CAAc;AAC/D,WAAIkE,EAAK,cAAc/B,EAAc,cACnCA,IAAgB+B,GAChBF,EAAA,IAEK7B;AAAA,EACT,GACMgC,IAAwB,MAAY;AACxC,IAAI7B,MAAgB,UAAWvC,EAAa,aAAauC,CAAW,GACpEA,IAAcvC,EAAa,WAAWkE,GAAexC,EAAkB;AAAA,EACzE,GACM2C,IAAqB,MAAY;AACrC,IAAAR,EAAA,GACAO,EAAA;AAAA,EACF,GAEME,IAAc,CAACC,MAAuB;AAC1C,UAAMf,IAAQe,EAAM;AACpB,IAAIf,EAAM,aAAa,KAAK,MAAM,kBAClCV,EAAa,IAAIU,CAAK,GACtBQ,EAAWR,CAAK;AAAA,EAClB;AACA,EAAAC,EAAM,iBAAiB,QAAQa,CAAW,GAC1CZ,EAAS,iBAAiB,QAAQY,CAAW,GAC7CP,EAAM,iBAAiB,QAAQO,CAAW;AAE1C,QAAME,IAAY,CAACC,IAAa,OAAgB;AAC9C,IAAIhC,MAAoB,WACtBzC,EAAa,aAAayC,CAAe,GACzCA,IAAkB,SAEpBsB,EAAM,MAAM,UAAU,QACtBA,EAAM,MAAM,gBAAgB,QACxBU,MACF7B,IAAkB,IAClBC,IAAa,IACbC,EAAa,OAAOiB,CAAK,GACzBA,EAAM,MAAM;AAAA,EAEhB;AAEA,MAAIW,GACAC;AACJ,QAAMC,KAAwB,IAAI,QAAc,CAACC,GAASC,MAAW;AACnE,IAAAJ,IAAuBG,GACvBF,IAAsBG,GACtBtC,IAAaxC,EAAa,WAAW,MAAM;AACzC,MAAA8E;AAAA,QACE,IAAI7C,EAAY;AAAA,UACd,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW;AAAA,UACX,YAAY;AAAA,QAAA,CACb;AAAA,MAAA;AAAA,IAEL,GAAGL,CAAsB;AAAA,EAC3B,CAAC,GAEKmD,IAAY,CAACR,MAA8B;AAC/C,QAAIA,EAAM,WAAWrC,EAAc;AACnC,UAAM8C,IAAYT,EAAM,WAAWd,EAAM,eACnCwB,IAAeV,EAAM,WAAWb,EAAS,eACzCwB,IAAYX,EAAM,WAAWR,EAAM;AACzC,QAAI,CAACiB,KAAa,CAACC,KAAgB,CAACC,EAAW;AAE/C,UAAMC,IAAUZ,EAAM;AACtB,QAAI,CAACY,KAAWA,EAAQ,WAAW,iBAAkB;AAErD,UAAMC,IAA+BF,IAAY,UAAUF,IAAY,UAAU;AACjF,QAAIG,EAAQ,WAAW,eAAe;AACpC,UAAIA,EAAQ,SAASC,EAAY;AACjC,UAAIA,MAAe,SAAS;AAC1B,YAAID,EAAQ,eAAevC,EAAiB;AAC5C,QAAAC,IAAa,IACTJ,MAAoB,WACtBzC,EAAa,aAAayC,CAAe,GACzCA,IAAkB,SAEhBsB,EAAM,MAAM,YAAY,YAASA,EAAM,MAAM,gBAAgB;AACjE;AAAA,MACF;AACA,MAAAhB,EAAW,IAAIqC,CAAU,GACrBrC,EAAW,IAAI,OAAO,KAAKA,EAAW,IAAI,UAAU,KAAK,CAACL,MAC5DA,IAAqB,IACjBF,MAAe,WACjBxC,EAAa,aAAawC,CAAU,GACpCA,IAAa,SAEfkB,EAAS,MAAM,gBAAgB,QAC/BgB,IAAA;AAEF;AAAA,IACF;AACA,QAAIS,EAAQ,WAAW,qBAAqBF,GAAc;AACxD,UACE,OAAOE,EAAQ,SAAU,YACzB,CAAC,OAAO,UAAUA,EAAQ,KAAK,KAC/BA,EAAQ,QAAQ7D,KAChB6D,EAAQ,QAAQ1D,KAChB,OAAO0D,EAAQ,UAAW,YAC1B,CAAC,OAAO,UAAUA,EAAQ,MAAM,KAChCA,EAAQ,SAAS7D,KACjB6D,EAAQ,SAAS3D;AAEjB;AAEF,MAAAmC,IAAyBwB,EAAQ,OACjCvB,IAA0BuB,EAAQ,QAClCtB,EAAA;AAAA,IACF;AAIA,QAHIsB,EAAQ,WAAW,oBACrBnB,EAAWkB,IAAYnB,IAAQiB,IAAYvB,IAAQC,CAAQ,GAEzDyB,EAAQ,WAAW,gBAAgBF,GAAc;AACnD,UAAI,CAACvC,EAAoB;AACzB,UAAIqB,EAAM,aAAa,KAAK,MAAM,eAAe;AAC/C,QAAApB,KAAgB,GAChBC,IAAkB,OAAOD,CAAY;AACrC,cAAM0C,IAAW,IAAI,IAAItB,EAAM,QAAQ,OAAO,aAAa;AAC3D,QAAAsB,EAAS,aAAa,IAAI,cAAczC,CAAe,GACvDmB,EAAM,MAAMsB,EAAS,SAAA;AAAA,MACvB;AACA,MAAAtB,EAAM,MAAM,UAAU,SACtBA,EAAM,MAAM,gBAAgBlB,IAAa,SAAS,QAC7CA,MACCJ,MAAoB,UAAWzC,EAAa,aAAayC,CAAe,GAC5EA,IAAkBzC,EAAa,WAAW,MAAMwE,EAAU,EAAI,GAAG5C,CAAsB;AAAA,IAE3F;AACA,IAAIuD,EAAQ,WAAW,kBAAkBD,KAAaD,MACpDT,EAAU,CAAC3B,CAAU;AAAA,EAEzB,GAEMyC,KAAetF,EAAa,YAAYkE,GAAevC,EAAgB,GACvE4D,IAAU,MAAY;AAC1B,IAAAZ,IAAsB3C,GAAiB,GACvCwD,EAAA;AAAA,EACF,GACMA,IAAU,MAAY;AAC1B,IAAIlD,MACJA,IAAY,IACRC,MAAgB,UAAWvC,EAAa,aAAauC,CAAW,GAChEC,MAAe,UAAWxC,EAAa,aAAawC,CAAU,GAC9DC,MAAoB,UAAWzC,EAAa,aAAayC,CAAe,GAC5EzC,EAAa,cAAcsF,EAAY,GACvCtF,EAAa,oBAAoB,WAAW+E,CAAS,GACrD/E,EAAa,oBAAoB,UAAUoE,CAAqB,GAChEpE,EAAa,oBAAoB,UAAUqE,CAAkB,GAC7DrE,EAAa,oBAAoB,YAAYoE,CAAqB,GAClEpE,EAAa,oBAAoB,cAAcoE,CAAqB,GACpEX,EAAM,oBAAoB,QAAQa,CAAW,GAC7CZ,EAAS,oBAAoB,QAAQY,CAAW,GAChDP,EAAM,oBAAoB,QAAQO,CAAW,GAC7CvC,EAAQ,QAAQ,oBAAoB,SAASwD,CAAO,GACpDvC,EAAO,OAAA;AAAA,EACT;AAEA,MAAI;AAOF,QANAhD,EAAa,iBAAiB,WAAW+E,CAAS,GAClD/E,EAAa,iBAAiB,UAAUoE,GAAuB,EAAE,SAAS,IAAM,GAChFpE,EAAa,iBAAiB,UAAUqE,CAAkB,GAC1DrE,EAAa,iBAAiB,YAAYoE,CAAqB,GAC/DpE,EAAa,iBAAiB,cAAcoE,CAAqB,GACjErC,EAAQ,QAAQ,iBAAiB,SAASwD,GAAS,EAAE,MAAM,IAAM,GAC7DxD,EAAQ,QAAQ,QAAS,OAAMC,EAAA;AACnC,IAAAD,EAAQ,OAAO,YAAYiB,CAAM,GACjCiB,EAAA,GACA,MAAMW;AAAA,EACR,SAASa,GAAO;AACd,UAAAD,EAAA,GACMC;AAAA,EACR;AAEA,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,SAASD;AAAA,EAAA;AAEb;AC3VA,MAAME,wBAAa,QAAA;AAGZ,SAASC,GACd7D,GACAC,GAC6B;AAC7B,MAAI6D,IAAWF,EAAO,IAAI5D,CAAM;AAChC,EAAK8D,MACHA,wBAAe,QAAA,GACfF,EAAO,IAAI5D,GAAQ8D,CAAQ;AAE7B,QAAMC,IAAWD,EAAS,IAAI7D,EAAQ,MAAM;AAC5C,MAAI8D,EAAU,QAAOA;AAErB,QAAMC,IAAuCjE,GAAMC,GAAQC,CAAO,EAC/D,KAAK,CAACgE,MAAQ;AACb,QAAIzD,IAAY;AAChB,UAAM0D,IAA6B;AAAA,MACjC,YAAY;AAAA,MACZ,UAAgB;AACd,QAAI1D,MACJA,IAAY,IACZP,EAAQ,QAAQ,oBAAoB,SAASiE,EAAO,OAAO,GACvDJ,EAAS,IAAI7D,EAAQ,MAAM,MAAM+D,KAASF,EAAS,OAAO7D,EAAQ,MAAM,GAC5EgE,EAAI,QAAA;AAAA,MACN;AAAA,IAAA;AAEF,WAAAhE,EAAQ,QAAQ,iBAAiB,SAASiE,EAAO,SAAS,EAAE,MAAM,IAAM,GACpEjE,EAAQ,QAAQ,WAASiE,EAAO,QAAA,GAC7BA;AAAA,EACT,CAAC,EACA,MAAM,CAACP,MAAmB;AACzB,UAAIG,EAAS,IAAI7D,EAAQ,MAAM,MAAM+D,KAASF,EAAS,OAAO7D,EAAQ,MAAM,GACtE0D;AAAA,EACR,CAAC;AACH,SAAAG,EAAS,IAAI7D,EAAQ,QAAQ+D,CAAO,GAC7BA;AACT;"}
|
|
1
|
+
{"version":3,"file":"danmaku.js","sources":["../src/danmaku/anchor.ts","../src/danmaku/mount.ts","../src/danmaku/index.ts"],"sourcesContent":["export interface DanmakuPageAnchor {\n /** Stable page-and-position key sent to the hosted danmaku runtime. */\n anchorKey: string;\n /** Human-readable 10% scroll bucket, useful for diagnostics. */\n scrollBucket: string;\n}\n\n/**\n * Build a stable page-position anchor without exposing the page URL.\n *\n * Canonical URLs and SPA hash routes participate in the local hash. Only the\n * resulting opaque key leaves the host page.\n */\nexport function readDanmakuPageAnchor(\n windowObject: Window = window,\n documentObject: Document = document,\n): DanmakuPageAnchor {\n const pageUrl = canonicalPageUrl(windowObject, documentObject);\n const bucket = scrollBucket(windowObject, documentObject);\n return {\n anchorKey: `page:${hashString(pageUrl)}:scroll:${bucket}`,\n scrollBucket: bucket,\n };\n}\n\nfunction canonicalPageUrl(windowObject: Window, documentObject: Document): string {\n const canonical = documentObject.querySelector<HTMLLinkElement>('link[rel=\"canonical\"][href]');\n const rawUrl = canonical?.href || windowObject.location.href;\n try {\n const url = new URL(rawUrl, windowObject.location.href);\n url.username = '';\n url.password = '';\n if (canonical && !url.hash && windowObject.location.hash) {\n url.hash = windowObject.location.hash;\n }\n return url.toString();\n } catch {\n return windowObject.location.href;\n }\n}\n\nfunction scrollBucket(windowObject: Window, documentObject: Document): string {\n const root = documentObject.documentElement;\n const body = documentObject.body;\n const scrollTop =\n windowObject.scrollY || windowObject.pageYOffset || root.scrollTop || body?.scrollTop || 0;\n const scrollHeight = Math.max(\n root.scrollHeight,\n root.offsetHeight,\n root.clientHeight,\n body?.scrollHeight ?? 0,\n body?.offsetHeight ?? 0,\n );\n const maxScroll = Math.max(0, scrollHeight - windowObject.innerHeight);\n if (maxScroll <= 1) return '0-100';\n\n const percent = Math.max(0, Math.min(99, (scrollTop / maxScroll) * 100));\n const start = Math.min(90, Math.floor(percent / 10) * 10);\n return `${start}-${start + 10}`;\n}\n\n/** Deterministic 64-bit-style hash encoded as at most 16 base36 characters. */\nfunction hashString(value: string): string {\n let high = 0xdeadbeef ^ value.length;\n let low = 0x41c6ce57 ^ value.length;\n for (let index = 0; index < value.length; index += 1) {\n const character = value.charCodeAt(index);\n high = Math.imul(high ^ character, 2654435761);\n low = Math.imul(low ^ character, 1597334677);\n }\n high = Math.imul(high ^ (high >>> 16), 2246822507);\n high ^= Math.imul(low ^ (low >>> 13), 3266489909);\n low = Math.imul(low ^ (low >>> 16), 2246822507);\n low ^= Math.imul(high ^ (high >>> 13), 3266489909);\n return (\n (low >>> 0).toString(36).padStart(7, '0') + (high >>> 0).toString(36).padStart(7, '0')\n ).slice(0, 16);\n}\n","import type { ViceMeClient } from '../core/client.ts';\nimport { BUILD_WIDGET_ORIGINS } from '../core/build-endpoints.ts';\nimport { clientDestroyed, ViceMeError } from '../core/errors.ts';\nimport type { CapabilityMountHandle, CapabilityMountOptions } from '../capability-mount.ts';\nimport { SDK_VERSION } from '../version.ts';\nimport {\n hasIntegratedTip,\n openIntegratedTip,\n registerIntegratedDanmaku,\n} from '../engagement/integration.ts';\nimport { readDanmakuPageAnchor, type DanmakuPageAnchor } from './anchor.ts';\n\ntype DanmakuFrameMode = 'stage' | 'controls' | 'modal';\n\ninterface DanmakuBridgeMessage {\n source?: unknown;\n action?: unknown;\n frameToken?: unknown;\n mode?: unknown;\n width?: unknown;\n height?: unknown;\n workKey?: unknown;\n}\n\nconst CONTROLS_MIN_SIZE = 32;\nconst CONTROLS_BOTTOM_GAP = 12;\nconst CONTROLS_BAR_HEIGHT = 56;\nconst CONTROLS_MAX_HEIGHT = 360;\nconst CONTROLS_LEGACY_MORE_HEIGHT = 328;\nconst CONTROLS_MORE_HEIGHT = 340;\nconst ANCHOR_DEBOUNCE_MS = 120;\nconst LOCATION_POLL_MS = 1_000;\nexport const FRAME_READY_TIMEOUT_MS = 8_000;\nconst ENGAGEMENT_REQUEST_KEYS = ['source', 'action', 'workKey'];\n\nfunction isStrictRecord(value: unknown, keys: string[]): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const actualKeys = Object.keys(value);\n return actualKeys.length === keys.length && keys.every((key) => actualKeys.includes(key));\n}\n\nexport async function mount(\n client: ViceMeClient,\n options: CapabilityMountOptions,\n): Promise<CapabilityMountHandle> {\n if (options.signal?.aborted) throw clientDestroyed();\n await client.ready();\n if (options.signal?.aborted) throw clientDestroyed();\n if (!client.hasCapability('danmaku')) {\n throw new ViceMeError({\n code: 'CAPABILITY_DISABLED',\n message: 'Danmaku is not available in this SDK build.',\n retryable: false,\n capability: 'danmaku',\n });\n }\n\n const documentObject = options.target.ownerDocument;\n const windowObject = documentObject.defaultView;\n if (!windowObject) {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Danmaku requires a browser document.',\n retryable: false,\n capability: 'danmaku',\n });\n }\n\n const widgetOrigin = BUILD_WIDGET_ORIGINS[client.region];\n let currentAnchor = readDanmakuPageAnchor(windowObject, documentObject);\n const locale =\n documentObject.documentElement.lang.trim() || windowObject.navigator.language || 'en';\n let destroyed = false;\n let anchorTimer: number | undefined;\n let readyTimer: number | undefined;\n let modalReadyTimer: number | undefined;\n let initialFramesReady = false;\n let modalAttempt = 0;\n let modalFrameToken = '';\n let modalReady = false;\n let unregisterIntegration: (() => void) | undefined;\n const loadedFrames = new WeakSet<HTMLIFrameElement>();\n const readyModes = new Set<DanmakuFrameMode>();\n\n const portal = documentObject.createElement('div');\n portal.dataset.vicemeDanmaku = 'mounted';\n portal.style.all = 'initial';\n portal.style.position = 'fixed';\n portal.style.inset = '0';\n portal.style.width = '100%';\n portal.style.height = '100%';\n portal.style.pointerEvents = 'none';\n portal.style.zIndex = '2147483000';\n portal.style.contain = 'layout style size';\n\n const shadow = portal.attachShadow({ mode: 'open' });\n const root = documentObject.createElement('div');\n root.style.boxSizing = 'border-box';\n root.style.position = 'fixed';\n root.style.inset = '0';\n root.style.width = '100%';\n root.style.height = '100%';\n root.style.pointerEvents = 'none';\n shadow.append(root);\n\n const frameUrl = (mode: DanmakuFrameMode): URL => {\n const url = new URL('/embed/danmaku', widgetOrigin);\n url.searchParams.set('mode', mode);\n url.searchParams.set('workKey', client.workKey);\n url.searchParams.set('theme', options.theme);\n url.searchParams.set('locale', locale);\n url.searchParams.set('sdk', SDK_VERSION);\n url.searchParams.set('anchorKey', currentAnchor.anchorKey);\n return url;\n };\n\n const createFrame = (\n mode: DanmakuFrameMode,\n title: string,\n source: string,\n ): HTMLIFrameElement => {\n const frame = documentObject.createElement('iframe');\n frame.title = title;\n frame.src = source;\n frame.loading = 'eager';\n frame.referrerPolicy = 'no-referrer';\n frame.setAttribute('allowtransparency', 'true');\n frame.setAttribute(\n 'sandbox',\n 'allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts',\n );\n frame.dataset.mode = mode;\n frame.style.boxSizing = 'border-box';\n frame.style.colorScheme = 'normal';\n frame.style.position = 'fixed';\n frame.style.margin = '0';\n frame.style.border = '0';\n frame.style.background = 'transparent';\n frame.style.width = '100%';\n frame.style.zIndex = '2147483000';\n return frame;\n };\n\n const stage = createFrame('stage', 'ViceMe Danmaku', frameUrl('stage').toString());\n stage.setAttribute('aria-hidden', 'true');\n stage.style.inset = '0';\n stage.style.height = '100%';\n stage.style.pointerEvents = 'none';\n\n const controls = createFrame(\n 'controls',\n 'ViceMe Danmaku controls',\n frameUrl('controls').toString(),\n );\n controls.style.left = '50%';\n controls.style.bottom = 'env(safe-area-inset-bottom, 0px)';\n controls.style.transform = 'translateX(-50%)';\n let controlsCompact = false;\n let controlsRequestedHeight = CONTROLS_BAR_HEIGHT;\n const applyControlsSize = (): void => {\n const viewportWidth = Math.max(\n CONTROLS_MIN_SIZE,\n Math.floor(windowObject.innerWidth || CONTROLS_MIN_SIZE),\n );\n controls.style.width = `${controlsCompact ? CONTROLS_MIN_SIZE : viewportWidth}px`;\n controls.style.height = `${controlsRequestedHeight}px`;\n };\n applyControlsSize();\n controls.style.pointerEvents = 'none';\n\n const modal = createFrame('modal', 'ViceMe Danmaku dialog', 'about:blank');\n modal.dataset.src = frameUrl('modal').toString();\n modal.style.inset = '0';\n modal.style.height = '100%';\n modal.style.display = 'none';\n modal.style.pointerEvents = 'none';\n\n root.append(stage, controls, modal);\n\n const postAnchor = (frame: HTMLIFrameElement): void => {\n if (!loadedFrames.has(frame)) return;\n frame.contentWindow?.postMessage(\n {\n source: 'viceme-danmaku',\n action: 'anchor-change',\n anchorKey: currentAnchor.anchorKey,\n },\n widgetOrigin,\n );\n };\n const postAnchorToMountedFrames = (): void => {\n postAnchor(stage);\n postAnchor(controls);\n if (modal.getAttribute('src') !== 'about:blank') postAnchor(modal);\n };\n const postTipAvailability = (available: boolean): void => {\n controls.contentWindow?.postMessage(\n {\n source: 'viceme-engagement',\n action: 'tip-availability',\n available,\n workKey: client.workKey,\n },\n widgetOrigin,\n );\n };\n\n const refreshAnchor = (): DanmakuPageAnchor => {\n if (destroyed) return currentAnchor;\n const next = readDanmakuPageAnchor(windowObject, documentObject);\n if (next.anchorKey !== currentAnchor.anchorKey) {\n currentAnchor = next;\n postAnchorToMountedFrames();\n }\n return currentAnchor;\n };\n const scheduleAnchorRefresh = (): void => {\n if (anchorTimer !== undefined) windowObject.clearTimeout(anchorTimer);\n anchorTimer = windowObject.setTimeout(refreshAnchor, ANCHOR_DEBOUNCE_MS);\n };\n const handleWindowResize = (): void => {\n applyControlsSize();\n scheduleAnchorRefresh();\n };\n\n const frameLoaded = (event: Event): void => {\n const frame = event.currentTarget as HTMLIFrameElement;\n if (frame.getAttribute('src') === 'about:blank') return;\n loadedFrames.add(frame);\n postAnchor(frame);\n };\n stage.addEventListener('load', frameLoaded);\n controls.addEventListener('load', frameLoaded);\n modal.addEventListener('load', frameLoaded);\n\n const hideModal = (resetFrame = false): void => {\n if (modalReadyTimer !== undefined) {\n windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = undefined;\n }\n modal.style.display = 'none';\n modal.style.pointerEvents = 'none';\n if (resetFrame) {\n modalFrameToken = '';\n modalReady = false;\n loadedFrames.delete(modal);\n modal.src = 'about:blank';\n }\n };\n\n let resolveInitialFrames: (() => void) | undefined;\n let rejectInitialFrames: ((error: ViceMeError) => void) | undefined;\n const initialFrameReadiness = new Promise<void>((resolve, reject) => {\n resolveInitialFrames = resolve;\n rejectInitialFrames = reject;\n readyTimer = windowObject.setTimeout(() => {\n reject(\n new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Hosted danmaku frames did not become ready in time.',\n retryable: true,\n capability: 'danmaku',\n }),\n );\n }, FRAME_READY_TIMEOUT_MS);\n });\n\n const onMessage = (event: MessageEvent): void => {\n if (event.origin !== widgetOrigin) return;\n const fromStage = event.source === stage.contentWindow;\n const fromControls = event.source === controls.contentWindow;\n const fromModal = event.source === modal.contentWindow;\n if (!fromStage && !fromControls && !fromModal) return;\n\n const message = event.data as DanmakuBridgeMessage | null;\n if (\n fromControls &&\n isStrictRecord(message, ENGAGEMENT_REQUEST_KEYS) &&\n message.source === 'viceme-engagement' &&\n message.workKey === client.workKey\n ) {\n if (message.action === 'request-tip-availability') {\n postTipAvailability(hasIntegratedTip(client, options.target));\n } else if (message.action === 'open-tip' && initialFramesReady) {\n openIntegratedTip(client, options.target);\n }\n return;\n }\n if (!message || message.source !== 'viceme-danmaku') return;\n\n const sourceMode: DanmakuFrameMode = fromModal ? 'modal' : fromStage ? 'stage' : 'controls';\n if (message.action === 'frame-ready') {\n if (message.mode !== sourceMode) return;\n if (sourceMode === 'modal') {\n if (message.frameToken !== modalFrameToken) return;\n modalReady = true;\n if (modalReadyTimer !== undefined) {\n windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = undefined;\n }\n if (modal.style.display === 'block') modal.style.pointerEvents = 'auto';\n return;\n }\n readyModes.add(sourceMode);\n if (readyModes.has('stage') && readyModes.has('controls') && !initialFramesReady) {\n initialFramesReady = true;\n if (readyTimer !== undefined) {\n windowObject.clearTimeout(readyTimer);\n readyTimer = undefined;\n }\n controls.style.pointerEvents = 'auto';\n resolveInitialFrames?.();\n }\n return;\n }\n if (message.action === 'resize-controls' && fromControls) {\n if (\n typeof message.width !== 'number' ||\n !Number.isSafeInteger(message.width) ||\n message.width < CONTROLS_MIN_SIZE ||\n typeof message.height !== 'number' ||\n !Number.isSafeInteger(message.height) ||\n message.height < CONTROLS_MIN_SIZE ||\n message.height > CONTROLS_MAX_HEIGHT\n ) {\n return;\n }\n const compact =\n message.width === CONTROLS_MIN_SIZE &&\n message.height <= CONTROLS_MIN_SIZE + CONTROLS_BOTTOM_GAP;\n if (!compact && message.height < CONTROLS_BAR_HEIGHT) return;\n controlsCompact = compact;\n controlsRequestedHeight = compact\n ? CONTROLS_MIN_SIZE + CONTROLS_BOTTOM_GAP\n : message.height === CONTROLS_LEGACY_MORE_HEIGHT\n ? CONTROLS_MORE_HEIGHT\n : message.height;\n applyControlsSize();\n }\n if (message.action === 'request-anchor') {\n postAnchor(fromModal ? modal : fromStage ? stage : controls);\n }\n if (message.action === 'open-modal' && fromControls) {\n if (!initialFramesReady) return;\n if (modal.getAttribute('src') === 'about:blank') {\n modalAttempt += 1;\n modalFrameToken = String(modalAttempt);\n const modalUrl = new URL(modal.dataset.src ?? 'about:blank');\n modalUrl.searchParams.set('frameToken', modalFrameToken);\n modal.src = modalUrl.toString();\n }\n modal.style.display = 'block';\n modal.style.pointerEvents = modalReady ? 'auto' : 'none';\n if (!modalReady) {\n if (modalReadyTimer !== undefined) windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = windowObject.setTimeout(() => hideModal(true), FRAME_READY_TIMEOUT_MS);\n }\n }\n if (message.action === 'close-modal' && (fromModal || fromControls)) {\n hideModal(!modalReady);\n }\n };\n\n const locationPoll = windowObject.setInterval(refreshAnchor, LOCATION_POLL_MS);\n const onAbort = (): void => {\n rejectInitialFrames?.(clientDestroyed());\n cleanup();\n };\n const cleanup = (): void => {\n if (destroyed) return;\n destroyed = true;\n if (anchorTimer !== undefined) windowObject.clearTimeout(anchorTimer);\n if (readyTimer !== undefined) windowObject.clearTimeout(readyTimer);\n if (modalReadyTimer !== undefined) windowObject.clearTimeout(modalReadyTimer);\n windowObject.clearInterval(locationPoll);\n windowObject.removeEventListener('message', onMessage);\n windowObject.removeEventListener('scroll', scheduleAnchorRefresh);\n windowObject.removeEventListener('resize', handleWindowResize);\n windowObject.removeEventListener('popstate', scheduleAnchorRefresh);\n windowObject.removeEventListener('hashchange', scheduleAnchorRefresh);\n stage.removeEventListener('load', frameLoaded);\n controls.removeEventListener('load', frameLoaded);\n modal.removeEventListener('load', frameLoaded);\n unregisterIntegration?.();\n unregisterIntegration = undefined;\n options.signal?.removeEventListener('abort', onAbort);\n portal.remove();\n };\n\n try {\n windowObject.addEventListener('message', onMessage);\n windowObject.addEventListener('scroll', scheduleAnchorRefresh, { passive: true });\n windowObject.addEventListener('resize', handleWindowResize);\n windowObject.addEventListener('popstate', scheduleAnchorRefresh);\n windowObject.addEventListener('hashchange', scheduleAnchorRefresh);\n options.signal?.addEventListener('abort', onAbort, { once: true });\n if (options.signal?.aborted) throw clientDestroyed();\n options.target.appendChild(portal);\n postAnchorToMountedFrames();\n await initialFrameReadiness;\n if (destroyed || options.signal?.aborted) throw clientDestroyed();\n unregisterIntegration = registerIntegratedDanmaku(client, options.target, {\n focus: () => controls.focus(),\n setTipAvailable: postTipAvailability,\n });\n } catch (error) {\n cleanup();\n throw error;\n }\n\n return {\n capability: 'danmaku',\n destroy: cleanup,\n };\n}\n","import type { ViceMeClient } from '../core/client.ts';\nimport { mount } from './mount.ts';\n\nexport interface DanmakuMountOptions {\n target: Element;\n theme: 'light' | 'dark' | 'auto';\n signal?: AbortSignal;\n}\n\nexport interface DanmakuMountHandle {\n readonly capability: 'danmaku';\n destroy(): void;\n}\n\nconst mounts = new WeakMap<ViceMeClient, WeakMap<Element, Promise<DanmakuMountHandle>>>();\n\n/** Explicit ESM/npm entry point; the CDN loader calls the same mount function. */\nexport function mountDanmaku(\n client: ViceMeClient,\n options: DanmakuMountOptions,\n): Promise<DanmakuMountHandle> {\n let byTarget = mounts.get(client);\n if (!byTarget) {\n byTarget = new WeakMap();\n mounts.set(client, byTarget);\n }\n const existing = byTarget.get(options.target);\n if (existing) return existing;\n\n const pending: Promise<DanmakuMountHandle> = mount(client, options)\n .then((raw) => {\n let destroyed = false;\n const handle: DanmakuMountHandle = {\n capability: 'danmaku' as const,\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n options.signal?.removeEventListener('abort', handle.destroy);\n if (byTarget.get(options.target) === pending) byTarget.delete(options.target);\n raw.destroy();\n },\n };\n options.signal?.addEventListener('abort', handle.destroy, { once: true });\n if (options.signal?.aborted) handle.destroy();\n return handle;\n })\n .catch((error: unknown) => {\n if (byTarget.get(options.target) === pending) byTarget.delete(options.target);\n throw error;\n });\n byTarget.set(options.target, pending);\n return pending;\n}\n"],"names":["readDanmakuPageAnchor","windowObject","documentObject","pageUrl","canonicalPageUrl","bucket","scrollBucket","hashString","canonical","rawUrl","url","root","body","scrollTop","scrollHeight","maxScroll","percent","start","value","high","low","index","character","CONTROLS_MIN_SIZE","CONTROLS_BOTTOM_GAP","CONTROLS_BAR_HEIGHT","CONTROLS_MAX_HEIGHT","CONTROLS_LEGACY_MORE_HEIGHT","CONTROLS_MORE_HEIGHT","ANCHOR_DEBOUNCE_MS","LOCATION_POLL_MS","FRAME_READY_TIMEOUT_MS","ENGAGEMENT_REQUEST_KEYS","isStrictRecord","keys","actualKeys","key","mount","client","options","clientDestroyed","ViceMeError","widgetOrigin","BUILD_WIDGET_ORIGINS","currentAnchor","locale","destroyed","anchorTimer","readyTimer","modalReadyTimer","initialFramesReady","modalAttempt","modalFrameToken","modalReady","unregisterIntegration","loadedFrames","readyModes","portal","shadow","frameUrl","mode","SDK_VERSION","createFrame","title","source","frame","stage","controls","controlsCompact","controlsRequestedHeight","applyControlsSize","viewportWidth","modal","postAnchor","postAnchorToMountedFrames","postTipAvailability","available","refreshAnchor","next","scheduleAnchorRefresh","handleWindowResize","frameLoaded","event","hideModal","resetFrame","resolveInitialFrames","rejectInitialFrames","initialFrameReadiness","resolve","reject","onMessage","fromStage","fromControls","fromModal","message","hasIntegratedTip","openIntegratedTip","sourceMode","compact","modalUrl","locationPoll","onAbort","cleanup","registerIntegratedDanmaku","error","mounts","mountDanmaku","byTarget","existing","pending","raw","handle"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ViceMeClient } from '../core/client.ts';
|
|
2
|
+
interface DanmakuIntegration {
|
|
3
|
+
focus(): void;
|
|
4
|
+
setTipAvailable(available: boolean): void;
|
|
5
|
+
}
|
|
6
|
+
interface TipIntegration {
|
|
7
|
+
open(): void;
|
|
8
|
+
}
|
|
9
|
+
export declare function registerIntegratedDanmaku(client: ViceMeClient, target: Element, danmaku: DanmakuIntegration): () => void;
|
|
10
|
+
export declare function registerIntegratedTip(client: ViceMeClient, target: Element, tip: TipIntegration): () => void;
|
|
11
|
+
export declare function hasIntegratedTip(client: ViceMeClient, target: Element): boolean;
|
|
12
|
+
export declare function openIntegratedTip(client: ViceMeClient, target: Element): void;
|
|
13
|
+
export declare function focusIntegratedDanmaku(client: ViceMeClient, target: Element): void;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../src/engagement/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,UAAU,kBAAkB;IAC1B,KAAK,IAAI,IAAI,CAAC;IACd,eAAe,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3C;AAED,UAAU,cAAc;IACtB,IAAI,IAAI,IAAI,CAAC;CACd;AA2BD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,kBAAkB,GAC1B,MAAM,IAAI,CAUZ;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,cAAc,GAClB,MAAM,IAAI,CAWZ;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAE/E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAE7E;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAElF"}
|