kplayer-ts 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -0
- package/dist/kplayer-ts.cjs +402 -0
- package/dist/kplayer-ts.cjs.map +1 -0
- package/dist/kplayer-ts.d.ts +3 -3
- package/dist/kplayer-ts.es.js +2166 -2522
- package/dist/kplayer-ts.es.js.map +1 -1
- package/dist/kplayer-ts.umd.js +139 -134
- package/dist/kplayer-ts.umd.js.map +1 -1
- package/dist/react/index.cjs +2 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.ts +31 -0
- package/dist/react/index.es.js +27 -0
- package/dist/react/index.es.js.map +1 -0
- package/dist/ts/controller.d.ts +7 -0
- package/dist/ts/player.d.ts +3 -0
- package/dist/ts/setting.d.ts +1 -0
- package/dist/ts/types.d.ts +17 -0
- package/package.json +41 -11
- package/dist/kplayer-ts.cjs.js +0 -397
- package/dist/kplayer-ts.cjs.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kplayer-ts.cjs","names":[],"sources":["../src/ts/utils.ts","../src/ts/options.ts","../src/ts/i18n.ts","../src/ts/icons.ts","../src/template/video.ts","../src/template/player.ts","../src/ts/template.ts","../src/ts/ad.ts","../src/ts/events.ts","../src/ts/fullscreen.ts","../src/ts/user.ts","../src/ts/subtitle.ts","../src/ts/subtitles.ts","../src/ts/bar.ts","../src/ts/timer.ts","../src/ts/bezel.ts","../src/ts/thumbnails.ts","../src/ts/controller.ts","../src/ts/setting.ts","../src/ts/hotkey.ts","../src/ts/contextmenu.ts","../src/ts/info-panel.ts","../src/ts/player.ts","../src/ts/index.ts"],"sourcesContent":["import type { ScrollPosition, NameMap, StorageUtil } from \"./types\";\n\n// SSR-safe user-agent: на server (Next.js, Node) `navigator` байхгүй тул\n// модуль импортлох үед унахгүйгээр хоосон мөр руу уначна.\nconst userAgent =\n typeof navigator !== \"undefined\" && navigator.userAgent\n ? navigator.userAgent\n : \"\";\n\nconst isMobile = /mobile|android|iphone|ipod|phone|ipad/i.test(userAgent);\n\nconst utils = {\n /**\n * Parse second to time string\n */\n secondToTime(second: number): string {\n second = second || 0;\n if (second === 0 || second === Infinity || second.toString() === \"NaN\") {\n return \"00:00\";\n }\n const add0 = (num: number): string => (num < 10 ? \"0\" + num : \"\" + num);\n const hour = Math.floor(second / 3600);\n const min = Math.floor((second - hour * 3600) / 60);\n const sec = Math.floor(second - hour * 3600 - min * 60);\n return (hour > 0 ? [hour, min, sec] : [min, sec]).map(add0).join(\":\");\n },\n\n getElementViewLeft(element: HTMLElement): number {\n let actualLeft = element.offsetLeft;\n let current = element.offsetParent as HTMLElement | null;\n const elementScrollLeft =\n document.body.scrollLeft + document.documentElement.scrollLeft;\n if (\n !document.fullscreenElement &&\n !(document as Document & { mozFullScreenElement?: Element })\n .mozFullScreenElement &&\n !(document as Document & { webkitFullscreenElement?: Element })\n .webkitFullscreenElement\n ) {\n while (current !== null) {\n actualLeft += current.offsetLeft;\n current = current.offsetParent as HTMLElement | null;\n }\n } else {\n while (current !== null && current !== element) {\n actualLeft += current.offsetLeft;\n current = current.offsetParent as HTMLElement | null;\n }\n }\n return actualLeft - elementScrollLeft;\n },\n\n getBoundingClientRectViewLeft(element: HTMLElement): number {\n const scrollTop =\n window.scrollY ||\n document.body.scrollTop +\n ((document.documentElement && document.documentElement.scrollTop) || 0);\n\n if (element.getBoundingClientRect) {\n const fn = this\n .getBoundingClientRectViewLeft as typeof this.getBoundingClientRectViewLeft & {\n offset?: number;\n };\n if (typeof fn.offset !== \"number\") {\n const temp = document.createElement(\"div\");\n temp.style.cssText = \"position:absolute;top:0;left:0;\";\n document.body.appendChild(temp);\n fn.offset = -temp.getBoundingClientRect().top - scrollTop;\n document.body.removeChild(temp);\n }\n const rect = element.getBoundingClientRect();\n const offset = fn.offset!;\n return rect.left + offset;\n } else {\n return this.getElementViewLeft(element);\n }\n },\n\n getScrollPosition(): ScrollPosition {\n return {\n left:\n window.scrollX ||\n document.documentElement.scrollLeft ||\n document.body.scrollLeft ||\n 0,\n top:\n window.scrollY ||\n document.documentElement.scrollTop ||\n document.body.scrollTop ||\n 0,\n };\n },\n\n setScrollPosition({ left = 0, top = 0 }: ScrollPosition): void {\n if (this.isFirefox) {\n document.documentElement.scrollLeft = left;\n document.documentElement.scrollTop = top;\n } else {\n window.scrollTo(left, top);\n }\n },\n\n isMobile,\n\n isFirefox: /firefox/i.test(userAgent),\n\n isChrome: /chrome/i.test(userAgent),\n\n isSafari: /safari/i.test(userAgent),\n\n storage: {\n set(key: string, value: string | number): void {\n localStorage.setItem(key, String(value));\n },\n get(key: string): string | null {\n return localStorage.getItem(key);\n },\n } as StorageUtil,\n\n nameMap: {\n dragStart: isMobile ? \"touchstart\" : \"mousedown\",\n dragMove: isMobile ? \"touchmove\" : \"mousemove\",\n dragEnd: isMobile ? \"touchend\" : \"mouseup\",\n } as NameMap,\n\n color2Number(color: string): number {\n if (color[0] === \"#\") {\n color = color.slice(1);\n }\n if (color.length === 3) {\n color = `${color[0]}${color[0]}${color[1]}${color[1]}${color[2]}${color[2]}`;\n }\n return (parseInt(color, 16) + 0x000000) & 0xffffff;\n },\n\n number2Color(number: number): string {\n return \"#\" + (\"00000\" + number.toString(16)).slice(-6);\n },\n\n number2Type(number: number): string {\n switch (number) {\n case 0:\n return \"right\";\n case 1:\n return \"top\";\n case 2:\n return \"bottom\";\n default:\n return \"right\";\n }\n },\n};\n\nexport default utils;\n","import type { KPlayerOptions } from \"./types\";\n\nexport default (\n options: Partial<KPlayerOptions> & { video: KPlayerOptions[\"video\"] },\n): KPlayerOptions => {\n const defaultOption: Partial<KPlayerOptions> = {\n container:\n (options as { element?: HTMLElement }).element ||\n (document.getElementsByClassName(\"kplayer\")[0] as HTMLElement),\n live: false,\n autoplay: false,\n theme: \"#b7daff\",\n loop: false,\n lang: (\n navigator.language ||\n (navigator as Navigator & { browserLanguage?: string }).browserLanguage ||\n \"en\"\n ).toLowerCase(),\n screenshot: false,\n airplay: true,\n chromecast: false,\n hotkey: true,\n preload: \"metadata\",\n volume: 0.7,\n playbackSpeed: [0.5, 0.75, 1, 1.25, 1.5, 2],\n video: {},\n contextmenu: [],\n ad: null,\n vastAD: false,\n vastADURL: \"\",\n mutex: true,\n pluginOptions: { hls: {}, flv: {}, dash: {}, webtorrent: {} },\n preventClickToggle: false,\n };\n\n for (const defaultKey in defaultOption) {\n if (\n Object.prototype.hasOwnProperty.call(defaultOption, defaultKey) &&\n !Object.prototype.hasOwnProperty.call(options, defaultKey)\n ) {\n (options as Record<string, unknown>)[defaultKey] = (\n defaultOption as Record<string, unknown>\n )[defaultKey];\n }\n }\n\n if (options.video) {\n if (!options.video.type) options.video.type = \"auto\";\n }\n\n if (typeof options.awaken === \"object\" && options.awaken) {\n if (!options.awaken.user) options.awaken.user = \"DIYgod\";\n }\n\n if (options.subtitle) {\n if (!options.subtitle.type) options.subtitle.type = \"webvtt\";\n if (!options.subtitle.fontSize) options.subtitle.fontSize = \"20px\";\n if (!options.subtitle.bottom) options.subtitle.bottom = \"40px\";\n if (!options.subtitle.color) options.subtitle.color = \"#fff\";\n }\n\n if (options.video?.quality && options.video.defaultQuality !== undefined) {\n options.video.url = options.video.quality[options.video.defaultQuality].url;\n }\n\n if (options.lang) {\n options.lang = options.lang.toLowerCase();\n }\n\n options.contextmenu = (options.contextmenu || []).concat([\n {\n key: \"about-author\",\n link: \"https://github.com/kenji-07/\",\n },\n ]);\n\n return options as KPlayerOptions;\n};\n","type TranslationMap = Record<string, string>;\ntype TranslationDB = Record<string, TranslationMap>;\n\nfunction i18n(\n this: { lang: string; fallbackLang: string; tran: (key: string) => string },\n lang: string,\n): void {\n this.lang = lang;\n this.fallbackLang = this.lang.includes(\"-\")\n ? this.lang.split(\"-\")[0]\n : this.lang;\n this.tran = (key: string): string => {\n key = key.toLowerCase();\n if (tranTxt[this.lang] && tranTxt[this.lang][key]) {\n return tranTxt[this.lang][key];\n } else if (tranTxt[this.fallbackLang] && tranTxt[this.fallbackLang][key]) {\n return tranTxt[this.fallbackLang][key];\n } else if (standard[key]) {\n return standard[key];\n } else {\n return key;\n }\n };\n}\n\nconst standard: TranslationMap = {\n \"awaken-loading\": \"Awaken ачааллаж байна\",\n top: \"Дээд\",\n bottom: \"Доод\",\n rolling: \"Гүйлгэх\",\n \"input-awaken-enter\": \"Awaken бичээд Enter дарна уу\",\n \"about-author\": \"Зохиогчийн тухай\",\n \"kplayer-feedback\": \"KPlayer санал хүсэлт\",\n \"about-kplayer\": \"KPlayer-ийн тухай\",\n loop: \"Дахин тоглуулах\",\n speed: \"Тоглуулах хурд\",\n quality: \"Бичлэгийн чанар\",\n \"opacity-awaken\": \"Awaken тунгалаг байдал\",\n normal: \"Хэвийн\",\n \"please-input-awaken\": \"Awaken текст оруулна уу!\",\n \"set-awaken-color\": \"Awaken өнгө тохируулах\",\n \"set-awaken-type\": \"Awaken төрөл тохируулах\",\n \"show-awaken\": \"Awaken харуулах\",\n \"video-failed\": \"Видео ачааллахад алдаа гарлаа\",\n \"awaken-failed\": \"Awaken ачааллахад алдаа гарлаа\",\n \"awaken-send-failed\": \"Awaken илгээхэд алдаа гарлаа\",\n \"switching-quality\": \"Чанар солигдож байна: %q\",\n \"switched-quality\": \"Чанар солигдлоо: %q\",\n ff: \">> %s секунд\",\n rew: \"<< %s секунд\",\n \"unlimited-awaken\": \"Хязгааргүй awaken\",\n \"send-awaken\": \"Awaken илгээх\",\n setting: \"ТОХИРГОО\",\n fullscreen: \"Бүтэн дэлгэц\",\n \"web-fullscreen\": \"Вэб бүтэн дэлгэц\",\n send: \"Илгээх\",\n screenshot: \"Дэлгэцийн зураг авах\",\n airplay: \"AirPlay\",\n chromecast: \"Chromecast\",\n subtitle: \"Хадмал орчуулга\",\n off: \"Унтраалттай\",\n \"show-subs\": \"Хадмал харуулах\",\n \"hide-subs\": \"Хадмал нуух\",\n volume: \"Дууны түвшин\",\n live: \"Шууд\",\n \"video-info\": \"Видео мэдээлэл\",\n play: \"Тоглуулах\",\n pause: \"Түр зогсоох\",\n rewind: \"10 секунд хойш\",\n forward: \"10 секунд урагш\",\n mute: \"Дуу хаах\",\n unmute: \"Дуу нээх\",\n seek: \"Хугацааны заагч\",\n \"video-player\": \"Видео тоглуулагч\",\n};\n\nconst tranTxt: TranslationDB = {\n mn: standard,\n en: {\n \"awaken-loading\": \"awaken is loading\",\n top: \"Top\",\n bottom: \"Bottom\",\n rolling: \"Rolling\",\n \"input-awaken-enter\": \"Input awaken, hit Enter\",\n \"about-author\": \"About author\",\n \"kplayer-feedback\": \"KPlayer feedback\",\n \"about-kplayer\": \"About KPlayer\",\n loop: \"Loop\",\n speed: \"Speed\",\n quality: \"Quality\",\n \"opacity-awaken\": \"Opacity for awaken\",\n normal: \"Normal\",\n \"please-input-awaken\": \"Please input awaken content!\",\n \"set-awaken-color\": \"Set awaken color\",\n \"set-awaken-type\": \"Set awaken type\",\n \"show-awaken\": \"Show awaken\",\n \"video-failed\": \"Video load failed\",\n \"awaken-failed\": \"awaken load failed\",\n \"awaken-send-failed\": \"awaken send failed\",\n \"switching-quality\": \"Switching to %q quality\",\n \"switched-quality\": \"Switched to %q quality\",\n ff: \">> %s s\",\n rew: \"<< %s s\",\n \"unlimited-awaken\": \"Unlimited awaken\",\n \"send-awaken\": \"Send awaken\",\n setting: \"Setting\",\n fullscreen: \"Full screen\",\n \"web-fullscreen\": \"Web full screen\",\n send: \"Send\",\n screenshot: \"Screenshot\",\n airplay: \"AirPlay\",\n chromecast: \"ChromeCast\",\n subtitle: \"Subtitle\",\n off: \"Off\",\n \"show-subs\": \"Show subtitle\",\n \"hide-subs\": \"Hide subtitle\",\n volume: \"Volume\",\n live: \"Live\",\n \"video-info\": \"Video info\",\n play: \"Play\",\n pause: \"Pause\",\n rewind: \"Rewind 10 seconds\",\n forward: \"Forward 10 seconds\",\n mute: \"Mute\",\n unmute: \"Unmute\",\n seek: \"Seek slider\",\n \"video-player\": \"Video player\",\n },\n \"zh-cn\": {\n \"awaken-loading\": \"弹幕加载中\",\n top: \"顶部\",\n bottom: \"底部\",\n rolling: \"滚动\",\n \"input-awaken-enter\": \"输入弹幕,回车发送\",\n \"about-author\": \"关于作者\",\n \"kplayer-feedback\": \"播放器意见反馈\",\n \"about-kplayer\": \"关于 KPlayer 播放器\",\n loop: \"洗脑循环\",\n speed: \"速度\",\n quality: \"画质\",\n \"opacity-awaken\": \"弹幕透明度\",\n normal: \"正常\",\n \"please-input-awaken\": \"要输入弹幕内容啊喂!\",\n \"set-awaken-color\": \"设置弹幕颜色\",\n \"set-awaken-type\": \"设置弹幕类型\",\n \"show-awaken\": \"显示弹幕\",\n \"video-failed\": \"视频加载失败\",\n \"awaken-failed\": \"弹幕加载失败\",\n \"awaken-send-failed\": \"弹幕发送失败\",\n \"switching-quality\": \"正在切换至 %q 画质\",\n \"switched-quality\": \"已经切换至 %q 画质\",\n ff: \"快进 %s 秒\",\n rew: \"快退 %s 秒\",\n \"unlimited-awaken\": \"海量弹幕\",\n \"send-awaken\": \"发送弹幕\",\n setting: \"设置\",\n fullscreen: \"全屏\",\n \"web-fullscreen\": \"页面全屏\",\n send: \"发送\",\n screenshot: \"截图\",\n airplay: \"无线投屏\",\n chromecast: \"ChromeCast\",\n subtitle: \"字幕\",\n off: \"关闭\",\n \"show-subs\": \"显示字幕\",\n \"hide-subs\": \"隐藏字幕\",\n volume: \"音量\",\n live: \"直播\",\n \"video-info\": \"视频统计信息\",\n play: \"播放\",\n pause: \"暂停\",\n rewind: \"后退10秒\",\n forward: \"前进10秒\",\n mute: \"静音\",\n unmute: \"取消静音\",\n seek: \"进度条\",\n \"video-player\": \"视频播放器\",\n },\n \"zh-tw\": {\n \"awaken-loading\": \"彈幕載入中\",\n top: \"頂部\",\n bottom: \"底部\",\n rolling: \"滾動\",\n \"input-awaken-enter\": \"輸入彈幕,Enter 發送\",\n \"about-author\": \"關於作者\",\n \"kplayer-feedback\": \"播放器意見回饋\",\n \"about-kplayer\": \"關於 KPlayer 播放器\",\n loop: \"循環播放\",\n speed: \"速度\",\n quality: \"畫質\",\n \"opacity-awaken\": \"彈幕透明度\",\n normal: \"正常\",\n \"please-input-awaken\": \"請輸入彈幕內容啊!\",\n \"set-awaken-color\": \"設定彈幕顏色\",\n \"set-awaken-type\": \"設定彈幕類型\",\n \"show-awaken\": \"顯示彈幕\",\n \"video-failed\": \"影片載入失敗\",\n \"awaken-failed\": \"彈幕載入失敗\",\n \"awaken-send-failed\": \"彈幕發送失敗\",\n \"switching-quality\": \"正在切換至 %q 畫質\",\n \"switched-quality\": \"已經切換至 %q 畫質\",\n ff: \"快進 %s 秒\",\n rew: \"快退 %s 秒\",\n \"unlimited-awaken\": \"巨量彈幕\",\n \"send-awaken\": \"發送彈幕\",\n setting: \"設定\",\n fullscreen: \"全螢幕\",\n \"web-fullscreen\": \"頁面全螢幕\",\n send: \"發送\",\n screenshot: \"截圖\",\n airplay: \"無線投屏\",\n chromecast: \"ChromeCast\",\n subtitle: \"字幕\",\n off: \"關閉\",\n \"show-subs\": \"顯示字幕\",\n \"hide-subs\": \"隱藏字幕\",\n volume: \"音量\",\n live: \"直播\",\n \"video-info\": \"影片統計訊息\",\n play: \"播放\",\n pause: \"暫停\",\n rewind: \"後退10秒\",\n forward: \"前進10秒\",\n mute: \"靜音\",\n unmute: \"取消靜音\",\n seek: \"進度條\",\n \"video-player\": \"視訊播放器\",\n },\n \"ko-kr\": {\n \"awaken-loading\": \"awaken를 불러오는 중입니다.\",\n top: \"Top\",\n bottom: \"Bottom\",\n rolling: \"Rolling\",\n \"input-awaken-enter\": \"awaken를 입력하고 Enter를 누르세요.\",\n \"about-author\": \"만든이\",\n \"kplayer-feedback\": \"피드백 보내기\",\n \"about-kplayer\": \"KPlayer 정보\",\n loop: \"반복\",\n speed: \"배속\",\n quality: \"화질\",\n \"opacity-awaken\": \"awaken 불투명도\",\n normal: \"표준\",\n \"please-input-awaken\": \"awaken를 입력하세요!\",\n \"set-awaken-color\": \"awaken 색상\",\n \"set-awaken-type\": \"awaken 설정\",\n \"show-awaken\": \"awaken 표시\",\n \"video-failed\": \"비디오를 불러오지 못했습니다.\",\n \"awaken-failed\": \"awaken를 불러오지 못했습니다.\",\n \"awaken-send-failed\": \"awaken 전송에 실패했습니다.\",\n \"switching-quality\": \"전환 %q 화질\",\n \"switched-quality\": \"전환 됨 %q 화질\",\n ff: \"앞으로 %s 초\",\n rew: \"뒤로 %s 초\",\n \"unlimited-awaken\": \"끝없는 awaken\",\n \"send-awaken\": \"awaken 보내기\",\n setting: \"설정\",\n fullscreen: \"전체 화면\",\n \"web-fullscreen\": \"웹 내 전체화면\",\n send: \"보내기\",\n screenshot: \"화면 캡쳐\",\n airplay: \"에어플레이\",\n chromecast: \"ChromeCast\",\n subtitle: \"부제\",\n off: \"끄다\",\n \"show-subs\": \"자막 보이기\",\n \"hide-subs\": \"자막 숨기기\",\n volume: \"볼륨\",\n live: \"생방송\",\n \"video-info\": \"비디오 정보\",\n play: \"재생\",\n pause: \"일시정지\",\n rewind: \"10초 뒤로\",\n forward: \"10초 앞으로\",\n mute: \"음소거\",\n unmute: \"음소거 해제\",\n seek: \"탐색 막대\",\n \"video-player\": \"비디오 플레이어\",\n },\n de: {\n \"awaken-loading\": \"awaken lädt...\",\n top: \"Oben\",\n bottom: \"Unten\",\n rolling: \"Rollend\",\n \"input-awaken-enter\": \"Drücke Enter nach dem Einfügen vom awaken\",\n \"about-author\": \"Über den Autor\",\n \"kplayer-feedback\": \"KPlayer Feedback\",\n \"about-kplayer\": \"Über KPlayer\",\n loop: \"Wiederholen\",\n speed: \"Geschwindigkeit\",\n quality: \"Qualität\",\n \"opacity-awaken\": \"Transparenz für awaken\",\n normal: \"Normal\",\n \"please-input-awaken\": \"Bitte awaken Inhalt eingeben!\",\n \"set-awaken-color\": \"awaken Farbe festlegen\",\n \"set-awaken-type\": \"awaken Typ festlegen\",\n \"show-awaken\": \"Zeige awaken\",\n \"video-failed\": \"Das Video konnte nicht geladen werden\",\n \"awaken-failed\": \"awaken konnte nicht geladen werden\",\n \"awaken-send-failed\": \"Das senden von awaken ist fehgeschlagen\",\n \"switching-quality\": \"Wechsle zur %q Qualität\",\n \"switched-quality\": \"Zur %q Qualität gewechselt\",\n ff: \"%s s Vorwärts\",\n rew: \"%s s Zurück\",\n \"unlimited-awaken\": \"Unlimitiertes awaken\",\n \"send-awaken\": \"Sende awaken\",\n setting: \"Einstellungen\",\n fullscreen: \"Vollbild\",\n \"web-fullscreen\": \"Browser Vollbild\",\n send: \"Senden\",\n screenshot: \"Screenshot\",\n airplay: \"AirPlay\",\n chromecast: \"ChromeCast\",\n subtitle: \"Untertitel\",\n off: \"Schließung\",\n \"show-subs\": \"Zeige Untertitel\",\n \"hide-subs\": \"Verstecke Untertitel\",\n volume: \"Lautstärke\",\n live: \"Live\",\n \"video-info\": \"Video Info\",\n play: \"Abspielen\",\n pause: \"Pause\",\n rewind: \"10 Sekunden zurück\",\n forward: \"10 Sekunden vor\",\n mute: \"Stummschalten\",\n unmute: \"Ton einschalten\",\n seek: \"Suchleiste\",\n \"video-player\": \"Videoplayer\",\n },\n ja: {\n \"awaken-loading\": \"コメントを読み込んでいます\",\n top: \"トップ\",\n bottom: \"ボトム\",\n rolling: \"スクロール\",\n \"input-awaken-enter\": \"コメントを入力し,Enter で送信\",\n \"about-author\": \"作者について\",\n \"kplayer-feedback\": \"KPlayer についての意見・要望\",\n \"about-kplayer\": \"KPlayer について\",\n loop: \"くり返し\",\n speed: \"再生速度\",\n quality: \"へ\",\n \"opacity-awaken\": \"コメントの透明度\",\n normal: \"通常\",\n \"please-input-awaken\": \"コメントを入力してください!\",\n \"set-awaken-color\": \"コメントの色\",\n \"set-awaken-type\": \"コメントの種類\",\n \"show-awaken\": \"コメント表示\",\n \"video-failed\": \"ビデオの読み込みに失敗\",\n \"awaken-failed\": \"コメントの読み込みに失敗\",\n \"awaken-send-failed\": \"コメントの送信に失敗\",\n \"switching-quality\": \"%qへ切り替え中\",\n \"switched-quality\": \"%qへ切り替え完了\",\n ff: \"%s 秒早送り\",\n rew: \"%s 秒早戻し\",\n \"unlimited-awaken\": \"コメント無制限\",\n \"send-awaken\": \"コメント送信\",\n setting: \"設定\",\n fullscreen: \"全画面表示\",\n \"web-fullscreen\": \"ブラウザ全体表示\",\n send: \"送信\",\n screenshot: \"画面コピー\",\n airplay: \"AirPlay\",\n chromecast: \"ChromeCast\",\n subtitle: \"字幕\",\n off: \"OFF\",\n \"show-subs\": \"字幕表示\",\n \"hide-subs\": \"字幕非表示\",\n volume: \"音量\",\n live: \"ライブ\",\n \"video-info\": \"動画情報\",\n play: \"再生\",\n pause: \"一時停止\",\n rewind: \"10秒戻る\",\n forward: \"10秒進む\",\n mute: \"ミュート\",\n unmute: \"ミュート解除\",\n seek: \"シークバー\",\n \"video-player\": \"ビデオプレーヤー\",\n },\n ru: {\n \"awaken-loading\": \"Загрузка комментариев\",\n top: \"Вверху\",\n bottom: \"Внизу\",\n rolling: \"Лента\",\n \"input-awaken-enter\": \"Введите комментарий, нажмите Enter\",\n \"about-author\": \"Об авторе\",\n \"kplayer-feedback\": \"Обратная связь\",\n \"about-kplayer\": \"О плеере\",\n loop: \"Закольцевать\",\n speed: \"Скорость\",\n quality: \"Качество\",\n \"opacity-awaken\": \"Прозрачность\",\n normal: \"Обычный\",\n \"please-input-awaken\": \"Пожалуйста, введите комментарий!\",\n \"set-awaken-color\": \"Цвет комментария\",\n \"set-awaken-type\": \"Тип комментария\",\n \"show-awaken\": \"Показать комментарии\",\n \"video-failed\": \"Ошибка загрузки видео\",\n \"awaken-failed\": \"Ошибка загрузки комментариев\",\n \"awaken-send-failed\": \"Ошибка отправки комментария\",\n \"switching-quality\": \"Переключение качества на: %q\",\n \"switched-quality\": \"Установлено качество: %q\",\n ff: \"Вперёд: %s с\",\n rew: \"Назад: %s с\",\n \"unlimited-awaken\": \"Без ограничений\",\n \"send-awaken\": \"Отправить комментарий\",\n setting: \"Настройки\",\n fullscreen: \"На весь экран\",\n \"web-fullscreen\": \"На весь Web экран\",\n send: \"Отправить\",\n screenshot: \"Скриншот\",\n airplay: \"AirPlay\",\n chromecast: \"ChromeCast\",\n subtitle: \"Комментарий\",\n off: \"Выкл\",\n \"show-subs\": \"Показать комментарии\",\n \"hide-subs\": \"Скрыть комментарии\",\n volume: \"Громкость\",\n live: \"Живые комментарии\",\n \"video-info\": \"Информация о видео\",\n play: \"Воспроизвести\",\n pause: \"Пауза\",\n rewind: \"Назад на 10 секунд\",\n forward: \"Вперёд на 10 секунд\",\n mute: \"Без звука\",\n unmute: \"Включить звук\",\n seek: \"Полоса перемотки\",\n \"video-player\": \"Видеоплеер\",\n },\n};\n\nexport { i18n };\n","import play from \"../assets/play.svg?raw\";\nimport pause from \"../assets/pause.svg?raw\";\nimport volumeUp from \"../assets/volume-up.svg?raw\";\nimport volumeDown from \"../assets/volume-down.svg?raw\";\nimport volumeOff from \"../assets/volume-off.svg?raw\";\nimport full from \"../assets/full.svg?raw\";\nimport fullWeb from \"../assets/full-web.svg?raw\";\nimport setting from \"../assets/setting.svg?raw\";\nimport right from \"../assets/right.svg?raw\";\nimport pallette from \"../assets/pallette.svg?raw\";\nimport camera from \"../assets/camera.svg?raw\";\nimport airplay from \"../assets/broadcast.svg?raw\";\nimport subtitle from \"../assets/subtitles.svg?raw\";\nimport loading from \"../assets/loading.svg?raw\";\nimport chromecast from \"../assets/cast.svg?raw\";\nimport back from \"../assets/back.svg?raw\";\nimport rewind from \"../assets/backward.svg?raw\";\nimport forward from \"../assets/forward.svg?raw\";\nimport video from \"../assets/hd.svg?raw\";\n\n// Бүх icon нь чимэглэлийн зориулалттай (товч/мөр нь aria-label-тай) тул\n// screen reader-ээс нуух + focus авахааргүй болгоно.\nconst decorative = (svg: string): string =>\n svg.replace(/<svg\\b/, '<svg aria-hidden=\"true\" focusable=\"false\"');\n\nconst Icons = {\n play: decorative(play),\n pause: decorative(pause),\n volumeUp: decorative(volumeUp),\n volumeDown: decorative(volumeDown),\n volumeOff: decorative(volumeOff),\n full: decorative(full),\n fullWeb: decorative(fullWeb),\n setting: decorative(setting),\n right: decorative(right),\n pallette: decorative(pallette),\n camera: decorative(camera),\n subtitle: decorative(subtitle),\n loading: decorative(loading),\n airplay: decorative(airplay),\n chromecast: decorative(chromecast),\n back: decorative(back),\n rewind: decorative(rewind),\n forward: decorative(forward),\n video: decorative(video),\n};\n\nexport default Icons;\n","import type { SubtitleOptions } from \"../ts/types\";\n\ninterface RenderVideoOptions {\n current?: boolean;\n airplay?: boolean;\n pic?: string;\n screenshot?: boolean;\n preload?: string;\n url?: string;\n subtitle?: SubtitleOptions | null;\n}\n\nfunction escapeAttr(value: unknown): string {\n return String(value ?? \"\")\n .replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n}\n\nexport default function renderVideo({\n current = false,\n airplay = false,\n pic = \"\",\n screenshot = false,\n preload = \"\",\n url = \"\",\n subtitle = null,\n}: RenderVideoOptions = {}): string {\n const enableSubtitle = subtitle && subtitle.type === \"webvtt\";\n\n return `\n<video\n class=\"kplayer-video ${current ? \"kplayer-video-current\" : \"\"}\"\n webkit-playsinline\n ${airplay ? 'x-webkit-airplay=\"allow\"' : \"\"}\n playsinline\n ${pic ? `poster=\"${escapeAttr(pic)}\"` : \"\"}\n ${screenshot ? 'crossorigin=\"anonymous\"' : \"\"}\n ${preload ? `preload=\"${escapeAttr(preload)}\"` : \"\"}\n ${airplay ? \"nosrc\" : url ? `src=\"${escapeAttr(url)}\"` : \"\"}\n>\n ${airplay ? `<source src=\"${escapeAttr(url)}\">` : \"\"}\n</video>`.trim();\n // ← <track> огт байхгүй\n}\n","import renderVideo from \"./video\";\nimport type { KPlayerOptions } from \"../ts/types\";\nimport type Icons from \"../ts/icons\";\n\ninterface RenderPlayerOptions {\n options: KPlayerOptions;\n index: number;\n tran: (key: string) => string;\n icons: typeof Icons;\n mobile: boolean;\n video: {\n current: boolean;\n pic?: string;\n screenshot?: boolean;\n airplay?: boolean;\n chromecast?: boolean;\n preload?: string;\n url?: string;\n subtitle?: KPlayerOptions[\"subtitle\"];\n };\n}\n\nfunction attr(value: unknown): string {\n return String(value ?? \"\")\n .replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n}\n\nfunction html(value: unknown): string {\n return value == null ? \"\" : String(value);\n}\n\nfunction checked(value: unknown): string {\n return value ? \"checked\" : \"\";\n}\n\nexport default function renderPlayer({\n options,\n index: _index,\n tran,\n icons,\n mobile: _mobile,\n video,\n}: RenderPlayerOptions): string {\n const theme = options.theme || \"#b7daff\";\n const awakenBottom =\n options.awaken &&\n typeof options.awaken === \"object\" &&\n options.awaken.bottom\n ? ` style=\"margin-bottom:${attr(options.awaken.bottom)}\"`\n : \"\";\n\n const subtitleIsString =\n options.subtitle && typeof options.subtitle.url === \"string\";\n\n const qualityName =\n options.video?.quality?.[options.video?.defaultQuality ?? 0]?.name || \"\";\n\n const backHTML = options.title?.back\n ? `\n<div class=\"kplayer-back\">\n <button class=\"kplayer-title-back-btn\" aria-label=\"Back\">\n <span class=\"kplayer-icon-content\">${html(icons.back)}</span>\n </button>\n</div>`\n : \"\";\n\n const titleHTML = options.title\n ? `\n${backHTML}\n<div class=\"kplayer-title-bar\">\n <div class=\"kplayer-title-info\">\n <div class=\"kplayer-title-main\">${html(options.title.title || \"\")}</div>\n ${\n options.title.description\n ? `<div class=\"kplayer-title-desc\">${html(options.title.description)}</div>`\n : \"\"\n }\n </div>\n</div>`\n : \"\";\n\n return `\n<div class=\"kplayer-mask\"></div>\n<div class=\"kplayer-video-wrap\">\n ${renderVideo(video)}\n ${\n options.logo\n ? `\n <div class=\"kplayer-logo\">\n <img src=\"${attr(options.logo)}\" alt=\"\">\n </div>`\n : \"\"\n }\n ${titleHTML}\n <div class=\"kplayer-awaken\"${awakenBottom}>\n <div class=\"kplayer-awaken-item kplayer-awaken-item--demo\"></div>\n </div>\n <div class=\"kplayer-subtitle\"></div>\n <div class=\"kplayer-bezel\">\n <span class=\"kplayer-bezel-icon\"></span>\n ${\n options.awaken\n ? `\n <span class=\"kplayer-danloading\">${html(tran(\"awaken-loading\"))}</span>`\n : \"\"\n }\n <span class=\"diplayer-loading-icon\">${html(icons.loading)}</span>\n </div>\n</div>\n<div class=\"kplayer-controller-mask\"></div>\n\n\n<div class=\"kplayer-controller\">\n\n <div class=\"kplayer-icons kplayer-icons-left\">\n <div class=\"kplayer-volume\">\n <button class=\"kplayer-icon kplayer-volume-icon\" aria-label=\"${attr(tran(\"mute\"))}\">\n <span class=\"kplayer-icon-content\">${html(icons.volumeDown)}</span>\n </button>\n <div class=\"kplayer-volume-bar-wrap\" data-balloon-pos=\"up\" role=\"slider\" tabindex=\"0\" aria-label=\"${attr(tran(\"volume\"))}\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"${Math.round((options.volume ?? 0.7) * 100)}\">\n <div class=\"kplayer-volume-bar\">\n <div class=\"kplayer-volume-bar-inner\" style=\"background: ${attr(theme)};\">\n <span class=\"kplayer-thumb\" style=\"background: ${attr(theme)}\"></span>\n </div>\n </div>\n </div>\n </div>\n <span class=\"kplayer-time\">\n <span class=\"kplayer-ptime\">0:00</span> /\n <span class=\"kplayer-dtime\">0:00</span>\n </span>\n ${\n options.live\n ? `\n <span class=\"kplayer-live-badge\"><span class=\"kplayer-live-dot\" style=\"background: ${attr(theme)};\"></span>${html(tran(\"live\"))}</span>`\n : \"\"\n }\n </div>\n\n <div class=\"kplayer-icons kplayer-icons-center\">\n <button class=\"kplayer-icon kplayer-rewind-icon\" aria-label=\"${attr(tran(\"rewind\"))}\">\n <span class=\"kplayer-icon-content\">${html(icons.rewind)}</span>\n </button>\n <button class=\"kplayer-icon kplayer-play-icon\" aria-label=\"${attr(tran(\"play\"))}\">\n <span class=\"kplayer-icon-content\">${html(icons.play)}</span>\n </button>\n <button class=\"kplayer-icon kplayer-forward-icon\" aria-label=\"${attr(tran(\"forward\"))}\">\n <span class=\"kplayer-icon-content\">${html(icons.forward)}</span>\n </button>\n</div>\n\n <div class=\"kplayer-icons kplayer-icons-right\">\n <div class=\"kplayer-camera-icon\"></div>\n <div class=\"kplayer-airplay-icon\"></div>\n <div class=\"kplayer-chromecast-icon\"></div>\n\n <div class=\"kplayer-setting\">\n <button class=\"kplayer-icon kplayer-setting-icon\" data-balloon=\"${attr(tran(\"setting\"))}\" data-balloon-pos=\"up\" aria-label=\"${attr(tran(\"setting\"))}\" aria-haspopup=\"true\">\n <span class=\"kplayer-icon-content\">${html(icons.setting)}</span>\n </button>\n\n <div class=\"kplayer-setting-box\">\n <!-- MAIN PANEL -->\n <div class=\"kplayer-setting-origin-panel\">\n\n ${\n options.subtitle\n ? `\n <div class=\"kplayer-setting-item kplayer-setting-subtitle-entry\">\n <div class=\"kplayer-setting-action-main\">\n <span class=\"kplayer-setting-action-icon\">${html(icons.subtitle)}</span>\n <span class=\"kplayer-label\">${html(tran(\"subtitle\"))}</span>\n </div>\n <div class=\"kplayer-setting-item-right\">\n <span class=\"kplayer-setting-current-value\" id=\"kplayer-subtitle-current\"></span>\n <span class=\"kplayer-setting-arrow\">${html(icons.right)}</span>\n </div>\n</div>`\n : \"\"\n }\n\n ${\n options.video?.quality ||\n options.video?.type === \"hls\" ||\n options.video?.type === \"auto\"\n ? `\n <div class=\"kplayer-setting-item kplayer-setting-quality-entry\">\n <div class=\"kplayer-setting-action-main\">\n <span class=\"kplayer-setting-action-icon\">${html(icons.video || icons.setting)}</span>\n <span class=\"kplayer-label\">${html(tran(\"quality\"))}</span>\n </div>\n <div class=\"kplayer-setting-item-right\">\n <span class=\"kplayer-setting-current-value\" id=\"kplayer-quality-current\"> ${html(qualityName || \"Auto\")}</span>\n <span class=\"kplayer-setting-arrow\">${html(icons.right)}</span>\n </div>\n</div>`\n : \"\"\n }\n\n ${\n options.airplay\n ? `\n <div class=\"kplayer-setting-action kplayer-setting-airplay-entry\">\n <div class=\"kplayer-setting-action-main\">\n <span class=\"kplayer-setting-action-icon\">${html(icons.airplay)}</span>\n <span class=\"kplayer-label\">${html(tran(\"airplay\"))}</span>\n </div>\n </div>`\n : \"\"\n }\n\n ${\n options.chromecast\n ? `\n <div class=\"kplayer-setting-action kplayer-setting-chromecast-entry\">\n <div class=\"kplayer-setting-action-main\">\n <span class=\"kplayer-setting-action-icon\">${html(icons.chromecast)}</span>\n <span class=\"kplayer-label\">${html(tran(\"chromecast\"))}</span>\n </div>\n </div>`\n : \"\"\n }\n\n ${\n options.screenshot\n ? `\n <div class=\"kplayer-setting-action kplayer-setting-screenshot-entry\">\n <div class=\"kplayer-setting-action-main\">\n <span class=\"kplayer-setting-action-icon\">${html(icons.camera)}</span>\n <span class=\"kplayer-label\">${html(tran(\"screenshot\"))}</span>\n </div>\n </div>`\n : \"\"\n }\n\n <div class=\"kplayer-setting-item kplayer-setting-speed\">\n <div class=\"kplayer-setting-action-main\">\n <span class=\"kplayer-label\">${html(tran(\"speed\"))}</span>\n </div>\n <div class=\"kplayer-setting-item-right\">\n <span class=\"kplayer-setting-speed-badge\" id=\"kplayer-speed-current\">1×</span>\n <span class=\"kplayer-setting-arrow\">${html(icons.right)}</span>\n </div>\n</div>\n\n <div class=\"kplayer-setting-item kplayer-setting-loop\">\n <div class=\"kplayer-setting-action-main\">\n <span class=\"kplayer-label\">${html(tran(\"loop\"))}</span>\n </div>\n <div class=\"kplayer-toggle\">\n <input class=\"kplayer-toggle-setting-input\" type=\"checkbox\" name=\"kplayer-toggle\" ${checked(options.loop)}>\n <label for=\"kplayer-toggle\"></label>\n </div>\n</div>\n\n <div class=\"kplayer-setting-item kplayer-setting-showdan\">\n <div class=\"kplayer-toggle\">\n <input class=\"kplayer-showdan-setting-input\" type=\"checkbox\" name=\"kplayer-toggle-dan\" ${checked(true)}>\n <label for=\"kplayer-toggle-dan\"></label>\n </div>\n</div>\n\n <div class=\"kplayer-setting-item kplayer-setting-danunlimit\">\n <span class=\"kplayer-label\">${html(tran(\"unlimited-awaken\"))}</span>\n <div class=\"kplayer-toggle\">\n <input class=\"kplayer-danunlimit-setting-input\" type=\"checkbox\" name=\"kplayer-toggle-danunlimit\" ${checked(\n typeof options.awaken === \"object\" &&\n options.awaken?.unlimited,\n )}>\n <label for=\"kplayer-toggle-danunlimit\"></label>\n </div>\n </div>\n\n <div class=\"kplayer-setting-item kplayer-setting-awaken\">\n <span class=\"kplayer-label\">${html(tran(\"opacity-awaken\"))}</span>\n <div class=\"kplayer-awaken-bar-wrap\">\n <div class=\"kplayer-awaken-bar\">\n <div class=\"kplayer-awaken-bar-inner\">\n <span class=\"kplayer-thumb\"></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- SPEED PANEL -->\n <div class=\"kplayer-setting-speed-panel\">\n <div class=\"kplayer-setting-panel-back kplayer-setting-back-main\">\n <div class=\"kplayer-setting-action-main\">\n <span class=\"kplayer-setting-back-icon\">${html(icons.back)}</span>\n <span class=\"kplayer-label\">${html(tran(\"speed\"))}</span>\n </div>\n </div>\n ${(options.playbackSpeed || [])\n .map(\n (speed) => `\n <div class=\"kplayer-setting-speed-item\" data-speed=\"${attr(speed)}\">\n <span class=\"kplayer-label\">${html(speed === 1 ? tran(\"normal\") : speed)}</span>\n <span class=\"kplayer-check-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg></span>\n </div>`,\n )\n .join(\"\")}\n </div>\n\n <!-- SUBTITLE PANEL -->\n <div class=\"kplayer-setting-subtitle-panel\">\n <div class=\"kplayer-setting-panel-back kplayer-setting-back-main\">\n <div class=\"kplayer-setting-action-main\">\n <span class=\"kplayer-setting-back-icon\">${html(icons.back)}</span>\n <span class=\"kplayer-label\">${html(tran(\"subtitle\"))}</span>\n </div>\n </div>\n ${\n options.subtitle\n ? subtitleIsString\n ? `\n <div class=\"kplayer-setting-subtitle-toggle\">\n <div class=\"kplayer-setting-action-main\">\n <span class=\"kplayer-setting-action-icon\">${html(icons.subtitle)}</span>\n <span class=\"kplayer-label\">${html(tran(\"hide-subs\"))}</span>\n </div>\n </div>`\n : `\n <div class=\"kplayer-subtitles-inline\">\n <div class=\"kplayer-subtitles-box\">\n <div class=\"kplayer-subtitles-panel\">\n ${(Array.isArray(options.subtitle.url)\n ? options.subtitle.url\n : []\n )\n .map((item) => {\n const subItem = item as {\n url?: string;\n lang?: string;\n name?: string;\n };\n const label = subItem.lang\n ? subItem.name\n ? `${subItem.name} (${tran(subItem.lang)})`\n : tran(subItem.lang)\n : subItem.name || \"\";\n return `\n<div class=\"kplayer-subtitles-item\" data-subtitle=\"${attr(subItem.url)}\">\n <span class=\"kplayer-label\">${html(label)}</span>\n <span class=\"kplayer-check-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg></span>\n</div>`;\n })\n .join(\"\")}\n </div>\n </div>\n </div>`\n : \"\"\n }\n </div>\n\n <!-- QUALITY PANEL -->\n <div class=\"kplayer-setting-quality-panel\">\n <div class=\"kplayer-setting-panel-back kplayer-setting-back-main\">\n <div class=\"kplayer-setting-action-main\">\n <span class=\"kplayer-setting-back-icon\">${html(icons.back)}</span>\n <span class=\"kplayer-label\">${html(tran(\"quality\"))}</span>\n </div>\n </div>\n ${\n options.video?.quality ||\n options.video?.type === \"hls\" ||\n options.video?.type === \"auto\"\n ? `\n <div class=\"kplayer-quality-inline\">\n <div class=\"kplayer-quality-list\">\n ${\n options.video?.quality\n ? options.video.quality\n .map(\n (item, i) => `\n <div class=\"kplayer-quality-item\" data-index=\"${i}\">\n <span class=\"kplayer-label\">${html(item.name)}</span>\n <span class=\"kplayer-check-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg></span>\n </div>`,\n )\n .join(\"\")\n : \"\"\n }\n </div>\n </div>`\n : \"\"\n }\n </div>\n </div>\n</div>\n\n <button class=\"kplayer-icon kplayer-full-in-icon\" data-balloon=\"${attr(tran(\"web-fullscreen\"))}\" data-balloon-pos=\"up\" aria-label=\"${attr(tran(\"web-fullscreen\"))}\">\n <span class=\"kplayer-icon-content\">${html(icons.fullWeb)}</span>\n </button>\n <button class=\"kplayer-icon kplayer-full-icon\" data-balloon=\"${attr(tran(\"fullscreen\"))}\" data-balloon-pos=\"up\" aria-label=\"${attr(tran(\"fullscreen\"))}\">\n <span class=\"kplayer-icon-content\">${html(icons.full)}</span>\n </button>\n </div>\n\n <div class=\"kplayer-bar-wrap\" role=\"slider\" tabindex=\"0\" aria-label=\"${attr(tran(\"seek\"))}\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\" aria-valuetext=\"0:00\">\n <div class=\"kplayer-bar-time hidden\">00:00</div>\n <div class=\"kplayer-bar-preview\"></div>\n <div class=\"kplayer-bar\">\n <div class=\"kplayer-loaded\" style=\"width: 0;\"></div>\n <div class=\"kplayer-played\" style=\"width: 0; background: ${attr(theme)}\">\n <span class=\"kplayer-thumb\" style=\"background: ${attr(theme)}\"></span>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"kplayer-info-panel kplayer-info-panel-hide\">\n <div class=\"kplayer-info-panel-close\">[x]</div>\n <div class=\"kplayer-info-panel-item kplayer-info-panel-item-version\">\n <span class=\"kplayer-info-panel-item-title\">Player version</span>\n <span class=\"kplayer-info-panel-item-data\"></span>\n </div>\n <div class=\"kplayer-info-panel-item kplayer-info-panel-item-fps\">\n <span class=\"kplayer-info-panel-item-title\">Player FPS</span>\n <span class=\"kplayer-info-panel-item-data\"></span>\n </div>\n <div class=\"kplayer-info-panel-item kplayer-info-panel-item-type\">\n <span class=\"kplayer-info-panel-item-title\">Video type</span>\n <span class=\"kplayer-info-panel-item-data\"></span>\n </div>\n <div class=\"kplayer-info-panel-item kplayer-info-panel-item-url\">\n <span class=\"kplayer-info-panel-item-title\">Video url</span>\n <span class=\"kplayer-info-panel-item-data\"></span>\n </div>\n <div class=\"kplayer-info-panel-item kplayer-info-panel-item-resolution\">\n <span class=\"kplayer-info-panel-item-title\">Video resolution</span>\n <span class=\"kplayer-info-panel-item-data\"></span>\n </div>\n <div class=\"kplayer-info-panel-item kplayer-info-panel-item-duration\">\n <span class=\"kplayer-info-panel-item-title\">Video duration</span>\n <span class=\"kplayer-info-panel-item-data\"></span>\n </div>\n ${\n options.awaken\n ? `\n <div class=\"kplayer-info-panel-item kplayer-info-panel-item-awaken-id\">\n <span class=\"kplayer-info-panel-item-title\">Awaken id</span>\n <span class=\"kplayer-info-panel-item-data\"></span>\n </div>\n <div class=\"kplayer-info-panel-item kplayer-info-panel-item-awaken-api\">\n <span class=\"kplayer-info-panel-item-title\">Awaken api</span>\n <span class=\"kplayer-info-panel-item-data\"></span>\n </div>\n <div class=\"kplayer-info-panel-item kplayer-info-panel-item-awaken-amount\">\n <span class=\"kplayer-info-panel-item-title\">Awaken amount</span>\n <span class=\"kplayer-info-panel-item-data\"></span>\n </div>`\n : \"\"\n }\n</div>\n\n<div class=\"kplayer-menu\">\n ${(options.contextmenu || [])\n .map((item) => {\n const text = `${item.key ? tran(item.key) : \"\"}${item.text ? item.text : \"\"}`;\n return `\n <div class=\"kplayer-menu-item\">\n <a ${item.link ? 'target=\"_blank\" rel=\"noopener noreferrer\"' : \"\"} href=\"${attr(item.link || \"#\")}\">${html(text)}</a>\n </div>`;\n })\n .join(\"\")}\n</div>\n\n<div class=\"kplayer-notice-list\"></div>\n<button class=\"kplayer-mobile-play\" style=\"display:none!important\">\n ${html(icons.play)}\n</button>\n\n<div class=\"kplayer-mobile-controls\">\n <button class=\"kplayer-mobile-rewind\" aria-label=\"${attr(tran(\"rewind\"))}\">\n <span class=\"kplayer-icon-content\">${html(icons.rewind)}</span>\n </button>\n <button class=\"kplayer-mobile-play-btn\" aria-label=\"${attr(tran(\"play\"))}\">\n <span class=\"kplayer-icon-content\">${html(icons.play)}</span>\n </button>\n <button class=\"kplayer-mobile-forward\" aria-label=\"${attr(tran(\"forward\"))}\">\n <span class=\"kplayer-icon-content\">${html(icons.forward)}</span>\n </button>\n</div>\n\n`.trim();\n}\n","import Icons from \"./icons\";\nimport renderPlayer from \"../template/player\";\nimport utils from \"./utils\";\nimport type { KPlayerOptions } from \"./types\";\nimport { i18n } from \"./i18n\";\n\ninterface TemplateOptions {\n container: HTMLElement;\n options: KPlayerOptions;\n index: number;\n tran: (key: string) => string;\n}\n\nclass Template {\n container: HTMLElement;\n options: KPlayerOptions;\n index: number;\n tran: (key: string) => string;\n\n // DOM refs\n volumeBar!: HTMLElement;\n volumeBarWrap!: HTMLElement;\n volumeBarWrapWrap!: HTMLElement;\n volumeButton!: HTMLElement;\n volumeButtonIcon!: HTMLElement;\n volumeIcon!: HTMLElement;\n playedBar!: HTMLElement;\n loadedBar!: HTMLElement;\n playedBarWrap!: HTMLElement;\n playedBarTime!: HTMLElement;\n awaken!: HTMLElement | null;\n awakenLoading!: HTMLElement | null;\n video!: HTMLVideoElement;\n bezel!: HTMLElement;\n playButton!: HTMLElement;\n mobilePlayButton!: HTMLElement;\n videoWrap!: HTMLElement;\n controllerMask!: HTMLElement;\n ptime!: HTMLElement;\n settingButton!: HTMLElement;\n settingBox!: HTMLElement;\n mask!: HTMLElement;\n loop!: HTMLElement;\n loopToggle!: HTMLInputElement;\n showAwaken!: HTMLElement;\n showAwakenToggle!: HTMLInputElement;\n unlimitAwaken!: HTMLElement;\n unlimitAwakenToggle!: HTMLInputElement;\n speed!: HTMLElement;\n speedItem!: NodeListOf<HTMLElement>;\n awakenOpacityBar!: HTMLElement | null;\n awakenOpacityBarWrap!: HTMLElement | null;\n awakenOpacityBarWrapWrap!: HTMLElement | null;\n awakenOpacityBox!: HTMLElement | null;\n dtime!: HTMLElement;\n controller!: HTMLElement;\n browserFullButton!: HTMLElement;\n webFullButton!: HTMLElement;\n menu!: HTMLElement;\n menuItem!: NodeListOf<HTMLElement>;\n qualityList!: HTMLElement;\n camareButton!: HTMLElement | null;\n airplayButton!: HTMLElement | null;\n chromecastButton!: HTMLElement | null;\n subtitleButton!: HTMLElement | null;\n subtitleButtonInner!: HTMLElement | null;\n subtitlesBox!: HTMLElement | null;\n subtitlesItem!: NodeListOf<HTMLElement>;\n subtitle!: HTMLElement;\n subtrack!: HTMLTrackElement | null;\n barPreview!: HTMLElement;\n barWrap!: HTMLElement;\n noticeList!: HTMLElement;\n infoPanel!: HTMLElement | null;\n infoPanelClose!: HTMLElement | null;\n infoVersion!: HTMLElement | null;\n infoFPS!: HTMLElement | null;\n infoType!: HTMLElement | null;\n infoUrl!: HTMLElement | null;\n infoResolution!: HTMLElement | null;\n infoDuration!: HTMLElement | null;\n infoAwakenId!: HTMLElement | null;\n infoAwakenApi!: HTMLElement | null;\n infoAwakenAmount!: HTMLElement | null;\n subtitlesButton!:\n | HTMLElement\n | {\n addEventListener: () => void;\n dataset: Record<string, string>;\n style: Record<string, string>;\n };\n qualityButton!: HTMLElement;\n titleBar!: HTMLElement | null;\n titleBack!: HTMLElement | null;\n titleMain!: HTMLElement | null;\n titleDesc!: HTMLElement | null;\n subtitleEntry!: HTMLElement | null;\n qualityEntry!: HTMLElement | null;\n qualityItems!: NodeListOf<HTMLElement>;\n\n constructor(options: TemplateOptions) {\n this.container = options.container;\n this.options = options.options;\n this.index = options.index;\n this.tran = options.tran;\n this.init();\n }\n\n init(): void {\n this.container.innerHTML = renderPlayer({\n options: this.options,\n index: this.index,\n tran: this.tran,\n icons: Icons,\n mobile: utils.isMobile,\n video: {\n current: true,\n pic: this.options.video.pic,\n screenshot: this.options.screenshot,\n airplay:\n utils.isSafari && !utils.isChrome ? this.options.airplay : false,\n chromecast: this.options.chromecast,\n preload: this.options.preload,\n url: this.options.video.url,\n subtitle: this.options.subtitle,\n },\n });\n\n const q = <T extends Element>(sel: string) =>\n this.container.querySelector<T>(sel);\n const qa = <T extends Element>(sel: string) =>\n this.container.querySelectorAll<T>(sel);\n\n this.volumeBar = q<HTMLElement>(\".kplayer-volume-bar-inner\")!;\n this.volumeBarWrap = q<HTMLElement>(\".kplayer-volume-bar\")!;\n this.volumeBarWrapWrap = q<HTMLElement>(\".kplayer-volume-bar-wrap\")!;\n this.volumeButton = q<HTMLElement>(\".kplayer-volume\")!;\n this.volumeButtonIcon = q<HTMLElement>(\".kplayer-volume-icon\")!;\n this.volumeIcon = q<HTMLElement>(\n \".kplayer-volume-icon .kplayer-icon-content\",\n )!;\n this.playedBar = q<HTMLElement>(\".kplayer-played\")!;\n this.loadedBar = q<HTMLElement>(\".kplayer-loaded\")!;\n this.playedBarWrap = q<HTMLElement>(\".kplayer-bar-wrap\")!;\n this.playedBarTime = q<HTMLElement>(\".kplayer-bar-time\")!;\n this.awaken = q<HTMLElement>(\".kplayer-awaken\");\n this.awakenLoading = q<HTMLElement>(\".kplayer-danloading\");\n this.video = q<HTMLVideoElement>(\".kplayer-video-current\")!;\n this.bezel = q<HTMLElement>(\".kplayer-bezel-icon\")!;\n this.playButton = q<HTMLElement>(\".kplayer-play-icon\")!;\n this.mobilePlayButton =\n q<HTMLElement>(\".kplayer-mobile-play\") ||\n document.createElement(\"button\");\n this.videoWrap = q<HTMLElement>(\".kplayer-video-wrap\")!;\n this.controllerMask = q<HTMLElement>(\".kplayer-controller-mask\")!;\n this.ptime = q<HTMLElement>(\".kplayer-ptime\")!;\n this.settingButton = q<HTMLElement>(\".kplayer-setting-icon\")!;\n this.settingBox = q<HTMLElement>(\".kplayer-setting-box\")!;\n this.mask = q<HTMLElement>(\".kplayer-mask\")!;\n this.loop = q<HTMLElement>(\".kplayer-setting-loop\")!;\n this.loopToggle = q<HTMLInputElement>(\n \".kplayer-setting-loop .kplayer-toggle-setting-input\",\n )!;\n this.showAwaken = q<HTMLElement>(\".kplayer-setting-showdan\")!;\n this.showAwakenToggle = q<HTMLInputElement>(\n \".kplayer-showdan-setting-input\",\n )!;\n this.unlimitAwaken = q<HTMLElement>(\".kplayer-setting-danunlimit\")!;\n this.unlimitAwakenToggle = q<HTMLInputElement>(\n \".kplayer-danunlimit-setting-input\",\n )!;\n this.speed = q<HTMLElement>(\".kplayer-setting-speed\")!;\n this.speedItem = qa<HTMLElement>(\".kplayer-setting-speed-item\");\n this.awakenOpacityBar = q<HTMLElement>(\".kplayer-awaken-bar-inner\");\n this.awakenOpacityBarWrap = q<HTMLElement>(\".kplayer-awaken-bar\");\n this.awakenOpacityBarWrapWrap = q<HTMLElement>(\".kplayer-awaken-bar-wrap\");\n this.awakenOpacityBox = q<HTMLElement>(\".kplayer-setting-awaken\");\n this.dtime = q<HTMLElement>(\".kplayer-dtime\")!;\n this.controller = q<HTMLElement>(\".kplayer-controller\")!;\n this.browserFullButton = q<HTMLElement>(\".kplayer-full-icon\")!;\n this.webFullButton = q<HTMLElement>(\".kplayer-full-in-icon\")!;\n this.menu = q<HTMLElement>(\".kplayer-menu\")!;\n this.menuItem = qa<HTMLElement>(\".kplayer-menu-item\");\n this.qualityList = q<HTMLElement>(\".kplayer-quality-list\")!;\n this.camareButton = q<HTMLElement>(\".kplayer-camera-icon\");\n this.airplayButton = q<HTMLElement>(\".kplayer-airplay-icon\");\n this.chromecastButton = q<HTMLElement>(\".kplayer-chromecast-icon\");\n this.subtitleButton = q<HTMLElement>(\".kplayer-subtitle-icon\");\n this.subtitleButtonInner = q<HTMLElement>(\n \".kplayer-subtitle-icon .kplayer-icon-content\",\n );\n this.subtitlesBox = q<HTMLElement>(\".kplayer-subtitles-box\");\n this.subtitlesItem = qa<HTMLElement>(\".kplayer-subtitles-item\");\n this.subtitle = q<HTMLElement>(\".kplayer-subtitle\")!;\n this.subtrack = q<HTMLTrackElement>(\".kplayer-subtrack\");\n this.barPreview = q<HTMLElement>(\".kplayer-bar-preview\")!;\n this.barWrap = q<HTMLElement>(\".kplayer-bar-wrap\")!;\n this.noticeList = q<HTMLElement>(\".kplayer-notice-list\")!;\n this.infoPanel = q<HTMLElement>(\".kplayer-info-panel\");\n this.infoPanelClose = q<HTMLElement>(\".kplayer-info-panel-close\");\n this.infoVersion = q<HTMLElement>(\n \".kplayer-info-panel-item-version .kplayer-info-panel-item-data\",\n );\n this.infoFPS = q<HTMLElement>(\n \".kplayer-info-panel-item-fps .kplayer-info-panel-item-data\",\n );\n this.infoType = q<HTMLElement>(\n \".kplayer-info-panel-item-type .kplayer-info-panel-item-data\",\n );\n this.infoUrl = q<HTMLElement>(\n \".kplayer-info-panel-item-url .kplayer-info-panel-item-data\",\n );\n this.infoResolution = q<HTMLElement>(\n \".kplayer-info-panel-item-resolution .kplayer-info-panel-item-data\",\n );\n this.infoDuration = q<HTMLElement>(\n \".kplayer-info-panel-item-duration .kplayer-info-panel-item-data\",\n );\n this.infoAwakenId = q<HTMLElement>(\n \".kplayer-info-panel-item-awaken-id .kplayer-info-panel-item-data\",\n );\n this.infoAwakenApi = q<HTMLElement>(\n \".kplayer-info-panel-item-awaken-api .kplayer-info-panel-item-data\",\n );\n this.infoAwakenAmount = q<HTMLElement>(\n \".kplayer-info-panel-item-awaken-amount .kplayer-info-panel-item-data\",\n );\n this.subtitlesButton = q<HTMLElement>(\".kplayer-subtitles-icon\") || {\n addEventListener: () => {},\n dataset: {},\n style: {},\n };\n this.qualityButton =\n q<HTMLElement>(\".kplayer-quality-icon\") || document.createElement(\"span\");\n this.titleBar = q<HTMLElement>(\".kplayer-title-bar\");\n this.titleBack = q<HTMLElement>(\".kplayer-title-back-btn\");\n this.titleMain = q<HTMLElement>(\".kplayer-title-main\");\n this.titleDesc = q<HTMLElement>(\".kplayer-title-desc\");\n this.subtitleEntry = q<HTMLElement>(\".kplayer-setting-subtitle-entry\");\n this.qualityEntry = q<HTMLElement>(\".kplayer-setting-quality-entry\");\n this.qualityItems = qa<HTMLElement>(\".kplayer-quality-item\");\n }\n\n static NewNotice(text: string, opacity: number, id?: string): HTMLElement {\n const notice = document.createElement(\"div\");\n notice.classList.add(\"kplayer-notice\");\n notice.style.opacity = String(opacity);\n notice.innerText = text;\n if (id) {\n notice.id = `kplayer-notice-${id}`;\n }\n return notice;\n }\n}\n\nexport default Template;\n","import type Kplayer from \"./player\";\nimport type { AdItem } from \"./types\";\n\nclass Ad {\n player: Kplayer;\n options: { url: AdItem[] } | null;\n currentAd: AdItem | null = null;\n adContainer: HTMLDivElement | null = null;\n adContent!: HTMLDivElement;\n skipBtn!: HTMLButtonElement;\n deeplinkBtn!: HTMLButtonElement;\n adLabel!: HTMLDivElement;\n skipTimer?: ReturnType<typeof setInterval>;\n skipRemaining = 0;\n adMarkers: HTMLElement[] = [];\n private _timeUpdateBound = false;\n private _shownAds: Set<string> = new Set();\n private _adVideo: HTMLVideoElement | null = null;\n\n constructor(player: Kplayer) {\n this.player = player;\n this.options = player.options.ad || null;\n this._createAdContainer();\n\n if (\n this.options &&\n Array.isArray(this.options.url) &&\n this.options.url.length > 0\n ) {\n this._renderBarMarkers();\n this._bindTimeUpdate();\n }\n }\n\n private _createAdContainer(): void {\n const wrap = this.player.template.videoWrap;\n\n this.adContainer = document.createElement(\"div\");\n this.adContainer.className = \"kplayer-ad-container\";\n Object.assign(this.adContainer.style, {\n display: \"none\",\n position: \"absolute\",\n top: \"0\",\n left: \"0\",\n right: \"0\",\n bottom: \"0\",\n zIndex: \"100\",\n background: \"#000\",\n });\n\n this.adContent = document.createElement(\"div\");\n this.adContent.className = \"kplayer-ad-content\";\n Object.assign(this.adContent.style, {\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: \"relative\",\n });\n\n this.skipBtn = document.createElement(\"button\");\n this.skipBtn.className = \"kplayer-ad-skip-btn\";\n Object.assign(this.skipBtn.style, {\n position: \"absolute\",\n bottom: \"60px\",\n right: \"16px\",\n zIndex: \"60\",\n display: \"none\",\n alignItems: \"center\",\n gap: \"6px\",\n padding: \"6px 14px\",\n border: \"none\",\n borderRadius: \"2px\",\n background: \"rgba(255, 255, 255, 0.96)\",\n color: \"rgba(0, 0, 0, 1.0)\",\n fontSize: \"13px\",\n fontWeight: \"400\",\n cursor: \"pointer\",\n });\n this.skipBtn.innerHTML = `<span class=\"kplayer-ad-skip-text\">Skip ad in <span class=\"kplayer-ad-skip-count\">5</span>s</span>`;\n this.skipBtn.addEventListener(\"click\", () => this._skipAd());\n\n this.deeplinkBtn = document.createElement(\"button\");\n this.deeplinkBtn.className = \"kplayer-ad-deeplink-btn\";\n Object.assign(this.deeplinkBtn.style, {\n position: \"absolute\",\n bottom: \"60px\",\n left: \"16px\",\n zIndex: \"60\",\n display: \"none\",\n alignItems: \"center\",\n gap: \"6px\",\n padding: \"6px 14px\",\n border: \"none\",\n borderRadius: \"2px\",\n background: \"rgba(255, 255, 255, 0.96)\",\n color: \"rgba(0, 0, 0, 1.0)\",\n fontSize: \"13px\",\n cursor: \"pointer\",\n });\n this.deeplinkBtn.textContent = \"Learn more\";\n this.deeplinkBtn.addEventListener(\"click\", () => {\n if (this.currentAd?.deeplink) {\n window.open(this.currentAd.deeplink, \"_blank\");\n }\n });\n\n this.adLabel = document.createElement(\"div\");\n this.adLabel.className = \"kplayer-ad-label\";\n Object.assign(this.adLabel.style, {\n position: \"absolute\",\n top: \"12px\",\n left: \"16px\",\n zIndex: \"60\",\n padding: \"5px 10px\",\n borderRadius: \"2px\",\n background: \"rgba(255, 174, 0, 0.8)\",\n color: \"rgba(255, 255, 255, 1.0)\",\n fontSize: \"12px\",\n letterSpacing: \"0.04em\",\n });\n this.adLabel.textContent = \"Ad\";\n\n this.adContainer.appendChild(this.adContent);\n this.adContainer.appendChild(this.skipBtn);\n this.adContainer.appendChild(this.deeplinkBtn);\n this.adContainer.appendChild(this.adLabel);\n wrap.appendChild(this.adContainer);\n }\n\n private _createMarker(pct: number, ad: AdItem): HTMLElement {\n const marker = document.createElement(\"div\");\n marker.className = \"kplayer-ad-marker\";\n marker.style.left = `${pct}%`;\n\n const tooltip = document.createElement(\"span\");\n tooltip.className = \"kplayer-ad-marker-text\";\n\n let tooltipText = \"Ad\";\n if (ad.name?.includes(\"vast_\")) {\n const offset = ad.name.replace(\"vast_\", \"\");\n tooltipText =\n offset === \"start\" || offset === \"end\" ? \"Ad\" : `Ad · ${offset}`;\n } else if (ad.name) {\n tooltipText = ad.name;\n }\n tooltip.textContent = tooltipText;\n marker.appendChild(tooltip);\n\n return marker;\n }\n\n private _renderBarMarkers(): void {\n this.player.on(\"durationchange\", () => {\n const duration = this.player.video.duration;\n if (!duration || duration === Infinity) return;\n\n this.adMarkers.forEach((m) => m.parentNode?.removeChild(m));\n this.adMarkers = [];\n\n (this.options?.url || []).forEach((ad) => {\n if (ad.startTime === undefined || ad.startTime <= 0) return;\n const pct = (ad.startTime / duration) * 100;\n if (pct >= 100) return;\n\n const marker = this._createMarker(pct, ad);\n this.player.template.playedBarWrap.appendChild(marker);\n this.adMarkers.push(marker);\n });\n });\n }\n\n private _bindTimeUpdate(): void {\n if (this._timeUpdateBound) return;\n this._timeUpdateBound = true;\n\n this.player.on(\"timeupdate\", () => {\n if (this.currentAd) return;\n if (!this.options?.url) return;\n\n const currentTime = this.player.video.currentTime;\n const duration = this.player.video.duration;\n\n for (const ad of this.options.url) {\n if (ad._isPostroll && duration && duration !== Infinity) {\n ad.startTime = duration - 1;\n }\n\n const key = `${ad.name}_${ad.startTime}`;\n if (this._shownAds.has(key)) continue;\n\n const diff = Math.abs(currentTime - (ad.startTime || 0));\n if (diff < 0.8) {\n this._shownAds.add(key);\n if (ad._impressionUrl) fetch(ad._impressionUrl).catch(() => {});\n this._showAd(ad);\n break;\n }\n }\n });\n }\n\n private _showAd(ad: AdItem): void {\n this.currentAd = ad;\n this.adContent.innerHTML = \"\";\n if (this.adContainer) this.adContainer.style.display = \"block\";\n this.player.container.classList.add(\"kplayer-ad-playing\");\n\n // ── Controller, title bar нуух ───────────────────\n this.player.controller.hide();\n this.player.controller.disableAutoHide = true;\n\n // Title bar нуух\n const titleBar = this.player.template.titleBar;\n if (titleBar) {\n titleBar.style.opacity = \"0\";\n titleBar.style.visibility = \"hidden\";\n titleBar.style.pointerEvents = \"none\";\n }\n\n // Settings panel хаах (хэрэв нээлттэй байвал)\n this.player.setting.hide();\n // ─────────────────────────────────────────────────\n\n this.deeplinkBtn.style.display = ad.deeplink ? \"flex\" : \"none\";\n\n if (ad.type === \"image\") {\n this._showImageAd(ad);\n } else if (ad.type === \"text\") {\n this._showTextAd(ad);\n } else if (ad.type === \"video\") {\n this._showVideoAd(ad);\n }\n\n if (ad.type !== \"video\") {\n this.player.pause();\n } else {\n this.player.video.pause();\n }\n\n this._startSkipTimer(ad.skipTime || 5);\n}\n\n private _showImageAd(ad: AdItem): void {\n const img = document.createElement(\"img\");\n img.src = ad.url;\n Object.assign(img.style, {\n maxWidth: \"100%\",\n maxHeight: \"100%\",\n objectFit: \"contain\",\n cursor: ad.deeplink ? \"pointer\" : \"default\",\n });\n if (ad.deeplink) {\n img.addEventListener(\"click\", () => window.open(ad.deeplink, \"_blank\"));\n }\n this.adContent.appendChild(img);\n }\n\n private _showTextAd(ad: AdItem): void {\n const bg = ad.backroundColor\n ? ad.backroundColor.startsWith(\"#\")\n ? ad.backroundColor\n : \"#\" + ad.backroundColor\n : \"#1a1a1a\";\n\n this.adContent.style.background = bg;\n if (this.adContainer) this.adContainer.style.background = bg;\n\n const text = document.createElement(\"div\");\n Object.assign(text.style, {\n color: \"#fff\",\n fontSize: \"18px\",\n fontWeight: \"400\",\n textAlign: \"center\",\n padding: \"24px\",\n lineHeight: \"1.6\",\n cursor: ad.deeplink ? \"pointer\" : \"default\",\n });\n text.textContent = ad.url;\n if (ad.deeplink) {\n text.addEventListener(\"click\", () => window.open(ad.deeplink, \"_blank\"));\n }\n this.adContent.appendChild(text);\n }\n\n private _showVideoAd(ad: AdItem): void {\n if (this.adContainer) this.adContainer.style.background = \"#000\";\n this.adContent.style.background = \"#000\";\n\n const video = document.createElement(\"video\");\n video.src = ad.url;\n video.autoplay = true;\n video.controls = false;\n Object.assign(video.style, {\n width: \"100%\",\n height: \"100%\",\n objectFit: \"contain\",\n cursor: ad.deeplink ? \"pointer\" : \"default\",\n });\n if (ad.deeplink) {\n video.addEventListener(\"click\", () => window.open(ad.deeplink, \"_blank\"));\n }\n video.addEventListener(\"ended\", () => this._closeAd());\n this.adContent.appendChild(video);\n this._adVideo = video;\n }\n\n private _startSkipTimer(seconds: number): void {\n this.skipRemaining = seconds;\n this.skipBtn.style.display = \"flex\";\n\n const textEl = this.skipBtn.querySelector(\".kplayer-ad-skip-text\");\n\n this.skipBtn.disabled = true;\n this.skipBtn.style.opacity = \"0.6\";\n this.skipBtn.style.cursor = \"default\";\n\n if (textEl) {\n textEl.innerHTML = `Skip ad in <span class=\"kplayer-ad-skip-count\">${this.skipRemaining}</span>s`;\n }\n\n clearInterval(this.skipTimer);\n this.skipTimer = setInterval(() => {\n this.skipRemaining--;\n\n if (this.skipRemaining <= 0) {\n clearInterval(this.skipTimer);\n this.skipBtn.disabled = false;\n this.skipBtn.style.opacity = \"1\";\n this.skipBtn.style.cursor = \"pointer\";\n if (textEl) textEl.textContent = \"Skip ad\";\n } else {\n if (textEl) {\n textEl.innerHTML = `Skip ad in <span class=\"kplayer-ad-skip-count\">${this.skipRemaining}</span>s`;\n }\n }\n }, 1000);\n }\n\n private _skipAd(): void {\n if (this.skipRemaining > 0) return;\n this._closeAd();\n }\n\n private _closeAd(): void {\n clearInterval(this.skipTimer);\n this.player.container.classList.remove(\"kplayer-ad-playing\");\n\n if (this._adVideo) {\n this._adVideo.pause();\n this._adVideo.src = \"\";\n this._adVideo = null;\n }\n\n this.adContent.style.background = \"\";\n if (this.adContainer) {\n this.adContainer.style.background = \"#000\";\n this.adContainer.style.display = \"none\";\n }\n this.skipBtn.style.display = \"none\";\n this.deeplinkBtn.style.display = \"none\";\n this.adContent.innerHTML = \"\";\n\n // ── Controller, title bar буцаах ─────────────────\n this.player.controller.disableAutoHide = false;\n this.player.controller.show();\n\n // Title bar буцаах\n const titleBar = this.player.template.titleBar;\n if (titleBar) {\n titleBar.style.opacity = \"\";\n titleBar.style.visibility = \"\";\n titleBar.style.pointerEvents = \"\";\n titleBar.style.transform = \"\";\n }\n // ─────────────────────────────────────────────────\n\n const lastAd = this.currentAd;\n this.currentAd = null;\n\n if (lastAd && lastAd.startTime !== undefined) {\n const resumeTime = (lastAd.startTime || 0) + 0.5;\n const duration = this.player.video.duration || 0;\n if (duration > 0 && resumeTime < duration) {\n this.player.video.currentTime = resumeTime;\n }\n }\n\n this.player.play();\n}\n\n async _loadVAST(url: string): Promise<void> {\n try {\n const res = await fetch(url);\n const text = await res.text();\n const parser = new DOMParser();\n const xml = parser.parseFromString(text, \"text/xml\");\n\n const vmapNS = \"http://www.iab.net/videosuite/vmap\";\n const adBreaks = xml.getElementsByTagNameNS(vmapNS, \"AdBreak\");\n\n if (adBreaks.length > 0) {\n const duration = this.player.video.duration || 0;\n const vastAds: Array<{\n vastUrl: string;\n startTime: number;\n timeOffset: string;\n }> = [];\n\n for (const adBreak of Array.from(adBreaks)) {\n const timeOffset = adBreak.getAttribute(\"timeOffset\") || \"\";\n let startTime = 0;\n\n if (timeOffset === \"start\") {\n startTime = 0;\n } else if (timeOffset === \"end\") {\n startTime = duration > 0 ? duration - 1 : 99999;\n } else if (timeOffset) {\n startTime = this._parseTime(timeOffset);\n }\n\n const adTagURI = adBreak.getElementsByTagNameNS(\n vmapNS,\n \"AdTagURI\",\n )[0];\n const vastUrl = adTagURI?.textContent?.trim();\n if (vastUrl) {\n vastAds.push({ vastUrl, startTime, timeOffset });\n }\n }\n\n for (const { vastUrl, startTime, timeOffset } of vastAds) {\n await this._fetchVASTAndRegister(vastUrl, startTime, timeOffset);\n }\n\n this._registerVMAPMarkers();\n } else {\n await this._parseVASTAndShow(xml, 0, 5);\n }\n } catch (e) {\n console.warn(\"[Kplayer] VAST/VMAP load failed:\", e);\n }\n }\n\n private async _fetchVASTAndRegister(\n vastUrl: string,\n startTime: number,\n timeOffset: string,\n ): Promise<void> {\n try {\n const res = await fetch(vastUrl);\n const text = await res.text();\n const parser = new DOMParser();\n const xml = parser.parseFromString(text, \"text/xml\");\n\n const mediaFile = xml.querySelector(\"MediaFile\");\n const videoUrl = mediaFile?.textContent?.trim();\n const skipOffsetAttr = xml\n .querySelector(\"Linear\")\n ?.getAttribute(\"skipoffset\");\n const skipTime = skipOffsetAttr ? this._parseTime(skipOffsetAttr) : 5;\n const impressionUrl = xml\n .querySelector(\"Impression\")\n ?.textContent?.trim();\n\n if (!videoUrl) return;\n\n const ad: AdItem = {\n type: \"video\",\n url: videoUrl,\n startTime,\n skipTime,\n name: `vast_${timeOffset}`,\n _impressionUrl: impressionUrl,\n _isPostroll: timeOffset === \"end\",\n };\n\n if (!this.options) this.options = { url: [] };\n if (!Array.isArray(this.options.url)) this.options.url = [];\n this.options.url.push(ad);\n } catch (e) {\n console.warn(\"[Kplayer] VAST fetch failed:\", vastUrl, e);\n }\n }\n\n private _registerVMAPMarkers(): void {\n const render = () => {\n const duration = this.player.video.duration;\n if (!duration || duration === Infinity) return;\n\n (this.options?.url || []).forEach((ad) => {\n if (ad._isPostroll) ad.startTime = duration - 1;\n });\n\n this.adMarkers.forEach((m) => m.parentNode?.removeChild(m));\n this.adMarkers = [];\n\n (this.options?.url || []).forEach((ad) => {\n if (ad.startTime === undefined || ad.startTime <= 0) return;\n const pct = (ad.startTime / duration) * 100;\n if (pct >= 100) return;\n\n const marker = this._createMarker(pct, ad);\n this.player.template.playedBarWrap.appendChild(marker);\n this.adMarkers.push(marker);\n });\n };\n\n if (this.player.video.duration && this.player.video.duration !== Infinity) {\n render();\n } else {\n this.player.on(\"durationchange\", render);\n }\n\n this._bindTimeUpdate();\n }\n\n private async _parseVASTAndShow(\n xml: Document,\n startTime: number,\n defaultSkip: number,\n ): Promise<void> {\n const mediaFile = xml.querySelector(\"MediaFile\");\n const videoUrl = mediaFile?.textContent?.trim();\n const skipOffsetAttr = xml\n .querySelector(\"Linear\")\n ?.getAttribute(\"skipoffset\");\n const skipTime = skipOffsetAttr\n ? this._parseTime(skipOffsetAttr)\n : defaultSkip;\n const impressionUrl = xml.querySelector(\"Impression\")?.textContent?.trim();\n if (impressionUrl) fetch(impressionUrl).catch(() => {});\n if (videoUrl) {\n this._showAd({ type: \"video\", url: videoUrl, startTime, skipTime });\n }\n }\n\n private _parseTime(str: string): number {\n if (!str) return 0;\n const parts = str.split(\":\");\n if (parts.length !== 3) return 0;\n return (\n parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60 + parseFloat(parts[2])\n );\n }\n\n destroy(): void {\n clearInterval(this.skipTimer);\n this.adMarkers.forEach((m) => m.parentNode?.removeChild(m));\n if (this.adContainer?.parentNode) {\n this.adContainer.parentNode.removeChild(this.adContainer);\n }\n }\n}\n\nexport default Ad;\n","type EventCallback = (info?: unknown) => void;\n\nclass Events {\n events: Record<string, EventCallback[]>;\n videoEvents: string[];\n playerEvents: string[];\n\n constructor() {\n this.events = {};\n\n this.videoEvents = [\n \"abort\",\n \"canplay\",\n \"canplaythrough\",\n \"durationchange\",\n \"emptied\",\n \"ended\",\n \"error\",\n \"loadeddata\",\n \"loadedmetadata\",\n \"loadstart\",\n \"mozaudioavailable\",\n \"pause\",\n \"play\",\n \"playing\",\n \"progress\",\n \"ratechange\",\n \"seeked\",\n \"seeking\",\n \"stalled\",\n \"suspend\",\n \"timeupdate\",\n \"volumechange\",\n \"waiting\",\n ];\n\n this.playerEvents = [\n \"screenshot\",\n \"thumbnails_show\",\n \"thumbnails_hide\",\n \"awaken_show\",\n \"awaken_hide\",\n \"awaken_clear\",\n \"awaken_loaded\",\n \"awaken_send\",\n \"awaken_opacity\",\n \"contextmenu_show\",\n \"contextmenu_hide\",\n \"notice_show\",\n \"notice_hide\",\n \"quality_start\",\n \"quality_end\",\n \"destroy\",\n \"resize\",\n \"fullscreen\",\n \"fullscreen_cancel\",\n \"webfullscreen\",\n \"webfullscreen_cancel\",\n \"subtitle_show\",\n \"subtitle_hide\",\n \"subtitle_change\",\n \"title_back\",\n ];\n }\n\n on(name: string, callback: EventCallback): void {\n if (this.type(name) && typeof callback === \"function\") {\n if (!this.events[name]) {\n this.events[name] = [];\n }\n this.events[name].push(callback);\n }\n }\n\n trigger(name: string, info?: unknown): void {\n if (this.events[name] && this.events[name].length) {\n for (let i = 0; i < this.events[name].length; i++) {\n this.events[name][i](info);\n }\n }\n }\n\n type(name: string): string | null {\n if (this.playerEvents.indexOf(name) !== -1) {\n return \"player\";\n } else if (this.videoEvents.indexOf(name) !== -1) {\n return \"video\";\n }\n console.error(`Unknown event name: ${name}`);\n return null;\n }\n}\n\nexport default Events;\n","import utils from \"./utils\";\nimport type KPlayer from \"./player\";\nimport type { FullScreenType, ScrollPosition } from \"./types\";\n\ntype DocWithFullscreen = Document & {\n mozFullScreenElement?: Element;\n webkitFullscreenElement?: Element;\n msFullscreenElement?: Element;\n cancelFullScreen?: () => void;\n mozCancelFullScreen?: () => void;\n webkitCancelFullScreen?: () => void;\n webkitCancelFullscreen?: () => void;\n msCancelFullScreen?: () => void;\n msExitFullscreen?: () => void;\n};\n\ntype ElementWithFullscreen = HTMLElement & {\n mozRequestFullScreen?: () => void;\n webkitRequestFullscreen?: () => void;\n msRequestFullscreen?: () => void;\n};\n\ntype VideoWithFullscreen = HTMLVideoElement & {\n webkitEnterFullscreen?: () => void;\n webkitEnterFullScreen?: () => void;\n};\n\nclass FullScreen {\n player: KPlayer;\n lastScrollPosition: ScrollPosition;\n fullscreenchange: () => void;\n docfullscreenchange: () => void;\n\n constructor(player: KPlayer) {\n this.player = player;\n this.lastScrollPosition = { left: 0, top: 0 };\n\n this.player.events.on(\"webfullscreen\", () => {\n this.player.resize();\n });\n this.player.events.on(\"webfullscreen_cancel\", () => {\n this.player.resize();\n utils.setScrollPosition(this.lastScrollPosition);\n });\n\n this.fullscreenchange = () => {\n this.player.resize();\n if (this.isFullScreen(\"browser\")) {\n this.player.events.trigger(\"fullscreen\");\n } else {\n utils.setScrollPosition(this.lastScrollPosition);\n this.player.events.trigger(\"fullscreen_cancel\");\n }\n };\n\n this.docfullscreenchange = () => {\n const doc = document as DocWithFullscreen;\n const fullEle =\n document.fullscreenElement ||\n doc.mozFullScreenElement ||\n doc.msFullscreenElement;\n if (fullEle && fullEle !== this.player.container) return;\n\n this.player.resize();\n if (fullEle) {\n this.player.events.trigger(\"fullscreen\");\n } else {\n utils.setScrollPosition(this.lastScrollPosition);\n this.player.events.trigger(\"fullscreen_cancel\");\n }\n };\n\n if (/Firefox/.test(navigator.userAgent)) {\n document.addEventListener(\n \"mozfullscreenchange\",\n this.docfullscreenchange,\n );\n document.addEventListener(\"fullscreenchange\", this.docfullscreenchange);\n } else {\n this.player.container.addEventListener(\n \"fullscreenchange\",\n this.fullscreenchange,\n );\n this.player.container.addEventListener(\n \"webkitfullscreenchange\",\n this.fullscreenchange,\n );\n document.addEventListener(\"msfullscreenchange\", this.docfullscreenchange);\n document.addEventListener(\"MSFullscreenChange\", this.docfullscreenchange);\n }\n }\n\n isFullScreen(type: FullScreenType = \"browser\"): Element | boolean | null {\n const doc = document as DocWithFullscreen;\n switch (type) {\n case \"browser\":\n return (\n document.fullscreenElement ||\n doc.mozFullScreenElement ||\n (doc as DocWithFullscreen & { webkitFullscreenElement?: Element })\n .webkitFullscreenElement ||\n doc.msFullscreenElement ||\n null\n );\n case \"web\":\n return this.player.container.classList.contains(\"kplayer-fulled\");\n }\n }\n\n request(type: FullScreenType = \"browser\"): void {\n const anotherType: FullScreenType = type === \"browser\" ? \"web\" : \"browser\";\n const anotherTypeOn = this.isFullScreen(anotherType);\n if (!anotherTypeOn) {\n this.lastScrollPosition = utils.getScrollPosition();\n }\n\n switch (type) {\n case \"browser\": {\n const el = this.player.container as ElementWithFullscreen;\n const video = this.player.video as VideoWithFullscreen;\n if (el.requestFullscreen) {\n el.requestFullscreen();\n } else if (el.mozRequestFullScreen) {\n el.mozRequestFullScreen();\n } else if (el.webkitRequestFullscreen) {\n el.webkitRequestFullscreen();\n } else if (video.webkitEnterFullscreen) {\n video.webkitEnterFullscreen();\n } else if (video.webkitEnterFullScreen) {\n video.webkitEnterFullScreen();\n } else if (el.msRequestFullscreen) {\n el.msRequestFullscreen();\n }\n break;\n }\n case \"web\":\n this.player.container.classList.add(\"kplayer-fulled\");\n document.body.classList.add(\"kplayer-web-fullscreen-fix\");\n this.player.events.trigger(\"webfullscreen\");\n break;\n }\n\n if (anotherTypeOn) {\n this.cancel(anotherType);\n }\n }\n\n cancel(type: FullScreenType = \"browser\"): void {\n const doc = document as DocWithFullscreen;\n switch (type) {\n case \"browser\":\n if (doc.cancelFullScreen) {\n doc.cancelFullScreen();\n } else if (doc.mozCancelFullScreen) {\n doc.mozCancelFullScreen();\n } else if (doc.webkitCancelFullScreen) {\n doc.webkitCancelFullScreen();\n } else if (doc.webkitCancelFullscreen) {\n doc.webkitCancelFullscreen();\n } else if (doc.msCancelFullScreen) {\n doc.msCancelFullScreen();\n } else if (doc.msExitFullscreen) {\n doc.msExitFullscreen();\n } else if (document.exitFullscreen) {\n document.exitFullscreen();\n }\n break;\n case \"web\":\n this.player.container.classList.remove(\"kplayer-fulled\");\n document.body.classList.remove(\"kplayer-web-fullscreen-fix\");\n this.player.events.trigger(\"webfullscreen_cancel\");\n break;\n }\n }\n\n toggle(type: FullScreenType = \"browser\"): void {\n if (this.isFullScreen(type)) {\n this.cancel(type);\n } else {\n this.request(type);\n }\n }\n\n destroy(): void {\n if (/Firefox/.test(navigator.userAgent)) {\n document.removeEventListener(\n \"mozfullscreenchange\",\n this.docfullscreenchange,\n );\n document.removeEventListener(\n \"fullscreenchange\",\n this.docfullscreenchange,\n );\n } else {\n this.player.container.removeEventListener(\n \"fullscreenchange\",\n this.fullscreenchange,\n );\n this.player.container.removeEventListener(\n \"webkitfullscreenchange\",\n this.fullscreenchange,\n );\n document.removeEventListener(\n \"msfullscreenchange\",\n this.docfullscreenchange,\n );\n document.removeEventListener(\n \"MSFullscreenChange\",\n this.docfullscreenchange,\n );\n }\n }\n}\n\nexport default FullScreen;\n","import utils from \"./utils\";\nimport type { KPlayerOptions } from \"./types\";\n\ntype UserKey = \"opacity\" | \"volume\" | \"unlimited\" | \"awaken\" | \"subtitle\";\n\ninterface UserData {\n opacity: number;\n volume: number;\n unlimited: number;\n awaken: number;\n subtitle: number;\n}\n\nclass User {\n storageName: Record<UserKey, string>;\n default: UserData;\n data: UserData;\n\n constructor(player: { options: KPlayerOptions }) {\n this.storageName = {\n opacity: \"kplayer-awaken-opacity\",\n volume: \"kplayer-volume\",\n unlimited: \"kplayer-awaken-unlimited\",\n awaken: \"kplayer-awaken-show\",\n subtitle: \"kplayer-subtitle-show\",\n };\n this.default = {\n opacity: 0.7,\n volume: player.options.hasOwnProperty(\"volume\")\n ? (player.options.volume ?? 0.7)\n : 0.7,\n unlimited:\n (player.options.awaken &&\n typeof player.options.awaken === \"object\" &&\n player.options.awaken.unlimited\n ? 1\n : 0) || 0,\n awaken: 1,\n subtitle: 1,\n };\n this.data = {} as UserData;\n this.init();\n }\n\n init(): void {\n for (const item in this.storageName) {\n const key = item as UserKey;\n const name = this.storageName[key];\n this.data[key] = parseFloat(\n utils.storage.get(name) || String(this.default[key]),\n );\n }\n }\n\n get(key: UserKey): number {\n return this.data[key];\n }\n\n set(key: UserKey, value: number): void {\n this.data[key] = value;\n utils.storage.set(this.storageName[key], value);\n }\n}\n\nexport default User;\n","import type Events from \"./events\";\nimport type { SubtitleOptions } from \"./types\";\n\nclass Subtitle {\n container: HTMLElement;\n video: HTMLVideoElement;\n options: SubtitleOptions;\n events: Events;\n private _track: TextTrack | null = null;\n\n constructor(\n container: HTMLElement,\n video: HTMLVideoElement,\n options: SubtitleOptions,\n events: Events,\n ) {\n this.container = container;\n this.video = video;\n this.options = options;\n this.events = events;\n this.init();\n }\n\n init(): void {\n this.container.style.fontSize = this.options.fontSize || \"20px\";\n this.container.style.bottom = this.options.bottom || \"40px\";\n this.container.style.color = this.options.color || \"#fff\";\n }\n\n // VTT текстийг parse хийж cue inject хийнэ — <track> ашиглахгүй\n async loadVttText(vttText: string): Promise<void> {\n this._clearTrack();\n\n const track = this.video.addTextTrack(\"subtitles\", \"\", \"\");\n track.mode = \"showing\"; // ← 'hidden' биш 'showing' болгоно\n this._track = track;\n\n const cues = this._parseVtt(vttText);\n\n for (const cue of cues) {\n try {\n track.addCue(cue);\n } catch (e) {\n console.warn(\"[KPlayer] addCue failed:\", e);\n }\n }\n\n // oncuechange-ийн оронд timeupdate ашиглах\n this._onTimeUpdateBound = this._onTimeUpdate.bind(this);\n this.video.addEventListener(\"timeupdate\", this._onTimeUpdateBound);\n }\n\n private _onTimeUpdateBound?: () => void;\n\n private _onTimeUpdate(): void {\n if (!this._track?.activeCues) return;\n\n const cues = this._track.activeCues;\n this.container.innerHTML = \"\";\n\n for (let i = 0; i < cues.length; i++) {\n const cue = cues[i] as VTTCue;\n const p = document.createElement(\"p\");\n p.textContent = cue.text.replace(/<[^>]+>/g, \"\");\n this.container.appendChild(p);\n }\n }\n\n private _clearTrack(): void {\n // timeupdate listener устгах\n if (this._onTimeUpdateBound) {\n this.video.removeEventListener(\"timeupdate\", this._onTimeUpdateBound);\n this._onTimeUpdateBound = undefined;\n }\n\n if (this._track) {\n while (this._track.cues && this._track.cues.length > 0) {\n this._track.removeCue(this._track.cues[0]);\n }\n this._track.mode = \"disabled\";\n this._track.oncuechange = null;\n this._track = null;\n }\n this.container.innerHTML = \"\";\n }\n\n private _parseVtt(vttText: string): VTTCue[] {\n const cues: VTTCue[] = [];\n const text = vttText.replace(/^\\uFEFF/, \"\").trim();\n const blocks = text.split(/\\n\\s*\\n/);\n\n\n for (const block of blocks) {\n const lines = block.trim().split(\"\\n\");\n if (!lines.length) continue;\n\n // WEBVTT, NOTE, STYLE алгасах\n if (\n lines[0].startsWith(\"WEBVTT\") ||\n lines[0].startsWith(\"NOTE\") ||\n lines[0].startsWith(\"STYLE\")\n )\n continue;\n\n // Timestamp мөр хайх\n let timeLineIdx = -1;\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].includes(\"-->\")) {\n timeLineIdx = i;\n break;\n }\n }\n if (timeLineIdx === -1) continue;\n\n const timeLine = lines[timeLineIdx];\n\n // MM:SS.mmm эсвэл HH:MM:SS.mmm хоёуланг дэмжих\n const timeMatch = timeLine.match(\n /((?:\\d{2}:)?\\d{2}:\\d{2}[.,]\\d{3})\\s*-->\\s*((?:\\d{2}:)?\\d{2}:\\d{2}[.,]\\d{3})/,\n );\n\n\n if (!timeMatch) continue;\n\n const start = this._timeToSeconds(timeMatch[1]);\n const end = this._timeToSeconds(timeMatch[2]);\n const cueText = lines\n .slice(timeLineIdx + 1)\n .join(\"\\n\")\n .trim();\n\n\n if (!cueText) continue;\n\n try {\n const cue = new VTTCue(start, end, cueText);\n cues.push(cue);\n } catch (e) {\n console.warn(\"[KPlayer] VTTCue failed:\", e, start, end, cueText);\n }\n }\n\n return cues;\n }\n\n private _timeToSeconds(timeStr: string): number {\n const normalized = timeStr.replace(\",\", \".\");\n const parts = normalized.split(\":\");\n\n if (parts.length === 3) {\n // HH:MM:SS.mmm\n return (\n parseInt(parts[0]) * 3600 +\n parseInt(parts[1]) * 60 +\n parseFloat(parts[2])\n );\n } else if (parts.length === 2) {\n // MM:SS.mmm\n return parseInt(parts[0]) * 60 + parseFloat(parts[1]);\n }\n return 0;\n }\n\n show(): void {\n this.container.classList.remove(\"kplayer-subtitle-hide\");\n if (this._track) this._track.mode = \"hidden\";\n this.events.trigger(\"subtitle_show\");\n }\n\n hide(): void {\n this.container.classList.add(\"kplayer-subtitle-hide\");\n if (this._track) this._track.mode = \"disabled\";\n this.events.trigger(\"subtitle_hide\");\n }\n\n toggle(): void {\n if (this.container.classList.contains(\"kplayer-subtitle-hide\")) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n destroy(): void {\n this._clearTrack();\n }\n}\n\nexport default Subtitle;\n","import type KPlayer from \"./player\";\n\nclass Subtitles {\n player: KPlayer;\n\n constructor(player: KPlayer) {\n this.player = player;\n\n this.player.template.mask.addEventListener(\"click\", () => {\n this.hide();\n });\n\n if (\n this.player.template.subtitlesButton &&\n \"addEventListener\" in this.player.template.subtitlesButton\n ) {\n this.player.template.subtitlesButton.addEventListener(\"click\", () => {\n this.adaptiveHeight();\n this.show();\n });\n }\n\n const items = Array.from(\n this.player.template.subtitlesItem || [],\n ) as HTMLElement[];\n const lastItemIndex = items.length - 1;\n\n if (lastItemIndex < 0) return;\n\n for (let i = 0; i < lastItemIndex; i++) {\n items[i].addEventListener(\"click\", () => {\n this.hide();\n this.selectSubtitle(i);\n });\n }\n\n items[lastItemIndex].addEventListener(\"click\", () => {\n this.hide();\n this.selectOff();\n });\n\n const defaultIdx = this.player.options.subtitle?.index ?? 0;\n if (items[defaultIdx]) {\n items.forEach((el) => el.classList.remove(\"kplayer-selected\"));\n items[defaultIdx].classList.add(\"kplayer-selected\");\n }\n }\n\n reloadTrack(): void {\n const video = this.player.video;\n const track = this.player.template.subtrack;\n\n if (!track) return;\n\n track.default = true;\n\n if (video?.textTracks?.[0]) {\n try {\n video.textTracks[0].mode = \"disabled\";\n video.textTracks[0].mode = \"showing\";\n return;\n } catch (_e) {\n // fallback\n }\n }\n\n if (video && typeof video.load === \"function\") {\n video.load();\n }\n }\n\n clearSelected(): void {\n const items = Array.from(\n this.player.template.subtitlesItem || [],\n ) as HTMLElement[];\n items.forEach((el) => el.classList.remove(\"kplayer-selected\"));\n }\n\n selectSubtitle(index: number): void {\n const items = Array.from(\n this.player.template.subtitlesItem || [],\n ) as HTMLElement[];\n const item = items[index];\n if (!item) return;\n\n this.clearSelected();\n item.classList.add(\"kplayer-selected\");\n this.player.options.subtitle!.index = index;\n\n // <track> src тавихын оронд JS-ээр ачаална\n this.player.loadSubtitleByIndex(index);\n\n if (\n this.player.template.subtitle.classList.contains(\"kplayer-subtitle-hide\")\n ) {\n this.subContainerShow();\n }\n }\n\n selectOff(): void {\n const items = Array.from(\n this.player.template.subtitlesItem || [],\n ) as HTMLElement[];\n const lastItemIndex = items.length - 1;\n const offItem = items[lastItemIndex];\n if (!offItem) return;\n\n this.clearSelected();\n offItem.classList.add(\"kplayer-selected\");\n this.player.options.subtitle!.index = lastItemIndex;\n\n // subtitle.ts дотор track-г нуух\n this.player.subtitle?.hide();\n this.player.template.subtitle.innerHTML = \"\";\n\n this.subContainerHide();\n }\n\n subContainerShow(): void {\n this.player.template.subtitle.classList.remove(\"kplayer-subtitle-hide\");\n this.player.events.trigger(\"subtitle_show\");\n }\n\n subContainerHide(): void {\n this.player.template.subtitle.classList.add(\"kplayer-subtitle-hide\");\n this.player.events.trigger(\"subtitle_hide\");\n }\n\n hide(): void {\n this.player.template.subtitlesBox?.classList.remove(\n \"kplayer-subtitles-box-open\",\n );\n this.player.template.mask.classList.remove(\"kplayer-mask-show\");\n this.player.controller.disableAutoHide = false;\n }\n\n show(): void {\n this.player.template.subtitlesBox?.classList.add(\n \"kplayer-subtitles-box-open\",\n );\n this.player.template.mask.classList.add(\"kplayer-mask-show\");\n this.player.controller.disableAutoHide = true;\n }\n\n adaptiveHeight(): void {\n const items = Array.from(this.player.template.subtitlesItem || []);\n const curBoxHeight = items.length * 30 + 14;\n const stdMaxHeight = this.player.template.videoWrap.offsetHeight * 0.8;\n\n if (this.player.template.subtitlesBox) {\n if (curBoxHeight >= stdMaxHeight - 50) {\n this.player.template.subtitlesBox.style.bottom = \"8px\";\n this.player.template.subtitlesBox.style.maxHeight = `${stdMaxHeight - 8}px`;\n } else {\n this.player.template.subtitlesBox.style.bottom = \"50px\";\n this.player.template.subtitlesBox.style.maxHeight = `${stdMaxHeight - 50}px`;\n }\n }\n }\n\n updateUrls(urls: Array<{ url?: string; lang?: string }>): void {\n if (!Array.isArray(urls)) return;\n\n if (this.player.options.subtitle) {\n this.player.options.subtitle.url =\n urls as typeof this.player.options.subtitle.url;\n }\n }\n}\n\nexport default Subtitles;\n","import type Template from \"./template\";\n\ntype BarType = \"volume\" | \"played\" | \"loaded\" | \"awaken\";\ntype BarDirection = \"width\" | \"height\";\n\nclass Bar {\n elements: Partial<Record<BarType, HTMLElement>>;\n\n constructor(template: Template) {\n this.elements = {};\n if (template.volumeBar) this.elements.volume = template.volumeBar;\n if (template.playedBar) this.elements.played = template.playedBar;\n if (template.loadedBar) this.elements.loaded = template.loadedBar;\n if (template.awakenOpacityBar)\n this.elements.awaken = template.awakenOpacityBar;\n }\n\n set(type: BarType, percentage: number, direction: BarDirection): void {\n percentage = Math.max(percentage, 0);\n percentage = Math.min(percentage, 1);\n if (this.elements[type]) {\n this.elements[type]!.style[direction] = percentage * 100 + \"%\";\n }\n }\n\n get(type: BarType): number {\n return parseFloat(this.elements[type]?.style.width || \"0\") / 100;\n }\n}\n\nexport default Bar;\n","import type KPlayer from \"./player\";\n\ntype TimerType = \"loading\" | \"info\" | \"fps\";\n\nclass Timer {\n player: KPlayer;\n types: TimerType[];\n loadingChecker?: ReturnType<typeof setInterval>;\n infoChecker?: ReturnType<typeof setInterval>;\n enableloadingChecker = false;\n enableinfoChecker = false;\n enablefpsChecker = false;\n fpsStart?: Date;\n fpsIndex = 0;\n\n constructor(player: KPlayer) {\n this.player = player;\n\n window.requestAnimationFrame =\n window.requestAnimationFrame ||\n (\n window as Window & {\n webkitRequestAnimationFrame?: typeof requestAnimationFrame;\n }\n ).webkitRequestAnimationFrame ||\n (\n window as Window & {\n mozRequestAnimationFrame?: typeof requestAnimationFrame;\n }\n ).mozRequestAnimationFrame ||\n (\n window as Window & {\n oRequestAnimationFrame?: typeof requestAnimationFrame;\n }\n ).oRequestAnimationFrame ||\n (\n window as Window & {\n msRequestAnimationFrame?: typeof requestAnimationFrame;\n }\n ).msRequestAnimationFrame ||\n function (callback: FrameRequestCallback) {\n window.setTimeout(callback, 1000 / 60);\n return 0;\n };\n\n this.types = [\"loading\", \"info\", \"fps\"];\n this.init();\n }\n\n init(): void {\n this.types.forEach((item) => {\n if (item !== \"fps\") {\n (this as unknown as Record<string, () => void>)[`init${item}Checker`]();\n }\n });\n }\n\n initloadingChecker(): void {\n let lastPlayPos = 0;\n let currentPlayPos = 0;\n let bufferingDetected = false;\n\n this.loadingChecker = setInterval(() => {\n if (this.enableloadingChecker) {\n currentPlayPos = this.player.video.currentTime;\n if (\n !bufferingDetected &&\n currentPlayPos === lastPlayPos &&\n !this.player.video.paused\n ) {\n this.player.container.classList.add(\"kplayer-loading\");\n bufferingDetected = true;\n }\n if (\n bufferingDetected &&\n currentPlayPos > lastPlayPos &&\n !this.player.video.paused\n ) {\n this.player.container.classList.remove(\"kplayer-loading\");\n bufferingDetected = false;\n }\n lastPlayPos = currentPlayPos;\n }\n }, 100);\n }\n\n initfpsChecker(): void {\n window.requestAnimationFrame(() => {\n if (this.enablefpsChecker) {\n this.initfpsChecker();\n if (!this.fpsStart) {\n this.fpsStart = new Date();\n this.fpsIndex = 0;\n } else {\n this.fpsIndex++;\n const fpsCurrent = new Date();\n if (fpsCurrent.getTime() - this.fpsStart.getTime() > 1000) {\n this.player.infoPanel.fps(\n (this.fpsIndex /\n (fpsCurrent.getTime() - this.fpsStart.getTime())) *\n 1000,\n );\n this.fpsStart = new Date();\n this.fpsIndex = 0;\n }\n }\n } else {\n this.fpsStart = undefined;\n this.fpsIndex = 0;\n }\n });\n }\n\n initinfoChecker(): void {\n this.infoChecker = setInterval(() => {\n if (this.enableinfoChecker) {\n this.player.infoPanel.update();\n }\n }, 1000);\n }\n\n enable(type: TimerType): void {\n (this as unknown as Record<string, boolean>)[`enable${type}Checker`] = true;\n if (type === \"fps\") {\n this.initfpsChecker();\n }\n }\n\n disable(type: TimerType): void {\n (this as unknown as Record<string, boolean>)[`enable${type}Checker`] =\n false;\n }\n\n destroy(): void {\n this.types.forEach((item) => {\n (this as unknown as Record<string, boolean>)[`enable${item}Checker`] =\n false;\n const checker = (\n this as unknown as Record<string, ReturnType<typeof setInterval>>\n )[`${item}Checker`];\n if (checker) clearInterval(checker);\n });\n }\n}\n\nexport default Timer;\n","class Bezel {\n container: HTMLElement;\n\n constructor(container: HTMLElement) {\n this.container = container;\n this.container.addEventListener(\"animationend\", () => {\n this.container.classList.remove(\"kplayer-bezel-transition\");\n });\n }\n\n switch(icon: string): void {\n this.container.innerHTML = icon;\n this.container.classList.add(\"kplayer-bezel-transition\");\n }\n}\n\nexport default Bezel;\n","import type Events from \"./events\";\n\ninterface ThumbnailsOptions {\n container: HTMLElement;\n barWidth: number;\n url: string;\n events?: Events;\n}\n\nclass Thumbnails {\n container: HTMLElement;\n barWidth: number;\n events?: Events;\n\n constructor(options: ThumbnailsOptions) {\n this.container = options.container;\n this.barWidth = options.barWidth;\n this.container.style.backgroundImage = `url('${options.url}')`;\n this.events = options.events;\n }\n\n resize(width: number, height: number, barWrapWidth: number): void {\n this.container.style.width = `${width}px`;\n this.container.style.height = `${height}px`;\n this.container.style.top = `${-height + 2}px`;\n this.barWidth = barWrapWidth;\n }\n\n show(): void {\n this.container.style.display = \"block\";\n this.events && this.events.trigger(\"thumbnails_show\");\n }\n\n move(position: number): void {\n this.container.style.backgroundPosition = `-${(Math.ceil((position / this.barWidth) * 100) - 1) * 160}px 0`;\n this.container.style.left = `${Math.min(\n Math.max(position - this.container.offsetWidth / 2, -10),\n this.barWidth - 150,\n )}px`;\n }\n\n hide(): void {\n this.container.style.display = \"none\";\n this.events && this.events.trigger(\"thumbnails_hide\");\n }\n}\n\nexport default Thumbnails;\n","import utils from \"./utils\";\nimport Thumbnails from \"./thumbnails\";\nimport Icons from \"./icons\";\nimport type KPlayer from \"./player\";\n\ndeclare let cast:\n | {\n SessionRequest: new (appId: string) => unknown;\n ApiConfig: new (\n req: unknown,\n cb1: () => void,\n cb2: (status: string) => void,\n ) => unknown;\n ReceiverAvailability: { AVAILABLE: string };\n initialize: (config: unknown, cb: () => void) => void;\n requestSession: (\n success: (s: unknown) => void,\n err: (e: { code: string }) => void,\n ) => void;\n media: {\n DEFAULT_MEDIA_RECEIVER_APP_ID: string;\n MediaInfo: new (url: string) => unknown;\n LoadRequest: new (info: unknown) => unknown;\n };\n }\n | undefined;\n\nlet runOnce = true;\nlet isCasting = false;\n\nclass Controller {\n player: KPlayer;\n autoHideTimer = 0;\n disableAutoHide = false;\n thumbnails?: Thumbnails;\n setAutoHideHandler?: () => void;\n private _skipBtn: HTMLButtonElement | null = null;\n private _skipTarget: number | null = null;\n private session: unknown = undefined;\n private currentMedia: unknown = null;\n // double-tap seek (mobile) төлөв\n private _tapTime = 0;\n private _tapSide: \"left\" | \"right\" | null = null;\n private _tapTimer = 0;\n private _seekAccum = 0;\n private _rippleTimer = 0;\n\n constructor(player: KPlayer) {\n this.player = player;\n\n if (!utils.isMobile) {\n this.setAutoHideHandler = this.setAutoHide.bind(this);\n this.player.container.addEventListener(\n \"mousemove\",\n this.setAutoHideHandler,\n );\n this.player.container.addEventListener(\"click\", this.setAutoHideHandler);\n this.player.on(\"play\", this.setAutoHideHandler);\n this.player.on(\"pause\", this.setAutoHideHandler);\n }\n\n this.initPlayButton();\n this.initSeekButtons();\n this.initThumbnails();\n this.initPlayedBar();\n this.initFullButton();\n this.initQualityButton();\n this.initScreenshotButton();\n if (this.player.options.subtitle) {\n if (typeof this.player.options.subtitle.url === \"string\") {\n this.initSubtitleButton();\n }\n }\n this.initHighlights();\n this.initAirplayButton();\n this.initChromecastButton();\n if (!utils.isMobile) {\n this.initVolumeButton();\n }\n }\n\n initPlayButton(): void {\n this.player.template.playButton.addEventListener(\"click\", () => {\n this.player.toggle();\n });\n\n this.player.template.mobilePlayButton.addEventListener(\"click\", () => {\n this.player.toggle();\n });\n\n if (!utils.isMobile) {\n if (!this.player.options.preventClickToggle) {\n this.player.template.videoWrap.addEventListener(\"click\", () => {\n this.player.toggle();\n });\n this.player.template.controllerMask.addEventListener(\"click\", () => {\n this.player.toggle();\n });\n }\n } else {\n // mobile: видеоны зүүн/баруун хагасыг давхар товшоод ±10 сек гүйлгэнэ,\n // ганц товшилт нь хяналтыг toggle хийнэ.\n this._setupMobileTapSeek();\n this.player.template.controllerMask.addEventListener(\"click\", () => {\n this.toggle();\n });\n }\n\n const mobileRewind = this.player.container.querySelector<HTMLElement>(\n \".kplayer-mobile-rewind\",\n );\n const mobileForward = this.player.container.querySelector<HTMLElement>(\n \".kplayer-mobile-forward\",\n );\n const mobilePlayBtn = this.player.container.querySelector<HTMLElement>(\n \".kplayer-mobile-play-btn\",\n );\n\n mobileRewind?.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.player.seek(this.player.video.currentTime - 10);\n this.setAutoHide();\n });\n mobileForward?.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.player.seek(this.player.video.currentTime + 10);\n this.setAutoHide();\n });\n mobilePlayBtn?.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.player.toggle();\n });\n }\n\n initSeekButtons(): void {\n const rewindBtn = this.player.container.querySelector<HTMLElement>(\n \".kplayer-rewind-icon\",\n );\n const forwardBtn = this.player.container.querySelector<HTMLElement>(\n \".kplayer-forward-icon\",\n );\n\n rewindBtn?.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.player.seek(this.player.video.currentTime - 10);\n });\n forwardBtn?.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.player.seek(this.player.video.currentTime + 10);\n });\n }\n\n initHighlights(): void {\n this._createSkipButton();\n\n this.player.on(\"durationchange\", () => {\n if (\n this.player.video.duration !== 1 &&\n this.player.video.duration !== Infinity\n ) {\n if (this.player.options.highlight) {\n const highlights =\n this.player.template.playedBarWrap.querySelectorAll(\n \".kplayer-highlight\",\n );\n Array.from(highlights).forEach((item) => {\n this.player.template.playedBarWrap.removeChild(item);\n });\n for (let i = 0; i < this.player.options.highlight.length; i++) {\n const h = this.player.options.highlight[i];\n if (!h.text || !h.time) continue;\n\n const p = document.createElement(\"div\");\n p.classList.add(\"kplayer-highlight\");\n p.style.left = (h.time / this.player.video.duration) * 100 + \"%\";\n p.innerHTML = `<span class=\"kplayer-highlight-text\">${h.text}</span>`;\n p.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.player.seek(h.time);\n if (this.player.paused) this.player.play();\n });\n this.player.template.playedBarWrap.insertBefore(\n p,\n this.player.template.playedBarTime,\n );\n }\n }\n }\n });\n\n this.player.on(\"timeupdate\", () => {\n this._updateSkipButton();\n });\n }\n\n private _createSkipButton(): void {\n if (this.player.container.querySelector(\".kplayer-skip-btn\")) return;\n\n const btn = document.createElement(\"button\");\n btn.classList.add(\"kplayer-skip-btn\");\n btn.style.display = \"none\";\n btn.innerHTML = `<span class=\"kplayer-skip-btn-text\"></span>`;\n\n btn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n if (this._skipTarget != null) {\n this.player.seek(this._skipTarget);\n if (this.player.paused) this.player.play();\n }\n btn.style.display = \"none\";\n });\n\n this.player.template.videoWrap.appendChild(btn);\n this._skipBtn = btn;\n this._skipTarget = null;\n }\n\n private _updateSkipButton(): void {\n if (!this.player.options.highlight || !this._skipBtn) return;\n\n const highlights = this.player.options.highlight;\n const currentTime = this.player.video.currentTime;\n let found = false;\n\n for (let i = 0; i < highlights.length - 1; i++) {\n const cur = highlights[i];\n const nxt = highlights[i + 1];\n\n const curIsStart = /\\bstart\\b|\\bэхлэл\\b/i.test(cur.text);\n if (!curIsStart) continue;\n const nxtIsEnd = /\\bend\\b|\\bтөгсгөл\\b/i.test(nxt.text);\n if (!nxtIsEnd) continue;\n if (currentTime < cur.time || currentTime >= nxt.time) continue;\n\n this._skipTarget = nxt.time;\n this._skipBtn.querySelector(\".kplayer-skip-btn-text\")!.textContent =\n cur.text;\n this._skipBtn.style.display = \"flex\";\n found = true;\n break;\n }\n\n if (!found) {\n this._skipBtn.style.display = \"none\";\n }\n }\n\n initThumbnails(): void {\n if (this.player.options.video.thumbnails) {\n this.thumbnails = new Thumbnails({\n container: this.player.template.barPreview,\n barWidth: this.player.template.barWrap.offsetWidth,\n url: this.player.options.video.thumbnails,\n events: this.player.events,\n });\n\n this.player.on(\"loadedmetadata\", () => {\n this.thumbnails?.resize(\n 160,\n (this.player.video.videoHeight / this.player.video.videoWidth) * 160,\n this.player.template.barWrap.offsetWidth,\n );\n });\n }\n }\n\n initPlayedBar(): void {\n const thumbMove = (e: MouseEvent | TouchEvent) => {\n let percentage =\n (((e as MouseEvent).clientX ||\n (e as TouchEvent).changedTouches[0].clientX) -\n utils.getBoundingClientRectViewLeft(\n this.player.template.playedBarWrap,\n )) /\n this.player.template.playedBarWrap.clientWidth;\n percentage = Math.max(0, Math.min(1, percentage));\n this.player.bar.set(\"played\", percentage, \"width\");\n this.player.template.ptime.innerHTML = utils.secondToTime(\n percentage * this.player.video.duration,\n );\n };\n\n const thumbUp = (e: MouseEvent | TouchEvent) => {\n document.removeEventListener(\n utils.nameMap.dragEnd,\n thumbUp as EventListener,\n );\n document.removeEventListener(\n utils.nameMap.dragMove,\n thumbMove as EventListener,\n );\n let percentage =\n (((e as MouseEvent).clientX ||\n (e as TouchEvent).changedTouches[0].clientX) -\n utils.getBoundingClientRectViewLeft(\n this.player.template.playedBarWrap,\n )) /\n this.player.template.playedBarWrap.clientWidth;\n percentage = Math.max(0, Math.min(1, percentage));\n this.player.bar.set(\"played\", percentage, \"width\");\n this.player.seek(\n this.player.bar.get(\"played\") * this.player.video.duration,\n );\n this.player.moveBar = false;\n };\n\n this.player.template.playedBarWrap.addEventListener(\n utils.nameMap.dragStart,\n () => {\n this.player.moveBar = true;\n document.addEventListener(\n utils.nameMap.dragMove,\n thumbMove as EventListener,\n );\n document.addEventListener(\n utils.nameMap.dragEnd,\n thumbUp as EventListener,\n );\n },\n );\n\n this.player.template.playedBarWrap.addEventListener(\n utils.nameMap.dragMove,\n (e) => {\n if (this.player.video.duration) {\n const px =\n this.player.template.playedBarWrap.getBoundingClientRect().left;\n const tx =\n ((e as MouseEvent).clientX ||\n (e as TouchEvent).changedTouches[0].clientX) - px;\n if (tx < 0 || tx > this.player.template.playedBarWrap.offsetWidth)\n return;\n const time =\n this.player.video.duration *\n (tx / this.player.template.playedBarWrap.offsetWidth);\n if (utils.isMobile) this.thumbnails?.show();\n this.thumbnails?.move(tx);\n this.player.template.playedBarTime.style.left = `${tx - (time >= 3600 ? 25 : 20)}px`;\n this.player.template.playedBarTime.innerText =\n utils.secondToTime(time);\n this.player.template.playedBarTime.classList.remove(\"hidden\");\n }\n },\n );\n\n this.player.template.playedBarWrap.addEventListener(\n utils.nameMap.dragEnd,\n () => {\n if (utils.isMobile) this.thumbnails?.hide();\n },\n );\n\n if (!utils.isMobile) {\n this.player.template.playedBarWrap.addEventListener(\"mouseenter\", () => {\n if (this.player.video.duration) {\n this.thumbnails?.show();\n this.player.template.playedBarTime.classList.remove(\"hidden\");\n }\n });\n this.player.template.playedBarWrap.addEventListener(\"mouseleave\", () => {\n if (this.player.video.duration) {\n this.thumbnails?.hide();\n this.player.template.playedBarTime.classList.add(\"hidden\");\n }\n });\n }\n\n // a11y: гар (keyboard)-аар хугацаа гүйлгэх (role=\"slider\")\n this.player.template.playedBarWrap.addEventListener(\n \"keydown\",\n (e: KeyboardEvent) => {\n const dur = this.player.video.duration;\n if (!dur || !isFinite(dur)) return;\n const cur = this.player.video.currentTime;\n let handled = true;\n switch (e.key) {\n case \"ArrowLeft\":\n this.player.seek(cur - 5);\n break;\n case \"ArrowRight\":\n this.player.seek(cur + 5);\n break;\n case \"PageDown\":\n this.player.seek(cur - 30);\n break;\n case \"PageUp\":\n this.player.seek(cur + 30);\n break;\n case \"Home\":\n this.player.seek(0);\n break;\n case \"End\":\n this.player.seek(dur);\n break;\n default:\n handled = false;\n }\n if (handled) e.preventDefault();\n },\n );\n }\n\n initFullButton(): void {\n this.player.template.browserFullButton.addEventListener(\"click\", () => {\n this.player.fullScreen.toggle(\"browser\");\n });\n this.player.template.webFullButton.addEventListener(\"click\", () => {\n this.player.fullScreen.toggle(\"web\");\n });\n }\n\n initVolumeButton(): void {\n const vWidth = 35;\n\n const volumeMove = (event: Event) => {\n const e = event as MouseEvent | TouchEvent;\n const percentage =\n (((e as MouseEvent).clientX ||\n (e as TouchEvent).changedTouches[0].clientX) -\n utils.getBoundingClientRectViewLeft(\n this.player.template.volumeBarWrap,\n ) -\n 5.5) /\n vWidth;\n this.player.volume(percentage);\n };\n\n const volumeUp = () => {\n document.removeEventListener(utils.nameMap.dragEnd, volumeUp);\n document.removeEventListener(utils.nameMap.dragMove, volumeMove);\n this.player.template.volumeButton.classList.remove(\n \"kplayer-volume-active\",\n );\n };\n\n this.player.template.volumeBarWrapWrap.addEventListener(\n \"click\",\n (event) => {\n const percentage =\n ((event.clientX || 0) -\n utils.getBoundingClientRectViewLeft(\n this.player.template.volumeBarWrap,\n ) -\n 5.5) /\n vWidth;\n this.player.volume(percentage);\n },\n );\n\n this.player.template.volumeBarWrapWrap.addEventListener(\n utils.nameMap.dragStart,\n () => {\n document.addEventListener(utils.nameMap.dragMove, volumeMove);\n document.addEventListener(utils.nameMap.dragEnd, volumeUp);\n this.player.template.volumeButton.classList.add(\n \"kplayer-volume-active\",\n );\n },\n );\n\n this.player.template.volumeButtonIcon.addEventListener(\"click\", () => {\n if (this.player.video.muted) {\n this.player.video.muted = false;\n this.player.switchVolumeIcon();\n this.player.bar.set(\"volume\", this.player.volume(), \"width\");\n } else {\n this.player.video.muted = true;\n this.player.template.volumeIcon.innerHTML = Icons.volumeOff;\n this.player.bar.set(\"volume\", 0, \"width\");\n }\n });\n\n // a11y: гар (keyboard)-аар дууны түвшин (role=\"slider\")\n this.player.template.volumeBarWrapWrap.addEventListener(\n \"keydown\",\n (e: KeyboardEvent) => {\n const v = this.player.volume(undefined, true, true);\n let handled = true;\n switch (e.key) {\n case \"ArrowUp\":\n case \"ArrowRight\":\n this.player.volume(Math.min(1, v + 0.05));\n break;\n case \"ArrowDown\":\n case \"ArrowLeft\":\n this.player.volume(Math.max(0, v - 0.05));\n break;\n case \"Home\":\n this.player.volume(1);\n break;\n case \"End\":\n this.player.volume(0);\n break;\n default:\n handled = false;\n }\n if (handled) e.preventDefault();\n },\n );\n }\n\n initQualityButton(): void {\n if (this.player.options.video.quality) {\n const defIdx = this.player.options.video.defaultQuality || 0;\n const items =\n this.player.template.qualityList.querySelectorAll<HTMLElement>(\n \".kplayer-quality-item\",\n );\n if (items[defIdx]) items[defIdx].classList.add(\"kplayer-selected\");\n\n this.player.template.qualityList.addEventListener(\"click\", (e) => {\n const item = (e.target as HTMLElement).closest<HTMLElement>(\n \".kplayer-quality-item\",\n );\n if (item) {\n items.forEach((el) => el.classList.remove(\"kplayer-selected\"));\n item.classList.add(\"kplayer-selected\");\n this.player.switchQuality(Number(item.dataset.index));\n }\n });\n }\n }\n\n initScreenshotButton(): void {\n if (this.player.options.screenshot && this.player.template.camareButton) {\n this.player.template.camareButton.addEventListener(\"click\", () => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = this.player.video.videoWidth;\n canvas.height = this.player.video.videoHeight;\n canvas\n .getContext(\"2d\")\n ?.drawImage(this.player.video, 0, 0, canvas.width, canvas.height);\n\n canvas.toBlob((blob) => {\n if (!blob) return;\n const dataURL = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = dataURL;\n link.download = \"kplayer.png\";\n link.style.display = \"none\";\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(dataURL);\n this.player.events.trigger(\"screenshot\", dataURL);\n });\n });\n }\n }\n\n initAirplayButton(): void {\n if (this.player.options.airplay) {\n if (\n (window as Window & { WebKitPlaybackTargetAvailabilityEvent?: unknown })\n .WebKitPlaybackTargetAvailabilityEvent\n ) {\n this.player.video.addEventListener(\n \"webkitplaybacktargetavailabilitychanged\",\n function (this: KPlayer, event: Event) {\n const ev = event as Event & { availability: string };\n if (ev.availability === \"available\") {\n this.template.airplayButton &&\n ((\n this.template.airplayButton as HTMLElement & {\n disable?: boolean;\n }\n ).disable = false);\n } else {\n this.template.airplayButton &&\n ((\n this.template.airplayButton as HTMLElement & {\n disable?: boolean;\n }\n ).disable = true);\n }\n this.template.airplayButton?.addEventListener(\"click\", () => {\n (\n this.video as HTMLVideoElement & {\n webkitShowPlaybackTargetPicker?: () => void;\n }\n ).webkitShowPlaybackTargetPicker?.();\n });\n }.bind(this.player),\n );\n } else {\n if (this.player.template.airplayButton) {\n (this.player.template.airplayButton as HTMLElement).style.display =\n \"none\";\n }\n }\n }\n }\n\n initChromecast(): void {\n const script = document.createElement(\"script\");\n script.setAttribute(\"type\", \"text/javascript\");\n script.setAttribute(\n \"src\",\n \"https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1\",\n );\n document.body.appendChild(script);\n\n (\n window as Window & { __onGCastApiAvailable?: (v: boolean) => void }\n ).__onGCastApiAvailable = (isAvailable: boolean) => {\n if (isAvailable) {\n cast = (window as Window & { chrome?: { cast: typeof cast } }).chrome\n ?.cast;\n if (!cast) return;\n const sessionRequest = new cast.SessionRequest(\n cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID,\n );\n const apiConfig = new cast.ApiConfig(\n sessionRequest,\n () => {},\n (status: string) => {\n if (status === cast!.ReceiverAvailability.AVAILABLE) {\n this.player.events.trigger(\"chromecast_available\", status);\n }\n },\n );\n cast.initialize(apiConfig, () => {});\n }\n };\n }\n\n initChromecastButton(): void {\n if (this.player.options.chromecast) {\n if (runOnce) {\n runOnce = false;\n this.initChromecast();\n }\n\n const launchMedia = (media: string): boolean => {\n if (!cast) return false;\n const mediaInfo = new cast.media.MediaInfo(media);\n const request = new cast.media.LoadRequest(mediaInfo);\n if (!this.session) {\n window.open(media);\n return false;\n }\n (\n this.session as {\n loadMedia: (\n r: unknown,\n s: unknown,\n e: unknown,\n ) => { play: () => void };\n }\n )\n .loadMedia(\n request,\n onMediaDiscovered.bind(this, \"loadMedia\"),\n onMediaError,\n )\n .play();\n return true;\n };\n\n const onMediaDiscovered = (_how: string, media: unknown) => {\n this.currentMedia = media;\n };\n\n const onMediaError = (err: unknown) => {\n console.error(\"Error launching media\", err);\n };\n\n this.player.template.chromecastButton?.addEventListener(\"click\", () => {\n if (isCasting) {\n isCasting = false;\n (this.currentMedia as { stop: () => void })?.stop();\n (this.session as { stop: () => void })?.stop();\n this.initChromecast();\n } else {\n isCasting = true;\n cast?.requestSession(\n (s) => {\n this.session = s;\n launchMedia(this.player.options.video.url || \"\");\n },\n (err) => {\n if (err.code === \"cancel\") {\n this.session = undefined;\n } else {\n console.error(\"Error selecting cast device\", err);\n }\n },\n );\n }\n });\n }\n }\n\n initSubtitleButton(): void {\n this.player.events.on(\"subtitle_show\", () => {\n if (\n this.player.template.subtitleButton &&\n \"dataset\" in this.player.template.subtitleButton\n ) {\n (this.player.template.subtitleButton as HTMLElement).dataset.balloon =\n this.player.tran(\"hide-subs\");\n }\n if (this.player.template.subtitleButtonInner) {\n this.player.template.subtitleButtonInner.style.opacity = \"\";\n }\n this.player.user.set(\"subtitle\", 1);\n });\n\n this.player.events.on(\"subtitle_hide\", () => {\n if (\n this.player.template.subtitleButton &&\n \"dataset\" in this.player.template.subtitleButton\n ) {\n (this.player.template.subtitleButton as HTMLElement).dataset.balloon =\n this.player.tran(\"show-subs\");\n }\n if (this.player.template.subtitleButtonInner) {\n this.player.template.subtitleButtonInner.style.opacity = \"0.4\";\n }\n this.player.user.set(\"subtitle\", 0);\n });\n\n if (\n this.player.template.subtitleButton &&\n \"addEventListener\" in this.player.template.subtitleButton\n ) {\n (this.player.template.subtitleButton as HTMLElement).addEventListener(\n \"click\",\n () => {\n this.player.subtitle?.toggle();\n },\n );\n }\n }\n\n _showTitleBar(): void {\n const bar = this.player.template.titleBar;\n if (!bar) return;\n bar.style.opacity = \"1\";\n bar.style.visibility = \"visible\";\n bar.style.transform = \"translateY(0)\";\n bar.style.pointerEvents = \"auto\";\n }\n\n _hideTitleBar(): void {\n const bar = this.player.template.titleBar;\n if (!bar) return;\n bar.style.opacity = \"0\";\n bar.style.visibility = \"hidden\";\n bar.style.transform = \"translateY(-8px)\";\n bar.style.pointerEvents = \"none\";\n }\n\n setAutoHide(): void {\n this.show();\n clearTimeout(this.autoHideTimer);\n this.autoHideTimer = window.setTimeout(() => {\n if (\n this.player.video.played.length &&\n !this.player.paused &&\n !this.disableAutoHide\n ) {\n this.hide();\n }\n }, 1500);\n }\n\n show(): void {\n this.player.container.classList.remove(\"kplayer-hide-controller\");\n this._showTitleBar();\n }\n\n hide(): void {\n this.player.container.classList.add(\"kplayer-hide-controller\");\n this.player.setting.hide();\n this._hideTitleBar();\n }\n\n isShow(): boolean {\n return !this.player.container.classList.contains(\"kplayer-hide-controller\");\n }\n\n toggle(): void {\n if (this.isShow()) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n // mobile: давхар товшилтоор ±10 сек гүйлгэх (YouTube маягийн)\n private _setupMobileTapSeek(): void {\n const wrap = this.player.template.videoWrap;\n const DOUBLE_MS = 300;\n wrap.addEventListener(\"click\", (e: MouseEvent) => {\n const rect = wrap.getBoundingClientRect();\n const side: \"left\" | \"right\" =\n e.clientX - rect.left < rect.width / 2 ? \"left\" : \"right\";\n const now = Date.now();\n const isDouble = now - this._tapTime < DOUBLE_MS && this._tapSide === side;\n\n if (isDouble) {\n // 2 дахь товшилт → гүйлгэх (хүлээж байсан single-tap toggle-г цуцална)\n window.clearTimeout(this._tapTimer);\n const cur = this.player.video.currentTime;\n const dur = this.player.video.duration;\n this._seekAccum += 10;\n if (side === \"left\") {\n this.player.seek(Math.max(0, cur - 10));\n } else {\n this.player.seek(dur ? Math.min(dur, cur + 10) : cur + 10);\n }\n this._showSeekRipple(side, this._seekAccum);\n this._tapTime = now; // дараалсан товшилтыг үргэлжлүүлнэ\n } else {\n // эхний товшилт → 2 дахь товшилтыг хүлээнэ, эс бөгөөс toggle\n this._tapTime = now;\n this._tapSide = side;\n this._seekAccum = 0;\n window.clearTimeout(this._tapTimer);\n this._tapTimer = window.setTimeout(() => {\n this.toggle();\n this._tapSide = null;\n }, DOUBLE_MS);\n }\n });\n }\n\n private _showSeekRipple(side: \"left\" | \"right\", seconds: number): void {\n const wrap = this.player.template.videoWrap;\n let el = wrap.querySelector<HTMLElement>(`.kplayer-tap-seek-${side}`);\n if (!el) {\n el = document.createElement(\"div\");\n el.className = `kplayer-tap-seek kplayer-tap-seek-${side}`;\n el.innerHTML = `<div class=\"kplayer-tap-seek-inner\">\n <span class=\"kplayer-tap-seek-icon\">${side === \"left\" ? Icons.rewind : Icons.forward}</span>\n <span class=\"kplayer-tap-seek-text\"></span>\n </div>`;\n wrap.appendChild(el);\n }\n const text = el.querySelector(\".kplayer-tap-seek-text\");\n if (text) text.textContent = `${seconds}`;\n // animation-ийг дахин эхлүүлнэ\n el.classList.remove(\"kplayer-tap-seek-active\");\n void el.offsetWidth; // reflow\n el.classList.add(\"kplayer-tap-seek-active\");\n window.clearTimeout(this._rippleTimer);\n this._rippleTimer = window.setTimeout(() => {\n el?.classList.remove(\"kplayer-tap-seek-active\");\n this._seekAccum = 0;\n }, 600);\n }\n\n destroy(): void {\n window.clearTimeout(this._tapTimer);\n window.clearTimeout(this._rippleTimer);\n if (!utils.isMobile && this.setAutoHideHandler) {\n this.player.container.removeEventListener(\n \"mousemove\",\n this.setAutoHideHandler,\n );\n this.player.container.removeEventListener(\n \"click\",\n this.setAutoHideHandler,\n );\n }\n clearTimeout(this.autoHideTimer);\n }\n}\n\nexport default Controller;\n","import utils from \"./utils\";\nimport type KPlayer from \"./player\";\n\nclass Setting {\n player: KPlayer;\n loop: boolean;\n showAwaken: number;\n unlimitAwaken: number;\n airplayEntry: HTMLElement | null;\n chromecastEntry: HTMLElement | null;\n screenshotEntry: HTMLElement | null;\n\n constructor(player: KPlayer) {\n this.player = player;\n\n this.player.template.mask.addEventListener(\"click\", () => {\n this.hide();\n if (this.player.contextmenu.shown) {\n this.player.contextmenu.hide();\n }\n if (this.player.subtitles) {\n this.player.subtitles.hide();\n }\n });\n this.player.template.settingButton.addEventListener(\"click\", () => {\n this.show();\n });\n\n // loop\n this.loop = this.player.options.loop || false;\n this.player.template.loopToggle.checked = this.loop;\n this.player.template.loop.addEventListener(\"click\", () => {\n this.player.template.loopToggle.checked =\n !this.player.template.loopToggle.checked;\n this.loop = this.player.template.loopToggle.checked;\n });\n\n // show awaken\n this.showAwaken = this.player.user.get(\"awaken\");\n if (!this.showAwaken) {\n this.player.awaken &&\n (this.player.awaken as unknown as { hide: () => void }).hide();\n }\n this.player.template.showAwakenToggle.checked = !!this.showAwaken;\n this.player.template.showAwaken.addEventListener(\"click\", () => {\n this.player.template.showAwakenToggle.checked =\n !this.player.template.showAwakenToggle.checked;\n if (this.player.template.showAwakenToggle.checked) {\n this.showAwaken = 1;\n (this.player.awaken as unknown as { show: () => void })?.show();\n } else {\n this.showAwaken = 0;\n (this.player.awaken as unknown as { hide: () => void })?.hide();\n }\n this.player.user.set(\"awaken\", this.showAwaken ? 1 : 0);\n this.hide();\n });\n\n // unlimit awaken\n this.unlimitAwaken = this.player.user.get(\"unlimited\");\n this.player.template.unlimitAwakenToggle.checked = !!this.unlimitAwaken;\n this.player.template.unlimitAwaken.addEventListener(\"click\", () => {\n this.player.template.unlimitAwakenToggle.checked =\n !this.player.template.unlimitAwakenToggle.checked;\n if (this.player.template.unlimitAwakenToggle.checked) {\n this.unlimitAwaken = 1;\n (\n this.player.awaken as unknown as { unlimit: (v: boolean) => void }\n )?.unlimit(true);\n } else {\n this.unlimitAwaken = 0;\n (\n this.player.awaken as unknown as { unlimit: (v: boolean) => void }\n )?.unlimit(false);\n }\n this.player.user.set(\"unlimited\", this.unlimitAwaken ? 1 : 0);\n this.hide();\n });\n\n // speed\n this.player.template.speed.addEventListener(\"click\", () => {\n this.player.template.settingBox.classList.add(\n \"kplayer-setting-box-speed\",\n );\n });\n\n const speeds = this.player.options.playbackSpeed || [];\n const defaultSpeedIdx = speeds.indexOf(1);\n if (\n defaultSpeedIdx >= 0 &&\n this.player.template.speedItem[defaultSpeedIdx]\n ) {\n this.player.template.speedItem[defaultSpeedIdx].classList.add(\n \"kplayer-selected\",\n );\n }\n\n Array.from(this.player.template.speedItem).forEach((el, i) => {\n el.addEventListener(\"click\", () => {\n Array.from(this.player.template.speedItem).forEach((s) =>\n s.classList.remove(\"kplayer-selected\"),\n );\n el.classList.add(\"kplayer-selected\");\n this.player.speed(Number((el as HTMLElement).dataset.speed));\n\n const badge = this.player.container.querySelector(\n \"#kplayer-speed-current\",\n );\n if (badge) {\n const spd = (el as HTMLElement).dataset.speed;\n badge.textContent = spd === \"1\" ? \"1×\" : spd + \"×\";\n }\n });\n });\n\n // subtitle entry\n if (this.player.template.subtitleEntry) {\n this.player.template.subtitleEntry.addEventListener(\"click\", () => {\n this.player.template.settingBox.classList.add(\n \"kplayer-setting-box-subtitle\",\n );\n });\n }\n\n // quality entry\n if (this.player.template.qualityEntry) {\n this.player.template.qualityEntry.addEventListener(\"click\", () => {\n this.player.template.settingBox.classList.add(\n \"kplayer-setting-box-quality\",\n );\n });\n }\n\n // action entries\n this.airplayEntry = this.player.container.querySelector(\n \".kplayer-setting-airplay-entry\",\n );\n this.chromecastEntry = this.player.container.querySelector(\n \".kplayer-setting-chromecast-entry\",\n );\n this.screenshotEntry = this.player.container.querySelector(\n \".kplayer-setting-screenshot-entry\",\n );\n\n if (this.screenshotEntry && this.player.template.camareButton) {\n this.screenshotEntry.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.player.template.camareButton?.click();\n this.hide();\n });\n }\n\n if (this.airplayEntry && this.player.template.airplayButton) {\n this.airplayEntry.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.player.template.airplayButton?.click();\n this.hide();\n });\n }\n\n if (this.chromecastEntry && this.player.template.chromecastButton) {\n this.chromecastEntry.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.player.template.chromecastButton?.click();\n this.hide();\n });\n }\n\n // back buttons\n const backBtns = this.player.container.querySelectorAll(\n \".kplayer-setting-back-main\",\n );\n backBtns.forEach((btn) => {\n btn.addEventListener(\"click\", () => {\n this.player.template.settingBox.classList.remove(\n \"kplayer-setting-box-speed\",\n );\n this.player.template.settingBox.classList.remove(\n \"kplayer-setting-box-subtitle\",\n );\n this.player.template.settingBox.classList.remove(\n \"kplayer-setting-box-quality\",\n );\n this.player.template.settingBox.classList.remove(\n \"kplayer-setting-box-narrow\",\n );\n });\n });\n\n // awaken opacity\n if (this.player.awaken) {\n const dWidth = 130;\n this.player.on(\"awaken_opacity\", (percentage) => {\n this.player.bar.set(\"awaken\", percentage as number, \"width\");\n this.player.user.set(\"opacity\", percentage as number);\n });\n (\n this.player.awaken as unknown as { opacity: (v: number) => void }\n )?.opacity(this.player.user.get(\"opacity\"));\n\n const awakenMove = (event: Event) => {\n const e = event as MouseEvent | TouchEvent;\n let percentage =\n (((e as MouseEvent).clientX ||\n (e as TouchEvent).changedTouches?.[0]?.clientX ||\n 0) -\n utils.getBoundingClientRectViewLeft(\n this.player.template.awakenOpacityBarWrap!,\n )) /\n dWidth;\n percentage = Math.max(0, Math.min(1, percentage));\n (\n this.player.awaken as unknown as { opacity: (v: number) => void }\n )?.opacity(percentage);\n };\n\n const awakenUp = () => {\n document.removeEventListener(utils.nameMap.dragEnd, awakenUp);\n document.removeEventListener(utils.nameMap.dragMove, awakenMove);\n this.player.template.awakenOpacityBox?.classList.remove(\n \"kplayer-setting-awaken-active\",\n );\n };\n\n this.player.template.awakenOpacityBarWrapWrap?.addEventListener(\n \"click\",\n (event) => {\n let percentage =\n ((event.clientX || 0) -\n utils.getBoundingClientRectViewLeft(\n this.player.template.awakenOpacityBarWrap!,\n )) /\n dWidth;\n percentage = Math.max(0, Math.min(1, percentage));\n (\n this.player.awaken as unknown as { opacity: (v: number) => void }\n )?.opacity(percentage);\n },\n );\n\n this.player.template.awakenOpacityBarWrapWrap?.addEventListener(\n utils.nameMap.dragStart,\n () => {\n document.addEventListener(utils.nameMap.dragMove, awakenMove);\n document.addEventListener(utils.nameMap.dragEnd, awakenUp);\n this.player.template.awakenOpacityBox?.classList.add(\n \"kplayer-setting-awaken-active\",\n );\n },\n );\n }\n\n this._setupMenuA11y();\n }\n\n // a11y: setting menu-ийн мөрүүдийг keyboard-аар ажиллах боломжтой болгоно\n private _setupMenuA11y(): void {\n const box = this.player.template.settingBox;\n if (!box) return;\n const rowSelector =\n \".kplayer-setting-item, .kplayer-setting-action, .kplayer-setting-speed-item, .kplayer-subtitles-item, .kplayer-quality-item, .kplayer-setting-subtitle-toggle, .kplayer-setting-panel-back\";\n box.querySelectorAll<HTMLElement>(rowSelector).forEach((el) => {\n if (!el.hasAttribute(\"role\")) el.setAttribute(\"role\", \"menuitem\");\n if (!el.hasAttribute(\"tabindex\")) el.setAttribute(\"tabindex\", \"0\");\n });\n // Enter / Space → click (динамикаар нэмэгдсэн мөрийг ч closest-ээр хамаарна)\n box.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.key !== \"Enter\" && e.key !== \" \") return;\n const target = (e.target as HTMLElement)?.closest<HTMLElement>(\n rowSelector,\n );\n if (target && box.contains(target)) {\n e.preventDefault();\n target.click();\n }\n });\n }\n\n hide(): void {\n this.player.template.settingBox.classList.remove(\n \"kplayer-setting-box-open\",\n );\n this.player.template.mask.classList.remove(\"kplayer-mask-show\");\n setTimeout(() => {\n this.player.template.settingBox.classList.remove(\n \"kplayer-setting-box-narrow\",\n );\n this.player.template.settingBox.classList.remove(\n \"kplayer-setting-box-speed\",\n );\n this.player.template.settingBox.classList.remove(\n \"kplayer-setting-box-subtitle\",\n );\n this.player.template.settingBox.classList.remove(\n \"kplayer-setting-box-quality\",\n );\n }, 300);\n\n this.player.controller.disableAutoHide = false;\n }\n\n show(): void {\n if (\n this.player.template.settingBox.classList.contains(\n \"kplayer-setting-box-open\",\n )\n ) {\n this.hide();\n return;\n }\n this.player.template.settingBox.classList.add(\"kplayer-setting-box-open\");\n this.player.template.mask.classList.add(\"kplayer-mask-show\");\n this.player.controller.disableAutoHide = true;\n }\n}\n\nexport default Setting;\n","import type KPlayer from \"./player\";\n\nclass HotKey {\n player: KPlayer;\n doHotKeyHandler: (e: KeyboardEvent) => void;\n cancelFullScreenHandler: (e: KeyboardEvent) => void;\n\n constructor(player: KPlayer) {\n this.player = player;\n this.doHotKeyHandler = this.doHotKey.bind(this);\n this.cancelFullScreenHandler = this.cancelFullScreen.bind(this);\n\n if (this.player.options.hotkey) {\n document.addEventListener(\"keydown\", this.doHotKeyHandler);\n }\n document.addEventListener(\"keydown\", this.cancelFullScreenHandler);\n }\n\n doHotKey(e: KeyboardEvent): void {\n if (this.player.focus) {\n const tag = (document.activeElement as HTMLElement).tagName.toUpperCase();\n const editable = document.activeElement?.getAttribute(\"contenteditable\");\n if (\n tag !== \"INPUT\" &&\n tag !== \"TEXTAREA\" &&\n editable !== \"\" &&\n editable !== \"true\"\n ) {\n let percentage: number;\n switch (e.keyCode) {\n case 32:\n e.preventDefault();\n this.player.toggle();\n break;\n case 37:\n e.preventDefault();\n if (this.player.options.live) break;\n this.player.seek(this.player.video.currentTime - 10);\n this.player.controller.setAutoHide();\n break;\n case 39:\n e.preventDefault();\n if (this.player.options.live) break;\n this.player.seek(this.player.video.currentTime + 10);\n this.player.controller.setAutoHide();\n break;\n case 38:\n e.preventDefault();\n percentage = this.player.volume() + 0.1;\n this.player.volume(percentage);\n break;\n case 40:\n e.preventDefault();\n percentage = this.player.volume() - 0.1;\n this.player.volume(percentage);\n break;\n }\n }\n }\n }\n\n cancelFullScreen(e: KeyboardEvent): void {\n switch (e.keyCode) {\n case 27:\n if (this.player.fullScreen.isFullScreen(\"web\")) {\n this.player.fullScreen.cancel(\"web\");\n }\n break;\n }\n }\n\n destroy(): void {\n if (this.player.options.hotkey) {\n document.removeEventListener(\"keydown\", this.doHotKeyHandler);\n }\n document.removeEventListener(\"keydown\", this.cancelFullScreenHandler);\n }\n}\n\nexport default HotKey;\n","import type KPlayer from \"./player\";\n\nclass ContextMenu {\n player: KPlayer;\n shown = false;\n contextmenuHandler: (e: MouseEvent) => void;\n videoContextHandler: (e: MouseEvent) => void;\n\n constructor(player: KPlayer) {\n this.player = player;\n\n Array.prototype.slice\n .call(this.player.template.menuItem)\n .forEach((item: HTMLElement, index: number) => {\n const menuItem = this.player.options.contextmenu?.[index];\n if (menuItem?.click) {\n item.addEventListener(\"click\", (e) => {\n e.preventDefault();\n menuItem.click!(this.player);\n this.hide();\n });\n }\n });\n\n this.contextmenuHandler = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const clientRect = this.player.container.getBoundingClientRect();\n const x = e.clientX - clientRect.left;\n const y = e.clientY - clientRect.top;\n\n if (this.shown) {\n this.hide();\n return;\n }\n this.show(x, y);\n };\n\n this.player.container.addEventListener(\n \"contextmenu\",\n this.contextmenuHandler,\n );\n\n this.videoContextHandler = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const clientRect = this.player.container.getBoundingClientRect();\n const x = e.clientX - clientRect.left;\n const y = e.clientY - clientRect.top;\n\n if (this.shown) {\n this.hide();\n return;\n }\n this.show(x, y);\n };\n\n this.player.video.addEventListener(\"contextmenu\", this.videoContextHandler);\n }\n\n show(x: number, y: number): void {\n this.player.template.menu.classList.add(\"kplayer-menu-show\");\n\n const clientRect = this.player.container.getBoundingClientRect();\n if (x + this.player.template.menu.offsetWidth >= clientRect.width) {\n this.player.template.menu.style.right = clientRect.width - x + \"px\";\n this.player.template.menu.style.left = \"initial\";\n } else {\n this.player.template.menu.style.left = x + \"px\";\n this.player.template.menu.style.right = \"initial\";\n }\n if (y + this.player.template.menu.offsetHeight >= clientRect.height) {\n this.player.template.menu.style.bottom = clientRect.height - y + \"px\";\n this.player.template.menu.style.top = \"initial\";\n } else {\n this.player.template.menu.style.top = y + \"px\";\n this.player.template.menu.style.bottom = \"initial\";\n }\n\n this.player.template.mask.classList.add(\"kplayer-mask-show\");\n this.shown = true;\n this.player.events.trigger(\"contextmenu_show\");\n }\n\n hide(): void {\n this.player.template.mask.classList.remove(\"kplayer-mask-show\");\n this.player.template.menu.classList.remove(\"kplayer-menu-show\");\n this.shown = false;\n this.player.events.trigger(\"contextmenu_hide\");\n }\n\n destroy(): void {\n this.player.container.removeEventListener(\n \"contextmenu\",\n this.contextmenuHandler,\n );\n if (this.videoContextHandler) {\n this.player.video.removeEventListener(\n \"contextmenu\",\n this.videoContextHandler,\n );\n }\n }\n}\n\nexport default ContextMenu;\n","import type KPlayer from \"./player\";\nimport type Template from \"./template\";\n\ndeclare const KPLAYER_VERSION: string;\ndeclare const GIT_HASH: string;\n\nclass InfoPanel {\n container: HTMLElement;\n template: Template;\n video: HTMLVideoElement;\n player: KPlayer;\n beginTime = 0;\n\n constructor(player: KPlayer) {\n this.container = player.template.infoPanel!;\n this.template = player.template;\n this.video = player.video;\n this.player = player;\n\n this.template.infoPanelClose?.addEventListener(\"click\", () => {\n this.hide();\n });\n }\n\n show(): void {\n this.beginTime = Date.now();\n this.update();\n this.player.timer.enable(\"info\");\n this.player.timer.enable(\"fps\");\n this.container.classList.remove(\"kplayer-info-panel-hide\");\n }\n\n hide(): void {\n this.player.timer.disable(\"info\");\n this.player.timer.disable(\"fps\");\n this.container.classList.add(\"kplayer-info-panel-hide\");\n }\n\n triggle(): void {\n if (this.container.classList.contains(\"kplayer-info-panel-hide\")) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n update(): void {\n if (this.template.infoVersion) {\n this.template.infoVersion.innerHTML = `v${KPLAYER_VERSION} ${GIT_HASH}`;\n }\n if (this.template.infoType) {\n this.template.infoType.innerHTML = this.player.type || \"\";\n }\n if (this.template.infoUrl) {\n this.template.infoUrl.innerHTML = this.player.options.video?.url || \"\";\n }\n if (this.template.infoResolution) {\n this.template.infoResolution.innerHTML = `${this.video.videoWidth} x ${this.video.videoHeight}`;\n }\n if (this.template.infoDuration) {\n this.template.infoDuration.innerHTML = String(this.video.duration);\n }\n if (\n this.player.options.awaken &&\n typeof this.player.options.awaken === \"object\"\n ) {\n if (this.template.infoAwakenId) {\n this.template.infoAwakenId.innerHTML =\n this.player.options.awaken.id || \"\";\n }\n if (this.template.infoAwakenApi) {\n this.template.infoAwakenApi.innerHTML =\n this.player.options.awaken.api || \"\";\n }\n }\n }\n\n fps(value: number): void {\n if (this.template.infoFPS) {\n this.template.infoFPS.innerHTML = `${value.toFixed(1)}`;\n }\n }\n}\n\nexport default InfoPanel;\n","import utils from \"./utils\";\nimport handleOption from \"./options\";\nimport { i18n } from \"./i18n\";\nimport Template from \"./template\";\nimport Icons from \"./icons\";\nimport Ad from \"./ad\";\nimport Events from \"./events\";\nimport FullScreen from \"./fullscreen\";\nimport User from \"./user\";\nimport Subtitle from \"./subtitle\";\nimport Subtitles from \"./subtitles\";\nimport Bar from \"./bar\";\nimport Timer from \"./timer\";\nimport Bezel from \"./bezel\";\nimport Controller from \"./controller\";\nimport Setting from \"./setting\";\nimport HotKey from \"./hotkey\";\nimport ContextMenu from \"./contextmenu\";\nimport InfoPanel from \"./info-panel\";\nimport renderVideo from \"../template/video\";\nimport type { KPlayerOptions, SubtitleItem } from \"./types\";\n\ndeclare const KPLAYER_VERSION: string;\n\ninterface HlsLevel {\n height?: number;\n bitrate?: number;\n}\n\ninterface HlsInstance {\n levels: HlsLevel[];\n currentLevel: number;\n nextLevel: number;\n loadLevel: number;\n autoLevelEnabled: boolean;\n loadSource(src: string): void;\n attachMedia(video: HTMLVideoElement): void;\n destroy(): void;\n on(event: string, cb: (...args: unknown[]) => void): void;\n off(event: string, cb: (...args: unknown[]) => void): void;\n DefaultConfig?: { loader: unknown };\n}\n\nlet index = 0;\nconst instances: KPlayer[] = [];\n\nfunction createBlobHLSLoader(Hls: {\n DefaultConfig: { loader: new (config: unknown) => unknown };\n}) {\n const DefaultLoader = Hls.DefaultConfig.loader;\n\n return class BlobHLSLoader extends (DefaultLoader as new (\n config: unknown,\n ) => {\n load: (\n context: unknown,\n config: unknown,\n callbacks: Record<string, unknown>,\n ) => void;\n }) {\n constructor(config: unknown) {\n super(config);\n const superLoad = this.load.bind(this);\n\n this.load = function (\n context: unknown,\n cfg: unknown,\n callbacks: Record<string, unknown>,\n ) {\n const ctx = context as { type?: string };\n const cbs = callbacks as {\n onSuccess: (\n response: { data?: unknown; url: string },\n stats: unknown,\n c: unknown,\n nd: unknown,\n ) => void;\n };\n const originalOnSuccess = cbs.onSuccess;\n\n cbs.onSuccess = function (response, stats, c, networkDetails) {\n try {\n if (ctx.type === \"fragment\") {\n const data = response.data;\n let blobData: ArrayBuffer | undefined;\n if (data instanceof ArrayBuffer) {\n blobData = data;\n } else if (typeof data === \"string\") {\n blobData = new TextEncoder().encode(data).buffer;\n }\n if (blobData) {\n const blob = new Blob([blobData], { type: \"video/mp2t\" });\n const blobUrl = URL.createObjectURL(blob);\n response.url = blobUrl;\n setTimeout(() => URL.revokeObjectURL(blobUrl), 10000);\n }\n }\n } catch (e) {\n console.warn(\"[KPlayer] BlobHLSLoader error:\", e);\n }\n originalOnSuccess(response, stats, c, networkDetails);\n };\n\n superLoad(context, cfg, callbacks);\n };\n }\n };\n}\n\nasync function fetchAndDecryptVtt(\n url: string,\n encrypt?: boolean,\n keyHex?: string,\n ivHex?: string,\n): Promise<string> {\n const res = await fetch(url, { mode: \"cors\" });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n let text = await res.text();\n\n if (encrypt && keyHex && ivHex) {\n const TIMESTAMP_REGEX =\n /^\\d{2}:\\d{2}:\\d{2}[.,]\\d{3}\\s*-->\\s*\\d{2}:\\d{2}:\\d{2}[.,]\\d{3}$/;\n\n const decryptLine = async (\n hex: string,\n key: CryptoKey,\n iv: Uint8Array,\n ): Promise<string> => {\n const encrypted = new Uint8Array(\n hex.match(/.{2}/g)!.map((b) => parseInt(b, 16)),\n );\n const decrypted = await crypto.subtle.decrypt(\n { name: \"AES-CBC\", iv: iv.buffer as ArrayBuffer },\n key,\n encrypted.buffer as ArrayBuffer,\n );\n return new TextDecoder().decode(decrypted);\n };\n\n const keyBuf = new Uint8Array(\n keyHex.match(/.{2}/g)!.map((b) => parseInt(b, 16)),\n );\n const ivBuf = new Uint8Array(\n ivHex.match(/.{2}/g)!.map((b) => parseInt(b, 16)),\n );\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n keyBuf.buffer as ArrayBuffer,\n { name: \"AES-CBC\" },\n false,\n [\"decrypt\"],\n );\n\n // base64 decode → hex encoded vtt string авна\n let hexVtt: string;\n try {\n hexVtt = atob(text.trim()); // base64 → hex string\n } catch {\n hexVtt = text; // base64 биш бол шууд hex гэж үзнэ\n }\n\n const lines = hexVtt.split(\"\\n\");\n const out: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) {\n out.push(line);\n continue;\n }\n if (TIMESTAMP_REGEX.test(trimmed)) {\n out.push(line);\n continue;\n }\n // hex string эсэхийг шалгах\n if (/^[0-9a-fA-F]+$/.test(trimmed) && trimmed.length % 2 === 0) {\n try {\n const decrypted = await decryptLine(trimmed, cryptoKey, ivBuf);\n out.push(decrypted);\n } catch {\n out.push(line);\n }\n } else {\n // hex биш мөр (WEBVTT, NOTE гэх мэт) — шууд дамжуулна\n out.push(line);\n }\n }\n text = out.join(\"\\n\");\n }\n\n return text;\n}\n\nclass KPlayer {\n options: KPlayerOptions;\n tran: (key: string) => string;\n events: Events;\n user: User;\n container: HTMLElement;\n noticeList: Record<string, ReturnType<typeof setTimeout> | null>;\n hlsQualityList: unknown[];\n hlsCurrentLevel: number;\n hlsAutoEnabled: boolean;\n template: Template;\n video: HTMLVideoElement;\n bar: Bar;\n bezel: Bezel;\n fullScreen: FullScreen;\n controller: Controller;\n setting: Setting;\n plugins: Record<string, unknown>;\n docClickFun: () => void;\n containerClickFun: () => void;\n focus = false;\n paused = true;\n timer: Timer;\n hotkey: HotKey;\n contextmenu: ContextMenu;\n infoPanel: InfoPanel;\n ad?: Ad;\n subtitle?: Subtitle;\n subtitles?: Subtitles;\n awaken?: unknown;\n moveBar = false;\n type?: string;\n qualityIndex?: number;\n quality?: { name: string; url: string; type?: string };\n switchingQuality = false;\n prevIndex?: number;\n prevVideo?: HTMLVideoElement;\n resizeObserver?: ResizeObserver;\n\n constructor(\n options: Partial<KPlayerOptions> & { video: KPlayerOptions[\"video\"] },\n ) {\n this.options = handleOption({\n preload: options.video?.type === \"webtorrent\" ? \"none\" : \"metadata\",\n ...options,\n });\n\n if (this.options.video.quality) {\n this.qualityIndex = this.options.video.defaultQuality ?? 0;\n this.quality = this.options.video.quality[this.qualityIndex];\n }\n\n this.tran = new (i18n as unknown as new (lang: string) => {\n tran: (k: string) => string;\n })(this.options.lang || \"en\").tran;\n this.events = new Events();\n this.user = new User(this);\n this.container = this.options.container;\n this.noticeList = {};\n this.hlsQualityList = [];\n this.hlsCurrentLevel = -1;\n this.hlsAutoEnabled = true;\n\n this.container.classList.add(\"kplayer\");\n // a11y: player-ийг нэрлэгдсэн бүс (landmark) болгоно\n if (!this.container.hasAttribute(\"role\")) {\n this.container.setAttribute(\"role\", \"region\");\n }\n if (!this.container.hasAttribute(\"aria-label\")) {\n this.container.setAttribute(\n \"aria-label\",\n this.options.title?.title || this.tran(\"video-player\"),\n );\n }\n if (!this.options.awaken) {\n this.container.classList.add(\"kplayer-no-awaken\");\n }\n if (this.options.live) {\n this.container.classList.add(\"kplayer-live\");\n } else {\n this.container.classList.remove(\"kplayer-live\");\n }\n if (utils.isMobile) {\n this.container.classList.add(\"kplayer-mobile\");\n }\n if (this.container.offsetWidth <= 500) {\n this.container.classList.add(\"kplayer-arrow\");\n }\n\n // multi subtitles setup\n if (this.options.subtitle && Array.isArray(this.options.subtitle.url)) {\n const offSubtitle: SubtitleItem = { subtitle: \"\", lang: \"off\", url: \"\" };\n (this.options.subtitle.url as SubtitleItem[]).push(offSubtitle);\n\n if (this.options.subtitle.defaultSubtitle !== undefined) {\n const ds = this.options.subtitle.defaultSubtitle;\n if (typeof ds === \"string\") {\n this.options.subtitle.index = (\n this.options.subtitle.url as SubtitleItem[]\n ).findIndex((sub) => sub.lang === ds || sub.name === ds);\n } else if (typeof ds === \"number\") {\n this.options.subtitle.index = ds;\n }\n }\n\n const urlArr = this.options.subtitle.url as SubtitleItem[];\n if (\n this.options.subtitle.index === -1 ||\n this.options.subtitle.index == null ||\n this.options.subtitle.index > urlArr.length - 1\n ) {\n this.options.subtitle.index = urlArr.findIndex(\n (sub) => sub.lang === this.options.lang,\n );\n }\n if (this.options.subtitle.index === -1) {\n this.options.subtitle.index = urlArr.length - 1;\n }\n }\n\n this.template = new Template({\n container: this.container,\n options: this.options,\n index,\n tran: this.tran,\n });\n\n this.video = this.template.video;\n this.bar = new Bar(this.template);\n this.bezel = new Bezel(this.template.bezel);\n this.fullScreen = new FullScreen(this);\n this.controller = new Controller(this);\n this.setting = new Setting(this);\n this.plugins = {};\n\n this.docClickFun = () => {\n this.focus = false;\n };\n this.containerClickFun = () => {\n this.focus = true;\n };\n document.addEventListener(\"click\", this.docClickFun, true);\n this.container.addEventListener(\"click\", this.containerClickFun, true);\n\n this.paused = true;\n this.timer = new Timer(this);\n this.hotkey = new HotKey(this);\n this.contextmenu = new ContextMenu(this);\n this.initVideo(\n this.video,\n (this.quality && this.quality.type) || this.options.video.type || \"auto\",\n );\n this.infoPanel = new InfoPanel(this);\n\n if (this.options.ad || this.options.vastAD) {\n this.ad = new Ad(this);\n }\n if (this.options.vastAD && this.options.vastADURL) {\n this.ad?._loadVAST(this.options.vastADURL);\n }\n\n // Title back button\n if (this.template.titleBack) {\n this.template.titleBack.addEventListener(\"click\", () => {\n if (typeof this.options.title?.onBack === \"function\") {\n this.options.title.onBack(this);\n } else {\n window.history.back();\n }\n this.events.trigger(\"title_back\");\n });\n }\n\n if (!this.awaken && this.options.autoplay) {\n this.play();\n }\n\n // Контейнерийн хэмжээ өөрчлөгдөх бүрт responsive layout-г шинэчилнэ\n // (зөвхөн UA эсвэл анхны өргөнд биш — аливаа embed/resize-д тохирно).\n if (typeof ResizeObserver !== \"undefined\") {\n this.resizeObserver = new ResizeObserver(() => this.resize());\n this.resizeObserver.observe(this.container);\n }\n\n this.moveBar = false;\n index++;\n instances.push(this);\n }\n\n seek(time: number): void {\n time = Math.max(time, 0);\n if (this.video.duration) {\n time = Math.min(time, this.video.duration);\n }\n if (this.video.currentTime < time) {\n this.notice(\n `${this.tran(\"ff\").replace(\"%s\", (time - this.video.currentTime).toFixed(0))}`,\n );\n } else if (this.video.currentTime > time) {\n this.notice(\n `${this.tran(\"rew\").replace(\"%s\", (this.video.currentTime - time).toFixed(0))}`,\n );\n }\n\n this.video.currentTime = time;\n\n if (this.awaken) {\n (this.awaken as { seek: () => void }).seek();\n }\n\n this.bar.set(\"played\", time / this.video.duration, \"width\");\n this.template.ptime.innerHTML = utils.secondToTime(time);\n }\n\n play(fromNative?: boolean): void {\n this.paused = false;\n if (this.video.paused && !utils.isMobile) {\n this.bezel.switch(Icons.play);\n }\n\n this.template.playButton.innerHTML = Icons.pause;\n this.template.mobilePlayButton.innerHTML = Icons.pause;\n this._setPlayLabel(this.tran(\"pause\"));\n\n if (!fromNative) {\n Promise.resolve(this.video.play()).catch(() => {\n this.pause();\n });\n }\n\n this.timer.enable(\"loading\");\n this.container.classList.remove(\"kplayer-paused\");\n this.container.classList.add(\"kplayer-playing\");\n\n if (this.awaken) {\n (this.awaken as { play: () => void }).play();\n }\n\n if (this.options.mutex) {\n for (const inst of instances) {\n if (this !== inst) inst.pause();\n }\n }\n\n const mobilePlayBtn = this.container.querySelector<HTMLElement>(\n \".kplayer-mobile-play-btn .kplayer-icon-content\",\n );\n if (mobilePlayBtn) mobilePlayBtn.innerHTML = Icons.pause;\n }\n\n pause(fromNative?: boolean): void {\n this.paused = true;\n this.container.classList.remove(\"kplayer-loading\");\n\n if (!this.video.paused && !utils.isMobile) {\n this.bezel.switch(Icons.pause);\n }\n\n this.template.playButton.innerHTML = Icons.play;\n this.template.mobilePlayButton.innerHTML = Icons.play;\n this._setPlayLabel(this.tran(\"play\"));\n\n if (!fromNative) {\n this.video.pause();\n }\n\n this.timer.disable(\"loading\");\n this.container.classList.remove(\"kplayer-playing\");\n this.container.classList.add(\"kplayer-paused\");\n\n if (this.awaken) {\n (this.awaken as { pause: () => void }).pause();\n }\n\n const mobilePlayBtn = this.container.querySelector<HTMLElement>(\n \".kplayer-mobile-play-btn .kplayer-icon-content\",\n );\n if (mobilePlayBtn) mobilePlayBtn.innerHTML = Icons.play;\n }\n\n // a11y: play/pause товчнуудын aria-label-г нэг дор шинэчилнэ\n private _setPlayLabel(label: string): void {\n this.template.playButton.setAttribute(\"aria-label\", label);\n this.container\n .querySelector<HTMLElement>(\".kplayer-mobile-play-btn\")\n ?.setAttribute(\"aria-label\", label);\n }\n\n switchVolumeIcon(): void {\n if (this.volume() >= 0.95) {\n this.template.volumeIcon.innerHTML = Icons.volumeUp;\n } else if (this.volume() > 0) {\n this.template.volumeIcon.innerHTML = Icons.volumeDown;\n } else {\n this.template.volumeIcon.innerHTML = Icons.volumeOff;\n }\n }\n\n volume(percentage?: number, nostorage?: boolean, nonotice?: boolean): number {\n const pct = parseFloat(String(percentage));\n if (!isNaN(pct)) {\n const clamped = Math.max(0, Math.min(1, pct));\n this.bar.set(\"volume\", clamped, \"width\");\n const formatPercentage = `${(clamped * 100).toFixed(0)}%`;\n (\n this.template.volumeBarWrapWrap as HTMLElement & {\n dataset: DOMStringMap;\n }\n ).dataset.balloon = formatPercentage;\n if (!nostorage) this.user.set(\"volume\", clamped);\n if (!nonotice) {\n this.notice(\n `${this.tran(\"volume\")} ${(clamped * 100).toFixed(0)}%`,\n undefined,\n undefined,\n \"volume\",\n );\n }\n this.video.volume = clamped;\n if (this.video.muted) this.video.muted = false;\n this.switchVolumeIcon();\n\n // a11y: volume slider + mute/unmute товчны утгыг шинэчилнэ\n const vPct = Math.round(clamped * 100);\n this.template.volumeBarWrapWrap.setAttribute(\n \"aria-valuenow\",\n String(vPct),\n );\n this.template.volumeBarWrapWrap.setAttribute(\n \"aria-valuetext\",\n formatPercentage,\n );\n this.template.volumeButtonIcon?.setAttribute(\n \"aria-label\",\n this.tran(clamped === 0 ? \"unmute\" : \"mute\"),\n );\n }\n return this.video.volume;\n }\n\n toggle(): void {\n if (this.video.paused) {\n this.play();\n } else {\n this.pause();\n }\n }\n\n on(name: string, callback: (info?: unknown) => void): void {\n this.events.on(name, callback);\n }\n\n initMSE(video: HTMLVideoElement, type: string): void {\n this.type = type;\n\n if (this.options.video.customType?.[type]) {\n const customFn = this.options.video.customType[type];\n if (typeof customFn === \"function\") {\n customFn(this.video, this);\n } else {\n console.error(`Illegal customType: ${type}`);\n }\n return;\n }\n\n let resolvedType = type;\n if (resolvedType === \"auto\") {\n if (/m3u8(#|\\?|$)/i.exec(video.src)) {\n resolvedType = \"hls\";\n } else if (/.flv(#|\\?|$)/i.exec(video.src)) {\n resolvedType = \"flv\";\n } else if (/.mpd(#|\\?|$)/i.exec(video.src)) {\n resolvedType = \"dash\";\n } else {\n resolvedType = \"normal\";\n }\n }\n\n // Safari/iOS нь HLS-г native дэмждэг (iOS дээр MSE байхгүй тул hls.js\n // ажиллахгүй) — энэ тохиолдолд hls.js-ийн оронд native тоглуулна.\n if (\n resolvedType === \"hls\" &&\n (video.canPlayType(\"application/x-mpegURL\") ||\n video.canPlayType(\"application/vnd.apple.mpegURL\"))\n ) {\n resolvedType = \"normal\";\n }\n\n this.type = resolvedType;\n const src = this.quality ? this.quality.url : video.src;\n\n switch (resolvedType) {\n case \"hls\": {\n const HlsLib = (\n window as Window & {\n Hls?: {\n isSupported: () => boolean;\n DefaultConfig: { loader: unknown };\n Events: Record<string, string>;\n } & (new (opts: unknown) => HlsInstance);\n }\n ).Hls;\n if (!HlsLib) {\n this.notice(\"Error: Can't find Hls.\");\n return;\n }\n if (!HlsLib.isSupported()) {\n this.notice(\"Error: Hls is not supported.\");\n return;\n }\n\n const userOptions = this.options.pluginOptions?.hls || {};\n const BlobLoader = createBlobHLSLoader(\n HlsLib as unknown as {\n DefaultConfig: { loader: new (c: unknown) => unknown };\n },\n );\n const hls = new HlsLib({\n ...userOptions,\n loader: BlobLoader,\n }) as HlsInstance;\n\n this.plugins.hls = hls;\n hls.loadSource(video.src);\n hls.attachMedia(video);\n\n hls.on(HlsLib.Events.MANIFEST_PARSED, () => {\n this.buildHlsQualityMenu(hls, HlsLib); // ← HlsLib дамжуулах\n this.updateHlsQualityCurrentLabel();\n });\n hls.on(HlsLib.Events.LEVEL_SWITCHED, (...args: unknown[]) => {\n const data = args[1] as { level: number };\n this.hlsCurrentLevel = data.level;\n this.updateHlsQualityCurrentLabel();\n });\n this.events.on(\"destroy\", () => {\n hls.destroy();\n delete this.plugins.hls;\n });\n break;\n }\n case \"flv\": {\n const flvjs = (\n window as Window & {\n flvjs?: {\n isSupported: () => boolean;\n createPlayer: (\n src: unknown,\n cfg?: unknown,\n ) => {\n attachMediaElement: (v: HTMLVideoElement) => void;\n load: () => void;\n unload: () => void;\n detachMediaElement: () => void;\n destroy: () => void;\n };\n };\n }\n ).flvjs;\n if (flvjs) {\n if (flvjs.isSupported()) {\n const flvPlayer = flvjs.createPlayer(\n Object.assign(\n this.options.pluginOptions?.flv?.mediaDataSource || {},\n {\n type: \"flv\",\n url: video.src,\n },\n ),\n this.options.pluginOptions?.flv?.config,\n );\n this.plugins.flvjs = flvPlayer;\n flvPlayer.attachMediaElement(video);\n flvPlayer.load();\n this.events.on(\"destroy\", () => {\n flvPlayer.unload();\n flvPlayer.detachMediaElement();\n flvPlayer.destroy();\n delete this.plugins.flvjs;\n });\n this.events.on(\"quality_end\", () => {\n if (src !== this.quality?.url) {\n flvPlayer.unload();\n flvPlayer.detachMediaElement();\n flvPlayer.destroy();\n }\n });\n } else {\n this.notice(\"Error: flvjs is not supported.\");\n }\n } else {\n this.notice(\"Error: Can't find flvjs.\");\n }\n break;\n }\n case \"dash\": {\n const dashjs = (\n window as Window & {\n dashjs?: {\n MediaPlayer: () => {\n create: () => {\n initialize: (\n v: HTMLVideoElement,\n src: string,\n autoplay: boolean,\n startTime: number,\n ) => void;\n updateSettings: (opts: unknown) => void;\n reset: () => void;\n };\n reset: () => void; // ← энд нэмнэ\n };\n };\n }\n ).dashjs;\n if (dashjs) {\n const dashjsPlayer = dashjs.MediaPlayer().create();\n dashjsPlayer.initialize(video, video.src, false, 0);\n dashjsPlayer.updateSettings(this.options.pluginOptions?.dash || {});\n this.plugins.dash = dashjsPlayer;\n this.events.on(\"destroy\", () => {\n dashjs.MediaPlayer().reset();\n delete this.plugins.dash;\n });\n this.events.on(\"quality_end\", () => {\n if (src !== this.quality?.url) dashjs.MediaPlayer().reset();\n });\n } else {\n this.notice(\"Error: Can't find dashjs.\");\n }\n break;\n }\n case \"webtorrent\": {\n const WebTorrent = (\n window as Window & {\n WebTorrent?: {\n WEBRTC_SUPPORT: boolean;\n new (opts?: unknown): {\n add: (\n id: string,\n cb: (torrent: {\n files: Array<{\n name: string;\n renderTo: (v: HTMLVideoElement, opts: unknown) => void;\n }>;\n }) => void,\n ) => void;\n remove: (id: string) => void;\n destroy: () => void;\n };\n };\n }\n ).WebTorrent;\n if (WebTorrent) {\n if (WebTorrent.WEBRTC_SUPPORT) {\n this.container.classList.add(\"kplayer-loading\");\n const client = new WebTorrent(\n this.options.pluginOptions?.webtorrent || {},\n );\n this.plugins.webtorrent = client;\n const torrentId = video.src;\n video.src = \"\";\n video.preload = \"metadata\";\n video.addEventListener(\n \"durationchange\",\n () => this.container.classList.remove(\"kplayer-loading\"),\n { once: true },\n );\n client.add(torrentId, (torrent) => {\n const file = torrent.files.find((f) => f.name.endsWith(\".mp4\"));\n file?.renderTo(this.video, {\n autoplay: this.options.autoplay,\n controls: false,\n });\n });\n this.events.on(\"destroy\", () => {\n client.remove(torrentId);\n client.destroy();\n delete this.plugins.webtorrent;\n });\n this.events.on(\"quality_end\", () => {\n if (src !== this.quality?.url) {\n client.remove(torrentId);\n client.destroy();\n }\n });\n } else {\n this.notice(\"Error: Webtorrent is not supported.\");\n }\n } else {\n this.notice(\"Error: Can't find Webtorrent.\");\n }\n break;\n }\n }\n }\n\n initVideo(video: HTMLVideoElement, type: string): void {\n this.initMSE(video, type);\n\n this.on(\"durationchange\", () => {\n if (video.duration !== 1 && video.duration !== Infinity) {\n this.template.dtime.innerHTML = utils.secondToTime(video.duration);\n }\n });\n\n this.on(\"progress\", () => {\n const percentage = video.buffered.length\n ? video.buffered.end(video.buffered.length - 1) / video.duration\n : 0;\n this.bar.set(\"loaded\", percentage, \"width\");\n });\n\n this.on(\"error\", () => {\n if (!this.video.error) return;\n if (this.tran && this.notice && this.type !== \"webtorrent\") {\n this.notice(this.tran(\"video-failed\"));\n }\n });\n\n this.on(\"ended\", () => {\n this.bar.set(\"played\", 1, \"width\");\n if (!this.setting.loop) {\n this.pause();\n } else {\n this.seek(0);\n this.play();\n }\n if (this.awaken) {\n (this.awaken as { danIndex: number }).danIndex = 0;\n }\n });\n\n this.on(\"play\", () => {\n if (this.paused) this.play(true);\n });\n\n this.on(\"pause\", () => {\n if (!this.paused) this.pause(true);\n });\n\n this.on(\"timeupdate\", () => {\n if (!this.moveBar) {\n this.bar.set(\n \"played\",\n this.video.currentTime / this.video.duration,\n \"width\",\n );\n }\n const currentTime = utils.secondToTime(this.video.currentTime);\n if (this.template.ptime.innerHTML !== currentTime) {\n this.template.ptime.innerHTML = currentTime;\n }\n\n // a11y: seek slider-ийн утгыг шинэчилнэ\n const dur = this.video.duration;\n if (dur && isFinite(dur)) {\n const pct = Math.round((this.video.currentTime / dur) * 100);\n this.template.barWrap.setAttribute(\"aria-valuenow\", String(pct));\n this.template.barWrap.setAttribute(\n \"aria-valuetext\",\n `${currentTime} / ${utils.secondToTime(dur)}`,\n );\n }\n });\n\n for (const eventName of this.events.videoEvents) {\n video.addEventListener(eventName, (e) => {\n this.events.trigger(eventName, e);\n });\n }\n\n this.volume(this.user.get(\"volume\"), true, true);\n\n if (this.options.subtitle) {\n this.subtitle = new Subtitle(\n this.template.subtitle,\n this.video,\n this.options.subtitle,\n this.events,\n );\n if (Array.isArray(this.options.subtitle.url)) {\n this.subtitles = new Subtitles(this);\n }\n if (!this.user.get(\"subtitle\")) {\n this.subtitle.hide();\n }\n this._loadSubtitleTexts();\n }\n }\n\n getHlsLevelLabel(level: HlsLevel): string {\n if (!level) return \"Auto\";\n if (level.height) return `${level.height}p`;\n if (level.bitrate) return `${Math.round(level.bitrate / 1000)}kbps`;\n return \"Auto\";\n }\n\n updateHlsQualityCurrentLabel(): void {\n const label = this.container.querySelector<HTMLElement>(\n \"#kplayer-quality-current\",\n );\n if (!label || !this.plugins.hls) return;\n\n const hls = this.plugins.hls as HlsInstance;\n if (hls.autoLevelEnabled) {\n const lvl = hls.levels[hls.currentLevel];\n label.textContent = lvl ? `Auto (${lvl.height}p)` : \"Auto\";\n } else {\n const lvl = hls.levels[hls.currentLevel];\n label.textContent = lvl ? `${lvl.height}p` : \"Manual\";\n }\n }\n\n buildHlsQualityMenu(\n hls: HlsInstance,\n HlsLib: {\n Events: Record<string, string>;\n isSupported: () => boolean;\n DefaultConfig: { loader: unknown };\n } & (new (opts: unknown) => HlsInstance),\n ): void {\n if (!hls?.levels?.length) return;\n\n const used = new Set<string>();\n const levels: Array<{\n index: number;\n name: string;\n height: number;\n bitrate: number;\n }> = [];\n\n hls.levels.forEach((level, idx) => {\n const key = `${level.height}-${level.bitrate}`;\n if (used.has(key)) return;\n used.add(key);\n levels.push({\n index: idx,\n name: level.height\n ? `${level.height}p`\n : `${Math.round((level.bitrate || 0) / 1000)}kbps`,\n height: level.height || 0,\n bitrate: level.bitrate || 0,\n });\n });\n\n levels.sort((a, b) => b.height - a.height || b.bitrate - a.bitrate);\n const list = [{ index: -1, name: \"Auto\" }, ...levels];\n\n const wrap = this.container.querySelector<HTMLElement>(\n \".kplayer-quality-list\",\n );\n if (!wrap) return;\n\n wrap.innerHTML = list\n .map(\n (item) => `\n <div class=\"kplayer-quality-item\" data-level=\"${item.index}\">\n <span class=\"kplayer-label\">${item.name}</span>\n </div>\n `,\n )\n .join(\"\");\n\n const items = wrap.querySelectorAll<HTMLElement>(\".kplayer-quality-item\");\n const label = this.container.querySelector<HTMLElement>(\n \"#kplayer-quality-current\",\n );\n\n items.forEach((el) => {\n // a11y: keyboard-аар сонгох боломжтой болгоно (setting-ийн keydown-д хамаарна)\n el.setAttribute(\"role\", \"menuitem\");\n el.setAttribute(\"tabindex\", \"0\");\n el.addEventListener(\"click\", () => {\n const level = Number(el.dataset.level);\n hls.currentLevel = level;\n hls.nextLevel = level;\n hls.loadLevel = level;\n items.forEach((i) => i.classList.remove(\"active\"));\n el.classList.add(\"active\");\n\n const qualityName = el.textContent?.trim() || \"\";\n if (label) label.textContent = qualityName;\n\n // Switching notice\n this.notice(\n `${this.tran(\"switching-quality\").replace(\"%q\", qualityName)}`,\n -1,\n undefined,\n \"switch-quality\",\n );\n\n // Switched notice — LEVEL_SWITCHED дээр нэг удаа\n const onSwitched = () => {\n this.notice(\n `${this.tran(\"switched-quality\").replace(\"%q\", qualityName)}`,\n 2000,\n undefined,\n \"switch-quality\",\n );\n hls.off(HlsLib.Events.LEVEL_SWITCHED, onSwitched);\n };\n hls.on(HlsLib.Events.LEVEL_SWITCHED, onSwitched);\n });\n });\n\n if (label) label.textContent = \"Auto\";\n }\n\n switchQuality(index: number | string): void {\n index = typeof index === \"string\" ? parseInt(index) : index;\n if (this.qualityIndex === index || this.switchingQuality) return;\n\n this.prevIndex = this.qualityIndex;\n this.qualityIndex = index;\n this.switchingQuality = true;\n this.quality = this.options.video.quality?.[index];\n if (!this.quality) return;\n\n if (this.template.qualityButton) {\n this.template.qualityButton.innerHTML = this.quality.name;\n }\n\n const qualityCurrent = this.container.querySelector<HTMLElement>(\n \"#kplayer-quality-current\",\n );\n if (qualityCurrent) qualityCurrent.textContent = this.quality.name;\n\n const paused = this.video.paused;\n this.video.pause();\n\n const videoHTML = renderVideo({\n current: false,\n pic: undefined,\n screenshot: this.options.screenshot,\n preload: \"auto\",\n url: this.quality.url,\n subtitle: this.options.subtitle,\n });\n\n const videoEle = new DOMParser().parseFromString(videoHTML, \"text/html\")\n .body.firstChild as HTMLVideoElement;\n\n this.template.videoWrap.insertBefore(\n videoEle,\n this.template.videoWrap.getElementsByTagName(\"div\")[0],\n );\n\n this.prevVideo = this.video;\n this.video = videoEle;\n this.initVideo(\n this.video,\n this.quality.type || this.options.video.type || \"auto\",\n );\n this.seek(this.prevVideo.currentTime);\n this.notice(\n `${this.tran(\"switching-quality\").replace(\"%q\", this.quality.name)}`,\n -1,\n undefined,\n \"switch-quality\",\n );\n this.events.trigger(\"quality_start\", this.quality);\n\n this.on(\"canplay\", () => {\n if (this.prevVideo) {\n if (this.video.currentTime !== this.prevVideo.currentTime) {\n this.seek(this.prevVideo.currentTime);\n return;\n }\n this.template.videoWrap.removeChild(this.prevVideo);\n this.video.classList.add(\"kplayer-video-current\");\n if (!paused) this.video.play();\n this.prevVideo = undefined;\n this.notice(\n `${this.tran(\"switched-quality\").replace(\"%q\", this.quality!.name)}`,\n undefined,\n undefined,\n \"switch-quality\",\n );\n this.switchingQuality = false;\n this.events.trigger(\"quality_end\");\n }\n });\n\n this.on(\"error\", () => {\n if (!this.video.error) return;\n if (this.prevVideo) {\n this.template.videoWrap.removeChild(this.video);\n this.video = this.prevVideo;\n if (!paused) this.video.play();\n this.qualityIndex = this.prevIndex;\n this.quality = this.options.video.quality?.[this.qualityIndex ?? 0];\n this.prevVideo = undefined;\n this.switchingQuality = false;\n }\n });\n }\n\n notice(text: string, time = 2000, opacity = 0.8, id?: string): void {\n let oldNoticeEle: HTMLElement | undefined;\n\n if (id) {\n oldNoticeEle = document.getElementById(`kplayer-notice-${id}`) as\n | HTMLElement\n | undefined;\n if (oldNoticeEle) oldNoticeEle.innerHTML = text;\n if (this.noticeList[id]) {\n clearTimeout(this.noticeList[id]!);\n this.noticeList[id] = null;\n }\n }\n\n if (!oldNoticeEle) {\n const notice = Template.NewNotice(text, opacity, id);\n this.template.noticeList.appendChild(notice);\n oldNoticeEle = notice;\n }\n\n this.events.trigger(\"notice_show\", oldNoticeEle);\n\n if (time > 0) {\n this.noticeList[id || \"\"] = setTimeout(\n ((e: HTMLElement, dp: KPlayer) => () => {\n e.addEventListener(\"animationend\", () => {\n dp.template.noticeList.removeChild(e);\n });\n e.classList.add(\"remove-notice\");\n dp.events.trigger(\"notice_hide\");\n dp.noticeList[id || \"\"] = null;\n })(oldNoticeEle, this),\n time,\n );\n }\n }\n\n resize(): void {\n // Narrow layout (нарийн контейнер) — өргөнөөс хамаарч responsive болгоно.\n this.container.classList.toggle(\n \"kplayer-arrow\",\n this.container.offsetWidth <= 500,\n );\n\n if (this.awaken) {\n (this.awaken as { resize: () => void }).resize();\n }\n if (this.controller.thumbnails) {\n this.controller.thumbnails.resize(\n 160,\n (this.video.videoHeight / this.video.videoWidth) * 160,\n this.template.barWrap.offsetWidth,\n );\n }\n this.events.trigger(\"resize\");\n }\n\n speed(rate: number): void {\n this.video.playbackRate = rate;\n }\n\n destroy(): void {\n instances.splice(instances.indexOf(this), 1);\n this.pause();\n this.resizeObserver?.disconnect();\n document.removeEventListener(\"click\", this.docClickFun, true);\n this.container.removeEventListener(\"click\", this.containerClickFun, true);\n this.fullScreen.destroy();\n this.hotkey.destroy();\n this.contextmenu.destroy();\n this.controller.destroy();\n this.timer.destroy();\n this.video.src = \"\";\n this.container.innerHTML = \"\";\n this.ad?.destroy();\n this.events.trigger(\"destroy\");\n }\n\n static get version(): string {\n return KPLAYER_VERSION;\n }\n\n // encrypt идэвхтэй үед key/iv-г шийднэ: keyProvider өгсөн бол түүгээр\n // (backend-ээс), эс бөгөөс статик key/iv-г ашиглана.\n private async _resolveSubtitleCrypto(): Promise<{\n key?: string;\n iv?: string;\n }> {\n const opts = this.options.subtitle;\n if (!opts?.encrypt) return {};\n if (opts.keyProvider) {\n try {\n const { key, iv } = await opts.keyProvider();\n return { key, iv };\n } catch (e) {\n console.warn(\"[KPlayer] subtitle keyProvider failed:\", e);\n }\n }\n return { key: opts.key, iv: opts.iv };\n }\n\n private async _loadSubtitleTexts(): Promise<void> {\n const opts = this.options.subtitle;\n if (!opts?.url || !Array.isArray(opts.url)) return;\n\n const idx = opts.index ?? 0;\n\n // Зөвхөн идэвхтэй subtitle-г ачаална\n const item = (opts.url as SubtitleItem[])[idx];\n if (!item?.url || item.lang === \"off\") return;\n\n try {\n const { key, iv } = await this._resolveSubtitleCrypto();\n const text = await fetchAndDecryptVtt(item.url, opts.encrypt, key, iv);\n await this.subtitle?.loadVttText(text);\n } catch (e) {\n console.warn(\"[KPlayer] Subtitle load failed:\", e);\n }\n }\n\n // subtitle солих үед дуудах (subtitles.ts дотор)\n public async loadSubtitleByIndex(index: number): Promise<void> {\n const opts = this.options.subtitle;\n if (!opts?.url || !Array.isArray(opts.url)) return;\n\n const item = (opts.url as SubtitleItem[])[index];\n if (!item?.url || item.lang === \"off\") {\n this.subtitle?.hide();\n return;\n }\n\n try {\n const { key, iv } = await this._resolveSubtitleCrypto();\n const text = await fetchAndDecryptVtt(item.url, opts.encrypt, key, iv);\n await this.subtitle?.loadVttText(text);\n this.subtitle?.show();\n } catch (e) {\n console.warn(\"[KPlayer] Subtitle switch failed:\", e);\n }\n }\n}\n\nexport default KPlayer;\n","import \"../css/index.less\";\nimport KPlayer from \"./player\";\n\nexport default KPlayer;\nexport type {\n KPlayerOptions,\n VideoQuality,\n SubtitleOptions,\n SubtitleItem,\n AdOptions,\n AdItem,\n HighlightItem,\n TitleOptions,\n ContextMenuItem,\n} from \"./types\";\n"],"mappings":"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"}
|