Greasy Fork 支持简体中文。

115Master

115网盘魔法优化: 画质增强 | 视频缩略图 | 在线字幕 | 内置 Jav 信息

// ==UserScript==
// @name         115Master
// @namespace    115Master
// @version      0.1.6
// @author       cbingb666
// @description  115网盘魔法优化: 画质增强 | 视频缩略图 | 在线字幕 | 内置 Jav 信息
// @icon         https://115.com/favicon.ico
// @homepage     https://github.com/cbingb666/115master
// @supportURL   https://github.com/cbingb666/115master/issues
// @include      https://115.com/?ct*
// @include      https://115.com/?aid*
// @include      https://dl.115cdn.net/master/*
// @include      https://115.com/web/lixian/video/?*
// @exclude      https://*.115.com/bridge*
// @exclude      https://*.115.com/static*
// @exclude      https://q.115.com/*
// @require      https://fastly.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js
// @require      https://fastly.jsdelivr.net/npm/[email protected]/dist/localforage.min.js
// @require      https://fastly.jsdelivr.net/npm/[email protected]/lodash.min.js
// @require      https://fastly.jsdelivr.net/npm/[email protected]/BigInteger.min.js
// @require      data:application/javascript,%3Bwindow.bigInt%3DbigInt%3B
// @require      https://cdn.jsdelivr.net/npm/[email protected]/js/md5.min.js
// @require      https://fastly.jsdelivr.net/npm/[email protected]/dayjs.min.js
// @require      data:application/javascript,%3Bwindow.dayjs%3Ddayjs%3B
// @require      https://fastly.jsdelivr.net/npm/[email protected]/dist/mux.min.js
// @require      data:application/javascript,%3Bwindow.Mux%3Dmuxjs%3B
// @require      https://fastly.jsdelivr.net/npm/[email protected]/dist/hls.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/m3u8-parser.min.js
// @require      https://fastly.jsdelivr.net/npm/[email protected]/dist/umd/photoswipe.umd.min.js
// @require      data:application/javascript,%3Bwindow.photoswipe%3DPhotoSwipe%3B
// @require      https://fastly.jsdelivr.net/npm/[email protected]/dist/umd/photoswipe-lightbox.umd.min.js
// @require      data:application/javascript,%3Bwindow.PhotoSwipeLightbox%3DPhotoSwipeLightbox%3B
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/system.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/extras/named-register.min.js
// @require      data:application/javascript,%3B(typeof%20System!%3D'undefined')%26%26(System%3Dnew%20System.constructor())%3B
// @resource     icon  https://115.com/favicon.ico
// @connect      115.com
// @connect      webapi.115.com
// @connect      proapi.115.com
// @connect      dl.115cdn.net
// @connect      cdnfhnfile.115cdn.net
// @connect      v.anxia.com
// @connect      115vod.com
// @connect      subtitlecat.com
// @connect      javbus.com
// @connect      javdb.com
// @connect      jdbstatic.com
// @connect      cpats01.115.com
// @grant        GM_addElement
// @grant        GM_addStyle
// @grant        GM_info
// @grant        GM_openInTab
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @run-at       document-start
// ==/UserScript==

(e=>{if(typeof GM_addStyle=="function"){GM_addStyle(e);return}const a=document.createElement("style");a.textContent=e,document.head.append(a)})(` .video-operation-tooltip{position:absolute;top:34px;left:50%;transform:translate(-50%);background:#0000004d;color:#fff;padding:8px 12px;border-radius:4px;font-size:12px;text-align:center;pointer-events:none;z-index:1000;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);width:60%;opacity:0}.video-operation-tooltip.show{transition:opacity .3s ease-in-out;transition-delay:.2s}.icon[data-v-6e980ff6]{width:26px;height:26px;vertical-align:middle;fill:currentColor}.icon[data-v-abf1332f]{width:24px;height:24px;vertical-align:middle;fill:currentColor}.loading-container[data-v-54976e1d]{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;overflow:hidden}.loading-backdrop[data-v-54976e1d]{position:absolute;top:0;left:0;width:100%;height:100%;background:#0f0f0fcc}.loading-effect[data-v-54976e1d]{position:relative;z-index:2;display:flex;justify-content:center;align-items:center;width:100%;height:100%}.loader[data-v-54976e1d]{position:relative;width:48px;height:48px;animation:scale-in-54976e1d .3s ease-out both}.loader-ring[data-v-54976e1d]{position:absolute;border-radius:50%;border:2px solid transparent}.outer[data-v-54976e1d]{width:100%;height:100%;border-top-color:#fffc;border-right-color:#fff9;animation:spin-54976e1d 1.5s linear infinite;box-shadow:0 0 10px #fff3}.inner[data-v-54976e1d]{width:70%;height:70%;top:15%;left:15%;border-bottom-color:#fffc;border-left-color:#fff9;animation:spin-reverse-54976e1d 1s linear infinite;box-shadow:0 0 8px #fff3}@keyframes spin-54976e1d{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spin-reverse-54976e1d{0%{transform:rotate(0)}to{transform:rotate(-360deg)}}@keyframes scale-in-54976e1d{0%{transform:scale(.5);opacity:0}to{transform:scale(1);opacity:1}}@keyframes fade-in-54976e1d{0%{opacity:0;-webkit-backdrop-filter:blur(0);backdrop-filter:blur(0)}to{opacity:1;-webkit-backdrop-filter:blur(20px) saturate(180%);backdrop-filter:blur(20px) saturate(180%)}}.preview-container[data-v-77441376]{position:absolute;bottom:100%;margin-bottom:10px;pointer-events:none;will-change:transform}.thumbnail-container[data-v-77441376]{position:relative;border-radius:16px;box-shadow:0 2px 8px #0f0f0fb3;overflow:hidden}.thumbnail-container canvas[data-v-77441376]{background:#0f0f0fe6}.time-tooltip[data-v-77441376]{text-align:center;margin-top:4px;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.5)}.thumbnail-loading[data-v-77441376]{position:absolute;top:0;left:0;right:0;bottom:0;background:#00000080;border-radius:16px}.progress-bar[data-v-6b1e2de1]{margin-bottom:10px;position:relative;font-size:13px}.progress-bar-wrapper[data-v-6b1e2de1]{padding:8px 0;cursor:pointer;position:relative}.progress-bar-container[data-v-6b1e2de1]{height:3px;background-color:#fff3;position:relative;transition:height .1s ease}.progress-bar-wrapper:hover .progress-bar-container[data-v-6b1e2de1]{height:5px}.progress-buffer[data-v-6b1e2de1]{position:absolute;height:100%;background-color:#fff6;transition:width .2s ease}.progress-current[data-v-6b1e2de1]{position:absolute;height:100%;background-color:var(--x-player-controller-progress-bar-color);transition:width .1s linear}.progress-current.progress-dragging[data-v-6b1e2de1]{background-color:var(--x-player-controller-progress-bar-color);transition:none}.progress-hover[data-v-6b1e2de1]{position:absolute;height:100%;background-color:var(--x-player-controller-progress-bar-color-hover);pointer-events:none}.progress-handle-container[data-v-6b1e2de1]{position:absolute;height:100%;transform:translate(-50%)}.progress-handle[data-v-6b1e2de1]{position:absolute;top:50%;left:50%;width:13px;height:13px;background-color:var(--x-player-controller-progress-bar-color);border-radius:50%;transform:translate(-50%,-50%) scale(0);transition:transform .1s ease;pointer-events:none}.progress-bar-wrapper:hover .progress-handle[data-v-6b1e2de1],.progress-handle.is-dragging[data-v-6b1e2de1]{transform:translate(-50%,-50%) scale(1)}.progress-handle-original[data-v-6b1e2de1]{background-color:#ffffff80;transform:translate(-50%,-50%) scale(1)!important}.x-popup[data-v-a8c7199f]{z-index:9999;border-radius:8px;position:relative;overflow:hidden}.x-popup-bg[data-v-a8c7199f]{position:absolute;top:0;right:0;bottom:0;left:0;background:#1c1c1cb3;-webkit-backdrop-filter:blur(20px) saturate(180%);backdrop-filter:blur(20px) saturate(180%);box-shadow:0 4px 12px #0000004d}.x-popup-content[data-v-a8c7199f]{position:relative;z-index:1}.x-menu[data-v-6ef95020]{min-width:200px;padding:8px;background:#1c1c1cf2;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border-radius:8px}[data-v-6ef95020] .menu-item{padding:8px 12px;color:#fff;cursor:pointer;transition:all .2s;font-size:14px;display:flex;align-items:center;justify-content:space-between;border-radius:6px;margin:2px 0}[data-v-6ef95020] .menu-item:hover{background:#ffffff1a}[data-v-6ef95020] .menu-item.active{color:var(--x-player-color-primary, #007aff);background:#007aff1a}[data-v-6ef95020] .menu-item.active:after{content:"\u2713";margin-left:8px}.quality-button[data-v-bc77eba9]{position:relative;padding:6px 12px;color:#fff;cursor:pointer;border-radius:6px;transition:all .2s;font-size:14px;display:flex;align-items:center;gap:4px;-webkit-user-select:none;user-select:none}.quality-button[data-v-bc77eba9]:hover{background:#ffffff26}.tooltip[data-v-bc77eba9]{padding:6px 12px;color:#fff;font-size:12px;white-space:nowrap;background:#1c1c1cf2;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border-radius:6px}[data-v-bc77eba9] .menu-item{position:relative;padding:8px 12px;color:#fff;cursor:pointer;transition:all .2s;font-size:14px;display:flex;align-items:center;justify-content:space-between;border-radius:6px;margin:2px 0}[data-v-bc77eba9] .menu-item:hover{background:#ffffff1a}[data-v-bc77eba9] .menu-item.active{color:var(--x-player-color-primary, #007aff);background:#007aff1a}[data-v-bc77eba9] .menu-item.active:after{content:"";position:absolute;right:12px;width:16px;height:16px;background-image:url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23007aff"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z"/></svg>');background-size:contain;background-repeat:no-repeat;background-position:center}.scroll-tip[data-v-b79b31e3]{position:absolute;left:50%;bottom:0;transform:translate(-50%);z-index:3;opacity:0;visibility:hidden;transition:all .3s ease}.scroll-tip.show[data-v-b79b31e3]{opacity:1;visibility:visible}.scroll-tip-content[data-v-b79b31e3]{display:flex;align-items:center;color:#fff;padding:12px 20px;border-radius:8px}.scroll-tip-content span[data-v-b79b31e3]{margin:4px 0}.icon[data-v-b79b31e3]{font-size:24px;animation:bounce-b79b31e3 1s infinite}@keyframes bounce-b79b31e3{0%,to{transform:translateY(-1px)}50%{transform:translateY(1px)}}.speed-button[data-v-bb11f985]{position:relative}.control-button[data-v-bb11f985]{display:flex;align-items:center;gap:4px;background:none;border:none;color:#fff;cursor:pointer;padding:4px 8px;font-size:13px;border-radius:4px;transition:background-color .2s}.control-button[data-v-bb11f985]:hover{background-color:#ffffff1a}.speed-menu[data-v-bb11f985]{position:absolute;bottom:100%;right:0;margin-bottom:8px;background-color:#1c1c1ce6;border-radius:4px;padding:8px 0;min-width:120px;box-shadow:0 2px 8px #0003}.speed-menu-items[data-v-bb11f985]{display:flex;flex-direction:column;gap:4px}.speed-menu-item[data-v-bb11f985]{background:none;border:none;color:#fff;cursor:pointer;padding:6px 16px;text-align:left;font-size:13px;transition:background-color .2s;width:100%}.speed-menu-item[data-v-bb11f985]:hover{background-color:#ffffff1a}.speed-menu-item.active[data-v-bb11f985]{color:var(--x-player-controller-progress-bar-color)}.fade-enter-active[data-v-bb11f985],.fade-leave-active[data-v-bb11f985]{transition:all .2s cubic-bezier(.4,0,.2,1)}.fade-enter-from[data-v-bb11f985],.fade-leave-to[data-v-bb11f985]{opacity:0;transform:translateY(4px)}.fade-enter-to[data-v-bb11f985],.fade-leave-from[data-v-bb11f985]{opacity:1;transform:translateY(0)}.subtitle-button[data-v-fec6a53e]{position:relative;display:inline-block}.control-button[data-v-fec6a53e]{background:none;border:none;color:#fff;cursor:pointer;padding:8px;transition:all .2s}.control-button[data-v-fec6a53e]:hover{opacity:.8}.subtitle-icon[data-v-fec6a53e]{width:24px;height:24px}.loading-icon[data-v-fec6a53e]{animation:spin-fec6a53e 1s linear infinite}@keyframes spin-fec6a53e{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.time-display[data-v-208629a5]{color:#fff;font-size:13px;display:flex;align-items:center;gap:4px;-webkit-user-select:none;user-select:none}.time-separator[data-v-208629a5]{opacity:.7}.volume-control[data-v-e33fb2a5]{display:flex;align-items:center;gap:8px}.volume-control-button[data-v-e33fb2a5]{display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:4px;border:none;background:transparent;cursor:pointer;color:#fff}.volume-control-button[data-v-e33fb2a5]:hover{opacity:.8}.volume-slider[data-v-e33fb2a5]{width:80px;display:flex;align-items:center}.volume-slider-track[data-v-e33fb2a5]{position:relative;width:100%;height:var(--x-player-volume-control-height)}.volume-slider-fill[data-v-e33fb2a5]{position:absolute;height:100%;background-color:var(--x-player-volume-control-fill-color);border-radius:calc(var(--x-player-volume-control-height) / 2);pointer-events:none}.volume-slider input[type=range][data-v-e33fb2a5]{position:absolute;width:100%;height:100%;background:var(--x-player-volume-control-track-color);border-radius:calc(var(--x-player-volume-control-height) / 2);outline:none;cursor:pointer;margin:0;padding:0}.volume-slider input[type=range][data-v-e33fb2a5]::-webkit-slider-thumb{-webkit-appearance:none;width:var(--x-player-volume-control-thumb-size);height:var(--x-player-volume-control-thumb-size);border-radius:50%;background:var(--x-player-volume-control-thumb-color);cursor:pointer;transition:all .2s ease;position:relative;z-index:1}.volume-slider input[type=range][data-v-e33fb2a5]::-webkit-slider-thumb:hover{transform:scale(1.2)}.volume-slider input[type=range][data-v-e33fb2a5]::-moz-range-thumb{width:var(--x-player-volume-control-thumb-size);height:var(--x-player-volume-control-thumb-size);border:none;border-radius:50%;background:var(--x-player-volume-control-thumb-color);cursor:pointer;transition:all .2s ease;position:relative;z-index:1}.volume-slider input[type=range][data-v-e33fb2a5]::-moz-range-thumb:hover{transform:scale(1.2)}.volume-slider input[type=range][data-v-e33fb2a5]::-ms-thumb{width:var(--x-player-volume-control-thumb-size);height:var(--x-player-volume-control-thumb-size);border-radius:50%;background:var(--x-player-volume-control-thumb-color);cursor:pointer;transition:all .2s ease;position:relative;z-index:1}.volume-slider input[type=range][data-v-e33fb2a5]::-ms-thumb:hover{transform:scale(1.2)}.material-symbols-rounded[data-v-e33fb2a5]{font-size:24px}.controls-wrapper[data-v-c45d079a]{position:absolute;bottom:0;left:0;right:0;pointer-events:auto}.controls-gradient[data-v-c45d079a]{position:absolute;bottom:0;left:0;right:0;height:180px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAC4CAYAAAAi0IY0AAAAAXNSR0IArs4c6QAAAQxJREFUOE9lyNdHBQAAhfHb3nvvuu2997jNe29TJJEkkkgSSSSJJJJEEkkiifRH5jsP56Xz8PM5gcC/xfCIWBNHxZsESiSaJEokQ4pJpUSaSadEhsmkskw2JXJMLiXyIN8UUKLQFFGi2JRQpaaMEuWmghKVUGWqKVFjgpSoNXVUvWmgRKNpokQztJhWSrSZdkp0mE6qy3RTosf0UqIP+s0AJQbNECWGzQg1asYoMW4mKBGCSTNFiWkzQ4lZM0eFTYQSUTNPiQVYNEuUWIYVWIU1WIcN2IQt2IYd2IU92IcDOIQjOIYTOIUzOIcLuIQruIYbuIU7uIcHeIQneIYXeIU3eIcP+IQv+IYf+P0Dkn4pkUpVXukAAAAASUVORK5CYII=);background-repeat:repeat-x;background-position:bottom;z-index:1;pointer-events:none;opacity:0;transition:opacity .3s ease}.controls-gradient.is-visible[data-v-c45d079a]{opacity:1}.video-controls[data-v-c45d079a]{position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,#000000b3);color:#fff;z-index:2;transform:translateY(calc(100% - 30px));opacity:.5;transition:all .3s ease}.video-controls.is-visible[data-v-c45d079a]{transform:translateY(0);opacity:1}.controls-content[data-v-c45d079a]{padding:10px 20px}.controls-bar[data-v-c45d079a]{display:flex;justify-content:space-between;align-items:center}.left-controls[data-v-c45d079a],.right-controls[data-v-c45d079a]{display:flex;align-items:center;gap:10px}button[data-v-c45d079a]{background:none;border:none;color:#fff;cursor:pointer;padding:5px}button[data-v-c45d079a]:hover{opacity:.8}.material-symbols-rounded[data-v-c45d079a]{font-size:24px;color:#fff;font-variation-settings:"FILL" 1,"wght" 400,"GRAD" 0,"opsz" 24}.progress-container[data-v-c45d079a]{position:absolute;top:0;left:20px;right:20px;z-index:3}.progress-container.hide[data-v-c45d079a]{transform:translateY(84px)}.controls-buttons[data-v-c45d079a]{margin-top:40px;padding-bottom:12px;transform-origin:bottom}.controls-buttons.hide[data-v-c45d079a]{transform:translateY(84px) scaleX(0)}.controls-gradient.hide[data-v-c45d079a]{opacity:0}:root{--x-player-background-color: #000;--x-player-color-primary: #0084ff;--x-player-color-primary-hover: #339dff;--x-player-color-primary-alpha: rgba(0, 132, 255, .3);--x-player-progress-bar-track-color: rgba(255, 255, 255, .3);--x-player-progress-bar-fill-color: var(--x-player-color-primary);--x-player-progress-bar-thumb-color: #fff;--x-player-progress-bar-thumb-size: 12px;--x-player-progress-bar-height: 4px;--x-player-volume-control-track-color: rgba(255, 255, 255, .3);--x-player-volume-control-fill-color: var(--x-player-color-primary);--x-player-volume-control-thumb-color: #fff;--x-player-volume-control-thumb-size: 12px;--x-player-volume-control-height: 4px;--x-player-controller-progress-bar-color: var(--x-player-color-primary);--x-player-controller-progress-bar-color-hover: var( --x-player-color-primary-hover )}.loading-container[data-v-45219110]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:2}.apple-loading[data-v-45219110]{position:relative;width:50px;height:20px;display:flex;align-items:center;justify-content:space-between}.apple-loading span[data-v-45219110]{width:10px;height:10px;background-color:#fffc;border-radius:50%;display:inline-block;animation:bounce-45219110 1.4s infinite ease-in-out both}.apple-loading span[data-v-45219110]:nth-child(1){animation-delay:-.32s}.apple-loading span[data-v-45219110]:nth-child(2){animation-delay:-.16s}@keyframes bounce-45219110{0%,80%,to{transform:scale(0);opacity:.3}40%{transform:scale(1);opacity:1}}.play-animation[data-v-9bc63abc]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:10;pointer-events:none}.play-animation-icon[data-v-9bc63abc]{width:80px;height:80px;background-color:#0009;border-radius:50%;display:flex;align-items:center;justify-content:center}.icon-wrapper[data-v-9bc63abc]{width:40px;height:40px;display:flex;align-items:center;justify-content:center}.fade-enter-active[data-v-9bc63abc],.fade-leave-active[data-v-9bc63abc]{transition:all .2s cubic-bezier(.4,0,.2,1)}.fade-enter-from[data-v-9bc63abc],.fade-leave-to[data-v-9bc63abc]{opacity:0;transform:translate(-50%,-50%) scale(.8)}.fade-enter-to[data-v-9bc63abc],.fade-leave-from[data-v-9bc63abc]{opacity:1;transform:translate(-50%,-50%) scale(1)}.x-player[data-v-2f4f5468]{width:100%;height:100%;position:relative;background-color:var(--x-player-background-color)}.x-player[data-v-2f4f5468] *{-webkit-user-select:none;user-select:none}.x-player.is-fullscreen[data-v-2f4f5468]{width:100vw;height:100vh}.player-container[data-v-2f4f5468]{position:relative;width:100%;height:100%;overflow:hidden}.video-container[data-v-2f4f5468]{position:relative;z-index:1;width:100%;height:100%;display:flex;justify-content:center;align-items:center}.video-mask[data-v-2f4f5468]{position:absolute;top:0;left:0;right:0;bottom:0;z-index:2}video[data-v-2f4f5468]{width:100%;height:100%;-webkit-backdrop-filter:saturate(1);backdrop-filter:saturate(1)}[data-v-2f4f5468] .controls-wrapper{z-index:3}.portal-container[data-v-2f4f5468]{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9999}.portal-container[data-v-2f4f5468]>*{pointer-events:auto}.resume-container[data-v-2f4f5468]{position:absolute;top:0;left:0;width:100%;height:100%;z-index:9999;display:flex;justify-content:center;align-items:center}.resume-container button[data-v-2f4f5468]{background-color:var(--x-player-background-color);color:var(--x-player-text-color);border-radius:32px;padding:8px 16px;font-size:14px;cursor:pointer}.skeleton[data-v-a833dc5b]{display:inline-block;position:relative;overflow:hidden;vertical-align:middle;background:#ffffff1a}.skeleton.circle[data-v-a833dc5b]{border-radius:50%!important}.skeleton-animated[data-v-a833dc5b]:after{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(90deg,#fff0,#ffffff1a,#fff0);animation:skeleton-loading-a833dc5b 1.5s infinite}@keyframes skeleton-loading-a833dc5b{0%{transform:translate(-100%)}to{transform:translate(100%)}}.header-file[data-v-708d094e]{display:flex;gap:8px;font-size:20px;font-weight:700}.header-file-text[data-v-708d094e]{color:#f1f1f1}.header-file-text-size[data-v-708d094e]{color:#999;font-size:12px}footer[data-v-c19dfa52]{padding:32px 0;color:#999;gap:16px;text-align:center}.footer-tags[data-v-c19dfa52]{display:flex;align-items:center;justify-content:center;gap:16px}p[data-v-c19dfa52]{font-size:12px}p a[data-v-c19dfa52]{color:#ff0}.loading-error[data-v-c2d74d07]{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:24px;color:#666}.loading-error-icon[data-v-c2d74d07]{width:48px;height:48px;color:#ff4d4f;animation:error-appear-c2d74d07 .3s ease-out}.loading-error-circle[data-v-c2d74d07]{opacity:0;animation:circle-appear-c2d74d07 .3s ease-out .2s forwards;transform-origin:center}.loading-error-cross[data-v-c2d74d07]{opacity:0;animation:cross-appear-c2d74d07 .3s ease-out .4s forwards;transform-origin:center}.loading-error-text[data-v-c2d74d07]{font-size:14px;animation:text-appear-c2d74d07 .3s ease-out .5s both}.loading-error-detail[data-v-c2d74d07]{font-size:12px;color:#999;animation:text-appear-c2d74d07 .3s ease-out .5s both}.loading-error-retry[data-v-c2d74d07]{padding:6px 16px;border:none;border-radius:4px;background:#ff4d4f;color:#fff;font-size:14px;cursor:pointer;transition:all .2s;animation:text-appear-c2d74d07 .3s ease-out .6s both}.loading-error-retry[data-v-c2d74d07]:hover{background:#ff7875}.loading-error-retry[data-v-c2d74d07]:active{background:#d9363e}@keyframes error-appear-c2d74d07{0%{transform:scale(.8);opacity:0}to{transform:scale(1);opacity:1}}@keyframes circle-appear-c2d74d07{0%{stroke-dasharray:0 100;transform:rotate(-90deg);opacity:0}to{stroke-dasharray:100 100;transform:rotate(90deg);opacity:1}}@keyframes cross-appear-c2d74d07{0%{transform:scale(0);opacity:0}to{transform:scale(1);opacity:1}}@keyframes text-appear-c2d74d07{0%{transform:translateY(-10px);opacity:0}to{transform:translateY(0);opacity:1}}.empty[data-v-a47b59ec]{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:32px 0;color:#666}.empty-image[data-v-a47b59ec]{margin-bottom:16px}.empty-image img[data-v-a47b59ec],.empty-image svg[data-v-a47b59ec]{max-width:100%;height:auto;vertical-align:middle}.empty-description[data-v-a47b59ec]{font-size:14px;line-height:1.6;text-align:center}.empty-footer[data-v-a47b59ec]{margin-top:16px}/*! PhotoSwipe main CSS by Dmytro Semenov | photoswipe.com */.pswp{--pswp-bg: #000;--pswp-placeholder-bg: #222;--pswp-root-z-index: 100000;--pswp-preloader-color: rgba(79, 79, 79, .4);--pswp-preloader-color-secondary: rgba(255, 255, 255, .9);--pswp-icon-color: #fff;--pswp-icon-color-secondary: #4f4f4f;--pswp-icon-stroke-color: #4f4f4f;--pswp-icon-stroke-width: 2px;--pswp-error-text-color: var(--pswp-icon-color)}.pswp{position:fixed;top:0;left:0;width:100%;height:100%;z-index:var(--pswp-root-z-index);display:none;touch-action:none;outline:0;opacity:.003;contain:layout style size;-webkit-tap-highlight-color:rgba(0,0,0,0)}.pswp:focus{outline:0}.pswp *{box-sizing:border-box}.pswp img{max-width:none}.pswp--open{display:block}.pswp,.pswp__bg{transform:translateZ(0);will-change:opacity}.pswp__bg{opacity:.005;background:var(--pswp-bg)}.pswp,.pswp__scroll-wrap{overflow:hidden}.pswp__scroll-wrap,.pswp__bg,.pswp__container,.pswp__item,.pswp__content,.pswp__img,.pswp__zoom-wrap{position:absolute;top:0;left:0;width:100%;height:100%}.pswp__img,.pswp__zoom-wrap{width:auto;height:auto}.pswp--click-to-zoom.pswp--zoom-allowed .pswp__img{cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.pswp--click-to-zoom.pswp--zoomed-in .pswp__img{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.pswp--click-to-zoom.pswp--zoomed-in .pswp__img:active{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.pswp--no-mouse-drag.pswp--zoomed-in .pswp__img,.pswp--no-mouse-drag.pswp--zoomed-in .pswp__img:active,.pswp__img{cursor:-webkit-zoom-out;cursor:-moz-zoom-out;cursor:zoom-out}.pswp__container,.pswp__img,.pswp__button,.pswp__counter{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pswp__item{z-index:1;overflow:hidden}.pswp__hidden{display:none!important}.pswp__content{pointer-events:none}.pswp__content>*{pointer-events:auto}.pswp__error-msg-container{display:grid}.pswp__error-msg{margin:auto;font-size:1em;line-height:1;color:var(--pswp-error-text-color)}.pswp .pswp__hide-on-close{opacity:.005;will-change:opacity;transition:opacity var(--pswp-transition-duration) cubic-bezier(.4,0,.22,1);z-index:10;pointer-events:none}.pswp--ui-visible .pswp__hide-on-close{opacity:1;pointer-events:auto}.pswp__button{position:relative;display:block;width:50px;height:60px;padding:0;margin:0;overflow:hidden;cursor:pointer;background:none;border:0;box-shadow:none;opacity:.85;-webkit-appearance:none;-webkit-touch-callout:none}.pswp__button:hover,.pswp__button:active,.pswp__button:focus{transition:none;padding:0;background:none;border:0;box-shadow:none;opacity:1}.pswp__button:disabled{opacity:.3;cursor:auto}.pswp__icn{fill:var(--pswp-icon-color);color:var(--pswp-icon-color-secondary)}.pswp__icn{position:absolute;top:14px;left:9px;width:32px;height:32px;overflow:hidden;pointer-events:none}.pswp__icn-shadow{stroke:var(--pswp-icon-stroke-color);stroke-width:var(--pswp-icon-stroke-width);fill:none}.pswp__icn:focus{outline:0}div.pswp__img--placeholder,.pswp__img--with-bg{background:var(--pswp-placeholder-bg)}.pswp__top-bar{position:absolute;left:0;top:0;width:100%;height:60px;display:flex;flex-direction:row;justify-content:flex-end;z-index:10;pointer-events:none!important}.pswp__top-bar>*{pointer-events:auto;will-change:opacity}.pswp__button--close{margin-right:6px}.pswp__button--arrow{position:absolute;width:75px;height:100px;top:50%;margin-top:-50px}.pswp__button--arrow:disabled{display:none;cursor:default}.pswp__button--arrow .pswp__icn{top:50%;margin-top:-30px;width:60px;height:60px;background:none;border-radius:0}.pswp--one-slide .pswp__button--arrow{display:none}.pswp--touch .pswp__button--arrow{visibility:hidden}.pswp--has_mouse .pswp__button--arrow{visibility:visible}.pswp__button--arrow--prev{right:auto;left:0}.pswp__button--arrow--next{right:0}.pswp__button--arrow--next .pswp__icn{left:auto;right:14px;transform:scaleX(-1)}.pswp__button--zoom{display:none}.pswp--zoom-allowed .pswp__button--zoom{display:block}.pswp--zoomed-in .pswp__zoom-icn-bar-v{display:none}.pswp__preloader{position:relative;overflow:hidden;width:50px;height:60px;margin-right:auto}.pswp__preloader .pswp__icn{opacity:0;transition:opacity .2s linear;animation:pswp-clockwise .6s linear infinite}.pswp__preloader--active .pswp__icn{opacity:.85}@keyframes pswp-clockwise{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.pswp__counter{height:30px;margin-top:15px;margin-inline-start:20px;font-size:14px;line-height:30px;color:var(--pswp-icon-color);text-shadow:1px 1px 3px var(--pswp-icon-color-secondary);opacity:.85}.pswp--one-slide .pswp__counter{display:none}.copy-button[data-v-a529d9a0]{display:inline-flex;align-items:center;justify-content:center;padding:2px 8px;border-radius:4px;background-color:#3b82f633;border:1px solid rgba(59,130,246,.4);color:#60a5fa;font-size:12px;cursor:pointer;transition:all .2s ease;outline:none;height:22px}.copy-button[data-v-a529d9a0]:hover{background-color:#3b82f64d}.copy-button.copied[data-v-a529d9a0]{background-color:#10b98133;border-color:#10b98166;color:#10b981}.copy-button-text[data-v-a529d9a0]{white-space:nowrap}.movie-info[data-v-54ae4cd9]{position:relative;display:flex;flex-direction:column}.movie-info-main[data-v-54ae4cd9]{position:relative;z-index:1;color:#e1e1e1;margin-top:24px}.movie-info-content[data-v-54ae4cd9]{display:flex;flex-direction:column;gap:12px}.movie-info-header[data-v-54ae4cd9]{margin-bottom:24px}.movie-info-header-title[data-v-54ae4cd9]{font-size:20px;font-weight:700;margin-bottom:4px;word-wrap:break-word;word-break:break-all;color:#f1f1f1;padding-right:140px}.movie-info-content-item[data-v-54ae4cd9]{display:flex;gap:8px;font-size:14px}.movie-info-content-item-label[data-v-54ae4cd9]{color:#999;min-width:40px}.movie-info-content-item-value[data-v-54ae4cd9]{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.movie-info-content-item-value a[data-v-54ae4cd9]{color:#60a5fa;text-decoration:none;transition:color .2s ease}.movie-info-content-item-value a[data-v-54ae4cd9]:hover{color:#3b82f6}.movie-info-header-actors[data-v-54ae4cd9]{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}.movie-info-header-actors-item[data-v-54ae4cd9]{position:relative;padding:4px;border-radius:8px;width:fit-content}.movie-info-header-actors-item-avatar[data-v-54ae4cd9]{position:relative;width:60px;height:60px}.movie-info-header-actors-item img[data-v-54ae4cd9]{width:60px;height:60px;border-radius:50%;object-fit:cover;border:2px solid #f1f1f1;box-sizing:border-box}.movie-info-header-actors-item-name[data-v-54ae4cd9]{font-size:16px;color:#f1f1f1;padding-right:8px}.movie-info-header-actors-item-sex[data-v-54ae4cd9]{position:absolute;top:-2px;right:-2px;width:16px;height:16px;border-radius:50%;display:flex;align-items:center;justify-content:center;background-color:#0009;color:#fff;font-size:12px}.movie-info-header-actors-item-sex.female[data-v-54ae4cd9]{background-color:#f472b6cc}.movie-info-header-actors-item-sex.male[data-v-54ae4cd9]{background-color:#3b82f6cc}.movie-info-header-actors-item-content[data-v-54ae4cd9]{display:flex;align-items:center;gap:12px;text-decoration:none;width:100%}.movie-info-source-switch[data-v-54ae4cd9]{position:absolute;top:0;right:0;display:flex;gap:8px;z-index:2}.movie-info-source-switch-item[data-v-54ae4cd9]{padding:6px 12px;border-radius:4px;background:#00000080;cursor:pointer;transition:all .2s ease}.movie-info-source-switch-item[data-v-54ae4cd9]:hover{background:#000000b3}.movie-info-source-switch-item.active[data-v-54ae4cd9]{background:#60a5fa}.movie-info-source-switch-item-text[data-v-54ae4cd9]{font-size:12px;color:#fff}.movie-info-thumb[data-v-54ae4cd9]{display:flex;flex-wrap:wrap;gap:12px;margin-top:24px}.movie-info-thumb-item[data-v-54ae4cd9]{width:calc(12.5% - 12px);aspect-ratio:1 / 1;border-radius:5px;overflow:hidden;cursor:pointer;transition:opacity .2s;display:block;text-decoration:none}.movie-info-thumb-item[data-v-54ae4cd9]:hover{opacity:.8}.movie-info-thumb-item img[data-v-54ae4cd9]{width:100%;height:100%;object-fit:cover}.playlist[data-v-1718588c]{position:relative;display:flex;flex-direction:column;width:100%;height:100%;background-color:#000000e6;color:#fff;box-sizing:border-box;border-radius:16px;z-index:1;overflow:hidden}.playlist-header[data-v-1718588c]{position:absolute;top:0;left:0;right:0;z-index:2;font-size:20px;color:#eee;padding:20px 28px}.playlist-list[data-v-1718588c]{display:flex;flex-direction:column;gap:8px;padding:12px 16px 20px;margin-top:68px;overflow-y:auto}.playlist-item[data-v-1718588c]{padding:12px;border-radius:8px;transition:background-color .2s ease;cursor:pointer;gap:2px;color:#eee;word-wrap:break-word}.playlist-item[data-v-1718588c]:hover{background-color:#ffffff1a}.playlist-item.active[data-v-1718588c]{background-color:#fff3}.playlist-item-title[data-v-1718588c]{font-size:14px}.playlist-item-size[data-v-1718588c]{font-size:12px;color:#999}.playlist[data-v-1718588c]::-webkit-scrollbar{width:6px}.playlist[data-v-1718588c]::-webkit-scrollbar-track{background:transparent}.playlist[data-v-1718588c]::-webkit-scrollbar-thumb{background-color:#fff3;border-radius:3px}.playlist[data-v-1718588c]::-webkit-scrollbar-thumb:hover{background-color:#ffffff4d}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#ffffff4d;border-radius:4px}::-webkit-scrollbar-thumb:hover{background:#ffffff4d}:fullscreen ::-webkit-scrollbar{width:0!important;height:0!important;display:none!important}.page-container[data-v-93440d89]{padding:36px 0 56px;background:#0f0f0f;display:flex;flex-direction:column;min-height:100vh;color:#fff;align-items:center;--video-player-height: calc(100vh - 112px) ;--page-main-width-a: calc(16 / 9 * (100vh - 36px - 24px * 2 - 28px));--page-main-width-b: calc(100vw - 440px) ;--page-main-width: min(var(--page-main-width-a), var(--page-main-width-b));--video-player-width: var(--page-main-width)}.page-local-play[data-v-93440d89]{display:inline-flex;background:#000;color:#fff;padding:10px 20px;border-radius:16px;cursor:pointer}.page-body[data-v-93440d89]{display:flex;gap:24px}.page-main[data-v-93440d89]{display:flex;flex-direction:column;width:var(--page-main-width);gap:24px}.page-flow[data-v-93440d89]{display:flex;flex-direction:column;gap:24px;min-height:720px}.video-player[data-v-93440d89]{aspect-ratio:16 / 9;width:var(--video-player-width);height:auto;border-radius:16px;overflow:hidden;box-shadow:0 0 500px 100px #7d7d7d26}.page-sider-playlist[data-v-93440d89]{width:380px;height:calc(100vh - 60px);flex:1}:fullscreen .page-container[data-v-93440d89]{padding:0 0 56px}:fullscreen .page-main[data-v-93440d89]{width:auto}:fullscreen .page-header[data-v-93440d89]{display:none}:fullscreen .page-flow[data-v-93440d89]{padding:0 490px 56px 86px;box-sizing:border-box}:fullscreen .page-sider[data-v-93440d89]{position:absolute;top:calc(100vh + 76px);right:86px}:fullscreen .page-sider-playlist[data-v-93440d89]{height:720px}:fullscreen .video-player[data-v-93440d89]{width:100vw;height:100vh;max-height:none;border-radius:0}.user-agent-popup-overlay[data-v-8574f3b4]{position:fixed;top:0;left:0;right:0;bottom:0;background-color:#0009;display:flex;justify-content:center;align-items:center;z-index:10000;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}.popup-main[data-v-8574f3b4]{padding:0 24px 24px}.user-agent-popup[data-v-8574f3b4]{background-color:#fff;border-radius:12px;box-shadow:0 10px 30px #0003;width:550px;max-width:90vw;max-height:90vh;overflow:auto;animation:popup-fade-in-8574f3b4 .3s cubic-bezier(.16,1,.3,1)}.user-agent-popup-header[data-v-8574f3b4]{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;border-bottom:1px solid #eaeaea}.user-agent-popup-header h3[data-v-8574f3b4]{margin:0;font-size:18px;font-weight:600;color:#333}.close-button[data-v-8574f3b4]{background:none;border:none;font-size:24px;cursor:pointer;color:#999;padding:0;line-height:1;width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.close-button[data-v-8574f3b4]:hover{color:#333;background-color:#f5f5f5}.popup-content[data-v-8574f3b4]{margin:24px 0;display:flex;align-items:flex-start;background-color:#f9f9f9;border-radius:8px;padding:16px}.content-icon[data-v-8574f3b4]{margin-right:16px;color:#2196f3;flex-shrink:0}.number-icon[data-v-8574f3b4]{display:flex;align-items:center;justify-content:center;width:24px;height:24px;background-color:#2196f3;color:#fff;border-radius:50%;font-size:14px;font-weight:600}.content-text[data-v-8574f3b4]{flex:1}.content-text p[data-v-8574f3b4]{line-height:1.6;margin:0 0 8px;color:#444}.content-text p[data-v-8574f3b4]:last-child{margin-bottom:0}.popup-desc[data-v-8574f3b4]{font-size:14px;color:#666;text-align:center;margin-top:24px}.popup-desc p[data-v-8574f3b4]{margin:0 0 8px;font-weight:500}.user-agent-box[data-v-8574f3b4]{background-color:#f5f5f5;border-radius:6px;padding:12px;font-size:12px;color:#666;word-break:break-all;text-align:left;font-family:monospace;border:1px solid #eaeaea}a[data-v-8574f3b4]{color:#2196f3;text-decoration:none;font-weight:500;transition:color .2s}a[data-v-8574f3b4]:hover{color:#0d6efd;text-decoration:underline}@keyframes popup-fade-in-8574f3b4{0%{opacity:0;transform:translateY(30px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}} `);

System.addImportMap({ imports: {"vue":"user:vue","localforage":"user:localforage","lodash":"user:lodash","photoswipe/lightbox":"user:photoswipe/lightbox","photoswipe":"user:photoswipe","blueimp-md5":"user:blueimp-md5","m3u8-parser":"user:m3u8-parser","dayjs":"user:dayjs","mux.js":"user:mux.js","hls.js":"user:hls.js","big-integer":"user:big-integer"} });
System.set("user:vue", (()=>{const _=Vue;('default' in _)||(_.default=_);return _})());
System.set("user:localforage", (()=>{const _=localforage;('default' in _)||(_.default=_);return _})());
System.set("user:lodash", (()=>{const _1=_;('default' in _1)||(_1.default=_1);return _1})());
System.set("user:photoswipe/lightbox", (()=>{const _=PhotoSwipeLightbox;('default' in _)||(_.default=_);return _})());
System.set("user:photoswipe", (()=>{const _=photoswipe;('default' in _)||(_.default=_);return _})());
System.set("user:blueimp-md5", (()=>{const _=md5;('default' in _)||(_.default=_);return _})());
System.set("user:m3u8-parser", (()=>{const _=m3u8Parser;('default' in _)||(_.default=_);return _})());
System.set("user:dayjs", (()=>{const _=dayjs;('default' in _)||(_.default=_);return _})());
System.set("user:mux.js", (()=>{const _=muxjs;('default' in _)||(_.default=_);return _})());
System.set("user:hls.js", (()=>{const _=Hls;('default' in _)||(_.default=_);return _})());
System.set("user:big-integer", (()=>{const _=bigInt;('default' in _)||(_.default=_);return _})());

System.register("./__entry.js", ['blueimp-md5', 'big-integer', 'vue', 'hls.js', 'localforage', 'dayjs', 'photoswipe/lightbox', 'lodash', 'm3u8-parser', 'mux.js'], (function (exports, module) {
  'use strict';
  var md5, bigInt, createApp, h, defineComponent, ref, openBlock, createBlock, Teleport, createElementBlock, createElementVNode, withModifiers, toDisplayString, createCommentVNode, onMounted, unref, createVNode, watch, reactive, computed, nextTick, getCurrentScope, onScopeDispose, toRef$1, readonly, customRef, onUnmounted, toValue, shallowRef, normalizeClass, Fragment, renderList, createTextVNode, isRef, getCurrentInstance, provide, withDirectives, vShow, Transition, withCtx, normalizeStyle, renderSlot, createStaticVNode, inject, resolveDynamicComponent, Hls, localforage, dayjs, PhotoSwipeLightbox, sampleSize, Parser, Mux;
  return {
    setters: [module => {
      md5 = module.default;
    }, module => {
      bigInt = module.default;
    }, module => {
      createApp = module.createApp;
      h = module.h;
      defineComponent = module.defineComponent;
      ref = module.ref;
      openBlock = module.openBlock;
      createBlock = module.createBlock;
      Teleport = module.Teleport;
      createElementBlock = module.createElementBlock;
      createElementVNode = module.createElementVNode;
      withModifiers = module.withModifiers;
      toDisplayString = module.toDisplayString;
      createCommentVNode = module.createCommentVNode;
      onMounted = module.onMounted;
      unref = module.unref;
      createVNode = module.createVNode;
      watch = module.watch;
      reactive = module.reactive;
      computed = module.computed;
      nextTick = module.nextTick;
      getCurrentScope = module.getCurrentScope;
      onScopeDispose = module.onScopeDispose;
      toRef$1 = module.toRef;
      readonly = module.readonly;
      customRef = module.customRef;
      onUnmounted = module.onUnmounted;
      toValue = module.toValue;
      shallowRef = module.shallowRef;
      normalizeClass = module.normalizeClass;
      Fragment = module.Fragment;
      renderList = module.renderList;
      createTextVNode = module.createTextVNode;
      isRef = module.isRef;
      getCurrentInstance = module.getCurrentInstance;
      provide = module.provide;
      withDirectives = module.withDirectives;
      vShow = module.vShow;
      Transition = module.Transition;
      withCtx = module.withCtx;
      normalizeStyle = module.normalizeStyle;
      renderSlot = module.renderSlot;
      createStaticVNode = module.createStaticVNode;
      inject = module.inject;
      resolveDynamicComponent = module.resolveDynamicComponent;
    }, module => {
      Hls = module.default;
    }, module => {
      localforage = module.default;
    }, module => {
      dayjs = module.default;
    }, module => {
      PhotoSwipeLightbox = module.default;
    }, module => {
      sampleSize = module.sampleSize;
    }, module => {
      Parser = module.Parser;
    }, module => {
      Mux = module.default;
    }],
    execute: (function () {

      function getDefaultExportFromCjs(x) {
        return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
      }
      var globToRegexp;
      var hasRequiredGlobToRegexp;
      function requireGlobToRegexp() {
        if (hasRequiredGlobToRegexp) return globToRegexp;
        hasRequiredGlobToRegexp = 1;
        globToRegexp = function(glob, opts) {
          if (typeof glob !== "string") {
            throw new TypeError("Expected a string");
          }
          var str = String(glob);
          var reStr = "";
          var extended = opts ? !!opts.extended : false;
          var globstar = opts ? !!opts.globstar : false;
          var inGroup = false;
          var flags = opts && typeof opts.flags === "string" ? opts.flags : "";
          var c;
          for (var i2 = 0, len = str.length; i2 < len; i2++) {
            c = str[i2];
            switch (c) {
              case "/":
              case "$":
              case "^":
              case "+":
              case ".":
              case "(":
              case ")":
              case "=":
              case "!":
              case "|":
                reStr += "\\" + c;
                break;
              case "?":
                if (extended) {
                  reStr += ".";
                  break;
                }
              case "[":
              case "]":
                if (extended) {
                  reStr += c;
                  break;
                }
              case "{":
                if (extended) {
                  inGroup = true;
                  reStr += "(";
                  break;
                }
              case "}":
                if (extended) {
                  inGroup = false;
                  reStr += ")";
                  break;
                }
              case ",":
                if (inGroup) {
                  reStr += "|";
                  break;
                }
                reStr += "\\" + c;
                break;
              case "*":
                var prevChar = str[i2 - 1];
                var starCount = 1;
                while (str[i2 + 1] === "*") {
                  starCount++;
                  i2++;
                }
                var nextChar = str[i2 + 1];
                if (!globstar) {
                  reStr += ".*";
                } else {
                  var isGlobstar = starCount > 1 && (prevChar === "/" || prevChar === undefined) && (nextChar === "/" || nextChar === undefined);
                  if (isGlobstar) {
                    reStr += "((?:[^/]*(?:/|$))*)";
                    i2++;
                  } else {
                    reStr += "([^/]*)";
                  }
                }
                break;
              default:
                reStr += c;
            }
          }
          if (!flags || !~flags.indexOf("g")) {
            reStr = "^" + reStr + "$";
          }
          return new RegExp(reStr, flags);
        };
        return globToRegexp;
      }
      var globToRegexpExports = requireGlobToRegexp();
      const globToRegex = /* @__PURE__ */ getDefaultExportFromCjs(globToRegexpExports);
      const NORMAL_HOST_155 = "115.com";
      const WEB_API_HOST_155 = "webapi.115.com";
      const PRO_API_HOST_155 = "proapi.115.com";
      const VOD_HOST_155 = "115vod.com";
      const DL_HOST_155 = "dl.115cdn.net";
      const NORMAL_URL_115 = `https://${NORMAL_HOST_155}`;
      const WEB_API_URL_115 = `https://${WEB_API_HOST_155}`;
      const PRO_API_URL_115 = `https://${PRO_API_HOST_155}`;
      const VOD_URL_115 = `https://${VOD_HOST_155}`;
      const ROUTE_MATCH = {
        HOME: "*://115.com/?*",
        VIDEO: `*://${DL_HOST_155}/master/video/*`
      };
      var _GM_addElement = /* @__PURE__ */ (() => typeof GM_addElement != "undefined" ? GM_addElement : undefined)();
      var _GM_info = /* @__PURE__ */ (() => typeof GM_info != "undefined" ? GM_info : undefined)();
      var _GM_openInTab = /* @__PURE__ */ (() => typeof GM_openInTab != "undefined" ? GM_openInTab : undefined)();
      var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : undefined)();
      var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : undefined)();
      class IRequest {
      }
      const isChrome = _GM_info.userAgentData.brands.some(
        (brand) => brand.brand === "Google Chrome"
      );
      class GMRequest extends IRequest {
        async request(url, options = {}) {
          const urlRe = new URL(url);
          if (options.params) {
            Object.entries(options.params).forEach(([key, value]) => {
              urlRe.searchParams.set(key, value.toString());
            });
          }
          const redirect = isChrome ? options.redirect || "manual" : "follow";
          return new Promise((resolve, reject) => {
            _GM_xmlhttpRequest({
              method: options.method || "GET",
              url: urlRe.href,
              headers: options.headers,
              data: options.body,
              timeout: options.timeout || 5e3,
              responseType: options.responseType,
              redirect,
              onload: (response) => {
                let data;
                try {
                  data = JSON.parse(response.responseText);
                } catch {
                  data = response.response;
                }
                resolve({
                  data,
                  status: response.status,
                  statusText: response.statusText,
                  headers: this.parseResponseHeaders(response.responseHeaders),
                  rawResponse: response
                });
              },
              onerror: (e) => {
                reject(new Error("请求失败", { cause: e.error }));
              },
              ontimeout: () => {
                reject(new Error("请求超时"));
              }
            });
          });
        }
        get(url, options) {
          return this.request(url, { ...options, method: "GET" });
        }
        post(url, data, options) {
          return this.request(url, { ...options, method: "POST", body: data });
        }
        parseResponseHeaders(headerStr) {
          const headers = {};
          if (!headerStr) return headers;
          const headerPairs = headerStr.split("\n");
          for (let i2 = 0; i2 < headerPairs.length; i2++) {
            const headerPair = headerPairs[i2].trim();
            if (headerPair) {
              const index = headerPair.indexOf(":");
              if (index > 0) {
                const key = headerPair.substring(0, index).trim();
                const val = headerPair.substring(index + 1).trim();
                headers[key.toLowerCase()] = val;
              }
            }
          }
          return headers;
        }
      }
      const qualityNumMap = {
        360: "360P",
        480: "480P",
        720: "720P",
        1080: "1080P",
        2160: "4K",
        9999: "原画"
      };
      const qualityCodeMap = {
        "3G": 360,
        SD: 480,
        HD: 720,
        UD: 1080,
        BD: 2160,
        YH: 9999
      };
      const USER_AGENT_115 = navigator.userAgent;
      class Logger {
        constructor(appName, moduleName) {
          this.appName = appName;
          this.moduleName = moduleName;
        }
        formatMessage(logName, ...args) {
          return [
            `%c${this.appName}%c ${this.moduleName}%c ${logName}%c ${args}`,
            "color: #409EFF; font-weight: bold",
            // appName 样式:蓝色
            "color: #67C23A; font-weight: bold",
            // moduleName 样式:绿色
            "color: #E6A23C; font-weight: bold",
            // logName 样式:黄色
            "color: inherit; margin-top: 4px"
            // 恢复默认样式
          ];
        }
        log(logName, ...args) {
          if (args.length === 0 || typeof args[0] === "string" || typeof args[0] === "number") {
            console.log(...this.formatMessage(logName, ...args));
          } else {
            console.log(...this.formatMessage(logName));
            console.log(...args);
          }
        }
        error(logName, msg) {
          console.log(...this.formatMessage(logName));
          console.error(msg);
        }
      }
      class AppLogger extends Logger {
        constructor(moduleName) {
          super("115Master", moduleName);
        }
      }
      class Rsa115 {
        constructor() {
          this.n = bigInt(
            "8686980c0f5a24c4b9d43020cd2c22703ff3f450756529058b1cf88f09b8602136477198a6e2683149659bd122c33592fdb5ad47944ad1ea4d36c6b172aad6338c3bb6ac6227502d010993ac967d1aef00f0c8e038de2e4d3bc2ec368af2e9f10a6f1eda4f7262f136420c07c331b871bf139f74f3010e3c4fe57df3afb71683",
            16
          );
          this.e = bigInt("10001", 16);
        }
        a2hex(byteArray) {
          let hexString = "";
          let nextHexByte;
          for (let i2 = 0; i2 < byteArray.length; i2++) {
            nextHexByte = byteArray[i2].toString(16);
            if (nextHexByte.length < 2) {
              nextHexByte = `0${nextHexByte}`;
            }
            hexString += nextHexByte;
          }
          return hexString;
        }
        hex2a(hex) {
          let str = "";
          for (let i2 = 0; i2 < hex.length; i2 += 2) {
            str += String.fromCharCode(parseInt(hex.substr(i2, 2), 16));
          }
          return str;
        }
        pkcs1pad2(s, n) {
          if (n < s.length + 11) {
            return null;
          }
          const ba = [];
          let pos = n;
          let i2 = s.length - 1;
          while (i2 >= 0 && pos > 0) {
            ba[--pos] = s.charCodeAt(i2--);
          }
          ba[--pos] = 0;
          while (pos > 2) {
            ba[--pos] = 255;
          }
          ba[--pos] = 2;
          ba[--pos] = 0;
          const c = this.a2hex(ba);
          return bigInt(c, 16);
        }
        pkcs1unpad2(a) {
          let b = a.toString(16);
          if (b.length % 2 !== 0) {
            b = `0${b}`;
          }
          const c = this.hex2a(b);
          let i2 = 1;
          while (c.charCodeAt(i2) !== 0) {
            i2++;
          }
          return c.slice(i2 + 1);
        }
        encrypt(text) {
          const m = this.pkcs1pad2(text, 128);
          if (!m) {
            throw new Error("pkcs1pad2 failed");
          }
          const c = m.modPow(this.e, this.n);
          let h2 = c.toString(16);
          while (h2.length < 128 * 2) {
            h2 = `0${h2}`;
          }
          return h2;
        }
        decrypt(text) {
          const ba = [];
          let i2 = 0;
          while (i2 < text.length) {
            ba[i2] = text.charCodeAt(i2);
            i2 += 1;
          }
          const a = bigInt(this.a2hex(ba), 16);
          const c = a.modPow(this.e, this.n);
          const d = this.pkcs1unpad2(c);
          return d;
        }
      }
      class Crypto115 {
        constructor() {
          this.rsa = new Rsa115();
          this.kts = [
            240,
            229,
            105,
            174,
            191,
            220,
            191,
            138,
            26,
            69,
            232,
            190,
            125,
            166,
            115,
            184,
            222,
            143,
            231,
            196,
            69,
            218,
            134,
            196,
            155,
            100,
            139,
            20,
            106,
            180,
            241,
            170,
            56,
            1,
            53,
            158,
            38,
            105,
            44,
            134,
            0,
            107,
            79,
            165,
            54,
            52,
            98,
            166,
            42,
            150,
            104,
            24,
            242,
            74,
            253,
            189,
            107,
            151,
            143,
            77,
            143,
            137,
            19,
            183,
            108,
            142,
            147,
            237,
            14,
            13,
            72,
            62,
            215,
            47,
            136,
            216,
            254,
            254,
            126,
            134,
            80,
            149,
            79,
            209,
            235,
            131,
            38,
            52,
            219,
            102,
            123,
            156,
            126,
            157,
            122,
            129,
            50,
            234,
            182,
            51,
            222,
            58,
            169,
            89,
            52,
            102,
            59,
            170,
            186,
            129,
            96,
            72,
            185,
            213,
            129,
            156,
            248,
            108,
            132,
            119,
            255,
            84,
            120,
            38,
            95,
            190,
            232,
            30,
            54,
            159,
            52,
            128,
            92,
            69,
            44,
            155,
            118,
            213,
            27,
            143,
            204,
            195,
            184,
            245
          ];
          this.keyS = [41, 35, 33, 94];
          this.keyL = [120, 6, 173, 76, 51, 134, 93, 24, 76, 1, 63, 70];
        }
        xor115Enc(src, srclen, key, keylen) {
          const mod4 = srclen % 4;
          const ret2 = [];
          for (let i2 = 0; i2 < mod4; i2++) {
            ret2.push(src[i2] ^ key[i2 % keylen]);
          }
          for (let i2 = mod4; i2 < srclen; i2++) {
            ret2.push(src[i2] ^ key[(i2 - mod4) % keylen]);
          }
          return ret2;
        }
        getkey(length, key) {
          if (key) {
            const results = [];
            for (let i2 = 0; i2 < length; i2++) {
              const v1 = key[i2] + this.kts[length * i2] & 255;
              const v2 = this.kts[length * (length - 1 - i2)];
              results.push(v1 ^ v2);
            }
            return results;
          }
          return length === 12 ? this.keyL.slice(0) : this.keyS.slice(0);
        }
        asymEncode(src, srclen) {
          const m = 128 - 11;
          let ret2 = "";
          for (let i2 = 0; i2 < Math.floor((srclen + m - 1) / m); i2++) {
            ret2 += this.rsa.encrypt(
              this.bytesToString(src.slice(i2 * m, Math.min((i2 + 1) * m, srclen)))
            );
          }
          return btoa(this.rsa.hex2a(ret2));
        }
        asymDecode(src, srclen) {
          const m = 128;
          let ret2 = "";
          for (let i2 = 0; i2 < Math.floor((srclen + m - 1) / m); i2++) {
            ret2 += this.rsa.decrypt(
              this.bytesToString(src.slice(i2 * m, Math.min((i2 + 1) * m, srclen)))
            );
          }
          return this.stringToBytes(ret2);
        }
        symEncode(src, srclen, key1, key2) {
          const k1 = this.getkey(4, key1);
          const k2 = this.getkey(12, key2);
          let ret2 = this.xor115Enc(src, srclen, k1, 4);
          ret2.reverse();
          ret2 = this.xor115Enc(ret2, srclen, k2, 12);
          return ret2;
        }
        symDecode(src, srclen, key1, key2) {
          const k1 = this.getkey(4, key1);
          const k2 = this.getkey(12, key2);
          let ret2 = this.xor115Enc(src, srclen, k2, 12);
          ret2.reverse();
          ret2 = this.xor115Enc(ret2, srclen, k1, 4);
          return ret2;
        }
        bytesToString(buf) {
          return buf.map((b) => String.fromCharCode(b)).join("");
        }
        stringToBytes(str) {
          return Array.from(str).map((c) => c.charCodeAt(0));
        }
        m115_encode(str, timestamp) {
          const key = this.stringToBytes(md5(`!@###@#${timestamp}DFDR@#@#`));
          let temp = this.stringToBytes(str);
          temp = this.symEncode(temp, temp.length, key);
          temp = key.slice(0, 16).concat(temp);
          return {
            data: this.asymEncode(temp, temp.length),
            key
          };
        }
        m115_decode(str, key) {
          let temp = this.stringToBytes(atob(str));
          temp = this.asymDecode(temp, temp.length);
          return this.bytesToString(
            this.symDecode(temp.slice(16), temp.length - 16, key, temp.slice(0, 16))
          );
        }
      }
      class Drive115Core {
        constructor(iRequest) {
          this.iRequest = iRequest;
          this.logger = new AppLogger("Drive115Core");
          this.BASE_URL = NORMAL_URL_115;
          this.WEB_API_URL = WEB_API_URL_115;
          this.PRO_API_URL = PRO_API_URL_115;
          this.VOD_URL_115 = VOD_URL_115;
          this.crypto115 = new Crypto115();
        }
        verify() {
          const time = (/* @__PURE__ */ new Date()).getTime();
          const w = 335;
          const h2 = 500;
          const t = (window.screen.availHeight - h2) / 2;
          const l = (window.screen.availWidth - w) / 2;
          const link = `https://captchaapi.115.com/?ac=security_code&type=web&cb=Close911_${time}`;
          const isConfirm = confirm("立即打开验证账号弹窗?");
          if (isConfirm) {
            let blocked = false;
            try {
              const WindowProxy = window.open(
                link,
                "请验证账号",
                `height=${h2},width=${w},top=${t},left=${l},toolbar=no,menubar=no,scrollbars=no,resizable=no,location=no,status=no`
              );
              if (WindowProxy == null) {
                blocked = true;
              }
            } catch (e) {
              blocked = true;
            }
            if (blocked) {
              alert("验证弹窗已被拦截,请允许本页面弹出式窗口!");
            }
          }
        }
        async fakeVodAuthPickcode(pickcode) {
          await this.iRequest.get(
            new URL(`?pickcode=${pickcode}`, this.VOD_URL_115).href,
            {
              headers: {
                "User-Agent": USER_AGENT_115
              },
              responseType: "document",
              redirect: "follow"
            }
          );
        }
        async getDownloadUrlByNormal(pickcode) {
          const response = await this.iRequest.get(
            new URL(`/files/download?pickcode=${pickcode}`, this.WEB_API_URL).href,
            {
              headers: {
                "Content-Type": "application/x-www-form-urlencoded"
              }
            }
          );
          if (response.data.errNo === 990001) {
            alert("登录已过期,请重新登录");
          }
          if (!response.data.state || !response.data.file_url) {
            throw new Error(
              `服务器返回数据格式错误: ${JSON.stringify(response.data)}`
            );
          }
          return {
            url: response.data.file_url
          };
        }
        async getDownloadUrlByPro(pickcode) {
          var _a;
          const tm = Math.floor(Date.now() / 1e3).toString();
          const src = JSON.stringify({ pickcode });
          const encoded = this.crypto115.m115_encode(src, tm);
          const data = `data=${encodeURIComponent(encoded.data)}`;
          this.logger.log("发送加密数据:", data);
          const response = await this.iRequest.post(
            new URL(`/app/chrome/downurl?t=${tm}`, this.PRO_API_URL).href,
            data,
            {
              headers: {
                "Content-Type": "application/x-www-form-urlencoded",
                "User-Agent": USER_AGENT_115
              }
            }
          );
          const responseData = response.data;
          this.logger.log("Pro方式响应:", responseData);
          if (!responseData.state) {
            throw new Error(`获取下载地址失败: ${JSON.stringify(responseData)}`);
          }
          const result = JSON.parse(
            this.crypto115.m115_decode(responseData.data, encoded.key)
          );
          const downloadInfo = Object.values(result)[0];
          const fileToken = (_a = response.headers["set-cookie"]) == null ? undefined : _a.split(";")[0];
          return {
            url: downloadInfo.url.url,
            fileToken
          };
        }
        async getFileDownloadUrl(pickcode) {
          try {
            return await this.getDownloadUrlByPro(pickcode);
          } catch (error) {
            console.warn("第一种获取下载链接失败", error);
            this.logger.log("开始使用第二种方式获取下载链接", error);
            const res = await this.getDownloadUrlByNormal(pickcode);
            return res;
          }
        }
        async getOriginFileUrl(pickcode, fileId) {
          const response = await this.iRequest.get(
            new URL(
              `/app/chrome/down?method=get_file_url&pickcode=${pickcode}`,
              this.PRO_API_URL
            ).href,
            {
              headers: {
                "Content-Type": "application/json",
                "User-Agent": USER_AGENT_115
              }
            }
          );
          const res = response.data;
          if (res.state) {
            const url = res.data[fileId].url.url;
            return { url };
          }
          throw new Error(`获取原文件地址失败: ${JSON.stringify(res)}`);
        }
        getM3u8RootUrl(pickcode) {
          return new URL(`/api/video/m3u8/${pickcode}.m3u8`, this.BASE_URL).href;
        }
        async parseM3u8Url(url) {
          var _a;
          const response = await this.iRequest.get(url, {
            headers: {
              "Content-Type": "application/json",
              "User-Agent": USER_AGENT_115
            }
          });
          if (((_a = response.data) == null ? undefined : _a.state) === false) {
            if (response.data.code === 911) {
              this.verify();
            }
            throw new Error(`获取m3u8文件失败: ${response.data.error}`);
          }
          const htmlText = response.data;
          const lines = htmlText.split("\n");
          const m3u8List = [];
          htmlText.split("\n").forEach((line, index) => {
            var _a2, _b;
            if (line.includes('NAME="')) {
              const extXStreamInf = line.match(/#EXT-X-STREAM-INF/);
              if (extXStreamInf) {
                const name = ((_a2 = line.match(/NAME="([^"]*)"/)) == null ? undefined : _a2[1]) ?? "";
                const url2 = (_b = lines[index + 1]) == null ? undefined : _b.trim();
                m3u8List.push({
                  name,
                  quality: qualityCodeMap[name],
                  url: url2
                });
              }
            }
          });
          m3u8List.sort((a, b) => b.quality - a.quality);
          this.logger.log("m3u8List result", m3u8List);
          return m3u8List;
        }
        async apsNatsortFiles(params) {
          const response = await this.iRequest.get(
            new URL("/aps/natsort/files.php", this.VOD_URL_115).href,
            {
              params,
              headers: {
                "Content-Type": "application/json",
                "User-Agent": USER_AGENT_115,
                host: VOD_HOST_155,
                referer: `${this.VOD_URL_115}/?pickcode=${params.pickcode}&share_id=0`
              }
            }
          );
          return response;
        }
        async webapiFiles(params) {
          const response = await this.iRequest.get(
            new URL("/webapi/files", this.VOD_URL_115).href,
            {
              params,
              headers: {
                "Content-Type": "application/json",
                "User-Agent": USER_AGENT_115,
                referer: `${this.VOD_URL_115}/?pickcode=${params.pickcode}&share_id=0`,
                host: VOD_HOST_155
              }
            }
          );
          return response;
        }
        async getPlaylist(cid, pickcode, offset = 0) {
          var _a;
          const obj = {
            pickcode,
            aid: 1,
            cid,
            offset,
            limit: 115,
            show_dir: 0,
            nf: "",
            qid: 0,
            type: 4,
            source: "",
            format: "json",
            star: "",
            is_q: "",
            is_share: "",
            r_all: 1,
            o: "file_name",
            asc: 1,
            cur: 1,
            natsort: 1
          };
          try {
            const response = await this.webapiFiles(obj);
            if (response.data.state) {
              return response.data;
            }
            throw new Error("webapiFiles 获取播放列表失败");
          } catch (error) {
            this.logger.log("获取webapiFiles失败,尝试使用apsNatsortFiles获取");
            const response = await this.apsNatsortFiles(obj);
            if ((_a = response.data) == null ? undefined : _a.state) {
              return response.data;
            }
            throw new Error(`获取播放列表失败: ${JSON.stringify(response)}`);
          }
        }
        async getFileInfo(params) {
          const response = await this.iRequest.get(
            new URL("/webapi/files/video", this.VOD_URL_115).href,
            {
              params,
              headers: {
                "Content-Type": "application/json",
                "User-Agent": USER_AGENT_115,
                referer: `${this.VOD_URL_115}/?pickcode=${params.pickcode}&share_id=0`,
                host: VOD_HOST_155
              }
            }
          );
          return response.data;
        }
      }
      class Drive115GM extends Drive115Core {
        constructor() {
          super(new GMRequest());
        }
      }
      const Drive115Instance = new Drive115GM();
      const logger = new AppLogger("getAvNumber");
      function getAvNumber(filename) {
        const name = filename;
        const cleanName = name.replace(/^\[?[a-zA-Z0-9]+\.[a-zA-Z]+\]?@?/g, "").replace(/\.[^\s]+$/, "").replace(/[\u4E00-\u9FA5]/g, "").replace(/[\u3040-\u309F\u30A0-\u30FF]/g, "");
        logger.log("清理干扰字符", `before:${name} -> after:${cleanName}`);
        const patterns = [
          // FC2系列 (如 FC2-PPV-123456)
          {
            name: "FC2系列",
            pattern: /fc2[^\d]*(?:ppv)?[^\d]*(\d{6,7})/i,
            format: (m) => `FC2-PPV-${m[1]}`
          },
          // HEYZO系列 (如 HEYZO-1234)
          {
            name: "HEYZO系列",
            pattern: /heyzo[^\d]*(\d{4})/i,
            format: (m) => `HEYZO-${m[1]}`
          },
          // 麻豆系列 (如 MDX-0123, MKY-NS-001)
          {
            name: "麻豆系列",
            pattern: /(mdx|mky|md)[^\d]*(?:ns)?[^\d]*(\d{3,4})/i,
            format: (m) => {
              const prefix = m[1].toUpperCase();
              const hasNS = cleanName.toLowerCase().includes("ns");
              return `${prefix}${hasNS ? "-NS" : ""}-${m[2]}`;
            }
          },
          // 一本道系列 or Muramura系列 (如 1pondo-123456_789、muramura-123114_163)
          {
            name: "一本道系列 or Muramura系列",
            pattern: /(\d{6})[\s|_]*(\d{3})/i,
            format: (m) => `${m[1]}_${m[2]}`
          },
          // Pacopacomama or 10musume系列 (如 10musume-123114_01、pacopacomama-123114_01)
          {
            name: "Pacopacomama or 10musume系列",
            pattern: /(\d{6})[\s|_]*(\d{2})/i,
            format: (m) => `${m[1]}_${m[2]}`
          },
          // Heydouga系列 (如 heydouga-4037-123)
          {
            name: "Heydouga系列",
            pattern: /(\d{4})[\s|-]*(\d{3,4})/i,
            format: (m) => `${m[1]}-${m[2]}`
          },
          // 加勒比系列 (如 carib-123-456)
          {
            name: "加勒比系列",
            pattern: /(?:carib|caribbean)[^\d]*(\d{3})[^\d]*(\d{3})/i,
            format: (m) => `CARIB-${m[1]}-${m[2]}`
          },
          // 东京热系列 (如 tokyo-hot-n1234)
          {
            name: "东京热系列",
            pattern: /tokyo[^\d]*hot[^\d]*([a-z])(\d{4})/i,
            format: (m) => `TOKYO-HOT-${m[1].toUpperCase()}${m[2]}`
          },
          // 特殊格式:字母数字混合 (如 T28-123)
          {
            name: "特殊格式:字母数字混合",
            pattern: /([a-zA-Z]+\d{1,2})-(\d{3})/i,
            format: (m) => `${m[1].toUpperCase()}-${m[2]}`
          },
          // 标准格式:字母-数字 (如 ABC-123, ABCD-12345)
          {
            name: "标准格式:字母-数字",
            pattern: /([a-zA-Z]{2,5})-?(\d{2,5})(?:c|-c)?/i,
            format: (m) => {
              return `${m[1].toUpperCase()}-${m[2]}`;
            }
          }
        ];
        for (const { name: name2, pattern, format } of patterns) {
          const match = cleanName.match(pattern);
          if (match) {
            logger.log("match name", name2);
            logger.log("match regexp", pattern.toString());
            const result = format(match);
            return result;
          }
        }
        logger.log("找不到番号");
        return null;
      }
      const isMac = _GM_info.userAgentData.platform.match(/mac/i);
      const GM_VALUE_KEY = {
        PLAYING_VIDEO_INFO: "playingVideoInfo"
      };
      const goToPlayer = (playingVideoInfo, isOpenInTab = false) => {
        _GM_setValue(GM_VALUE_KEY.PLAYING_VIDEO_INFO, playingVideoInfo);
        const params = new URLSearchParams({
          cid: playingVideoInfo.cid || "",
          pick_code: playingVideoInfo.pickCode,
          avNumber: playingVideoInfo.avNumber || "",
          title: playingVideoInfo.title
        });
        const url = `https://${DL_HOST_155}/master/video/?${params.toString()}`;
        if (isOpenInTab) {
          _GM_openInTab(url, {
            active: true
          });
          return;
        }
        history.pushState({}, "", url);
      };
      const webLinkShortcutsMpv = (url) => {
        const shell = {
          bin: "/opt/homebrew/bin/mpv",
          url,
          userAgent: navigator.userAgent
        };
        return `shortcuts://run-shortcut?name=115MasterWebLink&input=text&text=${encodeURIComponent(
    JSON.stringify(shell)
  )}`;
      };
      const webLinkIINA = (url) => {
        return `iina://weblink?url=${encodeURIComponent(url)}&mpv_http-header-fields=${encodeURIComponent(
    `User-Agent: ${navigator.userAgent.replace(",", "\\,")}`
  )}`;
      };
      class FileOperationMenu {
        constructor() {
          this.ContentsMenubuttons = [
            {
              class: "115-player",
              title: "使用【115官方播放器】",
              text: "5️⃣ 官方播放"
            },
            ...isMac ? [
              {
                class: "iina-player",
                title: "使用【iina】",
                text: "🎵 iina 播放"
              }
            ] : [],
            {
              class: "master-player",
              title: "使用【Master播放器】",
              text: "▶️ Master 播放"
            }
          ];
          this.logger = new AppLogger("FileOperationMenu");
          this.init();
        }
        // 初始化
        init() {
          this.logger.log("init");
          this.addFileItemHoverMenu();
        }
        // 添加文件项悬停菜单
        addFileItemHoverMenu() {
          document.addEventListener("mouseover", this.handleMouseOver.bind(this));
        }
        // 处理鼠标悬停事件
        handleMouseOver(event) {
          const target = event.target;
          const listItem = target.closest(
            '.list-cell li[file_type="1"]'
          );
          const isNormalItem = !!target.closest(".list-contents");
          if (!listItem || !this.isValidFileItem(listItem)) return;
          if (listItem.getAttribute("paly_button") === "1") return;
          listItem.setAttribute("paly_button", "1");
          const fileOpr = this.getFileOperationElement(listItem);
          if (fileOpr && isNormalItem) {
            this.createButtons(fileOpr, listItem);
          }
          this.addVideoEventListeners(listItem, isNormalItem);
        }
        // 获取文件操作元素
        getFileOperationElement(item) {
          const listOpr = item.querySelector(".file-opr");
          if (listOpr) return listOpr;
          const thumbOpr = item.querySelector(".file-opt");
          return thumbOpr;
        }
        // 验证文件项是否有效
        isValidFileItem(element) {
          const baseCheck = element.getAttribute("file_type") === "1" && element.getAttribute("file_mode") !== "4" && element.getAttribute("paly_button") !== "1";
          const hasDuration = element.querySelector(".duration") !== null;
          return baseCheck && hasDuration;
        }
        addVideoEventListeners(listItem, isNormalItem) {
          var _a, _b;
          const openVideo = this.createOpenVideoHandler(listItem);
          listItem.addEventListener("dblclick", openVideo);
          listItem.addEventListener("auxclick", (e) => {
            if (e.button === 1) {
              e.preventDefault();
              e.stopPropagation();
              e.stopImmediatePropagation();
              _GM_openInTab(
                new URL(
                  `/?pickcode=${listItem.getAttribute("pick_code")}&share_id=0`,
                  VOD_URL_115
                ).href,
                { active: true }
              );
            }
          });
          (_a = listItem.querySelector(".file-name .name")) == null ? undefined : _a.addEventListener("click", openVideo, true);
          (_b = listItem.querySelector(".file-thumb")) == null ? undefined : _b.addEventListener("click", openVideo, true);
          if (!isNormalItem) {
            const tooltip = document.createElement("div");
            tooltip.className = "video-operation-tooltip";
            tooltip.innerHTML = `
				<div>点击中键<br />官方播放</div>
			`;
            listItem.style.position = "relative";
            listItem.appendChild(tooltip);
            listItem.addEventListener("mouseenter", () => {
              tooltip.classList.add("show");
              setTimeout(() => {
                tooltip.style.opacity = "1";
              }, 0);
            });
            listItem.addEventListener("mouseleave", () => {
              tooltip.classList.remove("show");
              setTimeout(() => {
                tooltip.style.opacity = "0";
              }, 0);
            });
          }
        }
        // 创建打开视频处理函数
        createOpenVideoHandler(listItem) {
          return (event) => {
            event.preventDefault();
            event.stopPropagation();
            event.stopImmediatePropagation();
            const playingVideoInfo = {
              pickCode: listItem.getAttribute("pick_code"),
              title: listItem.getAttribute("title"),
              avNumber: getAvNumber(listItem.getAttribute("title")) || undefined,
              cid: listItem.getAttribute("cid"),
              size: parseInt(listItem.getAttribute("file_size"))
            };
            this.logger.log("即将播放", playingVideoInfo);
            goToPlayer(playingVideoInfo, true);
          };
        }
        // 创建文件操作菜单按钮
        createButtons(fileOpr, listItem) {
          this.ContentsMenubuttons.forEach((button) => {
            const link = this.createNormalItemButtonElement(button);
            fileOpr.prepend(link);
            this.addButtonClickHandler(link, listItem);
          });
        }
        // 创建普通文件项按钮元素
        createNormalItemButtonElement(button) {
          const link = document.createElement("a");
          link.href = "javascript:void(0)";
          link.className = button.class;
          link.title = button.title;
          link.style.cssText = "pointer-events: all; position: relative; z-index: 1000;";
          const span = document.createElement("span");
          span.textContent = button.text;
          span.style.pointerEvents = "none";
          link.appendChild(span);
          return link;
        }
        // 添加按钮点击事件处理函数
        addButtonClickHandler(link, listItem) {
          link.addEventListener("mousedown", async (e) => {
            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();
            if (link.classList.contains("115-player")) {
              _GM_openInTab(
                new URL(
                  `/?pickcode=${listItem.getAttribute("pick_code")}&share_id=0`,
                  VOD_URL_115
                ).href,
                { active: true }
              );
            } else if (link.classList.contains("master-player")) {
              const playingVideoInfo = {
                pickCode: listItem.getAttribute("pick_code"),
                title: listItem.getAttribute("title"),
                avNumber: getAvNumber(listItem.getAttribute("title")) || undefined,
                cid: listItem.getAttribute("cid"),
                size: parseInt(listItem.getAttribute("file_size"))
              };
              goToPlayer(playingVideoInfo, true);
            } else if (link.classList.contains("iina-player")) {
              try {
                const download = await Drive115Instance.getFileDownloadUrl(
                  listItem.getAttribute("pick_code")
                );
                open(webLinkIINA(download.url));
              } catch (error) {
                this.logger.error("打开iina失败", error);
                alert("打开iina失败");
              }
            }
          });
        }
        // 销毁
        destroy() {
          document.removeEventListener("mouseover", this.handleMouseOver.bind(this));
        }
      }
      class HomePage {
        constructor() {
          this.logger = new AppLogger("HomePage");
          this.init();
        }
        init() {
          this.logger.log("init");
          this.fileOperationMenu = new FileOperationMenu();
        }
        destroy() {
          this.fileOperationMenu.destroy();
        }
      }
      function tryOnScopeDispose(fn) {
        if (getCurrentScope()) {
          onScopeDispose(fn);
          return true;
        }
        return false;
      }
      const isClient = typeof window !== "undefined" && typeof document !== "undefined";
      typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
      const notNullish = (val) => val != null;
      const noop = () => {
      };
      function createFilterWrapper(filter, fn) {
        function wrapper(...args) {
          return new Promise((resolve, reject) => {
            Promise.resolve(filter(() => fn.apply(this, args), { fn, thisArg: this, args })).then(resolve).catch(reject);
          });
        }
        return wrapper;
      }
      function throttleFilter(...args) {
        let lastExec = 0;
        let timer;
        let isLeading = true;
        let lastRejector = noop;
        let lastValue;
        let ms;
        let trailing;
        let leading;
        let rejectOnCancel;
        if (!isRef(args[0]) && typeof args[0] === "object")
          ({ delay: ms, trailing = true, leading = true, rejectOnCancel = false } = args[0]);
        else
          [ms, trailing = true, leading = true, rejectOnCancel = false] = args;
        const clear = () => {
          if (timer) {
            clearTimeout(timer);
            timer = undefined;
            lastRejector();
            lastRejector = noop;
          }
        };
        const filter = (_invoke) => {
          const duration2 = toValue(ms);
          const elapsed = Date.now() - lastExec;
          const invoke = () => {
            return lastValue = _invoke();
          };
          clear();
          if (duration2 <= 0) {
            lastExec = Date.now();
            return invoke();
          }
          if (elapsed > duration2 && (leading || !isLeading)) {
            lastExec = Date.now();
            invoke();
          } else if (trailing) {
            lastValue = new Promise((resolve, reject) => {
              lastRejector = rejectOnCancel ? reject : resolve;
              timer = setTimeout(() => {
                lastExec = Date.now();
                isLeading = true;
                resolve(invoke());
                clear();
              }, Math.max(0, duration2 - elapsed));
            });
          }
          if (!leading && !timer)
            timer = setTimeout(() => isLeading = true, duration2);
          isLeading = false;
          return lastValue;
        };
        return filter;
      }
      function promiseTimeout(ms, throwOnTimeout = false, reason = "Timeout") {
        return new Promise((resolve, reject) => {
          if (throwOnTimeout)
            setTimeout(() => reject(reason), ms);
          else
            setTimeout(resolve, ms);
        });
      }
      function getLifeCycleTarget(target) {
        return getCurrentInstance();
      }
      function toArray(value) {
        return Array.isArray(value) ? value : [value];
      }
      function toRef(...args) {
        if (args.length !== 1)
          return toRef$1(...args);
        const r = args[0];
        return typeof r === "function" ? readonly(customRef(() => ({ get: r, set: noop }))) : ref(r);
      }
      function useThrottleFn(fn, ms = 200, trailing = false, leading = true, rejectOnCancel = false) {
        return createFilterWrapper(
          throttleFilter(ms, trailing, leading, rejectOnCancel),
          fn
        );
      }
      function tryOnUnmounted(fn, target) {
        const instance = getLifeCycleTarget();
        if (instance)
          onUnmounted(fn, target);
      }
      function createUntil(r, isNot = false) {
        function toMatch(condition, { flush = "sync", deep = false, timeout, throwOnTimeout } = {}) {
          let stop = null;
          const watcher = new Promise((resolve) => {
            stop = watch(
              r,
              (v) => {
                if (condition(v) !== isNot) {
                  if (stop)
                    stop();
                  else
                    nextTick(() => stop == null ? undefined : stop());
                  resolve(v);
                }
              },
              {
                flush,
                deep,
                immediate: true
              }
            );
          });
          const promises = [watcher];
          if (timeout != null) {
            promises.push(
              promiseTimeout(timeout, throwOnTimeout).then(() => toValue(r)).finally(() => stop == null ? undefined : stop())
            );
          }
          return Promise.race(promises);
        }
        function toBe(value, options) {
          if (!isRef(value))
            return toMatch((v) => v === value, options);
          const { flush = "sync", deep = false, timeout, throwOnTimeout } = options != null ? options : {};
          let stop = null;
          const watcher = new Promise((resolve) => {
            stop = watch(
              [r, value],
              ([v1, v2]) => {
                if (isNot !== (v1 === v2)) {
                  if (stop)
                    stop();
                  else
                    nextTick(() => stop == null ? undefined : stop());
                  resolve(v1);
                }
              },
              {
                flush,
                deep,
                immediate: true
              }
            );
          });
          const promises = [watcher];
          if (timeout != null) {
            promises.push(
              promiseTimeout(timeout, throwOnTimeout).then(() => toValue(r)).finally(() => {
                stop == null ? undefined : stop();
                return toValue(r);
              })
            );
          }
          return Promise.race(promises);
        }
        function toBeTruthy(options) {
          return toMatch((v) => Boolean(v), options);
        }
        function toBeNull(options) {
          return toBe(null, options);
        }
        function toBeUndefined(options) {
          return toBe(undefined, options);
        }
        function toBeNaN(options) {
          return toMatch(Number.isNaN, options);
        }
        function toContains(value, options) {
          return toMatch((v) => {
            const array = Array.from(v);
            return array.includes(value) || array.includes(toValue(value));
          }, options);
        }
        function changed(options) {
          return changedTimes(1, options);
        }
        function changedTimes(n = 1, options) {
          let count = -1;
          return toMatch(() => {
            count += 1;
            return count >= n;
          }, options);
        }
        if (Array.isArray(toValue(r))) {
          const instance = {
            toMatch,
            toContains,
            changed,
            changedTimes,
            get not() {
              return createUntil(r, !isNot);
            }
          };
          return instance;
        } else {
          const instance = {
            toMatch,
            toBe,
            toBeTruthy,
            toBeNull,
            toBeNaN,
            toBeUndefined,
            changed,
            changedTimes,
            get not() {
              return createUntil(r, !isNot);
            }
          };
          return instance;
        }
      }
      function until(r) {
        return createUntil(r);
      }
      const defaultWindow = isClient ? window : undefined;
      const defaultDocument = isClient ? window.document : undefined;
      function unrefElement(elRef) {
        var _a;
        const plain = toValue(elRef);
        return (_a = plain == null ? undefined : plain.$el) != null ? _a : plain;
      }
      function useMounted() {
        const isMounted = shallowRef(false);
        const instance = getCurrentInstance();
        if (instance) {
          onMounted(() => {
            isMounted.value = true;
          }, instance);
        }
        return isMounted;
      }
      function useSupported(callback) {
        const isMounted = useMounted();
        return computed(() => {
          isMounted.value;
          return Boolean(callback());
        });
      }
      function useMutationObserver(target, callback, options = {}) {
        const { window: window2 = defaultWindow, ...mutationOptions } = options;
        let observer;
        const isSupported = useSupported(() => window2 && "MutationObserver" in window2);
        const cleanup = () => {
          if (observer) {
            observer.disconnect();
            observer = undefined;
          }
        };
        const targets = computed(() => {
          const value = toValue(target);
          const items = toArray(value).map(unrefElement).filter(notNullish);
          return new Set(items);
        });
        const stopWatch = watch(
          () => targets.value,
          (targets2) => {
            cleanup();
            if (isSupported.value && targets2.size) {
              observer = new MutationObserver(callback);
              targets2.forEach((el) => observer.observe(el, mutationOptions));
            }
          },
          { immediate: true, flush: "post" }
        );
        const takeRecords = () => {
          return observer == null ? undefined : observer.takeRecords();
        };
        const stop = () => {
          stopWatch();
          cleanup();
        };
        tryOnScopeDispose(stop);
        return {
          isSupported,
          stop,
          takeRecords
        };
      }
      function useAsyncState(promise, initialState, options) {
        const {
          immediate = true,
          delay = 0,
          onError = noop,
          onSuccess = noop,
          resetOnExecute = true,
          shallow = true,
          throwError
        } = options != null ? options : {};
        const state = shallow ? shallowRef(initialState) : ref(initialState);
        const isReady = shallowRef(false);
        const isLoading = shallowRef(false);
        const error = shallowRef(undefined);
        async function execute(delay2 = 0, ...args) {
          if (resetOnExecute)
            state.value = initialState;
          error.value = undefined;
          isReady.value = false;
          isLoading.value = true;
          if (delay2 > 0)
            await promiseTimeout(delay2);
          const _promise = typeof promise === "function" ? promise(...args) : promise;
          try {
            const data = await _promise;
            state.value = data;
            isReady.value = true;
            onSuccess(data);
          } catch (e) {
            error.value = e;
            onError(e);
            if (throwError)
              throw e;
          } finally {
            isLoading.value = false;
          }
          return state.value;
        }
        if (immediate) {
          execute(delay);
        }
        const shell = {
          state,
          isReady,
          isLoading,
          error,
          execute
        };
        function waitUntilIsLoaded() {
          return new Promise((resolve, reject) => {
            until(isLoading).toBe(false).then(() => resolve(shell)).catch(reject);
          });
        }
        return {
          ...shell,
          then(onFulfilled, onRejected) {
            return waitUntilIsLoaded().then(onFulfilled, onRejected);
          }
        };
      }
      function useTitle(newTitle = null, options = {}) {
        var _a, _b, _c;
        const {
          document: document2 = defaultDocument,
          restoreOnUnmount = (t) => t
        } = options;
        const originalTitle = (_a = document2 == null ? undefined : document2.title) != null ? _a : "";
        const title = toRef((_b = newTitle != null ? newTitle : document2 == null ? undefined : document2.title) != null ? _b : null);
        const isReadonly2 = !!(newTitle && typeof newTitle === "function");
        function format(t) {
          if (!("titleTemplate" in options))
            return t;
          const template = options.titleTemplate || "%s";
          return typeof template === "function" ? template(t) : toValue(template).replace(/%s/g, t);
        }
        watch(
          title,
          (newValue, oldValue) => {
            if (newValue !== oldValue && document2)
              document2.title = format(newValue != null ? newValue : "");
          },
          { immediate: true }
        );
        if (options.observe && !options.titleTemplate && document2 && !isReadonly2) {
          useMutationObserver(
            (_c = document2.head) == null ? undefined : _c.querySelector("title"),
            () => {
              if (document2 && document2.title !== title.value)
                title.value = format(document2.title);
            },
            { childList: true }
          );
        }
        tryOnScopeDispose(() => {
          if (restoreOnUnmount) {
            const restoredTitle = restoreOnUnmount(originalTitle, title.value || "");
            if (restoredTitle != null && document2)
              document2.title = restoredTitle;
          }
        });
        return title;
      }
      const useControls = () => {
        const visible = ref(true);
        const isMouseInControls = ref(false);
        const isMouseInMenu = ref(false);
        let hideControlsTimer = null;
        const setIsMouseInControls = (value) => {
          isMouseInControls.value = value;
          if (value) {
            hideControlsTimer = null;
          }
        };
        const setIsMouseInMenu = (value) => {
          isMouseInMenu.value = value;
        };
        const show = () => {
          visible.value = true;
        };
        const hide = () => {
          visible.value = false;
        };
        const clearHideControlsTimer = () => {
          if (hideControlsTimer) {
            clearTimeout(hideControlsTimer);
            hideControlsTimer = null;
          }
        };
        const showWithAutoHide = () => {
          show();
          hideWithDelay();
        };
        const hideWithDelay = () => {
          clearHideControlsTimer();
          hideControlsTimer = window.setTimeout(() => {
            if (isMouseInControls.value || isMouseInMenu.value) {
              return;
            }
            hide();
          }, 1e3);
        };
        return {
          visible,
          show,
          hide,
          showWithAutoHide,
          hideWithDelay,
          clearHideControlsTimer,
          setIsMouseInControls,
          setIsMouseInMenu
        };
      };
      function useFullscreen() {
        const isFullscreen = ref(false);
        const handleFullscreenChange = () => {
          isFullscreen.value = !!document.fullscreenElement;
        };
        onMounted(() => {
          document.addEventListener("fullscreenchange", handleFullscreenChange);
          document.addEventListener("webkitfullscreenchange", handleFullscreenChange);
          document.addEventListener("mozfullscreenchange", handleFullscreenChange);
          document.addEventListener("MSFullscreenChange", handleFullscreenChange);
        });
        onUnmounted(() => {
          document.removeEventListener("fullscreenchange", handleFullscreenChange);
          document.removeEventListener(
            "webkitfullscreenchange",
            handleFullscreenChange
          );
          document.removeEventListener("mozfullscreenchange", handleFullscreenChange);
          document.removeEventListener("MSFullscreenChange", handleFullscreenChange);
        });
        const toggleFullscreen = async () => {
          try {
            if (!document.fullscreenElement) {
              window.scrollTo(0, 0);
              await document.documentElement.requestFullscreen();
            } else {
              await document.exitFullscreen();
            }
          } catch (error) {
            console.error("Failed to toggle fullscreen:", error);
          }
        };
        return {
          isFullscreen,
          toggleFullscreen
        };
      }
      function useHotKey({
        togglePlay,
        skip,
        adjustVolume
      }) {
        const handleKeydown = (event) => {
          if (event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement) {
            return;
          }
          switch (event.code) {
            // 空格键
            case "Space":
              event.preventDefault();
              togglePlay();
              break;
            // 左箭头
            case "ArrowLeft":
              event.preventDefault();
              skip(-5);
              break;
            // 右箭头
            case "ArrowRight":
              event.preventDefault();
              skip(5);
              console.log("右箭头");
              break;
            // 上箭头
            case "ArrowUp":
              event.preventDefault();
              adjustVolume(5);
              break;
            // 下箭头
            case "ArrowDown":
              event.preventDefault();
              adjustVolume(-5);
              break;
          }
        };
        onMounted(() => {
          document.addEventListener("keydown", handleKeydown);
        });
        onUnmounted(() => {
          document.removeEventListener("keydown", handleKeydown);
        });
      }
      const usePlaybackRate = (videoElementRef) => {
        const playbackRate = ref(1);
        const setPlaybackRate = (rate) => {
          if (!videoElementRef.value) return;
          videoElementRef.value.playbackRate = rate;
          playbackRate.value = rate;
        };
        return {
          playbackRate,
          setPlaybackRate
        };
      };
      const usePlaying = (videoElementRef) => {
        const isPlaying = ref(false);
        const autoplay = ref(false);
        const loop = ref(false);
        const isLoading = ref(false);
        const updatePlayingState = () => {
          if (!videoElementRef.value) return;
          isPlaying.value = !videoElementRef.value.paused;
        };
        const togglePlay = async () => {
          if (!videoElementRef.value) return;
          try {
            if (videoElementRef.value.paused) {
              await videoElementRef.value.play();
            } else {
              videoElementRef.value.pause();
            }
          } catch (error) {
            console.error("Failed to toggle play state:", error);
          }
        };
        const showLoading = () => {
          isLoading.value = true;
        };
        const cancelLoading = () => {
          isLoading.value = false;
        };
        watch(videoElementRef, () => {
          if (!videoElementRef.value) return;
          showLoading();
          videoElementRef.value.addEventListener("play", updatePlayingState);
          videoElementRef.value.addEventListener("pause", updatePlayingState);
          videoElementRef.value.addEventListener("playing", updatePlayingState);
          videoElementRef.value.addEventListener("ended", updatePlayingState);
          videoElementRef.value.addEventListener("waiting", showLoading);
          videoElementRef.value.addEventListener("canplay", cancelLoading);
        });
        onUnmounted(() => {
          if (!videoElementRef.value) return;
          videoElementRef.value.removeEventListener("play", updatePlayingState);
          videoElementRef.value.removeEventListener("pause", updatePlayingState);
          videoElementRef.value.removeEventListener("playing", updatePlayingState);
          videoElementRef.value.removeEventListener("ended", updatePlayingState);
          videoElementRef.value.removeEventListener("waiting", showLoading);
          videoElementRef.value.removeEventListener("canplay", cancelLoading);
        });
        return {
          loop,
          autoplay,
          isPlaying,
          isLoading,
          togglePlay
        };
      };
      const useProgress = (videoElementRef) => {
        const currentTime = ref(0);
        const duration2 = ref(0);
        const buffered = ref(0);
        const progress = ref(0);
        const seekTo = (time) => {
          if (!videoElementRef.value) return;
          currentTime.value = time;
          progress.value = time / duration2.value * 100;
          videoElementRef.value.currentTime = time;
        };
        const updateProgress = () => {
          if (!videoElementRef.value) return;
          currentTime.value = videoElementRef.value.currentTime;
          duration2.value = videoElementRef.value.duration;
          progress.value = currentTime.value / duration2.value * 100;
        };
        const updateBuffer = () => {
          if (!videoElementRef.value) return;
          const timeRanges = videoElementRef.value.buffered;
          if (timeRanges.length > 0) {
            buffered.value = timeRanges.end(timeRanges.length - 1) / videoElementRef.value.duration * 100;
          }
        };
        const skip = (seconds) => {
          if (!videoElementRef.value) return;
          const newTime = currentTime.value + seconds;
          const clampedTime = Math.min(Math.max(0, newTime), duration2.value);
          seekTo(clampedTime);
        };
        watch(videoElementRef, () => {
          if (!videoElementRef.value) return;
          videoElementRef.value.addEventListener("timeupdate", updateProgress);
          videoElementRef.value.addEventListener("loadedmetadata", updateProgress);
          videoElementRef.value.addEventListener("progress", updateBuffer);
        });
        onUnmounted(() => {
          if (!videoElementRef.value) return;
          videoElementRef.value.removeEventListener("timeupdate", updateProgress);
          videoElementRef.value.removeEventListener("loadedmetadata", updateProgress);
          videoElementRef.value.removeEventListener("progress", updateBuffer);
        });
        return {
          currentTime,
          duration: duration2,
          buffered,
          progress,
          seekTo,
          skip
        };
      };
      function useHls(videoElement) {
        const instance = shallowRef(null);
        const isSupported = Hls.isSupported();
        const initHls = (url, config = {}) => {
          if (!isSupported) {
            console.warn("HLS is not supported in this browser");
            return false;
          }
          if (!videoElement.value) {
            console.warn("videoElement is null");
            return false;
          }
          instance.value = new Hls({
            autoStartLoad: true,
            startPosition: -1,
            debug: false,
            ...config
          });
          instance.value.loadSource(url);
          instance.value.attachMedia(videoElement.value);
          return true;
        };
        const destroy = () => {
          if (instance.value) {
            instance.value.destroy();
            instance.value = null;
          }
        };
        return {
          instance,
          isSupported,
          initHls,
          destroy
        };
      }
      const useSource = (videoElementRef, sources) => {
        const list = sources;
        const current = ref(null);
        const videoKey = computed(() => {
          var _a;
          return (_a = current.value) == null ? undefined : _a.url;
        });
        const hls = useHls(videoElementRef);
        const cleanupRef = ref(() => undefined);
        const isInterrupt = ref(false);
        const initializeVideo = async (source) => {
          current.value = source;
          await nextTick();
          if (!videoElementRef.value) return;
          if (videoElementRef.value.src) {
            videoElementRef.value.src = "";
          }
          if (source.type === "hls") {
            hls.initHls(source.url, source.hlsConfig);
          } else {
            videoElementRef.value.src = source.url;
            videoElementRef.value.load();
            videoElementRef.value.play();
          }
          return () => {
            if (videoElementRef.value) {
              videoElementRef.value.src = "";
              hls.destroy();
            }
          };
        };
        const changeQuality = async (source) => {
          var _a, _b, _c;
          const currentTime = ((_a = videoElementRef.value) == null ? undefined : _a.currentTime) || 0;
          const wasPlaying = !((_b = videoElementRef.value) == null ? undefined : _b.paused);
          (_c = cleanupRef.value) == null ? undefined : _c.call(cleanupRef);
          cleanupRef.value = await initializeVideo(source);
          if (videoElementRef.value) {
            videoElementRef.value.currentTime = currentTime;
            if (wasPlaying) {
              videoElementRef.value.play();
            }
          }
        };
        const interruptSource = () => {
          var _a;
          isInterrupt.value = true;
          (_a = cleanupRef.value) == null ? undefined : _a.call(cleanupRef);
        };
        const resumeSource = () => {
          isInterrupt.value = false;
          initializeVideo(current.value);
        };
        watch(
          list,
          async () => {
            var _a;
            (_a = cleanupRef.value) == null ? undefined : _a.call(cleanupRef);
            isInterrupt.value = false;
            if (sources.value.length === 0) {
              return;
            }
            cleanupRef.value = await initializeVideo(list.value[0]);
          },
          { immediate: true, deep: true }
        );
        return {
          videoKey,
          list,
          current,
          changeQuality,
          interruptSource,
          resumeSource,
          isInterrupt
        };
      };
      const useSubtitles = (videoElementRef, subtitles, loadingSubtitles, onSubtitleChange) => {
        const current = ref(null);
        const changeTrack = (subtitle) => {
          var _a, _b;
          const tracks = (_a = videoElementRef.value) == null ? undefined : _a.textTracks;
          if (tracks) {
            for (let i2 = 0; i2 < tracks.length; i2++) {
              tracks[i2].mode = "disabled";
            }
            if (subtitle) {
              const index = ((_b = subtitles.value) == null ? undefined : _b.findIndex((s) => s.url === subtitle.url)) ?? -1;
              if (index >= 0 && tracks[index]) {
                tracks[index].mode = "showing";
              }
            }
          }
        };
        const change = (subtitle) => {
          current.value = subtitle;
          changeTrack(subtitle);
          onSubtitleChange == null ? undefined : onSubtitleChange(subtitle);
        };
        const setDefaultSubtitle = (subtitles2) => {
          const defaultSubtitle = subtitles2.find((s) => s.default);
          if (defaultSubtitle) {
            change(defaultSubtitle);
          }
        };
        const restoreCurrentSubtitle = () => {
          if (current.value) {
            change(current.value);
          }
        };
        watch(subtitles, (newSubtitles) => {
          if (newSubtitles) {
            setDefaultSubtitle(newSubtitles);
          }
        });
        return {
          list: subtitles,
          current,
          change,
          loadingSubtitles,
          restoreCurrentSubtitle
        };
      };
      const useVolume = (videoElementRef) => {
        const volume = ref(100);
        const isMuted = ref(false);
        const setVolume = (value) => {
          if (!videoElementRef.value) return;
          videoElementRef.value.volume = value / 100;
          volume.value = value;
          isMuted.value = value === 0;
        };
        const toggleMute = () => {
          if (!videoElementRef.value) return;
          videoElementRef.value.muted = !videoElementRef.value.muted;
          isMuted.value = videoElementRef.value.muted;
          if (videoElementRef.value.muted) {
            volume.value = 0;
          } else {
            volume.value = videoElementRef.value.volume * 100;
          }
        };
        const adjustVolume = (delta) => {
          if (!videoElementRef.value) return;
          const newVolume = Math.min(Math.max(0, volume.value + delta), 100);
          setVolume(newVolume);
        };
        return {
          volume,
          isMuted,
          setVolume,
          toggleMute,
          adjustVolume
        };
      };
      const PlayerSymbol = Symbol("VideoPlayer");
      function useVideoPlayer(videoElementRef, rootProps) {
        const volume = useVolume(videoElementRef);
        const playbackRate = usePlaybackRate(videoElementRef);
        const fullscreen = useFullscreen();
        const progress = useProgress(videoElementRef);
        const playing = usePlaying(videoElementRef);
        const controls = useControls();
        const subtitles = useSubtitles(
          videoElementRef,
          rootProps.subtitles,
          rootProps.loadingSubtitles,
          rootProps.onSubtitleChange
        );
        const source = useSource(videoElementRef, rootProps.sources);
        useHotKey({
          togglePlay: playing.togglePlay,
          skip: progress.skip,
          adjustVolume: volume.adjustVolume
        });
        const context = {
          rootProps,
          fullscreen,
          volume,
          playbackRate,
          progress,
          playing,
          controls,
          subtitles,
          source,
          refs: {
            videoElementRef
          }
        };
        provide(PlayerSymbol, context);
        return context;
      }
      function usePlayerContext() {
        const context = inject(PlayerSymbol);
        if (!context) {
          throw new Error(
            "usePlayerContext must be used within a VideoPlayer component"
          );
        }
        return context;
      }
      const _hoisted_1$u = {
        xmlns: "http://www.w3.org/2000/svg",
        width: "48",
        height: "48",
        viewBox: "0 -960 960 960"
      };
      function render$8(_ctx, _cache) {
        return openBlock(), createElementBlock("svg", _hoisted_1$u, _cache[0] || (_cache[0] = [
          createElementVNode("path", { d: "M180-180h103q12.75 0 21.38 8.68 8.62 8.67 8.62 21.5 0 12.82-8.62 21.32-8.63 8.5-21.38 8.5H150q-12.75 0-21.37-8.63Q120-137.25 120-150v-133q0-12.75 8.68-21.38 8.67-8.62 21.5-8.62 12.82 0 21.32 8.62 8.5 8.63 8.5 21.38zm600 0v-103q0-12.75 8.68-21.38 8.67-8.62 21.5-8.62 12.82 0 21.32 8.62 8.5 8.63 8.5 21.38v133q0 12.75-8.62 21.37Q822.75-120 810-120H677q-12.75 0-21.37-8.68-8.63-8.67-8.63-21.5 0-12.82 8.63-21.32 8.62-8.5 21.37-8.5zM180-780v103q0 12.75-8.68 21.37-8.67 8.63-21.5 8.63-12.82 0-21.32-8.63-8.5-8.62-8.5-21.37v-133q0-12.75 8.63-21.38Q137.25-840 150-840h133q12.75 0 21.38 8.68 8.62 8.67 8.62 21.5 0 12.82-8.62 21.32-8.63 8.5-21.38 8.5zm600 0H677q-12.75 0-21.37-8.68-8.63-8.67-8.63-21.5 0-12.82 8.63-21.32 8.62-8.5 21.37-8.5h133q12.75 0 21.38 8.62Q840-822.75 840-810v133q0 12.75-8.68 21.37-8.67 8.63-21.5 8.63-12.82 0-21.32-8.63-8.5-8.62-8.5-21.37z" }, null, -1)
        ]));
      }
      const Fullscreen = { render: render$8 };
      const _hoisted_1$t = {
        xmlns: "http://www.w3.org/2000/svg",
        width: "48",
        height: "48",
        viewBox: "0 -960 960 960"
      };
      function render$7(_ctx, _cache) {
        return openBlock(), createElementBlock("svg", _hoisted_1$t, _cache[0] || (_cache[0] = [
          createElementVNode("path", { d: "M253-253H150q-12.75 0-21.37-8.68-8.63-8.67-8.63-21.5 0-12.82 8.63-21.32 8.62-8.5 21.37-8.5h133q12.75 0 21.38 8.62Q313-295.75 313-283v133q0 12.75-8.68 21.37-8.67 8.63-21.5 8.63-12.82 0-21.32-8.63-8.5-8.62-8.5-21.37zm454 0v103q0 12.75-8.68 21.37-8.67 8.63-21.5 8.63-12.82 0-21.32-8.63-8.5-8.62-8.5-21.37v-133q0-12.75 8.63-21.38Q664.25-313 677-313h133q12.75 0 21.38 8.68 8.62 8.67 8.62 21.5 0 12.82-8.62 21.32-8.63 8.5-21.38 8.5zM253-707v-103q0-12.75 8.68-21.38 8.67-8.62 21.5-8.62 12.82 0 21.32 8.62 8.5 8.63 8.5 21.38v133q0 12.75-8.62 21.37Q295.75-647 283-647H150q-12.75 0-21.37-8.68-8.63-8.67-8.63-21.5 0-12.82 8.63-21.32 8.62-8.5 21.37-8.5zm454 0h103q12.75 0 21.38 8.68 8.62 8.67 8.62 21.5 0 12.82-8.62 21.32-8.63 8.5-21.38 8.5H677q-12.75 0-21.37-8.63Q647-664.25 647-677v-133q0-12.75 8.68-21.38 8.67-8.62 21.5-8.62 12.82 0 21.32 8.62 8.5 8.63 8.5 21.38z" }, null, -1)
        ]));
      }
      const FullscreenExit = { render: render$7 };
      const _sfc_main$r = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          svg: {},
          size: {},
          color: {}
        },
        setup(__props) {
          return (_ctx, _cache) => {
            return openBlock(), createBlock(resolveDynamicComponent(_ctx.svg), {
              class: "icon",
              style: normalizeStyle({ width: _ctx.size, height: _ctx.size, color: _ctx.color })
            }, null, 8, ["style"]);
          };
        }
      });
      const _export_sfc = (sfc, props) => {
        const target = sfc.__vccOpts || sfc;
        for (const [key, val] of props) {
          target[key] = val;
        }
        return target;
      };
      const Icon = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-6e980ff6"]]);
      const _sfc_main$q = /* @__PURE__ */ defineComponent({
        __name: "FullscreenButton",
        setup(__props) {
          const { fullscreen } = usePlayerContext();
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("button", {
              onClick: _cache[0] || (_cache[0] = //@ts-ignore
              (...args) => unref(fullscreen).toggleFullscreen && unref(fullscreen).toggleFullscreen(...args))
            }, [
              createVNode(Icon, {
                svg: unref(fullscreen).isFullscreen.value ? unref(FullscreenExit) : unref(Fullscreen),
                class: "icon"
              }, null, 8, ["svg"])
            ]);
          };
        }
      });
      const _hoisted_1$s = {
        xmlns: "http://www.w3.org/2000/svg",
        width: "48",
        height: "48",
        viewBox: "0 -960 960 960"
      };
      function render$6(_ctx, _cache) {
        return openBlock(), createElementBlock("svg", _hoisted_1$s, _cache[0] || (_cache[0] = [
          createElementVNode("path", { d: "M585-200q-24.75 0-42.37-17.63Q525-235.25 525-260v-440q0-24.75 17.63-42.38Q560.25-760 585-760h115q24.75 0 42.38 17.62Q760-724.75 760-700v440q0 24.75-17.62 42.37Q724.75-200 700-200zm-325 0q-24.75 0-42.37-17.63Q200-235.25 200-260v-440q0-24.75 17.63-42.38Q235.25-760 260-760h115q24.75 0 42.38 17.62Q435-724.75 435-700v440q0 24.75-17.62 42.37Q399.75-200 375-200zm325-60h115v-440H585zm-325 0h115v-440H260zm0-440v440zm325 0v440z" }, null, -1)
        ]));
      }
      const Pause = { render: render$6 };
      const _hoisted_1$r = {
        xmlns: "http://www.w3.org/2000/svg",
        width: "48",
        height: "48",
        viewBox: "0 -960 960 960"
      };
      function render$5(_ctx, _cache) {
        return openBlock(), createElementBlock("svg", _hoisted_1$r, _cache[0] || (_cache[0] = [
          createElementVNode("path", { d: "M320-258v-450q0-14 9.07-22 9.06-8 21.15-8 3.78 0 7.91 1 4.12 1 7.87 3l354 226q7 5 10.5 11t3.5 14-3.5 14-10.5 11L366-232q-3.78 2-7.95 3-4.16 1-7.94 1-12.11 0-21.11-8t-9-22m60-54 269-171-269-171z" }, null, -1)
        ]));
      }
      const Play = { render: render$5 };
      const _sfc_main$p = /* @__PURE__ */ defineComponent({
        __name: "PlayButton",
        setup(__props) {
          const { playing } = usePlayerContext();
          const icon = computed(() => {
            return playing.isPlaying.value ? Pause : Play;
          });
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("button", {
              onClick: _cache[0] || (_cache[0] = //@ts-ignore
              (...args) => unref(playing).togglePlay && unref(playing).togglePlay(...args))
            }, [
              createVNode(Icon, {
                svg: icon.value,
                class: "icon"
              }, null, 8, ["svg"])
            ]);
          };
        }
      });
      const PlayButton = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-abf1332f"]]);
      const fillZero = (value) => {
        return value.toString().padStart(2, "0");
      };
      const formatTime = (seconds) => {
        if (Number.isNaN(seconds)) {
          return "--:--";
        }
        const hours = Math.floor(seconds / 3600);
        const minutes = Math.floor(seconds % 3600 / 60);
        const remainingSeconds = Math.floor(seconds % 60);
        return `${hours > 0 ? `${fillZero(hours)}:` : ""}${fillZero(minutes)}:${fillZero(remainingSeconds)}`;
      };
      const _sfc_main$o = {};
      const _hoisted_1$q = { class: "loading-container" };
      function _sfc_render(_ctx, _cache) {
        return openBlock(), createElementBlock("div", _hoisted_1$q, _cache[0] || (_cache[0] = [
          createStaticVNode('<div class="loading-backdrop" data-v-54976e1d></div><div class="loading-effect" data-v-54976e1d><div class="loader" data-v-54976e1d><div class="loader-ring outer" data-v-54976e1d></div><div class="loader-ring inner" data-v-54976e1d></div></div></div>', 2)
        ]));
      }
      const Loading$1 = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["render", _sfc_render], ["__scopeId", "data-v-54976e1d"]]);
      const _hoisted_1$p = { class: "thumbnail-container" };
      const _hoisted_2$f = ["width", "height"];
      const _hoisted_3$e = { class: "thumbnail-loading" };
      const _hoisted_4$9 = { class: "time-tooltip" };
      const DEFAULT_WIDTH = 320;
      const DEFAULT_HEIGHT = 180;
      const _sfc_main$n = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          visible: { type: Boolean },
          position: {},
          time: {},
          progressBarWidth: {}
        },
        setup(__props) {
          const props = __props;
          const { rootProps, source } = usePlayerContext();
          const { onThumbnailRequest } = rootProps;
          const thumbnailCanvas = ref(null);
          const ctx = computed(() => {
            var _a;
            return (_a = thumbnailCanvas.value) == null ? undefined : _a.getContext("2d");
          });
          const width = ref(DEFAULT_WIDTH);
          const height = ref(DEFAULT_HEIGHT);
          const thumb = reactive({
            lastHoverTime: -1,
            lastRequestTime: -1,
            renderTime: -1,
            renderImage: null
          });
          const loading = computed(
            () => thumb.lastRequestTime >= 0 && thumb.lastRequestTime === thumb.lastHoverTime
          );
          const previewTransform = computed(() => {
            if (!thumbnailCanvas.value) return -(width.value / 2);
            const thumbnailWidth = width.value;
            const centerOffset = props.progressBarWidth * (props.position / 100);
            if (centerOffset < thumbnailWidth / 2) {
              return -centerOffset;
            }
            if (centerOffset > props.progressBarWidth - thumbnailWidth / 2) {
              return -(thumbnailWidth - (props.progressBarWidth - centerOffset));
            }
            return -(thumbnailWidth / 2);
          });
          const lastTimer = ref(null);
          const updateThumbnail = async (hoverTime, isLast) => {
            if (lastTimer.value) {
              clearTimeout(lastTimer.value);
              lastTimer.value = null;
            }
            thumb.renderImage = null;
            if (!isLast) {
              lastTimer.value = setTimeout(() => {
                if (hoverTime === thumb.lastHoverTime) {
                  updateThumbnail(hoverTime, true);
                }
              }, 300);
            }
            const cacheImage = await onThumbnailRequest({
              type: "Cache",
              time: hoverTime,
              isLast
            });
            if (cacheImage) {
              thumb.renderImage = cacheImage;
              thumb.renderTime = hoverTime;
              if (isLast) {
                thumb.lastRequestTime = -1;
              }
              return;
            }
            thumb.lastRequestTime = hoverTime;
            const newImage = await onThumbnailRequest({
              type: "Must",
              time: hoverTime,
              isLast
            });
            if (!newImage) return;
            if (hoverTime === thumb.lastHoverTime && isLast) {
              thumb.lastRequestTime = -1;
              thumb.renderImage = newImage;
              thumb.renderTime = hoverTime;
            }
          };
          watch(
            () => [props.visible, props.time],
            async () => {
              if (!onThumbnailRequest) return;
              if (!props.visible || !props.time) {
                thumb.lastHoverTime = -1;
                thumb.renderImage = null;
                return;
              }
              const hoverTime = props.time;
              thumb.lastHoverTime = hoverTime;
              await updateThumbnail(hoverTime, false);
            }
          );
          watch(
            () => thumb.renderImage,
            (newVal, oldVal) => {
              if (thumbnailCanvas.value && ctx.value) {
                width.value = (newVal == null ? undefined : newVal.width) ?? (oldVal == null ? undefined : oldVal.width) ?? DEFAULT_WIDTH;
                height.value = (newVal == null ? undefined : newVal.height) ?? (oldVal == null ? undefined : oldVal.height) ?? DEFAULT_HEIGHT;
                requestAnimationFrame(() => {
                  ctx.value.fillRect(0, 0, width.value, height.value);
                  if (newVal && thumb.renderTime === thumb.lastHoverTime) {
                    ctx.value.drawImage(newVal, 0, 0, width.value, height.value);
                  }
                });
              }
            }
          );
          watch([source.list], () => {
            thumb.lastHoverTime = -1;
            thumb.lastRequestTime = -1;
            thumb.renderTime = -1;
            thumb.renderImage = null;
            if (lastTimer.value) {
              clearTimeout(lastTimer.value);
              lastTimer.value = null;
            }
          });
          onUnmounted(() => {
            if (lastTimer.value) {
              clearTimeout(lastTimer.value);
              lastTimer.value = null;
            }
          });
          return (_ctx, _cache) => {
            return withDirectives((openBlock(), createElementBlock("div", {
              class: "preview-container",
              style: normalizeStyle({
                left: `${_ctx.position}%`,
                transform: `translateX(${previewTransform.value}px)`
              })
            }, [
              createElementVNode("div", _hoisted_1$p, [
                createElementVNode("canvas", {
                  ref_key: "thumbnailCanvas",
                  ref: thumbnailCanvas,
                  width: width.value,
                  height: height.value
                }, null, 8, _hoisted_2$f),
                withDirectives(createElementVNode("div", _hoisted_3$e, [
                  createVNode(Loading$1)
                ], 512), [
                  [vShow, loading.value]
                ])
              ]),
              createElementVNode("div", _hoisted_4$9, toDisplayString(unref(formatTime)(_ctx.time)), 1)
            ], 4)), [
              [vShow, _ctx.visible]
            ]);
          };
        }
      });
      const Thumbnail = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["__scopeId", "data-v-77441376"]]);
      const _hoisted_1$o = { class: "progress-bar" };
      const _hoisted_2$e = { class: "progress-bar-container" };
      const _sfc_main$m = /* @__PURE__ */ defineComponent({
        __name: "ProgressBar",
        setup(__props) {
          const { progress } = usePlayerContext();
          const progressBarRef = ref(null);
          const progressBarWidth = computed(() => {
            var _a;
            return ((_a = progressBarRef.value) == null ? undefined : _a.offsetWidth) || 0;
          });
          const isDragging = ref(false);
          const dragProgress = ref(0);
          const originalProgress = ref(0);
          const previewTime = ref(0);
          const previewProgress = ref(0);
          const isPreviewVisible = ref(false);
          const handleBarWrapperMouseEnter = () => {
            if (!isPreviewVisible.value) {
              showPreview();
            }
          };
          const handleBarWrapperMouseLeave = () => {
            hidePreview();
          };
          const calculatePosition = (event, element) => {
            const rect = element.getBoundingClientRect();
            const position = (event.clientX - rect.left) / rect.width;
            return Math.min(Math.max(position, 0), 1);
          };
          const handleBarWrapperMouseDown = (event) => {
            if (!progressBarRef.value) return;
            const position = calculatePosition(event, progressBarRef.value);
            startDragging(position);
            document.addEventListener("mousemove", handleGlobalMouseMove);
            document.addEventListener("mouseup", handleMouseUp);
          };
          const handleMouseUp = (event) => {
            document.removeEventListener("mousemove", handleGlobalMouseMove);
            document.removeEventListener("mouseup", handleMouseUp);
            const position = calculatePosition(event, progressBarRef.value);
            stopDragging(position);
          };
          const handleBarWrapperMouseMove = (event) => {
            if (!progressBarRef.value) return;
            const position = calculatePosition(event, progressBarRef.value);
            updatePreview(position);
          };
          const handleGlobalMouseMove = (event) => {
            if (!progressBarRef.value) return;
            const position = calculatePosition(event, progressBarRef.value);
            updateDragging(position);
          };
          const handleBarWrapperClick = (event) => {
            if (!progressBarRef.value || isDragging.value) return;
            const position = calculatePosition(event, progressBarRef.value);
            const newTime = position * progress.duration.value;
            progress.seekTo(newTime);
          };
          const updatePreview = (position) => {
            previewProgress.value = position * 100;
            previewTime.value = position * progress.duration.value;
          };
          const startDragging = (position) => {
            isDragging.value = true;
            originalProgress.value = progress.progress.value;
            dragProgress.value = position * 100;
            previewTime.value = position * progress.duration.value;
          };
          const updateDragging = (position) => {
            if (!isDragging.value) return;
            dragProgress.value = position * 100;
            previewTime.value = position * progress.duration.value;
          };
          const stopDragging = (position) => {
            if (isDragging.value) {
              const finalTime = position * progress.duration.value;
              progress.seekTo(finalTime);
              previewProgress.value = position * 100;
              previewTime.value = finalTime;
            }
            isDragging.value = false;
          };
          const showPreview = () => {
            isPreviewVisible.value = true;
          };
          const hidePreview = () => {
            if (!isDragging.value) {
              isPreviewVisible.value = false;
              previewProgress.value = 0;
              previewTime.value = 0;
            }
          };
          onUnmounted(() => {
            document.removeEventListener("mousemove", handleGlobalMouseMove);
            document.removeEventListener("mouseup", handleMouseUp);
          });
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", _hoisted_1$o, [
              createElementVNode("div", {
                ref_key: "progressBarRef",
                ref: progressBarRef,
                class: "progress-bar-wrapper",
                onClick: handleBarWrapperClick,
                onMousemove: handleBarWrapperMouseMove,
                onMouseenter: handleBarWrapperMouseEnter,
                onMouseleave: handleBarWrapperMouseLeave,
                onMousedown: handleBarWrapperMouseDown
              }, [
                createElementVNode("div", _hoisted_2$e, [
                  createElementVNode("div", {
                    class: "progress-buffer",
                    style: normalizeStyle({ width: `${unref(progress).buffered.value}%` })
                  }, null, 4),
                  createElementVNode("div", {
                    class: "progress-current",
                    style: normalizeStyle({
                      width: `${unref(progress).progress.value}%`,
                      opacity: isDragging.value ? 0.5 : 1
                    })
                  }, null, 4),
                  isDragging.value ? (openBlock(), createElementBlock("div", {
                    key: 0,
                    class: "progress-current progress-dragging",
                    style: normalizeStyle({ width: `${dragProgress.value}%` })
                  }, null, 4)) : createCommentVNode("", true),
                  withDirectives(createElementVNode("div", {
                    class: "progress-hover",
                    style: normalizeStyle({ width: `${previewProgress.value}%` })
                  }, null, 4), [
                    [vShow, isPreviewVisible.value && !isDragging.value]
                  ]),
                  isDragging.value ? (openBlock(), createElementBlock("div", {
                    key: 1,
                    class: "progress-handle-container",
                    style: normalizeStyle({ left: `${originalProgress.value}%` })
                  }, _cache[0] || (_cache[0] = [
                    createElementVNode("div", { class: "progress-handle progress-handle-original" }, null, -1)
                  ]), 4)) : createCommentVNode("", true),
                  createElementVNode("div", {
                    class: "progress-handle-container",
                    style: normalizeStyle({
                      left: `${isDragging.value ? dragProgress.value : unref(progress).progress.value}%`
                    })
                  }, [
                    createElementVNode("div", {
                      class: normalizeClass(["progress-handle", { "is-dragging": isDragging.value }])
                    }, null, 2)
                  ], 4)
                ]),
                createVNode(Thumbnail, {
                  visible: isPreviewVisible.value || isDragging.value,
                  position: isDragging.value ? dragProgress.value : previewProgress.value,
                  time: isDragging.value ? previewTime.value : isPreviewVisible.value ? previewTime.value : unref(progress).currentTime.value,
                  "progress-bar-width": progressBarWidth.value
                }, null, 8, ["visible", "position", "time", "progress-bar-width"])
              ], 544)
            ]);
          };
        }
      });
      const ProgressBar = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["__scopeId", "data-v-6b1e2de1"]]);
      const PortalSymbol = Symbol("XPlayerPortal");
      function usePortalProvider() {
        const container = ref(null);
        const context = {
          container
        };
        provide(PortalSymbol, context);
        return context;
      }
      function usePortal() {
        const context = inject(PortalSymbol);
        if (!context) {
          throw new Error("usePortal must be used within a XPlayer component");
        }
        return context;
      }
      const _hoisted_1$n = { class: "x-popup-content" };
      const _sfc_main$l = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          visible: { type: Boolean },
          x: { default: 0 },
          y: { default: 0 }
        },
        emits: ["update:visible"],
        setup(__props, { emit: __emit }) {
          const props = __props;
          const emit = __emit;
          const { container } = usePortal();
          const portalContainer = computed(() => container.value || "body");
          const style = computed(() => ({
            left: `${props.x}px`,
            top: `${props.y}px`,
            position: container.value ? "absolute" : "fixed"
          }));
          const handleClickOutside = (event) => {
            if (props.visible) {
              emit("update:visible", false);
            }
          };
          watch(
            () => props.visible,
            (visible) => {
              if (visible) {
                setTimeout(() => {
                  document.addEventListener("click", handleClickOutside);
                }, 0);
              } else {
                document.removeEventListener("click", handleClickOutside);
              }
            },
            { immediate: true }
          );
          onUnmounted(() => {
            document.removeEventListener("click", handleClickOutside);
          });
          return (_ctx, _cache) => {
            return openBlock(), createBlock(Teleport, {
              to: portalContainer.value,
              disabled: !portalContainer.value
            }, [
              withDirectives(createElementVNode("div", {
                class: "x-popup",
                style: normalizeStyle(style.value),
                onClick: _cache[0] || (_cache[0] = withModifiers(() => {
                }, ["stop"]))
              }, [
                _cache[1] || (_cache[1] = createElementVNode("div", { class: "x-popup-bg" }, null, -1)),
                createElementVNode("div", _hoisted_1$n, [
                  renderSlot(_ctx.$slots, "default", {}, undefined, true)
                ])
              ], 4), [
                [vShow, _ctx.visible]
              ])
            ], 8, ["to", "disabled"]);
          };
        }
      });
      const Popup = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["__scopeId", "data-v-a8c7199f"]]);
      const _sfc_main$k = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          visible: { type: Boolean },
          triggerRef: {},
          placement: {},
          offset: {}
        },
        emits: ["mouseenter", "mouseleave", "update:visible"],
        setup(__props, { emit: __emit }) {
          const props = __props;
          const emit = __emit;
          const { controls } = usePlayerContext();
          const menuRef = ref();
          const forceUpdate = ref(0);
          const menuPosition = computed(() => {
            forceUpdate.value;
            if (!props.triggerRef || !menuRef.value) return { x: 0, y: 0 };
            const triggerRect = props.triggerRef.getBoundingClientRect();
            const menuRect = menuRef.value.getBoundingClientRect();
            const playerContainer = props.triggerRef.closest(".x-player");
            if (!playerContainer) return { x: 0, y: 0 };
            const playerRect = playerContainer.getBoundingClientRect();
            const triggerLeft = triggerRect.left - playerRect.left;
            const triggerTop = triggerRect.top - playerRect.top;
            const triggerBottom = triggerRect.bottom - playerRect.top;
            const spaceBelow = playerRect.height - triggerBottom;
            const spaceAbove = triggerTop;
            const offset = props.offset ?? 8;
            let y;
            if (props.placement === "top" || props.placement !== "bottom" && spaceBelow < menuRect.height && spaceAbove >= menuRect.height) {
              y = triggerTop - menuRect.height - offset;
            } else {
              y = triggerBottom + offset;
            }
            const x = Math.min(triggerLeft, playerRect.width - menuRect.width - 16);
            return { x, y };
          });
          watch(
            () => props.visible,
            (visible) => {
              if (visible) {
                setTimeout(() => {
                  forceUpdate.value++;
                }, 0);
              }
              controls.setIsMouseInMenu(visible);
            }
          );
          const handleMouseEnter = () => emit("mouseenter");
          const handleMouseLeave = () => emit("mouseleave");
          const handleVisibleChange = (visible) => {
            emit("update:visible", visible);
          };
          return (_ctx, _cache) => {
            return openBlock(), createBlock(Popup, {
              visible: _ctx.visible,
              x: menuPosition.value.x,
              y: menuPosition.value.y,
              onClick: _cache[0] || (_cache[0] = withModifiers(() => {
              }, ["stop"])),
              onMouseenter: handleMouseEnter,
              onMouseleave: handleMouseLeave,
              "onUpdate:visible": handleVisibleChange
            }, {
              default: withCtx(() => [
                createElementVNode("div", {
                  class: "x-menu",
                  ref_key: "menuRef",
                  ref: menuRef
                }, [
                  renderSlot(_ctx.$slots, "default", {}, undefined, true)
                ], 512)
              ]),
              _: 3
            }, 8, ["visible", "x", "y"]);
          };
        }
      });
      const Menu = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["__scopeId", "data-v-6ef95020"]]);
      const _hoisted_1$m = ["onClick"];
      const _sfc_main$j = /* @__PURE__ */ defineComponent({
        __name: "QualityButton",
        setup(__props) {
          const { source, subtitles } = usePlayerContext();
          const menuVisible = ref(false);
          const buttonRef = ref();
          const currentQuality = computed(() => {
            if (!source.current.value) return "自动";
            const quality = source.current.value.displayQuality || source.current.value.quality;
            return typeof quality === "number" ? `${quality}P` : quality;
          });
          const toggleMenu = () => {
            menuVisible.value = !menuVisible.value;
          };
          const handleMenuVisibleChange = (visible) => {
            menuVisible.value = visible;
          };
          const getDisplayQuality = (sourceValue) => {
            const quality = sourceValue.displayQuality || sourceValue.quality;
            return typeof quality === "number" ? `${quality}P` : quality;
          };
          const handleQualityChange = async (sourceValue) => {
            menuVisible.value = false;
            await source.changeQuality(sourceValue);
            subtitles.restoreCurrentSubtitle();
          };
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", {
              ref_key: "buttonRef",
              ref: buttonRef,
              class: "quality-button",
              onClick: toggleMenu
            }, [
              createElementVNode("span", null, toDisplayString(currentQuality.value), 1),
              createVNode(Menu, {
                visible: menuVisible.value,
                triggerRef: buttonRef.value,
                placement: "top",
                "onUpdate:visible": handleMenuVisibleChange
              }, {
                default: withCtx(() => [
                  (openBlock(true), createElementBlock(Fragment, null, renderList(unref(source).list.value, (item) => {
                    var _a;
                    return openBlock(), createElementBlock("div", {
                      key: item.quality,
                      class: normalizeClass(["menu-item", { active: item.quality === ((_a = unref(source).current) == null ? undefined : _a.value.quality) }]),
                      onClick: ($event) => handleQualityChange(item)
                    }, toDisplayString(getDisplayQuality(item)), 11, _hoisted_1$m);
                  }), 128))
                ]),
                _: 1
              }, 8, ["visible", "triggerRef"])
            ], 512);
          };
        }
      });
      const QualityButton = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["__scopeId", "data-v-bc77eba9"]]);
      const _sfc_main$i = /* @__PURE__ */ defineComponent({
        __name: "ScrollTip",
        setup(__props) {
          const { fullscreen } = usePlayerContext();
          const isVisible = ref(false);
          const timer = ref(null);
          watch(
            () => fullscreen.isFullscreen.value,
            (newVal) => {
              if (newVal) {
                isVisible.value = true;
                timer.value = window.setTimeout(() => {
                  isVisible.value = false;
                }, 2e3);
              } else {
                isVisible.value = false;
                if (timer.value) {
                  window.clearTimeout(timer.value);
                  timer.value = null;
                }
              }
            }
          );
          onUnmounted(() => {
            if (timer.value) {
              window.clearTimeout(timer.value);
              timer.value = null;
            }
          });
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", {
              class: normalizeClass(["scroll-tip", { "show": isVisible.value }])
            }, _cache[0] || (_cache[0] = [
              createElementVNode("div", { class: "scroll-tip-content" }, [
                createElementVNode("span", null, "往下滚动有惊喜"),
                createElementVNode("span", { class: "icon" }, "👇")
              ], -1)
            ]), 2);
          };
        }
      });
      const ScrollTip = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-b79b31e3"]]);
      const _hoisted_1$l = { class: "speed-button" };
      const _hoisted_2$d = { class: "speed-menu-items" };
      const _hoisted_3$d = ["onClick"];
      const _sfc_main$h = /* @__PURE__ */ defineComponent({
        __name: "SpeedButton",
        setup(__props) {
          const { playbackRate } = usePlayerContext();
          const isMenuVisible = ref(false);
          const playbackRates = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
          const toggleSpeedMenu = () => {
            isMenuVisible.value = !isMenuVisible.value;
          };
          const hideMenu = () => {
            isMenuVisible.value = false;
          };
          const handleSpeedChange = (rate) => {
            playbackRate.setPlaybackRate(rate);
            hideMenu();
          };
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", _hoisted_1$l, [
              createElementVNode("button", {
                class: "control-button",
                onClick: toggleSpeedMenu
              }, toDisplayString(unref(playbackRate).playbackRate.value) + " X ", 1),
              createVNode(Transition, { name: "fade" }, {
                default: withCtx(() => [
                  isMenuVisible.value ? (openBlock(), createElementBlock("div", {
                    key: 0,
                    class: "speed-menu",
                    onMouseleave: hideMenu
                  }, [
                    createElementVNode("div", _hoisted_2$d, [
                      (openBlock(), createElementBlock(Fragment, null, renderList(playbackRates, (rate) => {
                        return createElementVNode("button", {
                          key: rate,
                          class: normalizeClass(["speed-menu-item", { active: unref(playbackRate).playbackRate.value === rate }]),
                          onClick: ($event) => handleSpeedChange(rate)
                        }, toDisplayString(rate), 11, _hoisted_3$d);
                      }), 64))
                    ])
                  ], 32)) : createCommentVNode("", true)
                ]),
                _: 1
              })
            ]);
          };
        }
      });
      const SpeedButton = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["__scopeId", "data-v-bb11f985"]]);
      const _hoisted_1$k = {
        xmlns: "http://www.w3.org/2000/svg",
        width: "48",
        height: "48",
        viewBox: "0 -960 960 960"
      };
      function render$4(_ctx, _cache) {
        return openBlock(), createElementBlock("svg", _hoisted_1$k, _cache[0] || (_cache[0] = [
          createElementVNode("path", { d: "M480-80q-84 0-157-31t-127-85-85-127-31-157 31-157 85-127 127-85 157-31q12 0 21 9t9 21-9 21-21 9q-141 0-240.5 99.5T140-480t99.5 240.5T480-140t240.5-99.5T820-480q0-12 9-21t21-9 21 9 9 21q0 84-31 157t-85 127-127 85-157 31" }, null, -1)
        ]));
      }
      const ProgressActivity = { render: render$4 };
      const _hoisted_1$j = {
        xmlns: "http://www.w3.org/2000/svg",
        width: "48",
        height: "48",
        viewBox: "0 -960 960 960"
      };
      function render$3(_ctx, _cache) {
        return openBlock(), createElementBlock("svg", _hoisted_1$j, _cache[0] || (_cache[0] = [
          createElementVNode("path", { d: "M140-160q-24 0-42-18t-18-42v-520q0-24 18-42t42-18h680q24 0 42 18t18 42v520q0 24-18 42t-42 18zm0-60h680v-520H140zm0 0v-520zm130-130h300q12.75 0 21.38-8.68 8.62-8.67 8.62-21.5 0-12.82-8.62-21.32-8.63-8.5-21.38-8.5H270q-12.75 0-21.37 8.68-8.63 8.67-8.63 21.5 0 12.82 8.63 21.32 8.62 8.5 21.37 8.5m120-120h300q12.75 0 21.38-8.68 8.62-8.67 8.62-21.5 0-12.82-8.62-21.32-8.63-8.5-21.38-8.5H390q-12.75 0-21.37 8.68-8.63 8.67-8.63 21.5 0 12.82 8.63 21.32 8.62 8.5 21.37 8.5m-119.82 0q12.82 0 21.32-8.68 8.5-8.67 8.5-21.5 0-12.82-8.68-21.32-8.67-8.5-21.5-8.5-12.82 0-21.32 8.68-8.5 8.67-8.5 21.5 0 12.82 8.68 21.32 8.67 8.5 21.5 8.5m420 120q12.82 0 21.32-8.68 8.5-8.67 8.5-21.5 0-12.82-8.68-21.32-8.67-8.5-21.5-8.5-12.82 0-21.32 8.68-8.5 8.67-8.5 21.5 0 12.82 8.68 21.32 8.67 8.5 21.5 8.5" }, null, -1)
        ]));
      }
      const Subtitles = { render: render$3 };
      const _hoisted_1$i = { class: "subtitle-button" };
      const _hoisted_2$c = ["disabled"];
      const _hoisted_3$c = ["onClick"];
      const _sfc_main$g = /* @__PURE__ */ defineComponent({
        __name: "SubtitleButton",
        setup(__props) {
          const { rootProps, subtitles } = usePlayerContext();
          const menuVisible = ref(false);
          const buttonRef = ref();
          const toggleMenu = () => {
            menuVisible.value = !menuVisible.value;
          };
          const handleMenuVisibleChange = (visible) => {
            menuVisible.value = visible;
          };
          const handleSubtitleSelect = (subtitle) => {
            menuVisible.value = false;
            subtitles.change(subtitle);
          };
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", _hoisted_1$i, [
              createElementVNode("button", {
                ref_key: "buttonRef",
                ref: buttonRef,
                class: "control-button",
                onClick: toggleMenu,
                title: "字幕",
                alt: "字幕",
                disabled: unref(subtitles).loadingSubtitles.value
              }, [
                unref(subtitles).loadingSubtitles.value ? (openBlock(), createBlock(Icon, {
                  key: 0,
                  svg: unref(ProgressActivity),
                  class: "loading-icon"
                }, null, 8, ["svg"])) : (openBlock(), createBlock(Icon, {
                  key: 1,
                  svg: unref(Subtitles)
                }, null, 8, ["svg"]))
              ], 8, _hoisted_2$c),
              createVNode(Menu, {
                visible: menuVisible.value,
                "onUpdate:visible": [
                  _cache[1] || (_cache[1] = ($event) => menuVisible.value = $event),
                  handleMenuVisibleChange
                ],
                triggerRef: buttonRef.value,
                placement: "top"
              }, {
                default: withCtx(() => [
                  createElementVNode("div", {
                    class: normalizeClass(["menu-item", { active: unref(subtitles).current.value === null }]),
                    onClick: _cache[0] || (_cache[0] = ($event) => handleSubtitleSelect(null))
                  }, " 关闭字幕 ", 2),
                  (openBlock(true), createElementBlock(Fragment, null, renderList(unref(subtitles).list.value, (subtitle) => {
                    var _a;
                    return openBlock(), createElementBlock("div", {
                      key: subtitle.url,
                      class: normalizeClass(["menu-item", { active: ((_a = unref(subtitles).current.value) == null ? undefined : _a.url) === subtitle.url }]),
                      onClick: ($event) => handleSubtitleSelect(subtitle)
                    }, toDisplayString(subtitle.label), 11, _hoisted_3$c);
                  }), 128))
                ]),
                _: 1
              }, 8, ["visible", "triggerRef"])
            ]);
          };
        }
      });
      const SubtitleButton = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["__scopeId", "data-v-fec6a53e"]]);
      const _hoisted_1$h = { class: "time-display" };
      const _sfc_main$f = /* @__PURE__ */ defineComponent({
        __name: "TimeDisplay",
        setup(__props) {
          const { progress } = usePlayerContext();
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", _hoisted_1$h, [
              createElementVNode("span", null, toDisplayString(unref(formatTime)(unref(progress).currentTime.value)), 1),
              _cache[0] || (_cache[0] = createElementVNode("span", { class: "time-separator" }, "/", -1)),
              createElementVNode("span", null, toDisplayString(unref(formatTime)(unref(progress).duration.value)), 1)
            ]);
          };
        }
      });
      const TimeDisplay = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["__scopeId", "data-v-208629a5"]]);
      const _hoisted_1$g = {
        xmlns: "http://www.w3.org/2000/svg",
        width: "48",
        height: "48",
        viewBox: "0 -960 960 960"
      };
      function render$2(_ctx, _cache) {
        return openBlock(), createElementBlock("svg", _hoisted_1$g, _cache[0] || (_cache[0] = [
          createElementVNode("path", { d: "M360-360H230q-13 0-21.5-8.5T200-390v-180q0-13 8.5-21.5T230-600h130l149-149q14-14 32.5-6.5T560-728v496q0 20-18.5 27.5T509-211zm380-120q0 52-26 94t-73 64q-8 4-14.5-1t-6.5-13v-289q0-8 6.5-13t14.5-1q47 22 73 65t26 94M500-648 387-540H260v120h127l113 109zM378-480" }, null, -1)
        ]));
      }
      const VolumeDown = { render: render$2 };
      const _hoisted_1$f = {
        xmlns: "http://www.w3.org/2000/svg",
        width: "48",
        height: "48",
        viewBox: "0 -960 960 960"
      };
      function render$1(_ctx, _cache) {
        return openBlock(), createElementBlock("svg", _hoisted_1$f, _cache[0] || (_cache[0] = [
          createElementVNode("path", { d: "M681-188q-17 12-35.5 22T607-148q-12 5-24.5 0T565-165q-5-11 .5-22t17.5-16q15-5 28.5-12t26.5-17L473-397v165q0 20-18.5 27.5T422-211L273-360H143q-13 0-21.5-8.5T113-390v-180q0-13 8.5-21.5T143-600h126L70-799q-9-9-8.5-21.5T71-842t21.5-9 21.5 9l721 721q9 9 9 21.5T835-78t-22 9-22-9zm92-293q0-93-52.5-168.5T583-759q-12-5-17-16t0-22q5-12 17.5-16.5t25.5.5q101 41 162.5 130.5T833-481q0 38-7.5 75T802-334q-8 17-19.5 20.5T760-315t-16.5-14.5.5-20.5q15-30 22-63t7-68M576-628q38 23 57.5 63.5T653-480v15q0 7-2 15-2 10-11 13t-17-5l-61-61q-5-5-7-10t-2-11v-91q0-9 7.5-13.5t15.5.5m-196-57q-5-5-5-11t5-11l42-42q14-14 32.5-6.5T473-728v100q0 10-9.5 13.5T447-618zm33 379v-150l-84-84H173v120h126zm-42-192" }, null, -1)
        ]));
      }
      const VolumeOff = { render: render$1 };
      const _hoisted_1$e = {
        xmlns: "http://www.w3.org/2000/svg",
        width: "48",
        height: "48",
        viewBox: "0 -960 960 960"
      };
      function render(_ctx, _cache) {
        return openBlock(), createElementBlock("svg", _hoisted_1$e, _cache[0] || (_cache[0] = [
          createElementVNode("path", { d: "M780-481q0-94-52.5-169T590-759q-12-5-17-16t0-22q5-12 17.5-16.5t25.5.5q101 41 162.5 131T840-481t-61.5 201T616-149q-13 5-25.5.5T573-165q-5-11 0-22t17-16q85-34 137.5-109T780-481M280-360H150q-13 0-21.5-8.5T120-390v-180q0-13 8.5-21.5T150-600h130l149-149q14-14 32.5-6.5T480-728v496q0 20-18.5 27.5T429-211zm380-120q0 52-26 94t-73 64q-8 4-14.5-1t-6.5-13v-289q0-8 6.5-13t14.5-1q47 22 73 65t26 94M420-648 307-540H180v120h127l113 109zM298-480" }, null, -1)
        ]));
      }
      const VolumeUp = { render };
      const _hoisted_1$d = { class: "volume-control" };
      const _hoisted_2$b = { class: "volume-slider" };
      const _hoisted_3$b = { class: "volume-slider-track" };
      const _hoisted_4$8 = ["value"];
      const _sfc_main$e = /* @__PURE__ */ defineComponent({
        __name: "VolumeControl",
        setup(__props) {
          const { volume } = usePlayerContext();
          const VolumeIcon = computed(() => {
            if (volume.isMuted.value) {
              return VolumeOff;
            }
            if (volume.volume.value < 50) {
              return VolumeDown;
            }
            if (volume.volume.value >= 50) {
              return VolumeUp;
            }
            return VolumeUp;
          });
          const handleVolumeChange = (event) => {
            const value = Number(event.target.value);
            volume.setVolume(value);
          };
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", _hoisted_1$d, [
              createElementVNode("button", {
                class: "volume-control-button",
                onClick: _cache[0] || (_cache[0] = //@ts-ignore
                (...args) => unref(volume).toggleMute && unref(volume).toggleMute(...args))
              }, [
                createVNode(Icon, {
                  svg: VolumeIcon.value,
                  class: "icon"
                }, null, 8, ["svg"])
              ]),
              createElementVNode("div", _hoisted_2$b, [
                createElementVNode("div", _hoisted_3$b, [
                  createElementVNode("div", {
                    class: "volume-slider-fill",
                    style: normalizeStyle({ width: `${unref(volume).volume.value}%` })
                  }, null, 4),
                  createElementVNode("input", {
                    type: "range",
                    min: "0",
                    max: "100",
                    value: unref(volume).volume.value,
                    onInput: handleVolumeChange
                  }, null, 40, _hoisted_4$8)
                ])
              ])
            ]);
          };
        }
      });
      const VolumeControl = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["__scopeId", "data-v-e33fb2a5"]]);
      const _hoisted_1$c = { class: "controls-content" };
      const _hoisted_2$a = { class: "controls-bar" };
      const _hoisted_3$a = { class: "left-controls" };
      const _hoisted_4$7 = { class: "right-controls" };
      const _sfc_main$d = /* @__PURE__ */ defineComponent({
        __name: "index",
        setup(__props) {
          const { controls, source } = usePlayerContext();
          return (_ctx, _cache) => {
            return unref(source).list.value.length > 0 ? (openBlock(), createElementBlock("div", {
              key: 0,
              class: "controls-wrapper",
              onMouseenter: _cache[0] || (_cache[0] = ($event) => unref(controls).setIsMouseInControls(true)),
              onMouseleave: _cache[1] || (_cache[1] = ($event) => unref(controls).setIsMouseInControls(false))
            }, [
              createElementVNode("div", {
                class: normalizeClass(["controls-gradient", { "is-visible": unref(controls).visible.value }])
              }, null, 2),
              createElementVNode("div", {
                class: normalizeClass(["video-controls", { "is-visible": unref(controls).visible.value }])
              }, [
                createElementVNode("div", _hoisted_1$c, [
                  createVNode(ProgressBar),
                  createElementVNode("div", _hoisted_2$a, [
                    createElementVNode("div", _hoisted_3$a, [
                      createVNode(PlayButton),
                      createVNode(VolumeControl),
                      createVNode(TimeDisplay)
                    ]),
                    createElementVNode("div", _hoisted_4$7, [
                      createVNode(SpeedButton),
                      createVNode(SubtitleButton),
                      createVNode(QualityButton),
                      createVNode(_sfc_main$q)
                    ])
                  ]),
                  createVNode(ScrollTip)
                ])
              ], 2)
            ], 32)) : createCommentVNode("", true);
          };
        }
      });
      const VideoControls = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["__scopeId", "data-v-c45d079a"]]);
      const _hoisted_1$b = { class: "loading-container" };
      const _sfc_main$c = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          show: { type: Boolean }
        },
        setup(__props) {
          return (_ctx, _cache) => {
            return withDirectives((openBlock(), createElementBlock("div", _hoisted_1$b, _cache[0] || (_cache[0] = [
              createElementVNode("div", { class: "apple-loading" }, [
                createElementVNode("span"),
                createElementVNode("span"),
                createElementVNode("span")
              ], -1)
            ]), 512)), [
              [vShow, _ctx.show]
            ]);
          };
        }
      });
      const Loading = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["__scopeId", "data-v-45219110"]]);
      const _hoisted_1$a = {
        key: 0,
        class: "play-animation"
      };
      const _hoisted_2$9 = { class: "play-animation-icon" };
      const _hoisted_3$9 = { class: "icon-wrapper" };
      const _sfc_main$b = /* @__PURE__ */ defineComponent({
        __name: "index",
        setup(__props) {
          const { playing } = usePlayerContext();
          const visible = ref(false);
          const timer = ref(null);
          watch(playing.isPlaying, (value) => {
            visible.value = true;
            if (timer.value) {
              clearTimeout(timer.value);
            }
            timer.value = window.setTimeout(() => {
              visible.value = false;
            }, 300);
          });
          return (_ctx, _cache) => {
            return openBlock(), createBlock(Transition, { name: "fade" }, {
              default: withCtx(() => [
                visible.value ? (openBlock(), createElementBlock("div", _hoisted_1$a, [
                  createElementVNode("div", _hoisted_2$9, [
                    createElementVNode("div", _hoisted_3$9, [
                      createVNode(Icon, {
                        svg: unref(playing).isPlaying.value ? unref(Play) : unref(Pause),
                        size: "50px"
                      }, null, 8, ["svg"])
                    ])
                  ])
                ])) : createCommentVNode("", true)
              ]),
              _: 1
            });
          };
        }
      });
      const PlayAnimation = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-9bc63abc"]]);
      const _hoisted_1$9 = { class: "player-container" };
      const _hoisted_2$8 = { class: "video-container" };
      const _hoisted_3$8 = ["poster", "muted", "volume", "autoplay", "loop"];
      const _hoisted_4$6 = ["src", "label", "srclang", "kind", "default"];
      const _hoisted_5$6 = {
        key: 0,
        class: "resume-container"
      };
      const _sfc_main$a = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          sources: {},
          onThumbnailRequest: { type: Function, default: undefined },
          subtitles: {},
          loadingSubtitles: {},
          onSubtitleChange: { type: Function, default: undefined },
          defaultSubtitle: { default: null }
        },
        setup(__props, { expose: __expose }) {
          const props = __props;
          const videoElement = ref(null);
          const portalContext = usePortalProvider();
          const { fullscreen, volume, playing, source, controls, subtitles } = useVideoPlayer(videoElement, props);
          const handleRootMouseMove = () => {
            controls.showWithAutoHide();
          };
          const handleRootMouseLeave = () => {
            controls.clearHideControlsTimer();
            controls.hide();
          };
          __expose({
            togglePlay: playing.togglePlay,
            interruptSource: source.interruptSource
          });
          return (_ctx, _cache) => {
            var _a;
            return openBlock(), createElementBlock("div", {
              class: normalizeClass(["x-player", { "is-fullscreen": unref(fullscreen).isFullscreen.value }]),
              onMousemove: handleRootMouseMove,
              onMouseleave: handleRootMouseLeave
            }, [
              createElementVNode("div", _hoisted_1$9, [
                createElementVNode("div", _hoisted_2$8, [
                  (openBlock(), createElementBlock("video", {
                    ref_key: "videoElement",
                    ref: videoElement,
                    key: unref(source).videoKey.value,
                    poster: (_a = unref(source).current.value) == null ? undefined : _a.poster,
                    muted: unref(volume).isMuted.value,
                    volume: unref(volume).volume.value / 100,
                    autoplay: unref(playing).autoplay.value,
                    loop: unref(playing).loop.value,
                    controls: false,
                    playsinline: true,
                    "webkit-playsinline": true,
                    onClick: _cache[0] || (_cache[0] = //@ts-ignore
                    (...args) => unref(playing).togglePlay && unref(playing).togglePlay(...args))
                  }, [
                    (openBlock(true), createElementBlock(Fragment, null, renderList(unref(subtitles).list.value, (subtitle, index) => {
                      return openBlock(), createElementBlock("track", {
                        key: index,
                        src: subtitle.url,
                        label: subtitle.label,
                        srclang: subtitle.srclang,
                        kind: subtitle.kind,
                        default: subtitle.default
                      }, null, 8, _hoisted_4$6);
                    }), 128))
                  ], 8, _hoisted_3$8)),
                  createVNode(PlayAnimation),
                  createVNode(Loading, {
                    show: unref(playing).isLoading.value
                  }, null, 8, ["show"]),
                  createElementVNode("div", {
                    class: "video-mask",
                    onClick: _cache[1] || (_cache[1] = //@ts-ignore
                    (...args) => unref(playing).togglePlay && unref(playing).togglePlay(...args)),
                    onDblclick: _cache[2] || (_cache[2] = //@ts-ignore
                    (...args) => unref(fullscreen).toggleFullscreen && unref(fullscreen).toggleFullscreen(...args))
                  }, null, 32),
                  createVNode(VideoControls)
                ])
              ]),
              createElementVNode("div", {
                class: "portal-container",
                ref: unref(portalContext).container
              }, null, 512),
              unref(source).isInterrupt.value ? (openBlock(), createElementBlock("div", _hoisted_5$6, [
                createElementVNode("button", {
                  onClick: _cache[3] || (_cache[3] = //@ts-ignore
                  (...args) => unref(source).resumeSource && unref(source).resumeSource(...args))
                }, "恢复")
              ])) : createCommentVNode("", true)
            ], 34);
          };
        }
      });
      const XPlayer = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-2f4f5468"]]);
      const useParamsVideoPage = () => {
        const pickCode = ref();
        const avNumber = ref();
        const cid = ref();
        const title = ref();
        const getParams = () => {
          const params = new URLSearchParams(window.location.search);
          pickCode.value = params.get("pick_code");
          avNumber.value = params.get("avNumber") || null;
          cid.value = params.get("cid");
          title.value = params.get("title");
        };
        getParams();
        return {
          pickCode,
          avNumber,
          cid,
          title,
          getParams
        };
      };
      class SubtitlePreferenceManager {
        constructor() {
          this.logger = new AppLogger("Utils SubtitlePreference");
          this.STORE_PREFIX = "115master_subtitle_preference_";
          this.store = localforage.createInstance({
            name: "115master",
            storeName: "subtitle_preferences"
          });
        }
        getStoreKey(videoName) {
          const cleanName = videoName.replace(/\.[^/.]+$/, "").trim();
          return `${this.STORE_PREFIX}${cleanName}`;
        }
        async savePreference(pickcode, subtitle) {
          try {
            const key = this.getStoreKey(pickcode);
            if (subtitle) {
              await this.store.setItem(key, subtitle);
              this.logger.log("保存字幕偏好成功", { pickcode, subtitle });
            } else {
              await this.store.removeItem(key);
              this.logger.log("清除字幕偏好成功", { pickcode });
            }
          } catch (error) {
            this.logger.error("保存字幕偏好失败", error);
          }
        }
        async getPreference(pickcode) {
          try {
            const key = this.getStoreKey(pickcode);
            const preference = await this.store.getItem(key);
            this.logger.log("获取字幕偏好", {
              pickcode,
              found: !!preference
            });
            return preference;
          } catch (error) {
            this.logger.error("获取字幕偏好失败", error);
            return null;
          }
        }
        async clear() {
          try {
            await this.store.clear();
            this.logger.log("清除所有字幕偏好成功");
          } catch (error) {
            this.logger.error("清除字幕偏好失败", error);
          }
        }
      }
      const subtitlePreference = new SubtitlePreferenceManager();
      const _sfc_main$9 = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          width: { default: "100%" },
          height: { default: "16px" },
          circle: { type: Boolean, default: false },
          borderRadius: { default: "4px" },
          animated: { type: Boolean, default: true }
        },
        setup(__props) {
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", {
              class: normalizeClass(["skeleton", {
                circle: _ctx.circle,
                "skeleton-animated": _ctx.animated
              }]),
              style: normalizeStyle({
                width: _ctx.width,
                height: _ctx.height,
                borderRadius: _ctx.borderRadius
              })
            }, [
              renderSlot(_ctx.$slots, "default", {}, undefined, true)
            ], 6);
          };
        }
      });
      const Skeleton = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-a833dc5b"]]);
      var duration$2 = { exports: {} };
      var duration$1 = duration$2.exports;
      var hasRequiredDuration;
      function requireDuration() {
        if (hasRequiredDuration) return duration$2.exports;
        hasRequiredDuration = 1;
        (function(module, exports) {
          !function(t, s) {
            module.exports = s();
          }(duration$1, function() {
            var t, s, n = 1e3, i2 = 6e4, e = 36e5, r = 864e5, o = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, u = 31536e6, d = 2628e6, a = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/, h2 = { years: u, months: d, days: r, hours: e, minutes: i2, seconds: n, milliseconds: 1, weeks: 6048e5 }, c = function(t2) {
              return t2 instanceof g;
            }, f = function(t2, s2, n2) {
              return new g(t2, n2, s2.$l);
            }, m = function(t2) {
              return s.p(t2) + "s";
            }, l = function(t2) {
              return t2 < 0;
            }, $ = function(t2) {
              return l(t2) ? Math.ceil(t2) : Math.floor(t2);
            }, y = function(t2) {
              return Math.abs(t2);
            }, v = function(t2, s2) {
              return t2 ? l(t2) ? { negative: true, format: "" + y(t2) + s2 } : { negative: false, format: "" + t2 + s2 } : { negative: false, format: "" };
            }, g = function() {
              function l2(t2, s2, n2) {
                var i3 = this;
                if (this.$d = {}, this.$l = n2, undefined === t2 && (this.$ms = 0, this.parseFromMilliseconds()), s2) return f(t2 * h2[m(s2)], this);
                if ("number" == typeof t2) return this.$ms = t2, this.parseFromMilliseconds(), this;
                if ("object" == typeof t2) return Object.keys(t2).forEach(function(s3) {
                  i3.$d[m(s3)] = t2[s3];
                }), this.calMilliseconds(), this;
                if ("string" == typeof t2) {
                  var e2 = t2.match(a);
                  if (e2) {
                    var r2 = e2.slice(2).map(function(t3) {
                      return null != t3 ? Number(t3) : 0;
                    });
                    return this.$d.years = r2[0], this.$d.months = r2[1], this.$d.weeks = r2[2], this.$d.days = r2[3], this.$d.hours = r2[4], this.$d.minutes = r2[5], this.$d.seconds = r2[6], this.calMilliseconds(), this;
                  }
                }
                return this;
              }
              var y2 = l2.prototype;
              return y2.calMilliseconds = function() {
                var t2 = this;
                this.$ms = Object.keys(this.$d).reduce(function(s2, n2) {
                  return s2 + (t2.$d[n2] || 0) * h2[n2];
                }, 0);
              }, y2.parseFromMilliseconds = function() {
                var t2 = this.$ms;
                this.$d.years = $(t2 / u), t2 %= u, this.$d.months = $(t2 / d), t2 %= d, this.$d.days = $(t2 / r), t2 %= r, this.$d.hours = $(t2 / e), t2 %= e, this.$d.minutes = $(t2 / i2), t2 %= i2, this.$d.seconds = $(t2 / n), t2 %= n, this.$d.milliseconds = t2;
              }, y2.toISOString = function() {
                var t2 = v(this.$d.years, "Y"), s2 = v(this.$d.months, "M"), n2 = +this.$d.days || 0;
                this.$d.weeks && (n2 += 7 * this.$d.weeks);
                var i3 = v(n2, "D"), e2 = v(this.$d.hours, "H"), r2 = v(this.$d.minutes, "M"), o2 = this.$d.seconds || 0;
                this.$d.milliseconds && (o2 += this.$d.milliseconds / 1e3, o2 = Math.round(1e3 * o2) / 1e3);
                var u2 = v(o2, "S"), d2 = t2.negative || s2.negative || i3.negative || e2.negative || r2.negative || u2.negative, a2 = e2.format || r2.format || u2.format ? "T" : "", h3 = (d2 ? "-" : "") + "P" + t2.format + s2.format + i3.format + a2 + e2.format + r2.format + u2.format;
                return "P" === h3 || "-P" === h3 ? "P0D" : h3;
              }, y2.toJSON = function() {
                return this.toISOString();
              }, y2.format = function(t2) {
                var n2 = t2 || "YYYY-MM-DDTHH:mm:ss", i3 = { Y: this.$d.years, YY: s.s(this.$d.years, 2, "0"), YYYY: s.s(this.$d.years, 4, "0"), M: this.$d.months, MM: s.s(this.$d.months, 2, "0"), D: this.$d.days, DD: s.s(this.$d.days, 2, "0"), H: this.$d.hours, HH: s.s(this.$d.hours, 2, "0"), m: this.$d.minutes, mm: s.s(this.$d.minutes, 2, "0"), s: this.$d.seconds, ss: s.s(this.$d.seconds, 2, "0"), SSS: s.s(this.$d.milliseconds, 3, "0") };
                return n2.replace(o, function(t3, s2) {
                  return s2 || String(i3[t3]);
                });
              }, y2.as = function(t2) {
                return this.$ms / h2[m(t2)];
              }, y2.get = function(t2) {
                var s2 = this.$ms, n2 = m(t2);
                return "milliseconds" === n2 ? s2 %= 1e3 : s2 = "weeks" === n2 ? $(s2 / h2[n2]) : this.$d[n2], s2 || 0;
              }, y2.add = function(t2, s2, n2) {
                var i3;
                return i3 = s2 ? t2 * h2[m(s2)] : c(t2) ? t2.$ms : f(t2, this).$ms, f(this.$ms + i3 * (n2 ? -1 : 1), this);
              }, y2.subtract = function(t2, s2) {
                return this.add(t2, s2, true);
              }, y2.locale = function(t2) {
                var s2 = this.clone();
                return s2.$l = t2, s2;
              }, y2.clone = function() {
                return f(this.$ms, this);
              }, y2.humanize = function(s2) {
                return t().add(this.$ms, "ms").locale(this.$l).fromNow(!s2);
              }, y2.valueOf = function() {
                return this.asMilliseconds();
              }, y2.milliseconds = function() {
                return this.get("milliseconds");
              }, y2.asMilliseconds = function() {
                return this.as("milliseconds");
              }, y2.seconds = function() {
                return this.get("seconds");
              }, y2.asSeconds = function() {
                return this.as("seconds");
              }, y2.minutes = function() {
                return this.get("minutes");
              }, y2.asMinutes = function() {
                return this.as("minutes");
              }, y2.hours = function() {
                return this.get("hours");
              }, y2.asHours = function() {
                return this.as("hours");
              }, y2.days = function() {
                return this.get("days");
              }, y2.asDays = function() {
                return this.as("days");
              }, y2.weeks = function() {
                return this.get("weeks");
              }, y2.asWeeks = function() {
                return this.as("weeks");
              }, y2.months = function() {
                return this.get("months");
              }, y2.asMonths = function() {
                return this.as("months");
              }, y2.years = function() {
                return this.get("years");
              }, y2.asYears = function() {
                return this.as("years");
              }, l2;
            }(), p = function(t2, s2, n2) {
              return t2.add(s2.years() * n2, "y").add(s2.months() * n2, "M").add(s2.days() * n2, "d").add(s2.hours() * n2, "h").add(s2.minutes() * n2, "m").add(s2.seconds() * n2, "s").add(s2.milliseconds() * n2, "ms");
            };
            return function(n2, i3, e2) {
              t = e2, s = e2().$utils(), e2.duration = function(t2, s2) {
                var n3 = e2.locale();
                return f(t2, { $l: n3 }, s2);
              }, e2.isDuration = c;
              var r2 = i3.prototype.add, o2 = i3.prototype.subtract;
              i3.prototype.add = function(t2, s2) {
                return c(t2) ? p(this, t2, 1) : r2.bind(this)(t2, s2);
              }, i3.prototype.subtract = function(t2, s2) {
                return c(t2) ? p(this, t2, -1) : o2.bind(this)(t2, s2);
              };
            };
          });
        })(duration$2);
        return duration$2.exports;
      }
      var durationExports = requireDuration();
      const duration = /* @__PURE__ */ getDefaultExportFromCjs(durationExports);
      dayjs.extend(duration);
      const formatDate = (timestamp) => {
        if (!timestamp) return "";
        return dayjs(timestamp).format("YYYY-MM-DD");
      };
      const formatDuration = (minutes) => {
        if (!minutes) return "";
        const hours = Math.floor(minutes / 60);
        const remainingMinutes = minutes % 60;
        const parts = [];
        if (hours > 0) {
          parts.push(`${hours}小时`);
        }
        if (remainingMinutes > 0) {
          parts.push(`${remainingMinutes}分钟`);
        }
        return parts.join(" ");
      };
      const formatFileSize = (bytes) => {
        if (!bytes) return "未知";
        const units = ["B", "KB", "MB", "GB", "TB"];
        let size = bytes;
        let unitIndex = 0;
        while (size >= 1024 && unitIndex < units.length - 1) {
          size /= 1024;
          unitIndex++;
        }
        return `${size.toFixed(2)} ${units[unitIndex]}`;
      };
      const _hoisted_1$8 = {
        key: 0,
        class: "header-file"
      };
      const _hoisted_2$7 = {
        key: 1,
        class: "header-file"
      };
      const _hoisted_3$7 = {
        key: 2,
        class: "header-file"
      };
      const _hoisted_4$5 = { class: "header-file-text" };
      const _hoisted_5$5 = { class: "header-file-text-size" };
      const _sfc_main$8 = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          fileInfo: {}
        },
        setup(__props) {
          return (_ctx, _cache) => {
            var _a, _b, _c;
            return _ctx.fileInfo.error ? (openBlock(), createElementBlock("div", _hoisted_1$8, _cache[0] || (_cache[0] = [
              createElementVNode("div", { class: "header-file-error" }, [
                createElementVNode("span", null, "❌ 获取文件信息失败")
              ], -1)
            ]))) : _ctx.fileInfo.isLoading || !_ctx.fileInfo.isLoading && !_ctx.fileInfo.isReady ? (openBlock(), createElementBlock("div", _hoisted_2$7, [
              createVNode(Skeleton, {
                width: "320px",
                height: "28px"
              })
            ])) : (openBlock(), createElementBlock("div", _hoisted_3$7, [
              createElementVNode("span", _hoisted_4$5, [
                createTextVNode(toDisplayString((_b = (_a = _ctx.fileInfo.state) == null ? undefined : _a.file_name) == null ? undefined : _b.toUpperCase()) + " ", 1),
                createElementVNode("span", _hoisted_5$5, toDisplayString(unref(formatFileSize)(Number((_c = _ctx.fileInfo.state) == null ? undefined : _c.file_size))), 1)
              ])
            ]));
          };
        }
      });
      const FileInfo = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-708d094e"]]);
      const _hoisted_1$7 = { class: "footer-tags" };
      const _hoisted_2$6 = ["href"];
      const _hoisted_3$6 = ["href"];
      const _hoisted_4$4 = ["src"];
      const _hoisted_5$4 = {
        href: "https://github.com/cbingb666",
        target: "_blank"
      };
      const _hoisted_6$3 = ["src"];
      const _sfc_main$7 = /* @__PURE__ */ defineComponent({
        __name: "index",
        setup(__props) {
          const info = computed(() => {
            return {
              version: _GM_info.script.version,
              author: _GM_info.script.author,
              homepage: _GM_info.script.homepage
            };
          });
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("footer", null, [
              _cache[1] || (_cache[1] = createElementVNode("p", null, "如果觉得这个脚本爆赞 👍", -1)),
              _cache[2] || (_cache[2] = createElementVNode("p", null, [
                createTextVNode("请帮我点个 "),
                createElementVNode("a", {
                  href: "https://github.com/cbingb666/115Master",
                  target: "_blank"
                }, "⭐"),
                createTextVNode(" 支持我开发更多有趣的功能吧~")
              ], -1)),
              createElementVNode("div", _hoisted_1$7, [
                createElementVNode("a", {
                  href: info.value.homepage,
                  target: "_blank"
                }, _cache[0] || (_cache[0] = [
                  createElementVNode("img", {
                    src: `https://img.shields.io/badge/GitHub-115Master-yellow`,
                    alt: "GitHub"
                  }, null, -1)
                ]), 8, _hoisted_2$6),
                createElementVNode("a", {
                  href: `https://github.com/cbingb666/115Master/releases/tag/v${info.value.version}`,
                  target: "_blank"
                }, [
                  createElementVNode("img", {
                    src: `https://img.shields.io/badge/Version-${info.value.version.replace(/-/g, ".")}-green`,
                    alt: "Version"
                  }, null, 8, _hoisted_4$4)
                ], 8, _hoisted_3$6),
                createElementVNode("a", _hoisted_5$4, [
                  createElementVNode("img", {
                    src: `https://img.shields.io/badge/Author-${info.value.author}-red`,
                    alt: "Author"
                  }, null, 8, _hoisted_6$3)
                ])
              ])
            ]);
          };
        }
      });
      const Footer = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-c19dfa52"]]);
      const scriptRel = /* @__PURE__ */ function detectScriptRel() {
        const relList = typeof document !== "undefined" && document.createElement("link").relList;
        return relList && relList.supports && relList.supports("modulepreload") ? "modulepreload" : "preload";
      }();
      const assetsURL = function(dep) {
        return "/" + dep;
      };
      const seen = {};
      const __vitePreload = function preload(baseModule, deps, importerUrl) {
        let promise = Promise.resolve();
        if (deps && deps.length > 0) {
          document.getElementsByTagName("link");
          const cspNonceMeta = document.querySelector(
            "meta[property=csp-nonce]"
          );
          const cspNonce = (cspNonceMeta == null ? undefined : cspNonceMeta.nonce) || (cspNonceMeta == null ? undefined : cspNonceMeta.getAttribute("nonce"));
          promise = Promise.allSettled(
            deps.map((dep) => {
              dep = assetsURL(dep);
              if (dep in seen) return;
              seen[dep] = true;
              const isCss = dep.endsWith(".css");
              const cssSelector = isCss ? '[rel="stylesheet"]' : "";
              if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) {
                return;
              }
              const link = document.createElement("link");
              link.rel = isCss ? "stylesheet" : scriptRel;
              if (!isCss) {
                link.as = "script";
              }
              link.crossOrigin = "";
              link.href = dep;
              if (cspNonce) {
                link.setAttribute("nonce", cspNonce);
              }
              document.head.appendChild(link);
              if (isCss) {
                return new Promise((res, rej) => {
                  link.addEventListener("load", res);
                  link.addEventListener(
                    "error",
                    () => rej(new Error(`Unable to preload CSS for ${dep}`))
                  );
                });
              }
            })
          );
        }
        function handlePreloadError(err) {
          const e = new Event("vite:preloadError", {
            cancelable: true
          });
          e.payload = err;
          window.dispatchEvent(e);
          if (!e.defaultPrevented) {
            throw err;
          }
        }
        return promise.then((res) => {
          for (const item of res || []) {
            if (item.status !== "rejected") continue;
            handlePreloadError(item.reason);
          }
          return baseModule().catch(handlePreloadError);
        });
      };
      const _hoisted_1$6 = { class: "loading-error" };
      const _hoisted_2$5 = { class: "loading-error-text" };
      const _hoisted_3$5 = { class: "loading-error-detail" };
      const defaultMessage = "加载失败";
      const _sfc_main$6 = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          retryable: { type: Boolean },
          message: {},
          detail: {},
          retryText: {}
        },
        emits: ["retry"],
        setup(__props) {
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", _hoisted_1$6, [
              _cache[1] || (_cache[1] = createElementVNode("svg", {
                class: "loading-error-icon",
                viewBox: "0 0 24 24",
                xmlns: "http://www.w3.org/2000/svg"
              }, [
                createElementVNode("circle", {
                  class: "loading-error-circle",
                  cx: "12",
                  cy: "12",
                  r: "10",
                  fill: "none",
                  stroke: "currentColor",
                  "stroke-width": "2"
                }),
                createElementVNode("path", {
                  class: "loading-error-cross",
                  d: "M8 8L16 16M8 16L16 8",
                  stroke: "currentColor",
                  "stroke-width": "2",
                  "stroke-linecap": "round"
                })
              ], -1)),
              createElementVNode("span", _hoisted_2$5, [
                renderSlot(_ctx.$slots, "default", {}, () => [
                  createTextVNode(toDisplayString(_ctx.message || defaultMessage), 1)
                ], true)
              ]),
              createElementVNode("span", _hoisted_3$5, toDisplayString(_ctx.detail), 1),
              _ctx.retryable ? (openBlock(), createElementBlock("button", {
                key: 0,
                class: "loading-error-retry",
                onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("retry"))
              }, toDisplayString(_ctx.retryText), 1)) : createCommentVNode("", true)
            ]);
          };
        }
      });
      const LoadingError = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-c2d74d07"]]);
      const _hoisted_1$5 = { class: "empty" };
      const _hoisted_2$4 = {
        key: 0,
        class: "empty-image"
      };
      const _hoisted_3$4 = ["src"];
      const _hoisted_4$3 = { class: "empty-description" };
      const _hoisted_5$3 = {
        key: 1,
        class: "empty-footer"
      };
      const _sfc_main$5 = /* @__PURE__ */ defineComponent({
        __name: "Empty",
        props: {
          description: { default: "暂无数据" },
          image: { default: "" },
          imageSize: { default: 100 },
          showImage: { type: Boolean, default: true }
        },
        setup(__props) {
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", _hoisted_1$5, [
              _ctx.showImage ? (openBlock(), createElementBlock("div", _hoisted_2$4, [
                _ctx.image ? (openBlock(), createElementBlock("img", {
                  key: 0,
                  src: _ctx.image,
                  style: normalizeStyle({ width: `${_ctx.imageSize}px` })
                }, null, 12, _hoisted_3$4)) : (openBlock(), createElementBlock("svg", {
                  key: 1,
                  style: normalizeStyle({ width: `${_ctx.imageSize}px`, height: `${_ctx.imageSize}px` }),
                  viewBox: "0 0 184 152",
                  xmlns: "http://www.w3.org/2000/svg"
                }, _cache[0] || (_cache[0] = [
                  createStaticVNode('<g fill="none" fill-rule="evenodd" data-v-a47b59ec><g transform="translate(24 31.67)" data-v-a47b59ec><ellipse fill-opacity=".8" fill="#F5F5F7" cx="67.797" cy="106.89" rx="67.797" ry="12.668" data-v-a47b59ec></ellipse><path d="M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z" fill="#AEB8C2" data-v-a47b59ec></path><path d="M101.537 86.214L80.63 61.102c-1.001-1.207-2.507-1.867-4.048-1.867H31.724c-1.54 0-3.047.66-4.048 1.867L6.769 86.214v13.792h94.768V86.214z" fill="url(#linearGradient-1)" transform="translate(13.56)" data-v-a47b59ec></path><path d="M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z" fill="#F5F5F7" data-v-a47b59ec></path><path d="M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z" fill="#DCE0E6" data-v-a47b59ec></path></g><path d="M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z" fill="#DCE0E6" data-v-a47b59ec></path><g transform="translate(149.65 15.383)" fill="#FFF" data-v-a47b59ec><ellipse cx="20.654" cy="3.167" rx="2.849" ry="2.815" data-v-a47b59ec></ellipse><path d="M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z" data-v-a47b59ec></path></g></g>', 1)
                ]), 4))
              ])) : createCommentVNode("", true),
              createElementVNode("div", _hoisted_4$3, toDisplayString(_ctx.description), 1),
              _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_5$3, [
                renderSlot(_ctx.$slots, "default", {}, undefined, true)
              ])) : createCommentVNode("", true)
            ]);
          };
        }
      });
      const Empty = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-a47b59ec"]]);
      function useCopy(duration2 = 2e3) {
        const isCopied = ref(false);
        const copyText = async (text) => {
          if (!text) return;
          try {
            await navigator.clipboard.writeText(text);
            isCopied.value = true;
            setTimeout(() => {
              isCopied.value = false;
            }, duration2);
          } catch (err) {
            console.error("复制失败:", err);
            throw err;
          }
        };
        return {
          isCopied,
          copyText
        };
      }
      const _hoisted_1$4 = { class: "copy-button-text" };
      const _sfc_main$4 = /* @__PURE__ */ defineComponent({
        __name: "CopyButton",
        props: {
          text: {},
          duration: {}
        },
        setup(__props) {
          const props = __props;
          const { isCopied, copyText } = useCopy(props.duration);
          const handleCopy = async () => {
            try {
              await copyText(props.text);
            } catch (error) {
            }
          };
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("button", {
              class: normalizeClass(["copy-button", { copied: unref(isCopied) }]),
              onClick: handleCopy
            }, [
              createElementVNode("span", _hoisted_1$4, toDisplayString(unref(isCopied) ? "已复制" : "复制"), 1)
            ], 2);
          };
        }
      });
      const CopyButton = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-a529d9a0"]]);
      const _hoisted_1$3 = { class: "movie-info" };
      const _hoisted_2$3 = { class: "movie-info-main" };
      const _hoisted_3$3 = { class: "movie-info-source-switch" };
      const _hoisted_4$2 = { class: "movie-info-header" };
      const _hoisted_5$2 = { class: "movie-info-header-title" };
      const _hoisted_6$2 = { class: "movie-info-header-actors" };
      const _hoisted_7$2 = { class: "movie-info-header-actors-item-content" };
      const _hoisted_8 = { class: "movie-info-header-actors-item-avatar" };
      const _hoisted_9 = {
        class: "movie-info-content",
        style: { "margin-top": "24px" }
      };
      const _hoisted_10 = { class: "movie-info-header-title" };
      const _hoisted_11 = { class: "movie-info-header-title-text" };
      const _hoisted_12 = { class: "movie-info-header-actors" };
      const _hoisted_13 = ["href"];
      const _hoisted_14 = { class: "movie-info-header-actors-item-avatar" };
      const _hoisted_15 = ["src", "alt"];
      const _hoisted_16 = { class: "movie-info-header-actors-item-name" };
      const _hoisted_17 = {
        key: 1,
        class: "movie-info-header-actors-item-content"
      };
      const _hoisted_18 = { class: "movie-info-header-actors-item-avatar" };
      const _hoisted_19 = ["src", "alt"];
      const _hoisted_20 = { class: "movie-info-header-actors-item-name" };
      const _hoisted_21 = { class: "movie-info-content" };
      const _hoisted_22 = { class: "movie-info-content-item" };
      const _hoisted_23 = { class: "movie-info-content-item-value" };
      const _hoisted_24 = ["href"];
      const _hoisted_25 = { class: "movie-info-content-item" };
      const _hoisted_26 = { class: "movie-info-content-item-value" };
      const _hoisted_27 = { class: "movie-info-content-item" };
      const _hoisted_28 = { class: "movie-info-content-item-value" };
      const _hoisted_29 = { class: "movie-info-content-item" };
      const _hoisted_30 = {
        key: 0,
        class: "movie-info-content-item-value"
      };
      const _hoisted_31 = {
        key: 1,
        class: "movie-info-content-item-value"
      };
      const _hoisted_32 = ["href"];
      const _hoisted_33 = { class: "movie-info-content-item" };
      const _hoisted_34 = {
        key: 0,
        class: "movie-info-content-item-value"
      };
      const _hoisted_35 = {
        key: 1,
        class: "movie-info-content-item-value"
      };
      const _hoisted_36 = ["href"];
      const _hoisted_37 = { class: "movie-info-content-item" };
      const _hoisted_38 = {
        key: 0,
        class: "movie-info-content-item-value"
      };
      const _hoisted_39 = {
        key: 1,
        class: "movie-info-content-item-value"
      };
      const _hoisted_40 = ["href"];
      const _hoisted_41 = { class: "movie-info-content-item" };
      const _hoisted_42 = {
        key: 0,
        class: "movie-info-content-item-value"
      };
      const _hoisted_43 = {
        key: 1,
        class: "movie-info-content-item-value"
      };
      const _hoisted_44 = ["href"];
      const _hoisted_45 = ["href"];
      const _hoisted_46 = ["src"];
      const DEFAULT_AVATAR = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2NjYyI+PHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6bTAgM2MxLjY2IDAgMyAxLjM0IDMgM3MtMS4zNCAzLTMgMy0zLTEuMzQtMy0zIDEuMzQtMyAzLTN6bTAgMTQuMmMtMi41IDAtNC43MS0xLjI4LTYtMy4yMi4wMy0xLjk5IDQtMy4wOCA2LTMuMDggMS45OSAwIDUuOTcgMS4wOSA2IDMuMDgtMS4yOSAxLjk0LTMuNSAzLjIyLTYgMy4yMnoiLz48L3N2Zz4=";
      const _sfc_main$3 = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          movieInfos: {}
        },
        setup(__props) {
          const props = __props;
          const movieInfoThumb = ref(null);
          const lightbox = ref(null);
          const activeSource = ref("javDBState");
          const movieInfo = computed(
            () => {
              return props.movieInfos[activeSource.value];
            }
          );
          watch(movieInfoThumb, async () => {
            var _a;
            if (!movieInfoThumb.value) return;
            (_a = lightbox.value) == null ? undefined : _a.destroy();
            await nextTick();
            lightbox.value = new PhotoSwipeLightbox({
              gallery: movieInfoThumb.value,
              children: ".movie-info-thumb-item",
              pswpModule: () => __vitePreload(() => module.import('photoswipe'), void 0 ),
              mouseMovePan: true,
              initialZoomLevel: "fit",
              wheelToZoom: true
            });
            lightbox.value.init();
            lightbox.value.addFilter("domItemData", (itemData, element) => {
              var _a2, _b;
              itemData.width = (_a2 = element.querySelector("img")) == null ? undefined : _a2.naturalWidth;
              itemData.height = (_b = element.querySelector("img")) == null ? undefined : _b.naturalHeight;
              return itemData;
            });
          });
          return (_ctx, _cache) => {
            var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
            return openBlock(), createElementBlock("div", _hoisted_1$3, [
              createElementVNode("div", _hoisted_2$3, [
                createElementVNode("div", _hoisted_3$3, [
                  createElementVNode("div", {
                    class: normalizeClass(["movie-info-source-switch-item", { active: activeSource.value === "javDBState" }]),
                    onClick: _cache[0] || (_cache[0] = ($event) => activeSource.value = "javDBState")
                  }, _cache[2] || (_cache[2] = [
                    createElementVNode("span", { class: "movie-info-source-switch-item-text" }, "JavDB", -1)
                  ]), 2),
                  createElementVNode("div", {
                    class: normalizeClass(["movie-info-source-switch-item", { active: activeSource.value === "javBusState" }]),
                    onClick: _cache[1] || (_cache[1] = ($event) => activeSource.value = "javBusState")
                  }, _cache[3] || (_cache[3] = [
                    createElementVNode("span", { class: "movie-info-source-switch-item-text" }, "JavBus", -1)
                  ]), 2)
                ]),
                movieInfo.value.error.value ? (openBlock(), createBlock(LoadingError, {
                  key: 0,
                  style: { "margin": "80px auto 40px" },
                  message: "获取影片信息失败,可能由于网络异常或者您没有科学上网",
                  detail: movieInfo.value.error.value.toString()
                }, null, 8, ["detail"])) : movieInfo.value.isLoading.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
                  createElementVNode("div", _hoisted_4$2, [
                    createElementVNode("div", _hoisted_5$2, [
                      createVNode(Skeleton, {
                        width: "80%",
                        height: "56px"
                      })
                    ])
                  ]),
                  createElementVNode("div", _hoisted_6$2, [
                    (openBlock(), createElementBlock(Fragment, null, renderList(1, (i2) => {
                      return createElementVNode("div", {
                        class: "movie-info-header-actors-item",
                        key: i2
                      }, [
                        createElementVNode("div", _hoisted_7$2, [
                          createElementVNode("div", _hoisted_8, [
                            createVNode(Skeleton, {
                              circle: "",
                              width: "60px",
                              height: "60px"
                            })
                          ]),
                          createVNode(Skeleton, {
                            width: "100px",
                            height: "22.5px"
                          })
                        ])
                      ]);
                    }), 64))
                  ]),
                  createElementVNode("div", _hoisted_9, [
                    (openBlock(), createElementBlock(Fragment, null, renderList(7, (i2) => {
                      return createElementVNode("div", {
                        class: "movie-info-content-item",
                        key: i2
                      }, [
                        createVNode(Skeleton, {
                          width: `${80 + Math.random() * 80}px`,
                          height: "20px"
                        }, null, 8, ["width"])
                      ]);
                    }), 64))
                  ])
                ], 64)) : !movieInfo.value.state.value ? (openBlock(), createBlock(Empty, {
                  key: 2,
                  style: { "margin": "80px auto 40px" },
                  description: "暂无影片信息,可能番号无法识别",
                  "image-size": 200
                })) : (openBlock(), createElementBlock(Fragment, { key: 3 }, [
                  (openBlock(), createElementBlock("div", {
                    class: "movie-info-header",
                    key: activeSource.value
                  }, [
                    createElementVNode("div", _hoisted_10, [
                      createElementVNode("span", _hoisted_11, toDisplayString((_a = movieInfo.value.state.value) == null ? undefined : _a.title), 1)
                    ]),
                    createElementVNode("div", _hoisted_12, [
                      (openBlock(true), createElementBlock(Fragment, null, renderList((_b = movieInfo.value.state.value) == null ? undefined : _b.actors, (actor) => {
                        return openBlock(), createElementBlock("div", {
                          class: "movie-info-header-actors-item",
                          key: actor.name
                        }, [
                          actor.url ? (openBlock(), createElementBlock("a", {
                            key: 0,
                            class: "movie-info-header-actors-item-content",
                            href: actor.url,
                            target: "_blank"
                          }, [
                            createElementVNode("div", _hoisted_14, [
                              createElementVNode("img", {
                                src: actor.face || DEFAULT_AVATAR,
                                alt: actor.name
                              }, null, 8, _hoisted_15),
                              actor.sex !== undefined ? (openBlock(), createElementBlock("span", {
                                key: 0,
                                class: normalizeClass(["movie-info-header-actors-item-sex", { female: actor.sex === 1, male: actor.sex === 0 }])
                              }, toDisplayString(actor.sex === 1 ? "♀" : "♂"), 3)) : createCommentVNode("", true)
                            ]),
                            createElementVNode("span", _hoisted_16, toDisplayString(actor.name), 1)
                          ], 8, _hoisted_13)) : (openBlock(), createElementBlock("div", _hoisted_17, [
                            createElementVNode("div", _hoisted_18, [
                              createElementVNode("img", {
                                src: actor.face || DEFAULT_AVATAR,
                                alt: actor.name
                              }, null, 8, _hoisted_19),
                              actor.sex !== undefined ? (openBlock(), createElementBlock("span", {
                                key: 0,
                                class: normalizeClass(["movie-info-header-actors-item-sex", { female: actor.sex === 1, male: actor.sex === 0 }])
                              }, toDisplayString(actor.sex === 1 ? "♀" : "♂"), 3)) : createCommentVNode("", true)
                            ]),
                            createElementVNode("span", _hoisted_20, toDisplayString(actor.name), 1)
                          ]))
                        ]);
                      }), 128))
                    ])
                  ])),
                  createElementVNode("div", _hoisted_21, [
                    createElementVNode("div", _hoisted_22, [
                      _cache[4] || (_cache[4] = createElementVNode("span", { class: "movie-info-content-item-label" }, " 番号: ", -1)),
                      createElementVNode("span", _hoisted_23, [
                        createElementVNode("a", {
                          href: (_c = movieInfo.value.state.value) == null ? undefined : _c.url,
                          target: "_blank"
                        }, toDisplayString(((_d = movieInfo.value.state.value) == null ? undefined : _d.avNumber) ?? "-"), 9, _hoisted_24),
                        ((_e = movieInfo.value.state.value) == null ? undefined : _e.avNumber) ? (openBlock(), createBlock(CopyButton, {
                          key: 0,
                          text: (_f = movieInfo.value.state.value) == null ? undefined : _f.avNumber
                        }, null, 8, ["text"])) : createCommentVNode("", true)
                      ])
                    ]),
                    createElementVNode("div", _hoisted_25, [
                      _cache[5] || (_cache[5] = createElementVNode("span", { class: "movie-info-content-item-label" }, " 日期: ", -1)),
                      createElementVNode("span", _hoisted_26, toDisplayString(unref(formatDate)((_g = movieInfo.value.state.value) == null ? undefined : _g.date) ?? "-"), 1)
                    ]),
                    createElementVNode("div", _hoisted_27, [
                      _cache[6] || (_cache[6] = createElementVNode("span", { class: "movie-info-content-item-label" }, " 时长: ", -1)),
                      createElementVNode("span", _hoisted_28, toDisplayString(unref(formatDuration)((_h = movieInfo.value.state.value) == null ? undefined : _h.duration) ?? "-"), 1)
                    ]),
                    createElementVNode("div", _hoisted_29, [
                      _cache[7] || (_cache[7] = createElementVNode("span", { class: "movie-info-content-item-label" }, " 导演: ", -1)),
                      !((_i = movieInfo.value.state.value) == null ? undefined : _i.director) ? (openBlock(), createElementBlock("span", _hoisted_30, "-")) : (openBlock(), createElementBlock("span", _hoisted_31, [
                        (openBlock(true), createElementBlock(Fragment, null, renderList((_j = movieInfo.value.state.value) == null ? undefined : _j.director, (director) => {
                          return openBlock(), createElementBlock("a", {
                            key: director.name,
                            href: director.url,
                            target: "_blank"
                          }, toDisplayString(director.name), 9, _hoisted_32);
                        }), 128))
                      ]))
                    ]),
                    createElementVNode("div", _hoisted_33, [
                      _cache[8] || (_cache[8] = createElementVNode("span", { class: "movie-info-content-item-label" }, " 片商: ", -1)),
                      !((_k = movieInfo.value.state.value) == null ? undefined : _k.studio) ? (openBlock(), createElementBlock("span", _hoisted_34, "-")) : (openBlock(), createElementBlock("span", _hoisted_35, [
                        (openBlock(true), createElementBlock(Fragment, null, renderList((_l = movieInfo.value.state.value) == null ? undefined : _l.studio, (studio) => {
                          return openBlock(), createElementBlock("a", {
                            key: studio.name,
                            href: studio.url,
                            target: "_blank"
                          }, toDisplayString(studio.name), 9, _hoisted_36);
                        }), 128))
                      ]))
                    ]),
                    createElementVNode("div", _hoisted_37, [
                      _cache[9] || (_cache[9] = createElementVNode("span", { class: "movie-info-content-item-label" }, " 系列: ", -1)),
                      !((_m = movieInfo.value.state.value) == null ? undefined : _m.series) ? (openBlock(), createElementBlock("span", _hoisted_38, "-")) : (openBlock(), createElementBlock("span", _hoisted_39, [
                        (openBlock(true), createElementBlock(Fragment, null, renderList((_n = movieInfo.value.state.value) == null ? undefined : _n.series, (serie) => {
                          return openBlock(), createElementBlock("a", {
                            key: serie.name,
                            href: serie.url,
                            target: "_blank"
                          }, toDisplayString(serie.name), 9, _hoisted_40);
                        }), 128))
                      ]))
                    ]),
                    createElementVNode("div", _hoisted_41, [
                      _cache[10] || (_cache[10] = createElementVNode("span", { class: "movie-info-content-item-label" }, " 类别: ", -1)),
                      !((_o = movieInfo.value.state.value) == null ? undefined : _o.category) ? (openBlock(), createElementBlock("span", _hoisted_42, "-")) : (openBlock(), createElementBlock("span", _hoisted_43, [
                        (openBlock(true), createElementBlock(Fragment, null, renderList((_p = movieInfo.value.state.value) == null ? undefined : _p.category, (category) => {
                          return openBlock(), createElementBlock("a", {
                            key: category.name,
                            href: category.url,
                            target: "_blank"
                          }, toDisplayString(category.name), 9, _hoisted_44);
                        }), 128))
                      ]))
                    ])
                  ]),
                  createElementVNode("div", {
                    class: "movie-info-thumb",
                    ref_key: "movieInfoThumb",
                    ref: movieInfoThumb
                  }, [
                    (openBlock(true), createElementBlock(Fragment, null, renderList((_q = movieInfo.value.state.value) == null ? undefined : _q.preview, (item, index) => {
                      return openBlock(), createElementBlock("a", {
                        class: "movie-info-thumb-item",
                        key: item.thumbnail,
                        href: item.raw,
                        target: "_blank"
                      }, [
                        createElementVNode("img", {
                          src: item.raw,
                          alt: "thumb"
                        }, null, 8, _hoisted_46)
                      ], 8, _hoisted_45);
                    }), 128))
                  ], 512)
                ], 64))
              ])
            ]);
          };
        }
      });
      const MovieInfo = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-54ae4cd9"]]);
      const _hoisted_1$2 = { class: "playlist" };
      const _hoisted_2$2 = {
        key: 0,
        class: "playlist-list"
      };
      const _hoisted_3$2 = {
        key: 1,
        class: "playlist-list"
      };
      const _hoisted_4$1 = {
        key: 2,
        class: "playlist-list"
      };
      const _hoisted_5$1 = ["onClick"];
      const _hoisted_6$1 = { class: "playlist-item-title" };
      const _hoisted_7$1 = { class: "playlist-item-size" };
      const _sfc_main$2 = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          playlist: {},
          pickCode: {}
        },
        emits: ["play"],
        setup(__props, { emit: __emit }) {
          const props = __props;
          const emit = __emit;
          const handlePlay = (item) => {
            if (item.pc === props.pickCode) {
              return;
            }
            emit("play", item);
          };
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", _hoisted_1$2, [
              _cache[0] || (_cache[0] = createElementVNode("div", { class: "playlist-header" }, " 播放列表 ", -1)),
              _ctx.playlist.error ? (openBlock(), createElementBlock("div", _hoisted_2$2, [
                createVNode(LoadingError)
              ])) : _ctx.playlist.isLoading || !_ctx.playlist.isLoading && !_ctx.playlist.isReady ? (openBlock(), createElementBlock("div", _hoisted_3$2, [
                (openBlock(), createElementBlock(Fragment, null, renderList(1, (i2) => {
                  return createVNode(Skeleton, {
                    width: "100%",
                    height: "60.5px",
                    "border-radius": "8px",
                    key: i2
                  });
                }), 64))
              ])) : (openBlock(), createElementBlock("div", _hoisted_4$1, [
                (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.playlist.state, (item) => {
                  return openBlock(), createElementBlock("div", {
                    class: normalizeClass(["playlist-item", { active: item.pc === _ctx.pickCode }]),
                    key: item.pc,
                    onClick: ($event) => handlePlay(item)
                  }, [
                    createElementVNode("div", _hoisted_6$1, toDisplayString(item.n), 1),
                    createElementVNode("div", _hoisted_7$1, toDisplayString(unref(formatFileSize)(item.s)), 1)
                  ], 10, _hoisted_5$1);
                }), 128))
              ]))
            ]);
          };
        }
      });
      const Playlist = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-1718588c"]]);
      const useDataFileInfo = () => {
        const fileInfo = useAsyncState(
          async (pickCode) => {
            const response = await Drive115Instance.getFileInfo({
              pickcode: pickCode,
              share_id: "0",
              local: "1"
            });
            return response;
          },
          {},
          {
            immediate: false
          }
        );
        return reactive(fileInfo);
      };
      var JAV_SOURCE = /* @__PURE__ */ ((JAV_SOURCE2) => {
        JAV_SOURCE2["JAVBUS"] = "JavBus";
        JAV_SOURCE2["JAVDB"] = "JavDB";
        return JAV_SOURCE2;
      })(JAV_SOURCE || {});
      const _Jav = class _Jav {
        constructor(iRequest) {
          this.iRequest = iRequest;
        }
        // 解析番号信息
        async parseInfo(html) {
          var _a, _b, _c, _d, _e;
          let dom = new DOMParser().parseFromString(html, "text/html");
          try {
            dom = await this.parseInfoBefore(dom);
          } catch (e) {
            return undefined;
          }
          const info = {
            source: this.source,
            url: this.url,
            avNumber: this.parseAvNumber(dom),
            title: this.parseTitle(dom),
            date: this.parseDate(dom),
            duration: this.parseDuration(dom),
            director: this.parseDirector(dom),
            actors: this.parseActor(dom),
            studio: this.parseStudio(dom),
            publisher: this.parsePublisher(dom),
            cover: this.parseCover(dom),
            preview: this.parsePreview(dom),
            series: this.parseSeries(dom),
            category: this.parseCategory(dom),
            score: (_a = this.parseScore) == null ? undefined : _a.call(this, dom),
            scoreCount: (_b = this.parseScoreCount) == null ? undefined : _b.call(this, dom),
            viewCount: (_c = this.parseViewCount) == null ? undefined : _c.call(this, dom),
            downloadCount: (_d = this.parseDownloadCount) == null ? undefined : _d.call(this, dom),
            comments: (_e = this.parseComments) == null ? undefined : _e.call(this, dom)
          };
          return this.parseInfoAfter(info);
        }
        // 解析番号信息后
        async parseInfoBefore(dom) {
          return dom;
        }
        // 解析番号信息后
        async parseInfoAfter(info) {
          return Promise.resolve(info);
        }
      };
      _Jav.PAGE_ERROR = new Error("请求页面错误");
      let Jav = _Jav;
      class JavBus extends Jav {
        constructor() {
          super(...arguments);
          this.source = JAV_SOURCE.JAVBUS;
          this.baseUrl = "https://www.javbus.com";
          this.url = "";
          this.labels = {};
        }
        async getInfoByAvNumber(avNumber) {
          const url = new URL(avNumber, this.baseUrl).href;
          this.url = url;
          const html = await this.iRequest.get(url);
          return await this.parseInfo(html.data);
        }
        async parseInfoBefore(dom) {
          const errorPage = dom.querySelector(".error-page");
          if (errorPage) {
            throw Jav.PAGE_ERROR;
          }
          const labels = this.getLabels(dom);
          this.labels = labels;
          return dom;
        }
        async parseInfoAfter(info) {
          var _a;
          return {
            ...info,
            title: (_a = info.title) == null ? undefined : _a.replace(new RegExp(`^${info.avNumber}`, "i"), "").trim()
          };
        }
        getLabels(dom) {
          const headers = dom.querySelectorAll(
            ".container .movie .info p > span.header, .container .movie .info p.header"
          );
          return Object.fromEntries(
            Array.from(headers).map((i2) => {
              var _a;
              return [
                (_a = i2.textContent) == null ? undefined : _a.replace(":", "").trim(),
                i2
              ];
            })
          );
        }
        parseAvNumber() {
          var _a, _b, _c;
          return ((_c = (_b = (_a = this.labels["識別碼"]) == null ? undefined : _a.nextElementSibling) == null ? undefined : _b.textContent) == null ? undefined : _c.trim()) ?? "";
        }
        parseTitle(dom) {
          var _a, _b;
          const title = (_b = (_a = dom.querySelector(".container h3")) == null ? undefined : _a.textContent) == null ? undefined : _b.trim();
          return title;
        }
        parseDate() {
          var _a, _b;
          const date = (_b = (_a = this.labels["發行日期"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.textContent;
          return date ? dayjs(date.trim().replace(/[^\d-]/g, "")).valueOf() : undefined;
        }
        parseDuration() {
          var _a, _b;
          const duration2 = (_b = (_a = this.labels["長度"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.textContent;
          return duration2 ? Number(duration2.trim().replace(/[^\d]/g, "")) : undefined;
        }
        parseDirector() {
          var _a, _b;
          const directors = (_b = (_a = this.labels["導演"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelectorAll("a");
          return (directors == null ? undefined : directors.length) ? Array.from(directors).map((i2) => ({
            name: i2.textContent,
            url: i2.getAttribute("href") ?? undefined
          })) : undefined;
        }
        parseActor() {
          var _a, _b, _c;
          const actors = (_c = (_b = (_a = this.labels["演員"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.nextElementSibling) == null ? undefined : _c.querySelectorAll(
            "li"
          );
          return (actors == null ? undefined : actors.length) ? Array.from(actors).map((i2) => {
            const a = i2.querySelector("a");
            const img = i2.querySelector("img");
            return {
              name: (img == null ? undefined : img.getAttribute("title")) ?? "",
              url: (a == null ? undefined : a.getAttribute("href")) ?? undefined,
              sex: undefined,
              face: ""
            };
          }) : undefined;
        }
        parseStudio() {
          var _a, _b;
          const studios = (_b = (_a = this.labels["製作商"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelectorAll("a");
          return (studios == null ? undefined : studios.length) ? Array.from(studios).map((i2) => ({
            name: i2.textContent,
            url: i2.getAttribute("href") ?? undefined
          })) : undefined;
        }
        parsePublisher() {
          var _a, _b;
          const publishers = (_b = (_a = this.labels["發行商"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelectorAll("a");
          return (publishers == null ? undefined : publishers.length) ? Array.from(publishers).map((i2) => ({
            name: i2.textContent,
            url: i2.getAttribute("href") ?? undefined
          })) : undefined;
        }
        parseCover(dom) {
          var _a;
          const cover = (_a = dom.querySelector(".container .bigImage img")) == null ? undefined : _a.getAttribute("src");
          return cover ? new URL(cover, this.baseUrl).href : undefined;
        }
        parsePreview(dom) {
          const previews = dom.querySelectorAll("#sample-waterfall a");
          return previews.length ? Array.from(previews).map((preview) => {
            var _a;
            return {
              raw: preview.getAttribute("href") ?? undefined,
              thumbnail: ((_a = preview.querySelector("img")) == null ? undefined : _a.getAttribute("src")) ?? undefined
            };
          }).filter((i2) => !!i2.raw || !!i2.thumbnail).map((i2) => {
            return {
              raw: i2.raw,
              thumbnail: i2.thumbnail ? new URL(i2.thumbnail, this.baseUrl).href : undefined
            };
          }) : undefined;
        }
        parseSeries() {
          var _a, _b;
          const series = (_b = (_a = this.labels["系列"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelectorAll("a");
          return (series == null ? undefined : series.length) ? Array.from(series).map((i2) => ({
            name: i2.textContent,
            url: i2.getAttribute("href") ?? undefined
          })) : undefined;
        }
        parseCategory() {
          var _a, _b;
          const categories = (_b = (_a = this.labels["類別"]) == null ? undefined : _a.nextElementSibling) == null ? undefined : _b.querySelectorAll("a");
          return (categories == null ? undefined : categories.length) ? Array.from(categories).map((i2) => ({
            name: i2.textContent,
            url: i2.getAttribute("href") ?? undefined
          })) : undefined;
        }
        parseComments() {
          return [];
        }
      }
      class JavDB extends Jav {
        constructor() {
          super(...arguments);
          this.source = JAV_SOURCE.JAVDB;
          this.baseUrl = "https://javdb.com";
          this.url = "";
          this.labels = {};
        }
        async getInfoByAvNumber(avNumber) {
          const params = new URLSearchParams({
            q: avNumber
          });
          const url = new URL(`/search?${params.toString()}`, this.baseUrl).href;
          const html = await this.iRequest.get(url, {
            responseType: "document"
          }).then((res) => {
            console.log("javdb search response", res);
            return res.rawResponse.responseText;
          }).catch((error) => {
            console.error(error);
            throw error;
          });
          const avNumberPageUrl = this.getAvNumberPageUrl(html);
          if (!avNumberPageUrl) {
            throw Jav.PAGE_ERROR;
          }
          this.url = avNumberPageUrl;
          const avNumberPageResponse = await this.iRequest.get(avNumberPageUrl, {
            responseType: "document"
          }).then((res) => {
            return res.rawResponse.responseText;
          }).catch((error) => {
            throw error;
          });
          return await this.parseInfo(avNumberPageResponse);
        }
        getAvNumberPageUrl(html) {
          var _a;
          const dom = new DOMParser().parseFromString(html, "text/html");
          const page = (_a = dom.querySelector(".movie-list .item a")) == null ? undefined : _a.getAttribute("href");
          return page ? new URL(page, this.baseUrl).href : undefined;
        }
        async parseInfoBefore(dom) {
          const labels = this.getLabels(dom);
          this.labels = labels;
          return dom;
        }
        getLabels(dom) {
          const headers = dom.querySelectorAll(".container .panel-block strong");
          return Object.fromEntries(
            Array.from(headers).map((i2) => {
              var _a;
              return [
                (_a = i2.textContent) == null ? undefined : _a.replace(":", "").trim(),
                i2
              ];
            })
          );
        }
        parseAvNumber() {
          var _a, _b, _c, _d;
          const avNumber = (_d = (_c = (_b = (_a = this.labels["番號"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelector(".value")) == null ? undefined : _c.textContent) == null ? undefined : _d.trim();
          return avNumber ?? undefined;
        }
        parseTitle(dom) {
          var _a, _b;
          const title = (_b = (_a = dom.querySelector(".current-title")) == null ? undefined : _a.textContent) == null ? undefined : _b.trim();
          return title ?? undefined;
        }
        parseDate() {
          var _a, _b, _c, _d;
          const date = (_d = (_c = (_b = (_a = this.labels["日期"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelector(".value")) == null ? undefined : _c.textContent) == null ? undefined : _d.trim();
          return date ? dayjs(date.replace(/[^\d-]/g, "")).valueOf() : 0;
        }
        parseDuration() {
          var _a, _b, _c, _d;
          const duration2 = (_d = (_c = (_b = (_a = this.labels["時長"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelector(".value")) == null ? undefined : _c.textContent) == null ? undefined : _d.trim();
          return duration2 ? Number(duration2.replace(/[^\d]/g, "")) : 0;
        }
        parseDirector() {
          var _a, _b;
          const directors = (_b = (_a = this.labels["導演"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelectorAll(".value a");
          return (directors == null ? undefined : directors.length) ? Array.from(directors).map((i2) => ({
            name: i2.textContent,
            url: i2.getAttribute("href") ?? undefined
          })).map((i2) => ({
            ...i2,
            url: i2.url ? new URL(i2.url, this.baseUrl).href : undefined
          })) : undefined;
        }
        parseActor() {
          var _a, _b;
          const actors = (_b = (_a = this.labels["演員"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelectorAll(".value a");
          return (actors == null ? undefined : actors.length) ? Array.from(actors).map((i2) => {
            var _a2, _b2;
            const href = i2.getAttribute("href") ?? undefined;
            const url = href ? new URL(href, this.baseUrl).href : undefined;
            const file = href == null ? undefined : href.split("/").pop();
            const fileGroup = file == null ? undefined : file.slice(0, 2).toLowerCase();
            const face = `https://c0.jdbstatic.com/avatars/${fileGroup}/${file}.jpg`;
            return {
              name: i2.textContent,
              url,
              face,
              sex: ((_a2 = i2.nextElementSibling) == null ? undefined : _a2.classList.contains("female")) ? 1 : ((_b2 = i2.nextElementSibling) == null ? undefined : _b2.classList.contains("male")) ? 0 : undefined
            };
          }) : undefined;
        }
        parseStudio() {
          var _a, _b;
          const studios = (_b = (_a = this.labels["片商"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelectorAll(".value a");
          return (studios == null ? undefined : studios.length) ? Array.from(studios).map((i2) => ({
            name: i2.textContent,
            url: i2.getAttribute("href") ?? undefined
          })).map((i2) => ({
            ...i2,
            url: i2.url ? new URL(i2.url, this.baseUrl).href : undefined
          })) : undefined;
        }
        parsePublisher() {
          return undefined;
        }
        parseCover(dom) {
          var _a;
          const cover = (_a = dom.querySelector("img.video-cover")) == null ? undefined : _a.getAttribute("src");
          return cover ?? undefined;
        }
        parsePreview(dom) {
          const previews = dom.querySelectorAll(".preview-images .tile-item");
          return previews.length ? Array.from(previews).map((i2) => {
            var _a;
            return {
              raw: (i2 == null ? undefined : i2.getAttribute("href")) ?? undefined,
              thumbnail: ((_a = i2.querySelector("img")) == null ? undefined : _a.getAttribute("src")) ?? undefined
            };
          }).filter((i2) => !!i2.raw || !!i2.thumbnail) : undefined;
        }
        parseSeries() {
          var _a, _b;
          const series = (_b = (_a = this.labels["系列"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelectorAll(".value a");
          return (series == null ? undefined : series.length) ? Array.from(series).map((i2) => ({
            name: i2.textContent,
            url: i2.getAttribute("href") ?? undefined
          })).map((i2) => ({
            ...i2,
            url: i2.url ? new URL(i2.url, this.baseUrl).href : undefined
          })) : undefined;
        }
        parseCategory() {
          var _a, _b;
          const categories = (_b = (_a = this.labels["類別"]) == null ? undefined : _a.parentElement) == null ? undefined : _b.querySelectorAll(".value a");
          return (categories == null ? undefined : categories.length) ? Array.from(categories).map((i2) => ({
            name: i2.textContent,
            url: i2.getAttribute("href") ?? undefined
          })).map((i2) => ({
            ...i2,
            url: i2.url ? new URL(i2.url, this.baseUrl).href : undefined
          })) : undefined;
        }
        parseComments(doc) {
          const comments = doc.querySelectorAll(".review-items .review-item");
          return comments.length ? Array.from(comments).map((i2) => {
            var _a, _b, _c, _d, _e, _f;
            return {
              content: (_a = i2.querySelector(".content")) == null ? undefined : _a.textContent,
              name: ((_d = (_c = (_b = i2.querySelector(".likes")) == null ? undefined : _b.nextSibling) == null ? undefined : _c.textContent) == null ? undefined : _d.trim()) ?? "",
              score: Array(i2.querySelector(".score-stars i")).length,
              time: dayjs((_e = i2.querySelector(".time")) == null ? undefined : _e.textContent).valueOf(),
              likeCount: Number((_f = i2.querySelector(".likes-count")) == null ? undefined : _f.textContent)
            };
          }) : undefined;
        }
      }
      const useDataMovieInfo = () => {
        const javDB = new JavDB(new GMRequest());
        const javBus = new JavBus(new GMRequest());
        const javDBState = useAsyncState(
          async (avNumber) => {
            if (!avNumber) {
              return null;
            }
            const res = await javDB.getInfoByAvNumber(avNumber);
            return res;
          },
          undefined,
          {
            immediate: false
          }
        );
        const javBusState = useAsyncState(
          async (avNumber) => {
            if (!avNumber) {
              return null;
            }
            return javBus.getInfoByAvNumber(avNumber);
          },
          undefined,
          {
            immediate: false
          }
        );
        const movieInfo = computed(() => {
          return {
            javDBState,
            javBusState
          };
        });
        return movieInfo;
      };
      const useDataPlaylist = () => {
        const playlist = useAsyncState(
          async (cid, pickcode) => {
            const res = await Drive115Instance.getPlaylist(cid, pickcode);
            return res.data;
          },
          [],
          {
            immediate: false
          }
        );
        return reactive(playlist);
      };
      class SubtitleCache {
        // 7天过期
        constructor() {
          this.logger = new AppLogger("Utils SubtitleCache");
          this.CACHE_PREFIX = "115master_subtitle_";
          this.DEFAULT_EXPIRES_IN = 7 * 24 * 60 * 60 * 1e3;
          this.store = localforage.createInstance({
            name: "115master",
            storeName: "subtitles"
          });
        }
        // 生成缓存键
        getCacheKey(keyword, language) {
          return `${this.CACHE_PREFIX}${keyword}_${language}`;
        }
        // 获取缓存
        async get(keyword, language) {
          try {
            const cacheKey = this.getCacheKey(keyword, language);
            const cacheItem = await this.store.getItem(cacheKey);
            if (!cacheItem) {
              this.logger.log("缓存未命中", { keyword, language });
              return null;
            }
            if (Date.now() - cacheItem.timestamp > cacheItem.expiresIn) {
              this.logger.log("缓存已过期", { keyword, language });
              await this.store.removeItem(cacheKey);
              return null;
            }
            this.logger.log("缓存命中", {
              keyword,
              language,
              count: cacheItem.subtitles.length,
              cacheItem
            });
            return cacheItem.subtitles;
          } catch (error) {
            this.logger.error("获取缓存失败", error);
            return null;
          }
        }
        async set(keyword, language, subtitles, expiresIn = this.DEFAULT_EXPIRES_IN) {
          try {
            const cacheKey = this.getCacheKey(keyword, language);
            const cacheItem = {
              subtitles,
              timestamp: Date.now(),
              expiresIn
            };
            await this.store.setItem(cacheKey, cacheItem);
            this.logger.log("设置缓存成功", {
              keyword,
              language,
              count: subtitles.length
            });
          } catch (error) {
            this.logger.error("设置缓存失败", error);
          }
        }
        // 清除所有缓存
        async clear() {
          try {
            await this.store.clear();
            this.logger.log("清除所有缓存成功");
          } catch (error) {
            this.logger.error("清除缓存失败", error);
          }
        }
      }
      const subtitleCache = new SubtitleCache();
      const convertSrtToVtt = (srt) => {
        let vtt = "WEBVTT\n\n";
        const blocks = srt.split(/\n\s*\n/);
        blocks.forEach((block) => {
          if (!block.trim()) return;
          const lines = block.trim().split("\n");
          if (lines.length < 2) return;
          let timeCodeIndex = 0;
          for (let i2 = 0; i2 < lines.length; i2++) {
            if (lines[i2].match(
              /^\d{2}:\d{2}:\d{2}[,\.]\d{3}\s*-->\s*\d{2}:\d{2}:\d{2}[,\.]\d{3}$/
            )) {
              timeCodeIndex = i2;
              break;
            }
          }
          if (timeCodeIndex === 0 && !lines[0].match(
            /^\d{2}:\d{2}:\d{2}[,\.]\d{3}\s*-->\s*\d{2}:\d{2}:\d{2}[,\.]\d{3}$/
          )) {
            timeCodeIndex = 1;
          }
          if (timeCodeIndex >= lines.length) return;
          const vttTimecode = lines[timeCodeIndex].replace(/,/g, ".");
          const text = lines.slice(timeCodeIndex + 1).join("\n");
          if (text.trim()) {
            vtt += `${vttTimecode}
${text}

`;
          }
        });
        return vtt;
      };
      const vttToBlobUrl = (vtt) => {
        const blob = new Blob([vtt], { type: "text/vtt; charset=utf-8" });
        return URL.createObjectURL(blob);
      };
      class SubtitleCat {
        constructor() {
          this.domain = "https://subtitlecat.com";
          this.logger = new AppLogger("Utils SubtitleCat");
        }
        getSubtitleText(url) {
          return new Promise((resolve, reject) => {
            _GM_xmlhttpRequest({
              url,
              method: "GET",
              onload: (response) => {
                resolve(response.responseText);
              },
              onerror: (error) => {
                reject(error);
              }
            });
          });
        }
        fetchSubtitleUrl(url, language) {
          return new Promise((resolve, reject) => {
            _GM_xmlhttpRequest({
              url,
              method: "GET",
              onload: async (response) => {
                var _a;
                const parser = new DOMParser();
                const doc = parser.parseFromString(response.response, "text/html");
                const subtitleUrl = (_a = doc.querySelector(`#download_${language}`)) == null ? undefined : _a.getAttribute("href");
                resolve(subtitleUrl || undefined);
              },
              onerror: (error) => {
                reject(error);
              }
            });
          });
        }
        parseSubtitleRow(row, language) {
          var _a, _b;
          const firstTd = row.querySelector("td:first-child");
          const link = firstTd == null ? undefined : firstTd.querySelector("a");
          const title = (link == null ? undefined : link.textContent) || "";
          const href = (link == null ? undefined : link.getAttribute("href")) || "";
          const langMatch = (_a = firstTd == null ? undefined : firstTd.textContent) == null ? undefined : _a.match(/translated from (\w+)/);
          const originLanguage = langMatch ? langMatch[1] : "";
          const hasThumbsDown = row.querySelector("td:nth-child(2) .fa-thumbs-down") !== null;
          const hasThumbsUp = row.querySelector("td:nth-child(2) .fa-thumbs-up") !== null;
          const comment = hasThumbsDown ? -1 : hasThumbsUp ? 1 : 0;
          const downloadsText = ((_b = row.querySelector("td:nth-child(3)")) == null ? undefined : _b.textContent) || "";
          const downloadsMatch = downloadsText.match(/\d+/);
          const downloads = downloadsMatch ? parseInt(downloadsMatch[0]) : 0;
          return {
            title,
            href,
            downloads,
            comment,
            originLanguage,
            targetLanguage: language
          };
        }
        async processSubtitleItem(item) {
          const url = await this.fetchSubtitleUrl(
            `${this.domain}/${item.href}`,
            item.targetLanguage
          );
          if (!url) return undefined;
          const subtitleText = await this.getSubtitleText(this.domain + url);
          const vttText = convertSrtToVtt(subtitleText);
          const blobUrl = vttToBlobUrl(vttText);
          return {
            ...item,
            id: md5(JSON.stringify(item)),
            url: blobUrl,
            vvtText: vttText,
            isCache: false
          };
        }
        sortResults(results) {
          return results.sort((a, b) => {
            if (b.comment !== a.comment) {
              return b.comment - a.comment;
            }
            return b.downloads - a.downloads;
          });
        }
        async fetchSubtitle(keyword, language) {
          const cachedSubtitles = await subtitleCache.get(keyword, language);
          if (cachedSubtitles) {
            this.logger.log("从缓存获取字幕成功");
            return cachedSubtitles.map((subtitle) => ({
              ...subtitle,
              url: vttToBlobUrl(subtitle.vvtText)
            }));
          }
          return new Promise((resolve, reject) => {
            _GM_xmlhttpRequest({
              url: `${this.domain}/index.php?search=${keyword}`,
              method: "GET",
              onload: async (response) => {
                try {
                  const parser = new DOMParser();
                  const doc = parser.parseFromString(response.response, "text/html");
                  const rows = Array.from(
                    doc.querySelectorAll(".sub-table tbody tr")
                  ).slice(0, 5);
                  this.logger.log("fetchSubtitle", `找到${rows.length}个疑似结果`);
                  const searchResults = rows.map((row) => this.parseSubtitleRow(row, language)).filter((item) => {
                    const match = item.title.toLowerCase().includes(keyword.toLowerCase());
                    this.logger.log(
                      "fetchSubtitle",
                      `${item.title} ${match ? "匹配" : "不匹配"}`
                    );
                    return match;
                  });
                  const processedResults = await Promise.all(
                    searchResults.map(async (item) => {
                      const result = await this.processSubtitleItem(item);
                      this.logger.log(
                        `转换字幕 ${item.title}`,
                        result ? "成功" : "失败"
                      );
                      return result;
                    })
                  );
                  const finalResults = this.sortResults(
                    processedResults.filter(
                      (item) => item !== void 0
                    )
                  );
                  if (finalResults.length > 0) {
                    await subtitleCache.set(
                      keyword,
                      language,
                      finalResults.map((i2) => ({
                        ...i2,
                        isCache: true
                      }))
                    );
                  }
                  this.logger.log("最终结果", finalResults);
                  resolve(finalResults);
                } catch (error) {
                  console.error("处理过程中出错:", error);
                  reject(error);
                }
              },
              onerror: (error) => {
                console.error("请求失败:", error);
                reject(error);
              }
            });
          });
        }
      }
      const subtitlecat = new SubtitleCat();
      const useDataSubtitles = () => {
        const subtitles = useAsyncState(
          async (pickcode, keyword) => {
            if (!keyword) {
              return [];
            }
            const ResSubtitles = await subtitlecat.fetchSubtitle(keyword, "zh-CN");
            const preference = await subtitlePreference.getPreference(pickcode);
            return ResSubtitles.map((subtitle) => ({
              id: subtitle.id,
              url: subtitle.url,
              label: subtitle.title,
              srclang: subtitle.targetLanguage,
              kind: "subtitles",
              default: preference ? preference.id === subtitle.id : false
            }));
          },
          [],
          {
            immediate: false
          }
        );
        return subtitles;
      };
      var mp4box_all = {};
      var hasRequiredMp4box_all;
      function requireMp4box_all() {
        if (hasRequiredMp4box_all) return mp4box_all;
        hasRequiredMp4box_all = 1;
        (function(exports) {
          var Log = /* @__PURE__ */ function() {
            var start = /* @__PURE__ */ new Date();
            var LOG_LEVEL_ERROR = 4;
            var LOG_LEVEL_WARNING = 3;
            var LOG_LEVEL_INFO = 2;
            var LOG_LEVEL_DEBUG = 1;
            var log_level = LOG_LEVEL_ERROR;
            var logObject = {
              setLogLevel: function(level) {
                if (level == this.debug) log_level = LOG_LEVEL_DEBUG;
                else if (level == this.info) log_level = LOG_LEVEL_INFO;
                else if (level == this.warn) log_level = LOG_LEVEL_WARNING;
                else if (level == this.error) log_level = LOG_LEVEL_ERROR;
                else log_level = LOG_LEVEL_ERROR;
              },
              debug: function(module, msg) {
                if (console.debug === undefined) {
                  console.debug = console.log;
                }
                if (LOG_LEVEL_DEBUG >= log_level) {
                  console.debug("[" + Log.getDurationString(/* @__PURE__ */ new Date() - start, 1e3) + "]", "[" + module + "]", msg);
                }
              },
              log: function(module, msg) {
                this.debug(module.msg);
              },
              info: function(module, msg) {
                if (LOG_LEVEL_INFO >= log_level) {
                  console.info("[" + Log.getDurationString(/* @__PURE__ */ new Date() - start, 1e3) + "]", "[" + module + "]", msg);
                }
              },
              warn: function(module, msg) {
                if (LOG_LEVEL_WARNING >= log_level) {
                  console.warn("[" + Log.getDurationString(/* @__PURE__ */ new Date() - start, 1e3) + "]", "[" + module + "]", msg);
                }
              },
              error: function(module, msg) {
                if (LOG_LEVEL_ERROR >= log_level) {
                  console.error("[" + Log.getDurationString(/* @__PURE__ */ new Date() - start, 1e3) + "]", "[" + module + "]", msg);
                }
              }
            };
            return logObject;
          }();
          Log.getDurationString = function(duration2, _timescale) {
            var neg;
            function pad(number, length) {
              var str = "" + number;
              var a = str.split(".");
              while (a[0].length < length) {
                a[0] = "0" + a[0];
              }
              return a.join(".");
            }
            if (duration2 < 0) {
              neg = true;
              duration2 = -duration2;
            } else {
              neg = false;
            }
            var timescale = _timescale || 1;
            var duration_sec = duration2 / timescale;
            var hours = Math.floor(duration_sec / 3600);
            duration_sec -= hours * 3600;
            var minutes = Math.floor(duration_sec / 60);
            duration_sec -= minutes * 60;
            var msec = duration_sec * 1e3;
            duration_sec = Math.floor(duration_sec);
            msec -= duration_sec * 1e3;
            msec = Math.floor(msec);
            return (neg ? "-" : "") + hours + ":" + pad(minutes, 2) + ":" + pad(duration_sec, 2) + "." + pad(msec, 3);
          };
          Log.printRanges = function(ranges) {
            var length = ranges.length;
            if (length > 0) {
              var str = "";
              for (var i2 = 0; i2 < length; i2++) {
                if (i2 > 0) str += ",";
                str += "[" + Log.getDurationString(ranges.start(i2)) + "," + Log.getDurationString(ranges.end(i2)) + "]";
              }
              return str;
            } else {
              return "(empty)";
            }
          };
          {
            exports.Log = Log;
          }
          var MP4BoxStream = function(arrayBuffer) {
            if (arrayBuffer instanceof ArrayBuffer) {
              this.buffer = arrayBuffer;
              this.dataview = new DataView(arrayBuffer);
            } else {
              throw "Needs an array buffer";
            }
            this.position = 0;
          };
          MP4BoxStream.prototype.getPosition = function() {
            return this.position;
          };
          MP4BoxStream.prototype.getEndPosition = function() {
            return this.buffer.byteLength;
          };
          MP4BoxStream.prototype.getLength = function() {
            return this.buffer.byteLength;
          };
          MP4BoxStream.prototype.seek = function(pos) {
            var npos = Math.max(0, Math.min(this.buffer.byteLength, pos));
            this.position = isNaN(npos) || !isFinite(npos) ? 0 : npos;
            return true;
          };
          MP4BoxStream.prototype.isEos = function() {
            return this.getPosition() >= this.getEndPosition();
          };
          MP4BoxStream.prototype.readAnyInt = function(size, signed) {
            var res = 0;
            if (this.position + size <= this.buffer.byteLength) {
              switch (size) {
                case 1:
                  if (signed) {
                    res = this.dataview.getInt8(this.position);
                  } else {
                    res = this.dataview.getUint8(this.position);
                  }
                  break;
                case 2:
                  if (signed) {
                    res = this.dataview.getInt16(this.position);
                  } else {
                    res = this.dataview.getUint16(this.position);
                  }
                  break;
                case 3:
                  if (signed) {
                    throw "No method for reading signed 24 bits values";
                  } else {
                    res = this.dataview.getUint8(this.position) << 16;
                    res |= this.dataview.getUint8(this.position + 1) << 8;
                    res |= this.dataview.getUint8(this.position + 2);
                  }
                  break;
                case 4:
                  if (signed) {
                    res = this.dataview.getInt32(this.position);
                  } else {
                    res = this.dataview.getUint32(this.position);
                  }
                  break;
                case 8:
                  if (signed) {
                    throw "No method for reading signed 64 bits values";
                  } else {
                    res = this.dataview.getUint32(this.position) << 32;
                    res |= this.dataview.getUint32(this.position + 4);
                  }
                  break;
                default:
                  throw "readInt method not implemented for size: " + size;
              }
              this.position += size;
              return res;
            } else {
              throw "Not enough bytes in buffer";
            }
          };
          MP4BoxStream.prototype.readUint8 = function() {
            return this.readAnyInt(1, false);
          };
          MP4BoxStream.prototype.readUint16 = function() {
            return this.readAnyInt(2, false);
          };
          MP4BoxStream.prototype.readUint24 = function() {
            return this.readAnyInt(3, false);
          };
          MP4BoxStream.prototype.readUint32 = function() {
            return this.readAnyInt(4, false);
          };
          MP4BoxStream.prototype.readUint64 = function() {
            return this.readAnyInt(8, false);
          };
          MP4BoxStream.prototype.readString = function(length) {
            if (this.position + length <= this.buffer.byteLength) {
              var s = "";
              for (var i2 = 0; i2 < length; i2++) {
                s += String.fromCharCode(this.readUint8());
              }
              return s;
            } else {
              throw "Not enough bytes in buffer";
            }
          };
          MP4BoxStream.prototype.readCString = function() {
            var arr = [];
            while (true) {
              var b = this.readUint8();
              if (b !== 0) {
                arr.push(b);
              } else {
                break;
              }
            }
            return String.fromCharCode.apply(null, arr);
          };
          MP4BoxStream.prototype.readInt8 = function() {
            return this.readAnyInt(1, true);
          };
          MP4BoxStream.prototype.readInt16 = function() {
            return this.readAnyInt(2, true);
          };
          MP4BoxStream.prototype.readInt32 = function() {
            return this.readAnyInt(4, true);
          };
          MP4BoxStream.prototype.readInt64 = function() {
            return this.readAnyInt(8, false);
          };
          MP4BoxStream.prototype.readUint8Array = function(length) {
            var arr = new Uint8Array(length);
            for (var i2 = 0; i2 < length; i2++) {
              arr[i2] = this.readUint8();
            }
            return arr;
          };
          MP4BoxStream.prototype.readInt16Array = function(length) {
            var arr = new Int16Array(length);
            for (var i2 = 0; i2 < length; i2++) {
              arr[i2] = this.readInt16();
            }
            return arr;
          };
          MP4BoxStream.prototype.readUint16Array = function(length) {
            var arr = new Int16Array(length);
            for (var i2 = 0; i2 < length; i2++) {
              arr[i2] = this.readUint16();
            }
            return arr;
          };
          MP4BoxStream.prototype.readUint32Array = function(length) {
            var arr = new Uint32Array(length);
            for (var i2 = 0; i2 < length; i2++) {
              arr[i2] = this.readUint32();
            }
            return arr;
          };
          MP4BoxStream.prototype.readInt32Array = function(length) {
            var arr = new Int32Array(length);
            for (var i2 = 0; i2 < length; i2++) {
              arr[i2] = this.readInt32();
            }
            return arr;
          };
          {
            exports.MP4BoxStream = MP4BoxStream;
          }
          var DataStream = function(arrayBuffer, byteOffset, endianness) {
            this._byteOffset = byteOffset || 0;
            if (arrayBuffer instanceof ArrayBuffer) {
              this.buffer = arrayBuffer;
            } else if (typeof arrayBuffer == "object") {
              this.dataView = arrayBuffer;
              if (byteOffset) {
                this._byteOffset += byteOffset;
              }
            } else {
              this.buffer = new ArrayBuffer(arrayBuffer || 0);
            }
            this.position = 0;
            this.endianness = endianness == null ? DataStream.LITTLE_ENDIAN : endianness;
          };
          DataStream.prototype = {};
          DataStream.prototype.getPosition = function() {
            return this.position;
          };
          DataStream.prototype._realloc = function(extra) {
            if (!this._dynamicSize) {
              return;
            }
            var req = this._byteOffset + this.position + extra;
            var blen = this._buffer.byteLength;
            if (req <= blen) {
              if (req > this._byteLength) {
                this._byteLength = req;
              }
              return;
            }
            if (blen < 1) {
              blen = 1;
            }
            while (req > blen) {
              blen *= 2;
            }
            var buf = new ArrayBuffer(blen);
            var src = new Uint8Array(this._buffer);
            var dst = new Uint8Array(buf, 0, src.length);
            dst.set(src);
            this.buffer = buf;
            this._byteLength = req;
          };
          DataStream.prototype._trimAlloc = function() {
            if (this._byteLength == this._buffer.byteLength) {
              return;
            }
            var buf = new ArrayBuffer(this._byteLength);
            var dst = new Uint8Array(buf);
            var src = new Uint8Array(this._buffer, 0, dst.length);
            dst.set(src);
            this.buffer = buf;
          };
          DataStream.BIG_ENDIAN = false;
          DataStream.LITTLE_ENDIAN = true;
          DataStream.prototype._byteLength = 0;
          Object.defineProperty(
            DataStream.prototype,
            "byteLength",
            { get: function() {
              return this._byteLength - this._byteOffset;
            } }
          );
          Object.defineProperty(
            DataStream.prototype,
            "buffer",
            {
              get: function() {
                this._trimAlloc();
                return this._buffer;
              },
              set: function(v) {
                this._buffer = v;
                this._dataView = new DataView(this._buffer, this._byteOffset);
                this._byteLength = this._buffer.byteLength;
              }
            }
          );
          Object.defineProperty(
            DataStream.prototype,
            "byteOffset",
            {
              get: function() {
                return this._byteOffset;
              },
              set: function(v) {
                this._byteOffset = v;
                this._dataView = new DataView(this._buffer, this._byteOffset);
                this._byteLength = this._buffer.byteLength;
              }
            }
          );
          Object.defineProperty(
            DataStream.prototype,
            "dataView",
            {
              get: function() {
                return this._dataView;
              },
              set: function(v) {
                this._byteOffset = v.byteOffset;
                this._buffer = v.buffer;
                this._dataView = new DataView(this._buffer, this._byteOffset);
                this._byteLength = this._byteOffset + v.byteLength;
              }
            }
          );
          DataStream.prototype.seek = function(pos) {
            var npos = Math.max(0, Math.min(this.byteLength, pos));
            this.position = isNaN(npos) || !isFinite(npos) ? 0 : npos;
          };
          DataStream.prototype.isEof = function() {
            return this.position >= this._byteLength;
          };
          DataStream.prototype.mapUint8Array = function(length) {
            this._realloc(length * 1);
            var arr = new Uint8Array(this._buffer, this.byteOffset + this.position, length);
            this.position += length * 1;
            return arr;
          };
          DataStream.prototype.readInt32Array = function(length, e) {
            length = length == null ? this.byteLength - this.position / 4 : length;
            var arr = new Int32Array(length);
            DataStream.memcpy(
              arr.buffer,
              0,
              this.buffer,
              this.byteOffset + this.position,
              length * arr.BYTES_PER_ELEMENT
            );
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += arr.byteLength;
            return arr;
          };
          DataStream.prototype.readInt16Array = function(length, e) {
            length = length == null ? this.byteLength - this.position / 2 : length;
            var arr = new Int16Array(length);
            DataStream.memcpy(
              arr.buffer,
              0,
              this.buffer,
              this.byteOffset + this.position,
              length * arr.BYTES_PER_ELEMENT
            );
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += arr.byteLength;
            return arr;
          };
          DataStream.prototype.readInt8Array = function(length) {
            length = length == null ? this.byteLength - this.position : length;
            var arr = new Int8Array(length);
            DataStream.memcpy(
              arr.buffer,
              0,
              this.buffer,
              this.byteOffset + this.position,
              length * arr.BYTES_PER_ELEMENT
            );
            this.position += arr.byteLength;
            return arr;
          };
          DataStream.prototype.readUint32Array = function(length, e) {
            length = length == null ? this.byteLength - this.position / 4 : length;
            var arr = new Uint32Array(length);
            DataStream.memcpy(
              arr.buffer,
              0,
              this.buffer,
              this.byteOffset + this.position,
              length * arr.BYTES_PER_ELEMENT
            );
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += arr.byteLength;
            return arr;
          };
          DataStream.prototype.readUint16Array = function(length, e) {
            length = length == null ? this.byteLength - this.position / 2 : length;
            var arr = new Uint16Array(length);
            DataStream.memcpy(
              arr.buffer,
              0,
              this.buffer,
              this.byteOffset + this.position,
              length * arr.BYTES_PER_ELEMENT
            );
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += arr.byteLength;
            return arr;
          };
          DataStream.prototype.readUint8Array = function(length) {
            length = length == null ? this.byteLength - this.position : length;
            var arr = new Uint8Array(length);
            DataStream.memcpy(
              arr.buffer,
              0,
              this.buffer,
              this.byteOffset + this.position,
              length * arr.BYTES_PER_ELEMENT
            );
            this.position += arr.byteLength;
            return arr;
          };
          DataStream.prototype.readFloat64Array = function(length, e) {
            length = length == null ? this.byteLength - this.position / 8 : length;
            var arr = new Float64Array(length);
            DataStream.memcpy(
              arr.buffer,
              0,
              this.buffer,
              this.byteOffset + this.position,
              length * arr.BYTES_PER_ELEMENT
            );
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += arr.byteLength;
            return arr;
          };
          DataStream.prototype.readFloat32Array = function(length, e) {
            length = length == null ? this.byteLength - this.position / 4 : length;
            var arr = new Float32Array(length);
            DataStream.memcpy(
              arr.buffer,
              0,
              this.buffer,
              this.byteOffset + this.position,
              length * arr.BYTES_PER_ELEMENT
            );
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += arr.byteLength;
            return arr;
          };
          DataStream.prototype.readInt32 = function(e) {
            var v = this._dataView.getInt32(this.position, e == null ? this.endianness : e);
            this.position += 4;
            return v;
          };
          DataStream.prototype.readInt16 = function(e) {
            var v = this._dataView.getInt16(this.position, e == null ? this.endianness : e);
            this.position += 2;
            return v;
          };
          DataStream.prototype.readInt8 = function() {
            var v = this._dataView.getInt8(this.position);
            this.position += 1;
            return v;
          };
          DataStream.prototype.readUint32 = function(e) {
            var v = this._dataView.getUint32(this.position, e == null ? this.endianness : e);
            this.position += 4;
            return v;
          };
          DataStream.prototype.readUint16 = function(e) {
            var v = this._dataView.getUint16(this.position, e == null ? this.endianness : e);
            this.position += 2;
            return v;
          };
          DataStream.prototype.readUint8 = function() {
            var v = this._dataView.getUint8(this.position);
            this.position += 1;
            return v;
          };
          DataStream.prototype.readFloat32 = function(e) {
            var v = this._dataView.getFloat32(this.position, e == null ? this.endianness : e);
            this.position += 4;
            return v;
          };
          DataStream.prototype.readFloat64 = function(e) {
            var v = this._dataView.getFloat64(this.position, e == null ? this.endianness : e);
            this.position += 8;
            return v;
          };
          DataStream.endianness = new Int8Array(new Int16Array([1]).buffer)[0] > 0;
          DataStream.memcpy = function(dst, dstOffset, src, srcOffset, byteLength) {
            var dstU8 = new Uint8Array(dst, dstOffset, byteLength);
            var srcU8 = new Uint8Array(src, srcOffset, byteLength);
            dstU8.set(srcU8);
          };
          DataStream.arrayToNative = function(array, arrayIsLittleEndian) {
            if (arrayIsLittleEndian == this.endianness) {
              return array;
            } else {
              return this.flipArrayEndianness(array);
            }
          };
          DataStream.nativeToEndian = function(array, littleEndian) {
            if (this.endianness == littleEndian) {
              return array;
            } else {
              return this.flipArrayEndianness(array);
            }
          };
          DataStream.flipArrayEndianness = function(array) {
            var u8 = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
            for (var i2 = 0; i2 < array.byteLength; i2 += array.BYTES_PER_ELEMENT) {
              for (var j = i2 + array.BYTES_PER_ELEMENT - 1, k = i2; j > k; j--, k++) {
                var tmp = u8[k];
                u8[k] = u8[j];
                u8[j] = tmp;
              }
            }
            return array;
          };
          DataStream.prototype.failurePosition = 0;
          String.fromCharCodeUint8 = function(uint8arr) {
            var arr = [];
            for (var i2 = 0; i2 < uint8arr.length; i2++) {
              arr[i2] = uint8arr[i2];
            }
            return String.fromCharCode.apply(null, arr);
          };
          DataStream.prototype.readString = function(length, encoding) {
            if (encoding == null || encoding == "ASCII") {
              return String.fromCharCodeUint8.apply(null, [this.mapUint8Array(length == null ? this.byteLength - this.position : length)]);
            } else {
              return new TextDecoder(encoding).decode(this.mapUint8Array(length));
            }
          };
          DataStream.prototype.readCString = function(length) {
            var blen = this.byteLength - this.position;
            var u8 = new Uint8Array(this._buffer, this._byteOffset + this.position);
            var len = blen;
            if (length != null) {
              len = Math.min(length, blen);
            }
            for (var i2 = 0; i2 < len && u8[i2] !== 0; i2++) ;
            var s = String.fromCharCodeUint8.apply(null, [this.mapUint8Array(i2)]);
            if (length != null) {
              this.position += len - i2;
            } else if (i2 != blen) {
              this.position += 1;
            }
            return s;
          };
          var MAX_SIZE = Math.pow(2, 32);
          DataStream.prototype.readInt64 = function() {
            return this.readInt32() * MAX_SIZE + this.readUint32();
          };
          DataStream.prototype.readUint64 = function() {
            return this.readUint32() * MAX_SIZE + this.readUint32();
          };
          DataStream.prototype.readInt64 = function() {
            return this.readUint32() * MAX_SIZE + this.readUint32();
          };
          DataStream.prototype.readUint24 = function() {
            return (this.readUint8() << 16) + (this.readUint8() << 8) + this.readUint8();
          };
          {
            exports.DataStream = DataStream;
          }
          DataStream.prototype.save = function(filename) {
            var blob = new Blob([this.buffer]);
            if (window.URL && URL.createObjectURL) {
              var url = window.URL.createObjectURL(blob);
              var a = document.createElement("a");
              document.body.appendChild(a);
              a.setAttribute("href", url);
              a.setAttribute("download", filename);
              a.setAttribute("target", "_self");
              a.click();
              window.URL.revokeObjectURL(url);
            } else {
              throw "DataStream.save: Can't create object URL.";
            }
          };
          DataStream.prototype._dynamicSize = true;
          Object.defineProperty(
            DataStream.prototype,
            "dynamicSize",
            {
              get: function() {
                return this._dynamicSize;
              },
              set: function(v) {
                if (!v) {
                  this._trimAlloc();
                }
                this._dynamicSize = v;
              }
            }
          );
          DataStream.prototype.shift = function(offset) {
            var buf = new ArrayBuffer(this._byteLength - offset);
            var dst = new Uint8Array(buf);
            var src = new Uint8Array(this._buffer, offset, dst.length);
            dst.set(src);
            this.buffer = buf;
            this.position -= offset;
          };
          DataStream.prototype.writeInt32Array = function(arr, e) {
            this._realloc(arr.length * 4);
            if (arr instanceof Int32Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
              DataStream.memcpy(
                this._buffer,
                this.byteOffset + this.position,
                arr.buffer,
                0,
                arr.byteLength
              );
              this.mapInt32Array(arr.length, e);
            } else {
              for (var i2 = 0; i2 < arr.length; i2++) {
                this.writeInt32(arr[i2], e);
              }
            }
          };
          DataStream.prototype.writeInt16Array = function(arr, e) {
            this._realloc(arr.length * 2);
            if (arr instanceof Int16Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
              DataStream.memcpy(
                this._buffer,
                this.byteOffset + this.position,
                arr.buffer,
                0,
                arr.byteLength
              );
              this.mapInt16Array(arr.length, e);
            } else {
              for (var i2 = 0; i2 < arr.length; i2++) {
                this.writeInt16(arr[i2], e);
              }
            }
          };
          DataStream.prototype.writeInt8Array = function(arr) {
            this._realloc(arr.length * 1);
            if (arr instanceof Int8Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
              DataStream.memcpy(
                this._buffer,
                this.byteOffset + this.position,
                arr.buffer,
                0,
                arr.byteLength
              );
              this.mapInt8Array(arr.length);
            } else {
              for (var i2 = 0; i2 < arr.length; i2++) {
                this.writeInt8(arr[i2]);
              }
            }
          };
          DataStream.prototype.writeUint32Array = function(arr, e) {
            this._realloc(arr.length * 4);
            if (arr instanceof Uint32Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
              DataStream.memcpy(
                this._buffer,
                this.byteOffset + this.position,
                arr.buffer,
                0,
                arr.byteLength
              );
              this.mapUint32Array(arr.length, e);
            } else {
              for (var i2 = 0; i2 < arr.length; i2++) {
                this.writeUint32(arr[i2], e);
              }
            }
          };
          DataStream.prototype.writeUint16Array = function(arr, e) {
            this._realloc(arr.length * 2);
            if (arr instanceof Uint16Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
              DataStream.memcpy(
                this._buffer,
                this.byteOffset + this.position,
                arr.buffer,
                0,
                arr.byteLength
              );
              this.mapUint16Array(arr.length, e);
            } else {
              for (var i2 = 0; i2 < arr.length; i2++) {
                this.writeUint16(arr[i2], e);
              }
            }
          };
          DataStream.prototype.writeUint8Array = function(arr) {
            this._realloc(arr.length * 1);
            if (arr instanceof Uint8Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
              DataStream.memcpy(
                this._buffer,
                this.byteOffset + this.position,
                arr.buffer,
                0,
                arr.byteLength
              );
              this.mapUint8Array(arr.length);
            } else {
              for (var i2 = 0; i2 < arr.length; i2++) {
                this.writeUint8(arr[i2]);
              }
            }
          };
          DataStream.prototype.writeFloat64Array = function(arr, e) {
            this._realloc(arr.length * 8);
            if (arr instanceof Float64Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
              DataStream.memcpy(
                this._buffer,
                this.byteOffset + this.position,
                arr.buffer,
                0,
                arr.byteLength
              );
              this.mapFloat64Array(arr.length, e);
            } else {
              for (var i2 = 0; i2 < arr.length; i2++) {
                this.writeFloat64(arr[i2], e);
              }
            }
          };
          DataStream.prototype.writeFloat32Array = function(arr, e) {
            this._realloc(arr.length * 4);
            if (arr instanceof Float32Array && this.byteOffset + this.position % arr.BYTES_PER_ELEMENT === 0) {
              DataStream.memcpy(
                this._buffer,
                this.byteOffset + this.position,
                arr.buffer,
                0,
                arr.byteLength
              );
              this.mapFloat32Array(arr.length, e);
            } else {
              for (var i2 = 0; i2 < arr.length; i2++) {
                this.writeFloat32(arr[i2], e);
              }
            }
          };
          DataStream.prototype.writeInt32 = function(v, e) {
            this._realloc(4);
            this._dataView.setInt32(this.position, v, e == null ? this.endianness : e);
            this.position += 4;
          };
          DataStream.prototype.writeInt16 = function(v, e) {
            this._realloc(2);
            this._dataView.setInt16(this.position, v, e == null ? this.endianness : e);
            this.position += 2;
          };
          DataStream.prototype.writeInt8 = function(v) {
            this._realloc(1);
            this._dataView.setInt8(this.position, v);
            this.position += 1;
          };
          DataStream.prototype.writeUint32 = function(v, e) {
            this._realloc(4);
            this._dataView.setUint32(this.position, v, e == null ? this.endianness : e);
            this.position += 4;
          };
          DataStream.prototype.writeUint16 = function(v, e) {
            this._realloc(2);
            this._dataView.setUint16(this.position, v, e == null ? this.endianness : e);
            this.position += 2;
          };
          DataStream.prototype.writeUint8 = function(v) {
            this._realloc(1);
            this._dataView.setUint8(this.position, v);
            this.position += 1;
          };
          DataStream.prototype.writeFloat32 = function(v, e) {
            this._realloc(4);
            this._dataView.setFloat32(this.position, v, e == null ? this.endianness : e);
            this.position += 4;
          };
          DataStream.prototype.writeFloat64 = function(v, e) {
            this._realloc(8);
            this._dataView.setFloat64(this.position, v, e == null ? this.endianness : e);
            this.position += 8;
          };
          DataStream.prototype.writeUCS2String = function(str, endianness, lengthOverride) {
            if (lengthOverride == null) {
              lengthOverride = str.length;
            }
            for (var i2 = 0; i2 < str.length && i2 < lengthOverride; i2++) {
              this.writeUint16(str.charCodeAt(i2), endianness);
            }
            for (; i2 < lengthOverride; i2++) {
              this.writeUint16(0);
            }
          };
          DataStream.prototype.writeString = function(s, encoding, length) {
            var i2 = 0;
            if (encoding == null || encoding == "ASCII") {
              if (length != null) {
                var len = Math.min(s.length, length);
                for (i2 = 0; i2 < len; i2++) {
                  this.writeUint8(s.charCodeAt(i2));
                }
                for (; i2 < length; i2++) {
                  this.writeUint8(0);
                }
              } else {
                for (i2 = 0; i2 < s.length; i2++) {
                  this.writeUint8(s.charCodeAt(i2));
                }
              }
            } else {
              this.writeUint8Array(new TextEncoder(encoding).encode(s.substring(0, length)));
            }
          };
          DataStream.prototype.writeCString = function(s, length) {
            var i2 = 0;
            if (length != null) {
              var len = Math.min(s.length, length);
              for (i2 = 0; i2 < len; i2++) {
                this.writeUint8(s.charCodeAt(i2));
              }
              for (; i2 < length; i2++) {
                this.writeUint8(0);
              }
            } else {
              for (i2 = 0; i2 < s.length; i2++) {
                this.writeUint8(s.charCodeAt(i2));
              }
              this.writeUint8(0);
            }
          };
          DataStream.prototype.writeStruct = function(structDefinition, struct) {
            for (var i2 = 0; i2 < structDefinition.length; i2 += 2) {
              var t = structDefinition[i2 + 1];
              this.writeType(t, struct[structDefinition[i2]], struct);
            }
          };
          DataStream.prototype.writeType = function(t, v, struct) {
            var tp;
            if (typeof t == "function") {
              return t(this, v);
            } else if (typeof t == "object" && !(t instanceof Array)) {
              return t.set(this, v, struct);
            }
            var lengthOverride = null;
            var charset = "ASCII";
            var pos = this.position;
            if (typeof t == "string" && /:/.test(t)) {
              tp = t.split(":");
              t = tp[0];
              lengthOverride = parseInt(tp[1]);
            }
            if (typeof t == "string" && /,/.test(t)) {
              tp = t.split(",");
              t = tp[0];
              charset = parseInt(tp[1]);
            }
            switch (t) {
              case "uint8":
                this.writeUint8(v);
                break;
              case "int8":
                this.writeInt8(v);
                break;
              case "uint16":
                this.writeUint16(v, this.endianness);
                break;
              case "int16":
                this.writeInt16(v, this.endianness);
                break;
              case "uint32":
                this.writeUint32(v, this.endianness);
                break;
              case "int32":
                this.writeInt32(v, this.endianness);
                break;
              case "float32":
                this.writeFloat32(v, this.endianness);
                break;
              case "float64":
                this.writeFloat64(v, this.endianness);
                break;
              case "uint16be":
                this.writeUint16(v, DataStream.BIG_ENDIAN);
                break;
              case "int16be":
                this.writeInt16(v, DataStream.BIG_ENDIAN);
                break;
              case "uint32be":
                this.writeUint32(v, DataStream.BIG_ENDIAN);
                break;
              case "int32be":
                this.writeInt32(v, DataStream.BIG_ENDIAN);
                break;
              case "float32be":
                this.writeFloat32(v, DataStream.BIG_ENDIAN);
                break;
              case "float64be":
                this.writeFloat64(v, DataStream.BIG_ENDIAN);
                break;
              case "uint16le":
                this.writeUint16(v, DataStream.LITTLE_ENDIAN);
                break;
              case "int16le":
                this.writeInt16(v, DataStream.LITTLE_ENDIAN);
                break;
              case "uint32le":
                this.writeUint32(v, DataStream.LITTLE_ENDIAN);
                break;
              case "int32le":
                this.writeInt32(v, DataStream.LITTLE_ENDIAN);
                break;
              case "float32le":
                this.writeFloat32(v, DataStream.LITTLE_ENDIAN);
                break;
              case "float64le":
                this.writeFloat64(v, DataStream.LITTLE_ENDIAN);
                break;
              case "cstring":
                this.writeCString(v, lengthOverride);
                break;
              case "string":
                this.writeString(v, charset, lengthOverride);
                break;
              case "u16string":
                this.writeUCS2String(v, this.endianness, lengthOverride);
                break;
              case "u16stringle":
                this.writeUCS2String(v, DataStream.LITTLE_ENDIAN, lengthOverride);
                break;
              case "u16stringbe":
                this.writeUCS2String(v, DataStream.BIG_ENDIAN, lengthOverride);
                break;
              default:
                if (t.length == 3) {
                  var ta = t[1];
                  for (var i2 = 0; i2 < v.length; i2++) {
                    this.writeType(ta, v[i2]);
                  }
                  break;
                } else {
                  this.writeStruct(t, v);
                  break;
                }
            }
            if (lengthOverride != null) {
              this.position = pos;
              this._realloc(lengthOverride);
              this.position = pos + lengthOverride;
            }
          };
          DataStream.prototype.writeUint64 = function(v) {
            var h2 = Math.floor(v / MAX_SIZE);
            this.writeUint32(h2);
            this.writeUint32(v & 4294967295);
          };
          DataStream.prototype.writeUint24 = function(v) {
            this.writeUint8((v & 16711680) >> 16);
            this.writeUint8((v & 65280) >> 8);
            this.writeUint8(v & 255);
          };
          DataStream.prototype.adjustUint32 = function(position, value) {
            var pos = this.position;
            this.seek(position);
            this.writeUint32(value);
            this.seek(pos);
          };
          DataStream.prototype.mapInt32Array = function(length, e) {
            this._realloc(length * 4);
            var arr = new Int32Array(this._buffer, this.byteOffset + this.position, length);
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += length * 4;
            return arr;
          };
          DataStream.prototype.mapInt16Array = function(length, e) {
            this._realloc(length * 2);
            var arr = new Int16Array(this._buffer, this.byteOffset + this.position, length);
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += length * 2;
            return arr;
          };
          DataStream.prototype.mapInt8Array = function(length) {
            this._realloc(length * 1);
            var arr = new Int8Array(this._buffer, this.byteOffset + this.position, length);
            this.position += length * 1;
            return arr;
          };
          DataStream.prototype.mapUint32Array = function(length, e) {
            this._realloc(length * 4);
            var arr = new Uint32Array(this._buffer, this.byteOffset + this.position, length);
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += length * 4;
            return arr;
          };
          DataStream.prototype.mapUint16Array = function(length, e) {
            this._realloc(length * 2);
            var arr = new Uint16Array(this._buffer, this.byteOffset + this.position, length);
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += length * 2;
            return arr;
          };
          DataStream.prototype.mapFloat64Array = function(length, e) {
            this._realloc(length * 8);
            var arr = new Float64Array(this._buffer, this.byteOffset + this.position, length);
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += length * 8;
            return arr;
          };
          DataStream.prototype.mapFloat32Array = function(length, e) {
            this._realloc(length * 4);
            var arr = new Float32Array(this._buffer, this.byteOffset + this.position, length);
            DataStream.arrayToNative(arr, e == null ? this.endianness : e);
            this.position += length * 4;
            return arr;
          };
          var MultiBufferStream = function(buffer) {
            this.buffers = [];
            this.bufferIndex = -1;
            if (buffer) {
              this.insertBuffer(buffer);
              this.bufferIndex = 0;
            }
          };
          MultiBufferStream.prototype = new DataStream(new ArrayBuffer(), 0, DataStream.BIG_ENDIAN);
          MultiBufferStream.prototype.initialized = function() {
            var firstBuffer;
            if (this.bufferIndex > -1) {
              return true;
            } else if (this.buffers.length > 0) {
              firstBuffer = this.buffers[0];
              if (firstBuffer.fileStart === 0) {
                this.buffer = firstBuffer;
                this.bufferIndex = 0;
                Log.debug("MultiBufferStream", "Stream ready for parsing");
                return true;
              } else {
                Log.warn("MultiBufferStream", "The first buffer should have a fileStart of 0");
                this.logBufferLevel();
                return false;
              }
            } else {
              Log.warn("MultiBufferStream", "No buffer to start parsing from");
              this.logBufferLevel();
              return false;
            }
          };
          ArrayBuffer.concat = function(buffer1, buffer2) {
            Log.debug("ArrayBuffer", "Trying to create a new buffer of size: " + (buffer1.byteLength + buffer2.byteLength));
            var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
            tmp.set(new Uint8Array(buffer1), 0);
            tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
            return tmp.buffer;
          };
          MultiBufferStream.prototype.reduceBuffer = function(buffer, offset, newLength) {
            var smallB;
            smallB = new Uint8Array(newLength);
            smallB.set(new Uint8Array(buffer, offset, newLength));
            smallB.buffer.fileStart = buffer.fileStart + offset;
            smallB.buffer.usedBytes = 0;
            return smallB.buffer;
          };
          MultiBufferStream.prototype.insertBuffer = function(ab) {
            var to_add = true;
            for (var i2 = 0; i2 < this.buffers.length; i2++) {
              var b = this.buffers[i2];
              if (ab.fileStart <= b.fileStart) {
                if (ab.fileStart === b.fileStart) {
                  if (ab.byteLength > b.byteLength) {
                    this.buffers.splice(i2, 1);
                    i2--;
                    continue;
                  } else {
                    Log.warn("MultiBufferStream", "Buffer (fileStart: " + ab.fileStart + " - Length: " + ab.byteLength + ") already appended, ignoring");
                  }
                } else {
                  if (ab.fileStart + ab.byteLength <= b.fileStart) ;
                  else {
                    ab = this.reduceBuffer(ab, 0, b.fileStart - ab.fileStart);
                  }
                  Log.debug("MultiBufferStream", "Appending new buffer (fileStart: " + ab.fileStart + " - Length: " + ab.byteLength + ")");
                  this.buffers.splice(i2, 0, ab);
                  if (i2 === 0) {
                    this.buffer = ab;
                  }
                }
                to_add = false;
                break;
              } else if (ab.fileStart < b.fileStart + b.byteLength) {
                var offset = b.fileStart + b.byteLength - ab.fileStart;
                var newLength = ab.byteLength - offset;
                if (newLength > 0) {
                  ab = this.reduceBuffer(ab, offset, newLength);
                } else {
                  to_add = false;
                  break;
                }
              }
            }
            if (to_add) {
              Log.debug("MultiBufferStream", "Appending new buffer (fileStart: " + ab.fileStart + " - Length: " + ab.byteLength + ")");
              this.buffers.push(ab);
              if (i2 === 0) {
                this.buffer = ab;
              }
            }
          };
          MultiBufferStream.prototype.logBufferLevel = function(info) {
            var i2;
            var buffer;
            var used, total;
            var ranges = [];
            var range;
            var bufferedString = "";
            used = 0;
            total = 0;
            for (i2 = 0; i2 < this.buffers.length; i2++) {
              buffer = this.buffers[i2];
              if (i2 === 0) {
                range = {};
                ranges.push(range);
                range.start = buffer.fileStart;
                range.end = buffer.fileStart + buffer.byteLength;
                bufferedString += "[" + range.start + "-";
              } else if (range.end === buffer.fileStart) {
                range.end = buffer.fileStart + buffer.byteLength;
              } else {
                range = {};
                range.start = buffer.fileStart;
                bufferedString += ranges[ranges.length - 1].end - 1 + "], [" + range.start + "-";
                range.end = buffer.fileStart + buffer.byteLength;
                ranges.push(range);
              }
              used += buffer.usedBytes;
              total += buffer.byteLength;
            }
            if (ranges.length > 0) {
              bufferedString += range.end - 1 + "]";
            }
            var log = info ? Log.info : Log.debug;
            if (this.buffers.length === 0) {
              log("MultiBufferStream", "No more buffer in memory");
            } else {
              log("MultiBufferStream", "" + this.buffers.length + " stored buffer(s) (" + used + "/" + total + " bytes), continuous ranges: " + bufferedString);
            }
          };
          MultiBufferStream.prototype.cleanBuffers = function() {
            var i2;
            var buffer;
            for (i2 = 0; i2 < this.buffers.length; i2++) {
              buffer = this.buffers[i2];
              if (buffer.usedBytes === buffer.byteLength) {
                Log.debug("MultiBufferStream", "Removing buffer #" + i2);
                this.buffers.splice(i2, 1);
                i2--;
              }
            }
          };
          MultiBufferStream.prototype.mergeNextBuffer = function() {
            var next_buffer;
            if (this.bufferIndex + 1 < this.buffers.length) {
              next_buffer = this.buffers[this.bufferIndex + 1];
              if (next_buffer.fileStart === this.buffer.fileStart + this.buffer.byteLength) {
                var oldLength = this.buffer.byteLength;
                var oldUsedBytes = this.buffer.usedBytes;
                var oldFileStart = this.buffer.fileStart;
                this.buffers[this.bufferIndex] = ArrayBuffer.concat(this.buffer, next_buffer);
                this.buffer = this.buffers[this.bufferIndex];
                this.buffers.splice(this.bufferIndex + 1, 1);
                this.buffer.usedBytes = oldUsedBytes;
                this.buffer.fileStart = oldFileStart;
                Log.debug("ISOFile", "Concatenating buffer for box parsing (length: " + oldLength + "->" + this.buffer.byteLength + ")");
                return true;
              } else {
                return false;
              }
            } else {
              return false;
            }
          };
          MultiBufferStream.prototype.findPosition = function(fromStart, filePosition, markAsUsed) {
            var i2;
            var abuffer = null;
            var index = -1;
            if (fromStart === true) {
              i2 = 0;
            } else {
              i2 = this.bufferIndex;
            }
            while (i2 < this.buffers.length) {
              abuffer = this.buffers[i2];
              if (abuffer.fileStart <= filePosition) {
                index = i2;
                if (markAsUsed) {
                  if (abuffer.fileStart + abuffer.byteLength <= filePosition) {
                    abuffer.usedBytes = abuffer.byteLength;
                  } else {
                    abuffer.usedBytes = filePosition - abuffer.fileStart;
                  }
                  this.logBufferLevel();
                }
              } else {
                break;
              }
              i2++;
            }
            if (index !== -1) {
              abuffer = this.buffers[index];
              if (abuffer.fileStart + abuffer.byteLength >= filePosition) {
                Log.debug("MultiBufferStream", "Found position in existing buffer #" + index);
                return index;
              } else {
                return -1;
              }
            } else {
              return -1;
            }
          };
          MultiBufferStream.prototype.findEndContiguousBuf = function(inputindex) {
            var i2;
            var currentBuf;
            var nextBuf;
            var index = inputindex !== undefined ? inputindex : this.bufferIndex;
            currentBuf = this.buffers[index];
            if (this.buffers.length > index + 1) {
              for (i2 = index + 1; i2 < this.buffers.length; i2++) {
                nextBuf = this.buffers[i2];
                if (nextBuf.fileStart === currentBuf.fileStart + currentBuf.byteLength) {
                  currentBuf = nextBuf;
                } else {
                  break;
                }
              }
            }
            return currentBuf.fileStart + currentBuf.byteLength;
          };
          MultiBufferStream.prototype.getEndFilePositionAfter = function(pos) {
            var index = this.findPosition(true, pos, false);
            if (index !== -1) {
              return this.findEndContiguousBuf(index);
            } else {
              return pos;
            }
          };
          MultiBufferStream.prototype.addUsedBytes = function(nbBytes) {
            this.buffer.usedBytes += nbBytes;
            this.logBufferLevel();
          };
          MultiBufferStream.prototype.setAllUsedBytes = function() {
            this.buffer.usedBytes = this.buffer.byteLength;
            this.logBufferLevel();
          };
          MultiBufferStream.prototype.seek = function(filePosition, fromStart, markAsUsed) {
            var index;
            index = this.findPosition(fromStart, filePosition, markAsUsed);
            if (index !== -1) {
              this.buffer = this.buffers[index];
              this.bufferIndex = index;
              this.position = filePosition - this.buffer.fileStart;
              Log.debug("MultiBufferStream", "Repositioning parser at buffer position: " + this.position);
              return true;
            } else {
              Log.debug("MultiBufferStream", "Position " + filePosition + " not found in buffered data");
              return false;
            }
          };
          MultiBufferStream.prototype.getPosition = function() {
            if (this.bufferIndex === -1 || this.buffers[this.bufferIndex] === null) {
              throw "Error accessing position in the MultiBufferStream";
            }
            return this.buffers[this.bufferIndex].fileStart + this.position;
          };
          MultiBufferStream.prototype.getLength = function() {
            return this.byteLength;
          };
          MultiBufferStream.prototype.getEndPosition = function() {
            if (this.bufferIndex === -1 || this.buffers[this.bufferIndex] === null) {
              throw "Error accessing position in the MultiBufferStream";
            }
            return this.buffers[this.bufferIndex].fileStart + this.byteLength;
          };
          {
            exports.MultiBufferStream = MultiBufferStream;
          }
          var MPEG4DescriptorParser = function() {
            var ES_DescrTag = 3;
            var DecoderConfigDescrTag = 4;
            var DecSpecificInfoTag = 5;
            var SLConfigDescrTag = 6;
            var descTagToName = [];
            descTagToName[ES_DescrTag] = "ES_Descriptor";
            descTagToName[DecoderConfigDescrTag] = "DecoderConfigDescriptor";
            descTagToName[DecSpecificInfoTag] = "DecoderSpecificInfo";
            descTagToName[SLConfigDescrTag] = "SLConfigDescriptor";
            this.getDescriptorName = function(tag) {
              return descTagToName[tag];
            };
            var that = this;
            var classes = {};
            this.parseOneDescriptor = function(stream) {
              var size = 0;
              var tag;
              var desc;
              var byteRead;
              tag = stream.readUint8();
              byteRead = stream.readUint8();
              while (byteRead & 128) {
                size = (size << 7) + (byteRead & 127);
                byteRead = stream.readUint8();
              }
              size = (size << 7) + (byteRead & 127);
              Log.debug("MPEG4DescriptorParser", "Found " + (descTagToName[tag] || "Descriptor " + tag) + ", size " + size + " at position " + stream.getPosition());
              if (descTagToName[tag]) {
                desc = new classes[descTagToName[tag]](size);
              } else {
                desc = new classes.Descriptor(size);
              }
              desc.parse(stream);
              return desc;
            };
            classes.Descriptor = function(_tag, _size) {
              this.tag = _tag;
              this.size = _size;
              this.descs = [];
            };
            classes.Descriptor.prototype.parse = function(stream) {
              this.data = stream.readUint8Array(this.size);
            };
            classes.Descriptor.prototype.findDescriptor = function(tag) {
              for (var i2 = 0; i2 < this.descs.length; i2++) {
                if (this.descs[i2].tag == tag) {
                  return this.descs[i2];
                }
              }
              return null;
            };
            classes.Descriptor.prototype.parseRemainingDescriptors = function(stream) {
              var start = stream.position;
              while (stream.position < start + this.size) {
                var desc = that.parseOneDescriptor(stream);
                this.descs.push(desc);
              }
            };
            classes.ES_Descriptor = function(size) {
              classes.Descriptor.call(this, ES_DescrTag, size);
            };
            classes.ES_Descriptor.prototype = new classes.Descriptor();
            classes.ES_Descriptor.prototype.parse = function(stream) {
              this.ES_ID = stream.readUint16();
              this.flags = stream.readUint8();
              this.size -= 3;
              if (this.flags & 128) {
                this.dependsOn_ES_ID = stream.readUint16();
                this.size -= 2;
              } else {
                this.dependsOn_ES_ID = 0;
              }
              if (this.flags & 64) {
                var l = stream.readUint8();
                this.URL = stream.readString(l);
                this.size -= l + 1;
              } else {
                this.URL = "";
              }
              if (this.flags & 32) {
                this.OCR_ES_ID = stream.readUint16();
                this.size -= 2;
              } else {
                this.OCR_ES_ID = 0;
              }
              this.parseRemainingDescriptors(stream);
            };
            classes.ES_Descriptor.prototype.getOTI = function(stream) {
              var dcd = this.findDescriptor(DecoderConfigDescrTag);
              if (dcd) {
                return dcd.oti;
              } else {
                return 0;
              }
            };
            classes.ES_Descriptor.prototype.getAudioConfig = function(stream) {
              var dcd = this.findDescriptor(DecoderConfigDescrTag);
              if (!dcd) return null;
              var dsi = dcd.findDescriptor(DecSpecificInfoTag);
              if (dsi && dsi.data) {
                var audioObjectType = (dsi.data[0] & 248) >> 3;
                if (audioObjectType === 31 && dsi.data.length >= 2) {
                  audioObjectType = 32 + ((dsi.data[0] & 7) << 3) + ((dsi.data[1] & 224) >> 5);
                }
                return audioObjectType;
              } else {
                return null;
              }
            };
            classes.DecoderConfigDescriptor = function(size) {
              classes.Descriptor.call(this, DecoderConfigDescrTag, size);
            };
            classes.DecoderConfigDescriptor.prototype = new classes.Descriptor();
            classes.DecoderConfigDescriptor.prototype.parse = function(stream) {
              this.oti = stream.readUint8();
              this.streamType = stream.readUint8();
              this.upStream = (this.streamType >> 1 & 1) !== 0;
              this.streamType = this.streamType >>> 2;
              this.bufferSize = stream.readUint24();
              this.maxBitrate = stream.readUint32();
              this.avgBitrate = stream.readUint32();
              this.size -= 13;
              this.parseRemainingDescriptors(stream);
            };
            classes.DecoderSpecificInfo = function(size) {
              classes.Descriptor.call(this, DecSpecificInfoTag, size);
            };
            classes.DecoderSpecificInfo.prototype = new classes.Descriptor();
            classes.SLConfigDescriptor = function(size) {
              classes.Descriptor.call(this, SLConfigDescrTag, size);
            };
            classes.SLConfigDescriptor.prototype = new classes.Descriptor();
            return this;
          };
          {
            exports.MPEG4DescriptorParser = MPEG4DescriptorParser;
          }
          var BoxParser = {
            ERR_INVALID_DATA: -1,
            ERR_NOT_ENOUGH_DATA: 0,
            OK: 1,
            // Boxes to be created with default parsing
            BASIC_BOXES: ["mdat", "idat", "free", "skip", "meco", "strk"],
            FULL_BOXES: ["hmhd", "nmhd", "iods", "xml ", "bxml", "ipro", "mere"],
            CONTAINER_BOXES: [
              ["moov", ["trak", "pssh"]],
              ["trak"],
              ["edts"],
              ["mdia"],
              ["minf"],
              ["dinf"],
              ["stbl", ["sgpd", "sbgp"]],
              ["mvex", ["trex"]],
              ["moof", ["traf"]],
              ["traf", ["trun", "sgpd", "sbgp"]],
              ["vttc"],
              ["tref"],
              ["iref"],
              ["mfra", ["tfra"]],
              ["meco"],
              ["hnti"],
              ["hinf"],
              ["strk"],
              ["strd"],
              ["sinf"],
              ["rinf"],
              ["schi"],
              ["trgr"],
              ["udta", ["kind"]],
              ["iprp", ["ipma"]],
              ["ipco"],
              ["grpl"],
              ["j2kH"],
              ["etyp", ["tyco"]]
            ],
            // Boxes effectively created
            boxCodes: [],
            fullBoxCodes: [],
            containerBoxCodes: [],
            sampleEntryCodes: {},
            sampleGroupEntryCodes: [],
            trackGroupTypes: [],
            UUIDBoxes: {},
            UUIDs: [],
            initialize: function() {
              BoxParser.FullBox.prototype = new BoxParser.Box();
              BoxParser.ContainerBox.prototype = new BoxParser.Box();
              BoxParser.SampleEntry.prototype = new BoxParser.Box();
              BoxParser.TrackGroupTypeBox.prototype = new BoxParser.FullBox();
              BoxParser.BASIC_BOXES.forEach(function(type) {
                BoxParser.createBoxCtor(type);
              });
              BoxParser.FULL_BOXES.forEach(function(type) {
                BoxParser.createFullBoxCtor(type);
              });
              BoxParser.CONTAINER_BOXES.forEach(function(types) {
                BoxParser.createContainerBoxCtor(types[0], null, types[1]);
              });
            },
            Box: function(_type, _size, _uuid) {
              this.type = _type;
              this.size = _size;
              this.uuid = _uuid;
            },
            FullBox: function(type, size, uuid) {
              BoxParser.Box.call(this, type, size, uuid);
              this.flags = 0;
              this.version = 0;
            },
            ContainerBox: function(type, size, uuid) {
              BoxParser.Box.call(this, type, size, uuid);
              this.boxes = [];
            },
            SampleEntry: function(type, size, hdr_size, start) {
              BoxParser.ContainerBox.call(this, type, size);
              this.hdr_size = hdr_size;
              this.start = start;
            },
            SampleGroupEntry: function(type) {
              this.grouping_type = type;
            },
            TrackGroupTypeBox: function(type, size) {
              BoxParser.FullBox.call(this, type, size);
            },
            createBoxCtor: function(type, parseMethod) {
              BoxParser.boxCodes.push(type);
              BoxParser[type + "Box"] = function(size) {
                BoxParser.Box.call(this, type, size);
              };
              BoxParser[type + "Box"].prototype = new BoxParser.Box();
              if (parseMethod) BoxParser[type + "Box"].prototype.parse = parseMethod;
            },
            createFullBoxCtor: function(type, parseMethod) {
              BoxParser[type + "Box"] = function(size) {
                BoxParser.FullBox.call(this, type, size);
              };
              BoxParser[type + "Box"].prototype = new BoxParser.FullBox();
              BoxParser[type + "Box"].prototype.parse = function(stream) {
                this.parseFullHeader(stream);
                if (parseMethod) {
                  parseMethod.call(this, stream);
                }
              };
            },
            addSubBoxArrays: function(subBoxNames) {
              if (subBoxNames) {
                this.subBoxNames = subBoxNames;
                var nbSubBoxes = subBoxNames.length;
                for (var k = 0; k < nbSubBoxes; k++) {
                  this[subBoxNames[k] + "s"] = [];
                }
              }
            },
            createContainerBoxCtor: function(type, parseMethod, subBoxNames) {
              BoxParser[type + "Box"] = function(size) {
                BoxParser.ContainerBox.call(this, type, size);
                BoxParser.addSubBoxArrays.call(this, subBoxNames);
              };
              BoxParser[type + "Box"].prototype = new BoxParser.ContainerBox();
              if (parseMethod) BoxParser[type + "Box"].prototype.parse = parseMethod;
            },
            createMediaSampleEntryCtor: function(mediaType, parseMethod, subBoxNames) {
              BoxParser.sampleEntryCodes[mediaType] = [];
              BoxParser[mediaType + "SampleEntry"] = function(type, size) {
                BoxParser.SampleEntry.call(this, type, size);
                BoxParser.addSubBoxArrays.call(this, subBoxNames);
              };
              BoxParser[mediaType + "SampleEntry"].prototype = new BoxParser.SampleEntry();
              if (parseMethod) BoxParser[mediaType + "SampleEntry"].prototype.parse = parseMethod;
            },
            createSampleEntryCtor: function(mediaType, type, parseMethod, subBoxNames) {
              BoxParser.sampleEntryCodes[mediaType].push(type);
              BoxParser[type + "SampleEntry"] = function(size) {
                BoxParser[mediaType + "SampleEntry"].call(this, type, size);
                BoxParser.addSubBoxArrays.call(this, subBoxNames);
              };
              BoxParser[type + "SampleEntry"].prototype = new BoxParser[mediaType + "SampleEntry"]();
              if (parseMethod) BoxParser[type + "SampleEntry"].prototype.parse = parseMethod;
            },
            createEncryptedSampleEntryCtor: function(mediaType, type, parseMethod) {
              BoxParser.createSampleEntryCtor.call(this, mediaType, type, parseMethod, ["sinf"]);
            },
            createSampleGroupCtor: function(type, parseMethod) {
              BoxParser[type + "SampleGroupEntry"] = function(size) {
                BoxParser.SampleGroupEntry.call(this, type, size);
              };
              BoxParser[type + "SampleGroupEntry"].prototype = new BoxParser.SampleGroupEntry();
              if (parseMethod) BoxParser[type + "SampleGroupEntry"].prototype.parse = parseMethod;
            },
            createTrackGroupCtor: function(type, parseMethod) {
              BoxParser[type + "TrackGroupTypeBox"] = function(size) {
                BoxParser.TrackGroupTypeBox.call(this, type, size);
              };
              BoxParser[type + "TrackGroupTypeBox"].prototype = new BoxParser.TrackGroupTypeBox();
              if (parseMethod) BoxParser[type + "TrackGroupTypeBox"].prototype.parse = parseMethod;
            },
            createUUIDBox: function(uuid, isFullBox, isContainerBox, parseMethod) {
              BoxParser.UUIDs.push(uuid);
              BoxParser.UUIDBoxes[uuid] = function(size) {
                if (isFullBox) {
                  BoxParser.FullBox.call(this, "uuid", size, uuid);
                } else {
                  if (isContainerBox) {
                    BoxParser.ContainerBox.call(this, "uuid", size, uuid);
                  } else {
                    BoxParser.Box.call(this, "uuid", size, uuid);
                  }
                }
              };
              BoxParser.UUIDBoxes[uuid].prototype = isFullBox ? new BoxParser.FullBox() : isContainerBox ? new BoxParser.ContainerBox() : new BoxParser.Box();
              if (parseMethod) {
                if (isFullBox) {
                  BoxParser.UUIDBoxes[uuid].prototype.parse = function(stream) {
                    this.parseFullHeader(stream);
                    if (parseMethod) {
                      parseMethod.call(this, stream);
                    }
                  };
                } else {
                  BoxParser.UUIDBoxes[uuid].prototype.parse = parseMethod;
                }
              }
            }
          };
          BoxParser.initialize();
          BoxParser.TKHD_FLAG_ENABLED = 1;
          BoxParser.TKHD_FLAG_IN_MOVIE = 2;
          BoxParser.TKHD_FLAG_IN_PREVIEW = 4;
          BoxParser.TFHD_FLAG_BASE_DATA_OFFSET = 1;
          BoxParser.TFHD_FLAG_SAMPLE_DESC = 2;
          BoxParser.TFHD_FLAG_SAMPLE_DUR = 8;
          BoxParser.TFHD_FLAG_SAMPLE_SIZE = 16;
          BoxParser.TFHD_FLAG_SAMPLE_FLAGS = 32;
          BoxParser.TFHD_FLAG_DUR_EMPTY = 65536;
          BoxParser.TFHD_FLAG_DEFAULT_BASE_IS_MOOF = 131072;
          BoxParser.TRUN_FLAGS_DATA_OFFSET = 1;
          BoxParser.TRUN_FLAGS_FIRST_FLAG = 4;
          BoxParser.TRUN_FLAGS_DURATION = 256;
          BoxParser.TRUN_FLAGS_SIZE = 512;
          BoxParser.TRUN_FLAGS_FLAGS = 1024;
          BoxParser.TRUN_FLAGS_CTS_OFFSET = 2048;
          BoxParser.Box.prototype.add = function(name) {
            return this.addBox(new BoxParser[name + "Box"]());
          };
          BoxParser.Box.prototype.addBox = function(box2) {
            this.boxes.push(box2);
            if (this[box2.type + "s"]) {
              this[box2.type + "s"].push(box2);
            } else {
              this[box2.type] = box2;
            }
            return box2;
          };
          BoxParser.Box.prototype.set = function(prop, value) {
            this[prop] = value;
            return this;
          };
          BoxParser.Box.prototype.addEntry = function(value, _prop) {
            var prop = _prop || "entries";
            if (!this[prop]) {
              this[prop] = [];
            }
            this[prop].push(value);
            return this;
          };
          {
            exports.BoxParser = BoxParser;
          }
          BoxParser.parseUUID = function(stream) {
            return BoxParser.parseHex16(stream);
          };
          BoxParser.parseHex16 = function(stream) {
            var hex16 = "";
            for (var i2 = 0; i2 < 16; i2++) {
              var hex = stream.readUint8().toString(16);
              hex16 += hex.length === 1 ? "0" + hex : hex;
            }
            return hex16;
          };
          BoxParser.parseOneBox = function(stream, headerOnly, parentSize) {
            var box2;
            var start = stream.getPosition();
            var hdr_size = 0;
            var diff;
            var uuid;
            if (stream.getEndPosition() - start < 8) {
              Log.debug("BoxParser", "Not enough data in stream to parse the type and size of the box");
              return { code: BoxParser.ERR_NOT_ENOUGH_DATA };
            }
            if (parentSize && parentSize < 8) {
              Log.debug("BoxParser", "Not enough bytes left in the parent box to parse a new box");
              return { code: BoxParser.ERR_NOT_ENOUGH_DATA };
            }
            var size = stream.readUint32();
            var type = stream.readString(4);
            var box_type = type;
            Log.debug("BoxParser", "Found box of type '" + type + "' and size " + size + " at position " + start);
            hdr_size = 8;
            if (type == "uuid") {
              if (stream.getEndPosition() - stream.getPosition() < 16 || parentSize - hdr_size < 16) {
                stream.seek(start);
                Log.debug("BoxParser", "Not enough bytes left in the parent box to parse a UUID box");
                return { code: BoxParser.ERR_NOT_ENOUGH_DATA };
              }
              uuid = BoxParser.parseUUID(stream);
              hdr_size += 16;
              box_type = uuid;
            }
            if (size == 1) {
              if (stream.getEndPosition() - stream.getPosition() < 8 || parentSize && parentSize - hdr_size < 8) {
                stream.seek(start);
                Log.warn("BoxParser", 'Not enough data in stream to parse the extended size of the "' + type + '" box');
                return { code: BoxParser.ERR_NOT_ENOUGH_DATA };
              }
              size = stream.readUint64();
              hdr_size += 8;
            } else if (size === 0) {
              if (parentSize) {
                size = parentSize;
              } else {
                if (type !== "mdat") {
                  Log.error("BoxParser", "Unlimited box size not supported for type: '" + type + "'");
                  box2 = new BoxParser.Box(type, size);
                  return { code: BoxParser.OK, box: box2, size: box2.size };
                }
              }
            }
            if (size !== 0 && size < hdr_size) {
              Log.error("BoxParser", "Box of type " + type + " has an invalid size " + size + " (too small to be a box)");
              return { code: BoxParser.ERR_NOT_ENOUGH_DATA, type, size, hdr_size, start };
            }
            if (size !== 0 && parentSize && size > parentSize) {
              Log.error("BoxParser", "Box of type '" + type + "' has a size " + size + " greater than its container size " + parentSize);
              return { code: BoxParser.ERR_NOT_ENOUGH_DATA, type, size, hdr_size, start };
            }
            if (size !== 0 && start + size > stream.getEndPosition()) {
              stream.seek(start);
              Log.info("BoxParser", "Not enough data in stream to parse the entire '" + type + "' box");
              return { code: BoxParser.ERR_NOT_ENOUGH_DATA, type, size, hdr_size, start };
            }
            if (headerOnly) {
              return { code: BoxParser.OK, type, size, hdr_size, start };
            } else {
              if (BoxParser[type + "Box"]) {
                box2 = new BoxParser[type + "Box"](size);
              } else {
                if (type !== "uuid") {
                  Log.warn("BoxParser", "Unknown box type: '" + type + "'");
                  box2 = new BoxParser.Box(type, size);
                  box2.has_unparsed_data = true;
                } else {
                  if (BoxParser.UUIDBoxes[uuid]) {
                    box2 = new BoxParser.UUIDBoxes[uuid](size);
                  } else {
                    Log.warn("BoxParser", "Unknown uuid type: '" + uuid + "'");
                    box2 = new BoxParser.Box(type, size);
                    box2.uuid = uuid;
                    box2.has_unparsed_data = true;
                  }
                }
              }
            }
            box2.hdr_size = hdr_size;
            box2.start = start;
            if (box2.write === BoxParser.Box.prototype.write && box2.type !== "mdat") {
              Log.info("BoxParser", "'" + box_type + "' box writing not yet implemented, keeping unparsed data in memory for later write");
              box2.parseDataAndRewind(stream);
            }
            box2.parse(stream);
            diff = stream.getPosition() - (box2.start + box2.size);
            if (diff < 0) {
              Log.warn("BoxParser", "Parsing of box '" + box_type + "' did not read the entire indicated box data size (missing " + -diff + " bytes), seeking forward");
              stream.seek(box2.start + box2.size);
            } else if (diff > 0) {
              Log.error("BoxParser", "Parsing of box '" + box_type + "' read " + diff + " more bytes than the indicated box data size, seeking backwards");
              if (box2.size !== 0) stream.seek(box2.start + box2.size);
            }
            return { code: BoxParser.OK, box: box2, size: box2.size };
          };
          BoxParser.Box.prototype.parse = function(stream) {
            if (this.type != "mdat") {
              this.data = stream.readUint8Array(this.size - this.hdr_size);
            } else {
              if (this.size === 0) {
                stream.seek(stream.getEndPosition());
              } else {
                stream.seek(this.start + this.size);
              }
            }
          };
          BoxParser.Box.prototype.parseDataAndRewind = function(stream) {
            this.data = stream.readUint8Array(this.size - this.hdr_size);
            stream.position -= this.size - this.hdr_size;
          };
          BoxParser.FullBox.prototype.parseDataAndRewind = function(stream) {
            this.parseFullHeader(stream);
            this.data = stream.readUint8Array(this.size - this.hdr_size);
            this.hdr_size -= 4;
            stream.position -= this.size - this.hdr_size;
          };
          BoxParser.FullBox.prototype.parseFullHeader = function(stream) {
            this.version = stream.readUint8();
            this.flags = stream.readUint24();
            this.hdr_size += 4;
          };
          BoxParser.FullBox.prototype.parse = function(stream) {
            this.parseFullHeader(stream);
            this.data = stream.readUint8Array(this.size - this.hdr_size);
          };
          BoxParser.ContainerBox.prototype.parse = function(stream) {
            var ret2;
            var box2;
            while (stream.getPosition() < this.start + this.size) {
              ret2 = BoxParser.parseOneBox(stream, false, this.size - (stream.getPosition() - this.start));
              if (ret2.code === BoxParser.OK) {
                box2 = ret2.box;
                this.boxes.push(box2);
                if (this.subBoxNames && this.subBoxNames.indexOf(box2.type) != -1) {
                  this[this.subBoxNames[this.subBoxNames.indexOf(box2.type)] + "s"].push(box2);
                } else {
                  var box_type = box2.type !== "uuid" ? box2.type : box2.uuid;
                  if (this[box_type]) {
                    Log.warn("Box of type " + box_type + " already stored in field of this type");
                  } else {
                    this[box_type] = box2;
                  }
                }
              } else {
                return;
              }
            }
          };
          BoxParser.Box.prototype.parseLanguage = function(stream) {
            this.language = stream.readUint16();
            var chars = [];
            chars[0] = this.language >> 10 & 31;
            chars[1] = this.language >> 5 & 31;
            chars[2] = this.language & 31;
            this.languageString = String.fromCharCode(chars[0] + 96, chars[1] + 96, chars[2] + 96);
          };
          BoxParser.SAMPLE_ENTRY_TYPE_VISUAL = "Visual";
          BoxParser.SAMPLE_ENTRY_TYPE_AUDIO = "Audio";
          BoxParser.SAMPLE_ENTRY_TYPE_HINT = "Hint";
          BoxParser.SAMPLE_ENTRY_TYPE_METADATA = "Metadata";
          BoxParser.SAMPLE_ENTRY_TYPE_SUBTITLE = "Subtitle";
          BoxParser.SAMPLE_ENTRY_TYPE_SYSTEM = "System";
          BoxParser.SAMPLE_ENTRY_TYPE_TEXT = "Text";
          BoxParser.SampleEntry.prototype.parseHeader = function(stream) {
            stream.readUint8Array(6);
            this.data_reference_index = stream.readUint16();
            this.hdr_size += 8;
          };
          BoxParser.SampleEntry.prototype.parse = function(stream) {
            this.parseHeader(stream);
            this.data = stream.readUint8Array(this.size - this.hdr_size);
          };
          BoxParser.SampleEntry.prototype.parseDataAndRewind = function(stream) {
            this.parseHeader(stream);
            this.data = stream.readUint8Array(this.size - this.hdr_size);
            this.hdr_size -= 8;
            stream.position -= this.size - this.hdr_size;
          };
          BoxParser.SampleEntry.prototype.parseFooter = function(stream) {
            BoxParser.ContainerBox.prototype.parse.call(this, stream);
          };
          BoxParser.createMediaSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_HINT);
          BoxParser.createMediaSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_METADATA);
          BoxParser.createMediaSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_SUBTITLE);
          BoxParser.createMediaSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_SYSTEM);
          BoxParser.createMediaSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_TEXT);
          BoxParser.createMediaSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, function(stream) {
            var compressorname_length;
            this.parseHeader(stream);
            stream.readUint16();
            stream.readUint16();
            stream.readUint32Array(3);
            this.width = stream.readUint16();
            this.height = stream.readUint16();
            this.horizresolution = stream.readUint32();
            this.vertresolution = stream.readUint32();
            stream.readUint32();
            this.frame_count = stream.readUint16();
            compressorname_length = Math.min(31, stream.readUint8());
            this.compressorname = stream.readString(compressorname_length);
            if (compressorname_length < 31) {
              stream.readString(31 - compressorname_length);
            }
            this.depth = stream.readUint16();
            stream.readUint16();
            this.parseFooter(stream);
          });
          BoxParser.createMediaSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, function(stream) {
            this.parseHeader(stream);
            stream.readUint32Array(2);
            this.channel_count = stream.readUint16();
            this.samplesize = stream.readUint16();
            stream.readUint16();
            stream.readUint16();
            this.samplerate = stream.readUint32() / (1 << 16);
            this.parseFooter(stream);
          });
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "avc1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "avc2");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "avc3");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "avc4");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "av01");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "dav1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "hvc1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "hev1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "hvt1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "lhe1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "dvh1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "dvhe");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "vvc1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "vvi1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "vvs1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "vvcN");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "vp08");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "vp09");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "avs3");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "j2ki");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "mjp2");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "mjpg");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "uncv");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, "mp4a");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, "ac-3");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, "ac-4");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, "ec-3");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, "Opus");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, "mha1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, "mha2");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, "mhm1");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, "mhm2");
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, "fLaC");
          BoxParser.createEncryptedSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_VISUAL, "encv");
          BoxParser.createEncryptedSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_AUDIO, "enca");
          BoxParser.createEncryptedSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_SUBTITLE, "encu");
          BoxParser.createEncryptedSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_SYSTEM, "encs");
          BoxParser.createEncryptedSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_TEXT, "enct");
          BoxParser.createEncryptedSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_METADATA, "encm");
          BoxParser.createBoxCtor("a1lx", function(stream) {
            var large_size = stream.readUint8() & 1;
            var FieldLength = ((large_size & 1) + 1) * 16;
            this.layer_size = [];
            for (var i2 = 0; i2 < 3; i2++) {
              if (FieldLength == 16) {
                this.layer_size[i2] = stream.readUint16();
              } else {
                this.layer_size[i2] = stream.readUint32();
              }
            }
          });
          BoxParser.createBoxCtor("a1op", function(stream) {
            this.op_index = stream.readUint8();
          });
          BoxParser.createFullBoxCtor("auxC", function(stream) {
            this.aux_type = stream.readCString();
            var aux_subtype_length = this.size - this.hdr_size - (this.aux_type.length + 1);
            this.aux_subtype = stream.readUint8Array(aux_subtype_length);
          });
          BoxParser.createBoxCtor("av1C", function(stream) {
            var tmp = stream.readUint8();
            if (tmp >> 7 & false) {
              Log.error("av1C marker problem");
              return;
            }
            this.version = tmp & 127;
            if (this.version !== 1) {
              Log.error("av1C version " + this.version + " not supported");
              return;
            }
            tmp = stream.readUint8();
            this.seq_profile = tmp >> 5 & 7;
            this.seq_level_idx_0 = tmp & 31;
            tmp = stream.readUint8();
            this.seq_tier_0 = tmp >> 7 & 1;
            this.high_bitdepth = tmp >> 6 & 1;
            this.twelve_bit = tmp >> 5 & 1;
            this.monochrome = tmp >> 4 & 1;
            this.chroma_subsampling_x = tmp >> 3 & 1;
            this.chroma_subsampling_y = tmp >> 2 & 1;
            this.chroma_sample_position = tmp & 3;
            tmp = stream.readUint8();
            this.reserved_1 = tmp >> 5 & 7;
            if (this.reserved_1 !== 0) {
              Log.error("av1C reserved_1 parsing problem");
              return;
            }
            this.initial_presentation_delay_present = tmp >> 4 & 1;
            if (this.initial_presentation_delay_present === 1) {
              this.initial_presentation_delay_minus_one = tmp & 15;
            } else {
              this.reserved_2 = tmp & 15;
              if (this.reserved_2 !== 0) {
                Log.error("av1C reserved_2 parsing problem");
                return;
              }
            }
            var configOBUs_length = this.size - this.hdr_size - 4;
            this.configOBUs = stream.readUint8Array(configOBUs_length);
          });
          BoxParser.createBoxCtor("avcC", function(stream) {
            var i2;
            var toparse;
            this.configurationVersion = stream.readUint8();
            this.AVCProfileIndication = stream.readUint8();
            this.profile_compatibility = stream.readUint8();
            this.AVCLevelIndication = stream.readUint8();
            this.lengthSizeMinusOne = stream.readUint8() & 3;
            this.nb_SPS_nalus = stream.readUint8() & 31;
            toparse = this.size - this.hdr_size - 6;
            this.SPS = [];
            for (i2 = 0; i2 < this.nb_SPS_nalus; i2++) {
              this.SPS[i2] = {};
              this.SPS[i2].length = stream.readUint16();
              this.SPS[i2].nalu = stream.readUint8Array(this.SPS[i2].length);
              toparse -= 2 + this.SPS[i2].length;
            }
            this.nb_PPS_nalus = stream.readUint8();
            toparse--;
            this.PPS = [];
            for (i2 = 0; i2 < this.nb_PPS_nalus; i2++) {
              this.PPS[i2] = {};
              this.PPS[i2].length = stream.readUint16();
              this.PPS[i2].nalu = stream.readUint8Array(this.PPS[i2].length);
              toparse -= 2 + this.PPS[i2].length;
            }
            if (toparse > 0) {
              this.ext = stream.readUint8Array(toparse);
            }
          });
          BoxParser.createBoxCtor("btrt", function(stream) {
            this.bufferSizeDB = stream.readUint32();
            this.maxBitrate = stream.readUint32();
            this.avgBitrate = stream.readUint32();
          });
          BoxParser.createFullBoxCtor("ccst", function(stream) {
            var flags = stream.readUint8();
            this.all_ref_pics_intra = (flags & 128) == 128;
            this.intra_pred_used = (flags & 64) == 64;
            this.max_ref_per_pic = (flags & 63) >> 2;
            stream.readUint24();
          });
          BoxParser.createBoxCtor("cdef", function(stream) {
            var i2;
            this.channel_count = stream.readUint16();
            this.channel_indexes = [];
            this.channel_types = [];
            this.channel_associations = [];
            for (i2 = 0; i2 < this.channel_count; i2++) {
              this.channel_indexes.push(stream.readUint16());
              this.channel_types.push(stream.readUint16());
              this.channel_associations.push(stream.readUint16());
            }
          });
          BoxParser.createBoxCtor("clap", function(stream) {
            this.cleanApertureWidthN = stream.readUint32();
            this.cleanApertureWidthD = stream.readUint32();
            this.cleanApertureHeightN = stream.readUint32();
            this.cleanApertureHeightD = stream.readUint32();
            this.horizOffN = stream.readUint32();
            this.horizOffD = stream.readUint32();
            this.vertOffN = stream.readUint32();
            this.vertOffD = stream.readUint32();
          });
          BoxParser.createBoxCtor("clli", function(stream) {
            this.max_content_light_level = stream.readUint16();
            this.max_pic_average_light_level = stream.readUint16();
          });
          BoxParser.createFullBoxCtor("cmex", function(stream) {
            if (this.flags & 1) {
              this.pos_x = stream.readInt32();
            }
            if (this.flags & 2) {
              this.pos_y = stream.readInt32();
            }
            if (this.flags & 4) {
              this.pos_z = stream.readInt32();
            }
            if (this.flags & 8) {
              if (this.version == 0) {
                if (this.flags & 16) {
                  this.quat_x = stream.readInt32();
                  this.quat_y = stream.readInt32();
                  this.quat_z = stream.readInt32();
                } else {
                  this.quat_x = stream.readInt16();
                  this.quat_y = stream.readInt16();
                  this.quat_z = stream.readInt16();
                }
              } else if (this.version == 1) ;
            }
            if (this.flags & 32) {
              this.id = stream.readUint32();
            }
          });
          BoxParser.createFullBoxCtor("cmin", function(stream) {
            this.focal_length_x = stream.readInt32();
            this.principal_point_x = stream.readInt32();
            this.principal_point_y = stream.readInt32();
            if (this.flags & 1) {
              this.focal_length_y = stream.readInt32();
              this.skew_factor = stream.readInt32();
            }
          });
          BoxParser.createBoxCtor("cmpd", function(stream) {
            this.component_count = stream.readUint32();
            this.component_types = [];
            this.component_type_urls = [];
            for (i = 0; i < this.component_count; i++) {
              var component_type = stream.readUint16();
              this.component_types.push(component_type);
              if (component_type >= 32768) {
                this.component_type_urls.push(stream.readCString());
              }
            }
          });
          BoxParser.createFullBoxCtor("co64", function(stream) {
            var entry_count2;
            var i2;
            entry_count2 = stream.readUint32();
            this.chunk_offsets = [];
            if (this.version === 0) {
              for (i2 = 0; i2 < entry_count2; i2++) {
                this.chunk_offsets.push(stream.readUint64());
              }
            }
          });
          BoxParser.createFullBoxCtor("CoLL", function(stream) {
            this.maxCLL = stream.readUint16();
            this.maxFALL = stream.readUint16();
          });
          BoxParser.createBoxCtor("colr", function(stream) {
            this.colour_type = stream.readString(4);
            if (this.colour_type === "nclx") {
              this.colour_primaries = stream.readUint16();
              this.transfer_characteristics = stream.readUint16();
              this.matrix_coefficients = stream.readUint16();
              var tmp = stream.readUint8();
              this.full_range_flag = tmp >> 7;
            } else if (this.colour_type === "rICC") {
              this.ICC_profile = stream.readUint8Array(this.size - 4);
            } else if (this.colour_type === "prof") {
              this.ICC_profile = stream.readUint8Array(this.size - 4);
            }
          });
          BoxParser.createFullBoxCtor("cprt", function(stream) {
            this.parseLanguage(stream);
            this.notice = stream.readCString();
          });
          BoxParser.createFullBoxCtor("cslg", function(stream) {
            if (this.version === 0) {
              this.compositionToDTSShift = stream.readInt32();
              this.leastDecodeToDisplayDelta = stream.readInt32();
              this.greatestDecodeToDisplayDelta = stream.readInt32();
              this.compositionStartTime = stream.readInt32();
              this.compositionEndTime = stream.readInt32();
            }
          });
          BoxParser.createFullBoxCtor("ctts", function(stream) {
            var entry_count2;
            var i2;
            entry_count2 = stream.readUint32();
            this.sample_counts = [];
            this.sample_offsets = [];
            if (this.version === 0) {
              for (i2 = 0; i2 < entry_count2; i2++) {
                this.sample_counts.push(stream.readUint32());
                var value = stream.readInt32();
                if (value < 0) {
                  Log.warn("BoxParser", "ctts box uses negative values without using version 1");
                }
                this.sample_offsets.push(value);
              }
            } else if (this.version == 1) {
              for (i2 = 0; i2 < entry_count2; i2++) {
                this.sample_counts.push(stream.readUint32());
                this.sample_offsets.push(stream.readInt32());
              }
            }
          });
          BoxParser.createBoxCtor("dac3", function(stream) {
            var tmp_byte1 = stream.readUint8();
            var tmp_byte2 = stream.readUint8();
            var tmp_byte3 = stream.readUint8();
            this.fscod = tmp_byte1 >> 6;
            this.bsid = tmp_byte1 >> 1 & 31;
            this.bsmod = (tmp_byte1 & 1) << 2 | tmp_byte2 >> 6 & 3;
            this.acmod = tmp_byte2 >> 3 & 7;
            this.lfeon = tmp_byte2 >> 2 & 1;
            this.bit_rate_code = tmp_byte2 & 3 | tmp_byte3 >> 5 & 7;
          });
          BoxParser.createBoxCtor("dec3", function(stream) {
            var tmp_16 = stream.readUint16();
            this.data_rate = tmp_16 >> 3;
            this.num_ind_sub = tmp_16 & 7;
            this.ind_subs = [];
            for (var i2 = 0; i2 < this.num_ind_sub + 1; i2++) {
              var ind_sub = {};
              this.ind_subs.push(ind_sub);
              var tmp_byte1 = stream.readUint8();
              var tmp_byte2 = stream.readUint8();
              var tmp_byte3 = stream.readUint8();
              ind_sub.fscod = tmp_byte1 >> 6;
              ind_sub.bsid = tmp_byte1 >> 1 & 31;
              ind_sub.bsmod = (tmp_byte1 & 1) << 4 | tmp_byte2 >> 4 & 15;
              ind_sub.acmod = tmp_byte2 >> 1 & 7;
              ind_sub.lfeon = tmp_byte2 & 1;
              ind_sub.num_dep_sub = tmp_byte3 >> 1 & 15;
              if (ind_sub.num_dep_sub > 0) {
                ind_sub.chan_loc = (tmp_byte3 & 1) << 8 | stream.readUint8();
              }
            }
          });
          BoxParser.createFullBoxCtor("dfLa", function(stream) {
            var BLOCKTYPE_MASK = 127;
            var LASTMETADATABLOCKFLAG_MASK = 128;
            var boxesFound = [];
            var knownBlockTypes = [
              "STREAMINFO",
              "PADDING",
              "APPLICATION",
              "SEEKTABLE",
              "VORBIS_COMMENT",
              "CUESHEET",
              "PICTURE",
              "RESERVED"
            ];
            do {
              var flagAndType = stream.readUint8();
              var type = Math.min(
                flagAndType & BLOCKTYPE_MASK,
                knownBlockTypes.length - 1
              );
              if (!type) {
                stream.readUint8Array(13);
                this.samplerate = stream.readUint32() >> 12;
                stream.readUint8Array(20);
              } else {
                stream.readUint8Array(stream.readUint24());
              }
              boxesFound.push(knownBlockTypes[type]);
              if (!!(flagAndType & LASTMETADATABLOCKFLAG_MASK)) {
                break;
              }
            } while (true);
            this.numMetadataBlocks = boxesFound.length + " (" + boxesFound.join(", ") + ")";
          });
          BoxParser.createBoxCtor("dimm", function(stream) {
            this.bytessent = stream.readUint64();
          });
          BoxParser.createBoxCtor("dmax", function(stream) {
            this.time = stream.readUint32();
          });
          BoxParser.createBoxCtor("dmed", function(stream) {
            this.bytessent = stream.readUint64();
          });
          BoxParser.createBoxCtor("dOps", function(stream) {
            this.Version = stream.readUint8();
            this.OutputChannelCount = stream.readUint8();
            this.PreSkip = stream.readUint16();
            this.InputSampleRate = stream.readUint32();
            this.OutputGain = stream.readInt16();
            this.ChannelMappingFamily = stream.readUint8();
            if (this.ChannelMappingFamily !== 0) {
              this.StreamCount = stream.readUint8();
              this.CoupledCount = stream.readUint8();
              this.ChannelMapping = [];
              for (var i2 = 0; i2 < this.OutputChannelCount; i2++) {
                this.ChannelMapping[i2] = stream.readUint8();
              }
            }
          });
          BoxParser.createFullBoxCtor("dref", function(stream) {
            var ret2;
            var box2;
            this.entries = [];
            var entry_count2 = stream.readUint32();
            for (var i2 = 0; i2 < entry_count2; i2++) {
              ret2 = BoxParser.parseOneBox(stream, false, this.size - (stream.getPosition() - this.start));
              if (ret2.code === BoxParser.OK) {
                box2 = ret2.box;
                this.entries.push(box2);
              } else {
                return;
              }
            }
          });
          BoxParser.createBoxCtor("drep", function(stream) {
            this.bytessent = stream.readUint64();
          });
          BoxParser.createFullBoxCtor("elng", function(stream) {
            this.extended_language = stream.readString(this.size - this.hdr_size);
          });
          BoxParser.createFullBoxCtor("elst", function(stream) {
            this.entries = [];
            var entry_count2 = stream.readUint32();
            for (var i2 = 0; i2 < entry_count2; i2++) {
              var entry = {};
              this.entries.push(entry);
              if (this.version === 1) {
                entry.segment_duration = stream.readUint64();
                entry.media_time = stream.readInt64();
              } else {
                entry.segment_duration = stream.readUint32();
                entry.media_time = stream.readInt32();
              }
              entry.media_rate_integer = stream.readInt16();
              entry.media_rate_fraction = stream.readInt16();
            }
          });
          BoxParser.createFullBoxCtor("emsg", function(stream) {
            if (this.version == 1) {
              this.timescale = stream.readUint32();
              this.presentation_time = stream.readUint64();
              this.event_duration = stream.readUint32();
              this.id = stream.readUint32();
              this.scheme_id_uri = stream.readCString();
              this.value = stream.readCString();
            } else {
              this.scheme_id_uri = stream.readCString();
              this.value = stream.readCString();
              this.timescale = stream.readUint32();
              this.presentation_time_delta = stream.readUint32();
              this.event_duration = stream.readUint32();
              this.id = stream.readUint32();
            }
            var message_size = this.size - this.hdr_size - (4 * 4 + (this.scheme_id_uri.length + 1) + (this.value.length + 1));
            if (this.version == 1) {
              message_size -= 4;
            }
            this.message_data = stream.readUint8Array(message_size);
          });
          BoxParser.createEntityToGroupCtor = function(type, parseMethod) {
            BoxParser[type + "Box"] = function(size) {
              BoxParser.FullBox.call(this, type, size);
            };
            BoxParser[type + "Box"].prototype = new BoxParser.FullBox();
            BoxParser[type + "Box"].prototype.parse = function(stream) {
              this.parseFullHeader(stream);
              if (parseMethod) {
                parseMethod.call(this, stream);
              } else {
                this.group_id = stream.readUint32();
                this.num_entities_in_group = stream.readUint32();
                this.entity_ids = [];
                for (i = 0; i < this.num_entities_in_group; i++) {
                  var entity_id = stream.readUint32();
                  this.entity_ids.push(entity_id);
                }
              }
            };
          };
          BoxParser.createEntityToGroupCtor("aebr");
          BoxParser.createEntityToGroupCtor("afbr");
          BoxParser.createEntityToGroupCtor("albc");
          BoxParser.createEntityToGroupCtor("altr");
          BoxParser.createEntityToGroupCtor("brst");
          BoxParser.createEntityToGroupCtor("dobr");
          BoxParser.createEntityToGroupCtor("eqiv");
          BoxParser.createEntityToGroupCtor("favc");
          BoxParser.createEntityToGroupCtor("fobr");
          BoxParser.createEntityToGroupCtor("iaug");
          BoxParser.createEntityToGroupCtor("pano");
          BoxParser.createEntityToGroupCtor("slid");
          BoxParser.createEntityToGroupCtor("ster");
          BoxParser.createEntityToGroupCtor("tsyn");
          BoxParser.createEntityToGroupCtor("wbbr");
          BoxParser.createEntityToGroupCtor("prgr");
          BoxParser.createEntityToGroupCtor("pymd", function(stream) {
            this.group_id = stream.readUint32();
            this.num_entities_in_group = stream.readUint32();
            this.entity_ids = [];
            for (var i2 = 0; i2 < this.num_entities_in_group; i2++) {
              var entity_id = stream.readUint32();
              this.entity_ids.push(entity_id);
            }
            this.tile_size_x = stream.readUint16();
            this.tile_size_y = stream.readUint16();
            this.layer_binning = [];
            this.tiles_in_layer_column_minus1 = [];
            this.tiles_in_layer_row_minus1 = [];
            for (i2 = 0; i2 < this.num_entities_in_group; i2++) {
              this.layer_binning[i2] = stream.readUint16();
              this.tiles_in_layer_row_minus1[i2] = stream.readUint16();
              this.tiles_in_layer_column_minus1[i2] = stream.readUint16();
            }
          });
          BoxParser.createFullBoxCtor("esds", function(stream) {
            var esd_data = stream.readUint8Array(this.size - this.hdr_size);
            if (typeof MPEG4DescriptorParser !== "undefined") {
              var esd_parser = new MPEG4DescriptorParser();
              this.esd = esd_parser.parseOneDescriptor(new DataStream(esd_data.buffer, 0, DataStream.BIG_ENDIAN));
            }
          });
          BoxParser.createBoxCtor("fiel", function(stream) {
            this.fieldCount = stream.readUint8();
            this.fieldOrdering = stream.readUint8();
          });
          BoxParser.createBoxCtor("frma", function(stream) {
            this.data_format = stream.readString(4);
          });
          BoxParser.createBoxCtor("ftyp", function(stream) {
            var toparse = this.size - this.hdr_size;
            this.major_brand = stream.readString(4);
            this.minor_version = stream.readUint32();
            toparse -= 8;
            this.compatible_brands = [];
            var i2 = 0;
            while (toparse >= 4) {
              this.compatible_brands[i2] = stream.readString(4);
              toparse -= 4;
              i2++;
            }
          });
          BoxParser.createFullBoxCtor("hdlr", function(stream) {
            if (this.version === 0) {
              stream.readUint32();
              this.handler = stream.readString(4);
              stream.readUint32Array(3);
              this.name = stream.readString(this.size - this.hdr_size - 20);
              if (this.name[this.name.length - 1] === "\0") {
                this.name = this.name.slice(0, -1);
              }
            }
          });
          BoxParser.createBoxCtor("hvcC", function(stream) {
            var i2, j;
            var length;
            var tmp_byte;
            this.configurationVersion = stream.readUint8();
            tmp_byte = stream.readUint8();
            this.general_profile_space = tmp_byte >> 6;
            this.general_tier_flag = (tmp_byte & 32) >> 5;
            this.general_profile_idc = tmp_byte & 31;
            this.general_profile_compatibility = stream.readUint32();
            this.general_constraint_indicator = stream.readUint8Array(6);
            this.general_level_idc = stream.readUint8();
            this.min_spatial_segmentation_idc = stream.readUint16() & 4095;
            this.parallelismType = stream.readUint8() & 3;
            this.chroma_format_idc = stream.readUint8() & 3;
            this.bit_depth_luma_minus8 = stream.readUint8() & 7;
            this.bit_depth_chroma_minus8 = stream.readUint8() & 7;
            this.avgFrameRate = stream.readUint16();
            tmp_byte = stream.readUint8();
            this.constantFrameRate = tmp_byte >> 6;
            this.numTemporalLayers = (tmp_byte & 13) >> 3;
            this.temporalIdNested = (tmp_byte & 4) >> 2;
            this.lengthSizeMinusOne = tmp_byte & 3;
            this.nalu_arrays = [];
            var numOfArrays = stream.readUint8();
            for (i2 = 0; i2 < numOfArrays; i2++) {
              var nalu_array = [];
              this.nalu_arrays.push(nalu_array);
              tmp_byte = stream.readUint8();
              nalu_array.completeness = (tmp_byte & 128) >> 7;
              nalu_array.nalu_type = tmp_byte & 63;
              var numNalus = stream.readUint16();
              for (j = 0; j < numNalus; j++) {
                var nalu = {};
                nalu_array.push(nalu);
                length = stream.readUint16();
                nalu.data = stream.readUint8Array(length);
              }
            }
          });
          BoxParser.createFullBoxCtor("iinf", function(stream) {
            var ret2;
            if (this.version === 0) {
              this.entry_count = stream.readUint16();
            } else {
              this.entry_count = stream.readUint32();
            }
            this.item_infos = [];
            for (var i2 = 0; i2 < this.entry_count; i2++) {
              ret2 = BoxParser.parseOneBox(stream, false, this.size - (stream.getPosition() - this.start));
              if (ret2.code === BoxParser.OK) {
                if (ret2.box.type !== "infe") {
                  Log.error("BoxParser", "Expected 'infe' box, got " + ret2.box.type);
                }
                this.item_infos[i2] = ret2.box;
              } else {
                return;
              }
            }
          });
          BoxParser.createFullBoxCtor("iloc", function(stream) {
            var byte;
            byte = stream.readUint8();
            this.offset_size = byte >> 4 & 15;
            this.length_size = byte & 15;
            byte = stream.readUint8();
            this.base_offset_size = byte >> 4 & 15;
            if (this.version === 1 || this.version === 2) {
              this.index_size = byte & 15;
            } else {
              this.index_size = 0;
            }
            this.items = [];
            var item_count = 0;
            if (this.version < 2) {
              item_count = stream.readUint16();
            } else if (this.version === 2) {
              item_count = stream.readUint32();
            } else {
              throw "version of iloc box not supported";
            }
            for (var i2 = 0; i2 < item_count; i2++) {
              var item = {};
              this.items.push(item);
              if (this.version < 2) {
                item.item_ID = stream.readUint16();
              } else if (this.version === 2) {
                item.item_ID = stream.readUint32();
              } else {
                throw "version of iloc box not supported";
              }
              if (this.version === 1 || this.version === 2) {
                item.construction_method = stream.readUint16() & 15;
              } else {
                item.construction_method = 0;
              }
              item.data_reference_index = stream.readUint16();
              switch (this.base_offset_size) {
                case 0:
                  item.base_offset = 0;
                  break;
                case 4:
                  item.base_offset = stream.readUint32();
                  break;
                case 8:
                  item.base_offset = stream.readUint64();
                  break;
                default:
                  throw "Error reading base offset size";
              }
              var extent_count = stream.readUint16();
              item.extents = [];
              for (var j = 0; j < extent_count; j++) {
                var extent = {};
                item.extents.push(extent);
                if (this.version === 1 || this.version === 2) {
                  switch (this.index_size) {
                    case 0:
                      extent.extent_index = 0;
                      break;
                    case 4:
                      extent.extent_index = stream.readUint32();
                      break;
                    case 8:
                      extent.extent_index = stream.readUint64();
                      break;
                    default:
                      throw "Error reading extent index";
                  }
                }
                switch (this.offset_size) {
                  case 0:
                    extent.extent_offset = 0;
                    break;
                  case 4:
                    extent.extent_offset = stream.readUint32();
                    break;
                  case 8:
                    extent.extent_offset = stream.readUint64();
                    break;
                  default:
                    throw "Error reading extent index";
                }
                switch (this.length_size) {
                  case 0:
                    extent.extent_length = 0;
                    break;
                  case 4:
                    extent.extent_length = stream.readUint32();
                    break;
                  case 8:
                    extent.extent_length = stream.readUint64();
                    break;
                  default:
                    throw "Error reading extent index";
                }
              }
            }
          });
          BoxParser.createBoxCtor("imir", function(stream) {
            var tmp = stream.readUint8();
            this.reserved = tmp >> 7;
            this.axis = tmp & 1;
          });
          BoxParser.createFullBoxCtor("infe", function(stream) {
            if (this.version === 0 || this.version === 1) {
              this.item_ID = stream.readUint16();
              this.item_protection_index = stream.readUint16();
              this.item_name = stream.readCString();
              this.content_type = stream.readCString();
              this.content_encoding = stream.readCString();
            }
            if (this.version === 1) {
              this.extension_type = stream.readString(4);
              Log.warn("BoxParser", "Cannot parse extension type");
              stream.seek(this.start + this.size);
              return;
            }
            if (this.version >= 2) {
              if (this.version === 2) {
                this.item_ID = stream.readUint16();
              } else if (this.version === 3) {
                this.item_ID = stream.readUint32();
              }
              this.item_protection_index = stream.readUint16();
              this.item_type = stream.readString(4);
              this.item_name = stream.readCString();
              if (this.item_type === "mime") {
                this.content_type = stream.readCString();
                this.content_encoding = stream.readCString();
              } else if (this.item_type === "uri ") {
                this.item_uri_type = stream.readCString();
              }
            }
          });
          BoxParser.createFullBoxCtor("ipma", function(stream) {
            var i2, j;
            entry_count = stream.readUint32();
            this.associations = [];
            for (i2 = 0; i2 < entry_count; i2++) {
              var item_assoc = {};
              this.associations.push(item_assoc);
              if (this.version < 1) {
                item_assoc.id = stream.readUint16();
              } else {
                item_assoc.id = stream.readUint32();
              }
              var association_count = stream.readUint8();
              item_assoc.props = [];
              for (j = 0; j < association_count; j++) {
                var tmp = stream.readUint8();
                var p = {};
                item_assoc.props.push(p);
                p.essential = (tmp & 128) >> 7 === 1;
                if (this.flags & 1) {
                  p.property_index = (tmp & 127) << 8 | stream.readUint8();
                } else {
                  p.property_index = tmp & 127;
                }
              }
            }
          });
          BoxParser.createFullBoxCtor("iref", function(stream) {
            var ret2;
            var box2;
            this.references = [];
            while (stream.getPosition() < this.start + this.size) {
              ret2 = BoxParser.parseOneBox(stream, true, this.size - (stream.getPosition() - this.start));
              if (ret2.code === BoxParser.OK) {
                if (this.version === 0) {
                  box2 = new BoxParser.SingleItemTypeReferenceBox(ret2.type, ret2.size, ret2.hdr_size, ret2.start);
                } else {
                  box2 = new BoxParser.SingleItemTypeReferenceBoxLarge(ret2.type, ret2.size, ret2.hdr_size, ret2.start);
                }
                if (box2.write === BoxParser.Box.prototype.write && box2.type !== "mdat") {
                  Log.warn("BoxParser", box2.type + " box writing not yet implemented, keeping unparsed data in memory for later write");
                  box2.parseDataAndRewind(stream);
                }
                box2.parse(stream);
                this.references.push(box2);
              } else {
                return;
              }
            }
          });
          BoxParser.createBoxCtor("irot", function(stream) {
            this.angle = stream.readUint8() & 3;
          });
          BoxParser.createFullBoxCtor("ispe", function(stream) {
            this.image_width = stream.readUint32();
            this.image_height = stream.readUint32();
          });
          BoxParser.createFullBoxCtor("kind", function(stream) {
            this.schemeURI = stream.readCString();
            this.value = stream.readCString();
          });
          BoxParser.createFullBoxCtor("leva", function(stream) {
            var count = stream.readUint8();
            this.levels = [];
            for (var i2 = 0; i2 < count; i2++) {
              var level = {};
              this.levels[i2] = level;
              level.track_ID = stream.readUint32();
              var tmp_byte = stream.readUint8();
              level.padding_flag = tmp_byte >> 7;
              level.assignment_type = tmp_byte & 127;
              switch (level.assignment_type) {
                case 0:
                  level.grouping_type = stream.readString(4);
                  break;
                case 1:
                  level.grouping_type = stream.readString(4);
                  level.grouping_type_parameter = stream.readUint32();
                  break;
                case 2:
                  break;
                case 3:
                  break;
                case 4:
                  level.sub_track_id = stream.readUint32();
                  break;
                default:
                  Log.warn("BoxParser", "Unknown leva assignement type");
              }
            }
          });
          BoxParser.createBoxCtor("lhvC", function(stream) {
            var i2, j;
            var tmp_byte;
            this.configurationVersion = stream.readUint8();
            this.min_spatial_segmentation_idc = stream.readUint16() & 4095;
            this.parallelismType = stream.readUint8() & 3;
            tmp_byte = stream.readUint8();
            this.numTemporalLayers = (tmp_byte & 13) >> 3;
            this.temporalIdNested = (tmp_byte & 4) >> 2;
            this.lengthSizeMinusOne = tmp_byte & 3;
            this.nalu_arrays = [];
            var numOfArrays = stream.readUint8();
            for (i2 = 0; i2 < numOfArrays; i2++) {
              var nalu_array = [];
              this.nalu_arrays.push(nalu_array);
              tmp_byte = stream.readUint8();
              nalu_array.completeness = (tmp_byte & 128) >> 7;
              nalu_array.nalu_type = tmp_byte & 63;
              var numNalus = stream.readUint16();
              for (j = 0; j < numNalus; j++) {
                var nalu = {};
                nalu_array.push(nalu);
                var length = stream.readUint16();
                nalu.data = stream.readUint8Array(length);
              }
            }
          });
          BoxParser.createBoxCtor("lsel", function(stream) {
            this.layer_id = stream.readUint16();
          });
          BoxParser.createBoxCtor("maxr", function(stream) {
            this.period = stream.readUint32();
            this.bytes = stream.readUint32();
          });
          function ColorPoint(x, y) {
            this.x = x;
            this.y = y;
          }
          ColorPoint.prototype.toString = function() {
            return "(" + this.x + "," + this.y + ")";
          };
          BoxParser.createBoxCtor("mdcv", function(stream) {
            this.display_primaries = [];
            this.display_primaries[0] = new ColorPoint(stream.readUint16(), stream.readUint16());
            this.display_primaries[1] = new ColorPoint(stream.readUint16(), stream.readUint16());
            this.display_primaries[2] = new ColorPoint(stream.readUint16(), stream.readUint16());
            this.white_point = new ColorPoint(stream.readUint16(), stream.readUint16());
            this.max_display_mastering_luminance = stream.readUint32();
            this.min_display_mastering_luminance = stream.readUint32();
          });
          BoxParser.createFullBoxCtor("mdhd", function(stream) {
            if (this.version == 1) {
              this.creation_time = stream.readUint64();
              this.modification_time = stream.readUint64();
              this.timescale = stream.readUint32();
              this.duration = stream.readUint64();
            } else {
              this.creation_time = stream.readUint32();
              this.modification_time = stream.readUint32();
              this.timescale = stream.readUint32();
              this.duration = stream.readUint32();
            }
            this.parseLanguage(stream);
            stream.readUint16();
          });
          BoxParser.createFullBoxCtor("mehd", function(stream) {
            if (this.flags & 1) {
              Log.warn("BoxParser", "mehd box incorrectly uses flags set to 1, converting version to 1");
              this.version = 1;
            }
            if (this.version == 1) {
              this.fragment_duration = stream.readUint64();
            } else {
              this.fragment_duration = stream.readUint32();
            }
          });
          BoxParser.createFullBoxCtor("meta", function(stream) {
            this.boxes = [];
            BoxParser.ContainerBox.prototype.parse.call(this, stream);
          });
          BoxParser.createFullBoxCtor("mfhd", function(stream) {
            this.sequence_number = stream.readUint32();
          });
          BoxParser.createFullBoxCtor("mfro", function(stream) {
            this._size = stream.readUint32();
          });
          BoxParser.createFullBoxCtor("mskC", function(stream) {
            this.bits_per_pixel = stream.readUint8();
          });
          BoxParser.createFullBoxCtor("mvhd", function(stream) {
            if (this.version == 1) {
              this.creation_time = stream.readUint64();
              this.modification_time = stream.readUint64();
              this.timescale = stream.readUint32();
              this.duration = stream.readUint64();
            } else {
              this.creation_time = stream.readUint32();
              this.modification_time = stream.readUint32();
              this.timescale = stream.readUint32();
              this.duration = stream.readUint32();
            }
            this.rate = stream.readUint32();
            this.volume = stream.readUint16() >> 8;
            stream.readUint16();
            stream.readUint32Array(2);
            this.matrix = stream.readUint32Array(9);
            stream.readUint32Array(6);
            this.next_track_id = stream.readUint32();
          });
          BoxParser.createBoxCtor("npck", function(stream) {
            this.packetssent = stream.readUint32();
          });
          BoxParser.createBoxCtor("nump", function(stream) {
            this.packetssent = stream.readUint64();
          });
          BoxParser.createFullBoxCtor("padb", function(stream) {
            var sample_count = stream.readUint32();
            this.padbits = [];
            for (var i2 = 0; i2 < Math.floor((sample_count + 1) / 2); i2++) {
              this.padbits = stream.readUint8();
            }
          });
          BoxParser.createBoxCtor("pasp", function(stream) {
            this.hSpacing = stream.readUint32();
            this.vSpacing = stream.readUint32();
          });
          BoxParser.createBoxCtor("payl", function(stream) {
            this.text = stream.readString(this.size - this.hdr_size);
          });
          BoxParser.createBoxCtor("payt", function(stream) {
            this.payloadID = stream.readUint32();
            var count = stream.readUint8();
            this.rtpmap_string = stream.readString(count);
          });
          BoxParser.createFullBoxCtor("pdin", function(stream) {
            var count = (this.size - this.hdr_size) / 8;
            this.rate = [];
            this.initial_delay = [];
            for (var i2 = 0; i2 < count; i2++) {
              this.rate[i2] = stream.readUint32();
              this.initial_delay[i2] = stream.readUint32();
            }
          });
          BoxParser.createFullBoxCtor("pitm", function(stream) {
            if (this.version === 0) {
              this.item_id = stream.readUint16();
            } else {
              this.item_id = stream.readUint32();
            }
          });
          BoxParser.createFullBoxCtor("pixi", function(stream) {
            var i2;
            this.num_channels = stream.readUint8();
            this.bits_per_channels = [];
            for (i2 = 0; i2 < this.num_channels; i2++) {
              this.bits_per_channels[i2] = stream.readUint8();
            }
          });
          BoxParser.createBoxCtor("pmax", function(stream) {
            this.bytes = stream.readUint32();
          });
          BoxParser.createFullBoxCtor("prdi", function(stream) {
            this.step_count = stream.readUint16();
            this.item_count = [];
            if (this.flags & 2) {
              for (var i2 = 0; i2 < this.step_count; i2++) {
                this.item_count[i2] = stream.readUint16();
              }
            }
          });
          BoxParser.createFullBoxCtor("prft", function(stream) {
            this.ref_track_id = stream.readUint32();
            this.ntp_timestamp = stream.readUint64();
            if (this.version === 0) {
              this.media_time = stream.readUint32();
            } else {
              this.media_time = stream.readUint64();
            }
          });
          BoxParser.createFullBoxCtor("pssh", function(stream) {
            this.system_id = BoxParser.parseHex16(stream);
            if (this.version > 0) {
              var count = stream.readUint32();
              this.kid = [];
              for (var i2 = 0; i2 < count; i2++) {
                this.kid[i2] = BoxParser.parseHex16(stream);
              }
            }
            var datasize = stream.readUint32();
            if (datasize > 0) {
              this.data = stream.readUint8Array(datasize);
            }
          });
          BoxParser.createFullBoxCtor("clef", function(stream) {
            this.width = stream.readUint32();
            this.height = stream.readUint32();
          });
          BoxParser.createFullBoxCtor("enof", function(stream) {
            this.width = stream.readUint32();
            this.height = stream.readUint32();
          });
          BoxParser.createFullBoxCtor("prof", function(stream) {
            this.width = stream.readUint32();
            this.height = stream.readUint32();
          });
          BoxParser.createContainerBoxCtor("tapt", null, ["clef", "prof", "enof"]);
          BoxParser.createBoxCtor("rtp ", function(stream) {
            this.descriptionformat = stream.readString(4);
            this.sdptext = stream.readString(this.size - this.hdr_size - 4);
          });
          BoxParser.createFullBoxCtor("saio", function(stream) {
            if (this.flags & 1) {
              this.aux_info_type = stream.readString(4);
              this.aux_info_type_parameter = stream.readUint32();
            }
            var count = stream.readUint32();
            this.offset = [];
            for (var i2 = 0; i2 < count; i2++) {
              if (this.version === 0) {
                this.offset[i2] = stream.readUint32();
              } else {
                this.offset[i2] = stream.readUint64();
              }
            }
          });
          BoxParser.createFullBoxCtor("saiz", function(stream) {
            if (this.flags & 1) {
              this.aux_info_type = stream.readString(4);
              this.aux_info_type_parameter = stream.readUint32();
            }
            this.default_sample_info_size = stream.readUint8();
            this.sample_count = stream.readUint32();
            this.sample_info_size = [];
            if (this.default_sample_info_size === 0) {
              for (var i2 = 0; i2 < this.sample_count; i2++) {
                this.sample_info_size[i2] = stream.readUint8();
              }
            }
          });
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_METADATA, "mett", function(stream) {
            this.parseHeader(stream);
            this.content_encoding = stream.readCString();
            this.mime_format = stream.readCString();
            this.parseFooter(stream);
          });
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_METADATA, "metx", function(stream) {
            this.parseHeader(stream);
            this.content_encoding = stream.readCString();
            this.namespace = stream.readCString();
            this.schema_location = stream.readCString();
            this.parseFooter(stream);
          });
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_SUBTITLE, "sbtt", function(stream) {
            this.parseHeader(stream);
            this.content_encoding = stream.readCString();
            this.mime_format = stream.readCString();
            this.parseFooter(stream);
          });
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_SUBTITLE, "stpp", function(stream) {
            this.parseHeader(stream);
            this.namespace = stream.readCString();
            this.schema_location = stream.readCString();
            this.auxiliary_mime_types = stream.readCString();
            this.parseFooter(stream);
          });
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_SUBTITLE, "stxt", function(stream) {
            this.parseHeader(stream);
            this.content_encoding = stream.readCString();
            this.mime_format = stream.readCString();
            this.parseFooter(stream);
          });
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_SUBTITLE, "tx3g", function(stream) {
            this.parseHeader(stream);
            this.displayFlags = stream.readUint32();
            this.horizontal_justification = stream.readInt8();
            this.vertical_justification = stream.readInt8();
            this.bg_color_rgba = stream.readUint8Array(4);
            this.box_record = stream.readInt16Array(4);
            this.style_record = stream.readUint8Array(12);
            this.parseFooter(stream);
          });
          BoxParser.createSampleEntryCtor(BoxParser.SAMPLE_ENTRY_TYPE_METADATA, "wvtt", function(stream) {
            this.parseHeader(stream);
            this.parseFooter(stream);
          });
          BoxParser.createSampleGroupCtor("alst", function(stream) {
            var i2;
            var roll_count = stream.readUint16();
            this.first_output_sample = stream.readUint16();
            this.sample_offset = [];
            for (i2 = 0; i2 < roll_count; i2++) {
              this.sample_offset[i2] = stream.readUint32();
            }
            var remaining = this.description_length - 4 - 4 * roll_count;
            this.num_output_samples = [];
            this.num_total_samples = [];
            for (i2 = 0; i2 < remaining / 4; i2++) {
              this.num_output_samples[i2] = stream.readUint16();
              this.num_total_samples[i2] = stream.readUint16();
            }
          });
          BoxParser.createSampleGroupCtor("avll", function(stream) {
            this.layerNumber = stream.readUint8();
            this.accurateStatisticsFlag = stream.readUint8();
            this.avgBitRate = stream.readUint16();
            this.avgFrameRate = stream.readUint16();
          });
          BoxParser.createSampleGroupCtor("avss", function(stream) {
            this.subSequenceIdentifier = stream.readUint16();
            this.layerNumber = stream.readUint8();
            var tmp_byte = stream.readUint8();
            this.durationFlag = tmp_byte >> 7;
            this.avgRateFlag = tmp_byte >> 6 & 1;
            if (this.durationFlag) {
              this.duration = stream.readUint32();
            }
            if (this.avgRateFlag) {
              this.accurateStatisticsFlag = stream.readUint8();
              this.avgBitRate = stream.readUint16();
              this.avgFrameRate = stream.readUint16();
            }
            this.dependency = [];
            var numReferences = stream.readUint8();
            for (var i2 = 0; i2 < numReferences; i2++) {
              var dependencyInfo = {};
              this.dependency.push(dependencyInfo);
              dependencyInfo.subSeqDirectionFlag = stream.readUint8();
              dependencyInfo.layerNumber = stream.readUint8();
              dependencyInfo.subSequenceIdentifier = stream.readUint16();
            }
          });
          BoxParser.createSampleGroupCtor("dtrt", function(stream) {
            Log.warn("BoxParser", "Sample Group type: " + this.grouping_type + " not fully parsed");
          });
          BoxParser.createSampleGroupCtor("mvif", function(stream) {
            Log.warn("BoxParser", "Sample Group type: " + this.grouping_type + " not fully parsed");
          });
          BoxParser.createSampleGroupCtor("prol", function(stream) {
            this.roll_distance = stream.readInt16();
          });
          BoxParser.createSampleGroupCtor("rap ", function(stream) {
            var tmp_byte = stream.readUint8();
            this.num_leading_samples_known = tmp_byte >> 7;
            this.num_leading_samples = tmp_byte & 127;
          });
          BoxParser.createSampleGroupCtor("rash", function(stream) {
            this.operation_point_count = stream.readUint16();
            if (this.description_length !== 2 + (this.operation_point_count === 1 ? 2 : this.operation_point_count * 6) + 9) {
              Log.warn("BoxParser", "Mismatch in " + this.grouping_type + " sample group length");
              this.data = stream.readUint8Array(this.description_length - 2);
            } else {
              if (this.operation_point_count === 1) {
                this.target_rate_share = stream.readUint16();
              } else {
                this.target_rate_share = [];
                this.available_bitrate = [];
                for (var i2 = 0; i2 < this.operation_point_count; i2++) {
                  this.available_bitrate[i2] = stream.readUint32();
                  this.target_rate_share[i2] = stream.readUint16();
                }
              }
              this.maximum_bitrate = stream.readUint32();
              this.minimum_bitrate = stream.readUint32();
              this.discard_priority = stream.readUint8();
            }
          });
          BoxParser.createSampleGroupCtor("roll", function(stream) {
            this.roll_distance = stream.readInt16();
          });
          BoxParser.SampleGroupEntry.prototype.parse = function(stream) {
            Log.warn("BoxParser", "Unknown Sample Group type: " + this.grouping_type);
            this.data = stream.readUint8Array(this.description_length);
          };
          BoxParser.createSampleGroupCtor("scif", function(stream) {
            Log.warn("BoxParser", "Sample Group type: " + this.grouping_type + " not fully parsed");
          });
          BoxParser.createSampleGroupCtor("scnm", function(stream) {
            Log.warn("BoxParser", "Sample Group type: " + this.grouping_type + " not fully parsed");
          });
          BoxParser.createSampleGroupCtor("seig", function(stream) {
            this.reserved = stream.readUint8();
            var tmp = stream.readUint8();
            this.crypt_byte_block = tmp >> 4;
            this.skip_byte_block = tmp & 15;
            this.isProtected = stream.readUint8();
            this.Per_Sample_IV_Size = stream.readUint8();
            this.KID = BoxParser.parseHex16(stream);
            this.constant_IV_size = 0;
            this.constant_IV = 0;
            if (this.isProtected === 1 && this.Per_Sample_IV_Size === 0) {
              this.constant_IV_size = stream.readUint8();
              this.constant_IV = stream.readUint8Array(this.constant_IV_size);
            }
          });
          BoxParser.createSampleGroupCtor("stsa", function(stream) {
            Log.warn("BoxParser", "Sample Group type: " + this.grouping_type + " not fully parsed");
          });
          BoxParser.createSampleGroupCtor("sync", function(stream) {
            var tmp_byte = stream.readUint8();
            this.NAL_unit_type = tmp_byte & 63;
          });
          BoxParser.createSampleGroupCtor("tele", function(stream) {
            var tmp_byte = stream.readUint8();
            this.level_independently_decodable = tmp_byte >> 7;
          });
          BoxParser.createSampleGroupCtor("tsas", function(stream) {
            Log.warn("BoxParser", "Sample Group type: " + this.grouping_type + " not fully parsed");
          });
          BoxParser.createSampleGroupCtor("tscl", function(stream) {
            Log.warn("BoxParser", "Sample Group type: " + this.grouping_type + " not fully parsed");
          });
          BoxParser.createSampleGroupCtor("vipr", function(stream) {
            Log.warn("BoxParser", "Sample Group type: " + this.grouping_type + " not fully parsed");
          });
          BoxParser.createFullBoxCtor("sbgp", function(stream) {
            this.grouping_type = stream.readString(4);
            if (this.version === 1) {
              this.grouping_type_parameter = stream.readUint32();
            } else {
              this.grouping_type_parameter = 0;
            }
            this.entries = [];
            var entry_count2 = stream.readUint32();
            for (var i2 = 0; i2 < entry_count2; i2++) {
              var entry = {};
              this.entries.push(entry);
              entry.sample_count = stream.readInt32();
              entry.group_description_index = stream.readInt32();
            }
          });
          function Pixel(row, col) {
            this.bad_pixel_row = row;
            this.bad_pixel_column = col;
          }
          Pixel.prototype.toString = function pixelToString() {
            return "[row: " + this.bad_pixel_row + ", column: " + this.bad_pixel_column + "]";
          };
          BoxParser.createFullBoxCtor("sbpm", function(stream) {
            var i2;
            this.component_count = stream.readUint16();
            this.component_index = [];
            for (i2 = 0; i2 < this.component_count; i2++) {
              this.component_index.push(stream.readUint16());
            }
            var flags = stream.readUint8();
            this.correction_applied = 128 == (flags & 128);
            this.num_bad_rows = stream.readUint32();
            this.num_bad_cols = stream.readUint32();
            this.num_bad_pixels = stream.readUint32();
            this.bad_rows = [];
            this.bad_columns = [];
            this.bad_pixels = [];
            for (i2 = 0; i2 < this.num_bad_rows; i2++) {
              this.bad_rows.push(stream.readUint32());
            }
            for (i2 = 0; i2 < this.num_bad_cols; i2++) {
              this.bad_columns.push(stream.readUint32());
            }
            for (i2 = 0; i2 < this.num_bad_pixels; i2++) {
              var row = stream.readUint32();
              var col = stream.readUint32();
              this.bad_pixels.push(new Pixel(row, col));
            }
          });
          BoxParser.createFullBoxCtor("schm", function(stream) {
            this.scheme_type = stream.readString(4);
            this.scheme_version = stream.readUint32();
            if (this.flags & 1) {
              this.scheme_uri = stream.readString(this.size - this.hdr_size - 8);
            }
          });
          BoxParser.createBoxCtor("sdp ", function(stream) {
            this.sdptext = stream.readString(this.size - this.hdr_size);
          });
          BoxParser.createFullBoxCtor("sdtp", function(stream) {
            var tmp_byte;
            var count = this.size - this.hdr_size;
            this.is_leading = [];
            this.sample_depends_on = [];
            this.sample_is_depended_on = [];
            this.sample_has_redundancy = [];
            for (var i2 = 0; i2 < count; i2++) {
              tmp_byte = stream.readUint8();
              this.is_leading[i2] = tmp_byte >> 6;
              this.sample_depends_on[i2] = tmp_byte >> 4 & 3;
              this.sample_is_depended_on[i2] = tmp_byte >> 2 & 3;
              this.sample_has_redundancy[i2] = tmp_byte & 3;
            }
          });
          BoxParser.createFullBoxCtor(
            "senc"
            /*, function(stream) {
            	this.parseFullHeader(stream);
            	var sample_count = stream.readUint32();
            	this.samples = [];
            	for (var i = 0; i < sample_count; i++) {
            		var sample = {};
            		// tenc.default_Per_Sample_IV_Size or seig.Per_Sample_IV_Size
            		sample.InitializationVector = this.readUint8Array(Per_Sample_IV_Size*8);
            		if (this.flags & 0x2) {
            			sample.subsamples = [];
            			subsample_count = stream.readUint16();
            			for (var j = 0; j < subsample_count; j++) {
            				var subsample = {};
            				subsample.BytesOfClearData = stream.readUint16();
            				subsample.BytesOfProtectedData = stream.readUint32();
            				sample.subsamples.push(subsample);
            			}
            		}
            		// TODO
            		this.samples.push(sample);
            	}
            }*/
          );
          BoxParser.createFullBoxCtor("sgpd", function(stream) {
            this.grouping_type = stream.readString(4);
            Log.debug("BoxParser", "Found Sample Groups of type " + this.grouping_type);
            if (this.version === 1) {
              this.default_length = stream.readUint32();
            } else {
              this.default_length = 0;
            }
            if (this.version >= 2) {
              this.default_group_description_index = stream.readUint32();
            }
            this.entries = [];
            var entry_count2 = stream.readUint32();
            for (var i2 = 0; i2 < entry_count2; i2++) {
              var entry;
              if (BoxParser[this.grouping_type + "SampleGroupEntry"]) {
                entry = new BoxParser[this.grouping_type + "SampleGroupEntry"](this.grouping_type);
              } else {
                entry = new BoxParser.SampleGroupEntry(this.grouping_type);
              }
              this.entries.push(entry);
              if (this.version === 1) {
                if (this.default_length === 0) {
                  entry.description_length = stream.readUint32();
                } else {
                  entry.description_length = this.default_length;
                }
              } else {
                entry.description_length = this.default_length;
              }
              if (entry.write === BoxParser.SampleGroupEntry.prototype.write) {
                Log.info("BoxParser", "SampleGroup for type " + this.grouping_type + " writing not yet implemented, keeping unparsed data in memory for later write");
                entry.data = stream.readUint8Array(entry.description_length);
                stream.position -= entry.description_length;
              }
              entry.parse(stream);
            }
          });
          BoxParser.createFullBoxCtor("sidx", function(stream) {
            this.reference_ID = stream.readUint32();
            this.timescale = stream.readUint32();
            if (this.version === 0) {
              this.earliest_presentation_time = stream.readUint32();
              this.first_offset = stream.readUint32();
            } else {
              this.earliest_presentation_time = stream.readUint64();
              this.first_offset = stream.readUint64();
            }
            stream.readUint16();
            this.references = [];
            var count = stream.readUint16();
            for (var i2 = 0; i2 < count; i2++) {
              var ref2 = {};
              this.references.push(ref2);
              var tmp_32 = stream.readUint32();
              ref2.reference_type = tmp_32 >> 31 & 1;
              ref2.referenced_size = tmp_32 & 2147483647;
              ref2.subsegment_duration = stream.readUint32();
              tmp_32 = stream.readUint32();
              ref2.starts_with_SAP = tmp_32 >> 31 & 1;
              ref2.SAP_type = tmp_32 >> 28 & 7;
              ref2.SAP_delta_time = tmp_32 & 268435455;
            }
          });
          BoxParser.SingleItemTypeReferenceBox = function(type, size, hdr_size, start) {
            BoxParser.Box.call(this, type, size);
            this.hdr_size = hdr_size;
            this.start = start;
          };
          BoxParser.SingleItemTypeReferenceBox.prototype = new BoxParser.Box();
          BoxParser.SingleItemTypeReferenceBox.prototype.parse = function(stream) {
            this.from_item_ID = stream.readUint16();
            var count = stream.readUint16();
            this.references = [];
            for (var i2 = 0; i2 < count; i2++) {
              this.references[i2] = {};
              this.references[i2].to_item_ID = stream.readUint16();
            }
          };
          BoxParser.SingleItemTypeReferenceBoxLarge = function(type, size, hdr_size, start) {
            BoxParser.Box.call(this, type, size);
            this.hdr_size = hdr_size;
            this.start = start;
          };
          BoxParser.SingleItemTypeReferenceBoxLarge.prototype = new BoxParser.Box();
          BoxParser.SingleItemTypeReferenceBoxLarge.prototype.parse = function(stream) {
            this.from_item_ID = stream.readUint32();
            var count = stream.readUint16();
            this.references = [];
            for (var i2 = 0; i2 < count; i2++) {
              this.references[i2] = {};
              this.references[i2].to_item_ID = stream.readUint32();
            }
          };
          BoxParser.createFullBoxCtor("SmDm", function(stream) {
            this.primaryRChromaticity_x = stream.readUint16();
            this.primaryRChromaticity_y = stream.readUint16();
            this.primaryGChromaticity_x = stream.readUint16();
            this.primaryGChromaticity_y = stream.readUint16();
            this.primaryBChromaticity_x = stream.readUint16();
            this.primaryBChromaticity_y = stream.readUint16();
            this.whitePointChromaticity_x = stream.readUint16();
            this.whitePointChromaticity_y = stream.readUint16();
            this.luminanceMax = stream.readUint32();
            this.luminanceMin = stream.readUint32();
          });
          BoxParser.createFullBoxCtor("smhd", function(stream) {
            this.balance = stream.readUint16();
            stream.readUint16();
          });
          BoxParser.createFullBoxCtor("ssix", function(stream) {
            this.subsegments = [];
            var subsegment_count = stream.readUint32();
            for (var i2 = 0; i2 < subsegment_count; i2++) {
              var subsegment = {};
              this.subsegments.push(subsegment);
              subsegment.ranges = [];
              var range_count = stream.readUint32();
              for (var j = 0; j < range_count; j++) {
                var range = {};
                subsegment.ranges.push(range);
                range.level = stream.readUint8();
                range.range_size = stream.readUint24();
              }
            }
          });
          BoxParser.createFullBoxCtor("stco", function(stream) {
            var entry_count2;
            entry_count2 = stream.readUint32();
            this.chunk_offsets = [];
            if (this.version === 0) {
              for (var i2 = 0; i2 < entry_count2; i2++) {
                this.chunk_offsets.push(stream.readUint32());
              }
            }
          });
          BoxParser.createFullBoxCtor("stdp", function(stream) {
            var count = (this.size - this.hdr_size) / 2;
            this.priority = [];
            for (var i2 = 0; i2 < count; i2++) {
              this.priority[i2] = stream.readUint16();
            }
          });
          BoxParser.createFullBoxCtor("sthd");
          BoxParser.createFullBoxCtor("stri", function(stream) {
            this.switch_group = stream.readUint16();
            this.alternate_group = stream.readUint16();
            this.sub_track_id = stream.readUint32();
            var count = (this.size - this.hdr_size - 8) / 4;
            this.attribute_list = [];
            for (var i2 = 0; i2 < count; i2++) {
              this.attribute_list[i2] = stream.readUint32();
            }
          });
          BoxParser.createFullBoxCtor("stsc", function(stream) {
            var entry_count2;
            var i2;
            entry_count2 = stream.readUint32();
            this.first_chunk = [];
            this.samples_per_chunk = [];
            this.sample_description_index = [];
            if (this.version === 0) {
              for (i2 = 0; i2 < entry_count2; i2++) {
                this.first_chunk.push(stream.readUint32());
                this.samples_per_chunk.push(stream.readUint32());
                this.sample_description_index.push(stream.readUint32());
              }
            }
          });
          BoxParser.createFullBoxCtor("stsd", function(stream) {
            var i2;
            var ret2;
            var entryCount;
            var box2;
            this.entries = [];
            entryCount = stream.readUint32();
            for (i2 = 1; i2 <= entryCount; i2++) {
              ret2 = BoxParser.parseOneBox(stream, true, this.size - (stream.getPosition() - this.start));
              if (ret2.code === BoxParser.OK) {
                if (BoxParser[ret2.type + "SampleEntry"]) {
                  box2 = new BoxParser[ret2.type + "SampleEntry"](ret2.size);
                  box2.hdr_size = ret2.hdr_size;
                  box2.start = ret2.start;
                } else {
                  Log.warn("BoxParser", "Unknown sample entry type: " + ret2.type);
                  box2 = new BoxParser.SampleEntry(ret2.type, ret2.size, ret2.hdr_size, ret2.start);
                }
                if (box2.write === BoxParser.SampleEntry.prototype.write) {
                  Log.info("BoxParser", "SampleEntry " + box2.type + " box writing not yet implemented, keeping unparsed data in memory for later write");
                  box2.parseDataAndRewind(stream);
                }
                box2.parse(stream);
                this.entries.push(box2);
              } else {
                return;
              }
            }
          });
          BoxParser.createFullBoxCtor("stsg", function(stream) {
            this.grouping_type = stream.readUint32();
            var count = stream.readUint16();
            this.group_description_index = [];
            for (var i2 = 0; i2 < count; i2++) {
              this.group_description_index[i2] = stream.readUint32();
            }
          });
          BoxParser.createFullBoxCtor("stsh", function(stream) {
            var entry_count2;
            var i2;
            entry_count2 = stream.readUint32();
            this.shadowed_sample_numbers = [];
            this.sync_sample_numbers = [];
            if (this.version === 0) {
              for (i2 = 0; i2 < entry_count2; i2++) {
                this.shadowed_sample_numbers.push(stream.readUint32());
                this.sync_sample_numbers.push(stream.readUint32());
              }
            }
          });
          BoxParser.createFullBoxCtor("stss", function(stream) {
            var i2;
            var entry_count2;
            entry_count2 = stream.readUint32();
            if (this.version === 0) {
              this.sample_numbers = [];
              for (i2 = 0; i2 < entry_count2; i2++) {
                this.sample_numbers.push(stream.readUint32());
              }
            }
          });
          BoxParser.createFullBoxCtor("stsz", function(stream) {
            var i2;
            this.sample_sizes = [];
            if (this.version === 0) {
              this.sample_size = stream.readUint32();
              this.sample_count = stream.readUint32();
              for (i2 = 0; i2 < this.sample_count; i2++) {
                if (this.sample_size === 0) {
                  this.sample_sizes.push(stream.readUint32());
                } else {
                  this.sample_sizes[i2] = this.sample_size;
                }
              }
            }
          });
          BoxParser.createFullBoxCtor("stts", function(stream) {
            var entry_count2;
            var i2;
            var delta;
            entry_count2 = stream.readUint32();
            this.sample_counts = [];
            this.sample_deltas = [];
            if (this.version === 0) {
              for (i2 = 0; i2 < entry_count2; i2++) {
                this.sample_counts.push(stream.readUint32());
                delta = stream.readInt32();
                if (delta < 0) {
                  Log.warn("BoxParser", "File uses negative stts sample delta, using value 1 instead, sync may be lost!");
                  delta = 1;
                }
                this.sample_deltas.push(delta);
              }
            }
          });
          BoxParser.createFullBoxCtor("stvi", function(stream) {
            var tmp32 = stream.readUint32();
            this.single_view_allowed = tmp32 & 3;
            this.stereo_scheme = stream.readUint32();
            var length = stream.readUint32();
            this.stereo_indication_type = stream.readString(length);
            var ret2;
            var box2;
            this.boxes = [];
            while (stream.getPosition() < this.start + this.size) {
              ret2 = BoxParser.parseOneBox(stream, false, this.size - (stream.getPosition() - this.start));
              if (ret2.code === BoxParser.OK) {
                box2 = ret2.box;
                this.boxes.push(box2);
                this[box2.type] = box2;
              } else {
                return;
              }
            }
          });
          BoxParser.createBoxCtor("styp", function(stream) {
            BoxParser.ftypBox.prototype.parse.call(this, stream);
          });
          BoxParser.createFullBoxCtor("stz2", function(stream) {
            var i2;
            var sample_count;
            this.sample_sizes = [];
            if (this.version === 0) {
              this.reserved = stream.readUint24();
              this.field_size = stream.readUint8();
              sample_count = stream.readUint32();
              if (this.field_size === 4) {
                for (i2 = 0; i2 < sample_count; i2 += 2) {
                  var tmp = stream.readUint8();
                  this.sample_sizes[i2] = tmp >> 4 & 15;
                  this.sample_sizes[i2 + 1] = tmp & 15;
                }
              } else if (this.field_size === 8) {
                for (i2 = 0; i2 < sample_count; i2++) {
                  this.sample_sizes[i2] = stream.readUint8();
                }
              } else if (this.field_size === 16) {
                for (i2 = 0; i2 < sample_count; i2++) {
                  this.sample_sizes[i2] = stream.readUint16();
                }
              } else {
                Log.error("BoxParser", "Error in length field in stz2 box");
              }
            }
          });
          BoxParser.createFullBoxCtor("subs", function(stream) {
            var i2, j;
            var entry_count2;
            var subsample_count;
            entry_count2 = stream.readUint32();
            this.entries = [];
            for (i2 = 0; i2 < entry_count2; i2++) {
              var sampleInfo = {};
              this.entries[i2] = sampleInfo;
              sampleInfo.sample_delta = stream.readUint32();
              sampleInfo.subsamples = [];
              subsample_count = stream.readUint16();
              if (subsample_count > 0) {
                for (j = 0; j < subsample_count; j++) {
                  var subsample = {};
                  sampleInfo.subsamples.push(subsample);
                  if (this.version == 1) {
                    subsample.size = stream.readUint32();
                  } else {
                    subsample.size = stream.readUint16();
                  }
                  subsample.priority = stream.readUint8();
                  subsample.discardable = stream.readUint8();
                  subsample.codec_specific_parameters = stream.readUint32();
                }
              }
            }
          });
          BoxParser.createFullBoxCtor("tenc", function(stream) {
            stream.readUint8();
            if (this.version === 0) {
              stream.readUint8();
            } else {
              var tmp = stream.readUint8();
              this.default_crypt_byte_block = tmp >> 4 & 15;
              this.default_skip_byte_block = tmp & 15;
            }
            this.default_isProtected = stream.readUint8();
            this.default_Per_Sample_IV_Size = stream.readUint8();
            this.default_KID = BoxParser.parseHex16(stream);
            if (this.default_isProtected === 1 && this.default_Per_Sample_IV_Size === 0) {
              this.default_constant_IV_size = stream.readUint8();
              this.default_constant_IV = stream.readUint8Array(this.default_constant_IV_size);
            }
          });
          BoxParser.createFullBoxCtor("tfdt", function(stream) {
            if (this.version == 1) {
              this.baseMediaDecodeTime = stream.readUint64();
            } else {
              this.baseMediaDecodeTime = stream.readUint32();
            }
          });
          BoxParser.createFullBoxCtor("tfhd", function(stream) {
            var readBytes = 0;
            this.track_id = stream.readUint32();
            if (this.size - this.hdr_size > readBytes && this.flags & BoxParser.TFHD_FLAG_BASE_DATA_OFFSET) {
              this.base_data_offset = stream.readUint64();
              readBytes += 8;
            } else {
              this.base_data_offset = 0;
            }
            if (this.size - this.hdr_size > readBytes && this.flags & BoxParser.TFHD_FLAG_SAMPLE_DESC) {
              this.default_sample_description_index = stream.readUint32();
              readBytes += 4;
            } else {
              this.default_sample_description_index = 0;
            }
            if (this.size - this.hdr_size > readBytes && this.flags & BoxParser.TFHD_FLAG_SAMPLE_DUR) {
              this.default_sample_duration = stream.readUint32();
              readBytes += 4;
            } else {
              this.default_sample_duration = 0;
            }
            if (this.size - this.hdr_size > readBytes && this.flags & BoxParser.TFHD_FLAG_SAMPLE_SIZE) {
              this.default_sample_size = stream.readUint32();
              readBytes += 4;
            } else {
              this.default_sample_size = 0;
            }
            if (this.size - this.hdr_size > readBytes && this.flags & BoxParser.TFHD_FLAG_SAMPLE_FLAGS) {
              this.default_sample_flags = stream.readUint32();
              readBytes += 4;
            } else {
              this.default_sample_flags = 0;
            }
          });
          BoxParser.createFullBoxCtor("tfra", function(stream) {
            this.track_ID = stream.readUint32();
            stream.readUint24();
            var tmp_byte = stream.readUint8();
            this.length_size_of_traf_num = tmp_byte >> 4 & 3;
            this.length_size_of_trun_num = tmp_byte >> 2 & 3;
            this.length_size_of_sample_num = tmp_byte & 3;
            this.entries = [];
            var number_of_entries = stream.readUint32();
            for (var i2 = 0; i2 < number_of_entries; i2++) {
              if (this.version === 1) {
                this.time = stream.readUint64();
                this.moof_offset = stream.readUint64();
              } else {
                this.time = stream.readUint32();
                this.moof_offset = stream.readUint32();
              }
              this.traf_number = stream["readUint" + 8 * (this.length_size_of_traf_num + 1)]();
              this.trun_number = stream["readUint" + 8 * (this.length_size_of_trun_num + 1)]();
              this.sample_number = stream["readUint" + 8 * (this.length_size_of_sample_num + 1)]();
            }
          });
          BoxParser.createFullBoxCtor("tkhd", function(stream) {
            if (this.version == 1) {
              this.creation_time = stream.readUint64();
              this.modification_time = stream.readUint64();
              this.track_id = stream.readUint32();
              stream.readUint32();
              this.duration = stream.readUint64();
            } else {
              this.creation_time = stream.readUint32();
              this.modification_time = stream.readUint32();
              this.track_id = stream.readUint32();
              stream.readUint32();
              this.duration = stream.readUint32();
            }
            stream.readUint32Array(2);
            this.layer = stream.readInt16();
            this.alternate_group = stream.readInt16();
            this.volume = stream.readInt16() >> 8;
            stream.readUint16();
            this.matrix = stream.readInt32Array(9);
            this.width = stream.readUint32();
            this.height = stream.readUint32();
          });
          BoxParser.createBoxCtor("tmax", function(stream) {
            this.time = stream.readUint32();
          });
          BoxParser.createBoxCtor("tmin", function(stream) {
            this.time = stream.readUint32();
          });
          BoxParser.createBoxCtor("totl", function(stream) {
            this.bytessent = stream.readUint32();
          });
          BoxParser.createBoxCtor("tpay", function(stream) {
            this.bytessent = stream.readUint32();
          });
          BoxParser.createBoxCtor("tpyl", function(stream) {
            this.bytessent = stream.readUint64();
          });
          BoxParser.TrackGroupTypeBox.prototype.parse = function(stream) {
            this.parseFullHeader(stream);
            this.track_group_id = stream.readUint32();
          };
          BoxParser.createTrackGroupCtor("msrc");
          BoxParser.TrackReferenceTypeBox = function(type, size, hdr_size, start) {
            BoxParser.Box.call(this, type, size);
            this.hdr_size = hdr_size;
            this.start = start;
          };
          BoxParser.TrackReferenceTypeBox.prototype = new BoxParser.Box();
          BoxParser.TrackReferenceTypeBox.prototype.parse = function(stream) {
            this.track_ids = stream.readUint32Array((this.size - this.hdr_size) / 4);
          };
          BoxParser.trefBox.prototype.parse = function(stream) {
            var ret2;
            var box2;
            while (stream.getPosition() < this.start + this.size) {
              ret2 = BoxParser.parseOneBox(stream, true, this.size - (stream.getPosition() - this.start));
              if (ret2.code === BoxParser.OK) {
                box2 = new BoxParser.TrackReferenceTypeBox(ret2.type, ret2.size, ret2.hdr_size, ret2.start);
                if (box2.write === BoxParser.Box.prototype.write && box2.type !== "mdat") {
                  Log.info("BoxParser", "TrackReference " + box2.type + " box writing not yet implemented, keeping unparsed data in memory for later write");
                  box2.parseDataAndRewind(stream);
                }
                box2.parse(stream);
                this.boxes.push(box2);
              } else {
                return;
              }
            }
          };
          BoxParser.createFullBoxCtor("trep", function(stream) {
            this.track_ID = stream.readUint32();
            this.boxes = [];
            while (stream.getPosition() < this.start + this.size) {
              ret = BoxParser.parseOneBox(stream, false, this.size - (stream.getPosition() - this.start));
              if (ret.code === BoxParser.OK) {
                box = ret.box;
                this.boxes.push(box);
              } else {
                return;
              }
            }
          });
          BoxParser.createFullBoxCtor("trex", function(stream) {
            this.track_id = stream.readUint32();
            this.default_sample_description_index = stream.readUint32();
            this.default_sample_duration = stream.readUint32();
            this.default_sample_size = stream.readUint32();
            this.default_sample_flags = stream.readUint32();
          });
          BoxParser.createBoxCtor("trpy", function(stream) {
            this.bytessent = stream.readUint64();
          });
          BoxParser.createFullBoxCtor("trun", function(stream) {
            var readBytes = 0;
            this.sample_count = stream.readUint32();
            readBytes += 4;
            if (this.size - this.hdr_size > readBytes && this.flags & BoxParser.TRUN_FLAGS_DATA_OFFSET) {
              this.data_offset = stream.readInt32();
              readBytes += 4;
            } else {
              this.data_offset = 0;
            }
            if (this.size - this.hdr_size > readBytes && this.flags & BoxParser.TRUN_FLAGS_FIRST_FLAG) {
              this.first_sample_flags = stream.readUint32();
              readBytes += 4;
            } else {
              this.first_sample_flags = 0;
            }
            this.sample_duration = [];
            this.sample_size = [];
            this.sample_flags = [];
            this.sample_composition_time_offset = [];
            if (this.size - this.hdr_size > readBytes) {
              for (var i2 = 0; i2 < this.sample_count; i2++) {
                if (this.flags & BoxParser.TRUN_FLAGS_DURATION) {
                  this.sample_duration[i2] = stream.readUint32();
                }
                if (this.flags & BoxParser.TRUN_FLAGS_SIZE) {
                  this.sample_size[i2] = stream.readUint32();
                }
                if (this.flags & BoxParser.TRUN_FLAGS_FLAGS) {
                  this.sample_flags[i2] = stream.readUint32();
                }
                if (this.flags & BoxParser.TRUN_FLAGS_CTS_OFFSET) {
                  if (this.version === 0) {
                    this.sample_composition_time_offset[i2] = stream.readUint32();
                  } else {
                    this.sample_composition_time_offset[i2] = stream.readInt32();
                  }
                }
              }
            }
          });
          BoxParser.createFullBoxCtor("tsel", function(stream) {
            this.switch_group = stream.readUint32();
            var count = (this.size - this.hdr_size - 4) / 4;
            this.attribute_list = [];
            for (var i2 = 0; i2 < count; i2++) {
              this.attribute_list[i2] = stream.readUint32();
            }
          });
          BoxParser.createFullBoxCtor("txtC", function(stream) {
            this.config = stream.readCString();
          });
          BoxParser.createBoxCtor("tyco", function(stream) {
            var count = (this.size - this.hdr_size) / 4;
            this.compatible_brands = [];
            for (var i2 = 0; i2 < count; i2++) {
              this.compatible_brands[i2] = stream.readString(4);
            }
          });
          BoxParser.createFullBoxCtor("udes", function(stream) {
            this.lang = stream.readCString();
            this.name = stream.readCString();
            this.description = stream.readCString();
            this.tags = stream.readCString();
          });
          BoxParser.createFullBoxCtor("uncC", function(stream) {
            var i2;
            this.profile = stream.readUint32();
            if (this.version == 1) ;
            else if (this.version == 0) {
              this.component_count = stream.readUint32();
              this.component_index = [];
              this.component_bit_depth_minus_one = [];
              this.component_format = [];
              this.component_align_size = [];
              for (i2 = 0; i2 < this.component_count; i2++) {
                this.component_index.push(stream.readUint16());
                this.component_bit_depth_minus_one.push(stream.readUint8());
                this.component_format.push(stream.readUint8());
                this.component_align_size.push(stream.readUint8());
              }
              this.sampling_type = stream.readUint8();
              this.interleave_type = stream.readUint8();
              this.block_size = stream.readUint8();
              var flags = stream.readUint8();
              this.component_little_endian = flags >> 7 & 1;
              this.block_pad_lsb = flags >> 6 & 1;
              this.block_little_endian = flags >> 5 & 1;
              this.block_reversed = flags >> 4 & 1;
              this.pad_unknown = flags >> 3 & 1;
              this.pixel_size = stream.readUint32();
              this.row_align_size = stream.readUint32();
              this.tile_align_size = stream.readUint32();
              this.num_tile_cols_minus_one = stream.readUint32();
              this.num_tile_rows_minus_one = stream.readUint32();
            }
          });
          BoxParser.createFullBoxCtor("url ", function(stream) {
            if (this.flags !== 1) {
              this.location = stream.readCString();
            }
          });
          BoxParser.createFullBoxCtor("urn ", function(stream) {
            this.name = stream.readCString();
            if (this.size - this.hdr_size - this.name.length - 1 > 0) {
              this.location = stream.readCString();
            }
          });
          BoxParser.createUUIDBox("a5d40b30e81411ddba2f0800200c9a66", true, false, function(stream) {
            this.LiveServerManifest = stream.readString(this.size - this.hdr_size).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
          });
          BoxParser.createUUIDBox("d08a4f1810f34a82b6c832d8aba183d3", true, false, function(stream) {
            this.system_id = BoxParser.parseHex16(stream);
            var datasize = stream.readUint32();
            if (datasize > 0) {
              this.data = stream.readUint8Array(datasize);
            }
          });
          BoxParser.createUUIDBox(
            "a2394f525a9b4f14a2446c427c648df4",
            true,
            false
            /*, function(stream) {
            	if (this.flags & 0x1) {
            		this.AlgorithmID = stream.readUint24();
            		this.IV_size = stream.readUint8();
            		this.KID = BoxParser.parseHex16(stream);
            	}
            	var sample_count = stream.readUint32();
            	this.samples = [];
            	for (var i = 0; i < sample_count; i++) {
            		var sample = {};
            		sample.InitializationVector = this.readUint8Array(this.IV_size*8);
            		if (this.flags & 0x2) {
            			sample.subsamples = [];
            			sample.NumberOfEntries = stream.readUint16();
            			for (var j = 0; j < sample.NumberOfEntries; j++) {
            				var subsample = {};
            				subsample.BytesOfClearData = stream.readUint16();
            				subsample.BytesOfProtectedData = stream.readUint32();
            				sample.subsamples.push(subsample);
            			}
            		}
            		this.samples.push(sample);
            	}
            }*/
          );
          BoxParser.createUUIDBox("8974dbce7be74c5184f97148f9882554", true, false, function(stream) {
            this.default_AlgorithmID = stream.readUint24();
            this.default_IV_size = stream.readUint8();
            this.default_KID = BoxParser.parseHex16(stream);
          });
          BoxParser.createUUIDBox("d4807ef2ca3946958e5426cb9e46a79f", true, false, function(stream) {
            this.fragment_count = stream.readUint8();
            this.entries = [];
            for (var i2 = 0; i2 < this.fragment_count; i2++) {
              var entry = {};
              var absolute_time = 0;
              var absolute_duration = 0;
              if (this.version === 1) {
                absolute_time = stream.readUint64();
                absolute_duration = stream.readUint64();
              } else {
                absolute_time = stream.readUint32();
                absolute_duration = stream.readUint32();
              }
              entry.absolute_time = absolute_time;
              entry.absolute_duration = absolute_duration;
              this.entries.push(entry);
            }
          });
          BoxParser.createUUIDBox("6d1d9b0542d544e680e2141daff757b2", true, false, function(stream) {
            if (this.version === 1) {
              this.absolute_time = stream.readUint64();
              this.duration = stream.readUint64();
            } else {
              this.absolute_time = stream.readUint32();
              this.duration = stream.readUint32();
            }
          });
          BoxParser.createFullBoxCtor("vmhd", function(stream) {
            this.graphicsmode = stream.readUint16();
            this.opcolor = stream.readUint16Array(3);
          });
          BoxParser.createFullBoxCtor("vpcC", function(stream) {
            var tmp;
            if (this.version === 1) {
              this.profile = stream.readUint8();
              this.level = stream.readUint8();
              tmp = stream.readUint8();
              this.bitDepth = tmp >> 4;
              this.chromaSubsampling = tmp >> 1 & 7;
              this.videoFullRangeFlag = tmp & 1;
              this.colourPrimaries = stream.readUint8();
              this.transferCharacteristics = stream.readUint8();
              this.matrixCoefficients = stream.readUint8();
              this.codecIntializationDataSize = stream.readUint16();
              this.codecIntializationData = stream.readUint8Array(this.codecIntializationDataSize);
            } else {
              this.profile = stream.readUint8();
              this.level = stream.readUint8();
              tmp = stream.readUint8();
              this.bitDepth = tmp >> 4 & 15;
              this.colorSpace = tmp & 15;
              tmp = stream.readUint8();
              this.chromaSubsampling = tmp >> 4 & 15;
              this.transferFunction = tmp >> 1 & 7;
              this.videoFullRangeFlag = tmp & 1;
              this.codecIntializationDataSize = stream.readUint16();
              this.codecIntializationData = stream.readUint8Array(this.codecIntializationDataSize);
            }
          });
          BoxParser.createBoxCtor("vttC", function(stream) {
            this.text = stream.readString(this.size - this.hdr_size);
          });
          BoxParser.createFullBoxCtor("vvcC", function(stream) {
            var i2, j;
            var bitReader = {
              held_bits: undefined,
              num_held_bits: 0,
              stream_read_1_bytes: function(strm2) {
                this.held_bits = strm2.readUint8();
                this.num_held_bits = 1 * 8;
              },
              stream_read_2_bytes: function(strm2) {
                this.held_bits = strm2.readUint16();
                this.num_held_bits = 2 * 8;
              },
              extract_bits: function(num_bits) {
                var ret2 = this.held_bits >> this.num_held_bits - num_bits & (1 << num_bits) - 1;
                this.num_held_bits -= num_bits;
                return ret2;
              }
            };
            bitReader.stream_read_1_bytes(stream);
            bitReader.extract_bits(5);
            this.lengthSizeMinusOne = bitReader.extract_bits(2);
            this.ptl_present_flag = bitReader.extract_bits(1);
            if (this.ptl_present_flag) {
              bitReader.stream_read_2_bytes(stream);
              this.ols_idx = bitReader.extract_bits(9);
              this.num_sublayers = bitReader.extract_bits(3);
              this.constant_frame_rate = bitReader.extract_bits(2);
              this.chroma_format_idc = bitReader.extract_bits(2);
              bitReader.stream_read_1_bytes(stream);
              this.bit_depth_minus8 = bitReader.extract_bits(3);
              bitReader.extract_bits(5);
              {
                bitReader.stream_read_2_bytes(stream);
                bitReader.extract_bits(2);
                this.num_bytes_constraint_info = bitReader.extract_bits(6);
                this.general_profile_idc = bitReader.extract_bits(7);
                this.general_tier_flag = bitReader.extract_bits(1);
                this.general_level_idc = stream.readUint8();
                bitReader.stream_read_1_bytes(stream);
                this.ptl_frame_only_constraint_flag = bitReader.extract_bits(1);
                this.ptl_multilayer_enabled_flag = bitReader.extract_bits(1);
                this.general_constraint_info = new Uint8Array(this.num_bytes_constraint_info);
                if (this.num_bytes_constraint_info) {
                  for (i2 = 0; i2 < this.num_bytes_constraint_info - 1; i2++) {
                    var cnstr1 = bitReader.extract_bits(6);
                    bitReader.stream_read_1_bytes(stream);
                    var cnstr2 = bitReader.extract_bits(2);
                    this.general_constraint_info[i2] = cnstr1 << 2 | cnstr2;
                  }
                  this.general_constraint_info[this.num_bytes_constraint_info - 1] = bitReader.extract_bits(6);
                } else {
                  bitReader.extract_bits(6);
                }
                if (this.num_sublayers > 1) {
                  bitReader.stream_read_1_bytes(stream);
                  this.ptl_sublayer_present_mask = 0;
                  for (j = this.num_sublayers - 2; j >= 0; --j) {
                    var val = bitReader.extract_bits(1);
                    this.ptl_sublayer_present_mask |= val << j;
                  }
                  for (j = this.num_sublayers; j <= 8 && this.num_sublayers > 1; ++j) {
                    bitReader.extract_bits(1);
                  }
                  this.sublayer_level_idc = [];
                  for (j = this.num_sublayers - 2; j >= 0; --j) {
                    if (this.ptl_sublayer_present_mask & 1 << j) {
                      this.sublayer_level_idc[j] = stream.readUint8();
                    }
                  }
                }
                this.ptl_num_sub_profiles = stream.readUint8();
                this.general_sub_profile_idc = [];
                if (this.ptl_num_sub_profiles) {
                  for (i2 = 0; i2 < this.ptl_num_sub_profiles; i2++) {
                    this.general_sub_profile_idc.push(stream.readUint32());
                  }
                }
              }
              this.max_picture_width = stream.readUint16();
              this.max_picture_height = stream.readUint16();
              this.avg_frame_rate = stream.readUint16();
            }
            var VVC_NALU_OPI = 12;
            var VVC_NALU_DEC_PARAM = 13;
            this.nalu_arrays = [];
            var num_of_arrays = stream.readUint8();
            for (i2 = 0; i2 < num_of_arrays; i2++) {
              var nalu_array = [];
              this.nalu_arrays.push(nalu_array);
              bitReader.stream_read_1_bytes(stream);
              nalu_array.completeness = bitReader.extract_bits(1);
              bitReader.extract_bits(2);
              nalu_array.nalu_type = bitReader.extract_bits(5);
              var numNalus = 1;
              if (nalu_array.nalu_type != VVC_NALU_DEC_PARAM && nalu_array.nalu_type != VVC_NALU_OPI) {
                numNalus = stream.readUint16();
              }
              for (j = 0; j < numNalus; j++) {
                var len = stream.readUint16();
                nalu_array.push({
                  data: stream.readUint8Array(len),
                  length: len
                });
              }
            }
          });
          BoxParser.createFullBoxCtor("vvnC", function(stream) {
            var tmp = strm.readUint8();
            this.lengthSizeMinusOne = tmp & 3;
          });
          BoxParser.SampleEntry.prototype.isVideo = function() {
            return false;
          };
          BoxParser.SampleEntry.prototype.isAudio = function() {
            return false;
          };
          BoxParser.SampleEntry.prototype.isSubtitle = function() {
            return false;
          };
          BoxParser.SampleEntry.prototype.isMetadata = function() {
            return false;
          };
          BoxParser.SampleEntry.prototype.isHint = function() {
            return false;
          };
          BoxParser.SampleEntry.prototype.getCodec = function() {
            return this.type.replace(".", "");
          };
          BoxParser.SampleEntry.prototype.getWidth = function() {
            return "";
          };
          BoxParser.SampleEntry.prototype.getHeight = function() {
            return "";
          };
          BoxParser.SampleEntry.prototype.getChannelCount = function() {
            return "";
          };
          BoxParser.SampleEntry.prototype.getSampleRate = function() {
            return "";
          };
          BoxParser.SampleEntry.prototype.getSampleSize = function() {
            return "";
          };
          BoxParser.VisualSampleEntry.prototype.isVideo = function() {
            return true;
          };
          BoxParser.VisualSampleEntry.prototype.getWidth = function() {
            return this.width;
          };
          BoxParser.VisualSampleEntry.prototype.getHeight = function() {
            return this.height;
          };
          BoxParser.AudioSampleEntry.prototype.isAudio = function() {
            return true;
          };
          BoxParser.AudioSampleEntry.prototype.getChannelCount = function() {
            return this.channel_count;
          };
          BoxParser.AudioSampleEntry.prototype.getSampleRate = function() {
            return this.samplerate;
          };
          BoxParser.AudioSampleEntry.prototype.getSampleSize = function() {
            return this.samplesize;
          };
          BoxParser.SubtitleSampleEntry.prototype.isSubtitle = function() {
            return true;
          };
          BoxParser.MetadataSampleEntry.prototype.isMetadata = function() {
            return true;
          };
          BoxParser.decimalToHex = function(d, padding) {
            var hex = Number(d).toString(16);
            padding = typeof padding === "undefined" || padding === null ? padding = 2 : padding;
            while (hex.length < padding) {
              hex = "0" + hex;
            }
            return hex;
          };
          BoxParser.avc1SampleEntry.prototype.getCodec = BoxParser.avc2SampleEntry.prototype.getCodec = BoxParser.avc3SampleEntry.prototype.getCodec = BoxParser.avc4SampleEntry.prototype.getCodec = function() {
            var baseCodec = BoxParser.SampleEntry.prototype.getCodec.call(this);
            if (this.avcC) {
              return baseCodec + "." + BoxParser.decimalToHex(this.avcC.AVCProfileIndication) + BoxParser.decimalToHex(this.avcC.profile_compatibility) + BoxParser.decimalToHex(this.avcC.AVCLevelIndication);
            } else {
              return baseCodec;
            }
          };
          BoxParser.hev1SampleEntry.prototype.getCodec = BoxParser.hvc1SampleEntry.prototype.getCodec = function() {
            var i2;
            var baseCodec = BoxParser.SampleEntry.prototype.getCodec.call(this);
            if (this.hvcC) {
              baseCodec += ".";
              switch (this.hvcC.general_profile_space) {
                case 0:
                  baseCodec += "";
                  break;
                case 1:
                  baseCodec += "A";
                  break;
                case 2:
                  baseCodec += "B";
                  break;
                case 3:
                  baseCodec += "C";
                  break;
              }
              baseCodec += this.hvcC.general_profile_idc;
              baseCodec += ".";
              var val = this.hvcC.general_profile_compatibility;
              var reversed = 0;
              for (i2 = 0; i2 < 32; i2++) {
                reversed |= val & 1;
                if (i2 == 31) break;
                reversed <<= 1;
                val >>= 1;
              }
              baseCodec += BoxParser.decimalToHex(reversed, 0);
              baseCodec += ".";
              if (this.hvcC.general_tier_flag === 0) {
                baseCodec += "L";
              } else {
                baseCodec += "H";
              }
              baseCodec += this.hvcC.general_level_idc;
              var hasByte = false;
              var constraint_string = "";
              for (i2 = 5; i2 >= 0; i2--) {
                if (this.hvcC.general_constraint_indicator[i2] || hasByte) {
                  constraint_string = "." + BoxParser.decimalToHex(this.hvcC.general_constraint_indicator[i2], 0) + constraint_string;
                  hasByte = true;
                }
              }
              baseCodec += constraint_string;
            }
            return baseCodec;
          };
          BoxParser.vvc1SampleEntry.prototype.getCodec = BoxParser.vvi1SampleEntry.prototype.getCodec = function() {
            var i2;
            var baseCodec = BoxParser.SampleEntry.prototype.getCodec.call(this);
            if (this.vvcC) {
              baseCodec += "." + this.vvcC.general_profile_idc;
              if (this.vvcC.general_tier_flag) {
                baseCodec += ".H";
              } else {
                baseCodec += ".L";
              }
              baseCodec += this.vvcC.general_level_idc;
              var constraint_string = "";
              if (this.vvcC.general_constraint_info) {
                var bytes = [];
                var byte = 0;
                byte |= this.vvcC.ptl_frame_only_constraint << 7;
                byte |= this.vvcC.ptl_multilayer_enabled << 6;
                var last_nonzero;
                for (i2 = 0; i2 < this.vvcC.general_constraint_info.length; ++i2) {
                  byte |= this.vvcC.general_constraint_info[i2] >> 2 & 63;
                  bytes.push(byte);
                  if (byte) {
                    last_nonzero = i2;
                  }
                  byte = this.vvcC.general_constraint_info[i2] >> 2 & 3;
                }
                if (last_nonzero === undefined) {
                  constraint_string = ".CA";
                } else {
                  constraint_string = ".C";
                  var base32_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
                  var held_bits = 0;
                  var num_held_bits = 0;
                  for (i2 = 0; i2 <= last_nonzero; ++i2) {
                    held_bits = held_bits << 8 | bytes[i2];
                    num_held_bits += 8;
                    while (num_held_bits >= 5) {
                      var val = held_bits >> num_held_bits - 5 & 31;
                      constraint_string += base32_chars[val];
                      num_held_bits -= 5;
                      held_bits &= (1 << num_held_bits) - 1;
                    }
                  }
                  if (num_held_bits) {
                    held_bits <<= 5 - num_held_bits;
                    constraint_string += base32_chars[held_bits & 31];
                  }
                }
              }
              baseCodec += constraint_string;
            }
            return baseCodec;
          };
          BoxParser.mp4aSampleEntry.prototype.getCodec = function() {
            var baseCodec = BoxParser.SampleEntry.prototype.getCodec.call(this);
            if (this.esds && this.esds.esd) {
              var oti = this.esds.esd.getOTI();
              var dsi = this.esds.esd.getAudioConfig();
              return baseCodec + "." + BoxParser.decimalToHex(oti) + (dsi ? "." + dsi : "");
            } else {
              return baseCodec;
            }
          };
          BoxParser.stxtSampleEntry.prototype.getCodec = function() {
            var baseCodec = BoxParser.SampleEntry.prototype.getCodec.call(this);
            if (this.mime_format) {
              return baseCodec + "." + this.mime_format;
            } else {
              return baseCodec;
            }
          };
          BoxParser.vp08SampleEntry.prototype.getCodec = BoxParser.vp09SampleEntry.prototype.getCodec = function() {
            var baseCodec = BoxParser.SampleEntry.prototype.getCodec.call(this);
            var level = this.vpcC.level;
            if (level == 0) {
              level = "00";
            }
            var bitDepth = this.vpcC.bitDepth;
            if (bitDepth == 8) {
              bitDepth = "08";
            }
            return baseCodec + ".0" + this.vpcC.profile + "." + level + "." + bitDepth;
          };
          BoxParser.av01SampleEntry.prototype.getCodec = function() {
            var baseCodec = BoxParser.SampleEntry.prototype.getCodec.call(this);
            var level = this.av1C.seq_level_idx_0;
            if (level < 10) {
              level = "0" + level;
            }
            var bitdepth;
            if (this.av1C.seq_profile === 2 && this.av1C.high_bitdepth === 1) {
              bitdepth = this.av1C.twelve_bit === 1 ? "12" : "10";
            } else if (this.av1C.seq_profile <= 2) {
              bitdepth = this.av1C.high_bitdepth === 1 ? "10" : "08";
            }
            return baseCodec + "." + this.av1C.seq_profile + "." + level + (this.av1C.seq_tier_0 ? "H" : "M") + "." + bitdepth;
          };
          BoxParser.Box.prototype.writeHeader = function(stream, msg) {
            this.size += 8;
            if (this.size > MAX_SIZE) {
              this.size += 8;
            }
            if (this.type === "uuid") {
              this.size += 16;
            }
            Log.debug("BoxWriter", "Writing box " + this.type + " of size: " + this.size + " at position " + stream.getPosition() + (msg || ""));
            if (this.size > MAX_SIZE) {
              stream.writeUint32(1);
            } else {
              this.sizePosition = stream.getPosition();
              stream.writeUint32(this.size);
            }
            stream.writeString(this.type, null, 4);
            if (this.type === "uuid") {
              stream.writeUint8Array(this.uuid);
            }
            if (this.size > MAX_SIZE) {
              stream.writeUint64(this.size);
            }
          };
          BoxParser.FullBox.prototype.writeHeader = function(stream) {
            this.size += 4;
            BoxParser.Box.prototype.writeHeader.call(this, stream, " v=" + this.version + " f=" + this.flags);
            stream.writeUint8(this.version);
            stream.writeUint24(this.flags);
          };
          BoxParser.Box.prototype.write = function(stream) {
            if (this.type === "mdat") {
              if (this.data) {
                this.size = this.data.length;
                this.writeHeader(stream);
                stream.writeUint8Array(this.data);
              }
            } else {
              this.size = this.data ? this.data.length : 0;
              this.writeHeader(stream);
              if (this.data) {
                stream.writeUint8Array(this.data);
              }
            }
          };
          BoxParser.ContainerBox.prototype.write = function(stream) {
            this.size = 0;
            this.writeHeader(stream);
            for (var i2 = 0; i2 < this.boxes.length; i2++) {
              if (this.boxes[i2]) {
                this.boxes[i2].write(stream);
                this.size += this.boxes[i2].size;
              }
            }
            Log.debug("BoxWriter", "Adjusting box " + this.type + " with new size " + this.size);
            stream.adjustUint32(this.sizePosition, this.size);
          };
          BoxParser.TrackReferenceTypeBox.prototype.write = function(stream) {
            this.size = this.track_ids.length * 4;
            this.writeHeader(stream);
            stream.writeUint32Array(this.track_ids);
          };
          BoxParser.avcCBox.prototype.write = function(stream) {
            var i2;
            this.size = 7;
            for (i2 = 0; i2 < this.SPS.length; i2++) {
              this.size += 2 + this.SPS[i2].length;
            }
            for (i2 = 0; i2 < this.PPS.length; i2++) {
              this.size += 2 + this.PPS[i2].length;
            }
            if (this.ext) {
              this.size += this.ext.length;
            }
            this.writeHeader(stream);
            stream.writeUint8(this.configurationVersion);
            stream.writeUint8(this.AVCProfileIndication);
            stream.writeUint8(this.profile_compatibility);
            stream.writeUint8(this.AVCLevelIndication);
            stream.writeUint8(this.lengthSizeMinusOne + (63 << 2));
            stream.writeUint8(this.SPS.length + (7 << 5));
            for (i2 = 0; i2 < this.SPS.length; i2++) {
              stream.writeUint16(this.SPS[i2].length);
              stream.writeUint8Array(this.SPS[i2].nalu);
            }
            stream.writeUint8(this.PPS.length);
            for (i2 = 0; i2 < this.PPS.length; i2++) {
              stream.writeUint16(this.PPS[i2].length);
              stream.writeUint8Array(this.PPS[i2].nalu);
            }
            if (this.ext) {
              stream.writeUint8Array(this.ext);
            }
          };
          BoxParser.co64Box.prototype.write = function(stream) {
            var i2;
            this.version = 0;
            this.flags = 0;
            this.size = 4 + 8 * this.chunk_offsets.length;
            this.writeHeader(stream);
            stream.writeUint32(this.chunk_offsets.length);
            for (i2 = 0; i2 < this.chunk_offsets.length; i2++) {
              stream.writeUint64(this.chunk_offsets[i2]);
            }
          };
          BoxParser.cslgBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = 4 * 5;
            this.writeHeader(stream);
            stream.writeInt32(this.compositionToDTSShift);
            stream.writeInt32(this.leastDecodeToDisplayDelta);
            stream.writeInt32(this.greatestDecodeToDisplayDelta);
            stream.writeInt32(this.compositionStartTime);
            stream.writeInt32(this.compositionEndTime);
          };
          BoxParser.cttsBox.prototype.write = function(stream) {
            var i2;
            this.version = 0;
            this.flags = 0;
            this.size = 4 + 8 * this.sample_counts.length;
            this.writeHeader(stream);
            stream.writeUint32(this.sample_counts.length);
            for (i2 = 0; i2 < this.sample_counts.length; i2++) {
              stream.writeUint32(this.sample_counts[i2]);
              if (this.version === 1) {
                stream.writeInt32(this.sample_offsets[i2]);
              } else {
                stream.writeUint32(this.sample_offsets[i2]);
              }
            }
          };
          BoxParser.drefBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = 4;
            this.writeHeader(stream);
            stream.writeUint32(this.entries.length);
            for (var i2 = 0; i2 < this.entries.length; i2++) {
              this.entries[i2].write(stream);
              this.size += this.entries[i2].size;
            }
            Log.debug("BoxWriter", "Adjusting box " + this.type + " with new size " + this.size);
            stream.adjustUint32(this.sizePosition, this.size);
          };
          BoxParser.elngBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = this.extended_language.length;
            this.writeHeader(stream);
            stream.writeString(this.extended_language);
          };
          BoxParser.elstBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = 4 + 12 * this.entries.length;
            this.writeHeader(stream);
            stream.writeUint32(this.entries.length);
            for (var i2 = 0; i2 < this.entries.length; i2++) {
              var entry = this.entries[i2];
              stream.writeUint32(entry.segment_duration);
              stream.writeInt32(entry.media_time);
              stream.writeInt16(entry.media_rate_integer);
              stream.writeInt16(entry.media_rate_fraction);
            }
          };
          BoxParser.emsgBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = 4 * 4 + this.message_data.length + (this.scheme_id_uri.length + 1) + (this.value.length + 1);
            this.writeHeader(stream);
            stream.writeCString(this.scheme_id_uri);
            stream.writeCString(this.value);
            stream.writeUint32(this.timescale);
            stream.writeUint32(this.presentation_time_delta);
            stream.writeUint32(this.event_duration);
            stream.writeUint32(this.id);
            stream.writeUint8Array(this.message_data);
          };
          BoxParser.ftypBox.prototype.write = function(stream) {
            this.size = 8 + 4 * this.compatible_brands.length;
            this.writeHeader(stream);
            stream.writeString(this.major_brand, null, 4);
            stream.writeUint32(this.minor_version);
            for (var i2 = 0; i2 < this.compatible_brands.length; i2++) {
              stream.writeString(this.compatible_brands[i2], null, 4);
            }
          };
          BoxParser.hdlrBox.prototype.write = function(stream) {
            this.size = 5 * 4 + this.name.length + 1;
            this.version = 0;
            this.flags = 0;
            this.writeHeader(stream);
            stream.writeUint32(0);
            stream.writeString(this.handler, null, 4);
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeCString(this.name);
          };
          BoxParser.hvcCBox.prototype.write = function(stream) {
            var i2, j;
            this.size = 23;
            for (i2 = 0; i2 < this.nalu_arrays.length; i2++) {
              this.size += 3;
              for (j = 0; j < this.nalu_arrays[i2].length; j++) {
                this.size += 2 + this.nalu_arrays[i2][j].data.length;
              }
            }
            this.writeHeader(stream);
            stream.writeUint8(this.configurationVersion);
            stream.writeUint8((this.general_profile_space << 6) + (this.general_tier_flag << 5) + this.general_profile_idc);
            stream.writeUint32(this.general_profile_compatibility);
            stream.writeUint8Array(this.general_constraint_indicator);
            stream.writeUint8(this.general_level_idc);
            stream.writeUint16(this.min_spatial_segmentation_idc + (15 << 24));
            stream.writeUint8(this.parallelismType + (63 << 2));
            stream.writeUint8(this.chroma_format_idc + (63 << 2));
            stream.writeUint8(this.bit_depth_luma_minus8 + (31 << 3));
            stream.writeUint8(this.bit_depth_chroma_minus8 + (31 << 3));
            stream.writeUint16(this.avgFrameRate);
            stream.writeUint8((this.constantFrameRate << 6) + (this.numTemporalLayers << 3) + (this.temporalIdNested << 2) + this.lengthSizeMinusOne);
            stream.writeUint8(this.nalu_arrays.length);
            for (i2 = 0; i2 < this.nalu_arrays.length; i2++) {
              stream.writeUint8((this.nalu_arrays[i2].completeness << 7) + this.nalu_arrays[i2].nalu_type);
              stream.writeUint16(this.nalu_arrays[i2].length);
              for (j = 0; j < this.nalu_arrays[i2].length; j++) {
                stream.writeUint16(this.nalu_arrays[i2][j].data.length);
                stream.writeUint8Array(this.nalu_arrays[i2][j].data);
              }
            }
          };
          BoxParser.kindBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = this.schemeURI.length + 1 + (this.value.length + 1);
            this.writeHeader(stream);
            stream.writeCString(this.schemeURI);
            stream.writeCString(this.value);
          };
          BoxParser.mdhdBox.prototype.write = function(stream) {
            this.size = 4 * 4 + 2 * 2;
            this.flags = 0;
            this.version = 0;
            this.writeHeader(stream);
            stream.writeUint32(this.creation_time);
            stream.writeUint32(this.modification_time);
            stream.writeUint32(this.timescale);
            stream.writeUint32(this.duration);
            stream.writeUint16(this.language);
            stream.writeUint16(0);
          };
          BoxParser.mehdBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = 4;
            this.writeHeader(stream);
            stream.writeUint32(this.fragment_duration);
          };
          BoxParser.mfhdBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = 4;
            this.writeHeader(stream);
            stream.writeUint32(this.sequence_number);
          };
          BoxParser.mvhdBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = 23 * 4 + 2 * 2;
            this.writeHeader(stream);
            stream.writeUint32(this.creation_time);
            stream.writeUint32(this.modification_time);
            stream.writeUint32(this.timescale);
            stream.writeUint32(this.duration);
            stream.writeUint32(this.rate);
            stream.writeUint16(this.volume << 8);
            stream.writeUint16(0);
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeUint32Array(this.matrix);
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeUint32(this.next_track_id);
          };
          BoxParser.SampleEntry.prototype.writeHeader = function(stream) {
            this.size = 8;
            BoxParser.Box.prototype.writeHeader.call(this, stream);
            stream.writeUint8(0);
            stream.writeUint8(0);
            stream.writeUint8(0);
            stream.writeUint8(0);
            stream.writeUint8(0);
            stream.writeUint8(0);
            stream.writeUint16(this.data_reference_index);
          };
          BoxParser.SampleEntry.prototype.writeFooter = function(stream) {
            for (var i2 = 0; i2 < this.boxes.length; i2++) {
              this.boxes[i2].write(stream);
              this.size += this.boxes[i2].size;
            }
            Log.debug("BoxWriter", "Adjusting box " + this.type + " with new size " + this.size);
            stream.adjustUint32(this.sizePosition, this.size);
          };
          BoxParser.SampleEntry.prototype.write = function(stream) {
            this.writeHeader(stream);
            stream.writeUint8Array(this.data);
            this.size += this.data.length;
            Log.debug("BoxWriter", "Adjusting box " + this.type + " with new size " + this.size);
            stream.adjustUint32(this.sizePosition, this.size);
          };
          BoxParser.VisualSampleEntry.prototype.write = function(stream) {
            this.writeHeader(stream);
            this.size += 2 * 7 + 6 * 4 + 32;
            stream.writeUint16(0);
            stream.writeUint16(0);
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeUint16(this.width);
            stream.writeUint16(this.height);
            stream.writeUint32(this.horizresolution);
            stream.writeUint32(this.vertresolution);
            stream.writeUint32(0);
            stream.writeUint16(this.frame_count);
            stream.writeUint8(Math.min(31, this.compressorname.length));
            stream.writeString(this.compressorname, null, 31);
            stream.writeUint16(this.depth);
            stream.writeInt16(-1);
            this.writeFooter(stream);
          };
          BoxParser.AudioSampleEntry.prototype.write = function(stream) {
            this.writeHeader(stream);
            this.size += 2 * 4 + 3 * 4;
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeUint16(this.channel_count);
            stream.writeUint16(this.samplesize);
            stream.writeUint16(0);
            stream.writeUint16(0);
            stream.writeUint32(this.samplerate << 16);
            this.writeFooter(stream);
          };
          BoxParser.stppSampleEntry.prototype.write = function(stream) {
            this.writeHeader(stream);
            this.size += this.namespace.length + 1 + this.schema_location.length + 1 + this.auxiliary_mime_types.length + 1;
            stream.writeCString(this.namespace);
            stream.writeCString(this.schema_location);
            stream.writeCString(this.auxiliary_mime_types);
            this.writeFooter(stream);
          };
          BoxParser.SampleGroupEntry.prototype.write = function(stream) {
            stream.writeUint8Array(this.data);
          };
          BoxParser.sbgpBox.prototype.write = function(stream) {
            this.version = 1;
            this.flags = 0;
            this.size = 12 + 8 * this.entries.length;
            this.writeHeader(stream);
            stream.writeString(this.grouping_type, null, 4);
            stream.writeUint32(this.grouping_type_parameter);
            stream.writeUint32(this.entries.length);
            for (var i2 = 0; i2 < this.entries.length; i2++) {
              var entry = this.entries[i2];
              stream.writeInt32(entry.sample_count);
              stream.writeInt32(entry.group_description_index);
            }
          };
          BoxParser.sgpdBox.prototype.write = function(stream) {
            var i2;
            var entry;
            this.flags = 0;
            this.size = 12;
            for (i2 = 0; i2 < this.entries.length; i2++) {
              entry = this.entries[i2];
              if (this.version === 1) {
                if (this.default_length === 0) {
                  this.size += 4;
                }
                this.size += entry.data.length;
              }
            }
            this.writeHeader(stream);
            stream.writeString(this.grouping_type, null, 4);
            if (this.version === 1) {
              stream.writeUint32(this.default_length);
            }
            if (this.version >= 2) {
              stream.writeUint32(this.default_sample_description_index);
            }
            stream.writeUint32(this.entries.length);
            for (i2 = 0; i2 < this.entries.length; i2++) {
              entry = this.entries[i2];
              if (this.version === 1) {
                if (this.default_length === 0) {
                  stream.writeUint32(entry.description_length);
                }
              }
              entry.write(stream);
            }
          };
          BoxParser.sidxBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = 4 * 4 + 2 + 2 + 12 * this.references.length;
            this.writeHeader(stream);
            stream.writeUint32(this.reference_ID);
            stream.writeUint32(this.timescale);
            stream.writeUint32(this.earliest_presentation_time);
            stream.writeUint32(this.first_offset);
            stream.writeUint16(0);
            stream.writeUint16(this.references.length);
            for (var i2 = 0; i2 < this.references.length; i2++) {
              var ref2 = this.references[i2];
              stream.writeUint32(ref2.reference_type << 31 | ref2.referenced_size);
              stream.writeUint32(ref2.subsegment_duration);
              stream.writeUint32(ref2.starts_with_SAP << 31 | ref2.SAP_type << 28 | ref2.SAP_delta_time);
            }
          };
          BoxParser.smhdBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 1;
            this.size = 4;
            this.writeHeader(stream);
            stream.writeUint16(this.balance);
            stream.writeUint16(0);
          };
          BoxParser.stcoBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = 4 + 4 * this.chunk_offsets.length;
            this.writeHeader(stream);
            stream.writeUint32(this.chunk_offsets.length);
            stream.writeUint32Array(this.chunk_offsets);
          };
          BoxParser.stscBox.prototype.write = function(stream) {
            var i2;
            this.version = 0;
            this.flags = 0;
            this.size = 4 + 12 * this.first_chunk.length;
            this.writeHeader(stream);
            stream.writeUint32(this.first_chunk.length);
            for (i2 = 0; i2 < this.first_chunk.length; i2++) {
              stream.writeUint32(this.first_chunk[i2]);
              stream.writeUint32(this.samples_per_chunk[i2]);
              stream.writeUint32(this.sample_description_index[i2]);
            }
          };
          BoxParser.stsdBox.prototype.write = function(stream) {
            var i2;
            this.version = 0;
            this.flags = 0;
            this.size = 0;
            this.writeHeader(stream);
            stream.writeUint32(this.entries.length);
            this.size += 4;
            for (i2 = 0; i2 < this.entries.length; i2++) {
              this.entries[i2].write(stream);
              this.size += this.entries[i2].size;
            }
            Log.debug("BoxWriter", "Adjusting box " + this.type + " with new size " + this.size);
            stream.adjustUint32(this.sizePosition, this.size);
          };
          BoxParser.stshBox.prototype.write = function(stream) {
            var i2;
            this.version = 0;
            this.flags = 0;
            this.size = 4 + 8 * this.shadowed_sample_numbers.length;
            this.writeHeader(stream);
            stream.writeUint32(this.shadowed_sample_numbers.length);
            for (i2 = 0; i2 < this.shadowed_sample_numbers.length; i2++) {
              stream.writeUint32(this.shadowed_sample_numbers[i2]);
              stream.writeUint32(this.sync_sample_numbers[i2]);
            }
          };
          BoxParser.stssBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = 4 + 4 * this.sample_numbers.length;
            this.writeHeader(stream);
            stream.writeUint32(this.sample_numbers.length);
            stream.writeUint32Array(this.sample_numbers);
          };
          BoxParser.stszBox.prototype.write = function(stream) {
            var i2;
            var constant = true;
            this.version = 0;
            this.flags = 0;
            if (this.sample_sizes.length > 0) {
              i2 = 0;
              while (i2 + 1 < this.sample_sizes.length) {
                if (this.sample_sizes[i2 + 1] !== this.sample_sizes[0]) {
                  constant = false;
                  break;
                } else {
                  i2++;
                }
              }
            } else {
              constant = false;
            }
            this.size = 8;
            if (!constant) {
              this.size += 4 * this.sample_sizes.length;
            }
            this.writeHeader(stream);
            if (!constant) {
              stream.writeUint32(0);
            } else {
              stream.writeUint32(this.sample_sizes[0]);
            }
            stream.writeUint32(this.sample_sizes.length);
            if (!constant) {
              stream.writeUint32Array(this.sample_sizes);
            }
          };
          BoxParser.sttsBox.prototype.write = function(stream) {
            var i2;
            this.version = 0;
            this.flags = 0;
            this.size = 4 + 8 * this.sample_counts.length;
            this.writeHeader(stream);
            stream.writeUint32(this.sample_counts.length);
            for (i2 = 0; i2 < this.sample_counts.length; i2++) {
              stream.writeUint32(this.sample_counts[i2]);
              stream.writeUint32(this.sample_deltas[i2]);
            }
          };
          BoxParser.tfdtBox.prototype.write = function(stream) {
            var UINT32_MAX = Math.pow(2, 32) - 1;
            this.version = this.baseMediaDecodeTime > UINT32_MAX ? 1 : 0;
            this.flags = 0;
            this.size = 4;
            if (this.version === 1) {
              this.size += 4;
            }
            this.writeHeader(stream);
            if (this.version === 1) {
              stream.writeUint64(this.baseMediaDecodeTime);
            } else {
              stream.writeUint32(this.baseMediaDecodeTime);
            }
          };
          BoxParser.tfhdBox.prototype.write = function(stream) {
            this.version = 0;
            this.size = 4;
            if (this.flags & BoxParser.TFHD_FLAG_BASE_DATA_OFFSET) {
              this.size += 8;
            }
            if (this.flags & BoxParser.TFHD_FLAG_SAMPLE_DESC) {
              this.size += 4;
            }
            if (this.flags & BoxParser.TFHD_FLAG_SAMPLE_DUR) {
              this.size += 4;
            }
            if (this.flags & BoxParser.TFHD_FLAG_SAMPLE_SIZE) {
              this.size += 4;
            }
            if (this.flags & BoxParser.TFHD_FLAG_SAMPLE_FLAGS) {
              this.size += 4;
            }
            this.writeHeader(stream);
            stream.writeUint32(this.track_id);
            if (this.flags & BoxParser.TFHD_FLAG_BASE_DATA_OFFSET) {
              stream.writeUint64(this.base_data_offset);
            }
            if (this.flags & BoxParser.TFHD_FLAG_SAMPLE_DESC) {
              stream.writeUint32(this.default_sample_description_index);
            }
            if (this.flags & BoxParser.TFHD_FLAG_SAMPLE_DUR) {
              stream.writeUint32(this.default_sample_duration);
            }
            if (this.flags & BoxParser.TFHD_FLAG_SAMPLE_SIZE) {
              stream.writeUint32(this.default_sample_size);
            }
            if (this.flags & BoxParser.TFHD_FLAG_SAMPLE_FLAGS) {
              stream.writeUint32(this.default_sample_flags);
            }
          };
          BoxParser.tkhdBox.prototype.write = function(stream) {
            this.version = 0;
            this.size = 4 * 18 + 2 * 4;
            this.writeHeader(stream);
            stream.writeUint32(this.creation_time);
            stream.writeUint32(this.modification_time);
            stream.writeUint32(this.track_id);
            stream.writeUint32(0);
            stream.writeUint32(this.duration);
            stream.writeUint32(0);
            stream.writeUint32(0);
            stream.writeInt16(this.layer);
            stream.writeInt16(this.alternate_group);
            stream.writeInt16(this.volume << 8);
            stream.writeUint16(0);
            stream.writeInt32Array(this.matrix);
            stream.writeUint32(this.width);
            stream.writeUint32(this.height);
          };
          BoxParser.trexBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = 4 * 5;
            this.writeHeader(stream);
            stream.writeUint32(this.track_id);
            stream.writeUint32(this.default_sample_description_index);
            stream.writeUint32(this.default_sample_duration);
            stream.writeUint32(this.default_sample_size);
            stream.writeUint32(this.default_sample_flags);
          };
          BoxParser.trunBox.prototype.write = function(stream) {
            this.version = 0;
            this.size = 4;
            if (this.flags & BoxParser.TRUN_FLAGS_DATA_OFFSET) {
              this.size += 4;
            }
            if (this.flags & BoxParser.TRUN_FLAGS_FIRST_FLAG) {
              this.size += 4;
            }
            if (this.flags & BoxParser.TRUN_FLAGS_DURATION) {
              this.size += 4 * this.sample_duration.length;
            }
            if (this.flags & BoxParser.TRUN_FLAGS_SIZE) {
              this.size += 4 * this.sample_size.length;
            }
            if (this.flags & BoxParser.TRUN_FLAGS_FLAGS) {
              this.size += 4 * this.sample_flags.length;
            }
            if (this.flags & BoxParser.TRUN_FLAGS_CTS_OFFSET) {
              this.size += 4 * this.sample_composition_time_offset.length;
            }
            this.writeHeader(stream);
            stream.writeUint32(this.sample_count);
            if (this.flags & BoxParser.TRUN_FLAGS_DATA_OFFSET) {
              this.data_offset_position = stream.getPosition();
              stream.writeInt32(this.data_offset);
            }
            if (this.flags & BoxParser.TRUN_FLAGS_FIRST_FLAG) {
              stream.writeUint32(this.first_sample_flags);
            }
            for (var i2 = 0; i2 < this.sample_count; i2++) {
              if (this.flags & BoxParser.TRUN_FLAGS_DURATION) {
                stream.writeUint32(this.sample_duration[i2]);
              }
              if (this.flags & BoxParser.TRUN_FLAGS_SIZE) {
                stream.writeUint32(this.sample_size[i2]);
              }
              if (this.flags & BoxParser.TRUN_FLAGS_FLAGS) {
                stream.writeUint32(this.sample_flags[i2]);
              }
              if (this.flags & BoxParser.TRUN_FLAGS_CTS_OFFSET) {
                if (this.version === 0) {
                  stream.writeUint32(this.sample_composition_time_offset[i2]);
                } else {
                  stream.writeInt32(this.sample_composition_time_offset[i2]);
                }
              }
            }
          };
          BoxParser["url Box"].prototype.write = function(stream) {
            this.version = 0;
            if (this.location) {
              this.flags = 0;
              this.size = this.location.length + 1;
            } else {
              this.flags = 1;
              this.size = 0;
            }
            this.writeHeader(stream);
            if (this.location) {
              stream.writeCString(this.location);
            }
          };
          BoxParser["urn Box"].prototype.write = function(stream) {
            this.version = 0;
            this.flags = 0;
            this.size = this.name.length + 1 + (this.location ? this.location.length + 1 : 0);
            this.writeHeader(stream);
            stream.writeCString(this.name);
            if (this.location) {
              stream.writeCString(this.location);
            }
          };
          BoxParser.vmhdBox.prototype.write = function(stream) {
            this.version = 0;
            this.flags = 1;
            this.size = 8;
            this.writeHeader(stream);
            stream.writeUint16(this.graphicsmode);
            stream.writeUint16Array(this.opcolor);
          };
          BoxParser.cttsBox.prototype.unpack = function(samples) {
            var i2, j, k;
            k = 0;
            for (i2 = 0; i2 < this.sample_counts.length; i2++) {
              for (j = 0; j < this.sample_counts[i2]; j++) {
                samples[k].pts = samples[k].dts + this.sample_offsets[i2];
                k++;
              }
            }
          };
          BoxParser.sttsBox.prototype.unpack = function(samples) {
            var i2, j, k;
            k = 0;
            for (i2 = 0; i2 < this.sample_counts.length; i2++) {
              for (j = 0; j < this.sample_counts[i2]; j++) {
                if (k === 0) {
                  samples[k].dts = 0;
                } else {
                  samples[k].dts = samples[k - 1].dts + this.sample_deltas[i2];
                }
                k++;
              }
            }
          };
          BoxParser.stcoBox.prototype.unpack = function(samples) {
            var i2;
            for (i2 = 0; i2 < this.chunk_offsets.length; i2++) {
              samples[i2].offset = this.chunk_offsets[i2];
            }
          };
          BoxParser.stscBox.prototype.unpack = function(samples) {
            var i2, j, k, l, m;
            l = 0;
            m = 0;
            for (i2 = 0; i2 < this.first_chunk.length; i2++) {
              for (j = 0; j < (i2 + 1 < this.first_chunk.length ? this.first_chunk[i2 + 1] : Infinity); j++) {
                m++;
                for (k = 0; k < this.samples_per_chunk[i2]; k++) {
                  if (samples[l]) {
                    samples[l].description_index = this.sample_description_index[i2];
                    samples[l].chunk_index = m;
                  } else {
                    return;
                  }
                  l++;
                }
              }
            }
          };
          BoxParser.stszBox.prototype.unpack = function(samples) {
            var i2;
            for (i2 = 0; i2 < this.sample_sizes.length; i2++) {
              samples[i2].size = this.sample_sizes[i2];
            }
          };
          BoxParser.DIFF_BOXES_PROP_NAMES = [
            "boxes",
            "entries",
            "references",
            "subsamples",
            "items",
            "item_infos",
            "extents",
            "associations",
            "subsegments",
            "ranges",
            "seekLists",
            "seekPoints",
            "esd",
            "levels"
          ];
          BoxParser.DIFF_PRIMITIVE_ARRAY_PROP_NAMES = [
            "compatible_brands",
            "matrix",
            "opcolor",
            "sample_counts",
            "sample_counts",
            "sample_deltas",
            "first_chunk",
            "samples_per_chunk",
            "sample_sizes",
            "chunk_offsets",
            "sample_offsets",
            "sample_description_index",
            "sample_duration"
          ];
          BoxParser.boxEqualFields = function(box_a, box_b) {
            if (box_a && !box_b) return false;
            var prop;
            for (prop in box_a) {
              if (BoxParser.DIFF_BOXES_PROP_NAMES.indexOf(prop) > -1) {
                continue;
              } else if (box_a[prop] instanceof BoxParser.Box || box_b[prop] instanceof BoxParser.Box) {
                continue;
              } else if (typeof box_a[prop] === "undefined" || typeof box_b[prop] === "undefined") {
                continue;
              } else if (typeof box_a[prop] === "function" || typeof box_b[prop] === "function") {
                continue;
              } else if (box_a.subBoxNames && box_a.subBoxNames.indexOf(prop.slice(0, 4)) > -1 || box_b.subBoxNames && box_b.subBoxNames.indexOf(prop.slice(0, 4)) > -1) {
                continue;
              } else {
                if (prop === "data" || prop === "start" || prop === "size" || prop === "creation_time" || prop === "modification_time") {
                  continue;
                } else if (BoxParser.DIFF_PRIMITIVE_ARRAY_PROP_NAMES.indexOf(prop) > -1) {
                  continue;
                } else {
                  if (box_a[prop] !== box_b[prop]) {
                    return false;
                  }
                }
              }
            }
            return true;
          };
          BoxParser.boxEqual = function(box_a, box_b) {
            if (!BoxParser.boxEqualFields(box_a, box_b)) {
              return false;
            }
            for (var j = 0; j < BoxParser.DIFF_BOXES_PROP_NAMES.length; j++) {
              var name = BoxParser.DIFF_BOXES_PROP_NAMES[j];
              if (box_a[name] && box_b[name]) {
                if (!BoxParser.boxEqual(box_a[name], box_b[name])) {
                  return false;
                }
              }
            }
            return true;
          };
          var VTTin4Parser = function() {
          };
          VTTin4Parser.prototype.parseSample = function(data) {
            var cues, cue;
            var stream = new MP4BoxStream(data.buffer);
            cues = [];
            while (!stream.isEos()) {
              cue = BoxParser.parseOneBox(stream, false);
              if (cue.code === BoxParser.OK && cue.box.type === "vttc") {
                cues.push(cue.box);
              }
            }
            return cues;
          };
          VTTin4Parser.prototype.getText = function(startTime, endTime, data) {
            function pad(n, width, z) {
              z = z || "0";
              n = n + "";
              return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
            }
            function secToTimestamp(insec) {
              var h2 = Math.floor(insec / 3600);
              var m = Math.floor((insec - h2 * 3600) / 60);
              var s = Math.floor(insec - h2 * 3600 - m * 60);
              var ms = Math.floor((insec - h2 * 3600 - m * 60 - s) * 1e3);
              return "" + pad(h2, 2) + ":" + pad(m, 2) + ":" + pad(s, 2) + "." + pad(ms, 3);
            }
            var cues = this.parseSample(data);
            var string = "";
            for (var i2 = 0; i2 < cues.length; i2++) {
              var cueIn4 = cues[i2];
              string += secToTimestamp(startTime) + " --> " + secToTimestamp(endTime) + "\r\n";
              string += cueIn4.payl.text;
            }
            return string;
          };
          var XMLSubtitlein4Parser = function() {
          };
          XMLSubtitlein4Parser.prototype.parseSample = function(sample) {
            var res = {};
            var i2;
            res.resources = [];
            var stream = new MP4BoxStream(sample.data.buffer);
            if (!sample.subsamples || sample.subsamples.length === 0) {
              res.documentString = stream.readString(sample.data.length);
            } else {
              res.documentString = stream.readString(sample.subsamples[0].size);
              if (sample.subsamples.length > 1) {
                for (i2 = 1; i2 < sample.subsamples.length; i2++) {
                  res.resources[i2] = stream.readUint8Array(sample.subsamples[i2].size);
                }
              }
            }
            if (typeof DOMParser !== "undefined") {
              res.document = new DOMParser().parseFromString(res.documentString, "application/xml");
            }
            return res;
          };
          var Textin4Parser = function() {
          };
          Textin4Parser.prototype.parseSample = function(sample) {
            var textString;
            var stream = new MP4BoxStream(sample.data.buffer);
            textString = stream.readString(sample.data.length);
            return textString;
          };
          Textin4Parser.prototype.parseConfig = function(data) {
            var textString;
            var stream = new MP4BoxStream(data.buffer);
            stream.readUint32();
            textString = stream.readCString();
            return textString;
          };
          {
            exports.VTTin4Parser = VTTin4Parser;
            exports.XMLSubtitlein4Parser = XMLSubtitlein4Parser;
            exports.Textin4Parser = Textin4Parser;
          }
          var ISOFile = function(stream) {
            this.stream = stream || new MultiBufferStream();
            this.boxes = [];
            this.mdats = [];
            this.moofs = [];
            this.isProgressive = false;
            this.moovStartFound = false;
            this.onMoovStart = null;
            this.moovStartSent = false;
            this.onReady = null;
            this.readySent = false;
            this.onSegment = null;
            this.onSamples = null;
            this.onError = null;
            this.sampleListBuilt = false;
            this.fragmentedTracks = [];
            this.extractedTracks = [];
            this.isFragmentationInitialized = false;
            this.sampleProcessingStarted = false;
            this.nextMoofNumber = 0;
            this.itemListBuilt = false;
            this.items = [];
            this.entity_groups = [];
            this.onSidx = null;
            this.sidxSent = false;
          };
          ISOFile.prototype.setSegmentOptions = function(id, user, options) {
            var trak = this.getTrackById(id);
            if (trak) {
              var fragTrack = {};
              this.fragmentedTracks.push(fragTrack);
              fragTrack.id = id;
              fragTrack.user = user;
              fragTrack.trak = trak;
              trak.nextSample = 0;
              fragTrack.segmentStream = null;
              fragTrack.nb_samples = 1e3;
              fragTrack.rapAlignement = true;
              if (options) {
                if (options.nbSamples) fragTrack.nb_samples = options.nbSamples;
                if (options.rapAlignement) fragTrack.rapAlignement = options.rapAlignement;
              }
            }
          };
          ISOFile.prototype.unsetSegmentOptions = function(id) {
            var index = -1;
            for (var i2 = 0; i2 < this.fragmentedTracks.length; i2++) {
              var fragTrack = this.fragmentedTracks[i2];
              if (fragTrack.id == id) {
                index = i2;
              }
            }
            if (index > -1) {
              this.fragmentedTracks.splice(index, 1);
            }
          };
          ISOFile.prototype.setExtractionOptions = function(id, user, options) {
            var trak = this.getTrackById(id);
            if (trak) {
              var extractTrack = {};
              this.extractedTracks.push(extractTrack);
              extractTrack.id = id;
              extractTrack.user = user;
              extractTrack.trak = trak;
              trak.nextSample = 0;
              extractTrack.nb_samples = 1e3;
              extractTrack.samples = [];
              if (options) {
                if (options.nbSamples) extractTrack.nb_samples = options.nbSamples;
              }
            }
          };
          ISOFile.prototype.unsetExtractionOptions = function(id) {
            var index = -1;
            for (var i2 = 0; i2 < this.extractedTracks.length; i2++) {
              var extractTrack = this.extractedTracks[i2];
              if (extractTrack.id == id) {
                index = i2;
              }
            }
            if (index > -1) {
              this.extractedTracks.splice(index, 1);
            }
          };
          ISOFile.prototype.parse = function() {
            var ret2;
            var box2;
            var parseBoxHeadersOnly = false;
            if (this.restoreParsePosition) {
              if (!this.restoreParsePosition()) {
                return;
              }
            }
            while (true) {
              if (this.hasIncompleteMdat && this.hasIncompleteMdat()) {
                if (this.processIncompleteMdat()) {
                  continue;
                } else {
                  return;
                }
              } else {
                if (this.saveParsePosition) {
                  this.saveParsePosition();
                }
                ret2 = BoxParser.parseOneBox(this.stream, parseBoxHeadersOnly);
                if (ret2.code === BoxParser.ERR_NOT_ENOUGH_DATA) {
                  if (this.processIncompleteBox) {
                    if (this.processIncompleteBox(ret2)) {
                      continue;
                    } else {
                      return;
                    }
                  } else {
                    return;
                  }
                } else {
                  var box_type;
                  box2 = ret2.box;
                  box_type = box2.type !== "uuid" ? box2.type : box2.uuid;
                  this.boxes.push(box2);
                  switch (box_type) {
                    case "mdat":
                      this.mdats.push(box2);
                      break;
                    case "moof":
                      this.moofs.push(box2);
                      break;
                    case "moov":
                      this.moovStartFound = true;
                      if (this.mdats.length === 0) {
                        this.isProgressive = true;
                      }
                    /* no break */
                    /* falls through */
                    default:
                      if (this[box_type] !== undefined) {
                        Log.warn("ISOFile", "Duplicate Box of type: " + box_type + ", overriding previous occurrence");
                      }
                      this[box_type] = box2;
                      break;
                  }
                  if (this.updateUsedBytes) {
                    this.updateUsedBytes(box2, ret2);
                  }
                }
              }
            }
          };
          ISOFile.prototype.checkBuffer = function(ab) {
            if (ab === null || ab === undefined) {
              throw "Buffer must be defined and non empty";
            }
            if (ab.fileStart === undefined) {
              throw "Buffer must have a fileStart property";
            }
            if (ab.byteLength === 0) {
              Log.warn("ISOFile", "Ignoring empty buffer (fileStart: " + ab.fileStart + ")");
              this.stream.logBufferLevel();
              return false;
            }
            Log.info("ISOFile", "Processing buffer (fileStart: " + ab.fileStart + ")");
            ab.usedBytes = 0;
            this.stream.insertBuffer(ab);
            this.stream.logBufferLevel();
            if (!this.stream.initialized()) {
              Log.warn("ISOFile", "Not ready to start parsing");
              return false;
            }
            return true;
          };
          ISOFile.prototype.appendBuffer = function(ab, last) {
            var nextFileStart;
            if (!this.checkBuffer(ab)) {
              return;
            }
            this.parse();
            if (this.moovStartFound && !this.moovStartSent) {
              this.moovStartSent = true;
              if (this.onMoovStart) this.onMoovStart();
            }
            if (this.moov) {
              if (!this.sampleListBuilt) {
                this.buildSampleLists();
                this.sampleListBuilt = true;
              }
              this.updateSampleLists();
              if (this.onReady && !this.readySent) {
                this.readySent = true;
                this.onReady(this.getInfo());
              }
              this.processSamples(last);
              if (this.nextSeekPosition) {
                nextFileStart = this.nextSeekPosition;
                this.nextSeekPosition = undefined;
              } else {
                nextFileStart = this.nextParsePosition;
              }
              if (this.stream.getEndFilePositionAfter) {
                nextFileStart = this.stream.getEndFilePositionAfter(nextFileStart);
              }
            } else {
              if (this.nextParsePosition) {
                nextFileStart = this.nextParsePosition;
              } else {
                nextFileStart = 0;
              }
            }
            if (this.sidx) {
              if (this.onSidx && !this.sidxSent) {
                this.onSidx(this.sidx);
                this.sidxSent = true;
              }
            }
            if (this.meta) {
              if (this.flattenItemInfo && !this.itemListBuilt) {
                this.flattenItemInfo();
                this.itemListBuilt = true;
              }
              if (this.processItems) {
                this.processItems(this.onItem);
              }
            }
            if (this.stream.cleanBuffers) {
              Log.info("ISOFile", "Done processing buffer (fileStart: " + ab.fileStart + ") - next buffer to fetch should have a fileStart position of " + nextFileStart);
              this.stream.logBufferLevel();
              this.stream.cleanBuffers();
              this.stream.logBufferLevel(true);
              Log.info("ISOFile", "Sample data size in memory: " + this.getAllocatedSampleDataSize());
            }
            return nextFileStart;
          };
          ISOFile.prototype.getInfo = function() {
            var i2, j;
            var movie = {};
            var trak;
            var track;
            var ref2;
            var sample_desc;
            var _1904 = (/* @__PURE__ */ new Date("1904-01-01T00:00:00Z")).getTime();
            if (this.moov) {
              movie.hasMoov = true;
              movie.duration = this.moov.mvhd.duration;
              movie.timescale = this.moov.mvhd.timescale;
              movie.isFragmented = this.moov.mvex != null;
              if (movie.isFragmented && this.moov.mvex.mehd) {
                movie.fragment_duration = this.moov.mvex.mehd.fragment_duration;
              }
              movie.isProgressive = this.isProgressive;
              movie.hasIOD = this.moov.iods != null;
              movie.brands = [];
              movie.brands.push(this.ftyp.major_brand);
              movie.brands = movie.brands.concat(this.ftyp.compatible_brands);
              movie.created = new Date(_1904 + this.moov.mvhd.creation_time * 1e3);
              movie.modified = new Date(_1904 + this.moov.mvhd.modification_time * 1e3);
              movie.tracks = [];
              movie.audioTracks = [];
              movie.videoTracks = [];
              movie.subtitleTracks = [];
              movie.metadataTracks = [];
              movie.hintTracks = [];
              movie.otherTracks = [];
              for (i2 = 0; i2 < this.moov.traks.length; i2++) {
                trak = this.moov.traks[i2];
                sample_desc = trak.mdia.minf.stbl.stsd.entries[0];
                track = {};
                movie.tracks.push(track);
                track.id = trak.tkhd.track_id;
                track.name = trak.mdia.hdlr.name;
                track.references = [];
                if (trak.tref) {
                  for (j = 0; j < trak.tref.boxes.length; j++) {
                    ref2 = {};
                    track.references.push(ref2);
                    ref2.type = trak.tref.boxes[j].type;
                    ref2.track_ids = trak.tref.boxes[j].track_ids;
                  }
                }
                if (trak.edts) {
                  track.edits = trak.edts.elst.entries;
                }
                track.created = new Date(_1904 + trak.tkhd.creation_time * 1e3);
                track.modified = new Date(_1904 + trak.tkhd.modification_time * 1e3);
                track.movie_duration = trak.tkhd.duration;
                track.movie_timescale = movie.timescale;
                track.layer = trak.tkhd.layer;
                track.alternate_group = trak.tkhd.alternate_group;
                track.volume = trak.tkhd.volume;
                track.matrix = trak.tkhd.matrix;
                track.track_width = trak.tkhd.width / (1 << 16);
                track.track_height = trak.tkhd.height / (1 << 16);
                track.timescale = trak.mdia.mdhd.timescale;
                track.cts_shift = trak.mdia.minf.stbl.cslg;
                track.duration = trak.mdia.mdhd.duration;
                track.samples_duration = trak.samples_duration;
                track.codec = sample_desc.getCodec();
                track.kind = trak.udta && trak.udta.kinds.length ? trak.udta.kinds[0] : { schemeURI: "", value: "" };
                track.language = trak.mdia.elng ? trak.mdia.elng.extended_language : trak.mdia.mdhd.languageString;
                track.nb_samples = trak.samples.length;
                track.size = trak.samples_size;
                track.bitrate = track.size * 8 * track.timescale / track.samples_duration;
                if (sample_desc.isAudio()) {
                  track.type = "audio";
                  movie.audioTracks.push(track);
                  track.audio = {};
                  track.audio.sample_rate = sample_desc.getSampleRate();
                  track.audio.channel_count = sample_desc.getChannelCount();
                  track.audio.sample_size = sample_desc.getSampleSize();
                } else if (sample_desc.isVideo()) {
                  track.type = "video";
                  movie.videoTracks.push(track);
                  track.video = {};
                  track.video.width = sample_desc.getWidth();
                  track.video.height = sample_desc.getHeight();
                } else if (sample_desc.isSubtitle()) {
                  track.type = "subtitles";
                  movie.subtitleTracks.push(track);
                } else if (sample_desc.isHint()) {
                  track.type = "metadata";
                  movie.hintTracks.push(track);
                } else if (sample_desc.isMetadata()) {
                  track.type = "metadata";
                  movie.metadataTracks.push(track);
                } else {
                  track.type = "metadata";
                  movie.otherTracks.push(track);
                }
              }
            } else {
              movie.hasMoov = false;
            }
            movie.mime = "";
            if (movie.hasMoov && movie.tracks) {
              if (movie.videoTracks && movie.videoTracks.length > 0) {
                movie.mime += 'video/mp4; codecs="';
              } else if (movie.audioTracks && movie.audioTracks.length > 0) {
                movie.mime += 'audio/mp4; codecs="';
              } else {
                movie.mime += 'application/mp4; codecs="';
              }
              for (i2 = 0; i2 < movie.tracks.length; i2++) {
                if (i2 !== 0) movie.mime += ",";
                movie.mime += movie.tracks[i2].codec;
              }
              movie.mime += '"; profiles="';
              movie.mime += this.ftyp.compatible_brands.join();
              movie.mime += '"';
            }
            return movie;
          };
          ISOFile.prototype.setNextSeekPositionFromSample = function(sample) {
            if (!sample) {
              return;
            }
            if (this.nextSeekPosition) {
              this.nextSeekPosition = Math.min(sample.offset + sample.alreadyRead, this.nextSeekPosition);
            } else {
              this.nextSeekPosition = sample.offset + sample.alreadyRead;
            }
          };
          ISOFile.prototype.processSamples = function(last) {
            var i2;
            var trak;
            if (!this.sampleProcessingStarted) return;
            if (this.isFragmentationInitialized && this.onSegment !== null) {
              for (i2 = 0; i2 < this.fragmentedTracks.length; i2++) {
                var fragTrak = this.fragmentedTracks[i2];
                trak = fragTrak.trak;
                while (trak.nextSample < trak.samples.length && this.sampleProcessingStarted) {
                  Log.debug("ISOFile", "Creating media fragment on track #" + fragTrak.id + " for sample " + trak.nextSample);
                  var result = this.createFragment(fragTrak.id, trak.nextSample, fragTrak.segmentStream);
                  if (result) {
                    fragTrak.segmentStream = result;
                    trak.nextSample++;
                  } else {
                    break;
                  }
                  if (trak.nextSample % fragTrak.nb_samples === 0 || (last || trak.nextSample >= trak.samples.length)) {
                    Log.info("ISOFile", "Sending fragmented data on track #" + fragTrak.id + " for samples [" + Math.max(0, trak.nextSample - fragTrak.nb_samples) + "," + (trak.nextSample - 1) + "]");
                    Log.info("ISOFile", "Sample data size in memory: " + this.getAllocatedSampleDataSize());
                    if (this.onSegment) {
                      this.onSegment(fragTrak.id, fragTrak.user, fragTrak.segmentStream.buffer, trak.nextSample, last || trak.nextSample >= trak.samples.length);
                    }
                    fragTrak.segmentStream = null;
                    if (fragTrak !== this.fragmentedTracks[i2]) {
                      break;
                    }
                  }
                }
              }
            }
            if (this.onSamples !== null) {
              for (i2 = 0; i2 < this.extractedTracks.length; i2++) {
                var extractTrak = this.extractedTracks[i2];
                trak = extractTrak.trak;
                while (trak.nextSample < trak.samples.length && this.sampleProcessingStarted) {
                  Log.debug("ISOFile", "Exporting on track #" + extractTrak.id + " sample #" + trak.nextSample);
                  var sample = this.getSample(trak, trak.nextSample);
                  if (sample) {
                    trak.nextSample++;
                    extractTrak.samples.push(sample);
                  } else {
                    this.setNextSeekPositionFromSample(trak.samples[trak.nextSample]);
                    break;
                  }
                  if (trak.nextSample % extractTrak.nb_samples === 0 || trak.nextSample >= trak.samples.length) {
                    Log.debug("ISOFile", "Sending samples on track #" + extractTrak.id + " for sample " + trak.nextSample);
                    if (this.onSamples) {
                      this.onSamples(extractTrak.id, extractTrak.user, extractTrak.samples);
                    }
                    extractTrak.samples = [];
                    if (extractTrak !== this.extractedTracks[i2]) {
                      break;
                    }
                  }
                }
              }
            }
          };
          ISOFile.prototype.getBox = function(type) {
            var result = this.getBoxes(type, true);
            return result.length ? result[0] : null;
          };
          ISOFile.prototype.getBoxes = function(type, returnEarly) {
            var result = [];
            ISOFile._sweep.call(this, type, result, returnEarly);
            return result;
          };
          ISOFile._sweep = function(type, result, returnEarly) {
            if (this.type && this.type == type) result.push(this);
            for (var box2 in this.boxes) {
              if (result.length && returnEarly) return;
              ISOFile._sweep.call(this.boxes[box2], type, result, returnEarly);
            }
          };
          ISOFile.prototype.getTrackSamplesInfo = function(track_id) {
            var track = this.getTrackById(track_id);
            if (track) {
              return track.samples;
            } else {
              return;
            }
          };
          ISOFile.prototype.getTrackSample = function(track_id, number) {
            var track = this.getTrackById(track_id);
            var sample = this.getSample(track, number);
            return sample;
          };
          ISOFile.prototype.releaseUsedSamples = function(id, sampleNum) {
            var size = 0;
            var trak = this.getTrackById(id);
            if (!trak.lastValidSample) trak.lastValidSample = 0;
            for (var i2 = trak.lastValidSample; i2 < sampleNum; i2++) {
              size += this.releaseSample(trak, i2);
            }
            Log.info("ISOFile", "Track #" + id + " released samples up to " + sampleNum + " (released size: " + size + ", remaining: " + this.samplesDataSize + ")");
            trak.lastValidSample = sampleNum;
          };
          ISOFile.prototype.start = function() {
            this.sampleProcessingStarted = true;
            this.processSamples(false);
          };
          ISOFile.prototype.stop = function() {
            this.sampleProcessingStarted = false;
          };
          ISOFile.prototype.flush = function() {
            Log.info("ISOFile", "Flushing remaining samples");
            this.updateSampleLists();
            this.processSamples(true);
            this.stream.cleanBuffers();
            this.stream.logBufferLevel(true);
          };
          ISOFile.prototype.seekTrack = function(time, useRap, trak) {
            var j;
            var sample;
            var seek_offset = Infinity;
            var rap_seek_sample_num = 0;
            var seek_sample_num = 0;
            var timescale;
            if (trak.samples.length === 0) {
              Log.info("ISOFile", "No sample in track, cannot seek! Using time " + Log.getDurationString(0, 1) + " and offset: 0");
              return { offset: 0, time: 0 };
            }
            for (j = 0; j < trak.samples.length; j++) {
              sample = trak.samples[j];
              if (j === 0) {
                seek_sample_num = 0;
                timescale = sample.timescale;
              } else if (sample.cts > time * sample.timescale) {
                seek_sample_num = j - 1;
                break;
              }
              if (useRap && sample.is_sync) {
                rap_seek_sample_num = j;
              }
            }
            if (useRap) {
              seek_sample_num = rap_seek_sample_num;
            }
            time = trak.samples[seek_sample_num].cts;
            trak.nextSample = seek_sample_num;
            while (trak.samples[seek_sample_num].alreadyRead === trak.samples[seek_sample_num].size) {
              if (!trak.samples[seek_sample_num + 1]) {
                break;
              }
              seek_sample_num++;
            }
            seek_offset = trak.samples[seek_sample_num].offset + trak.samples[seek_sample_num].alreadyRead;
            Log.info("ISOFile", "Seeking to " + (useRap ? "RAP" : "") + " sample #" + trak.nextSample + " on track " + trak.tkhd.track_id + ", time " + Log.getDurationString(time, timescale) + " and offset: " + seek_offset);
            return { offset: seek_offset, time: time / timescale };
          };
          ISOFile.prototype.getTrackDuration = function(trak) {
            var sample;
            if (!trak.samples) {
              return Infinity;
            }
            sample = trak.samples[trak.samples.length - 1];
            return (sample.cts + sample.duration) / sample.timescale;
          };
          ISOFile.prototype.seek = function(time, useRap) {
            var moov = this.moov;
            var trak;
            var trak_seek_info;
            var i2;
            var seek_info = { offset: Infinity, time: Infinity };
            if (!this.moov) {
              throw "Cannot seek: moov not received!";
            } else {
              for (i2 = 0; i2 < moov.traks.length; i2++) {
                trak = moov.traks[i2];
                if (time > this.getTrackDuration(trak)) {
                  continue;
                }
                trak_seek_info = this.seekTrack(time, useRap, trak);
                if (trak_seek_info.offset < seek_info.offset) {
                  seek_info.offset = trak_seek_info.offset;
                }
                if (trak_seek_info.time < seek_info.time) {
                  seek_info.time = trak_seek_info.time;
                }
              }
              Log.info("ISOFile", "Seeking at time " + Log.getDurationString(seek_info.time, 1) + " needs a buffer with a fileStart position of " + seek_info.offset);
              if (seek_info.offset === Infinity) {
                seek_info = { offset: this.nextParsePosition, time: 0 };
              } else {
                seek_info.offset = this.stream.getEndFilePositionAfter(seek_info.offset);
              }
              Log.info("ISOFile", "Adjusted seek position (after checking data already in buffer): " + seek_info.offset);
              return seek_info;
            }
          };
          ISOFile.prototype.equal = function(b) {
            var box_index = 0;
            while (box_index < this.boxes.length && box_index < b.boxes.length) {
              var a_box = this.boxes[box_index];
              var b_box = b.boxes[box_index];
              if (!BoxParser.boxEqual(a_box, b_box)) {
                return false;
              }
              box_index++;
            }
            return true;
          };
          {
            exports.ISOFile = ISOFile;
          }
          ISOFile.prototype.lastBoxStartPosition = 0;
          ISOFile.prototype.parsingMdat = null;
          ISOFile.prototype.nextParsePosition = 0;
          ISOFile.prototype.discardMdatData = false;
          ISOFile.prototype.processIncompleteBox = function(ret2) {
            var box2;
            var merged;
            var found;
            if (ret2.type === "mdat") {
              box2 = new BoxParser[ret2.type + "Box"](ret2.size);
              this.parsingMdat = box2;
              this.boxes.push(box2);
              this.mdats.push(box2);
              box2.start = ret2.start;
              box2.hdr_size = ret2.hdr_size;
              this.stream.addUsedBytes(box2.hdr_size);
              this.lastBoxStartPosition = box2.start + box2.size;
              found = this.stream.seek(box2.start + box2.size, false, this.discardMdatData);
              if (found) {
                this.parsingMdat = null;
                return true;
              } else {
                if (!this.moovStartFound) {
                  this.nextParsePosition = box2.start + box2.size;
                } else {
                  this.nextParsePosition = this.stream.findEndContiguousBuf();
                }
                return false;
              }
            } else {
              if (ret2.type === "moov") {
                this.moovStartFound = true;
                if (this.mdats.length === 0) {
                  this.isProgressive = true;
                }
              }
              merged = this.stream.mergeNextBuffer ? this.stream.mergeNextBuffer() : false;
              if (merged) {
                this.nextParsePosition = this.stream.getEndPosition();
                return true;
              } else {
                if (!ret2.type) {
                  this.nextParsePosition = this.stream.getEndPosition();
                } else {
                  if (this.moovStartFound) {
                    this.nextParsePosition = this.stream.getEndPosition();
                  } else {
                    this.nextParsePosition = this.stream.getPosition() + ret2.size;
                  }
                }
                return false;
              }
            }
          };
          ISOFile.prototype.hasIncompleteMdat = function() {
            return this.parsingMdat !== null;
          };
          ISOFile.prototype.processIncompleteMdat = function() {
            var box2;
            var found;
            box2 = this.parsingMdat;
            found = this.stream.seek(box2.start + box2.size, false, this.discardMdatData);
            if (found) {
              Log.debug("ISOFile", "Found 'mdat' end in buffered data");
              this.parsingMdat = null;
              return true;
            } else {
              this.nextParsePosition = this.stream.findEndContiguousBuf();
              return false;
            }
          };
          ISOFile.prototype.restoreParsePosition = function() {
            return this.stream.seek(this.lastBoxStartPosition, true, this.discardMdatData);
          };
          ISOFile.prototype.saveParsePosition = function() {
            this.lastBoxStartPosition = this.stream.getPosition();
          };
          ISOFile.prototype.updateUsedBytes = function(box2, ret2) {
            if (this.stream.addUsedBytes) {
              if (box2.type === "mdat") {
                this.stream.addUsedBytes(box2.hdr_size);
                if (this.discardMdatData) {
                  this.stream.addUsedBytes(box2.size - box2.hdr_size);
                }
              } else {
                this.stream.addUsedBytes(box2.size);
              }
            }
          };
          ISOFile.prototype.add = BoxParser.Box.prototype.add;
          ISOFile.prototype.addBox = BoxParser.Box.prototype.addBox;
          ISOFile.prototype.init = function(_options) {
            var options = _options || {};
            this.add("ftyp").set("major_brand", options.brands && options.brands[0] || "iso4").set("minor_version", 0).set("compatible_brands", options.brands || ["iso4"]);
            var moov = this.add("moov");
            moov.add("mvhd").set("timescale", options.timescale || 600).set("rate", options.rate || 1 << 16).set("creation_time", 0).set("modification_time", 0).set("duration", options.duration || 0).set("volume", options.width ? 0 : 256).set("matrix", [1 << 16, 0, 0, 0, 1 << 16, 0, 0, 0, 1073741824]).set("next_track_id", 1);
            moov.add("mvex");
            return this;
          };
          ISOFile.prototype.addTrack = function(_options) {
            if (!this.moov) {
              this.init(_options);
            }
            var options = _options || {};
            options.width = options.width || 320;
            options.height = options.height || 320;
            options.id = options.id || this.moov.mvhd.next_track_id;
            options.type = options.type || "avc1";
            var trak = this.moov.add("trak");
            this.moov.mvhd.next_track_id = options.id + 1;
            trak.add("tkhd").set("flags", BoxParser.TKHD_FLAG_ENABLED | BoxParser.TKHD_FLAG_IN_MOVIE | BoxParser.TKHD_FLAG_IN_PREVIEW).set("creation_time", 0).set("modification_time", 0).set("track_id", options.id).set("duration", options.duration || 0).set("layer", options.layer || 0).set("alternate_group", 0).set("volume", 1).set("matrix", [0, 0, 0, 0, 0, 0, 0, 0, 0]).set("width", options.width << 16).set("height", options.height << 16);
            var mdia = trak.add("mdia");
            mdia.add("mdhd").set("creation_time", 0).set("modification_time", 0).set("timescale", options.timescale || 1).set("duration", options.media_duration || 0).set("language", options.language || "und");
            mdia.add("hdlr").set("handler", options.hdlr || "vide").set("name", options.name || "Track created with MP4Box.js");
            mdia.add("elng").set("extended_language", options.language || "fr-FR");
            var minf = mdia.add("minf");
            if (BoxParser[options.type + "SampleEntry"] === undefined) return;
            var sample_description_entry = new BoxParser[options.type + "SampleEntry"]();
            sample_description_entry.data_reference_index = 1;
            var media_type = "";
            for (var mediaType in BoxParser.sampleEntryCodes) {
              var codes = BoxParser.sampleEntryCodes[mediaType];
              for (var i2 = 0; i2 < codes.length; i2++) {
                if (codes.indexOf(options.type) > -1) {
                  media_type = mediaType;
                  break;
                }
              }
            }
            switch (media_type) {
              case "Visual":
                minf.add("vmhd").set("graphicsmode", 0).set("opcolor", [0, 0, 0]);
                sample_description_entry.set("width", options.width).set("height", options.height).set("horizresolution", 72 << 16).set("vertresolution", 72 << 16).set("frame_count", 1).set("compressorname", options.type + " Compressor").set("depth", 24);
                if (options.avcDecoderConfigRecord) {
                  var avcC = new BoxParser.avcCBox();
                  avcC.parse(new MP4BoxStream(options.avcDecoderConfigRecord));
                  sample_description_entry.addBox(avcC);
                } else if (options.hevcDecoderConfigRecord) {
                  var hvcC = new BoxParser.hvcCBox();
                  hvcC.parse(new MP4BoxStream(options.hevcDecoderConfigRecord));
                  sample_description_entry.addBox(hvcC);
                }
                break;
              case "Audio":
                minf.add("smhd").set("balance", options.balance || 0);
                sample_description_entry.set("channel_count", options.channel_count || 2).set("samplesize", options.samplesize || 16).set("samplerate", options.samplerate || 1 << 16);
                break;
              case "Hint":
                minf.add("hmhd");
                break;
              case "Subtitle":
                minf.add("sthd");
                switch (options.type) {
                  case "stpp":
                    sample_description_entry.set("namespace", options.namespace || "nonamespace").set("schema_location", options.schema_location || "").set("auxiliary_mime_types", options.auxiliary_mime_types || "");
                    break;
                }
                break;
              case "Metadata":
                minf.add("nmhd");
                break;
              case "System":
                minf.add("nmhd");
                break;
              default:
                minf.add("nmhd");
                break;
            }
            if (options.description) {
              sample_description_entry.addBox(options.description);
            }
            if (options.description_boxes) {
              options.description_boxes.forEach(function(b) {
                sample_description_entry.addBox(b);
              });
            }
            minf.add("dinf").add("dref").addEntry(new BoxParser["url Box"]().set("flags", 1));
            var stbl = minf.add("stbl");
            stbl.add("stsd").addEntry(sample_description_entry);
            stbl.add("stts").set("sample_counts", []).set("sample_deltas", []);
            stbl.add("stsc").set("first_chunk", []).set("samples_per_chunk", []).set("sample_description_index", []);
            stbl.add("stco").set("chunk_offsets", []);
            stbl.add("stsz").set("sample_sizes", []);
            this.moov.mvex.add("trex").set("track_id", options.id).set("default_sample_description_index", options.default_sample_description_index || 1).set("default_sample_duration", options.default_sample_duration || 0).set("default_sample_size", options.default_sample_size || 0).set("default_sample_flags", options.default_sample_flags || 0);
            this.buildTrakSampleLists(trak);
            return options.id;
          };
          BoxParser.Box.prototype.computeSize = function(stream_) {
            var stream = stream_ || new DataStream();
            stream.endianness = DataStream.BIG_ENDIAN;
            this.write(stream);
          };
          ISOFile.prototype.addSample = function(track_id, data, _options) {
            var options = _options || {};
            var sample = {};
            var trak = this.getTrackById(track_id);
            if (trak === null) return;
            sample.number = trak.samples.length;
            sample.track_id = trak.tkhd.track_id;
            sample.timescale = trak.mdia.mdhd.timescale;
            sample.description_index = options.sample_description_index ? options.sample_description_index - 1 : 0;
            sample.description = trak.mdia.minf.stbl.stsd.entries[sample.description_index];
            sample.data = data;
            sample.size = data.byteLength;
            sample.alreadyRead = sample.size;
            sample.duration = options.duration || 1;
            sample.cts = options.cts || 0;
            sample.dts = options.dts || 0;
            sample.is_sync = options.is_sync || false;
            sample.is_leading = options.is_leading || 0;
            sample.depends_on = options.depends_on || 0;
            sample.is_depended_on = options.is_depended_on || 0;
            sample.has_redundancy = options.has_redundancy || 0;
            sample.degradation_priority = options.degradation_priority || 0;
            sample.offset = 0;
            sample.subsamples = options.subsamples;
            trak.samples.push(sample);
            trak.samples_size += sample.size;
            trak.samples_duration += sample.duration;
            if (trak.first_dts === undefined) {
              trak.first_dts = options.dts;
            }
            this.processSamples();
            var moof = this.createSingleSampleMoof(sample);
            this.addBox(moof);
            moof.computeSize();
            moof.trafs[0].truns[0].data_offset = moof.size + 8;
            this.add("mdat").data = new Uint8Array(data);
            return sample;
          };
          ISOFile.prototype.createSingleSampleMoof = function(sample) {
            var sample_flags = 0;
            if (sample.is_sync)
              sample_flags = 1 << 25;
            else
              sample_flags = 1 << 16;
            var moof = new BoxParser.moofBox();
            moof.add("mfhd").set("sequence_number", this.nextMoofNumber);
            this.nextMoofNumber++;
            var traf = moof.add("traf");
            var trak = this.getTrackById(sample.track_id);
            traf.add("tfhd").set("track_id", sample.track_id).set("flags", BoxParser.TFHD_FLAG_DEFAULT_BASE_IS_MOOF);
            traf.add("tfdt").set("baseMediaDecodeTime", sample.dts - (trak.first_dts || 0));
            traf.add("trun").set("flags", BoxParser.TRUN_FLAGS_DATA_OFFSET | BoxParser.TRUN_FLAGS_DURATION | BoxParser.TRUN_FLAGS_SIZE | BoxParser.TRUN_FLAGS_FLAGS | BoxParser.TRUN_FLAGS_CTS_OFFSET).set("data_offset", 0).set("first_sample_flags", 0).set("sample_count", 1).set("sample_duration", [sample.duration]).set("sample_size", [sample.size]).set("sample_flags", [sample_flags]).set("sample_composition_time_offset", [sample.cts - sample.dts]);
            return moof;
          };
          ISOFile.prototype.lastMoofIndex = 0;
          ISOFile.prototype.samplesDataSize = 0;
          ISOFile.prototype.resetTables = function() {
            var i2;
            var trak, stco, stsc, stsz, stts, ctts, stss;
            this.initial_duration = this.moov.mvhd.duration;
            this.moov.mvhd.duration = 0;
            for (i2 = 0; i2 < this.moov.traks.length; i2++) {
              trak = this.moov.traks[i2];
              trak.tkhd.duration = 0;
              trak.mdia.mdhd.duration = 0;
              stco = trak.mdia.minf.stbl.stco || trak.mdia.minf.stbl.co64;
              stco.chunk_offsets = [];
              stsc = trak.mdia.minf.stbl.stsc;
              stsc.first_chunk = [];
              stsc.samples_per_chunk = [];
              stsc.sample_description_index = [];
              stsz = trak.mdia.minf.stbl.stsz || trak.mdia.minf.stbl.stz2;
              stsz.sample_sizes = [];
              stts = trak.mdia.minf.stbl.stts;
              stts.sample_counts = [];
              stts.sample_deltas = [];
              ctts = trak.mdia.minf.stbl.ctts;
              if (ctts) {
                ctts.sample_counts = [];
                ctts.sample_offsets = [];
              }
              stss = trak.mdia.minf.stbl.stss;
              var k = trak.mdia.minf.stbl.boxes.indexOf(stss);
              if (k != -1) trak.mdia.minf.stbl.boxes[k] = null;
            }
          };
          ISOFile.initSampleGroups = function(trak, traf, sbgps, trak_sgpds, traf_sgpds) {
            var l;
            var k;
            var sample_group_info;
            var sample_group_key;
            function SampleGroupInfo(_type, _parameter, _sbgp) {
              this.grouping_type = _type;
              this.grouping_type_parameter = _parameter;
              this.sbgp = _sbgp;
              this.last_sample_in_run = -1;
              this.entry_index = -1;
            }
            if (traf) {
              traf.sample_groups_info = [];
            }
            if (!trak.sample_groups_info) {
              trak.sample_groups_info = [];
            }
            for (k = 0; k < sbgps.length; k++) {
              sample_group_key = sbgps[k].grouping_type + "/" + sbgps[k].grouping_type_parameter;
              sample_group_info = new SampleGroupInfo(sbgps[k].grouping_type, sbgps[k].grouping_type_parameter, sbgps[k]);
              if (traf) {
                traf.sample_groups_info[sample_group_key] = sample_group_info;
              }
              if (!trak.sample_groups_info[sample_group_key]) {
                trak.sample_groups_info[sample_group_key] = sample_group_info;
              }
              for (l = 0; l < trak_sgpds.length; l++) {
                if (trak_sgpds[l].grouping_type === sbgps[k].grouping_type) {
                  sample_group_info.description = trak_sgpds[l];
                  sample_group_info.description.used = true;
                }
              }
              if (traf_sgpds) {
                for (l = 0; l < traf_sgpds.length; l++) {
                  if (traf_sgpds[l].grouping_type === sbgps[k].grouping_type) {
                    sample_group_info.fragment_description = traf_sgpds[l];
                    sample_group_info.fragment_description.used = true;
                    sample_group_info.is_fragment = true;
                  }
                }
              }
            }
            if (!traf) {
              for (k = 0; k < trak_sgpds.length; k++) {
                if (!trak_sgpds[k].used && trak_sgpds[k].version >= 2) {
                  sample_group_key = trak_sgpds[k].grouping_type + "/0";
                  sample_group_info = new SampleGroupInfo(trak_sgpds[k].grouping_type, 0);
                  if (!trak.sample_groups_info[sample_group_key]) {
                    trak.sample_groups_info[sample_group_key] = sample_group_info;
                  }
                }
              }
            } else {
              if (traf_sgpds) {
                for (k = 0; k < traf_sgpds.length; k++) {
                  if (!traf_sgpds[k].used && traf_sgpds[k].version >= 2) {
                    sample_group_key = traf_sgpds[k].grouping_type + "/0";
                    sample_group_info = new SampleGroupInfo(traf_sgpds[k].grouping_type, 0);
                    sample_group_info.is_fragment = true;
                    if (!traf.sample_groups_info[sample_group_key]) {
                      traf.sample_groups_info[sample_group_key] = sample_group_info;
                    }
                  }
                }
              }
            }
          };
          ISOFile.setSampleGroupProperties = function(trak, sample, sample_number, sample_groups_info) {
            var k;
            var index;
            sample.sample_groups = [];
            for (k in sample_groups_info) {
              sample.sample_groups[k] = {};
              sample.sample_groups[k].grouping_type = sample_groups_info[k].grouping_type;
              sample.sample_groups[k].grouping_type_parameter = sample_groups_info[k].grouping_type_parameter;
              if (sample_number >= sample_groups_info[k].last_sample_in_run) {
                if (sample_groups_info[k].last_sample_in_run < 0) {
                  sample_groups_info[k].last_sample_in_run = 0;
                }
                sample_groups_info[k].entry_index++;
                if (sample_groups_info[k].entry_index <= sample_groups_info[k].sbgp.entries.length - 1) {
                  sample_groups_info[k].last_sample_in_run += sample_groups_info[k].sbgp.entries[sample_groups_info[k].entry_index].sample_count;
                }
              }
              if (sample_groups_info[k].entry_index <= sample_groups_info[k].sbgp.entries.length - 1) {
                sample.sample_groups[k].group_description_index = sample_groups_info[k].sbgp.entries[sample_groups_info[k].entry_index].group_description_index;
              } else {
                sample.sample_groups[k].group_description_index = -1;
              }
              if (sample.sample_groups[k].group_description_index !== 0) {
                var description;
                if (sample_groups_info[k].fragment_description) {
                  description = sample_groups_info[k].fragment_description;
                } else {
                  description = sample_groups_info[k].description;
                }
                if (sample.sample_groups[k].group_description_index > 0) {
                  if (sample.sample_groups[k].group_description_index > 65535) {
                    index = (sample.sample_groups[k].group_description_index >> 16) - 1;
                  } else {
                    index = sample.sample_groups[k].group_description_index - 1;
                  }
                  if (description && index >= 0) {
                    sample.sample_groups[k].description = description.entries[index];
                  }
                } else {
                  if (description && description.version >= 2) {
                    if (description.default_group_description_index > 0) {
                      sample.sample_groups[k].description = description.entries[description.default_group_description_index - 1];
                    }
                  }
                }
              }
            }
          };
          ISOFile.process_sdtp = function(sdtp, sample, number) {
            if (!sample) {
              return;
            }
            if (sdtp) {
              sample.is_leading = sdtp.is_leading[number];
              sample.depends_on = sdtp.sample_depends_on[number];
              sample.is_depended_on = sdtp.sample_is_depended_on[number];
              sample.has_redundancy = sdtp.sample_has_redundancy[number];
            } else {
              sample.is_leading = 0;
              sample.depends_on = 0;
              sample.is_depended_on = 0;
              sample.has_redundancy = 0;
            }
          };
          ISOFile.prototype.buildSampleLists = function() {
            var i2;
            var trak;
            for (i2 = 0; i2 < this.moov.traks.length; i2++) {
              trak = this.moov.traks[i2];
              this.buildTrakSampleLists(trak);
            }
          };
          ISOFile.prototype.buildTrakSampleLists = function(trak) {
            var j;
            var stco, stsc, stsz, stts, ctts, stss, stsd, subs, sbgps, sgpds, stdp;
            var chunk_run_index, chunk_index, last_chunk_in_run, offset_in_chunk, last_sample_in_chunk;
            var last_sample_in_stts_run, stts_run_index, last_sample_in_ctts_run, ctts_run_index, last_stss_index, subs_entry_index, last_subs_sample_index;
            trak.samples = [];
            trak.samples_duration = 0;
            trak.samples_size = 0;
            stco = trak.mdia.minf.stbl.stco || trak.mdia.minf.stbl.co64;
            stsc = trak.mdia.minf.stbl.stsc;
            stsz = trak.mdia.minf.stbl.stsz || trak.mdia.minf.stbl.stz2;
            stts = trak.mdia.minf.stbl.stts;
            ctts = trak.mdia.minf.stbl.ctts;
            stss = trak.mdia.minf.stbl.stss;
            stsd = trak.mdia.minf.stbl.stsd;
            subs = trak.mdia.minf.stbl.subs;
            stdp = trak.mdia.minf.stbl.stdp;
            sbgps = trak.mdia.minf.stbl.sbgps;
            sgpds = trak.mdia.minf.stbl.sgpds;
            last_sample_in_stts_run = -1;
            stts_run_index = -1;
            last_sample_in_ctts_run = -1;
            ctts_run_index = -1;
            last_stss_index = 0;
            subs_entry_index = 0;
            last_subs_sample_index = 0;
            ISOFile.initSampleGroups(trak, null, sbgps, sgpds);
            if (typeof stsz === "undefined") {
              return;
            }
            for (j = 0; j < stsz.sample_sizes.length; j++) {
              var sample = {};
              sample.number = j;
              sample.track_id = trak.tkhd.track_id;
              sample.timescale = trak.mdia.mdhd.timescale;
              sample.alreadyRead = 0;
              trak.samples[j] = sample;
              sample.size = stsz.sample_sizes[j];
              trak.samples_size += sample.size;
              if (j === 0) {
                chunk_index = 1;
                chunk_run_index = 0;
                sample.chunk_index = chunk_index;
                sample.chunk_run_index = chunk_run_index;
                last_sample_in_chunk = stsc.samples_per_chunk[chunk_run_index];
                offset_in_chunk = 0;
                if (chunk_run_index + 1 < stsc.first_chunk.length) {
                  last_chunk_in_run = stsc.first_chunk[chunk_run_index + 1] - 1;
                } else {
                  last_chunk_in_run = Infinity;
                }
              } else {
                if (j < last_sample_in_chunk) {
                  sample.chunk_index = chunk_index;
                  sample.chunk_run_index = chunk_run_index;
                } else {
                  chunk_index++;
                  sample.chunk_index = chunk_index;
                  offset_in_chunk = 0;
                  if (chunk_index <= last_chunk_in_run) ;
                  else {
                    chunk_run_index++;
                    if (chunk_run_index + 1 < stsc.first_chunk.length) {
                      last_chunk_in_run = stsc.first_chunk[chunk_run_index + 1] - 1;
                    } else {
                      last_chunk_in_run = Infinity;
                    }
                  }
                  sample.chunk_run_index = chunk_run_index;
                  last_sample_in_chunk += stsc.samples_per_chunk[chunk_run_index];
                }
              }
              sample.description_index = stsc.sample_description_index[sample.chunk_run_index] - 1;
              sample.description = stsd.entries[sample.description_index];
              sample.offset = stco.chunk_offsets[sample.chunk_index - 1] + offset_in_chunk;
              offset_in_chunk += sample.size;
              if (j > last_sample_in_stts_run) {
                stts_run_index++;
                if (last_sample_in_stts_run < 0) {
                  last_sample_in_stts_run = 0;
                }
                last_sample_in_stts_run += stts.sample_counts[stts_run_index];
              }
              if (j > 0) {
                trak.samples[j - 1].duration = stts.sample_deltas[stts_run_index];
                trak.samples_duration += trak.samples[j - 1].duration;
                sample.dts = trak.samples[j - 1].dts + trak.samples[j - 1].duration;
              } else {
                sample.dts = 0;
              }
              if (ctts) {
                if (j >= last_sample_in_ctts_run) {
                  ctts_run_index++;
                  if (last_sample_in_ctts_run < 0) {
                    last_sample_in_ctts_run = 0;
                  }
                  last_sample_in_ctts_run += ctts.sample_counts[ctts_run_index];
                }
                sample.cts = trak.samples[j].dts + ctts.sample_offsets[ctts_run_index];
              } else {
                sample.cts = sample.dts;
              }
              if (stss) {
                if (j == stss.sample_numbers[last_stss_index] - 1) {
                  sample.is_sync = true;
                  last_stss_index++;
                } else {
                  sample.is_sync = false;
                  sample.degradation_priority = 0;
                }
                if (subs) {
                  if (subs.entries[subs_entry_index].sample_delta + last_subs_sample_index == j + 1) {
                    sample.subsamples = subs.entries[subs_entry_index].subsamples;
                    last_subs_sample_index += subs.entries[subs_entry_index].sample_delta;
                    subs_entry_index++;
                  }
                }
              } else {
                sample.is_sync = true;
              }
              ISOFile.process_sdtp(trak.mdia.minf.stbl.sdtp, sample, sample.number);
              if (stdp) {
                sample.degradation_priority = stdp.priority[j];
              } else {
                sample.degradation_priority = 0;
              }
              if (subs) {
                if (subs.entries[subs_entry_index].sample_delta + last_subs_sample_index == j) {
                  sample.subsamples = subs.entries[subs_entry_index].subsamples;
                  last_subs_sample_index += subs.entries[subs_entry_index].sample_delta;
                }
              }
              if (sbgps.length > 0 || sgpds.length > 0) {
                ISOFile.setSampleGroupProperties(trak, sample, j, trak.sample_groups_info);
              }
            }
            if (j > 0) {
              trak.samples[j - 1].duration = Math.max(trak.mdia.mdhd.duration - trak.samples[j - 1].dts, 0);
              trak.samples_duration += trak.samples[j - 1].duration;
            }
          };
          ISOFile.prototype.updateSampleLists = function() {
            var i2, j, k;
            var default_sample_description_index, default_sample_duration, default_sample_size, default_sample_flags;
            var last_run_position;
            var box2, moof, traf, trak, trex;
            var sample;
            var sample_flags;
            if (this.moov === undefined) {
              return;
            }
            while (this.lastMoofIndex < this.moofs.length) {
              box2 = this.moofs[this.lastMoofIndex];
              this.lastMoofIndex++;
              if (box2.type == "moof") {
                moof = box2;
                for (i2 = 0; i2 < moof.trafs.length; i2++) {
                  traf = moof.trafs[i2];
                  trak = this.getTrackById(traf.tfhd.track_id);
                  trex = this.getTrexById(traf.tfhd.track_id);
                  if (traf.tfhd.flags & BoxParser.TFHD_FLAG_SAMPLE_DESC) {
                    default_sample_description_index = traf.tfhd.default_sample_description_index;
                  } else {
                    default_sample_description_index = trex ? trex.default_sample_description_index : 1;
                  }
                  if (traf.tfhd.flags & BoxParser.TFHD_FLAG_SAMPLE_DUR) {
                    default_sample_duration = traf.tfhd.default_sample_duration;
                  } else {
                    default_sample_duration = trex ? trex.default_sample_duration : 0;
                  }
                  if (traf.tfhd.flags & BoxParser.TFHD_FLAG_SAMPLE_SIZE) {
                    default_sample_size = traf.tfhd.default_sample_size;
                  } else {
                    default_sample_size = trex ? trex.default_sample_size : 0;
                  }
                  if (traf.tfhd.flags & BoxParser.TFHD_FLAG_SAMPLE_FLAGS) {
                    default_sample_flags = traf.tfhd.default_sample_flags;
                  } else {
                    default_sample_flags = trex ? trex.default_sample_flags : 0;
                  }
                  traf.sample_number = 0;
                  if (traf.sbgps.length > 0) {
                    ISOFile.initSampleGroups(trak, traf, traf.sbgps, trak.mdia.minf.stbl.sgpds, traf.sgpds);
                  }
                  for (j = 0; j < traf.truns.length; j++) {
                    var trun = traf.truns[j];
                    for (k = 0; k < trun.sample_count; k++) {
                      sample = {};
                      sample.moof_number = this.lastMoofIndex;
                      sample.number_in_traf = traf.sample_number;
                      traf.sample_number++;
                      sample.number = trak.samples.length;
                      traf.first_sample_index = trak.samples.length;
                      trak.samples.push(sample);
                      sample.track_id = trak.tkhd.track_id;
                      sample.timescale = trak.mdia.mdhd.timescale;
                      sample.description_index = default_sample_description_index - 1;
                      sample.description = trak.mdia.minf.stbl.stsd.entries[sample.description_index];
                      sample.size = default_sample_size;
                      if (trun.flags & BoxParser.TRUN_FLAGS_SIZE) {
                        sample.size = trun.sample_size[k];
                      }
                      trak.samples_size += sample.size;
                      sample.duration = default_sample_duration;
                      if (trun.flags & BoxParser.TRUN_FLAGS_DURATION) {
                        sample.duration = trun.sample_duration[k];
                      }
                      trak.samples_duration += sample.duration;
                      if (trak.first_traf_merged || k > 0) {
                        sample.dts = trak.samples[trak.samples.length - 2].dts + trak.samples[trak.samples.length - 2].duration;
                      } else {
                        if (traf.tfdt) {
                          sample.dts = traf.tfdt.baseMediaDecodeTime;
                        } else {
                          sample.dts = 0;
                        }
                        trak.first_traf_merged = true;
                      }
                      sample.cts = sample.dts;
                      if (trun.flags & BoxParser.TRUN_FLAGS_CTS_OFFSET) {
                        sample.cts = sample.dts + trun.sample_composition_time_offset[k];
                      }
                      sample_flags = default_sample_flags;
                      if (trun.flags & BoxParser.TRUN_FLAGS_FLAGS) {
                        sample_flags = trun.sample_flags[k];
                      } else if (k === 0 && trun.flags & BoxParser.TRUN_FLAGS_FIRST_FLAG) {
                        sample_flags = trun.first_sample_flags;
                      }
                      sample.is_sync = sample_flags >> 16 & 1 ? false : true;
                      sample.is_leading = sample_flags >> 26 & 3;
                      sample.depends_on = sample_flags >> 24 & 3;
                      sample.is_depended_on = sample_flags >> 22 & 3;
                      sample.has_redundancy = sample_flags >> 20 & 3;
                      sample.degradation_priority = sample_flags & 65535;
                      var bdop = traf.tfhd.flags & BoxParser.TFHD_FLAG_BASE_DATA_OFFSET ? true : false;
                      var dbim = traf.tfhd.flags & BoxParser.TFHD_FLAG_DEFAULT_BASE_IS_MOOF ? true : false;
                      var dop = trun.flags & BoxParser.TRUN_FLAGS_DATA_OFFSET ? true : false;
                      var bdo = 0;
                      if (!bdop) {
                        if (!dbim) {
                          if (j === 0) {
                            bdo = moof.start;
                          } else {
                            bdo = last_run_position;
                          }
                        } else {
                          bdo = moof.start;
                        }
                      } else {
                        bdo = traf.tfhd.base_data_offset;
                      }
                      if (j === 0 && k === 0) {
                        if (dop) {
                          sample.offset = bdo + trun.data_offset;
                        } else {
                          sample.offset = bdo;
                        }
                      } else {
                        sample.offset = last_run_position;
                      }
                      last_run_position = sample.offset + sample.size;
                      if (traf.sbgps.length > 0 || traf.sgpds.length > 0 || trak.mdia.minf.stbl.sbgps.length > 0 || trak.mdia.minf.stbl.sgpds.length > 0) {
                        ISOFile.setSampleGroupProperties(trak, sample, sample.number_in_traf, traf.sample_groups_info);
                      }
                    }
                  }
                  if (traf.subs) {
                    trak.has_fragment_subsamples = true;
                    var sample_index = traf.first_sample_index;
                    for (j = 0; j < traf.subs.entries.length; j++) {
                      sample_index += traf.subs.entries[j].sample_delta;
                      sample = trak.samples[sample_index - 1];
                      sample.subsamples = traf.subs.entries[j].subsamples;
                    }
                  }
                }
              }
            }
          };
          ISOFile.prototype.getSample = function(trak, sampleNum) {
            var buffer;
            var sample = trak.samples[sampleNum];
            if (!this.moov) {
              return null;
            }
            if (!sample.data) {
              sample.data = new Uint8Array(sample.size);
              sample.alreadyRead = 0;
              this.samplesDataSize += sample.size;
              Log.debug("ISOFile", "Allocating sample #" + sampleNum + " on track #" + trak.tkhd.track_id + " of size " + sample.size + " (total: " + this.samplesDataSize + ")");
            } else if (sample.alreadyRead == sample.size) {
              return sample;
            }
            while (true) {
              var index = this.stream.findPosition(true, sample.offset + sample.alreadyRead, false);
              if (index > -1) {
                buffer = this.stream.buffers[index];
                var lengthAfterStart = buffer.byteLength - (sample.offset + sample.alreadyRead - buffer.fileStart);
                if (sample.size - sample.alreadyRead <= lengthAfterStart) {
                  Log.debug("ISOFile", "Getting sample #" + sampleNum + " data (alreadyRead: " + sample.alreadyRead + " offset: " + (sample.offset + sample.alreadyRead - buffer.fileStart) + " read size: " + (sample.size - sample.alreadyRead) + " full size: " + sample.size + ")");
                  DataStream.memcpy(
                    sample.data.buffer,
                    sample.alreadyRead,
                    buffer,
                    sample.offset + sample.alreadyRead - buffer.fileStart,
                    sample.size - sample.alreadyRead
                  );
                  buffer.usedBytes += sample.size - sample.alreadyRead;
                  this.stream.logBufferLevel();
                  sample.alreadyRead = sample.size;
                  return sample;
                } else {
                  if (lengthAfterStart === 0) return null;
                  Log.debug("ISOFile", "Getting sample #" + sampleNum + " partial data (alreadyRead: " + sample.alreadyRead + " offset: " + (sample.offset + sample.alreadyRead - buffer.fileStart) + " read size: " + lengthAfterStart + " full size: " + sample.size + ")");
                  DataStream.memcpy(
                    sample.data.buffer,
                    sample.alreadyRead,
                    buffer,
                    sample.offset + sample.alreadyRead - buffer.fileStart,
                    lengthAfterStart
                  );
                  sample.alreadyRead += lengthAfterStart;
                  buffer.usedBytes += lengthAfterStart;
                  this.stream.logBufferLevel();
                }
              } else {
                return null;
              }
            }
          };
          ISOFile.prototype.releaseSample = function(trak, sampleNum) {
            var sample = trak.samples[sampleNum];
            if (sample.data) {
              this.samplesDataSize -= sample.size;
              sample.data = null;
              sample.alreadyRead = 0;
              return sample.size;
            } else {
              return 0;
            }
          };
          ISOFile.prototype.getAllocatedSampleDataSize = function() {
            return this.samplesDataSize;
          };
          ISOFile.prototype.getCodecs = function() {
            var i2;
            var codecs = "";
            for (i2 = 0; i2 < this.moov.traks.length; i2++) {
              var trak = this.moov.traks[i2];
              if (i2 > 0) {
                codecs += ",";
              }
              codecs += trak.mdia.minf.stbl.stsd.entries[0].getCodec();
            }
            return codecs;
          };
          ISOFile.prototype.getTrexById = function(id) {
            var i2;
            if (!this.moov || !this.moov.mvex) return null;
            for (i2 = 0; i2 < this.moov.mvex.trexs.length; i2++) {
              var trex = this.moov.mvex.trexs[i2];
              if (trex.track_id == id) return trex;
            }
            return null;
          };
          ISOFile.prototype.getTrackById = function(id) {
            if (this.moov === undefined) {
              return null;
            }
            for (var j = 0; j < this.moov.traks.length; j++) {
              var trak = this.moov.traks[j];
              if (trak.tkhd.track_id == id) return trak;
            }
            return null;
          };
          ISOFile.prototype.itemsDataSize = 0;
          ISOFile.prototype.flattenItemInfo = function() {
            var items = this.items;
            var entity_groups = this.entity_groups;
            var i2, j;
            var item;
            var meta = this.meta;
            if (meta === null || meta === undefined) return;
            if (meta.hdlr === undefined) return;
            if (meta.iinf === undefined) return;
            for (i2 = 0; i2 < meta.iinf.item_infos.length; i2++) {
              item = {};
              item.id = meta.iinf.item_infos[i2].item_ID;
              items[item.id] = item;
              item.ref_to = [];
              item.name = meta.iinf.item_infos[i2].item_name;
              if (meta.iinf.item_infos[i2].protection_index > 0) {
                item.protection = meta.ipro.protections[meta.iinf.item_infos[i2].protection_index - 1];
              }
              if (meta.iinf.item_infos[i2].item_type) {
                item.type = meta.iinf.item_infos[i2].item_type;
              } else {
                item.type = "mime";
              }
              item.content_type = meta.iinf.item_infos[i2].content_type;
              item.content_encoding = meta.iinf.item_infos[i2].content_encoding;
            }
            if (meta.grpl) {
              for (i2 = 0; i2 < meta.grpl.boxes.length; i2++) {
                entity_group = {};
                entity_group.id = meta.grpl.boxes[i2].group_id;
                entity_group.entity_ids = meta.grpl.boxes[i2].entity_ids;
                entity_group.type = meta.grpl.boxes[i2].type;
                entity_groups[entity_group.id] = entity_group;
              }
            }
            if (meta.iloc) {
              for (i2 = 0; i2 < meta.iloc.items.length; i2++) {
                var itemloc = meta.iloc.items[i2];
                item = items[itemloc.item_ID];
                if (itemloc.data_reference_index !== 0) {
                  Log.warn("Item storage with reference to other files: not supported");
                  item.source = meta.dinf.boxes[itemloc.data_reference_index - 1];
                }
                switch (itemloc.construction_method) {
                  case 0:
                    break;
                  case 1:
                    break;
                  case 2:
                    Log.warn("Item storage with construction_method : not supported");
                    break;
                }
                item.extents = [];
                item.size = 0;
                for (j = 0; j < itemloc.extents.length; j++) {
                  item.extents[j] = {};
                  item.extents[j].offset = itemloc.extents[j].extent_offset + itemloc.base_offset;
                  if (itemloc.construction_method == 1) {
                    item.extents[j].offset += meta.idat.start + meta.idat.hdr_size;
                  }
                  item.extents[j].length = itemloc.extents[j].extent_length;
                  item.extents[j].alreadyRead = 0;
                  item.size += item.extents[j].length;
                }
              }
            }
            if (meta.pitm) {
              items[meta.pitm.item_id].primary = true;
            }
            if (meta.iref) {
              for (i2 = 0; i2 < meta.iref.references.length; i2++) {
                var ref2 = meta.iref.references[i2];
                for (j = 0; j < ref2.references.length; j++) {
                  items[ref2.from_item_ID].ref_to.push({ type: ref2.type, id: ref2.references[j] });
                }
              }
            }
            if (meta.iprp) {
              for (var k = 0; k < meta.iprp.ipmas.length; k++) {
                var ipma = meta.iprp.ipmas[k];
                for (i2 = 0; i2 < ipma.associations.length; i2++) {
                  var association = ipma.associations[i2];
                  item = items[association.id];
                  if (!item) {
                    item = entity_groups[association.id];
                  }
                  if (item) {
                    if (item.properties === undefined) {
                      item.properties = {};
                      item.properties.boxes = [];
                    }
                    for (j = 0; j < association.props.length; j++) {
                      var propEntry = association.props[j];
                      if (propEntry.property_index > 0 && propEntry.property_index - 1 < meta.iprp.ipco.boxes.length) {
                        var propbox = meta.iprp.ipco.boxes[propEntry.property_index - 1];
                        item.properties[propbox.type] = propbox;
                        item.properties.boxes.push(propbox);
                      }
                    }
                  }
                }
              }
            }
          };
          ISOFile.prototype.getItem = function(item_id) {
            var buffer;
            var item;
            if (!this.meta) {
              return null;
            }
            item = this.items[item_id];
            if (!item.data && item.size) {
              item.data = new Uint8Array(item.size);
              item.alreadyRead = 0;
              this.itemsDataSize += item.size;
              Log.debug("ISOFile", "Allocating item #" + item_id + " of size " + item.size + " (total: " + this.itemsDataSize + ")");
            } else if (item.alreadyRead === item.size) {
              return item;
            }
            for (var i2 = 0; i2 < item.extents.length; i2++) {
              var extent = item.extents[i2];
              if (extent.alreadyRead === extent.length) {
                continue;
              } else {
                var index = this.stream.findPosition(true, extent.offset + extent.alreadyRead, false);
                if (index > -1) {
                  buffer = this.stream.buffers[index];
                  var lengthAfterStart = buffer.byteLength - (extent.offset + extent.alreadyRead - buffer.fileStart);
                  if (extent.length - extent.alreadyRead <= lengthAfterStart) {
                    Log.debug("ISOFile", "Getting item #" + item_id + " extent #" + i2 + " data (alreadyRead: " + extent.alreadyRead + " offset: " + (extent.offset + extent.alreadyRead - buffer.fileStart) + " read size: " + (extent.length - extent.alreadyRead) + " full extent size: " + extent.length + " full item size: " + item.size + ")");
                    DataStream.memcpy(
                      item.data.buffer,
                      item.alreadyRead,
                      buffer,
                      extent.offset + extent.alreadyRead - buffer.fileStart,
                      extent.length - extent.alreadyRead
                    );
                    buffer.usedBytes += extent.length - extent.alreadyRead;
                    this.stream.logBufferLevel();
                    item.alreadyRead += extent.length - extent.alreadyRead;
                    extent.alreadyRead = extent.length;
                  } else {
                    Log.debug("ISOFile", "Getting item #" + item_id + " extent #" + i2 + " partial data (alreadyRead: " + extent.alreadyRead + " offset: " + (extent.offset + extent.alreadyRead - buffer.fileStart) + " read size: " + lengthAfterStart + " full extent size: " + extent.length + " full item size: " + item.size + ")");
                    DataStream.memcpy(
                      item.data.buffer,
                      item.alreadyRead,
                      buffer,
                      extent.offset + extent.alreadyRead - buffer.fileStart,
                      lengthAfterStart
                    );
                    extent.alreadyRead += lengthAfterStart;
                    item.alreadyRead += lengthAfterStart;
                    buffer.usedBytes += lengthAfterStart;
                    this.stream.logBufferLevel();
                    return null;
                  }
                } else {
                  return null;
                }
              }
            }
            if (item.alreadyRead === item.size) {
              return item;
            } else {
              return null;
            }
          };
          ISOFile.prototype.releaseItem = function(item_id) {
            var item = this.items[item_id];
            if (item.data) {
              this.itemsDataSize -= item.size;
              item.data = null;
              item.alreadyRead = 0;
              for (var i2 = 0; i2 < item.extents.length; i2++) {
                var extent = item.extents[i2];
                extent.alreadyRead = 0;
              }
              return item.size;
            } else {
              return 0;
            }
          };
          ISOFile.prototype.processItems = function(callback) {
            for (var i2 in this.items) {
              var item = this.items[i2];
              this.getItem(item.id);
              if (callback && !item.sent) {
                callback(item);
                item.sent = true;
                item.data = null;
              }
            }
          };
          ISOFile.prototype.hasItem = function(name) {
            for (var i2 in this.items) {
              var item = this.items[i2];
              if (item.name === name) {
                return item.id;
              }
            }
            return -1;
          };
          ISOFile.prototype.getMetaHandler = function() {
            if (!this.meta) {
              return null;
            } else {
              return this.meta.hdlr.handler;
            }
          };
          ISOFile.prototype.getPrimaryItem = function() {
            if (!this.meta || !this.meta.pitm) {
              return null;
            } else {
              return this.getItem(this.meta.pitm.item_id);
            }
          };
          ISOFile.prototype.itemToFragmentedTrackFile = function(_options) {
            var options = _options || {};
            var item = null;
            if (options.itemId) {
              item = this.getItem(options.itemId);
            } else {
              item = this.getPrimaryItem();
            }
            if (item == null) return null;
            var file = new ISOFile();
            file.discardMdatData = false;
            var trackOptions = { type: item.type, description_boxes: item.properties.boxes };
            if (item.properties.ispe) {
              trackOptions.width = item.properties.ispe.image_width;
              trackOptions.height = item.properties.ispe.image_height;
            }
            var trackId = file.addTrack(trackOptions);
            if (trackId) {
              file.addSample(trackId, item.data);
              return file;
            } else {
              return null;
            }
          };
          ISOFile.prototype.write = function(outstream) {
            for (var i2 = 0; i2 < this.boxes.length; i2++) {
              this.boxes[i2].write(outstream);
            }
          };
          ISOFile.prototype.createFragment = function(track_id, sampleNumber, stream_) {
            var trak = this.getTrackById(track_id);
            var sample = this.getSample(trak, sampleNumber);
            if (sample == null) {
              this.setNextSeekPositionFromSample(trak.samples[sampleNumber]);
              return null;
            }
            var stream = stream_ || new DataStream();
            stream.endianness = DataStream.BIG_ENDIAN;
            var moof = this.createSingleSampleMoof(sample);
            moof.write(stream);
            moof.trafs[0].truns[0].data_offset = moof.size + 8;
            Log.debug("MP4Box", "Adjusting data_offset with new value " + moof.trafs[0].truns[0].data_offset);
            stream.adjustUint32(moof.trafs[0].truns[0].data_offset_position, moof.trafs[0].truns[0].data_offset);
            var mdat = new BoxParser.mdatBox();
            mdat.data = sample.data;
            mdat.write(stream);
            return stream;
          };
          ISOFile.writeInitializationSegment = function(ftyp, moov, total_duration, sample_duration) {
            var i2;
            Log.debug("ISOFile", "Generating initialization segment");
            var stream = new DataStream();
            stream.endianness = DataStream.BIG_ENDIAN;
            ftyp.write(stream);
            var mvex = moov.add("mvex");
            if (total_duration) {
              mvex.add("mehd").set("fragment_duration", total_duration);
            }
            for (i2 = 0; i2 < moov.traks.length; i2++) {
              mvex.add("trex").set("track_id", moov.traks[i2].tkhd.track_id).set("default_sample_description_index", 1).set("default_sample_duration", sample_duration).set("default_sample_size", 0).set("default_sample_flags", 1 << 16);
            }
            moov.write(stream);
            return stream.buffer;
          };
          ISOFile.prototype.save = function(name) {
            var stream = new DataStream();
            stream.endianness = DataStream.BIG_ENDIAN;
            this.write(stream);
            stream.save(name);
          };
          ISOFile.prototype.getBuffer = function() {
            var stream = new DataStream();
            stream.endianness = DataStream.BIG_ENDIAN;
            this.write(stream);
            return stream.buffer;
          };
          ISOFile.prototype.initializeSegmentation = function() {
            var i2;
            var initSegs;
            var trak;
            var seg;
            if (this.onSegment === null) {
              Log.warn("MP4Box", "No segmentation callback set!");
            }
            if (!this.isFragmentationInitialized) {
              this.isFragmentationInitialized = true;
              this.nextMoofNumber = 0;
              this.resetTables();
            }
            initSegs = [];
            for (i2 = 0; i2 < this.fragmentedTracks.length; i2++) {
              var moov = new BoxParser.moovBox();
              moov.mvhd = this.moov.mvhd;
              moov.boxes.push(moov.mvhd);
              trak = this.getTrackById(this.fragmentedTracks[i2].id);
              moov.boxes.push(trak);
              moov.traks.push(trak);
              seg = {};
              seg.id = trak.tkhd.track_id;
              seg.user = this.fragmentedTracks[i2].user;
              seg.buffer = ISOFile.writeInitializationSegment(this.ftyp, moov, this.moov.mvex && this.moov.mvex.mehd ? this.moov.mvex.mehd.fragment_duration : undefined, this.moov.traks[i2].samples.length > 0 ? this.moov.traks[i2].samples[0].duration : 0);
              initSegs.push(seg);
            }
            return initSegs;
          };
          BoxParser.Box.prototype.printHeader = function(output) {
            this.size += 8;
            if (this.size > MAX_SIZE) {
              this.size += 8;
            }
            if (this.type === "uuid") {
              this.size += 16;
            }
            output.log(output.indent + "size:" + this.size);
            output.log(output.indent + "type:" + this.type);
          };
          BoxParser.FullBox.prototype.printHeader = function(output) {
            this.size += 4;
            BoxParser.Box.prototype.printHeader.call(this, output);
            output.log(output.indent + "version:" + this.version);
            output.log(output.indent + "flags:" + this.flags);
          };
          BoxParser.Box.prototype.print = function(output) {
            this.printHeader(output);
          };
          BoxParser.ContainerBox.prototype.print = function(output) {
            this.printHeader(output);
            for (var i2 = 0; i2 < this.boxes.length; i2++) {
              if (this.boxes[i2]) {
                var prev_indent = output.indent;
                output.indent += " ";
                this.boxes[i2].print(output);
                output.indent = prev_indent;
              }
            }
          };
          ISOFile.prototype.print = function(output) {
            output.indent = "";
            for (var i2 = 0; i2 < this.boxes.length; i2++) {
              if (this.boxes[i2]) {
                this.boxes[i2].print(output);
              }
            }
          };
          BoxParser.mvhdBox.prototype.print = function(output) {
            BoxParser.FullBox.prototype.printHeader.call(this, output);
            output.log(output.indent + "creation_time: " + this.creation_time);
            output.log(output.indent + "modification_time: " + this.modification_time);
            output.log(output.indent + "timescale: " + this.timescale);
            output.log(output.indent + "duration: " + this.duration);
            output.log(output.indent + "rate: " + this.rate);
            output.log(output.indent + "volume: " + (this.volume >> 8));
            output.log(output.indent + "matrix: " + this.matrix.join(", "));
            output.log(output.indent + "next_track_id: " + this.next_track_id);
          };
          BoxParser.tkhdBox.prototype.print = function(output) {
            BoxParser.FullBox.prototype.printHeader.call(this, output);
            output.log(output.indent + "creation_time: " + this.creation_time);
            output.log(output.indent + "modification_time: " + this.modification_time);
            output.log(output.indent + "track_id: " + this.track_id);
            output.log(output.indent + "duration: " + this.duration);
            output.log(output.indent + "volume: " + (this.volume >> 8));
            output.log(output.indent + "matrix: " + this.matrix.join(", "));
            output.log(output.indent + "layer: " + this.layer);
            output.log(output.indent + "alternate_group: " + this.alternate_group);
            output.log(output.indent + "width: " + this.width);
            output.log(output.indent + "height: " + this.height);
          };
          var MP4Box2 = {};
          MP4Box2.createFile = function(_keepMdatData, _stream) {
            var keepMdatData = _keepMdatData !== undefined ? _keepMdatData : true;
            var file = new ISOFile(_stream);
            file.discardMdatData = keepMdatData ? false : true;
            return file;
          };
          {
            exports.createFile = MP4Box2.createFile;
          }
        })(mp4box_all);
        return mp4box_all;
      }
      var mp4box_allExports = requireMp4box_all();
      const MP4Box = /* @__PURE__ */ getDefaultExportFromCjs(mp4box_allExports);
      class ClipperCore {
        constructor(options) {
          this.options = options;
        }
        // 辅助函数:获取解码器所需的额外数据
        // biome-ignore lint/suspicious/noExplicitAny: <unknow>
        getExtradata(mp4box) {
          try {
            const entry = mp4box.moov.traks[0].mdia.minf.stbl.stsd.entries[0];
            const box2 = entry.avcC ?? entry.hvcC ?? entry.vpcC;
            if (box2 != null) {
              const buffer = new ArrayBuffer(1024);
              const stream = new mp4box_allExports.DataStream(buffer, 0, mp4box_allExports.DataStream.BIG_ENDIAN);
              box2.write(stream);
              return new Uint8Array(stream.buffer, 8, stream.position - 8);
            }
          } catch (error) {
            console.error("Error in getExtradata:", error);
          }
          return null;
        }
        // 根据 URL 获取 ArrayBuffer,支持流式读取
        async fetchBuffer(url, signal, onData) {
          var _a;
          const response = await fetch(url, { signal });
          if (!onData) {
            return await response.arrayBuffer();
          }
          const reader = (_a = response.body) == null ? undefined : _a.getReader();
          if (!reader) {
            throw new Error("Stream not supported");
          }
          const chunks = [];
          let totalLength = 0;
          while (true) {
            const { done, value } = await reader.read();
            if (done) break;
            if (value) {
              chunks.push(value);
              totalLength += value.length;
              onData(value);
            }
          }
          const result = new Uint8Array(totalLength);
          let offset = 0;
          for (const chunk of chunks) {
            result.set(chunk, offset);
            offset += chunk.length;
          }
          return result.buffer;
        }
        // 计算缩略图大小
        calcClipSize(width, height, maxWidth, maxHeight) {
          const scale = Math.min(maxWidth / width, maxHeight / height);
          return {
            width: width * scale,
            height: height * scale
          };
        }
        // 流式处理单个片段
        async processStreamingSegment({
          url,
          nbSamples,
          maxWidth,
          maxHeight
        }) {
          const frames = [];
          let sampleCount = 0;
          let retryCount = 0;
          const MAX_RETRIES = 10;
          const allData = [];
          let totalDataSize = 0;
          const controller = new AbortController();
          const signal = controller.signal;
          const createDecodePipeline = () => {
            const mp4boxfile = MP4Box.createFile();
            const transmuxer = new Mux.mp4.Transmuxer();
            const videoDecoder = null;
            const videoTrack = null;
            const execute = () => new Promise((resolve, reject) => {
              const checkTermination = () => {
                if (sampleCount >= nbSamples) {
                  controller.abort();
                  resolve(frames);
                  return true;
                }
                return false;
              };
              transmuxer.on("data", (segment) => {
                const initSegment = new Uint8Array(segment.initSegment);
                const data = new Uint8Array(segment.data);
                const buffer = new ArrayBuffer(
                  initSegment.byteLength + data.byteLength
                );
                const uint8View = new Uint8Array(buffer);
                uint8View.set(initSegment, 0);
                uint8View.set(data, initSegment.byteLength);
                buffer.fileStart = 0;
                mp4boxfile.appendBuffer(buffer);
              });
              mp4boxfile.onReady = (info) => {
                pipeline.videoTrack = info.videoTracks[0];
                if (pipeline.videoTrack) {
                  mp4boxfile.setExtractionOptions(pipeline.videoTrack.id, "video", {
                    nbSamples
                  });
                  const { width, height } = this.calcClipSize(
                    pipeline.videoTrack.track_width,
                    pipeline.videoTrack.track_height,
                    maxWidth,
                    maxHeight
                  );
                  pipeline.videoDecoder = new VideoDecoder({
                    output: async (videoFrame) => {
                      const img = await createImageBitmap(videoFrame, {
                        resizeQuality: "pixelated",
                        premultiplyAlpha: "none",
                        resizeWidth: width,
                        resizeHeight: height
                      });
                      const frame = {
                        img,
                        duration: videoFrame.duration,
                        timestamp: videoFrame.timestamp
                      };
                      sampleCount++;
                      frames.push(frame);
                      videoFrame.close();
                      checkTermination();
                    },
                    error: reject
                  });
                  pipeline.videoDecoder.configure({
                    codec: pipeline.videoTrack.codec,
                    codedWidth: pipeline.videoTrack.track_width,
                    codedHeight: pipeline.videoTrack.track_height,
                    hardwareAcceleration: "prefer-hardware",
                    optimizeForLatency: true,
                    description: this.getExtradata(mp4boxfile)
                  });
                  mp4boxfile.start();
                }
              };
              mp4boxfile.onSamples = (trackId, _, samples) => {
                var _a;
                if (((_a = pipeline.videoTrack) == null ? undefined : _a.id) === trackId) {
                  mp4boxfile.stop();
                  for (let i2 = 0; i2 < samples.length && sampleCount < nbSamples; i2++) {
                    const sample = samples[i2];
                    const isKeyFrame = sample.is_sync;
                    const chunk = new EncodedVideoChunk({
                      type: isKeyFrame ? "key" : "delta",
                      timestamp: sample.cts * 1e7 / pipeline.videoTrack.timescale,
                      duration: sample.duration * 1e7 / pipeline.videoTrack.timescale,
                      data: sample.data
                    });
                    if (pipeline.videoDecoder) {
                      pipeline.videoDecoder.decode(chunk);
                    }
                  }
                }
                if (pipeline.videoDecoder) {
                  pipeline.videoDecoder.flush().catch(reject);
                }
              };
            });
            const pipeline = {
              mp4boxfile,
              transmuxer,
              videoDecoder,
              videoTrack,
              execute
            };
            return pipeline;
          };
          return new Promise((resolve, reject) => {
            let pipeline = createDecodePipeline();
            const dataBuffer = [];
            let totalBufferSize = 0;
            const MIN_BUFFER_SIZE = 1024 * 50;
            const processAccumulatedData = () => {
              if (totalBufferSize < MIN_BUFFER_SIZE) {
                return;
              }
              try {
                const combinedBuffer = new Uint8Array(totalBufferSize);
                let offset = 0;
                for (const chunk of dataBuffer) {
                  combinedBuffer.set(chunk, offset);
                  offset += chunk.length;
                }
                pipeline.transmuxer.push(combinedBuffer);
                pipeline.transmuxer.flush();
                pipeline.mp4boxfile.flush();
                dataBuffer.length = 0;
                totalBufferSize = 0;
              } catch (error) {
                handleError(error);
              }
            };
            const handleError = (error) => {
              console.warn(`解码重试 ${retryCount + 1}/${MAX_RETRIES}:`, error);
              if (retryCount < MAX_RETRIES) {
                retryCount++;
                sampleCount = 0;
                frames.length = 0;
                try {
                  pipeline = createDecodePipeline();
                  const combinedBuffer = new Uint8Array(totalDataSize);
                  let offset = 0;
                  for (const chunk of allData) {
                    combinedBuffer.set(chunk, offset);
                    offset += chunk.length;
                  }
                  pipeline.execute().then(() => {
                    resolve(frames);
                  }).catch(handleError);
                  pipeline.transmuxer.push(combinedBuffer);
                  pipeline.transmuxer.flush();
                  pipeline.mp4boxfile.flush();
                } catch (retryError) {
                  handleError(retryError);
                }
              } else {
                reject(error);
              }
            };
            pipeline.execute().then(() => {
              resolve(frames);
            }).catch(handleError);
            this.fetchBuffer(url, signal, (chunk) => {
              allData.push(chunk);
              totalDataSize += chunk.length;
              dataBuffer.push(chunk);
              totalBufferSize += chunk.length;
              processAccumulatedData();
            }).catch((err) => {
              if (err instanceof DOMException && err.name === "AbortError") {
                console.log("fetchBuffer abort");
              } else {
                handleError(err);
              }
            });
          });
        }
      }
      class M3U8Clipper extends ClipperCore {
        constructor(options) {
          super(options);
          this.options = options;
          this.segmentCache = /* @__PURE__ */ new Map();
          this.M3U8Info = null;
          this.clipingPromise = /* @__PURE__ */ new Map();
          this.blur = 0;
          this.blurSegments = [];
        }
        async init(url, blur) {
          var _a;
          this.blur = blur;
          await this.fetchM3U8Info(url);
          this.blurSegments = this.getblurSegments(((_a = this.M3U8Info) == null ? undefined : _a.segments) ?? []);
        }
        // 模糊时间
        blurTime(time) {
          var _a;
          const _blurTime = time - time % this.blur + this.blur / 2;
          return Math.min(Math.max(0, _blurTime), ((_a = this.M3U8Info) == null ? undefined : _a.totalDuration) ?? 0);
        }
        // 模糊分段
        getblurSegments(segments) {
          return segments.filter((segment) => {
            const segmentBlurTime = this.blurTime(segment._startTime);
            const isInBlurRange = segment._startTime <= segmentBlurTime && segment._endTime >= segmentBlurTime;
            return isInBlurRange;
          });
        }
        // 获取 M3U8 信息
        async fetchM3U8Info(url) {
          const response = await fetch(url);
          const m3u8Text = await response.text();
          const parser = new Parser();
          parser.push(m3u8Text);
          parser.end();
          const manifest = parser.manifest;
          let startTime = 0;
          manifest.segments = manifest.segments.map((segment, index) => {
            const uri = new URL(segment.uri, url).href;
            const endTime = startTime + segment.duration;
            const info = {
              ...segment,
              _uri: uri,
              _duration: segment.duration,
              _startTime: startTime,
              _endTime: endTime,
              _index: index
            };
            startTime = endTime;
            return info;
          });
          manifest.totalDuration = startTime;
          this.M3U8Info = manifest;
          return manifest;
        }
        // 获取缩略图
        async getClip(time) {
          var _a;
          if (!this.M3U8Info) {
            throw new Error("M3U8Info is not initialized");
          }
          const segment = this.findSegmentByTime(time);
          if (!segment) {
            throw new Error(
              `Segment is not found: ${time},totalDuration: ${(_a = this.M3U8Info) == null ? undefined : _a.totalDuration}`
            );
          }
          const clipingPromise = this.clipingPromise.get(segment._index);
          if (clipingPromise) {
            throw new Error(
              `Segment is already being clipped: ${segment._index}
				`
            );
          }
          const promise = this.clipsSegment(segment);
          this.clipingPromise.set(segment._index, promise);
          const segmentClips = await promise;
          if (!segmentClips) {
            return null;
          }
          this.segmentCache.set(segment._index, segmentClips);
          return this.findFrameByTime(segmentClips, time);
        }
        // 获取缓存缩略图
        getClipByCache(time) {
          var _a;
          if (!this.M3U8Info) {
            throw new Error("M3U8Info is not initialized");
          }
          const segment = this.findSegmentByTime(time);
          if (!segment) {
            throw new Error(
              `Segment is not found: ${time},totalDuration: ${(_a = this.M3U8Info) == null ? undefined : _a.totalDuration}`
            );
          }
          const clips = this.segmentCache.get(segment._index);
          if (!clips) {
            return null;
          }
          return this.findFrameByTime(clips, time);
        }
        // 根据时间获取分段
        findSegmentByTime(time) {
          if (!this.M3U8Info) {
            throw new Error("M3U8Info is not initialized");
          }
          for (const segment of this.M3U8Info.segments) {
            if (time >= segment._startTime && time < segment._endTime) {
              return segment;
            }
          }
          return null;
        }
        // 清除缓存
        clear() {
          this.M3U8Info = null;
          this.segmentCache.clear();
          this.clipingPromise.clear();
        }
        // 根据 URL 生成分段截图
        async clipsSegment(segment) {
          const startTime = performance.now();
          try {
            const processedFrames = await this.processStreamingSegment({
              url: segment._uri,
              nbSamples: 1,
              maxWidth: this.options.maxWidth,
              maxHeight: this.options.maxHeight
            });
            if (!processedFrames.length) {
              console.warn("No video frames extracted");
              return null;
            }
            const endTime = performance.now();
            const totalTime = endTime - startTime;
            const segmentClips = {
              frames: processedFrames,
              count: processedFrames.length,
              segment,
              times: {
                total: totalTime
              }
            };
            console.log(`分段截图完成
				耗时:${segmentClips.times.total}ms
				分片 URL:${segmentClips.segment._uri}
				分片索引:${segmentClips.segment._index}
				分片截图数量:${segmentClips.frames.length}
				分片时长:${segmentClips.segment._duration}s 
				分片开始时间:${segmentClips.segment._startTime}s
				分片结束时间:${segmentClips.segment._endTime}s
				`);
            return segmentClips;
          } catch (error) {
            console.error("Error processing segment:", error);
            return null;
          }
        }
        // 根据 time 获取帧
        findFrameByTime(segmentClips, time) {
          return segmentClips.frames.find(
            (frame) => segmentClips.segment._startTime + frame.timestamp >= time
          ) ?? segmentClips.frames[0] ?? null;
        }
      }
      class Scheduler {
        constructor(options = {}) {
          this.queue = [];
          this.running = /* @__PURE__ */ new Map();
          this.laneRunningCount = /* @__PURE__ */ new Map();
          this.options = {
            maxConcurrent: 3,
            maxQueueLength: 100,
            defaultRetryDelay: 1e3,
            laneConfig: {}
          };
          this.options = {
            ...this.options,
            ...options
          };
          Object.keys(this.options.laneConfig).forEach((laneName) => {
            this.laneRunningCount.set(laneName, 0);
          });
        }
        /**
         * 添加任务到队列
         */
        async add(execute, options = {}) {
          var _a;
          if (this.queue.length >= this.options.maxQueueLength) {
            throw new Error("队列已满");
          }
          if (options.id && this.get(options.id)) {
            throw new Error(
              `任务已存在: ${options.id} ${(_a = this.get(options.id)) == null ? undefined : _a.status}`
            );
          }
          let resolve = undefined;
          let reject = undefined;
          const promise = new Promise((_resolve, _reject) => {
            resolve = _resolve;
            reject = _reject;
          });
          const task = {
            execute,
            promise,
            priority: options.priority || 0,
            resolve,
            reject,
            timeout: options.timeout,
            retries: options.retries || 0,
            id: options.id || Math.random().toString(36).substr(2, 9),
            lane: options.lane,
            status: "pending",
            immediate: options.immediate,
            action: options.action
          };
          if (task.lane && this.isPaused(task.lane)) {
            task.status = "paused";
          }
          if (task.action === "push") {
            this.queue.push(task);
          } else {
            this.queue.unshift(task);
          }
          this.sort();
          if (task.immediate) {
            this.processQueue();
          }
          return task.promise;
        }
        sort() {
          this.queue.sort((a, b) => {
            var _a, _b;
            const aLanePriority = a.lane ? ((_a = this.options.laneConfig[a.lane]) == null ? undefined : _a.priority) || 0 : 0;
            const bLanePriority = b.lane ? ((_b = this.options.laneConfig[b.lane]) == null ? undefined : _b.priority) || 0 : 0;
            if (aLanePriority !== bLanePriority) {
              return aLanePriority - bLanePriority;
            }
            return a.priority - b.priority;
          });
        }
        /**
         * 暂停全部或指定任务或任务车道
         */
        pause(idOrLane) {
          this.running.forEach((task) => {
            if (!idOrLane || task.id === idOrLane || task.lane === idOrLane) {
              task.status = "paused";
            }
          });
          this.queue.forEach((task) => {
            if (!idOrLane || task.id === idOrLane || task.lane === idOrLane) {
              task.status = "paused";
            }
          });
        }
        /**
         * 恢复全部或指定任务或任务车道
         */
        resume(idOrLane) {
          this.queue.forEach((task) => {
            if ((!idOrLane || task.id === idOrLane || task.lane === idOrLane) && task.status === "paused") {
              task.status = "pending";
            }
          });
          this.sort();
          this.processQueue();
        }
        /**
         * 取消指定任务或任务车道
         */
        cancel(idOrLane) {
          this.queue = this.queue.filter((task) => {
            if (task.id === idOrLane || task.lane === idOrLane) {
              task.status = "cancelled";
              task.reject(new Error("Task cancelled"));
              return false;
            }
            return true;
          });
          this.running.forEach((task, taskId) => {
            if (task.id === idOrLane || task.lane === idOrLane) {
              task.status = "cancelled";
              task.reject(new Error("Task cancelled"));
              this.running.delete(taskId);
              if (task.lane) {
                this.decrementLaneRunningCount(task.lane);
              }
            }
          });
        }
        /**
         * 重试指定任务或任务车道
         */
        retry(idOrLane, retries) {
          const tasksToRetry = [];
          this.queue.forEach((task) => {
            if ((task.id === idOrLane || task.lane === idOrLane) && task.status === "failed") {
              task.retries = retries ?? task.retries;
              task.status = "pending";
              tasksToRetry.push(task);
            }
          });
          tasksToRetry.forEach((task) => {
            this.queue.push(task);
          });
          this.processQueue();
        }
        isPaused(idOrLane) {
          return Boolean(
            this.queue.some(
              (task) => task.lane === idOrLane && task.status === "paused"
              /* Paused */
            )
          );
        }
        /**
         * 增加车道运行计数
         */
        incrementLaneRunningCount(lane) {
          const currentCount = this.laneRunningCount.get(lane) || 0;
          this.laneRunningCount.set(lane, currentCount + 1);
        }
        /**
         * 减少车道运行计数
         */
        decrementLaneRunningCount(lane) {
          const currentCount = this.laneRunningCount.get(lane) || 0;
          if (currentCount > 0) {
            this.laneRunningCount.set(lane, currentCount - 1);
          }
        }
        /**
         * 获取车道当前运行任务数
         */
        getLaneRunningCount(lane) {
          return this.laneRunningCount.get(lane) || 0;
        }
        /**
         * 检查车道是否可以运行更多任务
         */
        canLaneRunMoreTasks(lane) {
          const laneConfig = this.options.laneConfig[lane];
          if (!laneConfig) return true;
          const currentCount = this.getLaneRunningCount(lane);
          return currentCount < laneConfig.maxConcurrent;
        }
        /**
         * 处理队列
         */
        async processQueue() {
          if (this.running.size >= this.options.maxConcurrent) {
            return;
          }
          const nextTask = this.queue.find((task) => {
            if (task.status !== "pending" || this.isPaused(task.id)) {
              return false;
            }
            if (task.lane && !this.canLaneRunMoreTasks(task.lane)) {
              return false;
            }
            return true;
          });
          if (!nextTask) return;
          this.queue = this.queue.filter((task) => task !== nextTask);
          this.running.set(nextTask.id, nextTask);
          nextTask.status = "running";
          if (nextTask.lane) {
            this.incrementLaneRunningCount(nextTask.lane);
          }
          try {
            let timeoutId;
            const executeWithTimeout = async () => {
              if (nextTask.timeout) {
                const timeoutPromise = new Promise((_, reject) => {
                  timeoutId = window.setTimeout(() => {
                    console.warn("Task timeout", nextTask.id);
                    reject(new Error("Task timeout"));
                  }, nextTask.timeout);
                });
                return Promise.race([nextTask.execute(), timeoutPromise]);
              }
              return nextTask.execute();
            };
            const result = await this.executeWithRetry(
              executeWithTimeout,
              nextTask.retries || 0,
              nextTask
            );
            if (timeoutId) clearTimeout(timeoutId);
            nextTask.status = "completed";
            nextTask.resolve(result);
          } catch (error) {
            nextTask.status = "failed";
            nextTask.reject(error);
          } finally {
            this.running.delete(nextTask.id);
            if (nextTask.lane) {
              this.decrementLaneRunningCount(nextTask.lane);
            }
            this.processQueue();
          }
        }
        /**
         * 带重试的执行
         */
        async executeWithRetry(fn, retriesLeft, task) {
          try {
            return await fn();
          } catch (error) {
            if (retriesLeft > 0 && task.status !== "cancelled") {
              console.warn("Task retry", task.id);
              await new Promise(
                (resolve) => setTimeout(resolve, this.options.defaultRetryDelay)
              );
              return this.executeWithRetry(fn, retriesLeft - 1, task);
            }
            throw error;
          }
        }
        /**
         * 获取队列状态
         */
        getStatus() {
          const laneStatus = {};
          this.laneRunningCount.forEach((count, lane) => {
            var _a;
            laneStatus[lane] = {
              running: count,
              maxConcurrent: ((_a = this.options.laneConfig[lane]) == null ? undefined : _a.maxConcurrent) || 0
            };
          });
          return {
            queueLength: this.queue.length,
            runningCount: this.running.size,
            maxConcurrent: this.options.maxConcurrent,
            lanes: laneStatus,
            tasks: {
              pending: this.queue.filter((t) => t.status === "pending").length,
              running: this.running.size,
              paused: this.queue.filter((t) => t.status === "paused").length,
              failed: this.queue.filter((t) => t.status === "failed").length,
              completed: this.queue.filter((t) => t.status === "completed").length,
              cancelled: this.queue.filter((t) => t.status === "cancelled").length
            }
          };
        }
        /**
         * 获取任务
         */
        get(idOrLane) {
          return this.queue.find((t) => t.id === idOrLane || t.lane === idOrLane) ?? this.running.get(idOrLane);
        }
        /**
         * 是否有正在运行的任务
         */
        hasRunning() {
          return this.running.size > 0;
        }
        /**
         * 获取车道的运行状态
         */
        getLaneStatus(lane) {
          const laneConfig = this.options.laneConfig[lane];
          const runningCount = this.getLaneRunningCount(lane);
          return {
            name: lane,
            running: runningCount,
            maxConcurrent: (laneConfig == null ? undefined : laneConfig.maxConcurrent) || 0,
            priority: (laneConfig == null ? undefined : laneConfig.priority) || 0,
            hasConfig: !!laneConfig
          };
        }
        /**
         * 尝试抢占车道
         */
        tryOvertaking(id, lane, priority) {
          const task = this.get(id);
          if (!task) return false;
          if (task.status === "pending" || task.status === "running" || task.status === "paused") {
            task.lane = lane;
            task.priority = priority ?? task.priority;
            this.sort();
            this.processQueue();
            return true;
          }
          return false;
        }
        /**
         *  尝试恢复任务
         */
        tryResume(id) {
          const task = this.get(id);
          if (!task) return false;
          if (task.status === "paused") {
            this.resume(id);
            return true;
          }
          return false;
        }
        /**
         * 设置车道配置
         */
        setLaneConfig(lane, config) {
          const currentConfig = this.options.laneConfig[lane] || {
            name: lane,
            priority: 0,
            maxConcurrent: this.options.maxConcurrent
          };
          this.options.laneConfig[lane] = {
            ...currentConfig,
            ...config
          };
          if (!this.laneRunningCount.has(lane)) {
            this.laneRunningCount.set(lane, 0);
          }
          this.sort();
          this.processQueue();
        }
        /**
         * 等待队列空闲
         */
        async waitIdle(time = 100) {
          if (!this.hasRunning()) {
            return;
          }
          await new Promise((resolve) => setTimeout(resolve, time));
          await this.waitIdle();
        }
        /**
         * 等待特定车道空闲
         */
        async waitLaneIdle(lane, time = 100) {
          if (this.getLaneRunningCount(lane) === 0) {
            return;
          }
          await new Promise((resolve) => setTimeout(resolve, time));
          await this.waitLaneIdle(lane, time);
        }
        /**
         * 清空队列
         */
        clear() {
          this.queue.forEach((task) => {
            task.status = "cancelled";
            task.reject(new Error("Queue cleared"));
          });
          this.queue = [];
          this.running.clear();
          this.laneRunningCount.clear();
          Object.keys(this.options.laneConfig).forEach((laneName) => {
            this.laneRunningCount.set(laneName, 0);
          });
        }
        get length() {
          return this.queue.length;
        }
        get runningCount() {
          return this.running.size;
        }
      }
      const CLIPPER_OPTIONS = {
        maxWidth: 320,
        maxHeight: 180
      };
      const LANE_CONFIG = {
        must: {
          name: "must",
          priority: 1,
          maxConcurrent: 5
        },
        buffer: {
          name: "buffer",
          priority: 2,
          maxConcurrent: 5
        }
      };
      const SCHEDULER_OPTIONS = {
        maxConcurrent: 5,
        maxQueueLength: 500,
        laneConfig: LANE_CONFIG
      };
      const BLUR = 30;
      function useDataThumbnails() {
        const clipper = new M3U8Clipper(CLIPPER_OPTIONS);
        const scheduler = new Scheduler(SCHEDULER_OPTIONS);
        let isInited = false;
        const initialize = async (sources) => {
          isInited = false;
          clipper.clear();
          const source = findLowestQualityHLS(sources);
          if (!source) return;
          await clipper.init(source.url, BLUR);
          await autoBuffer();
          isInited = true;
        };
        const findLowestQualityHLS = (sources) => {
          let lowestQuality = null;
          sources.forEach((source) => {
            if (source.type === "hls") {
              if (!lowestQuality || source.quality < lowestQuality.quality) {
                lowestQuality = source;
              }
            }
          });
          return lowestQuality;
        };
        const onMThumbnailRequestMust = useThrottleFn(
          async (time, isLast) => {
            if (!isInited || Number.isNaN(time)) {
              return null;
            }
            const segment = clipper.findSegmentByTime(time);
            const id = (segment == null ? undefined : segment._uri) ?? "";
            if (!id) {
              throw new Error("segment is not null");
            }
            const lane = isLast ? LANE_CONFIG.must : LANE_CONFIG.buffer;
            let promise;
            const task = scheduler.get(id);
            if (task && isLast && scheduler.tryOvertaking(id, LANE_CONFIG.must.name)) {
              promise = task.promise;
            } else if (task) {
              promise = task.promise;
            } else {
              promise = scheduler.add(
                async () => {
                  const clipImage = await clipper.getClip(time);
                  return (clipImage == null ? undefined : clipImage.img) ?? null;
                },
                {
                  id,
                  lane: lane.name,
                  priority: 0,
                  immediate: true,
                  action: "unshift"
                }
              );
            }
            return await promise.catch((error) => {
              console.error(error.message);
              throw error;
            });
          },
          125,
          true,
          false
        );
        const onThumbnailRequest = async ({
          type,
          time,
          isLast
        }) => {
          if (!isInited || Number.isNaN(time)) {
            return null;
          }
          const _blurTime = clipper.blurTime(time);
          if (type === "Cache") {
            const clipImage = clipper.getClipByCache(_blurTime);
            return (clipImage == null ? undefined : clipImage.img) ?? null;
          }
          return onMThumbnailRequestMust(_blurTime, isLast);
        };
        const autoBuffer = async () => {
          const blurSegments = sampleSize(
            clipper.blurSegments,
            Math.max(
              Math.min(clipper.blurSegments.length, 50),
              clipper.blurSegments.length / (localStorage.getItem("115master-super-auto-buffer") ? 1 : 3)
            )
          );
          if (!blurSegments.length) {
            throw new Error("blurSegments is not null");
          }
          let preloadCount = 0;
          const now = performance.now();
          for (const segment of blurSegments) {
            const id = segment._uri ?? "";
            if (scheduler.get(id)) {
              continue;
            }
            scheduler.add(
              async () => {
                const clipImage = await clipper.getClip(segment._startTime);
                return (clipImage == null ? undefined : clipImage.img) ?? null;
              },
              {
                id,
                lane: LANE_CONFIG.buffer.name,
                priority: 1,
                immediate: true,
                action: "unshift"
              }
            ).then(() => {
              preloadCount++;
              console.log(`
						preloadCount: ${preloadCount}
						progress: ${preloadCount / blurSegments.length * 100}%
						time: ${(performance.now() - now) / 1e3}s
					`);
            });
          }
        };
        const clear = () => {
          clipper.clear();
          scheduler.clear();
        };
        tryOnUnmounted(() => {
          clear();
        });
        return {
          initialize,
          onThumbnailRequest,
          clear
        };
      }
      const useDataVideoSources = () => {
        const list = ref([]);
        const fetch2 = async (pickCode) => {
          const [download, m3u8List] = await Promise.allSettled([
            Drive115Instance.getFileDownloadUrl(pickCode),
            Drive115Instance.parseM3u8Url(Drive115Instance.getM3u8RootUrl(pickCode))
          ]);
          if (download.status === "fulfilled") {
            list.value.unshift({
              name: "Ultra原画",
              url: download.value.url,
              type: "auto",
              quality: 99999,
              displayQuality: "Ultra原画"
            });
            document.cookie = download.value.fileToken || "";
          }
          if (m3u8List.status === "fulfilled") {
            list.value.push(
              ...m3u8List.value.map((item) => ({
                name: `${item.quality}P`,
                url: item.url,
                type: "hls",
                quality: item.quality,
                displayQuality: qualityNumMap[item.quality]
              }))
            );
          } else {
            console.log("m3u8", m3u8List.reason);
          }
        };
        const cleanup = () => {
          list.value = [];
        };
        return {
          list,
          fetch: fetch2,
          cleanup
        };
      };
      const _hoisted_1$1 = { class: "page-container" };
      const _hoisted_2$1 = { class: "page-body" };
      const _hoisted_3$1 = { class: "page-main" };
      const _hoisted_4 = { class: "page-flow" };
      const _hoisted_5 = { class: "local-player" };
      const _hoisted_6 = { class: "page-footer" };
      const _hoisted_7 = { class: "page-sider" };
      const _sfc_main$1 = /* @__PURE__ */ defineComponent({
        __name: "index",
        setup(__props) {
          const xplayerRef = ref();
          const xplayerShow = ref(true);
          const params = useParamsVideoPage();
          const DataVideoSources = useDataVideoSources();
          const DataThumbnails = useDataThumbnails();
          const DataSubtitles = useDataSubtitles();
          const DataMovieInfo = useDataMovieInfo();
          const DataFileInfo = useDataFileInfo();
          const DataPlaylist = useDataPlaylist();
          const handleSubtitleChange = async (subtitle) => {
            await subtitlePreference.savePreference(
              params.pickCode.value,
              subtitle || null
            );
          };
          const handleLocalPlay = async (player) => {
            var _a;
            const { url } = await Drive115Instance.getFileDownloadUrl(params.pickCode.value);
            switch (player) {
              case "mpv":
                open(webLinkShortcutsMpv(url));
                break;
              case "iina":
                (_a = xplayerRef.value) == null ? undefined : _a.interruptSource();
                setTimeout(() => {
                  open(webLinkIINA(url));
                }, 300);
                break;
            }
          };
          useTitle(params.title.value || "");
          const handlePlay = async (item) => {
            goToPlayer({
              cid: params.cid.value,
              pickCode: item.pc,
              title: item.n,
              size: item.s,
              avNumber: getAvNumber(item.n)
            });
            params.getParams();
            DataThumbnails.clear();
            DataVideoSources.cleanup();
            DataSubtitles.execute(0, params.pickCode.value, null);
            DataMovieInfo.value.javDBState.execute(0, null);
            DataMovieInfo.value.javBusState.execute(0, null);
            await nextTick();
            await loadData(false);
          };
          const loadData = async (isFirst = true) => {
            DataVideoSources.fetch(params.pickCode.value).then(() => {
              DataThumbnails.initialize(DataVideoSources.list.value);
            });
            Drive115Instance.fakeVodAuthPickcode(params.pickCode.value).then(() => {
              DataFileInfo.execute(0, params.pickCode.value);
              isFirst && DataPlaylist.execute(0, params.cid.value, params.pickCode.value);
            });
            if (params.avNumber.value) {
              DataMovieInfo.value.javDBState.execute(0, params.avNumber.value);
              DataMovieInfo.value.javBusState.execute(0, params.avNumber.value);
              DataSubtitles.execute(0, params.pickCode.value, params.avNumber.value);
            }
          };
          useTitle(params.title.value || "");
          onMounted(async () => {
            await loadData();
          });
          return (_ctx, _cache) => {
            return openBlock(), createElementBlock("div", _hoisted_1$1, [
              createElementVNode("div", _hoisted_2$1, [
                createElementVNode("div", _hoisted_3$1, [
                  xplayerShow.value ? (openBlock(), createBlock(XPlayer, {
                    key: 0,
                    ref_key: "xplayerRef",
                    ref: xplayerRef,
                    class: "video-player",
                    sources: unref(DataVideoSources).list,
                    subtitles: unref(DataSubtitles).state,
                    onThumbnailRequest: unref(DataThumbnails).onThumbnailRequest,
                    loadingSubtitles: unref(DataSubtitles).isLoading,
                    onSubtitleChange: handleSubtitleChange
                  }, null, 8, ["sources", "subtitles", "onThumbnailRequest", "loadingSubtitles"])) : createCommentVNode("", true),
                  createElementVNode("div", _hoisted_4, [
                    createVNode(FileInfo, { fileInfo: unref(DataFileInfo) }, null, 8, ["fileInfo"]),
                    createElementVNode("div", _hoisted_5, [
                      unref(isMac) ? (openBlock(), createElementBlock("button", {
                        key: 0,
                        class: "page-local-play",
                        onClick: _cache[0] || (_cache[0] = ($event) => handleLocalPlay("iina"))
                      }, "IINA Beta")) : createCommentVNode("", true)
                    ]),
                    createVNode(MovieInfo, { movieInfos: unref(DataMovieInfo) }, null, 8, ["movieInfos"]),
                    createElementVNode("div", _hoisted_6, [
                      createVNode(Footer)
                    ])
                  ])
                ]),
                createElementVNode("div", _hoisted_7, [
                  createVNode(Playlist, {
                    class: "page-sider-playlist",
                    pickCode: unref(params).pickCode.value,
                    playlist: unref(DataPlaylist),
                    onPlay: handlePlay
                  }, null, 8, ["pickCode", "playlist"])
                ])
              ])
            ]);
          };
        }
      });
      const Video = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-93440d89"]]);
      const resetDocument = () => {
        document.body.style.backgroundColor = "#000";
        document.body.style.margin = "0";
        document.body.innerHTML = `<div id="app"></div>`;
        document.title = "";
        _GM_addElement("link", {
          id: "favicon",
          rel: "icon",
          href: "https://115.com/favicon.ico"
        });
      };
      const videoPage = () => {
        resetDocument();
        createApp(Video).mount("#app");
      };
      const _hoisted_1 = { class: "popup-main" };
      const _hoisted_2 = { class: "popup-desc" };
      const _hoisted_3 = { class: "user-agent-box" };
      const _sfc_main = /* @__PURE__ */ defineComponent({
        __name: "index",
        props: {
          visible: { type: Boolean }
        },
        emits: ["update:visible"],
        setup(__props, { emit: __emit }) {
          const emit = __emit;
          const userAgent = ref(navigator.userAgent);
          const close = () => {
            emit("update:visible", false);
          };
          return (_ctx, _cache) => {
            return openBlock(), createBlock(Teleport, { to: "body" }, [
              _ctx.visible ? (openBlock(), createElementBlock("div", {
                key: 0,
                class: "user-agent-popup-overlay",
                onClick: close
              }, [
                createElementVNode("div", {
                  class: "user-agent-popup",
                  onClick: _cache[0] || (_cache[0] = withModifiers(() => {
                  }, ["stop"]))
                }, [
                  createElementVNode("div", { class: "user-agent-popup-header" }, [
                    _cache[1] || (_cache[1] = createElementVNode("h3", null, "115Master 提示", -1)),
                    createElementVNode("button", {
                      class: "close-button",
                      onClick: close
                    }, "×")
                  ]),
                  createElementVNode("div", _hoisted_1, [
                    _cache[3] || (_cache[3] = createElementVNode("div", { class: "popup-content" }, [
                      createElementVNode("div", { class: "content-icon" }, [
                        createElementVNode("span", { class: "number-icon" }, "1")
                      ]),
                      createElementVNode("div", { class: "content-text" }, [
                        createElementVNode("p", null, "现在不需要 User-Agent Switcher and Manager 插件了"),
                        createElementVNode("p", null, " 快卸载掉他吧~ "),
                        createElementVNode("p", null, " 然后刷新下页面,复活我~ ")
                      ])
                    ], -1)),
                    createElementVNode("div", _hoisted_2, [
                      _cache[2] || (_cache[2] = createElementVNode("p", null, "当前的 User-Agent", -1)),
                      createElementVNode("div", _hoisted_3, toDisplayString(userAgent.value), 1)
                    ])
                  ])
                ])
              ])) : createCommentVNode("", true)
            ]);
          };
        }
      });
      const UserAgentPopup = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-8574f3b4"]]);
      const checkUserAgent = () => {
        const userAgent = navigator.userAgent;
        const is115Browser27 = userAgent.includes("115Browser/27");
        if (is115Browser27) {
          const popupContainer = document.createElement("div");
          document.body.appendChild(popupContainer);
          const app = createApp({
            render() {
              return h(UserAgentPopup, {
                visible: true,
                "onUpdate:visible": (value) => {
                  if (!value) {
                    setTimeout(() => {
                      app.unmount();
                      document.body.removeChild(popupContainer);
                    }, 300);
                  }
                }
              });
            }
          });
          app.mount(popupContainer);
          throw new Error(
            "115Master脚本启动失败: 现在不需要修改【User-Agent】请删除插件~"
          );
        }
      };
      class DebugInfo {
        constructor() {
          this.Logger = new Logger("115Master", "DebugInfo");
        }
        bootstrapInfo() {
          this.Logger.log(
            "bootstrap-info",
            `
${_GM_info.script.name} 启动成功,喜欢这个脚本的话,帮我在主页点个 Star 吧!
版本: ${_GM_info.script.version}
作者: ${_GM_info.script.author}
描述: ${_GM_info.script.description}
主页: ${_GM_info.script.homepage}
开始执行脚本时间:${performance.now()} ms
refferer: ${window.location.href}
        `
          );
        }
      }
      const debugInfo = new DebugInfo();
      debugInfo.bootstrapInfo();
      checkUserAgent();
      const routeMatch = [
        {
          match: ROUTE_MATCH.HOME,
          exec: () => new HomePage()
        },
        {
          match: ROUTE_MATCH.VIDEO,
          exec: () => videoPage()
        }
      ];
      const main = () => {
        for (const route of routeMatch) {
          if (globToRegex(route.match).test(window.location.href)) {
            route.exec();
          }
        }
      };
      if (document.readyState === "complete" || document.readyState === "interactive") {
        main();
      } else {
        window.addEventListener("DOMContentLoaded", main);
      }

    })
  };
}));

System.import("./__entry.js", "./");