// ==UserScript==
// @name Miss Player | 去广告 | 单手播放器
// @description 定制播放器-竖屏单手操作|去广告|自动展开详情|自动高画质|重定向支持|自动登录| missav | jable | pornhub |
// @version 1.0.0
// @author Chris_C
// @match *://*.missav.ws/*
// @match *://*.missav.ai/*
// @match *://*/*
// @grant none
// @icon https://missav.ws/img/favicon.ico
// @license MIT
// @namespace https://github.com/x/miss-player
// @noframes
// @run-at document-start
// ==/UserScript==
/*! For license information please see miss_player.user.js.LICENSE.txt */
(() => {
"use strict";
var t = {
56: (t, e, n) => {
t.exports = function(t) {
var e = n.nc;
e && t.setAttribute("nonce", e)
}
},
72: t => {
var e = [];
function n(t) {
for (var n = -1, r = 0; r < e.length; r++)
if (e[r].identifier === t) {
n = r;
break
} return n
}
function r(t, r) {
for (var i = {}, a = [], s = 0; s < t.length; s++) {
var l = t[s],
c = r.base ? l[0] + r.base : l[0],
u = i[c] || 0,
d = "".concat(c, " ").concat(u);
i[c] = u + 1;
var h = n(d),
p = {
css: l[1],
media: l[2],
sourceMap: l[3],
supports: l[4],
layer: l[5]
};
if (-1 !== h) e[h].references++, e[h].updater(p);
else {
var f = o(p, r);
r.byIndex = s, e.splice(s, 0, {
identifier: d,
updater: f,
references: 1
})
}
a.push(d)
}
return a
}
function o(t, e) {
var n = e.domAPI(e);
return n.update(t),
function(e) {
if (e) {
if (e.css === t.css && e.media === t.media && e.sourceMap === t.sourceMap && e.supports === t.supports && e.layer === t.layer) return;
n.update(t = e)
} else n.remove()
}
}
t.exports = function(t, o) {
var i = r(t = t || [], o = o || {});
return function(t) {
t = t || [];
for (var a = 0; a < i.length; a++) {
var s = n(i[a]);
e[s].references--
}
for (var l = r(t, o), c = 0; c < i.length; c++) {
var u = n(i[c]);
0 === e[u].references && (e[u].updater(), e.splice(u, 1))
}
i = l
}
}
},
113: t => {
t.exports = function(t, e) {
if (e.styleSheet) e.styleSheet.cssText = t;
else {
for (; e.firstChild;) e.removeChild(e.firstChild);
e.appendChild(document.createTextNode(t))
}
}
},
314: t => {
t.exports = function(t) {
var e = [];
return e.toString = function() {
return this.map((function(e) {
var n = "",
r = void 0 !== e[5];
return e[4] && (n += "@supports (".concat(e[4], ") {")), e[2] && (n += "@media ".concat(e[2], " {")), r && (n += "@layer".concat(e[5].length > 0 ? " ".concat(e[5]) : "", " {")), n += t(e), r && (n += "}"), e[2] && (n += "}"), e[4] && (n += "}"), n
})).join("")
}, e.i = function(t, n, r, o, i) {
"string" == typeof t && (t = [
[null, t, void 0]
]);
var a = {};
if (r)
for (var s = 0; s < this.length; s++) {
var l = this[s][0];
null != l && (a[l] = !0)
}
for (var c = 0; c < t.length; c++) {
var u = [].concat(t[c]);
r && a[u[0]] || (void 0 !== i && (void 0 === u[5] || (u[1] = "@layer".concat(u[5].length > 0 ? " ".concat(u[5]) : "", " {").concat(u[1], "}")), u[5] = i), n && (u[2] ? (u[1] = "@media ".concat(u[2], " {").concat(u[1], "}"), u[2] = n) : u[2] = n), o && (u[4] ? (u[1] = "@supports (".concat(u[4], ") {").concat(u[1], "}"), u[4] = o) : u[4] = "".concat(o)), e.push(u))
}
}, e
}
},
540: t => {
t.exports = function(t) {
var e = document.createElement("style");
return t.setAttributes(e, t.attributes), t.insert(e, t.options), e
}
},
601: t => {
t.exports = function(t) {
return t[1]
}
},
610: (t, e, n) => {
n.r(e), n.d(e, {
default: () => g
});
var r = n(72),
o = n.n(r),
i = n(825),
a = n.n(i),
s = n(659),
l = n.n(s),
c = n(56),
u = n.n(c),
d = n(540),
h = n.n(d),
p = n(113),
f = n.n(p),
m = n(935),
v = {};
v.styleTagTransform = f(), v.setAttributes = u(), v.insert = l().bind(null, "head"), v.domAPI = a(), v.insertStyleElement = h(), o()(m.A, v);
const g = m.A && m.A.locals ? m.A.locals : void 0
},
659: t => {
var e = {};
t.exports = function(t, n) {
var r = function(t) {
if (void 0 === e[t]) {
var n = document.querySelector(t);
if (window.HTMLIFrameElement && n instanceof window.HTMLIFrameElement) try {
n = n.contentDocument.head
} catch (t) {
n = null
}
e[t] = n
}
return e[t]
}(t);
if (!r) throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
r.appendChild(n)
}
},
825: t => {
t.exports = function(t) {
if ("undefined" == typeof document) return {
update: function() {},
remove: function() {}
};
var e = t.insertStyleElement(t);
return {
update: function(n) {
! function(t, e, n) {
var r = "";
n.supports && (r += "@supports (".concat(n.supports, ") {")), n.media && (r += "@media ".concat(n.media, " {"));
var o = void 0 !== n.layer;
o && (r += "@layer".concat(n.layer.length > 0 ? " ".concat(n.layer) : "", " {")), r += n.css, o && (r += "}"), n.media && (r += "}"), n.supports && (r += "}");
var i = n.sourceMap;
i && "undefined" != typeof btoa && (r += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(i)))), " */")), e.styleTagTransform(r, t, e.options)
}(e, t, n)
},
remove: function() {
! function(t) {
if (null === t.parentNode) return !1;
t.parentNode.removeChild(t)
}(e)
}
}
}
},
935: (t, e, n) => {
n.d(e, {
A: () => s
});
var r = n(601),
o = n.n(r),
i = n(314),
a = n.n(i)()(o());
a.push([t.id, '/* =========== 基础变量定义 =========== */\n:root {\n /* 颜色系统 - 符合Apple Dark Mode设计规范 */\n --shadcn-background: 0 0% 0%; /* 纯黑色背景 */\n --shadcn-foreground: 0 0% 100%; /* 纯白色前景 */\n --shadcn-card: 0 0% 10%; /* 深灰色卡片背景 */\n --shadcn-card-foreground: 0 0% 95%; /* 淡灰白色卡片前景 */\n --shadcn-popover: 0 0% 10%; /* 深灰色弹出层背景 */\n --shadcn-popover-foreground: 0 0% 95%; /* 淡灰白色弹出层前景 */\n --shadcn-primary: 210 10% 90%; /* 淡蓝灰色主色 */\n --shadcn-primary-foreground: 210 20% 10%; /* 深蓝灰色主色前景 */\n --shadcn-secondary: 0 0% 15%; /* 次要颜色为深灰色 */\n --shadcn-secondary-foreground: 0 0% 95%; /* 淡灰白色次要前景 */\n --shadcn-muted: 0 0% 30%; /* 柔和的深灰色 */\n --shadcn-muted-foreground: 0 0% 70%; /* 柔和的浅灰色前景 */\n --shadcn-accent: 212 40% 30%; /* 柔和的蓝灰色强调色 */\n --shadcn-accent-foreground: 0 0% 95%; /* 淡灰白色强调前景 */\n --shadcn-destructive: 0 50% 40%; /* 柔和的红色 */\n --shadcn-destructive-foreground: 0 0% 95%; /* 淡灰白色破坏性操作前景 */\n --shadcn-border: 0 0% 20%; /* 深灰色边框 */\n --shadcn-input: 0 0% 15%; /* 深灰色输入框 */\n --shadcn-ring: 212 70% 45%; /* 蓝色环 */\n \n /* 状态颜色 - 符合Apple设计规范的柔和色调 */\n --shadcn-green: 142 50% 45%; /* 柔和的绿色 */\n --shadcn-green-foreground: 0 0% 95%; /* 淡灰白色绿色前景 */\n --shadcn-blue: 211 70% 55%; /* 柔和的蓝色 */\n --shadcn-blue-foreground: 0 0% 95%; /* 淡灰白色蓝色前景 */\n --shadcn-red: 0 60% 50%; /* 柔和的红色 */\n --shadcn-red-foreground: 0 0% 95%; /* 淡灰白色红色前景 */\n --shadcn-orange: 25 80% 50%; /* 柔和的橙色 */\n --shadcn-orange-foreground: 0 0% 95%; /* 淡灰白色橙色前景 */\n --shadcn-purple: 262 60% 60%; /* 柔和的紫色 */\n --shadcn-purple-foreground: 0 0% 95%; /* 淡灰白色紫色前景 */\n \n /* 圆角 */\n --shadcn-radius: 0.5rem;\n --shadcn-radius-sm: 0.3rem;\n --shadcn-radius-lg: 0.8rem;\n \n /* 按钮尺寸 */\n --button-sm: 20px;\n --button-md: 32px;\n --button-lg: 40px;\n --button-xl: 48px;\n \n /* 常用动画 */\n --anim-quick: 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n --anim-smooth: 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n --anim-bounce: 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);\n \n /* 阴影 - Apple风格阴影更柔和 */\n --shadow-sm: 0 2px 5px rgba(0, 0, 0, 0.2);\n --shadow-md: 0 4px 10px rgba(0, 0, 0, 0.25);\n --shadow-lg: 0 8px 20px rgba(0, 0, 0, 0.3);\n \n /* 字体 */\n --font-sans: "SF Pro Display", "SF Pro", "Segoe UI", "Microsoft YaHei", "微软雅黑", "PingFang SC", "苹方", "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";\n}\n\n/* 全局字体设置 */\nhtml, body, button, input, select, textarea {\n font-family: var(--font-sans);\n}\n\n/* 确保所有元素都使用全局字体 */\n*, *::before, *::after {\n font-family: inherit;\n}\n\n.tm-video-overlay * {\n font-family: var(--font-sans);\n}\n\n/* =========== 通用组件样式 =========== */\n\n/* 浮动按钮 */\n.tm-floating-button {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: var(--button-xl);\n height: var(--button-xl);\n border-radius: calc(var(--button-xl) / 2);\n background-color: hsl(var(--shadcn-blue));\n color: hsl(var(--shadcn-blue-foreground));\n border: none;\n box-shadow: var(--shadow-md), 0 0 0 1px rgba(255, 255, 255, 0.1);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 9980;\n cursor: pointer;\n transition: all var(--anim-smooth);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n}\n\n.tm-floating-button:hover {\n transform: translateY(-3px) scale(1.05);\n box-shadow: var(--shadow-lg), 0 0 0 1px rgba(255, 255, 255, 0.15);\n background-color: hsl(var(--shadcn-purple));\n}\n\n.tm-floating-button:active {\n transform: scale(0.95);\n}\n\n/* =========== 视频播放器样式 =========== */\n\n/* 整体布局 */\n.tm-video-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 100%;\n background-color: rgba(0, 0, 20, 0.8); /* 更深的背景色 */\n z-index: 9990;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-start;\n backdrop-filter: blur(30px); /* 增加模糊效果,符合iOS风格 */\n -webkit-backdrop-filter: blur(30px);\n padding: 0; /* 移除默认padding */\n}\n\n/* 按钮容器 - 放置在视频容器顶部外面 */\n.tm-button-container {\n width: 100%;\n display: flex;\n justify-content: space-between;\n padding: 8px 10px;\n box-sizing: border-box;\n z-index: 9993;\n}\n\n.tm-video-container {\n position: relative;\n overflow: hidden;\n width: 100%;\n height: auto;\n max-height: 80vh;\n margin-top: 0;\n display: flex;\n align-items: flex-start;\n justify-content: center;\n background-color: hsl(var(--shadcn-card));\n border-radius: var(--shadcn-radius-lg);\n box-shadow: var(--shadow-lg);\n z-index: 9992;\n}\n\n.tm-video-wrapper {\n position: relative;\n overflow: hidden;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n will-change: transform;\n border-radius: var(--shadcn-radius) var(--shadcn-radius) 0 0;\n}\n\n/* 确保视频元素随容器高度变化 */\n.tm-video-wrapper video {\n width: auto !important; \n height: 100% !important; \n max-width: none !important; \n object-fit: contain !important; \n transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n touch-action: pan-y; \n cursor: grab; \n}\n\n/* 调整手柄 */\n.tm-handle-container {\n left: 0;\n right: 0;\n bottom: 10px;\n height: 30px;\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 9992;\n width: 100%;\n}\n\n.tm-resize-handle {\n position: absolute;\n height: 5px;\n width: 134px;\n max-width: 134px;\n background-color: hsla(var(--shadcn-foreground) / 0.6);\n border-radius: 2.5px;\n cursor: ns-resize;\n touch-action: none;\n opacity: 0.5;\n will-change: transform;\n transition: all var(--anim-quick);\n box-shadow: none;\n}\n\n.tm-resize-handle::after {\n content: \'\';\n position: absolute;\n left: -10px;\n right: -10px;\n top: -15px;\n bottom: -15px;\n background: transparent;\n}\n\n.tm-resize-handle:hover {\n opacity: 1;\n background-color: hsla(var(--shadcn-foreground) / 0.8);\n}\n\n/* 控制按钮基础样式 */\n.tm-control-button-base {\n color: hsl(var(--shadcn-secondary-foreground));\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all var(--anim-quick);\n backdrop-filter: blur(12px); /* 增加模糊效果 */\n -webkit-backdrop-filter: blur(12px);\n box-shadow: var(--shadow-sm);\n}\n\n/* 关闭按钮 */\n.tm-close-button {\n position: relative;\n width: var(--button-md);\n height: var(--button-md);\n border-radius: calc(var(--button-md) / 2);\n background-color: hsla(var(--shadcn-secondary) / 0.5); /* 更透明的背景 */\n color: hsl(var(--shadcn-secondary-foreground));\n border: 1px solid hsla(var(--shadcn-border) / 0.1); /* 减少边框强度 */\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all var(--anim-smooth);\n z-index: 9994;\n}\n\n.tm-close-button:hover {\n background-color: hsl(var(--shadcn-destructive));\n transform: scale(1.1);\n box-shadow: var(--shadow-md);\n}\n\n.tm-close-button:active {\n transform: scale(0.9);\n}\n\n/* 设置按钮 */\n.tm-settings-button {\n position: relative;\n width: var(--button-md);\n height: var(--button-md);\n border-radius: calc(var(--button-md) / 2);\n background-color: hsla(var(--shadcn-secondary) / 0.7);\n color: hsl(var(--shadcn-secondary-foreground));\n border: 1px solid hsla(var(--shadcn-border) / 0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 9993;\n cursor: pointer;\n transition: all var(--anim-quick);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n box-shadow: var(--shadow-sm);\n}\n\n.tm-settings-button:hover {\n background-color: hsla(var(--shadcn-accent) / 0.9);\n transform: scale(1.1) rotate(30deg);\n box-shadow: var(--shadow-md);\n}\n\n.tm-settings-button:active {\n transform: scale(0.9);\n}\n\n/* 设置面板 */\n.tm-settings-panel {\n position: absolute;\n top: calc(env(safe-area-inset-top, 8px) + 60px);\n right: 16px;\n background-color: hsla(var(--shadcn-card) / 0.7);\n backdrop-filter: blur(15px);\n -webkit-backdrop-filter: blur(15px);\n border-radius: var(--shadcn-radius);\n border: 1px solid hsla(var(--shadcn-border) / 0.1); /* 淡化边框 */\n padding: 12px;\n box-shadow: var(--shadow-md);\n z-index: 9996;\n min-width: 200px;\n transform: translateY(-10px);\n opacity: 0;\n pointer-events: none;\n transition: transform var(--anim-smooth), opacity var(--anim-smooth);\n}\n\n.tm-settings-panel.active {\n transform: translateY(0);\n opacity: 1;\n pointer-events: auto;\n}\n\n/* 设置选项 */\n.tm-settings-option {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px;\n border-radius: var(--shadcn-radius-sm);\n margin-bottom: 8px;\n transition: background-color var(--anim-quick);\n}\n\n.tm-settings-option:hover {\n background-color: hsla(var(--shadcn-muted) / 0.5); /* 半透明悬停效果 */\n}\n\n.tm-settings-option:last-child {\n margin-bottom: 0;\n}\n\n.tm-settings-label {\n font-family: var(--font-sans);\n font-size: 14px;\n color: hsl(var(--shadcn-foreground));\n}\n\n/* 切换开关 */\n.tm-toggle-switch {\n position: relative;\n display: inline-block;\n width: 40px;\n height: 24px;\n}\n\n.tm-toggle-switch input {\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.tm-toggle-slider {\n position: absolute;\n cursor: pointer;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: hsla(var(--shadcn-muted) / 0.7); /* 关闭状态背景 */\n border-radius: 12px;\n transition: var(--anim-quick);\n}\n\n.tm-toggle-slider:before {\n position: absolute;\n content: "";\n height: 20px;\n width: 20px;\n left: 2px;\n bottom: 2px;\n background-color: hsl(var(--shadcn-foreground));\n border-radius: 50%;\n transition: var(--anim-quick);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 细微阴影 */\n}\n\n.tm-toggle-slider.checked {\n background-color: hsl(var(--shadcn-blue)); /* 开启状态背景 */\n}\n\n.tm-toggle-slider.checked:before {\n transform: translateX(16px);\n}\n\n/* 播放速率滑块 */\n.tm-playback-rate-slider {\n display: flex;\n align-items: center;\n margin-left: 0;\n height: var(--button-md);\n width: 100%;\n background: hsl(var(--shadcn-card) / 0.85);\n border-radius: 8px;\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n position: relative;\n overflow: hidden;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n transition: box-shadow 0.3s ease, transform 0.2s ease;\n cursor: pointer;\n}\n\n.tm-playback-rate-slider:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n transform: translateY(-1px);\n}\n\n.tm-playback-rate-slider.dragging {\n box-shadow: var(--shadow-md);\n background: hsla(var(--shadcn-card) / 0.9);\n}\n\n.tm-slider-container {\n width: 100%;\n height: 100%;\n background: hsla(var(--shadcn-secondary) / 0.8);\n position: relative;\n overflow: hidden;\n display: flex;\n align-items: center;\n}\n\n.tm-slider-level {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: hsl(0 0% 50% / 1);\n width: 50%;\n transform-origin: left;\n transition: width 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);\n z-index: 1;\n}\n\n.tm-slider-text {\n display: flex;\n justify-content: space-between;\n width: 100%;\n padding: 0 12px;\n z-index: 2;\n position: relative;\n}\n\n.tm-speed-label {\n color: hsl(var(--shadcn-muted-foreground));\n font-size: 13px;\n font-weight: 500;\n transition: color 0.3s ease;\n}\n\n.tm-speed-value {\n color: hsl(var(--shadcn-foreground));\n font-size: 13px;\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n\n/* 速度标签和值 */\n.tm-speed-label {\n color: hsl(var(--shadcn-muted-foreground));\n font-size: 13px;\n font-weight: 400;\n transition: color var(--anim-quick);\n}\n\n.tm-playback-rate-slider:hover .tm-speed-label {\n color: hsl(var(--shadcn-foreground));\n}\n\n.tm-speed-value {\n color: hsl(var(--shadcn-foreground));\n font-size: 13px;\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n\n/* 速度值颜色状态 */\n.tm-speed-value.fast {\n color: hsl(var(--shadcn-orange));\n}\n\n.tm-speed-value.slow {\n color: hsl(var(--shadcn-blue));\n}\n\n.tm-speed-value.normal {\n color: hsl(var(--shadcn-foreground));\n}\n\n/* 进度条控制组件 */\n.tm-progress-controls {\n position: relative;\n width: 100%;\n bottom: 0;\n left: 0;\n right: 0;\n display: flex;\n flex-direction: column;\n z-index: 9991;\n border-radius: 0 0 var(--shadcn-radius-lg) var(--shadcn-radius-lg);\n font-family: var(--font-sans);\n transition: opacity var(--anim-smooth);\n}\n\n/* 进度条容器 */\n.tm-progress-bar-container {\n position: relative;\n height: 12px;\n display: flex;\n align-items: center;\n cursor: pointer;\n user-select: none; /* 防止文本选择 */\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n touch-action: none; /* 防止触摸设备上的默认行为 */\n}\n\n/* 进度条 */\n.tm-progress-bar {\n width: 100%;\n height: 8px;\n background-color: hsla(var(--shadcn-muted) / 0.5);\n border-radius: 8px;\n overflow: hidden;\n position: relative;\n transition: height 0.15s;\n}\n\n.tm-progress-bar:hover {\n height: 6px;\n}\n\n/* 添加进度条交互状态样式 */\n.tm-progress-bar-expanded {\n height: 16px !important;\n}\n\n.tm-progress-bar-normal {\n height: 8px !important;\n}\n\n/* 进度条拖动状态 */\n.tm-progress-bar.tm-dragging {\n height: 16px !important;\n background-color: hsla(var(--shadcn-muted-foreground) / 0.7);\n cursor: grabbing;\n}\n\n/* 容器在拖动时的样式 */\n.tm-progress-bar-container:has(.tm-dragging) {\n cursor: grabbing;\n}\n\n/* 进度指示器 */\n.tm-progress-indicator {\n height: 100%;\n width: 0%;\n background-color: hsla(var(--shadcn-muted) / 0.8);\n border-radius: 0;\n position: absolute;\n left: 0;\n top: 0;\n transition: width 0.1s linear;\n overflow: hidden;\n}\n\n/* 拖动时的进度指示器样式 */\n.tm-dragging .tm-progress-indicator {\n background-color: hsl(var(--shadcn-card-foreground));\n box-shadow: none;\n transition: none; /* 拖动时禁用过渡效果,使响应更即时 */\n}\n\n/* 确保进度条容器正确处理溢出 */\n.tm-progress-bar {\n overflow: hidden;\n}\n\n/* 进度条手柄 */\n.tm-progress-handle {\n width: 12px;\n height: 12px;\n background-color: hsl(var(--shadcn-blue));\n border: 2px solid hsl(var(--shadcn-card));\n border-radius: 50%;\n position: absolute;\n top: 50%;\n left: 0%;\n transform: translate(0, -50%);\n z-index: 2;\n opacity: 1;\n transition: opacity 0.15s, width 0.15s, height 0.15s, box-shadow 0.15s;\n box-shadow: 0 0 0 4px hsl(var(--shadcn-blue) / 0.2);\n cursor: grab;\n}\n\n.tm-progress-handle:hover,\n.tm-progress-handle.dragging {\n transform: translate(0, -50%) scale(1.1);\n box-shadow: 0 0 0 6px hsl(var(--shadcn-blue) / 0.3);\n}\n\n/* 循环标记 - Apple Design风格优化 */\n.tm-loop-marker {\n position: absolute;\n width: 4px;\n height: 100%; /* 与进度条等高 */\n top: 0; /* 位于进度条上方,不是突出来的 */\n transform: translateX(-50%);\n z-index: 3;\n transition: opacity 0.3s cubic-bezier(0.25, 0.1, 0.25, 1), \n transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275),\n box-shadow 0.2s cubic-bezier(0.25, 0.1, 0.25, 1);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n}\n\n/* 循环开始标记(A) */\n.tm-loop-start-marker {\n background-color: hsla(var(--shadcn-green) / 0.5);\n border-radius: 2px;\n box-shadow: 0 0 6px hsla(var(--shadcn-green) / 0.3);\n}\n\n/* 循环结束标记(B) */\n.tm-loop-end-marker {\n background-color: hsla(var(--shadcn-orange) / 0.5);\n border-radius: 2px;\n box-shadow: 0 0 6px hsla(var(--shadcn-orange) / 0.3);\n}\n\n/* 循环标记悬停效果 */\n.tm-loop-marker:hover {\n cursor: pointer;\n z-index: 4;\n}\n\n.tm-loop-start-marker:hover {\n background-color: hsla(var(--shadcn-green) / 0.7);\n box-shadow: 0 0 10px hsla(var(--shadcn-green) / 0.5);\n}\n\n.tm-loop-end-marker:hover {\n background-color: hsla(var(--shadcn-orange) / 0.7);\n box-shadow: 0 0 10px hsla(var(--shadcn-orange) / 0.5);\n}\n\n/* 循环激活时的标记样式 */\n.tm-loop-marker.active {\n opacity: 1;\n}\n\n.tm-loop-marker:not(.active) {\n opacity: 0.7;\n}\n\n/* 添加标记的文本标签 */\n.tm-loop-marker::before {\n content: attr(data-label);\n position: absolute;\n top: -24px;\n left: 50%;\n transform: translateX(-50%);\n background-color: hsla(var(--shadcn-card) / 0.7);\n color: hsl(var(--shadcn-card-foreground));\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n opacity: 0;\n transition: opacity 0.2s ease, transform 0.2s ease;\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n border: 1px solid hsla(var(--shadcn-border) / 0.1);\n white-space: nowrap;\n z-index: 5;\n}\n\n.tm-loop-start-marker::before {\n content: "循环起点";\n}\n\n.tm-loop-end-marker::before {\n content: "循环终点";\n}\n\n.tm-loop-marker:hover::before {\n opacity: 1;\n transform: translateX(-50%) translateY(-4px);\n}\n\n/* 时间容器状态样式 */\n.tm-start-time-container-hover {\n background-color: hsl(var(--shadcn-green) / 0.1);\n border-color: hsl(var(--shadcn-green) / 0.3);\n}\n\n.tm-start-time-container-default {\n background-color: hsl(var(--shadcn-secondary) / 0.5);\n border-color: hsl(var(--shadcn-border) / 0.1);\n}\n\n.tm-end-time-container-hover {\n background-color: hsl(var(--shadcn-orange) / 0.1);\n border-color: hsl(var(--shadcn-orange) / 0.3);\n}\n\n.tm-end-time-container-default {\n background-color: hsl(var(--shadcn-secondary) / 0.5);\n border-color: hsl(var(--shadcn-border) / 0.1);\n}\n\n/* 循环按钮状态 */\n.tm-loop-button-hover {\n background-color: hsl(var(--shadcn-accent) / 0.3);\n transform: translateY(-1px);\n}\n\n.tm-loop-button-active {\n background-color: hsl(var(--shadcn-muted) / 0.7);\n}\n\n.tm-loop-button-default {\n background-color: hsl(var(--shadcn-secondary) / 0.5);\n transform: translateY(0);\n}\n\n/* 暂停/播放速度指示器 */\n.tm-indicator-base {\n position: absolute;\n padding: 8px 16px;\n background-color: hsla(var(--shadcn-card) / 0.6); /* 更透明 */\n color: hsl(var(--shadcn-card-foreground));\n border-radius: var(--shadcn-radius);\n opacity: 0;\n backdrop-filter: blur(15px); /* 增强模糊效果 */\n -webkit-backdrop-filter: blur(15px);\n box-shadow: var(--shadow-md);\n border: 1px solid hsla(var(--shadcn-border) / 0.1); /* 淡化边框 */\n transform: translateY(20px);\n transition: opacity var(--anim-smooth), transform var(--anim-smooth);\n pointer-events: none;\n z-index: 9994;\n font-size: 15px;\n font-weight: 500;\n}\n\n.tm-indicator-base.visible {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n/* 暂停指示器 */\n.tm-pause-indicator {\n width: 80px;\n height: 80px;\n}\n\n/* 播放速度指示器 */\n.tm-playback-rate-indicator {\n top: 30%;\n border-radius: var(--shadcn-radius);\n padding: 10px 16px;\n font-size: 16px;\n font-weight: bold;\n}\n\n/* 进度条相关布局样式 */\n.tm-progress-row {\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n}\n\n.tm-seek-control-row {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n width: 100%;\n box-sizing: border-box;\n}\n\n.tm-loop-control-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n box-sizing: border-box;\n position: relative;\n}\n\n.tm-playback-control-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n position: relative;\n width: 100%;\n}\n\n/* 播放控制区域相关样式 */\n.tm-left-controls, .tm-center-controls, .tm-right-controls {\n flex: 1;\n display: flex;\n}\n\n.tm-left-controls {\n justify-content: flex-start;\n}\n\n.tm-center-controls {\n justify-content: center;\n}\n\n.tm-right-controls {\n justify-content: flex-end;\n}\n\n/* 时间显示 */\n.tm-time-display {\n display: flex;\n justify-content: space-between;\n color: hsl(var(--shadcn-foreground) / 0.9);\n font-size: 12px;\n margin-top: -2px;\n font-variant-numeric: tabular-nums;\n gap: 8px;\n}\n\n.tm-time-display-container {\n display: flex;\n justify-content: space-between;\n width: 100%;\n padding: 0px 1px;\n margin-bottom: 4px;\n}\n\n.tm-current-time, .tm-total-duration {\n color: hsl(var(--shadcn-card-foreground) / 0.9);\n font-size: 0.8rem;\n min-width: 60px;\n font-variant-numeric: tabular-nums;\n font-weight: 400;\n line-height: 1;\n}\n\n.tm-current-time {\n text-align: left;\n}\n\n.tm-total-duration {\n text-align: right;\n}\n\n.tm-loop-control {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.tm-start-time-container, .tm-end-time-container {\n display: flex;\n align-items: center;\n background-color: hsl(var(--shadcn-secondary) / 0.5);\n border: 1px solid hsl(var(--shadcn-border) / 0.1);\n border-radius: 6px;\n padding: 4px 4px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n/* 添加悬停效果 */\n.tm-start-time-container:hover {\n background-color: hsl(var(--shadcn-green) / 0.1);\n border-color: hsl(var(--shadcn-green) / 0.3);\n transform: translateY(-1px);\n}\n\n.tm-end-time-container:hover {\n background-color: hsl(var(--shadcn-orange) / 0.1);\n border-color: hsl(var(--shadcn-orange) / 0.3);\n transform: translateY(-1px);\n}\n\n.tm-set-loop-start-label, .tm-set-loop-end-label {\n font-size: 1rem;\n font-weight: 600;\n padding: 0px 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* A按钮标签 - 始终保持绿色 */\n.tm-set-loop-start-label {\n font-size: 1rem;\n font-weight: 600;\n padding: 0px 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: hsl(var(--shadcn-green));\n}\n\n/* B按钮标签 - 始终保持橙色 */\n.tm-set-loop-end-label {\n font-size: 1rem;\n font-weight: 600;\n padding: 0px 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: hsl(var(--shadcn-orange));\n}\n\n.tm-loop-toggle-button {\n display: flex;\n align-items: center;\n background-color: hsl(var(--shadcn-secondary) / 0.5);\n border: 1px solid hsl(var(--shadcn-border) / 0.1);\n border-radius: 6px;\n padding: 4px 8px;\n font-size: 0.875rem;\n cursor: pointer;\n transition: all 0.2s ease;\n font-weight: 500;\n gap: 6px;\n color: hsl(var(--shadcn-foreground));\n}\n\n/* Loop按钮标签样式 */\n.tm-loop-toggle-label {\n font-size: 1rem;\n font-weight: 600;\n padding: 0px 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: hsl(var(--shadcn-muted-foreground) / 0.9);\n transition: color 0.2s ease;\n}\n\n/* 添加标签激活状态 */\n.tm-loop-toggle-label.active {\n color: hsl(var(--shadcn-red));\n}\n\n/* 循环按钮 - 两种状态 */\n.tm-loop-toggle-button.active {\n background-color: hsl(var(--shadcn-red) / 0.1);\n border-color: hsl(var(--shadcn-red) / 0.3);\n}\n\n.tm-loop-toggle-button:not(.active) {\n background-color: hsl(var(--shadcn-secondary) / 0.5);\n border-color: hsl(var(--shadcn-border) / 0.1);\n}\n\n/* 循环按钮悬停效果统一 */\n.tm-loop-toggle-button:hover {\n background-color: hsl(var(--shadcn-red) / 0.1);\n border-color: hsl(var(--shadcn-red) / 0.3);\n transform: translateY(-1px);\n}\n\n.tm-loop-toggle-button:active {\n transform: scale(0.98);\n}\n\n.tm-loop-indicator-circle {\n transition: fill 0.2s ease;\n}\n\n.tm-loop-toggle-button:hover .tm-loop-indicator-circle {\n fill: hsl(var(--shadcn-red) / 0.7);\n}\n\n.tm-loop-toggle-button.active .tm-loop-indicator-circle {\n fill: hsl(var(--shadcn-red));\n}\n\n/* 添加新的样式 */\n/* 快进/快退按钮组样式 */\n.tm-rewind-group, .tm-forward-group {\n display: flex;\n flex-direction: column;\n width: 50%;\n gap: 8px;\n align-items: center;\n}\n\n.tm-rewind-buttons-container {\n display: flex;\n flex-direction: row-reverse;\n flex-wrap: wrap;\n width: 100%;\n justify-content: flex-end;\n align-content: flex-start;\n gap: 6px;\n}\n\n.tm-forward-buttons-container {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n width: 100%;\n justify-content: flex-end;\n align-content: flex-start;\n gap: 6px;\n}\n\n/* 循环时间显示样式 */\n.tm-loop-start-position, .tm-loop-end-position {\n color: hsl(var(--shadcn-muted-foreground));\n font-size: 0.875rem;\n min-width: 70px;\n text-align: center;\n display: inline-block;\n font-variant-numeric: tabular-nums;\n}\n\n/* 时间控制按钮基础样式 */\n.tm-time-control-button {\n background-color: hsl(var(--shadcn-secondary) / 0.5);\n color: hsl(var(--shadcn-secondary-foreground));\n border: 1px solid hsl(var(--shadcn-border) / 0.1);\n border-radius: var(--shadcn-radius-sm);\n padding: 0;\n font-size: 0.75rem;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(.25,.8,.25,1);\n white-space: nowrap;\n font-weight: 500;\n box-shadow: 0 1px 2px rgba(0,0,0,0.05);\n width: var(--button-xl);\n height: var(--button-lg);\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n}\n\n.tm-time-control-button:hover {\n background-color: hsl(var(--shadcn-accent) / 0.6);\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n}\n\n.tm-time-control-button:active {\n transform: scale(0.95);\n box-shadow: none;\n}\n\n.tm-time-control-button-active {\n transform: scale(0.95);\n box-shadow: none;\n}\n\n.tm-time-control-button-after-active {\n transform: none;\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);\n}\n\n.tm-time-control-button-inner {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.tm-rewind-icon {\n margin-right: -2px;\n}\n\n.tm-forward-icon {\n margin-left: -2px;\n}\n\n.tm-time-text-margin-left {\n margin-left: 2px;\n}\n\n.tm-time-text-margin-right {\n margin-right: 2px;\n}\n\n/* 控制按钮状态 */\n.tm-control-button-hover {\n background-color: hsl(var(--shadcn-accent) / 0.3);\n transform: none;\n}\n\n.tm-control-button-default {\n background-color: hsl(var(--shadcn-secondary) / 0.5);\n transform: none;\n}\n\n/* 控制面板容器 */\n.tm-control-buttons {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 12px;\n padding: 12px;\n position: fixed;\n bottom: calc(10px + env(safe-area-inset-bottom, 0px)); /* 保持距离底部10px,同时考虑iOS安全区域 */\n left: 50%;\n transform: translateX(-50%);\n width: 95%;\n min-width: 350px;\n max-width: 700px;\n flex-direction: column;\n background-color: hsla(var(--shadcn-card) / 0.5);\n overflow: hidden;\n box-sizing: border-box;\n border-radius: 12px;\n border: 1px solid hsla(var(--shadcn-border) / 0.1);\n box-shadow: var(--shadow-md);\n backdrop-filter: blur(30px);\n -webkit-backdrop-filter: blur(30px);\n z-index: 9991;\n}\n\n/* 控制按钮 */\n.tm-control-button {\n position: relative;\n width: var(--button-md);\n height: var(--button-md);\n border-radius: calc(var(--button-md) / 2);\n background-color: hsla(var(--shadcn-secondary) / 0.6);\n color: hsl(var(--shadcn-secondary-foreground));\n border: 1px solid hsla(var(--shadcn-border) / 0.1);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all var(--anim-quick);\n}\n\n.tm-control-button:hover {\n background-color: hsla(var(--shadcn-accent) / 0.7);\n transform: translateY(-2px);\n box-shadow: var(--shadow-sm);\n}\n\n.tm-control-button:active {\n transform: scale(0.95);\n box-shadow: none;\n}\n\n.tm-control-button.active {\n background-color: hsla(var(--shadcn-blue) / 0.7);\n color: hsl(var(--shadcn-blue-foreground));\n box-shadow: 0 0 0 2px hsla(var(--shadcn-blue) / 0.3);\n}\n\n.tm-control-button svg,\n.tm-control-button img {\n width: 16px;\n height: 16px;\n}\n\n/* 控制行 */\n.tm-control-row {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 8px;\n margin-top: 4px;\n opacity: 1;\n transition: opacity var(--anim-quick), height var(--anim-quick);\n height: auto;\n overflow: hidden;\n}\n\n.tm-control-row.hidden {\n opacity: 0;\n height: 0;\n margin: 0;\n}\n\n/* \n * 静态样式迁移总结:\n * 1. 已将进度条高度变化从行内样式转为CSS类:tm-progress-bar-expanded, tm-progress-bar-normal\n * 2. 已将循环标记点样式从行内样式转为CSS类:tm-loop-marker-point等\n * 3. 已将时间容器交互状态从行内样式转为CSS类:tm-start-time-container-hover等\n * 4. 已将循环按钮交互状态从行内样式转为CSS类:tm-loop-button-hover等\n * 5. 已将倍速滑块交互状态从行内样式转为CSS类:tm-playback-slider-hover等\n * 6. 已将控制按钮交互状态从行内样式转为CSS类:tm-control-button-hover等\n * 7. 已将时间控制按钮交互状态从行内样式转为CSS类:tm-time-control-button-hover等\n * \n * 注意:某些动态计算的样式值(如宽度百分比)仍使用行内样式直接设置\n */\n\n/* 时间控制按钮状态 */\n.tm-time-control-button-hover {\n background-color: hsl(var(--shadcn-accent) / 0.6);\n transform: none;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n}\n\n.tm-time-control-button-active {\n transform: scale(0.95);\n box-shadow: none;\n}\n\n.tm-time-control-button-default {\n transform: translateY(0);\n box-shadow: 0 1px 2px rgba(0,0,0,0.05);\n}\n\n.tm-time-control-button-after-active {\n transform: none;\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);\n}\n\n/* =========== 横屏模式样式 =========== */\n@media screen and (orientation: landscape) {\n /* 视频容器横屏样式 */\n .tm-video-container {\n width: 100%;\n height: 100vh !important;\n max-height: 100vh !important;\n min-height: auto !important;\n margin: 0;\n padding: 0;\n /* 安全区域 */\n padding-left: env(safe-area-inset-left, 16px);\n padding-right: env(safe-area-inset-right, 16px);\n border-radius: 0;\n box-shadow: none;\n display: flex;\n justify-content: center;\n align-items: center;\n background-color: black;\n }\n\n /* 视频包装器横屏样式 */\n .tm-video-wrapper {\n width: 100%;\n height: 100%;\n border-radius: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n overflow: hidden;\n }\n\n /* 视频元素横屏样式 */\n .tm-video-wrapper video {\n width: 100% !important;\n height: auto !important;\n max-height: 100vh !important;\n object-fit: contain !important;\n }\n\n /* 当视频高度比例大于宽度比例时的样式 */\n .tm-video-wrapper.video-portrait video {\n width: auto !important;\n height: 100% !important;\n max-width: 100% !important;\n }\n\n /* 按钮容器横屏样式 - 只保留退出按钮 */\n .tm-button-container {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 9995;\n background-color: transparent;\n padding: 16px;\n padding-top: calc(env(safe-area-inset-top, 8px) + 8px);\n display: flex;\n justify-content: space-between;\n transition: opacity 0.3s ease, transform 0.3s ease;\n }\n\n /* 控制界面隐藏时的动画效果 */\n .tm-video-overlay.controls-hidden .tm-button-container {\n opacity: 0;\n transform: translateY(-20px);\n pointer-events: none;\n }\n\n /* 控制界面显示时的动画效果 */\n .tm-video-overlay .tm-button-container {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n }\n\n /* 设置按钮在横屏时不再隐藏 */\n .tm-settings-button {\n display: flex;\n background-color: hsla(var(--shadcn-secondary) / 0.3);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n }\n\n /* 关闭按钮半透明 */\n .tm-close-button {\n background-color: hsla(var(--shadcn-secondary) / 0.3);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n }\n\n /* 控制面板横屏样式 */\n .tm-control-buttons {\n position: absolute;\n bottom: calc(10px + env(safe-area-inset-bottom, 0px)); /* 保持距离底部10px,同时考虑iOS安全区域 */\n left: 50%;\n transform: translateX(-50%);\n width: 90%;\n max-width: 700px;\n min-width: 350px; /* 与竖屏模式保持一致 */\n background-color: hsla(var(--shadcn-card) / 0.3);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n z-index: 9994;\n padding: 12px;\n padding-bottom: 12px; /* 移除原来的calc计算,因为我们已经在bottom属性中处理了 */\n border-radius: 12px;\n border: 1px solid hsla(var(--shadcn-border) / 0.1);\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);\n transition: opacity 0.3s ease, transform 0.3s ease;\n }\n\n /* 控制界面隐藏时的动画效果 */\n .tm-video-overlay.controls-hidden .tm-control-buttons {\n opacity: 0;\n transform: translateX(-50%) translateY(20px);\n pointer-events: none;\n }\n\n /* 控制界面显示时的动画效果 */\n .tm-video-overlay .tm-control-buttons {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n pointer-events: auto;\n }\n\n /* 横屏模式下的播放器遮罩层 */\n .tm-video-overlay {\n background-color: black;\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n }\n\n /* 浮动按钮样式 - 确保在所有屏幕方向上正确显示 */\n .tm-floating-button {\n bottom: 30px;\n right: 30px;\n }\n}\n\n/* 进度条拖动时间指示器 */\n.tm-time-indicator {\n position: absolute;\n background-color: hsla(var(--shadcn-card) / 0.8);\n color: hsl(var(--shadcn-card-foreground));\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 12px;\n font-weight: 500;\n pointer-events: none;\n z-index: 9995;\n opacity: 0;\n transform: translateY(-8px);\n transition: opacity 0.2s, transform 0.2s;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n border: 1px solid hsla(var(--shadcn-border) / 0.1);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n}\n\n/* 循环时间容器状态样式 - 优化版 */\n/* A按钮容器 - 两种状态 */\n.tm-start-time-container.active {\n background-color: hsl(var(--shadcn-green) / 0.15);\n border-color: hsl(var(--shadcn-green) / 0.4);\n}\n\n.tm-start-time-container:not(.active) {\n background-color: hsl(var(--shadcn-secondary) / 0.5);\n border-color: hsl(var(--shadcn-border) / 0.1);\n}\n\n/* B按钮容器 - 两种状态 */\n.tm-end-time-container.active {\n background-color: hsl(var(--shadcn-orange) / 0.15);\n border-color: hsl(var(--shadcn-orange) / 0.4);\n}\n\n.tm-end-time-container:not(.active) {\n background-color: hsl(var(--shadcn-secondary) / 0.5);\n border-color: hsl(var(--shadcn-border) / 0.1);\n}\n\n/* A按钮标签 - 两种状态 */\n.tm-set-loop-start-label.active {\n color: hsl(var(--shadcn-green));\n opacity: 1;\n}\n\n.tm-set-loop-start-label:not(.active) {\n color: hsl(var(--shadcn-muted-foreground) / 0.8);\n opacity: 0.9;\n}\n\n/* B按钮标签 - 两种状态 */\n.tm-set-loop-end-label.active {\n color: hsl(var(--shadcn-orange));\n opacity: 1;\n}\n\n.tm-set-loop-end-label:not(.active) {\n color: hsl(var(--shadcn-muted-foreground) / 0.8);\n opacity: 0.9;\n}\n\n/* 循环时间文本 - 两种状态 */\n.tm-loop-start-position.active, .tm-loop-end-position.active {\n color: hsl(var(--shadcn-foreground));\n opacity: 1;\n}\n\n.tm-loop-start-position:not(.active), .tm-loop-end-position:not(.active) {\n color: hsl(var(--shadcn-muted-foreground));\n opacity: 0.9;\n}\n\n/* 循环按钮 - 两种状态 */\n.tm-loop-toggle-button.active {\n background-color: hsl(var(--shadcn-red) / 0.1);\n border-color: hsl(var(--shadcn-red) / 0.3);\n}\n\n.tm-loop-toggle-button:not(.active) {\n background-color: hsl(var(--shadcn-secondary) / 0.5);\n border-color: hsl(var(--shadcn-border) / 0.1);\n}\n\n/* 循环按钮悬停效果统一 */\n.tm-loop-toggle-button:hover {\n background-color: hsl(var(--shadcn-red) / 0.1);\n border-color: hsl(var(--shadcn-red) / 0.3);\n transform: translateY(-1px);\n}\n\n.tm-loop-toggle-button:active {\n transform: scale(0.98);\n}\n\n/* 循环区间连接效果 */\n.tm-loop-range {\n position: absolute;\n height: 4px;\n background: linear-gradient(90deg, \n hsla(var(--shadcn-green) / 0.3) 0%, \n hsla(var(--shadcn-orange) / 0.3) 100%);\n top: 50%;\n transform: translateY(-50%);\n border-radius: 2px;\n opacity: 0;\n transition: opacity 0.3s ease;\n z-index: 1;\n pointer-events: none;\n}\n\n.tm-loop-range.active {\n opacity: 0.7;\n box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);\n}\n\n/* 循环区间悬停效果 */\n.tm-progress-bar-container:hover .tm-loop-range.active {\n opacity: 0.9;\n height: 6px;\n}', ""]);
const s = a
}
},
e = {};
function n(r) {
var o = e[r];
if (void 0 !== o) return o.exports;
var i = e[r] = {
id: r,
exports: {}
};
return t[r](i, i.exports, n), i.exports
}
function r(t) {
return r = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, r(t)
}
function o(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, a(r.key), r)
}
}
function i(t, e, n) {
return (e = a(e)) in t ? Object.defineProperty(t, e, {
value: n,
enumerable: !0,
configurable: !0,
writable: !0
}) : t[e] = n, t
}
function a(t) {
var e = function(t) {
if ("object" != r(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != r(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == r(e) ? e : e + ""
}
n.n = t => {
var e = t && t.__esModule ? () => t.default : () => t;
return n.d(e, {
a: e
}), e
}, n.d = (t, e) => {
for (var r in e) n.o(e, r) && !n.o(t, r) && Object.defineProperty(t, r, {
enumerable: !0,
get: e[r]
})
}, n.o = (t, e) => Object.prototype.hasOwnProperty.call(t, e), n.r = t => {
"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
value: "Module"
}), Object.defineProperty(t, "__esModule", {
value: !0
})
}, n.nc = void 0;
var s = function() {
return t = function t() {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t)
}, e = [{
key: "throttle",
value: function(t) {
var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 200,
n = 0;
return function() {
var r = Date.now();
if (!(r - n < e)) {
n = r;
for (var o = arguments.length, i = new Array(o), a = 0; a < o; a++) i[a] = arguments[a];
return t.apply(this, i)
}
}
}
}, {
key: "debounce",
value: function(t) {
var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 200,
n = null;
return function() {
for (var r = this, o = arguments.length, i = new Array(o), a = 0; a < o; a++) i[a] = arguments[a];
n && clearTimeout(n), n = setTimeout((function() {
t.apply(r, i), n = null
}), e)
}
}
}, {
key: "isIOS",
value: function() {
return null === this._cache.isIOS && (this._cache.isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream), this._cache.isIOS
}
}, {
key: "isSafari",
value: function() {
return /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
}
}, {
key: "isPortrait",
value: function() {
return window.innerHeight > window.innerWidth
}
}, {
key: "checkDeviceAndOrientation",
value: function() {
return this.isPortrait()
}
}, {
key: "getSafeAreaInsets",
value: function() {
var t = window.getComputedStyle(document.documentElement);
return {
top: parseInt(t.getPropertyValue("--sat") || t.getPropertyValue("--safe-area-inset-top") || "0", 10) || 44,
right: parseInt(t.getPropertyValue("--sar") || t.getPropertyValue("--safe-area-inset-right") || "0", 10) || 16,
bottom: parseInt(t.getPropertyValue("--sab") || t.getPropertyValue("--safe-area-inset-bottom") || "0", 10) || 34,
left: parseInt(t.getPropertyValue("--sal") || t.getPropertyValue("--safe-area-inset-left") || "0", 10) || 16
}
}
}, {
key: "createElementWithStyle",
value: function(t, e, n) {
var r = document.createElement(t);
return e && (r.className = e), n && (r.style.cssText = n), r
}
}, {
key: "createSVGIcon",
value: function(t) {
var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 24,
n = document.createElementNS("http://www.w3.org/2000/svg", "svg");
n.setAttribute("width", e), n.setAttribute("height", e), n.setAttribute("viewBox", "0 0 24 24"), n.setAttribute("fill", "none"), n.setAttribute("stroke", "currentColor"), n.setAttribute("stroke-width", "2"), n.setAttribute("stroke-linecap", "round"), n.setAttribute("stroke-linejoin", "round");
var r = document.createElementNS("http://www.w3.org/2000/svg", "path");
return r.setAttribute("d", t), n.appendChild(r), n
}
}, {
key: "formatTime",
value: function(t) {
var e = Math.floor(t / 3600),
n = Math.floor(t % 3600 / 60),
r = Math.floor(t % 60);
return e > 0 ? "".concat(e, ":").concat(n < 10 ? "0" : "").concat(n, ":").concat(r < 10 ? "0" : "").concat(r) : "".concat(n, ":").concat(r < 10 ? "0" : "").concat(r)
}
}, {
key: "updateSafariThemeColor",
value: function() {
var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "#000000",
e = arguments.length > 1 && void 0 !== arguments[1] && arguments[1];
if (this.isSafari() || this.isIOS()) {
var n = document.querySelector('meta[name="theme-color"]');
e && n && !this._theme.original.dark && (this._theme.original.dark = n.content), n || ((n = document.createElement("meta")).name = "theme-color", document.head.appendChild(n)), n.content = t
}
}
}, {
key: "restoreSafariThemeColor",
value: function() {
if (this._theme.original.dark) this.updateSafariThemeColor(this._theme.original.dark);
else {
var t = document.querySelector('meta[name="theme-color"]');
t && t.parentNode && t.parentNode.removeChild(t)
}
}
}], null && o(t.prototype, null), e && o(t, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function l(t) {
return l = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, l(t)
}
function c(t, e) {
var n = Object.keys(t);
if (Object.getOwnPropertySymbols) {
var r = Object.getOwnPropertySymbols(t);
e && (r = r.filter((function(e) {
return Object.getOwnPropertyDescriptor(t, e).enumerable
}))), n.push.apply(n, r)
}
return n
}
function u(t) {
for (var e = 1; e < arguments.length; e++) {
var n = null != arguments[e] ? arguments[e] : {};
e % 2 ? c(Object(n), !0).forEach((function(e) {
d(t, e, n[e])
})) : Object.getOwnPropertyDescriptors ? Object.defineProperties(t, Object.getOwnPropertyDescriptors(n)) : c(Object(n)).forEach((function(e) {
Object.defineProperty(t, e, Object.getOwnPropertyDescriptor(n, e))
}))
}
return t
}
function d(t, e, n) {
return (e = p(e)) in t ? Object.defineProperty(t, e, {
value: n,
enumerable: !0,
configurable: !0,
writable: !0
}) : t[e] = n, t
}
function h(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, p(r.key), r)
}
}
function p(t) {
var e = function(t) {
if ("object" != l(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != l(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == l(e) ? e : e + ""
}
i(s, "_cache", {
isIOS: null,
safeAreaInsets: null,
lastOrientation: null
}), i(s, "_theme", {
original: {
light: null,
dark: null
}
});
var f = function() {
return t = function t() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), console.log("[PlayerCore] 初始化..."), this.defaultPlaybackRate = 1, this.targetVideo = null, this.videoState = {
currentTime: 0,
isPlaying: !1,
volume: 1,
playbackRate: 1
}, this.options = Object.assign({
containerId: "tm-video-container",
startLooped: !1,
startMuted: !1
}, e), this.callingButton = this.options.callingButton || null, this.initialized = !1
}, e = [{
key: "init",
value: function() {
if (!this.initialized) return this.cleanupExistingOverlays(), this.targetVideo = this.findTargetVideo(), this.targetVideo ? (this.saveVideoState(), this.initialized = !0, console.log("[PlayerCore] 核心初始化完成"), this.targetVideo) : (console.error("[PlayerCore] 未找到视频元素"), void(this.callingButton && (this.callingButton.style.display = "flex")))
}
}, {
key: "cleanupExistingOverlays",
value: function() {
var t = document.querySelectorAll(".tm-video-overlay");
t.length > 0 && (console.log("[PlayerCore] 清理 ".concat(t.length, " 个现有overlay元素")), t.forEach((function(t) {
t && t.parentNode && t.parentNode.removeChild(t)
})))
}
}, {
key: "findTargetVideo",
value: function() {
for (var t = null, e = 0, n = ["#player video", "#video video", "div.plyr__video-wrapper video", ".video-js video", "#player > video", "#video-player > video", "video[preload]:not([muted])"]; e < n.length; e++) {
var r = n[e];
if (t = document.querySelector(r)) return console.log("[PlayerCore] 通过选择器找到视频:", r), t
}
var o = Array.from(document.querySelectorAll("video"));
if (console.log("[PlayerCore] 找到视频元素数量:", o.length), 0 === o.length) return console.log("[PlayerCore] 未找到视频元素"), null;
if (1 === o.length) return console.log("[PlayerCore] 找到单个视频元素"), o[0];
var i = o.map((function(t) {
return {
element: t,
rect: t.getBoundingClientRect()
}
})).filter((function(t) {
return t.rect.width > 50 && t.rect.height > 50
})).map((function(t) {
return u(u({}, t), {}, {
area: t.rect.width * t.rect.height
})
})).sort((function(t, e) {
return e.area - t.area
}));
return i.length > 0 ? (console.log("[PlayerCore] 选择最大的可见视频"), i[0].element) : (console.log("[PlayerCore] 回退到第一个视频元素"), o[0])
}
}, {
key: "saveVideoState",
value: function() {
this.targetVideo && (this.originalParent = this.targetVideo.parentNode, this.originalIndex = Array.from(this.originalParent.children).indexOf(this.targetVideo), this.videoState = {
currentTime: this.targetVideo.currentTime,
isPaused: this.targetVideo.paused,
videoSrc: this.targetVideo.src,
posterSrc: this.targetVideo.poster,
wasMuted: this.targetVideo.muted,
controls: this.targetVideo.controls
})
}
}, {
key: "restoreVideoState",
value: function() {
var t = this;
try {
this.targetVideo.playbackRate = this.defaultPlaybackRate, this.targetVideo.currentTime = this.videoState.currentTime;
var e = this.targetVideo.play();
void 0 !== e && e.catch((function(e) {
console.log("视频自动播放被阻止,尝试静音播放: ", e), t.targetVideo.muted = !0, t.targetVideo.play().catch((function(t) {
console.error("即使静音也无法自动播放: ", t)
}))
}))
} catch (t) {
console.error("尝试播放时出错: ", t)
}
}
}, {
key: "close",
value: function(t, e) {
if (t) {
this.videoState.currentTime = this.targetVideo.currentTime, this.videoState.isPlaying = !this.targetVideo.paused, this.videoState.volume = this.targetVideo.volume, this.videoState.playbackRate = this.targetVideo.playbackRate, this.targetVideo.paused || this.targetVideo.pause(), this.originalParent && this.targetVideo && this.targetVideo.parentNode && this.targetVideo.parentNode !== this.originalParent && (-1 !== this.originalIndex && this.originalParent.childNodes.length > this.originalIndex ? this.originalParent.insertBefore(this.targetVideo, this.originalParent.childNodes[this.originalIndex]) : this.originalParent.appendChild(this.targetVideo), this.targetVideo.style.width = "", this.targetVideo.style.height = "", this.targetVideo.style.maxHeight = "", this.targetVideo.style.margin = "", this.targetVideo.style.position = ""), t.parentNode && t.parentNode.removeChild(t);
var n = document.getElementById("tm-fullscreen-style");
n && n.parentNode.removeChild(n), this.initialized = !1, s.restoreSafariThemeColor(), this.callingButton && (this.callingButton.style.display = "flex")
}
}
}], e && h(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function m(t) {
return m = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, m(t)
}
function v(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, g(r.key), r)
}
}
function g(t) {
var e = function(t) {
if ("object" != m(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != m(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == m(e) ? e : e + ""
}
var y = function() {
return t = function t(e) {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.playerCore = e, this.targetVideo = e.targetVideo, this.overlay = null, this.container = null, this.videoWrapper = null, this.handleContainer = null, this.handle = null, this.closeBtn = null, this.settingsBtn = null, this.settingsPanel = null, this.buttonContainer = null, this.safeArea = {
top: 44,
bottom: 34
}, this.isLandscape = !1, this.controlsVisible = !0, this.controlsHideTimeout = null
}, e = [{
key: "createUI",
value: function() {
return console.log("[UIManager] createUI started."), this.createOverlayAndContainer(), this.createVideoWrapper(), this.createResizeHandle(), this.createCloseButton(), this.createSettingsButton(), this.createButtonContainer(), this.createSettingsPanel(), this.setupOrientationListener(), console.log("[UIManager] UI基础元素创建完成"), {
overlay: this.overlay,
container: this.container,
videoWrapper: this.videoWrapper,
handleContainer: this.handleContainer,
handle: this.handle,
closeBtn: this.closeBtn,
settingsBtn: this.settingsBtn,
settingsPanel: this.settingsPanel,
buttonContainer: this.buttonContainer
}
}
}, {
key: "createOverlayAndContainer",
value: function() {
this.overlay = document.createElement("div"), this.overlay.className = "tm-video-overlay", this.overlay.style.zIndex = "9990";
var t = .8 * window.innerWidth,
e = window.innerWidth * (9 / 16);
this.container = document.createElement("div"), this.container.className = "tm-video-container", this.container.style.height = "".concat(t, "px"), this.container.style.minHeight = "".concat(e, "px"), console.log("[UIManager] Container element created:", this.container), console.log("[UIManager] createOverlayAndContainer finished.")
}
}, {
key: "createVideoWrapper",
value: function() {
var t = this;
this.videoWrapper = document.createElement("div"), this.videoWrapper.className = "tm-video-wrapper", this.targetVideo && this.targetVideo.parentNode && this.targetVideo.parentNode.removeChild(this.targetVideo), this.targetVideo.controls = !1, this.videoWrapper.appendChild(this.targetVideo), this.targetVideo.addEventListener("loadedmetadata", (function() {
t.updateVideoAspectRatio()
})), this.videoWrapper.addEventListener("click", (function() {
t.isLandscape && t.toggleControlsVisibility()
}))
}
}, {
key: "createResizeHandle",
value: function() {
var t = this;
this.handleContainer = document.createElement("div"), this.handleContainer.className = "tm-handle-container", this.handle = document.createElement("div"), this.handle.className = "tm-resize-handle", this.handle.insertAdjacentHTML("beforeend", '\n <div style="\n position: absolute;\n left: -10px;\n right: -10px;\n top: -15px;\n bottom: -15px;\n background: transparent;\n "></div>\n '), this.handle.addEventListener("mouseenter", (function() {
t.handle.style.opacity = "1", t.handle.style.backgroundColor = "hsla(var(--shadcn-foreground) / 0.8)"
})), this.handle.addEventListener("mouseleave", (function() {
t.isDraggingHandle || (t.handle.style.opacity = "0.5", t.handle.style.backgroundColor = "hsla(var(--shadcn-foreground) / 0.6)")
})), this.handle.addEventListener("mousedown", (function() {
t.handle.style.cursor = "grabbing", window.navigator.vibrate && window.navigator.vibrate(5)
})), document.addEventListener("mouseup", (function() {
t.isDraggingHandle || (t.handle.style.cursor = "grab")
})), this.handle.addEventListener("touchstart", (function() {
t.handle.style.opacity = "1", t.handle.style.backgroundColor = "hsla(var(--shadcn-foreground) / 0.8)", window.navigator.vibrate && window.navigator.vibrate(5)
}), {
passive: !0
}), this.handle.addEventListener("touchend", (function() {
t.isDraggingHandle || (t.handle.style.opacity = "0.5", t.handle.style.backgroundColor = "hsla(var(--shadcn-foreground) / 0.6)")
})), this.handleContainer.appendChild(this.handle)
}
}, {
key: "createCloseButton",
value: function() {
var t = this;
this.closeBtn = document.createElement("button"), this.closeBtn.className = "tm-close-button tm-control-button-base", this.closeBtn.innerHTML = '\n <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M18 6L6 18M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ', this.closeBtn.addEventListener("mouseenter", (function() {
t.closeBtn.style.backgroundColor = "hsla(var(--shadcn-destructive) / 0.9)", t.closeBtn.style.transform = "scale(1.1)"
})), this.closeBtn.addEventListener("mouseleave", (function() {
t.closeBtn.style.backgroundColor = "hsla(var(--shadcn-background) / 0.7)", t.closeBtn.style.transform = "scale(1)"
}))
}
}, {
key: "createSettingsButton",
value: function() {
var t = this;
this.settingsBtn = document.createElement("button"), this.settingsBtn.className = "tm-settings-button tm-control-button-base", this.settingsBtn.innerHTML = '\n <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M12 15C13.6569 15 15 13.6569 15 12C15 10.3431 13.6569 9 12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M19.4 15C19.1277 15.6171 19.2583 16.3378 19.73 16.82L19.79 16.88C20.1837 17.2737 20.4009 17.7994 20.4009 18.345C20.4009 18.8906 20.1837 19.4163 19.79 19.81C19.4163 20.2037 18.8906 20.4209 18.345 20.4209C17.7994 20.4209 17.2737 20.2037 16.91 19.81L16.85 19.75C16.3678 19.2783 15.6471 19.1477 15.03 19.42C14.4301 19.6801 14.0386 20.2502 14.03 20.89V21C14.03 21.5304 13.8193 22.0391 13.4442 22.4142C13.0691 22.7893 12.5604 23 12.03 23C11.4996 23 10.9909 22.7893 10.6158 22.4142C10.2407 22.0391 10.03 21.5304 10.03 21V20.91C10.0112 20.2556 9.5979 19.6818 8.98 19.43C8.36289 19.1577 7.64221 19.2883 7.16 19.76L7.1 19.82C6.73629 20.2137 6.21056 20.4309 5.665 20.4309C5.11944 20.4309 4.59371 20.2137 4.23 19.82C3.83628 19.4463 3.61911 18.9206 3.61911 18.375C3.61911 17.8294 3.83628 17.3037 4.23 16.93L4.29 16.87C4.76167 16.3878 4.89231 15.6671 4.62 15.05C4.35995 14.4501 3.78985 14.0586 3.15 14.05H3C2.46957 14.05 1.96086 13.8393 1.58579 13.4642C1.21071 13.0891 1 12.5804 1 12.05C1 11.5196 1.21071 11.0109 1.58579 10.6358C1.96086 10.2607 2.46957 10.05 3 10.05H3.09C3.74435 10.0312 4.31814 9.61788 4.57 9C4.84231 8.38289 4.71167 7.66221 4.24 7.18L4.18 7.12C3.78628 6.75629 3.56911 6.23056 3.56911 5.685C3.56911 5.13944 3.78628 4.61371 4.18 4.25C4.55371 3.85628 5.07944 3.63911 5.625 3.63911C6.17056 3.63911 6.69629 3.85628 7.07 4.25L7.13 4.31C7.61221 4.78167 8.33289 4.91231 8.95 4.64H9C9.59994 4.37995 9.99144 3.80985 10 3.17V3C10 2.46957 10.2107 1.96086 10.5858 1.58579C10.9609 1.21071 11.4696 1 12 1C12.5304 1 13.0391 1.21071 13.4142 1.58579C13.7893 1.96086 14 2.46957 14 3V3.09C14.0086 3.72985 14.4001 4.29995 15 4.56C15.6171 4.83231 16.3378 4.70167 16.82 4.23L16.88 4.17C17.2437 3.77628 17.7694 3.55911 18.325 3.55911C18.8806 3.55911 19.4063 3.77628 19.77 4.17C20.1637 4.54371 20.3809 5.06944 20.3809 5.615C20.3809 6.16056 20.1637 6.68629 19.77 7.06L19.71 7.12C19.2383 7.60221 19.1077 8.32289 19.38 8.94L19.4 9C19.66 9.59994 20.2301 9.99144 20.87 10H21C21.5304 10 22.0391 10.2107 22.4142 10.5858C22.7893 10.9609 23 11.4696 23 12C23 12.5304 22.7893 13.0391 22.4142 13.4142C22.0391 13.7893 21.5304 14 21 14H20.91C20.2702 14.0086 19.7001 14.4001 19.44 15H19.4Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ', this.settingsBtn.addEventListener("mouseenter", (function() {
t.settingsBtn.style.backgroundColor = "hsla(var(--shadcn-accent) / 0.9)", t.settingsBtn.style.transform = "rotate(45deg)"
})), this.settingsBtn.addEventListener("mouseleave", (function() {
t.settingsBtn.style.backgroundColor = "hsla(var(--shadcn-background) / 0.7)", t.settingsBtn.style.transform = "rotate(0deg)"
}))
}
}, {
key: "createSettingsPanel",
value: function() {
this.settingsPanel = document.createElement("div"), this.settingsPanel.className = "tm-settings-panel", this.settingsPanel.style.display = "none"
}
}, {
key: "createButtonContainer",
value: function() {
this.buttonContainer = document.createElement("div"), this.buttonContainer.className = "tm-button-container", this.buttonContainer.style.top = "10px", this.buttonContainer.style.right = "10px", this.buttonContainer.style.display = "flex", this.buttonContainer.style.alignItems = "center", this.buttonContainer.style.gap = "10px", this.buttonContainer.style.zIndex = "99999"
}
}, {
key: "setupOrientationListener",
value: function() {
var t = this;
this.checkOrientation(), window.addEventListener("orientationchange", (function() {
setTimeout((function() {
t.checkOrientation()
}), 300)
})), window.addEventListener("resize", (function() {
t.checkOrientation()
}))
}
}, {
key: "setupInteractionListeners",
value: function() {
var t = this;
console.log("[UIManager] 设置交互事件监听器"), this.overlay && (this.overlay.addEventListener("mousemove", (function() {
t.isLandscape && (t.showControls(), t.autoHideControls())
})), this.overlay.addEventListener("touchmove", (function() {
t.isLandscape && (t.showControls(), t.autoHideControls())
}), {
passive: !0
}), this.overlay.addEventListener("touchstart", (function(e) {
t.isLandscape && e.target.closest(".tm-control-button, .tm-time-control-button, .tm-close-button") && (t.showControls(), t.autoHideControls(), e.stopPropagation())
}), {
passive: !1
}))
}
}, {
key: "checkOrientation",
value: function() {
var t = window.innerWidth > window.innerHeight;
this.isLandscape !== t && (this.isLandscape = t, this.handleOrientationChange())
}
}, {
key: "handleOrientationChange",
value: function() {
console.log("[UIManager] 屏幕方向变化:", this.isLandscape ? "横屏" : "竖屏"), this.updateContainerMinHeight(), this.updateVideoAspectRatio(), this.playerCore.controlManager && (this.playerCore.controlManager.updateProgressBar(), this.playerCore.controlManager.updateCurrentTimeDisplay(), this.updateControlPanelVisibility()), this.handleContainer && (this.handleContainer.style.display = this.isLandscape ? "none" : "flex"), this.isLandscape ? (this.showControls(), this.autoHideControls()) : (this.showControls(), this.controlsHideTimeout && (clearTimeout(this.controlsHideTimeout), this.controlsHideTimeout = null))
}
}, {
key: "updateControlPanelVisibility",
value: function() {
if (this.playerCore.controlManager) {
var t = this.playerCore.controlManager.controlButtonsContainer;
if (t) {
var e = t.querySelector(".tm-progress-row"),
n = t.querySelector(".tm-seek-control-row"),
r = t.querySelector(".tm-loop-control-row"),
o = t.querySelector(".tm-playback-control-row");
if (this.isLandscape) {
e && (e.style.display = "flex", e.style.backgroundColor = "transparent"), n && (n.style.display = "flex", n.style.justifyContent = "center", n.style.alignItems = "center", n.style.gap = "20px", n.style.backgroundColor = "transparent"), r && (r.style.display = "flex", r.style.backgroundColor = "transparent"), o && (o.style.display = "flex", o.style.backgroundColor = "transparent"), this.settingsBtn && (this.settingsBtn.style.display = "flex", this.settingsBtn.style.backgroundColor = "hsla(var(--shadcn-secondary) / 0.3)", this.settingsBtn.style.backdropFilter = "blur(4px)");
var i = t.querySelector(".tm-rewind-group"),
a = t.querySelector(".tm-forward-group");
i && (i.style.width = "auto", i.style.flex = "0 1 auto"), a && (a.style.width = "auto", a.style.flex = "0 1 auto")
} else {
e && (e.style.display = ""), n && (n.style.display = "", n.style.justifyContent = "", n.style.alignItems = "", n.style.gap = ""), r && (r.style.display = ""), o && (o.style.display = ""), this.settingsBtn && (this.settingsBtn.style.display = "", this.settingsBtn.style.backgroundColor = "", this.settingsBtn.style.backdropFilter = "");
var s = t.querySelector(".tm-rewind-group"),
l = t.querySelector(".tm-forward-group");
s && (s.style.width = "", s.style.flex = ""), l && (l.style.width = "", l.style.flex = "")
}
}
}
}
}, {
key: "updateVideoAspectRatio",
value: function() {
if (this.videoWrapper && this.targetVideo) {
var t = this.targetVideo.videoWidth,
e = this.targetVideo.videoHeight;
if (t && e) {
var n = t / e,
r = n < 1;
r ? this.videoWrapper.classList.add("video-portrait") : this.videoWrapper.classList.remove("video-portrait"), console.log("[UIManager] 视频比例更新:", n, r ? "竖屏视频" : "横屏视频")
}
}
}
}, {
key: "showControls",
value: function() {
this.overlay && (this.overlay.classList.remove("controls-hidden"), this.controlsVisible = !0, this.controlsHideTimeout && (clearTimeout(this.controlsHideTimeout), this.controlsHideTimeout = null))
}
}, {
key: "hideControls",
value: function() {
this.overlay && this.isLandscape && (this.overlay.classList.add("controls-hidden"), this.controlsVisible = !1)
}
}, {
key: "toggleControlsVisibility",
value: function() {
this.controlsVisible ? this.hideControls() : (this.showControls(), this.autoHideControls())
}
}, {
key: "autoHideControls",
value: function() {
var t = this;
this.isLandscape && (this.controlsHideTimeout && clearTimeout(this.controlsHideTimeout), this.controlsHideTimeout = setTimeout((function() {
t.hideControls()
}), 3e3))
}
}, {
key: "updateContainerMinHeight",
value: function() {
if (this.container && this.targetVideo)
if (this.isLandscape) console.log("[UIManager] 横屏模式,使用CSS样式控制高度");
else {
var t = this.targetVideo.videoWidth || this.targetVideo.naturalWidth,
e = this.targetVideo.videoHeight || this.targetVideo.naturalHeight;
if (t && e) {
var n = window.innerWidth * (e / t);
this.container.style.minHeight = "".concat(n, "px"), console.log("[UIManager] 更新容器最小高度:", n)
}
}
}
}, {
key: "assembleDOM",
value: function() {
this.container.appendChild(this.videoWrapper), this.buttonContainer.appendChild(this.closeBtn), this.buttonContainer.appendChild(this.settingsBtn), this.overlay.appendChild(this.buttonContainer), this.overlay.appendChild(this.container), this.overlay.appendChild(this.handleContainer), this.overlay.appendChild(this.settingsPanel), document.body.appendChild(this.overlay), this.updateContainerMinHeight(), this.setupInteractionListeners(), console.log("[UIManager] DOM组装完成", {
overlay: this.overlay.isConnected,
container: this.container.isConnected,
videoWrapper: this.videoWrapper.isConnected,
video: this.targetVideo.isConnected
})
}
}], e && v(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function b(t) {
return b = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, b(t)
}
function w(t, e) {
(null == e || e > t.length) && (e = t.length);
for (var n = 0, r = Array(e); n < e; n++) r[n] = t[n];
return r
}
function k(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, x(r.key), r)
}
}
function x(t) {
var e = function(t) {
if ("object" != b(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != b(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == b(e) ? e : e + ""
}
var E = function() {
return t = function t(e, n) {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.playerCore = e, this.targetVideo = e.targetVideo, this.uiElements = n, this.controlButtonsContainer = null, this.playPauseButton = null, this.muteButton = null, this.progressBarElement = null, this.progressIndicator = null, this.currentTimeDisplay = null, this.totalDurationDisplay = null, this.timeIndicator = null, this.progressControlsContainer = null, this.pauseIndicator = null, this.playbackRateIndicator = null, this.loopManager = null, this.loopStartMarker = null, this.loopEndMarker = null, this.loopStartDisplay = null, this.loopEndDisplay = null, this.isDraggingProgress = !1, this.clickLock = !1, this.clickLockTimeout = null
}, e = [{
key: "init",
value: function() {
return this.progressControlsContainer = this.createProgressControls(), this.controlButtonsContainer = this.createControlButtonsContainer(), this.initEventListeners(), {
progressControlsContainer: this.progressControlsContainer,
controlButtonsContainer: this.controlButtonsContainer
}
}
}, {
key: "setLoopManager",
value: function(t) {
this.loopManager = t
}
}, {
key: "initEventListeners",
value: function() {
var t = this;
this.targetVideo.addEventListener("timeupdate", this.updateProgressBar.bind(this)), this.targetVideo.addEventListener("loadedmetadata", (function() {
t.updateProgressBar(), t.updateLoopTimeDisplay(), t.updateLoopMarkers()
})), this.progressBarElement.addEventListener("click", this.handleProgressClick.bind(this)), this.progressBarElement.addEventListener("mousedown", this.startProgressDrag.bind(this)), this.progressBarElement.addEventListener("touchstart", this.startProgressDrag.bind(this), {
passive: !1
}), this.uiElements.videoWrapper.addEventListener("click", (function(e) {
if (console.log("[ControlManager] 视频包装器点击事件触发"), e.target === t.uiElements.videoWrapper || e.target === t.targetVideo) {
if (t.clickLock) return void console.log("[ControlManager] 点击锁定中,忽略此次点击");
t.clickLock = !0, t.clickLockTimeout && clearTimeout(t.clickLockTimeout), t.clickLockTimeout = setTimeout((function() {
t.clickLock = !1, t.clickLockTimeout = null
}), 500), console.log("[ControlManager] 触发视频点击事件,当前状态:", t.targetVideo.paused ? "已暂停" : "正在播放"), t.targetVideo.paused ? t.targetVideo.play() : (t.targetVideo.pause(), t.showPauseIndicator()), t.updatePlayPauseButton()
}
})), this.targetVideo.addEventListener("play", (function() {
t.updatePlayPauseButton()
})), this.targetVideo.addEventListener("pause", (function() {
t.updatePlayPauseButton(), t.showPauseIndicator()
})), this.targetVideo.addEventListener("volumechange", (function() {
t.updateMuteButton()
})), this.targetVideo.addEventListener("ratechange", (function() {
if (t.playbackRateSlider) {
var e = t.targetVideo.playbackRate,
n = (e - .1) / 2.9 * 100;
t.updatePlaybackRateSlider && t.updatePlaybackRateSlider(n), t.showPlaybackRateIndicator(e)
}
}))
}
}, {
key: "createProgressControls",
value: function() {
var t = this;
this.progressControlsContainer = document.createElement("div"), this.progressControlsContainer.className = "tm-progress-controls";
var e = document.createElement("div");
e.className = "tm-time-display-container", this.currentTimeDisplay = document.createElement("span"), this.currentTimeDisplay.className = "tm-current-time", this.currentTimeDisplay.textContent = "00:00:00", this.totalDurationDisplay = document.createElement("span"), this.totalDurationDisplay.className = "tm-total-duration", this.totalDurationDisplay.textContent = "-00:00:00";
var n = document.createElement("div");
return n.className = "tm-progress-bar-container", this.progressBarElement = document.createElement("div"), this.progressBarElement.className = "tm-progress-bar", this.progressIndicator = document.createElement("div"), this.progressIndicator.className = "tm-progress-indicator", n.addEventListener("mouseenter", (function() {
t.progressBarElement.classList.add("tm-progress-bar-expanded")
})), n.addEventListener("mouseleave", (function() {
t.isDraggingProgress || (t.progressBarElement.classList.add("tm-progress-bar-normal"), t.progressBarElement.classList.remove("tm-progress-bar-expanded"))
})), n.addEventListener("touchstart", (function() {
t.progressBarElement.classList.add("tm-progress-bar-expanded"), t.progressBarElement.classList.remove("tm-progress-bar-normal")
}), {
passive: !0
}), n.addEventListener("touchend", (function() {
t.isDraggingProgress || (t.progressBarElement.classList.add("tm-progress-bar-normal"), t.progressBarElement.classList.remove("tm-progress-bar-expanded"))
})), this.loopStartMarker = document.createElement("div"), this.loopStartMarker.className = "tm-loop-marker tm-loop-start-marker", this.loopStartMarker.style.display = "none", this.loopEndMarker = document.createElement("div"), this.loopEndMarker.className = "tm-loop-marker tm-loop-end-marker", this.loopEndMarker.style.display = "none", this.loopRangeElement = document.createElement("div"), this.loopRangeElement.className = "tm-loop-range", this.loopRangeElement.style.display = "none", e.appendChild(this.currentTimeDisplay), e.appendChild(this.totalDurationDisplay), this.progressBarElement.appendChild(this.progressIndicator), n.appendChild(this.progressBarElement), n.appendChild(this.loopStartMarker), n.appendChild(this.loopEndMarker), n.appendChild(this.loopRangeElement), this.progressControlsContainer.appendChild(e), this.progressControlsContainer.appendChild(n), this.progressControlsContainer
}
}, {
key: "createControlButtonsContainer",
value: function() {
var t = this;
this.controlButtonsContainer = document.createElement("div"), this.controlButtonsContainer.className = "tm-control-buttons";
var e = document.createElement("div");
e.className = "tm-progress-row", e.appendChild(this.progressControlsContainer), this.controlButtonsContainer.appendChild(e);
var n = document.createElement("div");
n.className = "tm-seek-control-row";
var r = document.createElement("div");
r.className = "tm-loop-control-row";
var o = document.createElement("div");
o.className = "tm-time-display";
var i = document.createElement("div");
i.className = "tm-loop-control";
var a = document.createElement("div");
a.className = "tm-rewind-group";
var s = document.createElement("div");
s.className = "tm-forward-group";
var l = document.createElement("div");
l.className = "tm-rewind-buttons-container";
var c = document.createElement("div");
c.className = "tm-forward-buttons-container", a.appendChild(l), s.appendChild(c), n.appendChild(a), n.appendChild(s), this.addTimeControlButton(l, "-5s", (function() {
return t.seekRelative(-5)
})), this.addTimeControlButton(l, "-10s", (function() {
return t.seekRelative(-10)
})), this.addTimeControlButton(l, "-30s", (function() {
return t.seekRelative(-30)
})), this.addTimeControlButton(l, "-1m", (function() {
return t.seekRelative(-60)
})), this.addTimeControlButton(l, "-5m", (function() {
return t.seekRelative(-300)
})), this.addTimeControlButton(l, "-10m", (function() {
return t.seekRelative(-600)
})), this.addTimeControlButton(c, "+5s", (function() {
return t.seekRelative(5)
})), this.addTimeControlButton(c, "+10s", (function() {
return t.seekRelative(10)
})), this.addTimeControlButton(c, "+30s", (function() {
return t.seekRelative(30)
})), this.addTimeControlButton(c, "+1m", (function() {
return t.seekRelative(60)
})), this.addTimeControlButton(c, "+5m", (function() {
return t.seekRelative(300)
})), this.addTimeControlButton(c, "+10m", (function() {
return t.seekRelative(600)
})), this.currentPositionDisplay = document.createElement("span"), this.currentPositionDisplay.className = "tm-loop-start-position", this.currentPositionDisplay.textContent = "00:00:00", this.setLoopStartButton = document.createElement("span"), this.setLoopStartButton.className = "tm-set-loop-start-label", this.setLoopStartButton.innerHTML = "A", this.durationDisplay = document.createElement("span"), this.durationDisplay.className = "tm-loop-end-position", this.durationDisplay.textContent = "00:00:00", this.setLoopEndButton = document.createElement("span"), this.setLoopEndButton.className = "tm-set-loop-end-label", this.setLoopEndButton.innerHTML = "B";
var u = document.createElement("div");
u.className = "tm-start-time-container";
var d = document.createElement("div");
d.className = "tm-end-time-container", u.addEventListener("click", (function() {
t.loopManager ? t.loopManager.setLoopStart() : console.error("[ControlManager] 循环管理器未设置,无法调用setLoopStart")
})), u.addEventListener("mouseover", (function() {})), u.addEventListener("mouseout", (function() {})), d.addEventListener("click", (function() {
t.loopManager ? t.loopManager.setLoopEnd() : console.error("[ControlManager] 循环管理器未设置,无法调用setLoopEnd")
})), d.addEventListener("mouseover", (function() {})), d.addEventListener("mouseout", (function() {})), u.appendChild(this.setLoopStartButton), u.appendChild(this.currentPositionDisplay), d.appendChild(this.setLoopEndButton), d.appendChild(this.durationDisplay);
var h = document.createElement("div");
h.className = "tm-loop-toggle-button", h.innerHTML = '\n <span class="tm-loop-toggle-label">Loop</span>\n <svg width="12" height="12" style="vertical-align: middle;">\n <circle class="tm-loop-indicator-circle" cx="6" cy="6" r="5" fill="hsl(var(--shadcn-muted-foreground) / 0.5)"></circle>\n </svg>\n ', i.appendChild(h);
var p = h;
p.addEventListener("mouseover", (function() {})), p.addEventListener("mouseout", (function() {})), p.addEventListener("click", (function() {
t.loopManager ? t.loopManager.toggleLoop() : console.error("[ControlManager] 循环管理器未设置,无法调用toggleLoop")
})), this.loopToggleButton = p, o.appendChild(u), o.appendChild(d), r.appendChild(o), r.appendChild(i), this.controlButtonsContainer.appendChild(n), this.controlButtonsContainer.appendChild(r);
var f = document.createElement("div");
f.className = "tm-playback-control-row";
var m = document.createElement("div");
m.className = "tm-left-controls";
var v = document.createElement("div");
v.className = "tm-center-controls";
var g = document.createElement("div");
return g.className = "tm-right-controls", f.appendChild(m), f.appendChild(v), f.appendChild(g), this.muteButton = this.addControlButton(m, "", (function() {
t.targetVideo.muted = !t.targetVideo.muted, t.updateMuteButton()
})), this.playPauseButton = this.addControlButton(v, "", (function() {
t.targetVideo.paused ? (t.targetVideo.play(), t.updatePlayPauseButton()) : (t.targetVideo.pause(), t.updatePlayPauseButton())
})), this.createPlaybackRateSlider(g), this.controlButtonsContainer.appendChild(f), this.updatePlayPauseButton(), this.updateMuteButton(), this.controlButtonsContainer
}
}, {
key: "createPlaybackRateSlider",
value: function(t) {
var e = this,
n = document.createElement("div");
n.className = "tm-playback-rate-slider";
var r = !1,
o = 1,
i = null,
a = document.createElement("div");
a.className = "tm-slider-container";
var s = document.createElement("div");
s.className = "tm-slider-level";
var l = document.createElement("div");
l.className = "tm-slider-marks";
var c = [{
pos: Math.round(.4 / 2.9 * 100),
label: "0.5x"
}, {
pos: Math.round(.9 / 2.9 * 100),
label: "1.0x"
}, {
pos: Math.round(1.4 / 2.9 * 100),
label: "1.5x"
}, {
pos: Math.round(1.9 / 2.9 * 100),
label: "2.0x"
}, {
pos: Math.round(100),
label: "3.0x"
}];
c.forEach((function(t) {
var e = t.pos,
n = (t.label, document.createElement("div"));
n.className = "tm-slider-mark", n.style.left = "".concat(e, "%"), l.appendChild(n)
}));
var u = document.createElement("div");
u.className = "tm-slider-text";
var d = document.createElement("div");
d.className = "tm-speed-label", d.textContent = "Speed";
var h = document.createElement("div");
h.className = "tm-speed-value", h.textContent = "1.0x", u.appendChild(d), u.appendChild(h), a.appendChild(l), a.appendChild(s), a.appendChild(u), n.appendChild(a), t.appendChild(n);
var p = function(t) {
s.style.width = "".concat(t, "%");
var n = .1 + t / 100 * 2.9;
n = .1 * Math.round(n / .1), (n = Math.max(.1, Math.min(3, n))) !== o && (o = n, e.targetVideo.playbackRate = n, h.textContent = "".concat(n.toFixed(1), "x"), h.classList.remove("tm-speed-value-fast", "tm-speed-value-slow", "tm-speed-value-normal"), n > 1.5 ? h.classList.add("tm-speed-value-fast") : n < .8 ? h.classList.add("tm-speed-value-slow") : h.classList.add("tm-speed-value-normal"))
},
f = function(t) {
r && g(t)
},
m = function(t) {
r = !0, n.classList.add("dragging"), n.classList.add("tm-playback-slider-dragging"), g(t)
},
v = function() {
r && (r = !1, n.classList.remove("dragging"), n.classList.remove("tm-playback-slider-dragging"), n.classList.add("tm-playback-slider-default"), i && (cancelAnimationFrame(i), i = null))
},
g = function(t) {
t.preventDefault();
var e = t.type.includes("touch") ? t.touches[0].clientX : t.clientX,
n = a.getBoundingClientRect(),
r = n.width;
i && cancelAnimationFrame(i), i = requestAnimationFrame((function() {
var t = (e - n.left) / r * 100;
t = Math.max(0, Math.min(100, t));
var o, i = function(t, e) {
var n = "undefined" != typeof Symbol && t[Symbol.iterator] || t["@@iterator"];
if (!n) {
if (Array.isArray(t) || (n = function(t, e) {
if (t) {
if ("string" == typeof t) return w(t, e);
var n = {}.toString.call(t).slice(8, -1);
return "Object" === n && t.constructor && (n = t.constructor.name), "Map" === n || "Set" === n ? Array.from(t) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? w(t, e) : void 0
}
}(t)) || e && t && "number" == typeof t.length) {
n && (t = n);
var r = 0,
o = function() {};
return {
s: o,
n: function() {
return r >= t.length ? {
done: !0
} : {
done: !1,
value: t[r++]
}
},
e: function(t) {
throw t
},
f: o
}
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
}
var i, a = !0,
s = !1;
return {
s: function() {
n = n.call(t)
},
n: function() {
var t = n.next();
return a = t.done, t
},
e: function(t) {
s = !0, i = t
},
f: function() {
try {
a || null == n.return || n.return()
} finally {
if (s) throw i
}
}
}
}(c.map((function(t) {
return t.pos
})));
try {
for (i.s(); !(o = i.n()).done;) {
var a = o.value;
if (Math.abs(t - a) < 5) {
t = a, window.navigator.vibrate && window.navigator.vibrate(5);
break
}
}
} catch (t) {
i.e(t)
} finally {
i.f()
}
p(t)
}))
};
a.addEventListener("mousedown", m, {
passive: !1
}), a.addEventListener("touchstart", m, {
passive: !1
}), window.addEventListener("mousemove", f, {
passive: !1
}), window.addEventListener("touchmove", f, {
passive: !1
}), window.addEventListener("mouseup", v), window.addEventListener("touchend", v), window.addEventListener("mouseleave", v), n.addEventListener("dblclick", (function() {
p(30)
})), p(30), this.playbackRateSlider = n, this.updatePlaybackRateSlider = p
}
}, {
key: "updatePlayPauseButton",
value: function() {
this.playPauseButton && (this.targetVideo.paused ? this.playPauseButton.innerHTML = '\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M18 12L7 5V19L18 12Z" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ' : this.playPauseButton.innerHTML = '\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M10 4H6V20H10V4Z" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M18 4H14V20H18V4Z" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ')
}
}, {
key: "updateMuteButton",
value: function() {
this.muteButton && (this.targetVideo.muted ? this.muteButton.innerHTML = '\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M11 5L6 9H2V15H6L11 19V5Z" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M23 9L17 15" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M17 9L23 15" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ' : this.muteButton.innerHTML = '\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M11 5L6 9H2V15H6L11 19V5Z" fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M15.54 8.46C16.4774 9.39764 17.004 10.6692 17.004 11.995C17.004 13.3208 16.4774 14.5924 15.54 15.53" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M18.54 5.46C20.4246 7.34535 21.4681 9.90302 21.4681 12.575C21.4681 15.247 20.4246 17.8047 18.54 19.69" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ')
}
}, {
key: "updateProgressBar",
value: function() {
if (this.targetVideo && this.progressBarElement && this.progressIndicator) {
var t = this.targetVideo.currentTime,
e = this.targetVideo.duration;
if (!(isNaN(e) || e <= 0)) {
var n = t / e * 100;
this.progressIndicator.style.width = "".concat(n, "%"), this.updateCurrentTimeDisplay(), this.loopManager && this.loopManager.loopActive && null !== this.loopManager.loopStartTime && null !== this.loopManager.loopEndTime && t >= this.loopManager.loopEndTime && (this.targetVideo.currentTime = this.loopManager.loopStartTime)
}
}
}
}, {
key: "updateCurrentTimeDisplay",
value: function() {
if (this.targetVideo && this.currentTimeDisplay && this.totalDurationDisplay) {
var t = this.targetVideo.currentTime,
e = this.targetVideo.duration;
if (!isNaN(e)) {
this.currentTimeDisplay.textContent = this.formatTime(t);
var n = e - t;
this.totalDurationDisplay.textContent = "-".concat(this.formatTime(n))
}
}
}
}, {
key: "addTimeControlButton",
value: function(t, e, n) {
var r = function(t) {
var e = parseInt(t.replace(/[+-]/g, "")),
n = t.includes("m") ? "m" : "s",
r = .5;
return "s" === n ? r = e <= 5 ? .5 : e <= 10 ? .6 : .7 : "m" === n && (r = 1 === e ? .8 : 5 === e ? .9 : 1), r
}(e),
o = document.createElement("button");
o.className = "tm-time-control-button", o.style.backgroundColor = "hsl(var(--shadcn-secondary) / ".concat(r, ")");
var i = e.includes("-"),
a = e.includes("+"),
s = e.replace(/[+-]/g, "");
return i ? o.innerHTML = '<div class="tm-time-control-button-inner">'.concat('<svg width="14" height="14" viewBox="0 0 12 24" fill="none" class="tm-rewind-icon">\n <path fill-rule="evenodd" clip-rule="evenodd" d="M3.70711 4.29289C3.31658 3.90237 2.68342 3.90237 2.29289 4.29289L-4.70711 11.2929C-5.09763 11.6834 -5.09763 12.3166 -4.70711 12.7071L2.29289 19.7071C2.68342 20.0976 3.31658 20.0976 3.70711 19.7071C4.09763 19.3166 4.09763 18.6834 3.70711 18.2929L-2.58579 12L3.70711 5.70711C4.09763 5.31658 4.09763 4.68342 3.70711 4.29289Z" fill="currentColor"/>\n </svg>', '<span class="tm-time-text-margin-left">').concat(s, "</span></div>") : a ? o.innerHTML = '<div class="tm-time-control-button-inner"><span class="tm-time-text-margin-right">'.concat(s, "</span>").concat('<svg width="14" height="14" viewBox="0 0 12 24" fill="none" class="tm-forward-icon">\n <path fill-rule="evenodd" clip-rule="evenodd" d="M8.29289 4.29289C8.68342 3.90237 9.31658 3.90237 9.70711 4.29289L16.7071 11.2929C17.0976 11.6834 17.0976 12.3166 16.7071 12.7071L9.70711 19.7071C9.31658 20.0976 8.68342 20.0976 8.29289 19.7071C7.90237 19.3166 7.90237 18.6834 8.29289 18.2929L14.5858 12L8.29289 5.70711C7.90237 5.31658 7.90237 4.68342 8.29289 4.29289Z" fill="currentColor"/>\n </svg>', "</div>") : o.textContent = e, o.addEventListener("click", n), o.addEventListener("mouseover", (function() {
o.classList.add("tm-time-control-button-hover"), o.classList.remove("tm-time-control-button-default")
})), o.addEventListener("mouseout", (function() {
o.classList.add("tm-time-control-button-default"), o.classList.remove("tm-time-control-button-hover", "tm-time-control-button-active", "tm-time-control-button-after-active")
})), o.addEventListener("mousedown", (function() {
o.classList.add("tm-time-control-button-active"), o.classList.remove("tm-time-control-button-hover", "tm-time-control-button-default", "tm-time-control-button-after-active")
})), o.addEventListener("mouseup", (function() {
o.classList.add("tm-time-control-button-after-active"), o.classList.remove("tm-time-control-button-active", "tm-time-control-button-hover", "tm-time-control-button-default")
})), t.appendChild(o), o
}
}, {
key: "seekRelative",
value: function(t) {
if (this.targetVideo) {
var e = Math.max(0, Math.min(this.targetVideo.duration, this.targetVideo.currentTime + t));
this.targetVideo.currentTime = e
}
}
}, {
key: "formatTime",
value: function(t) {
var e = Math.floor(t / 3600),
n = Math.floor(t % 3600 / 60),
r = Math.floor(t % 60);
return "".concat(e, ":").concat(n.toString().padStart(2, "0"), ":").concat(r.toString().padStart(2, "0"))
}
}, {
key: "addControlButton",
value: function(t, e, n) {
var r = document.createElement("button");
return r.className = "tm-control-button", r.textContent = e, r.addEventListener("click", n), r.addEventListener("mouseover", (function() {
r.classList.add("tm-control-button-hover"), r.classList.remove("tm-control-button-default")
})), r.addEventListener("mouseout", (function() {
r.classList.add("tm-control-button-default"), r.classList.remove("tm-control-button-hover")
})), t.appendChild(r), r
}
}, {
key: "showPauseIndicator",
value: function() {
var t = this;
this.pauseIndicator && (this.pauseIndicator.parentNode && this.pauseIndicator.parentNode.removeChild(this.pauseIndicator), this.pauseIndicator = null), this.pauseIndicator = document.createElement("div"), this.pauseIndicator.className = "tm-indicator-base tm-pause-indicator", this.pauseIndicator.style.position = "absolute", this.pauseIndicator.style.top = "50%", this.pauseIndicator.style.left = "50%", this.pauseIndicator.style.transform = "translate(-50%, -50%)", this.pauseIndicator.style.display = "flex", this.pauseIndicator.style.justifyContent = "center", this.pauseIndicator.style.alignItems = "center", this.pauseIndicator.innerHTML = '\n <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M14,6v20c0,1.1-0.9,2-2,2H8c-1.1,0-2-0.9-2-2V6c0-1.1,0.9-2,2-2h4C13.1,4,14,4.9,14,6z M24,4h-4\n c-1.1,0-2,0.9-2,2v20c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2V6C26,4.9,25.1,4,24,4z" fill="white"/>\n </svg>\n ', this.uiElements.videoWrapper.appendChild(this.pauseIndicator), requestAnimationFrame((function() {
t.pauseIndicator.classList.add("visible")
})), setTimeout((function() {
t.pauseIndicator && (t.pauseIndicator.classList.remove("visible"), setTimeout((function() {
t.pauseIndicator && t.pauseIndicator.parentNode && (t.pauseIndicator.parentNode.removeChild(t.pauseIndicator), t.pauseIndicator = null)
}), 300))
}), 1e3)
}
}, {
key: "showPlaybackRateIndicator",
value: function(t) {
var e = this;
this.playbackRateIndicator && (clearTimeout(this.playbackRateIndicator.hideTimeout), this.playbackRateIndicator.parentNode && this.playbackRateIndicator.parentNode.removeChild(this.playbackRateIndicator), this.playbackRateIndicator = null), this.playbackRateIndicator = document.createElement("div"), this.playbackRateIndicator.className = "tm-indicator-base tm-playback-rate-indicator", this.playbackRateIndicator.style.position = "absolute", this.playbackRateIndicator.style.top = "20%", this.playbackRateIndicator.style.left = "50%", this.playbackRateIndicator.style.transform = "translateX(-50%)", this.playbackRateIndicator.textContent = "".concat(t.toFixed(1), "x"), t > 1.5 ? this.playbackRateIndicator.style.color = "hsl(var(--shadcn-orange))" : t < .8 && (this.playbackRateIndicator.style.color = "hsl(var(--shadcn-blue))"), this.uiElements.videoWrapper.appendChild(this.playbackRateIndicator), requestAnimationFrame((function() {
e.playbackRateIndicator.classList.add("visible")
})), this.playbackRateIndicator.hideTimeout = setTimeout((function() {
e.playbackRateIndicator && (e.playbackRateIndicator.classList.remove("visible"), setTimeout((function() {
e.playbackRateIndicator && e.playbackRateIndicator.parentNode && (e.playbackRateIndicator.parentNode.removeChild(e.playbackRateIndicator), e.playbackRateIndicator = null)
}), 300))
}), 1500)
}
}], e && k(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function S(t) {
return S = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, S(t)
}
function C(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, L(r.key), r)
}
}
function L(t) {
var e = function(t) {
if ("object" != S(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != S(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == S(e) ? e : e + ""
}
var P = function() {
return t = function t(e, n) {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.playerCore = e, this.targetVideo = e.targetVideo, this.uiElements = n, this.container = n.container, this.handle = n.handle, this.isDraggingHandle = !1, this.startX = 0, this.startY = 0, this.startWidth = 0, this.startHeight = 0, this.handleMoveHandler = null, this.handleEndHandler = null
}, e = [{
key: "init",
value: function() {
return this.handle.addEventListener("mousedown", this.startHandleDrag.bind(this)), this.handle.addEventListener("touchstart", this.startHandleDrag.bind(this), {
passive: !1
}), this
}
}, {
key: "updateHandlePosition",
value: function() {
if (this.uiElements.handleContainer && this.container) {
this.container.getBoundingClientRect();
var t = this.uiElements.videoWrapper.getBoundingClientRect();
this.uiElements.handleContainer.style.top = "".concat(t.bottom, "px")
}
}
}, {
key: "startHandleDrag",
value: function(t) {
this.isDraggingHandle = !0, this.handle.style.cursor = "grabbing";
var e = t.type.includes("touch");
this.startY = e ? t.touches[0].clientY : t.clientY, this.startHeight = this.container.offsetHeight;
var n = this._handleDragMove.bind(this),
r = this._handleDragEnd.bind(this);
e ? (document.addEventListener("touchmove", n, {
passive: !1
}), document.addEventListener("touchend", r), document.addEventListener("touchcancel", r)) : (document.addEventListener("mousemove", n), document.addEventListener("mouseup", r)), this.handleMoveHandler = n, this.handleEndHandler = r, t.preventDefault()
}
}, {
key: "_handleDragMove",
value: function(t) {
if (this.isDraggingHandle) {
t.preventDefault();
var e = (t.type.includes("touch") ? t.touches[0].clientY : t.clientY) - this.startY,
n = parseFloat(this.container.style.minHeight) || window.innerWidth * (9 / 16),
r = Math.max(n, this.startHeight + e);
this.container.style.height = r + "px"
}
}
}, {
key: "_handleDragEnd",
value: function(t) {
this.isDraggingHandle && (this.isDraggingHandle = !1, this.handle.style.cursor = "grab", document.removeEventListener("touchmove", this.handleMoveHandler), document.removeEventListener("touchend", this.handleEndHandler), document.removeEventListener("touchcancel", this.handleEndHandler), document.removeEventListener("mousemove", this.handleMoveHandler), document.removeEventListener("mouseup", this.handleEndHandler), this.handleMoveHandler = null, this.handleEndHandler = null, t.type.startsWith("touch") && t.preventDefault())
}
}, {
key: "handleMouseDown",
value: function(t) {
0 === t.button && (this.isDraggingHandle = !0, this.startY = t.clientY, this.startHeight = this.uiElements.handleContainer.offsetHeight, this.handleMoveHandler = this.handleMouseMove.bind(this), this.handleEndHandler = this.handleMouseUp.bind(this), document.addEventListener("mousemove", this.handleMoveHandler), document.addEventListener("mouseup", this.handleEndHandler), this.updateHandlePosition())
}
}, {
key: "handleMouseMove",
value: function(t) {
if (this.isDraggingHandle) {
var e = t.clientY - this.startY,
n = this.startHeight + e;
n < 50 || n > 200 || (this.uiElements.handleContainer.style.height = "".concat(n, "px"), this.updateHandlePosition())
}
}
}, {
key: "handleMouseUp",
value: function(t) {
this.isDraggingHandle = !1, document.removeEventListener("mousemove", this.handleMoveHandler), document.removeEventListener("mouseup", this.handleEndHandler), this.updateHandlePosition()
}
}, {
key: "handleMouseLeave",
value: function(t) {
this.isDraggingHandle = !1, document.removeEventListener("mousemove", this.handleMoveHandler), document.removeEventListener("mouseup", this.handleEndHandler), this.updateHandlePosition()
}
}], e && C(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function T(t) {
return T = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, T(t)
}
function M(t, e) {
(null == e || e > t.length) && (e = t.length);
for (var n = 0, r = Array(e); n < e; n++) r[n] = t[n];
return r
}
function B(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, V(r.key), r)
}
}
function V(t) {
var e = function(t) {
if ("object" != T(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != T(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == T(e) ? e : e + ""
}
var j = function() {
return t = function t(e, n) {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.playerCore = e, this.targetVideo = e.targetVideo, this.uiElements = n, this.loopStartTime = null, this.loopEndTime = null, this.loopActive = !1, this.loopStartMarker = null, this.loopEndMarker = null, this.loopRangeElement = null, this.currentPositionDisplay = null, this.durationDisplay = null, this.loopToggleButton = null, this._handleLoopTimeUpdate = this._handleLoopTimeUpdate.bind(this)
}, e = [{
key: "init",
value: function(t) {
return this.loopStartMarker = t.loopStartMarker, this.loopEndMarker = t.loopEndMarker, this.loopRangeElement = t.loopRangeElement, this.currentPositionDisplay = t.currentPositionDisplay, this.durationDisplay = t.durationDisplay, this.loopToggleButton = t.loopToggleButton, this._parseUrlHashParams(), this
}
}, {
key: "setState",
value: function(t) {
return console.log("[LoopManager] 状态更新:", Object.keys(t).map((function(e) {
return "".concat(e, ": ").concat(t[e])
})).join(", ")), Object.assign(this, t), this._updateUI(), this
}
}, {
key: "_parseUrlHashParams",
value: function() {
var t = this;
if (window.location.hash) {
var e = window.location.hash.substring(1);
if (e.includes("-")) {
var n = function(t, e) {
return function(t) {
if (Array.isArray(t)) return t
}(t) || function(t, e) {
var n = null == t ? null : "undefined" != typeof Symbol && t[Symbol.iterator] || t["@@iterator"];
if (null != n) {
var r, o, i, a, s = [],
l = !0,
c = !1;
try {
if (i = (n = n.call(t)).next, 0 === e) {
if (Object(n) !== n) return;
l = !1
} else
for (; !(l = (r = i.call(n)).done) && (s.push(r.value), s.length !== e); l = !0);
} catch (t) {
c = !0, o = t
} finally {
try {
if (!l && null != n.return && (a = n.return(), Object(a) !== a)) return
} finally {
if (c) throw o
}
}
return s
}
}(t, e) || function(t, e) {
if (t) {
if ("string" == typeof t) return M(t, e);
var n = {}.toString.call(t).slice(8, -1);
return "Object" === n && t.constructor && (n = t.constructor.name), "Map" === n || "Set" === n ? Array.from(t) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? M(t, e) : void 0
}
}(t, e) || function() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
}()
}(e.split("-"), 2),
r = n[0],
o = n[1],
i = this._parseTimeString(r),
a = this._parseTimeString(o);
if (null !== i && null !== a) {
console.log("[LoopManager] 从URL解析循环区间: ".concat(r, "-").concat(o));
var s = {
loopStartTime: i,
loopEndTime: a
},
l = function() {
t.targetVideo.currentTime = i, window.location.hostname.includes("missav") ? (s.loopActive = !0, console.log("[LoopManager] 在missav网站上设置循环状态")) : (s.loopActive = !0, console.log("[LoopManager] 在其他网站上设置循环状态")), t.setState(s), t.targetVideo.removeEventListener("timeupdate", t._handleLoopTimeUpdate), t.targetVideo.addEventListener("timeupdate", t._handleLoopTimeUpdate), t.targetVideo.paused && t.targetVideo.play().catch((function(e) {
console.log("视频自动播放被阻止: ", e), t.targetVideo.muted = !0, t.targetVideo.play().catch((function(t) {
console.error("即使静音也无法播放: ", t)
}))
})), t.targetVideo.removeEventListener("loadedmetadata", l)
};
this.targetVideo.readyState >= 1 ? l() : this.targetVideo.addEventListener("loadedmetadata", l)
}
} else if (e.match(/^\d{2}:\d{2}:\d{2}$/)) {
var c = this._parseTimeString(e);
if (null !== c) {
console.log("[LoopManager] 从URL解析时间点: ".concat(e));
var u = function() {
t.targetVideo.currentTime = c, t.setState({
loopStartTime: c
}), t.targetVideo.removeEventListener("loadedmetadata", u)
};
this.targetVideo.readyState >= 1 ? u() : this.targetVideo.addEventListener("loadedmetadata", u)
}
}
}
}
}, {
key: "_parseTimeString",
value: function(t) {
if (!t) return null;
var e = t.match(/^(\d{2}):(\d{2}):(\d{2})$/);
return e ? 3600 * parseInt(e[1], 10) + 60 * parseInt(e[2], 10) + parseInt(e[3], 10) : null
}
}, {
key: "_updateUrlHash",
value: function() {
var t = "";
if (null !== this.loopStartTime && (t = this.formatTimeWithHours(this.loopStartTime), null !== this.loopEndTime && (t += "-".concat(this.formatTimeWithHours(this.loopEndTime)))), t) {
var e = window.location.pathname + window.location.search + "#" + t;
window.history.replaceState(null, "", e), console.log("[LoopManager] 更新URL: ".concat(e))
}
}
}, {
key: "_clickCopyStartTime",
value: function() {
document.querySelector("input#clip-start-time + a").click()
}
}, {
key: "_clickCopyEndTime",
value: function() {
document.querySelector("input#clip-end-time + a").click()
}
}, {
key: "_toggleLooping",
value: function() {
document.querySelector(".sm\\:ml-6 button").click()
}
}, {
key: "setLoopEnd",
value: function() {
if (this.targetVideo) {
var t = this.targetVideo.currentTime;
if (window.location.hostname.includes("missav")) this._clickCopyEndTime(), this.setState({
loopEndTime: t
});
else {
if (null !== this.loopStartTime && t <= this.loopStartTime) return void console.log("[LoopManager] 循环结束点必须在开始点之后");
this.setState({
loopEndTime: t
}), console.log("[LoopManager] 设置循环结束点: ".concat(this.formatTimeWithHours(t))), this._updateUrlHash()
}
window.navigator.vibrate && window.navigator.vibrate(10)
}
}
}, {
key: "setLoopStart",
value: function() {
if (this.targetVideo) {
var t = this.targetVideo.currentTime;
if (window.location.hostname.includes("missav")) this._clickCopyStartTime(), this.setState({
loopStartTime: t
});
else {
if (null !== this.loopEndTime && t >= this.loopEndTime) return void console.log("[LoopManager] 循环开始点必须在结束点之前");
this.setState({
loopStartTime: t
}), console.log("[LoopManager] 设置循环开始点: ".concat(this.formatTimeWithHours(t))), this._updateUrlHash()
}
window.navigator.vibrate && window.navigator.vibrate(10)
}
}
}, {
key: "toggleLoop",
value: function() {
if (window.location.hostname.includes("missav")) this._toggleLooping();
else {
if (null === this.loopStartTime || null === this.loopEndTime) return void console.log("请先使用 A 和 B 按钮记录循环的开始和结束时间。");
this.loopActive ? this.disableLoop() : this.enableLoop()
}
}
}, {
key: "enableLoop",
value: function() {
var t = this;
this.targetVideo && null !== this.loopStartTime && null !== this.loopEndTime ? (console.log("[LoopManager] 启用循环播放: ".concat(this.formatTimeWithHours(this.loopStartTime), " - ").concat(this.formatTimeWithHours(this.loopEndTime))), this.setState({
loopActive: !0
}), this.targetVideo.removeEventListener("timeupdate", this._handleLoopTimeUpdate), this.targetVideo.addEventListener("timeupdate", this._handleLoopTimeUpdate), (this.targetVideo.currentTime < this.loopStartTime || this.targetVideo.currentTime > this.loopEndTime) && (this.targetVideo.currentTime = this.loopStartTime), this.targetVideo.paused && this.targetVideo.play().catch((function(e) {
console.log("视频自动播放被阻止: ", e), t.targetVideo.muted = !0, t.targetVideo.play().catch((function(t) {
console.error("即使静音也无法播放: ", t)
}))
})), window.navigator.vibrate && window.navigator.vibrate([10, 30, 10])) : console.log("[LoopManager] 无法启用循环: 循环点未设置")
}
}, {
key: "disableLoop",
value: function() {
this.loopActive && (console.log("[LoopManager] 禁用循环播放"), this.targetVideo.removeEventListener("timeupdate", this._handleLoopTimeUpdate), this.setState({
loopActive: !1
}))
}
}, {
key: "_handleLoopTimeUpdate",
value: function() {
if (this.loopActive && null !== this.loopStartTime && null !== this.loopEndTime) {
var t = this.targetVideo.currentTime;
(t >= this.loopEndTime || t < this.loopStartTime) && (this.targetVideo.currentTime = this.loopStartTime)
}
}
}, {
key: "_updateUI",
value: function() {
console.log("[LoopManager] 更新UI元素 - 循环状态:", this.loopActive ? "激活" : "未激活", "开始点:", null !== this.loopStartTime ? this.formatTimeWithHours(this.loopStartTime) : "未设置", "结束点:", null !== this.loopEndTime ? this.formatTimeWithHours(this.loopEndTime) : "未设置"), this.updateLoopTimeDisplay(), this.updateLoopMarkers(), this._updateLoopButtonStyle()
}
}, {
key: "_updateLoopButtonStyle",
value: function() {
if (this.loopToggleButton)
if (this.loopActive) {
this.loopToggleButton.classList.add("active");
var t = this.loopToggleButton.querySelector(".tm-loop-indicator-circle");
t && t.setAttribute("fill", "hsl(var(--shadcn-red))");
var e = this.loopToggleButton.querySelector(".tm-loop-toggle-label");
e && e.classList.add("active")
} else {
this.loopToggleButton.classList.remove("active");
var n = this.loopToggleButton.querySelector(".tm-loop-indicator-circle");
n && n.setAttribute("fill", "hsl(var(--shadcn-muted-foreground) / 0.5)");
var r = this.loopToggleButton.querySelector(".tm-loop-toggle-label");
r && r.classList.remove("active")
}
}
}, {
key: "_updateStartTimeContainerStyle",
value: function() {
var t = document.querySelector(".tm-start-time-container");
t && (null !== this.loopStartTime ? (this.currentPositionDisplay.textContent = this.formatTimeWithHours(this.loopStartTime), this.currentPositionDisplay.classList.add("active"), t.classList.add("active")) : (this.currentPositionDisplay.textContent = "00:00:00", this.currentPositionDisplay.classList.remove("active"), t.classList.remove("active")))
}
}, {
key: "_updateEndTimeContainerStyle",
value: function() {
var t = document.querySelector(".tm-end-time-container");
t && (null !== this.loopEndTime ? (this.durationDisplay.textContent = this.formatTimeWithHours(this.loopEndTime), this.durationDisplay.classList.add("active"), t.classList.add("active")) : (this.durationDisplay.textContent = "00:00:00", this.durationDisplay.classList.remove("active"), t.classList.remove("active")))
}
}, {
key: "updateLoopTimeDisplay",
value: function() {
this._updateStartTimeContainerStyle(), this._updateEndTimeContainerStyle()
}
}, {
key: "updateLoopMarkers",
value: function() {
var t = this;
if (this.targetVideo && this.loopStartMarker && this.loopEndMarker) {
var e = document.querySelector(".tm-progress-bar");
if (e) {
var n = e.offsetWidth,
r = this.targetVideo.duration;
if (!(r <= 0) && n) {
var o = function(e, n) {
var o = n ? t.loopStartMarker : t.loopEndMarker;
if (null !== e && !isNaN(e) && e >= 0 && e <= r) {
var i = e / r * 100;
o.style.left = "".concat(i, "%"), o.style.display = "block", t.loopActive ? o.classList.add("active") : o.classList.remove("active"), o.setAttribute("title", n ? "循环起点: ".concat(t.formatTimeWithHours(e)) : "循环终点: ".concat(t.formatTimeWithHours(e))), o.setAttribute("data-time", t.formatTimeWithHours(e))
} else o.style.display = "none"
};
if (o(this.loopStartTime, !0), o(this.loopEndTime, !1), this.loopActive && null !== this.loopStartTime && null !== this.loopEndTime) {
if (this.loopStartMarker.classList.add("active"), this.loopEndMarker.classList.add("active"), this.loopRangeElement) {
var i = this.loopStartTime / r * 100,
a = this.loopEndTime / r * 100 - i;
a > 0 ? (this.loopRangeElement.style.left = "".concat(i, "%"), this.loopRangeElement.style.width = "".concat(a, "%"), this.loopRangeElement.style.display = "block", this.loopRangeElement.classList.add("active")) : this.loopRangeElement.style.display = "none"
}
} else this.loopStartMarker.classList.remove("active"), this.loopEndMarker.classList.remove("active"), this.loopRangeElement && (this.loopRangeElement.classList.remove("active"), this.loopRangeElement.style.display = "none")
}
}
}
}
}, {
key: "formatTimeWithHours",
value: function(t) {
if (isNaN(t) || t < 0) return "00:00:00";
var e = Math.floor(t),
n = Math.floor(e / 3600),
r = Math.floor(e % 3600 / 60),
o = e % 60;
return "".concat(n.toString().padStart(2, "0"), ":").concat(r.toString().padStart(2, "0"), ":").concat(o.toString().padStart(2, "0"))
}
}], e && B(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function O(t) {
return O = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, O(t)
}
function D(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, H(r.key), r)
}
}
function H(t) {
var e = function(t) {
if ("object" != O(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != O(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == O(e) ? e : e + ""
}
var I = function() {
return t = function t(e, n) {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.playerCore = e, this.targetVideo = e.targetVideo, this.uiElements = n, this.progressBarElement = null, this.progressIndicator = null, this.currentTimeDisplay = null, this.totalDurationDisplay = null, this.timeIndicator = null, this.isDraggingProgress = !1, this.progressHandleMoveHandler = null, this.progressHandleUpHandler = null, this.lastDragX = 0, this.isTouchDevice = "ontouchstart" in window
}, e = [{
key: "init",
value: function(t) {
return this.progressBarElement = t.progressBarElement, this.progressIndicator = t.progressIndicator, this.currentTimeDisplay = t.currentTimeDisplay, this.totalDurationDisplay = t.totalDurationDisplay, this.timeIndicator = t.timeIndicator, this.progressBarContainer = this.progressBarElement.parentElement, this.progressBarElement.addEventListener("click", this.handleProgressClick.bind(this)), this.progressBarContainer.addEventListener("mousedown", this.startProgressDrag.bind(this)), this.progressBarContainer.addEventListener("touchstart", this.startProgressDrag.bind(this), {
passive: !1
}), this.targetVideo.addEventListener("timeupdate", this.updateProgressBar.bind(this)), this
}
}, {
key: "updateProgressBar",
value: function() {
if (this.targetVideo && this.progressBarElement && this.progressIndicator) {
var t = this.targetVideo.currentTime,
e = this.targetVideo.duration;
if (!(isNaN(e) || e <= 0)) {
var n = t / e * 100;
this.progressIndicator.style.width = "".concat(n, "%"), this.updateCurrentTimeDisplay()
}
}
}
}, {
key: "updateCurrentTimeDisplay",
value: function() {
if (this.targetVideo && this.currentTimeDisplay && this.totalDurationDisplay) {
var t = this.targetVideo.currentTime,
e = this.targetVideo.duration;
if (!isNaN(e)) {
this.currentTimeDisplay.textContent = this.formatTime(t);
var n = e - t;
this.totalDurationDisplay.textContent = "-".concat(this.formatTime(n))
}
}
}
}, {
key: "formatTime",
value: function(t) {
if (isNaN(t) || t < 0) return "00:00:00";
var e = Math.floor(t),
n = Math.floor(e / 3600),
r = Math.floor(e % 3600 / 60),
o = e % 60;
return "".concat(n.toString().padStart(2, "0"), ":").concat(r.toString().padStart(2, "0"), ":").concat(o.toString().padStart(2, "0"))
}
}, {
key: "handleProgressClick",
value: function(t) {
if (!this.isDraggingProgress) {
var e = this.progressBarElement.getBoundingClientRect(),
n = (t.clientX - e.left) / e.width,
r = this.targetVideo.duration;
if (!isNaN(r)) {
var o = r * n;
this.targetVideo.currentTime = o, this.updateProgressBar()
}
}
}
}, {
key: "seekRelative",
value: function(t) {
if (this.targetVideo) {
var e = Math.max(0, Math.min(this.targetVideo.duration, this.targetVideo.currentTime + t));
this.targetVideo.currentTime = e
}
}
}, {
key: "startProgressDrag",
value: function(t) {
t.preventDefault(), t.stopPropagation(), this.isDraggingProgress = !0, this.lastDragX = t.type.includes("touch") ? t.touches[0].clientX : t.clientX, this.progressBarElement.classList.add("tm-progress-bar-expanded"), this.progressBarElement.classList.remove("tm-progress-bar-normal"), this.progressBarElement.classList.add("tm-dragging"), this.timeIndicator && (this.timeIndicator.style.display = "block", this.timeIndicator.style.opacity = "1", this.updateTimeIndicator(t));
var e = this.handleProgressMove.bind(this),
n = this.handleProgressUp.bind(this);
this.removeProgressEventListeners(), t.type.includes("touch") ? (document.addEventListener("touchmove", e, {
passive: !1
}), document.addEventListener("touchend", n, {
passive: !1
}), document.addEventListener("touchcancel", n, {
passive: !1
})) : (document.addEventListener("mousemove", e), document.addEventListener("mouseup", n), document.addEventListener("mouseleave", n)), this.progressHandleMoveHandler = e, this.progressHandleUpHandler = n;
var r = this.progressBarElement.getBoundingClientRect(),
o = ((t.type.includes("touch") ? t.touches[0].clientX : t.clientX) - r.left) / r.width;
o = Math.max(0, Math.min(1, o));
var i = this.targetVideo.duration;
if (!isNaN(i)) {
var a = i * o;
this.targetVideo.currentTime = a, this.progressIndicator.style.width = "".concat(100 * o, "%"), this.updateCurrentTimeDisplay()
}
}
}, {
key: "handleProgressMove",
value: function(t) {
if (this.isDraggingProgress) {
t.preventDefault();
var e = t.type.includes("touch") ? t.touches[0].clientX : t.clientX;
this.updateTimeIndicator(t);
var n = this.progressBarElement.getBoundingClientRect();
if (!(n.width <= 0)) {
var r = (e - n.left) / n.width;
r = Math.max(0, Math.min(1, r));
var o = this.targetVideo.duration;
if (!isNaN(o)) {
var i = o * r;
this.progressIndicator.style.width = "".concat(100 * r, "%"), this.targetVideo.currentTime = i, this.currentTimeDisplay.textContent = this.formatTime(i);
var a = o - i;
this.totalDurationDisplay.textContent = "-".concat(this.formatTime(a)), this.lastDragX = e
}
}
}
}
}, {
key: "handleProgressUp",
value: function(t) {
if (this.isDraggingProgress) {
var e = this.progressBarElement.getBoundingClientRect(),
n = ((t.type.includes("touch") ? t.changedTouches && t.changedTouches[0] ? t.changedTouches[0].clientX : this.lastDragX : t.clientX || this.lastDragX) - e.left) / e.width;
n = Math.max(0, Math.min(1, n));
var r = this.targetVideo.duration;
isNaN(r) || (this.targetVideo.currentTime = r * n), this.timeIndicator && (this.timeIndicator.style.opacity = "0"), this.progressBarElement.classList.remove("tm-dragging"), this.progressBarElement.classList.contains("tm-progress-bar-hovered") || (this.progressBarElement.classList.add("tm-progress-bar-normal"), this.progressBarElement.classList.remove("tm-progress-bar-expanded")), this.isDraggingProgress = !1, this.lastDragX = 0, this.removeProgressEventListeners()
}
}
}, {
key: "removeProgressEventListeners",
value: function() {
this.progressHandleMoveHandler && (document.removeEventListener("mousemove", this.progressHandleMoveHandler), document.removeEventListener("touchmove", this.progressHandleMoveHandler)), this.progressHandleUpHandler && (document.removeEventListener("mouseup", this.progressHandleUpHandler), document.removeEventListener("touchend", this.progressHandleUpHandler), document.removeEventListener("touchcancel", this.progressHandleUpHandler), document.removeEventListener("mouseleave", this.progressHandleUpHandler)), this.progressHandleMoveHandler = null, this.progressHandleUpHandler = null
}
}, {
key: "updateTimeIndicator",
value: function(t) {
if (this.timeIndicator && this.targetVideo) {
var e = t.type.includes("touch") ? t.touches[0].clientX : t.clientX,
n = (t.type.includes("touch") ? t.touches[0].clientY : t.clientY, this.uiElements.videoWrapper.getBoundingClientRect()),
r = this.progressBarElement.getBoundingClientRect(),
o = Math.max(n.left + 10, Math.min(n.right - 10, e)),
i = r.top - 20;
this.timeIndicator.style.left = "".concat(o, "px"), this.timeIndicator.style.top = "".concat(i, "px");
var a = (e - r.left) / r.width,
s = Math.max(0, Math.min(1, a)),
l = this.targetVideo.duration;
if (!isNaN(l)) {
var c = l * s;
this.timeIndicator.textContent = "".concat(this.formatTime(c), " / ").concat(this.formatTime(l))
}
}
}
}], e && D(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function _(t) {
return _ = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, _(t)
}
function R(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, N(r.key), r)
}
}
function N(t) {
var e = function(t) {
if ("object" != _(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != _(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == _(e) ? e : e + ""
}
var A = function() {
return t = function t(e, n, r) {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.playerCore = e, this.targetVideo = e.targetVideo, this.uiElements = n, this.managers = r, this.resizeObserver = null, this.clickLock = !1, this.clickLockTimeout = null
}, e = [{
key: "init",
value: function() {
var t = this;
return this.handleVideoWrapperClickBound = this.handleVideoWrapperClick.bind(this), this.uiElements.videoWrapper.addEventListener("click", this.handleVideoWrapperClickBound), this.handleCloseButtonClickBound = this.handleCloseButtonClick.bind(this), this.uiElements.closeBtn.addEventListener("click", this.handleCloseButtonClickBound), this.handleWindowResizeBound = this.handleWindowResize.bind(this), window.addEventListener("resize", this.handleWindowResizeBound), this.handleContainerResizeBound = this.handleContainerResize.bind(this), this.resizeObserver = new ResizeObserver(this.handleContainerResizeBound), this.resizeObserver.observe(this.uiElements.container), this.initVideoEventListeners(), this.handleSettingsButtonClickBound = this.handleSettingsButtonClick.bind(this), this.uiElements.settingsBtn.addEventListener("click", this.handleSettingsButtonClickBound), this.handleOverlayTouchMoveBound = function(e) {
t.managers.uiManager && t.managers.uiManager.isLandscape && (t.managers.uiManager.showControls(), t.managers.uiManager.autoHideControls())
}, this.uiElements.overlay.addEventListener("touchmove", this.handleOverlayTouchMoveBound, {
passive: !0
}), this
}
}, {
key: "initVideoEventListeners",
value: function() {
var t = this;
this.handleMetadataLoadedBound = function() {
t.managers.progressManager && t.managers.progressManager.updateProgressBar(), t.managers.loopManager && (t.managers.loopManager.updateLoopTimeDisplay(), t.managers.loopManager.updateLoopMarkers()), t.managers.dragManager && t.managers.dragManager.updateHandlePosition(), t.managers.uiManager && t.managers.uiManager.updateContainerMinHeight(), t.managers.swipeManager && t.managers.swipeManager.updateSize()
}, this.targetVideo.addEventListener("loadedmetadata", this.handleMetadataLoadedBound), this.handleCanPlayBound = function() {
t.managers.uiManager && t.managers.uiManager.updateContainerMinHeight(), t.managers.swipeManager && t.managers.swipeManager.updateSize()
}, this.targetVideo.addEventListener("canplay", this.handleCanPlayBound), this.handleVideoResizeBound = function() {
t.managers.uiManager && t.managers.uiManager.updateContainerMinHeight(), t.managers.swipeManager && t.managers.swipeManager.updateSize()
}, this.targetVideo.addEventListener("resize", this.handleVideoResizeBound), this.handlePlayBound = function() {
t.managers.controlManager && t.managers.controlManager.updatePlayPauseButton()
}, this.targetVideo.addEventListener("play", this.handlePlayBound), this.handlePauseBound = function() {
t.managers.controlManager && (t.managers.controlManager.updatePlayPauseButton(), t.managers.controlManager.showPauseIndicator())
}, this.targetVideo.addEventListener("pause", this.handlePauseBound)
}
}, {
key: "handleVideoWrapperClick",
value: function(t) {
var e = this;
if (console.log("[EventManager] 视频包装器点击事件触发"), t.target === this.uiElements.videoWrapper || t.target === this.targetVideo) {
if (this.clickLock) return void console.log("[EventManager] 点击锁定中,忽略此次点击");
if (this.managers.swipeManager && "function" == typeof this.managers.swipeManager.wasRecentlyDragging && this.managers.swipeManager.wasRecentlyDragging()) return void console.log("[EventManager] 忽略拖动后的点击");
this.clickLock = !0, this.clickLockTimeout && clearTimeout(this.clickLockTimeout), this.clickLockTimeout = setTimeout((function() {
e.clickLock = !1, e.clickLockTimeout = null
}), 500), console.log("[EventManager] 触发视频点击事件,当前状态:", this.targetVideo.paused ? "已暂停" : "正在播放"), this.targetVideo.paused ? this.targetVideo.play() : (this.targetVideo.pause(), this.managers.controlManager && this.managers.controlManager.showPauseIndicator()), this.managers.controlManager && this.managers.controlManager.updatePlayPauseButton()
}
}
}, {
key: "handleCloseButtonClick",
value: function() {
console.log("[EventManager] 处理关闭按钮点击"), this.cleanup(), this.playerCore.close(this.uiElements.overlay, this.uiElements.container)
}
}, {
key: "handleSettingsButtonClick",
value: function() {
this.managers.settingsManager && this.managers.settingsManager.toggleSettingsPanel()
}
}, {
key: "handleWindowResize",
value: function() {
this.managers.uiManager && this.managers.uiManager.updateContainerMinHeight(), this.managers.dragManager && this.managers.dragManager.updateHandlePosition(), this.managers.swipeManager && this.managers.swipeManager.updateSize()
}
}, {
key: "handleContainerResize",
value: function() {
this.managers.dragManager && this.managers.dragManager.updateHandlePosition(), this.managers.swipeManager && this.managers.swipeManager.updateSize()
}
}, {
key: "cleanup",
value: function() {
console.log("[EventManager] 清理所有事件监听器"), window.removeEventListener("resize", this.handleWindowResizeBound), this.resizeObserver && (this.resizeObserver.disconnect(), this.resizeObserver = null), this.clickLockTimeout && (clearTimeout(this.clickLockTimeout), this.clickLockTimeout = null), this.uiElements.videoWrapper && this.uiElements.videoWrapper.removeEventListener("click", this.handleVideoWrapperClickBound), this.uiElements.closeBtn && this.uiElements.closeBtn.removeEventListener("click", this.handleCloseButtonClickBound), this.uiElements.settingsBtn && this.uiElements.settingsBtn.removeEventListener("click", this.handleSettingsButtonClickBound), this.targetVideo && (this.targetVideo.removeEventListener("loadedmetadata", this.handleMetadataLoadedBound), this.targetVideo.removeEventListener("canplay", this.handleCanPlayBound), this.targetVideo.removeEventListener("resize", this.handleVideoResizeBound), this.targetVideo.removeEventListener("play", this.handlePlayBound), this.targetVideo.removeEventListener("pause", this.handlePauseBound)), this.uiElements.overlay && this.uiElements.overlay.removeEventListener("touchmove", this.handleOverlayTouchMoveBound)
}
}], e && R(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function z(t) {
return z = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, z(t)
}
function W(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, U(r.key), r)
}
}
function U(t) {
var e = function(t) {
if ("object" != z(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != z(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == z(e) ? e : e + ""
}
var q = function() {
return t = function t(e, n) {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.playerCore = e, this.targetVideo = e.targetVideo, this.uiElements = n, this.settingsPanel = n.settingsPanel, this.overlayClickHandler = null, this.settings = {
showSeekControlRow: !0,
showLoopControlRow: !0,
showPlaybackControlRow: !0,
showProgressBar: !0
}
}, e = [{
key: "init",
value: function() {
return this.loadSettings(), this.createSettingsPanel(), this
}
}, {
key: "createSettingsPanel",
value: function() {
var t = this,
e = document.createElement("div");
e.className = "tm-settings-options", e.style.display = "flex", e.style.flexDirection = "column", e.style.gap = "12px";
var n = this.createSettingOption("显示-进度条", "showProgressBar", this.settings.showProgressBar, (function(e) {
t.settings.showProgressBar = e, t.saveSettings(), t.updateControlRowsVisibility()
})),
r = this.createSettingOption("显示-进度跳转", "showSeekControlRow", this.settings.showSeekControlRow, (function(e) {
t.settings.showSeekControlRow = e, t.saveSettings(), t.updateControlRowsVisibility()
})),
o = this.createSettingOption("显示-循环控制", "showLoopControlRow", this.settings.showLoopControlRow, (function(e) {
t.settings.showLoopControlRow = e, t.saveSettings(), t.updateControlRowsVisibility()
})),
i = this.createSettingOption("显示-播放倍速", "showPlaybackControlRow", this.settings.showPlaybackControlRow, (function(e) {
t.settings.showPlaybackControlRow = e, t.saveSettings(), t.updateControlRowsVisibility()
}));
e.appendChild(n), e.appendChild(r), e.appendChild(o), e.appendChild(i), this.settingsPanel.appendChild(e)
}
}, {
key: "createSettingOption",
value: function(t, e, n, r) {
var o = document.createElement("div");
o.className = "tm-settings-option", o.id = "tm-setting-".concat(e);
var i = document.createElement("label");
i.className = "tm-settings-label", i.textContent = t, i.style.cursor = "pointer", i.style.flex = "1";
var a = document.createElement("div");
a.className = "tm-toggle-switch";
var s = document.createElement("input");
s.type = "checkbox", s.checked = n, s.style.position = "absolute", s.style.left = "-9999px";
var l = document.createElement("span");
l.className = n ? "tm-toggle-slider checked" : "tm-toggle-slider", o.tabIndex = 0, a.appendChild(s), a.appendChild(l);
var c = function(t) {
t.preventDefault(), t.stopPropagation(), s.checked = !s.checked, s.checked ? l.className = "tm-toggle-slider checked" : l.className = "tm-toggle-slider", "function" == typeof r && r(s.checked)
};
return o.addEventListener("click", c), o.addEventListener("keydown", (function(t) {
"Enter" !== t.key && " " !== t.key || (t.preventDefault(), c(t))
})), o.appendChild(i), o.appendChild(a), o
}
}, {
key: "toggleSettingsPanel",
value: function() {
var t = this;
this.settingsPanel.classList.contains("active") ? this.closeSettingsPanel() : (this.settingsPanel.style.display = "block", setTimeout((function() {
t.settingsPanel.classList.add("active")
}), 10), this.overlayClickHandler = function(e) {
t.settingsPanel.contains(e.target) || e.target === t.uiElements.settingsBtn || t.closeSettingsPanel()
}, setTimeout((function() {
t.uiElements.overlay && t.uiElements.overlay.addEventListener("click", t.overlayClickHandler)
}), 50))
}
}, {
key: "closeSettingsPanel",
value: function() {
var t = this;
this.settingsPanel.classList.remove("active"), this.uiElements.overlay && this.overlayClickHandler && (this.uiElements.overlay.removeEventListener("click", this.overlayClickHandler), this.overlayClickHandler = null), setTimeout((function() {
t.settingsPanel.style.display = "none"
}), 300)
}
}, {
key: "loadSettings",
value: function() {
try {
var t = function(t, e) {
try {
if ("function" == typeof GM_getValue) return GM_getValue(t, e);
var n = localStorage.getItem("missNoAD_".concat(t));
return null !== n ? JSON.parse(n) : e
} catch (n) {
return console.debug("获取".concat(t, "设置失败:"), n), e
}
};
this.settings.showProgressBar = t("showProgressBar", !0), this.settings.showSeekControlRow = t("showSeekControlRow", !0), this.settings.showLoopControlRow = t("showLoopControlRow", !0), this.settings.showPlaybackControlRow = t("showPlaybackControlRow", !0)
} catch (t) {
console.error("加载设置时出错:", t)
}
}
}, {
key: "saveSettings",
value: function() {
try {
var t = function(t, e) {
try {
return "function" == typeof GM_setValue ? (GM_setValue(t, e), !0) : (localStorage.setItem("missNoAD_".concat(t), JSON.stringify(e)), !0)
} catch (e) {
return console.debug("保存".concat(t, "设置失败:"), e), !1
}
};
t("showProgressBar", this.settings.showProgressBar), t("showSeekControlRow", this.settings.showSeekControlRow), t("showLoopControlRow", this.settings.showLoopControlRow), t("showPlaybackControlRow", this.settings.showPlaybackControlRow)
} catch (t) {
console.error("保存设置时出错:", t)
}
}
}, {
key: "updateControlRowsVisibility",
value: function() {
var t = document.querySelector(".tm-control-buttons");
if (t) {
var e = t.querySelector(".tm-seek-control-row"),
n = t.querySelector(".tm-loop-control-row"),
r = t.querySelector(".tm-playback-control-row"),
o = t.querySelector(".tm-progress-row");
o && (o.style.display = this.settings.showProgressBar ? "flex" : "none"), e && (e.style.display = this.settings.showSeekControlRow ? "flex" : "none"), n && (n.style.display = this.settings.showLoopControlRow ? "flex" : "none"), r && (r.style.display = this.settings.showPlaybackControlRow ? "flex" : "none")
}
}
}, {
key: "updateSetting",
value: function(t, e) {
this.settings.hasOwnProperty(t) && (this.settings[t] = e, this.saveSettings(), t.startsWith("show") && t.endsWith("Row") && this.updateControlRowsVisibility())
}
}], e && W(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function F(t) {
return F = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, F(t)
}
function X(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, G(r.key), r)
}
}
function G(t) {
var e = function(t) {
if ("object" != F(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != F(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == F(e) ? e : e + ""
}
var Y = function() {
return t = function t(e, n, r) {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.video = e, this.container = n, this.handle = r, this.offset = 0, this.maxOffset = 0, this.isDragging = !1, this.isHandleDragging = !1, this.startX = 0, this.startOffset = 0, this.lastSnapPosition = null, this.wasDragging = !1, this.dragEndTimestamp = 0, this.dragDistance = 0, this.minDragDistance = 10, this.videoWidth = 0, this.videoHeight = 0, this.containerWidth = 0, this.containerHeight = 0, this.videoScale = 1, this.velocityTracker = {
positions: [],
lastTimestamp: 0,
currentVelocity: 0
}, this.handleVelocityTracker = {
positions: [],
lastTimestamp: 0,
currentVelocity: 0
}, this.animation = {
active: !1,
rafId: null,
targetOffset: 0,
startTime: 0,
duration: 0
}, this._pointerDownHandler = this._handlePointerDown.bind(this), this._pointerMoveHandler = this._handlePointerMove.bind(this), this._pointerUpHandler = this._handlePointerUp.bind(this), this._handlePointerDownHandler = this._handleHandlePointerDown.bind(this), this._handlePointerMoveHandler = this._handleHandlePointerMove.bind(this), this._handlePointerUpHandler = this._handleHandlePointerUp.bind(this), this._init()
}, e = [{
key: "_init",
value: function() {
var t = this;
console.log("[VideoSwipeManager] 初始化管理器"), this.video.style.willChange = "transform", this.video.style.transition = "transform 0.2s cubic-bezier(0.215, 0.61, 0.355, 1)", this.video.addEventListener("pointerdown", this._pointerDownHandler), this.handle && (this.handle.style.willChange = "transform, left", this.handle.style.transition = "left 0.2s cubic-bezier(0.215, 0.61, 0.355, 1), width 0.2s ease", this.handle.addEventListener("pointerdown", this._handlePointerDownHandler)), this._updateConstraints(), this.video.addEventListener("loadedmetadata", (function() {
console.log("[VideoSwipeManager] 视频元数据加载完成,更新约束"), t._updateConstraints()
})), this.video.addEventListener("canplay", (function() {
console.log("[VideoSwipeManager] 视频可播放,更新约束"), t._updateConstraints()
}))
}
}, {
key: "_updateVideoDimensions",
value: function() {
if (this.videoWidth = this.video.videoWidth || this.video.naturalWidth || 0, this.videoHeight = this.video.videoHeight || this.video.naturalHeight || 0, this.containerWidth = this.container.offsetWidth, this.containerHeight = this.container.offsetHeight, this.videoWidth <= 0 || this.videoHeight <= 0 || this.containerWidth <= 0 || this.containerHeight <= 0) return this.videoScale = 1, this.maxOffset = 0, !1;
var t = this.video.getBoundingClientRect(),
e = t.width,
n = t.height;
this.videoScale = n / this.videoHeight;
var r = Math.max(0, e - this.containerWidth);
return this.maxOffset = r / 2, !0
}
}, {
key: "_updateConstraints",
value: function() {
return !this._updateVideoDimensions() || this.maxOffset <= 0 ? (this._applyOffset(0, !1), this._updateHandleState(!1), !1) : (this.offset = Math.max(-this.maxOffset, Math.min(this.offset, this.maxOffset)), this._applyOffset(this.offset, !1), this._updateHandleState(!0), !0)
}
}, {
key: "_applyOffset",
value: function(t) {
var e = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1];
return this.offset = Math.max(-this.maxOffset, Math.min(t, this.maxOffset)), this.video.style.transition = e ? "transform 0.2s cubic-bezier(0.215, 0.61, 0.355, 1)" : "none", this.video.style.transform = "translateX(".concat(this.offset, "px)"), this._updateHandlePosition(), this
}
}, {
key: "_updateHandleState",
value: function(t) {
if (this.handle) {
if (this._updateHandleWidth(), t) {
this.handle.style.cursor = "grab", this.video.style.cursor = "grab";
var e = this.handle.parentElement;
e && (e.style.cursor = "grab")
} else this.handle.style.cursor = "default", this.video.style.cursor = "default";
this._updateHandlePosition()
}
}
}, {
key: "_updateHandleWidth",
value: function() {
this.handle && (this.handle.style.width = "".concat(30, "%"))
}
}, {
key: "_updateHandlePosition",
value: function() {
if (this.handle) {
var t = this.handle.parentElement;
if (t) {
if (this.maxOffset <= 0) return this.handle.style.left = "50%", void(this.handle.style.transform = "translateX(-50%)");
var e = t.offsetWidth,
n = e - this.handle.offsetWidth,
r = (1 - (this.offset + this.maxOffset) / (2 * this.maxOffset)) * n / e * 100;
this.handle.style.left = "".concat(r, "%"), this.handle.style.transform = ""
}
}
}
}, {
key: "_trackVelocity",
value: function(t) {
var e = Date.now(),
n = this.velocityTracker;
for (n.positions.push({
x: t,
time: e
}); n.positions.length > 1 && e - n.positions[0].time > 100;) n.positions.shift();
if (n.positions.length > 1) {
var r = n.positions[0],
o = n.positions[n.positions.length - 1],
i = o.time - r.time;
i > 0 && (n.currentVelocity = (o.x - r.x) / i)
}
n.lastTimestamp = e
}
}, {
key: "_applyInertia",
value: function() {
if (!(Math.abs(this.velocityTracker.currentVelocity) < .1)) {
var t = this.velocityTracker.currentVelocity,
e = t * t / .004 * Math.sign(t),
n = this.offset + e;
n = Math.max(-this.maxOffset, Math.min(n, this.maxOffset));
var r = Math.min(.8 * Math.abs(t / .002), 400);
this._animateTo(n, r)
}
}
}, {
key: "_animateTo",
value: function(t) {
var e = this,
n = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 300;
this.animation.active && cancelAnimationFrame(this.animation.rafId), this.animation.active = !0, this.animation.targetOffset = t, this.animation.startTime = Date.now(), this.animation.duration = n;
var r = function() {
var o = Date.now() - e.animation.startTime;
if (o >= n) return e._applyOffset(t, !1), void(e.animation.active = !1);
var i = 1 - Math.pow(1 - o / n, 3),
a = e.offset + (t - e.offset) * i;
e._applyOffset(a, !1), e.animation.rafId = requestAnimationFrame(r)
};
this.animation.rafId = requestAnimationFrame(r)
}
}, {
key: "_handlePointerDown",
value: function(t) {
this.maxOffset <= 0 || t.isPrimary && (this.animation.active && (cancelAnimationFrame(this.animation.rafId), this.animation.active = !1), this.isDragging = !0, this.startX = t.clientX, this.startOffset = this.offset, this.dragDistance = 0, this.velocityTracker.positions = [], this.velocityTracker.lastTimestamp = Date.now(), this.velocityTracker.currentVelocity = 0, this._trackVelocity(t.clientX), this.video.style.cursor = "grabbing", this.video.style.transition = "none", this.video.setPointerCapture && this.video.setPointerCapture(t.pointerId), this.video.addEventListener("pointermove", this._pointerMoveHandler), this.video.addEventListener("pointerup", this._pointerUpHandler), this.video.addEventListener("pointercancel", this._pointerUpHandler), window.navigator.vibrate && window.navigator.vibrate(5), t.preventDefault())
}
}, {
key: "_handlePointerMove",
value: function(t) {
if (this.isDragging && t.isPrimary) {
var e = t.clientX - this.startX;
this.dragDistance = Math.max(this.dragDistance, Math.abs(e));
var n = Math.max(-this.maxOffset, Math.min(this.startOffset + e, this.maxOffset));
this._applyOffset(n, !1), this._trackVelocity(t.clientX), t.preventDefault()
}
}
}, {
key: "_handlePointerUp",
value: function(t) {
this.isDragging && t.isPrimary && (this.isDragging = !1, this.dragDistance > this.minDragDistance ? (this.wasDragging = !0, this.dragEndTimestamp = Date.now()) : this.wasDragging = !1, this.video.releasePointerCapture && this.video.releasePointerCapture(t.pointerId), this.video.removeEventListener("pointermove", this._pointerMoveHandler), this.video.removeEventListener("pointerup", this._pointerUpHandler), this.video.removeEventListener("pointercancel", this._pointerUpHandler), this.video.style.cursor = "grab", this._applyInertia(), t.preventDefault())
}
}, {
key: "_handleHandlePointerDown",
value: function(t) {
if (!(this.maxOffset <= 0) && t.isPrimary) {
this.animation.active && (cancelAnimationFrame(this.animation.rafId), this.animation.active = !1), this.isHandleDragging = !0, this.startX = t.clientX, this.dragDistance = 0, this.startOffset = this.offset;
var e = this.handle.parentElement,
n = e ? e.offsetWidth : 0;
if (n > 0) {
var r = this.handle.getBoundingClientRect();
this.startHandleLeft = r.left - e.getBoundingClientRect().left, this.startHandleLeftPercent = this.startHandleLeft / n * 100
} else this.startHandleLeft = 0, this.startHandleLeftPercent = 0;
this.handle.style.cursor = "grabbing", this.handle.style.transition = "none", this.handle.setPointerCapture && this.handle.setPointerCapture(t.pointerId), this.handle.addEventListener("pointermove", this._handlePointerMoveHandler), this.handle.addEventListener("pointerup", this._handlePointerUpHandler), this.handle.addEventListener("pointercancel", this._handlePointerUpHandler), window.navigator.vibrate && window.navigator.vibrate(5), t.preventDefault()
}
}
}, {
key: "_handleHandlePointerMove",
value: function(t) {
if (this.isHandleDragging && t.isPrimary) {
var e = this.handle.parentElement;
if (e) {
var n = e.offsetWidth,
r = this.handle.offsetWidth;
if (!(n <= 0 || r <= 0)) {
var o = t.clientX - this.startX;
this.dragDistance = Math.max(this.dragDistance, Math.abs(o));
var i = this.startHandleLeft + o,
a = n - r;
i = Math.max(0, Math.min(i, a)), this._trackHandleVelocity(i);
for (var s = !1, l = 0, c = [0, a / 2, a]; l < c.length; l++) {
var u = c[l];
if (Math.abs(i - u) < 15) {
i = u, s = !0, !window.navigator.vibrate || this.lastSnapPosition && this.lastSnapPosition === u || (window.navigator.vibrate(15), this.lastSnapPosition = u);
break
}
}
s || (this.lastSnapPosition = null);
var d = i / n * 100;
this.handle.style.left = "".concat(d, "%");
var h = 2 * (1 - (a > 0 ? i / a : 0)) * this.maxOffset - this.maxOffset;
this.video.style.transform = "translateX(".concat(h, "px)"), this.video.style.transition = "none", this.offset = h, t.preventDefault()
}
}
}
}
}, {
key: "_handleHandlePointerUp",
value: function(t) {
this.isHandleDragging && t.isPrimary && (this.isHandleDragging = !1, this.dragDistance > this.minDragDistance ? (this.wasDragging = !0, this.dragEndTimestamp = Date.now()) : this.wasDragging = !1, this.lastSnapPosition = null, this.handle.releasePointerCapture && this.handle.releasePointerCapture(t.pointerId), this.handle.removeEventListener("pointermove", this._handlePointerMoveHandler), this.handle.removeEventListener("pointerup", this._handlePointerUpHandler), this.handle.removeEventListener("pointercancel", this._handlePointerUpHandler), this.handle.style.cursor = "grab", this._applyHandleInertia(), t.preventDefault())
}
}, {
key: "_trackHandleVelocity",
value: function(t) {
var e = Date.now(),
n = this.handleVelocityTracker;
for (n.positions.push({
position: t,
time: e
}); n.positions.length > 1 && e - n.positions[0].time > 100;) n.positions.shift();
if (n.positions.length > 1) {
var r = n.positions[0],
o = n.positions[n.positions.length - 1],
i = o.time - r.time;
i > 0 && (n.currentVelocity = (o.position - r.position) / i)
}
n.lastTimestamp = e
}
}, {
key: "_applyHandleInertia",
value: function() {
if (!(Math.abs(this.handleVelocityTracker.currentVelocity) < .1)) {
var t = this.handle.parentElement;
if (t) {
for (var e = t.offsetWidth, n = e - this.handle.offsetWidth, r = this.handle.getBoundingClientRect(), o = t.getBoundingClientRect(), i = r.left - o.left, a = this.handleVelocityTracker.currentVelocity, s = i + a * a / .004 * Math.sign(a), l = [0, n / 2, n], c = s = Math.max(0, Math.min(s, n)), u = Number.MAX_VALUE, d = 0, h = l; d < h.length; d++) {
var p = h[d],
f = Math.abs(s - p);
f < 30 && f < u && (c = p, u = f)
}
u < Number.MAX_VALUE && (s = c);
var m = s / e * 100,
v = 2 * (1 - (n > 0 ? s / n : 0)) * this.maxOffset - this.maxOffset;
this.handle.style.transition = "left 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)", this.video.style.transition = "transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)", this.handle.style.left = "".concat(m, "%"), this.video.style.transform = "translateX(".concat(v, "px)"), this.offset = v, u < Number.MAX_VALUE && window.navigator.vibrate && window.navigator.vibrate(10), this.handleVelocityTracker.positions = [], this.handleVelocityTracker.currentVelocity = 0
}
}
}
}, {
key: "setOffset",
value: function(t) {
var e = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1];
return this._applyOffset(t, e)
}
}, {
key: "reset",
value: function() {
var t = !(arguments.length > 0 && void 0 !== arguments[0]) || arguments[0];
return this._applyOffset(0, t), this.wasDragging = !1, this
}
}, {
key: "updateSize",
value: function() {
if (console.log("[VideoSwipeManager] 更新尺寸和约束"), this.video && this.container) {
var t = this.video.getBoundingClientRect(),
e = this.container.getBoundingClientRect();
console.log("[VideoSwipeManager] 视频尺寸: ".concat(t.width, "x").concat(t.height, ", 容器尺寸: ").concat(e.width, "x").concat(e.height));
var n = this._updateConstraints();
console.log("[VideoSwipeManager] 约束更新结果: ".concat(n, ", 最大偏移量: ").concat(this.maxOffset))
} else console.error("[VideoSwipeManager] 视频或容器元素不存在");
return this
}
}, {
key: "destroy",
value: function() {
this.video && (this.video.removeEventListener("pointerdown", this._pointerDownHandler), this.video.style.transform = "", this.video.style.willChange = "", this.video.style.transition = "", this.video.style.cursor = ""), this.handle && (this.handle.removeEventListener("pointerdown", this._handlePointerDownHandler), this.handle.style.willChange = "", this.handle.style.transition = "", this.handle.style.left = "", this.handle.style.width = "", this.handle.style.cursor = ""), this.animation.active && (cancelAnimationFrame(this.animation.rafId), this.animation.active = !1), this.wasDragging = !1
}
}, {
key: "wasRecentlyDragging",
value: function() {
var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 150;
return !(!this.wasDragging || Date.now() - this.dragEndTimestamp > t && (this.wasDragging = !1, 1))
}
}], e && X(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function Q(t) {
return Q = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, Q(t)
}
function Z(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, $(r.key), r)
}
}
function $(t) {
var e = function(t) {
if ("object" != Q(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != Q(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == Q(e) ? e : e + ""
}
var J = function() {
return t = function t() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), console.log("[CustomVideoPlayer] 初始化..."), this.playerCore = new f(e), this.callingButton = e.callingButton || null, this.managers = {}, this.initialized = !1
}, (e = [{
key: "init",
value: function() {
var t = this;
if (!this.initialized) {
if (this.playerCore || (this.playerCore = new f({
callingButton: this.callingButton
})), this.playerCore.init(), !this.playerCore.targetVideo) return console.error("[CustomVideoPlayer] 核心初始化失败: 未找到视频元素"), void(this.callingButton && (this.callingButton.style.display = "flex"));
var e = new y(this.playerCore),
n = e.createUI();
this.managers.uiManager = e, e.assembleDOM();
var r = new q(this.playerCore, n);
r.init(), this.managers.settingsManager = r;
var o = new E(this.playerCore, n),
i = (o.createProgressControls(), o.createControlButtonsContainer());
this.managers.controlManager = o, n.overlay.appendChild(i);
var a = new I(this.playerCore, n);
a.init({
progressBarElement: o.progressBarElement,
progressIndicator: o.progressIndicator,
currentTimeDisplay: o.currentTimeDisplay,
totalDurationDisplay: o.totalDurationDisplay,
timeIndicator: o.timeIndicator
}), this.managers.progressManager = a;
var l = new j(this.playerCore, n);
l.init({
loopStartMarker: o.loopStartMarker,
loopEndMarker: o.loopEndMarker,
loopRangeElement: o.loopRangeElement,
currentPositionDisplay: o.currentPositionDisplay,
durationDisplay: o.durationDisplay,
loopToggleButton: o.loopToggleButton
}), this.managers.loopManager = l, o.setLoopManager(l);
var c = new P(this.playerCore, n);
c.init(), this.managers.dragManager = c, this.playerCore.targetVideo && n.videoWrapper && n.handle && (console.log("[CustomVideoPlayer] 初始化SwipeManager..."), this.swipeManager = new Y(this.playerCore.targetVideo, n.videoWrapper, n.handle), this.managers.swipeManager = this.swipeManager);
var u = new A(this.playerCore, n, this.managers);
u.init(), this.managers.eventManager = u, r.updateControlRowsVisibility(), this.playerCore.restoreVideoState(), a.updateProgressBar(), a.updateCurrentTimeDisplay(), s.updateSafariThemeColor("#000000", !0), setTimeout((function() {
t.swipeManager && t.swipeManager.updateSize(), c.updateHandlePosition()
}), 100), this.initialized = !0, console.log("[CustomVideoPlayer] 初始化完成")
}
}
}, {
key: "close",
value: function() {
for (var t in this.playerCore.close(this.managers.uiManager.overlay, this.managers.uiManager.container), this.managers.eventManager && this.managers.eventManager.cleanup(), this.swipeManager && (this.swipeManager.destroy(), this.swipeManager = null), this.managers) this.managers[t] && "function" == typeof this.managers[t].cleanup && this.managers[t].cleanup(), this.managers[t] = null;
this.initialized = !1, this.managers = {}, this.playerCore = null
}
}]) && Z(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function K(t) {
return K = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, K(t)
}
function tt(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, et(r.key), r)
}
}
function et(t) {
var e = function(t) {
if ("object" != K(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != K(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == K(e) ? e : e + ""
}
var nt = function() {
return t = function t() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.button = null, this.videoPlayer = null, this.resizeTimeout = null, this.playerState = e.playerState || null
}, e = [{
key: "init",
value: function() {
this.cleanupExistingButtons(), this.createButton(), window.addEventListener("resize", this.handleResize.bind(this)), window.matchMedia("(orientation: portrait)").addEventListener("change", this.handleResize.bind(this))
}
}, {
key: "cleanupExistingButtons",
value: function() {
var t = document.querySelectorAll(".tm-floating-button");
t.length > 0 && (console.log("[FloatingButton] 清理 ".concat(t.length, " 个现有浮动按钮")), t.forEach((function(t) {
t && t.parentNode && t.parentNode.removeChild(t)
})))
}
}, {
key: "handleResize",
value: function() {
var t = this;
this.resizeTimeout && clearTimeout(this.resizeTimeout), this.resizeTimeout = setTimeout((function() {
t.button.style.display = "flex", t.updateButtonPosition()
}), 200)
}
}, {
key: "createButton",
value: function() {
var t = this;
if (this.button = s.createElementWithStyle("button", "tm-floating-button"), this.button.innerHTML = '\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <rect x="2" y="2" width="20" height="20" rx="5" ry="5" fill="currentColor" opacity="0.2"></rect>\n <path d="m10 8 6 4-6 4V8Z" fill="currentColor" stroke="currentColor"></path>\n </svg>\n ', this.button.addEventListener("mousedown", (function(e) {
var n = document.createElement("span"),
r = t.button.getBoundingClientRect(),
o = Math.max(r.width, r.height),
i = e.clientX - r.left - o / 2,
a = e.clientY - r.top - o / 2;
n.style.cssText = "\n position: absolute;\n width: ".concat(o, "px;\n height: ").concat(o, "px;\n left: ").concat(i, "px;\n top: ").concat(a, "px;\n background-color: rgba(255, 255, 255, 0.3);\n border-radius: 50%;\n transform: scale(0);\n pointer-events: none;\n animation: ripple-effect 0.6s ease-out forwards;\n "), t.button.appendChild(n), setTimeout((function() {
n.remove()
}), 600)
})), this.button.addEventListener("click", (function() {
t.handleButtonClick()
})), this.button.style.display = "flex", document.body.appendChild(this.button), !document.getElementById("tm-ripple-style")) {
var e = document.createElement("style");
e.id = "tm-ripple-style", e.textContent = "\n @keyframes ripple-effect {\n 0% {\n transform: scale(0);\n opacity: 1;\n }\n 80% {\n transform: scale(1.5);\n opacity: 0.5;\n }\n 100% {\n transform: scale(2);\n opacity: 0;\n }\n }\n ", document.head.appendChild(e)
}
return this.updateButtonPosition(), this.button
}
}, {
key: "updateButtonPosition",
value: function() {
if (this.button) {
var t = s.getSafeAreaInsets();
s.isPortrait() ? (this.button.style.bottom = "".concat(Math.max(20, t.bottom), "px"), this.button.style.right = "20px", this.button.style.left = "auto") : (this.button.style.bottom = "".concat(Math.max(20, t.bottom + 10), "px"), this.button.style.right = "".concat(Math.max(20, t.right + 10), "px"), this.button.style.left = "auto"), this.button.style.zIndex = "9980"
}
}
}, {
key: "handleButtonClick",
value: function() {
this.button.style.display = "none", this.videoPlayer = new J({
playerState: this.playerState,
callingButton: this.button
}), this.videoPlayer.init()
}
}, {
key: "remove",
value: function() {
this.button && this.button.parentNode && this.button.parentNode.removeChild(this.button), window.removeEventListener("resize", this.handleResize), this.button = null
}
}], e && tt(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function rt(t) {
return rt = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, rt(t)
}
function ot(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, it(r.key), r)
}
}
function it(t) {
var e = function(t) {
if ("object" != rt(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != rt(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == rt(e) ? e : e + ""
}
var at = function() {
return t = function t() {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.settings = {
showSeekControlRow: !0,
showLoopControlRow: !0,
showPlaybackControlRow: !0
}, this._setupStorageMethods()
}, e = [{
key: "_setupStorageMethods",
value: function() {
this.hasGMAPI = "function" == typeof GM_getValue && "function" == typeof GM_setValue
}
}, {
key: "getValue",
value: function(t, e) {
try {
if (this.hasGMAPI) return GM_getValue(t, e);
var n = localStorage.getItem("missNoAD_".concat(t));
return null !== n ? JSON.parse(n) : e
} catch (t) {
return console.debug("获取存储值失败:", t), e
}
}
}, {
key: "setValue",
value: function(t, e) {
try {
return this.hasGMAPI ? (GM_setValue(t, e), !0) : (localStorage.setItem("missNoAD_".concat(t), JSON.stringify(e)), !0)
} catch (t) {
return console.debug("存储值失败:", t), !1
}
}
}, {
key: "loadSettings",
value: function() {
try {
this.settings.showSeekControlRow = this.getValue("showSeekControlRow", !0), this.settings.showLoopControlRow = this.getValue("showLoopControlRow", !0), this.settings.showPlaybackControlRow = this.getValue("showPlaybackControlRow", !0)
} catch (t) {
console.error("[PlayerState] 加载设置失败:", t)
}
}
}, {
key: "saveSettings",
value: function() {
try {
this.setValue("showSeekControlRow", this.settings.showSeekControlRow), this.setValue("showLoopControlRow", this.settings.showLoopControlRow), this.setValue("showPlaybackControlRow", this.settings.showPlaybackControlRow)
} catch (t) {
console.error("[PlayerState] 保存设置失败:", t)
}
}
}, {
key: "updateSetting",
value: function(t, e) {
t in this.settings && (this.settings[t] = e, this.saveSettings())
}
}], e && ot(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function st(t) {
return st = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, st(t)
}
function lt(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, ct(r.key), r)
}
}
function ct(t) {
var e = function(t) {
if ("object" != st(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != st(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == st(e) ? e : e + ""
}
var ut = function() {
return t = function t() {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t)
}, e = [{
key: "toast",
value: function(t) {
var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 3e3,
n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "rgba(0, 0, 0, 0.8)",
r = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : "#fff",
o = arguments.length > 4 && void 0 !== arguments[4] ? arguments[4] : "top",
i = document.createElement("div");
i.innerText = t, i.style.cssText = "\n position: fixed;\n z-index: 100000;\n left: 50%;\n transform: translateX(-50%);\n padding: 10px 15px;\n border-radius: 4px;\n color: ".concat(r, ";\n background: ").concat(n, ";\n font-size: 14px;\n max-width: 80%;\n text-align: center;\n word-break: break-all;\n "), "top" === o ? i.style.top = "10%" : "bottom" === o ? i.style.bottom = "10%" : "center" === o && (i.style.top = "50%", i.style.transform = "translate(-50%, -50%)"), document.body.appendChild(i), setTimeout((function() {
i.style.opacity = "0", i.style.transition = "opacity 0.5s", setTimeout((function() {
document.body.removeChild(i)
}), 500)
}), e)
}
}, {
key: "throttle",
value: function(t, e) {
var n = 0;
return function() {
var r = Date.now();
if (r - n >= e) {
n = r;
for (var o = arguments.length, i = new Array(o), a = 0; a < o; a++) i[a] = arguments[a];
return t.apply(this, i)
}
}
}
}, {
key: "waitForElement",
value: function(t) {
var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 1e4,
n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : 100;
return new Promise((function(r, o) {
var i = document.querySelector(t);
if (i) return r(i);
var a = Date.now(),
s = setInterval((function() {
var n = document.querySelector(t);
if (n) return clearInterval(s), r(n);
Date.now() - a > e && (clearInterval(s), o(new Error("等待元素 ".concat(t, " 超时"))))
}), n)
}))
}
}, {
key: "getValue",
value: function(t, e) {
try {
var n = localStorage.getItem("autologin_".concat(t));
if (null !== n) try {
return JSON.parse(n)
} catch (t) {
return n
}
return e
} catch (t) {
return console.error("获取存储值失败:", t), e
}
}
}, {
key: "setValue",
value: function(t, e) {
try {
var n = "object" === st(e) ? JSON.stringify(e) : e;
localStorage.setItem("autologin_".concat(t), n)
} catch (t) {
console.error("设置存储值失败:", t)
}
}
}], null && lt(t.prototype, null), e && lt(t, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function dt(t) {
return dt = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, dt(t)
}
function ht(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, pt(r.key), r)
}
}
function pt(t) {
var e = function(t) {
if ("object" != dt(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != dt(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == dt(e) ? e : e + ""
}
var ft, mt, vt, gt = function() {
return t = function t() {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t)
}, e = [{
key: "userLang",
get: function() {
return navigator.languages && navigator.languages[0] || navigator.language || "en"
}
}, {
key: "translate",
value: function(t) {
var e = (arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "") || this.userLang;
return (this.strings[e] || this.strings.en)[t] || this.strings.en[t]
}
}], null && ht(t.prototype, null), e && ht(t, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t;
var t, e
}();
function yt(t) {
return yt = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, yt(t)
}
function bt() {
bt = function() {
return e
};
var t, e = {},
n = Object.prototype,
r = n.hasOwnProperty,
o = Object.defineProperty || function(t, e, n) {
t[e] = n.value
},
i = "function" == typeof Symbol ? Symbol : {},
a = i.iterator || "@@iterator",
s = i.asyncIterator || "@@asyncIterator",
l = i.toStringTag || "@@toStringTag";
function c(t, e, n) {
return Object.defineProperty(t, e, {
value: n,
enumerable: !0,
configurable: !0,
writable: !0
}), t[e]
}
try {
c({}, "")
} catch (t) {
c = function(t, e, n) {
return t[e] = n
}
}
function u(t, e, n, r) {
var i = e && e.prototype instanceof g ? e : g,
a = Object.create(i.prototype),
s = new B(r || []);
return o(a, "_invoke", {
value: L(t, n, s)
}), a
}
function d(t, e, n) {
try {
return {
type: "normal",
arg: t.call(e, n)
}
} catch (t) {
return {
type: "throw",
arg: t
}
}
}
e.wrap = u;
var h = "suspendedStart",
p = "suspendedYield",
f = "executing",
m = "completed",
v = {};
function g() {}
function y() {}
function b() {}
var w = {};
c(w, a, (function() {
return this
}));
var k = Object.getPrototypeOf,
x = k && k(k(V([])));
x && x !== n && r.call(x, a) && (w = x);
var E = b.prototype = g.prototype = Object.create(w);
function S(t) {
["next", "throw", "return"].forEach((function(e) {
c(t, e, (function(t) {
return this._invoke(e, t)
}))
}))
}
function C(t, e) {
function n(o, i, a, s) {
var l = d(t[o], t, i);
if ("throw" !== l.type) {
var c = l.arg,
u = c.value;
return u && "object" == yt(u) && r.call(u, "__await") ? e.resolve(u.__await).then((function(t) {
n("next", t, a, s)
}), (function(t) {
n("throw", t, a, s)
})) : e.resolve(u).then((function(t) {
c.value = t, a(c)
}), (function(t) {
return n("throw", t, a, s)
}))
}
s(l.arg)
}
var i;
o(this, "_invoke", {
value: function(t, r) {
function o() {
return new e((function(e, o) {
n(t, r, e, o)
}))
}
return i = i ? i.then(o, o) : o()
}
})
}
function L(e, n, r) {
var o = h;
return function(i, a) {
if (o === f) throw Error("Generator is already running");
if (o === m) {
if ("throw" === i) throw a;
return {
value: t,
done: !0
}
}
for (r.method = i, r.arg = a;;) {
var s = r.delegate;
if (s) {
var l = P(s, r);
if (l) {
if (l === v) continue;
return l
}
}
if ("next" === r.method) r.sent = r._sent = r.arg;
else if ("throw" === r.method) {
if (o === h) throw o = m, r.arg;
r.dispatchException(r.arg)
} else "return" === r.method && r.abrupt("return", r.arg);
o = f;
var c = d(e, n, r);
if ("normal" === c.type) {
if (o = r.done ? m : p, c.arg === v) continue;
return {
value: c.arg,
done: r.done
}
}
"throw" === c.type && (o = m, r.method = "throw", r.arg = c.arg)
}
}
}
function P(e, n) {
var r = n.method,
o = e.iterator[r];
if (o === t) return n.delegate = null, "throw" === r && e.iterator.return && (n.method = "return", n.arg = t, P(e, n), "throw" === n.method) || "return" !== r && (n.method = "throw", n.arg = new TypeError("The iterator does not provide a '" + r + "' method")), v;
var i = d(o, e.iterator, n.arg);
if ("throw" === i.type) return n.method = "throw", n.arg = i.arg, n.delegate = null, v;
var a = i.arg;
return a ? a.done ? (n[e.resultName] = a.value, n.next = e.nextLoc, "return" !== n.method && (n.method = "next", n.arg = t), n.delegate = null, v) : a : (n.method = "throw", n.arg = new TypeError("iterator result is not an object"), n.delegate = null, v)
}
function T(t) {
var e = {
tryLoc: t[0]
};
1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e)
}
function M(t) {
var e = t.completion || {};
e.type = "normal", delete e.arg, t.completion = e
}
function B(t) {
this.tryEntries = [{
tryLoc: "root"
}], t.forEach(T, this), this.reset(!0)
}
function V(e) {
if (e || "" === e) {
var n = e[a];
if (n) return n.call(e);
if ("function" == typeof e.next) return e;
if (!isNaN(e.length)) {
var o = -1,
i = function n() {
for (; ++o < e.length;)
if (r.call(e, o)) return n.value = e[o], n.done = !1, n;
return n.value = t, n.done = !0, n
};
return i.next = i
}
}
throw new TypeError(yt(e) + " is not iterable")
}
return y.prototype = b, o(E, "constructor", {
value: b,
configurable: !0
}), o(b, "constructor", {
value: y,
configurable: !0
}), y.displayName = c(b, l, "GeneratorFunction"), e.isGeneratorFunction = function(t) {
var e = "function" == typeof t && t.constructor;
return !!e && (e === y || "GeneratorFunction" === (e.displayName || e.name))
}, e.mark = function(t) {
return Object.setPrototypeOf ? Object.setPrototypeOf(t, b) : (t.__proto__ = b, c(t, l, "GeneratorFunction")), t.prototype = Object.create(E), t
}, e.awrap = function(t) {
return {
__await: t
}
}, S(C.prototype), c(C.prototype, s, (function() {
return this
})), e.AsyncIterator = C, e.async = function(t, n, r, o, i) {
void 0 === i && (i = Promise);
var a = new C(u(t, n, r, o), i);
return e.isGeneratorFunction(n) ? a : a.next().then((function(t) {
return t.done ? t.value : a.next()
}))
}, S(E), c(E, l, "Generator"), c(E, a, (function() {
return this
})), c(E, "toString", (function() {
return "[object Generator]"
})), e.keys = function(t) {
var e = Object(t),
n = [];
for (var r in e) n.push(r);
return n.reverse(),
function t() {
for (; n.length;) {
var r = n.pop();
if (r in e) return t.value = r, t.done = !1, t
}
return t.done = !0, t
}
}, e.values = V, B.prototype = {
constructor: B,
reset: function(e) {
if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(M), !e)
for (var n in this) "t" === n.charAt(0) && r.call(this, n) && !isNaN(+n.slice(1)) && (this[n] = t)
},
stop: function() {
this.done = !0;
var t = this.tryEntries[0].completion;
if ("throw" === t.type) throw t.arg;
return this.rval
},
dispatchException: function(e) {
if (this.done) throw e;
var n = this;
function o(r, o) {
return s.type = "throw", s.arg = e, n.next = r, o && (n.method = "next", n.arg = t), !!o
}
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var a = this.tryEntries[i],
s = a.completion;
if ("root" === a.tryLoc) return o("end");
if (a.tryLoc <= this.prev) {
var l = r.call(a, "catchLoc"),
c = r.call(a, "finallyLoc");
if (l && c) {
if (this.prev < a.catchLoc) return o(a.catchLoc, !0);
if (this.prev < a.finallyLoc) return o(a.finallyLoc)
} else if (l) {
if (this.prev < a.catchLoc) return o(a.catchLoc, !0)
} else {
if (!c) throw Error("try statement without catch or finally");
if (this.prev < a.finallyLoc) return o(a.finallyLoc)
}
}
}
},
abrupt: function(t, e) {
for (var n = this.tryEntries.length - 1; n >= 0; --n) {
var o = this.tryEntries[n];
if (o.tryLoc <= this.prev && r.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
var i = o;
break
}
}
i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
var a = i ? i.completion : {};
return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, v) : this.complete(a)
},
complete: function(t, e) {
if ("throw" === t.type) throw t.arg;
return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), v
},
finish: function(t) {
for (var e = this.tryEntries.length - 1; e >= 0; --e) {
var n = this.tryEntries[e];
if (n.finallyLoc === t) return this.complete(n.completion, n.afterLoc), M(n), v
}
},
catch: function(t) {
for (var e = this.tryEntries.length - 1; e >= 0; --e) {
var n = this.tryEntries[e];
if (n.tryLoc === t) {
var r = n.completion;
if ("throw" === r.type) {
var o = r.arg;
M(n)
}
return o
}
}
throw Error("illegal catch attempt")
},
delegateYield: function(e, n, r) {
return this.delegate = {
iterator: V(e),
resultName: n,
nextLoc: r
}, "next" === this.method && (this.arg = t), v
}
}, e
}
function wt(t, e, n, r, o, i, a) {
try {
var s = t[i](a),
l = s.value
} catch (t) {
return void n(t)
}
s.done ? e(l) : Promise.resolve(l).then(r, o)
}
function kt(t) {
return function() {
var e = this,
n = arguments;
return new Promise((function(r, o) {
var i = t.apply(e, n);
function a(t) {
wt(i, r, o, a, s, "next", t)
}
function s(t) {
wt(i, r, o, a, s, "throw", t)
}
a(void 0)
}))
}
}
function xt(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, Et(r.key), r)
}
}
function Et(t) {
var e = function(t) {
if ("object" != yt(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != yt(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == yt(e) ? e : e + ""
}
ft = gt, vt = {
en: {
accountNull: "Error: Email or password is empty.",
loginSuccess: "Login successful, refreshing the page.",
networkFailed: "Status code error.",
loginFailed: "Login failed, incorrect email or password. Check console for error details.",
autoLogin: "Auto Login"
},
"zh-CN": {
accountNull: "邮箱或密码为空",
loginSuccess: "登录成功,即将刷新页面。",
networkFailed: "状态码错误",
loginFailed: "登录失败,邮箱或密码错误,可以在控制台查看错误信息。",
autoLogin: "自动登录"
},
"zh-TW": {
accountNull: "郵箱或密碼為空",
loginSuccess: "登錄成功,即將刷新頁面。",
networkFailed: "狀態碼錯誤",
loginFailed: "登錄失敗,郵箱或密碼錯誤,可以在控制台查看錯誤信息。",
autoLogin: "自動登錄"
},
ja: {
accountNull: "エラー:メールアドレスまたはパスワードが空です。",
loginSuccess: "ログイン成功、ページを更新します。",
networkFailed: "ステータスコードエラー",
loginFailed: "ログインに失敗しました。メールアドレスまたはパスワードが間違っています。エラーの詳細はコンソールで確認できます。",
autoLogin: "自動ログイン"
},
vi: {
accountNull: "Lỗi: Email hoặc mật khẩu trống.",
loginSuccess: "Đăng nhập thành công, đang làm mới trang.",
networkFailed: "Lỗi mã trạng thái.",
loginFailed: "Đăng nhập không thành công, email hoặc mật khẩu không chính xác. Xem chi tiết lỗi trên bảng điều khiển.",
autoLogin: "Đăng nhập tự động"
}
}, (mt = pt(mt = "strings")) in ft ? Object.defineProperty(ft, mt, {
value: vt,
enumerable: !0,
configurable: !0,
writable: !0
}) : ft[mt] = vt;
var St = function() {
return function(t, e) {
return e && xt(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t
}((function t() {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.domains = ["missav.ws", "missav.ai", "missav.com", "thisav.com"]
}), [{
key: "isSupportedSite",
value: function() {
var t = window.location.hostname;
return this.domains.some((function(e) {
return t.includes(e)
}))
}
}, {
key: "login",
value: (r = kt(bt().mark((function t(e, n) {
var r, o, i, a, s;
return bt().wrap((function(t) {
for (;;) switch (t.prev = t.next) {
case 0:
if (e && n) {
t.next = 3;
break
}
return ut.toast(gt.translate("accountNull"), 2e3, "#FF0000", "#ffffff", "top"), t.abrupt("return", !1);
case 3:
return t.prev = 3, t.next = 6, fetch("https://missav.ws/cn/api/login", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
email: e,
password: n,
remember: !0
})
});
case 6:
if ((o = t.sent).ok) {
t.next = 14;
break
}
return t.next = 10, o.text();
case 10:
throw i = t.sent, console.error("登录错误:", {
status: o.status,
statusText: o.statusText,
responseText: i
}), ut.toast("登录失败: ".concat(i), 2e3, "#FF0000", "#ffffff", "top"), new Error(gt.translate("networkFailed"));
case 14:
if (null === (r = o.headers.get("Content-Type")) || void 0 === r || !r.includes("application/json")) {
t.next = 20;
break
}
return t.next = 17, o.json();
case 17:
a = t.sent, t.next = 26;
break;
case 20:
return t.next = 22, o.text();
case 22:
throw s = t.sent, console.error(gt.translate("loginFailed"), {
status: o.status,
statusText: o.statusText,
responseText: s
}), ut.toast(gt.translate("loginFailed"), 2e3, "#FF0000", "#ffffff", "top"), new Error(gt.translate("loginFailed"));
case 26:
return console.log("登录成功:", a), ut.toast(gt.translate("loginSuccess"), 2e3, "rgb(18, 187, 2)", "#ffffff", "top"), setTimeout((function() {
location.reload()
}), 1e3), t.abrupt("return", !0);
case 32:
return t.prev = 32, t.t0 = t.catch(3), ut.toast("错误发生: ".concat(t.t0.message), 2e3, "#FF0000", "#ffffff", "top"), t.abrupt("return", !1);
case 36:
case "end":
return t.stop()
}
}), t, null, [
[3, 32]
])
}))), function(t, e) {
return r.apply(this, arguments)
})
}, {
key: "checkLoginStatus",
value: (n = kt(bt().mark((function t() {
var e;
return bt().wrap((function(t) {
for (;;) switch (t.prev = t.next) {
case 0:
return t.prev = 0, t.next = 3, this.checkLoginByAPI();
case 3:
if (null === (e = t.sent)) {
t.next = 6;
break
}
return t.abrupt("return", e);
case 6:
return t.abrupt("return", this.checkLoginByDOM());
case 9:
return t.prev = 9, t.t0 = t.catch(0), console.error("检查登录状态时出错:", t.t0), t.abrupt("return", !1);
case 13:
case "end":
return t.stop()
}
}), t, this, [
[0, 9]
])
}))), function() {
return n.apply(this, arguments)
})
}, {
key: "checkLoginByAPI",
value: (e = kt(bt().mark((function t() {
var e, n;
return bt().wrap((function(t) {
for (;;) switch (t.prev = t.next) {
case 0:
return t.prev = 0, t.next = 4, fetch("https://missav.ws/api/actresses/1016525/view", {
method: "GET",
credentials: "include"
});
case 4:
if ((e = t.sent).ok) {
t.next = 7;
break
}
return t.abrupt("return", null);
case 7:
return t.next = 9, e.json();
case 9:
return n = t.sent, t.abrupt("return", null !== n.user);
case 13:
return t.prev = 13, t.t0 = t.catch(0), console.debug("API登录状态检查出错:", t.t0.message), t.abrupt("return", null);
case 17:
case "end":
return t.stop()
}
}), t, null, [
[0, 13]
])
}))), function() {
return e.apply(this, arguments)
})
}, {
key: "checkLoginByDOM",
value: function() {
try {
var t = document.querySelector("button[x-on\\:click=\"currentPage = 'login'\"]"),
e = document.querySelector(".relative.ml-3 img.h-8.w-8.rounded-full"),
n = document.querySelector('[x-data="{userDropdownOpen: false}"]');
return !t || e || n
} catch (t) {
return console.debug("DOM检测登录状态时出错:", t.message), !1
}
}
}, {
key: "addAutoLoginOption",
value: (t = kt(bt().mark((function t(e) {
var n, r, o, i, a, s;
return bt().wrap((function(t) {
for (;;) switch (t.prev = t.next) {
case 0:
return t.prev = 0, t.next = 3, ut.waitForElement("form[x-show=\"currentPage === 'login'\"] .relative.flex.items-start.justify-between");
case 3:
n = t.sent, (r = document.createElement("div")).className = "flex", r.innerHTML = '\n <div class="flex items-center h-5">\n <input id="auto_login" type="checkbox" class="focus:ring-primary h-4 w-4 text-primary border-gray-300 rounded __text_mode_custom_bg__">\n </div>\n <div class="ml-3 text-sm">\n <label for="auto_login" class="font-medium text-nord4">'.concat(gt.translate("autoLogin"), "</label>\n </div>\n "), (o = n.querySelector(".flex")).parentNode.insertBefore(r, o.nextSibling), i = ut.getValue("autoLogin", !0), document.getElementById("auto_login").checked = i, document.getElementById("auto_login").addEventListener("change", (function() {
var t = document.getElementById("auto_login").checked;
ut.setValue("autoLogin", t), e && e({
autoLogin: t
})
})), (a = document.querySelector("form[x-show=\"currentPage === 'login'\"]")) && (s = a.querySelector('button[type="submit"]')) && s.addEventListener("click", (function() {
setTimeout((function() {
var t = document.getElementById("login_email"),
n = document.getElementById("login_password"),
r = document.getElementById("auto_login");
if (t && n && r && r.checked) {
var o = t.value,
i = n.value;
ut.setValue("userEmail", o), ut.setValue("userPassword", i), e && e({
email: o,
password: i,
autoLogin: !0
})
}
}), 100)
})), t.next = 19;
break;
case 16:
t.prev = 16, t.t0 = t.catch(0), console.error("添加自动登录选项时出错:", t.t0);
case 19:
case "end":
return t.stop()
}
}), t, null, [
[0, 16]
])
}))), function(e) {
return t.apply(this, arguments)
})
}]);
var t, e, n, r
}();
function Ct(t) {
return Ct = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, Ct(t)
}
function Lt(t, e) {
(null == e || e > t.length) && (e = t.length);
for (var n = 0, r = Array(e); n < e; n++) r[n] = t[n];
return r
}
function Pt() {
Pt = function() {
return e
};
var t, e = {},
n = Object.prototype,
r = n.hasOwnProperty,
o = Object.defineProperty || function(t, e, n) {
t[e] = n.value
},
i = "function" == typeof Symbol ? Symbol : {},
a = i.iterator || "@@iterator",
s = i.asyncIterator || "@@asyncIterator",
l = i.toStringTag || "@@toStringTag";
function c(t, e, n) {
return Object.defineProperty(t, e, {
value: n,
enumerable: !0,
configurable: !0,
writable: !0
}), t[e]
}
try {
c({}, "")
} catch (t) {
c = function(t, e, n) {
return t[e] = n
}
}
function u(t, e, n, r) {
var i = e && e.prototype instanceof g ? e : g,
a = Object.create(i.prototype),
s = new B(r || []);
return o(a, "_invoke", {
value: L(t, n, s)
}), a
}
function d(t, e, n) {
try {
return {
type: "normal",
arg: t.call(e, n)
}
} catch (t) {
return {
type: "throw",
arg: t
}
}
}
e.wrap = u;
var h = "suspendedStart",
p = "suspendedYield",
f = "executing",
m = "completed",
v = {};
function g() {}
function y() {}
function b() {}
var w = {};
c(w, a, (function() {
return this
}));
var k = Object.getPrototypeOf,
x = k && k(k(V([])));
x && x !== n && r.call(x, a) && (w = x);
var E = b.prototype = g.prototype = Object.create(w);
function S(t) {
["next", "throw", "return"].forEach((function(e) {
c(t, e, (function(t) {
return this._invoke(e, t)
}))
}))
}
function C(t, e) {
function n(o, i, a, s) {
var l = d(t[o], t, i);
if ("throw" !== l.type) {
var c = l.arg,
u = c.value;
return u && "object" == Ct(u) && r.call(u, "__await") ? e.resolve(u.__await).then((function(t) {
n("next", t, a, s)
}), (function(t) {
n("throw", t, a, s)
})) : e.resolve(u).then((function(t) {
c.value = t, a(c)
}), (function(t) {
return n("throw", t, a, s)
}))
}
s(l.arg)
}
var i;
o(this, "_invoke", {
value: function(t, r) {
function o() {
return new e((function(e, o) {
n(t, r, e, o)
}))
}
return i = i ? i.then(o, o) : o()
}
})
}
function L(e, n, r) {
var o = h;
return function(i, a) {
if (o === f) throw Error("Generator is already running");
if (o === m) {
if ("throw" === i) throw a;
return {
value: t,
done: !0
}
}
for (r.method = i, r.arg = a;;) {
var s = r.delegate;
if (s) {
var l = P(s, r);
if (l) {
if (l === v) continue;
return l
}
}
if ("next" === r.method) r.sent = r._sent = r.arg;
else if ("throw" === r.method) {
if (o === h) throw o = m, r.arg;
r.dispatchException(r.arg)
} else "return" === r.method && r.abrupt("return", r.arg);
o = f;
var c = d(e, n, r);
if ("normal" === c.type) {
if (o = r.done ? m : p, c.arg === v) continue;
return {
value: c.arg,
done: r.done
}
}
"throw" === c.type && (o = m, r.method = "throw", r.arg = c.arg)
}
}
}
function P(e, n) {
var r = n.method,
o = e.iterator[r];
if (o === t) return n.delegate = null, "throw" === r && e.iterator.return && (n.method = "return", n.arg = t, P(e, n), "throw" === n.method) || "return" !== r && (n.method = "throw", n.arg = new TypeError("The iterator does not provide a '" + r + "' method")), v;
var i = d(o, e.iterator, n.arg);
if ("throw" === i.type) return n.method = "throw", n.arg = i.arg, n.delegate = null, v;
var a = i.arg;
return a ? a.done ? (n[e.resultName] = a.value, n.next = e.nextLoc, "return" !== n.method && (n.method = "next", n.arg = t), n.delegate = null, v) : a : (n.method = "throw", n.arg = new TypeError("iterator result is not an object"), n.delegate = null, v)
}
function T(t) {
var e = {
tryLoc: t[0]
};
1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e)
}
function M(t) {
var e = t.completion || {};
e.type = "normal", delete e.arg, t.completion = e
}
function B(t) {
this.tryEntries = [{
tryLoc: "root"
}], t.forEach(T, this), this.reset(!0)
}
function V(e) {
if (e || "" === e) {
var n = e[a];
if (n) return n.call(e);
if ("function" == typeof e.next) return e;
if (!isNaN(e.length)) {
var o = -1,
i = function n() {
for (; ++o < e.length;)
if (r.call(e, o)) return n.value = e[o], n.done = !1, n;
return n.value = t, n.done = !0, n
};
return i.next = i
}
}
throw new TypeError(Ct(e) + " is not iterable")
}
return y.prototype = b, o(E, "constructor", {
value: b,
configurable: !0
}), o(b, "constructor", {
value: y,
configurable: !0
}), y.displayName = c(b, l, "GeneratorFunction"), e.isGeneratorFunction = function(t) {
var e = "function" == typeof t && t.constructor;
return !!e && (e === y || "GeneratorFunction" === (e.displayName || e.name))
}, e.mark = function(t) {
return Object.setPrototypeOf ? Object.setPrototypeOf(t, b) : (t.__proto__ = b, c(t, l, "GeneratorFunction")), t.prototype = Object.create(E), t
}, e.awrap = function(t) {
return {
__await: t
}
}, S(C.prototype), c(C.prototype, s, (function() {
return this
})), e.AsyncIterator = C, e.async = function(t, n, r, o, i) {
void 0 === i && (i = Promise);
var a = new C(u(t, n, r, o), i);
return e.isGeneratorFunction(n) ? a : a.next().then((function(t) {
return t.done ? t.value : a.next()
}))
}, S(E), c(E, l, "Generator"), c(E, a, (function() {
return this
})), c(E, "toString", (function() {
return "[object Generator]"
})), e.keys = function(t) {
var e = Object(t),
n = [];
for (var r in e) n.push(r);
return n.reverse(),
function t() {
for (; n.length;) {
var r = n.pop();
if (r in e) return t.value = r, t.done = !1, t
}
return t.done = !0, t
}
}, e.values = V, B.prototype = {
constructor: B,
reset: function(e) {
if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(M), !e)
for (var n in this) "t" === n.charAt(0) && r.call(this, n) && !isNaN(+n.slice(1)) && (this[n] = t)
},
stop: function() {
this.done = !0;
var t = this.tryEntries[0].completion;
if ("throw" === t.type) throw t.arg;
return this.rval
},
dispatchException: function(e) {
if (this.done) throw e;
var n = this;
function o(r, o) {
return s.type = "throw", s.arg = e, n.next = r, o && (n.method = "next", n.arg = t), !!o
}
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var a = this.tryEntries[i],
s = a.completion;
if ("root" === a.tryLoc) return o("end");
if (a.tryLoc <= this.prev) {
var l = r.call(a, "catchLoc"),
c = r.call(a, "finallyLoc");
if (l && c) {
if (this.prev < a.catchLoc) return o(a.catchLoc, !0);
if (this.prev < a.finallyLoc) return o(a.finallyLoc)
} else if (l) {
if (this.prev < a.catchLoc) return o(a.catchLoc, !0)
} else {
if (!c) throw Error("try statement without catch or finally");
if (this.prev < a.finallyLoc) return o(a.finallyLoc)
}
}
}
},
abrupt: function(t, e) {
for (var n = this.tryEntries.length - 1; n >= 0; --n) {
var o = this.tryEntries[n];
if (o.tryLoc <= this.prev && r.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
var i = o;
break
}
}
i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
var a = i ? i.completion : {};
return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, v) : this.complete(a)
},
complete: function(t, e) {
if ("throw" === t.type) throw t.arg;
return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), v
},
finish: function(t) {
for (var e = this.tryEntries.length - 1; e >= 0; --e) {
var n = this.tryEntries[e];
if (n.finallyLoc === t) return this.complete(n.completion, n.afterLoc), M(n), v
}
},
catch: function(t) {
for (var e = this.tryEntries.length - 1; e >= 0; --e) {
var n = this.tryEntries[e];
if (n.tryLoc === t) {
var r = n.completion;
if ("throw" === r.type) {
var o = r.arg;
M(n)
}
return o
}
}
throw Error("illegal catch attempt")
},
delegateYield: function(e, n, r) {
return this.delegate = {
iterator: V(e),
resultName: n,
nextLoc: r
}, "next" === this.method && (this.arg = t), v
}
}, e
}
function Tt(t, e, n, r, o, i, a) {
try {
var s = t[i](a),
l = s.value
} catch (t) {
return void n(t)
}
s.done ? e(l) : Promise.resolve(l).then(r, o)
}
function Mt(t) {
return function() {
var e = this,
n = arguments;
return new Promise((function(r, o) {
var i = t.apply(e, n);
function a(t) {
Tt(i, r, o, a, s, "next", t)
}
function s(t) {
Tt(i, r, o, a, s, "throw", t)
}
a(void 0)
}))
}
}
function Bt(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, Vt(r.key), r)
}
}
function Vt(t) {
var e = function(t) {
if ("object" != Ct(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != Ct(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == Ct(e) ? e : e + ""
}
var jt = function() {
return function(t, e) {
return e && Bt(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t
}((function t() {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.userEmail = "", this.userPassword = "", this.autoLogin = !0, this.providers = [new St], this.activeProvider = null
}), [{
key: "init",
value: (n = Mt(Pt().mark((function t() {
return Pt().wrap((function(t) {
for (;;) switch (t.prev = t.next) {
case 0:
if (this.loadLoginInfo(), this.activeProvider = this.getMatchingProvider(), this.activeProvider) {
t.next = 5;
break
}
return console.debug("没有找到匹配的登录提供者"), t.abrupt("return");
case 5:
return t.next = 7, this.activeProvider.addAutoLoginOption(this.handleLoginInfoChange.bind(this));
case 7:
return t.next = 9, this.checkLoginAndAutoLogin();
case 9:
case "end":
return t.stop()
}
}), t, this)
}))), function() {
return n.apply(this, arguments)
})
}, {
key: "handleLoginInfoChange",
value: function(t) {
void 0 !== t.email && (this.userEmail = t.email, ut.setValue("userEmail", t.email)), void 0 !== t.password && (this.userPassword = t.password, ut.setValue("userPassword", t.password)), void 0 !== t.autoLogin && (this.autoLogin = t.autoLogin, ut.setValue("autoLogin", t.autoLogin))
}
}, {
key: "loadLoginInfo",
value: function() {
this.userEmail = ut.getValue("userEmail", ""), this.userPassword = ut.getValue("userPassword", ""), this.autoLogin = ut.getValue("autoLogin", !0)
}
}, {
key: "getMatchingProvider",
value: function() {
var t, e = function(t, e) {
var n = "undefined" != typeof Symbol && t[Symbol.iterator] || t["@@iterator"];
if (!n) {
if (Array.isArray(t) || (n = function(t, e) {
if (t) {
if ("string" == typeof t) return Lt(t, e);
var n = {}.toString.call(t).slice(8, -1);
return "Object" === n && t.constructor && (n = t.constructor.name), "Map" === n || "Set" === n ? Array.from(t) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? Lt(t, e) : void 0
}
}(t)) || e && t && "number" == typeof t.length) {
n && (t = n);
var r = 0,
o = function() {};
return {
s: o,
n: function() {
return r >= t.length ? {
done: !0
} : {
done: !1,
value: t[r++]
}
},
e: function(t) {
throw t
},
f: o
}
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
}
var i, a = !0,
s = !1;
return {
s: function() {
n = n.call(t)
},
n: function() {
var t = n.next();
return a = t.done, t
},
e: function(t) {
s = !0, i = t
},
f: function() {
try {
a || null == n.return || n.return()
} finally {
if (s) throw i
}
}
}
}(this.providers);
try {
for (e.s(); !(t = e.n()).done;) {
var n = t.value;
if (n.isSupportedSite()) return n
}
} catch (t) {
e.e(t)
} finally {
e.f()
}
return null
}
}, {
key: "checkLoginAndAutoLogin",
value: (e = Mt(Pt().mark((function t() {
return Pt().wrap((function(t) {
for (;;) switch (t.prev = t.next) {
case 0:
if (this.activeProvider) {
t.next = 2;
break
}
return t.abrupt("return");
case 2:
return t.prev = 2, t.next = 5, this.activeProvider.checkLoginStatus();
case 5:
if (t.sent || !this.autoLogin || !this.userEmail || !this.userPassword) {
t.next = 10;
break
}
return console.log("用户未登录,尝试自动登录"), t.next = 10, this.activeProvider.login(this.userEmail, this.userPassword);
case 10:
t.next = 15;
break;
case 12:
t.prev = 12, t.t0 = t.catch(2), console.error("登录检查过程出错:", t.t0);
case 15:
case "end":
return t.stop()
}
}), t, this, [
[2, 12]
])
}))), function() {
return e.apply(this, arguments)
})
}, {
key: "login",
value: (t = Mt(Pt().mark((function t(e, n) {
return Pt().wrap((function(t) {
for (;;) switch (t.prev = t.next) {
case 0:
if (this.activeProvider) {
t.next = 3;
break
}
return console.error("没有匹配的登录提供者"), t.abrupt("return", !1);
case 3:
return this.handleLoginInfoChange({
email: e,
password: n
}), t.next = 6, this.activeProvider.login(e, n);
case 6:
return t.abrupt("return", t.sent);
case 7:
case "end":
return t.stop()
}
}), t, this)
}))), function(e, n) {
return t.apply(this, arguments)
})
}]);
var t, e, n
}();
function Ot(t) {
return Ot = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, Ot(t)
}
function Dt() {
Dt = function() {
return e
};
var t, e = {},
n = Object.prototype,
r = n.hasOwnProperty,
o = Object.defineProperty || function(t, e, n) {
t[e] = n.value
},
i = "function" == typeof Symbol ? Symbol : {},
a = i.iterator || "@@iterator",
s = i.asyncIterator || "@@asyncIterator",
l = i.toStringTag || "@@toStringTag";
function c(t, e, n) {
return Object.defineProperty(t, e, {
value: n,
enumerable: !0,
configurable: !0,
writable: !0
}), t[e]
}
try {
c({}, "")
} catch (t) {
c = function(t, e, n) {
return t[e] = n
}
}
function u(t, e, n, r) {
var i = e && e.prototype instanceof g ? e : g,
a = Object.create(i.prototype),
s = new B(r || []);
return o(a, "_invoke", {
value: L(t, n, s)
}), a
}
function d(t, e, n) {
try {
return {
type: "normal",
arg: t.call(e, n)
}
} catch (t) {
return {
type: "throw",
arg: t
}
}
}
e.wrap = u;
var h = "suspendedStart",
p = "suspendedYield",
f = "executing",
m = "completed",
v = {};
function g() {}
function y() {}
function b() {}
var w = {};
c(w, a, (function() {
return this
}));
var k = Object.getPrototypeOf,
x = k && k(k(V([])));
x && x !== n && r.call(x, a) && (w = x);
var E = b.prototype = g.prototype = Object.create(w);
function S(t) {
["next", "throw", "return"].forEach((function(e) {
c(t, e, (function(t) {
return this._invoke(e, t)
}))
}))
}
function C(t, e) {
function n(o, i, a, s) {
var l = d(t[o], t, i);
if ("throw" !== l.type) {
var c = l.arg,
u = c.value;
return u && "object" == Ot(u) && r.call(u, "__await") ? e.resolve(u.__await).then((function(t) {
n("next", t, a, s)
}), (function(t) {
n("throw", t, a, s)
})) : e.resolve(u).then((function(t) {
c.value = t, a(c)
}), (function(t) {
return n("throw", t, a, s)
}))
}
s(l.arg)
}
var i;
o(this, "_invoke", {
value: function(t, r) {
function o() {
return new e((function(e, o) {
n(t, r, e, o)
}))
}
return i = i ? i.then(o, o) : o()
}
})
}
function L(e, n, r) {
var o = h;
return function(i, a) {
if (o === f) throw Error("Generator is already running");
if (o === m) {
if ("throw" === i) throw a;
return {
value: t,
done: !0
}
}
for (r.method = i, r.arg = a;;) {
var s = r.delegate;
if (s) {
var l = P(s, r);
if (l) {
if (l === v) continue;
return l
}
}
if ("next" === r.method) r.sent = r._sent = r.arg;
else if ("throw" === r.method) {
if (o === h) throw o = m, r.arg;
r.dispatchException(r.arg)
} else "return" === r.method && r.abrupt("return", r.arg);
o = f;
var c = d(e, n, r);
if ("normal" === c.type) {
if (o = r.done ? m : p, c.arg === v) continue;
return {
value: c.arg,
done: r.done
}
}
"throw" === c.type && (o = m, r.method = "throw", r.arg = c.arg)
}
}
}
function P(e, n) {
var r = n.method,
o = e.iterator[r];
if (o === t) return n.delegate = null, "throw" === r && e.iterator.return && (n.method = "return", n.arg = t, P(e, n), "throw" === n.method) || "return" !== r && (n.method = "throw", n.arg = new TypeError("The iterator does not provide a '" + r + "' method")), v;
var i = d(o, e.iterator, n.arg);
if ("throw" === i.type) return n.method = "throw", n.arg = i.arg, n.delegate = null, v;
var a = i.arg;
return a ? a.done ? (n[e.resultName] = a.value, n.next = e.nextLoc, "return" !== n.method && (n.method = "next", n.arg = t), n.delegate = null, v) : a : (n.method = "throw", n.arg = new TypeError("iterator result is not an object"), n.delegate = null, v)
}
function T(t) {
var e = {
tryLoc: t[0]
};
1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e)
}
function M(t) {
var e = t.completion || {};
e.type = "normal", delete e.arg, t.completion = e
}
function B(t) {
this.tryEntries = [{
tryLoc: "root"
}], t.forEach(T, this), this.reset(!0)
}
function V(e) {
if (e || "" === e) {
var n = e[a];
if (n) return n.call(e);
if ("function" == typeof e.next) return e;
if (!isNaN(e.length)) {
var o = -1,
i = function n() {
for (; ++o < e.length;)
if (r.call(e, o)) return n.value = e[o], n.done = !1, n;
return n.value = t, n.done = !0, n
};
return i.next = i
}
}
throw new TypeError(Ot(e) + " is not iterable")
}
return y.prototype = b, o(E, "constructor", {
value: b,
configurable: !0
}), o(b, "constructor", {
value: y,
configurable: !0
}), y.displayName = c(b, l, "GeneratorFunction"), e.isGeneratorFunction = function(t) {
var e = "function" == typeof t && t.constructor;
return !!e && (e === y || "GeneratorFunction" === (e.displayName || e.name))
}, e.mark = function(t) {
return Object.setPrototypeOf ? Object.setPrototypeOf(t, b) : (t.__proto__ = b, c(t, l, "GeneratorFunction")), t.prototype = Object.create(E), t
}, e.awrap = function(t) {
return {
__await: t
}
}, S(C.prototype), c(C.prototype, s, (function() {
return this
})), e.AsyncIterator = C, e.async = function(t, n, r, o, i) {
void 0 === i && (i = Promise);
var a = new C(u(t, n, r, o), i);
return e.isGeneratorFunction(n) ? a : a.next().then((function(t) {
return t.done ? t.value : a.next()
}))
}, S(E), c(E, l, "Generator"), c(E, a, (function() {
return this
})), c(E, "toString", (function() {
return "[object Generator]"
})), e.keys = function(t) {
var e = Object(t),
n = [];
for (var r in e) n.push(r);
return n.reverse(),
function t() {
for (; n.length;) {
var r = n.pop();
if (r in e) return t.value = r, t.done = !1, t
}
return t.done = !0, t
}
}, e.values = V, B.prototype = {
constructor: B,
reset: function(e) {
if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(M), !e)
for (var n in this) "t" === n.charAt(0) && r.call(this, n) && !isNaN(+n.slice(1)) && (this[n] = t)
},
stop: function() {
this.done = !0;
var t = this.tryEntries[0].completion;
if ("throw" === t.type) throw t.arg;
return this.rval
},
dispatchException: function(e) {
if (this.done) throw e;
var n = this;
function o(r, o) {
return s.type = "throw", s.arg = e, n.next = r, o && (n.method = "next", n.arg = t), !!o
}
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var a = this.tryEntries[i],
s = a.completion;
if ("root" === a.tryLoc) return o("end");
if (a.tryLoc <= this.prev) {
var l = r.call(a, "catchLoc"),
c = r.call(a, "finallyLoc");
if (l && c) {
if (this.prev < a.catchLoc) return o(a.catchLoc, !0);
if (this.prev < a.finallyLoc) return o(a.finallyLoc)
} else if (l) {
if (this.prev < a.catchLoc) return o(a.catchLoc, !0)
} else {
if (!c) throw Error("try statement without catch or finally");
if (this.prev < a.finallyLoc) return o(a.finallyLoc)
}
}
}
},
abrupt: function(t, e) {
for (var n = this.tryEntries.length - 1; n >= 0; --n) {
var o = this.tryEntries[n];
if (o.tryLoc <= this.prev && r.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
var i = o;
break
}
}
i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
var a = i ? i.completion : {};
return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, v) : this.complete(a)
},
complete: function(t, e) {
if ("throw" === t.type) throw t.arg;
return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), v
},
finish: function(t) {
for (var e = this.tryEntries.length - 1; e >= 0; --e) {
var n = this.tryEntries[e];
if (n.finallyLoc === t) return this.complete(n.completion, n.afterLoc), M(n), v
}
},
catch: function(t) {
for (var e = this.tryEntries.length - 1; e >= 0; --e) {
var n = this.tryEntries[e];
if (n.tryLoc === t) {
var r = n.completion;
if ("throw" === r.type) {
var o = r.arg;
M(n)
}
return o
}
}
throw Error("illegal catch attempt")
},
delegateYield: function(e, n, r) {
return this.delegate = {
iterator: V(e),
resultName: n,
nextLoc: r
}, "next" === this.method && (this.arg = t), v
}
}, e
}
function Ht(t, e, n, r, o, i, a) {
try {
var s = t[i](a),
l = s.value
} catch (t) {
return void n(t)
}
s.done ? e(l) : Promise.resolve(l).then(r, o)
}
function It() {
return _t.apply(this, arguments)
}
function _t() {
var t;
return t = Dt().mark((function t() {
var e;
return Dt().wrap((function(t) {
for (;;) switch (t.prev = t.next) {
case 0:
return t.prev = 0, e = new jt, t.next = 4, e.init();
case 4:
return t.abrupt("return", e);
case 7:
return t.prev = 7, t.t0 = t.catch(0), console.error("自动登录模块初始化失败:", t.t0), t.abrupt("return", null);
case 11:
case "end":
return t.stop()
}
}), t, null, [
[0, 7]
])
})), _t = function() {
var e = this,
n = arguments;
return new Promise((function(r, o) {
var i = t.apply(e, n);
function a(t) {
Ht(i, r, o, a, s, "next", t)
}
function s(t) {
Ht(i, r, o, a, s, "throw", t)
}
a(void 0)
}))
}, _t.apply(this, arguments)
}
function Rt(t) {
return Rt = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, Rt(t)
}
function Nt(t, e) {
(null == e || e > t.length) && (e = t.length);
for (var n = 0, r = Array(e); n < e; n++) r[n] = t[n];
return r
}
function At(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, zt(r.key), r)
}
}
function zt(t) {
var e = function(t) {
if ("object" != Rt(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != Rt(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == Rt(e) ? e : e + ""
}
var Wt = function() {
return function(t, e) {
return e && At(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t
}((function t() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.adSelectors = e.adSelectors || [], this.customStyles = e.customStyles || [], this.blockedUrlPatternsSet = new Set(e.blockedUrlPatterns || []), this.adKeywordsRegex = /ads|analytics|tracker|affiliate|stat|pixel|banner|pop|click|outstream\.video|vast|vmap|preroll|midroll|postroll|adserve/i
}), [{
key: "isEmpty",
value: function() {
return 0 === this.adSelectors.length && 0 === this.customStyles.length && 0 === this.blockedUrlPatternsSet.size
}
}, {
key: "shouldBlockUrl",
value: function(t) {
if (!t || "string" != typeof t) return !1;
if (this.adKeywordsRegex.test(t)) return !0;
var e, n = function(t, e) {
var n = "undefined" != typeof Symbol && t[Symbol.iterator] || t["@@iterator"];
if (!n) {
if (Array.isArray(t) || (n = function(t, e) {
if (t) {
if ("string" == typeof t) return Nt(t, e);
var n = {}.toString.call(t).slice(8, -1);
return "Object" === n && t.constructor && (n = t.constructor.name), "Map" === n || "Set" === n ? Array.from(t) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? Nt(t, e) : void 0
}
}(t)) || e && t && "number" == typeof t.length) {
n && (t = n);
var r = 0,
o = function() {};
return {
s: o,
n: function() {
return r >= t.length ? {
done: !0
} : {
done: !1,
value: t[r++]
}
},
e: function(t) {
throw t
},
f: o
}
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
}
var i, a = !0,
s = !1;
return {
s: function() {
n = n.call(t)
},
n: function() {
var t = n.next();
return a = t.done, t
},
e: function(t) {
s = !0, i = t
},
f: function() {
try {
a || null == n.return || n.return()
} finally {
if (s) throw i
}
}
}
}(this.blockedUrlPatternsSet);
try {
for (n.s(); !(e = n.n()).done;) {
var r = e.value;
if (t.includes(r)) return !0
}
} catch (t) {
n.e(t)
} finally {
n.f()
}
return !1
}
}])
}();
const Ut = Wt;
function qt(t) {
return qt = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, qt(t)
}
function Ft(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, Xt(r.key), r)
}
}
function Xt(t) {
var e = function(t) {
if ("object" != qt(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != qt(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == qt(e) ? e : e + ""
}
var Gt = function() {
return function(t, e) {
return e && Ft(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t
}((function t(e) {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.config = e
}), [{
key: "applyAdBlockStyles",
value: function() {
if (0 !== this.config.adSelectors.length || 0 !== this.config.customStyles.length) {
var t = document.createElement("style");
t.id = "adblock-styles", t.type = "text/css";
var e = "";
this.config.adSelectors.length > 0 && (e += this.config.adSelectors.join(", ") + " { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; }"), this.config.customStyles.length > 0 && (e += "\n" + this.config.customStyles.map((function(t) {
return "".concat(t.selector, " { ").concat(t.styles, " }")
})).join("\n")), t.textContent = e, document.head.appendChild(t), console.log("已应用广告屏蔽样式")
}
}
}])
}();
const Yt = Gt;
function Qt(t) {
return Qt = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, Qt(t)
}
function Zt(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, $t(r.key), r)
}
}
function $t(t) {
var e = function(t) {
if ("object" != Qt(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != Qt(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == Qt(e) ? e : e + ""
}
var Jt = function() {
return function(t, e) {
return e && Zt(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t
}((function t(e) {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.config = e, this.CLEANUP_THROTTLE = 500, this.observer = null
}), [{
key: "cleanIframes",
value: function() {
for (var t = (arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : null) || document.getElementsByTagName("iframe"), e = 0; e < t.length; e++) {
var n = t[e];
n.src && !n.src.includes("plyr.io") && n.remove()
}
}
}, {
key: "removeAdElements",
value: function() {
if (0 !== this.config.adSelectors.length)
for (var t = 0; t < this.config.adSelectors.length; t++) try {
for (var e = document.querySelectorAll(this.config.adSelectors[t]), n = 0; n < e.length; n++) e[n].remove()
} catch (t) {}
}
}, {
key: "observeDOMChanges",
value: function() {
var t = this;
if (!this.observer) {
var e = !1,
n = !1,
r = null,
o = function() {
e && (t.removeAdElements(), e = !1), n && (t.cleanIframes(), n = !1), r = null
};
this.observer = new MutationObserver((function(t) {
for (var i = !1, a = !1, s = 0; s < t.length; s++) {
var l = t[s];
if (l.addedNodes.length) {
i = !0;
for (var c = 0; c < l.addedNodes.length; c++)
if ("IFRAME" === l.addedNodes[c].nodeName) {
a = !0;
break
}
}
if (i && a) break
}
i && (e = !0), a && (n = !0), !e && !n || r || (r = setTimeout(o, 50))
})), this.observer.observe(document.documentElement, {
childList: !0,
subtree: !0
}), console.log("DOM监听已启动")
}
}
}, {
key: "disconnect",
value: function() {
this.observer && (this.observer.disconnect(), this.observer = null, console.log("DOM监听已停止"))
}
}])
}();
const Kt = Jt;
function te(t) {
return te = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, te(t)
}
function ee(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, ne(r.key), r)
}
}
function ne(t) {
var e = function(t) {
if ("object" != te(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != te(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == te(e) ? e : e + ""
}
var re = function() {
return function(t, e) {
return e && ee(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t
}((function t(e) {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.config = e
}), [{
key: "blockTrackingRequests",
value: function() {
var t = XMLHttpRequest.prototype.open,
e = this.config;
XMLHttpRequest.prototype.open = function(n, r) {
return "string" == typeof r && e.shouldBlockUrl(r) ? (this.send = function() {}, this.onload = null, void(this.onerror = null)) : t.apply(this, arguments)
};
var n = window.fetch;
window.fetch = function(t, r) {
var o = t;
return t instanceof Request && (o = t.url), "string" == typeof o && e.shouldBlockUrl(o) ? Promise.resolve(new Response("", {
status: 200,
headers: {
"Content-Type": "text/plain"
}
})) : n.apply(this, arguments)
}
}
}, {
key: "blockIframeLoading",
value: function() {
var t = document.createElement,
e = this.config;
document.createElement = function(n) {
var r = t.call(document, n);
if ("iframe" === n.toLowerCase()) {
var o = r.src;
Object.defineProperty(r, "src", {
set: function(t) {
"string" == typeof t && e.shouldBlockUrl(t) ? console.log("拦截iframe:", t) : o = t
},
get: function() {
return o
}
});
var i = r.setAttribute;
r.setAttribute = function(t, n) {
if ("src" !== t || "string" != typeof n || !e.shouldBlockUrl(n)) return i.call(this, t, n);
console.log("拦截iframe setAttribute:", n)
}
}
return r
}
}
}, {
key: "blockPopups",
value: function() {
window.open = function() {
return null
}, "undefined" != typeof unsafeWindow && (unsafeWindow.open = function() {
return null
})
}
}, {
key: "init",
value: function() {
this.blockIframeLoading(), this.blockTrackingRequests(), this.blockPopups(), console.log("请求拦截已启用")
}
}])
}();
const oe = re,
ie = {
adSelectors: ['div[class="space-y-6 mb-6"]', 'div[class*="root--"][class*="bottomRight--"]', 'div[class="grid md:grid-cols-2 gap-8"]', 'ul[class="mb-4 list-none text-nord14 grid grid-cols-2 gap-2"]', 'div[class="space-y-5 mb-5"]', 'iframe[src*="ads"]', 'iframe[src*="banner"]', 'iframe[src*="pop"]', "iframe[data-ad]", 'iframe[id*="ads"]', 'iframe[class*="ads"]', 'iframe:not([src*="plyr.io"])'],
customStyles: [{
selector: 'div[class="my-2 text-sm text-nord4 truncate"]',
styles: "white-space: normal !important;"
}, {
selector: "body",
styles: "background-color: #000000 !important;"
}, {
selector: 'div[class*="z-max"]',
styles: "z-index: 9000 !important;"
}],
blockedUrlPatterns: ["exoclick.com", "juicyads.com", "popads.net", "adsterra.com", "trafficjunky.com", "adnium.com", "ad-maven.com", "browser-update.org", "mopvip.icu", "toppages.pw", "cpmstar.com", "propellerads.com", "tsyndicate.com", "syndication.exosrv.com", "ads.exosrv.com", "tsyndicate.com/sdk", "cdn.tsyndicate.com", "adsco.re", "adscpm.site", "a-ads.com", "ad-delivery.net", "outbrain.com", "taboola.com", "mgid.com", "revcontent.com", "adnxs.com", "pubmatic.com", "rubiconproject.com", "openx.net", "criteo.com", "doubleclick.net"],
isVideoSite: !0,
domains: ["missav.ws", "missav.ai", "missav.com", "thisav.com"]
};
function ae(t) {
return ae = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, ae(t)
}
function se(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, le(r.key), r)
}
}
function le(t) {
var e = function(t) {
if ("object" != ae(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != ae(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == ae(e) ? e : e + ""
}
var ce = function() {
return function(t, e) {
return e && se(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t
}((function t() {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t);
var e, n = (e = window.location.href, /^https?:\/\/(www\.)?(missav|thisav)\.(com|ws|ai)/.test(e) ? ie : {
adSelectors: [],
customStyles: [],
blockedUrlPatterns: []
});
this.config = new Ut(n), this.styleManager = new Yt(this.config), this.domCleaner = new Kt(this.config), this.requestBlocker = new oe(this.config)
}), [{
key: "preventDetection",
value: function() {
window.AdBlock = !1, window.adblock = !1, window.adsbygoogle = {
loaded: !0
}, "undefined" != typeof unsafeWindow && (unsafeWindow.AdBlock = !1, unsafeWindow.adblock = !1, unsafeWindow.adsbygoogle = {
loaded: !0
})
}
}, {
key: "setupPeriodicCleaning",
value: function() {
var t = this;
this.domCleaner.removeAdElements(!0), this.domCleaner.observeDOMChanges(), setInterval((function() {
return t.domCleaner.removeAdElements()
}), 2e3)
}
}, {
key: "init",
value: function() {
var t = this;
this.config.isEmpty() || (console.log("广告屏蔽模块已启用"), this.preventDetection(), this.styleManager.applyAdBlockStyles(), this.requestBlocker.init(), "loading" === document.readyState ? document.addEventListener("DOMContentLoaded", (function() {
return t.setupPeriodicCleaning()
})) : this.setupPeriodicCleaning())
}
}])
}();
const ue = ce;
function de(t) {
return de = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, de(t)
}
function he(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, pe(r.key), r)
}
}
function pe(t) {
var e = function(t) {
if ("object" != de(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != de(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == de(e) ? e : e + ""
}
var fe = function() {
return function(t, e) {
return e && he(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t
}((function t() {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.maxAttempts = 3, this.attemptInterval = 1e3
}), [{
key: "SHOW_MORE_SELECTOR",
get: function() {
return "a.text-nord13.font-medium.flex.items-center"
}
}, {
key: "autoExpandDetails",
value: function() {
var t = this;
console.log("[DetailExpander] 尝试自动展开详情"), this.expandDetailsSingle();
var e = 0,
n = setInterval((function() {
(t.expandDetailsSingle() || ++e >= t.maxAttempts) && (clearInterval(n), console.log("[DetailExpander] 完成尝试 (".concat(e + 1, "次)")))
}), this.attemptInterval)
}
}, {
key: "expandDetailsSingle",
value: function() {
try {
var t = document.querySelector(this.SHOW_MORE_SELECTOR);
if (t) return console.log('[DetailExpander] 找到"显示更多"按钮,点击展开'), t.click(), !0
} catch (t) {
console.error("[DetailExpander] 展开详情时出错:", t)
}
return !1
}
}])
}();
function me(t) {
return me = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, me(t)
}
function ve(t, e) {
(null == e || e > t.length) && (e = t.length);
for (var n = 0, r = Array(e); n < e; n++) r[n] = t[n];
return r
}
function ge(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, ye(r.key), r)
}
}
function ye(t) {
var e = function(t) {
if ("object" != me(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != me(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == me(e) ? e : e + ""
}
var be = function() {
return function(t, e) {
return e && ge(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t
}((function t() {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.maxAttempts = 20, this.attemptInterval = 500
}), [{
key: "setupAutoHighestQuality",
value: function() {
var t = this;
if (console.log("[QualityManager] 尝试设置视频最高画质"), this.setHighestQualitySingle()) console.log("[QualityManager] 成功设置最高画质");
else {
var e = 0,
n = setInterval((function() {
(t.setHighestQualitySingle() || ++e >= t.maxAttempts) && (clearInterval(n), console.log("[QualityManager] 完成尝试 (".concat(e + 1, "次)")))
}), this.attemptInterval);
window.addEventListener("load", (function() {
return t.setHighestQualitySingle()
}))
}
}
}, {
key: "setHighestQualitySingle",
value: function() {
try {
var t = window.player || ("undefined" != typeof unsafeWindow ? unsafeWindow.player : null);
if (!(t && t.config && t.config.quality && t.config.quality.options && t.config.quality.options.length)) return !1;
var e = Math.max.apply(Math, function(t) {
return function(t) {
if (Array.isArray(t)) return ve(t)
}(t) || function(t) {
if ("undefined" != typeof Symbol && null != t[Symbol.iterator] || null != t["@@iterator"]) return Array.from(t)
}(t) || function(t, e) {
if (t) {
if ("string" == typeof t) return ve(t, e);
var n = {}.toString.call(t).slice(8, -1);
return "Object" === n && t.constructor && (n = t.constructor.name), "Map" === n || "Set" === n ? Array.from(t) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? ve(t, e) : void 0
}
}(t) || function() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
}()
}(t.config.quality.options));
return console.log("[QualityManager] 设置画质:", e), t.quality = e, t.config.quality.selected = e, "function" == typeof t.quality && t.quality(e), !0
} catch (t) {
return console.error("[QualityManager] 设置最高画质时出错:", t), !1
}
}
}])
}();
function we(t) {
return we = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, we(t)
}
function ke(t, e) {
(null == e || e > t.length) && (e = t.length);
for (var n = 0, r = Array(e); n < e; n++) r[n] = t[n];
return r
}
function xe(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, Ee(r.key), r)
}
}
function Ee(t) {
var e = function(t) {
if ("object" != we(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != we(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == we(e) ? e : e + ""
}
var Se = function() {
return function(t, e) {
return e && xe(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t
}((function t() {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.redirectRules = [{
pattern: /^https?:\/\/(www\.)?(missav|thisav)\.com\//i,
targetDomain: "missav.ws"
}]
}), [{
key: "checkAndRedirect",
value: function() {
var t, e = window.location.href,
n = function(t, e) {
var n = "undefined" != typeof Symbol && t[Symbol.iterator] || t["@@iterator"];
if (!n) {
if (Array.isArray(t) || (n = function(t, e) {
if (t) {
if ("string" == typeof t) return ke(t, e);
var n = {}.toString.call(t).slice(8, -1);
return "Object" === n && t.constructor && (n = t.constructor.name), "Map" === n || "Set" === n ? Array.from(t) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? ke(t, e) : void 0
}
}(t)) || e && t && "number" == typeof t.length) {
n && (t = n);
var r = 0,
o = function() {};
return {
s: o,
n: function() {
return r >= t.length ? {
done: !0
} : {
done: !1,
value: t[r++]
}
},
e: function(t) {
throw t
},
f: o
}
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
}
var i, a = !0,
s = !1;
return {
s: function() {
n = n.call(t)
},
n: function() {
var t = n.next();
return a = t.done, t
},
e: function(t) {
s = !0, i = t
},
f: function() {
try {
a || null == n.return || n.return()
} finally {
if (s) throw i
}
}
}
}(this.redirectRules);
try {
for (n.s(); !(t = n.n()).done;) {
var r = t.value;
if (r.pattern.test(e)) {
console.log("[UrlRedirector] 匹配到重定向规则:", r);
var o = this.applyRedirect(e, r);
if (o !== e) return console.log("[UrlRedirector] 重定向到:", o), window.location.href = o, !0
}
}
} catch (t) {
n.e(t)
} finally {
n.f()
}
return !1
}
}, {
key: "applyRedirect",
value: function(t, e) {
return e.targetDomain ? t.replace(/^(https?:\/\/)(?:www\.)?(missav|thisav)\.com\//i, "$1".concat(e.targetDomain, "/")) : t
}
}])
}();
function Ce(t) {
return Ce = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, Ce(t)
}
function Le(t, e) {
for (var n = 0; n < e.length; n++) {
var r = e[n];
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, Pe(r.key), r)
}
}
function Pe(t) {
var e = function(t) {
if ("object" != Ce(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var n = e.call(t, "string");
if ("object" != Ce(n)) return n;
throw new TypeError("@@toPrimitive must return a primitive value.")
}
return String(t)
}(t);
return "symbol" == Ce(e) ? e : e + ""
}
var Te = function() {
return function(t, e) {
return e && Le(t.prototype, e), Object.defineProperty(t, "prototype", {
writable: !1
}), t
}((function t() {
! function(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this, t), this.detailExpander = new fe, this.qualityManager = new be, this.urlRedirector = new Se
}), [{
key: "init",
value: function() {
var t = this;
console.log("[UserExperienceEnhancer] 初始化用户体验增强功能"), this.urlRedirector.checkAndRedirect(), "loading" === document.readyState ? document.addEventListener("DOMContentLoaded", (function() {
t.initFeatures()
})) : this.initFeatures()
}
}, {
key: "initFeatures",
value: function() {
try {
this.detailExpander.autoExpandDetails(), this.qualityManager.setupAutoHighestQuality()
} catch (t) {
console.error("[UserExperienceEnhancer] 初始化功能时出错:", t)
}
}
}])
}();
function Me(t) {
return Me = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
}, Me(t)
}
function Be() {
Be = function() {
return e
};
var t, e = {},
n = Object.prototype,
r = n.hasOwnProperty,
o = Object.defineProperty || function(t, e, n) {
t[e] = n.value
},
i = "function" == typeof Symbol ? Symbol : {},
a = i.iterator || "@@iterator",
s = i.asyncIterator || "@@asyncIterator",
l = i.toStringTag || "@@toStringTag";
function c(t, e, n) {
return Object.defineProperty(t, e, {
value: n,
enumerable: !0,
configurable: !0,
writable: !0
}), t[e]
}
try {
c({}, "")
} catch (t) {
c = function(t, e, n) {
return t[e] = n
}
}
function u(t, e, n, r) {
var i = e && e.prototype instanceof g ? e : g,
a = Object.create(i.prototype),
s = new B(r || []);
return o(a, "_invoke", {
value: L(t, n, s)
}), a
}
function d(t, e, n) {
try {
return {
type: "normal",
arg: t.call(e, n)
}
} catch (t) {
return {
type: "throw",
arg: t
}
}
}
e.wrap = u;
var h = "suspendedStart",
p = "suspendedYield",
f = "executing",
m = "completed",
v = {};
function g() {}
function y() {}
function b() {}
var w = {};
c(w, a, (function() {
return this
}));
var k = Object.getPrototypeOf,
x = k && k(k(V([])));
x && x !== n && r.call(x, a) && (w = x);
var E = b.prototype = g.prototype = Object.create(w);
function S(t) {
["next", "throw", "return"].forEach((function(e) {
c(t, e, (function(t) {
return this._invoke(e, t)
}))
}))
}
function C(t, e) {
function n(o, i, a, s) {
var l = d(t[o], t, i);
if ("throw" !== l.type) {
var c = l.arg,
u = c.value;
return u && "object" == Me(u) && r.call(u, "__await") ? e.resolve(u.__await).then((function(t) {
n("next", t, a, s)
}), (function(t) {
n("throw", t, a, s)
})) : e.resolve(u).then((function(t) {
c.value = t, a(c)
}), (function(t) {
return n("throw", t, a, s)
}))
}
s(l.arg)
}
var i;
o(this, "_invoke", {
value: function(t, r) {
function o() {
return new e((function(e, o) {
n(t, r, e, o)
}))
}
return i = i ? i.then(o, o) : o()
}
})
}
function L(e, n, r) {
var o = h;
return function(i, a) {
if (o === f) throw Error("Generator is already running");
if (o === m) {
if ("throw" === i) throw a;
return {
value: t,
done: !0
}
}
for (r.method = i, r.arg = a;;) {
var s = r.delegate;
if (s) {
var l = P(s, r);
if (l) {
if (l === v) continue;
return l
}
}
if ("next" === r.method) r.sent = r._sent = r.arg;
else if ("throw" === r.method) {
if (o === h) throw o = m, r.arg;
r.dispatchException(r.arg)
} else "return" === r.method && r.abrupt("return", r.arg);
o = f;
var c = d(e, n, r);
if ("normal" === c.type) {
if (o = r.done ? m : p, c.arg === v) continue;
return {
value: c.arg,
done: r.done
}
}
"throw" === c.type && (o = m, r.method = "throw", r.arg = c.arg)
}
}
}
function P(e, n) {
var r = n.method,
o = e.iterator[r];
if (o === t) return n.delegate = null, "throw" === r && e.iterator.return && (n.method = "return", n.arg = t, P(e, n), "throw" === n.method) || "return" !== r && (n.method = "throw", n.arg = new TypeError("The iterator does not provide a '" + r + "' method")), v;
var i = d(o, e.iterator, n.arg);
if ("throw" === i.type) return n.method = "throw", n.arg = i.arg, n.delegate = null, v;
var a = i.arg;
return a ? a.done ? (n[e.resultName] = a.value, n.next = e.nextLoc, "return" !== n.method && (n.method = "next", n.arg = t), n.delegate = null, v) : a : (n.method = "throw", n.arg = new TypeError("iterator result is not an object"), n.delegate = null, v)
}
function T(t) {
var e = {
tryLoc: t[0]
};
1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e)
}
function M(t) {
var e = t.completion || {};
e.type = "normal", delete e.arg, t.completion = e
}
function B(t) {
this.tryEntries = [{
tryLoc: "root"
}], t.forEach(T, this), this.reset(!0)
}
function V(e) {
if (e || "" === e) {
var n = e[a];
if (n) return n.call(e);
if ("function" == typeof e.next) return e;
if (!isNaN(e.length)) {
var o = -1,
i = function n() {
for (; ++o < e.length;)
if (r.call(e, o)) return n.value = e[o], n.done = !1, n;
return n.value = t, n.done = !0, n
};
return i.next = i
}
}
throw new TypeError(Me(e) + " is not iterable")
}
return y.prototype = b, o(E, "constructor", {
value: b,
configurable: !0
}), o(b, "constructor", {
value: y,
configurable: !0
}), y.displayName = c(b, l, "GeneratorFunction"), e.isGeneratorFunction = function(t) {
var e = "function" == typeof t && t.constructor;
return !!e && (e === y || "GeneratorFunction" === (e.displayName || e.name))
}, e.mark = function(t) {
return Object.setPrototypeOf ? Object.setPrototypeOf(t, b) : (t.__proto__ = b, c(t, l, "GeneratorFunction")), t.prototype = Object.create(E), t
}, e.awrap = function(t) {
return {
__await: t
}
}, S(C.prototype), c(C.prototype, s, (function() {
return this
})), e.AsyncIterator = C, e.async = function(t, n, r, o, i) {
void 0 === i && (i = Promise);
var a = new C(u(t, n, r, o), i);
return e.isGeneratorFunction(n) ? a : a.next().then((function(t) {
return t.done ? t.value : a.next()
}))
}, S(E), c(E, l, "Generator"), c(E, a, (function() {
return this
})), c(E, "toString", (function() {
return "[object Generator]"
})), e.keys = function(t) {
var e = Object(t),
n = [];
for (var r in e) n.push(r);
return n.reverse(),
function t() {
for (; n.length;) {
var r = n.pop();
if (r in e) return t.value = r, t.done = !1, t
}
return t.done = !0, t
}
}, e.values = V, B.prototype = {
constructor: B,
reset: function(e) {
if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(M), !e)
for (var n in this) "t" === n.charAt(0) && r.call(this, n) && !isNaN(+n.slice(1)) && (this[n] = t)
},
stop: function() {
this.done = !0;
var t = this.tryEntries[0].completion;
if ("throw" === t.type) throw t.arg;
return this.rval
},
dispatchException: function(e) {
if (this.done) throw e;
var n = this;
function o(r, o) {
return s.type = "throw", s.arg = e, n.next = r, o && (n.method = "next", n.arg = t), !!o
}
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var a = this.tryEntries[i],
s = a.completion;
if ("root" === a.tryLoc) return o("end");
if (a.tryLoc <= this.prev) {
var l = r.call(a, "catchLoc"),
c = r.call(a, "finallyLoc");
if (l && c) {
if (this.prev < a.catchLoc) return o(a.catchLoc, !0);
if (this.prev < a.finallyLoc) return o(a.finallyLoc)
} else if (l) {
if (this.prev < a.catchLoc) return o(a.catchLoc, !0)
} else {
if (!c) throw Error("try statement without catch or finally");
if (this.prev < a.finallyLoc) return o(a.finallyLoc)
}
}
}
},
abrupt: function(t, e) {
for (var n = this.tryEntries.length - 1; n >= 0; --n) {
var o = this.tryEntries[n];
if (o.tryLoc <= this.prev && r.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
var i = o;
break
}
}
i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
var a = i ? i.completion : {};
return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, v) : this.complete(a)
},
complete: function(t, e) {
if ("throw" === t.type) throw t.arg;
return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), v
},
finish: function(t) {
for (var e = this.tryEntries.length - 1; e >= 0; --e) {
var n = this.tryEntries[e];
if (n.finallyLoc === t) return this.complete(n.completion, n.afterLoc), M(n), v
}
},
catch: function(t) {
for (var e = this.tryEntries.length - 1; e >= 0; --e) {
var n = this.tryEntries[e];
if (n.tryLoc === t) {
var r = n.completion;
if ("throw" === r.type) {
var o = r.arg;
M(n)
}
return o
}
}
throw Error("illegal catch attempt")
},
delegateYield: function(e, n, r) {
return this.delegate = {
iterator: V(e),
resultName: n,
nextLoc: r
}, "next" === this.method && (this.arg = t), v
}
}, e
}
function Ve(t, e, n, r, o, i, a) {
try {
var s = t[i](a),
l = s.value
} catch (t) {
return void n(t)
}
s.done ? e(l) : Promise.resolve(l).then(r, o)
}! function() {
var t = null;
function e() {
return r.apply(this, arguments)
}
function r() {
var e;
return e = Be().mark((function e() {
return Be().wrap((function(e) {
for (;;) switch (e.prev = e.next) {
case 0:
return e.prev = 0, r = void 0, document.getElementById("tm-player-styles") || ((r = document.querySelector('meta[name="viewport"]')) || ((r = document.createElement("meta")).name = "viewport", document.head.appendChild(r)), r.content = "width=device-width, initial-scale=1.0, viewport-fit=cover", console.log("[Miss NoAD Player] 已配置viewport以支持安全区域"), n(610), console.log("[Miss NoAD Player] 样式注入完成")), (new Te).init(), console.log("[Miss NoAD Player] 用户体验增强模块已初始化"), (t = new at).loadSettings(), new nt({
playerState: t
}).init(), e.next = 10, It();
case 10:
e.sent && console.log("[Miss NoAD Player] 自动登录模块已初始化"), (new ue).init(), console.log("[Miss NoAD Player] 初始化完成"), e.next = 20;
break;
case 17:
e.prev = 17, e.t0 = e.catch(0), console.error("[Miss NoAD Player] 初始化失败:", e.t0);
case 20:
case "end":
return e.stop()
}
var r
}), e, null, [
[0, 17]
])
})), r = function() {
var t = this,
n = arguments;
return new Promise((function(r, o) {
var i = e.apply(t, n);
function a(t) {
Ve(i, r, o, a, s, "next", t)
}
function s(t) {
Ve(i, r, o, a, s, "throw", t)
}
a(void 0)
}))
}, r.apply(this, arguments)
}
"complete" === document.readyState || "interactive" === document.readyState ? setTimeout(e, 100) : document.addEventListener("DOMContentLoaded", (function() {
return setTimeout(e, 100)
}))
}()
})();